; Program: T3M-ON1.Z80
; Author: Joe Wright
; Date: 10 June 1986
;
; Serial port overlay to TERM III for the Oneac computer.
; Z80 DART and 615,385 Hz Baud Rate Generator.
;
MDPORT EQU 92H ; Z80 sio-0 or dart
M1$DATA EQU MDPORT ; Data port
M1$STAT EQU MDPORT+1 ; Status port
RDA EQU 1 ; Receive data available
TBE EQU 4 ; Transmit buffer empty
DCD EQU 8 ; Data carrier detect
RES EQU 10H ; Reset external/status
;
; Baud rate table. Low order byte is baud rate generator divisor,
; High order byte is the Dart divisor (WR4, 1 stop bit).
;
BD300 EQU 0C400H ; /64, /32
BD1200 EQU 04400H ; /16, /32
BD2400 EQU 08410H ; /32, /8
BD4800 EQU 04410H ; /16, /8
BD9600 EQU 0C420H ; /64, /1
BD19200 EQU 08420H ; /32, /1
BD38400 EQU 04420H ; /16, /1
;
ORG 600H ; Base address (600h - 6ffh)
;
; Modem Support Package
;
M1$INIT:
JP SM1$INIT ; Initialize dart
M1$ISTAT:
JP SM1$ISTAT ; Test input status (rda)
M1$OSTAT:
JP SM1$OSTAT ; Test output status (tbe)
M1$IN:
JP SM1$IN ; Input a byte from the usart
M1$OUT:
JP SM1$OUT ; Output a byte to the usart
M1$BREAK:
JP SM1$BREAK ; Cause the usart to issue a break
MM1$CST:
JP SM1$CST ; Determine carrier status (detect) on usart
M1$SPTAB:
DB 01111111B ; All rates available
;
; Modem Routines
;
; Modem 1 Initialization
; Function: To initialize the Modem 1 Port
; Input Parameters: A=Speed
; 0=no set
; 1= 300
; 2= 1200
; 3= 2400
; 4= 4800
; 5= 9600
; 6=19200
; 7=38400
; Output Parameters: A=Set Speed (same table as above)
; ZERO FLAG SET
;
SM1$INIT:
PUSH HL
PUSH DE
PUSH BC
PUSH AF ; Save all registers
OR A
JR Z,NO$BAUD ; No speed selected
CP 8
JR NC,NO$BAUD ; Out of range
;
; Set up to determine if desired speed is available
;
LD B,A ; Save it a moment
LD C,A ; Two copies
XOR A ; Clear A
SCF ; Set carry flag
;
; Shift carry into A (speed) times corresponding to speed table
;
LOOP: RLA
DEC C
JR NZ,LOOP ; Shift into position
;
; See if we have a match
;
LD HL,M1$SPTAB ; Point to speed table
AND (HL) ; Check for corresponding bit
LD A,B ; Get speed
JR Z,NO$BAUD ; Not available
;
; Speed value in range, set it up
;
LD DE,BD300
DEC A
JR Z,SETBAUD ; Set 300 bps
LD DE,BD1200
DEC A
JR Z,SETBAUD ; Set 1200 bps
LD DE,BD2400
DEC A
JR Z,SETBAUD ; Set 2400 bps
LD DE,BD4800
DEC A
JR Z,SETBAUD ; Set 4800 bps
LD DE,BD9600
DEC A
JR Z,SETBAUD ; Set 9600 bps
LD DE,BD19200
DEC A
JR Z,SETBAUD ; Set 19200 bps
LD DE,BD38400
DEC A ; Insure A=0, Set 38400 bps
;
; Set up the baud rate requested
;
SETBAUD:
CALL SELBNK ; A=0 returns system port data
AND 0CFH ; Mask rate generator xx00xxxxB
OR E ; Selected rate
LD C,A ; Return it in C
CALL SELBNK ; A<=>0 sets new rate
LD A,4
OUT (M1$STAT),A ; Select WR4
LD A,D ; Get dart divisor, 1 stop bit
OUT (M1$STAT),A
LD A,3
OUT (M1$STAT),A ; WR3
LD A,0C1H ; 8 bits, Rx enable
OUT (M1$STAT),A
LD A,5
OUT (M1$STAT),A ; WR5
LD A,0EAH ; DTR, 8 bits, Tx enable, RTS
OUT (M1$STAT),A
;
SMINIT$RET:
POP AF
ERR$RET:
POP BC
POP DE
POP HL
OR A ; Set zero flag
RET
; Speed value out of range, do nothing, return zero
;
NO$BAUD:
POP AF ; Adjust stack
XOR A ; A zero
JR ERR$RET ; Quit, having failed..
;
; SELBNK routine in the ON bios gets/sets the baud rate clock
; This routine also affects the bank port and the terminal speed.
; Please don't play around with it.
;
SELBNK:
LD HL,(1) ; Bios jump table
LD L,33H ; Offset to selbnk jump
JP (HL) ; Do it, return to caller
;
; Modem 1 Input Status
; Function: To return byte ready (RDA) status
; Input Parameters: None
; Output Parameters: A=0 if no byte, A=0FFH if byte ready
;
SM1$ISTAT:
IN A,(M1$STAT) ; Get status byte
AND RDA ; Data available?
RET Z ; Zero if no data
LD A,0FFH ; Load with ff
RET
;
; Modem 1 Output Status
; Function: To return buffer empty (TBE) status
; Input Parameters: None
; Output Parameters: A=0 if buffer full, A=0FFH if buffer empty (TBE)
;
SM1$OSTAT:
IN A,(M1$STAT) ; Get status byte
AND TBE ; Buffer empty?
RET Z ; Zero if not empty
LD A,0FFH ; Load with ff
RET
;
; Modem 1 Input
; Function: To return a byte in the A Reg from Modem 1
; Input Parameters: None
; Output Parameters: A=byte (MSB NOT cleared)
;
SM1$IN:
CALL M1$ISTAT ; Get status
JP Z,M1$IN ; Continue until data available
IN A,(M1$DATA) ; Get char
RET
;
; Modem 1 Output
; Function: To output the byte in the A Reg to Modem 1
; Input Parameters: A=byte
; Output Parameters: None
;
SM1$OUT:
PUSH AF ; Save byte
M1OLOOP:
CALL M1$OSTAT ; Check output status
JP Z,M1OLOOP ; Wait until empty
POP AF ; Get byte
OUT (M1$DATA),A ; Output it
RET
;
; Modem 1 Break
; Function: To return the status of the break function for Modem 1
; and to execute the break if function is available
; Input Parameters: A=0 to return status, A=0FFH to break
; Output Parameters: A=0 and Zero Flag Set if Break not supported
;
SM1$BREAK:
XOR A ; Not implemented
RET
;
; Modem 1 Carrier Status Detect
; Function: Determine if carrier is present
; Input Parameters: None
; Output Parameters: A=0 if no carrier, A=0FFH if carrier
;
SM1$CST:
LD A,RES ; Reset external/status
OUT (M1$STAT),A
IN A,(M1$STAT) ; Get new status
AND DCD ; Check data carrier
RET Z ; No carrier, else..
OR 0FFH ; Set af
RET