Boot module for G68 floppy disk drive
Reads the first sector of the disk, then loads the OS9Boot file. Since the DMA feature in the G68 doesn't go through the DAT, the extended address must be set in the G68 before the operation.
opt l nam GIMIX G68 controller boot source opt -c use defsfile ttl Boot Module pag Type set SYSTM+OBJCT Revs set REENT+2 mod BTEND,BTNAM,Type,Revs,BTENT,BTSTA BTNAM fcs "Boot" fcb 1 fcc "(C) 1982 Microware" ********************************************************************* * * Static Storage * * org 0 V.SEL rmb 2 Drive select reg addr. V.DMACTL rmb 2 DMA control register ptr V.DMAADR rmb 2 DMA address register ptr V.CMDR rmb 2 Command/status register ptr V.TRKR rmb 2 Track register ptr V.SECR rmb 2 Sector register ptr V.DATR rmb 2 Data register ptr V.SIDE rmb 1 V.DENS rmb 1 V.WPROT rmb 1 Software write protection V.FDSTA rmb 1 FD status V.EXTDMA rmb 1 Extended DMA address (lower nibble) V.8INCH rmb 1 V.TMP rmb 1 V.EFLG rmb 1 Set "e" for head settle time V.BUF rmb 2 V.TRCK rmb 1 V.SELFLG rmb 1 Flags for the select register V.TOT rmb 2 Total number of sectors on media V.FMT rmb 1 V.TKS rmb 1 BTSTA equ . * * Fd1797 Commands * F.REST equ $0B Restore command F.SEEK equ $1B Seek command F.STPI equ $4B Step in one track command F.READ equ $88 Read sector command F.WRIT equ $A8 Write sector command F.TYP1 equ $D0 Force type 1 status F.WRTR equ $F4 Write track command pag Steprt fcb 0 P.T0S fcb 10 P.SCT fcb 16 BTENT clra ldb #BTSTA Get size of needed static INILUP pshs a decb bne INILUP tfr s,u Point "u" to static ldx #DPort stx V.SEL,U Address of drive select reg. leax 1,x stx V.DMACTL,u leax 1,x stx V.DMAADR,u leax 2,x lda #F.Typ1 sta 0,x Inz controller chip stx V.CMDR,u leax 1,X Address of track register stx V.TRKR,U leax 1,X Address of sector register stx V.SECR,U leax 1,X Address of data register stx V.DATR,U lda #$FF sta V.TRCK,U Inz to high track count lda [V.SEL,u] anda #1 Check for 8-inch drive sta V.8INCH,u pshs U,X,D ldd #256 Get buffer for LSN 0 read os9 F$SRqMem bcs BOOTE1 Problem no mem tfr U,D ldu 4,s Restore "u" std V.BUF,u Save buffer addr for use clrb ldx #0 Get sector zero lbsr READSK bcs BOOTE1 Branch if can't ldy V.BUF,u ldd DD.BSZ,Y Get bootstrap size std 0,S Return to caller beq BOOT2 branch if no boot file ldx DD.BT+1,Y Get boot sector ldd DD.TOT+1,y get total number of sectors of disk std V.TOT,u save it lda DD.FMT,y get disk format sta V.FMT,u save it lda DD.TKS,y get number of sectors per track sta V.TKS,u save it ldd #256 ldu V.BUF,u os9 F$SRtMem return initial buffer ldd 0,s Get bootstrap size OS9 F$SRqMem Get boot memory bcs BOOTE1 Branch if none tfr u,d ldu 4,S Get static storage std 2,S std V.BUF,u save allocated memory ldd 0,S BOOT1 pshs D,X Save size, sector number clrb bsr READSK Read sector bcs BOOTER puls D,X Retrieve size, sector number inc V.BUF,U Move buffer ptr leax 1,X Up sector number subd #$100 Subtract page read bhi BOOT1 Branch if more BOOT2 clra CLEAR Carry puls b,a bra Bootz BOOTER leas 4,S Return scratch BOOTE1 leas 2,S Return scratch Bootz puls x,u leas BTSTA,s De-allocate static fm stack Retrn1 rts ********************************************************* * * Restore Drive To Track Zero * RESTOR lda #1 Select drive 0 sta V.SELFLG,u clr V.TRCK,U Old track = 0 lda #5 Repeat five times RESTR2 ldb #F.STPI Step in command pshs A eorb STEPRT,pcr clr V.TMP,u lbsr WCR0 Issue command, delay & wait for done. puls A deca DONE Stepping? bne RESTR2 ldb #F.REST Restore command eorb Steprt,pcr lbra WCR0 pag ************************************************************* * * Read Sector Command * * Input: B = Msb Of Logical Sector Number * X = Lsb'S Of Logical Sector Number * Y = Ptr To Path Descriptor * U = Ptr To Global Storage * * Output: 256 Bytes Of Data Returned In Buffer * * Error: Cc=Set, B=Error Code * READSK lda #$91 Error retry code bra RDSK3 RDSK1 bcc RDSK3 Retry without restore pshs D,X bsr RESTOR Drive to tr00 puls D,X RDSK3 pshs D,X bsr READSC Read sector puls D,X bcc Retrn1 Return if no error lsra DONE? bne RDSK1 ...no; retry. * * Fall Through To Try One Last Time * READSC bsr PHYSIC Move head to track bcs Retrn1 ldx V.BUF,u Point to buffer lda #$10 sta V.TMP,u ldb #F.READ Read sector command lbsr WCR0 lbra READCK PHYERR comb ldb #E$Sect rts ************************************************************** * * Convert Logical Sector Number * To Physical Track And Sector * * Input: B = Msb Of Logical Sector Number * X = Lsb'S Of Logical Sector Number PHYSIC lda #1 select drive 0 sta V.SELFLG,u lda #$20 set single density operation sta V.DENS,u clr V.SIDE,u tstb CHECK Sector bounds bne PHYERR msb must be zero tfr X,D Logical sector (os-9) cmpd #0 Logical sector zero? beq PHYSC7 ..yes; skip conversion. cmpd V.TOT,u higher than max for disk? bcc PHYERR branch if so tst V.8INCH,u bne PHYSC0 subb P.T0S,pcr On side 1 track zero? sbca #0 bcc PHYSC1 clra addb P.T0S,pcr bra PHYSC7 * 16 sectors PHYSC0 subb P.SCT,pcr sbca #0 bcc PHYSC1 clra addb P.SCT,pcr bra PHYSC7 * Read track 0 PHYSC1 stb V.TMP,u clrb pshs B Will be track number ldb V.FMT,u Disk format lsrb SHIFT Side bit to carry ldb V.TMP,u bcc PHYSC4 * Double sided read PHYSC2 com V.SIDE,U Switch sides bne PHYSC3 Skip track inc if side 1 inc 0,S PHYSC3 subb V.TKS,u sbca #0 bcc PHYSC2 Repeat until less than 1 trk bra PHYSC5 * Calculate track for single sided disk PHYSC4 inc 0,S Increment track number subb V.TKS,u sbca #0 bcc PHYSC4 PHYSC5 lda V.FMT,u bita #2 Check density beq PHYSC6 branch if single track density clr V.DENS,u double density PHYSC6 puls a addb V.TKS,u PHYSC7 stb [V.SECR,u] ldb V.DENS,u orb V.SELFLG,u set density stb V.SELFLG,u ldb V.TRCK,u stb [V.TRKR,u] PHYSC8 ldb [V.SEL,u] bitb #$20 Motor starting up? bne PHYSC8 ..yes; wait for bit to go away cmpa V.TRCK,u already on the correct track? beq Setrk9 branch if so sta V.TRCK,u sta [V.DATR,u] ldb #F.SEEK Command eorb Steprt,pcr clr V.TMP,u bsr WCR0 Issue command lda #4 sta V.EFLG,u Setrk9 clrb rts **************************************************************** * * * Write Command Register * * Level 2: Set the DMA extended address from logical address * * Input: (X)=logical address * (B)=FDC command WCR0 equ * ifeq LEVEL-2pshs B tfr X,D anda #$F0 lsra Shift block number to lower nibble lsra lsra ldy D.SysDAT Get system DAT ldd A,Y get block number clra lsrb set the DMA extended bits rora lsrb rora lsrb rora lsrb rora stb V.EXTDMA,u pshs A make copy of block number pshs X lda 0,S anda #$0F ora 2,S load the high nibble of block sta 0,S puls X puls A,Bendc stx [V.DMAADR,u] Set buffer address lda V.SELFLG,u tst V.8INCH,u beq WCR00 ora #$C0 Select 8" drive WCR00 sta [V.SEL,u] lda V.TMP,u ifeq LEVEL-2ora V.EXTDMA,u add in the extended bank addressendc tst V.SIDE,u beq WCR01 ora #$40 Select side one WCR01 sta [V.DMACTL,u] tst V.TMP,u beq WCR orb V.EFLG,u clr V.EFLG,u tst V.SIDE,u beq WCR orb #$02 Select side 1 WCR stb [V.CMDR,u] Issue command WCR1 lda [V.SEL,u] Get status bita #$40 Ready? beq WCR1 ..no; check again lda [V.CMDR,u] Get status and clear interrupt rts *********************************************************** * * Check Status For Error Conditions * * Input: (B)= Status Of Fd1797 * * If Error: (B)= Error Code & Carry Is Set * * If No Error: Carry Is Clear * STCK bita #%01000000 Write protected? bne WPERR READCK bita #%00000100 Lost data? bne RDWRER bita #%00001000 Check sum ok? bne ERRCRC bita #%00010000 Seek error? bne ERSEEK bita #%10000000 Drive ready? bne ERNRDY ..no; error clrb rts ERRCRC comb ldb #E$CRC Error: bad check sum rts ERSEEK comb ldb #E$Seek Error: seek error rts RDWRER ldb V.TMP,u bitb #%00100000 Write fault? bne RDERR WRERR comb ldb #E$Write rts RDERR comb ldb #E$Read rts ERNRDY comb ldb #E$NotRdy Error: drive not ready rts WPERR comb ldb #E$WP rts emod BTEND equ *