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.
 
 
 
 
 
 

183 lines
3.8 KiB

;
;==================================================================================================
; S100 PROPELLER CONSOLE DRIVER
;==================================================================================================
;
; TODO:
;
SCON_IOBASE .EQU $0000 ; NOTE: 16-BIT I/O
;
SCON_STATUS .EQU SCON_IOBASE
SCON_DATA .EQU SCON_IOBASE + 1
;
SCON_KBDRDY .EQU %00000010
SCON_DSPRDY .EQU %00000100
;
SCON_COLS .EQU 80
SCON_ROWS .EQU 40
;
DEVECHO "SCON: IO="
DEVECHO SCON_IOBASE
DEVECHO "\n"
;
;
;
SCON_PREINIT:
;
; ADD OURSELVES TO CIO DISPATCH TABLE
;
OR $FF ; CLEAR OUT
LD (SCON_UNIT),A ; ... SCON UNIT NUMBER
CALL SCON_DETECT ; SEE IF WE ARE THERE
RET NZ ; ABORT IF NOT
;
LD D,0 ; PHYSICAL UNIT IS ZERO
LD E,CIODEV_SCON ; DEVICE TYPE
LD BC,SCON_FNTBL ; BC := FUNCTION TABLE ADDRESS
CALL CIO_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED
LD (SCON_UNIT),A ; RECORD OUR UNIT NUMBER
CALL CIO_SETCRT ; SET OURSELVES AS THE CRT DEVICE
;
XOR A ; SIGNAL SUCCESS
RET
;
;
;
SCON_INIT:
CALL NEWLINE
PRTS("SCON:$")
PRTS(" IO=0x$") ; FORMATTING
LD A,SCON_IOBASE
CALL PRTHEXBYTE
;
LD A,(SCON_UNIT)
CP $FF
JR NZ,SCON_INIT1
;
; HARDWARE NOT PRESENT
PRTS(" NOT PRESENT$")
OR $FF ; SIGNAL FAILURE
RET
;
SCON_INIT1:
; DISPLAY CONSOLE DIMENSIONS
CALL PC_SPACE
LD A,SCON_COLS
CALL PRTDECB
LD A,'X'
CALL COUT
LD A,SCON_ROWS
CALL PRTDECB
CALL PRTSTRD
.TEXT " TEXT (ANSI)$"
;
XOR A ; SIGNAL SUCCESS
RET
;
; DRIVER FUNCTION TABLE
;
SCON_FNTBL:
.DW SCON_IN
.DW SCON_OUT
.DW SCON_IST
.DW SCON_OST
.DW SCON_INITDEV
.DW SCON_QUERY
.DW SCON_DEVICE
#IF (($ - SCON_FNTBL) != (CIO_FNCNT * 2))
.ECHO "*** INVALID SCON FUNCTION TABLE ***\n"
#ENDIF
;
;
;
SCON_IN:
CALL SCON_IST ; CHECK FOR CHAR PENDING
JR Z,SCON_IN ; WAIT FOR IT IF NECESSARY
;IN0 A,(SCON_DATA) ; READ THE CHAR FROM PROPIO
LD BC,SCON_DATA ; DATA PORT (16 BIT I/O)
IN A,(C) ; READ THE CHAR FROM PROPIO
LD E,A
RET
;
;
;
SCON_IST:
;IN0 A,(SCON_STATUS) ; READ LINE STATUS REGISTER
LD BC,SCON_STATUS ; STATUS PORT (16-BIT I/O)
IN A,(C) ; READ LINE STATUS REGISTER
AND SCON_KBDRDY ; ISOLATE KBDRDY
JP Z,CIO_IDLE ; RETURN VIA IDLE PROCESSING
OR $FF ; SET A=$FF TO SIGNAL READY
RET ; RETURN
;
;
;
SCON_OUT:
CALL SCON_OST ; CHECK FOR OUTPUT READY
JR Z,SCON_OUT ; WAIT IF NECESSARY
LD A,E ; RECOVER THE CHAR TO WRITE
;OUT0 (SCON_DATA),A ; WRITE THE CHAR TO PROPIO
LD BC,SCON_DATA ; DATA PORT (16 BIT I/O)
OUT (C),A ; WRITE THE CHAR TO PROPIO
RET
;
;
;
SCON_OST:
;IN0 A,(SCON_STATUS) ; READ LINE STATUS REGISTER
LD BC,SCON_STATUS ; STATUS PORT (16-BIT I/O)
IN A,(C) ; READ LINE STATUS REGISTER
AND SCON_DSPRDY ; ISOLATE DSPRDY
JP Z,CIO_IDLE ; RETURN VIA IDLE PROCESSING
OR $FF ; SET A=$FF TO SIGNAL READY
RET ; RETURN
;
;
;
SCON_INITDEV:
SYSCHKERR(ERR_NOTIMPL)
RET
;
;
;
SCON_QUERY:
LD DE,0
LD HL,0
XOR A
RET
;
;
;
SCON_DEVICE:
LD D,CIODEV_SCON ; D := DEVICE TYPE
LD E,0 ; E := DEVICE NUM, ALWAYS 0
LD C,$BF ; C := DEVICE TYPE, 0xBF IS PROP TERM
LD H,0 ; H := 0, DRIVER HAS NO MODES
LD L,SCON_IOBASE ; L := BASE I/O ADDRESS
XOR A ; SIGNAL SUCCESS
RET
;
; TEST FOR HARDWARE PRESENCE.
; THIS IS REALLY A POOR SOLUTION. WE ASSUME THAT THE STATUS AND
; DATA PORT SHOULD NOT BE THE SAME VALUE. IF SO, IT PROBABLY MEANS
; THERE IS NOTHING THERE.
;
SCON_DETECT:
IN A,(SCON_STATUS) ; GET STATUS PORT VALUE DIRECTLY
CP $FF ; CHECK FOR $FF
JR Z,SCON_DETECT1 ; IF $FF, NOT ACTIVE
LD B,A ; STASH IN B
IN A,(SCON_DATA) ; READ DATA PORT
CP B ; SAME?
JR Z,SCON_DETECT1 ; IF SO, NOT ACTIVE
XOR A ; SIGNAL ACTIVE
RET
SCON_DETECT1:
OR $FF ; SET NZ TO SIGNAL NOT PRESENT
RET ; DONE
;
;
;
SCON_UNIT .DB $FF ; OUR ASSIGNED UNIT NUMBER