aboutsummaryrefslogtreecommitdiffstats
path: root/src/boot.asm
blob: 513c3926b71f015f6a25d2f943cec8c73228f414 (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
; =============================================================================
; boot.asm - cartridge header, reset vectors, kernel entry & init
; =============================================================================
INCLUDE "include/gbos.inc"

; -----------------------------------------------------------------------------
; RST vectors. We reserve rst $30 as the syscall trap.
; -----------------------------------------------------------------------------
SECTION "rst00", ROM0[$00]
    ret
SECTION "rst30_syscall", ROM0[$30]
    jp SyscallTrap          ; user code does: ld c, SYS_x ; rst $30

; -----------------------------------------------------------------------------
; Interrupt vectors
; -----------------------------------------------------------------------------
SECTION "vblank", ROM0[$40]
    reti
SECTION "stat", ROM0[$48]
    reti
SECTION "timer", ROM0[$50]
    jp TimerISR             ; drives preemptive scheduling
SECTION "serial", ROM0[$58]
    reti
SECTION "joypad", ROM0[$60]
    reti

; -----------------------------------------------------------------------------
; Entry point. rgbfix writes the Nintendo logo + header over $104-$14F.
; -----------------------------------------------------------------------------
SECTION "entry", ROM0[$100]
    nop
    jp KernelInit
    ds $150 - @         ; reserve $104-$14F for logo + header (rgbfix fills)

; -----------------------------------------------------------------------------
; Kernel init
; -----------------------------------------------------------------------------
SECTION "kinit", ROM0

KernelInit:
    di
    ld sp, KSTACK_TOP

    ; enable cart RAM (MBC5)
    ld a, $0A
    ld [MBC5_RAM_ENABLE], a

    call ClearKernelRAM
    call CopyHramCode           ; move context-switch trampoline into HRAM
    call ProcInit               ; wipe process table

    ; --- spawn the two demo tasks (text-in-ROM model) ---
    ; task A: entry TaskA, RAM bank 0, u-area WRAM bank 1
    ld hl, TaskA
    ld b, 0                     ; RAM bank
    ld c, 1                     ; WRAM u-area bank
    call ProcCreate

    ld hl, TaskB
    ld b, 1
    ld c, 2
    call ProcCreate

    call SchedInit              ; pick first task, set wCurProc

    ; interrupts: enable timer for preemption
    xor a
    ld [rIF], a
    ; ld a, IEF_TIMER  ; (timer bit) - leave masked for cooperative demo
    ; ld [rIE], a

    ; hand control to the first task via a context switch-in
    jp SchedRunFirst

; -----------------------------------------------------------------------------
ClearKernelRAM:
    ; zero the kernel globals region only ($C000-$CBFF). We must NOT touch
    ; $CC00-$CFFF: the kernel stack (SP=$D000) grows down into it, and our
    ; own return address lives there while this routine runs.
    ld hl, $C000
    ld bc, $0C00
.loop
    xor a
    ld [hl+], a
    dec bc
    ld a, b
    or c
    jr nz, .loop
    ret