- .area _CODE
+ .area _BOOT
.db 'A'
.db 'B'
- .dw wtfami + 0x4000
+ .dw bootstrap
.dw 0,0,0,0,0,0
-;
-; Entered at 0x4000 but linked at 0x0000 so be careful
-;
-wtfami: di
-
- ld a, #0x23 ; Debug port
- out (0x2e), a
- ld a, #':'
- out (0x2f), a
-
- in a, (0xA8)
- ld d, a
- and #0x0C ; bits for 0x4000
- ld b, a
- rla
- rla ; to 0x8000
- or b ; and 0x4000
- rla
- rla ; to 0xC000/8000
- or b ; and 0x4000
- ld b, a ; B is now the bits for
- ; putting 48K of cartridge
- ; in place
- out (0xA8), a ; Map cartridge
+ .globl enaslt
+ .globl slotrom
+ .globl slotram
+ .globl find_ram
+
+ ; At this point the BIOS has detected the cartridge AB signature and
+ ; jumped here; we have the rom bios in bank 0, ram in bank 3, and rom
+ ; in bank 1 (this code).
+bootstrap:
+ di
+ ld sp,#0xf340 ; temporary stack
+
+ ; FIXME: init vdp using bios so that font is in place after vdpinit
+ ld a,#0x50
+ ld (0xf3ae),a
+ ld ix,#0x00d5
+ call #0x015f
+
+ call find_ram
+ ld (slotram),a
+ call find_rom
+ ld (slotrom),a
+
+ ; set cartridge rom in bank 0 and ram in bank 2
+ ld hl,#0
+ call enaslt
+ ld a,(slotram)
+ ld hl,#0x8000
+ call enaslt
ld a, #3
- out (0xFC), a ; Begin mapping RAM
- ld a, #'1'
- out (0x2f), a
- exx
- ld hl, #0x4000 ; Cartridge 0x4000 -> RAM 0
- ld de, #0x0
+ out (0xFE),a
+
+ ; copy kernel page 3 to ram
+ ld hl, #0x0
+ ld de, #0x8000
ld bc, #0x4000
ldir
- dec a
- out (0xFC), a
- ld de, #0 ; 0x8000 -> RAM 0x4000
+
+ ; set ram in bank 0 and cartridge rom in bank 2
+ ld a,(slotram)
+ ld hl,#0
+ call enaslt
+ ld a,(slotrom)
+ ld hl,#0x8000
+ call enaslt
+
+ ; copy kernel pages 2 and 1 to ram
+ ld a, #2
+ out (0xFC),a
+ ld hl, #0x4000
+ ld de, #0x0
ld bc, #0x4000
ldir
- dec a
- out (0xFC), a
- ld de, #0 ; 0xC000 -> RAM 0x8000
+ ld a, #1
+ out (0xFC),a
+ ld hl, #0x8000
+ ld de, #0x0
ld bc, #0x4000
ldir
- exx
- ld a, #3 ; put the maps right
+
+ ; prepare mapped ram pages for all-ram
+ ld a, #3
out (0xFC), a
ld a, #2
out (0xFD), a
ld a, #1
out (0xFE), a
- xor a
- out (0xFF), a
- ld a, #'G'
- out (0x2f), a
- ld a, d
- and #0xC0 ; RAM in 0xC000 slot bits
- ld e, a
- rra ; Propogate into other banks
- rra
- or e
- rra
- rra
- or e
- rra
- rra
- or e
- ld e, a ; E is now "all RAM"
- and #0xF3
- ld c, a
- ld a, d ; Get original status
- and #0x0c ; bits for 0x4000 as cartridge
- or c ; bits for the RAM
- out (0xA8), a
- ld a, #'O'
- out (0x2f), a
- ;
- ; We now have RAM where we need it
- ;
- jp ramgo
-ramgo: ld a, #'!'
- out (0x2f), a
- ld a, e
- out (0xA8), a ; Now go all ram
+
+ ; set bank 2 to ram
+ ld a,(slotram)
+ ld hl,#0x8000
+ call enaslt
+
+ ; jump to start while keeping rom in page 1 (we are running from it)
+ ; will switch to all-ram in there
jp 0x100
- ; Hack Hack FIXME
- .ds 0x73
+
+ ; find slot currently set in page 1
+ ; returns slot in reg a using FxxxSSPP format (see enaslt)
+find_rom:
+ in a,(0xa8)
+ rrca
+ rrca
+ and #3
+ ld c,a
+ ld b,#0
+ ld hl,#0xfcc1 ; system variables containing slot and sub-slot data
+ ; set up by bios on boot
+ add hl,bc
+ ld a,(hl)
+ and #0x80
+ jr z,find_rom0
+ or c
+ ld c,a
+ inc hl
+ inc hl
+ inc hl
+ inc hl
+ ld a,(hl)
+ and #0x0C
+find_rom0:
+ or c
+ ret
+
+ ; find slot currently set in page 3
+ ; returns slot in reg a using FxxxSSPP format (see enaslt)
+find_ram:
+ in a,(0xa8)
+ rlca
+ rlca
+ and #3
+ ld c,a
+ ld b,#0
+ ld hl,#0xfcc1 ; system variables containing slot and sub-slot data
+ ; set up by bios on boot
+ add hl,bc
+ ld a,(hl)
+ and #0x80
+ jr z,find_ram0
+ or c
+ ld c,a
+ inc hl
+ inc hl
+ inc hl
+ inc hl
+ ld a,(hl)
+ rlca
+ rlca
+ rlca
+ rlca
+ and #0x0C
+find_ram0:
+ or c
+ ret
+
+ ; set slot and subslot at target address
+ ; (from msx bios listing)
+ ; hl - target address
+ ; a - slot : FxxxSSPP
+ ; F : expanded slot flag (if F=0, SS is ignored)
+ ; SS : expanded subslot
+ ; PP : primary slot
+enaslt:
+ call selprm ; calculate bit pattern and mask code
+ jp m, eneslt ; if expanded set secondary first
+ in a,(0xa8)
+ and c
+ or b
+ out (0xa8),a ; set primary slot
+ ret
+eneslt:
+ push hl
+ call selexp ; set secondary slot
+ pop hl
+ jr enaslt
+
+ ; calculate bit pattern and mask
+selprm:
+ di
+ push af
+ ld a,h
+ rlca
+ rlca
+ and #3
+ ld e,a ; bank number
+ ld a,#0xC0
+selprm1:
+ rlca
+ rlca
+ dec e
+ jp p, selprm1
+ ld e,a ; mask pattern
+ cpl
+ ld c,a ; inverted mask pattern
+ pop af
+ push af
+ and #3 ; extract xxxxxxPP
+ inc a
+ ld b,a
+ ld a,#0xAB
+selprm2:
+ add a,#0x55
+ djnz selprm2
+ ld d,a ; primary slot bit pattern
+ and e
+ ld b,a
+ pop af
+ and a ; if expanded slot set sign flag
+ ret
+
+ ; set secondary slot
+selexp:
+ push af
+ ld a,d
+ and #0xC0 ; get slot number for bank 3
+ ld c,a
+ pop af
+ push af
+ ld d,a
+ in a,(0xa8)
+ ld b,a
+ and #0x3F
+ or c
+ out (0xa8),a ; set bank 3 to target slot
+ ld a,d
+ rrca
+ rrca
+ and #3
+ ld d,a
+ ld a,#0xAB ; secondary slot to bit pattern
+selexp1:
+ add a,#0x55
+ dec d
+ jp p,selexp1
+ and e
+ ld d,a
+ ld a,e
+ cpl
+ ld h,a
+ ld a,(0xffff) ; read and update secondary slot register
+ cpl
+ ld l,a
+ and h ; strip off old bits
+ or d ; add new bits
+ ld (0xffff),a
+ ld a,b
+ out (0xa8),a ; restore status
+ pop af
+ and #3
+ ret
+
; Just for the benefit of the map file
.globl start
+ .globl enaslt
+ .globl slotram
+ .globl find_ram
; startup code @0x100
.area _CODE
; We assume here that the kernel packs below 48K for now we've got a few
; KBytes free but revisit as needed
;
-start: di
- ld a, #4 ; 0 holds 8K of stuff we might want
- out (0xff), a ; if we go the OS route, so use 4
- ; plus "0" is magic so this saves
- ; shifting them all by one.
+ .ds 0x100
+start:
+ di
; Debug port
ld a, #0x23
- out (0x2e), a
+ out (0x2e), a
ld a, #'@'
out (0x2f), a
+
+ ; read slot before switching ram page
+ ld a,(slotram)
+ ld hl,#0x4000
+ call enaslt
+
+ ld a, #4 ; 0 holds 8K of stuff we might want
+ out (0xff), a ; if we go the OS route, so use 4
+ ; plus "0" is magic so this saves
+ ; shifting them all by one.
+
+
ld sp, #kstack_top
+
; move the common memory where it belongs
ld hl, #s__INITIALIZER
ld de, #s__COMMONMEM
ld bc, #l__COMMONMEM
ldir
+
; move the discardable memory where it belongs
ld de, #s__DISCARD
ld bc, #l__DISCARD
ldir
+
; then zero the data area
ld hl, #s__DATA
ld de, #s__DATA + 1
call init_hardware
call _fuzix_main
di
-stop: halt
+stop: halt
jr stop