# HG changeset patch # User boisy # Date 1050946597 0 # Node ID 2cdb7acff8aa2fbfaa3a14d8f9b1a765a36a02ea # Parent f052edb830d2bb823963207875fd4f0b2b0d7508 More comments diff -r f052edb830d2 -r 2cdb7acff8aa level2/modules/rbf.asm --- a/level2/modules/rbf.asm Mon Apr 21 16:56:47 2003 +0000 +++ b/level2/modules/rbf.asm Mon Apr 21 17:36:37 2003 +0000 @@ -3,10 +3,72 @@ * * $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 * ------------------------------------------------------------------ -* NitrOS-9 2.00 distribution ??/??/?? +* ??? 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 @@ -37,6 +99,14 @@ L0012 fcb $26 + +**************************** +* +* Main entry point for RBF +* +* Entry: Y = Path descriptor pointer +* U = Register stack pointer + start bra Create nop lbra Open @@ -52,285 +122,335 @@ lbra SetStat lbra Close -************ -* Create, according to the book, needs -* A=access mode desired -* B=file attributes -* X=address of the pathlist -* Exits with -* A=pathnum -* X=last byte of pathlist address -* if error -* CC.C set -* B=errcode -Create pshs y ptr to descriptor - leas -$05,s + +* +* 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 + lda R$B,u force directory bit off anda #^DIR. sta R$B,u ENDC - lbsr FindFile - bcs Creat47 carry=not found - ldb #E$CEF else exists error -Creat47 cmpb #E$PNNF not found? + 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 - cmpa #'/ full path? - beq Creat7E yes, go - pshs x - ldx PD.RGS,y - stu R$X,x - ldb PD.SBP,y these 4 did have < in front - ldx PD.SBP+1,y made 3 byte cmnds but some are 2! - lda PD.SSZ,y + +* 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 - ldx PD.RGS,y - lda R$A,x + 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. $20 - beq Creat6E - ldd R$Y,x -Creat6E addd #1 bug fix, thanks Gene K. - bcc Creat75 - ldd #$FFFF -Creat75 lbsr FatScan - bcc Creat83 - leas 6,s -Creat7C leas 2,s -Creat7E leas 5,s - lbra ErMemRtn + 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. -Creat83 std $0B,s sectors alloc'd - ldb PD.SBP,y - ldx PD.SBP+1,y starting LSN - stb $08,s +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 - stb PD.SBP,y + 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 - stq PD.CP,y + 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 find start of dir + lbsr L0957 move entry into sector buffer bcs CreatB5 -CreatAC tst ,x empty slot? - beq CreatC7 empty spot, go - lbsr L0942 else get next slot - bcc CreatAC -CreatB5 cmpb #E$EOF - bne Creat7C some other error - ldd #DIR.SZ - lbsr Writ599 extend dir by $20 - bcs Creat7C out of alloc? - lbsr MDir263 - lbsr L0957 -CreatC7 leau ,x - lbsr Creat169 - puls x - os9 F$PrsNam +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 - bls CreatD9 - ldb #29 -CreatD9 clra + 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 - tfr y,d - ldy $05,s - decb + 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 + oim #$80,b,u set high bit on last char of name ELSE lda b,u ora #$80 sta b,u ENDC - ldb ,s + ldb ,s get logical sector # of file desc ldx $01,s - stb DIR.FD,u + stb DIR.FD,u save it into directory entry stx DIR.FD+1,u - lbsr L1205 + lbsr L1205 flush sector to disk bcs Creat151 - ldu PD.BUF,y - bsr Creat170 - lda #FDBUF - sta PD.SMF,y - ldx PD.RGS,y - lda R$B,x - sta ,u - ldx Writ571,pcr - cmpx $06,s - bne Read4F4 - lbsr L1098 +* do reading/writing +Read4D3 ldd R$X,u get caller's buffer pointer + ldx R$Y,u get length of read + pshs x,b,a preserve 'em +Read4D9 lda PD.SMF,y get stat flags + bita #SINBUF sector in buffer/ + bne Read4F9 yes, read it + tst PD.CP+3,y read pointer on even sector? + bne Read4F4 no, skip ahead + tst $02,s MSB of length have anything? + beq Read4F4 no, skip ahead + leax >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 +Read4F9 ldu PD.BUF,y get sector buffer pointer clra ldb PD.CP+3,y - leau d,u - negb - sbca #$FF - ldx ,s - cmpd $02,s - bls Read50C - ldd $02,s -Read50C pshs b,a - jsr [$08,s] - stx $02,s +* 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 @@ -747,51 +977,77 @@ andb #^BufBusy stb PD.SMF,y ENDC - ldb $01,s - addb PD.CP+3,y - stb PD.CP+3,y - bne Read530 - lbsr L1237 - inc PD.CP+2,y + 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 - subd ,s++ - std $02,s - jmp [$04,s] +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 + -WriteLn pshs y +* +* I$WritLn Entry Point +* +* Entry: +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* +WriteLn pshs y save PD pointer clrb - ldy R$Y,u - beq WtLn55E - ldx 64k - negb / + negb / invert it sbca #$00 - addd R$Y,u - std R$Y,u -WtLn55E puls y + 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 + -Write ldd R$Y,u - lbsr L0B0C - bcs Writ598 - ldd R$Y,u - beq Writ597 - bsr Writ599 - bcs Writ598 +* +* 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 @@ -809,9 +1065,9 @@ ENDC rts -Writ582 lbsr Read4D3 +Writ582 lbsr Read4D3 go read stuff lbne Read4D9 - leas $08,s + leas $08,s skip stuff on stack ldy PD.Exten,y lda #$01 lbsr L0AD1 @@ -819,61 +1075,81 @@ Writ597 clrb Writ598 rts -Writ599 addd PD.CP+2,y - tfr d,x - ldd PD.CP,y +* 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 + adcd #0 add in any carry from above ELSE adcb #0 adca #0 ENDC -Writ5A3 cmpd PD.SIZ,y - bcs Writ597 - bhi Writ5AF - cmpx PD.SIZ+2,y - bls Writ597 -Writ5AF pshs u - ldu PD.SIZ+2,y - stx PD.SIZ+2,y - ldx PD.SIZ,y - std PD.SIZ,y - pshs u,x - lbsr L0C6F - puls u,x - bcc Writ5C9 - stx PD.SIZ,y +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 +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 +Gst5FF rts return * SS.POS * Entry A=path num * B=$05 * Exit X=msw of pos * U=lsw of pos -Gst600 cmpb #SS.POS - bne Gst60D +Gst600 cmpb #SS.POS is it SS.Pos? + bne Gst60D no, keep checking IFNE H6309 - ldq PD.CP,y +* 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 - std R$X,u - ldd PD.CP+2,y - std R$U,u + 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 @@ -918,18 +1196,18 @@ * R$B = SS.FD ($0F) * R$X = ptr to 256 byte buffer * R$Y = # of bytes of FD required -Gst60D cmpb #SS.FD - bne Gst627 - lbsr RdFlDscr - bcs Gst5FF - ldu PD.RGS,y - ldd R$Y,u - tsta - beq Gst620 - ldd #$0100 -Gst620 ldx R$X,u - ldu PD.BUF,y - lbra Read4AF +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 # @@ -938,86 +1216,111 @@ * R$Y = msb - Length of read * lsb - MSB of LSN * R$U = LSW of LSN -Gst627 cmpb #SS.FDInf - bne Gst640 - lbsr L1237 - bcs Gst5FF - ldb R$Y,u - ldx R$U,u - lbsr L113A +Gst627 cmpb #SS.FDInf SS.FDInf? + bne Gst640 no, let driver handle it + lbsr L1237 check for sector flush bcs Gst5FF - ldu PD.RGS,y - ldd R$Y,u - clra - bra Gst620 -Gst640 lda #D$GSTA - lbra L113C + 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 + -SetStat ldb R$B,u - cmpb #SS.OPT - bne Sst659 - ldx R$X,u - leax $02,x - leau PD.STP,y - ldy #(PD.TFM-PD.STP) - lbra Writ5CB -Sst659 cmpb #SS.Size +* +* 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 + ldd PD.FD+1,y is there a file descriptor? bne Sst669 tst PD.FD,y - lbeq Sst7A8 -Sst669 lda PD.MOD,y - bita #WRITE. - beq Sst697 - ldd R$X,u - ldx R$U,u + 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 -Sst67F lbra Writ5A3 +* 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 + lbsr L0EFE delete from end of the file puls u,x - stx PD.CP,y + stx PD.CP,y restore current position stu PD.CP+2,y rts -Sst697 comb - ldb #E$BMode -Sst69A 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 - bne Sst6D9 +Sst69B cmpb #SS.FD is it SS.FD? + bne Sst6D9 no, keep checking lda PD.MOD,y - bita #WRITE. - beq Sst697 - lbsr RdFlDscr - bcs Sst69A - pshs y - ldx R$X,u - ldu PD.BUF,y - ldy y; memadd to regs.U - bcs Sst7AB - stu PD.Exten,y - clr PE.SigID,u - sty PE.PDptr,u - stu PE.Wait,u - ldx PD.RGS,y - ldx R$X,x + + +* Find a file in current data/execution directory +* Called by Create/Open & Delete +* +* Entry: U=caller's stack reg. ptr +* Y=Path dsc. ptr +FindFile ldd #$0100 get size of sector +* Note, following line is stb PD.SMF,y in v30! + stb PD.FST,y clear state flags?? + os9 F$SRqMem request a 256 byte sector buffer + bcs Sst7AB couldn't get memory, return with error + stu PD.BUF,y save ptr to sector buffer + leau ,y point U to path descriptor + ldx L0012,pcr confusion reigns supreme here, +Sst81E ldu PD.DEV,y get pointer to device table + stu PD.DVT,y copy it for user + lda PD.DRV,y get drive # + ldb >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 - addd V$STAT,u - addd #DRVBEG - std PD.DTB,y - lda ,s - anda #$7F - cmpa #'@ - bne Sst83F - leax $01,x - bra Sst861 -Sst83F lbsr L1110 - lbcs L0915 - ldu PD.BUF,y - ldd DD.DSK,u - std PD.DSK,y - ldd PD.FD+1,y - bne Sst861 + 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 - sta PD.FD,y + 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 +Sst861 stx $04,s save pointer to pathname stx $08,s -Sst865 lbsr L1237 - lbcs L0915 + +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 - anda #$7F - cmpa #'@ - beq Sst87B - lbsr RdFlDscr - lbcs L0915 -Sst87B lbsr L0A2A - lda ,s - cmpa #'/ - bne L08EF + cmpa #PDELIM was the trailing character a slash? + bne L08EF no, skip ahead clr $02,s clr $03,s - lda PD.MOD,y - ora #DIR. - lbsr ChkAttrs - bcs L090D - lbsr Open1CE - ldx $08,s - leax $01,x - lbsr GtDvcNam - std ,s - stx $04,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 - bcs L090D + ldy $06,s get path descriptor pointer + bcs L090D error in pathname, return pshs u,y - ldu PD.Exten,y - leau PE.FilNm,u - clra - tfr d,y - lbsr Writ5CB + 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 + lbsr L0957 read in a directory sector bra L08C1 -L08BC bsr L0918 + +* Scan diretory for name +L08BC bsr L0918 get file descriptor IFNE H6309 -L08BE bsr L0942 +L08BE bsr L0942 get next directory entry from drive ELSE L08BE lbsr L0942 ENDC -L08C1 bcs L090D - tst ,x - beq L08BC +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 - leax PE.FilNm,x - lbsr L09BF - ldx $06,s + 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 - bsr L0926 + 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 - lbra Sst865 + lbsr L0A90 check record lock? + lbra Sst865 go try again L08EF ldx $08,s - tsta - bmi L08FC - os9 F$PrsNam - leax ,y + 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 @@ -1309,13 +1637,14 @@ ldb #E$PNNF L0915 coma bra L08FF + L0918 pshs d lda $04,s - cmpa #'/ + cmpa #PDELIM beq L0940 ldd $06,s bne L0940 - bra L0928 fewer clock cycles + bra L0928 fewer clock cycles L0926 pshs d L0928 stx $06,s lda PD.FD,y @@ -1323,7 +1652,7 @@ ldd PD.FD+1,y std PD.DFD+1,y IFNE H6309 - ldq PD.CP,y was ldd,std here + ldq PD.CP,y stq PD.DCP,y ELSE ldd PD.CP,y @@ -1332,35 +1661,36 @@ std PD.DCP+2,y ENDC L0940 puls pc,b,a -L0942 ldb PD.CP+3,y - addb #DIR.SZ - stb PD.CP+3,y - bcc L0957 - lbsr L1237 + +* 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 - lbsr RdLn473 - bcs L097E - ldd #DIR.SZ +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 - lda PD.SMF,y - bita #SINBUF - bne L0977 + 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 - lda PD.BUF,y - tfr d,x - clrb -L097E rts +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 @@ -1369,24 +1699,23 @@ os9 F$LDABX puls pc,u,x,b -* -GtDvcNam os9 F$PrsNam - pshs x - bcc L09B7 - clrb -L0992 pshs a - anda #$7F - cmpa #'. - puls a - bne L09AD - incb +GtDvcNam os9 F$PrsNam parse the filename + pshs x preserve pointer to name + bcc L09B7 no error, check name length & return + clrb clear a counter flag +L0992 pshs a preserve last character + anda #$7F clear high bit of last character + cmpa #'. is it current data directory? + puls a restore last character + bne L09AD no, skip ahead + incb flag it's a dir leax 1,x - tsta - bmi L09AD - bsr L097F - cmpb #$03 - bcs L0992 - lda #'/ + tsta is it the last character of pathname? + bmi L09AD yes, skip ahead + bsr L097F get next character + cmpb #$03 third character of DIR? + bcs L0992 no, try again + lda #PDELIM decb leax -3,x L09AD tstb @@ -1394,70 +1723,77 @@ L09B0 comb ldb #E$BPNam puls pc,x -L09B5 leay ,x -L09B7 cmpb #DIR.FD-DIR.NM this IS correct, 33 was wrong! - bhi L09B0 - andcc #^Carry - puls pc,x +L09B5 leay ,x +L09B7 cmpb #DIR.FD-DIR.NM past maximum size of name? + bhi L09B0 yes, return error + andcc #^Carry clear error status + puls pc,x return +* Check for a match of 2 names +* Entry: Y=Pointer to high bit terminated string #1 +* X=Pointer to string #2 +* B=Length of string #1 L09BF pshs y,x,b,a -L09C1 lda ,y+ - bmi L09D1 - decb - beq L09CE +L09C1 lda ,y+ get a byte from #2 + bmi L09D1 last one, skip ahead + decb done length? + beq L09CE yes, return no match eora ,x+ - anda #$DF - beq L09C1 -L09CE comb - puls pc,y,x,b,a + anda #$DF match from #1? + beq L09C1 yes, check next char +L09CE comb set carry + puls pc,y,x,b,a return -L09D1 decb - bne L09CE +L09D1 decb decrement length + bne L09CE not done, return no match eora ,x anda #$5F bne L09CE - clrb + clrb clear carry for match puls pc,y,x,b,a -* -ChkAttrs tfr a,b - anda #(EXEC.!UPDAT.) - andb #(DIR.!SHARE.) - pshs x,b,a - lbsr RdFlDscr - bcs L0A0C - ldu PD.BUF,y - ldx 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 - ldb V.MapSct,x + bne L0E26 no, skip ahead + ldb V.MapSct,x another check cmpb DD.MAP,x bcs L0E34 -L0E26 ldd DD.DSK,x - std V.DiskID,x - lda DD.MAP,x - sta V.BMapSz,x + +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 -L0E34 incb - stb 6,s - ldx PD.DTB,y - cmpb V.ResBit,x - beq L0E70 - lbsr L1091 + 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 - cmpb 4,s - bls L0E51 - clra - ldb 5,s - bra L0E54 + 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 - leau d,x - ldy $0C,s +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 + clrd at starting bit number 0 ELSE clra clrb ENDC os9 F$SchBit - bcc L0E9D - cmpy 8,s - bls L0E70 - sty 8,s - std $0A,s - lda 6,s - sta 7,s -L0E70 ldy <$10,s - ldb 6,s - cmpb 4,s - bcs L0E81 - bhi L0E80 - tst 5,s - bne L0E81 + 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 - cmpb V.MapSct,x - bne L0E34 - ldb 7,s - beq L0EF0 - cmpb 6,s - beq L0E96 - stb 6,s - lbsr L1091 -L0E96 ldx PD.BUF,y - ldd $0A,s - ldy 8,s -L0E9D std $0A,s - sty 8,s - os9 F$AllBit - ldy $10,s - ldb $06,s - lbsr L1069 - bcs L0EF2 - ldx PD.DTB,y - lda 6,s - deca - sta V.MapSct,x +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 lsb a forced 0,msb->carry - rolb but carry out of a to lsb - lsla now 2 lsb of a=%00 - rolb and top 2 bits of a now in b - lsla 3 cleared bits - rolb and 3 roll-ins - stb PD.SBP,y <$16,y - ora $0A,s - ldb $0B,s - ldx 8,s - ldy $10,s - std PD.SBP+1,y - stx PD.SSZ+1,y - ldd 2,s + 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 - rol PD.SBP+1,y + +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 + rol PD.SSZ+1,y shift segment cluster size to sector size L0EE6 IFNE H6309 lsrd @@ -2106,22 +2503,28 @@ rorb ENDC bcc L0ED7 - clrb - ldd PD.SSZ+1,y - bra L0EFA + + 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 - lbsr L1070 +L0EF2 ldy $10,s get old Y off of the stack + lbsr L1070 return allocation bitmap? coma -L0EFA leas $0E,s +L0EFA leas $0E,s skip 12-byte buffer, and D puls pc,u,y,x -L0EFE clra - lda PD.MOD,y - bita #DIR. #$80 - bne L0F6F + +* 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 - stq PD.CP,y + 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 @@ -2133,23 +2536,24 @@ lbsr L0B1B bcs L0F6E lbsr L0CDF - bne L0F6F - lbsr L10B2 + bne L0F6F exit + lbsr L10B2 find a segment bcc L0F26 - cmpb #E$NES + cmpb #E$NES non-existing segment error bra L0F67 -L0F26 ldd PD.SBL+1,y + +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 - beq L0F35 + tst PD.CP+3,y on a sector boundary? + beq L0F35 yes, skip ahead IFNE H6309 - decd ok here, carry NOT used below + decd ok here, carry NOT used below ELSE subd #$0001 ENDC L0F35 pshs d - ldu PD.DTB,y + ldu PD.DTB,y number of sectors per cluster ldd DD.BIT,u IFNE H6309 decd @@ -2172,10 +2576,11 @@ std PD.SBP+1,y bcc L0F5F inc PD.SBP,y -L0F5F bsr ClrFBits +L0F5F bsr ClrFBits delete a segment bcc L0F70 leas 4,s - cmpb #E$IBA + cmpb #E$IBA illegal block address + L0F67 bne L0F6E L0F69 lbsr RdFlDscr bcc L0F79 @@ -2188,28 +2593,28 @@ std FDSL.B,x L0F79 ldu PD.BUF,y IFNE H6309 - ldq PD.SIZ,y $0F,y - stq FD.SIZ,u $09,u + 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 $0F,y - std FD.SIZ,u $09,u - ldd PD.SIZ+2,y $11,y - std FD.SIZ+2,u $0B,u + ldd PD.SIZ,y + std FD.SIZ,u + ldd PD.SIZ+2,y + std FD.SIZ+2,u ENDC - tfr x,d fixes d + tfr x,d clrb inca - leax FDSL.S,x + 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 + ldd -FDSL.S,x grab stuff from the last segment std PD.SBP,y lda -FDSL.B,x - sta PD.SBP+2,y - bsr ClrFBits + sta PD.SBP+2,y save sector beginning physical sector number + bsr ClrFBits delete a segment bcs L0FC9 stx 2,s lbsr RdFlDscr @@ -2221,16 +2626,16 @@ clra clrb ENDC - std -$05,x is this "-FDSL.?" stuffs + 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 + leax FDSL.S,x go to the next segment cmpx ,s - bcs L0F8E -L0FC1 + bcs L0F8E if not done, do another +L0FC1 equ * IFNE H6309 clrd ELSE @@ -2238,15 +2643,28 @@ clrb ENDC sta PD.SSZ,y - std PD.SSZ+1,y + std PD.SSZ+1,y segment size is zero L0FC9 leas 4,s rts -ClrFBits pshs u,y,x,a +* 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 + decd ELSE subd #$0001 ENDC @@ -2256,12 +2674,13 @@ bcc L0FF4 inc PD.SBP,y bra L0FF4 -L0FE5 lsr PD.SBP,y + +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 +L0FF4 equ * IFNE H6309 lsrd ELSE @@ -2269,6 +2688,7 @@ rorb ENDC bcc L0FE5 + clrb ldd PD.SSZ+1,y beq L1034 @@ -2276,7 +2696,7 @@ IFNE H6309 lsrd lsrd - lsrd + lsrd get cluster byte number into D ELSE lsra rorb @@ -2287,85 +2707,89 @@ ENDC tfr b,a ldb #E$IBA - cmpa DD.MAP,x - bhi L1033 + 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 +L1012 bsr L1036 flush the sector, and OWN the bitmap bcs L1012 - ldb ,s - bsr L1091 + ldb ,s grab the sector number + bsr L1091 go read a sector fro the allocation bitmap bcs L1033 - ldx PD.BUF,y - ldd PD.SBP+1,y - anda #$07 - ldy PD.SSZ+1,y - os9 F$DelBit + 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 - bsr L1069 - bcc L1034 + 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 - bra L1043 + +L1036 lbsr L1237 flush the sector to disk + bra L1043 skip ahead -L103B lbsr L0C56 - os9 F$IOQu - bsr L1053 -L1043 bcs L1052 - ldx PD.DTB,y - lda V.BMB,x - bne L103B - lda PD.CPR,y - sta V.BMB,x +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 - -L1053 ldu