; utility fastloader by Todd S. Elliott, Feb. 1999
; feel free to use routines w/o attribution.
; EBUD format
; This is just a demo that shows how a program can burst load in a PRG file.
; Should work with or w/o SCPU v2.
; Should work with any drive that recognizes BCIS (71/81/FD/HD)
; It is only for the 128 mode.
; Tested with a CMD HD. The estimated throughput was roughly 9,200 bytes/sec.

.dvi 9
.dvo 9
.org $1300; unused area in 128 mode
.obj "@0:burstloader"

; equates

dv     = $ba; current KERNAL device number
filename = $0400; buffer of 20 chars for the filename
grabpx = $0b00; temp buffer for the SuperRAM+Disk routines
errbuffer = filename+20; buffer of 30 characters for the command channel
ciasdr = $dc0c; burst serial data register
ciaicr = $dc0d; burst serial data byte register
ci2pra = $dd00; CIA #2 data ports A - Controls the 16k addressing range of VIC
setlfs = $ffba; set logical file channel
setnam = $ffbd; set filename
open   = $ffc0; opens a file
close  = $ffc3; closes a file
chkout = $ffc9; defines an output channel
clrchn = $ffcc; clears all channels and restores devices
chrout = $ffd2; outputs a character

; starts the burst sequence
util'fastloader =*
  jsr inquire'disk; required before a bcis load is attempted.
  jsr clrchn; don't know if this call is needed.
  ldx #$0f
  jsr chkout
  ldy #$09; length
- lda burst'loadfile,y
  jsr chrout; issues the fastloader command
  dey
  bpl -
  jsr clrchn
  sei; disable interrupts while servicing burst data
  bit ciaicr; flush out the burst queue
  jsr afrd

read'loadsector =*; sectors are 254 bytes in size
  jsr get'burst'byte; get the burst status byte.
  cmp #$02; check for an error
  bcc ++
  cmp #%00011111; check for an EOI
  beq +
  cli
  jmp burst'error; service the error
+ jsr get'burst'byte; get the bytes remaining indicator
  tax
  ldy #$02
- jsr get'burst'byte; get individual bytes for the last sector
  sta grabpx,y
  iny
  dex
  bne -
; You would need to stash the remaining bytes somewhere in memory.
  cli; we're done with bursting and reenable IRQ's
  jsr close'command'channel
  rts; exits the demo

+ ldy #$02; we're dealing with 254 bytes
- jsr get'burst'byte
  sta grabpx,y; store it to a temporary buffer
  iny; it is destructive in nature as this buffer is overwritten all the time.
  bne -; It's just a demo...
; You would need to add a routine here that stashes the 254-byte buffer to a
; more meaningful location such as SuperRAM or whatnot.
  beq read'loadsector; relative JMP

; Error checking routines
burst'error =*; checks for burst serial errors
  jsr close'command'channel
  lda #$ff; not fully developed. It just assigns an arbitrary value.
  sta errbuffer; indicate an error
  rts

;Opens the Command channel
open'command'channel =*
  lda #$0f; logical file number
  tay     ; secondary address
  ldx dv  ; current device number
  jsr setlfs
  lda #$00
  jsr setnam
  jsr open
  ldx #$0f; select the command channel for the following CHKIN or CHKOUT
  rts

close'command'channel =*
  jsr clrchn; restores default i/o
  lda #$0f; select the logical file number
  jmp close

get'burst'byte =*; taken from the Compute!'s 128 Programmer's Guide
; See also Miklos Garamszeghy's articles in the Transactor and Commodore Mag.
  lda #$08
- bit ciaicr; wait for 8 bits to arrive over the burst serial bus
  beq -
afrd =*; ack for req protocol
  lda ci2pra
  eor #$10
  sta ci2pra; toggles theCLK line
  lda ciasdr; now, get the byte that was bursted earlier
  rts

inquire'disk =*; issues the inquire disk function command
  jsr open'command'channel
  jsr chkout
  ldy #$03
- lda burst'cmd,y; issues the inquire disk function
  jsr chrout
  dey
  bpl -
  jsr clrchn
  sei
  bit ciaicr
  jsr afrd; burst handshake
  jsr get'burst'byte
  cli
  and #%00001111; get rid of upper nybble
  cmp #$02; check for error
  bcc +
  pla
  pla; clean up stack
  jmp burst'error; and handle the error
+ rts

burst'cmd =*; initializes the burst channel
.byte 13,4
.asc "0u"

burst'loadfile =*; the actual filename used for the fastloader
; substitute the 'test' for the actual filename you want to use. Be sure to
; note its length and modify the calling routine accordingly.
.byte 13
;asc "*,tset"
.byte 42,44,84,83,69,84
.byte 31; or $9f, I think, for SEQ files.
.asc "0u"

; end file utility fastloader demo


