6502 with a serial port - a minimal monitor?

Programming the 6502 microprocessor and its relatives in assembly and other languages.
User avatar
enso
Posts: 904
Joined: 29 Sep 2012

Re: 6502 with a serial port - a minimal monitor?

Post by enso »

Garth, you make many good points. Toolchains spin out of control; assemblers don't.

As for the external macro engine - it' just a source transformation, so in case of conditional assembly, parts of the source will not be included in the output. Is there a tricky part I am missing?

With macros there are plenty of tricky points. For instance - do you just run one pass? Or do you run multiple passes until your output is stable (no more macros to expand). If you have macros defining other macros, it can get strange. Or when macro parameters change during the transformation process.. Some assemblers insist on certain values being constant, often to my dismay.
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut
User avatar
GARTHWILSON
Forum Moderator
Posts: 8774
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: 6502 with a serial port - a minimal monitor?

Post by GARTHWILSON »

The toolchain makers want to integrate everything, so if you have different ones for different families of products from different companies, the editor which is where you spend much of your time won't be consistent from one to the next. Why not use a really, really good one (like MultiEdit in my case) so you can know and use the same one for everything. It has the ability, if you want to use it, to highlight structures for different languages, link to different assemblers to highlight errors caught in assembly, etc.. I don't need a proprietary toolchain for that. I've had up to about 34 different files open at once, some minimized, others tiled and windowed different ways, and some just hiding, and this is in DOS, and it's all point-and-click, and uses a hi-res monitor allowing you to see two full pages side by side if you wish. I use the same editor for different assemblers and compilers.
Quote:
As for the external macro engine - it' just a source transformation, so in case of conditional assembly, parts of the source will not be included in the output. Is there a tricky part I am missing?
Regarding the conditional assembly, I was partly thinking of whether it would work the same way in the macros as in non-macro parts of the assembly code. If they were two separate pieces of software written by different people, they might not work the same.
Quote:
With macros there are plenty of tricky points. For instance - do you just run one pass? Or do you run multiple passes until your output is stable (no more macros to expand). If you have macros defining other macros, it can get strange. Or when macro parameters change during the transformation process. Some assemblers insist on certain values being constant, often to my dismay.
I'm a macro junkie. I had only one special case, 22 years ago, where something required the assembler to make more than the normal two passes. I can't remember what it was. It was plenty fast though, and the extra few seconds' wait was no big deal. I've never heard of macros defining macros, although I might be able to imagine a use for it (similar to OOP). Macros must always be defined before they're invoked though, including invocation by another macro, and defining one and then not using it does not carry any penalties like an unused subroutine would. The whole reason for the two-pass assembler of course is that the first pass will encounter references to many program labels that are still ahead and unknown. The operand fields will be left blank and later filled in on the second pass after they have been found. This would go for macros too, where parameters may refer to labels that come after the macro invocation. We did have another topic recently where someone apparently had problems because variables were being referred to before they were defined (which is not a good programming practice), and the assembler did not know yet in the first pass if it should leave one byte or two for the operand for ZP versus abs addressing.
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?
User avatar
enso
Posts: 904
Joined: 29 Sep 2012

Re: 6502 with a serial port - a minimal monitor?

Post by enso »

In fasm on x86 and ARM, I used recursive macro definitions extensively to build dictionaries for Forth-like systems. For every word in the bootstrap kernel the HEAD macro was redefined to include its previous definition with the new head appended and linked to previous one. In the end, the macro was executed, creating hundreds of words perfectly linked and ready to go! I learned that trick from the creators of RetroForth, I think (before they decided to use some kind of a VM and the whole project became useless for me). Creating a bootstrap Forth environment with macros is surprisingly impossible with some assemblers.

In particular, you want to keep the pointer to the last word in a variable after its defined, so that the next one can create a link pointer to it. Some assemblers just can't keep that variable set correctly. In many, you cant ORG <variable> or <expression>, so you can't adjust the output pointer or calculate the position of objects in memory dynamically.
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut
User avatar
enso
Posts: 904
Joined: 29 Sep 2012

Re: 6502 with a serial port - a minimal monitor?

Post by enso »

Daryl, thanks for such quick help. I love your monitor and am enjoying it greatly.

Tomorrow I will try to integrate a serial load command. Any tips? It should be trivial, but worth checking...

I was thinking about sending a binary with a 16-bit address, 16-bit size. This way a simple keystroke should be enough to load a file, without any parameters...
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: 6502 with a serial port - a minimal monitor?

Post by 8BIT »

enso wrote:
Daryl, thanks for such quick help. I love your monitor and am enjoying it greatly.

Tomorrow I will try to integrate a serial load command. Any tips? It should be trivial, but worth checking...

I was thinking about sending a binary with a 16-bit address, 16-bit size. This way a simple keystroke should be enough to load a file, without any parameters...
Sounds easy enough. Read the first 4 bytes, put the first two in the startaddr, startaddr_h pair in zero page. The put the next two in addrptr, addrptr_h pair. These are defined in SBC2os.asm.

Then read a byte, store using sta (startaddr),y or sta (startaddr,x) (with x or y properly set to 0). The increment addrptr pair and decrement the addrptr pair until it reaches 0. As long as you use handshaking to ensure no bytes are lost, it should work.

You can optimize for speed later, if needed.

Daryl
Please visit my website -> https://sbc.rictor.org/
teamtempest
Posts: 443
Joined: 08 Nov 2009
Location: Minnesota
Contact:

Re: 6502 with a serial port - a minimal monitor?

Post by teamtempest »

Quote:
I did find another bug last year in C32 (with INCLude files in a macro not getting included until the macro is finished) but found a way around it.
I still claim that may not be a bug but a reasonable design choice. Mostly because HXA would do the same thing if I let it, instead of flagging it as an error. Nested macros and nested includes are treated separately, and trying to unite them would at the very least seem to introduce a lot of overhead checking on each input line that in most cases would be wasted effort.

Not that I've actually sat down and tried to work my way through coding it. Just the thought makes me tired (what this forum needs is a good "sleeping" emoticon!).

And anyway, because HXA can nest macros the reason you want file inclusion in them is moot!
User avatar
GARTHWILSON
Forum Moderator
Posts: 8774
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: 6502 with a serial port - a minimal monitor?

Post by GARTHWILSON »

enso wrote:
In fasm on x86 and ARM, I used recursive macro definitions extensively to build dictionaries for Forth-like systems. For every word in the bootstrap kernel the HEAD macro was redefined to include its previous definition with the new head appended and linked to previous one. In the end, the macro was executed, creating hundreds of words perfectly linked and ready to go! I learned that trick from the creators of RetroForth, I think (before they decided to use some kind of a VM and the whole project became useless for me). Creating a bootstrap Forth environment with macros is surprisingly impossible with some assemblers.

In particular, you want to keep the pointer to the last word in a variable after its defined, so that the next one can create a link pointer to it. Some assemblers just can't keep that variable set correctly. In many, you cant ORG <variable> or <expression>, so you can't adjust the output pointer or calculate the position of objects in memory dynamically.
In my '816 Forth, the header macro is:

Code: Select all

HEADER:         MACRO NAME, precedence  ; Lay down name and link fields.  NAME is a quoted string or string expression.

 IF HEADERS? && ! OMIT_HEADERS          ; If HEADERS is true and OMIT_HEADERS is false,
                                        ; then go ahead lay down the header.
   last_NFA:    SETL    new_NFA
    new_NFA:    SETL    $
                DFB     precedence | {npc-$-1}, NAME
        npc:                            ; Use this label for the calculation of the name length byte above.
        IF      $ & 1                   ; If next addr is odd,
                DFB     0               ; add a nul byte before you
        ENDI
                DWL     last_NFA        ; lay down the link field.
 ELSE
        IF      $ & 1
                DFB     0               ; Even if headers are not allowed,
        ENDI                            ; you should still align.
 ENDI
                ENDM
 ;-------------------
where HEADERS?, OMIT_HEADERS, last_NFA, and new_NFA are assembler variable set and changed as many times as you like by SETL (SET Label value). The two variables HEADERS? and OMIT_HEADERS offer three levels of headersless code: locally headerless (like for just a word or two), global, and, in between, a range that's wider than just local. (I know the macro is kind of ugly, but macros tend to be that way, which is one reason we like to make them macros and hide that stuff.) Use of the header macro is like:

Code: Select all

        HEADER "1+", NOT_IMMEDIATE      ; ( n -- n+1 )
_1ADD:  PRIMITIVE
        INC   0,X
        GO_NEXT
 ;-------------------
where PRIMITIVE just lays down the address of the INC 0,X as the CFA, and the GO_NEXT macro makes it easy to change all the JMP NEXT's for different versions of NEXT like with or without interrupt support, do single-stepping, program-trace, etc..

Quote:
And anyway, because HXA can nest macros the reason you want file inclusion in them is moot!
Yes, macro nesting is nice. Since C32 doesn't have it, I resorted to the INCLude files as a work-around, and then ran into the problem that required another work-around.
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?
whartung
Posts: 1004
Joined: 13 Dec 2003

Re: 6502 with a serial port - a minimal monitor?

Post by whartung »

m4 is useable, just awful. I've used it with mine. For one thing, whereas pretty much every other macro processor on the planet is line oriented, m4 is character oriented. It just makes it that much more of a pain to use.

But it's ubiquitous, so there's that.

There's also the C pre-processor. Less powerful than m4, but more sane. It's good for the simpler stuff like includes and conditional compilation.

The primary benefit of an integrated macro processor is that the listing and error messages can make much more sense. A simple point about the include file, if you use m4 or cpp for that, you'll simply get an error on "line 1234" without having any idea where "line 1234" is, since the assembler see a single, consolidated file, not individual first class chunks.

I need to rewrite the expression parser on mine, I'm unhappy with it, then I'll look at adding an INCLUDE capability, and when that's done I'll likely have enough ammo to just make a generic macro processing facility to it.

And I'm only interested in things that can run natively on the Mac, I spooled up a Linux VM to build the CPU test source file, but I won't do that routinely.

Maybe I should port mine to Emacs, make it native :).
User avatar
BitWise
In Memoriam
Posts: 996
Joined: 02 Mar 2004
Location: Berkshire, UK
Contact:

Re: 6502 with a serial port - a minimal monitor?

Post by BitWise »

Garth, why are you aligning the code field address?

The only reason I can think of this to ensure both bytes are on the same page to avoid the 6502 JMP (indirect) bug but on all later devices this is fixed.

I use the same approach to generating my Forth headers in Dev65 (but I don't align on 65C02)
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs
User avatar
GARTHWILSON
Forum Moderator
Posts: 8774
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: 6502 with a serial port - a minimal monitor?

Post by GARTHWILSON »

BitWise wrote:
Garth, why are you aligning the code field address?
The 2nd "IF" aligns the LFA, and since it takes two bytes, the CFA is automatically aligned. If you compile headerless code, the 3rd "IF" still aligns it the CFA even though there's no name field or link field.
Quote:
The only reason I can think of this to ensure both bytes are on the same page to avoid the 6502 JMP (indirect) bug but on all later devices this is fixed.

I use the same approach to generating my Forth headers in Dev65 (but I don't align on 65C02)
I aligned because, IIRC, it made something easier in the SEE (decompiling) word, partly because I allow all 256 characters in names (including ones with high bit set) except of course space, CR, LF, and a few others that would be extremely impractical. This allows names to have the special ANSI characters like ±½°. Without delving into it again at the moment, I don't remember exactly why it made decompiling easier. It was too many years ago.
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?
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: 6502 with a serial port - a minimal monitor?

Post by BigEd »

enso wrote:
GARTHWILSON wrote:
... and teamtempest's (Anton Treuenfels') HXA at http://home.earthlink.net/~hxa/ which includes macros to do the program structures I have been promoting.
Unfortunately, windows or dos only...
HXA works fine on Linux, just have Wine installed and you can invoke it directly.

Cheers
Ed
User avatar
enso
Posts: 904
Joined: 29 Sep 2012

Re: 6502 with a serial port - a minimal monitor?

Post by enso »

Great, I will give hxa a try!

Thank you for pointing out the error location problem with a separate macro processor. That is a problem - the assembler never sees the original code, and the macro processor is done by the time the error occurs. I am still attached to the idea as a separate macro processor makes the assembly cleaner somehow. Maybe.

One way to handle it is to attach a line-number comment during macro processing, perhaps at the end of the line. Each output line is then matched to the original line number in the comment, so when an error occurs, you know where to look.
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut
Tor
Posts: 597
Joined: 10 Apr 2011
Location: Norway/Japan

Re: 6502 with a serial port - a minimal monitor?

Post by Tor »

enso wrote:
One way to handle it is to attach a line-number comment during macro processing, perhaps at the end of the line. Each output line is then matched to the original line number in the comment, so when an error occurs, you know where to look.
cpp does something like that. There's a #line statement. It can also be used in the assembly output when compiling (for example) C, so that you can look at the assembly (.S files) and see which section of statements corresponds to which source code line (and it's also used to generate the debugging info used by GDB when tracing executables).

-Tor
Last edited by Tor on Fri Jul 12, 2013 10:33 pm, edited 1 time in total.
User avatar
enso
Posts: 904
Joined: 29 Sep 2012

Re: 6502 with a serial port - a minimal monitor?

Post by enso »

Yes, inserting "line=..." or ".line" perhaps statements is even better than messing with comments. The assembler can track them. A similar issue happens with macro expansion and some assemblers really botch the error location.

Garth, in my 32-bit forths I've aligned heads to 8 and 16-byte bounds (as it's a lot faster) and often used the 3 or 4 low bits for flags... BTW, what is the memory footprint of your minimal Forth setup? Forth is a heck of a lot more useful than any monitor...
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut
User avatar
enso
Posts: 904
Joined: 29 Sep 2012

Re: 6502 with a serial port - a minimal monitor?

Post by enso »

Daryl, I am working on the loader.

I added an 'L' (for load) command into the ASCII command table, the jump table and a 0 in the secondary table. What is the purpose of that table - is it an opportunity to run a different command after the main one is done?
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut
Post Reply