; Burst load in an entire FD 2000 disk image. ; 1998 by Todd S. Elliott ; Feel free to use, but please attribute it in some fashion. ; Optimized for the SCPU's SuperRAM and is only for version 2 boards ; should be simple to convert these routines for 1750XL REU's capable of ; snarfing in an entire FD 2000 disk image at once. ; Can read in an entire FD 2000 disk image in 3 minutes, 45 seconds. ; With some work, it can read in a FD 4000 disk image, but I have not tried ; this yet, even though I do have a FD 4000 disk drive and some ED floppies. ; I'm lazy. :) ; Possible uses for these routines include archival backup, compression, ; transfers between computers, defragmenters, etc. ; Equates sb = $11f0; start bank of exp. RAM ; The user must set this to a value that will not interfere ; with the system. tr = $fb; current track se = $fc; current sector 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 setbnk = $ff68; sets the source bank setlfs = $ffba; set logical file channel setnam = $ffbd; set filename open = $ffc0; opens a file close = $ffc3; closes a file load = 65493; loads a file chkin = $ffc6; defines an input channel chkout = $ffc9; defines an output channel clrchn = $ffcc; clears all channels and restores devices chrin = $ffcf; inputs a character chrout = $ffd2; outputs a character ; for the CMDFD drive burst'FD'image =*; gets a disk image and store it into SuperRAM ; When done, side 0 of the FD disk will be first in SuperRAM, and side 1 of ; the FD disk will follow, aligned on a bank boundary in SuperRAM. ; prep up the routine with prelim stuff. lda #$01 sta se+2; get two sides of a FD disk lda #$00 sta cmd'read+5; read side 0 of a FD disk lda #$00 sta d2+2; set up high byte of destination page in destination bank lda sb; get start bank for destination transfers sta d1+1; SB must be set earlier to point to a valid start bank in SuperRAM. jsr set'FD'params; sets up prelim variables jsr inquire'disk; issues the inquire disk function new'cmd'track =*; issues a track command to read in an entire track jsr send'u0'cmd; issues BCIS command jsr burst'read'physical'sectors; reads in 1024 byte sectors cli lda #$0a; $14 if you want to read in a FD 4000 image - never tried this. sta se; reset the sector count inc cmd'read+4; point it to the current track for the current burst reading inc cmd'read+1; point it to the very next track for the burst read routines dec tr; are we done with tracks 1-80 of a FD disk? bne new'cmd'track ldx se+2; get side counter dex bmi + jsr get'FD'syspart; get the FD system partition located at track 81 + lda #16; read side 1 of the FD disk sta cmd'read+5 lda #$00 sta d2+2; set up high byte of destination page in destination bank inc d1+1; set up bank byte so that each disk side falls on a bank boundary jsr set'FD'params; set up the variables for the other side of the FD disk dec se+2; are we done with two sides? bpl new'cmd'track jsr close'command'channel jmp disk'error'check; and RTS set'FD'params =*; sets up the parameters for the FD whole disk read routine ldx #$00 stx cmd'read+4; initial track inx stx cmd'read+3; set up the initial sector stx cmd'read+1; keep on reading in the next track lda #10; set up end of sector for the first half of disk image ; but change this to 20 for a FD 4000 disk - Never tried this before. sta cmd'read+2 sta se; set up the initial sector read lda #80 sta tr; set up the initial track read rts get'FD'syspart =*; gets the FD system partition ; prep up the routine with prelim stuff. lda #$03; read only three sectors sta cmd'read+2; may be different if a FD 4000 disk is used. sta se ; issues a track command to read the system partition jsr send'u0'cmd jsr burst'read'physical'sectors cli rts ; saves the SuperRAM image into a .f20 file save'f20 =*; for the FD 2000 ; Since side 0 and side 1 are stored in SuperRAM in their respective regions, ; this routine splices them together, storing side 0, track 1, side 1, track ; 1, side 0, track 2, side 1, track 2, and so on into a sequential and ; understandable disk image file. Due to its size, the file is split in half. jsr set'imagename; give it a default filename ; these values are optimized for FD 2000 disks. Some changes are necessary ; if one wanted to save FD 4000 disk images. lda #$01 sta se; get two disk sides lda #$07 sta se+1; move 2Kb of system partition info lda sb; get start bank in SuperRAM clc adc #12; save partition information first which is at sb+12+$8400 sta d6+2 lda #$84 sta d5+2; set high byte of SuperRAM - jsr getblox; fetches system partition info and saves it bpl - lda #$00 sta d5+2; set the high byte of SuperRAM sta z2+2; set the high byte of SuperRAM lda sb sta d6+2; set start bank in SuperRAM clc adc #13; get offset for side 1 of the FD disk sta z3+2; and make it also a start bank in SuperRAM lp1 =* lda #$80 sta se+1 lda #12 sta se+2; move 12*65536+128*256 bytes lp0 =* lda #39 sta tr; move 40 sectors at a time - jsr getblox; fetches the disk image data and saves it bne + dec se+2; get high byte as well + dec tr bpl - lda #39 sta tr; reset the sector count - jsr fetch'diskblock'too; get side 1 ldy #$00 - lda grabpx,y; get the disk block data jsr chrout; and save it to disk iny bne - inc z2+2; get next page in SuperRAM bne + inc z3+2; get next bank in SuperRAM + dec se+1; decrement the disk block count bne + dec se+2; get high byte as well bmi ++ + dec tr bpl -- bne lp0; go back again + lda #$02 jsr close jsr disk'error'check; check for an error, etc. beq +; check for an error rts; otherwise, abort. + dec se bmi + inc fd'image'name+5; put the next number in the image.fhd file jsr set'imagename jmp lp1 + rts send'u0'cmd =*; issues the u0 command ldx #$0f jsr chkout ldy #$07 - lda cmd'read,y jsr chrout; issues the U0 BCIS burst read command that the FD understands dey bpl - jmp clrchn; and RTS burst'read'physical'sectors =*; uses burst method to load in physical sectors ; in 1Kb chunks ; use burst serial routines sei; disable interrupts for maximum xfer rate bit ciaicr; clears the register by merely reading it jsr afrd; ack for req signal read'physical'sector =*; for reading the next batch of bytes in a burst sequence jsr get'burst'byte; gets the first byte to look for an error and #%00001111; get only the last four bits cmp #$02; check for error bcc + cli pla pla; clean up stack jmp burst'error; handle it + ldx #$03; 1024 byte sectors stx se+1 - ldy #$00 - jsr get'burst'byte sta grabpx,y; stores it for the SuperRAM routines iny bne - jsr stash'disk'block; stash the disk block into superRAM inc d2+2; increment the SuperRAM addy by a page bne + inc d1+1; increment high byte if necessary + dec se+1 bpl -- dec se bne read'physical'sector rts set'imagename =*; sets the filename sequence for the save disk image routine. lda #$02; LFN ldx dv tay; SA jsr setlfs lda #14; length ldx #fd'image'name jsr setnam ldx #$0f jsr setbnk jsr open ldx #$02 jmp chkout getblox =*; fetches a disk block of 256 bytes jsr fetch'disk'block ldy #$00 - lda grabpx,y; jsr chrout iny bne - inc d5+2; get next page in SuperRAM bne + inc d6+2; get next bank in SuperRAM + dec se+1; decrement the disk block count rts inquire'disk =*; issues the inquire disk function command ; this routine is needed so a FD 2000 disk can be logged into for further ; BCIS activities. 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 ; Error checking routines disk'error'check =* jsr open'command'channel jsr chkin; redirect input to device ldy #$00 - jsr chrin; gets a single byte, etc. sta errbuffer,y; stores it in error buffer iny cmp #13; detected? bne - dey lda #$00 sta errbuffer,y; delimit it. jsr close'command'channel ; add code here to print out the error ; --- ; add code here to print out the error lda errbuffer; get the first digit asl:asl:asl:asl; get the digit sta errbuffer lda errbuffer+1; get the second digit and #%00001111; get rid of upper nybble ora errbuffer; combine the upper/lower nybbles ; .A will contain the error code. sec; indicate error rts burst'error =*; checks for burst serial errors ; simplistic error checking. jsr close'command'channel lda #$ff 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 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 stash'disk'block =*; stashes a disk block to SuperRAM ; Should be simple to convert these routines for the 1750XL REU's. ; now the block is at the grabpx area - move it to SuperRAM clc .byte $fb; XCE command .byte $c2,$30; REP #%00110000- turn on 16 bit regs and acc .byte $8b; PHB instruction .byte $a2 .word grabpx; LDX #grabpx- source addy for memory move d2 .byte $a0,$00,$00; ldy #$0000- dest addy for memory move .byte $a9,$ff,$00; lda #$00ff- move only 256 bytes d1 .byte $54,$00,$00; MVN $00,$02- move from bank 0 to bank 2, etc. .byte $ab; PLB instruction .byte $e2,$30; SEP #%00110000- turn on 8 bit regs and acc sec .byte $fb; XCE command- go back into emulation mode rts fetch'disk'block =*; fetches a disk block from SuperRAM clc .byte $fb; XCE command .byte $c2,$30; REP #%00110000- turn on 16 bit regs and acc d5 .byte $a2,$00,$00; LDX #$0000- source addy for memory move .byte $a0 .word grabpx; ldy #grabpx- dest addy for memory move .byte $a9,$ff,$00; lda #$00ff- move only 256 bytes d6 .byte $54,$00,$00; MVN $00,$02- move from bank 0 to bank 2, etc. .byte $e2,$30; SEP #%00110000- turn on 8 bit regs and acc sec .byte $fb; XCE command- go back into emulation mode rts; and exits the routine fetch'diskblock'too =*; fetches a disk block from SuperRAM clc .byte $fb; XCE command .byte $c2,$30; REP #%00110000- turn on 16 bit regs and acc z2 .byte $a2,$00,$00; LDX #$0000- source addy for memory move .byte $a0 .word grabpx; ldy #grabpx- dest addy for memory move .byte $a9,$ff,$00; lda #$00ff- move only 256 bytes z3 .byte $54,$00,$00; MVN $00,$02- move from bank 0 to bank 2, etc. .byte $e2,$30; SEP #%00110000- turn on 8 bit regs and acc sec .byte $fb; XCE command- go back into emulation mode rts; and exits the routine ;Data for the routines cmd'read =*; the actual FD burst read command .byte 13,1,10,1,0,64 .asc "0u" burst'cmd =*; initializes the burst channel .byte 13,4 .asc "0u" fd'image'name =*; default FD disk image name .asc "image0.fhd,p,w" ; end file fd2k loader ___________________________________________________________________ You don't need to buy Internet access to use free Internet e-mail. Get completely free e-mail from Juno at http://www.juno.com/getjuno.html or call Juno at (800) 654-JUNO [654-5866]