;HRTmon Amiga system monitor ;Copyright (C) 1991-1998 Alain Malek Alain.Malek@cryogen.com ; ;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 can find the full GNU GPL online at: http://www.gnu.org ;file access routines ;----------------------------------------------------- ;-------------- can open max 2 files ----------------- ;-> d1=ptr on filename (ended by a zero) ;-> d2=mode 0=oldfile,-1=newfile,1=oldfile or olddir (used to delete a dir) ;<- d0=ptr on file_handle open_file movem.l d1-d7/a0-a4,-(a7) st disk_op move.l d2,d7 ;copy mode in d7 move.l d1,d6 ;copy of full filename* in d6 lea.l file_handle1,a1 tst.l (a1) beq.b .okfree lea.l file_handle2,a1 tst.l (a1) beq.b .okfree moveq #0,d0 bra.w .error .okfree bsr find_partition tst.l d0 beq.w .error move.l d0,a3 move.l d0,file_part(a1) move.l d2,file_parent(a1) clr.l file_seek(a1) clr.l file_extpos(a1) sf file_written(a1) sf file_dir(a1) bsr copy_name ;set BCPL name into filehandle move.l part_device(a3),a2 lea.l extension,a0 move.l file_parent(a1),d0 move.l d0,d3 bsr read_fbuffer ;read ROOT or PARENT bsr test_sum beq.b .oksum moveq #0,d0 bra.w .error .oksum tst.l d7 ;oldfile or newfile ? bpl.w .oldfile ;-------------- open new file -------------- clr.l file_size(a1) bsr alloc_block ;find block for file_header bpl.b .okhead move.w #DISKFULL_ERR,drive_err moveq #0,d0 bra.w .error .okhead move.l d0,file_header(a1) move.l d0,file_extension(a1) bsr calc_hash move.l d3,d6 ;d6=place where to ins. in hash sf d5 ;signal for d6 found .next2 lea.l extension,a0 move.l (a0,d0.w),d0 ;find end of hash list beq.b .okfreeh tst.b d5 ;already found place where bne.b .foundins ;to insert in hash list ? cmp.l file_header(a1),d0 bls.b .foundins st d5 move.l d3,d6 ;d6=place where to ins. in hash .foundins move.l d0,d3 ;d3=no of actual loaded block bsr read_fbuffer ;read next in hash list bsr test_sum beq.b .oksum2 move.l file_header(a1),d0 bsr free_block bsr update_bitmap moveq #0,d0 bra.w .error .oksum2 lea.l 108*4(a0),a0 bsr cmp_filename ;file already exists ? bne.b .different move.l file_header(a1),d0 bsr free_block bsr update_bitmap move.w #FILEEXIST_ERR,drive_err moveq #0,d0 bra.w .error .different move.w #124*4,d0 bra.b .next2 .okfreeh tst.b d5 beq.b .loaded cmp.l d3,d6 ;block already loaded ? beq.b .loaded move.l d6,d0 move.l d0,d3 bsr read_fbuffer .loaded cmp.l #1,127*4(a0) ;ROOT ? beq.b .puthash move.l 1*4(a0),d0 cmp.l file_parent(a1),d0 ;is it the PARENT bne.b .putlist .puthash bsr calc_hash move.l (a0,d0.w),d6 ;next in hash list move.l file_header(a1),(a0,d0.w) bra.b .savesec .putlist move.l 124*4(a0),d6 ;next in hash list move.l file_header(a1),124*4(a0) .savesec lea.l extension,a0 bsr calc_sum move.l d3,d0 bsr write_fbuffer ;write back the block ;containing the ref to the file ;-------------- init the file header -- lea.l secbuf,a4 moveq #128-1,d0 .clr clr.l (a4)+ ;clear whole block dbf d0,.clr lea.l secbuf,a0 move.l #2,(a0) ;Type 2 (T.SHORT) move.l file_header(a1),1*4(a0) ;Header Key lea.l 108*4(a0),a4 lea.l file_name(a1),a0 moveq #8-1,d0 .copy_name move.l (a0)+,(a4)+ ;copy filename dbf d0,.copy_name lea.l secbuf,a0 move.l file_parent(a1),125*4(a0) ;parent move.l #-3,127*4(a0) ;sec.type (File-header) move.l d6,124*4(a0) ;next in hash list bsr calc_sum move.l file_header(a1),d0 bsr write_fbuffer ;write new file header block bsr update_bitmap bra.w .okfile ;ok, return file_handle ;-------------- open old file -------------- .oldfile bsr calc_hash .next lea.l extension,a0 move.l (a0,d0.w),d0 bne.b .oknext move.w #FILENOTFOUND_ERR,drive_err moveq #0,d0 bra.b .error .oknext bsr read_fbuffer ;read next in hash list bsr test_sum beq.b .oksum3 moveq #0,d0 bra.b .error .oksum3 lea.l 108*4(a0),a0 ;filename bsr cmp_filename beq.b .found move.w #124*4,d0 bra.b .next .found lea.l extension,a0 move.l d0,file_header(a1) move.l d0,file_extension(a1) move.l 81*4(a0),file_size(a1) ;copy file_size cmp.l #-3,127*4(a0) ;is it a real file_header ? beq.b .okfile tst.l d7 ;allow to open a dir ? beq.b .nodir cmp.l #2,127*4(a0) ;is it a directory ? beq.b .okfile .nodir move.w #FILENOTFOUND_ERR,drive_err moveq #0,d0 bra.b .error .okfile move.l a1,d0 ;return file_handle .error tst.l d0 bne.b .noerr clr.l (a1) ;free file_handle .noerr movem.l (a7)+,d1-d7/a0-a4 tst.l d0 rts ;---------------------------------------------------------- ;-> d1=ptr on file_handle ;<- d0=result 0=no error -1=error close_file movem.l d1-d7/a0-a4,-(a7) tst.l d1 beq.b .endclose move.l d1,a1 move.l file_part(a1),a3 move.l part_device(a3),a2 tst.b file_written(a1) beq.b .notwritten bsr update_bitmap lea.l secbuf,a0 move.l file_header(a1),d0 bsr read_fbuffer ;read fileheader move.l file_size(a1),81*4(a0) ;update filesize tst.l 2*4(a0) ;any block present ? beq.b .noblock move.l 77*4(a0),4*4(a0) ;copy first block no .noblock bsr calc_sum bsr write_fbuffer ;write correct fileheader .notwritten bsr flush_fbuffer jsr MOTOFF_CMD(a2) clr.l (a1) ;Free file_handle .endclose moveq #0,d0 movem.l (a7)+,d1-d7/a0-a4 rts ;---------------------------------------------------------- ;-> d1=ptr on file_handle ;-> d2=ptr on buffer ;-> d3=len to read ;<- d0=result 0=ok -1=error read_file movem.l d1-d7/a0-a4,-(a7) move.l d1,a1 move.l file_part(a1),a3 move.l part_device(a3),a2 move.l file_size(a1),d4 sub.l file_seek(a1),d4 ;max val for len cmp.l d4,d3 ble.b .oklen move.l d4,d3 ;truncate len .oklen tst.l d3 beq.w .endread move.l d2,a4 .recheck move.l file_extension(a1),d0 lea.l extension,a0 bsr read_fbuffer ;read extension block bsr test_sum bne.w .endread move.l file_seek(a1),d0 sub.l file_extpos(a1),d0 cmp.l #72*512,d0 blt.b .inthisext move.l 126*4(a0),d0 ;next extension block move.l d0,file_extension(a1) add.l #72*512,file_extpos(a1) bra.b .recheck .inthisext move.l file_seek(a1),d4 sub.l file_extpos(a1),d4 moveq #9,d1 lsr.l d1,d4 ;div 512 neg.w d4 add.w #71,d4 lea.l extension,a0 lsl.w #2,d4 move.l 6*4(a0,d4.w),d0 ;first data block lsr.w #2,d4 move.l file_seek(a1),d1 and.l #$1ff,d1 ;get offset in first block lea.l secbuf,a0 bsr read_fbuffer ;read first data block move.l #512,d5 sub.l d1,d5 ;nb bytes in first block cmp.l d3,d5 bge.w .lastread ;all bytes to read in this block ? lea.l secbuf,a0 add.l d1,a0 sub.l d5,d3 add.l d5,file_seek(a1) subq.w #1,d5 .copyf move.b (a0)+,(a4)+ ;copy bytes from 1st block dbf d5,.copyf .nextdata subq.w #1,d4 ;next block bpl.b .okextension ;still in this extension ? lea.l extension,a0 move.l 126*4(a0),d0 ;next extension move.l d0,file_extension(a1) bsr read_fbuffer ;read next extension block bsr test_sum bne.b .endread moveq #71,d4 add.l #72*512,file_extpos(a1) .okextension lea.l extension,a0 lsl.w #2,d4 move.l 6*4(a0,d4.w),d0 ;next data block lsr.w #2,d4 cmp.l #512,d3 ;nb bytes to read > 1 block ? blt.b .readlast move.l a4,a0 bsr read_fbuffer ;read data block lea.l 512(a4),a4 add.l #512,file_seek(a1) sub.l #512,d3 bne.b .nextdata bra.b .endread ;no more bytes to read .readlast lea.l secbuf,a0 bsr read_fbuffer moveq #0,d1 ;offset in block=0 .lastread lea.l secbuf,a0 add.l d1,a0 add.l d3,file_seek(a1) subq.w #1,d3 .copy move.b (a0)+,(a4)+ dbf d3,.copy .endread moveq #0,d0 tst.w drive_err beq.b .noerr moveq #-1,d0 .noerr movem.l (a7)+,d1-d7/a0-a4 rts ;---------------------------------------------------------- ;-> d1=ptr on file_handle ;-> d2=ptr on buffer ;-> d3=len to write ;<- d0=result 0=ok -1=error write_file movem.l d1-d7/a0-a4,-(a7) move.l d1,a1 st file_written(a1) move.l file_part(a1),a3 move.l part_device(a3),a2 move.l file_size(a1),d0 sub.l file_seek(a1),d0 ;nb bytes till end of file cmp.l d0,d3 ble.b .noappend tst.l d0 beq.b .noover bsr overwrite ;overwrite till end of file tst.w drive_err bne.b .end add.l d0,d2 ;new buffer address sub.l d0,d3 ;nb bytes left to write .noover move.l d3,d0 bsr append ;then append bra.b .end .noappend move.l d3,d0 bsr overwrite .end bsr update_bitmap moveq #0,d0 tst.w drive_err beq.b .exit moveq #-1,d0 .exit movem.l (a7)+,d1-d7/a0-a4 rts ;-> a1=ptr on file_handle ;-> d0=nb bytes to overwrite ;-> d2=ptr on buffer ;-> a2=device ;-> a3=part overwrite movem.l d0-a4,-(a7) move.l d2,a4 move.l d0,d3 .recheck move.l file_extension(a1),d0 lea.l extension,a0 bsr read_fbuffer ;read extension block bsr test_sum bne.w .endwrite move.l file_seek(a1),d0 sub.l file_extpos(a1),d0 cmp.l #72*512,d0 blt.b .inthisext move.l 126*4(a0),d0 ;next extension block move.l d0,file_extension(a1) add.l #72*512,file_extpos(a1) bra.b .recheck .inthisext move.l file_seek(a1),d4 sub.l file_extpos(a1),d4 moveq #9,d1 lsr.l d1,d4 ;div 512 neg.w d4 add.w #71,d4 lea.l extension,a0 lsl.w #2,d4 move.l 6*4(a0,d4.w),d0 ;first data block lsr.w #2,d4 move.l file_seek(a1),d1 and.l #$1ff,d1 ;get offset in first block lea.l secbuf,a0 bsr read_fbuffer ;read first data block move.l #512,d5 sub.l d1,d5 ;nb bytes in first block cmp.l d3,d5 bge.w .lastwrite ;all bytes to write in this block ? lea.l secbuf,a0 add.l d1,a0 sub.l d5,d3 add.l d5,file_seek(a1) subq.w #1,d5 .copyf move.b (a4)+,(a0)+ ;copy bytes to 1st block dbf d5,.copyf lea.l secbuf,a0 bsr write_fbuffer ;write back first block .nextdata subq.w #1,d4 ;next block bpl.b .okextension ;still in this extension ? lea.l extension,a0 move.l 126*4(a0),d0 ;next extension move.l d0,file_extension(a1) bsr read_fbuffer ;read next extension block bsr test_sum bne.b .endwrite moveq #71,d4 add.l #72*512,file_extpos(a1) .okextension lea.l extension,a0 lsl.w #2,d4 move.l 6*4(a0,d4.w),d0 ;next data block lsr.w #2,d4 cmp.l #512,d3 ;nb bytes to write > 1 block ? blt.b .writelast move.l a4,a0 bsr write_fbuffer ;write data block lea.l 512(a4),a4 sub.l #512,d3 add.l #512,file_seek(a1) bne.b .nextdata bra.b .endwrite ;no more bytes to write .writelast lea.l secbuf,a0 bsr read_fbuffer moveq #0,d1 ;offset in block=0 .lastwrite lea.l secbuf,a0 add.l d1,a0 add.l d3,file_seek(a1) subq.w #1,d3 .copy move.b (a4)+,(a0)+ dbf d3,.copy lea.l secbuf,a0 bsr write_fbuffer ;write back last block .endwrite movem.l (a7)+,d0-a4 rts ;-> a1=ptr on file_handle ;-> d0=nb bytes to append ;-> d2=ptr on buffer ;-> a2=device ;-> a3=part append movem.l d0-a4,-(a7) move.l d2,a4 move.l d0,d3 .recheck move.l file_extension(a1),d0 lea.l extension,a0 bsr read_fbuffer ;read extension block bsr test_sum bne.w .error move.l file_seek(a1),d0 sub.l file_extpos(a1),d0 cmp.l #72*512,d0 blt.w .inthisext move.l 126*4(a0),d0 ;next extension block bne.b .okhere ;exists ? bsr alloc_block ;alloc new extension block bpl.b .okalloc bsr delete_fh move.w #DISKFULL_ERR,drive_err bra.w .error .okalloc lea.l extension,a0 move.l d0,126*4(a0) ;put in extension block list move.l d0,-(a7) bsr calc_sum move.l file_extension(a1),d0 bsr write_fbuffer ;write back extension block move.l (a7)+,d0 ;restore new extension block no lea.l extension,a0 moveq #128-1,d1 .clrex clr.l (a0)+ ;clear new extension block dbf d1,.clrex lea.l extension,a0 move.l #$10,(a0) ;T.LIST move.l d0,1*4(a0) ;header key move.l file_header(a1),125*4(a0) ;parent move.l #-3,127*4(a0) ;sec.type bsr calc_sum bsr write_fbuffer ;write back new extension block .okhere move.l d0,file_extension(a1) add.l #72*512,file_extpos(a1) bra.w .recheck .inthisext move.l file_seek(a1),d4 sub.l file_extpos(a1),d4 move.l d4,d0 moveq #9,d1 lsr.l d1,d4 ;div 512 neg.w d4 add.w #71,d4 lea.l extension,a0 and.w #$1ff,d0 ;need to alloc a new block ? beq.w .aligned lsl.w #2,d4 move.l 6*4(a0,d4.w),d0 lsr.w #2,d4 lea.l secbuf,a0 bsr read_fbuffer move.l file_seek(a1),d1 and.l #$1ff,d1 add.l d1,a0 neg.l d1 add.l #512,d1 ;nb bytes left in this block cmp.l d3,d1 ble.b .noall move.l d3,d1 .noall add.l d1,file_size(a1) add.l d1,file_seek(a1) sub.l d1,d3 bra.b .godbf .copyb move.b (a4)+,(a0)+ ;copy data in last block .godbf dbf d1,.copyb lea.l secbuf,a0 bsr write_fbuffer ;write back last block tst.l d3 beq.w .endwrite .nextwrite subq.w #1,d4 bpl.w .aligned bsr alloc_block ;get new extension block bpl.b .okalloc3 lea.l extension,a0 move.l file_extension(a1),d0 bsr calc_sum bsr write_fbuffer ;write back last extension bsr delete_fh move.w #DISKFULL_ERR,drive_err bra.w .error .okalloc3 lea.l extension,a0 move.l d0,126*4(a0) ;put in extension list move.l d0,-(a7) bsr calc_sum move.l file_extension(a1),d0 bsr write_fbuffer ;write back old extension move.l (a7)+,d0 lea.l extension,a0 moveq #128-1,d1 .clrex2 clr.l (a0)+ ;clear new extension block dbf d1,.clrex2 lea.l extension,a0 move.l #$10,(a0) ;T.LIST move.l d0,1*4(a0) ;header key move.l file_header(a1),125*4(a0) ;parent move.l #-3,127*4(a0) ;sec.type move.l d0,file_extension(a1) add.l #72*512,file_extpos(a1) bsr calc_sum bsr write_fbuffer ;write back new extension block moveq #71,d4 .aligned bsr alloc_block ;get new data block bpl.b .okalloc2 lea.l extension,a0 move.l file_extension(a1),d0 bsr calc_sum bsr write_fbuffer ;write back last extension bsr delete_fh move.w #DISKFULL_ERR,drive_err bra.w .error .okalloc2 lea.l extension,a0 addq.l #1,2*4(a0) ;1 block de plus dans la list lsl.w #2,d4 move.l d0,6*4(a0,d4.w) lsr.w #2,d4 move.l a4,a0 cmp.l #512,d3 ble.b .slow bsr write_fbuffer ;write new data block bra.b .okfast .slow bsr write_fbuffer ;write new data block .okfast move.l #512,d0 cmp.l d0,d3 ble.b .last add.l d0,a4 sub.l d0,d3 ;reduce nb bytes left to write add.l d0,file_seek(a1) add.l d0,file_size(a1) bra.w .nextwrite .last add.l d3,file_size(a1) add.l d3,file_seek(a1) lea.l extension,a0 move.l file_extension(a1),d0 bsr calc_sum bsr write_fbuffer ;write back last extension .endwrite .error movem.l (a7)+,d0-a4 rts ;---------------------------------------------------------- ;-> d1=ptr on file_handle ;-> d2=seek offset ;-> d3=mode -1=beginning, 0=current, 1=end seek_file movem.l d1-d7/a0-a4,-(a7) move.l d1,a1 tst.l d3 bpl.b .nobegin ;-------------- beginning -------- cmp.l file_seek(a1),d2 bge.b .noback move.l file_header(a1),file_extension(a1) clr.l file_extpos(a1) move.l d2,file_seek(a1) bra.b .end .noback move.l d2,file_seek(a1) bra.b .end ;-------------- current ---------- .nobegin tst.l d3 bne.b .nocurrent tst.l d2 bpl.b .okpos move.l file_header(a1),file_extension(a1) clr.l file_extpos(a1) .okpos add.l d2,file_seek(a1) bra.b .end ;-------------- end -------------- .nocurrent move.l file_size(a1),d1 sub.l d2,d1 cmp.l file_seek(a1),d1 bge.b .noback2 move.l file_header(a1),file_extension(a1) clr.l file_extpos(a1) .noback2 move.l d1,file_seek(a1) .end move.l file_seek(a1),d0 cmp.l file_size(a1),d0 ;bigger than max val ? ble.b .okmax move.l file_size(a1),file_seek(a1) .okmax tst.l file_seek(a1) ;negative ? bpl.b .okmin clr.l file_seek(a1) .okmin movem.l (a7)+,d1-d7/a0-a4 rts ;----------------------------------------------------- ;-> d1=ptr on dirname (ended by a zero) create_dir movem.l d0-d7/a0-a4,-(a7) st disk_op move.l d1,d6 ;copy of full filename* in d6 lea.l file_handle1,a1 tst.l (a1) beq.b .okfree lea.l file_handle2,a1 tst.l (a1) beq.b .okfree moveq #0,d0 bra.w .error .okfree bsr find_partition tst.l d0 beq.w .error move.l d0,a3 move.l d0,file_part(a1) move.l d2,file_parent(a1) clr.l file_seek(a1) clr.l file_extpos(a1) sf file_written(a1) bsr copy_name ;set BCPL name into filehandle move.l part_device(a3),a2 lea.l extension,a0 move.l file_parent(a1),d0 move.l d0,d3 bsr read_fbuffer ;read ROOT or DIR bsr test_sum bne.w .error clr.l file_size(a1) bsr alloc_block ;find block for dir_header bpl.b .okhead move.w #DISKFULL_ERR,drive_err moveq #0,d0 bra.w .error .okhead move.l d0,file_header(a1) move.l d0,file_extension(a1) bsr calc_hash move.l d3,d6 ;d6=place where to ins. in hash sf d5 ;signal for d6 found .next2 lea.l extension,a0 move.l (a0,d0.w),d0 ;find end of hash list beq.b .okfreeh tst.b d5 ;already found place where bne.b .foundins ;to insert in hash list ? cmp.l file_header(a1),d0 bls.b .foundins st d5 move.l d3,d6 ;d6=place where to ins. in hash .foundins move.l d0,d3 ;d3=no of actual loaded block bsr read_fbuffer ;read next in hash list bsr test_sum beq.b .oksum2 move.l file_header(a1),d0 bsr free_block bsr update_bitmap moveq #0,d0 bra.w .error .oksum2 lea.l 108*4(a0),a0 bsr cmp_filename ;file already exists ? bne.b .different move.l file_header(a1),d0 bsr free_block bsr update_bitmap move.w #FILEEXIST_ERR,drive_err moveq #0,d0 bra.w .error .different move.w #124*4,d0 bra.b .next2 .okfreeh tst.b d5 beq.b .loaded cmp.l d3,d6 ;block already loaded ? beq.b .loaded move.l d6,d0 move.l d0,d3 bsr read_fbuffer .loaded cmp.l #1,127*4(a0) ;ROOT ? beq.b .puthash move.l 1*4(a0),d0 cmp.l file_parent(a1),d0 ;is it the PARENT bne.b .putlist .puthash bsr calc_hash move.l (a0,d0.w),d6 ;next in hash list move.l file_header(a1),(a0,d0.w) bra.b .savesec .putlist move.l 124*4(a0),d6 ;next in hash list move.l file_header(a1),124*4(a0) .savesec lea.l extension,a0 bsr calc_sum move.l d3,d0 bsr write_fbuffer ;write back the block ;containing the ref to the dir ;-------------- init the dir block -- lea.l secbuf,a4 moveq #128-1,d0 .clr clr.l (a4)+ ;clear whole block dbf d0,.clr lea.l secbuf,a0 move.l #2,(a0) ;Type 2 (T.SHORT) move.l file_header(a1),1*4(a0) ;Header Key lea.l 108*4(a0),a4 lea.l file_name(a1),a0 moveq #8-1,d0 .copy_name move.l (a0)+,(a4)+ ;copy dirname dbf d0,.copy_name lea.l secbuf,a0 move.l file_parent(a1),125*4(a0) ;parent move.l #2,127*4(a0) ;sec.type (dir) move.l d6,124*4(a0) ;next in hash list bsr calc_sum move.l file_header(a1),d0 bsr write_fbuffer ;write new dir block bsr update_bitmap bsr flush_fbuffer jsr UPDATE_CMD(a2) jsr MOTOFF_CMD(a2) .error clr.l (a1) ;free file_handle movem.l (a7)+,d0-d7/a0-a4 rts ;---------------------------------------------------------- ;-------------- change current directory (CD) ------------- ;-> d1=ptr on new current path name change_dir movem.l d0-d7/a0-a4,-(a7) st disk_op move.l d1,a0 .seekend tst.b (a0)+ bne.b .seekend subq.l #2,a0 ;go on last char cmp.l d1,a0 blt.b .empty cmp.b #'/',(a0)+ beq.b .already cmp.b #':',-1(a0) ;device ? beq.b .already move.b #'/',(a0)+ .already move.b #'a',(a0)+ ;dummy filename for find partition sf (a0)+ .empty move.l d1,d6 ;copy of full filename* in d6 lea.l file_handle1,a1 tst.l (a1) beq.b .okfree lea.l file_handle2,a1 tst.l (a1) beq.b .okfree moveq #0,d0 bra.w .error .okfree bsr find_partition tst.l d0 beq.b .error movem.l d0/d2,current_dir bsr flush_fbuffer move.l d0,a3 move.l part_device(a3),a2 jsr MOTOFF_CMD(a2) .error movem.l (a7)+,d0-d7/a0-a4 rts ;---------------------------------------------------------- ;-------------- Print path -------------------------------- ;-> d0=block no of actual dir ;-> a3=partition print_path movem.l d0/a0-a4,-(a7) st disk_op move.l part_device(a3),a2 lea.l general_txt+80,a4 .loop lea.l secbuf,a0 bsr read_fbuffer cmp.l #1,127*4(a0) ;ROOT ? beq.b .root move.b #'/',-(a4) bsr.b .check_len bne.b .out bsr .put_name bsr.b .check_len bne.b .out move.l 125*4(a0),d0 ;get parent bne.b .loop bra.b .err .root move.b #':',-(a4) bsr.b .check_len bne.b .out lea.l part_name(a3),a0 bsr .put_name2 .out move.l a4,a0 bsr print .err movem.l (a7)+,d0/a0-a4 rts ;put BCPL name from secbuf to -(a4) .put_name move.l a0,-(a7) lea.l secbuf+108*4,a0 bsr .put_name2 move.l (a7)+,a0 rts ;put BCPL name from a0 to -(a4) .put_name2 movem.l d0/a0,-(a7) moveq #0,d0 move.b (a0)+,d0 ;name length add.l d0,a0 bra.b .godbf .copy move.b -(a0),-(a4) bsr.b .check_len bne.b .outn .godbf dbf d0,.copy .outn movem.l (a7)+,d0/a0 rts ;-> a4 ;<- FLAGS 0=len ok -1=full .check_len movem.l d0/a4,-(a7) cmp.l #general_txt+2,a4 bne.b .nofull move.l #'....',(a4) moveq #-1,d0 bra.b .outl .nofull moveq #0,d0 .outl movem.l (a7)+,d0/a4 rts ;---------------------------------------------------------- ;-------------- Get Free Blocks -------------------------- ;-> a3=ptr on partition get_free_blocks st disk_op move.l part_nbsec(a3),d0 lsr.l #1,d0 ;ROOT block no lea.l secbuf,a0 bsr read_fbuffer ;read ROOT block bsr test_sum beq.b .oksum moveq #0,d0 bra.w .error .oksum .error rts ;---------------------------------------------------------- ;-------------- ExNext ------------------------------------ ;-> d1=ptr on dir path to list or previous examined file_handle ;<- d0=file_handle on next file 0=no next -1=error ;<- d1=ptr on partition of dir (returned only on first call) ;<- d2=block no of parent (returned only on first call) ExNext st disk_op movem.l d1-a4,-(a7) cmp.l #file_handle1,d1 beq.b .next cmp.l #file_handle2,d1 bne.b .first .next move.l d1,a1 move.l file_part(a1),a3 move.l part_device(a3),a2 lea.l secbuf,a0 move.l file_header(a1),d0 bsr read_fbuffer ;read previous file header bsr test_sum bne.w .error2 move.l 124*4(a0),d0 ;next in hash list bne.w .found bsr calc_hash lea.l extension,a0 ;dir block here lea.l 4(a0,d0.w),a0 ;next in hash table .seek2 cmp.l #extension+78*4,a0 ;end of hash table ? beq.w .enddir move.l (a0)+,d0 beq.b .seek2 bra.w .found ;------------------------------------------- .first move.l d1,a0 ;path name .seekend tst.b (a0)+ bne.b .seekend subq.l #2,a0 ;go on last char cmp.l d1,a0 bge.b .noempty move.l d1,a0 bra.b .already .noempty cmp.b #'/',(a0)+ beq.b .already cmp.b #':',-1(a0) ;device ? beq.b .already move.b #'/',(a0)+ .already move.b #'a',(a0)+ ;dummy filename for find partition sf (a0)+ lea.l file_handle1,a1 tst.l (a1) beq.b .okfree lea.l file_handle2,a1 tst.l (a1) beq.b .okfree moveq #0,d0 bra.w .error .okfree bsr find_partition tst.l d0 beq.w .error move.l d0,(a1) move.l d0,(a7) ;return partition in d1 move.l d2,4(a7) ;return parent block no in d2 move.l d0,a3 move.l part_device(a3),a2 move.l d2,file_parent(a1) move.l file_parent(a1),d0 lea.l extension,a0 bsr read_fbuffer ;read dir block bsr test_sum bne.b .error2 lea.l 6*4(a0),a4 ;start of hashtable moveq #72-1,d1 ;hashtable size .seekfirst move.l (a4)+,d0 ;find first file bne.b .found dbf d1,.seekfirst .enddir clr.l (a1) moveq #0,d0 ;end of dir bra.b .endx .found move.l d0,file_header(a1) lea.l secbuf,a0 bsr read_fbuffer ;read first file header bsr test_sum bne.b .error2 move.l 81*4(a0),file_size(a1) lea.l file_name(a1),a4 cmp.l #-3,127*4(a0) ;is it a file_header ? or a dir ? sne file_dir(a1) lea.l 108*4(a0),a0 moveq #8-1,d0 .copyn move.l (a0)+,(a4)+ ;copy BCPL filename dbf d0,.copyn move.l a1,d0 bra.b .endx .error2 clr.l (a1) ;free file_handle .error moveq #-1,d0 bra.b .out .endx tst.w drive_err bne.b .error2 .out movem.l (a7)+,d1-a4 rts ;---------------------------------------------------------- ;<- d1=ptr on filename to delete (or empty directory) delete_file movem.l d0-d2/a1,-(a7) moveq #1,d2 ;mode old file or old dir bsr open_file tst.l d0 beq.b .err move.l d0,a1 bsr delete_fh clr.l (a1) ;free file_handle .err movem.l (a7)+,d0-d2/a1 rts ;<- a1=file_handle delete_fh movem.l d0-a4,-(a7) st disk_op move.l file_part(a1),a3 move.l part_device(a3),a2 move.l file_parent(a1),d0 move.l d0,d3 lea.l extension,a0 bsr read_fbuffer ;read PARENT dir bsr test_sum bne.w .error move.l file_header(a1),d1 bsr calc_hash .next cmp.l (a0,d0.w),d1 beq.b .found move.l (a0,d0.w),d0 beq.w .error ;should never happen move.l d0,d3 bsr read_fbuffer bsr test_sum bne.w .error move.w #124*4,d0 bra.b .next .found move.w d0,d2 move.l d1,d0 lea.l secbuf,a0 bsr read_fbuffer ;read file header bsr test_sum bne.w .error cmp.l #1,127*4(a0) bne.b .noroot .notempty move.w #NOTEMPTY_ERR,drive_err bra.w .error .noroot cmp.l #2,127*4(a0) bne.b .nodir lea.l 6*4(a0),a0 moveq #72-1,d0 .check tst.l (a0)+ ;dir is empty ? bne.b .notempty dbf d0,.check lea.l secbuf,a0 .nodir move.l 124*4(a0),d0 ;next in hash chain lea.l extension,a0 move.l d0,(a0,d2.w) move.l d3,d0 bsr calc_sum bsr write_fbuffer ;write back block before file_header lea.l extension,a0 move.l file_header(a1),d0 bsr read_fbuffer ;file_header in extension bsr test_sum bne.b .error move.l file_header(a1),d0 bsr free_block ;free file_header .next_ext lea.l extension,a0 move.l 2*4(a0),d1 ;nb blocks lea.l 78*4(a0),a4 bra.b .godbf .loop move.l -(a4),d0 bsr free_block .godbf dbf d1,.loop move.l 126*4(a0),d0 ;next extension ? beq.b .end bsr read_fbuffer ;read next extension bsr test_sum bne.b .error bsr free_block ;free extension block bra.b .next_ext .end .error bsr update_bitmap bsr flush_fbuffer movem.l (a7)+,d0-a4 rts ;---------------------------------------------------------- ;-> d1=filename ;<- d0=ptr on partition structure (0=error) ;<- d1=ptr on filename (without path) ;<- d2=dir key where the file is find_partition movem.l d3-d7/a0-a4,-(a7) st disk_op move.l d1,d7 move.l current_dir,a3 ;default partition move.l current_dir+4,d6 ;default dir lea.l part_name(a3),a0 lea.l part_nametemp,a1 moveq #8-1,d0 ;copy partition name .copyn move.l (a0)+,(a1)+ ;in case there isn't a device: dbf d0,.copyn ;in the path move.l d7,a0 .seek tst.b (a0) beq.w .endofname cmp.b #':',(a0)+ ;seek device name (ex. HD0: ) bne.b .seek subq.l #1,a0 sub.l d7,a0 move.l a0,d0 cmp.l #30,d0 ble.b .oksize moveq #30,d0 .oksize lea.l part_nametemp,a1 move.l a1,a0 moveq #8-1,d1 .clr clr.l (a0)+ ;clear part_nametemp dbf d1,.clr move.b d0,(a1)+ ;write len of name move.l d7,a0 move.w d0,d1 bra.b .godbf .copyname move.b (a0)+,d0 bsr upper_case move.b d0,(a1)+ ;copy part_name .godbf dbf d1,.copyname addq.l #1,a0 ;skip ':' char move.l a0,d7 lea.l part_nametemp,a0 lea.l floppy0,a3 ;find partition structure .seek2 lea.l part_name(a3),a1 move.l a0,a4 moveq #8-1,d0 .cmpname cmpm.l (a1)+,(a4)+ bne.b .notsame dbf d0,.cmpname move.l part_nbsec(a3),d6 lsr.l #1,d6 ;ROOT block is default dir bra.b .endofname .notsame move.l part_next(a3),d0 beq.b .err move.l d0,a3 bra.b .seek2 .err move.w #DEVICENOTFOUND_ERR,drive_err moveq #0,d0 bra.w .end ;-------------- find directory ------------- .endofname bsr test_change tst.w drive_err ;test if an error occured bne.b .exit cmp.l #$444f5301,part_filesystem(a3) ;DOS\1 FFS ? beq.b .okFFS cmp.l #$444f5303,part_filesystem(a3) ;DOS\3 FFS INTL ? beq.b .okFFS move.w #NOFFS_ERR,drive_err .exit moveq #0,d0 bra.w .end .okFFS move.l part_device(a3),a2 move.l d7,a0 .seekslash tst.b (a0) beq.w .nomore cmp.b #"/",(a0)+ bne.b .seekslash subq.l #1,a0 cmp.l d7,a0 bne.b .noparent addq.l #1,d7 ;skip '/' char move.l d6,d0 lea.l secbuf,a0 bsr read_fbuffer ;read actual dir bsr test_sum bne.w .error move.l 125*4(a0),d6 ;parent bne.b .okFFS ;found a parent ? move.w #ILLEGALPATH_ERR,drive_err moveq #0,d0 bra.w .end .noparent sub.l d7,a0 move.l a0,d2 ;dir_name len lea.l part_nametemp,a1 move.l a1,a0 moveq #8-1,d1 .clr2 clr.l (a1)+ dbf d1,.clr2 move.b d2,(a0)+ ;set dir_name len move.l d7,a1 bra.b .godbf2 .copydn move.b (a1)+,(a0)+ ;copy dir_name .godbf2 dbf d2,.copydn move.l a1,d7 addq.l #1,d7 ;skip '/' char lea.l secbuf,a0 move.l d6,d0 bsr read_fbuffer ;read actual dir bsr test_sum bne.b .error lea.l part_nametemp,a0 move.b part_filesystem+3(a3),d0 ;get DOSTYPE bsr calc_hash2 .nextdir lea.l secbuf,a0 move.l (a0,d0.w),d6 ;read hash ptr beq.b .illegal move.l d6,d0 bsr read_fbuffer ;read new dir bsr test_sum bne.b .error lea.l part_nametemp,a0 lea.l secbuf+108*4,a1 bsr cmp_filename2 beq.b .okdirname move.w #124*4,d0 bra.b .nextdir .okdirname cmp.l #2,secbuf+127*4 ;is it a dir ? beq.w .okFFS .illegal move.w #ILLEGALPATH_ERR,drive_err .error moveq #0,d0 ;not a dir, then error bra.b .end .nomore move.l d7,a0 tst.b (a0) ;empty filename ? bne.b .okfilename move.w #FILEEXIST_ERR,drive_err moveq #0,d0 bra.b .end .okfilename move.l a3,d0 move.l d7,d1 move.l d6,d2 .end movem.l (a7)+,d3-d7/a0-a4 rts ;---------------------------------------------------------- ;-------------- test if disk was changed and reinit ------- ;-------------- partition structure ----------------------- ;-> a3=ptr on partition test_change movem.l d0/a0-a3,-(a7) st disk_op move.l part_device(a3),a2 moveq #0,d0 ;test if changed cmd jsr CHANGE_CMD(a2) tst.l d0 beq.b .nochange bpl.b .newdisk clr.l part_filesystem(a3) ;no disk bra.b .end .newdisk lea.l secbuf,a0 clr.l (a0) moveq #0,d0 jsr READ_CMD(a2) ;read boot-block move.l secbuf,part_filesystem(a3) bra.b .end .nochange tst.l part_filesystem(a3) beq.b .newdisk .end movem.l (a7)+,d0/a0-a3 rts ;---------------------------------------------------------- ;-------------- copy name into file handle ---------------- ;-------------- convert it into BCPL ---------------------- ;-> d1=ptr on name ended by zero ;-> a1=file_handle copy_name move.l a2,-(a7) lea.l file_name(a1),a2 rept 8 clr.l (a2)+ endr lea.l file_name(a1),a2 bsr copy_name2 move.l (a7)+,a2 rts ;-> d1=ptr on name ended by zero ;-> a2=dest address copy_name2 movem.l d0-d2/a0-a3,-(a7) lea.l 1(a2),a3 move.l d1,a0 moveq #30-1,d0 ;maxlen of filename moveq #-1,d2 .copy addq.w #1,d2 move.b (a0)+,(a3)+ dbeq d0,.copy beq.b .nomax moveq #30,d2 .nomax move.b d2,(a2) ;write filename len movem.l (a7)+,d0-d2/a0-a3 rts ;---------------------------------------------------------- ;-> a1=file_handle ;<- d0=hash val *4 calc_hash movem.l a0,-(a7) move.l file_part(a1),a0 move.b part_filesystem+3(a0),d0 ;get DOSTYPE lea.l file_name(a1),a0 bsr.b calc_hash2 movem.l (a7)+,a0 rts ;-> a0=ptr on BCPL name ;-> d0=DOSTYPE 1=FFS, 3=INTL FFS, 5=DCFS ;<- d0=hash val *4 calc_hash2 movem.l d1-d3/a0-a1,-(a7) move.b d0,d3 ;d3=DOSTYPE moveq #0,d0 move.b (a0)+,d0 ;read len of name move.w d0,d2 subq.w #1,d2 move.w d0,d1 moveq #0,d0 .loop2 mulu #13,d1 move.b (a0)+,d0 cmp.b #3,d3 ;check DOSTYPE blt.b .nointl cmp.b #$f7,d0 beq.b .okintl bsr.b intl_conv bra.b .okintl .nointl bsr upper_case .okintl add.w d0,d1 and.w #$7ff,d1 dbf d2,.loop2 divu #72,d1 swap d1 addq.w #6,d1 move.w d1,d0 lsl.w #2,d0 movem.l (a7)+,d1-d3/a0-a1 rts ;-> d0=ascII char intl_conv movem.l d1-d2,-(a7) move.b d0,d2 move.l #"~`za",d1 ;$7e607a61 bclr #7,d0 beq.b .hashcv1 swap d1 .hashcv1 cmp.b d1,d0 blt.b .hashcv2 lsr.l #8,d1 cmp.b d1,d0 bgt.b .hashcv2 bclr #5,d2 .hashcv2 move.b d2,d0 movem.l (a7)+,d1-d2 rts ;---------------------------------------------------------- ;-> a1=file_handle ;-> a0=ptr on BCPL name to compare ;<- FLAGS =result 0=same -1=different cmp_filename movem.l a1,-(a7) lea.l file_name(a1),a1 bsr.b cmp_filename2 movem.l (a7)+,a1 rts ;-> a1=ptr on BCPL name1 to compare ;-> a0=ptr on BCPL name2 to compare ;<- FLAGS =result 0=same -1=different cmp_filename2 movem.l d0-d2/a0-a1,-(a7) move.b (a1)+,d0 cmp.b (a0)+,d0 bne.b .err moveq #0,d1 move.b d0,d1 bra.b .godbf .loop move.b (a1)+,d0 bsr upper_case move.b d0,d2 move.b (a0)+,d0 bsr upper_case cmp.b d0,d2 bne.b .err .godbf dbf d1,.loop moveq #0,d0 bra.b .ok .err moveq #-1,d0 .ok movem.l (a7)+,d0-d2/a0-a1 rts ;--------------------------------------------------------------- ;-------------- find a free block in the bitmap and set it ----- ;-> a1=ptr on file_handle ;<- d0=free block no. -1=error alloc_block movem.l d1-d7/a0-a4,-(a7) move.l file_part(a1),a3 move.l part_device(a3),a2 cmp.l bitmap_part,a3 beq.w .okloaded .search bsr update_bitmap move.l a3,bitmap_part move.l part_nbsec(a3),d0 lsr.l #1,d0 ;ROOT block lea.l secbuf,a0 bsr read_fbuffer ;read ROOT block move.w #79*4,d4 ;start of bitmap_block table move.w #104*4,d5 ;end of table move.l #2,bitmap_offset .next bsr update_bitmap lea.l secbuf,a0 move.l (a0,d4.w),d0 ;get bitmap block move.l d0,bitmap_no lea.l bitmap,a0 bsr read_fbuffer ;read bitmap block bsr alloc_block2 tst.l d0 bmi.b .diskfull bne.b .end add.l #127*32,bitmap_offset addq.w #4,d4 ;next block in bitmap list cmp.w d5,d4 ;max val reached ? bne.b .next lea.l secbuf,a0 move.l (a0,d5.w),d0 ;get next bitmap list no bsr read_fbuffer move.w #127*4,d5 moveq #0,d4 bra.b .next .okloaded bsr alloc_block2 tst.l d0 ;found a free block ? bmi.b .diskfull beq.w .search .end .diskfull tst.l d0 movem.l (a7)+,d1-d7/a0-a4 rts ;-------------- find a free block in the actual bitmap block -------- ;-------------- (called by alloc_block only) ------------------------ ;-> a3=ptr on partition ;<- d0=no of free block, 0=no free block in bitmap block, -1=disk full alloc_block2 movem.l d1-d3/a0,-(a7) lea.l bitmap+4,a0 move.l bitmap_offset,d0 move.l part_nbsec(a3),d3 ;max limit .seek2 move.l (a0)+,d1 bne.b .deeper moveq #32,d1 add.l d1,d0 cmp.l d3,d0 bge.b .full bra.b .skip .deeper moveq #32-1,d2 .seek lsr.l #1,d1 bcs.b .found addq.l #1,d0 cmp.l d3,d0 bge.b .full dbf d2,.seek .skip cmp.l #bitmap+512,a0 bne.b .seek2 moveq #0,d0 ;end of block reached bra.b .end .full moveq #-1,d0 bra.b .end .found move.l d0,d1 sub.l bitmap_offset,d1 move.l d1,d2 lsr.l #5,d2 lea.l bitmap+4,a0 lsl.l #2,d2 move.l (a0,d2.l),d3 and.l #$1f,d1 bclr d1,d3 ;alloc block in bitmap move.l d3,(a0,d2.l) st bitmap_modified tst.l d0 .end movem.l (a7)+,d1-d3/a0 rts ;--------------------------------------------------------------- ;-------------- free a block in the bitmap --------------------- ;-> d0=no of block to free ;-> a1=ptr on file_handle free_block movem.l d0-a4,-(a7) move.l file_part(a1),a3 move.l part_device(a3),a2 move.l d0,d7 cmp.l bitmap_part,a3 bne.b .load move.l d0,d7 move.l bitmap_offset,d0 cmp.l d0,d7 ;is this block in the blt.b .load ;actual bitmap block add.l #127*32,d0 cmp.l d0,d7 bge.b .load .free move.l d7,d1 sub.l bitmap_offset,d1 move.l d1,d2 lsr.l #5,d2 lea.l bitmap+4,a0 lsl.l #2,d2 move.l (a0,d2.l),d3 and.l #$1f,d1 bset d1,d3 ;free block in bitmap move.l d3,(a0,d2.l) bra.w .end .load bsr update_bitmap move.l d7,d6 divu #127*32,d6 ;d6=no of block to search ext.l d6 move.l a3,bitmap_part move.l part_nbsec(a3),d0 lsr.l #1,d0 ;ROOT block lea.l secbuf,a0 bsr read_fbuffer ;read ROOT block bsr test_sum bne.b .error move.w #79*4,d4 ;start of bitmap_block table move.w #104*4,d5 ;end of table move.l #2,bitmap_offset .nomax tst.l d6 beq.b .found add.l #32*127,bitmap_offset subq.l #1,d6 addq.w #4,d4 cmp.w d4,d5 bne.b .nomax lea.l secbuf,a0 move.l (a0,d4.w),d0 bsr read_fbuffer ;read the bitmap block table moveq #0,d4 move.w #127*4,d5 bra.b .nomax .found lea.l secbuf,a0 move.l (a0,d4.w),d0 move.l d0,bitmap_no lea.l bitmap,a0 bsr read_fbuffer ;read the bitmap block bsr test_sum bne.b .error bra.w .free .end st bitmap_modified .error movem.l (a7)+,d0-a4 rts ;---------------------------------------------------------- ;-------------- write back the bitmap to disk ------------- update_bitmap movem.l d0/a0-a3,-(a7) tst.b bitmap_modified beq.b .nomodif sf bitmap_modified move.l bitmap_part,a3 move.l part_device(a3),a2 lea.l bitmap,a0 bsr calc_bitmapsum move.l bitmap_no,d0 bsr write_fbuffer .nomodif movem.l (a7)+,d0/a0-a3 rts ;---------------------------------------------------------- ;calculate a block checksum and write it in the block ;-> a0=ptr on block calc_sum movem.l d0-d1/a0-a1,-(a7) move.l a0,a1 clr.l 5*4(a0) ;clear sum moveq #0,d1 moveq #512/4-1,d0 .sum add.l (a0)+,d1 dbf d0,.sum neg.l d1 move.l d1,5*4(a1) movem.l (a7)+,d0-d1/a0-a1 rts ;---------------------------------------------------------- ;-------------- calcualte bitmap checksum and set it ------ ;-> a0=ptr on bitmap block calc_bitmapsum movem.l d0-d1/a0-a1,-(a7) move.l a0,a1 clr.l (a0) ;clear sum moveq #0,d1 moveq #512/4-1,d0 .sum add.l (a0)+,d1 dbf d0,.sum neg.l d1 move.l d1,(a1) movem.l (a7)+,d0-d1/a0-a1 rts ;---------------------------------------------------------- ;-------------- test the checksum of a block -------------- ;-> a0=ptr on block to test ;<- FLAGS 0=sum ok -1=bad checksum test_sum: movem.l d0-d1/a0,-(a7) moveq #0,d0 moveq #512/16-1,d1 .sum add.l (a0)+,d0 add.l (a0)+,d0 add.l (a0)+,d0 add.l (a0)+,d0 dbf d1,.sum tst.l d0 beq.b .ok move.w #BADCHECKSUM_ERR,drive_err moveq #-1,d0 .ok movem.l (a7)+,d0-d1/a0 rts cnop 0,4 file_handle1 dc.l 0 ;part dc.l 0 ;parent dc.l 0 ;header dc.l 0 ;extension dc.l 0 ;extension pos dc.l 0 ;filesize dc.l 0 ;seek pos dcb.b 32,0 ;name dc.b 0 ;written flag dc.b 0 ;dir cnop 0,4 file_handle2 dc.l 0 ;part dc.l 0 ;parent dc.l 0 ;header dc.l 0 ;extension dc.l 0 ;extension pos dc.l 0 ;filesize dc.l 0 ;seek pos dcb.b 32,0 ;name dc.b 0 ;written flag dc.b 0 ;dir cnop 0,4 current_dir dc.l floppy0 ;ptr on partition dc.l 880 ;ptr on dir key part_nametemp dcb.b 32,0 cnop 0,4 extension dcb.b 512,0 ;buffers secbuf dcb.b 512,0 ;used for bitmap dcb.b 512,0 ;filesystem bitmap_no dc.l 0 ;no of bitmap sector in bitmap buffer bitmap_part dc.l 0 ;ptr on partition of bitmap buffer bitmap_offset dc.l 0 ;no of the first block of the bitmap bitmap_modified dc.b 0 ;0=no modif. -1=modified cnop 0,4