QLMultimon - source question

Anything QL Software or Programming Related.
User avatar
NormanDunbar
Forum Moderator
Posts: 2251
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

QLMultimon - source question

Post by NormanDunbar »

Hi Jan,

in QLMultimon I've seen you do the following in EXAM_REGS (mon1_asm) - the comments are mine:

Code: Select all

    LEA       -$68(A0),A0     ; Start of job again
    LEA       EXTAB-$54(A6),A2    ; ???? -> TODO
    MOVE.L    A2,$1C(A0)      ; JB_TRAPV - vector table
    CMPA.L    $28010,A0       ; SV_BASIC = Start of SuperBASIC area
    BEQ.S     ST_TP_1         ; Skip if SuperBASIC is the job
    ADDA.L    (A0),A0         ; JB_LEN = job length in header
    BRA.S     ST_TP
And a similar thing when clearing up.

My question is, what's this line actually setting in the job's JB_TRAPV, because to me it looks like it's setting the trap vectors for the monitored job to be -2(A6) of the monitor, and not EXTAB.

We have the following in the code:

Code: Select all

EXTAB     EQU       82              Exception table
EXTABEND  EQU       158             End of Exception Table
Then later:

Code: Select all

          LEA       EXTABEND(A6),A7 ; Top of Exception vector table
          MOVEQ     #10,D0          ; Counter for 11 exception vectors

*--------------------------------------------------------------------
* Loop around for TRAP #15 to TRAP #5. Each of these points to the
* EXBRKPNT code and will fire a breakpoint if executed.
*--------------------------------------------------------------------
SETTRAPS  PEA       EXBRKPNT        ; Code for this trap's vector
          DBF       D0,SETTRAPS     ; Do all of #15 down to #5

          PEA       EXINTL7         ; Interrupt level 7
          PEA       EXTRACE         ; Trace exception
          PEA       EXPRIVV         ; Privilege violation
          PEA       EXTRAPV         ; TRAPV
          PEA       EXCHK           ; CHK
          PEA       EXDIVZER        ; Divide by zero exception
          PEA       EXILLINST       ; ILLEGAL instruction exception
          PEA       EXADDERR        ; Address error exception

          MOVE.L    A7,A1           ; EXTAB = Exception vectors address
          LEA       DATASPACE(A6),A7    ; Reset stack pointer
          MOVEQ     #-1,D1          ; For the current job
          MOVEQ     #MT_TRAPV,D0
          TRAP      #1              ; Set the exception vectors
So, the monitor sets up its exception vector table at EXTAB(A6) which is 82(A6) or $52(A6) but you appear to be subtracting $54 from this to set the vector table in the monitored jobs, and when cleaning up at the end, you check the active jobs for the same address in JB_TRAPV in the job's header. I'm assuming that the job being monitored has to be set up to use the monitor's vector table because otherwise, only the monitor would be able to be breakpointed/traced etc - hence my confusion at the "minus $54" bit, why not just "EXTAB(A6)" which is where the vector table starts.

What am I obviously missing here please? Why the EXTAB-$54(A6)?

Cheers,
Norm.

PS. I'm adding comments to the monitor as and when I have a couple of hours free from "having a life" :D - you can see/check what I've done so far (for correct guessing) at https://github.com/NormanDunbar/QL-MultiMon but when done, I'll whack it back into the live repository, via a pull request.


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.
User avatar
janbredenbeek
Super Gold Card
Posts: 629
Joined: Wed Jan 21, 2015 4:54 pm
Location: Hilversum, The Netherlands

Re: QLMultimon - source question

Post by janbredenbeek »

Hi Norman,

Nice to see someone looking at the code I wrote more than 30 years ago :) . Please note that this was one of my first attempts at writing 68000 machinecode for the QL and, even by the standards at that time, very dirty programming practice! Multimon should really have been a resident program rather than an executable job, at least the exception handling code.
But to answer your question about the $54 offset of JB_TRAPV: this is a documented property of the QDOS exception handler, caused by the way the original QL ROM handles exceptions. You will find a series of BSRs starting at location $0028 in these ROMs which call a subroutine, which in turn uses the return address put on the stack to calculate the location of the user-defined exception vector. Since the first BSR is at $0028, the return addresses will be in the range $002A to $004E (in total 19 words sinds the BSRs are short ones). In order to find the (long word) vector's address, the ROM exception handler needs to double the return address so it will be in the range $0054 to $009C, and then - you guess it - subtract the base address of $0054. However, this offset is NOT subtracted at the time of execution but instead stored in JB_TRAPV/SV_TRAPV by the MT.TRAPV call, so this saves one SUB instruction in the exception handler.
Since the EXAM_REGS subroutine blatantly puts its own exception table in the examined job's JB_TRAPV vector, it has to take care of the $54 offset itself. (I really should have done this by using MT.TRAPV, but I felt a little uncomfortable calling QDOS TRAPs in exception handling code...).
Even Minerva observes this $54 offset although the ROM exception handlers are at different addresses there.
PS. I'm adding comments to the monitor as and when I have a couple of hours free from "having a life" :D - you can see/check what I've done so far (for correct guessing) at https://github.com/NormanDunbar/QL-MultiMon but when done, I'll whack it back into the live repository, via a pull request.
Thanks, I sometimes have a hard time figuring out what I was doing back then :) . I've done some work on the code too, mainly to clean things up but I still have plans to introduce new features. I will publish it on my GitHub page when it assembles to a more or less working version...

Jan.


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

Re: QLMultimon - source question

Post by NormanDunbar »

Hi Jan,

thanks for the reply. What you said didn't strike any memories for me - about the $54 being subtracted from the vertor table address - so I went looking. In the QDOS Technical Guide for QDOS 1.03, I saw nothing at all. I don't have a searchable PDF etc so it could be there, somewhere, but there's nothing in the job header details or in the description for MT_TRAPV.

Equally, I see nothing in Dickens. However, I do see, on page 94, of Pennell that JB_TRAPV and SV_TRAPV both get the current exception vector table minus $54, so that confirms what you said. Rather embarrassingly, I appear to have underlined the text describing this in my copy - so I obviously thought about it at some point since 1985 or so!

I also note that Dickens, Pennell and QDOS TG all mention that a job's JB_TRAPV can be safely modified by a trap, but if you want to modify it directly, you need "care".

I might add, that if you wrote a monitor as a first foray into learning MC68000 Assembly Language then you picked a hard program to learn with! Well done.


If you are looking for suggestions on improvements, I have one. On a breakpoint, there are two thinks I'd like to see:

1. The disassembly window (the one line one) should disassemble the instruction and not the TRAP #15. It's a little disconcerting to know where you are when you have multiple breakpoints and they all show TRAP #15 as the instruction "broken" at.

2. An option to keep a breakpoint after it has been executed. At the moment, If I need to break multiple times, I have to keep setting a break and, I think I remember this correctly, when I do, I get the TRAP #15 instruction in the breakpoint table as opposed to the one I really want! (I might be wrong on that though, I think I'm right.)


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.
User avatar
janbredenbeek
Super Gold Card
Posts: 629
Joined: Wed Jan 21, 2015 4:54 pm
Location: Hilversum, The Netherlands

Re: QLMultimon - source question

Post by janbredenbeek »

Hi Norman,
NormanDunbar wrote:Hi Jan,

thanks for the reply. What you said didn't strike any memories for me - about the $54 being subtracted from the vertor table address - so I went looking. In the QDOS Technical Guide for QDOS 1.03, I saw nothing at all. I don't have a searchable PDF etc so it could be there, somewhere, but there's nothing in the job header details or in the description for MT_TRAPV.

Equally, I see nothing in Dickens. However, I do see, on page 94, of Pennell that JB_TRAPV and SV_TRAPV both get the current exception vector table minus $54, so that confirms what you said. Rather embarrassingly, I appear to have underlined the text describing this in my copy - so I obviously thought about it at some point since 1985 or so!
I actually got my knowledge from Pennell. I still have that book, it's a real QDOS bible though it has some errors.
I also note that Dickens, Pennell and QDOS TG all mention that a job's JB_TRAPV can be safely modified by a trap, but if you want to modify it directly, you need "care".
The way Multimon handles exceptions now is quite dirty. It saves the registers in the current job's header (which is good) but then re-starts itself without using the scheduler. The exception handlers should really be a resident part (perhaps the whole code should run in supervisor mode like QMON - but that will probably be challenging to write).
I might add, that if you wrote a monitor as a first foray into learning MC68000 Assembly Language then you picked a hard program to learn with! Well done.
Well I started with the SuperBASIC disassembler from Pennell's first book but needed more speed, I also had already two years experience with assembly on the Spectrum (most of the layout was stolen from Hisoft's MONS :o ). I've had even written an assembler in SuperBASIC before only to find out that it was too slow to be of practical use ;) .
If you are looking for suggestions on improvements, I have one. On a breakpoint, there are two thinks I'd like to see:

1. The disassembly window (the one line one) should disassemble the instruction and not the TRAP #15. It's a little disconcerting to know where you are when you have multiple breakpoints and they all show TRAP #15 as the instruction "broken" at.

2. An option to keep a breakpoint after it has been executed. At the moment, If I need to break multiple times, I have to keep setting a break and, I think I remember this correctly, when I do, I get the TRAP #15 instruction in the breakpoint table as opposed to the one I really want! (I might be wrong on that though, I think I'm right.)
You should be able to set up to 10 breakpoints. But after taking a look at the code I discovered that it doesn't check if the address to be broken is already in the breakpoint table. This might explain why you got the TRAP #15 instead of the real instruction...

regards, Jan.


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

Re: QLMultimon - source question

Post by NormanDunbar »

I might be wrong but if the exception table is owned by job zero, it might work for all jobs. I need to check this at some point (after xmas!) - however I have a nagging feeling that I'm wrong on this!

Qmon and Qmon2 have bugs! Lau Reeves wrote a new monitor some years back and sent me a copy. I've looked everywhere for it and can't find it. Bugger!

I'm aware that I can set up to 10 breakpoints but I would like them to remain set after I've hit one when executing. At the moment, they get deleted from the table first time they are reached. If I'm in a loop, it only breaks once. :(

Anyway, I'm having fun adding comments. Mon1 is almost finished now. :D

I might have used you SuperBASIC assembler in the past, was it in the QUANTA library by any chance?

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.
User avatar
janbredenbeek
Super Gold Card
Posts: 629
Joined: Wed Jan 21, 2015 4:54 pm
Location: Hilversum, The Netherlands

Re: QLMultimon - source question

Post by janbredenbeek »

NormanDunbar wrote:I might be wrong but if the exception table is owned by job zero, it might work for all jobs. I need to check this at some point (after xmas!) - however I have a nagging feeling that I'm wrong on this!
To my best knowledge (Pennell, ROM disassembly) SV_TRAPV gets a copy from JB_TRAPV every time a job gets a timeslice, so it's the current job which 'owns' the exception table. Also, newly created jobs inherit the table from the creating job, not the owner job. Of course, if that job goes away without clearing JB_TRAPV you're in big trouble when an exception occurs...
I'm aware that I can set up to 10 breakpoints but I would like them to remain set after I've hit one when executing. At the moment, they get deleted from the table first time they are reached. If I'm in a loop, it only breaks once. :(
It should be fairly easy to implement - just leave off the BSR.S to REMOVEBRK in the EXBRKPNT handler. You can manually remove the breakpoint using the U command.
Anyway, I'm having fun adding comments. Mon1 is almost finished now. :D
It looks great! This must have been quite some hours of work to figure out! I've added a few corrections, you can merge these into your branch. I will probably use your commented version for further development, though I first have to figure out how to merge my unfinished changes with your comments...
I might have used you SuperBASIC assembler in the past, was it in the QUANTA library by any chance?
This would come as a surprise to me as I never have submitted it for a distribution library as far as I know, and I have lost the source anyway as it probably resided on a MDV cartridge that has gone bananas. But there is a remote chance that it has ended up somewhere in the Dutch Sin_QL_air library and maybe also the Quanta library.
It's not in my BBS archive either so I guess I must have lost it long ago, probably even before 1987.

regards, Jan.


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

Re: QLMultimon - source question

Post by NormanDunbar »

I knew I was wrong about the exceptions! It was the job owner and child jobs that I was thinking about. Thanks.

Is there a link to your corrections please, and I will get them merged.


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.
User avatar
tofro
Font of All Knowledge
Posts: 2685
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: QLMultimon - source question

Post by tofro »

janbredenbeek wrote:Also, newly created jobs inherit the table from the creating job, not the owner job. Of course, if that job goes away without clearing JB_TRAPV you're in big trouble when an exception occurs...
That sounds a bit like a system design fault to me, even if it's documented in the Technical guide (p. 14):
A job set up by, even if not owned by, a job which has set up a table of trap vectors, will use the same table as that job, until it is redefined.
As there is no life-time relationship between a job and its creator, but instead between the owner and the job. It can be worked around by clearing JB_TRAPV of the child before the creator terminates, as you say, but is still somewhat dangerous and un-intuitive.

Tobias


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

Re: QLMultimon - source question

Post by janbredenbeek »

NormanDunbar wrote:I knew I was wrong about the exceptions! It was the job owner and child jobs that I was thinking about. Thanks.

Is there a link to your corrections please, and I will get them merged.
I've done a pull request with my changes, you should be able to merge it into your own source tree.

regards, Jan.


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

Re: QLMultimon - source question

Post by janbredenbeek »

tofro wrote:
janbredenbeek wrote:Also, newly created jobs inherit the table from the creating job, not the owner job. Of course, if that job goes away without clearing JB_TRAPV you're in big trouble when an exception occurs...
That sounds a bit like a system design fault to me, even if it's documented in the Technical guide (p. 14):
A job set up by, even if not owned by, a job which has set up a table of trap vectors, will use the same table as that job, until it is redefined.
As there is no life-time relationship between a job and its creator, but instead between the owner and the job. It can be worked around by clearing JB_TRAPV of the child before the creator terminates, as you say, but is still somewhat dangerous and un-intuitive.
Which is the reason why it's better to have it somewhere in resident space. The code there would then be able to enter a monitor program or, if that's not possible, just present a Blue Screen of Death :D .

regards, Jan.


Post Reply