Newer
Older
uBix-Retro / dump / oa-2.0.9 / sysapps / fs / fsibm / cmd.a65
/****************************************************************************
   
    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.

****************************************************************************/

/*
 * exports "rename", "rmdir", "delete", "mkdir"
 * "dloop", "setfile", "xclrfzei", "sfclus"
 * "findfile", "fextend", "format"
 */

          .(
	.data
cluster   .word 0
pcl       .word 0
	.zero
ezei      .word 0
	.text

&rename   .(
          jsr inidrv
          bcs re
          ldy #FS_CMD_NAME
          lda #ATTR_CLSD|ATTR_DIR
          ldx #0
          jsr findfile   ; bei gefunden sind ezei,DCL/DSEC/DPOS gesetzt
          bcs re
          stx fname+NAME_A
          iny
          jsr fil2nam
          
          ldy #F_FCL
          lda pcl
          sta (fzei),y
          iny
          lda pcl+1
          sta (fzei),y
          
          ldx #<-1
          jsr findentry
          bcc fexist
          cmp #E_NOCLUS
          bne re
          
          jsr d2f
          jsr cl2sec
          bcs re
          ldy fpuffer
          jsr RDBUF
          bcs re
          jsr xadbufpos
          sta ezei
          stx ezei+1
          
          jsr ynam2ezei
          bcs err
          ldy fpuffer
          jsr WABUF          
re        jmp xfrebuf
fexist    lda #E_FILEXIST
err       sec
          jmp xfrebuf
          .)

&rmdir    .(
          jsr inidrv
          bcs re
          ldy #FS_CMD_NAME
          lda #ATTR_DIR
          ldx #0
          jsr findfile
          bcs re
          lda #"*"
          sta fname+NAME_N
          sta fname+NAME_E
          lda #ATTR_DIR|ATTR_CLSD|ATTR_HID|ATTR_SYS
          sta fname+NAME_A
          ldx #<-1
          jsr findentry
          bcc rtest
          .byt $2c
notempty  lda #E_FDNEMPTY
          sec
re        jmp xfrebuf
rloop     jsr findnext
          bcs rend
rtest     ldy #DE_ATTR
          lda (ezei),y
          and #ATTR_DIR
          beq notempty
          ldy #DE_NAME
          lda (ezei),y
          cmp #"."
          bne notempty
          iny
          lda (ezei),y
          cmp #"."
          bne r2
          iny
r2        lda (ezei),y
          cmp #" "
          bne notempty
          iny
          cpy #DE_ATTR
          bcc r2
          bcs rloop
          
rend      cmp #E_NOCLUS
          bne re
          jsr d2f
          jsr xfcl2fscl
          jsr cl2sec
          bcs re
          ldy fpuffer
          jsr RDBUF
          bcs re
          jsr xadbufpos
          sta ezei
          stx ezei+1
          jmp xdel
          .)
          
&delete   .(
	.data
xfl       .byt 0
	.text

          jsr inidrv
          bcs de
          ldy #FS_CMD_NAME
          lda #ATTR_CLSD
          ldx #0
          jsr findfile
          bcs de
          ldx #1
          .byt $2c
&xdel     ldx #0
          stx xfl
dl        sec
          jsr tstlocked
          bcs de
          ldy #DE_NAME
          lda #$e5            ; null ist auf dem PC Endekennzeichen f�r dir
          sta (ezei),y
          ldy fpuffer
          jsr MDBUF
          ldy #DE_FCLUS+1
          lda (ezei),y
          tax
          dey
          lda (ezei),y
          jsr dloop
          bcs endex
          ldx xfl
          beq ende2
          jsr d2f
          jsr findnext
          bcc dl
          cmp #E_NOCLUS
          bne de
ende2     clc
endex     php
          pha
          ldy fpuffer
          jsr WABUF
          bcs dexx
          ldy drive
          jsr DWBUF
          bcs dexx
          pla
          plp
          jmp xfrebuf
dexx      tax
          pla
          txa
          plp
de        sec
          jmp xfrebuf

	.zero
xzei      .word 0
	.text

&&dloop   sta cluster
          stx cluster+1
          ldy #0
          sty xzei
          sty xzei+1
          jsr gnexcl
          bcs dend
          sta pcl
          stx pcl+1
          lda cluster
          ldx cluster+1
          ldy #xzei
          jsr snexcl
          bcs de
          lda pcl
          ldx pcl+1
          jmp dloop
dend      cmp #E_NOCLUS
          bne de
          lda cluster
          ldx cluster+1
          ldy #xzei
          jmp snexcl
          .)
          
&mkdir    .(
          jsr inidrv
          bcs err
          ldy #FS_CMD_NAME
          lda #ATTR_DIR
          jsr setfile
          bcs err
          jsr clrclus
          bcs err
          jsr cl2sec
          bcs err
          ldy fpuffer
          jsr RDBUF
          bcs err
          ldx fpuffer
          jsr setpadr
          sta ezei
          stx ezei+1
          lda #" "
          ldy #1
m1        sta fname,y
          iny
          cpy #NAME_A
          bcc m1
          lda #"."
          sta fname+NAME_N
          lda #ATTR_DIR
          sta fname+NAME_A
          jsr xnam2ezei
          ldy #DE_FCLUS
          lda cluster
          sta (ezei),y
          iny
          lda cluster+1
          sta (ezei),y
          lda #"."
          sta fname+NAME_N+1
          lda #DE_SLEN
          clc
          adc ezei
          sta ezei
          bcc m2
          inc ezei+1
m2        jsr xnam2ezei
          ldy #DE_FCLUS
          lda pcl
          sta (ezei),y
          iny
          lda pcl+1
          sta (ezei),y
          ldy fpuffer
          jsr WABUF
err       jmp xfrebuf
          .)

&setfile  .(      ; open new file, a=attr, y=pointer to Name in PCBUF-1
          ldx #1
          jsr findfile
          bcs sok
          lda #E_FILEXIST
errx      sec
          rts
sok       cmp #E_OK
          bne errx
          jsr d2f        ; DCL,DSEC,DPOS nach FCL,FSEC,FPOS = Leerer Eintrag
          jsr sfclus     ; freien Cluster suchen, belegen und nach a/x bzw cluster
          bcs errx
          jsr cl2sec     ; FCL,FSEC nach a/x=Sektor-Nummer umrechnen
          bcs errx
          ldy fpuffer
          jsr RDBUF      ; und Sektor lesen
          bcs errx
          jsr xadbufpos  ; FPOS+Puffer-Adresse nach a/x
          sta ezei
          stx ezei+1
          ldy #DE_FCLUS  ; Cluster speichern im Dir-Eintrag
          lda cluster
          sta (ezei),y
          iny
          lda cluster+1
          sta (ezei),y
          ldy #DE_SIZE   ; L„nge auf Null setzen im Dir-Eintrag
          lda #0
          sta (ezei),y
          iny
          sta (ezei),y
          iny
          sta (ezei),y
          iny
          sta (ezei),y
          jsr nam2ezei   ; Name in Dir-Eintrag
          bcs err

          ldy fpuffer    ; Puffer speichern 
          jsr WABUF
          bcs err
          ldy drive      ; f�rs Drive die FAT sichern 
          jsr DWBUF
          bcs err

          ldy #F_FCL     ; Startcluster als File-Start setzen
          lda cluster
          sta (fzei),y
          iny
          lda cluster+1
          sta (fzei),y

          jsr xfcl2fscl  ; und als Startcluster des Files setzen (f�r Lock)

          jsr xclrfsp    ; FSEC,FPOS l”schen
          lda #0
          ldy #F_LEN     ; Dateil„nge im FPB auf Null setzen
          sta (fzei),y
          iny
          sta (fzei),y
          iny
          sta (fzei),y
          iny
          sta (fzei),y
&&xclrfzei
          ldy #F_FZEI    ; Set pointer for read/write to null
          lda #0
          sta (fzei),y
          iny
          sta (fzei),y
          iny
          sta (fzei),y
          iny
          sta (fzei),y
          clc
err       rts

;free      ldy #DE_NAME
;          lda #0
;          sta (ezei),y
;          lda #E_DISKFULL
;          sec
;          rts
          .)

&sfclus   .(
#ifdef SHOWC
     lda #"+"
     jsr SEROUT
#endif
          lda #2
          ldx #0
          clc
          jsr gfrecl     ; ab Cluster 1 nach freiem Cluster suchen 
          bcs errx
          sta cluster
          stx cluster+1
          ldy #<EOFCLUS
          sty ezei
          ldy #>EOFCLUS
          sty ezei+1
          ldy #ezei
          jsr snexcl     ; neuer Cluster kriegt End of File als Folgecluster
          bcs errx
#ifdef SHOWC
     lda cluster+1
     jsr HEXOUT
     lda cluster 
     jsr HEXOUT
     clc
#endif
          lda cluster
          ldx cluster+1
errx      rts
          .)

          .(
namend    lda #E_FILLNAM
          sec
          rts          
&nam2ezei 
          ldx #1
          .byt $2c
&xnam2ezei
          ldx #0
          .byt $2c
&ynam2ezei
          ldx #<-1
          ldy #0
md1       lda fname,y
          sta (ezei),y
          cmp #"*"
          beq namend
          cmp #"?"
          beq namend
          cmp #34
          beq namend
          cmp #"."
          bne md1x
          txa
          bne namend
md1x      iny
          cpy #NAME_SLEN
          bcc md1
          txa
          bpl cendx
          clc
          rts
cendx     lda #0
          ldy #DE_SIZE
md2       sta (ezei),y
          iny
          cpy #DE_SIZE+4
          bcc md2

          lda #0
          ldy #5
c1        sta PCBUF,y
          dey
          bpl c1
          ldy #1         ; minimale Anzahl Bytes
          lda #TI_GET
          ldx #SEND_TIME
          jsr SEND
          bcs cnd        ; x-reg ist noch vom Send gesetzt 
          sec
          jsr XRECEIVE
cnd       
          ; Umwandlung 6 Byte in 4 Byte und dann nach (ezei),DE_TIME/DATE   

          lda PCBUF+TE_SG_YEAR
          sec
          sbc #80
          and #%01111111
          asl
          sta ar1
          lda PCBUF+TE_SG_MONTH
          and #%00001000
          lsr
          lsr
          lsr
          ora ar1
          ldy #DE_DATE+1
          sta (ezei),y
          lda PCBUF+TE_SG_MONTH
          and #%00000111 
          asl
          asl
          asl
          asl
          asl
          sta ar1
          lda PCBUF+TE_SG_DAY
          and #%00011111
          ora ar1
          ldy #DE_DATE
          sta (ezei),y
          
          lda PCBUF+TE_SG_HOUR
          and #%00011111
          asl
          asl
          asl
          sta ar1
          lda PCBUF+TE_SG_MIN
          and #%00111000
          lsr
          lsr
          lsr
          ora ar1
          ldy #DE_TIME+1
          sta (ezei),y
          lda PCBUF+TE_SG_MIN
          and #%00000111 
          asl
          asl
          asl
          asl
          asl
          sta ar1
          lda PCBUF+TE_SG_SEC
          and #%00111110
          lsr
          ora ar1
          ldy #DE_TIME
          sta (ezei),y

cend      clc
          rts

          .)

&findfile .(
	.data
xflag     .byt 0
attr      .byt 0
npos      .byt 0
	.text

          sta attr  ; attribut, nach dem gesucht wird
          stx xflag ; x=0 lesen, x=1 leeren Eintrag suchen test file exist
          sty npos  ; y=position Name in PCBUF
          
          lda PCBUF,y
          cmp #DIRSIGN  ; da eh immer bei clus=0 gestartet wird, backslash
          bne l1    ; am Anfang ignorieren
          inc npos
l1
          jsr xclrfcl
          
fl        ldy npos
          lda PCBUF,y
          beq fnoname
          jsr xfil2nam
          sty npos

          ldy #F_FCL
          lda (fzei),y   
          sta pcl        ; pcl ist Startcluster des dirs
          iny
          lda (fzei),y
          sta pcl+1

          ldy npos
          lda PCBUF,y
          php
          ldx xflag
          lda attr
          plp
          beq f2
          lda #ATTR_DIR
          ldx #0
f2        sta fname+NAME_A
          jsr findentry
          bcs fe
          ldy #DE_ATTR
          lda (ezei),y
          tax
          ldy npos
          inc npos
          lda PCBUF,y
          bne fl
          clc
fe        rts 
fnoname   lda #E_FNOFIL
          sec
          rts    
          .)

findentry .(
	.data
x2fl      .byt 0
x3fl      .byt 0
	.text

          stx x2fl       ; x<0 dann nur auf exist testen, F_Dxx nicht „ndern
          stx x3fl       ; x=1 ist freien Eintrag suchen, x=0 Datei finden
          jsr xclrfsec
fnew      jsr xclrfpos
        
          jsr cl2sec
          bcs fe
          ldy fpuffer
          jsr RDBUF
          bcc f0
fe        rts
    
f0        ldx fpuffer
          jsr setpadr
          sta ezei
          stx ezei+1
          
fl        ldy #DE_NAME
          lda (ezei),y
          beq frex
          cmp #$e5
          bne fl2
          jmp fre
frex      lda x3fl
          bmi frey
          beq frey
          lda x2fl
          beq frez
          jsr f2d
frez      lda #E_OK
          .byt $2c
frey      lda #E_NOCLUS
          jmp nexend
          
fl2       lda fname+NAME_N-DE_NAME,y
          cmp #"*"
          beq namok
          cmp #"?"
          beq fl1
          cmp (ezei),y
          bne next
fl1       iny
          cpy #DE_EXT
          bcc fl2
namok     ldy #DE_EXT
fl3       lda fname+NAME_E-DE_EXT,y
          cmp #"*"
          beq extok
          cmp #"?"
          beq fl4
          cmp (ezei),y
          bne next
fl4       iny
          cpy #DE_ATTR
          bcc fl3
extok     ldy #DE_ATTR
          lda fname+NAME_A
          tax
          and (ezei),y
          bne found
          txa
          and #ATTR_CLSD
          beq next
          lda (ezei),y
          beq found
&findnext          
next      lda #DE_SLEN
          clc
          adc ezei
          sta ezei
          bcc n1
          inc ezei+1
n1        lda #DE_SLEN
          jsr xadfpos
          bcs nexsec
          jmp fl
nexsec    jsr snext           ; sucht bei FCL,FSEC
          bcc f0a
          cmp #E_NOCLUS
          bne nexend
          ldx x3fl            ; soll keinen leeren suchen
          bmi nexend
          beq nexend          ; dann E_NOCLUS
          ldx x2fl            ; soll suchen und hat gefunden 
          beq nexxend         ; dann OK und c=1
          jsr fextend 
          bcs nexend
          jsr clrclus         ; l”scht Cluster
          bcs nexend
          jsr f2d
nexxend   lda #E_OK
nexend    sec
          rts
f0a       jmp fnew
          
fre       lda x2fl
          bmi next
          beq next
          jsr f2d
          lda #0
          sta x2fl
          beq next

found     bit x2fl
          bmi fend
          jsr f2d

          ldy #DE_FCLUS+1
          lda (ezei),y
          tax
          dey
          lda (ezei),y
          ldy #F_FCL
          sta (fzei),y
          iny
          txa
          sta (fzei),y

          jsr xfcl2fscl

          ldy #DE_SIZE+1
          lda (ezei),y
          tax
          dey
          lda (ezei),y
          ldy #F_LEN
          sta (fzei),y
          iny
          txa
          sta (fzei),y
          ldy #DE_SIZE+3
          lda (ezei),y
          tax
          dey
          lda (ezei),y
          ldy #F_LEN+2
          sta (fzei),y
          iny
          txa
          sta (fzei),y

          jsr xclrfzei
          jsr xclrfpos
fend      clc
          rts
          .)

&fextend  .(             ; extend file when writing
          ldy #F_FCL+1
          lda (fzei),y
          tax
          dey
          lda (fzei),y
          bne f1
          cpx #0         ; im Main-Dir nicht m”glich 
          bne f1
          lda #E_NOCLUS
          sec
          rts
f1        jsr gnexcl     ; n„chsten Cluster der Datei suchen
          bcc fok        ; 
          cmp #E_NOCLUS
          bne ferr       ; Lese- oder sonstwas-Fehler
          ldy #F_FCL+1   
          lda (fzei),y
          tax
          dey
          lda (fzei),y
          sec
          jsr gfrecl     ; ab letztem Cluster der Datei freien Cluster suchen
          bcs ferr       ; nicht gefunden 
          sta ezei
          stx ezei+1
          ldy #F_FCL+1
          lda (fzei),y
          tax
          dey
          lda (fzei),y
          ldy #ezei
          jsr snexcl     ; und Folgecluster setzen
          bcs ferr       ; war nix
          ldy #F_FCL+1
          lda ezei+1
          sta (fzei),y
          dey
          tax
          lda ezei
          sta (fzei),y
          ldy #<EOFCLUS
          sty ezei
          ldy #>EOFCLUS  
          sty ezei+1
          ldy #ezei
          jsr snexcl     ; der neue Cluster kriegt ein End Of File als Folgecluster
          bcs ferr
          
fok       jsr xclrfsp    ; FSEC=FPOS=0
          clc
          rts
ferr      sec
          rts
          .)
          
&format   .(
          ; ldx PCBUF+FS_CMD_DRV
          ; jsr setdzei
          ldx drive
          jsr dchanged
          lda PCBUF+FS_CMD_PFAD
          ldx drive
          jsr DFORMAT
          bcs ferr3

#ifdef DEBUGFS
lda #"f":jsr SEROUT
lda drive:jsr HEXOUT
lda dzei+1:jsr HEXOUT:lda dzei:jsr HEXOUT
#endif
          ldx drive
          jsr GETDPB
          bcs ferr3
;jmp ferr2
          ldy drive
;.byt 2
          jsr CLBUF
          bcs ferr3         
          ldy #D_STC+1
          lda (dzei),y
          sta ezei+1
          dey
          lda (dzei),y
          sta ezei

#ifdef DEBUGFS
.(
lda #"c":jsr SEROUT
lda dzei+1:jsr HEXOUT
lda dzei:jsr HEXOUT
lda ezei+1:jsr HEXOUT
lda ezei:jsr HEXOUT
.)
#endif

fwl       sec
          lda ezei
          sbc #1
          sta ezei
          lda ezei+1
          sbc #0
          sta ezei+1
          ora ezei
          beq ffat

          lda ezei
          ldx ezei+1
	  sta ar2
	  stx ar2+1
	  lda #0
	  sta ar2+2
	  sta ar2+3
          ldy drive
          jsr W2BUF
ferr3     bcs ferr2
          bcc fwl

ffat      lda #<-1
          sta ezei
          sta ezei+1
          ldy #ezei
          lda #0
          tax
          jsr snexcl
          bcs ferr2
          lda #1
          ldx #0
          ldy #ezei
          jsr snexcl
          bcs ferr2
          ldy drive
          jsr CLBUF
          bcs ferr2
          sta ezei
          stx ezei+1
          ldy #FS_CMD_NAME
;.byt 2
          jsr fil2nam
          lda #ATTR_DSK
          sta fname+NAME_A
          jsr nam2ezei
          ldy #D_STD+1
          lda (dzei),y
          tax
          dey
          lda (dzei),y
	  sta ar2
	  stx ar2+1
	  lda #0
	  sta ar2+2
	  sta ar2+3
          ldy drive
          jsr W2BUF
;.byt 2
          bcs ferr2
          ldy drive
          jsr DWBUF
ferr2     rts
          .)

          .)