;-------------------------------------------------------------------------------------------------------- ;- ;- Name: sharpmz-test.asm ;- Created: October 2018 ;- Author(s): Philip Smart ;- Description: Sharp MZ series tester utility. ;- This assembly language program is a quick coding to aid in testing components ;- of the SharpMZ Series FPGA emulation and more recently the tranZPUter ;- and video module offshoots. It is a rough and ready program just to aid ;- exercising of hardware changes to verify they work and are reliable. ;- ;- Currently it aids in testing: ;- 1. Tape Read ;- 2. Tape Write ;- 3. Memory Test ;- 4. Graphics RAM Test ;- ;- Credits: ;- Copyright: (c) 2018-20 Philip Smart ;- ;- History: October 2018 - Merged 2 utilities to create this compilation. ;- September 2020 - Updated to enable testing of the Video Module v2.0 ;- ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify ;- it under the terms of the GNU General Public License as published ;- by the Free Software Foundation, either version 3 of the License, or ;- (at your option) any later version. ;- ;- This source file is distributed in the hope that it will be useful, ;- but WITHOUT ANY WARRANTY; without even the implied warranty of ;- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;- GNU General Public License for more details. ;- ;- You should have received a copy of the GNU General Public License ;- along with this program. If not, see . ;-------------------------------------------------------------------------------------------------------- GETL: EQU 00003h LETNL: EQU 00006h NL: EQU 00009h PRNTS: EQU 0000Ch PRNT: EQU 00012h MSG: EQU 00015h MSGX: EQU 00018h MROMINIT: EQU 00000h MONIT: EQU 00086h ST1: EQU 00095h PRTHL: EQU 003BAh PRTHX: EQU 003C3h DPCT: EQU 00DDCh ?BRK: EQU 00D11h ?RSTR1: EQU 00EE6h TPSTART: EQU 010F0h MEMSTART: EQU 01200h GRAMSTART: EQU 0C000h GRAMEND: EQU 0FFFFh MSTART: EQU 0B800h MEMCHKEND: EQU 0B8H ;----------------------------------------------- ; IO ports in hardware and values. ;----------------------------------------------- MMCFG EQU 060H ; Memory management configuration latch. SETXMHZ EQU 062H ; Select the alternate clock frequency. SET2MHZ EQU 064H ; Select the system 2MHz clock frequency. CLKSELRD EQU 066H ; Read clock selected setting, 0 = 2MHz, 1 = XMHz SVCREQ EQU 068H ; I/O Processor service request. CPLDSTATUS EQU 06BH ; Version 2.1 CPLD status register. CPUCFG EQU 06CH ; Version 2.2 CPU configuration register. CPUSTATUS EQU 06CH ; Version 2.2 CPU runtime status register. CPUINFO EQU 06DH ; Version 2.2 CPU information register. CPLDCFG EQU 06EH ; Version 2.1 CPLD configuration register. CPLDINFO EQU 06FH ; Version 2.1 CPLD version information register. VMPNUM EQU 0A0H ; Set the parameter number to update. VMPLBYTE EQU 0A1H ; Update the lower selected parameter byte. VMPUBYTE EQU 0A2H ; Update the upper selected parameter byte. PALSLCTOFF EQU 0A3H ; set the palette slot Off position to be adjusted. PALSLCTON EQU 0A4H ; set the palette slot On position to be adjusted. PALSETRED EQU 0A5H ; set the red palette value according to the PALETTE_PARAM_SEL address. PALSETGREEN EQU 0A6H ; set the green palette value according to the PALETTE_PARAM_SEL address. PALSETBLUE EQU 0A7H ; set the blue palette value according to the PALETTE_PARAM_SEL address. VMPALETTE EQU 0B0H ; Select Palette: ; 0xB0 sets the palette. The Video Module supports 4 bit per colour output but there is only enough RAM for 1 bit per colour so the pallette is used to change the colours output. ; Bits [7:0] defines the pallete number. This indexes a lookup table which contains the required 4bit output per 1bit input. ; GPU: GPUPARAM EQU 0B2H ; 0xB2 set parameters. Store parameters in a long word to be used by the graphics command processor. ; The parameter word is 128 bit and each write to the parameter word shifts left by 8 bits and adds the new byte at bits 7:0. GPUCMD EQU 0B3H ; 0xB3 set the graphics processor unit commands. GPUSTATUS EQU 0B3H ; [7;1] - FSM state, [0] - 1 = busy, 0 = idle ; Bits [5:0] - 0 = Reset parameters. ; 1 = Clear to val. Start Location (16 bit), End Location (16 bit), Red Filter, Green Filter, Blue Filter ; VMCTRL EQU 0B8H ; Video Module control register. [2:0] - 0000 = MZ80K, 0001 = MZ80C, 0010 = MZ1200, 0011 = MZ80A, 0100 = MZ700, 0101 = MZ800, 0110 = MZ1500, 0111 = MZ80B, 1000 = MZ2000, 1001 = MZ2200, 1010 = MZ2500. [4] = 0 - 40 col, 1 - 80 col. VMGRMODE EQU 0B9H ; Video Module graphics mode. 7/6 = Operator (00=OR,01=AND,10=NAND,11=XOR), 5=GRAM Output Enable, 4 = VRAM Output Enable, 3/2 = Write mode (00=Page 1:Red, 01=Page 2:Green, 10=Page 3:Blue, 11=Indirect), 1/0=Read mode (00=Page 1:Red, 01=Page2:Green, 10=Page 3:Blue, 11=Not used). VMREDMASK EQU 0BAH ; Video Module Red bit mask (1 bit = 1 pixel, 8 pixels per byte). VMGREENMASK EQU 0BBH ; Video Module Green bit mask (1 bit = 1 pixel, 8 pixels per byte). VMBLUEMASK EQU 0BCH ; Video Module Blue bit mask (1 bit = 1 pixel, 8 pixels per byte). VMPAGE EQU 0BDH ; Video Module memory page register. [1:0] switches in 1 16Kb page (3 pages) of graphics ram to C000 - FFFF. Bits [1:0] = page, 00 = off, 01 = Red, 10 = Green, 11 = Blue. This overrides all MZ700/MZ80B page switching functions. [7] 0 - normal, 1 - switches in CGROM for upload at D000:DFFF. VMVGATTR EQU 0BEH ; Select VGA Border colour and attributes. Bit 2 = Red, 1 = Green, 0 = Blue. VMVGAMODE EQU 0BFH ; Select VGA output mode. Bits [3:0] - Output mode. GDCRTC EQU 0CFH ; MZ-800 CRTC control register GDCMD EQU 0CEH ; MZ-800 CRTC Mode register GDGRF EQU 0CDH ; MZ-800 read format register GDGWF EQU 0CCH ; MZ-800 write format register MMIO0 EQU 0E0H ; MZ-700/MZ-800 Memory Management Set 0 MMIO1 EQU 0E1H ; MZ-700/MZ-800 Memory Management Set 1 MMIO2 EQU 0E2H ; MZ-700/MZ-800 Memory Management Set 2 MMIO3 EQU 0E3H ; MZ-700/MZ-800 Memory Management Set 3 MMIO4 EQU 0E4H ; MZ-700/MZ-800 Memory Management Set 4 MMIO5 EQU 0E5H ; MZ-700/MZ-800 Memory Management Set 5 MMIO6 EQU 0E6H ; MZ-700/MZ-800 Memory Management Set 6 MMIO7 EQU 0E7H ; MZ-700/MZ-800 Memory Management Set 7 SYSCTRL EQU 0F0H ; System board control register. [2:0] - 000 MZ80A Mode, 2MHz CPU/Bus, 001 MZ80B Mode, 4MHz CPU/Bus, 010 MZ700 Mode, 3.54MHz CPU/Bus. GRAMMODE EQU 0F4H ; MZ80B Graphics mode. Bit 0 = 0, Write to Graphics RAM ;----------------------------------------------- ; GPU commands. ;----------------------------------------------- GPUCLEARVRAM EQU 001H ; Clear the VRAM without updating attributes. GPUCLEARVRAMCA EQU 002H ; Clear the VRAM/ARAM with given attribute byte, GPUCLEARVRAMP EQU 003H ; Clear the VRAM/ARAM with parameters. GPUCLEARGRAM EQU 081H ; Clear the entire Framebuffer. GPUCLEARGRAMP EQU 082H ; Clear the Framebuffer according to parameters. GPURESET EQU 0FFH ; Reset the GPU, return to idle state. ;----------------------------------------------- ; Memory mapped ports in hardware. ;----------------------------------------------- SCRN: EQU 0D000H ARAM: EQU 0D800H DSPCTL: EQU 0DFFFH ; Screen 40/80 select register (bit 7) KEYPA: EQU 0E000h KEYPB: EQU 0E001h KEYPC: EQU 0E002h KEYPF: EQU 0E003h CSTR: EQU 0E002h CSTPT: EQU 0E003h CONT0: EQU 0E004h CONT1: EQU 0E005h CONT2: EQU 0E006h CONTF: EQU 0E007h SUNDG: EQU 0E008h TEMP: EQU 0E008h MEMSW: EQU 0E00CH MEMSWR: EQU 0E010H INVDSP: EQU 0E014H NRMDSP: EQU 0E015H SCLDSP: EQU 0E200H SCLBASE: EQU 0E2H ;----------------------------------------------- ; CPLD Configuration constants. ;----------------------------------------------- MODE_MZ80K EQU 0 ; Set to MZ-80K mode. MODE_MZ80C EQU 1 ; Set to MZ-80C mode. MODE_MZ1200 EQU 2 ; Set to MZ-1200 mode. MODE_MZ80A EQU 3 ; Set to MZ-80A mode (base mode on MZ-80A hardware). MODE_MZ700 EQU 4 ; Set to MZ-700 mode (base mode on MZ-700 hardware). MODE_MZ800 EQU 5 ; Set to MZ-800 mode. MODE_MZ80B EQU 6 ; Set to MZ-80B mode. MODE_MZ2000 EQU 7 ; Set to MZ-2000 mode. MODE_VIDEO_FPGA EQU 8 ; Bit flag (bit 3) to switch CPLD into using the new FPGA video hardware. MODE_RESET_PRESERVE EQU 080H ; Preserve register configuration through reset. ;----------------------------------------------- ; CPLD Command Instruction constants. ;----------------------------------------------- CPLD_RESET_HOST EQU 1 ; CPLD level command to reset the host system. CPLD_HOLD_HOST_BUS EQU 2 ; CPLD command to hold the host bus. CPLD_RELEASE_HOST_BUS EQU 3 ; CPLD command to release the host bus. ;----------------------------------------------- ; Video Module control bits. ;----------------------------------------------- MODE_80CHAR EQU 010H ; Enable 80 character display. MODE_COLOUR EQU 020H ; Enable colour display. SYSMODE_MZ80A EQU 000H ; System board mode MZ80A, 2MHz CPU/Bus. SYSMODE_MZ80B EQU 020H ; System board mode MZ80B, 4MHz CPU/Bus. SYSMODE_MZ2000 EQU 020H ; System board mode MZ2000, 4MHz CPU/Bus. SYSMODE_MZ700 EQU 042H ; System board mode MZ700, 3.54MHz CPU/Bus. VMMODE_MZ80K EQU 000H ; Video mode = MZ80K VMMODE_MZ80C EQU 001H ; Video mode = MZ80C VMMODE_MZ1200 EQU 002H ; Video mode = MZ1200 VMMODE_MZ80A EQU 003H ; Video mode = MZ80A VMMODE_MZ700 EQU 004H ; Video mode = MZ700 VMMODE_MZ800 EQU 005H ; Video mode = MZ800 VMMODE_MZ1500 EQU 006H ; Video mode = MZ1500 VMMODE_MZ80B EQU 007H ; Video mode = MZ80B VMMODE_MZ2000 EQU 008H ; Video mode = MZ2000 VMMODE_MZ2200 EQU 009H ; Video mode = MZ2200 VMMODE_MZ2500 EQU 00AH ; Video mode = MZ2500 VMMODE_VGA_OFF EQU 000H ; Set VGA mode off, external monitor is driven by standard internal 60Hz signals. VMMODE_VGA_INT EQU 000H ; Set VGA mode off, external monitor is driven by standard internal 60Hz signals. VMMODE_VGA_INT50 EQU 001H ; Set VGA mode off, external monitor is driven by standard internal 50Hz signals. VMMODE_VGA_640x480 EQU 002H ; Set external monitor to VGA 640x480 @ 60Hz mode. VMMODE_VGA_800x600 EQU 003H ; Set external monitor to VGA 800x600 @ 60Hz mode. ;----------------------------------------------- ; tranZPUter SW Memory Management modes ;----------------------------------------------- TZMM_ENIOWAIT EQU 020H ; Memory management IO Wait State enable - insert a wait state when an IO operation to E0-FF is executed. TZMM_ORIG EQU 000H ; Original Sharp MZ80A mode, no tranZPUter features are selected except the I/O control registers (default: 0x60-063). TZMM_BOOT EQU 001H ; Original mode but E800-EFFF is mapped to tranZPUter RAM so TZFS can be booted. TZMM_TZFS EQU 002H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-FFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected. TZMM_TZFS2 EQU 003H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 1. TZMM_TZFS3 EQU 004H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 2. TZMM_TZFS4 EQU 005H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 3. TZMM_CPM EQU 006H + TZMM_ENIOWAIT ; CPM main memory configuration, all memory on the tranZPUter board, 64K block 4 selected. Special case for F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard. TZMM_CPM2 EQU 007H + TZMM_ENIOWAIT ; CPM main memory configuration, F000-FFFF are on the tranZPUter board in block 4, 0040-CFFF and E800-EFFF are in block 5, mainboard for D000-DFFF (video), E000-E800 (Memory control) selected. ; Special case for 0000:003F (interrupt vectors) which resides in block 4, F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard. TZMM_COMPAT EQU 008H + TZMM_ENIOWAIT ; Original mode but with main DRAM in Bank 0 to allow bootstrapping of programs from other machines such as the MZ700. TZMM_HOSTACCESS EQU 009H + TZMM_ENIOWAIT ; Mode to allow code running in Bank 0, address E800:FFFF to access host memory. Monitor ROM 0000-0FFF and Main DRAM 0x1000-0xD000, video and memory mapped I/O are on the host machine, User/Floppy ROM E800-FFFF are in tranZPUter memory. TZMM_MZ700_0 EQU 00AH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the mainboard. TZMM_MZ700_1 EQU 00BH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6. TZMM_MZ700_2 EQU 00CH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6. TZMM_MZ700_3 EQU 00DH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible. TZMM_MZ700_4 EQU 00EH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible. TZMM_MZ800 EQU 00FH + TZMM_ENIOWAIT ; MZ800 Mode - Tracks original hardware mode offering MZ700/MZ800 configurations. TZMM_MZ2000 EQU 010H + TZMM_ENIOWAIT; ; MZ2000 Mode - Running on MZ2000 hardware, configuration set according to runtime configuration registers. TZMM_FPGA EQU 015H + TZMM_ENIOWAIT ; Open up access for the K64F to the FPGA resources such as memory. All other access to RAM or mainboard is blocked. TZMM_TZPUM EQU 016H + TZMM_ENIOWAIT ; Everything in on mainboard, no access to tranZPUter memory. TZMM_TZPU EQU 017H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected. ;TZMM_TZPU0 EQU 018H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected. ;TZMM_TZPU1 EQU 019H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 1 is selected. ;TZMM_TZPU2 EQU 01AH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 2 is selected. ;TZMM_TZPU3 EQU 01BH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 3 is selected. ;TZMM_TZPU4 EQU 01CH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 4 is selected. ;TZMM_TZPU5 EQU 01DH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 5 is selected. ;TZMM_TZPU6 EQU 01EH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 6 is selected. ;TZMM_TZPU7 EQU 01FH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 7 is selected. ;----------------------------------------------- ; BIOS WORK AREA (MZ80A) ;----------------------------------------------- TZVARMEM: EQU 0F4A0H TZSVCMEM: EQU 0F560H ; Start of a memory structure used to communicate with the K64F I/O processor for services such as disk access. TZSVCSIZE: EQU 00280H ; TZSVCDIRSZ: EQU 20 ; Size of the directory/file name. TZSVCFILESZ: EQU 17 ; Size of a Sharp filename. TZSVCLONGFILESZ: EQU 31 ; Size of a standard filename. TZSVCLONGFMTSZ: EQU 20 ; Size of a formatted standard filename for use in directory listings. TZSVCWILDSZ: EQU 20 ; Size of the wildcard. TZSVCSECSIZE: EQU 512 TZSVCDIR_ENTSZ: EQU 32 ; Size of a directory entry. TZSVCWAITIORETRIES: EQU 500 ; Wait retries for IO response. TZSVCWAITCOUNT: EQU 65535 ; Wait retries for IO request response. TZSVC_FTYPE_MZF: EQU 0 ; File type being handled is an MZF TZSVC_FTYPE_CAS: EQU 1 ; File type being handled is an CASsette BASIC script. TZSVC_FTYPE_BAS: EQU 2 ; File type being handled is an BASic script TZSVC_FTYPE_ALL: EQU 10 ; Handle any filetype. TZSVC_FTYPE_ALLFMT: EQU 11 ; Special case for directory listings, all files but truncated and formatted. ; TZ Service Commands TZSVC_CMD_READDIR EQU 01H ; Service command to open a directory and return the first block of entries. TZSVC_CMD_NEXTDIR EQU 02H ; Service command to return the next block of an open directory. TZSVC_CMD_READFILE EQU 03H ; Service command to open a file and return the first block. TZSVC_CMD_NEXTREADFILE EQU 04H ; Service command to return the next block of an open file. TZSVC_CMD_WRITEFILE EQU 05H ; Service command to create a file and save the first block. TZSVC_CMD_NEXTWRITEFILE EQU 06H ; Service command to write the next block to the open file. TZSVC_CMD_CLOSE EQU 07H ; Service command to close any open file or directory. TZSVC_CMD_LOADFILE EQU 08H ; Service command to load a file directly into tranZPUter memory. TZSVC_CMD_SAVEFILE EQU 09H ; Service command to save a file directly from tranZPUter memory. TZSVC_CMD_ERASEFILE EQU 0aH ; Service command to erase a file on the SD card. TZSVC_CMD_CHANGEDIR EQU 0bH ; Service command to change the active directory on the SD card. TZSVC_CMD_LOAD40ABIOS EQU 20H ; Service command requesting that the 40 column version of the SA1510 BIOS is loaded. TZSVC_CMD_LOAD80ABIOS EQU 21H ; Service command requesting that the 80 column version of the SA1510 BIOS is loaded. TZSVC_CMD_LOAD700BIOS40 EQU 22H ; Service command requesting that the MZ700 1Z-013A 40 column BIOS is loaded. TZSVC_CMD_LOAD700BIOS80 EQU 23H ; Service command requesting that the MZ700 1Z-013A 80 column patched BIOS is loaded. TZSVC_CMD_LOAD80BIPL EQU 24H ; Service command requesting the MZ-80B IPL is loaded. TZSVC_CMD_LOAD800BIOS EQU 25H ; Service command requesting that the MZ800 9Z-504M BIOS is loaded. TZSVC_CMD_LOAD2000IPL EQU 26H ; Service command requesting the MZ-2000 IPL is loaded. TZSVC_CMD_LOADTZFS EQU 2FH ; Service command requesting the loading of TZFS. This service is for machines which normally dont have a monitor BIOS. ie. MZ-80B/MZ-2000 and manually request TZFS. TZSVC_CMD_LOADBDOS EQU 30H ; Service command to reload CPM BDOS+CCP. TZSVC_CMD_ADDSDDRIVE EQU 31H ; Service command to attach a CPM disk to a drive number. TZSVC_CMD_READSDDRIVE EQU 32H ; Service command to read an attached SD file as a CPM disk drive. TZSVC_CMD_WRITESDDRIVE EQU 33H ; Service command to write to a CPM disk drive which is an attached SD file. TZSVC_CMD_CPU_BASEFREQ EQU 40H ; Service command to switch to the mainboard frequency. TZSVC_CMD_CPU_ALTFREQ EQU 41H ; Service command to switch to the alternate frequency provided by the K64F. TZSVC_CMD_CPU_CHGFREQ EQU 42H ; Service command to set the alternate frequency in hertz. TZSVC_CMD_CPU_SETZ80 EQU 50H ; Service command to switch to the external Z80 hard cpu. TZSVC_CMD_CPU_SETT80 EQU 51H ; Service command to switch to the internal T80 soft cpu. TZSVC_CMD_CPU_SETZPUEVO EQU 52H ; Service command to switch to the internal ZPU Evolution soft cpu. TZSVC_CMD_EMU_SETMZ80K EQU 53H ; Service command to switch to the internal Sharp MZ Series Emulation of the MZ80K. TZSVC_CMD_EMU_SETMZ80C EQU 54H ; "" "" "" MZ80C. TZSVC_CMD_EMU_SETMZ1200 EQU 55H ; "" "" "" MZ1200. TZSVC_CMD_EMU_SETMZ80A EQU 56H ; "" "" "" MZ80A. TZSVC_CMD_EMU_SETMZ700 EQU 57H ; "" "" "" MZ700. TZSVC_CMD_EMU_SETMZ800 EQU 58H ; "" "" "" MZ800. TZSVC_CMD_EMU_SETMZ1500 EQU 59H ; "" "" "" MZ1500. TZSVC_CMD_EMU_SETMZ80B EQU 5AH ; "" "" "" MZ80B. TZSVC_CMD_EMU_SETMZ2000 EQU 5BH ; "" "" "" MZ2000. TZSVC_CMD_EMU_SETMZ2200 EQU 5CH ; "" "" "" MZ2200. TZSVC_CMD_EMU_SETMZ2500 EQU 5DH ; "" "" "" MZ2500. TZSVC_CMD_EXIT EQU 07FH ; Service command to terminate TZFS and restart the machine in original mode. TZSVC_STATUS_OK EQU 000H ; Flag to indicate the K64F processing completed successfully. TZSVC_STATUS_REQUEST EQU 0FEH ; Flag to indicate the Z80 has made a request to the K64F. TZSVC_STATUS_PROCESSING EQU 0FFH ; Flag to indicate the K64F is processing a command. ORG TPSTART SPV: IBUFE: ; TAPE BUFFER (128 BYTES) ;ATRB: DS virtual 1 ; ATTRIBUTE ATRB: DB 01h ; Code Type, 01 = Machine Code. ;NAME: DS virtual 17 ; FILE NAME NAME: DB "SHARPMZ TEST V1", 0Dh, 00h ; Title/Name (17 bytes). ;SIZE: DS virtual 2 ; BYTESIZE SIZE: DW MEND - MSTART ; Size of program. ;DTADR: DS virtual 2 ; DATA ADDRESS DTADR: DW MSTART ; Load address of program. ;EXADR: DS virtual 2 ; EXECUTION ADDRESS EXADR: DW MSTART ; Exec address of program. COMNT: DS 104 ; COMMENT KANAF: DS virtual 1 ; KANA FLAG (01=GRAPHIC MODE) DSPXY: DS virtual 2 ; DISPLAY COORDINATES MANG: DS virtual 27 ; COLUMN MANAGEMENT FLASH: DS virtual 1 ; FLASHING DATA FLPST: DS virtual 2 ; FLASHING POSITION FLSST: DS virtual 1 ; FLASHING STATUS FLSDT: DS virtual 1 ; CURSOR DATA STRGF: DS virtual 1 ; STRING FLAG DPRNT: DS virtual 1 ; TAB COUNTER TMCNT: DS virtual 2 ; TAPE MARK COUNTER SUMDT: DS virtual 2 ; CHECK SUM DATA CSMDT: DS virtual 2 ; FOR COMPARE SUM DATA AMPM: DS virtual 1 ; AMPM DATA TIMFG: DS virtual 1 ; TIME FLAG SWRK: DS virtual 1 ; KEY SOUND FLAG TEMPW: DS virtual 1 ; TEMPO WORK ONTYO: DS virtual 1 ; ONTYO WORK OCTV: DS virtual 1 ; OCTAVE WORK RATIO: DS virtual 2 ; ONPU RATIO BUFER: DS virtual 81 ; GET LINE BUFFER ORG MSTART JP START ; Graphics Initialisation. Needs to be in memory before C000-FFFF ; ; 0x6E CPLD Configuration register. ; ; The mode can be changed by a Z80 transaction write into the register and it is acted upon if the mode switches between differing values. The Z80 write is typically used ; by host software such as RFS. ; ; [2:0] - Mode/emulated machine. ; 000 = MZ-80K ; 001 = MZ-80C ; 010 = MZ-1200 ; 011 = MZ-80A ; 100 = MZ-700 ; 101 = MZ-800 ; 110 = MZ-80B ; 111 = MZ-2000 ; [3] - Mainboard Video - 1 = Enable, 0 = Disable - This flag allows Z-80 transactions in the range D000:DFFF to be directed to the mainboard. When disabled all transactions ; can only be seen by the FPGA video logic. The FPGA uses this flag to enable/disable it's functionality. ; [6:4] = Mainboard/CPU clock. ; 000 = Sharp MZ80A 2MHz System Clock. ; 001 = Sharp MZ80B 4MHz System Clock. ; 010 = Sharp MZ700 3.54MHz System Clock. ; 011 -111 = Reserved, defaults to 2MHz System Clock. ; ; ; 0xF8 set the video mode. ; Bits [2:0] define the Video Module machine compatibility. 000 = MZ80K, 001 = MZ80C, 010 = MZ1200, 011 = MZ80A, 100 = MZ-700, 101 = MZ-800, 110 = MZ-80B, 111 = MZ2000, ; Bit [3] defines the 40/80 column mode, 0 = 40 col, 1 = 80 col. ; Bit [4] defines the colour mode, 0 = mono, 1 = colour - ignored on certain modes. ; Bit [5] defines wether PCGRAM is enabled, 0 = disabled, 1 = enabled. ; Bits [7:6] define the VGA mode. ; 0xF9 set the graphics mode. 7/6 = Operator (00=OR,01=AND,10=NAND,11=XOR), ; 5 = GRAM Output Enable (=0), 4 = VRAM Output Enable (=0), ; 3/2 = Write mode (00=Page 1:Red, 01=Page 2:Green, 10=Page 3:Blue, 11=Indirect), ; 1/0 = Read mode (00=Page 1:Red, 01=Page2:Green, 10=Page 3:Blue, 11=Not used). ; 0xFA set the Red bit mask (1 bit = 1 pixel, 8 pixels per byte). ; 0xFB set the Green bit mask (1 bit = 1 pixel, 8 pixels per byte). ; 0xFC set the Blue bit mask (1 bit = 1 pixel, 8 pixels per byte). ; 0xFD set the Video memory page in block C000:FFFF ; [1:0] switches in 1 16Kb page (3 pages) of graphics ram to C000 - FFFF. 00 = disabled, standard VRAM, 01 = Red page, 10 = Blue page, 11 = Green page. ; [7] 0 - normal, 1 - switches in CGROM for upload at D000:DFFF. GRAMINIT: OUT (VMGRMODE),A ; Set provided graphics mode. LD A,1 ; Switch graphics page into C000:FFFF memory bank OUT (VMPAGE),A GRAM0: LD HL,GRAMSTART ; Start of graphics page. LD BC,GRAMEND - GRAMSTART ; Size of graphics page (16KB). GRAM1: LD A,000h ; Clear memory. LD (HL),A INC HL DEC BC LD A,B OR C JR NZ,GRAM1 LD A,0 ; Revert to normal memory. OUT (VMPAGE),A RET ; Graphics Test. Needs to be in memory before C000-FFFF ; GRAMTEST: OUT (VMGRMODE),A LD A,1 ; Switch graphics page into C000:FFFF memory bank OUT (VMPAGE),A LD D, 1 ; Number of iterations. LD E,080h GRAMTST0: LD HL,GRAMSTART LD BC,GRAMEND - GRAMSTART GRAMTST1: LD A,E LD (HL),A INC HL DEC BC LD A,B OR C JR NZ,GRAMTST1 RR E JR NZ,GRAMTST0 ;JR C,GRAMTST0 DEC D JR NZ,GRAMTST0 LD A,0 ; Revert to normal memory. OUT (VMPAGE),A RET ; GRAMTEST2: OUT (VMGRMODE),A LD A,1 ; Switch graphics page into C000:FFFF memory bank OUT (VMPAGE),A LD E,0FFH GRAMTST4: LD HL,GRAMSTART LD BC,GRAMEND - GRAMSTART GRAMTST5: LD A,E LD (HL),A INC HL DEC BC LD A,B OR C JR NZ,GRAMTST5 LD A,0 ; Revert to normal memory. OUT (VMPAGE),A RET ; Graphics Test routine. ; ; Graphics mode:- 7/6 = Operator (00=OR,01=AND,10=NAND,11=XOR), ; 5 = GRAM Output Enable 0 = active. ; 4 = VRAM Output Enable, 0 = active. ; 3/2 = Write mode (00=Page 1:Red, 01=Page 2:Green, 10=Page 3:Blue, 11=Indirect), ; 1/0 = Read mode (00=Page 1:Red, 01=Page2:Green, 10=Page 3:Blue, 11=Not used). ; GRAPHICS1: LD B, 128 GRAPH0: PUSH BC LD A,010h ; Red page read/write. CALL GRAMTEST LD A,015h ; Green page read/write. CALL GRAMTEST LD A,01Ah ; Blue page. CALL GRAMTEST POP BC DJNZ GRAPH0 JP GETL1 GRAPHICS2: LD A, 0FFH ; Run through the filter mask. OUT (VMREDMASK),A OUT (VMGREENMASK),A OUT (VMBLUEMASK),A GRAPH1: LD A, 01Ch ; Set graphics mode to Indirect Page write. CALL GRAMTEST2 IN A,(VMREDMASK) DEC A OUT (VMREDMASK),A JR NZ, GRAPH1 IN A,(VMGREENMASK) DEC A OUT (VMGREENMASK),A JR NZ, GRAPH1 IN A,(VMBLUEMASK) DEC A OUT (VMBLUEMASK),A JR NZ, GRAPH1 JP GETL1 ; Graphics progress bar indicator. Needs to be in memory before C000-FFFF ; GRPHIND: LD HL,(GRPHPOS) ; Get position of graphics progress line. LD A,001H OUT (VMPAGE),A ; Enable graphics memory. LD A,0FFh LD (HL),A LD A,0 OUT (VMPAGE),A ; Disable graphics memory. INC HL LD (GRPHPOS),HL LD A,08CH OUT (VMGRMODE),A RET ; ; Start of main program. ; START: LD HL,0066H ; Set NMI so it doesnt bother us. LD (HL), 0EDH ; Set to RETN instruction. INC HL LD (HL), 045H IN A, (CPLDINFO) ; Get hardware information. AND 07H ; Remove version. LD D, A OR MODE_VIDEO_FPGA ; Ensure the video hardware is enabled. OUT (CPLDCFG),A LD A,D CP MODE_MZ80A JR NZ,START2 LD A,VMMODE_MZ700 ; Switch to MZ700 video mode for colour testing. JR START3 ;IN A,(VMCTRL) ;AND 0C0H ; Mask out all but VGA mode. START2: OR D ; Bring in mode. START3: OUT (VMCTRL),A ; Activate. LD A, VMMODE_VGA_800x600 ; VGA mode 800x600 OUT (VMVGAMODE),A ; SIGNON: LD A,016H CALL PRNT LD A,071H ; Blue background, white characters in colour mode. Bit 7 is set as a write to bit 7 @ DFFFH selects 80Char mode. LD HL,ARAM CALL CLR8 CALL NL LD DE,TITLE CALL MSG CALL LETNL CALL LETNL ; 0x6E CPLD Configuration register. ; ; The mode can be changed by a Z80 transaction write into the register and it is acted upon if the mode switches between differing values. The Z80 write is typically used ; by host software such as RFS. ; ; [2:0] - Mode/emulated machine. ; 000 = MZ-80K ; 001 = MZ-80C ; 010 = MZ-1200 ; 011 = MZ-80A ; 100 = MZ-700 ; 101 = MZ-800 ; 110 = MZ-80B ; 111 = MZ-2000 ; [3] - Mainboard Video - 1 = Enable, 0 = Disable - This flag allows Z-80 transactions in the range D000:DFFF to be directed to the mainboard. When disabled all transactions ; can only be seen by the FPGA video logic. The FPGA uses this flag to enable/disable it's functionality. ; [6:4] = Mainboard/CPU clock. ; 000 = Sharp MZ80A 2MHz System Clock. ; 001 = Sharp MZ80B 4MHz System Clock. ; 010 = Sharp MZ700 3.54MHz System Clock. ; 011 -111 = Reserved, defaults to 2MHz System Clock. ; ; ; 0xF8 set the video mode. ; Bits [2:0] define the Video Module machine compatibility. 000 = MZ80K, 001 = MZ80C, 010 = MZ1200, 011 = MZ80A, 100 = MZ-700, 101 = MZ-800, 110 = MZ-80B, 111 = MZ2000, ; Bit [3] defines the 40/80 column mode, 0 = 40 col, 1 = 80 col. ; Bit [4] defines the colour mode, 0 = mono, 1 = colour - ignored on certain modes. ; Bit [5] defines wether PCGRAM is enabled, 0 = disabled, 1 = enabled. ; Bits [7:6] define the VGA mode. ; 0xF9 set the graphics mode. 7/6 = Operator (00=OR,01=AND,10=NAND,11=XOR), ; 5 = GRAM Output Enable (=0), 4 = VRAM Output Enable (=0), ; 3/2 = Write mode (00=Page 1:Red, 01=Page 2:Green, 10=Page 3:Blue, 11=Indirect), ; 1/0 = Read mode (00=Page 1:Red, 01=Page2:Green, 10=Page 3:Blue, 11=Not used). ; 0xFA set the Red bit mask (1 bit = 1 pixel, 8 pixels per byte). ; 0xFB set the Green bit mask (1 bit = 1 pixel, 8 pixels per byte). ; 0xFC set the Blue bit mask (1 bit = 1 pixel, 8 pixels per byte). ; 0xFD set the Video memory page in block C000:FFFF bit 0, set the CGROM upload access in bit 7. INITGRPH: LD DE,MSG_INITGR CALL MSG CALL LETNL LD A,0FFh ; Set Red filter. OUT (VMREDMASK),A LD A,0FFh ; Set Green filter. OUT (VMGREENMASK),A LD A,0FFh ; Set Blue filter. OUT (VMBLUEMASK),A LD A,010h ; Enable graphics output and character display output. Initialise Red page. CALL GRAMINIT LD A,015h ; Initialise Green page. CALL GRAMINIT LD A,01Ah ; Initialise Blue page. CALL GRAMINIT LD A, 0ECh ; Set graphics mode to Indirect Page write, disable graphics output. OUT (VMGRMODE),A LD HL,0DE00h LD (GRPHPOS),HL ; INITMEM: LD DE,MSG_INITM CALL MSG CALL LETNL LD HL,1200h LD BC,MSTART - 1200h CLEAR1: LD A,00h LD (HL),A INC HL DEC BC LD A,B OR C JP NZ,CLEAR1 JP HELP ; Output known commands at startup. GETL1: LD A, 0ECh ; Set graphics mode to VRAM enable, GRAM disable. OUT (VMGRMODE),A CALL NL GETL1A: LD A,03EH CALL PRNT LD DE,BUFER CALL GETL CMDCMP: LD HL,CMDTABLE CMDCMP0: LD DE,BUFER+1 ; First command byte after the * prompt. LD A,(HL) CP 000H JR Z,GETL1A ; Skip processing on lines where just CR pressed. BIT 7,A ; Bit 7 set on command properties indicates table end, exit if needed. JR NZ,CMDNOCMP LD C,A ; Command properties into C SET 6,C ; Assume command match. AND 007H ; Mask out bytes in command mask. LD B,A ; Number of bytes in command. INC HL CMDCMP1: LD A,(DE) ; Compare all bytes and reset match bit if we find a difference. CP (HL) JR Z, CMDCMP2 RES 6,C ; No command match. CMDCMP2: INC DE INC HL DJNZ CMDCMP1 BIT 6,C ; Bit 7 is still set then we have a command match. JR NZ,CMDCMP3 INC HL INC HL ; Skip over function address JR CMDCMP0 ; Try match next command. CMDCMP3: LD A,(HL) ; Command function address into HL INC HL LD H,(HL) LD L,A PUSH HL LD (TMPADR),DE ; Store the key buffer location where arguments start. LD HL,CMDCMPEND ; Location to return to after function is called. EX (SP),HL ; Swap the return location with the location to call. PUSH HL ; Put location to call at top of stack. RET ; Pop into PC and run. ; CMDNOCMP: LD DE,MSGBADCMD CALL MSG CALL NL CMDCMPEND: JP GETL1A ; Monitor command table. This table contains the list of recognised commands along with the ; handler function and bank in which it is located. ; ; 7 6 5:3 2:0 ; END MATCH UNUSED SIZE CMDTABLE: DB 000H | 000H | 000H | 004H DB "HELP" DW HELP DB 000H | 000H | 000H | 005H DB "GRPH1" DW GRAPHICS1 DB 000H | 000H | 000H | 005H DB "GRPH2" DW GRAPHICS2 DB 000H | 000H | 000H | 004H DB "GPU1" DW GPU1 DB 000H | 000H | 000H | 004H DB "GPU2" DW GPU2 DB 000H | 000H | 000H | 003H DB "PAL" DW PALETTE DB 000H | 000H | 000H | 007H DB "MEMTEST" DW MEMTEST DB 000H | 000H | 000H | 004H DB "LOAD" DW LOAD DB 000H | 000H | 000H | 005H DB "TIMER" DW TIMERTST DB 000H | 000H | 000H | 004H DB "SAVE" DW SAVE DB 000H | 000H | 000H | 004H DB "QUIT" DW MROMINIT DB 000H | 000H | 000H | 004H DB "VGA0" ; Set VGA mode. DW VGA0 DB 000H | 000H | 000H | 004H DB "VGA1" ; Set VGA mode. DW VGA1 DB 000H | 000H | 000H | 004H DB "VGA2" ; Set VGA mode. DW VGA2 DB 000H | 000H | 000H | 004H DB "VGA3" ; Set VGA mode. DW VGA3 DB 000H | 000H | 000H | 001H VGA0: IN A,(VMVGAMODE) AND 0F0H OUT (VMVGAMODE),A JP GETL1 VGA1: IN A,(VMVGAMODE) AND 0F0H OR 000H OUT (VMVGAMODE),A JP GETL1 VGA2: IN A,(VMVGAMODE) AND 0F0H OR 001H OUT (VMVGAMODE),A JP GETL1 VGA3: IN A,(VMVGAMODE) AND 0F0H OR 002H OUT (VMVGAMODE),A JP GETL1 ; Simple commands to exercise the GPU functions. ; ; First up, character clear with parameters. Create descending cleared areas with incremental ; character and colour. This puts a lot of pressure on the GPU/Video memory, not so pretty to watch ; but does test it out. GPU1: XOR A LD (GPUCHAR),A LD (GPUATTR),A LD (GPUSTARTX),A GPUNEXT0: XOR A LD (GPUSTARTY),A GPUNEXT1: LD A,(GPUSTARTX) LD (GPUENDX),A GPUNEXT2: LD A,(GPUSTARTY) LD (GPUENDY),A ; Wait for the GPU to become ready. GPUWAIT1: IN A,(GPUSTATUS) BIT 0,A JR NZ,GPUWAIT1 ; Setup the GPU parameters to fill area. GPUNEXT3: LD A,(GPUSTARTX) OUT (GPUPARAM),A LD A,(GPUSTARTY) OUT (GPUPARAM),A LD A,(GPUENDX) OUT (GPUPARAM),A LD A,(GPUENDY) OUT (GPUPARAM),A LD A,(GPUCHAR) OUT (GPUPARAM),A LD A,(GPUATTR) OUT (GPUPARAM),A ; Issue the GPU command. LD A,GPUCLEARVRAMP OUT (GPUCMD),A ; Next End Y loop. LD A,(GPUENDY) INC A LD (GPUENDY),A CP 25 JP C, GPUWAIT1 ; Change the character. LD A,(GPUCHAR) INC A LD (GPUCHAR),A ; Next End X loop. LD A,(GPUENDX) INC A LD (GPUENDX),A CP 40 JP C, GPUNEXT2 ; Wait for the GPU to become ready. GPUWAIT2: IN A,(GPUSTATUS) BIT 0,A JR NZ,GPUWAIT2 ; Setup the GPU parameters to clear area. LD A,(GPUSTARTX) OUT (GPUPARAM),A LD A,(GPUSTARTY) OUT (GPUPARAM),A LD A,(GPUENDX) OUT (GPUPARAM),A LD A,(GPUENDY) OUT (GPUPARAM),A LD A,000H ; Space OUT (GPUPARAM),A LD A,071H ; Default white on blue. OUT (GPUPARAM),A ; Issue the GPU command. LD A,GPUCLEARVRAMP OUT (GPUCMD),A ; Adjust back colour. LD A,(GPUATTR) LD C,A AND 0F8H LD D,A LD A,C INC A AND 007H OR D LD (GPUATTR),A ; Next Start Y loop. LD A,(GPUSTARTY) INC A LD (GPUSTARTY),A CP 25 JP C, GPUNEXT1 ; Adjust front colour. LD A,(GPUATTR) LD C,A AND 08FH LD D,A LD A,C SRL A SRL A SRL A SRL A INC A AND 007H SLA A SLA A SLA A SLA A AND 070H OR D LD (GPUATTR),A ; Next Start X loop. LD A,(GPUSTARTX) INC A LD (GPUSTARTX),A CP 40 JP C, GPUNEXT0 JP GETL1 ; Second up, same as above but end co-ordinates are fixed. GPU2: XOR A LD (GPUCHAR),A LD (GPUATTR),A LD (GPUSTARTX),A GPUNEXT5: XOR A LD (GPUSTARTY),A ; Setup the GPU parameters to fill area. GPUNEXT6: LD A,(GPUSTARTX) OUT (GPUPARAM),A LD A,(GPUSTARTY) OUT (GPUPARAM),A LD A,39 OUT (GPUPARAM),A LD A,24 OUT (GPUPARAM),A LD A,(GPUCHAR) OUT (GPUPARAM),A LD A,(GPUATTR) OUT (GPUPARAM),A ; Issue the GPU command. LD A,GPUCLEARVRAMP OUT (GPUCMD),A ; Wait for the command to complete. GPUWAIT3: IN A,(GPUSTATUS) BIT 0,A JR NZ,GPUWAIT3 LD BC,0 GPUWAIT5: DEC BC LD A,B OR C JR NZ,GPUWAIT5 ; Setup the GPU parameters to clear area. LD A,(GPUSTARTX) OUT (GPUPARAM),A LD A,(GPUSTARTY) OUT (GPUPARAM),A LD A,(GPUENDX) OUT (GPUPARAM),A LD A,(GPUENDY) OUT (GPUPARAM),A LD A,000H ; Space OUT (GPUPARAM),A LD A,071H ; Default white on blue. OUT (GPUPARAM),A ; Issue the GPU command. LD A,GPUCLEARVRAMP OUT (GPUCMD),A ; Wait for the command to complete. GPUWAIT4: IN A,(GPUSTATUS) BIT 0,A JR NZ,GPUWAIT4 ; Adjust back colour. LD A,(GPUATTR) LD C,A AND 0F8H LD D,A LD A,C INC A AND 007H OR D LD (GPUATTR),A ; Next Start Y loop. LD A,(GPUSTARTY) INC A LD (GPUSTARTY),A CP 25 JP C, GPUNEXT6 ; Change the character. LD A,(GPUCHAR) INC A LD (GPUCHAR),A ; Adjust front colour. LD A,(GPUATTR) LD C,A AND 08FH LD D,A LD A,C SRL A SRL A SRL A SRL A INC A AND 007H SLA A SLA A SLA A SLA A AND 070H OR D LD (GPUATTR),A ; Next Start X loop. LD A,(GPUSTARTX) INC A LD (GPUSTARTX),A CP 40 JP C, GPUNEXT5 JP GETL1 ; Draw bars in descending colours prior to palette test. PALETTE: LD A,GPUCLEARVRAM OUT (GPUCMD),A ; Wait for the command to complete. PALWAIT1: IN A,(GPUSTATUS) BIT 0,A JR NZ,PALWAIT1 XOR A LD (GPUCHAR),A LD (GPUSTARTX),A LD (GPUSTARTY),A LD A,030H LD (GPUATTR),A ; Setup the GPU parameters to fill area. PALNEXT1: LD A,(GPUSTARTX) OUT (GPUPARAM),A LD A,(GPUSTARTY) OUT (GPUPARAM),A LD A,39 OUT (GPUPARAM),A LD A,24 OUT (GPUPARAM),A LD A,(GPUCHAR) OUT (GPUPARAM),A LD A,(GPUATTR) OUT (GPUPARAM),A ; Issue the GPU command. LD A,GPUCLEARVRAMP OUT (GPUCMD),A ; Wait for the command to complete. PALWAIT2: IN A,(GPUSTATUS) BIT 0,A JR NZ,PALWAIT2 ; Change the character. LD A,(GPUCHAR) INC A LD (GPUCHAR),A ; Adjust back colour. LD A,(GPUATTR) LD C,A AND 0F8H LD D,A LD A,C INC A AND 007H LD E,A OR D LD (GPUATTR),A ; Adjust front colour. LD A,(GPUATTR) LD C,A AND 08FH LD D,A LD A,C SRL A SRL A SRL A SRL A INC A AND 007H SLA A SLA A SLA A SLA A AND 070H OR D LD (GPUATTR),A ; Next Start Y loop. PALNEXT2: LD A,(GPUSTARTY) INC A LD (GPUSTARTY),A CP 25 JP C, PALNEXT1 LD A,0FFH ; Choose palette 255 for tests. OUT (VMPALETTE),A OUT (PALSLCTON),A ; Enable writes to the ON values of palette 255 ; LD E,0 ; Red LD D,0 ; Green LD L,0 ; Blue PALNEXT5: LD A,E OUT (PALSETRED),A LD A,D OUT (PALSETGREEN),A LD A,L OUT (PALSETBLUE),A LD BC,32768 PALWAIT4: DEC BC LD A,B OR C JR NZ,PALWAIT4 INC L LD A,L CP 020H JR C, PALNEXT5 LD L,0 INC D LD A,D CP 020H JR NZ, PALNEXT5 LD D,0 INC E LD A,E CP 020H JR NZ, PALNEXT5 XOR A PALNEXT3: OUT (VMPALETTE),A LD BC,0 PALWAIT3: DEC BC LD A,B OR C JR NZ,PALWAIT3 IN A, (VMPALETTE) INC A OR A JR NZ, PALNEXT3 JP GETL1 MEMTEST: LD B,240 ; Number of loops LOOP: LD HL,MEMSTART ; Start of checked memory, LD D,MEMCHKEND ; End memory check LOOP1: LD A,000h CP L JR NZ,LOOP1b CALL PRTHL ; Print HL as 4digit hex. LD A,0C4h ; Move cursor left. LD E,004h ; 4 times. LOOP1a: CALL DPCT DEC E JR NZ,LOOP1a LOOP1b: INC HL LD A,H CP D ; Have we reached end of memory. JR Z,LOOP3 ; Yes, exit. LD A,(HL) ; Read memory location under test, ie. 0. CPL ; Subtract, ie. FF - A, ie FF - 0 = FF. LD (HL),A ; Write it back, ie. FF. SUB (HL) ; Subtract written memory value from A, ie. should be 0. JR NZ,LOOP2 ; Not zero, we have an error. LD A,(HL) ; Reread memory location, ie. FF CPL ; Subtract FF - FF LD (HL),A ; Write 0 SUB (HL) ; Subtract 0 JR Z,LOOP1 ; Loop if the same, ie. 0 LOOP2: LD A,16h CALL PRNT ; Print A CALL PRTHX ; Print HL as 4 digit hex. CALL PRNTS ; Print space. XOR A LD (HL),A LD A,(HL) ; Get into A the failing bits. CALL PRTHX ; Print A as 2 digit hex. CALL PRNTS ; Print space. LD A,0FFh ; Repeat but first load FF into memory LD (HL),A LD A,(HL) CALL PRTHX ; Print A as 2 digit hex. NOP JR LOOP4 LOOP3: CALL PRTHL LD DE,OKCHECK CALL MSG ; Print check message in DE LD A,B ; Print loop count. CALL PRTHX LD DE,OKMSG CALL MSG ; Print ok message in DE CALL NL CALL GRPHIND DEC B JR NZ,LOOP LD DE,DONEMSG CALL MSG ; Print check message in DE JP GETL1 LOOP4: LD B,09h CALL PRNTS ; Print space. XOR A ; Zero A SCF ; Set Carry LOOP5: PUSH AF ; Store A and Flags LD (HL),A ; Store 0 to bad location. LD A,(HL) ; Read back CALL PRTHX ; Print A as 2 digit hex. CALL PRNTS ; Print space POP AF ; Get back A (ie. 0 + C) RLA ; Rotate left A. Bit LSB becomes Carry (ie. 1 first instance), Carry becomes MSB DJNZ LOOP5 ; Loop if not zero, ie. print out all bit locations written and read to memory to locate bad bit. XOR A ; Zero A, clears flags. LD A,80h LD B,08h LOOP6: PUSH AF ; Repeat above but AND memory location with original A (ie. 80) LD C,A ; Basically walk through all the bits to find which one is stuck. LD (HL),A LD A,(HL) AND C NOP JR Z,LOOP8 ; If zero then print out the bit number NOP NOP LD A,C CPL LD (HL),A LD A,(HL) AND C JR NZ,LOOP8 ; As above, if the compliment doesnt yield zero, print out the bit number. LOOP7: POP AF RRCA NOP DJNZ LOOP6 JP GETL1 LOOP8: CALL LETNL ; New line. LD DE,BITMSG ; BIT message CALL MSG ; Print message in DE LD A,B DEC A CALL PRTHX ; Print A as 2 digit hex, ie. BIT number. CALL LETNL ; New line LD DE,BANKMSG ; BANK message CALL MSG ; Print message in DE LD A,H CP 50h ; 'P' JR NC,LOOP9 ; Work out bank number, 1, 2 or 3. LD A,01h JR LOOP11 LOOP9: CP 90h JR NC,LOOP10 LD A,02h JR LOOP11 LOOP10: LD A,03h LOOP11: CALL PRTHX ; Print A as 2 digit hex, ie. BANK number. JR LOOP7 ; ; LOAD COMMAND ; LOAD: CALL ?RDI JP C,?ER LOA0: CALL NL LD DE,MSG_LOADFROM CALL MSG LD HL,(DTADR) CALL PRTHL CALL NL LD DE,MSG_LOADEXEC CALL MSG LD HL,(EXADR) CALL PRTHL CALL NL LD DE,MSG_LOADSIZE CALL MSG LD HL,(SIZE) CALL PRTHL CALL NL LD DE,MSG_LOADFILE CALL MSGX LD DE,NAME CALL MSGX CALL NL CALL ?RDD JP C,?ER LD HL,(EXADR) LD A,H CP 12h JP C,GETL1 JP (HL) ; SAVE COMMAND SAVE: LD HL,TESTBUF LD DE,IBUFE LD BC,128 LDIR LD DE,TITLE_SAVE CALL MSG CALL LETNL CALL LETNL LD DE,MSG_SAVEFROM CALL MSG LD HL,(DTADR) CALL PRTHL CALL NL LD DE,MSG_SAVEEXEC CALL MSG LD HL,(EXADR) CALL PRTHL CALL NL LD DE,MSG_SAVESIZE CALL MSG LD HL,(SIZE) CALL PRTHL CALL NL LD DE,MSG_SAVEFILE CALL MSGX LD DE,NAME CALL MSGX CALL NL LD A,01H ; ATTRIBUTE: OBJECT CODE LD (ATRB),A ; LD DE,MSG_WHDR CALL MSGX CALL NL CALL QWRI JP C,QER ; WRITE ERROR ; LD DE,MSG_WDATA CALL MSGX CALL NL ; CALL QWRD ; DATA JP C,QER CALL NL LD DE,MSGOK ; OK MESSAGE CALL MSGX ; CALL MSGX JP GETL1 ; ; ERROR (LOADING) ; QER: CP 02h JP Z,GETL1 LD DE,MSG_ERRWRITE CALL MSG JP GETL1 ; ; ERROR (LOADING) ; ?ER: CP 02h JP Z,GETL1 LD DE,MSG_ERRCHKSUM CALL MSG JP GETL1 ; ; READ INFORMATION ; ; EXIT ACC = 0 : OK CF=0 ; = 1 : ER CF=1 ; = 2 : BREAK CF=1 ; ?RDI: DI PUSH DE PUSH BC PUSH HL LD D,0D2h LD E,0CCh LD BC,80h LD HL,IBUFE RD1: CALL MOTOR JP C,RTP6 CALL TMARK JP C,RTP6 ; CALL PRTHL CALL RTAPE POP HL POP BC POP DE ;CALL MSTOP PUSH AF LD A,(TIMFG) CP 0F0h JR NZ,RD2 EI RD2: POP AF RET ; ; READ DATA ; ?RDD: DI PUSH DE PUSH BC PUSH HL LD D,0D2h LD E,53h LD BC,(SIZE) LD HL,(DTADR) LD A,B OR C JP Z,RDD1 JR RD1 RDD1: POP HL POP BC POP DE ;CALL MSTOP PUSH AF LD A,(TIMFG) CP 0F0h JR NZ,RDD2 EI RDD2: POP AF RET ; ; READ TAPE ; RTAPE: ;PUSH BC ;PUSH DE ;LD DE,MSG_READTAPE ;CALL MSG ;CALL NL ;POP DE ;POP BC PUSH DE PUSH BC PUSH HL LD H,2 RTP1: LD BC,KEYPB LD DE,CSTR RTP2: CALL EDGE JP C,RTP6 CALL DLY3 LD A,(DE) AND 20h JP Z,RTP2 LD D,H LD HL,0 LD (SUMDT),HL POP HL POP BC PUSH BC PUSH HL RTP3: CALL RBYTE JP C,RTP6 LD (HL),A INC HL DEC BC LD A,B OR C JP NZ,RTP3 LD HL,(SUMDT) CALL RBYTE ; Checksum MSB JP C,RTP6 LD D,A CALL RBYTE ; Checksum LSB JP C,RTP6 LD E,A CP L JP NZ,RTP5 LD A,D CP H JP NZ,RTP5 RTP0: XOR A ; PUSH HL PUSH DE PUSH DE LD DE,MSG_CHKSUM_MZ1 CALL MSGX CALL PRTHL CALL NL LD DE,MSG_CHKSUM_TP1 CALL MSGX POP DE EX DE,HL CALL PRTHL CALL NL POP DE POP HL ; RTP4: RET2: POP HL POP BC POP DE CALL MSTOP PUSH AF LD A,(TIMFG) CP 0F0h JR NZ,RTP8 EI RTP8: POP AF RET RTP5: PUSH HL PUSH DE PUSH DE LD DE,MSG_CHKSUM_MZ2 CALL MSGX CALL PRTHL CALL NL LD DE,MSG_CHKSUM_TP2 CALL MSGX POP DE EX DE,HL CALL PRTHL CALL NL POP DE POP HL ; LD D,1 DEC D JR Z,RTP7 LD H,D CALL GAPCK JP RTP1 RTP7: LD A,1 JR RTP9 RTP6: LD A,2 RTP9: SCF JR RTP4 ; ; EDGE ; BC = KEYPB ; DE = CSTR ; EXIT CF = 0 : EDGE ; = 1 : BREAK ; EDGE: LD A,0F0h LD (KEYPA),A NOP EDG1: LD A,(BC) AND 81h ; SHIFT & BREAK JP NZ,EDG0 SCF RET EDG0: LD A,(DE) AND 20h JP NZ,EDG1 EDG2: LD A,(BC) AND 81h JP NZ,EDG3 SCF RET EDG3: LD A,(DE) AND 20h JP Z,EDG2 RET ; ; 1 BYTE READ ; ; EXIT SUMDT=STORE ; CF = 1 : BREAK ; = 0 : DATA=ACC ; RBYTE: PUSH BC PUSH DE PUSH HL LD HL,0800h LD BC,KEYPB LD DE,CSTR RBY1: CALL EDGE JP C,RBY3 CALL DLY3 LD A,(DE) AND 20h JP Z,RBY2 PUSH HL LD HL,(SUMDT) INC HL LD (SUMDT),HL POP HL SCF RBY2: LD A,L RLA LD L,A DEC H JP NZ,RBY1 CALL EDGE LD A,L RBY3: POP HL POP DE POP BC RET ; ; TAPE MARK DETECT ; ; E=@L@ : INFORMATION ; =@S@ : DATA ; EXIT CF = 0 : OK ; = 1 : BREAK ; TMARK: CALL GAPCK PUSH BC PUSH DE PUSH HL PUSH BC PUSH DE LD DE,MSG_TAPEMARK CALL MSG CALL NL POP DE POP BC LD HL,2828h LD A,E CP 0CCh JP Z,TM0 LD HL,1414h TM0: LD (TMCNT),HL LD BC,KEYPB LD DE,CSTR TM1: LD HL,(TMCNT) TM2: CALL EDGE JP C,TM4 CALL DLY3 LD A,(DE) AND 20h JP Z,TM1 DEC H JP NZ,TM2 ; CALL PRTHL TM3: CALL EDGE JP C,TM4 CALL DLY3 LD A,(DE) AND 20h JP NZ,TM1 DEC L JP NZ,TM3 CALL EDGE RET3: TM4: POP HL POP DE POP BC RET TM4A: CALL NL CALL PRTHL ; Print HL as 4digit hex. LD A,0C4h ; Move cursor left. TM4B: CALL DPCT CALL DPCT CALL DPCT CALL DPCT CALL NL JP GETL1 ; ; MOTOR ON ; ; D=@W@ : WRITE ; =@R@ : READ ; EXIT CF=0 : OK ; =1 : BREAK MOTOR: PUSH BC PUSH DE PUSH HL PUSH BC PUSH DE LD DE,MSG_MOTORTG CALL MSG CALL NL POP DE POP BC LD B,10 MOT1: LD A,(CSTR) AND 10h JR Z,MOT4 MOT2: LD B,0A6h MOT3: CALL DLY12 DJNZ MOT3 XOR A MOT7: JR RET3 MOT4: LD A,06h LD HL,CSTPT LD (HL),A INC A LD (HL),A DJNZ MOT1 CALL NL LD A,D CP 0D7h JR Z,MOT8 LD DE,MSG1 JR MOT9 MOT8: LD DE,MSG3 CALL MSGX LD DE,MSG2 MOT9: CALL MSGX MOT5: LD A,(CSTR) AND 10h JR NZ,MOT2 CALL ?BRK JR NZ,MOT5 SCF JR MOT7 ; ; MOTOR STOP ; MSTOP: PUSH AF PUSH BC PUSH DE PUSH BC PUSH DE LD DE,MSG_MOTORSTP CALL MSG CALL NL POP DE POP BC LD B,10 MST1: LD A,(CSTR) AND 10H JR Z,MST3 MST2: LD A,06h LD (CSTPT),A INC A LD (CSTPT),A DJNZ MST1 MST3: JP ?RSTR1 ; ; CHECK SUM ; ; BC = SIZE ; HL = DATA ADR ; EXIT SUMDT=STORE ; CSMDT=STORE ; CKSUM: PUSH BC PUSH DE PUSH HL LD DE,0 CKS1: LD A,B OR C JR NZ,CKS2 EX DE,HL LD (SUMDT),HL LD (CSMDT),HL POP HL POP DE POP BC RET CKS2: LD A,(HL) PUSH BC LD B,+8 CKS3: RLCA JR NC,CKS4 INC DE CKS4: DJNZ CKS3 POP BC INC HL DEC BC JR CKS1 ; ; 107 uS DELAY ; DLY1: LD A,14 DLY1A: DEC A JP NZ,DLY1A RET ; ; 240 uS DELAY ; DLY2: LD A,13 DLY2A: DEC A JP NZ,DLY2A RET ; ; 240 uS x 3 DELAY ; DLY3: NEG NEG LD A,42 JP DLY2A ; ; 12mS DELAY DLY12: PUSH BC LD B,35 DLY12A: CALL DLY3 DJNZ DLY12A POP BC RET ; ; GAP * TAPEMARK ; ; E = @L@ : LONG GAP ; = @S@ : SHORT GAP ; GAP: PUSH BC PUSH DE PUSH HL LD A,E LD BC,55F0h ;Number of pulses for the Long Gap. LD DE,2828h ;40 + 40 LTM CP 0CCh JP Z,GAP0 LD BC,2AF8h ;Number of pulses for a Short Gap. LD DE,1414h ;20 + 20 LTM GAP0: PUSH DE LD DE,MSG_WGAPS CALL MSG ; GAP1: CALL SHORT ;22000 short GAP pulses. LD H,B LD L,C LD A,000h CP L JR NZ,GAP1D CALL PRTHL ; Print HL as 4digit hex. LD A,0C4h ; Move cursor left. LD E,004h ; 4 times. GAP1B: CALL DPCT DEC E JR NZ,GAP1B GAP1D: DEC BC LD A,B OR C JR NZ,GAP1 LD H,B LD L,C CALL PRTHL ; Print HL as 4digit hex. LD DE,MSG_SPC CALL MSG CALL LETNL POP DE ; LD BC,20000 ; 2 Second delay GAP1C: CALL DLY1 DEC BC LD A,B OR C JR NZ,GAP1C ; PUSH DE GAP1A: LD DE,MSG_WGAPL CALL MSGX POP DE GAP2: PUSH DE CALL LONG ;40 or 20 Long Pulses (LTM or STM) LD H,00h LD L,D CALL PRTHL ; Print HL as 4digit hex. LD A,0C4h ; Move cursor left. LD E,004h ; 4 times. GAP2B: CALL DPCT DEC E JR NZ,GAP2B LD BC,1000 ; .1 Second delay GAP2D: CALL DLY1 DEC BC LD A,B OR C JR NZ,GAP2D POP DE DEC D JR NZ,GAP2 LD H,000h LD L,D CALL PRTHL ; Print HL as 4digit hex. PUSH DE LD DE,MSG_SPC CALL MSG CALL LETNL POP DE ; LD BC,20000 ; 2 Second delay GAP2C: CALL DLY1 DEC BC LD A,B OR C JR NZ,GAP2C ; GAP2A: PUSH DE LD DE,MSG_WGAPS2 CALL MSGX POP DE GAP3: PUSH DE CALL SHORT ;40 or 20 Short Pulses (LTM or STM) LD H,00h LD L,E CALL PRTHL ; Print HL as 4digit hex. LD A,0C4h ; Move cursor left. LD E,004h ; 4 times. GAP3B: CALL DPCT DEC E JR NZ,GAP3B LD BC,1000 ; .1 Second delay GAP3D: CALL DLY1 DEC BC LD A,B OR C JR NZ,GAP3D POP DE DEC E JR NZ,GAP3 LD H,000h LD L,E CALL PRTHL ; Print HL as 4digit hex. PUSH DE LD DE,MSG_SPC CALL MSGX CALL LETNL POP DE ; LD BC,20000 ; 2 Second delay GAP3C: CALL DLY1 DEC BC LD A,B OR C JR NZ,GAP3C ; GAP3A: PUSH DE LD DE,MSG_WGAPL2 CALL MSGX CALL LETNL POP DE CALL LONG ;1 Long Pulse POP HL POP DE POP BC RET ;GAP Test - fixed 80 x short, 80 x long to see if hardware is receiving and counting correctly. ; ;GAP: PUSH BC ; PUSH DE ;GAP0: LD BC,050h ;Number of pulses for the Long Gap. ;GAP1: CALL SHORT ;GAP1A: DEC BC ; LD A,B ; OR C ; JR NZ,GAP1 ; LD BC,0050h ;Number of pulses for the Long Gap. ;GAP2: CALL LONG ;GAP2A: DEC BC ; LD A,B ; OR C ; JR NZ,GAP2 ;GAP3A: JR GAP3A ;GAP3: POP DE ; POP BC ; RET ; ; GAP CHECK ; GAPCK: PUSH BC PUSH DE PUSH HL LD DE,MSG_GAPCK CALL MSG CALL NL LD BC,KEYPB LD DE,CSTR GAPCK1: LD H,100 GAPCK2: CALL EDGE JR C,GAPCK3 CALL DLY3 LD A,(DE) AND 20h JR NZ,GAPCK1 DEC H JR NZ,GAPCK2 GAPCK3: JP RET3 ; ; 1 bit write ; Short Pulse ; SHORT: PUSH AF LD A,03h LD (CSTPT),A CALL DLY1 CALL DLY1 LD A,02h LD (CSTPT),A CALL DLY1 CALL DLY1 POP AF RET ; ; 1 bit write ; Long Pulse ; LONG: PUSH AF LD A,03h LD (CSTPT),A CALL DLY1 CALL DLY1 CALL DLY1 CALL DLY1 LD A,02h LD (CSTPT),A CALL DLY1 CALL DLY1 CALL DLY1 CALL DLY2 POP AF RET ; WRITE INFORMATION QWRI: DI PUSH DE PUSH BC PUSH HL LD D,0D7H ; "W" LD E,0CCH ; "L" LD HL,IBUFE ; 10F0H LD BC,80H ; WRITE BYTE SIZE WRI1: CALL CKSUM ; CHECK SUM CALL MOTOR ; MOTOR ON JR C,WRI3 LD A,E CP 0CCH ; "L" - Long Gap/Tape Mark? JR NZ,WRI2 CALL NL PUSH DE LD DE,MSGN7 ; WRITING RST 18H ; CALL MSGX LD DE,NAME ; FILE NAME RST 18H ; CALL MSGX CALL NL POP DE WRI2: CALL GAP CALL WTAPE WRI3: JP RET2 ; WRITE DATA ; EXIT CF=0 : OK ; =1 : BREAK QWRD: DI PUSH DE PUSH BC PUSH HL LD D,0D7H ; "W" LD E,53H ; "S" L047D: LD BC,(SIZE) ; WRITE DATA BYTE SIZE LD HL,(DTADR) ; WRITE DATA ADDRESS LD A,B OR C JP Z,RET1 JR WRI1 ; TAPE WRITE ; BC=BYTE SIZE ; HL=DATA LOW ADDRESS ; EXIT CF=0 : OK ; =1 : BREAK WTAPE: PUSH DE PUSH BC PUSH HL LD D,02H LD A,0F0H ; 88H WOULD BE BETTER!! LD (KEYPA),A ; E000H WTAP1: LD A,(HL) CALL WBYTE ; 1 BYTE WRITE LD A,(KEYPB) ; E001H AND 81H ; SHIFT & BREAK JP NZ,WTAP2 LD A,02H ; BREAK IN CODE SCF JR WTAP3 WTAP2: INC HL DEC BC LD A,B OR C JP NZ,WTAP1 LD HL,(SUMDT) ; SUM DATA SET LD A,H CALL WBYTE ; Send Checksum LD A,L CALL WBYTE WTAP3A: PUSH DE LD DE,MSG_WGAPL2 CALL MSGX CALL LETNL POP DE CALL LONG DEC D JP NZ,L04C2 ; Another copy to be sent? OR A JP WTAP3 L04C2: PUSH DE LD DE,MSG_SPCS CALL MSGX POP DE LD B,0 ; Send 256 short pulses. L04C4: CALL SHORT LD H,00h LD L,B CALL PRTHL ; Print HL as 4digit hex. LD A,0C4h ; Move cursor left. LD E,004h ; 4 times. SPCS2: CALL DPCT DEC E JR NZ,SPCS2 DEC B JP NZ,L04C4 LD H,00h LD L,B CALL PRTHL ; Print HL as 4digit hex. LD BC,2500 ; .25 Second delay SPCS3: CALL DLY1 DEC BC LD A,B OR C JR NZ,SPCS3 CALL LETNL POP HL ; Retrieve saved location and size POP BC PUSH BC PUSH HL JP WTAP1 ; Repeat send. WTAP3: RET1: POP HL POP BC POP DE RET DB 2FH DB 4EH ; VERIFY (FROM $CMT) ; EXIT ACC=0 : OK CF=0 ; =1 : ER CF=1 ; =2 : BREAK CF=1 QVRFY: DI PUSH DE PUSH BC PUSH HL LD BC,(SIZE) LD HL,(DTADR) LD D,0D2H ; "R" LD E,53H ; "S" LD A,B OR C JP Z,RTP4 ; END CALL CKSUM CALL MOTOR JP C,RTP6 ; BRK CALL TMARK ; TAPE MARK DETECT JP C,RTP6 ; BRK CALL TVRFY JP RTP4 ; DATA VERIFY ; BC=SIZE ; HL=DATA LOW ADDRESS ; CSMDT=CHECK SUM ; EXIT ACC=0 : OK CF=0 ; =1 : ER =1 ; =2 : BREAK =1 TVRFY: PUSH DE PUSH BC PUSH HL LD H,02H ; COMPARE TWICE TVF1: LD BC,KEYPB LD DE,CSTR TVF2: CALL EDGE JP C,RTP6 ; BRK CALL DLY3 ; CALL DLY2*3 LD A,(DE) AND 20H JP Z,TVF2 LD D,H POP HL POP BC PUSH BC PUSH HL ; COMPARE TAPE DATA AND STORAGE TVF3: CALL RBYTE JP C,RTP6 ; BRK CP (HL) JP NZ,RTP7 ; ERROR, NOT EQUAL INC HL ; STORAGE ADDRESS + 1 DEC BC ; SIZE - 1 LD A,B OR C JR NZ,TVF3 ; COMPARE CHECK SUM (1199H/CSMDT) AND TAPE LD HL,(CSMDT) CALL RBYTE CP H JP NZ,RTP7 ; ERROR, NOT EQUAL CALL RBYTE CP L JP NZ,RTP7 ; ERROR, NOT EQUAL DEC D ; NUMBER OF COMPARES (2) - 1 JP Z,RTP8 ; OK, 2 COMPARES LD H,D ; (-->05C7H), SAVE NUMBER OF COMPARES JR TVF1 ; NEXT COMPARE ; 1 BYTE WRITE WBYTE: PUSH BC LD B,8 CALL LONG WBY1: RLCA CALL C,LONG CALL NC,SHORT DEC B JP NZ,WBY1 POP BC RET ARARA: POP HL JP ABCD DLY1S: PUSH AF PUSH BC LD C,10 L0324: CALL DLY12 DEC C JR NZ,L0324 POP BC POP AF RET ; Test the 8253 Timer, configure it as per the monitor and display the read back values. TIMERTST: CALL NL LD DE,MSG_TIMERTST CALL MSG CALL NL LD DE,MSG_TIMERVAL CALL MSG LD A,01h LD DE,8000h CALL ?TMST NDE: JP NDE JP GETL1 ?TMST: DI PUSH BC PUSH DE PUSH HL LD (AMPM),A LD A,0F0H LD (TIMFG),A ABCD: LD HL,0A8C0H XOR A SBC HL,DE PUSH HL INC HL EX DE,HL LD HL,CONTF ; Control Register LD (HL),0B0H ; 10110000 Control Counter 2 10, Write 2 bytes 11, 000 Interrupt on Terminal Count, 0 16 bit binary LD (HL),074H ; 01110100 Control Counter 1 01, Write 2 bytes 11, 010 Rate Generator, 0 16 bit binary LD (HL),030H ; 00110100 Control Counter 1 01, Write 2 bytes 11, 010 interrupt on Terminal Count, 0 16 bit binary LD HL,CONT2 ; Counter 2 LD (HL),E LD (HL),D LD HL,CONT1 ; Counter 1 LD (HL),00AH LD (HL),000H LD HL,CONT0 ; Counter 0 LD (HL),00CH LD (HL),0C0H ; LD HL,CONT2 ; Counter 2 ; LD C,(HL) ; LD A,(HL) ; CP D ; JP NZ,L0323 ; LD A,C ; CP E ; JP Z,CDEF ; L0323: PUSH AF PUSH BC PUSH DE PUSH HL ; LD HL,CONTF ; Control Register LD (HL),080H LD HL,CONT2 ; Counter 2 LD C,(HL) LD A,(HL) CALL PRTHX LD A,C CALL PRTHX ; CALL PRNTS ;CALL DLY1S ; LD HL,CONTF ; Control Register LD (HL),040H LD HL,CONT1 ; Counter 1 LD C,(HL) LD A,(HL) CALL PRTHX LD A,C CALL PRTHX ; CALL PRNTS ;CALL DLY1S ; LD HL,CONTF ; Control Register LD (HL),000H LD HL,CONT0 ; Counter 0 LD C,(HL) LD A,(HL) CALL PRTHX LD A,C CALL PRTHX ; ;CALL DLY1S ; LD A,0C4h ; Move cursor left. LD E,0Eh ; 4 times. L0330: CALL DPCT DEC E JR NZ,L0330 ; ; LD C,20 ;L0324: CALL DLY12 ; DEC C ; JR NZ,L0324 ; POP HL POP DE POP BC POP AF ; LD HL,CONT2 ; Counter 2 LD C,(HL) LD A,(HL) CP D JP NZ,L0323 LD A,C CP E JP NZ,L0323 ; ; PUSH AF PUSH BC PUSH DE PUSH HL CALL NL CALL NL CALL NL LD DE,MSG_TIMERVAL2 CALL MSG POP HL POP DE POP BC POP AF ; CDEF: POP DE LD HL,CONT1 LD (HL),00CH LD (HL),07BH INC HL L0336: PUSH AF PUSH BC PUSH DE PUSH HL ; LD HL,CONTF ; Control Register LD (HL),080H LD HL,CONT2 ; Counter 2 LD C,(HL) LD A,(HL) CALL PRTHX LD A,C CALL PRTHX ; CALL PRNTS CALL DLY1S ; LD HL,CONTF ; Control Register LD (HL),040H LD HL,CONT1 ; Counter 1 LD C,(HL) LD A,(HL) CALL PRTHX LD A,C CALL PRTHX ; CALL PRNTS CALL DLY1S ; LD HL,CONTF ; Control Register LD (HL),000H LD HL,CONT0 ; Counter 0 LD C,(HL) LD A,(HL) CALL PRTHX LD A,C CALL PRTHX ; CALL DLY1S ; LD A,0C4h ; Move cursor left. LD E,0Eh ; 4 times. L0340: CALL DPCT DEC E JR NZ,L0340 ; POP HL POP DE POP BC POP AF LD HL,CONT2 ; Counter 2 LD C,(HL) LD A,(HL) CP D JR NZ,L0336 LD A,C CP E JR NZ,L0336 CALL NL LD DE,MSG_TIMERVAL3 CALL MSG POP HL POP DE POP BC EI RET ?TMRD: PUSH HL LD HL,CONTF LD (HL),080H DEC HL DI LD E,(HL) LD D,(HL) EI LD A,E OR D JR Z,?TMR1 XOR A LD HL,0A8C0H SBC HL,DE JR C,?TMR2 EX DE,HL LD A,(AMPM) POP HL RET ?TMR1: LD DE,0A8C0H ?TMR1A: LD A,(AMPM) XOR 001H POP HL RET ?TMR2: DI LD HL,CONT2 LD A,(HL) CPL LD E,A LD A,(HL) CPL LD D,A EI INC DE JR ?TMR1A TIMIN: PUSH AF PUSH BC PUSH DE PUSH HL LD HL,AMPM LD A,(HL) XOR 001H LD (HL),A LD HL,CONTF LD (HL),080H DEC HL PUSH HL LD E,(HL) LD D,(HL) LD HL,0A8C0H ADD HL,DE DEC HL DEC HL EX DE,HL POP HL LD (HL),E LD (HL),D POP HL POP DE POP BC POP AF EI RET ; Method to clear memory either to 0 or a given pattern. ; CLR8Z: XOR A CLR8: LD BC,00800H CLRMEM: PUSH DE LD D,A L09E8: LD (HL),D INC HL DEC BC LD A,B OR C JR NZ,L09E8 POP DE RET ; Help/Synoposis of commands available. ; HELP: CALL LETNL LD DE,MSG_HELP1 CALL MSG CALL LETNL LD DE,MSG_HELP2 CALL MSG CALL LETNL LD DE,MSG_HELP3 CALL MSG CALL LETNL LD DE,MSG_HELP4 CALL MSG CALL LETNL LD DE,MSG_HELP5 CALL MSG CALL LETNL LD DE,MSG_HELP6 CALL MSG CALL LETNL LD DE,MSG_HELP7 CALL MSG CALL LETNL LD DE,MSG_HELP8 CALL MSG CALL LETNL LD DE,MSG_HELP9 CALL MSG CALL LETNL CALL LETNL JP GETL1 TMPADR: DW 00000H GPUCHAR: DW 00000H GPUATTR: DW 00000H GPUSTARTX: DW 00000H GPUSTARTY: DW 00000H GPUENDX: DW 00000H GPUENDY: DW 00000H MSG_HELP1: DB "GRPH[1-2]= TEST GRAPHICS", 0Dh, 00h MSG_HELP2: DB "GPU[1-2] = TEST GPU", 0Dh, 00h MSG_HELP3: DB "PAL = TEST PALETTE", 0Dh, 00h MSG_HELP4: DB "MEMTEST = TEST MEMORY", 0Dh, 00h MSG_HELP5: DB "LOAD = LOAD TAPE", 0Dh, 00h MSG_HELP6: DB "TIMER = TIMER TEST", 0Dh, 00h MSG_HELP7: DB "SAVE = WRITE TEST TAPE", 0Dh, 00h MSG_HELP8: DB "VGA[0-3] = SET VGA MODE", 0Dh, 00h MSG_HELP9: DB "QUIT = QUIT TO MONITOR", 0Dh, 00h TITLE: DB "SHARPMZ TESTER (C) P.SMART 2018-20", 0Dh, 00h MSG_INITGR:DB "INIT GRAPHICS", 0Dh MSG_INITM: DB "INIT MEMORY", 0Dh TITLE_SAVE:DB "WRITE TEST TAPE", 0Dh MSGBADCMD: DB "???", 0DH, 00H MSG1: DW 207Fh MSG2: DB "PLAY", 0Dh, 00h MSG3: DW 207Fh ; PRESS RECORD DB "RECORD.", 0Dh, 00h MSGN7: DB "WRITING ", 0Dh, 00h MSGOK: DB "OK", 0Dh, 00h MSG_ERRCHKSUM: DB "CHECKSUM ERROR", 0Dh MSG_ERRWRITE: DB "WRITE ERROR", 0Dh MSG_READTAPE: DB "READ TAPE", 0Dh, 00h MSG_TAPEMARK: DB "TAPEMARK", 0Dh, 00h MSG_MOTORTG: DB "MOTOR TOGGLE", 0Dh, 00h MSG_MOTORSTP: DB "MOTOR STOP", 0Dh, 00h MSG_TPMARK: DB "TAPE MARK START", 0Dh, 00h MSG_GAPCK: DB "GAP CHECK", 0Dh, 00h MSG_LOADFILE: DB "LOAD FILE = ",0Dh, 00h MSG_LOADFROM: DB "LOAD ADDRESS = ", 0Dh, 00h MSG_LOADEXEC: DB "EXEC ADDRESS = ", 0Dh, 00h MSG_LOADSIZE: DB "LOAD SIZE = ", 0Dh, 00h MSG_SAVEFILE: DB "SAVE FILE = ",0Dh, 00h MSG_SAVEFROM: DB "SAVE ADDRESS = ", 0Dh, 00h MSG_SAVEEXEC: DB "SAVE EXEC ADDRESS = ", 0Dh, 00h MSG_SAVESIZE: DB "SAVE SIZE = ", 0Dh, 00h MSG_CHKSUM_MZ1: DB " MZ CHECKSUM (OK) = ", 0Dh, 00h MSG_CHKSUM_TP1: DB "TAPE CHECKSUM (OK) = ", 0Dh, 00h MSG_CHKSUM_MZ2: DB " MZ CHECKSUM (ER) = ", 0Dh, 00h MSG_CHKSUM_TP2: DB "TAPE CHECKSUM (ER) = ", 0Dh, 00h MSG_WHDR: DB "WRITE HEADER...", 0Dh MSG_WDATA: DB "WRITE DATA...", 0Dh MSGGAP: DB "GAP WRITTEN", 0Dh, 00h MSG_WGAPS: DB "WRITE GAP: ", 0Dh, 00h MSG_WGAPS2:DB "WRITE TM SHORT: ", 0Dh, 00h MSG_WGAPL: DB "WRITE TM LONG: ", 0Dh, 00h MSG_WGAPL2:DB "WRITE 1 LONG BIT", 0Dh, 00h MSG_SPCS: DB "WRITE 256 SHORT: ", 0Dh, 00h MSG_SPC: DB ", WAIT.", 0Dh, 00h MSGTAPE DB "HEADER WRITTEN", 0Dh, 00h MSG_TIMERTST: DB "8253 TIMER TEST", 0Dh, 00h MSG_TIMERVAL: DB "READ VALUE 1: ", 0Dh, 00h MSG_TIMERVAL2: DB "READ VALUE 2: ", 0Dh, 00h MSG_TIMERVAL3: DB "READ DONE.", 0Dh, 00h OKCHECK: DB ", CHECK: ", 0Dh OKMSG: DB " OK.", 0Dh DONEMSG: DB 11h DB "RAM TEST COMPLETE.", 0Dh BITMSG: DB " BIT: ", 0Dh BANKMSG: DB " BANK: ", 0Dh GRPHPOS: DB 00h, 00h ; Test tape image to save. TESTBUF: ; TAPE BUFFER (128 BYTES) TATRB: DB 02h ; Code Type, 01 = Machine Code. TNAME: DB "TEST TAPE SAVE", 0Dh, 00h, 00h ; Title/Name (17 bytes). TSIZE: DW TESTEND - TESTSTART ; Size of program. TDTADR: DW TESTSTART ; Load address of program. TEXADR: DW TESTSTART ; Exec address of program. TCOMNT: DB "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" TESTSTART: DB 01h DB 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 DB 16,17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 DB 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 DB 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63 DB 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79 DB 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95 DB 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111 DB 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127 DB 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143 DB 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159 DB 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175 DB 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191 DB 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207 DB 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223 DB 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239 DB 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 TESTEND: MEND: