2019-10-12 21:28:50 +00:00
|
|
|
# Zapple-II
|
2019-10-12 22:37:10 +00:00
|
|
|
Tools for building and running Z80 code under ProDOS on an Apple II with a
|
|
|
|
Z80 Softcard (or clone)
|
|
|
|
|
|
|
|
- Z80 cross assemblers running under ProDOS on the Apple II
|
|
|
|
- CP/M BDOS emulation to allow CP/M programs to run under ProDOS
|
|
|
|
- Sample program: Processor Technology's SOL-20 BASIC/5
|
|
|
|
|
2019-10-13 00:47:41 +00:00
|
|
|
Aztec C v3.2 can be found [on this website](http://aztecmuseum.ca).
|
|
|
|
|
2019-10-12 22:37:10 +00:00
|
|
|
# Z80 Cross Assemblers & Tools
|
|
|
|
I didn't fancy writing a Z80 assembler from scratch, and I wasn't able to
|
|
|
|
find any existing Z80 cross-assemblers for 6502. In order to get something
|
|
|
|
up-and-running quickly, I searched for small Z80 assemblers written in C.
|
|
|
|
|
|
|
|
## Z80Asm
|
|
|
|
|
|
|
|
The first suitable candidate I found was `Z80Asm`, which was developed by Udo
|
|
|
|
Munk back in the 1988 to 1990 timeframe. (Hr. Munk is still active and has
|
|
|
|
repositories here on GitHub.) I am using an older version of Z80Asm (v1.1)
|
|
|
|
which is written in K&R (pre-ANSI) C, so it was easy to get it to compile on
|
|
|
|
Aztec C for the Apple II.
|
|
|
|
|
|
|
|
The program is rather large for Aztec C's compiler, and the resulting binary
|
|
|
|
was also too large to run in the available memory. I made a few minor
|
|
|
|
modifications:
|
|
|
|
|
|
|
|
- I split the largest source file `z80arfun.c` into eight pieces because
|
|
|
|
Aztec C can't handle files larger than around 500 lines.
|
|
|
|
- Slimmed down a few buffers to save some RAM.
|
|
|
|
- Reduced the number of supported files from 512 to 10.
|
|
|
|
- I had to compile the code to Aztec C VM code using `cci` rather than to
|
|
|
|
native 6502 code using `cc`. The natively compiled version creates an
|
|
|
|
executable which is too large to run.
|
|
|
|
|
|
|
|
The resulting assembler runs but it is quite slow due to the use of the Aztec
|
|
|
|
VM and can't assemble large programs with lots of symbols without running out
|
|
|
|
of memory. However I have been using it successfully to develop the BDOS
|
|
|
|
emulation.
|
|
|
|
|
|
|
|
`Z80Asm` also builds and runs on Linux which allows larger files to be
|
|
|
|
assembled and is much faster than running on 6502 at 1Mhz.
|
|
|
|
|
|
|
|
## Z80as
|
|
|
|
|
|
|
|
Udo Munk pointed me towards an alternative assembler, `Z80as`, which was
|
|
|
|
originally developed by the Mark Williams Company and which ran on PDP-11
|
|
|
|
under Coherent. This assembler has the advantage of small size, and is also
|
|
|
|
written in K&R C.
|
|
|
|
|
2019-10-13 00:18:59 +00:00
|
|
|
`Z80as` compiled 'out-of-the-box' under Aztec C on the Apple II, without any
|
|
|
|
modification.
|
|
|
|
|
|
|
|
This assembler generates Intel HEX files rather than BIN files, so I wrote a
|
|
|
|
simple converter called `HEX2BIN`.
|
2019-10-12 22:37:10 +00:00
|
|
|
|
|
|
|
`Z80as` also builds and runs on Linux which allows larger files to be
|
|
|
|
assembled and is much faster than running on 6502 at 1Mhz.
|
|
|
|
|
|
|
|
## HEX2BIN
|
|
|
|
|
|
|
|
This is a quick-and-dirty conversion program for converting the HEX files
|
|
|
|
generated by `Z80as` into BIN files that can be loaded on the Apple II using
|
|
|
|
`BLOAD`.
|
|
|
|
|
|
|
|
HEX files can have 'holes' in them, and `HEX2BIN` takes care of zero-filling
|
|
|
|
the holes.
|
|
|
|
|
|
|
|
# CP/M BDOS Emulation
|
|
|
|
|
|
|
|
I have started work on a CP/M BDOS emulation layer. The plan is to add
|
|
|
|
support for all the CP/M 2.2 system calls, which should allow a CP/M program
|
|
|
|
to run on the Softcard Z80 CPU and have all the system calls routed to the
|
|
|
|
6502 and serviced using the Apple II ROM monitor routines and the ProDOS MLI.
|
|
|
|
|
|
|
|
This is at an embryonic stage at the moment as it only provides three system
|
|
|
|
calls:
|
|
|
|
|
|
|
|
- BDOS call 01h: `C_READ` - Console input
|
|
|
|
- BDOS call 02h: `C_WRITE` - Console output
|
|
|
|
- BDOS call 0Bh: `C_STAT` - Console status
|
|
|
|
|
|
|
|
There are two parts to the BDOS emulation:
|
|
|
|
|
|
|
|
- `softcard80.asm` - This is the Z80 code to handle BDOS calls and send them
|
|
|
|
to the 6502 to be processed. Written in Z80 assembler. I am currently
|
|
|
|
assembling this using `Z80asm` (but will probably switch to `Z80as` when it
|
|
|
|
grows too large.
|
|
|
|
- `softcard65.asm` - This is the 6502 back end code. Written in Merlin8 v2.58.
|
|
|
|
|
|
|
|
# Sample Programs
|
|
|
|
|
|
|
|
## BASIC/5
|
|
|
|
|
|
|
|
This is one of the BASIC interpreters from the Processor Technologies SOL-20
|
|
|
|
system. The source code was provided as an example with z80as.
|
|
|
|
|
2019-10-13 00:18:59 +00:00
|
|
|
I assembled this code under `Z80as` on Linux, since it defines too many
|
|
|
|
symbols to assemble natively on the Apple II in the available memory. I plan
|
|
|
|
to take a look at the Aztec C build configuration to see if it is possible
|
|
|
|
to find more memory for dynamic allocation (ie: `malloc()`).
|
|
|
|
|
2019-10-12 22:37:10 +00:00
|
|
|
It is a 5K BASIC, so it is rather primitive. However it does have a floating
|
|
|
|
point package and trig functions.
|
|
|
|
|
|
|
|
BASIC/5 only uses three system calls: `C_READ`, `C_WRITE` and `C_STATUS`.
|
|
|
|
|
|
|
|
There is currently no support for loading or saving BASIC programs, but I may
|
|
|
|
add this later.
|
|
|
|
|
|
|
|
The manual for BASIC/5 is included in this GitHub repo, in PDF format.
|
|
|
|
|
2019-10-13 00:47:41 +00:00
|
|
|
Interestingly, there was a bug in the original BASIC/5 source that caused it
|
|
|
|
to initialize one byte of memory too many, blowing away the first byte of the
|
|
|
|
BDOS implementation at the top of memory. This has been patched by adding a
|
|
|
|
`DEC HL` instuction at line 47 (shout-out to Qkumba for finding what the
|
|
|
|
issue was!)
|
|
|
|
|
|
|
|
# How to Build the Code
|
|
|
|
|
|
|
|
You don't really need to build the code unless you want to make changes.
|
|
|
|
Pre-compiled versions of everything are included in this repository.
|
|
|
|
|
2019-10-13 00:54:11 +00:00
|
|
|
The 800K ProDOS disk image `zapple2.po` has all the files you should need.
|
|
|
|
|
2019-10-13 00:47:41 +00:00
|
|
|
## Building `Z80asm` using Aztec C
|
|
|
|
|
|
|
|
- Two scripts are provided to do the build: `compile` and `link`
|
|
|
|
- Run the script `compile`. This takes a long time!
|
|
|
|
- Run the script `link`. This just takes a couple of minutes.
|
|
|
|
- `z80asm` executable is created.
|
|
|
|
|
|
|
|
Note that `z80asm` can only be run from the Aztec C shell. It should be
|
|
|
|
possible to build it as a normal ProDOS application, but I have not done this
|
|
|
|
yet.
|
|
|
|
|
|
|
|
## Building `Z80as` using Aztec C
|
|
|
|
|
|
|
|
I didn't provide a script for this. Just build all the C files in Aztec C
|
|
|
|
as follows:
|
|
|
|
|
|
|
|
```
|
|
|
|
cc as0.c
|
|
|
|
cc as1.c
|
|
|
|
cc as2.c
|
|
|
|
cc as3.c
|
|
|
|
cc as4.c
|
|
|
|
cc as5.c
|
|
|
|
cc as6.c
|
|
|
|
ln -o z80as as0.o as1.o as2.o as3.0 as4.0 as5.0 as6.0 -lc
|
|
|
|
```
|
|
|
|
## Building `HEX2BIN` using Aztec C
|
|
|
|
|
|
|
|
- You can just run the script `makeh2b` in Aztec C
|
|
|
|
- This just does the following:
|
|
|
|
|
|
|
|
```
|
|
|
|
cc hex2bin.c
|
|
|
|
ln hex2bin.o -lc
|
|
|
|
```
|
|
|
|
|
|
|
|
## Building `SOFTCARD65` using Merlin8 2.58
|
|
|
|
|
|
|
|
- Start Merlin8 (v2.58)
|
|
|
|
- Hit 'D' for disk commands, enter `PREFIX /ZAPPLE2`
|
|
|
|
- Hit 'L' for load, enter `SOFTCARD65` and hit return.
|
|
|
|
- Hit 'E' for edit.
|
|
|
|
- Type `ASM` to assemble.
|
|
|
|
- Type 'Q' to go to the main menu.
|
|
|
|
- Hit 'O' to save the object file `SOFTCARD65` to disk, and hit return.
|
|
|
|
- Hit 'Q' to quit to ProDOS.
|
|
|
|
|
|
|
|
## Building `SOFTCARD80.BIN` using `Z80asm`
|
|
|
|
|
|
|
|
- In the Aztec C shell, enter the following commands:
|
|
|
|
- `cd /zapple2`
|
|
|
|
- `z80asm softcard80.asm`
|
|
|
|
|
2019-10-12 22:37:10 +00:00
|
|
|
# How to Run The Code
|
|
|
|
|
2019-10-13 00:47:41 +00:00
|
|
|
I provided a couple of ProDOS EXEC files to load all the pieces and run the
|
|
|
|
code:
|
|
|
|
|
|
|
|
`RUNBASIC5` performs the following operations:
|
|
|
|
|
|
|
|
```
|
|
|
|
BLOAD /ZAPPLE2/SOFTCARD80.BIN,A$FFD,Ttxt
|
|
|
|
BLOAD /ZAPPLE2/BASIC5.BIN,A$1100,T$00
|
|
|
|
BRUN /ZAPPLE2/SOFTCARD65
|
|
|
|
```
|
|
|
|
|
|
|
|
A little explanation is in order:
|
|
|
|
|
|
|
|
- The first line loads the Z80 code which provides the CP/M BDOS interface.
|
|
|
|
It is loaded at address $0FFD because there is a three byte prefix on the
|
|
|
|
BIN file (created by Z80asm). The actual start address is $1000 in 6502
|
|
|
|
address space, which is 0000H for the Z80.
|
|
|
|
- The second line loads the BASIC5 image at $1100 (0100H for the Z80).
|
|
|
|
- Finally we just run the 6502 code in `SOFTCARD65` to bootstrap the process.
|
|
|
|
This loads higher in memory (but below 32K at the moment because of a
|
|
|
|
Z80asm bug where it is treating the address as a signed 16 bit integer).
|
|
|
|
|
|
|
|
The other EXEC file `RUNTESTSTUB` is the same, but omits the second step.
|
|
|
|
Instead of running BASIC, it runs some internal test code that is part of
|
|
|
|
`SOFTCARD80.BIN`.
|
|
|
|
|
|
|
|
|
2019-10-12 22:37:10 +00:00
|
|
|
|