mirror of https://github.com/wwarthen/RomWBW.git
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.
392 lines
8.6 KiB
392 lines
8.6 KiB
;
|
|
;==================================================================================================
|
|
; HARDWARE SUPPORT FOR HITACHI HD44780 OR EQUIVALENT
|
|
;==================================================================================================
|
|
;
|
|
; CURRENTLY ASSUMES A 20X4 DISPLAY
|
|
;
|
|
; TYPICAL PORTS USED ON RCBUS ECOSYSTEM:
|
|
;
|
|
; PRIMARY ALT
|
|
; FUNCTION $DA $AA
|
|
; DATA $DB $AB
|
|
;
|
|
LCD_FUNC .EQU LCDBASE + 0 ; WRITE
|
|
LCD_STAT .EQU LCDBASE + 0 ; READ
|
|
LCD_DATA .EQU LCDBASE + 1 ; READ/WRITE
|
|
;
|
|
LCD_FUNC_CLEAR .EQU $01 ; CLEAR DISPLAY
|
|
LCD_FUNC_HOME .EQU $02 ; HOME CURSOR & REMOVE ALL SHIFTING
|
|
LCD_FUNC_ENTRY .EQU $04 ; SET CUR DIR AND DISPLAY SHIFT
|
|
LCD_FUNC_DISP .EQU $08 ; DISP, CUR, BLINK ON/OFF
|
|
LCD_FUNC_SHIFT .EQU $10 ; MOVE CUR / SHIFT DISP
|
|
LCD_FUNC_SET .EQU $20 ; SET INTERFACE PARAMS
|
|
LCD_FUNC_CGADR .EQU $40 ; SET CGRAM ADRESS
|
|
LCD_FUNC_DDADR .EQU $80 ; SET DDRAM ADDRESS
|
|
;
|
|
DEVECHO "LCD: IO="
|
|
DEVECHO LCDBASE
|
|
DEVECHO "\n"
|
|
;
|
|
; HARDWARE RESET PRIOR TO ROMWBW CONSOLE INITIALIZATION
|
|
;
|
|
LCD_PREINIT:
|
|
;
|
|
; RESET LCD CONTROLLER, DELAYS ARE FIXED, BUSY FLAG
|
|
; CANNOT BE USED YET, CONTROLLER MAY NOT EXIST!
|
|
LD A,LCD_FUNC_SET | %11000
|
|
OUT (LCD_FUNC),A
|
|
LD DE,50000/16 ; WAIT >40MS, WE USE 50MS
|
|
CALL VDELAY ; DO IT
|
|
LD A,LCD_FUNC_SET | %11000
|
|
OUT (LCD_FUNC),A
|
|
LD DE,5000/16 ; WAIT >4.1MS, WE USE 5MS
|
|
CALL VDELAY ; DO IT
|
|
LD A,LCD_FUNC_SET | %11000
|
|
OUT (LCD_FUNC),A
|
|
LD DE,5000/16 ; WAIT >4.1MS, WE USE 5MS
|
|
CALL VDELAY ; DO IT
|
|
;
|
|
; TEST FOR PRESENCE...
|
|
CALL LCD_DETECT ; PROBE FOR HARDWARE
|
|
LD A,(LCD_PRESENT) ; GET PRESENCE FLAG
|
|
OR A ; SET FLAGS
|
|
RET Z ; BAIL OUT IF NOT PRESENT
|
|
;
|
|
; WE CAN NOW DO NORMAL I/O W/ BUSY FLAG
|
|
LD DE,LCD_INIT_SEQ ; INIT SEQUENCE
|
|
CALL LCD_OUTFS ; SEND IT
|
|
;
|
|
; PUT SOMETHING ON THE DISPLAY
|
|
LD DE,LCD_STR_BAN
|
|
CALL LCD_OUTDS
|
|
;
|
|
; SECOND LINE
|
|
; CPU TYPE
|
|
LD HL,$0100 ; ROW 2, COL 0
|
|
CALL LCD_GOTORC
|
|
LD HL,LCD_CPU
|
|
LD A,(HB_CPUTYPE) ; GET CPU TYPE
|
|
RRCA ; WORD OFFSET
|
|
CALL ADDHLA ; ADD OFFSET
|
|
LD E,(HL) ; GET LSB
|
|
INC HL ; BUMP
|
|
LD D,(HL) ; GET MSB
|
|
CALL LCD_OUTDS
|
|
LD DE,LCD_STR_XPU
|
|
CALL LCD_OUTDS
|
|
;
|
|
; "12.345 MHz" RIGHT JUSTIFIED
|
|
LD HL,$010A ; ROW 2, COL 10
|
|
CALL LCD_GOTORC
|
|
LD HL,(CB_CPUKHZ)
|
|
PUSH HL
|
|
LD BC,10000 ; 10 MHZ
|
|
SBC HL,BC ; SUBTRACT
|
|
JR NC,LCD_PREINIT1
|
|
LD A,' ' ; EXTRA PAD
|
|
CALL LCD_OUTD
|
|
LCD_PREINIT1:
|
|
POP HL
|
|
CALL LCD_PRTD3M ; PRINT AS DECIMAL WITH 3 DIGIT MANTISSA
|
|
LD DE,LCD_STR_MHZ
|
|
CALL LCD_OUTDS
|
|
;
|
|
; THIRD LINE
|
|
LD HL,$0200 ; ROW 2, COL 0
|
|
CALL LCD_GOTORC
|
|
LD DE,LCD_STR_CFG
|
|
CALL LCD_OUTDS
|
|
;
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; DONE
|
|
;
|
|
; POST CONSOLE INITIALIZATION
|
|
;
|
|
LCD_INIT:
|
|
CALL NEWLINE ; FORMATTING
|
|
PRTS("LCD: IO=$")
|
|
LD A,LCDBASE
|
|
CALL PRTHEXBYTE
|
|
;
|
|
LD A,(LCD_PRESENT) ; GET PRESENCE FLAG
|
|
OR A ; SET FLAGS
|
|
JR Z,LCD_INIT1 ; HANDLE NOT PRESENT
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; DONE
|
|
;
|
|
LCD_INIT1:
|
|
PRTS(" NOT PRESENT$")
|
|
OR $FF
|
|
RET
|
|
;
|
|
; CALLED FROM HBIOS RIGHT BEFORE A DISK ACCESS
|
|
; HL: ADDRESS OF 32-BIT SECTOR NUMBER (LITTLE-ENDIAN)
|
|
;
|
|
; FORMAT: "Disk #99 R:12345678"
|
|
; 01234567890123456789
|
|
;
|
|
LCD_DSKACT:
|
|
; SAVE EVERYTHING
|
|
PUSH AF
|
|
PUSH BC
|
|
PUSH DE
|
|
PUSH HL
|
|
;
|
|
LD A,(LCD_PRESENT) ; GET PRESENCE FLAG
|
|
OR A ; SET FLAGS
|
|
JR Z,LCD_DSKACT_Z ; HANDLE NOT PRESENT
|
|
;
|
|
PUSH HL
|
|
LD HL,$0300 ; ROW 3, COL 0
|
|
CALL LCD_GOTORC ; SET DISPLAY ADDRESS
|
|
POP HL
|
|
;
|
|
LD DE,LCD_STR_IO ; PREFIX
|
|
CALL LCD_OUTDS ; SEND TO DISPLAY (COLS 0-5)
|
|
;
|
|
LD A,(HB_DSKUNIT) ; GET DISK UNIT NUM
|
|
CALL LCD_DSKACT_BYTE ; SEND TO DISPLAY (COLS 6-7) HEX???
|
|
;
|
|
LD A,' ' ; SEPARATOR
|
|
CALL LCD_OUTD ; SEND TO DISPLAY (COL 8)
|
|
CALL LCD_OUTD ; SEND TO DISPLAY (COL 9)
|
|
;
|
|
LD A,(HB_DSKFUNC) ; ACTIVE DISK FUNCTION
|
|
CP BF_DIOWRITE ; WRITE?
|
|
LD A,'W' ; ASSUME WRITE
|
|
JR Z,LCD_DSKACT0 ; GO AHEAD
|
|
LD A,'R' ; OTHERWISE READ
|
|
LCD_DSKACT0:
|
|
CALL LCD_OUTD ; SEND CHAR (COL 10)
|
|
;
|
|
LD A,':' ; SEPARATOR
|
|
CALL LCD_OUTD ; SEND TO DISPLAY (COL 11)
|
|
;
|
|
LD A,3 ; POINT TO
|
|
CALL ADDHLA ; END OF DWORD (MSB)
|
|
LD B,4 ; DO 4 BYTES
|
|
;
|
|
LCD_DSKACT1:
|
|
LD A,(HL) ; GET BYTE
|
|
CALL LCD_DSKACT_BYTE ; SEND TO DISPLAY (COLS 12-19)
|
|
DEC HL ; DEC PTR
|
|
DJNZ LCD_DSKACT1 ; DO ALL 4 BYTES
|
|
;
|
|
LCD_DSKACT_Z:
|
|
; CLEAN UP AND GO AWAY
|
|
POP HL
|
|
POP DE
|
|
POP BC
|
|
POP AF
|
|
RET
|
|
;
|
|
LCD_DSKACT_BYTE:
|
|
PUSH AF ; SAVE BYTE
|
|
RRCA ; DO TOP NIBBLE FIRST
|
|
RRCA
|
|
RRCA
|
|
RRCA
|
|
CALL HEXCONV ; CONVERT NIBBLE TO ASCII
|
|
CALL LCD_OUTD ; SEND TO DISPLAY
|
|
POP AF ; RECOVER CURRENT BYTE
|
|
CALL HEXCONV ; CONVERT NIBBLE TO ASCII
|
|
CALL LCD_OUTD ; SEND TO DISPLAY
|
|
RET ; DONE
|
|
;
|
|
; DETECT PRESENCE OF LCD CONTROLLER BY WRITING AND READING BACK
|
|
; TEST VALUES IN THE CONTROLLER RAM.
|
|
; WE DO NOT USE THE NORMAL READ/WRITE ROUTINES BECAUSE WE DO
|
|
; NOT WANT TO STALL WAITING ON THE BUSY FLAG IF THE CONTROLLER
|
|
; IS NOT PRESENT
|
|
;
|
|
LCD_DETECT:
|
|
; FIRST PASS W/ TEST VALUE $AA
|
|
LD C,$AA
|
|
CALL LCD_DETECT_PASS
|
|
JR NZ,LCD_DETECT1
|
|
;
|
|
; SECOND PASS W/ TEST VALUE $55
|
|
LD C,$55
|
|
CALL LCD_DETECT_PASS
|
|
JR NZ,LCD_DETECT1
|
|
;
|
|
; LCD PRESENT
|
|
OR $FF
|
|
JR LCD_DETECT_Z
|
|
;
|
|
LCD_DETECT1:
|
|
; LCD NOT PRESENT
|
|
XOR A
|
|
JR LCD_DETECT_Z
|
|
;
|
|
LCD_DETECT_Z:
|
|
LD (LCD_PRESENT),A
|
|
RET
|
|
;
|
|
; WRITE AND READBACK VALUE IN C TO THE FIRST BYTE OF DDRAM
|
|
; RETURN WITH COMPARE RESULT
|
|
;
|
|
LCD_DETECT_PASS:
|
|
CALL LCD_DELAY ; WAIT
|
|
LD A,LCD_FUNC_DDADR
|
|
OUT (LCD_FUNC),A ; POINT TO FIRST BYTE
|
|
CALL LCD_DELAY ; WAIT
|
|
LD A,C ; TEST VALUE
|
|
OUT (LCD_DATA),A ; WRITE IT
|
|
CALL LCD_DELAY ; WAIT
|
|
LD A,LCD_FUNC_DDADR
|
|
OUT (LCD_FUNC),A ; POINT TO FIRST BYTE
|
|
CALL LCD_DELAY
|
|
IN A,(LCD_DATA) ; GET VALUE
|
|
CP C ; AS WRITTEN?
|
|
RET
|
|
;
|
|
; DELAY USED DURING DETECT, >37US
|
|
;
|
|
LCD_DELAY:
|
|
CALL DELAY ; 16US
|
|
CALL DELAY ; 16US
|
|
JP DELAY ; 16US, TOTAL 48US
|
|
;
|
|
; SEND FUNCTION CODE IN A
|
|
;
|
|
LCD_OUTF:
|
|
PUSH AF ; SAVE CODE
|
|
LCD_OUTF1:
|
|
IN A,(LCD_STAT) ; GET STATUS
|
|
AND $80 ; ISOLATE BUSY FLAG
|
|
JR NZ,LCD_OUTF1 ; LOOP TILL NOT BUSY
|
|
POP AF ; RECOVER CODE
|
|
OUT (LCD_FUNC),A ; SEND IT
|
|
RET ; DONE
|
|
;
|
|
; SEND FUNCTION STRING
|
|
; DE=STRING ADDRESS, NULL TERMINATED
|
|
;
|
|
LCD_OUTFS:
|
|
LD A,(DE) ; NEXT BYTE TO SEND
|
|
OR A ; SET FLAGS
|
|
RET Z ; DONE WHEN NULL REACHED
|
|
INC DE ; BUMP POINTER
|
|
CALL LCD_OUTF ; SEND IT
|
|
JR LCD_OUTFS ; LOOP AS NEEDED
|
|
;
|
|
; SEND DATA BYTE IN A
|
|
;
|
|
LCD_OUTD:
|
|
PUSH AF ; SAVE BYTE
|
|
LCD_OUTD1:
|
|
IN A,(LCD_STAT) ; GET STATUS
|
|
AND $80 ; ISOLATE BUSY FLAG
|
|
JR NZ,LCD_OUTD1 ; LOOP TILL NOT BUSY
|
|
POP AF ; RECOVER BYTE
|
|
OUT (LCD_DATA),A ; SEND IT
|
|
RET ; DONE
|
|
;
|
|
; SEND DATA STRING
|
|
; DE=STRING ADDRESS, NULL TERMINATED
|
|
;
|
|
LCD_OUTDS:
|
|
LD A,(DE) ; NEXT BYTE TO SEND
|
|
OR A ; SET FLAGS
|
|
RET Z ; DONE WHEN NULL REACHED
|
|
INC DE ; BUMP POINTER
|
|
CALL LCD_OUTD ; SEND IT
|
|
JR LCD_OUTDS ; LOOP AS NEEDED
|
|
;
|
|
; GET DATA BYTE INTO A
|
|
;
|
|
LCD_IND:
|
|
IN A,(LCD_STAT) ; GET STATUS
|
|
AND $80 ; ISOLATE BUSY FLAG
|
|
JR NZ,LCD_IND ; LOOP TILL NOT BUSY
|
|
POP AF ; RECOVER BYTE
|
|
IN A,(LCD_DATA) ; GET IT
|
|
RET ; DONE
|
|
;
|
|
; GOTO ROW(H),COL(L)
|
|
;
|
|
LCD_GOTORC:
|
|
PUSH HL ; SAVE INCOMING
|
|
LD A,H ; ROW # TO A
|
|
LD HL,LCD_ROWS ; POINT TO ROWS TABLE
|
|
CALL ADDHLA ; INDEX TO ROW ENTRY
|
|
LD A,(HL) ; GET RWO START
|
|
POP HL ; RECOVER INCOMING
|
|
ADD A,L ; ADD COLUMN
|
|
ADD A,LCD_FUNC_DDADR ; APPLY FUNCTION BIT
|
|
JR LCD_OUTF ; AND SEND IT
|
|
;
|
|
; PRINT VALUE OF HL AS THOUSANDTHS, IE. 0.000
|
|
;
|
|
LCD_PRTD3M:
|
|
PUSH BC
|
|
PUSH DE
|
|
PUSH HL
|
|
LD E,'0'
|
|
LD BC,-10000
|
|
CALL LCD_PRTD3M1
|
|
LD E,0
|
|
LD BC,-1000
|
|
CALL LCD_PRTD3M1
|
|
LD A,'.'
|
|
CALL LCD_OUTD
|
|
LD BC,-100
|
|
CALL LCD_PRTD3M1
|
|
LD C,-10
|
|
CALL LCD_PRTD3M1
|
|
LD C,-1
|
|
CALL LCD_PRTD3M1
|
|
POP HL
|
|
POP DE
|
|
POP BC
|
|
RET
|
|
LCD_PRTD3M1:
|
|
LD A,'0' - 1
|
|
LCD_PRTD3M2:
|
|
INC A
|
|
ADD HL,BC
|
|
JR C,LCD_PRTD3M2
|
|
SBC HL,BC
|
|
CP E
|
|
JR Z,LCD_PRTD3M3
|
|
LD E,0
|
|
CALL LCD_OUTD
|
|
LCD_PRTD3M3:
|
|
RET
|
|
;
|
|
; DATA STORAGE
|
|
;
|
|
LCD_PRESENT .DB 0 ; NON-ZERO WHEN HARDWARE DETECTED
|
|
;
|
|
LCD_ROWS .DB $00,$40,$14,$54 ; ROW START INDEX
|
|
;
|
|
LCD_INIT_SEQ:
|
|
.DB LCD_FUNC_SET | %11000 ; FUNCTION SET, 2 LINES, 5X8 FONT
|
|
.DB LCD_FUNC_DISP ; DISPLAY OFF
|
|
.DB LCD_FUNC_CLEAR ; CLEAR DISPLAY, HOME CURSOR
|
|
.DB LCD_FUNC_ENTRY | $02 ; INCREMENT, NO SHIFT
|
|
.DB LCD_FUNC_DISP | $04 ; DISPLAY ON, NO CURSOR, NO BLINK
|
|
.DB $00 ; TERMINATOR
|
|
;
|
|
LCD_STR_BAN .DB "RomWBW v", BIOSVER, 0
|
|
LCD_STR_CFG .DB "Build: ", CONFIG, 0
|
|
LCD_STR_IO .DB "Disk #", 0
|
|
LCD_STR_XPU .DB " CPU",0
|
|
LCD_STR_SPD .DB "12.345",0
|
|
LCD_STR_MHZ .DB " MHz",0
|
|
;
|
|
LCD_CPU .DW LCD_CPU_Z80
|
|
.DW LCD_CPU_Z180
|
|
.DW LCD_CPU_Z180K
|
|
.DW LCD_CPU_Z180N
|
|
.DW LCD_CPU_Z280
|
|
.DW LCD_CPU_EZ80
|
|
;
|
|
LCD_CPU_Z80 .DB "Z80",0
|
|
LCD_CPU_Z180 .DB "Z180",0
|
|
LCD_CPU_Z180K .DB "Z180-K",0
|
|
LCD_CPU_Z180N .DB "Z180-N",0
|
|
LCD_CPU_Z280 .DB "Z280",0
|
|
LCD_CPU_EZ80 .DB "EZ80",0
|
|
|