;bootable zpage seek/read ;copyright (c) Peter Ferrie 2015-16 ;thanks to 4am for inspiration and testing ;assemble using ACME !cpu 6502 !to "0boot",plain *=$800 tracks = $d1 ;user-defined address = $d1 ;user-defined entry = $d1d1 ;user-defined sectors = $00 ;user-defined, sectors to load from partial track (increase tracks first) version = 2 ;memory usage: ;256 bytes ($200-2FF) static table grouped = $200 ;106 bytes ($300-369) static table preshift = $300 ;86 bytes ($36A-3BF) dynamic table (2-bit array) bit2tbl = $36a !byte 1 ;we'll read the other one ourselves lsr ;check sector number bne + ;branch if not 1 inc $3d ;increment sector (faster to find) txa lsr lsr lsr lsr ora #$c0 ;slot to PROM base pha lda #$5b ;read-1 pha rts ;the following TAY is a workaround for a CFFA bug ;the bug is that Y isn't zero on entry ;the workaround sets it to one instead ;it's not zero, but it's better than #$10 + tay txa ora #$8c ;slot to Q6L - ldx $900, y stx $0, y ;copy RTS to zpage iny bne - - iny ldx <(patchtbl-1), y sta $0, x ;replace placeholders with Q6L bne - and #$f0 ;PHASEOFF sta <(slotpatch6+1) ora #8 ;MOTOROFF sta <(slotpatch8+1) ldx #(stackend-addrtbl) - lda <(addrtbl-1), x pha ;copy stack frame dex bne - ldy #<(tracks*2) bne + ;branch always *=$839 jsr preread lda #>(entry-1) pha lda #<(entry-1) pha ldx #<((tracks*16)+sectors) lda #address jmp $bf00 ;DOS 3.3 launcher entrypoint ;build read/seek call-sequence per track + !if sectors>0 { txa pha lda #0 { ++ } pha lda #<(seek-1) pha ;push seek twice for two phases dey bne - ;construct denibbilisation table ;pre-shifted for interleave read ldx #$40 -- ldy <(tmpval+1) tya asl bit <(tmpval+1) beq + ora <(tmpval+1) eor #$ff and #$7e - bcs + lsr bne - dex txa asl asl sta preshift-$16, y + dec <(tmpval+1) bne -- ;construct 2-bit group table -- lsr <(curtrk+1) lsr <(curtrk+1) - lda 0 { !byte $2c ldx #<(-sectors) } stx