;read any file slot 6 version ;copyright (c) Peter Ferrie 2013 ;!cpu 65c02 ;!to "trk",plain ;*=$800 adrlo = $26 ;constant from boot prom adrhi = $27 ;constant from boot prom tmpsec = $3c ;constant from boot prom reqsec = $3d ;constant from boot prom A1L = $3c ;constant from ROM A1H = $3d ;constant from ROM A2L = $3e ;constant from ROM A2H = $3f ;constant from ROM curtrk = $40 niblo = $41 nibhi = $42 A4L = $42 ;constant from ROM A4H = $43 ;constant from ROM sizelo = $44 sizehi = $45 secsize = $46 TEMPX = $f9 TEMPY = $fa namlo = $fb namhi = $fc step = $fd ;state for stepper motor tmptrk = $fe ;temporary copy of current track phase = $ff ;current phase for seek reloc = $bc00 dirbuf = $bf00 MOVE = $fe2c ;unhook DOS and build nibble table init: jsr $fe93 jsr $fe89 lda #unreloc sta A1H lda #<(unreloc+(codeend-opendir)-1) sta A2L lda #>(unreloc+(codeend-opendir)-1) sta A2H ldy #0 sty A4L lda #>reloc sta A4H jsr MOVE ldx #3 L1: stx $3c txa asl bit $3c beq L3 ora $3c eor #$ff and #$7e L2: bcs L3 lsr bne L2 tya sta nibtbl, x iny L3: inx bpl L1 rts unreloc: ;!pseudopc reloc { ;turn on drive and read volume table of contents opendir: lda $c0e9 ldx #0 stx adrlo stx secsize lda #$11 jsr readdirsec firstent: lda dirbuf+1 ;lock if entry not found beq * ;read directory sector ldx dirbuf+2 jsr seekread1 ldy #7 ;number of directory entries in a sector ldx #$2b ;offset of filename in directory entry nextent: tya pha ; was **phy** txa pha ; was **phx** ldy #$1d ; match name backwards (slower but smaller) L4: lda (namlo), y cmp dirbuf, x beq foundname pla ; move to next directory in this block, if possible clc adc #$23 tax pla tay ; was **ply** dey bne nextent beq firstent ; was **bra** foundname: dex dey bpl L4 pla tay ; was **ply** pla ; read track/sector list lda dirbuf-32, y ldx dirbuf-31, y jsr seekread1 ; read load offset and length info only, initially lda #filbuf jsr seekread ; reduce load offset by 4, to account for offset and length sec lda filbuf sbc #4 sta adrlo lda filbuf+1 sbc #0 sta adrhi ; save on stack bytes that will be overwritten by extra read ldy #3 L5: lda (adrlo), y pha dey bpl L5 lda adrhi pha lda adrlo pha ; increase load size by 4, to account for offst and length lda filbuf+2 adc #3 sta sizelo sta secsize lda filbuf+3 adc #0 sta sizehi beq readfirst ldy #0 ; was **stz secsize** sty secsize readfirst: ldy #$0c ; read a file sector readnext: lda dirbuf, y ldx dirbuf+1, y sty TEMPY ; ** was phy ** jsr seekread1 ldy TEMPY ; ** was ply ** ; if low count is non-zero then we are done ; (can happen only for partial last block) lda secsize bne readdone ; continue if more than $100 bytes left dec sizehi bne L6 ;set read size to min(length, $100) lda sizelo beq readdone sta secsize L6: inc adrhi iny iny bne readnext ; save current address for after t/s read lda adrhi pha lda adrlo pha lda #0 sta adrlo ; was **stz adrlo** ; read next track/sector sector lda dirbuf+1 ldx dirbuf+2 jsr readdirsec clc ; restore current address readdone: pla sta adrhi pla sta adrlo bcc readfirst lda $c0e8 ; restore from stack bytes that were overwritten by extra read ldx #3 ldy #0 L7: pla sta (adrlo), y iny dex bpl L7 rts readdirsec: ldy #>dirbuf seekread: sty adrhi seekread1: sta phase lda sectbl, x sta reqsec jsr readadr ; if track does not match, then seek lda curtrk cmp phase beq checksec jsr seek ; [re-]read sector L8: jsr readadr checksec: cmp reqsec bne L8 ; read sector data readdata: ldy $c0ec bpl readdata L9: cpy #$d5 bne readdata L10: ldy $c0ec bpl L10 cpy #$aa ;we need Y=#$AA later bne L9 L11: lda $c0ec bpl L11 eor #$ad ;zero A if match bne * ;lock if read failure L12: ldx $c0ec bpl L12 eor nibtbl-$80, x sta bit2tbl-$aa, y iny bne L12 L13: ldx $c0ec bpl L13 eor nibtbl-$80, x sta (adrlo), y ;the real address iny cpy secsize bne L13 ldy #0 L14: ldx #$a9 L15: inx beq L14 lda (adrlo), y lsr bit2tbl-$aa, x rol lsr bit2tbl-$aa, x rol sta (adrlo), y iny cpy secsize bne L15 rts ;no tricks here, just the regular stuff readadr: lda $c0ec bpl readadr L16: cmp #$d5 bne readadr L17: lda $c0ec bpl L17 cmp #$aa bne L16 L18: lda $c0ec bpl L18 cmp #$96 bne L16 ldy #3 L19: sta curtrk L20: lda $c0ec bpl L20 rol sta tmpsec L21: lda $c0ec bpl L21 and tmpsec dey bne L19 rts ;===================== ; Stepper motor delay ;===================== stepdelay: stx TEMPX ; was **phx** and #3 rol tax lda $c0e0, x lda TEMPX ; was **pla** L22: ldx #$13 L23: dex bne L23 sec sbc #1 ; was **dec** bne L22 seekret: rts ;================ ; SEEK ;================ seek: asl curtrk lda #0 sta step ; *** WAS *** stz step asl phase copy_cur: lda curtrk sta tmptrk sec sbc phase beq seekret bcs L24 eor #$ff inc curtrk bcc L25 L24: sec sbc #1 ; *** WAS *** dec dec curtrk L25: cmp step bcc L26 lda step L26: cmp #8 bcs L27 tay sec L27: lda curtrk ldx step1, y jsr stepdelay lda tmptrk ldx step2, y jsr stepdelay inc step bne copy_cur step1: .byte $01, $30, $28, $24, $20, $1e, $1d, $1c step2: .byte $70, $2c, $26, $22, $1f, $1e, $1d, $1c sectbl: .byte 0, $0d, $0b, 9, 7, 5, 3, 1, $0e, $0c, $0a, 8, 6, 4, 2, $0f codeend = * nibtbl = * bit2tbl = nibtbl+128 filbuf = bit2tbl+86 dataend = filbuf+4 ;hack to error out when code is too large for current address ;!if ((dirbuf-(dataend-opendir))&$ff00)