Where To Start Programming A Montior?

Building your first 6502-based project? We'll help you get started here.
NickH93
Posts: 34
Joined: 16 Apr 2017

Where To Start Programming A Montior?

Post by NickH93 »

Not sure if this falls under the category of newbies or programming, but I feel like it'd be the former.

I've gotten much farther in 65C02 assembly than I ever thought possible. I've made blinking LEDs in various sequences, and I've made a successful program to use bit-banging to display a given string of text on my Hitachi HD44780-based LCD. I find the language to be really hands on and I love it.

I've been working on keyboard input routines, etc....


Anyhow, does anyone have any good resources on where to start programming my own memory monitor?

I have the general idea of how it'd work, in terms of comparing my input with a given value to know which subroutine (command to execute) etc. I just am having a hard time figuring out how it would decipher multiple parts. Like for example "L 4000" in some monitor would have to decipher L for list, and 4000 as which address to display the contents of....etc.

Anyways, any good place to start?

Thanks all! You've all been the best resource imaginable.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Where To Start Programming A Montior?

Post by barrym95838 »

You're doing great, Nick! You might want to check out "WOZMON" for a minimal example, and work up from there.

Mike B.
whartung
Posts: 1004
Joined: 13 Dec 2003

Re: Where To Start Programming A Montior?

Post by whartung »

There's been a bunch of discussion in the WOPR thread, towards the end.

viewtopic.php?f=12&t=4465
User avatar
jim30109
Posts: 45
Joined: 31 Mar 2017

Re: Where To Start Programming A Montior?

Post by jim30109 »

One question to ask yourself is what you want to use it for.

I'm working towards two 16k EPROMs. Actually probably one 32k that I can bank switch.

With one, I want BASIC and something of a barebones monitor. With the other I want a full blown monitor with support for breakpoints, stepping, simple assembly, and simple disassembly. (It will probably also have VTL when I'm done.)

One thing that was also "table stakes" for me was the ability to create and load Intel HEX files.

I started with Jeff Tranter's JMON in part because it supports the 65c816. It is very heavily modified and I've gutted out features I won't use. I've also modified the commands to be more natural to me and in line with the 1802 monitor I use on another build.

Once you get into the guts of most well written monitors you will probably find it easy to tweak and build on.

Thanks,
Jim W4JBM
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Where To Start Programming A Montior?

Post by barrym95838 »

jim30109 wrote:
... (It will probably also have VTL when I'm done.) ...
Heck, you could probably integrate a monitor into VTL02 and provide some decent functionality for a few hundred more bytes of code.

Mike B.
User avatar
jim30109
Posts: 45
Joined: 31 Mar 2017

Re: Where To Start Programming A Montior?

Post by jim30109 »

That's an interesting idea. I know one of the challenges I've had is trying to scale back Page Zero and stack usage so I can use the monitor without having to worry too much about conflicts. But VTL is pretty light--I have been thinking of it more as something that could fill out a 16k ROM than something that could act as a monitor shell.

I'm going to have to think on that a bit, but I kind of like that idea just as something to try.

Jim
NickH93
Posts: 34
Joined: 16 Apr 2017

Re: Where To Start Programming A Montior?

Post by NickH93 »

Thanks everyone for the tips. Looking at these examples does help a lot, but I think for the mean time I'm going to port a monitor for my use.

There are just some things I still don't seem to get, especially when it comes to parsing and processing a command. Baby steps. I just need to start there.

I have nothing against the ACIA based monitors, I only want to write one so I can use it with my character LCD.

As far as what I hope to do with it, no more than your average. WOZMON is a perfect example of what I'm looking for actually. Read, write, and run.

Anyways, looks like I have some more research to do.
NickH93
Posts: 34
Joined: 16 Apr 2017

Re: Where To Start Programming A Montior?

Post by NickH93 »

So, update:


I have officially got a keyboard interface, using Daryl Rictor's AVR PC keyboard decoder with an ATTiny26, working beautifully and storing characters on my LCD and in a buffer with no bounce. Wooo!

Anyways, I've gotten more and more pieces to the puzzle on how to make a monitor, and I will share my progress the more I get it, but I've run into a roadblock:

The keyboard interface and LCD all run off of ASCII hex codes

Is there any way to convert ASCII into hex data, but not the ASCII code?

For example, if I type in say "30" in ASCII, that I could convert that into just $30

That way, if I type what I WANT to be the address of 4000 on my keyboard, the computer would know to look at $4000, and not 4000 in ASCII hex codes?

Thanks!
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Where To Start Programming A Montior?

Post by GARTHWILSON »

NickH93 wrote:
Is there any way to convert ASCII into hex data, but not the ASCII code?

For example < . . . >
There are various ways to do it, but here's probably almost the simplest for 16-bit on the 65c02. It does not include base conversions, error-checking, or finding the numerals in the string, but it does include initializing the variable, and it covers the possibility of different numbers of hex digits (up to four):

Code: Select all

Init:   STZ  <variable>
        STZ  <variable+1>
        RTS
 ;------------------

DIGIT:  SEC                  ; Start with ASCII digit in A.  Must be in the range of 0-9 and A-F.
        SBC  #$30            ; Put number in the range of 0-9 and $11-16
        CMP  #$0A            ; Is it too high to be in the 0-9 range?
        BCC  1$
        SBC  #7              ; If so, bring $11-16 down to $0A-$0F.  (C was still set.)

 1$:    ASL  <variable>      ; Now scoot anything that was in the variable over by four bits
        ROL  <variable+1>    ; (shifting 0's in on the right), to make room for the new digit
                             ; as least significant.  This does not affect the accumulator.
        ASL  <variable>
        ROL  <variable+1>

        ASL  <variable>
        ROL  <variable+1>

        ASL  <variable>
        ROL  <variable+1>

        ORA  <variable>      ; Now put the new digit in on the right.
        STA  <variable>

        RTS
 ;------------------
With only slight additional complexity, you may be able to build it on the stack (either the page-1 hardware stack or a virtual stack in ZP or elsewhere) and eliminate the variable.

There's a page of more-involved code on this site at http://6502.org/source/strings/ascii-to-32bit.html .
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
NickH93
Posts: 34
Joined: 16 Apr 2017

Re: Where To Start Programming A Montior?

Post by NickH93 »

Thank you so much. I will give this a shot in the morning!
NickH93
Posts: 34
Joined: 16 Apr 2017

Re: Where To Start Programming A Montior?

Post by NickH93 »

Thank you so much for that code. It works perfectly.

I am so close to having a monitor that should display a byte of data at any given address.


The last piece of the puzzle is to just to be able to do the opposite. The value I want to display is in hex, and I want it in ASCII.

Is there a similar piece of code to do this?

Thanks!
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: Where To Start Programming A Montior?

Post by floobydust »

NickH93 wrote:
Thank you so much for that code. It works perfectly.

I am so close to having a monitor that should display a byte of data at any given address.


The last piece of the puzzle is to just to be able to do the opposite. The value I want to display is in hex, and I want it in ASCII.

Is there a similar piece of code to do this?

Thanks!
You should search for the book "6502 Assembly Language Subroutines" written by Levanthal and Saville. Excellent in all and covers a lot of the routines you would require to write a monitor. It's pretty much a staple for 6502 programming and shows source code and usage. You'll find most monitors use a handful of useful routines for code conversion as you need to do this at the command line to get input data and display output data.

I've re-written many such routines either leveraging 65C02 opcodes and/or addressing modes and in some cases just to make them shorter and/or faster. Here's a piece of code that will do what you want from a byte value in the A reg:

Code: Select all

;BIN2ASC subroutine: Convert byte in A register to two ASCII HEX digits
;Return: A register = high digit, Y register = low digit
BIN2ASC		PHA	;Save A Reg on stack
					AND	#$0F	;Mask off high nibble
					JSR	ASCII	;Convert nibble to ASCII HEX digit
					TAY	;Move to Y Reg
					PLA	;Get character back from stack
					LSR	A	;Shift high nibble to lower 4 bits
					LSR	A
					LSR	A
					LSR	A
;
ASCII			CMP	#$0A	;Check for 10 or less
					BCC	ASOK	;Branch if less than 10
					CLC	;Clear carry for addition
					ADC	#$07	;Add $07 for A-F
ASOK			ADC	#$30	;Add $30 for ASCII
					RTS	;Return to caller
So, to use this, simply load the A reg with the byte value and then you can print the ASCII characters directly using something like this, which uses the above routine:

Code: Select all

;PRBYTE subroutine:
; Converts a single Byte to 2 HEX ASCII characters and sends to console
; on entry, A reg contains the Byte to convert/send
; Register contents are preserved on entry/exit
PRBYTE		PHA	;Save A register
					PHY	;Save Y register
PRBYT2		JSR	BIN2ASC	;Convert A reg to 2 ASCII Hex characters
					JSR	CHROUT	;Print high nibble from A reg
					TYA	;Transfer low nibble to A reg
					JSR	CHROUT	;Print low nibble from A reg
					PLY	;Restore Y Register
					PLA	;Restore A Register
					RTS	;And return to caller
In the above routine, CHROUT simply prints the character in the A reg to a terminal via an async port.

If you need to print a word (2 bytes) use the above code and this routine:

Code: Select all

;PRWORD	subroutine:
;	Converts a 16-bit word to 4 HEX ASCII characters and sends to console
; on entry, A reg contains High Byte, Y reg contains Low Byte
; Register contents are preserved on entry/exit
PRWORD		PHA	;Save A register
					PHY	;Save Y register
					JSR	PRBYTE	;Convert and print one HEX character (00-FF)
					TYA	;Get Low byte value
					BRA	PRBYT2	;Finish up Low Byte and exit
NickH93
Posts: 34
Joined: 16 Apr 2017

Re: Where To Start Programming A Montior?

Post by NickH93 »

floobydust wrote:
NickH93 wrote:
Thank you so much for that code. It works perfectly.

I am so close to having a monitor that should display a byte of data at any given address.


The last piece of the puzzle is to just to be able to do the opposite. The value I want to display is in hex, and I want it in ASCII.

Is there a similar piece of code to do this?

Thanks!
You should search for the book "6502 Assembly Language Subroutines" written by Levanthal and Saville. Excellent in all and covers a lot of the routines you would require to write a monitor. It's pretty much a staple for 6502 programming and shows source code and usage. You'll find most monitors use a handful of useful routines for code conversion as you need to do this at the command line to get input data and display output data.

I've re-written many such routines either leveraging 65C02 opcodes and/or addressing modes and in some cases just to make them shorter and/or faster. Here's a piece of code that will do what you want from a byte value in the A reg:

Code: Select all

;BIN2ASC subroutine: Convert byte in A register to two ASCII HEX digits
;Return: A register = high digit, Y register = low digit
BIN2ASC		PHA	;Save A Reg on stack
					AND	#$0F	;Mask off high nibble
					JSR	ASCII	;Convert nibble to ASCII HEX digit
					TAY	;Move to Y Reg
					PLA	;Get character back from stack
					LSR	A	;Shift high nibble to lower 4 bits
					LSR	A
					LSR	A
					LSR	A
;
ASCII			CMP	#$0A	;Check for 10 or less
					BCC	ASOK	;Branch if less than 10
					CLC	;Clear carry for addition
					ADC	#$07	;Add $07 for A-F
ASOK			ADC	#$30	;Add $30 for ASCII
					RTS	;Return to caller
So, to use this, simply load the A reg with the byte value and then you can print the ASCII characters directly using something like this, which uses the above routine:

Code: Select all

;PRBYTE subroutine:
; Converts a single Byte to 2 HEX ASCII characters and sends to console
; on entry, A reg contains the Byte to convert/send
; Register contents are preserved on entry/exit
PRBYTE		PHA	;Save A register
					PHY	;Save Y register
PRBYT2		JSR	BIN2ASC	;Convert A reg to 2 ASCII Hex characters
					JSR	CHROUT	;Print high nibble from A reg
					TYA	;Transfer low nibble to A reg
					JSR	CHROUT	;Print low nibble from A reg
					PLY	;Restore Y Register
					PLA	;Restore A Register
					RTS	;And return to caller
In the above routine, CHROUT simply prints the character in the A reg to a terminal via an async port.

If you need to print a word (2 bytes) use the above code and this routine:

Code: Select all

;PRWORD	subroutine:
;	Converts a 16-bit word to 4 HEX ASCII characters and sends to console
; on entry, A reg contains High Byte, Y reg contains Low Byte
; Register contents are preserved on entry/exit
PRWORD		PHA	;Save A register
					PHY	;Save Y register
					JSR	PRBYTE	;Convert and print one HEX character (00-FF)
					TYA	;Get Low byte value
					BRA	PRBYT2	;Finish up Low Byte and exit


Thank you so much for your help. I will try this out and search for this book as well.
NickH93
Posts: 34
Joined: 16 Apr 2017

Re: Where To Start Programming A Montior?

Post by NickH93 »

Well I'm happy to report through everyone's help, and lots of studying and learning on my own, I officially have a monitor that will read back the data stored at an address. Verified it with my reset vector, some test data, and the start of my EEPROM. 100% accuracy! :D

I've also made a write command to write a value to an address with limited success. Doesn't work always. Got too tired to figure out why it didn't always work and I will try again today, but I WAS able to switch off an LED by writing data to the VIA's output register, and then verify the byte was written by reading that address.

I plan on adding a run command. That should be easy enough.

Never thought I'd get this computer running, let alone program my own monitor. Quite exciting.
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: Where To Start Programming A Montior?

Post by floobydust »

NickH93 wrote:
Well I'm happy to report through everyone's help, and lots of studying and learning on my own, I officially have a monitor that will read back the data stored at an address. Verified it with my reset vector, some test data, and the start of my EEPROM. 100% accuracy! :D

I've also made a write command to write a value to an address with limited success. Doesn't work always. Got too tired to figure out why it didn't always work and I will try again today, but I WAS able to switch off an LED by writing data to the VIA's output register, and then verify the byte was written by reading that address.

I plan on adding a run command. That should be easy enough.

Never thought I'd get this computer running, let alone program my own monitor. Quite exciting.
It's always nice to have some successes when starting out. Glad to hear that you're on your way with the monitor code. I also found a link for the book download. I bought a copy when it first came out, but it's nice to have a PDF version for travel.

https://ia800907.us.archive.org/24/item ... utines.pdf
Post Reply