Files
TZFS/asm/testtz.asm

2255 lines
83 KiB
NASM

i;--------------------------------------------------------------------------------------------------------
;-
;- Name: testtz.asm
;- Created: June 2020
;- Author(s): Philip Smart
;- Description: tranZPUter tester program
;- A small program to exercise parts of the tranZPUter to aid in problem resolution.
;-
;- Credits:
;- Copyright: (c) 2019-20 Philip Smart <philip.smart@net2net.org>
;-
;- History: Jun 2020 - Initial version.
;-
;--------------------------------------------------------------------------------------------------------
;- This source file is free software: you can redistribute it and-or modify
;- it under the terms of the GNU General Public License as published
;- by the Free Software Foundation, either version 3 of the License, or
;- (at your option) any later version.
;-
;- This source file is distributed in the hope that it will be useful,
;- but WITHOUT ANY WARRANTY; without even the implied warranty of
;- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;- GNU General Public License for more details.
;-
;- You should have received a copy of the GNU General Public License
;- along with this program. If not, see <http://www.gnu.org/licenses/>.
;--------------------------------------------------------------------------------------------------------
INCLUDE "testtz_definitions.asm"
INCLUDE "macros.asm"
ORG 10F0h
; Tape header (MZF) - this program is a loadable executable.
DB 01h ; Code Type, 01 = Machine Code.
DB "TZTESTER V1.0", 0Dh, 00h, 00h, 00h ; Title/Name (17 bytes).
DW PGMEND - START ; Size of program.
DW START ; Load address of program.
DW START ; Exec address of program.
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h ; Comment (104 bytes).
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
ORG 01200h
START: DI ; Disable Interrupts and sat mode. NB. Interrupts are physically disabled by 8255 Port C2 set to low.
IM 1
;
INIT1: LD SP,BOOTSTACK ; Setup to use local stack until CPM takes over.
;
LD HL,LVARSTART ; Start of local page variable area
LD BC,LVAREND-LVARSTART ; Size of local page variable area.
XOR A
LD D,A
INIT2: LD (HL),D ; Clear variable memory.
INC HL
DEC BC
LD A,B
OR C
JR NZ,INIT2
;
CALL MODE ; Configure 8255 port C, set Motor Off, VGATE to 1 (off) and INTMSK to 0 (interrupts disabled).
LD A,016H
CALL PRNT
LD A,017H ; Blue background, white characters in colour mode. Bit 7 is set as a write to bit 7 @ DFFFH selects 80Char mode.
LD HL,ARAM
CALL CLR8
LD A,004H
LD (TEMPW),A ; Setup the tempo for sound output.
INIT3: ; Setup the initial cursor, for CAPSLOCK this is a double underscore.
LD A,080H ; Cursor on (Bit D7=1).
LD (FLASHCTL),A
; Change to 80 character mode.
LD A, 128 ; 80 char mode.
LD (DSPCTL), A
CALL MLDSP
CALL NL
INIT4: LD DE,TESTTZSIGNON
CALL MONPRTSTR
CALL BEL ; Beep to indicate startup - for cases where screen is slow to startup.
LD A,0FFH
LD (SWRK),A
;
; Switch out the monitor and write to address 0000
;
TEST1: LD DE,MSGTEST1
CALL MONPRTSTR
;
LD HL,00000H
LD D,(HL)
INC HL
LD E,(HL)
LD (MONSTORE),DE
;
LD BC,0
TEST1A: PUSH BC
OUT (0E0H),A
LD HL,00000H
LD (HL),C
INC HL
LD (HL),B
DEC HL
LD E,(HL)
INC HL
LD D,(HL)
;JR TEST1
; Page in the monitor and check print out the value from the RAM just paged out and the value in the monitor RAM to verify the bank switched.
OUT (0E4H),A
LD HL,00000H
LD A,(HL)
LD B,A
INC HL
LD A,(HL)
LD H,A
LD L,B
;JR TEST1
LD A,H
CP D
JR Z,TEST1B1
JR TEST1B2
TEST1B1: LD A,L
CP E
JR NZ,TEST1B2
;
LD BC,(MONSTORE) ; Check that the byte isnt the last contents of the monitor rom.
LD A,B
CP H
JR NZ,TEST1E
LD A,C
CP L
JR NZ,TEST1E
;
TEST1B2: PUSH DE
CALL PRTHL
CALL PRTS ; Print space.
POP DE
EX DE,HL
CALL PRTHL
;
LD A,0C4h ; Move cursor left.
LD E,9 ; 9 times.
TEST1B: CALL DPCT
DEC E
JR NZ,TEST1B
;
TEST1C: POP BC
DEC BC
LD A,B
OR C
JR NZ,TEST1A
JP DONE
;
TEST1E: PUSH DE
CALL PRTHL
CALL PRTS ; Print space.
POP DE
EX DE,HL
CALL PRTHL
;
LD DE,MSGFAIL
CALL MONPRTSTR
POP HL
PUSH HL
CALL PRTHL
CALL NL
;
LD DE,(MONSTORE)
LD HL,00000H
LD (HL),E
INC HL
LD (HL),D
JR TEST1C
DONE: LD DE,MSGDONE
CALL MONPRTSTR
JP 0E800H
LVARSTART EQU $ ; Start of local page variables.
SPV:
IBUFE: ; TAPE BUFFER (128 BYTES)
ATRB: DS 1 ; ATTRIBUTE
NAME: DS 17 ; FILE NAME
SIZE: DS 2 ; BYTESIZE
DTADR: DS 2 ; DATA ADDRESS
EXADR: DS 2 ; EXECUTION ADDRESS
COMNT: DS 92 ; Comment / code area of CMT header.
SWPW: DS 10 ; SWEEP WORK
KDATW: DS 2 ; KEY WORK
KANAF: DS 1 ; KANA FLAG (01=GRAPHIC MODE)
DSPXY: DS 2 ; DISPLAY COORDINATES
MANG: DS 6 ; COLUMN MANAGEMENT
MANGE: DS 1 ; COLUMN MANAGEMENT END
PBIAS: DS 1 ; PAGE BIAS
ROLTOP: DS 1 ; ROLL TOP BIAS
MGPNT: DS 1 ; COLUMN MANAG. POINTER
PAGETP: DS 2 ; PAGE TOP
ROLEND: DS 1 ; ROLL END
DS 14 ; BIAS
FLASH: DS 1 ; FLASHING DATA
SFTLK: DS 1 ; SHIFT LOCK
REVFLG: DS 1 ; REVERSE FLAG
FLSDT: DS 1 ; CURSOR DATA
STRGF: DS 1 ; STRING FLAG
DPRNT: DS 1 ; TAB COUNTER
SWRK: DS 1 ; KEY SOUND FLAG
TEMPW: DS 1 ; TEMPO WORK
ONTYO: DS 1 ; ONTYO WORK
OCTV: DS 1 ; OCTAVE WORK
RATIO: DS 2 ; ONPU RATIO
DSPXYADDR: DS 2 ; Address of last known position.
TMPADR DS 2 ; TEMPORARY ADDRESS STORAGE
TMPSIZE DS 2 ; TEMPORARY SIZE
TMPCNT DS 2 ; TEMPORARY COUNTER
FLASHCTL: DS 1 ; CURSOR FLASH CONTROL. BIT 0 = Cursor On/Off, BIT 1 = Cursor displayed.
;
CURSORPSAV DS 2 ; Cursor save position;default 0,0
HAVELOADED DS 1 ; To show that a value has been put in for Ansi emualtor.
ANSIFIRST DS 1 ; Holds first character of Ansi sequence
NUMBERBUF DS 20 ; Buffer for numbers in Ansi
NUMBERPOS DS 2 ; Address within buffer
CHARACTERNO DS 1 ; Byte within Ansi sequence. 0=first,255=other
CURSORCOUNT DS 1 ; 1/50ths of a second since last change
FONTSET DS 1 ; Ansi font setup.
JSW_FF DS 1 ; Byte value to turn on/off FF routine
JSW_LF DS 1 ; Byte value to turn on/off LF routine
CHARACTER DS 1 ; To buffer character to be printed.
CURSORPOS DS 2 ; Cursor position, default 0,0.
BOLDMODE DS 1
HIBRITEMODE DS 1 ; 0 means on, &C9 means off
UNDERSCMODE DS 1
ITALICMODE DS 1
INVMODE DS 1
CHGCURSMODE DS 1
ANSIMODE DS 1 ; 1 = on, 0 = off
COLOUR EQU 0
MONSTORE DS 2
DS 256, 0FFH ; Stack space for cold and warm boot.
BOOTSTACK EQU $
;
LVAREND EQU $ ; End of local page variables
;-------------------------------------------------------------------------------
; START OF AUDIO CONTROLLER FUNCTIONALITY
;-------------------------------------------------------------------------------
; Melody function.
MLDY: PUSH BC
PUSH DE
PUSH HL
LD A,002H
LD (OCTV),A
LD B,001H
MLD1: LD A,(DE)
CP 00DH
JR Z,MLD4
CP 0C8H
JR Z,MLD4
CP 0CFH
JR Z,MLD2
CP 02DH
JR Z,MLD2
CP 02BH
JR Z,MLD3
CP 0D7H
JR Z,MLD3
CP 023H
LD HL,MTBL
JR NZ,MLD1A
LD HL,M?TBL
INC DE
MLD1A: CALL ONPU
JR C,MLD1
CALL RYTHM
JR C,MLD5
CALL MLDST
LD B,C
JR MLD1
MLD2: LD A,003H
MLD2A: LD (OCTV),A
INC DE
JR MLD1
MLD3: LD A,001H
JR MLD2A
MLD4: CALL RYTHM
MLD5: PUSH AF
CALL MLDSP
POP AF
POP HL
POP DE
POP BC
RET
ONPU: PUSH BC
LD B,008H
LD A,(DE)
ONP1A: CP (HL)
JR Z,ONP2
INC HL
INC HL
INC HL
DJNZ ONP1A
SCF
INC DE
POP BC
RET
ONP2: INC HL
PUSH DE
LD E,(HL)
INC HL
LD D,(HL)
EX DE,HL
LD A,H
OR A
JR Z,ONP2B
LD A,(OCTV)
ONP2A: DEC A
JR Z,ONP2B
ADD HL,HL
JR ONP2A
ONP2B: LD (RATIO),HL
LD HL,OCTV
LD (HL),002H
DEC HL
POP DE
INC DE
LD A,(DE)
LD B,A
AND 0F0H
CP 030H
JR Z,ONP2C
LD A,(HL)
JR ONP2D
ONP2C: INC DE
LD A,B
AND 00FH
LD (HL),A
ONP2D: LD HL,OPTBL
ADD A,L
LD L,A
LD C,(HL)
LD A,(TEMPW)
LD B,A
XOR A
JP MLDDLY
RYTHM: LD HL,KEYPA
LD (HL),0F0H
INC HL
LD A,(HL)
AND 081H
JR NZ,L02D5
SCF
RET
L02D5: LD A,(SUNDG)
RRCA
JR C,L02D5
L02DB: LD A,(SUNDG)
RRCA
JR NC,L02DB
DJNZ L02D5
XOR A
RET
MLDST: LD HL,(RATIO)
LD A,H
OR A
JR Z,MLDSP
PUSH DE
EX DE,HL
LD HL,CONT0
LD (HL),E
LD (HL),D
LD A,001H
POP DE
JR L02C4
MLDSP: LD A,034H
LD (CONTF),A
XOR A
L02C4: LD (SUNDG),A
RET
MLDDLY: ADD A,C
DJNZ MLDDLY
POP BC
LD C,A
XOR A
RET
TEMPO: PUSH AF
PUSH BC
AND 00FH
LD B,A
LD A,008H
SUB B
LD (TEMPW),A
POP BC
POP AF
RET
;
; Method to sound the bell, basically play a constant tone.
;
BEL: PUSH DE
LD DE,00DB1H
CALL MLDY
POP DE
RET
;
; Melody (note) lookup table.
;
MTBL: DB 043H
DB 077H
DB 007H
DB 044H
DB 0A7H
DB 006H
DB 045H
DB 0EDH
DB 005H
DB 046H
DB 098H
DB 005H
DB 047H
DB 0FCH
DB 004H
DB 041H
DB 071H
DB 004H
DB 042H
DB 0F5H
DB 003H
DB 052H
DB 000H
DB 000H
M?TBL: DB 043H
DB 00CH
DB 007H
DB 044H
DB 047H
DB 006H
DB 045H
DB 098H
DB 005H
DB 046H
DB 048H
DB 005H
DB 047H
DB 0B4H
DB 004H
DB 041H
DB 031H
DB 004H
DB 042H
DB 0BBH
DB 003H
DB 052H
DB 000H
DB 000H
OPTBL: DB 001H
DB 002H
DB 003H
DB 004H
DB 006H
DB 008H
DB 00CH
DB 010H
DB 018H
DB 020H
;-------------------------------------------------------------------------------
; END OF AUDIO CONTROLLER FUNCTIONALITY
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; UTILITIES
;-------------------------------------------------------------------------------
; Function to print a string with control character interpretation.
MONPRTSTR: LD A,(DE)
OR A
RET Z
INC DE
MONPRTSTR2: CALL PRNT
JR MONPRTSTR
; A function from the z88dk stdlib, a delay loop with T state accuracy.
;
; enter : hl = tstates >= 141
; uses : af, bc, hl
T_DELAY: LD BC,-141
ADD HL,BC
LD BC,-23
TDELAYLOOP: ADD HL,BC
JR C, TDELAYLOOP
LD A,L
ADD A,15
JR NC, TDELAYG0
CP 8
JR C, TDELAYG1
OR 0
TDELAYG0: INC HL
TDELAYG1: RRA
JR C, TDELAYB0
NOP
TDELAYB0: RRA
JR NC, TDELAYB1
OR 0
TDELAYB1: RRA
RET NC
RET
; Method to multiply a 16bit number by another 16 bit number to arrive at a 32bit result.
; Input: DE = Factor 1
; BC = Factor 2
; Output:DEHL = 32bit Product
;
MULT16X16: LD HL,0
LD A,16
MULT16X1: ADD HL,HL
RL E
RL D
JR NC,$+6
ADD HL,BC
JR NC,$+3
INC DE
DEC A
JR NZ,MULT16X1
RET
; Method to add a 16bit number to a 32bit number to obtain a 32bit product.
; Input: DEHL = 32bit Addend
; BC = 16bit Addend
; Output:DEHL = 32bit sum.
;
ADD3216: ADD HL,BC
EX DE,HL
LD BC,0
ADC HL,BC
EX DE,HL
RET
; Method to clear memory either to 0 or a given pattern.
;
CLR8Z: XOR A
CLR8: LD BC,00800H
CLRMEM: PUSH DE
LD D,A
L09E8: LD (HL),D
INC HL
DEC BC
LD A,B
OR C
JR NZ,L09E8
POP DE
RET
;-------------------------------------------------------------------------------
; END OF UTILITIES
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; START OF KEYBOARD FUNCTIONALITY (INTR HANDLER SEPERATE IN CBIOS)
;-------------------------------------------------------------------------------
MODE: LD HL,KEYPF
LD (HL),08AH
LD (HL),007H ; Set Motor to Off.
LD (HL),004H ; Disable interrupts by setting INTMSK to 0.
LD (HL),001H ; Set VGATE to 1.
RET
;-------------------------------------------------------------------------------
; END OF KEYBOARD FUNCTIONALITY
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; START OF SCREEN FUNCTIONALITY
;-------------------------------------------------------------------------------
; CR PAGE MODE1
.CR: CALL .MANG
RRCA
JP NC,CURS2
LD L,000H
INC H
CP ROW - 1 ; End of line?
JR Z,.CP1
INC H
JP CURS1
.CP1: LD (DSPXY),HL
; SCROLLER
.SCROL: LD BC,SCRNSZ - COLW ; Scroll COLW -1 lines
LD DE,SCRN ; Start of the screen.
LD HL,SCRN + COLW ; Start of screen + 1 line.
LDIR
EX DE,HL
LD B,COLW ; Clear last line at bottom of screen.
CALL CLER
LD BC,0001AH
LD DE,MANG
LD HL,MANG + 1
LDIR
LD (HL),000H
LD A,(MANG)
OR A
JP Z,RSTR
LD HL,DSPXY + 1
DEC (HL)
JR .SCROL
DPCT: PUSH AF ; Display control, character is mapped to a function call.
PUSH BC
PUSH DE
PUSH HL
LD B,A
AND 0F0H
CP 0C0H
JP NZ,RSTR
XOR B
RLCA
LD C,A
LD B,000H
LD HL,.CTBL
DPCT1: ADD HL,BC
LD E,(HL)
INC HL
LD D,(HL)
EX DE,HL
JP (HL)
PRT: LD A,C
CALL ADCN
LD C,A
AND 0F0H
CP 0F0H
RET Z
CP 0C0H
LD A,C
JR NZ,PRNT3
PRNT5: CALL DPCT
CP 0C3H
JR Z,PRNT4
CP 0C5H
JR Z,PRNT2
CP 0CDH ; CR
JR Z,PRNT2
CP 0C6H
RET NZ
PRNT2: XOR A
PRNT2A: LD (DPRNT),A
RET
PRNT3: CALL DSP
PRNT4: LD A,(DPRNT)
INC A
CP COLW*2 ; 050H
JR C,PRNT4A
SUB COLW*2 ; 050H
PRNT4A: JR PRNT2A
NL: LD A,(DPRNT)
OR A
RET Z
LTNL: LD A,0CDH
JR PRNT5
PRTT: CALL PRTS
LD A,(DPRNT)
OR A
RET Z
L098C: SUB 00AH
JR C,PRTT
JR NZ,L098C
RET
; Delete a character on screen.
DELCHR: LD A,0C7H
CALL DPCT
JR PRNT1
NEWLINE: CALL NL
JR PRNT1
;
; Function to disable the cursor display.
;
CURSOROFF: DI
CALL CURSRSTR ; Restore character under the cursor.
LD HL,FLASHCTL ; Indicate cursor is now off.
RES 7,(HL)
EI
RET
;
; Function to enable the cursor display.
;
CURSORON: DI
CALL DSPXYTOADDR ; Update the screen address for where the cursor should appear.
LD HL,FLASHCTL ; Indicate cursor is now on.
SET 7,(HL)
EI
RET
;
; Function to restore the character beneath the cursor iff the cursor is being dislayed.
;
CURSRSTR: PUSH HL
PUSH AF
LD HL,FLASHCTL ; Check to see if there is a cursor at the current screen location.
BIT 6,(HL)
JR Z,CURSRSTR1
RES 6,(HL)
LD HL,(DSPXYADDR) ; There is so we must restore the original character before further processing.
LD A,(FLASH)
LD (HL),A
CURSRSTR1: POP AF
POP HL
RET
;
; Function to convert XY co-ordinates to a physical screen location and save.
;
DSPXYTOADDR:PUSH HL
PUSH DE
PUSH BC
LD BC,(DSPXY) ; Calculate the new cursor position based on the XY coordinates.
LD DE,COLW
LD HL,SCRN - COLW
DSPXYTOA1: ADD HL,DE
DEC B
JP P,DSPXYTOA1
LD B,000H
ADD HL,BC
RES 3,H
LD (DSPXYADDR),HL ; Store the new address.
LD A,(HL) ; Store the new character.
LD (FLASH),A
DSPXYTOA2: POP BC
POP DE
POP HL
RET
;
; Function to print a space.
;
PRTS: LD A,020H
; Function to print a character to the screen. If the character is a control code it is processed as necessary
; otherwise the character is converted from ASCII display and displayed.
;
PRNT: DI
CALL CURSRSTR ; Restore char under cursor.
CP 00DH
JR Z,NEWLINE
CP 00AH
JR Z,NEWLINE
CP 07FH
JR Z,DELCHR
CP BACKS
JR Z,DELCHR
PUSH BC
LD C,A
LD B,A
CALL PRT
LD A,B
POP BC
PRNT1: CALL DSPXYTOADDR
EI
RET
;
; Function to print out the contents of HL as 4 digit Hexadecimal.
;
PRTHL: LD A,H
CALL PRTHX
LD A,L
JR PRTHX
RET
;
; Function to print out the contents of A as 2 digit Hexadecimal
;
PRTHX: PUSH AF
RRCA
RRCA
RRCA
RRCA
CALL ASC
CALL PRNT
POP AF
CALL ASC
JP PRNT
ASC: AND 00FH
CP 00AH
JR C,NOADD
ADD A,007H
NOADD: ADD A,030H
RET
;CLR8Z: XOR A
; LD BC,00800H
; PUSH DE
; LD D,A
;L09E8: LD (HL),D
; INC HL
; DEC BC
; LD A,B
; OR C
; JR NZ,L09E8
; POP DE
; RET
REV: LD HL,REVFLG
LD A,(HL)
OR A
CPL
LD (HL),A
JR Z,REV1
LD A,(INVDSP)
JR REV2
REV1: LD A,(NRMDSP)
REV2: JP RSTR
.MANG: LD HL,MANG
.MANG2: LD A,(DSPXY + 1)
ADD A,L
LD L,A
LD A,(HL)
INC HL
RL (HL)
OR (HL)
RR (HL)
RRCA
EX DE,HL
LD HL,(DSPXY)
RET
L09C7: PUSH DE
PUSH HL
LD HL,PBIAS
XOR A
RLD
LD D,A
LD E,(HL)
RRD
XOR A
RR D
RR E
LD HL,SCRN
ADD HL,DE
LD (PAGETP),HL
POP HL
POP DE
RET
DSP: PUSH AF
PUSH BC
PUSH DE
PUSH HL
LD B,A
CALL PONT
LD (HL),B
LD HL,(DSPXY)
LD A,L
DSP01: CP COLW - 1 ; End of line.
JP NZ,CURSR
CALL .MANG
JR C,CURSR
.DSP03: EX DE,HL
LD (HL),001H
INC HL
LD (HL),000H
JP CURSR
CURSD: LD HL,(DSPXY)
LD A,H
CP ROW - 1
JR Z,CURS4
INC H
CURS1: ;CALL MGP.I
CURS3: LD (DSPXY),HL
JR RSTR
CURSU: LD HL,(DSPXY)
LD A,H
OR A
JR Z,CURS5
DEC H
CURSU1: JR CURS3
CURSR: LD HL,(DSPXY)
LD A,L
CP COLW - 1 ; End of line
JR NC,CURS2
INC L
JR CURS3
CURS2: LD L,000H
INC H
LD A,H
CP ROW
JR C,CURS1
LD H,ROW - 1
LD (DSPXY),HL
CURS4: JP .SCROL
CURSL: LD HL,(DSPXY)
LD A,L
OR A
JR Z,CURS5A
DEC L
JR CURS3
CURS5A: LD L,COLW - 1 ; End of line
DEC H
JP P,CURSU1
LD H,000H
LD (DSPXY),HL
CURS5: JR RSTR
CLRS: LD HL,MANG
LD B,01BH
CALL CLER
LD HL,SCRN
PUSH HL
CALL CLR8Z
POP HL
CLRS1: LD A,(SCLDSP)
HOM0: LD HL,00000H
JP CURS3
RSTR: POP HL
RSTR1: POP DE
POP BC
POP AF
RET
DEL: LD HL,(DSPXY)
LD A,H
OR L
JR Z,RSTR
LD A,L
OR A
JR NZ,DEL1
CALL .MANG
JR C,DEL1
CALL PONT
DEC HL
LD (HL),000H
JR CURSL
DEL1: CALL .MANG
RRCA
LD A,COLW
JR NC,L0F13
RLCA
L0F13: SUB L
LD B,A
CALL PONT
PUSH HL
POP DE
DEC DE
SET 4,D
DEL2: RES 3,H
RES 3,D
LD A,(HL)
LD (DE),A
INC HL
INC DE
DJNZ DEL2
DEC HL
LD (HL),000H
JP CURSL
INST: CALL .MANG
RRCA
LD L,COLW - 1 ; End of line
LD A,L
JR NC,INST1A
INC H
INST1A: CALL PNT1
PUSH HL
LD HL,(DSPXY)
JR NC,INST2
LD A,(COLW*2)-1 ; 04FH
INST2: SUB L
LD B,A
POP DE
LD A,(DE)
OR A
JR NZ,RSTR
CALL PONT
LD A,(HL)
LD (HL),000H
INST1: INC HL
RES 3,H
LD E,(HL)
LD (HL),A
LD A,E
DJNZ INST1
JR RSTR
PONT: LD HL,(DSPXY)
PNT1: PUSH AF
PUSH BC
PUSH DE
PUSH HL
POP BC
LD DE,COLW
LD HL,SCRN - COLW
PNT2: ADD HL,DE
DEC B
JP P,PNT2
LD B,000H
ADD HL,BC
RES 3,H
POP DE
POP BC
POP AF
RET
CLER: XOR A
JR DINT
CLRFF: LD A,0FFH
DINT: LD (HL),A
INC HL
DJNZ DINT
RET
ADCN: PUSH BC
PUSH HL
LD HL,ATBL ;00AB5H
LD C,A
LD B,000H
ADD HL,BC
LD A,(HL)
JR DACN3
DACN: PUSH BC
PUSH HL
PUSH DE
LD HL,ATBL
LD D,H
LD E,L
LD BC,00100H
CPIR
JR Z,DACN1
LD A,0F0H
DACN2: POP DE
DACN3: POP HL
POP BC
RET
DACN1: OR A
DEC HL
SBC HL,DE
LD A,L
JR DACN2
; CTBL PAGE MODE1
.CTBL: DW .SCROL
DW CURSD
DW CURSU
DW CURSR
DW CURSL
DW HOM0
DW CLRS
DW DEL
DW INST
DW RSTR
DW RSTR
DW RSTR
DW REV
DW .CR
DW RSTR
DW RSTR
; ASCII TO DISPLAY CODE TABLE
ATBL: DB 0CCH ; NUL '\0' (null character)
DB 0E0H ; SOH (start of heading)
DB 0F2H ; STX (start of text)
DB 0F3H ; ETX (end of text)
DB 0CEH ; EOT (end of transmission)
DB 0CFH ; ENQ (enquiry)
DB 0F6H ; ACK (acknowledge)
DB 0F7H ; BEL '\a' (bell)
DB 0F8H ; BS '\b' (backspace)
DB 0F9H ; HT '\t' (horizontal tab)
DB 0FAH ; LF '\n' (new line)
DB 0FBH ; VT '\v' (vertical tab)
DB 0FCH ; FF '\f' (form feed)
DB 0FDH ; CR '\r' (carriage ret)
DB 0FEH ; SO (shift out)
DB 0FFH ; SI (shift in)
DB 0E1H ; DLE (data link escape)
DB 0C1H ; DC1 (device control 1)
DB 0C2H ; DC2 (device control 2)
DB 0C3H ; DC3 (device control 3)
DB 0C4H ; DC4 (device control 4)
DB 0C5H ; NAK (negative ack.)
DB 0C6H ; SYN (synchronous idle)
DB 0E2H ; ETB (end of trans. blk)
DB 0E3H ; CAN (cancel)
DB 0E4H ; EM (end of medium)
DB 0E5H ; SUB (substitute)
DB 0E6H ; ESC (escape)
DB 0EBH ; FS (file separator)
DB 0EEH ; GS (group separator)
DB 0EFH ; RS (record separator)
DB 0F4H ; US (unit separator)
DB 000H ; SPACE
DB 061H ; !
DB 062H ; "
DB 063H ; #
DB 064H ; $
DB 065H ; %
DB 066H ; &
DB 067H ; '
DB 068H ; (
DB 069H ; )
DB 06BH ; *
DB 06AH ; +
DB 02FH ; ,
DB 02AH ; -
DB 02EH ; .
DB 02DH ; /
DB 020H ; 0
DB 021H ; 1
DB 022H ; 2
DB 023H ; 3
DB 024H ; 4
DB 025H ; 5
DB 026H ; 6
DB 027H ; 7
DB 028H ; 8
DB 029H ; 9
DB 04FH ; :
DB 02CH ; ;
DB 051H ; <
DB 02BH ; =
DB 057H ; >
DB 049H ; ?
DB 055H ; @
DB 001H ; A
DB 002H ; B
DB 003H ; C
DB 004H ; D
DB 005H ; E
DB 006H ; F
DB 007H ; G
DB 008H ; H
DB 009H ; I
DB 00AH ; J
DB 00BH ; K
DB 00CH ; L
DB 00DH ; M
DB 00EH ; N
DB 00FH ; O
DB 010H ; P
DB 011H ; Q
DB 012H ; R
DB 013H ; S
DB 014H ; T
DB 015H ; U
DB 016H ; V
DB 017H ; W
DB 018H ; X
DB 019H ; Y
DB 01AH ; Z
DB 052H ; [
DB 059H ; \ '\\'
DB 054H ; ]
DB 0BEH ; ^
DB 03CH ; _
DB 0C7H ; `
DB 081H ; a
DB 082H ; b
DB 083H ; c
DB 084H ; d
DB 085H ; e
DB 086H ; f
DB 087H ; g
DB 088H ; h
DB 089H ; i
DB 08AH ; j
DB 08BH ; k
DB 08CH ; l
DB 08DH ; m
DB 08EH ; n
DB 08FH ; o
DB 090H ; p
DB 091H ; q
DB 092H ; r
DB 093H ; s
DB 094H ; t
DB 095H ; u
DB 096H ; v
DB 097H ; w
DB 098H ; x
DB 099H ; y
DB 09AH ; z
DB 0BCH ; {
DB 080H ; |
DB 040H ; }
DB 0A5H ; ~
DB 0C0H ; DEL
DB 040H
DB 0BDH
DB 09DH
DB 0B1H
DB 0B5H
DB 0B9H
DB 0B4H
DB 09EH
DB 0B2H
DB 0B6H
DB 0BAH
DB 0BEH
DB 09FH
DB 0B3H
DB 0B7H
DB 0BBH
DB 0BFH
DB 0A3H
DB 085H
DB 0A4H
DB 0A5H
DB 0A6H
DB 094H
DB 087H
DB 088H
DB 09CH
DB 082H
DB 098H
DB 084H
DB 092H
DB 090H
DB 083H
DB 091H
DB 081H
DB 09AH
DB 097H
DB 093H
DB 095H
DB 089H
DB 0A1H
DB 0AFH
DB 08BH
DB 086H
DB 096H
DB 0A2H
DB 0ABH
DB 0AAH
DB 08AH
DB 08EH
DB 0B0H
DB 0ADH
DB 08DH
DB 0A7H
DB 0A8H
DB 0A9H
DB 08FH
DB 08CH
DB 0AEH
DB 0ACH
DB 09BH
DB 0A0H
DB 099H
DB 0BCH
DB 0B8H
DB 080H
DB 03BH
DB 03AH
DB 070H
DB 03CH
DB 071H
DB 05AH
DB 03DH
DB 043H
DB 056H
DB 03FH
DB 01EH
DB 04AH
DB 01CH
DB 05DH
DB 03EH
DB 05CH
DB 01FH
DB 05FH
DB 05EH
DB 037H
DB 07BH
DB 07FH
DB 036H
DB 07AH
DB 07EH
DB 033H
DB 04BH
DB 04CH
DB 01DH
DB 06CH
DB 05BH
DB 078H
DB 041H
DB 035H
DB 034H
DB 074H
DB 030H
DB 038H
DB 075H
DB 039H
DB 04DH
DB 06FH
DB 06EH
DB 032H
DB 077H
DB 076H
DB 072H
DB 073H
DB 047H
DB 07CH
DB 053H
DB 031H
DB 04EH
DB 06DH
DB 048H
DB 046H
DB 07DH
DB 044H
DB 01BH
DB 058H
DB 079H
DB 042H
DB 060H
DB 0FDH
DB 0CBH
DB 000H
DB 01EH
;-------------------------------------------------------------------------------
; END OF SCREEN FUNCTIONALITY
;-------------------------------------------------------------------------------
;----------------------------------------
;
; ANSI EMULATION
;
; Emulate the Ansi standard
; N.B. Turned on when Chr
; 27 recieved.
; Entry - A = Char
; Exit - None
; Used - None
;
;----------------------------------------
ANSITERM: PUSH HL
PUSH DE
PUSH BC
PUSH AF
LD C,A ; Move character into C for safe keeping
;
LD A,(ANSIMODE)
OR A
JR NZ,ANSI2
LD A,C
CP 27
JP NZ,NOTANSI ; If it is Chr 27 then we haven't just
; been turned on, so don't bother with
; all the checking.
LD A,1 ; Turn on.
LD (ANSIMODE),A
JP AnsiMore
ANSI2: LD A,(CHARACTERNO) ; CHARACTER number in sequence
OR A ; Is this the first character?
JP Z,AnsiFirst ; Yes, deal with this strange occurance!
LD A,C ; Put character back in C to check
CP ";" ; Is it a semi colon?
JP Z,AnsiSemi
CP "0" ; Is it a number?
JR C,ANSI_NN ; If <0 then no
CP "9"+1 ; If >9 then no
JP C,AnsiNumber
ANSI_NN: CP "?" ; Simple trap for simple problem!
JP Z,AnsiMore
CP "@" ; Is it a letter?
JP C,ANSIEXIT ; Abandon if not letter; something wrong
ANSIFOUND: CALL CURSRSTR ; Restore any character under the cursor.
LD HL,(NUMBERPOS) ; Get value of number buffer
LD A,(HAVELOADED) ; Did we put anything in this byte?
OR A
JR NZ,AF1
LD (HL),255 ; Mark the fact that nothing was put in
AF1: INC HL
LD A,254
LD (HL),A ; Mark end of sequence (for unlimited length sequences)
;Disable cursor as unwanted side effects such as screen flicker may occur.
LD A,(FLASHCTL)
BIT 7,A
CALL NZ,CURSOROFF
XOR A
LD (CURSORCOUNT),A ; Restart count
LD A,0C9h
LD (CHGCURSMODE),A ; Disable flashing temp.
LD HL,NUMBERBUF ; For the routine called.
LD A,C ; Restore number
;
; Now work out what happens...
;
CP "A" ; Check for supported Ansi characters
JP Z,CUU ; Upwards
CP "B"
JP Z,CUD ; Downwards
CP "C"
JP Z,CUF ; Forward
CP "D"
JP Z,CUB ; Backward
CP "H"
JP Z,CUP ; Locate
CP "f"
JP Z,HVP ; Locate
CP "J"
JP Z,ED ; Clear screen
CP "m"
JP Z,SGR ; Set graphics renditon
CP "K"
JP Z,EL ; Clear to end of line
CP "s"
JP Z,SCP ; Save the cursor position
CP "u"
JP Z,RCP ; Restore the cursor position
ANSIEXIT: CALL CURSORON ; If t
LD HL,NUMBERBUF ; Numbers buffer position
LD (NUMBERPOS),HL
XOR A
LD (CHARACTERNO),A ; Next time it runs, it will be the
; first character
LD (HAVELOADED),A ; We haven't filled this byte!
LD (CHGCURSMODE),A ; Cursor allowed back again!
XOR A
LD (ANSIMODE),A
JR AnsiMore
NOTANSI: CP 000h ; Filter unprintable characters.
JR Z,AnsiMore
CALL PRNT
AnsiMore: POP AF
POP BC
POP DE
POP HL
RET
;
; The various routines needed to handle the filtered characters
;
AnsiFirst: LD A,255
LD (CHARACTERNO),A ; Next character is not first!
LD A,C ; Get character back
LD (ANSIFIRST),A ; Save first character to check later
CP "(" ; ( and [ have characters to follow
JP Z,AnsiMore ; and are legal.
CP "["
JP Z,AnsiMore
CP 09Bh ; CSI
JP Z,AnsiF1 ; Pretend that "[" was first ;-)
JP ANSIEXIT ; = and > don't have anything to follow
; them but are legal.
; Others are illegal, so abandon anyway.
AnsiF1: LD A,"[" ; Put a "[" for first character
LD (ANSIFIRST),A
JP ANSIEXIT
AnsiSemi: LD HL,(NUMBERPOS) ; Move the number pointer to the
LD A,(HAVELOADED) ; Did we put anything in this byte?
OR A
JR NZ,AS1
LD (HL),255 ; Mark the fact that nothing was put in
AS1: INC HL ; move to next byte
LD (NUMBERPOS),HL
XOR A
LD (HAVELOADED),A ; New byte => not filled!
JP AnsiMore
AnsiNumber: LD HL,(NUMBERPOS) ; Get address for number
LD A,(HAVELOADED)
OR A ; If value is zero
JR NZ,AN1
LD A,C ; Get value into A
SUB "0" ; Remove ASCII offset
LD (HL),A ; Save and Exit
LD A,255
LD (HAVELOADED),A ; Yes, we _have_ put something in!
JP AnsiMore
AN1: LD A,(HL) ; Stored value in A; TBA in C
ADD A,A ; 2 *
LD D,A ; Save the 2* for later
ADD A,A ; 4 *
ADD A,A ; 8 *
ADD A,D ; 10 *
ADD A,C ; 10 * + new num
SUB "0" ; And remove offset from C value!
LD (HL),A ; Save and Exit.
JP AnsiMore ; Note routine will only work up to 100
; which should be okay for this application.
;--------------------------------
; GET NUMBER
;
; Gets the next number from
; the list
;
; Entry - HL = address to get
; from
; Exit - HL = next address
; A = value
; IF a=255 then default value
; If a=254 then end of sequence
; Used - None
;--------------------------------
GetNumber: LD A,(HL) ; Get number
CP 254
RET Z ; Return if end of sequence,ie still point to
; end
INC HL ; Return pointing to next byte
RET ; Else next address and return
;*** ANSI UP
;
CUU: CALL GetNumber ; Number into A
LD B,A ; Save value into B
CP 255
JR NZ,CUUlp
LD B,1 ; Default value
CUUlp: LD A,(DSPXY+1) ; A <- Row
CP B ; Is it too far?
JR C,CUU1
SUB B ; No, then go back that far.
JR CUU2
CUU1: LD A,0 ; Make the choice, top line.
CUU2: LD (DSPXY+1),A ; Row <- A
JP ANSIEXIT
;*** ANSI DOWN
;
CUD: LD A,(ANSIFIRST)
CP "["
JP NZ,ANSIEXIT ; Ignore ESC(B
CALL GetNumber
LD B,A ; Save value in b
CP 255
JR NZ,CUDlp
LD B,1 ; Default
CUDlp: LD A,(DSPXY+1) ; A <- Row
ADD A,B
CP ROW ; Too far?
JP C,CUD1
LD A,ROW-1 ; Too far then bottom of screen
CUD1: LD (DSPXY+1),A ; Row <- A
JP ANSIEXIT
;*** ANSI RIGHT
;
CUF: CALL GetNumber ; Number into A
LD B,A ; Value saved in B
CP 255
JR NZ,CUFget
LD B,1 ; Default
CUFget: LD A,(DSPXY) ; A <- Column
ADD A,B ; Add movement.
CP 80 ; Too far?
JR C,CUF2
LD A,79 ; Yes, right edge
CUF2: LD (DSPXY),A ; Column <- A
JP ANSIEXIT
;*** ANSI LEFT
;
CUB: CALL GetNumber ; Number into A
LD B,A ; Save value in B
CP 255
JR NZ,CUBget
LD B,1 ; Default
CUBget: LD A,(DSPXY) ; A <- Column
CP B ; Too far?
JR C,CUB1a
SUB B
JR CUB1b
CUB1a: LD A,0
CUB1b: LD (DSPXY),A ; Column <-A
JP ANSIEXIT
;*** ANSI LOCATE
;
HVP:
CUP: CALL GetNumber
CP 255
CALL Z,DefaultLine ; Default = 1
CP 254 ; Sequence End -> 1
CALL Z,DefaultLine
CP ROW+1 ; Out of range then don't move
JP NC,ANSIEXIT
OR A
CALL Z,DefaultLine ; 0 means default, some strange reason
LD D,A
CALL GetNumber
CP 255 ; Default = 1
CALL Z,DefaultColumn
CP 254 ; Sequence End -> 1
CALL Z,DefaultColumn
CP 81 ; Out of range, then don't move
JP NC,ANSIEXIT
OR A
CALL Z,DefaultColumn ; 0 means go with default
LD E,A
EX DE,HL
DEC H ; Translate from Ansi co-ordinates to hardware
DEC L ; co-ordinates
LD (DSPXY),HL ; Set the cursor position.
JP ANSIEXIT
DefaultColumn:
DefaultLine:LD A,1
RET
;*** ANSI CLEAR SCREEN
;
ED: CALL GetNumber
OR A
JP Z,ED1 ; Zero means first option
CP 254 ; Also default
JP Z,ED1
CP 255
JP Z,ED1
CP 1
JP Z,ED2
CP 2
JP NZ,ANSIEXIT
;*** Option 2
;
ED3: LD HL,0
LD (DSPXY),HL ; Home the cursor
LD A,(JSW_FF)
OR A
JP NZ,ED_Set_LF
CALL CALCSCADDR
CALL CLRSCRN
JP ANSIEXIT
ED_Set_LF: XOR A ; Note simply so that
LD (JSW_LF),A ; ESC[2J works the same as CTRL-L
JP ANSIEXIT
;*** Option 0
;
ED1: LD HL,(DSPXY) ; Get and save cursor position
LD A,H
OR L
JP Z,ED3 ; If we are at the top of the
; screen and clearing to the bottom
; then we are clearing all the screen!
PUSH HL
LD A,ROW-1
SUB H ; ROW - Row
LD HL,0 ; Zero start
OR A ; Do we have any lines to add?
JR Z,ED1_2 ; If no bypass that addition!
LD B,A ; Number of lines to count
LD DE,80
ED1_1: ADD HL,DE
DJNZ ED1_1
ED1_2: EX DE,HL ; Value into DE
POP HL
LD A,80
SUB L ; 80 - Columns
LD L,A ; Add to value before
LD H,0
ADD HL,DE
PUSH HL ; Value saved for later
LD HL,(DSPXY) ; _that_ value again!
POP BC ; Number to blank
CALL CALCSCADDR
CALL CLRSCRN ; Now do it!
JP ANSIEXIT ; Then exit properly
;*** Option 1 - clear from cursor to beginning of screen
;
ED2: LD HL,(DSPXY) ; Get and save cursor position
PUSH HL
LD A,H
LD HL,0 ; Zero start
OR A ; Do we have any lines to add?
JR Z,ED2_2 ; If no bypass that addition!
LD B,A ; Number of lines
LD DE,80
ED2_1: ADD HL,DE
DJNZ ED2_1
ED2_2: EX DE,HL ; Value into DE
POP HL
LD H,0
ADD HL,DE
PUSH HL ; Value saved for later
LD HL,0 ; Find the begining!
POP BC ; Number to blank
CALL CLRSCRN ; Now do it!
JP ANSIEXIT ; Then exit properly
; *** ANSI CLEAR LINE
;
EL: CALL GetNumber ; Get value
CP 0
JP Z,EL1 ; Zero & Default are the same
CP 255
JP Z,EL1
CP 254
JP Z,EL1
CP 1
JP Z,EL2
CP 2
JP NZ,ANSIEXIT ; Otherwise don't do a thing
;*** Option 2 - clear entire line.
;
LD HL,(DSPXY)
LD L,0
LD (DSPXY),HL
CALL CALCSCADDR
LD BC,80 ; 80 bytes to clear (whole line)
CALL CLRSCRN
JP ANSIEXIT
;*** Option 0 - Clear from Cursor to end of line.
;
EL1: LD HL,(DSPXY)
LD A,80 ; Calculate distance to end of line
SUB L
LD C,A
LD B,0
LD (DSPXY),HL
PUSH HL
POP DE
CALL CALCSCADDR
CALL CLRSCRN
JP ANSIEXIT
;*** Option 1 - clear from cursor to beginning of line.
;
EL2: LD HL,(DSPXY)
LD C,L ; BC = distance from start of line
LD B,0
LD L,0
LD (DSPXY),HL
CALL CALCSCADDR
CALL CLRSCRN
JP ANSIEXIT
; In HL = XY Pos
; Out = Screen address.
CALCSCADDR: PUSH AF
PUSH BC
PUSH DE
PUSH HL
LD A,H
LD B,H
LD C,L
LD HL,SCRN
OR A
JR Z,CALC3
LD DE,80
CALC2: ADD HL,DE
DJNZ CALC2
CALC3: POP DE
ADD HL,BC
POP DE
POP BC
POP AF
RET
; HL = address
; BC = length
CLRSCRN: PUSH HL ; 1 for later!
LD D,H
LD E,L
INC DE ; DE <- HL +1
PUSH BC ; Save the value a little longer!
XOR A
LD (HL), A ; Blank this area!
LDIR ; *** just like magic ***
; only I forgot it in 22a!
POP BC ; Restore values
POP HL
LD DE,2048 ; Move to attributes block
ADD HL,DE
LD D,H
LD E,L
INC DE ; DE = HL + 1
LD A,(FONTSET) ; Save in the current values.
LD (HL),A
LDIR
RET
;*** ANSI SET GRAPHICS RENDITION
;
SGR: CALL GetNumber
CP 254 ; 254 signifies end of sequence
JP Z,ANSIEXIT
OR A
CALL Z,AllOff
CP 255 ; Default means all off
CALL Z,AllOff
CP 1
CALL Z,BoldOn
CP 2
CALL Z,BoldOff
CP 4
CALL Z,UnderOn
CP 5
CALL Z,ItalicOn
CP 6
CALL Z,ItalicOn
CP 7
CALL Z,InverseOn
JP SGR ; Code is re-entrant
;--------------------------------
;
; RESET GRAPHICS
;
; Entry - None
; Exit - None
; Used - None
;--------------------------------
AllOff: PUSH AF ; Save registers
LD A,0C9h ; = off
LD (BOLDMODE),A ; Turn the flags off
LD (ITALICMODE),A
LD (UNDERSCMODE),A
LD (INVMODE),A
LD A,007h ; Black background, white chars.
LD (FONTSET),A ; Reset the bit map store
POP AF ; Restore register
RET
;--------------------------------
;
; TURN BOLD ON
;
; Entry - None
; Exit - None
; Used - None
;--------------------------------
BoldOn: PUSH AF ; Save register
XOR A ; 0 means on
LD (BOLDMODE),A
BOn1: LD A,(FONTSET)
SET 0,A ; turn ON indicator flag
LD (FONTSET),A
POP AF ; Restore register
RET
;--------------------------------
;
; TURN BOLD OFF
;
; Entry - None
; Exit - None
; Used - None
;--------------------------------
BoldOff: PUSH AF ; Save register
PUSH BC
LD A,0C9h ; &C9 means off
LD (BOLDMODE),A
BO1: LD A,(FONTSET)
RES 0,A ; turn OFF indicator flag
LD (FONTSET),A
POP BC
POP AF ; Restore register
RET
;--------------------------------
;
; TURN ITALICS ON
; (replaces flashing)
; Entry - None
; Exit - None
; Used - None
;--------------------------------
ItalicOn: PUSH AF ; Save AF
XOR A
LD (ITALICMODE),A ; 0 means on
LD A,(FONTSET)
SET 1,A ; turn ON indicator flag
LD (FONTSET),A
POP AF ; Restore register
RET
;--------------------------------
;
; TURN UNDERLINE ON
;
; Entry - None
; Exit - None
; Used - None
;--------------------------------
UnderOn: PUSH AF ; Save register
XOR A ; 0 means on
LD (UNDERSCMODE),A
LD A,(FONTSET)
SET 2,A ; turn ON indicator flag
LD (FONTSET),A
POP AF ; Restore register
RET
;--------------------------------
;
; TURN INVERSE ON
;
; Entry - None
; Exit - None
; Used - None
;--------------------------------
InverseOn: PUSH AF ; Save register
XOR A ; 0 means on
LD (INVMODE),A
LD A,(FONTSET)
SET 3,A ; turn ON indicator flag
LD (FONTSET),A
POP AF ; Restore AF
RET
;*** ANSI SAVE CURSOR POSITION
;
SCP: LD HL,(DSPXY) ; (backup) <- (current)
LD (CURSORPSAV),HL
JP ANSIEXIT
;*** ANSI RESTORE CURSOR POSITION
;
RCP: LD HL,(CURSORPSAV) ; (current) <- (backup)
LD (DSPXY),HL
JP ANSIEXIT
;-------------------------------------------------------------------------------
; END OF ANSI TERMINAL FUNCTIONALITY
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; START OF DEBUGGING FUNCTIONALITY
;-------------------------------------------------------------------------------
; Debug routine to print out all registers and dump a section of memory for analysis.
;
DEBUG: IF ENADEBUG = 1
LD (DBGSTACKP),SP
LD SP,DBGSTACK
;
PUSH AF
PUSH BC
PUSH DE
PUSH HL
;
PUSH AF
PUSH HL
PUSH DE
PUSH BC
PUSH AF
LD DE, INFOMSG
CALL MONPRTSTR
POP BC
LD A,B
CALL PRTHX
LD A,C
CALL PRTHX
LD DE, INFOMSG2
CALL MONPRTSTR
POP BC
LD A,B
CALL PRTHX
LD A,C
CALL PRTHX
LD DE, INFOMSG3
CALL MONPRTSTR
POP DE
LD A,D
CALL PRTHX
LD A,E
CALL PRTHX
LD DE, INFOMSG4
CALL MONPRTSTR
POP HL
LD A,H
CALL PRTHX
LD A,L
CALL PRTHX
LD DE, INFOMSG5
CALL MONPRTSTR
LD HL,(DBGSTACKP)
LD A,H
CALL PRTHX
LD A,L
CALL PRTHX
CALL NL
LD DE, DRVMSG
CALL MONPRTSTR
LD A, (CDISK)
CALL PRTHX
LD DE, FDCDRVMSG
CALL MONPRTSTR
LD A, (FDCDISK)
CALL PRTHX
LD DE, SEKTRKMSG
CALL MONPRTSTR
LD BC,(SEKTRK)
LD A,B
CALL PRTHX
LD A,C
CALL PRTHX
CALL PRTS
LD A,(SEKSEC)
CALL PRTHX
CALL PRTS
LD A,(SEKHST)
CALL PRTHX
LD DE, HSTTRKMSG
CALL MONPRTSTR
LD BC,(HSTTRK)
LD A,B
CALL PRTHX
LD A,C
CALL PRTHX
CALL PRTS
LD A,(HSTSEC)
CALL PRTHX
LD DE, UNATRKMSG
CALL MONPRTSTR
LD BC,(UNATRK)
LD A,B
CALL PRTHX
LD A,C
CALL PRTHX
CALL PRTS
LD A,(UNASEC)
CALL PRTHX
LD DE, CTLTRKMSG
CALL MONPRTSTR
LD A,(TRACKNO) ; NB. Track number is 16bit, FDC only uses lower 8bit and assumes little endian read.
CALL PRTHX
CALL PRTS
LD A,(SECTORNO)
CALL PRTHX
LD DE, DMAMSG
CALL MONPRTSTR
LD BC,(DMAADDR)
LD A,B
CALL PRTHX
LD A,C
CALL PRTHX
CALL NL
;
POP AF
JR C, SKIPDUMP
;
LD HL,DPBASE ; Dump the startup vectors.
LD DE, 1000H
ADD HL, DE
EX DE,HL
LD HL,DPBASE
CALL DUMPX
LD HL,00000h ; Dump the startup vectors.
LD DE, 00A0H
ADD HL, DE
EX DE,HL
LD HL,00000h
CALL DUMPX
LD HL,IBUFE ; Dump the data area.
LD DE, 0300H
ADD HL, DE
EX DE,HL
LD HL,IBUFE
CALL DUMPX
LD HL,CBASE ; Dump the CCP + BDOS area.
LD DE,CPMBIOS - CBASE
ADD HL, DE
EX DE,HL
LD HL,CBASE
CALL DUMPX
SKIPDUMP: ;JR SKIPDUMP
POP HL
POP DE
POP BC
POP AF
;
LD SP,(DBGSTACKP)
RET
; HL = Start
; DE = End
DUMPX: LD A,10
DUM1: LD (TMPCNT),A
DUM3: LD B,010h
LD C,02Fh
CALL NLPHL
DUM2: CALL SPHEX
INC HL
PUSH AF
LD A,(DSPXY)
ADD A,C
LD (DSPXY),A
POP AF
CP 020h
JR NC,L0D51
LD A,02Eh
L0D51: CALL PRNT
LD A,(DSPXY)
INC C
SUB C
LD (DSPXY),A
DEC C
DEC C
DEC C
PUSH HL
SBC HL,DE
POP HL
JR NC,DUM7
L0D78: DJNZ DUM2
LD A,(TMPCNT)
DEC A
LD (TMPCNT),A
JR NZ,DUM3
DUM4: ;CALL CHKKY
CP 0FFH
JR NZ,DUM4
;CALL GETKY
CP 'D'
JR NZ,DUM5
LD A,8
JR DUM1
DUM5: CP 'U'
JR NZ,DUM6
PUSH DE
LD DE,00100H
OR A
SBC HL,DE
POP DE
LD A,8
JR DUM1
DUM6: CP 'X'
JR Z,DUM7
JR DUMPX
DUM7: CALL NL
RET
NLPHL: CALL NL
CALL PRTHL
RET
; SPACE PRINT AND DISP ACC
; INPUT:HL=DISP. ADR.
SPHEX: CALL PRTS ; SPACE PRINT
LD A,(HL)
CALL PRTHX ; DSP OF ACC (ASCII)
LD A,(HL)
RET
; Debugger messages, bit cryptic but this is due to limited space on the screen.
;
DRVMSG: DB "DRV=", 000H
FDCDRVMSG: DB ",FDC=", 000H
SEKTRKMSG: DB ",S=", 000H
HSTTRKMSG: DB ",H=", 000H
UNATRKMSG: DB ",U=", 000H
CTLTRKMSG: DB ",C=", 000H
DMAMSG: DB ",DMA=", 000H
INFOMSG: DB "AF=", NUL
INFOMSG2: DB ",BC=", 000H
INFOMSG3: DB ",DE=", 000H
INFOMSG4: DB ",HL=", 000H
INFOMSG5: DB ",SP=", 000H
; Seperate stack for the debugger so as not to affect anything it is reporting on.
;
DBGSTACKP: DS 2
DS 128, 0AAH
DBGSTACK: EQU $
ALIGN 00400H
ENDIF
;-------------------------------------------------------------------------------
; END OF DEBUGGING FUNCTIONALITY
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; START OF STATIC LOOKUP TABLES AND CONSTANTS
;-------------------------------------------------------------------------------
;--------------------------------------
; Test Message table
;--------------------------------------
TESTTZSIGNON:DB "** tranZPUter Tester Program (C) P.D. Smart, 2020 **", CR, CR, NUL
MSGTEST1: DB "E0/E4 Test, write into RAM and see if it writes onto the Monitor ROM.", CR, "A downcount is the write pattern, first column is ROM contents", CR, NUL
MSGFAIL: DB " - Failed at loop count: ", NUL
MSGDONE: DB "Tests complete.", CR, NUL
;-------------------------------------------------------------------------------
; END OF STATIC LOOKUP TABLES AND CONSTANTS
;-------------------------------------------------------------------------------
PGMEND: EQU $