
 sttl WD1000 Bootstrap
 pag

*
* driver equates
*

board      equ     $E000               board decodes from f300 to f3ff (?)

extadr     equ     board+$25           74LS374 latch for 4 extended address
*                                      lines (bits 0-3),
chan1      equ     %00010000           (bits 4-5),

auxdecode  equ     board+$50           74LS139 for misc. decodes
wd1000_res equ     auxdecode+1         winchester software reset

dma        equ     board+$00           68B44 dma controller

*   memory register definitions:
dmac1a     equ     dma+$04                 channel 1 address register
dmac1c     equ     dma+$06                 channel 1 byte count register
*
*   channel control register definitions:
*
dmacc1     equ     dma+$11                 channel 1 control register
*
*   priority control register definition:
*
dmaprc     equ     dma+$14                 priority control register
*
*   interrupt control register definition:
*
dmaicr     equ     dma+$15                 interrupt control register
*
*   data chain register definition:
*
dmadcr     equ     dma+$16                 data chain control register

wd1000     equ     board+$30           WD1000 5-1/4 winchester controller

wd_data    equ     wd1000+0            data register

wd_error   equ     wd1000+1            error register (read only)
*                                      bit 7 bad block detect
*                                      bit 6 CRC error, data field
*                                      bit 5 CRC error, ID field
*                                      bit 4 ID not found
*                                      bit 3 unused
*                                      bit 2 Aborted Command
*                                      bit 1 TR000 (track zero) error
*                                      bit 0 DAM not found
wd_wr_pre  equ     wd1000+1            write precomp (write only)

wd_sec_cnt equ     wd1000+2            sector count (during format)

wd_sec_num equ     wd1000+3            sector number

wd_cyl_low equ     wd1000+4            cylinder (low byte)
*                                      C0-C7
wd_cyl_hi  equ     wd1000+5            cylinder (high byte)
*                                      C8-C9

wd_sdh     equ     wd1000+6            size/drive/head
*                                      bit 7 XX,
*                                      bit 6,5 sector size (256,512,128)
*                                      bit 4,3 drive select (0,1,2,3)
*                                      bit 2,1,0 head select (0-7)
wd_secsize equ     %00000000           256 byte sectors
wd_sz_512  equ     %00100000           512 byte sectors
wd_sel0    equ     %00000000           select drive zero
wd_sel1    equ     %00001000           select drive one
wd_sel2    equ     %00010000           select drive two
wd_sel3    equ     %00011000           select drive three

wd_status  equ     wd1000+7            status (read only)
*                                      bit 7 busy
*                                      bit 6 ready
*                                      bit 5 write fault
*                                      bit 4 seek complete
*                                      bit 3 data request
*                                      bit 2,1 unused
*                                      bit 0 error (code in wd_error
wd_cmd     equ     wd1000+7            command (write only)
wd_restore equ     %00010110           restore with 3ms step rate
wd_seek    equ     %01110000           seek with 10us step rate
wd_read    equ     %00101000           read sector DMA
*
* Boot loader
*
wdload ldd #0 shut down DMA just in case
 std dmaprc
 tst wd1000_res reset controller
 ldb #10 give the drive some time
wdld0 ldx #0000
wdld1 lda wd_status check for "Ready"
 cmpa #$50
 beq wdld2 jump if ready
 leax -1,x try again
 bne wdld1
 decb
 bne wdld0 keep trying
 ldb #$FF set error condition code
 bra wdexit
wdld2 lda #$20+$80 set up drive 0, 512 byte sectors, ECC
 sta wd_sdh
 lda #wd_restore send restore command
 sta wd_cmd
w5ld3 lda wd_status wait for drive ready
 bmi w5ld3
 lda wd_status check for errors
 bita #$01
 bne wdexit
*
* Read block 1 into physical $01000
*
 ldd #0 Cylinder 0
 sta wd_cyl_hi
 stb wd_cyl_low
 ldb #1 Sector 1
 stb wd_sec_num
 lda #$00 set up DMA address
 ora #chan1 set for channel 1
 sta extadr  set high 4 bits
 ldd #$1000 Mapped to $B000
 std dmac1a set channel 1 address
 ldd #512 set up count
 std dmac1c
 lda #$00 set for DMA read
 sta dmacc1 set up channel control register
 sta dmaicr
 lda #$08 set four channel DMA
 sta dmadcr
 lda #$02 set up channel 1 DMA
 sta dmaprc
 lda #wd_read send READ SECTOR command
 sta wd_cmd
 ldb #10
wdld4 ldx #5000 suitable wait time
wdld45 lda wd_status check status
 bpl wdld5 jump when command complete
 leax -1,x
 bne wdld45
 decb
 bne wdld4
 ldb #$FF set error return
 bra wdexit
wdld5 bita #$01 check for errors
 bne wdexit jump if error
 ldb #10
wdld6 ldx #5000
wdld65 lda dmacc1 wait for DMA completion
 bmi wdld7
 leax -1,x
 bne wdld65
 decb
 bne wdld6
 ldb #$FF return error
 bra wdexit
wdld7 clra set no error
wdexit pshs cc save condition codes
 ldx #$B000 set bootstrap address
 ldd #0 shut down DMA
 std dmaprc
 puls cc,pc return
