# HG changeset patch # User boisy # Date 1054653570 0 # Node ID 57157a062b5d6b3fc7a93b02796c9aabd1d379f0 # Parent 70df6eac0ae3901e557fa6c29fef8ab4627a7d19 Rbf2 handles sector sizes up to 2048 bytes diff -r 70df6eac0ae3 -r 57157a062b5d level2/modules/rbf2.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/level2/modules/rbf2.asm Tue Jun 03 15:19:30 2003 +0000 @@ -0,0 +1,3181 @@ +******************************************************************** +* RBF - Random Block File Manager +* +* $Id$ +* +* Modified for 6309 Native mode by Bill Nobel, L. Curtis Boyle & Wes Gale +* +* This also contains the patch for un-deleting files +* +* Undocumented SetStt/GetStt calls: +* +* GetStt: +* SS.FD ($0F) - Returns a file descriptor +* Entry: R$A=Path # +* R$B=SS.FD ($0F) +* R$X=Pointer to a 256 byte buffer +* R$Y=# bytes of FD required +* SS.FDInf ($20) - Directly reads a file descriptor from anywhere +* on drive. +* Entry: R$A=Path # +* R$B=SS.FDInf ($20) +* R$X=Pointer to a 256 byte buffer +* R$Y= MSB - Length of read +* LSB - MSB of logical sector # +* R$U= LSW of logical sector # +* SetStt: +* SS.FD ($0F) - Writes a file descriptor +* Entry: R$A=Path # +* R$B=SS.FD ($0F) +* R$X=Pointer to a maximum 256 byte buffer +* R$Y=# bytes of FD to write +* SS.Ticks ($10) - Set # ticks to wait for record lock release +* Entry: R$A=Path # +* R$B=SS.Ticks ($10) +* R$X=# Ticks to wait +* SS.Lock ($11) - Force Lock/Release of a file. +* Locks from current position to a specified size +* Entry: R$A=Path # +* R$B=SS.Lock ($11) +* R$X=LSW of end byte position +* R$U=MSW of end byte position +* SS.Attr ($1C) - Allows changing of file/directory attributes +* If changing directory attribute it scans to +* see if directory is empty. +* Entry: R$A=Path # +* R$B=SS.Attr ($1C) +* R$X= LSB - File attributes +* SS.RsBit ($1E) - Reserve bitmap sector (doesn't allocate) +* Locks the bitmap sector from other programs +* so they cannot allocate in it. +* Useful when working in allocation map. +* Entry: R$A=Path # +* R$B=SS.RsBit ($1E) +* R$X= LSB - Sector # of bitmap +* +* Ed. Comments Who YY/MM/DD +* ------------------------------------------------------------------ +* ??? Started putting in comments from buggy 1.09 ??? 93/09/19 +* code +* ??? Fixed WP error bug on file delete ??? 93/09/19 +* Fixed FD read error bug in delete +* ??? Fixed long overdue LHA bug ??? 94/07/15 +* Modified M$Exec driver calls @ L11EB to use +* V$DRIVEX +* ??? Changed L11EB to just PSHS/PULS A,X,PC ??? 94/07/27 +* instead of D,X,PC (saves 2 cycles per +* driver call) +* Changed BRA L12C6 @ L128E to PULS PC,U,X +* ??? NitrOS-9 2.00 distribution ??? ??/??/?? +* 35 Fixed FD.SEG bug GH ??/??/?? +* Folded RBF 30 comments into this version BGP 03/04/21 + + nam RBF + ttl Random Block File Manager + + ifp1 + use defsfile + use rbfdefs + endc + +rev set $01 +ty set FlMgr + IFNE H6309 +lg set Obj6309 + ELSE +lg set Objct + ENDC +tylg set ty+lg +atrv set ReEnt+rev +edition set 35 + + org $00 +size equ . + + mod eom,name,tylg,atrv,start,size + +name fcs /RBF/ + fcb edition + +L0012 fcb DRVMEM + + +**************************** +* +* Main entry point for RBF +* +* Entry: Y = Path descriptor pointer +* U = Register stack pointer + +start bra Create + nop + lbra Open + lbra MakDir + lbra ChgDir + lbra Delete + lbra Seek + lbra Read + lbra Write + lbra ReadLn + lbra WriteLn + lbra GetStat + lbra SetStat + lbra Close + + +* +* I$Create Entry Point +* +* Entry: A = access mode desired +* B = file attributes +* X = address of the pathlist +* +* Exit: A = pathnum +* X = last byte of pathlist address +* +* Error: CC Carry set +* B = errcode +* +Create pshs y Preserve path desc ptr + leas -$05,s Make 5 byte buffer on stack + IFNE H6309 + aim #^DIR.,R$B,u + ELSE + lda R$B,u force directory bit off + anda #^DIR. + sta R$B,u + ENDC + lbsr FindFile try & find it in directory + bcs Creat47 branch if doesn't exist + +* File already exists + ldb #E$CEF else exists error +Creat47 cmpb #E$PNNF not found? + bne Creat7E + +* File doesn't exist, create it + cmpa #PDELIM full path? + beq Creat7E yes, return + pshs x preserve filename pointer + ldx PD.RGS,y get register stack pointer + stu R$X,x save updated pathname pointer +* These 4 did have < in front, made 3 byte cmnds but some are 2! + ldb PD.SBP,y get physical sector # of segment list + ldx PD.SBP+1,y + lda PD.SSZ,y get size of segment list in bytes + ldu PD.SSZ+1,y + pshs u,x,b,a preserve it all + ldx PD.RGS,y get register stack pointer +* Calculate default file size, if enabled +* This sets D to 0 if bit 5 of R$A is NOT set. If bit 5 of R$A is set +* when called, register Y will contain a default file size + lda R$A,x get file mode (read/write/update) + clrb + anda #PEXEC. bit 5 set? + beq Creat6E no, skip ahead + ldd R$Y,x get default file size +* account for FD sector, I think. +* changed from addd #1, bcc, ldd #$FFFF. +* The INCD gets D=$0000 (and CC.Z set) if it overflows from $FFFF->$0000 +* then if it's zero, a DECD forces it to be $FFFF +Creat6E addd #1 above 64k in size? (bug fix, thanks Gene K.) + bcc Creat75 no, skip ahead: changed from BCC + ldd #$FFFF force it to 64k +Creat75 lbsr FatScan find the space in the allocation map + bcc Creat83 got it, skip ahead + leas 6,s purge segment sizes from stack +* and fall through to routine which returns with an error. + +Creat7C leas 2,s purge user's pathname pointer +Creat7E leas 5,s purge local data + lbra ErMemRtn return with error + +* Create the file +Creat83 std $0B,s save segment size + ldb PD.SBP,y save segment physical sector # in path desc. + ldx PD.SBP+1,y starting LSN + stb $08,s on stack too + stx $09,s + puls u,x,b,a restore segment physical sector # & sizes + stb PD.SBP,y save it as current + stx PD.SBP+1,y + sta PD.SSZ,y + stu PD.SSZ+1,y +* Find empty slot in directory sector for new file + IFNE H6309 + ldq PD.DCP,y get directory entry pointer for new file + stq PD.CP,y save it as current file pointer + ELSE + ldd PD.DCP,y + std PD.CP,y + ldd PD.DCP+2,y + std PD.CP+2,y + ENDC + lbsr L0957 move entry into sector buffer + bcs CreatB5 +CreatAC tst ,x file exist here already? + beq CreatC7 no, found empty slot, skip ahead + lbsr L0942 point to next entry + bcc CreatAC try again +CreatB5 cmpb #E$EOF end of directory? + bne Creat7C no, return error +* Create the directory entry for new file + ldd #DIR.SZ get size of directory entry + lbsr Writ599 add it to size of directory + bcs Creat7C out of alloc? + lbsr MDir263 set file size in file descriptor + lbsr L0957 read in a directory sector +CreatC7 leau ,x point to directory entry + lbsr Creat169 clear it out + puls x restore pathname pointer + os9 F$PrsNam parse it to get filename + bcs Creat7E + cmpb #29 length of name right size? + bls CreatD9 yes, skip ahead + ldb #29 else force it to 29 chars +CreatD9 clra move length to Y + tfr d,y + lbsr Writ5CB move name of file to directory entry + tfr y,d move length of name to D + ldy $05,s restore PDpointer + decb subtract 1 off length + IFNE H6309 + oim #$80,b,u set high bit on last char of name + ELSE + lda b,u + ora #$80 + sta b,u + ENDC + ldb ,s get logical sector # of file desc + ldx $01,s + stb DIR.FD,u save it into directory entry + stx DIR.FD+1,u + lbsr L1205 flush sector to disk + bcs Creat151 +* Setup file descriptor + ldu PD.BUF,y get sector buffer pointer + bsr Creat170 clear it out + lda #FDBUF get file descriptor in buffer flag + sta PD.SMF,y save it as current sector buffer state + ldx PD.RGS,y get register stack pointer + lda R$B,x get file attributes + sta FD.ATT,u save it as current attributes + ldx Writ571,pcr WritLn or ReadLn? + cmpx $06,s check the stack + bne Read4F4 skipahead + lbsr L1098 find a segment + bra Read4F7 + +Read4F4 lbsr L1256 +Read4F7 bcs Read4C1 +Read4F9 ldu PD.BUF,y get sector buffer pointer + clra + ldb PD.CP+3,y +* addr d,u + leau d,u point to offset within the buffer + negb get D=number of byte left to read in the sector? + sbca #$FF not quite sure what this is... + ldx ,s grab caller's buffer pointer + cmpd $02,s check bytes left in sector against number to read + bls Read50C lower, OK + ldd $02,s grab number of bytes to read +Read50C pshs b,a save + jsr [$08,s] call our calling routine! + stx $02,s save new address to write to on-stack + IFNE H6309 + aim #^BufBusy,PD.SMF,y + ELSE + ldb PD.SMF,y + andb #^BufBusy + stb PD.SMF,y + ENDC + ldb $01,s get LSB of bytes read + addb PD.CP+3,y add it to current pointer + stb PD.CP+3,y save new file position + bne Read530 didn't grab whole sector, skip ahead + lbsr L1237 flush the sector + inc PD.CP+2,y add + bne Read52E + inc PD.CP+1,y + bne Read52E + inc PD.CP,y +Read52E bcs Read4C3 +Read530 ldd $04,s grab number of bytes to read/write + subd ,s++ take out number we've read/written + std $02,s save on-stack + jmp [$04,s] go back to calling routine with D,X on-stack + + +* +* I$WritLn Entry Point +* +* Entry: +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* +WriteLn pshs y save PD pointer + clrb + ldy R$Y,u grab size of data to write + beq WtLn55E exit if none + ldx 64k + negb / invert it + sbca #$00 + addd R$Y,u add to bytes to write + std R$Y,u save new number of bytes to write +WtLn55E puls y restore PD pointer, and fall through to Write + + +* +* I$Write Entry Point +* +* Entry: +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* +Write ldd R$Y,u get size of write + lbsr L0B0C wait for I/O lock + bcs Writ598 error, return + ldd R$Y,u get size again + beq Writ597 zero, nothing to write so return + bsr Writ599 expand the file if needed + bcs Writ598 error on expand, return + bsr Writ582 +Writ571 pshs y,b,a + tfr d,y + bsr Writ5CB + puls y,b,a + leax d,x + IFNE H6309 + oim #(BUFMOD!SINBUF),PD.SMF,y + ELSE + pshs a + lda PD.SMF,y + ora #(BUFMOD!SINBUF) + sta PD.SMF,y + puls a + ENDC + rts + +Writ582 lbsr Read4D3 go read stuff + lbne Read4D9 + leas $08,s skip stuff on stack + ldy PD.Exten,y + lda #$01 + lbsr L0AD1 + ldy PE.PDptr,y +Writ597 clrb +Writ598 rts + +* Add bytes to current file position with file length extension +* Entry: D=# bytes to add +Writ599 addd PD.CP+2,y add length to LSW of current pointer + tfr d,x copy it + ldd PD.CP,y get MSW + IFNE H6309 + adcd #0 add in any carry from above + ELSE + adcb #0 + adca #0 + ENDC +Writ5A3 cmpd PD.SIZ,y MSW past eof? + bcs Writ597 no, return + bhi Writ5AF yes, add a sector + cmpx PD.SIZ+2,y LSW past eof? + bls Writ597 no, return +Writ5AF pshs u preserve U + ldu PD.SIZ+2,y get LSW of current size + stx PD.SIZ+2,y save new size + ldx PD.SIZ,y get MSW of new size + std PD.SIZ,y save new size +* ATD: L0C6F looks like it already saves U and X, so saving them here is +* unnecessary. + pshs u,x preserve old size + lbsr L0C6F allocate new size of file + puls u,x restore old size + bcc Writ5C9 no error from allocate, return + stx PD.SIZ,y put old size back + stu PD.SIZ+2,y +Writ5C9 puls pc,u restore U & return + +* Move bytes from user to system +* Entry: X=Source pointer +* Y=Byte count +* U=Destination pointer +Writ5CB pshs x + ldx $0F, so we can't use short n,R + ldq PD.SIZ,y get current file size +Gst5F8 std R$X,u save to the user + stw R$U,u save LSW + ELSE + ldd PD.SIZ,y + std R$X,u + ldd PD.SIZ+2,y + std R$U,u + ENDC +Gst5FF rts return + +* SS.POS +* Entry A=path num +* B=$05 +* Exit X=msw of pos +* U=lsw of pos +Gst600 cmpb #SS.POS is it SS.Pos? + bne Gst60D no, keep checking + IFNE H6309 +* use 2 LDD, STD, same size as ldq/std/stw, PD.CP+2 <$0F, we can use short n,R + ldq PD.CP,y get current file pointer + bra Gst5F8 + ELSE + ldd PD.CP,y get current file pointer + std R$X,u save MSW + ldd PD.CP+2,y get current file pointer + std R$U,u save LSW + rts + ENDC + +* Getstt(SS.FD) +* Entry: R$A = Path # +* R$B = SS.FD ($0F) +* R$X = ptr to 256 byte buffer +* R$Y = # of bytes of FD required +Gst60D cmpb #SS.FD is it SS.FD? + bne Gst627 no, keep checking + lbsr RdFlDscr go get file descriptor + bcs Gst5FF exit on error + ldu PD.RGS,y get register stack pointer + ldd R$Y,u get # bytesof FD he wants + tsta legal value? + beq Gst620 yes, skip ahead + ldd #$0100 get max size of FD +Gst620 ldx R$X,u get pointer + ldu PD.BUF,y get pointer to FD + lbra Read4AF move it to user space + +* Getstt(SS.FDInf) +* Entry: R$A = Path # +* R$B = SS.FDInf ($20) +* R$X = ptr to 256 byte buffer +* R$Y = msb - Length of read +* lsb - MSB of LSN +* R$U = LSW of LSN +Gst627 cmpb #SS.FDInf SS.FDInf? + bne Gst640 no, let driver handle it + lbsr L1237 check for sector flush + bcs Gst5FF + ldb R$Y,u get MSB of sector # + ldx R$U,u get LSW of sector # + lbsr L113A read the sector + bcs Gst5FF error, return + ldu PD.RGS,y get register stack pointer + ldd R$Y,u get length of data to move + clra clear MSB + bra Gst620 move it to user + +* Let driver handle the rest +Gst640 lda #D$GSTA get getstat function offset + lbra L113C send it to driver + + +* +* I$SetStat Entry Point +* +* Entry: +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* +SetStat ldb R$B,u get function code +* TODO: remove next line since SS.OPT is 0 + cmpb #SS.OPT + bne Sst659 not SS.OPT, skip ahead + ldx R$X,u get pointer to option packet + leax $02,x skip device type and drive # + leau PD.STP,y get pointer to start of data + ldy #(PD.TFM-PD.STP) get # bytes to move (not including PD.TFM) + lbra Writ5CB move 'em & return + +* SS.Size +Sst659 cmpb #SS.Size is it SS.Size? + bne Sst69B + ldd PD.FD+1,y is there a file descriptor? + bne Sst669 + tst PD.FD,y + lbeq Sst7A8 no, return error +Sst669 lda PD.MOD,y get file mode + bita #WRITE. is it write? + beq Sst697 no, return error + ldd R$X,u get MSW of new size + ldx R$U,u get LSW of new size + cmpd PD.SIZ,y + bcs Sst682 + bne Sst67F + cmpx PD.SIZ+2,y + bcs Sst682 +* New size is larger +Sst67F lbra Writ5A3 add new size to file +* New size is smaller +Sst682 std PD.SIZ,y + stx PD.SIZ+2,y + ldd PD.CP,y + ldx PD.CP+2,y + pshs x,b,a + lbsr L0EFE delete from end of the file + puls u,x + stx PD.CP,y restore current position + stu PD.CP+2,y + rts +* Return bad mode error +Sst697 comb set carry + ldb #E$BMode get bad mod error +Sst69A rts return + +* SetStt(SS.FD) #$0F - returns FD to disk +* Entry: R$A = Path # +* R$B = SS.FD ($0F) +* R$X = ptr to 256 byte buffer +* R$Y = # bytes to write +Sst69B cmpb #SS.FD is it SS.FD? + bne Sst6D9 no, keep checking + lda PD.MOD,y + bita #WRITE. is it write mode? + beq Sst697 no, return bad mode error + lbsr RdFlDscr read in file descriptor + bcs Sst69A error, return + pshs y preserve path descriptor pointer + ldx R$X,u get pointer to caller's buffer + ldu PD.BUF,y get pointer to FD + ldy L0012,pcr get sizeof drive tables +* confusion reigns supreme here, +* one source loaction says its number of drive tables, +* and the next says its the size of the table! And a 3rd +* says its D.TYP. + mul calculate offset into drive tables + addd V$STAT,u add start of static memory + addd #DRVBEG add offset to drive tables + std PD.DTB,y save pointer to drive table + lda ,s get character back + anda #$7F strip high bit + cmpa #PENTIR was it entire flag? + bne Sst83F no, keep going + leax $01,x move to next character + bra Sst861 go on + +Sst83F lbsr L1110 read in LSN0 + lbcs L0915 error, return + ldu PD.BUF,y get sector buffer pointer from the read-in sector + +* otherwise use the pointer from PD.DTB + ldd DD.DSK,u get disk ID + std PD.DSK,y put it in path descriptor + ldd PD.FD+1,y does it have a file descriptor? + bne Sst861 yes, skip ahead + lda PD.FD,y + bne Sst861 + lda DD.DIR,u get LSN of root directory + sta PD.FD,y put it in path descriptor + ldd DD.DIR+1,u + std PD.FD+1,y +Sst861 stx $04,s save pointer to pathname + stx $08,s + +Sst865 lbsr L1237 flush sector buffer + lbcs L0915 error, exit + lda ,s get last character of pathname + anda #$7F mask off high bit + cmpa #PENTIR entire device flag? + beq Sst87B yes, skip ahead + lbsr RdFlDscr read in file descriptor + lbcs L0915 error, return +Sst87B lbsr L0A2A check if directory is busy + lda ,s + cmpa #PDELIM was the trailing character a slash? + bne L08EF no, skip ahead + clr $02,s + clr $03,s + lda PD.MOD,y get file mode + ora #DIR. mask in directory bit + lbsr ChkAttrs can user access directory? + bcs L090D no, return + lbsr Open1CE setup path descriptor & start scan + ldx $08,s get pathname pointer + leax $01,x bump to next character + lbsr GtDvcNam check for valid name + std ,s save length of name + stx $04,s save updated name pointer + sty $08,s + ldy $06,s get path descriptor pointer + bcs L090D error in pathname, return + pshs u,y + ldu PD.Exten,y get pointer to path extension + leau PE.FilNm,u point to filename buffer + clra clear MSB of name length + tfr d,y move it to Y + lbsr Writ5CB move filename to temp area + puls u,y + lbsr L0957 read in a directory sector + bra L08C1 + +* Scan diretory for name +L08BC bsr L0918 get file descriptor + IFNE H6309 +L08BE bsr L0942 get next directory entry from drive + ELSE +L08BE lbsr L0942 + ENDC +L08C1 bcs L090D error, + tst ,x filename exists? + beq L08BC no, get next entry + clra + ldb $01,s + exg x,y + ldx PD.Exten,x get path extension pointer + leax PE.FilNm,x point to user's filename + lbsr L09BF compare the names + ldx $06,s get pointer to path descriptor + exg x,y + bcs L08BE names don't match, skip to next + bsr L0926 cop this DIR file descriptor to path descriptor + lda DIR.FD,x + sta PD.FD,y + ldd DIR.FD+1,x + std PD.FD+1,y + lbsr L0A90 check record lock? + lbra Sst865 go try again + +L08EF ldx $08,s + tsta last character? + bmi L08FC yes, skip ahead + os9 F$PrsNam parse the name + leax ,y go to the next part of the name + ldy $06,s +L08FC stx $04,s + clra +L08FF lda ,s + leas $04,s + pshs b,a,cc + IFNE H6309 + aim #^BufBusy,PD.SMF,y + ELSE + lda PD.SMF,y + anda #^BufBusy + sta PD.SMF,y + ENDC + puls pc,u,y,x,b,a,cc + +L090D cmpb #E$EOF + bne L0915 + bsr L0918 + ldb #E$PNNF +L0915 coma + bra L08FF + +L0918 pshs d + lda $04,s + cmpa #PDELIM + beq L0940 + ldd $06,s + bne L0940 + bra L0928 fewer clock cycles +L0926 pshs d +L0928 stx $06,s + lda PD.FD,y + sta PD.DFD,y + ldd PD.FD+1,y + std PD.DFD+1,y + IFNE H6309 + ldq PD.CP,y + stq PD.DCP,y + ELSE + ldd PD.CP,y + std PD.DCP,y + ldd PD.CP+2,y + std PD.DCP+2,y + ENDC +L0940 puls pc,b,a + +* Move to next directory entry +L0942 ldb PD.CP+3,y get current byte pointer + addb #DIR.SZ add in diretory entry size + stb PD.CP+3,y save it back + bcc L0957 didn't wrap, skip ahead (need new sector) + lbsr L1237 check for sector flush + inc PD.CP+2,y + bne L0957 + inc PD.CP+1,y + bne L0957 + inc PD.CP,y +L0957 ldd #DIR.SZ get directory entry size + lbsr RdLn473 end of directory? + bcs L097E yes, return + ldd #DIR.SZ get directory entry size + lbsr L0B0C + bcs L097E yes, return + lda PD.SMF,y get state flags + bita #SINBUF sector in buffer? + bne L0977 yes, skip ahead + lbsr L1098 + bcs L097E + lbsr L1256 + bcs L097E +L0977 ldb PD.CP+3,y get offset into sector + lda PD.BUF,y get MSB of sector buffer pointer + tfr d,x move it to X + clrb clear error status +L097E rts return + +* Get a byte from other task +L097F pshs u,x,b + ldu 2048 cluster segments??? +* It may be easier to read in the FD, and COMPACT it by looking for +* LSN+SIZE=next segment LSN. But that would take 48*(30?) clock cycles, +* which is a lot of time... but maybe not compared to F$All/F$Sch, and +* the sector read/writes... + cmpa #8 at least 256*8 bits to allocate? + bcs L0E04 number of clusters is OK, skip ahead + ldd #$0800 force one sector of clusters max. to be allocated +L0E04 std $0C,s save as the number of clusters to allocate + lbsr L1036 make us the current user of the allocation bitmap + lbcs L0EF2 exit on error + ldx PD.DTB,y get drive table + ldd V.DiskID,x and old disk ID + cmpd DD.DSK,x check against the current disk ID + bne L0E26 if not the same, make us the current disk ID + lda V.BMapSz,x same allocation bitmap size? + cmpa DD.MAP,x + bne L0E26 no, skip ahead + ldb V.MapSct,x another check + cmpb DD.MAP,x + bcs L0E34 + +L0E26 ldd DD.DSK,x get current disk ID + std V.DiskID,x make us the disk to use + lda DD.MAP,x grab number of sectors in allocation bitmap + sta V.BMapSz,x save for later + clrb + stb V.MapSct,x make this zero for now +L0E34 incb account for LSN0 + stb 6,s lowest reasonable bitmap sector number +* ATD: Is this line necessary? All calls to L0E34 set up X already + ldx PD.DTB,y get drive table pointer again + cmpb V.ResBit,x check B against reserved bitmap sector + beq L0E70 same, skip ahead + lbsr L1091 go read in a bitmap sector + lbcs L0EF2 + ldb 6,s grab copy of V.MapSCT again + cmpb 4,s check against number of sectors in allocation bitmap + bls L0E51 lower, continue + clra if at end of the allocation bitmap, + ldb 5,s don't search it all, but just to the end of the + bra L0E54 last sector in the allocation bitmap + +* ATD: This the routine that we would fix to cache a compressed version +* of the allocation bitmap. i.e. largest group of contiguous free sectors, +* where 255 == 256 by definition. At 1 byte/sector, max. 256 sectors in the +* allocation bitmap, max. 256 bytes. The search should be a LOT faster then, +* as we'll only have to search memory and not read in all those sectors. +* If we're really daring, we could build the new FD without reading the +* allocation bitmap _at_all_, and just use a 'best-fit' algorithm on the +* cached version, and update the bitmap later. +* RBF doesn't do any other search bit calls, so this is the routine. +L0E51 ldd #$0100 +L0E54 ldx PD.BUF,y where to start searching + leau d,x where to stop searching + ldy $0C,s number of bits to find +* ATD: force it to be less than 1 sector here... + IFNE H6309 + clrd at starting bit number 0 + ELSE + clra + clrb + ENDC + os9 F$SchBit + bcc L0E9D found bits + cmpy 8,s check number of found bits against our maximum + bls L0E70 smaller, skip ahead + sty 8,s save as new maximum + std $0A,s save starting bit number + lda 6,s grab current sector + sta 7,s save for later +L0E70 ldy <$10,s grab old PD pointer + ldb 6,s grab current bitmap sector number + cmpb 4,s check against highest sector number of bitmap + bcs L0E81 we're OK, skip ahead + bhi L0E80 we're too high, skip ahead + tst 5,s check bytes in the sector + bne L0E81 not zero: skip ahead +L0E80 clrb +L0E81 ldx PD.DTB,y get drive table pointer again + cmpb V.MapSct,x check against lowest reasonable bitmap sector + bne L0E34 ifnot the same, continue + + ldb 7,s grab sector number of largest block found + beq L0EF0 zero, exit with E$Full error + cmpb 6,s is it the current sector? + beq L0E96 yes, skip ahead + stb 6,s make it the current sector + lbsr L1091 go read the sector in from disk + +L0E96 ldx PD.BUF,y point to the sector in the buffer + ldd $0A,s grab starting bit number + ldy 8,s and number of bits to allocate +L0E9D std $0A,s save starting bit number + sty 8,s and number of bits to allocate + os9 F$AllBit go allocate the bits + ldy $10,s grab the PD pointer again + ldb $06,s and the sector number + lbsr L1069 write it out to disk + bcs L0EF2 exit on error +* ATD: add check for segments left to allocate, if we've allocated +* one entire sector's worth??? +* What about special-purpose code to read the allocation bitmap byte by byte +* and do it that way? I dunno... +* Have some routine inside L0DB5 call another routine which allocates segments +* one sector at a time... have a check: got one sector? +* ATD: We'll probably have to add in allocation bitmap caching for this +* to work properly.... + ldx PD.DTB,y drive table pointer + lda 6,s current sector + deca decreemnt + sta V.MapSct,x AHA! Last searched sector for later use + clrb + lsla move high bit of A into CC.C + rolb move CC.C into B + lsla etc. + rolb cannot do a ROLD, as that would be LSB, ROLA + lsla i.e. move the 3 high bits of A into low bits of B + rolb and shift A by 3 + stb PD.SBP,y save segment beginning physical sector number + ora $0A,s OR in with the start bit number + ldb $0B,s grab LSB of starting bit number + ldx 8,s and number of free sectors found +* ATD: Is this next line really necessary? + ldy $10,s get PD pointer + std PD.SBP+1,y save low 2 bytes of segment beginning physical SN + stx PD.SSZ+1,y and segment size in clusters + ldd 2,s grab number of sectors per cluster + bra L0EE6 + +L0ED7 lsl PD.SBP+2,y shift physical sector numberup + rol PD.SBP+1,y to LSN, to account for cluster size + rol PD.SBP,y + lsl PD.SSZ+2,y + rol PD.SSZ+1,y shift segment cluster size to sector size +L0EE6 + IFNE H6309 + lsrd + ELSE + lsra + rorb + ENDC + bcc L0ED7 + + clrb no errors + ldd PD.SSZ+1,y number of sectors allocated + bra L0EFA and return to the user + +L0EF0 ldb #E$Full +L0EF2 ldy $10,s get old Y off of the stack + lbsr L1070 return allocation bitmap? + coma +L0EFA leas $0E,s skip 12-byte buffer, and D + puls pc,u,y,x + +* Set the size of a file to PD.SIZ, where PD.SIZ is SMALLER than the +* current size of the file. +L0EFE clra clear the carry +* This code ensures that directories are never shrunk in size. + lda PD.MOD,y access mode + bita #DIR. directory? + bne L0F6F yes (bit set), exit immediately + IFNE H6309 + ldq PD.SIZ,y grab size of the file + stq PD.CP,y make it the current position + ELSE + ldd PD.SIZ,y + std PD.CP,y + ldd PD.SIZ+2,y + std PD.CP+2,y + ENDC + ldd #$FFFF + tfr d,x + lbsr L0B1B + bcs L0F6E + lbsr L0CDF + bne L0F6F exit + lbsr L10B2 find a segment + bcc L0F26 + cmpb #E$NES non-existing segment error + bra L0F67 + +L0F26 ldd PD.SBL+1,y not quite sure what's going on here... + subd PD.CP+1,y + addd PD.SSZ+1,y + tst PD.CP+3,y on a sector boundary? + beq L0F35 yes, skip ahead + IFNE H6309 + decd ok here, carry NOT used below + ELSE + subd #$0001 + ENDC +L0F35 pshs d + ldu PD.DTB,y number of sectors per cluster + ldd DD.BIT,u + IFNE H6309 + decd + comd + andd ,s++ + ELSE + subd #$0001 + coma + comb + anda ,s+ + andb ,s+ + ENDC + ldu PD.SSZ+1,y + std PD.SSZ+1,y + beq L0F69 + tfr u,d + subd PD.SSZ+1,y + pshs x,b,a + addd PD.SBP+1,y + std PD.SBP+1,y + bcc L0F5F + inc PD.SBP,y +L0F5F bsr ClrFBits delete a segment + bcc L0F70 + leas 4,s + cmpb #E$IBA illegal block address + +L0F67 bne L0F6E +L0F69 lbsr RdFlDscr + bcc L0F79 +L0F6E coma +L0F6F rts + +L0F70 lbsr RdFlDscr + bcs L0FC9 + puls x,b,a + std FDSL.B,x +L0F79 ldu PD.BUF,y + IFNE H6309 + ldq PD.SIZ,y grab file size from the PD + stq FD.SIZ,u save in the FD file size + ELSE + ldd PD.SIZ,y + std FD.SIZ,u + ldd PD.SIZ+2,y + std FD.SIZ+2,u + ENDC + tfr x,d + clrb + inca + leax FDSL.S,x go to the next segment + pshs x,b,a + bra L0FB4 +L0F8E ldd -2,x + beq L0FC1 + std PD.SSZ+1,y + ldd -FDSL.S,x grab stuff from the last segment + std PD.SBP,y + lda -FDSL.B,x + sta PD.SBP+2,y save sector beginning physical sector number + bsr ClrFBits delete a segment + bcs L0FC9 + stx 2,s + lbsr RdFlDscr + bcs L0FC9 + ldx 2,s + IFNE H6309 + clrd + ELSE + clra + clrb + ENDC + std -$05,x clear out the segment + sta -$03,x + std -$02,x +L0FB4 lbsr L11FD + bcs L0FC9 + ldx 2,s + leax FDSL.S,x go to the next segment + cmpx ,s + bcs L0F8E if not done, do another +L0FC1 equ * + IFNE H6309 + clrd + ELSE + clra + clrb + ENDC + sta PD.SSZ,y + std PD.SSZ+1,y segment size is zero +L0FC9 leas 4,s + rts + +* de-allocate a segment +ClrFBits pshs u,y,x,a get device table pointer + ldx PD.DTB,y + +* ATD: Added next few lines to ENSURE that LSN0 and the allocation bitmap +* are NEVER marked as de-allocated in the allocation bitmap +* ldd PD.SBP,y grab beginning segment physical LSN +* bne L0FD0 skip next code if too high +* ldd DD.MAP,x get number of bytes in allocation bitmap +* addd #$01FF add 1 for LSN0, round up a sector: A=lowest LSN +* cmpa PD.SBP+2,y check LSN0 + DD.MAP against LSN to deallocate +* blo L0FD0 if PD.SBP is higher than LSN0 + DD.MAP, allow it +* ldb #E$IBA illegal block address: can't deallocate LSN0 +* bra L1033 or the allocation bitmap sectors from the bitmap! + + ldd DD.BIT,x + IFNE H6309 + decd + ELSE + subd #$0001 + ENDC + addd PD.SBP+1,y + std PD.SBP+1,y + ldd DD.BIT,x + bcc L0FF4 + inc PD.SBP,y + bra L0FF4 + +L0FE5 lsr PD.SBP,y convert sector number to cluster number + ror PD.SBP+1,y + ror PD.SBP+2,y + lsr PD.SSZ+1,y + ror PD.SSZ+2,y +L0FF4 equ * + IFNE H6309 + lsrd + ELSE + lsra + rorb + ENDC + bcc L0FE5 + + clrb + ldd PD.SSZ+1,y + beq L1034 + ldd PD.SBP,y + IFNE H6309 + lsrd + lsrd + lsrd get cluster byte number into D + ELSE + lsra + rorb + lsra + rorb + lsra + rorb + ENDC + tfr b,a + ldb #E$IBA + cmpa DD.MAP,x is the LSN too high: mapped outside of the bitmap? + bhi L1033 yes, error out + inca + sta ,s +L1012 bsr L1036 flush the sector, and OWN the bitmap + bcs L1012 + ldb ,s grab the sector number + bsr L1091 go read a sector fro the allocation bitmap + bcs L1033 + ldx PD.BUF,y where to start + ldd PD.SBP+1,y bit offset to delete +* ATD: keep deleting sectors until we're done! + anda #$07 make sure it's within the current sector +* ATD: fix segment sizes! + ldy PD.SSZ+1,y number of clusters to deallocate + os9 F$DelBit go delete them (no error possible) + ldy 3,s + ldb ,s grab bitmap sector number again + bsr L1069 go write it out + bcc L1034 xit on error +L1033 coma +L1034 puls pc,u,y,x,a + +L1036 lbsr L1237 flush the sector to disk + bra L1043 skip ahead + +L103B lbsr L0C56 wakeup the process + os9 F$IOQu queue the process + bsr L1053 check for process wakeup +L1043 bcs L1052 error, return + ldx PD.DTB,y get drive table ptr + lda V.BMB,x bitmap sector + bne L103B if set, continue + lda PD.CPR,y get our process number + sta V.BMB,x make us the current user of the bitmap +L1052 rts + +* Wait for process to wakeup +L1053 ldu takes state from x and + sta PD.SMF,y / stores to y, is infamous "lha" bug + clr PD.SMF,x + puls pc,u,x + +L12B5 ldy PE.PDptr,y + lbsr L1220 + lbsr L113A + bcs L12C6 + IFNE H6309 + oim #(BufBusy!SINBUF),PD.SMF,y + ELSE + pshs a + lda PD.SMF,y + ora #(BufBusy!SINBUF) + sta PD.SMF,y + puls a + ENDC +L12C6 puls pc,u,x + + emod +eom equ * + end +