aboutsummaryrefslogtreecommitdiffstats
path: root/src/boot.asm
diff options
context:
space:
mode:
authoruser <user@clank>2026-07-18 10:10:04 +0200
committeruser <user@clank>2026-07-18 10:10:17 +0200
commit0cc9b0a8bdf774ee376937d5a6767ccdced51245 (patch)
tree221326e7a86fa0121ae7eea1763a9f3ffa8100e6 /src/boot.asm
parentkernel: dmesg-style boot spew before init spawns (diff)
downloadgbos-0cc9b0a8bdf774ee376937d5a6767ccdced51245.tar.gz
gbos-0cc9b0a8bdf774ee376937d5a6767ccdced51245.tar.xz
gbos-0cc9b0a8bdf774ee376937d5a6767ccdced51245.zip
kernel: a real timer source (64 Hz tick IRQ) + uptime(1)
The kernel had no clock: TimerISR was a reti stub, IEF_TIMER masked, and IME was never enabled - the vectors were decorative. sys_sleep just polls DIV deltas per-process; nothing counted globally. Now: TAC runs the hardware timer at 16384 Hz with TMA=0, so TIMA overflows at exactly 64 Hz; TimerISR increments a monotonic 32-bit wTicks (wraps after ~2.1 years). Scheduling stays cooperative - the ISR is transparent. Enabling IME in a kernel written for zero interrupts needs care wherever SP points into memory whose bank is being switched (an IRQ pushes onto SP): - read_block/write_block map the disk bank over the $A000 window that holds the caller's stack -> di/ei around the transfer (~2ms, well under the 15.6ms tick period, so no tick is ever lost) - hSwitchTo switches SVBK + cart-RAM banks under the outgoing stack -> di on entry, ei once the incoming stack is mapped - fork already runs on KSTACK_TOP2 (fixed WRAM) - safe as-is - term_putc's SVBK switch only remaps $Dxxx, stacks live in $Axxx/$Cxxx SYS_UPTIME (36) copies the counter (4B LE, di/ei so the read can't tear) to a user buffer; libc gticks(); usr/uptime.c formats 'up [Nd] H:MM:SS'. uptime avoids SDCC long div/shift entirely: sm83.lib modules link into their own areas that land in the $A000 RAM window (latent build.sh trap, documented there) - bytewise >>6 plus bounded subtraction loops instead.
Diffstat (limited to 'src/boot.asm')
-rw-r--r--src/boot.asm14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/boot.asm b/src/boot.asm
index c2d461a..4049f9d 100644
--- a/src/boot.asm
+++ b/src/boot.asm
@@ -81,11 +81,19 @@ KernelInit:
call SchedInit ; pick first task, set wCurProc
- ; interrupts: enable timer for preemption
+ ; system tick: hardware timer at 16384 Hz input, TMA=0 -> TIMA overflow
+ ; IRQ at 64 Hz. TimerISR just counts (wTicks); scheduling stays
+ ; cooperative. Only the timer bit is enabled in IE.
+ xor a
+ ld [rTIMA], a
+ ld [rTMA], a
+ ld a, %00000111 ; enable | 16384 Hz
+ ld [rTAC], a
xor a
ld [rIF], a
- ; ld a, IEF_TIMER ; (timer bit) - leave masked for cooperative demo
- ; ld [rIE], a
+ ld a, IEF_TIMER
+ ld [rIE], a
+ ei
; hand control to the first task via a context switch-in
jp SchedRunFirst