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.
363 lines
9.7 KiB
363 lines
9.7 KiB
;
|
|
;==================================================================================================
|
|
; DSKY V1 ICM7218 (DISPLAY AND KEYBOARD) ROUTINES
|
|
;==================================================================================================
|
|
;
|
|
; THE ICM MAY COINCIDE ON THE SAME PPI BUS AS A PPISD. IT MAY NOT
|
|
; SHARE A PPI BUS WITH A PPIDE. SEE PPI_BUS.TXT FOR MORE INFORMATION.
|
|
;
|
|
; LED SEGMENTS (BIT VALUES)
|
|
;
|
|
; +--40--+
|
|
; 02 20
|
|
; +--04--+
|
|
; 08 10
|
|
; +--01--+ 80
|
|
;
|
|
; ICM SCAN CODES ARE ONE BYTE: CCRRRRRR
|
|
; BITS 7-6 IDENTFY THE COLUMN OF THE KEY PRESSED
|
|
; BITS 5-0 ARE A BITMAP, WITH A BIT ON TO INDICATE ROW OF KEY PRESSED
|
|
;
|
|
; ____PC0________PC1________PC2________PC3____
|
|
; PB5 | $20 [D] $60 [E] $A0 [F] $E0 [BO]
|
|
; PB4 | $10 [A] $50 [B] $90 [C] $D0 [GO]
|
|
; PB3 | $08 [7] $48 [8] $88 [9] $C8 [EX]
|
|
; PB2 | $04 [4] $44 [5] $84 [6] $C4 [DE]
|
|
; PB1 | $02 [1] $42 [2] $82 [3] $C2 [EN]
|
|
; PB0 | $01 [FW] $41 [0] $81 [BK] $C1 [CL]
|
|
;
|
|
;
|
|
ICM_PPIA .EQU ICMPPIBASE + 0 ; PORT A
|
|
ICM_PPIB .EQU ICMPPIBASE + 1 ; PORT B
|
|
ICM_PPIC .EQU ICMPPIBASE + 2 ; PORT C
|
|
ICM_PPIX .EQU ICMPPIBASE + 3 ; PPI CONTROL PORT
|
|
;
|
|
DEVECHO "ICM: IO="
|
|
DEVECHO ICMPPIBASE
|
|
DEVECHO "\n"
|
|
;
|
|
;__ICM_INIT__________________________________________________________________________________________
|
|
;
|
|
; CONFIGURE PARALLEL PORT AND CLEAR KEYPAD BUFFER
|
|
;____________________________________________________________________________________________________
|
|
;
|
|
ICM_PREINIT:
|
|
LD A,(DSKY_DISPACT) ; DSKY DISPATCHER ALREADY SET?
|
|
OR A ; SET FLAGS
|
|
RET NZ ; IF ALREADY ACTIVE, ABORT
|
|
;
|
|
OR $FF ; SIGNAL TO WAIT FOR KEY RELEASE
|
|
LD (ICM_KEYBUF),A ; SET IT
|
|
;
|
|
; PPI PORT B IS NORMALLY SET TO INPUT, BUT HERE WE
|
|
; TEMPORARILY SET IT TO OUTPUT. WHILE IN OUTPUT MODE, WE
|
|
; WRITE A VALUE OF $FF WHICH WILL BE PERSISTED BY THE PPI
|
|
; CHIP BUS HOLD CIRCUIT IF THERE IS NO ICM PRESENT. SO,
|
|
; WE CAN SUBSEQUENTLY TEST FOR PPIB=$FF TO SEE IF THERE IS
|
|
; NO ICM AND PREVENT PROBLEMS WITH PHANTOM ICM KEY PRESSES.
|
|
; IF A ICM IS PRESENT, IT WILL SIMPLY OVERPOWER THE PPI
|
|
; BUS HOLD CIRCUIT.
|
|
LD A,$80 ; PA OUT, PB OUT, PC OUT
|
|
OUT (ICM_PPIX),A
|
|
LD A,$FF ; SET PPIB=$FF, BUS HOLD
|
|
OUT (ICM_PPIB),A
|
|
;
|
|
LD A,$82 ; PA OUT, PB IN, PC OUT
|
|
OUT (ICM_PPIX),A
|
|
;
|
|
;IN A,(ICM_PPIB) ; *DEBUG*
|
|
;CALL PRTHEXBYTE ; *DEBUG*
|
|
;
|
|
IN A,(ICM_PPIB) ; READ PPIB
|
|
XOR $FF ; INVERT RESULT
|
|
;
|
|
CALL ICM_RESET
|
|
;
|
|
RET Z ; BAIL OUT NOW IF NOT PRESENT
|
|
;
|
|
; RECORD HARDWARE PRESENT
|
|
LD A,$FF
|
|
LD (ICM_PRESENT),A
|
|
;
|
|
; REGISTER DRIVER WITH HBIOS
|
|
LD BC,ICM_DISPATCH
|
|
CALL DSKY_SETDISP
|
|
;
|
|
RET
|
|
;
|
|
ICM_INIT:
|
|
CALL NEWLINE ; FORMATTING
|
|
PRTS("ICM:$") ; FORMATTING
|
|
;
|
|
PRTS(" IO=0x$") ; FORMATTING
|
|
LD A,ICMPPIBASE ; GET BASE PORT
|
|
CALL PRTHEXBYTE ; PRINT BASE PORT
|
|
;
|
|
LD A,(ICM_PRESENT) ; PRESENT?
|
|
OR A ; SET FLAGS
|
|
RET NZ ; YES, ALL DONE
|
|
PRTS(" NOT PRESENT$") ; NOT PRESENT
|
|
;
|
|
RET
|
|
;
|
|
; ICM DEVICE FUNCTION DISPATCH ENTRY
|
|
; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR
|
|
; B: FUNCTION (IN)
|
|
;
|
|
ICM_DISPATCH:
|
|
LD A,B ; GET REQUESTED FUNCTION
|
|
AND $0F ; ISOLATE SUB-FUNCTION
|
|
JP Z,ICM_RESET ; RESET DSKY HARDWARE
|
|
DEC A
|
|
JP Z,ICM_STAT ; GET KEYPAD STATUS
|
|
DEC A
|
|
JP Z,ICM_GETKEY ; READ A KEY FROM THE KEYPAD
|
|
DEC A
|
|
JP Z,ICM_SHOWHEX ; DISPLAY A 32-BIT BINARY VALUE IN HEX
|
|
DEC A
|
|
JP Z,ICM_SHOWSEG ; DISPLAY SEGMENTS
|
|
DEC A
|
|
JP Z,ICM_KEYLEDS ; SET KEYPAD LEDS
|
|
DEC A
|
|
JP Z,ICM_STATLED ; SET STATUS LED
|
|
DEC A
|
|
JP Z,ICM_BEEP ; BEEP DSKY SPEAKER
|
|
DEC A
|
|
JP Z,ICM_DEVICE ; DEVICE INFO
|
|
SYSCHKERR(ERR_NOFUNC)
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
ICM_RESET:
|
|
PUSH AF
|
|
LD A,$70 ; PPISD AND 7218 INACTIVE
|
|
OUT (ICM_PPIC),A
|
|
POP AF
|
|
RET
|
|
;
|
|
; CHECK FOR KEY PRESS, SAVE RAW VALUE, RETURN STATUS
|
|
;
|
|
ICM_STAT:
|
|
LD A,(ICM_KEYBUF) ; GET CURRENT BUF VAL
|
|
CP $FF ; $FF MEANS WE ARE WAITING FOR PREV KEY TO BE RELEASED
|
|
JR Z,ICM_STAT1 ; CHECK FOR PREV KEY RELEASE
|
|
OR A ; DO WE HAVE A SCAN CODE BUFFERED ALREADY?
|
|
RET NZ ; IF SO, WE ARE DONE
|
|
JR ICM_STAT2 ; OTHERWISE, DO KEY CHECK
|
|
|
|
ICM_STAT1:
|
|
; WAITING FOR PREVIOUS KEY RELEASE
|
|
CALL ICM_KEY ; SCAN
|
|
JR Z,ICM_STAT2 ; IF ZERO, PREV KEY RELEASED, CONTINUE
|
|
XOR A ; SIGNAL NO KEY PRESSED
|
|
RET ; AND DONE
|
|
|
|
ICM_STAT2:
|
|
CALL ICM_KEY ; SCAN
|
|
LD (ICM_KEYBUF),A ; SAVE RESULT
|
|
RET ; RETURN WITH ZF SET APPROPRIATELY
|
|
;
|
|
; WAIT FOR A ICM KEYPRESS AND RETURN
|
|
;
|
|
ICM_GETKEY:
|
|
CALL ICM_STAT ; CHECK STATUS
|
|
JR Z,ICM_GETKEY ; LOOP IF NOTHING READY
|
|
LD A,(ICM_KEYBUF)
|
|
LD B,24 ; SIZE OF DECODE TABLE
|
|
LD C,0 ; INDEX
|
|
LD HL,ICM_KEYMAP ; POINT TO BEGINNING OF TABLE
|
|
ICM_GETKEY1:
|
|
CP (HL) ; MATCH?
|
|
JR Z,ICM_GETKEY2 ; FOUND, DONE
|
|
INC HL
|
|
INC C ; BUMP INDEX
|
|
DJNZ ICM_GETKEY1 ; LOOP UNTIL EOT
|
|
ICM_GETKEY1A:
|
|
LD A,$FF ; NOT FOUND ERR, RETURN $FF
|
|
RET
|
|
ICM_GETKEY2:
|
|
LD A,$FF ; SET KEY BUF TO $FF
|
|
LD (ICM_KEYBUF),A ; DO IT
|
|
; RETURN THE INDEX POSITION WHERE THE SCAN CODE WAS FOUND
|
|
LD E,C ; RETURN INDEX VALUE
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
; DISPLAY HEX VALUE FROM DE:HL
|
|
;
|
|
ICM_SHOWHEX:
|
|
LD BC,DSKY_HEXBUF ; POINT TO HEX BUFFER
|
|
CALL ST32 ; STORE 32-BIT BINARY THERE
|
|
LD HL,DSKY_HEXBUF ; FROM: BINARY VALUE (HL)
|
|
LD DE,DSKY_BUF ; TO: SEGMENT BUFFER (DE)
|
|
CALL DSKY_BIN2SEG ; CONVERT
|
|
LD HL,DSKY_BUF ; POINT TO SEGMENT BUFFER
|
|
; AND FALL THRU TO DISPLAY IT
|
|
;
|
|
; ICM SHOW BUFFER
|
|
; HL: ADDRESS OF BUFFER
|
|
;
|
|
ICM_SHOWSEG:
|
|
LD A,82H ; SETUP PPI
|
|
OUT (ICM_PPIX),A
|
|
CALL ICM_COFF
|
|
LD A,$F0 ; 7218 -> (DATA COMING, NO DECODE)
|
|
OUT (ICM_PPIA),A
|
|
CALL ICM_STROBEC ; STROBE COMMAND
|
|
LD B,DSKY_BUFLEN ; NUMBER OF DIGITS
|
|
LD C,ICM_PPIA
|
|
ICM_HEXOUT2:
|
|
LD A,(HL)
|
|
CALL ICM_XLAT ; MAP SEGMENTS
|
|
XOR $80 ; FIX DOT POLARITY
|
|
OUT (C),A
|
|
INC HL
|
|
DEC B
|
|
JP Z,ICM_STROBE ; DO FINAL STROBE AND RETURN
|
|
CALL ICM_STROBE ; STROBE BYTE VALUE
|
|
JR ICM_HEXOUT2
|
|
ICM_STROBEC: ; COMMAND STROBE
|
|
LD A,80H | 30H
|
|
JP ICM_STROBE0
|
|
ICM_STROBE: ; DATA STROBE
|
|
LD A,00H | 30H ; SET WRITE STROBE
|
|
ICM_STROBE0:
|
|
OUT (ICM_PPIC),A ; OUT TO PORTC
|
|
CALL DLY2 ; DELAY
|
|
ICM_COFF:
|
|
LD A,40H | 30H ; QUIESCE
|
|
OUT (ICM_PPIC),A ; OUT TO PORTC
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
ICM_KEYLEDS:
|
|
ICM_STATLED:
|
|
ICM_BEEP:
|
|
XOR A ; PRETEND SUCCESS
|
|
RET
|
|
;
|
|
; DEVICE INFORMATION
|
|
;
|
|
ICM_DEVICE:
|
|
LD D,DSKYDEV_ICM ; D := DEVICE TYPE
|
|
LD E,0 ; E := PHYSICAL DEVICE NUMBER
|
|
LD H,0 ; H := MODE
|
|
LD L,ICMPPIBASE ; L := BASE I/O ADDRESS
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
;__ICM_KEY___________________________________________________________________________________________
|
|
;
|
|
; CHECK FOR KEY PRESS W/ DEBOUNCE
|
|
;____________________________________________________________________________________________________
|
|
;
|
|
ICM_KEY:
|
|
CALL ICM_SCAN ; INITIAL KEY PRESS SCAN
|
|
LD E,A ; SAVE INITIAL SCAN VALUE
|
|
ICM_KEY1:
|
|
; MAX BOUNCE TIME FOR OMRON B3F IS 3MS
|
|
PUSH DE ; SAVE DE
|
|
LD DE,300 ; ~3MS DELAY
|
|
CALL VDELAY ; DO IT
|
|
CALL ICM_SCAN ; REPEAT SCAN
|
|
POP DE ; RESTORE DE
|
|
RET Z ; IF NOTHING PRESSED, DONE
|
|
CP E ; SAME?
|
|
JR ICM_KEY2 ; YES, READY TO RETURN
|
|
LD E,A ; OTHERWISE, SAVE NEW SCAN VAL
|
|
JR ICM_KEY1 ; AND LOOP UNTIL STABLE VALUE
|
|
ICM_KEY2:
|
|
OR A ; SET FLAGS BASED ON VALUE
|
|
RET ; AND DONE
|
|
;
|
|
;__ICM_SCAN__________________________________________________________________________________________
|
|
;
|
|
; SCAN KEYPAD AND RETURN RAW SCAN CODE (RETURNS ZERO IF NO KEY PRESSED)
|
|
;____________________________________________________________________________________________________
|
|
;
|
|
ICM_SCAN:
|
|
LD B,4 ; 4 COLUMNS
|
|
LD C,$01 ; FIRST COLUMN
|
|
LD E,0 ; INITIAL COL ID
|
|
ICM_SCAN1:
|
|
LD A,C ; COL TO A
|
|
OR $70 ; KEEP PPISD AND 7218 INACTIVE
|
|
OUT (ICM_PPIC),A ; ACTIVATE COL
|
|
IN A,(ICM_PPIB) ; READ ROW BITS
|
|
AND $3F ; MASK, WE ONLY HAVE 6 ROWS, OTHERS UNDEFINED
|
|
JR NZ,ICM_SCAN2 ; IF NOT ZERO, GOT SOMETHING
|
|
RLC C ; NEXT COL
|
|
INC E ; BUMP COL ID
|
|
DJNZ ICM_SCAN1 ; LOOP THROUGH ALL COLS
|
|
XOR A ; NOTHING FOUND, RETURN ZERO
|
|
JP ICM_RESET ; RETURN VIA RESET
|
|
ICM_SCAN2:
|
|
RRC E ; MOVE COL ID
|
|
RRC E ; ... TO HIGH BITS 6 & 7
|
|
OR E ; COMBINE WITH ROW
|
|
JP ICM_RESET ; RETURN VIA RESET
|
|
;
|
|
;
|
|
; CONVERT FORM STANDARD SEGMENT ENCODING TO ICM ENCODING
|
|
;
|
|
; From: To:
|
|
; +--01--+ +--40--+
|
|
; 20 02 02 20
|
|
; +--40--+ +--04--+
|
|
; 10 04 08 10
|
|
; +--08--+ 80 +--01--+ 80
|
|
;
|
|
ICM_XLAT:
|
|
PUSH BC
|
|
PUSH HL
|
|
LD C,A ; ORIG VALUE TO C
|
|
XOR A ; INIT RESULT VALUE
|
|
LD B,8
|
|
LD HL,ICM_XTBL
|
|
ICM_XLAT1:
|
|
RRC C ; SHIFT NEXT BIT TO CF
|
|
JR NC,ICM_XLAT2 ; SKIP IF BIT NOT SET
|
|
OR (HL)
|
|
ICM_XLAT2:
|
|
INC HL
|
|
DJNZ ICM_XLAT1
|
|
POP HL
|
|
POP BC
|
|
RET
|
|
;
|
|
ICM_XTBL .DB $40, $20, $10, $01, $08, $02, $04, $80
|
|
;
|
|
;_ _TABLE_____________________________________________________________________________________________________________
|
|
;
|
|
ICM_KEYMAP:
|
|
; POS $00 $01 $02 $03 $04 $05 $06 $07
|
|
; KEY [0] [1] [2] [3] [4] [5] [6] [7]
|
|
.DB $41, $02, $42, $82, $04, $44, $84, $08
|
|
;
|
|
; POS $08 $09 $0A $0B $0C $0D $0E $0F
|
|
; KEY [8] [9] [A] [B] [C] [D] [E] [F]
|
|
.DB $48, $88, $10, $50, $90, $20, $60, $A0
|
|
;
|
|
; POS $10 $11 $12 $13 $14 $15 $16 $17
|
|
; KEY [FW] [BK] [CL] [EN] [DE] [EX] [GO] [BO]
|
|
.DB $01, $81, $C1, $C2, $C4, $C8, $D0, $E0
|
|
;
|
|
; KBD WORKING STORAGE
|
|
;
|
|
ICM_KEYBUF .DB 0
|
|
;
|
|
;==================================================================================================
|
|
; UTILTITY FUNCTIONS
|
|
;==================================================================================================
|
|
;
|
|
;
|
|
;==================================================================================================
|
|
; STORAGE
|
|
;==================================================================================================
|
|
;
|
|
; SEG DISPLAY WORKING STORAGE
|
|
;
|
|
ICM_PRESENT .DB 0
|
|
|