6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Wed Oct 02, 2024 8:37 pm

All times are UTC




Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Mon Apr 24, 2017 8:31 pm 
Offline

Joined: Sun Apr 16, 2017 2:35 am
Posts: 34
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.


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 24, 2017 9:45 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1948
Location: Sacramento, CA, USA
You're doing great, Nick! You might want to check out "WOZMON" for a minimal example, and work up from there.

Mike B.


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 24, 2017 11:04 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
There's been a bunch of discussion in the WOPR thread, towards the end.

viewtopic.php?f=12&t=4465


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 25, 2017 7:19 pm 
Offline
User avatar

Joined: Fri Mar 31, 2017 7:52 pm
Posts: 45
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


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 25, 2017 9:01 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1948
Location: Sacramento, CA, USA
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.


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 25, 2017 10:41 pm 
Offline
User avatar

Joined: Fri Mar 31, 2017 7:52 pm
Posts: 45
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


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 27, 2017 2:19 pm 
Offline

Joined: Sun Apr 16, 2017 2:35 am
Posts: 34
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.


Top
 Profile  
Reply with quote  
PostPosted: Mon May 22, 2017 2:32 am 
Offline

Joined: Sun Apr 16, 2017 2:35 am
Posts: 34
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!


Top
 Profile  
Reply with quote  
PostPosted: Mon May 22, 2017 4:21 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8521
Location: Southern California
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:
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?


Top
 Profile  
Reply with quote  
PostPosted: Mon May 22, 2017 5:13 am 
Offline

Joined: Sun Apr 16, 2017 2:35 am
Posts: 34
Thank you so much. I will give this a shot in the morning!


Top
 Profile  
Reply with quote  
PostPosted: Mon May 22, 2017 9:17 pm 
Offline

Joined: Sun Apr 16, 2017 2:35 am
Posts: 34
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!


Top
 Profile  
Reply with quote  
PostPosted: Mon May 22, 2017 9:40 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1383
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:
;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:
;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:
;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

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


Top
 Profile  
Reply with quote  
PostPosted: Tue May 23, 2017 12:48 am 
Offline

Joined: Sun Apr 16, 2017 2:35 am
Posts: 34
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:
;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:
;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:
;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.


Top
 Profile  
Reply with quote  
PostPosted: Tue May 23, 2017 1:30 pm 
Offline

Joined: Sun Apr 16, 2017 2:35 am
Posts: 34
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.


Top
 Profile  
Reply with quote  
PostPosted: Tue May 23, 2017 1:43 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1383
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

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


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 22 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: