Newer
Older
uBix-Retro / dump / oa-2.0.9 / sysapps / fs / fsdev.a65
/****************************************************************************
   
    OS/A65 Version 2.0.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.

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


          .(
#ifdef ROM
start     .word ende		; pointer to end of file in ROM
#ifdef FSDEV_AS_INIT
          .byt  PK_INIT+$80	; file type = filesystem + auto-execute bit
#else
          .byt  PK_FS+$80	; file type = filesystem + auto-execute bit
#endif
          .word PRG		; execution start
          .byt  16		; RAM size in 256-byte blocks
	  .byt  >$ff-ROMSTART; $ff-start ; shared mem size in 256-byte blocks
	  .byt  0		; priority
          .word 0		; stdin, stdout/stderr device number
          .asc  "fsdev",0,0	; command line
#else

#include  "kdefs.i65"
#include  "kernel.i65"
#include  "fdefs.i65"

          .word $800
          *=$800
          jmp PRG

#endif

#include  "fsdef.i65"

#ifndef MAXFILE
#ifndef NOMMU
#define   MAXFILE   8
#else
#define	  MAXFILE   4		/* must be more than ANZDRV (number of
				   drives), because for each drive a buffer
				   is reserved */
#endif	/* NOMMU */
#endif	/* MAXFILE */

#define   BUFSIZE   128

#ifdef FSDEV_NOROM
#define   ANZDRV    1
#else
#define   ANZDRV    2
#endif

	.zero
fzei      .word 0
bzei      .word 0
rzei      .word 0

	.data
owntask   .byt 0
anz       .byt 0
cnt       .byt 0
cmd       .byt 0
client    .byt 0
actfil    .byt 0
dev       .byt 0
ftab      .dsb F_SLEN*MAXFILE

	.bss
buf       .dsb MAXFILE*BUFSIZE

	.text

PRG       .(
          stx owntask

          ldx #<-1
          jsr setzei     ; init setzei (actfil)
          ldx #0
          stx anz
p1        jsr setzei
          lda #F_FL_FRE
          ldy #F_FL
          sta (fzei),y
          inx
          cpx #MAXFILE
          bcc p1

	  ; we now inherit PCBUF from the FORK call (if PK_FS)
	  ; clc
	  ; ldx #SEM_SENDBUF
	  ; jsr PSEM

          lda #ANZDRV         ; 2 Drives
          sta PCBUF+FM_REG_DRVS
          lda owntask
          sta PCBUF+FM_REG_ENV
          lda #FM_REG
          ldx #SEND_FM   
          ldy #2
          jsr SEND

	  php
	  ldx #SEM_SENDBUF
	  jsr VSEM
	  plp

          bcc loopt
          jmp TERM

loopt     lda anz
          bne loop
          sec
          .byt $24
loop      clc
          jsr RECEIVE
          bcs l1
          jsr rxmess
l1        ldx #0
          stx cnt
          stx anz
l2        jsr setzei
          ldy #F_FL
          lda (fzei),y
          cmp #F_FL_FRE
          bne l2a
          jmp nextl

l2a       inc anz
          ldy #F_MODE
          lda (fzei),y
          cmp #F_MODE_RD
          bne l3

ol        ldy #F_BYT
          lda (fzei),y
          ldy #F_LEN
          cmp (fzei),y
          beq l4
          pha
          ldy #F_STR
          lda (fzei),y
          tax
          pla
          tay
          lda (bzei),y
          jsr PUTC
          bcs l5n
          ldy #F_BYT
          lda (fzei),y
          clc
          adc #1
          sta (fzei),y
          jmp ol

l4        ldy #F_FL
          lda (fzei),y
          cmp #F_FL_EOF
          bne l4a
          ldy #F_STR
          lda (fzei),y
          tax
          lda #SC_EOF
          jsr STRCMD
          jsr close
          jmp nextl
l4a       jsr clrbuf
          jsr loadbuf
          bcc l5
          ldy #F_FL
          lda #F_FL_EOF
          sta (fzei),y
l5        jmp nextl

l5n       cmp #E_NUL
          bne l5
          ldy #F_STR
          lda (fzei),y
          tax
          lda #SC_EOF
          jsr STRCMD
          jsr close

l3 nextl  
          inc cnt
          ldx cnt
          cpx #MAXFILE
          bcs endloop
          jmp l2
endloop   jsr YIELD
          jmp loopt
          .)

rxmess    .(
          stx client
          cmp #FS_OPEN_DR
          bne rx1
          jsr getfre
          bcs rxe1a
          jsr clrbuf
          lda #F_FL_DIR
oprrx     ldy #F_FL
          sta (fzei),y
          lda PCBUF+FS_OPEN_STR
          ldy #F_STR
          sta (fzei),y
          ldy #F_MODE
          lda #F_MODE_RD
          sta (fzei),y
          lda #<-1
          ldy #F_DEV
          sta (fzei),y
          lda PCBUF+FS_OPEN_DRV
          ldy #F_DRV
          sta (fzei),y
          ldy #F_STR
          lda (fzei),y
          tay
          jmp rxok

#ifndef FSDEV_NOROM
oprrom    jsr findrnam
          bcs rxe1a
          jsr getfre
          bcs rxe1a
          jsr clrbuf
          jsr ldrombuf
          lda #F_FL_EOF
          jmp oprrx
#endif

rx1       cmp #FS_OPEN_RD
          bne rx2

#ifndef FSDEV_NOROM
          lda PCBUF+FS_OPEN_DRV
          beq oprdev
          jmp oprrom
#endif

oprdev    lda PCBUF+FS_OPEN_STR         /* Stream vom Open sichern      */
          sta cnt
          ldx #0
          ldy #FS_OPEN_NAME
rxw1      lda PCBUF,y                   /* Name vom Open in PCBUF       */
          sta PCBUF,x                   /* fuer DC_GNUM kopieren        */
          inx
          iny
          cmp #0
          bne rxw1
          lda #DC_GNUM                  /* Die Device-Nummer zu dem     */
          jsr DEVCMD                    /* Namen holen                  */
rxe1a     bcs rxe1                      /* Fehler dann Ende             */
          stx dev                       /* Device-Nummer speichern      */
          ldy cnt                       /* Stream als                   */
          lda #DC_PS                    /* Ausgabe des Devices          */
          jsr DEVCMD                    /* registrieren                 */
          bcs rxe1                      /* Fehler dann Ende             */
          ldx dev                       /* Device-Nummer zur�ckholen    */
          lda #DC_RX_ON                 /* šbertragung starten          */
          jsr DEVCMD                    /* und los...                   */
          bcs rxe1                      /* Fehler dann Ende             */
          ldy cnt                       /* hier geht's normal weiter    */
          jmp rxok

rx2       cmp #FS_OPEN_OW
          beq rx2a
          cmp #FS_OPEN_WR
          bne rx3
rx2a      
#ifndef FSDEV_NOROM
	  lda PCBUF+FS_OPEN_DRV
          beq opwdev
          jmp opwrom
#endif

opwdev    lda PCBUF+FS_OPEN_STR
          sta cnt
          ldx #0
          ldy #FS_OPEN_NAME
rxr1      lda PCBUF,y
          sta PCBUF,x
          inx
          iny
          cmp #0
          bne rxr1
          lda #DC_GNUM
          jsr DEVCMD
          bcs rxe1
          stx dev
          ldy cnt
          lda #DC_GS
          jsr DEVCMD
          bcs rxe1
          ldx dev
          lda #DC_TX_ON
          jsr DEVCMD
          bcs rxe1
          ldy cnt
          jmp rxok

#ifndef FSDEV_NOROM
opwrom    lda #E_FWPROT
          .byt $2c
#endif
rx3       lda #E_NOTIMP
          .byt $2c
rxok      lda #E_OK
          .byt $2c
rxe1      lda #E_FNOFIL
          sta PCBUF+FS_X_ERR
          ldx owntask
          stx PCBUF+FS_X_ENV
          ldy actfil
          sty PCBUF+FS_X_FIL
          ldy #FS_X_SLEN
          ldx client
          jmp SEND
          .)

loadbuf   .(
          ldy #F_DEV
          lda (fzei),y
          bpl ldr0
          jmp loadirnam

ldr0      
	clc
	ldx #SEM_SENDBUF
	jsr PSEM

	  ldy #F_DRV
          lda (fzei),y
          beq lddev

          ldy #F_DEV
          lda (fzei),y
          jsr setrzei
          bcs lde             ; rzei zeigt auf verkettungszeiger
          ldy #P_NAME+1
; ldr3      iny                 ; deshalb hier zwei mehr
;           iny
;           lda (rzei),y
;           bpl ldr3            ; ende der Tabelle feststellen
          ldx #<-1
ldr4      inx
          iny
          lda (rzei),y
          sta PCBUF,x
          bne ldr4
          beq ldr5
          
lddev     ldy #F_DEV
          lda (fzei),y
          tax
          lda #DC_GNAM
          jsr DEVCMD
          bcs lde
ldr5      ldx #0
          ldy #FS_DIR_NAME
ld1       lda PCBUF,x
          sta (bzei),y
          inx
          iny
          cmp #0
          bne ld1
          tya

	pha
	ldx #SEM_SENDBUF
	jsr VSEM
	pla

          ldy #F_LEN
          sta (fzei),y
          lda #0
          ldy #FS_DIR_LEN
ld2       sta (bzei),y
          iny
          cpy #FS_DIR_MODE
          bcc ld2
          lda #FS_DIR_MOD_FIL
          sta (bzei),y
          ldy #F_DEV
          lda (fzei),y
          clc
          adc #1
          sta (fzei),y
          clc
          rts

lde   
	ldx #SEM_SENDBUF
	jsr VSEM
    	  ldy #0
lde1      lda ldet,y
          sta (bzei),y
          iny
          cpy #FS_DIR_NAME+1
          bcc lde1
          tya
          ldy #F_LEN
          sta (fzei),y
          sec
          rts
          
ldet      .word 0,0
          .byt 0,0,0,0,0,0,FS_DIR_MOD_FRE,0
          
loadirnam 
#ifndef FSDEV_NOROM
	  ldy #F_DRV
          lda (fzei),y
          bne romnam
#endif
          lda #<devtxt
          ldy #>devtxt
#ifndef FSDEV_NOROM
          bne dn1
romnam    lda #<romtxt
          ldy #>romtxt
#endif
dn1       sta rzei
          sty rzei+1
          ldy #0
dn2       lda (rzei),y
          sta (bzei),y
          iny
          cpy #FS_DIR_NAME
          bcc dn2
dn3       lda (rzei),y
          sta (bzei),y
          iny
          cmp #0
          bne dn3
          tya
          ldy #F_LEN
          sta (fzei),y
          lda #0
          ldy #F_DEV
          sta (fzei),y
          clc
          rts

#ifndef FSDEV_NOROM
romtxt    .word 0,0      ; len
          .byt  90,8,23
          .byt  9,33,0
          .byt  FS_DIR_MOD_NAM
          .asc "romdisk",0
#endif

devtxt    .word 0,0
          .byt 90,8,23
          .byt 9,33,0
          .byt FS_DIR_MOD_NAM
          .asc "devices",0

          .)

close     lda #F_FL_FRE
          ldy #F_FL
          sta (fzei),y
          rts

getfre    .(
          ldx #ANZDRV
          stx cnt
gf1       jsr setzei
          ldy #F_FL
          lda (fzei),y
          cmp #F_FL_FRE  
          clc
          beq gf2
          inc cnt
          ldx cnt
          cpx #MAXFILE
          bcc gf1
gf2       rts
          .)
     
clrbuf    lda #0
          ldy #F_LEN
          sta (fzei),y
          ldy #F_BYT
          sta (fzei),y
          rts
    
setzei    .(             ; setzt zeiger, x=filenr
          cpx actfil
          beq sz1
          stx actfil
          txa
          asl
          asl
          asl
          clc
          adc #<ftab
          sta fzei
          lda #>ftab
          adc #0
          sta fzei+1
          txa
#if 1
	  lsr
	  pha
	  lda #0
	  ror		; clears carry
	  adc #<buf
	  sta bzei
	  pla
	  adc #>buf
	  sta bzei+1
#else
          clc
          adc #>buf*2
          lsr
          sta bzei+1
          lda #<buf*2
          ror
          sta bzei
#endif
sz1       rts
          .)

setrzei   .(
          sta cmd
          ldx #<ROMSTART
          lda #>ROMSTART
ldr1      stx rzei
          sta rzei+1
          ldy #1
          lda (rzei),y
          dey
          and (rzei),y
          tax
          inx
          sec
          beq lde        ; dann Verkettungszeiger =-1
          lda cmd
          clc
          beq lde
          dec cmd
          lda (rzei),y
          tax
          iny
          lda (rzei),y
          jmp ldr1
lde       rts
          .)

#ifndef FSDEV_NOROM
findrnam  .(
          lda #<ROMSTART
          ldx #>ROMSTART
fn1       sta rzei
          stx rzei+1
          ldy #1
          lda (rzei),y
          dey
          and (rzei),y
          tay
          iny
          beq fns
          ldy #P_NAME+1
; fn2       iny
;           iny
;           lda (rzei),y
;           bpl fn2             ; ende der Tabelle ?
          ldx #<-1
fn3       iny
          inx
          lda (rzei),y
          cmp PCBUF+FS_OPEN_NAME,x
          bne fnnxt
          cmp #0
          bne fn3
          clc
          rts
fnnxt     ldy #1
          lda (rzei),y
          tax
          dey
          lda (rzei),y
          jmp fn1
fns       sec
          rts
          .)

ldrombuf  .(
          lda #0
          tay
          sta (bzei),y
          iny
          sta (bzei),y
          iny
lr1       lda (rzei),y
          sta (bzei),y
          iny
          cpy #P_NAME+2
          bcc lr1
; lr2       lda (rzei),y
;           sta (bzei),y
;           iny
;           cmp #128            ; Ende der Tabelle bei <0
;           bcs lre
;           lda (rzei),y
;           sta (bzei),y
;           iny
;           bne lr2
lre       tya
          ldy #F_LEN
          sta (fzei),y
          rts
          .)
#endif

#undef ANZDRV
#undef BUFSIZE
#undef MAXFILE

ende      .)