ASSIST09 Monitor
ASSIST09 Monitor
The ASSIST09 Monitor was published by Motorola in their official MC6809 Programmers Reference Manual, circa 1981.
ASSIST09 is a 2KB Monitor, which is designed to take advantage of the 6809’s position independent coding ability. The 12 available Service Calls are called in a position independent manner via a SWI call.
The Monitor also provides hooks for replacing internal services with user written routines (for use by ASSIST09), and also provides the ability for user written extensions to be called on start-up.
I have provided a verified original ASSIST09 Assembly source code, which I’ve updated for compatibility with the ASM6809 Cross Assembler (which I currently use). This can be found on the MECB GitHub repository, as: ASSIST09_Original_ASM6809.asm
This topic is for any ASSIST09 related discussion.
ASSIST09 is a 2KB Monitor, which is designed to take advantage of the 6809’s position independent coding ability. The 12 available Service Calls are called in a position independent manner via a SWI call.
The Monitor also provides hooks for replacing internal services with user written routines (for use by ASSIST09), and also provides the ability for user written extensions to be called on start-up.
I have provided a verified original ASSIST09 Assembly source code, which I’ve updated for compatibility with the ASM6809 Cross Assembler (which I currently use). This can be found on the MECB GitHub repository, as: ASSIST09_Original_ASM6809.asm
This topic is for any ASSIST09 related discussion.
Re: MECB 6809 Testing, Coding, Sound!
This may not be the best channel to ask this and it is a bit of tangent to the previous discussion but I was curious if you were familiar with the use of functions available via the vector table in ASSIST09? In particular I was wanted to call CIDTA to provide a means to exit out of my long test loops without blocking the loop i.e. check for a key press. I can get the address of the routine via the VECTRSW system call but the function doesn't seem to work when I call it. My suspicion is that the direct page is incorrect and that is preventing the function from operating correctly but it is unclear to me how to set it in an appropriate manner. It looks like DP needs to be set to $DF - I could do that manually, and that does make things work, but it seems to defeat the purpose of all the abstracting of internals that ASSIST09 seems to be doing. I guess I was expecting the DP to be set by ASSIST09 to whatever it uses when starting a loaded program but it seems that isn't the case. Do you happen to know if there is a legit way to set up the DP for ASSIST09 use?
Re: MECB 6809 Testing, Coding, Sound!
I've made a new topic "ASSIST09 Monitor" (and moved your post here), as it seemed appropriate to create a seperate topic for any discussion ASSIST09 related.
Note that the VECTRSW service call is intended for replacing ASSIST09 services with user written replacements.epaell wrote: ↑Fri Mar 22, 2024 10:31 pm In particular I was wanted to call CIDTA to provide a means to exit out of my long test loops without blocking the loop i.e. check for a key press. I can get the address of the routine via the VECTRSW system call but the function doesn't seem to work when I call it. My suspicion is that the direct page is incorrect and that is preventing the function from operating correctly but it is unclear to me how to set it in an appropriate manner. It looks like DP needs to be set to $DF - I could do that manually, and that does make things work, but it seems to defeat the purpose of all the abstracting of internals that ASSIST09 seems to be doing. I guess I was expecting the DP to be set by ASSIST09 to whatever it uses when starting a loaded program but it seems that isn't the case. Do you happen to know if there is a legit way to set up the DP for ASSIST09 use?
i.e. Swapping the address of an internal routine for a new replacement routine you have written (for ASSIST09 to use).
In the case of the CIDTA routine, you'd call VECTRSW with code $22, if you wanted to replace the .CIDTA entry to instead point to your own routine (if perhaps you had implemented a keyboard to replace the default ACIA input routine).
ASSIST09 itself would then use your new keyboard / character input implementation, instead of its default serial terminal input.
Obtaining the address of the internal CIDTA routine (via VECTRSW service), is not intended for you to then call the ROM routine. Hence your observation about an otherwise apparent DP register assumption.
There are only 12 Service Routines provided by ASSIST09, all called via SWI for position independance.
The only character input routine is INCHP (Code 0), which returns the input character (in A). Unfortunately this is a blocking call, so return is held until a character is available.
If you were wanting a non-blocking input character check routine, you would need to write your own handler.
If using the default ACIA serial terminal input, you could optionally use VECTRSW to obtain the .ACIA address in the system (thereby ensuring the ACIA physical address only needs to be specified within the ASSIST09 code).
Of course, if you were using an alternate character input interface (e.g. your own keyboard interface, or an alternate secondary ACIA etc.), you'd have written your own drivers / service routines anyway.
Hope this helps to clarify?
Re: ASSIST09 Monitor
I noticed that if index register X is set to 0 and A=<vector> when calling the VCTRSW service, it returns the current address of the vector being requested. So for _ACIA it returns $E008 and for _CIDTA it returns $FADC. That's why I was getting hopeful that I could just query those addresses and make use of them as they stand in ASSIST09 just to avoid duplicating code. Unfortunately, the first line of the routine I wanted used direct page addressing and the DP seemed to be set to something different to what ASSIST09 was using.
It's not a major issue and is simple enough to inherit the non-blocking code from ASSIST09 with a bit of cut and paste - I guess I just have a bit of an uneasy feeling about repeating code that I know is already there ... but I also have an uneasy feeling about hacking the DP value to make that code work.
BTW, it was funny watching your second recent ROM-expansion video because I went through the exact same steps in trying to get asm6809 to compile ASSIST09 a week or two ago (because I wanted to get the assembly listing). I assumed that you were using asm6809 for it previously so was surprised that I had to make changes to the code ... but your recent video explained the history of that and looks like we went through the exact same steps in changing the code.
It's not a major issue and is simple enough to inherit the non-blocking code from ASSIST09 with a bit of cut and paste - I guess I just have a bit of an uneasy feeling about repeating code that I know is already there ... but I also have an uneasy feeling about hacking the DP value to make that code work.
BTW, it was funny watching your second recent ROM-expansion video because I went through the exact same steps in trying to get asm6809 to compile ASSIST09 a week or two ago (because I wanted to get the assembly listing). I assumed that you were using asm6809 for it previously so was surprised that I had to make changes to the code ... but your recent video explained the history of that and looks like we went through the exact same steps in changing the code.
Re: ASSIST09 Monitor
Yes, X is intended to hold the replacement handler address, or zero if just wanting to query the existing address.epaell wrote: ↑Sat Mar 23, 2024 11:03 pm I noticed that if index register X is set to 0 and A=<vector> when calling the VCTRSW service, it returns the current address of the vector being requested. So for _ACIA it returns $E008 and for _CIDTA it returns $FADC. That's why I was getting hopeful that I could just query those addresses and make use of them as they stand in ASSIST09 just to avoid duplicating code. Unfortunately, the first line of the routine I wanted used direct page addressing and the DP seemed to be set to something different to what ASSIST09 was using.
On return X always holds the previous value of the vector (which would still be the current value, if X was 0 on entry).
I'm not clear on what the intended purpose of being able to query the existing address is, given it is intended as a vector swap service, and there doesn't appear to be any efficencies / logic to "checking first".
It's probably that query ability alone, that creates confusion! Perhaps they thought it was just a logical thing to do if a zero address is passed?
EDIT: In retrospect, I wrote the above sentences thinking only of routine addresses (for ASSIST09 extended indirect calls), overlooking the fact that the vector table also includes resource addresses (which are of course valid to query). Perhaps this would have been better implemented as two seperate tables. One just for routine addresses (with no query function), and one just for resource addresses (with a query function). No doubt this has been debated many times before (over the last 40+ years since the code was written. LOL).
I can certainly see the temptation of wanting to call the existing routine, instead of duplicating code.
I suppose you could use code 0 (A=0), to retrieve the vector table address (.AVTBL), knowing that ASSIST09 defaults to having the vector table in the work page. Therefore, the high byte of the return value, is the value you want for the DP register setup.epaell wrote: ↑Sat Mar 23, 2024 11:03 pm It's not a major issue and is simple enough to inherit the non-blocking code from ASSIST09 with a bit of cut and paste - I guess I just have a bit of an uneasy feeling about repeating code that I know is already there ... but I also have an uneasy feeling about hacking the DP value to make that code work.
However, this probaby goes against all the rules, as you are then assuming that the .AVTBL address hasn't been changed by another process.
Although if it's all your code, and you've commented it properly, I guess you would be making a reasonably safe assumption.
EDIT: Actually, as the routine is using DP to access a vector table entry, it's the current vector table address that's actually relevant (so ignore what I said in the two sentences above).
Plus, there's the issue of whether you should be saving and restoring the existing DP value. By which time you probably should just steal / duplicate the ASSIST09 CIDTA code.
LOL. That's really funny. When I was doing it, I remember thinking that this has probably been done many times before.epaell wrote: ↑Sat Mar 23, 2024 11:03 pm BTW, it was funny watching your second recent ROM-expansion video because I went through the exact same steps in trying to get asm6809 to compile ASSIST09 a week or two ago (because I wanted to get the assembly listing). I assumed that you were using asm6809 for it previously so was surprised that I had to make changes to the code ... but your recent video explained the history of that and looks like we went through the exact same steps in changing the code.
I guess by making a video of my process and the fact that I was able to compare the assembled code to an original "known good" ROM dump from the 80s, I felt it would at least be potentially useful to someone else, so I made the result available via github.
Hopefully this helps save at least one other duplication of effort in the future.
Re: ASSIST09 Monitor
Is everyone able to single step code using ASSIST09? I'm not getting optimal function out of the monitor. Which is to say, I don't get behavior outline in the manual.
It seems that breakpoints will break only one time.
I am unable to trace at all. T #, or . is behaviorally equivalent to G.
Breakpoints don't seem to work properly; if I stop at a breakpoint and type G again, expecting to loop back to the breakpoint, it never does.
I'm getting around this by inserting and breaking on a NOP before the instruction I'm interested in. After breaking at the NOP I can type G <address of NOP + 1> and code will continue through the loop and break again.
And I've been able to step through code by deleting and inserting breakpoints after every break, but this is obviously not a great way to debug.
It's likely I've got something wrong. But not sure what as of now. I'm working my way through the ASSIST09 code, and pulling back the veil, but I'm certainly not there yet.
How exactly does STlevel work? I think I'm setting an address (depth) of the stack at which trace is suppressed, but maybe I'm not really understanding it.
I have managed to get some fixed point math working and I'm displaying a sine wave on the terminal. Funny how something so simple can be so rewarding. I still have to put my video card together and fix up an RGB to VGA converter.
It seems that breakpoints will break only one time.
I am unable to trace at all. T #, or . is behaviorally equivalent to G.
Breakpoints don't seem to work properly; if I stop at a breakpoint and type G again, expecting to loop back to the breakpoint, it never does.
I'm getting around this by inserting and breaking on a NOP before the instruction I'm interested in. After breaking at the NOP I can type G <address of NOP + 1> and code will continue through the loop and break again.
And I've been able to step through code by deleting and inserting breakpoints after every break, but this is obviously not a great way to debug.
It's likely I've got something wrong. But not sure what as of now. I'm working my way through the ASSIST09 code, and pulling back the veil, but I'm certainly not there yet.
How exactly does STlevel work? I think I'm setting an address (depth) of the stack at which trace is suppressed, but maybe I'm not really understanding it.
I have managed to get some fixed point math working and I'm displaying a sine wave on the terminal. Funny how something so simple can be so rewarding. I still have to put my video card together and fix up an RGB to VGA converter.
Re: ASSIST09 Monitor
Hi Mike. I did a video where I walked-through an example of single stepping with ASSIST09, and also explained the 'S' command (Stlevel).
You can find this here: Retro 8-bit - Motorola 6809 - 80's WireWrap Homebrew (Part 2 - Fire it up! - and Hello World) - 25:22 - Code Tracing / Single Stepping
With ASSIST09, breakpoints and single stepping are controlled by the NMI Interrupt, triggered by a timer in the 6840 PTM.
If not working for you as demonstrated, (on your MECB system), then first thing I'd check is that the NMI jumper on your Motorola I/O Card is in-place (and generating a low Interrupt pulse on the NMI bus line). Then, I'd check that your MC6840 PTM is functioning correctly.
Hope this helps with diagnosing the issue.
Re: ASSIST09 Monitor
YES! That was it. I didn't have the NMI jumper on the Motorola I/O card. Thanks Greg -- I am having such a good time with your MECB 6809 computer!
Re: ASSIST09 Monitor
Awesome! I'm so glad it was that simple! I guess, this is due to the flexibility I designed in. So, the PTM NMI connection is optional (in case it wasn't desired for your use-case). If I'd hard-wired it, then it wouldn't catch you out, but then you also wouldn't have the flexibility.
Re: ASSIST09 Monitor
And I wouldn't have learned as much! I think it's a good design and I wouldn't change it.
Not to mention that I'm not sure if I would appreciate what ASSIST09 is doing for me if I hadn't gone through all the hoops in my initial debugging!