314 lines
6.5 KiB
ArmAsm
314 lines
6.5 KiB
ArmAsm
.importzp sp, ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, sreg, data_start
|
|
|
|
.autoimport on
|
|
|
|
.export fatbuf
|
|
|
|
.feature string_escapes
|
|
|
|
.MACPACK generic
|
|
|
|
fatbuf = $A000
|
|
filebuf = $B000
|
|
|
|
.zeropage
|
|
|
|
tbase: .res 2
|
|
tlen: .res 2
|
|
dbase: .res 2
|
|
dlen: .res 2
|
|
olen: .res 1
|
|
otype: .res 1
|
|
|
|
userptr: .res 2
|
|
|
|
.segment "BOOTLOADER"
|
|
|
|
sectors_per_cluster = $800D
|
|
reserved_sectors = $800E
|
|
fat_count = $8010
|
|
sectors_per_fat = $8024
|
|
|
|
O65_NO_C65 = $00
|
|
O65_MAGIC = $02
|
|
O65_VERSION = $05
|
|
O65_MODE = $06
|
|
O65_TBASE = $08
|
|
O65_TLEN = $0a
|
|
O65_DBASE = $0c
|
|
O65_DLEN = $0e
|
|
O65_BBASE = $10
|
|
O65_BLEN = $12
|
|
O65_ZBASE = $14
|
|
O65_ZLEN = $16
|
|
O65_STACK = $18
|
|
O65_OPT_START = $1A
|
|
|
|
_start:
|
|
lda #<str
|
|
ldx #>str
|
|
jsr _cputs
|
|
|
|
; Read root directory entry into fatbuf
|
|
lda data_start
|
|
ldx data_start + 1
|
|
jsr pushax
|
|
stz sreg
|
|
stz sreg+1
|
|
jsr pusheax
|
|
lda #<fatbuf
|
|
ldx #>fatbuf
|
|
jsr pushax
|
|
lda #<ptr1
|
|
ldx #>ptr1
|
|
jsr _SD_readSingleBlock
|
|
|
|
lda #<fatbuf
|
|
ldx #>fatbuf
|
|
jsr _SD_printBuf
|
|
|
|
lda #$20 ; Start at first directory entry (first is a disk label)
|
|
sta ptr3
|
|
lda #>fatbuf
|
|
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
|
|
@next: clc ; otherwise, go to the next entry (+0x20)
|
|
lda ptr3
|
|
adc #$20
|
|
sta ptr3
|
|
bcc @4
|
|
inc ptr3 + 1
|
|
@4: lda #<word_str
|
|
ldx #>word_str
|
|
jsr pushax
|
|
lda ptr3
|
|
ldx ptr3 + 1
|
|
pha
|
|
phx
|
|
jsr pushax
|
|
phy
|
|
ldy #$4
|
|
jsr _cprintf
|
|
ply
|
|
plx
|
|
stx ptr3 + 1
|
|
pla
|
|
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
|
|
jsr _cputs ; print out short filenames as we read them
|
|
lda #$0d
|
|
jsr _cputc
|
|
lda #$0a
|
|
jsr _cputc
|
|
lda #<kernel_str ; load the string "KERNEL O65"
|
|
ldx #>kernel_str
|
|
jsr pushax
|
|
plx ; then push the string we read earlier
|
|
pla
|
|
jsr _strcmp
|
|
bne @next ; if they are not equal then try next entry
|
|
lda #<_good ; print match if we found it
|
|
ldx #>_good
|
|
jsr _cputs ; otherwise continue on
|
|
|
|
lda #<word_str
|
|
ldx #>word_str
|
|
jsr pushax
|
|
|
|
lda ptr3
|
|
pha
|
|
lda ptr3 + 1
|
|
pha
|
|
|
|
ldy #$1d ; load file size (256)
|
|
lda (ptr3),y
|
|
lsr ; divide by 2 to get file size (512)
|
|
sta filesiz
|
|
jsr pusha0
|
|
ldy #$4
|
|
jsr _cprintf
|
|
|
|
pla
|
|
sta ptr3 + 1
|
|
pla
|
|
sta ptr3
|
|
|
|
ldy #$1b ; load high byte of low first cluster
|
|
lda (ptr3),y
|
|
tax
|
|
dey
|
|
lda (ptr3),y ; load low byte of 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 @5 ; handle carry
|
|
inx
|
|
@5: sta cluster
|
|
stx cluster + 1
|
|
|
|
lda #<filebuf
|
|
ldx #>filebuf
|
|
sta userptr
|
|
stx userptr + 1
|
|
|
|
@read_sd:
|
|
lda cluster
|
|
ldx cluster + 1
|
|
stz sreg
|
|
stz sreg+1
|
|
jsr pusheax
|
|
lda userptr
|
|
ldx userptr + 1
|
|
jsr pushax
|
|
lda #<ptr1
|
|
ldx #>ptr1
|
|
jsr _SD_readSingleBlock
|
|
|
|
lda userptr
|
|
ldx userptr + 1
|
|
jsr _SD_printBuf
|
|
|
|
dec filesiz
|
|
bmi @doneload
|
|
inc cluster
|
|
inc userptr + 1
|
|
inc userptr + 1
|
|
bra @read_sd
|
|
|
|
@doneload:
|
|
ldy #O65_TBASE
|
|
lda filebuf,y
|
|
sta tbase
|
|
iny
|
|
ldx filebuf,y
|
|
stx tbase + 1
|
|
|
|
ldy #O65_TLEN
|
|
lda filebuf,y
|
|
sta tlen
|
|
iny
|
|
ldx filebuf,y
|
|
stx tlen + 1
|
|
|
|
|
|
ldy #O65_DBASE
|
|
lda filebuf,y
|
|
sta dbase
|
|
iny
|
|
ldx filebuf,y
|
|
stx dbase + 1
|
|
|
|
ldy #O65_DLEN
|
|
lda filebuf,y
|
|
sta dlen
|
|
iny
|
|
ldx filebuf,y
|
|
stx dlen + 1
|
|
|
|
ldy #O65_OPT_START
|
|
phy
|
|
@opt_len:
|
|
lda #<opt_str
|
|
ldx #>opt_str
|
|
jsr pushax
|
|
ply
|
|
lda filebuf,y
|
|
beq @opt_end
|
|
sta olen
|
|
phy
|
|
jsr pusha0
|
|
ply
|
|
iny
|
|
lda filebuf,y
|
|
sta otype
|
|
phy
|
|
jsr pusha0
|
|
ldy #$6
|
|
jsr _cprintf
|
|
|
|
lda #<word_str
|
|
ldx #>word_str
|
|
jsr pushax
|
|
|
|
pla
|
|
adc olen
|
|
dec
|
|
dec
|
|
pha
|
|
bra @opt_len
|
|
|
|
@opt_end:
|
|
iny ; account for reading size
|
|
phy
|
|
lda #<opt_done
|
|
ldx #>opt_done
|
|
jsr pushax
|
|
pla
|
|
pha
|
|
jsr pusha0
|
|
ldy #$4
|
|
jsr _cprintf
|
|
|
|
pla
|
|
ldx #>filebuf
|
|
adc #<filebuf
|
|
bcc @6
|
|
inx
|
|
@6: sta userptr
|
|
stx userptr + 1
|
|
lda #<word_str
|
|
ldx #>word_str
|
|
jsr pushax
|
|
lda userptr
|
|
ldx userptr + 1
|
|
jsr pushax
|
|
ldy #$4
|
|
jsr _cprintf
|
|
|
|
;void* __fastcall__ memcpy (void* dest, const void* src, size_t count);
|
|
|
|
lda tbase
|
|
ldx tbase + 1
|
|
jsr pushax
|
|
lda userptr
|
|
ldx userptr + 1
|
|
jsr pushax
|
|
lda tlen
|
|
ldx tlen + 1
|
|
jsr _memcpy
|
|
|
|
lda #<$1000
|
|
ldx #>$1000
|
|
jsr _SD_printBuf
|
|
|
|
@end: bra @end
|
|
|
|
|
|
filesiz: .res 1
|
|
cluster: .res 2
|
|
|
|
str: .asciiz "boot2\r\n"
|
|
kernel_str: .asciiz "KERNEL O65"
|
|
_good: .asciiz "Found KERNEL\r\n"
|
|
word_str: .asciiz "Word Value: %x\r\n"
|
|
|
|
opt_str: .asciiz "Opt Len: %x, Opt Type: %x\r\n"
|
|
opt_done: .asciiz "Options done. total option length: %x\r\n" |