MDV Low Level Routines

Anything QL Software or Programming Related.
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,

With more confidence now, I am trying to update an existing Block on MDV as the next exercise.

I believe I need to first position the tape on a given sector.
I therefore scan all the sectors in a loop using MD.SECTR, until the sector I need comes by.

I am surprised to see, that after each valid Sector Header, I also get a BAD Header as if the routine tries to get past a Block Header that immediatelly follows. I realised, to find a Sector I need to set up a counter at least 2*255.

After the sector I need is found, I push word containing File-No/Block-No onto the Stack and call MD.WRITE, with A1 pointing to 512K buffered data to write.

However, I am not so far able to update the block using MD.WRITE.

I am thinking of calling MD.SECTR yet again to pass the Block Header, with hopefully tape positioned on the block I need to update, but I am not at all sure, I have the right understanding of it.

Can anyone please advise.
Many thanks.
Tom


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

Re: MDV Low Level Routines

Post by tofro »

tcat,

I believe the block header needs to be part of your data. The QL can only write the whole sector including block header, checksum, and data block in one go. That is, I believe your buffer must be larger than 512 bytes.

I have never used MD.WRITE myself - but you should be able to find out how much data it wants by comparing A1 before and after.

Tobias


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

Re: MDV Low Level Routines

Post by Martin_Head »

This isn't something I have ever actually tried to do, but it sounds like your doing it right.
I believe the block header needs to be part of your data. The QL can only write the whole sector including block header, checksum, and data block in one go. That is, I believe your buffer must be larger than 512 bytes.


I don't think so, Why would you need to put the file and the block number on the stack if it's included in you data block?

On the subject of the file and block number on the stack. The QL advanced user guide says, "Before MD.WRITE is called , the stack pointer must be set to point to two words. The first word is the file number and the second word is the block number of the sector to be written."
So does this mean you have to move the stack pointer down 8 bytes and then put the two words above it. Or does it mean you leave the stack pointer alone, and place the two words under it?
I am surprised to see, that after each valid Sector Header, I also get a BAD Header as if the routine tries to get past a Block Header that immediatelly follows. I realised, to find a Sector I need to set up a counter at least 2*255.
I know this may be a stupid question... But your not trying to stop the microdrive motor between reads are you? Reading the sector headers and writing data blocks should be one continuous operation. Also you want to keep your machine code efficient, bear in mind that after you have read a sector header, you only have a certain amount of time (as the tape is still moving) to check it's the right sector header that you want, and to 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.

Martin Head


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

Re: MDV Low Level Routines

Post by tofro »

Martin_Head wrote:Also you want to keep your machine code efficient, bear in mind that after you have read a sector header, you only have a certain amount of time (as the tape is still moving) to check it's the right sector header that you want, and to 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.
Martin Head
Martin,

that was exactly the reason why I assumed you need to provide the full block in the buffer.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
Outsoft
Super Gold Card
Posts: 695
Joined: Sat Apr 19, 2014 1:30 pm
Location: Italy
Contact:

Re: MDV Low Level Routines

Post by Outsoft »

tcat wrote:Hi All,

I am curious to know, how some of the copy protected programs work. I learnt about tricks of checking that a dummy file lies on a bad block. I wonder what are the actual routines manipulating single blocks on a tape, is this done by some specific IPC controller routines, could these be found documented somewhere?

Would be also interesting to learn about MDV catalogs (allocation tables) and their structure for holding information on free, bad, and allocated blocks.

Many thanks in advance.
Tom
Great work Tomas!

That routines need to be compatible under with all QLroms for being ueseful ;)

Daniele Terdina with mDump2 used "NON documeted QDOS routines" (the same of Locksmith I think) to read well bad sectors and works with all ROMS (except Minerva naturally).

And also It doesn't work on a GC/SGC too.


User avatar
janbredenbeek
Super Gold Card
Posts: 631
Joined: Wed Jan 21, 2015 4:54 pm
Location: Hilversum, The Netherlands

Re: MDV Low Level Routines

Post by janbredenbeek »

Martin_Head wrote:This isn't something I have ever actually tried to do, but it sounds like your doing it right.

On the subject of the file and block number on the stack. The QL advanced user guide says, "Before MD.WRITE is called , the stack pointer must be set to point to two words. The first word is the file number and the second word is the block number of the sector to be written."
So does this mean you have to move the stack pointer down 8 bytes and then put the two words above it. Or does it mean you leave the stack pointer alone, and place the two words under it?
The Technical Manual is not very clear about this. However Andrew Pennell's QDOS Companion is:

"Before calling this, a word containing the file number (high byte) and block number (low byte) should be pushed on the stack (the extra word is not removed by the routine). The data in the buffer, together with the word containing the file number and block number, are written onto the tape. The routine writes at the current position, so using this without MD.SECTR to position the tape will probably corrupt the tape.
This should be called with code like:
MOVE.W NOS,-(A7) file and block number
MOVE.W $126,A0
JSR $4000(A0)
ADDQ.L #2,A7 remove extra"

So the file and block number are NOT part of the 512 byte data block, and are in fact written as a separate block on the tape with its own checksum (which is also stated by Pennell).
I hope this will clarify things. Also note that on entry A3 must point to the control register at $18020.

cheers, Jan.


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 Jan, and All,

Let me thank you All for all much useful clues and hints.

I was somehow able to write sectors from the very start, but I was failing to see the results, as I realised I needed to remove just written OLD cart, put a NEW one in, do DIR on it - to trigger MEDIA CHANGE, put the OLD back, this possibly is the effect of RANDOM numbers?

Ah yes, now I see I am forgetting to correct supervisor stack,

Code: Select all

ADDQ.L #2,SP           ;Correct stack
is this caller's responsibility like on ATARI?

The TEST excercise I do is:

[1] copy sector 0 - the MAP
[2] copy directory
[3] copy a file fitting a single block

DIR MDV2_ then shows the effect, also stats different sectors used/total.

Now I wish to be able to detect NO MEDIA present, otherwise I got spur of bytes onto channel #0.

Many, many thanks
Tomas
Last edited by tcat on Thu Jun 30, 2016 9:46 am, edited 1 time in total.


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 »

Jan,

A little personal note, I use QED editor, is it your work?
People fond of MetaComco ED may forgive, I prefer QED :/)

Tomas


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

Re: MDV Low Level Routines

Post by Martin_Head »

tcat wrote:Hi Jan, and All,

Let me thank you All for all much useful clues and hints.

I was somehow able to write sectors from the very start, but I was failing to see the results, as I realised I needed to remove just written OLD cart, put a NEW one in, do DIR on it - to trigger MEDIA CHANGE, put the OLD back, this possibly is the effect of RANDOM numbers?
It's likely that the slave blocks were getting in the way. You altered the contents of the cartridge, but the slave blocks did not know. So when you tried to read, you just got what was still in the slave blocks. Rather than what was on the cartridge. Swapping the cartridge causes the slave blocks to be reset.

Martin Head


User avatar
NormanDunbar
Forum Moderator
Posts: 2271
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: MDV Low Level Routines

Post by NormanDunbar »

I think calling fs_flush might help? Perhaps?
I'm not near a QDOS manual so I might be wrong!

Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
Post Reply