aboutsummaryrefslogtreecommitdiffstats
path: root/src/dmesg.asm
blob: 5d991b006c9acf09658f769dfbdb8d8d379fdb93 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
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