💾 Archived View for spam.works › mirrors › textfiles › apple › ANATOMY › fninit.txt captured on 2023-06-16 at 21:11:30.
View Raw
More Information
-=-=-=-=-=-=-
- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*
- *
- INIT function handler *
- *
- ----------------------------------------------------------------*
- *
- The INIT function handler (FNINIT, $AEBE) is only called *
- by the INIT command handler (CMDINIT, $A54F). The execution *
- pattern of FNINIT is described in the preamble accompanying *
- the formatted disassembly of the INIT command handler. *
- *
- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*
(AE8E)
FNINIT JSR ZWRKAREA ;Initialize the work area.
* Zero out the FM work area so it can be customized
* in accordance with the calling function.
* (Although some work bytes may not be subsequently
* altered, don't be lulled into thinking that they
* are not important. Zero values are just as relevant
* as non-zero values.)
* (P.S. Don't confuse the FM work area with its
* image (FM work buffer) that is housed in the
* chain of DOS buffers.)
(ABDC)
ZWRKAREA LDA #0
TAX ;Initialize the x-index.
ZEROWRKA STA FMWKAREA,X ;Put a $00 byte in work area.
INX
CPX #45 ;Work area is 45 bytes long.
(ABE5) BNE ZEROWRKA
* Begin customizing the work area.
* Get volume, drive, slot & catalog track
* values from the FM parameter list. Put
* drive, slot*16, catalog track and
* complemented volume number in the work area.
(ABE7) LDA VOLFM ;Volume number.
EOR #$FF ;Calculate 1's complement of volume #.
STA VOLWA
LDA DRVFM ;Drive #.
STA DRVWA
LDA SLOTFM ;Get slot #.
ASL ;Calculate slot * 16.
ASL
ASL
ASL
TAX ;Set (x) = slot * 16.
STX SLOT16WA
LDA #$11 ;Normal catalog trk = #17.
STA TRKWA
(AC05) RTS
(AE91) LDA #4 ;Opcode for format.
(AE93) JSR RWTSDRV1 ;Call RWTS driver to FORMAT the disk.
(B058)
RWTSDRV1 .
.
(See dis'mbly of RWTSDRV1 using FORMAT.)
.
.
(RTS)
- Put volume, number of next track to be
- assigned and assignment direction in the
- VTOC sector buffer.
(AE96) LDA VOLWA ;Complemented volume number (from work area).
EOR #$FF ;Uncomplement it & put volume # in VTOC.
STA VOLUSED
LDA #$11 ;Use trk # 17 for catalog track.
(AEA0) STA NXTRKUSE ;Set the catalog trk as the next track to
;assign. (NXTRKUSE is located in the VTOC.)
(AEA3) LDA #1 ;Assignment direction is forward.
(AEA5) STA DRECTION
- Zero out the VTOC buffer from TRKMAP0 to
- the end of the VTOC sector. (Note: This
- allocates all tracks.)
(AEA8) LDX #56 ;Offset to TRKMAP0 in the VTOC.
LDA #0
ZVTOC STA VTOCBUFF,X ;Zero out a TRKMAP byte.
INX
(AEB0) BNE ZVTOC
- Free up all tracks except tracks
- 0, 1, 2 & catalog track (#17).
-
- NOTE: DOS only occupies sectors
- 0 to 4 on track 2, but this routine
- takes the rest of the sectors on
- track 2 out of circulation.
(AEB2) LDX #$0C ;Offset to start of trkmap3.
FREETRK CPX #$8C ;Offset 1 past the end of TRKMAP34.
BEQ FREEDTKS ;Done up to end of TRKMAP#$34?
LDY #3 ;Initialize the index to the end of FRETKMSK.
FREEIT LDA FRETKMSK,Y ;Free most TRKMAPs. (Starting with
(AEBA) ;TRKMAP3.) NOTE: Not freeing up VTOC
;sector or tracks used by DOS.
(AEBD) STA TRKMAP0,X ;Free tracks by placing the following bytes
;in each TRKMAP: "FF FF 00 00".
(AEC0) INX ;Kick up index to byte in TRKMAP.
(AEC1) DEY ;Reduce index to FRETKMSK cause loading from
;the end of FRETKMSK: "00 00 FF FF".
(AEC2) BPL FREEIT ;(4 bytes/TRKMAP & 4 bytes/FRETKMSK)
CPX #$44 ;Offset to start of TRKMAP17 (ie. cat trk).
(AEC6) BNE FREETRK ;Have we freed trks 3 to 16 yet?
;If not, take branch.
(AEC8) LDX #$48 ;Offset to trk 18 (ie. skip the cat trk).
BNE FREETRK ;ALWAYS - go free trks 18 to 34.
FREEDTKS JSR WRITVTOC ;Write freed up VTOC to disk.
(AECC)
* Write the Volume Table of Contents (VTOC).
(AFFB)
WRITVTOC LDA #2 ;Write opcode for RWTS.
* Common to read/write the VTOC.
(AFFD)
RDWRVTOC LDY ADRVTOC ;Get the address of the VTOC from the FM
STY IBBUFP ;constants table & designate it as the
LDY ADRVTOC+1 ;I/O buffer in RWTS's IOB.
STY IBBUFP+1
LDX TRKWA ;Enter RWTS driver with (x)/(x) = trk/sec values of
LDY #0 ;the VTOC.
(B00E) JMP RWTSDRVR ;Call RWTS driver to read/write the VTOC.
------------
* Read/Write Track/Sector driver.
RWTSDRVR .
.
(See dis'mbly of RWTS driver using WRITE.)
.
.
(RTS)
- Clear out the directory sector buffer.
(AECF) LDX #0
TXA
CLRDIREC STA DIRECBUF,X
INX
BNE CLRDIREC
(AED8) JSR PT2DIRBF
* Designate the directory sector buffer
* as the I/O buffer in RWTS's IOB.
(B045)
PT2DIRBF LDA ADRDIRBF ;Get the addr of the directory sec buf
STA IBBUFP ;in the FM constants table.
LDA ADRDIRBF+1 ;Store it in RWTS's IOB.
STA IBBUFP+1
(B051) RTS
(AEDB) LDA #$11 ;(a) = number of catalog track.
LDY SECPERTK ;Number of sectors/track = 16.
DEY
DEY
(AEE2) STA IBTRK ;Put catalog track in IOB.
- Write the directory sectors
- (trk17, secs 15 to 1).
(AEE5)
SETLNKTK STA DIRLNKTK ;Set the trk/sec values for the link to the
SETLNKSC STY DIRLNKSC ;next directory sector.
INY ;Get the number of the sector to be written
STY IBSECT ;and put it in RWTS's IOB.
LDA #2 ;Write opcode for RWTS.
(AEF1) JSR RWTSDRV1 ;Write the directory sector to the disk.
(B058)
RWTSDRV1 .
.
(See dis'mbly of RWTS driver using WRITE.
.
.
(RTS)
(AEF4) LDY DIRLNKSC ;Sector value of the next directory sec to write.
DEY ;Kick it down (will increment it later).
BMI DOIMAGE ;Don't do sector 0 cause that is the VTOC.
BNE SETLNKSC ;Go write sectors 2 to 15.
TYA
(AEFD) BEQ SETLNKTK ;Go back to write sector 1 and zero out
;the directory sector links.
- Routine to write the DOS image
- on tracks 0 to 2.
(AEFF)
DOIMAGE JSR PRPWRDOS ;Get ready to write the DOS image.
* Set up RWTS's IOB to write DOS.
(B7C2)
PRPWRDOS LDA FIRDOSPG ;Designate the start of DOS as the address
STA IBBUFP+1 ;of the I/O buffer in RWTS's IOB.
LDA #0
STA IBBUFP
LDA VOLWA ;Complement the volume number.
EOR #$FF
STA IBVOL
(B7D5) RTS
(AF02) JSR WRDOSIMG ;Write the DOS image
* Write the DOS image in trks 0 to 2.
* That is, write trk02/sec04 ($B5FF) down
* to trk00/sec0C ($9D00).
(B74A)
WRDOSIMG LDA BTSTAGE+1 ;Calculate the number 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 ;Write opcode for RWTS.
STA IBCMD
(B76C) JSR RWPAGES ;Write trk2/sec4 to trk0/sec0.
* Read/write a group of pages.
(B793)
RWPAGES LDA ADROFIOB+1 ;Initialize (a)/(y) with hi/low bytes
(B796) LDY ADROFIOB ;of the addr of RWTS's IOB for entry
;into RWTS.
(B799) JSR ENTERWTS ;Enter into RWTS to read/write a sector.
* Entry to RWTS.
(B7B5) PHP ;Save status on stk.
;(c) = 0 if seek or read.
;(c) = 1 if write or format.
(B7B6) SEI ;Set the interrupt disable flag to prevent
;any further interrupts from occurring when
;doing real-time programming.
(B7B7) JSR RWTS ;Enter RWTS proper to do operation:
; $00=seek, $01=read,
; $02=write & $03=format.
* RWTS proper.
(BD00)
RWTS .
.
(See dis'mbly of RWTS in formatted
dis'mbly of RWTS driver using WRITE.)
.
.
(RTS)
(B7BA) BCS ERRENTER ;Operation was not successful.
PLP ;Throw status off the stack.
CLC ;Signal operation was successful.
(B7BE) RTS
============
(B7BF)
ERRENTER PLP ;Throw status off the stack.
SEC ;Signal operation was unsuccessful.
(B7C1) RTS
============
(B79C) LDY IBSECT ;Get # of sector just read or written.
(B79F) DEY ;Value for next sector to read/write
;(when executing BOOT1, #$09 --> #$FF).
(B7A0) BPL SAMETRK ;Branch to use the same track.
* Start a new track.
(B7A2) LDY #$0F ;Start with sector 15.
NOP
NOP
(B7A6) DEC IBTRK ;Reduce # of trk wanted.
* Adjust pointer to IOB and test if there
* are any more sectors to read/write.
(B7A9)
SAMETRK STY IBSECT ;Store number of sector wanted.
DEC IBBUFP+1 ;Reduce buffer's page address.
(B7AF) DEC BT2PGCTR ;Reduce counter for # of pages
;(ie. sectors) to read or write.
(B7B2) BNE RWPAGES ;More sectors to read or write.
(B7B4) RTS
* Write trk00/sec09 ($BFFF) down
* to trk00/sec00 ($B600).
(B76F) LDA BTSTAGE+1 ;Store hi byte of address of the
STA IMG8D+1 ;start of Boot1 (#$B6).
CLC ;Calulate the hi byte of the address of
ADC #9 ;trk00/sec09 (#$B6 + #$09 = #$BF).
STA IBBUFP+1 ;Set buffer to send info to page #$BF.
LDA #10 ;Designate that there are 10 pages to
STA BT2PGCTR ;write (#$BFFF - #$B600).
SEC
SBC #1
(B783) STA IMG8FF ;Designate that 9 pages are to be read
;when BOOT1 is executed.
(B786) STA IBSECT ;Start writing with trk0/sec9.
(B789) JSR RWPAGES ;Go write trk0/sec9 to trk0/sec0.
* Read/write a group of pages.
(B793)
RWPAGES LDA ADROFIOB+1 ;Initialize (a)/(y) with hi/low bytes
(B796) LDY ADROFIOB ;of the addr of RWTS's IOB for entry
;into RWTS.
(B799) JSR ENTERWTS ;Enter into RWTS to read/write a sector.
* Entry to RWTS.
(B7B5) PHP ;Save status on stk.
;(c) = 0 if seek or read.
;(c) = 1 if write or format.
(B7B6) SEI ;Set the interrupt disable flag to prevent
;any further interrupts from occurring when
;doing real-time programming.
(B7B7) JSR RWTS ;Enter RWTS proper to do operation:
; $00=seek, $01=read,
; $02=write & $03=format.
* RWTS proper.
(BD00)
RWTS .
.
(See dis'mbly of RWTS in formatted
dis'mbly of RWTS driver using WRITE.)
.
.
(RTS)
(B7BA) BCS ERRENTER ;Operation was not successful.
PLP ;Throw status off the stack.
CLC ;Signal operation was successful.
(B7BE) RTS
=============
(B7BF)
ERRENTER PLP ;Throw status off the stack.
SEC ;Signal operation was unsuccessful.
(B7C1) RTS
============
(B79C) LDY IBSECT ;Get # of sector just read or written.
(B79F) DEY ;Value for next sector to read/write
;(when executing BOOT1, #$09 --> #$FF).
(B7A0) BPL SAMETRK ;Branch to use the same track.
* Start a new track.
(B7A2) LDY #$0F ;Start with sector 15.
NOP
NOP
(B7A6) DEC IBTRK ;Reduce # of trk wanted.
* Adjust pointer to IOB and test if there
* are any more sectors to read/write.
(B7A9)
SAMETRK STY IBSECT ;Store number of sector wanted.
DEC IBBUFP+1 ;Reduce buffer's page address.
(B7AF) DEC BT2PGCTR ;Reduce counter for # of pages to
;read or write.
(B7B2) BNE RWPAGES ;More sectors to read or write.
(B7B4) RTS
============
(B78C) RTS
============
(AF05) JMP GOODFMXT ;Exit cleanly.
------------
(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
STA STATUS
(B38E) JSR CPYFMWA ;Copy the work area to the work buffer.
* Copy the FM work area (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 work buffer.
(AF0A) BEQ PT2FMBUF ;ALWAYS.
(AF12)
PT2FMBUF LDA WRKBUFFM,X ;Get address of selected buffer from the
STA A4L ;FM parameter list & 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
(AE81) RTS
(B391) PLP ;Retrieve status of success of operation
;from the stack.
(B392) LDX STKSAV ;Adjust stack pointer to force exit to the
TXS ;caller even if we are several subroutines
(B396) RTS ;deeper than the original entry point.
============ ;(Returns to AFTRFUNC ($A6AB) in the
;FMDRIVER routine ($A6A8).