/**************************************************************************** OS/A65 Version 2.1.0 Multitasking Operating System for 6502 Computers Copyright (C) 1989-1998 Andre Fachat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ****************************************************************************/ /* * cluster handling * * exports: * clrclus * snext * cl2sec * gfrebyt * gfrecl * gnexcl * snexcl */ .( &clrclus .( ldy fpuffer jsr CLBUF bcs cce ldy #D_SPC+1 lda (dzei),y tax dey lda (dzei),y ldy #F_FSEC sta (fzei),y iny txa sta (fzei),y wl ldy #F_FSEC sec lda (fzei),y sbc #1 tax iny lda (fzei),y sbc #0 bcc cce sta (fzei),y dey txa sta (fzei),y jsr cl2sec bcs cce ldy fpuffer jsr W2BUF ; gets pars from ar2 bcc wl cce rts .) &snext .( ldy #F_FSEC lda (fzei),y clc adc #1 sta (fzei),y iny tax sta ar1 lda (fzei),y adc #0 sta (fzei),y sta ar1+1 ldy #F_FCL lda (fzei),y iny ora (fzei),y bne snok lda ar1+1 ; bei Cluster =0 ldy #D_SPD+1 ; nicht �ber Main-Dir lesen cmp (dzei),y bcc nexend bne nexerr txa dey cmp (dzei),y bcc nexend nexerr lda #E_NOCLUS rts snok lda ar1+1 ldy #D_SPC+1 cmp (dzei),y bcc nexend bne next dey txa cmp (dzei),y bcc nexend next jsr xclrfsec ldy #F_FCL+1 lda (fzei),y tax dey lda (fzei),y jsr gnexcl bcs nexrts ldy #F_FCL sta (fzei),y iny txa sta (fzei),y nexend clc nexrts rts .) &cl2sec .( /* berechnet Sektor aus fpb-Daten -> a/x */ ldy #F_FCL+1 lda (fzei),y tax dey lda (fzei),y bne cd cpx #0 bne cd /* hier bei Main-Directory */ ldy #F_FSEC+1 lda (fzei),y tax dey lda (fzei),y clc ldy #D_STD adc (dzei),y pha iny txa adc (dzei),y txa pla sta ar2 stx ar2+1 ldy #0 sty ar2+2 sty ar2+3 clc rts cd sec /* hier bei normalen Files */ sbc #2 sta ar1 txa sbc #0 sta ar1+1 bcs cdok cerr sec lda #E_ILLCLUS rts cdok lda #0 sta ar1+2 sta ar1+3 ldy #D_SPC+1 lda (dzei),y tax dey lda (dzei),y jsr mult32 bcs cerr ldy #F_FSEC ; sector in cluster adc (fzei),y sta ar2 iny txa adc (fzei),y sta ar2+1 bcc cdo1 inc ar2+2 bne cdo1 inc ar2+3 cdo1 clc ldy #D_STC ; sector of first cluster lda (dzei),y adc ar2 sta ar2 iny lda (dzei),y adc ar2+1 sta ar2+1 bcc cdo2 inc ar2+2 bne cdo2 inc ar2+3 cdo2 lda ar2+3 ; we only handle 24 bit sector numbers bne cerr clc rts .) .data fr1 .word 0 ; cluster fr2 .word 0 ; sektor fr3 .word 0 ; pos im sec fr4 .word 0 ; gesuchter Cluster fr5 .word 0 ; Startcluster bei suchschleife fr6 .word 0 ; Anzahl freier Cluster .zero fatzei .word 0 .text &gfrebyt .( lda #2 ldx #0 stx fr6 ; Z�hler f�r freie Cluster stx fr6+1 sta fr5 ; Cluster, bis zu dem gesucht wird stx fr5+1 sta fr1 ; Cluster, ab dem gesucht wird stx fr1+1 gfl lda fr1 ldx fr1+1 jsr gld ; sucht ab a/x bis fr5 bcs end inc fr6 bne gflx inc fr6+1 gflx jsr incmp ; mu� erh�ht werden, um n�chsten Cluster zu testen bne gfl ; noch nicht zuende dann weitersuchen beq gok end cmp #E_FDISKFULL beq gok sec rts gok lda fr6 sta ar1 lda fr6+1 sta ar1+1 lda #0 sta ar1+2 sta ar1+3 ldy #D_SPC+1 lda (dzei),y tax dey lda (dzei),y jsr mult4 ldy #D_BPS+1 lda (dzei),y tax dey lda (dzei),y jsr mult4 clc rts .) &gfrecl .( ; a/x =Cluster-1 ab dem gesucht wird sta fr5 stx fr5+1 sta fr1 stx fr1+1 bcc gld jsr incmp bne gld gle lda #E_FDISKFULL sec rts &gld jsr lfat bcs grts ldy #0 gl lda (fatzei),y sta fr4 jsr tstend bcs grts lda (fatzei),y sta fr4+1 ldy #D_BFLAG lda (dzei),y bne fat16 lda fr1 lsr bcc gerade lda fr4 and #$f0 ora fr4+1 beq found bne next gerade lda fr4+1 ; bei geradem Cluster gleich drei byte and #$0f ; = 2 Cluster testen ora fr4 beq found jsr incmp beq gle lda fr4+1 and #$f0 sta fr4 jsr tstend bcs grts lda (fatzei),y sta fr4+1 ora fr4 beq found bne next fat16 lda fr4 ora fr4+1 beq found next jsr incmp beq gle jsr tstend bcs grts bcc gl found lda fr1 ldx fr1+1 clc grts rts .) #ifdef SHOWC clushow .( lda fr1+1 jsr HEXOUT lda fr1 jsr HEXOUT lda #":" jsr SEROUT lda fr4+1 jsr HEXOUT lda fr4 jsr HEXOUT lda #"@" jsr SEROUT lda fatzei+1 jsr HEXOUT lda fatzei jsr HEXOUT lda #"," jsr SEROUT txa jsr HEXOUT jsr CRLFOUT rts .) #endif incmp .( inc fr1 bne g1 inc fr1+1 g1 lda fr1+1 ldy #D_CLUS+1 cmp (dzei),y bcc gok bne g0 dey lda fr1 cmp (dzei),y bcc gok g0 lda #0 sta fr1+1 lda #2 sta fr1 gok lda fr1 ldx fr1+1 cpx fr5+1 bne glr cmp fr5 glr rts .) &gnexcl .( jsr lfat bcs fcerr ldy #0 lda (fatzei),y sta fr4 jsr tstend bcs fcerr lda (fatzei),y sta fr4+1 ldy #D_BFLAG lda (dzei),y bne no12 lda fr1 lsr bcc noshft lda fr4+1 lsr ror fr4 lsr ror fr4 lsr ror fr4 lsr ror fr4 sta fr4+1 noshft lda fr4+1 and #$0f sta fr4+1 and #%00001000 ; Minus-Bit beq no12 lda fr4+1 ora #$f0 sta fr4+1 no12 ldy #D_CLUS+1 lda fr4+1 cmp (dzei),y bcc test2 bne eof lda fr4 dey cmp (dzei),y bcs eof test2 lda fr4 ldx fr4+1 bne ok cmp #2 bcc illclus ok clc fcerr rts eof lda fr4 cmp #$ff bne illclus cmp fr4+1 beq nocl illclus lda #E_ILLCLUS .byt $2c nocl lda #E_NOCLUS sec rts .) &snexcl .( ; a/x=cluster-Nr, y=zeiger auf zu setzenden Wert in ZP pha lda 0,y sta fr4 lda 1,y sta fr4+1 pla jsr lfat bcs fcerr ldy #D_BFLAG lda (dzei),y bne s1 lda fr4+1 and #$0f sta fr4+1 lda fr1 lsr bcc s1 lda fr4 asl rol fr4+1 asl rol fr4+1 asl rol fr4+1 asl rol fr4+1 sta fr4 ldy #0 lda (fatzei),y and #$0f ora fr4 sta fr4 s1 ldy #0 lda fr4 sta (fatzei),y ldy drive jsr MDBUF jsr tstend bcs fcerr ldy #D_BFLAG lda (dzei),y bne s2 lda fr1 lsr bcs s2 ldy #0 lda (fatzei),y and #$f0 ora fr4+1 sta fr4+1 s2 ldy #0 lda fr4+1 sta (fatzei),y ldy drive jsr MDBUF clc fcerr rts .) tstend .( inc fr3 ; increment Zeiger in FAT bne t1 inc fr3+1 t1 inc fatzei bne t2 inc fatzei+1 t2 lda fr3+1 ldx fr3 jsr xcmpfpos ; ist Ende des Puffers ? bcc fok ; nein inc fr2 bne f2 inc fr2+1 f2 lda fr2 ldx fr2+1 jsr RDFAT bcs fcerr ldx drive jsr setpadr sta fatzei stx fatzei+1 ldy #0 sty fr3 sty fr3+1 fok ldy #0 clc fcerr rts .) lfat .( sta fr1 stx fr1+1 ldy #D_CLUS+1 txa cmp (dzei),y bcc lok bne lerr lda fr1 dey cmp (dzei),y bcc lok lerr lda #E_ILLPAR rts lok ldy #D_BFLAG lda (dzei),y and #1 beq fat12 lda fr1 asl sta ar1 txa rol jmp f1 fat12 lda fr1 sta fr2 stx fr2+1 lsr fr2+1 ror fr2 clc adc fr2 sta ar1 txa adc fr2+1 f1 sta ar1+1 lda #0 sta ar1+2 sta ar1+3 ldy #D_BPS+1 lda (dzei),y tax dey lda (dzei),y jsr div32 bcc fx lda #E_ILLPAR sec rts fx sta fr2 ; Sektor in der FAT stx fr2+1 ldy ar1 ; Position im Block sty fr3 ldy ar1+1 sty fr3+1 jsr RDFAT ; l�dt FAT-Block Nr a/x bcs fcerrx ldx drive jsr setpadr clc adc fr3 sta fatzei txa adc fr3+1 sta fatzei+1 clc fcerrx rts .) RDFAT .( ldy #D_STF clc adc (dzei),y sta ar2 iny txa adc (dzei),y sta ar2+1 lda #0 sta ar2+2 sta ar2+3 ldy drive jmp RDBUF .) mult4 .( /* a/x * ar1(4 Byte) -> ar1 (4 Byte) */ clc sta ar3 stx ar3+1 lda #0 sta ar2 sta ar2+1 sta ar2+2 sta ar2+3 txa ora ar3 beq mend mloop lsr ar3+1 ror ar3 bcc mnext clc lda ar1 adc ar2 sta ar2 lda ar1+1 adc ar2+1 sta ar2+1 lda ar1+2 adc ar2+2 sta ar2+2 lda ar1+3 adc ar2+3 sta ar2+3 bcs mend mnext lda ar3 ora ar3+1 beq mend asl ar1 rol ar1+1 rol ar1+2 rol ar1+3 bcc mloop mend lda ar2 sta ar1 lda ar2+1 sta ar1+1 lda ar2+2 sta ar1+2 lda ar2+3 sta ar1+3 rts .) .)