>HADFS6 v.5.61 ( OSGBPB - Multibyte data read/write ( ================================== (* v5.28 len does not have to be addr+4 2) v5.52 Bugfixed missing TYA in RWSub <2 v5.53 Tidying up and checking for 16M+ disks F: Pable%=able%64: Fast GBPB Z "Assembling S.HADFS6" dO%=P%-Block%+mcode% n [OPT0 x*\.gbpb0:\RTS:\ In previous source file : ,\ ====================================== ,\ OSGBPB - Multiple byte data read/write ,\ ====================================== .gbpb CMP #0:BEQ gbpb0 CMP #12:BCS gbpb0 >JSR GrabAbs :\ Ensure we have workspace "STX blk+0:STY blk+1:STA argnum LDY #12 .gbpbSetPtr 4LDA (blk),Y:STA ptrstore-9,Y :\ ptrstore=new DEY:CPY #8:BNE gbpbSetPtr LDA argnum BCMP #5:BCC P%+5:JMP gbpbInfo :\ Function 5+ - read disk info LDA (blk),Y "KBEQ P%+5:JMP gbpbExit :\ num>16M, can't transfer all in one go ,4JSR GetChn :\ A=channel, Y=0 65LDX argnum:CPX #3:BCS gbpbIn :\ 3,4 - Read data @6JSR CheckOutput:BNE gbpbNext :\ 1,2 - Write data J .gbpbIn TJSR CheckInput ^0.gbpbNext :\ X=>channel h ? OBCC gbpbTooMany:LDY #5 :\ +num>, jump to do num=- .gbpbSetTrans OLDA (blk),Y:STA ptrstore-5,Y :\ +num<=, use requested num OINY:CPY #9:BNE gbpbSetTrans :\ ptrstore=number to transfer =CLC:BCC gbpbInfo :\ CLC=not .gbpbTooMany SEC LLDA WS+&09,X:SBC WS+&05,X:STA ptrstore+0 :\ +num>, use - instead &,LDA WS+&0A,X:SBC WS+&06,X:STA ptrstore+1 0,LDA WS+&0B,X:SBC WS+&07,X:STA ptrstore+2 :VLDA WS+&0C,X:SBC WS+&08,X:STA ptrstore+3 :\ ptrstore=end-, number to transfer D9SEC :\ SEC= N .gbpbInfo XHPHP:LDY #5:LDA (blk),Y:STA len+0:DEY :\ len+0 set for gbpb5+ b.gbpbAddrLp lHLDA (blk),Y:STA addr-1,Y:DEY:BNE gbpbAddrLp :\ Copy address to addr vbTXA:PHA:JSR CheckAddr:PLA:TAX :\ Page requested memory in, preserve X=>chaninfo : LDA argnum:ASL A:TAY "LDA gbpbTable-2,Y:STA argtmp+0 "LDA gbpbTable-1,Y:STA argtmp+1 HLDA argnum:PLP:JSR JumpAT:LDY #4 :\ Call GBPB subroutine .AddrToCtrlLp ^LDA addr-1,Y:STA (blk),Y:DEY:BNE AddrToCtrlLp:\ Copy updated address back to control block  .gbpbExit "LDA #0:LDX blk+0:LDY blk+1:RTS .JumpAT:JMP (argtmp) : .gbpbTable $EQUW gbpb1:EQUW gbpb2:EQUW gbpb3 $EQUW gbpb4:EQUW gbpb5:EQUW gbpb6  $EQUW gbpb7:EQUW gbpb8:EQUW gbpb9 EQUW gbpb10:EQUW gbpb11  : *"\ On entry to OSGBPB routines, 4A\ addr =data address (forced to I/O if no Tube or screen) >(\ ?len =number byte 0 for gbpb5+ H;\ ptrstore=number to transfer for gbpb1-4, always <16M R)\ X =>channel info for gbpb1-4 \\ Y =corrupted f\ A =function p\ Cy = flag z\ On exit, (\ control block num and ptr updated \ Cy = flag \ A,X,Y ignored : 4\ ---------------------------------------------- 4\ OSGBPB 1,2,3,4 - Write and Read multiple bytes 4\ ---------------------------------------------- .gbpb1:.gbpb2:.gbpb3:.gbpb4 4PHP:LDY #3 :\ Save flag  .RWlp1 4LDA ptrstore,Y:PHA:DEY:BPL RWlp1 :\ Save number ELDA WS+&05,X:BEQ RWZero :\ Already on a sector boundary ILDA #0:SEC:SBC WS+&05,X:STA len+0 :\ Number of bytes to end of sector  LDA ptrstore+1:A ptrstore+2 HA ptrstore+3:BNE RWok :\ More than one sector to transfer @LDA ptrstore+0:CMP len+0:BCS RWok :\ number > remainder here $9STA len+0 :\ Use this instead . .RWok 8NJSR RWBytes:BEQ RWFinished :\ Now at sect boundary, jump if no more B .RWZero LAJSR FindSector :\ sect=next sector in file VNLDA ptrstore+2:STA len+2 :\ len+1/2=number of sectors to transfer `LDA ptrstore+1:STA len+1 jFLDY argnum:CPY #3:LDA #0:ADC #&FF :\ Convert Y=1/2, 3/4 -> A=FF/00 tSTA action ~[TXA:PHA:JSR DiskMainGBPB:PLA:TAX :\ Transfer whole sectors, allowed to corrupt A,X,Y,P CLC FLDA ptrstore+1:ADC WS+&06,X:STA WS+&06,X :\ =+number transfered ,LDA ptrstore+2:ADC WS+&07,X:STA WS+&07,X ^LDA ptrstore+3:ADC WS+&08,X:STA WS+&08,X :\ ptrstore=length-first, ie ?ptrstore=remainder MLDA ptrstore:JSR RWBytesA :\ Transfer any remaining bytes .RWFinished  LDY #0  .RWlp2 ?PLA:STA ptrstore,Y:INY:CPY #4:BNE RWlp2 :\ Restore number  INY:SEC  .RWSub JLDA (blk),Y:SBC ptrstore-5,Y :\ num=num-actual transfered &STA (blk),Y:INY:TYA: #9:BNE RWSub  7LDA argnum:CMP #3:BCS RWEnd :\ Read, all done =PLP:BCC RWEnd1 :\ Write at , all done : (-\ Write remaining bytes, extending past 2 .RWLast PLA:SBC #0:STA ptrstore+1 :\ num=num-number transfered 0PLA:SBC #0:STA ptrstore+2 :PLA:SBC #0:STA ptrstore+3 DA ptrstore+2:A ptrstore+1 NCA ptrstore+0:RTS :\ Return EQ if nothing left to do X: b.RWBytesIO l?JSR ScreenOn:JSR GetChn:TAY :\ Allowed to corrupt A,Y,X,P vLDX #addr:LDA argnum CMP #3:BCS RWLoadLp  .RWSaveLp 9LDA (0,X):SEC:JSR putget1 :\ bput without GrabAbs #JSR UpdateCounters:BNE RWSaveLp BEQ RWBytesEnd :  .RWLoadLp 9CLC:JSR putget1:STA (0,X) :\ bget without GrabAbs #JSR UpdateCounters:BNE RWLoadLp .RWBytesEnd ?JSR ScreenOff :\ Allowed to corrupt A,Y,X,P JMP RWBytesDone : .UpdateCounters  =LDA #1:JSR gbpbUpd:DEC len+0:RTS:\ addr=addr+1, len=len-1 :  : **\ ------------------------------------ 4*\ OSGBPB 5,6,7 - Read disk information >*\ ------------------------------------ H.gbpb5:.gbpb6:.gbpb7 RPHA \;JSR CheckContext :\ Ensure a valid context f9JSR GetOptNum :\ Ensure usernum valid pCJSR CheckNames2 :\ Ensure context names in memory zLDX #0:LDY #0 ?PLA:CMP #6:BCS gbpb67 :\ Jump to read dir/lib names =LDA #16:JSR CopyInfo :\ Copy disk name to buffer 0JSR GetOptNum2:JSR PutInInfo :\ Boot option 1LDA CSD+d:JSR PutInInfo :\ Drive number  \ A=9 - read 00 B\ A=10 - read 00 U\ A=11 - read 00 D\ N\ A=12 - read 00 \ "\ A=9,10,11, XY+0 =0 - use CSD :\ XY=0<>0 - use directory on opened channel \ \ On entry, addr =address +\ len =number to transfer \ ptrstore=index 3\ Uses ptrstore?0 = ret - returned index "2\ ptrstore?1 = index - current index ,9\ ptrstore?2 = fcnt - number of items done 6:\ ---------------------------------------------------- @.gbpb9:.gbpb10:.gbpb11 JCMP #10:BCS gbpb9null T3:]: _NoGBAddr%=0:z%=P%-gbpb9:P%=P%-z%:O%=O%-z% ^1JSR GetChn:BEQ gbpb8 :\ Channel=0, use CSD h4JSR CheckChannel :\ Point to channel info r3 #&10:BNE gbpb8a :\ Is a directory, use it |MJMP errNotDir :\ Otherwise, error (this gives XXX is not a dir) : .gbpb8 6LDX #CSD-(WS+1) :\ GBPB 8 always reads CSD .gbpb8a 3JSR CheckContext :\ Ensure context valid 3JSR GetOptNum:LDY #3 :\ Ensure usernum valid .gbpb8lp1 4LDA WS+4,X:STA sect,Y :\ sect=directory to use DEX:DEY:BPL gbpb8lp1 /LDA ret:STA index :\ Initialise index 1LDA #0:STA fcnt :\ Nothing transfered 9JSR GetDir :\ Load first directory chunk :  .gbpb8dir >JSR dirInit:BEQ gbpb8MT :\ Directory empty, Y=0, A=files 3LDA HDR+&0D:STA (blk),Y :\ Store cycle number & .gbpb8lp2 0>JSR dirNext:BEQ gbpb8next :\ Empty directory entry ::JSR DoIOwn:BPL gbpb8own :\ I own all entries DJLDY #7:LDA (fptr),Y:BMI gbpb8step :\ Private entry, step to next entry N .gbpb8own XRLDX index:BEQ gbpb8found :\ index=0, use this entry, X=>start of info b DEC index l.gbpb8step v DEC files .gbpb8next ;LDA files:BNE gbpb8lp2 :\ Step to next entry .gbpb8MT MJSR NextChunk:BNE gbpb8dir :\ Load next chunk, loop until all done 8JSR gbpb8counter:SEC:RTS :\ No more entries : .gbpb8found .z% :LDA argnum: #2:BEQ gbpb8name :\ 8,9 - no info block CLDA blk+1:PHA:LDA blk+0:PHA :\ Save control block pointer CLDA #&0E:STA blk+1:LDA #&FE:STA blk+0 :\ Point to our workspace CJSR ConvertBlk0 :\ Get object information FPLA:STA blk+0:PLA:STA blk+1 :\ Restore control block pointer (TXA:STA &F10:LDY #0 :\ Object .gbpb8lp3 5LDA #0:STA &F11,Y :\ Clear object b8-b31 8LDA &F04,Y:STA &F18,Y :\ Copy exec to timestamp *INY:CPY #5:BNE gbpb8lp3 47LDA &F00:STA &F1C:LDY #22 :\ Top byte of timestamp > .gbpb8lp4 H(LDA (fptr),Y:STA &F14-22,Y :\ Sector RINY:CPY #25:BNE gbpb8lp4 \LDA HDR+&0C: #&80 f9BMI P%+5:STA &F16 :\ SmallDir sector b16-b23 p5LDA drive:STA &F17 :\ Sector drive number z.:]: _NoGBAddr%:z%=P%-z%:P%=P%-z%:O%=O%-z% : .gbpb8name LDY #0:LDA argnum DCMP #9:PHP:BEQ gbpb8lp5 :\ GBPB 9 - store name at offset 0 INX .z% DBCC gbpb8lp5 :\ GBPB 8 - store name at offset 1 GLDX #&14:CMP #10:BEQ gbpb8lp5 :\ GBPB 10 - store name at offset &14 GLDX #&1D :\ GBPB 11 - store name at offset &1D .:]: _NoGBAddr%:z%=P%-z%:P%=P%-z%:O%=O%-z% : .gbpb8lp5 7LDA (fptr),Y: #127 :\ Get filename character ,CMP #"!":BCC gbpb8send :\ End of name +STA &F00,X:INX:INY :\ Store it ?CPY #10:BNE gbpb8lp5 :\ Loop for up to 10 characters $.gbpb8send .APLP:BCS gbpb8send2 :\ GBPB 9,10,11 - zero terminated 89STY &F00:BCC gbpb8send3 :\ GBPB 8 - length prefix B: L.gbpb8send2 V9LDA #0:STA &F00,X:INX :\ Insert zero terminator `.z% j"LDA argnum: #2:BEQ gbpb8send3 t+TXA:ADC #3: #&FC:TAX :\ Word align ~.:]: _NoGBAddr%:z%=P%-z%:P%=P%-z%:O%=O%-z% : .gbpb8send3 $TXA:TAY:LDA len+0:PHA :\ Length 6JSR gbpbLoader :\ Send data to user memory PLA:STA len+0 #INC ret :\ Index to next !INC fcnt :\ Number done "DEC len+0 :\ Number to do LDY #9:LDA ret STA (blk),Y :\ Index JSR gbpb8counter CLC:LDA len+0:BEQ gbpb8end JMP gbpb8next  : .gbpb8counter LDY #5:LDX len+0:LDA argnum ( #3:BEQ gbpb8send4 2ILDX fcnt :\ 9,10,11 give num. returned, not num. not returned <.gbpb8send4 FMTXA:STA (blk),Y :\ Store number not returned (8) or number returned (9+) P .gbpb8end ZRTS d: n5\ PutInInfo and GetChn within fake module headers x: ] $ 11;20,9);O%-mcode%;" bytes" > "S.HADFS7"