;2/14/85
;
; **********************************************
; ***      c-64 end of 1541 fast loader      ***
; ***         ( with error-checking )        ***
; **********************************************
;
;***  variables  ***
       *=$02
;
track  *=*+1
sector *=*+1
data   *=*+1
toread *=*+1
ptr    *=*+2 ; (2 bytes).
stat   *=*+1
devc   *=*+1 ; device number.
;
ci2pra = $dd00
datin  = $80 ; port bits.
clkin  = $40
datout = $20
clkout = $10
;
;
chkin  = $ffc6
chkout = $ffc9
chrin  = $ffcf
chrout = $ffd2
clrchn = $ffcc
close  = $ffc3
setnam = $ffbd
setlfs = $ffba
open   = $ffc0
;
rdcmd  = 1 ; disk command to read in and send a sector.
offcmd = 0 ; disk command to revert to dos control.
;
;
;
       *=$c000; ****  entry to init and load a file  ****
;
flddef ldx #21 ; default track & sector.
       ldy #4
fld8   lda #8 ; default to drive #8.
;
fld    sta devc
       jsr fstart ; ** init drive  **  (no params)
       bcs clsall ; error on open..
;
       lda ci2pra+2 ; save ddr value.
       pha
       lda #datout+clkout ; new ddr.
       sta ci2pra+2
       jsr fload    ; ** load a file **  (x,y = t,s)
       pla
       sta ci2pra+2 ; restore ddr.
;
clsall lda #2     ; close files.
       jsr close
       lda #15
       jsr close ; *****  exit  *****
;
       sec
       lda stat ; status (.a) should be zero on exit.
       cmp #1
       bne exit
       clc      ; carry-clear if all ok.
       lda #0
exit   rts
;
;
;
;***********************************************************
;***  init :  read drive program from sector into drive  ***
;***********************************************************
;
fstart stx track ;save .x, .y
       sty sector
       lda #1
       sta stat ; start with no error.
;
       lda #15
       jsr close
       lda #2
       jsr close
       lda #15 ; open 15,8,15,"i0"
       tay
       ldx devc
       jsr setlfs
       lda #2
       ldx #<i0
       ldy #>i0
       jsr setnam
       jsr open
       bcc finit
;
errr   ora #$80 ; i/o err: make .a non-zero.
err1   sta stat
       sec
       rts
;
finit  lda #2 ;open the data channel 2,8,2,"#2".
       ldx devc
       tay
       jsr setlfs
       lda #2
       ldx #<dname1
       ldy #>dname1
       jsr setnam
       jsr open
       bcs errr
;
       ldx #15 ; send 'b-p: 2 0'
       jsr chkout
       ldy #0
sbp01  lda bfpnt,y
       beq sbp05
       jsr chrout
       iny
       bne sbp01
sbp05  jsr clrchn
;
       ldx #2     ;send drive code to $0500.
       jsr chkout ; (256 bytes)
       bcs errr
       ldy #0
       fnt0 lda drvcod,y
       jsr chrout
       iny
       bne fnt0
fnt5   jsr clrchn ;send eoi.
;
       ldx #15
       jsr chkout ; send rest of code in 'm-w' cmd.
       ldy #5
mw0010 lda mwr1,y
       jsr chrout
       dey
       bpl mw0010
       ldy #0    ; 31 more bytes.
mw0020 lda drvcod+256,y
       jsr chrout
       iny
       cpy mwr1
       bne mw0020
       jsr clrchn
;
       ldx #$0f  ;drive: jmp to $0500.
       jsr chkout
       lda #'u
       jsr chrout
       lda #'3
       jsr chrout
       jsr clrchn ;done init.
;
       ldx track
       ldy sector ;recover .x, .y
       clc
       rts
;
;
i0     .byt 'i0'
dname1 .byt '#2'
bfpnt  .byt 'b-p: 2 0',0
mwr1   .byt 31,6,0,'w-m'
;
;
;
;**********************************************************
;**   load a file:   give starting track=.x, sector=.y   **
;**********************************************************
; *
; * drive reverts to normal dos control after
; *   file is loaded.
; * drive must be initialized, ready for rdcmd.
; *
;
fload  stx track  ; save file's starting t,s.
       sty sector
       lda ci2pra ; clear lines.
       and #$ff-clkout-datout
       sta ci2pra
fl0    bit ci2pra ; wait for lines to clear.
       bpl fl0
       bvc fl0
;
       lda #rdcmd ; disk command to get a sector.
       jsr sndbyt
       lda track  ; give first t,s.
       jsr sndbyt
       lda sector
       jsr sndbyt
;
       jsr getbyt ; get job status first.
       sta stat
;
fl1    jsr getbyt
       sta track  ; get t,s link (next sector).
       jsr getbyt
       sta sector
;
       jsr getbyt ; get file starting address.
       sta ptr
       jsr getbyt
       sta ptr+1
;
       lda #252   ; 252 bytes left in this block.
       sta toread
;
;                  ; get a byte.
flo010 jsr getbyt
       ldx track   ; is this last sector?
       bne flo015  ; (no)
       tax
       lda sector  ; (yes) are we past end of file?
       eor #$ff
       cmp toread
       bcs flo017  ; (yes) wait out rest of sector.
       txa
;
flo015 ldy #0      ; (no) store byte.
       sta (ptr),y
;
flo017 inc ptr    ; increment pointer.
       bne flo020
       inc ptr+1
;
flo020 dec toread ; # bytes left in this block.
       bne flo010
;
;
       lda stat   ; was read ok?
       cmp #1
       bne flfin  ; no - don't finish load.
;
       lda track  ; was this last sector of file?
       bne flo030
flfin  lda #offcmd ; (yes) send "off" command to drive.
       jsr sndbyt
       rts        ; exit the load routine ("stat").
;
;
flo030 lda #rdcmd ; (no) read another sector:
       jsr sndbyt
       lda track  ; send out next track, sector.
       jsr sndbyt
       lda sector
       jsr sndbyt
;
       jsr getbyt ; get job status.
       sta stat
;
       jsr getbyt ; get new t,s link.
       sta track
       jsr getbyt
       sta sector
;
       lda #254   ; 254 bytes left in block.
       sta toread
       jmp flo010
;
;
;
;      ***************************
;      ***   serial routines   ***
;      ***    (andy finkel)    ***
;      ***************************
;
;
;
;******************************
;*  get byte from disk drive  *
;******************************
;
getbyt lda #$80
       sta data
;
getbit lda ci2pra ; set clock-hi.
       ora #clkout
       sta ci2pra
;
getbo0 lda ci2pra ; wait for data-hi.
       tay
       and #datin
       bne getbo0
;
       tya       ; set clock-lo.
       and #$ff-clkout
       sta ci2pra
;
getbo1 lda ci2pra ; wait for data-lo.
       tay
       and #datin
       beq getbo1
;
getbo2 tya       ; set clk-hi.
       ora #clkout
       sta ci2pra
;
       ldx #7    ; ...wait for drive to send a bit...
getbo3 dex
       bne getbo3
;
       lda ci2pra
       tay         ; get data bit.
       and #$ff-clkout
       sta ci2pra ; set clk-low.
       tya
       asl a
       ror data
       bcc getbo2  ; get rest of data bits.
;
       lda data
       eor #$ff
       rts
;
;
;*****************************
;*  send byte to disk drive  *
;*****************************
;
sndbyt sta data
       ldx #8
abit   jsr sclk1  ; set clock-hi.
;
waitd  jsr settle ; wait for data-hi.
       and #datin
       bne waitd
       jsr sclk0  ; set clock-lo.
;
sndb01 jsr settle ; wait for data-lo.
       tay
       and #datin
       beq sndb01
;
       tya
       ora #clkout
       lsr data
       bcc sndbo2
       ora #datout
sndbo2 sta ci2pra ; send a bit with clock-hi.
;
       ldy #7     ; ...wait...
sndbo3 dey
       bne sndbo3
;
       jsr sclk0  ; clear clock.
;
       dex
       bne abit  ; do other bits in byte.
       rts
;
;
;**********************
;*  debounce io port  *
;**********************
;
settle lda ci2pra
       cmp ci2pra
       bne settle
       rts
;
;************************
;*  set clock out high  *
;************************
;
sclk1  lda ci2pra
       ora #clkout
       and #$ff-datout
       bne putprt
;
;***********************
;*  set clock out low  *
;***********************
;
sclk0  lda ci2pra
       and #$ff-datout-clkout
;
putprt sta ci2pra
       nop
       nop
       rts
;
;
drvcod *=*+287 ; disk drive code at end.
;
;
.end
