diff --git a/Source/Apps/tstdksyng.asm b/Source/Apps/tstdksyng.asm new file mode 100644 index 00000000..1f56dec5 --- /dev/null +++ b/Source/Apps/tstdksyng.asm @@ -0,0 +1,765 @@ +; +;================================================================================================== +; DSKY V3 TEST APPLICATION +;================================================================================================== +; +; BUILD WITH TASM: +; tasm -t80 -g3 -fFF tstdsky.asm tstdsky.com tstdsky.lst +; +; z80asm -itstdsky.asm -ltstdsky.lst -otstdsky.com +; +; 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. +; +DSKY_OSC: EQU 2000000 ; OSCILLATOR FREQ IN HZ +; +BDOS: EQU FALSE ; BDOS OR DIRECT TO 8250ISH +; +UART: EQU $68 ; UART BASE IO ADDRESS +PPI_BASE: EQU $60 ; PPI BASE IO PORT +; +; LED SEGMENTS (BIT VALUES) +; +; +--01--+ +; 20 02 +; +--40--+ +; 10 04 +; +--08--+ 80 +; +; KEY CODE MAP (KEY CODES) --CCCRRR +; +; 00 08 10 18 +; 01 09 11 19 +; 02 0A 12 1A +; 03 0B 13 1B +; 04 0C 14 1C +; 05 0D 15 1D +; +; LED BIT MAP (BIT VALUES) +; +; $08 $09 $0A $0B +; --- --- --- --- +; 01 01 01 01 +; 02 02 02 02 +; 04 04 04 04 +; 08 08 08 08 +; 10 10 10 10 +; 20 20 20 20 +; +FALSE: EQU 0 +TRUE: EQU ~FALSE +; +PPIA: EQU PPI_BASE + 0 ; PORT A +PPIB: EQU PPI_BASE + 1 ; PORT B +PPIC: EQU PPI_BASE + 2 ; PORT C +PPIX: EQU PPI_BASE + 3 ; PIO 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 /RD /WR CS CS 0 0 A0 +; +; SETTING BITS 3 & 4 WILL ASSERT /CS ON 3279 +; CLEAR BITS 5 OR 6 TO ASSERT READ/WRITE +; +DSKY_PPI_IDLE: EQU %01100000 +; +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 Test Program, v1.2, 2021-06-26$" + CALL PRTSTRD + DB "\r\nPPI 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 + JR 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 + 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: --CCCRRR + 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 E,$01 ; STARTING VALUE +M5: + CALL CST ; CONSOLE STATUS + JR NZ,M8 ; ABORT IF KEY PRESSED + LD B,12 ; 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 +; +EXIT: +; + ; CLEAR ALL + LD A,DSKY_CMD_CLR + CALL DSKY_CMD +; + ; 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 +; + ; 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 +; +; ; DIAGNOSTIC +; LD A,'W' +; CALL COUT +; +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 +; +; ; DIAGNOSTIC +; LD A,'R' +; CALL COUT +; +DSKY_PPIRD1: + 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: +; + ; SETUP PPI + 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 + ; DONE + CALL DSKY_PPIIDLE + 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 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 5,B + OUT (C),B + NOP ; MAY NOT BE NEEDED + SET 5,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 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 6,B + OUT (C),B +; + ; GET VALUE + IN A,(PPIA) +; + ; DEASSERT /RD + SET 6,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 +; +; 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 + 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),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) ; 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 + 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 + POP AF + RET +; +; +; +USEDELAY: EQU FALSE + INCLUDE "./SOFTWARE/util.asm" +; +; STORAGE +; +DSKY_PPIX_VAL: DB 0 +; +DSPBUF: DS 16,0 +; +PAT1: DB $01,$02,$04,$08,$10,$20,$40,$80 + DB $11,$22,$44,$88,$FF,$FF,$FF,$FF +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 + DS STACKSIZ,0 +STACK: EQU $ +; + END