FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   1

      1                         ;^Z80^
      2                         ; modem control information
      3                         ; Coleco 300 baud direct connect modem
      4                         ;      4/5/84
      5                         ;
      6                         ; Data port = 05EH
      7                         ; Control port = 05FH
      8                         ;
      9                         ; Useful equates
     10           005E          DATAP   EQU     05EH
     11           005F          CTRLP   EQU     05FH
     12                         ;
     13                         ;     Mode instruction values
     14           0080          NULL    EQU     080H
     15                         ;
     16                         ; To generate mode byte, select one from column A
     17                         ; and one from column B. See your INTEL dealer for optional
     18                         ; accessories. Add these all together, and spit 'em out.
     19                         ; Chef's suggestion: DEFAULT EQU  STPB1+BITS7+PEN+EP
     20                         ;                    [7 bits, 1 stop bit, even parity]
     21                         ;
     22                         ; column A
     23           0040          STPB1   EQU     040H    ; 1 stop bit
     24           0080          STPB15  EQU     080H    ; 1 1/2 stop bits
     25           00C0          STPB2   EQU     0C0H    ; 2 stop bits
     26                         ; column B
     27           0000          BITS5   EQU     000H    ; 5 bits/char
     28           0004          BITS6   EQU     004H    ; 6 bits/char
     29           0008          BITS7   EQU     008H    ; 7 bits/char
     30           000C          BITS8   EQU     00CH    ; 8 bits/char
     31                         ; optional accessories
     32           0020          EP      EQU     020H    ; 1=even parity, 0=odd
     33           0010          PEN     EQU     010H    ; 1=enable parity, 0=disable
     34                         ; required options
     35                         ;  ---> The only one applicable here is 300 baud!!!  <---
     36           0003          X64     EQU     003H    ; 64x clock rate [300 baud]
     37                         ;
     38                         ; the assumed default value
     39           00CC          DEFAULT EQU     STPB2+BITS8     ; 8 bits, 2 stops, no parity
     40                         ; Command instruction values
     41                         ;
     42                         ; Select desired functions, then add to get command byte
     43                         ;
     44           0080          EHM     EQU     080H    ; 1=enter hunt mode [no effect on async op]
     45                                                 ; [same as NULL]
     46           0040          IR      EQU     040H    ; 1=internal reset
     47           0020          RTS     EQU     020H    ; 1=set RTS to 0, enable transmitter
     48           0010          ER      EQU     010H    ; 1=reset error conditions
     49           0008          SBRK    EQU     008H    ; 1=send break [TXD goes "low"]
     50           0004          RXE     EQU     004H    ; 1=receive enable
     51           0001          TXE     EQU     001H    ; 1=transmit enable
     52           0002          DTR     EQU     002H    ; set DTR to 0, seize phone line
     53                         ;
     54                         ; Note this important stuff  |
     55                         ;                            V
     56                         ; 1:    If DTR ever gets set to 0, [SZ or preset goes low] then

FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   2

     57                         ;       modem goes to originate mode.
     58                         ; 2:    Once line is seized, DTR is set to 1, ^SZ is low, so
     59                         ;       7474 has preset=H, data=L,.html clear=H. In this condition,
     60                         ;       toggling clock [RTS or ^TXE] will change to answer mode
     61                         ;
     62                         ; So what?
     63                         ;
     64                         ; With phone hung up, modem is in originate mode. To seize line,
     65                         ; set DTR and RTS to 1 [this drops ^SZ]. This grabs phone line
     66                         ; and enables carrier.
     67                         ; To switch to answer mode, set RTS to 0 then back to 1.
     68                         ;
     69                         ;  STATUS BITS
     70                         ;
     71           0000          TXRDY   EQU     0               ; indicates transmitter empty
     72           0001          RXRDY   EQU     1               ; indicates valid character ready
     73           0002          TXMT    EQU     2               ; indicates buffer empty
     74           0003          P_ERR   EQU     3               ; set when parity error detected
     75           0004          OE      EQU     4               ; set on overrun error
     76           0005          FE      EQU     5               ; set on framing error
     77           0006          BD      EQU     6               ; set when break detected
     78           0007          DSR     EQU     7               ; indicated carrier detect
     79           0007          CD      EQU     DSR
     80                         ;
     81                         ; data areas
     82   0000' 80              C_DATA  DEFB    NULL            ; current 8251 command
     83                         ;
     84                         ; global subroutine names
     85                         ;
     86                                 GLOBAL  DELAY,DIAL,SEIZE,ANSMOD
     87                                 GLOBAL  HANGUP,CD_STAT,U_STAT
     88                                 GLOBAL  CHR_IN,CHR_OUT,M_INIT
     89                                 GLOBAL  SET_UART
     90                         ;
     91                         ;***************************************************************************
     92                         ; SUBROUTINES
     93                         ;***************************************************************************
     94                         ;
     95                         ; Wait 10 msec
     96   0001'                 DELAY:
     97   0001' F5                      PUSH            AF              ; [3 uSEC]
     98   0002' C5                      PUSH            BC              ; [3]
     99   0003' D5                      PUSH            DE              ; [3]
    100   0004' E5                      PUSH            HL              ; [3]
    101   0005' 21 0000                 LD              HL,0            ; [2.5]
    102   0008' 11 0000                 LD              DE,0            ; [2.5]
    103   000B' 01 3606                 LD              BC,1590
    104                         ; with all the pushes and pops, we've used about 32 uSEC.
    105                         ; we need a total of 2,000 LDIRs less 7
    106                         ; BUT this is off a bit, so we have to go about 18% faster
    107   000E' ED B0                   LDIR
    108   0010' E1                      POP             HL              ; [3]
    109   0011' D1                      POP             DE              ; [3]
    110   0012' C1                      POP             BC              ; [3]
    111   0013' F1                      POP             AF              ; [3]
    112   0014' C9                      RET
    113                         ;

FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   3

    114                         ; *************************************
    115                         ; DIAL DIGIT
    116                         ;  ENTRY: A=ASCII DIGIT 0-9
    117                         ;  EXIT:  NONE
    118   0015'                 DIAL:
    119   0015' F5                      PUSH            AF
    120   0016' C5                      PUSH            BC
    121   0017' D5                      PUSH            DE
    122   0018' E5                      PUSH            HL
    123                         ;thaT
    124   0019' FE 50                   CP              'P'
    125   001B' 28 36                   JR              Z,PAUSE
    126   001D' FE 70                   CP              'p'
    127   001F' 28 32                   JR              Z,PAUSE
    128   0021' FE 2C                   CP              ','             ;Comma=pause
    129   0023' 28 2E                   JR              Z,PAUSE
    130   0025' FE 3A                   CP              '9'+1
    131   0027' 30 31                   JR              NC,BAD_DGT      ;if character >= ':' then we lose
    132   0029' FE 30                   CP              '0'
    133   002B' 38 2D                   JR              C,BAD_DGT               ;if char < '0' then we lose
    134   002D' 20 02                   JR              NZ,CHAR_OK
    135                         ; an ASCII 0 means 10 pulses, so start with '9'+1
    136   002F' 3E 3A                   LD              A,'9'+1
    137   0031'                 CHAR_OK:
    138   0031' D6 30                   SUB             '0'
    139   0033' 47                      LD              B,A                     ;number of pulses is now in B
    140                         ;
    141   0034'                 PLSE_LP:
    142                         ; All dialing is in originate mode. We assume that the line was
    143                         ; already seized.
    144                         ;
    145                         ; unseize line for 18/29 of the 100 ms pulse time [60 ms]
    146   0034' 3E 25                   LD              A,RXE+TXE+RTS
    147   0036' D3 5F                   OUT             (CTRLP),A       ;PICK UP
    148   0038' C5                      PUSH            BC
    149   0039' 06 06                   LD              B,6
    150   003B'                 PLP1:
    151   003B' CD 0100'                CALL            DELAY
    152   003E' 10 FB                   DJNZ            PLP1
    153   0040' C1                      POP             BC
    154                         ; seize line for 11/29 of the 100 ms pulse time [40 ms]
    155   0041' 3E 27                   LD              A,RXE+TXE+RTS+DTR
    156   0043' D3 5F                   OUT             (CTRLP),A       ;PICK UP
    157   0045' C5                      PUSH            BC
    158   0046' 06 04                   LD              B,4
    159   0048'                 PLP2:
    160   0048' CD 0100'                CALL            DELAY
    161   004B' 10 FB                   DJNZ            PLP2
    162   004D' C1                      POP             BC
    163                         ;
    164                         ; next pulse
    165   004E' 10 E4                   DJNZ            PLSE_LP
    166
    167   0050' 32 0000'                LD              (C_DATA),A              ;SAVE LAST VALUE
    168                         ;
    169                         ; delay between digits
    170   0053'                 PAUSE:

FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   4

    171   0053' 06 50                   LD              B,80                    ;800 ms
    172   0055'                 PLP3:
    173   0055' CD 0100'                CALL            DELAY
    174   0058' 10 FB                   DJNZ            PLP3
    175   005A'                 BAD_DGT:
    176   005A' E1                      POP             HL
    177   005B' D1                      POP             DE
    178   005C' C1                      POP             BC
    179   005D' F1                      POP             AF
    180   005E' C9                      RET
    181
    182                         ; ***************************
    183                         ; SEIZE LINE
    184                         ;  ENTRY: A=0 FOR ORIGINATE MODE
    185                         ;         A-0FFH FOR ANSWER MODE
    186                         ;  EXIT:  CARRIER IS ENABLED
    187                         ;         REGS A & C GET TRASHED
    188   005F'                 SEIZE:
    189   005F' 4F                      LD              C,A             ; SAVE
    190   0060' CD 7900'                CALL            HANGUP
    191   0063' 3E 27                   LD              A,RXE+TXE+RTS+DTR
    192   0065' 32 0000'                LD              (C_DATA),A      ; SAVE LAST COMMAND
    193   0068' D3 5F                   OUT             (CTRLP),A       ; PICK UP
    194   006A' 79                      LD              A,C
    195   006B' B7                      OR              A
    196   006C' C8                      RET             Z               ; ALL DONE
    197                         ; *****************
    198                         ; ANSWER MODE
    199                         ; SWITCHES MODEM DIRECTLY TO ANSWER MODE
    200                         ; Assumes modem off-hook
    201                         ;    EXIT:  REG A TRASHED
    202   006D'                 ANSMOD:
    203                         ; ONE FULL PULSE OF RTS LINE
    204   006D' 3E 07                   LD              A,RXE+TXE+DTR
    205   006F' D3 5F                   OUT             (CTRLP),A
    206   0071' 3E 27                   LD              A,RXE+TXE+RTS+DTR
    207   0073' 32 0000'                LD              (C_DATA),A      ; SAVE LAST COMMAND
    208   0076' D3 5F                   OUT             (CTRLP),A
    209   0078' C9                      RET
    210                         ; **********************
    211                         ; HANGUP
    212                         ;    HANGS UP PHONE. TRASHES REG A
    213                         ;
    214   0079'                 HANGUP:
    215   0079' 3E 25                   LD              A,RXE+TXE+RTS
    216   007B' 32 0000'                LD              (C_DATA),A      ; SAVE LAST COMMAND
    217   007E' D3 5F                   OUT             (CTRLP),A       ; HANG UP PHONE AND SWITCH TO ORIGINATE MODE
    218   0080' C9                      RET
    219                         ; **********************
    220                         ; CARRIER_STATUS
    221                         ;   READS STATUS FROM UART AND MODEM CHIP
    222                         ;       ENTRY:
    223                         ;       EXIT:   NZ=CARRIER DETECT
    224                         ;               Z=NO CARRIER
    225   0081'                 CD_STAT:
    226   0081' DB 5F                   IN              A,(CTRLP)
    227   0083' CB 7F                   BIT             DSR,A

FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   5

    228   0085' C9                      RET
    229                         ; **********************
    230                         ; UART_STATUS
    231                         ;   CHECKS UART FOR ERRORS AND/OR DATA
    232                         ;       ENTRY:
    233                         ;       EXIT:   NC=NO ERRORS
    234                         ;               C=DATA ERROR
    235                         ;               NZ=CHARACTER PRESENT
    236                         ;               Z=NO CHARACTER
    237   0086'                 U_STAT:
    238   0086' DB 5F                   IN              A,(CTRLP)
    239   0088' B7                      OR              A
    240   0089' 18 01                   JR              URT_CMN
    241   008B'                 URT_ERR:
    242   008B' 37                      SCF
    243   008C'                 URT_CMN:
    244   008C' CB 4F                   BIT             RXRDY,A
    245   008E' C9                      RET
    246                         ; ************************
    247                         ; CHARACTER_IN
    248                         ;       ENTRY:
    249                         ;       EXIT:   A=CHARACTER FROM MODEM
    250                         ;               NC=NO ERROR
    251                         ;               C=DATA ERROR
    252
    253   008F'                 CHR_IN:
    254   008F' CD 8600'                CALL            U_STAT
    255   0092' 28 FB                   JR              Z,CHR_IN        ;WAIT FOR CHARACTER
    256   0094' DB 5E                   IN              A,(DATAP)
    257   0096' B7                      OR              A
    258   0097' C9                      RET
    259   0098'                 CHR_ERR:
    260   0098' 3A 0000'                LD              A,(C_DATA)
    261   009B' F6 10                   OR              ER              ;clear for errors
    262   009D' D3 5F                   OUT             (CTRLP),A
    263   009F' EE 10                   XOR             ER              ;disable error reset
    264   00A1' D3 5F                   OUT             (CTRLP),A
    265   00A3' 3E 00                   LD              A,0
    266   00A5' C9                      RET
    267                         ; *********************
    268                         ; CHARACTER_OUT
    269                         ;       ENTRY:  A=CHARACTER TO TRANSMIT
    270                         ;       EXIT:   NONE
    271   00A6'                 CHR_OUT:
    272   00A6' F5                      PUSH            AF
    273                         ; WAIT UNTIL TRANSMITTER CLEAR
    274   00A7'                 CHR_L1:
    275   00A7' DB 5F                   IN              A,(CTRLP)
    276   00A9' CB 57                   BIT             TXMT,A
    277   00AB' 28 FA                   JR              Z,CHR_L1
    278                         ; DUMP THE SUCKER OUT
    279   00AD' F1                      POP             AF
    280   00AE' D3 5E                   OUT             (DATAP),A
    281   00B0' C9                      RET
    282                         ; *************************
    283                         ; MODEM_INIT
    284                         ;   PRESETS MODEM TO KNOWN INITIAL STATE

FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   6

    285   00B1'                 M_INIT:
    286   00B1' 3E 80                   LD              A,NULL
    287   00B3' 32 0000'                LD              (C_DATA),A      ; fool it into hanging up
    288   00B6' 3E CC                   LD              A,DEFAULT       ; desired default value
    289
    290                         ; *************************
    291                         ; SET_UART
    292                         ;   SETS UART TO DESIRED STOP BITS, PARITY, ETC
    293                         ;       ENTRY:  A=stop bits + bits/char + parity
    294                         ;       EXIT:   NONE
    295   00B8'                 SET_UART:
    296   00B8' F6 03                   OR              X64             ; clock rate is always 64x
    297   00BA' F5                      PUSH            AF
    298   00BB' 3E 80                   LD              A,080H
    299   00BD' D3 5F                   OUT             (CTRLP),A
    300   00BF' D3 5F                   OUT             (CTRLP),A       ; get the 8251's attention
    301   00C1' 3E 40                   LD              A,040H
    302   00C3' D3 5F                   OUT             (CTRLP),A
    303   00C5' F1                      POP             AF
    304   00C6' D3 5F                   OUT             (CTRLP),A       ; dump the init value out
    305   00C8' 3A 0000'                LD              A,(C_DATA)
    306   00CB' D3 5F                   OUT             (CTRLP),A
    307   00CD' C9                      RET

     0 Error(s) Detected.   206 Program Bytes.
    54 Symbols Detected.

FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   7

Value   Symbol          Defined         Referenced:

006D' ANSMOD               202      86
005A' BAD_DGT              175     131   133
0006  BD                    77
0000  BITS5                 27
0004  BITS6                 28
0008  BITS7                 29
000C  BITS8                 30      39
0007  CD                    79
0081' CD_STAT              225      87
0031' CHAR_OK              137     134
0098' CHR_ERR              259
008F' CHR_IN               253      88   255
00A7' CHR_L1               274     277
00A6' CHR_OUT              271      88
005F  CTRLP                 11     147   156   193   205   208   217   226   238   262   264   275   299   300   302   304   306
0000' C_DATA                82     167   192   207   216   260   287   305
005E  DATAP                 10     256   280
00CC  DEFAULT               39     288
0001' DELAY                 96      86   151   160   173
0015' DIAL                 118      86
0007  DSR                   78      79   227
0002  DTR                   52     155   191   204   206
0080  EHM                   44
0020  EP                    32
0010  ER                    48     261   263
0005  FE                    76
0079' HANGUP               214      87   190
0040  IR                    46
00B1' M_INIT               285      88
0080  NULL                  14      82   286
0004  OE                    75
0053' PAUSE                170     125   127   129
0010  PEN                   33
003B' PLP1                 150     152
0048' PLP2                 159     161
0055' PLP3                 172     174
0034' PLSE_LP              141     165
0003  P_ERR                 74
0020  RTS                   47     146   155   191   206   215
0004  RXE                   50     146   155   191   204   206   215
0001  RXRDY                 72     244
0008  SBRK                  49
005F' SEIZE                188      86
00B8' SET_UART             295      89
0040  STPB1                 23
0080  STPB15                24
00C0  STPB2                 25      39
0001  TXE                   51     146   155   191   204   206   215
0002  TXMT                  73     276
0000  TXRDY                 71
008C' URT_CMN              243     240
008B' URT_ERR              241
0086' U_STAT               237      87   254
0003  X64                   36     296