Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78fddfb2eb | ||
|
|
066e049538 | ||
|
|
e3771cdf9c | ||
|
|
0a0ed14c6c | ||
| 9baeec811b | |||
|
|
75fb464b4d | ||
|
|
dcb308f0df | ||
|
|
5fa8d1fada | ||
|
|
462052140e | ||
|
|
5d0daa838e | ||
|
|
1ff4b558a5 |
21
.gitignore
vendored
21
.gitignore
vendored
@@ -1743,3 +1743,24 @@ software/FusionX/src/z80drv/src/z80driver.c.bad
|
||||
software/FusionX/src/z80drv/src/z80vhw_rfs.c.bad
|
||||
CPLD/v1.0/MZ2000.old/
|
||||
|
||||
# Un-ignore files needed for CI/CD builds
|
||||
!software/asm/
|
||||
!software/asm/*.asm
|
||||
!software/asm/include/
|
||||
!software/asm/include/*.asm
|
||||
!software/tools/
|
||||
!software/tools/assemble_*.sh
|
||||
!software/tools/copytosd.sh
|
||||
!software/tools/make_cpmdisks.sh
|
||||
!software/tools/glass*.jar
|
||||
!software/tools/dz80
|
||||
!software/tools/dz80_v20
|
||||
!software/tools/nasconv
|
||||
!software/tools/mzftool.pl
|
||||
!software/tools/flashmmcfg
|
||||
!software/tmp/
|
||||
!software/roms/
|
||||
!software/roms/*.rom
|
||||
!software/roms/*.bin
|
||||
!software/roms/*.BIN
|
||||
!software/roms/*.ori
|
||||
|
||||
572
README.md
vendored
572
README.md
vendored
@@ -1,4 +1,10 @@
|
||||
<img src='http://eaw.app/images/FusionX_Wired.png' height='70%' width='70%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
# tzpuFusionX
|
||||
|
||||
**Website:** [engineers@work](https://eaw.app) | **Repository:** [git.eaw.app/eaw/tzpuFusionX](https://git.eaw.app/eaw/tzpuFusionX)
|
||||
|
||||
---
|
||||
|
||||
<img src='../images/FusionX_Wired.png' height='70%' width='70%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
|
||||
## <font style="color: yellow;" size="6">Overview</font>
|
||||
|
||||
@@ -7,7 +13,7 @@ The tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> is a spinoff concept from the tra
|
||||
rapid application loading from SD card and by using a daughter board, better graphics and sound.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The <i>FusionX</i> board can also be used to power alternative CPU's on the host for testing, development and to provide a completely different software platform and applications. It can use the underlying hosts keyboard, monitor, I/O and additionally better graphics and sound provided by the <i>FusionX</i>.
|
||||
The <i>FusionX</i> board can also be used to power alternative CPUs on the host for testing, development and to provide a completely different software platform and applications. It can use the underlying hosts keyboard, monitor, I/O and additionally better graphics and sound provided by the <i>FusionX</i>.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
It shares similarities with the tran<i>ZPU</i>ter<sup><i>Fusion</i></sup> but instead of realising it in hardware via an FPGA it realises
|
||||
@@ -18,7 +24,7 @@ Using the same base design as the tran<i>ZPU</i>ter<sup><i>Fusion</i></sup> it i
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
In Z80 configuration, a Linux Kernel driver instantiates a Z80 emulation which realises a Z80 CPU in software which in turn can command and control the host system. The kernel driver along with a controlling application
|
||||
can provide a wealth of features to the host through this mechanism. The SOM is also connected to an SD Drive and USB 2.0 port so there is no limit to features which can be proivded.
|
||||
can provide a wealth of features to the host through this mechanism. The SOM is also connected to an SD Drive and USB 2.0 port so there is no limit to features which can be provided.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
Like the tran<i>ZPU</i>ter<sup><i>Fusion</i></sup>, the tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> can provide enhanced video and sound to the host. The SOM incorporates dual DAC audio and a 2D GPU with configurable resolutions switched onto the hosts video and audio outputs under software control.
|
||||
@@ -27,8 +33,8 @@ Like the tran<i>ZPU</i>ter<sup><i>Fusion</i></sup>, the tran<i>ZPU</i>ter<sup><i
|
||||
The <i>FusionX</i> board is ideal for any developer wanting to physically program and interact with retro hardware using a Linux platform with Wifi and USB/Serial port connectivity.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
To most retro users, in the early stages of <i>FusionX</i> development, the board wont have much use. As the project matures, a board can be obtained and installed into the Z80 socket of their Sharp or simlar Z80 based system (providing there is sufficient room to accommodate this board) and utilise the upgraded featues, such as:
|
||||
<ul style="line-height: 0.9em;"><font size="3">
|
||||
To most retro users, in the early stages of <i>FusionX</i> development, the board won't have much use. As the project matures, a board can be obtained and installed into the Z80 socket of their Sharp or similar Z80 based system (providing there is sufficient room to accommodate this board) and utilise the upgraded features, such as:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">Original host specifications</font><br>- the machine behaves just as though it had a physical Z80 within. There might be slight differences in the Z80 functionality as it is implemented in software but the Z80 hardware timing is accurate.</li>
|
||||
<li><font style="color: orange;" size="3">Accelerator</font><br>- the Z80 can run at much higher speeds due to the abundance of memory and 1.2GHz dual-core processor, which would typically see performance upto that of a 500MHz Z80.</li>
|
||||
<li><font style="color: orange;" size="3">Emulation</font><br>- emulation of all the Sharp MZ series machines, experiencing it through the host system keyboard, monitor and I/O.</li>
|
||||
@@ -82,13 +88,13 @@ thus the CPLD is able to drive 5V circuitry and with sufficient drive current, 2
|
||||
The CPLD internal state machines are clocked by an external 50MHz oscillator, this allows for adequate sampling and state change for a typical 1MHz - 6MHz Z80 host.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">Schematic 2 - I/O (Audio, UART, USB)</font>
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The SOM is rich in peripherals and this circuit interfaces some of them for use in the FusionX, these include:
|
||||
|
||||
<ul style="line-height: 0.9em;"><font size="3">
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">Stereo Audio Microphone input</font><br>- a digital microphone input is also available but the pins are used in the CPLD interface.</li>
|
||||
<li><font style="color: orange;" size="3">Stereo Audio DAC output</font><br>- dual digital to analogue converters for sound output which can be clocked at 48KHz.</li>
|
||||
<li><font style="color: orange;" size="3">WiFi Antenna</font><br>- a SSW101B 20/40MHz IEEE 802.11 b/g/n/e/l/n/w WiFi transceiver operating in the 2.4GHz band with a 500M range. The SOM also includes a 100MHz ETH PHY but this is not used in this design as hard wired ethernet is not practical for a board which is
|
||||
@@ -97,12 +103,12 @@ sited inside a retro machine.</li>
|
||||
<li><font style="color: orange;" size="3">USB</font><br>- a Linux connected USB port allowing for device expansion, such as additional storage, mice etc.</li>
|
||||
<li><font style="color: orange;" size="3">Fast UART</font><br>- high speed full duplex with hardware handshake UART.</li>
|
||||
<li><font style="color: orange;" size="3">UART</font><br>- standard 2 pin UART operating upto 500KHz.</li>
|
||||
<li><font style="color: orange;" size="3">SD Card</font><br>- the SOM has inbuilt FlashNAND so can accomodate a simple Linux filesystem, addition of an SD card allows for greater storage of Host applications and Linux utilities. An SD card also makes for ease of upgrades as the SOM will auto upgrade when a suitably prepared SD card is present on boot.</li>
|
||||
<li><font style="color: orange;" size="3">SD Card</font><br>- the SOM has inbuilt FlashNAND so can accommodate a simple Linux filesystem, addition of an SD card allows for greater storage of Host applications and Linux utilities. An SD card also makes for ease of upgrades as the SOM will auto upgrade when a suitably prepared SD card is present on boot.</li>
|
||||
</font></ul>
|
||||
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">Schematic 3 - Video (VideoDAC, Contrast DAC)</font>
|
||||
|
||||
@@ -117,7 +123,7 @@ DAC, as it is sending the video signal with colour information as a voltage cont
|
||||
In order to get true black, the CPLD creates a blanking signal, MONO.BLANK, which is paired with a MUX 0V clamp on the daughter board which drives the monochrome monitor, this sees the RGB332 as 0V when 00000000 is present, then varying between 4.01V-5V when non-zero.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">Schematic 4 - Power Supply (3.3V, USB)</font>
|
||||
|
||||
@@ -128,7 +134,7 @@ The power supply, for the SOM and CPLD, converts the 5V present on the Z80 socke
|
||||
Additionally, a software controlled USB power switch is installed to enable (and reset if required) +5V power to the USB expansion port.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">Schematic 5 - CPLD Interface</font>
|
||||
|
||||
@@ -136,70 +142,490 @@ Additionally, a software controlled USB power switch is installed to enable (and
|
||||
The final schematic is the interface between the SOM and the CPLD. Originally this was going to be a bi-directional 16bit bus with Read/Write and Strobe signals but after testing, the setup time for a 16bit signal with tri-state switching was much slower than an SPI connection
|
||||
due to the GPIO register layout and operation within the SOM and the speed of the I/O operations within the SOM.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
The solution used is to have a bidirectional 72MHz SPI bus between the SOM and CPLD for transmitting Z80 transaction requests and an 8bit read only parallel bus for more rapid reading of Z80 Data and seperate Z80 state information.
|
||||
The solution used is to have a bidirectional 72MHz SPI bus between the SOM and CPLD for transmitting Z80 transaction requests and an 8bit read only parallel bus for more rapid reading of Z80 Data and separate Z80 state information.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
#### <font style="color: yellow;" size="5">PCB
|
||||
#### <font style="color: yellow;" size="5">PCB</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The PCB was designed with minimum size as a primary requirement for the various machines in which it would be installed. It also had to be compatible with the tran<i>ZPU</i>ter<sup><i>Fusion</i></sup> for interchangeability.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
A major concern was heat dissipation as the PCB, when installed within an MZ-700 is very close to existing motherboard components which give off a lot of heat with no air circulation in a sealed compact housing. This meant active components couldnt be sited on the PCB underside
|
||||
A major concern was heat dissipation as the PCB, when installed within an MZ-700 is very close to existing motherboard components which give off a lot of heat with no air circulation in a sealed compact housing. This meant active components couldn't be sited on the PCB underside
|
||||
as heat generation would lead to instability and failure, which in turn led to an increase in the final PCB size.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The smallest components which could be manually assembled where used, ie. 0402/0603 passive devices and 0.5mm IC pitch spacing to reduce overall size and a 4 layer stackup selected to fit all required components.
|
||||
The smallest components which could be manually assembled were used, ie. 0402/0603 passive devices and 0.5mm IC pitch spacing to reduce overall size and a 4 layer stackup selected to fit all required components.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
</div>
|
||||
|
||||
<font style="color: cyan;" size="4">PCB Top Overview</font>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">PCB Bottom Overview</font>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">PCB 4 Layer Routing Overview</font>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">PCB Assembled</font>
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
<font style="color: cyan;" size="4">PCB Component Placement and Bill of Materials</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
Click <a href="http://eaw.app/_pages/FusionX_v1_0_BOM.html">here</a> to view an interactive PCB component placement diagram and Bill of Materials.
|
||||
Click <a href="../_pages/FusionX_v1_0_BOM.html">here</a> to view an interactive PCB component placement diagram and Bill of Materials.
|
||||
</div>
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
<a name="cpld" id="cpld"></a>
|
||||
###### <font style="color: yellow;" size="5">CPLD</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> uses an Altera MAX7000AE CPLD — specifically the <b>EPM7512AETC144-10</b> — as the central interface between the SOM and the host Z80 socket. This is a 512-macrocell, 144-pin TQFP device operating at 3.3V LVTTL on its outputs while accepting 5V TTL levels on its inputs, making it directly compatible with vintage Sharp MZ and other Z80-based hardware without any additional level shifting.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The CPLD design is written in VHDL and built with <b>Altera Quartus II 13.0.1 SP1 (Web Edition)</b>. Because each host machine has slightly different bus timing requirements and memory map constraints, a separate VHDL implementation is maintained for each supported host:
|
||||
</div>
|
||||
<div style="padding-top: 0.4em;"></div>
|
||||
|
||||
| VHDL Variant | Host Machine | Directory |
|
||||
|---|---|---|
|
||||
| `tzpuFusionX.vhd` (MZ80A) | Sharp MZ-80A | `CPLD/v1.0/MZ80A/` |
|
||||
| `tzpuFusionX.vhd` (MZ700) | Sharp MZ-700 | `CPLD/v1.0/MZ700/` |
|
||||
| `tzpuFusionX.vhd` (MZ2000) | Sharp MZ-2000 | `CPLD/v1.0/MZ2000/` |
|
||||
| `tzpuFusionX.vhd` (PCW8256) | Amstrad PCW-8256 | `CPLD/v1.0/PCW8256/` |
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="cpld-purpose" id="cpld-purpose"></a>
|
||||
<font style="color: cyan;" size="4">Purpose and Role</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The CPLD performs several functions that would be impractical or impossible to implement directly in software on the SOM:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">Voltage level translation</font><br>— Bridges the 5V TTL Z80 host bus to the 3.3V LVTTL signals used by the SOM. The MAX7000AE is 5V tolerant on inputs and drives outputs at 3.3V, which exceeds the 2.4V switching threshold of 5V TTL receivers, giving up to 25mA drive per pin.</li>
|
||||
<li><font style="color: orange;" size="3">Cycle-accurate Z80 bus timing</font><br>— The CPLD implements a hardware FSM clocked by a 50MHz external oscillator that samples the host Z80 clock and reproduces the precise T-state sequence for every bus cycle type. This offloads all critical timing from the SOM, which only needs to respond with data within the window defined by the CPLD FSM.</li>
|
||||
<li><font style="color: orange;" size="3">SOM interface bridging</font><br>— Converts between the Z80 parallel bus protocol and the SPI + 8-bit GPIO interface used by the SOM kernel module, translating bus events into a format that the SSD202 can service efficiently from a Linux kernel thread.</li>
|
||||
<li><font style="color: orange;" size="3">Video and audio switching</font><br>— Controls multiplexers that select between the host machine's native video/audio output and the SOM video/audio for routing to the monitor and speakers via daughter board connectors. Switching is commanded by the SOM over SPI.</li>
|
||||
<li><font style="color: orange;" size="3">Video sync and clock generation</font><br>— Generates composite sync (<code>VGA_CSYNCn</code>) from the SOM VSync and HSync signals, detects blanking intervals, generates a 25MHz pixel clock for the monochrome DAC (by dividing the 50MHz oscillator), and produces a colour carrier frequency signal (<code>VGA_COLR</code>) for composite colour output.</li>
|
||||
<li><font style="color: orange;" size="3">Reset management</font><br>— Monitors the host Z80 RESET line and implements a dual-press reset protocol: a single reset press asserts a soft reset to the SOM (allowing the Z80 application to reinitialise), while a second press within one second drives the SOM <code>PM_RESET</code> line to force a full SOM power-cycle reboot.</li>
|
||||
<li><font style="color: orange;" size="3">USB power control</font><br>— Controls the USB VBUS power enable signal under SOM command.</li>
|
||||
</font></ul>
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="cpld-fsm" id="cpld-fsm"></a>
|
||||
<font style="color: cyan;" size="4">Z80 Bus FSM</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The heart of the CPLD design is a finite state machine (<code>SOMFSMState</code>) that tracks and reproduces the Z80 bus cycle state at 50MHz resolution. The FSM monitors the host Z80 clock edges and the bus control signals (MREQ, IORQ, RD, WR, M1, RFSH, BUSRQ, HALT, WAIT) to classify each bus cycle and step through the correct T-state sequence:
|
||||
</div>
|
||||
<div style="padding-top: 0.4em;"></div>
|
||||
|
||||
| FSM State | Z80 Bus Cycle | Description |
|
||||
|---|---|---|
|
||||
| `IdleCycle` | — | Bus is idle; waiting for MREQ or IORQ assertion. |
|
||||
| `FetchCycle` | Opcode Fetch (M1) | M1 + MREQ + RD active; address and data phases timed across T1–T3. |
|
||||
| `RefreshCycle` | DRAM Refresh | RFSH + MREQ active; lower 7 bits of address presented for DRAM row refresh. |
|
||||
| `ReadCycle` | Memory Read | MREQ + RD active; address presented T1, data sampled T3. |
|
||||
| `WriteCycle` | Memory Write | MREQ + WR active; address and data presented T1–T2, write strobed T3. |
|
||||
| `ReadIOCycle` | I/O Read | IORQ + RD active; I/O address and data phases with WAIT support. |
|
||||
| `WriteIOCycle` | I/O Write | IORQ + WR active; I/O address and data presented with WAIT support. |
|
||||
| `HaltCycle` | HALT | Z80 HALT assertion detected; repeated NOP fetch cycles suppressed. |
|
||||
| `BusReqCycle` | Bus Request | BUSRQ asserted; BUSACK driven, bus lines tri-stated, SOM notified. |
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
Each state has numbered sub-states (e.g. <code>FetchCycle_11</code>, <code>FetchCycle_20</code>) corresponding to individual half-cycles within the T-state, allowing the CPLD to assert or deassert control signals with sub-clock-cycle precision relative to the host CLK edges.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
A secondary <code>CTRLFSMState</code> FSM handles SPI command processing (<code>CTRLCMD_Idle</code> → <code>CTRLCMD_ReadIOWrite</code>) independently of the main bus cycle FSM, so that SPI transactions from the SOM do not block Z80 bus cycle servicing.
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="cpld-som-interface" id="cpld-som-interface"></a>
|
||||
<font style="color: cyan;" size="4">SOM Interface</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The CPLD presents two distinct interfaces to the SOM:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">SPI slave (write path)</font><br>— A 4-wire SPI slave (<code>VSOM_SPI_CLK</code>, <code>VSOM_SPI_MOSI</code>, <code>VSOM_SPI_MISO</code>, <code>VSOM_SPI_CSn</code>) receives commands and data from the SOM. Up to 4 bytes per frame are shifted in via a serial shift register and decoded into bus control commands (memory write data, I/O write data, video/audio source selection, USB power control). The SPI clock polarity is parameterised (<code>SPI_CLK_POLARITY</code>) to accommodate different SOM SPI configurations.</li>
|
||||
<li><font style="color: orange;" size="3">8-bit parallel bus (read path)</font><br>— An 8-bit output bus (<code>VSOM_DATA_OUT[7:0]</code>) with a <code>VSOM_HBYTE</code> select line presents either the low or high byte of the current Z80 address/data word to the SOM GPIO inputs. Additional single-bit status lines report: <code>VSOM_READY</code> (FSM idle), <code>VSOM_LTSTATE</code> (last T-state of current cycle), <code>VSOM_BUSRQ</code>, <code>VSOM_BUSACK</code>, <code>VSOM_INT</code>, <code>VSOM_NMI</code>, <code>VSOM_WAIT</code>, and <code>VSOM_RESET</code>.</li>
|
||||
</font></ul>
|
||||
|
||||
This split architecture — SPI for writes, GPIO parallel bus for reads — matches the relative performance characteristics of the SSD202: SPI is clocked and reliable for multi-byte writes, while GPIO direct register access gives the lowest possible read latency for sampling bus state within a Z80 T-state window.
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="cpld-build" id="cpld-build"></a>
|
||||
<font style="color: cyan;" size="4">Building the CPLD Image</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The CPLD bitstream is produced using <b>Altera Quartus II 13.0.1 SP1 Web Edition</b>, which is available as a free download from the Intel FPGA (formerly Altera) website. The Web Edition supports all MAX7000AE devices and is sufficient for this project.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<font style="color: cyan;" size="3">Opening the Project</font><br>
|
||||
|
||||
Each host machine variant has its own Quartus project in the corresponding subdirectory. To build the MZ-80A variant, for example:
|
||||
|
||||
<pre style="font-size: 0.70em; line-height: 1.3em; background: #1a1a1a; padding: 1em; border-radius: 4px; overflow-x: auto;"># Open in Quartus II GUI:
|
||||
File -> Open Project -> CPLD/v1.0/MZ80A/build/tzpuFusionX_MZ80A.qpf
|
||||
|
||||
# Or launch from the command line using the Quartus shell:
|
||||
quartus_sh --flow compile tzpuFusionX_MZ80A
|
||||
</pre>
|
||||
|
||||
The project references three VHDL source files (paths relative to the project <code>build/</code> directory):
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><code>../tzpuFusionX_Toplevel.vhd</code> — top-level entity instantiation and I/O pin definitions</li>
|
||||
<li><code>../tzpuFusionX_pkg.vhd</code> — shared package (types, constants)</li>
|
||||
<li><code>../tzpuFusionX.vhd</code> — main RTL architecture (FSMs, SPI, bus interface, video/audio control)</li>
|
||||
</font></ul>
|
||||
|
||||
<font style="color: cyan;" size="3">Compilation</font><br>
|
||||
|
||||
In the Quartus GUI select <b>Processing → Start Compilation</b> (or press Ctrl+L). The tool runs Analysis & Synthesis, Fitter, Assembler and Timing Analysis in sequence. A successful build produces:
|
||||
|
||||
<pre style="font-size: 0.70em; line-height: 1.3em; background: #1a1a1a; padding: 1em; border-radius: 4px; overflow-x: auto;">build/output_files/tzpuFusionX_MZ80A.pof # Programmer Object File (JTAG programming)
|
||||
build/output_files/tzpuFusionX_MZ80A.fit.rpt # Fitter report (resource usage)
|
||||
build/output_files/tzpuFusionX_MZ80A.sta.rpt # Timing analysis report
|
||||
</pre>
|
||||
|
||||
The <code>.pof</code> file is the binary image used to program the physical CPLD device.
|
||||
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
<font style="color: cyan;" size="3">Programming the CPLD</font><br>
|
||||
|
||||
Programming is performed via JTAG using an Altera USB-Blaster or compatible JTAG adapter connected to the 10-pin JTAG header on the <i>FusionX</i> board:
|
||||
<ol style="line-height: 1.6em;"><font size="3">
|
||||
<li>Connect the USB-Blaster to the <i>FusionX</i> JTAG header and the host PC.</li>
|
||||
<li>Power the <i>FusionX</i> board (the CPLD must be powered during programming).</li>
|
||||
<li>In Quartus II, open <b>Tools → Programmer</b>.</li>
|
||||
<li>Load the chain description file: <code>build/output_files/tzpuFusionX_MZ80A.cdf</code>.</li>
|
||||
<li>Verify the USB-Blaster is detected in the hardware list, then click <b>Start</b>.</li>
|
||||
<li>Programming completes in a few seconds; the CPLD becomes active immediately on completion.</li>
|
||||
</font></ol>
|
||||
|
||||
The CPLD retains its programmed logic indefinitely without power (MAX7000AE uses EEPROM-based configuration cells) so the device only needs to be programmed once per build or when updating to a new bitstream.
|
||||
</div>
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
## <font style="color: yellow;" size="6">Software</font>
|
||||
|
||||
<font size="2">Under construction.</font>
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The <i>FusionX</i> software stack spans from the Linux operating system through to dedicated kernel modules and user-space utilities. The complete software set is built using a customised SigmaStar build environment and loaded onto the SOM's SPI NAND flash. On boot, U-boot initialises the SOM and hands off to the Linux kernel, which loads the Buildroot root filesystem. The <i>FusionX</i> startup script then configures the system and brings the Z80 emulator online.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The software components are:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">Linux OS</font><br>— Kernel 4.9-rt (PREEMPT_RT) with Buildroot root filesystem running on the SigmaStar SSD202 dual-core Cortex-A7.</li>
|
||||
<li><font style="color: orange;" size="3">z80drv.ko</font><br>— Linux kernel module implementing the Z80 CPU emulator and host hardware interface. Runs the Z80 emulation loop on a dedicated CPU core.</li>
|
||||
<li><font style="color: orange;" size="3">ttymzdrv.ko</font><br>— Linux TTY kernel module that presents the Sharp MZ keyboard and display as a standard Linux terminal device (<code>/dev/ttymz0</code>).</li>
|
||||
<li><font style="color: orange;" size="3">z80ctrl</font><br>— User-space command-line utility for controlling the z80drv kernel module: load ROM images, add virtual hardware devices, start/stop emulation and inspect emulated memory.</li>
|
||||
<li><font style="color: orange;" size="3">k64fcpu</font><br>— User-space daemon emulating a K64F virtual CPU. Used in TZFS mode to manage ROM loading and inter-processor communication with the Z80 emulator.</li>
|
||||
<li><font style="color: orange;" size="3">sharpbiter</font><br>— Sharp MZ arbiter daemon, coordinating access to the shared Sharp MZ hardware resources between the Z80 emulator and the Linux TTY driver.</li>
|
||||
</font></ul>
|
||||
|
||||
Startup is handled by <code>start_FusionX.sh</code>, which loads <code>ttymzdrv.ko</code>, starts a getty login session on <code>/dev/ttymz0</code>, pins all Linux processes and IRQs to CPU0, loads <code>z80drv.ko</code> onto the isolated CPU1, then launches the <code>k64fcpu</code> and <code>sharpbiter</code> daemons. Two pre-built startup modes are provided:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">RFS mode</font><br>(<code>startZ80_RFS.sh</code>) — loads the ROM Filing System virtual hardware device and starts the MZ-80A emulator with 40- or 80-column ROM images.</li>
|
||||
<li><font style="color: orange;" size="3">TZFS mode</font><br>(<code>startZ80_TZFS.sh</code>) — loads the tranZPUter SW virtual hardware device and starts the <code>k64fcpu</code> K64F daemon which manages Monitor and TZFS ROM image loading.</li>
|
||||
</font></ul>
|
||||
</div>
|
||||
|
||||
|
||||
<a name="architecture" id="architecture"></a>
|
||||
###### <font style="color: yellow;" size="5">Architecture</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The <i>FusionX</i> software architecture is layered, with each layer handling a distinct responsibility. From the host machine's perspective the flow is entirely transparent — the Z80 socket behaves as a normal Z80 CPU while the SOM is silently intercepting and emulating every bus cycle.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<pre style="font-size: 0.70em; line-height: 1.3em; background: #1a1a1a; padding: 1em; border-radius: 4px; overflow-x: auto;">
|
||||
Sharp MZ Host
|
||||
+------------------------------------------+
|
||||
| Z80 DIP-40 Socket |
|
||||
+--------------+---------------------------+
|
||||
| Z80 bus (address, data, control)
|
||||
+--------------v---------------------------+
|
||||
| CPLD (Altera MAX 7000A) |
|
||||
| . 5V <-> 3.3V level translation |
|
||||
| . Cycle-accurate Z80 bus timing |
|
||||
| . 50 MHz internal clock |
|
||||
+--------------+---------------------------+
|
||||
| SPI (50 MHz) + 8-bit GPIO bus
|
||||
+--------------v---------------------------+
|
||||
| SSD202 SOM -- CPU1 (dedicated) |
|
||||
| +--------------------------------------+|
|
||||
| | z80drv.ko kernel module ||
|
||||
| | +----------------------------------+||
|
||||
| | | z80io.c (GPIO/SPI HAL) |||
|
||||
| | +----------------------------------+||
|
||||
| | | Zeta Z80 CPU emulator core |||
|
||||
| | +----------------------------------+||
|
||||
| | | Virtual hardware modules |||
|
||||
| | | (z80vhw_*.c, inline) |||
|
||||
| | +----------------------------------+||
|
||||
| +--------------------------------------+|
|
||||
| |
|
||||
| SSD202 SOM -- CPU0 (Linux) |
|
||||
| +--------------------------------------+|
|
||||
| | Linux 4.9-rt / Buildroot rootfs ||
|
||||
| | ttymzdrv.ko --> /dev/ttymz0 ||
|
||||
| | z80ctrl (control utility) ||
|
||||
| | k64fcpu (K64F daemon) ||
|
||||
| | sharpbiter (MZ arbiter) ||
|
||||
| +--------------------------------------+|
|
||||
+------------------------------------------+
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="dual-core-design" id="dual-core-design"></a>
|
||||
<font style="color: cyan;" size="4">Dual-Core Design</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The SSD202's two Cortex-A7 cores operate under a strict separation of responsibility. At startup every Linux process and every hardware IRQ affinity is migrated to CPU0, leaving CPU1 exclusively available to the Z80 emulation kernel thread. The CPU frequency governor is set to performance mode (1.2GHz fixed) after the emulator starts to prevent frequency-scaling transitions from introducing timing variation in the emulation loop.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<b>CPU0 — Linux and User-Space Services</b><br>
|
||||
Runs the complete Linux 4.9-rt operating system, all user-space daemons and handles all hardware interrupts. Key responsibilities on CPU0 include:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">ttymzdrv.ko</font><br>— Linux TTY kernel module that maps the Sharp MZ keyboard and display to <code>/dev/ttymz0</code>. Supports suspend and resume, enabling the user to switch seamlessly between a Z80 session and a Linux console at the host machine without losing state in either.</li>
|
||||
<li><font style="color: orange;" size="3">z80ctrl utility</font><br>— Command-line tool for runtime control of the Z80 emulator: loading ROM images, registering virtual hardware devices, starting and stopping the emulation loop, and inspecting emulated memory. Communicates with <code>z80drv.ko</code> via a kernel character device.</li>
|
||||
<li><font style="color: orange;" size="3">k64fcpu daemon</font><br>— User-space daemon that emulates a K64F virtual CPU. Active in TZFS mode; it manages Monitor and TZFS ROM image loading into the emulator's memory space and relays inter-processor commands to <code>z80drv.ko</code>.</li>
|
||||
<li><font style="color: orange;" size="3">sharpbiter daemon</font><br>— Sharp MZ arbiter; coordinates access to the shared Sharp MZ keyboard and display hardware between the TTY driver and the Z80 emulator so that both can operate without conflicting on the underlying I/O registers.</li>
|
||||
<li><font style="color: orange;" size="3">WiFi and web server</font><br>— The SOM's integrated 802.11 b/g/n transceiver (SSW101B) provides network connectivity. A lightweight web server on CPU0 can serve configuration and status pages, and the WiFi stack handles OTA firmware delivery via SD card auto-upgrade on boot.</li>
|
||||
</font></ul>
|
||||
|
||||
<b>CPU1 — Z80 Emulator (dedicated)</b><br>
|
||||
Exclusively runs the <code>kthread_z80</code> kernel thread spawned by <code>z80drv.ko</code>. No other process or interrupt is ever scheduled on CPU1 after initialisation. The emulation loop on CPU1:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li>Calls the Zeta Z80 CPU core for each instruction execution step</li>
|
||||
<li>Dispatches each resulting memory or I/O access to the correct handler — physical host hardware, kernel-resident RAM image, or a virtual hardware module function</li>
|
||||
<li>Drives the GPIO and SPI hardware via <code>z80io.c</code> to assert or sample the Z80 bus signals through the CPLD</li>
|
||||
<li>Runs at 1.2GHz with the PREEMPT_RT kernel ensuring minimal interrupt jitter even from CPU0 activity</li>
|
||||
</font></ul>
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="cpld-bus-interface" id="cpld-bus-interface"></a>
|
||||
<font style="color: cyan;" size="4">CPLD Bus Interface</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The hardware path from the SOM to the Z80 host socket passes through an Altera MAX 7000A CPLD. This device serves two essential roles:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">Voltage level translation</font><br>— The CPLD is 5V tolerant on its inputs and drives outputs at 3.3V Low Voltage TTL levels. Since the 5V TTL switching threshold is approximately 2.4V the CPLD can drive 5V host logic directly with up to 25mA per pin, making the board compatible with unmodified vintage Z80 hardware.</li>
|
||||
<li><font style="color: orange;" size="3">Cycle-accurate Z80 bus timing</font><br>— The CPLD embeds state machines clocked by an external 50MHz oscillator. These state machines sample the Z80 host clock and reproduce the precise T-state sequence for each bus cycle (fetch, memory read/write, I/O read/write) as defined in the Z80 state diagrams. This means the SOM kernel module does not need to replicate sub-microsecond Z80 timing in software — the CPLD handles it in hardware.</li>
|
||||
</font></ul>
|
||||
|
||||
The SOM communicates with the CPLD through two parallel channels:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">SPI channel (50MHz)</font><br>— used for writing data and commands to the CPLD. SPI write is used in preference to GPIO for host bus writes because it is clocked and therefore more reliable for multi-byte transfers at speed.</li>
|
||||
<li><font style="color: orange;" size="3">8-bit GPIO bus</font><br>— used by <code>z80io.c</code> for reading bus status and address/data values from the CPLD. Direct register access is used (bypassing the SigmaStar HAL API after initialisation) to minimise read latency. The maximum read throughput achievable via the SSD202 GPIO structure is approximately 2MB/s for an 8-bit byte — fast enough to service Z80 bus cycles at typical host clock rates (1MHz–6MHz) when combined with the CPLD buffering.</li>
|
||||
</font></ul>
|
||||
|
||||
Because the GPIO read throughput sets an upper bound on bus transaction rate, Z80 programs execute from kernel-resident memory images rather than being read from the physical host memory bus on every access. ROM images are loaded into kernel memory at startup, and all memory accesses by the emulated Z80 are serviced from there — the physical host bus is only engaged when a <code>PHYSICAL</code>-type block is encountered (e.g. for host video RAM or hardware registers that must be accessed on the real hardware).
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="memory-architecture" id="memory-architecture"></a>
|
||||
<font style="color: cyan;" size="4">Memory Architecture</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The 128MB DRAM on the SSD202 SOM is shared between the Linux operating system and the Z80 kernel module. The kernel module allocates a contiguous region of physically-addressed kernel memory to hold ROM and RAM images for the emulated Z80. This region is accessed directly by the <code>kthread_z80</code> running on CPU1, with no virtual memory translation overhead in the inner emulation loop.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The emulated Z80 sees a configurable memory map across the standard 64KB (0x0000–0xFFFF) address space. Each region is assigned one of the following access types:
|
||||
</div>
|
||||
<div style="padding-top: 0.4em;"></div>
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `kernel RAM` | Read/write region backed by a kernel-allocated DRAM buffer. Standard RAM for the emulated machine. |
|
||||
| `kernel ROM` | Read-only region in kernel DRAM. Write cycles are silently discarded. Used for Monitor ROMs, BASIC ROMs, User ROMs, TZFS ROM pages. |
|
||||
| `PHYSICAL` | Pass-through to real host hardware — the SOM releases the CPLD bus and the host hardware responds to the cycle directly. Used for host video RAM and I/O registers that must interact with real hardware. |
|
||||
| `VIRTUAL` | Each access triggers a C handler function within the kernel module. Used to emulate peripheral devices (floppy controller, QuickDisk, RFS banking logic) without any real hardware. |
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
ROM images are loaded into kernel memory at startup by <code>z80ctrl --loadrom</code> (or automatically by the active virtual hardware module or the <code>k64fcpu</code> daemon in TZFS mode). Multiple ROM page sets can be resident simultaneously — the RFS virtual hardware module, for example, maintains up to four switchable ROM pages (MROM, User ROM I/II/III) for 40-column and 80-column configurations.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
Machine timing constants for each supported host (MZ-80A, MZ-700, MZ-2000, PCW-8256) are defined in <code>z80driver.h</code> and used by the emulation loop to pace bus cycles at the correct rate relative to the host clock, ensuring that time-sensitive software (tape motor control, serial I/O, delay loops) behaves as it would on original hardware.
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="virtual-hardware-modules" id="virtual-hardware-modules"></a>
|
||||
<font style="color: cyan;" size="4">Virtual Hardware Modules</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
Virtual hardware modules are C source files (<code>z80vhw_*.c</code>) that define the behaviour of a specific host machine or peripheral set. Rather than being compiled as separately-linked objects they are <code>#include</code>d directly into <code>z80driver.c</code>, so their handler functions are inlined into the emulation dispatch path with no function-call overhead.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
Up to five virtual hardware devices can be active simultaneously (<code>MAX_VIRTUAL_DEVICES 5</code>). Devices are registered at runtime before the emulator starts using <code>z80ctrl --adddev --device <name></code>. Each registered device receives memory read, memory write, I/O read and I/O write callbacks for the address ranges it claims, and can optionally install its own ROM images and configure the memory map during initialisation.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The available modules and the host machines they support are:
|
||||
</div>
|
||||
<div style="padding-top: 0.4em;"></div>
|
||||
|
||||
| Module | Host | Role |
|
||||
|--------|------|------|
|
||||
| `z80vhw_mz80a.c` | Sharp MZ-80A | Original MZ-80A memory map, keyboard matrix and display I/O — no extensions. |
|
||||
| `z80vhw_mz700.c` | Sharp MZ-700 | MZ-700 bank-switching, video and keyboard I/O emulation. |
|
||||
| `z80vhw_mz2000.c` | Sharp MZ-2000 | MZ-2000 memory map, extended video modes and I/O. |
|
||||
| `z80vhw_pcw.c` | Amstrad PCW-8256 | PCW-8256 memory/bank paging and peripheral I/O. |
|
||||
| `z80vhw_rfs.c` | MZ-80A + RFS board | ROM Filing System: manages four switchable ROM pages (40-col and 80-col sets), SD-based MZF program loading, bank switching. |
|
||||
| `z80vhw_tzpu.c` | MZ-80A + tranZPUter SW | tranZPUter SW virtual hardware; the kernel-side driver works with the userspace <code>k64fcpu</code> daemon to provide K64F virtual CPU behaviour, TZFS ROM page management and CP/M support. |
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The TZPU module (<code>z80vhw_tzpu.c</code>) is architecturally distinct from the others. Because the K64F co-processor behaviour is complex and stateful, it is split across two components: the <code>z80vhw_tzpu.c</code> kernel-side stub handles fast bus-cycle dispatch while the <code>k64fcpu</code> user-space daemon on CPU0 manages ROM loading, memory bank selection and higher-level K64F command processing. The two halves communicate via a shared memory region in the kernel module.
|
||||
</div>
|
||||
|
||||
|
||||
<a name="build" id="build"></a>
|
||||
###### <font style="color: yellow;" size="5">Build</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The complete <i>FusionX</i> OS and application set is built using the <code>Build_FusionX.sh</code> script, which wraps the SigmaStar SDK build system and produces a ready-to-flash NAND image. Building requires a Linux host with the ARM cross-compiler toolchain installed.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<font style="color: cyan;" size="4">Prerequisites</font>
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li>ARM cross-compiler: <code>arm-linux-gnueabihf-gcc</code> (e.g. from <code>gcc-arm-linux-gnueabihf</code> package)</li>
|
||||
<li>SigmaStar SDK source tree (kernel, U-boot, Buildroot) in the parent directory structure expected by <code>Build_FusionX.sh</code></li>
|
||||
<li>FusionX application source in the <code>../FusionX</code> directory relative to the linux build directory</li>
|
||||
<li>Standard build tools: <code>make</code>, <code>cmake</code>, <code>bc</code>, <code>libssl-dev</code></li>
|
||||
</font></ul>
|
||||
|
||||
<font style="color: cyan;" size="4">Building the Full OS Image</font>
|
||||
|
||||
The build is launched from the <code>software/linux/</code> directory:
|
||||
|
||||
<pre style="font-size: 0.70em; line-height: 1.3em; background: #1a1a1a; padding: 1em; border-radius: 4px; overflow-x: auto;"># Build full image for FusionX (project 2D06, SPI NAND, SSD202, 256MB flash)
|
||||
./Build_FusionX.sh -f nand -p ssd202 -o 2D06 -m 256
|
||||
</pre>
|
||||
|
||||
This builds in sequence: U-boot bootloader, Linux kernel (using the FusionX custom defconfig <code>infinity2m_spinand_fusionx_defconfig</code>), Buildroot root filesystem and the FusionX application set. Output images are written to <code>project/image/output/images/</code>.
|
||||
|
||||
For the standard SigmaStar reference configuration use project <code>2D07</code> instead.
|
||||
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<font style="color: cyan;" size="4">Building Kernel Modules Only</font>
|
||||
|
||||
The kernel modules can be rebuilt independently against an already-built kernel tree, which is useful during development:
|
||||
|
||||
<pre style="font-size: 0.70em; line-height: 1.3em; background: #1a1a1a; padding: 1em; border-radius: 4px; overflow-x: auto;"># Build z80drv kernel module
|
||||
cd software/FusionX/src/z80drv/src.mz80a
|
||||
make
|
||||
|
||||
# Build ttymzdrv kernel module
|
||||
cd software/FusionX/src/ttymz
|
||||
make
|
||||
</pre>
|
||||
|
||||
The resulting <code>z80drv.ko</code> and <code>ttymzdrv.ko</code> files can be copied directly to the <code>/apps/FusionX/modules/</code> directory on the running SOM (via SSH or SD card) and loaded with <code>insmod</code>.
|
||||
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<font style="color: cyan;" size="4">Flashing and Updates</font>
|
||||
|
||||
The flash image produced by the build script is programmed to the SOM SPI NAND via the SigmaStar ISP tool over USB. Once the initial image is installed, subsequent updates can be delivered via SD card — when the SOM boots with a suitably prepared SD card present it will auto-upgrade the NAND image without requiring a USB connection.
|
||||
</div>
|
||||
|
||||
|
||||
###### <font style="color: yellow;" size="5">Linux</font>
|
||||
|
||||
<font size="2">Under construction.</font>
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The Linux platform runs on the SigmaStar SSD202 (Infinity2M) SOM — a 29mm × 29mm stamp module containing a dual-core ARM Cortex-A7 at 1.2GHz, 128MB DRAM, 256MB SPI NAND flash and an integrated 802.11 b/g/n WiFi transceiver. The kernel is Linux 4.9 with the PREEMPT_RT real-time patch applied to minimise scheduling latency, which is essential for responsive Z80 emulation.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The complete OS image — U-boot bootloader, Linux kernel, Buildroot root filesystem and FusionX application set — is assembled using the <code>Build_FusionX.sh</code> script, a customised version of the SigmaStar SDK build system. Two project targets are defined:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">2D06</font><br>— FusionX custom configuration using the <code>infinity2m_spinand_fusionx_defconfig</code> kernel defconfig.</li>
|
||||
<li><font style="color: orange;" size="3">2D07</font><br>— Standard SigmaStar reference configuration using <code>infinity2m_spinand_ssc011a_s01a_minigui_defconfig</code>.</li>
|
||||
</font></ul>
|
||||
|
||||
The build script is invoked as: <code>Build_FusionX.sh -f nand -p ssd202 -o 2D06 -m 256</code> and produces a full flash image ready for programming to the SOM NAND.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
A key aspect of the Linux configuration is CPU isolation. At startup all Linux processes and hardware IRQs are migrated to CPU0. CPU1 is then dedicated exclusively to the <code>kthread_z80</code> kernel thread which runs the Z80 emulation loop. This CPU affinity separation, combined with the PREEMPT_RT kernel, gives the Z80 emulator the most consistent and lowest-latency access to the host hardware interface. The CPU performance governor is also set to maximum frequency (1.2GHz) after the Z80 emulator is running to avoid frequency scaling causing timing variation in the emulation loop.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The root filesystem is a Buildroot-based minimal Linux environment stored in the SOM NAND flash. An optional SD card can extend storage for Sharp MZ application software, ROM images and additional Linux utilities. When a suitably prepared SD card is present at boot the SOM will auto-upgrade from it, simplifying firmware updates.
|
||||
</div>
|
||||
|
||||
|
||||
###### <font style="color: yellow;" size="5">Z80 Emulator</font>
|
||||
|
||||
<font size="2">Under construction.</font>
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The Z80 emulator is implemented as a Linux kernel module, <code>z80drv.ko</code> (v1.4, April 2023). It uses the <a href="https://github.com/redcode/Z80">Zeta Z80 CPU emulator library</a> by Manuel Sainz de Baranda y Goñi as its Z80 instruction-set core, wrapped in a kernel-space driver that interfaces with the SSD202 GPIO hardware and the CPLD Z80 host interface.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The hardware path from the SOM to the Z80 host socket runs: SSD202 GPIO / SPI → CPLD → Z80 DIP-40 socket. The CPLD handles accurate Z80 bus timing using a 50MHz clock, so the kernel module does not need to reproduce precise T-state timing itself. The GPIO interface is managed by <code>z80io.c</code>, which calls the SigmaStar HAL for initialisation but accesses registers directly for bit-level read/write operations to minimise latency. The practical read throughput of the SSD202 GPIO structure is approximately 2MB/s for an 8-bit byte, which means programs execute from emulated (kernel) memory rather than from the physical host memory over the bus.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The emulator supports the following host machines, each with its own virtual hardware module:
|
||||
<table style="font-size: 0.85em; width: 100%; border-collapse: collapse; margin-top: 0.5em;">
|
||||
<thead>
|
||||
<tr style="background: #2a2a2a;">
|
||||
<th style="padding: 0.4em 0.8em; text-align: left; border: 1px solid #444;">Virtual Hardware Module</th>
|
||||
<th style="padding: 0.4em 0.8em; text-align: left; border: 1px solid #444;">Host Machine</th>
|
||||
<th style="padding: 0.4em 0.8em; text-align: left; border: 1px solid #444;">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td style="padding: 0.4em 0.8em; border: 1px solid #444;"><code>z80vhw_mz80a.c</code></td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">Sharp MZ-80A</td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">Original MZ-80A behaviour, no additions</td></tr>
|
||||
<tr><td style="padding: 0.4em 0.8em; border: 1px solid #444;"><code>z80vhw_mz700.c</code></td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">Sharp MZ-700</td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">Original MZ-700 behaviour, no additions</td></tr>
|
||||
<tr><td style="padding: 0.4em 0.8em; border: 1px solid #444;"><code>z80vhw_mz2000.c</code></td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">Sharp MZ-2000</td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">MZ-2000 emulation</td></tr>
|
||||
<tr><td style="padding: 0.4em 0.8em; border: 1px solid #444;"><code>z80vhw_pcw.c</code></td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">Amstrad PCW-8256</td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">PCW-8256 emulation</td></tr>
|
||||
<tr><td style="padding: 0.4em 0.8em; border: 1px solid #444;"><code>z80vhw_rfs.c</code></td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">MZ-80A + RFS</td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">ROM Filing System virtual hardware for MZ-80A</td></tr>
|
||||
<tr><td style="padding: 0.4em 0.8em; border: 1px solid #444;"><code>z80vhw_tzpu.c</code></td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">MZ-80A + tranZPUter SW</td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">tranZPUter SW virtual hardware; combines kernel driver with userspace <code>k64fcpu</code> daemon</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The virtual hardware modules are compiled inline into <code>z80drv.ko</code> rather than linked as separate objects, which eliminates function call overhead in the emulation hot path. Up to five virtual hardware devices can be active simultaneously (<code>MAX_VIRTUAL_DEVICES 5</code>). Devices are added at runtime using <code>z80ctrl --adddev --device <name></code> before starting the emulator.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The <code>z80ctrl</code> utility provides full runtime control of the emulator from the Linux command line:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><code>--adddev --device <name></code> — add a virtual hardware device (rfs, tzpu, mz700, mz80a, mz2000, pcw)</li>
|
||||
<li><code>--start</code> / <code>--stop</code> — start or stop the Z80 emulation loop</li>
|
||||
<li><code>--loadrom --file <path> --addr <hex> --type <n></code> — load a ROM binary into emulated memory</li>
|
||||
<li><code>--mem --addr <hex> --len <n></code> — inspect emulated memory contents</li>
|
||||
<li><code>--cmd <hex></code> — send a command byte directly to the CPLD/Z80 gateway</li>
|
||||
</font></ul>
|
||||
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The <code>ttymzdrv.ko</code> module (<code>ttymz.c</code>, v1.2, July 2023) provides a standard Linux TTY interface on <code>/dev/ttymz0</code> backed by the Sharp MZ keyboard and display hardware. This allows the host machine's console to be used as a Linux terminal — running a getty login session — while also supporting suspend and resume to switch the display between Linux and the Z80 emulation session without losing state. Supported hosts are MZ-80A, MZ-700 and MZ-2000.
|
||||
</div>
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
## <font style="color: yellow;" size="6">Daughter Boards</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The tranZPUter series was initially developed in the Sharp MZ-80A and was primarily a Z80 replacement. As the concept evolved and the tranZPUter SW-700 was developed for the MZ-700 it became more of an integral component of the machine, offering original and upgraded Video and Audio capabilites by intercepting and routing existing signals.
|
||||
The tranZPUter series was initially developed in the Sharp MZ-80A and was primarily a Z80 replacement. As the concept evolved and the tranZPUter SW-700 was developed for the MZ-700 it became more of an integral component of the machine, offering original and upgraded Video and Audio capabilities by intercepting and routing existing signals.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
After significant developments on the tranZPUter SW-700 it became desirable to port it back to the MZ-80A and MZ-2000 but these machines had different CPU orientation and signal requirements, ie. driving an internal and external monitor. This requirement led to the concept of daughter boards, where a specific board would be designed and developed for
|
||||
@@ -207,7 +633,7 @@ the target host and would plug into the tranZPUter SW-700 card. Ideally I wanted
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
During the design of the tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> one of the main requirements was to make the board small, the Z80 orientation changeable and also compatible with the tran<i>ZPU</i>ter<sup><i>Fusion</i></sup> so that it could fit many machines and be interchangeable. As the SW-700 also interfaced to the Video and Audio of the machines
|
||||
and each was quite different, it became apparent that the tran<i>ZPU</i>ter<sup>FusionX</sup> needed to include a concept to allow different video/audio interfaces according to the targetted host. This concept was realised via daughter boards. Two connectors would link the tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> to a daughter board which would be
|
||||
and each was quite different, it became apparent that the tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> needed to include a concept to allow different video/audio interfaces according to the targeted host. This concept was realised via daughter boards. Two connectors would link the tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> to a daughter board which would be
|
||||
specifically designed for the intended host.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
@@ -226,7 +652,7 @@ The purpose of the MZ-700 daughter board is to interface the video/audio circuit
|
||||
is switched between the MZ-700 and <i>FusionX</i> under control of the <i>FusionX</i>.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The original sound circuity of the MZ-700 drives a speaker directly and in order to inject <i>FusionX</i> audio into the MZ-700 speaker, the mainboard speaker output is routed to the daughter board, level converted and switched under control of the <i>FusionX</I>. The <i>FusionX</i> offers stereo sound so this is selectively switched/mixed with the
|
||||
The original sound circuitry of the MZ-700 drives a speaker directly and in order to inject <i>FusionX</i> audio into the MZ-700 speaker, the mainboard speaker output is routed to the daughter board, level converted and switched under control of the <i>FusionX</I>. The <i>FusionX</i> offers stereo sound so this is selectively switched/mixed with the
|
||||
original MZ-700 sound and fed to a Class D amplifier which then drives the internal speaker. Line level stereo output is achieved via an additional 4pin connector and used as required.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
@@ -241,7 +667,7 @@ This setup allows for Linux or emulated machines, whilst running as an applicati
|
||||
The MZ-700 daughter board consists of three 4way SPDT analogue switches to route video and audio signals under <i>FusionX</i> control and a Class D power amplifier.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">MZ-700 Video Interface PCB</font>
|
||||
|
||||
@@ -251,16 +677,16 @@ The MZ-700 daughter board PCB is small and compact due to the space restrictions
|
||||
|
||||
<div style='content: ""; clear: both; display: table;'>
|
||||
<div style='width: 35%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/VideoInterface_MZ700_v1_0_3D_Top.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/VideoInterface_MZ700_v1_0_3D_Top.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
<div style='width: 39%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/VideoInterface_MZ700_v1_0_3D_Bottom.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/VideoInterface_MZ700_v1_0_3D_Bottom.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style='content: ""; clear: both; display: table;'>
|
||||
<div style='width: 80%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/FusionX_MZ700.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/FusionX_MZ700.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -284,7 +710,7 @@ The video signals from the mainboard are switched with the <i>FusionX</i> video
|
||||
The <i>FusionX</i> RGB output is routed to the MZ-2000 external RGB video socket allowing for upto full HD external colour video display.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The sound circuity of the MZ-2000 is sent to an audio amplifier on the CRT monitor. This signal is intercepted and switched with the <i>FusionX</i> audio which then drives the CRT monitor amplifier. Line level stereo output is achieved via an additional 4pin connector and used as required.
|
||||
The sound circuitry of the MZ-2000 is sent to an audio amplifier on the CRT monitor. This signal is intercepted and switched with the <i>FusionX</i> audio which then drives the CRT monitor amplifier. Line level stereo output is achieved via an additional 4pin connector and used as required.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
</div>
|
||||
@@ -295,26 +721,26 @@ The sound circuity of the MZ-2000 is sent to an audio amplifier on the CRT monit
|
||||
The MZ-2000 daughter board consists of two 4way SPDT analogue switches to route video and audio signals under <i>FusionX</i> control. One SPDT switch is used for creating pure black in the modified video signal generated on the <i>FusionX</i> board.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">MZ-2000 Video Interface PCB</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The MZ-2000 daughter board PCB is small and compact due to the space restrictions and the number of connectors it must carry. It plugs into the mainboard monitor/IPL male connectors and then presents new CRT monitor, external Video and IPL/RESET switch connectors for all the exising internal cabling.
|
||||
The MZ-2000 daughter board PCB is small and compact due to the space restrictions and the number of connectors it must carry. It plugs into the mainboard monitor/IPL male connectors and then presents new CRT monitor, external Video and IPL/RESET switch connectors for all the existing internal cabling.
|
||||
</div>
|
||||
|
||||
<div style='content: ""; clear: both; display: table;'>
|
||||
<div style='width: 50%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/VideoInterface_MZ2000_v1_0_3D_Top.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/VideoInterface_MZ2000_v1_0_3D_Top.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
<div style='width: 50%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/VideoInterface_MZ2000_v1_0_3D_Bottom.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/VideoInterface_MZ2000_v1_0_3D_Bottom.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style='content: ""; clear: both; display: table;'>
|
||||
<div style='width: 60%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/FusionX_MZ2000.png' height='80%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/FusionX_MZ2000.png' height='80%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -323,7 +749,7 @@ The MZ-2000 daughter board PCB is small and compact due to the space restriction
|
||||
###### <font style="color: yellow;" size="5">MZ-80A Daughter Board</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The purpose of the MZ-80A daughter board is to interface the video/audio/reset circuits of the <i>FusionX</I> board with those of the MZ-80A. The MZ-80A has an internal monochrome CRT, cutouts for and external RGB video socket and internal Audio with an amplifier on the monochrome CRT control board.
|
||||
The purpose of the MZ-80A daughter board is to interface the video/audio/reset circuits of the <i>FusionX</I> board with those of the MZ-80A. The MZ-80A has an internal monochrome CRT, cutouts for an external RGB video socket and internal Audio with an amplifier on the monochrome CRT control board.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The daughter board is designed to plug into the vertical mainboard CRT video connector with a gap so that the data cassette connector can be simultaneously connected. The gap is necessary as the CRT video connector sits close to the rear sidewall so the daughter board must extend forwards towards the keyboard.
|
||||
@@ -332,7 +758,7 @@ The daughter board is designed to plug into the vertical mainboard CRT video con
|
||||
It presents all the required connectors to connect the RESET switch (both in and out), internal monitor and external monitor on the same board.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The RESET input is intercepted on the daughter board and sent to the <i>FusionX</i>. Technically it isnt needed as the <i>FusionX</i> samples the Z80 Reset which is based on this input, but it can be useful, for example, detecting requests to reboot the SOM (double press) rather than the MZ-80A circuitry.
|
||||
The RESET input is intercepted on the daughter board and sent to the <i>FusionX</i>. Technically it isn't needed as the <i>FusionX</i> samples the Z80 Reset which is based on this input, but it can be useful, for example, detecting requests to reboot the SOM (double press) rather than the MZ-80A circuitry.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The video signals from the mainboard are switched with the <i>FusionX</i> video monochrome signals and sent to the internal CRT monitor. This allows for original video output on the CRT monitor or advanced <i>FusionX</i> text and graphics, resolution subject to the timing constraints of the monitor.
|
||||
@@ -341,7 +767,7 @@ The video signals from the mainboard are switched with the <i>FusionX</i> video
|
||||
The <i>FusionX</i> RGB output is routed to the MZ-80A external RGB video socket (if installed) allowing for upto full HD external colour video display.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The sound circuity of the MZ-80A is sent to an audio amplifier on the CRT monitor. This signal is intercepted and switched with the <i>FusionX</i> audio which then drives the CRT monitor amplifier. Line level stereo output is achieved via an additional 4pin connector and used as required.
|
||||
The sound circuitry of the MZ-80A is sent to an audio amplifier on the CRT monitor. This signal is intercepted and switched with the <i>FusionX</i> audio which then drives the CRT monitor amplifier. Line level stereo output is achieved via an additional 4pin connector and used as required.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
</div>
|
||||
@@ -352,20 +778,20 @@ The sound circuity of the MZ-80A is sent to an audio amplifier on the CRT monito
|
||||
The MZ-80A daughter board consists of two 4way SPDT analogue switches to route video and audio signals under <i>FusionX</i> control. One SPDT switch is used for creating pure black in the modified video signal generated on the <i>FusionX</i> board.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">MZ-80A Video Interface PCB</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The MZ-80A daughter board PCB is small and compact with a large punchout to enable connection with the mainboard CRT connector and thru connection of the data cassette signal connector. It plugs into the mainboard CRT monitor connector and then presents new CRT monitor, external Video and RESET In/Out switch connectors to be used with all the exising internal cabling.
|
||||
The MZ-80A daughter board PCB is small and compact with a large punchout to enable connection with the mainboard CRT connector and thru connection of the data cassette signal connector. It plugs into the mainboard CRT monitor connector and then presents new CRT monitor, external Video and RESET In/Out switch connectors to be used with all the existing internal cabling.
|
||||
</div>
|
||||
|
||||
<div style='content: ""; clear: both; display: table;'>
|
||||
<div style='width: 47%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/VideoInterface_MZ80A_V1_0_3D_Top.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/VideoInterface_MZ80A_V1_0_3D_Top.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
<div style='width: 50%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/VideoInterface_MZ80A_V1_0_3D_Bottom.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/VideoInterface_MZ80A_V1_0_3D_Bottom.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
@@ -384,6 +810,17 @@ The table below contains all the sites referenced in the design and programming
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
<div style="padding-left: 10%;">
|
||||
<font size="4">
|
||||
<style>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
tr td {
|
||||
padding-top: 0em;
|
||||
}
|
||||
tr:nth-child(4) td {
|
||||
padding-top: 0;
|
||||
}
|
||||
</style>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -438,6 +875,17 @@ The table below contains all the datasheets and manuals referenced in the design
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
<div style="padding-left: 10%;">
|
||||
<font size="4">
|
||||
<style>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
tr td {
|
||||
padding-top: 0em;
|
||||
}
|
||||
tr:nth-child(4) td {
|
||||
padding-top: 0;
|
||||
}
|
||||
</style>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -548,19 +996,43 @@ The table below contains all the datasheets and manuals referenced in the design
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
## <font style="color: yellow;" size="5">Demonstration Videos</font>
|
||||
<a name="project-preview" id="project-preview"></a>
|
||||
## <font style="color: yellow;" size="6">Project Preview</font>
|
||||
|
||||
<a href="https://t.co/ZP4T3oisrg">MZ-2000 Demo</a>
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
Development progress on the tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> was shared on X (formerly Twitter) as each milestone was reached. The posts below document key stages from the first hardware bring-up through to running RFS, MZ-700 and MZ-2000 emulation:
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<a href="https://t.co/6lJoGkNuiP">MZ-700 Demo</a>
|
||||
<a href="https://x.com/engineerswork1/status/1579209688495054849" target="_blank">https://x.com/engineerswork1/status/1579209688495054849</a><br>
|
||||
<a href="https://x.com/engineerswork1/status/1583918702415577089" target="_blank">https://x.com/engineerswork1/status/1583918702415577089</a><br>
|
||||
<a href="https://x.com/engineerswork1/status/1596925535787286528" target="_blank">https://x.com/engineerswork1/status/1596925535787286528</a><br>
|
||||
<a href="https://x.com/engineerswork1/status/1616571495957909510" target="_blank">https://x.com/engineerswork1/status/1616571495957909510</a><br>
|
||||
<a href="https://x.com/engineerswork1/status/1630985022604804109" target="_blank">https://x.com/engineerswork1/status/1630985022604804109</a>
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="demonstration-videos" id="demonstration-videos"></a>
|
||||
<font style="color: yellow;" size="5">Demonstration Videos</font>
|
||||
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
<font style="color: cyan;" size="4">MZ-80A Demo (includes virtual RFS Board)</font>
|
||||
|
||||
<blockquote class="twitter-tweet" data-dnt="true" data-theme="dark"><p lang="en" dir="ltr"> <a href="https://t.co/3gbEHVzS6X">pic.twitter.com/3gbEHVzS6X</a></p>— engineers@work (@engineerswork1) <a href="https://twitter.com/engineerswork1/status/1625281950897303553?ref_src=twsrc%5Etfw">February 13, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
||||
|
||||
<font style="color: cyan;" size="4">MZ-2000 Demo</font>
|
||||
|
||||
<blockquote class="twitter-tweet" data-dnt="true" data-theme="dark"><p lang="zxx" dir="ltr"><a href="https://t.co/ZP4T3oisrg">pic.twitter.com/ZP4T3oisrg</a></p>— engineers@work (@engineerswork1) <a href="https://twitter.com/engineerswork1/status/1596925985592864768?ref_src=twsrc%5Etfw">November 27, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
||||
|
||||
<font style="color: cyan;" size="4">MZ-700 Demo</font>
|
||||
|
||||
<blockquote class="twitter-tweet" data-dnt="true" data-theme="dark"><p lang="en" dir="ltr"> <a href="https://t.co/6lJoGkNuiP">pic.twitter.com/6lJoGkNuiP</a></p>— engineers@work (@engineerswork1) <a href="https://twitter.com/engineerswork1/status/1586864092601630721?ref_src=twsrc%5Etfw">October 30, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
## <font style="color: yellow;" size="5">Credits</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The Z80 Emulation used in the <i>FusionX</i> is (c) 1999-2022 Manuel Sainz de Baranda y Goñi, which is licensed under the LGPL v3 license, source can be found in <a href="https://github.com/redcode/Z80">github</a>.
|
||||
The Z80 Emulation used in the <i>FusionX</i> is (c) 1999-2022 Manuel Sainz de Baranda y Goñi, which is licensed under the LGPL v3 license, source can be found in <a href="https://github.com/redcode/Z80">Gitea</a>.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The SSD202/SOM2D0X build system is based on Linux with extensions by SigmaStar and Industio, licensing can be found in their updated source files.
|
||||
@@ -571,7 +1043,7 @@ The SSD202/SOM2D0X build system is based on Linux with extensions by SigmaStar a
|
||||
## <font style="color: yellow;" size="5">Licenses</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
This design, hardware and software (attributable components excluding seperately licensed software) is licensed under the GNU Public Licence v3 and free to use, adapt and modify by individuals, groups and educational institutes.
|
||||
This design, hardware and software (attributable components excluding separately licensed software) is licensed under the GNU Public Licence v3 and free to use, adapt and modify by individuals, groups and educational institutes.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
No commercial use to be made of this design or any hardware/firmware component without express permission from the author.
|
||||
|
||||
438
build.sh
Executable file
438
build.sh
Executable file
@@ -0,0 +1,438 @@
|
||||
#!/bin/bash
|
||||
#########################################################################################################
|
||||
##
|
||||
## Name: build.sh
|
||||
## Created: March 2026
|
||||
## Author(s): Philip Smart
|
||||
## Description: FusionX global build script
|
||||
## Builds all software components for the FusionX tranZPUter board:
|
||||
## - Z80 assembly ROMs (monitor, MS BASIC, CP/M, TZFS)
|
||||
## - Linux kernel modules (z80drv, ttymzdrv) for each target machine
|
||||
## - User-space applications (sharpbiter, k64fcpu, z80ctrl)
|
||||
## - SPI tools (mspi_main)
|
||||
## - CPLD bitstreams for each target machine (requires Quartus Docker)
|
||||
##
|
||||
## Credits:
|
||||
## Copyright: (c) 2019-2026 Philip Smart <philip.smart@net2net.org>
|
||||
##
|
||||
## History: March 2026 - Initial global build script.
|
||||
##
|
||||
#########################################################################################################
|
||||
## 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/>.
|
||||
#########################################################################################################
|
||||
|
||||
# Root directory of the FusionX project.
|
||||
ROOT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
# Directories.
|
||||
SOFTDIR="${ROOT_DIR}/software"
|
||||
ASMDIR="${SOFTDIR}/asm"
|
||||
INCDIR="${ASMDIR}/include"
|
||||
TMPDIR="${SOFTDIR}/tmp"
|
||||
ROMDIR="${SOFTDIR}/roms"
|
||||
TOOLDIR="${SOFTDIR}/tools"
|
||||
CPLDDIR="${ROOT_DIR}/CPLD/v1.0"
|
||||
DRVDIR="${SOFTDIR}/FusionX/src/z80drv"
|
||||
TTYDIR="${SOFTDIR}/FusionX/src/ttymz"
|
||||
SPIDIR="${SOFTDIR}/FusionX/src/spitools"
|
||||
BINDIR="${SOFTDIR}/FusionX/bin"
|
||||
MODDIR="${SOFTDIR}/FusionX/modules"
|
||||
|
||||
# Tools.
|
||||
ASM_JAR="${TOOLDIR}/glass-0.5.1.jar"
|
||||
CROSS_PREFIX="arm-linux-gnueabihf-"
|
||||
|
||||
# Build targets.
|
||||
SOFTWARE_TARGETS="MZ80A MZ700 MZ2000"
|
||||
CPLD_TARGETS="MZ80A MZ700 MZ2000 PCW8256"
|
||||
|
||||
# Assembly build lists.
|
||||
BUILDROMLIST="mz2000_ipl_original mz2000_ipl_tzpu mz2000_ipl_fusionx mz800_1z_013b mz800_9z_504m mz800_iocs mz80afi monitor_sa1510 monitor_80c_sa1510 monitor_1z-013a monitor_80c_1z-013a monitor_1z-013a-km monitor_80c_1z-013a-km mz80b_ipl"
|
||||
BUILDMZFLIST="5z009-1b sa-5510_tzfs msbasic_mz80a msbasic_mz700 msbasic_tz40 msbasic_tz80 sharpmz-test"
|
||||
BUILDTZFSROMLIST="tzfs"
|
||||
BUILDTZFSMZFLIST="testtz"
|
||||
CPMVERSIONS="mz700_80c:0 mz80a_80c:1 mz80a_std:2"
|
||||
|
||||
# Counters for summary.
|
||||
PASS=0
|
||||
FAIL=0
|
||||
SKIP=0
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Helper functions.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
log_info() { echo "==> $*"; }
|
||||
log_ok() { echo " [OK] $*"; PASS=$((PASS + 1)); }
|
||||
log_fail() { echo " [FAIL] $*"; FAIL=$((FAIL + 1)); }
|
||||
log_skip() { echo " [SKIP] $*"; SKIP=$((SKIP + 1)); }
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Build all or selected FusionX components."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --all Build everything (default)"
|
||||
echo " --asm Build Z80 assembly ROMs only"
|
||||
echo " --tzfs Build TZFS ROM only"
|
||||
echo " --cpm Build CP/M only"
|
||||
echo " --drivers Build kernel modules and user-space apps only"
|
||||
echo " --spi Build SPI tools only"
|
||||
echo " --cpld Build CPLD bitstreams only (requires Quartus Docker)"
|
||||
echo " --clean Clean all build artifacts"
|
||||
echo " --help Show this help"
|
||||
echo ""
|
||||
echo "Software targets: ${SOFTWARE_TARGETS}"
|
||||
echo "CPLD targets: ${CPLD_TARGETS}"
|
||||
exit 0
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build Z80 Assembly ROMs and MZF files.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_asm_roms() {
|
||||
log_info "Building Z80 Assembly ROMs and MZF files..."
|
||||
|
||||
if ! command -v java &>/dev/null; then
|
||||
log_skip "Java not found - cannot assemble Z80 ROMs"
|
||||
return
|
||||
fi
|
||||
if [ ! -f "${ASM_JAR}" ]; then
|
||||
log_skip "GLASS assembler not found at ${ASM_JAR}"
|
||||
return
|
||||
fi
|
||||
|
||||
mkdir -p "${TMPDIR}" "${ROMDIR}"
|
||||
|
||||
for f in ${BUILDROMLIST} ${BUILDMZFLIST}; do
|
||||
SRCNAME="${f}"
|
||||
ASMNAME="${f}.asm"
|
||||
OBJNAME="${f}.obj"
|
||||
SYMNAME="${f}.sym"
|
||||
ROMNAME="${f}.rom"
|
||||
MZFNAME="${f}.mzf"
|
||||
|
||||
# MS BASIC variant handling.
|
||||
case "${SRCNAME}" in
|
||||
msbasic_mz80a)
|
||||
ASMNAME="msbasic.asm"
|
||||
echo "BUILD_VERSION EQU 0" > "${INCDIR}/MSBASIC_BuildVersion.asm"
|
||||
;;
|
||||
msbasic_mz700)
|
||||
ASMNAME="msbasic.asm"
|
||||
echo "BUILD_VERSION EQU 1" > "${INCDIR}/MSBASIC_BuildVersion.asm"
|
||||
;;
|
||||
msbasic_tz40)
|
||||
ASMNAME="msbasic.asm"
|
||||
echo "BUILD_VERSION EQU 2" > "${INCDIR}/MSBASIC_BuildVersion.asm"
|
||||
;;
|
||||
msbasic_tz80)
|
||||
ASMNAME="msbasic.asm"
|
||||
echo "BUILD_VERSION EQU 3" > "${INCDIR}/MSBASIC_BuildVersion.asm"
|
||||
;;
|
||||
esac
|
||||
|
||||
if java -jar "${ASM_JAR}" "${ASMDIR}/${ASMNAME}" "${TMPDIR}/${OBJNAME}" "${TMPDIR}/${SYMNAME}" -I "${INCDIR}" -I "${ASMDIR}" 2>&1; then
|
||||
if echo "${BUILDROMLIST}" | grep -qw "${SRCNAME}"; then
|
||||
cp "${TMPDIR}/${OBJNAME}" "${ROMDIR}/${ROMNAME}"
|
||||
log_ok "ROM: ${ROMNAME}"
|
||||
else
|
||||
cp "${TMPDIR}/${OBJNAME}" "${ROMDIR}/${MZFNAME}"
|
||||
log_ok "MZF: ${MZFNAME}"
|
||||
fi
|
||||
else
|
||||
log_fail "${SRCNAME}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Composite MZ-800 ROM.
|
||||
if [ -f "${ROMDIR}/mz800_1z_013b.rom" ] && [ -f "${ROMDIR}/mz800_cgrom.ori" ] && \
|
||||
[ -f "${ROMDIR}/mz800_9z_504m.rom" ] && [ -f "${ROMDIR}/mz800_iocs.rom" ]; then
|
||||
cat "${ROMDIR}/mz800_1z_013b.rom" "${ROMDIR}/mz800_cgrom.ori" \
|
||||
"${ROMDIR}/mz800_9z_504m.rom" "${ROMDIR}/mz800_iocs.rom" > "${ROMDIR}/mz800_ipl.rom"
|
||||
log_ok "ROM: mz800_ipl.rom (composite)"
|
||||
fi
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build TZFS ROM for each machine+board combination.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_tzfs() {
|
||||
log_info "Building TZFS ROMs..."
|
||||
|
||||
if ! command -v java &>/dev/null; then
|
||||
log_skip "Java not found - cannot assemble TZFS"
|
||||
return
|
||||
fi
|
||||
|
||||
mkdir -p "${TMPDIR}" "${ROMDIR}"
|
||||
|
||||
local DEFSFILE="${INCDIR}/tzfs_definitions.asm"
|
||||
local MACHINES="MZ80A MZ700 MZ2000"
|
||||
|
||||
for machine in ${MACHINES}; do
|
||||
# Set machine target in definitions.
|
||||
for m in MZ80A MZ700 MZ1500 MZ2000; do
|
||||
local val=0
|
||||
[ "${m}" = "${machine}" ] && val=1
|
||||
sed -i "s/^BUILD_${m}\s\+EQU\s\+[01]/BUILD_${m} EQU ${val}/" "${DEFSFILE}"
|
||||
done
|
||||
|
||||
# Set board to FusionX.
|
||||
sed -i "s/^BUILD_FUSIONX\s\+EQU\s\+[01]/BUILD_FUSIONX EQU 1/" "${DEFSFILE}"
|
||||
sed -i "s/^BUILD_PICOZ80\s\+EQU\s\+[01]/BUILD_PICOZ80 EQU 0/" "${DEFSFILE}"
|
||||
|
||||
for f in ${BUILDTZFSROMLIST} ${BUILDTZFSMZFLIST}; do
|
||||
if java -jar "${ASM_JAR}" "${ASMDIR}/${f}.asm" "${TMPDIR}/${f}.obj" "${TMPDIR}/${f}.sym" -I "${INCDIR}" -I "${ASMDIR}" 2>&1; then
|
||||
local lower_machine=$(echo "${machine}" | tr '[:upper:]' '[:lower:]')
|
||||
if echo "${BUILDTZFSROMLIST}" | grep -qw "${f}"; then
|
||||
cp "${TMPDIR}/${f}.obj" "${ROMDIR}/${f}_${lower_machine}_fusionx.rom"
|
||||
log_ok "TZFS ROM: ${f}_${lower_machine}_fusionx.rom"
|
||||
else
|
||||
cp "${TMPDIR}/${f}.obj" "${ROMDIR}/${f}_${lower_machine}_fusionx.mzf"
|
||||
log_ok "TZFS MZF: ${f}_${lower_machine}_fusionx.mzf"
|
||||
fi
|
||||
else
|
||||
log_fail "TZFS: ${f} (${machine})"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build CP/M for each version.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_cpm() {
|
||||
log_info "Building CP/M variants..."
|
||||
|
||||
if ! command -v java &>/dev/null; then
|
||||
log_skip "Java not found - cannot assemble CP/M"
|
||||
return
|
||||
fi
|
||||
|
||||
mkdir -p "${TMPDIR}" "${ROMDIR}"
|
||||
|
||||
for ver in ${CPMVERSIONS}; do
|
||||
local FILEEXT=$(echo "${ver}" | cut -d: -f1)
|
||||
local BUILDVER=$(echo "${ver}" | cut -d: -f2)
|
||||
echo "BUILD_VERSION EQU ${BUILDVER}" > "${INCDIR}/cpm_buildversion.asm"
|
||||
|
||||
local all_ok=true
|
||||
for f in cbios cpm22; do
|
||||
if java -jar "${ASM_JAR}" "${ASMDIR}/${f}.asm" "${TMPDIR}/${f}.obj" "${TMPDIR}/${f}.sym" -I "${INCDIR}" -I "${ASMDIR}" 2>&1; then
|
||||
cp "${TMPDIR}/${f}.obj" "${ROMDIR}/${f}.bin"
|
||||
else
|
||||
log_fail "CP/M: ${f} (${FILEEXT})"
|
||||
all_ok=false
|
||||
fi
|
||||
done
|
||||
|
||||
if ${all_ok}; then
|
||||
cat "${ROMDIR}/cpm22.bin" "${ROMDIR}/cbios.bin" > "${ROMDIR}/cpm223_${FILEEXT}.bin"
|
||||
log_ok "CP/M: cpm223_${FILEEXT}.bin"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build kernel modules and user-space applications for each target machine.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_drivers() {
|
||||
log_info "Building kernel modules and user-space applications..."
|
||||
|
||||
if ! command -v ${CROSS_PREFIX}gcc &>/dev/null; then
|
||||
log_skip "ARM cross-compiler (${CROSS_PREFIX}gcc) not found"
|
||||
return
|
||||
fi
|
||||
|
||||
local KERNEL_DIR="${SOFTDIR}/linux/kernel"
|
||||
if [ ! -f "${KERNEL_DIR}/Makefile" ]; then
|
||||
log_skip "Kernel source tree not found at ${KERNEL_DIR}"
|
||||
return
|
||||
fi
|
||||
|
||||
for target in ${SOFTWARE_TARGETS}; do
|
||||
log_info " Target: ${target}"
|
||||
|
||||
# Build z80drv kernel module + user-space tools.
|
||||
# Must cd into directory because Makefile uses $(PWD) for kernel path.
|
||||
if [ -f "${DRVDIR}/Makefile" ]; then
|
||||
if (cd "${DRVDIR}" && make "${target}" 2>&1); then
|
||||
(cd "${DRVDIR}" && make install 2>&1) || true
|
||||
log_ok "z80drv + apps (${target})"
|
||||
else
|
||||
log_fail "z80drv (${target})"
|
||||
fi
|
||||
(cd "${DRVDIR}" && make clean 2>&1) || true
|
||||
fi
|
||||
|
||||
# Build ttymzdrv kernel module.
|
||||
if [ -f "${TTYDIR}/Makefile" ]; then
|
||||
if (cd "${TTYDIR}" && make "${target}" 2>&1); then
|
||||
(cd "${TTYDIR}" && make install 2>&1) || true
|
||||
log_ok "ttymzdrv (${target})"
|
||||
else
|
||||
log_fail "ttymzdrv (${target})"
|
||||
fi
|
||||
(cd "${TTYDIR}" && make clean 2>&1) || true
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build SPI tools.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_spi() {
|
||||
log_info "Building SPI tools..."
|
||||
|
||||
if ! command -v ${CROSS_PREFIX}gcc &>/dev/null; then
|
||||
log_skip "ARM cross-compiler (${CROSS_PREFIX}gcc) not found"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -f "${SPIDIR}/Makefile" ]; then
|
||||
if (cd "${SPIDIR}" && make all 2>&1); then
|
||||
log_ok "SPI tools (mspi_main)"
|
||||
else
|
||||
log_fail "SPI tools"
|
||||
fi
|
||||
else
|
||||
log_skip "SPI tools Makefile not found"
|
||||
fi
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build CPLD bitstreams for each target machine.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_cpld() {
|
||||
log_info "Building CPLD bitstreams..."
|
||||
|
||||
if ! command -v quartus_sh &>/dev/null; then
|
||||
log_skip "Quartus not found in PATH (use Quartus Docker: qp130)"
|
||||
return
|
||||
fi
|
||||
|
||||
for target in ${CPLD_TARGETS}; do
|
||||
local BUILDDIR="${CPLDDIR}/${target}/build"
|
||||
local PROJECT="tzpuFusionX_${target}"
|
||||
|
||||
if [ ! -f "${BUILDDIR}/${PROJECT}.qpf" ]; then
|
||||
log_skip "CPLD: No Quartus project for ${target}"
|
||||
continue
|
||||
fi
|
||||
|
||||
log_info " Compiling CPLD: ${target}"
|
||||
if (cd "${BUILDDIR}" && quartus_sh --flow compile "${PROJECT}" 2>&1); then
|
||||
if [ -f "${BUILDDIR}/output_files/${PROJECT}.pof" ]; then
|
||||
log_ok "CPLD: ${PROJECT}.pof"
|
||||
else
|
||||
log_fail "CPLD: ${target} (no .pof output)"
|
||||
fi
|
||||
else
|
||||
log_fail "CPLD: ${target}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Clean all build artifacts.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
do_clean() {
|
||||
log_info "Cleaning build artifacts..."
|
||||
|
||||
# Assembly temporaries.
|
||||
rm -f "${TMPDIR}"/*.obj "${TMPDIR}"/*.sym 2>/dev/null
|
||||
|
||||
# Driver build artifacts.
|
||||
if [ -f "${DRVDIR}/Makefile" ]; then
|
||||
(cd "${DRVDIR}" && make clean 2>/dev/null) || true
|
||||
fi
|
||||
if [ -f "${TTYDIR}/Makefile" ]; then
|
||||
(cd "${TTYDIR}" && make clean 2>/dev/null) || true
|
||||
fi
|
||||
if [ -f "${SPIDIR}/Makefile" ]; then
|
||||
(cd "${SPIDIR}" && make clean 2>/dev/null) || true
|
||||
fi
|
||||
|
||||
log_ok "Clean complete"
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Main.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
BUILD_ASM=false
|
||||
BUILD_TZFS=false
|
||||
BUILD_CPM=false
|
||||
BUILD_DRIVERS=false
|
||||
BUILD_SPI=false
|
||||
BUILD_CPLD=false
|
||||
BUILD_ALL=false
|
||||
DO_CLEAN=false
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
BUILD_ALL=true
|
||||
fi
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--all) BUILD_ALL=true ;;
|
||||
--asm) BUILD_ASM=true ;;
|
||||
--tzfs) BUILD_TZFS=true ;;
|
||||
--cpm) BUILD_CPM=true ;;
|
||||
--drivers) BUILD_DRIVERS=true ;;
|
||||
--spi) BUILD_SPI=true ;;
|
||||
--cpld) BUILD_CPLD=true ;;
|
||||
--clean) DO_CLEAN=true ;;
|
||||
--help|-h) usage ;;
|
||||
*) echo "Unknown option: $1"; usage ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
echo "========================================"
|
||||
echo " FusionX Build System"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
if ${DO_CLEAN}; then
|
||||
do_clean
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ${BUILD_ALL} || ${BUILD_ASM}; then build_asm_roms; fi
|
||||
if ${BUILD_ALL} || ${BUILD_TZFS}; then build_tzfs; fi
|
||||
if ${BUILD_ALL} || ${BUILD_CPM}; then build_cpm; fi
|
||||
if ${BUILD_ALL} || ${BUILD_DRIVERS}; then build_drivers; fi
|
||||
if ${BUILD_ALL} || ${BUILD_SPI}; then build_spi; fi
|
||||
if ${BUILD_ALL} || ${BUILD_CPLD}; then build_cpld; fi
|
||||
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo " Build Summary"
|
||||
echo " Passed: ${PASS} Failed: ${FAIL} Skipped: ${SKIP}"
|
||||
echo "========================================"
|
||||
|
||||
if [ ${FAIL} -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
BIN
software/FusionX/bin/k64fcpu
vendored
BIN
software/FusionX/bin/k64fcpu
vendored
Binary file not shown.
BIN
software/FusionX/bin/sharpbiter
vendored
BIN
software/FusionX/bin/sharpbiter
vendored
Binary file not shown.
BIN
software/FusionX/bin/z80ctrl
vendored
BIN
software/FusionX/bin/z80ctrl
vendored
Binary file not shown.
BIN
software/FusionX/modules/ttymzdrv.ko
vendored
BIN
software/FusionX/modules/ttymzdrv.ko
vendored
Binary file not shown.
BIN
software/FusionX/modules/z80drv.ko
vendored
BIN
software/FusionX/modules/z80drv.ko
vendored
Binary file not shown.
5
software/FusionX/src/ttymz/Makefile
vendored
5
software/FusionX/src/ttymz/Makefile
vendored
@@ -1,5 +1,6 @@
|
||||
# Select the target host.
|
||||
#MODEL := MZ2000
|
||||
#MODEL := MZ1500
|
||||
#MODEL := MZ700
|
||||
#MODEL := MZ80A
|
||||
#MODEL := PCW8XXX
|
||||
@@ -26,6 +27,7 @@ all:
|
||||
|
||||
MZ80A: MODEL_MZ80A
|
||||
MZ700: MODEL_MZ700
|
||||
MZ1500: MODEL_MZ1500
|
||||
MZ2000: MODEL_MZ2000
|
||||
PCW8XXX: MODEL_PCW8XXX
|
||||
PCW9XXX: MODEL_PCW9XXX
|
||||
@@ -34,6 +36,8 @@ MODEL_MZ80A:
|
||||
$(MAKE) MODEL=MZ80A BUILD_MZ80A
|
||||
MODEL_MZ700:
|
||||
$(MAKE) MODEL=MZ700 BUILD_MZ700
|
||||
MODEL_MZ1500:
|
||||
$(MAKE) MODEL=MZ1500 BUILD_MZ1500
|
||||
MODEL_MZ2000:
|
||||
$(MAKE) MODEL=MZ2000 BUILD_MZ2000
|
||||
MODEL_PCW8XXX:
|
||||
@@ -43,6 +47,7 @@ MODEL_PCW9XXX:
|
||||
|
||||
BUILD_MZ80A: kmod
|
||||
BUILD_MZ700: kmod
|
||||
BUILD_MZ1500: kmod
|
||||
BUILD_MZ2000: kmod
|
||||
BUILD_PCW8XXX: kmod
|
||||
BUILD_PCW9XXX: kmod
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
219
software/FusionX/src/ttymz/sharpmz.h
vendored
219
software/FusionX/src/ttymz/sharpmz.h
vendored
@@ -12,6 +12,9 @@
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: v1.0 Feb 2023 - Initial write of the Sharp MZ series hardware interface software.
|
||||
// v1.01 Mar 2023 - Bug fixes and additional ESC sequence processing.
|
||||
// v1.02 May 2023 - Updates to accommodate MZ-1500 host.
|
||||
// v1.2 Jul 2023 - Fixed MZ-1500 ATB Display of lower case characters.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -37,36 +40,47 @@
|
||||
#endif
|
||||
|
||||
// Build time target. Overrides if compile time definition given.
|
||||
#if defined(TARGET_HOST_MZ700)
|
||||
#define TARGET_HOST_MZ700 1
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ2000)
|
||||
#define TARGET_HOST_MZ2000 1
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ80A)
|
||||
#if defined(TARGET_HOST_MZ80A)
|
||||
#define TARGET_HOST_MZ80A 1
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ700)
|
||||
#define TARGET_HOST_MZ700 1
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ1500)
|
||||
#define TARGET_HOST_MZ1500 1
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ2000)
|
||||
#define TARGET_HOST_MZ2000 1
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_PCW8XXX) || defined(TARGET_HOST_PCW9XXX)
|
||||
#define TARGET_HOST_PCW 1
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#else
|
||||
#define TARGET_HOST_MZ700 0 // Target compilation for an MZ700
|
||||
#define TARGET_HOST_MZ2000 0 // MZ2000
|
||||
#define TARGET_HOST_MZ80A 0 // MZ80A
|
||||
#define TARGET_HOST_MZ1500 0 // MZ1500
|
||||
#define TARGET_HOST_MZ2000 0 // MZ2000
|
||||
#define TARGET_HOST_PCW 0 // Amstrad PCW8XXX/9XXX
|
||||
#endif
|
||||
|
||||
// Video display constants.
|
||||
#define VC_MAX_ROWS 25 // Maximum number of rows on display.
|
||||
#if defined(TARGET_HOST_MZ700)
|
||||
#if (TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
#define VC_MAX_COLUMNS 40 // Maximum number of columns on display.
|
||||
#else
|
||||
#define VC_MAX_COLUMNS 80 // Maximum number of columns on display.
|
||||
@@ -78,14 +92,25 @@
|
||||
#define KEYB_AUTOREPEAT_INITIAL_TIME 800 // Time in milliseconds before starting autorepeat.
|
||||
#define KEYB_AUTOREPEAT_TIME 100 // Time in milliseconds between auto repeating characters.
|
||||
#define KEYB_FLASH_TIME 350 // Time in milliseconds for the cursor flash change.
|
||||
#define CURSOR_THICK_BLOCK 0x43 // Thick block cursor for lower case CAPS OFF
|
||||
#define CURSOR_BLOCK 0xEF // Block cursor for SHIFT Lock.
|
||||
#define CURSOR_UNDERLINE 0x3E // Thick underscore for CAPS Lock.
|
||||
#define MAX_KEYB_BUFFER_SIZE 32 // Maximum size of the keyboard buffer.
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
#define KEY_SCAN_ROWS 10 // Number of rows on keyboard to scan.
|
||||
#define CURSOR_CHR_THICK_BLOCK 0x43 // Thick block cursor for Shift Lock.
|
||||
#define CURSOR_CHR_BLOCK 0xD0 // Block cursor for CAPS Lock.
|
||||
#define CURSOR_CHR_GRAPH 0xFF // Graphic cursor for GRAPH mode.
|
||||
#define CURSOR_CHR_UNDERLINE 0x3C // Underline for lower case CAPS OFF.
|
||||
#elif (TARGET_HOST_MZ2000 == 1)
|
||||
#define KEY_SCAN_ROWS 12
|
||||
#define CURSOR_CHR_THICK_BLOCK 0x1E // Thick block cursor for Shift Lock.
|
||||
#define CURSOR_CHR_BLOCK 0x82 // Block cursor for CAPS Lock.
|
||||
#define CURSOR_CHR_GRAPH 0x93 // Graphic cursor for GRAPH mode.
|
||||
#define CURSOR_CHR_UNDERLINE 0x1F // Underline for lower case CAPS OFF.
|
||||
#endif
|
||||
|
||||
// Audio constants.
|
||||
#define TIMER_8253_MZ80A_FREQ 2000000 // Base input frequency of Timer 0 for square wave generation.
|
||||
#define TIMER_8253_MZ700_FREQ 768000 // Base input frequency of Timer 0 for square wave generation.
|
||||
#define TIMER_8253_MZ1500_FREQ 768000 // Base input frequency of Timer 0 for square wave generation.
|
||||
|
||||
// Base addresses and sizes within the Video Controller.
|
||||
#define VIDEO_BASE_ADDR 0x000000 // Base address of the Video Controller.
|
||||
@@ -134,7 +159,7 @@
|
||||
#define VMATTR_BG_MASKOUT 0xF8 // Mask to filter out background attribute.
|
||||
#define VMATTR_BG_MASKIN 0x07 // Mask to filter out background attribute.
|
||||
|
||||
// Sharp MZ constants.
|
||||
// Sharp MZ-80A/700 constants.
|
||||
//
|
||||
#define MBADDR_KEYPA 0xE000 // Mainboard 8255 Port A
|
||||
#define MBADDR_KEYPB 0xE001 // Mainboard 8255 Port B
|
||||
@@ -155,6 +180,45 @@
|
||||
#define MBADDR_SCLDSP 0xE200 // Hardware scroll, a read to each location adds 8 to the start of the video access address therefore creating hardware scroll. 00 - reset to power up
|
||||
#define MBADDR_SCLBASE 0xE2 // High byte scroll base.
|
||||
#define MBADDR_DSPCTL 0xDFFF // Display 40/80 select register (bit 7)
|
||||
#define IO_ADDR_E0 0xE0
|
||||
#define IO_ADDR_E1 0xE1
|
||||
#define IO_ADDR_E2 0xE2
|
||||
#define IO_ADDR_E3 0xE3
|
||||
#define IO_ADDR_E4 0xE4
|
||||
#define IO_ADDR_E5 0xE5
|
||||
#define IO_ADDR_E6 0xE6
|
||||
#define IO_ADDR_E7 0xE7
|
||||
#define IO_ADDR_E8 0xE8
|
||||
#define IO_PSG_BOTH 0xE9
|
||||
#define IO_ADDR_EA 0xEA
|
||||
#define IO_ADDR_EB 0xEB
|
||||
#define IO_PCG_PRIO 0xF0
|
||||
#define IO_PALETTE 0xF1
|
||||
|
||||
// Sharp MZ-2000 constants.
|
||||
#define MBADDR_FDC 0x0D8 // MB8866 IO Region 0D8h - 0DBh
|
||||
#define MBADDR_FDC_CR MBADDR_FDC + 0x00 // Command Register
|
||||
#define MBADDR_FDC_STR MBADDR_FDC + 0x00 // Status Register
|
||||
#define MBADDR_FDC_TR MBADDR_FDC + 0x01 // Track Register
|
||||
#define MBADDR_FDC_SCR MBADDR_FDC + 0x02 // Sector Register
|
||||
#define MBADDR_FDC_DR MBADDR_FDC + 0x03 // Data Register
|
||||
#define MBADDR_FDC_MOTOR MBADDR_FDC + 0x04 // 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)
|
||||
#define MBADDR_FDC_SIDE MBADDR_FDC + 0x05 // Side select, Bit 0 when set = SIDE SELECT LOW,
|
||||
#define MBADDR_FDC_DDEN MBADDR_FDC + 0x06 // Double density enable, 0 = double density, 1 = single density disks.
|
||||
#define MBADDR_PPIA 0x0E0 // 8255 Port A
|
||||
#define MBADDR_PPIB 0x0E1 // 8255 Port B
|
||||
#define MBADDR_PPIC 0x0E2 // 8255 Port C
|
||||
#define MBADDR_PPICTL 0x0E3 // 8255 Control Port
|
||||
#define MBADDR_PIOA 0x0E8 // Z80 PIO Port A
|
||||
#define MBADDR_PIOCTLA 0x0E9 // Z80 PIO Port A Control Port
|
||||
#define MBADDR_PIOB 0x0EA // Z80 PIO Port B
|
||||
#define MBADDR_PIOCTLB 0x0EB // Z80 PIO Port B Control Port
|
||||
#define MBADDR_CRTBKCOLR 0x0F4 // Configure external CRT background colour.
|
||||
#define MBADDR_CRTGRPHPRIO 0x0F5 // Graphics priority register, character or a graphics colour has front display priority.
|
||||
#define MBADDR_CRTGRPHSEL 0x0F6 // Graphics output select on CRT or external CRT
|
||||
#define MBADDR_GRAMCOLRSEL 0x0F7 // Graphics RAM colour bank select.
|
||||
#define MBADDR_GRAMADDRL 0x0C000 // Graphics RAM base address.
|
||||
|
||||
//Common character definitions.
|
||||
#define SCROLL 0x01 // Set scroll direction UP.
|
||||
@@ -201,7 +265,7 @@
|
||||
#define CTRL_Z 0x1A
|
||||
#define ESC 0x1B
|
||||
#define CTRL_SLASH 0x1C
|
||||
#define CTRL_LB 0x1B
|
||||
#define CTRL_LB 0x1
|
||||
#define CTRL_RB 0x1D
|
||||
#define CTRL_CAPPA 0x1E
|
||||
#define CTRL_UNDSCR 0x1F
|
||||
@@ -216,15 +280,16 @@
|
||||
#define FUNC8 0x87
|
||||
#define FUNC9 0x88
|
||||
#define FUNC10 0x89
|
||||
#define PAGEUP 0xE0
|
||||
#define PAGEDOWN 0xE1
|
||||
#define CURHOMEKEY 0xE2
|
||||
#define ALPHAGRAPHKEY 0xE3
|
||||
#define HOTKEY_ORIGINAL 0xE8
|
||||
#define HOTKEY_RFS80 0xE9
|
||||
#define HOTKEY_RFS40 0xEA
|
||||
#define HOTKEY_TZFS 0xEB
|
||||
#define HOTKEY_LINUX 0xEC
|
||||
#define HOTKEY_ORIGINAL 0xE0
|
||||
#define HOTKEY_RFS80 0xE1
|
||||
#define HOTKEY_RFS40 0xE2
|
||||
#define HOTKEY_TZFS 0xE3
|
||||
#define HOTKEY_LINUX 0xE4
|
||||
#define PAGEUP 0xE8
|
||||
#define PAGEDOWN 0xE9
|
||||
#define CURHOMEKEY 0xEA
|
||||
#define ALPHAGRAPHKEY 0xEB
|
||||
#define SHIFTLOCKKEY 0xEC
|
||||
#define NOKEY 0xF0
|
||||
#define CURSRIGHT 0xF1
|
||||
#define CURSLEFT 0xF2
|
||||
@@ -263,6 +328,85 @@
|
||||
#define READ_HARDWARE() (\
|
||||
z80io_PRL_Read8(1)\
|
||||
)
|
||||
#define WRITE_HARDWARE_IO(__force__,__addr__,__data__)\
|
||||
{\
|
||||
if(!ctrl.suspendIO || __force__ == 1)\
|
||||
{\
|
||||
SPI_SEND32((uint32_t)__addr__ << 16 | __data__ << 8 | CPLD_CMD_WRITEIO_ADDR);\
|
||||
}\
|
||||
}
|
||||
#define READ_HARDWARE_IO_INIT(__force__,__addr__)\
|
||||
{\
|
||||
if(!ctrl.suspendIO || __force__ == 1)\
|
||||
{\
|
||||
SPI_SEND32((uint32_t)__addr__ << 16 | 0x00 << 8 | CPLD_CMD_READIO_ADDR);\
|
||||
while(CPLD_READY() == 0);\
|
||||
}\
|
||||
}
|
||||
#define READ_HARDWARE_IO() (\
|
||||
z80io_PRL_Read8(1)\
|
||||
)
|
||||
// Video memory macros, allows for options based on host hardware - All Sharp MZ series are very similar.
|
||||
#if (TARGET_HOST_MZ2000 == 1)
|
||||
// A7 : H 0xD000:0xD7FF or 0xC000:0xFFFF VRAM paged in.
|
||||
// A6 : H Select Character VRAM (H) or Graphics VRAM (L)
|
||||
// A5 : H Select 80 char mode, 40 char mode = L
|
||||
// A4 : L Select all key strobe lines active, for detection of any key press.
|
||||
// A3-A0: Keyboard strobe lines
|
||||
#define ENABLE_VIDEO() {\
|
||||
display.hwVideoMode = (display.hwVideoMode & 0x3F) | 0xC0;\
|
||||
WRITE_HARDWARE_IO(0, MBADDR_PIOA, display.hwVideoMode);\
|
||||
}
|
||||
#define DISABLE_VIDEO() {\
|
||||
display.hwVideoMode = (display.hwVideoMode & 0x3F);\
|
||||
WRITE_HARDWARE_IO(0, MBADDR_PIOA, display.hwVideoMode);\
|
||||
}
|
||||
#define WRITE_VRAM_CHAR(__addr__,__data__,__xlat__) WRITE_HARDWARE(0,__addr__,__data__)
|
||||
#define WRITE_VRAM_ATTRIBUTE(__addr__,__data__) {}
|
||||
#define WRITE_KEYB_STROBE(__data__)\
|
||||
{\
|
||||
display.hwVideoMode = (display.hwVideoMode & 0xF0) | 0x10 | (__data__ & 0x0F);\
|
||||
WRITE_HARDWARE_IO(0, MBADDR_PIOA, display.hwVideoMode );\
|
||||
}
|
||||
#define READ_KEYB_INIT() READ_HARDWARE_IO_INIT(0, MBADDR_PIOB)
|
||||
#define READ_KEYB() READ_HARDWARE_IO()
|
||||
#elif (TARGET_HOST_MZ1500 ==1)
|
||||
#define ENABLE_VIDEO() {}
|
||||
#define DISABLE_VIDEO() {}
|
||||
#define WRITE_VRAM_CHAR(__addr__,__data__,__xlat__) if(__xlat__ == 1)\
|
||||
{\
|
||||
if(islower(__data__))\
|
||||
{\
|
||||
WRITE_HARDWARE(0,__addr__,(dispCodeMap[(int)(__data__)].dispCode & 0x7F));\
|
||||
READ_HARDWARE_INIT(0,(__addr__+0x800));\
|
||||
WRITE_HARDWARE(0,(__addr__+0x800),(READ_HARDWARE() | 0x80));\
|
||||
} else\
|
||||
{\
|
||||
WRITE_HARDWARE(0,__addr__,dispCodeMap[(int)(__data__)].dispCode);\
|
||||
READ_HARDWARE_INIT(0,(__addr__+0x800));\
|
||||
WRITE_HARDWARE(0,(__addr__+0x800),(READ_HARDWARE() & 0x7F));\
|
||||
}\
|
||||
} else\
|
||||
{\
|
||||
WRITE_HARDWARE(0,__addr__, __data__);\
|
||||
}
|
||||
#define WRITE_VRAM_ATTRIBUTE(__addr__,__data__) {\
|
||||
READ_HARDWARE_INIT(0,(__addr__));\
|
||||
WRITE_HARDWARE(0,__addr__,((READ_HARDWARE() & 0x80) | (__data__ & 0x7F)));\
|
||||
}
|
||||
#define WRITE_KEYB_STROBE(__data__) WRITE_HARDWARE(0, MBADDR_KEYPA, __data__)
|
||||
#define READ_KEYB_INIT() READ_HARDWARE_INIT(0, MBADDR_KEYPB)
|
||||
#define READ_KEYB() READ_HARDWARE()
|
||||
#else
|
||||
#define ENABLE_VIDEO() {}
|
||||
#define DISABLE_VIDEO() {}
|
||||
#define WRITE_VRAM_CHAR(__addr__,__data__,__xlat__) WRITE_HARDWARE(0,__addr__,(__xlat__ == 1 ? dispCodeMap[(int)__data__].dispCode : __data__))
|
||||
#define WRITE_VRAM_ATTRIBUTE(__addr__,__data__) WRITE_HARDWARE(0,__addr__,__data__)
|
||||
#define WRITE_KEYB_STROBE(__data__) WRITE_HARDWARE(0, MBADDR_KEYPA, __data__)
|
||||
#define READ_KEYB_INIT() READ_HARDWARE_INIT(0, MBADDR_KEYPB)
|
||||
#define READ_KEYB() READ_HARDWARE()
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Cursor flash mechanism control states.
|
||||
@@ -316,7 +460,7 @@ typedef struct {
|
||||
// Mapping table from keyboard scan codes to Sharp MZ keys.
|
||||
//
|
||||
typedef struct {
|
||||
uint8_t scanCode[80];
|
||||
uint8_t scanCode[KEY_SCAN_ROWS*8];
|
||||
} t_scanCodeMap;
|
||||
|
||||
// Mapping table of a sharp keycode to an ANSI escape sequence string.
|
||||
@@ -349,16 +493,19 @@ typedef struct {
|
||||
uint8_t lineWrap; // Wrap line at display edge (1) else stop printing at display edge.
|
||||
uint8_t useAnsiTerm; // Enable (1) Ansi Terminal Emulator, (0) disable.
|
||||
uint8_t inDebug; // Prevent recursion when outputting debug information.
|
||||
|
||||
// Working variables.
|
||||
uint8_t hwVideoMode; // Physical configuration of the video control register.
|
||||
} t_displayBuffer;
|
||||
|
||||
// Structure for maintaining the Sharp MZ keyboard parameters and data. Used to retrieve and map a key along with associated
|
||||
// attributes such as cursor flashing.
|
||||
//
|
||||
typedef struct {
|
||||
uint8_t scanbuf[2][10];
|
||||
uint8_t keydown[10];
|
||||
uint8_t keyup[10];
|
||||
uint8_t keyhold[10];
|
||||
uint8_t scanbuf[2][KEY_SCAN_ROWS];
|
||||
uint8_t keydown[KEY_SCAN_ROWS];
|
||||
uint8_t keyup[KEY_SCAN_ROWS];
|
||||
uint8_t keyhold[KEY_SCAN_ROWS];
|
||||
uint32_t holdTimer;
|
||||
uint8_t breakKey; // Break key pressed.
|
||||
uint8_t ctrlKey; // Ctrl key pressed.
|
||||
@@ -398,10 +545,10 @@ typedef struct {
|
||||
uint8_t setDisplayMode; // Display mode command detected.
|
||||
uint8_t setExtendedMode; // Extended mode command detected.
|
||||
uint8_t charbuf[80]; // Storage for the parameter characters as they are received.
|
||||
uint16_t param[10]; // Parsed paraemters.
|
||||
uint16_t param[10]; // Parsed parameters.
|
||||
uint8_t saveRow; // Store the current row when requested.
|
||||
uint8_t saveCol; // Store the current column when requested.
|
||||
uint8_t saveDisplayRow; // Store the current display buffer row when requested.
|
||||
uint8_t saveDisplayRow; // Store the current display buffer row when requested.
|
||||
} t_AnsiTerm;
|
||||
|
||||
// Application execution constants.
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
// switching between a Linux session and a Z80 session, the idea
|
||||
// being the TTY will continue to run within the mirrored framebuffer
|
||||
// and when reselected, refresh the hardware screen.
|
||||
// Apr 2023 - v1.1 Updated to include MZ-2000 mode.
|
||||
// Jul 2023 - v1.2 Updates and bug fixes.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -863,8 +865,8 @@ static int __init ttymz_init(void)
|
||||
mzInit();
|
||||
|
||||
// Sign on.
|
||||
sprintf(buf, "%s %s", DRIVER_DESCRIPTION, DRIVER_VERSION); mzWriteString(0, 0, buf, -1);
|
||||
sprintf(buf, "%s %s\n", DRIVER_COPYRIGHT, DRIVER_AUTHOR); mzWriteString(0, 1, buf, -1);
|
||||
sprintf(buf, "%s %s", DRIVER_TITLE, DRIVER_VERSION); mzWriteString(0, 0, buf, -1);
|
||||
sprintf(buf, "%s %s\n", DRIVER_COPYRIGHT, DRIVER_AUTHOR); mzWriteString(0, 1, buf, -1);
|
||||
|
||||
pr_info(DRIVER_DESCRIPTION " " DRIVER_VERSION "\n");
|
||||
|
||||
|
||||
23
software/FusionX/src/ttymz/ttymz.h
vendored
23
software/FusionX/src/ttymz/ttymz.h
vendored
@@ -11,6 +11,8 @@
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Feb 2023 - v1.0 Initial write of the Sharp MZ tty driver software.
|
||||
// Apr 2023 - v1.1 Updated to include MZ-2000 mode.
|
||||
// Jul 2023 - v1.2 Updates and bug fixes.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -33,15 +35,28 @@
|
||||
|
||||
// Constants.
|
||||
#define DRIVER_LICENSE "GPL"
|
||||
#define DRIVER_AUTHOR "Philip D Smart"
|
||||
#define DRIVER_AUTHOR "P.D.Smart"
|
||||
#define DRIVER_DESCRIPTION "Sharp MZ TTY Driver"
|
||||
#define DRIVER_VERSION "v1.01"
|
||||
#define DRIVER_VERSION_DATE "Mar 2023"
|
||||
#define DRIVER_COPYRIGHT "(C) 2018-2023"
|
||||
#define DRIVER_VERSION "v1.2"
|
||||
#define DRIVER_VERSION_DATE "July 2023"
|
||||
#define DRIVER_COPYRIGHT "(C) 2018-23"
|
||||
#define DEVICE_NAME "ttymz"
|
||||
#define DRIVER_NAME "SharpMZ_tty"
|
||||
#define DEBUG_ENABLED 0 // 0 = disabled, 1 .. debug level.
|
||||
#define ARBITER_NAME "sharpbiter"
|
||||
#if (TARGET_HOST_MZ80A == 1)
|
||||
#define DRIVER_TITLE "Sharp MZ-80A TTY"
|
||||
#elif (TARGET_HOST_MZ700 == 1)
|
||||
#define DRIVER_TITLE "Sharp MZ-700 TTY"
|
||||
#elif (TARGET_HOST_MZ1500 == 1)
|
||||
#define DRIVER_TITLE "Sharp MZ-1500 TTY"
|
||||
#elif (TARGET_HOST_MZ2000 == 1)
|
||||
#define DRIVER_TITLE "Sharp MZ-2000 TTY"
|
||||
#elif (TARGET_HOST_PCW == 1)
|
||||
#define DRIVER_TITLE "Amstrad PCW-8XXX TTY"
|
||||
#else
|
||||
#define DRIVER_MODEL "not defined"
|
||||
#endif
|
||||
|
||||
// Fake UART values
|
||||
#define MCR_DTR 0x01
|
||||
|
||||
5
software/FusionX/src/z80drv/Makefile
vendored
5
software/FusionX/src/z80drv/Makefile
vendored
@@ -1,4 +1,5 @@
|
||||
#MODEL := MZ2000
|
||||
#MODEL := MZ1500
|
||||
#MODEL := MZ700
|
||||
#MODEL := MZ80A
|
||||
#MODEL := PCW8XXX
|
||||
@@ -23,6 +24,7 @@ all:
|
||||
|
||||
MZ80A: MODEL_MZ80A
|
||||
MZ700: MODEL_MZ700
|
||||
MZ1500: MODEL_MZ1500
|
||||
MZ2000: MODEL_MZ2000
|
||||
PCW8XXX: MODEL_PCW8XXX
|
||||
PCW9XXX: MODEL_PCW9XXX
|
||||
@@ -31,6 +33,8 @@ MODEL_MZ80A:
|
||||
$(MAKE) MODEL=MZ80A BUILD_MZ80A
|
||||
MODEL_MZ700:
|
||||
$(MAKE) MODEL=MZ700 BUILD_MZ700
|
||||
MODEL_MZ1500:
|
||||
$(MAKE) MODEL=MZ1500 BUILD_MZ1500
|
||||
MODEL_MZ2000:
|
||||
$(MAKE) MODEL=MZ2000 BUILD_MZ2000
|
||||
MODEL_PCW8XXX:
|
||||
@@ -40,6 +44,7 @@ MODEL_PCW9XXX:
|
||||
|
||||
BUILD_MZ80A: sharpbiter k64fcpu kmod z80ctrl
|
||||
BUILD_MZ700: sharpbiter k64fcpu kmod z80ctrl
|
||||
BUILD_MZ1500: sharpbiter k64fcpu kmod z80ctrl
|
||||
BUILD_MZ2000: sharpbiter k64fcpu kmod z80ctrl
|
||||
BUILD_PCW8XXX: kmod z80ctrl
|
||||
BUILD_PCW9XXX: kmod z80ctrl
|
||||
|
||||
11
software/FusionX/src/z80drv/README.txt
vendored
11
software/FusionX/src/z80drv/README.txt
vendored
@@ -1,12 +1,13 @@
|
||||
Development Cycle
|
||||
-----------------
|
||||
|
||||
To avoid changes for one host affecting another the driver is split into seperate hosts containing almost identical code.
|
||||
The idea, after development is complete, is to merge them into a single drive which autodetects, via the CPLD, the host model
|
||||
and selects the code accordingly.
|
||||
z80drv now supports several machines, ie. MZ-80A, MZ-700, MZ-2000, PCW-8256 with more in the pipeline.
|
||||
|
||||
Please edit Makefile and set the model prior to changing the Model source. In theory this file will be deleted once the source is
|
||||
merged.
|
||||
Please edit Makefile and set the model prior to changing the Model source. Alternatively, isse make with the host name, ie. make MZ80A.
|
||||
|
||||
The virtual device concept (ie. an MZ-700 with a tranZPUter SW card) has been incorporated as virtual hardware modules, ie. z80vhw_rfs.c
|
||||
which adds the RFS card to the MZ-700/MZ-80A. These virtual devices are built and added to the target kernel module dependent on supported
|
||||
host.
|
||||
|
||||
Zeta
|
||||
----
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
// History: Feb 2023 v1.0 - Source copied from zSoft and modified to run as a daemon, stripping
|
||||
// out all low level control methods.
|
||||
// v1.01 - Updates to make compatible with the TZFS changes.
|
||||
// Apr v1.02 - Updates to add MZ-2000 servicing.
|
||||
// May v1.03 - Updates to add MZ-1500 servicing.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -64,7 +66,7 @@ extern "C" {
|
||||
#include "z80driver.h"
|
||||
#include "tzpu.h"
|
||||
|
||||
#define VERSION "1.01"
|
||||
#define VERSION "1.02"
|
||||
#define AUTHOR "P.D.Smart"
|
||||
#define COPYRIGHT "(c) 2018-23"
|
||||
|
||||
@@ -2328,6 +2330,13 @@ void loadTranZPUterDefaultROMS(uint8_t cpuConfig)
|
||||
}
|
||||
break;
|
||||
|
||||
case HW_MZ1500:
|
||||
#if(DEBUG_ENABLED & 0x2)
|
||||
if(Z80Ctrl->debug >= 2) printf("Loading 1Z_009B\n");
|
||||
#endif
|
||||
result = loadTZFS(MZ_ROM_1Z_009B_40C, MZ_MROM_ADDR);
|
||||
break;
|
||||
|
||||
case HW_MZ80B:
|
||||
//result = loadBIOS(MZ_ROM_MZ80B_IPL, MZ80B, MZ_MROM_ADDR);
|
||||
result = loadBIOS(MZ_ROM_MZ80B_IPL, MZ_MROM_ADDR);
|
||||
@@ -2402,6 +2411,7 @@ void processServiceRequest(void)
|
||||
// Update the service control record address according to memory mode.
|
||||
//
|
||||
z80Control.svcControlAddr = getServiceAddr();
|
||||
printf("Service Addr:%04x\n", z80Control.svcControlAddr);
|
||||
|
||||
// Get the command and associated parameters.
|
||||
copyFromZ80((uint8_t *)&svcControl, z80Control.svcControlAddr, TZSVC_CMD_SIZE, TRANZPUTER);
|
||||
@@ -2411,7 +2421,7 @@ void processServiceRequest(void)
|
||||
{
|
||||
copyFromZ80((uint8_t *)&svcControl.sector, z80Control.svcControlAddr+TZSVC_CMD_SIZE, TZSVC_SECTOR_SIZE, TRANZPUTER);
|
||||
}
|
||||
|
||||
printf("Received command:%02x\n", svcControl.cmd);
|
||||
//memoryDump((uint32_t)&svcControl, sizeof(svcControl), 5, 8, 0, 0);
|
||||
// Check this is a valid request.
|
||||
if(svcControl.result == TZSVC_STATUS_REQUEST)
|
||||
@@ -2560,7 +2570,7 @@ void processServiceRequest(void)
|
||||
break;
|
||||
|
||||
// Load the MZ-2000 IPL ROM into memory for compatibility switch.
|
||||
case TZSVC_CMD_LOAD2000IPL:
|
||||
case TZSVC_CMD_LOAD2KIPL:
|
||||
loadBIOS((const char *)OS_BASE_DIR TZSVC_DEFAULT_TZFS_DIR "/" MZ_ROM_MZ2000_IPL, MZ_MROM_ADDR);
|
||||
|
||||
// Set the frequency of the CPU if we are emulating the hardware.
|
||||
@@ -2570,6 +2580,21 @@ void processServiceRequest(void)
|
||||
setZ80CPUFrequency(MZ_2000_CPU_FREQ, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
// Load the MZ-2000 Basic 1Z001 into memory.
|
||||
case TZSVC_CMD_LOAD2KBASIC1:
|
||||
loadBIOS((const char *)OS_BASE_DIR TZSVC_DEFAULT_ROM_DIR "/" MZ_ROM_MZ2000_1Z001, MZ_MROM_ADDR);
|
||||
break;
|
||||
|
||||
// Load the MZ-2000 Basic 1Z002 into memory.
|
||||
case TZSVC_CMD_LOAD2KBASIC2:
|
||||
loadBIOS((const char *)OS_BASE_DIR TZSVC_DEFAULT_ROM_DIR "/" MZ_ROM_MZ2000_1Z002, MZ_MROM_ADDR);
|
||||
break;
|
||||
|
||||
// Load the MZ-2000 1Z001M Monitor ROM into memory.
|
||||
case TZSVC_CMD_LOAD2KMON:
|
||||
loadBIOS((const char *)OS_BASE_DIR TZSVC_DEFAULT_ROM_DIR "/" MZ_ROM_MZ2000_1Z001M, MZ_MROM_ADDR);
|
||||
break;
|
||||
|
||||
// Load TZFS upon request. This service is for the MZ-80B/MZ-2000 which dont have a monitor BIOS installed and TZFS isnt loaded upon reset but rather through user request.
|
||||
case TZSVC_CMD_LOADTZFS:
|
||||
@@ -2709,6 +2734,8 @@ void processServiceRequest(void)
|
||||
printf("Error: Unsupported Raw SD Write feature.\n");
|
||||
break;
|
||||
|
||||
// Load
|
||||
|
||||
// Command to exit from TZFS and return machine to original mode.
|
||||
case TZSVC_CMD_EXIT:
|
||||
// Disable secondary frequency.
|
||||
@@ -2927,6 +2954,8 @@ int main(int argc, char *argv[])
|
||||
z80Control.hostType = HW_MZ80A;
|
||||
#elif (TARGET_HOST_MZ700 == 1)
|
||||
z80Control.hostType = HW_MZ700;
|
||||
#elif (TARGET_HOST_MZ1500 == 1)
|
||||
z80Control.hostType = HW_MZ1500;
|
||||
#elif (TARGET_HOST_MZ2000 == 1)
|
||||
z80Control.hostType = HW_MZ2000;
|
||||
#else
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Feb 2023 v1.0 - Initial write.
|
||||
// Apr 2023 v1.1 - Updates to include MZ-2000.
|
||||
// Apr 2023 v1.2 - Updates to include MZ-1500.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -337,12 +339,15 @@ int main(int argc, char *argv[])
|
||||
#if(TARGET_HOST_MZ80A == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ700 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ1500 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#endif
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_RFS80;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
@@ -355,10 +360,12 @@ int main(int argc, char *argv[])
|
||||
ioctlCmd.cmd = IOCTL_CMD_ADD_DEVICE;
|
||||
#if(TARGET_HOST_MZ80A == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A;
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
#elif(TARGET_HOST_MZ700 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
#elif(TARGET_HOST_MZ1500 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
#endif
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
@@ -381,12 +388,15 @@ int main(int argc, char *argv[])
|
||||
#if(TARGET_HOST_MZ80A == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ700 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ1500 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#endif
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_RFS80;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
@@ -418,12 +428,15 @@ int main(int argc, char *argv[])
|
||||
#if(TARGET_HOST_MZ80A == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ700 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ1500 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#endif
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_RFS80;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
@@ -449,12 +462,15 @@ int main(int argc, char *argv[])
|
||||
#if(TARGET_HOST_MZ80A == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ700 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ1500 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#endif
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_RFS80;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
22
software/FusionX/src/z80drv/src/tzpu.h
vendored
22
software/FusionX/src/z80drv/src/tzpu.h
vendored
@@ -50,6 +50,8 @@
|
||||
#define OS_BASE_DIR "/apps/FusionX/host/MZ-80A/" // Linux base directory where all the files are stored. On a real tranZPUter this would be the SD card root dir.
|
||||
#elif (TARGET_HOST_MZ700 == 1)
|
||||
#define OS_BASE_DIR "/apps/FusionX/host/MZ-700/"
|
||||
#elif (TARGET_HOST_MZ1500 == 1)
|
||||
#define OS_BASE_DIR "/apps/FusionX/host/MZ-1500/"
|
||||
#elif (TARGET_HOST_MZ2000 == 1)
|
||||
#define OS_BASE_DIR "/apps/FusionX/host/MZ-2000/"
|
||||
#endif
|
||||
@@ -203,7 +205,7 @@
|
||||
// CPLD Configuration constants.
|
||||
#define HWMODE_MZ80K 0x00 // Hardware mode = MZ80K
|
||||
#define HWMODE_MZ80C 0x01 // Hardware mode = MZ80C
|
||||
#define HWMODE_MZ1200 0x02 // Hardware mode = MZ1200
|
||||
#define HWMODE_MZ1500 0x02 // Hardware mode = MZ1500
|
||||
#define HWMODE_MZ80A 0x03 // Hardware mode = MZ80A
|
||||
#define HWMODE_MZ700 0x04 // Hardware mode = MZ700
|
||||
#define HWMODE_MZ800 0x05 // Hardware mode = MZ800
|
||||
@@ -321,7 +323,11 @@
|
||||
|
||||
// Service request constants.
|
||||
//
|
||||
#define TZSVC_CMD_STRUCT_ADDR_TZFS 0x0ED80 // Address of the command structure within TZFS - exists in 64K Block 0.
|
||||
#if (TARGET_HOST_MZ2000 == 1)
|
||||
#define TZSVC_CMD_STRUCT_ADDR_TZFS 0x06D80 // Address of the command structure within MZ-2000 IPL Mode
|
||||
#else
|
||||
#define TZSVC_CMD_STRUCT_ADDR_TZFS 0x0ED80 // Address of the command structure within TZFS - exists in 64K Block 0.
|
||||
#endif
|
||||
#define TZSVC_CMD_STRUCT_ADDR_CPM 0x4F560 // Address of the command structure within CP/M - exists in 64K Block 4.
|
||||
#define TZSVC_CMD_STRUCT_ADDR_MZ700 0x6FD80 // Address of the command structure within MZ700 compatible programs - exists in 64K Block 6.
|
||||
#define TZSVC_CMD_STRUCT_ADDR_ZOS 0x11FD80 // 0x7FD80 // Address of the command structure for zOS use, exists in shared memory rather than FPGA. Spans top of block 6 and all of block 7.
|
||||
@@ -351,7 +357,10 @@
|
||||
#define TZSVC_CMD_LOAD700BIOS80 0x23 // Service command requesting that the MZ700 1Z-013A 80 column patched BIOS is loaded.
|
||||
#define TZSVC_CMD_LOAD80BIPL 0x24 // Service command requesting the MZ-80B IPL is loaded.
|
||||
#define TZSVC_CMD_LOAD800BIOS 0x25 // Service command requesting that the MZ800 9Z-504M BIOS is loaded.
|
||||
#define TZSVC_CMD_LOAD2000IPL 0x26 // Service command requesting the MZ-2000 IPL is loaded.
|
||||
#define TZSVC_CMD_LOAD2KIPL 0x26 // Service command requesting the MZ-2000 IPL is loaded.
|
||||
#define TZSVC_CMD_LOAD2KBASIC1 0x27 // Service command to load BASIC 1Z-001 for the MZ-2000.
|
||||
#define TZSVC_CMD_LOAD2KBASIC2 0x28 // Service command to load BASIC 1Z-002 for the MZ-2000.
|
||||
#define TZSVC_CMD_LOAD2KMON 0x29 // Service command to load Monitor 1Z001M for the MZ-2000 IPL.
|
||||
#define TZSVC_CMD_LOADTZFS 0x2F // Service command requesting the loading of TZFS. This service is for machines which normally dont have a monitor BIOS. ie. MZ-80B/MZ-2000 and manually request TZFS.
|
||||
#define TZSVC_CMD_LOADBDOS 0x30 // Service command to reload CPM BDOS+CCP.
|
||||
#define TZSVC_CMD_ADDSDDRIVE 0x31 // Service command to attach a CPM disk to a drive number.
|
||||
@@ -379,6 +388,7 @@
|
||||
#define TZSVC_CMD_SD_WRITESECTOR 0x62 // Service command to provide raw write access to the underlying SD card.
|
||||
#define TZSVC_CMD_EXIT 0x7F // Service command to terminate TZFS and restart the machine in original mode.
|
||||
#define TZSVC_DEFAULT_TZFS_DIR "TZFS" // Default directory where TZFS files are stored.
|
||||
#define TZSVC_DEFAULT_ROM_DIR "ROMS" // Default directory where ROM files are stored.
|
||||
#define TZSVC_DEFAULT_CPM_DIR "CPM" // Default directory where CPM files are stored.
|
||||
#define TZSVC_DEFAULT_MZF_DIR "MZF" // Default directory where MZF files are stored.
|
||||
#define TZSVC_DEFAULT_CAS_DIR "CAS" // Default directory where BASIC CASsette files are stored.
|
||||
@@ -413,6 +423,7 @@
|
||||
#define MZ_ROM_1Z_013A_KM_40C "1Z-013A-KM.rom" // Original 40 character Monitor ROM for the Sharp MZ700 with keyboard remapped for the MZ80A.
|
||||
#define MZ_ROM_1Z_013A_KM_80C "1Z-013A-KM-8.rom" // Original Monitor ROM patched for the Sharp MZ700 with keyboard remapped for the MZ80A and patched for 80 column mode.
|
||||
#define MZ_ROM_1Z_013A_2000 "1Z-013A-2000.rom" // Original 40 character Monitor ROM for the Sharp MZ700 modified to run on an MZ-2000.
|
||||
#define MZ_ROM_1Z_009B_40C "1Z-009B.rom" // Original 40 character MZ-1500 Monitor ROM.
|
||||
#define MZ_ROM_9Z_504M_COMBINED "MZ800_IPL.rom" // Original MZ-800 BIOS which comprises the 1Z_013B BIOS, 9Z_504M IPL, CGROM and IOCS.
|
||||
#define MZ_ROM_9Z_504M "MZ800_9Z_504M.rom" // Modified MZ-800 9Z_504M IPL to contain a select TZFS option.
|
||||
#define MZ_ROM_1Z_013B "MZ800_1Z_013B.rom" // Original MZ-800 1Z_013B MZ-700 compatible BIOS.
|
||||
@@ -423,6 +434,9 @@
|
||||
#define MZ_ROM_MZ2000_IPL_TZPU "MZ2000_IPL_TZPU.rom" // Modified IPL ROM for the tranZPUter running on the Sharp MZ-2000.
|
||||
#define MZ_ROM_MZ2000_CGROM "MZ2000_CGROM.rom" // MZ-2000 CGROM.
|
||||
#define MZ_ROM_TZFS "tzfs.rom" // tranZPUter Filing System ROM.
|
||||
#define MZ_ROM_MZ2000_1Z001 "mz2000_basic_1z001.rom" // MZ-2000 BASIC 1Z-001.
|
||||
#define MZ_ROM_MZ2000_1Z002 "mz2000_basic_1z002.rom" // MZ-2000 BASIC 1Z-002.
|
||||
#define MZ_ROM_MZ2000_1Z001M "mz2000_mon_1z001m.rom" // MZ-2000 BASIC 1Z-002.
|
||||
|
||||
// CP/M constants.
|
||||
//
|
||||
@@ -470,7 +484,7 @@ enum TARGETS {
|
||||
enum MACHINE_HW_TYPES {
|
||||
HW_MZ80K = HWMODE_MZ80K, // Host hardware = MZ-80K.
|
||||
HW_MZ80C = HWMODE_MZ80C, // Host hardware = MZ-80C.
|
||||
HW_MZ1200 = HWMODE_MZ1200, // Host hardware = MZ-1200.
|
||||
HW_MZ1500 = HWMODE_MZ1500, // Host hardware = MZ-1500.
|
||||
HW_MZ80A = HWMODE_MZ80A, // Host hardware = MZ-80A.
|
||||
HW_MZ700 = HWMODE_MZ700, // Host hardware = MZ-700.
|
||||
HW_MZ800 = HWMODE_MZ800, // Host hardware = MZ-800.
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
//
|
||||
// History: Oct 2022 v1.0 - v1.Initial write of the z80 kernel driver software.
|
||||
// Feb 2023 v1.1 - Extended to allow Rom upload for RFS and other drivers.
|
||||
// May 2023 v1.2 - Extended to accommodate MZ-1500 host.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -54,7 +55,7 @@
|
||||
#include <Z80.h>
|
||||
#include "z80driver.h"
|
||||
|
||||
#define VERSION "1.1"
|
||||
#define VERSION "1.2"
|
||||
#define AUTHOR "P.D.Smart"
|
||||
#define COPYRIGHT "(c) 2018-23"
|
||||
|
||||
@@ -127,7 +128,7 @@ enum CTRL_COMMANDS {
|
||||
static t_Z80Ctrl *Z80Ctrl = NULL;
|
||||
static uint8_t *Z80RAM = NULL;
|
||||
static uint8_t *Z80ROM = NULL;
|
||||
static uint32_t *Z80PAGE[MEMORY_MODES];
|
||||
static uint32_t *Z80PAGE[MEMORY_MODES+MEMORY_SUB_MODES];
|
||||
static uint8_t memoryPage = 0;
|
||||
|
||||
// Method to obtain and return the output screen width.
|
||||
@@ -436,7 +437,7 @@ int z80load(int fdZ80, char *fileName, uint32_t memLoadAddr, long fileOffset, lo
|
||||
}
|
||||
else
|
||||
{
|
||||
#if(TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ80A)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
if(mzfHeader.loadAddr > 0x1000)
|
||||
{
|
||||
#endif
|
||||
@@ -446,7 +447,7 @@ int z80load(int fdZ80, char *fileName, uint32_t memLoadAddr, long fileOffset, lo
|
||||
// Now read in the data.
|
||||
fread(&Z80RAM[mzfHeader.loadAddr], mzfHeader.fileSize, 1, ptr);
|
||||
printf("Loaded %s, Size:%04x, Addr:%04x, Exec:%04x\n", fileName, mzfHeader.fileSize, mzfHeader.loadAddr, mzfHeader.execAddr);
|
||||
#if(TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ80A)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -459,7 +460,7 @@ int z80load(int fdZ80, char *fileName, uint32_t memLoadAddr, long fileOffset, lo
|
||||
// Set PC to 2 (NST) which switches to RUN mode and executes at 0000H
|
||||
ioctlCmd.z80.pc = 2;
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ80A)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
// MZ-700 or MZ-80A just use the MZF header exec address.
|
||||
ioctlCmd.z80.pc = mzfHeader.execAddr;
|
||||
#endif
|
||||
@@ -601,6 +602,10 @@ int ctrlCmd(int fdZ80, enum CTRL_COMMANDS cmd, long param1, long param2, long pa
|
||||
{
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
}
|
||||
else if(strcasecmp((char *)param1, "MZ1500") == 0)
|
||||
{
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
}
|
||||
else if(strcasecmp((char *)param1, "MZ2000") == 0)
|
||||
{
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
@@ -638,6 +643,10 @@ int ctrlCmd(int fdZ80, enum CTRL_COMMANDS cmd, long param1, long param2, long pa
|
||||
{
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
}
|
||||
else if(strcasecmp((char *)param1, "MZ1500") == 0)
|
||||
{
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
}
|
||||
else if(strcasecmp((char *)param1, "MZ2000") == 0)
|
||||
{
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
@@ -1029,7 +1038,7 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
// Loop through all the memory mapping pages, each page specifies a 64K mapping block, all memory accesses go through this map.
|
||||
for(idx=0; idx < MEMORY_MODES; idx++)
|
||||
for(idx=0; idx < MEMORY_MODES+MEMORY_SUB_MODES; idx++)
|
||||
{
|
||||
// Try and bind the page, if it doesnt exist, then the pointer will be NULL so it wont be used.
|
||||
Z80PAGE[idx] = (uint32_t *)mmap(0, ((MEMORY_BLOCK_SLOTS*sizeof(uint32_t)) + (0x1000*(idx+1))), PROT_READ | PROT_WRITE, MAP_SHARED, fdZ80, 0);
|
||||
|
||||
@@ -13,31 +13,35 @@
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
// (c) 1999-2023 Manuel Sainz de Baranda y Goñi
|
||||
//
|
||||
// History: Oct 2022 - v1.0 Initial write of the z80 kernel driver software.
|
||||
// Jan 2023 - v1.1 Added MZ-2000/MZ-80A modes. There are serious limitations with the
|
||||
// SSD202 I/O. The I/O Bus appears to run at 72MHz and the GPIO bits
|
||||
// are split across 2x16 registers per bit. This limits 8bit read
|
||||
// speed to < 2MB/s, write speed slower due to select signal. Thus it
|
||||
// is not feasible to run a program in the host memory at full speed.
|
||||
// Virtual (Kernel) memory is used for all programs and host is only
|
||||
// accessed for specific reasons, such as the MZ-80A FDD Bios which
|
||||
// changes according to state of READY signal. I/O operations have to
|
||||
// use lookahead during fetch cycle to steal time in order to meet timings.
|
||||
// If SigmaStar make a newer SSD or an alternative becomes available which
|
||||
// has I/O bus running at 4x speed or has 32bit per cycle GPIO access then
|
||||
// the design needs to be upgraded to fulfill the idea of running programs
|
||||
// in host memory at full speed.
|
||||
// Feb 2023 - v1.2 Added MZ-80A Rom Filing System device driver. This allows the FusionX
|
||||
// hosted in an MZ-80A to run the original RFS Monitor and software.
|
||||
// Feb 2023 - v1.3 Added tranZPUter SW device driver. This allows the FusionX hosted
|
||||
// in any supported host to run TZFS and the updated applications
|
||||
// such as CP/M, SA-5510 Basic, MS-Basic etc. Adding this device driver
|
||||
// prepares the ground to add the SOM GPU as the Video emulation of
|
||||
// the Sharp machines.
|
||||
// Mar 2023 - v1.4 With the advent of the PCW-8XXX series, seperated distinct machine
|
||||
// configurations into device driver modules, which are only built
|
||||
// if same as the target machine. This then allows the z80 driver to be
|
||||
// a vanilla Z80 or customisations for hosts pulled in.
|
||||
// History: Oct 2022 - v1.0 Initial write of the z80 kernel driver software.
|
||||
// Jan 2023 - v1.1 Added MZ-2000/MZ-80A modes. There are serious limitations with the
|
||||
// SSD202 I/O. The I/O Bus appears to run at 72MHz and the GPIO bits
|
||||
// are split across 2x16 registers per bit. This limits 8bit read
|
||||
// speed to < 2MB/s, write speed slower due to select signal. Thus it
|
||||
// is not feasible to run a program in the host memory at full speed.
|
||||
// Virtual (Kernel) memory is used for all programs and host is only
|
||||
// accessed for specific reasons, such as the MZ-80A FDD Bios which
|
||||
// changes according to state of READY signal. I/O operations have to
|
||||
// use lookahead during fetch cycle to steal time in order to meet timings.
|
||||
// If SigmaStar make a newer SSD or an alternative becomes available which
|
||||
// has I/O bus running at 4x speed or has 32bit per cycle GPIO access then
|
||||
// the design needs to be upgraded to fulfill the idea of running programs
|
||||
// in host memory at full speed.
|
||||
// Feb 2023 - v1.2 Added MZ-80A Rom Filing System device driver. This allows the FusionX
|
||||
// hosted in an MZ-80A to run the original RFS Monitor and software.
|
||||
// Feb 2023 - v1.3 Added tranZPUter SW device driver. This allows the FusionX hosted
|
||||
// in any supported host to run TZFS and the updated applications
|
||||
// such as CP/M, SA-5510 Basic, MS-Basic etc. Adding this device driver
|
||||
// prepares the ground to add the SOM GPU as the Video emulation of
|
||||
// the Sharp machines.
|
||||
// Mar 2023 - v1.4 With the advent of the PCW-8XXX series, seperated distinct machine
|
||||
// configurations into device driver modules, which are only built
|
||||
// if same as the target machine. This then allows the z80 driver to be
|
||||
// a vanilla Z80 or customisations for hosts pulled in.
|
||||
// Apr 2023 - v1.4.1 Completed MZ2000 mode to work with arbiter and ttymz.
|
||||
// May 2023 - v1.5 Added MZ1500 modes.
|
||||
// Jul 2023 - v1.6 Updated MZ-700 code, adding sub-memory maps to increase page mapping
|
||||
// speed specifically to enable reliable tape read/write.
|
||||
//
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
@@ -117,12 +121,15 @@ static DEFINE_MUTEX(Z80DRV_MUTEX);
|
||||
#if(TARGET_HOST_MZ80A == 1)
|
||||
#include "z80vhw_mz80a.c"
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
#include "z80vhw_rfs.c"
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ700 == 1)
|
||||
#include "z80vhw_mz700.c"
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
#include "z80vhw_mz1500.c"
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
#include "z80vhw_mz2000.c"
|
||||
#endif
|
||||
@@ -161,13 +168,19 @@ static inline void decodeMemoryMapSetup(zuint16 address, zuint8 data, uint8_t io
|
||||
mz700DecodeMemoryMapSetup(address, data, ioFlag, readFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ1500)
|
||||
{
|
||||
mz1500DecodeMemoryMapSetup(address, data, ioFlag, readFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ2000)
|
||||
{
|
||||
mz2000DecodeMemoryMapSetup(address, data, ioFlag, readFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_RFS)
|
||||
{
|
||||
rfsDecodeMemoryMapSetup(address, data, ioFlag, readFlag);
|
||||
@@ -213,6 +226,12 @@ static inline zuint8 readVirtual(zuint16 address, uint8_t ioFlag)
|
||||
data = mz700Read(address, ioFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ1500)
|
||||
{
|
||||
data = mz1500Read(address, ioFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ2000)
|
||||
{
|
||||
@@ -226,7 +245,7 @@ static inline zuint8 readVirtual(zuint16 address, uint8_t ioFlag)
|
||||
} else
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
// RFS only has memory mapped registers.
|
||||
if((Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_RFS) && ioFlag == 0)
|
||||
{
|
||||
@@ -267,6 +286,12 @@ static inline void writeVirtual(zuint16 address, zuint8 data, uint8_t ioFlag)
|
||||
mz700Write(address, data, ioFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ1500)
|
||||
{
|
||||
mz1500Write(address, data, ioFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ2000)
|
||||
{
|
||||
@@ -280,7 +305,7 @@ static inline void writeVirtual(zuint16 address, zuint8 data, uint8_t ioFlag)
|
||||
} else
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
// RFS only has memory mapped registers.
|
||||
if((Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_RFS) && ioFlag == 0)
|
||||
{
|
||||
@@ -455,7 +480,11 @@ static zuint8 z80_read(void *context, zuint16 address)
|
||||
Z_UNUSED(context)
|
||||
|
||||
// Only read if the address is in physical RAM.
|
||||
#if(TARGET_HOST_PCW == 0)
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
// MZ-1500 take into account PCG being active, always go to hardware when active. Cannot use the map because
|
||||
// this can change during PCG active mode and must be reflected when PCG is deactivated.
|
||||
if(isPhysical(address) || (Z80Ctrl->pcgMode == 1 && address >= 0xD000))
|
||||
#elif(TARGET_HOST_PCW == 0)
|
||||
if(isPhysical(address))
|
||||
#else
|
||||
if(isPhysicalHW(address))
|
||||
@@ -526,6 +555,28 @@ static zuint8 z80_read(void *context, zuint16 address)
|
||||
Z80Ctrl->keyportTrigger = 0;
|
||||
}
|
||||
}
|
||||
#elif (TARGET_HOST_MZ1500 == 1)
|
||||
// Keyport data? Store.
|
||||
if(isHW(address) && address == 0xE001 && (Z80Ctrl->keyportStrobe & 0x0f) == 8)
|
||||
{
|
||||
Z80Ctrl->keyportShiftCtrl = (data & 0x40) == 0 ? 0x01 : 0x00;
|
||||
} else
|
||||
if(isHW(address) && address == 0xE001 && Z80Ctrl->keyportShiftCtrl == 1)
|
||||
{
|
||||
if((Z80Ctrl->keyportStrobe & 0x0f) == 5 && (data & 0xF0) != 0xF0)
|
||||
{
|
||||
Z80Ctrl->keyportHotKey = (data & 0x80) == 0 ? HOTKEY_ORIGINAL :
|
||||
(data & 0x40) == 0 ? HOTKEY_RFS40 :
|
||||
(data & 0x20) == 0 ? HOTKEY_TZFS :
|
||||
(data & 0x10) == 0 ? HOTKEY_LINUX : 0x00;
|
||||
Z80Ctrl->keyportTrigger = Z80Ctrl->keyportHotKey;
|
||||
} else
|
||||
{
|
||||
Z80Ctrl->keyportTrigger = 0;
|
||||
}
|
||||
}
|
||||
#elif (TARGET_HOST_MZ2000 == 1)
|
||||
|
||||
#endif
|
||||
|
||||
#if(DEBUG_ENABLED & 1)
|
||||
@@ -545,7 +596,7 @@ static void z80_write(void *context, zuint16 address, zuint8 data)
|
||||
// Locals.
|
||||
Z_UNUSED(context)
|
||||
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
// To detect Hotkey presses, we need to store the keyboard strobe data and on keydata read.
|
||||
if(isHW(address) && address == 0xE000)
|
||||
{
|
||||
@@ -560,8 +611,15 @@ static void z80_write(void *context, zuint16 address, zuint8 data)
|
||||
if(isPhysicalRAM(address))
|
||||
writeVirtualRAM(address, data);
|
||||
Z80Ctrl->ioReadAhead = 0;
|
||||
}
|
||||
else if(isPhysical(address))
|
||||
} else
|
||||
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
// MZ-1500 take into account PCG being active, always go to hardware when active. Cannot use the map because
|
||||
// this can change during PCG active mode and must be reflected when PCG is deactivated.
|
||||
if(isPhysical(address) || (Z80Ctrl->pcgMode == 1 && address >= 0xD000))
|
||||
#else
|
||||
if(isPhysical(address))
|
||||
#endif
|
||||
{
|
||||
// Commence cycle to write the data to real RAM.
|
||||
SPI_SEND_32(address, data << 8 | CPLD_CMD_WRITE_ADDR);
|
||||
@@ -807,6 +865,31 @@ static zuint8 z80_in(void *context, zuint16 port)
|
||||
// Finally ensure the data from the port is ready and retrieve it.
|
||||
while(CPLD_READY() == 0);
|
||||
value = z80io_PRL_Read();
|
||||
|
||||
#if (TARGET_HOST_MZ2000 == 1)
|
||||
// Keyport data? Store.
|
||||
if((port&0xff) == 0xEA)
|
||||
{
|
||||
// If this is the CTRL key row, check the CTRL key.
|
||||
if((Z80Ctrl->keyportStrobe & 0x1f) == 0x1b)
|
||||
{
|
||||
Z80Ctrl->keyportShiftCtrl = (value & 0x08) == 0 ? 0x01 : 0x00;
|
||||
if(Z80Ctrl->keyportShiftCtrl == 1)
|
||||
{
|
||||
Z80Ctrl->keyportTrigger = 0;
|
||||
}
|
||||
} else
|
||||
// If CTRL key is held and we scan the Function Key Row (not all keys mode), then action the pressed key.
|
||||
if(Z80Ctrl->keyportShiftCtrl == 1 && (Z80Ctrl->keyportStrobe & 0x1f) == 0x10 && (value&0x0f) != 0x0f)
|
||||
{
|
||||
Z80Ctrl->keyportHotKey = (value & 0x01) == 0 ? HOTKEY_ORIGINAL :
|
||||
// (value & 0x02) == 0 ? HOTKEY_RFS40 :
|
||||
// (value & 0x04) == 0 ? HOTKEY_TZFS :
|
||||
(value & 0x08) == 0 ? HOTKEY_LINUX : 0x00;
|
||||
Z80Ctrl->keyportTrigger = Z80Ctrl->keyportHotKey;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
// Virtual I/O Port.
|
||||
if(isVirtualIO(port))
|
||||
@@ -854,6 +937,14 @@ static void z80_out(void *context, zuint16 port, zuint8 value)
|
||||
// Decode address to action any host specific memory map changes.
|
||||
decodeMemoryMapSetup(port, value, 1, false);
|
||||
#endif
|
||||
|
||||
#if (TARGET_HOST_MZ2000 == 1)
|
||||
// To detect Hotkey presses, we need to store the keyboard strobe data and on keydata read.
|
||||
if((port&0xff) == 0xE8)
|
||||
{
|
||||
Z80Ctrl->keyportStrobe = value;
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
if(isVirtualIO(port))
|
||||
{
|
||||
@@ -1007,39 +1098,38 @@ int thread_z80(void * thread_nr)
|
||||
// Reset pressed?
|
||||
if(CPLD_RESET())
|
||||
{
|
||||
resetZ80();
|
||||
|
||||
// Wait for release before restarting CPU.
|
||||
while(CPLD_RESET());
|
||||
} else
|
||||
{
|
||||
// Update state to indicate request has been actioned.
|
||||
mutex_lock(&Z80RunModeMutex);
|
||||
if(Z80RunMode == Z80_STOP) Z80RunMode = Z80_STOPPED;
|
||||
if(Z80RunMode == Z80_PAUSE) Z80RunMode = Z80_PAUSED;
|
||||
if(Z80RunMode == Z80_CONTINUE) Z80RunMode = Z80_RUNNING;
|
||||
if(Z80RunMode == Z80_RUNNING) canRun=1; else canRun=0;
|
||||
mutex_unlock(&Z80RunModeMutex);
|
||||
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
// Hotkey pressed? Bring up user menu.
|
||||
if(Z80Ctrl->keyportTrigger != 0x00 && Z80Ctrl->keyportTriggerLast == 0)
|
||||
{
|
||||
z80menu();
|
||||
|
||||
// Send signal to arbiter to change run mode.
|
||||
sendSignal(Z80Ctrl->arbTask, SIGUSR1);
|
||||
Z80Ctrl->keyportShiftCtrl = 0;
|
||||
|
||||
// Suspend processing until arbiter sets up new environment.
|
||||
mutex_lock(&Z80RunModeMutex);
|
||||
Z80RunMode = Z80_STOPPED;
|
||||
canRun = 0;
|
||||
mutex_unlock(&Z80RunModeMutex);
|
||||
}
|
||||
Z80Ctrl->keyportTriggerLast = Z80Ctrl->keyportTrigger;
|
||||
#endif
|
||||
resetZ80();
|
||||
}
|
||||
|
||||
// Update state to indicate request has been actioned.
|
||||
mutex_lock(&Z80RunModeMutex);
|
||||
if(Z80RunMode == Z80_STOP) Z80RunMode = Z80_STOPPED;
|
||||
if(Z80RunMode == Z80_PAUSE) Z80RunMode = Z80_PAUSED;
|
||||
if(Z80RunMode == Z80_CONTINUE) Z80RunMode = Z80_RUNNING;
|
||||
if(Z80RunMode == Z80_RUNNING) canRun=1; else canRun=0;
|
||||
mutex_unlock(&Z80RunModeMutex);
|
||||
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1 || TARGET_HOST_MZ2000 == 1)
|
||||
// Hotkey pressed? Bring up user menu.
|
||||
if(Z80Ctrl->keyportTrigger != 0x00 && Z80Ctrl->keyportTriggerLast == 0)
|
||||
{
|
||||
z80menu();
|
||||
|
||||
// Send signal to arbiter to change run mode.
|
||||
sendSignal(Z80Ctrl->arbTask, SIGUSR1);
|
||||
Z80Ctrl->keyportShiftCtrl = 0;
|
||||
|
||||
// Suspend processing until arbiter sets up new environment.
|
||||
mutex_lock(&Z80RunModeMutex);
|
||||
Z80RunMode = Z80_STOPPED;
|
||||
canRun = 0;
|
||||
mutex_unlock(&Z80RunModeMutex);
|
||||
}
|
||||
Z80Ctrl->keyportTriggerLast = Z80Ctrl->keyportTrigger;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Release spinlock as we are unloading driver.
|
||||
@@ -1179,10 +1269,10 @@ static int z80drv_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
}
|
||||
// Another one, as the memory bank page maps are allocated dynamically, need to send a size which indicates which memory block to map. This is done by the size of a memory map
|
||||
// added to it the map slot as 0x1000 per slot.
|
||||
else if(size >= ((MEMORY_BLOCK_SLOTS*sizeof(uint32_t)) + 0x1000) && size < ((MEMORY_BLOCK_SLOTS*sizeof(uint32_t)) + (MEMORY_MODES * 0x1000)))
|
||||
else if(size >= ((MEMORY_BLOCK_SLOTS*sizeof(uint32_t)) + 0x1000) && size < ((MEMORY_BLOCK_SLOTS*sizeof(uint32_t)) + ((MEMORY_MODES+MEMORY_SUB_MODES) * 0x1000)))
|
||||
{
|
||||
// Loop through all the memory page slots, if active and the size is in range, then map the memory to user space.
|
||||
for(idx=0; idx < MEMORY_MODES; idx++)
|
||||
for(idx=0; idx < MEMORY_MODES+MEMORY_SUB_MODES; idx++)
|
||||
{
|
||||
if(size >= ((MEMORY_BLOCK_SLOTS*sizeof(uint32_t)) + ((idx+1)*0x1000)) && size < ((MEMORY_BLOCK_SLOTS*sizeof(uint32_t)) + ((idx+2) * 0x1000)))
|
||||
{
|
||||
@@ -1376,19 +1466,24 @@ void setupMemory(enum Z80_MEMORY_PROFILE mode)
|
||||
mz700SetupMemory(mode);
|
||||
else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ1500)
|
||||
mz1500SetupMemory(mode);
|
||||
else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ2000)
|
||||
mz2000SetupMemory(mode);
|
||||
else
|
||||
#endif
|
||||
// RFS board only works in an MZ-80A at present.
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
// RFS board only works on an MZ-80A/MZ-700/MZ-1500 at present.
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_RFS)
|
||||
rfsSetupMemory(mode);
|
||||
else
|
||||
#endif
|
||||
// tranZPUter operates in all supported Sharp machines.
|
||||
#if(TARGET_HOST_PCW == 0)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_TZPU)
|
||||
tzpuSetupMemory(mode);
|
||||
else
|
||||
@@ -1407,6 +1502,11 @@ void setupMemory(enum Z80_MEMORY_PROFILE mode)
|
||||
|
||||
// Inhibit mode disabled.
|
||||
Z80Ctrl->inhibitMode = 0;
|
||||
|
||||
#if defined(TARGET_HOST_MZ1500)
|
||||
// Flag to indicate PCG active, all memory accesses from D000:FFFF are sent to hardware.
|
||||
Z80Ctrl->pcgMode = 0;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1567,6 +1667,7 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
case 2:
|
||||
Z80Ctrl->cpuGovernorDelayROM = ROM_DELAY_X2;
|
||||
Z80Ctrl->cpuGovernorDelayRAM = RAM_DELAY_X2;
|
||||
pr_info("ROM:%d, RAM:%d\n", Z80Ctrl->cpuGovernorDelayROM, Z80Ctrl->cpuGovernorDelayRAM);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
@@ -1640,10 +1741,10 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
if(idx < Z80Ctrl->virtualDeviceCnt)
|
||||
break;
|
||||
|
||||
#if(TARGET_HOST_MZ80A == 0 && TARGET_HOST_MZ700 == 0)
|
||||
#if(TARGET_HOST_MZ80A == 0 && TARGET_HOST_MZ700 == 0 && TARGET_HOST_MZ1500 == 0)
|
||||
if(ioctlCmd.vdev.device & VIRTUAL_DEVICE_RFS)
|
||||
{
|
||||
pr_info("RFS Board currently supported on MZ-80A/MZ-700 Hosts only.\n");
|
||||
pr_info("RFS Board currently supported on MZ-80A/MZ-700/MZ-1500 Hosts only.\n");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -1665,7 +1766,7 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
case VIRTUAL_DEVICE_RFS40:
|
||||
case VIRTUAL_DEVICE_RFS80:
|
||||
Z80Ctrl->virtualDevice[Z80Ctrl->virtualDeviceCnt++] = ioctlCmd.vdev.device;
|
||||
@@ -1682,6 +1783,14 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
case VIRTUAL_DEVICE_MZ1500:
|
||||
Z80Ctrl->virtualDevice[Z80Ctrl->virtualDeviceCnt++] = ioctlCmd.vdev.device;
|
||||
Z80Ctrl->virtualDeviceBitMap |= ioctlCmd.vdev.device;
|
||||
mz1500Init(0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
case VIRTUAL_DEVICE_MZ2000:
|
||||
Z80Ctrl->virtualDevice[Z80Ctrl->virtualDeviceCnt++] = ioctlCmd.vdev.device;
|
||||
@@ -1756,7 +1865,7 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
case VIRTUAL_DEVICE_RFS40:
|
||||
case VIRTUAL_DEVICE_RFS80:
|
||||
Z80Ctrl->virtualDeviceBitMap &= ~ioctlCmd.vdev.device;
|
||||
@@ -1771,6 +1880,13 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
case VIRTUAL_DEVICE_MZ1500:
|
||||
Z80Ctrl->virtualDeviceBitMap &= ~ioctlCmd.vdev.device;
|
||||
mz1500Remove();
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
case VIRTUAL_DEVICE_MZ2000:
|
||||
Z80Ctrl->virtualDeviceBitMap &= ~ioctlCmd.vdev.device;
|
||||
@@ -1978,8 +2094,8 @@ static int __init ModuleInit(void)
|
||||
goto initExit;
|
||||
}
|
||||
// Default memory mode is 0, ie. Original. Additional modes may be used by drivers such as the tzpu driver.
|
||||
Z80Ctrl->memoryMode = 0;
|
||||
for(idx=0; idx < MEMORY_MODES; idx++)
|
||||
Z80Ctrl->memoryMode = 0;
|
||||
for(idx=0; idx < MEMORY_MODES+MEMORY_SUB_MODES; idx++)
|
||||
{
|
||||
(Z80Ctrl->page[idx]) = NULL;
|
||||
}
|
||||
@@ -2032,7 +2148,7 @@ static int __init ModuleInit(void)
|
||||
Z80Ctrl->ioReadAhead = 0;
|
||||
Z80Ctrl->ioWriteAhead = 0;
|
||||
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1 || TARGET_HOST_MZ2000 == 1)
|
||||
// Initialse hotkey detection variables.
|
||||
Z80Ctrl->keyportStrobe = 0x00;
|
||||
Z80Ctrl->keyportShiftCtrl = 0x00;
|
||||
@@ -2089,7 +2205,7 @@ static void __exit ModuleExit(void)
|
||||
}
|
||||
|
||||
// Return the memory used for the Z80 'virtual memory' and control variables.
|
||||
for(idx=0; idx < MEMORY_MODES; idx++)
|
||||
for(idx=0; idx < MEMORY_MODES+MEMORY_SUB_MODES; idx++)
|
||||
{
|
||||
if(Z80Ctrl->page[idx] != NULL)
|
||||
{
|
||||
|
||||
132
software/FusionX/src/z80drv/src/z80driver.h
vendored
132
software/FusionX/src/z80drv/src/z80driver.h
vendored
@@ -12,9 +12,13 @@
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
// (c) 1999-2023 Manuel Sainz de Baranda y Goñi
|
||||
//
|
||||
// History: Oct 2022 - v1.0 Initial write of the z80 kernel driver software.
|
||||
// Jan 2023 - v1.1 Added MZ-2000/MZ-80A modes.
|
||||
// Feb 2023 - v1.2 Added RFS virtual driver.
|
||||
// History: Oct 2022 - v1.0 Initial write of the z80 kernel driver software.
|
||||
// Jan 2023 - v1.1 Added MZ-2000/MZ-80A modes.
|
||||
// Feb 2023 - v1.2 Added RFS virtual driver.
|
||||
// Apr 2023 - v1.4.1 Completed MZ2000 mode to work with arbiter and ttymz.
|
||||
// May 2023 - v1.5 Added MZ1500 modes.
|
||||
// Jul 2023 - v1.6 Updated MZ-700 code, adding sub-memory maps to increase page mapping
|
||||
// speed specifically to enable reliable tape read/write.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -39,26 +43,37 @@
|
||||
#if defined(TARGET_HOST_MZ700)
|
||||
#define TARGET_HOST_MZ700 1
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ2000)
|
||||
#define TARGET_HOST_MZ2000 1
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ1500)
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ1500 1
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ80A)
|
||||
#define TARGET_HOST_MZ80A 1
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_PCW8XXX) || defined(TARGET_HOST_PCW9XXX)
|
||||
#define TARGET_HOST_PCW 1
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#else
|
||||
#define TARGET_HOST_MZ700 0 // Target compilation for an MZ700
|
||||
#define TARGET_HOST_MZ2000 0 // MZ2000
|
||||
#define TARGET_HOST_MZ1500 0 // MZ1500
|
||||
#define TARGET_HOST_MZ80A 0 // MZ80A
|
||||
#define TARGET_HOST_PCW 0 // Amstrad PCW8XXX/9XXX
|
||||
#endif
|
||||
@@ -67,8 +82,8 @@
|
||||
#define DRIVER_LICENSE "GPL"
|
||||
#define DRIVER_AUTHOR "Philip D Smart"
|
||||
#define DRIVER_DESCRIPTION "Z80 CPU Emulator and Hardware Interface Driver"
|
||||
#define DRIVER_VERSION "v1.4"
|
||||
#define DRIVER_VERSION_DATE "Apr 2023"
|
||||
#define DRIVER_VERSION "v1.6"
|
||||
#define DRIVER_VERSION_DATE "July 2023"
|
||||
#define DRIVER_COPYRIGHT "(C) 2018-2023"
|
||||
#define Z80_VIRTUAL_ROM_SIZE (65536 * 32) // Sized to maximum Kernel contiguous allocation size, 2M which is 4x512K ROMS.
|
||||
#define Z80_VIRTUAL_RAM_SIZE (65536 * 32) // Sized to maximum Kernel contiguous allocation size, 2M.
|
||||
@@ -99,11 +114,11 @@
|
||||
#define IO_TYPE_VIRTUAL_HW 0x40000000
|
||||
|
||||
// Hotkeys handled.
|
||||
#define HOTKEY_ORIGINAL 0xE8
|
||||
#define HOTKEY_RFS40 0xE9
|
||||
#define HOTKEY_RFS80 0xEA
|
||||
#define HOTKEY_TZFS 0xEB
|
||||
#define HOTKEY_LINUX 0xEC
|
||||
#define HOTKEY_ORIGINAL 0xE0
|
||||
#define HOTKEY_RFS40 0xE1
|
||||
#define HOTKEY_RFS80 0xE2
|
||||
#define HOTKEY_TZFS 0xE3
|
||||
#define HOTKEY_LINUX 0xE4
|
||||
|
||||
//*********************************************************************************************
|
||||
// Delay periods for the various hosts, which need adding to the primary opcode fetch in
|
||||
@@ -144,6 +159,82 @@
|
||||
#define INSTRUCTION_DELAY_RAM_224MHZ 4
|
||||
#define INSTRUCTION_DELAY_RAM_448MHZ 1
|
||||
#endif
|
||||
#if(DEBUG_ENABLED == 0)
|
||||
#define INSTRUCTION_DELAY_ROM_3_54MHZ 253
|
||||
#define INSTRUCTION_DELAY_ROM_7MHZ 126
|
||||
#define INSTRUCTION_DELAY_ROM_14MHZ 63
|
||||
#define INSTRUCTION_DELAY_ROM_28MHZ 32
|
||||
#define INSTRUCTION_DELAY_ROM_56MHZ 16
|
||||
#define INSTRUCTION_DELAY_ROM_112MHZ 8
|
||||
#define INSTRUCTION_DELAY_ROM_224MHZ 4
|
||||
#define INSTRUCTION_DELAY_ROM_448MHZ 1
|
||||
#define INSTRUCTION_DELAY_RAM_3_54MHZ 240
|
||||
#define INSTRUCTION_DELAY_RAM_7MHZ 120
|
||||
#define INSTRUCTION_DELAY_RAM_14MHZ 60
|
||||
#define INSTRUCTION_DELAY_RAM_28MHZ 30
|
||||
#define INSTRUCTION_DELAY_RAM_56MHZ 15
|
||||
#define INSTRUCTION_DELAY_RAM_112MHZ 8
|
||||
#define INSTRUCTION_DELAY_RAM_224MHZ 4
|
||||
#define INSTRUCTION_DELAY_RAM_448MHZ 1
|
||||
#endif
|
||||
#define INSTRUCTION_EQUIV_FREQ_3_54MHZ 3540000
|
||||
#define INSTRUCTION_EQUIV_FREQ_7MHZ 7000000
|
||||
#define INSTRUCTION_EQUIV_FREQ_14MHZ 14000000
|
||||
#define INSTRUCTION_EQUIV_FREQ_28MHZ 28000000
|
||||
#define INSTRUCTION_EQUIV_FREQ_56MHZ 56000000
|
||||
#define INSTRUCTION_EQUIV_FREQ_112MHZ 112000000
|
||||
#define INSTRUCTION_EQUIV_FREQ_224MHZ 224000000
|
||||
#define INSTRUCTION_EQUIV_FREQ_448MHZ 448000000
|
||||
#define INSTRUCTION_GOVERNOR_IO_SKIP 10
|
||||
|
||||
enum Z80_INSTRUCTION_DELAY {
|
||||
ROM_DELAY_NORMAL = INSTRUCTION_DELAY_ROM_3_54MHZ,
|
||||
ROM_DELAY_X2 = INSTRUCTION_DELAY_ROM_7MHZ,
|
||||
ROM_DELAY_X4 = INSTRUCTION_DELAY_ROM_14MHZ,
|
||||
ROM_DELAY_X8 = INSTRUCTION_DELAY_ROM_28MHZ,
|
||||
ROM_DELAY_X16 = INSTRUCTION_DELAY_ROM_56MHZ,
|
||||
ROM_DELAY_X32 = INSTRUCTION_DELAY_ROM_112MHZ,
|
||||
ROM_DELAY_X64 = INSTRUCTION_DELAY_ROM_224MHZ,
|
||||
ROM_DELAY_X128 = INSTRUCTION_DELAY_ROM_448MHZ,
|
||||
RAM_DELAY_NORMAL = INSTRUCTION_DELAY_RAM_3_54MHZ,
|
||||
RAM_DELAY_X2 = INSTRUCTION_DELAY_RAM_7MHZ,
|
||||
RAM_DELAY_X4 = INSTRUCTION_DELAY_RAM_14MHZ,
|
||||
RAM_DELAY_X8 = INSTRUCTION_DELAY_RAM_28MHZ,
|
||||
RAM_DELAY_X16 = INSTRUCTION_DELAY_RAM_56MHZ,
|
||||
RAM_DELAY_X32 = INSTRUCTION_DELAY_RAM_112MHZ,
|
||||
RAM_DELAY_X64 = INSTRUCTION_DELAY_RAM_224MHZ,
|
||||
RAM_DELAY_X128 = INSTRUCTION_DELAY_RAM_448MHZ,
|
||||
CPU_FREQUENCY_NORMAL = INSTRUCTION_EQUIV_FREQ_3_54MHZ,
|
||||
CPU_FREQUENCY_X2 = INSTRUCTION_EQUIV_FREQ_7MHZ,
|
||||
CPU_FREQUENCY_X4 = INSTRUCTION_EQUIV_FREQ_14MHZ,
|
||||
CPU_FREQUENCY_X8 = INSTRUCTION_EQUIV_FREQ_28MHZ,
|
||||
CPU_FREQUENCY_X16 = INSTRUCTION_EQUIV_FREQ_56MHZ,
|
||||
CPU_FREQUENCY_X32 = INSTRUCTION_EQUIV_FREQ_112MHZ,
|
||||
CPU_FREQUENCY_X64 = INSTRUCTION_EQUIV_FREQ_224MHZ,
|
||||
CPU_FREQUENCY_X128 = INSTRUCTION_EQUIV_FREQ_448MHZ,
|
||||
};
|
||||
#endif
|
||||
//
|
||||
// MZ-1500
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
#if(DEBUG_ENABLED > 0)
|
||||
#define INSTRUCTION_DELAY_ROM_3_54MHZ 253
|
||||
#define INSTRUCTION_DELAY_ROM_7MHZ 126
|
||||
#define INSTRUCTION_DELAY_ROM_14MHZ 63
|
||||
#define INSTRUCTION_DELAY_ROM_28MHZ 32
|
||||
#define INSTRUCTION_DELAY_ROM_56MHZ 16
|
||||
#define INSTRUCTION_DELAY_ROM_112MHZ 8
|
||||
#define INSTRUCTION_DELAY_ROM_224MHZ 4
|
||||
#define INSTRUCTION_DELAY_ROM_448MHZ 1
|
||||
#define INSTRUCTION_DELAY_RAM_3_54MHZ 253
|
||||
#define INSTRUCTION_DELAY_RAM_7MHZ 126
|
||||
#define INSTRUCTION_DELAY_RAM_14MHZ 63
|
||||
#define INSTRUCTION_DELAY_RAM_28MHZ 32
|
||||
#define INSTRUCTION_DELAY_RAM_56MHZ 16
|
||||
#define INSTRUCTION_DELAY_RAM_112MHZ 8
|
||||
#define INSTRUCTION_DELAY_RAM_224MHZ 4
|
||||
#define INSTRUCTION_DELAY_RAM_448MHZ 1
|
||||
#endif
|
||||
#if(DEBUG_ENABLED == 0)
|
||||
#define INSTRUCTION_DELAY_ROM_3_54MHZ 253
|
||||
#define INSTRUCTION_DELAY_ROM_7MHZ 126
|
||||
@@ -310,7 +401,7 @@ enum Z80_INSTRUCTION_DELAY {
|
||||
#define INSTRUCTION_DELAY_ROM_64MHZ 14
|
||||
#define INSTRUCTION_DELAY_ROM_128MHZ 7
|
||||
#define INSTRUCTION_DELAY_ROM_256MHZ 3
|
||||
#define INSTRUCTION_DELAY_RAM_2MHZ 425
|
||||
#define INSTRUCTION_DELAY_RAM_2MHZ 429
|
||||
#define INSTRUCTION_DELAY_RAM_4MHZ 210
|
||||
#define INSTRUCTION_DELAY_RAM_8MHZ 105
|
||||
#define INSTRUCTION_DELAY_RAM_16MHZ 52
|
||||
@@ -510,6 +601,7 @@ enum Z80_INSTRUCTION_DELAY {
|
||||
// The memory page arrays dont check for allocation due to speed, it is assumed a memory mode page has been allocated and defined prior to the memoryMode
|
||||
// variable being set to that page.
|
||||
#define MEMORY_MODES 32 // Maximum number of different memory modes.
|
||||
#define MEMORY_SUB_MODES 6 // Number of possible alternate memory maps for a given memory mode.
|
||||
#define MEMORY_PAGE_SIZE 0x10000 // Total size of directly addressable memory.
|
||||
#define MEMORY_BLOCK_GRANULARITY 0x1 // Any change update MEMORY_BLOCK_SHIFT and mask in MEMORY_BLOCK_MASK
|
||||
#define MEMORY_BLOCK_SHIFT 0
|
||||
@@ -573,12 +665,12 @@ enum Z80_INSTRUCTION_DELAY {
|
||||
}
|
||||
#define resetZ80() {\
|
||||
setupMemory(Z80Ctrl->defaultPageMode);\
|
||||
z80_instant_reset(&Z80CPU);\
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_TZPU)\
|
||||
{\
|
||||
Z80RunMode = Z80_STOPPED;\
|
||||
sendSignal(Z80Ctrl->ioTask, SIGUSR1); \
|
||||
udelay(2000);\
|
||||
}\
|
||||
z80_instant_reset(&Z80CPU);\
|
||||
}
|
||||
|
||||
#define IO_ADDR_E0 0xE0
|
||||
@@ -611,8 +703,9 @@ enum VIRTUAL_DEVICE {
|
||||
VIRTUAL_DEVICE_NONE = 0x00000000,
|
||||
VIRTUAL_DEVICE_MZ80A = 0x00000001,
|
||||
VIRTUAL_DEVICE_MZ700 = 0x00000002,
|
||||
VIRTUAL_DEVICE_MZ2000 = 0x00000004,
|
||||
VIRTUAL_DEVICE_PCW = 0x00000008,
|
||||
VIRTUAL_DEVICE_MZ1500 = 0x00000004,
|
||||
VIRTUAL_DEVICE_MZ2000 = 0x00000008,
|
||||
VIRTUAL_DEVICE_PCW = 0x00000010,
|
||||
VIRTUAL_DEVICE_RFS40 = 0x01000000,
|
||||
VIRTUAL_DEVICE_RFS80 = 0x02000000,
|
||||
VIRTUAL_DEVICE_RFS = 0x03000000,
|
||||
@@ -648,10 +741,10 @@ typedef struct {
|
||||
// 16bit Input Address -> map -> Pointer to 24bit memory address + type flag.
|
||||
// -> Pointer+<low bits of address> to 24bit memory address + type flag.
|
||||
//uint32_t page[MEMORY_BLOCK_SLOTS];
|
||||
uint32_t *page[MEMORY_MODES];
|
||||
uint32_t *page[MEMORY_MODES+MEMORY_SUB_MODES];
|
||||
uint32_t shadowPage[MEMORY_BLOCK_SLOTS]; // Shadow page is for manipulation and backup of an existing page.
|
||||
|
||||
// Current memory mode as used by active driver.
|
||||
// Current memory modes as used by an active driver.
|
||||
uint8_t memoryMode;
|
||||
|
||||
// I/O Page map.
|
||||
@@ -673,6 +766,11 @@ typedef struct {
|
||||
// blocks actions which arent allowed during inhibit.
|
||||
uint8_t inhibitMode;
|
||||
|
||||
#if defined(TARGET_HOST_MZ1500)
|
||||
// Flag to indicate PCG active, all memory accesses from D000:FFFF are sent to hardware.
|
||||
uint8_t pcgMode;
|
||||
#endif
|
||||
|
||||
// I/O lookahead flags - to overcome SSD202 io slowness.
|
||||
uint8_t ioReadAhead;
|
||||
uint8_t ioWriteAhead;
|
||||
|
||||
606
software/FusionX/src/z80drv/src/z80vhw_mz1500.c
Normal file
606
software/FusionX/src/z80drv/src/z80vhw_mz1500.c
Normal file
@@ -0,0 +1,606 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80vhw_mz1500.c
|
||||
// Created: May 2023
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 Virtual Hardware Driver - MZ-1500
|
||||
// This file contains the methods used to emulate the original Sharp MZ-1500 without
|
||||
// any additions, such as the RFS or TZFS boards.
|
||||
//
|
||||
// These drivers are intended to be instantiated inline to reduce overhead of a call
|
||||
// and as such, they are included like header files rather than C linked object files.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: May 2023 v1.0 - Initial write based on the MZ700 module.
|
||||
// Jul 2023 - v1.6 - Updated MZ-700 code, adding sub-memory maps to increase page mapping
|
||||
// speed specifically to enable reliable tape read/write. Code changes
|
||||
// reflected in MZ-1500 module. Addition of MZ-1R18 emulation.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 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/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/time.h>
|
||||
#include "z80io.h"
|
||||
|
||||
#include <gpio_table.h>
|
||||
#include <asm/io.h>
|
||||
#include <infinity2m/gpio.h>
|
||||
#include <infinity2m/registers.h>
|
||||
|
||||
// Device constants.
|
||||
#define RAM_BASE_ADDR 0x00000 // Base address of the 512K RAM.
|
||||
|
||||
// PCW control.
|
||||
typedef struct {
|
||||
uint8_t regCtrl; // Control register.
|
||||
uint8_t loDRAMen; // Lower bank 0000:0FFF DRAM enabled, else monitor.
|
||||
uint8_t hiDRAMen; // Higher bank D000:FFFF DRAM enabled, else memory mapped I/O.
|
||||
uint32_t *ramFileMem; // 64K RamFile memory.
|
||||
uint16_t ramFileAddr; // Address pointer of the MZ-1R18 64K Ram File Board memory.
|
||||
} t_MZ1500Ctrl;
|
||||
|
||||
// RFS Board control.
|
||||
static t_MZ1500Ctrl MZ1500Ctrl;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Method to setup the memory page config to reflect the PCW configuration.
|
||||
void mz1500SetupMemory(enum Z80_MEMORY_PROFILE mode)
|
||||
{
|
||||
// Locals.
|
||||
uint8_t subMode;
|
||||
uint32_t idx;
|
||||
|
||||
// Setup defaults.
|
||||
MZ1500Ctrl.regCtrl = 0x00;
|
||||
MZ1500Ctrl.loDRAMen = 0; // Default is monitor ROM is enabled.
|
||||
MZ1500Ctrl.hiDRAMen = 0; // Default is memory mapped I/O enabled.
|
||||
Z80Ctrl->inhibitMode = 0;
|
||||
|
||||
// Setup default mode according to run mode, ie. Physical run or Virtual run.
|
||||
//
|
||||
if(mode == USE_PHYSICAL_RAM)
|
||||
{
|
||||
// Initialise the page pointers and memory to use physical RAM.
|
||||
for(idx=0x0000; idx < MEMORY_PAGE_SIZE; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
if(idx >= 0 && idx < 0x1000)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_ROM, idx);
|
||||
}
|
||||
else if(idx >= 0x1000 && idx < 0xD000)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_RAM, idx);
|
||||
}
|
||||
else if(idx >= 0xD000 && idx < 0xE000)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx);
|
||||
}
|
||||
else if(idx >= 0xE000 && idx < 0xE800)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx);
|
||||
}
|
||||
else if(idx >= 0xE800 && idx < 0x10000)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_ROM, idx);
|
||||
} else
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_RAM, idx);
|
||||
}
|
||||
}
|
||||
for(idx=0x0000; idx < IO_PAGE_SIZE; idx++)
|
||||
{
|
||||
Z80Ctrl->iopage[idx] = idx | IO_TYPE_PHYSICAL_HW;
|
||||
}
|
||||
// Cancel refresh as using physical RAM for program automatically refreshes DRAM.
|
||||
Z80Ctrl->refreshDRAM = 0;
|
||||
}
|
||||
else if(mode == USE_VIRTUAL_RAM)
|
||||
{
|
||||
// Initialise the page pointers and memory to use virtual RAM.
|
||||
for(idx=0x0000; idx < MEMORY_PAGE_SIZE; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
if(idx >= 0 && idx < 0x1000)
|
||||
{
|
||||
setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
else if(idx >= 0x1000 && idx < 0xD000)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
else if(idx >= 0xD000 && idx < 0xE000)
|
||||
{
|
||||
setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_PHYSICAL_VRAM, idx);
|
||||
}
|
||||
else if(idx >= 0xE000 && idx < 0xE800)
|
||||
{
|
||||
setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_PHYSICAL_HW, idx);
|
||||
}
|
||||
else if(idx >= 0xE800 && idx < 0xF000)
|
||||
{
|
||||
setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
else if(idx >= 0xF000 && idx < 0x10000)
|
||||
{
|
||||
setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
}
|
||||
for(idx=0x0000; idx < IO_PAGE_SIZE; idx++)
|
||||
{
|
||||
if((idx&0x00ff) == 0xEA || (idx&0x00ff) == 0xEB)
|
||||
{
|
||||
Z80Ctrl->iopage[idx] = idx | IO_TYPE_VIRTUAL_HW;
|
||||
} else
|
||||
{
|
||||
Z80Ctrl->iopage[idx] = idx | IO_TYPE_PHYSICAL_HW;
|
||||
}
|
||||
}
|
||||
// Setup sub-memory pages to enable rapid switch according to memory bank commands.
|
||||
for(subMode=0; subMode < MEMORY_SUB_MODES; subMode++)
|
||||
{
|
||||
if(Z80Ctrl->page[MEMORY_MODES+subMode] == NULL)
|
||||
{
|
||||
#if(DEBUG_ENABLED & 0x01)
|
||||
if(Z80Ctrl->debug >=3) pr_info("Allocating memory sub page:%d\n", subMode);
|
||||
#endif
|
||||
(Z80Ctrl->page[MEMORY_MODES+subMode]) = (uint32_t *)kmalloc((MEMORY_BLOCK_SLOTS*sizeof(uint32_t)), GFP_KERNEL);
|
||||
if ((Z80Ctrl->page[MEMORY_MODES+subMode]) == NULL)
|
||||
{
|
||||
pr_info("z80drv: failed to allocate memory sub mapping page:%d memory!", subMode);
|
||||
}
|
||||
}
|
||||
|
||||
// Duplicate current mode into the sub page prior to setting up specific config.
|
||||
memcpy((uint8_t *)Z80Ctrl->page[MEMORY_MODES+subMode], (uint8_t *)Z80Ctrl->page[0], MEMORY_BLOCK_SLOTS*sizeof(uint32_t));
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + subMode;
|
||||
|
||||
// MZ1500 memory mode switches.
|
||||
//
|
||||
// MZ-1500
|
||||
// |0000:0FFF|1000:CFFF|D000:FFFF
|
||||
// ------------------------------
|
||||
// OUT 0xE0 = |DRAM |DRAM |<last>
|
||||
// OUT 0xE1 = |<last> |DRAM |DRAM
|
||||
// OUT 0xE2 = |MONITOR |DRAM |<last>
|
||||
// OUT 0xE3 = |<last> |DRAM |Memory Mapped I/O
|
||||
// OUT 0xE4 = |MONITOR |DRAM |Memory Mapped I/O
|
||||
// OUT 0xE5 = |<last> |DRAM |PCG Enable
|
||||
// OUT 0xE6 = |<last> |DRAM |PCG Disable
|
||||
//
|
||||
// Sub-memory page maps:
|
||||
//
|
||||
// LOW BANK HIGH BANK PAGE MAP
|
||||
// DRAM 0
|
||||
// DRAM MEMORY MAP 1
|
||||
// Inhibit 2
|
||||
// DRAM 3
|
||||
// MONITOR MEMORY MAP 4
|
||||
// Inhibit 5
|
||||
//
|
||||
if(subMode >= 0 && subMode < 3)
|
||||
{
|
||||
// Enable lower 4K block as DRAM
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
}
|
||||
if(subMode >= 3 && subMode < 6)
|
||||
{
|
||||
// Enable lower 4K block as Monitor ROM
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
}
|
||||
if(subMode == 0 || subMode == 3)
|
||||
{
|
||||
// Enable upper 12K block, including Video/Memory Mapped peripherals area, as DRAM.
|
||||
for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
// MZ-700 mode we only work in first 64K block.
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
}
|
||||
if(subMode == 1 || subMode == 4)
|
||||
{
|
||||
// Enable Video RAM and Memory mapped peripherals in upper 12K block.
|
||||
for(idx=0xD000; idx < 0xE000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx);
|
||||
}
|
||||
for(idx=0xE000; idx < 0xE800; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx);
|
||||
}
|
||||
for(idx=0xE800; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
}
|
||||
if(subMode == 2 || subMode == 5)
|
||||
{
|
||||
// Inhibit. Backup current page data in region 0xD000-0xFFFF and inhibit it.
|
||||
for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_INHIBIT, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 4;
|
||||
|
||||
// Enable refresh as using virtual RAM stops refresh of host DRAM.
|
||||
Z80Ctrl->refreshDRAM = 2;
|
||||
}
|
||||
|
||||
// Reset memory paging to default.
|
||||
SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR);
|
||||
|
||||
pr_info("MZ-1500 Memory Setup complete.\n");
|
||||
}
|
||||
|
||||
// Method to load a ROM image into the RAM memory.
|
||||
//
|
||||
uint8_t mz1500LoadROM(const char* romFileName, uint32_t loadAddr, uint32_t loadSize)
|
||||
{
|
||||
// Locals.
|
||||
uint8_t result = 0;
|
||||
long noBytes;
|
||||
struct file *fp;
|
||||
|
||||
fp = filp_open(romFileName, O_RDONLY, 0);
|
||||
if(IS_ERR(fp))
|
||||
{
|
||||
pr_info("Error opening ROM Image:%s\n:", romFileName);
|
||||
result = 1;
|
||||
} else
|
||||
{
|
||||
vfs_llseek(fp, 0, SEEK_SET);
|
||||
noBytes = kernel_read(fp, fp->f_pos, &Z80Ctrl->ram[loadAddr], loadSize);
|
||||
if(noBytes < loadSize)
|
||||
{
|
||||
pr_info("Short load, ROM Image:%s, bytes loaded:%08x\n:", romFileName, loadSize);
|
||||
}
|
||||
filp_close(fp,NULL);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Perform any setup operations, such as variable initialisation, to enable use of this module.
|
||||
void mz1500Init(uint8_t mode)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t idx;
|
||||
|
||||
// Reset memory paging to default.
|
||||
SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR);
|
||||
|
||||
#if(DEBUG_ENABLED & 0x01)
|
||||
if(Z80Ctrl->debug >=3) pr_info("Allocating MZ-1R18 memory\n");
|
||||
#endif
|
||||
// Allocate memory for the MZ-1R18 64K Ram File board.
|
||||
MZ1500Ctrl.ramFileMem = (uint32_t *)kmalloc((65536 * sizeof(uint8_t)), GFP_KERNEL);
|
||||
if(MZ1500Ctrl.ramFileMem == NULL)
|
||||
{
|
||||
pr_info("z80drv: failed to allocate MZ-1R18 Ram File memory!");
|
||||
}
|
||||
MZ1500Ctrl.ramFileAddr = 0x0000;
|
||||
|
||||
// Initialise the virtual RAM from the HOST DRAM. This is to maintain compatibility as some applications (in my experience) have
|
||||
// bugs, which Im putting down to not initialising variables. The host DRAM is in a pattern of 0x00..0x00, 0xFF..0xFF repeating
|
||||
// when first powered on.
|
||||
pr_info("Sync Host RAM to virtual RAM.\n");
|
||||
for(idx=0; idx < Z80_VIRTUAL_RAM_SIZE; idx++)
|
||||
{
|
||||
if(idx >= 0x1000 && idx < 0xD000)
|
||||
{
|
||||
SPI_SEND32((uint32_t)idx << 16 | CPLD_CMD_READ_ADDR);
|
||||
while(CPLD_READY() == 0);
|
||||
Z80Ctrl->ram[idx] = z80io_PRL_Read8(1);
|
||||
} else
|
||||
{
|
||||
Z80Ctrl->ram[idx] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
// Original mode, ie. no virtual devices active, copy the host BIOS into the Virtual ROM and initialise remainder of ROM memory
|
||||
// such that the host behaves as per original spec.
|
||||
pr_info("Sync Host BIOS to virtual ROM.\n");
|
||||
for(idx=0; idx < Z80_VIRTUAL_ROM_SIZE; idx++)
|
||||
{
|
||||
// Copy BIOS and any add-on ROMS.
|
||||
if((idx >= 0x0000 && idx < 0x1000) || (idx >= 0xE800 && idx < 0x10000))
|
||||
{
|
||||
SPI_SEND32((uint32_t)idx << 16 | CPLD_CMD_READ_ADDR);
|
||||
while(CPLD_READY() == 0);
|
||||
Z80Ctrl->rom[idx] = z80io_PRL_Read8(1);
|
||||
} else
|
||||
{
|
||||
Z80Ctrl->rom[idx] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
// Initial memory config.
|
||||
mz1500SetupMemory(Z80Ctrl->defaultPageMode);
|
||||
|
||||
pr_info("Enabling MZ-1500 driver.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Perform any de-initialisation when the driver is removed.
|
||||
void mz1500Remove(void)
|
||||
{
|
||||
pr_info("Removing MZ-1500 driver.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Method to decode an address and make any system memory map changes as required.
|
||||
//
|
||||
static inline void mz1500DecodeMemoryMapSetup(zuint16 address, zuint8 data, uint8_t ioFlag, uint8_t readFlag)
|
||||
{
|
||||
// Locals.
|
||||
//uint32_t idx;
|
||||
|
||||
// Decoding memory address or I/O address?
|
||||
if(ioFlag == 0)
|
||||
{
|
||||
#if(DEBUG_ENABLED & 1)
|
||||
if(Z80Ctrl->debug >= 3)
|
||||
{
|
||||
pr_info("MEM:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag);
|
||||
}
|
||||
#endif
|
||||
// Certain machines have memory mapped I/O, these need to be handled in-situ as some reads may change the memory map.
|
||||
// These updates are made whilst waiting for the CPLD to retrieve the requested byte.
|
||||
//
|
||||
// 0000 - 0FFF : MZ80K/A/700 = Monitor ROM or RAM (MZ80A rom swap)
|
||||
// 1000 - CFFF : MZ80K/A/700 = RAM
|
||||
// C000 - CFFF : MZ80A = Monitor ROM (MZ80A rom swap)
|
||||
// D000 - D7FF : MZ80K/A/700 = VRAM
|
||||
// D800 - DFFF : MZ1500 = Colour VRAM (MZ1500)
|
||||
// E000 - E003 : MZ80K/A/700 = 8255
|
||||
// E004 - E007 : MZ80K/A/700 = 8254
|
||||
// E008 - E00B : MZ80K/A/700 = LS367
|
||||
// E00C - E00F : MZ80A = Memory Swap (MZ80A)
|
||||
// E010 - E013 : MZ80A = Reset Memory Swap (MZ80A)
|
||||
// E014 : MZ80A/700 = Normat CRT display
|
||||
// E015 : MZ80A/700 = Reverse CRT display
|
||||
// E200 - E2FF : MZ80A/700 = VRAM roll up/roll down.
|
||||
// E800 - EFFF : MZ80K/A/700 = User ROM socket or DD Eprom (MZ1500)
|
||||
// F000 - F7FF : MZ80K/A/700 = Floppy Disk interface.
|
||||
// F800 - FFFF : MZ80K/A/700 = Floppy Disk interface.
|
||||
switch(address)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
#if(DEBUG_ENABLED & 1)
|
||||
if(Z80Ctrl->debug >= 3)
|
||||
{
|
||||
pr_info("IO:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check to see if the memory mode page has been allocated for requested mode, if it hasnt, we need to allocate and then define.
|
||||
if(((address&0xFF) - 0xE0) >= 0 && ((address&0xFF) - 0xE0) < 7)
|
||||
{
|
||||
// MZ1500 memory mode switch.
|
||||
//
|
||||
// MZ-1500
|
||||
// |0000:0FFF|1000:CFFF|D000:FFFF
|
||||
// ------------------------------
|
||||
// OUT 0xE0 = |DRAM |DRAM |<last>
|
||||
// OUT 0xE1 = |<last> |DRAM |DRAM
|
||||
// OUT 0xE2 = |MONITOR |DRAM |<last>
|
||||
// OUT 0xE3 = |<last> |DRAM |Memory Mapped I/O
|
||||
// OUT 0xE4 = |MONITOR |DRAM |Memory Mapped I/O
|
||||
// OUT 0xE5 = |<last> |DRAM |PCG Enable
|
||||
// OUT 0xE6 = |<last> |DRAM |PCG Disable
|
||||
//
|
||||
// Sub-memory page maps:
|
||||
//
|
||||
// LOW BANK HIGH BANK PAGE MAP
|
||||
// DRAM 0
|
||||
// DRAM MEMORY MAP 1
|
||||
// Inhibit 2
|
||||
// DRAM 3
|
||||
// MONITOR MEMORY MAP 4
|
||||
// Inhibit 5
|
||||
//
|
||||
// Determine if this is a memory management port and update the memory page if required.
|
||||
switch(address & 0x00FF)
|
||||
{
|
||||
case IO_ADDR_E0:
|
||||
MZ1500Ctrl.loDRAMen = 1;
|
||||
break;
|
||||
|
||||
case IO_ADDR_E1:
|
||||
MZ1500Ctrl.hiDRAMen = 1;
|
||||
break;
|
||||
|
||||
case IO_ADDR_E2:
|
||||
MZ1500Ctrl.loDRAMen = 0;
|
||||
break;
|
||||
|
||||
case IO_ADDR_E3:
|
||||
MZ1500Ctrl.hiDRAMen = 0;
|
||||
break;
|
||||
|
||||
case IO_ADDR_E4:
|
||||
MZ1500Ctrl.loDRAMen = 0;
|
||||
MZ1500Ctrl.hiDRAMen = 0;
|
||||
Z80Ctrl->inhibitMode = 0;
|
||||
Z80Ctrl->pcgMode = 0;
|
||||
break;
|
||||
|
||||
// PCG Bank Switching.
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// 0 0 - CGROM
|
||||
// 0 1 - PCG Blue Plane
|
||||
// 1 0 - PCG Red Plane
|
||||
// 1 1 - PCG Green Plane
|
||||
case IO_ADDR_E5:
|
||||
// Any PCG access goes to hardware, set flag and access occurs in primary read/write routines.
|
||||
Z80Ctrl->pcgMode = 1;
|
||||
break;
|
||||
|
||||
// Disable PCG Bank Switching.
|
||||
case IO_ADDR_E6:
|
||||
// Disable PCG mode.
|
||||
Z80Ctrl->pcgMode = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Setup memory mode based on flag state.
|
||||
if(Z80Ctrl->inhibitMode)
|
||||
{
|
||||
if(MZ1500Ctrl.loDRAMen)
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 2;
|
||||
else
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 5;
|
||||
} else
|
||||
if(MZ1500Ctrl.loDRAMen)
|
||||
{
|
||||
if(MZ1500Ctrl.hiDRAMen && !Z80Ctrl->pcgMode)
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 0;
|
||||
else
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 1;
|
||||
} else
|
||||
{
|
||||
if(MZ1500Ctrl.hiDRAMen && !Z80Ctrl->pcgMode)
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 3;
|
||||
else
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 4;
|
||||
}
|
||||
Z80Ctrl->governorSkip = 0;
|
||||
} else
|
||||
if((address&0xff) >= 0xD8 && (address&0xff) < 0xDF)
|
||||
{
|
||||
// Do nothing for the Disk interface.
|
||||
} else
|
||||
if((address&0xff) >= 0xF4 && (address&0xff) < 0xF8)
|
||||
{
|
||||
Z80Ctrl->governorSkip = 0;
|
||||
} else
|
||||
{
|
||||
// Z80Ctrl->governorSkip = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method to read from either the memory mapped registers if enabled else the RAM.
|
||||
static inline uint8_t mz1500Read(zuint16 address, uint8_t ioFlag)
|
||||
{
|
||||
// Locals.
|
||||
uint8_t data = 0xFF;
|
||||
|
||||
// I/O Operation?
|
||||
if(ioFlag)
|
||||
{
|
||||
switch((address&0xff))
|
||||
{
|
||||
// MZ-1R18 Ram File Data Register.
|
||||
case 0xEA:
|
||||
data = MZ1500Ctrl.ramFileMem[MZ1500Ctrl.ramFileAddr];
|
||||
MZ1500Ctrl.ramFileAddr++;
|
||||
break;
|
||||
|
||||
// MZ-1R18 Ram File Control Register.
|
||||
case 0xEB:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
switch(address)
|
||||
{
|
||||
default:
|
||||
if(isVirtualMemory(address))
|
||||
{
|
||||
// Retrieve data from virtual memory.
|
||||
data = isVirtualROM(address) ? readVirtualROM(address) : readVirtualRAM(address);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(data);
|
||||
}
|
||||
|
||||
// Method to handle writes.
|
||||
static inline void mz1500Write(zuint16 address, zuint8 data, uint8_t ioFlag)
|
||||
{
|
||||
// Locals.
|
||||
// uint32_t idx;
|
||||
|
||||
// I/O Operation?
|
||||
if(ioFlag)
|
||||
{
|
||||
switch((address&0xff))
|
||||
{
|
||||
// MZ-1R18 Ram File Data Register.
|
||||
case 0xEA:
|
||||
MZ1500Ctrl.ramFileMem[MZ1500Ctrl.ramFileAddr] = data;
|
||||
MZ1500Ctrl.ramFileAddr++;
|
||||
break;
|
||||
|
||||
// MZ-1R18 Ram File Control Register.
|
||||
case 0xEB:
|
||||
MZ1500Ctrl.ramFileAddr = (address & 0xff00) | data;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
switch(address)
|
||||
{
|
||||
default:
|
||||
if(isVirtualRAM(address))
|
||||
{
|
||||
// Update virtual memory.
|
||||
writeVirtualRAM(address, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -51,16 +51,50 @@
|
||||
#include <infinity2m/gpio.h>
|
||||
#include <infinity2m/registers.h>
|
||||
|
||||
#include "tzpu.h"
|
||||
|
||||
// Device constants.
|
||||
#define RAM_BASE_ADDR 0x00000 // Base address of the 512K RAM.
|
||||
|
||||
// System ROM's, either use the host machine ROM or preload a ROM image.
|
||||
#define ROM_DIR "/apps/FusionX/host/MZ-2000/ROMS/"
|
||||
#define ROM_IPL_ORIG_FILENAME ROM_DIR "mz2000_ipl.orig"
|
||||
#define ROM_IPL_ORIG_FILENAME ROM_DIR "mz2000_ipl_original.rom"
|
||||
#define ROM_IPL_FUSIONX_FILENAME ROM_DIR "mz2000_ipl_fusionx.rom"
|
||||
#define ROM_IPL_TZPU_FILENAME ROM_DIR "mz2000_ipl_tzpu.rom"
|
||||
#define ROM_1Z001M_FILENAME ROM_DIR "1Z001M.rom"
|
||||
|
||||
// Boot ROM rom load and size definitions.
|
||||
#define ROM_BOOT_LOAD_ADDR 0x000000
|
||||
#define ROM_BOOT_SIZE 0x800
|
||||
#define ROM_1Z001M_LOAD_ADDR 0x000000
|
||||
#define ROM_ORIG_BOOT_SIZE 0x800
|
||||
#define ROM_TZPU_BOOT_SIZE 0x1000
|
||||
#define ROM_FUSIONX_BOOT_SIZE 0x1000
|
||||
#define ROM_1Z001M_BOOT_SIZE 0x10FB
|
||||
|
||||
// Sharp MZ-2000 constants.
|
||||
#define MBADDR_FDC 0x0D8 // MB8866 IO Region 0D8h - 0DBh
|
||||
#define MBADDR_FDC_CR MBADDR_FDC + 0x00 // Command Register
|
||||
#define MBADDR_FDC_STR MBADDR_FDC + 0x00 // Status Register
|
||||
#define MBADDR_FDC_TR MBADDR_FDC + 0x01 // Track Register
|
||||
#define MBADDR_FDC_SCR MBADDR_FDC + 0x02 // Sector Register
|
||||
#define MBADDR_FDC_DR MBADDR_FDC + 0x03 // Data Register
|
||||
#define MBADDR_FDC_MOTOR MBADDR_FDC + 0x04 // 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)
|
||||
#define MBADDR_FDC_SIDE MBADDR_FDC + 0x05 // Side select, Bit 0 when set = SIDE SELECT LOW,
|
||||
#define MBADDR_FDC_DDEN MBADDR_FDC + 0x06 // Double density enable, 0 = double density, 1 = single density disks.
|
||||
#define MBADDR_PPIA 0x0E0 // 8255 Port A
|
||||
#define MBADDR_PPIB 0x0E1 // 8255 Port B
|
||||
#define MBADDR_PPIC 0x0E2 // 8255 Port C
|
||||
#define MBADDR_PPICTL 0x0E3 // 8255 Control Port
|
||||
#define MBADDR_PIOA 0x0E8 // Z80 PIO Port A
|
||||
#define MBADDR_PIOCTLA 0x0E9 // Z80 PIO Port A Control Port
|
||||
#define MBADDR_PIOB 0x0EA // Z80 PIO Port B
|
||||
#define MBADDR_PIOCTLB 0x0EB // Z80 PIO Port B Control Port
|
||||
#define MBADDR_CRTBKCOLR 0x0F4 // Configure external CRT background colour.
|
||||
#define MBADDR_CRTGRPHPRIO 0x0F5 // Graphics priority register, character or a graphics colour has front display priority.
|
||||
#define MBADDR_CRTGRPHSEL 0x0F6 // Graphics output select on CRT or external CRT
|
||||
#define MBADDR_GRAMCOLRSEL 0x0F7 // Graphics RAM colour bank select.
|
||||
#define MBADDR_GRAMADDRL 0x0C000 // Graphics RAM base address.
|
||||
|
||||
// PCW control.
|
||||
typedef struct {
|
||||
@@ -84,9 +118,6 @@ void mz2000SetupMemory(enum Z80_MEMORY_PROFILE mode)
|
||||
// Locals.
|
||||
uint32_t idx;
|
||||
|
||||
// The PCW contains upto 512KB of standard RAM which can be expnded to a physical max of 2MB. The kernel malloc limit is 2MB so the whole virtual
|
||||
// memory can be mapped into the PCW memory address range.
|
||||
|
||||
// Setup defaults.
|
||||
MZ2000Ctrl.lowMemorySwap = 0x01; // Set memory swap flag to swapped, ie. IPL mode sees DRAM 0x0000:0x7FFF swapped to 0x8000:0xFFFF and ROM pages into 0x0000.
|
||||
MZ2000Ctrl.highMemoryVRAM = 0x00;
|
||||
@@ -148,12 +179,22 @@ void mz2000SetupMemory(enum Z80_MEMORY_PROFILE mode)
|
||||
Z80Ctrl->refreshDRAM = 2;
|
||||
}
|
||||
|
||||
// tranZPUter I/O Ports need to be declared virtual to process locally.
|
||||
for(idx=0x0000; idx < IO_PAGE_SIZE; idx+=0x0100)
|
||||
{
|
||||
Z80Ctrl->iopage[idx+IO_TZ_SVCREQ] = IO_TZ_SVCREQ | IO_TYPE_VIRTUAL_HW;
|
||||
Z80Ctrl->iopage[idx+IO_TZ_SYSREQ] = IO_TZ_SYSREQ | IO_TYPE_VIRTUAL_HW;
|
||||
}
|
||||
|
||||
// Ensure 40 char mode is enabled.
|
||||
// SPI_SEND_32(MBADDR_PIOA, 0x13);
|
||||
|
||||
pr_info("MZ-2000 Memory Setup complete.\n");
|
||||
}
|
||||
|
||||
// Method to load a ROM image into the RAM memory.
|
||||
//
|
||||
uint8_t mz2000LoadROM(const char* romFileName, uint32_t loadAddr, uint32_t loadSize)
|
||||
uint8_t mz2000LoadROM(const char* romFileName, uint8_t useROM, uint32_t loadAddr, uint32_t loadSize)
|
||||
{
|
||||
// Locals.
|
||||
uint8_t result = 0;
|
||||
@@ -168,10 +209,10 @@ uint8_t mz2000LoadROM(const char* romFileName, uint32_t loadAddr, uint32_t loadS
|
||||
} else
|
||||
{
|
||||
vfs_llseek(fp, 0, SEEK_SET);
|
||||
noBytes = kernel_read(fp, fp->f_pos, &Z80Ctrl->ram[loadAddr], loadSize);
|
||||
noBytes = kernel_read(fp, fp->f_pos, useROM == 1 ? &Z80Ctrl->rom[loadAddr] : &Z80Ctrl->ram[loadAddr], loadSize);
|
||||
if(noBytes < loadSize)
|
||||
{
|
||||
pr_info("Short load, ROM Image:%s, bytes loaded:%08x\n:", romFileName, loadSize);
|
||||
pr_info("Short load, Image:%s, bytes loaded:%08x\n:", romFileName, loadSize);
|
||||
}
|
||||
filp_close(fp,NULL);
|
||||
}
|
||||
@@ -185,6 +226,35 @@ void mz2000Init(uint8_t mode)
|
||||
// Locals.
|
||||
uint32_t idx;
|
||||
|
||||
// // Initialise the Z80 PIO/8255 controllers.
|
||||
// //
|
||||
// SPI_SEND_32(MBADDR_PPICTL, 0x82); // 8255 A=OUT B=IN C=OUT
|
||||
// SPI_SEND_32(MBADDR_PPIC, 0x58); // BST=1 NST=0 OPEN=1 WRITE=1
|
||||
// SPI_SEND_32(MBADDR_PPIA, 0xF7); // All signals inactive, stop cassette.
|
||||
// SPI_SEND_32(MBADDR_PIOCTLA, 0x0F); // Setup PIO A
|
||||
// SPI_SEND_32(MBADDR_PIOCTLB, 0xCF); // Setup PIO B
|
||||
// SPI_SEND_32(MBADDR_PIOCTLB, 0xFF);
|
||||
//
|
||||
// // Initialise video hardware.
|
||||
// //
|
||||
// SPI_SEND_32(MBADDR_CRTGRPHSEL, 0x00); // Set Graphics VRAM to default, no access to GRAM.
|
||||
// SPI_SEND_32(MBADDR_CRTBKCOLR, 0x00); // Set background colour on external output to black.
|
||||
// SPI_SEND_32(MBADDR_GRAMCOLRSEL, 0x01); // Activate Blue graphics RAM bank for graphics operations (this is the default installed bank, red and green are optional).
|
||||
// SPI_SEND_32(MBADDR_CRTGRPHPRIO, 0x07); // Enable all colour bank graphic output with character priority.
|
||||
// SPI_SEND_32(MBADDR_PIOA, 0x13); // A7 : H 0xD000:0xD7FF or 0xC000:0xFFFF VRAN paged in.
|
||||
// // A6 : H Select Character VRAM (H) or Graphics VRAM (L)
|
||||
// // A5 : H Select 80 char mode, 40 char mode = L
|
||||
// // A4 : L Select all key strobe lines active, for detection of any key press.
|
||||
// // A3-A0: Keyboard strobe lines
|
||||
// SPI_SEND_32(MBADDR_PPIA, 0xFF); // A7 : L APSS Search for next program
|
||||
// // A6 : L Automatic playback at end of rewind
|
||||
// // A5 : L Automatic rewind during playback(recording)
|
||||
// // A4 : L Invert Video
|
||||
// // A3 : L Stop Cassette
|
||||
// // A2 : L Play Cassette
|
||||
// // A1 : L Fast Forward
|
||||
// // A0 : L Rewind
|
||||
|
||||
// Initialise the virtual RAM from the HOST DRAM. This is to maintain compatibility as some applications (in my experience) have
|
||||
// bugs, which Im putting down to not initialising variables. The host DRAM is in a pattern of 0x00..0x00, 0xFF..0xFF repeating
|
||||
// when first powered on.
|
||||
@@ -226,8 +296,11 @@ void mz2000Init(uint8_t mode)
|
||||
|
||||
// Initial memory config.
|
||||
mz2000SetupMemory(Z80Ctrl->defaultPageMode);
|
||||
|
||||
// mz2000LoadROM(ROM_IPL_ORIG_FILENAME, ROM_BOOT_LOAD_ADDR, ROM_BOOT_SIZE);
|
||||
|
||||
// Overwrite the ROM with a modified version (comment out) if needed.
|
||||
//mz2000LoadROM(ROM_IPL_ORIG_FILENAME, ROM_BOOT_LOAD_ADDR, ROM_ORIG_BOOT_SIZE);
|
||||
//mz2000LoadROM(ROM_IPL_TZPU_FILENAME, ROM_BOOT_LOAD_ADDR, ROM_TZPU_BOOT_SIZE);
|
||||
mz2000LoadROM(ROM_IPL_FUSIONX_FILENAME, 1, ROM_BOOT_LOAD_ADDR, ROM_FUSIONX_BOOT_SIZE);
|
||||
|
||||
pr_info("Enabling MZ-2000 driver.\n");
|
||||
return;
|
||||
@@ -299,6 +372,7 @@ static inline void mz2000DecodeMemoryMapSetup(zuint16 address, zuint8 data, uint
|
||||
// NST pages in all RAM and resets cpu.
|
||||
if(data & 0x01)
|
||||
{
|
||||
pr_info("NST Reset\n");
|
||||
MZ2000Ctrl.lowMemorySwap = 0;
|
||||
for(idx=0x0000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
@@ -320,6 +394,7 @@ static inline void mz2000DecodeMemoryMapSetup(zuint16 address, zuint8 data, uint
|
||||
// If IPL is active (L), reconfigure memory for power on state.
|
||||
if((data & 0x01) == 0)
|
||||
{
|
||||
pr_info("IPL Reset\n");
|
||||
mz2000SetupMemory(Z80Ctrl->defaultPageMode);
|
||||
}
|
||||
break;
|
||||
@@ -415,9 +490,28 @@ static inline void mz2000Write(zuint16 address, zuint8 data, uint8_t ioFlag)
|
||||
// I/O Operation?
|
||||
if(ioFlag)
|
||||
{
|
||||
switch(address)
|
||||
// Only the lower 8 bits of the I/O address are processed as the upper byte is not used in the Sharp models.
|
||||
//
|
||||
switch(address & 0x00FF)
|
||||
{
|
||||
case IO_TZ_SVCREQ:
|
||||
#if(DEBUG_ENABLED & 0x01)
|
||||
if(Z80Ctrl->debug >= 3) pr_info("SVCREQ:%02x\n", data);
|
||||
#endif
|
||||
|
||||
// If a k64f process has registered, send it a service request signal.
|
||||
pr_info("Sending signal,%02x\n", data);
|
||||
sendSignal(Z80Ctrl->ioTask, SIGIO);
|
||||
break;
|
||||
|
||||
case IO_TZ_SYSREQ:
|
||||
#if(DEBUG_ENABLED & 0x01)
|
||||
if(Z80Ctrl->debug >= 3) pr_info("SYSREQ:%02x\n", data);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_info("PORT:%02x\n", data);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
|
||||
@@ -12,8 +12,11 @@
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Mar 2023 v1.0 - Initial write based on the RFS hardware module.
|
||||
// Apr 2023 v1.1 - Updates from the PCW/MZ2000 changes.
|
||||
// History: Mar 2023 - v1.0 - Initial write based on the RFS hardware module.
|
||||
// Apr 2023 - v1.1 - Updates from the PCW/MZ2000 changes.
|
||||
// Jul 2023 - v1.6 - Updated MZ-700 code, adding sub-memory maps to increase page mapping
|
||||
// speed specifically to enable reliable tape read/write. Addition of
|
||||
// MZ-1R18 emulation.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -58,6 +61,10 @@
|
||||
// PCW control.
|
||||
typedef struct {
|
||||
uint8_t regCtrl; // Control register.
|
||||
uint8_t loDRAMen; // Lower bank 0000:0FFF DRAM enabled, else monitor.
|
||||
uint8_t hiDRAMen; // Higher bank D000:FFFF DRAM enabled, else memory mapped I/O.
|
||||
uint32_t *ramFileMem; // 64K RamFile memory.
|
||||
uint16_t ramFileAddr; // Address pointer of the MZ-1R18 64K Ram File Board memory.
|
||||
} t_MZ700Ctrl;
|
||||
|
||||
// RFS Board control.
|
||||
@@ -72,13 +79,14 @@ static t_MZ700Ctrl MZ700Ctrl;
|
||||
void mz700SetupMemory(enum Z80_MEMORY_PROFILE mode)
|
||||
{
|
||||
// Locals.
|
||||
uint8_t subMode;
|
||||
uint32_t idx;
|
||||
|
||||
// The PCW contains upto 512KB of standard RAM which can be expnded to a physical max of 2MB. The kernel malloc limit is 2MB so the whole virtual
|
||||
// memory can be mapped into the PCW memory address range.
|
||||
|
||||
// Setup defaults.
|
||||
MZ700Ctrl.regCtrl = 0x00;
|
||||
MZ700Ctrl.regCtrl = 0x00;
|
||||
MZ700Ctrl.loDRAMen = 0; // Default is monitor ROM is enabled.
|
||||
MZ700Ctrl.hiDRAMen = 0; // Default is memory mapped I/O enabled.
|
||||
Z80Ctrl->inhibitMode = 0;
|
||||
|
||||
// Setup default mode according to run mode, ie. Physical run or Virtual run.
|
||||
//
|
||||
@@ -150,8 +158,108 @@ void mz700SetupMemory(enum Z80_MEMORY_PROFILE mode)
|
||||
}
|
||||
for(idx=0x0000; idx < IO_PAGE_SIZE; idx++)
|
||||
{
|
||||
Z80Ctrl->iopage[idx] = idx | IO_TYPE_PHYSICAL_HW;
|
||||
if((idx&0x00ff) == 0xEA || (idx&0x00ff) == 0xEB)
|
||||
{
|
||||
Z80Ctrl->iopage[idx] = idx | IO_TYPE_VIRTUAL_HW;
|
||||
} else
|
||||
{
|
||||
Z80Ctrl->iopage[idx] = idx | IO_TYPE_PHYSICAL_HW;
|
||||
}
|
||||
}
|
||||
// Setup sub-memory pages to enable rapid switch according to memory bank commands.
|
||||
for(subMode=0; subMode < MEMORY_SUB_MODES; subMode++)
|
||||
{
|
||||
if(Z80Ctrl->page[MEMORY_MODES+subMode] == NULL)
|
||||
{
|
||||
#if(DEBUG_ENABLED & 0x01)
|
||||
if(Z80Ctrl->debug >=3) pr_info("Allocating memory sub page:%d\n", subMode);
|
||||
#endif
|
||||
(Z80Ctrl->page[MEMORY_MODES+subMode]) = (uint32_t *)kmalloc((MEMORY_BLOCK_SLOTS*sizeof(uint32_t)), GFP_KERNEL);
|
||||
if ((Z80Ctrl->page[MEMORY_MODES+subMode]) == NULL)
|
||||
{
|
||||
pr_info("z80drv: failed to allocate memory sub mapping page:%d memory!", subMode);
|
||||
}
|
||||
}
|
||||
|
||||
// Duplicate current mode into the sub page prior to setting up specific config.
|
||||
memcpy((uint8_t *)Z80Ctrl->page[MEMORY_MODES+subMode], (uint8_t *)Z80Ctrl->page[0], MEMORY_BLOCK_SLOTS*sizeof(uint32_t));
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + subMode;
|
||||
|
||||
// MZ700 memory mode switch.
|
||||
//
|
||||
// MZ-700
|
||||
// |0000:0FFF|1000:CFFF|D000:FFFF
|
||||
// ------------------------------
|
||||
// OUT 0xE0 = |DRAM |DRAM |<last>
|
||||
// OUT 0xE1 = |<last> |DRAM |DRAM
|
||||
// OUT 0xE2 = |MONITOR |DRAM |<last>
|
||||
// OUT 0xE3 = |<last> |DRAM |Memory Mapped I/O
|
||||
// OUT 0xE4 = |MONITOR |DRAM |Memory Mapped I/O
|
||||
// OUT 0xE5 = |<last> |DRAM |Inhibit
|
||||
// OUT 0xE6 = |<last> |DRAM |<return to last>
|
||||
//
|
||||
// Sub-memory page maps:
|
||||
//
|
||||
// LOW BANK HIGH BANK PAGE MAP
|
||||
// DRAM 0
|
||||
// DRAM MEMORY MAP 1
|
||||
// Inhibit 2
|
||||
// DRAM 3
|
||||
// MONITOR MEMORY MAP 4
|
||||
// Inhibit 5
|
||||
//
|
||||
if(subMode >= 0 && subMode < 3)
|
||||
{
|
||||
// Enable lower 4K block as DRAM
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
}
|
||||
if(subMode >= 3 && subMode < 6)
|
||||
{
|
||||
// Enable lower 4K block as Monitor ROM
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
}
|
||||
if(subMode == 0 || subMode == 3)
|
||||
{
|
||||
// Enable upper 12K block, including Video/Memory Mapped peripherals area, as DRAM.
|
||||
for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
// MZ-700 mode we only work in first 64K block.
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
}
|
||||
if(subMode == 1 || subMode == 4)
|
||||
{
|
||||
// Enable Video RAM and Memory mapped peripherals in upper 12K block.
|
||||
for(idx=0xD000; idx < 0xE000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx);
|
||||
}
|
||||
for(idx=0xE000; idx < 0xE800; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx);
|
||||
}
|
||||
for(idx=0xE800; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
}
|
||||
if(subMode == 2 || subMode == 5)
|
||||
{
|
||||
// Inhibit. Backup current page data in region 0xD000-0xFFFF and inhibit it.
|
||||
for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_INHIBIT, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 4;
|
||||
|
||||
// Enable refresh as using virtual RAM stops refresh of host DRAM.
|
||||
Z80Ctrl->refreshDRAM = 2;
|
||||
}
|
||||
@@ -196,6 +304,20 @@ void mz700Init(uint8_t mode)
|
||||
// Locals.
|
||||
uint32_t idx;
|
||||
|
||||
// Reset memory paging to default.
|
||||
SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR);
|
||||
|
||||
#if(DEBUG_ENABLED & 0x01)
|
||||
if(Z80Ctrl->debug >=3) pr_info("Allocating MZ-1R18 memory\n");
|
||||
#endif
|
||||
// Allocate memory for the MZ-1R18 64K Ram File board.
|
||||
MZ700Ctrl.ramFileMem = (uint32_t *)kmalloc((65536 * sizeof(uint8_t)), GFP_KERNEL);
|
||||
if(MZ700Ctrl.ramFileMem == NULL)
|
||||
{
|
||||
pr_info("z80drv: failed to allocate MZ-1R18 Ram File memory!");
|
||||
}
|
||||
MZ700Ctrl.ramFileAddr = 0x0000;
|
||||
|
||||
// Initialise the virtual RAM from the HOST DRAM. This is to maintain compatibility as some applications (in my experience) have
|
||||
// bugs, which Im putting down to not initialising variables. The host DRAM is in a pattern of 0x00..0x00, 0xFF..0xFF repeating
|
||||
// when first powered on.
|
||||
@@ -230,29 +352,27 @@ void mz700Init(uint8_t mode)
|
||||
}
|
||||
}
|
||||
|
||||
// Add in a test program to guage execution speed.
|
||||
#if(TARGET_HOST_MZ700 == 1)
|
||||
Z80Ctrl->ram[0x1200] = 0x01;
|
||||
Z80Ctrl->ram[0x1201] = 0x86;
|
||||
Z80Ctrl->ram[0x1202] = 0xf2;
|
||||
Z80Ctrl->ram[0x1203] = 0x3e;
|
||||
Z80Ctrl->ram[0x1204] = 0x15;
|
||||
Z80Ctrl->ram[0x1205] = 0x3d;
|
||||
Z80Ctrl->ram[0x1206] = 0x20;
|
||||
Z80Ctrl->ram[0x1207] = 0xfd;
|
||||
Z80Ctrl->ram[0x1208] = 0x0b;
|
||||
Z80Ctrl->ram[0x1209] = 0x78;
|
||||
Z80Ctrl->ram[0x120a] = 0xb1;
|
||||
Z80Ctrl->ram[0x120b] = 0x20;
|
||||
Z80Ctrl->ram[0x120c] = 0xf6;
|
||||
Z80Ctrl->ram[0x120d] = 0xc3;
|
||||
Z80Ctrl->ram[0x120e] = 0x00;
|
||||
Z80Ctrl->ram[0x120f] = 0x00;
|
||||
#endif
|
||||
|
||||
// Reset memory paging to default.
|
||||
SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR);
|
||||
// Initial memory config.
|
||||
mz700SetupMemory(Z80Ctrl->defaultPageMode);
|
||||
|
||||
// Add in a test program to guage execution speed.
|
||||
Z80Ctrl->ram[0x1200] = 0x01;
|
||||
Z80Ctrl->ram[0x1201] = 0x86;
|
||||
Z80Ctrl->ram[0x1202] = 0xf2;
|
||||
Z80Ctrl->ram[0x1203] = 0x3e;
|
||||
Z80Ctrl->ram[0x1204] = 0x15;
|
||||
Z80Ctrl->ram[0x1205] = 0x3d;
|
||||
Z80Ctrl->ram[0x1206] = 0x20;
|
||||
Z80Ctrl->ram[0x1207] = 0xfd;
|
||||
Z80Ctrl->ram[0x1208] = 0x0b;
|
||||
Z80Ctrl->ram[0x1209] = 0x78;
|
||||
Z80Ctrl->ram[0x120a] = 0xb1;
|
||||
Z80Ctrl->ram[0x120b] = 0x20;
|
||||
Z80Ctrl->ram[0x120c] = 0xf6;
|
||||
Z80Ctrl->ram[0x120d] = 0xc3;
|
||||
Z80Ctrl->ram[0x120e] = 0x00;
|
||||
Z80Ctrl->ram[0x120f] = 0x00;
|
||||
|
||||
pr_info("Enabling MZ-700 driver.\n");
|
||||
return;
|
||||
}
|
||||
@@ -269,17 +389,17 @@ void mz700Remove(void)
|
||||
static inline void mz700DecodeMemoryMapSetup(zuint16 address, zuint8 data, uint8_t ioFlag, uint8_t readFlag)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t idx;
|
||||
//uint32_t idx;
|
||||
|
||||
// Decoding memory address or I/O address?
|
||||
if(ioFlag == 0)
|
||||
{
|
||||
// #if(DEBUG_ENABLED & 1)
|
||||
// if(Z80Ctrl->debug >= 2)
|
||||
// {
|
||||
// pr_info("MEM:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag);
|
||||
// }
|
||||
// #endif
|
||||
#if(DEBUG_ENABLED & 1)
|
||||
if(Z80Ctrl->debug >= 3)
|
||||
{
|
||||
pr_info("MEM:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag);
|
||||
}
|
||||
#endif
|
||||
// Certain machines have memory mapped I/O, these need to be handled in-situ as some reads may change the memory map.
|
||||
// These updates are made whilst waiting for the CPLD to retrieve the requested byte.
|
||||
//
|
||||
@@ -306,116 +426,97 @@ static inline void mz700DecodeMemoryMapSetup(zuint16 address, zuint8 data, uint8
|
||||
}
|
||||
} else
|
||||
{
|
||||
// #if(DEBUG_ENABLED & 1)
|
||||
// if(Z80Ctrl->debug >= 2)
|
||||
// {
|
||||
// pr_info("IO:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag);
|
||||
// }
|
||||
// #endif
|
||||
#if(DEBUG_ENABLED & 1)
|
||||
if(Z80Ctrl->debug >= 3)
|
||||
{
|
||||
pr_info("IO:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Determine if this is a memory management port and update the memory page if required.
|
||||
switch(address & 0x00FF)
|
||||
// Check to see if the memory mode page has been allocated for requested mode, if it hasnt, we need to allocate and then define.
|
||||
if(((address&0xFF) - 0xE0) >= 0 && ((address&0xFF) - 0xE0) < 7)
|
||||
{
|
||||
// MZ700 memory mode switch.
|
||||
//
|
||||
//
|
||||
// MZ-700
|
||||
// |0000:0FFF|1000:CFFF|D000:FFFF
|
||||
// ------------------------------
|
||||
// OUT 0xE0 = |DRAM | |
|
||||
// OUT 0xE1 = | | |DRAM
|
||||
// OUT 0xE2 = |MONITOR | |
|
||||
// OUT 0xE3 = | | |Memory Mapped I/O
|
||||
// OUT 0xE0 = |DRAM |DRAM |<last>
|
||||
// OUT 0xE1 = |<last> |DRAM |DRAM
|
||||
// OUT 0xE2 = |MONITOR |DRAM |<last>
|
||||
// OUT 0xE3 = |<last> |DRAM |Memory Mapped I/O
|
||||
// OUT 0xE4 = |MONITOR |DRAM |Memory Mapped I/O
|
||||
// OUT 0xE5 = | | |Inhibit
|
||||
// OUT 0xE6 = | | |<return>
|
||||
//
|
||||
// <return> = Return to the state prior to the complimentary command being invoked.
|
||||
// Enable lower 4K block as DRAM
|
||||
case IO_ADDR_E0:
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
break;
|
||||
// OUT 0xE5 = |<last> |DRAM |Inhibit
|
||||
// OUT 0xE6 = |<last> |DRAM |<return to last>
|
||||
//
|
||||
// Sub-memory page maps:
|
||||
//
|
||||
// LOW BANK HIGH BANK PAGE MAP
|
||||
// DRAM 0
|
||||
// DRAM MEMORY MAP 1
|
||||
// Inhibit 2
|
||||
// DRAM 3
|
||||
// MONITOR MEMORY MAP 4
|
||||
// Inhibit 5
|
||||
//
|
||||
// Determine if this is a memory management port and update the memory page if required.
|
||||
switch(address & 0x00FF)
|
||||
{
|
||||
case IO_ADDR_E0:
|
||||
MZ700Ctrl.loDRAMen = 1;
|
||||
break;
|
||||
|
||||
// Enable upper 12K block, including Video/Memory Mapped peripherals area, as DRAM.
|
||||
case IO_ADDR_E1:
|
||||
if(!Z80Ctrl->inhibitMode)
|
||||
{
|
||||
for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
// MZ-700 mode we only work in first 64K block.
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Enable MOnitor ROM in lower 4K block
|
||||
case IO_ADDR_E2:
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
break;
|
||||
|
||||
// Enable Video RAM and Memory mapped peripherals in upper 12K block.
|
||||
case IO_ADDR_E3:
|
||||
if(!Z80Ctrl->inhibitMode)
|
||||
{
|
||||
for(idx=0xD000; idx < 0xE000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx);
|
||||
}
|
||||
for(idx=0xE000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IO_ADDR_E1:
|
||||
MZ700Ctrl.hiDRAMen = 1;
|
||||
break;
|
||||
|
||||
// Reset to power on condition memory map.
|
||||
case IO_ADDR_E4:
|
||||
// Lower 4K set to Monitor ROM.
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
if(!Z80Ctrl->inhibitMode)
|
||||
{
|
||||
// Upper 12K to hardware.
|
||||
for(idx=0xD000; idx < 0xE000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx);
|
||||
}
|
||||
for(idx=0xE000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IO_ADDR_E2:
|
||||
MZ700Ctrl.loDRAMen = 0;
|
||||
break;
|
||||
|
||||
// Inhibit. Backup current page data in region 0xD000-0xFFFF and inhibit it.
|
||||
case IO_ADDR_E5:
|
||||
for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
backupMemoryType(idx/MEMORY_BLOCK_GRANULARITY);
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_INHIBIT, idx);
|
||||
}
|
||||
Z80Ctrl->inhibitMode = 1;
|
||||
break;
|
||||
case IO_ADDR_E3:
|
||||
MZ700Ctrl.hiDRAMen = 0;
|
||||
break;
|
||||
|
||||
// Restore D000-FFFF to its original state.
|
||||
case IO_ADDR_E6:
|
||||
for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
restoreMemoryType(idx/MEMORY_BLOCK_GRANULARITY);
|
||||
}
|
||||
Z80Ctrl->inhibitMode = 0;
|
||||
break;
|
||||
case IO_ADDR_E4:
|
||||
MZ700Ctrl.loDRAMen = 0;
|
||||
MZ700Ctrl.hiDRAMen = 0;
|
||||
Z80Ctrl->inhibitMode = 0;
|
||||
break;
|
||||
|
||||
// Port is not a memory management port.
|
||||
default:
|
||||
break;
|
||||
case IO_ADDR_E5:
|
||||
Z80Ctrl->inhibitMode = 1;
|
||||
break;
|
||||
|
||||
case IO_ADDR_E6:
|
||||
Z80Ctrl->inhibitMode = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Setup memory mode based on flag state.
|
||||
if(Z80Ctrl->inhibitMode)
|
||||
{
|
||||
if(MZ700Ctrl.loDRAMen)
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 2;
|
||||
else
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 5;
|
||||
} else
|
||||
if(MZ700Ctrl.loDRAMen)
|
||||
{
|
||||
if(MZ700Ctrl.hiDRAMen)
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 0;
|
||||
else
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 1;
|
||||
} else
|
||||
{
|
||||
if(MZ700Ctrl.hiDRAMen)
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 3;
|
||||
else
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,8 +530,18 @@ static inline uint8_t mz700Read(zuint16 address, uint8_t ioFlag)
|
||||
// I/O Operation?
|
||||
if(ioFlag)
|
||||
{
|
||||
switch(address)
|
||||
switch((address&0xff))
|
||||
{
|
||||
// MZ-1R18 Ram File Data Register.
|
||||
case 0xEA:
|
||||
data = MZ700Ctrl.ramFileMem[MZ700Ctrl.ramFileAddr];
|
||||
MZ700Ctrl.ramFileAddr++;
|
||||
break;
|
||||
|
||||
// MZ-1R18 Ram File Control Register.
|
||||
case 0xEB:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -460,8 +571,19 @@ static inline void mz700Write(zuint16 address, zuint8 data, uint8_t ioFlag)
|
||||
// I/O Operation?
|
||||
if(ioFlag)
|
||||
{
|
||||
switch(address)
|
||||
switch((address&0xff))
|
||||
{
|
||||
// MZ-1R18 Ram File Data Register.
|
||||
case 0xEA:
|
||||
MZ700Ctrl.ramFileMem[MZ700Ctrl.ramFileAddr] = data;
|
||||
MZ700Ctrl.ramFileAddr++;
|
||||
break;
|
||||
|
||||
// MZ-1R18 Ram File Control Register.
|
||||
case 0xEB:
|
||||
MZ700Ctrl.ramFileAddr = (address & 0xff00) | data;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -194,6 +194,9 @@ void pcwInit(uint8_t mode)
|
||||
Z80Ctrl->ram[0] = 0x00;
|
||||
Z80Ctrl->ram[1] = 0x00;
|
||||
|
||||
// Initial memory config.
|
||||
pcwSetupMemory(Z80Ctrl->defaultPageMode);
|
||||
|
||||
pr_info("Enabling PCW-%s driver.\n", mode == 0 ? "8256" : "9256");
|
||||
return;
|
||||
}
|
||||
@@ -297,7 +300,7 @@ pr_info("VORIGIN:%02x\n", data);
|
||||
pr_info("SCREENATTR:%02x\n", data);
|
||||
break;
|
||||
case IO_GACMD:
|
||||
pr_info("GACMD:%02x\n", data);
|
||||
//pr_info("GACMD:%02x\n", data);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -95,6 +95,8 @@
|
||||
#define ROM_DIR "/apps/FusionX/host/MZ-80A/RFS/"
|
||||
#elif(TARGET_HOST_MZ700 == 1)
|
||||
#define ROM_DIR "/apps/FusionX/host/MZ-700/RFS/"
|
||||
#elif(TARGET_HOST_MZ1500 == 1)
|
||||
#define ROM_DIR "/apps/FusionX/host/MZ-1500/RFS/"
|
||||
#else
|
||||
#error "Unknown host configured."
|
||||
#endif
|
||||
@@ -106,20 +108,23 @@
|
||||
#define ROM_USER_I_80C_FILENAME ROM_DIR "USER_ROM_256_80c.bin"
|
||||
#define ROM_USER_II_80C_FILENAME ROM_DIR "USER_ROM_II_256_80c.bin"
|
||||
#define ROM_USER_III_80C_FILENAME ROM_DIR "USER_ROM_III_256_80c.bin"
|
||||
#define ROM_MZ_1E05_FILENAME ROM_DIR "mz-1e05.bin"
|
||||
|
||||
// RFS Board ROM rom load and size definitions.
|
||||
#define ROM_MROM_LOAD_ADDR 0x000000
|
||||
#define ROM_USER_I_LOAD_ADDR 0x080000
|
||||
#define ROM_USER_II_LOAD_ADDR 0x100000
|
||||
#define ROM_USER_III_LOAD_ADDR 0x180000
|
||||
#define ROM_MZ_1E05_ADDR ((Z80_VIRTUAL_ROM_SIZE-0x10000)+0xF000)
|
||||
#define ROM_MROM_SIZE 0x80000
|
||||
#define ROM_USER_I_SIZE 0x80000
|
||||
#define ROM_USER_II_SIZE 0x80000
|
||||
#define ROM_USER_III_SIZE 0x80000
|
||||
#define ROM_MZ_1E05_SIZE 0x1000
|
||||
|
||||
// SD Drive constants.
|
||||
#define SD_DIR "/apps/FusionX/host/MZ-80A/RFS/"
|
||||
#define SD_CARD_FILENAME SD_DIR "SHARP_MZ80A_RFS_CPM_IMAGE_1.img"// SD Card Binary Image.
|
||||
#define SD_CARD_FILENAME SD_DIR "SHARP_MZ80A_RFS_CPM_IMAGE_1.img" // SD Card Binary Image.
|
||||
|
||||
// MMC/SD command (SPI mode)
|
||||
#define CMD0 0x40 + 0 // GO_IDLE_STATE
|
||||
@@ -255,9 +260,14 @@ void rfsSetupMemory(enum Z80_MEMORY_PROFILE mode)
|
||||
// Enable refresh as using virtual RAM stops refresh of host DRAM.
|
||||
Z80Ctrl->refreshDRAM = 2;
|
||||
|
||||
#if (TARGET_HOST_MZ700 == 1)
|
||||
#if (TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
// Reset memory paging to default.
|
||||
SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR);
|
||||
|
||||
#if (TARGET_HOST_MZ1500 == 1)
|
||||
// MZ-1500, E4 reset closes the PCG access.
|
||||
Z80Ctrl->pcgMode = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// No I/O Ports on the RFS board.
|
||||
@@ -311,10 +321,16 @@ void rfsInit(uint8_t mode80c)
|
||||
while(CPLD_READY() == 0);
|
||||
Z80Ctrl->rom[idx+(Z80_VIRTUAL_ROM_SIZE-0x10000)] = z80io_PRL_Read8(1);
|
||||
}
|
||||
rfsLoadROM(ROM_MZ_1E05_FILENAME, ROM_MZ_1E05_ADDR, ROM_MZ_1E05_SIZE);
|
||||
|
||||
#if (TARGET_HOST_MZ700 == 1)
|
||||
#if (TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
// Reset memory paging to default.
|
||||
SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR);
|
||||
|
||||
#if (TARGET_HOST_MZ1500 == 1)
|
||||
// MZ-1500, E4 reset closes the PCG access.
|
||||
Z80Ctrl->pcgMode = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pr_info("Enabling RFS(%d) driver.\n", mode80c == 1 ? 80 : 40);
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Feb 2023 v1.0 - Initial write based on the tranZPUter SW hardware.
|
||||
// Apr 2023 v1.1 - Updates & bug fixes.
|
||||
// History: Feb 2023 - v1.0 - Initial write based on the tranZPUter SW hardware.
|
||||
// Apr 2023 - v1.1 - Updates & bug fixes.
|
||||
// Jul 2023 - v1.6 - Updated MZ-700 code, adding sub-memory maps to increase page mapping
|
||||
// speed specifically to enable reliable tape read/write.
|
||||
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -68,6 +71,8 @@ typedef struct {
|
||||
uint8_t regCpuInfo; // Internal FPGA CPU information register.
|
||||
uint8_t regCpldCfg; // Internal CPLD config register.
|
||||
uint8_t regCpldInfo; // Internal CPLD information register.
|
||||
uint8_t loDRAMen; // Lower bank 0000:0FFF DRAM enabled, else monitor.
|
||||
uint8_t hiDRAMen; // Higher bank D000:FFFF DRAM enabled, else memory mapped I/O.
|
||||
} t_TZPUCtrl;
|
||||
|
||||
// TZPU Board control.
|
||||
@@ -147,10 +152,12 @@ void tzpuSetupMemory(enum Z80_MEMORY_PROFILE mode)
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
TZPUCtrl.regCpldInfo = (CPLD_VERSION << 4) | (CPLD_HAS_FPGA_VIDEO << 3) | HWMODE_MZ2000;
|
||||
#endif
|
||||
TZPUCtrl.regCpldCfg = 0x00; // Not used, as no CPLD available, but need to store/return value if addressed.
|
||||
TZPUCtrl.regCpldCfg = 0x00; // Not used, as no CPLD available, but need to store/return value if addressed.
|
||||
TZPUCtrl.loDRAMen = 0; // Default is monitor ROM is enabled.
|
||||
TZPUCtrl.hiDRAMen = 0; // Default is memory mapped I/O enabled.
|
||||
|
||||
// Default memory mode, TZFS.
|
||||
Z80Ctrl->memoryMode = TZMM_ORIG;
|
||||
Z80Ctrl->memoryMode = TZMM_TZFS;
|
||||
|
||||
// Reset IO mapping.
|
||||
for(idx=0x0000; idx < IO_PAGE_SIZE; idx++)
|
||||
@@ -246,7 +253,7 @@ void tzpuRemove(void)
|
||||
uint32_t idx;
|
||||
|
||||
// Go through and clear all memory maps, leave the original page in slot 0.
|
||||
for(idx=1; idx < MEMORY_MODES; idx++)
|
||||
for(idx=1; idx < MEMORY_MODES+MEMORY_SUB_MODES; idx++)
|
||||
{
|
||||
if(Z80Ctrl->page[idx] != NULL)
|
||||
{
|
||||
@@ -267,17 +274,18 @@ void tzpuRemove(void)
|
||||
static inline void tzpuDecodeMemoryMapSetup(zuint16 address, zuint8 data, uint8_t ioFlag, uint8_t readFlag)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t idx;
|
||||
//uint32_t idx;
|
||||
|
||||
// I/O or Memory?
|
||||
if(ioFlag == 0)
|
||||
{
|
||||
// #if(DEBUG_ENABLED & 1)
|
||||
// if(Z80Ctrl->debug >= 2)
|
||||
// {
|
||||
// pr_info("MEM:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag);
|
||||
// }
|
||||
// #endif
|
||||
#if(DEBUG_ENABLED & 1)
|
||||
if(Z80Ctrl->debug >= 3)
|
||||
{
|
||||
pr_info("MEM:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Certain machines have memory mapped I/O, these need to be handled in-situ as some reads may change the memory map.
|
||||
// These updates are made whilst waiting for the CPLD to retrieve the requested byte.
|
||||
//
|
||||
@@ -305,116 +313,87 @@ static inline void tzpuDecodeMemoryMapSetup(zuint16 address, zuint8 data, uint8_
|
||||
} else
|
||||
// I/O Decoding.
|
||||
{
|
||||
// #if(DEBUG_ENABLED & 1)
|
||||
// if(Z80Ctrl->debug >= 2)
|
||||
// {
|
||||
// pr_info("IO:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag);
|
||||
// }
|
||||
// #endif
|
||||
|
||||
// Determine if this is a memory management port and update the memory page if required.
|
||||
switch(address & 0x00FF)
|
||||
#if(DEBUG_ENABLED & 1)
|
||||
if(Z80Ctrl->debug >= 3)
|
||||
{
|
||||
pr_info("IO:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check to see if the memory mode page has been allocated for requested mode, if it hasnt, we need to allocate and then define.
|
||||
if(((address&0xFF) - 0xE0) >= 0 && ((address&0xFF) - 0xE0) < MEMORY_SUB_MODES)
|
||||
{
|
||||
// MZ700 memory mode switch.
|
||||
//
|
||||
//
|
||||
// MZ-700
|
||||
// |0000:0FFF|1000:CFFF|D000:FFFF
|
||||
// ------------------------------
|
||||
// OUT 0xE0 = |DRAM | |
|
||||
// OUT 0xE1 = | | |DRAM
|
||||
// OUT 0xE2 = |MONITOR | |
|
||||
// OUT 0xE3 = | | |Memory Mapped I/O
|
||||
// OUT 0xE0 = |DRAM |DRAM |<last>
|
||||
// OUT 0xE1 = |<last> |DRAM |DRAM
|
||||
// OUT 0xE2 = |MONITOR |DRAM |<last>
|
||||
// OUT 0xE3 = |<last> |DRAM |Memory Mapped I/O
|
||||
// OUT 0xE4 = |MONITOR |DRAM |Memory Mapped I/O
|
||||
// OUT 0xE5 = | | |Inhibit
|
||||
// OUT 0xE6 = | | |<return>
|
||||
//
|
||||
// <return> = Return to the state prior to the complimentary command being invoked.
|
||||
// Enable lower 4K block as DRAM
|
||||
case IO_ADDR_E0:
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
break;
|
||||
// OUT 0xE5 = |<last> |DRAM |Inhibit
|
||||
// OUT 0xE6 = |<last> |DRAM |<return to last>
|
||||
//
|
||||
// Determine if this is a memory management port and update the memory page if required.
|
||||
switch(address & 0x00FF)
|
||||
{
|
||||
case IO_ADDR_E0:
|
||||
TZPUCtrl.loDRAMen = 1;
|
||||
break;
|
||||
|
||||
// Enable upper 12K block, including Video/Memory Mapped peripherals area, as DRAM.
|
||||
case IO_ADDR_E1:
|
||||
if(!Z80Ctrl->inhibitMode)
|
||||
{
|
||||
for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
// MZ-700 mode we only work in first 64K block.
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Enable MOnitor ROM in lower 4K block
|
||||
case IO_ADDR_E2:
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
break;
|
||||
|
||||
// Enable Video RAM and Memory mapped peripherals in upper 12K block.
|
||||
case IO_ADDR_E3:
|
||||
if(!Z80Ctrl->inhibitMode)
|
||||
{
|
||||
for(idx=0xD000; idx < 0xE000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx);
|
||||
}
|
||||
for(idx=0xE000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IO_ADDR_E1:
|
||||
TZPUCtrl.hiDRAMen = 1;
|
||||
break;
|
||||
|
||||
// Reset to power on condition memory map.
|
||||
case IO_ADDR_E4:
|
||||
// Lower 4K set to Monitor ROM.
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
if(!Z80Ctrl->inhibitMode)
|
||||
{
|
||||
// Upper 12K to hardware.
|
||||
for(idx=0xD000; idx < 0xE000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx);
|
||||
}
|
||||
for(idx=0xE000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IO_ADDR_E2:
|
||||
TZPUCtrl.loDRAMen = 0;
|
||||
break;
|
||||
|
||||
// Inhibit. Backup current page data in region 0xD000-0xFFFF and inhibit it.
|
||||
case IO_ADDR_E5:
|
||||
for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
backupMemoryType(idx/MEMORY_BLOCK_GRANULARITY);
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_INHIBIT, idx);
|
||||
}
|
||||
Z80Ctrl->inhibitMode = 1;
|
||||
break;
|
||||
case IO_ADDR_E3:
|
||||
TZPUCtrl.hiDRAMen = 0;
|
||||
break;
|
||||
|
||||
// Restore D000-FFFF to its original state.
|
||||
case IO_ADDR_E6:
|
||||
for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
restoreMemoryType(idx/MEMORY_BLOCK_GRANULARITY);
|
||||
}
|
||||
Z80Ctrl->inhibitMode = 0;
|
||||
break;
|
||||
case IO_ADDR_E4:
|
||||
TZPUCtrl.loDRAMen = 0;
|
||||
TZPUCtrl.hiDRAMen = 0;
|
||||
Z80Ctrl->inhibitMode = 0;
|
||||
break;
|
||||
|
||||
// Port is not a memory management port.
|
||||
default:
|
||||
break;
|
||||
case IO_ADDR_E5:
|
||||
Z80Ctrl->inhibitMode = 1;
|
||||
break;
|
||||
|
||||
case IO_ADDR_E6:
|
||||
Z80Ctrl->inhibitMode = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Setup memory mode based on flag state.
|
||||
if(Z80Ctrl->inhibitMode)
|
||||
{
|
||||
if(TZPUCtrl.loDRAMen)
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 2;
|
||||
else
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 5;
|
||||
} else
|
||||
if(TZPUCtrl.loDRAMen)
|
||||
{
|
||||
if(TZPUCtrl.hiDRAMen)
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 0;
|
||||
else
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 1;
|
||||
} else
|
||||
{
|
||||
if(TZPUCtrl.hiDRAMen)
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 3;
|
||||
else
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -493,6 +472,7 @@ static inline uint8_t tzpuRead(zuint16 address, uint8_t ioFlag)
|
||||
static inline void tzpuWrite(zuint16 address, zuint8 data, uint8_t ioFlag)
|
||||
{
|
||||
// Locals
|
||||
uint8_t subMode;
|
||||
uint32_t idx;
|
||||
|
||||
// The tranZPUter board, in order to autoboot and use valuable space for variables, allows writing into the User ROM
|
||||
@@ -925,6 +905,95 @@ static inline void tzpuWrite(zuint16 address, zuint8 data, uint8_t ioFlag)
|
||||
}
|
||||
}
|
||||
// Memory map now created/switched.
|
||||
|
||||
// Allocate/populate the sub-memory maps for this mode. TZFS currently uses sub-memory modes for MZ-700 page banking.
|
||||
if(Z80Ctrl->memoryMode == TZMM_TZFS)
|
||||
{
|
||||
for(subMode=0; subMode < MEMORY_SUB_MODES; subMode++)
|
||||
{
|
||||
if(Z80Ctrl->page[MEMORY_MODES+subMode] == NULL)
|
||||
{
|
||||
#if(DEBUG_ENABLED & 0x01)
|
||||
if(Z80Ctrl->debug >=3) pr_info("Allocating memory sub page:%d\n", subMode);
|
||||
#endif
|
||||
pr_info("Allocating memory sub page:%d,%d\n", subMode, (MEMORY_BLOCK_SLOTS*sizeof(uint32_t)));
|
||||
(Z80Ctrl->page[MEMORY_MODES+subMode]) = (uint32_t *)kmalloc((MEMORY_BLOCK_SLOTS*sizeof(uint32_t)), GFP_KERNEL);
|
||||
if ((Z80Ctrl->page[MEMORY_MODES+subMode]) == NULL)
|
||||
{
|
||||
pr_info("z80drv: failed to allocate memory sub mapping page:%d memory!", subMode);
|
||||
}
|
||||
}
|
||||
|
||||
// Duplicate current mode into the sub page prior to setting up specific config.
|
||||
memcpy((uint8_t *)Z80Ctrl->page[MEMORY_MODES+subMode], (uint8_t *)Z80Ctrl->page[(data & (MEMORY_MODES - 1))], MEMORY_BLOCK_SLOTS*sizeof(uint32_t));
|
||||
Z80Ctrl->memoryMode = MEMORY_MODES + subMode;
|
||||
TZPUCtrl.loDRAMen = 0;
|
||||
TZPUCtrl.hiDRAMen = 0;
|
||||
Z80Ctrl->inhibitMode = 0;
|
||||
|
||||
// MZ700 memory mode switch.
|
||||
//
|
||||
// MZ-700
|
||||
// |0000:0FFF|1000:CFFF|D000:FFFF
|
||||
// ------------------------------
|
||||
// OUT 0xE0 = |DRAM |DRAM |<last>
|
||||
// OUT 0xE1 = |<last> |DRAM |DRAM
|
||||
// OUT 0xE2 = |MONITOR |DRAM |<last>
|
||||
// OUT 0xE3 = |<last> |DRAM |Memory Mapped I/O
|
||||
// OUT 0xE4 = |MONITOR |DRAM |Memory Mapped I/O
|
||||
// OUT 0xE5 = |<last> |DRAM |Inhibit
|
||||
// OUT 0xE6 = |<last> |DRAM |<return to last>
|
||||
//
|
||||
// Sub-memory page maps:
|
||||
//
|
||||
// LOW BANK HIGH BANK PAGE MAP
|
||||
// DRAM 0
|
||||
// DRAM MEMORY MAP 1
|
||||
// Inhibit 2
|
||||
// DRAM 3
|
||||
// MONITOR MEMORY MAP 4
|
||||
// Inhibit 5
|
||||
//
|
||||
if(subMode >= 0 && subMode < 3)
|
||||
{
|
||||
// Enable lower 4K block as DRAM
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
}
|
||||
if(subMode == 0 || subMode == 3)
|
||||
{
|
||||
// Enable upper 12K block, including Video/Memory Mapped peripherals area, as DRAM.
|
||||
for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
// MZ-700 mode we only work in first 64K block.
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
}
|
||||
if(subMode == 1 || subMode == 4)
|
||||
{
|
||||
// Enable Video RAM and Memory mapped peripherals in upper 12K block.
|
||||
for(idx=0xD000; idx < 0xE000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx);
|
||||
}
|
||||
for(idx=0xE000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx);
|
||||
}
|
||||
}
|
||||
if(subMode == 2 || subMode == 5)
|
||||
{
|
||||
// Inhibit. Backup current page data in region 0xD000-0xFFFF and inhibit it.
|
||||
for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_INHIBIT, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Z80Ctrl->memoryMode = (data & (MEMORY_MODES - 1));
|
||||
break;
|
||||
|
||||
case IO_TZ_SETXMHZ:
|
||||
|
||||
1
software/asm/1Z001M.asm
Symbolic link
1
software/asm/1Z001M.asm
Symbolic link
@@ -0,0 +1 @@
|
||||
/srv2/SharpSoft/MZ-2000/ASM/1Z001M.asm
|
||||
3303
software/asm/1z-013a-km.asm
Normal file
3303
software/asm/1z-013a-km.asm
Normal file
File diff suppressed because it is too large
Load Diff
25545
software/asm/5z009-1b.asm
Normal file
25545
software/asm/5z009-1b.asm
Normal file
File diff suppressed because it is too large
Load Diff
1658
software/asm/SFD700.asm
Normal file
1658
software/asm/SFD700.asm
Normal file
File diff suppressed because it is too large
Load Diff
2298
software/asm/asm.asm
Normal file
2298
software/asm/asm.asm
Normal file
File diff suppressed because it is too large
Load Diff
5908
software/asm/basic_sp-5025.asm
Normal file
5908
software/asm/basic_sp-5025.asm
Normal file
File diff suppressed because it is too large
Load Diff
1615
software/asm/cbios.asm
Normal file
1615
software/asm/cbios.asm
Normal file
File diff suppressed because it is too large
Load Diff
3908
software/asm/cbiosII.asm
Normal file
3908
software/asm/cbiosII.asm
Normal file
File diff suppressed because it is too large
Load Diff
35
software/asm/cpm22-bios.asm
Normal file
35
software/asm/cpm22-bios.asm
Normal file
@@ -0,0 +1,35 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;-
|
||||
;- 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 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
|
||||
|
||||
; All CBIOS code, tables and variables are now stored in the cbios.asm and cbiosII.asm as a seperate assembled
|
||||
; binary.
|
||||
3764
software/asm/cpm22.asm
Normal file
3764
software/asm/cpm22.asm
Normal file
File diff suppressed because it is too large
Load Diff
1
software/asm/include/MSBASIC_BuildVersion.asm
Normal file
1
software/asm/include/MSBASIC_BuildVersion.asm
Normal file
@@ -0,0 +1 @@
|
||||
BUILD_VERSION EQU 3
|
||||
1
software/asm/include/cpm_buildversion.asm
Normal file
1
software/asm/include/cpm_buildversion.asm
Normal file
@@ -0,0 +1 @@
|
||||
BUILD_VERSION EQU 2
|
||||
536
software/asm/include/cpm_definitions.asm
Normal file
536
software/asm/include/cpm_definitions.asm
Normal file
@@ -0,0 +1,536 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;-
|
||||
;- 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-21 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.
|
||||
; May 2020 - Cut from the RFS version of CPM for the tranZPUter SW board.
|
||||
;- Apr 2021 - Updates backported from the RFS version of CPM.
|
||||
;-
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;- 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.
|
||||
;-----------------------------------------------
|
||||
; CPM for MZ-700 with with Video Module and 80 Columns display.
|
||||
IF BUILD_VERSION = 0
|
||||
BUILD_VIDEOMODULE EQU 1 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0
|
||||
BUILD_MZ80A EQU 0 ; Build for the Sharp MZ-80A base hardware.
|
||||
BUILD_MZ700 EQU 1 ; Build for the Sharp MZ-700 base hardware.
|
||||
BUILD_80C EQU 1 ; Build for an 80 column (Video Module or 40/80 Colour Card) equipped machine, 0 = standard 40 column.
|
||||
ENDIF
|
||||
; CPM for MZ-80A with with Video Module (if not present expects 40/80 Colour Board) and 80 Columns display.
|
||||
IF BUILD_VERSION = 1
|
||||
BUILD_VIDEOMODULE EQU 1 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0
|
||||
BUILD_MZ80A EQU 1 ; Build for the Sharp MZ-80A base hardware.
|
||||
BUILD_MZ700 EQU 0 ; Build for the Sharp MZ-700 base hardware.
|
||||
BUILD_80C EQU 1 ; Build for an 80 column (Video Module or 40/80 Colour Card) equipped machine, 0 = standard 40 column.
|
||||
ENDIF
|
||||
; CPM for MZ-80A with with standard 40 column display.
|
||||
IF BUILD_VERSION = 2
|
||||
BUILD_VIDEOMODULE EQU 0 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0
|
||||
BUILD_MZ80A EQU 1 ; Build for the Sharp MZ-80A base hardware.
|
||||
BUILD_MZ700 EQU 0 ; Build for the Sharp MZ-700 base hardware.
|
||||
BUILD_80C EQU 0 ; Build for an 80 column (Video Module or 40/80 Colour Card) equipped machine, 0 = standard 40 column.
|
||||
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 64 ; Ensure this is a power of 2, max size 256.
|
||||
|
||||
; Debugging
|
||||
ENADEBUG EQU 1 ; Enable debugging logic, 1 = enable, 0 = disable
|
||||
|
||||
;-----------------------------------------------
|
||||
; Entry/compilation start points.
|
||||
;-----------------------------------------------
|
||||
MROMADDR EQU 00000H ; Start of SA1510 Monitor ROM.
|
||||
CBASE EQU 0DA00H
|
||||
CPMCCP EQU CBASE ; CP/M System entry
|
||||
CPMBDOS EQU CPMCCP + 0806H ; BDOS entry
|
||||
CPMBIOS EQU CPMCCP + 01600H ; Original CPM22 BIOS entry
|
||||
CBIOSSTART EQU CPMBIOS ; Start of the actual CBIOS code.
|
||||
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
|
||||
QDEBUG EQU CBIOSSTART + 51
|
||||
CCP EQU CBASE
|
||||
CCPCLRBUF EQU CBASE + 3
|
||||
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
|
||||
; Old Flash RAM mapping
|
||||
;FDCJMP1BLK EQU 0F3C0H ; The memory mapping FlashRAM only has 64byte granularity so we need to block 64 bytes per FDC vector.
|
||||
;FDCJMP1 EQU 0F3FEH ; ROM paged vector 1.
|
||||
;FDCJMP2BLK EQU 0F7C0H ; The memory mapping FlashRAM only has 64byte granularity so we need to block 64 bytes per FDC vector.
|
||||
;FDCJMP2 EQU 0F7FEH ; ROM paged vector 2.
|
||||
; New CPLD mapping
|
||||
FDCJMP1BLK EQU 0F3FEH ; The memory mapping CPLD has 1byte granularity so we need to block just 2 bytes per FDC vector.
|
||||
FDCJMP1 EQU 0F3FEH ; ROM paged vector 1.
|
||||
FDCJMP2BLK EQU 0F7FEH ; The memory mapping CPLD has 1byte granularity so we need to block just 2 bytes per FDC vector.
|
||||
FDCJMP2 EQU 0F7FEH ; ROM paged vector 2.
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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
|
||||
|
||||
;-----------------------------------------------
|
||||
; IO ports in hardware and values.
|
||||
;-----------------------------------------------
|
||||
MMCFG EQU 060H ; Memory management configuration latch.
|
||||
SETXMHZ EQU 062H ; Select the alternate clock frequency.
|
||||
SET2MHZ EQU 064H ; Select the system 2MHz clock frequency.
|
||||
CLKSELRD EQU 066H ; Read clock selected setting, 0 = 2MHz, 1 = XMHz
|
||||
SVCREQ EQU 068H ; I/O Processor service request.
|
||||
CPLDSTATUS EQU 06BH ; Version 2.1 CPLD status register.
|
||||
CPUCFG EQU 06CH ; Version 2.2 CPU configuration register.
|
||||
CPUSTATUS EQU 06CH ; Version 2.2 CPU runtime status register.
|
||||
CPUINFO EQU 06DH ; Version 2.2 CPU information register.
|
||||
CPLDCFG EQU 06EH ; Version 2.1 CPLD configuration register.
|
||||
CPLDINFO EQU 06FH ; Version 2.1 CPLD version information register.
|
||||
VMPNUM EQU 0A0H ; Set the parameter number to update.
|
||||
VMPLBYTE EQU 0A1H ; Update the lower selected parameter byte.
|
||||
VMPUBYTE EQU 0A2H ; Update the upper selected parameter byte.
|
||||
PALSLCTOFF EQU 0A3H ; set the palette slot Off position to be adjusted.
|
||||
PALSLCTON EQU 0A4H ; set the palette slot On position to be adjusted.
|
||||
PALSETRED EQU 0A5H ; set the red palette value according to the PALETTE_PARAM_SEL address.
|
||||
PALSETGREEN EQU 0A6H ; set the green palette value according to the PALETTE_PARAM_SEL address.
|
||||
PALSETBLUE EQU 0A7H ; set the blue palette value according to the PALETTE_PARAM_SEL address.
|
||||
VMPALETTE EQU 0B0H ; Select Palette:
|
||||
; 0xB0 sets the palette. The Video Module supports 4 bit per colour output but there is only enough RAM for 1 bit per colour so the pallette is used to change the colours output.
|
||||
; Bits [7:0] defines the pallete number. This indexes a lookup table which contains the required 4bit output per 1bit input.
|
||||
; GPU:
|
||||
GPUPARAM EQU 0B2H ; 0xB2 set parameters. Store parameters in a long word to be used by the graphics command processor.
|
||||
; The parameter word is 128 bit and each write to the parameter word shifts left by 8 bits and adds the new byte at bits 7:0.
|
||||
GPUCMD EQU 0B3H ; 0xB3 set the graphics processor unit commands.
|
||||
GPUSTATUS EQU 0B3H ; [7;1] - FSM state, [0] - 1 = busy, 0 = idle
|
||||
; Bits [5:0] - 0 = Reset parameters.
|
||||
; 1 = Clear to val. Start Location (16 bit), End Location (16 bit), Red Filter, Green Filter, Blue Filter
|
||||
;
|
||||
VMCTRL EQU 0B8H ; Video Module control register. [2:0] - 000 (default) = MZ80A, 001 = MZ-700, 010 = MZ800, 011 = MZ80B, 100 = MZ80K, 101 = MZ80C, 110 = MZ1200, 111 = MZ2000. [3] = 0 - 40 col, 1 - 80 col.
|
||||
VMGRMODE EQU 0B9H ; Video Module graphics mode. 7/6 = Operator (00=OR,01=AND,10=NAND,11=XOR), 5=GRAM Output Enable, 4 = VRAM Output Enable, 3/2 = Write mode (00=Page 1:Red, 01=Page 2:Green, 10=Page 3:Blue, 11=Indirect), 1/0=Read mode (00=Page 1:Red, 01=Page2:Green, 10=Page 3:Blue, 11=Not used).
|
||||
VMREDMASK EQU 0BAH ; Video Module Red bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
||||
VMGREENMASK EQU 0BBH ; Video Module Green bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
||||
VMBLUEMASK EQU 0BCH ; Video Module Blue bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
||||
VMPAGE EQU 0BDH ; Video Module memory page register. [1:0] switches in 1 16Kb page (3 pages) of graphics ram to C000 - FFFF. Bits [1:0] = page, 00 = off, 01 = Red, 10 = Green, 11 = Blue. This overrides all MZ700/MZ80B page switching functions. [7] 0 - normal, 1 - switches in CGROM for upload at D000:DFFF.
|
||||
VMVGATTR EQU 0BEH ; Select VGA Border colour and attributes. Bit 2 = Red, 1 = Green, 0 = Blue.
|
||||
VMVGAMODE EQU 0BFH ; Select VGA output mode. Bits [3:0] - Output mode.
|
||||
|
||||
GDCRTC EQU 0CFH ; MZ-800 CRTC control register
|
||||
GDCMD EQU 0CEH ; MZ-800 CRTC Mode register
|
||||
GDGRF EQU 0CDH ; MZ-800 read format register
|
||||
GDGWF EQU 0CCH ; MZ-800 write format register
|
||||
MMIO0 EQU 0E0H ; MZ-700/MZ-800 Memory Management Set 0
|
||||
MMIO1 EQU 0E1H ; MZ-700/MZ-800 Memory Management Set 1
|
||||
MMIO2 EQU 0E2H ; MZ-700/MZ-800 Memory Management Set 2
|
||||
MMIO3 EQU 0E3H ; MZ-700/MZ-800 Memory Management Set 3
|
||||
MMIO4 EQU 0E4H ; MZ-700/MZ-800 Memory Management Set 4
|
||||
MMIO5 EQU 0E5H ; MZ-700/MZ-800 Memory Management Set 5
|
||||
MMIO6 EQU 0E6H ; MZ-700/MZ-800 Memory Management Set 6
|
||||
MMIO7 EQU 0E7H ; MZ-700/MZ-800 Memory Management Set 7
|
||||
SYSCTRL EQU 0F0H ; System board control register. [2:0] - 000 MZ80A Mode, 2MHz CPU/Bus, 001 MZ80B Mode, 4MHz CPU/Bus, 010 MZ700 Mode, 3.54MHz CPU/Bus.
|
||||
GRAMMODE EQU 0F4H ; MZ80B Graphics mode. Bit 0 = 0, Write to Graphics RAM I, Bit 0 = 1, Write to Graphics RAM II. Bit 1 = 1, blend Graphics RAM I output on display, Bit 2 = 1, blend Graphics RAM II output on display.
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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
|
||||
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
|
||||
|
||||
; 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.
|
||||
|
||||
;
|
||||
;-----------------------------------------------
|
||||
; CPLD Configuration constants.
|
||||
;-----------------------------------------------
|
||||
MODE_MZ80K EQU 0 ; Set to MZ-80K mode.
|
||||
MODE_MZ80C EQU 1 ; Set to MZ-80C mode.
|
||||
MODE_MZ1200 EQU 2 ; Set to MZ-1200 mode.
|
||||
MODE_MZ80A EQU 3 ; Set to MZ-80A mode (base mode on MZ-80A hardware).
|
||||
MODE_MZ700 EQU 4 ; Set to MZ-700 mode (base mode on MZ-700 hardware).
|
||||
MODE_MZ800 EQU 5 ; Set to MZ-800 mode.
|
||||
MODE_MZ80B EQU 6 ; Set to MZ-80B mode.
|
||||
MODE_MZ2000 EQU 7 ; Set to MZ-2000 mode.
|
||||
MODE_VIDEO_FPGA EQU 8 ; Bit flag (bit 3) to switch CPLD into using the new FPGA video hardware.
|
||||
MODE_RESET_PRESERVE EQU 080H ; Preserve register configuration through reset.
|
||||
|
||||
;-----------------------------------------------
|
||||
; CPLD Command Instruction constants.
|
||||
;-----------------------------------------------
|
||||
CPLD_RESET_HOST EQU 1 ; CPLD level command to reset the host system.
|
||||
CPLD_HOLD_HOST_BUS EQU 2 ; CPLD command to hold the host bus.
|
||||
CPLD_RELEASE_HOST_BUS EQU 3 ; CPLD command to release the host bus.
|
||||
|
||||
;-----------------------------------------------
|
||||
; FPGA CPU enhancement control bits.
|
||||
;-----------------------------------------------
|
||||
CPUMODE_SET_Z80 EQU 000H ; Set the CPU to the hard Z80.
|
||||
CPUMODE_SET_T80 EQU 001H ; Set the CPU to the soft T80.
|
||||
CPUMODE_SET_ZPU_EVO EQU 002H ; Set the CPU to the soft ZPU Evolution.
|
||||
CPUMODE_SET_AAA EQU 004H ; Place holder for a future soft CPU.
|
||||
CPUMODE_SET_BBB EQU 008H ; Place holder for a future soft CPU.
|
||||
CPUMODE_SET_CCC EQU 010H ; Place holder for a future soft CPU.
|
||||
CPUMODE_SET_DDD EQU 020H ; Place holder for a future soft CPU.
|
||||
CPUMODE_IS_Z80 EQU 000H ; Status value to indicate if the hard Z80 available.
|
||||
CPUMODE_IS_T80 EQU 001H ; Status value to indicate if the soft T80 available.
|
||||
CPUMODE_IS_ZPU_EVO EQU 002H ; Status value to indicate if the soft ZPU Evolution available.
|
||||
CPUMODE_IS_AAA EQU 004H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_IS_BBB EQU 008H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_IS_CCC EQU 010H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_IS_DDD EQU 020H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_RESET_CPU EQU 080H ; Reset the soft CPU. Active high, when high the CPU is held in RESET, when low the CPU runs.
|
||||
CPUMODE_IS_SOFT_AVAIL EQU 040H ; Marker to indicate if the underlying FPGA can support soft CPU's.
|
||||
CPUMODE_IS_SOFT_MASK EQU 0C0H ; Mask to filter out the Soft CPU availability flags.
|
||||
CPUMODE_IS_CPU_MASK EQU 03FH ; Mask to filter out which soft CPU's are available.
|
||||
|
||||
;-----------------------------------------------
|
||||
; Video Module control bits.
|
||||
;-----------------------------------------------
|
||||
MODE_80CHAR EQU 010H ; Enable 80 character display.
|
||||
MODE_COLOUR EQU 020H ; Enable colour display.
|
||||
SYSMODE_MZ80A EQU 000H ; System board mode MZ80A, 2MHz CPU/Bus.
|
||||
SYSMODE_MZ80B EQU 020H ; System board mode MZ80B, 4MHz CPU/Bus.
|
||||
SYSMODE_MZ2000 EQU 020H ; System board mode MZ2000, 4MHz CPU/Bus.
|
||||
SYSMODE_MZ700 EQU 042H ; System board mode MZ700, 3.54MHz CPU/Bus.
|
||||
VMMODE_MZ80K EQU 000H ; Video mode = MZ80K
|
||||
VMMODE_MZ80C EQU 001H ; Video mode = MZ80C
|
||||
VMMODE_MZ1200 EQU 002H ; Video mode = MZ1200
|
||||
VMMODE_MZ80A EQU 003H ; Video mode = MZ80A
|
||||
VMMODE_MZ700 EQU 004H ; Video mode = MZ700
|
||||
VMMODE_MZ800 EQU 005H ; Video mode = MZ800
|
||||
VMMODE_MZ1500 EQU 006H ; Video mode = MZ1500
|
||||
VMMODE_MZ80B EQU 007H ; Video mode = MZ80B
|
||||
VMMODE_MZ2000 EQU 008H ; Video mode = MZ2000
|
||||
VMMODE_MZ2200 EQU 009H ; Video mode = MZ2200
|
||||
VMMODE_MZ2500 EQU 00AH ; Video mode = MZ2500
|
||||
VMMODE_PCGRAM EQU 020H ; Enable PCG RAM.
|
||||
VMMODE_VGA_OFF EQU 000H ; Set VGA mode off, external monitor is driven by standard internal 60Hz signals.
|
||||
VMMODE_VGA_INT EQU 000H ; Set VGA mode off, external monitor is driven by standard internal 60Hz signals.
|
||||
VMMODE_VGA_INT50 EQU 001H ; Set VGA mode off, external monitor is driven by standard internal 50Hz signals.
|
||||
VMMODE_VGA_640x480 EQU 002H ; Set external monitor to VGA 640x480 @ 60Hz mode.
|
||||
VMMODE_VGA_800x600 EQU 003H ; Set external monitor to VGA 800x600 @ 60Hz mode.
|
||||
|
||||
;-----------------------------------------------
|
||||
; GPU commands.
|
||||
;-----------------------------------------------
|
||||
GPUCLEARVRAM EQU 001H ; Clear the VRAM without updating attributes.
|
||||
GPUCLEARVRAMCA EQU 002H ; Clear the VRAM/ARAM with given attribute byte,
|
||||
GPUCLEARVRAMP EQU 003H ; Clear the VRAM/ARAM with parameters.
|
||||
GPUCLEARGRAM EQU 081H ; Clear the entire Framebuffer.
|
||||
GPUCLEARGRAMP EQU 082H ; Clear the Framebuffer according to parameters.
|
||||
GPURESET EQU 0FFH ; Reset the GPU, return to idle state.
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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, F3FE:F3FF & F7FE:F7FF (floppy disk paging vectors) which resides on the mainboard.
|
||||
TZMM_COMPAT EQU 008H ; TZMM_ENIOWAIT ; Original mode but with main DRAM in Bank 0 to allow bootstrapping of programs from other machines such as the MZ700.
|
||||
TZMM_HOSTACCESS EQU 009H ; TZMM_ENIOWAIT ; Mode to allow code running in Bank 0, address E800:FFFF to access host memory. Monitor ROM 0000-0FFF and Main DRAM 0x1000-0xD000, video and memory mapped I/O are on the host machine, User/Floppy ROM E800-FFFF are in tranZPUter memory.
|
||||
TZMM_MZ700_0 EQU 00AH ; TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the mainboard.
|
||||
TZMM_MZ700_1 EQU 00BH ; TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
|
||||
TZMM_MZ700_2 EQU 00CH ; TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
|
||||
TZMM_MZ700_3 EQU 00DH ; TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
|
||||
TZMM_MZ700_4 EQU 00EH ; TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
|
||||
TZMM_MZ800 EQU 00FH ; TZMM_ENIOWAIT ; MZ800 Mode - Tracks original hardware mode offering MZ700/MZ800 configurations.
|
||||
TZMM_MZ2000 EQU 010H + TZMM_ENIOWAIT; ; MZ2000 Mode - Running on MZ2000 hardware, configuration set according to runtime configuration registers.
|
||||
TZMM_FPGA EQU 015H ; TZMM_ENIOWAIT ; Open up access for the K64F to the FPGA resources such as memory. All other access to RAM or mainboard is blocked.
|
||||
TZMM_TZPUM EQU 016H ; TZMM_ENIOWAIT ; Everything in on mainboard, no access to tranZPUter memory.
|
||||
TZMM_TZPU EQU 017H ; TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
|
||||
;TZMM_TZPU0 EQU 018H ; TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
|
||||
;TZMM_TZPU1 EQU 019H ; TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 1 is selected.
|
||||
;TZMM_TZPU2 EQU 01AH ; TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 2 is selected.
|
||||
;TZMM_TZPU3 EQU 01BH ; TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 3 is selected.
|
||||
;TZMM_TZPU4 EQU 01CH ; TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 4 is selected.
|
||||
;TZMM_TZPU5 EQU 01DH ; TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 5 is selected.
|
||||
;TZMM_TZPU6 EQU 01EH ; TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 6 is selected.
|
||||
;TZMM_TZPU7 EQU 01FH ; TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 7 is selected.
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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
|
||||
|
||||
;
|
||||
; CPM constants
|
||||
;
|
||||
CPM_SD_SEC EQU 32
|
||||
CPM_SD_TRK EQU 1024
|
||||
CPM_SD_IMGSZ EQU CPM_SD_TRK * CPM_SD_SEC * SD_SECSIZE
|
||||
|
||||
;-----------------------------------------------
|
||||
; BIOS WORK AREA (MZ80A)
|
||||
;-----------------------------------------------
|
||||
TZVARMEM: EQU 0F4A0H
|
||||
TZSVCMEM: EQU 0F560H ; Start of a memory structure used to communicate with the K64F I/O processor for services such as disk access.
|
||||
TZSVCSIZE: EQU 00280H ;
|
||||
TZSVCDIRSZ: EQU 20 ; Size of the directory/file name.
|
||||
TZSVCFILESZ: EQU 17 ; Size of a Sharp filename.
|
||||
TZSVCLONGFILESZ: EQU 31 ; Size of a standard filename.
|
||||
TZSVCLONGFMTSZ: EQU 20 ; Size of a formatted standard filename for use in directory listings.
|
||||
TZSVCWILDSZ: EQU 20 ; Size of the wildcard.
|
||||
TZSVCSECSIZE: EQU 512
|
||||
TZSVCDIR_ENTSZ: EQU 32 ; Size of a directory entry.
|
||||
TZSVCWAITIORETRIES: EQU 500 ; Wait retries for IO response.
|
||||
TZSVCWAITCOUNT: EQU 65535 ; Wait retries for IO request response.
|
||||
TZSVC_FTYPE_MZF: EQU 0 ; File type being handled is an MZF
|
||||
TZSVC_FTYPE_MZFHDR: EQU 1 ; File type being handled is an MZF Header.
|
||||
TZSVC_FTYPE_CAS: EQU 2 ; File type being handled is an CASsette BASIC script.
|
||||
TZSVC_FTYPE_BAS: EQU 3 ; 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.
|
||||
|
||||
TZSVC_CMD_READDIR EQU 01H ; Service command to open a directory and return the first block of entries.
|
||||
TZSVC_CMD_NEXTDIR EQU 02H ; Service command to return the next block of an open directory.
|
||||
TZSVC_CMD_READFILE EQU 03H ; Service command to open a file and return the first block.
|
||||
TZSVC_CMD_NEXTREADFILE EQU 04H ; Service command to return the next block of an open file.
|
||||
TZSVC_CMD_WRITEFILE EQU 05H ; Service command to create a file and save the first block.
|
||||
TZSVC_CMD_NEXTWRITEFILE EQU 06H ; Service command to write the next block to the open file.
|
||||
TZSVC_CMD_CLOSE EQU 07H ; Service command to close any open file or directory.
|
||||
TZSVC_CMD_LOADFILE EQU 08H ; Service command to load a file directly into tranZPUter memory.
|
||||
TZSVC_CMD_SAVEFILE EQU 09H ; Service command to save a file directly from tranZPUter memory.
|
||||
TZSVC_CMD_ERASEFILE EQU 0aH ; Service command to erase a file on the SD card.
|
||||
TZSVC_CMD_CHANGEDIR EQU 0bH ; Service command to change the active directory on the SD card.
|
||||
TZSVC_CMD_LOAD40ABIOS EQU 20H ; Service command requesting that the 40 column version of the SA1510 BIOS is loaded.
|
||||
TZSVC_CMD_LOAD80ABIOS EQU 21H ; Service command requesting that the 80 column version of the SA1510 BIOS is loaded.
|
||||
TZSVC_CMD_LOAD700BIOS40 EQU 22H ; Service command requesting that the MZ700 1Z-013A 40 column BIOS is loaded.
|
||||
TZSVC_CMD_LOAD700BIOS80 EQU 23H ; Service command requesting that the MZ700 1Z-013A 80 column patched BIOS is loaded.
|
||||
TZSVC_CMD_LOAD80BIPL EQU 24H ; Service command requesting the MZ-80B IPL is loaded.
|
||||
TZSVC_CMD_LOAD800BIOS EQU 25H ; Service command requesting that the MZ800 9Z-504M BIOS is loaded.
|
||||
TZSVC_CMD_LOAD2000IPL EQU 26H ; Service command requesting the MZ-2000 IPL is loaded.
|
||||
TZSVC_CMD_LOADTZFS EQU 2FH ; Service command requesting the loading of TZFS. This service is for machines which normally dont have a monitor BIOS. ie. MZ-80B/MZ-2000 and manually request TZFS.
|
||||
TZSVC_CMD_LOADBDOS EQU 30H ; Service command to reload CPM BDOS+CCP.
|
||||
TZSVC_CMD_ADDSDDRIVE EQU 31H ; Service command to attach a CPM disk to a drive number.
|
||||
TZSVC_CMD_READSDDRIVE EQU 32H ; Service command to read an attached SD file as a CPM disk drive.
|
||||
TZSVC_CMD_WRITESDDRIVE EQU 33H ; Service command to write to a CPM disk drive which is an attached SD file.
|
||||
TZSVC_CMD_CPU_BASEFREQ EQU 40H ; Service command to switch to the mainboard frequency.
|
||||
TZSVC_CMD_CPU_ALTFREQ EQU 41H ; Service command to switch to the alternate frequency provided by the K64F.
|
||||
TZSVC_CMD_CPU_CHGFREQ EQU 42H ; Service command to set the alternate frequency in hertz.
|
||||
TZSVC_CMD_CPU_SETZ80 EQU 50H ; Service command to switch to the external Z80 hard cpu.
|
||||
TZSVC_CMD_CPU_SETT80 EQU 51H ; Service command to switch to the internal T80 soft cpu.
|
||||
TZSVC_CMD_CPU_SETZPUEVO EQU 52H ; Service command to switch to the internal ZPU Evolution soft cpu.
|
||||
TZSVC_CMD_EMU_SETMZ80K EQU 53H ; Service command to switch to the internal Sharp MZ Series Emulation of the MZ80K.
|
||||
TZSVC_CMD_EMU_SETMZ80C EQU 54H ; "" "" "" MZ80C.
|
||||
TZSVC_CMD_EMU_SETMZ1200 EQU 55H ; "" "" "" MZ1200.
|
||||
TZSVC_CMD_EMU_SETMZ80A EQU 56H ; "" "" "" MZ80A.
|
||||
TZSVC_CMD_EMU_SETMZ700 EQU 57H ; "" "" "" MZ700.
|
||||
TZSVC_CMD_EMU_SETMZ800 EQU 58H ; "" "" "" MZ800.
|
||||
TZSVC_CMD_EMU_SETMZ1500 EQU 59H ; "" "" "" MZ1500.
|
||||
TZSVC_CMD_EMU_SETMZ80B EQU 5AH ; "" "" "" MZ80B.
|
||||
TZSVC_CMD_EMU_SETMZ2000 EQU 5BH ; "" "" "" MZ2000.
|
||||
TZSVC_CMD_EMU_SETMZ2200 EQU 5CH ; "" "" "" MZ2200.
|
||||
TZSVC_CMD_EMU_SETMZ2500 EQU 5DH ; "" "" "" MZ2500.
|
||||
TZSVC_CMD_EXIT EQU 07FH ; Service command to terminate TZFS and restart the machine in original mode.
|
||||
TZSVC_STATUS_OK EQU 000H ; Flag to indicate the K64F processing completed successfully.
|
||||
TZSVC_STATUS_REQUEST EQU 0FEH ; Flag to indicate the Z80 has made a request to the K64F.
|
||||
TZSVC_STATUS_PROCESSING EQU 0FFH ; Flag to indicate the K64F is processing a command.
|
||||
152
software/asm/include/macros.asm
Normal file
152
software/asm/include/macros.asm
Normal file
@@ -0,0 +1,152 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;-
|
||||
;- Name: Macros.asm
|
||||
;- Created: July 2019
|
||||
;- Author(s): Philip Smart
|
||||
;- Description: Z80 Assembler Macros Library
|
||||
;- This is an aassembly language macro source file containing resusable code in the form
|
||||
; of Macros for the various Z80 projects under development.
|
||||
;- Credits:
|
||||
;- Copyright: (c) 2018-2020 Philip Smart <philip.smart@net2net.org>
|
||||
;-
|
||||
;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW.
|
||||
;-
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;- 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/>.
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
|
||||
; 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
|
||||
|
||||
; Macro to create a Jump table entry point for a Bank to Bank function call.
|
||||
; The address of the real function in the required page is given as ?addr
|
||||
; and the bank in which it will reside is given in ?bank. The logic then takes
|
||||
; care of stack and memory mode manipulation to call the method and return to the
|
||||
; caller with all registers unaffected going to the called function and returning from
|
||||
; the called function. This allows any method to be placed in a bank as space dictates.
|
||||
CALLBNK: MACRO ?addr, ?bank
|
||||
EXX
|
||||
EX AF,AF'
|
||||
LD HL,?addr ; Real function to call.
|
||||
LD A,?bank ; Bank in which the function resides.
|
||||
JP BANKTOBANK_
|
||||
ENDM
|
||||
|
||||
; As above but just jump to the required location in the alternate bank, no return.
|
||||
JMPBNK: MACRO ?addr, ?bank
|
||||
EX AF,AF'
|
||||
LD A,?bank ; Bank in which the function resides.
|
||||
LD (MMCFGVAL),A ; Store the value in a memory variable as we cant read the latch once programmed.
|
||||
OUT (MMCFG),A ; Switch to the TZFS memory mode, SA1510 is now in RAM at 0000H
|
||||
EX AF,AF'
|
||||
LD HL,?addr ; Real function to jump to.
|
||||
JP (HL)
|
||||
ENDM
|
||||
|
||||
; Method to allow one bank to call a routine in another bank with all registers preserved in and out and
|
||||
; reentrant so banks can call banks. It is costly in processing time and should only be
|
||||
; used infrequently.
|
||||
;
|
||||
; Input: A = Memory mode to switch into.
|
||||
; (HLSAVE)= Original HL to pass to caller.
|
||||
; HL = Address to call.
|
||||
; AF = Stored on stack to pass to called function.
|
||||
; All other registers passed to called function.
|
||||
; All registers are passed untouched to the caller.
|
||||
; Stack; BKTOBKRET:AF (original memory mode) : Caller return address.
|
||||
; Output: All registers and flags returned to caller.
|
||||
;
|
||||
JMPTOBNK: MACRO
|
||||
LD (FNADDR),HL ; Save the function to call address stored in HL
|
||||
LD L,A ; Save A to retrieve the old Memory mode and push it on the stack so it can be restored after return.
|
||||
LD A,(MMCFGVAL)
|
||||
PUSH AF
|
||||
LD A,L
|
||||
; NB. Dont disable interrupts, goes to mode 7 then returns to MMCFGVAL,so apart from a double switch there should be no race state.
|
||||
LD (MMCFGVAL),A ; Store the value in a memory variable as we cant read the latch once programmed.
|
||||
OUT (MMCFG),A ; Switch to the TZFS memory mode, SA1510 is now in RAM at 0000H
|
||||
LD HL,BKTOBKRET ; Store the return address which must come back to this functionality before original caller.
|
||||
PUSH HL
|
||||
LD HL,(FNADDR) ; Push the address of the function to call onto the stack.
|
||||
PUSH HL
|
||||
EXX
|
||||
EX AF,AF'
|
||||
RET ; Call the required function by popping address off stack.
|
||||
BKTOBKRET: EX (SP),HL ; Retrieve original memory mode from stack.
|
||||
EX AF,AF'
|
||||
LD A,H
|
||||
LD (MMCFGVAL),A ; Store the value in a memory variable as we cant read the latch once programmed.
|
||||
OUT (MMCFG),A ; Switch to the TZFS memory mode, SA1510 is now in RAM at 0000H
|
||||
EX AF,AF'
|
||||
POP HL ; Restore HL.
|
||||
RET
|
||||
ENDM
|
||||
|
||||
; Alternate version which preserves caller stack and creates local stack, used in CPM where the caller (CPM) has a tiny stack
|
||||
; and the CBIOS needs more space. This version isnt reentrant, it is only used one way, CPM -> CBIOS.
|
||||
JMPTOBNK2: MACRO
|
||||
LD (STKSAVE),SP
|
||||
LD SP,CBIOSSTACK
|
||||
LD (FNADDR),HL ; Save the function to call address stored in HL
|
||||
; NB. Dont disable interrupts, goes to mode 7 then returns to MMCFGVAL,so apart from a double switch there should be no race state.
|
||||
LD A,TZMM_CPM2
|
||||
LD (MMCFGVAL),A ; Store the value in a memory variable as we cant read the latch once programmed.
|
||||
OUT (MMCFG),A ; Switch to the TZFS memory mode, SA1510 is now in RAM at 0000H
|
||||
LD HL,BKTOBKRET2 ; Store the return address which must come back to this functionality before original caller.
|
||||
PUSH HL
|
||||
LD HL,(FNADDR) ; Push the address of the function to call onto the stack.
|
||||
PUSH HL
|
||||
EXX
|
||||
EX AF,AF'
|
||||
RET ; Call the required function by popping address off stack.
|
||||
BKTOBKRET2: EX AF,AF'
|
||||
LD A,TZMM_CPM
|
||||
LD (MMCFGVAL),A ; Store the value in a memory variable as we cant read the latch once programmed.
|
||||
OUT (MMCFG),A ; Switch to the TZFS memory mode, SA1510 is now in RAM at 0000H
|
||||
EX AF,AF'
|
||||
LD SP,(STKSAVE)
|
||||
RET
|
||||
ENDM
|
||||
1
software/asm/include/msbasic_buildversion.asm
Normal file
1
software/asm/include/msbasic_buildversion.asm
Normal file
@@ -0,0 +1 @@
|
||||
BUILD_VERSION EQU 3
|
||||
534
software/asm/include/msbasic_definitions.asm
Normal file
534
software/asm/include/msbasic_definitions.asm
Normal file
@@ -0,0 +1,534 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;-
|
||||
;- 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-20 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 backport changes from the RFS version after v2.1 hw changes.
|
||||
;
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;- 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.
|
||||
|
||||
; MZ-80A Standard Machine Configuration.
|
||||
IF BUILD_VERSION = 0
|
||||
BUILD_MZ80A EQU 1 ; Build for the standard Sharp MZ80A, no lower memory. Manually change MAXMEM above.
|
||||
BUILD_MZ700 EQU 0 ; Build for the Sharp MZ-700 base hardware.
|
||||
BUILD_MZ80A_TZFS EQU 0 ; Build for TZFS running on an MZ-80A where extended memory is available.
|
||||
BUILD_MZ700_TZFS EQU 0 ; Build for TZFS running on an MZ-700 where extended memory is available.
|
||||
BUILD_VIDEOMODULE EQU 0 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0
|
||||
BUILD_80C EQU 0
|
||||
INCLUDE_ANSITERM EQU 1 ; Include the Ansi terminal emulation processor in the build.
|
||||
ENDIF
|
||||
; MZ-700 Standard Machine Configuration.
|
||||
IF BUILD_VERSION = 1
|
||||
BUILD_MZ80A EQU 0
|
||||
BUILD_MZ700 EQU 1 ; Build for the Sharp MZ-700 base hardware.
|
||||
BUILD_MZ80A_TZFS EQU 0 ; Build for TZFS running on an MZ-80A where extended memory is available.
|
||||
BUILD_MZ700_TZFS EQU 0 ; Build for TZFS running on an MZ-700 where extended memory is available.
|
||||
BUILD_VIDEOMODULE EQU 0 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0
|
||||
BUILD_80C EQU 0
|
||||
INCLUDE_ANSITERM EQU 1 ; Include the Ansi terminal emulation processor in the build.
|
||||
ENDIF
|
||||
; TZFS Enhanced MZ-80A/MZ-700 with no video card upgrade.
|
||||
IF BUILD_VERSION = 2
|
||||
BUILD_MZ80A EQU 0
|
||||
BUILD_MZ700 EQU 0 ; Build for the Sharp MZ-700 base hardware.
|
||||
BUILD_MZ80A_TZFS EQU 0 ; Build for TZFS running on an MZ-80A where extended memory is available.
|
||||
BUILD_MZ700_TZFS EQU 1 ; Build for TZFS running on an MZ-700 where extended memory is available.
|
||||
BUILD_VIDEOMODULE EQU 0 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0
|
||||
BUILD_80C EQU 0
|
||||
INCLUDE_ANSITERM EQU 1 ; Include the Ansi terminal emulation processor in the build.
|
||||
ENDIF
|
||||
; TZFS Enhanced MZ-80A/MZ-700 with VideoModule (or 40/80 Colour Board on MZ-80A).
|
||||
IF BUILD_VERSION = 3
|
||||
BUILD_MZ700 EQU 0 ; Build for the Sharp MZ-700 base hardware.
|
||||
BUILD_MZ80A EQU 0
|
||||
BUILD_MZ80A_TZFS EQU 0 ; Build for TZFS running on an MZ-80A where extended memory is available.
|
||||
BUILD_MZ700_TZFS EQU 1 ; Build for TZFS running on an MZ-700 where extended memory is available.
|
||||
BUILD_VIDEOMODULE EQU 1 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0
|
||||
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.
|
||||
ELSE
|
||||
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
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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
|
||||
|
||||
;-----------------------------------------------
|
||||
; IO ports in hardware and values.
|
||||
;-----------------------------------------------
|
||||
MMCFG EQU 060H ; Memory management configuration latch.
|
||||
SETXMHZ EQU 062H ; Select the alternate clock frequency.
|
||||
SET2MHZ EQU 064H ; Select the system 2MHz clock frequency.
|
||||
CLKSELRD EQU 066H ; Read clock selected setting, 0 = 2MHz, 1 = XMHz
|
||||
SVCREQ EQU 068H ; I/O Processor service request.
|
||||
CPLDSTATUS EQU 06BH ; Version 2.1 CPLD status register.
|
||||
CPUCFG EQU 06CH ; Version 2.2 CPU configuration register.
|
||||
CPUSTATUS EQU 06CH ; Version 2.2 CPU runtime status register.
|
||||
CPUINFO EQU 06DH ; Version 2.2 CPU information register.
|
||||
CPLDCFG EQU 06EH ; Version 2.1 CPLD configuration register.
|
||||
CPLDINFO EQU 06FH ; Version 2.1 CPLD version information register.
|
||||
VMPNUM EQU 0A0H ; Set the parameter number to update.
|
||||
VMPLBYTE EQU 0A1H ; Update the lower selected parameter byte.
|
||||
VMPUBYTE EQU 0A2H ; Update the upper selected parameter byte.
|
||||
PALSLCTOFF EQU 0A3H ; set the palette slot Off position to be adjusted.
|
||||
PALSLCTON EQU 0A4H ; set the palette slot On position to be adjusted.
|
||||
PALSETRED EQU 0A5H ; set the red palette value according to the PALETTE_PARAM_SEL address.
|
||||
PALSETGREEN EQU 0A6H ; set the green palette value according to the PALETTE_PARAM_SEL address.
|
||||
PALSETBLUE EQU 0A7H ; set the blue palette value according to the PALETTE_PARAM_SEL address.
|
||||
VMPALETTE EQU 0B0H ; Select Palette:
|
||||
; 0xB0 sets the palette. The Video Module supports 4 bit per colour output but there is only enough RAM for 1 bit per colour so the pallette is used to change the colours output.
|
||||
; Bits [7:0] defines the pallete number. This indexes a lookup table which contains the required 4bit output per 1bit input.
|
||||
; GPU:
|
||||
GPUPARAM EQU 0B2H ; 0xB2 set parameters. Store parameters in a long word to be used by the graphics command processor.
|
||||
; The parameter word is 128 bit and each write to the parameter word shifts left by 8 bits and adds the new byte at bits 7:0.
|
||||
GPUCMD EQU 0B3H ; 0xB3 set the graphics processor unit commands.
|
||||
GPUSTATUS EQU 0B3H ; [7;1] - FSM state, [0] - 1 = busy, 0 = idle
|
||||
; Bits [5:0] - 0 = Reset parameters.
|
||||
; 1 = Clear to val. Start Location (16 bit), End Location (16 bit), Red Filter, Green Filter, Blue Filter
|
||||
;
|
||||
VMCTRL EQU 0B8H ; Video Module control register. [2:0] - 000 (default) = MZ80A, 001 = MZ-700, 010 = MZ800, 011 = MZ80B, 100 = MZ80K, 101 = MZ80C, 110 = MZ1200, 111 = MZ2000. [3] = 0 - 40 col, 1 - 80 col.
|
||||
VMGRMODE EQU 0B9H ; Video Module graphics mode. 7/6 = Operator (00=OR,01=AND,10=NAND,11=XOR), 5=GRAM Output Enable, 4 = VRAM Output Enable, 3/2 = Write mode (00=Page 1:Red, 01=Page 2:Green, 10=Page 3:Blue, 11=Indirect), 1/0=Read mode (00=Page 1:Red, 01=Page2:Green, 10=Page 3:Blue, 11=Not used).
|
||||
VMREDMASK EQU 0BAH ; Video Module Red bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
||||
VMGREENMASK EQU 0BBH ; Video Module Green bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
||||
VMBLUEMASK EQU 0BCH ; Video Module Blue bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
||||
VMPAGE EQU 0BDH ; Video Module memory page register. [1:0] switches in 1 16Kb page (3 pages) of graphics ram to C000 - FFFF. Bits [1:0] = page, 00 = off, 01 = Red, 10 = Green, 11 = Blue. This overrides all MZ700/MZ80B page switching functions. [7] 0 - normal, 1 - switches in CGROM for upload at D000:DFFF.
|
||||
VMVGATTR EQU 0BEH ; Select VGA Border colour and attributes. Bit 2 = Red, 1 = Green, 0 = Blue.
|
||||
VMVGAMODE EQU 0BFH ; Select VGA output mode. Bits [3:0] - Output mode.
|
||||
GDCRTC EQU 0CFH ; MZ-800 CRTC control register
|
||||
GDCMD EQU 0CEH ; MZ-800 CRTC Mode register
|
||||
GDGRF EQU 0CDH ; MZ-800 read format register
|
||||
GDGWF EQU 0CCH ; MZ-800 write format register
|
||||
MMIO0 EQU 0E0H ; MZ-700/MZ-800 Memory Management Set 0
|
||||
MMIO1 EQU 0E1H ; MZ-700/MZ-800 Memory Management Set 1
|
||||
MMIO2 EQU 0E2H ; MZ-700/MZ-800 Memory Management Set 2
|
||||
MMIO3 EQU 0E3H ; MZ-700/MZ-800 Memory Management Set 3
|
||||
MMIO4 EQU 0E4H ; MZ-700/MZ-800 Memory Management Set 4
|
||||
MMIO5 EQU 0E5H ; MZ-700/MZ-800 Memory Management Set 5
|
||||
MMIO6 EQU 0E6H ; MZ-700/MZ-800 Memory Management Set 6
|
||||
MMIO7 EQU 0E7H ; MZ-700/MZ-800 Memory Management Set 7
|
||||
SYSCTRL EQU 0F0H ; System board control register. [2:0] - 000 MZ80A Mode, 2MHz CPU/Bus, 001 MZ80B Mode, 4MHz CPU/Bus, 010 MZ700 Mode, 3.54MHz CPU/Bus.
|
||||
GRAMMODE EQU 0F4H ; MZ80B Graphics mode. Bit 0 = 0, Write to Graphics RAM I, Bit 0 = 1, Write to Graphics RAM II. Bit 1 = 1, blend Graphics RAM I output on display, Bit 2 = 1, blend Graphics RAM II output on display.
|
||||
|
||||
;-----------------------------------------------
|
||||
; CPLD Configuration constants.
|
||||
;-----------------------------------------------
|
||||
MODE_MZ80K EQU 0 ; Set to MZ-80K mode.
|
||||
MODE_MZ80C EQU 1 ; Set to MZ-80C mode.
|
||||
MODE_MZ1200 EQU 2 ; Set to MZ-1200 mode.
|
||||
MODE_MZ80A EQU 3 ; Set to MZ-80A mode (base mode on MZ-80A hardware).
|
||||
MODE_MZ700 EQU 4 ; Set to MZ-700 mode (base mode on MZ-700 hardware).
|
||||
MODE_MZ800 EQU 5 ; Set to MZ-800 mode.
|
||||
MODE_MZ80B EQU 6 ; Set to MZ-80B mode.
|
||||
MODE_MZ2000 EQU 7 ; Set to MZ-2000 mode.
|
||||
MODE_VIDEO_FPGA EQU 8 ; Bit flag (bit 3) to switch CPLD into using the new FPGA video hardware.
|
||||
MODE_RESET_PRESERVE EQU 080H ; Preserve register configuration through reset.
|
||||
|
||||
;-----------------------------------------------
|
||||
; CPLD Command Instruction constants.
|
||||
;-----------------------------------------------
|
||||
CPLD_RESET_HOST EQU 1 ; CPLD level command to reset the host system.
|
||||
CPLD_HOLD_HOST_BUS EQU 2 ; CPLD command to hold the host bus.
|
||||
CPLD_RELEASE_HOST_BUS EQU 3 ; CPLD command to release the host bus.
|
||||
|
||||
;-----------------------------------------------
|
||||
; FPGA CPU enhancement control bits.
|
||||
;-----------------------------------------------
|
||||
CPUMODE_SET_Z80 EQU 000H ; Set the CPU to the hard Z80.
|
||||
CPUMODE_SET_T80 EQU 001H ; Set the CPU to the soft T80.
|
||||
CPUMODE_SET_ZPU_EVO EQU 002H ; Set the CPU to the soft ZPU Evolution.
|
||||
CPUMODE_SET_AAA EQU 004H ; Place holder for a future soft CPU.
|
||||
CPUMODE_SET_BBB EQU 008H ; Place holder for a future soft CPU.
|
||||
CPUMODE_SET_CCC EQU 010H ; Place holder for a future soft CPU.
|
||||
CPUMODE_SET_DDD EQU 020H ; Place holder for a future soft CPU.
|
||||
CPUMODE_IS_Z80 EQU 000H ; Status value to indicate if the hard Z80 available.
|
||||
CPUMODE_IS_T80 EQU 001H ; Status value to indicate if the soft T80 available.
|
||||
CPUMODE_IS_ZPU_EVO EQU 002H ; Status value to indicate if the soft ZPU Evolution available.
|
||||
CPUMODE_IS_AAA EQU 004H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_IS_BBB EQU 008H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_IS_CCC EQU 010H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_IS_DDD EQU 020H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_RESET_CPU EQU 080H ; Reset the soft CPU. Active high, when high the CPU is held in RESET, when low the CPU runs.
|
||||
CPUMODE_IS_SOFT_AVAIL EQU 040H ; Marker to indicate if the underlying FPGA can support soft CPU's.
|
||||
CPUMODE_IS_SOFT_MASK EQU 0C0H ; Mask to filter out the Soft CPU availability flags.
|
||||
CPUMODE_IS_CPU_MASK EQU 03FH ; Mask to filter out which soft CPU's are available.
|
||||
|
||||
;-----------------------------------------------
|
||||
; Video Module control bits.
|
||||
;-----------------------------------------------
|
||||
MODE_80CHAR EQU 010H ; Enable 80 character display.
|
||||
MODE_COLOUR EQU 020H ; Enable colour display.
|
||||
SYSMODE_MZ80A EQU 000H ; System board mode MZ80A, 2MHz CPU/Bus.
|
||||
SYSMODE_MZ80B EQU 020H ; System board mode MZ80B, 4MHz CPU/Bus.
|
||||
SYSMODE_MZ2000 EQU 020H ; System board mode MZ2000, 4MHz CPU/Bus.
|
||||
SYSMODE_MZ700 EQU 042H ; System board mode MZ700, 3.54MHz CPU/Bus.
|
||||
VMMODE_MZ80K EQU 000H ; Video mode = MZ80K
|
||||
VMMODE_MZ80C EQU 001H ; Video mode = MZ80C
|
||||
VMMODE_MZ1200 EQU 002H ; Video mode = MZ1200
|
||||
VMMODE_MZ80A EQU 003H ; Video mode = MZ80A
|
||||
VMMODE_MZ700 EQU 004H ; Video mode = MZ700
|
||||
VMMODE_MZ800 EQU 005H ; Video mode = MZ800
|
||||
VMMODE_MZ1500 EQU 006H ; Video mode = MZ1500
|
||||
VMMODE_MZ80B EQU 007H ; Video mode = MZ80B
|
||||
VMMODE_MZ2000 EQU 008H ; Video mode = MZ2000
|
||||
VMMODE_MZ2200 EQU 009H ; Video mode = MZ2200
|
||||
VMMODE_MZ2500 EQU 00AH ; Video mode = MZ2500
|
||||
VMMODE_PCGRAM EQU 020H ; Enable PCG RAM.
|
||||
VMMODE_VGA_OFF EQU 000H ; Set VGA mode off, external monitor is driven by standard internal 60Hz signals.
|
||||
VMMODE_VGA_INT EQU 000H ; Set VGA mode off, external monitor is driven by standard internal 60Hz signals.
|
||||
VMMODE_VGA_INT50 EQU 001H ; Set VGA mode off, external monitor is driven by standard internal 50Hz signals.
|
||||
VMMODE_VGA_640x480 EQU 002H ; Set external monitor to VGA 640x480 @ 60Hz mode.
|
||||
VMMODE_VGA_800x600 EQU 003H ; Set external monitor to VGA 800x600 @ 60Hz mode.
|
||||
|
||||
;-----------------------------------------------
|
||||
; GPU commands.
|
||||
;-----------------------------------------------
|
||||
GPUCLEARVRAM EQU 001H ; Clear the VRAM without updating attributes.
|
||||
GPUCLEARVRAMCA EQU 002H ; Clear the VRAM/ARAM with given attribute byte,
|
||||
GPUCLEARVRAMP EQU 003H ; Clear the VRAM/ARAM with parameters.
|
||||
GPUCLEARGRAM EQU 081H ; Clear the entire Framebuffer.
|
||||
GPUCLEARGRAMP EQU 082H ; Clear the Framebuffer according to parameters.
|
||||
GPURESET EQU 0FFH ; Reset the GPU, return to idle state.
|
||||
|
||||
;-----------------------------------------------
|
||||
; tranZPUter SW Memory Management modes
|
||||
;-----------------------------------------------
|
||||
TZMM_ENIOWAIT EQU 020H ; Memory management IO Wait State enable - insert a wait state when an IO operation to E0-FF is executed.
|
||||
TZMM_ORIG EQU 000H ; Original Sharp MZ80A mode, no tranZPUter features are selected except the I/O control registers (default: 0x60-063).
|
||||
TZMM_BOOT EQU 001H ; Original mode but E800-EFFF is mapped to tranZPUter RAM so TZFS can be booted.
|
||||
TZMM_TZFS EQU 002H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-FFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected.
|
||||
TZMM_TZFS2 EQU 003H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 1.
|
||||
TZMM_TZFS3 EQU 004H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 2.
|
||||
TZMM_TZFS4 EQU 005H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 3.
|
||||
TZMM_CPM EQU 006H + TZMM_ENIOWAIT ; CPM main memory configuration, all memory on the tranZPUter board, 64K block 4 selected. Special case for F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard.
|
||||
TZMM_CPM2 EQU 007H + TZMM_ENIOWAIT ; CPM main memory configuration, F000-FFFF are on the tranZPUter board in block 4, 0040-CFFF and E800-EFFF are in block 5, mainboard for D000-DFFF (video), E000-E800 (Memory control) selected.
|
||||
; Special case for 0000:003F (interrupt vectors) which resides in block 4, F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard.
|
||||
TZMM_COMPAT EQU 008H + TZMM_ENIOWAIT ; Original mode but with main DRAM in Bank 0 to allow bootstrapping of programs from other machines such as the MZ700.
|
||||
TZMM_HOSTACCESS EQU 009H + TZMM_ENIOWAIT ; Mode to allow code running in Bank 0, address E800:FFFF to access host memory. Monitor ROM 0000-0FFF and Main DRAM 0x1000-0xD000, video and memory mapped I/O are on the host machine, User/Floppy ROM E800-FFFF are in tranZPUter memory.
|
||||
TZMM_MZ700_0 EQU 00AH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the mainboard.
|
||||
TZMM_MZ700_1 EQU 00BH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
|
||||
TZMM_MZ700_2 EQU 00CH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
|
||||
TZMM_MZ700_3 EQU 00DH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
|
||||
TZMM_MZ700_4 EQU 00EH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
|
||||
TZMM_MZ800 EQU 00FH + TZMM_ENIOWAIT ; MZ800 Mode - Tracks original hardware mode offering MZ700/MZ800 configurations.
|
||||
TZMM_MZ2000 EQU 010H + TZMM_ENIOWAIT; ; MZ2000 Mode - Running on MZ2000 hardware, configuration set according to runtime configuration registers.
|
||||
TZMM_FPGA EQU 015H + TZMM_ENIOWAIT ; Open up access for the K64F to the FPGA resources such as memory. All other access to RAM or mainboard is blocked.
|
||||
TZMM_TZPUM EQU 016H + TZMM_ENIOWAIT ; Everything in on mainboard, no access to tranZPUter memory.
|
||||
TZMM_TZPU EQU 017H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
|
||||
;TZMM_TZPU0 EQU 018H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
|
||||
;TZMM_TZPU1 EQU 019H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 1 is selected.
|
||||
;TZMM_TZPU2 EQU 01AH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 2 is selected.
|
||||
;TZMM_TZPU3 EQU 01BH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 3 is selected.
|
||||
;TZMM_TZPU4 EQU 01CH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 4 is selected.
|
||||
;TZMM_TZPU5 EQU 01DH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 5 is selected.
|
||||
;TZMM_TZPU6 EQU 01EH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 6 is selected.
|
||||
;TZMM_TZPU7 EQU 01FH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 7 is selected.
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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_MZFHDR: EQU 1 ; File type being handled is an MZF Header.
|
||||
TZSVC_FTYPE_CAS: EQU 2 ; File type being handled is an CASsette BASIC script.
|
||||
TZSVC_FTYPE_BAS: EQU 3 ; 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_LOAD40ABIOS EQU 20H ; Service command requesting that the 40 column version of the SA1510 BIOS is loaded.
|
||||
TZSVC_CMD_LOAD80ABIOS EQU 21H ; Service command requesting that the 80 column version of the SA1510 BIOS is loaded.
|
||||
TZSVC_CMD_LOAD700BIOS40 EQU 22H ; Service command requesting that the MZ700 1Z-013A 40 column BIOS is loaded.
|
||||
TZSVC_CMD_LOAD700BIOS80 EQU 23H ; Service command requesting that the MZ700 1Z-013A 80 column patched BIOS is loaded.
|
||||
TZSVC_CMD_LOAD80BIPL EQU 24H ; Service command requesting the MZ-80B IPL is loaded.
|
||||
TZSVC_CMD_LOAD800BIOS EQU 25H ; Service command requesting that the MZ800 9Z-504M BIOS is loaded.
|
||||
TZSVC_CMD_LOAD2000IPL EQU 26H ; Service command requesting the MZ-2000 IPL is loaded.
|
||||
TZSVC_CMD_LOADTZFS EQU 2FH ; Service command requesting the loading of TZFS. This service is for machines which normally dont have a monitor BIOS. ie. MZ-80B/MZ-2000 and manually request TZFS.
|
||||
TZSVC_CMD_LOADBDOS EQU 30H ; Service command to reload CPM BDOS+CCP.
|
||||
TZSVC_CMD_ADDSDDRIVE EQU 31H ; Service command to attach a CPM disk to a drive number.
|
||||
TZSVC_CMD_READSDDRIVE EQU 32H ; Service command to read an attached SD file as a CPM disk drive.
|
||||
TZSVC_CMD_WRITESDDRIVE EQU 33H ; Service command to write to a CPM disk drive which is an attached SD file.
|
||||
TZSVC_CMD_CPU_BASEFREQ EQU 40H ; Service command to switch to the mainboard frequency.
|
||||
TZSVC_CMD_CPU_ALTFREQ EQU 41H ; Service command to switch to the alternate frequency provided by the K64F.
|
||||
TZSVC_CMD_CPU_CHGFREQ EQU 42H ; Service command to set the alternate frequency in hertz.
|
||||
TZSVC_CMD_CPU_SETZ80 EQU 50H ; Service command to switch to the external Z80 hard cpu.
|
||||
TZSVC_CMD_CPU_SETT80 EQU 51H ; Service command to switch to the internal T80 soft cpu.
|
||||
TZSVC_CMD_CPU_SETZPUEVO EQU 52H ; Service command to switch to the internal ZPU Evolution soft cpu.
|
||||
TZSVC_CMD_EMU_SETMZ80K EQU 53H ; Service command to switch to the internal Sharp MZ Series Emulation of the MZ80K.
|
||||
TZSVC_CMD_EMU_SETMZ80C EQU 54H ; "" "" "" MZ80C.
|
||||
TZSVC_CMD_EMU_SETMZ1200 EQU 55H ; "" "" "" MZ1200.
|
||||
TZSVC_CMD_EMU_SETMZ80A EQU 56H ; "" "" "" MZ80A.
|
||||
TZSVC_CMD_EMU_SETMZ700 EQU 57H ; "" "" "" MZ700.
|
||||
TZSVC_CMD_EMU_SETMZ800 EQU 58H ; "" "" "" MZ800.
|
||||
TZSVC_CMD_EMU_SETMZ1500 EQU 59H ; "" "" "" MZ1500.
|
||||
TZSVC_CMD_EMU_SETMZ80B EQU 5AH ; "" "" "" MZ80B.
|
||||
TZSVC_CMD_EMU_SETMZ2000 EQU 5BH ; "" "" "" MZ2000.
|
||||
TZSVC_CMD_EMU_SETMZ2200 EQU 5CH ; "" "" "" MZ2200.
|
||||
TZSVC_CMD_EMU_SETMZ2500 EQU 5DH ; "" "" "" MZ2500.
|
||||
TZSVC_CMD_EXIT EQU 07FH ; Service command to terminate TZFS and restart the machine in original mode.
|
||||
TZSVC_STATUS_OK EQU 000H ; Flag to indicate the K64F processing completed successfully.
|
||||
TZSVC_STATUS_REQUEST EQU 0FEH ; Flag to indicate the Z80 has made a request to the K64F.
|
||||
TZSVC_STATUS_PROCESSING EQU 0FFH ; Flag to indicate the K64F is processing a command.
|
||||
316
software/asm/include/testtz_definitions.asm
Normal file
316
software/asm/include/testtz_definitions.asm
Normal file
@@ -0,0 +1,316 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;-
|
||||
;- Name: TESTTZ_Definitions.asm
|
||||
;- Created: June 2020
|
||||
;- Author(s): Philip Smart
|
||||
;- Description: tranZPUter tester program
|
||||
;- A small program to exercise parts of the tranZPUter to aid in problem resolution.
|
||||
;-
|
||||
;- Credits:
|
||||
;- Copyright: (c) 2019-20 Philip Smart <philip.smart@net2net.org>
|
||||
;-
|
||||
;- History: Jun 2020 - Initial version.
|
||||
;-
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;- 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.
|
||||
;-----------------------------------------------
|
||||
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
|
||||
|
||||
; Debugging
|
||||
ENADEBUG EQU 0 ; Enable debugging logic, 1 = enable, 0 = disable
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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
|
||||
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_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
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
; IO ports in hardware and values.
|
||||
;-----------------------------------------------
|
||||
MMCFG EQU 060H ; Memory management configuration latch.
|
||||
SETXMHZ EQU 062H ; Select the alternate clock frequency.
|
||||
SET2MHZ EQU 064H ; Select the system 2MHz clock frequency.
|
||||
CLKSELRD EQU 066H ; Read clock selected setting, 0 = 2MHz, 1 = XMHz
|
||||
SVCREQ EQU 068H ; I/O Processor service request.
|
||||
CPLDSTATUS EQU 06BH ; Version 2.1 CPLD status register.
|
||||
CPUCFG EQU 06CH ; Version 2.2 CPU configuration register.
|
||||
CPUSTATUS EQU 06CH ; Version 2.2 CPU runtime status register.
|
||||
CPUINFO EQU 06DH ; Version 2.2 CPU information register.
|
||||
CPLDCFG EQU 06EH ; Version 2.1 CPLD configuration register.
|
||||
CPLDINFO EQU 06FH ; Version 2.1 CPLD version information register.
|
||||
VMPNUM EQU 0A0H ; Set the parameter number to update.
|
||||
VMPLBYTE EQU 0A1H ; Update the lower selected parameter byte.
|
||||
VMPUBYTE EQU 0A2H ; Update the upper selected parameter byte.
|
||||
PALSLCTOFF EQU 0A3H ; set the palette slot Off position to be adjusted.
|
||||
PALSLCTON EQU 0A4H ; set the palette slot On position to be adjusted.
|
||||
PALSETRED EQU 0A5H ; set the red palette value according to the PALETTE_PARAM_SEL address.
|
||||
PALSETGREEN EQU 0A6H ; set the green palette value according to the PALETTE_PARAM_SEL address.
|
||||
PALSETBLUE EQU 0A7H ; set the blue palette value according to the PALETTE_PARAM_SEL address.
|
||||
VMPALETTE EQU 0B0H ; Select Palette:
|
||||
; 0xB0 sets the palette. The Video Module supports 4 bit per colour output but there is only enough RAM for 1 bit per colour so the pallette is used to change the colours output.
|
||||
; Bits [7:0] defines the pallete number. This indexes a lookup table which contains the required 4bit output per 1bit input.
|
||||
; GPU:
|
||||
GPUPARAM EQU 0B2H ; 0xB2 set parameters. Store parameters in a long word to be used by the graphics command processor.
|
||||
; The parameter word is 128 bit and each write to the parameter word shifts left by 8 bits and adds the new byte at bits 7:0.
|
||||
GPUCMD EQU 0B3H ; 0xB3 set the graphics processor unit commands.
|
||||
GPUSTATUS EQU 0B3H ; [7;1] - FSM state, [0] - 1 = busy, 0 = idle
|
||||
; Bits [5:0] - 0 = Reset parameters.
|
||||
; 1 = Clear to val. Start Location (16 bit), End Location (16 bit), Red Filter, Green Filter, Blue Filter
|
||||
;
|
||||
VMCTRL EQU 0B8H ; Video Module control register. [2:0] - 000 (default) = MZ80A, 001 = MZ-700, 010 = MZ800, 011 = MZ80B, 100 = MZ80K, 101 = MZ80C, 110 = MZ1200, 111 = MZ2000. [3] = 0 - 40 col, 1 - 80 col.
|
||||
VMGRMODE EQU 0B9H ; Video Module graphics mode. 7/6 = Operator (00=OR,01=AND,10=NAND,11=XOR), 5=GRAM Output Enable, 4 = VRAM Output Enable, 3/2 = Write mode (00=Page 1:Red, 01=Page 2:Green, 10=Page 3:Blue, 11=Indirect), 1/0=Read mode (00=Page 1:Red, 01=Page2:Green, 10=Page 3:Blue, 11=Not used).
|
||||
VMREDMASK EQU 0BAH ; Video Module Red bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
||||
VMGREENMASK EQU 0BBH ; Video Module Green bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
||||
VMBLUEMASK EQU 0BCH ; Video Module Blue bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
||||
VMPAGE EQU 0BDH ; Video Module memory page register. [1:0] switches in 1 16Kb page (3 pages) of graphics ram to C000 - FFFF. Bits [1:0] = page, 00 = off, 01 = Red, 10 = Green, 11 = Blue. This overrides all MZ700/MZ80B page switching functions. [7] 0 - normal, 1 - switches in CGROM for upload at D000:DFFF.
|
||||
VMVGATTR EQU 0BEH ; Select VGA Border colour and attributes. Bit 2 = Red, 1 = Green, 0 = Blue.
|
||||
VMVGAMODE EQU 0BFH ; Select VGA output mode. Bits [3:0] - Output mode.
|
||||
|
||||
GDCRTC EQU 0CFH ; MZ-800 CRTC control register
|
||||
GDCMD EQU 0CEH ; MZ-800 CRTC Mode register
|
||||
GDGRF EQU 0CDH ; MZ-800 read format register
|
||||
GDGWF EQU 0CCH ; MZ-800 write format register
|
||||
MMIO0 EQU 0E0H ; MZ-700/MZ-800 Memory Management Set 0
|
||||
MMIO1 EQU 0E1H ; MZ-700/MZ-800 Memory Management Set 1
|
||||
MMIO2 EQU 0E2H ; MZ-700/MZ-800 Memory Management Set 2
|
||||
MMIO3 EQU 0E3H ; MZ-700/MZ-800 Memory Management Set 3
|
||||
MMIO4 EQU 0E4H ; MZ-700/MZ-800 Memory Management Set 4
|
||||
MMIO5 EQU 0E5H ; MZ-700/MZ-800 Memory Management Set 5
|
||||
MMIO6 EQU 0E6H ; MZ-700/MZ-800 Memory Management Set 6
|
||||
MMIO7 EQU 0E7H ; MZ-700/MZ-800 Memory Management Set 7
|
||||
SYSCTRL EQU 0F0H ; System board control register. [2:0] - 000 MZ80A Mode, 2MHz CPU/Bus, 001 MZ80B Mode, 4MHz CPU/Bus, 010 MZ700 Mode, 3.54MHz CPU/Bus.
|
||||
GRAMMODE EQU 0F4H ; MZ80B Graphics mode. Bit 0 = 0, Write to Graphics RAM I, Bit 0 = 1, Write to Graphics RAM II. Bit 1 = 1, blend Graphics RAM I output on display, Bit 2 = 1, blend Graphics RAM II output on display.
|
||||
|
||||
;-----------------------------------------------
|
||||
; CPLD Configuration constants.
|
||||
;-----------------------------------------------
|
||||
MODE_MZ80K EQU 0 ; Set to MZ-80K mode.
|
||||
MODE_MZ80C EQU 1 ; Set to MZ-80C mode.
|
||||
MODE_MZ1200 EQU 2 ; Set to MZ-1200 mode.
|
||||
MODE_MZ80A EQU 3 ; Set to MZ-80A mode (base mode on MZ-80A hardware).
|
||||
MODE_MZ700 EQU 4 ; Set to MZ-700 mode (base mode on MZ-700 hardware).
|
||||
MODE_MZ800 EQU 5 ; Set to MZ-800 mode.
|
||||
MODE_MZ80B EQU 6 ; Set to MZ-80B mode.
|
||||
MODE_MZ2000 EQU 7 ; Set to MZ-2000 mode.
|
||||
MODE_VIDEO_FPGA EQU 8 ; Bit flag (bit 3) to switch CPLD into using the new FPGA video hardware.
|
||||
MODE_RESET_PRESERVE EQU 080H ; Preserve register configuration through reset.
|
||||
|
||||
;-----------------------------------------------
|
||||
; CPLD Command Instruction constants.
|
||||
;-----------------------------------------------
|
||||
CPLD_RESET_HOST EQU 1 ; CPLD level command to reset the host system.
|
||||
CPLD_HOLD_HOST_BUS EQU 2 ; CPLD command to hold the host bus.
|
||||
CPLD_RELEASE_HOST_BUS EQU 3 ; CPLD command to release the host bus.
|
||||
|
||||
;-----------------------------------------------
|
||||
; FPGA CPU enhancement control bits.
|
||||
;-----------------------------------------------
|
||||
CPUMODE_SET_Z80 EQU 000H ; Set the CPU to the hard Z80.
|
||||
CPUMODE_SET_T80 EQU 001H ; Set the CPU to the soft T80.
|
||||
CPUMODE_SET_ZPU_EVO EQU 002H ; Set the CPU to the soft ZPU Evolution.
|
||||
CPUMODE_SET_EMU_MZ EQU 004H ; Set the hardware to enable the Sharp MZ Series emulations.
|
||||
CPUMODE_SET_BBB EQU 008H ; Place holder for a future soft CPU.
|
||||
CPUMODE_SET_CCC EQU 010H ; Place holder for a future soft CPU.
|
||||
CPUMODE_SET_DDD EQU 020H ; Place holder for a future soft CPU.
|
||||
CPUMODE_IS_Z80 EQU 000H ; Status value to indicate if the hard Z80 available.
|
||||
CPUMODE_IS_T80 EQU 001H ; Status value to indicate if the soft T80 available.
|
||||
CPUMODE_IS_ZPU_EVO EQU 002H ; Status value to indicate if the soft ZPU Evolution available.
|
||||
CPUMODE_IS_EMU_MZ EQU 004H ; Status value to indicate the Sharp MZ Series Hardware Emulation logic is available.
|
||||
CPUMODE_IS_BBB EQU 008H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_IS_CCC EQU 010H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_IS_DDD EQU 020H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_RESET_CPU EQU 080H ; Reset the soft CPU. Active high, when high the CPU is held in RESET, when low the CPU runs.
|
||||
CPUMODE_IS_SOFT_AVAIL EQU 040H ; Marker to indicate if the underlying FPGA can support soft CPU's.
|
||||
CPUMODE_IS_SOFT_MASK EQU 0C0H ; Mask to filter out the Soft CPU availability flags.
|
||||
CPUMODE_IS_CPU_MASK EQU 03FH ; Mask to filter out which soft CPU's are available.
|
||||
|
||||
;-----------------------------------------------
|
||||
; Video Module control bits.
|
||||
;-----------------------------------------------
|
||||
MODE_80CHAR EQU 010H ; Enable 80 character display.
|
||||
MODE_COLOUR EQU 020H ; Enable colour display.
|
||||
SYSMODE_MZ80A EQU 000H ; System board mode MZ80A, 2MHz CPU/Bus.
|
||||
SYSMODE_MZ80B EQU 020H ; System board mode MZ80B, 4MHz CPU/Bus.
|
||||
SYSMODE_MZ2000 EQU 020H ; System board mode MZ2000, 4MHz CPU/Bus.
|
||||
SYSMODE_MZ700 EQU 042H ; System board mode MZ700, 3.54MHz CPU/Bus.
|
||||
VMMODE_MZ80K EQU 000H ; Video mode = MZ80K
|
||||
VMMODE_MZ80C EQU 001H ; Video mode = MZ80C
|
||||
VMMODE_MZ1200 EQU 002H ; Video mode = MZ1200
|
||||
VMMODE_MZ80A EQU 003H ; Video mode = MZ80A
|
||||
VMMODE_MZ700 EQU 004H ; Video mode = MZ700
|
||||
VMMODE_MZ800 EQU 005H ; Video mode = MZ800
|
||||
VMMODE_MZ1500 EQU 006H ; Video mode = MZ1500
|
||||
VMMODE_MZ80B EQU 007H ; Video mode = MZ80B
|
||||
VMMODE_MZ2000 EQU 008H ; Video mode = MZ2000
|
||||
VMMODE_MZ2200 EQU 009H ; Video mode = MZ2200
|
||||
VMMODE_MZ2500 EQU 00AH ; Video mode = MZ2500
|
||||
VMMODE_PCGRAM EQU 020H ; Enable PCG RAM.
|
||||
VMMODE_VGA_OFF EQU 000H ; Set VGA mode off, external monitor is driven by standard internal 60Hz signals.
|
||||
VMMODE_VGA_INT EQU 000H ; Set VGA mode off, external monitor is driven by standard internal 60Hz signals.
|
||||
VMMODE_VGA_INT50 EQU 001H ; Set VGA mode off, external monitor is driven by standard internal 50Hz signals.
|
||||
VMMODE_VGA_640x480 EQU 002H ; Set external monitor to VGA 640x480 @ 60Hz mode.
|
||||
VMMODE_VGA_800x600 EQU 003H ; Set external monitor to VGA 800x600 @ 60Hz mode.
|
||||
|
||||
;-----------------------------------------------
|
||||
; GPU commands.
|
||||
;-----------------------------------------------
|
||||
GPUCLEARVRAM EQU 001H ; Clear the VRAM without updating attributes.
|
||||
GPUCLEARVRAMCA EQU 002H ; Clear the VRAM/ARAM with given attribute byte,
|
||||
GPUCLEARVRAMP EQU 003H ; Clear the VRAM/ARAM with parameters.
|
||||
GPUCLEARGRAM EQU 081H ; Clear the entire Framebuffer.
|
||||
GPUCLEARGRAMP EQU 082H ; Clear the Framebuffer according to parameters.
|
||||
GPURESET EQU 0FFH ; Reset the GPU, return to idle state.
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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 + TZMM_ENIOWAIT ; Original mode but with main DRAM in Bank 0 to allow bootstrapping of programs from other machines such as the MZ700.
|
||||
TZMM_HOSTACCESS EQU 009H + TZMM_ENIOWAIT ; Mode to allow code running in Bank 0, address E800:FFFF to access host memory. Monitor ROM 0000-0FFF and Main DRAM 0x1000-0xD000, video and memory mapped I/O are on the host machine, User/Floppy ROM E800-FFFF are in tranZPUter memory.
|
||||
TZMM_MZ700_0 EQU 00AH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the mainboard.
|
||||
TZMM_MZ700_1 EQU 00BH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
|
||||
TZMM_MZ700_2 EQU 00CH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
|
||||
TZMM_MZ700_3 EQU 00DH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
|
||||
TZMM_MZ700_4 EQU 00EH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
|
||||
TZMM_MZ800 EQU 00FH + TZMM_ENIOWAIT ; MZ800 Mode - Tracks original hardware mode offering MZ700/MZ800 configurations.
|
||||
TZMM_MZ2000 EQU 010H + TZMM_ENIOWAIT; ; MZ2000 Mode - Running on MZ2000 hardware, configuration set according to runtime configuration registers.
|
||||
TZMM_FPGA EQU 015H + TZMM_ENIOWAIT ; Open up access for the K64F to the FPGA resources such as memory. All other access to RAM or mainboard is blocked.
|
||||
TZMM_TZPUM EQU 016H + TZMM_ENIOWAIT ; Everything in on mainboard, no access to tranZPUter memory.
|
||||
TZMM_TZPU EQU 017H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
|
||||
;TZMM_TZPU0 EQU 018H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
|
||||
;TZMM_TZPU1 EQU 019H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 1 is selected.
|
||||
;TZMM_TZPU2 EQU 01AH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 2 is selected.
|
||||
;TZMM_TZPU3 EQU 01BH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 3 is selected.
|
||||
;TZMM_TZPU4 EQU 01CH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 4 is selected.
|
||||
;TZMM_TZPU5 EQU 01DH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 5 is selected.
|
||||
;TZMM_TZPU6 EQU 01EH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 6 is selected.
|
||||
;TZMM_TZPU7 EQU 01FH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 7 is selected.
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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)
|
||||
;-----------------------------------------------
|
||||
362
software/asm/include/tzfs_definitions.asm
Normal file
362
software/asm/include/tzfs_definitions.asm
Normal file
@@ -0,0 +1,362 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;-
|
||||
;- Name: TZFS_Definitions.asm
|
||||
;- Created: September 2019
|
||||
;- Author(s): Philip Smart
|
||||
;- Description: Sharp MZ series tzfs (tranZPUter Filing System).
|
||||
;- This assembly language program is a branch from the original RFS written for the
|
||||
;- MZ80A_RFS upgrade board. It is adapted to work within the similar yet different
|
||||
;- environment of the tranZPUter SW which has a large RAM capacity (512K) and an
|
||||
;- I/O processor in the K64F/ZPU.
|
||||
;-
|
||||
;- Credits:
|
||||
;- Copyright: (c) 2019-21 Philip Smart <philip.smart@net2net.org>
|
||||
;-
|
||||
;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW.
|
||||
;- July 2020 - Updates to accommodate v2.1 of the tranZPUter board.
|
||||
;-
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;- 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.
|
||||
;-----------------------------------------------
|
||||
BUILD_MZ80A EQU 0 ; Build for the standard Sharp MZ80A, no lower memory.
|
||||
BUILD_MZ700 EQU 0 ; Build for the Sharp MZ-700 base hardware.
|
||||
BUILD_MZ2000 EQU 1 ; Build for the Sharp MZ-2000 base hardware.
|
||||
|
||||
; Debugging
|
||||
ENADEBUG EQU 0 ; Enable debugging logic, 1 = enable, 0 = disable
|
||||
|
||||
;-----------------------------------------------
|
||||
; Entry/compilation start points.
|
||||
;-----------------------------------------------
|
||||
MROMADDR EQU 00000H ; Start of SA1510 Monitor ROM.
|
||||
UROMADDR EQU 0E800H ; Start of User ROM Address space.
|
||||
UROMBSTBL EQU UROMADDR + 020H ; Entry point to the bank switching table.
|
||||
TZFSJMPTABLE EQU UROMADDR + 00080H ; Start of jump table.
|
||||
BANKRAMADDR EQU 0F000H ; Start address of the banked RAM used for TZFS functionality.
|
||||
FDCROMADDR EQU 0F000H
|
||||
FDCJMP1 EQU 0F3FEH ; ROM paged vector 1.
|
||||
FDCJMP2 EQU 0F7FEH ; ROM paged vector 2.
|
||||
FDCJMP3 EQU 0F7FEH ; ROM paged vector 3.
|
||||
FDCJMP4 EQU 0F7FEH ; ROM paged vector 4.
|
||||
PRGBOOTJMP EQU 0CF00H ; Location to load bootstrap for original host program.
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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
|
||||
|
||||
;-----------------------------------------------
|
||||
; IO ports in hardware and values.
|
||||
;-----------------------------------------------
|
||||
MMCFG EQU 060H ; Memory management configuration latch.
|
||||
SETXMHZ EQU 062H ; Select the alternate clock frequency.
|
||||
SET2MHZ EQU 064H ; Select the system 2MHz clock frequency.
|
||||
CLKSELRD EQU 066H ; Read clock selected setting, 0 = 2MHz, 1 = XMHz
|
||||
SVCREQ EQU 068H ; I/O Processor service request.
|
||||
CPLDSTATUS EQU 06BH ; Version 2.1 CPLD status register.
|
||||
CPUCFG EQU 06CH ; Version 2.2 CPU configuration register.
|
||||
CPUSTATUS EQU 06CH ; Version 2.2 CPU runtime status register.
|
||||
CPUINFO EQU 06DH ; Version 2.2 CPU information register.
|
||||
CPLDCFG EQU 06EH ; Version 2.1 CPLD configuration register.
|
||||
CPLDINFO EQU 06FH ; Version 2.1 CPLD version information register.
|
||||
VMPNUM EQU 0A0H ; Set the parameter number to update.
|
||||
VMPLBYTE EQU 0A1H ; Update the lower selected parameter byte.
|
||||
VMPUBYTE EQU 0A2H ; Update the upper selected parameter byte.
|
||||
PALSLCTOFF EQU 0A3H ; set the palette slot Off position to be adjusted.
|
||||
PALSLCTON EQU 0A4H ; set the palette slot On position to be adjusted.
|
||||
PALSETRED EQU 0A5H ; set the red palette value according to the PALETTE_PARAM_SEL address.
|
||||
PALSETGREEN EQU 0A6H ; set the green palette value according to the PALETTE_PARAM_SEL address.
|
||||
PALSETBLUE EQU 0A7H ; set the blue palette value according to the PALETTE_PARAM_SEL address.
|
||||
VMPALETTE EQU 0B0H ; Select Palette:
|
||||
; 0xB0 sets the palette. The Video Module supports 4 bit per colour output but there is only enough RAM for 1 bit per colour so the pallette is used to change the colours output.
|
||||
; Bits [7:0] defines the pallete number. This indexes a lookup table which contains the required 4bit output per 1bit input.
|
||||
; GPU:
|
||||
GPUPARAM EQU 0B2H ; 0xB2 set parameters. Store parameters in a long word to be used by the graphics command processor.
|
||||
; The parameter word is 128 bit and each write to the parameter word shifts left by 8 bits and adds the new byte at bits 7:0.
|
||||
GPUCMD EQU 0B3H ; 0xB3 set the graphics processor unit commands.
|
||||
GPUSTATUS EQU 0B3H ; [7;1] - FSM state, [0] - 1 = busy, 0 = idle
|
||||
; Bits [5:0] - 0 = Reset parameters.
|
||||
; 1 = Clear to val. Start Location (16 bit), End Location (16 bit), Red Filter, Green Filter, Blue Filter
|
||||
;
|
||||
VMCTRL EQU 0B8H ; Video Module control register. [2:0] - 000 (default) = MZ80A, 001 = MZ-700, 010 = MZ800, 011 = MZ80B, 100 = MZ80K, 101 = MZ80C, 110 = MZ1200, 111 = MZ2000. [3] = 0 - 40 col, 1 - 80 col.
|
||||
VMGRMODE EQU 0B9H ; Video Module graphics mode. 7/6 = Operator (00=OR,01=AND,10=NAND,11=XOR), 5=GRAM Output Enable, 4 = VRAM Output Enable, 3/2 = Write mode (00=Page 1:Red, 01=Page 2:Green, 10=Page 3:Blue, 11=Indirect), 1/0=Read mode (00=Page 1:Red, 01=Page2:Green, 10=Page 3:Blue, 11=Not used).
|
||||
VMREDMASK EQU 0BAH ; Video Module Red bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
||||
VMGREENMASK EQU 0BBH ; Video Module Green bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
||||
VMBLUEMASK EQU 0BCH ; Video Module Blue bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
||||
VMPAGE EQU 0BDH ; Video Module memory page register. [1:0] switches in 1 16Kb page (3 pages) of graphics ram to C000 - FFFF. Bits [1:0] = page, 00 = off, 01 = Red, 10 = Green, 11 = Blue. This overrides all MZ700/MZ80B page switching functions. [7] 0 - normal, 1 - switches in CGROM for upload at D000:DFFF.
|
||||
VMVGATTR EQU 0BEH ; Select VGA Border colour and attributes. Bit 2 = Red, 1 = Green, 0 = Blue.
|
||||
VMVGAMODE EQU 0BFH ; Select VGA output mode. Bits [3:0] - Output mode.
|
||||
GDCRTC EQU 0CFH ; MZ-800 CRTC control register
|
||||
GDCMD EQU 0CEH ; MZ-800 CRTC Mode register
|
||||
GDGRF EQU 0CDH ; MZ-800 read format register
|
||||
GDGWF EQU 0CCH ; MZ-800 write format register
|
||||
MMIO0 EQU 0E0H ; MZ-700/MZ-800 Memory Management Set 0
|
||||
MMIO1 EQU 0E1H ; MZ-700/MZ-800 Memory Management Set 1
|
||||
MMIO2 EQU 0E2H ; MZ-700/MZ-800 Memory Management Set 2
|
||||
MMIO3 EQU 0E3H ; MZ-700/MZ-800 Memory Management Set 3
|
||||
MMIO4 EQU 0E4H ; MZ-700/MZ-800 Memory Management Set 4
|
||||
MMIO5 EQU 0E5H ; MZ-700/MZ-800 Memory Management Set 5
|
||||
MMIO6 EQU 0E6H ; MZ-700/MZ-800 Memory Management Set 6
|
||||
MMIO7 EQU 0E7H ; MZ-700/MZ-800 Memory Management Set 7
|
||||
SYSCTRL EQU 0F0H ; System board control register. [2:0] - 000 MZ80A Mode, 2MHz CPU/Bus, 001 MZ80B Mode, 4MHz CPU/Bus, 010 MZ700 Mode, 3.54MHz CPU/Bus.
|
||||
GRAMMODE EQU 0F4H ; MZ80B Graphics mode. Bit 0 = 0, Write to Graphics RAM I, Bit 0 = 1, Write to Graphics RAM II. Bit 1 = 1, blend Graphics RAM I output on display, Bit 2 = 1, blend Graphics RAM II output on display.
|
||||
|
||||
;-----------------------------------------------
|
||||
; CPLD Configuration constants.
|
||||
;-----------------------------------------------
|
||||
MODE_MZ80K EQU 0 ; Set to MZ-80K mode.
|
||||
MODE_MZ80C EQU 1 ; Set to MZ-80C mode.
|
||||
MODE_MZ1200 EQU 2 ; Set to MZ-1200 mode.
|
||||
MODE_MZ80A EQU 3 ; Set to MZ-80A mode (base mode on MZ-80A hardware).
|
||||
MODE_MZ700 EQU 4 ; Set to MZ-700 mode (base mode on MZ-700 hardware).
|
||||
MODE_MZ800 EQU 5 ; Set to MZ-800 mode.
|
||||
MODE_MZ80B EQU 6 ; Set to MZ-80B mode.
|
||||
MODE_MZ2000 EQU 7 ; Set to MZ-2000 mode.
|
||||
MODE_VIDEO_FPGA EQU 8 ; Bit flag (bit 3) to switch CPLD into using the new FPGA video hardware.
|
||||
MODE_RESET_PRESERVE EQU 080H ; Preserve register configuration through reset.
|
||||
|
||||
;-----------------------------------------------
|
||||
; CPLD Command Instruction constants.
|
||||
;-----------------------------------------------
|
||||
CPLD_RESET_HOST EQU 1 ; CPLD level command to reset the host system.
|
||||
CPLD_HOLD_HOST_BUS EQU 2 ; CPLD command to hold the host bus.
|
||||
CPLD_RELEASE_HOST_BUS EQU 3 ; CPLD command to release the host bus.
|
||||
|
||||
;-----------------------------------------------
|
||||
; FPGA CPU enhancement control bits.
|
||||
;-----------------------------------------------
|
||||
CPUMODE_SET_Z80 EQU 000H ; Set the CPU to the hard Z80.
|
||||
CPUMODE_SET_T80 EQU 001H ; Set the CPU to the soft T80.
|
||||
CPUMODE_SET_ZPU_EVO EQU 002H ; Set the CPU to the soft ZPU Evolution.
|
||||
CPUMODE_SET_EMU_MZ EQU 004H ; Set the hardware to enable the Sharp MZ Series emulations.
|
||||
CPUMODE_SET_BBB EQU 008H ; Place holder for a future soft CPU.
|
||||
CPUMODE_SET_CCC EQU 010H ; Place holder for a future soft CPU.
|
||||
CPUMODE_SET_DDD EQU 020H ; Place holder for a future soft CPU.
|
||||
CPUMODE_IS_Z80 EQU 000H ; Status value to indicate if the hard Z80 available.
|
||||
CPUMODE_IS_T80 EQU 001H ; Status value to indicate if the soft T80 available.
|
||||
CPUMODE_IS_ZPU_EVO EQU 002H ; Status value to indicate if the soft ZPU Evolution available.
|
||||
CPUMODE_IS_EMU_MZ EQU 004H ; Status value to indicate the Sharp MZ Series Hardware Emulation logic is available.
|
||||
CPUMODE_IS_BBB EQU 008H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_IS_CCC EQU 010H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_IS_DDD EQU 020H ; Place holder to indicate if a future soft CPU is available.
|
||||
CPUMODE_RESET_CPU EQU 080H ; Reset the soft CPU. Active high, when high the CPU is held in RESET, when low the CPU runs.
|
||||
CPUMODE_IS_SOFT_AVAIL EQU 040H ; Marker to indicate if the underlying FPGA can support soft CPU's.
|
||||
CPUMODE_IS_SOFT_MASK EQU 0C0H ; Mask to filter out the Soft CPU availability flags.
|
||||
CPUMODE_IS_CPU_MASK EQU 03FH ; Mask to filter out which soft CPU's are available.
|
||||
|
||||
;-----------------------------------------------
|
||||
; Video Module control bits.
|
||||
;-----------------------------------------------
|
||||
MODE_80CHAR EQU 010H ; Enable 80 character display.
|
||||
MODE_COLOUR EQU 020H ; Enable colour display.
|
||||
SYSMODE_MZ80A EQU 000H ; System board mode MZ80A, 2MHz CPU/Bus.
|
||||
SYSMODE_MZ80B EQU 020H ; System board mode MZ80B, 4MHz CPU/Bus.
|
||||
SYSMODE_MZ2000 EQU 020H ; System board mode MZ2000, 4MHz CPU/Bus.
|
||||
SYSMODE_MZ700 EQU 042H ; System board mode MZ700, 3.54MHz CPU/Bus.
|
||||
VMMODE_MZ80K EQU 000H ; Video mode = MZ80K
|
||||
VMMODE_MZ80C EQU 001H ; Video mode = MZ80C
|
||||
VMMODE_MZ1200 EQU 002H ; Video mode = MZ1200
|
||||
VMMODE_MZ80A EQU 003H ; Video mode = MZ80A
|
||||
VMMODE_MZ700 EQU 004H ; Video mode = MZ700
|
||||
VMMODE_MZ800 EQU 005H ; Video mode = MZ800
|
||||
VMMODE_MZ1500 EQU 006H ; Video mode = MZ1500
|
||||
VMMODE_MZ80B EQU 007H ; Video mode = MZ80B
|
||||
VMMODE_MZ2000 EQU 008H ; Video mode = MZ2000
|
||||
VMMODE_MZ2200 EQU 009H ; Video mode = MZ2200
|
||||
VMMODE_MZ2500 EQU 00AH ; Video mode = MZ2500
|
||||
VMMODE_PCGRAM EQU 020H ; Enable PCG RAM.
|
||||
VMMODE_VGA_OFF EQU 000H ; Set VGA mode off, external monitor is driven by standard internal 60Hz signals.
|
||||
VMMODE_VGA_INT EQU 000H ; Set VGA mode off, external monitor is driven by standard internal 60Hz signals.
|
||||
VMMODE_VGA_INT50 EQU 001H ; Set VGA mode off, external monitor is driven by standard internal 50Hz signals.
|
||||
VMMODE_VGA_640x480 EQU 002H ; Set external monitor to VGA 640x480 @ 60Hz mode.
|
||||
VMMODE_VGA_800x600 EQU 003H ; Set external monitor to VGA 800x600 @ 60Hz mode.
|
||||
|
||||
;-----------------------------------------------
|
||||
; GPU commands.
|
||||
;-----------------------------------------------
|
||||
GPUCLEARVRAM EQU 001H ; Clear the VRAM without updating attributes.
|
||||
GPUCLEARVRAMCA EQU 002H ; Clear the VRAM/ARAM with given attribute byte,
|
||||
GPUCLEARVRAMP EQU 003H ; Clear the VRAM/ARAM with parameters.
|
||||
GPUCLEARGRAM EQU 081H ; Clear the entire Framebuffer.
|
||||
GPUCLEARGRAMP EQU 082H ; Clear the Framebuffer according to parameters.
|
||||
GPURESET EQU 0FFH ; Reset the GPU, return to idle state.
|
||||
|
||||
;-----------------------------------------------
|
||||
; tranZPUter SW Memory Management modes
|
||||
;-----------------------------------------------
|
||||
TZMM_ENIOWAIT EQU 020H ; Memory management IO Wait State enable - insert a wait state when an IO operation to E0-FF is executed.
|
||||
TZMM_ORIG EQU 000H ; Original Sharp MZ80A mode, no tranZPUter features are selected except the I/O control registers (default: 0x60-063).
|
||||
TZMM_BOOT EQU 001H ; Original mode but E800-EFFF is mapped to tranZPUter RAM so TZFS can be booted.
|
||||
TZMM_TZFS EQU 002H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-FFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected.
|
||||
TZMM_TZFS2 EQU 003H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 1.
|
||||
TZMM_TZFS3 EQU 004H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 2.
|
||||
TZMM_TZFS4 EQU 005H + TZMM_ENIOWAIT ; TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 3.
|
||||
TZMM_CPM EQU 006H + TZMM_ENIOWAIT ; CPM main memory configuration, all memory on the tranZPUter board, 64K block 4 selected. Special case for F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard.
|
||||
TZMM_CPM2 EQU 007H + TZMM_ENIOWAIT ; CPM main memory configuration, F000-FFFF are on the tranZPUter board in block 4, 0040-CFFF and E800-EFFF are in block 5, mainboard for D000-DFFF (video), E000-E800 (Memory control) selected.
|
||||
; Special case for 0000:003F (interrupt vectors) which resides in block 4, F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard.
|
||||
TZMM_COMPAT EQU 008H + TZMM_ENIOWAIT ; Original mode but with main DRAM in Bank 0 to allow bootstrapping of programs from other machines such as the MZ700.
|
||||
TZMM_HOSTACCESS EQU 009H + TZMM_ENIOWAIT ; Mode to allow code running in Bank 0, address E800:FFFF to access host memory. Monitor ROM 0000-0FFF and Main DRAM 0x1000-0xD000, video and memory mapped I/O are on the host machine, User/Floppy ROM E800-FFFF are in tranZPUter memory.
|
||||
TZMM_MZ700_0 EQU 00AH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the mainboard.
|
||||
TZMM_MZ700_1 EQU 00BH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
|
||||
TZMM_MZ700_2 EQU 00CH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
|
||||
TZMM_MZ700_3 EQU 00DH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
|
||||
TZMM_MZ700_4 EQU 00EH + TZMM_ENIOWAIT ; MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
|
||||
TZMM_MZ800 EQU 00FH + TZMM_ENIOWAIT ; MZ800 Mode - Tracks original hardware mode offering MZ700/MZ800 configurations.
|
||||
TZMM_MZ2000 EQU 010H + TZMM_ENIOWAIT; ; MZ2000 Mode - Running on MZ2000 hardware, configuration set according to runtime configuration registers.
|
||||
TZMM_FPGA EQU 015H + TZMM_ENIOWAIT ; Open up access for the K64F to the FPGA resources such as memory. All other access to RAM or mainboard is blocked.
|
||||
TZMM_TZPUM EQU 016H + TZMM_ENIOWAIT ; Everything in on mainboard, no access to tranZPUter memory.
|
||||
TZMM_TZPU EQU 017H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
|
||||
;TZMM_TZPU0 EQU 018H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
|
||||
;TZMM_TZPU1 EQU 019H + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 1 is selected.
|
||||
;TZMM_TZPU2 EQU 01AH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 2 is selected.
|
||||
;TZMM_TZPU3 EQU 01BH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 3 is selected.
|
||||
;TZMM_TZPU4 EQU 01CH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 4 is selected.
|
||||
;TZMM_TZPU5 EQU 01DH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 5 is selected.
|
||||
;TZMM_TZPU6 EQU 01EH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 6 is selected.
|
||||
;TZMM_TZPU7 EQU 01FH + TZMM_ENIOWAIT ; Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 7 is selected.
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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
|
||||
|
||||
;-----------------------------------------------
|
||||
; Entry/compilation start points.
|
||||
;-----------------------------------------------
|
||||
TPSTART: EQU 010F0h
|
||||
MEMSTART: EQU 01200h
|
||||
MSTART: EQU 0E900h
|
||||
MZFHDRSZ EQU 128
|
||||
TZFSSECTSZ EQU 256
|
||||
MROMSIZE EQU 4096
|
||||
UROMSIZE EQU 2048
|
||||
FNSIZE EQU 17
|
||||
|
||||
;-----------------------------------------------
|
||||
; RAM Banks, 0-3 are reserved for TZFS code in
|
||||
; the User/Floppy ROM bank area.
|
||||
;-----------------------------------------------
|
||||
USRROMPAGES EQU 3 ; User ROM
|
||||
ROMBANK0 EQU 0 ; TZFS Bank 0 - Main RFS Entry point and functions.
|
||||
ROMBANK1 EQU 1 ; TZFS Bank 1 -
|
||||
ROMBANK2 EQU 2 ; TZFS Bank 2 -
|
||||
ROMBANK3 EQU 3 ; TZFS Bank 3 -
|
||||
|
||||
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 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.
|
||||
193
software/asm/include/tzfs_mondef.asm
Normal file
193
software/asm/include/tzfs_mondef.asm
Normal file
@@ -0,0 +1,193 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;-
|
||||
;- Name: tzfs_mondef.asm
|
||||
;- Created: September 2019
|
||||
;- Author(s): Philip Smart
|
||||
;- Description: Sharp MZ series tzfs (tranZPUter Filing System).
|
||||
;- This assembly language program is a branch from the original RFS written for the
|
||||
;- MZ80A_RFS upgrade board. It is adapted to work within the similar yet different
|
||||
;- environment of the tranZPUter SW which has a large RAM capacity (512K) and an
|
||||
;- I/O processor in the K64F/ZPU.
|
||||
;-
|
||||
;- This file contains the SA-1510/1Z-013A monitor specific definitions.
|
||||
;-
|
||||
;- Credits:
|
||||
;- Copyright: (c) 2019-21 Philip Smart <philip.smart@net2net.org>
|
||||
;-
|
||||
;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW.
|
||||
;- July 2020 - Updates to accommodate v2.1 of the tranZPUter board.
|
||||
;-
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;- 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/>.
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
|
||||
;-------------------------------------------------------
|
||||
; 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
|
||||
|
||||
; ROM location differences between the MZ80A and MZ-700.
|
||||
IF BUILD_MZ80A > 0
|
||||
SS: EQU 00089h
|
||||
ST1: EQU 00095h
|
||||
WTAPE: EQU 00485H
|
||||
MOTOR: EQU 006A3H
|
||||
?MODE: EQU 0074DH
|
||||
?KEY EQU 008CAh
|
||||
DLY12: EQU 00DA7h
|
||||
DLY12A: EQU 00DAAh
|
||||
ELSE
|
||||
SS: EQU 000A2H
|
||||
ST1: EQU 000ADH
|
||||
WTAPE: EQU 0048AH
|
||||
MOTOR: EQU 0069FH
|
||||
?MODE: EQU 0073EH
|
||||
?KEY EQU 009B3H
|
||||
DLY12: EQU 00996H
|
||||
ENDIF
|
||||
|
||||
;-----------------------------------------------
|
||||
; 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
|
||||
|
||||
; 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
|
||||
123
software/asm/include/tzfs_svcstruct.asm
Normal file
123
software/asm/include/tzfs_svcstruct.asm
Normal file
@@ -0,0 +1,123 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;-
|
||||
;- Name: tzfs_svcstruct.asm
|
||||
;- Created: September 2019
|
||||
;- Author(s): Philip Smart
|
||||
;- Description: Sharp MZ series tzfs (tranZPUter Filing System).
|
||||
;- This assembly language program is a branch from the original RFS written for the
|
||||
;- MZ80A_RFS upgrade board. It is adapted to work within the similar yet different
|
||||
;- environment of the tranZPUter SW which has a large RAM capacity (512K) and an
|
||||
;- I/O processor in the K64F/ZPU.
|
||||
;-
|
||||
;- This file holds the TZFS service structure definition.
|
||||
;-
|
||||
;- Credits:
|
||||
;- Copyright: (c) 2019-21 Philip Smart <philip.smart@net2net.org>
|
||||
;-
|
||||
;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW.
|
||||
;- July 2020 - Updates to accommodate v2.1 of the tranZPUter board.
|
||||
;-
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;- 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/>.
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
|
||||
TZSVC_CMD_READDIR EQU 01H ; Service command to open a directory and return the first block of entries.
|
||||
TZSVC_CMD_NEXTDIR EQU 02H ; Service command to return the next block of an open directory.
|
||||
TZSVC_CMD_READFILE EQU 03H ; Service command to open a file and return the first block.
|
||||
TZSVC_CMD_NEXTREADFILE EQU 04H ; Service command to return the next block of an open file.
|
||||
TZSVC_CMD_WRITEFILE EQU 05H ; Service command to create a file and save the first block.
|
||||
TZSVC_CMD_NEXTWRITEFILE EQU 06H ; Service command to write the next block to the open file.
|
||||
TZSVC_CMD_CLOSE EQU 07H ; Service command to close any open file or directory.
|
||||
TZSVC_CMD_LOADFILE EQU 08H ; Service command to load a file directly into tranZPUter memory.
|
||||
TZSVC_CMD_SAVEFILE EQU 09H ; Service command to save a file directly from tranZPUter memory.
|
||||
TZSVC_CMD_ERASEFILE EQU 0aH ; Service command to erase a file on the SD card.
|
||||
TZSVC_CMD_CHANGEDIR EQU 0bH ; Service command to change the active directory on the SD card.
|
||||
TZSVC_CMD_LOAD40ABIOS EQU 20H ; Service command requesting that the 40 column version of the SA1510 BIOS is loaded.
|
||||
TZSVC_CMD_LOAD80ABIOS EQU 21H ; Service command requesting that the 80 column version of the SA1510 BIOS is loaded.
|
||||
TZSVC_CMD_LOAD700BIOS40 EQU 22H ; Service command requesting that the MZ700 1Z-013A 40 column BIOS is loaded.
|
||||
TZSVC_CMD_LOAD700BIOS80 EQU 23H ; Service command requesting that the MZ700 1Z-013A 80 column patched BIOS is loaded.
|
||||
TZSVC_CMD_LOAD80BIPL EQU 24H ; Service command requesting the MZ-80B IPL is loaded.
|
||||
TZSVC_CMD_LOAD800BIOS EQU 25H ; Service command requesting that the MZ800 9Z-504M BIOS is loaded.
|
||||
TZSVC_CMD_LOAD2KIPL EQU 26H ; Service command requesting the MZ-2000 IPL is loaded.
|
||||
TZSVC_CMD_LOAD2KBASIC1 EQU 27H ; Service command to load BASIC 1Z-001 for the MZ-2000.
|
||||
TZSVC_CMD_LOAD2KBASIC2 EQU 28H ; Service command to load BASIC 1Z-002 for the MZ-2000.
|
||||
TZSVC_CMD_LOAD2KMON EQU 29H ; Service command to load Monitor 1Z001M for the MZ-2000 IPL.
|
||||
TZSVC_CMD_LOADTZFS EQU 2FH ; Service command requesting the loading of TZFS. This service is for machines which normally dont have a monitor BIOS. ie. MZ-80B/MZ-2000 and manually request TZFS.
|
||||
TZSVC_CMD_LOADBDOS EQU 30H ; Service command to reload CPM BDOS+CCP.
|
||||
TZSVC_CMD_ADDSDDRIVE EQU 31H ; Service command to attach a CPM disk to a drive number.
|
||||
TZSVC_CMD_READSDDRIVE EQU 32H ; Service command to read an attached SD file as a CPM disk drive.
|
||||
TZSVC_CMD_WRITESDDRIVE EQU 33H ; Service command to write to a CPM disk drive which is an attached SD file.
|
||||
TZSVC_CMD_CPU_BASEFREQ EQU 40H ; Service command to switch to the mainboard frequency.
|
||||
TZSVC_CMD_CPU_ALTFREQ EQU 41H ; Service command to switch to the alternate frequency provided by the K64F.
|
||||
TZSVC_CMD_CPU_CHGFREQ EQU 42H ; Service command to set the alternate frequency in hertz.
|
||||
TZSVC_CMD_CPU_SETZ80 EQU 50H ; Service command to switch to the external Z80 hard cpu.
|
||||
TZSVC_CMD_CPU_SETT80 EQU 51H ; Service command to switch to the internal T80 soft cpu.
|
||||
TZSVC_CMD_CPU_SETZPUEVO EQU 52H ; Service command to switch to the internal ZPU Evolution soft cpu.
|
||||
TZSVC_CMD_EMU_SETMZ80K EQU 53H ; Service command to switch to the internal Sharp MZ Series Emulation of the MZ80K.
|
||||
TZSVC_CMD_EMU_SETMZ80C EQU 54H ; "" "" "" MZ80C.
|
||||
TZSVC_CMD_EMU_SETMZ1200 EQU 55H ; "" "" "" MZ1200.
|
||||
TZSVC_CMD_EMU_SETMZ80A EQU 56H ; "" "" "" MZ80A.
|
||||
TZSVC_CMD_EMU_SETMZ700 EQU 57H ; "" "" "" MZ700.
|
||||
TZSVC_CMD_EMU_SETMZ800 EQU 58H ; "" "" "" MZ800.
|
||||
TZSVC_CMD_EMU_SETMZ1500 EQU 59H ; "" "" "" MZ1500.
|
||||
TZSVC_CMD_EMU_SETMZ80B EQU 5AH ; "" "" "" MZ80B.
|
||||
TZSVC_CMD_EMU_SETMZ2000 EQU 5BH ; "" "" "" MZ2000.
|
||||
TZSVC_CMD_EMU_SETMZ2200 EQU 5CH ; "" "" "" MZ2200.
|
||||
TZSVC_CMD_EMU_SETMZ2500 EQU 5DH ; "" "" "" MZ2500.
|
||||
TZSVC_CMD_EXIT EQU 07FH ; Service command to terminate TZFS and restart the machine in original mode.
|
||||
TZSVC_STATUS_OK EQU 000H ; Flag to indicate the K64F processing completed successfully.
|
||||
TZSVC_STATUS_REQUEST EQU 0FEH ; Flag to indicate the Z80 has made a request to the K64F.
|
||||
TZSVC_STATUS_PROCESSING EQU 0FFH ; Flag to indicate the K64F is processing a command.
|
||||
|
||||
|
||||
; Variables and control structure used by the I/O processor for service calls and requests.
|
||||
ORG TZSVCMEM
|
||||
|
||||
;TZSVCMEM: EQU 0ED80H ; 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 5 ; 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_MZFHDR: EQU 1 ; File type being handled is an MZF Header.
|
||||
TZSVC_FTYPE_CAS: EQU 2 ; File type being handled is an CASsette BASIC script.
|
||||
TZSVC_FTYPE_BAS: EQU 3 ; 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_SECTOR_LBA: EQU TZSVC_TRACK_NO ; Sector in 32bit LBA format.
|
||||
TZSVC_MEM_TARGET: EQU TZSVC_TRACK_NO ; Memory command should target, 0 = tranZPUter, 1 = mainboard.
|
||||
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.
|
||||
|
||||
498
software/asm/include/tzfs_utilities.asm
Normal file
498
software/asm/include/tzfs_utilities.asm
Normal file
@@ -0,0 +1,498 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;-
|
||||
;- Name: RFS_Utilities.asm
|
||||
;- Created: September 2019
|
||||
;- Author(s): Philip Smart
|
||||
;- Description: Sharp MZ series tzfs (tranZPUter Filing System).
|
||||
;- This assembly language program is a branch from the original RFS written for the
|
||||
;- MZ80A_RFS upgrade board. It is adapted to work within the similar yet different
|
||||
;- environment of the tranZPUter SW which has a large RAM capacity (512K) and an
|
||||
;- I/O processor in the K64F/ZPU.
|
||||
;-
|
||||
;- Credits:
|
||||
;- Copyright: (c) 2019-20 Philip Smart <philip.smart@net2net.org>
|
||||
;-
|
||||
;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW.
|
||||
;-
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;- 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
|
||||
77
software/asm/include/tzfs_variables.asm
Normal file
77
software/asm/include/tzfs_variables.asm
Normal file
@@ -0,0 +1,77 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;-
|
||||
;- Name: tzfs_variales.asm
|
||||
;- Created: September 2019
|
||||
;- Author(s): Philip Smart
|
||||
;- Description: Sharp MZ series tzfs (tranZPUter Filing System).
|
||||
;- This assembly language program is a branch from the original RFS written for the
|
||||
;- MZ80A_RFS upgrade board. It is adapted to work within the similar yet different
|
||||
;- environment of the tranZPUter SW which has a large RAM capacity (512K) and an
|
||||
;- I/O processor in the K64F/ZPU.
|
||||
;-
|
||||
;- This file holds the TZFS variable definitions.
|
||||
;-
|
||||
;- Credits:
|
||||
;- Copyright: (c) 2019-21 Philip Smart <philip.smart@net2net.org>
|
||||
;-
|
||||
;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW.
|
||||
;- July 2020 - Updates to accommodate v2.1 of the tranZPUter board.
|
||||
;-
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;- 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/>.
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
|
||||
; Starting EC80H - variables used by the filing system.
|
||||
ORG TZVARMEM
|
||||
|
||||
;TZVARMEM: EQU 0EC80H
|
||||
;TZVARSIZE: EQU 00100H
|
||||
WARMSTART: DS virtual 1 ; Warm start mode, 0 = cold start, 1 = warm start.
|
||||
SCRNMODE: DS virtual 1 ; Mode of screen, [0] = 0 - 40 char, 1 - 80 char, [1] = 0 - Mainboard video, 1 - FPGA Video, [2] = 1 set VGA mode, 0 = standard, [7:4] Video mode.
|
||||
SCRNMODE2: DS virtual 1 ; Mode of screen, [3:0] - VGA mode.
|
||||
MMCFGVAL: DS virtual 1 ; Current memory model value.
|
||||
HLSAVE: DS virtual 2 ; Storage for HL during bank switch manipulation.
|
||||
AFSAVE: DS virtual 2 ; Storage for AF during bank switch manipulation.
|
||||
FNADDR: DS virtual 2 ; Function to be called address.
|
||||
TMPADR: DS virtual 2 ; TEMPORARY ADDRESS STORAGE
|
||||
TMPSIZE: DS virtual 2 ; TEMPORARY SIZE
|
||||
TMPCNT: DS virtual 2 ; TEMPORARY COUNTER
|
||||
TMPLINECNT: DS virtual 2 ; Temporary counter for displayed lines.
|
||||
TMPSTACKP: DS virtual 2 ; Temporary stack pointer save.
|
||||
DUMPADDR: DS virtual 2 ; Address used by the D(ump) command so that calls without parameters go onto the next block.
|
||||
CMTLOLOAD: DS virtual 1 ; Flag to indicate that a tape program is loaded into hi memory then shifted to low memory after ROM pageout.
|
||||
CMTCOPY: DS virtual 1 ; Flag to indicate that a CMT copy operation is taking place.
|
||||
CMTAUTOEXEC: DS virtual 1 ; Auto execution flag, run CMT program when loaded if flag clear.
|
||||
DTADRSTORE: DS virtual 2 ; Backup for load address if actual load shifts to lo memory or to 0x1200 for copy.
|
||||
SDCOPY: DS virtual 1 ; Flag to indicate an SD copy is taking place, either CMT->SD or SD->CMT.
|
||||
RESULT: DS virtual 1 ; Result variable needed for interbank calls when a result is needed.
|
||||
SDAUTOEXEC: DS virtual 1 ; Flag to indicate if a loaded file should be automatically executed.
|
||||
FDCCMD: DS virtual 1 ; Floppy disk command storage.
|
||||
MOTON: DS virtual 1 ; Motor on flag.
|
||||
TRK0FD1: DS virtual 1 ; Floppy Disk 1 track 0 indicator.
|
||||
TRK0FD2: DS virtual 1 ; Floppy Disk 2 track 0 indicator.
|
||||
TRK0FD3: DS virtual 1 ; Floppy Disk 3 track 0 indicator.
|
||||
TRK0FD4: DS virtual 1 ; Floppy Disk 4 track 0 indicator.
|
||||
RETRIES: DS virtual 1 ; Retries count for a command.
|
||||
BPARA: DS virtual 1
|
||||
CMTINACTIVE: DS virtual 1 ; Flag to indicate if the CMT is inactive (1)/SD active (0) for the CMT wrapper handlers.
|
||||
CMTFILENO: DS virtual 1 ; Sequential file access file number. Used when no filename is given, uses the directory entry number for the set wildcard,
|
||||
HWMODEL: DS virtual 1 ; Model of machine to tailor code execution
|
||||
CMTSAMPLECNT: DS virtual 1 ; Delay count for bit sampling.
|
||||
CMTDLY1CNTM: DS virtual 1 ; Short pulse delay count MARK
|
||||
CMTDLY1CNTS: DS virtual 1 ; Short pulse delay count SPACE
|
||||
CMTDLY2CNTM: DS virtual 1 ; Long pulse delay count MARK
|
||||
CMTDLY2CNTS: DS virtual 1 ; Long pulse delay count SPACE
|
||||
DS virtual (TZVARMEM + TZVARSIZE) - $ ; Top of variable area downwards is used as the working stack, SA1510 space isnt used.
|
||||
TZSTACK: EQU TZVARMEM + TZVARSIZE
|
||||
8
software/asm/monitor_1z-013a-2000.asm
Normal file
8
software/asm/monitor_1z-013a-2000.asm
Normal 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.
|
||||
MODE80C:EQU 0 ; Monitor is being built for an 80 column display.
|
||||
MODE2K: EQU 1 ; Monitor is being built for an MZ-2000 machine.
|
||||
|
||||
INCLUDE "1z-013a.asm"
|
||||
8
software/asm/monitor_1z-013a-km.asm
Normal file
8
software/asm/monitor_1z-013a-km.asm
Normal 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.
|
||||
MODE80C:EQU 0 ; Monitor is being built for an 80 column display.
|
||||
MODE2K: EQU 0 ; Monitor is being built for an MZ-2000 machine.
|
||||
|
||||
INCLUDE "1z-013a-km.asm"
|
||||
8
software/asm/monitor_1z-013a.asm
Normal file
8
software/asm/monitor_1z-013a.asm
Normal 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.
|
||||
MODE80C:EQU 0 ; Monitor is being built for an 80 column display.
|
||||
MODE2K: EQU 0 ; Monitor is being built for an MZ-2000 machine.
|
||||
|
||||
INCLUDE "1z-013a.asm"
|
||||
8
software/asm/monitor_80c_1z-013a-km.asm
Normal file
8
software/asm/monitor_80c_1z-013a-km.asm
Normal 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.
|
||||
MODE80C:EQU 1 ; Monitor is being built for an 80 column display.
|
||||
MODE2K: EQU 0 ; Monitor is being built for an MZ-2000 machine.
|
||||
|
||||
INCLUDE "1z-013a-km.asm"
|
||||
8
software/asm/monitor_80c_1z-013a.asm
Normal file
8
software/asm/monitor_80c_1z-013a.asm
Normal 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.
|
||||
MODE80C:EQU 1 ; Monitor is being built for an 80 column display.
|
||||
MODE2K: EQU 0 ; Monitor is being built for an MZ-2000 machine.
|
||||
|
||||
INCLUDE "1z-013a.asm"
|
||||
9
software/asm/monitor_80c_sa1510.asm
Normal file
9
software/asm/monitor_80c_sa1510.asm
Normal file
@@ -0,0 +1,9 @@
|
||||
; 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
|
||||
KUMA: EQU 0
|
||||
|
||||
INCLUDE "sa1510.asm"
|
||||
9
software/asm/monitor_kuma_sa1510.asm
Normal file
9
software/asm/monitor_kuma_sa1510.asm
Normal file
@@ -0,0 +1,9 @@
|
||||
; 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 0
|
||||
KUMA: EQU 1
|
||||
|
||||
INCLUDE "sa1510.asm"
|
||||
9
software/asm/monitor_sa1510.asm
Normal file
9
software/asm/monitor_sa1510.asm
Normal file
@@ -0,0 +1,9 @@
|
||||
; 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
|
||||
KUMA: EQU 0
|
||||
|
||||
INCLUDE "sa1510.asm"
|
||||
9699
software/asm/msbasic.asm
Normal file
9699
software/asm/msbasic.asm
Normal file
File diff suppressed because it is too large
Load Diff
617
software/asm/mz-1e05.asm
Normal file
617
software/asm/mz-1e05.asm
Normal file
@@ -0,0 +1,617 @@
|
||||
; V1.10
|
||||
;
|
||||
; To compile use:
|
||||
;
|
||||
; AS80 [1.31] - Assembler for 8080/8085/Z80 microprocessor.
|
||||
;
|
||||
; Available from:
|
||||
; - http://www.falstaff.demon.co.uk/cross.html
|
||||
; - ftp://ftp.simtel.net/pub/simtelnet/msdos/crossasm/as80_131.zip
|
||||
; - and many Simtel mirrors.
|
||||
;
|
||||
; as80 -i -l -n -x2 -v -z mz-1e05.asm
|
||||
|
||||
|
||||
|
||||
|
||||
;
|
||||
;----< MFM Minifloppy control >----
|
||||
;
|
||||
;
|
||||
; Call condition
|
||||
;
|
||||
; Case of disk initialize
|
||||
; Drive N = IX+0 (0 - 3)
|
||||
;
|
||||
;
|
||||
; Case of sequential read & write
|
||||
; Drive N = IX+0 (0 - 3)
|
||||
;
|
||||
; Sector addrs = IX+1,2 (0 - $045F) H C S
|
||||
; (0 - 1119) -> 70 x 16 sectors -> 2 x 35 x 16
|
||||
; Byte size = IX+3,4
|
||||
; Address = IX+5,6
|
||||
; Next track = IX+7
|
||||
; Next sector = IX+8
|
||||
; Start track = IX+9
|
||||
; Start sector = IX+10
|
||||
;
|
||||
;
|
||||
; I/O Port address
|
||||
;
|
||||
CR EQU $D8 ; CommandRegister
|
||||
TR EQU $D9 ; TrackRegister
|
||||
SCR EQU $DA ; SeCtorRegister
|
||||
DR EQU $DB ; DataRegister
|
||||
DM EQU $DC ; DriveMotor
|
||||
HS EQU $DD ; HeadSelect
|
||||
|
||||
|
||||
|
||||
TIMST EQU $0033
|
||||
|
||||
;
|
||||
; Subroutine work
|
||||
;
|
||||
BPRO EQU $CF00
|
||||
BUF EQU $11A3
|
||||
BPARA EQU BPRO - 23 ; BootPARAmeter
|
||||
|
||||
|
||||
CMD EQU BPARA + 11 ; CoMmanD
|
||||
MTFG EQU CMD + 1 ; MoTorFlaG
|
||||
CLBF0 EQU MTFG + 1
|
||||
CLBF1 EQU CLBF0 + 1
|
||||
CLBF2 EQU CLBF1 + 1
|
||||
CLBF3 EQU CLBF2 + 1
|
||||
VRFCNT EQU CLBF3 + 1 ; VeRiFyCouNT
|
||||
STAFG EQU VRFCNT + 1 ; STAtusFlaG
|
||||
|
||||
|
||||
;
|
||||
;
|
||||
;--------< Ercode map >--------
|
||||
;
|
||||
; 50 : Not ready
|
||||
; 41 : Data error
|
||||
; Track 80 err
|
||||
; Write protect err
|
||||
; Seek err
|
||||
; CRC err
|
||||
; Lost data
|
||||
; 54 : Unformat
|
||||
; Recode not found
|
||||
; 56 : Invalid data
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
ORG $F000
|
||||
|
||||
|
||||
MZ_1E05:
|
||||
NOP
|
||||
LD HL,$00AD
|
||||
JR L_F007
|
||||
FDX:
|
||||
EX (SP),HL
|
||||
L_F007:
|
||||
LD (BPARA + 21),HL
|
||||
XOR A
|
||||
LD DE,0
|
||||
CALL TIMST
|
||||
CALL FDCC ; FD i/o check
|
||||
JP NZ,NOTIO
|
||||
LD DE,BPARA ; destination address
|
||||
LD HL,BOOT ; source address
|
||||
LD BC,11 ; 11 bytes
|
||||
LDIR ; copy
|
||||
SJP:
|
||||
LD IX,BPARA
|
||||
CALL BREAD ; read from drive 0, sector 0,
|
||||
;
|
||||
LD HL,BPRO ; compare this address
|
||||
LD DE,IPLMC ; with the IPL MasterCode
|
||||
LD B,7 ; this are 7 bytes : 3,'IPLPRO'
|
||||
MCHECK:
|
||||
LD C,(HL)
|
||||
LD A,(DE)
|
||||
CP C
|
||||
JP NZ,MASTE ; not equal than MasterError
|
||||
INC HL
|
||||
INC DE
|
||||
DJNZ MCHECK
|
||||
; else Master was found
|
||||
LD DE,IPLM0 ; 'IPL IS LOADING'
|
||||
RST $18
|
||||
LD DE,BPRO + 7 ; NAME
|
||||
RST $18
|
||||
LD HL,(BPRO + $16) ; TARGETADDRESS from BootBlock
|
||||
LD A,H
|
||||
OR L
|
||||
JR NZ,L_F051 ; if it is != 0 than normal file
|
||||
LD HL,(BPRO + $18) ; TARGETADDRESS from BootBlock
|
||||
LD A,H
|
||||
OR L
|
||||
JR Z,L_F057 ; if it is also 0 than ROM replace file
|
||||
L_F051:
|
||||
XOR A ; else normal file,
|
||||
LD HL,(BPRO + $18) ; TARGETADDRESS from BootBlock
|
||||
JR L_F05C
|
||||
L_F057:
|
||||
LD A,$FF ; target is at $0000, bankswitching is needed
|
||||
LD HL,$1200 ; for now use temporary buffer at $1200
|
||||
L_F05C:
|
||||
LD ($CEFD),A
|
||||
|
||||
LD (IX + 5),L ; set the TargetAddress
|
||||
LD (IX + 6),H
|
||||
|
||||
LD HL,(BPRO + $14) ; BYTE SIZE from BootBlock
|
||||
LD (IX + 3),L
|
||||
LD (IX + 4),H
|
||||
|
||||
LD HL,(BPRO + $1E) ; START SECTOR from BootBlock
|
||||
LD (IX + 1),L
|
||||
LD (IX + 2),H
|
||||
;
|
||||
CALL BREAD
|
||||
CALL MOFF
|
||||
|
||||
LD A,($CEFD)
|
||||
CP $FF
|
||||
JR NZ,L_F093
|
||||
OUT ($E0),A
|
||||
LD HL,$1200 ; SourceAddress
|
||||
LD DE,(BPRO + $16) ; TargetAddress
|
||||
LD BC,(BPRO + $14) ; ByteCounter
|
||||
LDIR ; copy
|
||||
L_F093:
|
||||
LD BC,$0200 ; Default code
|
||||
LD HL,(BPRO + $18) ; TARGET/EXECUTION ADDRESS from BootBlock
|
||||
JP (HL)
|
||||
|
||||
MASTE:
|
||||
CALL MOFF
|
||||
LD DE,ERRM1 ; 'NOT MASTER'
|
||||
JR ERRTR1
|
||||
ERRTRT:
|
||||
CP 50
|
||||
NOTIO:
|
||||
LD DE,IPLM3 ; 'MAKE READY FD'
|
||||
JR Z,ERRTR1
|
||||
LD DE,ERRM0 ; 'FD:LOADING ERROR'
|
||||
ERRTR1:
|
||||
CALL $0009
|
||||
RST $18
|
||||
LD SP,$10EE
|
||||
LD HL,(BPARA + 21)
|
||||
EX (SP),HL
|
||||
RET
|
||||
;
|
||||
;
|
||||
; PARAMETER SETTING
|
||||
;
|
||||
IPLMC:
|
||||
DB $03 ; IPL MASTER FLAG
|
||||
DB 'IPLPRO'
|
||||
|
||||
BOOT:
|
||||
DB $00 ; DRIVE NO.
|
||||
DW $0000 ; SECTOR ADDR.
|
||||
DW $0100 ; IFM BYTE SIZE
|
||||
DW BPRO ; IFM LOADING ADDR.
|
||||
DW $0000 ; IX+7,8 (track 0, sector 0)
|
||||
|
||||
|
||||
|
||||
ERRM1:
|
||||
DB 'FD:NOT MASTER',$0D
|
||||
IPLM0:
|
||||
DB 'IPL IS LOADING ',$0D
|
||||
IPLM3:
|
||||
DB 'MAKE READY FD',$0D
|
||||
ERRM0:
|
||||
DB 'FD:LOADING ERROR',$0D
|
||||
|
||||
FDCC:
|
||||
LD A,$A5
|
||||
LD B,A
|
||||
OUT (TR),A
|
||||
CALL DLY80U
|
||||
IN A,(TR)
|
||||
CP B
|
||||
RET
|
||||
|
||||
L_F111:
|
||||
DB $00, $00
|
||||
;
|
||||
;
|
||||
; READY CHECK
|
||||
;
|
||||
READY:
|
||||
LD A,(MTFG)
|
||||
RRCA
|
||||
CALL NC,MTON
|
||||
LD A,(IX + 0) ; DRIVE NO SET
|
||||
OR $84
|
||||
OUT (DM),A ; DRIVE SELECT MOTON
|
||||
XOR A
|
||||
LD (CMD),A
|
||||
CALL DLY60M
|
||||
LD HL,0
|
||||
REDY0:
|
||||
DEC HL
|
||||
LD A,H
|
||||
OR L
|
||||
JR Z,REDY1
|
||||
IN A,(CR) ; STATUS GET
|
||||
CPL
|
||||
RLCA
|
||||
JR C,REDY0
|
||||
LD C,(IX + 0)
|
||||
LD HL,CLBF0
|
||||
LD B,$00
|
||||
ADD HL,BC
|
||||
BIT 0,(HL)
|
||||
JR NZ,REDY2
|
||||
CALL RCLB
|
||||
SET 0,(HL)
|
||||
REDY2:
|
||||
RET
|
||||
|
||||
REDY1:
|
||||
LD A,$32
|
||||
JP ERJMP
|
||||
;
|
||||
;
|
||||
; MOTOR ON
|
||||
;
|
||||
MTON:
|
||||
LD A,$80
|
||||
OUT (DM),A
|
||||
LD B,16
|
||||
MTD1:
|
||||
CALL DLY60M
|
||||
DJNZ MTD1
|
||||
LD A,1
|
||||
LD (MTFG),A
|
||||
RET
|
||||
;
|
||||
;
|
||||
; SEEK TREATMENT
|
||||
;
|
||||
SEEK:
|
||||
LD A,$1B ; 1x = SEEK,
|
||||
CALL CMDOT1 ; load head, no verify, max stepping rate
|
||||
AND $99
|
||||
RET
|
||||
;
|
||||
;
|
||||
; MOTOR OFF
|
||||
;
|
||||
MOFF:
|
||||
PUSH AF
|
||||
CALL DLY1M ; 1000 US DELAY
|
||||
XOR A
|
||||
OUT (DM),A
|
||||
LD (CLBF0),A
|
||||
LD (CLBF1),A
|
||||
LD (CLBF2),A
|
||||
LD (CLBF3),A
|
||||
LD (MTFG),A
|
||||
POP AF
|
||||
RET
|
||||
;
|
||||
;
|
||||
; RECALIBRATION
|
||||
;
|
||||
RCLB:
|
||||
LD A,$0B ; 0x = RESTORE (seek track 0)
|
||||
CALL CMDOT1 ; load head, no verify, max stepping rate
|
||||
AND $85
|
||||
XOR $04
|
||||
RET Z
|
||||
|
||||
L_F189:
|
||||
JP ERROR
|
||||
;
|
||||
;
|
||||
; COMMAND OUT ROUTINE
|
||||
;
|
||||
CMDOT1:
|
||||
LD (CMD),A
|
||||
CPL
|
||||
OUT (CR),A
|
||||
CALL BSYON
|
||||
CALL DLY60M
|
||||
IN A,(CR)
|
||||
CPL
|
||||
LD (STAFG),A
|
||||
RET
|
||||
;
|
||||
;
|
||||
; BUSY AND WAIT
|
||||
;
|
||||
BSYON:
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
CALL BSY0
|
||||
BSYON2:
|
||||
LD HL,$0000
|
||||
BSYON0:
|
||||
DEC HL
|
||||
LD A,H
|
||||
OR L
|
||||
JR Z,BSYON1
|
||||
IN A,(CR)
|
||||
RRCA
|
||||
JR NC,BSYON0
|
||||
POP HL
|
||||
POP DE
|
||||
RET
|
||||
;
|
||||
BSYON1:
|
||||
DEC E
|
||||
JR NZ,BSYON2
|
||||
BSYONE:
|
||||
LD A,$29
|
||||
POP HL
|
||||
POP DE
|
||||
JP ERJMP
|
||||
;
|
||||
BSYOFF:
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
CALL BSY0
|
||||
BSYOF2:
|
||||
LD HL,$0000
|
||||
BSYOF0:
|
||||
DEC HL
|
||||
LD A,H
|
||||
OR L
|
||||
JR Z,BSYOF1
|
||||
IN A,(CR) ; Status Register
|
||||
RRCA
|
||||
JR C,BSYOF0
|
||||
POP HL
|
||||
POP DE
|
||||
RET
|
||||
;
|
||||
BSYOF1:
|
||||
DEC E
|
||||
JR NZ,BSYOF2
|
||||
JR BSYONE
|
||||
;
|
||||
BSY0:
|
||||
CALL DLY80U
|
||||
LD E,$07
|
||||
RET
|
||||
;
|
||||
;
|
||||
; SEQUENTIAL READ
|
||||
;
|
||||
BREAD:
|
||||
CALL CNVRT
|
||||
CALL PARST1 ; HL = IX + 5,6 (TargetAddress)
|
||||
RE8:
|
||||
CALL SIDST
|
||||
CALL SEEK
|
||||
JP NZ,ERJMP
|
||||
CALL PARST2 ; C = DataRegister
|
||||
DI ; disable interrupts
|
||||
LD A,$94 ; 9x = READ SECTOR, multiple records
|
||||
CALL CMDOT2 ; compare for side 0, 15ms delay,
|
||||
RE6: ; disable side select compare
|
||||
LD B,0 ; ByteCounter = 0, to load 256 bytes of the sector
|
||||
RE4:
|
||||
IN A,(CR)
|
||||
RRCA
|
||||
JR C,RE3
|
||||
RRCA
|
||||
JR C,RE4
|
||||
INI ; (HL) = in(C), B = B - 1 , HL = HL + 1
|
||||
JR NZ,RE4
|
||||
|
||||
INC (IX + 8) ; NextSector = NextSector + 1
|
||||
LD A,(IX + 8)
|
||||
CP $11 ; if NextSector = 17
|
||||
JR Z,L_F213 ; than end
|
||||
DEC D ; else SectorCounter = SectorCounter - 1
|
||||
JR NZ,RE6 ; if SectorCounter = 0
|
||||
JR L_F214 ; than end
|
||||
L_F213:
|
||||
DEC D
|
||||
L_F214:
|
||||
CALL INTER
|
||||
RE3:
|
||||
EI ; enable interrupts
|
||||
IN A,(CR)
|
||||
CPL
|
||||
LD (STAFG),A
|
||||
AND $FF
|
||||
JR NZ,ERROR
|
||||
CALL ADJ ; adjust sector and track
|
||||
JP Z,REND
|
||||
LD A,(IX + 7) ; track
|
||||
JR RE8
|
||||
REND:
|
||||
LD A,$80
|
||||
OUT (DM),A ; motor on
|
||||
RET
|
||||
;
|
||||
;
|
||||
; PARAMETER SET
|
||||
;
|
||||
;
|
||||
PARST1:
|
||||
CALL READY
|
||||
LD D,(IX + 4) ; D = bytes to read (highbyte) (256 bytes)
|
||||
LD A,(IX + 3) ; A = bytes to read (lowbyte)
|
||||
OR A ; if A = 0
|
||||
JR Z,L_F23F ; than it's ok
|
||||
INC D ; else read 256 bytes more (1 sector)
|
||||
L_F23F:
|
||||
LD A,(IX + 10) ; NextSector = StartSector
|
||||
LD (IX + 8),A
|
||||
|
||||
LD A,(IX + 9) ; NextTrack = StartTrack
|
||||
LD (IX + 7),A
|
||||
|
||||
LD L,(IX + 5) ; HL = TargetAddress
|
||||
LD H,(IX + 6)
|
||||
RET
|
||||
|
||||
;
|
||||
;
|
||||
; SIZE SEEK SET
|
||||
;
|
||||
SIDST:
|
||||
SRL A
|
||||
CPL
|
||||
OUT (DR),A
|
||||
JR NC,L_F25D ; NC than Head 0
|
||||
LD A,1 ; else Head 1
|
||||
JR L_F25E
|
||||
L_F25D:
|
||||
XOR A
|
||||
L_F25E:
|
||||
CPL
|
||||
OUT (HS),A ; set HeadSelect
|
||||
RET
|
||||
;
|
||||
;
|
||||
; TRACK & SECTOR SET
|
||||
;
|
||||
PARST2:
|
||||
LD C,DR
|
||||
LD A,(IX + 7) ; A = NextTrack
|
||||
SRL A
|
||||
CPL
|
||||
OUT (TR),A
|
||||
LD A,(IX + 8) ; A = NextSector
|
||||
CPL
|
||||
OUT (SCR),A
|
||||
RET
|
||||
;
|
||||
;
|
||||
; ADJUST SECT & TRACK
|
||||
;
|
||||
ADJ:
|
||||
LD A,(IX + 8) ; A = NextSector
|
||||
CP 17 ; if NextSector = 17
|
||||
JR NZ,L_F282 ; than the border is not reached
|
||||
LD A,$01 ; else
|
||||
LD (IX + 8),A ; NextSector = 1
|
||||
INC (IX + 7) ; NextTrack = NextTrack + 1
|
||||
L_F282:
|
||||
LD A,D
|
||||
OR A
|
||||
RET
|
||||
;
|
||||
;
|
||||
; COMMAND OUT & WAIT
|
||||
;
|
||||
CMDOT2:
|
||||
LD (CMD),A
|
||||
CPL
|
||||
OUT (CR),A
|
||||
CALL BSYOFF
|
||||
RET
|
||||
;
|
||||
;
|
||||
; FORCE INTERRUPT
|
||||
;
|
||||
INTER:
|
||||
LD A,$D8
|
||||
CPL
|
||||
OUT (CR),A
|
||||
CALL BSYON
|
||||
RET
|
||||
|
||||
;
|
||||
;
|
||||
; STATUS CHECK
|
||||
;
|
||||
ERROR:
|
||||
LD A,(CMD)
|
||||
CP $0B ; Restore (seek track 0)
|
||||
JR Z,ERCK1
|
||||
CP $1B ; Seek
|
||||
JR Z,ERCK1
|
||||
CP $F4 ; Write track
|
||||
JR Z,ERCK1
|
||||
LD A,(STAFG)
|
||||
BIT 7,A
|
||||
JR NZ,ERRET
|
||||
BIT 6,A
|
||||
JR NZ,ERRET1
|
||||
BIT 4,A
|
||||
LD A,54
|
||||
JR NZ,ERJMP
|
||||
JR ERRET1
|
||||
ERCK1:
|
||||
LD A,(STAFG)
|
||||
BIT 7,A
|
||||
JR NZ,ERRET
|
||||
ERRET1:
|
||||
LD A,41
|
||||
JR ERJMP
|
||||
ERRET:
|
||||
LD A,50
|
||||
ERJMP:
|
||||
CALL MOFF
|
||||
JP ERRTRT
|
||||
;
|
||||
;
|
||||
; SECTOR TO TRACK & SECTOR CONVERT
|
||||
;
|
||||
CNVRT:
|
||||
LD B,0 ; TrackCounter = 0
|
||||
LD DE,16 ; 16 sectors per track
|
||||
LD L,(IX + 1) ; HL = SectorAddress
|
||||
LD H,(IX + 2)
|
||||
XOR A
|
||||
TRANS0:
|
||||
SBC HL,DE ; SectorAddress - SectorPerTrack
|
||||
JR C,TRANS1 ; if < 0 than ready
|
||||
INC B ; else TrackCounter = TrackCounter + 1
|
||||
JR TRANS0 ; next try
|
||||
|
||||
TRANS1:
|
||||
ADD HL,DE ; undo the last substraction
|
||||
LD H,B
|
||||
INC L ; adjust sector (sector is 1..16 and not 0..15)
|
||||
LD (IX + 9),H ; set StartTrack
|
||||
LD (IX + 10),L ; set StartSector
|
||||
RET
|
||||
|
||||
;
|
||||
;
|
||||
; TIME DELAY ( 1m & 60m & 80u )
|
||||
;
|
||||
DLY80U:
|
||||
PUSH DE
|
||||
LD DE,15
|
||||
JP DLYT
|
||||
|
||||
DLY1M:
|
||||
PUSH DE
|
||||
LD DE,160
|
||||
JP DLYT
|
||||
|
||||
DLY60M:
|
||||
PUSH DE
|
||||
LD DE,8230
|
||||
DLYT:
|
||||
DEC DE
|
||||
LD A,E
|
||||
OR D
|
||||
JR NZ,DLYT
|
||||
POP DE
|
||||
RET
|
||||
|
||||
|
||||
ORG $FFF0
|
||||
|
||||
DB ' 84.03.14 V1.0A'
|
||||
1739
software/asm/mz2000_ipl.asm
Normal file
1739
software/asm/mz2000_ipl.asm
Normal file
File diff suppressed because it is too large
Load Diff
6
software/asm/mz2000_ipl_fusionx.asm
Normal file
6
software/asm/mz2000_ipl_fusionx.asm
Normal file
@@ -0,0 +1,6 @@
|
||||
; Configurable parameters.
|
||||
;BUILDVERSION EQU 0 ; Build original IPL ROM.
|
||||
;BUILDVERSION EQU 1 ; Build enhanced tranZPUter IPL ROM.
|
||||
BUILDVERSION EQU 2 ; Build enhanced for FusionX IPL ROM.
|
||||
|
||||
INCLUDE "mz2000_ipl.asm"
|
||||
5
software/asm/mz2000_ipl_original.asm
Normal file
5
software/asm/mz2000_ipl_original.asm
Normal file
@@ -0,0 +1,5 @@
|
||||
; Configurable parameters.
|
||||
BUILDVERSION EQU 0 ; Build original IPL ROM.
|
||||
;BUILDVERSION EQU 1 ; Build enhanced tranZPUter IPL ROM.
|
||||
|
||||
INCLUDE "mz2000_ipl.asm"
|
||||
5
software/asm/mz2000_ipl_tzpu.asm
Normal file
5
software/asm/mz2000_ipl_tzpu.asm
Normal file
@@ -0,0 +1,5 @@
|
||||
; Configurable parameters.
|
||||
;BUILDVERSION EQU 0 ; Build original IPL ROM.
|
||||
BUILDVERSION EQU 1 ; Build enhanced tranZPUter IPL ROM.
|
||||
|
||||
INCLUDE "mz2000_ipl.asm"
|
||||
4
software/asm/mz2000_mon_1z001m.asm
Normal file
4
software/asm/mz2000_mon_1z001m.asm
Normal file
@@ -0,0 +1,4 @@
|
||||
; Configurable parameters.
|
||||
BUILDVERSION EQU 2 ; Build enhanced tranZPUter IPL ROM.
|
||||
|
||||
INCLUDE "1Z001M.asm"
|
||||
2952
software/asm/mz800_1z_013b.asm
Normal file
2952
software/asm/mz800_1z_013b.asm
Normal file
File diff suppressed because it is too large
Load Diff
3164
software/asm/mz800_9z_504m.asm
Normal file
3164
software/asm/mz800_9z_504m.asm
Normal file
File diff suppressed because it is too large
Load Diff
1613
software/asm/mz800_iocs.asm
Normal file
1613
software/asm/mz800_iocs.asm
Normal file
File diff suppressed because it is too large
Load Diff
372
software/asm/mz80afi.asm
Normal file
372
software/asm/mz80afi.asm
Normal file
@@ -0,0 +1,372 @@
|
||||
; 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 "tzfs_definitions.asm"
|
||||
INCLUDE "tzfs_mondef.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
|
||||
904
software/asm/mz80b_ipl.asm
Normal file
904
software/asm/mz80b_ipl.asm
Normal file
@@ -0,0 +1,904 @@
|
||||
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
|
||||
;
|
||||
;
|
||||
; CALL - 17 T-states
|
||||
; LD - 7 T-states
|
||||
; DEC - 4 T-states
|
||||
; JP cc- 10 T-states
|
||||
; RET - 10 T-states
|
||||
; 17 + 7 + ((4+10)*49) + 10 = 720 * 1/4000000 = 180uS
|
||||
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)
|
||||
|
||||
; Align to ROM size.
|
||||
DS 0800H - 1 - ($ + 0800H - 1) % 0800H, 0FFh
|
||||
|
||||
;----------------------------------------------------------
|
||||
; 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
|
||||
661
software/asm/mz80kfdif.asm
Normal file
661
software/asm/mz80kfdif.asm
Normal file
@@ -0,0 +1,661 @@
|
||||
;
|
||||
; MZ-80K FDC ROM
|
||||
;
|
||||
ORG F000H
|
||||
F000 00 NOP
|
||||
F001 F3 DI
|
||||
F002 AF XOR A
|
||||
F003 329C11 LD (#119C),A ;clock off
|
||||
F006 3EC3 LD A,#C3 ;JP code for error trap
|
||||
F008 320B10 LD (#100B),A
|
||||
F00B 215AF0 LD HL,#F05A ;error can't boot
|
||||
F00E 220C10 LD (#100C),HL ;error trap
|
||||
F011 11F09F LD DE,#9FF0 ;transfer 9 bytes from
|
||||
F014 2187F0 LD HL,#F087 ;ROM to RAM for use
|
||||
;
|
||||
;IBT1
|
||||
;
|
||||
F017 010900 IBT1: LD BC,#0009 ;by (IX+D) in reader
|
||||
F01A EDB0 LDIR
|
||||
F01C CD0900 CALL CRLF ;NL
|
||||
F01F 117AF0 LD DE,MESS1
|
||||
F022 CD1500 CALL MESSAGE ;msg "BOOT DRIVE ?"
|
||||
F025 11009F LD DE,BUFF2
|
||||
F028 CD0300 CALL USER ;get line
|
||||
F02B 210C00 LD HL,#000C
|
||||
F02E 19 ADD HL,DE ;skip around msg
|
||||
F02F 7E LD A,(HL) ;pickup answer to prompt
|
||||
F030 FE0D CP #0D ;CR ?
|
||||
F032 2002 JR NZ,#F036 ;Z=CR assume drive 1
|
||||
F034 3E31 LD A,#31 ;ASCII for 1
|
||||
;
|
||||
;IBT2
|
||||
;
|
||||
F036 47 IBT2: LD B,A ;save driveno
|
||||
F037 E6F0 AND #F0 ;take ASCII and convert
|
||||
F039 FE30 CP #30 ;to numeric having
|
||||
F03B 20DF JR NZ,IBT1 ;checked >1 & <=4
|
||||
F03D 78 LD A,B ;get driveno
|
||||
F03E E60F AND #0F ;mask
|
||||
F040 3D DEC A ;-1 00-03
|
||||
F041 FE04 CP #04
|
||||
F043 30D7 JR NC,IBT1 ;dud key, >=4, try again
|
||||
F045 32F09F LD (#9FF0),A ;save drive no
|
||||
F048 321110 LD (#1011),A ;save drive no
|
||||
F04B DD21F09F LD IX,#9FF0 ;IX pointer to fdc parameters at 9FF0
|
||||
;ready for disk read
|
||||
F04F CD3BF1 CALL READER ;get boot records
|
||||
F052 3A0098 LD A,(#9800) ;1st byte of input buffer of boot records
|
||||
F055 FEC3 CP #C3 ;jump cmd?
|
||||
F057 CA0098 JP Z,#9800 ;yes, execute to 9800
|
||||
;
|
||||
;IBT3
|
||||
;
|
||||
F05A 31F010 IBT3: LD SP,#10F0 ;no, reset stack
|
||||
F05D CD0900 CALL CRLF ;NL
|
||||
F060 116CF0 LD DE,MESS2 ;msg can't boot
|
||||
F063 CD1500 CALL MESSAGE
|
||||
F066 CDA7F0 CALL MOTOFF ;motor off
|
||||
F069 C38200 JP MAINLP ;warm start, ret to monitor
|
||||
;
|
||||
;MESS2
|
||||
;
|
||||
F06C 45523A43 MESS2: DB "ER:CAN'T BOOT"
|
||||
F070 414E2754
|
||||
F074 20424F4F
|
||||
F078 54
|
||||
F079 0D DB 0DH
|
||||
;
|
||||
;MESS1
|
||||
;
|
||||
F07A 424F4F54 DB "BOOT DRIVE ?"
|
||||
F07E 20445249
|
||||
F082 5645203F
|
||||
F086 0D DB 0DH
|
||||
;
|
||||
;DDATA
|
||||
;fdc parameters
|
||||
;
|
||||
F087 00 DB 00H ;drive no-1
|
||||
F088 00 DB 00H ;trk*2 remainder = head
|
||||
F089 01 DB 01H ;sector no (range: 01 - 10)
|
||||
F08A 00 DB 00H ;$80 = add 1 record to read to (F08B)
|
||||
F08B 0700 DB 07H ;07H = 07*2 = 14 sectors to read, add 1 if (F08A = $80)
|
||||
F08D 0098 DB 00H,98H ;9800H = load addr.
|
||||
F08F 00 DB 00H ;no meaning
|
||||
;
|
||||
;MOTON
|
||||
;
|
||||
F090 C5 MOTON: PUSH BC ;starts motors
|
||||
F091 01F808 LD BC,#08F8
|
||||
F094 ED78 IN A,(C) ;start motor
|
||||
F096 010000 LD BC,#0000
|
||||
;
|
||||
;WAIT1
|
||||
;
|
||||
F099 0B WAIT1: DEC BC ;wait for motor to
|
||||
F09A 00 NOP ;get up to speed
|
||||
F09B 00 NOP
|
||||
F09C 78 LD A,B
|
||||
F09D B1 OR C
|
||||
F09E 20F9 JR NZ,WAIT1
|
||||
F0A0 3E01 LD A,#01
|
||||
F0A2 320210 LD (MOTFLG),A ;01=on 00=off
|
||||
F0A5 C1 POP BC
|
||||
F0A6 C9 RET
|
||||
;
|
||||
;MOTOFF
|
||||
;
|
||||
F0A7 C5 MOTOFF: PUSH BC ;stop motors
|
||||
F0A8 CDAEF1 CALL LNGDEL ;timed wait
|
||||
F0AB 01F800 LD BC,#00F8
|
||||
F0AE ED78 IN A,(C)
|
||||
F0B0 C1 POP BC
|
||||
F0B1 C9 RET
|
||||
;
|
||||
;SKZERO
|
||||
;
|
||||
F0B2 CDBDF0 SKZERO: CALL DREADY ;seek track 0
|
||||
F0B5 AF XOR A
|
||||
F0B6 D3F9 OUT (#F9),A ;clear track reg
|
||||
F0B8 320010 LD (#1000),A
|
||||
F0BB D3FA OUT (#FA),A ;send seek zero code
|
||||
;
|
||||
;DREADY
|
||||
;
|
||||
F0BD C5 DREADY: PUSH BC
|
||||
F0BE 010000 LD BC,#0000
|
||||
;
|
||||
;DRY1
|
||||
;
|
||||
F0C1 DBF9 DRY1: IN A,(#F9) ;get DRDY, CRDY, RQM
|
||||
F0C3 E603 AND #03 ;leave DRDY, CRDY
|
||||
;
|
||||
;DRY2
|
||||
;
|
||||
F0C5 FE02 DRY2: CP #02 ;wait for DRDY & CRDY
|
||||
F0C7 2002 JR NZ,WAIT2 ;no, =03
|
||||
F0C9 C1 POP BC ;yes, =02
|
||||
F0CA C9 RET
|
||||
;
|
||||
;WAIT2
|
||||
;
|
||||
F0CB 0B WAIT2: DEC BC
|
||||
F0CC 78 LD A,B
|
||||
F0CD B1 OR C
|
||||
F0CE 20F1 JR NZ,DRY1
|
||||
F0D0 C1 POP BC
|
||||
F0D1 3E32 LD A,#32
|
||||
F0D3 320810 LD (#1008),A ;error 40 (not found)
|
||||
F0D6 C30B10 JP #100B ;error can't boot
|
||||
;
|
||||
;STATUS
|
||||
;
|
||||
F0D9 DBFA STATUS: IN A,(#FA) ;read status
|
||||
F0DB E6F0 AND #F0
|
||||
F0DD 07 RLCA
|
||||
F0DE 30F9 JR NC,STATUS ;wait for CRDY
|
||||
F0E0 E6F0 AND #F0 ;mask leave CRDY, S1, S2, S3
|
||||
F0E2 0F RRCA ;move right until S§
|
||||
F0E3 0F RRCA ;is in B0
|
||||
F0E4 0F RRCA
|
||||
F0E5 0F RRCA
|
||||
F0E6 B7 OR A ;clear flags
|
||||
F0E7 C8 RET Z ;Z=ok
|
||||
F0E8 FE0C CP #0C ;0C=drive not ready etc.
|
||||
F0EA 2004 JR NZ,STS1
|
||||
F0EC 3E32 LD A,#32 ;error code 40 (not found)
|
||||
F0EE 180A JR STS3
|
||||
;
|
||||
STS1
|
||||
;
|
||||
F0F0 FE04 STS1: CP #04 ;04=ID not found
|
||||
F0F2 2004 JR NZ,STS2
|
||||
F0F4 3E36 LD A,#36 ;error code 54 (unformat error)
|
||||
F0F6 1802 JR STS3
|
||||
;
|
||||
;STS2
|
||||
;
|
||||
F0F8 3E29 STS2: LD A,#29
|
||||
F0FA 320810 LD (#1008),A ;error code 41 disk hw error
|
||||
F0FD 37 SCF
|
||||
F0FE C9 RET
|
||||
;
|
||||
;PRMDRV
|
||||
;
|
||||
F0FF C5 PRMDRV: PUSH BC ;prime drive
|
||||
F100 E5 PUSH HL
|
||||
F101 CD90F0 CALL MOTON
|
||||
F104 DD7E00 LD A,(IX+#00) ;get drive no-1
|
||||
F107 E603 AND #03 ;form drive code
|
||||
F109 F61C OR #1C ;set TND, MOTOR, SELECT BIT
|
||||
F10B 320110 LD (#1001),A ;keep drive code
|
||||
F10E E60F AND #0F ;mask out TND
|
||||
F110 47 LD B,A
|
||||
F111 0EF8 LD C,#F8
|
||||
F113 ED60 IN H,(C) ;select drive
|
||||
F115 3E32 LD A,#32
|
||||
;
|
||||
;PRM1
|
||||
;
|
||||
F117 CDAEF1 PRM1: CALL LNGDEL ;wait for head
|
||||
F11A 3D DEC A :to load
|
||||
F11B 20FA JR NZ,PRM1
|
||||
F11D 010000 LD BC,#0000
|
||||
;
|
||||
;PRM2
|
||||
;
|
||||
F120 DBF9 PRM2: IN A,(#F9) ;get DRDY, CRDY, RQM
|
||||
F122 E607 AND #07 ;mask out RUBBISH
|
||||
F124 FE06 CP #06 ;DRDY & CRDY ?
|
||||
F126 2006 JR NZ,PRM3 ;NZ=no, keep trying
|
||||
F128 CDB2F0 CALL SKZERO
|
||||
F12B E1 POP HL
|
||||
F12C C1 POP BC
|
||||
F12D C9 RET ;correct exit
|
||||
;
|
||||
;PRM3
|
||||
;
|
||||
F12E 0B PRM3: DEC BC
|
||||
F12F 78 LD A,B
|
||||
F130 B1 OR C
|
||||
F131 20ED JR NZ,PRM2
|
||||
F133 3E32 LD A,#32
|
||||
F135 320810 LD (#1008),A ;error 40 (not found)
|
||||
F138 C30B10 JP #100B ;abort; error can't boot
|
||||
;
|
||||
;READER
|
||||
;
|
||||
F13B 3E0A READER: LD A,#0A ;no. of tries
|
||||
F13D 320710 LD (#1007),A
|
||||
;
|
||||
;RDR1
|
||||
;
|
||||
F140 CDFFF0 RDR1: CALL PRMDRV
|
||||
F143 3A0110 LD A,(#1001) ;keep drive in use
|
||||
F146 47 LD B,A
|
||||
F147 0EF8 LD C,#F8
|
||||
F149 D9 EXX ;save all regs
|
||||
F14A 0EFB LD C,#FB ;port fb??
|
||||
F14C DD5E03 LD E,(IX+#03) ;no meaning
|
||||
F14F DD5604 LD D,(IX+#04) ;get half of numbers to read (7)
|
||||
F152 CB13 RL E ;B7 to carry
|
||||
F154 CB12 RL D ;double number of sectors (14), add carry
|
||||
F156 1E03 LD E,#03 ;no meaning
|
||||
F158 DD6E05 LD L,(IX+#05) ;get loading address lo
|
||||
F15B DD6606 LD H,(IX+#06) ;hi into HL
|
||||
F15E CDBDF0 CALL DREADY
|
||||
F161 AF XOR A ;no meaning
|
||||
F162 DD7E01 LD A,(IX+#01) ;get track to read
|
||||
F165 1F RRA ;divide by 2, remainder to carry = head no.
|
||||
F166 D3F9 OUT (#F9),A ;send track to FDC
|
||||
F168 DD7E02 LD A,(IX+#02) ;sector number
|
||||
F16B 3002 JR NC,RDR2
|
||||
F16D F680 OR #80 ;odds/evens for side code
|
||||
;
|
||||
;RDR2
|
||||
;
|
||||
F16F D3F8 RDR2: OUT (#F8),A ;send sect+side
|
||||
F171 CDA6F1 CALL SHTDEL ;short delay
|
||||
F174 3E70 LD A,#70 ;seek & read code
|
||||
F176 320010 LD (#1000),A ;keep it
|
||||
F179 F3 DI
|
||||
F17A D3FA OUT (#FA),A ;send seek & read code to FDC
|
||||
;
|
||||
;RDR3
|
||||
;
|
||||
F17C 0680 RDR3: LD B,#80 ;128 bytes/sector
|
||||
;
|
||||
;RDR4
|
||||
;
|
||||
F17E DBF9 RDR4: IN A,(#F9) ;get DRDY, CRDY, RQM
|
||||
F180 A3 AND E ;mask with 03
|
||||
F181 28FB JR Z,RDR4 ;wait for either CRDY/RQM
|
||||
F183 0F RRCA ;RQM into carry
|
||||
F184 300C JR NC,RDR5 ;NC=no RQM
|
||||
F186 EDA2 INI ;get data. port FB to (HL), B=B-1
|
||||
F188 C27EF1 JP NZ,RDR4 ;do whole sector
|
||||
F18B 15 DEC D ;dec sector counter
|
||||
F18C C27CF1 JP NZ,RDR3 ;NZ=more to do
|
||||
F18F D9 EXX ;restore all regs
|
||||
F190 ED78 IN A,(C) ;send TND high
|
||||
;
|
||||
;RDR5
|
||||
;
|
||||
F192 CDD9F0 RDR5: CALL STATUS
|
||||
F195 D0 RET NC ;NC=good read
|
||||
F196 3A0710 LD A,(#1007)
|
||||
F199 3D DEC A ;A try gone
|
||||
F19A 320710 LD (#1007),A ;counter 10times
|
||||
F19D CA0B10 JP Z,#100B ;can't read at all abort
|
||||
F1A0 CDB2F0 CALL SKZERO
|
||||
F1A3 C340F1 JP RDR1
|
||||
;
|
||||
;SHTDEL
|
||||
;
|
||||
F1A6 F5 SHTDEL: PUSH AF
|
||||
F1A7 3E0A LD A,#0A
|
||||
;
|
||||
;SDY1
|
||||
;
|
||||
F1A9 3D SDY1: DEC A
|
||||
F1AA 20FD JR NZ,SDY1
|
||||
F1AC F1 POP AF
|
||||
F1AD C9 RET
|
||||
;
|
||||
;LNGDEL
|
||||
;
|
||||
F1AE F5 LNGDEL: PUSH AF ;long delay
|
||||
F1AF 3E0A LD A,#0A
|
||||
;
|
||||
;LDY1
|
||||
;
|
||||
F1B1 CDA6F1 LDY1: CALL SHTDEL
|
||||
F1B4 3D DEC A
|
||||
F1B5 20FA JR NZ,LDY1
|
||||
F1B7 F1 POP AF
|
||||
F1B8 C9 RET
|
||||
|
||||
CRLF: EQU 00009H
|
||||
MESSAGE: EQU 00015H
|
||||
BUFF2: EQU 9F00H
|
||||
USER: EQU 00003H
|
||||
MAINLP: EQU 00082H
|
||||
MOTFLG: EQU 1002H
|
||||
END
|
||||
|
||||
;
|
||||
;no meaning !!
|
||||
;
|
||||
F1B9 13 INC DE
|
||||
F1BA 1B DEC DE
|
||||
F1BB 72 LD (HL),D
|
||||
F1BC DE42 SBC A,#42
|
||||
F1BE FB EI
|
||||
F1BF 2F CPL
|
||||
F1C0 58 LD E,B
|
||||
F1C1 43 LD B,E
|
||||
F1C2 7C LD A,H
|
||||
F1C3 52 LD D,D
|
||||
F1C4 3023 JR NC,#F1E9 ; (35)
|
||||
F1C6 71 LD (HL),C
|
||||
F1C7 42 LD B,D
|
||||
F1C8 1020 DJNZ #F1EA ; (32)
|
||||
F1CA 74 LD (HL),H
|
||||
F1CB 40 LD B,B
|
||||
F1CC 43 LD B,E
|
||||
F1CD 03 INC BC
|
||||
F1CE 51 LD D,C
|
||||
F1CF 00 NOP
|
||||
F1D0 3C INC A
|
||||
F1D1 42 LD B,D
|
||||
F1D2 D8 RET C
|
||||
F1D3 60 LD H,B
|
||||
F1D4 FB EI
|
||||
F1D5 09 ADD HL,BC
|
||||
F1D6 FC402C CALL M,#2C40
|
||||
F1D9 80 ADD A,B
|
||||
F1DA 79 LD A,C
|
||||
F1DB 2A4940 LD HL,(#4049)
|
||||
F1DE 4D LD C,L
|
||||
F1DF EE3E XOR #3E
|
||||
F1E1 B2 OR D
|
||||
F1E2 1EA2 LD E,#A2
|
||||
F1E4 58 LD E,B
|
||||
F1E5 02 LD (BC),A
|
||||
F1E6 58 LD E,B
|
||||
F1E7 12 LD (DE),A
|
||||
F1E8 02 LD (BC),A
|
||||
F1E9 43 LD B,E
|
||||
F1EA 02 LD (BC),A
|
||||
F1EB 220002 LD (#0200),HL
|
||||
F1EE 2D DEC L
|
||||
F1EF 4B LD C,E
|
||||
F1F0 5A LD E,D
|
||||
F1F1 0A LD A,(BC)
|
||||
F1F2 40 LD B,B
|
||||
F1F3 4A LD C,D
|
||||
F1F4 13 INC DE
|
||||
F1F5 42 LD B,D
|
||||
F1F6 45 LD B,L
|
||||
F1F7 0A LD A,(BC)
|
||||
F1F8 5B LD E,E
|
||||
F1F9 6E LD L,(HL)
|
||||
F1FA 6A LD L,D
|
||||
F1FB 4E LD C,(HL)
|
||||
F1FC 4E LD C,(HL)
|
||||
F1FD 4E LD C,(HL)
|
||||
F1FE 5D LD E,L
|
||||
F1FF 7E LD A,(HL)
|
||||
F200 3011 JR NC,#F213 ; (17)
|
||||
F202 DD300E JR NC,#F213 ; (14)
|
||||
F205 067E LD B,#7E
|
||||
F207 FE3A CP #3A
|
||||
F209 CAC221 JP Z,#21C2
|
||||
F20C 12 LD (DE),A
|
||||
F20D 23 INC HL
|
||||
F20E 13 INC DE
|
||||
F20F 0D DEC C
|
||||
F210 C20622 JP NZ,#2206
|
||||
F213 C3C221 JP #21C2
|
||||
|
||||
F216 3AB830 LD A,(#30B8)
|
||||
F219 FEB1 CP #B1
|
||||
F21B CA4522 JP Z,#2245
|
||||
F21E 2A5030 LD HL,(#3050)
|
||||
F221 CD1E20 CALL #201E
|
||||
F224 7E LD A,(HL)
|
||||
F225 FE27 CP #27
|
||||
F227 CA5722 JP Z,#2257
|
||||
F22A 3E84 LD A,#84
|
||||
F22C 327630 LD (#3076),A
|
||||
F22F 3E02 LD A,#02
|
||||
F231 327730 LD (#3077),A
|
||||
F234 CDCA13 CALL #13CA
|
||||
F237 D24A22 JP NC,#224A
|
||||
F23A 2E00 LD L,#00
|
||||
F23C 3EB2 LD A,#B2
|
||||
F23E 32C830 LD (#30C8),A
|
||||
F241 7D LD A,L
|
||||
F242 326F30 LD (#306F),A
|
||||
F245 3E01 LD A,#01
|
||||
F247 C3C321 JP #21C3
|
||||
|
||||
F24A 3ABE30 LD A,(#30BE)
|
||||
F24D FEC5 CP #C5
|
||||
F24F C23C22 JP NZ,#223C
|
||||
F252 3EB0 LD A,#B0
|
||||
F254 C33E22 JP #223E
|
||||
|
||||
F257 23 INC HL
|
||||
F258 7E LD A,(HL)
|
||||
F259 E67F AND #7F
|
||||
F25B 6F LD L,A
|
||||
F25C C33C22 JP #223C
|
||||
|
||||
F25F 3AB830 LD A,(#30B8)
|
||||
F262 FEB1 CP #B1
|
||||
F264 CA9022 JP Z,#2290
|
||||
F267 2A5030 LD HL,(#3050)
|
||||
F26A CD1E20 CALL #201E
|
||||
F26D 3E80 LD A,#80
|
||||
F26F 327630 LD (#3076),A
|
||||
F272 3E01 LD A,#01
|
||||
F274 327730 LD (#3077),A
|
||||
F277 CDCA13 CALL #13CA
|
||||
F27A D29522 JP NC,#2295
|
||||
F27D 210000 LD HL,#0000
|
||||
F280 3E82 LD A,#82
|
||||
F282 32C830 LD (#30C8),A
|
||||
F285 226330 LD (#3063),HL
|
||||
F288 116F30 LD DE,#306F
|
||||
F28B 7C LD A,H
|
||||
F28C 12 LD (DE),A
|
||||
F28D 13 INC DE
|
||||
F28E 7D LD A,L
|
||||
F28F 12 LD (DE),A
|
||||
F290 3E02 LD A,#02
|
||||
F292 C3C321 JP #21C3
|
||||
|
||||
F295 3ABE30 LD A,(#30BE)
|
||||
F298 FEC5 CP #C5
|
||||
F29A C2A222 JP NZ,#22A2
|
||||
F29D 3EB1 LD A,#B1
|
||||
F29F C38222 JP #2282
|
||||
|
||||
F2A2 CDEA1A CALL #1AEA
|
||||
F2A5 C38222 JP #2282
|
||||
|
||||
F2A8 2A5030 LD HL,(#3050)
|
||||
F2AB CD1E20 CALL #201E
|
||||
F2AE 116F30 LD DE,#306F
|
||||
F2B1 0600 LD B,#00
|
||||
F2B3 0E04 LD C,#04
|
||||
F2B5 7E LD A,(HL)
|
||||
F2B6 23 INC HL
|
||||
F2B7 FE27 CP #27
|
||||
F2B9 C2F822 JP NZ,#22F8
|
||||
F2BC 7E LD A,(HL)
|
||||
F2BD FE27 CP #27
|
||||
F2BF C2DE22 JP NZ,#22DE
|
||||
F2C2 3AB830 LD A,(#30B8)
|
||||
F2C5 FEB1 CP #B1
|
||||
F2C7 CAD522 JP Z,#22D5
|
||||
F2CA AF XOR A
|
||||
F2CB 21C830 LD HL,#30C8
|
||||
F2CE B8 CP B
|
||||
F2CF CAD922 JP Z,#22D9
|
||||
F2D2 3EB3 LD A,#B3
|
||||
F2D4 77 LD (HL),A
|
||||
F2D5 78 LD A,B
|
||||
F2D6 C3C321 JP #21C3
|
||||
|
||||
F2D9 3EB4 LD A,#B4
|
||||
F2DB C3D422 JP #22D4
|
||||
|
||||
F2DE FE8D CP #8D
|
||||
F2E0 CAF822 JP Z,#22F8
|
||||
F2E3 FE0A CP #0A
|
||||
F2E5 CAF822 JP Z,#22F8
|
||||
F2E8 E67F AND #7F
|
||||
F2EA 12 LD (DE),A
|
||||
F2EB 23 INC HL
|
||||
F2EC 13 INC DE
|
||||
F2ED 04 INC B
|
||||
F2EE 0D DEC C
|
||||
F2EF C2BC22 JP NZ,#22BC
|
||||
F2F2 117A30 LD DE,#307A
|
||||
F2F5 C3BC22 JP #22BC
|
||||
|
||||
F2F8 3E53 LD A,#53
|
||||
F2FA CD111C CALL #1C11
|
||||
F2FD C3C222 JP #22C2
|
||||
|
||||
F300 CDE511 CALL #11E5
|
||||
F303 CD0C20 CALL #200C
|
||||
F306 FE3A CP #3A
|
||||
F308 C26423 JP NZ,#2364
|
||||
F30B 2A5030 LD HL,(#3050)
|
||||
F30E CD1E20 CALL #201E
|
||||
F311 3E80 LD A,#80
|
||||
F313 327630 LD (#3076),A
|
||||
F316 3E02 LD A,#02
|
||||
F318 327730 LD (#3077),A
|
||||
F31B CDCA13 CALL #13CA
|
||||
F31E DA2E23 JP C,#232E
|
||||
F321 3ACC30 LD A,(#30CC)
|
||||
F324 FE01 CP #01
|
||||
F326 C23123 JP NZ,#2331
|
||||
F329 3ECC LD A,#CC
|
||||
F32B CD111C CALL #1C11
|
||||
F32E 210000 LD HL,#0000
|
||||
F331 3AB830 LD A,(#30B8)
|
||||
F334 FEB1 CP #B1
|
||||
F336 CA6E23 JP Z,#236E
|
||||
F339 FEB2 CP #B2
|
||||
F33B CAC221 JP Z,#21C2
|
||||
F33E 226330 LD (#3063),HL
|
||||
F341 3EA2 LD A,#A2
|
||||
F343 32C830 LD (#30C8),A
|
||||
F346 CDB51D CALL #1DB5
|
||||
F349 06DD LD B,#DD
|
||||
F34B 30CD JR NC,#F31A ; (-51)
|
||||
F34D E5 PUSH HL
|
||||
F34E 1111DD LD DE,#DD11
|
||||
F351 300E JR NC,#F361 ; (14)
|
||||
F353 067E LD B,#7E
|
||||
F355 FE3A CP #3A
|
||||
F357 CAC221 JP Z,#21C2
|
||||
F35A 12 LD (DE),A
|
||||
F35B 23 INC HL
|
||||
F35C 13 INC DE
|
||||
F35D 0D DEC C
|
||||
F35E C25423 JP NZ,#2354
|
||||
F361 C3C221 JP #21C2
|
||||
|
||||
F364 3E4E LD A,#4E
|
||||
F366 CD111C CALL #1C11
|
||||
F369 3EB4 LD A,#B4
|
||||
F36B C3BF21 JP #21BF
|
||||
|
||||
F36E EB EX DE,HL
|
||||
F36F 2A4D31 LD HL,(#314D)
|
||||
F372 2B DEC HL
|
||||
F373 2B DEC HL
|
||||
F374 2B DEC HL
|
||||
F375 72 LD (HL),D
|
||||
F376 23 INC HL
|
||||
F377 73 LD (HL),E
|
||||
F378 23 INC HL
|
||||
F379 3680 LD (HL),#80
|
||||
F37B C3C221 JP #21C2
|
||||
|
||||
F37E CC44A0 CALL Z,#A044
|
||||
F381 41 LD B,C
|
||||
F382 AC XOR H
|
||||
F383 2842 JR Z,#F3C7 ; (66)
|
||||
F385 C3A9F1 JP #F1A9
|
||||
|
||||
F388 0A LD A,(BC)
|
||||
F389 CC44A0 CALL Z,#A044
|
||||
F38C 41 LD B,C
|
||||
F38D AC XOR H
|
||||
F38E 2844 JR Z,#F3D4 ; (68)
|
||||
F390 C5 PUSH BC
|
||||
F391 A9 XOR C
|
||||
F392 F1 POP AF
|
||||
F393 1A LD A,(DE)
|
||||
F394 CC44A0 CALL Z,#A044
|
||||
F397 2842 JR Z,#F3DB ; (66)
|
||||
F399 C3A9AC JP #ACA9
|
||||
|
||||
F39C 41 LD B,C
|
||||
F39D F1 POP AF
|
||||
F39E 02 LD (BC),A
|
||||
F39F CC44A0 CALL Z,#A044
|
||||
F3A2 2844 JR Z,#F3E8 ; (68)
|
||||
F3A4 C5 PUSH BC
|
||||
F3A5 A9 XOR C
|
||||
F3A6 AC XOR H
|
||||
F3A7 41 LD B,C
|
||||
F3A8 F1 POP AF
|
||||
F3A9 12 LD (DE),A
|
||||
F3AA CC44A0 CALL Z,#A044
|
||||
F3AD 41 LD B,C
|
||||
F3AE AC XOR H
|
||||
F3AF C9 RET
|
||||
|
||||
F3B0 F2ED57 JP P,#57ED
|
||||
F3B3 CC44A0 CALL Z,#A044
|
||||
F3B6 41 LD B,C
|
||||
F3B7 AC XOR H
|
||||
F3B8 D2F2ED JP NC,#EDF2
|
||||
F3BB 5F LD E,A
|
||||
F3BC CC44A0 CALL Z,#A044
|
||||
F3BF C9 RET
|
||||
|
||||
F3C0 AC XOR H
|
||||
F3C1 41 LD B,C
|
||||
F3C2 F2ED47 JP P,#47ED
|
||||
F3C5 CC44A0 CALL Z,#A044
|
||||
F3C8 D2AC41 JP NC,#41AC
|
||||
F3CB F2ED4F JP P,#4FED
|
||||
F3CE CC44A0 CALL Z,#A044
|
||||
F3D1 53 LD D,E
|
||||
F3D2 50 LD D,B
|
||||
F3D3 AC XOR H
|
||||
F3D4 48 LD C,B
|
||||
F3D5 CCF1F9 CALL Z,#F9F1
|
||||
F3D8 CC44A0 CALL Z,#A044
|
||||
F3DB 53 LD D,E
|
||||
F3DC 50 LD D,B
|
||||
F3DD AC XOR H
|
||||
F3DE C9 RET
|
||||
|
||||
F3DF D8 RET C
|
||||
F3E0 F2DDF9 JP P,#F9DD
|
||||
F3E3 CC44A0 CALL Z,#A044
|
||||
F3E6 53 LD D,E
|
||||
F3E7 50 LD D,B
|
||||
F3E8 AC XOR H
|
||||
F3E9 C9 RET
|
||||
|
||||
F3EA 59 LD E,C
|
||||
F3EB F2FDF9 JP P,#F9FD
|
||||
F3EE 50 LD D,B
|
||||
F3EF 55 LD D,L
|
||||
F3F0 53 LD D,E
|
||||
F3F1 48 LD C,B
|
||||
F3F2 A0 AND B
|
||||
F3F3 42 LD B,D
|
||||
F3F4 C3F1C5 JP #C5F1
|
||||
|
||||
F3F7 50 LD D,B
|
||||
F3F8 55 LD D,L
|
||||
F3F9 53 LD D,E
|
||||
F3FA 48 LD C,B
|
||||
F3FB A0 AND B
|
||||
F3FC 44 LD B,H
|
||||
F3FD C5 PUSH BC
|
||||
F3FE F1 POP AF
|
||||
F3FF D5 PUSH DE
|
||||
4853
software/asm/nascombasic.asm
Normal file
4853
software/asm/nascombasic.asm
Normal file
File diff suppressed because it is too large
Load Diff
155
software/asm/ramcheck.asm
Normal file
155
software/asm/ramcheck.asm
Normal 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
|
||||
7525
software/asm/sa-5510_tzfs.asm
Normal file
7525
software/asm/sa-5510_tzfs.asm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -42,10 +42,14 @@ START: LD SP,STACK
|
||||
CALL ?CLER ; Clear 256 bytes from NAME 10F1h to 11F0h
|
||||
LD A,016H
|
||||
CALL PRNT
|
||||
IF MODE80C = 0
|
||||
LD A,007H ; Black background, white characters. Bit 7 is clear as a write to bit 7 @ DFFFH selects 40Char mode.
|
||||
IF KUMA = 1
|
||||
LD A,0CFH
|
||||
ELSE
|
||||
LD A,017H ; Blue background, white characters in colour mode. Bit 7 is set as a write to bit 7 @ DFFFH selects 80Char mode.
|
||||
IF MODE80C = 0
|
||||
LD A,007H ; Black background, white characters. Bit 7 is clear as a write to bit 7 @ DFFFH selects 40Char mode.
|
||||
ELSE
|
||||
LD A,017H ; Blue background, white characters in colour mode. Bit 7 is set as a write to bit 7 @ DFFFH selects 80Char mode.
|
||||
ENDIF
|
||||
ENDIF
|
||||
LD HL,ARAM
|
||||
JR STRT1
|
||||
@@ -130,13 +134,19 @@ LOAD: CALL ?RDI
|
||||
JR C,ST1
|
||||
JP (HL)
|
||||
|
||||
|
||||
; LOADING
|
||||
MSG?2: DB 04CH, 0B7H, 0A1H, 09CH
|
||||
DB 0A6H, 0B0H, 097H, 020H
|
||||
DB 00DH
|
||||
|
||||
; SIGN ON BANNER
|
||||
MSG?3: DB "** MONITOR SA-1510 **", 0DH
|
||||
; SIGN ON BANNER - Different for Kuma 80 BIOS
|
||||
MSG?3: IF KUMA = 0
|
||||
DB "** MONITOR SA-1510 **", 0DH
|
||||
ELSE
|
||||
DB "*K",0A5H,0B3H,0A1H," MZ-80A M",0B7H,0B0H,0A6H
|
||||
DB 096H,0B7H,09DH,"*",00DH,"*",00DH
|
||||
ENDIF
|
||||
|
||||
; For 80 Character mode we need some space, so shorten the Check Sum Error message.
|
||||
;
|
||||
@@ -148,7 +158,7 @@ MSGE1: IF MODE80C = 0
|
||||
DB "CK SUM?", 0DH
|
||||
ENDIF
|
||||
|
||||
; Hook = 7 bytes.
|
||||
; Hook = 7 bytes using space taken from Check Sum message.
|
||||
HOOK: IF MODE80C = 1
|
||||
LD A,0FFH
|
||||
LD (SPAGE),A
|
||||
@@ -156,27 +166,56 @@ HOOK: IF MODE80C = 1
|
||||
ENDIF
|
||||
|
||||
; CR PAGE MODE1
|
||||
.CR: CALL .MANG
|
||||
RRCA
|
||||
JP NC,CURS2
|
||||
LD L,000H
|
||||
INC H
|
||||
CP ROW - 1 ; End of line?
|
||||
JR Z,.CP1
|
||||
INC H
|
||||
JP CURS1
|
||||
.CR: IF KUMA = 1
|
||||
LD HL,(DSPXY)
|
||||
JP CURS2
|
||||
ELSE
|
||||
CALL .MANG
|
||||
RRCA
|
||||
JP NC,CURS2
|
||||
LD L,000H
|
||||
INC H
|
||||
CP ROW - 1 ; End of line?
|
||||
JR Z,.CP1
|
||||
INC H
|
||||
JP CURS1
|
||||
ENDIF
|
||||
.CR1: IF KUMA = 1
|
||||
NEG
|
||||
LD (SPAGE),A
|
||||
ADD A,004H
|
||||
LD (KEYPF),A
|
||||
RET
|
||||
DB 00EH
|
||||
ENDIF
|
||||
|
||||
.CP1: LD (DSPXY),HL
|
||||
|
||||
; SCROLLER
|
||||
.SCROL: LD BC,SCRNSZ - COLW ; Scroll COLW -1 lines
|
||||
.SCROL: IF KUMA = 1
|
||||
LD BC, 0780H
|
||||
ELSE
|
||||
LD BC,SCRNSZ - COLW ; Scroll COLW -1 lines
|
||||
ENDIF
|
||||
LD DE,SCRN ; Start of the screen.
|
||||
LD HL,SCRN + COLW ; Start of screen + 1 line.
|
||||
IF KUMA = 1
|
||||
LD HL,0D050H
|
||||
ELSE
|
||||
LD HL,SCRN + COLW ; Start of screen + 1 line.
|
||||
ENDIF
|
||||
LDIR
|
||||
EX DE,HL
|
||||
LD B,COLW ; Clear last line at bottom of screen.
|
||||
IF KUMA = 1
|
||||
LD B, 050H
|
||||
ELSE
|
||||
LD B,COLW ; Clear last line at bottom of screen.
|
||||
ENDIF
|
||||
CALL ?CLER
|
||||
LD BC,0001AH
|
||||
IF KUMA = 1
|
||||
JP ?RSTR
|
||||
ELSE
|
||||
LD BC,0001AH
|
||||
ENDIF
|
||||
LD DE,MANG
|
||||
LD HL,MANG + 1
|
||||
LDIR
|
||||
@@ -587,22 +626,46 @@ TIMIN: PUSH AF
|
||||
EI
|
||||
RET
|
||||
|
||||
.DSP03: EX DE,HL
|
||||
LD (HL),001H
|
||||
INC HL
|
||||
LD (HL),000H
|
||||
JP CURSR
|
||||
.MANG2: LD A,(DSPXY + 1)
|
||||
ADD A,L
|
||||
LD L,A
|
||||
LD A,(HL)
|
||||
INC HL
|
||||
RL (HL)
|
||||
OR (HL)
|
||||
RR (HL)
|
||||
RRCA
|
||||
EX DE,HL
|
||||
LD HL,(DSPXY)
|
||||
.DSP03: IF KUMA = 1
|
||||
LD A,(SPAGE)
|
||||
OR A
|
||||
LD A,027H
|
||||
RET Z
|
||||
ADD A,A
|
||||
INC A
|
||||
RET
|
||||
|
||||
L03A7: PUSH BC
|
||||
CALL .DSP03
|
||||
LD B,A
|
||||
LD A,L
|
||||
CP B
|
||||
POP BC
|
||||
RET
|
||||
|
||||
L03B0: CALL .DSP03
|
||||
LD L,A
|
||||
XOR A
|
||||
DEC H
|
||||
RET
|
||||
ELSE
|
||||
EX DE,HL
|
||||
LD (HL),001H
|
||||
INC HL
|
||||
LD (HL),000H
|
||||
JP CURSR
|
||||
.MANG2: LD A,(DSPXY + 1)
|
||||
ADD A,L
|
||||
LD L,A
|
||||
LD A,(HL)
|
||||
INC HL
|
||||
RL (HL)
|
||||
OR (HL)
|
||||
RR (HL)
|
||||
RRCA
|
||||
EX DE,HL
|
||||
LD HL,(DSPXY)
|
||||
ENDIF
|
||||
RET
|
||||
|
||||
LD C,H
|
||||
@@ -1141,7 +1204,11 @@ L0743: DEC H
|
||||
?MODE: LD HL,KEYPF
|
||||
LD (HL),08AH
|
||||
LD (HL),007H
|
||||
LD (HL),005H
|
||||
IF KUMA = 1
|
||||
LD (HL),004H
|
||||
ELSE
|
||||
LD (HL),005H
|
||||
ENDIF
|
||||
LD (HL),001H
|
||||
RET
|
||||
|
||||
@@ -1270,7 +1337,11 @@ CHGPA: XOR A
|
||||
JR CHGPK1
|
||||
ENDIF
|
||||
CHGPK: LD A,0FFH
|
||||
CHGPK1: LD (SPAGE),A
|
||||
CHGPK1: IF KUMA = 1
|
||||
CALL .CR1
|
||||
ELSE
|
||||
LD (SPAGE),A
|
||||
ENDIF
|
||||
LD A,0C6H
|
||||
CALL ?DPCT
|
||||
CHGP1: JP GETL0
|
||||
@@ -1581,7 +1652,12 @@ REV2: JP ?RSTR
|
||||
.MANG: LD HL,MANG
|
||||
LD A,(SPAGE)
|
||||
OR A
|
||||
JP NZ,.MANG2
|
||||
IF KUMA = 1
|
||||
JR NZ,.MANG1 ; (+018H)
|
||||
NOP
|
||||
ELSE
|
||||
JP NZ,.MANG2
|
||||
ENDIF
|
||||
LD A,(MGPNT)
|
||||
.MANG3: SUB 008H
|
||||
INC HL
|
||||
@@ -2407,14 +2483,24 @@ DLY12A: CALL DLY3
|
||||
CALL ?PONT
|
||||
LD (HL),B
|
||||
LD HL,(DSPXY)
|
||||
LD A,L
|
||||
DSP01: CP COLW - 1 ; End of line.
|
||||
IF KUMA = 1
|
||||
CALL L03A7
|
||||
ELSE
|
||||
LD A,L
|
||||
ENDIF
|
||||
DSP01: IF KUMA = 0
|
||||
CP COLW - 1 ; End of line.
|
||||
ENDIF
|
||||
JR NZ,DSP04
|
||||
CALL .MANG
|
||||
JR C,DSP04
|
||||
LD A,(SPAGE)
|
||||
OR A
|
||||
JP NZ,.DSP03
|
||||
IF KUMA
|
||||
JP NZ,CURSR
|
||||
ELSE
|
||||
JP NZ,.DSP03
|
||||
ENDIF
|
||||
EX DE,HL
|
||||
LD A,B
|
||||
CP 007H
|
||||
@@ -2535,8 +2621,12 @@ CURSU1: CALL MGP.D
|
||||
JR CURS3
|
||||
|
||||
CURSR: LD HL,(DSPXY)
|
||||
LD A,L
|
||||
CP COLW - 1 ; End of line
|
||||
IF KUMA = 1
|
||||
CALL L03A7
|
||||
ELSE
|
||||
LD A,L
|
||||
CP COLW - 1 ; End of line
|
||||
ENDIF
|
||||
JR NC,CURS2
|
||||
INC L
|
||||
JR CURS3
|
||||
@@ -2555,8 +2645,12 @@ CURSL: LD HL,(DSPXY)
|
||||
JR Z,CURS5A
|
||||
DEC L
|
||||
JR CURS3
|
||||
CURS5A: LD L,COLW - 1 ; End of line
|
||||
DEC H
|
||||
CURS5A: IF KUMA = 1
|
||||
CALL L03B0
|
||||
ELSE
|
||||
LD L,COLW - 1 ; End of line
|
||||
DEC H
|
||||
ENDIF
|
||||
JP P,CURSU1
|
||||
LD H,000H
|
||||
LD (DSPXY),HL
|
||||
@@ -2643,13 +2737,24 @@ INST: CALL .MANG
|
||||
RRCA
|
||||
LD L,COLW - 1 ; End of line
|
||||
LD A,L
|
||||
JR NC,INST1A
|
||||
INC H
|
||||
INST1A: CALL ?PNT1
|
||||
PUSH HL
|
||||
LD HL,(DSPXY)
|
||||
JR NC,INST2
|
||||
LD A,(COLW*2)-1 ; 04FH
|
||||
IF KUMA = 1
|
||||
JR NC,INST1B
|
||||
LD A,028H
|
||||
ADD A,L
|
||||
LD L,A
|
||||
INST1B: CALL ?PNT1
|
||||
PUSH HL
|
||||
LD HL,(DSPXY)
|
||||
NOP
|
||||
ELSE
|
||||
JR NC,INST1A
|
||||
INC H
|
||||
INST1A: CALL ?PNT1
|
||||
PUSH HL
|
||||
LD HL,(DSPXY)
|
||||
JR NC,INST2
|
||||
LD A,(COLW*2)-1 ; 04FH
|
||||
ENDIF
|
||||
INST2: SUB L
|
||||
LD B,A
|
||||
POP DE
|
||||
@@ -2720,16 +2825,30 @@ ROLU1: CALL MGP.I
|
||||
PUSH HL
|
||||
POP BC
|
||||
LD DE,COLW
|
||||
LD HL,SCRN - COLW
|
||||
LD A,(SPAGE)
|
||||
OR A
|
||||
JR NZ,?PNT2
|
||||
LD HL,(PAGETP)
|
||||
SBC HL,DE
|
||||
?PNT2: ADD HL,DE
|
||||
DEC B
|
||||
JP P,?PNT2
|
||||
LD B,000H
|
||||
IF KUMA = 1
|
||||
LD HL,(PAGETP)
|
||||
INC B
|
||||
LD A,(SPAGE)
|
||||
OR A
|
||||
JR Z,L0FCE ; (+008H)
|
||||
LD HL,0D000H
|
||||
LD E,050H
|
||||
JR L0FCE ; (+001H)
|
||||
L0FCD: ADD HL,DE
|
||||
L0FCE: DJNZ L0FCD ; (-003H)
|
||||
NOP
|
||||
ELSE
|
||||
LD HL,SCRN - COLW
|
||||
LD A,(SPAGE)
|
||||
OR A
|
||||
JR NZ,?PNT2
|
||||
LD HL,(PAGETP)
|
||||
SBC HL,DE
|
||||
?PNT2: ADD HL,DE
|
||||
DEC B
|
||||
JP P,?PNT2
|
||||
LD B,000H
|
||||
ENDIF
|
||||
ADD HL,BC
|
||||
RES 3,H
|
||||
POP DE
|
||||
|
||||
1658
software/asm/sfd700.asm
Normal file
1658
software/asm/sfd700.asm
Normal file
File diff suppressed because it is too large
Load Diff
2657
software/asm/sharpmz-test.asm
Normal file
2657
software/asm/sharpmz-test.asm
Normal file
File diff suppressed because it is too large
Load Diff
2254
software/asm/testtz.asm
Normal file
2254
software/asm/testtz.asm
Normal file
File diff suppressed because it is too large
Load Diff
2522
software/asm/tzfs.asm
Normal file
2522
software/asm/tzfs.asm
Normal file
File diff suppressed because it is too large
Load Diff
553
software/asm/tzfs_bank2.asm
Normal file
553
software/asm/tzfs_bank2.asm
Normal file
@@ -0,0 +1,553 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;-
|
||||
;- Name: tzfs_bank2.asm
|
||||
;- Created: July 2019
|
||||
;- Author(s): Philip Smart
|
||||
;- Description: Sharp MZ series tzfs (tranZPUter Filing System).
|
||||
;- Bank 2 - F000:FFFF - Help and messages
|
||||
;-
|
||||
;- This assembly language program is a branch from the original RFS written for the
|
||||
;- MZ80A_RFS upgrade board. It is adapted to work within the similar yet different
|
||||
;- environment of the tranZPUter SW which has a large RAM capacity (512K) and an
|
||||
;- I/O processor in the K64F/ZPU.
|
||||
;-
|
||||
;- Credits:
|
||||
;- Copyright: (c) 2018-2020 Philip Smart <philip.smart@net2net.org>
|
||||
;-
|
||||
;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW.
|
||||
;- Dec 2020 - Updates to accommodate v1.3 of the tranZPUter SW-700 board where soft
|
||||
;- CPU's now become possible.
|
||||
;-
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;- 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/>.
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
|
||||
;============================================================
|
||||
;
|
||||
; TZFS BANK 2 - Help and message functions.
|
||||
;
|
||||
;============================================================
|
||||
ORG BANKRAMADDR
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; 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
|
||||
CALL PRINTASCII
|
||||
PRINTMSG2: INC DE
|
||||
JR PRINTMSG
|
||||
PRINTMSG3: LD HL,6+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,6+2
|
||||
JR PRINTMSG4
|
||||
PRINTMSG7: LD HL,6+4
|
||||
JR PRINTMSG4
|
||||
PRINTMSG8: LD HL,6+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
|
||||
|
||||
; 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 23 ; Check to see if a page of output has been displayed, if it has, pause.
|
||||
JR Z,PRTSTR5
|
||||
INC A
|
||||
PRTSTR4: LD (TMPLINECNT),A
|
||||
POP AF
|
||||
JR PRTSTR2
|
||||
PRTSTR5: CALL GETKY
|
||||
CP ' '
|
||||
JR NZ,PRTSTR5
|
||||
XOR A
|
||||
JR PRTSTR4
|
||||
PRTSTRE: POP DE
|
||||
POP BC
|
||||
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
|
||||
|
||||
; 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
|
||||
ATBLE: EQU $
|
||||
|
||||
; 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
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF PRINT ROUTINE METHODS
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
; The FDC controller uses it's busy/wait signal as a ROM address line input, this
|
||||
; causes a jump in the code dependent on the signal status. It gets around the 2MHz Z80 not being quick
|
||||
; enough to process the signal by polling.
|
||||
ALIGN_NOPS FDCJMP1
|
||||
ORG FDCJMP1
|
||||
FDCJMPL2: JP (IX)
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
;
|
||||
; Message table
|
||||
;
|
||||
;-------------------------------------------------------------------------------
|
||||
; 0 + <- 39
|
||||
; -----------------------------------------
|
||||
MSGSON: DB "+ TZFS v1.6 ", NULL ; Version 1.0-> first split from RFS v2.0
|
||||
MSGSONEND: DB " **", CR, NULL ; Signon banner termination.
|
||||
MSGSONT80: DB "(T80)", NULL ; T80 CPU detected.
|
||||
MSGNOTFND: DB "Not Found", CR, NULL
|
||||
MSGBADCMD: DB "???", CR, NULL
|
||||
MSGSDRERR: DB "SD Read error, Sec:",0FBH, NULL
|
||||
MSGSVFAIL: DB "Save failed.", CR, NULL
|
||||
MSGERAFAIL: DB "Erase failed.", CR, NULL
|
||||
MSGCDFAIL: DB "Directory invalid.", CR, NULL
|
||||
MSGERASEDIR:DB "Deleted dir entry:",0FBH, NULL
|
||||
MSGCMTDATA: DB "Load:",0FEH,",Exec:",0FFH, ",Size:", 0FBH, CR, NULL
|
||||
MSGNOTBIN: DB "Not binary", CR, NULL
|
||||
MSGLOAD: DB CR, "Loading ",'"',0FAH,'"', CR, NULL
|
||||
MSGSAVE: DB CR, "Filename: ", NULL
|
||||
MSGE1: DB CR, "Check sum error!", CR, NULL ; Check sum error.
|
||||
MSGCMTWRITE:DB CR, "Writing ", '"',0FAH,'"', CR, NULL
|
||||
MSGOK: DB CR, "OK!", CR, NULL
|
||||
MSGSAVEOK: DB "Tape image saved.", CR, NULL
|
||||
MSGBOOTDRV: DB CR, "Floppy boot drive ?", NULL
|
||||
MSGLOADERR: DB CR, "Disk loading error", CR, NULL
|
||||
MSGIPLLOAD: DB CR, "Disk loading ", NULL
|
||||
MSGDSKNOTMST:DB CR, "This is not a boot disk", CR, NULL
|
||||
MSGINITM: DB "Init memory", CR, NULL
|
||||
MSGREAD4HEX:DB "Bad hex number", CR, NULL
|
||||
MSGT2SDERR: DB "Copy from Tape to SD Failed", CR, NULL
|
||||
MSGSD2TERR: DB "Copy from SD to Tape Failed", CR, NULL
|
||||
MSGT2SDOK: DB "Success, Tape to SD done.", CR, NULL
|
||||
MSGSD2TOK: DB "Success, SD to Tape done.", CR, NULL
|
||||
MSGUNKNHW: DB "Unknown hardware, cannot change!", CR, NULL
|
||||
MSGFAILBIOS:DB "Failed to load alternate BIOS!", CR, NULL
|
||||
MSGFAILEXIT:DB "TZFS exit failed, I/O proc error!", CR, NULL
|
||||
MSGFREQERR: DB "Error, failed to change frequency!", CR, NULL
|
||||
MSGBADNUM: DB "Error, bad number supplied!", CR, NULL
|
||||
MSGNOFPGA: DB "Error, no FPGA video module!", CR, NULL
|
||||
MSGT80ERR: DB "Error, failed to switch to T80 CPU!", CR, NULL
|
||||
MSGZ80ERR: DB "Error, failed to switch to Z80 CPU!", CR, NULL
|
||||
MSGZPUERR: DB "Error, failed to switch to ZPU CPU!", CR, NULL
|
||||
MSGNOSOFTCPU:DB "No soft cpu hardware!", CR, NULL
|
||||
MSGNOT80CPU:DB "T80 not available!", CR, NULL
|
||||
MSGNOEMU: DB "No Sharp MZ Series Emu hardware!", CR, NULL
|
||||
;
|
||||
OKCHECK: DB ", CHECK: ", CR, NULL
|
||||
OKMSG: DB " OK.", CR, NULL
|
||||
DONEMSG: DB 11h
|
||||
DB "RAM TEST COMPLETE.", CR, NULL
|
||||
BITMSG: DB " BIT: ", CR, NULL
|
||||
BANKMSG: DB " BANK: ", CR, NULL
|
||||
MSG_TIMERTST:DB "8253 TIMER TEST", CR, NULL
|
||||
MSG_TIMERVAL:DB "READ VALUE 1: ", CR, NULL
|
||||
MSG_TIMERVAL2:DB "READ VALUE 2: ", CR, NULL
|
||||
MSG_TIMERVAL3:DB "READ DONE.", CR, NULL
|
||||
|
||||
|
||||
; The FDC controller uses it's busy/wait signal as a ROM address line input, this
|
||||
; causes a jump in the code dependent on the signal status. It gets around the 2MHz Z80 not being quick
|
||||
; enough to process the signal by polling.
|
||||
ALIGN_NOPS FDCJMP2
|
||||
ORG FDCJMP2
|
||||
FDCJMPH2: JP (IY)
|
||||
|
||||
; Continuation of messages after the Floppy Disk controller fixed location.
|
||||
MSGNOZPUCPU:DB "ZPU Evo not available!", CR, NULL
|
||||
MSGNOCMTDIR:DB "CMT has no directory.", CR, NULL
|
||||
MSGNOVERIFY:DB "No Verify for SD drive.", CR, NULL
|
||||
|
||||
SVCRESPERR: DB "I/O Response Error, time out!", CR, NULL
|
||||
SVCIOERR: DB "I/O Error, time out!", CR, NULL
|
||||
|
||||
;TESTMSG: DB "HL is:",0FBH, 00DH, 000H
|
||||
;TESTMSG2: DB "DE is:",0FBH, 00DH, 000H
|
||||
;TESTMSG3: DB "BC is:",0FBH, 00DH, 000H
|
||||
;TESTMSG4: DB "4 is:",0FBH, 00DH, 000H
|
||||
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF HELP SCREEN FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; Simple help screen to display commands.
|
||||
HELP: ;CALL NL
|
||||
LD DE, HELPSCR
|
||||
CALL PRTSTR
|
||||
RET
|
||||
|
||||
; Help text. Use of lower case, due to Sharp's non standard character set, is not easy, you have to manually code each byte
|
||||
; hence using upper case.
|
||||
HELPSCR: ; "--------- 40 column width -------------"
|
||||
DB "4 40 col mode.", 00DH
|
||||
DB "8 80 col mode.", 00DH
|
||||
;DB "40A select MZ-80A 40col Mode.", 00DH
|
||||
;DB "80A select MZ-80A 80col Mode.", 00DH
|
||||
;DB "80B select MZ-80B Mode.", 00DH
|
||||
;DB "700 select MZ-700 40col Mode.", 00DH
|
||||
;DB "7008 select MZ-700 80col Mode.", 00DH
|
||||
DB "B toggle keyboard bell.", 00DH
|
||||
DB "BASIC load BASIC SA-5510.", 00DH
|
||||
DB "C[b] clear memory $1200-$D000.", 00DH
|
||||
DB "CD[d] switch to SD directory [d].", 00DH
|
||||
DB "CPM load CPM.", 00DH
|
||||
DB "DXXXX[YYYY] dump mem XXXX to YYYY.", 00DH
|
||||
DB "DIR[wc] SD dir listing, wc=wildcard.", 00DH
|
||||
DB "ECfn erase file, fn=No or Filename", 00DH
|
||||
DB "EX exit TZFS, reset as original.", 00DH
|
||||
DB "Fx boot fd drive x.", 00DH
|
||||
DB "FREQn set CPU to nKHz, 0 default.", 00DH
|
||||
DB "H this help screen.", 00DH
|
||||
DB "JXXXX jump to location XXXX.", 00DH
|
||||
DB "LTfn[,M] load tape, fn=Filename", 00DH
|
||||
DB " M = HW Mode, K=80K,C=80C,1=1200", 00DH
|
||||
DB " A=80A,7=700,8=800,B=80B,2=2000", 00DH
|
||||
DB "LCfn[,M] load from SD, fn=No or FileN", 00DH
|
||||
DB " add NX for no exec, ie.LCNX.", 00DH
|
||||
DB "MXXXX edit memory starting at XXXX.", 00DH
|
||||
DB "MZmc activate hardware emulation.", 00DH
|
||||
DB " mc =80K,80C,1200,80A,700,800,80B,2000", 00DH
|
||||
DB "P test printer.", 00DH
|
||||
DB "R test dram memory.", 00DH
|
||||
DB "SDDd change to SD directory {d}.", 00DH
|
||||
DB "SD2Tfn[,M] copy SD to tape.", 00DH
|
||||
DB "STXXXXYYYYZZZZ[,M] save mem to tape.", 00DH
|
||||
DB "SCXXXXYYYYZZZZ save mem to card.", 00DH
|
||||
DB " XXXX=start, YYYY=end, ZZZZ=exec", 00DH
|
||||
DB "T test timer.", 00DH
|
||||
DB "T2SD[B][,M] copy tape to SD, B=Bulk", 00DH
|
||||
DB "T80 switch to soft T80 CPU.", 00DH
|
||||
DB "V verify tape save.", 00DH
|
||||
DB "VBORDERn set vga border colour.", 00DH
|
||||
DB "VMODEn set video mode.", 00DH
|
||||
DB "VGAn set VGA mode.", 00DH
|
||||
DB "Z80 switch to hard Z80 CPU.", 00DH
|
||||
DB "ZPU switch to ZPU Evo CPU / zOS.", 00DH
|
||||
; "--------- 40 column width -------------"
|
||||
DB 000H
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF HELP SCREEN FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
;
|
||||
; Ensure we fill the entire 4K by padding with FF's.
|
||||
;
|
||||
ALIGN_NOPS 10000H
|
||||
1169
software/asm/tzfs_bank3.asm
Normal file
1169
software/asm/tzfs_bank3.asm
Normal file
File diff suppressed because it is too large
Load Diff
344
software/asm/tzfs_bank4.asm
Normal file
344
software/asm/tzfs_bank4.asm
Normal file
@@ -0,0 +1,344 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;-
|
||||
;- Name: tzfs_bank4.asm
|
||||
;- Created: July 2019
|
||||
;- Author(s): Philip Smart
|
||||
;- Description: Sharp MZ series tzfs (tranZPUter Filing System).
|
||||
;- Bank 4 - F000:FFFF -
|
||||
;-
|
||||
;- This assembly language program is a branch from the original RFS written for the
|
||||
;- MZ80A_RFS upgrade board. It is adapted to work within the similar yet different
|
||||
;- environment of the tranZPUter SW which has a large RAM capacity (512K) and an
|
||||
;- I/O processor in the K64F/ZPU.
|
||||
;-
|
||||
;- Credits:
|
||||
;- Copyright: (c) 2018-2020 Philip Smart <philip.smart@net2net.org>
|
||||
;-
|
||||
;- History: May 2020 - Branch taken from RFS v2.0 and adapted for the tranZPUter SW.
|
||||
;- Dec 2020 - Updates to accommodate v1.3 of the tranZPUter SW-700 board where soft
|
||||
;- CPU's now become possible.
|
||||
;-
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
;- 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/>.
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
;============================================================
|
||||
;
|
||||
; TZFS BANK 4 - TZFS commands
|
||||
;
|
||||
;============================================================
|
||||
ORG BANKRAMADDR
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF ADDITIONAL TZFS COMMANDS
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; Method to set the video mode.
|
||||
; Param: 0 - Enable FPGA and set to MZ-80K mode.
|
||||
; 1 - Enable FPGA and set to MZ-80C mode.
|
||||
; 2 - Enable FPGA and set to MZ-1200 mode.
|
||||
; 3 - Enable FPGA and set to MZ-80A mode (base mode on MZ-80A hardware).
|
||||
; 4 - Enable FPGA and set to MZ-700 mode (base mode on MZ-700 hardware).
|
||||
; 5 - Enable FPGA and set to MZ-1500 mode.
|
||||
; 6 - Enable FPGA and set to MZ-800 mode.
|
||||
; 7 - Enable FPGA and set to MZ-80B mode.
|
||||
; 8 - Enable FPGA and set to MZ-2000 mode.
|
||||
; 9 - Enable FPGA and set to MZ-2200 mode.
|
||||
; 10 - Enable FPGA and set to MZ-2500 mode.
|
||||
; O - Turn off FPGA Video, turn on mainboard video.
|
||||
SETVMODE: IN A,(CPLDINFO) ; Get configuration of hardware.
|
||||
BIT 3,A
|
||||
JP Z,NOFPGAERR ; No hardware so cannot change mode.
|
||||
PUSH DE ; Preserve DE in case no number given.
|
||||
POP BC
|
||||
CALL ConvertStringToNumber ; Convert the input into 0 (disable) or frequency in KHz.
|
||||
JR NZ,SETVMODEOFF
|
||||
LD A,H
|
||||
CP 0
|
||||
JP NZ,BADNUMERR ; Check that the given mode is in range 0 - 7.
|
||||
LD A,L
|
||||
CP 10
|
||||
JP NC,BADNUMERR
|
||||
;
|
||||
SETVMODE0: IN A,(CPLDCFG)
|
||||
OR MODE_VIDEO_FPGA ; Set the tranZPUter CPLD hardware to enable the FPGA video mode.
|
||||
OUT (CPLDCFG),A
|
||||
;
|
||||
IN A,(VMCTRL) ; Get current setting.
|
||||
AND 0F0H ; Clear old mode setting.
|
||||
OR L ; Add in new setting.
|
||||
OUT (VMCTRL),A
|
||||
RLC L ; Shift mode to position for SCRNMODE storage.
|
||||
RLC L
|
||||
RLC L
|
||||
RLC L
|
||||
LD A,(SCRNMODE) ; Repeat for the screen mode variable, used when resetting or changing display settings.
|
||||
AND 007H ; Clear video mode setting.
|
||||
OR L ; Add in new setting.
|
||||
SET 2, A ; Set flag to indicate video mode override - ie, dont use base machine mode.
|
||||
SETVMODECLR:SET 1, A ; Ensure flag set so on restart the FPGA video mode is selected.
|
||||
LD (SCRNMODE),A
|
||||
LD A, 016H ; Clear the screen so we start from a known position.
|
||||
CALL PRNT
|
||||
LD A,071H ; Blue background and white characters.
|
||||
LD HL,ARAM
|
||||
CALL CLR8
|
||||
RET
|
||||
SETVMODEOFF:LD A,(DE)
|
||||
CP 'O'
|
||||
JR Z,SETVMODE1
|
||||
CP 'o'
|
||||
JP NZ,BADNUMERR
|
||||
SETVMODE1: LD A,(SCRNMODE) ; Disable flag to enable FPGA on restart.
|
||||
RES 1,A
|
||||
LD (SCRNMODE),A
|
||||
IN A,(CPLDCFG)
|
||||
AND ~MODE_VIDEO_FPGA ; Set the tranZPUter CPLD hardware to disable the FPGA video mode.
|
||||
OUT (CPLDCFG),A
|
||||
RET
|
||||
|
||||
; Method to set the VGA output mode of the external display.
|
||||
SETVGAMODE: IN A,(CPLDINFO) ; Get configuration of hardware.
|
||||
BIT 3,A
|
||||
JP Z,NOFPGAERR ; No hardware so cannot change mode.
|
||||
CALL ConvertStringToNumber ; Convert the input into 0-3, 0 = off, 1 = 640x480, 2=1024x768, 3=800x600.
|
||||
JP NZ,BADNUMERR
|
||||
LD A,H
|
||||
CP 0
|
||||
JP NZ,BADNUMERR ; Check that the given mode is in range 0 - 15.
|
||||
LD A,L
|
||||
CP 15
|
||||
JP NC,BADNUMERR
|
||||
;
|
||||
;RRC L
|
||||
;RRC L ; Value to top 2 bits ready to be applied to VGA mode register.
|
||||
;
|
||||
SETVGAMODE1:IN A,(CPLDCFG)
|
||||
OR MODE_VIDEO_FPGA ; Set the tranZPUter CPLD hardware to enable the FPGA video mode.
|
||||
OUT (CPLDCFG),A
|
||||
;
|
||||
LD A, L ; Add in new setting.
|
||||
OUT (VMVGAMODE),A
|
||||
LD (SCRNMODE2), A
|
||||
JP SETVMODECLR
|
||||
|
||||
; Method to set the VGA border colour on the external display.
|
||||
SETVBORDER: IN A,(CPLDINFO) ; Get configuration of hardware.
|
||||
BIT 3,A
|
||||
JP Z,NOFPGAERR ; No hardware so cannot change mode.
|
||||
CALL ConvertStringToNumber ; Convert the input into 0 - 7, bit 2 = Red, 1 = Green, 0 = Blue.
|
||||
JP NZ,BADNUMERR
|
||||
LD A,H
|
||||
CP 0
|
||||
JP NZ,BADNUMERR ; Check that the given mode is in range 0 - 7.
|
||||
LD A,L
|
||||
CP 7
|
||||
JP NC,BADNUMERR
|
||||
;
|
||||
IN A,(CPLDCFG)
|
||||
OR MODE_VIDEO_FPGA ; Set the tranZPUter CPLD hardware to enable the FPGA video mode.
|
||||
OUT (CPLDCFG),A
|
||||
;
|
||||
LD A,L
|
||||
OUT (VMVGATTR),A
|
||||
RET
|
||||
|
||||
; Method to enable/disable the alternate CPU frequency and change it's values.
|
||||
;
|
||||
SETFREQ: CALL ConvertStringToNumber ; Convert the input into 0 (disable) or frequency in KHz.
|
||||
JP NZ,BADNUMERR
|
||||
LD (TZSVC_CPU_FREQ),HL ; Set the required frequency in the service structure.
|
||||
LD A,H
|
||||
CP L
|
||||
JR NZ,SETFREQ1
|
||||
LD A, TZSVC_CMD_CPU_BASEFREQ ; Switch to the base frequency.
|
||||
JR SETFREQ2
|
||||
SETFREQ1: LD A, TZSVC_CMD_CPU_ALTFREQ ; Switch to the alternate frequency.
|
||||
SETFREQ2: CALL SVC_CMD
|
||||
OR A
|
||||
JP NZ,SETFREQERR
|
||||
LD A,H
|
||||
CP L
|
||||
RET Z ; If we are disabling the alternate cpu frequency (ie. = 0) exit.
|
||||
LD A, TZSVC_CMD_CPU_CHGFREQ ; Switch to the base frequency.
|
||||
CALL SVC_CMD
|
||||
OR A
|
||||
JP NZ,SETFREQERR
|
||||
RET
|
||||
|
||||
; Method to configure the hardware to use the T80 CPU instantiated in the FPGA.
|
||||
;
|
||||
SETT80: IN A,(CPUINFO)
|
||||
LD C,A
|
||||
AND CPUMODE_IS_SOFT_MASK
|
||||
CP CPUMODE_IS_SOFT_AVAIL
|
||||
JP NZ,SOFTCPUERR
|
||||
LD A,C
|
||||
AND CPUMODE_IS_T80
|
||||
JP Z,NOT80ERR
|
||||
;LD L,VMMODE_VGA_640x480 ; Enable VGA mode for a better display.
|
||||
;CALL SETVGAMODE1
|
||||
LD A, TZSVC_CMD_CPU_SETT80 ; We need to ask the K64F to switch to the T80 as it may involve loading of ROMS.
|
||||
CALL SVC_CMD
|
||||
OR A
|
||||
JP NZ,SETT80ERR
|
||||
RET
|
||||
|
||||
; Method to configure the hardware to use the original Z80 CPU installed on the tranZPUter board.
|
||||
;
|
||||
SETZ80: IN A,(CPUINFO)
|
||||
AND CPUMODE_IS_SOFT_MASK
|
||||
CP CPUMODE_IS_SOFT_AVAIL
|
||||
JP NZ,SOFTCPUERR
|
||||
CALL SETVMODE1 ; Turn off VGA mode, return to default MZ video.
|
||||
LD A, TZSVC_CMD_CPU_SETZ80
|
||||
CALL SVC_CMD
|
||||
OR A
|
||||
JP NZ,SETZ80ERR
|
||||
RET
|
||||
|
||||
; Method to configure the hardware to use the ZPU Evolution CPU instantiated in the FPGA.
|
||||
;
|
||||
SETZPUEVO: IN A,(CPUINFO)
|
||||
LD C,A
|
||||
AND CPUMODE_IS_SOFT_MASK
|
||||
CP CPUMODE_IS_SOFT_AVAIL
|
||||
JP NZ,SOFTCPUERR
|
||||
LD A,C
|
||||
AND CPUMODE_IS_ZPU_EVO
|
||||
JP Z,NOZPUERR
|
||||
LD L,VMMODE_VGA_640x480 ; Enable VGA mode for a better display.
|
||||
CALL SETVGAMODE1
|
||||
LD A, TZSVC_CMD_CPU_SETZPUEVO ; We need to ask the K64F to switch to the ZPU Evo as it may involve loading of ROMS.
|
||||
CALL SVC_CMD
|
||||
OR A
|
||||
JP NZ,SETZPUERR
|
||||
HALT ; ZPU will take over so stop the Z80 from further processing.
|
||||
|
||||
;----------------------------------------------
|
||||
; Hardware Emulation Mode Activation Routines.
|
||||
;----------------------------------------------
|
||||
|
||||
SETMZ80K: LD D, TZSVC_CMD_EMU_SETMZ80K ; We need to ask the K64F to switch to the Sharp MZ80K emulation as it involves loading ROMS.
|
||||
JR SETEMUMZ
|
||||
SETMZ80C: LD D, TZSVC_CMD_EMU_SETMZ80C
|
||||
JR SETEMUMZ
|
||||
SETMZ1200: LD D, TZSVC_CMD_EMU_SETMZ1200
|
||||
JR SETEMUMZ
|
||||
SETMZ80A: LD D, TZSVC_CMD_EMU_SETMZ80A
|
||||
JR SETEMUMZ
|
||||
SETMZ700: LD D, TZSVC_CMD_EMU_SETMZ700
|
||||
JR SETEMUMZ
|
||||
SETMZ1500: LD D, TZSVC_CMD_EMU_SETMZ1500
|
||||
JR SETEMUMZ
|
||||
SETMZ800: LD D, TZSVC_CMD_EMU_SETMZ800
|
||||
JR SETEMUMZ
|
||||
SETMZ80B: LD D, TZSVC_CMD_EMU_SETMZ80B
|
||||
JR SETEMUMZ
|
||||
SETMZ2000: LD D, TZSVC_CMD_EMU_SETMZ2000
|
||||
JR SETEMUMZ
|
||||
SETMZ2200: LD D, TZSVC_CMD_EMU_SETMZ2200
|
||||
JR SETEMUMZ
|
||||
SETMZ2500: LD D, TZSVC_CMD_EMU_SETMZ2500
|
||||
JR SETEMUMZ
|
||||
;
|
||||
; General function to determine if the emulator MZ hardware is present and activate it. Activation requires making a request to the
|
||||
; I/O processor as it needs to load up the correct BIOS etc prior to activating the emulation.
|
||||
;
|
||||
SETEMUMZ: IN A,(CPUINFO) ; Verify that the FPGA has emuMZ capabilities.
|
||||
LD C,A
|
||||
AND CPUMODE_IS_SOFT_MASK
|
||||
CP CPUMODE_IS_SOFT_AVAIL
|
||||
JR NZ,SOFTCPUERR
|
||||
LD A,C
|
||||
AND CPUMODE_IS_EMU_MZ
|
||||
JR Z,NOEMUERR
|
||||
LD L,VMMODE_VGA_640x480 ; Enable VGA mode for a better display.
|
||||
CALL SETVGAMODE1
|
||||
;
|
||||
PUSH DE ; Setup the initial video mode based on the required emulation.
|
||||
LD A,D
|
||||
SUB TZSVC_CMD_EMU_SETMZ80K
|
||||
LD L,A
|
||||
LD H,0
|
||||
CALL SETVMODE0
|
||||
POP DE
|
||||
;
|
||||
LD A, D ; Load up the required emulation mode.
|
||||
CALL SVC_CMD
|
||||
OR A
|
||||
JR NZ,SETT80ERR
|
||||
HALT
|
||||
|
||||
; Simple routine to clear screen or attributes.
|
||||
CLR8: LD BC,00800H
|
||||
PUSH DE
|
||||
LD D,A
|
||||
CLR8_1: LD (HL),D
|
||||
INC HL
|
||||
DEC BC
|
||||
LD A,B
|
||||
OR C
|
||||
JR NZ,CLR8_1
|
||||
POP DE
|
||||
RET
|
||||
;
|
||||
; Message addresses are in Bank2.
|
||||
;
|
||||
NOFPGAERR: LD DE,MSGNOFPGA
|
||||
JR BADNUM2
|
||||
SETFREQERR: LD DE,MSGFREQERR
|
||||
JR BADNUM2
|
||||
SETT80ERR: LD DE,MSGT80ERR
|
||||
JR BADNUM2
|
||||
SETZ80ERR: LD DE,MSGZ80ERR
|
||||
JR BADNUM2
|
||||
SETZPUERR: LD DE,MSGZPUERR
|
||||
JR BADNUM2
|
||||
SOFTCPUERR: LD DE,MSGNOSOFTCPU
|
||||
JR BADNUM2
|
||||
NOT80ERR: LD DE,MSGNOT80CPU
|
||||
JR BADNUM2
|
||||
NOZPUERR: LD DE,MSGNOZPUCPU
|
||||
JR BADNUM2
|
||||
NOEMUERR: LD DE,MSGNOEMU
|
||||
JR BADNUM2
|
||||
BADNUMERR: LD DE,MSGBADNUM
|
||||
BADNUM2: CALL ?PRINTMSG
|
||||
RET
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF ADDITIONAL TZFS COMMANDS
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; The FDC controller uses it's busy/wait signal as a ROM address line input, this
|
||||
; causes a jump in the code dependent on the signal status. It gets around the 2MHz Z80 not being quick
|
||||
; enough to process the signal by polling.
|
||||
ALIGN_NOPS FDCJMP1
|
||||
ORG FDCJMP1
|
||||
FDCJMPL4: JP (IX)
|
||||
|
||||
|
||||
; The FDC controller uses it's busy/wait signal as a ROM address line input, this
|
||||
; causes a jump in the code dependent on the signal status. It gets around the 2MHz Z80 not being quick
|
||||
; enough to process the signal by polling.
|
||||
ALIGN_NOPS FDCJMP2
|
||||
ORG FDCJMP2
|
||||
FDCJMPH4: JP (IY)
|
||||
|
||||
|
||||
; Ensure we fill the entire 4K by padding with FF's.
|
||||
;
|
||||
ALIGN_NOPS 10000H
|
||||
BIN
software/roms/1Z001M.rom
vendored
Normal file
BIN
software/roms/1Z001M.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/KUMA80.BIN
vendored
Normal file
BIN
software/roms/KUMA80.BIN
vendored
Normal file
Binary file not shown.
BIN
software/roms/monitor_1z-013a-km.rom
vendored
Normal file
BIN
software/roms/monitor_1z-013a-km.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/monitor_1z-013a.rom
vendored
Normal file
BIN
software/roms/monitor_1z-013a.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/monitor_80c_1z-013a-km.rom
vendored
Normal file
BIN
software/roms/monitor_80c_1z-013a-km.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/monitor_80c_1z-013a.rom
vendored
Normal file
BIN
software/roms/monitor_80c_1z-013a.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/monitor_80c_sa1510.rom
vendored
Normal file
BIN
software/roms/monitor_80c_sa1510.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/monitor_sa1510.rom
vendored
Normal file
BIN
software/roms/monitor_sa1510.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/mz2000_basic_1z001.rom
vendored
Executable file
BIN
software/roms/mz2000_basic_1z001.rom
vendored
Executable file
Binary file not shown.
BIN
software/roms/mz2000_basic_1z002.rom
vendored
Executable file
BIN
software/roms/mz2000_basic_1z002.rom
vendored
Executable file
Binary file not shown.
BIN
software/roms/mz2000_ipl_fusionx.rom
vendored
Normal file
BIN
software/roms/mz2000_ipl_fusionx.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/mz2000_ipl_original.rom
vendored
Normal file
BIN
software/roms/mz2000_ipl_original.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/mz2000_ipl_tzpu.rom
vendored
Normal file
BIN
software/roms/mz2000_ipl_tzpu.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/mz2000_mon_1z001m.rom
vendored
Normal file
BIN
software/roms/mz2000_mon_1z001m.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/mz800_1z_013b.rom
vendored
Normal file
BIN
software/roms/mz800_1z_013b.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/mz800_9z_504m.rom
vendored
Normal file
BIN
software/roms/mz800_9z_504m.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/mz800_iocs.rom
vendored
Normal file
BIN
software/roms/mz800_iocs.rom
vendored
Normal file
Binary file not shown.
BIN
software/roms/mz800_ipl.rom
vendored
Normal file
BIN
software/roms/mz800_ipl.rom
vendored
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user