new memory and project layout

This commit is contained in:
Joppe Blondel
2026-10-01 12:17:47 +02:00
parent 9b1fcac8ee
commit d19ffc70a1
10 changed files with 397 additions and 272 deletions
+60 -34
View File
@@ -1,12 +1,13 @@
# Z80 UART monitor
This ROM provides a small interactive monitor and a bundled Z80 Tiny BASIC
interpreter on the UART/CTC card at I/O base `20`. At reset, a small ROM
bootstrap copies both programs into the top 16 KiB of RAM and starts the
monitor. Only occupied code/vector bytes are stored and copied; uninitialized
data is cleared directly in high RAM. The low ROM can subsequently be disabled
without taking away the monitor, Tiny BASIC, monitor data, or interrupt table.
No runtime RAM below `C000` is used.
This project provides a resident BIOS, an interactive monitor, and ROM-resident
applications for a Z80 system with a UART/CTC card at I/O base `20`.
At reset, a small ROM bootstrap copies only the BIOS and monitor into the top
16 KiB of RAM at `C000`. The BIOS initializes interrupt mode 2 and the UART,
then starts the monitor. Applications remain in ROM and execute in place while
calling the stable BIOS jump table in high RAM. Tiny BASIC is the first such
application, linked at ROM address `1000`.
Connect a terminal at **2400 baud, 8 data bits, no parity, 1 stop bit**.
Commands are case-insensitive and all numeric arguments are hexadecimal; an
@@ -20,8 +21,8 @@ optional `0x` prefix is accepted.
| `I 20` | Read I/O port 20 |
| `O 20 57` | Write 57 to I/O port 20 |
| `G 8000` | Execute code at address 8000 |
| `G D000` | Start the bundled Z80 Tiny BASIC interpreter |
| `B` or `BASIC` | Shortcut for `G D000` |
| `G 1000` | Start the ROM-resident Z80 Tiny BASIC interpreter |
| `B` or `BASIC` | Shortcut for `G 1000` |
| `HELP` | Show the command summary |
`G` transfers control with a return address on the stack, so code ending in
@@ -43,45 +44,70 @@ The outputs are:
The current compact image is 6,157 bytes. Its ROM layout is:
- `0000-007F`: reset/copy bootstrap
- `0080-0F6E`: monitor image copied to RAM at `C000-CEEE`
- `0F6F-0FFF`: unused space reserved for monitor growth
- `1000-180C`: Tiny BASIC image copied to RAM at `D000-D80C`
- `0080-0F9D`: packed BIOS+monitor image copied to RAM at `C000-CF1D`
- `0F9E-0FFF`: unused space reserved for the resident image to grow
- `1000-180C`: Tiny BASIC, executed directly from ROM
- `180D-7FFF`: unused space available for additional ROM content
The monitor executable starts at `C080`; its IM 2 vector table is at `C040`.
The bootstrap obtains both copy lengths from generated/linker symbols, so the
copied sizes track changes to the programs automatically.
The resident image starts at `C000`, its IM 2 vector table is at `C040`, and
linked code starts at `C080`. The bootstrap obtains the resident copy length
from a linker symbol, so it tracks BIOS and monitor changes automatically.
The resulting high-RAM layout is:
The resulting RAM layout is:
- `C000-CEEE`: monitor vectors, services, and code
- `CEEF-CFFF`: free
- `D000-D80C`: Tiny BASIC code
- `D80D-DFFF`: free
- `E000-E7FF`: Tiny BASIC workspace and BASIC program text
- `E800-E877`: Tiny BASIC variables and input buffer
- `E878-EFFF`: Tiny BASIC stack space
- `F000-FFFF`: monitor globals and monitor stack
- `8000-AFFF`: Tiny BASIC workspace and BASIC program text
- `B000-B077`: Tiny BASIC variables and input buffer
- `B078-BFFF`: Tiny BASIC stack space
- `C000-CF1D`: resident BIOS, vectors, services, and monitor
- `CF1E-EFFF`: free space for resident-image growth
- `F000-FFFF`: BIOS globals, UART buffers, and monitor stack
The BIOS and monitor continue to work if low ROM is disabled. ROM-resident
applications naturally require ROM to remain mapped while they execute.
## BIOS interface
Assembly applications include `include/bios.inc` and call these fixed entries:
| Address | Service | Interface |
| --- | --- | --- |
| `C050` | `BIOS_PUTC` | Write character in `A` |
| `C053` | `BIOS_TRY_GETC` | Return character in `A`, or zero |
| `C056` | `BIOS_GETC` | Wait for and return a character in `A` |
| `C059` | `BIOS_IO_OUT` | Write `L` to port `A` |
| `C05C` | `BIOS_IO_IN` | Read port `A`, returning the value in `A` |
| `C05F` | `BIOS_DELAY_MS` | Delay approximately `HL` milliseconds |
| `C062` | `BIOS_MONITOR` | Warm-start the monitor; does not return |
The service wrappers preserve working registers except for documented return
values. The monitor uses the corresponding C API declared in `bios.h`.
Project organization:
- `boot.asm`: ROM bootstrap, high vectors, BIOS jump table, and assembly glue
- `bios.c` / `bios.h`: UART, buffers, interrupts, and resident BIOS API
- `monitor.c`: command interpreter implemented on the BIOS API
- `apps/tinybasic.asm`: first ROM-resident application
- `apps/README.md`: ROM application memory and integration contract
- `include/bios.inc`: stable assembly interface for ROM applications
## Tiny BASIC
The original GNU-z80asm listing is retained as `tinybasic/tinybasic.asm`. Its
`sdasz80` port is `tinybasic/tinybasic_sdas.asm` and is built automatically.
The port replaces fixed low-page `RST` calls with relocatable calls and uses a
marker-based command table so addresses in the `D000` page work correctly.
Tiny BASIC is built from `apps/tinybasic.asm`. The port replaces fixed low-page
`RST` calls with relocatable calls and uses a marker-based command table so it
can be linked at a nonzero ROM address.
At reset the bootstrap copies Tiny BASIC from ROM offset `1000` to `D000`.
Start it from the monitor with:
Tiny BASIC is linked at and runs directly from ROM address `1000`. Start it from
the monitor with:
```text
B
```
`BASIC` and `G D000` are equivalent alternatives.
`BASIC` and `G 1000` are equivalent alternatives.
Tiny BASIC calls the monitor ABI at `C050` for output and `C053` for
non-blocking input. The assembly ABI wrappers preserve the working registers,
and Tiny BASIC keeps interrupts enabled so it can share the monitor's configured
Tiny BASIC calls the BIOS at `C050` for output and `C053` for non-blocking
input. Tiny BASIC keeps interrupts enabled so it can share the BIOS-configured
interrupt-driven UART.
Line editing accepts either `BS` (`08`) or `DEL` (`7F`) for backspace and emits