Boot module for DC3 floppy disk drive
The Boot module is called by part the of the kernel to load the remaining modules. Boot usually contains a minimal device driver for a disk drive. It loads the first sector of the disk, then looks for the location of "OS9Boot" and loads it into memory.
opt l nam Swtpc Dc-3 controller boot source opt -c use defsfile ttl Boot Module pag ******************************************************************* * * Microware Systems Corporation * * * Os-9 Swtpc Dc-3 Disk Boot Module * * Software To Boot Swtpc Dc-2, And Dc-3 Disk Controllers * * Revised By * William G. Phelps * * * This Controller Uses The Fdc1 1771 Lsi Disk Controller * ********************************************************************** *************************************************************** * * Disk Boot Module Header * * mod BTEND,BTNAM,SYSTM+OBJCT,REENT+1,BTENT,BTSTA BTNAM fcs "Boot" fcb 1 Edition telltale byte ******************* * Revision History * edition 0: prehistoric * edition 1: all use statements converted to use defsfile * copyright removed from object file * disktype set Dc3 added ******************* pag Steprt fcb 0 ********************************************************************* * * Static Storage * * org 0 V.SEL rmb 2 Drive select reg addr. V.CMDR rmb 2 V.TRKR rmb 2 V.SECR rmb 2 V.DATR rmb 2 V.EFLG rmb 1 Set "e" for head settle time V.SIDE rmb 1 Current side; 0:=side 0 V.TMP rmb 1 Temporary save byte V.BUF rmb 2 Local buffer addr V.TRCK rmb 1 Current track V.DRV rmb 1 Drive select reg save BTSTA equ . Total static requirement * * Fd1771 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 **************************************************************** * * Initialize The I/O Port * * Input: (U)= Pointer To Global Storage * * On Exit: (A) Modified * (X) Modified * (Y) Unchanged * (U) Unchanged * BTENT clra ldb #BTSTA Get size of needed static INILUP pshs a decb bne INILUP tfr s,u Point "u" to static ldx #DPORT Point to controller addr stx V.SEL,U Address of drive select reg. leax 4,X Address of command register stx V.CMDR,U lda #F.Typ1 sta 0,x Inz controller chip lbsr Delay Wait for 1771 lda 0,x Read controller status to clear it. 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 * Fall thru to do the boot pag ******************************************************************* * * Bootstrap System From Disk * * (U)= Pointer Global Storage * * Output: (D)= Length Of Bootstrap Data * (X)= Address Of Start Of Boot Data * (Y) Unchanged * (U) Unchanged * LBOOT pshs D,X,U Save registers clra clrb ldy #1 ldx D.FMBM ldu D.FMBM+2 OS9 F$SchBit Search for buffer spot bcs BOOTE1 Problem no mem exg a,b Convert page no. to addr ldu 4,s Restore "u" std V.BUF,u Save buffer addr for use clrb ldx #0 Get sector zero bsr READSK bcs BOOTE1 Branch if can't ldd DD.BSZ,Y Get bootstrap size std 0,S Return to caller OS9 F$SRqMem Get boot memory bcs BOOTE1 Branch if none stu 2,S Return to caller ldu 4,S Get static storage ldx 2,s Get mem addr stx V.BUF,u ldx DD.BT+1,Y Get boot sector ldd DD.BSZ,Y Get boot size beq BOOT2 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 d 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 rts pag ********************************************************* * * Restore Drive To Track Zero * * Input: (Y)= Pointer To Path Descriptor * (U)= Pointer To Global Storage * * If Error: (B)= Error Code & Carry Is Set * * Note: We Are Stepping In Several Tracks Before * Issuing The Restore. As Suggested In The * Application Notes. * RESTOR clr V.Drv,u clr V.TRCK,U Old track = 0 lda #5 Repeat five times RESTR2 ldb #F.STPI Step in command pshs A lbsr WCR0 Issue command, delay & wait for done. puls A deca DONE Stepping? bne RESTR2 ...no; step again. ldb #F.REST Restore command 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 cmpx #0 Is this sector zero? bne RDSK3 Branch if not Read0 bsr RDSK3 Read sector into buffer bcs Retrn1 ldy V.BUF,u Point "y" to dd. info clrb Retrn1 rts 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 orcc #IRQMask+FIRQMask Disable interrupts ldb #F.READ Read sector command lbsr WCR Issue command pshs Y,U Save regs ldy V.CMDR,U ldu V.DATR,U bra READS3 pag ************************************************************ * * Read Loop * READS2 lda ,U Get data sta ,X+ Store it READS3 ldb ,Y Get status bitb #%00000010 Data req? bne READS2 ..yes; honor it. bitb #%00000001 Done? bne READS3 ...no; try again. puls Y,U Restore regs bitb #%00000100 Lost data? bne RDERR ..yes; return it. bra STCK RDERR comb ldb #E$Read rts pag ************************************************************** * * Convert Logical Sector Number To Physical Track And Sector * * Input: B = Msb Of Logical Sector Number * X = Lsb'S Of Logical Sector Number * Output: A = Physical Track Number * Sector Reg = Physical Sector Number * Error: B = Error Code, W/Carry Set * PHYERR comb ldb #E$SECT Error: bad sector number rts PHYSIC clr V.DRV,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 DD.TOT+1,Y Too high sector number? bhs PHYERR ..yes; sorry stb V.TMP,U Save (b) clrb pshs B Will be track number ldb DD.FMT,Y lsrb SHIFT Side bit to carry ldb V.TMP,U Restore (b) bcs PHYSC4 Bra if double sided dec 0,S PHYSC2 inc 0,S subb DD.TKS,Y Subtract one track worth of sectors sbca #0 bcc PHYSC2 Repeat until less than 1 track size bra PHYSC5 PHYSC3 com V.SIDE,U Switch sides bne PHYSC4 Skip track inc if side 1 inc 0,S PHYSC4 subb DD.TKS,Y sbca #0 bcc PHYSC3 Repeat until less than 1 trk PHYSC5 addb DD.TKS,Y Add back for sector number puls A Desired track. PHYSC7 stb [V.SECR,U] Put sector (b) in sector reg * Fall thru to do actual seek pag ************************************************************** * * Move Head To New Track * * Update Track Table With * The Current Track * * Load The Track Register With The * Old Track * * Input: * A = New Track * B = Seek Function Code (F.Seek) * Output: * B = Contents Of Fd1771 Status Reg * A,X = Destroyed * SETTRK ldb V.SIDE,U Get side info andb #%01000000 Mask all but needed bit orb V.DRV,U Mask into drive select stb V.DRV,U Save it ldb V.TRCK,U Get old track stb [V.TRKR,U] Put old track in trk reg cmpa V.TRCK,U Same track? beq SETRK9 ..yes; skip seek. sta V.TRCK,U Update with new track sta [V.DATR,U] Put new trk in data reg ldb #F.SEEK Command bsr WCR0 Issue command lda #4 sta V.EFLG,U Setrk9 clrb rts pag *********************************************************** * * Check Status For Error Conditions * * Input: (B)= Status Of Fd1771 * * If Error: (B)= Error Code & Carry Is Set * * If No Error: Carry Is Clear * STCK bitb #%10000000 Drive ready? bne ERNRDY ..no; error bitb #%00010000 Seek error? bne ERSEEK ..yes; return error bitb #%00001000 Check sum ok? bne ERRCRC ..no; return error clrb rts ERNRDY comb ldb #E$NotRdy Error: drive not ready rts ERSEEK comb ldb #E$SEEK Error: seek error rts ERRCRC comb ldb #E$CRC Error: bad check sum rts pag **************************************************************** * * * Write Command Register * * * 1 - Will Add Step Rate To Seek Commands When Wcr0 Called * 2 - Issues Command To Controller Chip * 3 - Will Wait For Status "Not Busy" If Wcr0 Called * * WCR0 eorb Steprt,pcr Add step rate to command bsr WCR Issue command & delay WCR02 ldb [V.CMDR,U] Get status bitb #%00000001 Busy? bne WCR02 ..yes; wait for it. rts WCR lda V.DRV,U sta [V.SEL,U] Select drive orb V.EFLG,U clr V.EFLG,U stb [V.CMDR,U] Issue command DELAY bsr DELAY1 DELAY1 bsr DELAY2 DELAY2 bsr DELAY4 DELAY4 nop rts emod BTEND equ * end