diff --git a/.gitignore b/.gitignore index 18cef4e0..bb8e3c86 100644 --- a/.gitignore +++ b/.gitignore @@ -78,6 +78,7 @@ Tools/unix/zx/zx !Source/Apps/FAT/FAT.COM !Source/Apps/ZMP/zmpx.com !Source/Apps/ZMD/zmdsubs.rel +!Source/Apps/Test/vdctest/font.asm !Source/BPBIOS/bpbuild.com !Source/BPBIOS/movp112.com !Source/BPBIOS/*.lib diff --git a/Source/Apps/Test/Build.cmd b/Source/Apps/Test/Build.cmd index d15ea50d..139ea0c9 100644 --- a/Source/Apps/Test/Build.cmd +++ b/Source/Apps/Test/Build.cmd @@ -19,6 +19,9 @@ pushd ppidetst && call Build || exit /b & popd pushd ramtest && call Build || exit /b & popd pushd I2C && call Build || exit /b & popd pushd rzsz && call Build || exit /b & popd +pushd vdctest && call Build || exit /b & popd +pushd kbdtest && call Build || exit /b & popd +pushd kbdinfo && call Build || exit /b & popd goto :eof diff --git a/Source/Apps/Test/Clean.cmd b/Source/Apps/Test/Clean.cmd index ee9af6ad..3cb2cdfa 100644 --- a/Source/Apps/Test/Clean.cmd +++ b/Source/Apps/Test/Clean.cmd @@ -14,3 +14,6 @@ pushd ppidetst && call Clean || exit /b 1 & popd pushd ramtest && call Clean || exit /b 1 & popd pushd I2C && call Clean || exit /b 1 & popd pushd rzsz && call Clean || exit /b 1 & popd +pushd vdctest && call Clean || exit /b 1 & popd +pushd kbdtest && call Clean || exit /b 1 & popd +pushd kbdinfo && call Clean || exit /b 1 & popd diff --git a/Source/Apps/Test/Makefile b/Source/Apps/Test/Makefile index 61717011..3c844c01 100644 --- a/Source/Apps/Test/Makefile +++ b/Source/Apps/Test/Makefile @@ -1,5 +1,5 @@ OBJECTS = -SUBDIRS = DMAmon I2C inttest ppidetst ramtest tstdskng rzsz +SUBDIRS = DMAmon I2C inttest ppidetst ramtest tstdskng rzsz vdctest kbdtest kbdinfo DEST = ../../../Binary/Apps/Test TOOLS =../../../Tools diff --git a/Source/Apps/Test/kbdinfo/Build.cmd b/Source/Apps/Test/kbdinfo/Build.cmd new file mode 100644 index 00000000..1f9866d6 --- /dev/null +++ b/Source/Apps/Test/kbdinfo/Build.cmd @@ -0,0 +1,10 @@ +@echo off +setlocal + +set TOOLS=../../../../Tools +set PATH=%TOOLS%\tasm32;%PATH% +set TASMTABS=%TOOLS%\tasm32 + +tasm -t180 -g3 -fFF kbdinfo.asm kbdinfo.com kbdinfo.lst || exit /b + +copy /Y kbdinfo.com ..\..\..\..\Binary\Apps\Test\ || exit /b diff --git a/Source/Apps/Test/kbdinfo/Clean.cmd b/Source/Apps/Test/kbdinfo/Clean.cmd new file mode 100644 index 00000000..9ecb428f --- /dev/null +++ b/Source/Apps/Test/kbdinfo/Clean.cmd @@ -0,0 +1,6 @@ +@echo off +setlocal + +if exist *.com del *.com +if exist *.lst del *.lst +if exist *.bin del *.bin diff --git a/Source/Apps/Test/kbdinfo/Makefile b/Source/Apps/Test/kbdinfo/Makefile new file mode 100644 index 00000000..3525056d --- /dev/null +++ b/Source/Apps/Test/kbdinfo/Makefile @@ -0,0 +1,7 @@ +OBJECTS = kbdinfo.com +DEST = ../../../../Binary/Apps/Test +TOOLS =../../../../Tools + +USETASM=1 + +include $(TOOLS)/Makefile.inc \ No newline at end of file diff --git a/Source/Apps/Test/kbdinfo/kbdinfo.asm b/Source/Apps/Test/kbdinfo/kbdinfo.asm new file mode 100644 index 00000000..151db818 --- /dev/null +++ b/Source/Apps/Test/kbdinfo/kbdinfo.asm @@ -0,0 +1,869 @@ +; +;======================================================================= +; Keyboard Information Utility (KBDINFO) +;======================================================================= +; +; Simple utility that attempts to determine the type of keyboard you +; have attached to an 8242 keyboard controller. +; +;======================================================================= +; +; Keyboard controller port addresses (adjust as needed) +; +iocmd .equ $E3 ; keyboard controller command port address +iodat .equ $E2 ; keyboard controller data port address +; +cpumhz .equ 8 ; for time delay calculations (not critical) +; +; General operational equates (should not requre adjustment) +; +stksiz .equ $40 ; Working stack size +; +ltimout .equ 0 ; 256*10ms = 2.56s +stimout .equ 10 ; 10*10ms = 100ms +; +restart .equ $0000 ; CP/M restart vector +bdos .equ $0005 ; BDOS invocation vector +; +;======================================================================= +; + .org $100 ; standard CP/M executable +; +; + ; setup stack (save old value) + ld (stksav),sp ; save stack + ld sp,stack ; set new stack +; + call crlf + ld de,str_banner ; banner + call prtstr +; + call main ; do the real work + jr z,exit ; completed all tests + ld de,str_run_failed + call crlf2 + call prtstr +; +exit: + call crlf2 + ld de,str_exit + call prtstr + + ; clean up and return to command processor + call crlf ; formatting + ld sp,(stksav) ; restore stack + jp restart ; return to CP/M via restart +; +; +;======================================================================= +; Main Program +;======================================================================= +; +main: +; +; Display active keyboard controller port addresses +; + call crlf2 + ld de,str_cmdport + call prtstr + ld a,iocmd + call prthex + call crlf + ld de,str_dataport + call prtstr + ld a,iodat + call prthex +; +; First, we attempt to contact the controller and keyboard, then +; print the keyboard identity and scan codes scupported +; + ; Run test series with translation off + call crlf2 + ld de,str_basic + call prtstr +; + call do_basic + ret nz +; +; We make two passes through the test series with different controller +; setup values. The first time is with scan code translation off and +; the second time with it on. +; + ; Run test series with translation off + call crlf2 + ld de,str_trans_off + call prtstr +; + ld a,$20 ; xlat disabled, mouse disabled, no ints + ld (ctlr_cfgval),a + call do_tests +; + ; Run test series with translation on + call crlf2 + ld de,str_trans_on + call prtstr +; + ld a,$60 ; xlat enabled, mouse disabled, no ints + ld (ctlr_cfgval),a + call do_tests + + xor a ; signal success + ret +; +; Perform basic keyboard tests, display keyboard identity, and +; inventory the supported scan code sets. +; +do_basic: + call ctlr_test + ret nz +; + ld a,$20 ; Xlat off for this checking + call ctlr_setup + ret nz +; + call kbd_reset + ret nz +; + call kbd_ident + ;ret nz +; + ld b,3 ; Loop control, 3 scan code sets + ld c,1 ; Current scan code number +do_basic1: + ld a,c ; Scan code set to A + push bc + call kbd_setsc ; Attempt to set it + pop bc + push af ; save result + call crlf2 + ld de,str_sc_tag + call prtstr + ld a,c + call prtdecb + pop af ; restore result + ld de,str_sc_ok + jr z,do_basic2 + ld de,str_sc_fail +do_basic2: + call prtstr + inc c + djnz do_basic1 +; + xor a ; signal success + ret +; +; This routine runs a series of controller and keyboard tests. The +; desired controller setup value should be placed in ctlr_cfgval +; prior to invoking this routine. +; +do_tests: + call ctlr_test + ret nz +; + ld a,(ctlr_cfgval) + call ctlr_setup + ret nz +; + call kbd_reset + ret nz +; + call kbd_ident + ;ret nz +; + ld a,2 + call kbd_setsc + ;ret nz +; + call kbd_dispsc + ;ret nz +; + call kbd_showkeys + ;ret nz +; + xor a ; signal success + ret +; +;======================================================================= +; Keyboard/Controller Test Routines +;======================================================================= +; +; Attempt self-test command on keyboard controller +; +; Keyboard controller should respond with an 0x55 on data port +; after being sent a 0xAA on the command port. +; +ctlr_test: + call crlf2 + ld de,str_ctlr_test + call prtstr + ld a,$aa ; self-test command + call put_cmd_dbg + jp c,err_ctlr_to ; handle controller error + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + cp $55 ; expected value? + jp nz,err_ctlr_test ; handle self-test error + call crlf + ld de,str_ctlr_test_ok + call prtstr + xor a + ret +; +; Keyboard controller setup +; +; Set keyboard controller command register to value in A +; +ctlr_setup: + push af ; save incoming value + call crlf2 + ld de,str_ctlr_setup + call prtstr + ld a,$60 ; write to command register 0 + call put_cmd_dbg + pop bc ; recover incoming to B + jp c,err_ctlr_to ; handle controller error + ld a,b + call put_data_dbg + jp c,err_ctlr_to ; handle controller error + xor a + ret +; +; Perform a keyboard reset +; +kbd_reset: + call crlf2 + ld de,str_kbd_reset + call prtstr + ld a,$ff ; Keyboard reset + call put_data_dbg + jp c,err_ctlr_to ; handle controller error + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + cp $FA ; Is it an ack as expected? + jp nz,err_kbd_reset + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + cp $AA ; Success? + jp nz,err_kbd_reset + call crlf + ld de,str_kbd_reset_ok + call prtstr + xor a + ret +; +; Identify keyboard +; +kbd_ident: + call crlf2 + ld de,str_kbd_ident + call prtstr + ld a,$f2 ; Identify keyboard command + call put_data_dbg + jp c,err_ctlr_to ; handle controller error + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + cp $FA ; Is it an ack as expected? + jp nz,err_kbd_ident + ; Now we need to receive 0-2 bytes. There is no way to know + ; how many are coming, so we receive bytes until there is a + ; timeout error. Timeout is shortened here so that we don't + ; have to wait seconds for the routine to complete normally. + ; A short timeout is more than sufficient here. + ld ix,workbuf + ld a,(timeout) ; save current timeout + push af + ld a,stimout ; set a short timeout + ld (timeout),a + ld b,8 ; buf max + ld c,0 ; buf len +kbd_ident1: + push bc + call get_data_dbg + pop bc + jr c,kbd_ident2 + ld (ix),a + inc ix + inc c + djnz kbd_ident1 +kbd_ident2: + pop af ; restore original timeout + ld (timeout),a + call crlf + ld de,str_kbd_ident_disp + call prtstr + ld a,'[' + call prtchr + ld ix,workbuf + ld a,c ; bytes to print + or a ; check for zero + jr z,kbd_ident4 ; handle zero + ld b,a ; setup loop counter + jr kbd_ident3a +kbd_ident3: + ld a,',' + call prtchr +kbd_ident3a: + ld a,(ix) + call prthex + inc ix + djnz kbd_ident3 +kbd_ident4: + ld a,']' + call prtchr + xor a + ret +; +; Display active scan code set being used +; +kbd_dispsc: + call crlf2 + ld de,str_kbd_getsc + call prtstr + ld a,$f0 ; Keyboard get/set scan code + call put_data_dbg + jp c,err_ctlr_to ; handle controller error + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + cp $FA ; Is it an ack as expected? + jp nz,err_kbd_getsc + ld a,$00 ; Get active scan code set + call put_data_dbg + jp c,err_ctlr_to ; handle controller error + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + cp $FA ; Is it an ack as expected? + jp nz,err_kbd_getsc + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + push af + call crlf + ld de,str_kbd_dispsc + call prtstr + pop af + call prtdecb + xor a + ret +; +; Set active scan code set to value in A +; +kbd_setsc: + ld (kbd_setsc_val),a ; Save incoming value + call crlf2 + ld de,str_kbd_setsc + call prtstr + call prtdecb + ld a,$f0 ; Keyboard get/set scan code + call put_data_dbg + jp c,err_ctlr_to ; handle controller error + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + cp $FA ; Is it an ack as expected? + jp nz,err_kbd_setsc + ld a,(kbd_setsc_val) ; Recover scan code set value + call put_data_dbg + jp c,err_ctlr_to ; handle controller error + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + cp $FA ; Is it an ack as expected? + jp nz,err_kbd_setsc + xor a + ret +; +kbd_setsc_val .db 0 +; +; +; Read and display raw scan codes +; +kbd_showkeys: + call crlf2 + ld de,str_disp_scan_codes + call prtstr +read_loop: + ld c,$06 ; BDOS direct console I/O + ld e,$FF ; Subfunction = read + call bdos + cp $1B ; Escape key? + ret z + call check_read + jr nz,read_loop + call get_data + jp c,err_ctlr_to ; handle controller error + push af + ld a,' ' + call prtchr + ld a,'[' + call prtchr + pop af + call prthex + ld a,']' + call prtchr + jr read_loop +; +;======================================================================= +; Keyboard Controller I/O Routines +;======================================================================= +; +wait_write: +; +; Wait for keyboard controller to be ready for a write +; A=0 indicates success (ZF set) +; + ld a,(timeout) ; setup timeout constant + ld b,a +wait_write1: + in a,(iocmd) ; get status + ld c,a ; save status + and $02 ; isolate input buf status bit + ret z ; 0 means ready, all done + call delay ; wait a bit + djnz wait_write1 ; loop until counter exhausted +; ld de,str_timeout_write ; write timeout message +; call crlf +; call prtstr +; ld a,c ; recover last status value +; call prthex + or $ff ; signal error + ret +; +wait_read: +; +; Wait for keyboard controller to be ready to read a byte +; A=0 indicates success (ZF set) +; + ld a,(timeout) ; setup timeout constant + ld b,a +wait_read1: + in a,(iocmd) ; get status + ld c,a ; save status + and $01 ; isolate input buf status bit + xor $01 ; invert so 0 means ready + ret z ; if 0, all done + call delay ; wait a bit + djnz wait_read1 ; loop until counter exhausted +; ld de,str_timeout_read ; write timeout message +; call crlf +; call prtstr +; ld a,c ; recover last status value +; call prthex + or $ff ; signal error + ret +; +check_read: +; +; Check for data ready to read +; A=0 indicates data available (ZF set) +; + in a,(iocmd) ; get status + and $01 ; isolate input buf status bit + xor $01 ; invert so 0 means ready + ret +; +put_cmd: +; +; Put a cmd byte from A to the keyboard interface with timeout +; CF set indicates timeout error +; + ld e,a ; save incoming value + call wait_write ; wait for controller ready + jr z,put_cmd1 ; if ready, move on + scf ; else, signal timeout error + ret ; and bail out +put_cmd1: + ld a,e ; recover value to write + out (iocmd),a ; write it + or a ; clear CF for success + ret +; +put_cmd_dbg: + call put_cmd + ret c + push af + + call crlf + ld de,str_put_cmd + call prtstr + call prthex + +; ld de,str_prefix ; " " +; call prtstr +; call prthex +; ld de,str_cmdout ; "->(CMD)" +; call prtstr + + pop af + ret +; +put_data: +; +; Put a data byte from A to the keyboard interface with timeout +; CF set indicates timeout error +; + ld e,a ; save incoming value + call wait_write ; wait for controller ready + jr z,put_data1 ; if ready, move on + scf ; else, signal timeout error + ret ; and bail out +put_data1: + ld a,e ; recover value to write + out (iodat),a ; write it + or a ; clear CF for success + ret +; +put_data_dbg: + call put_data + ret c + push af + + call crlf + ld de,str_put_data + call prtstr + call prthex + +; ld de,str_prefix ; " " +; call prtstr +; call prthex +; ld de,str_dataout ; "->(DATA)" +; call prtstr + + pop af + ret + +; +; Get a data byte from the keyboard interface to A with timeout +; CF set indicates timeout error +; +get_data: + call wait_read ; wait for byte to be ready + jr z,get_data1 ; if readym, move on + scf ; else signal timeout error + ret ; and bail out +get_data1: + in a,(iodat) ; get data byte + or a ; clear CF for success + ret +; +get_data_dbg: + call get_data + ret c + push af + + call crlf + ld de,str_get_data + call prtstr + call prthex + +; ld de,str_datain ; " (DATA)->" +; call prtstr +; call prthex + + pop af + ret +; +; Error Handlers +; +err_ctlr_to: + ld de,str_err_ctlr_to + jr err_ret +; +err_ctlr_test: + ld de,str_err_ctlr_test + jr err_ret +; +err_kbd_reset: + ld de,str_err_kbd_reset + jr err_ret +; +err_kbd_getsc: + ld de,str_err_kbd_getsc + jr err_ret +; +err_kbd_setsc: + ld de,str_err_kbd_setsc + jr err_ret +; +err_kbd_ident: + ld de,str_err_kbd_ident + jr err_ret +; +err_ret: + call crlf2 + call prtstr + or $ff ; signal error + ret +; +;======================================================================= +; Utility Routines +;======================================================================= +; +; +; Print character in A without destroying any registers +; +prtchr: + push bc ; save registers + push de + push hl + ld e,a ; character to print in E + ld c,$02 ; BDOS function to output a character + call bdos ; do it + pop hl ; restore registers + pop de + pop bc + ret +; +prtdot: +; + ; shortcut to print a dot preserving all regs + push af ; save af + ld a,'.' ; load dot char + call prtchr ; print it + pop af ; restore af + ret ; done +; +; Print a zero terminated string at (de) without destroying any registers +; +prtstr: + push af + push de +; +prtstr1: + ld a,(de) ; get next char + or a + jr z,prtstr2 + call prtchr + inc de + jr prtstr1 +; +prtstr2: + pop de ; restore registers + pop af + ret +; +; Print a hex value prefix "0x" +; +prthexpre: + push af + ld a,'0' + call prtchr + ld a,'x' + call prtchr + pop af + ret + +; +; Print the value in A in hex without destroying any registers +; +prthex: + call prthexpre +prthex1: + push af ; save AF + push de ; save DE + call hexascii ; convert value in A to hex chars in DE + ld a,d ; get the high order hex char + call prtchr ; print it + ld a,e ; get the low order hex char + call prtchr ; print it + pop de ; restore DE + pop af ; restore AF + ret ; done +; +; print the hex word value in hl +; +prthexword: + call prthexpre +prthexword1: + push af + ld a,h + call prthex1 + ld a,l + call prthex1 + pop af + ret +; +; print the hex dword value in de:hl +; +prthex32: + call prthexpre + push bc + push de + pop bc + call prthexword1 + push hl + pop bc + call prthexword1 + pop bc + ret +; +; Convert binary value in A to ascii hex characters in DE +; +hexascii: + ld d,a ; save A in D + call hexconv ; convert low nibble of A to hex + ld e,a ; save it in E + ld a,d ; get original value back + rlca ; rotate high order nibble to low bits + rlca + rlca + rlca + call hexconv ; convert nibble + ld d,a ; save it in D + ret ; done +; +; Convert low nibble of A to ascii hex +; +hexconv: + and $0F ; low nibble only + add a,$90 + daa + adc a,$40 + daa + ret +; +; Print value of A or HL in decimal with leading zero suppression +; Use prtdecb for A or prtdecw for HL +; +prtdecb: + push hl + ld h,0 + ld l,a + call prtdecw ; print it + pop hl + ret +; +prtdecw: + push af + push bc + push de + push hl + call prtdec0 + pop hl + pop de + pop bc + pop af + ret +; +prtdec0: + ld e,'0' + ld bc,-10000 + call prtdec1 + ld bc,-1000 + call prtdec1 + ld bc,-100 + call prtdec1 + ld c,-10 + call prtdec1 + ld e,0 + ld c,-1 +prtdec1: + ld a,'0' - 1 +prtdec2: + inc a + add hl,bc + jr c,prtdec2 + sbc hl,bc + cp e + ret z + ld e,0 + call prtchr + ret +; +; Start a new line +; +crlf2: + call crlf ; two of them +crlf: + push af ; preserve AF + ld a,13 ; + call prtchr ; print it + ld a,10 ; + call prtchr ; print it + pop af ; restore AF + ret +; +; Delay ~10ms +; +delay: + push af + push de + ld de,625 ; 10000us/16us +delay0: + ld a,(cpuscl) +delay1: + dec a + jr nz,delay1 + dec de + ld a,d + or e + jp nz,delay0 + pop de + pop af + ret +; +; +; +;======================================================================= +; Constants +;======================================================================= +; +str_banner .db "Keyboard Information v0.2, 23-Dec-2021",0 +str_exit .db "Done, Thank you for using Keyboard Information!",0 +str_cmdport .db "Keyboard Controller Command Port: ",0 +str_dataport .db "Keyboard Controller Data Port: ",0 +;str_prefix .db " ",0 +;str_cmdout .db "->(CMD)",0 +;str_dataout .db "->(DATA)",0 +;str_datain .db " (DATA)->",0 +;str_timeout_write .db "Keyboard Controller Write Timeout, Status: ",0 +;str_timeout_read .db "Keyboard Controller Read Timeout, Status: ",0 +str_err_ctlr_to .db "Keyboard Controller I/O Timeout",0 +str_err_ctlr_test .db "Keyboard Controller Self-Test Failed",0 +str_put_cmd .db " Sent Command ",0 +str_put_data .db " Sent Data ",0 +str_get_data .db " Got Data ",0 +str_ctlr_test .db "Attempting Controller Self-Test",0 +str_ctlr_test_ok .db "Controller Self-Test OK",0 +str_ctlr_setup .db "Performing Controller Setup",0 +str_basic .db "***** Basic Keyboard Checks and Scan Code Inventory *****",0 +str_trans_off .db "***** Testing with Scan Code Translation DISABLED *****",0 +str_trans_on .db "***** Testing with Scan Code Translation ENABLED *****",0 +str_kbd_reset .db "Attempting Keyboard Reset",0 +str_kbd_reset_ok .db "Keyboard Reset OK",0 +str_err_kbd_reset .db "Keyboard Reset Failed",0 +str_kbd_getsc .db "Requesting Active Scan Code Set from Keyboard",0 +str_kbd_dispsc .db "Active Keyboard Scan Code Set is #",0 +str_err_kbd_getsc .db "Error getting Active Keyboard Scan Code Set",0 +str_kbd_setsc .db "Setting Active Keyboard Scan Code Set to #",0 +str_err_kbd_setsc .db "Error setting Active Keyboard Scan Code Set",0 +str_kbd_ident .db "Keyboard Identification",0 +str_kbd_ident_disp .db "Keyboard Identity: ",0 +str_sc_tag .db "Scan Code Set #",0 +str_sc_ok .db " IS supported",0 +str_sc_fail .db " IS NOT supported",0 +str_err_kbd_ident .db "Error performing Keyboard Identification",0 +str_disp_scan_codes .db "Displaying Raw Scan Codes",13,10 + .db " Press keys on test keyboard to display scan codes",13,10 + .db " Press on CP/M console to end",13,10,13,10,0 +str_run_failed .db "***** HARDWARE ERROR *****",13,10,13,10 + .db "A basic hardware or configuration issue prevented",13,10 + .db "Keyboard Information from completing the full set",13,10 + .db "of tests. Check your hardware and verify the port",13,10 + .db "addresses being used for the keyboard controller",0 +; +;======================================================================= +; Working data +;======================================================================= +; +stksav .dw 0 ; stack pointer saved at start + .fill stksiz,0 ; stack +stack .equ $ ; stack top +; +workbuf .fill 8 +workbuf_len .db 0 +; +ctlr_cfgval .db 0 ; Value for controller cmd reg 0 +; +cpuscl .db cpumhz - 2 +timeout .db ltimout +; +;======================================================================= +; + .end \ No newline at end of file diff --git a/Source/Apps/Test/kbdtest/Build.cmd b/Source/Apps/Test/kbdtest/Build.cmd new file mode 100644 index 00000000..5ae6b746 --- /dev/null +++ b/Source/Apps/Test/kbdtest/Build.cmd @@ -0,0 +1,11 @@ +@echo off +setlocal + +set TOOLS=../../../../Tools +set PATH=%TOOLS%\tasm32;%PATH% +set TASMTABS=%TOOLS%\tasm32 + +tasm -t180 -g3 -fFF kbdtest.asm kbdtest.com kbdtest.lst || exit /b + +copy /Y kbdtest.com ..\..\..\..\Binary\Apps\Test\ || exit /b + diff --git a/Source/Apps/Test/kbdtest/Clean.cmd b/Source/Apps/Test/kbdtest/Clean.cmd new file mode 100644 index 00000000..9ecb428f --- /dev/null +++ b/Source/Apps/Test/kbdtest/Clean.cmd @@ -0,0 +1,6 @@ +@echo off +setlocal + +if exist *.com del *.com +if exist *.lst del *.lst +if exist *.bin del *.bin diff --git a/Source/Apps/Test/kbdtest/Makefile b/Source/Apps/Test/kbdtest/Makefile new file mode 100644 index 00000000..f83c46d4 --- /dev/null +++ b/Source/Apps/Test/kbdtest/Makefile @@ -0,0 +1,7 @@ +OBJECTS = kbdtest.com +DEST = ../../../../Binary/Apps/Test +TOOLS =../../../../Tools + +USETASM=1 + +include $(TOOLS)/Makefile.inc \ No newline at end of file diff --git a/Source/Apps/Test/kbdtest/kbdtest.asm b/Source/Apps/Test/kbdtest/kbdtest.asm new file mode 100644 index 00000000..84f43664 --- /dev/null +++ b/Source/Apps/Test/kbdtest/kbdtest.asm @@ -0,0 +1,368 @@ +; +; Test program for Z80 KBDMSE on Retrobrewcomputer.org (Load with CPM). +; +; V0.1 ;Original version 2/23/2014 by John Monahan +; V0.2 ;Update for Z80 KBDMSE with VT82C42 PS/2 Keyboard Controller by Andrew Lynch +; +; Based on works by John Monahan S100Computers.com +; for S100 MSDOS Support Board with HT6542B Keyboard Controller +; Thanks to John for generously posting this program for others to use and adapt +; +; This is a simple test program to work with the Z80 KBDMSE board. It is written so +; the only other hardware use is the CP/M Console Port -- typically serial port interface. +; Note the data is displayed in crude (bulk) form. A proper scancode to ASCII translation +; routine must be written for practical use. See the IBM PC BIOS or SKEY.Z80 docs + + + +; PORT ASSIGNMENTS + +KEY_DATA .EQU 0E2H ;Port used to access keyboard & Mouse (also sometimes Controller itself) +KEY_CTRL .EQU 0E3H ;Port for VT82C42 PS/2 Keyboard & Mouse Controller + +ESC .EQU 1BH +CR .EQU 0DH +LF .EQU 0AH +TAB .EQU 09H +BELL .EQU 07H + + .ORG 0100H +START: + LD SP,STACK + + LD HL,SIGNON ; Signon + CALL PRINT_STRING + + LD C,0AAH ;Test PS/2 Controller + CALL CMD_OUT +CHK1: + CALL KEY_IN_STATUS ;wait for feedback + JR Z,CHK1 + IN A,(KEY_DATA) + CP 055H ;If not 55H then error + JR NZ,INIT_ERR + LD C,060H ; Set keyboard controller cmd byte + CALL CMD_OUT + LD C,$60 ; XLAT ENABLED, MOUSE DISABLED, NO INTS + CALL KEY_OUT + LD C,0AEH ;Enable 1st PS/2 port + CALL CMD_OUT ;Send it + JR DONE_INIT + +INIT_ERR: + LD HL,INIT_ERR_STR ;Say error + CALL PRINT_STRING + HALT ;Just Halt! + +DONE_INIT: + LD HL,INIT_OK ;Say all OK + CALL PRINT_STRING + +LOOP: + CALL KEY_IN_STATUS ;See if keyboard key available + JR Z,LOOP + IN A,(KEY_DATA) + LD C,A ;Store in [C] + LD HL,SCAN_MSG + CALL PRINT_STRING ;No registers changed + + CALL A_HEXOUT ;Display Hex value of typed character + two spaces + + ;CP 0F0H ;Is it an UP key + AND 080H ;Is it an UP key + JR Z,DOWNKY ;Must be a down key stroke + LD HL,UPKEY_MSG ;Say Up Key + CALL PRINT_STRING + CALL ZCRLF + JR LOOP + +DOWNKY: + CP 58H ;Is it CAPS Lock key +; CP 3AH ;Is it CAPS Lock key + JR NZ,NOT_CAPSKEY + LD HL,CAPS_MSG ;Say Caps lock key + CALL PRINT_STRING + CALL ZCRLF + JR LOOP + +NOT_CAPSKEY: + CP 12H ;Is it a SHIFT key +; CP 2AH ;Is it a SHIFT key + JR Z,SHIFTKEY + CP 59H ;Is it the other SHIFT key +; CP 36H ;Is it the other SHIFT key + JR NZ,NOT_SHIFTKEY + +SHIFTKEY: + LD HL,SHIFT_MSG ;Say Shift key + CALL PRINT_STRING + CALL ZCRLF + JR LOOP + +NOT_SHIFTKEY: + CP 14H ;Is it the CTRL key +; CP 1DH ;Is it the CTRL key + JR NZ,NOT_CTRLKEY + LD HL,CTRL_MSG ;Say CTRL key + CALL PRINT_STRING + CALL ZCRLF + JR LOOP + +NOT_CTRLKEY: + CP 77H ;Is it the NUM LOCK key +; CP 45H ;Is it the NUM LOCK key + JR NZ,NOT_NUMKEY + LD HL,NUM_MSG ;Say Number key + CALL PRINT_STRING + CALL ZCRLF + JR LOOP + +NOT_NUMKEY: + PUSH BC ;Save Character + LD HL,IBM1_MSG ;Say Table 1 lookup + CALL PRINT_STRING + LD HL,IBM1TBL ;Point to lookup table for upper case + CALL SHOW_CHAR + + POP BC ;Get back character + LD HL,IBM2_MSG ;Say Table 2 lookup + CALL PRINT_STRING + LD HL,IBM2TBL ;Point to lookup table for upper case + CALL SHOW_CHAR + + CALL ZCRLF + JR LOOP + +SHOW_CHAR: + LD D,0 + LD E,C + ADD HL,DE ;Add in offset + LD C,(HL) + LD A,C + CP ESC + RET Z ;ESC messes up the screen display + CP CR + RET Z ;CR messes up the screen display + CP LF + RET Z ;LF messes up the screen display + CP TAB + RET Z ;TAB messes up the screen display + CALL ZCO ;Display on Screen + RET + +KEY_IN_STATUS: ;Ret NZ if character is available + IN A,(KEY_CTRL) + AND 1 + RET ;Ret NZ if character available + +CMD_OUT: ;Send a byte (in [C]) to Control port + IN A,(KEY_CTRL) + AND 2 + JR NZ,CMD_OUT ;Chip is not ready yet to receive character + LD A,C + OUT (KEY_CTRL),A + RET + +KEY_OUT: ;Send a byte (in [C]) to Data port + IN A,(KEY_CTRL) + AND 2 + JR NZ,KEY_OUT ;Chip is not ready yet to receive character + LD A,C + OUT (KEY_DATA),A + RET + + +; A_HEXOUT ;output the 2 hex digits in [A] +A_HEXOUT: ;No registers altered + push AF + push BC + push AF + srl a + srl a + srl a + srl a + call hexdigout + pop AF + call hexdigout ;get upper nibble + LD C,' ' + call ZCO ;Space for easy reading + call ZCO + pop BC + pop AF + ret + +hexdigout: + and 0fh ;convert nibble to ascii + add a,90h + daa + adc a,40h + daa + LD c,a + call ZCO + ret + +; Main console I/O routines +; + +ZCO: + PUSH HL + LD E,C + LD C,02H ;BDOS Function 2 Write Console Byte + CALL 0005H ;Call BDOS + POP HL + RET + +ZCI: + LD C,0BH ;BDOS Function 11 Read Console Status + CALL 0005H ;Call BDOS + JP Z,ZCI + LD C,01H ;BDOS Function 1 Read Console Byte + CALL 0005H ;Call BDOS + RET +; +; Send CR/LF to Console +; +ZCRLF: + PUSH AF + PUSH BC + LD C,CR + CALL ZCO + LD C,LF + CALL ZCO + POP BC + POP AF + RET + + +PRINT_STRING: + PUSH AF + push BC +print1: + LD a,(HL) ;Point to start of string + inc HL ;By using the CS over-ride we will always have + CP '$' ;a valid pointer to messages at the end of this monitor + JP z,print2 + CP 0 ;Also terminate with 0's + JP Z,print2 + LD C,A + call ZCO + jp print1 +print2: + pop BC + POP AF + ret + +;--------------------------------------------------------------------------------------------------- + +SIGNON: + .DB CR,LF,LF + .DB "Test VT82C42 PC Keyboard & Mouse controller chip on Z80 KBDMSE Board." + .DB CR,LF,"$" +INIT_ERR_STR: + .DB CR,LF,BELL + .DB "Error: The 0xAA Test of Controller did nor return 0x55. Program Halted." + .DB CR,LF,"$" +INIT_OK: + .DB CR,LF + .DB "The 0xAA Test of Controller returned 0x55. Now enter keyboard keys." + .DB CR,LF,LF,"$" + +SCAN_MSG: + .DB "Scancode = $" +UPKEY_MSG: + .DB "(Up Keystroke)$" +CAPS_MSG: + .DB "(Caps Lock)$" +SHIFT_MSG: + .DB "(Shift Key)$" +CTRL_MSG: + .DB "(CTRL Key)$" +NUM_MSG: + .DB "(NUM Key)$" +IBM1_MSG: + .DB "Table 1 lookup -> $" +IBM2_MSG: + .DB " Table 2 lookup -> $" + + +IBM1TBL: ;The "Normal" table + ;00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f +; .DB 0,"*", 0,"*","*","*","*","*", 0,"*","*","*","*",09H,"`",00H + .DB 000,027,"1","2","3","4","5","6","7","8","9","0","-","=",008,009 ;00-0F + + ;10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1a, 1b, 1c, 1d, 1e, 1f +; .DB 0, 0, 0, 0, 0,"q","1", 0, 0, 0,"z","s","a","w","2",0 + .DB "q","w","e","r","t","y","u","i","o","p","[","]",013,000,"a","s" ;10-1F + + ;20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 2a, 2b, 2c, 2d, 2e, 2f +; .DB 0,"c","x","d","e","4","3", 0, 0," ","v","f","t","r","5",0 + .DB "d","f","g","h","j","k","l",";",27H,60H,000,092,"z","x","c","v" ;20-2F + + ;30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 3a, 3b, 3c, 3d, 3e, 3f +; .DB 0,"n","b","h","g","y","6", 0, 0, 0,"m","j","u","7","8",0 + .DB "b","n","m",",",".","/",000,000,000," ",000,000,000,000,000,000 ;30-3F + + ;40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 4a, 4b, 4c, 4d, 4e, 4f +; .DB 0,",","k","i","o","0","9", 0, 0,".","/","l",";","p","-",0 + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;40-4F + + ;50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 5a, 5b, 5c, 5d, 5e, 5f +; .DB 0, 0,27H, 0,"[","=", 0, 0, 0, 0,0DH,"]", 0,5CH, 0,0 + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;50-5F + + ;60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 6a, 6b, 6c, 6d, 6e, 6f +; .DB 0, 0, 0, 0, 0, 0,08H, 0, 0,11H, 0,13H,10H, 0, 0, 0 + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;60-6F + + ;70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 7a, 7b, 7c, 7d, 7e, 7f +; .DB 0BH,7FH,03H,15H,04H,05H,1BH,00H,"*",02H,18H,16H,0CH,17H,"*",0 + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;70-7F + + ;80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 8a, 8b, 8c, 8d, 8e, 8f +; .DB 0, 0, 0,"*", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;80-8F + + +IBM2TBL: ;If the SHIFT key or CAPS lock key is on + ;00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f +; .DB 0, "*", 0,"*","*","*","*","*", 0,"*","*","*","*",09H,"~",00H + .DB 000,027,"!","@","#","$","%","^","&","*","(",")","_","+",008,009 ;00-0F + + ;10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1a, 1b, 1c, 1d, 1e, 1f +; .DB 0, 0, 0, 0, 0,"Q","!", 0, 0, 0,"Z","S","A","W","@",0 + .DB "Q","W","E","R","T","Y","U","I","O","P","{","}",013,000,"A","S" ;10-1F + + ;20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 2a, 2b, 2c, 2d, 2e, 2f +; .DB 0,"C","X","D","E","$","#", 0, 0," ","V","F","T","R","%",0 + .DB "D","F","G","H","J","K","L",":",034,"~",000,"|","Z","X","C","V" ;20-2F + + ;30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 3a, 3b, 3c, 3d, 3e, 3f +; .DB 0,"N","B","H","G","Y","^", 0, 0, 0,"M","J","U","&","*",0 + .DB "B","N","M","<",">","?",000,000,000," ",000,000,000,000,000,000 ;30-3F + + ;40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 4a, 4b, 4c, 4d, 4e, 4f +; .DB 0,"<","K","I","O",29H,"(", 0, 0,">","?","L",":","P", "_",0 + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;40-4F + + ;50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 5a, 5b, 5c, 5d, 5e, 5f +; .DB 0, 0,22H, 0,"{","+", 0, 0, 0, 0,0DH,"}", 0,"|", 0,0 + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;50-5F + + ;60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 6a, 6b, 6c, 6d, 6e, 6f +; .DB 0, 0, 0, 0, 0, 0,08H, 0, 0,11H, 0,13H,10H, 0, 0, 0 + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;60-6F + + ;70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 7a, 7b, 7c, 7d, 7e, 7f +; .DB 0BH,7FH,03H,15H,04H,05H,1BH,00H,"*",02H,18H,16H,0CH,17H,"*",0 + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;70-7F + + ;80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 8a, 8b, 8c, 8d, 8e, 8f +; .DB 0, 0, 0,"*", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;80-8F + + + .FILL 040H,000H +STACK: .DB 0H + .FILL 19,000H + +.END diff --git a/Source/Apps/Test/vdctest/Build.cmd b/Source/Apps/Test/vdctest/Build.cmd new file mode 100644 index 00000000..814cb585 --- /dev/null +++ b/Source/Apps/Test/vdctest/Build.cmd @@ -0,0 +1,12 @@ +@echo off +setlocal + +set TOOLS=../../../../Tools +set PATH=%TOOLS%\tasm32;%PATH% +set TASMTABS=%TOOLS%\tasm32 + +tasm -t180 -g3 -fFF vdctest.asm vdctest.com vdctest.lst || exit /b +tasm -t180 -g3 -fFF vdconly.asm vdconly.com vdconly.lst || exit /b + +copy /Y vdctest.com ..\..\..\..\Binary\Apps\Test\ || exit /b +copy /Y vdconly.com ..\..\..\..\Binary\Apps\Test\ || exit /b diff --git a/Source/Apps/Test/vdctest/Clean.cmd b/Source/Apps/Test/vdctest/Clean.cmd new file mode 100644 index 00000000..9ecb428f --- /dev/null +++ b/Source/Apps/Test/vdctest/Clean.cmd @@ -0,0 +1,6 @@ +@echo off +setlocal + +if exist *.com del *.com +if exist *.lst del *.lst +if exist *.bin del *.bin diff --git a/Source/Apps/Test/vdctest/Makefile b/Source/Apps/Test/vdctest/Makefile new file mode 100644 index 00000000..c182b787 --- /dev/null +++ b/Source/Apps/Test/vdctest/Makefile @@ -0,0 +1,7 @@ +OBJECTS = vdctest.com vdconly.com +DEST = ../../../../Binary/Apps/Test +TOOLS =../../../../Tools + +USETASM=1 + +include $(TOOLS)/Makefile.inc \ No newline at end of file diff --git a/Source/Apps/Test/vdctest/font.asm b/Source/Apps/Test/vdctest/font.asm new file mode 100644 index 00000000..67ce06ac --- /dev/null +++ b/Source/Apps/Test/vdctest/font.asm @@ -0,0 +1,1025 @@ +FONT: + .DB $18,$18,$18,$FF,$FF,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C0,$C0,$30,$30,$C0,$C0,$30,$30 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$18,$18,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $33,$33,$CC,$CC,$33,$33,$CC,$CC + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $33,$99,$CC,$66,$33,$99,$CC,$66 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F0,$F0,$F0,$F0,$F0,$F0,$F0,$F0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $CC,$CC,$33,$33,$CC,$CC,$33,$33 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $03,$03,$03,$03,$03,$03,$03,$03 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$CC,$CC,$33,$33 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $CC,$99,$33,$66,$CC,$99,$33,$66 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $03,$03,$03,$03,$03,$03,$03,$03 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$1F,$1F,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$0F,$0F,$0F,$0F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$1F,$1F,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$F8,$F8,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$1F,$1F,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$FF,$FF,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$FF,$FF,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$F8,$F8,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $07,$07,$07,$07,$07,$07,$07,$07 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $01,$03,$06,$6C,$78,$70,$60,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$18,$00,$00,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$66,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$FF,$66,$FF,$66,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$3E,$60,$3C,$06,$7C,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $62,$66,$0C,$18,$30,$66,$46,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$3C,$38,$67,$66,$3F,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $06,$0C,$18,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $0C,$18,$30,$30,$30,$18,$0C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $30,$18,$0C,$0C,$0C,$18,$30,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$66,$3C,$FF,$3C,$66,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$18,$18,$7E,$18,$18,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$18,$18,$30 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$7E,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$18,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$03,$06,$0C,$18,$30,$60,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$6E,$76,$66,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$38,$18,$18,$18,$7E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$06,$0C,$30,$60,$7E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$06,$1C,$06,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $06,$0E,$1E,$66,$7F,$06,$06,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7E,$60,$7C,$06,$06,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$60,$7C,$66,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7E,$66,$0C,$18,$18,$18,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$66,$3C,$66,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$66,$3E,$06,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$18,$00,$00,$18,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$18,$00,$00,$18,$18,$30 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $0E,$18,$30,$60,$30,$18,$0E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$7E,$00,$7E,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $70,$18,$0C,$06,$0C,$18,$70,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$06,$0C,$18,$00,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$6E,$6E,$60,$62,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$3C,$66,$7E,$66,$66,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7C,$66,$66,$7C,$66,$66,$7C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$60,$60,$60,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $78,$6C,$66,$66,$66,$6C,$78,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7E,$60,$60,$78,$60,$60,$7E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7E,$60,$60,$78,$60,$60,$60,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$60,$6E,$66,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$66,$7E,$66,$66,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$18,$18,$18,$18,$18,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $1E,$0C,$0C,$0C,$0C,$6C,$38,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$6C,$78,$70,$78,$6C,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $60,$60,$60,$60,$60,$60,$7E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $63,$77,$7F,$6B,$63,$63,$63,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$76,$7E,$7E,$6E,$66,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$66,$66,$66,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7C,$66,$66,$7C,$60,$60,$60,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$66,$66,$66,$3C,$0E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7C,$66,$66,$7C,$78,$6C,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$60,$3C,$06,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7E,$18,$18,$18,$18,$18,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$66,$66,$66,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$66,$66,$66,$3C,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $63,$63,$63,$6B,$7F,$77,$63,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$3C,$18,$3C,$66,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$66,$3C,$18,$18,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7E,$06,$0C,$18,$30,$60,$7E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$30,$30,$30,$30,$30,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $40,$60,$30,$18,$0C,$06,$02,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$0C,$0C,$0C,$0C,$0C,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$18,$24,$42,$42,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$30,$18,$0C,$04,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$3C,$06,$3E,$66,$3E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$60,$60,$7C,$66,$66,$7C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$3C,$60,$60,$60,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$06,$06,$3E,$66,$66,$3E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$3C,$66,$7E,$60,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$0E,$18,$3E,$18,$18,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$3E,$66,$66,$3E,$06,$7C + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$60,$60,$7C,$66,$66,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$18,$00,$38,$18,$18,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$06,$00,$06,$06,$06,$06,$3C + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$60,$60,$6C,$78,$6C,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$38,$18,$18,$18,$18,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$66,$7F,$7F,$6B,$63,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$7C,$66,$66,$66,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$3C,$66,$66,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$7C,$66,$66,$7C,$60,$60 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$3E,$66,$66,$3E,$06,$06 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$7C,$66,$60,$60,$60,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$3E,$60,$3C,$06,$7C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$18,$7E,$18,$18,$18,$0E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$66,$66,$66,$66,$3E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$66,$66,$66,$3C,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$63,$6B,$7F,$3E,$36,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$66,$3C,$18,$3C,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$66,$66,$66,$3E,$0C,$78 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$7E,$0C,$18,$30,$7E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$0C,$10,$10,$20,$10,$10,$0C + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$18,$18,$18,$18,$18,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$18,$04,$04,$02,$04,$04,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$32,$4C,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$81,$81,$81,$81,$81,$81,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F0,$F0,$F0,$F0,$0F,$0F,$0F,$0F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$91,$91,$9F,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$C3,$F9,$C1,$99,$C1,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$9F,$9F,$83,$99,$99,$83,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$C3,$9F,$9F,$9F,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$F9,$F9,$C1,$99,$99,$C1,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$C3,$99,$81,$9F,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$F1,$E7,$C1,$E7,$E7,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$C1,$99,$99,$C1,$F9,$83 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$9F,$9F,$83,$99,$99,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$E7,$FF,$C7,$E7,$E7,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$F9,$FF,$F9,$F9,$F9,$F9,$C3 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$9F,$9F,$93,$87,$93,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$C7,$E7,$E7,$E7,$E7,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$99,$80,$80,$94,$9C,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$83,$99,$99,$99,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$C3,$99,$99,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$83,$99,$99,$83,$9F,$9F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$C1,$99,$99,$C1,$F9,$F9 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$83,$99,$9F,$9F,$9F,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$C1,$9F,$C3,$F9,$83,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$E7,$81,$E7,$E7,$E7,$F1,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$99,$99,$99,$99,$C1,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$99,$99,$99,$C3,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$9C,$94,$80,$C1,$C9,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$99,$C3,$E7,$C3,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$99,$99,$99,$C1,$F3,$87 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$81,$F3,$E7,$CF,$81,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$CF,$CF,$CF,$CF,$CF,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F3,$ED,$CF,$83,$CF,$9D,$03,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$F3,$F3,$F3,$F3,$F3,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$E7,$C3,$81,$E7,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$EF,$CF,$80,$80,$CF,$EF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$E7,$FF,$FF,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$99,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$00,$99,$00,$99,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$C1,$9F,$C3,$F9,$83,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $9D,$99,$F3,$E7,$CF,$99,$B9,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$C3,$C7,$98,$99,$C0,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F9,$F3,$E7,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F3,$E7,$CF,$CF,$CF,$E7,$F3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $CF,$E7,$F3,$F3,$F3,$E7,$CF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$99,$C3,$00,$C3,$99,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$E7,$E7,$81,$E7,$E7,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$E7,$E7,$CF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$81,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$E7,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FC,$F9,$F3,$E7,$CF,$9F,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$91,$89,$99,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$C7,$E7,$E7,$E7,$81,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$F9,$F3,$CF,$9F,$81,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$F9,$E3,$F9,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F9,$F1,$E1,$99,$80,$F9,$F9,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $81,$9F,$83,$F9,$F9,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$9F,$83,$99,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $81,$99,$F3,$E7,$E7,$E7,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$99,$C3,$99,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$99,$C1,$F9,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$E7,$FF,$FF,$E7,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$E7,$FF,$FF,$E7,$E7,$CF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F1,$E7,$CF,$9F,$CF,$E7,$F1,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$81,$FF,$81,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $8F,$E7,$F3,$F9,$F3,$E7,$8F,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$F9,$F3,$E7,$FF,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$00,$00,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$C3,$99,$81,$99,$99,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $83,$99,$99,$83,$99,$99,$83,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$9F,$9F,$9F,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $87,$93,$99,$99,$99,$93,$87,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $81,$9F,$9F,$87,$9F,$9F,$81,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $81,$9F,$9F,$87,$9F,$9F,$9F,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$9F,$91,$99,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$99,$81,$99,$99,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$E7,$E7,$E7,$E7,$E7,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E1,$F3,$F3,$F3,$F3,$93,$C7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$93,$87,$8F,$87,$93,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $9F,$9F,$9F,$9F,$9F,$9F,$81,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $9C,$88,$80,$94,$9C,$9C,$9C,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$89,$81,$81,$91,$99,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$99,$99,$99,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $83,$99,$99,$83,$9F,$9F,$9F,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$99,$99,$99,$C3,$F1,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $83,$99,$99,$83,$87,$93,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$9F,$C3,$F9,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $81,$E7,$E7,$E7,$E7,$E7,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$99,$99,$99,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$99,$99,$99,$C3,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $9C,$9C,$9C,$94,$80,$88,$9C,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$C3,$E7,$C3,$99,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$99,$C3,$E7,$E7,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $81,$F9,$F3,$E7,$CF,$9F,$81,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$00,$00,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3F,$3F,$CF,$CF,$3F,$3F,$CF,$CF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$E7,$E7,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $CC,$CC,$33,$33,$CC,$CC,$33,$33 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $CC,$66,$33,$99,$CC,$66,$33,$99 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$FF,$FF,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3F,$3F,$3F,$3F,$3F,$3F,$3F,$3F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $33,$33,$CC,$CC,$33,$33,$CC,$CC + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FC,$FC,$FC,$FC,$FC,$FC,$FC,$FC + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$33,$33,$CC,$CC + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $33,$66,$CC,$99,$33,$66,$CC,$99 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FC,$FC,$FC,$FC,$FC,$FC,$FC,$FC + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$E0,$E0,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$F0,$F0,$F0,$F0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$E0,$E0,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$07,$07,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$E0,$E0,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$00,$00,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$00,$00,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$07,$07,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3F,$3F,$3F,$3F,$3F,$3F,$3F,$3F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $1F,$1F,$1F,$1F,$1F,$1F,$1F,$1F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F8,$F8,$F8,$F8,$F8,$F8,$F8,$F8 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$FF,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FE,$FC,$F9,$93,$87,$8F,$9F,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$0F,$0F,$0F,$0F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F0,$F0,$F0,$F0,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$07,$07,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $0F,$0F,$0F,$0F,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $0F,$0F,$0F,$0F,$F0,$F0,$F0,$F0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$6E,$6E,$60,$62,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$3C,$66,$7E,$66,$66,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7C,$66,$66,$7C,$66,$66,$7C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$60,$60,$60,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $78,$6C,$66,$66,$66,$6C,$78,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7E,$60,$60,$78,$60,$60,$7E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7E,$60,$60,$78,$60,$60,$60,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$60,$6E,$66,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$66,$7E,$66,$66,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$18,$18,$18,$18,$18,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $1E,$0C,$0C,$0C,$0C,$6C,$38,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$6C,$78,$70,$78,$6C,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $60,$60,$60,$60,$60,$60,$7E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $63,$77,$7F,$6B,$63,$63,$63,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$76,$7E,$7E,$6E,$66,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$66,$66,$66,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7C,$66,$66,$7C,$60,$60,$60,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$66,$66,$66,$3C,$0E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7C,$66,$66,$7C,$78,$6C,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$60,$3C,$06,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7E,$18,$18,$18,$18,$18,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$66,$66,$66,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$66,$66,$66,$3C,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $63,$63,$63,$6B,$7F,$77,$63,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$3C,$18,$3C,$66,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$66,$3C,$18,$18,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7E,$06,$0C,$18,$30,$60,$7E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$30,$30,$30,$30,$30,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $0C,$12,$30,$7C,$30,$62,$FC,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$0C,$0C,$0C,$0C,$0C,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$18,$3C,$7E,$18,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$10,$30,$7F,$7F,$30,$10,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$18,$00,$00,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$66,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $66,$66,$FF,$66,$FF,$66,$66,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$3E,$60,$3C,$06,$7C,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $62,$66,$0C,$18,$30,$66,$46,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$3C,$38,$67,$66,$3F,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $06,$0C,$18,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $0C,$18,$30,$30,$30,$18,$0C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $30,$18,$0C,$0C,$0C,$18,$30,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$66,$3C,$FF,$3C,$66,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$18,$18,$7E,$18,$18,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$18,$18,$30 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$7E,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$18,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$03,$06,$0C,$18,$30,$60,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$6E,$76,$66,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$38,$18,$18,$18,$7E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$06,$0C,$30,$60,$7E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$06,$1C,$06,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $06,$0E,$1E,$66,$7F,$06,$06,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7E,$60,$7C,$06,$06,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$60,$7C,$66,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $7E,$66,$0C,$18,$18,$18,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$66,$3C,$66,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$66,$3E,$06,$66,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$18,$00,$00,$18,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$18,$00,$00,$18,$18,$30 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $0E,$18,$30,$60,$30,$18,$0E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$7E,$00,$7E,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $70,$18,$0C,$06,$0C,$18,$70,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$66,$06,$0C,$18,$00,$18,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$FF,$FF,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $08,$1C,$3E,$7F,$7F,$1C,$3E,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$18,$18,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$FF,$FF,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$FF,$FF,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$FF,$FF,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$FF,$FF,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $30,$30,$30,$30,$30,$30,$30,$30 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$E0,$F0,$38,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$1C,$0F,$07,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$38,$F0,$E0,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C0,$C0,$C0,$C0,$C0,$C0,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C0,$E0,$70,$38,$1C,$0E,$07,$03 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $03,$07,$0E,$1C,$38,$70,$E0,$C0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$C0,$C0,$C0,$C0,$C0,$C0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$03,$03,$03,$03,$03,$03 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$3C,$7E,$7E,$7E,$7E,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$FF,$FF,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $36,$7F,$7F,$7F,$3E,$1C,$08,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $60,$60,$60,$60,$60,$60,$60,$60 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$07,$0F,$1C,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$E7,$7E,$3C,$3C,$7E,$E7,$C3 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$3C,$7E,$66,$66,$7E,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$66,$66,$18,$18,$3C,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $06,$06,$06,$06,$06,$06,$06,$06 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $08,$1C,$3E,$7F,$3E,$1C,$08,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$FF,$FF,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C0,$C0,$30,$30,$C0,$C0,$30,$30 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$18,$18,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$03,$3E,$76,$36,$36,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$7F,$3F,$1F,$0F,$07,$03,$01 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F0,$F0,$F0,$F0,$F0,$F0,$F0,$F0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $CC,$CC,$33,$33,$CC,$CC,$33,$33 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $03,$03,$03,$03,$03,$03,$03,$03 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$CC,$CC,$33,$33 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FE,$FC,$F8,$F0,$E0,$C0,$80 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $03,$03,$03,$03,$03,$03,$03,$03 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$1F,$1F,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$0F,$0F,$0F,$0F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$1F,$1F,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$F8,$F8,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$1F,$1F,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$FF,$FF,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$FF,$FF,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$F8,$F8,$18,$18,$18 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $07,$07,$07,$07,$07,$07,$07,$07 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $03,$03,$03,$03,$03,$03,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$F0,$F0,$F0,$F0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $0F,$0F,$0F,$0F,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $18,$18,$18,$F8,$F8,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F0,$F0,$F0,$F0,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F0,$F0,$F0,$F0,$0F,$0F,$0F,$0F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$91,$91,$9F,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$C3,$99,$81,$99,$99,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $83,$99,$99,$83,$99,$99,$83,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$9F,$9F,$9F,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $87,$93,$99,$99,$99,$93,$87,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $81,$9F,$9F,$87,$9F,$9F,$81,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $81,$9F,$9F,$87,$9F,$9F,$9F,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$9F,$91,$99,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$99,$81,$99,$99,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$E7,$E7,$E7,$E7,$E7,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E1,$F3,$F3,$F3,$F3,$93,$C7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$93,$87,$8F,$87,$93,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $9F,$9F,$9F,$9F,$9F,$9F,$81,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $9C,$88,$80,$94,$9C,$9C,$9C,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$89,$81,$81,$91,$99,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$99,$99,$99,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $83,$99,$99,$83,$9F,$9F,$9F,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$99,$99,$99,$C3,$F1,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $83,$99,$99,$83,$87,$93,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$9F,$C3,$F9,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $81,$E7,$E7,$E7,$E7,$E7,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$99,$99,$99,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$99,$99,$99,$C3,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $9C,$9C,$9C,$94,$80,$88,$9C,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$C3,$E7,$C3,$99,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$99,$C3,$E7,$E7,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $81,$F9,$F3,$E7,$CF,$9F,$81,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$CF,$CF,$CF,$CF,$CF,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F3,$ED,$CF,$83,$CF,$9D,$03,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$F3,$F3,$F3,$F3,$F3,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$E7,$C3,$81,$E7,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$EF,$CF,$80,$80,$CF,$EF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$E7,$FF,$FF,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$99,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $99,$99,$00,$99,$00,$99,$99,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$C1,$9F,$C3,$F9,$83,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $9D,$99,$F3,$E7,$CF,$99,$B9,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$C3,$C7,$98,$99,$C0,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F9,$F3,$E7,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F3,$E7,$CF,$CF,$CF,$E7,$F3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $CF,$E7,$F3,$F3,$F3,$E7,$CF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$99,$C3,$00,$C3,$99,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$E7,$E7,$81,$E7,$E7,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$E7,$E7,$CF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$81,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$E7,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FC,$F9,$F3,$E7,$CF,$9F,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$91,$89,$99,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$C7,$E7,$E7,$E7,$81,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$F9,$F3,$CF,$9F,$81,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$F9,$E3,$F9,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F9,$F1,$E1,$99,$80,$F9,$F9,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $81,$9F,$83,$F9,$F9,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$9F,$83,$99,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $81,$99,$F3,$E7,$E7,$E7,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$99,$C3,$99,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$99,$C1,$F9,$99,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$E7,$FF,$FF,$E7,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$E7,$FF,$FF,$E7,$E7,$CF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F1,$E7,$CF,$9F,$CF,$E7,$F1,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$81,$FF,$81,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $8F,$E7,$F3,$F9,$F3,$E7,$8F,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C3,$99,$F9,$F3,$E7,$FF,$E7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$00,$00,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F7,$E3,$C1,$80,$80,$E3,$C1,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$E7,$E7,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$00,$00,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$00,$00,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$00,$00,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$00,$00,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $CF,$CF,$CF,$CF,$CF,$CF,$CF,$CF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F3,$F3,$F3,$F3,$F3,$F3,$F3,$F3 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$1F,$0F,$C7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E3,$F0,$F8,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$C7,$0F,$1F,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3F,$3F,$3F,$3F,$3F,$3F,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3F,$1F,$8F,$C7,$E3,$F1,$F8,$FC + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FC,$F8,$F1,$E3,$C7,$8F,$1F,$3F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$3F,$3F,$3F,$3F,$3F,$3F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$FC,$FC,$FC,$FC,$FC,$FC + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$C3,$81,$81,$81,$81,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$00,$00,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $C9,$80,$80,$80,$C1,$E3,$F7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $9F,$9F,$9F,$9F,$9F,$9F,$9F,$9F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$F8,$F0,$E3,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3C,$18,$81,$C3,$C3,$81,$18,$3C + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$C3,$81,$99,$99,$81,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$99,$99,$E7,$E7,$C3,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F9,$F9,$F9,$F9,$F9,$F9,$F9,$F9 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F7,$E3,$C1,$80,$C1,$E3,$F7,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$00,$00,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3F,$3F,$CF,$CF,$3F,$3F,$CF,$CF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$E7,$E7,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FC,$C1,$89,$C9,$C9,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$80,$C0,$E0,$F0,$F8,$FC,$FE + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$FF,$FF,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3F,$3F,$3F,$3F,$3F,$3F,$3F,$3F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $33,$33,$CC,$CC,$33,$33,$CC,$CC + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FC,$FC,$FC,$FC,$FC,$FC,$FC,$FC + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$33,$33,$CC,$CC + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$01,$03,$07,$0F,$1F,$3F,$7F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FC,$FC,$FC,$FC,$FC,$FC,$FC,$FC + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$E0,$E0,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$F0,$F0,$F0,$F0 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$E0,$E0,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$07,$07,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$E0,$E0,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$00,$00,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$00,$00,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$07,$07,$E7,$E7,$E7 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $3F,$3F,$3F,$3F,$3F,$3F,$3F,$3F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $1F,$1F,$1F,$1F,$1F,$1F,$1F,$1F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F8,$F8,$F8,$F8,$F8,$F8,$F8,$F8 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$FF,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$FF,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$FF,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FC,$FC,$FC,$FC,$FC,$FC,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $FF,$FF,$FF,$FF,$0F,$0F,$0F,$0F + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $F0,$F0,$F0,$F0,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $E7,$E7,$E7,$07,$07,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 + .DB $0F,$0F,$0F,$0F,$FF,$FF,$FF,$FF + .DB $00,$00,$00,$00,$00,$00,$00,$00 diff --git a/Source/Apps/Test/vdctest/vdconly.asm b/Source/Apps/Test/vdctest/vdconly.asm new file mode 100644 index 00000000..6f7b54ca --- /dev/null +++ b/Source/Apps/Test/vdctest/vdconly.asm @@ -0,0 +1,1055 @@ +;__CVDUTEST________________________________________________________________________________________ +; +; CVDUTEST COLOR VDU TEST +; +; WRITTEN BY: DAN WERNER -- 11/4/2011 +;__________________________________________________________________________________________________ +; + +; DATA CONSTANTS +;__________________________________________________________________________________________________ +;IDE REGISTER IO PORT ; FUNCTION +M8563Status .EQU $E4 +M8563Register .EQU $E4 +M8563Data .EQU $E5 + +I8242Status .EQU $E3 +I8242Command .EQU $E3 +I8242Data .EQU $E2 + + + .ORG $0100 +;__________________________________________________________________________________________________ +; MAIN PROGRAM BEGINS HERE +;__________________________________________________________________________________________________ +INITVDU: + CALL VDU_INIT ; INIT VDU +; CALL KB_INITIALIZE ; INIT KB + + CALL DSPMATRIX ; DISPLAY INIT MATRIX SCREEN +; CALL WAIT_KBHIT ; WAIT FOR A KEYSTROKE + +LOOP1: +; CALL GET_KEY + LD A,27 ; SIMULATE KEYSTROKE TO END PROGRAM + + LD C,14 + CP 13 + JP Z,LOOP2 + CP 27 + JP Z,LOOP3 + CP '6' + JP Z,LOOP4 + CALL VDU_PutChar ; DUMP CHAR TO DISPLAY + JP LOOP1 +LOOP2: + LD A,0 ; YES, WRAP TO NEXT LINE + LD (TERM_X),A ; STORE X + LD A,(TERM_Y) ; A= Y COORD + INC A ; INC Y COORD + LD (TERM_Y),A ; STORE Y + CALL GOTO_XY ; YES, HANDLE SCROLLING + JP LOOP1 +LOOP3: + LD C,00H ; CP/M SYSTEM RESET CALL + CALL 0005H ; RETURN TO PROMPT + RET +LOOP4: + CALL REVERSE_SCROLL + JP LOOP1 + + +;__DO_SCROLL_______________________________________________________________________________________ +; +; SCROLL THE SCREEN UP ONE LINE +;__________________________________________________________________________________________________ +DO_SCROLL: + PUSH AF ; STORE AF +DO_SCROLLE1: + PUSH HL ; STORE HL + PUSH BC ; STORE BC + + LD B, 24 ; GET REGISTER 24 + CALL VDU_GREG ; + OR 80H ; TURN ON COPY BIT + LD D,A ; PARK IT + + LD HL, (VDU_DISPLAY_START) ; GET UP START OF DISPLAY + LD E,23 ; +DO_SCROLL1: + LD B, 18 ; SET UPDATE(DEST) POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE(DEST) POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD BC,0050H ; + ADD HL,BC ; + LD B, 32 ; SET SOURCE POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 33 ; SET SOURCE POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + LD B, 24 ; SET COPY + LD A,D ; + CALL VDU_WREG ; WRITE IT + + LD B, 30 ; SET AMOUNT TO COPY + LD A,050H ; + CALL VDU_WREG ; WRITE IT + DEC A + LD A,E ; + CP 00H ; + JP NZ,DO_SCROLL1 ; LOOP TILL DONE + + LD HL, (VDU_DISPLAY_START) ; GET UP START OF DISPLAY + LD BC,0820H ; + ADD HL,BC ; + LD E,23 +DO_SCROLL2: + LD B, 18 ; SET UPDATE(DEST) POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE(DEST) POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD BC,0050H ; + ADD HL,BC ; + LD B, 32 ; SET SOURCE POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 33 ; SET SOURCE POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + LD B, 24 ; SET COPY + LD A,D ; + CALL VDU_WREG ; WRITE IT + + LD B, 30 ; SET AMOUNT TO COPY + LD A,050H ; + CALL VDU_WREG ; WRITE IT + DEC E + LD A,E ; + CP 00H ; + JP NZ,DO_SCROLL2 ; LOOP TILL DONE + + + LD A,23 ; SET CURSOR TO BEGINNING OF LAST LINE + LD (TERM_Y),A ; + LD A,(TERM_X) ; + PUSH AF ; STORE X COORD + LD A,0 ; + LD (TERM_X),A ; + CALL GOTO_XY ; SET CURSOR POSITION TO BEGINNING OF LINE + POP AF ; RESTORE X COORD + POP BC ; RESTORE BC + CALL PERF_ERASE_EOL ; ERASE SCROLLED LINE + LD (TERM_X),A ; + CALL GOTO_XY ; SET CURSOR POSITION + POP HL ; RESTORE HL + POP AF ; RESTORE AF + RET ; + +;__REVERSE_SCROLL__________________________________________________________________________________ +; +; SCROLL THE SCREEN DOWN ONE LINE +;__________________________________________________________________________________________________ +REVERSE_SCROLL: + PUSH AF ; STORE AF + PUSH HL ; STORE HL + PUSH BC ; STORE BC + + LD B, 24 ; GET REGISTER 24 + CALL VDU_GREG ; + OR 80H ; TURN ON COPY BIT + LD E,A ; PARK IT + + LD HL, (VDU_DISPLAY_START) ; GET UP START OF DISPLAY + LD BC,0730H ; + ADD HL,BC + LD D,23 ; +REVERSE_SCROLL1: + LD B, 18 ; SET UPDATE(DEST) POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE(DEST) POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD BC,0FFB0H ; + ADD HL,BC ; + LD B, 32 ; SET SOURCE POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 33 ; SET SOURCE POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + LD B, 24 ; SET COPY + LD A,E ; + CALL VDU_WREG ; WRITE IT + + LD B, 30 ; SET AMOUNT TO COPY + LD A,050H ; + CALL VDU_WREG ; WRITE IT + + DEC D + LD A,D ; + CP 00H ; + JP NZ,REVERSE_SCROLL1 ; LOOP TILL DONE + + + LD HL, (VDU_DISPLAY_START) ; GET UP START OF DISPLAY + LD BC,0F50H ; + ADD HL,BC + LD D,23 ; +REVERSE_SCROLL2: + LD B, 18 ; SET UPDATE(DEST) POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE(DEST) POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD BC,0FFB0H ; + ADD HL,BC ; + LD B, 32 ; SET SOURCE POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 33 ; SET SOURCE POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + LD B, 24 ; SET COPY + LD A,E ; + CALL VDU_WREG ; WRITE IT + + LD B, 30 ; SET AMOUNT TO COPY + LD A,050H ; + CALL VDU_WREG ; WRITE IT + + DEC D + LD A,D ; + CP 00H ; + JP NZ,REVERSE_SCROLL2 ; LOOP TILL DONE + LD A,0 ; SET CURSOR TO BEGINNING OF FIRST LINE + LD (TERM_Y),A ; + LD A,(TERM_X) ; + PUSH AF ; STORE X COORD + LD A,0 ; + LD (TERM_X),A ; + CALL GOTO_XY ; SET CURSOR POSITION TO BEGINNING OF LINE + POP AF ; RESTORE AF + POP BC ; RESTORE BC + CALL PERF_ERASE_EOL ; ERASE SCROLLED LINE + LD (TERM_X),A ; + CALL GOTO_XY ; SET CURSOR POSITION + POP HL ; RESTORE HL + POP AF ; RESTORE AF + RET ; + +;__VDU_INIT_________________________________________________________________________________________ +; +; INITIALIZE VDU +;__________________________________________________________________________________________________ +VDU_INIT: + PUSH AF ; STORE AF + PUSH DE ; STORE DE + PUSH HL ; STORE HL + PUSH BC ; STORE BC + + CALL VDU_CRTInit ; INIT 8563 VDU CHIP + CALL VDU_LOADFONT ; + CALL PERF_CURSOR_HOME ; CURSOR HOME + LD C,14 ; + CALL PERF_ERASE_EOS ; CLEAR SCREEN + CALL VDU_CursorOn ; TURN ON CURSOR + + POP BC ; + POP HL ; + POP DE ; + POP AF ; + + RET + +;__PERF_CURSOR_HOME________________________________________________________________________________ +; +; PERFORM CURSOR HOME +;__________________________________________________________________________________________________ +PERF_CURSOR_HOME: + LD A,0 ; LOAD 0 INTO A + LD (TERM_X),A ; SET X COORD + LD (TERM_Y),A ; SET Y COORD + JP GOTO_XY ; MOVE CURSOR TO POSITION + +;__PERF_ERASE_EOS__________________________________________________________________________________ +; +; PERFORM ERASE FROM CURSOR POS TO END OF SCREEN +; C= DEFAULT COLOR +;__________________________________________________________________________________________________ +PERF_ERASE_EOS: + PUSH HL + PUSH AF + PUSH BC + + LD HL, (VDU_DisplayPos) ; GET CURRENT DISPLAY ADDRESS + LD B, 18 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + CALL GOTO_XY ; MOVE CURSOR + LD DE,0820H ; SET SCREEN SIZE INTO HL +PERF_ERASE_EOS_LOOP: + LD A, ' ' ; MOVE SPACE CHARACTER INTO A + LD B,31 ; + CALL VDU_WREG ; WRITE IT TO SCREEN, VDU WILL AUTO INC TO NEXT ADDRESS + DEC DE ; DEC COUNTER + LD A,D ; IS COUNTER 0 YET? + OR E ; + JP NZ,PERF_ERASE_EOS_LOOP ; NO, LOOP + LD DE,0820H ; SET SCREEN SIZE INTO HL +PERF_ERASE_EOS_CLOOP: + LD A, C ; MOVE COLOR INTO A + LD B,31 ; + CALL VDU_WREG ; WRITE IT TO SCREEN, VDU WILL AUTO INC TO NEXT ADDRESS + DEC DE ; DEC COUNTER + LD A,D ; IS COUNTER 0 YET? + OR E ; + JP NZ,PERF_ERASE_EOS_CLOOP ; NO, LOOP + + CALL GOTO_XY ; YES, MOVE CURSOR BACK TO ORIGINAL POSITION + POP BC + POP AF + POP HL + RET + +;__PERF_ERASE_EOL__________________________________________________________________________________ +; +; PERFORM ERASE FROM CURSOR POS TO END OF LINE +; C=DEFAULT COLOR +;__________________________________________________________________________________________________ +PERF_ERASE_EOL: + PUSH HL + PUSH AF + PUSH BC + + LD A,(TERM_X) ; GET CURRENT CURSOR X COORD + LD D,A ; STORE IT IN C + LD A,80 ; MOVE CURRENT LINE WIDTH INTO A + SUB D ; GET REMAINING POSITIONS ON CURRENT LINE + LD B,A ; MOVE IT INTO B +PERF_ERASE_EOL_LOOP: + LD A, ' ' ; MOVE SPACE CHARACTER INTO A + CALL VDU_PutCharRAW ; + DJNZ PERF_ERASE_EOL_LOOP ; LOOP UNTIL DONE + CALL GOTO_XY ; MOVE CURSOR BACK TO ORIGINAL POSITION + POP BC + POP AF + POP HL + RET + +;__DSPMATRIX_______________________________________________________________________________________ +; +; DISPLAY INTRO SCREEN +;__________________________________________________________________________________________________ +DSPMATRIX: + CALL PERF_CURSOR_HOME ; RESET CURSOR TO HOME POSITION + LD HL,TESTMATRIX ; SET HL TO SCREEN IMAGE + LD DE, 1919 ; SET IMAGE SIZE +; LD C,00000011B ; SET COLOR + LD C,00001111B ; SET COLOR +DSPMATRIX_LOOP: + LD A,(HL) ; GET NEXT CHAR FROM IMAGE + call VDU_PutChar ; DUMP CHAR TO DISPLAY + INC HL ; INC POINTER + DEC DE ; DEC COUNTER + LD A,D ; IS COUNTER ZERO? + OR E ; + JP NZ,DSPMATRIX_LOOP ; NO, LOOP + CALL PERF_CURSOR_HOME ; YES, RESET CURSOR TO HOME POSITION + RET + +TESTMATRIX: + .TEXT "0 1 2 3 4 5 6 7 " + .TEXT "01234567890123456789012345678901234567890123456789012345678901234567890123456789" + .TEXT "2 " + .TEXT "3 " + .TEXT "4 ===================================================== " + .TEXT "5 " + .TEXT "6 **** * * **** * * **** * * " + .TEXT "7 * * * * * * * * * * * * " + .TEXT "8 * * * * * * * * * ** " + .TEXT "9 * * * * * * * * * ** " + .TEXT "10 * * * * * * * * * * * * " + .TEXT "11 **** * **** **** **** * * " + .TEXT "12 " + .TEXT "13 ===================================================== " + .TEXT "14 " + .TEXT "15 VDU TEST V0.1 VT-52 EMULATION " + .TEXT "16 " + .TEXT "17 ** PRESS ANY KEY TO ENTER TERMINAL MODE ** " + .TEXT "18 " + .TEXT "19 " + .TEXT "21 " + .TEXT "22 " + .TEXT "23 " + .TEXT "24 " + + +;__VDU_WREG________________________________________________________________________________________ +; +; WRITE VALUE IN A TO REGISTER IN B +; B: REGISTER TO UPDATE +; A: VALUE TO WRITE +;__________________________________________________________________________________________________ +VDU_WREG: + PUSH AF ; STORE AF +VDU_WREG_1: + IN A,(M8563Status) ; read address/status register + BIT 7,A ; if bit 7 = 1 than an update strobe has been occured + JR Z,VDU_WREG_1 ; wait for ready + LD A,B ; + OUT (M8563Register),A ; select register +VDU_WREG_2: + IN A,(M8563Status) ; read address/status register + BIT 7,A ; if bit 7 = 1 than an update strobe has been occured + JR Z,VDU_WREG_2 ; wait for ready + POP AF ; + OUT (M8563Data),A ; PUT DATA + RET + + +;__VDU_GREG________________________________________________________________________________________ +; +; GET VALUE FROM REGISTER IN B PLACE IN A +; B: REGISTER TO GET +; A: VALUE +;__________________________________________________________________________________________________ +VDU_GREG: + IN A,(M8563Status) ; read address/status register + BIT 7,A ; if bit 7 = 1 than an update strobe has been occured + JR Z,VDU_GREG ; wait for ready + LD A,B ; + OUT (M8563Register) , A ; select register +VDU_GREG_1: + IN A,(M8563Status) ; read address/status register + BIT 7,A ; if bit 7 = 1 than an update strobe has been occured + JR Z,VDU_GREG_1 ; wait for ready + IN A,(M8563Data) ; GET DATA + RET + + + +VDU_Init8563: + .DB 126,80,102,73,32,224,25,29,252,231,160,231,0,0,7,128 + .DB 18,23,15,208,8,32,120,232,32,71,240,0,47,231,79,7,15,208,125,100,245 + +;__VDU_CRTInit_____________________________________________________________________________________ +; +; INIT VDU CHIP +;__________________________________________________________________________________________________ +VDU_CRTInit: + PUSH AF ; STORE AF + PUSH BC ; STORE BC + PUSH HL ; STORE HL + + LD B,$00 ; B = 0 + LD HL,VDU_Init8563 ; HL = pointer to the default values + XOR A ; A = 0 +VDU_CRTInitLoop: + LD A,(HL) ; GET VALUE + CALL VDU_WREG ; WRITE IT + INC HL + INC B ; + LD A,B ; + CP 37 ; + JR NZ,VDU_CRTInitLoop ; LOOP UNTIL DONE + POP HL ; RESTORE HL + POP BC ; RESTORE BC + POP AF ; RESTORE AF + RET + + +;__VDU_CursorOn____________________________________________________________________________________ +; +; TURN ON CURSOR +;__________________________________________________________________________________________________ +VDU_CursorOn: + PUSH AF ; STORE AF + LD A, $60 ; SET CURSOR VALUE + JP VDU_CursorSet ; + +;__VDU_CursorOff___________________________________________________________________________________ +; +; TURN OFF CURSOR +;__________________________________________________________________________________________________ +VDU_CursorOff: + PUSH AF ; STORE AF + LD A, $20 ; SET CURSOR VALUE +VDU_CursorSet: + PUSH BC ; STORE BC + LD B,10 + CALL VDU_WREG ; WRITE IT + POP BC ; RESTORE BC + POP AF ; RESTORE AF + RET + +;__GOTO_XY_________________________________________________________________________________________ +; +; MOVE CURSOR TO POSITON IN TERM_X AND TERM_Y +;__________________________________________________________________________________________________ +GOTO_XY: + PUSH AF ; STORE AF + + LD A,(TERM_Y) ; PLACE Y COORD IN A + CP 24 ; IS 24? + JP Z,DO_SCROLLE1 ; YES, MUST SCROLL + + PUSH BC ; STORE BC + PUSH DE ; STORE DE + LD A,(TERM_X) ; + LD H,A ; + LD A,(TERM_Y) ; + LD L,A ; + PUSH HL ; STORE HL + LD B, A ; B = Y COORD + LD DE, 80 ; MOVE LINE LENGTH INTO DE + LD HL, 0 ; MOVE 0 INTO HL + LD A, B ; A=B + CP 0 ; Y=0? + JP Z, VDU_YLoopEnd ; THEN DO NOT MULTIPLY BY 80 +VDU_YLoop: ; HL = 80 * Y + ADD HL, DE ; HL=HL+DE + DJNZ VDU_YLoop ; LOOP +VDU_YLoopEnd: ; + POP DE ; DE = org HL + LD E, D ; E = X + LD D, 0 ; D = 0 + ADD HL, DE ; HL = HL + X + LD (VDU_DisplayPos), HL ; + PUSH HL ; + POP DE ; + LD HL,(VDU_DISPLAY_START) ; + ADD HL,DE ; + LD B, 18 ; SET UPDATE ADDRESS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE ADDRESS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + LD B, 14 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 15 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + POP DE ; RESTORE DE + POP BC ; RESTORE BC + POP AF ; RESTORE AF + RET + +;__VDU_PutChar______________________________________________________________________________________ +; +; PLACE CHARACTER ON SCREEN +; A: CHARACTER TO OUTPUT +; C: COLOR +;__________________________________________________________________________________________________ +VDU_PutChar: + PUSH DE ; STORE DE + PUSH AF ; STORE AF + PUSH HL ; STORE HL + LD D,A ; STORE CHAR IN D + LD A,(TERM_X) ; PLACE X COORD IN A + INC A ; INC X COORD + LD (TERM_X),A ; STORE IN A + CP 80 ; IS 80? + JP NZ,VDU_PutChar1 ; NO, PLACE CHAR ON DISPLAY + LD A,0 ; YES, WRAP TO NEXT LINE + LD (TERM_X),A ; STORE X + LD A,(TERM_Y) ; A= Y COORD + INC A ; INC Y COORD + LD (TERM_Y),A ; STORE Y + CP 24 ; IS PAST END OF SCREEN? + CALL Z,GOTO_XY ; YES, HANDLE SCROLLING +VDU_PutChar1: ; + ; + LD HL, (VDU_DisplayPos) ; GET CURRENT DISPLAY ADDRESS + LD B, 18 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD A,D ; RESTORE CHAR + LD B,31 ; + CALL VDU_WREG ; WRITE IT + PUSH HL ; + LD DE,$0820 ; + ADD HL,DE ; + LD B, 18 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD A,C ; GET COLOR + LD B,31 ; + CALL VDU_WREG ; WRITE IT + POP HL ; RESTORE ADDRESS + INC HL ; INCREMENT IT + LD (VDU_DisplayPos), HL ; STORE CURRENT DISPLAY ADDRESS + PUSH HL ; MOVE HL TO DE + POP DE ; + LD HL,(VDU_DISPLAY_START) ; + ADD HL,DE ; + LD B, 14 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 15 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + POP HL ; RESTORE HL + POP AF ; RESTORE AF + POP DE ; RESTORE DE + RET + +VDU_PutCharRAW: + PUSH BC ; + LD D,A ; + LD HL, (VDU_DisplayPos) ; GET CURRENT DISPLAY ADDRESS + LD B, 18 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD A,D ; RESTORE CHAR + LD B,31 ; + CALL VDU_WREG ; WRITE IT + PUSH HL ; + LD DE,$0820 ; + ADD HL,DE ; + LD B, 18 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD A,C ; GET COLOR + LD B,31 ; + CALL VDU_WREG ; WRITE IT + POP HL ; RESTORE ADDRESS + INC HL ; INCREMENT IT + LD (VDU_DisplayPos), HL ; STORE CURRENT DISPLAY ADDRESS + POP BC + RET + +;__VDU_LOADFONT____________________________________________________________________________________ +; +; LOAD SCREEN FONT +;__________________________________________________________________________________________________ +VDU_LOADFONT: + PUSH AF + PUSH BC + + LD HL,$2000 ; SET FONT LOCATION + ; + LD B, 18 ; SET UPDATE ADDRESS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE ADDRESS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + LD B,$00 ; FONT SIZE + LD C,$20 ; FONT SIZE + LD HL,FONT ; FONT DATA +VDU_LOADFONT_LOOP: + IN A,(M8563Status) ; read address/status register + BIT 7,A ; if bit 7 = 1 than an update strobe has been occured + JR Z,VDU_LOADFONT_LOOP ; wait for ready + LD A,31 ; + OUT (M8563Register) , A ; select register +VDU_LOADFONT_LOOP_1: + IN A,(M8563Status) ; read address/status register + BIT 7,A ; if bit 7 = 1 than an update strobe has been occured + JR Z,VDU_LOADFONT_LOOP_1 ; wait for ready + LD A,(HL) ; + OUT (M8563Data) , A ; PUT DATA + INC HL + DJNZ VDU_LOADFONT_LOOP ; + DEC C ; + JP NZ,VDU_LOADFONT_LOOP ; + POP BC + POP AF + RET + +;__KB_INITIALIZE___________________________________________________________________________________ +; +; INIT KEYBOARD CONTROLLER +;__________________________________________________________________________________________________ +KB_INITIALIZE: + LD C,0a7H ; + CALL I8242CommandPut ; + LD C,0aeH ; + CALL I8242CommandPut ; + LD C,0aaH ; + CALL I8242CommandPut ; + LD A,0 ; EMPTY KB QUEUE + LD (KB_QUEUE_PTR),A ; + RET + +;__I8242CommandPut_________________________________________________________________________________ +; +; WRITE VALUE IN A TO 8242 +; C: VALUE TO WRITE +;__________________________________________________________________________________________________ +I8242CommandPut: + IN A,(I8242Status) ; read status register + BIT 1,A ; if bit 1 = 1 + JR NZ,I8242CommandPut ; wait for ready + LD A,C ; + OUT (I8242Command),A ; select register + RET + +;__WAIT_KBHIT______________________________________________________________________________________ +; +; WAIT FOR A KEY PRESS +;__________________________________________________________________________________________________ +WAIT_KBHIT: + CALL KB_PROCESS ; call keyboard routine + LD A,(KB_QUEUE_PTR) ; IS QUEUE EMPTY? + OR A ; set flags + JP Z,WAIT_KBHIT ; if no keys waiting, try again + RET + +;__IS_KBHIT________________________________________________________________________________________ +; +; WAS A KEY PRESSED? +;__________________________________________________________________________________________________ +IS_KBHIT: + CALL KB_PROCESS ; call keyboard routine + LD A,(KB_QUEUE_PTR) ; ask if keyboard has key waiting + RET + +;__GET_KEY_________________________________________________________________________________________ +; +; GET KEY PRESS VALUE +;__________________________________________________________________________________________________ +GET_KEY: + CALL WAIT_KBHIT ; WAIT FOR A KEY + LD A,(KB_QUEUE_PTR) ; GET QUEUE POINTER + OR A ; + RET Z ; ABORT IF QUEUE EMPTY + PUSH BC ; STORE BC + LD B,A ; STORE QUEUE COUNT FOR LATER + PUSH HL ; STORE HL + LD A,(KB_QUEUE) ; GET TOP BYTE FROM QUEUE + PUSH AF ; STORE IT + LD HL,KB_QUEUE ; GET POINTER TO QUEUE +GET_KEY_LOOP: ; + INC HL ; POINT TO NEXT VALUE IN QUEUE + LD A,(HL) ; GET VALUE + DEC HL ; + LD (HL),A ; MOVE IT UP ONE + INC HL ; + DJNZ GET_KEY_LOOP ; LOOP UNTIL DONE + LD A,(KB_QUEUE_PTR) ; DECREASE QUEUE POINTER BY ONE + DEC A ; + LD (KB_QUEUE_PTR),A ; + POP AF ; RESTORE VALUE + POP HL ; RESTORE HL + POP BC ; RESTORE BC + RET + + +;__KB_PROCESS______________________________________________________________________________________ +; +; a=0 if want to know if a byte is available, and a=1 to ask for the byte +;__________________________________________________________________________________________________ +KB_PROCESS: + IN A,(I8242Status) ; read status register + BIT 0,A ; if bit 0 = 0 + RET Z ; EXIT + IN A,(I8242Data) ; GET BYTE + call KB_decodechar ; returns char or 0 for things like keyup, some return directly to cp/m + ret ; return to cp/m + +;__KB_waitbyte______________________________________________________________________________________ +; +; WAIT FOR byte TO BE available +;__________________________________________________________________________________________________ +KB_waitbyte: + IN A,(I8242Status) ; read status register + BIT 0,A ; if bit 0 = 0 + jp Z,KB_waitbyte ; LOOP + IN A,(I8242Data) ; GET BYTE + RET + +;__KB_decodechar____________________________________________________________________________________ +; +; decode character pass a and prints out the char +; on the LCD screen +;__________________________________________________________________________________________________ +KB_decodechar: + cp 0 ; is it zero + ret z ; return if a zero - no need to do anything + + ld c,a ; + cp 0AAh ; shift (down, because up would be trapped by 0F above) + jp z,shiftup ; + cp 0B6h ; other shift key + jp z,shiftup ; + cp 9Dh ; control key + jp z,controlup ; + AND 80H ; if bit 7 = 1 + RET nz ; ignore char up + ld a,C ; + cp 0E0h ; TWO BYTE + JP Z,twobyte ; + cp 03Ah ; caps lock so toggle + jp z,capstog ; + cp 2Ah ; shift (down, because up would be trapped by 0F above) + jp z,shiftdown ; + cp 36h ; other shift key + jp z,shiftdown ; + cp 01Dh ; control key + jp z,controldown ; + ld c,a ; + ld b,0 ; add bc to hl + ld hl,normalkeys ; offset to add + add hl,bc ; + ld a,(ctrl) ; + cp 0 ; is control being held down? + jR z,dc1 ; no so go back to test caps lock on + ld a,(hl) ; get the letter, should be smalls + sub 96 ; a=97 so subtract 96 a=1=^A + JP KB_ENQUEUE ; STORE ON KB QUEUE +dc1: ld a,(capslock) ; + cp 0 ; is it 0, if so then don't add the caps offset + jr z,dc2 ; + ld c,080h ; add another 50h to smalls to get caps + add hl,bc ; +dc2: ld a,(hl) ; + JP KB_ENQUEUE ; STORE ON KB QUEUE +twobyte:; already got EO so get the next character + call KB_waitbyte + cp 053h ; delete + jp z,deletekey ; + cp 01Ch ; return on number pad + jp z,returnkey ; + cp 050h ; + jp z,downarrow ; + cp 04Dh ; + jp z,rightarrow ; + cp 04Bh ; + jp z,leftarrow ; + cp 048h ; + jp z,uparrow ; + cp 052h ; + jp z,insert ; + cp 049h ; + jp z,pageup ; + cp 051h ; + jp z,pagedown ; + cp 047h ; + jp z,home ; + cp 04Fh ; + jp z,end ; + ld a,0 ; returns nothing + ret +home: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'?' ; ? + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'w' ; w + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +end: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'?' ; ? + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'q' ; q + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +downarrow: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'B' ; B + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +rightarrow: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'C' ; C + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +leftarrow: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'D' ; D + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +uparrow: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'A' ; A + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +insert: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'?' ; ? + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'p' ; p + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +pageup: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'?' ; ? + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'y' ; y + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +pagedown: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'?' ; ? + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'s' ; s + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +controldown: ; same code as shiftdown but diff location + ld a,0ffh ; + ld (ctrl),a ; control down + ld a,0 ; + ret ; +controlup: ; control key up see shift for explanation + ld a,0 ; + ld (ctrl),a ; + ld a,0 ; + ret ; +returnkey: ; + ld a,13 ; + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +deletekey: ; + ld a,07fh ; delete key value that cp/m uses + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +capstog: ; + ld a,(capslock) ; + xor 11111111B ; swap all the bits + ld (capslock),a ; + ld a,0 ; returns nothing + ret ; +shiftdown: ; shift is special - hold it down and it autorepeats + ; so once it is down, turn caps on and ignore all further shifts + ; only an F0+shift turns caps lock off again + ld a,0ffh ; + ld (capslock),a ; + ld a,0 ; returns nothing + ret ; +shiftup: ; shiftup turns off caps lock definitely + ld a,0 ; + ld (capslock),a ; + ld a,0 ; returns nothing + ret ; + +;__KB_ENQUEUE______________________________________________________________________________________ +; +; STORE A BYTE IN THE KEYBOARD QUEUE +; A: BYTE TO ENQUEUE +;__________________________________________________________________________________________________ +KB_ENQUEUE: + PUSH DE ; STORE DE + PUSH HL ; STORE HL + PUSH AF ; STORE VALUE + LD A,(KB_QUEUE_PTR); PUT QUEUE POINTER IN A + CP 15 ; IS QUEUE FULL + JP P,KB_ENQUEUE_AB ; YES, ABORT + LD HL,KB_QUEUE ; GET QUEUE POINTER + PUSH HL ; MOVE HL TO BC + POP BC ; + LD H,0 ; ZERO OUT H + LD L,A ; PLACE QUEUE POINTER IN L + ADD HL,BC ; POINT HL AT THE NEXT LOACTION TO ADD VALUE + POP AF ; RESTORE VALUE + LD (HL),A ; ENQUEUE VALUE + LD A,(KB_QUEUE_PTR); GET QUEUE POINTER + INC A ; INC IT + LD (KB_QUEUE_PTR),A; STORE QUEUE POINTER +KB_ENQUEUE_AB: + POP HL ; RESTORE HL + POP DE ; RESTORE DE + RET + +normalkeys: ; The TI character codes, offset from label by keyboard scan code + .db 000,027,"1","2","3","4","5","6","7","8","9","0","-","=",008,009 ;00-0F + .DB "q","w","e","r","t","y","u","i","o","p","[","]",013,000,"a","s" ;10-1F + .DB "d","f","g","h","j","k","l",";",27H,60H,000,092,"z","x","c","v" ;20-2F + .DB "b","n","m",",",".","/",000,000,000," ",000,000,000,000,000,000 ;30-3F + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;40-4F + .db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;50-5F + .db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;60-6F + .db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;70-7F + .db 000,027,"!","@","#","$","%","^","&","*","(",")","_","+",008,009 + .DB "Q","W","E","R","T","Y","U","I","O","P","{","}",013,000,"A","S" + .DB "D","F","G","H","J","K","L",":",034,"~",000,"|","Z","X","C","V" + .DB "B","N","M","<",">","?",000,000,000," ",000,000,000,000,000,000 + .db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 + .db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 + .db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 + + .include "font.asm" + +;__________________________________________________________________________________________________ +; +; RAM STORAGE AREAS +;__________________________________________________________________________________________________ + +ALT_KEYPAD .DB 0 ; ALT KEYPAD ENABLED? +GR_MODE .DB 0 ; GRAPHICS MODE ENABLED? +TERM_X: .DB 0 ; CURSOR X +TERM_Y: .DB 0 ; CURSOR Y +TERMSTATE: .DB 0 ; TERMINAL STATE + ; 0 = NORMAL + ; 1 = ESC RCVD +VDU_DisplayPos: .DW 0 ; CURRENT DISPLAY POSITION +VDU_DISPLAY_START: + .DW 0 ; CURRENT DISPLAY POSITION +capslock .DB 0 ; location for caps lock, either 00000000 or 11111111 +ctrl .DB 0 ; location for ctrl on or off 00000000 or 11111111 +numlock .DB 0 ; location for num lock +skipcount .DB 0 ; only check some calls, speeds up a lot of cp/m + +KB_QUEUE .DB 0,0,0,0,0,0,0,0 ; 16 BYTE KB QUEUE + .DB 0,0,0,0,0,0,0,0 +KB_QUEUE_PTR .DB 0 ; POINTER TO QUEUE +PARKSTACK .DW 0000 ; SAVE STACK POINTER + + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; +TERMSTACK: .DB 0 ; + + + .end diff --git a/Source/Apps/Test/vdctest/vdctest.asm b/Source/Apps/Test/vdctest/vdctest.asm new file mode 100644 index 00000000..60eb8564 --- /dev/null +++ b/Source/Apps/Test/vdctest/vdctest.asm @@ -0,0 +1,1089 @@ +;__CVDUTEST________________________________________________________________________________________ +; +; CVDUTEST COLOR VDU TEST +; +; WRITTEN BY: DAN WERNER -- 11/4/2011 +;__________________________________________________________________________________________________ +; + +; DATA CONSTANTS +;__________________________________________________________________________________________________ +;IDE REGISTER IO PORT ; FUNCTION +M8563Status .EQU $E4 +M8563Register .EQU $E4 +M8563Data .EQU $E5 + +I8242Status .EQU $E3 +I8242Command .EQU $E3 +I8242Data .EQU $E2 + + + .ORG $0100 +;__________________________________________________________________________________________________ +; MAIN PROGRAM BEGINS HERE +;__________________________________________________________________________________________________ +INITVDU: + CALL VDU_INIT ; INIT VDU + CALL KB_INITIALIZE ; INIT KB + + CALL DSPMATRIX ; DISPLAY INIT MATRIX SCREEN + CALL WAIT_KBHIT ; WAIT FOR A KEYSTROKE + +LOOP1: + CALL GET_KEY + LD C,14 + CP 13 + JP Z,LOOP2 + CP 27 + JP Z,LOOP3 + CP '6' + JP Z,LOOP4 + CALL VDU_PutChar ; DUMP CHAR TO DISPLAY + JP LOOP1 +LOOP2: + LD A,0 ; YES, WRAP TO NEXT LINE + LD (TERM_X),A ; STORE X + LD A,(TERM_Y) ; A= Y COORD + INC A ; INC Y COORD + LD (TERM_Y),A ; STORE Y + CALL GOTO_XY ; YES, HANDLE SCROLLING + JP LOOP1 +LOOP3: + LD C,00H ; CP/M SYSTEM RESET CALL + CALL 0005H ; RETURN TO PROMPT + RET +LOOP4: + CALL REVERSE_SCROLL + JP LOOP1 + + +;__DO_SCROLL_______________________________________________________________________________________ +; +; SCROLL THE SCREEN UP ONE LINE +;__________________________________________________________________________________________________ +DO_SCROLL: + PUSH AF ; STORE AF +DO_SCROLLE1: + PUSH HL ; STORE HL + PUSH BC ; STORE BC + + LD B, 24 ; GET REGISTER 24 + CALL VDU_GREG ; + OR 80H ; TURN ON COPY BIT + LD D,A ; PARK IT + + LD HL, (VDU_DISPLAY_START) ; GET UP START OF DISPLAY + LD E,23 ; +DO_SCROLL1: + LD B, 18 ; SET UPDATE(DEST) POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE(DEST) POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD BC,0050H ; + ADD HL,BC ; + LD B, 32 ; SET SOURCE POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 33 ; SET SOURCE POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + LD B, 24 ; SET COPY + LD A,D ; + CALL VDU_WREG ; WRITE IT + + LD B, 30 ; SET AMOUNT TO COPY + LD A,050H ; + CALL VDU_WREG ; WRITE IT + DEC A + LD A,E ; + CP 00H ; + JP NZ,DO_SCROLL1 ; LOOP TILL DONE + + LD HL, (VDU_DISPLAY_START) ; GET UP START OF DISPLAY + LD BC,0820H ; + ADD HL,BC ; + LD E,23 +DO_SCROLL2: + LD B, 18 ; SET UPDATE(DEST) POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE(DEST) POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD BC,0050H ; + ADD HL,BC ; + LD B, 32 ; SET SOURCE POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 33 ; SET SOURCE POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + LD B, 24 ; SET COPY + LD A,D ; + CALL VDU_WREG ; WRITE IT + + LD B, 30 ; SET AMOUNT TO COPY + LD A,050H ; + CALL VDU_WREG ; WRITE IT + DEC E + LD A,E ; + CP 00H ; + JP NZ,DO_SCROLL2 ; LOOP TILL DONE + + + LD A,23 ; SET CURSOR TO BEGINNING OF LAST LINE + LD (TERM_Y),A ; + LD A,(TERM_X) ; + PUSH AF ; STORE X COORD + LD A,0 ; + LD (TERM_X),A ; + CALL GOTO_XY ; SET CURSOR POSITION TO BEGINNING OF LINE + POP AF ; RESTORE X COORD + POP BC ; RESTORE BC + CALL PERF_ERASE_EOL ; ERASE SCROLLED LINE + LD (TERM_X),A ; + CALL GOTO_XY ; SET CURSOR POSITION + POP HL ; RESTORE HL + POP AF ; RESTORE AF + RET ; + +;__REVERSE_SCROLL__________________________________________________________________________________ +; +; SCROLL THE SCREEN DOWN ONE LINE +;__________________________________________________________________________________________________ +REVERSE_SCROLL: + PUSH AF ; STORE AF + PUSH HL ; STORE HL + PUSH BC ; STORE BC + + LD B, 24 ; GET REGISTER 24 + CALL VDU_GREG ; + OR 80H ; TURN ON COPY BIT + LD E,A ; PARK IT + + LD HL, (VDU_DISPLAY_START) ; GET UP START OF DISPLAY + LD BC,0730H ; + ADD HL,BC + LD D,23 ; +REVERSE_SCROLL1: + LD B, 18 ; SET UPDATE(DEST) POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE(DEST) POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD BC,0FFB0H ; + ADD HL,BC ; + LD B, 32 ; SET SOURCE POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 33 ; SET SOURCE POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + LD B, 24 ; SET COPY + LD A,E ; + CALL VDU_WREG ; WRITE IT + + LD B, 30 ; SET AMOUNT TO COPY + LD A,050H ; + CALL VDU_WREG ; WRITE IT + + DEC D + LD A,D ; + CP 00H ; + JP NZ,REVERSE_SCROLL1 ; LOOP TILL DONE + + + LD HL, (VDU_DISPLAY_START) ; GET UP START OF DISPLAY + LD BC,0F50H ; + ADD HL,BC + LD D,23 ; +REVERSE_SCROLL2: + LD B, 18 ; SET UPDATE(DEST) POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE(DEST) POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD BC,0FFB0H ; + ADD HL,BC ; + LD B, 32 ; SET SOURCE POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 33 ; SET SOURCE POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + LD B, 24 ; SET COPY + LD A,E ; + CALL VDU_WREG ; WRITE IT + + LD B, 30 ; SET AMOUNT TO COPY + LD A,050H ; + CALL VDU_WREG ; WRITE IT + + DEC D + LD A,D ; + CP 00H ; + JP NZ,REVERSE_SCROLL2 ; LOOP TILL DONE + LD A,0 ; SET CURSOR TO BEGINNING OF FIRST LINE + LD (TERM_Y),A ; + LD A,(TERM_X) ; + PUSH AF ; STORE X COORD + LD A,0 ; + LD (TERM_X),A ; + CALL GOTO_XY ; SET CURSOR POSITION TO BEGINNING OF LINE + POP AF ; RESTORE AF + POP BC ; RESTORE BC + CALL PERF_ERASE_EOL ; ERASE SCROLLED LINE + LD (TERM_X),A ; + CALL GOTO_XY ; SET CURSOR POSITION + POP HL ; RESTORE HL + POP AF ; RESTORE AF + RET ; + + + +;__VDU_INIT_________________________________________________________________________________________ +; +; INITIALIZE VDU +;__________________________________________________________________________________________________ +VDU_INIT: + PUSH AF ; STORE AF + PUSH DE ; STORE DE + PUSH HL ; STORE HL + PUSH BC ; STORE BC + + CALL VDU_CRTInit ; INIT 8563 VDU CHIP + CALL VDU_LOADFONT ; + CALL PERF_CURSOR_HOME ; CURSOR HOME + LD C,14 ; + CALL PERF_ERASE_EOS ; CLEAR SCREEN + CALL VDU_CursorOn ; TURN ON CURSOR + + POP BC ; + POP HL ; + POP DE ; + POP AF ; + + RET + +;__PERF_CURSOR_HOME________________________________________________________________________________ +; +; PERFORM CURSOR HOME +;__________________________________________________________________________________________________ +PERF_CURSOR_HOME: + LD A,0 ; LOAD 0 INTO A + LD (TERM_X),A ; SET X COORD + LD (TERM_Y),A ; SET Y COORD + JP GOTO_XY ; MOVE CURSOR TO POSITION + +;__PERF_ERASE_EOS__________________________________________________________________________________ +; +; PERFORM ERASE FROM CURSOR POS TO END OF SCREEN +; C= DEFAULT COLOR +;__________________________________________________________________________________________________ +PERF_ERASE_EOS: + PUSH HL + PUSH AF + PUSH BC + + LD HL, (VDU_DisplayPos) ; GET CURRENT DISPLAY ADDRESS + LD B, 18 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + CALL GOTO_XY ; MOVE CURSOR + LD DE,0820H ; SET SCREEN SIZE INTO HL +PERF_ERASE_EOS_LOOP: + LD A, ' ' ; MOVE SPACE CHARACTER INTO A + LD B,31 ; + CALL VDU_WREG ; WRITE IT TO SCREEN, VDU WILL AUTO INC TO NEXT ADDRESS + DEC DE ; DEC COUNTER + LD A,D ; IS COUNTER 0 YET? + OR E ; + JP NZ,PERF_ERASE_EOS_LOOP ; NO, LOOP + LD DE,0820H ; SET SCREEN SIZE INTO HL +PERF_ERASE_EOS_CLOOP: + LD A, C ; MOVE COLOR INTO A + LD B,31 ; + CALL VDU_WREG ; WRITE IT TO SCREEN, VDU WILL AUTO INC TO NEXT ADDRESS + DEC DE ; DEC COUNTER + LD A,D ; IS COUNTER 0 YET? + OR E ; + JP NZ,PERF_ERASE_EOS_CLOOP ; NO, LOOP + + CALL GOTO_XY ; YES, MOVE CURSOR BACK TO ORIGINAL POSITION + POP BC + POP AF + POP HL + RET + +;__PERF_ERASE_EOL__________________________________________________________________________________ +; +; PERFORM ERASE FROM CURSOR POS TO END OF LINE +; C=DEFAULT COLOR +;__________________________________________________________________________________________________ +PERF_ERASE_EOL: + PUSH HL + PUSH AF + PUSH BC + + LD A,(TERM_X) ; GET CURRENT CURSOR X COORD + LD D,A ; STORE IT IN C + LD A,80 ; MOVE CURRENT LINE WIDTH INTO A + SUB D ; GET REMAINING POSITIONS ON CURRENT LINE + LD B,A ; MOVE IT INTO B +PERF_ERASE_EOL_LOOP: + LD A, ' ' ; MOVE SPACE CHARACTER INTO A + CALL VDU_PutCharRAW ; + DJNZ PERF_ERASE_EOL_LOOP ; LOOP UNTIL DONE + CALL GOTO_XY ; MOVE CURSOR BACK TO ORIGINAL POSITION + POP BC + POP AF + POP HL + RET + +;__DSPMATRIX_______________________________________________________________________________________ +; +; DISPLAY INTRO SCREEN +;__________________________________________________________________________________________________ +DSPMATRIX: + CALL PERF_CURSOR_HOME ; RESET CURSOR TO HOME POSITION + LD HL,TESTMATRIX ; SET HL TO SCREEN IMAGE + LD DE, 1919 ; SET IMAGE SIZE + LD C,00000011B ; SET COLOR +DSPMATRIX_LOOP: + LD A,(HL) ; GET NEXT CHAR FROM IMAGE + call VDU_PutChar ; DUMP CHAR TO DISPLAY + INC HL ; INC POINTER + DEC DE ; DEC COUNTER + LD A,D ; IS COUNTER ZERO? + OR E ; + JP NZ,DSPMATRIX_LOOP ; NO, LOOP + CALL PERF_CURSOR_HOME ; YES, RESET CURSOR TO HOME POSITION + RET + +TESTMATRIX: + .TEXT "0 1 2 3 4 5 6 7 " + .TEXT "01234567890123456789012345678901234567890123456789012345678901234567890123456789" + .TEXT "2 " + .TEXT "3 " + .TEXT "4 ===================================================== " + .TEXT "5 " + .TEXT "6 **** * * **** * * **** * * " + .TEXT "7 * * * * * * * * * * * * " + .TEXT "8 * * * * * * * * * ** " + .TEXT "9 * * * * * * * * * ** " + .TEXT "10 * * * * * * * * * * * * " + .TEXT "11 **** * **** **** **** * * " + .TEXT "12 " + .TEXT "13 ===================================================== " + .TEXT "14 " + .TEXT "15 VDU TEST V0.1 VT-52 EMULATION " + .TEXT "16 " + .TEXT "17 ** PRESS ANY KEY TO ENTER TERMINAL MODE ** " + .TEXT "18 " + .TEXT "19 " + .TEXT "21 " + .TEXT "22 " + .TEXT "23 " + .TEXT "24 " + + +;__VDU_WREG________________________________________________________________________________________ +; +; WRITE VALUE IN A TO REGISTER IN B +; B: REGISTER TO UPDATE +; A: VALUE TO WRITE +;__________________________________________________________________________________________________ +VDU_WREG: + PUSH AF ; STORE AF +VDU_WREG_1: + IN A,(M8563Status) ; read address/status register + BIT 7,A ; if bit 7 = 1 than an update strobe has been occured + JR Z,VDU_WREG_1 ; wait for ready + LD A,B ; + OUT (M8563Register),A ; select register +VDU_WREG_2: + IN A,(M8563Status) ; read address/status register + BIT 7,A ; if bit 7 = 1 than an update strobe has been occured + JR Z,VDU_WREG_2 ; wait for ready + POP AF ; + OUT (M8563Data),A ; PUT DATA + RET + + +;__VDU_GREG________________________________________________________________________________________ +; +; GET VALUE FROM REGISTER IN B PLACE IN A +; B: REGISTER TO GET +; A: VALUE +;__________________________________________________________________________________________________ +VDU_GREG: + IN A,(M8563Status) ; read address/status register + BIT 7,A ; if bit 7 = 1 than an update strobe has been occured + JR Z,VDU_GREG ; wait for ready + LD A,B ; + OUT (M8563Register) , A ; select register +VDU_GREG_1: + IN A,(M8563Status) ; read address/status register + BIT 7,A ; if bit 7 = 1 than an update strobe has been occured + JR Z,VDU_GREG_1 ; wait for ready + IN A,(M8563Data) ; GET DATA + RET + + + +VDU_Init8563: + .DB 126,80,102,73,32,224,25,29,252,231,160,231,0,0,7,128 + .DB 18,23,15,208,8,32,120,232,32,71,240,0,47,231,79,7,15,208,125,100,245 + +;__VDU_CRTInit_____________________________________________________________________________________ +; +; INIT VDU CHIP +;__________________________________________________________________________________________________ +VDU_CRTInit: + PUSH AF ; STORE AF + PUSH BC ; STORE BC + PUSH HL ; STORE HL + + LD B,$00 ; B = 0 + LD HL,VDU_Init8563 ; HL = pointer to the default values + XOR A ; A = 0 +VDU_CRTInitLoop: + LD A,(HL) ; GET VALUE + CALL VDU_WREG ; WRITE IT + INC HL + INC B ; + LD A,B ; + CP 37 ; + JR NZ,VDU_CRTInitLoop ; LOOP UNTIL DONE + POP HL ; RESTORE HL + POP BC ; RESTORE BC + POP AF ; RESTORE AF + RET + + +;__VDU_CursorOn____________________________________________________________________________________ +; +; TURN ON CURSOR +;__________________________________________________________________________________________________ +VDU_CursorOn: + PUSH AF ; STORE AF + LD A, $60 ; SET CURSOR VALUE + JP VDU_CursorSet ; + +;__VDU_CursorOff___________________________________________________________________________________ +; +; TURN OFF CURSOR +;__________________________________________________________________________________________________ +VDU_CursorOff: + PUSH AF ; STORE AF + LD A, $20 ; SET CURSOR VALUE +VDU_CursorSet: + PUSH BC ; STORE BC + LD B,10 + CALL VDU_WREG ; WRITE IT + POP BC ; RESTORE BC + POP AF ; RESTORE AF + RET + +;__GOTO_XY_________________________________________________________________________________________ +; +; MOVE CURSOR TO POSITON IN TERM_X AND TERM_Y +;__________________________________________________________________________________________________ +GOTO_XY: + PUSH AF ; STORE AF + + LD A,(TERM_Y) ; PLACE Y COORD IN A + CP 24 ; IS 24? + JP Z,DO_SCROLLE1 ; YES, MUST SCROLL + + PUSH BC ; STORE BC + PUSH DE ; STORE DE + LD A,(TERM_X) ; + LD H,A ; + LD A,(TERM_Y) ; + LD L,A ; + PUSH HL ; STORE HL + LD B, A ; B = Y COORD + LD DE, 80 ; MOVE LINE LENGTH INTO DE + LD HL, 0 ; MOVE 0 INTO HL + LD A, B ; A=B + CP 0 ; Y=0? + JP Z, VDU_YLoopEnd ; THEN DO NOT MULTIPLY BY 80 +VDU_YLoop: ; HL = 80 * Y + ADD HL, DE ; HL=HL+DE + DJNZ VDU_YLoop ; LOOP +VDU_YLoopEnd: ; + POP DE ; DE = org HL + LD E, D ; E = X + LD D, 0 ; D = 0 + ADD HL, DE ; HL = HL + X + LD (VDU_DisplayPos), HL ; + PUSH HL ; + POP DE ; + LD HL,(VDU_DISPLAY_START) ; + ADD HL,DE ; + LD B, 18 ; SET UPDATE ADDRESS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE ADDRESS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + LD B, 14 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 15 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + POP DE ; RESTORE DE + POP BC ; RESTORE BC + POP AF ; RESTORE AF + RET + +;__VDU_PutChar______________________________________________________________________________________ +; +; PLACE CHARACTER ON SCREEN +; A: CHARACTER TO OUTPUT +; C: COLOR +;__________________________________________________________________________________________________ +VDU_PutChar: + PUSH DE ; STORE DE + PUSH AF ; STORE AF + PUSH HL ; STORE HL + LD D,A ; STORE CHAR IN D + LD A,(TERM_X) ; PLACE X COORD IN A + INC A ; INC X COORD + LD (TERM_X),A ; STORE IN A + CP 80 ; IS 80? + JP NZ,VDU_PutChar1 ; NO, PLACE CHAR ON DISPLAY + LD A,0 ; YES, WRAP TO NEXT LINE + LD (TERM_X),A ; STORE X + LD A,(TERM_Y) ; A= Y COORD + INC A ; INC Y COORD + LD (TERM_Y),A ; STORE Y + CP 24 ; IS PAST END OF SCREEN? + CALL Z,GOTO_XY ; YES, HANDLE SCROLLING +VDU_PutChar1: ; + ; + LD HL, (VDU_DisplayPos) ; GET CURRENT DISPLAY ADDRESS + LD B, 18 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD A,D ; RESTORE CHAR + LD B,31 ; + CALL VDU_WREG ; WRITE IT + PUSH HL ; + LD DE,$0820 ; + ADD HL,DE ; + LD B, 18 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD A,C ; GET COLOR + LD B,31 ; + CALL VDU_WREG ; WRITE IT + POP HL ; RESTORE ADDRESS + INC HL ; INCREMENT IT + LD (VDU_DisplayPos), HL ; STORE CURRENT DISPLAY ADDRESS + PUSH HL ; MOVE HL TO DE + POP DE ; + LD HL,(VDU_DISPLAY_START) ; + ADD HL,DE ; + LD B, 14 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 15 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + POP HL ; RESTORE HL + POP AF ; RESTORE AF + POP DE ; RESTORE DE + RET + +VDU_PutCharRAW: + PUSH BC ; + LD D,A ; + LD HL, (VDU_DisplayPos) ; GET CURRENT DISPLAY ADDRESS + LD B, 18 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD A,D ; RESTORE CHAR + LD B,31 ; + CALL VDU_WREG ; WRITE IT + PUSH HL ; + LD DE,$0820 ; + ADD HL,DE ; + LD B, 18 ; SET UPDATE CSR POS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE CSR POS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + LD A,C ; GET COLOR + LD B,31 ; + CALL VDU_WREG ; WRITE IT + POP HL ; RESTORE ADDRESS + INC HL ; INCREMENT IT + LD (VDU_DisplayPos), HL ; STORE CURRENT DISPLAY ADDRESS + POP BC + RET + +;__VDU_LOADFONT____________________________________________________________________________________ +; +; LOAD SCREEN FONT +;__________________________________________________________________________________________________ +VDU_LOADFONT: + PUSH AF + PUSH BC + + LD HL,$2000 ; SET FONT LOCATION + ; + LD B, 18 ; SET UPDATE ADDRESS IN VDU + LD A,H ; + CALL VDU_WREG ; WRITE IT + LD B, 19 ; SET UPDATE ADDRESS IN VDU + LD A,L ; + CALL VDU_WREG ; WRITE IT + + LD B,$00 ; FONT SIZE + LD C,$20 ; FONT SIZE + LD HL,FONT ; FONT DATA +VDU_LOADFONT_LOOP: + IN A,(M8563Status) ; read address/status register + BIT 7,A ; if bit 7 = 1 than an update strobe has been occured + JR Z,VDU_LOADFONT_LOOP ; wait for ready + LD A,31 ; + OUT (M8563Register) , A ; select register +VDU_LOADFONT_LOOP_1: + IN A,(M8563Status) ; read address/status register + BIT 7,A ; if bit 7 = 1 than an update strobe has been occured + JR Z,VDU_LOADFONT_LOOP_1 ; wait for ready + LD A,(HL) ; + OUT (M8563Data) , A ; PUT DATA + INC HL + DJNZ VDU_LOADFONT_LOOP ; + DEC C ; + JP NZ,VDU_LOADFONT_LOOP ; + POP BC + POP AF + RET + +;__KB_INITIALIZE___________________________________________________________________________________ +; +; INIT KEYBOARD CONTROLLER +;__________________________________________________________________________________________________ +KB_INITIALIZE: + LD C,0aaH ; SELF TEST + CALL I8242CommandPut ; + LD C,060H ; SET COMMAND REGISTER + CALL I8242CommandPut ; + LD C,$60 ; XLAT ENABLED, MOUSE DISABLED, NO INTS + CALL I8242DataPut ; + LD C,0a7H ; DISABLE MOUSE + CALL I8242CommandPut ; + LD C,0aeH ; ENABLE KEYBOARD + CALL I8242CommandPut ; + LD A,0 ; EMPTY KB QUEUE + LD (KB_QUEUE_PTR),A ; + RET + +;__I8242CommandPut_________________________________________________________________________________ +; +; WRITE VALUE IN A TO 8242 +; C: VALUE TO WRITE +;__________________________________________________________________________________________________ +I8242CommandPut: + IN A,(I8242Status) ; read status register + BIT 1,A ; if bit 1 = 1 + JR NZ,I8242CommandPut ; wait for ready + LD A,C ; + OUT (I8242Command),A ; select register + RET + +;__I8242DataPut____________________________________________________________________________________ +; +; WRITE VALUE IN A TO 8242 +; C: VALUE TO WRITE +;__________________________________________________________________________________________________ +I8242DataPut: + IN A,(I8242Status) ; read status register + BIT 1,A ; if bit 1 = 1 + JR NZ,I8242DataPut ; wait for ready + LD A,C ; + OUT (I8242Data),A ; select register + RET + +;__WAIT_KBHIT______________________________________________________________________________________ +; +; WAIT FOR A KEY PRESS +;__________________________________________________________________________________________________ +WAIT_KBHIT: + CALL KB_PROCESS ; call keyboard routine + LD A,(KB_QUEUE_PTR) ; IS QUEUE EMPTY? + OR A ; set flags + JP Z,WAIT_KBHIT ; if no keys waiting, try again + RET + +;__IS_KBHIT________________________________________________________________________________________ +; +; WAS A KEY PRESSED? +;__________________________________________________________________________________________________ +IS_KBHIT: + CALL KB_PROCESS ; call keyboard routine + LD A,(KB_QUEUE_PTR) ; ask if keyboard has key waiting + RET + + +;__GET_KEY_________________________________________________________________________________________ +; +; GET KEY PRESS VALUE +;__________________________________________________________________________________________________ +GET_KEY: + CALL WAIT_KBHIT ; WAIT FOR A KEY + LD A,(KB_QUEUE_PTR) ; GET QUEUE POINTER + OR A ; + RET Z ; ABORT IF QUEUE EMPTY + PUSH BC ; STORE BC + LD B,A ; STORE QUEUE COUNT FOR LATER + PUSH HL ; STORE HL + LD A,(KB_QUEUE) ; GET TOP BYTE FROM QUEUE + PUSH AF ; STORE IT + LD HL,KB_QUEUE ; GET POINTER TO QUEUE +GET_KEY_LOOP: ; + INC HL ; POINT TO NEXT VALUE IN QUEUE + LD A,(HL) ; GET VALUE + DEC HL ; + LD (HL),A ; MOVE IT UP ONE + INC HL ; + DJNZ GET_KEY_LOOP ; LOOP UNTIL DONE + LD A,(KB_QUEUE_PTR) ; DECREASE QUEUE POINTER BY ONE + DEC A ; + LD (KB_QUEUE_PTR),A ; + POP AF ; RESTORE VALUE + POP HL ; RESTORE HL + POP BC ; RESTORE BC + RET + + +;__KB_PROCESS______________________________________________________________________________________ +; +; a=0 if want to know if a byte is available, and a=1 to ask for the byte +;__________________________________________________________________________________________________ +KB_PROCESS: + IN A,(I8242Status) ; read status register + BIT 0,A ; if bit 0 = 0 + RET Z ; EXIT + IN A,(I8242Data) ; GET BYTE + call KB_decodechar ; returns char or 0 for things like keyup, some return directly to cp/m + ret ; return to cp/m + +;__KB_waitbyte______________________________________________________________________________________ +; +; WAIT FOR byte TO BE available +;__________________________________________________________________________________________________ +KB_waitbyte: + IN A,(I8242Status) ; read status register + BIT 0,A ; if bit 0 = 0 + jp Z,KB_waitbyte ; LOOP + IN A,(I8242Data) ; GET BYTE + RET + + + +;__KB_decodechar____________________________________________________________________________________ +; +; decode character pass a and prints out the char +; on the LCD screen +;__________________________________________________________________________________________________ +KB_decodechar: + cp 0 ; is it zero + ret z ; return if a zero - no need to do anything + + ld c,a ; + cp 0AAh ; shift (down, because up would be trapped by 0F above) + jp z,shiftup ; + cp 0B6h ; other shift key + jp z,shiftup ; + cp 9Dh ; control key + jp z,controlup ; + AND 80H ; if bit 7 = 1 + RET nz ; ignore char up + ld a,C ; + cp 0E0h ; TWO BYTE + JP Z,twobyte ; + cp 03Ah ; caps lock so toggle + jp z,capstog ; + cp 2Ah ; shift (down, because up would be trapped by 0F above) + jp z,shiftdown ; + cp 36h ; other shift key + jp z,shiftdown ; + cp 01Dh ; control key + jp z,controldown ; + ld c,a ; + ld b,0 ; add bc to hl + ld hl,normalkeys ; offset to add + add hl,bc ; + ld a,(ctrl) ; + cp 0 ; is control being held down? + jR z,dc1 ; no so go back to test caps lock on + ld a,(hl) ; get the letter, should be smalls + sub 96 ; a=97 so subtract 96 a=1=^A + JP KB_ENQUEUE ; STORE ON KB QUEUE +dc1: ld a,(capslock) ; + cp 0 ; is it 0, if so then don't add the caps offset + jr z,dc2 ; + ld c,080h ; add another 50h to smalls to get caps + add hl,bc ; +dc2: ld a,(hl) ; + JP KB_ENQUEUE ; STORE ON KB QUEUE +twobyte:; already got EO so get the next character + call KB_waitbyte + cp 053h ; delete + jp z,deletekey ; + cp 01Ch ; return on number pad + jp z,returnkey ; + cp 050h ; + jp z,downarrow ; + cp 04Dh ; + jp z,rightarrow ; + cp 04Bh ; + jp z,leftarrow ; + cp 048h ; + jp z,uparrow ; + cp 052h ; + jp z,insert ; + cp 049h ; + jp z,pageup ; + cp 051h ; + jp z,pagedown ; + cp 047h ; + jp z,home ; + cp 04Fh ; + jp z,end ; + ld a,0 ; returns nothing + ret +home: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'?' ; ? + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'w' ; w + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +end: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'?' ; ? + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'q' ; q + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +downarrow: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'B' ; B + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +rightarrow: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'C' ; C + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +leftarrow: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'D' ; D + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +uparrow: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'A' ; A + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +insert: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'?' ; ? + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'p' ; p + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +pageup: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'?' ; ? + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'y' ; y + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +pagedown: ; + ld a,1BH ; ESC + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'?' ; ? + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ld a,'s' ; s + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +controldown: ; same code as shiftdown but diff location + ld a,0ffh ; + ld (ctrl),a ; control down + ld a,0 ; + ret ; +controlup: ; control key up see shift for explanation + ld a,0 ; + ld (ctrl),a ; + ld a,0 ; + ret ; +returnkey: ; + ld a,13 ; + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +deletekey: ; + ld a,07fh ; delete key value that cp/m uses + CALL KB_ENQUEUE ; STORE ON KB QUEUE + ret ; +capstog: ; + ld a,(capslock) ; + xor 11111111B ; swap all the bits + ld (capslock),a ; + ld a,0 ; returns nothing + ret ; +shiftdown: ; shift is special - hold it down and it autorepeats + ; so once it is down, turn caps on and ignore all further shifts + ; only an F0+shift turns caps lock off again + ld a,0ffh ; + ld (capslock),a ; + ld a,0 ; returns nothing + ret ; +shiftup: ; shiftup turns off caps lock definitely + ld a,0 ; + ld (capslock),a ; + ld a,0 ; returns nothing + ret ; + +;__KB_ENQUEUE______________________________________________________________________________________ +; +; STORE A BYTE IN THE KEYBOARD QUEUE +; A: BYTE TO ENQUEUE +;__________________________________________________________________________________________________ +KB_ENQUEUE: + PUSH DE ; STORE DE + PUSH HL ; STORE HL + PUSH AF ; STORE VALUE + LD A,(KB_QUEUE_PTR); PUT QUEUE POINTER IN A + CP 15 ; IS QUEUE FULL + JP P,KB_ENQUEUE_AB ; YES, ABORT + LD HL,KB_QUEUE ; GET QUEUE POINTER + PUSH HL ; MOVE HL TO BC + POP BC ; + LD H,0 ; ZERO OUT H + LD L,A ; PLACE QUEUE POINTER IN L + ADD HL,BC ; POINT HL AT THE NEXT LOACTION TO ADD VALUE + POP AF ; RESTORE VALUE + LD (HL),A ; ENQUEUE VALUE + LD A,(KB_QUEUE_PTR); GET QUEUE POINTER + INC A ; INC IT + LD (KB_QUEUE_PTR),A; STORE QUEUE POINTER +KB_ENQUEUE_AB: + POP HL ; RESTORE HL + POP DE ; RESTORE DE + RET + + + + +normalkeys: ; The TI character codes, offset from label by keyboard scan code + .db 000,027,"1","2","3","4","5","6","7","8","9","0","-","=",008,009 ;00-0F + .DB "q","w","e","r","t","y","u","i","o","p","[","]",013,000,"a","s" ;10-1F + .DB "d","f","g","h","j","k","l",";",27H,60H,000,092,"z","x","c","v" ;20-2F + .DB "b","n","m",",",".","/",000,000,000," ",000,000,000,000,000,000 ;30-3F + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;40-4F + .db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;50-5F + .db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;60-6F + .db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;70-7F + .db 000,027,"!","@","#","$","%","^","&","*","(",")","_","+",008,009 + .DB "Q","W","E","R","T","Y","U","I","O","P","{","}",013,000,"A","S" + .DB "D","F","G","H","J","K","L",":",034,"~",000,"|","Z","X","C","V" + .DB "B","N","M","<",">","?",000,000,000," ",000,000,000,000,000,000 + .db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 + .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 + .db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 + .db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 + + +; .DB 0,"*", 0,"*","*","*","*","*", 0,"*","*","*","*",09H,"`",00H +; .DB 0, 0, 0, 0, 0,"q","1", 0, 0, 0,"z","s","a","w","2",0 +; .DB 0,"c","x","d","e","4","3", 0, 0," ","v","f","t","r","5",0 +; .DB 0,"n","b","h","g","y","6", 0, 0, 0,"m","j","u","7","8",0 +; .DB 0,",","k","i","o","0","9", 0, 0,".","/","l",";","p","-",0 +; .DB 0, 0,27H, 0,"[","=", 0, 0, 0, 0,0DH,"]", 0,5CH, 0,0 +; .DB 0, 0, 0, 0, 0, 0,08H, 0, 0,11H, 0,13H,10H, 0, 0, 0 +; .DB 0BH,7FH,03H,15H,04H,05H,1BH,00H,"*",02H,18H,16H,0CH,17H,"*",0 +; .DB 0, 0, 0,"*", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + + + .include "font.asm" + +;__________________________________________________________________________________________________ +; +; RAM STORAGE AREAS +;__________________________________________________________________________________________________ + +ALT_KEYPAD .DB 0 ; ALT KEYPAD ENABLED? +GR_MODE .DB 0 ; GRAPHICS MODE ENABLED? +TERM_X: .DB 0 ; CURSOR X +TERM_Y: .DB 0 ; CURSOR Y +TERMSTATE: .DB 0 ; TERMINAL STATE + ; 0 = NORMAL + ; 1 = ESC RCVD +VDU_DisplayPos: .DW 0 ; CURRENT DISPLAY POSITION +VDU_DISPLAY_START: + .DW 0 ; CURRENT DISPLAY POSITION +capslock .DB 0 ; location for caps lock, either 00000000 or 11111111 +ctrl .DB 0 ; location for ctrl on or off 00000000 or 11111111 +numlock .DB 0 ; location for num lock +skipcount .DB 0 ; only check some calls, speeds up a lot of cp/m + +KB_QUEUE .DB 0,0,0,0,0,0,0,0 ; 16 BYTE KB QUEUE + .DB 0,0,0,0,0,0,0,0 +KB_QUEUE_PTR .DB 0 ; POINTER TO QUEUE +PARKSTACK .DW 0000 ; SAVE STACK POINTER + + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; + .DB 0,0,0,0,0,0,0,0 ; +TERMSTACK: .DB 0 ; + + + .end diff --git a/Source/CPM3/Build.cmd b/Source/CPM3/Build.cmd index 852c8266..24d69ca1 100644 --- a/Source/CPM3/Build.cmd +++ b/Source/CPM3/Build.cmd @@ -21,11 +21,13 @@ zx Z80ASM -UTIL/MF || exit /b copy optdsk.lib ldropts.lib || exit /b zx Z80ASM -BIOSLDR/MF || exit /b move /Y biosldr.rel biosldrd.rel || exit /b +move /Y biosldr.lst biosldrd.lst || exit /b zx LINK -CPMLDRD[L100]=CPMLDR,BIOSLDRD,UTIL || exit /b move /Y cpmldrd.com cpmldr.bin || exit /b copy optcmd.lib ldropts.lib || exit /b zx Z80ASM -BIOSLDR/MF || exit /b move /Y biosldr.rel biosldrc.rel || exit /b +move /Y biosldr.lst biosldrd.lst || exit /b zx LINK -CPMLDRC[L100]=CPMLDR,BIOSLDRC,UTIL || exit /b move /Y cpmldrc.com cpmldr.com || exit /b rem pause diff --git a/Source/HBIOS/cvdu.asm b/Source/HBIOS/cvdu.asm index 7c68ac72..e2dcc4aa 100644 --- a/Source/HBIOS/cvdu.asm +++ b/Source/HBIOS/cvdu.asm @@ -55,9 +55,24 @@ TERMENABLE .SET TRUE ; INCLUDE TERMINAL PSEUDODEVICE DRIVER ; CVDU_INIT: LD IY,CVDU_IDAT ; POINTER TO INSTANCE DATA - - CALL NEWLINE ; FORMATTING - PRTS("CVDU: IO=0x$") + + CALL NEWLINE + PRTS("CVDU: MODE=$") +#IF (CVDUMODE == CVDUMODE_ECB) + PRTS("ECB$") +#ENDIF +#IF (CVDUMODE == CVDUMODE_MBC) + PRTS("MBC$") +#ENDIF +; +#IF (CVDUMON == CVDUMON_CGA) + PRTS(" CGA$") +#ENDIF +#IF (CVDUMON == CVDUMON_EGA) + PRTS(" EGA$") +#ENDIF +; + PRTS(" IO=0x$") LD A,CVDU_STAT CALL PRTHEXBYTE CALL CVDU_PROBE ; CHECK FOR HW PRESENCE @@ -808,8 +823,10 @@ CVDU_INIT8563: .DB $1D ; 7: vert. sync postition .DB $FC ; 8: interlace mode .DB $E7 ; 9: char height - 1 - .DB $A0 ; 10: cursor mode, start line - .DB $E7 ; 11: cursor end line +; .DB $A0 ; 10: cursor mode, start line + .DB $47 ; 10: cursor mode, start line +; .DB $E7 ; 11: cursor end line + .DB $07 ; 11: cursor end line .DB $00 ; 12: display start addr hi .DB $00 ; 13: display start addr lo .DB $07 ; 14: cursor position hi @@ -819,7 +836,8 @@ CVDU_INIT8563: .DB $0F ; 18: update address hi .DB $D0 ; 19: update address lo .DB $08 ; 20: attribute start addr hi - .DB $20 ; 21: attribute start addr lo +; .DB $20 ; 21: attribute start addr lo + .DB $00 ; 21: attribute start addr lo .DB $78 ; 22: char hor size cntrl 0x78 .DB $E8 ; 23: vert char pixel space - 1, increase to 13 with new font .DB $20 ; 24: copy/fill, reverse, blink rate; vertical scroll diff --git a/Source/HBIOS/kbd.asm b/Source/HBIOS/kbd.asm index 2d39197c..4ae36c51 100644 --- a/Source/HBIOS/kbd.asm +++ b/Source/HBIOS/kbd.asm @@ -73,6 +73,13 @@ KBD_INIT: LD A,$AA ; CONTROLLER SELF TEST CALL KBD_PUTCMD ; SEND IT CALL KBD_GETDATA ; CONTROLLER SHOULD RESPOND WITH $55 (ACK) + + CP $55 ; IS IT THERE? + JR Z,KBD_INIT1 ; IF SO, CONTINUE + PRTS(" NOT PRESENT$") ; DIAGNOSE PROBLEM + RET ; BAIL OUT + +KBD_INIT1: LD A,$60 ; SET COMMAND REGISTER CALL KBD_PUTCMD ; SEND IT ; LD A,$60 ; XLAT ENABLED, MOUSE DISABLED, NO INTS diff --git a/Source/Images/Build.cmd b/Source/Images/Build.cmd index 2f5672e1..63c6572d 100644 --- a/Source/Images/Build.cmd +++ b/Source/Images/Build.cmd @@ -1,30 +1,30 @@ @echo off setlocal -::call BuildDisk.cmd bp wbw_hd512 || exit /b +::call BuildDisk.cmd bp hd wbw_hd512 || exit /b ::goto :eof echo. echo Building Floppy Disk Images... echo. -call BuildDisk.cmd cpm22 wbw_fd144 ..\cpm22\cpm_wbw.sys || exit /b -call BuildDisk.cmd zsdos wbw_fd144 ..\zsdos\zsys_wbw.sys || exit /b -::call BuildDisk.cmd nzcom wbw_fd144 ..\zsdos\zsys_wbw.sys || exit /b -::call BuildDisk.cmd cpm3 wbw_fd144 ..\cpm3\cpmldr.sys || exit /b -::call BuildDisk.cmd zpm3 wbw_fd144 ..\cpm3\cpmldr.sys || exit /b -call BuildDisk.cmd ws4 wbw_fd144 || exit /b +call BuildDisk.cmd cpm22 fd wbw_fd144 ..\cpm22\cpm_wbw.sys || exit /b +call BuildDisk.cmd zsdos fd wbw_fd144 ..\zsdos\zsys_wbw.sys || exit /b +call BuildDisk.cmd nzcom fd wbw_fd144 ..\zsdos\zsys_wbw.sys || exit /b +call BuildDisk.cmd cpm3 fd wbw_fd144 ..\cpm3\cpmldr.sys || exit /b +call BuildDisk.cmd zpm3 fd wbw_fd144 ..\zpm3\zpmldr.sys || exit /b +call BuildDisk.cmd ws4 fd wbw_fd144 || exit /b echo. echo Building Hard Disk Images (512 directory entry format)... echo. -call BuildDisk.cmd cpm22 wbw_hd512 ..\cpm22\cpm_wbw.sys || exit /b -call BuildDisk.cmd zsdos wbw_hd512 ..\zsdos\zsys_wbw.sys || exit /b -call BuildDisk.cmd nzcom wbw_hd512 ..\zsdos\zsys_wbw.sys || exit /b -call BuildDisk.cmd cpm3 wbw_hd512 ..\cpm3\cpmldr.sys || exit /b -call BuildDisk.cmd zpm3 wbw_hd512 ..\zpm3\zpmldr.sys || exit /b -call BuildDisk.cmd ws4 wbw_hd512 || exit /b +call BuildDisk.cmd cpm22 hd wbw_hd512 ..\cpm22\cpm_wbw.sys || exit /b +call BuildDisk.cmd zsdos hd wbw_hd512 ..\zsdos\zsys_wbw.sys || exit /b +call BuildDisk.cmd nzcom hd wbw_hd512 ..\zsdos\zsys_wbw.sys || exit /b +call BuildDisk.cmd cpm3 hd wbw_hd512 ..\cpm3\cpmldr.sys || exit /b +call BuildDisk.cmd zpm3 hd wbw_hd512 ..\zpm3\zpmldr.sys || exit /b +call BuildDisk.cmd ws4 hd wbw_hd512 || exit /b -if exist ..\BPBIOS\bpbio-ww.rel call BuildDisk.cmd bp wbw_hd512 || exit /b +if exist ..\BPBIOS\bpbio-ww.rel call BuildDisk.cmd bp hd wbw_hd512 || exit /b echo. echo Building Combo Disk (512 directory entry format) Image... @@ -33,14 +33,14 @@ copy /b ..\..\Binary\hd512_cpm22.img + ..\..\Binary\hd512_zsdos.img + ..\..\Bina echo. echo Building Hard Disk Images (1024 directory entry format)... echo. -call BuildDisk.cmd cpm22 wbw_hd1024 ..\cpm22\cpm_wbw.sys || exit /b -call BuildDisk.cmd zsdos wbw_hd1024 ..\zsdos\zsys_wbw.sys || exit /b -call BuildDisk.cmd nzcom wbw_hd1024 ..\zsdos\zsys_wbw.sys || exit /b -call BuildDisk.cmd cpm3 wbw_hd1024 ..\cpm3\cpmldr.sys || exit /b -call BuildDisk.cmd zpm3 wbw_hd1024 ..\zpm3\zpmldr.sys || exit /b -call BuildDisk.cmd ws4 wbw_hd1024 || exit /b +call BuildDisk.cmd cpm22 hd wbw_hd1024 ..\cpm22\cpm_wbw.sys || exit /b +call BuildDisk.cmd zsdos hd wbw_hd1024 ..\zsdos\zsys_wbw.sys || exit /b +call BuildDisk.cmd nzcom hd wbw_hd1024 ..\zsdos\zsys_wbw.sys || exit /b +call BuildDisk.cmd cpm3 hd wbw_hd1024 ..\cpm3\cpmldr.sys || exit /b +call BuildDisk.cmd zpm3 hd wbw_hd1024 ..\zpm3\zpmldr.sys || exit /b +call BuildDisk.cmd ws4 hd wbw_hd1024 || exit /b -if exist ..\BPBIOS\bpbio-ww.rel call BuildDisk.cmd bp wbw_hd1024 || exit /b +if exist ..\BPBIOS\bpbio-ww.rel call BuildDisk.cmd bp hd wbw_hd1024 || exit /b copy hd1024_prefix.dat ..\..\Binary\ || exit /b diff --git a/Source/Images/BuildDisk.ps1 b/Source/Images/BuildDisk.ps1 index b0ff3808..dd2805d1 100644 --- a/Source/Images/BuildDisk.ps1 +++ b/Source/Images/BuildDisk.ps1 @@ -1,4 +1,4 @@ -Param($Disk, $Format="", $SysFile="") +Param($Disk, $Type="", $Format="", $SysFile="") $ErrorAction = 'Stop' @@ -6,6 +6,12 @@ $CpmToolsPath = '../../Tools/cpmtools' $env:PATH = $CpmToolsPath + ';' + $env:PATH +if ($Type.Length -eq 0) +{ + Write-Error "No disk type specified!" -ErrorAction Stop + return +} + if ($Format.Length -eq 0) { Write-Error "No disk format specified!" -ErrorAction Stop @@ -75,9 +81,9 @@ for ($Usr=0; $Usr -lt 16; $Usr++) } } -if (Test-Path("d_${Disk}.txt")) +if (Test-Path("${Type}_${Disk}.txt")) { - foreach($Line in Get-Content "d_${Disk}.txt") + foreach($Line in Get-Content "${Type}_${Disk}.txt") { $Spec = $Line.Trim() if (($Spec.Length -gt 0) -and ($Spec.Substring(0,1) -ne "#")) diff --git a/Source/Images/Common/All/ZDE.DOC b/Source/Images/Common/All/ZDE.DOC new file mode 100644 index 00000000..6bf63117 --- /dev/null +++ b/Source/Images/Common/All/ZDE.DOC @@ -0,0 +1,1043 @@ +ZDE 1.0 Manual + ZDE + + Z-System Display Editor + + Version 1.0 10 Mar 89 + + ZDE and its documentation are copyright 1989 by Carson Wilson, + all rights reserved. They may not be circulated in any + incomplete or modified form without written permission of the + author. Any commercial use of ZDE, defined as any situation + where the duplicator receives revenue by duplicating or + distributing ZDE by itself or in conjunction with any hardware + or software product, is expressly prohibited unless authorized + in writing by Carson Wilson. + + +1. Introduction. + + ZDE, the Z-System Display Editor, is a small, fast, powerful +text editor based Eric Meyer's famous Video Display Editor (VDE). +ZDE retains all features of VDE, but removes defects and supports +special ZCPR and ZSDOS features such as named directories, +register variables, automatic disk relog, and file datestamp +support. The install program has also been improved (see +ZDE10.NEW for a complete rundown of improvements). At the same +time, I have tried to be conscientious about the balance between +features and memory usage. If I added every new feature or +convenience that came to mind, we would soon have a luxurious +in-memory editor for 2 kilobyte files! Much of the following is +adapted with permission from Eric Meyer's VDE.DOC. + + ZDE's native ASCII mode and definable macros make it an ideal +programmer's editor; its full formatting and printing features +also make it an efficient word processor. Written entirely in Z80 +assembler, ZDE is F-A-S-T. There are no disk overlays, and all +editing is done in memory. As a result, finding a string near the +end of a 50K file takes WordStar 3.3 about 14 seconds (8MHz Z80); +ZDE does it in under a second. This is like moving through air +instead of molasses: you will find that you can do more of your +work on screen, and less on paper. + +Among ZDE's features are: + +Full-screen editing User area and named directory support +Block operations Wordwrap and reformat +File datestamp support Macro programs +Disk file operations Margins, tabs, spacing +Find and replace WordStar compatibility +Many print features Undeletion +Configurable options Support for all CP/M terminals + + +2. Installing ZDE. + + ZDE works with Z80 CP/M 2.2 and 3.0 and compatible systems. +It is ideal for portable computers with limited disk space. There +are many user configurable options, and ZDE can be installed for +all CP/M terminals. If you are running ZCPR, ZSDOS or Z3PLUS, ZDE +offers features not available with less advanced system software, +but these system enhancements are not required. + + To install ZDE, use the ZDENSTAL configuration program; see +the accompanying file ZDENSTAL.DOC. You should install ZDE for +your computer's terminal at the earliest convenience, since this +greatly enhances performance. There are many other installable +options; you will discover how you want everything set in the +course of using ZDE, so don't worry about going through all of it +at first. For ease of reference, portions of this manual +referring to installable options and settings are enclosed in +square brackets ("[" and "]"). + + +3. Invoking ZDE. + + ZDE is invoked from your system's command prompt using the +following syntax ("ufn" means "unambiguous file name"): + + ZDE Begin working on a new file. + + ZDE ufn Edit a new or already existing file. + + ZDE dir:ufn Edit a new or existing file from another + directory. + + ZDE ufn m Edit a file using mode "m." + ZDE ufn[m + +"m" above can be either W, A, or N (see File Modes, below), and +"dir" can be either a drive, a user area, a drive followed by a +user area, or a ZCPR named directory. For example: + + ZDE A4:MYFILE.TXT N Begin working on MYFILE.TXT at user + area 4, drive A, in non-document + mode. + + The size of the file to be edited is limited by available +memory. This will vary for different systems, but normally the +maximum size will be between 45 and 55k. If a file is too large +to edit, you must break it up and edit the pieces separately. +Numerous CP/M utilities are available which will break up and +rejoin ASCII files. + + +4. ZDE's Command Set. + + ZDE's commands consist of simple one- or two-key +combinations, easily found by the touch typist without +distraction. Most commands are the same as WordStar's. If you +have questions that this file can't answer, a WordStar manual may +be a useful reference. But ZDE is not a WordStar "clone"; there +are significant differences, including an extended set of +ESC-commands for functions such as macros (see below). + Virtually complete compatibility with the WordStar command +(sub)set can be achieved UNLESS the keys ^J, ^K, and ^L are used +as arrow keys (as on many CP/M computers). In this event ZDE +synonyms must be used: ESC- for the ^K- prefix; ESC-H for ^J; and +^\ for ^L (see ZDENSTAL.DOC for terminal installation). + +4.1. Command Summary. + + Below, the "^" character indicates use of the Ctrl key: ^K = +Ctrl+K. The ESC (^K), ^O, and ^Q prefixes require pressing two +keys in sequence: ^O C, for instance means press ^O, then C (or +^C). Any prefix may be canceled by typing ESC or Space. + +4.1.1. Control Keys: Single Keystroke Commands. + + ^J (ESC H) = display Help menus. + + CR = Carriage return (^M). Marks a paragraph end. + BS = Backspace (^H). + TAB = Hard Tab mode: insert tab (^I). Variable Tab mode: move + to next stop. + + Arrow keys: WordStar: ^E up, ^X down, ^S left, ^D right. + Alternate: configurable, default ^K, ^J, ^H, ^L. + + ^F = move to start of next word right. + ^A = move to start of next word left. + ^R = scroll back one screen. + ^C = scroll forward one screen. + ^W = scroll back one line. + ^Z = scroll forward one line. + + ^G = delete character to the right of the cursor. + DEL = delete character to the left (configurable). + ^U = undelete a character. + ^T = delete word to right of cursor. + ^Y = delete current line. + + ^N = insert a carriage return (break line) at present + position. + ^V = toggle INSERT mode on and off. + ^^ = toggle case (upper/lower) of character at cursor. + ^P = insert following control code in text. + ^B = reformat current paragraph. + ^L (^\) = repeat find/replace (repeats last ^QF or ^QA + command). + +4.1.2. File and Block Commands: first hit ^K (or ESC), then the + key shown. + + ^K I = display file/memory Information message. + + ^K F = List files in disk directory. + ^K E = Erase a disk file. + + ^K L = Load a brand new file to begin editing. + ^K N = change the current file Name (affects Save, eXit). + ^K S = Save the current file to disk, and continue editing. + ^K D = Done. Save the file, then load a new one. + ^K X = eXit: Save the file, then Quit to CP/M. + ^K Q = Quit to CP/M, abandoning current file. + + ^K R = Read a disk file into text at cursor position. + ^K P = Print the text (whole file or block). + + ^K B = mark the start of a Block. + ^K K = mark the end of a block. + ^K U = Unmark the block. + ^K Y = Delete the marked block. + ^K C = Copy the block text at present cursor position. + ^K V = moVe the block text to the present cursor position. + ^K W = Write the marked block to a disk file. + +4.1.3. Escape and Macro Commands: first hit ESC, then the key + shown. + + ESC arrows: Left/Right (including ^S/D) = shift screen + horizontally + by 32 columns. + Up/Down (including ^E/X) = shift screen + vertically + by 1/4 screen. + ESC TAB = move back to last tab stop. + + ESC M = execute a Macro string of commands. + ESC # = store macro on numeric key for later recall. + ESC 0..9 = use stored key. (In macro mode: jump label.) + ESC !,=,~,+ = used in Macro programming (see below). + ESC ; = brief pause, during Macro execution only. + +4.1.4. Quick Commands: first hit ^Q, then the key shown. + + ^Q Arrows: Left/Right (including ^S/D) = go to start or end + of line. + Up/Down (including ^E/X) = go to top or bottom + of screen. + ^Q R = move to top of file. + ^Q C = move to end of file. + ^Q I = move to specified page or line number. + ^Q B = move to marked block. + ^Q Q = move to next line in queue (ZCPR only). + ^Q Z = move to next place marker. + + ^Q F = find next occurrence of a string. + ^Q A = find and replace a string. + + ^Q Y = delete from cursor to end of current line. + ^Q DEL = delete from cursor to beginning of current line. + ^Q T = delete until specified character (caution--powerful!). + ^Q U = undelete a line. + +4.1.5. Onscreen Commands: first hit ^O, then the key shown. + + ^O Arrow: Up (including ^E) = make current line top of + screen. + + ^O R = set right margin (column 1 turns off + wordwrap/formatting). + ^O L = set left margin. + ^O X = toggle Margin Release on/off. + ^O C = center current line. + ^O F = align current line flush with the right margin. + + ^O Q = toggle header on/off. + ^O T = toggle ruler line on/off. + ^O D = toggle display of hard CRs on/off. + + ^O A = toggle Auto Indent on/off. + ^O S = toggle Double Spacing on/off. + ^O H = toggle hyphenation on/off. + ^O V = toggle tab mode Hard/Variable. + ^O I = set variable tab stop. + ^O N = clear variable tab stop. + + ^O P = set page length (0 turns off pagination). + ^O W = toggle windowing on/off (see below). + ^O Z = temporarily blank the entire screen. + + +5. Command Descriptions. + +5.1. Auto-Indent Mode (^O-A). + + Auto-Indent is useful for typing outlines, structured program +source code, and other text where the "left margin" varies. +Auto-Indent causes the RETURN key to act differently: If you are +entering new text, it will be indented to match the previous line. +If you are just moving through the file, the cursor advances past +any existing indentation. + +5.2. Block Commands (^K-B, -K, -U, -R, -Y, -W, -C, -V, -P-B, + ^Q-B). + + A "block" of text is normally delimited by two markers +[default: ^@] which remain in memory until reset or deleted. + ^K-B marks the beginning of the block; ^K-K marks its end. +Markers are inserted in the text. The two markers are identical; +the first one present is the start. + ^K-U unmarks the block, removing any marker(s) set (block +markers can also be deleted individually as ordinary characters). +Markers are automatically removed as appropriate when ^K-B/-K are +used again. + ^K-R reads in the contents of a disk file, inserting it as a +block after the current cursor position. You will be asked for +the name (and, optionally, mode) of the file. Other block +operation commands all require a Block to be marked: + ^K-Y deletes the block (including markers). + ^K-W writes the block text to a disk file; you will be asked +for the filename (and optional mode). + ^K-V moves the Block text to the present cursor location, +deleting the original; ^K-C copies it and leaves the original. +Sometimes ZDE will run out of memory when moving blocks within a +large file. If this occurs, just write the block to a file, +delete it, and read it back in as: "^K-W, ^K-Y, ^K-R". + ^K-P-B (^K-P with B option) prints the block text only. + The ^Q-B command, from wherever you are in the file, moves +the cursor to the Block start. + +5.3. Cursor Movement (Arrow keys; ^F; ^A; ^Q-R, -C, -I). + + ZDE supports three sets of Arrow keys, which function +interchangeably. The two built-in sets support the WordStar +"arrow key diamond" ^E, ^X, ^D, ^S, and the ANSI standard 3-byte +sequences (ESC-[-A, etc.). The third set is user-configurable, +and must be installed with ZDENSTAL. These keys move the cursor +up, down, right, and left respectively. Note: if you install ^J, +^K, and ^L as arrow keys, you must use ESC- commands for help, +file operations, and repeat find/replace, respectively. + Preceded by ^Q-, any arrow key (except ANSI) moves more +quickly: to the top or bottom of the screen, to the left or right +end of the line. + There are also two word movement commands: ^F moves right, to +the start of the next word; ^A moves left, to the start of the +previous (or current) word. Both have maximum ranges of 255 +characters. + For quickly covering large distances, the commands ^Q-R and +^Q-C go all the way to the beginning and end of the file, +respectively, and ^Q-I goes to any specified page (or line, in +non-documents). + +5.4. Deleting (^G, DEL, ^T, ^Y, ^Q-Y, -DEL, -T). + + You can delete text one CHARACTER at a time: ^G deletes to +the right of the cursor, and DEL to the left. [If you have no DEL +key, you can install another equivalent.] Note that the ordinary +BS (^H) does not normally delete. + ^T deletes an entire WORD to the right (up to 255 characters) + ^Y deletes the entire current LINE. ^Q-Y deletes only the +part of the line to the right of the cursor; ^Q-DEL deletes the +part to the left. + ^Q-T deletes UP TO a specified character. Example: "^Q-T." +deletes to the end of the sentence. Special case: "^Q-T-CR" +deletes to the next HARD CR, the end of the paragraph. This is a +powerful command, so use it with caution. + Accidentally deleted text can usually be recovered (see +Undelete, below). + +5.5. Disk Operations (^K-F, -E). + + ^K-F gives an unsorted list of disk FILES: hit CR to list the +directory specified by the current file, or specify a drive, user, +or named directory (colon optional). If there is not enough room +to fit all the files on the screen, you will see "..." at the end +to indicate that there were still more. Press ESC or Space to +continue. + ^K-E will ERASE a single disk file to provide more room on +the disk (no wildcards allowed). + +5.6. File Commands (^K-N, -S, -X, -Q, -D, -L). + + ^K-N NAMES your work or changes the current file mode. You +can change the filename in the header before saving, and/or change +its mode to WordStar, ASCII, or Nondocument. To set the file +mode, introduce the mode character with the left square bracket, +e.g., "Name: MYFILE.WS [W". + ^K-S SAVES your work: what's in memory is written to disk +under the file name in the header (you must have a file name; one +will be requested if necessary). If that file already existed, a +backup (.BAK) file may be preserved [configurable; see +installation guide]. If you haven't changed the file, ZDE prompts +you to confirm that you want to resave it anyway. + There are several different commands for finishing up: + ^K-X saves your work and then EXITS to CP/M. + ^K-Q just QUITS. If the file has been modified, ZDE asks if +you want to abandon the changes. + ^K-D (DONE) saves your work, then loads a new file to edit. + ^K-L quits the current file and LOADS a new one to begin +editing. + +5.7. Find, Replace (^Q-F, -A, ^L, ^\). + + ^Q-F is the command to FIND a string. The search normally +proceeds from the cursor position forward, and is case +(upper/lower) insensitive. There are two options: "B" = search +backwards; "C" = case sensitive search. If used, the options +must be enclosed in slashes (eg, "/bc/") before the search string. +(If you want to search for a string beginning with a slash, use an +empty (//) option first.) In addition, a ^P-Z [this can be +reconfigured] functions as a wildcard matching any single +character. Other control codes, like ^M for newline, can be +included (with the ^P prefix where needed). Examples: + + Find: /c/^MLABEL matches "LABEL" at start of line only; + Find: 4^Z^Z01 matches "42201", "47401", etc; + Find: wordstar matches "WORDSTAR", "WordStar" etc; + Find: ///88 matches "/88"; + Find: /b/esc looks backwards for "Esc", "esc", etc. + + ^Q-A is the FIND/REPLACE command. It asks for a string to +find, and what to change it to (all options above apply to the +search string only). The cursor will be placed on each occurrence +of the string successively, starting at the cursor location. You +will see the prompt "Chg?" in the header. To replace the old +string with the new one, press "Y"; anything else skips to the +next. To change all further occurrences without being asked, +press "*". ESC cancels at any time. (Note: if ^Q-A is used in a +Macro, it will automatically assume "*" with no further input +required.) + ^L (or ^\, if ^L is an arrow key) repeats the last ^Q-F or +^Q-A command. For ^Q-A, you will be asked whether you want to +replace the found string. For both, direction and case options +remain unchanged. + +5.8. Header (^O-Q). + + ZDE normally gives you a header, or status line, at the top +of the screen. However, if you like you can toggle the header +display on and off with the ^O-Q (QUIET) command. [The header may +also be suppressed by default.] This lets you see more file text. +It can also speed up operation on some slower terminals, as the +position doesn't have to be continually updated. + + A typical header line looks something like: +------------------------------------------------------------------ +B0/WORK:ZDE.DOC [A Pg 8 Ln 31 Cl 53 INS vt hy AI DS MR ^Q_ +------------------------------------------------------------------ + "B0/WORK:ZDE.DOC [A" = Current directory, filename, and mode. + "Pg 8, etc" = Current position in file by page, line, column. +For "N"ondocuments, there is no page number display. If +pagination (^O-P) is off, you will see "Pg 0" (document) or "OP" +(nondocument) here. + "INS" = Insert mode on (^V). + "vt" = Variable tabs on (^O-V). + "hy" = Hyphenation enabled. (^O-H) Doesn't display in "N" + mode. + "AI" = Auto indent mode on (^O-A). + "DS" = Double spacing (^O-S). + "MR" = Margins released (^O-X). Doesn't display in "N" mode. + "^Q_": Prefix keys (and some prompts) display here. + +5.9. Information (^K-I). + + ^KI displays an Information message with: + + - the ZDE version and date; + - whether (Y/N) the file has been changed since last saved; + - the current size of the file in bytes; + - the number of bytes of text memory used and free (1024 + bytes = 1K). + + You will note that the file uses about 20-25% less memory +than its actual length; this is due to ZDE's compression of text. +(Note: ZDE is limited to 16-bit arithmetic. In the unlikely event +that file size should exceed 64K it will be shown mod 64K; just +add 65536.) + Block moves and copying are limited by the amount of free +memory. Further, when there is less than 1K free, response time +can get very slow. + +5.10. Insert Mode (^V). + + ^V toggles insertion on and off. If insert is OFF, any text +to the right of the cursor is overwritten as you type. If insert +is ON, what you type is inserted, and existing text moves to the +right. + +5.11. Line Spacing (^O-S). + + The ^O-S command toggles between single and double line +spacing. In double space mode, the following functions generate +double carriage returns: CR (^M), Insert CR (^N), Reform (^B), +Wordwrap. You can easily mix single and double spacing; the ^B +command can convert between the two. Note: if you prefer to keep +your actual file single spaced, you can still get a double-spaced +printout by using the "D" option of the ^K-P command (see +Printing). + +5.12. Margins (^O-R, -L, -X, -C, -F). + + ^O-R sets the RIGHT margin, enabling wordwrap, reformatting, +and centering. A right margin of 1 disables all formatting +functions (same as in "N"ondocument mode). At the prompt +"Column:" enter the column number (1-255), or just hit CR for the +current cursor column. If the value entered conflicts with the +current left margin, ZDE sets the left margin to 1. + ^O-L sets the LEFT margin in an identical fashion; of course, +the value must always be less than the current right margin, +meaning it's best to set the right margin first. + ^O-X temporarily RELEASES the margins (resets them to 1), +allowing you to type outside them. Use ^O-X again to restore the +margins. + ^O-C CENTERS the current line with respect to the margins, if +set. ^O-F sets the current line FLUSH right, if the right margin +is set. + +5.13. Pagination (^O-P). + + The ^O-P command sets the page length. Enter a value from 0 +to 255, or just hit CR to restore the default value [normally 54]. + When the value is nonzero, it determines the page and line +shown in the document header ("Pg xx Ln xx"), and page-oriented +Print functions (formfeeds, headers, start/stop print) are enabled. + When the value is zero, pagination is off. The header will +say "Pg 0 Ln xxxx", showing you the absolute line number in the +file. Also, printing occurs with no page breaks or formfeeds. +This can be useful for printing small things right after each +other on the same sheet; or, in conjunction with the "*" print +option, can be used to print out multiple copies of index cards, +labels, etc. + ZDE never sends a formfeed before printing; begin your file +with a ^P-L character if you need one. Otherwise, use of ^P-L is +not recommended in document files as it renders ZDE's page count +inaccurate. + +5.14. Place Markers and Line Queue (^P-Z, ^Q-Z, ^Q-Q). + + You can set any number of temporary PLACE MARKERS in the text +with ^P-Z (they will appear as ^Z). The ^Q-Z command moves the +cursor to the next place marker in the file, cycling back to the +top of the file if needed. Place markers are NOT saved to disk. + ZCPR users may also store a QUEUE of up to eight line numbers +in their user-defined messages (a set of sixteen bytes of +protected memory "available for user definition"). The ^Q-Q +command will then cycle through the queue of line numbers, +returning to the first location when it reaches a value of zero. +A value greater than the number of lines in the file takes the +cursor to the end of the file. The numbers are stored as two-byte +inverted hexadecimal words. This facility is intended as an +interface between other programs and ZDE for such purposes as +storing the locations of compiler errors, however ZCPR users may +also find it useful to POKE these locations directly before +invoking ZDE. + +5.15. Printer Codes (^P). + + Control codes for special effects in printing can be entered +in the text with the ^P prefix. Thus pressing ^P-^H (or ^P-H) +embeds a ^H, etc. Several standard codes are: + + ^H - backspace - overstrike previous character + ^I - hard (ASCII) tab - printers respond variously to this + ^L - formfeed (Not recommended unless pagination (^O-P) + disabled) + + The Block marker, normally ^@, cannot be embedded, and ^Z is +reserved for use as a place marker. Control codes display on +screen as capital letters, highlighted if possible. ZDE assumes +they are not characters, so they are not counted when reformatting +text. + For greater convenience, you can also arrange to have a +single ^P-code produce an entire string of bytes for commonly used +printing effects. ZDE supports a subset of WordStar's printer +installation, seven definable codes: four toggles, four switches. +The Printer Installation in ZDENSTAL allows you to choose what +codes you want to use, and install the actual control sequences +your printer needs. The defaults are: + + toggles: ^B, ^D, ^S, ^Y + switches: ^Q, ^W, ^E, ^R + + In WordStar these toggles are Boldface, Doublestrike, +Underline, and Ribbon/Italic respectively, but you can make them +anything you like. "Toggles" are good for features like underline +and bold that are turned on and off. "Switches" are better for +multivalued parameters like character pitch. + Example: your printer uses ESC-U-01 (and 00) to turn +underlining on (and off). If you install these codes with +ZDENSTAL: + ^S toggle on: (03)1B5501 + ...and off: (03)1B5500 + +then all you have to type in ZDE to get underlined text is: +^PSunderlined text^PS. + +5.16. Printing (^K-P). + + The ^K-P command PRINTS all or part of the file in memory. +You will be asked for a set of "Options:", at which point you may +enter zero or more of the following, in any order: + + B prints only the currently marked BLOCK. + P PAUSES for your keystroke before each page (sheet + feed). + D DOUBLE SPACES all text to be printed. + Lnn sets the printer LEFT MARGIN to nn columns [the + default value can be set with ZDENSTAL]. + ^ FILTERS control characters ^X to text "^X". + *nn prints the job out nn TIMES (nn=1..255). + @nn begins printing AT the nn'th page. + =nn renumbers the pages beginning with nn. + #nn prints only (up to) a TOTAL of nn pages. + "..." uses the quoted string as a HEADER. The string, + followed immediately by the page number, will print + at the top right of each page near the margin (maxi- + mum length is 50 characters; an empty string, "", + gives numbered pages with no header text.) + +The last four options (@,=,#,"") are NOT allowed if pagination is +disabled (^O-P), or if "B"lock print was chosen. Examples: + +Options: L12P + - Print the file with a left margin of 12 columns, pausing + before each page for you to press a key (other than Esc). + +Options: @6#2=14"Instructions, page " + - Print the sixth and seventh pages of the file, but numbered + 14 and 15, with the header shown. + +Options: BD^*2 + - Print out the current marked Block twice, double spaced, + with control filtering. + + In "W" mode, lines beginning with a "." will be regarded as +WordStar dot commands, and will neither print out nor affect the +page count (they have no other effect either). + You can abort printing at any time with ESC (this may take a +moment, or a few keystrokes, depending on your BIOS). + +5.17. Ruler Line (^O-T). + + To help you align text properly, ^O-T toggles display of a +"ruler line" above the text on and off. + In each column you will see one of several symbols: "[]" +designate the current margins (if set); "-" indicates areas within +the current margins, "." outside them. Also, tab stops are marked +by either "T" (Variable) or "I" (Hard). Examples: + +("A" mode) [-----T-----T-----------T--------------]........ +("N" mode) I.......I.......I.......I.......I.......I....... + +5.18. Tabs (^I, ESC-TAB, ^O-V, ^O-I, ^O-N). + + There are two Tab modes: Variable and Hard, and the ^O-V +command toggles between them. In Hard Tab mode the Tab key +produces an actual ^I (ASCII 09); whether this overwrites any +existing text depends on the Insert toggle. Hard Tabs display by +default at fixed intervals of 8 screen columns [this is +configurable to any multiple of 2]. + In Variable Tab mode, the Tab key moves the cursor to the +next variable tab stop (you can always get a Hard Tab by typing +^P-I). If Insert is on, spaces are inserted up to the next tab +stop. Otherwise, existing text is skipped over, but spaces are +still added at the end of a line as needed. Up to eight tab stops +may be set with ^O-I and cleared with ^O-N; the defaults are in +columns 6, 11, 16, and 21 [these are configurable]. At the +prompt, enter the column number desired, or hit RETURN for the +cursor column. + The ^O-I command also accepts two multiple-set inputs: "@nn" +sets tab stops every "nn" columns, while "#n1,n2,..." sets tabs at +columns "n1,n2, ...". Both remove any pre-existing tabs, and +typing "@" or "#" alone simply clears all tabs. + The ESC-TAB command moves backward (left) to the previous +variable or hard tab stop. + +5.19. Undelete (^U, ^Q-U). + + The undelete functions may be used (repeatedly if necessary) +to recover a reasonable amount of text deleted either by +overtyping, or with any of ZDE's delete commands, IF the cursor +has not yet been moved away. ^U undeletes one character; ^Q-U +does a whole line. + Restrictions: undelete may not recover all of a Block delete +unless the cursor was in or near the block deleted, and it may +work imperfectly if DEL has been used several times in sequence. + Further use after all deleted text is recovered will produce +junk (usually duplicates of text above the cursor, which is +sometimes useful). + +5.20. Upper/Lower Case (^^). + + The ^^ (ctl-caret) command changes the case of the character +at the cursor, if it was a letter, and moves the cursor one +character to the right. Useful for capitalizing a string of +lowercase text, or vice versa. + +5.21. Window and Screen (^W, ^Z, ESC-Arrows, ^O-Up, -W, -Z). + + ZDE supports several functions to move and alter the display +screen. + The ^W and ^Z commands scroll the screen up and down a line +at a time, without moving the cursor (unless necessary). + Preceded by ESC, any arrow (except ANSI) moves the screen +rather than the cursor: the text as a whole shifts up/down 1/4 +screen, or right/left 32 columns, while the cursor stays put (the +cursor must be past column 32 for horizontal shifts to work). + Preceded by ^O-, any UP arrow key (except ANSI) makes the +current text line the top of the screen. + The ^O-W command creates a WINDOW in the bottom half of the +screen, which retains a copy of the file text starting at the +current line, plus the current status and/or ruler line(s), if +any. Editing continues normally in the top half of the screen. +This is useful for comparing different sections of text within a +file, or even between different files. Typing ^O-W again removes +the Window. Note: Windowing is only supported for screens of 15 +or more lines. + The ^O-Z command temporarily zaps (blanks) the entire screen; +good for avoiding CRT burn-in, or just protecting work from prying +eyes or fingers. Restore the screen by pressing ESC or SPACE. +Note: if Windowing was in effect, any text in the window will be +lost. + +5.22. Wordwrap, Reformat (^B, ^O-D). + + WORDWRAP is automatic in Document ("W" or "A") modes whenever +the right margin is set. Any text entered will be formatted to +the current margin settings as you type. The end of a paragraph +is marked by a "HARD CR", which occurs when you press the RETURN +key (this is a CR immediately following a character of text). In +contrast, when wordwrap occurs you get a "SOFT CR" (which is +actually a CR with a space before it). You can change a hard CR +into a soft one, or vice versa, by deleting or adding a space at +the end of the line. Hitting RETURN also hardens a soft CR. The +distinction between hard and soft CRs is only important when +reformatting. + ^B REFORMATS from the line the cursor is on, to the end of +the paragraph, according to the current margin settings and line +spacing. ^B may be used not only to reshape a paragraph after +editing, but also to change its margins and line spacing. +Indentation can be tricky if you have a left margin set. If the +current line is indented relative to the next one, ZDE assumes +that amount as your paragraph indentation. + ^O-D toggles DISPLAY OF HARD CRs. Hard CRs, otherwise +invisible, can be caused to display as a "<" character. This can +be useful; some may find it distracting, so it turns off. + + +6. Macros. + +6.1. Macro (ESC-M). + + A MACRO is a string of ZDE commands and text that, once +defined, can be repeated automatically. When you type ESC-M you +will be asked for the string, then a "Repeat count". Usually you +will simply type a number for the repeat count (0-9, or "*" for +"indefinitely"). You will see the results as the macro executes, +and you can abort it at any time by pressing ESC. If you are sure +you know what you're doing, you can speed up Macro execution by +specifying "Quiet" mode: press "Q" before the repeat count. Only +the header, if present, will be updated as the Macro runs. + Macros also stop any time an error occurs; the error message +will be visible, and can be cleared by pressing ESC. Many +commands (like Find or Reformat) are designed to generate errors +at the end of the file so that indefinite ("*") Macros containing +them halt there. You may need to abort other indefinite Macros +manually. + ZDE turns INSERT OFF before running a macro, so that the same +key sequence will always have the same effect. INSERT status is +restored when the macro terminates. + In order to include any input line editing characters (BS, +CR, etc.) in a macro, you must prefix them with ^P. (NOTE: To +make them easier to read and understand, Macro listings are given +here as they function, not as they are typed in. ^P prefixes as +needed are NOT shown. Keystrokes are separated by dashes or +commas for clarity, and "_" means a space or blank.) Here are some +sample Macros: + + 1. View a file by scrolling slowly through it: + + ESC-;, ^C + + This will pause, then scroll down. (Use a repeat count + of "*".) + + 2. Can you figure out what this one does? + + ^QR, ^QF, (, CR, ^G, ^KB, ^QF, ), CR, ^G, ^KK, ^QC, CR, ^KV + + (Answer: .elif eht fo dne eht ta meht fo tsil a gnikam + elif a fo tuo sesehtnerap ni stnemmoc ekat lliw tI) + + ZDE Macros are very powerful tools, particularly given their +programmability and storage on function keys. + +6.2. Macro Key (ESC-#, ESC-0..9). + + Up to 10 MACRO KEYS can be stored (0..9), by entering them +with the ESC-M command, then using ESC-# to save them. They can +then be recalled and used simply by typing ESC-number. Example: +typing ESC-#-0 will store the last Macro used in the ESC-0 command +so that it can be recalled and reused at any future time simply by +typing ESC-0. + Ordinarily, Macro Keys operate just like the original Macro, +asking for a "Repeat count" when executed. If you want to +suppress this prompt (resulting in a "function key" that executes +just once) you can type "N" (for No repeat) before storing the key +number. Example: ESC-#-N-0 makes ESC-0 a no-repeat macro key. +If you also don't need to see the Macro work, and want to make it +faster, you can make it QUIET as well by typing "Q" instead (for +Quiet) before the key number. Example: ESC-#-Q-0 stores ESC-0 as +a quiet no-repeat key sequence. + If the Macro (ESC-M) string is empty, using ESC-# will delete +a Macro Key. Using a defined Key makes it the last macro used, so +it can be stored again in another key if desired. Trying to use +an undefined Macro Key results in an error. + There are 500 bytes total available for all 10 keys, and a +128 byte limit for any one Key (ZDE's own input line will only +accept 65 bytes, but ZDENSTAL can handle up to the full 128.) + USAGE HINT: If you want to re-use a macro without having to +type it in again, use ESC-# to assign it to a key, then call it up +by number. + Besides simply storing Macros, here are some useful Macro +Keys: + + 1. Storing different sets of margins (e.g., for quotes). + For example, + ^OL, 12, CR, ^OR, 66, CR + + 2. Typing any frequently repeated phrase; "ESC-6" is much + more convenient than "^PSWorld Wide Widgets Ltd. (N.A.)^PS". + + 3. Swap the two characters preceding the cursor: + ^S, ^S, ^G, ^D, ^U, ^U, ^D, ^G + +[ZDENSTAL allows you to install defaults for all ten Macro Keys. +Thus a copy of ZDE can be customized for any task, such as the +formatting requirements of specialized writing or programming +languages.] + +6.3. Macro Programming (ESC-0..9, ESC-!,=,~,+,;). + + ZDE has several commands which function only in a Macro +string, and give you control over the execution of a macro, +allowing true programming. + ESC-0..9 function as LABELS 0..9 when entered as part of a +Macro. They have no effect, but can be "jumped" to by other +commands. + ESC-! followed by 0..9 is a JUMP instruction, and causes +macro execution to resume with the command following the label +ESC-0..9. Example: ESC!2 jumps to label 2. As two special cases, +ESC-![ jumps to the beginning of the Macro, and ESC-!] jumps to +the end (aborts). + ESC-= and ESC-~, followed by a character and then a label +0..9 (or "[","]"), are CONDITIONAL JUMPS: they jump to the label +or the start or end of the macro IF the character at the cursor +position matches (ESC-=) or doesn't match (ESC-~) the character +specified. Example: ESC~^M2 jumps to ESC-2 if the current +character is NOT a CR. + ESC-= and ESC-~, followed by a character and then ">" or "<", +are SEARCH LOOPS. They will continue to move the cursor right +(">") or left ("<") AS LONG AS the character at the cursor matches +(ESC-=) or doesn't match (ESC-~) the specified character. Both +search loops terminate automatically at the beginning or end of +the file. Example: ESC=_> moves right as long as the current +character is a space. + ESC-+, followed by 0..9, CHAINS to another macro key, +allowing you to build macros strings longer than the storage limit +of any one key. It does not "call" the key; there is no +returning. Example: ESC+9 chains to Key 9. + ESC-; (semicolon) gives a brief pause, presumably so the user +can see what's happening on screen. + Macro programs are stored just like any other macro string +(usually with "N"o repeat count). If you program in an endless +loop, you will at some point have to abort with ESC. Don't make +macro programs "Q"uiet until you're sure they work. + Example: here is a good macro program (best stored as a Quiet +Key) to move the cursor to the start of the current sentence: + + ESC~.1, ^S, ESC1, ESC~.<, ESC2, ^D, ESC=_2, ESC=^M2 + +You could write this out in programmer's pseudo-code as: + + If not "." goto label1 + Move left ;move left if already on period +label1: While not "." move Left ;move left to previous period +label2: Move right ;now move back right + If " " goto label2 ; as long as you see a space + If "^M" goto label2 ; or a Return + (all done) + + +7. General Information. + +7.1. Disk Space. + + ZDE isn't disk-bound; if you run out of disk space, just +insert another disk (always keep a blank FORMATTED disk around). +Alternatively, you can use the ESC-F and ESC-E commands to purge +unneeded files. [If you have small disks, you can also install +ZDE not to preserve BAK files.] + Let ZDE's filesize limits encourage you to break work up into +files of 50K or less; larger files make inefficient use of floppy +disks. + +7.2. Error Messages. + + Press ESC or Space to continue. "Error" alone means the +command used just won't work in this situation. (Example: a block +command was used with no block marked.) More specific errors are: + + "Out of Memory" - the file, block, or key string won't fit in + RAM. + "Invalid Key" - an illegal command key sequence was pressed. + "I/O Error" - file not found, disk full, empty/invalid + drive, etc. +"Cannot Reformat" - word too long, or margins invalid. + "Not Found" - the object of a search was not found. + "Syntax Error" - a macro programming command was misused. + +7.3. File Modes. + + ZDE has three FILE MODES: "W"ordStar document, "A"SCII +document, and "N"on-document. The basic difference concerns the +format of disk files. + In "W" mode, ZDE reads and writes WordStar-compatible files. +ZDE can edit a WordStar document, except that any right +justification will be lost. WordStar can edit any ZDE "W" file in +Document mode. + In "A" or "N" mode, ZDE reads and writes text as standard +ASCII 7-bit characters, a universal format accepted by virtually +all software. The only difference between "A" and "N" modes lies +in the default settings on loading a new file. Typically "A" mode +is used for word processing, and "N" mode for programming and +other technical applications. + +DEFAULTS FOR: Margins Tabs Hard CR disp. +------------ ------- ---- ------------ +"A"SCII or "W"ordStar mode ACTIVE VARIABLE [ON] +"N"on-document DISABLED HARD OFF + + The file mode option can be specified along with the filename +at any ZDE file function prompt, allowing you to mix WordStar and +ASCII disk files as needed (see Invoking ZDE, above). You can +also change the current mode with the ^K-N function by entering a +new mode (e.g., "[W") with or without a filename. + [ZDENSTAL allows you to select a default file mode, to be +used when no mode is specified (originally this is "A"). Further, +you can specify two filetype masks for automatic mode selection +(e.g., all "ASM" files as "N" mode) to override that default.] + NOTE ON ASCII FILES - The "A"SCII-document file format used +since VDE 2.50, to allow accurate formatting and WordStar +compatibility, distinguishes between HARD and SOFT CRs (see +Wordwrap, above). Consequently, if you edit an ASCII file created +by other software (including earlier versions of VDE), it may +appear to be full of hard CRs, making text impossible to reformat. +There are two easy ways to solve this problem: first, you can use +^Q-A to find "^M"s and selectively replace them with " ^M". +Alternatively, the following Macro (best stored as a Quiet macro +Key) does a good job of "softening up" paragraphs for reformatting: + + ^QS,^X,ESC=_],ESC=CR],^S,^V_^V,^D,ESC![ + +7.4. Hyphenation (^O-H). + + ZDE can't introduce hyphens, but it does recognize them in +the text, treating them as a legitimate place to break a line, so +if you have a long word close to the margin, you can insert a +hyphen where you'd like the word to be broken. + Similarly, ZDE can't unhyphenate. If it is trying to +reformat and finds a hyphen at the end of a line, it will pause to +ask you what to do with it. You will see the prompt "Chg?" in the +header, and can: + Press "Y" to remove the hyphen and space, joining the word; + "N" to leave the hyphen, but still join the word; + "ESC" to leave both the hyphen and the space alone. +Typically you would choose "Y" for "soft" hyphens that you +introduced to break up a word ("intro-duction"); "N" for hard +hyphens that are part of a word ("vis-a-vis"); and "ESC" for +punctuation (dashes "--", etc.). After your choice, reformatting +will proceed automatically. + You can toggle hyphenation on and off with ^O-H. If off, +hyphens are not treated differently from any other text character. +[The ^O-H default can be changed with ZDENSTAL.] + +7.5. Interruption. + + If ZDE is interrupted by messages from other software (BIOS +error, resident utilities, etc.), it may lose control of the +screen. The best way to return it to normal is by blanking and +restoring the screen (^O-Z, ESC). + +7.6. Prompts. + + First, ZDE has several simple prompts requiring you to +confirm an action by typing "Y" or "N": + + "Abandon changes?" - warns the file you want to Quit has + been changed. +"Unchanged; save anyway?" - reminds the file you want saved isn't + changed. + "Delete original?" - do you want to delete block copied + from 2nd file? + "Chg?" - do you want to change this instance of + a string? + +Then, there are a few special purpose prompts: + + "Repeat count:" - enter (optional "Q" and) repeat count + for Macro. + "Key number:" - enter (optional "N/Q" and) key number + for Key. + "Rdy" - press any key to print next page (ESC + quits). + +Finally, there are a variety of prompts for either numeric or +string input, like "Column:" or "Find string:". You are expected +to type in a string (up to 65 characters). The following control +keys operate: + + Correct mistake: BS (^H), ^S, or Del + Erase entire entry: ^X + Abort operation: ^U + +Note that to get any of these codes, or a CR, into the string +itself, you must precede it with ^P (this includes ^P). Examples: +to find a line beginning with a "*" (find "^M,*") type + + ^Q-F, ^P-CR, *, CR. + +Now to get this into a Macro with ESC-M, you would have to type + + ESC-M, ^Q-F, ^P-P, ^P-CR, *, ^P-CR, CR. + +7.7. WordStar Compatibility. + + In most respects ZDE operates much like WordStar; one big +difference is the absence of a "No-File" menu. You are always in +edit mode; use ^K-L to select a new file to edit. + If the keys ^J, ^K, ^L are in use as CP/M arrow keys, you +must use ZDE's original command set to substitute for them as +follows: + + Block prefix (^K-)... ESC- + Help menu (^J)....... ESC-H + Repeat find (^L)..... ^\ + + If these keys are NOT installed as arrow keys, they retain +their WordStar functions. Then, of course, ZDE lacks some +WordStar commands, and has some of its own. Aside from these, +there are the following differences in common commands: + +COMMON USE WORDSTAR 4 ZDE ZDE NOTES +Hide block ^K-H ^K-U Actually unmarks block. +Erase disk file ^K-J ^K-E +Set Place Mark ^K-0..9 ^P-Z Not individually numbered. +Go to Place Mark ^Q-0..9 ^Q-P Cyclic. + +COMMON COMMAND WORDSTAR 4 USE ZDE USE + ^^ Soften hard CR Transpose upper/lowercase + ^K-N Column block mode Rename current work + ^O-D Display ^P codes Display hard CRs + ^O-F Ruler from text Flush right + ^O-P Preview mode Page length + ^Q-U Repeat align Repeat undelete + +Note that ZDE does not implement WordStar "dot commands" in text, +though in "W" mode it avoids printing them. + + +8. Disclaimer. + + You use ZDE at your own risk. The author accepts no +liability for any damages resulting from its use or misuse. +Direct problem reports and suggestions to the author; include a +stamped return envelope for a reply if desired. Thanks to the +many users of ZDE whose feedback has led to improvements and bug +fixes in the past. + + Carson Wilson Sysop: Antelope Freeway RAS + 1359 W. Greenleaf 312-764-5162, Chicago + Chicago, IL 60626 24 hours, 3-12-2400 baud diff --git a/Source/Images/Makefile b/Source/Images/Makefile index 444293d6..bda9e88b 100644 --- a/Source/Images/Makefile +++ b/Source/Images/Makefile @@ -3,7 +3,8 @@ # SYSTEMS = ../CPM22/cpm_wbw.sys ../ZSDOS/zsys_wbw.sys ../CPM3/cpmldr.sys ../ZPM3/zpmldr.sys -FDIMGS = fd144_cpm22.img fd144_zsdos.img fd144_ws4.img +FDIMGS = fd144_cpm22.img fd144_zsdos.img fd144_nzcom.img \ + fd144_cpm3.img fd144_zpm3.img fd144_ws4.img HD512IMGS = hd512_cpm22.img hd512_zsdos.img hd512_nzcom.img \ hd512_cpm3.img hd512_zpm3.img hd512_ws4.img # HDIMGS += hd512_bp.img @@ -42,7 +43,7 @@ hd1024_combo.img: $(HD1024PREFIX) $(HD1024IMGS) # at build time, a few variables are set (sys, fmt, type, size, d) based on the # target to build. first, we build an empty image using the a tr, dd pipeline. # we then scan the d_{d}/u* directories, copying in files to user numbers -# then process the d_{d}.txt file, copying in those files, and finally maybe put +# then process the ?d_{d}.txt file, copying in those files, and finally maybe put # an OS at the start of each image # @@ -75,13 +76,13 @@ blankhd1024: (*zpm3*) sys=../ZPM3/zpmldr.sys;; \ esac ; \ if echo $@ | grep -q ^fd144_ ; then \ - fmt=wbw_fd144 ; type=fd144_ ; proto=blank144 ; \ + fmt=wbw_fd144 ; dtype=fd ; type=fd144_ ; proto=blank144 ; \ fi ; \ if echo $@ | grep -q ^hd512_ ; then \ - fmt=wbw_hd512 ; type=hd512_ ; proto=blankhd512 ; \ + fmt=wbw_hd512 ; dtype=hd ; type=hd512_ ; proto=blankhd512 ; \ fi ; \ if echo $@ | grep -q ^hd1024_ ; then \ - fmt=wbw_hd1024 ; type=hd1024_ ; proto=blankhd1024 ; \ + fmt=wbw_hd1024 ; dtype=hd ; type=hd1024_ ; proto=blankhd1024 ; \ fi ; \ d=$$(echo $(basename $@) | sed s/$$type//) ; \ echo Generating $@ ; \ @@ -101,9 +102,10 @@ blankhd1024: done ; \ fi ; \ done ; \ - if [ -f d_$$d.txt ] ; then \ - echo " " copying files from d_$$d.txt ; \ - grep -v ^# d_$$d.txt | tr -d '\r' | while read file user ; do \ + echo $${dtype}_$$d.txt ; \ + if [ -f $${dtype}_$$d.txt ] ; then \ + echo " " copying files from $${dtype}_$$d.txt ; \ + grep -v ^# $${dtype}_$$d.txt | tr -d '\r' | while read file user ; do \ rf=$$($(CASEFN) $$file | sort -V) ; \ echo " " $$rf ; \ if [ -z "$$rf" ] ; then \ diff --git a/Source/Images/ReadMe.txt b/Source/Images/ReadMe.txt index 3954af2f..29e4a583 100644 --- a/Source/Images/ReadMe.txt +++ b/Source/Images/ReadMe.txt @@ -98,11 +98,12 @@ command prompt and navigate to the Images directory. Use the command "Build" to build both the floppy and hard disk images in one run. You can build a single disk image by running BuildDisk.cmd: - BuildDisk [] + BuildDisk [] where: specifies the disk contents (e.g., "cpm22") + specifies disk type ("fd" for floppy, or "hd" for hard disk) specifies the disk format which must be one of: - "fd144": 1.44M floppy disk - "hd512": hard disk with 512 directory entries @@ -112,7 +113,7 @@ where: For example: - | BuildDisk.cmd cpm22 wbw_hd512 ..\cpm22\cpm_wbw.sys + | BuildDisk.cmd cpm22 hd wbw_hd512 ..\cpm22\cpm_wbw.sys will create a hard disk image (512 directory entry format) with the CP/M 2.2 files from the d_cpm22 directory tree and will place the diff --git a/Source/Images/fd_bp.txt b/Source/Images/fd_bp.txt new file mode 100644 index 00000000..88605d3f --- /dev/null +++ b/Source/Images/fd_bp.txt @@ -0,0 +1,51 @@ +# +# Add ZSystem images +# +../BPBIOS/*.img 0: +../BPBIOS/*.rel 0: +../BPBIOS/*.zrl 0: +../BPBIOS/*.zex 0: +../BPBIOS/bpbuild.com 0: +# +# Add RomWBW utilities +# +#../../Binary/Apps/*.com 15: +../../Binary/Apps/assign.com 15: +../../Binary/Apps/fat.com 15: +../../Binary/Apps/fdu.com 15: +../../Binary/Apps/fdu.doc 15: +../../Binary/Apps/format.com 15: +../../Binary/Apps/mode.com 15: +../../Binary/Apps/rtc.com 15: +../../Binary/Apps/survey.com 15: +../../Binary/Apps/syscopy.com 15: +../../Binary/Apps/sysgen.com 15: +../../Binary/Apps/talk.com 15: +../../Binary/Apps/tbasic.com 15: +../../Binary/Apps/timer.com 15: +../../Binary/Apps/tune.com 15: +../../Binary/Apps/xm.com 15: +../../Binary/Apps/zmp.com 15: +../../Binary/Apps/zmp.hlp 15: +../../Binary/Apps/zmp.doc 15: +../../Binary/Apps/zmxfer.ovr 15: +../../Binary/Apps/zmterm.ovr 15: +../../Binary/Apps/zminit.ovr 15: +../../Binary/Apps/zmconfig.ovr 15: +../../Binary/Apps/zmd.com 15: +# +# Add Tune sample files +# +../../Binary/Apps/Tunes/*.pt? 3: +../../Binary/Apps/Tunes/*.mym 3: +# +# Add Common Applications +# +Common/All/*.* 15: +Common/CPM22/*.* 15: +#Common/Z/u10/*.* 10: +Common/Z/u14/*.* 14: +Common/Z/u15/*.* 15: +Common/Z3/u10/*.* 10: +Common/Z3/u14/*.* 14: +Common/Z3/u15/*.* 15: diff --git a/Source/Images/fd_cpm22.txt b/Source/Images/fd_cpm22.txt new file mode 100644 index 00000000..44a39734 --- /dev/null +++ b/Source/Images/fd_cpm22.txt @@ -0,0 +1,45 @@ +# +# Add the ReadMe document +# +d_cpm22/ReadMe.txt 0: +# +# Add RomWBW utilities +# +#../../Binary/Apps/*.com 0: +../../Binary/Apps/assign.com 0: +../../Binary/Apps/fat.com 0: +../../Binary/Apps/fdu.com 0: +../../Binary/Apps/fdu.doc 0: +../../Binary/Apps/format.com 0: +../../Binary/Apps/mode.com 0: +../../Binary/Apps/rtc.com 0: +../../Binary/Apps/survey.com 0: +../../Binary/Apps/syscopy.com 0: +../../Binary/Apps/sysgen.com 0: +../../Binary/Apps/talk.com 0: +../../Binary/Apps/tbasic.com 0: +../../Binary/Apps/timer.com 0: +../../Binary/Apps/tune.com 0: +../../Binary/Apps/xm.com 0: +../../Binary/Apps/zmp.com 0: +../../Binary/Apps/zmp.hlp 0: +../../Binary/Apps/zmp.doc 0: +../../Binary/Apps/zmxfer.ovr 0: +../../Binary/Apps/zmterm.ovr 0: +../../Binary/Apps/zminit.ovr 0: +../../Binary/Apps/zmconfig.ovr 0: +../../Binary/Apps/zmd.com 0: +# +# Add Tune sample files +# +../../Binary/Apps/Tunes/*.pt? 3: +../../Binary/Apps/Tunes/*.mym 3: +# +# Add OS image +# +../CPM22/cpm_wbw.sys 0:cpm.sys +# +# Add Common Applications +# +Common/All/*.* 0: +Common/CPM22/*.* 0: diff --git a/Source/Images/fd_cpm3.txt b/Source/Images/fd_cpm3.txt new file mode 100644 index 00000000..f324e5a9 --- /dev/null +++ b/Source/Images/fd_cpm3.txt @@ -0,0 +1,52 @@ +# +# Add files from CPM3 build +# +../CPM3/cpmldr.com 0: +../CPM3/cpmldr.sys 0: +../CPM3/ccp.com 0: +../CPM3/gencpm.com 0: +../CPM3/genres.dat 0: +../CPM3/genbnk.dat 0: +../CPM3/bios3.spr 0: +../CPM3/bnkbios3.spr 0: +../CPM3/bdos3.spr 0: +../CPM3/bnkbdos3.spr 0: +../CPM3/resbdos3.spr 0: +../CPM3/cpm3res.sys 0: +../CPM3/cpm3bnk.sys 0: +../CPM3/gencpm.dat 0: +../CPM3/cpm3.sys 0: +../CPM3/readme.1st 0: +../CPM3/cpm3fix.pat 0: +# +# Add RomWBW utilities +# +#../../Binary/Apps/*.com 0: +../../Binary/Apps/assign.com 0: +../../Binary/Apps/fat.com 0: +../../Binary/Apps/fdu.com 0: +../../Binary/Apps/fdu.doc 0: +../../Binary/Apps/format.com 0: +../../Binary/Apps/mode.com 0: +../../Binary/Apps/rtc.com 0: +../../Binary/Apps/survey.com 0: +../../Binary/Apps/syscopy.com 0: +#../../Binary/Apps/sysgen.com 0: +#../../Binary/Apps/talk.com 0: +../../Binary/Apps/tbasic.com 0: +../../Binary/Apps/timer.com 0: +../../Binary/Apps/tune.com 0: +../../Binary/Apps/xm.com 0: +../../Binary/Apps/zmp.com 0: +../../Binary/Apps/zmp.hlp 0: +../../Binary/Apps/zmp.doc 0: +../../Binary/Apps/zmxfer.ovr 0: +../../Binary/Apps/zmterm.ovr 0: +../../Binary/Apps/zminit.ovr 0: +../../Binary/Apps/zmconfig.ovr 0: +../../Binary/Apps/zmd.com 0: +# +# Add Common Applications +# +Common/All/*.* 0: +Common/CPM3/*.* 0: diff --git a/Source/Images/fd_nzcom.txt b/Source/Images/fd_nzcom.txt new file mode 100644 index 00000000..5a4dfb46 --- /dev/null +++ b/Source/Images/fd_nzcom.txt @@ -0,0 +1,31 @@ +# +# Add the ReadMe document +# +d_nzcom/ReadMe.txt 0: +# +# Add RomWBW utilities +# +#../../Binary/Apps/*.com 0: +../../Binary/Apps/assign.com 0: +../../Binary/Apps/fat.com 0: +../../Binary/Apps/fdu.com 0: +../../Binary/Apps/rtc.com 0: +../../Binary/Apps/syscopy.com 0: +../../Binary/Apps/talk.com 0: +../../Binary/Apps/timer.com 0: +../../Binary/Apps/xm.com 0: +# +# Add OS images +# +../ZSDOS/zsys_wbw.sys 0:zsys.sys +# +# Add Common Applications +# +Common/All/*.* 0: +Common/CPM22/*.* 0: +#Common/Z/u10/*.* 0: +Common/Z/u14/*.* 0: +Common/Z/u15/*.* 0: +Common/Z3/u10/*.* 0: +Common/Z3/u14/*.* 0: +Common/Z3/u15/*.* 0: diff --git a/Source/Images/fd_zpm3.txt b/Source/Images/fd_zpm3.txt new file mode 100644 index 00000000..dcec6bfa --- /dev/null +++ b/Source/Images/fd_zpm3.txt @@ -0,0 +1,49 @@ +# +# Add files from ZPM3 build +# +../ZPM3/zpmldr.com 0: +../ZPM3/zpmldr.sys 0: +../CPM3/cpmldr.com 0: +../CPM3/cpmldr.sys 0: +../ZPM3/autotog.com 15: +../ZPM3/clrhist.com 15: +../ZPM3/setz3.com 15: +../ZPM3/cpm3.sys 0: +../ZPM3/zccp.com 0: +../ZPM3/zinstal.zpm 0: +../ZPM3/startzpm.com 0: +../ZPM3/makedos.com 0: +../ZPM3/gencpm.dat 0: +../ZPM3/bnkbios3.spr 0: +../ZPM3/bnkbdos3.spr 0: +../ZPM3/resbdos3.spr 0: +# +# Add RomWBW utilities +# +#../../Binary/Apps/*.com 15: +../../Binary/Apps/assign.com 15: +../../Binary/Apps/fat.com 15: +../../Binary/Apps/fdu.com 15: +../../Binary/Apps/fdu.doc 15: +../../Binary/Apps/format.com 15: +../../Binary/Apps/mode.com 15: +../../Binary/Apps/rtc.com 15: +../../Binary/Apps/survey.com 15: +../../Binary/Apps/syscopy.com 15: +../../Binary/Apps/sysgen.com 15: +../../Binary/Apps/talk.com 15: +../../Binary/Apps/tbasic.com 15: +../../Binary/Apps/timer.com 15: +../../Binary/Apps/tune.com 15: +../../Binary/Apps/xm.com 15: +# +# Add Common Applications +# +Common/All/*.* 15: +Common/CPM3/*.* 15: +#Common/Z/u10/*.* 10: +Common/Z/u14/*.* 14: +Common/Z/u15/*.* 15: +Common/Z3/u10/*.* 10: +Common/Z3/u14/*.* 14: +Common/Z3/u15/*.* 15: diff --git a/Source/Images/fd_zsdos.txt b/Source/Images/fd_zsdos.txt new file mode 100644 index 00000000..09af8c9f --- /dev/null +++ b/Source/Images/fd_zsdos.txt @@ -0,0 +1,61 @@ +# +# Add the ReadMe document +# +d_zsdos/ReadMe.txt 0: +# +# Include selected CP/M 2.2 files +# +d_cpm22/u0/ASM.COM 0: +d_cpm22/u0/LIB.COM 0: +d_cpm22/u0/LINK.COM 0: +d_cpm22/u0/LOAD.COM 0: +d_cpm22/u0/MAC.COM 0: +#d_cpm22/u0/PIP.COM 0: ??? +d_cpm22/u0/RMAC.COM 0: +d_cpm22/u0/STAT.COM 0: +d_cpm22/u0/SUBMIT.COM 0: +d_cpm22/u0/XSUB.COM 0: +# +# Add RomWBW utilities +# +#../../Binary/Apps/*.com 0: +../../Binary/Apps/assign.com 0: +../../Binary/Apps/fat.com 0: +../../Binary/Apps/fdu.com 0: +../../Binary/Apps/fdu.doc 0: +../../Binary/Apps/format.com 0: +../../Binary/Apps/mode.com 0: +../../Binary/Apps/rtc.com 0: +../../Binary/Apps/survey.com 0: +../../Binary/Apps/syscopy.com 0: +../../Binary/Apps/sysgen.com 0: +../../Binary/Apps/talk.com 0: +../../Binary/Apps/tbasic.com 0: +../../Binary/Apps/timer.com 0: +../../Binary/Apps/tune.com 0: +../../Binary/Apps/xm.com 0: +../../Binary/Apps/zmp.com 0: +../../Binary/Apps/zmp.hlp 0: +../../Binary/Apps/zmp.doc 0: +../../Binary/Apps/zmxfer.ovr 0: +../../Binary/Apps/zmterm.ovr 0: +../../Binary/Apps/zminit.ovr 0: +../../Binary/Apps/zmconfig.ovr 0: +../../Binary/Apps/zmd.com 0: +# +# Add Tune sample files +# +../../Binary/Apps/Tunes/*.pt? 3: +../../Binary/Apps/Tunes/*.mym 3: +# +# Add OS image +# +../ZSDOS/zsys_wbw.sys 0:zsys.sys +# +# Add Common Applications +# +Common/All/*.* 0: +Common/CPM22/*.* 0: +#Common/Z/u10/*.* 0: +Common/Z/u14/*.* 0: +Common/Z/u15/*.* 0: diff --git a/Source/Images/d_bp.txt b/Source/Images/hd_bp.txt similarity index 81% rename from Source/Images/d_bp.txt rename to Source/Images/hd_bp.txt index c613ebc7..ea4ba8ef 100644 --- a/Source/Images/d_bp.txt +++ b/Source/Images/hd_bp.txt @@ -33,15 +33,7 @@ ../../Binary/Apps/zminit.ovr 15: ../../Binary/Apps/zmconfig.ovr 15: ../../Binary/Apps/zmd.com 15: - # -#../../Binary/Apps/i2clcd.com 2: -#../../Binary/Apps/i2cscan.com 2: -#../../Binary/Apps/rtcds7.com 2: -#../../Binary/Apps/rtchb.com 2: -#../../Binary/Apps/ppidetst.com 2: -#../../Binary/Apps/ramtest.com 2: -#../../Binary/Apps/tstdskng.com 2: ../../Binary/Apps/Test/*.com 2: Test/*.* 2: # diff --git a/Source/Images/d_cpm22.txt b/Source/Images/hd_cpm22.txt similarity index 79% rename from Source/Images/d_cpm22.txt rename to Source/Images/hd_cpm22.txt index 0be74e3d..11372530 100644 --- a/Source/Images/d_cpm22.txt +++ b/Source/Images/hd_cpm22.txt @@ -30,13 +30,6 @@ d_cpm22/ReadMe.txt 0: ../../Binary/Apps/zmconfig.ovr 0: ../../Binary/Apps/zmd.com 0: # -#../../Binary/Apps/i2clcd.com 2: -#../../Binary/Apps/i2cscan.com 2: -#../../Binary/Apps/rtcds7.com 2: -#../../Binary/Apps/rtchb.com 2: -#../../Binary/Apps/ppidetst.com 2: -#../../Binary/Apps/ramtest.com 2: -#../../Binary/Apps/tstdskng.com 2: ../../Binary/Apps/Test/*.com 2: Test/*.* 2: # diff --git a/Source/Images/d_cpm3.txt b/Source/Images/hd_cpm3.txt similarity index 82% rename from Source/Images/d_cpm3.txt rename to Source/Images/hd_cpm3.txt index da74a74b..3c8c78c0 100644 --- a/Source/Images/d_cpm3.txt +++ b/Source/Images/hd_cpm3.txt @@ -46,13 +46,6 @@ ../../Binary/Apps/zmconfig.ovr 0: ../../Binary/Apps/zmd.com 0: # -#../../Binary/Apps/i2clcd.com 2: -#../../Binary/Apps/i2cscan.com 2: -#../../Binary/Apps/rtcds7.com 2: -#../../Binary/Apps/rtchb.com 2: -#../../Binary/Apps/ppidetst.com 2: -#../../Binary/Apps/ramtest.com 2: -#../../Binary/Apps/tstdskng.com 2: ../../Binary/Apps/Test/*.com 2: Test/*.* 2: # diff --git a/Source/Images/d_nzcom.txt b/Source/Images/hd_nzcom.txt similarity index 83% rename from Source/Images/d_nzcom.txt rename to Source/Images/hd_nzcom.txt index e0fa9c63..0c904109 100644 --- a/Source/Images/d_nzcom.txt +++ b/Source/Images/hd_nzcom.txt @@ -47,13 +47,6 @@ d_zsdos/u0/*.* 0: ../../Binary/Apps/zmconfig.ovr 0: ../../Binary/Apps/zmd.com 0: # -#../../Binary/Apps/i2clcd.com 2: -#../../Binary/Apps/i2cscan.com 2: -#../../Binary/Apps/rtcds7.com 2: -#../../Binary/Apps/rtchb.com 2: -#../../Binary/Apps/ppidetst.com 2: -#../../Binary/Apps/ramtest.com 2: -#../../Binary/Apps/tstdskng.com 2: ../../Binary/Apps/Test/*.com 2: Test/*.* 2: # diff --git a/Source/Images/d_zpm3.txt b/Source/Images/hd_zpm3.txt similarity index 83% rename from Source/Images/d_zpm3.txt rename to Source/Images/hd_zpm3.txt index 878159bf..61bcd4de 100644 --- a/Source/Images/d_zpm3.txt +++ b/Source/Images/hd_zpm3.txt @@ -45,13 +45,6 @@ ../../Binary/Apps/zmconfig.ovr 15: ../../Binary/Apps/zmd.com 15: # -#../../Binary/Apps/i2clcd.com 2: -#../../Binary/Apps/i2cscan.com 2: -#../../Binary/Apps/rtcds7.com 2: -#../../Binary/Apps/rtchb.com 2: -#../../Binary/Apps/ppidetst.com 2: -#../../Binary/Apps/ramtest.com 2: -#../../Binary/Apps/tstdskng.com 2: ../../Binary/Apps/Test/*.com 2: Test/*.* 2: # diff --git a/Source/Images/d_zsdos.txt b/Source/Images/hd_zsdos.txt similarity index 82% rename from Source/Images/d_zsdos.txt rename to Source/Images/hd_zsdos.txt index 72106517..806d879a 100644 --- a/Source/Images/d_zsdos.txt +++ b/Source/Images/hd_zsdos.txt @@ -43,13 +43,6 @@ d_cpm22/u0/XSUB.COM 0: ../../Binary/Apps/zmconfig.ovr 0: ../../Binary/Apps/zmd.com 0: # -#../../Binary/Apps/i2clcd.com 2: -#../../Binary/Apps/i2cscan.com 2: -#../../Binary/Apps/rtcds7.com 2: -#../../Binary/Apps/rtchb.com 2: -#../../Binary/Apps/ppidetst.com 2: -#../../Binary/Apps/ramtest.com 2: -#../../Binary/Apps/tstdskng.com 2: ../../Binary/Apps/Test/*.com 2: Test/*.* 2: # diff --git a/Source/ver.inc b/Source/ver.inc index 69e8e59f..f14ca9b3 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,4 +2,4 @@ #DEFINE RMN 1 #DEFINE RUP 1 #DEFINE RTP 0 -#DEFINE BIOSVER "3.1.1-pre.144" +#DEFINE BIOSVER "3.1.1-pre.146" diff --git a/Source/ver.lib b/Source/ver.lib index 0e84f405..a22e049f 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 1 rup equ 1 rtp equ 0 biosver macro - db "3.1.1-pre.144" + db "3.1.1-pre.146" endm