From 0ccc5d5a1102fa941ae3b9d9569f8a7134fe65a1 Mon Sep 17 00:00:00 2001 From: Philip Smart Date: Sun, 26 Feb 2023 19:38:01 +0000 Subject: [PATCH] Updates to support an assembler/disassembler and new commands. --- Basic | 2 +- asm/include/tzfs_definitions.asm | 8 +- asm/include/tzfs_mondef.asm | 3 +- asm/include/tzfs_svcstruct.asm | 3 +- asm/include/tzfs_utilities.asm | 3 +- asm/include/tzfs_variables.asm | 3 +- asm/sa-5510_tzfs.asm | 4 +- asm/sa1510.asm | 6 +- asm/tzfs.asm | 264 ++- asm/tzfs_bank2.asm | 163 +- asm/tzfs_bank3.asm | 127 +- asm/tzfs_bank4.asm | 1668 ++++++++++++++++- ...pm22_mz80a_std.hdr => cpm22_mz80a_40c.hdr} | Bin roms/mz80afi.rom | Bin 2048 -> 2048 bytes roms/tzfs.rom | Bin 18432 -> 67072 bytes tools/assemble_cpm.sh | 2 +- 16 files changed, 2049 insertions(+), 207 deletions(-) rename hdr/{cpm22_mz80a_std.hdr => cpm22_mz80a_40c.hdr} (100%) diff --git a/Basic b/Basic index 46b7cfa..4d14dc7 120000 --- a/Basic +++ b/Basic @@ -1 +1 @@ -/dvlp/Projects/SharpSoft/Basic \ No newline at end of file +../SharpSoft/Basic \ No newline at end of file diff --git a/asm/include/tzfs_definitions.asm b/asm/include/tzfs_definitions.asm index 4d27e9d..6390f17 100644 --- a/asm/include/tzfs_definitions.asm +++ b/asm/include/tzfs_definitions.asm @@ -10,10 +10,11 @@ ;- I/O processor in the K64F/ZPU. ;- ;- Credits: -;- Copyright: (c) 2019-21 Philip Smart +;- Copyright: (c) 2018-2023 Philip Smart ;- ;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW. ;- July 2020 - Updates to accommodate v2.1 of the tranZPUter board. +;- Feb 2023 - TZFS now running on FusionX. Small changes to ensure compatibility. ;- ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify @@ -33,9 +34,10 @@ ;----------------------------------------------- ; Features. ;----------------------------------------------- -BUILD_MZ80A EQU 0 ; Build for the standard Sharp MZ80A, no lower memory. -BUILD_MZ700 EQU 1 ; Build for the Sharp MZ-700 base hardware. +BUILD_MZ80A EQU 1 ; Build for the standard Sharp MZ80A, no lower memory. +BUILD_MZ700 EQU 0 ; Build for the Sharp MZ-700 base hardware. BUILD_MZ2000 EQU 0 ; Build for the Sharp MZ-2000 base hardware. +BUILD_FUSIONX EQU 1 ; Build for the set host using the FusionX board. ; Debugging ENADEBUG EQU 0 ; Enable debugging logic, 1 = enable, 0 = disable diff --git a/asm/include/tzfs_mondef.asm b/asm/include/tzfs_mondef.asm index dfdf92a..a143f2b 100644 --- a/asm/include/tzfs_mondef.asm +++ b/asm/include/tzfs_mondef.asm @@ -12,10 +12,11 @@ ;- This file contains the SA-1510/1Z-013A monitor specific definitions. ;- ;- Credits: -;- Copyright: (c) 2019-21 Philip Smart +;- Copyright: (c) 2018-2023 Philip Smart ;- ;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW. ;- July 2020 - Updates to accommodate v2.1 of the tranZPUter board. +;- Feb 2023 - TZFS now running on FusionX. Small changes to ensure compatibility. ;- ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify diff --git a/asm/include/tzfs_svcstruct.asm b/asm/include/tzfs_svcstruct.asm index 006cb19..8ad4ae1 100644 --- a/asm/include/tzfs_svcstruct.asm +++ b/asm/include/tzfs_svcstruct.asm @@ -12,10 +12,11 @@ ;- This file holds the TZFS service structure definition. ;- ;- Credits: -;- Copyright: (c) 2019-21 Philip Smart +;- Copyright: (c) 2018-2023 Philip Smart ;- ;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW. ;- July 2020 - Updates to accommodate v2.1 of the tranZPUter board. +;- Feb 2023 - TZFS now running on FusionX. Small changes to ensure compatibility. ;- ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify diff --git a/asm/include/tzfs_utilities.asm b/asm/include/tzfs_utilities.asm index e1b3761..02fdbd3 100644 --- a/asm/include/tzfs_utilities.asm +++ b/asm/include/tzfs_utilities.asm @@ -10,9 +10,10 @@ ;- I/O processor in the K64F/ZPU. ;- ;- Credits: -;- Copyright: (c) 2019-20 Philip Smart +;- Copyright: (c) 2018-2023 Philip Smart ;- ;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW. +;- Feb 2023 - TZFS now running on FusionX. Small changes to ensure compatibility. ;- ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify diff --git a/asm/include/tzfs_variables.asm b/asm/include/tzfs_variables.asm index 09e26d0..ca6e13a 100644 --- a/asm/include/tzfs_variables.asm +++ b/asm/include/tzfs_variables.asm @@ -12,10 +12,11 @@ ;- This file holds the TZFS variable definitions. ;- ;- Credits: -;- Copyright: (c) 2019-21 Philip Smart +;- Copyright: (c) 2018-2023 Philip Smart ;- ;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW. ;- July 2020 - Updates to accommodate v2.1 of the tranZPUter board. +;- Feb 2023 - TZFS now running on FusionX. Small changes to ensure compatibility. ;- ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify diff --git a/asm/sa-5510_tzfs.asm b/asm/sa-5510_tzfs.asm index 03f6612..304aff8 100644 --- a/asm/sa-5510_tzfs.asm +++ b/asm/sa-5510_tzfs.asm @@ -126,10 +126,10 @@ QWRD EQU CMT_WRDATA ; Declare the MZF header to bootstrap BASIC from tape/SD. BOOTATRB: DB 01h ; Code Type, 01 = Machine Code. BOOTNAME: IF BUILD_ORIG = 1 - DB "BASIC SA-5510 ", 0Dh ; Title/Name (17 bytes). + DB "BASIC-SA-5510 ", 0Dh ; Title/Name (17 bytes). ENDIF IF BUILD_TZFS = 1 - DB "BASIC SA-5510-TZ", 0Dh ; Title/Name (17 bytes). + DB "BASIC-SA-5510-TZ", 0Dh ; Title/Name (17 bytes). ENDIF BOOTSIZE: DW BASICEND - TAPECOPY ; Size of program. BOOTDTADR: DW TAPECOPY ; Load address of program. diff --git a/asm/sa1510.asm b/asm/sa1510.asm index 759f957..63e78cd 100644 --- a/asm/sa1510.asm +++ b/asm/sa1510.asm @@ -667,16 +667,16 @@ HOM0: LD HL,00000H INC L HLHEX: PUSH DE - CALL L041F + CALL _2HEX JR C,L041D LD H,A - CALL L041F + CALL _2HEX JR C,L041D LD L,A L041D: POP DE RET -L041F: PUSH BC +_2HEX: PUSH BC LD A,(DE) INC DE CALL HEX diff --git a/asm/tzfs.asm b/asm/tzfs.asm index 47f496b..ae96a2e 100644 --- a/asm/tzfs.asm +++ b/asm/tzfs.asm @@ -10,25 +10,28 @@ ;- I/O processor in the K64F/ZPU. ;- ;- Credits: -;- Copyright: (c) 2018-2020 Philip Smart +;- Copyright: (c) 2018-2023 Philip Smart ;- -;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW. -;- July 2020 - Not many changes but updated version to v1.1 to coincide with the -;- hardware v1.1 version, thus differentiating between v1.0 board and v1.1. -;- July 2020 - Updates to accomodate the v2.1 hardware. Additional commands and fixed a -;- few bugs like the load from card by name! -;- Dec 2020 - Updates to accommodate v1.3 of the tranZPUter SW-700 board where soft -;- CPU's now become possible. -;- Jan 2021 - Additional changes to accommodate soft CPU's. -;- Mar 2021 - Bug fixes - MZ-700/MZ-80A address differences. -;- - Added optional machine model code on load command to enable 700/800 -;- programs to be loaded without changing the MZ800 mode switch. -;- Apr 2021 - Added 40/80 Colour Card control. Reorganised to free up space. -;- Apr 2021 - Updated to add ?RDI/?RDD/?WRI/?WRD/DIR/CD methods to ease conversion of -;- programs from cassette storage to SD storage, first conversion being -;- BASIC SA-5510. -;- Jul 2021 - Updated the CMT routines to now be configurable so that all MZ series -;- are catered for, ie. read/write 80B machines. +;- History: May 2020 v1.0 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW. +;- July 2020 v1.1 - Not many changes but updated version to v1.1 to coincide with the +;- hardware v1.1 version, thus differentiating between v1.0 board and v1.1. +;- July 2020 - Updates to accomodate the v2.1 hardware. Additional commands and fixed a +;- few bugs like the load from card by name! +;- Dec 2020 - Updates to accommodate v1.3 of the tranZPUter SW-700 board where soft +;- CPU's now become possible. +;- Jan 2021 - Additional changes to accommodate soft CPU's. +;- Mar 2021 - Bug fixes - MZ-700/MZ-80A address differences. +;- - Added optional machine model code on load command to enable 700/800 +;- programs to be loaded without changing the MZ800 mode switch. +;- Apr 2021 - Added 40/80 Colour Card control. Reorganised to free up space. +;- Apr 2021 v1.5 - Updated to add ?RDI/?RDD/?WRI/?WRD/DIR/CD methods to ease conversion of +;- programs from cassette storage to SD storage, first conversion being +;- BASIC SA-5510. +;- Jul 2021 v1.6 - Updated the CMT routines to now be configurable so that all MZ series +;- are catered for, ie. read/write 80B machines. +;- Feb 2023 v1.7 - TZFS now running on FusionX. Changes to ensure compatibility and +;- addition of new commands, assemble, disassemble, fill, write I/O, +;- read I/O. ;- ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify @@ -129,17 +132,28 @@ SET_FREQ: JP ?SETFREQ ; UROMA ?PRTSTR: CALLBNK PRTSTR, TZMM_TZFS2 ?HELP: CALLBNK HELP, TZMM_TZFS2 ?MCORX: CALLBNK MCORX, TZMM_TZFS3 +?COPYM: CALLBNK COPYM, TZMM_TZFS4 +?WRITEIO: CALLBNK WRITEIO, TZMM_TZFS4 +?READIO: CALLBNK READIO, TZMM_TZFS4 ?DUMPBC: CALLBNK DUMPBC, TZMM_TZFS3 ?DUMPX: CALLBNK DUMPX, TZMM_TZFS3 ?DUMP: CALLBNK DUMP, TZMM_TZFS3 -?INITMEMX: CALLBNK INITMEMX, TZMM_TZFS3 +?FILL: CALLBNK FILL, TZMM_TZFS3 +?GETMEM: CALLBNK GETMEM, TZMM_TZFS +?SETMEM: CALLBNK SETMEM, TZMM_TZFS +?DASM: CALLBNK DASM_MAIN, TZMM_TZFS4 +?ASM: CALLBNK ASM_MAIN, TZMM_TZFS4 + IF BUILD_FUSIONX = 0 ?SETVMODE: CALLBNK SETVMODE, TZMM_TZFS4 ?SETVGAMODE:CALLBNK SETVGAMODE, TZMM_TZFS4 ?SETVBORDER:CALLBNK SETVBORDER, TZMM_TZFS4 + ENDIF ; BUILD_FUSIONX ?SETFREQ: CALLBNK SETFREQ, TZMM_TZFS4 + IF BUILD_FUSIONX = 0 ?SETT80: CALLBNK SETT80, TZMM_TZFS4 ?SETZ80: CALLBNK SETZ80, TZMM_TZFS4 ?SETZPUEVO: CALLBNK SETZPUEVO, TZMM_TZFS4 + ENDIF ; BUILD_FUSIONX ?TIMERTST: CALLBNK TIMERTST, TZMM_TZFS3 ?PTESTX: CALLBNK PTESTX, TZMM_TZFS3 ?GETMODEL: CALLBNK GETMODEL, TZMM_TZFS3 @@ -149,6 +163,7 @@ CNV_ATOS: CALLBNK CNVSTR_AS, TZMM_TZFS2 ; ?RDDTZFS: CALLBNK RDDTZFS, TZMM_TZFS3 ?WRITZFS: CALLBNK WRITZFS, TZMM_TZFS3 ?WRDTZFS: CALLBNK WRDTZFS, TZMM_TZFS3 + IF BUILD_FUSIONX = 0 ?SETMZ80K: CALLBNK SETMZ80K, TZMM_TZFS4 ?SETMZ80C: CALLBNK SETMZ80C, TZMM_TZFS4 ?SETMZ1200: CALLBNK SETMZ1200, TZMM_TZFS4 @@ -160,6 +175,7 @@ CNV_ATOS: CALLBNK CNVSTR_AS, TZMM_TZFS2 ; ?SETMZ2000: CALLBNK SETMZ2000, TZMM_TZFS4 ?SETMZ2200: CALLBNK SETMZ2200, TZMM_TZFS4 ?SETMZ2500: CALLBNK SETMZ2500, TZMM_TZFS4 + ENDIF ; BUILD_FUSIONX ;----------------------------------------- @@ -284,8 +300,10 @@ SIGNON1: CALL DPCT IN A,(CPUSTATUS) ; Check to see if the T80 is running. AND CPUMODE_IS_T80 ; T80 running? JR Z,SIGNON2 - LD DE,MSGSONT80 - CALL ?PRINTMSG + IF BUILD_FUSIONX = 0 + LD DE,MSGSONT80 + CALL ?PRINTMSG + ENDIF ; BUILD_FUSIONX SIGNON2: LD DE,MSGSONEND CALL ?PRINTMSG @@ -527,6 +545,14 @@ GOTOX: CALL HEXIYX JP (HL) + ; Method to read a byte out of main memory when configured in default TZFS1 mode. +GETMEM: LD A,(HL) + RET + ; Method to write a byte into main memory when configured in default TZFS1 mode. +SETMEM: LD (HL),A + RET + + ;==================================== ; ; Screen Width and Mode Commands @@ -558,12 +584,18 @@ SETMODE80: IN A,(CPLDINFO) ; Get c SETMODE40A: IN A,(CPLDINFO) ; Get configuration of hardware. BIT 3,A LD A,MODE_MZ80A ; Set the tranZPUter CPLD hardware translation to MZ80A mode. - JR Z,SETMODE40_1 - LD A,VMMODE_MZ80A ; Setup the display to 40 char MZ80A mode. + JR NZ,SETMODE40_0 + LD HL,DSPCTL ; Assume the 40/80 card is installed, switch to 40char mode. + XOR A + LD E,(HL) + LD (HL),A + JR SETMODE40_2 + ; +SETMODE40_0:LD A,VMMODE_MZ80A ; Setup the display to 40 char MZ80A mode. OUT (VMCTRL),A ; Activate. LD A, MODE_MZ80A + MODE_VIDEO_FPGA ; Set the tranZPUter CPLD hardware translation to MZ80A mode with FPGA video enabled. SETMODE40_1:OUT (CPLDCFG),A ; - XOR A +SETMODE40_2:XOR A LD (SPAGE), A ; Allow MZ80A scrolling LD A,(SCRNMODE) RES 0, A @@ -572,11 +604,11 @@ SETMODE40_1:OUT (CPLDCFG),A ; IN A,(CPLDINFO) ; Check to see if this is an MZ700, if it is not, setup the correct frequency. AND 007H CP MODE_MZ80A - JR Z,SETMODE40_2 + JR Z,SETMODE40_3 LD A,SYSMODE_MZ80A ; Setup the board to run at 2MHz OUT (SYSCTRL),A ; Activate -SETMODE40_2:LD A,TZSVC_CMD_LOAD40ABIOS ; Request the I/O processor loads the SA1510 40column BIOS into memory. +SETMODE40_3:LD A,TZSVC_CMD_LOAD40ABIOS ; Request the I/O processor loads the SA1510 40column BIOS into memory. SETBIOS: CALL SVC_CMD ; And make communications wit the I/O processor, returning with the result of load operation. OR A JP Z,MROMADDR @@ -588,13 +620,18 @@ SETBIOS: CALL SVC_CMD ; And m SETMODE80A: IN A,(CPLDINFO) ; Get configuration of hardware. BIT 3,A LD A, MODE_MZ80A ; Set the tranZPUter CPLD hardware translation to MZ80A mode. - JR Z,SETMODE40_1 ; No hardware so cannot do 80 char mode. + JR NZ,SETMODE80_0 + LD HL,DSPCTL ; Assume the 40/80 card is installed, switch to 80char mode. + LD A,128 + LD E,(HL) + LD (HL),A + JR SETMODE80_2 ; - LD A,VMMODE_MZ80A + MODE_80CHAR ; Setup the display to 80 char MZ80A mode. +SETMODE80_0:LD A,VMMODE_MZ80A + MODE_80CHAR ; Setup the display to 80 char MZ80A mode. OUT (VMCTRL),A ; Activate. LD A, MODE_MZ80A + MODE_VIDEO_FPGA ; Set the tranZPUter CPLD hardware translation to MZ80A mode with FPGA video enabled. SETMODE80_1:OUT (CPLDCFG),A ; - LD A, 0FFH +SETMODE80_2:LD A, 0FFH LD (SPAGE), A ; MZ80K Scrolling in 80 column mode for time being. LD A,(SCRNMODE) SET 0, A ; Indicate 80 column mode for startup. @@ -603,11 +640,11 @@ SETMODE80_1:OUT (CPLDCFG),A ; IN A,(CPLDINFO) ; Check to see if this is an MZ700, if it is not, setup the correct frequency. AND 007H CP MODE_MZ80A - JR Z,SETMODE80_2 + JR Z,SETMODE80_3 LD A,SYSMODE_MZ80A ; Setup the board to run at 2MHz OUT (SYSCTRL),A ; Activate -SETMODE80_2:LD A,TZSVC_CMD_LOAD80ABIOS ; Request the I/O processor loads the SA1510 80column BIOS into memory. +SETMODE80_3:LD A,TZSVC_CMD_LOAD80ABIOS ; Request the I/O processor loads the SA1510 80column BIOS into memory. JR SETBIOS @@ -1271,11 +1308,23 @@ DIRSD4: RET ; ; Quick method to load the basic interpreter. So long as the filename doesnt change this method will load and boot Basic. -LOADBASIC: LD DE,BASICFILENM +LOADBASIC: + IF BUILD_MZ80A > 0 + LD DE,BASICFNM80A + ENDIF + IF BUILD_MZ700 > 0 + LD DE,BASICFNM700 + ENDIF JR LOADSDCARD ; Quick method to load CPM. So long as the filename doesnt change this method will load and boot CPM. -LOADCPM: LD DE,CPMFILENAME +LOADCPM: + IF BUILD_MZ80A > 0 + LD DE,CPMFNAME80A + ENDIF + IF BUILD_MZ700 > 0 + LD DE,CPMFNAME700 + ENDIF JR LOADSDCARD ; Entry point when copying the SD file. Setup flags to indicate copying to effect any special processing. @@ -2122,10 +2171,12 @@ L0300: IN A,(0D8H) ; State reg ; B = Characters copied (ie. B - input B = no characters). ; GETSTRING: LD A,(DE) ; Skip white space before copy. - CP ' ' + CP 33 JR NC, GETSTR1 CP 00DH - JR GETSTR2 ; No directory means use the I/O set default. + JR Z, GETSTR2 ; No directory means use the I/O set default. + OR A + JR Z, GETSTR2 INC DE JR GETSTRING GETSTR1: LD (HL),A ; Copy the name entered by user. Validation is done on the I/O processor, bad directory name will result in error next read/write. @@ -2314,8 +2365,10 @@ LOCALTEST: LD A,0 RET ; Quick load program names. -CPMFILENAME:DB "CPM223 MZ-700-80", 000H -BASICFILENM:DB "S-BASIC", 000H +CPMFNAME80A:DB "CPM223 MZ-80A-80", 000H +BASICFNM80A:DB "BASIC-SA-5510-TZ", 000H +CPMFNAME700:DB "CPM223 MZ-700-80", 000H +BASICFNM700:DB "S-BASIC", 000H DEFAULTFN: DB "DEFAULT" DEFAULTFNE: EQU $ @@ -2354,6 +2407,9 @@ CMDTABLE: ;DB 000H | 000H | 000H | 003H ;DB 000H | 000H | 000H | 003H ;DB "700" ; Switch to 40 column MZ700 mode. ;DW SETMODE700 + DB 000H | 000H | 000H | 003H + DB "ASM" ; Assembler. + DW ?ASM DB 000H | 000H | 000H | 005H DB "BASIC" ; Load and run BASIC SA-5510. DW LOADBASIC @@ -2364,11 +2420,14 @@ CMDTABLE: ;DB 000H | 000H | 000H | 003H DB "CPM" ; Load and run CPM. DW LOADCPM DB 000H | 000H | 000H | 002H + DB "CP" ; Copy memory + DW ?COPYM + DB 000H | 000H | 000H | 002H DB "CD" ; SD Card Directory change command. DW CHGSDDIR - DB 000H | 000H | 000H | 001H - DB 'C' ; Clear Memory. - DW ?INITMEMX + DB 000H | 000H | 000H | 004H + DB "DASM" ; Disassembler. + DW ?DASM DB 000H | 000H | 000H | 003H DB "DIR" ; List SD Card directory. DW DIRSDCARD @@ -2382,6 +2441,9 @@ CMDTABLE: ;DB 000H | 000H | 000H | 003H DB "EX" ; Exit out of TZFS to original Monitor. DW EXITTZFS DB 000H | 000H | 000H | 004H + DB "FILL" ; Fill Memory. + DW ?FILL + DB 000H | 000H | 000H | 004H DB "FREQ" ; Set or change the CPU frequency. DW ?SETFREQ DB 000H | 000H | 000H | 001H @@ -2409,42 +2471,44 @@ CMDTABLE: ;DB 000H | 000H | 000H | 003H DB "L" ; Original Load from CMT DW LOADTAPE ; - DB 000H | 000H | 000H | 005H - DB "MZ80K" ; Invoke MZ80K Hardware Emulation. - DW ?SETMZ80K - DB 000H | 000H | 000H | 005H - DB "MZ80C" ; Invoke MZ80C Hardware Emulation. - DW ?SETMZ80C - DB 000H | 000H | 000H | 006H - DB "MZ1200" ; Invoke MZ1200 Hardware Emulation. - DW ?SETMZ1200 - DB 000H | 000H | 000H | 005H - DB "MZ80A" ; Invoke MZ80A Hardware Emulation. - DW ?SETMZ80A - DB 000H | 000H | 000H | 005H - DB "MZ700" ; Invoke MZ700 Hardware Emulation. - DW ?SETMZ700 - DB 000H | 000H | 000H | 006H - DB "MZ1500" ; Invoke MZ1500 Hardware Emulation. - DW ?SETMZ1500 - DB 000H | 000H | 000H | 005H - DB "MZ800" ; Invoke MZ800 Hardware Emulation. - DW ?SETMZ800 - DB 000H | 000H | 000H | 005H - DB "MZ80B" ; Invoke MZ80B Hardware Emulation. - DW ?SETMZ80B - DB 000H | 000H | 000H | 006H - DB "MZ2000" ; Invoke MZ2000 Hardware Emulation. - DW ?SETMZ2000 - DB 000H | 000H | 000H | 006H - DB "MZ2200" ; Invoke MZ2200 Hardware Emulation. - DW ?SETMZ2200 - DB 000H | 000H | 000H | 006H - DB "MZ2500" ; Invoke MZ2500 Hardware Emulation. - DW ?SETMZ2500 - DB 000H | 000H | 000H | 002H - DB "MZ" ; Invoke default MZ80A Hardware Emulation. - DW ?SETMZ80A + IF BUILD_FUSIONX = 0 + DB 000H | 000H | 000H | 005H + DB "MZ80K" ; Invoke MZ80K Hardware Emulation. + DW ?SETMZ80K + DB 000H | 000H | 000H | 005H + DB "MZ80C" ; Invoke MZ80C Hardware Emulation. + DW ?SETMZ80C + DB 000H | 000H | 000H | 006H + DB "MZ1200" ; Invoke MZ1200 Hardware Emulation. + DW ?SETMZ1200 + DB 000H | 000H | 000H | 005H + DB "MZ80A" ; Invoke MZ80A Hardware Emulation. + DW ?SETMZ80A + DB 000H | 000H | 000H | 005H + DB "MZ700" ; Invoke MZ700 Hardware Emulation. + DW ?SETMZ700 + DB 000H | 000H | 000H | 006H + DB "MZ1500" ; Invoke MZ1500 Hardware Emulation. + DW ?SETMZ1500 + DB 000H | 000H | 000H | 005H + DB "MZ800" ; Invoke MZ800 Hardware Emulation. + DW ?SETMZ800 + DB 000H | 000H | 000H | 005H + DB "MZ80B" ; Invoke MZ80B Hardware Emulation. + DW ?SETMZ80B + DB 000H | 000H | 000H | 006H + DB "MZ2000" ; Invoke MZ2000 Hardware Emulation. + DW ?SETMZ2000 + DB 000H | 000H | 000H | 006H + DB "MZ2200" ; Invoke MZ2200 Hardware Emulation. + DW ?SETMZ2200 + DB 000H | 000H | 000H | 006H + DB "MZ2500" ; Invoke MZ2500 Hardware Emulation. + DW ?SETMZ2500 + DB 000H | 000H | 000H | 002H + DB "MZ" ; Invoke default MZ80A Hardware Emulation. + DW ?SETMZ80A + ENDIF ; DB 000H | 000H | 000H | 001H DB 'M' ; Edit Memory. @@ -2452,6 +2516,9 @@ CMDTABLE: ;DB 000H | 000H | 000H | 003H DB 000H | 000H | 000H | 001H DB 'P' ; Printer test. DW ?PTESTX + DB 000H | 000H | 000H | 003H + DB "RIO" ; Read I/O + DW ?READIO DB 000H | 000H | 000H | 001H DB 'R' ; Memory test. DW MEMTEST @@ -2476,31 +2543,40 @@ CMDTABLE: ;DB 000H | 000H | 000H | 003H DB 000H | 000H | 000H | 004H DB "T2SD" ; Copy Tape to SD Card. DW TAPE2SD - DB 000H | 000H | 000H | 003H - DB "T80" ; Switch to soft T80 CPU. - DW ?SETT80 + IF BUILD_FUSIONX = 0 + DB 000H | 000H | 000H | 003H + DB "T80" ; Switch to soft T80 CPU. + DW ?SETT80 + ENDIF DB 000H | 000H | 000H | 001H DB 'T' ; Timer test. DW ?TIMERTST - DB 000H | 000H | 000H | 007H - DB "VBORDER" ; Set VGA border colour. - DW ?SETVBORDER - DB 000H | 000H | 000H | 005H - DB "VMODE" ; Set VGA mode. - DW ?SETVMODE - DB 000H | 000H | 000H | 003H - DB "VGA" ; Set VGA mode. - DW ?SETVGAMODE + IF BUILD_FUSIONX = 0 + DB 000H | 000H | 000H | 007H + DB "VBORDER" ; Set VGA border colour. + DW ?SETVBORDER + DB 000H | 000H | 000H | 005H + DB "VMODE" ; Set VGA mode. + DW ?SETVMODE + DB 000H | 000H | 000H | 003H + DB "VGA" ; Set VGA mode. + DW ?SETVGAMODE + ENDIF DB 000H | 000H | 000H | 001H DB 'V' ; Verify CMT Save. DW VRFYX DB 000H | 000H | 000H | 003H - DB "Z80" ; Switch to soft Z80 CPU. - DW ?SETZ80 - DB 000H | 000H | 000H | 003H - DB "ZPU" ; Switch to soft ZPU Evolution CPU. - DW ?SETZPUEVO - DB 000H | 000H | 000H | 001H + DB "WIO" ; Write I/O + DW ?WRITEIO + IF BUILD_FUSIONX = 0 + DB 000H | 000H | 000H | 003H + DB "Z80" ; Switch to soft Z80 CPU. + DW ?SETZ80 + DB 000H | 000H | 000H | 003H + DB "ZPU" ; Switch to soft ZPU Evolution CPU. + DW ?SETZPUEVO + DB 000H | 000H | 000H | 001H + ENDIF diff --git a/asm/tzfs_bank2.asm b/asm/tzfs_bank2.asm index cfd0ece..4656643 100644 --- a/asm/tzfs_bank2.asm +++ b/asm/tzfs_bank2.asm @@ -12,11 +12,12 @@ ;- I/O processor in the K64F/ZPU. ;- ;- Credits: -;- Copyright: (c) 2018-2020 Philip Smart +;- Copyright: (c) 2018-2023 Philip Smart ;- ;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW. ;- Dec 2020 - Updates to accommodate v1.3 of the tranZPUter SW-700 board where soft ;- CPU's now become possible. +;- Feb 2023 - TZFS now running on FusionX. Small changes to ensure compatibility. ;- ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify @@ -141,36 +142,41 @@ PRTMSG: LD A,(DE) PRTMSGE: POP BC RET - ; A modified print string routine with full screen pause to print out the help screen text. The routine prints out true ascii - ; as opposed to Sharp modified ascii. + ; A modified print string routine with full screen pause to print out the help screen text or other page text. The routine prints out true ascii + ; as opposed to Sharp modified ascii. It can be called with a multi line string or many times with single string, pausing if rowcount gets to end of string. ; A string is NULL terminated. PRTSTR: PUSH AF PUSH BC PUSH DE - LD A,0 - LD (TMPLINECNT),A + PUSH HL + LD HL,TMPCNT + OR A + JR NZ,PRTSTR1 ; Carry set skip row count init, used when calling multiple times. + LD (HL),A PRTSTR1: LD A,(DE) CP 000H ; NULL terminates the string. - JR Z,PRTSTRE + JR Z,PRTSTR3 CP 00DH ; As does CR. JR Z,PRTSTR3 PRTSTR2: CALL PRINTASCII INC DE - JR PRTSTR1 + JR PRTSTR1 + ; PRTSTR3: PUSH AF - LD A,(TMPLINECNT) - CP 23 ; Check to see if a page of output has been displayed, if it has, pause. - JR Z,PRTSTR5 - INC A -PRTSTR4: LD (TMPLINECNT),A - POP AF - JR PRTSTR2 -PRTSTR5: CALL GETKY + LD A,(HL) + CP 24 ; Check to see if a page of output has been displayed, if it has, pause. + JR C,PRTSTR5 +PRTSTR4: CALL GETKY CP ' ' - JR NZ,PRTSTR5 + JR NZ,PRTSTR4 XOR A - JR PRTSTR4 -PRTSTRE: POP DE + LD (HL),A +PRTSTR5: POP AF + INC (HL) ; Increment row count, used in repeated calls not clearing rowcount to zero. + OR A + JR NZ, PRTSTR2 + POP HL + POP DE POP BC POP AF RET @@ -409,9 +415,11 @@ FDCJMPL2: JP (IX) ;------------------------------------------------------------------------------- ; 0 + <- 39 ; ----------------------------------------- -MSGSON: DB "+ TZFS v1.6 ", NULL ; Version 1.0-> first split from RFS v2.0 +MSGSON: DB "+ TZFS v1.7 ", NULL ; Version 1.0-> first split from RFS v2.0 MSGSONEND: DB " **", CR, NULL ; Signon banner termination. + IF BUILD_FUSIONX = 0 MSGSONT80: DB "(T80)", NULL ; T80 CPU detected. + ENDIF ; BUILD_FUSIONX MSGNOTFND: DB "Not Found", CR, NULL MSGBADCMD: DB "???", CR, NULL MSGSDRERR: DB "SD Read error, Sec:",0FBH, NULL @@ -431,7 +439,6 @@ MSGBOOTDRV: DB CR, "Floppy boot drive ?", MSGLOADERR: DB CR, "Disk loading error", CR, NULL MSGIPLLOAD: DB CR, "Disk loading ", NULL MSGDSKNOTMST:DB CR, "This is not a boot disk", CR, NULL -MSGINITM: DB "Init memory", CR, NULL MSGREAD4HEX:DB "Bad hex number", CR, NULL MSGT2SDERR: DB "Copy from Tape to SD Failed", CR, NULL MSGSD2TERR: DB "Copy from SD to Tape Failed", CR, NULL @@ -442,6 +449,7 @@ MSGFAILBIOS:DB "Failed to load alternate BIOS!", MSGFAILEXIT:DB "TZFS exit failed, I/O proc error!", CR, NULL MSGFREQERR: DB "Error, failed to change frequency!", CR, NULL MSGBADNUM: DB "Error, bad number supplied!", CR, NULL + IF BUILD_FUSIONX = 0 MSGNOFPGA: DB "Error, no FPGA video module!", CR, NULL MSGT80ERR: DB "Error, failed to switch to T80 CPU!", CR, NULL MSGZ80ERR: DB "Error, failed to switch to Z80 CPU!", CR, NULL @@ -449,6 +457,7 @@ MSGZPUERR: DB "Error, failed to switch to ZPU CPU!", MSGNOSOFTCPU:DB "No soft cpu hardware!", CR, NULL MSGNOT80CPU:DB "T80 not available!", CR, NULL MSGNOEMU: DB "No Sharp MZ Series Emu hardware!", CR, NULL + ENDIF ; BUILD_FUSIONX ; OKCHECK: DB ", CHECK: ", CR, NULL OKMSG: DB " OK.", CR, NULL @@ -460,6 +469,8 @@ MSG_TIMERTST:DB "8253 TIMER TEST", MSG_TIMERVAL:DB "READ VALUE 1: ", CR, NULL MSG_TIMERVAL2:DB "READ VALUE 2: ", CR, NULL MSG_TIMERVAL3:DB "READ DONE.", CR, NULL +MSGNOINSTR: DB "Bad instruction.", CR, NULL +MSGNOPARAM: DB "Bad parameter.", CR, NULL ; The FDC controller uses it's busy/wait signal as a ROM address line input, this @@ -489,58 +500,78 @@ SVCIOERR: DB "I/O Error, time out!", ;------------------------------------------------------------------------------- ; Simple help screen to display commands. -HELP: ;CALL NL - LD DE, HELPSCR +HELP: LD DE, HELPSCR + XOR A ; Paging starts at 0. CALL PRTSTR RET ; Help text. Use of lower case, due to Sharp's non standard character set, is not easy, you have to manually code each byte ; hence using upper case. HELPSCR: ; "--------- 40 column width -------------" - DB "4 40 col mode.", 00DH - DB "8 80 col mode.", 00DH - ;DB "40A select MZ-80A 40col Mode.", 00DH - ;DB "80A select MZ-80A 80col Mode.", 00DH - ;DB "80B select MZ-80B Mode.", 00DH - ;DB "700 select MZ-700 40col Mode.", 00DH - ;DB "7008 select MZ-700 80col Mode.", 00DH - DB "B toggle keyboard bell.", 00DH - DB "BASIC load BASIC SA-5510.", 00DH - DB "C[b] clear memory $1200-$D000.", 00DH - DB "CD[d] switch to SD directory [d].", 00DH - DB "CPM load CPM.", 00DH - DB "DXXXX[YYYY] dump mem XXXX to YYYY.", 00DH - DB "DIR[wc] SD dir listing, wc=wildcard.", 00DH - DB "ECfn erase file, fn=No or Filename", 00DH - DB "EX exit TZFS, reset as original.", 00DH - DB "Fx boot fd drive x.", 00DH - DB "FREQn set CPU to nKHz, 0 default.", 00DH - DB "H this help screen.", 00DH - DB "JXXXX jump to location XXXX.", 00DH - DB "LTfn[,M] load tape, fn=Filename", 00DH - DB " M = HW Mode, K=80K,C=80C,1=1200", 00DH - DB " A=80A,7=700,8=800,B=80B,2=2000", 00DH - DB "LCfn[,M] load from SD, fn=No or FileN", 00DH - DB " add NX for no exec, ie.LCNX.", 00DH - DB "MXXXX edit memory starting at XXXX.", 00DH - DB "MZmc activate hardware emulation.", 00DH - DB " mc =80K,80C,1200,80A,700,800,80B,2000", 00DH - DB "P test printer.", 00DH - DB "R test dram memory.", 00DH - DB "SDDd change to SD directory {d}.", 00DH - DB "SD2Tfn[,M] copy SD to tape.", 00DH - DB "STXXXXYYYYZZZZ[,M] save mem to tape.", 00DH - DB "SCXXXXYYYYZZZZ save mem to card.", 00DH - DB " XXXX=start, YYYY=end, ZZZZ=exec", 00DH - DB "T test timer.", 00DH - DB "T2SD[B][,M] copy tape to SD, B=Bulk", 00DH - DB "T80 switch to soft T80 CPU.", 00DH - DB "V verify tape save.", 00DH - DB "VBORDERn set vga border colour.", 00DH - DB "VMODEn set video mode.", 00DH - DB "VGAn set VGA mode.", 00DH - DB "Z80 switch to hard Z80 CPU.", 00DH - DB "ZPU switch to ZPU Evo CPU / zOS.", 00DH + DB "4 40 col mode", 00DH + DB "8 80 col mode", 00DH + ;DB "40A select MZ-80A 40col Mode", 00DH + ;DB "80A select MZ-80A 80col Mode", 00DH + ;DB "80B select MZ-80B Mode", 00DH + ;DB "700 select MZ-700 40col Mode", 00DH + ;DB "7008 select MZ-700 80col Mode", 00DH + DB "ASMXXXX assemble into dest XXXX", 00DH + DB "B toggle keyboard bell", 00DH + DB "BASIC load BASIC SA-5510", 00DH + DB "CD[d] switch to SD directory [d]", 00DH + DB "CPXXXXYYYYZZZZ", 00DH + DB " copy XXXX to YYYY of size ZZZZ", 00DH + DB "CPM load CPM", 00DH + DB "DXXXX[YYYY]", 00DH + DB " dump mem XXXX to YYYY", 00DH + DB "DASMXXXX[YYYY]", 00DH + DB " disassemble XXXX to YYYY", 00DH + DB "DIR[wc] SD dir listing, wc=wildcard", 00DH + DB "ECfn erase file, fn=No or Filename", 00DH + DB "EX exit TZFS, reset as original", 00DH + DB "Fx boot fd drive x", 00DH + DB "FILLXXXXYYYY[ZZ]", 00DH + DB " Fill memory from XXXX to YYYY", 00DH + DB "FREQn set CPU to nKHz, 0 default", 00DH + DB "H this help screen", 00DH + DB "JXXXX jump to location XXXX", 00DH + DB "LTfn[,M] load tape, fn=Filename", 00DH + DB " M = HW Mode, K=80K,C=80C,", 00DH + DB " 1=1200,A=80A,7=700,8=800,", 00DH + DB " B=80B, 2=2000", 00DH + DB "LCfn[,M] load from SD, fn=No or FileN", 00DH + DB " add NX for no exec, ie.LCNX", 00DH + DB "MXXXX edit memory starting at XXXX", 00DH + IF BUILD_FUSIONX = 0 + DB "MZmc activate hardware emulation", 00DH + DB " mc =80K,80C,1200,80A,700,800,", 00DH + DB " 80B,2000", 00DH + ENDIF ; BUILD_FUSIONX + DB "P test printer", 00DH + DB "R test dram memory", 00DH + DB "RIOXXXX Read I/O port XXXX and print", 00DH + ;DB "SDDd change to SD directory {d}", 00DH + DB "SD2Tfn[,M] copy SD to tape", 00DH + DB "STXXXXYYYYZZZZ[,M]", 00DH + DB " save memory to tape", 00DH + DB "SCXXXXYYYYZZZZ", 00DH + DB " save mem to card, XXXX=start", 00DH + DB " YYYY=end, ZZZZ=exec", 00DH + DB "T test timer", 00DH + DB "T2SD[B][,M]", 00DH + DB " copy tape to SD, B=Bulk", 00DH + IF BUILD_FUSIONX = 0 + DB "T80 switch to soft T80 CPU", 00DH + ENDIF ; BUILD_FUSIONX + DB "V verify tape save", 00DH + DB "WIOXXXXYY Write YY to I/O port XXXX", 00DH + IF BUILD_FUSIONX = 0 + DB "VBORDERn set vga border colour", 00DH + DB "VMODEn set video mode", 00DH + DB "VGAn set VGA mode", 00DH + DB "Z80 switch to hard Z80 CPU", 00DH + DB "ZPU switch to ZPU Evo CPU / zOS", 00DH + ENDIF ; BUILD_FUSIONX ; "--------- 40 column width -------------" DB 000H diff --git a/asm/tzfs_bank3.asm b/asm/tzfs_bank3.asm index ad5c67e..f8bad59 100644 --- a/asm/tzfs_bank3.asm +++ b/asm/tzfs_bank3.asm @@ -12,11 +12,12 @@ ;- I/O processor in the K64F/ZPU. ;- ;- Credits: -;- Copyright: (c) 2018-2020 Philip Smart +;- Copyright: (c) 2018-2023 Philip Smart ;- ;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW. ;- Jul 2021 - Updated to add configurable tape read/write for MZ80K,80B and 800 series ;- machines. +;- Feb 2023 - TZFS now running on FusionX. Small changes to ensure compatibility. ;- ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify @@ -39,6 +40,7 @@ ; TZFS BANK 3 - Utilities and additional commands. ; ;============================================================ + ORG BANKRAMADDR ;------------------------------------------------------------------------------- @@ -194,7 +196,6 @@ MCRX3: LD H,B ; memor LD L,C JR MCORX1 - ; Dump method when called interbank as HL cannot be passed. ; ; BC = Start @@ -290,28 +291,6 @@ DUMP9: LD (DUMPADDR),HL ; Store CALL NL RET - - ; Cmd tool to clear memory. - ; Read cmd line for an init byte, if one not present, use 00H - ; -INITMEMX: CALL _2HEX - JR NC,INITMEMX1 - LD A,000H -INITMEMX1: PUSH AF - LD DE,MSGINITM - CALL ?PRINTMSG - LD HL,1200h - LD BC,0D000h - 1200h - POP DE -CLEAR1: LD A,D - LD (HL),A - INC HL - DEC BC - LD A,B - OR C - JP NZ,CLEAR1 - RET - ;------------------------------------------------------------------------------- ; END OF ADDITIONAL TZFS COMMAND METHODS ;------------------------------------------------------------------------------- @@ -647,7 +626,11 @@ SLPT: DB 01H ; TEXT ; ; Example: ; 17 + 7 + ((4+10)*x) + 12 + 10 = 564 * 1/3546000 = 159uS + (7 + 13 * (1/3546000)) = 164.5uS -CMTSETDLY: LD A,(HWMODEL) ; Get the machine model we are conforming to. + ; (66 + (14 * x)) / 3540000 = delay + ; MZ-700 - x = ((delay * 3540000) - 66) / 14 + ; MZ-80A - x = ((delay * 2000000) - 66) / 14 +CMTSETDLY: IF BUILD_MZ700 > 0 + LD A,(HWMODEL) ; Get the machine model we are conforming to. CP 5 ; MZ-800 has its own timing. JR Z,CMTSETDLY0 CP 6 ; MZ-80B uses 1800 baud settings @@ -656,7 +639,7 @@ CMTSETDLY: LD A,(HWMODEL) ; G JR Z,CMTSETDLY1 ; ; K Series - LD A,86 ; Remainder of the machines us a 1200 baud setting, + LD A,86 ; Remainder of the machines use a 1200 baud setting, LD (CMTSAMPLECNT),A ; 368uS sample point. LD A,56 ; LD (CMTDLY1CNTM),A ; 240us @@ -690,6 +673,54 @@ CMTSETDLY1: LD A,52 ; 2 LD (CMTDLY2CNTM),A ; LD A,80 ; + 334uS = 667uS LD (CMTDLY2CNTS),A ; + ENDIF + ; The values below are for an MZ-80A running at 2MHz under the FusionX board. + ; If TZFS runs on more platforms then a table will be the best method forward. + IF BUILD_MZ80A > 0 + LD A,(HWMODEL) ; Get the machine model we are conforming to. + CP 5 ; MZ-800 has its own timing. + JR Z,CMTSETDLY0 + CP 6 ; MZ-80B uses 1800 baud settings + JR Z,CMTSETDLY1 + CP 7 ; MZ-2000 uses 1800 baud settings + JR Z,CMTSETDLY1 + ; + ; K Series + LD A,47 ; Remainder of the machines use a 1200 baud setting, + LD (CMTSAMPLECNT),A ; 368uS sample point. + LD A,30 ; + LD (CMTDLY1CNTM),A ; 240us + LD A,33 ; + LD (CMTDLY1CNTS),A ; + 264uS = 504uS + LD A,62 + LD (CMTDLY2CNTM),A ; 464uS + LD A,66 + LD (CMTDLY2CNTS),A ; + 494uS = 958uS + RET + ; MZ-800 +CMTSETDLY0: LD A,49 ; 379uS sample point + LD (CMTSAMPLECNT),A + LD A,30 ; 240uS + LD (CMTDLY1CNTM),A + LD A,35 ; + 278uS = 518uS + LD (CMTDLY1CNTS),A + LD A,62 ; 470uS + LD (CMTDLY2CNTM),A ; + LD A,66 ; + 494uS = 964uS + LD (CMTDLY2CNTS),A ; + RET + ; B Series +CMTSETDLY1: LD A,32 ; 255uS sample point. + LD (CMTSAMPLECNT),A + LD A,19 ; 166.75uS + LD (CMTDLY1CNTM),A + LD A,19 ; + 166uS = 332.75uS + LD (CMTDLY1CNTS),A + LD A,43 ; 333uS + LD (CMTDLY2CNTM),A ; + LD A,43 ; + 334uS = 667uS + LD (CMTDLY2CNTS),A ; + ENDIF RET @@ -1155,14 +1186,54 @@ WBY1: RLCA -;--------------------------------------------------------------------------------------------------------------------- + ;--------------------------------------------------------------------------------------------------------------------- ; The FDC controller uses it's busy/wait signal as a ROM address line input, this ; causes a jump in the code dependent on the signal status. It gets around the 2MHz Z80 not being quick ; enough to process the signal by polling. ALIGN_NOPS FDCJMP2 ORG FDCJMP2 FDCJMPH3: JP (IY) -;--------------------------------------------------------------------------------------------------------------------- + ;--------------------------------------------------------------------------------------------------------------------- + + ;------------------------------------------------------------------------------- + ; START OF ADDITIONAL TZFS COMMAND METHODS + ;------------------------------------------------------------------------------- + + ; Cmd tool to Fill memory. + ; Read cmd line the start address, end address and byte to initialise with, if one not present, use 00H + ; +FILL: CALL READ4HEX + JR C,FILLERR + PUSH HL + CALL READ4HEX + JR C,FILLERR + LD (TMPADR),DE + POP DE ; DE = Start addr + OR A + SBC HL,DE ; HL - DE = Count + PUSH HL + POP BC ; Count of bytes to fill + JR C,FILLERR ; Overflow, End > Start + JR Z,FILLERR ; Nothing to do, Start = End + PUSH DE + LD DE,(TMPADR) + CALL _2HEX ; Get optional byte to use for fill, default to 00H + JR NC,FILL1 + LD A,000H +FILL1: POP HL + LD (HL),A + PUSH HL + POP DE + INC DE + LDIR ; Copy (HL) -> (DE) filling memory with same byte. + RET +FILLERR: LD DE,MSGNOPARAM + CALL ?PRINTMSG + RET + + ;------------------------------------------------------------------------------- + ; END OF ADDITIONAL TZFS COMMAND METHODS + ;------------------------------------------------------------------------------- ; Ensure we fill the entire 4K by padding with FF's. ; diff --git a/asm/tzfs_bank4.asm b/asm/tzfs_bank4.asm index 0ad8286..6076bae 100644 --- a/asm/tzfs_bank4.asm +++ b/asm/tzfs_bank4.asm @@ -4,19 +4,26 @@ ;- Created: July 2019 ;- Author(s): Philip Smart ;- Description: Sharp MZ series tzfs (tranZPUter Filing System). -;- Bank 4 - F000:FFFF - +;- Bank 4 - 1200:CFFF, F000:FFFF ;- ;- This assembly language program is a branch from the original RFS written for the ;- MZ80A_RFS upgrade board. It is adapted to work within the similar yet different ;- environment of the tranZPUter SW which has a large RAM capacity (512K) and an ;- I/O processor in the K64F/ZPU. ;- -;- Credits: -;- Copyright: (c) 2018-2020 Philip Smart +;- Credits: Assembler/Disassembler base code (C) Eric M. Klaus Feb 2023. Based on TASM and adapted +;- to the Sharp system under TZFS. +;- Copyright: (c) 2018-2023 Philip Smart ;- ;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW. ;- Dec 2020 - Updates to accommodate v1.3 of the tranZPUter SW-700 board where soft ;- CPU's now become possible. +;- Feb 2023 - TZFS now running on FusionX. Changes to ensure compatibility and +;- addition of new commands, assemble, disassemble, fill, write I/O, +;- read I/O. +;- TZFS4 now extended to the full RAM range, 1200:CFFF and F000:FFFF. In +;- this memory mode, writing to the core memory page must be done by the +;- API which is sited in E800:EFFF. ;- ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify @@ -37,14 +44,1658 @@ ;============================================================ ; ; TZFS BANK 4 - TZFS commands + ; - Full range, 1200:CFFF, F000:FFFF available. ; ;============================================================ + + ORG MEMSTART + +COUNT_C: DS 1 ; Counter C +ADDR: +ADDR_LO: DS 1 +ADDR_HI: DS 1 +ASM_ADDR: DS 8 ; Assembler Destination address +ASM_BUF: DS 16 ; 16 byte ASM Input Buffer +OUT_BUF: DS 4 ; 4 byte test buffer(last part of ASM_BUF) +INS_BUF: DS 4 ; 4 Byte Instruction Buffer +PARM_BUF: DS 7 ; 7 Byte Parm Buffer +VAL_BUF: ; 5 Byte Value Buffer +VAL_BUF_HI: DS 2 ; 2 Hi Bytes in Value Buffer +VAL_BUF_LO: DS 2 ; 2 Lo Bytes in Value Buffer + DS 1 +SRC_ADDR: DS 2 ; 2 byte source pointer storage +DES_ADDR: DS 2 ; 2 byte destination pointer storage +BLK_ADDR: DS 2 ; 2 byte table block pointer storage +ROW_ADDR: DS 2 ; 2 byte table row pointer storage +BLK_NUM: DS 1 ; 1 byte Block Number +BLK_SIZE: DS 1 ; 1 byte Block Size +ROW_NUM: DS 1 ; 1 byte Row Number +ML_BUF: DS 2 ; 3 byte ML buffer +ML_BTCOUNT: DS 1 ; Last byte of ML buffer(byte count) +VAL_LO: DS 1 ; Converted value LO +VAL_HI: DS 1 ; Converted value Hi + + ; Fill remaining variable area 0's. + ALIGN_NOPS MEMSTART+0800H + + ORG MEMSTART+0800H + + ;------------------------------------------------------------------------------- + ; START OF ADDITIONAL TZFS COMMANDS + ;------------------------------------------------------------------------------- + + ;****************************************************************** + ; DASM_MAIN Z80 Dis-Assembler + ; Based on tables used by the TASM for the Z80 target + ;****************************************************************** +DASM_MAIN: CALL HLHEX ; get starting address + LD (ADDR_LO),HL + LD (SRC_ADDR),HL ; Save in SRC_ADDR & SRC_ADDR+1 + + LD BC,0h ; Add 1 To Start Address BC=0000 + SCF ; C=1 + ADC HL,BC ; Add HL+BC+C to HL(FFFF will overflow to 0000) + RET Z ; Exit if xFFFF was entered + + INC DE + INC DE + INC DE + INC DE + CALL HLHEX ; get end address + JP NC,DASM_UENDAD ; User entered a non-zero address(use it) + XOR A + LD (ASM_ADDR),A ; NOT Using End Address - Just do 16 rows + LD (ASM_ADDR+1),A ; Set ASM_ADDR=x0000 + + LD A,10h + LD (COUNT_C),A ; Set Row Counter = 16 + JP DASM_UROWCT + +DASM_UENDAD:LD A,0FFh ; End Address Was entered - Use It + LD (COUNT_C),A ; Set Row Counter = xFF + + ;LD HL,(ADDR_LO) + LD (ASM_ADDR),HL +DASM_UROWCT:LD HL,(SRC_ADDR) + LD (ADDR_LO),HL + + XOR A + LD (TMPCNT),A ; Set paging rowcount to 0. Used with PRTSTR. + + ; ** Print CR, LF, ADDR_HI, ADDR_LO (in HEX), space +DASM_LOOP1: CALL NL ; Print CR & LF + LD A,(ADDR_HI) ; Print Address Buffer + CALL PRTHX + LD A,(ADDR_LO) + CALL PRTHX + CALL PRNTS ; Print Space + + LD HL,ASM_BUF ; Clear ASM_BUF, INS_BUF, PARM_BUF & VAL_BUF + LD B,30h ; (Set to all spaces) + CALL MEMSET + + ; ** Get 2 bytes from memory pointed to by ADDR_LO & ADDR_HI + LD HL,(ADDR_LO) ; Address ->HL + LD A,(HL) ; First Byte ->A + CALL ?GETMEM ; First Byte ->A + LD (ML_BUF),A ; Store in ML_BUF Byte 0 + + INC HL + CALL ?GETMEM ; Second Byte ->A + LD (ML_BUF+1),A ; Store in ML_BUF Byte 1 + + CALL DASMBITINST ; Is This a BIT,SET or RES Inst.? + JP NZ,DASM_FIND ; NO=Do regular search + CALL DSMFINDOPCD ; Search For Matching BIT,SET,RES OP Code + JP Z,DASM_ERR ; NOT FOUND - Error Message + CALL DASMGETINST ; Copy 4 byte Assembler Inst. to ASM_BUF + JP DASM_JUSTV ; VAL_BUF has already been populated + +DASM_FIND: CALL DSMFINDOPCD ; Search For Matching OP Code + JP Z,DASM_ERR ; NOT FOUND - Error Message + + CALL DASMGETINST ; Copy 4 byte Assembler Inst. to ASM_BUF + + ; ** Are Data Bytes expected? YES=COPY TO VAL_BUF + LD A,'0' + LD (VAL_BUF_HI),A ; Set VAL_BUF_HI="00" + LD (VAL_BUF_HI+1),A + LD A,0 + LD (VAL_BUF_LO),A ; Set VAL_BUF_LO=NULL(NO DATA indicator) + + CALL DASMGETVAL ; Get 1 or 2 value bytes from memory +DASM_JUSTV: CALL DSMLFJVAL ; Left justify VAL_BUF(Trim leading zeros) + CALL DASMGETPARM ; Build parameter string with value data + CALL DSMRTRIMASM ; Trim trailing spaces from ASM_BUF + + LD A,0Fh ; Output Memory Bytes and Advance Address Pointer + LD C,A + LD HL,(ADDR_LO) ; Address ->HL + LD A,(ML_BTCOUNT) ; Get Total Byte count from lookup table + LD B,A ; Save in B +DASM_MEMOUT:CALL ?GETMEM ; LD A,(HL) + CALL PRTHX + CALL PRNTS ; Print Space + INC HL ; Adjust memory pointer and byte count + DEC C + DEC C + DEC C + DEC B + JP NZ,DASM_MEMOUT ; DONE? NO=Continue + LD (ADDR_LO),HL ; Save New Memory Address + +DASM_SPCOUT:CALL PRNTS ; Pad with spaces to 15 bytes + DEC C + JP NZ,DASM_SPCOUT ; DONE? NO=Continue + + LD BC,010H + LD DE,NAME + PUSH DE + LD HL,ASM_BUF + LDIR + POP DE + LD A,1 + CALL ?PRTSTR ; Print assembly string. + + LD A,(COUNT_C) ; Get Row Count + CP 0FFh ; Using End Address? + JP Z,DASM_CKEADR + DEC A ; Decrement + RET Z ; DONE? - YES = Exit + LD (COUNT_C),A ; NO= Save Row Count + JP DASM_LOOP1 ; Continue... + +DASM_CKEADR:LD HL,(ASM_ADDR) ; Get End Address + LD BC,(ADDR_LO) ; Get Memory Address pointer + SBC HL,BC ; Subtract End from Current + RET M ; If resulte negative - Exit + JP DASM_LOOP1 ; Otherwise Continue... + +DASM_ERR: LD DE,MSGNOTFND + CALL ?PRINTMSG + SCF + RET + + ;****************************************************************** + ; Dis-Assembler Routines + ;****************************************************************** + + ;****************************************************************** + ; ISVALBUF0 + ; Return Z=1 if VAL_BUF contains a single '0' followed by a NULL + ;****************************************************************** +ISVALBUF0: LD A,(VAL_BUF) + CP '0' + JP NZ,IZVBFZ_RET + LD A,(VAL_BUF+1) + CP 0 +IZVBFZ_RET: RET + + ;****************************************************************** + ; IS_DIGIT + ; + ; RETURN Z=1 if A is 'A'-'F' otherwise Z=0 (A is unchanged ) + ; NOTE: A MUST be a non-zero ASCII Digit + ;****************************************************************** +IS_DIGIT: CALL ISDECDIGIT ; Is it '0'-'9' + JP Z,IS_DIG_EXIT ; YES=EXIT with Z=1 + + CALL ISHEXDIGIT ; test for 'A'-'F' and return +IS_DIG_EXIT:RET + + ;****************************************************************** + ; ISHEXDIGIT + ; + ; RETURN Z=1 if A is 'A'-'F' otherwise Z=0 (A is unchanged) + ; NOTE: A MUST be a non-zero ASCII Digit + ;****************************************************************** +ISHEXDIGIT: CP 'A' ; is A <'A'? + JP M,ISHEXD_EXIT ; YES=just exit Z=0 + CP 'G' ; is A <='F'? + JP M,ISHEXD_ZRET ; YES=return Z=1 + JP ISHEXD_EXIT ; otherwise return Z=0 + +ISHEXD_ZRET:CP A ; Set Z=1 and Return + RET + +ISHEXD_EXIT:CP 0 ; Set Z=0 and Return + RET + + ;****************************************************************** + ; ISDECDIGIT + ; + ; RETURN A=1 if A is '0'-'9' otherwise Z=0 (A is unchanged) + ; NOTE: A MUST be a non-zero ASCII Digit + ;****************************************************************** +ISDECDIGIT: CP '0' ; is A <'0'? + JP M,ISDECD_EXIT ; YES= exit with Z=0 + CP 03Ah ; is A <='9'? + JP M,ISDECD_ZRET ; YES=return Z=1 + JP ISDECD_EXIT ; otherwise just exit with Z=0 + +ISDECD_ZRET:CP A ; Set Z=1 and Return + RET + +ISDECD_EXIT:CP 0 ; Set Z=0 and Return + RET + + ;****************************************************************** + ; MEMSET + ; HL=src B=COUNT A=FILL BYTE + ; COPY A to (HL) for B bytes + ;****************************************************************** +MEMSET: LD (HL),A + INC HL + DEC B + JP NZ, MEMSET + RET + + ;****************************************************************** + ; RTJUSTVAL + ; Shift bytes in VAL_BUF right until left padded with '0's + ;****************************************************************** +RTJUSTVAL: PUSH IX + PUSH BC + LD IX,VAL_BUF + LD B,05h ; B=MAX search count 5 + +RTJVAL_LOOP:LD A,(IX+3) ; Get last byte from VAL_BUF + CP ' ' ; Is It SPACE? + JP NZ,RTJVAL_EXIT ; Exit + LD A,(IX+2) ; Shift 3 bytes left 1 positiom + LD (IX+3),A + LD A,(IX+1) + LD (IX+2),A + LD A,(IX+0) + LD (IX+1),A + LD A,'0' ; Pad first position with '0' + LD (IX+0),A + DEC B + JP NZ,RTJVAL_LOOP + +RTJVAL_EXIT:POP BC + POP IX + RET + + ;****************************************************************** + ; ISIXIYPRM + ; Is parameter (IX*) or (IY*) + ;****************************************************************** +ISIXIYPRM: PUSH BC + PUSH HL + LD C,0 ; C = match counter + LD B,7 ; B = byte counter + LD HL,(ROW_ADDR) ; HL = Row data pointer +ISIX_LOOP: LD A,(HL) ; Get a byte from row + CP '(' ; If '(', 'I' or '*' Increment C + JP Z,ISIX_CKI + CP '*' + JP Z,ISIX_COUNT + JP ISIX_NEXT ; None of the above then continue + +ISIX_CKI: INC HL ; Check for '(' followed by 'I' + LD A,(HL) ; Get byte after the '(' just found + CP 'I' ; Is it = 'I'? + JP Z,ISIX_COUNT ; Yes=Count the match + JP ISIX_NEXT2 ; No = Continue + +ISIX_COUNT: INC C +ISIX_NEXT: INC HL ; Advance row data pointer +ISIX_NEXT2: DEC B ; Decrement byte count + JP NZ,ISIX_LOOP ; DONE? NO = Continue + LD A,C ; Get match count + CP 2 ; If = 2 Return Z=1 otherwise Z=0 + POP HL + POP BC + RET + ;****************************************************************** + ; DSMRTRIMASM + ; Trim trailing spaces from ASM_BUF + ;****************************************************************** +DSMRTRIMASM:PUSH BC + PUSH HL + LD B,0Fh ; B=MAX loop count 15 + LD HL,ASM_BUF+15 ; HL=tail of ASM_BUF + +DSMRTA_LOOP:LD A,(HL) ; Get a byte from VAL_BUF + CP ' ' ; Is It ' '? + JP NZ,DSMRTA_EXIT ; No = Exit + XOR A ; A=00h + LD (HL),A ; Store in ASM_BUF + DEC HL ; Decrement ASM_BUF pointer + DEC B ; Decrement byte count + JP NZ,DSMRTA_LOOP ; Done? No=Continue + +DSMRTA_EXIT:POP HL ; Restore BC, HL & Exit + POP BC + RET + ;****************************************************************** + ; DSMLFJVAL + ; Shift bytes in VAL_BUF left until non-zero char is encountered + ;****************************************************************** +DSMLFJVAL: PUSH BC + LD B,03h ; B=MAX loop count 3 + +DSMLFJ_LOOP:LD A,(VAL_BUF) ; Get 1st byte from VAL_BUF + CP '0' ; Is It '0'? + JP NZ,DSMLFJ_EXIT ; No = Exit + LD A,(VAL_BUF+1) ; Shift 3 bytes left 1 positiom + LD (VAL_BUF),A + LD A,(VAL_BUF+2) + LD (VAL_BUF+1),A + LD A,(VAL_BUF+3) + LD (VAL_BUF+2),A + LD A,0 ; Set last position to NULL + LD (VAL_BUF+3),A + DEC B + JP NZ,DSMLFJ_LOOP + +DSMLFJ_EXIT:POP BC + RET + + ;****************************************************************** + ; BYTE2ASCII + ; Convert Hex Value of A to 2 Hex ASCII bytes in HL + ; NOTE: L=MSB, H=LSB since strings are usually Hi,Lo eg:"35" + ; if we use LD (address),HL then address = L and address+1 = H + ;****************************************************************** +BYTE2ASCII: LD H,A ; Save A in H + RRA ; Shift Hi 4 Bits to Low 4 Bits + RRA + RRA + RRA + CALL NIB_TOHEX + LD L,A ; MSB->L + LD A,H ; Restore A from H + CALL NIB_TOHEX + LD H,A ; LSB->H + RET + + ;****************************************************************** + ; NIB_TOHEX + ; Convert Lo 4 bits of A to ASCII of it's HEX value (0-9 or A-F) + ;****************************************************************** +NIB_TOHEX: AND 0Fh ; Mask Hi 4 Bits + CP 0Ah ; is it 9 or less? + JP M,ADD_30X + ADD A,07h +ADD_30X: ADD A,030h + RET + + ;****************************************************************** + ; DASMBITINST + ; ML_BUF contains 2 bytes from current memory location. + ; If Byte1=0xCB and (Byte2 & 0xC0) > 0 This is a BIR, SET or RES inst. + ; Pull the "Bit" value from Byte2 and populate VAL_LO + ; Mask the "Bit" indicator bits from byte 2 and do the lookup + ;****************************************************************** + +DASMBITINST:LD B,0CBh ; B=0xCB + LD A,(ML_BUF) ; A=ML_BUF Byte1 + CP B ; Compare A with B + JP NZ,DASMBIT_RET ; NoMatch Exit with Z=0 + LD A,(ML_BUF+1) ; Get Byte2 + AND 0C0h ; AND with 0xCO + JP NZ,DASMBIT_VAL ; Not Zero then this is a BIT,SET or RES + LD A,0FFh ; Otherwise... + JP DASMBITRETN ; Return with Z=0 + +DASMBIT_VAL:LD A,(ML_BUF+1) ; Get Byte2 + AND 038h ; Mask All but 'BIT#' bits + RRA ; Shift Right 3x + RRA + RRA + AND 07h + PUSH HL ; Save Address Pointer + CALL BYTE2ASCII ; Convert A to 2 ASCII Bytes in HL + LD (VAL_BUF_LO),HL ; Store 2 bytes in VAL_BUF_LO + LD A,'0' + LD (VAL_BUF_HI),A + LD (VAL_BUF_HI+1),A ; Store '00' in VAL_BUF_HI + POP HL ; Restore Address pointer + LD A,(ML_BUF+1) ; Get Byte2 + AND 0C7h ; AND with 0xC7 + LD (ML_BUF+1),A ; Replace MLByte2 +DASMBITRETZ:LD A,0 ; Return with Z=1 +DASMBITRETN:CP 0 ; Return with Z=0 +DASMBIT_RET:RET + + ;****************************************************************** + ; DASMGETPARM + ; Build the Assembly instruction parameter string from bytes in + ; the found row in the lookup table. + ; Assumes justified value bytes are already in VAL_BUF if required. + ; NOTE: ROW_ADDR is set by successful find by DSMFINDOPCD + ;****************************************************************** + +DASMGETPARM:LD B,7 ; Byte Counter = 7 + LD IY,ASM_BUF+5 ; ;IY=Target Address (ASM_BUF+5) + LD IX,(ROW_ADDR) ; IX=Source Address (Table Row Address) +DASM_GETPRM:LD A,(IX) ; Get Parm Byte + CP '*' ; Is it a '*'? + JP NZ,DASM_SAVPAR ; NO=Save Parm byte + + CALL ISIXIYPRM ; Is this an (IX*) ot (IY*) Parm? + JP NZ,DASM_MOVVAL ; NO=Just move the value bytes + CALL ISVALBUF0 ; Is VAL_BUF="0" + JP Z,DASM_NXTPR2 ; YES=Skip move of value bytes + LD A,'+' + LD (IY),A ; Store a '+' + INC IY ; Advance Target Address & move value bytes + +DASM_MOVVAL:LD C,4 ; Byte count=4 + LD HL,VAL_BUF ; HL = VAL_BUF +DASM_MVLOOP:LD A,(HL) ; Get a value byte + CP 0 ; NULL? + JP Z,DASM_SAVH ; YES=DONE goto Save 'h' & continue + LD (IY),A ; Store the value char + INC IY ; Advance destination (ASM_BUF) pointer + INC HL + DEC C + JP NZ,DASM_MVLOOP + +DASM_SAVH: LD A,'h' ; Load the 'h' +DASM_SAVPAR:LD (IY),A ; Store parm char +DASM_NXTPAR:INC IY ; Advance Target Address +DASM_NXTPR2:INC IX ; Advance Source Address + DEC B ; Count Source bytes + JP NZ,DASM_GETPRM ; DONE? NO=Continue + RET ; YES= Exit + + ;****************************************************************** + ; DASMGETVAL + ; Copy 1 or 2 bytes of value data from memory to VAL_BUF + ; Data value are converted to ASCII HEX chars in VAL_BUF + ; NOTE: ML_BTCOUNT is set by successful find by DSMFINDOPCD + ;****************************************************************** + +DASMGETVAL: LD HL,(ADDR_LO) ; Get memory Address->HL + LD A,(ML_BTCOUNT) ; Get Total Byte count from lookup table + LD B,A ; Save in B + DEC B ; Skip 1 Byte count + INC HL ; Skip 1 byte in memory + LD A,(ML_BUF+1) ; Is this a 2 byte instruction? + CP 0 + JP Z,DASMCKBTCNT ; NO= check final byte count + DEC B ; Decrement byte count + INC HL ; Adjust memory pointer +DASMCKBTCNT:LD A,0 + CP B ; Is byte count=0? + JP Z,DASM_GVEXIT ; YES=NO Data Bytes expected - Exit + CALL ?GETMEM ; LD A,(HL) ;Get 1st Data Byte from memory + PUSH HL ; Save Address Pointer + CALL BYTE2ASCII ; Convert A to 2 ASCII Bytes in HL + LD (VAL_BUF_LO),HL ; Store 2 bytes in VAL_BUF_LO + POP HL ; Restore Address pointer + DEC B + LD A,0 + CP B ; Is byte count=0? + JP Z,DASM_GVEXIT ; YES=NO More Data Bytes expected - Exit + INC HL + CALL ?GETMEM ; LD A,(HL) ;Get 2nd Data Byte from memory + CALL BYTE2ASCII ; Convert A to 2 ASCII Bytes in HL + LD (VAL_BUF_HI),HL ; Store 2 bytes in VAL_BUF_LO +DASM_GVEXIT:RET + + ;****************************************************************** + ; DASMGETINST + ; Copy 4 byte Assembler Instruction to ASM_BUFF + ; NOTE: BLK_ADDR is set by successful find by DSMFINDOPCD + ;****************************************************************** +DASMGETINST:LD HL,(BLK_ADDR) ; Block Header Row Address ->HL + LD DE,ASM_BUF ; ASM_BUF address->DE + LD B,04h ; Byte Count=4 +DASM_MOVINS:INC HL ; Inc Block Header data pointer + LD A,(HL) ; Get 1 byte from Block Header + LD (DE),A ; Save to ASM_BUF + INC DE ; Inc destination (ASM_BUF) pointer + DEC B ; Dec byte count + JP NZ,DASM_MOVINS ; DONE? No=Continue + RET ; YES=Exit + + ;****************************************************************** + ; DSMFINDOPCD + ; ML_BUF contains 2 bytes from current memory location. + ; Search opcode table for a matching opcode + ; Return with BLK_ADDR=block header address, ROW_ADDR=found row address + ; ML_BYCOUNT=a non-zero count if match was found + ;****************************************************************** + +DSMFINDOPCD:PUSH BC + LD IX,OPCD_TABLE ; Set IX=Table Start Address +DSMFN_LOOP1:LD A,(IX+0) + CP '#' ; Is Row Byte0='#'? + JP NZ,DSMFNCKBT1 ; YES=SAVE IX->BLK_ADDR + LD (BLK_ADDR),IX + JP DSMFNNXTROW + +DSMFNCKBT1: LD A,(ML_BUF) ; IS ML_BUF0=(CB,DD,ED or FD)? + CP 0CBh + JP Z,DSMFN_CKBT2 + CP 0DDh + JP Z,DSMFN_CKBT2 + CP 0EDh + JP Z,DSMFN_CKBT2 + CP 0FDh + JP Z,DSMFN_CKBT2 + LD C,(IX+7) ; If ML_BUF0 is NOT one of the above + CP C ; Compare with row byte7 + JP NZ,DSMFNNXTROW ; NO=Next Row + LD A,0 + LD C,(IX+8) ; Get Row Byte8 + CP C ; Is it Zero + JP Z,DSMFN_MATCH ; YES=MATCH! + JP DSMFNNXTROW ; NO=Next Row + +DSMFN_CKBT2:LD C,(IX+8) ; If ML_BUF0=(CB,DD,ED or FD)? + CP C ; Compare with row byte8 + JP NZ,DSMFNNXTROW ; NO=Next Row + LD A,(ML_BUF+1) ; YES=Check Next Byte + LD C,(IX+7) ; Combare with row byte7 + CP C + JP Z,DSMFN_MATCH ; YES=MATCH! + +DSMFNNXTROW:LD BC,000Ah ; Add 10 to IX and KEEP LOOKING + ADD IX,BC + LD A,(IX+5) ; End Of Lookup Table? + CP 0 + JP NZ,DSMFN_LOOP1 ; NO=Keep Looking otherwise EXIT + +DSMFN_MATCH:LD (ROW_ADDR),IX ; Save IX->ROW_ADDR + LD A,(IX+8) + LD (ML_BUF+1),A ; Save row byte8 ->ML_BUF1 + LD A,(IX+9) + LD (ML_BTCOUNT),A ; Save byte count->ML_BYCOUNT + CP 0 ; Set Z flag if NOT FOUND + POP BC + RET + + ;****************************************************************** + ; *** END DIS_MAIN + ;****************************************************************** + + ;****************************************************************** + ; ASM_MAIN Z80 Assembler + ; Based on tables used by the TASM for the Z80 target + ;****************************************************************** +ASM_MAIN: CALL HLHEX ; Print "Enter Address:" and get 4 hex bytes + JP C,DASM_ERR + LD (ADDR),HL + + ; ** Print CR, LF, ADDR_HI, ADDR_LO (in HEX), space +ASM_LOOP1: CALL NL ; Print CR & LF + LD A,(ADDR_HI) ; Print Address Buffer + CALL PRTHX + LD A,(ADDR_LO) + CALL PRTHX + CALL PRNTS ; Print Space + + LD HL,ASM_BUF ; Clear ASM_BUF, INS_BUF, PARM_BUF & VAL_BUF + LD B,30h + CALL MEMSET + + LD DE,BUFER ; Use the SA1510 input buffer, it is larger and free format. + CALL GETL + CALL HLHEX ; Check if the address is present, if it is, update address as user may have changed it. + JR C,ASM_LOOP3 + LD (ADDR),HL +ASM_LOOP3: LD BC,01005H + LD DE,BUFER+5 ; Skip memory address. + LD HL,ASM_BUF + CALL GETSTR + LD A,0C2H ; Put cursor back to end of input line. Need to use display control for scrolling. + CALL ?DPCT ; Cursor up. + + ; Clear the line, could have old data on it. + LD A,(SCRNMODE) + LD B,39 + OR A + JR Z,ASM_LOOP4 + LD B,79 +ASM_LOOP4: CALL PRNTS + DJNZ ASM_LOOP4 + + ; Reprint the line, removing leading white space. + LD HL,(DSPXY) + LD L, 0 + LD (DSPXY),HL + LD A,(ADDR_HI) ; Print Address Buffer + CALL PRTHX + LD A,(ADDR_LO) + CALL PRTHX + CALL PRNTS ; Print Space + LD DE,ASM_BUF +ASM_LOOP5: LD A,(DE) + CP 000H + JR Z,ASM_LOOP6 + CALL PRNT + INC DE + JR ASM_LOOP5 + +ASM_LOOP6: LD HL,(DSPXY) + LD L, 22 + LD (DSPXY),HL ; To end of instruction. + + LD A,(ASM_BUF) ; Check 1st byte of ASM_BUF + CP 0 ; Nothing was entered (QUIT) + JP Z,ASM_EXIT ; Just exit + +;ASM_LOOP2: CALL PRNTS ; print spaces (16-input length from B) +; INC C +; LD A,C +; CP 0Fh +; JP M,ASM_LOOP2 + +ASM_CPYINS: LD DE,INS_BUF + LD HL,ASM_BUF + CALL CPY2SPC ; Copy the instruction from ASM_BUF to INST_BUF + CALL SKIPSPC ; find the start of the parm. bytes + + LD BC,PARM_BUF + CALL PADWSPC ; Pad the instruction buffer to 4 bytes + + ;**** Process the input parameter ***** + LD A,10h + LD B,A ; Load byte counter =16 +GET_NEXTASM:LD A,(HL) ; Get 1 byte from ASM_BUF + CP 0 ; if we reached the end of input? + JP Z,ASMLOOPEXIT ; just exit + CALL ISFLAGORNUM ; Is it $,+,# or 0-9? + JP NZ,SAVE_ASMCHR + CALL ASMGETVAL ; Extract the numbers to VAL_BUF + LD A,'*' ; Load PARM_BUF with a '*' + LD (DE),A + INC DE ; Advance dest. pointer + LD A,(HL) ; Get next non-number byte from ASM_BUF + +SAVE_ASMCHR:CP 0 ; if we reached the end while in getval()? + JP Z,ASMLOOPEXIT ; just exit + LD (DE),A ; Otherwise store the byte + INC DE ; Advance dest. pointer + INC HL ; Advance src. pointer + DEC B + JP NZ,GET_NEXTASM + +ASMLOOPEXIT:LD BC,VAL_BUF + CALL PADWSPC ; Pad the parm buffer to 7 bytes + + LD (SRC_ADDR),HL ; Save HL & DE + LD (DES_ADDR),DE + + CALL ASMFINDINST ; Find Instruction in table + LD A,(BLK_SIZE) ; Got a match? YES=search for a parameter match + CP 0 + JP NZ,ASM_FINDPRM +ASM_ERR_INS:LD DE,MSGNOINSTR + CALL ?PRINTMSG + JP ASM_LOOP1 ; Get another line of ASM input... + + +ASM_FINDPRM:CALL ASMFINDPARM ; Look for matching parameter pattern + LD A,(ML_BUF+2) ; Found one? NO=ERROR + CP 0 + JP NZ,ASMOUTML + LD DE,MSGNOPARAM + CALL ?PRINTMSG + JP ASM_LOOP1 ; Get another line of ASM input... + + +ASMOUTML: CALL RTJUSTVAL ; Right Justify VAL_BUF + + LD DE,VAL_BUF_HI ; Convert 4 ASCII Chars in VAL_BUF to 2 values + CALL HLHEX + JR C, ASM_ERR_INS ; Couldnt convert the number. + LD A,H + LD (VAL_HI),A + LD A,L + LD (VAL_LO),A + + ;; Populate OUT_BUF with ML output + LD IX,OUT_BUF + LD A,(ML_BUF+1) + CP 0 + JP Z,ASMNOBYTE2 + LD (IX),A + INC IX + CP 0CBh ; Is this a BIT,SET or RES Inst? + JP NZ,ASMNOBYTE2 ; NO=Continue + LD A,(ML_BUF) ; YES=Check 1st ML byte + AND 0C0h ; Are Bits 7 or 6 are set? + JP Z,ASMNOBYTE2 ; NO=Continue + LD A,(ML_BUF) ; YES=Combine Val with ML_BUF byte1 + LD B,A + LD A,(VAL_LO) + SLA A + SLA A + SLA A + AND 38h + OR B + LD (ML_BUF),A + +ASMNOBYTE2: LD A,(ML_BUF) + LD (IX),A + INC IX + + LD A,(VAL_LO) + LD (IX),A + INC IX + LD A,(VAL_HI) + LD (IX),A + + ;; *** Move ML code(s) to target address, *** + ;; *** print them and adjust pointer *** + ;CALL PRNTS + ;CALL PRNTS + ;CALL PRNTS + ;CALL PRNTS + +ASM_TOMEM: LD A,(ML_BTCOUNT) ; Load Byte Count ->B + LD B,A + LD IX,OUT_BUF ; Load IX with OUT_BUF address +ASM_TOMEM1: LD HL,(ADDR_LO) ; Load HL with Target Address + LD A,(IX) ; Get Byte to Move + CALL ?SETMEM ; Store at target address + CALL PRTHX ; Print it + CALL PRNTS ; Print 1 space + INC HL ; Advance Target Pointer + LD (ADDR_LO),HL ; Save in ADDR_LO & HI + INC IX ; Advance ML_BUF pointer + DEC B ; Decrement byte counter + JP NZ,ASM_TOMEM1 ; Done? NO=Continue + JP ASM_LOOP1 ; Get another line of ASM input... + +ASM_EXIT: RET + + ;****************************************************************** + ; END of ASM_MAIN + ;****************************************************************** + + ;****************************************************************** + ; Z80 Assembler Routines + ;****************************************************************** + + ; Method to get a string parameter and copy it into the provided buffer. + ; (Duplicate method, also in Bank TZFS1). + ; Inputs: + ; DE = Pointer to BUFER where user entered data has been placed. + ; HL = Pointer to Destination buffer. + ; B = Max number of characters to read. + ; Outputs: + ; DE and HL point to end of bufer and buffer resepectively. + ; B = Characters copied (ie. B - input B = no characters). + ; +GETSTR: LD A,(DE) ; Skip white space and control characters before copy. + CP 33 + JR NC, GSTR1 + CP 00DH + JR Z, GSTR2 ; No directory means use the I/O set default. + OR A + JR Z, GSTR2 + INC DE + INC C ; Count the characters on the line. + JR GETSTR +GSTR1: LD (HL),A ; Copy the name entered by user. Validation is done on the I/O processor, bad directory name will result in error next read/write. + INC DE + INC HL + INC C ; Count the characters on the line. + LD A,(DE) ; Get next char and check it isnt CR, end of input line character. + CP 00DH + JR Z,GSTR2 ; Finished if we encounter CR. + DJNZ GSTR1 ; Loop until buffer is full, ignore characters beyond buffer limit. +GSTR2: XOR A ; Place end of buffer terminator as I/O processor uses C strings. + LD (HL),A + RET + + ;****************************************************************** + ; ASMFINDPARM + ; HL=src dest = PARM_BUF + ; Search block until match of PARM_BUF or end of block is found + ; Return with HL pointing to match block B=block count + ;****************************************************************** +ASMFINDPARM:PUSH DE + PUSH BC + PUSH HL + LD IX,(BLK_ADDR) ; Load Saved Block Address->IX + LD A,(BLK_SIZE) ; Get Block Size + LD L,A ; L=ROW COUNTER +AFP_NEXTROW:LD DE,000Ah ; 10 bytes per row + ADD IX,DE ; Add 10 to Address (next block) + LD (ROW_ADDR),IX ; Save ROW Address + LD IY,PARM_BUF ; IY=PARM_BUF + LD C,07h ; Loop count =7 +AFP_CMPLOOP:LD A,(IX+0) ; Get Table byte->A + LD B,(IY+0) ; Get PARM_BUF byte->B + CP B ; Compare A-B + JP NZ,AFP_NOMATCH ; Mismatch = Exit loop + INC IX ; Advance pointers + INC IY + DEC C ; Decrement loop count + JP NZ,AFP_CMPLOOP ; Not done yet - continue + JP AFP_MATCH ; Match Found Get ML Bytes & Counts + ; Match not found, advance to next block +AFP_NOMATCH:DEC L ; Decrement row counter + JP Z,AFP_NOFIND ; Done = NOT FOUND EXIT + LD IX,(ROW_ADDR) ; Get Saved ROW Address->IX + JP AFP_NEXTROW ; Continue + +AFP_NOFIND: LD A,0 ; Not Found set ML_BUF[2]=0 + LD (ML_BUF+2),A + JP AFP_EXIT + +AFP_MATCH: LD A,(IX+0) ; Get Table ML Byte 1 + LD (ML_BUF),A ; Save it in M_BUF[0] + LD A,(IX+1) ; Get Table ML Byte 2 + LD (ML_BUF+1),A ; Save it in M_BUF[1] + LD A,(IX+2) ; Get Table ML Byte count + LD (ML_BUF+2),A ; Save it in M_BUF[2] + +AFP_EXIT: POP HL + POP BC + POP DE + RET + + ;****************************************************************** + ; ASMFINDINST + ; HL=src dest = VAL_BUF + ; Search table until match of INS_BUF or end of table is found + ; Return with IX pointing to match block B=block count + ;****************************************************************** +ASMFINDINST:PUSH DE + PUSH BC + LD A,0 + LD (ROW_NUM),A + LD IX,OPCD_TABLE +AFI_NEXTBLK:LD (BLK_ADDR),IX ; Save Block Address + LD A,(IX+5) ; Get Block Size & Save + LD (BLK_SIZE),A + CP 0 ; If Block Size = 0 EXIT + JP Z,AFI_EXIT + + LD IY,INS_BUF ; IX=INS_BUF + LD C,04h ; Loop count =4 +AFI_CMPLOOP:LD A,(IX+1) ; Get Table byte->A + LD B,(IY+0) ; Get INS_BUF byte->B + CP B ; Compare A-B + JP NZ,AFI_NOMATCH ; Mismatch = Exit loop + INC IX ; Advance pointers + INC IY + DEC C ; Decremebnt loop count + JP NZ,AFI_CMPLOOP ; Not done yet - continue + JP AFI_EXIT ; Match Found EXIT + ; Match not found, advance to next block +AFI_NOMATCH:LD A,(BLK_SIZE) ; Get Block Size + INC A ; Add 1 to Block count + LD IX,(BLK_ADDR) ; Get Saved Block Start Address + LD DE,000Ah ; 10 bytes per row +AFI_BLKLOOP:ADD IX,DE ; Add 10 to Address + DEC A ; Decrement block counter + JP NZ,AFI_BLKLOOP ; Not Done = loop + LD A,(ROW_NUM) ; Advance Row Number + INC A + LD (ROW_NUM),A + JP AFI_NEXTBLK + +AFI_EXIT: POP BC + POP DE + RET + + ;****************************************************************** + ; ASMRTJVAL + ; Shift bytes in VAL_BUF right until left padded with '0's + ;****************************************************************** +ASMRJTVAL: PUSH DE + PUSH BC + LD IX,VAL_BUF + LD B,05h ; B=MAX search count 5 + +ASMRJT_LOOP:LD A,(IX+3) ; Get last byte from VAL_BUF + CP ' ' ; Is It SPACE? + JP NZ,ASMRJT_EXIT ; Exit + LD A,(IX+2) ; Shift 3 bytes left 1 positiom + LD (IX+3),A + LD A,(IX+1) + LD (IX+2),A + LD A,(IX+0) + LD (IX+1),A + LD A,'0' ; Pad first position with '0' + LD (IX+0),A + DEC B + JP NZ,ASMRJT_LOOP + +ASMRJT_EXIT:POP BC + POP DE + RET + + ;****************************************************************** + ; ASMGETVAL + ; HL=src dest = VAL_BUF + ; Copy bytes from src to dest until a non digit is encountered (4 bytes max.) + ; skip over number flags ('$','+,'#') + ;****************************************************************** +ASMGETVAL: PUSH DE + PUSH BC + LD DE,VAL_BUF + LD B,05h ; B=MAX search count 5 +ASMGVL_LOOP:LD A,(HL) ; Get a byte from ASM_BUF + + CP 0 ; End of input? + JP Z,ASMGVL_EXIT ; Exit + + CALL ISVALFLAG ; Test A for '#' '$' or '+' + JP Z,ASMGVL_SKIP ; If match then just skip it + + CALL IS_DIGIT ; Is A= '0'-'9' or 'A'-'F'? + JP NZ,ASMGVL_EXIT + LD (DE),A ; Save the byte to VAL_BUF + INC DE ; Advance the destination pointer +ASMGVL_SKIP:INC HL ; Advance the sourc pointer + DEC B ; Decrement byte count + JP NZ,ASMGVL_LOOP ; Max reached? NO=Continue +ASMGVL_EXIT:POP BC + POP DE + RET + + ;****************************************************************** + ; ISFLAGORNUM + ; + ; RETURN Z=1 if A = '$', '+' ,'#' or '0'-'9' + ;****************************************************************** +ISFLAGORNUM:CALL ISVALFLAG ; is A ='$','#' or '+'? + JP Z,ISNUMF_ZRET ; YES=return Z=1 + + CALL ISDECDIGIT ; Test for '0-'9' +ISNUMF_ZRET:RET ;(Z is set accordingly) + + ;****************************************************************** + ; ISVALFLAG + ; + ; RETURN Z=1 if A = '$', '+' ,'#' or '0'-'9' (A is unchanged ) + ; NOTE: A MUST be a non-zero ASCII Digit + ;****************************************************************** +ISVALFLAG: CP '$' ; is A ='$'? + JP Z,ISVALF_ZRET ; YES=return Z=1 + CP '+' ; is A ='+'? + JP Z,ISVALF_ZRET ; YES=return Z=1 + CP '#' ; is A ='#'? + JP Z,ISVALF_ZRET ; YES=return Z=1 + + CP 0 ; Otherwise set Z=0 +ISVALF_ZRET:RET + ;****************************************************************** + ; PADWSPC + ; DE=dest BC=END + ; starting at current DE fill with spaces until DE=BC + ; NOTE: BC MUST BE > DE no bounds checking is done + ;****************************************************************** +PADWSPC: LD A,B + CP D + JP NZ,DOPADWSPC + LD A,C + CP E + JP M,PADWSP_EXIT + JP NZ,DOPADWSPC +PADWSP_EXIT:RET +DOPADWSPC: LD A,' ' + LD (DE),A + INC DE + JP PADWSPC + + ;****************************************************************** + ; SKIPSPC + ; HL=src b=MAX + ; advance HL until it is pointing at a non-space byte (16 bytes max.) + ;****************************************************************** +SKIPSPC: LD B,10h ; B= MAX byte count 16 +SKIPSP_LOOP:LD A,(HL) + INC HL + CP ' ' + JP Z,SKIPSP_EXIT + CP 0 + JP Z,SKIPSP_EXIT + DEC B + JP NZ,SKIPSP_LOOP +SKIPSP_EXIT:RET + + ;****************************************************************** + ; CPY2SPC + ; HL=src DE=dest b=count + ; Copy bytes from src to dest until a space is encountered (12 bytes max.) + ;****************************************************************** +CPY2SPC: LD B,0Ch ; B= MAX byte count 12 +CPY2SP_LOOP:LD A,(HL) + CP ' ' + JP Z,CPY2SP_EXIT ; Found space so EXIT + + CP 0 + JP NZ,CPY2SP_COPY ; Found NULL before space + LD A,' ' + LD (HL),A ; Replace with space & exit + INC HL + LD A,0 ; Terminate + LD (HL),A + DEC HL + JP CPY2SP_EXIT + +CPY2SP_COPY:LD (DE),A ; Copy the byte + INC DE ; Advance destination pointer + INC HL ; Advance source pointer + DEC B ; Decremet byte count + JP NZ,CPY2SP_LOOP ; If MAX not reached continue... +CPY2SP_EXIT:RET + + ;------------------------------------------------------------------------------- + ; Z80 Assembler lookup table + ; FORMAT: 10 bytes per row + ; Instruction Blocks: start with # followed by 4 char instruction + ; byte 5 = #of rows for this instruction + ; Parameter Blocks: A 7 byte parameter pattern + ; Opcode byte 1, Opcode byte 2(if any otherwise zero) + ; Number of byte used for opcodes & data parameters. + ;------------------------------------------------------------------------------- +OPCD_TABLE: DB "#ADC ", 00FH, 000H, 000H, 000H, 000H + DB "A,(HL) ", 08EH, 000H, 001H + DB "A,(IX*)", 08EH, 0DDH, 003H + DB "A,(IY*)", 08EH, 0FDH, 003H + DB "A,A ", 08FH, 000H, 001H + DB "A,B ", 088H, 000H, 001H + DB "A,C ", 089H, 000H, 001H + DB "A,D ", 08AH, 000H, 001H + DB "A,E ", 08BH, 000H, 001H + DB "A,H ", 08CH, 000H, 001H + DB "A,L ", 08DH, 000H, 001H + DB "A,* ", 0CEH, 000H, 002H + DB "HL,BC ", 04AH, 0EDH, 002H + DB "HL,DE ", 05AH, 0EDH, 002H + DB "HL,HL ", 06AH, 0EDH, 002H + DB "HL,SP ", 07AH, 0EDH, 002H + DB "#ADD ", 017H, 000H, 000H, 000H, 000H + DB "A,(HL) ", 086H, 000H, 001H + DB "A,(IX*)", 086H, 0DDH, 003H + DB "A,(IY*)", 086H, 0FDH, 003H + DB "A,A ", 087H, 000H, 001H + DB "A,B ", 080H, 000H, 001H + DB "A,C ", 081H, 000H, 001H + DB "A,D ", 082H, 000H, 001H + DB "A,E ", 083H, 000H, 001H + DB "A,H ", 084H, 000H, 001H + DB "A,L ", 085H, 000H, 001H + DB "A,* ", 0C6H, 000H, 002H + DB "HL,BC ", 009H, 000H, 001H + DB "HL,DE ", 019H, 000H, 001H + DB "HL,HL ", 029H, 000H, 001H + DB "HL,SP ", 039H, 000H, 001H + DB "IX,BC ", 009H, 0DDH, 002H + DB "IX,DE ", 019H, 0DDH, 002H + DB "IX,IX ", 029H, 0DDH, 002H + DB "IX,SP ", 039H, 0DDH, 002H + DB "IY,BC ", 009H, 0FDH, 002H + DB "IY,DE ", 019H, 0FDH, 002H + DB "IY,IY ", 029H, 0FDH, 002H + DB "IY,SP ", 039H, 0FDH, 002H + DB "#AND ", 00BH, 000H, 000H, 000H, 000H + DB "(HL) ", 0A6H, 000H, 001H + DB "(IX*) ", 0A6H, 0DDH, 003H + DB "(IY*) ", 0A6H, 0FDH, 003H + DB "A ", 0A7H, 000H, 001H + DB "B ", 0A0H, 000H, 001H + DB "C ", 0A1H, 000H, 001H + DB "D ", 0A2H, 000H, 001H + DB "E ", 0A3H, 000H, 001H + DB "H ", 0A4H, 000H, 001H + DB "L ", 0A5H, 000H, 001H + DB "* ", 0E6H, 000H, 002H + DB "#BIT ", 008H, 000H, 000H, 000H, 000H + DB "*,(HL) ", 046H, 0CBH, 002H + DB "*,A ", 047H, 0CBH, 002H + DB "*,B ", 040H, 0CBH, 002H + DB "*,C ", 041H, 0CBH, 002H + DB "*,D ", 042H, 0CBH, 002H + DB "*,E ", 043H, 0CBH, 002H + DB "*,H ", 044H, 0CBH, 002H + DB "*,L ", 045H, 0CBH, 002H + DB "#CALL", 009H, 000H, 000H, 000H, 000H + DB "C,* ", 0DCH, 000H, 003H + DB "M,* ", 0FCH, 000H, 003H + DB "NC,* ", 0D4H, 000H, 003H + DB "NZ,* ", 0C4H, 000H, 003H + DB "P,* ", 0F4H, 000H, 003H + DB "PE,* ", 0ECH, 000H, 003H + DB "PO,* ", 0E4H, 000H, 003H + DB "Z,* ", 0CCH, 000H, 003H + DB "* ", 0CDH, 000H, 003H + DB "#CCF ", 001H, 000H, 000H, 000H, 000H + DB " ", 03FH, 000H, 001H + DB "#CP ", 00BH, 000H, 000H, 000H, 000H + DB "(HL) ", 0BEH, 000H, 001H + DB "(IX*) ", 0BEH, 0DDH, 003H + DB "(IY*) ", 0BEH, 0FDH, 003H + DB "A ", 0BFH, 000H, 001H + DB "B ", 0B8H, 000H, 001H + DB "C ", 0B9H, 000H, 001H + DB "D ", 0BAH, 000H, 001H + DB "E ", 0BBH, 000H, 001H + DB "H ", 0BCH, 000H, 001H + DB "L ", 0BDH, 000H, 001H + DB "* ", 0FEH, 000H, 002H + DB "#CPD ", 001H, 000H, 000H, 000H, 000H + DB " ", 0A9H, 0EDH, 002H + DB "#CPDR", 001H, 000H, 000H, 000H, 000H + DB " ", 0B9H, 0EDH, 002H + DB "#CPIR", 001H, 000H, 000H, 000H, 000H + DB " ", 0B1H, 0EDH, 002H + DB "#CPI ", 001H, 000H, 000H, 000H, 000H + DB " ", 0A1H, 0EDH, 002H + DB "#CPL ", 001H, 000H, 000H, 000H, 000H + DB " ", 02FH, 000H, 001H + DB "#DAA ", 001H, 000H, 000H, 000H, 000H + DB " ", 027H, 000H, 001H + DB "#DEC ", 010H, 000H, 000H, 000H, 000H + DB "(HL) ", 035H, 000H, 001H + DB "(IX*) ", 035H, 0DDH, 003H + DB "(IY*) ", 035H, 0FDH, 003H + DB "A ", 03DH, 000H, 001H + DB "B ", 005H, 000H, 001H + DB "BC ", 00BH, 000H, 001H + DB "C ", 00DH, 000H, 001H + DB "D ", 015H, 000H, 001H + DB "DE ", 01BH, 000H, 001H + DB "E ", 01DH, 000H, 001H + DB "H ", 025H, 000H, 001H + DB "HL ", 02BH, 000H, 001H + DB "IX ", 02BH, 0DDH, 002H + DB "IY ", 02BH, 0FDH, 002H + DB "L ", 02DH, 000H, 001H + DB "SP ", 03BH, 000H, 001H + DB "#DI ", 001H, 000H, 000H, 000H, 000H + DB " ", 0F3H, 000H, 001H + DB "#DJNZ", 001H, 000H, 000H, 000H, 000H + DB "* ", 010H, 000H, 002H + DB "#EI ", 001H, 000H, 000H, 000H, 000H + DB " ", 0FBH, 000H, 001H + DB "#EX ", 005H, 000H, 000H, 000H, 000H + DB "(SP),HL", 0E3H, 000H, 001H + DB "(SP),IX", 0E3H, 0DDH, 002H + DB "(SP),IY", 0E3H, 0FDH, 002H + DB "AF,AF", 02CH, 020H, 008H, 000H, 001H + DB "DE,HL ", 0EBH, 000H, 001H + DB "#EXX ", 001H, 000H, 000H, 000H, 000H + DB " ", 0D9H, 000H, 001H + DB "#HALT", 001H, 000H, 000H, 000H, 000H + DB " ", 076H, 000H, 001H + DB "#IM ", 003H, 000H, 000H, 000H, 000H + DB "0 ", 046H, 0EDH, 002H + DB "1 ", 056H, 0EDH, 002H + DB "2 ", 05EH, 0EDH, 002H + DB "#IN ", 008H, 000H, 000H, 000H, 000H + DB "A,(C) ", 078H, 0EDH, 002H + DB "B,(C) ", 040H, 0EDH, 002H + DB "C,(C) ", 048H, 0EDH, 002H + DB "D,(C) ", 050H, 0EDH, 002H + DB "E,(C) ", 058H, 0EDH, 002H + DB "H,(C) ", 060H, 0EDH, 002H + DB "L,(C) ", 068H, 0EDH, 002H + DB "A,(*) ", 0DBH, 000H, 002H + DB "#IN0 ", 007H, 000H, 000H, 000H, 000H + DB " A,(*) ", 038H, 0EDH, 003H + DB " B,(*) ", 000H, 0EDH, 003H + DB " C,(*) ", 008H, 0EDH, 003H + DB " D,(*) ", 010H, 0EDH, 003H + DB " E,(*) ", 018H, 0EDH, 003H + DB " H,(*) ", 020H, 0EDH, 003H + DB " L,(*) ", 028H, 0EDH, 003H + DB "#INC ", 010H, 000H, 000H, 000H, 000H + DB "(HL) ", 034H, 000H, 001H + DB "(IX*) ", 034H, 0DDH, 003H + DB "(IY*) ", 034H, 0FDH, 003H + DB "A ", 03CH, 000H, 001H + DB "B ", 004H, 000H, 001H + DB "BC ", 003H, 000H, 001H + DB "C ", 00CH, 000H, 001H + DB "D ", 014H, 000H, 001H + DB "DE ", 013H, 000H, 001H + DB "E ", 01CH, 000H, 001H + DB "H ", 024H, 000H, 001H + DB "HL ", 023H, 000H, 001H + DB "IX ", 023H, 0DDH, 002H + DB "IY ", 023H, 0FDH, 002H + DB "L ", 02CH, 000H, 001H + DB "SP ", 033H, 000H, 001H + DB "#IND ", 001H, 000H, 000H, 000H, 000H + DB " ", 0AAH, 0EDH, 002H + DB "#INDR", 001H, 000H, 000H, 000H, 000H + DB " ", 0BAH, 0EDH, 002H + DB "#INI ", 001H, 000H, 000H, 000H, 000H + DB " ", 0A2H, 0EDH, 002H + DB "#INIR", 001H, 000H, 000H, 000H, 000H + DB " ", 0B2H, 0EDH, 002H + DB "#JP ", 00CH, 000H, 000H, 000H, 000H + DB "(HL) ", 0E9H, 000H, 001H + DB "(IX) ", 0E9H, 0DDH, 002H + DB "(IY) ", 0E9H, 0FDH, 002H + DB "C,* ", 0DAH, 000H, 003H + DB "M,* ", 0FAH, 000H, 003H + DB "NC,* ", 0D2H, 000H, 003H + DB "NZ,* ", 0C2H, 000H, 003H + DB "P,* ", 0F2H, 000H, 003H + DB "PE,* ", 0EAH, 000H, 003H + DB "PO,* ", 0E2H, 000H, 003H + DB "Z,* ", 0CAH, 000H, 003H + DB "* ", 0C3H, 000H, 003H + DB "#JR ", 005H, 000H, 000H, 000H, 000H + DB "C,* ", 038H, 000H, 002H + DB "NC,* ", 030H, 000H, 002H + DB "NZ,* ", 020H, 000H, 002H + DB "Z,* ", 028H, 000H, 002H + DB "* ", 018H, 000H, 002H + DB "#LD ", 084H, 000H, 000H, 000H, 000H + DB "(BC),A ", 002H, 000H, 001H + DB "(DE),A ", 012H, 000H, 001H + DB "(HL),A ", 077H, 000H, 001H + DB "(HL),B ", 070H, 000H, 001H + DB "(HL),C ", 071H, 000H, 001H + DB "(HL),D ", 072H, 000H, 001H + DB "(HL),E ", 073H, 000H, 001H + DB "(HL),H ", 074H, 000H, 001H + DB "(HL),L ", 075H, 000H, 001H + DB "(HL),* ", 036H, 000H, 002H + DB "(IX*),A", 077H, 0DDH, 003H + DB "(IX*),B", 070H, 0DDH, 003H + DB "(IX*),C", 071H, 0DDH, 003H + DB "(IX*),D", 072H, 0DDH, 003H + DB "(IX*),E", 073H, 0DDH, 003H + DB "(IX*),H", 074H, 0DDH, 003H + DB "(IX*),L", 075H, 0DDH, 003H + DB "(IX*),*", 036H, 0DDH, 004H + DB "(IY*),A", 077H, 0FDH, 003H + DB "(IY*),B", 070H, 0FDH, 003H + DB "(IY*),C", 071H, 0FDH, 003H + DB "(IY*),D", 072H, 0FDH, 003H + DB "(IY*),E", 073H, 0FDH, 003H + DB "(IY*),H", 074H, 0FDH, 003H + DB "(IY*),L", 075H, 0FDH, 003H + DB "(IY*),*", 036H, 0FDH, 004H + DB "(*),A ", 032H, 000H, 003H + DB "(*),BC ", 043H, 0EDH, 004H + DB "(*),DE ", 053H, 0EDH, 004H + DB "(*),HL ", 022H, 000H, 003H + DB "(*),IX ", 022H, 0DDH, 004H + DB "(*),IY ", 022H, 0FDH, 004H + DB "(*),SP ", 073H, 0EDH, 004H + DB "A,(BC) ", 00AH, 000H, 001H + DB "A,(DE) ", 01AH, 000H, 001H + DB "A,(HL) ", 07EH, 000H, 001H + DB "A,(IX*)", 07EH, 0DDH, 003H + DB "A,(IY*)", 07EH, 0FDH, 003H + DB "A,A ", 07FH, 000H, 001H + DB "A,B ", 078H, 000H, 001H + DB "A,C ", 079H, 000H, 001H + DB "A,D ", 07AH, 000H, 001H + DB "A,E ", 07BH, 000H, 001H + DB "A,H ", 07CH, 000H, 001H + DB "A,I ", 057H, 0EDH, 002H + DB "A,L ", 07DH, 000H, 001H + DB "A,R ", 05FH, 0EDH, 002H + DB "A,(*) ", 03AH, 000H, 003H + DB "A,* ", 03EH, 000H, 002H + DB "B,(HL) ", 046H, 000H, 001H + DB "B,(IX*)", 046H, 0DDH, 003H + DB "B,(IY*)", 046H, 0FDH, 003H + DB "B,A ", 047H, 000H, 001H + DB "B,B ", 040H, 000H, 001H + DB "B,C ", 041H, 000H, 001H + DB "B,D ", 042H, 000H, 001H + DB "B,E ", 043H, 000H, 001H + DB "B,H ", 044H, 000H, 001H + DB "B,L ", 045H, 000H, 001H + DB "B,* ", 006H, 000H, 002H + DB "BC,(*) ", 04BH, 0EDH, 004H + DB "BC,* ", 001H, 000H, 003H + DB "C,(HL) ", 04EH, 000H, 001H + DB "C,(IX*)", 04EH, 0DDH, 003H + DB "C,(IY*)", 04EH, 0FDH, 003H + DB "C,A ", 04FH, 000H, 001H + DB "C,B ", 048H, 000H, 001H + DB "C,C ", 049H, 000H, 001H + DB "C,D ", 04AH, 000H, 001H + DB "C,E ", 04BH, 000H, 001H + DB "C,H ", 04CH, 000H, 001H + DB "C,L ", 04DH, 000H, 001H + DB "C,* ", 00EH, 000H, 002H + DB "D,(HL) ", 056H, 000H, 001H + DB "D,(IX*)", 056H, 0DDH, 003H + DB "D,(IY*)", 056H, 0FDH, 003H + DB "D,A ", 057H, 000H, 001H + DB "D,B ", 050H, 000H, 001H + DB "D,C ", 051H, 000H, 001H + DB "D,D ", 052H, 000H, 001H + DB "D,E ", 053H, 000H, 001H + DB "D,H ", 054H, 000H, 001H + DB "D,L ", 055H, 000H, 001H + DB "D,* ", 016H, 000H, 002H + DB "DE,(*) ", 05BH, 0EDH, 004H + DB "DE,* ", 011H, 000H, 003H + DB "E,(HL) ", 05EH, 000H, 001H + DB "E,(IX*)", 05EH, 0DDH, 003H + DB "E,(IY*)", 05EH, 0FDH, 003H + DB "E,A ", 05FH, 000H, 001H + DB "E,B ", 058H, 000H, 001H + DB "E,C ", 059H, 000H, 001H + DB "E,D ", 05AH, 000H, 001H + DB "E,E ", 05BH, 000H, 001H + DB "E,H ", 05CH, 000H, 001H + DB "E,L ", 05DH, 000H, 001H + DB "E,* ", 01EH, 000H, 002H + DB "H,(HL) ", 066H, 000H, 001H + DB "H,(IX*)", 066H, 0DDH, 003H + DB "H,(IY*)", 066H, 0FDH, 003H + DB "H,A ", 067H, 000H, 001H + DB "H,B ", 060H, 000H, 001H + DB "H,C ", 061H, 000H, 001H + DB "H,D ", 062H, 000H, 001H + DB "H,E ", 063H, 000H, 001H + DB "H,H ", 064H, 000H, 001H + DB "H,L ", 065H, 000H, 001H + DB "H,* ", 026H, 000H, 002H + DB "HL,(*) ", 02AH, 000H, 003H + DB "HL,* ", 021H, 000H, 003H + DB "I,A ", 047H, 0EDH, 002H + DB "IX,(*) ", 02AH, 0DDH, 004H + DB "IX,* ", 021H, 0DDH, 004H + DB "IY,(*) ", 02AH, 0FDH, 004H + DB "IY,* ", 021H, 0FDH, 004H + DB "L,(HL) ", 06EH, 000H, 001H + DB "L,(IX*)", 06EH, 0DDH, 003H + DB "L,(IY*)", 06EH, 0FDH, 003H + DB "L,A ", 06FH, 000H, 001H + DB "L,B ", 068H, 000H, 001H + DB "L,C ", 069H, 000H, 001H + DB "L,D ", 06AH, 000H, 001H + DB "L,E ", 06BH, 000H, 001H + DB "L,H ", 06CH, 000H, 001H + DB "L,L ", 06DH, 000H, 001H + DB "L,* ", 02EH, 000H, 002H + DB "R,A ", 04FH, 0EDH, 002H + DB "SP,(*) ", 07BH, 0EDH, 004H + DB "SP,HL ", 0F9H, 000H, 001H + DB "SP,IX ", 0F9H, 0DDH, 002H + DB "SP,IY ", 0F9H, 0FDH, 002H + DB "SP,* ", 031H, 000H, 003H + DB "#LDD ", 001H, 000H, 000H, 000H, 000H + DB " ", 0A8H, 0EDH, 002H + DB "#LDDR", 001H, 000H, 000H, 000H, 000H + DB " ", 0B8H, 0EDH, 002H + DB "#LDI ", 001H, 000H, 000H, 000H, 000H + DB " ", 0A0H, 0EDH, 002H + DB "#LDIR", 001H, 000H, 000H, 000H, 000H + DB " ", 0B0H, 0EDH, 002H + DB "#NEG ", 001H, 000H, 000H, 000H, 000H + DB " ", 044H, 0EDH, 002H + DB "#NOP ", 001H, 000H, 000H, 000H, 000H + DB " ", 000H, 000H, 001H + DB "#OR ", 00BH, 000H, 000H, 000H, 000H + DB "(HL) ", 0B6H, 000H, 001H + DB "(IX*) ", 0B6H, 0DDH, 003H + DB "(IY*) ", 0B6H, 0FDH, 003H + DB "A ", 0B7H, 000H, 001H + DB "B ", 0B0H, 000H, 001H + DB "C ", 0B1H, 000H, 001H + DB "D ", 0B2H, 000H, 001H + DB "E ", 0B3H, 000H, 001H + DB "H ", 0B4H, 000H, 001H + DB "L ", 0B5H, 000H, 001H + DB "* ", 0F6H, 000H, 002H + DB "#OTDR", 001H, 000H, 000H, 000H, 000H + DB " ", 0BBH, 0EDH, 002H + DB "#OTIR", 001H, 000H, 000H, 000H, 000H + DB " ", 0B3H, 0EDH, 002H + DB "#OUT ", 008H, 000H, 000H, 000H, 000H + DB "(C),A ", 079H, 0EDH, 002H + DB "(C),B ", 041H, 0EDH, 002H + DB "(C),C ", 049H, 0EDH, 002H + DB "(C),D ", 051H, 0EDH, 002H + DB "(C),E ", 059H, 0EDH, 002H + DB "(C),H ", 061H, 0EDH, 002H + DB "(C),L ", 069H, 0EDH, 002H + DB "(*),A ", 0D3H, 000H, 002H + DB "#OUT0", 007H, 000H, 000H, 000H, 000H + DB "(*),A ", 039H, 0EDH, 003H + DB "(*),B ", 001H, 0EDH, 003H + DB "(*),C ", 009H, 0EDH, 003H + DB "(*),D ", 011H, 0EDH, 003H + DB "(*),E ", 019H, 0EDH, 003H + DB "(*),H ", 021H, 0EDH, 003H + DB "(*),L ", 029H, 0EDH, 003H + DB "#OUTD", 001H, 000H, 000H, 000H, 000H + DB " ", 0ABH, 0EDH, 002H + DB "#OUTI", 001H, 000H, 000H, 000H, 000H + DB " ", 0A3H, 0EDH, 002H + DB "#POP ", 006H, 000H, 000H, 000H, 000H + DB "AF ", 0F1H, 000H, 001H + DB "BC ", 0C1H, 000H, 001H + DB "DE ", 0D1H, 000H, 001H + DB "HL ", 0E1H, 000H, 001H + DB "IX ", 0E1H, 0DDH, 002H + DB "IY ", 0E1H, 0FDH, 002H + DB "#PUSH", 006H, 000H, 000H, 000H, 000H + DB "AF ", 0F5H, 000H, 001H + DB "BC ", 0C5H, 000H, 001H + DB "DE ", 0D5H, 000H, 001H + DB "HL ", 0E5H, 000H, 001H + DB "IX ", 0E5H, 0DDH, 002H + DB "IY ", 0E5H, 0FDH, 002H + DB "#RES ", 008H, 000H, 000H, 000H, 000H + DB "*,(HL) ", 086H, 0CBH, 002H + DB "*,A ", 087H, 0CBH, 002H + DB "*,B ", 080H, 0CBH, 002H + DB "*,C ", 081H, 0CBH, 002H + DB "*,D ", 082H, 0CBH, 002H + DB "*,E ", 083H, 0CBH, 002H + DB "*,H ", 084H, 0CBH, 002H + DB "*,L ", 085H, 0CBH, 002H + DB "#RET ", 009H, 000H, 000H, 000H, 000H + DB " ", 0C9H, 000H, 001H + DB "C ", 0D8H, 000H, 001H + DB "M ", 0F8H, 000H, 001H + DB "NC ", 0D0H, 000H, 001H + DB "NZ ", 0C0H, 000H, 001H + DB "P ", 0F0H, 000H, 001H + DB "PE ", 0E8H, 000H, 001H + DB "PO ", 0E0H, 000H, 001H + DB "Z ", 0C8H, 000H, 001H + DB "#RETI", 001H, 000H, 000H, 000H, 000H + DB " ", 04DH, 0EDH, 002H + DB "#RETN", 001H, 000H, 000H, 000H, 000H + DB " ", 045H, 0EDH, 002H + DB "#RL ", 008H, 000H, 000H, 000H, 000H + DB "(HL) ", 016H, 0CBH, 002H + DB "A ", 017H, 0CBH, 002H + DB "B ", 010H, 0CBH, 002H + DB "C ", 011H, 0CBH, 002H + DB "D ", 012H, 0CBH, 002H + DB "E ", 013H, 0CBH, 002H + DB "H ", 014H, 0CBH, 002H + DB "L ", 015H, 0CBH, 002H + DB "#RLA ", 001H, 000H, 000H, 000H, 000H + DB " ", 017H, 000H, 001H + DB "#RLC ", 008H, 000H, 000H, 000H, 000H + DB "(HL) ", 006H, 0CBH, 002H + DB "A ", 007H, 0CBH, 002H + DB "B ", 000H, 0CBH, 002H + DB "C ", 001H, 0CBH, 002H + DB "D ", 002H, 0CBH, 002H + DB "E ", 003H, 0CBH, 002H + DB "H ", 004H, 0CBH, 002H + DB "L ", 005H, 0CBH, 002H + DB "#RLCA", 001H, 000H, 000H, 000H, 000H + DB " ", 007H, 000H, 001H + DB "#RLD ", 001H, 000H, 000H, 000H, 000H + DB " ", 06FH, 0EDH, 002H + DB "#RR ", 008H, 000H, 000H, 000H, 000H + DB "(HL) ", 01EH, 0CBH, 002H + DB "A ", 01FH, 0CBH, 002H + DB "B ", 018H, 0CBH, 002H + DB "C ", 019H, 0CBH, 002H + DB "D ", 01AH, 0CBH, 002H + DB "E ", 01BH, 0CBH, 002H + DB "H ", 01CH, 0CBH, 002H + DB "L ", 01DH, 0CBH, 002H + DB "#RRA ", 001H, 000H, 000H, 000H, 000H + DB " ", 01FH, 000H, 001H + DB "#RRC ", 008H, 000H, 000H, 000H, 000H + DB "(HL) ", 00EH, 0CBH, 002H + DB "A ", 00FH, 0CBH, 002H + DB "B ", 008H, 0CBH, 002H + DB "C ", 009H, 0CBH, 002H + DB "D ", 00AH, 0CBH, 002H + DB "E ", 00BH, 0CBH, 002H + DB "H ", 00CH, 0CBH, 002H + DB "L ", 00DH, 0CBH, 002H + DB "#RRCA", 001H, 000H, 000H, 000H, 000H + DB " ", 00FH, 000H, 001H + DB "#RRD ", 001H, 000H, 000H, 000H, 000H + DB " ", 067H, 0EDH, 002H + DB "#RST ", 008H, 000H, 000H, 000H, 000H + DB "00H ", 0C7H, 000H, 001H + DB "08H ", 0CFH, 000H, 001H + DB "10H ", 0D7H, 000H, 001H + DB "18H ", 0DFH, 000H, 001H + DB "20H ", 0E7H, 000H, 001H + DB "28H ", 0EFH, 000H, 001H + DB "30H ", 0F7H, 000H, 001H + DB "38H ", 0FFH, 000H, 001H + DB "#SBC ", 00FH, 000H, 000H, 000H, 000H + DB "A,(HL) ", 09EH, 000H, 001H + DB "A,(IX*)", 09EH, 0DDH, 003H + DB "A,(IY*)", 09EH, 0FDH, 003H + DB "A,A ", 09FH, 000H, 001H + DB "A,B ", 098H, 000H, 001H + DB "A,C ", 099H, 000H, 001H + DB "A,D ", 09AH, 000H, 001H + DB "A,E ", 09BH, 000H, 001H + DB "A,H ", 09CH, 000H, 001H + DB "A,L ", 09DH, 000H, 001H + DB "HL,BC ", 042H, 0EDH, 002H + DB "HL,DE ", 052H, 0EDH, 002H + DB "HL,HL ", 062H, 0EDH, 002H + DB "HL,SP ", 072H, 0EDH, 002H + DB "A,* ", 0DEH, 000H, 002H + DB "#SCF ", 001H, 000H, 000H, 000H, 000H + DB " ", 037H, 000H, 001H + DB "#SET ", 008H, 000H, 000H, 000H, 000H + DB "*,(HL) ", 0C6H, 0CBH, 002H + DB "*,A ", 0C7H, 0CBH, 002H + DB "*,B ", 0C0H, 0CBH, 002H + DB "*,C ", 0C1H, 0CBH, 002H + DB "*,D ", 0C2H, 0CBH, 002H + DB "*,E ", 0C3H, 0CBH, 002H + DB "*,H ", 0C4H, 0CBH, 002H + DB "*,L ", 0C5H, 0CBH, 002H + DB "#SLA ", 008H, 000H, 000H, 000H, 000H + DB "(HL) ", 026H, 0CBH, 002H + DB "A ", 027H, 0CBH, 002H + DB "B ", 020H, 0CBH, 002H + DB "C ", 021H, 0CBH, 002H + DB "D ", 022H, 0CBH, 002H + DB "E ", 023H, 0CBH, 002H + DB "H ", 024H, 0CBH, 002H + DB "L ", 025H, 0CBH, 002H + DB "#SRA ", 008H, 000H, 000H, 000H, 000H + DB "(HL) ", 02EH, 0CBH, 002H + DB "A ", 02FH, 0CBH, 002H + DB "B ", 028H, 0CBH, 002H + DB "C ", 029H, 0CBH, 002H + DB "D ", 02AH, 0CBH, 002H + DB "E ", 02BH, 0CBH, 002H + DB "H ", 02CH, 0CBH, 002H + DB "L ", 02DH, 0CBH, 002H + DB "#SRL ", 008H, 000H, 000H, 000H, 000H + DB "(HL) ", 03EH, 0CBH, 002H + DB "A ", 03FH, 0CBH, 002H + DB "B ", 038H, 0CBH, 002H + DB "C ", 039H, 0CBH, 002H + DB "D ", 03AH, 0CBH, 002H + DB "E ", 03BH, 0CBH, 002H + DB "H ", 03CH, 0CBH, 002H + DB "L ", 03DH, 0CBH, 002H + DB "#SUB ", 00BH, 000H, 000H, 000H, 000H + DB "(HL) ", 096H, 000H, 001H + DB "(IX*) ", 096H, 0DDH, 003H + DB "(IY*) ", 096H, 0FDH, 003H + DB "A ", 097H, 000H, 001H + DB "B ", 090H, 000H, 001H + DB "C ", 091H, 000H, 001H + DB "D ", 092H, 000H, 001H + DB "E ", 093H, 000H, 001H + DB "H ", 094H, 000H, 001H + DB "L ", 095H, 000H, 001H + DB "* ", 0D6H, 000H, 002H + DB "#XOR ", 00BH, 000H, 000H, 000H, 000H + DB "(HL) ", 0AEH, 000H, 001H + DB "(IX*) ", 0AEH, 0DDH, 003H + DB "(IY*) ", 0AEH, 0FDH, 003H + DB "A ", 0AFH, 000H, 001H + DB "B ", 0A8H, 000H, 001H + DB "C ", 0A9H, 000H, 001H + DB "D ", 0AAH, 000H, 001H + DB "E ", 0ABH, 000H, 001H + DB "H ", 0ACH, 000H, 001H + DB "L ", 0ADH, 000H, 001H + DB "* ", 0EEH, 000H, 002H + DB "#END ", 000H, 000H, 000H, 000H, 000H + ;------------------------------------------------------------------------------- + ; END of Z80 Assembler lookup table + ;------------------------------------------------------------------------------- + + ; Fill remaining bytes with NOP's (000H). + ALIGN_NOPS 0D000H + + ; Next block of code goes up in the F000:FFFF ROM space. + ; ORG BANKRAMADDR ;------------------------------------------------------------------------------- ; START OF ADDITIONAL TZFS COMMANDS ;------------------------------------------------------------------------------- + ; Copy - Source, Destination, Size. +COPYM: CALL READ4HEX ; Start address + JR C,COPYMERR + LD (TMPADR),HL + CALL READ4HEX + JR C,COPYMERR + LD (TMPCNT),HL + CALL READ4HEX + JR C,COPYMERR + PUSH HL + POP BC + LD HL,(TMPCNT) + LD DE,(TMPADR) + LDIR +COPYMERR: RET + + ; Write to I/O port. 16bit address to BC, 8bit value to A. +WRITEIO: CALL READ4HEX ; Get 16bit I/O port. + JR C,WRITEIOER + PUSH HL ; Swap to BC so B=15:8, C=7:0 + POP BC + CALL _2HEX ; Get 8 bit data. + OUT (C),A ; Write 8 bit data to 16bit port. +WRITEIOER: RET + + ; Read 16bit I/O port value. +READIO: CALL READ4HEX ; Get 16bit I/O port. + JR C,READIOER + PUSH HL ; Swap to BC so B=15:8, C=7:0 + POP BC + IN A,(C) ; Get 8bit value from 16bit I/O port. + CALL PRTHX ; Print. + CALL NL +READIOER: RET + + + ; FusionX doesnt yet have the video capabilities, so no need to build in the logic. + IF BUILD_FUSIONX = 0 + ; Method to set the video mode. ; Param: 0 - Enable FPGA and set to MZ-80K mode. ; 1 - Enable FPGA and set to MZ-80C mode. @@ -154,6 +1805,7 @@ SETVBORDER: IN A,(CPLDINFO) ; Get c LD A,L OUT (VMVGATTR),A RET + ENDIF ; BUILD_FUSIONX ; Method to enable/disable the alternate CPU frequency and change it's values. ; @@ -178,6 +1830,9 @@ SETFREQ2: CALL SVC_CMD JP NZ,SETFREQERR RET + ; FusionX doesnt have the soft CPU capabilities, so no need to build in the logic. + IF BUILD_FUSIONX = 0 + ; Method to configure the hardware to use the T80 CPU instantiated in the FPGA. ; SETT80: IN A,(CPUINFO) @@ -281,6 +1936,7 @@ SETEMUMZ: IN A,(CPUINFO) ; Veri OR A JR NZ,SETT80ERR HALT + ENDIF ; BUILD_FUSIONX ; Simple routine to clear screen or attributes. CLR8: LD BC,00800H @@ -297,10 +1953,9 @@ CLR8_1: LD (HL),D ; ; Message addresses are in Bank2. ; + IF BUILD_FUSIONX = 0 NOFPGAERR: LD DE,MSGNOFPGA JR BADNUM2 -SETFREQERR: LD DE,MSGFREQERR - JR BADNUM2 SETT80ERR: LD DE,MSGT80ERR JR BADNUM2 SETZ80ERR: LD DE,MSGZ80ERR @@ -315,6 +1970,9 @@ NOZPUERR: LD DE,MSGNOZPUCPU JR BADNUM2 NOEMUERR: LD DE,MSGNOEMU JR BADNUM2 + ENDIF ; BUILD_FUSIONX +SETFREQERR: LD DE,MSGFREQERR + JR BADNUM2 BADNUMERR: LD DE,MSGBADNUM BADNUM2: CALL ?PRINTMSG RET diff --git a/hdr/cpm22_mz80a_std.hdr b/hdr/cpm22_mz80a_40c.hdr similarity index 100% rename from hdr/cpm22_mz80a_std.hdr rename to hdr/cpm22_mz80a_40c.hdr diff --git a/roms/mz80afi.rom b/roms/mz80afi.rom index abaea63d94860f4878f1795cb4c1907c1ac567ff..159ad027d1f136eff7417d319e76dc8fb40b7b0f 100644 GIT binary patch delta 17 YcmZn=Xb_m7#Mn7exrVWGSQ3vWYlCF!%2817y=Qp`tyZhGYHLw@Ezw#HAnE~+7LhiZObxYQNM>3{fD#BNcddPf6R_?7yKTS! z{chVmW`^Iaz4lsb|MuFCv(Fhh?}0#L^K*S-lKb{R=T?z-9|*K?=U+*82P(a{2ZnB@ z#kR|i_c-qk^n4m2eG##riXytDbN|GvWnio&_H2v&Y)j7Bmcp|w*PU&tJKK`p_i2P} zUcYE>A;$r68rrF$TQqd@$b=r0&ev*Opdwqp7($CQ^qi*mqJ}=w5H~Vm#n3M%saA{{ z;$kQ4rOcZ^qGma3V508LrzX%!&2oW;I<@EvPfzIGp&|Rwglvb3mK+E+7|+`72-Mom zXT7%u^4s$r#v>KO5uFvbbD!6>uOi7uD%-Dh#P^18tZUyWa*n9F8Sv_zvC(^5p!4m0 zod>P@hHGjY+z$xWWmMJC8$N6fDVsvdAW+qZ&7BA9+COsN8n7C~1J~4w=b)naPJ%%` zYMMtz1#VD&^!Sloy@!;Q#CW84cHz(@kNg$%tKQx`6pW42ZEyF zzBR~)ajo71!OopL$9ZoJDhinswf7Y=*o2=wUBZqLsL;_Q@=_Cj?p$j~>)d3m6J5gU zkd{trXljyVv%zDGfmfp>WDP<6Ws*FdtCw5!^%68genT&fe=&esy79gNsi!Lz+94<= zhbj0pF~pomKAHShN4JEn8v*IyGV6d+d|0{Z*S{f>y!NEx@=RB}@J{m>lvN&sc&<_U zjZ2y4(fua;Z3#;CiuZ7%)N13nSS8u9M49iHrCj95Q<5B4C@zu|6N^SR5k4kXS>RZ% z*gPJ2!%4C7}Z&UD+?@4?RUYN5wc|vIaub1{KSdIHjWd%4B4dhBcVPn zEMOo;H9(gbwD8_nE!eDY;)*3297fRq%G3XfH-p0-}_fJ1WjpHUHA=gsQz| zTR-ZyW%rA7Ksmaz;%_U@2W9b=iKc`PBR%ry3D5E*gOIrvkvo{4q!SQ1l8l19wa@*0 zU=3p0nyi4q$`(kpRfPA5iPd^?jdh zKP5al$PbvoNQ3*~fYTr(Jr?jj5@>W7ZJY(%gJl0}BnqlM98e|l-B``}SO7{=f{=!D?QA*rx`um?(ePzWxYni?P)h|?M-Up{cS z!Tmij6b8G*ezO|qgXk)_#USiccvrZT9=eY1WHXND-_2I4P2rmf-QRW4S zypY4DeTv^D?-N4eiaG8l1nGY}{r|)L`TLChkOZ?o61iUy6Kr|T@A2&W-*7nV7uP;a zjQHvBi?d;02fHKKBsJ9HHVJ@ujv~&Q1a*b$hviw^UMLZ6Ls$tr zw@y>;hrc=)I(jI!O08Wz`8a{Bx^S^Wcj49E`vcd;ze$7yPLAUg;)qZ-iM*r0I&hQw z{=hz{QK#_YB8Rz7(TNKkk#$O#c&$SxCPOPby5yf8cite}tjrW=dSafVbmwUpXbyh=V(hWjGV|PcBXo22kSszUOm)E=5%!J>z!eHH|PjoB@hm`ZcQTBD4pzS5|VIm;I7vCC)=w*V~pG| zCdoe@g3)(B&Jwo;XLCkQ-a2%s-ro4W+&)P3GtK>y@XT53V&TEFRww8@5wJR-{$kig zKLNAL_X5;AP9paN=>WE_hOx~zgi3Aa&S3#Y*hP!ocLn7{gGY~l>6E5Kh@6LC?!G

KU(nD_aB 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 a<81u@%k~`$oH4){U<@z@7z6(}1OE+Y-Q1M` delta 3633 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 diff --git a/tools/assemble_cpm.sh b/tools/assemble_cpm.sh index bdca672..6b2b7b0 100755 --- a/tools/assemble_cpm.sh +++ b/tools/assemble_cpm.sh @@ -39,7 +39,7 @@ INCDIR=${ROOTDIR}/asm/include ROMDIR=${ROOTDIR}/roms # Compiled or source ROM files. HDRDIR=${ROOTDIR}/hdr # MZF headers directory. MZFDIR=${ROOTDIR}/MZF/Common # MZF Format source files. -CPMVERSIONS="mz700_80c:0 mz80a_80c:1 mz80a_std:2" +CPMVERSIONS="mz700_80c:0 mz80a_80c:1 mz80a_40c:2" # As the tranZPUter project has eveolved different variants of CP/M are needed, so this loop along with the CPMVERSIONS string builds the versions as needed. for ver in ${CPMVERSIONS}