💾 Archived View for mirrors.apple2.org.za › archive › www.textfiles.com › apple › ANATOMY › rwtsd1.f… captured on 2024-08-19 at 03:02:34.

View Raw

More Information

⬅️ Previous capture (2023-01-29)

-=-=-=-=-=-=-

             
                                                                  *-----------------------*
                                                                  *                       *
                                                                  * RWTSDRV1 USING FORMAT *
                                                                  *       CONTinued       *
                                                                  *                       *
                                                                  *-----------------------*
                                                                           .
                                                                           .
                                                                           .
                                                                  (BF1F)   BCS VRFYRTN  ;Irrelevant -already chkd write-protect
                                                                                        ;switch when we wrote the address.
                                                                  (BF21)   INC FRMTSEC  ;Increase sec #.
                                                                           LDA FRMTSEC
                                                                           CMP #$10     ;Done all 16 secs yet?
                                                                  (BF27)   BCC FRMTASEC ;No - go do some more.

                                                                  * VERIFY a single track.

                                                                  * Note:  We just finished formatting
                                                                  * sector $0F.  Because sector $OF
                                                                  * shouldn't overwrite too much of the
                                                                  * sync gap (originally 128 syncs long)
                                                                  * that was written prior to sec $00, and
                                                                  * because we don't waste too much time
                                                                  * between writing the last byte of sec $0F
                                                                  * and looking for the next addr header, we
                                                                  * expect to begin our verification with
                                                                  * sec $00.

                                                                  * Initialize counters.
                                                                  (BF29)   LDY #$0F     ;SET COUNTER FOR # OF SECS VERIFIED.
                                                                           STY FRMTSEC
                                                                           LDA #48      ;SET COUNTER FOR # OF ATTEMPTS.
                                                                  (BF2F)   STA READCNTR

                                                                  * Fill sector map with POSITIVE #'s.
                                                                  (BF32)
                                                                  FILSECMP STA SECFLGS,Y
                                                                           DEY
                                                                  (BF36)   BPL FILSECMP

                                                                  * Delay to let some syncs pass by.
                                                                  (BF38)   LDY SYNCNTR  ;Initialize (y).
                                                                  BYPSYNCS JSR VRFYRTN  ;(12 cyc)
                                                                           JSR VRFYRTN  ;(12 cyc)
                                                                           JSR VRFYRTN  ;(12 cyc)
                                                                           PHA          ;(3 cyc)
                                                                           PLA          ;(4 cyc)
                                                                           NOP          ;(2 cyc)
                                                                           DEY          ;(2 cyc)
                                                                  (BF47)   BNE BYPSYNCS ;(3 cyc on branch, 2 on fall thru)

                                                                  * Read address of first sector encountered.
                                                                  * (THIS BETTER BE SECTOR 0!!!!  If it isn't,
                                                                  * our drive is a bit too fast & we will
                                                                  * eventually have to reformat the track.)
                                                                  (BF49)   JSR RDADDR   ;Read addr of first sec encountered.
                                                                                        ;(See dis'mbly below.)
                                                                  (BF4C)   BCS REREADDR ;Bad read, try again.
                                                                           LDA SECDSK   ;Was sec read = sector 0?
                                                                  (BF50)   BEQ RDNXTDAT ;Yes - go read next data sec.
  
                                                                  * DIDN'T FIND SECTOR $00 WHEN EXPECTED.
                                                                  * Drive must be faster than anticipated
                                                                  * because sector $0F overlaid too much of
                                                                  * the long sync gap (gap 1) that was 
                                                                  * originally written before sector $00.
                                                                  * We will have to reformat this track using
                                                                  * 128 self-syncs before sector $00 (gap 1)
                                                                  * and less sync bytes between other sectors
                                                                  * (gap 3).  This will insure that less gap-1
                                                                  * syncs will be overwritten by sector $0F.
                                                                  * Note that, depending on just how much too
                                                                  * fast the drive is, we may have to reformat
                                                                  * this track several times before we get it
                                                                  * right.  Each time we reformat, we reduce
                                                                  * the number of gap-3 syncs.  If the sync
                                                                  * counter is greater than or equal to 16,
                                                                  * we write two less syncs.  If the counter
                                                                  * is less than 16, we only reduce the gap-3
                                                                  * by one sync.  In order to give the machine
                                                                  * time to decode information, we won't
                                                                  * allow a gap less than five syncs long.
                                                                  * (Note that we won't reformat the track
                                                                  * until we find the address header for sec $0F.
                                                                  * This presumably keeps like-numbered sectors
                                                                  * in adjacent tracks in some semblance of order.)
                                                                  (BF52)   LDA #16
                                                                           CMP SYNCNTR  ;Condition carry.
                                                                           LDA SYNCNTR  ;If sync count < 16, subtract 1.
                                                                           SBC #1       ;Else subtract 2.
                                                                           STA SYNCNTR
                                                                           CMP #5       ;Do we have at least 5 syncs?
                                                                           BCS REREADDR ;Yes.
                                                                           SEC          ;No - signal error cause need
                                                                  (BF61)   RTS          ;at least 5 syncs.  Drive is
                                                                           ============ ;so fast that it is out-to-lunch.

                                                                  * Read the sector address.
                                                                  (BF62)
                                                                  RDNXTADR JSR RDADDR   ;Read the address header.
                                                                                        ;(See dis'mbly below.)
                                                                  
                                                                  (BF65)   BCS BADREAD  ;Branch if addr read was bad.

                                                                  * Read the data proper.
                                                                  (BF67)
                                                                  RDNXTDAT JSR READATA  ;Read the actual data bytes.
                                                                  (BF6A)   BCC CKSECMAP ;Read was good so chk if this
                                                                                        ;sec has already been read.

                                                                  (BF6C)
                                                                  BADREAD  DEC READCNTR ;Either got a bad read or else we
                                                                                        ;already verified this sector.
                                                                                        ;Reduce the number of chances left.
                                                                  (BF6F)   BNE RDNXTADR ;More chances left.  Go try again.

                                                                  * Doing a re-read.  Will definitely
                                                                  * have to reformat.
                                                                  (BF71)
                                                                  REREADDR JSR RDADDR   ;See dis'mbly below.
                                                                  (BF74)   BCS NOTLAST  ;Got a bad read.

                                                                  * We will reformat but we don't want
                                                                  * to do so until we read sector $0F.
                                                                  * Have we found sector $0F yet?
                                                                  (BF76)   LDA SECDSK   ;Get phys # of sec just read.
                                                                           CMP #$0F     ;Was it sector 15?
                                                                           BNE NOTLAST  ;No, go look some more.
                                                                  (BF7C)   JSR READATA  ;Yes.  Read the data in sec $0F.
                                                                                        ;(See dis'mbly below.)
                                                                  (BF7F)   BCC FORMATRK ;Good read on sec 15 so now the timing
                                                                  (BF81)                ;is right to GO REFORMAT THIS TRACK.
                                                                  NOTLAST  DEC READCNTR ;Bad read, chk if more chances left.
                                                                           BNE REREADDR ;Yes - go try again.
                                                                           SEC          ;Exhausted all chances, so set
                                                                  VRFYRTN  RTS          ;(c) as error flag & exit.
                                                                  (BF87)   ============

                                                                  * Check if this sector was previously
                                                                  * verified.  If not, update sector
                                                                  * verification map.  (If timing is
                                                                  * right, should never encounter an
                                                                  * already verified sec before FRMTSEC
                                                                  * decrements from $00 to $FF.)
                                                                  (BF88)
                                                                  CKSECMAP LDY SECDSK   ;Use # of sec found as index
                                                                                        ;to the verification map.
                                                                  (BF8A)   LDA SECFLGS,Y ;Get map byte (neg = prev verified).
                                                                           BMI BADREAD  ;Oh Oh!  Already verified this one.
                                                                           LDA #$FF     ;Set byte in map to signal that
                                                                           STA SECFLGS,Y ;this sector was just verified.
                                                                           DEC FRMTSEC  ;Any secs left to verify?
                                                                  (BF96)   BPL RDNXTADR ;Yes - go do some more.

                                                                  * All secs verified. Check if
                                                                  * we just did track $00.
                                                                  (BF98)   LDA FRMTKCTR ;Was trk just formatted = trk $00?
                                                                  (BF9A)   BNE NOTRK0   ;No - so exit cleanly.

                                                                  * Just formatted & verified trk $00.
                                                                  * Trk $00 is the outside track and 
                                                                  * therefore has the largest length
                                                                  * in which to write bytes.  Because
                                                                  * subsequent tracks have a smaller
                                                                  * circumference, we must reduce the
                                                                  * number of syncs to write between
                                                                  * sectors (gap-3) so we can get all
                                                                  * the needed info into a smaller space.
                                                                  (BF9C)   LDA SYNCNTR  ;Check sync count.
                                                                           CMP #16      ;Less than 16 syncs?
                                                                  (BFA0)   BCC VRFYRTN  ;Yes - exit cleanly.
                                                                                        ;Don't want to start off with a
                                                                                        ;smaller gap, so skip the following
                                                                                        ;code which reduces the gap size.

                                                                  * Reduce the size of gap-3.
                                                                  (BFA2)   DEC SYNCNTR  ;Gap > = 16 syncs long, so can afford to
                                                                           DEC SYNCNTR  ;reduce it by two, so can accommodate
                                                                  NOTRK0   CLC          ;a tighter track.  Exit cleanly.
                                                                  (BFA7)   RTS
                                                                           ===========

                                            (BEDC)   LDA #8       ;Set (a) as default value in case
                                                                  ;couldn't format.
                                            (BEDF)   BCS ERRFRMT  ;Branch if couldn't format.

                                            * Do a read of trk just formatted.
                                            * (Eventhough track verified, read
                                            * it again until locate track 0.
                                            * Presumably, this (partially)
                                            * double checks verification and
                                            * keeps sectors in different tracks
                                            * somewhat adjacent?)
                                            (BEE0)   LDA #48      ;Set 48 attempts to read.
                                                     STA READCNTR
                                            RDAGAIN  SEC          ;Default (c)=1 to signal error.
                                                     DEC READCNTR ;Reduce chances to read.
                                                     BEQ ERRFRMT  ;Exhausted all chances.
                                            (BEEB)   JSR RDADDR   ;Go read addr header to find sector
                                                                  ;that we want to read or write.

                                                                  * Read the address header.
                                                                  (B944)
                                                                  RDADDR   LDY #$FC     ;Designate 772 chances (#$FCFC to #$10000) 
                                                                                        ;to find the correct address prologue.
                                                                  (B946)   STY PROSCRTH
                                                                  KICKNTR  INY
                                                                           BNE TRYD5
                                                                           INC PROSCRTH
                                                                  (B94D)   BEQ ERRTN    ;Error - can't find proglogue.

                                                                  * Look for address prologue ("D5 AA 96").
                                                                  (B94F)
                                                                  TRYD5    LDA Q5L,X
                                                                           BPL TRYD5    ;Wait for a full byte.
                                                                  VERSUSD5 CMP #$D5     ;Was it a "D5"?
                                                                           BNE KICKNTR  ;No - try again.
                                                                           NOP          ;Wait 2 cycles.
                                                                  TRYAA    LDA Q6L,X
                                                                           BPL TRYAA    ;Wait for full byte.
                                                                           CMP #$AA     ;Was it an "AA"?
                                                                           BNE VERSUSD5 ;No - retry sequence.
                                                                  (B962)   LDY #3       ;Set (y) for later reading of
                                                                                        ;vol, trk, sec, checksum info
                                                                                        ;from address field.
                                                                  (B964)
                                                                  TRY96    LDA Q6L,X
                                                                           BPL TRY96    ;Wait for full byte.
                                                                           CMP #$96     ;Was it a "96"?
                                                                  (B96B)   BNE VERSUSD5 ;No - retry sequence.

                                                                  * Read odd-even encoded volume, track,
                                                                  * sector and checksum values from the
                                                                  * address field.  (When reading,
                                                                  * calculate a running checksum.)
                                                                  * From: byte1:  1  b7  1 b5  1 b3  1 b1
                                                                  *       byte2:  b6 1  b4 1  b2 1  b0 1
                                                                  *       -------------------------------
                                                                  * To:   byte:   b7 b6 b5 b4 b3 b2 b1 b0

                                                                  (B96D)   LDA #0       ;Initialize running checksum val.
                                                                  CALCK    STA CKSUMCAL
                                                                  GETHDR   LDA Q6L,X    ;Get odd-encoded byte.
                                                                           BPL GETHDR   ;Wait for a full byte.
                                                                  (B976)   ROL          ;Shift bits & put set
                                                                                        ;carry in bit0 pos'n.
                                                                  (B977)   STA PROSCRTH ;Save shifted version.
                                                                  RDHDR    LDA Q6L,X    ;Get even-encoded byte.
                                                                           BPL GETHDR   ;Wait for full byte.
                                                                           AND PROSCRTH ;Merge the bytes to normal.
                                                                  (B980)   STA: CKSUMDSK,Y ;Store info read from addr
                                                                                        ;field in zero page:
                                                                                        ;$2F = vol found, $2E = trk found,
                                                                                        ;$2D = sec found, $2C = checksum found.
                                                                                        ;(Use ":" to force 3-byte instruction.)
                                                                  (B983)   EOR CKSUMCAL ;Update running checksum.
                                                                           DEY
                                                                           BPL CALCK
                                                                           TAY          ;Put checksum found in (y).
                                                                  (B989)   BNE ERRTN    ;If chec sum found < > 0, then error.
                                                                                        ;Hackers often change these two bytes
                                                                                        ;to "CLC" and "RTS" instructions in
                                                                                        ;order to defeat the address checksum
                                                                                        ;and ignore the address epilogue.
         
                                                                  * Read first 2 bytes (only) of
                                                                  * the address epilogue ("DE AA").
                                                                  (B98B)
                                                                  TRYEPIDE LDA Q6L,X    ;Get first byte.
                                                                           BPL TRYEPIDE ;Wait for a full byte.
                                                                           CMP #$DE     ;Was it a "DE"?
                                                                           BNE ERRTN    ;No - try again.
                                                                           NOP          ;Stall 2 cycles.
                                                                  TRYEPIAA LDA Q6L,X    ;Get second byte.
                                                                           BPL TRYEPIAA ;Wait for a full byte.
                                                                           CMP #$AA     ;Was it an "AA"?
                                                                           BNE ERRTN    ;No - retry sequence.
                                                                  GOODRTN  CLC          ;Signal good read.
                                                                  (B99F)   RTS
                                                                           ============

                                                                  (B942)
                                                                  ERRTN    SEC          ;Signal bad read.
                                                                  (B943)   RTS          ;Hackers often change the "SEC" to
                                                                           ============ ;a "CLC" in order to defeat error
                                                                                        ;checking.

                                            (BEEE)   BCS RDAGAIN  ;Bad read - try again.
                                                     LDA SECDSK   ;Was it sector 0?
                                                     BNE RDAGAIN  ;No - try again.
                                            (BEF4)   JSR READATA  ;Last chance to read data.

                                                                  * Read data sector into RWTS's buffers.
                                                                  * Look for data prologue.
                                                                  (B8DC)
                                                                  READATA  LDY #32      ;Set (y) to designate 32
                                                                  REDUCEY  DEY          ;attempts to find data prologue.
                                                                           BEQ ERRTN    ;Error - couldn't find data prologue.
                                                                  PRODATD5 LDA Q6L,X    ;Get byte from data prologue.
                                                                           BPL PRODATD5 ;Wait for a full byte.
                                                                  VERSD5   EOR #$D5     ;Check if byte was a "D5".
                                                                           BNE REDUCEY  ;Wasn't a "D5, reduce counter.
                                                                           NOP          ;Stall 2 cycles.
                                                                  PRODATAA LDA Q6L,X    ;Read next data prologue byte.
                                                                           BPL PRODATAA ;Wait for a full byte.
                                                                           CMP #$AA     ;Was it an "AA"?
                                                                           BNE VERSD5   ;No - restart sequence.
                                                                  (B8F4)   LDY #86      ;Set (y) for later use
                                                                                        ;in the read data routine.
                                                                  (B8F6)
                                                                  PRODATAD LDA Q6L,X    ;Read next byte in data prologue.
                                                                           BPL PRODATAD ;Wait for a full byte.
                                                                           CMP #$AD     ;Was it an "AD"?
                                                                  (B8FD)   BNE VERSD5   ;No - restart search sequence.

                                                                  * Read first 86 bytes of data into
                                                                  * RWTSBUF2 ($BC55 --> $BC00).
                                                                  *
                                                                  * Use disk byte as index to the
                                                                  * NDX2NIBL table which contains
                                                                  * offsets that we would be using
                                                                  * if we were accessing a table
                                                                  * of disk bytes when writing.
                                                                  * (That is, we are just doing
                                                                  * the opposite of writing.)
                                                                  * EOR value from NDX2NIBL table
                                                                  * with the previous EOR result.
                                                                  * (On entry, use #$00 for previous
                                                                  * EOR result.)
                                                                  (B8FF)   LDA #0       ;Initialize (a) for later EORing.
                                                                  RDUCY    DEY          ;Reduce index to RWTSBUF2.
                                                                           STY PROSCRTH ;Save index.
                                                                  RDSKBYT  LDY Q6L,X    ;(y) = disk byte.
                                                                           BPL RDSKBYT  ;Wait for a full byte.
                                                                  (B909)   EOR NDX2NIBL-$96,Y ;Use (y) as index to tbl
                                                                                        ;      of 2-encoded nibbles.
                                                                  (B90C)   LDY PROSCRTH ;Store 2-encoded nibble in RWTSBUF2.
                                                                           STA RWTSBUF2,Y
                                                                  (B911)   BNE RDUCY    ;Conditioned from the "LDY PROSCRTH".

                                                                  * Read rest of sector into RWTSBUF1
                                                                  * ($BB00 --> $BBFF).
                                                                  *
                                                                  * Use disk byte as index to the
                                                                  * NDX2NIBL table which contains
                                                                  * offsets that we would be using
                                                                  * if we were accessing a table
                                                                  * of disk bytes when writing.
                                                                  * (That is, we are just doing
                                                                  * the opposite of writing.)
                                                                  * EOR value from NDX2NIBL table
                                                                  * with the previous EOR result.
                                                                  (B913)
                                                                  SAVYNDX  STY PROSCRTH ;Save index to RWTSBUF1.
                                                                  RDSKBYT2 LDY Q6L,X    ;(y) = disk byte.
                                                                           BPL RDSKBYT2 ;Wait for a full byte.
                                                                           EOR NDX2NIBL-$96,Y ;Get 6-encoded nibble from tbl.
                                                                           LDY PROSCRTH ;Get index to RWTSBUF1.
                                                                           STA RWTSBUF1,Y ;Store 6-encoded nibble in RWTSBUF1.
                                                                           INY
                                                                  (B923)   BNE SAVYNDX  ;More disk bytes to read.

                                                                  * Read the data checksum.
                                                                  (B925)
                                                                  RDCHECK  LDY Q6L,X    ;Get data checksum.
                                                                           BPL RDCHECK  ;Wait for full byte.
                                                                  (B92A)   CMP NDX2NIBL-$96,Y ;Converted checksum = val in $BBFF?
                                                                                        ;Remember:  Val in $#BBFF is result of
                                                                                        ;previous cummulative EORing.  There4,
                                                                                        ;this comparison with (a) detects any
                                                                                        ;(non-cancelling) error(s) that may
                                                                                        ;have occurred in the entire sector!!!
                                                                  (B92D)   BNE ERRTN    ;No - got an error.
                                                                                        ;Hackers often change these two bytes
                                                                                        ;to "CLC" and "RTS" instructions in
                                                                                        ;order to defeat the data checksum
                                                                                        ;and ignore the data epilogue.

                                                                  * Read the first two bytes (only)
                                                                  * of the data epilogue ("DE AA").
                                                                  (B92F)
                                                                  EPIRDDE  LDA Q6L,X    ;Read first byte of data epilogue.
                                                                           BPL EPIRDDE  ;Wait for a full byte.
                                                                           CMP #$DE     ;Was it a "DE"?
                                                                           BNE ERRTN    ;No - got an error.
                                                                           NOP          ;Stall for 2 cycles.
                                                                  EPIRDAA  LDA Q6L,X    ;Read 2nd data epilogue byte.
                                                                           BPL EPIRDAA  ;Wait for a full byte.
                                                                           CMP #$AA     ;Was it an "AA"?
                                                                           BEQ GOODRTN  ;Yes - got a good read.
                                                                  ERRTN    SEC          ;Signal bad read.
                                                                  (B943)   RTS          ;Hackers often change the "SEC" to a
                                                                           ============ ;"CLC" in order to defeat error checking.

                                                                  (B99E)
                                                                  GOODRTN  CLC          ;Signal good read.
                                                                  (B99F)   RTS
                                                                           =============

                                            (BEF7)   BCS RDAGAIN  ;Last chance bombed out!!!
                                                     INC FRMTKCTR ;Kick up trk counter.
                                                     LDA FRMTKCTR ;Set (a) for next trk count.
                                                     CMP #$23     ;Done all trks yet (#0 to #34)?
                                                     BCC FRMNXTRK ;No - GO FORMAT THE NEXT TRACK.
                                                     CLC          ;Signal finished all tracks.
                                            (BF02)   BCC DONEFRMT ;ALWAYS - ONLY GOOD EXIT.
                                                     ------------

                                            * Note:  No matter what kind of error we
                                            * might have encountered when formatting,
                                            * the IOB error code is always set to $08.
                                            * This is later translated to an FM error
                                            * code (also $08) which DOS displays as
                                            * a I/O error message.  (This is why trying
                                            * to format a write-protected disk results
                                            * in a an I/O error message instead of a
                                            * disk-write-protected message.)
                                            * If no error occurred, the IOB error byte
                                            * will be set to some random number (as a result of
                                            * referencing a hardware switch).
                                            (BF04)
                                            ERRFRMT  LDY #13      ;Index to return code in IOB.
                                                     STA (PTR2IOB),Y ;Store return code.
                                                     SEC          ;Signal that an error occurred.
                                            DONEFRMT LDA MTROFF,X ;Turn motor off & exit with (c)
                                            (BF0C)   RTS          ;denoting success status.
                                                     ============

                      (B7BA)   BCS ERRENTER ;Branch if operation unsuccessful.
                               PLP          ;Throw status off stk.
                               CLC          ;Signal successful.
                      (B7BE)   RTS
                               ============

                      (B7BF)
                      ERRENTER PLP          ;Throw status off stk.
                               SEC          ;Signal UNsuccessful.
                      (B7C1)   RTS
                               ============

(B093)   LDA IBSMOD   ;Get vol found from IOB
         STA VOLFM    ;& put it in Fm parm list.
         LDA #$FF     ;Designate vol wanted in
(B09B)   STA IBVOL    ;IOB as 255 for next time.
                      ;(Actually using 0 cause FF EOR FF = 0.)
(B09E)   BCS ERRWTSDR ;Branch if UNsuccessful operation.
(B0A0)   RTS
         =============


(B0A1)
ERRWTSDR LDA IBSTAT   ;Get RWTS'S error code.


(B0A4)   LDY #7       ;Set (y) for FM vol mismatch.
         CMP #$20     ;Vol mismatch?
         BEQ SETFMERR ;Yes.
         LDY #$04     ;No.
         CMP #$10     ;Write protected?
         BEQ SETFMERR ;Yes.
         LDY #8       ;Must have been other, so
SETFMERR TYA          ;designate as general I/O error.
(B0B3)   JMP BADFMXIT ;Go handler error.
         ------------

(B385)
BADFMXIT SEC          ;(c) = 1 to signal UNsuccessful.
FMEXIT   PHP          ;Preserve success of operation on stk.
         STA RTNCODFM ;Put appropriate return code in FM parm list.
         LDA #0       ;Avoid that infamous $48 bug.
         STA STATUS
(B38E)   JSR CPYFMWA

                      (AE7E)
                      CPYFMWA  JSR SELWKBUF

                                            * Point the A4L/H pointer at the DOS work buffer (chain).
                                            (AF08)
                                            SELWKBUF LDX #0       ;Designate work area buffer.
                                            (AF0A)  BEQ PT2FMBUF ;ALWAYS.

                                            (AF12)
                                            PT2FMBUF LDA WRKBUFFM,X ;Get addr of DOS's work buffer
                                                     STA A4L      ;(chain) from FM parm list and put
                                                     LDA WRKBUFFM+1,X ;it in the A4L/H pointer.
                                                     STA A4L+1
                                            (AF1C)   RTS

                      * Copy work area buffer (non-chain)
                      * to DOS work buffer (chain).
                      (AE81)   LDY #0
                      STORWRK  LDA FMWKAREA,Y
                               STA (A4L),Y
                               INY
                               CPY #45
                               BNE STORWRK
                      (AE8D)   RTS

(B391)   PLP          ;Exit with (c) conditioned accordingly.
         LDX STKSAV   ;Reset the stack pointer so execution will
         TXS          ;return to the caller of the function.
(B396)   RTS          ;(Normally returns to AFTRFUNC ($A6AB)
         ============ ;located in the FMDRIVER routine ($A6A8).)