; Program: T3M-HI2.Z80
; Use: Term3 Modem Overlay
; Written by: David McCord
; Last revised: 04/02/87
;
; Latest Revisions:
; dmm   4/02/87 v2.0
;       Reworked baud rate setting, adding support for 9.216MHz and 12.288MHz
; clock rates.  Also added equate for selection of which serial port will
; be used, ASCI0 or ASCI1.  You must set the clock rate equates and ASCI
; equates appropriately (below) before assembly!
;
; dmm   4/21/86 v1.0
;       Originally MODEMH80.Z80; renamed to conform to new naming standards
; for TERM III interface files (T3M-xx#.Z80 for "modem interfaces";
; T3T-xx#.Z80 for "telephone interfaces"; and T3C-xx#.Z80 for combined
; modem AND telephone interfaces (as with the MOSART)).
;       Fixed a minor bug in the mi$init routine.
;
; Term3 Modem Interface for SB180/HD64180
; Uses HD64180 ASCI 0 (modem port on SB180)
;
; Modified from original MSB180.LIB file 03-21-86 by D. McCord
; Supports baud rates up to 38.4Kbps (max 19.2Kbps for 9.216MHz clock)
;
; This program, both source code and object code, is
; copyright 1986 Echelon, Inc.  Duplication for non-commercial personal
; use is permitted; all other duplication is prohibited unless authorized
; in writing by copyright holder.
;
; To use:
;       ZAS T3M-HI2 H                   <- make .HEX file output
;       MLOAD MODEM.BIN=T3M-HI2         <- create binary file
;       T3INS INSTALL                   <- install into TERM3 modules
;
; Cabling:
;       Because of the HD64180's internal logic (which will not
;       allow sending characters when the carrier detect input is
;       false), a special cable must be used.  Also, a different cable
;       is used for a T3SERVER/T3MASTER application.
;
;               TERM3 Modem Application Cable
;
;               SB180                   Modem
;                 1 --------------------- 1
;                 2 --------------------- 2
;                 3 --------------------- 3
;                 4 --------------------- 4
;                 5 --------------------- 8     <- note
;                 6 --------------------- 6
;                 7 --------------------- 7
;                 8 --------------------- 5     <- note
;                20 --------------------- 20
;
;         TERM3 T3MASTER/T3SERVER Application Cable (Tested with
;   AMPRO Little Board and Magnum Digital PRO-180 as "Other Computer")
;
;               SB180(Master)   Other Computer(Server)
;                 1 --------------------- 1
;                 2 --------------------- 2
;                 3 --------------------- 3
;                 4 --+
;                 5 --| <- Note: 4, 5, & 8 tied together
;                 8 --+
;                 7 --------------------- 7
;
; define "yes" and "no"
;
no      equ     0
yes     equ     not no
;
; User-select equates - select "yes" to only one clock rate
;
c6144kHz                equ     no      ;  6.144MHz
c9216kHz                equ     yes     ;  9.216MHz
c12288kHz       equ     no      ; 12.288MHz
;
; select ASCI 0 (modem port on SB180) or ASCI 1
;
asci0           equ     yes
asci1           equ     no
;
; Non-changeable equates
;
base    equ     600h            ; base of Modem Interface in T3 tools
        if     asci0
cntla   EQU     0               ; ASCI Control Register A Channel 0
cntlb   EQU     2               ; ASCI Control Register B Channel 0
stat    EQU     4               ; ASCI Status Register Channel 0
tdr     EQU     6               ; ASCI Transmit Data Register Channel 0
rdr     EQU     8               ; ASCI Receive Data Register Channel 0
        endif
        if     asci1
cntla   EQU     1               ; ASCI Control Register A Channel 1
cntlb   EQU     3               ; ASCI Control Register B Channel 1
stat    EQU     5               ; ASCI Status Register Channel 1
tdr     EQU     7               ; ASCI Transmit Data Register Channel 1
rdr     EQU     9               ; ASCI Receive Data Register Channel 1
        endif
CTS     EQU     00100000B       ; Clear-to-send input (pin 5)
DCD     EQU     00000100B       ; Data Carrier detect bit (pin 8)
RDRF    EQU     10000000B       ; RECEIVE DATA REGISTER FULL
TDRE    EQU     00000010B       ; TRANSMIT DATA REGISTER EMPTY
;
; Term3 Baud Rate definitions
;
; chart of baud rates vs. clock speed for 64180
;
;       6.144MHz clock      9.216MHZ clock      12.288MHz clock
;           PS  DR  SS          PS  DR  SS           PS  DR  SS
; 38400      0   0   0           -- na --             0   0   1
; 19200      0   0   1           1   0   0            0   0   2
;  9600      0   0   2           1   0   1            0   0   3
;  4800      0   0   3           1   0   2            0   0   4
;  2400      0   0   4           1   0   3            0   0   5
;  1200      0   0   5           1   0   4            0   0   6
;   300      0   1   5           1   0   6            0   1   6
;
        if     c6144kHz
bauds   equ     01111111b       ; this modem interface supports 300, 1200,
                               ; 2400, 4800, 9600, 19200, 38400
        endif
;
        if     c9216kHz
bauds   equ     00111111b       ; this modem interface supports 300, 1200,
                               ; 2400, 4800, 9600, 19200
        endif
;
        if     c12288kHz
bauds   equ     01111111b       ; this modem interface supports 300, 1200,
                               ; 2400, 4800, 9600, 19200, 38400
        endif
;
       .HD64   ; enable Hitachi Mnemonics
       org     base
;
; Jump Table
;
       JP      INIT            ; m1$init
       JP      ISTAT           ; M1$istat
       JP      OSTAT           ; m1$ostat
       JP      INP             ; m1$in
       JP      OUTP            ; m1$out
       JP      BREAK           ; m1$break
       JP      CST             ; m1$cst
AVAILBD:
       DB      bauds           ; set via EQUate above
;
; initialization.  Set baud rate, but leave DTR (really RTS) high
;
INIT:
        if     c9216kHz
       cp      7               ; we can't do 38.4K @ 9.216MHz
       jr      z,noset
        endif
       OR      A               ; is entry parameter 0?
       JR      NZ,SETB         ; if yes, fall thru to no set
NOSET:  POP     AF
       XOR     A               ; return "not supported"
       RET
SETB:   PUSH    HL              ; save regs
       PUSH    DE
       LD      HL,[b300-1]     ; get base of baud table
       LD      D,0             ; prep for subsequent add
       LD      E,A             ; index into baud rate table
       ADD     HL,DE           ; add index to base
       LD      D,(HL)          ; get desired byte
       OUT0    (cntlb),D       ; send it
       POP     DE
       POP     HL
       OR      A               ; return proper indication to calling routine
       RET
;
; Input status.  Returns Z and A=0 if nothing waiting.
;
ISTAT:  CALL    IISTAT
       AND     RDRF
       RET     Z
       LD      A,0FFH
       RET
;
; Read stat twice, as per Hitachi manual
;
IISTAT: IN0     A,(stat)
       IN0     A,(stat)
       OR      A
       RET
;
; Check state of CTS* and return A=0 and Z if CTS is true.
;
CKCTS:  IN0     A,(cntlb)
       AND     CTS
       RET     Z
       LD      A,0FFh
       RET
;
; Output status.  Returns Z and A=0 if not ready to send.
;
OSTAT:  CALL    IISTAT          ; GET STATUS REG
       AND     TDRE
       JR      Z,DOCTS
OST1:   LD      A,0FFH
       OR      A
       RET
;
; TDRE is false.  Is it because CTS is false?
;
DOCTS:  CALL    CKCTS           ; look at CTS (really modem carrier)
       JR      NZ,OST1         ; CTS is false; goto faking "OK to send"
       XOR     A               ; return "not ready" indication
       RET
;
; Recieve a character
;
INP:    CALL    ISTAT
       JR      Z,INP
       IN0     A,(rdr)
       RET
;
; Send a character
;
OUTP:   PUSH    AF
       CALL    CKCTS           ; check CTS
       JR      NZ,DELAY        ; if CTS is false, delay before sending
OUTP1:  CALL    OSTAT
       JR      Z,OUTP1
OUTP2:  POP     AF              ; return point from "CTS false" delay
       OUT0    (tdr),A
       RET
;
; This delay routine is used when CTS (pin 5 on SB180) is false.  Hitachi
; designed the ASCI 0 to lock the TDRE status bit false when CTS is false,
; yet the ASCI 0 can still send characters under this circumstance.  However,
; because TDRE is always false, we must manually delay after each character
; to prevent over-running the serial port.  Worst case for this delay is
; 300 bps, where each character (10 bits) is 33.3 milliseconds.  This
; delay subroutine delays about 36 milliseconds in an HD64180 system at
; the selected clock rate.
;
        if     c6144kHz
wait    equ     12
        endif
        if     c9216kHz
wait    equ     18
        endif
        if     c12288kHz
wait    equ     24
        endif
DELAY:  LD      A,wait          ; 6 T-states
D1:     PUSH    AF              ; 11 T-states                   |
       LD      A,0FFh          ; 6 T-states                    |
D2:     EX      (SP),HL         ; 16 T-states           | 72 if |
       EX      (SP),HL         ; 16                    | true, | 18398 if
       EX      (SP),HL         ; 16                    | 70 if |  true,
       EX      (SP),HL         ; 16                    | false | 18396 if
       DEC     A               ; 4                     |       |  false
       JR      NZ,D2           ; 8 if true, 6 if false |       |
       POP     AF              ; 9                             |
       DEC     A               ; 4                             |
       JR      NZ,D1           ; 8 if true, 6 if false         |
       JR      OUTP2           ; return and force send of character
;
; process BREAK request
;
BREAK:  XOR     A
       RET             ;NO BREAK AVAILABLE
;
; check carrier status
;
CST:    CALL    CKCTS           ; check CTS (really modem carrier, via
       JR      Z,CST1          ; the special cable discussed above
       XOR     A               ; NO CARRIER
       RET
CST1:   LD      A,0FFH
       OR      A
       RET
;
; Baud Rate Tables
;
        if     c6144kHz
;
; HD64180 commands to set baud rates @ 6.144 MHz clock
;
b300:   db      00001101b       ; no PS, sampling rate 64, divide ratio 32
b1200:  db      00000101b       ; no PS, sampling rate 16, divide ratio 32
b2400:  db      00000100b       ; no PS, sampling rate 16, divide ratio 16
b4800:  db      00000011b       ; no PS, sampling rate 16, divide ratio 8
b9600:  db      00000010b       ; no PS, sampling rate 16, divide ratio 4
b19200: db      00000001b       ; no PS, sampling rate 16, divide ratio 2
b38400: db      00000000b       ; no PS, sampling rate 16, divide ratio 1
        endif
        if     c9216kHz
;
; HD64180 commands to set baud rates @ 9.216 MHz clock
;
b300:   db      00100110b       ; PS, sampling rate 16, divide ratio 64
b1200:  db      00100100b       ; PS, sampling rate 16, divide ratio 16
b2400:  db      00100011b       ; PS, sampling rate 16, divide ratio 8
b4800:  db      00100010b       ; PS, sampling rate 16, divide ratio 4
b9600:  db      00100001b       ; PS, sampling rate 16, divide ratio 2
b19200: db      00100000b       ; PS, sampling rate 16, divide ratio 1
        endif
        if     c12288kHz
;
; HD64180 commands to set baud rates @ 12.288 MHz clock
;
b300:   db      00001110b       ; no PS, sampling rate 64, divide ratio 64
b1200:  db      00000110b       ; no PS, sampling rate 16, divide ratio 64
b2400:  db      00000101b       ; no PS, sampling rate 16, divide ratio 32
b4800:  db      00000100b       ; no PS, sampling rate 16, divide ratio 16
b9600:  db      00000011b       ; no PS, sampling rate 16, divide ratio 8
b19200: db      00000010b       ; no PS, sampling rate 16, divide ratio 4
b38400: db      00000001b       ; no PS, sampling rate 16, divide ratio 2
        endif
;
; End of this modem interface
;
       db      'copyright 1987 Echelon, Inc.'