Mercurial > hg > Members > kono > nitros9-code
view level1/modules/boot_1773.asm @ 1965:7d14b2ce38c4
Added pointer to saved LSN0
author | afra |
---|---|
date | Wed, 04 Jan 2006 14:24:43 +0000 |
parents | 6d5bd8549d28 |
children | ee587586c0ab |
line wrap: on
line source
******************************************************************** * Boot - WD1773 Boot module * * $Id$ * * Edt/Rev YYYY/MM/DD Modified by * Comment * ------------------------------------------------------------------ * 4 1985/??/?? * Original Tandy distribution version. * * 6 1998/10/12 Boisy G. Pitre * Obtained from L2 Upgrade archive, has 6ms step rate and disk timeout * changes. * * 6r2 2003/05/18 Boisy G. Pitre * Added '.' output for each sector for OS-9 L2 and NitrOS9 for * Mark Marlette (a special request :). * * 6r3 2003/08/31 Robert Gault * Put BLOB-stop code in place, changed orb #$30 to orb #$28 * * 6r4 2004/02/17 Rodney Hamilton * Minor optimizations, improvements in source comments * * 7 2005/10/10 Boisy G. Pitre * Added fragmented bootfile support * 7 2005/10/13 Robert Gault * Changed timing loops for H6309L2 so that code shortened enough to * fit within the $1D0 boundary. nam Boot ttl WD1773 Boot module IFP1 use defsfile ENDC * FDC Control Register bits at $FF40 HALTENA equ %10000000 SIDESEL equ %01000000 DRVSEL3 if no DS drives DDEN equ %00100000 READY equ %00010000 READY for Tandy WD1773-based controllers MOTON equ %00001000 DRVSEL2 equ %00000100 DRVSEL1 equ %00000010 DRVSEL0 equ %00000001 * Default Boot is from drive 0 BootDr set DRVSEL0 IFEQ DNum-1 BootDr set DRVSEL1 Alternate boot from drive 1 ENDC IFEQ DNum-2 BootDr set DRVSEL2 Alternate boot from drive 2 ENDC IFEQ DNum-3 BootDr set SIDESEL Alternate boot from drive 3 ENDC * WD17x3 DPort offsets CONTROL equ 0 CMDREG equ 8+0 write-only STATREG equ CMDREG read-only TRACKREG equ 8+1 SECTREG equ 8+2 DATAREG equ 8+3 * Sector Size SECTSIZE equ 256 * Step Rates: * $00 = 6ms * $01 = 12ms * $02 = 20ms * $03 = 30ms STEP set $00 tylg set Systm+Objct atrv set ReEnt+rev rev set $00 edition set 7 mod eom,name,tylg,atrv,start,size * NOTE: these are U-stack offsets, not DP seglist rmb 2 pointer to segment list blockloc rmb 2 pointer to memory requested blockimg rmb 2 duplicate of the above bootsize rmb 2 size in bytes LSN0Ptr rmb 2 In memory LSN0 pointer drvsel rmb 1 currtrak rmb 1 * Note, for optimization purposes, the following two variables * should be adjacent!! ddtks rmb 1 no. of sectors per track ddfmt rmb 1 side rmb 1 side 2 flag size equ . name fcs /Boot/ fcb edition * Common booter-required defines LSN24BIT equ 0 FLOPPY equ 1 * HWInit - Initialize the device * Entry: Y = hardware address * Exit: Carry Clear = OK, Set = Error * B = error (Carry Set) HWInit lda #%11010000 ($D0) Force Interrupt (stops any command in progress) sta CMDREG,y write command to command register lbsr Delay2 delay 54~ lda STATREG,y clear status register lda #$FF sta currtrak,u set current track to 255 leax >NMIRtn,pcr point to NMI routine IFGT Level-1 stx <D.NMI save address ELSE stx >D.XNMI+1 save address lda #$7E sta >D.XNMI ENDC lda #MOTON turn on drive motor ora WhichDrv,pcr sta CONTROL,y * MOTOR ON spin-up delay loop (~307 mSec) IFGT Level-1 IFNE H6309 ldd #$F000 3 cycles ELSE ldd #50000 ENDC ELSE ldd #25000 ENDC * IFNE H6309 * nop * ENDC L003A nop 1 cycles nop 1 cycles * IFNE H6309 * nop * nop * nop * ENDC subd #$0001 4 cycles bne L003A 3 cycles * HWTerm - Terminate the device * Entry: Y = hardware address * Exit: Carry Clear = OK, Set = Error * B = error (Carry Set) HWTerm clrb rts use ../../6809l1/modules/boot_common.asm DoDDns lda #DDEN+MOTON double density enable and motor on ora WhichDrv,pcr OR in selected drive sta drvsel,u save drive selection byte clr currtrak,u clear current track lda #$05 lbsr SetTrak Set the track to the head we want ldb #0+STEP RESTORE cmd lbra Talk2FDC send command and wait for it to complete * HWRead - Read a 256 byte sector from the device * Entry: Y = hardware address * B = bits 23-16 of LSN * X = bits 15-0 of LSN * blockloc,u = ptr to 256 byte sector * Exit: X = ptr to data (i.e. ptr in blockloc,u) HWRead lda #$91 bsr L00DF else branch subroutine bcs HWRRts branch if error ldx blockloc,u get buffer pointer in X for caller clrb HWRRts rts L00D7 bcc L00DF pshs x,b,a bsr DoDDns puls x,b,a L00DF pshs x,b,a save LSN, command bsr ReadSect puls x,b,a restore LSN, command bcc HWRRts branch if OK lsra bne L00D7 ReadSect bsr Seek2Sect seek to the sector stored in X bcs HWRRts if error, return to caller ldx blockloc,u get address of buffer to fill orcc #IntMasks mask interrupts pshs x save X ldx #$FFFF ldb #%10000000 ($80) READ SECTOR command stb CMDREG,y write to command register ldb drvsel,u (DDEN+MOTORON+BootDr) * NOTE: The 1773 FDC multiplexes the write precomp enable and ready * signals on the ENP/RDY pin, so the READY bit must always be ON for * read and seek commands. (from the FD502 FDC Service Manual) orb #DDEN+READY set DDEN+READY bits ($30) tst side,u are we on side 2? beq L0107 orb #SIDESEL set side 2 bit L0107 stb CONTROL,y lbsr Delay2 delay 54~ orb #HALTENA HALT enable ($80) * lda #%00000010 RESTORE cmd ($02) *L0111 bita >DPort+STATREG * bne L0123 * leay -$01,y * bne L0111 * lda drvsel,u * sta >DPort+CONTROL * puls y * bra L0138 stb CONTROL,y nop nop * bra L0123 ldx ,s get X saved earlier * Sector READ Loop L0123 lda DATAREG,y read from WD DATA register sta ,x+ * stb >DPort+CONTROL nop bra L0123 * RVH NOTE: This ONLY works for double density boot disks! The Tandy * controllers internally gate HALT enable with the DDEN bit, which * means that reading a single-density boot disk will not generate the * NMI signal needed to exit the read loop! Single-density disks must * use a polled I/O loop instead. NMIRtn leas R$Size,s adjust stack puls x ldb STATREG,y read WD STATUS register bitb #$9C any errors? * bitb #$04 LOST DATA bit set? beq r@ branch if not * beq ChkErr branch if not L0138 comb else we will return error ldb #E$Read r@ rts Seek2Sect lda #MOTON permit alternate drives ora WhichDrv,pcr permit alternate drives sta drvsel,u save byte to static mem clr side,u start on side 1 tfr x,d move LSN into D cmpd #$0000 zero? beq L016C branch if so clr ,-s else clear space on stack tst ddfmt,u double sided disk? beq SnglSid branch if not bra DblSid * Double-sided code L0152 com side,u flag side 2 bne DblSid inc ,s DblSid subb ddtks,u sbca #$00 bcc L0152 bra L0168 L0160 inc ,s SnglSid subb ddtks,u subtract sectors per track from B sbca #$00 bcc L0160 L0168 addb #18 add sectors per track (should this be ddtks?) puls a get current track indicator off of stack L016C incb stb SECTREG,y save in sector register SetTrak ldb currtrak,u get current track in B stb TRACKREG,y save in track register cmpa currtrak,u same as A? beq rtsok branch if so sta currtrak,u sta DATAREG,y ldb #$10+STEP SEEK command bsr Talk2FDC send command to controller pshs x * Seek Delay ldx #$222E delay ~39 mSec (78mS L1) SeekDly leax -$01,x bne SeekDly puls x rtsok clrb rts *ChkErr bitb #$98 evaluate WD status (READY, RNF, CRC err) * bne L0138 * clrb * rts Talk2FDC bsr DoCMD issue FDC cmd, wait 54~ FDCLoop ldb STATREG,y get status bitb #$01 still BUSY? bne FDCLoop loop until command completes rts * Issue command and wait 54 clocks * Controller requires a min delay of 14uS (DD) or 28uS (SD) * following a command write before status register is valid DoCMD bsr SelNSend * Delay branches * 54 clock delay including bsr (=30uS/L2,60us/L1) * H6309 code changed to reduce code size, RG IFEQ H6309 Delay2 lbsr Delay3 Delay3 lbsr Delay4 Delay4 ELSE Delay2 lda #5 3 cycles Delay3 exg a,a 5 cycles | 10*5 deca 2 cycles | bne Delay3 3 cycles | ENDC rts * Select And Send * Entry: B = command byte SelNSend lda drvsel,u sta CONTROL,y stb CMDREG,y rts IFGT Level-1 * Filler to get $1D0 Filler fill $39,$1D0-3-2-1-* ENDC Address fdb DPort WhichDrv fcb BootDr emod eom equ * end