MDV Low Level Routines

Anything QL Software or Programming Related.
Post Reply
User avatar
janbredenbeek
Super Gold Card
Posts: 632
Joined: Wed Jan 21, 2015 4:54 pm
Location: Hilversum, The Netherlands

Re: MDV Low Level Routines

Post by janbredenbeek »

Martin_Head wrote: Does that still happen with the direct sector access routines? With direct sector access a physical definition block may not exist.
The message is printed by the gap interrupt handler, not by the MD.SECTR vector itself. In addition, a flag at offset $23 in the physical definition block is set that signals the error to the I/O traps so they return the error to the application (that's why you see the 'bad or changed medium' error often twice).
The code in the gap interrupt handler checks SV.MDRUN first and returns immediately (clearing the interrupt) when it's zero, else it grabs the address of the physical definition block from SV.FSDEF with almost no sanity checks. So if you want to do direct sector access ensure that SV.MDRUN is zero and interrupts are disabled so the interrupt-driven MDV routines don't get in the way.

cheers, Jan.


Martin_Head
Aurora
Posts: 852
Joined: Tue Dec 17, 2013 1:17 pm

Re: MDV Low Level Routines

Post by Martin_Head »

This is a message for tcat. As I am having problems emailing him.......


I have attached a text document with the information I have on Microdrive image files.

I have also attached a couple of basic programs that I put together for myself, for examining Qemulator image files. Explorer1 for version 1 images, and Explorer2 for version 2 images.

Quick notes on using them
-------------------------------------
You will need QPC2 running with a screen size of at least 800x600 pixels
Run the program. It will say to in future use GOTO 1000
Type GOTO 1000, Enter the drive and filename of the image file, and it will be loaded into memory
You can then use the following commands from the keyboard

dumpinfo - displays the 46 byte image header

showsector (sectornumber) - Displays the microdrives sector number. So showsector 0, will display the map.

showimage (sectornumber) - Displays the image files sector number.


Martin Head
Attachments
MDV Image files.zip
This is a text file
(1.54 KiB) Downloaded 107 times
Explorer.zip
This is BASIC
(4.02 KiB) Downloaded 93 times


tcat
Super Gold Card
Posts: 633
Joined: Fri Jan 18, 2013 5:27 pm
Location: Prague, Czech Republic

Re: MDV Low Level Routines

Post by tcat »

Martin,

Many thanks so far, is it alright I add some more code to Explorer[1-2]_bas, with some experiments of mine?
I state your Name in the revision history.

Again a big thank you.
Tomas


Martin_Head
Aurora
Posts: 852
Joined: Tue Dec 17, 2013 1:17 pm

Re: MDV Low Level Routines

Post by Martin_Head »

tcat wrote:Martin,

Many thanks so far, is it alright I add some more code to Explorer[1-2]_bas, with some experiments of mine?
Do whatever you want to the programs. I just wrote them for my own use. I was thinking of combining them into one program to handle both types of Qemulator image files. (Explorer2 is just a very quick patch of Explorer1, and there is very little difference between them).

Martin Head


tcat
Super Gold Card
Posts: 633
Joined: Fri Jan 18, 2013 5:27 pm
Location: Prague, Czech Republic

Re: MDV Low Level Routines

Post by tcat »

Hi,

Possibly with a bit of luck, I can now seem able to duplicate uDUMP1 image onto a real MDV media.
I still cannot believe It, but it happens in 'a single tape loop pass'.

I currenlty look into a possible code optimisation, that goes between MD.SECTR and MD.WRITE, as I am afraid of the timing...
...set up and call MD.WRITE before the tape has moved passed the start of the block header that you want. Looking at page 306 of the QL advanced user guide, Gap 1 (that's the one between the sector header, you've just read, and the start of the block header that you want to overwrite) is 3600us. That's three and a half thousands of a second
To get some speed, I set up List of Sector Pointers in S*BASIC before making CALL to machine routine. This is what goes between MD.SECTR and MD.WRITE.

Code: Select all

; Start writing sector blocks to MDV

         lsl.w    #$02,d7           ;Sector List index, d7*4
         movea.l  blkBuff,a0        ;Pointer to List
         movea.l  $00(a0,d7.w),a1   ;Pointer to Block, blkBuff+d7*4


; Push word, file-no, block-no onto the stack
         move.w   (a1),-(sp)
         addq.l   #$02,a1           ;Move over [file-no][blk-no]
Many thanks
Tomas


Martin_Head
Aurora
Posts: 852
Joined: Tue Dec 17, 2013 1:17 pm

Re: MDV Low Level Routines

Post by Martin_Head »

Use a 'move.w (a1)+,-(sp)' then you would not need the 'addq.l'. Saves a couple of bytes and about 12 clock cycles.

I'm not sure if a 'lea blkBuff,a0' would be quicker than a 'movea.l'

Martin Head


Silvester
Gold Card
Posts: 436
Joined: Thu Dec 12, 2013 10:14 am
Location: UK

Re: MDV Low Level Routines

Post by Silvester »

Interesting thread, folks :-)
janbredenbeek wrote:

The QDOS routines which handle this are quite deeply buried into interrupt-service code. But if you want to look at it, here is my in-depth (but unfortunately incomplete) JS ROM disassembly which documents most of the MDV handling code in parts 3 and 5.
I also did a complete commented disassembly of the JS MDV routines if it's of any interest: http://www.dilwyn.me.uk/docs/disassem/jsromasm.zip

It was quite a while ago now, I think most of my brain cells that held that info have since disintegrated (like the sponge in a old MDV cartridge).

The one thing I do recall though was being convinced that the calls to FS.FLUSH and FS.CHECK are reversed. They perform the oppposite function. ie. to flush MDV files - call check, and vice-versa !

Have I lost my mind, can anyone confirm?
Edit : Doh! I've spotted the source of my past confusion. At the time my only references were QL Technical Manual and QDOS Companion - both state FS.FLUSH only flushes write buffers, FS.CHECK checked for pending read & write operations. In fact FS.FLUSH updates both read and write buffers, FS.CHECK only checks for pending read buffers.
tofro wrote:
I am not sure I like DEL_DEFB at all.
Ditto, only ever used it once (I first checked for no open files, anything pending etc).

Had to restore the entire contents of my Miracle Hard Drive afterwards. :evil:

Never dared to use it since. It does appear to attempt something quite seismic.
tofro wrote:
So DEL_DEFB is OK on a fairly standard QL, but might cause all sorts of trouble on more modern expansions that weren't there when TK2 was designed.
Maybe, but since TT wrote MHD driver I thought it would be OK. I guess there might be a remote possibility something else upset it. Would only attempt to use it again at arms length on a non-HDD system :-)
Last edited by Silvester on Thu Jul 07, 2016 9:10 am, edited 1 time in total.


David
tcat
Super Gold Card
Posts: 633
Joined: Fri Jan 18, 2013 5:27 pm
Location: Prague, Czech Republic

Re: MDV Low Level Routines

Post by tcat »

Martin_Head wrote:Use a 'move.w (a1)+,-(sp)' then you would not need the 'addq.l'. Saves a couple of bytes and about 12 clock cycles.

I'm not sure if a 'lea blkBuff,a0' would be quicker than a 'movea.l'

Martin Head

Martin,

I will try, just wondering how many cycles=3600us, i.e. how many instructions may fit between gaps, while I realise each instruction may have different cycle count.

Thank you so far.

Tomas


User avatar
tofro
Font of All Knowledge
Posts: 2702
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: MDV Low Level Routines

Post by tofro »

tcat,

If you really want to know this:

The 68k users manual lists the cycles needed for each instruction (note this varies according to addressing mode)

http://cache.freescale.com/files/32bit/ ... 8000UM.pdf

Refer to chapter 7, the figures in there are for an 8-bit data bus.

A NOP, for example, takes 8 clock cycles - a DIVS (probably the worst one) takes 162 cycles for the instruction, for the address calculation you need to add between 0 (register) and 36 (absolute long) cycles so you end up at somewhere like 200 cycles for this command.

Regards,
Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Martin_Head
Aurora
Posts: 852
Joined: Tue Dec 17, 2013 1:17 pm

Re: MDV Low Level Routines

Post by Martin_Head »

tcat wrote: Martin,

I will try, just wondering how many cycles=3600us, i.e. how many instructions may fit between gaps, while I realise each instruction may have different cycle count.

Thank you so far.

Tomas
Good question.... Somebody say if my maths goes wrong....

The 68008 processor in the QL runs at 7.5MHz. So one cycle takes 0.13uS (1/750000)

3600uS/0.13uS = 27692 cycles. So you have about 27500 clock cycles to play with. Some of these may get lost to things like screen display generation and RAM refresh cycles. But I have no idea how many.

Martin Head


Post Reply