MDV Low Level Routines

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

Re: MDV Low Level Routines

Postby janbredenbeek » Thu Jun 30, 2016 5:29 pm

tcat wrote:Jan,

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

Tomas

Thank you!
Speaking of QED: I've been delving in the QED source and object files which have been around in my archives for 25+ years. The version 1.01 which was distributed (which you probably have) is the oldest stable version around but I've done more development after that. There is a stable version 1.02 which supports TK2 default directories (but AFAIK was never released) and even a 2.0 version which supports editing multiple files (but is probably not stable). I have to sort things out first but you can expect an announcement in the next days...

cheers, Jan.


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

Re: MDV Low Level Routines

Postby janbredenbeek » Thu Jun 30, 2016 5:49 pm

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

Cheers,
Norm.

FS_FLUSH works at file level (it writes out buffers, much like doing a CLOSE but without actually closing the file). You can't force a reread of the map or directory unless you resort to dirty tricks like modifying the physical definition block (pointed to by the SV.FSDEF array), at which point you also should clear any corresponding slave blocks. 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.

cheers, Jan.


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

Re: MDV Low Level Routines

Postby tofro » Thu Jun 30, 2016 6:04 pm

The only way I know you can force the system to drop the slave blocks and re-read them (other than directly manipulating the slave block table, which might severely upset any device driver) fro S*BSIC is to allocate a ridiculous amount (i.e. nearly everything free) of memory and instantly release it.

Due to the way QDOS is implemented, it will force the device drivers to instantly drop all of their slave blocks in favor of the job that wants the memory. (And, on some ROM versions, will trigger all sorts of faults due to memory becoming tight....)

Another way to do it might be calling the mdv driver's forced slaving routine at 28(a3). I have never tried that myself, though.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
janbredenbeek
Gold Card
Posts: 438
Joined: Wed Jan 21, 2015 4:54 pm
Location: Hilversum, The Netherlands

Re: MDV Low Level Routines

Postby janbredenbeek » Thu Jun 30, 2016 6:22 pm

tcat wrote:
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?

Hi Tomas,

I wrote an extensive reply to this but somehow it got lost :( . In any case, there is no way for the software to detect a cartridge change other than by scanning the sector header and comparing the name + random number to what's already present in the physical definition block (pointed to by SV.FSDEF; one for each drive). As this is all cached information (like the slave blocks in 'free' memory), any direct write to the MDV should also update the stored map and slave blocks, else you will probably read wrong information (at best) or end up with a corrupted cartridge (at worst). The QDOS code which handles this is mostly part of low level interrupt service code and not easily accessible for applications. But if you want to have a peek at it, here is my extensive (but incomplete) disassembly of the JS ROM (especially parts 3 and 5 are interesting).

cheers, Jan.


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

Re: MDV Low Level Routines

Postby janbredenbeek » Thu Jun 30, 2016 6:31 pm

Hi All,

I didn't realise that there is a way to force a re-read of the MDV map: Use the TK2 DEL_DEFB command! This clears all physical definition blocks (including stored MDV maps) so the MDV driver must re-read everything! I believe it was included in TK2 to reduce heap fragmentation (physical definition blocks are allocated in the Common Heap whenever you access a device for the first time, if you do this while a memory-consuming program is already running your heap might become fragmented).

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

Postby tcat » Thu Jun 30, 2016 6:51 pm

Martin, Jan, Tobias, .., All

Pleanty of feedback I have got, to delve into studying more.

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.


Just curious, how many cycles, instructions I may hope to get executed within the Gap1?
Also, how much this is influenced by RAM speed?

Tom


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

Re: MDV Low Level Routines

Postby janbredenbeek » Fri Jul 01, 2016 1:03 am

tcat wrote:Martin, Jan, Tobias, .., All

Pleanty of feedback I have got, to delve into studying more.

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.


Just curious, how many cycles, instructions I may hope to get executed within the Gap1?
Also, how much this is influenced by RAM speed?

Tom


Normally the sectors are written using 'gap interrups'. That is, the hardware interrupts the CPU when a gap passes the head and the CPU reads or writes the following data block (including header) according to the status of the sector in the 'pending operations' map and slave block. So the write process is synchronised to the passing of the start of a new sector on the tape.
The only time when interrupts are not used is during a FORMAT operation. This routine starts on a JS at address $5000 (exactly!) and contains a lot of timing constants. Since internal RAM runs at slower speed than ROM (due to the ZX8301 constantly accessing the RAM to build the video signal) you can't just copy this code to RAM. Only external RAM such as on a Trump Card can be as fast as ROM.

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

Postby tcat » Fri Jul 01, 2016 8:20 am

Jan,

My Simple 512K RAM addon, completes this benchmark in 17secs.

Code: Select all

100 ram=RESPR(16): RESTORE 140
110 FOR p=ram TO ram+14 STEP 2: READ x: POKE_W p,x
125 t=DATE: CALL ram
130 PRINT "Test complete in ";DATE-t;" seconds."
140 DATA 28771,29439,20937,-2,20936,-8,28672,20085


Can it stand any good to Trump?

Tomas


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

Re: MDV Low Level Routines

Postby tcat » Fri Jul 01, 2016 8:30 am

Dears, All,

Just another thought, I was suprised to see that blocks belonging to the same file, are not writen one right after the other, but rather there seem 12 blocks in between.

So perhaps catching every dozen's sector and its block, may work even in standard 128K QL RAM, as we get more time for code processing?

Tomas


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

Re: MDV Low Level Routines

Postby tofro » Fri Jul 01, 2016 9:54 am

The skew of 12 sectors when selecting the "possible next" sector to write to is a pretty much arbitrary number that was chosen to make sure when reading the QL has enough time to "digest" the previous sector (including slave block handling, which can take quite a bit of time) without missing the next one to read and then have to wait a full tape revolution for it to come back again.

If you don't do slave block handling (I just assume you don't), you should (rough calculation) actually be able to catch every or at least every second sector coming by.


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO

Who is online

Users browsing this forum: No registered users and 8 guests