Files
RFS/asm/rfs.asm
Philip Smart dbfa22baa4 Fix SFD700 build failures caused by Glass assembler IF scope limitations
Glass Z80 assembler (v0.5.1) makes labels inside IF blocks invisible from
outside those blocks. This caused multiple build failures for the SFD700
target:

- JP _PRTMZF/_PRTDBG in jump table: replaced with DB 0C3H + DW encoding
  which resolves same-condition scope forward references via DW
- LD DE,MSG* across IF scopes: created LDDE macro (DB 011H + DW) that
  produces identical machine code to LD DE,nn for all build targets
- SFD700 command table (CMDTABLE2): moved after all INCLUDE statements
  so DW function references resolve as backward same-scope references
- Removed FD/FDDIR entry from SFD700 command table — FDDIR only exists
  for ROMDISK/picoZ80 builds (MZ-700 WD1773 FDC direct access)
- Fixed PRTSTR→PRINTMSG undefined symbol in rfs_bank7.asm
- Fixed BUILD_PICOZ80 comment (was incorrectly labelled as SFD700)

All three build targets (ROMDISK, SFD700, picoZ80) verified clean.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 22:55:26 +00:00

1601 lines
78 KiB
NASM

;--------------------------------------------------------------------------------------------------------
;-
;- Name: rfs.asm
;- Created: July 2019
;- Author(s): Philip Smart
;- Description: Sharp MZ series Rom Filing System.
;- This assembly language program is written to utilise the banked flashroms added with
;- the MZ-80A RFS hardware upgrade.
;-
;- Credits:
;- Copyright: (c) 2018-2026 Philip Smart <philip.smart@net2net.org>
;-
;- History: v1.0 July 2019 - Merged 2 utilities to create this compilation.
;- v2.0 May 2020 - Bank switch changes with release of v2 pcb with coded latch. The coded
;- latch adds additional instruction overhead as the control latches share
;- the same address space as the Flash RAMS thus the extra hardware to
;- only enable the control registers if a fixed number of reads is made
;- into the upper 8 bytes which normally wouldnt occur. Caveat - ensure
;- that no loop instruction is ever placed into EFF8H - EFFFH.
;- v2.0 July 2020 - Updated for the v2.1 hardware. RFS can run with a tranZPUter board with
;- or without the K64 I/O processor. RFS wont use the K64 processor all
;- operations are done by the Z80 under RFS.
;- v2.1 April 2021- Updates for the v2.1 RFS board.
;- v2.2 June 2023 - Updates for the Kuma 40/80 upgrade and FusionX.
;- v2.3 Aug 2023 - Updates to make RFS run under the SFD700 Floppy Disk Interface board.
;- UROM remains the same, a 2K paged ROM, MROM is located at F000 when
;- RFS is built for the SFD700.
;- v2.31 Dec 2025 - Bug fixes. Disabled internal floppy control logic for SFD700 as it is not
;- needed, AFI ROM always needs to be present, especially for MZ-80A.
;- v2.32 Mar 2026 - Added DUC command.
;- v2.33 Mar 2026 - Expanded to 12 Banks.
;-
;--------------------------------------------------------------------------------------------------------
;- This source file is free software: you can redistribute it and-or modify
;- it under the terms of the GNU General Public License as published
;- by the Free Software Foundation, either version 3 of the License, or
;- (at your option) any later version.
;-
;- This source file is distributed in the hope that it will be useful,
;- but WITHOUT ANY WARRANTY; without even the implied warranty of
;- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;- GNU General Public License for more details.
;-
;- You should have received a copy of the GNU General Public License
;- along with this program. If not, see <http://www.gnu.org/licenses/>.
;--------------------------------------------------------------------------------------------------------
; Bring in additional resources.
INCLUDE "rfs_definitions.asm"
;============================================================
;
; USER ROM BANK 0 - Main RFS Entry point and functions.
;
;============================================================
ORG UROMADDR
;--------------------------------
; Common code spanning all banks.
;--------------------------------
ROMFS: NOP
HWSELROM ; Select the first ROM.
JP ROMFS_1 ; Skip the reset vector.
JP 00000H ; Other banks will switch at this point thus forcing a full reset.
ALIGN_NOPS UROMBSTBL
;------------------------------------------------------------------------------------------
; Bank switching code, allows a call to code in another bank.
; This code is duplicated in each bank such that a bank switch doesnt affect logic flow.
;------------------------------------------------------------------------------------------
;
BKSW0to0: PUSH AF
LD A, ROMBANK0 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK0 ; Required bank to call.
JR BKSW0_0
BKSW0to1: PUSH AF
LD A, ROMBANK0 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK1 ; Required bank to call.
JR BKSW0_0
BKSW0to2: PUSH AF
LD A, ROMBANK0 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK2 ; Required bank to call.
JR BKSW0_0
BKSW0to3: PUSH AF
LD A, ROMBANK0 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK3 ; Required bank to call.
JR BKSW0_0
BKSW0to4: PUSH AF
LD A, ROMBANK0 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK4 ; Required bank to call.
JR BKSW0_0
BKSW0to5: PUSH AF
LD A, ROMBANK0 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK5 ; Required bank to call.
JR BKSW0_0
BKSW0to6: PUSH AF
LD A, ROMBANK0 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK6 ; Required bank to call.
JR BKSW0_0
BKSW0to7: PUSH AF
LD A, ROMBANK0 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK7 ; Required bank to call.
JR BKSW0_0
BKSW0to8: PUSH AF
LD A, ROMBANK0 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK8 ; Required bank to call.
JR BKSW0_0
BKSW0to9: PUSH AF
LD A, ROMBANK0 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK9 ; Required bank to call.
JR BKSW0_0
BKSW0to10: PUSH AF
LD A, ROMBANK0 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK10 ; Required bank to call.
JR BKSW0_0
BKSW0to11: PUSH AF
LD A, ROMBANK0 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK11 ; Required bank to call.
;
BKSW0_0: PUSH HL ; Place function to call on stack
LD HL, BKSWRET0 ; Place bank switchers return address on stack.
EX (SP),HL
LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it.
BNKSWSEL
JP (HL) ; Jump to required function.
BKSWRET0: POP AF ; Get bank which called us.
BNKSWSELRET
POP AF
RET ; Return to caller.
;-----------------------------------------
; picoZ80/RomDisk: trampolines for _PRTMZF and _PRTDBG.
; Defined BEFORE the jump table so they are backward references.
; Real implementations are in bank 9 (rfs_bank9.asm).
;-----------------------------------------
IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
_PRTMZF: LD HL,RFSJMPTABLE ; Bank 9 jump table: JP _PRTMZF9 at same address.
CALL BKSW0to9
RET
_PRTDBG: LD HL,RFSJMPTABLE+3 ; Bank 9 jump table: JP _PRTDBG9.
CALL BKSW0to9
RET
ENDIF
; Critical - External applications need to know the address of the Jump Table.
; If changed, go through the applications and update RFSJMPTABLE.
ALIGN RFSJMPTABLE
ORG RFSJMPTABLE
;------------------------------------------------------------------------------------------
; Enhanced function Jump table.
; This table is generally used by the monitor ROM to call functions within the User ROM.
;------------------------------------------------------------------------------------------
IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
PRTMZF: JP _PRTMZF ; UROMADDR+A0H - Print out an MZF header stored in the IBUFE location.
PRTDBG: JP _PRTDBG ; UROMADDR+A3H - Print out debug information, if enabled.
ENDIF
IF BUILD_SFD700 = 1
; SFD700: Use DB+DW encoding for JP — Glass cannot resolve forward
; references to labels in IF scope blocks via JP instruction.
PRTMZF: DB 0C3H ; JP _PRTMZF
DW _PRTMZF
PRTDBG: DB 0C3H ; JP _PRTDBG
DW _PRTDBG
ENDIF
CMT_RDINF: JP _CMT_RDINF ; UROMADDR+A6H - Tape/SD intercept handler - Read Header
CMT_RDDATA: JP _CMT_RDDATA ; UROMADDR+A9H - Tape/SD intercept handler - Read Data
CMT_WRINF: JP _CMT_WRINF ; UROMADDR+ACH - Tape/SD intercept handler - Write Header
CMT_WRDATA: JP _CMT_WRDATA ; UROMADDR+AFH - Tape/SD intercept handler - Write Data
CMT_VERIFY: JP _CMT_VERIFY ; UROMADDR+B2H - Tape/SD intercept handler - Verify Data
CMT_DIR: JP _CMT_DIR ; UROMADDR+B5H - SD card directory listing command.
CNV_ATOS: JP _CNV_ATOS ; UROMADDR+B8H - Convert string from Ascii to Sharp Ascii
;-----------------------------------------
;-----------------------------------------
; Initialisation and startup.
;-----------------------------------------
;
; NB. Bank control registers are left selected. Any software needing access to the top 8 bytes of a
; ROM/RAM page need to disable them, perform their actions then re-emable.
;
;
ROMFS_1:
LD A, (ROMBK1) ; Ensure all banks are at default
CP 8 ; If the ROMBK1 value is 255, an illegal value, then the machine has just started so initialise memory.
JR C, ROMFS_3
XOR A ; Clear the lower stack space as we use it for variables.
LD B, 7*8
LD HL, 01000H
ROMFS_2: LD (HL),A
INC HL
DJNZ ROMFS_2
SETCODELTCH ; On RomDisk setup coded latch to default.
LD A, (ROMBK1)
ROMFS_3: HWSELMROM ; start up.
LD A, (ROMBK2)
HWSELUROM
;-------------------------------------------------------------------------------
; START OF RFS INITIALISATION AND COMMAND ENTRY PROCESSOR FUNCTIONALITY.
;-------------------------------------------------------------------------------
;
; Replacement command processor in place of the SA1510 command processor.
;
MONITOR: IF FUSIONX_ENA+BUILD_SFD700 = 0
IN A,(CPLDINFO) ; See if a tranZPUter board is present.
AND 0E7H ; Mask out the CPLD Version and host HW.
LD C,A
CP 020H ; Upper bits specify the version, should be at least 1.
JR C,CHKTZ1
AND 007H ; Get Hardware, should be an MZ-80A for RFS.
CP MODE_MZ80A
LD A,C
JR Z,CHKTZ1
XOR A
CHKTZ1: AND 0E0H
ELSE
XOR A
ENDIF
LD (TZPU), A ; Flag = 0 if no tranZPUter present otherwise contains version (1 - 15).
IF VIDEOMODULE_ENA = 1
LD HL,DSPCTL ; Setup address of display control register latch.
ENDIF
;
XOR A ; Set the initial SDCFS active drive number.
LD (SDDRIVENO),A
;
IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
LD A, (ROMBK1) ; Is the 80column MZ-80A monitor active? Yes, set display as 80col.
CP 1
JR Z, SET80CHAR
CP 0
JR NZ, SIGNON
ENDIF
IF BUILD_SFD700 = 1 ; Ensure in 40 column mode.
ENDIF
;
SET40CHAR: IF VIDEOMODULE_ENA = 1
XOR A ; Using MROM in Bank 0 = 40 char mode.
LD E,(HL) ; Dummy operation to enable latch write via multivibrator.
LD (HL), A
ENDIF
IF KUMA80_ENA = 1 ; Kuma modification toggles the INTEN bit PC2 of the 8255 to switch mode, 0 = 40 column.
LD A,04H
LD (KEYPF),A
ENDIF
XOR A
LD (SCRNMODE), A
LD (SPAGE), A ; Allow MZ80A scrolling
JR SIGNON
SET80CHAR: IF VIDEOMODULE_ENA = 1
LD A, 128 ; Using MROM in Bank 1 = 80 char mode.
LD E,(HL) ; Dummy operation to enable latch write via multivibrator.
LD (HL), A
ENDIF
IF KUMA80_ENA = 1 ; Kuma modification toggles the INTEN bit PC2 of the 8255 to switch mode, 1 = 80 column.
LD A,05H
LD (KEYPF),A
ENDIF
LD A, 1
LD (SCRNMODE), A
LD A, 0FFH
LD (SPAGE), A ; MZ80K Scrolling in 80 column mode for time being.
;
SIGNON: LD A,0C4h ; Move cursor left to overwrite part of SA-1510 monitor banner.
LD E,004h ; 2 times.
SIGNON1: CALL DPCT
DEC E
JR NZ,SIGNON1
;
LD A,(TZPU)
OR A
JR Z,SIGNON2
LDDE MSGSONTZ
JR SIGNON3
;
SIGNON2: LDDE MSGSON ; Sign on message,
SIGNON3: LD HL,PRINTMSG
CALL BKSW0to6
; JR ST1X
; Initialise SD card, report any errors.
IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
LD HL, SDINIT ; SD Card Initialisation
CALL BKSW0to2 ; Call the initialisation routine.
LD A,L
OR A ; 0 = No error.
JR Z,ST1X
; Place error code in C to print as a number and report with the error message.
ADD A,'0'
LD C,A
LDDE MSGSDINITER
LD HL,PRINTMSG
CALL BKSW0to6
ENDIF
; Command processor, table based.
; A line is input then a comparison made with entries in the table. If a match is found then the bank and function
; address are extracted and a call to the function @ given bank made. The commands can be of variable length
; but important to not that longer commands using the same letters as shorter commands must appear first in the table.
;
ST1X: CALL NL ; Command line monitor extension.
LD A,'*'
CALL PRNT
LD DE,BUFER
CALL GETL
;
LD A,(BUFER+1) ; Drive change number 0..9. Each number represents an RFS SDCFS Drive number.
CP '0'
JR C,CMDCMP
CP ':'
JR NC,CMDCMP
SUB '0'
LD D,A
LD A,(BUFER+2)
CP CR ; If a CR is present then we match, a drive selection number was entered.
LD A,D
JR NZ,CMDCMP
; Simple command, just update the active drive number.
LD (SDDRIVENO),A
JR ST1X
;
CMDCMP: XOR A ; Clear the result variable used by interbank calls. Some functions set this variable and we act on it.
LD (RESULT),A
IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
LD HL,CMDTABLE
ENDIF
IF BUILD_SFD700 = 1
LD HL,CMDTABLE2 ; SFD700 Command table located in lower location.
ENDIF
CMDCMP0: LD DE,BUFER+1 ; First command byte after the * prompt.
LD A,(HL)
CP 000H
JR Z,ST1X ; Skip processing on lines where just CR pressed.
CP 0FFH ; All bits set on command properties indicates table end, exit if needed.
JR Z,CMDNOCMP
;
LD C,A ; Command properties into C
SET 7,C ; Assume command match.
AND 007H ; Mask out bytes in command mask.
LD B,A ; Number of bytes in command.
INC HL
CMDCMP1: LD A,(DE) ; Compare all bytes and reset match bit if we find a difference.
CP (HL)
JR Z, CMDCMP2
RES 7,C ; No command match.
CMDCMP2: INC DE
INC HL
DJNZ CMDCMP1
BIT 7,C ; Bit 7 is still set then we have a command match.
JR NZ,CMDCMP3
INC HL
INC HL ; Skip over function address
JR CMDCMP0 ; Try match next command.
CMDCMP3: LD A,(HL) ; Command function address into HL
INC HL
LD H,(HL)
LD L,A
PUSH HL ; Push the address of the function to be called.
LD (TMPADR),DE ; Store the key buffer location where arguments start.
LD A,C ; Get back command properties, ie. bank number
SRL A ; Shift 3 size bits to obtain bank number
SRL A
SRL A
AND 00FH ; Mask out just the bank number of the command.
CP 000H
JR Z,CMDCMP6 ; No point using the bank switching logic for the current bank 0.
LD B,A
LD HL,BKSW0to0 ; Base address of bank switching functions.
LD DE,BKSW0to1 - BKSW0to0 ; DE is the number of bytes between bank switch calls.
OR A
JR Z,CMDCMP5
CMDCMP4: ADD HL,DE ; Basically adding the bank size to the address to get ROM location.
DJNZ CMDCMP4
CMDCMP5: EX DE,HL ; Address of bank switch function into DE.
POP HL ; Get address of command into HL.
LD BC,CMDCMPEND
PUSH BC ; Address to return to after command is executed.
PUSH DE ; Now jump to DE which will switch to the correct bank and execute function at HL.
LD DE,(TMPADR)
RET ; Return to address in DE, which is the required bank.
CMDCMP6: LD DE,CMDCMPEND ; Put return address onto stack.
PUSH DE
LD DE,(TMPADR) ; For the current bank, just jump to the function.
JP (HL)
CMDNOCMP: LD A,(BUFER+1) ; If nothing was entered, ignore line otherwise print questions to show command wasnt recognised.
OR A
JR Z,CMDCMPEND
CP 00DH
JR Z,CMDCMPEND
LDDE MSGBADCMD
LD HL,PRINTMSG
CALL BKSW0to6
CMDCMPEND: LD A,(RESULT)
CP 0FEH ; A Result code of 0FEH means execute loaded code, address is in the CMT Header EXADR location.
JP NZ,ST1X
LD HL,(EXADR)
JP (HL)
; Monitor command table (ROMDISK). This table contains the list of recognised commands along with the
; handler function and bank in which it is located.
;
; 7 6:3 2:0
; MATCH BANK SIZE
CMDTABLE: IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
DB 000H | 000H | 002H ; Bit 2:0 = Command Size, 5:3 = Bank, 6 = Command match, 7 = Command table end.
DB "40" ; 40 Char screen mode.
DW SETMODE40
DB 000H | 000H | 002H
DB "80" ; 80 Char screen mode.
DW SETMODE80
;DB 000H | 000H | 004H
;DB "7008" ; Switch to 80 column MZ700 mode.
;DW SETMODE7008
;DB 000H | 000H | 003H
;DB "700" ; Switch to 40 column MZ700 mode.
;DW SETMODE700
DB 000H | 040H | 003H
DB "ASM" ; Assembler.
DW ASM_MAIN
DB 000H | 048H | 005H ; Bank 9.
DB "BASIC" ; Load and run BASIC SA-5510.
DW LOADBASIC9
DB 000H | 020H | 001H
DB 'B' ; Bell.
DW SGX
DB 000H | 048H | 003H ; Bank 9.
DB "CPM" ; Load and run CPM.
DW LOADCPM9
DB 000H | 018H | 002H
DB "CP" ; Copy Memory.
DW MCOPY
DB 000H | 018H | 001H
DB 'C' ; Clear Memory.
DW INITMEMX
DB 000H | 038H | 004H
DB "DASM" ; Disassembler.
DW DASM_MAIN
DB 000H | 018H | 003H
DB "DUC" ; Dump SD Card file contents (hex or text).
DW DUMPSDCARD
DB 000H | 018H | 001H
DB 'D' ; Dump Memory.
DW DUMPX
DB 000H | 010H | 002H
DB "EC" ; Erase file.
DW ERASESD
DB 000H | 008H | 002H
DB "FL" ; 'FL' RFS Floppy load/boot.
DW FLOPPY
DB 000H | 008H | 002H
DB "FD" ; 'FD' Floppy directory.
DW FDDIR
DB 000H | 008H | 001H
DB 0AAH ; 'f' Original Floppy boot code.
DW FDCK
DB 000H | 058H | 001H
DB 'H' ; Help screen (bank 11).
DW HELP
DB 000H | 018H | 002H ; Bank 3, 2-char command.
DB "IN" ; I/O port input.
DW INX
DB 000H | 048H | 002H ; Bank 9.
DB "IR" ; List ROM directory.
DW DIRROM9
DB 000H | 010H | 002H
DB "IC" ; List SD Card directory.
DW DIRSDCARD
DB 000H | 000H | 001H
DB 'J' ; Jump to address.
DW GOTOX
DB 000H | 020H | 004H
DB "LTNX" ; Load from CMT without auto execution.
DW LOADTAPENX
DB 000H | 020H | 002H
DB "LT" ; Load from CMT
DW LOADTAPE
DB 000H | 048H | 004H ; Bank 9.
DB "LRNX" ; Load from ROM without auto execution.
DW LOADROMNX9
DB 000H | 048H | 002H ; Bank 9.
DB "LR" ; Load from ROM
DW LOADROM9
DB 000H | 010H | 004H
DB "LCNX" ; Load from SDCARD without auto execution.
DW LOADSDCARDX
DB 000H | 010H | 002H
DB "LC" ; Load from SD CARD
DW LOADSDCARD
DB 000H | 020H | 001H
DB "L" ; Original Load from CMT
DW LOADTAPE
DB 000H | 018H | 001H
DB 'M' ; Edit Memory.
DW MCORX
DB 000H | 018H | 003H ; Bank 3, 3-char command.
DB "OUT" ; I/O port output.
DW OUTX
DB 000H | 018H | 001H
DB 'P' ; Printer test.
DW PTESTX
DB 000H | 020H | 001H
DB 'R' ; Memory test.
DW MEMTEST
DB 000H | 018H | 004H
DB "SD2T" ; Copy SD Card to Tape.
DW SD2TAPE
DB 000H | 010H | 002H
DB "SC" ; Save to SD CARD
DW SAVESDCARD
DB 000H | 020H | 002H
DB "ST" ; Save to CMT
DW SAVEX
DB 000H | 020H | 001H
DB 'S' ; Save to CMT
DW SAVEX
DB 000H | 000H | 004H
DB "TEST" ; A test function used in debugging.
DW LOCALTEST
DB 000H | 018H | 004H
DB "T2SD" ; Copy Tape to SD Card.
DW TAPE2SD
DB 000H | 020H | 001H
DB 'T' ; Timer test.
DW TIMERTST
DB 000H | 000H | 001H
DB 'V' ; Verify CMT Save.
DW VRFYX
DB 000H | 000H | 001H
DB 'X' ; Exchange to hi load rom so DRAM = 0000:0CFFF
DW HIROM
IF BUILD_PICOZ80 = 1
DB 000H | 020H | 002H ; Bank 4, 2-char command.
DB "QL" ; Boot first file from QD drive.
DW QDBOOT
DB 000H | 020H | 002H ; Bank 4, 2-char command.
DB "QD" ; List QD drive directory.
DW QDLIST
ENDIF
DB 0FFH ; END OF TABLE
ENDIF
;-------------------------------------------------------------------------------
; END OF RFS INITIALISATION AND COMMAND ENTRY PROCESSOR FUNCTIONALITY.
;-------------------------------------------------------------------------------
; A method used when testing hardware, scope and code will change but one of its purposes is to generate a scope signal pattern.
;
LOCALTEST: LD A,64
LD (0EFFBH),A
JP LOCALTEST
;-------------------------------------------------------------------------------
; START OF RFS COMMAND FUNCTIONS.
;-------------------------------------------------------------------------------
; Method to branch execution to a user given address.
;
GOTOX: CALL HEXIYX
JP (HL)
HEXIYX: EX (SP),IY
POP AF
CALL HLHEX
JR C,HEXIYX2
JP (IY)
HEXIYX2: POP AF ; Waste the intermediate caller address
RET
;====================================
;
; Screen Width Commands
;
;====================================
HIROM: IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
LD A, (MEMSW) ; Swap ROM into high range slot.
LD A, ROMBANK2
LD (ROMBK1),A ; Save bank being enabled.
HWSELMROM ; Switch to the hiload rom in bank 2.
JP 0C000H
ENDIF
SETMODE40: IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
LD A, ROMBANK0 ; Switch to 40Char monitor.
LD (ROMBK1),A
HWSELMROM
IF VIDEOMODULE_ENA = 1
LD HL,DSPCTL ; Setup address of display control register latch.
LD A, 0
LD E,(HL) ; Dummy operation to enable latch write via multivibrator.
LD (HL), A
ENDIF
IF KUMA80_ENA = 1 ; Kuma80 modification uses INTEN on PC@ of 8255, 0 = 40 column.
LD A,04H
LD (KEYPF),A
ENDIF
JP MONIT
ENDIF
SETMODE80: IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
LD A, ROMBANK1 ; Switch to 80char monitor.
LD (ROMBK1),A
HWSELMROM
IF VIDEOMODULE_ENA = 1
LD HL,DSPCTL ; Setup address of display control register latch.
LD A, 128
LD E,(HL) ; Dummy operation to enable latch write via multivibrator.
LD (HL), A
ENDIF
IF KUMA80_ENA = 1 ; Kuma80 modification uses INTEN on PC@ of 8255, 0 = 40 column.
LD A,05H
LD (KEYPF),A
ENDIF
JP MONIT
ENDIF
NOTZPU: LDDE MSGNOTZINST ; No tranZPUter installed.
LD HL,PRINTMSG
CALL BKSW0to6
RET
; The RFS depends on variables stored in unused parts of the Monitor scratch area.
; When switching into a compatibility mode the memory is switched and these variables go
; out of scope. This routine clears the memory and sets any crucial variables after
; memory switch so that a restart functions as expected.
;
SETMODECLR: POP HL ; Get return address, will go OOS after memory mode change.
LD A,TZMM_COMPAT
OUT (MMCFG),A ; Set memory mode to compatibility.
XOR A ; Clear out the RFS variable area in the tranZPUter memory.
LD DE, 01000H
LD B, 030H
SETCLR_1: LD (DE),A
INC DE
DJNZ SETCLR_1
JP (HL) ; Return to caller.
; Command to switch to the MZ700 compatibility mode with 80 column display.
;
;SETMODE7008:LD A,(TZPU) ; Check there is a tranZPUter card installed.
; OR A
; JR Z,NOTZPU
; LD HL,DSPCTL ; Setup address of display control register latch.
; LD A, 128 ; Setup for 80char display.
; LD E,(HL) ; Dummy operation to enable latch write via multivibrator.
; LD (HL), A
; CALL SETMODECLR ; Set memory mode and clear variable area.
; LD A,ROMBANK5 ; Select the 80 column version of the 1Z-013A ROM.
;SETMODE_2: LD (ROMBK1),A
; LD (BNKSELMROM),A
; LD A,MODE_MZ700 ; Set the CPLD compatibility mode.
;SETMODE_3: OUT (CPLDCFG),A
; JP MONIT ; Cold start the monitor.
; Command to switch to the MZ700 compatibility mode with original 40 column display.
;
;SETMODE700: LD A,(TZPU) ; Check there is a tranZPUter card installed.
; OR A
; JR Z,NOTZPU
; LD HL,DSPCTL ; Setup address of display control register latch.
; LD A, 0 ; Setup for 40char display.
; LD E,(HL) ; Dummy operation to enable latch write via multivibrator.
; LD (HL), A
; CALL SETMODECLR ; Set memory mode and clear variable area.
; LD A,ROMBANK4 ; Select the 40 column version of the 1Z-013A ROM.
; JR SETMODE_2
;====================================
;
; ROM File System Commands
;
;====================================
;------------------------------------------------------------------------------------------
; ROM File System functions.
; picoZ80/RomDisk: moved to bank 9 (rfs_bank9.asm) to free space in bank 0.
; SFD700: kept inline (4K UROM banks have plenty of room).
;------------------------------------------------------------------------------------------
IF BUILD_SFD700 = 1
; HL contains address of block to check.
ISMZF: PUSH BC
PUSH DE
PUSH HL
;
LD A,(HL)
CP OBJCD ; Only interested in machine code images.
JR NZ, ISMZFNOT
;
INC HL
LD DE,NAME ; Checks to confirm this is an MZF header.
LD B,FNSIZE ; Maximum of 17 characters, including terminator in filename.
ISMZFNXT: LD A,(HL)
LD (DE),A
CP 00DH ; If we find a terminator then this indicates potentially a valid name.
JR Z, ISMZFNXT3
CP 000H ; Same applies for NULL terminator.
JR Z, ISMZFNXT3
CP 020H ; >= Space
JR C, ISMZFNOT
CP 05DH ; =< ]
JR C, ISMZFNXT3
ISMZFNXT2: CP 091H
JR C, ISMZFNOT ; DEL or > 0x7F, cant be a valid filename so this is not an MZF header.
ISMZFNXT3: INC DE
INC HL
DJNZ ISMZFNXT
ISMZFYES: CP A ; Set zero flag to indicate match.
ISMZFNOT: POP HL
POP DE
POP BC
RET
_PRTDBG: IF ENADEBUG = 1
PUSH HL
PUSH DE
PUSH BC
PUSH AF
IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
LD A,(ROMBK1)
HWSELMROM ; Set the MROM bank back to original.
ENDIF
CALL PRTHL ; HL
LD A, ' '
CALL PRNT
LD H,B
LD L,C
CALL PRTHL ; BC
LD A, ' '
CALL PRNT
LD H,D
LD L,E
CALL PRTHL ; DE
LD A, ' '
CALL PRNT
POP HL ; Get AF into HL.
PUSH HL
CALL PRTHL ; AF
LD A, ' '
CALL PRNT
LD A, ':'
CALL PRNT
LD A, ' '
CALL PRNT
; CALL NL
; CALL GETKY
IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
LD A,(WRKROMBK1)
HWSELMROM ; Set the MROM bank back to scanned bank.
ENDIF
POP AF
POP BC
POP DE
POP HL
RET
ENDIF
_PRTMZF: PUSH BC
PUSH DE
PUSH HL
;
IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
LD A,(ROMBK1) ; Ensure main MROM is switched in.
HWSELMROM
ENDIF
;
LD A,(SCRNMODE)
CP 0
LD H,47
JR Z,PRTMZF0
LD H,93
PRTMZF0: LD A,(TMPLINECNT) ; Pause if we fill the screen.
LD E,A
INC E
CP H
JR NZ,PRTNOPAUSE
LD E, 0
PRTPAUSE: CALL GETKY
CP ' '
JR Z,PRTNOPAUSE
CP 'X' ; Exit from listing.
LD A,001H
JR Z,PRTMZF4
JR PRTPAUSE
PRTNOPAUSE: LD A,E
LD (TMPLINECNT),A
;
LD A, D ; Print out file number and increment.
CALL PRTHX
LD A, '.' ; File type is MACHINE CODE program.
CALL PRNT
LD DE,NAME ; Print out filename.
LD B,FNSIZE ; Maximum size of filename.
_PRTMSG: LD A,(DE)
INC DE
CP 000H
JR Z,_PRTMSGE
CP 00DH
JR Z,_PRTMSGE
CALL PRNT
DJNZ _PRTMSG
;
_PRTMSGE: LD HL, (DSPXY)
;
LD A,L
CP 20
LD A,20
JR C, PRTMZF2
;
LD A,(SCRNMODE) ; 40 Char mode? 2 columns of filenames displayed so NL.
CP 0
JR Z,PRTMZF1
;
LD A,L ; 80 Char mode we print 4 columns of filenames.
CP 40
LD A,40
JR C, PRTMZF2
;
LD A,L
CP 60
LD A,60
JR C, PRTMZF2
;
PRTMZF1: CALL NL
JR PRTMZF3
PRTMZF2: LD L,A
LD (DSPXY),HL
PRTMZF3: XOR A
PRTMZF4: OR A
PUSH AF
IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
LD A, (WRKROMBK1)
HWSELMROM
ENDIF
POP AF
POP HL
POP DE
POP BC
RET
; Method to list the directory of the ROM devices.
;
DIRROM: ;DI ; Disable interrupts as we are switching out the main rom.
;
LD A,1 ; Account for the title.
LD (TMPLINECNT),A
;
LDDE MSGRDIRLST ; Print out header.
LD HL,PRINTMSG
CALL BKSW0to6
; D = File sequence number.
LD D,0 ; File numbering start.
;
; Get directory of User ROM (RomDisk).
;
IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
LD A,ROMBANK3
LD (WRKROMBK1),A
HWSELMROM
CALL DIRMROM
ENDIF
;
; Scan MROM Bank
; B = Bank Page
; C = Block in page
;
LD B,MROMPAGES ; First set of pages are reserved in MROM bank.
LD C,0 ; Block in page.
;
DIRNXTPG: LD A,B
LD (WRKROMBK1), A
HWSELMROM ; Select bank.
PUSH BC ; Preserve bank count/block number.
PUSH DE ; Preserve file numbering.
LD A,C
IF RFSSECTSZ >= 512
RLCA
ENDIF
IF RFSSECTSZ >= 1024
RLCA
ENDIF
LD B,A
LD C,0
LD HL,MROMSTART ; Add block offset to get the valid block address.
ADD HL,BC
CALL ISMZF
POP DE
POP BC
JR NZ, DIRNOTMZF
;
CALL PRTMZF
JR NZ,DIRNXTPGX
INC D ; Next file sequence number.
;
DIRNOTMZF: INC C ; Next block.
LD A,C
CP MROMSIZE/RFSSECTSZ ; Max blocks per page reached?
JR C, DIRNXTPG2
LD C,0
INC B
DIRNXTPG2: LD A,B
CP 080h ; MROM has 128 banks of 4K, so stop when we reach 128.
JR NZ, DIRNXTPG
DIRNXTPGX: LD A,(ROMBK1)
HWSELMROM ; Set the MROM bank back to original.
;EI ; No need to block interrupts now as MROM bank restored.
RET ; End of scan, return to monitor
; In:
; HL = filename
; D = File sequence number.
; Out:
; B = Bank Page file found
; C = Block where found.
; D = File sequence number.
; Z set if found.
FINDMZF: PUSH DE
LD (TMPADR), HL ; Save name of program to load.
EX DE, HL ; String needed in DE for conversion.
LD HL,0FFFFh ; Tag the filenumber as invalid.
LD (TMPCNT), HL
CALL ConvertStringToNumber ; See if a file number was given instead of a filename.
JR NZ, FINDMZF0 ;
LD (TMPCNT), HL ; Store filenumber making load by filenumber valid.
;
; Scan MROM Bank
; B = Bank Page
; C = Block in page
;
FINDMZF0: POP DE ; Get file sequence number in D.
LD B,MROMPAGES ; First set of pages are reserved in User ROM bank.
LD C,0 ; Block in page.
FINDMZF1: LD A,B
LD (WRKROMBK1), A
HWSELMROM ; Select bank.
FINDMZF2: PUSH BC ; Preserve bank count/block number.
PUSH DE ; Preserve file numbering.
LD HL,MROMSTART ; Add block offset to get the valid block.
LD A,C
IF RFSSECTSZ >= 512
RLCA
ENDIF
IF RFSSECTSZ >= 1024
RLCA
ENDIF
LD B,A
LD C,0
ADD HL,BC
CALL ISMZF
POP DE
POP BC
LD A,(ROMBK1)
HWSELMROM ; Set the MROM bank back to original.
JR NZ, FINDMZF4 ; Z set if we found an MZF record.
INC HL ; Save address of filename.
PUSH HL
; CALL PRTMZF ; Print out for confirmation.
LD HL,(TMPCNT)
LD A,H
CP 0FFh ; If TMPCNT tagged as 0xFF then we dont have a filenumber so must match filename.
JR Z, FINDMZF3
LD A,L ; Check file number, load if match
CP D
JR NZ, FINDMZF3 ; Check name just in case.
POP HL
JR FINDMZFYES ; Else the filenumber matches so load the file.
FINDMZF3: POP HL
PUSH DE
PUSH BC
LD DE,(TMPADR) ; Original DE put onto stack, original filename into HL
LD BC,FNSIZE
LD A,(WRKROMBK1)
HWSELMROM ; Select correct bank for comparison.
CALL CMPSTRING
POP BC
POP DE
JR Z, FINDMZFYES
INC D ; Next file sequence number.
FINDMZF4: INC C
LD A,C
CP MROMSIZE/RFSSECTSZ ; Max blocks per page reached?
JR C, FINDMZF5
LD C,0
INC B
FINDMZF5: LD A,B
CP 080h ; MROM has 128 banks of 4K, so stop when we get to 128.
JR NZ, FINDMZF1
INC B
JR FINDMZFNO
FINDMZFYES: ; Flag set by previous test.
FINDMZFNO: PUSH AF
LD A,(ROMBK1)
HWSELMROM ; Set the MROM bank back to original.
POP AF
RET
; Load Program from ROM
; IN DE Name of program to load.
; OUT zero Set if string1 = string2, reset if string1 != string2.
; carry Set if string1 > string2, reset if string1 <= string2.
LOADROMNX: LD L,0FFH
JR LOADROM1
LOADROM: LD L,000H
LOADROM1: ;DI
PUSH HL ; Preserve execute flag.
EX DE,HL ; User ROM expects HL to have the filename pointer.
; D = File sequence number.
LD D,0 ; File numbering start.
;
IF BUILD_ROMDISK+BUILD_PICOZ80 = 1
PUSH HL ; Save pointer to filename for FINDMZF in Monitor ROM.
LD A,ROMBANK3 ; Activate the RFS Utilities MROM bank.
LD (WRKROMBK1), A
HWSELMROM
CALL MFINDMZF ; Try and find the file in User ROM via MROM utility.
POP HL
JR Z,MROMLOAD0
ENDIF
;
CALL FINDMZF ; Find the bank and block where the file resides. HL = filename.
JR Z, LROMLOAD
;
JR LROMNTFND ; Requested file not found.
;
MROMLOAD0: PUSH BC ; Preserve bank and block where MZF file found.
PUSH AF ; Preserve 7:6 of A which is upper bank select.
LD A,(ROMBK1) ; Page in monitor so we can print a message.
HWSELMROM
LDDE MSGLOAD+1 ; Skip initial file type identifier.
LD BC,NAME
LD HL,PRINTMSG
CALL BKSW0to6
LD A,(WRKROMBK1) ; Revert to MROM bank to load the application.
HWSELMROM
POP AF
POP BC
;
CALL MROMLOAD ; Load the file from User ROM via MROM utility.
JP Z, LROMLOAD5
LROMNTFND: POP HL ; Dont need execute flag anymore so waste it.
LD A,(ROMBK1)
HWSELMROM
LD HL,PRINTMSG
LDDE MSGNOTFND ; Not found
CALL BKSW0to6
LOADROMEND:;EI
RET
;
; Load program from RFS Bank 1 (MROM Bank)
;
LROMLOAD: PUSH BC
;
PUSH BC ; Print Loading <file>
LDDE MSGLOAD+1
LD BC,NAME
LD HL,PRINTMSG
CALL BKSW0to6
POP BC
;
LD A,B
LD (WRKROMBK1),A
HWSELMROM
;
LD DE, IBUFE ; Copy the header into the work area.
LD HL, MROMSTART ; Add block offset to get the valid block.
LD A,C
IF RFSSECTSZ >= 512
RLCA
ENDIF
IF RFSSECTSZ >= 1024
RLCA
ENDIF
LD B,A
LD C,0
ADD HL,BC
LD BC, MZFHDRSZ
LDIR
PUSH HL
LD DE, (DTADR)
LD HL, (SIZE)
LD BC, RFSSECTSZ - MZFHDRSZ
SBC HL, BC
JR NC, LROMLOAD4
LD HL, (SIZE)
JR LROMLOAD4
; HL = address in active block to read.
; B = Bank
; C = Block
LROMLOAD2: LD A, B
LD (WRKROMBK1), A
HWSELMROM
LROMLOAD3: PUSH BC
LD HL, MROMSTART
LD A, C
IF RFSSECTSZ >= 512
RLCA
ENDIF
IF RFSSECTSZ >= 1024
RLCA
ENDIF
LD B, A
LD C, 0
ADD HL,BC
PUSH HL
LD DE, (TMPADR)
LD HL, (TMPSIZE)
LD BC, RFSSECTSZ
SBC HL, BC
JR NC, LROMLOAD4
LD BC, (TMPSIZE)
LD HL, 0
LROMLOAD4: LD (TMPSIZE), HL ; HL contains remaining amount of bytes to load.
POP HL
;
LD A, B ; Pre check to ensure BC is not zero.
OR C
JR Z, LROMLOAD8
LDIR
LD BC, (TMPSIZE)
LD A, B ; Post check to ensure we still have bytes
OR C
JR Z, LROMLOAD8
;
LD (TMPADR),DE ; Address we are loading into.
POP BC
LROMLOAD6: INC C
LD A, C
CP MROMSIZE/RFSSECTSZ ; Max blocks per page reached?
JR C, LROMLOAD7
LD C, 0
INC B
;
LROMLOAD7: LD A, B
CP 080h
JR Z, LROMLOAD5
JR LROMLOAD2
;
LROMLOAD8: POP BC
LROMLOAD5: POP HL ; Retrieve execute flag.
LD A,(ROMBK1)
HWSELMROM ; Set the MROM bank back to original.
LD A,L ; Autoexecute turned off?
CP 0FFh
JP Z,LROMLOAD9 ; Go back to monitor if it has been, else execute.
LD HL,(EXADR)
;EI ; No need to block interrupts now as MROM bank restored.
JP (HL) ; Execution address.
LROMLOAD9: RET
; Quick method to load CPM. So long as the filename doesnt change this method will load and boot CPM.
LOADCPM: LD DE,CPMFN48 ; Load up the 48K version of CPM
LOADPRGNM: PUSH HL
LD HL,BUFER
LOADPRGNM1: LD A,(DE)
LD (HL),A
CP CR
JR Z,LOADPRGNM2
INC DE
INC HL
JR LOADPRGNM1
LOADPRGNM2: POP HL
LD DE,BUFER
JP LOADROM
; 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
JR LOADPRGNM
ENDIF ; BUILD_SFD700
LOADPROG: LD HL,LOADSDCARD
CALL BKSW0to2
RET
;-------------------------------------------------------------------------------
; END OF RFS COMMAND FUNCTIONS.
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; DEVICE DRIVERS - Intercept handlers to provide enhanced services to
; existing MA-80A BIOS API functions.
;-------------------------------------------------------------------------------
; Method to set the RFS Drive number from the Load/Save string provided.
SETDRIVE: LD A,(DE) ; If a drive is given it will be in format <driveno>:<filename>
OR A ; Exit if null or CR found, no drive specifier present.
JR Z,SETDRV3
CP 00DH
JR Z,SETDRV3
CP '"' ; String quotes, skip over.
JR NZ,SETDRV1
INC DE
JR SETDRIVE
;
SETDRV1: LD A,(DE) ; Check for <digit>:, if no colon exit.
LD C,A
INC DE
LD A,(DE)
DEC DE
CP ':'
JR NZ, SETDRV3
;
LD A,C
CP 'C' ; CMT unit specified by C:
JR Z,SETDRV2
SUB '0' ; Check the drive number, should be in range 0..9
JP C,SD_INVDRV
CP 10
JP NC,SD_INVDRV
SETDRV2: INC DE
LD (SDDRIVENO),A ; Store drive number for later use.
XOR A
LD (CMTFILENO),A ; Setup the starting file number for sequential file reads (ie. when no filename given).
;
PUSH DE ; Need to remove the drive qualifier once processed.
PUSH DE
INC DE
INC DE ; Move onto filename.
EX DE,HL
POP DE
LD BC,SDDIR_FNSZ
LDIR
POP DE
;
SETDRV3: XOR A
RET
; Method to check if the active drive is the CMT.
CHECKCMT: LD A,(SDDRIVENO)
CP 'C'
RET
; Convert the lower 4 bits of A into a Hex character.
TOHEXDIGIT: AND 00FH ; Simple logic, add 30H to get 0..9, add additional 7 if value >= 10 to get digits A..F.
CP 00AH
JR C,NOADD
ADD A,007H
NOADD: ADD A,030H
RET
; Convert a number into Hex string and store in buffer pointed to by DE.
;
TOHEX: PUSH DE
PUSH AF ; Save AF to retrieve lower 4 bits.
RRCA ; Shift upper 4 bits to lower to convert to hex.
RRCA
RRCA
RRCA
CALL TOHEXDIGIT
LD (DE),A ; Store and convert lower 4 bits.
INC DE
POP AF
CALL TOHEXDIGIT
LD (DE),A
INC DE
LD A,CR ; Terminate with a CR.
LD (DE),A
POP DE ; DE back to start of string.
RET
; Handler to intercept the CMT Read Header Information call and insert selectable
; SD Card RFS Drive functionality.
; DE contains a pointer to memory containing the file to load. If (DE) = NULL then
; load the next sequential file from the SD card directory.
; DE = Filename. Can contain a drive specifier in format <driveno>:<filename>
;
; No registers or flags should be affected as we dont know the caller state.
_CMT_RDINF: CALL SETDRIVE ; Set drive if specified.
RET NZ
CALL CHECKCMT ; If drive is set to the CMT Unit exit with Z set so that the original CMT handlers are called.
JP Z,?RDI
LD A,(DE) ; Check to see if empty string given, if so expand the default Next file number into the buffer.
CP CR
JR NZ,_CMT_RDINF1
LD A,(CMTFILENO) ; Get next sequential number and convert to hex.
PUSH AF
CALL TOHEX
POP AF
INC A ; Increment number so next call retrieves the next sequential file.
LD (CMTFILENO),A
;
_CMT_RDINF1:PUSH DE
LD HL,LOADSDINF ; DE already points to the filename, call LOADSDINF to locate it on the SD card and setup the header.
CALL BKSW0to2
; Copy the filename into the Buffer provided allowing for file number to name expansion.
POP DE
LD HL,NAME
LD BC,SDDIR_FNSZ
LDIR
;
LD A,(RESULT)
OR A
RET Z ; 0 = success, return with carry clear.
SCF ; > 0 = fail, return with carry set.
RET
; Handler to intercept the CMT Read Data call and insert selectable SD Card RFS
; Drive functionality.
;
; No registers or flags should be affected as we dont know the caller state.
_CMT_RDDATA:LD HL,LOADSDDATA
CALL BKSW0to2
LD A,(RESULT)
OR A
JR NZ,_CMT_RDERR
RET
_CMT_RDERR: SCF
RET
; Handler to intercept the CMT Write Header Information call and insert selectable
; SD Card RFS Drive functionality.
;
; No registers or flags should be affected as we dont know the caller state.
;
; At the moment, the WRINF call only creates a filename if non specified. The actual write to file occurs in WRDATA. Once I have more understanding of
; how the sequential data mode works I can adapt it to be compatible.
_CMT_WRINF: LD DE,NAME ; Caller has already setup the CMT header so we use this for processing.
;
CALL SETDRIVE ; Set drive if specified.
RET NZ
CALL CHECKCMT
JP Z,?WRI
;
LD A,(DE) ; Check to see if empty string given, if so create a default name.
CP CR
JR NZ,_CMT_WRINF1
;
LD HL,DEFAULTFN
LD BC,DEFAULTFNE - DEFAULTFN
LDIR
LD A,(CMTFILENO) ; Get next sequential number and convert to hex.
PUSH AF
CALL TOHEX
POP AF
INC A ; Increment number so next call retrieves the next sequential file.
LD (CMTFILENO),A
;
_CMT_WRINF1:LD A,0 ; Always success as nothing is written.
OR A
RET
; Handler to intercept the CMT Write Data call and insert selectable SD Card RFS
; Drive functionality.
;
; No registers or flags should be affected as we dont know the caller state.
_CMT_WRDATA: LD HL,SAVESDDATA
CALL BKSW0to2
LD A,(RESULT)
OR A
JR NZ,_CMT_RDERR
RET
; Handler to intercept the CMT Verify Data call and insert selectable SD Card
; RFS Drive functionality.
;
; No registers or flags should be affected as we dont know the caller state.
_CMT_VERIFY:CALL SETDRIVE ; Set drive if specified.
RET NZ
CALL CHECKCMT
JR Z,_VERIFY
LDDE MSGNOVERIFY
JR SD_ERRMSG
_VERIFY: JP ?VRFY
SD_INVDRV: LDDE MSGINVDRV ; Invalid drive specified.
JR SD_ERRMSG
SD_NOTFND: LDDE MSGNOTFND
SD_ERRMSG: LD HL,PRINTMSG
CALL BKSW0to6 ; Print message that file wasnt found.
LD A,1
OR A
RET
; Method to list the contents of the active RFS drive number.
_CMT_DIR: CALL SETDRIVE ; Change to the given drive.
RET NZ
CALL CHECKCMT ; Cannot DIR tape drive so give error.
JP Z,_CMT_NODIR
LD HL,DIRSDCARD
CALL BKSW0to2 ; Call the standard RFS directory command.
RET
_CMT_NODIR: LDDE MSGNOCMTDIR
JR SD_ERRMSG
; Stub to call the ASCII to Sharp ASCII conversion routine stored in Bank 5.
; Inputs: DE = String to convert, NULL or CR terminated.
; B = Maximum number of characters to convert.
; All registers except AF preserved.
;
_CNV_ATOS: PUSH HL
LD HL,CNVSTR_AS
CALL BKSW0to5
POP HL
RET
;-------------------------------------------------------------------------------
; END OF DEVICE DRIVERS
;-------------------------------------------------------------------------------
;--------------------------------------
;
; Message table - Refer to bank 6 for
; all messages.
;
;--------------------------------------
; Quick load program names.
CPMFN48: DB "CPM223RFS", 00DH
BASICFILENM:DB "BASIC SA-5510RFS", 00DH
DEFAULTFN: DB "DEFAULT"
DEFAULTFNE: EQU $
; Bring in additional resources.
USE_CMPSTRING: EQU 1
USE_SUBSTRING: EQU 0
USE_INDEX: EQU 0
USE_STRINSERT: EQU 0
USE_STRDELETE: EQU 0
USE_CONCAT: EQU 0
USE_CNVUPPER: EQU 1
USE_CNVCHRTONUM: EQU 1
USE_ISNUMERIC: EQU 1
USE_CNVSTRTONUM: EQU 1
;
INCLUDE "macros.asm"
INCLUDE "rfs_utilities.asm"
;
; Ensure we fill the entire 2K by padding with FF's.
;
ALIGN 0EFF8h
ORG 0EFF8h
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0AAh
IF BUILD_SFD700 = 1
ALIGN 0F000H
ENDIF
MEND:
;
; Include all other banks which make up the RFS User sited ROM.
;
INCLUDE "rfs_bank1.asm"
INCLUDE "rfs_bank2.asm"
INCLUDE "rfs_bank3.asm"
INCLUDE "rfs_bank4.asm"
INCLUDE "rfs_bank5.asm"
INCLUDE "rfs_bank6.asm"
INCLUDE "rfs_bank7.asm"
INCLUDE "rfs_bank8.asm"
INCLUDE "rfs_bank9.asm"
INCLUDE "rfs_bank10.asm"
INCLUDE "rfs_bank11.asm"
;============================================================
;
; SFD700 COMMAND TABLE
;
; Placed after all bank includes so DW forward references to
; functions in various IF blocks are resolved as backward refs.
;============================================================
IF BUILD_SFD700 = 1
ORG 0E000H
ALIGN 0E300H
ENDIF
; Monitor command table (SFD700). This table contains the list of recognised commands along with the
; handler function and bank in which it is located.
;
; 7 6:3 2:0
; MATCH BANK SIZE
CMDTABLE2: IF BUILD_SFD700 = 1
DB 000H | 038H | 003H
DB "ASM" ; Assembler.
DW ASM_MAIN
DB 000H | 000H | 005H
DB "BASIC" ; Load and run BASIC SA-5510.
DW LOADBASIC
DB 000H | 020H | 001H
DB 'B' ; Bell.
DW SGX
DB 000H | 000H | 003H
DB "CPM" ; Load and run CPM.
DW LOADCPM
DB 000H | 018H | 002H
DB "CP" ; Copy Memory.
DW MCOPY
DB 000H | 018H | 003H
DB "DUC" ; Dump SD Card file contents (hex or text).
DW DUMPSDCARD
DB 000H | 018H | 001H
DB 'C' ; Clear Memory.
DW INITMEMX
DB 000H | 038H | 004H
DB "DASM" ; Disassembler.
DW DASM_MAIN
DB 000H | 018H | 001H
DB 'D' ; Dump Memory.
DW DUMPX
DB 000H | 008H | 002H
DB "FL" ; 'FL' RFS Floppy load.
DW FDCK
; NB: FD/FDDIR command not available on SFD700 — FDDIR only exists
; for ROMDISK/picoZ80 builds (MZ-700 WD1773 FDC). SFD700 uses
; AFI ROM at F000 via FDCK for floppy operations.
DB 000H | 058H | 001H
DB 'H' ; Help screen (bank 11).
DW HELP
DB 000H | 018H | 002H ; Bank 3, 2-char command.
DB "IN" ; I/O port input.
DW INX
DB 000H | 000H | 002H
DB "IR" ; List ROM directory.
DW DIRROM
DB 000H | 000H | 001H
DB 'J' ; Jump to address.
DW GOTOX
DB 000H | 020H | 004H
DB "LTNX" ; Load from CMT without auto execution.
DW LOADTAPENX
DB 000H | 020H | 002H
DB "LT" ; Load from CMT
DW LOADTAPE
DB 000H | 000H | 004H
DB "LRNX" ; Load from ROM without auto execution.
DW LOADROMNX
DB 000H | 000H | 002H
DB "LR" ; Load from ROM
DW LOADROM
DB 000H | 020H | 001H
DB "L" ; Original Load from CMT
DW LOADTAPE
DB 000H | 018H | 001H
DB 'M' ; Edit Memory.
DW MCORX
DB 000H | 018H | 003H ; Bank 3, 3-char command.
DB "OUT" ; I/O port output.
DW OUTX
DB 000H | 018H | 001H
DB 'P' ; Printer test.
DW PTESTX
DB 000H | 020H | 001H
DB 'R' ; Memory test.
DW MEMTEST
DB 000H | 020H | 002H
DB "ST" ; Save to CMT
DW SAVEX
DB 000H | 020H | 001H
DB 'S' ; Save to CMT
DW SAVEX
DB 000H | 000H | 004H
DB "TEST" ; A test function used in debugging.
DW LOCALTEST
DB 000H | 020H | 001H
DB 'T' ; Timer test.
DW TIMERTST
DB 000H | 000H | 001H
DB 'V' ; Verify CMT Save.
DW VRFYX
DB 0FFH ; END OF TABLE
ENDIF