Files
super6502/sw/bios/bootloader.s
2023-08-15 23:06:10 -07:00

195 lines
3.9 KiB
ArmAsm

.importzp sp, ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, sreg
.autoimport on
.feature string_escapes
.MACPACK generic
.MACPACK longbranch
_console_clear = $0
_console_read_char = $2
_console_write_char = $4
_sd_readblock = $6
sectors_per_cluster = $800D
reserved_sectors = $800E
fat_count = $8010
sectors_per_fat = $8024
buf = $8200
addrh = $0000
addrl = $0000
.zeropage
data_start: .res 2
.segment "BOOTSECTOR"
_start:
jmp _main
.byte "SUPR6502"
_preamble:
.res (11+_start-_preamble)
_bpb: .res 60
_main:
lda #<str
ldx #>str
jsr _cputs
lda fat_count
cmp #$2
jne @fail
lda sectors_per_fat
asl
pha
lda sectors_per_fat + 1
rol
tax
pla
adc reserved_sectors
bcc @a
inx
@a: sta data_start
stx data_start + 1
jsr pushax
stz sreg
stz sreg+1
jsr pusheax
lda #<buf
ldx #>buf
jsr pushax
lda #<ptr1
ldx #>ptr1
jsr _SD_readSingleBlock
lda #<buf
ldx #>buf
jsr _SD_printBuf
lda #$20 ; Start at first directory entry (first is a disk label)
sta ptr3
lda #>buf
sta ptr3 + 1
ldy #$0b ; look for attributes
@1: lda (ptr3),y
cmp #$0f ; if attribute is 0xf, this is a lfn
bne @2 ; if not an lfn, then try to read filename
clc ; otherwise, go to the next entry (+0x20)
lda ptr3
adc #$20
sta ptr3
bra @1
@2: ldy #11 ; ignore the attributes. Write null to make a string
lda #$00
sta (ptr3),y
lda ptr3 ; store address of the filename string on the stack
pha
ldx ptr3 + 1
phx
lda #<_boot2_str ; load the string "BOOT2 BIN"
ldx #>_boot2_str
jsr pushax
plx ; then push the string we read earlier
pla
jsr _strcmp
bne @fail ; if they are not equal then fail
lda #<_good ; TODO: We should try the next entry
ldx #>_good
jsr _cputs ; otherwise continue on
ldy #$1b ; load the high byte of the low first cluster
lda (ptr3),y
tax
dey
lda (ptr3),y ; load the low byte of the low first cluster
sec
sbc #$02 ; don't handle carry, assume low byte is not 0 or 1
ldx data_start + 1 ; load x as high data start
asl ; multiply cluster num (minus 2) by 8
asl
asl
clc
adc data_start ; add that to low data start
bcc @3 ; handle carry
inx
@3: stz sreg
stz sreg+1
phx
pha
jsr pusheax
lda #<buf
ldx #>buf
jsr pushax
lda #<ptr1
ldx #>ptr1
jsr _SD_readSingleBlock
stz sreg
stz sreg+1
pla
plx
inc
jsr pusheax
lda #<buf
ldx #>buf
inx
inx
jsr pushax
lda #<ptr1
ldx #>ptr1
jsr _SD_readSingleBlock
jmp buf
bra @end
; Now we have the cluster number of the bootloader (3)
; this means we need to read from address 00ef_e000 + ((3 -2) * 8 * 512)
; 00eff000 is the address we want, which is efe000 + 4096
@fail: lda #<_fail
ldx #>_fail
jsr _cputs
@end: bra @end
str: .asciiz "boot\r\n"
_boot2_str: .asciiz "BOOT2 BIN"
_fail: .asciiz "not bootloader\r\n"
_good: .asciiz "found bootloader!\r\n"
_cluster: .asciiz "cluster: %lx\r\n"
_addr: .asciiz "addr: %x\r\n"
_end:
.res (440+_start-_end)
.res 6
.res 16
.res 16
.res 16
.res 16
.byte $55
.byte $AA