Boot module for Dragon 64 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.
nam Boot
ttl os9 system module
use defsfile
ttl Boot Module
NMIVec equ $109
V.SEL equ $FF40 Drive select reg addr.
mod BTEND,BTNAM,SYSTM+OBJCT,REENT+1,BTENT,BTSTA
BTNAM fcs "Boot"
fcb 1 Edition
V.DRV rmb 1 Drive select reg save
V.TMP rmb 1 Temporary save byte
V.BUF rmb 1
u0003 rmb 1
V.TRCK rmb 1
BTSTA equ .
*
* WD1793 Commands
*
F.REST equ $00
F.SEEK equ $10
F.STEP equ $28
F.STPI equ $40
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 $F0 Write track command
STEPRATE equ 3
DRIVE1 equ %00000001
DRIVE2 equ %00000010
DRIVE3 equ %00000100
MOTORON equ %00001000
PRECOMP equ %00010000
DDENS equ %00100000 Double density enable
DRIVE4 equ %01000000
WAITENBL equ %10000000 Wait enable
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 #V.SEL
lda #F.Typ1
sta 0,x Inz controller chip
lbsr DELAY1
lda 0,x Read controller status to clear it.
lda >$FF22
lda #$FF
sta V.TRCK,u
leax NMISVC,pcr
stx NMIVec+1
lda #$7E Store JMP command
sta NMIVec
lda #$04
sta >$FF48
ldd #$C350
L0043 nop
nop
subd #$0001
bne L0043
pshs u,x,b,a
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 clrb 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 #$43
pshs a
bsr RESTR9
puls a
deca
bne RESTR2
ldb #$03
RESTR9 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
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.
READSC bsr PHYSIC
bcs Retrn1
ldx V.BUF,u
orcc #$50
pshs y,dp,cc
lda #$FF
tfr a,dp
lda #$34
sta <$03 ($FF03)
lda #$37
sta <$23
lda <$22
ldb #$88
stb <$40
ldb #$24
stb <$48
L00FC sync
lda <$43
ldb <$22
sta ,x+
bra L00FC
NMISVC leas R$Size,s
lda #$04
sta <$48
lda #$34
sta <$23
ldb <$40
puls y,dp,cc
bitb #$04
beq STCK
RDERR comb
ldb #$F4
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
*
PHYSIC clr V.Drv,u
tfr X,D Logical sector (os-9)
cmpd #0 Logical sector zero?
beq PHYSC7
clr ,-s
bra PHYSC4
PHYSC2 inc ,s
PHYSC4 subd #$0012
bcc PHYSC2
addb #$12
puls a
PHYSC7 incb
PHYSC8 stb >$FF42
bsr DELAY1
cmpb >$FF42
bne PHYSC8
ldb V.TRCK,u
stb >$FF41
cmpa V.TRCK,u
beq L015C
sta V.TRCK,u
sta >$FF43
ldb #$13
bsr WCR0
pshs x
ldx #$222E
SETRK8 leax -$01,x
bne SETRK8
puls x
L015C 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 #%10011000
bne RDERR
clrb
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 bsr WCR Issue command & delay
L0166 ldb >$FF40
lsrb
bcs L0166
rts
L016D lda #$04
sta >$FF48
stb >$FF40
rts
WCR bsr L016D
DELAY1 lbsr DELAY2
DELAY2 lbsr DELAY4
DELAY4 rts
emod
BTEND equ *