Monday, April 25, 2011

Microzine #40 rescued!

I've been sitting on Microzine #40 for almost a month trying to figure out how to save it. The problem is it has failing sectors so typical copy programs like Copy ][+ or archival programs like Shrinkit will see an I/O error and either skip the bad sector or else abort entirely.

But I've had a belief that repeated reads of the bad sectors would eventually result in success.

So I finally wrote my own little sector copy program.

Or at least I intended to. I started writing a DOS 3.3 sector copy program only to realize that all of my development tools were in ProDOS so instead I decided to write a block copier. A block is merely 2 sectors which means I would need to get two good sector reads at a time instead of just one which is twice as "hard" on a disk full of errors, but still very doable.

I am pleased to report that by using my own copy program I was able to "brute force" copy Microzine #40 and save it. (at least, the disk checksums passed so I think I most likely got good reads)

For fun, here is the little ProDOS program that I wrote to accomplish this feat.



* matt copier

mli EQU $BF00
cout EQU $FDED
CLS EQU $FC58
prbyte EQU $FDDA
ptr equ $6

ORG $2000

start
jsr outstr
asc "Insert 5.25 disks to copy and press a key to start",8d,00
wait LDA $c000
bpl wait
sta $c010
loop
lda block_idx
sta readblock
sta writeblock
cmp #$18
bcc :1
lda block_idx+1
sta readblock+1
sta writeblock+1
cmp #$01
bcs :done
:1
jsr outstr
asc 8d,"Block: ",00
lda block_idx+1
jsr prbyte
lda block_idx
jsr prbyte

; read block
:read
jsr mli
db $80
da read_parms
bcs :error ; if no error, do the write

:write
jsr mli
db $81
da write_parms
bcc :next

:error
pha
jsr outstr
asc " Err code: ",00
pla
jsr prbyte
bra loop

:next
; increment block index
lda block_idx
inc
sta block_idx
cmp #$00 ; did we overflow?
bne loop ; if we didn't overflow
lda block_idx+1
inc
sta block_idx+1
bra loop
:done
jsr mli
db $65
da quitparms

block_idx ds 2

quitparms db 4
ds 6

read_parms
db 3 ; 3 parameters
db %01100000 ; drive 0, slot 6
da buf ; read buffer
readblock ds 2 ; block to read

write_parms
db 3
db %11100000 ; drive 1, slot 6
da buf ; write buffer
writeblock ds 2 ; block to write

outstr pla
sta ptr
pla
sta ptr+1
ldy #1
:1 lda (ptr),y
beq :4
jsr cout
iny
bra :1
:4 clc
tya
adc ptr
sta ptr
lda #0
adc ptr+1
pha
lda ptr
pha
rts

buf

typ #$ff
sav copy.system

No comments:

Post a Comment