6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 11:43 pm

All times are UTC




Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Tue May 03, 2022 2:10 am 
Offline

Joined: Sat Oct 09, 2021 11:21 am
Posts: 718
Location: Texas
This is an extension from my "Acolyte 6502/VGA" topic here:

viewtopic.php?f=4&t=7096

Hello everyone! I want your critiquing and criticism. I want to know what is good and what is bad about my monitor program. Attached is a picture with guiding points of interest.

The main idea is that you type these commands, and it reads/writes/modifies hex code. The disassembler on the side is new, but very useful. I am planning/hoping to add an assembler as well, just another command and a lot of code essentially. You can also use the arrow keys and page up/down to move the cursor around. Kind of a mix between straight command-line and a "GUI" if you can call it that.

I've been researching this stuff for a bit. Wozmon, Tedmon, Supermon, etc. A page like this is very helpful to see what features I should be aiming towards:

https://www.c64-wiki.com/wiki/TEDMON

I know that mine is not like that, and it will never be. My video memory is write-only, so I cannot easily just move back up a line or two and resubmit it like you could in Tedmon or some such. That is why I'm focusing on displaying a 'GUI' style with a cursor and all that. Plus that seemed user friendly to me.

The goal here is to make something more-or-less self sufficient. Stand alone. The user can write their own code, save it for later, but also load and run files from another computer, etc. Like a mini-operating system. It would replace what would usually be filled with BASIC or some such. I also want it as user friendly as a monitor can be. Less technical, more ease of use. A big example of this is using the arrow keys to move the cursor around.

What do you suggest? What things would make this better? It could be aesthetic, it could be functional. Some examples you could critique could be:

- The letters/symbols for commands. Or even, my choice of commands, or lack thereof.
- The layout on the screen.
- Even the way this is using the cursor and selection conceptually.

I know I'm asking pros here, but put your newbie hat on for a minute and tell me: What would make this good to use? Better? Easier?

Thoughts? Comments? Critiques? Criticisms? You won't hurt my feelings, I'm just wanting a good end-user product.

Thank you everyone, I appreciate your insights.

Chad


Attachments:
AcolyteMonitor1.asm [61.62 KiB]
Downloaded 53 times
MonitorHelp.jpg
MonitorHelp.jpg [ 3.75 MiB | Viewed 1433 times ]
Top
 Profile  
Reply with quote  
PostPosted: Tue May 03, 2022 2:57 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8507
Location: Midwestern USA
TEDMON is Commodore’s adaptation of Jim Butterfield’s Supermon 64. The version found in the C-128 was not called TEDMON, according to Fred Bowen and actually was closer to Supermon 64 than was TEDMON.

Unless you plan to incorporate a full-screen editor into your firmware, I recommend you seek a copy of the Supermon 64 source code and study it in detail. Trying to decipher some of Commodore’s mods to Supermon 64 will be an exercise in patience.

BTW, when I wrote Supermon 816, I copied the user interface of Supermon 64, which had been around in one form or another since the 1970s. I saw no reason to deviate from something that every Commodore assembly language programmer and his pet donkey had used since antiquity.

I strongly advise against modeling WozMon. It was not one of Wozniak’s sterling programming efforts and, in fact, is a sort of “black sheep” in today’s 6502 world.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Tue May 03, 2022 6:40 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
The design looks reasonable to me - navigation looks sensible, as does the layout.

I'd advise looking as widely as possible at other monitors - not restricted to Commodore, or to Apple, or even necessarily to 6502.

I suspect it's better to start with useful functions which are feasible to implement, and then decide on which command letters to use - if indeed the choice of single-letter commands feels right. That is, don't start with 26 letters and see which commands they might stand for.

It might be worth thinking how to display the story of machine states if and when you implement single-stepping.


Top
 Profile  
Reply with quote  
PostPosted: Tue May 03, 2022 7:39 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
BigDumbDinosaur wrote:
It was not one of Wozniak’s sterling programming efforts and, in fact, is a sort of “black sheep” in today’s 6502 world.
Are you speaking on behalf of today's 65xx world, or just your corner of it?
WOZMON is notably limited, but in my opinion was a perfect mate to the hardware on which it ran (256 bytes of ROM, no cursor controls except CR). The "address-first" command structure is a matter of taste, and kind of reminds me of RPN in a pleasing way. Would your "black sheep" opinion apply to classic HP hand-held calculators as well? There's nothing wrong with having a personal opinion, as long as it's characterized as such.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Tue May 03, 2022 10:01 am 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
Well, asking for a critique can be dangerous, but I'll take an initial stab at it. I would echo some of the existing comments and also agree with BDD on doing a deep dive on existing code like Supermon 64 and others.

The user interface will most likely be something that you're comfortable with. I wouldn't say you should pattern it after another monitor, but as Ed noted, look at other monitor programs to get an idea on how the UI was done and what functions were included. As far as functions go, I'd suggest making a list of requirements you think you will need to make working with the hardware easy and functional. Having a consistent command structure is also nice, as many commands will have similar input parameters.

I did take a look at your source code.... I will take a "stab" at it.... it's not very useful, in my opinion of course. What I see here is a lack of structure, virtually no comments and very little to suggest what is being done in the routines. You might want to consider creating a separate BIOS for your hardware and make those routines accessible via a JUMP table, which is quite common. The BIOS would have a clearly defined set of functions against the hardware that can be used by a Monitor program or other applications/utilities. The Monitor part could also be written as a separate program that only uses the BIOS to communicate with your hardware. It also could have a JUMP table to make core routines accessible from other applications/utilities.

I would recommend getting copies of some existing manuals, such as the "6502 Assembly Language Subroutines" by Leventhal/Saville. You will find many useful bits of code there which you can likely adapt to what you need, or at least get a better idea on how to write certain types of routines. Going back to your code, there are so many sections which are a "brute force" approach, i.e., sending a mnemonic to your screen. You load the A reg with each character and send it through a routine. Writing a routine that sends a string of characters would be most useful here and significantly reduce your code size.

It would be useful to include a help screen that simply shows what the commands are with some basic input parameters. Commenting your code will be useful to you in the future, when you go back and look at it some years later. Here's a small snippet of code from my C02Monitor that is the input routine that checks for a command and calls the appropriate routine from a command table for execution.

Code:
;**************************************************************************************************
;*                              Command input loop                                                *
;**************************************************************************************************
;*                      This is the Monitor Warm start vector                                     *
;**************************************************************************************************
WARM_MON        LDX     #$FF            ;Initialize Stack pointer
                TXS                     ;Xfer to stack
                RMB7    CMDFLAG         ;Clear bit7 of command flag
                LDA     #$16            ;Get prompt msg
                JSR     PROMPT          ;Send to terminal
;
CMON            JSR     RDCHAR          ;Wait for keystroke (converts to upper-case)
                LDX     #MONTAB-MONCMD-1        ;Get command list count
CMD_LP          CMP     MONCMD,X        ;Compare to command list
                BNE     CMD_DEC         ;Check for next command and loop
                PHA                     ;Save keystroke
                TXA                     ;Xfer Command index to A Reg
                ASL     A               ;Multiply keystroke value by 2 (command offset)
                TAX                     ;Xfer Command offset address to table MONTAB
                PLA                     ;Restore keystroke (some commands send to terminal)
                JSR     DOCMD           ;Call Monitor command processor as a subroutine
                BRA     WARM_MON        ;Command processed, branch / wait for next command
DOCMD           JMP     (MONTAB,X)      ;Execute command from Table
;
CMD_DEC         DEX                     ;Decrement index count
                BPL     CMD_LP          ;If more to check, loop back
                JSR     BEEP            ;Beep for error, not valid command character
                BRA     CMON            ;Branch back and re-enter Monitor
;


I would note that many of us old guys tend to use shorter labels, in my case, mainly because the assembler I used back in the 80's had limits on how long a label could be, so most folks simply looked at making them short and trying to make them somewhat obvious for what they are... but sometimes you have to punt on these. But in any case, I tend to comment heavily, especially in my BIOS section. I also add clock cycle counts for key code sections in the BIOS that touches the hardware, which comes in pretty handy at times for debugging problems elsewhere. An example of this is:

Code:
;**************************************************************************************************
;
;Interrupt 1 - This is the ISR which is responsible for servicing the IDE controller.
; The RTC does not require any ISR capabilities as no Alarm functions are being used in the BIOS.
; There are extra inserts which can be used if needed at a later date.
; The only functions that might make sense would be to add the Alarm function at a future date.
; Once the IDE controller BIOS has matured, if there's any room left in the allocated ROM area,
; I'll revisit it.
;
;The ISR for the IDE controller will handle the data transfer for LBA read/write/verify functions
; and handle any error functions. By design, the 16-bit Data Transfer feature is used for:
; Reading / Writing / Verifying of all LBA block data and the IDE Identification data.
;
;The BIOS is using the Alternate Status register to determine if DRQ (Data Request) is active.
; This works as a handshake for 16-bit data transfers without issue. Note that the normal Status
; register resets the interrupt when read, so this is only done once in the ISR per loop.
;
;Update: This ISR has been moved to the front of the ISR chain, i.e., this ISR routine gets
; serviced first, then jumps to the next ISR, which services the DUART. This makes a noticeable
; improvement in data transfer from the IDE controller. Note that overhead for this routine will
; add 33 clock cycles if it just exits (IDE controller did not generate an interrupt).
;
;To check if an interrupt has been generated by the IDE controller, the Alternate Status register
; can be read. This contains the same information as the standard Status register but will NOT
; reset the interrupt on the IDE controller. By reading the Alternate Status register first, we
; can first determine what the status of the IDE controller is and take action if required.
; Note that not all bit settings imply an interrupt was generated. Specifically, looking at the
; bit definitions below, Bits 6 and 4 are set when the IDE is ready, hence a normal condition
; where nothing requires any attention. Also, a Busy condition can imply the IDE controller is
; working on a command but may not have generated an interrupt yet. If The Busy bit (7) is set,
; then all other bits are invalid per Seagate documentation, so we trigger on that first.
;
;One annoying feature for IDE is "when" interrupts are generated. For any Read operation, once
; the command has been accepted, data is placed into the IDE buffer, followed by generating
; an interrupt to the system. Once this is done, the system will read the data. By accessing the
; Status register, the interrupt will be reset. This is normal operation. For a write operation,
; The command is sent, then DRQ goes active, which requires the data be sent to the IDE Device.
; Once the data is written, an interrupt is generated after it's completed.
; As a result, there's little function of having an ISR for servicing the write function.
; As interrupts are enabled for the IDE Controller, all generated interrupts must be handled.
;
; Status Register bits as defined as follows:
;       - Bit 7 = Busy (a Command has been accepted)
;       - Bit 6 = Ready (IDE controller is ready to accept a command)
;       - Bit 5 = Write Fault (A write command failed against the media)
;       - Bit 4 = DSC (is set when a Seek is completed)
;       - Bit 3 = Data Request (set when there is data to transfer, read or write)
;       - Bit 2 = Correction (set when a recoverable data error was corrected)
;       - Bit 1 = 0 (not used)
;       - Bit 0 = Error (set when the previous command had an unrecoverable error)
;
;       NOTE: 25 clock cycles to here if DUART ISR is second!
;
INTERUPT1                               ;Interrupt 1 (IDE)
                LDA     IDE_ALT_STATUS  ;Get Alternate Status Register (4)
                BMI     REGEXT01        ;If Busy bit active, just exit (2/3)
;
; - Check for Data Request (DRQ), as the Read LBA operation is the main function
;   of the ISR, which will handle the data transfer from the IDE controller to store the
;   data into memory. This ISR will handle single and multiple block transfers.
;
                LDA     IDE_STATUS      ;Get Status (resets IRQ) (4)
                AND     #%00001000      ;Check for DRQ (2)
                BNE     IDE_READ_BLK    ;Branch if active (2/3)
;
; - If no DRQ is sensed, the other possibilities are:
; 1- A LBA Write has occurred and the interrupt was generated after the transfer.
; 2- A Verify operation has occurred and the interrupt was generated after the verify.
; So we check for these two options and branch accordingly.
;
                BBS2    MATCH,IDE_WRIT_BLK      ;If Bit 2 set, Write operation (5)
                BBS1    MATCH,IDE_VRFY_BLK      ;If Bit 1 set, Verify operation (5)
                BRA     REGEXT01                ;Exit ISR handler (3)
;
IDE_READ_BLK                            ;IDE Read a Block of data
;
;Note: Arrival here means that the DRQ bit in the status register is active.
; This implies that:
;  1- A LBA Block Read is in progress. If so, the data transfer will be handled below.
;     This also handles multiple LBA Reads and manages the pointers and such. It also
;     clears the LBA Read bit in the MATCH Flag when completed.
;
;  2- A LBA Block Write with multilpe blocks is in progress. If so, the actual data
;     transfer is handled via the IDE WRITE Block routine. An interrupt is generated
;     at the end of each LBA transfer, so that is monitored here and the LBA Write bit
;     in the MATCH Flag is cleared when there are no more blocks to transfer.
;
;Also realize that this ISR will be executed every time the DUART generates an interrupt.
; This will happen every 10ms for the Jiffy-Clock timer and for character transmit and receive.
;
                BBR3    MATCH,REGEXT01  ;If Bit 3 clear, IDE Write (5)
;
LBA_XFER        LDA     IDE_ALT_STATUS  ;Get Status (clears IRQ) (4)
                AND     #%00001000      ;Check for DRQ (2)
                BEQ     IDE_RD_DONE     ;If not active, done, exit (2/3)
;
IDE_RD_RBLK
                LDA     IDE_DATA        ;Read low byte (high byte in latch) (4)
                STA     (BIOS_XFERL)    ;Store low byte (5)
                INC     BIOS_XFERL      ;Increment pointers (5)
                BNE     IDE_RD_BLK1     ; (2/3)
                INC     BIOS_XFERH      ; (5)
IDE_RD_BLK1
                LDA     IDE_16_READ     ;Read high byte from latch (4)
                STA     (BIOS_XFERL)    ;Store high byte (5)
                INC     BIOS_XFERL      ;Increment pointers (5)
                BNE     LBA_XFER        ;Loop back to Xfer, saves 3 clock cycles (2/3)
                INC     BIOS_XFERH      ; (5)
IDE_RD_BLK2
                BRA     LBA_XFER        ;Loop back till no more DRQs (3)
;
IDE_RD_DONE     DEC     BIOS_XFERC      ;Decrement Block Count to transfer (5)
                BNE     IDE_ALL_DONE    ;Branch around Flag Reset until all blocks moved (2/3)
                RMB3    MATCH           ;Clear Read Block flag (5)
;
IDE_ALL_DONE    LDA     IDE_ALT_STATUS  ;Get Alternate Status Register (4)
                STA     IDE_STATUS_RAM  ;Save it to RAM location (3)
REGEXT01        JMP     (VECINSRT0)     ;Exit ISR handler (6)
;
IDE_WRIT_BLK                            ;IDE Write a Block of data
                LDA     BIOS_XFERC      ;Check Block Count to transfer (3)
                BNE     IDE_ALL_DONE    ;Branch to exit if more blocks need to be moved (2/3)
                RMB2    MATCH           ;Clear Write Block flag (5)
                BRA     IDE_ALL_DONE    ;Branch and finish ISR (3)
;
IDE_VRFY_BLK                            ;IDE Verify a Block of data
                RMB1    MATCH           ;Clear Verify Block flag (5)
                BRA     IDE_ALL_DONE    ;Branch and finish ISR (3)
;
;**************************************************************************************************


One last bit of input from my side.... I tend to put limits on the amount of space any code should be. For my current C02 Pocket SBC, I have a limit for the BIOS of 2KB less the I/O window, which is 160 bytes located at $FE00. I also have a JMP table at $FF00. The BIOS code starts at $F800. For the Monitor code, it has a limit of 6KB, from $E000 to $F7FF. There are also limits on how much Page Zero space is used for the BIOS and Monitor. I also think you might want to break up the code a bit... separate modules that you can link together, one being a set of code defines and equates for your hardware addresses, page zero usage, etc. Feel free to grab any of my code from my GitHub page and use whatever you like. You'll find some areas of my code that others (like Mike Barry and BDD) have suggested as improvements and were implemented.

Finally, have fun doing this... and comment everything, as years down the road, when you look at your own code, you'll be scratching you head asking yourself what it all does :shock:

Hope this is useful...

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Tue May 03, 2022 12:09 pm 
Offline

Joined: Sat Oct 09, 2021 11:21 am
Posts: 718
Location: Texas
BigDumbDinosaur wrote:
BTW, when I wrote Supermon 816, I copied the user interface of Supermon 64, which had been around in one form or another since the 1970s. I saw no reason to deviate from something that every Commodore assembly language programmer and his pet donkey had used since antiquity.


I found this: https://github.com/jblang/supermon64

Essentially the command style is the same as what I was thinking. Use single letter functions, type stuff after it, hit enter, stuff happens. Print results on a need-only basis (as in, don't print out the entire 256 byte page of data each time!). If you are fancy, be able to go back up to those existing lines, modify, and hit enter, stuff happens.

Because my video display is write-only, vertical scrolling is out of the question (unless I duplicate everything in RAM of course). That is why I went with a non-conventional display style. But I will highly consider what you are saying BDD. Being more "universal" is very important.

What was the name of your pet donkey? :)

BigEd wrote:
I'd advise looking as widely as possible at other monitors - not restricted to Commodore, or to Apple, or even necessarily to 6502.


It is very difficult to search for "monitors" on the web. Because this LCD display thingy I'm viewing this all on is also called a "monitor". Plus, I was a baby/toddler in the 80's so I don't remember any names of these things. More often than not, I simply stumble upon them while searching. Is there some type of list of monitors that I can start looking more specifically into?

BigEd wrote:
It might be worth thinking how to display the story of machine states if and when you implement single-stepping.


Hm. Hadn't even thought of that. Maybe I'm looking for an "Assembler" and not a "Monitor"?

barrym95838 wrote:
BigDumbDinosaur wrote:
It was not one of Wozniak’s sterling programming efforts and, in fact, is a sort of “black sheep” in today’s 6502 world.
Are you speaking on behalf of today's 65xx world, or just your corner of it?
WOZMON is notably limited, but in my opinion was a perfect mate to the hardware on which it ran (256 bytes of ROM, no cursor controls except CR). The "address-first" command structure is a matter of taste, and kind of reminds me of RPN in a pleasing way. Would your "black sheep" opinion apply to classic HP hand-held calculators as well? There's nothing wrong with having a personal opinion, as long as it's characterized as such.


I didn't want to start a fight :) I personally like WozMon, I think it's super compact and makes sense. Yes, it's primitive, but it was for the Apple 1, not Apple 2.

floobydust wrote:
The user interface will most likely be something that you're comfortable with. I wouldn't say you should pattern it after another monitor, but as Ed noted, look at other monitor programs to get an idea on how the UI was done and what functions were included. As far as functions go, I'd suggest making a list of requirements you think you will need to make working with the hardware easy and functional. Having a consistent command structure is also nice, as many commands will have similar input parameters.


Ok, that is also good advice. Honestly I've been thinking of going with a more 'menu' approach. Or some type of 'autocomplete'. I know that sounds fancy, but it is just trying to prevent errors and help the computer with parsing.

floobydust wrote:
I did take a look at your source code....


Uh oh... ;)

floobydust wrote:
I will take a "stab" at it.... it's not very useful, in my opinion of course. What I see here is a lack of structure, virtually no comments and very little to suggest what is being done in the routines. You might want to consider creating a separate BIOS for your hardware and make those routines accessible via a JUMP table, which is quite common. The BIOS would have a clearly defined set of functions against the hardware that can be used by a Monitor program or other applications/utilities. The Monitor part could also be written as a separate program that only uses the BIOS to communicate with your hardware. It also could have a JUMP table to make core routines accessible from other applications/utilities.


I included my code just as an afterthought. My first intention here was to find what the user side of things would be like. "Hey guys, what makes a car nice to drive in? Radio? Four doors? Air conditioning? Cigarette lighter?" Kevin, your response was, "Dude, let's pop the hood!" Haha! And yeah, my fuel line is dangerously close to the radiator, I'm lacking a idle screw on my carburetor, and it's emitting blue smoke from the exhaust. A warning light is on the dash, something about my alternator. And the lightbulb to my license plate is out: TICKET!

floobydust wrote:
I would recommend getting copies of some existing manuals, such as the "6502 Assembly Language Subroutines" by Leventhal/Saville. You will find many useful bits of code there which you can likely adapt to what you need, or at least get a better idea on how to write certain types of routines. Going back to your code, there are so many sections which are a "brute force" approach, i.e., sending a mnemonic to your screen. You load the A reg with each character and send it through a routine. Writing a routine that sends a string of characters would be most useful here and significantly reduce your code size.


I know that my code is very inefficient at this point. I'm still so new to Assembly. I think like I'm programming in C still. Still, I also feel like I usually learn this stuff best when the need arises. For example, the brute force method of mnemonics, at this point is no big deal because I have a TON of ROM left over, and I'm too lazy to focus on making that portion of code efficient. However, my PS/2 keyboard signals were having overlapping interrupts, and so I had to tighten that code a lot to make it work. And work now it does, so I move on to the next thing. This is not best practices, but I'm not a professional anyways. I learn best when I need to learn it.

floobydust wrote:
One last bit of input from my side.... I tend to put limits on the amount of space any code should be. For my current C02 Pocket SBC, I have a limit for the BIOS of 2KB less the I/O window, which is 160 bytes located at $FE00. I also have a JMP table at $FF00. The BIOS code starts at $F800. For the Monitor code, it has a limit of 6KB, from $E000 to $F7FF. There are also limits on how much Page Zero space is used for the BIOS and Monitor. I also think you might want to break up the code a bit... separate modules that you can link together, one being a set of code defines and equates for your hardware addresses, page zero usage, etc. Feel free to grab any of my code from my GitHub page and use whatever you like. You'll find some areas of my code that others (like Mike Barry and BDD) have suggested as improvements and were implemented.


I looked up one of your monitors: https://github.com/floobydust/Micromon- ... croMon.asm

I see you are using the single letter instructions, and I think you have a focus primarily on MONITORING the system. I don't even have a command to look at the accumulator! I think more and more that I am really just wanting an "Assembler", not a "Monitor" so much. Hm.

The jump tables are interesting to me. I don't yet understand their usefulness entirely though. I see we have two things:

RTS is "go somewhere for a bit, and come right back"
JMP is "go somewhere and do not come back"

If I were to "go somewhere and not come back", well that is the next line of code anyways! As in, straight-lining code is itself a long list of "go to the next line and do not come back".

floobydust wrote:
Finally, have fun doing this... and comment everything, as years down the road, when you look at your own code, you'll be scratching you head asking yourself what it all does :shock:

Hope this is useful...


Yes it is, thank you very much. I definitely need to comment. I *will* do that soon enough. Right now I'm still experimenting. If this whole code I've been typing gets deleted tomorrow, I wouldn't cry much. I'm still learning, so this is one big tutorial essentially. Comments and efficient will come eventually.

Well, thank you everyone for this so far! I am starting to see that I really just want an Assembler, not an Monitor. Well, monitor is still good and all, but maybe not the first reasoning. I don't care so much about "what is in the accumulator" or "how many clock cycles have elapsed" or "single stepping through code". Instead I'm looking for "write this code, execute, see results" or "download this pre-existing code and run it". A replacement for BASIC, but using Assembly language instead. So, in the very least, you all have helped me see my goals better. Thank you for that.

Chad


Top
 Profile  
Reply with quote  
PostPosted: Tue May 03, 2022 12:54 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
Good point about the difficulty of search...

My UK101 had a remarkably minimal monitor - it was enough to inspect and modify any byte, and to start execution at any address, and that was it. As I recall, it only displayed the current address and current contents, and gave no clue as to the command letters- and no feedback either.

It was, however, enough, in the sense that one could load a program and run it, and to a very limited extent debug it. Most likely one would use this monitor as a loader, to load something more functional.

But it probably was as it was because it used hardly any ROM space. Similarly for Woz, I'm sure - no coincidence that it's 256 bytes.

Bruce here wrote a one page monitor, called c'mon. (Edit: I see now c'mon is written for the '816)

Everything beyond what my uk101 monitor could do is a matter of increasing convenience and putting off the time to load up something more functional. A line by line disassembler is handy, as is a one page or more memory dump. Something to fill memory with a constant is common enough. Something to search for a string or byte sequence can be handy.

Probably only by using a monitor will you get a feel for what facilities you'll want to add. But I think once you've executed a program and found that it misbehaves, you'll find a single step utility quite useful.


Top
 Profile  
Reply with quote  
PostPosted: Tue May 03, 2022 2:40 pm 
Offline

Joined: Sat Feb 19, 2022 10:14 pm
Posts: 147
I was at a similar point last year, wondering what functions/features to add to my 6502 monitor program. I had started with Wozmon and was adding functions one at a time. This got old after a while. Looking for something more holistic, I remembered the references to the Forth language often discussed on this site. I found it to make an excellent operating system for my 6502 builds.

There are a lot of good resources for Forth. To just get an idea of what it is, Nick Morgan's Easy Forth provides a nice web-based interative introduction.

For my own system, I started with Jonesforth (not specific to the 6502 but very instructional for writing your own system) and Scot W. Stevenson's Tali Forth 2 (a well developed system for the 6502).

One nice thing about Forth is that all of the work you've done already can be easily incorporated into it.


Top
 Profile  
Reply with quote  
PostPosted: Tue May 03, 2022 2:42 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
Chad, I took a look at your source, and I see your predilection for in-lining. It's one solution to a problem, and suits your style, so I can't bring myself to criticize working code, especially if you wrote it by yourself for yourself, and intend to debug and maintain it yourself. There are hundreds of opportunities in there to comment better and to apply the "DRY" principle, if those qualities float your boat as much as they do mine. If they don't, then I'm okay with that. Although ...
Code:
   INX
   CPX #$00
   BNE
   ...
Someone here (not I) once remarked that a kitten dies every time those three instructions appear together in a 65xx source.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Tue May 03, 2022 2:44 pm 
Offline

Joined: Sun Nov 08, 2009 1:56 am
Posts: 411
Location: Minnesota
I kind of like the screen layout, but I'm a bit confused by what it's actually showing. I see three points - a page and disassembly start at $9000, a cursor at $9020 and a selection at $9080 - and I'm not sure why they're distinct. I would expect that disassembly would start at either the cursor position or the selection start. Maybe a separate command to "disassemble from cursor position" to be used after "move cursor"?

The selected area is fairly clear, but might be even more clear if in inverse video. Is there anything I can do with a selection, once I have one?

I would not immediately associate "L" with "load audio file". Maybe "A"? I associate "X" with "exit monitor" and "G" for "go to address and start execution".

"R" and "W" are pretty clearly associated with a fixed (and implied) EEPROM address. That being the case, why not also have a fixed RAM buffer to read and write to and from? Is there any situation in which it would be an advantage to have a variable RAM starting address? I certainly do not know but suspect that in practice you already pretty much always use the same RAM addresses already (at least I would). If so, they're easily hard-coded and can be changed by anyone who has access to the source code.

You might think about an option to display memory as ASCII or ISO-Latin-1 (if your character generator supports it), so any character strings are more readily picked out.


Top
 Profile  
Reply with quote  
PostPosted: Tue May 03, 2022 4:01 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 491
sburrow wrote:
Hm. Hadn't even thought of that. Maybe I'm looking for an "Assembler" and not a "Monitor"?


It might be helpful to expand your search to include "Debuggers." There's a lot of functional overlap between old-thyme monitors and debuggers. The functionality you're going for seems to be pretty close to the old DOS "debug" program. There's an open-source reimplementation of it in FreeDOS. I don't know how helpful it would be for deep study, since it's for a totally different architecture.

All of Dr. Dobbs Journal is available on (I believe) archive.org. The first volume (the issues from its first year of publication, which was 1976, if I remember right) has some good 6502 stuff, including a 6502 disassembler from Woz and Allen, 6502 breakpoint routines, a mini floating point package, and an actual monitor program. Listings for these programs usually fit on a page or two. They are often very strange looking and minimally commented. The monitor program I just mentioned has the addressing mode for every instruction printed in parentheses after each mnemonic!

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Tue May 03, 2022 4:27 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
I searched for [6502 machine monitor] and the results looked pretty much on-topic. (Edit: and similarly for z80)


Top
 Profile  
Reply with quote  
PostPosted: Tue May 03, 2022 9:46 pm 
Offline

Joined: Sat Oct 09, 2021 11:21 am
Posts: 718
Location: Texas
tmr4 wrote:
Looking for something more holistic, I remembered the references to the Forth language often discussed on this site. I found it to make an excellent operating system for my 6502 builds.

One nice thing about Forth is that all of the work you've done already can be easily incorporated into it.


That is a really good idea. I hear that you can type Assembly in Forth and it's perfectly fine with it. I will have to think that over. Good idea though.

barrym95838 wrote:
Code:
   INX
   CPX #$00
   BNE
   ...
Someone here (not I) once remarked that a kitten dies every time those three instructions appear together in a 65xx source.


Meow. Poor kittens. I am guessing it is because INX flags Z?

teamtempest wrote:
I kind of like the screen layout, but I'm a bit confused by what it's actually showing. I see three points - a page and disassembly start at $9000, a cursor at $9020 and a selection at $9080 - and I'm not sure why they're distinct. I would expect that disassembly would start at either the cursor position or the selection start. Maybe a separate command to "disassemble from cursor position" to be used after "move cursor"?


Right. I had experimented with that, but then I would want to code to not always just start from the cursor position, say if I wanted to edit something further down, but still look at what is above and below that location.

teamtempest wrote:
The selected area is fairly clear, but might be even more clear if in inverse video. Is there anything I can do with a selection, once I have one?


Oooo, THAT is a good idea! I like that a lot! The selection is mainly whenever you Move or Read or Save. Like you said, it's the 'highlighted' portion.

teamtempest wrote:
You might think about an option to display memory as ASCII or ISO-Latin-1 (if your character generator supports it), so any character strings are more readily picked out.


I've been thinking about that too. In the end, I decided the code would be better. BUT, I'm thinking of something entirely new now...

Paganini wrote:
All of Dr. Dobbs Journal is available on (I believe) archive.org. The first volume (the issues from its first year of publication, which was 1976, if I remember right) has some good 6502 stuff, including a 6502 disassembler from Woz and Allen, 6502 breakpoint routines, a mini floating point package, and an actual monitor program. Listings for these programs usually fit on a page or two. They are often very strange looking and minimally commented. The monitor program I just mentioned has the addressing mode for every instruction printed in parentheses after each mnemonic!


I saw that just a bit ago. Very cool! I really don't know Apple very well, so I don't know how much I could convert their code to my code. But that is good to see stuff is out there. Thank you.

So, I've been thinking about this a lot throughout the day. I think my "monitor" is ok enough, but what I'm wanting to do is make an "assembler". This would have to be a nearly separate piece of software. I'm not ditching all of what I have, but I'm planning on not having a wall of hex all of the time now. I'm trying to work out ways to make the mnemonics and addressing modes work smoothly right now, mainly with lookup tables. I've attempted it a few times today and I'm kind of failing. But that's ok, when I fail, I just try something else! Eventually I'll get it to work :)

Thanks for the advice everyone. I'll probably be showing you something entirely different soon enough. When I have time, that is. And if this REALLY fails, then I'll probably be giving Forth a try.

Chad


Top
 Profile  
Reply with quote  
PostPosted: Sun May 29, 2022 8:40 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
sburrow wrote:
The jump tables are interesting to me. I don't yet understand their usefulness entirely though. I see we have two things:

RTS is "go somewhere for a bit, and come right back"
JMP is "go somewhere and do not come back"


A jump table is a way to future proof your design. It is a list of jumps starting at a given address. Your application calls the BIOS/Kernel routines by performing a JSR to a given address in the jump table. That address is a JMP to the actual routine which ends with an RTS. In future versions of your BIOS/Kernel, the starting address of system routines could change. The jump table, as part of the BIOS, is changed accordingly. Suppose for the sake of argument that address $FFD2 is a jump to a routine to output a character to the display, address $FFD5 is a jump to a routine to load data from an external device to RAM, and address $FFD8 is a routine to send data from ram to an external device. The locations of these routines will not matter to whoever writes an application for your system, even if the locations change. Only the locations in the jump table will matter. In this example, a JSR to $FFD2 will always output a character regardless of the address of the routine to do so.


Top
 Profile  
Reply with quote  
PostPosted: Sun May 29, 2022 8:51 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895

Just saw this thread on jump tables.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 10 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: