forked from MirrorRepos/RomWBW
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.
1188 lines
20 KiB
1188 lines
20 KiB
;
|
|
;==================================================================================================
|
|
; DSKY NEXT GENERATION TEST APPLICATION
|
|
;==================================================================================================
|
|
;
|
|
; TO BUILD:
|
|
;
|
|
; TASM -t80 -g3 -fFF TSTDSKNG.ASM TSTDSKNG.COM TSTDSKNG.LST
|
|
;
|
|
; PIO 82C55 I/O IS DECODED TO PORT $60-$67 (ADJUST BELOW AS NEEDED)
|
|
; ASSUMES UART AT PORT $68 (ADJUST BELOW AS NEEDED)
|
|
;
|
|
; THIS CODE IS BELIEVED TO BE COMPATIBLE WITH PPIDE OR PPISD
|
|
; RUNNING ON SAME PPI BUS.
|
|
;
|
|
FALSE: .EQU 0
|
|
TRUE: .EQU !FALSE
|
|
;
|
|
DSKY_OSC: .EQU 3000000 ; OSCILLATOR FREQ IN HZ
|
|
;
|
|
BDOS: .EQU TRUE ; BDOS OR DIRECT TO 8250ISH
|
|
DSKY_PROTO: .EQU FALSE ; SET FOR DSKYNG PROTOTYPE
|
|
;
|
|
UART_BASE: .EQU $68 ; UART BASE IO ADDRESS
|
|
PPI_BASE_DEF: .EQU $60 ; PPI BASE IO PORT
|
|
;
|
|
; 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 CONTROL
|
|
;
|
|
; LED BIT MAP (BIT VALUES)
|
|
;
|
|
; $08 $09 $0A $0B $0C
|
|
; --- --- --- --- ---
|
|
; 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
|
|
;
|
|
PPIA: .EQU 0 ; PORT A OFFSET
|
|
PPIB: .EQU 1 ; PORT B OFFSET
|
|
PPIC: .EQU 2 ; PORT C OFFSET
|
|
PPIX: .EQU 3 ; PIO CONTROL PORT OFFSET
|
|
;
|
|
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
|
|
;
|
|
;
|
|
#IF (DSKY_PROTO)
|
|
;
|
|
DSKY_PPI_IDLE: .EQU %01100000
|
|
;
|
|
DSKY_RDBIT .EQU 6
|
|
DSKY_WRBIT .EQU 5
|
|
;
|
|
#ELSE
|
|
;
|
|
DSKY_PPI_IDLE: .EQU %00000110
|
|
;
|
|
DSKY_RDBIT .EQU 2
|
|
DSKY_WRBIT .EQU 1
|
|
;
|
|
#ENDIF
|
|
;
|
|
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 DSKY_OSC / 100000 ; PRESCALER
|
|
;
|
|
.ORG $100
|
|
;
|
|
; SAVE PREVIOUS STACK POINTER, AND SWITCH TO OUR STACK
|
|
LD (STACKSAV),SP
|
|
LD SP,STACK
|
|
;
|
|
CALL PRTSTRD
|
|
.DB "\r\nNextGenDSKY$"
|
|
;
|
|
#IF (DSKY_PROTO)
|
|
CALL PRTSTRD
|
|
.DB " Prototype$"
|
|
#ENDIF
|
|
;
|
|
CALL PRTSTRD
|
|
.DB " Test Program, v1.4a, 2021-07-18$"
|
|
;
|
|
CALL GET_BASE
|
|
JP NZ,EXIT
|
|
;
|
|
CALL PRTSTRD
|
|
.DB "\r\nDSKYng PPI base port: 0x$"
|
|
LD A,(PPI_BASE)
|
|
CALL PRTHEXBYTE
|
|
CALL NEWLINE
|
|
;
|
|
CALL DSKY_INIT
|
|
CALL DSKY_READ
|
|
;
|
|
CALL PRTSTRD
|
|
.DB "\r\nCLEAR Command (all ON)$"
|
|
LD A,DSKY_CMD_CLRX
|
|
CALL DSKY_CMD
|
|
CALL WAITKEY
|
|
CALL DSKY_READ
|
|
;
|
|
CALL PRTSTRD
|
|
.DB "\r\nCLEAR Command (all OFF)$"
|
|
LD A,DSKY_CMD_CLR
|
|
CALL DSKY_CMD
|
|
CALL WAITKEY
|
|
CALL DSKY_READ
|
|
;
|
|
CALL PRTSTRD
|
|
.DB "\r\nIndividual segments and LEDs$"
|
|
LD HL,PAT1
|
|
LD B,PAT1LN
|
|
LD C,0
|
|
CALL DSKY_PUTSTR
|
|
CALL WAITKEY
|
|
CALL DSKY_READ
|
|
;
|
|
CALL PRTSTRD
|
|
.DB "\r\nIncrementing segments and LEDs$"
|
|
LD HL,PAT2
|
|
LD B,PAT2LN
|
|
LD C,0
|
|
CALL DSKY_PUTSTR
|
|
CALL WAITKEY
|
|
CALL DSKY_READ
|
|
;
|
|
CALL PRTSTRD
|
|
.DB "\r\nOmit individual segments and LEDs$"
|
|
LD HL,PAT3
|
|
LD B,PAT3LN
|
|
LD C,0
|
|
CALL DSKY_PUTSTR
|
|
CALL WAITKEY
|
|
CALL DSKY_READ
|
|
;
|
|
; DISPLAY HEX DIGITS 0-7
|
|
;
|
|
CALL PRTSTRD
|
|
.DB "\r\nHex digits 0-7$"
|
|
LD HL,HEX1
|
|
LD B,HEX1LN
|
|
LD C,0
|
|
CALL DSKY_PUTENCSTR
|
|
CALL WAITKEY
|
|
CALL DSKY_READ
|
|
;
|
|
CALL PRTSTRD
|
|
.DB "\r\nHex digits 8-F$"
|
|
LD HL,HEX2
|
|
LD B,HEX2LN
|
|
LD C,0
|
|
CALL DSKY_PUTENCSTR
|
|
CALL WAITKEY
|
|
CALL DSKY_READ
|
|
;
|
|
CALL DSKY_BLANK
|
|
;
|
|
; WAIT FOR KEY THEN DISPLAY FIFO CONTENTS
|
|
CALL PRTSTRD
|
|
.DB "\r\nPress keys on pad (console key to end)...$"
|
|
;
|
|
; CLEAR BUFFER
|
|
LD HL,DSPBUF
|
|
LD A,$10
|
|
LD B,8
|
|
M1:
|
|
LD (HL),A
|
|
INC HL
|
|
DJNZ M1
|
|
;
|
|
; DISPLAY INIITAL BUFFER
|
|
LD B,8
|
|
LD C,0
|
|
LD HL,DSPBUF
|
|
CALL DSKY_PUTENCSTR
|
|
;
|
|
M2:
|
|
CALL CST ; CONSOLE STATUS
|
|
JP NZ,M4 ; ABORT IF KEY PRESSED
|
|
CALL DSKY_STAT
|
|
AND $3F ; DUMP 2 HIGH BITS
|
|
JR Z,M2 ; LOOP IF STATUS ZERO
|
|
CALL PRTSTRD
|
|
.DB "\r\nFIFO status=$"
|
|
CALL PRTHEXBYTE
|
|
AND $0F ; ISOLATE THE CUR FIFO LEN
|
|
JR Z,M2 ; LOOP IF NOTHING THERE
|
|
PUSH AF
|
|
LD A,DSKY_CMD_FIFO
|
|
CALL DSKY_CMD
|
|
POP BC ; B := CUR FIFO LEN
|
|
CALL PRTSTRD
|
|
.DB ", key code(s)=$"
|
|
|
|
M3:
|
|
PUSH BC
|
|
CALL DSKY_DIN
|
|
XOR %11000000 ; FLIP CONTROL & SHIFT MODIFIERS
|
|
CALL PRTHEXBYTE
|
|
CALL PC_SPACE
|
|
; SHIFT BUFFER
|
|
LD HL,DSPBUF+5
|
|
LD DE,DSPBUF+7
|
|
LD BC,6
|
|
LDDR
|
|
; PUT NEW VALUE AT START
|
|
PUSH AF
|
|
RRCA
|
|
RRCA
|
|
RRCA
|
|
RRCA
|
|
AND $0F
|
|
LD (DSPBUF),A
|
|
POP AF
|
|
PUSH AF
|
|
AND $0F
|
|
LD (DSPBUF+1),A
|
|
; UPDATE THE DISPLAY
|
|
LD B,8
|
|
LD C,0
|
|
LD HL,DSPBUF
|
|
CALL DSKY_PUTENCSTR
|
|
POP AF
|
|
; TOGGLE LED, KEY CODE: CSCCCRRR
|
|
PUSH AF
|
|
AND $07 ; ISOLATE ROW
|
|
LD B,A ; SAVE IN B
|
|
POP AF
|
|
RRCA
|
|
RRCA
|
|
RRCA
|
|
AND $07 ; ISOLATE COLUMN
|
|
LD C,A ; SAVE IN C
|
|
CALL DSKY_TOGLED ; TOGGLE LED AT ROW/COL
|
|
POP BC ; INSIDE LOOP COUNTER
|
|
DJNZ M3
|
|
JP M2 ; LOOP
|
|
M4:
|
|
CALL CIN ; DUMP PENDING CONSOLE KEY
|
|
;
|
|
; DANCING LIGHTS
|
|
CALL PRTSTRD
|
|
.DB "\r\nDance, Baby, Dance (console key to end)...$"
|
|
|
|
LD A,DSKY_CMD_CLR
|
|
CALL DSKY_CMD
|
|
;
|
|
|
|
|
|
|
|
LD E,$01 ; STARTING VALUE
|
|
M5:
|
|
CALL CST ; CONSOLE STATUS
|
|
JR NZ,M8 ; ABORT IF KEY PRESSED
|
|
LD B,16 ; NUMBER OF BYTES
|
|
LD C,$00 ; STARTING LOCATION (BYTE)
|
|
M6:
|
|
LD A,E
|
|
CALL DSKY_PUTBYTE
|
|
INC C ; NEXT LOCATION
|
|
DJNZ M6 ; INNER LOOP FOR ALL BYTES
|
|
RLC E ; ROTATE THE VALUE
|
|
LD B,0 ; DELAY LOOP
|
|
M7:
|
|
CALL DLY64
|
|
DJNZ M7
|
|
JR M5 ; REPEAT OUTER LOOP
|
|
M8:
|
|
CALL CIN ; DUMP PENDING CONSOLE KEY
|
|
;
|
|
; CLEAR ALL
|
|
LD A,DSKY_CMD_CLR
|
|
CALL DSKY_CMD
|
|
;
|
|
EXIT:
|
|
; GOODBYE
|
|
CALL PRTSTRD
|
|
.DB "\r\nThank you, please call again\r\n$"
|
|
;
|
|
; CLEAN UP AND RETURN TO OS
|
|
LD SP,(STACKSAV)
|
|
;
|
|
RET
|
|
;
|
|
; SETUP PPI FOR WRITING: PUT PPI PORT A IN OUTPUT MODE
|
|
; AVOID REWRTING PPIX IF ALREADY IN OUTPUT MODE
|
|
;
|
|
DSKY_PPIWR:
|
|
PUSH AF
|
|
PUSH BC
|
|
;
|
|
LD A,(PPI_BASE)
|
|
ADD A,PPIX
|
|
LD C,A
|
|
;
|
|
; CHECK FOR WRITE MODE
|
|
LD A,(PPIX_VAL)
|
|
CP DSKY_PPIX_WR
|
|
JR Z,DSKY_PPIWR1
|
|
;
|
|
; SET PPI TO WRITE MODE
|
|
LD A,DSKY_PPIX_WR
|
|
OUT (C),A
|
|
LD (PPIX_VAL),A
|
|
;
|
|
; RESTORE PORT C (MAY NOT BE NEEDED)
|
|
LD A,DSKY_PPI_IDLE
|
|
DEC C
|
|
OUT (C),A
|
|
;
|
|
DSKY_PPIWR1:
|
|
;
|
|
POP BC
|
|
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
|
|
PUSH BC
|
|
;
|
|
LD A,(PPI_BASE)
|
|
ADD A,PPIX
|
|
LD C,A
|
|
;
|
|
; CHECK FOR READ MODE
|
|
LD A,(PPIX_VAL)
|
|
CP DSKY_PPIX_RD
|
|
JR Z,DSKY_PPIRD1
|
|
;
|
|
; SET PPI TO READ MODE
|
|
LD A,DSKY_PPIX_RD
|
|
OUT (C),A
|
|
LD (PPIX_VAL),A
|
|
;
|
|
; RESTORE PORT C (MAY NOT BE NEEDED)
|
|
LD A,DSKY_PPI_IDLE
|
|
DEC C
|
|
OUT (C),A
|
|
;
|
|
DSKY_PPIRD1:
|
|
POP BC
|
|
POP AF
|
|
RET
|
|
;
|
|
; RELEASE USE OF PPI
|
|
;
|
|
DSKY_PPIIDLE:
|
|
JR DSKY_PPIRD ; SAME AS READ MODE
|
|
;
|
|
;
|
|
;
|
|
DSKY_INIT:
|
|
; RESET DSKY
|
|
CALL DSKY_RES
|
|
; SET CLOCK SCALER TO 20
|
|
LD A,DSKY_CMD_CLK | DSKY_PRESCL
|
|
CALL DSKY_CMD
|
|
LD A,%00001000 ; dan
|
|
CALL DSKY_CMD
|
|
;
|
|
RET
|
|
;
|
|
; HARDWARE RESET 8279 BY PULSING RESET LINE
|
|
;
|
|
DSKY_RES:
|
|
;
|
|
PUSH BC
|
|
LD A,(PPI_BASE)
|
|
ADD A,PPIC
|
|
LD C,A
|
|
; SETUP PPI
|
|
CALL DSKY_PPIRD
|
|
; INIT 8279 VALUES TO IDLE STATE
|
|
LD A,DSKY_PPI_IDLE
|
|
OUT (C),A
|
|
; PULSE RESET SIGNAL ON 8279
|
|
SET 7,A
|
|
OUT (C),A
|
|
RES 7,A
|
|
OUT (C),A
|
|
; DONE
|
|
CALL DSKY_PPIIDLE
|
|
POP BC
|
|
RET
|
|
;
|
|
; COMMAND IN A
|
|
; TRASHES BC
|
|
;
|
|
DSKY_CMD:
|
|
LD B,$01
|
|
JR DSKY_DOUT2
|
|
;
|
|
; DATA VALUE IN 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 A,(PPI_BASE)
|
|
ADD A,PPIC
|
|
LD C,A
|
|
;
|
|
; 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
|
|
DEC C
|
|
DEC C
|
|
POP AF
|
|
OUT (C),A
|
|
INC C
|
|
INC C
|
|
;
|
|
; PULSE /WR
|
|
RES DSKY_WRBIT,B
|
|
OUT (C),B
|
|
NOP ; MAY NOT BE NEEDED
|
|
SET DSKY_WRBIT,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
|
|
;
|
|
; STATUS VALUE IN A
|
|
; TRASHES BC
|
|
;
|
|
DSKY_STAT:
|
|
LD B,$01
|
|
JR DSKY_DIN2
|
|
;
|
|
; DATA VALUE RETURNED IN A
|
|
; TRASHES BC
|
|
;
|
|
DSKY_DIN:
|
|
LD B,$00
|
|
;
|
|
DSKY_DIN2:
|
|
; SET PPI LINE CONFIG TO WRITE MODE
|
|
CALL DSKY_PPIRD
|
|
;
|
|
; SETUP
|
|
LD A,(PPI_BASE)
|
|
ADD A,PPIC
|
|
LD C,A
|
|
;
|
|
; 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 DSKY_RDBIT,B
|
|
OUT (C),B
|
|
;
|
|
; GET VALUE
|
|
DEC C
|
|
DEC C
|
|
IN A,(C)
|
|
INC C
|
|
INC C
|
|
;
|
|
; DEASSERT /RD
|
|
SET DSKY_RDBIT,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
|
|
;
|
|
; BLANK THE 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
|
|
;
|
|
; HL IS ADR OF ENCODED STRING OF BYTES
|
|
; B IS LEN OF STRING (BYTES)
|
|
; C IS POSITION IN DISPLAY RAM TO WRITE
|
|
;
|
|
DSKY_PUTENCSTR:
|
|
PUSH BC
|
|
LD A,C
|
|
ADD A,DSKY_CMD_WDSP
|
|
CALL DSKY_CMD
|
|
POP BC
|
|
EX DE,HL
|
|
DSKY_PUTENCSTR1:
|
|
LD A,(DE)
|
|
INC DE
|
|
LD HL,HEXMAP
|
|
CALL ADDHLA
|
|
LD A,(HL)
|
|
XOR $FF
|
|
PUSH BC
|
|
CALL DSKY_DOUT
|
|
POP BC
|
|
DJNZ DSKY_PUTENCSTR1
|
|
RET
|
|
;
|
|
; TOGGLE LED AT ROW (B) AND COLUMN (C)
|
|
;
|
|
DSKY_TOGLED:
|
|
; CONVERT B (ROW) TO BIT VALUE
|
|
XOR A
|
|
INC B
|
|
SCF
|
|
DSKY_TOGLED1:
|
|
RLA
|
|
DJNZ DSKY_TOGLED1
|
|
LD B,A
|
|
; LED COLS START AT 8
|
|
LD A,8
|
|
ADD A,C
|
|
LD C,A
|
|
; FLIP THE BIT
|
|
CALL DSKY_GETBYTE ; GET CURRENT COL BITMAP
|
|
XOR B ; FLIP DESIRED BIT
|
|
CALL DSKY_PUTBYTE ; WRITE VLAUE BACK TO COLUMN
|
|
RET
|
|
;
|
|
; READ AND PRINT DISPLAY RAM (RAW BYTES)
|
|
;
|
|
DSKY_READ:
|
|
CALL PRTSTRD
|
|
.DB "\r\nRead display RAM: $"
|
|
LD B,16 ; 16 BYTES
|
|
LD C,0 ; POSITION 0
|
|
LD HL,DSPBUF
|
|
CALL DSKY_GETSTR
|
|
LD B,$10
|
|
LD HL,DSPBUF
|
|
DSKY_READ1:
|
|
LD A,(HL)
|
|
INC HL
|
|
CALL PC_SPACE
|
|
CALL PRTHEXBYTE
|
|
DJNZ DSKY_READ1
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
GET_BASE:
|
|
CALL PRTSTRD
|
|
.DB "\r\nDSKYng PPI base port [0x$"
|
|
LD A,(PPI_BASE)
|
|
CALL PRTHEXBYTE
|
|
CALL PRTSTRD
|
|
.DB "]: $"
|
|
LD A,(PPI_BASE)
|
|
CALL GETHEXBYTE
|
|
JR C,GET_BASE1
|
|
LD (PPI_BASE),A
|
|
XOR A
|
|
RET
|
|
;
|
|
GET_BASE1:
|
|
CALL PRTSTRD
|
|
.DB "\r\nInvalid DSKYng PPI base port value!$"
|
|
JR GET_BASE
|
|
;
|
|
; OUTPUT CHARACTER FROM A
|
|
;
|
|
COUT:
|
|
PUSH AF ;
|
|
PUSH BC ;
|
|
PUSH DE ;
|
|
PUSH HL ;
|
|
|
|
#IF (BDOS)
|
|
LD C,2 ; BDOS FUNC: CONSOLE OUTPUT
|
|
LD E,A ; CHARACTER TO E
|
|
CALL $0005 ; CALL BDOS
|
|
#ELSE
|
|
LD C,A
|
|
COUT1:
|
|
IN A,(UART_BASE + 05H) ; READ LINE STATUS REGISTER
|
|
AND 20H ; TEST IF UART IS READY TO SEND
|
|
JP Z,COUT1 ; IF NOT REPEAT
|
|
LD A,C ; GET TO ACCUMULATOR
|
|
OUT (UART_BASE),A ; THEN WRITE THE CHAR TO UART (UART0 = 068h + $00)
|
|
#ENDIF
|
|
|
|
POP HL ;
|
|
POP DE ;
|
|
POP BC ;
|
|
POP AF ;
|
|
RET ; DONE
|
|
;
|
|
; INPUT CHARACTER TO A
|
|
;
|
|
CIN:
|
|
PUSH BC ;
|
|
PUSH DE ;
|
|
PUSH HL ;
|
|
#IF BDOS
|
|
CIN1:
|
|
LD C,6 ; BDOS FUNC: DIRECT CONSOLE I/O
|
|
LD E,$FF ; SET FOR INPUT
|
|
CALL $0005 ; CALL BDOS, CHARACTER TO A
|
|
OR A ; CHECK FOR NO CHAR, $00
|
|
JR Z,CIN1 ; LOOP TIL WE GET A CHAR
|
|
#ELSE
|
|
CIN1:
|
|
CALL CST ; IS A CHAR READY TO BE READ FROM UART?
|
|
CP 00H ;
|
|
JP Z,CIN1 ; NO? TRY AGAIN
|
|
IN A,(UART_BASE) ; YES? READ THE CHAR FROM THE UART (UART0 = 068h + $00)
|
|
#ENDIF
|
|
POP HL ;
|
|
POP DE ;
|
|
POP BC ;
|
|
RET ; DONE
|
|
;
|
|
; RETURN INPUT STATUS IN A (0 = NO CHAR, !=0 CHAR WAITING)
|
|
;
|
|
CST:
|
|
PUSH BC ;
|
|
PUSH DE ;
|
|
PUSH HL ;
|
|
#IF BDOS
|
|
LD C,$0B ; BDOS FUNC: GET CONSOLE STATUS
|
|
CALL $0005 ; CALL BDOS
|
|
OR A ; SET FLAGS
|
|
#ELSE
|
|
; CONSOLE STATUS, RETURN 0FFH IF CHARACTER READY, 00H IF NOT
|
|
IN A,(UART_BASE + 05H) ; READ LINE STATUS REGISTER (UART5 = 068h + $05)
|
|
AND 01H ; TEST IF DATA IN RECEIVE BUFFER
|
|
; IS THERE A CHAR READY? 0=NO, 1=YES
|
|
JP Z,CST1 ;
|
|
LD A,0FFH ; YES, PUT 0FFh IN A AND RETURN
|
|
CST1: ;
|
|
; NO, LEAVE 000h IN A AND RETURN
|
|
#ENDIF
|
|
POP HL ;
|
|
POP DE ;
|
|
POP BC ;
|
|
RET ; DONE
|
|
;
|
|
; WAIT FOR A KEY
|
|
;
|
|
WAITKEY:
|
|
PUSH AF
|
|
CALL PRTSTRD
|
|
.DB ", press a key to continue...$"
|
|
CALL CIN
|
|
CP $1B
|
|
JP Z,EXIT
|
|
POP AF
|
|
RET
|
|
;
|
|
;==================================================================================================
|
|
; UTILITY FUNCTIONS
|
|
;==================================================================================================
|
|
;
|
|
;
|
|
CHR_BEL: .EQU 07H
|
|
CHR_CR: .EQU 0DH
|
|
CHR_LF: .EQU 0AH
|
|
CHR_BS: .EQU 08H
|
|
CHR_ESC: .EQU 1BH
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; UTILITY PROCS TO PRINT SINGLE CHARACTERS WITHOUT TRASHING ANY REGISTERS
|
|
;
|
|
PC_SPACE:
|
|
PUSH AF
|
|
LD A,' '
|
|
JR PC_PRTCHR
|
|
|
|
PC_PERIOD:
|
|
PUSH AF
|
|
LD A,'.'
|
|
JR PC_PRTCHR
|
|
|
|
PC_COLON:
|
|
PUSH AF
|
|
LD A,':'
|
|
JR PC_PRTCHR
|
|
|
|
PC_COMMA:
|
|
PUSH AF
|
|
LD A,','
|
|
JR PC_PRTCHR
|
|
|
|
PC_LBKT:
|
|
PUSH AF
|
|
LD A,'['
|
|
JR PC_PRTCHR
|
|
|
|
PC_RBKT:
|
|
PUSH AF
|
|
LD A,']'
|
|
JR PC_PRTCHR
|
|
|
|
PC_LT:
|
|
PUSH AF
|
|
LD A,'<'
|
|
JR PC_PRTCHR
|
|
|
|
PC_GT:
|
|
PUSH AF
|
|
LD A,'>'
|
|
JR PC_PRTCHR
|
|
|
|
PC_LPAREN:
|
|
PUSH AF
|
|
LD A,'('
|
|
JR PC_PRTCHR
|
|
|
|
PC_RPAREN:
|
|
PUSH AF
|
|
LD A,')'
|
|
JR PC_PRTCHR
|
|
|
|
PC_ASTERISK:
|
|
PUSH AF
|
|
LD A,'*'
|
|
JR PC_PRTCHR
|
|
|
|
PC_CR:
|
|
PUSH AF
|
|
LD A,CHR_CR
|
|
JR PC_PRTCHR
|
|
|
|
PC_LF:
|
|
PUSH AF
|
|
LD A,CHR_LF
|
|
JR PC_PRTCHR
|
|
|
|
PC_PRTCHR:
|
|
CALL COUT
|
|
POP AF
|
|
RET
|
|
|
|
NEWLINE2:
|
|
CALL NEWLINE
|
|
NEWLINE:
|
|
CALL PC_CR
|
|
CALL PC_LF
|
|
RET
|
|
;
|
|
; PRINT A CHARACTER REFERENCED BY POINTER AT TOP OF STACK
|
|
; USAGE:
|
|
; CALL PRTCH
|
|
; DB 'X'
|
|
;
|
|
PRTCH:
|
|
EX (SP),HL
|
|
PUSH AF
|
|
LD A,(HL)
|
|
CALL COUT
|
|
POP AF
|
|
INC HL
|
|
EX (SP),HL
|
|
RET
|
|
;
|
|
; PRINT A STRING AT ADDRESS SPECIFIED IN HL
|
|
; STRING MUST BE TERMINATED BY '$'
|
|
; USAGE:
|
|
; LD HL,MYSTR
|
|
; CALL PRTSTR
|
|
; ...
|
|
; MYSTR: DB "HELLO$"
|
|
;
|
|
PRTSTR:
|
|
LD A,(HL)
|
|
INC HL
|
|
CP '$'
|
|
RET Z
|
|
CALL COUT
|
|
JR PRTSTR
|
|
;
|
|
; PRINT A STRING DIRECT: REFERENCED BY POINTER AT TOP OF STACK
|
|
; STRING MUST BE TERMINATED BY '$'
|
|
; USAGE:
|
|
; CALL PRTSTRD
|
|
; DB "HELLO$"
|
|
; ...
|
|
;
|
|
PRTSTRD:
|
|
EX (SP),HL
|
|
PUSH AF
|
|
CALL PRTSTR
|
|
POP AF
|
|
EX (SP),HL
|
|
RET
|
|
;
|
|
; PRINT A STRING INDIRECT: REFERENCED BY INDIRECT POINTER AT TOP OF STACK
|
|
; STRING MUST BE TERMINATED BY '$'
|
|
; USAGE:
|
|
; CALL PRTSTRI(MYSTRING)
|
|
; MYSTRING DB "HELLO$"
|
|
;
|
|
PRTSTRI:
|
|
EX (SP),HL
|
|
PUSH AF
|
|
LD A,(HL)
|
|
INC HL
|
|
PUSH HL
|
|
LD H,(HL)
|
|
LD L,A
|
|
CALL PRTSTR
|
|
POP HL
|
|
INC HL
|
|
POP AF
|
|
EX (SP),HL
|
|
RET
|
|
;
|
|
; PRINT THE HEX BYTE VALUE IN A
|
|
;
|
|
PRTHEXBYTE:
|
|
PUSH AF
|
|
PUSH DE
|
|
CALL HEXASCII
|
|
LD A,D
|
|
CALL COUT
|
|
LD A,E
|
|
CALL COUT
|
|
POP DE
|
|
POP AF
|
|
RET
|
|
;
|
|
; PRINT THE HEX WORD VALUE IN BC
|
|
;
|
|
PRTHEXWORD:
|
|
PUSH AF
|
|
LD A,B
|
|
CALL PRTHEXBYTE
|
|
LD A,C
|
|
CALL PRTHEXBYTE
|
|
POP AF
|
|
RET
|
|
;
|
|
; PRINT THE HEX WORD VALUE IN HL
|
|
;
|
|
PRTHEXWORDHL:
|
|
PUSH AF
|
|
LD A,H
|
|
CALL PRTHEXBYTE
|
|
LD A,L
|
|
CALL PRTHEXBYTE
|
|
POP AF
|
|
RET
|
|
;
|
|
; CONVERT BINARY VALUE IN A TO ASCII HEX CHARACTERS IN DE
|
|
;
|
|
HEXASCII:
|
|
LD D,A
|
|
CALL HEXCONV
|
|
LD E,A
|
|
LD A,D
|
|
RLCA
|
|
RLCA
|
|
RLCA
|
|
RLCA
|
|
CALL HEXCONV
|
|
LD D,A
|
|
RET
|
|
;
|
|
; CONVERT LOW NIBBLE OF A TO ASCII HEX
|
|
;
|
|
HEXCONV:
|
|
AND 0FH ;LOW NIBBLE ONLY
|
|
ADD A,90H
|
|
DAA
|
|
ADC A,40H
|
|
DAA
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
GETHEXBYTE:
|
|
PUSH AF ; SAVE INCOMING VALUE
|
|
LD C,0AH ; BDOS READ CONSOLE BUFFER
|
|
LD DE,CONBUF
|
|
CALL 5 ; GET EDITED STRING
|
|
CALL NEWLINE
|
|
POP DE ; RESTORE INCOMING TO D
|
|
|
|
; OK WE SHOULD NOW HAVE A STRING WITH A HEX NUMBER
|
|
LD HL,CONBUF
|
|
INC HL
|
|
LD A,(HL) ; GET CHARACTER COUNT
|
|
INC HL
|
|
CP 3
|
|
JR C,GHB0 ; OK IF <= 2 CHARS
|
|
SCF ; SIGNAL ERROR
|
|
RET ; AND RETURN
|
|
|
|
GHB0:
|
|
OR A ; SET FLAGS
|
|
JR NZ,GHB1 ; GOT CHARS, GO AHEAD
|
|
LD A,D ; RESTORE INCOMING VALUE
|
|
OR A ; SIGNAL SUCCESS
|
|
RET ; AND DONE
|
|
|
|
GHB1:
|
|
LD B,A ; COUNT TO B
|
|
LD C,0 ; INITIAL VALUE
|
|
|
|
GHB2:
|
|
LD A,(HL) ; GET NEXT CHAR
|
|
INC HL
|
|
CALL ISHEX
|
|
RET C ; ABORT ON NON-HEX CHAR
|
|
|
|
; OK WE ARE HERE WHEN WE HAVE A VALID CHARACTER (0-9,A-F,A-F) NEED TO CONVERT TO BINARY
|
|
; CHARACTER IS STILL IN A
|
|
|
|
CP 3AH ; TEST FOR 0-9
|
|
JP M,GHB2C
|
|
CP 47H ; TEST FOR A-F
|
|
JP M,GHB2B
|
|
CP 67H ; TEST FOR A-F
|
|
JP M,GHB2A
|
|
GHB2A: SUB 20H ; CHARACTER IS A-F
|
|
GHB2B: SUB 07H ; CHARACTER IS A-F
|
|
GHB2C: SUB 30H ; CHARACTER IS 0-9
|
|
|
|
RLC C ; MULTIPLY CUR VALUE BY 16
|
|
RLC C
|
|
RLC C
|
|
RLC C
|
|
ADD A,C ; ADD TO ACCUM
|
|
LD C,A ; PUT BACK IN C
|
|
|
|
DJNZ GHB2 ; LOOP THRU ALL CHARS
|
|
|
|
LD A,C ; INTO A FOR RETURN
|
|
OR A ; SIGNAL SUCCESS
|
|
RET ; DONE
|
|
|
|
ISHEX:
|
|
CP 30H ; CHECK IF LESS THAN CHARACTER 0
|
|
JP M,NOTHEX
|
|
CP 3AH ; CHECK FOR > 9
|
|
JP M,ISHX1 ; OK, CHARACTER IS 1-9
|
|
|
|
CP 41H ; CHECK FOR CHARACTER LESS THAN A
|
|
JP M,NOTHEX
|
|
CP 47H ; CHECK FOR CHARACTERS > F
|
|
JP M,ISHX1
|
|
|
|
CP 61H ; CHECK FOR CHARACTERS < A
|
|
JP M,NOTHEX
|
|
|
|
CP 67H ; CHECK FOR CHARACTER > F
|
|
JP M,ISHX1
|
|
NOTHEX:
|
|
SCF ; SET CARRY TO INDICATE FAIL
|
|
RET
|
|
|
|
ISHX1:
|
|
SCF
|
|
CCF
|
|
RET
|
|
;
|
|
; SHORT DELAY FUNCTIONS. NO CLOCK SPEED COMPENSATION, SO THEY
|
|
; WILL RUN LONGER ON SLOWER SYSTEMS. THE NUMBER INDICATES THE
|
|
; NUMBER OF CALL/RET INVOCATIONS. A SINGLE CALL/RET IS
|
|
; 27 T-STATES ON A Z80, 25 T-STATES ON A Z180
|
|
;
|
|
; ; Z80 Z180
|
|
; ; ---- ----
|
|
DLY64: CALL DLY32 ; 1728 1600
|
|
DLY32: CALL DLY16 ; 864 800
|
|
DLY16: CALL DLY8 ; 432 400
|
|
DLY8: CALL DLY4 ; 216 200
|
|
DLY4: CALL DLY2 ; 108 100
|
|
DLY2: CALL DLY1 ; 54 50
|
|
DLY1: RET ; 27 25
|
|
;
|
|
; ADD HL,A
|
|
;
|
|
; A REGISTER IS DESTROYED!
|
|
;
|
|
ADDHLA:
|
|
ADD A,L
|
|
LD L,A
|
|
RET NC
|
|
INC H
|
|
RET
|
|
;
|
|
; STORAGE
|
|
;
|
|
PPI_BASE: .DB PPI_BASE_DEF
|
|
;
|
|
CONBUF: .DB 8 ; MAXIMUM CHARS
|
|
.DB 0 ; COUNT
|
|
.FILL 8 ; SIZE OF BUFFER
|
|
;
|
|
PPIX_VAL: .DB 0
|
|
;
|
|
DSPBUF: .FILL 16,0
|
|
;
|
|
PAT1: .DB $01,$02,$04,$08,$10,$20,$40,$80
|
|
.DB $11,$22,$44,$88,$00,$00,$00,$00
|
|
PAT1LN: .EQU $ - PAT1
|
|
PAT2: .DB $01,$03,$07,$0F,$1F,$3F,$7F,$FF
|
|
.DB $11,$33,$77,$FF,$00,$00,$00,$00
|
|
PAT2LN: .EQU $ - PAT2
|
|
PAT3: .DB $FE,$FD,$FB,$F7,$EF,$DF,$BF,$7F
|
|
.DB $77,$BB,$DD,$EE,$00,$00,$00,$00
|
|
PAT3LN: .EQU $ - PAT3
|
|
BLANK: .DB $00,$00,$00,$00,$00,$00,$00,$00
|
|
.DB $00,$00,$00,$00,$00,$00,$00,$00
|
|
BLNKLN: .EQU $ - BLANK
|
|
HEX1: .DB $0,$1,$2,$3,$4,$5,$6,$7
|
|
HEX1LN: .EQU $ - HEX1
|
|
HEX2: .DB $8,$9,$A,$B,$C,$D,$E,$F
|
|
HEX2LN: .EQU $ - HEX2
|
|
;
|
|
HEXMAP:
|
|
; '0' '1' '2' '3' '4' '5' '6' '7'
|
|
.DB $3F, $06, $5B, $4F, $66, $6D, $7D, $07
|
|
; '8' '9' 'A' 'B' 'C' 'D' 'E' 'F'
|
|
.DB $7F, $67, $77, $7C, $39, $5E, $79, $71
|
|
;
|
|
.DB $00
|
|
;
|
|
STACKSAV: .DW 0
|
|
STACKSIZ: .EQU $100 ; WE ARE A STACK PIG
|
|
.FILL STACKSIZ,0
|
|
STACK: .EQU $
|
|
;
|
|
.END
|
|
|