Relocated monitor to top 16k

This commit is contained in:
Joppe Blondel
2026-09-28 13:54:52 +02:00
parent bedcbfdd24
commit 53b44adcef
3 changed files with 71 additions and 24 deletions
+24 -11
View File
@@ -9,10 +9,13 @@ METAL_RELFILES := $(METAL_ASM_SRCFILES:%.asm=$(BUILDDIR)/metal/%.rel) \
METAL_CC := sdcc METAL_CC := sdcc
METAL_AS := sdasz80 METAL_AS := sdasz80
METAL_MAKEBIN := makebin METAL_MAKEBIN := makebin
METAL_FLAGS := -mz80 --no-std-crt0 --code-loc 0x0080 --data-loc 0x8000 METAL_FLAGS := -mz80 --no-std-crt0 --code-loc 0xC080 --code-size 0x2F80 --data-loc 0xF000
METAL_CPPFLAGS := -I src -I $(BUILDDIR)/metal/generated --disable-warning 283 METAL_CPPFLAGS := -I src -I $(BUILDDIR)/metal/generated --disable-warning 283
METAL_BIN_SIZE := 32768 METAL_BIN_SIZE := 32768
METAL_RAM_SIZE := 32768 METAL_RAM_SIZE := 16384
METAL_IMAGE_SIZE := 65536
MONITOR_BASE := 0xC000
MONITOR_ROM_OFFSET := 128
.DEFAULT_GOAL := metal .DEFAULT_GOAL := metal
@@ -21,24 +24,34 @@ METAL_RAM_SIZE := 32768
all: metal all: metal
metal: $(BUILDDIR)/metal/$(TARGET).ihx $(BUILDDIR)/metal/$(TARGET).bin $(BUILDDIR)/metal/$(TARGET).prog.bin metal: $(BUILDDIR)/metal/$(TARGET).ihx $(BUILDDIR)/metal/$(TARGET).bin $(BUILDDIR)/metal/$(TARGET).prog.bin
@awk -v rom_capacity=$(METAL_BIN_SIZE) -v ram_capacity=$(METAL_RAM_SIZE) '\ @stored=$$(wc -c < $(BUILDDIR)/metal/$(TARGET).prog.bin); \
$$1 ~ /^_(CODE|HOME|GSINIT|GSFINAL|INITIALIZER|ITABLE[0-7]*)$$/ { rom += $$5 } \ awk -v rom_capacity=$(METAL_BIN_SIZE) -v stored=$$stored -v ram_capacity=$(METAL_RAM_SIZE) '\
$$1 ~ /^_(DATA|INITIALIZED|BSEG|BSS|HEAP|STACK)$$/ { ram += $$5 } \ $$1 ~ /^_(CODE|HOME|GSINIT|GSFINAL|INITIALIZER)$$/ || $$1 ~ /^_ITABLE/ { code += $$5 } \
$$1 ~ /^_(DATA|INITIALIZED|BSEG|BSS|HEAP)$$/ { data += $$5 } \
END { \ END { \
printf "\nMemory usage:\n"; \ printf "\nMemory usage:\n"; \
printf " ROM: %5u / %5u bytes (%5.1f%%), %5u bytes free\n", rom, rom_capacity, 100 * rom / rom_capacity, rom_capacity - rom; \ printf " ROM storage: %5u / %5u bytes (%5.1f%%)\n", stored, rom_capacity, 100 * stored / rom_capacity; \
printf " RAM: %5u / %5u bytes (%5.1f%%), %5u bytes free\n", ram, ram_capacity, 100 * ram / ram_capacity, ram_capacity - ram; \ printf " Runtime RAM: %5u / %5u bytes (%5.1f%%), %5u bytes for growth/stack\n", code + data, ram_capacity, 100 * (code + data) / ram_capacity, ram_capacity - code - data; \
printf " code/vector: %5u bytes; static data: %5u bytes\n", code, data; \
}' $(BUILDDIR)/metal/$(TARGET).map }' $(BUILDDIR)/metal/$(TARGET).map
$(BUILDDIR)/metal/$(TARGET).ihx: $(METAL_RELFILES) $(BUILDDIR)/metal/$(TARGET).ihx: $(METAL_RELFILES)
@mkdir -p $(@D) @mkdir -p $(@D)
$(METAL_CC) $(METAL_FLAGS) -o $@ $(METAL_RELFILES) $(METAL_CC) $(METAL_FLAGS) -o $@ $(METAL_RELFILES)
$(BUILDDIR)/metal/$(TARGET).bin: $(BUILDDIR)/metal/$(TARGET).ihx $(BUILDDIR)/metal/$(TARGET).flat.bin: $(BUILDDIR)/metal/$(TARGET).ihx
$(METAL_MAKEBIN) -s $(METAL_BIN_SIZE) $< $@ $(METAL_MAKEBIN) -s $(METAL_IMAGE_SIZE) $< $@
$(BUILDDIR)/metal/$(TARGET).prog.bin: $(BUILDDIR)/metal/$(TARGET).ihx $(BUILDDIR)/metal/$(TARGET).prog.bin: $(BUILDDIR)/metal/$(TARGET).flat.bin
$(METAL_MAKEBIN) -p $< $@ @payload_end=$$(awk '$$1 == "DEF" && $$2 == "monitor_image_end" { print $$3 }' $(BUILDDIR)/metal/$(TARGET).noi); \
payload_size=$$((payload_end - $(MONITOR_BASE))); \
test $$payload_size -gt 0; \
dd if=$< of=$@ bs=1 count=$(MONITOR_ROM_OFFSET) status=none; \
dd if=$< of=$@ bs=1 skip=$$(( $(MONITOR_BASE) )) seek=$(MONITOR_ROM_OFFSET) count=$$payload_size conv=notrunc status=none
$(BUILDDIR)/metal/$(TARGET).bin: $(BUILDDIR)/metal/$(TARGET).flat.bin $(BUILDDIR)/metal/$(TARGET).prog.bin
dd if=$< of=$@ bs=$(METAL_BIN_SIZE) count=1 status=none
dd if=$(BUILDDIR)/metal/$(TARGET).prog.bin of=$@ conv=notrunc status=none
$(BUILDDIR)/metal/%.rel: %.c $(BUILDDIR)/metal/%.rel: %.c
@mkdir -p $(@D) @mkdir -p $(@D)
+17 -2
View File
@@ -1,7 +1,14 @@
# Z80 UART monitor # Z80 UART monitor
This ROM provides a small interactive monitor on the UART/CTC card at I/O base This ROM provides a small interactive monitor on the UART/CTC card at I/O base
`20`. Connect a terminal at **2400 baud, 8 data bits, no parity, 1 stop bit**. `20`. At reset, a small ROM bootstrap copies the monitor into the top 16 KiB of
RAM at `C000-FFFF` and starts it there. Only the occupied vector/code bytes are
stored and copied; uninitialized data is cleared directly in high RAM. The low ROM can subsequently be disabled
without taking the monitor, its data, or its interrupt table away. Runtime code
and vectors occupy the lower part of this window, globals begin at `F000`, and
the stack grows downward from `FFFF`; no RAM below `C000` is used.
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 Commands are case-insensitive and all numeric arguments are hexadecimal; an
optional `0x` prefix is accepted. optional `0x` prefix is accepted.
@@ -26,4 +33,12 @@ make
``` ```
The outputs are `build/metal/monitor.bin` (32 KiB ROM image) and The outputs are `build/metal/monitor.bin` (32 KiB ROM image) and
`build/metal/monitor.prog.bin` (compact programmer image). `build/metal/monitor.prog.bin` (compact programmer image). The ROM layout is:
- `0000-007F`: reset/copy bootstrap
- `0080...`: compact vector/code image copied to RAM starting at `C000`
- Remaining bytes: unused and available for additional ROM content
The monitor executable starts at `C080`; its IM 2 vector table is at `C040`.
`monitor.prog.bin` ends immediately after the occupied payload, while
`monitor.bin` remains a complete 32 KiB chip image.
+30 -11
View File
@@ -1,5 +1,7 @@
STACK_TOP = 0xFFFF STACK_TOP = 0xFFFF
DELAY_LOOPS_PER_MS = 40 DELAY_LOOPS_PER_MS = 40
MONITOR_BASE = 0xC000
MONITOR_ROM_SOURCE = 0x0080
.globl _main .globl _main
.globl _delay_ms .globl _delay_ms
@@ -8,33 +10,49 @@ DELAY_LOOPS_PER_MS = 40
.globl _enable_interrupts .globl _enable_interrupts
.globl _disable_interrupts .globl _disable_interrupts
.globl _jump_to .globl _jump_to
.globl monitor_image_end
.globl s__DATA .globl s__DATA
.globl l__DATA .globl l__DATA
.globl s__INITIALIZER .globl s__INITIALIZER
.globl s__INITIALIZED .globl s__INITIALIZED
.globl l__INITIALIZER .globl l__INITIALIZER
.area _ITABLE (ABS) .area _BOOT (ABS)
.org 0x00 .org 0x00
jp init jp boot_copy
.org 0x08 .org 0x08
boot_copy:
di
ld sp, #STACK_TOP
ld hl, #MONITOR_ROM_SOURCE
ld de, #MONITOR_BASE
ld bc, #(monitor_image_end - MONITOR_BASE)
ldir
jp init
.area _ITABLE (ABS)
; The executable vector page is part of the image copied to high RAM.
.org MONITOR_BASE
jp init
.org MONITOR_BASE + 0x08
reti reti
.org 0x10 .org MONITOR_BASE + 0x10
reti reti
.org 0x18 .org MONITOR_BASE + 0x18
reti reti
.org 0x20 .org MONITOR_BASE + 0x20
reti reti
.org 0x28 .org MONITOR_BASE + 0x28
reti reti
.org 0x30 .org MONITOR_BASE + 0x30
reti reti
.org 0x38 .org MONITOR_BASE + 0x38
reti reti
; ITABLE ; IM 2 table: the CTC supplies vectors 40, 42, 44, and 46.
.org 0x40 .org MONITOR_BASE + 0x40
.dw ctc_isr ; CTC channel 0: vector 0x40 .dw ctc_isr ; CTC channel 0: vector 0x40
.dw ctc_isr ; CTC channel 1: vector 0x42 .dw ctc_isr ; CTC channel 1: vector 0x42
.dw ctc_isr ; CTC channel 2: vector 0x44 .dw ctc_isr ; CTC channel 2: vector 0x44
@@ -48,7 +66,7 @@ init:
call gsinit call gsinit
; Setup interrupt mode 2 ; Setup interrupt mode 2
xor a ld a, #0xC0
ld i, a ld i, a
im 2 im 2
call _main call _main
@@ -88,6 +106,7 @@ clear_loop:
gsinit_done: gsinit_done:
.area _GSFINAL .area _GSFINAL
ret ret
monitor_image_end:
.area _CODE .area _CODE