You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

149 lines
3.0 KiB

;
;==================================================================================================
; SIMPLE SERIAL DRIVER
;==================================================================================================
;
; TODO:
;
DEVECHO "SSER: IO="
DEVECHO SSERSTATUS
DEVECHO "\n"
;
;
;
SSER_PREINIT:
;
; TEST FOR PRESENCE
;
XOR A ; CLEAR ACCUM
LD (SSER_PRESENT),A ; PRESET TO NOT PRESENT
CALL SSER_DETECT ; CHECK FOR HARDWARE, Z=PRESENT
RET NZ ; ABORT IF NOT PRESENT
OR $FF ; PRESENT FLAG
LD (SSER_PRESENT),A ; STORE IT
;
; ADD OURSELVES TO CIO DISPATCH TABLE
;
LD D,0 ; PHYSICAL UNIT IS ZERO
LD E,CIODEV_SSER ; DEVICE TYPE
LD BC,SSER_FNTBL ; BC := FUNCTION TABLE ADDRESS
CALL CIO_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED
;
XOR A
RET
;
;
;
SSER_INIT:
LD A,(SSER_PRESENT) ; PRESENT FLAG
OR A ; SET FLAGS
RET Z ; ABORT IF NOT PRESENT
CALL NEWLINE
PRTS("SSER:$")
PRTS(" IO=0x$") ; FORMATTING
LD A,SSERSTATUS
CALL PRTHEXBYTE
;
XOR A ; SIGNAL SUCCESS
RET
;
; DRIVER FUNCTION TABLE
;
SSER_FNTBL:
.DW SSER_IN
.DW SSER_OUT
.DW SSER_IST
.DW SSER_OST
.DW SSER_INITDEV
.DW SSER_QUERY
.DW SSER_DEVICE
#IF (($ - SSER_FNTBL) != (CIO_FNCNT * 2))
.ECHO "*** INVALID SSER FUNCTION TABLE ***\n"
#ENDIF
;
;
;
SSER_IN:
CALL SSER_IST ; CHECK FOR CHAR PENDING
JR Z,SSER_IN ; WAIT FOR IT IF NECESSARY
IN A,(SSERDATA) ; READ THE CHAR
LD E,A
RET
;
;
;
SSER_IST:
IN A,(SSERSTATUS) ; READ LINE STATUS REGISTER
#IF (SSERIINV)
CPL
#ENDIF
AND SSERIRDY ; ISOLATE DATA READY
JP Z,CIO_IDLE ; RETURN VIA IDLE PROCESSING
OR $FF ; SET A=$FF TO SIGNAL READY
RET ; RETURN
;
;
;
SSER_OUT:
CALL SSER_OST ; CHECK FOR OUTPUT READY
JR Z,SSER_OUT ; WAIT IF NECESSARY
LD A,E ; RECOVER THE CHAR TO WRITE
OUT (SSERDATA),A ; WRITE THE CHAR
RET
;
;
;
SSER_OST:
IN A,(SSERSTATUS) ; READ LINE STATUS REGISTER
#IF (SSEROINV)
CPL
#ENDIF
AND SSERORDY ; ISOLATE OUTPUT RDY
JP Z,CIO_IDLE ; RETURN VIA IDLE PROCESSING
OR $FF ; SET A=$FF TO SIGNAL READY
RET ; RETURN
;
;
;
SSER_INITDEV:
SYSCHKERR(ERR_NOTIMPL)
RET
;
;
;
SSER_QUERY:
LD DE,SSERCFG
XOR A
RET
;
;
;
SSER_DEVICE:
LD D,CIODEV_SSER ; D := DEVICE TYPE
LD E,0 ; E := DEVICE NUM, ALWAYS 0
LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232
LD H,0 ; H := 0, DRIVER HAS NO MODES
LD L,SSERSTATUS ; L := BASE I/O ADDRESS
XOR A ; SIGNAL SUCCESS
RET
;
; TEST FOR HARDWARE PRESENCE BY CHECKING THE STATUS PORT. IF IT IS
; $FF, WE ASSUME NOT PRESENT. THEN READ PORT A DIFFERENT WAY. IF
; PRESENT PORT SHOULD HAVE SAME VALUE.
;
;
SSER_DETECT:
IN A,(SSERSTATUS) ; GET DATA PORT VALUE DIRECTLY
CP $FF ; CHECK FOR $FF
JR NZ,SSER_DETECT1 ; IF NOT $FF, MAY BE ACTIVE, CONTINUE
OR A ; SWITCH ZF BACK TO NZ
RET ; DONE
SSER_DETECT1:
LD C,SSERSTATUS ; PORT ADR TO C
IN B,(C) ; GET DATA PORT VALUE VIA (C)
CP B ; COMPARE, EQUAL IMPLIES ACTIVE PORT
RET
;
;
;
SSER_PRESENT .DB 0 ; FLAG FOR HARDWARE PRESENT