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.
 
 
 
 
 
 

774 lines
16 KiB

;
;==================================================================================================
; DSKYNG (DISPLAY AND KEYBOARD NEXT GENERATION) ROUTINES
;==================================================================================================
;
; A DSKYNG CAN SHARE A PPI BUS WITH EITHER A PPIDE OR PPISD.
; SEE PPI_BUS.TXT FOR MORE INFORMATION.
;
; LED SEGMENTS (BIT VALUES)
;
; +--01--+
; 20 02
; +--40--+
; 10 04
; +--08--+ 80
;
; KEY CODE MAP (KEY CODES) CSCCCRRR
; ||||||||
; |||||+++-- ROW
; ||+++----- COL
; |+-------- SHIFT
; +--------- CONTROL
;
; 00 08 10 18 23
; 01 09 11 19 22
; 02 0A 12 1A 21
; 03 0B 13 1B 20
; 04 0C 14 1C SHIFT
; 05 0D 15 1D CTRL
;
; LED BIT MAP (BIT VALUES)
;
; $08 $09 $0A $0B $0C $0D $0E $0F
; --- --- --- --- --- --- --- ---
; 01 01 01 01 01
; 02 02 02 02 02
; 04 04 04 04 04
; 08 08 08 08 08
; 10 10 10 10 10
; 20 20 20 20 20 L1 L2 BUZZ
;
PPIA .EQU DSKYPPIBASE + 0 ; PORT A
PPIB .EQU DSKYPPIBASE + 1 ; PORT B
PPIC .EQU DSKYPPIBASE + 2 ; PORT C
PPIX .EQU DSKYPPIBASE + 3 ; PPI CONTROL PORT
;
DSKY_PPIX_RD: .EQU %10010010 ; PPIX VALUE FOR READS
DSKY_PPIX_WR: .EQU %10000010 ; PPIX VALUE FOR WRITES
;
; PIO CHANNEL C:
;
; 7 6 5 4 3 2 1 0
; RES 0 0 CS CS /RD /WR A0
;
; SETTING BITS 3 & 4 WILL ASSERT /CS ON 3279
; CLEAR BITS 1 OR 2 TO ASSERT READ/WRITE
;
DSKY_PPI_IDLE: .EQU %00000110
;
DSKY_CMD_CLR: .EQU %11011111 ; CLEAR (ALL OFF)
DSKY_CMD_CLRX: .EQU %11010011 ; CLEAR (ALL ON)
DSKY_CMD_WDSP: .EQU %10010000 ; WRITE DISPLAY RAM
DSKY_CMD_RDSP: .EQU %01110000 ; READ DISPLAY RAM
DSKY_CMD_CLK: .EQU %00100000 ; SET CLK PRESCALE
DSKY_CMD_FIFO: .EQU %01000000 ; READ FIFO
;
DSKY_PRESCL: .EQU DSKYOSC/100000 ; PRESCALER
;
;__DSKY_PREINIT______________________________________________________________________________________
;
; CONFIGURE PARALLEL PORT AND INITIALIZE 8279
;____________________________________________________________________________________________________
;
;
; HARDWARE RESET 8279 BY PULSING RESET LINE
;
DSKY_PREINIT:
; CHECK FOR PPI
CALL DSKY_PPIDETECT ; TEST FOR PPI HARDWARE
RET NZ ; BAIL OUT IF NOT THERE
; SETUP PPI TO DEFAULT MODE
CALL DSKY_PPIRD
; INIT 8279 VALUES TO IDLE STATE
LD A,DSKY_PPI_IDLE
OUT (PPIC),A
; PULSE RESET SIGNAL ON 8279
SET 7,A
OUT (PPIC),A
RES 7,A
OUT (PPIC),A
; INITIALIZE 8279
CALL DSKY_REINIT
; NOW SEE IF A DSKYNG IS REALLY THERE...
LD A,$A5
LD (DSKY_BUF),A
LD HL,DSKY_BUF
LD C,0
LD B,1
CALL DSKY_PUTSTR
LD HL,DSKY_BUF
LD C,0
LD B,1
CALL DSKY_GETSTR
LD A,(DSKY_BUF)
CP $A5
RET NZ ; BAIL OUT IF MISCOMPARE
LD A,$FF
LD (DSKY_PRESENT),A
RET
;
DSKY_REINIT:
CALL DSKY_PPIIDLE
; SET CLOCK SCALER TO 20
LD A,DSKY_CMD_CLK | DSKY_PRESCL
CALL DSKY_CMD
; FALL THRU
;
DSKY_RESET:
; RESET DSKY -- CLEAR RAM AND FIFO
LD A,DSKY_CMD_CLR
CALL DSKY_CMD
;
; 8259 TAKES ~160US TO CLEAR RAM DURING WHICH TIME WRITES TO
; DISPLAY RAM ARE INHIBITED. HIGH BIT OF STATUS BYTE IS SET
; DURING THIS WINDOW. TO PREVENT A DEADLOCK, A LOOP COUNTER
; IS USED TO IMPLEMENT A TIMEOUT.
LD B,0 ; TIMEOUT LOOP COUNTER
DSKY_RESET1:
PUSH BC ; SAVE COUNTER
CALL DSKY_ST ; GET STATUS BYTE
POP BC ; RECOVER COUNTER
BIT 7,A ; BIT 7 IS DISPLAY RAM BUSY
JR Z,DSKY_RESET2 ; MOVE ON IF DONE
DJNZ DSKY_RESET1 ; LOOP TILL TIMEOUT
;
DSKY_RESET2:
RET
;
;__DSKY_INIT_________________________________________________________________________________________
;
; DISPLAY DSKY INFO
;____________________________________________________________________________________________________
;
#IFDEF HBIOS
;
DSKY_INIT:
CALL NEWLINE ; FORMATTING
PRTS("DSKY:$") ; FORMATTING
;
PRTS(" IO=0x$") ; FORMATTING
LD A,DSKYPPIBASE ; GET BASE PORT
CALL PRTHEXBYTE ; PRINT BASE PORT
PRTS(" MODE=$") ; FORMATTING
PRTS("NG$") ; PRINT DSKY TYPE
;
LD A,(DSKY_PRESENT) ; PRESENT?
OR A ; SET FLAGS
RET NZ ; YES, ALL DONE
PRTS(" NOT PRESENT$") ; NOT PRESENT
RET ; DONE
;
#ENDIF
;
;__DSKY_PPIDETECT____________________________________________________________________________________
;
; PROBE FOR PPI HARDWARE
;____________________________________________________________________________________________________
;
DSKY_PPIDETECT:
;
; TEST FOR PPI EXISTENCE
; WE SETUP THE PPI TO WRITE, THEN WRITE A VALUE OF ZERO
; TO PORT A (DATALO), THEN READ IT BACK. IF THE PPI IS THERE
; THEN THE BUS HOLD CIRCUITRY WILL READ BACK THE ZERO. SINCE
; WE ARE IN WRITE MODE, AN IDE CONTROLLER WILL NOT BE ABLE TO
; INTERFERE WITH THE VALUE BEING READ.
CALL DSKY_PPIWR
;
LD C,PPIA ; PPI PORT A
XOR A ; VALUE ZERO
OUT (C),A ; PUSH VALUE TO PORT
IN A,(C) ; GET PORT VALUE
OR A ; SET FLAGS
RET ; AND RETURN
;
#IFDEF DSKY_KBD
;
KY_0 .EQU $00
KY_1 .EQU $01
KY_2 .EQU $02
KY_3 .EQU $03
KY_4 .EQU $04
KY_5 .EQU $05
KY_6 .EQU $06
KY_7 .EQU $07
KY_8 .EQU $08
KY_9 .EQU $09
KY_A .EQU $0A
KY_B .EQU $0B
KY_C .EQU $0C
KY_D .EQU $0D
KY_E .EQU $0E
KY_F .EQU $0F
KY_FW .EQU $10 ; FORWARD
KY_BK .EQU $11 ; BACKWARD
KY_CL .EQU $12 ; CLEAR
KY_EN .EQU $13 ; ENTER
KY_DE .EQU $14 ; DEPOSIT
KY_EX .EQU $15 ; EXAMINE
KY_GO .EQU $16 ; GO
KY_BO .EQU $17 ; BOOT
KY_F4 .EQU $18 ; F4
KY_F3 .EQU $19 ; F3
KY_F2 .EQU $20 ; F2
KY_F1 .EQU $21 ; F1
;
;__DSKY_STAT_________________________________________________________________________________________
;
; CHECK FOR KEY PRESS, SAVE RAW VALUE, RETURN STATUS
;____________________________________________________________________________________________________
;
DSKY_STAT:
LD A,(DSKY_PRESENT) ; DOES IT EXIST?
OR A ; SET FLAGS
RET Z ; ABORT WITH A=0 IF NOT THERE
CALL DSKY_ST
AND $0F ; ISOLATE THE CUR FIFO LEN
RET
;
;__DSKY_GETKEY_____________________________________________________________________________________
;
; WAIT FOR A DSKY KEYPRESS AND RETURN
;____________________________________________________________________________________________________
;
DSKY_GETKEY:
LD A,(DSKY_PRESENT) ; DOES IT EXIST?
OR A ; SET FLAGS
JR Z,DSKY_GETKEY1A ; ABORT IF NOT PRESENT
CALL DSKY_STAT
JR Z,DSKY_GETKEY ; LOOP IF NOTHING THERE
LD A,DSKY_CMD_FIFO
CALL DSKY_CMD
CALL DSKY_DIN
XOR %11000000 ; FLIP POLARITY OF SHIFT/CTL BITS
PUSH AF ; SAVE VALUE
AND $3F ; STRIP SHIFT/CTL BITS FOR LOOKUP
LD B,28 ; SIZE OF DECODE TABLE
LD C,0 ; INDEX
LD HL,DSKY_KEYMAP ; POINT TO BEGINNING OF TABLE
DSKY_GETKEY1:
CP (HL) ; MATCH?
JR Z,DSKY_GETKEY2 ; FOUND, DONE
INC HL
INC C ; BUMP INDEX
DJNZ DSKY_GETKEY1 ; LOOP UNTIL EOT
POP AF ; FIX STACK
DSKY_GETKEY1A:
LD A,$FF ; NOT FOUND ERR, RETURN $FF
RET
DSKY_GETKEY2:
; RETURN THE INDEX POSITION WHERE THE SCAN CODE WAS FOUND
; THE ORIGINAL SHIFT/CTRL BITS ARE RESTORED
POP AF ; RESTORE RAW VALUE
AND %11000000 ; ISOLATE SHIFT/CTRL BITS
OR C ; COMBINE WITH INDEX VALUE
RET
;
;_KEYMAP_TABLE_____________________________________________________________________________________________________________
;
DSKY_KEYMAP:
; POS $00 $01 $02 $03 $04 $05 $06 $07
; KEY [0] [1] [2] [3] [4] [5] [6] [7]
.DB $0D, $04, $0C, $14, $03, $0B, $13, $02
;
; POS $08 $09 $0A $0B $0C $0D $0E $0F
; KEY [8] [9] [A] [B] [C] [D] [E] [F]
.DB $0A, $12, $01, $09, $11, $00, $08, $10
;
; POS $10 $11 $12 $13 $14 $15 $16 $17
; KEY [FW] [BK] [CL] [EN] [DE] [EX] [GO] [BO]
.DB $05, $15, $1D, $1C, $1B, $1A, $19, $18
; POS $18 $19 $20 $21
; KEY [F4] [F3] [F2] [F1]
.DB $23, $22, $21, $20
;
#ENDIF ; DSKY_KBD
;
;==================================================================================================
; CONVERT 32 BIT BINARY TO 8 BYTE HEX SEGMENT DISPLAY
;==================================================================================================
;
; HL: ADR OF 32 BIT BINARY
; DE: ADR OF DEST LED SEGMENT DISPLAY BUFFER (8 BYTES)
;
DSKY_BIN2SEG:
PUSH HL
PUSH DE
LD B,4 ; 4 BYTES OF INPUT
EX DE,HL
DSKY_BIN2SEG1:
LD A,(DE) ; FIRST NIBBLE
SRL A
SRL A
SRL A
SRL A
PUSH HL
LD HL,DSKY_HEXMAP
CALL DSKY_ADDHLA
LD A,(HL)
POP HL
LD (HL),A
INC HL
LD A,(DE) ; SECOND NIBBLE
AND 0FH
PUSH HL
LD HL,DSKY_HEXMAP
CALL DSKY_ADDHLA
LD A,(HL)
POP HL
LD (HL),A
INC HL
INC DE ; NEXT BYTE
DJNZ DSKY_BIN2SEG1
POP DE
POP HL
RET
;
;==================================================================================================
; DSKY SHOW BUFFER
; HL: ADDRESS OF BUFFER
;==================================================================================================
;
DSKY_SHOW:
LD C,0 ; STARTING DISPLAY POSITION
LD B,DSKY_BUFLEN ; NUMBER OF CHARS
JP DSKY_PUTSTR
;
;==================================================================================================
; DSKYNG OUTPUT ROUTINES
;==================================================================================================
;
; SEND DSKY COMMAND BYTE IN REGISTER A
; TRASHES BC
;
DSKY_CMD:
LD B,$01
JR DSKY_DOUT2
;
; SEND DSKY DATA BYTE IN REGISTER A
; TRASHES BC
;
DSKY_DOUT:
LD B,$00
;
DSKY_DOUT2:
;
; SAVE INCOMING DATA BYTE
PUSH AF
;
; SET PPI LINE CONFIG TO WRITE MODE
CALL DSKY_PPIWR
;
; SETUP
LD C,PPIC
;
; SET ADDRESS FIRST
LD A,DSKY_PPI_IDLE
OR B
OUT (C),A
;
; ASSERT 8279 /CS
SET 3,A
SET 4,A
OUT (C),A
;
; PPIC WORKING VALUE TO REG B NOW
LD B,A
;
; ASSERT DATA BYTE VALUE
POP AF
OUT (PPIA),A
;
; PULSE /WR
RES 1,B
OUT (C),B
NOP ; MAY NOT BE NEEDED
SET 1,B
OUT (C),B
;
; DEASSERT /CS
RES 3,B
RES 4,B
OUT (C),B
;
; CLEAR ADDRESS BIT
RES 0,B
OUT (C),B
;
; DONE
CALL DSKY_PPIIDLE
RET
;
;==================================================================================================
; DSKYNG OUTPUT ROUTINES
;==================================================================================================
;
; RETURN DSKY STATUS VALUE IN A
; TRASHES BC
;
DSKY_ST:
LD B,$01
JR DSKY_DIN2
;
; RETURN NEXT DATA VALUE IN A
; TRASHES BC
;
DSKY_DIN:
LD B,$00
;
DSKY_DIN2:
; SET PPI LINE CONFIG TO READ MODE
CALL DSKY_PPIRD
;
; SETUP
LD C,PPIC
;
; SET ADDRESS FIRST
LD A,DSKY_PPI_IDLE
OR B
OUT (C),A
;
; ASSERT 8279 /CS
SET 3,A
SET 4,A
OUT (C),A
;
; PPIC WORKING VALUE TO REG B NOW
LD B,A
;
; ASSERT /RD
RES 2,B
OUT (C),B
;
; GET VALUE
IN A,(PPIA)
;
; DEASSERT /RD
SET 2,B
OUT (C),B
;
; DEASSERT /CS
RES 3,B
RES 4,B
OUT (C),B
;
; CLEAR ADDRESS BIT
RES 0,B
OUT (C),B
;
; DONE
CALL DSKY_PPIIDLE
RET
;
;==================================================================================================
; DSKYNG UTILITY ROUTINES
;==================================================================================================
;
; BLANK DSKYNG DISPLAY (WITHOUT USING CLEAR)
;
DSKY_BLANK:
LD A,DSKY_CMD_WDSP
CALL DSKY_CMD
LD B,16
DSKY_BLANK1:
PUSH BC
LD A,$FF
CALL DSKY_DOUT
POP BC
DJNZ DSKY_BLANK1
RET
;
; WRITE A RAW BYTE VALUE TO DSKY DISPLAY RAM
; AT LOCATION IN REGISTER C, VALUE IN A.
;
DSKY_PUTBYTE:
PUSH BC
PUSH AF
LD A,C
ADD A,DSKY_CMD_WDSP
CALL DSKY_CMD
POP AF
XOR $FF
CALL DSKY_DOUT
POP BC
RET
;
; READ A RAW BYTE VALUE FROM DSKY DISPLAY RAM
; AT LOCATION IN REGISTER C, VALUE RETURNED IN A
;
DSKY_GETBYTE:
PUSH BC
LD A,C
ADD A,DSKY_CMD_RDSP
CALL DSKY_CMD
CALL DSKY_DIN
XOR $FF
POP BC
RET
;
; WRITE A STRING OF RAW BYTE VALUES TO DSKY DISPLAY RAM
; AT LOCATION IN REGISTER C, LENGTH IN B, ADDRESS IN HL.
;
DSKY_PUTSTR:
PUSH BC
LD A,C
ADD A,DSKY_CMD_WDSP
CALL DSKY_CMD
POP BC
;
DSKY_PUTSTR1:
LD A,(HL)
XOR $FF
INC HL
PUSH BC
CALL DSKY_DOUT
POP BC
DJNZ DSKY_PUTSTR1
RET
;
; READ A STRING OF RAW BYTE VALUES FROM DSKY DISPLAY RAM
; AT LOCATION IN REGISTER C, LENGTH IN B, ADDRESS IN HL.
;
DSKY_GETSTR:
PUSH BC
LD A,C
ADD A,DSKY_CMD_RDSP
CALL DSKY_CMD
POP BC
;
DSKY_GETSTR1:
PUSH BC
CALL DSKY_DIN
POP BC
XOR $FF
LD (HL),A
INC HL
DJNZ DSKY_GETSTR1
RET
;
; This function is intended to update the LEDs. It expects 8 bytes
; following the call, and updates the entire matrix.
;
; EXAMPLE:
; CALL DSKY_PUTLED
; .DB $00,$00,$00,$00,$00,$00,$00,$00
;
DSKY_PUTLED:
EX (SP),HL
PUSH AF
PUSH BC
LD C,8
DSKY_PUTLED_1:
LD A,(HL)
PUSH BC
CALL DSKY_PUTBYTE
POP BC
INC C
INC HL
LD A,C
CP $10
JP NZ,DSKY_PUTLED_1
POP BC
POP AF
EX (SP),HL
RET
;
; This function is intended to beep the speaker on the DSKY
;
DSKY_BEEP:
PUSH AF
PUSH BC
LD C,$0F
CALL DSKY_GETBYTE
OR $20
LD C,$0F
CALL DSKY_PUTBYTE
;;; timer . . .
PUSH HL
LD hl,$8FFF
DSKY_BEEP1:
DEC HL
LD A,H
CP 0
JP NZ,DSKY_BEEP1
POP HL
LD C,$0F
CALL DSKY_GETBYTE
AND $DF
LD C,$0F
CALL DSKY_PUTBYTE
POP BC
POP AF
RET
;
; This function is intended to turn on DSKY L1
;
DSKY_L1ON:
PUSH AF
PUSH BC
LD C,$0D
CALL DSKY_GETBYTE
OR $20
LD C,$0D
CALL DSKY_PUTBYTE
POP BC
POP AF
RET
;
; This function is intended to turn on DSKY L2
;
DSKY_L2ON:
PUSH AF
PUSH BC
LD C,$0E
CALL DSKY_GETBYTE
OR $20
LD C,$0E
CALL DSKY_PUTBYTE
POP BC
POP AF
RET
;
; This function is intended to turn off DSKY L1
;
DSKY_L1OFF:
PUSH AF
PUSH BC
LD C,$0D
CALL DSKY_GETBYTE
AND $DF
LD C,$0D
CALL DSKY_PUTBYTE
POP BC
POP AF
RET
;
; This function is intended to turn off DSKY L2
;
DSKY_L2OFF:
PUSH AF
PUSH BC
LD C,$0E
CALL DSKY_GETBYTE
AND $DF
LD C,$0E
CALL DSKY_PUTBYTE
POP BC
POP AF
RET
;
;==================================================================================================
; DSKYNG LINE CONTROL ROUTINES
;==================================================================================================
;
; SETUP PPI FOR WRITING: PUT PPI PORT A IN OUTPUT MODE
; AVOID REWRTING PPIX IF ALREADY IN OUTPUT MODE
;
DSKY_PPIWR:
PUSH AF
;
; CHECK FOR WRITE MODE
LD A,(DSKY_PPIX_VAL)
CP DSKY_PPIX_WR
JR Z,DSKY_PPIWR1
;
; SET PPI TO WRITE MODE
LD A,DSKY_PPIX_WR
OUT (PPIX),A
LD (DSKY_PPIX_VAL),A
;
; RESTORE PORT C (MAY NOT BE NEEDED)
LD A,DSKY_PPI_IDLE
OUT (PPIC),A
;
DSKY_PPIWR1:
;
POP AF
RET
;
; SETUP PPI FOR READING: PUT PPI PORT A IN INPUT MODE
; AVOID REWRTING PPIX IF ALREADY IN INPUT MODE
;
DSKY_PPIRD:
PUSH AF
;
; CHECK FOR READ MODE
LD A,(DSKY_PPIX_VAL)
CP DSKY_PPIX_RD
JR Z,DSKY_PPIRD1
;
; SET PPI TO READ MODE
LD A,DSKY_PPIX_RD
OUT (PPIX),A
LD (DSKY_PPIX_VAL),A
;
DSKY_PPIRD1:
POP AF
RET
;
; RELEASE USE OF PPI
;
DSKY_PPIIDLE:
JR DSKY_PPIRD ; SAME AS READ MODE
;
;==================================================================================================
; UTILTITY FUNCTIONS
;==================================================================================================
;
DSKY_ADDHLA:
ADD A,L
LD L,A
RET NC
INC H
RET
;
;==================================================================================================
; STORAGE
;==================================================================================================
;
; CODES FOR NUMERICS
; HIGH BIT ALWAYS CLEAR TO SUPPRESS DECIMAL POINT
; SET HIGH BIT TO SHOW DECIMAL POINT
;
DSKY_HEXMAP:
.DB $3F ; 0
.DB $06 ; 1
.DB $5B ; 2
.DB $4F ; 3
.DB $66 ; 4
.DB $6D ; 5
.DB $7D ; 6
.DB $07 ; 7
.DB $7F ; 8
.DB $67 ; 9
.DB $77 ; A
.DB $7C ; B
.DB $39 ; C
.DB $5E ; D
.DB $79 ; E
.DB $71 ; F
;
DSKY_PPIX_VAL: .DB 0
DSKY_PRESENT: .DB 0
;
; SEG DISPLAY WORKING STORAGE
;
DSKY_BUF .FILL 8,0
DSKY_BUFLEN .EQU $ - DSKY_BUF
DSKY_HEXBUF .FILL 4,0
DSKY_HEXBUFLEN .EQU $ - DSKY_HEXBUF