*=================================
*       OTHER ERROR PATCH.
*        ($B65D - $B670)
* - USED WHEN FM DRIVER GETS AN
*   ERROR THAT IS NOT AN OUT-OF-
*   DATA ERROR.
* - ALSO CONTAINS THE APPEND FLAG.
*=================================

APPNDFLG HEX 00 ;APPEND FLAG.

* ERROR WAS DEADLY, SO BETTER
* RELEASE THE FILE'S BUFFER AND
* MAKE SURE THE APPEND FLAG IS OFF.

OTHRERR JSR GETBUFF ;LOCATE BUFFER BELONGING TO THE
;FILE. (PUT ADR IN A3L/H PTR.)
 BCS TOERRMSG ;NO BUFFER WAS ASSIGNED, SO NO
;NEED 2 RELEASE THE FILE'S BUF OR
;TURN OFF THE APPEND FLAG.
 LDA #0 ;ZERO OUT THE APPEND FLAG & SET
 TAY ;(Y) TO NDEX THE 1RST BYTE OF THE
 STA APPNDFLG ;DOS NAME BUFFER.
 STA (A3L),Y ;RELEASE FILE'S DOS BUFFER.
TOERRMSG LDA RTNCODFM ;GET ERROR CODE TO INDEX ERR MSG.
 JMP ERRHNDLR ;EXIT & GO PRINT ERROR MESSAGE.


*=================================
*     PATCH TO HANDLE APPEND.
*        ($B671 - $B685)
*=================================

* PREPARE TO MANUALLY BACK UP THE
* FILE POINTER IF NECESSARY.  NEED
* TO BACK IT UP ONE BYTE IF A $00
* BYTE WAS ENCOUNTERED IN A DATA
* SECTOR.  HOWEVER, IF A ZEROED-
* OUT DATA PAIR (LISTED IN A T/S
* LIST) OR A ZEROED-OUT T/S LINK
* WAS ENCOUNTERED, THEN THE FILE
* POINTER IS POSITIONED CORRECTLY.
* (P.S. AT ONE TIME IN THE HISTORY
* OF DOS, THE POSITION FUNCTION
* WAS USED TO BACK UP THE POINTER.)
* ENTER WITH APPEND FLAG SET IF A
* $00 WAS DETECTED IN A (NON-EMPTY)
* FILE'S T/S LIST.

CKAPFLG LDA APPNDFLG ;IS APPEND FLAG ON?
 BEQ CLRAPFLG ;NO - FLAG IS OFF.
 INC RECNMBFM ;YES -SO INCREMENT THE FILE MGR'S
 BNE CLRAPFLG ;VERSION OF THE RECORD # BECAUSE
 INC RECNMBFM+1 ;RECNMBFM IS POINTING AT THE LAST
;VALID DATA BYTE AND WE WANT IT 2
;POINT AT THE NEXT POTENTIAL
;RECORD NUMBER.  (P.S.  REMEMBER
;THAT RECNMBFM LAGS RECNMBWA BY
;ONE BYTE.)
CLRAPFLG LDA #0 ;DON'T NEED THE APPEND FLAG ANY
 STA APPNDFLG ;MORE, SO TURN IT OFF.
 JMP RSETPTRS ;GO BACK UP THE FILE POINTER.


*==================================
* PATCH TO VERIFY A RANGE-OF-BYTES.
* (CALLED BY RWRANGE TO R/W RANGE
* OF BYTES & THEN VERIFY THE DATA.)
*==================================

VRFYRWNG STA SUBCODFM ;PUT RANGE-OF-BYTES SUBCODE IN
;RWTS'S IOB.
 JSR FMDRIVER ;CALL FM DRIVER TO READ/WRITE A
;RANGE OF BYTES.
 JSR CMDCLOSE ;CLOSE FILE & THEN VERIFY DATA.
 JMP CMDVERFY


*================================
*          APPEND PATCH.
*         ($B692 -$B6B2)
* - USED TO HANDLE AN END-OF-DATA
*   ERROR.
*================================

* THIS PATCH IS DIFFICULT TO UNDER-
* STAND BECAUSE IT IS A PATCH THAT
* HAS BEEN ADDED TO REPAIR PREVIOUS
* PATCHES AND BECAUSE EXECUTION FAILS
* ON OCCASSION.  AS A RESULT, THE APPEND
* COMMAND HAS EVOLVED INTO A CLASSIC
* CASE OF SPAGHETTI PROGRAMMING.
* PARTS OF THE FOLLOWING ROUTINES
* SEEM USELESS.  THEY MAY JUST BE
* RESIDUAL (BUT INNOCUOUS) INSTRUCS
* THAT ARE LEFT OVER FROM AN EARLIER
* VERSION OF DOS.

* CHECK IF FILE POINTER AND WASTEBYT
* ARE ZEROES.

APNDPTCH LDY #$13
CK4ZEROS LDA (A4L),Y
 BNE SETAPFLG ;UNLESS WE ARE DEALING WITH A
;USELESS FILE THAT WAS PREVIOUSLY
;OPENED. BUT NEVER CLOSED, THIS
;INSTRUCTION IS ALWAYS TAKEN.
 INY
 CPY #$17
 BNE CK4ZEROS

* THE PURPOSE OF THE FOLLOWING
* INSTRUCTIONS IS NOT UNDERSTOOD.
* THIS SECTION OF CODE MAY HAVE BEEN
* DESIGNED TO DEAL WITH USELESS FILES
* THAT WERE OPENED BUT NEVER CLOSED.
* WHATEVER THE ORIGINAL PURPOSE WAS,
* THE FOLLOWING CODE APPEARS TO KEEP
* THE FILE POINTER AT #$000000 WHEN
* AN EMPTY FILE (IE. FILE WITH NO
* DATA) IS ENCOUNTERED.

 LDY #$19 ;COPY IMAGE OF RECNMBWA/+1 AND
COPYRECS LDA (A4L),Y ;BYTOFFWA/+1 THAT WERE JUST
 STA RECLENFM-$19,Y ;STORED IN THE WORK BUFFER TO
 INY ;RECNMBFM/+1 AND BYTOFFFM/+1 IN
 CPY #$1D ;THE FM PARAMETER LIST.
 BNE COPYRECS
FMDVRTN JMP BK2FMDRV


* SET THE APPEND FLAG.
* (NEVER ENTERED IF DEALING WITH
* AN EMPTY FILE.)

SETAPFLG LDX #$FF
 STX APPNDFLG ;SET THE APPEND FLAG.
 BNE FMDVRTN ;ALWAYS.


*=================================
*    YET ANOTHER APPEND PATCH.
*        ($B6B3 - $B6CE)
*=================================

* BUGGY ROUTINE USED TO BACK UP THE
* FILE POINTER.  IF A FILE IS $FFFF
* (#65536) BYTES LONG (OR SOME
* MULTIPLE THEREOF), THE APPEND CMD
* WILL FAIL BECAUSE THIS ROUTINE
* NEGLECTS TO BACK UP THE HI BYTE
* OF THE FILE POINTER (FILPTSEC+1).

RSETPTRS LDA RECNMBFM ;RECONCILE RECORD NUMBER VERSIONS
 STA FILPTBYT ;AND LOWEST TWO BYTE OF THE FILE
 STA RECNMBWA ;POINTER.
 LDA RECNMBFM+1
 STA WASTEBYT ;APPEARS TO BE IRRELEVANT.
;OBVIOUSLY HAS SOMETHING TO DO
;WITH CK4ZEROS ROUTINE DESCRIBED
;ABOVE.
 STA RECNMBWA+1
 STA FILPTSEC
 TSX ;RESET THE STK POINTER SO WE CAN
 STX STKSAV ;USE THE FMEXIT ROUTINE TO RETURN
;TO THE CALLER OF THE APPEND CMD.
;(NOTE: THIS WILL BE EXCEPTIONAL
;EXIT ROUTE FOR FMEXIT.)
 JMP GOODFMXT ;EXIT THE APPEND CMD VIA FMEXIT
;ROUTINE. EXECUTION ACTUALLY RTNS
;2 AFTRCMD ($A17D) LOCATED IN THE
;CMD PARSING AND PROCESSING
;ROUTINES.


*=================================
*           FREE SPACE
*=================================

 DS 1 ;($B6CF)


*=================================
*     STRAY CODE (NOT USED).
*         ($B6D0-$B6E7.)
*=================================

* - DO A HOME & THEN PRINT "B01-00"
* - CONSIDER TO BE FREE SPACE.

 JSR HOME
 LDA #"B"
 JSR COUT
 LDA #$01
 JSR PRBYTE
 LDA #"-"
 JSR COUT
 LDA #$00
 JSR PRBYTE
 RTS


*=================================
*           FREE SPACE
*=================================

 DS 21 ;($B6E8-$B6FC.)


*=================================
*       STORAGE FOR BOOT1.
*        ($B6FD - $B6FF)
*   (IMAGE MOVED TO $8FD-$8FF.)
*=================================

IMG8FD DA $B600 ;VARIES FROM $B600-$BF00 ON 48K
;SLAVE.  (EVENTUALLY POINTS TO THE
;START OF BOOT2 AT $B700.  IMAGE
;OF BT1LDADR AT $8FD.)
IMG8FF DS 1 ;CONTAINS # OF PAGES TO READ WHEN
;EXECUTING BOOT1.  ALSO DOUBLES AS
;LOGICAL SEC#.  INITIALLY = $01.
;VARIES FROM:$09 --> $00 --> $FF.
;(IMAGE OF BT1PG2RD AT $8FF.)


*=========================================
*          BOOT2 ($B700 - $B749).
*=========================================

* - READS IN THE REST OF DOS STARING AT
*   TRK02/SEC04 DOWN TO TRK00/SEC0A
*   ($B5FF --> $9B00).  (SECTORS 0A & 0B
*   OF TRK 0 ($9CFF - $9B00) ARE
*   EMPTY.)
* - AFTER THE REST OF DOS IS READ IN,
*   EXECUTION JUMPS TO DOS'S COLDSTART
*   ROUTINE (DOSCLD, $9D84).
* - NOTE THAT ON ENTRY:  (X) = SLOT * 16.
*:::::::::::::::::::::::::::::::::::::::::


* PREPARE RWTS'S INPUT-OUTOUT BLOCK
* (IOB) AND DESIGNATE THE NUMBER OF
* SECTORS TO READ.

BOOT2 STX IBSLOT ;(X) = SLOT*16 WANTED.
 STX IOBPSN ;LAST-USED SLOT*16.
 LDA #1 ;DESIGNATE BOTH LAST-USED & WNTD
 STA IOBPDN ;DRIVES TO BE DRIVE#1.
 STA IBDRVN
 LDA NMPG2RD ;SET NUMBER OF PAGES TO READ.
 STA BT2PGCTR ;COUNTER 4 NUMBER OF PGS 2 READ.
 LDA #2 ;START WITH TRK$02/SEC$04.
 STA IBTRK ;TRACK.
 LDA #4
 STA IBSECT ;SECTOR.
 LDY BT1MGADR+1 ;(Y)=HI BYTE OF ADDR OF IMAGE OF
;BOOT1 (#$B6 ON 48K SLAVE).
 DEY ;DEFINE I/O BUF AS 1 PAGE BELOW
 STY IBBUFP+1 ;BOOT1.
 LDA #1 ;OPCODE FOR READ.
 STA IBCMD

* CONVERT FROM (X) = SLOT*16
* TO (X) = SLOT.

 TXA ;(X) = SLOT * 16.
 LSR ;DIVIDE BY 16.
 LSR
 LSR
 LSR
 TAX ;(X) = SLOT.

* INITIALIZE PAGE-4 LOCATIONS WITH
* TRACK #'S ASSOC WITH THE DRIVES.

 LDA #0
 STA TRK4DRV2,X
 STA TRK4DRV1,X

* CALL ROUTINE TO READ IN THE REST OF DOS.

 JSR RWPAGES ;GO READ A GROUP OF PAGES (SECS).
 LDX #$FF ;COMPLETELY CLEAR OUT THE STACK.
 TXS
 STX IBVOL ;SET VOL TO $FF (COMPLEMENT OF 0)
 JMP CLOBCARD ;GO CLOBBER THE LANGUAGE CARD AND
;SET VIDEO OUTPUT (SIMUL8 PR#0).
;(RETURNS TO NEXT INSTRUC BELOW.)

BK2BOOT2 JSR SETKBD ;SIMULATE "IN#0" STATEMENT.
;(THAT IS, SELECT KEYBOARD.)
 JMP DOSCOLD ;JUMP IN2 DOS'S COLDSTART ROUTINE
;(AT $9DE4) TO BUILD THE DOS BUFS
;AND THE PAGE-3 VECTOR TABLE AND
;THEN RUN THE "HELLO" PROGRAM.
;************* NOTE *************
;* THIS INSTRUC IS A HACKER'S   *
;* DREAM.  FOR INSTANCE, YOU CAN*
;* CHANGE THE JUMP TO POINT TO  *
;* YOUR OWN PASSWORD OR TIME-   *
;* BOMB PRGM THAT YOU HAVE      *
;* DEVIOUSLY IMBEDDED IN AN     *
;* UNUSED SECTION OF DOS.       *
;********************************


*================================
* WRITE DOS IMAGE ON TRKS 0 - 2.
* (USED BY INIT FUNCTION.)
*
* WRITE TRK02/SEC04 ($B5FF) DOWN
* TO TRK00/SEC0C ($9D00).
*================================

WRDOSIMG LDA BTSTAGE+1 ;CALC # OF PAGES TO WRITE:
 SEC ;    (#$B6 - #$9D = #$19 OR #25.)
 SBC IBBUFP+1
 STA BT2PGCTR ;SET COUNTER FOR 25 PAGES.
 LDA BTSTAGE+1
 STA IBBUFP+1
 DEC IBBUFP+1 ;START WITH PAGE #$B5.
 LDA #2 ;START WITH TRK02/SEC04.
 STA IBTRK
 LDA #4
 STA IBSECT
 LDA #2 ;SET WRITE COMMAND.
 STA IBCMD
 JSR RWPAGES ;WRT TRK02/SEC04 TO TRK00/SEC00.

* WRITE TRK00/SEC09 ($BFFF) DOWN
* TO TRK00/SEC00 ($9D00).

 LDA BTSTAGE+1 ;STORE HI BYTE OF ADRRESS OF THE
 STA IMG8FD+1 ;START OF BOOT1 (#$B6).
 CLC ;CALC HI BYTE ADR OF TRK00/SEC09
 ADC #9 ;(#$B6 + #$09 = #$BF).
 STA IBBUFP+1 ;SET BUF 2 SEND INFO 2 PAGE #$BF.
 LDA #10 ;DESIGNATE 10 PAGES TO WRITE.
 STA BT2PGCTR ;(#$BFFF - #$B600).
 SEC
 SBC #1
 STA IMG8FF ;SIGNIFY THAT THERE ARE 9 PAGES 2
;BE READ WHEN BOOT1 IS EXECUTED.
 STA IBSECT ;START WRITING WITH TRK00/SEC09.
 JSR RWPAGES ;WRITE TRK00/SEC09 2 TRK00/SEC00.
 RTS


*================================*
*    FREE SPACE ($B78D-$B792).
*================================*

 HEX 000000000000 ;UNUSED.


*=================================
*   READ/WRITE A GROUP OF PAGES.
*=================================

RWPAGES LDA ADROFIOB+1 ;INIT (A)/(Y) WITH HI/LOW BYTS OF
 LDY ADROFIOB ;ADR OF RWTS'S IOB 4 NTRY 2 RWTS.
 JSR ENTERWTS ;ENTER IN2 RWTS 2 READ/WRITE SEC.
 LDY IBSECT ;GET # OF SEC JUST RD OR WRITTEN
 DEY ;VAL 4 NXT SEC 2 READ/WRITE (WHEN
;EXECUTING BOOT1, #$09 --> #$FF).
 BPL SAMETRK ;BRANCH TO USE THE SAME TRACK.

* START A NEW TRACK.

 LDY #$0F ;START WITH SEC 15.
 NOP
 NOP
 DEC IBTRK ;REDUCE TRK# WANTED.

* ADJUST POINTER TO IOB & TEST IF THERE
* ARE ANY MORE SECTORS TO READ/WRITE.

SAMETRK STY IBSECT ;STORE NUMBER OF SEC WANTED.
 DEC IBBUFP+1 ;REDUCE BUFFER'S PAGE ADR.
 DEC BT2PGCTR ;REDUCE CNTR 4 # OF SECS 2 READ.
 BNE RWPAGES ;MORE SECS TO READ.
 RTS


*===================================
*      ROUTE EXECUTION TO RWTS.
*===================================

* NORMAL ROUTE TO ENTER RWTS FROM
* CUSTOM ASSEMBLY LANGUAGE PRGMS.
* ON ENTRY - THE IOB AND DCT TBLS
*            MUST ALREADY BE SET UP.
*          - (Y) AND (A) = LOW AND
*            HI BYTES (RESPECTIVELY)
*            OF ADDR OF IOB TABLE.
* (P.S.  NOTE THAT THE $3D9 VECTOR
* JUMPS TO HERE!!!)

ENTERWTS PHP ;SAVE STATUS ON STK.
;(C)=0 IF SEEKING OR READING.
;(C)=1 IF WRITING OR FORMATTING.
 SEI ;SET INTERRUPT DISABLE FLAG TO
;PREVENT ANY FURTHER MASKABLE
;INTERRUPTS WHEN DOING REAL-TIME
;PROGRAMMING.
 JSR RWTS ;ENTER RWTS PROPER 2 DO OPERAT'N:
;          $00=SEEK, $01=READ,
;          $02=WRITE, $03=FORMAT.
 BCS ERRENTER ;OPERATION WAS NOT SUCCESSFUL.
;NVR TAKEN IF JUST SEEKING CAUSE
;NO ERROR SIGNALLING ROUTINES ARE
;ASSOCIATED WITH THAT OPERATION.
 PLP ;THROW STATUS OFF STACK.
 CLC ;SIGNAL SUCCESSFUL.
 RTS

ERRENTER PLP ;THROW STATUS OFF STACK.
 SEC ;SIGNAL UNSUCCESSFUL.
 RTS


*=================================
* SET UP RWTS'S IOB TO WRITE DOS.
*=================================

PRPWRDOS LDA FIRDOSPG+1 ;DESIGNATE START OF DOS AS ADR OF
 STA IBBUFP+1 ;I/O BUF IN RWTS'S IOB.
 LDA #0
 STA IBBUFP
 LDA VOLWA ;COMPLEMENT VOL#.
 EOR #$FF
 STA IBVOL
 RTS


*=================================
* ZERO OUT THE CURRENT (256-BYTE)
* BUFFER.
*=================================

ZCURBUF LDA #0
 TAY
ZCURBUF1 STA (A4L),Y
 INY
 BNE ZCURBUF1
 RTS


*=================================
*      PARAMETERS FOR BOOT2.
*        ($B7DF - $B7E7)
*=================================

 DS 1 ;UNUSED ($B7DF).
NMPG2RD HEX 1B ;# OF PAGES TO READ (#27).
BT2PGCTR DS 1 ;# OF PAGES LEFT 2 READ (VARIES).
BT1RSTSC HEX 0A ;FIRST SEC # IN STAGE (#10).

 DS 1 ;UNUSED ($B7E3).
ADROFIOB DA IBTYPE ;ADR OF RWTS'S IOB (NORM $B7E8).
BTSTAGE DA SEC2RDB6 ;ADR OF START OF IMAGE OF BOOT1.
;(NORMALLY, $B600.)
BT1MGADR = BTSTAGE


*=================================
* RWTS'S INPUT/OUTPUT BLOCK (IOB).
*        ($B7E8 - $B7FA)
*=================================

IBTYPE HEX 01 ;TABLE TYPE (SHOULD BE $01).
IBSLOT DS 1 ;SLOT WANTED * 16.
IBDRVN DS 1 ;DRIVE WANTED ($01 OR $02).
IBVOL DS 1 ;VOL WANTED ($00 GOOD FOR ALL).
IBTRK DS 1 ;TRK WANTED.
IBSECT DS 1 ;LOGICAL SEC WANTED.
IBDCTP DA DEVTPC ;PTS 2 DEVICE CHARACTERISTIC TBL.
;(NORMALLY, $B7FB).
IBBUFP DS 2 ;PTS 2 RWTS'S I/O BUFFER.
IBSECSZ HEX 0001 ;SEC SIZ IN BYTS (LOW/HI FORMAT).
IBCMD DS 1 ;RWTS COMMAND CODE:
;          $00=SEEK, $01=READ,
;          $02=WRITE, $04=FORMAT.
IBSTAT DS 1 ;ERROR CODE:
;$00=NO ERRS, $10=WRIT PROT,
;$20=VOL MISMTCH, $40=I/O(DRV)ERR
;$80=READ ERR.
IBSMOD DS 1 ;VOLUME FOUND.
IOBPSN DS 1 ;SLOT*16 OF LAST ACCESS (FOUND).
IOBPDN DS 1 ;DRIVE # OF LAST ACCESS (FOUND).
 HEX 0000 ;UNUSED ($B7F9-$B7FA).


*=================================
*   DEVICE CHARACTERISTIC TABLE.
*        ($B7FB - $B7FF)
*=================================

DEVTPC HEX 00 ;DEVICE TYPE.
PPTC HEX 01 ;PHASES/TRK. (EVEN VAL = 1PHASE,
;ODD VAL = 2PHASE.)  THEREFORE,
;$01=2 PHASE (WHICH TRANSLATES TO
;2 ARM MOVEMENTS PER TRACK).
MONTC HEX EFD8 ;MOTOR-ON-TIME COUNT.
 DS 1 ;UNUSED ($B7FF).
�D