*================================================================* * * * Position Function handler * * * *================================================================* * * * The position function handler (FNPOSN, $AD12) is simply * * used to adjust the filepointer. This function is used * * sparingly by DOS. As a matter of fact, FNPOSN is only called * * by READ (CMDREAD, $A510) and WRITE (CMDWRITE,$A51B) commands * * that are accompanied by R(ecord number) and/or B(yte) * * parameters. (Even the POSITION command does not use the * * position function.) In an earlier version of DOS 3.3, FNPOSN * * was used to back the file pointer up when a end-of-file marker * * was detected via the APPEND command. However, APPEND now * * adjusts the filepointer manually. * * * *----------------------------------------------------------------* (AD12) FNPOSN JSR CALCFPTR ;Using R-, L-, & B-parameters, calculate ;the position of the file pointer. * Calculate the exact position of the three-byte file pointer: * FILPTSEC = sector offset (low/hi format) into entire file (2 bytes). * FILPTBYT = byte offset into current sector (1 byte). * All three bytes define the exact position of the file pointer * via the following formula: * (record number * record length) + byte offset into record * where: RECNMBFM = record number from R-parameter (set * by user when using random access files * or simply incremented when using other * file types). * RECLENWA = record length parsed from L-parameter * and assigned with open command (else * defaulted to a size of 1). * BYTOFFFM = offset into the current record (set by * user when using open command or * occassionally used with sequential files * as a B-parameter). * Note that you can actually directly access any byte in any * file by bypassing the command interpreter and setting the * L-, B- & R-parameters however you want. (B300) CALCFPTR LDA RECNMBFM ;Put record # in multiplier and STA FILPTBYT ;also save it in the work area. STA RECNMBWA LDA RECNMBFM+1 STA FILPTSEC STA RECNMBWA+1 LDA #0 ;Zero out the hi order byte of the sector (B314) STA FILPTSEC+1 ;offset into the file. * Calculate: Record number * record length. * This routine simply multiplies two 16-bit * numbers together. It may at first seem * confusing because FILPTSEC & FILPTBYT * are both used for holding the multiplier * (record #) and part of the product result. * However, the bits of the product don't get mixed * up with the bits of the multiplier because rolling * in a product bit also rolls out the last-used * multiplier bit (ie. there is no bit overlap). (B317) LDY #16 ;16 bits / one 2-byte number. NMBXLEN TAX ;Save part of running product. ;(On first entry, set (x) = 0.) LDA FILPTBYT ;Set (a) = multiplier. LSR ;Put multiplier bit in carry. BCS NMBXLEN1 ;If (c)=1, go add multiplicand to running product. TXA ;(a) = part of running product. BCC NMBXLEN2 ;Always branch. No use adding multiplicand cause ;bit of multiplier is 0. Therefore, just go shift ;running product. NMBXLEN1 CLC ;Add multiplicand to running version of shifted product. LDA FILPTSEC+1 ADC RECLENWA STA FILPTSEC+1 TXA ;Set (a) = low byte of running product. ADC RECLENWA+1 NMBXLEN2 ROR ;Shift the running product (as a unit) 1 bit ROR FILPTSEC+1 ;position right for next time around. ROR FILPTSEC ;Shift lower 2 bytes of running product and ROR FILPTBYT ;at the same time throw out the last-used ;multiplier bit. DEY ;Reduce bit counter. (B33C) BNE NMBXLEN ;Branch if haven't done all 16 bits yet. * Copy byte offset into record from * the FM parameter list to the work area. (B33E) CLC LDA BYTOFFFM (B342) STA BYTOFFWA * Calculate lowest order byte of file pointer. * BYTOFFWA = offset into current record. * = byte offset into record * + (record length * record number). (B345) ADC FILPTBYT STA FILPTBYT LDA BYTOFFFM+1 STA BYTPFFWA+1 ADC FILPTSEC STA FILPTSEC BCC CALCRTS INC FILPTSEC+1 CALCRTS RTS (B35C) (AD15) JMP GOODFMXT ;Go exit the file manager. ------------ (B37F) GOODFMXT LDA RTNCODFM CLC ;(c) = 0 to signal good operation. BCC FMEXIT BADFMXIT SEC ;(c) = 1 to signal unsuccessful. FMEXIT PHP ;Save status on stack. STA RTNCODFM ;Store return code in FM parameter list. LDA #0 ;Avoid that infamous $48 bug. STA STATUS (B38E) JSR CPYFMWA ;Copy work area to the work buffer. * Copy the FM work area buffer (non-chain) * to the FM work buffer (in DOS chain). (AE7E) CPYFMWA JSR SELWKBUF ;Select the FM work buffer (in DOS chain). * Point the A4L/H pointer at the FM work buffer. (AF08) SELWKBUF LDX #0 ;Set index to select FM work buffer. (AF0A) BEQ PT2FMBUF ;ALWAYS. (AF12) PT2FMBUF LDA WRKBUFFM,X ;Get address of selected buffer from the STA A4L ;FM parameter list and put it in the pointer. LDA WRKBUFFM+1,X STA A4L+1 (AF1C) RTS (AE81) LDY #0 ;Initialize index. STORWRK LDA FMWKAREA,Y ;Get byte from the FM work area. STA (A4L),Y ;Put it in the work buffer. INY CPY #45 ;45 bytes to copy (0 to 44). BNE STORWRK (AE8D) RTS (B391) PLP ;Retrieve status of success of operation ;back from the stack. (B392) LDX STKSAV ;Adjust the stack pointer to force exit TXS ;to the caller of the function even if we (B396) RTS ;are presently several subroutines deeper ============ ;than the original entry point. (Returns ;to AFTRFUNC ($A6AB) in the FMDRIVER routine ;($A6A8).)