Good 65816 monitor?

Programming the 6502 microprocessor and its relatives in assembly and other languages.
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Good 65816 monitor?

Post by BigDumbDinosaur »

fachat wrote:
Ah no worries. Thanks for standing in as my proverbial rubber duck ;-)
<Quack> <Quack>  Now where’s a towel so I can dry off and go back to bed?  :D

Oh, wait!  You must’ve been rubber duck debugging.  No need for the towel.  :P

For the record, I do Clyde debugging.  Clyde is the stuffed puppy who hangs out on one of the bookshelves in my office.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
fachat
Posts: 1123
Joined: 05 Jul 2005
Location: near Heidelberg, Germany
Contact:

Re: Good 65816 monitor?

Post by fachat »

Another find. In

Code: Select all

monreg
you are reading the register values using

Code: Select all

addr,y
addressing, which again conflicts with the direct page location of the list of shadow register.

Code: Select all

;                                                    
;                                                    
;       display .C, .X, .Y, SP & DP...               
;                                                    
.0000030 jsr printspc          ;spacing              
         rep #m_seta                                 
         lda reg_ax,y          ;get register value   
         sep #m_seta                                 
         jsr dpyhexw           ;convert & display    
        .rept s_word                                 
         iny                                         
        .endr                                        
         cpy #reg_dbx-reg_ax                         
         bcc .0000030          ;next                 
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/
fachat
Posts: 1123
Joined: 05 Jul 2005
Location: near Heidelberg, Germany
Contact:

Re: Good 65816 monitor?

Post by fachat »

There is another one on binasc:

Code: Select all

3112 T:1950  a2 00                    @0000040  ldx #0          ;operand index            
3113 T:1952  a0 05                              ldy #s_sfac-1         ;workspace index    
3114 T:1954                                    ;                                          
3115 T:1954  b5 19                    @0000050  lda faca,x            ;copy operand to... 
3116 T:1956  99 21 00                           sta facb,y            ;workspace in...    
3117 T:1959  88                                 dey                    ;big-endian order  
3118 T:195a  e8                                 inx                                       
Edit: loop unrolling this is only a single byte larger (and should even be quicker...)
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/
fachat
Posts: 1123
Joined: 05 Jul 2005
Location: near Heidelberg, Germany
Contact:

Re: Good 65816 monitor?

Post by fachat »

Now the only ,y addressing modes that potentially conflict are auxbuf and ibuffer, IFF I want to move them to directpage.
I did do this for auxbuf, by introducing an "auxbufp" that is set on init and points to the auxbuf.
I'll probably do that with ibuffer too....

The problem with both of them is that they are being addressed using a mixed bag of addressing modes, ,x ,y, and absolute, with varying indexes into them...

André

Edit: it's even worse, ibuffer is being used in pea as well as in immediate values....
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/
fachat
Posts: 1123
Joined: 05 Jul 2005
Location: near Heidelberg, Germany
Contact:

Re: Good 65816 monitor?

Post by fachat »

I have now (I htink) put all runtime variables into direct page.

Also, I have done some changes to improve handling on the Commodore full screen editor:
- you can edit memory dump in place, and it will continue such that you can just move through a full dump with <ret>
- you can edit disassembly in place, it will ignore the hex bytes in the output and the next line is prepared so that you only need to press <ret>

What I will probably also do is add "XM" "bits" display in each disassmbly output line. Currently it seems the assembler does not honor the "m" bit in the SR, as when I assemble with

Code: Select all

A 340 LDA #0
it assembles in 8bit mode even if the m bit is not set in the SR.

Having it in every line makes it easier to follow anyway, I'll probably add "MX" optional parameter to the D on how to start the disassembly, and on the A command anyway.

André

Edit: for your reference: https://github.com/fachat/upet_supermon816
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Good 65816 monitor?

Post by BigDumbDinosaur »

fachat wrote:
I have now (I htink) put all runtime variables into direct page.
I’ve been following along, but not commenting, to see where this is all headed.

When I wrote the first rendition of Supermon 816 (SM816), it was meant to be part of POC 1.0’s firmware—not a stand-alone program.  Up until POC V1.2, addressable ROM was 8 KB in size.  Accordingly, I did my best to contract the firmware, especially when I subsequently added the SCSI driver to POC V1.1’s firmware, along with some SM816 command extensions to access SCSI primitives.  Naturally, the BIOS API, reset and IRQ handlers had to be expanded to included the SCSI subsystem, which resulted in the code bumping into the ROM’s “walls.”  That, in turn, led to a reorganization of the memory map to increase addressable ROM space, which first appeared in POC V1.2.

From the beginning of firmware development, I have worked to keep a lid on total direct-page consumption so applications would not be starved.  Hence I split the firmware’s run-time storage between direct page and absolute addressing, depending on how such storage was being used, required addressing modes, and need-for-speed.  These efforts left a decent-sized direct-page block for applications that weren’t relocating direct page elsewhere while running.

With the development of POC V1.2, which has four TIA-232 serial I/O (SIO) channels, direct-page consumption had to be increased to accommodate the scaled-up (and rewritten-for-succinctness), interrupt-driven, SIO driver, which was now talking to a total of 13 chip registers (three per channel, plus a common register) and managing eight SIO queues.  Of the several techniques I investigated, I concluded the best results would be obtained by setting up a static pointer array on direct page for reading/writing queues and UART registers.  Doing so would facilitate routing I/O operations to a specific channel by passing a zero-based cardinal channel number into the SIO driver—using (<dp>,X) addressing to select a particular set of pointers in the array.

As a consequence of increasing the SIO driver’s direct-page “footprint,” I relocated more monitor variables to absolute storage, which had no affect on perceived performance, but maintained the unencumbered direct-page size.  Hence some of the code you see in SM816, such as the seemingly-illogical use of .Y to index direct-page addresses, is the result of size containment.  Given that the target for SM816 is a 65C816-powered machine running exclusively in native mode, there was no anticipation of a mixed-mode environment like what you have, which as you discovered, complicates matters.  :)

Quote:
What I will probably also do is add "XM" "bits" display in each disassmbly output line. Currently it seems the assembler does not honor the "m" bit in the SR, as when I assemble with

Code: Select all

A 340 LDA #0
it assembles in 8bit mode even if the m bit is not set in the SR.
The assembler’s behavior during immediate-mode instruction assembly is intentional.  The value in the SR shadow register is not necessarily what would be appropriate when the code being assembled is executed. which is why SR is ignored.  As no assembler has any way of knowing what are appropriate register sizes (not “modes”) at any given point when the program is running, it’s the programmer’s responsibility to make that determination.

As the assembler always reduces an operand to the minimum number of bits that will fit the instruction being assembled (which 6502 assemblers have been doing since time immemorial), assembling an eight-bit, immediate mode instruction with a byte-sized operand is the default, where possible.  If you need to “coerce” a byte-sized value into a word-sized operand, precede the immediate-mode operator (#) with a “bang” (!), e.g., LDA !#15, which example will assemble A9 15 00 and add $03 to PC following assembly.  Generation of a 16-bit operand is automatic if the value you enter during assembly is 16 bits.  That behavior also applies when using on-the-fly base conversion, e.g., LDA !#+21 instead of LDA !#15.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
fachat
Posts: 1123
Joined: 05 Jul 2005
Location: near Heidelberg, Germany
Contact:

Re: Good 65816 monitor?

Post by fachat »

Hi BDD, thanks for explaining your rationale!

I was just observing, not judging. I know that software is developed with specific intentions in mind and when I come with some different ideas, it sometimes clashes...

My goals is to basically have one copy of the assembler in RAM, and be able to run it - in parallel - multiple times. For this, I cannot use absolute addressing for any runtime variables. using direct page - esp. when it doesn't clobber the "real" zero page - is a nice approach for that. Also, as I finally decided to run in mapped memory, I am not really hindered by program size.
Btw, the assembler still fully runs in native mode. It's only when doing I/O that it jumps back to emulation mode for the actual I/O routines.

But let me say only this: my opinion on the 65816 addressing modes with direct page hasn't improved. While being able to redirect direct page "elsewhere" is a valuable feature, mixing up the addressing modes when direct page is not at zero makes it very cumbersome and error prone.

re: assembling with wide arguments. Understood. As I allow to edit the disassembly inline, I will probably add the "!" to the printout so when just pressing enter on the disassembled line, it should produce the very same assembly.

Also, as I just noticed,

Code: Select all

sta !12
does not produce a 16 bit addressing mode but gives an error. That would probably be a valuable addition, esp. when "$12" and "$0012" may be completely different physical addresses due to one being subject to direct page pointer and the other not.

Having said all that, thanks for the great piece of software! After all, a working 65816 monitor with assembler and disassembler in almost just 4k is a cool thing, and code is readable and well structured, so it is easy to patch it around for my purposes!

André
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Good 65816 monitor?

Post by BigDumbDinosaur »

fachat wrote:
My goals is to basically have one copy of the assembler in RAM, and be able to run it - in parallel - multiple times.
Ah...that you want to stuff all of Supermon 816’s variables into direct page now makes sense.  In effect, you are using the shared-text principle found in UNIX and Linux, starting with (if memory correctly serves me) with the 0413 style of a.out.  That sounds like an interesting exercise.  How are you handling the MPU stack?
Quote:
Btw, the assembler still fully runs in native mode. It's only when doing I/O that it jumps back to emulation mode for the actual I/O routines.
Mode switching is tricky—plenty of land mines await you, especially if an IRQ hits at an awkward moment.  How do you handle that?
Quote:
But let me say only this: my opinion on the 65816 addressing modes with direct page hasn't improved. While being able to redirect direct page "elsewhere" is a valuable feature, mixing up the addressing modes when direct page is not at zero makes it very cumbersome and error prone.
I’m not sure I understand.  What do you mean by “mixing up the addressing modes when direct page is not at zero makes it very cumbersome and error prone.”?
Quote:
re: assembling with wide arguments. Understood. As I allow to edit the disassembly inline, I will probably add the "!" to the printout so when just pressing enter on the disassembled line, it should produce the very same assembly.
That, I think, may prove to be an unwieldy enhancement to incorporate.
Quote:
Also, as I just noticed,

Code: Select all

sta !12

does not produce a 16 bit addressing mode but gives an error. That would probably be a valuable addition, esp. when "$12" and "$0012" may be completely different physical addresses due to one being subject to direct page pointer and the other not.
When Daryl, others and I were brainstorming how to handle the myriad addressing modes possible with the 816 for inclusion in his supercharged version of the Kowalski assembler, the question came up on how to force assembly of something such as STA $12 to have a 16- or 24-bit address operand.  We settled on STA \n<addr>, in which n is 1, 2 or 3.  Hence STA \2$12 would assemble as 8D 12 00 and STA \3$12 would assemble as 8F 12 00 00.

Although I have not had a reason to date to force expansion of the address operand in that fashion while assembling code in SM816, I will look over the operand-parsing section in the assembler to see if such expansion could be incorporated using the above method.  I want to reserve the use of ! for coercing byte-size immediate-mode operands to word-size.

Quote:
Having said all that, thanks for the great piece of software! After all, a working 65816 monitor with assembler and disassembler in almost just 4k is a cool thing, and code is readable and well structured, so it is easy to patch it around for my purposes!
You’re benefiting from a nearly half-century of experience in writing 6502 code, including a stint of about three years in which I did professional development on the Commodore 128DCR and Lt. Kernal.  That was a complex project and I went through great lengths while developing the package to thoroughly comment everything (including how to do ISAM with the C-128DCR/Lt. Kernal system).  The finished project had nearly 100,000 lines of code spread out over some 40 source files.  A full assembly of the entire package took two days of run time.  :shock"

When I embarked on the POC series and decided to do a deep dive into the 65C816, I followed old habits and carefully documented everything (and still have the early firmware from 16 years ago), especially the monitor.  Writing and debugging a full-featured monitor for the 816 proved to be a challenge, to say the least, with the disassembler probably the most challenging part, especially in trying to get immediate-mode disassembly correct.

So I am always glad when I read of someone using the monitor in their project.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
fachat
Posts: 1123
Joined: 05 Jul 2005
Location: near Heidelberg, Germany
Contact:

Re: Good 65816 monitor?

Post by fachat »

BigDumbDinosaur wrote:
fachat wrote:
My goals is to basically have one copy of the assembler in RAM, and be able to run it - in parallel - multiple times.
Ah...that you want to stuff all of Supermon 816’s variables into direct page now makes sense.  In effect, you are using the shared-text principle found in UNIX and Linux, starting with (if memory correctly serves me) with the 0413 style of a.out.  That sounds like an interesting exercise.  How are you handling the MPU stack?
I'm switching stacks between threads and I'm going to write a little thread switcher. Basically one thread only runs in the interrupt.
Quote:
Quote:
Btw, the assembler still fully runs in native mode. It's only when doing I/O that it jumps back to emulation mode for the actual I/O routines.
Mode switching is tricky—plenty of land mines await you, especially if an IRQ hits at an awkward moment.  How do you handle that?
As this is debug code only, when running "in the background" I'm just running with I=1, i.e. interrupts disabled.
Quote:
Quote:
But let me say only this: my opinion on the 65816 addressing modes with direct page hasn't improved. While being able to redirect direct page "elsewhere" is a valuable feature, mixing up the addressing modes when direct page is not at zero makes it very cumbersome and error prone.
I’m not sure I understand.  What do you mean by “mixing up the addressing modes when direct page is not at zero makes it very cumbersome and error prone.”?
Sorry that was not said clear enough. I mean that the 6502 already has only few index registers, and it depends on the register X or Y whether some addressing modes are available or not. And then the 65816 on top of that adds basically a second address space but _only_ for zeropage/direct page addressing. Combine that with the fact that assemblers automatically use directpage vs. absolute addressing depending not only on the address size (optimize to directpage when address < 256), but also on whether directpage mode even exists (even for addresses >255), I find it extremely difficult (if not annoying) making sure you end up using the correct address.
Quote:
Quote:
re: assembling with wide arguments. Understood. As I allow to edit the disassembly inline, I will probably add the "!" to the printout so when just pressing enter on the disassembled line, it should produce the very same assembly.
That, I think, may prove to be an unwieldy enhancement to incorporate.
Quote:
Also, as I just noticed,

Code: Select all

sta !12
does not produce a 16 bit addressing mode but gives an error. That would probably be a valuable addition, esp. when "$12" and "$0012" may be completely different physical addresses due to one being subject to direct page pointer and the other not.
When Daryl, others and I were brainstorming how to handle the myriad addressing modes possible with the 816 for inclusion in his supercharged version of the Kowalski assembler, the question came up on how to force assembly of something such as STA $12 to have a 16- or 24-bit address operand.  We settled on STA \n<addr>, in which n is 1, 2 or 3.  Hence STA \2$12 would assemble as 8D 12 00 and STA \3$12 would assemble as 8F 12 00 00.
Ah yes, I think I saw some (few) addressing modes in the assembler source... almost forgot...
Quote:
Although I have not had a reason to date to force expansion of the address operand in that fashion while assembling code in SM816, I will look over the operand-parsing section in the assembler to see if such expansion could be incorporated using the above method.  I want to reserve the use of ! for coercing byte-size immediate-mode operands to word-size.
Quote:
Having said all that, thanks for the great piece of software! After all, a working 65816 monitor with assembler and disassembler in almost just 4k is a cool thing, and code is readable and well structured, so it is easy to patch it around for my purposes!
You’re benefiting from a nearly half-century of experience in writing 6502 code, including a stint of about three years in which I did professional development on the Commodore 128DCR and Lt. Kernal.  That was a complex project and I went through great lengths while developing the package to thoroughly comment everything (including how to do ISAM with the C-128DCR/Lt. Kernal system).  The finished project had nearly 100,000 lines of code spread out over some 40 source files.  A full assembly of the entire package took two days of run time.  :shock"
Quite some feat! My BDOS is probably my largest project using the native assembler, and this ran in less then maybe an hour if all files are combined...
Quote:
When I embarked on the POC series and decided to do a deep dive into the 65C816, I followed old habits and carefully documented everything (and still have the early firmware from 16 years ago), especially the monitor.  Writing and debugging a full-featured monitor for the 816 proved to be a challenge, to say the least, with the disassembler probably the most challenging part, especially in trying to get immediate-mode disassembly correct.
Yes that is very good. I just recently have found even bugs in Sam Falvo's lib6502 disassembler, which I am using in my Micro-PET emulator, so getting that right in 65816 assembly instead of C is really cool!
Quote:
So I am always glad when I read of someone using the monitor in their project.
You can be proud of it!

André
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/
Post Reply