qboot: initial work

This commit is contained in:
Vince Weaver 2020-08-20 16:43:34 -04:00
parent 87ad2caad2
commit f8eb0fd058
4 changed files with 480 additions and 0 deletions

19
qboot/Makefile Normal file
View File

@ -0,0 +1,19 @@
include ../Makefile.inc
DOS33_RAW = ../dos33fs-utils/dos33_raw
all: boot.dsk
boot.dsk: BOOT
cp empty.dsk boot.dsk
$(DOS33_RAW) boot.dsk 0 0 BOOT
BOOT: boot_sector.o
ld65 -o BOOT boot_sector.o -C ../linker_scripts/apple2_800.inc
boot_sector.o: boot_sector.s stage2.s
ca65 -o boot_sector.o boot_sector.s -l boot_sector.lst
clean:
rm -f *~ *.o *.lst BOOT

204
qboot/boot_sector.s Normal file
View File

@ -0,0 +1,204 @@
; fast seek/multi-read
; copyright (c) Peter Ferrie 2015-16
sectors = $d1 ; user-defined
firsttrk = $d1 ; user-defined, first track to read
firstsec = $d1 ; user-defined, first sector to read
address = $d1 ; user-defined
entry = $d1d1 ; user-defined
version = 1
;memory usage:
;256 bytes ($bd00-bdff) static table
grouped = $bd00
;106 bytes ($xx00-xx69) static table
preshift = code_end
zvalue = $fd ;only during init
znibble = $fe ;only during init
zmask = $ff ;only during init
; $26/$27 sector read location (ROM), scratch space (RWTS)
; $3D sector number
; at entry (at least on AppleWin) A=1, X=60, Y=0
; qkumba says cffa cards leave Y at $10
; 26/27 = 00/09
; 3D = 1
; For Disk II booting, the firmware loads track0/sector0
; to $800 and then jumps to $801
.org $800
.byte 1 ; number of sectors for ROM to load
boot_entry:
; this code loads two sectors up to $BE/$BF
lsr ; check sector number
tay
adc #$bd
sta $27 ; set or update address as needed
asl
; be, bf, c0 (1011 1011 1100)
; so if hit $c000 we are done
bmi not_three ; branch if not 3
inc $3d ; increment sector (faster to find)
; call to the read routine in proper slot
; using rts to jump indirect to
; $CX5C
; this routine reads sector in $3D on track $41
; to address in $26/$27
; when it's done it jumps back to $801
txa ; x is slot# << 4
lsr
lsr
lsr
lsr
ora #$c0 ; slot to PROM base
pha
lda #$5b ;read-1
pha
rts
not_three:
txa
ora #$8c ; slot to Q6L
; Q6L?
; 1000 1100
patch_loop:
iny
ldx patchtbl-3, y
sta code_begin, x ;replace placeholders with Q6L
bne patch_loop
and #$f8 ;MOTOROFF
sta slotpatch7+1
eor #8 ;PHASEOFF
sta slotpatch8+1
ldx #$3f
stx zmask
inx
ldy #$7f
bne skip_ahead ; branch always
; pad with zeros until $839
.res $839-*
;*=$839
lda #>(entry-1)
pha
lda #<(entry-1)
pha
jsr preread
jmp $bf00 ;DOS 3.3 launcher entrypoint
patchtbl:
.byte <(slotpatch1+1), <(slotpatch2+1), <(slotpatch3+1), <(slotpatch4+1), <(slotpatch5+1), <(slotpatch6+1)
indextbl: ;the 0 also terminates the patchtbl list!
.byte 0, 2, 1, 3
;construct denibbilisation table
;pre-shifted for interleave read
skip_ahead:
loopaa:
sty znibble
tya
asl
bit znibble
beq loopz
ora znibble
eor #$ff
and #$7e
loopa:
bcs loopz
lsr
bne loopa
dex
txa
asl
asl
sta preshift-$16, Y
loopz:
dey
bne loopaa
;construct 2-bit group table
sty zvalue
loopbb:
lsr zmask
lsr zmask
loopb:
lda indextbl, X
sta grouped, Y
inc zvalue
lda zvalue
and zmask
bne loopy
inx
txa
and #3
tax
loopy:
iny
iny
iny
iny
cpy #3
bcs loopb
iny
cpy #3
bcc loopbb
lda #>(entry-1)
pha
lda #<(entry-1)
pha
jsr preread
jmp seekread
preread:
;copy post-read if necessary
;push post-read address here
; pla
; tax
; pla
; tay
; lda #>(postread-1)
; pha
; lda #<(postread-1)
; pha
; tya
; pha
; txa
; pha
lda #<(firsttrk*2)
sta phase+1
ldx #sectors
lda #address
ldy #firstsec
rts
end_code:
.res $8fe-*
; traditionally, entry point to jump to at end of loading
; $be01 in this case
;*=$8fe
.byte $be, 1
.include "stage2.s"

BIN
qboot/empty.dsk Normal file

Binary file not shown.

257
qboot/stage2.s Normal file
View File

@ -0,0 +1,257 @@
;the following lives on sectors $0E and $0D
; ????
.org $be00
code_begin:
.byte version
readnib:
slotpatch1:
lda $c0d1 ; ???
bpl readnib
rts
;fill address array for one track
seekread:
sty startsec+1
sta tmpadr+1
stx total+1
inittrk:
sec
lda #$10
sbc startsec+1
cmp total+1
bcs it_skip
tax
it_skip:
stx partial1
stx partial2
jsr seek
startsec:
ldy #$d1
tmpadr:
tmpadr_loop:
lda #$d1
sta addrtbl, y
inc tmpadr+1
iny
dec partial1
bne tmpadr_loop
read:
outer_read:
jsr readnib
inner_read:
cmp #$d5
bne outer_read
jsr readnib
cmp #$aa
bne inner_read
tay ; we need Y=#$AA later
jsr readnib
eor #$ad ; zero A if match
beq check_mode
;if not #$AD, then #$96 is assumed
ldy #2 ; volume, track, sector
another:
jsr readnib
rol ; set carry
sta sector+1
jsr readnib
and sector+1
dey
bpl another
tay
ldx addrtbl, Y ; fetch corresponding address
beq read
sta sector+1 ; store index for later
stx adrpatch1+2
stx adrpatch8+2
stx adrpatch2+2
stx adrpatch3+2
stx adrpatch5+2
stx adrpatch7+2
inx
stx adrpatch9+2
dex
dex
stx adrpatch4+2
stx adrpatch6+2
ldy #$fe
adrpatch1:
loop2:
lda $d102, Y
pha
iny
bne loop2
branch_read:
bcs read ; branch always
check_mode:
cpx #0
beq read ; loop if not expecting #$AD
loop33:
sta tmpval+1 ; zero rolling checksum
slotpatch2:
loop4:
ldx $c0d1
bpl loop4
lda preshift-$96, X
adrpatch2:
sta $d102, Y ; store 2-bit array
tmpval:
eor #$d1
iny
bne loop33
ldy #$aa
slotpatch3:
loop5:
ldx $c0d1
bpl loop5
eor preshift-$96, X
adrpatch3:
ldx $d102, Y ; bit2tbl
eor grouped+2, X ; first 86 nibbles use group bits 0-1
adrpatch4:
sta $d156, y
iny
bne loop5
and #$fc
ldy #$aa
slotpatch4:
loop6:
ldx $c0d1
bpl loop6
eor preshift-$96, X
adrpatch5:
ldx $d102, Y ; bit2tbl
eor grouped+1, X ; second 86 nibbles use group bits 2-3
adrpatch6:
sta $d1ac, Y
iny
bne loop6
and #$fc
ldx #$ac
slotpatch5:
loop7:
ldy $c0d1
bpl loop7
eor preshift-$96, Y
adrpatch7:
ldy $d100, X ; bit2tbl
eor grouped, Y ; last 84 nibbles use group bits 4-5
adrpatch8:
sta $d100, x
inx
bne loop7
and #$fc
slotpatch6:
loop8:
ldy $c0d1
bpl loop8
eor preshift-$96, Y
cmp #1 ; carry = !zero
ldy #1
loop9:
pla
adrpatch9:
sta $d100, Y
dey
bpl loop9
branch_read2:
bcs branch_read ; branch if checksum failure
sector:
ldy #$d1
txa
sta addrtbl, Y ; zero corresponding address
dec total+1
dec partial2 ; adjust remaining count (faster than looping over array)
sec
bne branch_read2 ; read all requested sectors in one track
total:
ldx #$d1
beq driveoff
inc phase+1
inc phase+1 ; update current track
jmp inittrk
driveoff:
slotpatch7:
lda $c0d1
seekret:
rts
seek:
lda #0
sta step+1
copy_cur:
curtrk:
lda #0
sta tmpval+1
sec
phase:
sbc #$d1
beq seekret
eor #$ff
inc curtrk+1
cmp step+1
bcc loop10
step:
lda #$d1
loop10:
cmp #8
bcs loop11
tay
sec
loop11:
lda curtrk+1
ldx step1, Y
bne loop12
loopmmm:
clc
lda tmpval+1
ldx step2, Y
loop12:
stx sector+1
and #3
rol
tax
slotpatch8:
sta $c0d1, X
loopmm:
ldx #$13
loopm:
dex
bne loopm
dec sector+1
bne loopmm
lsr
bcs loopmmm
inc step+1
bne copy_cur
step1: .byte 1, $30, $28, $24, $20, $1e, $1d, $1c
step2: .byte $70, $2c, $26, $22, $1f, $1e, $1d, $1c
addrtbl: .res 16
partial1 = *
partial2 = partial1+1
code_end=partial2+1