RFS repository created from software component of the MZ80A_RFS repository branch v2.1

This commit is contained in:
Philip Smart
2023-02-22 21:27:02 +00:00
commit 71215df41d
148 changed files with 84668 additions and 0 deletions

615
README.md Normal file
View File

@@ -0,0 +1,615 @@
## Rom Filing System
<div style="text-align: justify">
The Rom Filing System is a hardware and software upgrade for the Sharp MZ80A. The original hardware replaces the Monitor and User ROM's on the motherboard by a daughter card with lifter sockets where upto 4x512Kbyte Flash RAM's and 1x512Kbyte Static RAM are sited.
<br><br>
Recently the tranZPUter FusionX added hardware compatibility to its virtual capabilities, encapsulating the original hardware as a virtual emulated device and as a consequence is fully RFS compliant.
<br><br>
One of the Flash RAM's is paged into the Monitor ROM socket and the other Flash RAM/Static RAM into the User ROM socket. The first 32Kbytes (8 slots x 4K) of the Monitor Flash RAM and the first 24Kybtes (12 slots of 2K) of the User Flash RAM is
dedicated to paged ROMs with the remainder being used to store Sharp MZF format binary images compacted within 256byte sectors and additional 2K paged Static RAM.
<br><br>
(<i>NB. The sector size may change to 128 byte sectors as the original reason for choosing 256 byte sectors no longer exists</i>).
</div>
--------------------------------------------------------------------------------------------------------
### RFS Software
<div style="text-align: justify">
In order to use the RFS Hardware, a comprehensive set of Z80 assembler methods needed to be written to allow bank paging and with it came the ability to upgrade the machines monitor functionality. This Z80
software forms the Rom Filing System which can be found in the repository within the &lt;software&gt; directory.
</div>
The following table describes each major file which forms the Rom Filing System:
| Module | Target ROM | Size | Bank | Description |
|------------------------|------------|------|------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| rfs.asm | User | 2K | 0 | Primary Rom Filing System and MZ700/MZ800 Monitor tools. |
| rfs_bank1.asm | User | 2K | 1 | Floppy disk controller functions. |
| rfs_bank2.asm | User | 2K | 2 | SD Card controller functions. |
| rfs_bank3.asm | User | 2K | 3 | Memory monitor utility functions and tape/SD copy utilities. |
| rfs_bank4.asm | User | 2K | 4 | CMT functions. |
| rfs_bank5.asm | User | 2K | 5 | Unused. |
| rfs_bank6.asm | User | 2K | 6 | Message printing routines, static messages, ascii conversion and help screen. |
| rfs_bank7.asm | User | 2K | 7 | Memory Test utility and 8253 Timer test. |
| cbios_bank1.asm | User | 2K | 8 | CPM CBIOS Utilities and Audio functions. |
| cbios_bank2.asm | User | 2K | 9 | CPM CBIOS Screen and ANSI Terminal functions. |
| cbios_bank3.asm | User | 2K | 10 | CPM CBIOS SD Card Controller functions. |
| cbios_bank4.asm | User | 2K | 11 | CPM CBIOS Floppy Disk Controller functions. |
| monitor_SA1510.asm | Monitor | 4K | 0 | Original SA1510 Monitor for 40 character display. |
| monitor_80c_SA1510.asm | Monitor | 4K | 1 | Original SA1510 Monitor patched for 80 character display. |
| cbios.asm | Monitor | 4K | 2 | CPM CBIOS (exec location 0xC000:0xCFFFF). |
| rfs_mrom.asm | Monitor | 4K | 3 | Rom Filing System helper functions located in the Monitor ROM space in Bank 3. These functions are used to scan and process MZF files stored within the User ROM space. |
| unassigned | Monitor | 4K | 4 | Unused slot. |
| unassigned | Monitor | 4K | 5 | Unused slot. |
| unassigned | Monitor | 4K | 6 | Unused slot. |
| unassigned | Monitor | 4K | 7 | Unused slot. |
<div style="text-align: justify">
<br>
In the User ROM, the rfs.asm module and all the rfs_bank&lt;x&gt;.asm modules form the Rom Filing System and are invoked by the original SA-1510 monitor on startup of the MZ80A (or reset). The functionality in these files provides
the Rom Filing System and additional MZ700/800 style monitor utilities. The way the code is structured, a call can be made from one bank to another without issue (stack and execution point manipulation is taken care of) thus
providing almost 16K program space in the User ROM slot.
<br><br>
Sharing the User ROM banks are the cbios_bank&lt;x&gt;.asm modules which form part of the CP/M Custom BIOS. They extend the functionality of the CBIOS without impacting RAM usage which is crucial within CP/M in order
to run as many applications as possible.
<br><br>
In the Monitor ROM, the rfs_mrom.asm module is located within the 4th bank (bank 3, bank 0 = original SA1510 ROM, bank 1 = 80 column modified SA1510 ROM) and provides utilities needed by the Rom Filing
System. These utilities are specifically needed for scanning and loading MZF files stored in the User ROM Flash RAM (because code executing in the User ROM cant page itself out to scan the
remainder of the ROM).
<br><br>
CPM v2.2 has been added with the CBIOS (Custom BIOS) being implemented within an MROM Bank (bank 2) along with User ROM Banks 8-11 mentioned above. This saves valuable RAM leaving only the CPM CCP and BDOS in RAM which can
be overwritten by programs, this gives a feasible 47K of useable program RAM. An intention is to include a paged RAM chip in the next release of the RFS Hardware which will allow upto 52K of program RAM.
<br><br>
There are several rapidly written shell scripts to aid in the building of the RFS software (which in all honesty need to be written into a single Python or Java tool). These can be seen in the following table along with their purpose:
<br><br>
</div>
| Script | Description |
|------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| assemble_cpm.sh | A shell script to build the CPM binary, the CPM MZF format application for loading via RFS and the CPM ROM Drives 0 & 1 |
| assemble_rfs.sh | A bash script to build the Rom Filing System ROM images. |
| assemble_roms.sh | A bash script to build all the standard MZ80A ROMS, such as the SA-1510 monitor ROM. |
| make_roms.sh | A bash script to build the RFS ROMS suitable for programming in the 512KByte Flash RAMS. These images contain the banked RFS ROMS, the various system ROMS such as SA-1510 and all the MZF programs to be loaded by the RFS. |
| make_cpmdisks.sh | A bash script to build a set of CPM disks, for use as Raw images in the SD Card or Rom drives and as CPC Extended Disk Formats for use in a Floppy disk emulator or copying to physical medium. |
| make_sdcard.sh | A bash script to create an SD card image combining the RFS Images and several CPM disk drives. This image is then binary copied onto the SD card and installed into the RFS SD Card reader. |
| mzftool.pl | A perl script to create/extract and manipulate MZF images. |
| processMZFfiles.sh| A bash script to convert a set of MZF programs into sectored images suitable for use in the Rom Filing System ROMS. |
| sdtool | A binary created from the src/tools repository which builds the RFS SD Card image, creating a directory and adding MZF/Binary applications into the drive image. |
--------------------------------------------------------------------------------------------------------
### Sharp BASIC SA-5510
<div style="text-align: justify">
The RFS development is primarily for the Sharp MZ-80A and as such it has a large base of BASIC programs. I originally converted Nascom's Microsoft BASIC to use under RFS as the source code was available making the task much easier + there is a large base
of BASIC programs for this interpreter.
<br><br>
After a bit of self-debate I decided to spend time disassembling the original Sharp SA-5510 BASIC to understand how it works and adapt a version suitable to work with the SD card under RFS. Byte location of the interpreter is critical as some programs
are written to expect functions at known locations so disassembly had to be accurate and modifications/enhancements made outside of the main program.
<br><br>
The solution I came up with was to extend the <b>LOAD</b> and <b>SAVE</b> commands and add an additional command <b>DIR</b> for listing of a card directory.
<br><br>
The LOAD/SAVE commands behave exactly as original except they are now intercepted and processed by RFS. On boot, the active SD drive (RFS has 10 drives, 0..9) is used and issuing a LOAD command will search for the requested program or choose the first program at location 00.
<br><br>
The table below lists the command extensions with a brief description.
</div>
| Command | Parameter | Description |
| ------- | --------- | ----------- |
| LOAD | "TEST" | Look for the program "TEST" on the active drive, generally 0 when SA-5510RFS is started. |
| LOAD | | Load the first or subsequent file in the active drive. If a file at slot 5 was previously loaded, issuing this command would load file at slot 6. |
| LOAD | "3:TEST" | Look for the program "TEST" on RFS Drive 3, setting the active drive to 3 at the same time. |
| LOAD | "C:TEST" | Look for the program "TEST" on the internal cassette drive, setting the active drive to the internal cassette at the same time. |
| SAVE | "TEST" | Find a program called "TEST" in the active drive and overwrite it, if it doesnt exist, it will create a file called "TEST". On the cassette it will just write immediately wherever you have positioned the tape. |
| SAVE | | Save the current program to a generated name "DEFAULT&lt;number&gt;" where &lt;number&gt; is the current sequence number used in the LOAD command. |
| SAVE | "3:TEST" | Find a program called "TEST" on RFS Drive 3 and overwrite it, if it doesnt exist, it will create a file called "TEST". It will also set the active drive to 3 for future operations. |
| SAVE | "C:TEST" | Save the current program to the internal cassette drive with the name "TEST". It will also set the active drive to C (CMT) for future operations. |
| DIR | | List out the SD card directory in RFS format, ie. A file number followed by the filename. |
| DIR | "3:" | List out the SD card directory on drive 3 in RFS format, ie. A file number followed by the filename. It will also set the active drive to 3 for future operations. |
<div style="text-align: justify">
To LOAD or SAVE a file to a different drive, qualify the filename with "&lt;drive no&gt;:...",<br>
&nbsp;&nbsp;&nbsp;&nbsp;ie. LOAD "3:TEST" - this will load program "TEST" from drive 3 and make drive 3 active.
<br><br>
To LOAD or SAVE to the builtin cassette drive, use the qualifier "C:"<br>
&nbsp;&nbsp;&nbsp;&nbsp;ie. LOAD "C:" or LOAD "C:TEST".
<br><br>
The new version of BASIC SA-5510 is named "BASIC SA-5510RFS" on the RFS ROM Drive and SD Drive.
</div>
See [SD Card Organisation](/sharpmz-upgrades-rfs/#sd-card-organisation) below for a description of the default drives and contents.
NB: I havent yet fully implemented the random file read/write BASIC operations as I dont fully understand the logic. Once I get a suitable program I can analyse I will adapt RFS so that it seeks, read/writes a single 64K tape block. If there exists
programs with > 64K databases then RFS will need to be adapted to span successive blocks.
--------------------------------------------------------------------------------------------------------
### Microsoft BASIC
<div style="text-align: justify">
The Sharp machines have several versions of BASIC available to use, on cassette or floppy, although they have limited compatibility with each other (ie. MZ80A SA5510 differs to the MZ-700 S-BASIC). Each machine can have
several variants, ie. SA-6510 for disk drive use or third party versions such as OM-500. Most of these BASIC interpreters run well on RFS so long as they were intended for use on the MZ-80A albeit they are limited to CMT (cassette) or Floppy storage only.
<br><br>
One drawback of the existing BASIC interpreters is availability of source code to update them with RFS extensions. Unless you disassemble the binary or edit the binary directly adding RFS commands is not possible. I came across this same issue during the
development of TZFS on the tranZPUter and needing a version of BASIC to aid in hardware debugging I settled on using a version of Microsoft Basic where the source code was freely available, ie. the NASCOM v4.7b version of BASIC from Microsoft.
This version of Basic has quite a large following in the retro world and consequently a plethora of existing BASIC programs. It is also fairly simple to extend with additional commands.
</div>
There are two versions of the NASCOM 4.7b source code available on the internet, either the original or a version stripped of several hardware dependent commands such as LOAD /SAVE /SCREEN but tweaked to add binary/hex variables by [Grant Searle](http://searle.wales/) for his
[multicomp project](http://searle.x10host.com/Multicomp/index.html). I took both versions to make a third, writing and expanding on available commands including the missing tape commands.
<div style="text-align: justify">
As the projects developed, Microsoft BASIC needed to support a variety of configurations, even under RFS there are potentially 5 possibilities. Not counting the tranZPUter running under RFS or the TZFS versions there are 3 RFS versions to consider, namely:
</div>
* MS-BASIC(MZ-80A) - Original hardware can be booted from cassette.
* MS-BASIC(RFS40) - RFS upgrade with 40 column display.
* MS-BASIC(RFS80) - RFS upgrade with 80 column display.
Each appears on the RFS drive and should be used according to hardware and need. The original [NASCOM Basic Manual](../docs/Nascom_Basic_Manual.pdf) should be consulted for the standard set of commands and functions. The table below outlines additions which I have added to better
suite the MZ-80A / RFS hardware.
| Command | Parameters | Version | Description |
|--------- |-------------------------------------|----------------------|------------------------------------------------------------------------------------|
| CLOAD | "\<filename\>" | MZ-80A | Load a cassette image from the tape drive, ie. tokenised BASIC program\. |
| CSAVE | "\<filename\>" | MZ-80A | Save current BASIC program to the tape drive in tokenised cassette image format\. |
| CLOAD | "[\<drive\>:]\<filename\>" | RFS40, RFS80 | Load a cassette image from the tape drive or SD card, ie. tokenised BASIC program\. <br> \<drive\> specifies the RFS drives to use, 0..9 and also makes the drive active for future commands\. <br>\<filename\> can be either an MZ 17 character name or a 2 digit RFS hex number. <br>i.e. CLOAD "8:13" or CLOAD "8:othello" will load the othello program from RFS drive 8. |
| CSAVE | "[\<drive\>:]\<filename\>" | RFS40, RFS80 | Save current BASIC program to the tape drive or SD card in tokenised cassette image format\. |
| DIR | "[\<drive\>:]" | RFS40, RFS80 | Display the active or specified RFS drive contents in RFS format. |
| ANSITERM | 0 = Off, 1 = On | MZ-80A, RFS40, RFS80 | Disable or enable (default) the inbuilt Ansi Terminal processor which recognises ANSI escape sequences and converts them into screen actions. This allows for use of portable BASIC programs which dont depend on specialised screen commands. FYI: The Star Trek V2 BASIC program uses ANSI escape sequences\. |
<div style="text-align: justify">
It is also quite easy to adapt this BASIC by changing the memory mode commands so that it will operate on a Sharp MZ-700/MZ-800 with full 64K RAM. The tranZPUter project contains such a version.
</div>
##### NASCOM Cassette Image Converter Tool
<div style="text-align: justify">
NASCOM BASIC programs can be found on the internet as Cassette image files. These files contain all the tape formatting data with embedded tokenised BASIC code. In order to be able to use these files I wrote a converter program which strips out the tape formatting data and reconstructs the BASIC code. In
addition, as this version of BASIC has been enhanced to support new commands, the token values have changed and so this program will automatically update the token value during conversion.
</div>
The converter is designed to run on the command line and it's synopsis is:
```bash
NASCONV v1.0
Required:-
-i | --image <file> Image file to be converted.
-o | --output <file> Target destination file for converted data.
Options:-
-l | --loadaddr <addr> MZ80A basic start address. NASCOM address is used to set correct MZ80A address.
-n | --nasaddr <addr> Original NASCOM basic start address.
-h | --help This help test.
-v | --verbose Output more messages.
Examples:
nasconv --image 3dnc.cas --output 3dnc.bas --nasaddr 0x10fa --loadaddr 0x4341 Convert the file 3dnc.cas from NASCOM cassette format.
```
The files created by the converter are easily useable on the tranZPUter, for the RFS version I need to update the BASIC code to read files from the SD card, wip.
--------------------------------------------------------------------------------------------------------
### RFS Monitor
<div style="text-align: justify">
Upon boot, the typical SA-1510 monitor signon banner will appear and be appended with "+ RFS" if all works well. The usual '* ' prompt appears and you can then issue any of the original SA-1510 commands along with a set of enhanced
commands, some of which were seen on the MZ700/ MZ800 range and others are custom.
<br><br>
The full set of commands are listed in the table below:
</div>
| Command | Parameters | Description |
|---------|-------------------------------------|------------------------------------------------------------------------------------|
| 1 .. 4 | | Switch to RFS Drive, ie. 1. switches to RFS Drive 1. |
| 40 | n/a | Switch to 40 Character mode if the 40/80 Column display upgrade has been added\. |
| 80 | n/a | Switch to 80 Character mode if the 40/80 Column display upgrade has been added\. |
| 700 | n/a | Switch to Sharp MZ-700 40 column BIOS and mode\. |
| 7008 | n/a | Switch to Sharp MZ-700 80 column BIOS and mode\. |
| B | n/a | Enable/Disable key entry beep\. |
| BASIC | n/a | Locates BASIC SA-5510 on the SD card, loads and runs it. |
| C | \[\<8 bit value\>\] | Initialise memory from 0x1200 \- Top of RAM with 0x00 or provided value\. |
| CPM | n/a | Locates CP/M 2.23 on the SD card, loads and runs it. |
| D | \<address>\[\<address2>\] | Dump memory from \<address> to \<address2> (or 20 lines) in hex and ascii. When a screen is full, the output is paused until a key is pressed\. <br><br>Subsequent 'D' commands without an address value continue on from last displayed address\.<br><br> Recognised keys during paging are:<br> 'D' - page down, 'U' - page up, 'X' - exit, all other keys list another screen of data\.|
| EC | \<name> or <br>\<file number> | Erase file from SD Card\. The SD Card is searched for a file with \<name> or \<file number> and if found, erased\. |
| F | \[\<drive number\>\] | Boot from the given Floppy Disk, if no disk number is given, you will be prompted to enter one\. |
| f | n/a | Execute the original Floppy Disk AFI code @ 0xF000 |
| H | n/a | Help screen of all these commands\. |
| IR | n/a | Paged directory listing of the files stored in ROM\. Each file title is preceded with a hex number which can be used to identify the file\. |
| IC | n/a/ | Paged directory listing of the files stored on the SD Card\. Each file title is preceded with a hex number which can be used to identify the file\. |
| J | \<address> | Jump \(start execution\) at location \<address>\. |
| L \| LT | n/a | Load file into memory from Tape and execute\. |
| LTNX | n/a | Load file into memory from Tape, dont execute\. |
| LR | \<name> or <br>\<file number> | Load file into memory from ROM\. The ROM is searched for a file with \<name> or \<file number> and if found, loaded and executed\. |
| LRNX | \<name> or <br>\<file number> | Load file into memory from ROM\. The ROM is searched for a file with \<name> or \<file number> and if found, loaded and not executed\. |
| LC | \<name> or <br>\<file number> | Load file into memory from SD Card\. The SD Card is searched for a file with \<name> or \<file number> and if found, loaded and executed\. |
| LCNX | \<name> or <br>\<file number> | Load file into memory from SD Card\. The SD Card is searched for a file with \<name> or \<file number> and if found, loaded and not executed\. |
| M | \<address> | Edit and change memory locations starting at \<address>\. |
| P | n/a | Run a test on connected printer\. |
| R | n/a | Run a memory test on main mmemory\. |
| S | \<start addr> \<end addr> \<exec addr> | Save a block of memory to tape\. You will be prompted to enter the filename\. <br><br>Ie\. S120020001203 - Save starting at 0x1200 up until 0x2000 and set execution address to 0x1203\. |
| SC | \<start addr> \<end addr> \<exec addr> | Save a block of memory to SD Card\. You will be prompted to enter the filename\. |
| SD2T | \<name> or <br>\<file number> | Copy a file from SD Card to Tape\. The SD Card is searched for a file with \<name> or \<file number> and if found, copied to a tape in the CMT\. |
| T | n/a | Test the 8253 timer\. |
| T2SD | n/a | Copy a file from Tape onto the SD Card. A program is loaded from Tape and written to a free position in the SD Card\. |
| V | n/a | Verify a file just written to tape with the original data stored in memory |
If the 40/80 column card is installed, typing '4' switches to 40 Column display, typing '8' switches to 80 Column display. For the directory listing commands, 4 columns of output will be shown when in 80 column mode.
--------------------------------------------------------------------------------------------------------
### Sharp MZ-700 Mode
<div style="text-align: justify">
The tranZPUter SW Version 2.1 board has now been developed and RFS software updated to coexist with this board without a K64F processor (the processor can be present but no use of its services will be made under RFS). This board adds Sharp MZ-700 hardware level
compatibility logic, both memory management and keyboard remapping are made within hardware.
<br><br>
In order to cater for this upgrade, RFS has been updated to include the MZ-700 1Z-013A monitor ROM and a command to enable it. When enabled, the machine is set to compatibility mode, the 1Z-013A ROM loaded as the primary monitor and reset. The keyboard
is remapped real time and so is the memory. Loading S-BASIC, read/write cassette etc works as expected on an MZ-700.
</div>
--------------------------------------------------------------------------------------------------------
## Building RFS
<div style="text-align: justify">
Building the Rom Filing System involves assembling the Z80 Assembly language source into a machine code binary and packaging it into an image suitable for writing onto a 512Kbyte Flash RAM. You may also want to include MZF applications
in the ROMS for rapid exection via the RFS system. If you intend to use CPM, see also the CPM documentation.
<br><br>
To accomplish it you need several tools and at the moment it is a script aided manual process.
</div>
## Paths
For ease of reading, the following shortnames refer to the corresponding path in this chapter.
| Short Name | |
|------------------|----------------------------------------------------------------------------|
| \[\<ABS PATH>\] | The path where this repository was extracted on your system. |
| \<software\> | \[\<ABS PATH>\]/MZ80A_RFS/software |
| \<roms\> | \[\<ABS PATH>\]/MZ80A_RFS/software/roms |
| \<CPM\> | \[\<ABS PATH>\]/MZ80A_RFS/software/CPM |
| \<tools\> | \[\<ABS PATH>\]/MZ80A_RFS/software/tools |
| \<src\> | \[\<ABS PATH>\]/MZ80A_RFS/software/src |
| \<MZF\> | \[\<ABS PATH>\]/MZ80A_RFS/software/MZF |
| \<MZB\> | \[\<ABS PATH>\]/MZ80A_RFS/software/MZB |
## Tools
<div style="text-align: justify">
All development has been made under Linux, specifically Debian/Ubuntu. I use Windows for flashing the RAM's and using the GUI version of CP/M Tools but havent dedicated any time into building the RFS under Windows. I will in due course
create a Docker image with all necessary tools installed, but in the meantime, in order to assemble the Z80 code, the C programs and work with the CP/M software andCP/M disk images, you will need to obtain and install the following tools.
</div>
[Z80 Glass Assembler](http://www.grauw.nl/blog/entry/740/) - A Z80 Assembler for converting Assembly files into machine code.<br>
[samdisk](https://simonowen.com/samdisk/) - A multi-os command line based low level disk manipulation tool.<br>
[cpmtools](https://www.cpm8680.com/cpmtools/) - A multi-os command line CP/M disk manipulation tool.<br>
[CPMToolsGUI](http://star.gmobb.jp/koji/cgi/wiki.cgi?page=CpmtoolsGUI) - A Windows based GUI CP/M disk manipulation tool.<br>
[z88dk](https://www.z88dk.org/forum/) - An excellent C development kit for the Z80 CPU.<br>
[sdcc](http://sdcc.sourceforge.net/) - Another excellent Small Device C compiler, the Z80 being one of its targets. z88dk provides an enhanced (for the Z80) version of this tool within its package.<br>
## Software
Building the software and final ROM images can be done by cloning the [repository](https://github.com/pdsmart/MZ80A_RFS.git) and running some of the shell scripts and binaries provided.
The basic procedure to build RFS as follows:
1. Make the RFS binary using \<tools\>/assemble_rfs.sh, this creates \<roms\>/rfs.rom for the User Bank Flash RAM and \<roms\>/rfs_mrom.rom for the Monitor Bank Flash RAM.
2. Make the original MZ80A monitor roms using \<tools\>/assemble_roms.sh, this creates \<roms\>/monitor_SA1510.rom and \<roms\>/monitor_80c_SA1510.rom for the Monitor Bank Flash RAM.
3. Make the rom images using \<tools\>/make_roms.sh, this creates \<roms\>/USER_ROM_256.bin for the User Bank Flash RAM and \<roms\>/MROM_256.bin for the Monitor Bank Flash RAM.
The rom images also contain a packed set of MZF applications found in the \<MZF\> directory. Edit the script \<tools\>/make_roms.sh to add or remove applications from the rom images.
The above procedure has been encoded in a set of shell scripts and C tools, which at the simplest level, is to run these commands:
````bash
cd <software>
tools/assemble_cpm.sh
tools/assemble_rfs.sh
tools/assemble_roms.sh
tools/make_cpmdisks.sh
tools/make_roms.sh
tools/make_sdcard.sh
````
The output of the above commands are ROM images \<roms\>/MROM_256.bin and \<roms\>/USER_ROM.256.bin which must be flashed into 512Kbyte Flash RAMS and inserted into the sockets on the
RFS adapter.
The applications which can be stored in the Flash RAMS are located in the \<MZF\> directory. In order to use them within the Flash RAM's, the applications need to be converted into sector rounded binary images and stored in the
\<MZB\> directory. The tool \<tool\>/processMZFiles.sh has been created for this purpose. Simply copy any MZF application into the \<MZF\> directory and run this tool:
```bash
cd <software>
tools/processMZFfiles.sh
```
The files will be converted and stored in the \<MZB\> directory and then used by the \<tools\>/make_roms.sh script when creating the ROM images. The \<tools\>/make_roms.sh script lists all the applications to be added into the
Flash RAM's and it will pack as many as space permits. To ensure your application appears in the Flash RAM, add it to the top of the list (just the filename not the .MZF extension), ie:
```bash
Edit the file <tools>/make_roms.sh
Locate the line: ROM_INCLUDE=
Below this line, add your application in the format: ROM_INCLUDE+="${MZBPATH}/<YOUR APPLICATION>.${SECTORSIZE}.bin"
ie. ROM_INCLUDE+="${MZB_PATH}/A-BASIC_SA-5510.${SECTORSIZE}.bin:"
Save the file and run the commands above to build the MonitorROM and USERROM's.
```
<div style="text-align: justify">
The SD Card image is created by the &#60;tools&#62;/make_sdcard.sh script and in its basic form creates an image which can be directly copied onto an SD Card. The start of the image is a Rom Filing System image which is populated with
MZF applications from the &#60;MZF&#62; directory. The RFS image is followed by several CPM Disk images and together is canned the SD Card Filing System.
</div>
In order to add/remove MZF applications from the Rom Filing System image, edit the &#60;tools&#62;/make_sdcard.sh script and change which MZF applications are to be installed. CP/M images are also added to the SD Card and this is covered in the
[CP/M](sharpmz-upgrades-cpm/) section.
<br>
To copy the SD Card Filing System image created by the &#60;tools&#62;/make_sdcard.sh script onto an SD card, use a suitable tool direct binary copy tool such as <b>dd</b> under Linux.<br>
ie. dd if=SHARP_MZ80A_RFS_CPM_IMAGE_1.img of=/dev/sdd bs=512
<br>
<div style="text-align: justify">
No disk partitioning is needed as the SDCFS image starts at sector 0 on the SD Card. Once the image has been copied, place into the SD Card Reader on the RFS Board.
</div>
## SD Card
<div style="text-align: justify">
A recent addition to the Rom Filing System is an SD Card. The initial version was implemented in minimal hardware using the bitbang technique and provides performance comparable with a floppy disk without the seek overhead or interleave
times. In v2.0 onwards this was extended to a full hardware SPI circuit giving ROM level performance.
</div>
I worked on using the [Petit FatFS by El CHaN](http://elm-chan.org/fsw/ff/00index_p.html) for the SD Card filing system, which is excellent, having previously used the full Fat version with my ZPU project, but the Z80 isnt the best
architecture for code size when using C. In the repository in \<src\>/tools is my developments along this line with a C program called 'sdtest' and a modularized PetitFS along with manually coded Z80 assembler to handle the bitbang
algorithm and SD Card initialisation and communications. The program compiles into an MZF application and when run performs flawlessly. The only issue as mentioned is size and when your limited to 2K and 4K banked roms with a 12K
filing system you have an immediate storage issue. It is feasible to build PetitFS into a set of ROM banks using the z88dk C Compiler which supports banked targets and \_\_far constructs but it would be a lot of effort for something
which really isnt required.
<div style="text-align: justify">
I thus took a step back and decided to create my own simple filing system which is described below. This filing system is used for Sharp MZ80A MZF applications and is for both read and write operations.
</div>
### SD Card Filing System
<div style="text-align: justify">
The SD Card Filing System resides at the beginning of the SD Card and is followed by several CPM disk drive images. The SDCFS image is constructed of a directory plus 256 file blocks. The directory in the image can contain upto 256 entries,
each entry being 32 bytes long.
<br><br>
10 SDCFS images are supported per SD Card, numbered 0..9.
<br><br>
The SDCFS directory entry is based on the MZF Header format and is as follows:
</div>
| FLAG1 | FLAG2 | FILE NAME | START SECTOR | SIZE | LOAD ADDR | EXEC ADDR | RESERVED |
|--------|--------|-----------|--------------|---------|-----------|-----------|----------|
| 1 Byte | 1 Byte | 17 Bytes | 4 Bytes | 2 Bytes | 2 Bytes | 2 Bytes | 3 Bytes |
| Parameter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| Description |
| --------- | --------------------------------------------------------------------------------------------- |
| FLAG1 | BIT 7 = 1, Valid directory entry, 0 = inactive. |
| FLAG2 | MZF Execution Code, 0x01 = Binary |
| FILENAME | Standard MZF format filename. |
| START SECTOR | Sector in the active SDCFS image where the program starts. It always starts at position 0 of the sector. |
| SIZE | Size in bytes of the program. Each file block occupies 64Kbyte space (as per a tape) and this parameter provides the actual space occupied by the program at the current time. |
| LOAD ADDR | Start address in memory where data should be loaded. |
| EXEC ADDR | If a binary then this parameter specifies the location to auto execute once loaded. |
| RESERVED | Not used at the moment. |
Each file block, 1 per directory entry, is 64K long which is intentional as it keeps a fixed size which is in line
with the maximum tape (CMT) length and can be freely read/written to just as if it were a tape. This allows for easy
use within tape based applications such as Basic SA-5510 or for copying SD Card \<-\> CMT.
<div style="text-align: justify">
The remainder of the SD Card is filled with 16MByte CPM Disk drive images. Each image is organised as 32 (512byte) Sectors x 1024 tracks
and 1 head. Each image will be mounted in CPM under its own drive letter.
</div>
Visually, the SD Card is organised as follows:
```
ADDR SECTOR FUNCTION
00000000 0000 ---------------------------------------------------------------------------
| ROM FILING SYSTEM IMAGE 0 |
| |
00000000 0000 | RFS DIRECTORY ENTRY 000 (32BYTE) |
| .. |
| .. |
00001FE0 000F | RFS DIRECTORY ENTRY 255 (32BYTE) |
00002000 0010 ---------------------------------------------------------------------------
| RFS FILE BLOCK 0 |
00011FFF 008F ---------------------------------------------------------------------------
...
00FF2000 7F90 ---------------------------------------------------------------------------
| RFS FILE BLOCK 255 |
01001FFF 800F ---------------------------------------------------------------------------
...
09012000 48090 ---------------------------------------------------------------------------
| ROM FILING SYSTEM IMAGE 9 |
| |
09012000 48090 | RFS DIRECTORY ENTRY 000 (32BYTE) |
| .. |
| .. |
09013FE0 4809F | RFS DIRECTORY ENTRY 255 (32BYTE) |
09014000 480A0 ---------------------------------------------------------------------------
| RFS FILE BLOCK 0 |
09023FFF 4811F ---------------------------------------------------------------------------
...
0A004000 50020 ---------------------------------------------------------------------------
| RFS FILE BLOCK 255 |
0A013FFF 5009F ---------------------------------------------------------------------------
... padding ...
10000000 80000 ---------------------------------------------------------------------------
| |
| CP/M DISK IMAGE 0 |
| |
11000000 88000 ---------------------------------------------------------------------------
| |
| CP/M DISK IMAGE 1 |
| |
12000000 90000 ---------------------------------------------------------------------------
| |
| CP/M DISK IMAGE 2 |
| |
XX000000 XX0000 ---------------------------------------------------------------------------
| |
| CP/M DISK IMAGE <n> |
| |
---------------------------------------------------------------------------
```
## SD Card Organisation
The tools in the repository create an SD card with 10 RFS Drives and 6 CP/M Drives. These are organised as follows:
| RFS Drive | Description |
| --------- | ----------- |
| 0 | Common and MZ-80A Machine Code programs. |
| 1 | MZ-80K Machine Code programs. |
| 2 | MZ-700 Machine Code programs. |
| 3 | MZ-800/MZ-1500 Machine Code programs. |
| 4 | MZ-80B/MZ-2000 Machine Code programs. |
| 5 | BASIC programs, type 2 (MZ80A) |
| 6 | BASIC programs, type 2 (MZ80K) |
| 7 | BASIC programs, type 5 (MZ700/800) |
| 8 | Other programs. |
| 9 | Other programs. |
| CPM Drive | User No | Contents | Comments |
| --------- | ------- | -------- | -------- |
| 0 | 0 | CPM00_SYSTEM | System programs. |
| | 1 | CPM01_TURBOP | Turbo Pascal. |
| | 2 | CPM02_HI_C | Hi-Soft C |
| | 3 | CPM03_FORTRAN80 | Fortran 80 |
| | 4 | CPM04_MBASIC | Microsoft Basic 80/85 |
| | 5 | CPM05_COBOL80_v13 | Cobol v1.3 |
| | 6 | CPM06_COBOL80_v20 | Cobol v2.0 |
| | 7 | CPM07_COBOL80 | Cobol 80 |
| | 8 | CPM08_Z80FORTH | Z80 Forth |
| | 9 | CPM09_CPMTEX | CP/M Tex |
| | 10 | CPM10_DISKUTILFUNC5 | Disk utilities. |
| | 11 | CPM11_MAC80 | Macro Assembler 80 |
| | 12 | CPM29_ZSID_v14 | ZSID Debugger. |
| | 13 | CPM32_ZCPR3 | ZCPR3 CCP enhancement. |
| | 14 | CPM33_ZCPR3_COMMON | ZCPR3 CCP enhancement common utilities. |
| 1 | 0 | CPM12_PASCALMTP_v561 | Pascal v5.61 |
| | 1 | CPM26_TPASCAL_v300a | Turbo Pascal v3.00a |
| | 2 | CPM13_MTPUG_01 | Pascal User Group Disk 01 |
| | 3 | CPM14_MTPUG_02 | Pascal User Group Disk 02 |
| | 4 | CPM15_MTPUG_03 | Pascal User Group Disk 03 |
| | 5 | CPM16_MTPUG_04 | Pascal User Group Disk 04 |
| | 6 | CPM17_MTPUG_05 | Pascal User Group Disk 05 |
| | 7 | CPM18_MTPUG_06 | Pascal User Group Disk 06 |
| | 8 | CPM19_MTPUG_07 | Pascal User Group Disk 07 |
| | 9 | CPM20_MTPUG_08 | Pascal User Group Disk 08 |
| | 10 | CPM21_MTPUG_09 | Pascal User Group Disk 09 |
| | 11 | CPM22_MTPUG_10 | Pascal User Group Disk 10 |
| 2 | 0 | CPM23_PLI | PLI Compiler. |
| | 1 | CPM24_PLI80_v13 | PLI 80 Compiler v1.3 |
| | 2 | CPM25_PLI80_v14 | PLI 80 Compiler v1.4 |
| | 3 | CPM28_PLM80 | PLM 80. |
| | 4 | CPM27_WORDSTAR_v30 | WordStar v3.0 |
| | 5 | CPM31_WORDSTAR_v330 | WordStar v3.3 |
| | 6 | CPM30_WORDSTAR_v400 | WordStar v4.0 |
| 3 | 0 | CPM_MC_C0 | Grant Searle's CPM collection Disk C0 |
| | 1 | CPM_MC_C1 | C1 |
| | 2 | CPM_MC_C2 | C2 |
| | 3 | CPM_MC_C3 | C3 |
| | 4 | CPM_MC_C4 | C4 |
| | 5 | CPM_MC_C5 | C5 |
| | 6 | CPM_MC_C6 | C6 |
| | 7 | CPM_MC_C7 | C7 |
| | 8 | CPM_MC_C8 | C8 |
| | 9 | CPM_MC_C9 | C9 |
| 4 | 0 | CPM_MC_D0 | Grant Searle's CPM collection Disk D0 |
| | 1 | CPM_MC_D1 | D1 |
| | 2 | CPM_MC_D2 | D2 |
| | 3 | CPM_MC_D3 | D3 |
| | 4 | CPM_MC_D4 | D4 |
| | 5 | CPM_MC_D5 | D5 |
| | 6 | CPM_MC_D6 | D6 |
| | 7 | CPM_MC_D7 | D7 |
| | 8 | CPM_MC_D8 | D8 |
| | 9 | CPM_MC_D9 | D9 |
| 5 | 0 | CPM_MC_E0 | Grant Searle's CPM collection Disk E0 |
| | 1 | CPM_MC_E1 | E1 |
| | 2 | CPM_MC_E2 | E2 |
| | 3 | CPM_MC_E3 | E3 |
| | 4 | CPM_MC_E4 | E4 |
| | 5 | CPM_MC_E5 | E5 |
| | 6 | CPM_MC_E6 | E6 |
| | 7 | CPM_MC_E7 | E7 |
| | 8 | CPM_MC_E8 | E8 |
| | 9 | CPM_MC_E9 | E9 |
| 6 | 0 | CPM_MC_F0 | Grant Searle's CPM collection Disk F0 |
| | 1 | CPM_MC_F1 | F1 |
| | 2 | CPM_MC_F2 | F2 |
| | 3 | CPM_MC_F3 | F3 |
| | 4 | CPM_MC_F4 | F4 |
| | 5 | CPM_MC_F5 | F5 |
| | 6 | CPM_MC_F6 | F6 |
| | 7 | CPM_MC_F7 | F7 |
| | 8 | CPM_MC_F8 | F8 |
| | 9 | CPM_MC_F9 | F9 |
## Credits
<div style="text-align: justify">
Where I have used or based any component on a 3rd parties design I have included the original authors copyright notice within the headers or given due credit. All 3rd party software, to my knowledge and research, is open source and freely useable, if there is found to be any component with licensing restrictions, it will be removed from this repository and a suitable link/config provided.
</div>
## Licenses
<div style="text-align: justify">
This design, hardware and software, is licensed under the GNU Public Licence v3.
</div>
### The Gnu Public License v3
<div style="text-align: justify">
The source and binary files in this project marked as GPL v3 are 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.
<br><br>
The source files are 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.
<br><br>
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
</div>

3307
asm/1z-013a.asm Normal file

File diff suppressed because it is too large Load Diff

2638
asm/cbios.asm Normal file

File diff suppressed because it is too large Load Diff

456
asm/cbios_bank1.asm Normal file
View File

@@ -0,0 +1,456 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: cbios_bank1.asm
;- Created: January 2020
;- Author(s): Philip Smart
;- Description: Sharp MZ series CPM BIOS System.
;- This assembly language program is written to utilise the banked flashroms added with
;- the MZ-80A RFS hardware upgrade for the CPM CBIOS in order to preserve RAM for actual
;- CPM TPA programs.
;-
;- Credits:
;- Copyright: (c) 2018-23 Philip Smart <philip.smart@net2net.org>
;-
;- History: Jan 2020 - Seperated Bank from RFS for dedicated use with CPM CBIOS.
;- May 2020 - Advent of the new RFS PCB v2.0, quite a few changes to accommodate the
;- additional and different hardware. The SPI is now onboard the PCB and
;- not using the printer interface card.
;- Mar 2021 - Updates for the RFS v2.1 board.
;-
;--------------------------------------------------------------------------------------------------------
;- 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 definitions and macros.
INCLUDE "cpm_buildversion.asm"
INCLUDE "cpm_definitions.asm"
INCLUDE "macros.asm"
;======================================
;
; USER ROM CPM CBIOS BANK 1
;
;======================================
ORG UROMADDR
;-----------------------------------------------------------------------------------------
; Common code spanning all banks to ensure that a Monitor is selected upon power up/reset.
;-----------------------------------------------------------------------------------------
NOP
LD B,16 ; If we read the bank control reset register 15 times then this will enable bank control and then the 16th read will reset all bank control registers to default.
CBIOS1_0: LD A,(BNKCTRLRST)
DJNZ CBIOS1_0 ; Apply the default number of coded latch reads to enable the bank control registers.
CBIOS1_1: LD A,BNKCTRLDEF ; Set coded latch, SDCS high, BBMOSI to high and BBCLK to high which enables SDCLK.
LD (BNKCTRL),A
NOP
NOP
NOP
XOR A ; We shouldnt arrive here after a reset, if we do, select MROM bank 0
LD (BNKSELMROM),A
NOP
NOP
NOP
LD (BNKSELUSER),A ; and start up - ie. SA1510 Monitor - this occurs as User Bank 0 is enabled and the jmp to 0 is coded in it.
;
; No mans land... this should have switched to Bank 0 and at this point there is a jump to 00000H.
JP 00000H ; This is for safety!!
;-------------------------------------------------------------------------------
; Jump table for entry into this pages functions.
;-------------------------------------------------------------------------------
ALIGN_NOPS UROMJMPTBL
JP ?REBOOT ; REBOOT
JP ?MLDY ; QMELDY
JP ?TEMP ; QTEMP
JP MLDST ; QMSTA
JP MLDSP ; QMSTP
JP ?BEL ; QBEL
JP ?MODE ; QMODE
JP ?TIMESET ; QTIMESET
JP ?TIMEREAD ; QTIMEREAD
JP ?CHKKY ; QCHKKY
JP ?GETKY ; QGETKY
; Method to reboot the machine into startup mode, ie. Monitor at MROM Bank 0, UROM at Bank 0.
?REBOOT: LD A,(MEMSWR) ; Switch memory to power up state, ie. Monitor ROM at 00000H
JP CBIOS1_1 ; Now run the code at the bank start which switches to bank 0, intitialises and then calls 00000H
;-------------------------------------------------------------------------------
; START OF AUDIO CONTROLLER FUNCTIONALITY
;-------------------------------------------------------------------------------
; Melody function.
?MLDY: PUSH BC
PUSH DE
PUSH HL
LD A,002H
LD (OCTV),A
LD B,001H
MLD1: LD A,(DE)
CP 00DH
JR Z,MLD4
CP 0C8H
JR Z,MLD4
CP 0CFH
JR Z,MLD2
CP 02DH
JR Z,MLD2
CP 02BH
JR Z,MLD3
CP 0D7H
JR Z,MLD3
CP 023H
LD HL,MTBL
JR NZ,MLD1A
LD HL,M?TBL
INC DE
MLD1A: CALL ONPU
JR C,MLD1
CALL RYTHM
JR C,MLD5
CALL MLDST
LD B,C
JR MLD1
MLD2: LD A,003H
MLD2A: LD (OCTV),A
INC DE
JR MLD1
MLD3: LD A,001H
JR MLD2A
MLD4: CALL RYTHM
MLD5: PUSH AF
CALL MLDSP
POP AF
POP HL
POP DE
POP BC
RET
ONPU: PUSH BC
LD B,008H
LD A,(DE)
ONP1A: CP (HL)
JR Z,ONP2
INC HL
INC HL
INC HL
DJNZ ONP1A
SCF
INC DE
POP BC
RET
ONP2: INC HL
PUSH DE
LD E,(HL)
INC HL
LD D,(HL)
EX DE,HL
LD A,H
OR A
JR Z,ONP2B
LD A,(OCTV)
ONP2A: DEC A
JR Z,ONP2B
ADD HL,HL
JR ONP2A
ONP2B: LD (RATIO),HL
LD HL,OCTV
LD (HL),002H
DEC HL
POP DE
INC DE
LD A,(DE)
LD B,A
AND 0F0H
CP 030H
JR Z,ONP2C
LD A,(HL)
JR ONP2D
ONP2C: INC DE
LD A,B
AND 00FH
LD (HL),A
ONP2D: LD HL,OPTBL
ADD A,L
LD L,A
LD C,(HL)
LD A,(TEMPW)
LD B,A
XOR A
JP MLDDLY
RYTHM: LD HL,KEYPA
LD (HL),0F0H
INC HL
LD A,(HL)
AND 081H
JR NZ,L02D5
SCF
RET
L02D5: LD A,(SUNDG)
RRCA
JR C,L02D5
L02DB: LD A,(SUNDG)
RRCA
JR NC,L02DB
DJNZ L02D5
XOR A
RET
MLDST: LD HL,(RATIO)
LD A,H
OR A
JR Z,MLDSP
PUSH DE
EX DE,HL
LD HL,CONT0
LD (HL),E
LD (HL),D
LD A,001H
POP DE
JR L02C4
MLDSP: LD A,034H
LD (CONTF),A
XOR A
L02C4: LD (SUNDG),A
RET
MLDDLY: ADD A,C
DJNZ MLDDLY
POP BC
LD C,A
XOR A
RET
?TEMP: PUSH AF
PUSH BC
AND 00FH
LD B,A
LD A,008H
SUB B
LD (TEMPW),A
POP BC
POP AF
RET
;
; Method to sound the bell, basically play a constant tone.
;
?BEL: PUSH DE
LD DE,00DB1H
CALL ?MLDY
POP DE
RET
;
; Melody (note) lookup table.
;
MTBL: DB 043H
DB 077H
DB 007H
DB 044H
DB 0A7H
DB 006H
DB 045H
DB 0EDH
DB 005H
DB 046H
DB 098H
DB 005H
DB 047H
DB 0FCH
DB 004H
DB 041H
DB 071H
DB 004H
DB 042H
DB 0F5H
DB 003H
DB 052H
DB 000H
DB 000H
M?TBL: DB 043H
DB 00CH
DB 007H
DB 044H
DB 047H
DB 006H
DB 045H
DB 098H
DB 005H
DB 046H
DB 048H
DB 005H
DB 047H
DB 0B4H
DB 004H
DB 041H
DB 031H
DB 004H
DB 042H
DB 0BBH
DB 003H
DB 052H
DB 000H
DB 000H
OPTBL: DB 001H
DB 002H
DB 003H
DB 004H
DB 006H
DB 008H
DB 00CH
DB 010H
DB 018H
DB 020H
;-------------------------------------------------------------------------------
; END OF AUDIO CONTROLLER FUNCTIONALITY
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; START OF RTC FUNCTIONALITY (INTR HANDLER IN MAIN CBIOS)
;-------------------------------------------------------------------------------
;
; BC:DE:HL contains the time in milliseconds (100msec resolution) since 01/01/1980. In IX is held the interrupt service handler routine address for the RTC.
; HL contains lower 16 bits, DE contains middle 16 bits, BC contains upper 16bits, allows for a time from 00:00:00 to 23:59:59, for > 500000 days!
; NB. Caller must disable interrupts before calling this method.
?TIMESET: LD (TIMESEC),HL ; Load lower 16 bits.
EX DE,HL
LD (TIMESEC+2),HL ; Load middle 16 bits.
PUSH BC
POP HL
LD (TIMESEC+4),HL ; Load upper 16 bits.
;
LD HL,CONTF
LD (HL),074H ; Set Counter 1, read/load lsb first then msb, mode 2 rate generator, binary
LD (HL),0B0H ; Set Counter 2, read/load lsb first then msb, mode 0 interrupt on terminal count, binary
DEC HL
LD DE,TMRTICKINTV ; 100Hz coming into Timer 2 from Timer 1, set divisor to set interrupts per second.
LD (HL),E ; Place current time in Counter 2
LD (HL),D
DEC HL
LD (HL),03BH ; Place divisor in Counter 1, = 315, thus 31500/315 = 100
LD (HL),001H
NOP
NOP
NOP
;
LD A, 0C3H ; Install the interrupt vector for when interrupts are enabled.
LD (00038H),A
LD (00039H),IX
RET
; Time Read;
; Returns BC:DE:HL where HL is lower 16bits, DE is middle 16bits and BC is upper 16bits of milliseconds since 01/01/1980.
?TIMEREAD: LD HL,(TIMESEC+4)
PUSH HL
POP BC
LD HL,(TIMESEC+2)
EX DE,HL
LD HL,(TIMESEC)
RET
;-------------------------------------------------------------------------------
; END OF RTC FUNCTIONALITY
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; START OF KEYBOARD FUNCTIONALITY (INTR HANDLER SEPERATE IN CBIOS)
;-------------------------------------------------------------------------------
?MODE: LD HL,KEYPF
LD (HL),08AH
LD (HL),007H ; Set Motor to Off.
LD (HL),004H ; Disable interrupts by setting INTMSK to 0.
LD (HL),001H ; Set VGATE to 1.
RET
; Method to check if a key has been pressed and stored in buffer..
?CHKKY: LD A, (KEYCOUNT)
OR A
JR Z,CHKKY2
LD A,0FFH
RET
CHKKY2: XOR A
RET
?GETKY: PUSH HL
LD A,(KEYCOUNT)
OR A
JR Z,GETKY2
GETKY1: DI ; Disable interrupts, we dont want a race state occurring.
LD A,(KEYCOUNT)
DEC A ; Take 1 off the total count as we are reading a character out of the buffer.
LD (KEYCOUNT),A
LD HL,(KEYREAD) ; Get the position in the buffer where the next available character resides.
LD A,(HL) ; Read the character and save.
PUSH AF
INC L ; Update the read pointer and save.
LD A,L
AND KEYBUFSIZE-1
LD L,A
LD (KEYREAD),HL
POP AF
EI ; Interrupts back on so keys and RTC are actioned.
JR ?PRCKEY ; Process the key, action any non ASCII keys.
;
GETKY2: LD A,(KEYCOUNT) ; No key available so loop until one is.
OR A
JR Z,GETKY2
JR GETKY1
;
?PRCKEY: CP CR ; CR
JR NZ,?PRCKY3
JR ?PRCKYE
?PRCKY3: CP HOMEKEY ; HOME
JR NZ,?PRCKY4
JR GETKY2
?PRCKY4: CP CLRKEY ; CLR
JR NZ,?PRCKY5
JR GETKY2
?PRCKY5: CP INSERT ; INSERT
JR NZ,?PRCKY6
JR GETKY2
?PRCKY6: CP DBLZERO ; 00
JR NZ,?PRCKY7
LD A,'0'
LD (KEYBUF),A ; Place a character into the keybuffer so we double up on 0
JR ?PRCKYX
?PRCKY7: CP BREAKKEY ; Break key processing.
JR NZ,?PRCKY8
JR ?PRCKYE
?PRCKY8: CP DELETE
JR NZ,?PRCKYX
LD A,BACKS ; Map DELETE to BACKSPACE, BACKSPACE is Rubout, DELETE is echo in CPM.
?PRCKYX:
?PRCKYE:
POP HL
RET
;-------------------------------------------------------------------------------
; END OF KEYBOARD FUNCTIONALITY
;-------------------------------------------------------------------------------
; Align to end of bank.
ALIGN UROMADDR + 07F8h
ORG UROMADDR + 07F8h
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh

1468
asm/cbios_bank2.asm Normal file

File diff suppressed because it is too large Load Diff

897
asm/cbios_bank3.asm Normal file
View File

@@ -0,0 +1,897 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: cbios_bank3.asm
;- Created: January 2020
;- Author(s): Philip Smart
;- Description: Sharp MZ series CPM BIOS System.
;- This assembly language program is written to utilise the banked flashroms added with
;- the MZ-80A RFS hardware upgrade for the CPM CBIOS in order to preserve RAM for actual
;- CPM TPA programs.
;-
;- Credits:
;- Copyright: (c) 2018-23 Philip Smart <philip.smart@net2net.org>
;-
;- History: Jan 2020 - Seperated Bank from RFS for dedicated use with CPM CBIOS.
;- May 2020 - Advent of the new RFS PCB v2.0, quite a few changes to accommodate the
;- additional and different hardware. The SPI is now onboard the PCB and
;- not using the printer interface card.
;- Mar 2021 - Updates for the RFS v2.1 board.
;--------------------------------------------------------------------------------------------------------
;- 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 definitions and macros.
INCLUDE "cpm_buildversion.asm"
INCLUDE "cpm_definitions.asm"
INCLUDE "macros.asm"
;============================================================
;
; USER ROM CPM CBIOS BANK 3 - SD Card Controller functions.
;
;============================================================
ORG UROMADDR
;-----------------------------------------------------------------------------------------
; Common code spanning all banks to ensure that a Monitor is selected upon power up/reset.
;-----------------------------------------------------------------------------------------
NOP
LD B,16 ; If we read the bank control reset register 15 times then this will enable bank control and then the 16th read will reset all bank control registers to default.
CBIOS3_0: LD A,(BNKCTRLRST)
DJNZ CBIOS3_0 ; Apply the default number of coded latch reads to enable the bank control registers.
LD A,BNKCTRLDEF ; Set coded latch, SDCS high, BBMOSI to high and BBCLK to high which enables SDCLK.
LD (BNKCTRL),A
NOP
NOP
NOP
XOR A ; We shouldnt arrive here after a reset, if we do, select MROM bank 0
LD (BNKSELMROM),A
NOP
NOP
NOP
LD (BNKSELUSER),A ; and start up - ie. SA1510 Monitor - this occurs as User Bank 0 is enabled and the jmp to 0 is coded in it.
;
; No mans land... this should have switched to Bank 0 and at this point there is a jump to 00000H.
JP 00000H ; This is for safety!!
;-------------------------------------------------------------------------------
; Jump table for entry into this pages functions.
;-------------------------------------------------------------------------------
ALIGN_NOPS UROMJMPTBL
JP ?SD_INIT ; SD_INIT
JP ?SD_READ ; SD_READ
JP ?SD_WRITE ; SD_WRITE
JP ?SD_GETLBA ; SD_GETLBA
JP ?SDC_READ ; SDC_READ
JP ?SDC_WRITE ; SDC_WRITE
;-------------------------------------------------------------------------------
; START OF SD CARD CONTROLLER FUNCTIONALITY
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; Hardware SPI SD Controller (HW_SPI_ENA = 1)
; This logic uses the RFS PCB v2+ hardware shift registers to communicate with
; an SD Card. It is the fastest solution available but has a high IC count.
;
; Software SPI SD Controller (SW_SPI_ENA = 1)
; This logic uses the RFS PCB v2+ logic to simulate the SPI interface with
; bitbanging techniques. It is similar to the Parallel Port SD Controller
; but uses logic on the RFS board rather than the parallel port interface.
;
; Parallel Port SD Controller (PP_SPI_ENA = 1)
; This logic uses the standard Sharp MZ-80A Parallel Port for simulating the
; SPI interface with bitbanging techniques. This interface is then used to
; communicate with an SD Card.
;-------------------------------------------------------------------------------
; Method to initialise the SD card.
;
?SD_INIT: LD A,0FFH ; CS to high (inactive)
CALL SPICS
;
CALL SPIINIT ; Train SD with our clock.
;
LD A,000H ; CS to low (active)
CALL SPICS
LD BC,SD_RETRIES ; Number of retries before deciding card is not present.
SD_INIT1: LD A,CMD0 ; Command 0
LD HL,00000H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
LD DE,00000H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
PUSH BC
;
CALL SDCMD
;
LD A,(SDBUF+6) ; Get response code.
DEC A ; Set Z flag to test if response is 0x01
POP BC
JP Z,SD_INIT2 ; Command response 0x01? Exit if match.
DEC BC
LD A,B
OR C
JR NZ,SD_INIT1 ; Retry for BC times.
LD A,1
JP SD_EXIT ; Error, card is not responding to CMD0
SD_INIT2: ; Now send CMD8 to get card details. This command can only be sent
; when the card is idle.
LD A,CMD8 ; CMD8 has 0x00001AA as parameter, load up registers and call command routine.
LD HL,00000H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
LD DE,0AA01H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
CALL SDCMD
; Version 2 card, check its voltage range. IF not in the 2.7-3.6V dont try the ACMD41 to get capabilities.
SD_INIT3: LD A,1 ; Check that we receive 0x0001AA in response.
LD (SDVER),A ; Indicate this is not a version 2 card.
LD A,(SDBUF+9)
CP 1
JP NZ,SD_INIT8
LD A,(SDBUF+10)
CP 0AAH
JP NZ,SD_INIT8
SD_INIT4: LD A,2 ; This is a version 2 card.
SD_INIT5: LD (SDVER),A ; Indicate this is not a version 2 card.
CALL SDACMD41
JR Z,SD_INIT6
LD A,2 ; Error, card is not responding to ACMD41
JP SD_EXIT
SD_INIT6: LD A,CMD58 ; CMD58 has 0x00000000 as parameter, load up registers and call command routine.
LD HL,00000H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
LD DE,00000H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
CALL SDCMD
LD A,(SDBUF+6)
CP 040H
LD A,CT_SD2
JR Z,SD_INIT7
LD A,CT_SD2 | CT_BLOCK
SD_INIT7: LD (SDCAP),A ; Set the capabilities according to the returned flag.
JR SD_INIT14
; Version 1 card or MMC v3.
SD_INIT8: CALL SDACMD41
LD A, CT_SD1
LD E,ACMD41 ; SD1 cards we use the ACMD41 command.
JR Z,SD_INIT9
LD A,CT_MMC
LD E,CMD1 ; MMC cards we use the CMD1 command.
SD_INIT9: LD (SDCAP),A
LD A,E
CP ACMD41
JR NZ,SD_INIT10
CALL SDACMD41
JR Z,SD_INIT14
LD A,3 ; Exit code, failed to initialise v1 card.
JR SD_EXIT
SD_INIT10: LD BC,10 ; ACMD41/CMD55 may take some cards time to process or respond, so give a large number of retries.
SD_INIT11: PUSH BC
LD A,CMD1 ; CMD1 has 0x00000000 as parameter, load up registers and call command routine.
LD HL,00000H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
LD DE,00000H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
CALL SDCMD
LD A,(SDBUF+6) ; Should be a response of 0 whereby the card has left idle.
OR A
JR Z,SD_INIT13
LD BC,0FFFFH ; Delay for at least 200mS for the card to recover and be ready.
SD_INIT12: DEC BC ; 6T
LD A,B ; 9T
OR C ; 4T
JR NZ,SD_INIT12 ; 12T = 31T x 500ns = 15.5uS x 12903 = 200mS
;
POP BC
DEC BC
LD A,B
OR C
JR NZ,SD_INIT11
LD A,4 ; Exit code, failed to initialise v1 MMC card.
JR SD_EXIT
SD_INIT13: POP BC
LD A,CMD16 ; No response from the card for an ACMD41/CMD1 so try CMD16 with parameter 0x00000200
LD HL,00000H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
LD DE,00002H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
CALL SDCMD
LD A,(SDBUF+6)
OR A
JR Z,SD_INIT14
LD A,0
LD (SDCAP),A ; No capabilities on this unknown card.
SD_INIT14: XOR A
JR SD_EXIT
SD_EXIT: OR A ; Return value is in A.
RET
;
; A = CMD to send
; LHED = Argument, ie. CMD = A, L, H, E, D, CRC
;
SDCMD: LD (SDBUF),A
LD (SDBUF+1),HL
EX DE,HL
LD (SDBUF+3),HL
;
; Send command but with parameters preloaded by caller.
SDCMDNP: LD B,5 ; R1 + 32bit argument for CMD8, CMD58
CP CMD8
LD C,135
JP Z,SDCMD0
LD C,1 ; CMD58 is not CRC checked so just set to 0x01.
CP CMD58
LD B,5 ; R1 + 32bit argument
JP Z,SDCMD0
;
LD B,1 ; Default, expect R1 which is 1 byte.
CP CMD0 ; Work out the CRC based on the command. CRC checking is
LD C,149 ; not implemented but certain commands require a fixed argument and CRC.
JP Z,SDCMD0
LD C,1 ; Remaining commands are not CRC checked so just set to 0x01.
SDCMD0: PUSH BC ; Save the CRC and the number of bytes to be returned,
LD A,C ; Store the CRC
LD (SDBUF+5),A
LD A,255 ; Preamble byte
CALL SPIOUT
LD HL,SDBUF
LD B,6
SDCMD1: PUSH BC
LD A,(HL)
INC HL
CALL SPIOUT ; Send the command and parameters.
POP BC
DJNZ SDCMD1
PUSH HL
LD HL,SD_RETRIES
SDCMD2: PUSH HL
CALL SPIIN
POP HL
CP 0FFH
JR NZ,SDCMD4
DEC HL
LD A,H
OR L
JR NZ,SDCMD2
;
; Error as we are not receiving data.
;
POP HL
POP BC
LD A,1 ; Force return code to be error.
LD (SDBUF+6),A
RET
SDCMD3: PUSH BC
PUSH HL
CALL SPIIN ;
SDCMD4: POP HL
LD (HL),A
INC HL
POP BC ; Get back number of expected bytes. HL = place in buffer to store response.
DJNZ SDCMD3
IF HW_SPI_ENA = 0
LD A,DOUT_HIGH | CLOCK_LOW | CS_HIGH
OUT (SPI_OUT),A
ENDIF
RET
; Method to send an Application Command to the SD Card. This involves sending CMD55 followed by the required command.
;
; A = ACMD to send
; LHED = Argument, ie. ACMD = A, L, H, E, D, CRC
;
SDACMD: PUSH AF
PUSH DE
PUSH HL
LD A,CMD55 ; CMD55 has 0x00000000 as parameter, load up registers and call command routine.
LD HL,00000H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
LD DE,00000H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
CALL SDCMD
POP HL
POP DE
LD A,(SDBUF+6) ; Should be a response of 0 or 1.
CP 2
JR NC,SDACMDE
POP AF
CALL SDCMD
SDACMD0: LD A,(SDBUF+6) ; Should be a response of 0 whereby the card has left idle.
OR A
RET
SDACMDE: POP AF
JR SDACMD0
; Method to send Application Command 41 to the SD card. This command involves retries and delays
; hence coded seperately.
;
; Returns Z set if successful, else NZ.
;
SDACMD41: LD BC,10 ; ACMD41/CMD55 may take some cards time to process or respond, so give a large number of retries.
SDACMD1: PUSH BC
LD A,ACMD41 ; ACMD41 has 0x40000000 as parameter, load up registers and call command routine.
LD HL,00040H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
LD DE,00000H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
CALL SDACMD
JR Z,SDACMD3 ; Should be a response of 0 whereby the card has left idle.
LD BC,12903 ; Delay for at least 200mS for the card to recover and be ready.
SDACMD2: DEC BC ; 6T
LD A,B ; 9T
OR C ; 4T
JR NZ,SDACMD2 ; 12T = 31T x 500ns = 15.5uS x 12903 = 200mS
;
POP BC
DEC BC
LD A,B
OR C
JR NZ,SDACMD1
LD A,1 ; Retries exceeded, return error.
OR A
RET
SDACMD3: POP BC ; Success, tidy up stack and exit with Z set.
XOR A
RET
; Method to initialise communications with the SD card. We basically train it to our clock characteristics.
; This is important, as is maintaining the same clock for read or write otherwise the card may not respond.
SPIINIT: IF HW_SPI_ENA = 1
; Hardware SPI on the RFS v2+ PCB.
LD B,10
LD A, 0FFH ; We need to send 80 '1's, so preload the data register with all 1's, future transmits dont require this as it self loads with 1's.
LD (HWSPIDATA),A
SPIINIT1: LD (HWSPISTART),A ; Commence transmission of an 8bit byte. Runs 1 8MHz, so 1 byte in 1uS, it takes the Z80 2uS for its quickest instruction at 2MHz clock.
DJNZ SPIINIT1
RET
ELSE
; Software SPI on the RFS v2+ PCB.
IF SW_SPI_ENA = 1
ELSE
; Software SPI on the centronics parallel port.
LD B,80
SPIINIT1: LD A,DOUT_HIGH | CLOCK_HIGH | CS_HIGH ; Output a 1
OUT (SPI_OUT),A
LD A,DOUT_HIGH | CLOCK_LOW | CS_HIGH ; Output a 1
OUT (SPI_OUT),A
DJNZ SPIINIT1
RET
ENDIF
ENDIF
; Method to set the Chip Select level on the SD card. The Chip Select is active LOW.
;
; A = 0 - Set CS LOW (active)
; A = 0xFF - Set CS HIGH (active)
SPICS: IF HW_SPI_ENA = 1
; Hardware SPI on the RFS v2+ PCB.
OR A
LD A,(ROMCTL)
SET 1,A ; If we are inactivating CS then set CS high and disable clock by setting BBCLK to low.
RES 0,A
JR NZ, SPICS0
RES 1,A ; If we are activating CS then set CS low and enable clock by setting BBCLK to high.
SET 0,A
SPICS0: LD (BNKCTRL),A
LD (ROMCTL),A
RET
ELSE
; Software SPI on the RFS v2+ PCB.
IF SW_SPI_ENA = 1
ELSE
; Software SPI on the centronics parallel port.
OR A
LD A,DOUT_HIGH | CLOCK_LOW | CS_LOW ; Set CS Low if parameter = 0 (ie. enable)
JR Z, SPICS0
LD A,DOUT_HIGH | CLOCK_LOW | CS_HIGH ; Set CS High if parameter != 0 (ie. disable)
SPICS0: OUT (SPI_OUT),A
RET
ENDIF
ENDIF
; Method to send a byte to the SD card via the SPI protocol.
; This method uses the hardware shift registers.
;
; Input A = Byte to send.
;
SPIOUT: IF HW_SPI_ENA = 1
; Hardware SPI on the RFS v2+ PCB.
LD (HWSPIDATA),A
LD (HWSPISTART),A
RET
ELSE
; Software SPI on the RFS v2+ PCB.
IF SW_SPI_ENA = 1
ELSE
; Software SPI on the centronics parallel port.
RLCA ; 65432107
RLCA ; 54321076
RLCA ; 43210765 - Adjust so that starting bit is same position as Data line.
LD E,A ; E = Character to send.
LD B,8 ; B = Bit count
SPIOUT0: LD A,E
AND DOUT_MASK ; Data bit to data line, clock and cs low.
RLC E
SPIOUT1: OUT (SPI_OUT),A
OR CLOCK_HIGH ; Clock high
OUT (SPI_OUT),A
AND CLOCK_MASK ; Clock low
OUT (SPI_OUT),A
DJNZ SPIOUT0 ; Perform actions for the full 8 bits.
RET
ENDIF
ENDIF
; Method to receive a byte from the SD card via the SPI protocol.
; This method uses the hardware shift registers.
; NB. Timing must be very similar in SPIOUT and SPIIN.
;
; Output: A = received byte.
;
SPIIN: IF HW_SPI_ENA = 1
; Hardware SPI on the RFS v2+ PCB.
LD (HWSPISTART),A ; Commence transmission to receive back data from the SD card, we just send 1's.
LD A,(HWSPIDATA) ; Get the data byte.
RET
ELSE
; Software SPI on the RFS v2+ PCB.
IF SW_SPI_ENA = 1
ELSE
; Software SPI on the centronics parallel port.
LD BC,00800H | SPI_OUT ; B = Bit count, C = clock port
LD L,0 ; L = Character being read.
LD D,DOUT_HIGH | CLOCK_LOW | CS_LOW ; Output a 0
OUT (C),D ; To start ensure clock is low and CS is low.
LD E,DOUT_HIGH | CLOCK_HIGH | CS_LOW ; Output a 0
SPIIN1: OUT (C),E ; Clock to high.
IN A,(SPI_IN) ; Input the received bit
OUT (C),D ; Clock to low.
SRL A
RL L
DJNZ SPIIN1 ; Perform actions for the full 8 bits.
LD A,L ; return value
RET
ENDIF
ENDIF
;-------------------------------------------------------------------------------
; End of SPI SD Controller
;-------------------------------------------------------------------------------
; A function from the z88dk stdlib, a delay loop with T state accuracy.
;
; enter : hl = tstates >= 141
; uses : af, bc, hl
T_DELAY: LD BC,-141
ADD HL,BC
LD BC,-23
TDELAYLOOP: ADD HL,BC
JR C, TDELAYLOOP
LD A,L
ADD A,15
JR NC, TDELAYG0
CP 8
JR C, TDELAYG1
OR 0
TDELAYG0: INC HL
TDELAYG1: RRA
JR C, TDELAYB0
NOP
TDELAYB0: RRA
JR NC, TDELAYB1
OR 0
TDELAYB1: RRA
RET NC
RET
; Method to skip over an SD card input stream to arrive at the required bytes,
;
; Input: BC = Number of bytes to skip.
;
SPISKIP: PUSH BC
CALL SPIIN
POP BC
DEC BC
LD A,B
OR C
JR NZ,SPISKIP
RET
; Method to convert an LBA value into a physical byte address. This is achieved by multiplying the block x 512.
; We take the big endian sector value, shift left 9 times then store the result back onto the stack.
; This is done as follows: <MSB> <2> <1> <0> => <2> <1> <0> 0 (ie. 8 bit shift): Shift left <0> with carry, shift left <1> shift left <2>, 0 to <LSB>
;
; Input: HL = Stack offset.
;
LBATOADDR: LD HL,(SDSTARTSEC+1)
LD A,(HL) ; Start ny retrieving bytes as HED0
INC HL
LD E,(HL)
INC HL
LD D,(HL)
LD L,A
SLA D ; Shift the long left by 9 to effect a x512
RL E
RL H
LD BC,(SDSTARTSEC)
LD A,H ; Now save the results as LHED, big endian format as used by the SD Card argument
LD (BC),A
INC BC
LD A,E
LD (BC),A
INC BC
LD A,D
LD (BC),A
INC BC
LD A,0
LD (BC),A
RET
; Method to read a sector or partial sector contents to an SD Card.
;
; This method was originally a C routine I was using for FatFS but optimised it (still more can be done). The C->ASM is not so optimal.
;
; Input: Memory variables: SDSTARTSEC= unsigned long sector. - The sector number or direct byte address for older cards. This is big endian as per card.
; HL: Address where to store data read from sector.
; Output: A = 0 - All ok. A > 0 - error occurred.
;
?SD_READ: DI
PUSH HL ; Store the load address.
LD A,000H
CALL SPICS ; Set CS low (active).
LD HL,(SDCAP) ; Test to see if CT_BLOCK is available.
LD H,0
LD A,CT_BLOCK
AND L
JP NZ,SD_READ1 ; If it has CT_BLOCK then use sector numbers otherwise multiply up to bytes.
CALL LBATOADDR ; Multiply the sector by 512 for byte addressing on older cards.
SD_READ1: ; A = ACMD to send
; LHED = Argument, ie. ACMD = A, L, H, E, D, CRC
LD A,CMD17 ; Send CMD17 to read a sector.
LD (SDBUF),A
LD HL,(SDSTARTSEC)
LD (SDBUF+1),HL
LD HL,(SDSTARTSEC+2)
LD (SDBUF+3),HL
CALL SDCMDNP ; Execute SD Command, parameters already loaded into command buffer.
LD A,(SDBUF+6) ; Fetch result and store.
AND A
JP NZ,SD_READ6
LD HL,1000 ; Sit in a tight loop waiting for the data packet arrival (ie. not 0xFF).
SD_READ2: PUSH HL
LD HL,200
CALL T_DELAY
CALL SPIIN
POP HL
CP 255
JP NZ,SD_READ3
DEC HL
LD A,H
OR L
JR NZ,SD_READ2
SD_READ3: CP 254 ; Data? If not exit with error code.
JP NZ,SD_READ6
LD BC,SD_SECSIZE ; Size of full sector + 2 bytes CRC.
POP HL ; Get the store address into HL.
SD_READ4: PUSH HL ; Start reading bytes into the buffer.
PUSH BC
CALL SPIIN
POP BC
POP HL
LD (HL),A
INC HL ; Update buffer pointer.
DEC BC
LD A,B
OR C
JP NZ,SD_READ4 ; Not zero, keep reading.
INC BC ; Were not interested in the CRC so skip it.
INC BC
CALL SPISKIP
LD A,0 ; And exit with success.
SD_READ5: PUSH AF
LD A,0FFH ; Disable CS therefore deselecting the SD Card.
CALL SPICS
POP AF
EI
RET
SD_READ6: POP HL
LD A,1
JR SD_READ5
; Method to write a 512byte sector to an SD Card.
;
; Input: Memory variables: SDSTARTSEC= unsigned long sector. - The sector number or direct byte address for older cards. This is big endian as per card.
; HL: Address of buffer to read data from.
; Output: A = 0 - All ok. A > 0 - error occurred.
?SD_WRITE: PUSH HL
LD A,000H ; Activate CS (set low).
CALL SPICS
; Open transaction.
LD HL,(SDCAP) ; Check to see if the card has block addressing.
LD H,0
LD A,CT_BLOCK
AND L
JP NZ,SD_WRITE1 ; If it hasnt then we need to multiply up to the correct byte.
CALL LBATOADDR ; Multiply the sector by 512 for byte addressing.
; A = ACMD to send
; LHED = Argument, ie. ACMD = A, L, H, E, D, CRC
SD_WRITE1: LD A,CMD24 ; Send CMD24 to write a sector.
LD (SDBUF),A
LD HL,(SDSTARTSEC) ; Place long endian sector into command buffer.
LD (SDBUF+1),HL
LD HL,(SDSTARTSEC+2)
LD (SDBUF+3),HL
CALL SDCMDNP ; Send command using No Parameters version as we loaded them into the command buffer already.
LD A,(SDBUF+6) ; Fetch result and store.
AND A
JP NZ,SD_WRITE10
LD A,255 ; Ok, so command sent successfully, mark the write by sending an 0xFF followed by 0xFE
CALL SPIOUT
LD A,254
CALL SPIOUT
; Write buffer.
LD DE,SD_SECSIZE
POP HL ; Address to read data from.
SD_WRITE2: LD A,D ; So long as we have bytes in the buffer, send to the card for writing.
OR E
JP Z,SD_WRITE3
PUSH DE
LD A,(HL) ; Get the byte to transmit.
INC HL ; And update the pointer.
CALL SPIOUT ; Transmit value in A.
POP DE
DEC DE
JR SD_WRITE2
; Close transaction.
SD_WRITE3: INC DE ; Add 2 bytes for CRC
INC DE
SD_WRITE4: LD A,D ; Test to see if we are already at zero, ie. all bytes sent. Exit if so.
OR E
JP Z,SD_WRITE5
DEC DE
PUSH DE
LD A,0 ; Send 0's as padding bytes and CRC.
CALL SPIOUT
POP DE
JP SD_WRITE4
SD_WRITE5: CALL SPIIN ; Check received response, if 0x05 which indicates write under way inside SD Card.
AND 01FH
LD L,A
LD H,0
CP 5
JP NZ,SD_WRITE11
LD HL,10000 ; Now wait for the write to complete allowing 1000mS before timing out.
PUSH HL
JR SD_WRITE7
SD_WRITE6: DEC HL
PUSH HL
LD HL,200 ; 200T state delay = 200 x 1/2000000 = 100uS
CALL T_DELAY
SD_WRITE7: CALL SPIIN ; Get a byte, if it is not 0xFF then we have our response so exit.
POP HL
CP 255
JP Z,SD_WRITE8
LD A,H
OR L
JR NZ,SD_WRITE6
SD_WRITE8: LD A,H ; End of timeout? If so we exit with the preset fail code.
OR L
JP Z,SD_WRITE11
XOR A ; Success code.
SD_WRITE9: PUSH AF
LD A,0FFH ; Disable SD Card Chip Select to finish.
CALL SPICS
POP AF
RET
SD_WRITE10: POP HL ; Waste the load address.
SD_WRITE11: LD A,1 ; Error exit.
JR SD_WRITE9
; Method to multiply a 16bit number by another 16 bit number to arrive at a 32bit result.
; Input: DE = Factor 1
; BC = Factor 2
; Output:DEHL = 32bit Product
;
MULT16X16: LD HL,0
LD A,16
MULT16X1: ADD HL,HL
RL E
RL D
JR NC,$+6
ADD HL,BC
JR NC,$+3
INC DE
DEC A
JR NZ,MULT16X1
RET
; Method to add a 16bit number to a 32bit number to obtain a 32bit product.
; Input: DEHL = 32bit Addend
; BC = 16bit Addend
; Output:DEHL = 32bit sum.
;
ADD3216: ADD HL,BC
EX DE,HL
LD BC,0
ADC HL,BC
EX DE,HL
RET
; Method to add two 32bit numbers whilst calculating the SD Start Sector.
; Input: DEHL = 32bit Addend
; (SDSTARTSEC) = 32bit Addend
; Output: (SDSTARTSEC) = 32bit Sum.
; Output; DEHL = 32bit Sum.
;
ADD32: LD BC,(SDSTARTSEC+2)
ADD HL,BC
LD (SDSTARTSEC+2),HL
LD BC,(SDSTARTSEC)
EX DE,HL
ADC HL,BC
LD (SDSTARTSEC),HL
EX DE,HL
RET
; Method to get the LBA sector from the current CP/M Track and Sector.
; This method needs to account for the Rom Filing System image and the other CPM disk images on the SD card.
;
; Input: (CDISK) = Disk number
; (HSTTRK) = Track
; (HSTSEC) = Sector
; Output: (SDSTARTSEC) = LBA on SD Card for the desired sector.
; DEHL = LBA on SD Card for the desired sector.
;
?SD_GETLBA: PUSH AF ; If needed, pass A and flags via the stack. NB This push is removed by BANKTOBANK so no need to pop after the call.
LD A,ROMBANK11 << 4 | ROMBANK10 ; Calling a function in Bank 11 (CBIOS Bank 4) and returning to current bank 10 (CBIOS Bank 3).
LD HL,QGETMAPDSK ; Calling the map disk function.
CALL BANKTOBANK ; Now make a bank to bank function call.
CP 0FFH
JR Z,SDGETLBAX ; This isnt a physical, ROM disk or SD disk, no need to perform any actions, exit.
CP 040H
JR C,SDGETLBAX ; This isnt a ROM disk or an SD disk, no need to perform any actions, exit.
AND 03FH ; Get the SD disk number.
LD B,0
LD C,A
LD DE,CPM_SD_IMGSZ / SD_SECSIZE
CALL MULT16X16
LD (SDSTARTSEC),DE
LD (SDSTARTSEC+2),HL
; DEHL contains the offset for the Disk number, ie. 0 for drive 1, CPM IMAGE SIZE for drive 2, 2x CPM IMAGE SIZE for drive 3 etc.
LD B,0
LD C, SD_SECPTRK ; Number of sectors per track.
LD DE,(HSTTRK) ; For the SD Card we use the full 16bit track number.
CALL MULT16X16
; Add the two.
CALL ADD32
; Add the number of sectors directly to the current sum.
LD A,(HSTSEC)
LD C,A
LD B,0
CALL ADD3216
; Now add the offset to account for the RFS image.
IF RFS_END_ADDR/SD_SECSIZE < 010000H
LD BC, RFS_END_ADDR/SD_SECSIZE ; Sector offset for the RFS Image.
CALL ADD3216
ELSE
LD BC,0 ; Padding is to an even address so lower word will always be zero.
ADD HL,BC
EX DE,HL
LD BC,(RFS_END_ADDR/SD_SECSIZE) / 010000H ; Upper word addition.
ADC HL,BC
EX DE,HL
ENDIF
; Store the final sum as the start sector.
PUSH HL
LD HL,SDSTARTSEC
LD (HL),D
INC HL
LD (HL),E
INC HL
POP DE
LD (HL),D
INC HL
LD (HL),E
LD HL,(SDSTARTSEC)
OR 1 ; Indicate we successfully mapped the track/sector to an LBA.
SDGETLBAX: RET
; Method to read a sector for CPM using its track/sector addressing. All reads occur in a 512byte sector.
;
; Inputs: (HSTTRK) - 16bit track number.
; (HSTSEK) - 8bit sector number.
; (CDISK) - Disk drive number.
?SDC_READ: CALL ?SD_GETLBA ; Get the SD card sector in LBA,
LD A,1
JP Z,SDC_READ1 ; Error in read, exit with stack tidy.
LD HL,HSTBUF ; Address of the host buffer to hold the sector.
CALL ?SD_READ ; Read in the sector.
OR A
JR NZ,SDC_READ1 ; Check for errors and report.
XOR A ; Indicate success.
SDC_READ1: RET
; Method to write a sector for CPM using its track/sector addressing. All writes occur in a 512byte sector.
;
; Inputs: (HSTTRK) - 16bit track number.
; (HSTSEK) - 8bit sector number.
; (CDISK) - Disk drive number.
; Outputs: A = 1 - Error.
; A = 0 - Success.
?SDC_WRITE: CALL ?SD_GETLBA ; Get the SD card sector in LBA,
LD A,1
JP Z,SDC_WRITE1 ; Error in read, exit with stack tidy.
LD HL,HSTBUF ; Setup the location of the buffer to write.
CALL ?SD_WRITE ; Call write to write the buffer into the given sector.
JR NZ,SDC_WRITE1
XOR A
SDC_WRITE1: RET
;-------------------------------------------------------------------------------
; END OF SD CARD CONTROLLER FUNCTIONALITY
;-------------------------------------------------------------------------------
; Align to end of bank.
ALIGN UROMADDR + 07F8h
ORG UROMADDR + 07F8h
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh

641
asm/cbios_bank4.asm Normal file
View File

@@ -0,0 +1,641 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: cbios_bank4.asm
;- Created: January 2020
;- Author(s): Philip Smart
;- Description: Sharp MZ series CPM BIOS System.
;- This assembly language program is written to utilise the banked flashroms added with
;- the MZ-80A RFS hardware upgrade for the CPM CBIOS in order to preserve RAM for actual
;- CPM TPA programs.
;-
;- Credits:
;- Copyright: (c) 2018-23 Philip Smart <philip.smart@net2net.org>
;-
;- History: Jan 2020 - Seperated Bank from RFS for dedicated use with CPM CBIOS.
;- May 2020 - Advent of the new RFS PCB v2.0, quite a few changes to accommodate the
;- additional and different hardware. The SPI is now onboard the PCB and
;- not using the printer interface card.
;- Mar 2021 - Updates for the RFS v2.1 board.
;--------------------------------------------------------------------------------------------------------
;- 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 definitions and macros.
INCLUDE "cpm_buildversion.asm"
INCLUDE "cpm_definitions.asm"
INCLUDE "macros.asm"
;============================================================
;
; USER ROM CPM CBIOS BANK 4 - Floppy Disk Controller functions.
;
;============================================================
ORG UROMADDR
;-----------------------------------------------------------------------------------------
; Common code spanning all banks to ensure that a Monitor is selected upon power up/reset.
;-----------------------------------------------------------------------------------------
NOP
LD B,16 ; If we read the bank control reset register 15 times then this will enable bank control and then the 16th read will reset all bank control registers to default.
CBIOS1_0: LD A,(BNKCTRLRST)
DJNZ CBIOS1_0 ; Apply the default number of coded latch reads to enable the bank control registers.
LD A,BNKCTRLDEF ; Set coded latch, SDCS high, BBMOSI to high and BBCLK to high which enables SDCLK.
LD (BNKCTRL),A
NOP
NOP
NOP
XOR A ; We shouldnt arrive here after a reset, if we do, select MROM bank 0
LD (BNKSELMROM),A
NOP
NOP
NOP
LD (BNKSELUSER),A ; and start up - ie. SA1510 Monitor - this occurs as User Bank 0 is enabled and the jmp to 0 is coded in it.
;
; No mans land... this should have switched to Bank 0 and at this point there is a jump to 00000H.
JP 00000H ; This is for safety!!
;-------------------------------------------------------------------------------
; Jump table for entry into this pages functions.
;-------------------------------------------------------------------------------
ALIGN_NOPS UROMJMPTBL
JP ?DSKINIT ; DSKINIT
JP ?SETDRVCFG ; SETDRVCFG
JP ?SETDRVMAP ; SETDRVMAP
JP ?SELDRIVE ; SELDRIVE
JP ?GETMAPDSK ; GETMAPDSK
JP ?DSKREAD ; DSKREAD
JP ?DSKWRITE ; DSKWRITE
;-------------------------------------------------------------------------------
; START OF FDC CONTROLLER FUNCTIONALITY
;-------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------
; Initialise drive and reset flags, Set motor off
;
;------------------------------------------------------------------------------------------------
?DSKINIT: XOR A
OUT (FDC_MOTOR),A ; Motor off
LD (TRK0FD1),A ; Track 0 flag drive 1
LD (TRK0FD2),A ; Track 0 flag drive 2
LD (TRK0FD3),A ; Track 0 flag drive 3
LD (TRK0FD4),A ; Track 0 flag drive 4
LD (MOTON),A ; Motor on flag
LD (MTROFFTIMER),A ; Clear the down counter for motor off.
LD A,(FDCROMADDR) ; Check to see if the FDC AFI ROM is installed, use this as
OR A ; an indicator that the FDC is present.
RET
; Function to create a mapping table between a CPM disk and a physical disk.
?SETDRVMAP: PUSH HL
PUSH DE
PUSH BC
; Zero out the map.
LD B,MAXDISKS
LD HL,DISKMAP
LD A,0FFH
SETDRVMAP1: LD (HL),A
INC HL
DJNZ SETDRVMAP1
LD HL,DISKMAP ; Place in the Map for next drive.
; Now go through each disk from the Disk Parameter Base list.
LD B,0 ; Disk number count = CDISK.
LD DE,0 ; Physical disk number, D = FDC, E = SDC.
SETDRVMAP2: LD A,B
CP MAXDISKS
JR Z,SETDRVMAP6
INC B
PUSH HL
PUSH DE
PUSH BC
; For the Disk in A, find the parameter table.
RLC A ; *2
RLC A ; *4
RLC A ; *8
RLC A ; *16
LD HL,DPBASE ; Base of disk description block.
LD B,0
LD C,A
ADD HL,BC ; HL contains address of actual selected disk block.
LD C,10
ADD HL,BC ; HL contains address of pointer to disk parameter block.
LD E,(HL)
INC HL
LD D,(HL) ; DE contains address of disk parameter block.
EX DE,HL
LD A,(HL)
LD E,A
LD BC,15
ADD HL,BC ; Move to configuuration byte which identifies the disk type.
;
POP BC
POP DE
LD A,(HL)
POP HL
BIT 4,A ; Disk type = FDC?
JR NZ,SETDRVMAP2A
BIT 3,A
JR Z,SETDRVMAP4 ; Is this an FDC controlled disk, if so store the mapping number in the map unchanged.
;
LD A,E
OR 020H ; This is a RAM drive, add 020H to the mapping number and store.
INC E
JR SETDRVMAP5
;
SETDRVMAP2A:BIT 3,A ; Is this an SD Card disk, if so, add 080H to the mapping number and store.
JR Z,SETDRVMAP3
LD A,E
OR 080H
INC E
JR SETDRVMAP5
SETDRVMAP3: LD A,E ; This is a ROM drive, add 040H to the mapping number and store.
OR 040H
INC E
JR SETDRVMAP5
;
SETDRVMAP4: LD A,D
INC D
SETDRVMAP5: LD (HL),A
INC HL
JR SETDRVMAP2
;
SETDRVMAP6: POP BC
POP DE
POP HL
RET
; Function to setup the drive parameters according to the CFG byte in the disk parameter block.
?SETDRVCFG: PUSH HL
PUSH DE
PUSH BC
LD A,(CDISK)
RLC A ; *2
RLC A ; *4
RLC A ; *8
RLC A ; *16
LD HL,DPBASE ; Base of disk description block.
LD B,0
LD C,A
ADD HL,BC ; HL contains address of actual selected disk block.
LD C,10
ADD HL,BC ; HL contains address of pointer to disk parameter block.
LD E,(HL)
INC HL
LD D,(HL) ; DE contains address of disk parameter block.
EX DE,HL
LD A,(HL)
LD E,A
LD BC,15
ADD HL,BC ; Move to configuuration byte.
XOR A
BIT 2,(HL)
JR Z,SETDRV0
INC A
SETDRV0: LD (INVFDCDATA),A ; Data inversion is set according to drive parameter.
LD A,4
BIT 1,(HL)
JR Z,SETDRV1
LD A,2
BIT 0,(HL)
JR Z,SETDRV1
LD A,1
SETDRV1: LD (SECTORCNT),A ; Set the disk sector size.
LD D,A
CP 4
LD A,E
JR Z,SETDRV1A
OR A
RR A
LD E,A
LD A,D
CP 2
LD A,E
JR Z,SETDRV1A
OR A
RR A ; Convert sectors per track from 128 bytes to 256 byte sectors.
SETDRV1A: INC A ; Add 1 to ease comparisons.
LD (SECPERTRK),A ; Only cater for 8bit, ie. 256 sectors.
DEC A
OR A
RR A
INC A ; Add 1 to ease comparisons.
LD (SECPERHEAD),A ; Convert sectors per track to sectors per head.
;
XOR A ; Disk type = FDC
BIT 4,(HL)
JR NZ,SETDRV1B ; 4 = 1?
BIT 3,(HL)
JR Z,SETDRV2 ; 3 = 0 - FDC
LD A,DSKTYP_RAM
JR SETDRV2
SETDRV1B: LD A,DSKTYP_ROM ; Disk type = ROMFS
BIT 3,(HL) ; 3 = 0? Thus 1:0 = ROM
JR Z,SETDRV2
LD A,DSKTYP_SDC ; Disk type = SD Card, ie. 1:1
SETDRV2: LD (DISKTYPE),A
POP BC
POP DE
POP HL
RET
; Method to get the current disk drive mapped to the correct controller.
; The CPM CDISK is mapped via MAPDISK[CDISK] and the result:
; Bit 7 = 1 - SD Card drive.
; Bit 6 = 1 - ROM Drive.
; BIT 7:6 = 00 - Floppy drive.
?GETMAPDSK: PUSH HL
PUSH BC
LD A,(CDISK)
LD HL,DISKMAP
LD C,A
LD B,0
ADD HL,BC
LD A,(HL) ; Get the physical number after mapping from the CDISK.
POP BC
POP HL
RET
; Select FDC drive (make active) based on value in DISKMAP[CDISK].
?SELDRIVE: CALL ?GETMAPDSK
CP 020H ; Anything with bit 7:5 set is not an FDC drive.
RET NC ; This isnt a physical floppy disk, no need to perform any actions, exit.
LD (FDCDISK),A
CALL DSKMTRON ; yes, set motor on and wait
LD A,(FDCDISK) ; select drive no
OR 084H
OUT (FDC_MOTOR),A ; Motor on for drive 0-3
XOR A
LD (FDCCMD),A ; clr latest FDC command byte
LD HL,00000H
SELDRV2: DEC HL
LD A,H
OR L
JP Z,SELDRVERR ; Reset and print message that this is not a valid disk.
IN A,(FDC_STR) ; Status register.
CPL
RLCA
JR C,SELDRV2 ; Wait on Drive Ready Bit (bit 7)
LD A,(FDCDISK) ; Drive number
LD C,A
LD HL,TRK0FD1 ; 1 track 0 flag for each drive
LD B,000H
ADD HL,BC ; Compute related flag 1002/1003/1004/1005
BIT 0,(HL)
JR NZ,SELDRV3 ; If the drive hasnt been intialised to track 0, intialise and set flag.
CALL DSKSEEKTK0 ; Seek track 0.
SET 0,(HL) ; Set bit 0 of trk 0 flag
SELDRV3: CALL ?SETDRVCFG
RET
; Turn disk motor on if not already running.
DSKMTRON: LD A,255 ; Ensure motor is kept running whilst we read/write.
LD (MTROFFTIMER),A
LD A,(MOTON) ; Test to see if motor is on, if it isnt, switch it on.
RRCA
JR NC, DSKMOTORON
RET
DSKMOTORON: PUSH BC
LD A,080H
OUT (FDC_MOTOR),A ; Motor on
LD B,010H ;
DSKMTR2: CALL MTRDELAY ;
DJNZ DSKMTR2 ; Wait until becomes ready.
LD A,001H ; Set motor on flag.
LD (MOTON),A ;
POP BC
RET
FDCDLY1: PUSH DE
LD DE,00007H
JP MTRDEL2
MTRDELAY: PUSH DE
LD DE,01013H
MTRDEL2: DEC DE
LD A,E
OR D
JR NZ,MTRDEL2
POP DE
RET
?DSKWRITE: LD A,MAXWRRETRY
LD (RETRIES),A
LD A,(SECTORCNT)
LD B,A
LD A,(HSTSEC)
DSKWRITE0A: DJNZ DSKWRITE0B
JR DSKWRITE1
DSKWRITE0B: OR A
RL A
JR DSKWRITE0A
DSKWRITE1: INC A
LD (SECTORNO), A ; Convert from Host 512 byte sector into local sector according to paraameter block.
LD HL,(HSTTRK)
LD (TRACKNO),HL
DSKWRITE2: CALL SETTRKSEC ; Set current track & sector, get load address to HL
DSKWRITE3: CALL SETHEAD ; Set side reg
CALL SEEK ; Command 1b output (seek)
JP NZ,SEEKRETRY ;
CALL OUTTKSEC ; Set track & sector reg
LD IX, 0F3FEH ; As below. L03FE
LD IY,WRITEDATA ; Write sector from memory.
DI
;
LD A,0B4H ; Write Sector multipe with Side Compare for side 1.
CALL DISKCMDWAIT
LD D,2 ; Regardless of 4x128, 2x256 or 1x512, we always read 512bytes by the 2x INI instruction with B=256.
STRTDATWR: LD B,0 ; 256 bytes to load.
JP (IX)
WRITEDATA: OUTI
JP NZ, 0F3FEH ; This is crucial, as the Z80 is running at 2MHz it is not fast enough so needs
; hardware acceleration in the form of a banked ROM, if disk not ready jumps to IX, if
; data ready, jumps to IY.
DEC D
JP NZ,0F3FEH ; If we havent read all sectors to form a 512 byte block, go for next sector.
JR DATASTOP
; Read disk starting at the first logical sector in param block 1009/100A
; Continue reading for the given size 100B/100C and store in the location
; Pointed to by the address stored in the parameter block. 100D/100E
?DSKREAD: LD A,MAXRDRETRY
LD (RETRIES),A
LD A,(SECTORCNT)
LD B,A
LD A,(HSTSEC)
DSKREAD0A: DJNZ DSKREAD0B
JR DSKREAD1
DSKREAD0B: OR A
RL A
JR DSKREAD0A
DSKREAD1: INC A
LD (SECTORNO), A ; Convert from Host 512 byte sector into local sector according to paraameter block.
LD HL,(HSTTRK)
LD (TRACKNO),HL
DSKREAD2: CALL SETTRKSEC ; Set current track & sector, get load address to HL
DSKREAD3: CALL SETHEAD ; Set side reg
CALL SEEK ; Command 1b output (seek)
JP NZ,SEEKRETRY ;
CALL OUTTKSEC ; Set track & sector reg
LD IX, 0F3FEH ; As below. L03FE
LD IY,READDATA ; Read sector into memory.
DI
;
LD A,094H ; Read Sector multiple with Side Compare for side 1.
CALL DISKCMDWAIT
LD D,2 ; Regardless of 4x128, 2x256 or 1x512, we always read 512bytes by the 2x INI instruction with B=256.
STRTDATRD: LD B,0 ; 256 bytes to load.
JP (IX)
; Get data from disk sector to staging area.
READDATA: INI
JP NZ,0F3FEH ; This is crucial, as the Z80 is running at 2MHz it is not fast enough so needs
; hardware acceleration in the form of a banked ROM, if disk not ready jumps to IX, if
; data ready, jumps to IY.
DEC D
JP NZ,0F3FEH ; If we havent read all sectors to form a 512 byte block, go for next sector.
;
;
DATASTOP: LD A,0D8H ; Force interrupt command, Immediate interrupt (I3 bit 3=1) of multiple sector read.
CPL
OUT (FDC_CR),A
CALL WAITRDY ; Wait for controller to become ready, acknowledging interrupt.
IN A,(FDC_STR) ; Check for errors.
CPL
AND 0FFH
JR NZ,SEEKRETRY
UPDSECTOR: PUSH HL
LD A,(SECTORCNT)
LD HL,SECTORNO
ADD A,(HL) ; Update sector to account for sectors read. NB. All reads will start at such a position
LD (HL), A ; that a read will not span a track or head. Ensure that disk formats meet an even 512byte format.
POP HL
MOTOROFF: LD A,MTROFFMSECS ; Schedule motor to be turned off.
LD (MTROFFTIMER),A
XOR A ; Successful read, return 0
EI
RET
SEEKRETRY: LD B,A ; Preserve the FDC Error byte.
LD A,(RETRIES)
DEC A
LD (RETRIES),A
LD A,B
JP Z,RETRIESERR
CALL DSKSEEKTK0
LD A, (READOP)
OR A
LD A,(TRACKNO) ; NB. Track number is 16bit, FDC only uses lower 8bit and assumes little endian read.
JP Z, DSKWRITE2 ; Try write again.
JP DSKREAD2 ; Try the read again.
DISKCMDWAIT:LD (FDCCMD),A
CPL
OUT (FDC_CR),A
CALL WAITBUSY
RET
; Send a command to the disk controller.
DSKCMD: LD (FDCCMD),A ; Store latest FDC command.
CPL ; Compliment it (FDC bit value is reversed).
OUT (FDC_CR),A ; Send command to FDC.
CALL WAITRDY ; Wait to become ready.
IN A,(FDC_STR) ; Get status register.
CPL ; Inverse (FDC is reverse bit logic).
RET
; Seek to programmed track.
SEEK: LD A,01BH ; Seek command, load head, verify stepping 6ms.
CALL DSKCMD
AND 099H
RET
; Set current track & sector, get load address to HL
SETTRKSEC: CALL ?SELDRIVE
LD A,(TRACKNO) ; NB. Track number is 16bit, FDC only uses lower 8bit and assumes little endian read.
LD HL, HSTBUF
RET
; Compute side/head.
SETHEAD: CPL ;
OUT (FDC_DR),A ; Output track no for SEEK command.
PUSH HL
LD HL,SECPERHEAD
LD A,(SECTORNO) ; Check sector, if greater than sector per track, change head.
CP (HL)
POP HL
JR NC,SETHD2 ; Yes, even, set side/head 1
LD A,001H ; No, odd, set side/head 0
JR SETHD3
; Set side/head register.
SETHD2: XOR A ; Side 0
SETHD3: CPL ; Side 1
OUT (FDC_SIDE),A ; Side/head register.
RET
; Set track and sector register.
OUTTKSEC: PUSH HL
LD HL,SECPERHEAD
;
LD C,FDC_DR ; Port for data retrieval in the INI instruction in main block.
LD A,(TRACKNO) ; Current track number, NB. Track number is 16bit, FDC only uses lower 8bit and assumes little endian read.
CPL
OUT (FDC_TR),A ; Track reg
;
LD A,(SECTORNO) ; Current sector number
CP (HL)
JR C,OUTTKSEC2
SUB (HL)
INC A ; Account for the +1 added to ease comparisons.
OUTTKSEC2: CPL
OUT (FDC_SCR),A ; Sector reg
POP HL
RET
; Seek to track 0.
DSKSEEKTK0: CALL DSKMTRON ; Make sure disk is spinning.
LD A,00BH ; Restore command, seek track 0.
CALL DSKCMD ; Send command to FDC.
AND 085H ; Process result.
XOR 004H
RET Z
JP DSKSEEKERR
; Wait for the drive to become ready.
WAITRDY: PUSH DE
PUSH HL
CALL FDCDLY1
LD E,007H
WAITRDY2: LD HL,00000H
WAITRDY3: DEC HL
LD A,H
OR L
JR Z,WAITRDY4
IN A,(FDC_STR)
CPL
RRCA
JR C,WAITRDY3
POP HL
POP DE
RET
WAITRDY4: DEC E
JR NZ,WAITRDY2
POP HL
POP DE
JP WAITRDYERR
WAITBUSY: PUSH DE
PUSH HL
CALL FDCDLY1
LD E,007H ; 7 Chances of a 16bit down count delay waiting for DRQ.
WAITBUSY2: LD HL,00000H
WAITBUSY3: DEC HL
LD A,H
OR L
JR Z,WAITBUSY4 ; Down counter expired, decrement retries, error on 0.
IN A,(FDC_STR) ; Get the FDC Status
CPL ; Switch to positive logic.
RRCA ; Shift Busy flag into Carry.
JR NC,WAITBUSY3 ; Busy not set, decrement counter and retry.
POP HL
POP DE
RET
WAITBUSY4: DEC E
JR NZ,WAITBUSY2
POP HL
POP DE
JP DSKERR
; Error processing. Consists of printing a message followed by debug data (if enabled) and returning with carry set
; to indicate error.
DSKERR: LD DE,LOADERR ; Loading error message
JR HDLERROR
SELDRVERR: LD DE,SELDRVMSG ; Select drive error message.
JR HDLERROR
WAITRDYERR: LD DE,WAITRDYMSG ; Waiting for ready timeout error message.
JR HDLERROR
DSKSEEKERR: LD DE,DSKSEEKMSG ; Disk seek to track error message.
JR HDLERROR
RETRIESERR: BIT 2,A ; Data overrun error if 1.
LD DE,DATAOVRMSG
JR NZ, RETRIESERR2
BIT 3,A ; CRC error if 1.
LD DE,CRCERRMSG
JR NZ,RETRIESERR2
LD DE,RETRIESMSG ; Data sector read error message.
RETRIESERR2:
; Process error, dump debug data and return fail code.
HDLERROR: LD HL,MSGSTRBUF ; Copy the error messae
HOLERR1: LD A,(DE)
LD (HL),A
CP NUL
JR Z,HOLERR2
INC DE
INC HL
JR HOLERR1
HOLERR2: LD DE,MSGSTRBUF
HOLPRTSTR: LD A,(DE)
OR A
JR Z,HOLERR3
INC DE
HOLPRTSTR2: LD HL,QPRNT
PUSH AF
LD A,ROMBANK9 << 4 | ROMBANK11 ; Call CBIOS Bank 2 from CBIOS Bank 4
CALL BANKTOBANK
JR HOLPRTSTR
HOLERR3: XOR A
CALL ?DSKINIT
CALL DSKMTRON
LD A,001H ; Indicate error by setting 1 in A register.
EI
RET
;-------------------------------------------------------------------------------
; END OF FDC CONTROLLER FUNCTIONALITY
;-------------------------------------------------------------------------------
;--------------------------------------
;
; Message table
;
;--------------------------------------
LOADERR: DB "DISK ERROR - LOADING", CR, NUL
SELDRVMSG: DB "DISK ERROR - SELECT", CR, NUL
WAITRDYMSG: DB "DISK ERROR - WAIT", CR, NUL
DSKSEEKMSG: DB "DISK ERROR - SEEK", CR, NUL
RETRIESMSG: DB "DISK ERROR - RETRIES", CR, NUL
DATAOVRMSG: DB "DISK ERROR - DATA OVERRUN", CR, NUL
CRCERRMSG: DB "DISK ERROR - CRC ERROR", CR, NUL
; Align to end of bank.
ALIGN UROMADDR + 07F8h
ORG UROMADDR + 07F8h
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh

84
asm/cpm22-bios.asm Normal file
View File

@@ -0,0 +1,84 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: cpm22-bios.asm
;- Created: January 2020
;- Author(s): Philip Smart
;- Description: CPM BIOS for CPM v2.23 on the Sharp MZ80A with the Rom Filing System.
;- Most of the code is stored in the ROM based CBIOS which is part of the
;- Rom Filing System upgrade. Declarations in this file are for tables
;- which need to reside in RAM.
;-
;- Credits: Some of the comments and parts of the deblocking/blocking algorithm come from the
; Z80-MBC2 project, (C) SuperFabius.
;- Copyright: (c) 2020-2023 Philip Smart <philip.smart@net2net.org>
;-
;- History: January 2020 - Initial creation.
;-
;--------------------------------------------------------------------------------------------------------
;- 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/>.
;--------------------------------------------------------------------------------------------------------
ORG CPMBIOS
; Boot strap code to setup the machine in order to run CPM and the CBIOS.
; Previously this used to be in the comment field of the tape header but with the
; advent of the SDCFS which doesnt store the comment, the bootstrap needs to be relocated.
; This code will be overwritten with the DP Headers on cold boot.
BOOTLDR: LD B, 0x10 ; Need to read the same location 16 times to enable I/O operations.
BOOTLDR2: LD A, (BNKCTRLRST)
DJNZ BOOTLDR2
LD A, 0x07
LD (BNKCTRL), A ; Setup the User ROM Bank default.
LD A, (MEMSW) ; Swap 0000:0FFF to C000:CFFF so lower location uses DRAM.
LD A, 0x02
LD (BNKSELMROM), A ; Setup the Monitor ROM bank default.
JP CBIOSSTART ; Cold start the CBIOS.
;------------------------------------------------------------------------------------------------------------
; DISK PARAMETER HEADER
;
; Disk parameter headers for disk 0 to 3
;
; +-------+------+------+------+----------+-------+-------+-------+
; | XLT | 0000 | 0000 | 0000 |DIRBUF | DPB | CSV | ALV |
; +------+------+------+-------+----------+-------+-------+-------+
; 16B 16B 16B 16B 16B 16B 16B 16B
;
; -XLT Address of the logical-to-physical translation vector, if used for this particular drive,
; or the value 0000H if no sector translation takes place (that is, the physical and
; logical sectornumbers are the same). Disk drives with identical sector skew factors share
; the same translatetables.
; -0000 Scratch pad values for use within the BDOS, initial value is unimportant.
; -DIRBUF Address of a 128-byte scratch pad area for directory operations within BDOS. All DPHs
; address the same scratch pad area.
; -DPB Address of a disk parameter block for this drive. Drives with identical disk characteristics
; address the same disk parameter block.
; -CSV Address of a scratch pad area used for software check for changed disks. This address is
; different for each DPH.
; -ALV Address of a scratch pad area used by the BDOS to keep disk storage allocation information.
; This address is different for each DPH.
;------------------------------------------------------------------------------------------------------------
;ALIGN_NOPS DPBASE ; Space for 2xROM, 2xFD, 3xSD or upto 7 drives
; These entries are created dynamically based on hardware available.
; NB. The Disk Parameter Blocks are stored in CBIOS ROM to save RAM space.
;------------------------------------------------------------------------------------------------------------
; CPN Disk work areas.
;------------------------------------------------------------------------------------------------------------
ALIGN_NOPS CDIRBUF ; Memory work areas, just allocate the space.
ALIGN_NOPS CSVALVMEM
ALIGN_NOPS CSVALVEND
ALIGN CBIOSDATA

3764
asm/cpm22.asm Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
BUILD_VERSION EQU 2

View File

@@ -0,0 +1 @@
BUILD_VERSION EQU 1

View File

@@ -0,0 +1,589 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: CPM_Definitions.asm
;- Created: January 2020
;- Author(s): Philip Smart
;- Description: Sharp MZ series CPM v2.23
;- Definitions for the Sharp MZ80A CPM v2.23 OS used in the RFS
;-
;- Credits:
;- Copyright: (c) 2019-23 Philip Smart <philip.smart@net2net.org>
;-
;- History: Jan 2020 - Initial version.
; May 2020 - Advent of the new RFS PCB v2.0, quite a few changes to accommodate the
; additional and different hardware. The SPI is now onboard the PCB and
; not using the printer interface card.
; Mar 2021 - Changes to work with the RFS v2.1 board.
;- Apr 2021 - Removed ROM and RAM Drive functionality as it provided no performance or
;- use benefit over SD which are much larger and RW.
;-
;--------------------------------------------------------------------------------------------------------
;- 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/>.
;--------------------------------------------------------------------------------------------------------
;-----------------------------------------------
; Features.
;-----------------------------------------------
HW_SPI_ENA EQU 1 ; Set to 1 if hardware SPI is present on the RFS PCB v2 board.
SW_SPI_ENA EQU 0 ; Set to 1 if software SPI is present on the RFS PCB v2 board.
PP_SPI_ENA EQU 0 ; Set to 1 if using the SPI interface via the Parallel Port, ie. for RFS PCB v1 which doesnt have SPI onboard.
; Build time options, only set to '1' to build, '0' to disable, only 1 can be set to '1'.
; IF BUILD_VERSION = 0
BUILD_80C EQU 1 ; Build for an MZ-80A with a 40/80 column card.
BUILD_40C EQU 0 ; Build for a standard 40 column MZ-80A.
; ENDIF
; IF BUILD_VERSION = 1
;BUILD_80C EQU 0 ; Build for an MZ-80A with a 40/80 column card.
;BUILD_40C EQU 1 ; Build for a standard 40 column MZ-80A.
; ENDIF
;-----------------------------------------------
; Configurable settings.
;-----------------------------------------------
MAXRDRETRY EQU 002h
MAXWRRETRY EQU 002h
BLKSIZ EQU 4096 ; CP/M allocation size
HSTSIZ EQU 512 ; host disk sector size
HSTSPT EQU 32 ; host disk sectors/trk
HSTBLK EQU HSTSIZ/128 ; CP/M sects/host buff
CPMSPT EQU HSTBLK * HSTSPT ; CP/M sectors/track
SECMSK EQU HSTBLK-1 ; sector mask
WRALL EQU 0 ; write to allocated
WRDIR EQU 1 ; write to directory
WRUAL EQU 2 ; write to unallocated
TMRTICKINTV EQU 5 ; Number of 0.010mSec ticks per interrupt, ie. resolution of RTC.
MTROFFMSECS EQU 100 ; Time from last access to motor being switched off in seconds in TMRTICKINTV ticks.
IF BUILD_80C = 1
COLW EQU 80 ; Width of the display screen (ie. columns).
ELSE
COLW EQU 40 ; Width of the display screen (ie. columns).
ENDIF
ROW EQU 25 ; Number of rows on display screen.
SCRNSZ EQU COLW * ROW ; Total size, in bytes, of the screen display area.
SCRLW EQU COLW / 8 ; Number of 8 byte regions in a line for hardware scroll.
; BIOS equates
MAXDISKS EQU 7 ; Max number of Drives supported
KEYBUFSIZE EQU 16 ; Ensure this is a power of 2, max size 256.
; Debugging
ENADEBUG EQU 0 ; Enable debugging logic, 1 = enable, 0 = disable
;-----------------------------------------------
; Entry/compilation start points.
;-----------------------------------------------
CBIOSSTART EQU 0C000h
CBIOSDATA EQU CBIOSSTART - 0400H
UROMADDR EQU 0E800H ; Start of User ROM Address space.
FDCROMADDR EQU 0F000H
CBASE EQU 0A000H
CPMCCP EQU CBASE ; CP/M System entry
CPMBDOS EQU CPMCCP + 0806H ; BDOS entry
CPMBIOS EQU CPMCCP + 01600H ; Original CPM22 BIOS entry
CPMCOPYRMSG EQU CBASE+8 ; Copyright message stored in CP/M binary.
BOOT EQU CBIOSSTART + 0
WBOOT EQU CBIOSSTART + 3
WBOOTE EQU CBIOSSTART + 3
CONST EQU CBIOSSTART + 6
CONIN EQU CBIOSSTART + 9
CONOUT EQU CBIOSSTART + 12
LIST EQU CBIOSSTART + 15
PUNCH EQU CBIOSSTART + 18
READER EQU CBIOSSTART + 21
HOME EQU CBIOSSTART + 24
SELDSK EQU CBIOSSTART + 27
SETTRK EQU CBIOSSTART + 30
SETSEC EQU CBIOSSTART + 33
SETDMA EQU CBIOSSTART + 36
READ EQU CBIOSSTART + 39
WRITE EQU CBIOSSTART + 42
FRSTAT EQU CBIOSSTART + 45
SECTRN EQU CBIOSSTART + 48
UNUSED EQU CBIOSSTART + 51
BANKTOBANK EQU CBIOSSTART + 54
CCP EQU CBASE
CCPCLRBUF EQU CBASE + 3
DPBASE EQU CPMBIOS
CDIRBUF EQU CPMBIOS + (MAXDISKS * 16)
CSVALVMEM EQU CDIRBUF + 128
CSVALVEND EQU CBIOSDATA - 1 ;CSVALVMEM + 1253
IOBYT EQU 00003H ; IOBYTE address
CDISK EQU 00004H ; Address of Current drive name and user number
CPMUSERDMA EQU 00080h ; Default CPM User DMA address.
DPSIZE EQU 16 ; Size of a Disk Parameter Block
DPBLOCK0 EQU SCRN - (8 * DPSIZE) ; Location of the 1st DPB in the CBIOS Rom.
DPBLOCK1 EQU DPBLOCK0 + DPSIZE
DPBLOCK2 EQU DPBLOCK1 + DPSIZE
DPBLOCK3 EQU DPBLOCK2 + DPSIZE
DPBLOCK4 EQU DPBLOCK3 + DPSIZE
DPBLOCK5 EQU DPBLOCK4 + DPSIZE
DPBLOCK6 EQU DPBLOCK5 + DPSIZE
DPBLOCK7 EQU DPBLOCK6 + DPSIZE
;-------------------------------------------------------
; Function entry points in the CBIOS ROMS
;-------------------------------------------------------
UROMJMPTBL EQU UROMADDR + 00020H ; Position at beginning of each bank of an API jump table of public methods in the bank
; Public functions in CBIOS User ROM Bank 1 - utility functions, ie. Audio.
QREBOOT EQU 0 + UROMJMPTBL
QMELDY EQU 3 + UROMJMPTBL
QTEMP EQU 6 + UROMJMPTBL
QMSTA EQU 9 + UROMJMPTBL
QMSTP EQU 12 + UROMJMPTBL
QBEL EQU 15 + UROMJMPTBL
QMODE EQU 18 + UROMJMPTBL
QTIMESET EQU 21 + UROMJMPTBL
QTIMEREAD EQU 24 + UROMJMPTBL
QCHKKY EQU 27 + UROMJMPTBL
QGETKY EQU 30 + UROMJMPTBL
; Public functions in CBIOS User ROM Bank 2 - Screen / ANSI terminal functions.
QPRNT EQU 0 + UROMJMPTBL
QPRTHX EQU 3 + UROMJMPTBL
QPRTHL EQU 6 + UROMJMPTBL
QANSITERM EQU 9 + UROMJMPTBL
; Public functions in CBIOS User ROM Bank 3 - SD Card functions.
SD_INIT EQU 0 + UROMJMPTBL
SD_READ EQU 3 + UROMJMPTBL
SD_WRITE EQU 6 + UROMJMPTBL
SD_GETLBA EQU 9 + UROMJMPTBL
SDC_READ EQU 12 + UROMJMPTBL
SDC_WRITE EQU 15 + UROMJMPTBL
; Public functions in CBIOS User ROM Bank 4 - Floppy Disk Controller functions.
QDSKINIT EQU 0 + UROMJMPTBL
QSETDRVCFG EQU 3 + UROMJMPTBL
QSETDRVMAP EQU 6 + UROMJMPTBL
QSELDRIVE EQU 9 + UROMJMPTBL
QGETMAPDSK EQU 12 + UROMJMPTBL
QDSKREAD EQU 15 + UROMJMPTBL
QDSKWRITE EQU 18 + UROMJMPTBL
;-----------------------------------------------
; Memory mapped ports in hardware.
;-----------------------------------------------
SCRN: EQU 0D000H
ARAM: EQU 0D800H
DSPCTL: EQU 0DFFFH ; Screen 40/80 select register (bit 7)
KEYPA: EQU 0E000h
KEYPB: EQU 0E001h
KEYPC: EQU 0E002h
KEYPF: EQU 0E003h
CSTR: EQU 0E002h
CSTPT: EQU 0E003h
CONT0: EQU 0E004h
CONT1: EQU 0E005h
CONT2: EQU 0E006h
CONTF: EQU 0E007h
SUNDG: EQU 0E008h
TEMP: EQU 0E008h
MEMSW: EQU 0E00CH
MEMSWR: EQU 0E010H
INVDSP: EQU 0E014H
NRMDSP: EQU 0E015H
SCLDSP: EQU 0E200H
SCLBASE: EQU 0E2H
BNKCTRLRST: EQU 0EFF8H ; Bank control reset, returns all registers to power up default.
BNKCTRLDIS: EQU 0EFF9H ; Disable bank control registers by resetting the coded latch.
HWSPIDATA: EQU 0EFFBH ; Hardware SPI Data register (read/write).
HWSPISTART: EQU 0EFFCH ; Start an SPI transfer.
BNKSELMROM: EQU 0EFFDh ; Select RFS Bank1 (MROM)
BNKSELUSER: EQU 0EFFEh ; Select RFS Bank2 (User ROM)
BNKCTRL: EQU 0EFFFH ; Bank Control register (read/write).
;
; RFS v2 Control Register constants.
;
BBCLK EQU 1 ; BitBang SPI Clock.
SDCS EQU 2 ; SD Card Chip Select, active low.
BBMOSI EQU 4 ; BitBang MOSI (Master Out Serial In).
CDLTCH1 EQU 8 ; Coded latch up count bit 1
CDLTCH2 EQU 16 ; Coded latch up count bit 2
CDLTCH3 EQU 32 ; Coded latch up count bit 3
BK2A19 EQU 64 ; User ROM Device Select Bit 0 (or Address bit 19).
BK2A20 EQU 128 ; User ROM Device Select Bit 1 (or Address bit 20).
; BK2A20 : BK2A19
; 0 0 = Flash RAM 0 (default).
; 0 1 = Flash RAM 1.
; 1 0 = Flasm RAM 2 or Static RAM 0.
; 1 1 = Reserved.
BNKCTRLDEF EQU BBMOSI+SDCS+BBCLK ; Default on startup for the Bank Control register.
;-----------------------------------------------
; IO ports in hardware and values.
;-----------------------------------------------
SPI_OUT EQU 0FFH
SPI_IN EQU 0FEH
;
DOUT_LOW EQU 000H
DOUT_HIGH EQU 004H
DOUT_MASK EQU 004H
DIN_LOW EQU 000H
DIN_HIGH EQU 001H
CLOCK_LOW EQU 000H
CLOCK_HIGH EQU 002H
CLOCK_MASK EQU 0FDH
CS_LOW EQU 000H
CS_HIGH EQU 001H
;-----------------------------------------------
; Rom File System Header (MZF)
;-----------------------------------------------
RFS_ATRB: EQU 00000h ; Code Type, 01 = Machine Code.
RFS_NAME: EQU 00001h ; Title/Name (17 bytes).
RFS_SIZE: EQU 00012h ; Size of program.
RFS_DTADR: EQU 00014h ; Load address of program.
RFS_EXADR: EQU 00016h ; Exec address of program.
RFS_COMNT: EQU 00018h ; COMMENT
MZFHDRSZ EQU 128 ; Full MZF Header size
MZFHDRNCSZ EQU 24 ; Only the primary MZF data, no comment field.
RFSSECTSZ EQU 256
MROMSIZE EQU 4096
UROMSIZE EQU 2048
BANKSPERTRACK EQU (ROMSECTORSIZE * ROMSECTORS) / UROMSIZE ; (8) We currently only use the UROM for disk images.
SECTORSPERBANK EQU UROMSIZE / ROMSECTORSIZE ; (16)
SECTORSPERBLOCK EQU RFSSECTSZ/ROMSECTORSIZE ; (2)
ROMSECTORSIZE EQU 128
ROMSECTORS EQU 128
RAMDRVSECTORSIZE EQU 512
RAMDRVMAXBANK EQU (RAMDRVSIZE * 1024)/UROMSIZE ; Maximum Bank number for the RAM drive.
;ROMBK1: EQU 01016H ; CURRENT MROM BANK
;ROMBK2: EQU 01017H ; CURRENT USERROM BANK
;WRKROMBK1: EQU 01018H ; WORKING MROM BANK
;WRKROMBK2: EQU 01019H ; WORKING USERROM BANK
;-----------------------------------------------
; ROM Banks, 0-7 are reserved for alternative
; Monitor versions, CPM and RFS
; code in MROM bank,
; 0-7 are reserved for RFS code in
; the User ROM bank.
; 8-15 are reserved for CPM code in
; the User ROM bank.
;-----------------------------------------------
MROMPAGES EQU 8
USRROMPAGES EQU 12 ; Monitor ROM : User ROM
ROMBANK0 EQU 0 ; MROM SA1510 40 Char : RFS Bank 0 - Main RFS Entry point and functions.
ROMBANK1 EQU 1 ; MROM SA1510 80 Char : RFS Bank 1 - Floppy disk controller and utilities.
ROMBANK2 EQU 2 ; CPM 2.2 CBIOS : RFS Bank 2 - SD Card controller and utilities.
ROMBANK3 EQU 3 ; RFS Utilities : RFS Bank 3 - Cmdline tools (Memory, Printer, Help)
ROMBANK4 EQU 4 ; Free : RFS Bank 4 - CMT Utilities.
ROMBANK5 EQU 5 ; Free : RFS Bank 5
ROMBANK6 EQU 6 ; Free : RFS Bank 6
ROMBANK7 EQU 7 ; Free : RFS Bank 7 - Memory and timer test utilities.
ROMBANK8 EQU 8 ; : CBIOS Bank 1 - Utilities
ROMBANK9 EQU 9 ; : CBIOS Bank 2 - Screen / ANSI Terminal
ROMBANK10 EQU 10 ; : CBIOS Bank 3 - SD Card
ROMBANK11 EQU 11 ; : CBIOS Bank 4 - Floppy disk controller.
OBJCD EQU 001h
;-----------------------------------------------
; IO Registers
;-----------------------------------------------
FDC EQU 0D8h ; MB8866 IO Region 0D8h - 0DBh
FDC_CR EQU FDC + 000h ; Command Register
FDC_STR EQU FDC + 000h ; Status Register
FDC_TR EQU FDC + 001h ; Track Register
FDC_SCR EQU FDC + 002h ; Sector Register
FDC_DR EQU FDC + 003h ; Data Register
FDC_MOTOR EQU FDC + 004h ; DS[0-3] and Motor control. 4 drives DS= BIT 0 -> Bit 2 = Drive number, 2=1,1=0,0=0 DS0, 2=1,1=0,0=1 DS1 etc
; bit 7 = 1 MOTOR ON LOW (Active)
FDC_SIDE EQU FDC + 005h ; Side select, Bit 0 when set = SIDE SELECT LOW
;-----------------------------------------------
; Common character definitions.
;-----------------------------------------------
SCROLL EQU 001H ;Set scroll direction UP.
BELL EQU 007H
SPACE EQU 020H
TAB EQU 009H ;TAB ACROSS (8 SPACES FOR SD-BOARD)
CR EQU 00DH
LF EQU 00AH
FF EQU 00CH
CS EQU 0CH ; Clear screen
DELETE EQU 07FH
BACKS EQU 008H
SOH EQU 1 ; For XModem etc.
EOT EQU 4
ACK EQU 6
NAK EQU 015H
NUL EQU 000H
NULL EQU 000H
CTRL_A EQU 001H
CTRL_B EQU 002H
CTRL_C EQU 003H
CTRL_D EQU 004H
CTRL_E EQU 005H
CTRL_F EQU 006H
CTRL_G EQU 007H
CTRL_H EQU 008H
CTRL_I EQU 009H
CTRL_J EQU 00AH
CTRL_K EQU 00BH
CTRL_L EQU 00CH
CTRL_M EQU 00DH
CTRL_N EQU 00EH
CTRL_O EQU 00FH
CTRL_P EQU 010H
CTRL_Q EQU 011H
CTRL_R EQU 012H
CTRL_S EQU 013H
CTRL_T EQU 014H
CTRL_U EQU 015H
CTRL_V EQU 016H
CTRL_W EQU 017H
CTRL_X EQU 018H
CTRL_Y EQU 019H
CTRL_Z EQU 01AH
ESC EQU 01BH
CTRL_SLASH EQU 01CH
CTRL_LB EQU 01BH
CTRL_RB EQU 01DH
CTRL_CAPPA EQU 01EH
CTRL_UNDSCR EQU 01FH
CTRL_AT EQU 000H
NOKEY EQU 0F0H
CURSRIGHT EQU 0F1H
CURSLEFT EQU 0F2H
CURSUP EQU 0F3H
CURSDOWN EQU 0F4H
DBLZERO EQU 0F5H
INSERT EQU 0F6H
CLRKEY EQU 0F7H
HOMEKEY EQU 0F8H
BREAKKEY EQU 0FBH
GRAPHKEY EQU 0FCH
ALPHAKEY EQU 0FDH
; MMC/SD command (SPI mode)
CMD0 EQU 64 + 0 ; GO_IDLE_STATE
CMD1 EQU 64 + 1 ; SEND_OP_COND
ACMD41 EQU 0x40+41 ; SEND_OP_COND (SDC)
CMD8 EQU 64 + 8 ; SEND_IF_COND
CMD9 EQU 64 + 9 ; SEND_CSD
CMD10 EQU 64 + 10 ; SEND_CID
CMD12 EQU 64 + 12 ; STOP_TRANSMISSION
CMD13 EQU 64 + 13 ; SEND_STATUS
ACMD13 EQU 0x40+13 ; SD_STATUS (SDC)
CMD16 EQU 64 + 16 ; SET_BLOCKLEN
CMD17 EQU 64 + 17 ; READ_SINGLE_BLOCK
CMD18 EQU 64 + 18 ; READ_MULTIPLE_BLOCK
CMD23 EQU 64 + 23 ; SET_BLOCK_COUNT
ACMD23 EQU 0x40+23 ; SET_WR_BLK_ERASE_COUNT (SDC)
CMD24 EQU 64 + 24 ; WRITE_BLOCK
CMD25 EQU 64 + 25 ; WRITE_MULTIPLE_BLOCK
CMD32 EQU 64 + 32 ; ERASE_ER_BLK_START
CMD33 EQU 64 + 33 ; ERASE_ER_BLK_END
CMD38 EQU 64 + 38 ; ERASE
CMD55 EQU 64 + 55 ; APP_CMD
CMD58 EQU 64 + 58 ; READ_OCR
; Card type flags (CardType)
CT_MMC EQU 001H ; MMC ver 3
CT_SD1 EQU 002H ; SD ver 1
CT_SD2 EQU 004H ; SD ver 2
CT_SDC EQU CT_SD1|CT_SD2 ; SD
CT_BLOCK EQU 008H ; Block addressing
; Disk types.
DSKTYP_FDC EQU 0 ; Type of disk is a Floppy disk and handled by the FDC controller.
DSKTYP_ROM EQU 1 ; Type of disk is a ROM and handled by the ROM methods.
DSKTYP_SDC EQU 2 ; Type of disk is an SD Card and handled by the SD Card methods.
DSKTYP_RAM EQU 3 ; Type of disk is a RAM Drive handled by ROM/RAM methods.
;
; Rom Filing System constants.
;
RFS_DIRENT EQU 256 ; Directory entries in the RFS directory.
RFS_DIRENTSZ EQU 32 ; Size of a directory entry.
RFS_DIRSIZE EQU RFS_DIRENT * RFS_DIRENTSZ ; Total size of the directory.
RFS_BLOCKSZ EQU 65536 ; Size of a file block per directory entry.
RFS_DRIVES EQU 10 ; Number of RFS Drives (Images).
RFS_IMGSZ EQU RFS_DIRSIZE + (RFS_DIRENT * RFS_BLOCKSZ) ; Total size of the RFS image.
RFS_END_ADDR EQU 010000000H ; End of RFS/Start of CP/M.
;
; CPM constants
;
CPM_SD_SEC EQU 32
CPM_SD_TRK EQU 1024
CPM_SD_IMGSZ EQU CPM_SD_TRK * CPM_SD_SEC * SD_SECSIZE
;
; SD Card constants.
;
SD_SECSIZE EQU 512 ; Default size of an SD Sector
SD_SECPTRK EQU CPM_SD_SEC ; Sectors of SD_SECSIZE per virtual track.
SD_TRACKS EQU CPM_SD_TRK ; Number of virtual tracks per disk image.
SD_RETRIES EQU 00100H ; Number of retries before giving up.
;-----------------------------------------------
; BIOS WORK AREA (MZ80A)
;-----------------------------------------------
ORG CBIOSDATA
; Keyboard processing, ensure starts where LSB = 0.
VARSTART EQU $ ; Start of variables.
KEYBUF: DS virtual KEYBUFSIZE ; Interrupt driven keyboard buffer.
KEYCOUNT: DS virtual 1
KEYWRITE: DS virtual 2 ; Pointer into the buffer where the next character should be placed.
KEYREAD: DS virtual 2 ; Pointer into the buffer where the next character can be read.
KEYLAST: DS virtual 1 ; KEY LAST VALUE
KEYRPT: DS virtual 1 ; KEY REPEAT COUNTER
USRBANKSAV: DS virtual 1 ; Save user bank number when calling another user bank.
HLSAVE: DS virtual 2 ; Space to save HL register when manipulating stack.
ROMCTL DS virtual 1 ; Rom Paging control register contents.
;
SPV:
IBUFE: ; TAPE BUFFER (128 BYTES)
ATRB: DS virtual 1 ; ATTRIBUTE
NAME: DS virtual 17 ; FILE NAME
SIZE: DS virtual 2 ; BYTESIZE
DTADR: DS virtual 2 ; DATA ADDRESS
EXADR: DS virtual 2 ; EXECUTION ADDRESS
COMNT: DS virtual 92 ; Comment / code area of CMT header.
SWPW: DS virtual 10 ; SWEEP WORK
KDATW: DS virtual 2 ; KEY WORK
KANAF: DS virtual 1 ; KANA FLAG (01=GRAPHIC MODE)
DSPXY: DS virtual 2 ; DISPLAY COORDINATES
;DSPXYLST: DS virtual 2 ; Last known cursor position, to compare with DSPXY to detect changes.
MANG: DS virtual 6 ; COLUMN MANAGEMENT
MANGE: DS virtual 1 ; COLUMN MANAGEMENT END
PBIAS: DS virtual 1 ; PAGE BIAS
ROLTOP: DS virtual 1 ; ROLL TOP BIAS
MGPNT: DS virtual 1 ; COLUMN MANAG. POINTER
PAGETP: DS virtual 2 ; PAGE TOP
ROLEND: DS virtual 1 ; ROLL END
DS virtual 14 ; BIAS
FLASH: DS virtual 1 ; FLASHING DATA
SFTLK: DS virtual 1 ; SHIFT LOCK
REVFLG: DS virtual 1 ; REVERSE FLAG
FLSDT: DS virtual 1 ; CURSOR DATA
STRGF: DS virtual 1 ; STRING FLAG
DPRNT: DS virtual 1 ; TAB COUNTER
FLASHCTL: DS virtual 1 ; CURSOR FLASH CONTROL. BIT 0 = Cursor On/Off, BIT 1 = Cursor displayed.
DSPXYADDR: DS virtual 2 ; Address of last known position.
;AMPM: DS virtual 1 ; AMPM DATA
;TIMFG: DS virtual 1 ; TIME FLAG
SWRK: DS virtual 1 ; KEY SOUND FLAG
TEMPW: DS virtual 1 ; TEMPO WORK
ONTYO: DS virtual 1 ; ONTYO WORK
OCTV: DS virtual 1 ; OCTAVE WORK
RATIO: DS virtual 2 ; ONPU RATIO
;BUFER: DS virtual 81 ; GET LINE BUFFER
;KEYBUF: DS virtual 1 ; KEY BUFFER
DRVAVAIL DS virtual 1 ; Flag to indicate which drive controllers are available. Bit 2 = SD, Bit 1 = ROM, Bit 0 = FDC
TIMESEC DS virtual 6 ; RTC 48bit TIME IN MILLISECONDS
FDCCMD DS virtual 1 ; LAST FDC COMMAND SENT TO CONTROLLER.
MOTON DS virtual 1 ; MOTOR ON = 1, OFF = 0
INVFDCDATA: DS virtual 1 ; INVERT DATA COMING FROM FDC, 1 = INVERT, 0 = AS IS
TRK0FD1 DS virtual 1 ; FD 1 IS AT TRACK 0 = BIT 0 set
TRK0FD2 DS virtual 1 ; FD 2 IS AT TRACK 0 = BIT 0 set
TRK0FD3 DS virtual 1 ; FD 3 IS AT TRACK 0 = BIT 0 set
TRK0FD4 DS virtual 1 ; FD 4 IS AT TRACK 0 = BIT 0 set
RETRIES DS virtual 2 ; DATA READ RETRIES
TMPADR DS virtual 2 ; TEMPORARY ADDRESS STORAGE
TMPSIZE DS virtual 2 ; TEMPORARY SIZE
TMPCNT DS virtual 2 ; TEMPORARY COUNTER
;
CPMROMLOC: DS virtual 2 ; Upper Byte = ROM Bank, Lower Byte = Page of CPM Image.
;CPMROMDRV0: DS virtual 2 ; Upper Byte = ROM Bank, Lower Byte = Page of CPM Rom Drive Image Disk 0.
;CPMROMDRV1: DS virtual 2 ; Upper Byte = ROM Bank, Lower Byte = Page of CPM Rom Drive Image Disk 1.
NDISKS: DS virtual 1 ; Dynamically calculated number of disks on boot.
DISKMAP: DS virtual MAXDISKS ; Disk map of CPM logical to physical controller disk.
FDCDISK: DS virtual 1 ; Physical disk number.
SECPERTRK: DS virtual 1 ; Sectors per track for 1 head.
SECPERHEAD: DS virtual 1 ; Sectors per head.
SECTORCNT: DS virtual 1 ; Sector size as a count of how many sectors make 512 bytes.
DISKTYPE: DS virtual 1 ; Disk type of current selection.
MTROFFTIMER: DS virtual 1 ; Second down counter for FDC motor off.
;
SEKDSK: DS virtual 1 ; Seek disk number
SEKTRK: DS virtual 2 ; Seek disk track
SEKSEC: DS virtual 1 ; Seek sector number
SEKHST: DS virtual 1 ; Seek sector host
;
HSTDSK: DS virtual 1 ; Host disk number
HSTTRK: DS virtual 2 ; Host track number
HSTSEC: DS virtual 1 ; Host sector number
HSTWRT: DS virtual 1 ; Host write flag
HSTACT: DS virtual 1 ;
;
UNACNT: DS virtual 1 ; Unalloc rec cnt
UNADSK: DS virtual 1 ; Last unalloc disk
UNATRK: DS virtual 2 ; Last unalloc track
UNASEC: DS virtual 1 ; Last unalloc sector
;
ERFLAG: DS virtual 1 ; Error number, 0 = no error.
READOP: DS virtual 1 ; If read operation then 1, else 0 for write.
RSFLAG: DS virtual 1 ; Read sector flag.
WRTYPE: DS virtual 1 ; Write operation type.
TRACKNO: DS virtual 2 ; Host controller track number
SECTORNO: DS virtual 1 ; Host controller sector number
DMAADDR: DS virtual 2 ; Last DMA address
HSTBUF: DS virtual 512 ; Host buffer for disk sector storage
HSTBUFE:
SDVER: DS virtual 1 ; SD Card version.
SDCAP: DS virtual 1 ; SD Card capabilities..
SDSTARTSEC DS virtual 4 ; Starting sector of data to read/write from/to SD card.
SDBUF: DS virtual 11 ; SD Card command fram buffer for the command and response storage.
CURSORPSAV DS virtual 2 ; Cursor save position;default 0,0
HAVELOADED DS virtual 1 ; To show that a value has been put in for Ansi emualtor.
ANSIFIRST DS virtual 1 ; Holds first character of Ansi sequence
NUMBERBUF DS virtual 20 ; Buffer for numbers in Ansi
NUMBERPOS DS virtual 2 ; Address within buffer
CHARACTERNO DS virtual 1 ; Byte within Ansi sequence. 0=first,255=other
CURSORCOUNT DS virtual 1 ; 1/50ths of a second since last change
FONTSET DS virtual 1 ; Ansi font setup.
JSW_FF DS virtual 1 ; Byte value to turn on/off FF routine
JSW_LF DS virtual 1 ; Byte value to turn on/off LF routine
CHARACTER DS virtual 1 ; To buffer character to be printed.
CURSORPOS DS virtual 2 ; Cursor position, default 0,0.
BOLDMODE DS virtual 1
HIBRITEMODE DS virtual 1 ; 0 means on, &C9 means off
UNDERSCMODE DS virtual 1
ITALICMODE DS virtual 1
INVMODE DS virtual 1
CHGCURSMODE DS virtual 1
ANSIMODE DS virtual 1 ; 1 = on, 0 = off
COLOUR EQU 0
SPSAVE: DS virtual 2 ; CPM Stack save.
SPISRSAVE: DS virtual 2
; Stack space for the CBIOS.
MSGSTRBUF: DS virtual 128 ; Lower end of the stack space is for interbank message printing, ie.space for a string to print.
BIOSSTACK EQU $
; Stack space for the Interrupt Service Routine.
DS virtual 16 ; Max 8 stack pushes.
ISRSTACK EQU $
DBGSTACKP: DS virtual 2
DS virtual 36
DBGSTACK: EQU $
VAREND EQU $ ; End of variables

34
asm/include/macros.asm Normal file
View File

@@ -0,0 +1,34 @@
; the following is only to get the original length of 2048 bytes
ALIGN: MACRO ?boundary
DS ?boundary - 1 - ($ + ?boundary - 1) % ?boundary, 0FFh
ENDM
; the following is only to get the original length of 2048 bytes
ALIGN_NOPS:MACRO ?boundary
DS ?boundary - 1 - ($ + ?boundary - 1) % ?boundary, 000h
ENDM
;
; Pads up to a certain address.
; Gives an error message if that address is already exceeded.
;
PAD: MACRO ?address
IF $ > ?address
ERROR "Alignment exceeds %s"; % ?address
ENDIF
ds ?address - $
ENDM
;
; Pads up to the next multiple of the specified address.
;
;ALIGN: MACRO ?boundary
; ds ?boundary - 1 - ($ + ?boundary - 1) % ?boundary
; ENDM
;
; Pads to ensure a section of the given size does not cross a 100H boundary.
;
ALIGN_FIT8: MACRO ?size
ds (($ + ?size - 1) >> 8) != ($ >> 8) && (100H - ($ & 0FFH)) || 0
ENDM

View File

@@ -0,0 +1 @@
BUILD_VERSION EQU 2

View File

@@ -0,0 +1,473 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: MSBASIC_Definitions.asm
;- Created: June 2020
;- Author(s): Philip Smart
;- Description: Sharp MZ series CPM v2.23
;- Definitions for the Sharp MZ80A CPM v2.23 OS used in the RFS
;-
;- Credits:
;- Copyright: (c) 2019-23 Philip Smart <philip.smart@net2net.org>
;-
;- History: Jan 2020 - Initial version.
; May 2020 - Advent of the new RFS PCB v2.0, quite a few changes to accommodate the
; additional and different hardware. The SPI is now onboard the PCB and
; not using the printer interface card.
; Jun 2020 - Copied and strpped from TZFS for BASIC.
; Mar 2021 - Updates to run on v2.1 RFS board and provide SD card CLOAD/CSAVE and DIR
; along with bug fixes.
;
;--------------------------------------------------------------------------------------------------------
;- 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/>.
;--------------------------------------------------------------------------------------------------------
;-----------------------------------------------
; Features.
;-----------------------------------------------
;-----------------------------------------------
;-----------------------------------------------
; Configurable settings.
;-----------------------------------------------
; Build options. Set just one to '1' the rest to '0'.
; NB: As there are now 4 versions and 1 or more need to be built, ie. MZ-80A and RFS version for RFS, a flag is set in the file
; BASIC_build.asm which configures the equates below for the correct build.
IF BUILD_VERSION = 0
BUILD_MZ80A EQU 1 ; Build for the standard Sharp MZ80A, no lower memory. Manually change MAXMEM above.
BUILD_RFS EQU 0 ; Build for standard RFS with SD enhancements.
BUILD_RFSTZ EQU 0 ; Build for RFS where the tranZPUter board is available without the K64F and running under RFS.
BUILD_TZFS EQU 0 ; Build for TZFS where extended memory is available.
BUILD_80C EQU 0
INCLUDE_ANSITERM EQU 1 ; Include the Ansi terminal emulation processor in the build.
ENDIF
IF BUILD_VERSION = 1
BUILD_MZ80A EQU 0
BUILD_RFS EQU 1
BUILD_RFSTZ EQU 0
BUILD_TZFS EQU 0
BUILD_80C EQU 1
INCLUDE_ANSITERM EQU 1 ; Include the Ansi terminal emulation processor in the build.
ENDIF
IF BUILD_VERSION = 2
BUILD_MZ80A EQU 0
BUILD_RFS EQU 1
BUILD_RFSTZ EQU 0
BUILD_TZFS EQU 0
BUILD_80C EQU 0
INCLUDE_ANSITERM EQU 1 ; Include the Ansi terminal emulation processor in the build.
ENDIF
IF BUILD_VERSION = 3
BUILD_MZ80A EQU 0
BUILD_RFS EQU 0
BUILD_RFSTZ EQU 1
BUILD_TZFS EQU 0
BUILD_80C EQU 1
INCLUDE_ANSITERM EQU 1 ; Include the Ansi terminal emulation processor in the build.
ENDIF
IF BUILD_VERSION = 4
BUILD_MZ80A EQU 0
BUILD_RFS EQU 0
BUILD_RFSTZ EQU 0
BUILD_TZFS EQU 1
BUILD_80C EQU 1
INCLUDE_ANSITERM EQU 1 ; Include the Ansi terminal emulation processor in the build.
ENDIF
IF BUILD_80C = 1
COLW: EQU 80 ; Width of the display screen (ie. columns).
ELSE
COLW: EQU 40 ; Width of the display screen (ie. columns).
ENDIF
TMRTICKINTV EQU 5 ; Number of 0.010mSec ticks per interrupt, ie. resolution of RTC.
ROW: EQU 25 ; Number of rows on display screen.
SCRNSZ: EQU COLW * ROW ; Total size, in bytes, of the screen display area.
SCRLW: EQU COLW / 8 ; Number of 8 byte regions in a line for hardware scroll.
; BIOS equates
KEYBUFSIZE EQU 64 ; Ensure this is a power of 2, max size 256.
IF BUILD_MZ80A = 1
MAXMEM EQU 0CFFFH ; Top of RAM on a standard Sharp MZ80A.
ENDIF
IF BUILD_RFS = 1
MAXMEM EQU 0CFFFH - TZSVCSECSIZE ; Top of RAM on a standard RFS equipped Sharp MZ80A. Top 512 bytes used by RFS SD sector buffer.
ENDIF
IF BUILD_TZFS+BUILD_RFSTZ > 0
MAXMEM EQU 10000H - TZSVCSIZE ; Top of RAM on the tranZPUter
ENDIF
; Tape load/save modes. Used as a flag to enable common code.
TAPELOAD EQU 1
CTAPELOAD EQU 2
TAPESAVE EQU 3
CTAPESAVE EQU 4
; Debugging
ENADEBUG EQU 0 ; Enable debugging logic, 1 = enable, 0 = disable
;-----------------------------------------------
; CMT Object types.
;-----------------------------------------------
ATR_OBJ EQU 1
ATR_BASIC_PROG EQU 2
ATR_BASIC_DATA EQU 3
ATR_SRC_FILE EQU 4
ATR_RELOC_FILE EQU 5
ATR_BASIC_MSCAS EQU 07EH
ATR_BASIC_MSTXT EQU 07FH
ATR_PASCAL_PROG EQU 0A0H
ATR_PASCAL_DATA EQU 0A1H
CMTATRB EQU 010F0H
CMTNAME EQU 010F1H
;-------------------------------------------------------
; Function entry points in the standard SA-1510 Monitor.
;-------------------------------------------------------
QWRI EQU 00021h
QWRD EQU 00024h
QRDI EQU 00027h
QRDD EQU 0002Ah
QVRFY EQU 0002Dh
;-------------------------------------------------------
; Function entry points in the RFS ROM.
;-------------------------------------------------------
CMT_RDINF EQU 0E886H ; UROMADDR+86H - Tape/SD intercept handler - Read Header
CMT_RDDATA EQU 0E889H ; UROMADDR+89H - Tape/SD intercept handler - Read Data
CMT_WRINF EQU 0E88CH ; UROMADDR+80H - Tape/SD intercept handler - Write Header
CMT_WRDATA EQU 0E88FH ; UROMADDR+8FH - Tape/SD intercept handler - Write Data
CMT_VERIFY EQU 0E892H ; UROMADDR+92H - Tape/SD intercept handler - Verify Data
CMT_DIR EQU 0E895H ; UROMADDR+95H - SD directory command.
CNV_ATOS EQU 0E898H ; UROMADDR+98H - Convert an ASCII string into Sharp ASCII
;-----------------------------------------------
; BASIC ERROR CODE VALUES
;-----------------------------------------------
NF EQU 00H ; NEXT without FOR
SN EQU 02H ; Syntax error
RG EQU 04H ; RETURN without GOSUB
OD EQU 06H ; Out of DATA
FC EQU 08H ; Function call error
OV EQU 0AH ; Overflow
OM EQU 0CH ; Out of memory
UL EQU 0EH ; Undefined line number
BS EQU 10H ; Bad subscript
DDA EQU 12H ; Re-DIMensioned array
DZ EQU 14H ; Division by zero (/0)
ID EQU 16H ; Illegal direct
TM EQU 18H ; Type miss-match
OS EQU 1AH ; Out of string space
LS EQU 1CH ; String too long
ST EQU 1EH ; String formula too complex
CN EQU 20H ; Can't CONTinue
UF EQU 22H ; UnDEFined FN function
MO EQU 24H ; Missing operand
HX EQU 26H ; HEX error
BN EQU 28H ; BIN error
BV EQU 2AH ; Bad Value error
IO EQU 2CH ; IO error
;-----------------------------------------------
; Memory mapped ports in hardware.
;-----------------------------------------------
SCRN: EQU 0D000H
ARAM: EQU 0D800H
DSPCTL: EQU 0DFFFH ; Screen 40/80 select register (bit 7)
KEYPA: EQU 0E000h
KEYPB: EQU 0E001h
KEYPC: EQU 0E002h
KEYPF: EQU 0E003h
CSTR: EQU 0E002h
CSTPT: EQU 0E003h
CONT0: EQU 0E004h
CONT1: EQU 0E005h
CONT2: EQU 0E006h
CONTF: EQU 0E007h
SUNDG: EQU 0E008h
TEMP: EQU 0E008h
MEMSW: EQU 0E00CH
MEMSWR: EQU 0E010H
INVDSP: EQU 0E014H
NRMDSP: EQU 0E015H
SCLDSP: EQU 0E200H
SCLBASE: EQU 0E2H
BNKCTRLRST: EQU 0EFF8H ; Bank control reset, returns all registers to power up default.
BNKCTRLDIS: EQU 0EFF9H ; Disable bank control registers by resetting the coded latch.
HWSPIDATA: EQU 0EFFBH ; Hardware SPI Data register (read/write).
HWSPISTART: EQU 0EFFCH ; Start an SPI transfer.
BNKSELMROM: EQU 0EFFDh ; Select RFS Bank1 (MROM)
BNKSELUSER: EQU 0EFFEh ; Select RFS Bank2 (User ROM)
BNKCTRL: EQU 0EFFFH ; Bank Control register (read/write).
;-----------------------------------------------
; IO Registers
;-----------------------------------------------
FDC EQU 0D8h ; MB8866 IO Region 0D8h - 0DBh
FDC_CR EQU FDC + 000h ; Command Register
FDC_STR EQU FDC + 000h ; Status Register
FDC_TR EQU FDC + 001h ; Track Register
FDC_SCR EQU FDC + 002h ; Sector Register
FDC_DR EQU FDC + 003h ; Data Register
FDC_MOTOR EQU FDC + 004h ; DS[0-3] and Motor control. 4 drives DS= BIT 0 -> Bit 2 = Drive number, 2=1,1=0,0=0 DS0, 2=1,1=0,0=1 DS1 etc
; bit 7 = 1 MOTOR ON LOW (Active)
FDC_SIDE EQU FDC + 005h ; Side select, Bit 0 when set = SIDE SELECT LOW
;-----------------------------------------------
; Common character definitions.
;-----------------------------------------------
SCROLL EQU 001H ;Set scroll direction UP.
BELL EQU 007H
SPACE EQU 020H
TAB EQU 009H ;TAB ACROSS (8 SPACES FOR SD-BOARD)
CR EQU 00DH
LF EQU 00AH
FF EQU 00CH
CS EQU 0CH ; Clear screen
DELETE EQU 07FH
BACKS EQU 008H
SOH EQU 1 ; For XModem etc.
EOT EQU 4
ACK EQU 6
NAK EQU 015H
NUL EQU 000H
;NULL EQU 000H
CTRL_A EQU 001H
CTRL_B EQU 002H
CTRL_C EQU 003H
CTRL_D EQU 004H
CTRL_E EQU 005H
CTRL_F EQU 006H
CTRL_G EQU 007H
CTRL_H EQU 008H
CTRL_I EQU 009H
CTRL_J EQU 00AH
CTRL_K EQU 00BH
CTRL_L EQU 00CH
CTRL_M EQU 00DH
CTRL_N EQU 00EH
CTRL_O EQU 00FH
CTRL_P EQU 010H
CTRL_Q EQU 011H
CTRL_R EQU 012H
CTRL_S EQU 013H
CTRL_T EQU 014H
CTRL_U EQU 015H
CTRL_V EQU 016H
CTRL_W EQU 017H
CTRL_X EQU 018H
CTRL_Y EQU 019H
CTRL_Z EQU 01AH
ESC EQU 01BH
CTRL_SLASH EQU 01CH
CTRL_LB EQU 01BH
CTRL_RB EQU 01DH
CTRL_CAPPA EQU 01EH
CTRL_UNDSCR EQU 01FH
CTRL_AT EQU 000H
NOKEY EQU 0F0H
CURSRIGHT EQU 0F1H
CURSLEFT EQU 0F2H
CURSUP EQU 0F3H
CURSDOWN EQU 0F4H
DBLZERO EQU 0F5H
INSERT EQU 0F6H
CLRKEY EQU 0F7H
HOMEKEY EQU 0F8H
BREAKKEY EQU 0FBH
GRAPHKEY EQU 0FCH
ALPHAKEY EQU 0FDH
;-----------------------------------------------
; Rom File System variable addresses.
;-----------------------------------------------
; Starting 1000H - Generally unused bytes not cleared by the monitor.
ROMBK1: EQU 01016H ; CURRENT MROM BANK
ROMBK2: EQU 01017H ; CURRENT USERROM BANK
WRKROMBK1: EQU 01018H ; WORKING MROM BANK
WRKROMBK2: EQU 01019H ; WORKING USERROM BANK
ROMCTL: EQU 0101AH ; Current Bank control register setting.
SCRNMODE: EQU 0101BH ; Mode of screen, 0 = 40 char, 1 = 80 char.
TMPADR: EQU 0101CH ; TEMPORARY ADDRESS STORAGE
TMPSIZE: EQU 0101EH ; TEMPORARY SIZE
TMPCNT: EQU 01020H ; TEMPORARY COUNTER
TMPLINECNT: EQU 01022H ; Temporary counter for displayed lines.
TMPSTACKP: EQU 01024H ; Temporary stack pointer save.
SDVER: EQU 01026H
SDCAP: EQU 01027H
SDDRIVENO EQU 01028H ; RFS SDCFS Active Drive Number
CMTFILENO EQU 01029H ; Next Sequential file number to read when file request given without name.
TZPU: EQU 0102AH ; Tranzputer present flag (0 = not present, > 0 = present and version number).
; Variables sharing the BUFER buffer, normally the BUFER is only used to get keyboard input and so long as data in BUFER is processed
; before calling the CMT/SD commands and not inbetween there shouldnt be any issue. Also the space used is at the top end of the buffer which is not used so often.
; This frees up memory needed by the CMT and SD card.
SECTORBUF: EQU 0CE00H ; Working buffer to place an SD card sector.
SDSTARTSEC EQU BUFER+50+0 ; Starting sector of data to read/write from/to SD card.
SDLOADADDR EQU BUFER+50+4 ; Address to read/write data from/to SD card.
SDLOADSIZE EQU BUFER+50+6 ; Total remaining byte count data to read/write from/to SD card.
SDAUTOEXEC EQU BUFER+50+8 ; Flag to indicate if a loaded image should be executed (=0xFF)
SDBUF: EQU BUFER+50+9 ; SD Card command fram buffer for the command and response storage.
DIRSECBUF: EQU BUFER+50+20 ; Directory sector in cache.
DUMPADDR: EQU BUFER+50+22 ; Address used by the D(ump) command so that calls without parameters go onto the next block.
CMTLOLOAD: EQU BUFER+50+24 ; Flag to indicate that a tape program is loaded into hi memory then shifted to low memory after ROM pageout.
CMTCOPY: EQU BUFER+50+25 ; Flag to indicate that a CMT copy operation is taking place.
CMTAUTOEXEC: EQU BUFER+50+26 ; Auto execution flag, run CMT program when loaded if flag clear.
DTADRSTORE: EQU BUFER+50+27 ; Backup for load address if actual load shifts to lo memory or to 0x1200 for copy.
SDCOPY: EQU BUFER+50+29 ; Flag to indicate an SD copy is taking place, either CMT->SD or SD->CMT.
RESULT: EQU BUFER+50+30 ; Result variable needed for interbank calls when a result is needed.
;--------------------------------------------------
; RFS ROM Banks, 0-7 are reserved for alternative
; Monitor versions, CPM and RFS
; code in MROM bank,
; 0-7 are reserved for RFS code in
; the User ROM bank.
; 8-15 are reserved for CPM code in
; the User ROM bank.
;--------------------------------------------------
MROMPAGES EQU 8
USRROMPAGES EQU 12 ; Monitor ROM : User ROM
ROMBANK0 EQU 0 ; MROM SA1510 40 Char : RFS Bank 0 - Main RFS Entry point and functions.
ROMBANK1 EQU 1 ; MROM SA1510 80 Char : RFS Bank 1 - Floppy disk controller and utilities.
ROMBANK2 EQU 2 ; CPM 2.2 CBIOS : RFS Bank 2 - SD Card controller and utilities.
ROMBANK3 EQU 3 ; RFS Utilities : RFS Bank 3 - Cmdline tools (Memory, Printer, Help)
ROMBANK4 EQU 4 ; MZ700 1Z-013A 40C : RFS Bank 4 - CMT Utilities.
ROMBANK5 EQU 5 ; MZ700-1Z-013A 80C : RFS Bank 5
ROMBANK6 EQU 6 ; MZ-80B IPL : RFS Bank 6
ROMBANK7 EQU 7 ; Free : RFS Bank 7 - Memory and timer test utilities.
ROMBANK8 EQU 8 ; : CBIOS Bank 1 - Utilities
ROMBANK9 EQU 9 ; : CBIOS Bank 2 - Screen / ANSI Terminal
ROMBANK10 EQU 10 ; : CBIOS Bank 3 - SD Card
ROMBANK11 EQU 11 ; : CBIOS Bank 4 - Floppy disk controller.
;-----------------------------------------------
; IO ports in hardware and values.
;-----------------------------------------------
MMCFG EQU 060H ; Memory management configuration latch.
SETXMHZ EQU 062H ; Select the alternate clock frequency.
SET2MHZ EQU 064H ; Select the system 2MHz clock frequency.
CLKSELRD EQU 066H ; Read clock selected setting, 0 = 2MHz, 1 = XMHz
SVCREQ EQU 068H ; I/O Processor service request.
;-----------------------------------------------
; tranZPUter SW Memory Management modes
;-----------------------------------------------
TZMM_ORIG EQU 000H ; Original Sharp MZ80A mode, no tranZPUter features are selected except the I/O control registers (default: 0x60-063).
TZMM_BOOT EQU 001H ; Original mode but E800-EFFF is mapped to tranZPUter RAM so TZFS can be booted.
TZMM_TZFS EQU 002H ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-FFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected.
TZMM_TZFS2 EQU 003H ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 1.
TZMM_TZFS3 EQU 004H ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 2.
TZMM_TZFS4 EQU 005H ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 3.
TZMM_CPM EQU 006H ; CPM main memory configuration, all memory on the tranZPUter board, 64K block 4 selected. Special case for F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard.
TZMM_CPM2 EQU 007H ; CPM main memory configuration, F000-FFFF are on the tranZPUter board in block 4, 0040-CFFF and E800-EFFF are in block 5, mainboard for D000-DFFF (video), E000-E800 (Memory control) selected.
; Special case for 0000:003F (interrupt vectors) which resides in block 4, F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard.
TZMM_COMPAT EQU 008H ; Original mode but with main DRAM in Bank 0 to allow bootstrapping of programs from other machines such as the MZ700.
TZMM_HOSTACCESS EQU 009H ; Mode to allow code running in Bank 0, address E800:FFFF to access host memory. Monitor ROM 0000-0FFF and Main DRAM 0x1000-0xD000, video and memory mapped I/O are on the host machine, User/Floppy ROM E800-FFFF are in tranZPUter memory.
TZMM_MZ700_0 EQU 00AH ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the mainboard.
TZMM_MZ700_1 EQU 00BH ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
TZMM_MZ700_2 EQU 00CH ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
TZMM_MZ700_3 EQU 00DH ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
TZMM_MZ700_4 EQU 00EH ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
TZMM_MZ800 EQU 00FH ; MZ800 Mode - Tracks original hardware mode offering MZ700/MZ800 configurations.
TZMM_FPGA EQU 015H ; Open up access for the K64F to the FPGA resources such as memory. All other access to RAM or mainboard is blocked.
TZMM_TZPUM EQU 016H ; Everything in on mainboard, no access to tranZPUter memory.
TZMM_TZPU EQU 017H ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
TZMM_TZPU0 EQU 018H ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
TZMM_TZPU1 EQU 019H ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 1 is selected.
TZMM_TZPU2 EQU 01AH ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 2 is selected.
TZMM_TZPU3 EQU 01BH ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 3 is selected.
TZMM_TZPU4 EQU 01CH ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 4 is selected.
TZMM_TZPU5 EQU 01DH ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 5 is selected.
TZMM_TZPU6 EQU 01EH ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 6 is selected.
TZMM_TZPU7 EQU 01FH ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 7 is selected.
;-----------------------------------------------
; TZ File System Header (MZF)
;-----------------------------------------------
TZFS_ATRB: EQU 00000h ; Code Type, 01 = Machine Code.
TZFS_NAME: EQU 00001h ; Title/Name (17 bytes).
TZFS_SIZE: EQU 00012h ; Size of program.
TZFS_DTADR: EQU 00014h ; Load address of program.
TZFS_EXADR: EQU 00016h ; Exec address of program.
TZFS_COMNT: EQU 00018h ; Comment
TZFS_MZFLEN: EQU 128 ; Length of the MZF header.
TZFS_CMTLEN: EQU 104 ; Length of the comment field
;-----------------------------------------------
; BIOS WORK AREA (MZ80A)
;-----------------------------------------------
; Variables and control structure used by the I/O processor for service calls and requests.
ORG TZSVCMEM
TZSVCMEM: EQU 0FD80H ; Start of a memory structure used to communicate with the K64F I/O processor for services such as disk access.
TZSVCSIZE: EQU 00280H ;
TZSVCDIRSZ: EQU 20 ; Size of the directory/file name.
TZSVCFILESZ: EQU 17 ; Size of a Sharp filename.
TZSVCLONGFILESZ: EQU 31 ; Size of a standard filename.
TZSVCLONGFMTSZ: EQU 20 ; Size of a formatted standard filename for use in directory listings.
TZSVCWILDSZ: EQU 20 ; Size of the wildcard.
TZSVCSECSIZE: EQU 512
TZSVCDIR_ENTSZ: EQU 32 ; Size of a directory entry.
TZSVCWAITIORETRIES: EQU 500 ; Wait retries for IO response.
TZSVCWAITCOUNT: EQU 65535 ; Wait retries for IO request response.
TZSVC_FTYPE_MZF: EQU 0 ; File type being handled is an MZF
TZSVC_FTYPE_CAS: EQU 1 ; File type being handled is an CASsette BASIC script.
TZSVC_FTYPE_BAS: EQU 2 ; File type being handled is an BASic script
TZSVC_FTYPE_ALL: EQU 10 ; Handle any filetype.
TZSVC_FTYPE_ALLFMT: EQU 11 ; Special case for directory listings, all files but truncated and formatted.
TZSVCCMD: DS virtual 1 ; Service command.
TZSVCRESULT: DS virtual 1 ; Service command result.
TZSVCDIRSEC: DS virtual 1 ; Storage for the directory sector number.
TZSVC_FILE_SEC: EQU TZSVCDIRSEC ; Union of the file and directory sector as only one can be used at a time.
TZSVC_TRACK_NO: DS virtual 2 ; Storage for the virtual drive track number.
TZSVC_SECTOR_NO: DS virtual 2 ; Storage for the virtual drive sector number.
TZSVC_FILE_NO: DS virtual 1 ; File number to be opened in a file service command.
TZSVC_FILE_TYPE: DS virtual 1 ; Type of file being accessed to differentiate between Sharp MZF files and other handled files.
TZSVC_LOADADDR: DS virtual 2 ; Dynamic load address for rom/images.
TZSVC_SAVEADDR: EQU TZSVC_LOADADDR ; Union of the load address and the cpu frequency change value, the address of data to be saved.
TZSVC_CPU_FREQ: EQU TZSVC_LOADADDR ; Union of the load address and the save address value, only one can be used at a time.
TZSVC_LOADSIZE: DS virtual 2 ; Size of image to load.
TZSVC_SAVESIZE: EQU TZSVC_LOADSIZE ; Size of image to be saved.
TZSVC_DIRNAME: DS virtual TZSVCDIRSZ ; Service directory/file name.
TZSVC_FILENAME: DS virtual TZSVCFILESZ ; Filename to be opened/created.
TZSVCWILDC: DS virtual TZSVCWILDSZ ; Directory wildcard for file pattern matching.
TZSVCSECTOR: DS virtual TZSVCSECSIZE ; Service command sector - to store directory entries, file sector read or writes.
TZSVC_CMD_READDIR: EQU 01H ; Service command to open a directory and return the first block of entries.
TZSVC_CMD_NEXTDIR: EQU 02H ; Service command to return the next block of an open directory.
TZSVC_CMD_READFILE: EQU 03H ; Service command to open a file and return the first block.
TZSVC_CMD_NEXTREADFILE: EQU 04H ; Service command to return the next block of an open file.
TZSVC_CMD_WRITEFILE: EQU 05H ; Service command to create a file and save the first block.
TZSVC_CMD_NEXTWRITEFILE:EQU 06H ; Service command to write the next block to the open file.
TZSVC_CMD_CLOSE: EQU 07H ; Service command to close any open file or directory.
TZSVC_CMD_LOADFILE: EQU 08H ; Service command to load a file directly into tranZPUter memory.
TZSVC_CMD_SAVEFILE: EQU 09H ; Service command to save a file directly from tranZPUter memory.
TZSVC_CMD_ERASEFILE: EQU 0aH ; Service command to erase a file on the SD card.
TZSVC_CMD_CHANGEDIR: EQU 0bH ; Service command to change the active directory on the SD card.
TZSVC_CMD_LOAD40BIOS: EQU 20H ; Service command requesting that the 40 column version of the SA1510 BIOS is loaded.
TZSVC_CMD_LOAD80BIOS: EQU 21H ; Service command requesting that the 80 column version of the SA1510 BIOS is loaded.
TZSVC_CMD_LOAD700BIOS40:EQU 22H ; Service command requesting that the MZ700 1Z-013A 40 column BIOS is loaded.
TZSVC_CMD_LOAD700BIOS80:EQU 23H ; Service command requesting that the MZ700 1Z-013A 80 column patched BIOS is loaded.
TZSVC_CMD_LOAD80BIPL: EQU 24H ; Service command requesting the MZ-80B IPL is loaded.
TZSVC_CMD_LOADBDOS: EQU 30H ; Service command to reload CPM BDOS+CCP.
TZSVC_CMD_ADDSDDRIVE: EQU 31H ; Service command to attach a CPM disk to a drive number.
TZSVC_CMD_READSDDRIVE: EQU 32H ; Service command to read an attached SD file as a CPM disk drive.
TZSVC_CMD_WRITESDDRIVE: EQU 33H ; Service command to write to a CPM disk drive which is an attached SD file.
TZSVC_CMD_CPU_BASEFREQ EQU 40H ; Service command to switch to the mainboard frequency.
TZSVC_CMD_CPU_ALTFREQ EQU 41H ; Service command to switch to the alternate frequency provided by the K64F.
TZSVC_CMD_CPU_CHGFREQ EQU 42H ; Service command to set the alternate frequency in hertz.
TZSVC_CMD_CPU_SETZ80 EQU 50H ; Service command to switch to the external Z80 hard cpu.
TZSVC_CMD_CPU_SETT80 EQU 51H ; Service command to switch to the internal T80 soft cpu.
TZSVC_STATUS_OK: EQU 000H ; Flag to indicate the K64F processing completed successfully.
TZSVC_STATUS_REQUEST: EQU 0FEH ; Flag to indicate the Z80 has made a request to the K64F.
TZSVC_STATUS_PROCESSING:EQU 0FFH ; Flag to indicate the K64F is processing a command.

View File

@@ -0,0 +1,563 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: RFS_Definitions.asm
;- Created: September 2019
;- Author(s): Philip Smart
;- Description: Sharp MZ series Rom Filing System.
;- Definitions for the RFS including SA1510 locations.
;-
;- Credits:
;- Copyright: (c) 2019-23 Philip Smart <philip.smart@net2net.org>
;-
;- History: Sep 2019 - Initial version.
;- May 2020 - Advent of the new RFS PCB v2.0, quite a few changes to accommodate the
;- additional and different hardware. The SPI is now onboard the PCB and
;- not using the printer interface card.
;- July 2020 - Updated for the tranZPUter 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.
;- March 2021- Updates to accommodate the RFS v2.1 board along with back porting TZFS
;- developments.
;-
;--------------------------------------------------------------------------------------------------------
;- 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/>.
;--------------------------------------------------------------------------------------------------------
;-----------------------------------------------
; Features.
;-----------------------------------------------
HW_SPI_ENA EQU 1 ; Set to 1 if hardware SPI is present on the RFS PCB v2 board.
SW_SPI_ENA EQU 0 ; Set to 1 if software SPI is present on the RFS PCB v2 board.
PP_SPI_ENA EQU 0 ; Set to 1 if using the SPI interface via the Parallel Port, ie. for RFS PCB v1 which doesnt have SPI onboard.
FUSIONX_ENA EQU 1 ; Set to 1 if using RFS on the tranZPUter FusionX board.
; Debugging
ENADEBUG EQU 0 ; Enable debugging logic, 1 = enable, 0 = disable
;-----------------------------------------------
; Entry/compilation start points.
;-----------------------------------------------
UROMADDR EQU 0E800H ; Start of User ROM Address space.
UROMBSTBL EQU UROMADDR + 020H ; Entry point to the bank switching table.
RFSJMPTABLE EQU UROMADDR + 00080H ; Start of jump table.
FDCROMADDR EQU 0F000H
;-----------------------------------------------
; Common character definitions.
;-----------------------------------------------
SCROLL EQU 001H ;Set scroll direction UP.
BELL EQU 007H
SPACE EQU 020H
TAB EQU 009H ;TAB ACROSS (8 SPACES FOR SD-BOARD)
CR EQU 00DH
LF EQU 00AH
FF EQU 00CH
CS EQU 0CH ; Clear screen
DELETE EQU 07FH
BACKS EQU 008H
SOH EQU 1 ; For XModem etc.
EOT EQU 4
ACK EQU 6
NAK EQU 015H
NUL EQU 000H
NULL EQU 000H
CTRL_A EQU 001H
CTRL_B EQU 002H
CTRL_C EQU 003H
CTRL_D EQU 004H
CTRL_E EQU 005H
CTRL_F EQU 006H
CTRL_G EQU 007H
CTRL_H EQU 008H
CTRL_I EQU 009H
CTRL_J EQU 00AH
CTRL_K EQU 00BH
CTRL_L EQU 00CH
CTRL_M EQU 00DH
CTRL_N EQU 00EH
CTRL_O EQU 00FH
CTRL_P EQU 010H
CTRL_Q EQU 011H
CTRL_R EQU 012H
CTRL_S EQU 013H
CTRL_T EQU 014H
CTRL_U EQU 015H
CTRL_V EQU 016H
CTRL_W EQU 017H
CTRL_X EQU 018H
CTRL_Y EQU 019H
CTRL_Z EQU 01AH
ESC EQU 01BH
CTRL_SLASH EQU 01CH
CTRL_LB EQU 01BH
CTRL_RB EQU 01DH
CTRL_CAPPA EQU 01EH
CTRL_UNDSCR EQU 01FH
CTRL_AT EQU 000H
NOKEY EQU 0F0H
CURSRIGHT EQU 0F1H
CURSLEFT EQU 0F2H
CURSUP EQU 0F3H
CURSDOWN EQU 0F4H
DBLZERO EQU 0F5H
INSERT EQU 0F6H
CLRKEY EQU 0F7H
HOMEKEY EQU 0F8H
BREAKKEY EQU 0FBH
GRAPHKEY EQU 0FCH
ALPHAKEY EQU 0FDH
;-------------------------------------------------------
; Function entry points in the standard SA-1510 Monitor.
;-------------------------------------------------------
GETL: EQU 00003h
LETNL: EQU 00006h
NL: EQU 00009h
PRNTS: EQU 0000Ch
PRNT: EQU 00012h
MSG: EQU 00015h
MSGX: EQU 00018h
GETKY EQU 0001Bh
BRKEY EQU 0001Eh
?WRI EQU 00021h
?WRD EQU 00024h
?RDI EQU 00027h
?RDD EQU 0002Ah
?VRFY EQU 0002Dh
MELDY EQU 00030h
?TMST EQU 00033h
MONIT: EQU 00000h
SS: EQU 00089h
ST1: EQU 00095h
HLHEX EQU 00410h
_2HEX EQU 0041Fh
?MODE: EQU 0074DH
?KEY EQU 008CAh
PRNT3 EQU 0096Ch
?ADCN EQU 00BB9h
?DACN EQU 00BCEh
?DSP: EQU 00DB5H
?BLNK EQU 00DA6h
?DPCT EQU 00DDCh
PRTHL: EQU 003BAh
PRTHX: EQU 003C3h
HEX: EQU 003F9h
DPCT: EQU 00DDCh
DLY12: EQU 00DA7h
DLY12A: EQU 00DAAh
?RSTR1: EQU 00EE6h
MOTOR: EQU 006A3H
CKSUM: EQU 0071AH
GAP: EQU 0077AH
WTAPE: EQU 00485H
MSTOP: EQU 00700H
;-----------------------------------------------
; Memory mapped ports in hardware.
;-----------------------------------------------
SCRN: EQU 0D000H
ARAM: EQU 0D800H
DSPCTL: EQU 0DFFFH ; Screen 40/80 select register (bit 7)
KEYPA: EQU 0E000h
KEYPB: EQU 0E001h
KEYPC: EQU 0E002h
KEYPF: EQU 0E003h
CSTR: EQU 0E002h
CSTPT: EQU 0E003h
CONT0: EQU 0E004h
CONT1: EQU 0E005h
CONT2: EQU 0E006h
CONTF: EQU 0E007h
SUNDG: EQU 0E008h
TEMP: EQU 0E008h
MEMSW: EQU 0E00CH
MEMSWR: EQU 0E010H
INVDSP: EQU 0E014H
NRMDSP: EQU 0E015H
SCLDSP: EQU 0E200H
SCLBASE: EQU 0E2H
BNKCTRLRST: EQU 0EFF8H ; Bank control reset, returns all registers to power up default.
BNKCTRLDIS: EQU 0EFF9H ; Disable bank control registers by resetting the coded latch.
HWSPIDATA: EQU 0EFFBH ; Hardware SPI Data register (read/write).
HWSPISTART: EQU 0EFFCH ; Start an SPI transfer.
BNKSELMROM: EQU 0EFFDh ; Select RFS Bank1 (MROM)
BNKSELUSER: EQU 0EFFEh ; Select RFS Bank2 (User ROM)
BNKCTRL: EQU 0EFFFH ; Bank Control register (read/write).
;
; RFS v2 Control Register constants.
;
BBCLK EQU 1 ; BitBang SPI Clock.
SDCS EQU 2 ; SD Card Chip Select, active low.
BBMOSI EQU 4 ; BitBang MOSI (Master Out Serial In).
CDLTCH1 EQU 8 ; Coded latch up count bit 1
CDLTCH2 EQU 16 ; Coded latch up count bit 2
CDLTCH3 EQU 32 ; Coded latch up count bit 3
BK2A19 EQU 64 ; User ROM Device Select Bit 0 (or Address bit 19).
BK2A20 EQU 128 ; User ROM Device Select Bit 1 (or Address bit 20).
; BK2A20 : BK2A19
; 0 0 = Flash RAM 0 (default).
; 0 1 = Flash RAM 1.
; 1 0 = Flasm RAM 2 or Static RAM 0.
; 1 1 = Reserved.`
BNKCTRLDEF EQU BBMOSI+SDCS+BBCLK ; Default on startup for the Bank Control register.
;-----------------------------------------------
; IO ports in hardware and values.
;-----------------------------------------------
SPI_OUT EQU 0FFH
SPI_IN EQU 0FEH
;
DOUT_LOW EQU 000H
DOUT_HIGH EQU 004H
DOUT_MASK EQU 004H
DIN_LOW EQU 000H
DIN_HIGH EQU 001H
CLOCK_LOW EQU 000H
CLOCK_HIGH EQU 002H
CLOCK_MASK EQU 0FDH
CS_LOW EQU 000H
CS_HIGH EQU 001H
;
MMCFG EQU 060H ; Memory management configuration latch.
SETXMHZ EQU 062H ; Select the alternate clock frequency.
SET2MHZ EQU 064H ; Select the system 2MHz clock frequency.
CLKSELRD EQU 066H ; Read clock selected setting, 0 = 2MHz, 1 = XMHz
SVCREQ EQU 068H ; I/O Processor service request.
CPUCFG EQU 06CH ; Version 2.2 CPU configuration register.
CPUSTATUS EQU 06CH ; Version 2.2 CPU runtime status register.
CPUINFO EQU 06DH ; Version 2.2 CPU information register.
CPLDCFG EQU 06EH ; Version 2.1 CPLD configuration register.
CPLDSTATUS EQU 06EH ; Version 2.1 CPLD status register.
CPLDINFO EQU 06FH ; Version 2.1 CPLD version information register.
MMIO0 EQU 0E0H ; MZ-700/MZ-800 Memory Management Set 0
MMIO1 EQU 0E1H ; MZ-700/MZ-800 Memory Management Set 1
MMIO2 EQU 0E2H ; MZ-700/MZ-800 Memory Management Set 2
MMIO3 EQU 0E3H ; MZ-700/MZ-800 Memory Management Set 3
MMIO4 EQU 0E4H ; MZ-700/MZ-800 Memory Management Set 4
MMIO5 EQU 0E5H ; MZ-700/MZ-800 Memory Management Set 5
MMIO6 EQU 0E6H ; MZ-700/MZ-800 Memory Management Set 6
MMIO7 EQU 0E7H ; MZ-700/MZ-800 Memory Management Set 7
;-----------------------------------------------
; CPLD Configuration constants.
;-----------------------------------------------
MODE_MZ80K EQU 0 ; Set to MZ-80K mode.
MODE_MZ80C EQU 1 ; Set to MZ-80C mode.
MODE_MZ1200 EQU 2 ; Set to MZ-1200 mode.
MODE_MZ80A EQU 3 ; Set to MZ-80A mode (base mode on MZ-80A hardware).
MODE_MZ700 EQU 4 ; Set to MZ-700 mode (base mode on MZ-700 hardware).
MODE_MZ800 EQU 5 ; Set to MZ-800 mode.
MODE_MZ80B EQU 6 ; Set to MZ-80B mode.
MODE_MZ2000 EQU 7 ; Set to MZ-2000 mode.
MODE_VIDEO_FPGA EQU 8 ; Bit flag (bit 3) to switch CPLD into using the new FPGA video hardware.
;-----------------------------------------------
; tranZPUter SW Memory Management modes
;-----------------------------------------------
TZMM_ENIOWAIT EQU 020H ; Memory management IO Wait State enable - insert a wait state when an IO operation to E0-FF is executed.
TZMM_ORIG EQU 000H ; Original Sharp MZ80A mode, no tranZPUter features are selected except the I/O control registers (default: 0x60-063).
TZMM_BOOT EQU 001H ; Original mode but E800-EFFF is mapped to tranZPUter RAM so TZFS can be booted.
TZMM_TZFS EQU 002H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-FFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected.
TZMM_TZFS2 EQU 003H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 1.
TZMM_TZFS3 EQU 004H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 2.
TZMM_TZFS4 EQU 005H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 3.
TZMM_CPM EQU 006H + TZMM_ENIOWAIT ; CPM main memory configuration, all memory on the tranZPUter board, 64K block 4 selected. Special case for F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard.
TZMM_CPM2 EQU 007H + TZMM_ENIOWAIT ; CPM main memory configuration, F000-FFFF are on the tranZPUter board in block 4, 0040-CFFF and E800-EFFF are in block 5, mainboard for D000-DFFF (video), E000-E800 (Memory control) selected.
; Special case for 0000:003F (interrupt vectors) which resides in block 4, F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard.
TZMM_COMPAT EQU 008H + TZMM_ENIOWAIT ; Original mode but with main DRAM in Bank 0 to allow bootstrapping of programs from other machines such as the MZ700.
TZMM_HOSTACCESS EQU 009H + TZMM_ENIOWAIT ; Mode to allow code running in Bank 0, address E800:FFFF to access host memory. Monitor ROM 0000-0FFF and Main DRAM 0x1000-0xD000, video and memory mapped I/O are on the host machine, User/Floppy ROM E800-FFFF are in tranZPUter memory.
TZMM_MZ700_0 EQU 00AH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the mainboard.
TZMM_MZ700_1 EQU 00BH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
TZMM_MZ700_2 EQU 00CH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
TZMM_MZ700_3 EQU 00DH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
TZMM_MZ700_4 EQU 00EH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
TZMM_MZ800 EQU 00FH + TZMM_ENIOWAIT ; MZ800 Mode - Tracks original hardware mode offering MZ700/MZ800 configurations.
TZMM_FPGA EQU 015H + TZMM_ENIOWAIT ; Open up access for the K64F to the FPGA resources such as memory. All other access to RAM or mainboard is blocked.
TZMM_TZPUM EQU 016H + TZMM_ENIOWAIT ; Everything in on mainboard, no access to tranZPUter memory.
TZMM_TZPU EQU 017H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
TZMM_TZPU0 EQU 018H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
TZMM_TZPU1 EQU 019H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 1 is selected.
TZMM_TZPU2 EQU 01AH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 2 is selected.
TZMM_TZPU3 EQU 01BH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 3 is selected.
TZMM_TZPU4 EQU 01CH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 4 is selected.
TZMM_TZPU5 EQU 01DH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 5 is selected.
TZMM_TZPU6 EQU 01EH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 6 is selected.
TZMM_TZPU7 EQU 01FH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 7 is selected.
;-----------------------------------------------
; Rom File System Header (MZF)
;-----------------------------------------------
RFS_ATRB: EQU 00000h ; Code Type, 01 = Machine Code.
RFS_NAME: EQU 00001h ; Title/Name (17 bytes).
RFS_SIZE: EQU 00012h ; Size of program.
RFS_DTADR: EQU 00014h ; Load address of program.
RFS_EXADR: EQU 00016h ; Exec address of program.
RFS_COMNT: EQU 00018h ; COMMENT
;-----------------------------------------------
; Entry/compilation start points.
;-----------------------------------------------
TPSTART: EQU 010F0h
MEMSTART: EQU 01200h
MSTART: EQU 0E900h
MZFHDRSZ EQU 128
RFSSECTSZ EQU 256
MROMSIZE EQU 4096
UROMSIZE EQU 2048
FNSIZE EQU 17
;
; Monitor ROM Jump Table definitions.
;
MROMJMPTBL: EQU 00070H
DIRMROM: EQU MROMJMPTBL + 00000H
MFINDMZF: EQU MROMJMPTBL + 00003H
MROMLOAD: EQU MROMJMPTBL + 00006H
;-----------------------------------------------
; ROM Banks, 0-7 are reserved for alternative
; Monitor versions, CPM and RFS
; code in MROM bank,
; 0-7 are reserved for RFS code in
; the User ROM bank.
; 8-15 are reserved for CPM code in
; the User ROM bank.
;-----------------------------------------------
MROMPAGES EQU 8
USRROMPAGES EQU 12 ; Monitor ROM : User ROM
ROMBANK0 EQU 0 ; MROM SA1510 40 Char : RFS Bank 0 - Main RFS Entry point and functions.
ROMBANK1 EQU 1 ; MROM SA1510 80 Char : RFS Bank 1 - Floppy disk controller and utilities.
ROMBANK2 EQU 2 ; CPM 2.2 CBIOS : RFS Bank 2 - SD Card controller and utilities.
ROMBANK3 EQU 3 ; RFS Utilities : RFS Bank 3 - Cmdline tools (Memory, Printer, Help)
ROMBANK4 EQU 4 ; MZ700 1Z-013A 40C : RFS Bank 4 - CMT Utilities.
ROMBANK5 EQU 5 ; MZ700-1Z-013A 80C : RFS Bank 5
ROMBANK6 EQU 6 ; MZ-80B IPL : RFS Bank 6
ROMBANK7 EQU 7 ; Free : RFS Bank 7 - Memory and timer test utilities.
ROMBANK8 EQU 8 ; : CBIOS Bank 1 - Utilities
ROMBANK9 EQU 9 ; : CBIOS Bank 2 - Screen / ANSI Terminal
ROMBANK10 EQU 10 ; : CBIOS Bank 3 - SD Card
ROMBANK11 EQU 11 ; : CBIOS Bank 4 - Floppy disk controller.
; MMC/SD command (SPI mode)
CMD0 EQU 64 + 0 ; GO_IDLE_STATE
CMD1 EQU 64 + 1 ; SEND_OP_COND
ACMD41 EQU 0x40+41 ; SEND_OP_COND (SDC)
CMD8 EQU 64 + 8 ; SEND_IF_COND
CMD9 EQU 64 + 9 ; SEND_CSD
CMD10 EQU 64 + 10 ; SEND_CID
CMD12 EQU 64 + 12 ; STOP_TRANSMISSION
CMD13 EQU 64 + 13 ; SEND_STATUS
ACMD13 EQU 0x40+13 ; SD_STATUS (SDC)
CMD16 EQU 64 + 16 ; SET_BLOCKLEN
CMD17 EQU 64 + 17 ; READ_SINGLE_BLOCK
CMD18 EQU 64 + 18 ; READ_MULTIPLE_BLOCK
CMD23 EQU 64 + 23 ; SET_BLOCK_COUNT
ACMD23 EQU 0x40+23 ; SET_WR_BLK_ERASE_COUNT (SDC)
CMD24 EQU 64 + 24 ; WRITE_BLOCK
CMD25 EQU 64 + 25 ; WRITE_MULTIPLE_BLOCK
CMD32 EQU 64 + 32 ; ERASE_ER_BLK_START
CMD33 EQU 64 + 33 ; ERASE_ER_BLK_END
CMD38 EQU 64 + 38 ; ERASE
CMD55 EQU 64 + 55 ; APP_CMD
CMD58 EQU 64 + 58 ; READ_OCR
SD_SECSIZE EQU 512 ; Default size of an SD Sector
SD_RETRIES EQU 00100H ; Number of retries before giving up.
; Card type flags (CardType)
CT_MMC EQU 001H ; MMC ver 3
CT_SD1 EQU 002H ; SD ver 1
CT_SD2 EQU 004H ; SD ver 2
CT_SDC EQU CT_SD1|CT_SD2 ; SD
CT_BLOCK EQU 008H ; Block addressing
; SD Card Directory structure. The directory entries are based on the MZF Header format and constraints.
;
; FLAG1 | FLAG2 | FILE NAME | START SECTOR | SIZE | LOAD ADDR | EXEC ADDR | RESERVED
; 1 Byte | 1 Byte | 17 Bytes | 2 Bytes | 2 Bytes | 2 Bytes | 2 Bytes | 5 Bytes
;
; FLAG1 : BIT 7 = 1, Valid directory entry, 0 = inactive.
; FLAG2 : MZF Execution Code, 0x01 = Binary
; FILENAME : Standard MZF format filename.
; START SECTOR : Sector in the SD card where the program starts. It always starts at position 0 of the sector.
; SIZE : Size in bytes of the program. Each file block occupies 64Kbyte space (as per a tape) and this
; parameter provides the actual space occupied by the program at the current time.
; LOAD ADDR : Start address in memory where data should be loaded.
; EXEC ADDR : If a binary then this parameter specifies the location to auto execute once loaded.
; RESERVED : Not used at the moemnt.
SDDIR_FLAG1 EQU 000H
SDDIR_FLAG2 EQU 001H
SDDIR_FILEN EQU 002H
SDDIR_SSEC EQU 013H
SDDIR_SIZE EQU 015H
SDDIR_LOAD EQU 017H
SDDIR_EXEC EQU 019H
SDDIR_FNSZ EQU FNSIZE
SDDIR_ENTSZ EQU 32
;
; Rom Filing System constants for the SD Card.
;
SDDIR_DIRENT EQU 256 ; Directory entries in the RFS directory.
SDDIR_DIRENTSZ EQU 32 ; Size of a directory entry.
SDDIR_DIRSIZE EQU SDDIR_DIRENT * SDDIR_DIRENTSZ ; Total size of the directory.
SDDIR_BLOCKSZ EQU 65536 ; Size of a file block per directory entry.
SDDIR_IMGSZ EQU SDDIR_DIRSIZE + (SDDIR_DIRENT * SDDIR_BLOCKSZ) ; Total size of the RFS image.
OBJCD EQU 001H ; MZF contains a binary object.
BTX1CD EQU 002H ; MZF contains an MZ-80K/80A BASIC program.
BTX2CD EQU 005H ; MZF contains an MZ-700/800 BASIC program.
BTX3CD EQU 07EH ; MZF contains a NASCOM Cassette BASIC program.
BTX4CD EQU 07FH ; MZF contains a NASCOM ASCII TEXT BASIC program.
TZOBJCD0 EQU 0F8H ; MZF contains a TZFS binary object for page 0.
TZOBJCD1 EQU 0F9H
TZOBJCD2 EQU 0FAH
TZOBJCD3 EQU 0FBH
TZOBJCD4 EQU 0FCH
TZOBJCD5 EQU 0FDH
TZOBJCD6 EQU 0FEH
TZOBJCD7 EQU 0FFH ; MZF contains a TZFS binary object for page 7.
;-----------------------------------------------
; SA-1510 MONITOR WORK AREA (MZ80A)
;-----------------------------------------------
STACK: EQU 010F0H
;
ORG STACK
;
SPV:
IBUFE: ; TAPE BUFFER (128 BYTES)
ATRB: DS virtual 1 ; ATTRIBUTE
NAME: DS virtual FNSIZE ; FILE NAME
SIZE: DS virtual 2 ; BYTESIZE
DTADR: DS virtual 2 ; DATA ADDRESS
EXADR: DS virtual 2 ; EXECUTION ADDRESS
COMNT: DS virtual 92 ; COMMENT
SWPW: DS virtual 10 ; SWEEP WORK
KDATW: DS virtual 2 ; KEY WORK
KANAF: DS virtual 1 ; KANA FLAG (01=GRAPHIC MODE)
DSPXY: DS virtual 2 ; DISPLAY COORDINATES
MANG: DS virtual 6 ; COLUMN MANAGEMENT
MANGE: DS virtual 1 ; COLUMN MANAGEMENT END
PBIAS: DS virtual 1 ; PAGE BIAS
ROLTOP: DS virtual 1 ; ROLL TOP BIAS
MGPNT: DS virtual 1 ; COLUMN MANAG. POINTER
PAGETP: DS virtual 2 ; PAGE TOP
ROLEND: DS virtual 1 ; ROLL END
DS virtual 14 ; BIAS
FLASH: DS virtual 1 ; FLASHING DATA
SFTLK: DS virtual 1 ; SHIFT LOCK
REVFLG: DS virtual 1 ; REVERSE FLAG
SPAGE: DS virtual 1 ; PAGE CHANGE
FLSDT: DS virtual 1 ; CURSOR DATA
STRGF: DS virtual 1 ; STRING FLAG
DPRNT: DS virtual 1 ; TAB COUNTER
TMCNT: DS virtual 2 ; TAPE MARK COUNTER
SUMDT: DS virtual 2 ; CHECK SUM DATA
CSMDT: DS virtual 2 ; FOR COMPARE SUM DATA
AMPM: DS virtual 1 ; AMPM DATA
TIMFG: DS virtual 1 ; TIME FLAG
SWRK: DS virtual 1 ; KEY SOUND FLAG
TEMPW: DS virtual 1 ; TEMPO WORK
ONTYO: DS virtual 1 ; ONTYO WORK
OCTV: DS virtual 1 ; OCTAVE WORK
RATIO: DS virtual 2 ; ONPU RATIO
BUFER: DS virtual 81 ; GET LINE BUFFER
; Starting 1000H - Generally unused bytes not cleared by the monitor.
ROMBK1: EQU 01016H ; CURRENT MROM BANK
ROMBK2: EQU 01017H ; CURRENT USERROM BANK
WRKROMBK1: EQU 01018H ; WORKING MROM BANK
WRKROMBK2: EQU 01019H ; WORKING USERROM BANK
ROMCTL: EQU 0101AH ; Current Bank control register setting.
SCRNMODE: EQU 0101BH ; Mode of screen, 0 = 40 char, 1 = 80 char.
TMPADR: EQU 0101CH ; TEMPORARY ADDRESS STORAGE
TMPSIZE: EQU 0101EH ; TEMPORARY SIZE
TMPCNT: EQU 01020H ; TEMPORARY COUNTER
TMPLINECNT: EQU 01022H ; Temporary counter for displayed lines.
TMPSTACKP: EQU 01024H ; Temporary stack pointer save.
SDVER: EQU 01026H
SDCAP: EQU 01027H
SDDRIVENO EQU 01028H ; RFS SDCFS Active Drive Number
CMTFILENO EQU 01029H ; Next Sequential file number to read when file request given without name.
TZPU: EQU 0102AH ; Tranzputer present flag (0 = not present, > 0 = present and version number).
; Variables sharing the BUFER buffer, normally the BUFER is only used to get keyboard input and so long as data in BUFER is processed
; before calling the CMT/SD commands and not inbetween there shouldnt be any issue. Also the space used is at the top end of the buffer which is not used so often.
; This frees up memory needed by the CMT and SD card.
SECTORBUF: EQU 0CE00H ; Working buffer to place an SD card sector.
SDSTARTSEC EQU BUFER+50+0 ; Starting sector of data to read/write from/to SD card.
SDLOADADDR EQU BUFER+50+4 ; Address to read/write data from/to SD card.
SDLOADSIZE EQU BUFER+50+6 ; Total remaining byte count data to read/write from/to SD card.
SDAUTOEXEC EQU BUFER+50+8 ; Flag to indicate if a loaded image should be executed (=0xFF)
SDBUF: EQU BUFER+50+9 ; SD Card command fram buffer for the command and response storage.
DIRSECBUF: EQU BUFER+50+20 ; Directory sector in cache.
DUMPADDR: EQU BUFER+50+22 ; Address used by the D(ump) command so that calls without parameters go onto the next block.
CMTLOLOAD: EQU BUFER+50+24 ; Flag to indicate that a tape program is loaded into hi memory then shifted to low memory after ROM pageout.
CMTCOPY: EQU BUFER+50+25 ; Flag to indicate that a CMT copy operation is taking place.
CMTAUTOEXEC: EQU BUFER+50+26 ; Auto execution flag, run CMT program when loaded if flag clear.
DTADRSTORE: EQU BUFER+50+27 ; Backup for load address if actual load shifts to lo memory or to 0x1200 for copy.
SDCOPY: EQU BUFER+50+29 ; Flag to indicate an SD copy is taking place, either CMT->SD or SD->CMT.
RESULT: EQU BUFER+50+30 ; Result variable needed for interbank calls when a result is needed.
; Quickdisk work area
;QDPA EQU 01130h ; QD code 1
;QDPB EQU 01131h ; QD code 2
;QDPC EQU 01132h ; QD header startaddress
;QDPE EQU 01134h ; QD header length
;QDCPA EQU 0113Bh ; QD error flag
;HDPT EQU 0113Ch ; QD new headpoint possition
;HDPT0 EQU 0113Dh ; QD actual headpoint possition
;FNUPS EQU 0113Eh
;FNUPF EQU 01140h
;FNA EQU 01141h ; File Number A (actual file number)
;FNB EQU 01142h ; File Number B (next file number)
;MTF EQU 01143h ; QD motor flag
;RTYF EQU 01144h
;SYNCF EQU 01146h ; SyncFlags
;RETSP EQU 01147h
;BUFER EQU 011A3h
;QDIRBF EQU 0CD90h
;SPV:
;IBUFE: ; TAPE BUFFER (128 BYTES)
;ATRB: DS virtual 1 ; Code Type, 01 = Machine Code.
;NAME: DS virtual 17 ; Title/Name (17 bytes).
;SIZE: DS virtual 2 ; Size of program.
;DTADR: DS virtual 2 ; Load address of program.
;EXADR: DS virtual 2 ; Exec address of program.
;COMNT: DS virtual 104 ; COMMENT
;KANAF: DS virtual 1 ; KANA FLAG (01=GRAPHIC MODE)
;DSPXY: DS virtual 2 ; DISPLAY COORDINATES
;MANG: DS virtual 27 ; COLUMN MANAGEMENT
;FLASH: DS virtual 1 ; FLASHING DATA
;FLPST: DS virtual 2 ; FLASHING POSITION
;FLSST: DS virtual 1 ; FLASHING STATUS
;FLSDT: DS virtual 1 ; CURSOR DATA
;STRGF: DS virtual 1 ; STRING FLAG
;DPRNT: DS virtual 1 ; TAB COUNTER
;TMCNT: DS virtual 2 ; TAPE MARK COUNTER
;SUMDT: DS virtual 2 ; CHECK SUM DATA
;CSMDT: DS virtual 2 ; FOR COMPARE SUM DATA
;AMPM: DS virtual 1 ; AMPM DATA
;TIMFG: DS virtual 1 ; TIME FLAG
;SWRK: DS virtual 1 ; KEY SOUND FLAG
;TEMPW: DS virtual 1 ; TEMPO WORK
;ONTYO: DS virtual 1 ; ONTYO WORK
;OCTV: DS virtual 1 ; OCTAVE WORK
;RATIO: DS virtual 2 ; ONPU RATIO

View File

@@ -0,0 +1,496 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: RFS_Utilities.asm
;- Created: September 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) 2019-23 Philip Smart <philip.smart@net2net.org>
;-
;- History: September 2018 - Merged 2 utilities to create this compilation.
;-
;--------------------------------------------------------------------------------------------------------
;- 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/>.
;--------------------------------------------------------------------------------------------------------
; Comparing Strings
; IN HL Address of string1.
; DE Address of string2.
; BC Max bytes to compare, 0x00 or 0x0d will early terminate.
; OUT zero Set if string1 = string2, reset if string1 != string2.
; carry Set if string1 > string2, reset if string1 <= string2.
CMPSTRING: IF USE_CMPSTRING = 1
PUSH HL
PUSH DE
CMPSTR1: LD A, (DE) ; Compare bytes.
CP 000h ; Check for end of string.
JR Z, CMPSTR3
CP 00Dh
JR Z, CMPSTR3
CPI ; Compare bytes.
JR NZ, CMPSTR2 ; If (HL) != (DE), abort.
INC DE ; Update pointer.
JP PE, CMPSTR1 ; Next byte if BC not zero.
CMPSTR2: DEC HL
CP (HL) ; Compare again to affect carry.
CMPSTR4: POP DE
POP HL
RET
CMPSTR3: LD A, (HL)
CP 000h ; Check for end of string.
JR Z, CMPSTR4
CP 00Dh
JR Z, CMPSTR4
SCF ; String 1 greater than string 2
JR CMPSTR4
ENDIF
; IN HL Address of source string, length-prefixed.
; DE Address of destination string, length-prefixed.
; B Start index. 1 = first character.
; C Length of substring to return.
;
; OUT carry Set if an error condition happened:
; If B is zero, then uses index of 1.
; If index > source length, an empty string is returned.
; If index + return length > source length, returns all
; characters from index to end-of-string.
SUBSTRING: IF USE_SUBSTRING = 1
PUSH DE ; It would be convenient to keep DE pointing to
; the start of the destination string
OR A ; Boolean OR resets carry
PUSH AF ; Save carry
LD A, B ; Is index beyond source length?
CP (HL)
DEC A ; Decrement A so NC can be used
JR NC,SUBST3
ADD A, C ; If index+len is > 255, error
JR C, SUBST1
INC A ; Increment A so C can be used
CP (HL) ; If index+len is beyond source length, then error
JR C, SUBST2
SUBST1: POP AF ; Set carry flag
SCF
PUSH AF
LD A, (HL) ; Get source length
SUB B ; Subtract start index
INC A ; Compensate
LD C, A ; New size of string
SUBST2: LD A, C ; Size of sting to get
LD (DE), A ; Save length index
INC DE ; To body of string
LD A, B ; Get index
LD B, 0 ; Zero-extend BC for LDIR
ADD A, L ; This is a sneaky way to add A to HL
LD L, A ; without using up another 16-bit register
ADC A, H ;
SUB L ;
LD H, A ;
LDIR ; Copy substring over
POP AF ; Restore flags
POP DE ; Restore destination
RET
SUBST3: XOR A ; Set a length index of zero
LD (DE), A
POP AF ; Clean off stack and set carry
POP DE
SCF
RET
ENDIF
; IN HL Address of string to look in, length prefixed.
; DE Address of string to find, length prefixed.
;
; OUT
; If found:
; A Offset into look-up string where the target string was found.
; The first byte (ignoring length prefix) is offset 1.
; carry Reset.
;
; If not found:
; A = 0
; carry Set.
INDEX: IF USE_INDEX = 1
LD A, (DE) ; Abort if string to find is too big
CP (HL)
INC A
JR NC, IDXABORT
DEC A ; Save length of string to find
LD IXL, A
LD B, 0 ; Put length of string to search in BC
LD C, (HL)
INC HL ; Advance pointers
INC DE
PUSH HL ; Save start of search string
IDXRST: PUSH DE ; Save start of key string
LD A, IXL ; Initialize matched characters counter
LD IXH, A
LD A, (DE) ; Get a character to match
CPIR ; Look for it
JR NZ, IDXNF ; Abort if not found
IDXLOOP: DEC IXH ; Update counter and see if done
JR Z, IDXFOUND
INC DE ; Get next character in key string
LD A, (DE)
CPI ; See if it matches next char in master
JR Z, IDXLOOP
JP PO, IDXNF ; Abort if we ran out of characters
POP DE ; If a mismatch, restart from the beginning
JR IDXRST
IDXNF: POP DE ; Clean stack
POP HL
IDXABORT: XOR A ; Report failure
SCF
RET
IDXFOUND: POP DE
POP BC ; BC = address of master
XOR A ; Put size of key string in DE
LD D, A
LD E, IXL
SBC HL, DE ; Find index
SBC HL, BC
LD A, L
INC A
RET
ENDIF
; IN HL Address of string to be inserted
; DE Address of string to receive insertion
; C Index. Start of string is 0
; OUT
; If successful:
; carry Reset
; HL Input DE
; If unsuccessful:
; carry Set. If new string length is > 255.
;
; Notes If index > string length, string is appended.
; Data after the string is destroyed.
STRINSERT: IF USE_STRINSERT = 1
LD A, (DE)
LD B, A
INC A
CP C
JR NC, STRINSERT1
LD C, B
STRINSERT1:DEC A
ADD A, (HL)
RET C
LD (DE), A ; Update length
PUSH DE ; Make room
PUSH HL
LD A, (HL)
INC C
LD H, 0
LD L, C
ADD HL, DE
LD D, H
LD E, L
PUSH AF
ADD A, E
LD E, A
ADC A, D
SUB E
LD D, A
POP AF
LD B, 0
LD C, A
PUSH HL
LDIR
POP DE ; Copy string over
POP HL
LD C, (HL)
INC HL
LDIR
POP HL
RET
ENDIF
; IN HL Address of string.
; B Index of first character to delete. First character is 0.
; C Number of characters to kill.
; OUT
; If successful:
; carry Reset
; If unsuccessful:
; carry Set
;
; Notes If B > string length, then error.
; If B + C > string length, deletion
; stops at end of string.
STRDELETE: IF USE_STRDELETE = 1
LD A, B ; See if index is too big
CP (HL)
CCF ; Flip for error
RET C
ADD A, C ; See if too many chars on chopping block
CP (HL)
JR C, STRDELETE1
INC B ; Set index as length
LD (HL), B
RET
STRDELETE1:PUSH HL
LD A, (HL)
SUB C
LD (HL), A
INC HL
LD E, C
LD C, B
LD B, 0
ADD HL, BC
SUB C
LD C, E
LD D, H
LD E, L
ADD HL, BC
LD C, A
LDIR
POP HL
RET
ENDIF
; IN HL Address of first string.
; DE Address of second string.
; OUT
; If successful:
; carry Reset
; If unsuccessful:
; carry Set
;
; Notes If new string lenght is > 255, error.
; HL is saved.
CONCAT: IF USE_CONCAT = 1
LD A, (DE) ; Combine lengths
ADD A, (HL)
RET C
LD C, (HL)
LD (HL), A
LD B, 0
INC C
PUSH HL
ADD HL, BC
EX DE, HL
LD C, (HL)
INC HL
LDIR
POP HL
RET
ENDIF
; Utility: Convert character to upper case
; On entry: A = Character in either case
; On exit: A = Character in upper case
; BC DE HL IX IY I AF' BC' DE' HL' preserved
ConvertCharToUCase: IF USE_CNVUPPER = 1
CP 'a' ;Character less than 'a'?
RET C ;Yes, so finished
CP 'z'+1 ;Character greater than 'z'?
RET NC ;Yes, so finished
SUB 'a'-'A' ;Convert case
RET
ENDIF
;
; Utility: Convert character to numberic value
; On entry: A = ASCII character (0-9 or A-F)
; On exit: If character is a valid hex digit:
; A = Numberic value (0 to 15) and Z flagged
; If character is not a valid hex digit:
; A = 0xFF and NZ flagged
; BC DE HL IX IY I AF' BC' DE' HL' preserved
; Interrupts not enabled
ConvertCharToNumber: IF USE_CNVCHRTONUM = 1
CALL ConvertCharToUCase
CP '0' ;Character < '0'?
JR C,@Bad ;Yes, so no hex character
CP '9'+1 ;Character <= '9'?
JR C,@OK ;Yes, got hex character
CP 'A' ;Character < 'A'
JR C,@Bad ;Yes, so not hex character
CP 'F'+1 ;Character <= 'F'
JR C,@OK ;No, not hex
; Character is not a hex digit so return
@Bad: LD A,0FFh ;Return status: not hex character
OR A ; A = 0xFF and NZ flagged
RET
; Character is a hex digit so adjust from ASCII to number
@OK: SUB '0' ;Subtract '0'
CP 00Ah ;Number < 10 ?
JR C,@Finished ;Yes, so finished
SUB 007h ;Adjust for 'A' to 'F'
@Finished: CP A ;Return A = number (0 to 15) and Z flagged to
RET ; indicate character is a valid hex digital
ENDIF
; Utility: Is character numeric?
; On entry: A = ASCII character
; On exit: Carry flag set if character is numeric (0 to 9)
; A BC DE HL IX IY I AF' BC' DE' HL' preserved
IsCharNumeric: IF USE_ISNUMERIC = 1
CP '0' ;Less than '0'?
JR C,@Not2 ;Yes, so go return NOT numeric
CP '9'+1 ;Less than or equal to '9'?
RET C ;Yes, so numeric (C flagged)
@Not2: OR A ;No, so NOT numeric (NC flagged)
RET
ENDIF
; Utility: Convert hexadecimal or decimal text to number
; On entry: DE = Pointer to start of ASCII string
; On exit: If valid number found:
; A = 0 and Z flagged
; HL = Number found
; If valid number not found:
; A != 0 and NZ flagged
; HL = Not specified
; DE = Not specified
; HL = Number
; BC DE IX IY I AF' BC' DE' HL' preserved
; Hexadecmal numbers can be prefixed with either "$" or "0x"
; Decimal numbers must be prefixed with "+"
; A number without a prefix is assumed to be hexadecimal
; Hexadecimal number without a prefix must start with "0" to "9"
; ... this is to stop the assembler getting confused between
; ... register names and constants which could be fixed by
; ... re-ordering the (dis)assebmer's instruction table
; Numbers can be terminated with ")", space, null or control code
; Negative numbers, preceded with "-", are not supported
; Text must be terminated with ')', space or control char.
ConvertStringToNumber: IF USE_CNVSTRTONUM = 1
PUSH BC
LD HL,0 ;Build result here
LD A,(DE) ;Get character from string
CP '+' ;Does string start with '+' ?
JR Z,@Decimal ;Yes, so its decimal
CP '$' ;Does string start with '$' ?
JR Z,@Hdecimal ;Yes, so its hexadecimal
CP 39 ;Does string start with apostrophe?
JR Z,@Char ;Yes, so its a character
CP '"' ;Does string start with '"' ?
JR Z,@Char ;Yes, so its a character
;; CALL IsCharNumeric ;Is first character '0' to '9' ?
;; JR NC,@Failure ;No, so invalid number
; CALL IsCharHex ;Is first character hexadecimal ?
; JR NC,@Failure ;No, so invalid hex character
CP '0' ;Is first character '0' ?
JR NZ,@HexNext ;No, so default to hexadecimal
; JR NZ,@DecNext ;No, so default to decimal
INC DE ;Point to next character in string
LD A,(DE) ;Get character from string
CALL ConvertCharToUCase
CP 'X' ;Is second character 'x' ?
JR NZ,@HexNext ;No, so must be default format
; JR NZ,@DecNext ;No, so must be default format
; Hexadecimal number...
@Hdecimal: INC DE ;Point to next character in string
@HexNext: LD A,(DE) ;Get character from string
CP ')' ;Terminated with a bracket?
JR Z,@Success ;yes, so success
CP 32+1 ;Space or control character?
JR C,@Success ;Yes, so successld hl
CALL ConvertCharToNumber ;Convert character to number
JR NZ,@Failure ;Return if failure (NZ flagged)
INC DE ;Point to next character in string
ADD HL,HL ;Current result = 16 * current result..
ADD HL,HL
ADD HL,HL
ADD HL,HL
OR L ;Add new number (0 to 15)..
LD L,A
JR @HexNext
; Decimal number...
@Decimal: INC DE ;Point to next character in string
@DecNext: LD A,(DE) ;Get character from string
CP ')' ;Terminated with a bracket?
JR Z,@Success ;yes, so success
CP 32+1 ;Space or control character?
JR C,@Success ;Yes, so success
CALL IsCharNumeric ;Is first character '0' to '9' ?
JR NC,@Failure ;No, so invalid number
CALL ConvertCharToNumber ;Convert character to number
JR NZ,@Failure ;Return if failure (NZ flagged)
INC DE ;Point to next character in string
PUSH DE
LD B,9 ;Current result = 10 * current result..
LD D,H
LD E,L
@DecLoop: ADD HL,DE ;Add result to itself 9 times
DJNZ @DecLoop
POP DE
ADD A,L ;Add new number (0 to 15)..
LD L,A
JR NC,@DecNext
INC H
JR @DecNext
; Character...
@Char: INC DE ;Point to next character in string
LD A,(DE) ;Get ASCII character
LD L,A ;Store ASCII value as result
LD H,0
; JR @Success
; Return result...
@Success: POP BC
XOR A ;Return success with A = 0 and Z flagged
RET
@Failure: POP BC
LD A,0FFh ;Return failure with A != 0
OR A ; and NZ flagged
RET
ENDIF

901
asm/ipl.asm Normal file
View File

@@ -0,0 +1,901 @@
ORG 0000H
;****************************************************************
;
; Personal Computer
; MZ-80B
;
; Initial Program Loader
;****************************************************************
;
JR START
;
; NST RESET
;
NST: LD A,03H
OUT (PPICTL),A ;Set PC1 NST=1
;
START: LD A,82H ;8255 A=OUT B=IN C=OUT
OUT (PPICTL),A
LD A,0FH ;PIO A=OUT
OUT (PIOCTLA),A
LD A,0CFH ;PIO B=IN
OUT (PIOCTLB),A
LD A,0FFH
OUT (PIOCTLB),A
LD A,58H ;BST=1 NST=0 OPEN=1 WRITE=1
OUT (PPIC),A
LD A,12H
OUT (PPIA),A
XOR A
OUT (GRPHCTL),A ;Set Graphics VRAM to default, input to GRPH I, no output.
LD SP,0FFE0H
LD HL,0D000H
LD A,0B3H
OUT (PIOA),A
CLEAR: LD (HL),00H ;DISPLAY CLEAR
INC HL
LD A,H
OR L
JR NZ,CLEAR
LD A,13H
OUT (PIOA),A
XOR A
LD (DRINO),A
LD (MTFG),A
KEYIN: CALL KEYS1
BIT 3,A ;C - Cassette.
JR Z,CMT
BIT 0,A ;/ - Boot external rom.
JP Z,EXROMT
JR NKIN ;No selection, so standard startup, try FDC then CMT.
;
KEYS1: LD B,14H ;Preserve A4-A7, set A4 to prevent all strobes low, the select line 5 (0-4).
KEYS: IN A,(PIOA)
AND 0F0H
OR B
OUT (PIOA),A
IN A,(PIOB) ;Read the strobed key.
RET
;
;
NKIN: CALL FDCC
JP Z,FD
JR CMT
;
FDCC: LD A,0A5H
LD B,A
OUT (0D9H),A
CALL DLY80U
IN A,(0D9H)
CP B
RET
;
; ;
; CMT CONTROL ;
; ;
;
CMT: CALL MSTOP
CALL DEL6
CALL KYEMES
CALL ?RDI
JR C,ST1
CALL LDMSG
LD HL,NAME
LD E,010H
LD C,010H
CALL DISP2
LD A,(ATRB)
CP 01H
JR NZ,MISMCH
CALL ?RDD
ST1: PUSH AF
CALL DEL6
CALL REW
POP AF
JP C,TRYAG
JP NST
;
MISMCH: LD HL,MES16
LD E,0AH
LD C,0FH
CALL DISP
CALL MSTOP
SCF
JR ST1
;
;READ INFORMATION
; CF=1:ERROR
RDINF:
?RDI: DI
LD D,04H
LD BC,0080H
LD HL,IBUFE
RD1: CALL MOTOR
JR C,STPEIR
CALL TMARK
JR C,STPEIR
CALL RTAPE
JR C,STPEIR
RET2S: BIT 3,D
JR Z,EIRTN
STPEIR: CALL MSTOP
EIRTN: EI
RET
;
;
;READ DATA
RDDAT:
?RDD: DI
LD D,08H
LD BC,(SIZE)
LD HL,8000H
JR RD1
;
;
;READ TAPE
; BC=SIZE
; DE=LOAD ADDRSS
RTAPE: PUSH DE
PUSH BC
PUSH HL
LD H,02H
RTP2: CALL SPDIN
JR C,TRTN1 ;BREAK
JR Z,RTP2
LD D,H
LD HL,0000H
LD (SUMDT),HL
POP HL
POP BC
PUSH BC
PUSH HL
RTP3: CALL RBYTE
JR C,TRTN1
LD (HL),A
INC HL
DEC BC
LD A,B
OR C
JR NZ,RTP3
LD HL,(SUMDT)
CALL RBYTE
JR C,TRTN1
LD E,A
CALL RBYTE
JR C,TRTN1
CP L
JR NZ,RTP5
LD A,E
CP H
JR Z,TRTN1
RTP5: DEC D
JR Z,RTP6
LD H,D
JR RTP2
RTP6: CALL BOOTER
SCF
TRTN1: POP HL
POP BC
POP DE
RET
;EDGE
EDGE: IN A,(PPIB)
CPL
RLCA
RET C ;BREAK
RLCA
JR NC,EDGE ;WAIT ON LOW
EDGE1: IN A,(PPIB)
CPL
RLCA
RET C ;BREAK
RLCA
JR C,EDGE1 ;WAIT ON HIGH
RET
; 1 BYTE READ
; DATA=A
; SUMDT STORE
RBYTE: PUSH HL
LD HL,0800H ; 8 BITS
RBY1: CALL SPDIN
JR C,RBY3 ;BREAK
JR Z,RBY2 ;BIT=0
PUSH HL
LD HL,(SUMDT) ;CHECKSUM
INC HL
LD (SUMDT),HL
POP HL
SCF
RBY2: RL L
DEC H
JR NZ,RBY1
CALL EDGE
LD A,L
RBY3: POP HL
RET
;TAPE MARK DETECT
; E=L:INFORMATION
; E=S:DATA
TMARK: PUSH HL
LD HL,1414H
BIT 3,D
JR NZ,TM0
ADD HL,HL
TM0: LD (TMCNT),HL
TM1: LD HL,(TMCNT)
TM2: CALL SPDIN
JR C,RBY3
JR Z,TM1
DEC H
JR NZ,TM2
TM3: CALL SPDIN
JR C,RBY3
JR NZ,TM1
DEC L
JR NZ,TM3
CALL EDGE
JR RBY3
;READ 1 BIT
SPDIN: CALL EDGE ;WAIT ON HIGH
RET C ;BREAK
CALL DLY2
IN A,(PPIB) ;READ BIT
AND 40H
RET
;
;
;MOTOR ON
MOTOR: PUSH DE
PUSH BC
PUSH HL
IN A,(PPIB)
AND 20H
JR Z,MOTRD
LD HL,MES6
LD E,0AH
LD C,0EH
CALL DISP
CALL OPEN
MOT1: IN A,(PIOB)
CPL
RLCA
JR C,MOTR
IN A,(PPIB)
AND 20H
JR NZ,MOT1
CALL KYEMES
CALL DEL1M
MOTRD: CALL PLAY
MOTR: POP HL
POP BC
POP DE
RET
;
;
;MOTOR STOP
MSTOP: LD A,0DH
OUT (PPICTL),A ;Set PC6 - READ MODE
LD A,1AH
OUT (PPIA),A
CALL DEL6
JR BLK3
;EJECT
OPEN: LD A,08H ;Reset PC4 - EJECT activate
OUT (PPICTL),A
CALL DEL6
LD A,09H
OUT (PPICTL),A ;Set PC4 - Deactivate EJECT
RET
;
;
KYEMES: LD HL,MES3
LD E,04H
LD C,1CH
CALL DISP
RET
;
;PLAY
PLAY: CALL FR
CALL DEL6
LD A,16H
OUT (PPIA),A
JR BLK3
BLK1: CALL DEL6
CALL BLK3
LD A,13H
BLK2: OUT (PPIA),A
BLK3: LD A,12H
OUT (PPIA),A
RET
;
;
FR: LD A,12H
FR1: OUT (PPIA),A
CALL DEL6
LD A,0BH
OUT (PPICTL),A ;Set PC5
CALL DEL6
LD A,0AH
OUT (PPICTL),A ;Reset PC5
RET
RRW: LD A,010H
JR FR1
;REWIND
REW: CALL RRW
JR BLK1
;
;TIMING DEL
DM1: PUSH AF
L0211: XOR A
L0212: DEC A
JR NZ,L0212
DEC BC
LD A,B
OR C
JR NZ,L0211
POP AF
POP BC
RET
DEL6: PUSH BC
LD BC,00E9H ;233D
JR DM1
DEL1M: PUSH BC
LD BC,060FH ;1551D
JR DM1
;
;TAPE DELAY TIMING
;
;
DLY2: LD A,31H
L022B: DEC A
JP NZ,L022B
RET
;
;
;
;
;
LDMSG: LD HL,MES1
LD E,00H
LD C,0EH
JR DISP
;
DISP2: LD A,93H
OUT (PIOA),A
JR DISP1
;
BOOTER: LD HL,MES8
LD E,0AH
LD C,0DH
;
DISP: LD A,93H
OUT (PIOA),A
EXX
LD HL,0D000H
DISP3: LD (HL),00H
INC HL
LD A,H
OR L
JR NZ,DISP3
EXX
DISP1: XOR A
LD B,A
LD D,0D0H
LDIR
LD A,13H
OUT (PIOA),A
RET
;
;
MES1: DB "IPL is loading"
MES3: DB "IPL is looking for a program"
MES6: DB "Make ready CMT"
MES8: DB "Loading error"
MES9: DB "Make ready FD"
MES10: DB "Press F or C"
MES11: DB "F:Floppy diskette"
MES12: DB "C:Cassette tape"
MES13: DB "Drive No? (1-4)"
MES14: DB "This diskette is not master"
MES15: DB "Pressing S key starts the CMT"
MES16: DB "File mode error"
;
IPLMC: DB 01H
DB "IPLPRO"
;
;
;FD
FD: LD IX,IBADR1
XOR A
LD (0CF1EH),A
LD (0CF1FH),A
LD IY,0FFE0H
LD HL,0100H
LD (IY+2),L
LD (IY+3),H
CALL BREAD ;INFORMATION INPUT
LD HL,0CF00H ;MASTER CHECK
LD DE,IPLMC
LD B,06H
MCHECK: LD C,(HL)
LD A,(DE)
CP C
JP NZ,NMASTE
INC HL
INC DE
DJNZ MCHECK
CALL LDMSG
LD HL,0CF07H
LD E,010H
LD C,0AH
CALL DISP2
LD IX,IBADR2
LD HL,(0CF14H)
LD (IY+2),L
LD (IY+3),H
CALL BREAD
CALL MOFF
JP NST
;
;
NODISK: LD HL,MES9
LD E,0AH
LD C,0DH
CALL DISP
JP ERR1
;
; READY CHECK
;
READY: LD A,(MTFG)
RRCA
CALL NC,MTON
LD A,(DRINO) ;DRIVE NO GET
OR 84H
OUT (DM),A ;DRIVE SELECT MOTON
XOR A
CALL DLY60M
LD HL,0000H
REDY0: DEC HL
LD A,H
OR L
JR Z,NODISK
IN A,(CR) ;STATUS GET
CPL
RLCA
JR C,REDY0
LD A,(DRINO)
LD C,A
LD HL,CLBF0
LD B,00H
ADD HL,BC
BIT 0,(HL)
RET NZ
CALL RCLB
SET 0,(HL)
RET
;
; MOTOR ON
;
MTON: LD A,80H
OUT (DM),A
LD B,0AH ;1SEC DELAY
MTD1: LD HL,3C19H
MTD2: DEC HL
LD A,L
OR H
JR NZ,MTD2
DJNZ MTD1
LD A,01H
LD (MTFG),A
RET
;
;SEEK TREATMENT
;
SEEK: LD A,1BH
CPL
OUT (CR),A
CALL BUSY
CALL DLY60M
IN A,(CR)
CPL
AND 99H
RET
;
;MOTOR OFF
;
MOFF: CALL DLY1M
XOR A
OUT (DM),A
LD (CLBF0),A
LD (CLBF1),A
LD (CLBF2),A
LD (CLBF3),A
LD (MTFG),A
RET
;
;RECALIBRATION
;
RCLB: PUSH HL
LD A,0BH
CPL
OUT (CR),A
CALL BUSY
CALL DLY60M
IN A,(CR)
CPL
AND 85H
XOR 04H
POP HL
RET Z
JP ERR
;
;BUSY AND WAIT
;
BUSY: PUSH DE
PUSH HL
CALL DLY80U
LD E,07H
BUSY2: LD HL,0000H
BUSY0: DEC HL
LD A,H
OR L
JR Z,BUSY1
IN A,(CR)
CPL
RRCA
JR C,BUSY0
POP HL
POP DE
RET
;
BUSY1: DEC E
JR NZ,BUSY2
JP ERR
;
;DATA CHECK
;
CONVRT: LD B,00H
LD DE,0010H
LD HL,(0CF1EH)
XOR A
TRANS: SBC HL,DE
JR C,TRANS1
INC B
JR TRANS
TRANS1: ADD HL,DE
LD H,B
INC L
LD (IY+4),H
LD (IY+5),L
DCHK: LD A,(DRINO)
CP 04H
JR NC,DTCK1
LD A,(IY+4)
CP 46H ;70D
JR NC,DTCK1
LD A,(IY+5)
OR A
JR Z,DTCK1
CP 11H ;17D
JR NC,DTCK1
LD A,(IY+2)
OR (IY+3)
RET NZ
DTCK1: JP ERR
;
;SEQUENTIAL READ
;
BREAD: DI
CALL CONVRT
LD A,0AH
LD (RETRY),A
READ1: CALL READY
LD D,(IY+3)
LD A,(IY+2)
OR A
JR Z,RE0
INC D
RE0: LD A,(IY+5)
LD (IY+1),A
LD A,(IY+4)
LD (IY+0),A
PUSH IX
POP HL
RE8: SRL A
CPL
OUT (DR),A
JR NC,RE1
LD A,01H
JR RE2
RE1: LD A,00H
RE2: CPL
OUT (HS),A
CALL SEEK
JR NZ,REE
LD C,0DBH
LD A,(IY+0)
SRL A
CPL
OUT (TR),A
LD A,(IY+1)
CPL
OUT (SCR),A
EXX
LD HL,RE3
PUSH HL
EXX
LD A,94H
CPL
OUT (CR),A
CALL WAIT
RE6: LD B,00H
RE4: IN A,(CR)
RRCA
RET C
RRCA
JR C,RE4
INI
JR NZ,RE4
INC (IY+1)
LD A,(IY+1)
CP 11H ;17D
JR Z,RETS
DEC D
JR NZ,RE6
JR RE5
RETS: DEC D
RE5: LD A,0D8H ;FORCE INTERRUPT
CPL
OUT (CR),A
CALL BUSY
RE3: IN A,(CR)
CPL
AND 0FFH
JR NZ,REE
EXX
POP HL
EXX
LD A,(IY+1)
CP 11H ;17D
JR NZ,REX
LD A,01H
LD (IY+1),A
INC (IY+0)
REX: LD A,D
OR A
JR NZ,RE7
LD A,80H
OUT (DM),A
RET
RE7: LD A,(IY+0)
JR RE8
REE: LD A,(RETRY)
DEC A
LD (RETRY),A
JR Z,ERR
CALL RCLB
JP READ1
;
; WAIT AND BUSY OFF
;
WAIT: PUSH DE
PUSH HL
CALL DLY80U
LD E,08H
WAIT2: LD HL,0000H
WAIT0: DEC HL
LD A,H
OR L
JR Z,WAIT1
IN A,(CR)
CPL
RRCA
JR NC,WAIT0
POP HL
POP DE
RET
WAIT1: DEC E
JR NZ,WAIT2
JR ERR
;
NMASTE: LD HL,MES14
LD E,07H
LD C,1BH ;27D
CALL DISP
JR ERR1
;
; ;
; ERRROR OR BREAK ;
; ;
;
ERR: CALL BOOTER
ERR1: CALL MOFF
TRYAG2: LD SP,0FFE0H
;
;TRYAG
;
TRYAG: CALL FDCC
JR NZ,TRYAG3
LD HL,MES10
LD E,5AH
LD C,0CH ;12D
CALL DISP2
LD E,0ABH
LD C,11H ;17D
CALL DISP2
LD E,0D3H
LD C,0FH ;15D
CALL DISP2
TRYAG1: CALL KEYS1
BIT 3,A
JP Z,CMT
BIT 6,A
JR Z,DNO
JR TRYAG1
DNO: LD HL,MES13 ;DRIVE NO SELECT
LD E,0AH
LD C,0FH
CALL DISP
DNO10: LD D,12H
CALL DNO0
JR NC,DNO3
LD D,18H
CALL DNO0
JR NC,DNO3
JR DNO10
DNO3: LD A,B
LD (DRINO),A
JP FD
;
TRYAG3: LD HL,MES15
LD E,54H
LD C,1DH ;29D
CALL DISP2
TRYAG4: LD B,06H
TRYAG5: CALL KEYS
BIT 3,A
JP Z,CMT
JR TRYAG5
;
DNO0: IN A,(PIOA)
AND 0F0H
OR D
OUT (PIOA),A
IN A,(PIOB)
LD B,00H
LD C,04H
RRCA
DNO1: RRCA
RET NC
INC B
DEC C
JR NZ,DNO1
RET
;
; TIME DELAY (1M &60M &80U )
;
DLY80U: PUSH DE
LD DE,000DH ;13D
JP DLYT
DLY1M: PUSH DE
LD DE,0082H ;130D
JP DLYT
DLY60M: PUSH DE
LD DE,1A2CH ;6700D
DLYT: DEC DE
LD A,E
OR D
JR NZ,DLYT
POP DE
RET
;
;
; ;
; INTRAM EXROM ;
; ;
;
EXROMT: LD HL,8000H
LD IX,EROM1
JR SEROMA
EROM1: IN A,(0F9H)
CP 00H
JP NZ,NKIN
LD IX,EROM2
ERMT1: JR SEROMA
EROM2: IN A,(0F9H)
LD (HL),A
INC HL
LD A,L
OR H
JR NZ,ERMT1
OUT (0F8H),A
JP NST
;
SEROMA: LD A,H
OUT (0F8H),A
LD A,L
OUT (0F9H),A
LD D,04H
SEROMD: DEC D
JR NZ,SEROMD
JP (IX)
; Pad to 4K as this is the standard MROM Bank size.
DS 01000H - $
;----------------------------------------------------------
; Variables/Work area
;----------------------------------------------------------
IBUFE: EQU 0CF00H
ATRB: EQU 0CF00H
NAME: EQU 0CF01H
SIZE: EQU 0CF12H
DTADR: EQU 0CF14H
SUMDT: EQU 0FFE0H
TMCNT: EQU 0FFE2H
;
;
;INPUT BUFFER ADDRESS
;
IBADR1: EQU 0CF00H
IBADR2: EQU 8000H
;
; SUBROUTINE WORK
;
NTRACK: EQU 0FFE0H
NSECT: EQU 0FFE1H
BSIZE: EQU 0FFE2H
STTR: EQU 0FFE4H
STSE: EQU 0FFE5H
MTFG: EQU 0FFE6H
CLBF0: EQU 0FFE7H
CLBF1: EQU 0FFE8H
CLBF2: EQU 0FFE9H
CLBF3: EQU 0FFEAH
RETRY: EQU 0FFEBH
DRINO: EQU 0FFECH
;
;
;
;
;
; MFM MINIFLOPPY CONTROL
;
;
;
; CASE OF DISK INITIALIZE
; DRIVE NO=DRINO (0-3)
;
; CASE OF SEQUENTIAL READ
; DRIVE NO=DRINO (0-3)
; BYTE SIZE =IY+2,3
; ADDRESS =IX+0,1
; NEXT TRACK =IY+0
; NEXT SECTOR =IY+1
; START TRACK =IY+4
; START SECTOR =IY+5
;
;
; I/O PORT ADDRESS
;
CR: EQU 0D8H ;STATUS/COMMAND PORT
TR: EQU 0D9H ;TRACK REG PORT
SCR: EQU 0DAH ;SECTOR REG PORT
DR: EQU 0DBH ;DATA REG PORT
DM: EQU 0DCH ;MOTOR/DRIVE PORT
HS: EQU 0DDH ;HEAD SIDE SELECT PORT
PPIA: EQU 0E0H
PPIB: EQU 0E1H
PPIC: EQU 0E2H
PPICTL: EQU 0E3H
PIOA: EQU 0E8H
PIOCTLA:EQU 0E9H
PIOB: EQU 0EAH
PIOCTLB:EQU 0EBH
GRPHCTL:EQU 0F4H

7
asm/monitor_1z-013a.asm Normal file
View File

@@ -0,0 +1,7 @@
; Configurable parameters.
COLW: EQU 40 ; Width of the display screen (ie. columns).
ROW: EQU 25 ; Number of rows on display screen.
SCRNSZ: EQU COLW * ROW ; Total size, in bytes, of the screen display area.
MODE80C:EQU 0
INCLUDE "1z-013a.asm"

View File

@@ -0,0 +1,7 @@
; Configurable parameters.
COLW: EQU 80 ; Width of the display screen (ie. columns).
ROW: EQU 25 ; Number of rows on display screen.
SCRNSZ: EQU COLW * ROW ; Total size, in bytes, of the screen display area.
MODE80C:EQU 1
INCLUDE "1z-013a.asm"

View File

@@ -0,0 +1,8 @@
; Configurable parameters.
COLW: EQU 80 ; Width of the display screen (ie. columns).
ROW: EQU 25 ; Number of rows on display screen.
SCRNSZ: EQU COLW * ROW ; Total size, in bytes, of the screen display area.
SCRLW: EQU COLW / 8 ; Number of 8 byte regions in a line for hardware scroll.
MODE80C:EQU 1
INCLUDE "sa1510.asm"

View File

@@ -0,0 +1,8 @@
; Configurable parameters.
COLW: EQU 80 ; Width of the display screen (ie. columns).
ROW: EQU 25 ; Number of rows on display screen.
SCRNSZ: EQU COLW * ROW ; Total size, in bytes, of the screen display area.
SCRLW: EQU COLW / 8 ; Number of 8 byte regions in a line for hardware scroll.
MODE80C:EQU 1
INCLUDE "sa1510_hiload.asm"

8
asm/monitor_sa1510.asm Normal file
View File

@@ -0,0 +1,8 @@
; Configurable parameters.
COLW: EQU 40 ; Width of the display screen (ie. columns).
ROW: EQU 25 ; Number of rows on display screen.
SCRNSZ: EQU COLW * ROW ; Total size, in bytes, of the screen display area.
SCRLW: EQU COLW / 8 ; Number of 8 byte regions in a line for hardware scroll.
MODE80C:EQU 0
INCLUDE "sa1510.asm"

View File

@@ -0,0 +1,8 @@
; Configurable parameters.
COLW: EQU 40 ; Width of the display screen (ie. columns).
ROW: EQU 25 ; Number of rows on display screen.
SCRNSZ: EQU COLW * ROW ; Total size, in bytes, of the screen display area.
SCRLW: EQU COLW / 8 ; Number of 8 byte regions in a line for hardware scroll.
MODE80C:EQU 0
INCLUDE "sa1510_hiload.asm"

9272
asm/msbasic.asm Normal file

File diff suppressed because it is too large Load Diff

371
asm/mz80afi.asm Normal file
View File

@@ -0,0 +1,371 @@
; Disassembly of the file "D:\MZ80AFI.BIN"
;
; CPU Type: Z80
;
; Using the opcode map file "D:\DZ80-INI.MAP"
; ; Created with dZ80 2.0
;
; on Thursday, 06 of February 2020 at 01:38 PM
;
i ; Bring in additional resources.
INCLUDE "rfs_definitions.asm"
INCLUDE "macros.asm"
;======================================
;
; Floppy Disk Interface
;
;======================================
ORG 0E800H
FLOPPY: NOP
LD DE,01008H
LD HL,PRMBLK
LD BC,0000BH
LDIR
CALL L0151
L000F: CALL NL
LD DE,BOOTDRV
CALL MSG
LD DE,011A3H
CALL GETL
LD A,(DE)
CP 01BH
JP Z,SS
LD HL,0000CH
ADD HL,DE
LD A,(HL)
CP 00DH
JR Z,L003A ; (+00dh)
CALL 03F9H
JR C,L000F ; (-023h)
DEC A
CP 004H
JR NC,L000F ; (-028h)
LD (01008H),A
L003A: LD IX,01008H
CALL L01BA
LD HL,0CE00H
LD DE,DSKID
LD B,007H
L0049: LD C,(HL)
LD A,(DE)
CP C
JP NZ,L008C
INC HL
INC DE
DJNZ L0049 ; (-00ah)
CALL NL
LD DE,IPLLOAD
CALL MSG
LD DE,0CE07H
CALL MSG
LD HL,(0CE16H)
LD (IX+005H),L
LD (IX+006H),H
LD HL,(0CE14H)
LD (IX+003H),L
LD (IX+004H),H
LD HL,(0CE1EH)
LD (IX+001H),L
LD (IX+002H),H
CALL L01BA
CALL L0151
LD HL,(0CE18H)
JP (HL)
L0087: LD DE,LOADERR
JR L008F ; (+003h)
L008C: LD DE,DSKNOTMST
L008F: CALL NL
CALL MSG
CALL NL
LD DE,DSKDAT
CALL MELDY
JP SS
BOOTDRV: DB "BOOY DRIVE ?", 00DH
LOADERR: DB "LOADING ERROR", 00DH
IPLLOAD: DB "IPL IS LOADING ", 00DH
DSKID: DB 002H, "IPLPRO"
DSKDAT: DB "A0", 0D7H, "ARA", 0D7H, "AR", 00DH
PRMBLK: DB 000H, 000H, 000H, 000H, 001H, 000H, 0CEH, 000H, 000H, 000H, 000H
DSKNOTMST: DB "THIS DISKETTE IS NOT MASTER", 00Dh
L0104: LD A,(01001H)
RRCA
CALL NC,L0138
LD A,(IX+000H)
OR 084H
OUT (0DCH),A
XOR A
LD (01000H),A
LD HL,00000H
L0119: DEC HL
LD A,H
OR L
JP Z,L029D
IN A,(0D8H)
CPL
RLCA
JR C,L0119 ; (-00ch)
LD C,(IX+000H)
LD HL,01002H
LD B,000H
ADD HL,BC
BIT 0,(HL)
JR NZ,L0137 ; (+005h)
CALL L0164
SET 0,(HL)
L0137: RET
L0138: LD A,080H
OUT (0DCH),A
LD B,010H
L013E: CALL L02C7
DJNZ L013E ; (-005h)
LD A,001H
LD (01001H),A
RET
L0149: LD A,01BH
CALL L0171
AND 099H
RET
L0151: XOR A
OUT (0DCH),A
LD (01002H),A
LD (01003H),A
LD (01004H),A
LD (01005H),A
LD (01001H),A
RET
L0164: LD A,00BH
CALL L0171
AND 085H
XOR 004H
RET Z
JP L029D
L0171: LD (01000H),A
CPL
OUT (0D8H),A
CALL L017E
IN A,(0D8H)
CPL
RET
L017E: PUSH DE
PUSH HL
CALL L02C0
LD E,007H
L0185: LD HL,00000H
L0188: DEC HL
LD A,H
OR L
JR Z,L0196 ; (+009h)
IN A,(0D8H)
CPL
RRCA
JR C,L0188 ; (-00bh)
POP HL
POP DE
RET
L0196: DEC E
JR NZ,L0185 ; (-014h)
JP L029D
L019C: PUSH DE
PUSH HL
CALL L02C0
LD E,007H
L01A3: LD HL,00000H
L01A6: DEC HL
LD A,H
OR L
JR Z,L01B4 ; (+009h)
IN A,(0D8H)
CPL
RRCA
JR NC,L01A6 ; (-00bh)
POP HL
POP DE
RET
L01B4: DEC E
JR NZ,L01A3 ; (-014h)
JP L029D
L01BA: CALL L0220
L01BD: CALL L0229
L01C0: CALL L0249
CALL L0149
JR NZ,L0216 ; (+04eh)
CALL L0259
PUSH IX
LD IX,L03FE
LD IY,L01DF
DI
LD A,094H
CALL L028A
L01DB: LD B,000H
JP (IX)
L01DF: INI
JP NZ,L03FE
POP IX
INC (IX+008H)
LD A,(IX+008H)
PUSH IX
LD IX,L03FE
CP 011H
JR Z,L01FB ; (+005h)
DEC D
JR NZ,L01DB ; (-01eh)
JR L01FC ; (+001h)
L01FB: DEC D
L01FC: CALL L0294
CALL L02D2
POP IX
IN A,(0D8H)
CPL
AND 0FFH
JR NZ,L0216 ; (+00bh)
CALL L0278
JP Z,L021B
LD A,(IX+007H)
JR L01C0 ; (-056h)
L0216: CALL L026A
JR L01BD ; (-05eh)
L021B: LD A,080H
OUT (0DCH),A
RET
L0220: CALL L02A3
LD A,00AH
LD (01006H),A
RET
L0229: CALL L0104
LD D,(IX+004H)
LD A,(IX+003H)
OR A
JR Z,L0236 ; (+001h)
INC D
L0236: LD A,(IX+00AH)
LD (IX+008H),A
LD A,(IX+009H)
LD (IX+007H),A
LD L,(IX+005H)
LD H,(IX+006H)
RET
L0249: SRL A
CPL
OUT (0DBH),A
JR NC,L0254 ; (+004h)
LD A,001H
JR L0255 ; (+001h)
L0254: XOR A
L0255: CPL
OUT (0DDH),A
RET
L0259: LD C,0DBH
LD A,(IX+007H)
SRL A
CPL
OUT (0D9H),A
LD A,(IX+008H)
CPL
OUT (0DAH),A
RET
L026A: LD A,(01006H)
DEC A
LD (01006H),A
JP Z,L029D
CALL L0164
RET
L0278: LD A,(IX+008H)
CP 011H
JR NZ,L0287 ; (+008h)
LD A,001H
LD (IX+008H),A
INC (IX+007H)
L0287: LD A,D
OR A
RET
L028A: LD (01000H),A
CPL
OUT (0D8H),A
CALL L019C
RET
L0294: LD A,0D8H
CPL
OUT (0D8H),A
CALL L017E
RET
L029D: CALL L0151
JP L0087
L02A3: LD B,000H
LD DE,00010H
LD L,(IX+001H)
LD H,(IX+002H)
XOR A
L02AF: SBC HL,DE
JR C,L02B6 ; (+003h)
INC B
JR L02AF ; (-007h)
L02B6: ADD HL,DE
LD H,B
INC L
LD (IX+009H),H
LD (IX+00AH),L
RET
L02C0: PUSH DE
LD DE,00007H
JP L02CB
L02C7: PUSH DE
LD DE,01013H
L02CB: DEC DE
LD A,E
OR D
JR NZ,L02CB ; (-005h)
POP DE
RET
L02D2: PUSH AF
LD A,(0119CH)
CP 0F0H
JR NZ,L02DB ; (+001h)
EI
L02DB: POP AF
RET
ALIGN 0EBFDh
DB 0FFh
L03FE: JP (IY)
;DB 0DDH
; DB 0E9H
; Ensure we fill the entire 1K by padding with FF's.
ALIGN 0EFFDh
DB 0FFh
LF7FE: DB 0fDH
DB 0E9H

155
asm/ramcheck.asm Normal file
View File

@@ -0,0 +1,155 @@
LETNL: EQU 0006h
PRNTS: EQU 000Ch
PRNT: EQU 0012h
MSG: EQU 0015h
MONIT: EQU 0086h
PRTHL: EQU 03BAh
PRTHX: EQU 03C3h
DPCT: EQU 0DDCh
MSTART: EQU 1200h
ORG 10F0h
DB 01h ; Code Type, 01 = Machine Code.
DB "RAM TEST V1.0", 0Dh, 00h, 00h ; Title/Name (17 bytes).
DW MSTART - START ; Size of program.
DW START ; Load address of program.
DW START ; Exec address of program.
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h ; Comment (104 bytes).
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
ORG 01200h
START: LD DE,TITLE
CALL MSG
CALL LETNL
LD B, 20 ; Number of loops
LOOP: LD HL,MSTART ; Start of checked memory,
LD D,0CEh ; End memory check CE00
LOOP1: LD A,000h
CP L
JR NZ,LOOP1b
CALL PRTHL ; Print HL as 4digit hex.
LD A,0C4h ; Move cursor left.
LD E,004h ; 4 times.
LOOP1a: CALL DPCT
DEC E
JR NZ,LOOP1a
LOOP1b: INC HL
LD A,H
CP D ; Have we reached end of memory.
JR Z,LOOP3 ; Yes, exit.
LD A,(HL) ; Read memory location under test, ie. 0.
CPL ; Subtract, ie. FF - A, ie FF - 0 = FF.
LD (HL),A ; Write it back, ie. FF.
SUB (HL) ; Subtract written memory value from A, ie. should be 0.
JR NZ,LOOP2 ; Not zero, we have an error.
LD A,(HL) ; Reread memory location, ie. FF
CPL ; Subtract FF - FF
LD (HL),A ; Write 0
SUB (HL) ; Subtract 0
JR Z,LOOP1 ; Loop if the same, ie. 0
LOOP2: LD A,16h
CALL PRNT ; Print A
CALL PRTHX ; Print HL as 4 digit hex.
CALL PRNTS ; Print space.
XOR A
LD (HL),A
LD A,(HL) ; Get into A the failing bits.
CALL PRTHX ; Print A as 2 digit hex.
CALL PRNTS ; Print space.
LD A,0FFh ; Repeat but first load FF into memory
LD (HL),A
LD A,(HL)
CALL PRTHX ; Print A as 2 digit hex.
NOP
JR LOOP4
LOOP3: LD DE,OKCHECK
CALL MSG ; Print check message in DE
LD A,B ; Print loop count.
CALL PRTHX
LD DE,OKMSG
CALL MSG ; Print ok message in DE
DEC B
JR NZ,LOOP
LD DE,DONEMSG
CALL MSG ; Print check message in DE
JP MONIT
OKCHECK: DB 11h
DB "CHECK: ", 0Dh
OKMSG: DB "OK.", 0Dh
DONEMSG: DB 11h
DB "RAM TEST COMPLETE.", 0Dh
LOOP4: LD B,09h
CALL PRNTS ; Print space.
XOR A ; Zero A
SCF ; Set Carry
LOOP5: PUSH AF ; Store A and Flags
LD (HL),A ; Store 0 to bad location.
LD A,(HL) ; Read back
CALL PRTHX ; Print A as 2 digit hex.
CALL PRNTS ; Print space
POP AF ; Get back A (ie. 0 + C)
RLA ; Rotate left A. Bit LSB becomes Carry (ie. 1 first instance), Carry becomes MSB
DJNZ LOOP5 ; Loop if not zero, ie. print out all bit locations written and read to memory to locate bad bit.
XOR A ; Zero A, clears flags.
LD A,80h
LD B,08h
LOOP6: PUSH AF ; Repeat above but AND memory location with original A (ie. 80)
LD C,A ; Basically walk through all the bits to find which one is stuck.
LD (HL),A
LD A,(HL)
AND C
NOP
JR Z,LOOP8 ; If zero then print out the bit number
NOP
NOP
LD A,C
CPL
LD (HL),A
LD A,(HL)
AND C
JR NZ,LOOP8 ; As above, if the compliment doesnt yield zero, print out the bit number.
LOOP7: POP AF
RRCA
NOP
DJNZ LOOP6
JP MONIT
LOOP8: CALL LETNL ; New line.
LD DE,BITMSG ; BIT message
CALL MSG ; Print message in DE
LD A,B
DEC A
CALL PRTHX ; Print A as 2 digit hex, ie. BIT number.
CALL LETNL ; New line
LD DE,BANKMSG ; BANK message
CALL MSG ; Print message in DE
LD A,H
CP 50h ; 'P'
JR NC,LOOP9 ; Work out bank number, 1, 2 or 3.
LD A,01h
JR LOOP11
LOOP9: CP 90h
JR NC,LOOP10
LD A,02h
JR LOOP11
LOOP10: LD A,03h
LOOP11: CALL PRTHX ; Print A as 2 digit hex, ie. BANK number.
JR LOOP7
BITMSG: DB " BIT: ", 0Dh
BANKMSG: DB " BANK: ", 0Dh
TITLE: DB "SHARPMZ RAM TEST (C) P. SMART 2018", 0Dh, 00h

1347
asm/rfs.asm Normal file

File diff suppressed because it is too large Load Diff

536
asm/rfs_bank1.asm Normal file
View File

@@ -0,0 +1,536 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: rfs_bank1.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-2023 Philip Smart <philip.smart@net2net.org>
;-
;- History: July 2019 - Merged 2 utilities to create this compilation.
; 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.
;-
;--------------------------------------------------------------------------------------------------------
;- 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/>.
;--------------------------------------------------------------------------------------------------------
;============================================================
;
; USER ROM BANK 1 - Floppy Disk Controller functions.
;
;============================================================
ORG UROMADDR
;--------------------------------
; Common code spanning all banks.
;--------------------------------
NOP
LD B,16 ; If we read the bank control reset register 15 times then this will enable bank control and then the 16th read will reset all bank control registers to default.
ROMFS1_0: LD A,(BNKCTRLRST)
DJNZ ROMFS1_0 ; Apply the default number of coded latch reads to enable the bank control registers.
LD A,BNKCTRLDEF ; Set coded latch, SDCS high, BBMOSI to high and BBCLK to high which enables SDCLK.
LD (BNKCTRL),A
NOP
NOP
NOP
XOR A ; We shouldnt arrive here after a reset, if we do, select UROM bank 0
LD (BNKSELMROM),A
NOP
NOP
NOP
LD (BNKSELUSER),A ; and start up - ie. SA1510 Monitor - this occurs as User Bank 0 is enabled and the jmp to 0 is coded in it.
;
; No mans land... this should have switched to Bank 0 and at this point there is a jump to 00000H.
JP 00000H ; This is for safety!!
;------------------------------------------------------------------------------------------
; 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.
;------------------------------------------------------------------------------------------
ALIGN_NOPS UROMBSTBL
;
BKSW1to0: PUSH AF
LD A, ROMBANK1 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK0 ; Required bank to call.
JR BKSW1_0
BKSW1to1: PUSH AF
LD A, ROMBANK1 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK1 ; Required bank to call.
JR BKSW1_0
BKSW1to2: PUSH AF
LD A, ROMBANK1 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK2 ; Required bank to call.
JR BKSW1_0
BKSW1to3: PUSH AF
LD A, ROMBANK1 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK3 ; Required bank to call.
JR BKSW1_0
BKSW1to4: PUSH AF
LD A, ROMBANK1 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK4 ; Required bank to call.
JR BKSW1_0
BKSW1to5: PUSH AF
LD A, ROMBANK1 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK5 ; Required bank to call.
JR BKSW1_0
BKSW1to6: PUSH AF
LD A, ROMBANK1 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK6 ; Required bank to call.
JR BKSW1_0
BKSW1to7: PUSH AF
LD A, ROMBANK1 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK7 ; Required bank to call.
;
BKSW1_0: PUSH HL ; Place function to call on stack
LD HL, BKSWRET1 ; Place bank switchers return address on stack.
EX (SP),HL
LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it.
LD (BNKSELUSER), A ; Repeat the bank switch B times to enable the bank control register and set its value.
JP (HL) ; Jump to required function.
BKSWRET1: POP AF ; Get bank which called us.
LD (BNKSELUSER), A ; Return to that bank.
POP AF
RET
FDCCMD EQU 01000H
MOTON EQU 01001H
TRK0FD1 EQU 01002H
TRK0FD2 EQU 01003H
TRK0FD3 EQU 01004H
TRK0FD4 EQU 01005H
RETRIES EQU 01006H
BPARA EQU 01008H
;-------------------------------------------------------------------------------
; START OF FLOPPY DISK CONTROLLER FUNCTIONALITY
;-------------------------------------------------------------------------------
; Method to check if the floppy interface ROM is present and if it is, jump to its entry point.
;
FDCK: CALL FDCKROM ; Check to see if the Floppy ROM is present, exit if it isnt.
CALL Z,0F000h
RET ; JP CMDCMPEND
FDCKROM: LD A,(0F000h)
OR A
RET
FLOPPY: PUSH DE ; Preserve pointer to input buffer.
LD DE,BPARA ; Copy disk parameter block into RAM work area. (From)
LD HL,PRMBLK ; (To)
LD BC,0000BH ; 11 bytes of config data.
LDIR ; BC=0, HL=F0E8, DE=1013
POP DE ; init 1001-1005, port $DC mit $00
LD A,(DE) ; If not at the end of the line, then process as the boot disk number.
CP 00Dh ;
JR NZ,GETBOOTDSK ;
CALL DSKINIT ; Initialise disk and flags.
L000F: LD DE,MSGBOOTDRV ;
LD HL,PRINTMSG
CALL BKSW1to6
LD DE,011A3H ;
CALL GETL ;
LD A,(DE) ;
CP 01BH ; Check input value is in range 1-4.
JP Z,SS ;
LD HL,0000CH ;
ADD HL,DE ;
LD A,(HL) ;
CP 00DH ;
JR Z,L003A ;
GETBOOTDSK:CALL HEX ; Convert number to binary
JR C,L000F ; If illegal, loop back and re-prompt.
DEC A ;
CP 004H ; Check in range, if not loop back.
JR NC,L000F ;
LD (BPARA),A ; Store in parameter block.
L003A: LD IX,BPARA ; Point to drive number.,
CALL DSKREAD ; Read sector 1 of trk 0
LD HL,0CE00H ; Now compare the first 7 bytes of what was read to see if this is a bootable disk.
LD DE,DSKID ;
LD B,007H ;
L0049: LD C,(HL) ;
LD A,(DE) ;
CP C ;
JP NZ,L008C ; If NZ then this is not a master disk, ie not bootable, so error exit with message.
INC HL ;
INC DE ;
DJNZ L0049 ;
LD DE,MSGIPLLOAD ;
LD HL,PRINTMSG
CALL BKSW1to6
LD DE,0CE07H ; Program name stored at 8th byte in boot sector.
LD HL,PRTFN
CALL BKSW1to6
LD HL,(0CE16H) ; Get the load address
LD (IX+005H),L ; And store in parameter block at 100D/100E
LD (IX+006H),H ;
INC HL
DEC HL
JR NZ, NOTCPM ; If load address is 0 then where loading CPM.
; LD A,(MEMSW) ; Page out ROM.
NOTCPM: LD HL,(0CE14H) ; Get the size
LD (IX+003H),L ; And store in parameter block at 100B/100C
LD (IX+004H),H ;
LD HL,(0CE1EH) ; Get logical sector number
LD (IX+001H),L ; And store in parameter block at 1009/100A
LD (IX+002H),H ;
CALL DSKREAD ; Read the required data and store in memory.
CALL DSKINIT ; Reset the disk ready for next operation.
LD HL,(0CE18H) ; Get the execution address
JP (HL) ; And execute.
DSKLOADERR:LD DE,MSGLOADERR ; Loading error message
JR L008F ; (+003h)
L008C: LD DE,MSGDSKNOTMST ; This is not a boot/master disk message.
L008F: LD HL,PRINTMSG
CALL BKSW1to6
LD DE,ERRTONE ; Play error tone.
CALL MELDY
;
LD SP,(TMPSTACKP) ; Recover the correct stack pointer before exit.
RET ; JP SS
L0104: LD A,(MOTON) ; motor on flag
RRCA ; motor off?
CALL NC,DSKMOTORON ; yes, set motor on and wait
LD A,(IX+000H) ;drive no
OR 084H ;
OUT (0DCH),A ; Motor on for drive 0-3
XOR A ;
LD (FDCCMD),A ; clr latest FDC command byte
LD HL,00000H ;
L0119: DEC HL ;
LD A,H ;
OR L ;
JP Z,DSKERR ; Reset and print message that this is not a bootable disk.
IN A,(0D8H) ; Status register.
CPL ;
RLCA ;
JR C,L0119 ; Wait on motor off (bit 7)
LD C,(IX+000H) ; Drive number
LD HL,TRK0FD1 ; 1 track 0 flag for each drive
LD B,000H ;
ADD HL,BC ; Compute related flag 1002/1003/1004/1005
BIT 0,(HL) ;
JR NZ,L0137 ;
CALL DSKSEEKTK0 ; Seek track 0.
SET 0,(HL) ; Set bit 0 of trk 0 flag
L0137: RET
; Turn disk motor on.
DSKMOTORON:LD A,080H
OUT (0DCH),A ; Motor on
LD B,010H ;
L013E: CALL L02C7 ;
DJNZ L013E ; Wait until becomes ready.
LD A,001H ; Set motor on flag.
LD (MOTON),A ;
RET
L0149: LD A,01BH
CALL DSKCMD
AND 099H
RET
; Initialise drive and reset flags, Set motor off
DSKINIT: XOR A
OUT (0DCH),A ; Motor on/off
LD (TRK0FD1),A ; Track 0 flag drive 1
LD (TRK0FD2),A ; Track 0 flag drive 2
LD (TRK0FD3),A ; Track 0 flag drive 3
LD (TRK0FD4),A ; Track 0 flag drive 4
LD (MOTON),A ; Motor on flag
RET
DSKSEEKTK0:LD A,00BH ; Restore command, seek track 0.
CALL DSKCMD ; Send command to FDC.
AND 085H ; Process result.
XOR 004H
RET Z
JP DSKERR
DSKCMD: LD (FDCCMD),A ; Store latest FDC command.
CPL ; Compliment it (FDC bit value is reversed).
OUT (0D8H),A ; Send command to FDC.
CALL L017E ; Wait to become ready.
IN A,(0D8H) ; Get status register.
CPL ; Inverse (FDC is reverse bit logic).
RET
L017E: PUSH DE
PUSH HL
CALL L02C0
LD E,007H
L0185: LD HL,00000H
L0188: DEC HL
LD A,H
OR L
JR Z,L0196 ; (+009h)
IN A,(0D8H)
CPL
RRCA
JR C,L0188 ; (-00bh)
POP HL
POP DE
RET
L0196: DEC E
JR NZ,L0185 ; (-014h)
JP DSKERR
L019C: PUSH DE
PUSH HL
CALL L02C0
LD E,007H
L01A3: LD HL,00000H
L01A6: DEC HL
LD A,H
OR L
JR Z,L01B4 ; (+009h)
IN A,(0D8H)
CPL
RRCA
JR NC,L01A6 ; (-00bh)
POP HL
POP DE
RET
L01B4: DEC E
JR NZ,L01A3 ; (-014h)
JP DSKERR
; Read disk starting at the first logical sector in param block 1009/100A
; Continue reading for the given size 100B/100C and store in the location
; Pointed to by the address stored in the parameter block. 100D/100E
DSKREAD: CALL L0220 ; Compute logical sector-no to track-no & sector-no, retries=10
L01BD: CALL L0229 ; Set current track & sector, get load address to HL
L01C0: CALL L0249 ; Set side reg
CALL L0149 ; Command 1b output (seek)
JR NZ,L0216 ;
CALL L0259 ; Set track & sector reg
PUSH IX ; Save 1008H
LD IX, 0F3FEH ; As below. L03FE
LD IY,L01DF ; Read sector into memory.
;DI
LD A,094H ; Latest FDC command byte
CALL L028A
L01DB: LD B,000H
JP (IX)
; Get data from disk sector to staging area (CE00).
L01DF: INI
LD A,(DE) ; If not at the end of the line, then process as the boot disk number.
JP NZ, 0F3FEH ; This is crucial, as the Z80 is running at 2MHz it is not fast enough so needs
; hardware acceleration in the form of a banked ROM, if disk not ready jumps to IX, if
; data ready, jumps to IY. L03FE
POP IX
INC (IX+008H) ; Increment current sector number
LD A,(IX+008H) ; Load current sector number
PUSH IX ; Save 1008H
LD IX, 0F3FEH ; As above. L03FE
CP 011H ; Sector 17? Need to loop to next track.
JR Z,L01FB
DEC D
JR NZ,L01DB
JR L01FC ; (+001h)
L01FB: DEC D
L01FC: CALL L0294
CALL L02D2
POP IX
IN A,(0D8H)
CPL
AND 0FFH
JR NZ,L0216 ; (+00bh)
CALL L0278
JP Z,L021B
LD A,(IX+007H)
JR L01C0 ; (-056h)
L0216: CALL L026A
JR L01BD ; (-05eh)
L021B: LD A,080H
OUT (0DCH),A ; Motor on
RET
L0220: CALL L02A3 ; compute logical sector no to track no & sector no
LD A,00AH ; 10 retries
LD (RETRIES),A
RET
; Set current track & sector, get load address to HL
L0229: CALL L0104
LD D,(IX+004H) ; Number of sectors to read
LD A,(IX+003H) ; Bytes to read
OR A ; 0?
JR Z,L0236 ; Yes
INC D ; Number of sectors to read + 1
L0236: LD A,(IX+00AH) ; Start sector number
LD (IX+008H),A ; To current sector number
LD A,(IX+009H) ; Start track number
LD (IX+007H),A ; To current track number
LD L,(IX+005H) ; Load address low byte
LD H,(IX+006H) ; Load address high byte
RET
; Compute side/head.
L0249: SRL A ; Track number even?
CPL ;
OUT (0DBH),A ; Output track no.
JR NC,L0254 ; Yes, even, set side/head 1
LD A,001H ; No, odd, set side/head 0
JR L0255
; Set side/head register.
L0254: XOR A ; Side 0
L0255: CPL ; Side 1
OUT (0DDH),A ; Side/head register.
RET
; Set track and sector register.
L0259: LD C,0DBH
LD A,(IX+007H) ; Current track number
SRL A
CPL
OUT (0D9H),A ; Track reg
LD A,(IX+008H) ; Current sector number
CPL
OUT (0DAH),A ; Sector reg
RET
L026A: LD A,(RETRIES)
DEC A
LD (RETRIES),A
JP Z,DSKERR
CALL DSKSEEKTK0
RET
L0278: LD A,(IX+008H)
CP 011H
JR NZ,L0287 ; (+008h)
LD A,001H
LD (IX+008H),A
INC (IX+007H)
L0287: LD A,D
OR A
RET
L028A: LD (FDCCMD),A
CPL
OUT (0D8H),A
CALL L019C
RET
L0294: LD A,0D8H
CPL
OUT (0D8H),A
CALL L017E
RET
DSKERR: CALL DSKINIT
JP DSKLOADERR
; Logical sector number to physical track and sector.
L02A3: LD B,000H
LD DE,00010H ; No of sectors per trk (16)
LD L,(IX+001H) ; Logical sector number
LD H,(IX+002H) ; 2 bytes in length
XOR A
L02AF: SBC HL,DE ; Subtract 16 sectors/trk
JR C,L02B6 ; Yes, negative value
INC B ; Count track
JR L02AF ; Loop
L02B6: ADD HL,DE ; Reset HL to the previous
LD H,B ; Track
INC L ; Correction +1
LD (IX+009H),H ; Start track no
LD (IX+00AH),L ; Start sector no
RET
L02C0: PUSH DE
LD DE,00007H
JP L02CB
L02C7: PUSH DE
LD DE,01013H
L02CB: DEC DE
LD A,E
OR D
JR NZ,L02CB ; (-005h)
POP DE
RET
L02D2: PUSH AF
LD A,(0119CH)
CP 0F0H
JR NZ,L02DB ; (+001h)
;EI
L02DB: POP AF
RET
;wait on bit 0 and bit 1 = 0 of state reg
L0300: IN A,(0D8H) ; State reg
RRCA
JR C,L0300 ; Wait on not busy
RRCA
JR C,L0300 ; Wait on data reg ready
JP (IY) ; to f1df
;-------------------------------------------------------------------------------
; END OF FLOPPY DISK CONTROLLER FUNCTIONALITY
;-------------------------------------------------------------------------------
;--------------------------------------
;
; Message table - Refer to bank 6 for
; all messages.
;
;--------------------------------------
; Error tone.
ERRTONE: DB "A0", 0D7H, "ARA", 0D7H, "AR", 00DH
; Identifier to indicate this is a valid boot disk
DSKID: DB 002H, "IPLPRO"
; Parameter block to indicate configuration and load area.
PRMBLK: DB 000H, 000H, 000H, 000H, 001H, 000H, 0CEH, 000H, 000H, 000H, 000H
; Ensure we fill the entire 2K by padding with FF's.
ALIGN 0EBFDh
DB 0FFh
L03FE: JP (IY)
ALIGN 0EFF8h
ORG 0EFF8h
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh

1605
asm/rfs_bank2.asm Normal file

File diff suppressed because it is too large Load Diff

548
asm/rfs_bank3.asm Normal file
View File

@@ -0,0 +1,548 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: rfs_bank3.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-2023 Philip Smart <philip.smart@net2net.org>
;-
;- History: July 2019 - Merged 2 utilities to create this compilation.
; 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.
;-
;--------------------------------------------------------------------------------------------------------
;- 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/>.
;--------------------------------------------------------------------------------------------------------
ROW EQU 25
COLW EQU 40
SCRNSZ EQU COLW * ROW
MODE80C EQU 0
;===========================================================
;
; USER ROM BANK 3 - Monitor memory utilities.
;
;===========================================================
ORG UROMADDR
;--------------------------------
; Common code spanning all banks.
;--------------------------------
NOP
LD B,16 ; If we read the bank control reset register 15 times then this will enable bank control and then the 16th read will reset all bank control registers to default.
ROMFS3_0: LD A,(BNKCTRLRST)
DJNZ ROMFS3_0 ; Apply the default number of coded latch reads to enable the bank control registers.
LD A,BNKCTRLDEF ; Set coded latch, SDCS high, BBMOSI to high and BBCLK to high which enables SDCLK.
LD (BNKCTRL),A
NOP
NOP
NOP
XOR A ; We shouldnt arrive here after a reset, if we do, select UROM bank 0
LD (BNKSELMROM),A
NOP
NOP
NOP
LD (BNKSELUSER),A ; and start up - ie. SA1510 Monitor - this occurs as User Bank 0 is enabled and the jmp to 0 is coded in it.
;
; No mans land... this should have switched to Bank 0 and at this point there is a jump to 00000H.
JP 00000H ; This is for safety!!
;------------------------------------------------------------------------------------------
; 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.
;------------------------------------------------------------------------------------------
ALIGN_NOPS UROMBSTBL
;
BKSW3to0: PUSH AF
LD A, ROMBANK3 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK0 ; Required bank to call.
JR BKSW3_0
BKSW3to1: PUSH AF
LD A, ROMBANK3 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK1 ; Required bank to call.
JR BKSW3_0
BKSW3to2: PUSH AF
LD A, ROMBANK3 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK2 ; Required bank to call.
JR BKSW3_0
BKSW3to3: PUSH AF
LD A, ROMBANK3 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK3 ; Required bank to call.
JR BKSW3_0
BKSW3to4: PUSH AF
LD A, ROMBANK3 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK4 ; Required bank to call.
JR BKSW3_0
BKSW3to5: PUSH AF
LD A, ROMBANK3 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK5 ; Required bank to call.
JR BKSW3_0
BKSW3to6: PUSH AF
LD A, ROMBANK3 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK6 ; Required bank to call.
JR BKSW3_0
BKSW3to7: PUSH AF
LD A, ROMBANK3 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK7 ; Required bank to call.
;
BKSW3_0: PUSH HL ; Place function to call on stack
LD HL, BKSWRET3 ; Place bank switchers return address on stack.
EX (SP),HL
LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it.
LD (BNKSELUSER), A ; Repeat the bank switch B times to enable the bank control register and set its value.
JP (HL) ; Jump to required function.
BKSWRET3: POP AF ; Get bank which called us.
LD (BNKSELUSER), A ; Return to that bank.
POP AF
RET
;-------------------------------------------------------------------------------
; START OF TAPE/SD CMDLINE TOOLS FUNCTIONALITY
;-------------------------------------------------------------------------------
; Method to copy an application on a tape to an SD stored application. The tape drive is read and the first
; encountered program is loaded into memory at 0x1200. The CMT header is populated with the correct details (even if
; the load address isnt 0x1200, the CMT Header contains the correct value).
; A call is then made to write the application to the SD card.
;
TAPE2SD: ; Load from tape into memory, filling the tape CMT header and loading data into location 0x1200.
LD HL,LOADTAPECP ; Call the Loadtape command, non execute version to get the tape contents into memory.
CALL BKSW3to4
LD A,(RESULT)
OR A
JR NZ,TAPE2SDERR
; Save to SD Card.
LD HL,SAVESDCARDX
CALL BKSW3to2
LD A,(RESULT)
OR A
JR NZ,TAPE2SDERR
LD DE,MSGT2SDOK
JR TAPE2SDERR2
TAPE2SDERR: LD DE,MSGT2SDERR
TAPE2SDERR2:LD HL,PRINTMSG
CALL BKSW3to6
RET
; Method to copy an SD stored application to a Cassette tape in the CMT.
; The directory entry number or filename is passed to the command and the entry is located within the SD
; directory structure. The file is then loaded into memory and the CMT header populated. A call is then made
; to write out the data to tap.
;
SD2TAPE: ; Load from SD, fill the CMT header then call CMT save.
LD HL,LOADSDCP
CALL BKSW3to2
LD A,(RESULT)
OR A
JR NZ,SD2TAPEERR
LD HL,SAVECMT
CALL BKSW3to4
LD A,(RESULT)
OR A
JR NZ,SD2TAPEERR
RET
SD2TAPEERR: LD DE,MSGSD2TERR
JR TAPE2SDERR2
RET
;-------------------------------------------------------------------------------
; END OF TAPE/SD CMDLINE TOOLS FUNCTIONALITY
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; START OF MEMORY CMDLINE TOOLS FUNCTIONALITY
;-------------------------------------------------------------------------------
;
; Memory correction
; command 'M'
;
MCORX: CALL READ4HEX ; correction address
RET C
MCORX1: CALL NLPHL ; corr. adr. print
CALL SPHEX ; ACC ASCII display
CALL PRNTS ; space print
LD DE,BUFER ; Input the data.
CALL GETL
LD A,(DE)
CP 01Bh ; If . pressed, exit.
RET Z
PUSH HL
POP BC
CALL HLHEX ; If the existing address is no longer hex, reset. HLASCII(DE). If it is hex, take as the address to store data into.
JR C,MCRX3 ; Line is corrupted as the address is no longer in Hex, reset.
INC DE
INC DE
INC DE
INC DE
INC DE ;
CALL _2HEX ; Get value entered.
JR C,MCORX1 ; Not hex, reset.
CP (HL) ; Not same as memory, reset.
JR NZ,MCORX1
INC DE ;
LD A,(DE) ; Check if no data just CR, if so, move onto next address.
CP 00Dh ; not correction
JR Z,MCRX2
CALL _2HEX ; Get the new entered data. ACCHL(ASCII)
JR C,MCORX1 ; New data not hex, reset.
LD (HL),A ; data correct so store.
MCRX2: INC HL
JR MCORX1
MCRX3: LD H,B ; memory address
LD L,C
JR MCORX1
; Memory copy command 'CPY'
; Parameters: XXXYYYZZZ - XXXX = Source, YYYY = Destination, ZZZZ = Size
MCOPY: CALL READ4HEX ; Source
JR C,MCOPYER1
PUSH HL
CALL READ4HEX ; Destination
JR C,MCOPYER2
PUSH HL
CALL READ4HEX ; Size
JR C,MCOPYER3
PUSH HL
POP BC ; Size
POP DE ; Destination
POP HL ; Source
LDIR
RET
;
MCOPYER3: POP HL
MCOPYER2: POP HL
MCOPYER1: RET
; Dump method when called interbank as HL cannot be passed.
;
; BC = Start
; DE = End
DUMPBC: PUSH BC
POP HL
JR DUMP
; Command line utility to dump memory.
; Get start and optional end addresses from the command line, ie. XXXX[XXXX]
; Paging is implemented, 23 lines at a time, pressing U goes back 100H, pressing D scrolls down 100H
;
DUMPX: CALL HLHEX ; Get start address if present into HL
JR NC,DUMPX1
LD DE,(DUMPADDR) ; Setup default start and end.
JR DUMPX2
DUMPX1: INC DE
INC DE
INC DE
INC DE
PUSH HL
CALL HLHEX ; Get end address if present into HL
POP DE ; DE = Start address
JR NC,DUMPX4 ; Both present? Then display.
DUMPX2: LD A,(SCRNMODE)
OR A
LD HL,000A0h ; Make up an end address based on 160 bytes from start for 40 column mode.
JR Z,DUMPX3
LD HL,00140h ; Make up an end address based on 320 bytes from start for 80 column mode.
DUMPX3: ADD HL,DE
DUMPX4: EX DE,HL
;
; HL = Start
; DE = End
DUMP: LD A,23
DUMP0: LD (TMPCNT),A
LD A,(SCRNMODE) ; Configure output according to screen mode, 40/80 chars.
OR A
JR NZ,DUMP1
LD B,008H ; 40 Char, output 23 lines of 40 char.
LD C,017H
JR DUMP2
DUMP1: LD B,010h ; 80 Char, output 23 lines of 80 char.
LD C,02Fh
DUMP2: CALL NLPHL
DUMP3: CALL SPHEX
INC HL
PUSH AF
LD A,(DSPXY)
ADD A,C
LD (DSPXY),A
POP AF
CP 020h
JR NC,DUMP4
LD A,02Eh
DUMP4: CALL ?ADCN
CALL PRNT3
LD A,(DSPXY)
INC C
SUB C
LD (DSPXY),A
DEC C
DEC C
DEC C
PUSH HL
SBC HL,DE
POP HL
JR NC,DUMP9
DUMP5: DJNZ DUMP3
LD A,(TMPCNT)
DEC A
JR NZ,DUMP0
DUMP6: CALL GETKY ; Pause, X to quit, D to go down a block, U to go up a block.
OR A
JR Z,DUMP6
CP 'D'
JR NZ,DUMP7
LD A,8
JR DUMP0
DUMP7: CP 'U'
JR NZ,DUMP8
PUSH DE
LD DE,00100H
OR A
SBC HL,DE
POP DE
LD A,8
JR DUMP0
DUMP8: CP 'X'
JR Z,DUMP9
JR DUMP
DUMP9: LD (DUMPADDR),HL ; Store last address so we can just press D for next page,
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
LD HL,PRINTMSG
CALL BKSW1to6
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
; Method to get the CMT parameters from the command line.
; The parameters which should be given are:
; XXXXYYYYZZZZ - where XXXX = Start Address, YYYY = End Address, ZZZZ = Execution Address.
; If the start, end and execution address parameters are correct, prompt for a filename which will be written into the CMT header.
; Output: Reg C = 0 - Success
; = 1 - Error.
GETCMTPARM: CALL READ4HEX ; Start address
JR C,GETCMT1
LD (DTADR),HL ; data adress buffer
LD B,H
LD C,L
CALL READ4HEX ; End address
JR C,GETCMT1
SBC HL,BC
INC HL
LD (SIZE),HL ; byte size buffer
CALL READ4HEX ; Execution address
JR C,GETCMT1
LD (EXADR),HL ; buffer
CALL NL
LD DE,MSGSAVE ; 'FILENAME? '
LD HL,PRINTMSG
CALL BKSW2to6 ; Print out the filename.
LD DE,BUFER
CALL GETL
LD HL,BUFER+10
LD DE,NAME ; name buffer
LD BC,FNSIZE
LDIR ; C = 0 means success.
RET
GETCMT1: LD C,1 ; C = 1 means an error occured.
RET
; Method to read 4 bytes from a buffer pointed to by DE and attempt to convert to a 16bit number. If it fails, print out an error
; message and return with C set.
;
; Input: DE = Address of digits to conver.
; Output: HL = 16 bit number.
READ4HEX: CALL HLHEX
JR C,READ4HEXERR
INC DE
INC DE
INC DE
INC DE
OR A ; Clear carry flag.
RET
READ4HEXERR:LD DE,MSGREAD4HEX ; Load up error message, print and exit.
READ4HEXPRE:LD HL,PRINTMSG
CALL BKSW1to6
SCF
RET
; SPACE PRINT AND DISP ACC
; INPUT:HL=DISP. ADR.
SPHEX: CALL PRNTS ; SPACE PRINT
LD A,(HL)
CALL PRTHX ; DSP OF ACC (ASCII)
LD A,(HL)
RET
; NEW LINE AND PRINT HL REG (ASCII)
NLPHL: CALL NL
CALL PRTHL
RET
;-------------------------------------------------------------------------------
; END OF MEMORY CMDLINE TOOLS FUNCTIONALITY
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; START OF PRINTER CMDLINE TOOLS FUNCTIONALITY
;-------------------------------------------------------------------------------
PTESTX: LD A,(DE)
CP '&' ; plotter test
JR NZ,PTST1X
PTST0X: INC DE
LD A,(DE)
CP 'L' ; 40 in 1 line
JR Z,.LPTX
CP 'S' ; 80 in 1 line
JR Z,..LPTX
CP 'C' ; Pen change
JR Z,PENX
CP 'G' ; Graph mode
JR Z,PLOTX
CP 'T' ; Test
JR Z,PTRNX
;
PTST1X: CALL PMSGX
ST1X2: RET
.LPTX: LD DE,LLPT ; 01-09-09-0B-0D
JR PTST1X
..LPTX: LD DE,SLPT ; 01-09-09-09-0D
JR PTST1X
PTRNX: LD A,004h ; Test pattern
JR LE999
PLOTX: LD A,002h ; Graph mode
LE999: CALL LPRNTX
JR PTST0X
PENX: LD A,01Dh ; 1 change code (text mode)
JR LE999
;
;
; 1 char print to $LPT
;
; in: ACC print data
;
;
LPRNTX: LD C,000h ; RDAX test
LD B,A ; print data store
CALL RDAX
LD A,B
OUT (0FFh),A ; data out
LD A,080h ; RDP high
OUT (0FEh),A
LD C,001h ; RDA test
CALL RDAX
XOR A ; RDP low
OUT (0FEh),A
RET
;
; $LPT msg.
; in: DE data low address
; 0D msg. end
;
PMSGX: PUSH DE
PUSH BC
PUSH AF
PMSGX1: LD A,(DE) ; ACC = data
CALL LPRNTX
LD A,(DE)
INC DE
CP 00Dh ; end ?
JR NZ,PMSGX1
POP AF
POP BC
POP DE
RET
;
; RDA check
;
; BRKEY in to monitor return
; in: C RDA code
;
RDAX: IN A,(0FEh)
AND 00Dh
CP C
RET Z
CALL BRKEY
JR NZ,RDAX
LD SP,ATRB
JR ST1X2
; 40 CHA. IN 1 LINE CODE (DATA)
LLPT: DB 01H ; TEXT MODE
DB 09H
DB 09H
DB 0BH
DB 0DH
; 80 CHA. 1 LINE CODE (DATA)
SLPT: DB 01H ; TEXT MODE
DB 09H
DB 09H
DB 09H
DB 0DH
;-------------------------------------------------------------------------------
; END OF PRINTER CMDLINE TOOLS FUNCTIONALITY
;-------------------------------------------------------------------------------
;--------------------------------------
;
; Message table - Refer to bank 6 for
; all messages.
;
;--------------------------------------
ALIGN 0EFF8h
ORG 0EFF8h
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh

335
asm/rfs_bank4.asm Normal file
View File

@@ -0,0 +1,335 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: rfs_bank4.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-2023 Philip Smart <philip.smart@net2net.org>
;-
;- History: July 2019 - Merged 2 utilities to create this compilation.
; 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.
;-
;--------------------------------------------------------------------------------------------------------
;- 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/>.
;--------------------------------------------------------------------------------------------------------
;===========================================================
;
; USER ROM BANK 4 - CMT Controller utilities.
;
;===========================================================
ORG UROMADDR
;--------------------------------
; Common code spanning all banks.
;--------------------------------
NOP
LD B,16 ; If we read the bank control reset register 15 times then this will enable bank control and then the 16th read will reset all bank control registers to default.
ROMFS4_0: LD A,(BNKCTRLRST)
DJNZ ROMFS4_0 ; Apply the default number of coded latch reads to enable the bank control registers.
LD A,BNKCTRLDEF ; Set coded latch, SDCS high, BBMOSI to high and BBCLK to high which enables SDCLK.
LD (BNKCTRL),A
NOP
NOP
NOP
XOR A ; We shouldnt arrive here after a reset, if we do, select UROM bank 0
LD (BNKSELMROM),A
NOP
NOP
NOP
LD (BNKSELUSER),A ; and start up - ie. SA1510 Monitor - this occurs as User Bank 0 is enabled and the jmp to 0 is coded in it.
;
; No mans land... this should have switched to Bank 0 and at this point there is a jump to 00000H.
JP 00000H ; This is for safety!!
;------------------------------------------------------------------------------------------
; 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.
;------------------------------------------------------------------------------------------
ALIGN_NOPS UROMBSTBL
;
BKSW4to0: PUSH AF
LD A, ROMBANK4 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK0 ; Required bank to call.
JR BKSW4_0
BKSW4to1: PUSH AF
LD A, ROMBANK4 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK1 ; Required bank to call.
JR BKSW4_0
BKSW4to2: PUSH AF
LD A, ROMBANK4 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK2 ; Required bank to call.
JR BKSW4_0
BKSW4to3: PUSH AF
LD A, ROMBANK4 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK3 ; Required bank to call.
JR BKSW4_0
BKSW4to4: PUSH AF
LD A, ROMBANK4 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK4 ; Required bank to call.
JR BKSW4_0
BKSW4to5: PUSH AF
LD A, ROMBANK4 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK5 ; Required bank to call.
JR BKSW4_0
BKSW4to6: PUSH AF
LD A, ROMBANK4 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK6 ; Required bank to call.
JR BKSW4_0
BKSW4to7: PUSH AF
LD A, ROMBANK4 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK7 ; Required bank to call.
;
BKSW4_0: PUSH HL ; Place function to call on stack
LD HL, BKSWRET4 ; Place bank switchers return address on stack.
EX (SP),HL
LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it.
LD (BNKSELUSER), A ; Repeat the bank switch B times to enable the bank control register and set its value.
JP (HL) ; Jump to required function.
BKSWRET4: POP AF ; Get bank which called us.
LD (BNKSELUSER), A ; Return to that bank.
POP AF
RET
;-------------------------------------------------------------------------------
; START OF CMT CONTROLLER FUNCTIONALITY
;-------------------------------------------------------------------------------
; CMT Utility to Load a program from tape.
;
; Three entry points:
; LOADTAPE = Load the first program shifting to lo memory if required and execute.
; LOADTAPENX = Load the first program and return without executing.
; LOADTAPECP = Load the first program to address 0x1200 and return.
;
LOADTAPECP: LD A,0FFH
LD (CMTAUTOEXEC),A
JR LOADTAPE2
LOADTAPENX: LD A,0FFH
JR LOADTAPE1
LOADTAPE: LD A,000H
LOADTAPE1: LD (CMTAUTOEXEC),A
XOR A
LOADTAPE2: LD (CMTCOPY),A ; Set cmt copy mode, 0xFF if we are copying.
LD A,0FFH ; If called interbank, set a result code in memory to detect success.
LD (RESULT),A
CALL ?RDI
JP C,?ERX2
LD DE,MSGLOAD ; 'LOADING '
LD BC,NAME
LD HL,PRINTMSG
CALL BKSW4to6
XOR A
LD (CMTLOLOAD),A
LD HL,(DTADR) ; Common code, store load address in case we shift or manipulate loading.
LD (DTADRSTORE),HL
LD A,(CMTCOPY) ; If were copying we always load at 0x1200.
OR A
JR Z,LOADTAPE3
LD HL,01200H
LD (DTADR),HL
LOADTAPE3: LD HL,(DTADR) ; If were loading and the load address is below 0x1200, shift it to 0x1200 to load then move into correct location.
LD A,H
OR L
JR NZ,LOADTAPE4
LD A,0FFh
LD (CMTLOLOAD),A
LD HL,01200h
LD (DTADR),HL
LOADTAPE4: CALL ?RDD
JP C,?ERX2
LD HL,(DTADRSTORE) ; Restore the original load address into the CMT header.
LD (DTADR),HL
LD A,(CMTCOPY)
OR A
JR NZ,LOADTAPE6
LOADTAPE5: LD A,(CMTAUTOEXEC) ; Get back the auto execute flag.
OR A
JR NZ,LOADTAPE6 ; Dont execute..
LD A,(CMTLOLOAD)
CP 0FFh
JR Z,LOADTAPELM ; Execute at low memory?
LD BC,00100h
LD HL,(EXADR)
JP (HL)
LOADTAPELM: LD A,(MEMSW) ; Perform memory switch, mapping out ROM from $0000 to $C000
LD HL,01200h ; Shift the program down to RAM at $0000
LD DE,00000h
LD BC,(SIZE)
LDIR
LD BC,00100h
LD HL,(EXADR) ; Fetch exec address and run.
JP (HL)
LOADTAPE6: LD DE,MSGCMTDATA
PUSH HL ; Load address as parameter 2.
LD HL,(EXADR)
PUSH HL ; Execution address as parameter 1.
LD BC,(SIZE) ; Size as BC parameter.
LD HL,PRINTMSG
CALL BKSW4to6
POP BC
POP BC ; Waste parameters.
XOR A ; Success.
LD (RESULT),A
RET
; SA1510 Routine to write a tape header. Copied into the RFS and modified to merge better
; with the RFS interface.
;
CMTWRI: ;DI
PUSH DE
PUSH BC
PUSH HL
LD D,0D7H
LD E,0CCH
LD HL,IBUFE
LD BC,00080H
CALL CKSUM
CALL MOTOR
JR C,CMTWRI2
LD A,E
CP 0CCH
JR NZ,CMTWRI1
PUSH HL
PUSH DE
PUSH BC
LD DE,MSGCMTWRITE
LD BC,NAME
LD HL,PRINTMSG
CALL BKSW4to6
POP BC
POP DE
POP HL
CMTWRI1: CALL GAP
CALL WTAPE
CMTWRI2: POP HL
POP BC
POP DE
CALL MSTOP
PUSH AF
LD A,(TIMFG)
CP 0F0H
JR NZ,CMTWRI3
;EI
CMTWRI3: POP AF
RET
; Method to save an application stored in memory to a cassette in the CMT. The start, size and execution address are either given in BUFER via the
; command line and the a filename is prompted for and read, or alternatively all the data is passed into the function already set in the CMT header.
; The tape is then opened and the header + data are written out.
;
SAVECMT: LD A,0FFH ; Set SDCOPY to indicate this is a copy command and not a command line save.
JR SAVEX1
;
; Normal entry point, the cmdline contains XXXXYYYYZZZZ where XXXX=start, YYYY=size, ZZZZ=exec addr. A filenname is prompted for and read.
; The data is stored in the CMT header prior to writing out the header and data..
;
SAVEX: LD HL,GETCMTPARM ; Get the CMT parameters.
CALL BKSW4to3
LD A,C
OR A
RET NZ ; Exit if an error occurred.
XOR A
SAVEX1: LD (SDCOPY),A
LD A,0FFH
LD (RESULT),A ; For interbank calls, pass result via a memory variable. Assume failure unless updated.
LD A,OBJCD ; Set attribute: OBJ
LD (ATRB),A
CALL CMTWRI ; Commence header write. Header doesnt need updating for header write.
?ERX1: JP C,?ERX2
LD A,(SDCOPY)
OR A
JR Z,SAVEX2
LD DE,(DTADR)
LD A,D ; If copying and address is below 1000H, then data is held at 1200H so update header for write.
CP 001H
JR NC,SAVEX2
LD DE,01200H
LD (DTADR),DE
SAVEX2: CALL ?WRD ; data
JR C,?ERX1
LD DE,MSGSAVEOK ; 'OK!'
LD HL,PRINTMSG
CALL BKSW4to6
LD A,0 ; Success.
LD (RESULT),A
RET
?ERX2: CP 002h
JR NZ,?ERX3
LD (RESULT),A ; Set break key pressed code.
RET Z
?ERX3: LD DE,MSGE1 ; 'CHECK SUM ER.'
LD HL,PRINTMSG
CALL BKSW4to6
RET
; Method to verify that a tape write occurred free of error. After a write, the tape is read and compared with the memory that created it.
;
VRFYX: CALL ?VRFY
JP C,?ERX2
LD DE,MSGOK ; 'OK!'
LD HL,PRINTMSG
CALL BKSW4to6
RET
; Method to toggle the audible key press sound, ie a beep when a key is pressed.
;
SGX: LD A,(SWRK)
RRA
CCF
RLA
LD (SWRK),A
RET
;-------------------------------------------------------------------------------
; END OF CMT CONTROLLER FUNCTIONALITY
;-------------------------------------------------------------------------------
;--------------------------------------
;
; Message table - Refer to bank 6 for
; all messages.
;
;--------------------------------------
ALIGN 0EFF8h
ORG 0EFF8h
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh

210
asm/rfs_bank5.asm Normal file
View File

@@ -0,0 +1,210 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: rfs_bank5.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-2023 Philip Smart <philip.smart@net2net.org>
;-
;- History: July 2019 - Merged 2 utilities to create this compilation.
; 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.
; Mar 2021 - Add mapping utilities for Sharp<->ASCII conversion.
;-
;--------------------------------------------------------------------------------------------------------
;- 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/>.
;--------------------------------------------------------------------------------------------------------
;======================================
;
; USER ROM BANK 5 - Utilities
;
;======================================
ORG UROMADDR
;--------------------------------
; Common code spanning all banks.
;--------------------------------
NOP
LD B,16 ; If we read the bank control reset register 15 times then this will enable bank control and then the 16th read will reset all bank control registers to default.
ROMFS5_0: LD A,(BNKCTRLRST)
DJNZ ROMFS5_0 ; Apply the default number of coded latch reads to enable the bank control registers.
LD A,BNKCTRLDEF ; Set coded latch, SDCS high, BBMOSI to high and BBCLK to high which enables SDCLK.
LD (BNKCTRL),A
NOP
NOP
NOP
XOR A ; We shouldnt arrive here after a reset, if we do, select UROM bank 0
LD (BNKSELMROM),A
NOP
NOP
NOP
LD (BNKSELUSER),A ; and start up - ie. SA1510 Monitor - this occurs as User Bank 0 is enabled and the jmp to 0 is coded in it.
;
; No mans land... this should have switched to Bank 0 and at this point there is a jump to 00000H.
JP 00000H ; This is for safety!!
;------------------------------------------------------------------------------------------
; 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.
;------------------------------------------------------------------------------------------
ALIGN_NOPS UROMBSTBL
;
BKSW5to0: PUSH AF
LD A, ROMBANK5 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK0 ; Required bank to call.
JR BKSW5_0
BKSW5to1: PUSH AF
LD A, ROMBANK5 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK1 ; Required bank to call.
JR BKSW5_0
BKSW5to2: PUSH AF
LD A, ROMBANK5 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK2 ; Required bank to call.
JR BKSW5_0
BKSW5to3: PUSH AF
LD A, ROMBANK5 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK3 ; Required bank to call.
JR BKSW5_0
BKSW5to4: PUSH AF
LD A, ROMBANK5 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK4 ; Required bank to call.
JR BKSW5_0
BKSW5to5: PUSH AF
LD A, ROMBANK5 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK5 ; Required bank to call.
JR BKSW5_0
BKSW5to6: PUSH AF
LD A, ROMBANK5 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK6 ; Required bank to call.
JR BKSW5_0
BKSW5to7: PUSH AF
LD A, ROMBANK5 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK7 ; Required bank to call.
;
BKSW5_0: PUSH HL ; Place function to call on stack
LD HL, BKSWRET5 ; Place bank switchers return address on stack.
EX (SP),HL
LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it.
LD (BNKSELUSER), A ; Repeat the bank switch B times to enable the bank control register and set its value.
JP (HL) ; Jump to required function.
BKSWRET5: POP AF ; Get bank which called us.
LD (BNKSELUSER), A ; Return to that bank.
POP AF
RET
; Method to convert a string with Sharp ASCII codes into standard ASCII codes via map lookup.
; Inputs: DE = pointer to string for conversion.
; B = Maximum number of characters to convert if string not terminated.
;
CNVSTR_SA: PUSH HL
PUSH DE
PUSH BC
CNVSTRSA1: LD A,(DE) ; Get character for conversion.
OR A ; Exit at End of String (NULL, CR)
JR Z,CNVSTRSAEX
CP 00DH
JR Z,CNVSTRSAEX
CP 020H ; No point mapping control characters.
JR C,CNVSTRSA2
;
LD HL,SHARPTOASC ; Start of mapping table.
PUSH BC
LD C,A
LD B,0
ADD HL,BC ; Add in character offset.
POP BC
LD A,(HL)
LD (DE),A ; Map character.
CNVSTRSA2: INC DE
DJNZ CNVSTRSA1
CNVSTRSAEX: POP BC ; Restore all registers used except AF.
POP DE
POP HL
RET
; Method to convert a string with standard ASCII into Sharp ASCII codes via scan lookup in the mapping table.
; Inputs: DE = pointer to string for conversion.
; B = Maximum number of characters to convert if string not terminated.
CNVSTR_AS: PUSH HL
PUSH DE
PUSH BC
CNVSTRAS1: LD A,(DE) ; Get character for conversion.
OR A ; Exit at End of String (NULL, CR)
JR Z,CNVSTRSAEX
CP 00DH
JR Z,CNVSTRSAEX
CP 020H ; No point mapping control characters.
JR C,CNVSTRAS5
LD HL,SHARPTOASC + 020H
PUSH BC
LD B, 0100H - 020H
CNVSTRAS2: CP (HL) ; Go through table looking for a match.
JR Z,CNVSTRAS3
INC HL
DJNZ CNVSTRAS2
JR CNVSTRAS4 ; No match then dont convert.
CNVSTRAS3: LD BC,SHARPTOASC ; On match or expiration of BC subtract table starting point to arrive at index.
OR A
SBC HL,BC
LD A,L ; Index is used as the converted character.
CNVSTRAS4: LD (DE),A
POP BC
CNVSTRAS5: INC DE
DJNZ CNVSTRAS1
JR CNVSTRSAEX
; Mapping table to convert between Sharp ASCII and standard ASCII.
; Sharp -> ASCII : Index with Sharp value into table to obtain conversion.
; ASCII -> Sharp : Scan into table looking for value, on match the idx is the conversion. NB 0x20 = 0x20.
SHARPTOASC: DB 000H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 000H, 020H, 020H ; 0x0F
DB 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H ; 0x1F
DB 020H, 021H, 022H, 023H, 024H, 025H, 026H, 027H, 028H, 029H, 02AH, 02BH, 02CH, 02DH, 02EH, 02FH ; 0x2F
DB 030H, 031H, 032H, 033H, 034H, 035H, 036H, 037H, 038H, 039H, 03AH, 03BH, 03CH, 03DH, 03EH, 03FH ; 0x3F
DB 040H, 041H, 042H, 043H, 044H, 045H, 046H, 047H, 048H, 049H, 04AH, 04BH, 04CH, 04DH, 04EH, 04FH ; 0x4F
DB 050H, 051H, 052H, 053H, 054H, 055H, 056H, 057H, 058H, 059H, 05AH, 05BH, 05CH, 05DH, 05EH, 05FH ; 0x5F
DB 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H ; 0x6F
DB 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H ; 0x7F
DB 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H ; 0x8F
DB 020H, 020H, 065H, 020H, 020H, 020H, 074H, 067H, 068H, 020H, 062H, 078H, 064H, 072H, 070H, 063H ; 0x9F
DB 071H, 061H, 07AH, 077H, 073H, 075H, 069H, 020H, 04FH, 06BH, 066H, 076H, 020H, 075H, 042H, 06AH ; 0xAF
DB 06EH, 020H, 055H, 06DH, 020H, 020H, 020H, 06FH, 06CH, 041H, 06FH, 061H, 020H, 079H, 020H, 020H ; 0xBF
DB 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H ; 0xCF
DB 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H ; 0xDF
DB 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H ; 0xEF
DB 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H, 020H ; 0xFF
ALIGN 0EFF8h
ORG 0EFF8h
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh

497
asm/rfs_bank6.asm Normal file
View File

@@ -0,0 +1,497 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: rfs_bank6.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-2023 Philip Smart <philip.smart@net2net.org>
;-
;- History: July 2019 - Merged 2 utilities to create this compilation.
; 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.
; 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.
;-
;--------------------------------------------------------------------------------------------------------
;- 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/>.
;--------------------------------------------------------------------------------------------------------
;======================================
;
; USER ROM BANK 6
;
;======================================
ORG UROMADDR
;--------------------------------
; Common code spanning all banks.
;--------------------------------
NOP
LD B,16 ; If we read the bank control reset register 15 times then this will enable bank control and then the 16th read will reset all bank control registers to default.
ROMFS6_0: LD A,(BNKCTRLRST)
DJNZ ROMFS6_0 ; Apply the default number of coded latch reads to enable the bank control registers.
LD A,BNKCTRLDEF ; Set coded latch, SDCS high, BBMOSI to high and BBCLK to high which enables SDCLK.
LD (BNKCTRL),A
NOP
NOP
NOP
XOR A ; We shouldnt arrive here after a reset, if we do, select UROM bank 0
LD (BNKSELMROM),A
NOP
NOP
NOP
LD (BNKSELUSER),A ; and start up - ie. SA1510 Monitor - this occurs as User Bank 0 is enabled and the jmp to 0 is coded in it.
;
; No mans land... this should have switched to Bank 0 and at this point there is a jump to 00000H.
JP 00000H ; This is for safety!!
;------------------------------------------------------------------------------------------
; 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.
;------------------------------------------------------------------------------------------
ALIGN_NOPS UROMBSTBL
;
BKSW6to0: PUSH AF
LD A, ROMBANK6 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK0 ; Required bank to call.
JR BKSW6_0
BKSW6to1: PUSH AF
LD A, ROMBANK6 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK1 ; Required bank to call.
JR BKSW6_0
BKSW6to2: PUSH AF
LD A, ROMBANK6 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK2 ; Required bank to call.
JR BKSW6_0
BKSW6to3: PUSH AF
LD A, ROMBANK6 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK3 ; Required bank to call.
JR BKSW6_0
BKSW6to4: PUSH AF
LD A, ROMBANK6 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK4 ; Required bank to call.
JR BKSW6_0
BKSW6to5: PUSH AF
LD A, ROMBANK6 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK5 ; Required bank to call.
JR BKSW6_0
BKSW6to6: PUSH AF
LD A, ROMBANK6 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK6 ; Required bank to call.
JR BKSW6_0
BKSW6to7: PUSH AF
LD A, ROMBANK6 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK7 ; Required bank to call.
;
BKSW6_0: PUSH HL ; Place function to call on stack
LD HL, BKSWRET6 ; Place bank switchers return address on stack.
EX (SP),HL
LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it.
LD (BNKSELUSER), A ; Repeat the bank switch B times to enable the bank control register and set its value.
JP (HL) ; Jump to required function.
BKSWRET6: POP AF ; Get bank which called us.
LD (BNKSELUSER), A ; Return to that bank.
POP AF
RET
;-------------------------------------------------------------------------------
; START OF PRINT ROUTINE METHODS
;-------------------------------------------------------------------------------
; Method to print out a true ASCII character, not the Sharp values. This is done using the mapping table ATBL for the
; range 0..127, 128.. call the original Sharp routine.
; Input: A = Ascii character.
PRINTASCII: PUSH HL
PUSH BC
CP 080H ; Anything above 080H isnt ascii so call original routine.
JR NC,PRINTASCII1
CP 00DH ; Carriage Return? Dont map just execute via original Sharp call.
JR Z,PRINTASCII1
LD HL,ATBL
LD C,A
LD B,0
ADD HL,BC
LD A,(HL)
CALL ?DSP
PRINTASCII0:POP BC
POP HL
RET
PRINTASCII1:CALL PRNT
JR PRINTASCII0
; Method to print out a string residing in this bank.
;
; As string messages take up space and banks are limited, it makes sense to locate all strings in one
; bank and print them out from here, hence this method.
;
; Also, as strings often require embedded values to be printed (aka printf), a basic mechanism for printing out stack
; parameters is provided. A PUSH before calling this method followed by an embedded marker (ie. 0xFF) will see the stack
; value printed in hex at the point in the string where the marker appears.
;
; Input: DE = Address, in this bank or any other location EXCEPT another bank.
; BC = Value to print with marker 0xFB if needed.
; Upto 4 stack values accessed by markers 0xFF, 0xFE, 0xFD, 0xFC
PRINTMSG: LD A,(DE)
CP 000H ; End of string?
RET Z
CP 0FFH ; Marker to print out first stack parameter.
JR Z,PRINTMSG3
CP 0FEH ; Marker to print out second stack parameter.
JR Z,PRINTMSG6
CP 0FDH ; Marker to print out third stack parameter.
JR Z,PRINTMSG7
CP 0FCH ; Marker to print out fourth stack parameter.
JR Z,PRINTMSG8
CP 0FBH ; Marker to print out BC.
JR Z,PRINTMSG9
CP 0FAH ; Marker to print out a filename with filename address stored in BC.
JR Z,PRINTMSG10
CP 0F9H ; Marker to print out C as a character.
JR NZ,PRINTMSG1
LD A,C
PRINTMSG1: CALL PRINTASCII
PRINTMSG2: INC DE
JR PRINTMSG
PRINTMSG3: LD HL,8+0 ; Get first stack parameter, there are 2 pushes on the stack plus return address before the parameters.
PRINTMSG4: ADD HL,SP
LD A,(HL)
INC HL
LD H,(HL)
LD L,A
PRINTMSG5: CALL PRTHL
JR PRINTMSG2
PRINTMSG6: LD HL,8+2
JR PRINTMSG4
PRINTMSG7: LD HL,8+4
JR PRINTMSG4
PRINTMSG8: LD HL,8+6
JR PRINTMSG4
PRINTMSG9: PUSH BC ; Print out contents of BC as 4 digit hex.
POP HL
JR PRINTMSG5
PRINTMSG10: PUSH DE ; Print out a filename with pointer stored in BC.
PUSH BC
POP DE
CALL PRTFN
POP DE
JR PRINTMSG2
; Method to print out the filename within an MZF header or SD Card header.
; The name may not be terminated as the full 17 chars are used, so this needs
; to be checked. Also, the filename uses Sharp Ascii so call the original Sharp
; print routine.
;
; Input: DE = Address of filename.
;
PRTFN: PUSH BC
LD B,FNSIZE ; Maximum size of filename.
PRTMSG: LD A,(DE)
INC DE
CP 000H ; If there is a valid terminator, exit.
JR Z,PRTMSGE
CP 00DH
JR Z,PRTMSGE
CALL PRNT
DJNZ PRTMSG ; Else print until 17 chars have been processed.
CALL NL
PRTMSGE: POP BC
RET
;-------------------------------------------------------------------------------
; END OF PRINT ROUTINE METHODS
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; START OF HELP SCREEN FUNCTIONALITY
;-------------------------------------------------------------------------------
; Simple help screen to display commands.
HELP: CALL NL
LD DE, HELPSCR
CALL PRTSTR
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 string is NULL terminated.
PRTSTR: PUSH AF
PUSH BC
PUSH DE
LD A,0
LD (TMPLINECNT),A
PRTSTR1: LD A,(DE)
CP 000H ; NULL terminates the string.
JR Z,PRTSTRE
CP 00DH ; As does CR.
JR Z,PRTSTR3
PRTSTR2: CALL PRINTASCII
INC DE
JR PRTSTR1
PRTSTR3: PUSH AF
LD A,(TMPLINECNT)
CP 24
JR Z,PRTSTR5
INC A
PRTSTR4: LD (TMPLINECNT),A
POP AF
JR PRTSTR2
PRTSTR5: CALL GETKY
CP ' '
JR NZ,PRTSTR5
XOR A
JR PRTSTR4
PRTSTRE: POP DE
POP BC
POP AF
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.
; 1 40
HELPSCR: DB "0..9 - select RFS Drive.", 00DH
DB "40 - 40 col mode.", 00DH
DB "80 - 80 col mode.", 00DH
;DB "700 - Select MZ-700 Mode.", 00DH
;DB "7008 - Select MZ-700 80 col Mode.", 00DH
DB "B - toggle keyboard bell.", 00DH
DB "BASIC - Load BASIC SA-5510.", 00DH
DB "C - clear memory $1200-$D000.", 00DH
DB "CPXXXXYYYYZZZZ - copy memory", 00DH
DB " XXXX=src,YYYY=dst,ZZZZ=size", 00DH
DB "CPM - Load CPM.", 00DH
DB "DXXXX[YYYY] - dump mem XXXX to YYYY.", 00DH
DB "EC[FN]- erase file, FN=No, or Filename", 00DH
DB "F[X] - boot fd drive X.", 00DH
DB "f - boot fd original rom.", 00DH
DB "H - this help screen.", 00DH
DB "IR/IC - rfs dir listing rom/sd card.", 00DH
DB "JXXXX - jump to location XXXX.", 00DH
DB "LT[FN]- load tape, FN=Filename", 00DH
DB "LR[FN]- load rom, FN=No. or Filename", 00DH
DB "LC[FN]- load sdcard, FN=No. or Filename", 00DH
DB " - add NX for no exec, ie.LRNX.", 00DH
DB "MXXXX - edit memory starting at XXXX.", 00DH
DB "P - test printer.", 00DH
DB "R - test dram memory.", 00DH
DB "SD2T - copy sd card to tape.", 00DH
DB "ST[XXXXYYYYZZZZ] - save mem to tape.", 00DH
DB "SC[XXXXYYYYZZZZ] - save mem to card.", 00DH
DB " XXXX=start,YYYY=end,ZZZZ=exec", 00DH
DB "T - test timer.", 00DH
DB "T2SD - copy tape to sd card.", 00DH
DB "V - verify tape save.", 00DH
DB 000H
;-------------------------------------------------------------------------------
; END OF HELP SCREEN FUNCTIONALITY
;-------------------------------------------------------------------------------
; TRUE ASCII TO DISPLAY CODE TABLE
;
ATBL: DB 0CCH ; NUL '\0' (null character)
DB 0E0H ; SOH (start of heading)
DB 0F2H ; STX (start of text)
DB 0F3H ; ETX (end of text)
DB 0CEH ; EOT (end of transmission)
DB 0CFH ; ENQ (enquiry)
DB 0F6H ; ACK (acknowledge)
DB 0F7H ; BEL '\a' (bell)
DB 0F8H ; BS '\b' (backspace)
DB 0F9H ; HT '\t' (horizontal tab)
DB 0FAH ; LF '\n' (new line)
DB 0FBH ; VT '\v' (vertical tab)
DB 0FCH ; FF '\f' (form feed)
DB 0FDH ; CR '\r' (carriage ret)
DB 0FEH ; SO (shift out)
DB 0FFH ; SI (shift in)
DB 0E1H ; DLE (data link escape)
DB 0C1H ; DC1 (device control 1)
DB 0C2H ; DC2 (device control 2)
DB 0C3H ; DC3 (device control 3)
DB 0C4H ; DC4 (device control 4)
DB 0C5H ; NAK (negative ack.)
DB 0C6H ; SYN (synchronous idle)
DB 0E2H ; ETB (end of trans. blk)
DB 0E3H ; CAN (cancel)
DB 0E4H ; EM (end of medium)
DB 0E5H ; SUB (substitute)
DB 0E6H ; ESC (escape)
DB 0EBH ; FS (file separator)
DB 0EEH ; GS (group separator)
DB 0EFH ; RS (record separator)
DB 0F4H ; US (unit separator)
DB 000H ; SPACE
DB 061H ; !
DB 062H ; "
DB 063H ; #
DB 064H ; $
DB 065H ; %
DB 066H ; &
DB 067H ; '
DB 068H ; (
DB 069H ; )
DB 06BH ; *
DB 06AH ; +
DB 02FH ; ,
DB 02AH ; -
DB 02EH ; .
DB 02DH ; /
DB 020H ; 0
DB 021H ; 1
DB 022H ; 2
DB 023H ; 3
DB 024H ; 4
DB 025H ; 5
DB 026H ; 6
DB 027H ; 7
DB 028H ; 8
DB 029H ; 9
DB 04FH ; :
DB 02CH ; ;
DB 051H ; <
DB 02BH ; =
DB 057H ; >
DB 049H ; ?
DB 055H ; @
DB 001H ; A
DB 002H ; B
DB 003H ; C
DB 004H ; D
DB 005H ; E
DB 006H ; F
DB 007H ; G
DB 008H ; H
DB 009H ; I
DB 00AH ; J
DB 00BH ; K
DB 00CH ; L
DB 00DH ; M
DB 00EH ; N
DB 00FH ; O
DB 010H ; P
DB 011H ; Q
DB 012H ; R
DB 013H ; S
DB 014H ; T
DB 015H ; U
DB 016H ; V
DB 017H ; W
DB 018H ; X
DB 019H ; Y
DB 01AH ; Z
DB 052H ; [
DB 059H ; \ '\\'
DB 054H ; ]
DB 0BEH ; ^
DB 03CH ; _
DB 0C7H ; `
DB 081H ; a
DB 082H ; b
DB 083H ; c
DB 084H ; d
DB 085H ; e
DB 086H ; f
DB 087H ; g
DB 088H ; h
DB 089H ; i
DB 08AH ; j
DB 08BH ; k
DB 08CH ; l
DB 08DH ; m
DB 08EH ; n
DB 08FH ; o
DB 090H ; p
DB 091H ; q
DB 092H ; r
DB 093H ; s
DB 094H ; t
DB 095H ; u
DB 096H ; v
DB 097H ; w
DB 098H ; x
DB 099H ; y
DB 09AH ; z
DB 0BCH ; {
DB 080H ; |
DB 040H ; }
DB 0A5H ; ~
DB 0C0H ; DEL
;--------------------------------------
;
; Message table
;
;--------------------------------------
MSGSONTZ: DB "+ TZ" ; Version 2.x with version 2.1+ of tranZPUter board installed.
MSGSON: DB "+ RFS ", 0ABh, "2.1a **", 00DH, 000H ; Version 2.x-> as we are now using the v2.x PCB with 4 devices on-board
MSGNOTFND: DB "Not Found", 00DH, 000H
MSGRDIRLST: DB "ROM Directory:", 00DH, 000H
MSGTRM: DB 00DH, 000H
MSGBADCMD: DB "???", 00DH, 000H
MSGSDINITER:DB "SD Card Error ", 0F9H, 00DH, 000H
MSGCDIRLST: DB "SD Card Directory ",0F9H,":", 00DH, 000H
MSGSDRERR: DB "Read error, Sec:",0FBH, 000H
MSGSDWERR: DB "Write error, Sec:",0FBH, 000H
MSGSVFAIL: DB "Error, save failed.", 00DH, 000H
MSGERAFAIL: DB "Dir update failed.", 00DH, 000H
MSGSVDIRENT:DB "Saving into dir entry:",0FBH, 00DH, 000H
MSGERASEDIR:DB "Deleted dir entry:",0FBH, 000H
MSGCMTDATA: DB "Load:",0FEH,",Exec:",0FFH, ",Size:",0FBH, 00DH, 000H
MSGNOTBIN: DB "Not binary", 00DH, 000H
MSGLOAD: DB 00DH, "Loading ",'"',0FAH,'"', 00DH, 000H
MSGSAVE: DB 00DH, "Filename: ", 000H
MSGDIRFULL: DB "Directory full", 00DH, 000H
MSGE1: DB 00DH, "Check sum error!", 00DH, 000H ; Check sum error.
MSGCMTWRITE:DB 00DH, "Writing ", '"',0FAH,'"', 00DH, 000H
MSGOK: DB 00DH, "OK!", 00DH, 000H
MSGSAVEOK: DB "Tape image saved.", 00DH, 000H
MSGBOOTDRV: DB 00DH, "Floppy boot drive ?", 000H
MSGLOADERR: DB 00DH, "Disk loading error", 00DH, 000H
MSGIPLLOAD: DB 00DH, "Disk loading ", 000H
MSGDSKNOTMST:DB 00DH, "Not a boot disk", 00Dh, 000H
MSGINITM: DB "Init memory", 00DH, 000H
MSGREAD4HEX:DB "Bad hex number", 00DH, 000H
MSGT2SDERR: DB "Copy from Tape to SD Failed", 00DH, 000H
MSGSD2TERR: DB "Copy from SD to Tape Failed", 00DH, 000H
MSGT2SDOK: DB "Success, Tape to SD done.", 00DH, 000H
MSGSD2TOK: DB "Success, SD to Tape done.", 00DH, 000H
MSGNOTZINST:DB "No tranZPUter >=v2 card installed.", 00DH, 000H
MSGNOCMTDIR:DB "CMT has no directory.", 00DH, 000H
MSGINVDRV: DB "Invalid drive, SD=0..9 or C=CMT", 00DH, 000H
MSGNOVERIFY:DB "No Verify for SD!", 00DH, 000H
ALIGN 0EFF8h
ORG 0EFF8h
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh

496
asm/rfs_bank7.asm Normal file
View File

@@ -0,0 +1,496 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: rfs_bank4.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-2023 Philip Smart <philip.smart@net2net.org>
;-
;- History: July 2019 - Merged 2 utilities to create this compilation.
; 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.
;-
;--------------------------------------------------------------------------------------------------------
;- 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/>.
;--------------------------------------------------------------------------------------------------------
;===========================================================
;
; USER ROM BANK 7 - Memory and timer test utilities.
;
;===========================================================
ORG UROMADDR
;--------------------------------
; Common code spanning all banks.
;--------------------------------
NOP
LD B,16 ; If we read the bank control reset register 15 times then this will enable bank control and then the 16th read will reset all bank control registers to default.
ROMFS7_0: LD A,(BNKCTRLRST)
DJNZ ROMFS7_0 ; Apply the default number of coded latch reads to enable the bank control registers.
LD A,BNKCTRLDEF ; Set coded latch, SDCS high, BBMOSI to high and BBCLK to high which enables SDCLK.
LD (BNKCTRL),A
NOP
NOP
NOP
XOR A ; We shouldnt arrive here after a reset, if we do, select UROM bank 0
LD (BNKSELMROM),A
NOP
NOP
NOP
LD (BNKSELUSER),A ; and start up - ie. SA1510 Monitor - this occurs as User Bank 0 is enabled and the jmp to 0 is coded in it.
;
; No mans land... this should have switched to Bank 0 and at this point there is a jump to 00000H.
JP 00000H ; This is for safety!!
;------------------------------------------------------------------------------------------
; 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.
;------------------------------------------------------------------------------------------
ALIGN_NOPS UROMBSTBL
;
BKSW7to0: PUSH AF
LD A, ROMBANK7 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK0 ; Required bank to call.
JR BKSW7_0
BKSW7to1: PUSH AF
LD A, ROMBANK7 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK1 ; Required bank to call.
JR BKSW7_0
BKSW7to2: PUSH AF
LD A, ROMBANK7 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK2 ; Required bank to call.
JR BKSW7_0
BKSW7to3: PUSH AF
LD A, ROMBANK7 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK3 ; Required bank to call.
JR BKSW7_0
BKSW7to4: PUSH AF
LD A, ROMBANK7 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK4 ; Required bank to call.
JR BKSW7_0
BKSW7to5: PUSH AF
LD A, ROMBANK7 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK5 ; Required bank to call.
JR BKSW7_0
BKSW7to6: PUSH AF
LD A, ROMBANK7 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK6 ; Required bank to call.
JR BKSW7_0
BKSW7to7: PUSH AF
LD A, ROMBANK7 ; Calling bank (ie. us).
PUSH AF
LD A, ROMBANK7 ; Required bank to call.
;
BKSW7_0: PUSH HL ; Place function to call on stack
LD HL, BKSWRET7 ; Place bank switchers return address on stack.
EX (SP),HL
LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it.
LD (BNKSELUSER), A ; Repeat the bank switch B times to enable the bank control register and set its value.
JP (HL) ; Jump to required function.
BKSWRET7: POP AF ; Get bank which called us.
LD (BNKSELUSER), A ; Return to that bank.
POP AF
RET
;-------------------------------------------------------------------------------
; START OF MEMORY TEST FUNCTIONALITY
;-------------------------------------------------------------------------------
MEMTEST: LD B,240 ; Number of loops
LOOP: LD HL,MEMSTART ; Start of checked memory,
LD D,0CFh ; End memory check CF00
LOOP1: LD A,000h
CP L
JR NZ,LOOP1b
CALL PRTHL ; Print HL as 4digit hex.
LD A,0C4h ; Move cursor left.
LD E,004h ; 4 times.
LOOP1a: CALL DPCT
DEC E
JR NZ,LOOP1a
LOOP1b: INC HL
LD A,H
CP D ; Have we reached end of memory.
JR Z,LOOP3 ; Yes, exit.
LD A,(HL) ; Read memory location under test, ie. 0.
CPL ; Subtract, ie. FF - A, ie FF - 0 = FF.
LD (HL),A ; Write it back, ie. FF.
SUB (HL) ; Subtract written memory value from A, ie. should be 0.
JR NZ,LOOP2 ; Not zero, we have an error.
LD A,(HL) ; Reread memory location, ie. FF
CPL ; Subtract FF - FF
LD (HL),A ; Write 0
SUB (HL) ; Subtract 0
JR Z,LOOP1 ; Loop if the same, ie. 0
LOOP2: LD A,16h
CALL PRNT ; Print A
CALL PRTHX ; Print HL as 4 digit hex.
CALL PRNTS ; Print space.
XOR A
LD (HL),A
LD A,(HL) ; Get into A the failing bits.
CALL PRTHX ; Print A as 2 digit hex.
CALL PRNTS ; Print space.
LD A,0FFh ; Repeat but first load FF into memory
LD (HL),A
LD A,(HL)
CALL PRTHX ; Print A as 2 digit hex.
NOP
JR LOOP4
LOOP3: CALL PRTHL
LD DE,OKCHECK
CALL MSG ; Print check message in DE
LD A,B ; Print loop count.
CALL PRTHX
LD DE,OKMSG
CALL MSG ; Print ok message in DE
CALL NL
DEC B
JR NZ,LOOP
LD DE,DONEMSG
CALL MSG ; Print check message in DE
JP ST1X
LOOP4: LD B,09h
CALL PRNTS ; Print space.
XOR A ; Zero A
SCF ; Set Carry
LOOP5: PUSH AF ; Store A and Flags
LD (HL),A ; Store 0 to bad location.
LD A,(HL) ; Read back
CALL PRTHX ; Print A as 2 digit hex.
CALL PRNTS ; Print space
POP AF ; Get back A (ie. 0 + C)
RLA ; Rotate left A. Bit LSB becomes Carry (ie. 1 first instance), Carry becomes MSB
DJNZ LOOP5 ; Loop if not zero, ie. print out all bit locations written and read to memory to locate bad bit.
XOR A ; Zero A, clears flags.
LD A,80h
LD B,08h
LOOP6: PUSH AF ; Repeat above but AND memory location with original A (ie. 80)
LD C,A ; Basically walk through all the bits to find which one is stuck.
LD (HL),A
LD A,(HL)
AND C
NOP
JR Z,LOOP8 ; If zero then print out the bit number
NOP
NOP
LD A,C
CPL
LD (HL),A
LD A,(HL)
AND C
JR NZ,LOOP8 ; As above, if the compliment doesnt yield zero, print out the bit number.
LOOP7: POP AF
RRCA
NOP
DJNZ LOOP6
JP ST1X
LOOP8: CALL LETNL ; New line.
LD DE,BITMSG ; BIT message
CALL MSG ; Print message in DE
LD A,B
DEC A
CALL PRTHX ; Print A as 2 digit hex, ie. BIT number.
CALL LETNL ; New line
LD DE,BANKMSG ; BANK message
CALL MSG ; Print message in DE
LD A,H
CP 50h ; 'P'
JR NC,LOOP9 ; Work out bank number, 1, 2 or 3.
LD A,01h
JR LOOP11
LOOP9: CP 90h
JR NC,LOOP10
LD A,02h
JR LOOP11
LOOP10: LD A,03h
LOOP11: CALL PRTHX ; Print A as 2 digit hex, ie. BANK number.
JR LOOP7
DLY1S: PUSH AF
PUSH BC
LD C,10
L0324: CALL DLY12
DEC C
JR NZ,L0324
POP BC
POP AF
RET
;-------------------------------------------------------------------------------
; END OF MEMORY TEST FUNCTIONALITY
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; START OF TIMER TEST FUNCTIONALITY
;-------------------------------------------------------------------------------
; Test the 8253 Timer, configure it as per the monitor and display the read back values.
TIMERTST: CALL NL
LD DE,MSG_TIMERTST
CALL MSG
CALL NL
LD DE,MSG_TIMERVAL
CALL MSG
LD A,01h
LD DE,8000h
CALL TIMERTST1
NDE: JP NDE
JP ST1X
TIMERTST1: ;DI
PUSH BC
PUSH DE
PUSH HL
LD (AMPM),A
LD A,0F0H
LD (TIMFG),A
ABCD: LD HL,0A8C0H
XOR A
SBC HL,DE
PUSH HL
INC HL
EX DE,HL
LD HL,CONTF ; Control Register
LD (HL),0B0H ; 10110000 Control Counter 2 10, Write 2 bytes 11, 000 Interrupt on Terminal Count, 0 16 bit binary
LD (HL),074H ; 01110100 Control Counter 1 01, Write 2 bytes 11, 010 Rate Generator, 0 16 bit binary
LD (HL),030H ; 00110100 Control Counter 1 01, Write 2 bytes 11, 010 interrupt on Terminal Count, 0 16 bit binary
LD HL,CONT2 ; Counter 2
LD (HL),E
LD (HL),D
LD HL,CONT1 ; Counter 1
LD (HL),00AH
LD (HL),000H
LD HL,CONT0 ; Counter 0
LD (HL),00CH
LD (HL),0C0H
; LD HL,CONT2 ; Counter 2
; LD C,(HL)
; LD A,(HL)
; CP D
; JP NZ,L0323H
; LD A,C
; CP E
; JP Z,CDEF
;
L0323H: PUSH AF
PUSH BC
PUSH DE
PUSH HL
;
LD HL,CONTF ; Control Register
LD (HL),080H
LD HL,CONT2 ; Counter 2
LD C,(HL)
LD A,(HL)
CALL PRTHX
LD A,C
CALL PRTHX
;
CALL PRNTS
;CALL DLY1S
;
LD HL,CONTF ; Control Register
LD (HL),040H
LD HL,CONT1 ; Counter 1
LD C,(HL)
LD A,(HL)
CALL PRTHX
LD A,C
CALL PRTHX
;
CALL PRNTS
;CALL DLY1S
;
LD HL,CONTF ; Control Register
LD (HL),000H
LD HL,CONT0 ; Counter 0
LD C,(HL)
LD A,(HL)
CALL PRTHX
LD A,C
CALL PRTHX
;
;CALL DLY1S
;
LD A,0C4h ; Move cursor left.
LD E,0Eh ; 4 times.
L0330: CALL DPCT
DEC E
JR NZ,L0330
;
; LD C,20
;L0324: CALL DLY12
; DEC C
; JR NZ,L0324
;
POP HL
POP DE
POP BC
POP AF
;
LD HL,CONT2 ; Counter 2
LD C,(HL)
LD A,(HL)
CP D
JP NZ,L0323H
LD A,C
CP E
JP NZ,L0323H
;
;
PUSH AF
PUSH BC
PUSH DE
PUSH HL
CALL NL
CALL NL
CALL NL
LD DE,MSG_TIMERVAL2
CALL MSG
POP HL
POP DE
POP BC
POP AF
;
CDEF: POP DE
LD HL,CONT1
LD (HL),00CH
LD (HL),07BH
INC HL
L0336H: PUSH AF
PUSH BC
PUSH DE
PUSH HL
;
LD HL,CONTF ; Control Register
LD (HL),080H
LD HL,CONT2 ; Counter 2
LD C,(HL)
LD A,(HL)
CALL PRTHX
LD A,C
CALL PRTHX
;
CALL PRNTS
CALL DLY1S
;
LD HL,CONTF ; Control Register
LD (HL),040H
LD HL,CONT1 ; Counter 1
LD C,(HL)
LD A,(HL)
CALL PRTHX
LD A,C
CALL PRTHX
;
CALL PRNTS
CALL DLY1S
;
LD HL,CONTF ; Control Register
LD (HL),000H
LD HL,CONT0 ; Counter 0
LD C,(HL)
LD A,(HL)
CALL PRTHX
LD A,C
CALL PRTHX
;
CALL DLY1S
;
LD A,0C4h ; Move cursor left.
LD E,0Eh ; 4 times.
L0340: CALL DPCT
DEC E
JR NZ,L0340
;
POP HL
POP DE
POP BC
POP AF
LD HL,CONT2 ; Counter 2
LD C,(HL)
LD A,(HL)
CP D
JR NZ,L0336H
LD A,C
CP E
JR NZ,L0336H
CALL NL
LD DE,MSG_TIMERVAL3
CALL MSG
POP HL
POP DE
POP BC
;EI
RET
;-------------------------------------------------------------------------------
; END OF TIMER TEST FUNCTIONALITY
;-------------------------------------------------------------------------------
;--------------------------------------
;
; Message table
;
;--------------------------------------
OKCHECK: DB ", CHECK: ", 0Dh
OKMSG: DB " OK.", 0Dh
DONEMSG: DB 11h
DB "RAM TEST COMPLETE.", 0Dh
BITMSG: DB " BIT: ", 0Dh
BANKMSG: DB " BANK: ", 0Dh
MSG_TIMERTST:
DB "8253 TIMER TEST", 0Dh, 00h
MSG_TIMERVAL:
DB "READ VALUE 1: ", 0Dh, 00h
MSG_TIMERVAL2:
DB "READ VALUE 2: ", 0Dh, 00h
MSG_TIMERVAL3:
DB "READ DONE.", 0Dh, 00h
ALIGN 0EFF8h
ORG 0EFF8h
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh

744
asm/rfs_mrom.asm Normal file
View File

@@ -0,0 +1,744 @@
;--------------------------------------------------------------------------------------------------------
;-
;- Name: rfs_mrom.asm
;- Created: September 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.
;- The purpose of this program is to provide helper utilities to the RFS in order that
;- the RFS can read the User Banks and extract required programs.
;-
;- Credits:
;- Copyright: (c) 2018-2023 Philip Smart <philip.smart@net2net.org>
;-
;- History: Sep 2019 - Initial version.
; 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.
;-
;--------------------------------------------------------------------------------------------------------
;- 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/>.
;--------------------------------------------------------------------------------------------------------
; MONITOR WORK AREA
; (MZ-80A)
STACK: EQU 010F0H
ORG STACK
SPV:
IBUFE: ; TAPE BUFFER (128 BYTES)
ATRB: DS virtual 1 ; ATTRIBUTE
NAME: DS virtual FNSIZE ; FILE NAME
SIZE: DS virtual 2 ; BYTESIZE
DTADR: DS virtual 2 ; DATA ADDRESS
EXADR: DS virtual 2 ; EXECUTION ADDRESS
COMNT: DS virtual 92 ; COMMENT
SWPW: DS virtual 10 ; SWEEP WORK
KDATW: DS virtual 2 ; KEY WORK
KANAF: DS virtual 1 ; KANA FLAG (01=GRAPHIC MODE)
DSPXY: DS virtual 2 ; DISPLAY COORDINATES
MANG: DS virtual 6 ; COLUMN MANAGEMENT
MANGE: DS virtual 1 ; COLUMN MANAGEMENT END
PBIAS: DS virtual 1 ; PAGE BIAS
ROLTOP: DS virtual 1 ; ROLL TOP BIAS
MGPNT: DS virtual 1 ; COLUMN MANAG. POINTER
PAGETP: DS virtual 2 ; PAGE TOP
ROLEND: DS virtual 1 ; ROLL END
DS virtual 14 ; BIAS
FLASH: DS virtual 1 ; FLASHING DATA
SFTLK: DS virtual 1 ; SHIFT LOCK
REVFLG: DS virtual 1 ; REVERSE FLAG
SPAGE: DS virtual 1 ; PAGE CHANGE
FLSDT: DS virtual 1 ; CURSOR DATA
STRGF: DS virtual 1 ; STRING FLAG
DPRNT: DS virtual 1 ; TAB COUNTER
TMCNT: DS virtual 2 ; TAPE MARK COUNTER
SUMDT: DS virtual 2 ; CHECK SUM DATA
CSMDT: DS virtual 2 ; FOR COMPARE SUM DATA
AMPM: DS virtual 1 ; AMPM DATA
TIMFG: DS virtual 1 ; TIME FLAG
SWRK: DS virtual 1 ; KEY SOUND FLAG
TEMPW: DS virtual 1 ; TEMPO WORK
ONTYO: DS virtual 1 ; ONTYO WORK
OCTV: DS virtual 1 ; OCTAVE WORK
RATIO: DS virtual 2 ; ONPU RATIO
BUFER: DS virtual 81 ; GET LINE BUFFER
; Starting 1000H - Generally unused bytes not cleared by the monitor.
ROMBK1: EQU 01016H ; CURRENT MROM BANK
ROMBK2: EQU 01017H ; CURRENT USERROM BANK
WRKROMBK1: EQU 01018H ; WORKING MROM BANK
WRKROMBK2: EQU 01019H ; WORKING USERROM BANK
ROMCTL: EQU 0101AH ; Current Bank control register setting.
SCRNMODE: EQU 0101BH ; Mode of screen, 0 = 40 char, 1 = 80 char.
TMPADR: EQU 0101CH ; TEMPORARY ADDRESS STORAGE
TMPSIZE: EQU 0101EH ; TEMPORARY SIZE
TMPCNT: EQU 01020H ; TEMPORARY COUNTER
TMPLINECNT: EQU 01022H ; Temporary counter for displayed lines.
TMPSTACKP: EQU 01024H ; Temporary stack pointer save.
; EQU TABLE I/O REPORT
;-----------------------------------------------
; Memory mapped ports in hardware.
;-----------------------------------------------
SCRN: EQU 0D000H
ARAM: EQU 0D800H
KEYPA: EQU 0E000h
KEYPB: EQU 0E001h
KEYPC: EQU 0E002h
KEYPF: EQU 0E003h
CSTR: EQU 0E002h
CSTPT: EQU 0E003h
CONT0: EQU 0E004h
CONT1: EQU 0E005h
CONT2: EQU 0E006h
CONTF: EQU 0E007h
SUNDG: EQU 0E008h
TEMP: EQU 0E008h
MEMSW: EQU 0E00CH
MEMSWR: EQU 0E010H
INVDSP: EQU 0E014H
NRMDSP: EQU 0E015H
SCLDSP: EQU 0E200H
BNKCTRLRST: EQU 0EFF8H ; Bank control reset, returns all registers to power up default.
BNKCTRLDIS: EQU 0EFF9H ; Disable bank control registers by resetting the coded latch.
HWSPIDATA: EQU 0EFFBH ; Hardware SPI Data register (read/write).
HWSPISTART: EQU 0EFFCH ; Start an SPI transfer.
BNKSELMROM: EQU 0EFFDh ; Select RFS Bank1 (MROM)
BNKSELUSER: EQU 0EFFEh ; Select RFS Bank2 (User ROM)
BNKCTRL: EQU 0EFFFH ; Bank Control register (read/write).
;
; RFS v2 Control Register constants.
;
BBCLK EQU 1 ; BitBang SPI Clock.
SDCS EQU 2 ; SD Card Chip Select, active low.
BBMOSI EQU 4 ; BitBang MOSI (Master Out Serial In).
CDLTCH1 EQU 8 ; Coded latch up count bit 1
CDLTCH2 EQU 16 ; Coded latch up count bit 2
CDLTCH3 EQU 32 ; Coded latch up count bit 3
BK2A19 EQU 64 ; User ROM Device Select Bit 0 (or Address bit 19).
BK2A20 EQU 128 ; User ROM Device Select Bit 1 (or Address bit 20).
; BK2A20 : BK2A19
; 0 0 = Flash RAM 0 (default).
; 0 1 = Flash RAM 1.
; 1 0 = Flasm RAM 2 or Static RAM 0.
; 1 1 = Reserved.`
BNKCTRLDEF EQU BBMOSI+SDCS+BBCLK ; Default on startup for the Bank Control register.
;-----------------------------------------------
; Rom File System Header (MZF)
;-----------------------------------------------
RFS_ATRB: EQU 00000h ; Code Type, 01 = Machine Code.
RFS_NAME: EQU 00001h ; Title/Name (17 bytes).
RFS_SIZE: EQU 00012h ; Size of program.
RFS_DTADR: EQU 00014h ; Load address of program.
RFS_EXADR: EQU 00016h ; Exec address of program.
RFS_COMNT: EQU 00018h ; COMMENT
;-----------------------------------------------
; ROM Banks, 0-7 are reserved for alternative
; Monitor versions, CPM and RFS
; code in MROM bank,
; 0-7 are reserved for RFS code in
; the User ROM bank.
; 8-15 are reserved for CPM code in
; the User ROM bank.
;-----------------------------------------------
MROMPAGES EQU 8
USRROMPAGES EQU 12 ; Monitor ROM : User ROM
ROMBANK0 EQU 0 ; MROM SA1510 40 Char : RFS Bank 0 - Main RFS Entry point and functions.
ROMBANK1 EQU 1 ; MROM SA1510 80 Char : RFS Bank 1 - Floppy disk controller and utilities.
ROMBANK2 EQU 2 ; CPM 2.2 CBIOS : RFS Bank 2 - SD Card controller and utilities.
ROMBANK3 EQU 3 ; RFS Utilities : RFS Bank 3 - Cmdline tools (Memory, Printer, Help)
ROMBANK4 EQU 4 ; Free : RFS Bank 4 - CMT Utilities.
ROMBANK5 EQU 5 ; Free : RFS Bank 5
ROMBANK6 EQU 6 ; Free : RFS Bank 6
ROMBANK7 EQU 7 ; Free : RFS Bank 7 - Memory and timer test utilities.
ROMBANK8 EQU 8 ; : CBIOS Bank 1 - Utilities
ROMBANK9 EQU 9 ; : CBIOS Bank 2 - Screen / ANSI Terminal
ROMBANK10 EQU 10 ; : CBIOS Bank 3 - SD Card
ROMBANK11 EQU 11 ; : CBIOS Bank 4 - Floppy disk controller.
; File types.
OBJCD EQU 001H ; MZF contains a binary object.
BTX1CD EQU 002H ; MZF contains a BASIC program.
BTX2CD EQU 005H ; MZF contains a BASIC program.
TZOBJCD0 EQU 0F8H ; MZF contains a TZFS binary object for page 0.
TZOBJCD1 EQU 0F8H
TZOBJCD2 EQU 0F8H
TZOBJCD3 EQU 0F8H
TZOBJCD4 EQU 0F8H
TZOBJCD5 EQU 0F8H
TZOBJCD6 EQU 0F8H
TZOBJCD7 EQU 0F8H ; MZF contains a TZFS binary object for page 7.
; Address definitions.
;
UROMADDR EQU 0E800H ; Start of User ROM Address space.
MROMJMPTBL EQU 00070H ; Fixed location of the Monitor ROM Jump Table.
;
; User ROM Jump Table definitions.
;
RFSJMPTABLE EQU UROMADDR + 00080H ; Entry point to the bank switching table.
PRTMZF EQU RFSJMPTABLE + 00000H ; Entry point into User ROM for the PRTMZF function.
PRTDBG EQU RFSJMPTABLE + 00003H ; Entry point into User ROM for the PRTDBG function.
;
MZFHDRSZ EQU 128
RFSSECTSZ EQU 256
MROMSIZE EQU 4096
UROMSIZE EQU 2048
FNSIZE EQU 17 ; Size of tape filename.
;ROW EQU 25
;COLW40 EQU 80
;SCRNSZ40 EQU COLW40 * ROW
;COLW80 EQU 80
;SCRNSZ80 EQU COLW80 * ROW
;MODE80C EQU 0
;======================================
;
; MONITOR ROM BANK 3 - RFS Utilities
;
;======================================
ORG 00000h
MONIT:
MROMBK3: JP START ; The lower part of the rom mimics the SA1510 MROM such that if a reset occurs when
; this bank is paged in, it starts up and reverts to the SA1510 MROM.
ALIGN_NOPS 0038H
ORG 0038H ; NMI Vector
JP 1038H ; Interrupt routine
ALIGN_NOPS 004AH
ORG 004Ah
; As this is not the monitor ROM, if we arrive at START it means a reset without the monitor rom bank being selected
; so we switch it in and do a jump to 0 for reset.
START: LD SP, STACK
IM 1
CALL ?MODE
LD B,0FFH
LD HL,NAME
CALL ?CLER
;
CALL INITBNKCTL
NOP
NOP
NOP
;
LD A,(ROMBK2) ; User ROM to default.
LD (BNKSELUSER), A
LD A, (ROMBK1) ; Monitor ROM to default.
LD (BNKSELMROM), A
; Location for STRT1 in monitor ROM (just after Colour RAM clear call). After the bank switch we should
; resume at this point in original monitor - ie. line commencing LD HL,TIMIN @ 006CH.
ORG 0006Ch
JR START
ALIGN_NOPS MROMJMPTBL
ORG MROMJMPTBL
;-----------------------------------------
; Enhanced function Jump table.
;-----------------------------------------
DIRMROM: JP _DIRMROM
MFINDMZF: JP _MFINDMZF
MROMLOAD: JP _MROMLOAD
;-----------------------------------------
;====================================
;
; ROM File System Commands
;
;====================================
; Method to initialise the bank control registers to a default state.
;
INITBNKCTL:LD B,16 ; If we read the bank control reset register 15 times then this will enable bank control and then the 16th read will reset all bank control registers to default.
INITBNK_1: LD A,(BNKCTRLRST)
DJNZ INITBNK_1 ; Apply the default number of coded latch reads to enable the bank control registers.
LD A,BNKCTRLDEF ; Set coded latch, SDCS high, BBMOSI to high and BBCLK to high which enables SDCLK.
LD (BNKCTRL),A
LD (ROMCTL),A ; Save to memory the value in the bank control register - this register is used for SPI etc so need to remember its setting.
RET
; Function to select a User Bank. If Carry is clear upon entry, on exit the control registers will be disabled. If carry is set then the control registers are left active.
;
SELUSRBNK: PUSH BC
PUSH AF
LD A,(ROMCTL) ; Get current setting for the coded latch, ie. number of reads needed to enable it.
LD C,A
RRA
RRA
CPL
AND 00FH ; Preserve bits 3-1, bit 0 is always 0 on the 74HCT191 latch.
LD B,A ; Set value to B for loop.
LD A,(BNKCTRLDIS)
SELUSRBNK1:LD A,(BNKSELUSER)
DJNZ SELUSRBNK1
POP AF
LD (BNKSELUSER),A ; Select the required bank.
LD A,C
POP BC
JR NC,SELUSRBNK2 ; If Carry is set by caller then leave the control registers active.
AND 03FH ; When we leave the registers active, set upper bank bits to 0 to select Flash RAM I, the default.
LD (BNKCTRL),A
RET
SELUSRBNK2:LD (BNKCTRL),A ; Update the upper address lines according to in-memory value.
LD (BNKCTRLDIS),A ; Disable the control registers, value of A is not important.
RET
; Function to select a User Bank. If Carry is clear upon entry, on exit the control registers will be disabled. If carry is set then the control registers are left active.
; During normal operations the control registers are enabled. When access is needed to the full User ROM space, ie for drive read/write then the registers are disabled after
; setting the correct bank. The upper bits of the User ROM address space (ie. bits 20:19 which select the device) are set to by the ROMCTL variable.
;
;SELUSRBNK: PUSH BC
; PUSH AF
; ; Reset to a known state to allow for spurious read/writes to control area clocking the up counter.
; LD B,15
;SEL1: LD A,(BNKCTRLDIS)
; DJNZ SEL1
; ; Now loop for the correct up counter required to enable the latches.
; LD B,15 ; Set value to B for loop.
;SELUSRBNK1:LD A,(BNKCTRL) ; Read the latch and compare with sample. Either we reach the count limit or the read differs indicating latch control.
; DJNZ SELUSRBNK1
; POP AF
; POP BC
; LD (BNKSELUSER),A ; Select the required bank.
; LD A,(ROMCTL)
; JR NC,SELUSRBNK2
; AND 03FH ; When we leave the registers active, set upper bank bits to 0 to select Flash RAM I, the default.
; LD (BNKCTRL),A
; RET
;SELUSRBNK2:LD (BNKCTRL),A
; LD (BNKCTRLDIS),A ; Disable the control registers, value of A is not important.
; RET
; HL contains address of block to check.
ISMZF: PUSH BC
PUSH DE
PUSH HL
;
LD A,(HL)
CP 001h ; 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
; B contains Bank to select.
; D = File sequence number.
; HL contains the Block page address.
_DIRMROM: PUSH BC
;
; Scan MROM Bank
; B = Bank Page
; C = Block in page
;
LD B,USRROMPAGES ; First 16x2K pages are reserved in User bank.
LD A,(ROMCTL)
AND 03FH ; Mask out the upper bank address lines so we start with Flash RAM I.
;
DIRNXTDVC: LD (ROMCTL),A
LD C,0 ; Block in page.
DIRNXTPG: LD A,B
LD (WRKROMBK2), A
OR A ; Select the required user bank and Clear carry so that the control registers are disabled.
CALL SELUSRBNK
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,0E800h + RFS_ATRB ; Add block offset to get the valid block address.
ADD HL,BC
CALL ISMZF
POP DE
POP BC
JR NZ, DIRNOTMZF
;
CALL _PRTMZF
INC D ; Next file sequence number.
DIRNOTMZF: INC C
LD A,C
CP UROMSIZE/RFSSECTSZ ; Max blocks per page reached?
JR C, DIRNXTPG2
LD C,0
INC B
DIRNXTPG2: LD A,B
CP 000h ; User rom has 256 banks of 2K, so stop when we wrap round to 0.
JR NZ, DIRNXTPG
LD A,(ROMCTL)
ADD A, 64
CP 0C0H ; If both upper address bits are set then we have come to the end.
JR C,DIRNXTDVC
AND 03FH
LD (ROMCTL),A ; Switch back to primary Flash RAM I device.
LD A,(ROMBK2)
SCF ; Select the required user bank and Set carry so that the control registers remain enabled.
CALL SELUSRBNK
POP BC
RET
; Wrapper to call the User ROM function to display the MZF filename.
; This function needs to manipulate the banks such that the calling bank is accessible.
_PRTMZF: LD A,(ROMBK2)
SCF ; Select the required user bank and Set carry so that the control registers remain enabled.
CALL SELUSRBNK
CALL PRTMZF
;CALL PRTDBG
LD A,(WRKROMBK2)
OR A ; Select the required user bank and Clear carry so that the control registers are disabled.
CALL SELUSRBNK
RET
; 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.
_MFINDMZF: 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
; D = File sequence number.
;
; Output: B = Bank where file found
; C = Block within bank where page found.
; A[7:6] = Upper bits of bank where page found.
;
FINDMZF0: POP DE ; Get file sequence number in D.
LD B,USRROMPAGES ; First 8 pages are reserved in User ROM bank.
;LD D,0 ; File numbering start.
LD A,(ROMCTL)
AND 03FH ; Mask out the upper bank address lines so we start with Flash RAM I.
;
FINDNXTDVC:LD (ROMCTL),A
LD C,0 ; Block in page.
;
FINDMZF1: LD A,B
LD (WRKROMBK2), A
OR A ; Select the required user bank and Clear carry so that the control registers are disabled.
CALL SELUSRBNK
FINDMZF2: PUSH BC ; Preserve bank count/block number.
PUSH DE ; Preserve file numbering.
LD HL,0E800h + RFS_ATRB ; 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
JR NZ, FINDMZF4 ; Z set if we found an MZF record.
INC HL ; Save address of filename.
PUSH HL
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 DE
LD BC,FNSIZE
CALL CMPSTRING
POP BC
POP DE
JR Z, FINDMZFYES
INC D ; Next file sequence number.
FINDMZF4: INC C
LD A,C
CP UROMSIZE/RFSSECTSZ ; Max blocks per page reached?
JR C, FINDMZF5
LD C,0
INC B
FINDMZF5: LD A,B
CP 000h ; User ROM has 256 banks of 2K, so stop when we wrap around to zero.
JR NZ, FINDMZF1
;
LD A,(ROMCTL)
ADD A, 64
CP 0C0H ; If both upper address bits are set then we have come to the end.
JR C,FINDNXTDVC
AND 03FH
LD (ROMCTL),A ; Switch back to primary Flash RAM I device.
;
INC B
JR FINDMZFNO
FINDMZFYES: ; Flag set by previous test.
FINDMZFNO: PUSH AF
LD A,(ROMBK2)
SCF ; Select the required user bank and Set carry so that the control registers remain enabled.
CALL SELUSRBNK
POP AF
RET
LD A,(ROMCTL)
AND 03FH
LD (ROMCTL),A ; Switch back to primary Flash RAM I device.
; Load Program from ROM
; Input: B = Bank of MZF File to load
; C = Block within bank of start of MZF file.
; A[7:6] = Upper bits of bank containing MZF File to load.
; Output:Zero = Set if file loaded, reset if an error occurred.
;
; Load program from User ROM Banks I, II or III
;
_MROMLOAD: PUSH BC
;
AND 0C0H ; Ensure only top two bits are used.
LD D,A
LD A,(ROMCTL)
AND 03FH ; Mask out the upper bank address lines so we can OR in the value given.
OR D
LD (ROMCTL),A
;
LD A,B
LD (WRKROMBK2),A
OR A ; Select the required user bank and Clear carry so that the control registers are disabled.
CALL SELUSRBNK
;
LD DE, IBUFE ; Copy the header into the work area.
LD HL, 0E800h ; 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
LROMLOAD1: LD A,(HL) ; Issues with LDIR and a signal artifact from the mainboard, so manual copy.
INC HL
LD (DE),A
INC DE
DEC BC
LD A,B
OR C
JR NZ,LROMLOAD1
PUSH HL
LD DE, (DTADR)
LD HL, (SIZE)
LD BC, RFSSECTSZ - MZFHDRSZ
OR A
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 (WRKROMBK2), A
OR A ; Select the required user bank and Clear carry so that the control registers are disabled.
CALL SELUSRBNK
LROMLOAD3: PUSH BC
LD HL, 0E800h
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
OR A
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
LROMLOAD9: LD (BNKCTRLDIS),A ; There exists an issue with using the mainboard decoder signal which I havent quite understood, random activation of the upcounter occurs which appears to be the refresh circuit.
LD A,(HL) ; Issues with LDIR and a signal artifact from the mainboard, so manual copy.
INC HL
LD (DE),A
INC DE
DEC BC
LD A,B
OR C
JR NZ,LROMLOAD9
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 UROMSIZE/RFSSECTSZ ; Max blocks per page reached?
JR C, LROMLOAD2 ;LROMLOAD3 ;LROMLOAD7
LD C, 0
INC B
;
LROMLOAD7: LD A, B
CP 000h
JR NZ, LROMLOAD2
OR 1
JR LROMLOAD5
;
LROMLOAD8: POP BC
LROMLOAD5: PUSH AF
LD A,(ROMCTL)
AND 03FH
LD (ROMCTL),A ; Switch back to primary Flash RAM I device.
LD A,(ROMBK2)
SCF ; Select the required user bank and Set carry so that the control registers remain enabled.
CALL SELUSRBNK
POP AF
RET
;======================================
;
; SA1510 mirrored functions.
;
;======================================
?MODE: LD HL,KEYPF
LD (HL),08AH
LD (HL),007H
LD (HL),005H
LD (HL),001H
RET
?CLER: XOR A
JR ?DINT
?CLRFF: LD A,0FFH
?DINT: LD (HL),A
INC HL
DJNZ ?DINT
RET
;======================================
;
; Message table
;
;======================================
; 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_definitions.asm"
INCLUDE "rfs_utilities.asm"
; Ensure we fill the entire 4K by padding with FF's.
ALIGN 1000H

7508
asm/sa-5510_rfs.asm Normal file

File diff suppressed because it is too large Load Diff

2833
asm/sa1510.asm Normal file

File diff suppressed because it is too large Load Diff

2804
asm/sa1510_hiload.asm Normal file

File diff suppressed because it is too large Load Diff

1658
asm/sfd700.asm Normal file

File diff suppressed because it is too large Load Diff

1780
asm/sharpmz-test.asm Normal file

File diff suppressed because it is too large Load Diff

56
build.sh Executable file
View File

@@ -0,0 +1,56 @@
#!/bin/bash
ROOT_DIR=`pwd`
SW_DIR=${ROOT_DIR}/
PROCESS_MZF_FILES=0
if [ "x$1" = '-m' ]; then
PROCESS_MZF_FILES=1
fi
(
cd $SW_DIR
tools/assemble_rfs.sh
if [ $? != 0 ]; then
echo "RFS assembly failed..."
exit 1
fi
tools/assemble_cpm.sh
if [ $? != 0 ]; then
echo "CPM assembly failed..."
exit 1
fi
tools/assemble_roms.sh
if [ $? != 0 ]; then
echo "ROMS assembly failed..."
exit 1
fi
# Only needed if the program source tree changes, takes too long to run on every build!
if [[ ${PROCESS_MFZ_FILES} -eq 1 ]]; then
tools/processMZFfiles.sh
if [ $? != 0 ]; then
echo "Failed to process MZF files into sectored variants...."
exit 1
fi
fi
tools/make_roms.sh
if [ $? != 0 ]; then
echo "ROM disk assembly failed..."
exit 1
fi
tools/make_cpmdisks.sh
if [ $? != 0 ]; then
echo "CPM disks assembly failed..."
exit 1
fi
tools/make_sdcard.sh
if [ $? != 0 ]; then
echo "SD card assembly failed..."
exit 1
fi
)
if [ $? != 0 ]; then
exit 1
fi
echo "Done!"

1623
config/diskdefs Normal file

File diff suppressed because it is too large Load Diff

7511
dis/SA-5510/SA-5510.asm Normal file

File diff suppressed because it is too large Load Diff

568
dis/SA-5510/SA-5510.ini Normal file
View File

@@ -0,0 +1,568 @@
----------------------------------------
-- dZ80 configuration file
----------------------------------------
----------------------------------------
-- Disassembly control
----------------------------------------
cpu="z80"
inputfile="SA-5510.bin"
outputfile="SA-5510.asm"
--fileheadersize=27
filebaseaddr=4605
disstart=0
disend=16946
--disstart=0
--disend=3584
--quiet=0
labelledoutput=1
----------------------------------------
-- Layout
----------------------------------------
labelreference=1
addresscolumn=1
opcodecolumn=1
relativejumpcomment=1
uppercase=1
autoblanklines=1
db="db"
comment="; "
radix=16
numprefix="0"
numsuffix="H"
----------------------------------------
-- Scripts
----------------------------------------
--script="scripts\\spectrum.lua"
----------------------------------------
-- References
----------------------------------------
referencefile="SA-5510.ref"
inportreference=1
outportreference=1
addressreference=1
indirectaddressreference=1
limitreferences=1
----------------------------------------
-- Opcode mapfile and code/data areas
----------------------------------------
--opmapfile="mayhem.map"
-- Code Region isnt required as v2.x sets the entire region to code unless a data region overrides it.
-- d_SetCodeRegion(4608, 2464)
-- Set the known data regions, either as a data region (byte), word or string. The type affects the assembly output definitions and word
-- regions will attempt to map to an address, ie. jump tables will be setup with labels rather than constants.
d_SetDataRegion( hex("1347"), 100) -- 0x1347
d_SetStringRegion(hex("1347"), 28)
d_SetStringRegion(hex("1364"), 31)
d_SetStringRegion(hex("1384"), 5)
d_SetStringRegion(hex("138A"), 6)
d_SetStringRegion(hex("1391"), 3)
d_SetStringRegion(hex("1395"), 6)
d_SetStringRegion(hex("139C"), 6)
d_SetDataRegion( hex("2FC2"), 30)
d_SetStringRegion(hex("2FC2"), 6)
d_SetStringRegion(hex("2FC9"), 8)
d_SetStringRegion(hex("2FD2"), 10)
d_SetStringRegion(hex("2FDD"), 2)
d_SetStringRegion(hex("1D44"), 9)
-- Reserved key words.
d_SetDataRegion( hex("15A8"), 402) -- 0x15A8 Start of tokens.
d_SetStringRegion(hex("15A8"), 2) -- 0 - REM
d_SetStringRegion(hex("15AB"), 3) -- 1 - DATA
d_SetStringRegion(hex("15AF"), 0) -- 2 - undefined
d_SetStringRegion(hex("15B0"), 0) -- 3 - undefined
d_SetStringRegion(hex("15B1"), 3) -- 4 - READ
d_SetStringRegion(hex("15B5"), 3) -- 5 - LIST
d_SetStringRegion(hex("15B9"), 2) -- 6 - RUN
d_SetStringRegion(hex("15BC"), 2) -- 7 - NEW
d_SetStringRegion(hex("15BF"), 4) -- 8 - PRINT
d_SetStringRegion(hex("15C4"), 2) -- 9 - LET
d_SetStringRegion(hex("15C7"), 2) -- 10 - FOR
d_SetStringRegion(hex("15CA"), 1) -- 11 - IF
d_SetStringRegion(hex("15CC"), 3) -- 12 - THEN
d_SetStringRegion(hex("15D0"), 3) -- 13 - GOTO
d_SetStringRegion(hex("15D4"), 4) -- 14 - GOSUB
d_SetStringRegion(hex("15D9"), 5) -- 15 - RETURN
d_SetStringRegion(hex("15DF"), 3) -- 16 - NEXT
d_SetStringRegion(hex("15E3"), 3) -- 17 - STOP
d_SetStringRegion(hex("15E7"), 2) -- 18 - END
d_SetStringRegion(hex("15EA"), 0) -- 19 - undefined
d_SetStringRegion(hex("15EB"), 1) -- 20 - ON
d_SetStringRegion(hex("15ED"), 3) -- 21 - LOAD
d_SetStringRegion(hex("15F1"), 3) -- 22 - SAVE
d_SetStringRegion(hex("15F5"), 5) -- 23 - VERIFY
d_SetStringRegion(hex("15FB"), 3) -- 24 - POKE
d_SetStringRegion(hex("15FF"), 2) -- 25 - DIM
d_SetStringRegion(hex("1602"), 5) -- 26 - DEF FN
d_SetStringRegion(hex("1608"), 4) -- 27 - INPUT
d_SetStringRegion(hex("160D"), 6) -- 28 - RESTORE
d_SetStringRegion(hex("1614"), 2) -- 29 - CLS
d_SetStringRegion(hex("1617"), 4) -- 30 - MUSIC
d_SetStringRegion(hex("161C"), 4) -- 31 - TEMPO
d_SetStringRegion(hex("1621"), 3) -- 32 - USRN
d_SetStringRegion(hex("1625"), 4) -- 33 - WOPEN
d_SetStringRegion(hex("162A"), 4) -- 34 - ROPEN
d_SetStringRegion(hex("162F"), 4) -- 35 - CLOSE
d_SetStringRegion(hex("1634"), 2) -- 36 - MON
d_SetStringRegion(hex("1637"), 4) -- 37 - LIMIT
d_SetStringRegion(hex("163C"), 3) -- 38 - CONT
d_SetStringRegion(hex("1640"), 2) -- 39 - GET
d_SetStringRegion(hex("1643"), 3) -- 40 - INP@
d_SetStringRegion(hex("1647"), 3) -- 41 - OUT@
d_SetStringRegion(hex("164B"), 5) -- 42 - CURSOR
d_SetStringRegion(hex("1651"), 2) -- 43 - SET
d_SetStringRegion(hex("1654"), 4) -- 44 - RESET
d_SetStringRegion(hex("1659"), 0) -- 45 - undefined
d_SetStringRegion(hex("165A"), 0) -- 46 - undefined
d_SetStringRegion(hex("165B"), 0) -- 47 - undefined
d_SetStringRegion(hex("165C"), 0) -- 48 - undefined
d_SetStringRegion(hex("165D"), 0) -- 49 - undefined
d_SetStringRegion(hex("165E"), 0) -- 59 - undefined
d_SetStringRegion(hex("165F"), 3) -- 51 - AUTO
d_SetStringRegion(hex("1663"), 0) -- 52 - undefined
d_SetStringRegion(hex("1664"), 0) -- 53 - undefined
d_SetStringRegion(hex("1665"), 5) -- 54 - COPY/P
d_SetStringRegion(hex("166B"), 5) -- 55 - PAGE/P
d_SetStringRegion(hex("1671"), 0) -- 56 - undefined
d_SetStringRegion(hex("1672"), 0) -- 57 - undefined
d_SetStringRegion(hex("1673"), 0) -- 58 - undefined
d_SetStringRegion(hex("1674"), 0) -- 59 - undefined
d_SetStringRegion(hex("1675"), 0) -- 60 - undefined
d_SetStringRegion(hex("1676"), 0) -- 61 - undefined
d_SetStringRegion(hex("1677"), 0) -- 62 - undefined
d_SetStringRegion(hex("1678"), 0) -- 63 - undefined
d_SetStringRegion(hex("1679"), 0) -- 64 - undefined
d_SetStringRegion(hex("167A"), 0) -- 65 - undefined
d_SetStringRegion(hex("167B"), 1) -- 66 - undefined
d_SetStringRegion(hex("167D"), 1) -- 67 - undefined
-- Functions
d_SetStringRegion(hex("167F"), 1) -- >=
d_SetStringRegion(hex("1681"), 1) -- <>
d_SetStringRegion(hex("1683"), 1) -- =<
d_SetStringRegion(hex("1685"), 1) -- <=
d_SetStringRegion(hex("1687"), 1) -- <=
d_SetStringRegion(hex("1689"), 1) -- <=
d_SetStringRegion(hex("168B"), 0) -- undefined
d_SetStringRegion(hex("168C"), 0) -- <=
d_SetStringRegion(hex("168D"), 0) -- <=
d_SetStringRegion(hex("168E"), 0) -- undefined
d_SetStringRegion(hex("168F"), 0) -- undefined
d_SetStringRegion(hex("1690"), 0) -- undefined
d_SetStringRegion(hex("1691"), 0) -- undefined
d_SetStringRegion(hex("1692"), 0) -- undefined
d_SetStringRegion(hex("1693"), 0) -- undefined
d_SetStringRegion(hex("1694"), 0) -- undefined
d_SetStringRegion(hex("1695"), 0) -- undefined
d_SetStringRegion(hex("1696"), 0) -- undefined
d_SetStringRegion(hex("1697"), 0) -- undefined
d_SetStringRegion(hex("1698"), 0) -- undefined
d_SetStringRegion(hex("1699"), 0) -- undefined
d_SetStringRegion(hex("169A"), 0) -- undefined
d_SetStringRegion(hex("169B"), 0) -- undefined
d_SetStringRegion(hex("169C"), 0) -- undefined
d_SetStringRegion(hex("169D"), 0) -- undefined
d_SetStringRegion(hex("168E"), 0) -- undefined
d_SetStringRegion(hex("168F"), 0) -- undefined
d_SetStringRegion(hex("16A0"), 1) -- TO
d_SetStringRegion(hex("16A2"), 3) -- STEP
d_SetStringRegion(hex("16A6"), 5) -- LEFT$(
d_SetStringRegion(hex("16AC"), 6) -- RIGHT$(
d_SetStringRegion(hex("16B3"), 4) -- MID$(
d_SetStringRegion(hex("16B8"), 3) -- LEN(
d_SetStringRegion(hex("16BC"), 4) -- CHR$(
d_SetStringRegion(hex("16C1"), 4) -- STR$(
d_SetStringRegion(hex("16C6"), 3) -- ASC(
d_SetStringRegion(hex("16CA"), 3) -- VAL(
d_SetStringRegion(hex("16CE"), 4) -- PEEK(
d_SetStringRegion(hex("16D3"), 3) -- TAB(
d_SetStringRegion(hex("16D7"), 6) -- SPACE$(
d_SetStringRegion(hex("16DE"), 3) -- SIZE
d_SetStringRegion(hex("16E2"), 2) -- undefined
d_SetStringRegion(hex("16E5"), 6) -- STRING$(
d_SetStringRegion(hex("16ED"), 0) -- undefined
d_SetStringRegion(hex("16EE"), 10) -- CHARACTER$(
d_SetStringRegion(hex("16F9"), 2) -- CSR
d_SetStringRegion(hex("16FC"), 12) -- undefined
d_SetStringRegion(hex("1709"), 3) -- RND(
d_SetStringRegion(hex("170D"), 3) -- SIN(
d_SetStringRegion(hex("1711"), 3) -- COS(
d_SetStringRegion(hex("1715"), 3) -- TAN(
d_SetStringRegion(hex("1719"), 3) -- ATN(
d_SetStringRegion(hex("171D"), 3) -- EXP(
d_SetStringRegion(hex("1721"), 3) -- INT(
d_SetStringRegion(hex("1725"), 3) -- LOG(
d_SetStringRegion(hex("1729"), 2) -- LN(
d_SetStringRegion(hex("172C"), 3) -- ABS(
d_SetStringRegion(hex("1730"), 3) -- SGN(
d_SetStringRegion(hex("1734"), 3) -- SQR(
d_SetStringRegion(hex("1738"), 2) -- End of Table
d_SetDataRegion( hex("13AB"), 77) -- 0x13AB
d_SetStringRegion(hex("4223"), 15) -- 0x4223 BASIC SA-5510
d_SetDataRegion( hex("1D15"), 2) -- 0x1D15 Data
d_SetDataRegion( hex("1C4C"), 1)
d_SetDataRegion( hex("1C63"), 1) -- 0x1C63 Data
d_SetWordRegion( hex("1BB2"), 128) -- 0x1BB2 Data
d_SetDataRegion( hex("3400"), 3) -- 0x3400 Data
d_SetDataRegion( hex("3404"), 1) -- 0x3404 Data
d_SetDataRegion( hex("2355"), 1) -- 0x2355 Data
d_SetDataRegion( hex("239F"), 1) -- 0x239f Data
d_SetWordRegion( hex("2691"), 34)
d_SetWordRegion( hex("26B3"), 40)
d_SetWordRegion( hex("26DB"), 24)
d_SetDataRegion( hex("26F3"), 6)
d_SetDataRegion( hex("27B2"), 2) -- 0x27B2 Data
d_SetDataRegion( hex("2884"), 1) -- 0x2885 Data
d_SetDataRegion( hex("2A83"), 25) -- 0x2A83 Data
--d_SetDataRegion( hex("2B3D"), 2) -- 0x2B3D Data
--d_SetDataRegion( hex("2D1D"), 2) -- 0x2D1D Data
-- Function table.
d_SetWordRegion( hex("22E1"), 18)
-- Function calls, CALL <Operation Byte> <Function>
d_SetDataRegion( hex("204A"), 2)
d_SetDataRegion( hex("12CE"), 1)
d_SetWordRegion( hex("12CF"), 2)
d_SetDataRegion( hex("1A78"), 1)
d_SetWordRegion( hex("1A79"), 2)
d_SetDataRegion( hex("1C54"), 1)
d_SetWordRegion( hex("1C55"), 2)
d_SetDataRegion( hex("1E23"), 1)
d_SetWordRegion( hex("1E24"), 2)
d_SetDataRegion( hex("20EB"), 1)
d_SetWordRegion( hex("20EC"), 2)
d_SetDataRegion( hex("21B3"), 1)
d_SetWordRegion( hex("21B4"), 2)
d_SetDataRegion( hex("287F"), 1)
d_SetWordRegion( hex("2880"), 2)
d_SetDataRegion( hex("2949"), 1)
d_SetWordRegion( hex("294A"), 2)
d_SetDataRegion( hex("29A2"), 1)
d_SetWordRegion( hex("29A3"), 2)
d_SetDataRegion( hex("2A3A"), 1)
d_SetWordRegion( hex("2A3B"), 2)
d_SetDataRegion( hex("2A4E"), 1)
d_SetWordRegion( hex("2A4F"), 2)
d_SetDataRegion( hex("2B10"), 1)
d_SetWordRegion( hex("2B11"), 2)
d_SetDataRegion( hex("2B32"), 1)
d_SetWordRegion( hex("2B33"), 2)
d_SetDataRegion( hex("2B6C"), 1)
d_SetWordRegion( hex("2B6D"), 2)
d_SetDataRegion( hex("2C05"), 1)
d_SetWordRegion( hex("2C06"), 2)
d_SetDataRegion( hex("2CFF"), 1)
d_SetWordRegion( hex("2D00"), 2)
d_SetDataRegion( hex("2D56"), 1)
d_SetWordRegion( hex("2D57"), 2)
d_SetDataRegion( hex("2D5C"), 1)
d_SetWordRegion( hex("2D5D"), 2)
d_SetDataRegion( hex("2CB2"), 1)
d_SetWordRegion( hex("2CB3"), 2)
d_SetDataRegion( hex("2D78"), 1)
d_SetWordRegion( hex("2D79"), 2)
d_SetDataRegion( hex("2D88"), 1)
d_SetWordRegion( hex("2D89"), 2)
d_SetDataRegion( hex("2D95"), 1)
d_SetWordRegion( hex("2D96"), 2)
d_SetDataRegion( hex("2DA2"), 1)
d_SetWordRegion( hex("2DA3"), 2)
d_SetDataRegion( hex("2DB0"), 1)
d_SetWordRegion( hex("2DB1"), 2)
d_SetDataRegion( hex("2E97"), 1)
d_SetWordRegion( hex("2E98"), 2)
d_SetDataRegion( hex("2FE7"), 1)
d_SetWordRegion( hex("2FE8"), 2)
d_SetDataRegion( hex("3323"), 1)
d_SetWordRegion( hex("3324"), 2)
d_SetDataRegion( hex("2D74"), 1)
d_SetDataRegion( hex("2E33"), 32)
d_SetDataRegion( hex("2EB0"), 3)
d_SetDataRegion( hex("2F8C"), 2)
d_SetDataRegion( hex("2FE8"), 2)
d_SetDataRegion( hex("37AE"), 269)
d_SetDataRegion( hex("3CE7"), 30)
d_SetDataRegion( hex("3F05"), 48)
d_SetDataRegion( hex("4041"), 35)
d_SetDataRegion( hex("406F"), 7)
d_SetDataRegion( hex("4121"), 56)
d_SetDataRegion( hex("18BE"), 3)
d_SetDataRegion( hex("18D7"), 3)
d_SetDataRegion( hex("1CAA"), 2)
d_SetWordRegion( hex("1D90"), 2)
d_SetDataRegion( hex("2104"), 3)
--d_SetDataRegion( hex("2221"), 3)
d_SetDataRegion( hex("2317"), 1)
d_SetDataRegion( hex("270F"), 3)
d_SetWordRegion( hex("2929"), 2)
d_SetDataRegion( hex("2A14"), 2)
d_SetDataRegion( hex("2A2A"), 2)
d_SetDataRegion( hex("2C8B"), 3)
d_SetWordRegion( hex("2CDE"), 2)
d_SetDataRegion( hex("2D10"), 2)
d_SetWordRegion( hex("2D90"), 2)
d_SetDataRegion( hex("30F4"), 3)
d_SetDataRegion( hex("3BE9"), 25)
d_SetDataRegion( hex("4118"), 3)
d_SetDataRegion( hex("3DED"), 5)
d_SetDataRegion( hex("3DF2"), 5)
d_SetDataRegion( hex("3DF7"), 5)
d_SetDataRegion( hex("3DFC"), 5)
d_SetDataRegion( hex("1B42"), 1)
d_SetDataRegion( hex("1C5A"), 1)
d_SetDataRegion( hex("1D02"), 1)
d_SetDataRegion( hex("1D89"), 1)
d_SetDataRegion( hex("1F31"), 1)
d_SetDataRegion( hex("204F"), 1)
d_SetDataRegion( hex("208F"), 1)
d_SetDataRegion( hex("2116"), 1)
d_SetDataRegion( hex("220F"), 1)
d_SetDataRegion( hex("221B"), 1)
d_SetDataRegion( hex("221F"), 1)
d_SetDataRegion( hex("245F"), 1)
d_SetDataRegion( hex("24FD"), 1)
d_SetDataRegion( hex("2715"), 1)
d_SetDataRegion( hex("284E"), 1)
d_SetDataRegion( hex("2855"), 1)
d_SetDataRegion( hex("288F"), 1)
d_SetDataRegion( hex("28C6"), 1)
d_SetDataRegion( hex("2AB3"), 1)
d_SetDataRegion( hex("2B75"), 1)
d_SetDataRegion( hex("2C21"), 1)
d_SetDataRegion( hex("2CEF"), 1)
d_SetDataRegion( hex("2D7E"), 1)
d_SetDataRegion( hex("2D8E"), 1)
d_SetDataRegion( hex("2D9B"), 1)
d_SetDataRegion( hex("2DA8"), 1)
d_SetDataRegion( hex("2DB6"), 1)
-- Create a mapping table of known Sharp I/O ports and 8 bit constants.
--
-- Format Addr IsAddr Label : IsAddr = 0, value is a constant, = 1, value is an address.
d_SetByteEquate(hex("FE") , 1, "PRTC" )
d_SetByteEquate(hex("FF") , 1, "PRTD" )
-- Create a mapping table of known Sharp MZ BIOS/Memory Mapped Hardware addresses which dz80
-- can use to replace an address with the label. The EQU list will also be output at the start
-- of the disassembly file so it can compile.
-- Format Addr IsAddr Label : IsAddr = 0, value is a constant, = 1, value is an address.
d_SetWordEquate(hex("0003"), 1, "GETL" )
d_SetWordEquate(hex("0006"), 1, "LETNL" )
d_SetWordEquate(hex("0009"), 1, "NL" )
d_SetWordEquate(hex("000C"), 1, "PRNTS" )
d_SetWordEquate(hex("000F"), 1, "PRNTT" )
d_SetWordEquate(hex("0012"), 1, "PRNT" )
d_SetWordEquate(hex("0015"), 1, "MSG" )
d_SetWordEquate(hex("0018"), 1, "MSGX" )
d_SetWordEquate(hex("001B"), 1, "GETKY" )
d_SetWordEquate(hex("001E"), 1, "BRKEY" )
d_SetWordEquate(hex("0021"), 1, "?WRI" )
d_SetWordEquate(hex("0024"), 1, "?WRD" )
d_SetWordEquate(hex("0027"), 1, "?RDI" )
d_SetWordEquate(hex("002A"), 1, "?RDD" )
d_SetWordEquate(hex("002D"), 1, "?VRFY" )
d_SetWordEquate(hex("0030"), 1, "MELDY" )
d_SetWordEquate(hex("0033"), 1, "?TMST" )
d_SetWordEquate(hex("003B"), 1, "TIMRD" )
d_SetWordEquate(hex("003E"), 1, "BELL" )
d_SetWordEquate(hex("0041"), 1, "XTEMP" )
d_SetWordEquate(hex("0044"), 1, "MSTA" )
d_SetWordEquate(hex("0047"), 1, "MSTP" )
d_SetWordEquate(hex("0000"), 1, "MONIT" )
d_SetWordEquate(hex("0089"), 1, "SS" )
d_SetWordEquate(hex("0095"), 1, "ST1" )
d_SetWordEquate(hex("0410"), 1, "HLHEX" )
d_SetWordEquate(hex("041F"), 1, "_2HEX" )
d_SetWordEquate(hex("074D"), 1, "?MODE" )
d_SetWordEquate(hex("08CA"), 1, "?KEY" )
d_SetWordEquate(hex("096C"), 1, "PRNT3" )
d_SetWordEquate(hex("0BB9"), 1, "?ADCN" )
d_SetWordEquate(hex("0BCE"), 1, "?DACN" )
d_SetWordEquate(hex("0DB5"), 1, "?DSP" )
d_SetWordEquate(hex("0DA6"), 1, "?BLNK" )
d_SetWordEquate(hex("0DDC"), 1, "?DPCT" )
d_SetWordEquate(hex("03BA"), 1, "PRTHL" )
d_SetWordEquate(hex("03C3"), 1, "PRTHX" )
d_SetWordEquate(hex("03DA"), 1, "ASC" )
d_SetWordEquate(hex("03F9"), 1, "HEX" )
d_SetWordEquate(hex("0DDC"), 1, "DPCT" )
d_SetWordEquate(hex("0DA7"), 1, "DLY12" )
d_SetWordEquate(hex("0DAA"), 1, "DLY12A" )
d_SetWordEquate(hex("0EE6"), 1, "?RSTR1" )
d_SetWordEquate(hex("06A3"), 1, "MOTOR" )
d_SetWordEquate(hex("071A"), 1, "CKSUM" )
d_SetWordEquate(hex("077A"), 1, "GAP" )
d_SetWordEquate(hex("0485"), 1, "WTAPE" )
d_SetWordEquate(hex("0700"), 1, "MSTOP" )
d_SetWordEquate(hex("11FD"), 1, "TAPECOPY" )
d_SetWordEquate(hex("1200"), 1, "COLDSTRT" )
d_SetWordEquate(hex("1250"), 1, "WARMSTRTMON")
d_SetWordEquate(hex("15A8"), 1, "CMDWORDTBL" )
d_SetWordEquate(hex("1BB2"), 1, "CMDJMPTBL" )
d_SetWordEquate(hex("2E33"), 1, "CMTBUF" )
d_SetWordEquate(hex("2E34"), 1, "CMTFNAME" )
d_SetWordEquate(hex("1C3C"), 1, "CMDREMDATA" )
d_SetWordEquate(hex("13AB"), 1, "SYNTAXERR" )
d_SetWordEquate(hex("2D12"), 1, "CMDREAD" )
d_SetWordEquate(hex("1C4D"), 1, "CMDLIST" )
d_SetWordEquate(hex("1E91"), 1, "CMDRUN" )
d_SetWordEquate(hex("1C42"), 1, "CMDNEW" )
d_SetWordEquate(hex("2B0D"), 1, "CMDPRINT" )
d_SetWordEquate(hex("1D6A"), 1, "CMDLET" )
d_SetWordEquate(hex("1F2B"), 1, "CMDFOR" )
d_SetWordEquate(hex("21AD"), 1, "CMDIF" )
d_SetWordEquate(hex("13AB"), 1, "CMDTHEN" )
d_SetWordEquate(hex("1EA6"), 1, "CMDGOTO" )
d_SetWordEquate(hex("1EC7"), 1, "CMDGOSUB" )
d_SetWordEquate(hex("1EF8"), 1, "CMDRETURN" )
d_SetWordEquate(hex("1FC0"), 1, "CMDNEXT" )
d_SetWordEquate(hex("1D2C"), 1, "CMDSTOP" )
d_SetWordEquate(hex("1D15"), 1, "CMDEND" )
d_SetWordEquate(hex("203E"), 1, "CMDON" )
d_SetWordEquate(hex("2D75"), 1, "CMDLOAD" )
d_SetWordEquate(hex("2D82"), 1, "CMDSAVE" )
d_SetWordEquate(hex("2EB3"), 1, "CMDVERIFY" )
d_SetWordEquate(hex("2191"), 1, "CMDPOKE" )
d_SetWordEquate(hex("2080"), 1, "CMDDIM" )
d_SetWordEquate(hex("2201"), 1, "CMDDEFFN" )
d_SetWordEquate(hex("2BFF"), 1, "CMDINPUT" )
d_SetWordEquate(hex("1D4D"), 1, "CMDRESTORE" )
d_SetWordEquate(hex("21A6"), 1, "CMDCLS" )
d_SetWordEquate(hex("2269"), 1, "CMDMUSIC" )
d_SetWordEquate(hex("2282"), 1, "CMDTEMPO" )
d_SetWordEquate(hex("2942"), 1, "CMDUSRN" )
d_SetWordEquate(hex("2D9F"), 1, "CMDWOPEN" )
d_SetWordEquate(hex("2D92"), 1, "CMDROPEN" )
d_SetWordEquate(hex("2DAD"), 1, "CMDCLOSE" )
d_SetWordEquate(hex("28B6"), 1, "CMDMON" )
d_SetWordEquate(hex("2967"), 1, "CMDLIMIT" )
d_SetWordEquate(hex("29CE"), 1, "CMDCONT" )
d_SetWordEquate(hex("2902"), 1, "CMDGET" )
d_SetWordEquate(hex("29FE"), 1, "CMDINP" )
d_SetWordEquate(hex("2A1C"), 1, "CMDOUT" )
d_SetWordEquate(hex("28B9"), 1, "CMDCURSOR" )
d_SetWordEquate(hex("2AA6"), 1, "CMDSET" )
d_SetWordEquate(hex("2AAA"), 1, "CMDRESET" )
d_SetWordEquate(hex("2A2F"), 1, "CMDAUTO" )
d_SetWordEquate(hex("33AB"), 1, "CMDCOPY" )
d_SetWordEquate(hex("32D4"), 1, "CMDPAGE" )
d_SetWordEquate(hex("13AE"), 1, "OVFLERR" )
d_SetWordEquate(hex("13B1"), 1, "ILDATERR" )
d_SetWordEquate(hex("13B4"), 1, "DATMISERR" )
d_SetWordEquate(hex("13B7"), 1, "STRLENERR" )
d_SetWordEquate(hex("13BA"), 1, "MEMERR" )
d_SetWordEquate(hex("13C0"), 1, "LINELENERR" )
d_SetWordEquate(hex("13C3"), 1, "GOSUBERR" )
d_SetWordEquate(hex("13C6"), 1, "FORNEXTERR" )
d_SetWordEquate(hex("13C9"), 1, "FUNCERR" )
d_SetWordEquate(hex("13CC"), 1, "NEXTFORERR" )
d_SetWordEquate(hex("13CF"), 1, "RETGOSBERR" )
d_SetWordEquate(hex("13D2"), 1, "UNDEFFNERR" )
d_SetWordEquate(hex("13D5"), 1, "LINEERR" )
d_SetWordEquate(hex("13D8"), 1, "CONTERR" )
d_SetWordEquate(hex("13DB"), 1, "BADWRERR" )
d_SetWordEquate(hex("13DE"), 1, "CMDSTMTERR" )
d_SetWordEquate(hex("13E1"), 1, "READDATAERR")
d_SetWordEquate(hex("13E4"), 1, "OPENERR" )
d_SetWordEquate(hex("13E7"), 1, "UNKNWNERR" )
d_SetWordEquate(hex("13EA"), 1, "OUTFILEERR" )
d_SetWordEquate(hex("13ED"), 1, "PRTNRDYERR" )
d_SetWordEquate(hex("13F0"), 1, "PRTHWERR" )
d_SetWordEquate(hex("13F3"), 1, "PRTPAPERERR")
d_SetWordEquate(hex("13F6"), 1, "CHKSUMERR" )
d_SetWordEquate(hex("1347"), 1, "TITLEMSG" )
d_SetWordEquate(hex("1364"), 1, "COPYRMSG" )
d_SetWordEquate(hex("1384"), 1, "READYMSG" )
d_SetWordEquate(hex("138A"), 1, "ERRORMSG" )
d_SetWordEquate(hex("1391"), 1, "INMSG" )
d_SetWordEquate(hex("1395"), 1, "BREAKMSG" )
d_SetWordEquate(hex("139C"), 1, "BYTESMSG" )
d_SetWordEquate(hex("13A3"), 1, "ERRCODE" )
d_SetWordEquate(hex("1332"), 1, "MSGNL" )
d_SetWordEquate(hex("167B"), 1, "UNUSEDTBL1" )
d_SetWordEquate(hex("167D"), 1, "UNUSEDTBL2" )
d_SetWordEquate(hex("124E"), 1, "WARMSTRT" )
d_SetWordEquate(hex("167F"), 1, "OPERATORTBL")
d_SetWordEquate(hex("17FC"), 1, "STRTONUM" )
d_SetWordEquate(hex("1E88"), 1, "GETNUM" )
d_SetWordEquate(hex("173F"), 1, "SKIPSPACE" )
d_SetWordEquate(hex("173E"), 1, "INCSKIPSPCE")
d_SetWordEquate(hex("177B"), 1, "EXECHL" )
d_SetWordEquate(hex("1795"), 1, "EXECNOTCHR" )
d_SetWordEquate(hex("17A3"), 1, "MATCHCHR" )
d_SetWordEquate(hex("490D"), 0, "LINEBUFR" )
d_SetComment( hex("1795"), "Scan for character after command" )
d_SetComment( hex("1779"), "Get address after call and jump to it via a RET command." )
d_SetComment( hex("2E1D"), "Compare loaded filename against name given by user." )
d_SetComment( hex("2B0D"), "Check to see if a stream, ie. /T = Tape is given. The 02FH below is / and the function after is called if it doesnt match /." )
d_SetComment( hex("1250"), "Sharp defined BASIC restart location from Monitor." )
-- Known Sharp Constants.
d_SetWordEquate(hex("10F0"), 0, "ATRB" ) -- ATTRIBUTE
d_SetWordEquate(hex("10F1"), 0, "NAME" ) -- FILE NAME
d_SetWordEquate(hex("1102"), 0, "SIZE" ) -- BYTESIZE
d_SetWordEquate(hex("1104"), 0, "DTADR" ) -- DATA ADDRESS
d_SetWordEquate(hex("1106"), 0, "EXADR" ) -- EXECUTION ADDRESS
d_SetWordEquate(hex("1108"), 0, "COMNT" ) -- COMMENT
d_SetWordEquate(hex("1164"), 0, "SWPW" ) -- SWEEP WORK
d_SetWordEquate(hex("116E"), 0, "KDATW" ) -- KEY WORK
d_SetWordEquate(hex("1170"), 0, "KANAF" ) -- KANA FLAG (01=GRAPHIC MODE)
d_SetWordEquate(hex("1171"), 0, "DSPXY" ) -- DISPLAY COORDINATES
d_SetWordEquate(hex("1173"), 0, "MANG" ) -- COLUMN MANAGEMENT
d_SetWordEquate(hex("1179"), 0, "MANGE" ) -- COLUMN MANAGEMENT END
d_SetWordEquate(hex("117A"), 0, "PBIAS" ) -- PAGE BIAS
d_SetWordEquate(hex("117B"), 0, "ROLTOP" ) -- ROLL TOP BIAS
d_SetWordEquate(hex("117C"), 0, "MGPNT" ) -- COLUMN MANAG. POINTER
d_SetWordEquate(hex("117D"), 0, "PAGETP" ) -- PAGE TOP
d_SetWordEquate(hex("117F"), 0, "ROLEND" ) -- ROLL END
d_SetWordEquate(hex("118E"), 0, "FLASH" ) -- FLASHING DATA
d_SetWordEquate(hex("118F"), 0, "SFTLK" ) -- SHIFT LOCK
d_SetWordEquate(hex("1190"), 0, "REVFLG" ) -- REVERSE FLAG
d_SetWordEquate(hex("1191"), 0, "SPAGE" ) -- PAGE CHANGE
d_SetWordEquate(hex("1192"), 0, "FLSDT" ) -- CURSOR DATA
d_SetWordEquate(hex("1193"), 0, "STRGF" ) -- STRING FLAG
d_SetWordEquate(hex("1194"), 0, "DPRNT" ) -- TAB COUNTER
d_SetWordEquate(hex("1195"), 0, "TMCNT" ) -- TAPE MARK COUNTER
d_SetWordEquate(hex("1197"), 0, "SUMDT" ) -- CHECK SUM DATA
d_SetWordEquate(hex("1199"), 0, "CSMDT" ) -- FOR COMPARE SUM DATA
d_SetWordEquate(hex("119B"), 0, "AMPM" ) -- AMPM DATA
d_SetWordEquate(hex("119C"), 0, "TIMFG" ) -- TIME FLAG
d_SetWordEquate(hex("119D"), 0, "SWRK" ) -- KEY SOUND FLAG
d_SetWordEquate(hex("119E"), 0, "TEMPW" ) -- TEMPO WORK
d_SetWordEquate(hex("119F"), 0, "ONTYO" ) -- ONTYO WORK
d_SetWordEquate(hex("11A0"), 0, "OCTV" ) -- OCTAVE WORK
d_SetWordEquate(hex("11A1"), 0, "RATIO" ) -- ONPU RATIO
d_SetWordEquate(hex("11A3"), 0, "BUFER" ) -- GET LINE BUFFER
----------------------------------------
-- End of configuration file
----------------------------------------

2643
dis/SA-5510/SA-5510.ref Normal file

File diff suppressed because it is too large Load Diff

1894
dis/XPATCH/XPATCH-5510.asm Normal file

File diff suppressed because it is too large Load Diff

875
dis/XPATCH/XPATCH-5510.ref Normal file
View File

@@ -0,0 +1,875 @@
dZ80 2.1 Reference file from the disassembly of "XPATCH-5510.bin".
Direct address Reference (127 entries)
--------------------------------------
Direct address 00000H. 3 references:
------------------------------------
05098H: LD DE,00000H
05696H: LD BC,00000H
05a94H: LD HL,00000H
Direct address 00002H. 1 references:
------------------------------------
05729H: LD BC,00002H
Direct address 00003H. 1 references:
------------------------------------
056f4H: LD BC,00003H
Direct address 0000aH. 2 references:
------------------------------------
050d8H: LD DE,0000AH
050e5H: LD DE,0000AH
Direct address 00011H. 1 references:
------------------------------------
05b06H: LD BC,00011H
Direct address 00016H. 1 references:
------------------------------------
05a83H: LD BC,00016H
Direct address 0001cH. 1 references:
------------------------------------
05a69H: LD BC,0001CH
Direct address 0005bH. 1 references:
------------------------------------
05b45H: LD BC,0005BH
Direct address 00080H. 1 references:
------------------------------------
0515fH: LD BC,00080H
Direct address 000f8H. 1 references:
------------------------------------
05b4dH: LD BC,000F8H
Direct address 00100H. 1 references:
------------------------------------
05167H: LD BC,00100H
Direct address 00200H. 1 references:
------------------------------------
05c8fH: LD BC,00200H
Direct address ATRB. 1 references:
----------------------------------
05b5eH: LD HL,010F0H
Direct address SIZE. 3 references:
----------------------------------
05bbdH: LD BC,(01102H)
05c08H: LD BC,(01102H)
05c72H: LD BC,(01102H)
Direct address DTADR. 2 references:
-----------------------------------
05bc9H: LD (01104H),DE
05befH: LD DE,(01104H)
Direct address BUFER. 6 references:
-----------------------------------
05386H: LD DE,011A3H
053e6H: LD DE,011A3H
054b0H: LD DE,011A3H
054fbH: LD DE,011A3H
05569H: LD DE,011A3H
055ecH: LD DE,011A3H
Direct address 011ccH. 2 references:
------------------------------------
053afH: LD DE,011CCH
0552eH: LD HL,011CCH
Direct address 01211H. 1 references:
------------------------------------
055abH: LD DE,01211H
Direct address 01414H. 1 references:
------------------------------------
05c92H: LD DE,01414H
Direct address 015a8H. 1 references:
------------------------------------
0584eH: LD HL,015A8H
Direct address 0165eH. 1 references:
------------------------------------
05a7aH: LD DE,0165EH
Direct address 01b35H. 1 references:
------------------------------------
0506dH: LD BC,01B35H
Direct address 01c16H. 1 references:
------------------------------------
05a66H: LD DE,01C16H
Direct address 02035H. 1 references:
------------------------------------
058b6H: LD SP,02035H
Direct address 02305H. 1 references:
------------------------------------
05a80H: LD DE,02305H
Direct address 02a2fH. 1 references:
------------------------------------
05a06H: CPL
Direct address 02f6cH. 1 references:
------------------------------------
05aafH: LD HL,02F6CH
Direct address 032d4H. 1 references:
------------------------------------
05a0eH: CALL NC,06D32H
Direct address 03302H. 2 references:
------------------------------------
05a8eH: LD HL,03302H
05b42H: LD DE,03302H
Direct address 0330bH. 1 references:
------------------------------------
05abaH: LD HL,0330BH
Direct address 03311H. 1 references:
------------------------------------
05a9dH: LD HL,03311H
Direct address 03338H. 1 references:
------------------------------------
05a88H: LD HL,03338H
Direct address 033abH. 1 references:
------------------------------------
05a0cH: XOR E
Direct address 04224H. 1 references:
------------------------------------
05b03H: LD DE,04224H
Direct address 04806H. 2 references:
------------------------------------
05a12H: LD B,048H
05b4aH: LD DE,04806H
Direct address 0488eH. 1 references:
------------------------------------
05a16H: ADC A,(HL)
Direct address 048c1H. 1 references:
------------------------------------
05aa3H: LD HL,048C1H
Direct address LINEBUFR. 7 references:
--------------------------------------
05378H: LD DE,0490DH
0539fH: LD DE,0490DH
05427H: LD DE,0490DH
054d7H: LD HL,0490DH
05501H: LD HL,0490DH
0555cH: LD DE,0490DH
057b3H: LD DE,0490DH
Direct address 0490fH. 1 references:
------------------------------------
053e9H: LD HL,0490FH
Direct address 04a0eH. 2 references:
------------------------------------
053d6H: LD DE,04A0EH
059acH: LD HL,04A0EH
Direct address 04e84H. 1 references:
------------------------------------
0574fH: LD IX,04E84H
Direct address 04e86H. 1 references:
------------------------------------
056cbH: LD HL,04E86H
Direct address 0505cH. 1 references:
------------------------------------
05248H: LD DE,0505CH
Direct address 05063H. 7 references:
------------------------------------
0509bH: LD (05063H),DE
050afH: LD (05063H),DE
050c4H: LD (05063H),DE
050efH: LD BC,(05063H)
051a6H: LD BC,(05063H)
0527aH: LD DE,(05063H)
0591cH: LD BC,(05063H)
Direct address 05065H. 5 references:
------------------------------------
050a1H: LD (05065H),DE
050baH: LD (05065H),DE
050c8H: LD (05065H),DE
05118H: LD BC,(05065H)
05926H: LD BC,(05065H)
Direct address 05067H. 3 references:
------------------------------------
050dbH: LD (05067H),DE
051adH: LD BC,(05067H)
0528aH: LD DE,(05067H)
Direct address 05069H. 2 references:
------------------------------------
050e8H: LD (05069H),DE
0529eH: LD DE,(05069H)
Direct address 0506dH. 1 references:
------------------------------------
05a10H: LD L,L
Direct address 0507dH. 1 references:
------------------------------------
05077H: LD DE,0507DH
Direct address 05089H. 1 references:
------------------------------------
0512dH: LD DE,05089H
Direct address 05255H. 1 references:
------------------------------------
05216H: LD DE,05255H
Direct address 05257H. 1 references:
------------------------------------
05231H: LD DE,05257H
Direct address 0525cH. 1 references:
------------------------------------
05221H: LD DE,0525CH
Direct address 052f0H. 1 references:
------------------------------------
05a14H: RET P
Direct address 05363H. 1 references:
------------------------------------
05a18H: LD H,E
Direct address 05446H. 1 references:
------------------------------------
05392H: LD DE,05446H
Direct address 05453H. 1 references:
------------------------------------
054a5H: LD DE,05453H
Direct address 05469H. 2 references:
------------------------------------
054c2H: LD BC,(05469H)
05531H: LD DE,(05469H)
Direct address 0548eH. 1 references:
------------------------------------
05a1aH: ADC A,(HL)
Direct address 05499H. 1 references:
------------------------------------
05565H: LD BC,05499H
Direct address 055abH. 1 references:
------------------------------------
0558aH: LD DE,055ABH
Direct address 055b3H. 1 references:
------------------------------------
054e7H: LD DE,055B3H
Direct address 055c5H. 1 references:
------------------------------------
05a1cH: PUSH BC
Direct address 055f8H. 1 references:
------------------------------------
055dcH: LD DE,055F8H
Direct address 05614H. 2 references:
------------------------------------
056a1H: LD (05614H),DE
056d3H: LD DE,(05614H)
Direct address 05616H. 1 references:
------------------------------------
05a1eH: LD D,056H
Direct address 05807H. 2 references:
------------------------------------
05744H: LD DE,05807H
05772H: LD HL,05807H
Direct address 05820H. 1 references:
------------------------------------
0576bH: LD HL,05820H
Direct address 05838H. 1 references:
------------------------------------
05acbH: LD HL,05838H
Direct address 05849H. 1 references:
------------------------------------
05ac2H: LD HL,05849H
Direct address 0585dH. 2 references:
------------------------------------
05840H: LD DE,0585DH
05857H: LD HL,0585DH
Direct address 05899H. 1 references:
------------------------------------
05b39H: LD HL,05899H
Direct address 058a5H. 1 references:
------------------------------------
0589fH: LD DE,058A5H
Direct address 058b7H. 1 references:
------------------------------------
05af4H: LD HL,058B7H
Direct address 058e0H. 1 references:
------------------------------------
05adeH: LD HL,058E0H
Direct address 058ebH. 1 references:
------------------------------------
05a04H: EX DE,HL
Direct address 05907H. 1 references:
------------------------------------
05a08H: RLCA
Direct address 0590eH. 1 references:
------------------------------------
05a0aH: LD C,059H
Direct address 059c7H. 1 references:
------------------------------------
05969H: LD DE,059C7H
Direct address 05a04H. 2 references:
------------------------------------
05a63H: LD HL,05A04H
05b0bH: LD HL,05A04H
Direct address 05a20H. 1 references:
------------------------------------
05a72H: LD DE,05A20H
Direct address 05a3cH. 1 references:
------------------------------------
05a6eH: LD HL,05A3CH
Direct address 05a52H. 1 references:
------------------------------------
05b00H: LD HL,05A52H
Direct address 05a61H. 1 references:
------------------------------------
05af8H: LD HL,05A61H
Direct address 05b55H. 1 references:
------------------------------------
05b3fH: LD HL,05B55H
Direct address 0d753H. 1 references:
------------------------------------
05c6fH: LD DE,0D753H
Direct address 0e548H. 1 references:
------------------------------------
05bb9H: LD DE,0E548H
Direct address 0ffffH. 1 references:
------------------------------------
05bb3H: LD HL,0FFFFH
Indirect address Reference (120 entries)
----------------------------------------
Indirect address DTADR. 2 references:
-------------------------------------
05bd9H: LD HL,(01104H)
05c76H: LD HL,(01104H)
Indirect address DSPXY. 2 references:
-------------------------------------
0521bH: LD (01171H),A
05228H: LD (01171H),A
Indirect address DPRNT. 1 references:
-------------------------------------
0539bH: LD A,(01194H)
Indirect address 01201H. 1 references:
--------------------------------------
05b33H: LD (01201H),HL
Indirect address 01225H. 1 references:
--------------------------------------
05b3cH: LD (01225H),HL
Indirect address 01492H. 1 references:
--------------------------------------
05aceH: LD (01492H),A
Indirect address 01493H. 1 references:
--------------------------------------
05ad1H: LD (01493H),HL
Indirect address 0153eH. 1 references:
--------------------------------------
05ac5H: LD (0153EH),A
Indirect address 0153fH. 1 references:
--------------------------------------
05ac8H: LD (0153FH),HL
Indirect address 018b4H. 1 references:
--------------------------------------
05b11H: LD (018B4H),HL
Indirect address 01958H. 6 references:
--------------------------------------
05153H: LD HL,(01958H)
052bbH: LD HL,(01958H)
053bbH: LD HL,(01958H)
05935H: LD HL,(01958H)
0598cH: LD HL,(01958H)
05b0eH: LD (01958H),HL
Indirect address 01ac8H. 1 references:
--------------------------------------
05b14H: LD (01AC8H),HL
Indirect address 01ae2H. 1 references:
--------------------------------------
05b17H: LD (01AE2H),HL
Indirect address 01b14H. 1 references:
--------------------------------------
05b1aH: LD (01B14H),HL
Indirect address 01b1cH. 1 references:
--------------------------------------
05b1dH: LD (01B1CH),HL
Indirect address 01c16H. 1 references:
--------------------------------------
05aeaH: LD (01C16H),A
Indirect address 01c17H. 1 references:
--------------------------------------
05aefH: LD (01C17H),A
Indirect address 01c7dH. 2 references:
--------------------------------------
05b7cH: LD (01C7DH),A
05b84H: LD (01C7DH),A
Indirect address 01c7eH. 1 references:
--------------------------------------
05b20H: LD (01C7EH),HL
Indirect address 01ccdH. 1 references:
--------------------------------------
05a91H: LD (01CCDH),HL
Indirect address 01ccfH. 1 references:
--------------------------------------
05a97H: LD (01CCFH),HL
Indirect address 01cd1H. 1 references:
--------------------------------------
05a9aH: LD (01CD1H),HL
Indirect address 01ec2H. 1 references:
--------------------------------------
05b23H: LD (01EC2H),HL
Indirect address 022c9H. 1 references:
--------------------------------------
05a8bH: LD (022C9H),HL
Indirect address 028f5H. 2 references:
--------------------------------------
05b6cH: LD (028F5H),A
05b74H: LD (028F5H),A
Indirect address 02b11H. 1 references:
--------------------------------------
05aa0H: LD (02B11H),HL
Indirect address 02d44H. 1 references:
--------------------------------------
05b26H: LD (02D44H),HL
Indirect address 02f19H. 2 references:
--------------------------------------
05c9aH: LD (02F19H),A
05ca2H: LD (02F19H),A
Indirect address 02f24H. 1 references:
--------------------------------------
05b29H: LD (02F24H),HL
Indirect address 0303cH. 1 references:
--------------------------------------
05b2cH: LD (0303CH),HL
Indirect address 03042H. 1 references:
--------------------------------------
05b2fH: LD (03042H),HL
Indirect address 0307bH. 1 references:
--------------------------------------
05aa6H: LD (0307BH),HL
Indirect address 03140H. 1 references:
--------------------------------------
05ab7H: LD (03140H),A
Indirect address 03141H. 1 references:
--------------------------------------
05abdH: LD (03141H),HL
Indirect address 0315bH. 1 references:
--------------------------------------
05ab2H: LD (0315BH),HL
Indirect address 0318cH. 1 references:
--------------------------------------
05aa9H: LD (0318CH),HL
Indirect address 03199H. 1 references:
--------------------------------------
05aacH: LD (03199H),HL
Indirect address 031adH. 1 references:
--------------------------------------
05adbH: LD (031ADH),A
Indirect address 031aeH. 1 references:
--------------------------------------
05ae1H: LD (031AEH),HL
Indirect address 0322eH. 1 references:
--------------------------------------
05ad4H: LD A,(0322EH)
Indirect address 041ecH. 1 references:
--------------------------------------
05afdH: LD (041ECH),A
Indirect address 041ffH. 1 references:
--------------------------------------
05b36H: LD (041FFH),HL
Indirect address 0430dH. 1 references:
--------------------------------------
058c3H: LD A,(0430DH)
Indirect address 04a0eH. 5 references:
--------------------------------------
053ceH: LD HL,(04A0EH)
054f2H: LD HL,(04A0EH)
0557bH: LD HL,(04A0EH)
05582H: LD (04A0EH),HL
055e4H: LD HL,(04A0EH)
Indirect address 04a10H. 1 references:
--------------------------------------
05543H: LD HL,(04A10H)
Indirect address 04ab3H. 3 references:
--------------------------------------
052f3H: LD HL,(04AB3H)
0562eH: LD HL,(04AB3H)
05c1fH: LD HL,(04AB3H)
Indirect address 04ab5H. 3 references:
--------------------------------------
0530eH: LD HL,(04AB5H)
05647H: LD HL,(04AB5H)
05c14H: LD HL,(04AB5H)
Indirect address 04e4eH. 2 references:
--------------------------------------
0519fH: LD (04E4EH),HL
0532eH: LD (04E4EH),HL
Indirect address 04e94H. 2 references:
--------------------------------------
05175H: LD HL,(04E94H)
05179H: LD (04E94H),HL
Indirect address 0504eH. 1 references:
--------------------------------------
0536dH: LD A,(0504EH)
Indirect address 05051H. 2 references:
--------------------------------------
050ecH: LD (05051H),HL
05901H: LD (05051H),HL
Indirect address 05063H. 1 references:
--------------------------------------
0595bH: LD HL,(05063H)
Indirect address 05065H. 4 references:
--------------------------------------
050f3H: LD HL,(05065H)
051b8H: LD HL,(05065H)
05272H: LD HL,(05065H)
05954H: LD HL,(05065H)
Indirect address 05067H. 2 references:
--------------------------------------
0510aH: LD HL,(05067H)
0594aH: LD HL,(05067H)
Indirect address 05069H. 1 references:
--------------------------------------
051c6H: LD HL,(05069H)
Indirect address 0506bH. 2 references:
--------------------------------------
05149H: LD (0506BH),HL
05943H: LD HL,(0506BH)
Indirect address 05465H. 6 references:
--------------------------------------
05364H: LD (05465H),A
0538bH: LD A,(05465H)
05432H: LD A,(05465H)
05490H: LD (05465H),A
05553H: LD A,(05465H)
055c7H: LD (05465H),A
Indirect address 05466H. 6 references:
--------------------------------------
0548aH: LD (05466H),A
0549fH: LD A,(05466H)
055d6H: LD A,(05466H)
0590fH: LD (05466H),A
05963H: LD A,(05466H)
05978H: LD (05466H),A
Indirect address 05467H. 6 references:
--------------------------------------
05383H: LD (05467H),A
053b7H: LD A,(05467H)
054b3H: LD A,(05467H)
054f5H: LD A,(05467H)
05574H: LD A,(05467H)
055efH: LD A,(05467H)
Indirect address 05468H. 4 references:
--------------------------------------
053b2H: LD (05468H),A
054c9H: LD A,(05468H)
05535H: LD A,(05468H)
0556fH: LD A,(05468H)
Indirect address 05469H. 3 references:
--------------------------------------
05404H: LD (05469H),HL
0556cH: LD HL,(05469H)
05598H: LD A,(05469H)
Indirect address 0546bH. 4 references:
--------------------------------------
05424H: LD (0546BH),HL
054adH: LD HL,(0546BH)
054bfH: LD HL,(0546BH)
0551eH: LD HL,(0546BH)
Indirect address 05611H. 5 references:
--------------------------------------
05617H: LD (05611H),A
05628H: LD (05611H),A
057e3H: LD A,(05611H)
057f2H: LD A,(05611H)
057ffH: LD A,(05611H)
Indirect address 05612H. 2 references:
--------------------------------------
056a5H: LD (05612H),HL
05736H: LD HL,(05612H)
Indirect address 05614H. 1 references:
--------------------------------------
056faH: LD HL,(05614H)
Indirect address 058e0H. 1 references:
--------------------------------------
058fdH: LD (058E0H),A
End of reference file for "XPATCH-5510.bin"

330
dis/XPATCH/XPATCH.ini Normal file
View File

@@ -0,0 +1,330 @@
----------------------------------------
-- dZ80 configuration file
----------------------------------------
----------------------------------------
-- Disassembly control
----------------------------------------
cpu="z80"
inputfile="XPATCH-5510.bin"
outputfile="XPATCH-5510.asm"
--fileheadersize=27
filebaseaddr=20572
disstart=0
disend=23724
--disstart=0
--disend=3584
--quiet=0
labelledoutput=1
----------------------------------------
-- Layout
----------------------------------------
labelreference=1
addresscolumn=1
opcodecolumn=1
relativejumpcomment=1
uppercase=1
autoblanklines=1
db="db"
comment="; "
radix=16
numprefix="0"
numsuffix="H"
----------------------------------------
-- Scripts
----------------------------------------
--script="scripts\\spectrum.lua"
----------------------------------------
-- References
----------------------------------------
referencefile="XPATCH-5510.ref"
inportreference=1
outportreference=1
addressreference=1
indirectaddressreference=1
limitreferences=1
----------------------------------------
-- Opcode mapfile and code/data areas
----------------------------------------
--opmapfile="mayhem.map"
-- Code Region isnt required as v2.x sets the entire region to code unless a data region overrides it.
d_SetCodeRegion(20572, 3152)
-- Set the known data regions, either as a data region (byte), word or string. The type affects the assembly output definitions and word
-- regions will attempt to map to an address, ie. jump tables will be setup with labels rather than constants.
d_SetDataRegion( hex("507D"), 27)
d_SetStringRegion( hex("507D"), 11)
d_SetStringRegion( hex("5089"), 15)
d_SetDataRegion( hex("5255"), 23)
d_SetStringRegion( hex("5257"), 4)
d_SetStringRegion( hex("525C"), 15)
d_SetDataRegion( hex("5446"), 31)
d_SetStringRegion( hex("5446"), 12)
d_SetStringRegion( hex("5453"), 17)
d_SetDataRegion( hex("5465"), 8)
d_SetStringRegion( hex("55B3"), 18)
d_SetStringRegion( hex("55F8"), 25)
d_SetDataRegion( hex("5807"), 49)
d_SetStringRegion( hex("5807"), 23)
--d_SetStringRegion( hex("581F"), 5)
d_SetStringRegion( hex("5827"), 5)
d_SetStringRegion( hex("582F"), 5)
d_SetDataRegion( hex("585D"), 45)
d_SetStringRegion( hex("585D"), 4)
d_SetStringRegion( hex("5862"), 5)
d_SetStringRegion( hex("5868"), 7)
d_SetStringRegion( hex("5870"), 5)
d_SetStringRegion( hex("5876"), 3)
d_SetStringRegion( hex("587A"), 5)
d_SetStringRegion( hex("5880"), 3)
d_SetStringRegion( hex("5884"), 3)
--d_SetStringRegion( hex("585D"), 4)
--d_SetDataRegion( hex("58A5"), 59)
--d_SetStringRegion( hex("58A5"), 17)
--d_SetStringRegion( hex("58B7"), 40)
d_SetDataRegion( hex("59C7"), 25)
d_SetStringRegion( hex("59C7"), 24)
d_SetDataRegion( hex("5A04"), 56)
d_SetWordRegion( hex("5A04"), 28)
-- Reserved key words.
d_SetDataRegion( hex("5A20"), 28)
d_SetStringRegion( hex("5A20"), 3) -- LINE
d_SetStringRegion( hex("5A24"), 3) -- AUTO
d_SetStringRegion( hex("5A28"), 2) -- CLR
d_SetStringRegion( hex("5A2B"), 3) -- MOVE
d_SetStringRegion( hex("5A2F"), 5) -- COPY/P
d_SetStringRegion( hex("5A35"), 5) -- PAGE/P
d_SetDataRegion( hex("5A52"), 17)
d_SetStringRegion( hex("5A52"), 15)
-- Create a mapping table of known Sharp I/O ports and 8 bit constants.
--
-- Format Addr IsAddr Label : IsAddr = 0, value is a constant, = 1, value is an address.
d_SetByteEquate(hex("FE") , 1, "PRTC" )
d_SetByteEquate(hex("FF") , 1, "PRTD" )
-- Create a mapping table of known Sharp MZ BIOS/Memory Mapped Hardware addresses which dz80
-- can use to replace an address with the label. The EQU list will also be output at the start
-- of the disassembly file so it can compile.
-- Format Addr IsAddr Label : IsAddr = 0, value is a constant, = 1, value is an address.
d_SetWordEquate(hex("0003"), 1, "GETL" )
d_SetWordEquate(hex("0006"), 1, "LETNL" )
d_SetWordEquate(hex("0009"), 1, "NL" )
d_SetWordEquate(hex("000C"), 1, "PRNTS" )
d_SetWordEquate(hex("000F"), 1, "PRNTT" )
d_SetWordEquate(hex("0012"), 1, "PRNT" )
d_SetWordEquate(hex("0015"), 1, "MSG" )
d_SetWordEquate(hex("0018"), 1, "MSGX" )
d_SetWordEquate(hex("001B"), 1, "GETKY" )
d_SetWordEquate(hex("001E"), 1, "BRKEY" )
d_SetWordEquate(hex("0021"), 1, "?WRI" )
d_SetWordEquate(hex("0024"), 1, "?WRD" )
d_SetWordEquate(hex("0027"), 1, "?RDI" )
d_SetWordEquate(hex("002A"), 1, "?RDD" )
d_SetWordEquate(hex("002D"), 1, "?VRFY" )
d_SetWordEquate(hex("0030"), 1, "MELDY" )
d_SetWordEquate(hex("0033"), 1, "?TMST" )
d_SetWordEquate(hex("003B"), 1, "TIMRD" )
d_SetWordEquate(hex("003E"), 1, "BELL" )
d_SetWordEquate(hex("0041"), 1, "XTEMP" )
d_SetWordEquate(hex("0044"), 1, "MSTA" )
d_SetWordEquate(hex("0047"), 1, "MSTP" )
d_SetWordEquate(hex("0000"), 1, "MONIT" )
d_SetWordEquate(hex("0089"), 1, "SS" )
d_SetWordEquate(hex("0095"), 1, "ST1" )
d_SetWordEquate(hex("0410"), 1, "HLHEX" )
d_SetWordEquate(hex("041F"), 1, "_2HEX" )
d_SetWordEquate(hex("074D"), 1, "?MODE" )
d_SetWordEquate(hex("08CA"), 1, "?KEY" )
d_SetWordEquate(hex("096C"), 1, "PRNT3" )
d_SetWordEquate(hex("0BB9"), 1, "?ADCN" )
d_SetWordEquate(hex("0BCE"), 1, "?DACN" )
d_SetWordEquate(hex("0DB5"), 1, "?DSP" )
d_SetWordEquate(hex("0DA6"), 1, "?BLNK" )
d_SetWordEquate(hex("0DDC"), 1, "?DPCT" )
d_SetWordEquate(hex("03BA"), 1, "PRTHL" )
d_SetWordEquate(hex("03C3"), 1, "PRTHX" )
d_SetWordEquate(hex("03DA"), 1, "ASC" )
d_SetWordEquate(hex("03F9"), 1, "HEX" )
d_SetWordEquate(hex("0DDC"), 1, "DPCT" )
d_SetWordEquate(hex("0DA7"), 1, "DLY12" )
d_SetWordEquate(hex("0DAA"), 1, "DLY12A" )
d_SetWordEquate(hex("0EE6"), 1, "?RSTR1" )
d_SetWordEquate(hex("06A3"), 1, "MOTOR" )
d_SetWordEquate(hex("071A"), 1, "CKSUM" )
d_SetWordEquate(hex("077A"), 1, "GAP" )
d_SetWordEquate(hex("0485"), 1, "WTAPE" )
d_SetWordEquate(hex("0700"), 1, "MSTOP" )
d_SetWordEquate(hex("11FD"), 1, "TAPECOPY" )
d_SetWordEquate(hex("1200"), 1, "COLDSTRT" )
d_SetWordEquate(hex("1250"), 1, "WARMSTRTMON")
d_SetWordEquate(hex("15A8"), 1, "CMDWORDTBL" )
d_SetWordEquate(hex("1BB2"), 1, "CMDJMPTBL" )
d_SetWordEquate(hex("2E33"), 1, "CMTBUF" )
d_SetWordEquate(hex("2E34"), 1, "CMTFNAME" )
-- Known BASIC SA-5510 labels/addresses.
d_SetWordEquate(hex("1C3C"), 1, "CMDREMDATA" )
d_SetWordEquate(hex("13AB"), 1, "SYNTAXERR" )
d_SetWordEquate(hex("2D12"), 1, "CMDREAD" )
d_SetWordEquate(hex("1C4D"), 1, "CMDLIST" )
d_SetWordEquate(hex("1E91"), 1, "CMDRUN" )
d_SetWordEquate(hex("1C42"), 1, "CMDNEW" )
d_SetWordEquate(hex("2B0D"), 1, "CMDPRINT" )
d_SetWordEquate(hex("1D6A"), 1, "CMDLET" )
d_SetWordEquate(hex("1F2B"), 1, "CMDFOR" )
d_SetWordEquate(hex("21AD"), 1, "CMDIF" )
d_SetWordEquate(hex("13AB"), 1, "CMDTHEN" )
d_SetWordEquate(hex("1EA6"), 1, "CMDGOTO" )
d_SetWordEquate(hex("1EC7"), 1, "CMDGOSUB" )
d_SetWordEquate(hex("1EF8"), 1, "CMDRETURN" )
d_SetWordEquate(hex("1FC0"), 1, "CMDNEXT" )
d_SetWordEquate(hex("1D2C"), 1, "CMDSTOP" )
d_SetWordEquate(hex("1D15"), 1, "CMDEND" )
d_SetWordEquate(hex("203E"), 1, "CMDON" )
d_SetWordEquate(hex("2D75"), 1, "CMDLOAD" )
d_SetWordEquate(hex("2D82"), 1, "CMDSAVE" )
d_SetWordEquate(hex("2EB3"), 1, "CMDVERIFY" )
d_SetWordEquate(hex("2191"), 1, "CMDPOKE" )
d_SetWordEquate(hex("2080"), 1, "CMDDIM" )
d_SetWordEquate(hex("2201"), 1, "CMDDEFFN" )
d_SetWordEquate(hex("2BFF"), 1, "CMDINPUT" )
d_SetWordEquate(hex("1D4D"), 1, "CMDRESTORE" )
d_SetWordEquate(hex("21A6"), 1, "CMDCLS" )
d_SetWordEquate(hex("2269"), 1, "CMDMUSIC" )
d_SetWordEquate(hex("2282"), 1, "CMDTEMPO" )
d_SetWordEquate(hex("2942"), 1, "CMDUSRN" )
d_SetWordEquate(hex("2D9F"), 1, "CMDWOPEN" )
d_SetWordEquate(hex("2D92"), 1, "CMDROPEN" )
d_SetWordEquate(hex("2DAD"), 1, "CMDCLOSE" )
d_SetWordEquate(hex("28B6"), 1, "CMDMON" )
d_SetWordEquate(hex("2967"), 1, "CMDLIMIT" )
d_SetWordEquate(hex("29CE"), 1, "CMDCONT" )
d_SetWordEquate(hex("2902"), 1, "CMDGET" )
d_SetWordEquate(hex("29FE"), 1, "CMDINP" )
d_SetWordEquate(hex("2A1C"), 1, "CMDOUT" )
d_SetWordEquate(hex("28B9"), 1, "CMDCURSOR" )
d_SetWordEquate(hex("2AA6"), 1, "CMDSET" )
d_SetWordEquate(hex("2AAA"), 1, "CMDRESET" )
d_SetWordEquate(hex("2A2F"), 1, "CMDAUTO" )
d_SetWordEquate(hex("33AB"), 1, "CMDCOPY" )
d_SetWordEquate(hex("32D4"), 1, "CMDPAGE" )
d_SetWordEquate(hex("13AE"), 1, "OVFLERR" )
d_SetWordEquate(hex("13B1"), 1, "ILDATERR" )
d_SetWordEquate(hex("13B4"), 1, "DATMISERR" )
d_SetWordEquate(hex("13B7"), 1, "STRLENERR" )
d_SetWordEquate(hex("13BA"), 1, "MEMERR" )
d_SetWordEquate(hex("13C0"), 1, "LINELENERR" )
d_SetWordEquate(hex("13C3"), 1, "GOSUBERR" )
d_SetWordEquate(hex("13C6"), 1, "FORNEXTERR" )
d_SetWordEquate(hex("13C9"), 1, "FUNCERR" )
d_SetWordEquate(hex("13CC"), 1, "NEXTFORERR" )
d_SetWordEquate(hex("13CF"), 1, "RETGOSBERR" )
d_SetWordEquate(hex("13D2"), 1, "UNDEFFNERR" )
d_SetWordEquate(hex("13D5"), 1, "LINEERR" )
d_SetWordEquate(hex("13D8"), 1, "CONTERR" )
d_SetWordEquate(hex("13DB"), 1, "BADWRERR" )
d_SetWordEquate(hex("13DE"), 1, "CMDSTMTERR" )
d_SetWordEquate(hex("13E1"), 1, "READDATAERR")
d_SetWordEquate(hex("13E4"), 1, "OPENERR" )
d_SetWordEquate(hex("13E7"), 1, "UNKNWNERR" )
d_SetWordEquate(hex("13EA"), 1, "OUTFILEERR" )
d_SetWordEquate(hex("13ED"), 1, "PRTNRDYERR" )
d_SetWordEquate(hex("13F0"), 1, "PRTHWERR" )
d_SetWordEquate(hex("13F3"), 1, "PRTPAPERERR")
d_SetWordEquate(hex("13F6"), 1, "CHKSUMERR" )
d_SetWordEquate(hex("1347"), 1, "TITLEMSG" )
d_SetWordEquate(hex("1364"), 1, "COPYRMSG" )
d_SetWordEquate(hex("1384"), 1, "READYMSG" )
d_SetWordEquate(hex("138A"), 1, "ERRORMSG" )
d_SetWordEquate(hex("1391"), 1, "INMSG" )
d_SetWordEquate(hex("1395"), 1, "BREAKMSG" )
d_SetWordEquate(hex("139C"), 1, "BYTESMSG" )
d_SetWordEquate(hex("13A3"), 1, "ERRCODE" )
d_SetWordEquate(hex("1332"), 1, "MSGNL" )
d_SetWordEquate(hex("167B"), 1, "UNUSEDTBL1" )
d_SetWordEquate(hex("167D"), 1, "UNUSEDTBL2" )
d_SetWordEquate(hex("124E"), 1, "WARMSTRT" )
d_SetWordEquate(hex("167F"), 1, "OPERATORTBL")
d_SetWordEquate(hex("17FC"), 1, "STRTONUM" )
d_SetWordEquate(hex("1E88"), 1, "GETNUM" )
d_SetWordEquate(hex("173F"), 1, "SKIPSPACE" )
d_SetWordEquate(hex("173E"), 1, "INCSKIPSPCE")
d_SetWordEquate(hex("177B"), 1, "EXECHL" )
d_SetWordEquate(hex("1795"), 1, "EXECNOTCHR" )
d_SetWordEquate(hex("17A3"), 1, "MATCHCHR" )
d_SetWordEquate(hex("490D"), 0, "LINEBUFR" )
-- XPATCH labels/addresses.
d_SetWordEquate(hex("5A63"), 1, "XPINIT" )
d_SetWordEquate(hex("5B55"), 1, "RELOC3302" )
d_SetWordEquate(hex("5BB0"), 1, "RELOC4806" )
-- Comments to be added at fixed addresses.
d_SetComment( hex("1250"), "Sharp defined BASIC restart location from Monitor." )
d_SetComment( hex("5B55"), "Relocated to 0x3302 for 0x5B bytes." )
d_SetComment( hex("5BB0"), "Relocated to 0x4806 for 0xF8 bytes." )
d_SetComment( hex("5CA8"), "End of Relocated code." )
-- Known Sharp Constants.
d_SetWordEquate(hex("10F0"), 0, "ATRB" ) -- ATTRIBUTE
d_SetWordEquate(hex("10F1"), 0, "NAME" ) -- FILE NAME
d_SetWordEquate(hex("1102"), 0, "SIZE" ) -- BYTESIZE
d_SetWordEquate(hex("1104"), 0, "DTADR" ) -- DATA ADDRESS
d_SetWordEquate(hex("1106"), 0, "EXADR" ) -- EXECUTION ADDRESS
d_SetWordEquate(hex("1108"), 0, "COMNT" ) -- COMMENT
d_SetWordEquate(hex("1164"), 0, "SWPW" ) -- SWEEP WORK
d_SetWordEquate(hex("116E"), 0, "KDATW" ) -- KEY WORK
d_SetWordEquate(hex("1170"), 0, "KANAF" ) -- KANA FLAG (01=GRAPHIC MODE)
d_SetWordEquate(hex("1171"), 0, "DSPXY" ) -- DISPLAY COORDINATES
d_SetWordEquate(hex("1173"), 0, "MANG" ) -- COLUMN MANAGEMENT
d_SetWordEquate(hex("1179"), 0, "MANGE" ) -- COLUMN MANAGEMENT END
d_SetWordEquate(hex("117A"), 0, "PBIAS" ) -- PAGE BIAS
d_SetWordEquate(hex("117B"), 0, "ROLTOP" ) -- ROLL TOP BIAS
d_SetWordEquate(hex("117C"), 0, "MGPNT" ) -- COLUMN MANAG. POINTER
d_SetWordEquate(hex("117D"), 0, "PAGETP" ) -- PAGE TOP
d_SetWordEquate(hex("117F"), 0, "ROLEND" ) -- ROLL END
d_SetWordEquate(hex("118E"), 0, "FLASH" ) -- FLASHING DATA
d_SetWordEquate(hex("118F"), 0, "SFTLK" ) -- SHIFT LOCK
d_SetWordEquate(hex("1190"), 0, "REVFLG" ) -- REVERSE FLAG
d_SetWordEquate(hex("1191"), 0, "SPAGE" ) -- PAGE CHANGE
d_SetWordEquate(hex("1192"), 0, "FLSDT" ) -- CURSOR DATA
d_SetWordEquate(hex("1193"), 0, "STRGF" ) -- STRING FLAG
d_SetWordEquate(hex("1194"), 0, "DPRNT" ) -- TAB COUNTER
d_SetWordEquate(hex("1195"), 0, "TMCNT" ) -- TAPE MARK COUNTER
d_SetWordEquate(hex("1197"), 0, "SUMDT" ) -- CHECK SUM DATA
d_SetWordEquate(hex("1199"), 0, "CSMDT" ) -- FOR COMPARE SUM DATA
d_SetWordEquate(hex("119B"), 0, "AMPM" ) -- AMPM DATA
d_SetWordEquate(hex("119C"), 0, "TIMFG" ) -- TIME FLAG
d_SetWordEquate(hex("119D"), 0, "SWRK" ) -- KEY SOUND FLAG
d_SetWordEquate(hex("119E"), 0, "TEMPW" ) -- TEMPO WORK
d_SetWordEquate(hex("119F"), 0, "ONTYO" ) -- ONTYO WORK
d_SetWordEquate(hex("11A0"), 0, "OCTV" ) -- OCTAVE WORK
d_SetWordEquate(hex("11A1"), 0, "RATIO" ) -- ONPU RATIO
d_SetWordEquate(hex("11A3"), 0, "BUFER" ) -- GET LINE BUFFER
----------------------------------------
-- End of configuration file
----------------------------------------

Binary file not shown.

BIN
hdr/CPM_RFS_1.hdr Normal file

Binary file not shown.

BIN
hdr/CPM_RFS_2.hdr Normal file

Binary file not shown.

BIN
hdr/cpm22.hdr Normal file

Binary file not shown.

BIN
hdr/sdtest.hdr Normal file

Binary file not shown.

30
proc_mzf.sh Executable file
View File

@@ -0,0 +1,30 @@
#!/bin/bash
ROOTDIR=/dvlp/Projects/dev/github
MZFDIR=${ROOTDIR}/MZF
MZBDIR=${ROOTDIR}/MZB
ls -l *.MZF *.mzf | sed 's/ / /g' | sed 's/ / /g' | cut -d' ' -f5,9- > /tmp/filelist
IFS=' '; while read -r FSIZE FNAME;
do
TNAME=`echo $FNAME | sed 's/mzf/MZF/g'`
if [ "$FNAME" != "$TNAME" ]; then
mv "$FNAME" "$TNAME"
fi
for BLOCKSIZE in 256 512 1024 2048 4096
do
for SECTORSIZE in `seq -s ' ' ${BLOCKSIZE} ${BLOCKSIZE} 65536`
do
BASE=`basename "$TNAME" .MZF`
if [ `echo ${FSIZE} - ${SECTORSIZE} | bc` -le 0 ];
then
echo $BASE $TNAME $SECTORSIZE
dd if=/dev/zero ibs=1 count=$SECTORSIZE 2>/dev/null | tr "\000" "\377" > "${MZBDIR}/$BASE.${BLOCKSIZE}.bin"
dd if="${MZFDIR}/$TNAME" of="${MZBDIR}/$BASE.${BLOCKSIZE}.bin" conv=notrunc 2>/dev/null
break;
fi
done
done
done </tmp/filelist

BIN
roms/IPL.rom Normal file

Binary file not shown.

BIN
roms/SA-5510_RFS.MZF Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
roms/blank_mrom.rom Normal file

Binary file not shown.

BIN
roms/cbios.rom Normal file

Binary file not shown.

BIN
roms/cbios_bank1.rom Normal file

Binary file not shown.

BIN
roms/cbios_bank2.rom Normal file

Binary file not shown.

BIN
roms/cbios_bank3.rom Normal file

Binary file not shown.

BIN
roms/cbios_bank4.rom Normal file

Binary file not shown.

BIN
roms/ipl.rom Normal file

Binary file not shown.

BIN
roms/monitor_1Z-013A.rom Normal file

Binary file not shown.

BIN
roms/monitor_1z-013a.rom Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
roms/monitor_80c_SA1510.rom Normal file

Binary file not shown.

Binary file not shown.

BIN
roms/monitor_80c_sa1510.rom Normal file

Binary file not shown.

Binary file not shown.

BIN
roms/monitor_SA1510.rom Normal file

Binary file not shown.

Binary file not shown.

BIN
roms/monitor_sa1510.rom Normal file

Binary file not shown.

Binary file not shown.

BIN
roms/mz80afi.rom Normal file

Binary file not shown.

BIN
roms/rfs.rom Normal file

Binary file not shown.

BIN
roms/rfs.tst.rom Normal file

Binary file not shown.

BIN
roms/rfs_mrom.rom Normal file

Binary file not shown.

53
src/PetitFS/00readme.txt Normal file
View File

@@ -0,0 +1,53 @@
Petit FatFs Module Source Files R0.03a (C)ChaN, 2019
FILES
pff.h Common include file for Petit FatFs and application module.
pff.c Petit FatFs module.
diskio.h Common include file for Petit FatFs and disk I/O module.
diskio.c Skeleton of low level disk I/O module.
Low level disk I/O module is not included in this archive because the Petit
FatFs module is only a generic file system layer and not depend on any
specific storage device. You have to provide a low level disk I/O module that
written to control your storage device.
AGREEMENTS
Petit FatFs module is an open source software to implement FAT file system to
small embedded systems. This is a free software and is opened for education,
research and commercial developments under license policy of following trems.
Copyright (C) 2019, ChaN, all right reserved.
* The Petit FatFs module is a free software and there is NO WARRANTY.
* No restriction on use. You can use, modify and redistribute it for
personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
* Redistributions of source code must retain the above copyright notice.
REVISION HISTORY
Jun 15, 2009 R0.01a First release (Branched from FatFs R0.07b)
Dec 14, 2009 R0.02 Added multiple code page support.
Added write funciton.
Changed stream read mode interface.
Dec 07,'2010 R0.02a Added some configuration options.
Fixed fails to open objects with DBCS character.
Jun 10, 2014 R0.03 Separated out configuration options to pffconf.h.
Added _USE_LCC option.
Added _FS_FAT16 option.
Jan 30, 2019 R0.03a Supported stdint.h for C99 and later.
Removed _WORD_ACCESS option.
Changed prefix of configuration options, _ to PF_.
Added some code pages.
Removed some code pages actually not valid.

136
src/PetitFS/Makefile Normal file
View File

@@ -0,0 +1,136 @@
#########################################################################################################
##
## Name: Makefile
## Created: January 2019
## Author(s): Philip Smart
## Description: PetitFS makefile
## This makefile builds the Petit FatFS for use in the RFS with banked ROMS.
##
## Credits:
## Copyright: (c) 2020 Philip Smart <philip.smart@net2net.org>
##
## History: March 2020 - Initial script written.
##
## Notes: Optional component enables:
##
#########################################################################################################
## 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/>.
#########################################################################################################
BASE =
CC = $(BASE)zcc
LD = $(BASE)zcc
AS = $(BASE)zcc
#CP = $(BASE)
#DUMP = $(BASE)
BASEDIR = ../..
#BASEDIR = ../../..
SWDIR = $(BASEDIR)/software
# we use printf from here
COMMON_DIR = $(SWDIR)/common
PFS_DIR = $(SWDIR)/common/PetitFS
INCLUDE_DIR = $(SWDIR)/include
# Working directory to build object files.
BUILD_DIR = pff_obj
COMMON_SRC = #$(COMMON_DIR)/sdmmc.c
PFS_SRC = $(PFS_DIR)/sdmmc.c $(PFS_DIR)/pff_func.c $(PFS_DIR)/pff_dir.c $(PFS_DIR)/pff_read.c $(PFS_DIR)/pff_write.c $(PFS_DIR)/pff_open.c $(PFS_DIR)/pff_mount.c
COMMON_OBJ = $(patsubst $(COMMON_DIR)/%.c,$(BUILD_DIR)/%.o,$(COMMON_SRC))
PFS_OBJ = $(patsubst $(PFS_DIR)/%.c,$(BUILD_DIR)/%.o,$(PFS_SRC))
COMMON_ASM = $(patsubst $(COMMON_DIR)/%.c,$(BUILD_DIR)/%.asm,$(COMMON_SRC))
PFS_ASM = $(patsubst $(PFS_DIR)/%.c,$(BUILD_DIR)/%.asm,$(PFS_SRC))
MAIN_PRJ = sdtest
MAIN_ASM = $(COMMON_ASM) $(PFS_ASM) $(patsubst %.c,$(BUILD_DIR)/%.asm,$(MAIN_SRC))
MAIN_SRC = sdtest.c
MAIN_OBJ = $(COMMON_OBJ) $(PFS_OBJ) $(patsubst %.c,$(BUILD_DIR)/%.o,$(MAIN_SRC))
MAIN_PRAGMA = rfs.inc
ROM_PRJ = rom
ROM_SRC =
ROM_OBJ = $(COMMON_OBJ) $(PFS_OBJ) $(patsubst %.c,$(BUILD_DIR)/%.o,$(ROM_SRC))
# Commandline options for each tool.
# To disable use of a given instruction, prefix it with no-
TARGET = +mz
VERBOSITY = -vn
OPTIMISATION = -O3
CFLAGS = $(TARGET) -pragma-define:REGISTER_SP=0xd000 -pragma-include:$(MAIN_PRAGMA) $(OPTIMISATION) -I. -I$(COMMON_DIR) -I$(PFS_DIR) -I$(INCLUDE_DIR) -lm $(VERBOSITY)
#
# Enable debug output.
OFLAGS += -DDEBUG
LFLAGS = $(TARGET) $(VERBOSITY) -pragma-define:REGISTER_SP=0xd000 -pragma-include:$(MAIN_PRAGMA) -lm -create-app -m
#
# Assembler flags.
ASFLAGS = $(TARGET) $(VERBOSITY) -c -I. -I$(COMMON_DIR) -I$(INCLUDE_DIR) -I$(STARTUP_DIR)
#
# Our target.
all: $(BUILD_DIR) $(MAIN_PRJ) #$(MAIN_ASM) #$(ROM_PRJ)
#
$(MAIN_PRJ): $(BUILD_DIR) $(MAIN_OBJ) #$(MAIN_PRJ).asm
$(MAIN_ASM): $(BUILD_DIR)
clean:
rm -f $(BUILD_DIR)/*.o *.hex *.lss *.elf *.map *.lst *.srec $(MAIN_PRJ) *~ */*.o *.bin *.srec *.dmp *.rpt *.ihx *.sym *.rel *.noi *.lk *.err *.mzt *.o
# Convert ELF binary to bin file.
%.bin: %.elf
@$(CP) -O binary $< $@
# Convert ELF to srec format for serial upload.
%.srec: %.elf
@$(CP) -O srec $< $@
# Link - this produces an ELF binary.
$(MAIN_PRJ): $(MAIN_OBJ)
$(CC) $(LFLAGS) $(MAIN_OBJ) -o $@ $(LIBS)
$(ROM_PRJ): $(ROM_OBJ)
$(CC) +z80 $(VERBOSITY) -pragma-define:REGISTER_SP=0xd000 -pragma-include:$(MAIN_PRAGMA) -lm -m $(ROM_OBJ) -o $@ $(LIBS)
$(BUILD_DIR)/%.o: %.c Makefile
$(CC) $(CFLAGS) $(OFLAGS) -o $@ -c $<
$(BUILD_DIR)/%.asm: %.c Makefile
$(CC) $(CFLAGS) $(OFLAGS) -a -o $@ -c $<
$(BUILD_DIR)/%.o: %.cpp Makefile
$(CC) $(CFLAGS) $(OFLAGS) -o $@ -c $<
$(BUILD_DIR)/%.o: %.asm Makefile
$(AS) $(ASFLAGS) -o $@ -c $<
$(BUILD_DIR)/%.o: $(COMMON_DIR)/%.c Makefile
$(CC) $(CFLAGS) $(OFLAGS) -o $@ -c $<
$(BUILD_DIR)/%.o: $(PFS_DIR)/%.c Makefile
$(CC) $(CFLAGS) $(OFLAGS) -o $@ -c $<
$(BUILD_DIR)/%.o: %.s
$(AS) $(ASFLAGS) -o $@ $<
$(BUILD_DIR)/%.o: $(STARTUP_DIR)/%.s
$(AS) $(ASFLAGS) -o $@ $<
$(BUILD_DIR):
mkdir $(BUILD_DIR)

95
src/PetitFS/diskio.asm Normal file
View File

@@ -0,0 +1,95 @@
;--------------------------------------------------------
; File Created by SDCC : free open source ANSI-C Compiler
; Version 4.0.0 #11528 (Linux)
;--------------------------------------------------------
.module diskio
.optsdcc -mz80
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
.globl _disk_initialize
.globl _disk_readp
.globl _disk_writep
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
.area _DATA
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
.area _INITIALIZED
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
.area _DABS (ABS)
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
.area _HOME
.area _GSINIT
.area _GSFINAL
.area _GSINIT
;--------------------------------------------------------
; Home
;--------------------------------------------------------
.area _HOME
.area _HOME
;--------------------------------------------------------
; code
;--------------------------------------------------------
.area _CODE
;diskio.c:12: DSTATUS disk_initialize (void)
; ---------------------------------
; Function disk_initialize
; ---------------------------------
_disk_initialize::
push ix
ld ix,#0
add ix,sp
dec sp
;diskio.c:18: return stat;
ld l, -1 (ix)
00101$:
;diskio.c:19: }
inc sp
pop ix
ret
;diskio.c:27: DRESULT disk_readp (
; ---------------------------------
; Function disk_readp
; ---------------------------------
_disk_readp::
push ix
ld ix,#0
add ix,sp
dec sp
;diskio.c:38: return res;
ld l, -1 (ix)
00101$:
;diskio.c:39: }
inc sp
pop ix
ret
;diskio.c:47: DRESULT disk_writep (
; ---------------------------------
; Function disk_writep
; ---------------------------------
_disk_writep::
push ix
ld ix,#0
add ix,sp
dec sp
;diskio.c:71: return res;
ld l, -1 (ix)
00103$:
;diskio.c:72: }
inc sp
pop ix
ret
.area _CODE
.area _INITIALIZER
.area _CABS (ABS)

73
src/PetitFS/diskiotmp.c Normal file
View File

@@ -0,0 +1,73 @@
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for Petit FatFs (C)ChaN, 2014 */
/*-----------------------------------------------------------------------*/
#include "diskio.h"
/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (void)
{
DSTATUS stat;
// Put your code here
return stat;
}
/*-----------------------------------------------------------------------*/
/* Read Partial Sector */
/*-----------------------------------------------------------------------*/
DRESULT disk_readp (
BYTE* buff, /* Pointer to the destination object */
DWORD sector, /* Sector number (LBA) */
UINT offset, /* Offset in the sector */
UINT count /* Byte count (bit15:destination) */
)
{
DRESULT res;
// Put your code here
return res;
}
/*-----------------------------------------------------------------------*/
/* Write Partial Sector */
/*-----------------------------------------------------------------------*/
DRESULT disk_writep (
BYTE* buff, /* Pointer to the data to be written, NULL:Initiate/Finalize write operation */
DWORD sc /* Sector number (LBA) or Number of bytes to send */
)
{
DRESULT res;
if (!buff) {
if (sc) {
// Initiate write process
} else {
// Finalize write process
}
} else {
// Send data to the disk
}
return res;
}

4534
src/PetitFS/pff.asm Normal file

File diff suppressed because it is too large Load Diff

1119
src/PetitFS/pff.c Normal file

File diff suppressed because it is too large Load Diff

4033
src/PetitFS/pff.c.asm Normal file

File diff suppressed because it is too large Load Diff

486
src/PetitFS/pff.h Normal file
View File

@@ -0,0 +1,486 @@
/*---------------------------------------------------------------------------/
/ Petit FatFs - FAT file system module include file R0.03a
/----------------------------------------------------------------------------/
/ Petit FatFs module is an open source software to implement FAT file system to
/ small embedded systems. This is a free software and is opened for education,
/ research and commercial developments under license policy of following trems.
/
/ Copyright (C) 2019, ChaN, all right reserved.
/ Modifications for RFS/Sharp MZ80A: Philip Smart, 2020
/
/ * The Petit FatFs module is a free software and there is NO WARRANTY.
/ * No restriction on use. You can use, modify and redistribute it for
/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
/ * Redistributions of source code must retain the above copyright notice.
/
/----------------------------------------------------------------------------*/
#ifndef PF_DEFINED
#define PF_DEFINED 8088 /* Revision ID */
#ifdef __cplusplus
extern "C" {
#endif
/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/---------------------------------------------------------------------------*/
#define PF_USE_LCC 0 /* Allow lower case ASCII and non-ASCII chars */
#define _FS_32ONLY 1
#define ABORT(err) {fs->flag = 0; return err;}
#define PF_CODE_PAGE 437
/* The PF_CODE_PAGE specifies the code page to be used on the target system.
/ SBCS code pages with PF_USE_LCC == 1 requiers a 128 byte of case conversion
/ table. It might occupy RAM on some platforms, e.g. avr-gcc.
/ When PF_USE_LCC == 0, PF_CODE_PAGE has no effect.
/
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
/ 771 - KBL
/ 775 - Baltic
/ 850 - Latin 1
/ 852 - Latin 2
/ 855 - Cyrillic
/ 857 - Turkish
/ 860 - Portuguese
/ 861 - Icelandic
/ 862 - Hebrew
/ 863 - Canadian French
/ 864 - Arabic
/ 865 - Nordic
/ 866 - Russian
/ 869 - Greek 2
/ 932 - Japanese (DBCS)
/ 936 - Simplified Chinese (DBCS)
/ 949 - Korean (DBCS)
/ 950 - Traditional Chinese (DBCS)
*/
/* Integer types used for FatFs API */
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
#include <stdint.h>
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
typedef unsigned char BYTE; /* char must be 8-bit */
typedef uint16_t WORD; /* 16-bit unsigned integer */
typedef uint16_t WCHAR; /* 16-bit unsigned integer */
typedef uint32_t DWORD; /* 32-bit unsigned integer */
#else /* Earlier than C99 */
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
typedef unsigned char BYTE; /* char must be 8-bit */
typedef unsigned short WORD; /* 16-bit unsigned integer */
typedef unsigned short WCHAR; /* 16-bit unsigned integer */
typedef unsigned long DWORD; /* 32-bit unsigned integer */
#endif
#define PF_INTDEF 1
#define CLUST DWORD
/* File system object structure */
typedef struct {
BYTE fs_type; /* FAT sub type */
BYTE flag; /* File status flags */
BYTE csize; /* Number of sectors per cluster */
BYTE pad1;
WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */
CLUST n_fatent; /* Number of FAT entries (= number of clusters + 2) */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */
DWORD database; /* Data start sector */
DWORD fptr; /* File R/W pointer */
DWORD fsize; /* File size */
CLUST org_clust; /* File start cluster */
CLUST curr_clust; /* File current cluster */
DWORD dsect; /* File current data sector */
} FATFS;
/* Directory object structure */
typedef struct {
WORD index; /* Current read/write index number */
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
CLUST sclust; /* Table start cluster (0:Static table) */
CLUST clust; /* Current cluster */
DWORD sect; /* Current sector */
} DIR;
/* File status structure */
typedef struct {
DWORD fsize; /* File size */
WORD fdate; /* Last modified date */
WORD ftime; /* Last modified time */
BYTE fattrib; /* Attribute */
char fname[13]; /* File name */
} FILINFO;
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* 0 */
FR_DISK_ERR, /* 1 */
FR_NOT_READY, /* 2 */
FR_NO_FILE, /* 3 */
FR_NOT_OPENED, /* 4 */
FR_NOT_ENABLED, /* 5 */
FR_NO_FILESYSTEM /* 6 */
} FRESULT;
/*--------------------------------------------------------------*/
/* Petit FatFs module application interface */
FRESULT pf_mount (FATFS* fs); /* Mount/Unmount a logical drive */
FRESULT pf_open (const char* path); /* Open a file */
FRESULT pf_read (void* buff, UINT btr, UINT* br); /* Read data from the open file */
FRESULT pf_write (const void* buff, UINT btw, UINT* bw); /* Write data to the open file */
FRESULT pf_lseek (DWORD ofs); /* Move file pointer of the open file */
FRESULT pf_opendir (DIR* dj, const char* path); /* Open a directory */
FRESULT pf_readdir (DIR* dj, FILINFO* fno); /* Read a directory item from the open directory */
/*--------------------------------------------------------------*/
/* Flags and offset address */
/* File status flag (FATFS.flag) */
#define FA_OPENED 0x01
#define FA_WPRT 0x02
#define FA__WIP 0x40
/* FAT sub type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
/* File attribute bits for directory entry */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#define AM_MASK 0x3F /* Mask of defined bits */
/*--------------------------------------------------------*/
/* DBCS code ranges and SBCS extend char conversion table */
/*--------------------------------------------------------*/
#if PF_USE_LCC == 0 /* ASCII upper case character only */
#elif PF_CODE_PAGE == 932 /* Japanese Shift-JIS */
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
#elif PF_CODE_PAGE == 936 /* Simplified Chinese GBK */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x40
#define _DS1E 0x7E
#define _DS2S 0x80
#define _DS2E 0xFE
#elif PF_CODE_PAGE == 949 /* Korean */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x41
#define _DS1E 0x5A
#define _DS2S 0x61
#define _DS2E 0x7A
#define _DS3S 0x81
#define _DS3E 0xFE
#elif PF_CODE_PAGE == 950 /* Traditional Chinese Big5 */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x40
#define _DS1E 0x7E
#define _DS2S 0xA1
#define _DS2E 0xFE
#elif PF_CODE_PAGE == 437 /* U.S. */
#define _EXCVT {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \
0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif PF_CODE_PAGE == 720 /* Arabic */
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif PF_CODE_PAGE == 737 /* Greek */
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xEF,0xF5,0xF0,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif PF_CODE_PAGE == 771 /* KBL */
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDC,0xDE,0xDE, \
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFE,0xFF}
#elif PF_CODE_PAGE == 775 /* Baltic */
#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F, \
0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF, \
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif PF_CODE_PAGE == 850 /* Latin 1 */
#define _EXCVT {0x43,0x55,0x45,0x41,0x41,0x41,0x41,0x43,0x45,0x45,0x45,0x49,0x49,0x49,0x41,0x41, \
0x45,0x92,0x92,0x4F,0x4F,0x4F,0x55,0x55,0x59,0x4F,0x55,0x4F,0x9C,0x4F,0x9E,0x9F, \
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0x41,0x41,0x41,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0x41,0x41,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD1,0xD1,0x45,0x45,0x45,0x49,0x49,0x49,0x49,0xD9,0xDA,0xDB,0xDC,0xDD,0x49,0xDF, \
0x4F,0xE1,0x4F,0x4F,0x4F,0x4F,0xE6,0xE8,0xE8,0x55,0x55,0x55,0x59,0x59,0xEE,0xEF, \
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif PF_CODE_PAGE == 852 /* Latin 2 */
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F, \
0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0xAC, \
0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF, \
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
#elif PF_CODE_PAGE == 855 /* Cyrillic */
#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F, \
0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF, \
0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
#elif PF_CODE_PAGE == 857 /* Turkish */
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x49,0x8E,0x8F, \
0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD0,0xD1,0xD2,0xD3,0xD4,0x49,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0xED,0xEE,0xEF, \
#elif PF_CODE_PAGE == 860 /* Portuguese */
#define _EXCVT {0x80,0x9A,0x90,0x8F,0x8E,0x91,0x86,0x80,0x89,0x89,0x92,0x8B,0x8C,0x98,0x8E,0x8F, \
0x90,0x91,0x92,0x8C,0x99,0xA9,0x96,0x9D,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0x86,0x8B,0x9F,0x96,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif PF_CODE_PAGE == 861 /* Icelandic */
#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x8B,0x8B,0x8D,0x8E,0x8F, \
0x90,0x92,0x92,0x4F,0x99,0x8D,0x55,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
0xA4,0xA5,0xA6,0xA7,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif PF_CODE_PAGE == 862 /* Hebrew */
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif PF_CODE_PAGE == 863 /* Canadian French */
#define _EXCVT {0x43,0x55,0x45,0x41,0x41,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x41,0x8F, \
0x45,0x45,0x45,0x4F,0x45,0x49,0x55,0x55,0x98,0x4F,0x55,0x9B,0x9C,0x55,0x55,0x9F, \
0xA0,0xA1,0x4F,0x55,0xA4,0xA5,0xA6,0xA7,0x49,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif PF_CODE_PAGE == 864 /* Arabic */
#define _EXCVT {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \
0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif PF_CODE_PAGE == 865 /* Nordic */
#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \
0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif PF_CODE_PAGE == 866 /* Russian */
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif PF_CODE_PAGE == 869 /* Greek 2 */
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x86,0x9C,0x8D,0x8F,0x90, \
0x91,0x90,0x92,0x95,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xA4,0xA5,0xA6,0xD9,0xDA,0xDB,0xDC,0xA7,0xA8,0xDF, \
0xA9,0xAA,0xAC,0xAD,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xCF,0xCF,0xD0,0xEF, \
0xF0,0xF1,0xD1,0xD2,0xD3,0xF5,0xD4,0xF7,0xF8,0xF9,0xD5,0x96,0x95,0x98,0xFE,0xFF}
#else
#error Unknown code page.
#endif
/* Character code support macros */
#define IsUpper(c) (((c)>='A')&&((c)<='Z'))
#define IsLower(c) (((c)>='a')&&((c)<='z'))
#if PF_USE_LCC && !defined(_EXCVT) /* DBCS configuration */
#ifdef _DF2S /* Two 1st byte areas */
#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
#else /* One 1st byte area */
#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
#endif
#ifdef _DS3S /* Three 2nd byte areas */
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
#else /* Two 2nd byte areas */
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
#endif
#else /* SBCS configuration */
#define IsDBCS1(c) 0
#define IsDBCS2(c) 0
#endif /* _EXCVT */
/* FatFs refers the members in the FAT structures with byte offset instead
/ of structure member because there are incompatibility of the packing option
/ between various compilers. */
#define BS_jmpBoot 0
#define BS_OEMName 3
#define BPB_BytsPerSec 11
#define BPB_SecPerClus 13
#define BPB_RsvdSecCnt 14
#define BPB_NumFATs 16
#define BPB_RootEntCnt 17
#define BPB_TotSec16 19
#define BPB_Media 21
#define BPB_FATSz16 22
#define BPB_SecPerTrk 24
#define BPB_NumHeads 26
#define BPB_HiddSec 28
#define BPB_TotSec32 32
#define BS_55AA 510
#define BS_DrvNum 36
#define BS_BootSig 38
#define BS_VolID 39
#define BS_VolLab 43
#define BS_FilSysType 54
#define BPB_FATSz32 36
#define BPB_ExtFlags 40
#define BPB_FSVer 42
#define BPB_RootClus 44
#define BPB_FSInfo 48
#define BPB_BkBootSec 50
#define BS_DrvNum32 64
#define BS_BootSig32 66
#define BS_VolID32 67
#define BS_VolLab32 71
#define BS_FilSysType32 82
#define MBR_Table 446
#define DIR_Name 0
#define DIR_Attr 11
#define DIR_NTres 12
#define DIR_CrtTime 14
#define DIR_CrtDate 16
#define DIR_FstClusHI 20
#define DIR_WrtTime 22
#define DIR_WrtDate 24
#define DIR_FstClusLO 26
#define DIR_FileSize 28
extern FATFS *FatFs; /* Pointer to the file system object (logical drive) */
#ifdef __cplusplus
}
#endif
#endif /* _PFATFS */

302
src/PetitFS/pff_dir.c Normal file
View File

@@ -0,0 +1,302 @@
/*----------------------------------------------------------------------------/
/ Petit FatFs - FAT file system module R0.03a
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2019, ChaN, all right reserved.
/ Modifications for RFS/Sharp MZ80A: Philip Smart, 2020
/
/ Petit FatFs module is an open source software. Redistribution and use of
/ Petit FatFs in source and binary forms, with or without modification, are
/ permitted provided that the following condition is met:
/
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/-----------------------------------------------------------------------------/
/ Jun 15,'09 R0.01a First release.
/
/ Dec 14,'09 R0.02 Added multiple code page support.
/ Added write funciton.
/ Changed stream read mode interface.
/ Dec 07,'10 R0.02a Added some configuration options.
/ Fixed fails to open objects with DBCS character.
/ Jun 10,'14 R0.03 Separated out configuration options to pffconf.h.
/ Added _USE_LCC option.
/ Added _FS_FAT16 option.
/
/ Jan 30,'19 R0.03a Supported stdint.h for C99 and later.
/ Removed _WORD_ACCESS option.
/ Changed prefix of configuration options, _ to PF_.
/ Added some code pages.
/ Removed some code pages actually not valid.
/
/ Mar 12,'20 R0.04 Removal of all non-FAT32 code and adapted for use in
/ banked ROMS as part of the RFS on the Sharp MZ80A.
/----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include "pff.h" /* Petit FatFs configurations and declarations */
#include "sdmmc.h" /* Declarations of low level disk I/O functions */
#include "pff_func.h"
#define PFF_DIR_C
#include "pff_dir.h"
/*-----------------------------------------------------------------------*/
/* Directory handling - Rewind directory index */
/*-----------------------------------------------------------------------*/
FRESULT dir_rewind (
DIR *dj /* Pointer to directory object */
)
{
CLUST clst;
FATFS *fs = FatFs;
dj->index = 0;
clst = dj->sclust;
if (clst == 1 || clst >= fs->n_fatent) { /* Check start cluster range */
return FR_DISK_ERR;
}
if(!clst)
{
clst = (CLUST)fs->dirbase;
}
dj->clust = clst; /* Current cluster */
dj->sect = clust2sect(clst); /* Current sector */
return FR_OK; /* Seek succeeded */
}
/*-----------------------------------------------------------------------*/
/* Directory handling - Move directory index next */
/*-----------------------------------------------------------------------*/
FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table */
DIR *dj /* Pointer to directory object */
)
{
CLUST clst;
WORD i;
FATFS *fs = FatFs;
i = dj->index + 1;
if (!i || !dj->sect) return FR_NO_FILE; /* Report EOT when index has reached 65535 */
if (!(i % 16)) { /* Sector changed? */
dj->sect++; /* Next sector */
if (dj->clust == 0) { /* Static table */
if (i >= fs->n_rootdir) return FR_NO_FILE; /* Report EOT when end of table */
}
else { /* Dynamic table */
if (((i / 16) & (fs->csize - 1)) == 0) { /* Cluster changed? */
clst = get_fat(dj->clust); /* Get next cluster */
if (clst <= 1) return FR_DISK_ERR;
if (clst >= fs->n_fatent) return FR_NO_FILE; /* Report EOT when it reached end of dynamic table */
dj->clust = clst; /* Initialize data for new cluster */
dj->sect = clust2sect(clst);
}
}
}
dj->index = i;
return FR_OK;
}
/*-----------------------------------------------------------------------*/
/* Directory handling - Find an object in the directory */
/*-----------------------------------------------------------------------*/
FRESULT dir_find (
DIR *dj, /* Pointer to the directory object linked to the file name */
BYTE *dir /* 32-byte working buffer */
)
{
FRESULT res;
BYTE c;
res = dir_rewind(dj); /* Rewind directory object */
if (res != FR_OK) return res;
do {
res = disk_readp(dir, dj->sect, (dj->index % 16) * 32, 32) /* Read an entry */
? FR_DISK_ERR : FR_OK;
if (res != FR_OK) break;
c = dir[DIR_Name]; /* First character */
if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) break; /* Is it a valid entry? */
res = dir_next(dj); /* Next entry */
} while (res == FR_OK);
return res;
}
/*-----------------------------------------------------------------------*/
/* Read an object from the directory */
/*-----------------------------------------------------------------------*/
FRESULT dir_read (
DIR *dj, /* Pointer to the directory object to store read object name */
BYTE *dir /* 32-byte working buffer */
)
{
FRESULT res;
BYTE a, c;
res = FR_NO_FILE;
while (dj->sect) {
res = disk_readp(dir, dj->sect, (dj->index % 16) * 32, 32) /* Read an entry */
? FR_DISK_ERR : FR_OK;
if (res != FR_OK) break;
c = dir[DIR_Name];
if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
a = dir[DIR_Attr] & AM_MASK;
if (c != 0xE5 && c != '.' && !(a & AM_VOL)) break; /* Is it a valid entry? */
res = dir_next(dj); /* Next entry */
if (res != FR_OK) break;
}
if (res != FR_OK) dj->sect = 0;
return res;
}
/*-----------------------------------------------------------------------*/
/* Get file information from directory entry */
/*-----------------------------------------------------------------------*/
void get_fileinfo ( /* No return code */
DIR *dj, /* Pointer to the directory object */
BYTE *dir, /* 32-byte working buffer */
FILINFO *fno /* Pointer to store the file information */
)
{
BYTE i, c;
char *p;
p = fno->fname;
if (dj->sect) {
for (i = 0; i < 8; i++) { /* Copy file name body */
c = dir[i];
if (c == ' ') break;
if (c == 0x05) c = 0xE5;
*p++ = c;
}
if (dir[8] != ' ') { /* Copy file name extension */
*p++ = '.';
for (i = 8; i < 11; i++) {
c = dir[i];
if (c == ' ') break;
*p++ = c;
}
}
fno->fattrib = dir[DIR_Attr]; /* Attribute */
fno->fsize = ld_dword(dir+DIR_FileSize); /* Size */
fno->fdate = ld_word(dir+DIR_WrtDate); /* Date */
fno->ftime = ld_word(dir+DIR_WrtTime); /* Time */
}
*p = 0;
}
/*--------------------------------------------------------------------------
Public Functions
--------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/* Create a Directroy Object */
/*-----------------------------------------------------------------------*/
FRESULT pf_opendir (
DIR *dj, /* Pointer to directory object to create */
const char *path /* Pointer to the directory path */
)
{
FRESULT res;
BYTE sp[12], dir[32];
FATFS *fs = FatFs;
if (!fs) { /* Check file system */
res = FR_NOT_ENABLED;
} else {
dj->fn = sp;
res = follow_path(dj, dir, path); /* Follow the path to the directory */
if (res == FR_OK) { /* Follow completed */
if (dir[0]) { /* It is not the root dir */
if (dir[DIR_Attr] & AM_DIR) { /* The object is a directory */
dj->sclust = get_clust(dir);
} else { /* The object is not a directory */
res = FR_NO_FILE;
}
}
if (res == FR_OK) {
res = dir_rewind(dj); /* Rewind dir */
}
}
}
return res;
}
/*-----------------------------------------------------------------------*/
/* Read Directory Entry in Sequense */
/*-----------------------------------------------------------------------*/
FRESULT pf_readdir (
DIR *dj, /* Pointer to the open directory object */
FILINFO *fno /* Pointer to file information to return */
)
{
FRESULT res;
BYTE sp[12], dir[32];
FATFS *fs = FatFs;
if (!fs) { /* Check file system */
res = FR_NOT_ENABLED;
} else {
dj->fn = sp;
if (!fno) {
res = dir_rewind(dj);
} else {
res = dir_read(dj, dir); /* Get current directory item */
if (res == FR_NO_FILE) res = FR_OK;
if (res == FR_OK) { /* A valid entry is found */
get_fileinfo(dj, dir, fno); /* Get the object information */
res = dir_next(dj); /* Increment read index for next */
// if (res == FR_NO_FILE) res = FR_OK;
}
}
}
return res;
}

39
src/PetitFS/pff_dir.h Normal file
View File

@@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------/
/ Petit FatFs - FAT file system module include file R0.03a
/----------------------------------------------------------------------------/
/ Petit FatFs module is an open source software to implement FAT file system to
/ small embedded systems. This is a free software and is opened for education,
/ research and commercial developments under license policy of following trems.
/
/ Copyright (C) 2019, ChaN, all right reserved.
/ Modifications for RFS/Sharp MZ80A: Philip Smart, 2020
/
/ * The Petit FatFs module is a free software and there is NO WARRANTY.
/ * No restriction on use. You can use, modify and redistribute it for
/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
/ * Redistributions of source code must retain the above copyright notice.
/
/----------------------------------------------------------------------------*/
#ifndef PF_DIR_DEFINED
#define PF_DIR_DEFINED 8088 /* Revision ID */
#ifdef __cplusplus
extern "C" {
#endif
/*--------------------------------------------------------------*/
/* Petit FatFs module application interface */
FRESULT dir_rewind(DIR *dj);
FRESULT dir_next(DIR *dj);
FRESULT dir_find(DIR *dj, BYTE *dir);
FRESULT dir_read(DIR *dj, BYTE *dir);
void get_fileinfo(DIR *dj, BYTE *dir, FILINFO *fno);
#ifdef __cplusplus
}
#endif
#endif

272
src/PetitFS/pff_func.c Normal file
View File

@@ -0,0 +1,272 @@
/*----------------------------------------------------------------------------/
/ Petit FatFs - FAT file system module R0.03a
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2019, ChaN, all right reserved.
/ Modifications for RFS/Sharp MZ80A: Philip Smart, 2020
/
/ Petit FatFs module is an open source software. Redistribution and use of
/ Petit FatFs in source and binary forms, with or without modification, are
/ permitted provided that the following condition is met:
/
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/-----------------------------------------------------------------------------/
/ Jun 15,'09 R0.01a First release.
/
/ Dec 14,'09 R0.02 Added multiple code page support.
/ Added write funciton.
/ Changed stream read mode interface.
/ Dec 07,'10 R0.02a Added some configuration options.
/ Fixed fails to open objects with DBCS character.
/ Jun 10,'14 R0.03 Separated out configuration options to pffconf.h.
/ Added _USE_LCC option.
/ Added _FS_FAT16 option.
/
/ Jan 30,'19 R0.03a Supported stdint.h for C99 and later.
/ Removed _WORD_ACCESS option.
/ Changed prefix of configuration options, _ to PF_.
/ Added some code pages.
/ Removed some code pages actually not valid.
/
/ Mar 12,'20 R0.04 Removal of all non-FAT32 code and adapted for use in
/ banked ROMS as part of the RFS on the Sharp MZ80A.
/----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include "pff.h" /* Petit FatFs configurations and declarations */
#include "sdmmc.h" /* Declarations of low level disk I/O functions */
#define PFF_FUNC_C
#include "pff_func.h"
/*--------------------------------------------------------------------------
Module Private Definitions
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------
Private Functions
---------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/* Load multi-byte word in the FAT structure */
/*-----------------------------------------------------------------------*/
WORD ld_word (const BYTE* ptr) /* Load a 2-byte little-endian word */
{
WORD rv;
rv = ptr[1];
rv = rv << 8 | ptr[0];
return rv;
}
DWORD ld_dword (const BYTE* ptr) /* Load a 4-byte little-endian word */
{
DWORD rv;
rv = ptr[3];
rv = rv << 8 | ptr[2];
rv = rv << 8 | ptr[1];
rv = rv << 8 | ptr[0];
return rv;
}
/*-----------------------------------------------------------------------*/
/* String functions */
/*-----------------------------------------------------------------------*/
/* Fill memory block */
void mem_set (void* dst, int val, int cnt) {
char *d = (char*)dst;
while (cnt--) *d++ = (char)val;
}
/* Compare memory block */
int mem_cmp (const void* dst, const void* src, int cnt) {
const char *d = (const char *)dst, *s = (const char *)src;
int r = 0;
while (cnt-- && (r = *d++ - *s++) == 0) ;
return r;
}
/*-----------------------------------------------------------------------*/
/* FAT access - Read value of a FAT entry */
/*-----------------------------------------------------------------------*/
CLUST get_fat ( /* 1:IO error, Else:Cluster status */
CLUST clst /* Cluster# to get the link information */
)
{
BYTE buf[4];
FATFS *fs = FatFs;
if (clst < 2 || clst >= fs->n_fatent) return 1; /* Range check */
switch (fs->fs_type) {
case FS_FAT32 :
if (disk_readp(buf, fs->fatbase + clst / 128, ((UINT)clst % 128) * 4, 4)) break;
return ld_dword(buf) & 0x0FFFFFFF;
}
return 1; /* An error occured at the disk I/O layer */
}
/*-----------------------------------------------------------------------*/
/* Get sector# from cluster# / Get cluster field from directory entry */
/*-----------------------------------------------------------------------*/
DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
CLUST clst /* Cluster# to be converted */
)
{
FATFS *fs = FatFs;
clst -= 2;
if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */
return (DWORD)clst * fs->csize + fs->database;
}
CLUST get_clust (
BYTE* dir /* Pointer to directory entry */
)
{
FATFS *fs = FatFs;
CLUST clst = 0;
clst = ld_word(dir+DIR_FstClusHI);
clst <<= 16;
clst |= ld_word(dir+DIR_FstClusLO);
return clst;
}
/*-----------------------------------------------------------------------*/
/* Pick a segment and create the object name in directory form */
/*-----------------------------------------------------------------------*/
FRESULT create_name (
DIR *dj, /* Pointer to the directory object */
const char **path /* Pointer to pointer to the segment in the path string */
)
{
BYTE c, d, ni, si, i, *sfn;
const char *p;
#if PF_USE_LCC && defined(_EXCVT)
static const BYTE cvt[] = _EXCVT;
#endif
/* Create file name in directory form */
sfn = dj->fn;
mem_set(sfn, ' ', 11);
si = i = 0; ni = 8;
p = *path;
for (;;) {
c = p[si++];
if (c <= ' ' || c == '/') break; /* Break on end of segment */
if (c == '.' || i >= ni) {
if (ni != 8 || c != '.') break;
i = 8; ni = 11;
continue;
}
#if PF_USE_LCC && defined(_EXCVT)
if (c >= 0x80) c = cvt[c - 0x80]; /* To upper extended char (SBCS) */
#endif
if (IsDBCS1(c) && i < ni - 1) { /* DBC 1st byte? */
d = p[si++]; /* Get 2nd byte */
sfn[i++] = c;
sfn[i++] = d;
} else { /* Single byte code */
if (PF_USE_LCC && IsLower(c)) c -= 0x20; /* toupper */
sfn[i++] = c;
}
}
*path = &p[si]; /* Rerurn pointer to the next segment */
sfn[11] = (c <= ' ') ? 1 : 0; /* Set last segment flag if end of path */
return FR_OK;
}
/*-----------------------------------------------------------------------*/
/* Follow a file path */
/*-----------------------------------------------------------------------*/
FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */
DIR *dj, /* Directory object to return last directory and found object */
BYTE *dir, /* 32-byte working buffer */
const char *path /* Full-path string to find a file or directory */
)
{
FRESULT res;
while (*path == ' ') path++; /* Strip leading spaces */
if (*path == '/') path++; /* Strip heading separator if exist */
dj->sclust = 0; /* Set start directory (always root dir) */
if ((BYTE)*path < ' ') { /* Null path means the root directory */
res = dir_rewind(dj);
dir[0] = 0;
} else { /* Follow path */
for (;;) {
res = create_name(dj, &path); /* Get a segment */
if (res != FR_OK) break;
res = dir_find(dj, dir); /* Find it */
if (res != FR_OK) break; /* Could not find the object */
if (dj->fn[11]) break; /* Last segment match. Function completed. */
if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow path because it is a file */
res = FR_NO_FILE; break;
}
dj->sclust = get_clust(dir); /* Follow next */
}
}
return res;
}
/*-----------------------------------------------------------------------*/
/* Check a sector if it is an FAT boot record */
/*-----------------------------------------------------------------------*/
BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */
BYTE *buf, /* Working buffer */
DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */
)
{
if (disk_readp(buf, sect, 510, 2)) { /* Read the boot record */
return 3;
}
if (ld_word(buf) != 0xAA55) { /* Check record signature */
return 2;
}
// if (!_FS_32ONLY && !disk_readp(buf, sect, BS_FilSysType, 2) && ld_word(buf) == 0x4146) { /* Check FAT12/16 */
// return 0;
// }
if (!disk_readp(buf, sect, BS_FilSysType32, 2) && ld_word(buf) == 0x4146) { /* Check FAT32 */
return 0;
}
return 1;
}

Some files were not shown because too many files have changed in this diff Show More