Iv'e not really gone through all your code, to try to figure out whats wrong. But this code -
Code: Select all
; Read mdv sectors NOTE JS ROM Only
; ================
; From CALL in SuperBASIC
; use CALL start,mdv_No,buffer
; on entrty D1=MDV number 1-8
; D2=start address of buffer
; Note buffer must be at least 138,000 bytes, or routine will write past
; the end of it
move.l d2,a1 ;buffer base
lea buffBase,a0
move.l a1,(a0) ;Save buffer base
; Wipe the buffer clean
move.w #$86C3,d7 ;34499 ((138000/4)-1 for DBcc)
clr_buf move.l #$0,(a1)+ ;Set buffer contents to zero
dbf d7,clr_buf
; Test Drive number
cmp.l #$09,d1
bge bad_drv ;Drive number >8
tst.l d1
beq bad_drv ;Drive number =0
trap #0 ;Enter supervisor mode
or.w #$0700,sr ;Turn off interupets
; Start MDV turning
lea $18020,a3
move.b #-$19,d0 ;$E7 Mask
and.b $280A0,d0 ;Read SV.TMODE except Minrodrive bit
ori.b #$10,d0 ;Set Microdrive bit to 1
move.b d0,$18002 ;Write to Transmit Control register
move.b d0,$280A0 ;Write to SV_TMODE
movea.l #$2c56,a0 ;Start MDV
jsr (a0)
; Wait a couple of seconds
lea $18000,a0 ;PC_CLOCK
move.l (a0),d3 ;Get time in d3
add.l #$03,d3 ;Add 3 seconds
wait cmp.l (a0),d3
bne.s wait
; MDV is up to speed. Start reading sectors
move.w #$0101,d5 ;Number of sectors to read (257)
;This is more than any cartridge can hold
;So there will be some overlap
;(same sectors twice at start and end)
movea.l buffBase,a1 ;Recover the buffer start
sec_loop lea curBuff,a0
move.l a1,(a0) ;Save current buffer position
move.w d5,4(a0) ;Save counter
; Start reading sectors from MDV
ReadSec add.l #$02,a1 ;Leave space for return result
; Read the next Sector Header
lea $18020,a3
move.w $12a,a0 ;MD.SECTR
jsr $4000(a0) ;Read header
bra.s bm ;Bad Medium
bra.s bh ;Bad Header
hd_ok add.l #$06,a1 ;Make room for checksum + block header
; Read the Sector Block
lea $18020,a3
move.w $124,a0 ;MD.READ
jsr $4000(a0) ;Read sector
bra.s rf ;Read Fail
; Sector read ok
sec_ok movea.l curBuff,a1 ;Get start of current buffer
move.w $2(a1),d0 ;Get header flag and sector number
and.w #$00FF,d0 ;Mask the Flag
move.w d0,(a1) ;Store the read sector number
move.b d1,$12(a1) ;Store File number
move.b d2,$13(a1) ;Store Block number
; Sector read complete OK
bra.s upd_ptr ;Do the next sector
;Deal with problems
bm movea.l curBuff,a1 ;Get start of current buffer
move.w #$FFFF,(a1) ;Flag bad with -1
bra.s bad_med ;Stop MDV return to BASIC with Bad Medium
bh movea.l curBuff,a1 ;Get start of current buffer
move.w #$FFFE,(a1) ;Flag bad with -2
bra.s upd_ptr ;Do next sector
rf movea.l curBuff,a1 ;Get start of current buffer
move.w #$FFFD,(a1) ;Flag bad with -3
; bra.s upd_ptr ;Do next sector (next line)
; Update pointer and loop counter
upd_ptr movea.l curBuff,a1 ;Retrieve current buffer position
move.w count,d5 ;Retrieve counter
add.l #$0218,a1 ;Update pointer for next sector. Add 536
subq.w #$01,d5 ;Decrement counter
beq.s spin_dwn ;Finished loop
bra sec_loop ;Go round the loop again
; Stop the MDV Turning
spin_dwn movea.l #$2c50,a0 ;Stop MDV
jsr (a0)
move.b #-$19,d0 ;$E7
and.b $280A0,d0 ;Set Microdrive Turing to 0
move.b d0,$18002 ;Write to Transmit Control register
move.b d0,$000280A0 ;and SV_TMODE. ULA Transmit mode
exit andi.w #$D8FF,sr ;Enable Interrupts and user mode
moveq #0,d0 ;No Error
rts ;Return to BASIC
; Stop the MDV Turning and return to basic with a Bad Medium error
bad_med movea.l #$2c50,a0 ;Stop MDV
jsr (a0)
move.b #-$19,d0 ;$E7
and.b $280A0,d0 ;Set Microdrive Turing to 0
move.b d0,$18002 ;Write to Transmit Control register
move.b d0,$000280A0 ;and SV_TMODE. ULA Transmit mode
andi.w #$D8FF,sr ;Enable Interrupts and user mode
moveq #-$20,d0 ;Bad Medium
rts ;Return to BASIC
bad_drv moveq #-$7,d0 ;Return to basic with Not Found
rts
buffBase ds.l 1 ;Base address of buffer storage space
curBuff ds.l 1 ;Address in buffer of current sector
count ds.w 1 ;Counter storage
Is from my MDI driver, For reading microdrive cartridges. It can be found here
http://www.dilwyn.me.uk/utils/MDIDriver106.zip on Dilwyn Jones's web site.
It starts the required MDV up, then reads all the sectors into a buffer, and then stops the MDV. If you just want to start the MDV, then stop it, you just need the code up to "MDV is up to speed. Start reading sectors", and then the code from "spin_dwn".
A couple of points which come to mind from when I developed this program are.
The stack pointer, try not to mess with it, don't put things on the stack, don't branch to subroutines, except for the official system calls.
You don't say which operating system you are using, But I had a lot of trouble getting it to work with Minerva, and I gave up on using it in Minerva in the end. (Minerva has it's own vectored routines to do the motor start up's and stop's, but like I said could not get them to work)
Martin Head