aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/boot.asm15
-rw-r--r--src/dmesg.asm311
-rw-r--r--src/fs.asm2
-rw-r--r--src/kdata.asm3
-rw-r--r--src/programs.asm1
5 files changed, 330 insertions, 2 deletions
diff --git a/src/boot.asm b/src/boot.asm
index c29267d..c2d461a 100644
--- a/src/boot.asm
+++ b/src/boot.asm
@@ -41,12 +41,19 @@ SECTION "kinit", ROM0
KernelInit:
di
ld sp, KSTACK_TOP
+ push af ; boot ROM hands the console model in A/B -
+ push bc ; park it on the (uncleared) stack for dmesg
; enable cart RAM (MBC5)
ld a, $0A
ld [MBC5_RAM_ENABLE], a
call ClearKernelRAM
+ pop bc
+ pop af
+ ld [wBootA], a
+ ld a, b
+ ld [wBootB], a
call CopyHramCode ; move context-switch trampoline into HRAM
call ProcInit ; wipe process table
; point wCurProc at the (zeroed) kernel PCB so disk I/O during boot restores
@@ -56,11 +63,15 @@ KernelInit:
ld a, HIGH(wKernelPCB)
ld [wCurProc+1], a
call pipe_init ; mark all pipes free
+ call term_init ; LCD console first, so the boot spew is visible
+ call boot_banner ; dmesg: kernel/console/cart/mem/proc lines
call net_init ; clear the socket table, set our IP (10.0.0.2)
+ call boot_net
call fs_init ; mount the disk (format on first boot; persists)
- call term_init ; set up the LCD text terminal
+ call boot_fs
call osk_init ; build the on-screen keyboard (window layer)
- ; terminal starts blank; shell output flows in via KPutc
+ call boot_tty
+ call boot_init ; "init: spawning pid 1"
; --- spawn the init task (pid 1); it fork()s the rest ---
ld hl, TaskInit
diff --git a/src/dmesg.asm b/src/dmesg.asm
new file mode 100644
index 0000000..5d991b0
--- /dev/null
+++ b/src/dmesg.asm
@@ -0,0 +1,311 @@
+; =============================================================================
+; dmesg.asm - kernel boot spew: everything the kernel knows implicitly before
+; init spawns, printed dmesg-style on the LCD console (and mirrored over the
+; link port, so a gbhub logs the whole boot).
+;
+; The info costs nothing to know:
+; - the boot ROM hands the console model in A/B at entry (saved to wBootA/B)
+; - the cartridge describes itself in its own header ($0147-$0149)
+; - the CGB memory map is a constant of the hardware
+; - subsystem shapes (proc slots, sockets, program table) are link-time facts
+; - fs_init just mounted (or formatted) the disk and left the block bitmap
+; in fs_bmbuf - counting free blocks is a 16-byte popcount
+; =============================================================================
+INCLUDE "include/gbos.inc"
+
+SECTION "dmesg", ROM0
+
+; -----------------------------------------------------------------------------
+; kernel console output (boot-time: no process context, so KPutc is unusable)
+; -----------------------------------------------------------------------------
+; kputc(A = char) - LCD terminal + serial mirror. Preserves BC/DE/HL.
+kputc::
+ push bc
+ push de
+ push hl
+ ld b, a
+ ld [rSB], a ; mirror to the link (gbhub console log)
+ ld a, $81
+ ld [rSC], a
+ ld a, b
+ call term_putc
+ pop hl
+ pop de
+ pop bc
+ ret
+
+; kputs(HL = NUL-terminated string). Clobbers A, HL.
+kputs::
+.l
+ ld a, [hl+]
+ or a
+ ret z
+ call kputc
+ jr .l
+
+; kputhex(A = byte) - two uppercase hex digits. Clobbers A.
+kputhex::
+ push af
+ swap a
+ call .nib
+ pop af
+.nib
+ and $0F
+ add "0"
+ cp "9" + 1
+ jr c, .put
+ add "A" - "9" - 1
+.put
+ jp kputc
+
+; kputdec(A = 0..255) - decimal, no leading zeros. Clobbers A, BC, DE.
+kputdec::
+ ld c, 0 ; "printed a digit yet" flag
+ ld b, 100
+ call .digit
+ ld b, 10
+ call .digit
+ add "0"
+ jp kputc ; ones digit always prints
+.digit ; A/B -> A = remainder; prints quotient digit
+ ld e, 0
+.sub
+ cp b
+ jr c, .rem
+ sub b
+ inc e
+ jr .sub
+.rem
+ ld d, a
+ ld a, e
+ or c
+ jr z, .skip ; leading zero
+ ld a, e
+ add "0"
+ call kputc
+ ld c, 1
+.skip
+ ld a, d
+ ret
+
+; -----------------------------------------------------------------------------
+; boot_banner - kernel line + console model + cart header + memory map + proc
+; shape. Called right after term_init.
+; -----------------------------------------------------------------------------
+boot_banner::
+ ld hl, .s_kernel
+ call kputs
+
+ ; console model: boot ROM leaves A=$11 (CGB/AGB, B bit0 = AGB), $01 (DMG),
+ ; $FF (MGB/pocket)
+ ld hl, .s_console
+ call kputs
+ ld a, [wBootA]
+ cp $11
+ jr nz, .not_cgb
+ ld a, [wBootB]
+ bit 0, a
+ jr z, .cgb
+ ld hl, .s_agb
+ jr .model
+.cgb
+ ld hl, .s_cgb
+ jr .model
+.not_cgb
+ cp $01
+ jr nz, .not_dmg
+ ld hl, .s_dmg
+ jr .model
+.not_dmg
+ ld hl, .s_mgb
+.model
+ call kputs
+ ld hl, .s_boota
+ call kputs
+ ld a, [wBootA]
+ call kputhex
+ ld a, ")"
+ call kputc
+ ld a, 10
+ call kputc
+
+ ; cart: the header describes the very cartridge we run from
+ ld hl, .s_cart
+ call kputs
+ ld a, [$0147] ; cart type
+ cp $19
+ jr c, .rawtype
+ cp $1F
+ jr nc, .rawtype
+ ld hl, .s_mbc5
+ call kputs
+ jr .romsize
+.rawtype
+ ld hl, .s_type
+ call kputs
+ ld a, [$0147]
+ call kputhex
+.romsize
+ ld hl, .s_rom
+ call kputs
+ ld a, [$0148] ; ROM size code: 32K << code
+ cp 9
+ jr nc, .romq
+ add a ; *2: word index into the pointer table
+ ld e, a
+ ld d, 0
+ ld hl, .romtab
+ add hl, de
+ ld a, [hl+]
+ ld h, [hl]
+ ld l, a
+ jr .romp
+.romq
+ ld hl, .s_unk
+.romp
+ call kputs
+ ld hl, .s_sram
+ call kputs
+ ld a, [$0149] ; cart RAM size code
+ cp 6
+ jr nc, .ramq
+ add a
+ ld e, a
+ ld d, 0
+ ld hl, .ramtab
+ add hl, de
+ ld a, [hl+]
+ ld h, [hl]
+ ld l, a
+ jr .ramp
+.ramq
+ ld hl, .s_unk
+.ramp
+ call kputs
+ ld hl, .s_sram2
+ call kputs
+
+ ; memory map: hardware constants of the CGB
+ ld hl, .s_mem
+ call kputs
+
+ ; processes + programs: link-time shape of the kernel
+ ld hl, .s_proc
+ call kputs
+ ld hl, ProgramTableEnd - ProgramTable ; bytes; 4 per entry
+ ld a, l
+ srl h
+ rra
+ srl h
+ rra ; /4 (table < 1K, fits in A)
+ call kputdec
+ ld hl, .s_progs
+ call kputs
+ ret
+
+.s_kernel: db "gbos sm83 microkernel\n", 0
+.s_console: db "console: ", 0
+.s_cgb: db "CGB", 0
+.s_agb: db "AGB", 0
+.s_dmg: db "DMG", 0
+.s_mgb: db "MGB", 0
+.s_boota: db " (boot a=$", 0
+.s_cart: db "cart: ", 0
+.s_mbc5: db "mbc5", 0
+.s_type: db "type $", 0
+.s_rom: db ", ", 0
+.s_sram: db " rom, ", 0
+.s_sram2: db " sram\n", 0
+.s_unk: db "?", 0
+.s_mem: db "mem: 32K wram 16K vram 127B hram\n", 0
+.s_proc: db "proc: {d:MAX_PROCS} slots, ", 0
+.s_progs: db " programs\n", 0
+.romtab: dw .r0, .r1, .r2, .r3, .r4, .r5, .r6, .r7, .r8
+.r0: db "32K",0
+.r1: db "64K",0
+.r2: db "128K",0
+.r3: db "256K",0
+.r4: db "512K",0
+.r5: db "1M",0
+.r6: db "2M",0
+.r7: db "4M",0
+.r8: db "8M",0
+.ramtab: dw .m0, .m1, .m2, .m3, .m4, .m5
+.m0: db "no",0
+.m1: db "2K",0
+.m2: db "8K",0
+.m3: db "32K",0
+.m4: db "128K",0
+.m5: db "64K",0
+
+; -----------------------------------------------------------------------------
+; boot_net - after net_init: the link is the network.
+; -----------------------------------------------------------------------------
+boot_net::
+ ld hl, .s
+ call kputs
+ ret
+.s: db "net: slip on link port, {d:MAX_SOCKS} sockets\n", 0
+
+; -----------------------------------------------------------------------------
+; boot_fs - after fs_init: mounted vs freshly formatted, and free blocks
+; (popcount of clear bits in the block bitmap fs_init left in fs_bmbuf).
+; -----------------------------------------------------------------------------
+boot_fs::
+ ld hl, .s_fs
+ call kputs
+ ld a, [wBootFsFresh]
+ or a
+ jr z, .mounted
+ ld hl, .s_fresh
+ call kputs
+ jr .count
+.mounted
+ ld hl, .s_mount
+ call kputs
+.count
+ ld hl, fs_bmbuf
+ ld b, FS_NBLOCKS / 8
+ ld c, 0 ; free-block count
+.byte
+ ld a, [hl+]
+ cpl ; set bits = free blocks
+ ld e, 8
+.bit
+ rra
+ jr nc, .nofree
+ inc c
+.nofree
+ dec e
+ jr nz, .bit
+ dec b
+ jr nz, .byte
+ ld a, c
+ call kputdec
+ ld hl, .s_of
+ call kputs
+ ld a, FS_NBLOCKS
+ call kputdec
+ ld hl, .s_blkfree
+ call kputs
+ ret
+.s_fs: db "fs: gbfs v{d:FS_VERSION} ", 0
+.s_mount: db "mounted, ", 0
+.s_fresh: db "formatted, ", 0
+.s_of: db "/", 0
+.s_blkfree: db " blk free\n", 0
+
+; -----------------------------------------------------------------------------
+; boot_tty / boot_init - console shape, and the handoff line.
+; -----------------------------------------------------------------------------
+boot_tty::
+ ld hl, .s
+ call kputs
+ ret
+.s: db "tty: 40x18 console, SELECT = osk\n", 0
+
+boot_init::
+ ld hl, .s
+ call kputs
+ ret
+.s: db "init: spawning pid 1\n", 0
diff --git a/src/fs.asm b/src/fs.asm
index 1c6d299..adc04fb 100644
--- a/src/fs.asm
+++ b/src/fs.asm
@@ -615,6 +615,8 @@ fs_init::
cp FS_VERSION
jr z, .load
.fmt
+ ld a, 1
+ ld [wBootFsFresh], a ; report "formatted" in the boot spew
call fs_format
.load
ld a, BLK_BITMAP
diff --git a/src/kdata.asm b/src/kdata.asm
index 83ed162..65a059a 100644
--- a/src/kdata.asm
+++ b/src/kdata.asm
@@ -62,3 +62,6 @@ wSleepLastDiv::DS 1 ; sys_sleep: previous DIV reading
wKillParent::DS 1 ; scratch for sys_kill
wPsBuf:: DS 2 ; scratch for sys_ps
wPnStart:: DS 2 ; scratch for sys_progname
+wBootA:: DS 1 ; A at entry: console model from the boot ROM
+wBootB:: DS 1 ; B at entry: bit0 set = AGB (GBA in CGB mode)
+wBootFsFresh::DS 1 ; fs_init formatted a blank disk this boot
diff --git a/src/programs.asm b/src/programs.asm
index 92c736b..6dbc584 100644
--- a/src/programs.asm
+++ b/src/programs.asm
@@ -237,6 +237,7 @@ ProgramTable::
dw ProgDhcp
db LOW(BANK(ProgIrc)), HIGH(BANK(ProgIrc))
dw ProgIrc
+ProgramTableEnd::
; -----------------------------------------------------------------------------
; NameTable (ROM0) - command name -> program id, searched by sys_lookup.