;2/14/85
;
; *************************************************
; ***  1541-end of fast-loader:  by matt blais  ***
; ***          ( with error-checking )          ***
; *************************************************
;
;
;  <<<  in the disk drive  >>>
;
pb   = $1800 ; serial i/o port.
jobs = $00   ; job queue.
hdrs = $06   ; t/s for job queue.
;
     *=$b5

waitrk *=*+1 ; track (,sec) waiting in buf2.
waisec *=*+1
track  *=*+1
sector *=*+1
data   *=*+1
index  *=*+1
jobst  *=*+1 ; status of read job.
tries  *=*+1
;
;
;*** i/o-port-bit values ***
datin  = $01
datout = $02
clkin  = $04
clkout = $08
ata    = $10 ; auto-atn enable (out).
atnin  = $80
;
rdcmd  = 1   ; read-sector command.
offcmd = 0   ; 'end' command.
read   = $80 ; job-queue read command.
nmtrys = 5
;
buf1 = $0300
buf2 = $0400
buf3 = $0500
;
;
;      *** disk code (init) at $0500 ***
;
*=buf3
;
;
int0   lda #0
       sta waitrk ; no sector waiting.
       lda #ata   ; clear lines.
       sta pb
;
;
;    ***** get command *****
;
cmdwt  jsr getbyt
       cli
       cmp #rdcmd
       beq rdsc10   ; read-sector cmd?
       rts
;
;
rdsc10 jsr getbyt  ; *** read-cmd: get t,s ***
       sta track
       jsr getbyt
       sta sector
;
       cmp waisec  ; is it waiting in buf2?
       bne rdblk   ; (no) go read it in.
       lda track
       cmp waitrk
       bne rdblk
;
rdsc15 cli
       ldx jobs+1   ; wait for buf-2 read to complete.
       bmi rdsc15
       stx jobst    ; save status of read job.
;
       dex          ; successful read?
       beq rdsc18
       dec tries    ; try again..
       bne rdb010
;
rdsc18 ldx #0        ; transfer buf2 to buf1.
rdsc20 lda buf2,x
       sta buf1,x
       inx
       bne rdsc20
;
rdsc30 lda buf1+0    ; double-buffer: read link sector to buf2.
       sta waitrk
       beq sndbf1    ; if track=0, no link.
       sta hdrs+2    ; next track.
;
       lda buf1+1
       sta waisec
       sta hdrs+3    ; read sector to buf2.
;
       lda #nmtrys   ; init try-cntr.
       sta tries
       lda #read
       sta jobs+1
;
;                      ; *** send buf1 ***
sndbf1 ldx #0
       stx index
       lda jobst
       jsr sndbyt    ; send job status first.
;
snd010 ldx index
       lda buf1,x
       jsr sndbyt    ; send a byte.
       inc index
       bne snd010
       beq cmdwt    ; done: wait for next command.
;
;
rdblk  lda track     ; read block to buf2, xfer to b1.
       sta hdrs+2
       lda sector
       sta hdrs+3
       lda #nmtrys  ; init try-counter.
       sta tries
;
rdb010 lda #read   ; put read cmd in job queue.
       sta jobs+1
;
       bne rdsc15  ; wait till read is fin, then xfer.
;
;
;
;      *****************************
;      ***  serial i/o routines  ***
;      ***                       ***
;      *****************************
;
;
;********************************
;*  fast i/o misc. subroutines  *
;********************************
;
debnc  lda pb
       cmp pb
       bne debnc
       rts
;
;
clk0   jsr debnc     ; wait for clk-lo.
       and #clkin 
       bne clk0
       rts
;
;
;************************
;*  get a byte from 64  *
;************************
;
getbyt lda #$80
       sta data
;
gtbit  jsr debnc      ; wait for clk-hi.
       tay
       and #clkin
       beq gtbit
       sei
;
       tya           ; set data-hi.
       ora #datout
       sta pb
;
       jsr clk0      ; wait for clock-lo.
       lda pb
       and #$ff-datout
       sta pb        ; set data-lo.
;
gtbo0  jsr debnc     ; wait for clock-hi.
       tay
       and #clkin
       beq gtbo0
       jsr clk0      ; wait for clock-lo.
;
       tya
       lsr a         ; read in a bit.
       ror data
       bcc gtbit     ; (repeat for 8 bits).
;
       lda data
       cli 
       rts
;
;
;***********************
;*  send a byte to 64  *
;***********************
;
sndbyt ldx #8
       sta data
;
bitsnd lda pb       ; wait for clock-hi.
       tay
       and #clkin
       beq bitsnd
       tya
       ora #datout ; set data-hi.
       sta pb
       sei
;
bsnd0  lda pb      ; wait for clock-lo.
       tay
       and #clkin
       bne bsnd0
;
bsnd1  tya        ; set data-lo.
       and #$ff-datout
       sta pb
;
bsnd2a lda pb    ; wait for clock-hi.
       tay
       and #clkin
       beq bsnd2a
;
       tya      ; compute bit.
       lsr data
       bcc bsnd2
       ora #datout
;
bsnd2  sta pb  ; send bit.
;
bsnd3  lda pb  ; wait for clock-low.
       tay
       and #clkin
       bne bsnd3
;
       tya    ; set data-low.
       and #$ff-datout
       sta pb
;
       dex   ; (repeat for 8 bits).
       bne bsnd2a
       cli
       rts
;
;
.end
