Project-28 - A somewhat Minimal 6502 system

Topics related to the SBC- series of printed circuit boards, designed by Daryl Rictor and popular with many 6502.org visitors.
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Project-28 - A somewhat Minimal 6502 system

Post by BigEd »

It's all good fun - and it gives you a benchmark frame rate(!) to improve on!
plasmo
Posts: 1273
Joined: 21 Dec 2018
Location: Albuquerque NM USA

Re: Project-28 - A somewhat Minimal 6502 system

Post by plasmo »

Try gosper glider gun, it is fun to watch; I also used it as a benchmark measuring the time for first gun to reach the edge of screen.
Bill
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: Project-28 - A somewhat Minimal 6502 system

Post by drogon »

plasmo wrote:
Try gosper glider gun, it is fun to watch; I also used it as a benchmark measuring the time for first gun to reach the edge of screen.
Bill
Well the above is a single glider, the gun itself is a bit bigger, however since you asked:

Code: Select all

+--------------------------------------+
|                        *             |
|                      * *             |
|            **      **            **  |
|           *   *    **            **  |
|**        *     *   **                |
|**        *   * **    * *             |
|          *     *       *             |
|           *   *                      |
|            **                        |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
+--------------------------------------+
Generation: 0
+--------------------------------------+
|                         *            |
|                         * *          |
|        **                  **    **  |
|      *   *                 **    **  |
|**   *     *                **        |
|**  ** *   *        *    * *          |
|     *     *         *   *            |
|      *   *     *  ***                |
|        **                            |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
+--------------------------------------+
Generation: 15
+--------------------------------------+
|                           *          |
|                          ****        |
|         **              ** * *   **  |
| *       *  *           *** *  *  **  |
|*   **       *           ** * *       |
|*     *      *            ****        |
| *****       *       *     *          |
|         *  *         *               |
|         **         ***               |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
+--------------------------------------+
Generation: 19
+--------------------------------------+
|                         *            |
|                         * *          |
|        **                  **    **  |
|      *   *                 **    **  |
|**   *     *                **        |
|**  ** *   *        *    * *          |
|     *     *         *   *            |
|      *   *     *  ***                |
|        **                            |
|                                      |
|                                      |
|                                      |
|                                      |
|                            *         |
|                          * *         |
|                           **         |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
+--------------------------------------+
Generation: 45
+--------------------------------------+
|                           *          |
|                          ****        |
|         **              ** * *   **  |
| *       *  *           *** *  *  **  |
|*   **       *           ** * *       |
|*     *      *            ****        |
| *****       *       *     *          |
|         *  *         *               |
|         **         ***               |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                             *        |
|                           * *        |
|                            **        |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
|                                      |
+--------------------------------------+
Generation: 46
The are 2 gliders well established in flight by generation 45/46 and the first glider reaches the edge of the screen by generation 75, so 75*58=72.5 minutes.

Code: Select all

+--------------------------------------+
|                         *            |
|                         * *          |
|        **                  **    **  |
|      *   *                 **    **  |
|**   *     *                **        |
|**  ** *   *        *    * *          |
|     *     *         *   *            |
|      *   *     *  ***                |
|        **                            |
|                                      |
|                                      |
|                                      |
|                                      |
|                            *         |
|                          * *         |
|                           **         |
|                                      |
|                                      |
|                                      |
|                                      |
|                                   *  |
|                                    * |
|                                  *** |
+--------------------------------------+
Generation: 75
This isn't breaking any speed records but from a retro-prespective it's good - for me, at least. If anyone remembers writing larger programs using "overlays" or chaining Basic programs together, preserving variables, this is is a good retro example...

I'm (very slowly) working on a "Super Star Trek" game which so-far needs 3 programs, preserving an area of RAM for the galaxy map, so one program is simply the long-range scanner printer ... I can chain a program and effect a 'return' to the original program with 2 variables, one for the next program to chain and one for the line to GOTO in that program to continue. Fiddly, but workable...

-Gordon
-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
J64C
Posts: 239
Joined: 11 Jul 2021

Re: Project-28 - A somewhat Minimal 6502 system

Post by J64C »

Legendary work, Gordon! Seeing these Kidd of posts is inspiring me to get back in to the swing of things.
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: Project-28 - A somewhat Minimal 6502 system

Post by drogon »

J64C wrote:
Legendary work, Gordon! Seeing these Kidd of posts is inspiring me to get back in to the swing of things.
Thanks.

Lifes been somewhat challenging this year, but I've found some time recently to carry on tinkering with it. the Basic has been tweaked, but I'm back to having zero bytes free in the 4K bank in the EEPROM for it... Ah well.

However one thing I've been doing is improving the serial IO routines - rather than a bit-banged 9600 baud I now have a much improved bit-banged 38400 baud! I couldn't quite make it faster with the current strategy - that was in response to some folks saying things along the lines of "well, if you stop the output the benchmark will go faster"... well, no, not really. Think about it - printing a Mandelbrot for example - it takes just over 10 minutes to do the calculate and print - and that's printing about 2000 characters - so at 1mS per character, 2 seconds out of that 10 minutes is printing, so really making the print faster won't really change anything.

Didn't stop me doing it anyway.... and what it does mean now is that if I ever have to drop i down to 1Mhz then it's still a respectable 19200 baud.

I'm still toying with the idea of making it as a kit to sell. The question I have there is ... boot to Basic or a machine-code monitor?

I already have my own monitor, but the main issue now is eeprom space... It's arranged as 8 banks of 4KB with 7 of those banks being used as Basic program storage - I can sactifice one bank for the monitor and a 2nd for the Basic, leaving just 6 banks for program storage.

And then with the monitor, do I keep it serial, or make it work with an add-on keypad and display (traditional multiplexed 7-segment LEDs or something like a 2 or 4 lines character LCD? Too many decisions to make right now.

And again, codespace - Another thought - with the monitor, I could copy all the serial IO code into RAM, so the Basic and Monitor uses the same serial IO code - that would free up some 200 bytes in the Basic ROM, but 256 byes less RAM (which already has 3 pages of the 4KB pre-allocated for ZP, Stack, keyboard input buffer and the 'bounce' buffer needed for program load/save code, so taking another page would leave just 3KB for your Basic program... It's getting a bit squeaky tight now...

Too many thoughts for now, but I welcome suggestions.

Cheers,

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Project-28 - A somewhat Minimal 6502 system

Post by BigEd »

All sounds good to me... 6 banks for program storage still feels like enough.

Bringing some much-needed code from ROM into RAM to free up space, that seems like a good tradeoff. Not much difference between 3k and 3.25k.

Here's an idea, might be simple, might not: separate Basic program from Basic data. Put all of Basic's variables and arrays into a RAM bank of their own. Or to look at it the other way, put the Basic program text into a bank of its own. Of course, some performance cost in the bank-switching.
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: Project-28 - A somewhat Minimal 6502 system

Post by drogon »

BigEd wrote:
All sounds good to me... 6 banks for program storage still feels like enough.

Bringing some much-needed code from ROM into RAM to free up space, that seems like a good tradeoff. Not much difference between 3k and 3.25k.

Here's an idea, might be simple, might not: separate Basic program from Basic data. Put all of Basic's variables and arrays into a RAM bank of their own. Or to look at it the other way, put the Basic program text into a bank of its own. Of course, some performance cost in the bank-switching.
Interesting idea, but there is only 4KB of RAM.

Although this isn't quite true. There is actually 8KB of RAM but only 4KB is accessible. (And remember it's a 6507, so only 8K worth of address lines)

To swap RAM banks I'd need an extra output bit, somewhere. To further compound the issue, the hardware IO region is inside the RAM region and not taken from somewhere else (like the ROM area). This was a bit of a design optimisation rather than for any sort of higher speed access to the IO

Then there might be the additional program code to manage it.

Right now, my TinyBasic has 27 variables, @ through Z and they are held in the first 54 byes of Zero page. The top 16 bytes of ZP are 2 8-bit registers: $F0 is the serial input bit (bit 7) and $F8 is the on-board button input (again, the top bit). It's also an output register that goes to an 8-bit latch which has 4 LEDs, 3 bits of ROM bank and one bit of serial output. The VIA is decoded as the top 16 bytes of page $100, so the stack is initialised at $EF. The bottom of page 1; $0100 through $017F is the keyboard input buffer.

Programs can peek/poke and there are operations to do this and to discover the start of free RAM ('TOP' which is the end of the program up to the end of RAM) This lets you hold strings and arrays. This would be a more useful data area to shadow in another bank of RAM...

RAM $0200 through $02FF is the 'bounce buffer' for saving programs to/from EEPROM - Code is copied here to do the save/load and directory operations - this is necessary because you can't run code in one bank and read data from another bank - that can only be done from RAM.

So while bank switching the RAM might be possible, I feel it might also take something from another design goal I had which was a somewhat minimal system. 4K ROM, 4K RAM... The additional ROM (EEPROM) banks are a bonus to allow for code storage. (And like the RAM chip more that you simply can't get a 4K EEPROM nor a 4K RAM chip any more) There is a spare pin on the GAL that glues it all together but I'm not sure if I can make it a flip-flop. I could have one less LED, or use an output pin on the VIA to switch RAM banks... Hm...

Now... Here is a thought... If I do go down the monitor route, then I can boot into the monitor, the monitor can copy 'vectors' to $02xx for things like putchar, getchar, getline and so on. Basic running in e.g. Bank 1 can call getchar - this enables bank 0, calls the ROM getchar, returns to RAM, re-selects the previous bank, returns from whence it came.

This is very similar to BBC Micro where this approach works extremely well.

So.. lets take that further and put vectors to load/save/dir there as well, and have the monitor hold that code - RAM code enables ROM 0, jumps into it, ROM copies the load/save/dir code to $0200 hopefully not overwriting the vectors, (as right now I copy all the code, but now it just needs to copy one of load/save/dir routines along the the common code they need). A minor thorn is that DIR needs to print, so for the DIR command I need to keep the serial output code accessible in RAM... Maybe not impossible, DIR itself only a few dozen bytes long.

That would free up lots of code (relatively speaking) in the Basic ROM too. (Software) complexity increases but so does functionality, and, more importantly, I don't need to use another page of my precious RAM :-)

Of-course if a Basic program goofs and pokes memory at random then who knows what might happen, but that is the same issue as on ALL the micros of the day and all today that don't have any sort of memory protection and while the potential is there, it very rarely happenes. (My experience, anyway)

Cheers,

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
gfoot
Posts: 871
Joined: 09 Jul 2021

Re: Project-28 - A somewhat Minimal 6502 system

Post by gfoot »

Catching up with this great thread that I missed, I was going to suggest that moving all the file I/O to a different ROM bank could win back some ROM space without really compromising your 4k/4k goal - as the runtime code still fits in that footprint - I think this is the conclusion you've got to already now. I like those ideas, and the project in general - if you do end up selling kits then I'll buy one for sure!

Another thought following on from what BigEd said was maybe the BASIC could read the program straight from ROM via a small RAM-based helper routine - but I appreciate that might be outside the spirit of the 4k/4k design choice.
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: Project-28 - A somewhat Minimal 6502 system

Post by drogon »

gfoot wrote:
Catching up with this great thread that I missed, I was going to suggest that moving all the file I/O to a different ROM bank could win back some ROM space without really compromising your 4k/4k goal - as the runtime code still fits in that footprint - I think this is the conclusion you've got to already now. I like those ideas, and the project in general - if you do end up selling kits then I'll buy one for sure!
Thanks.

So only one ROM bank can be active at any one time. So for code in ROM 0 to call code in ROM 1, it has to go via RAM - with the RAM code changing bank, calling the code in the new bank, restoring the original bank then returning.

Think of it like BBC Basic calling file IO - Basic and File IO are in the same physical address space in different ROMs. Basic calls the OS (in a separate ROM), the OS turns off Basic, turns on the File ROM, calls the file code, restores the active ROM and returns to Basic - although in this case that "OS" code has to be in RAM.

So - I have little stubs in (say) page 2 that does this - enables the monitor rom, calls the monitor rom for (e.g.) character out, returns to RAM, restores the Basic ROM and returns. That's very workable.

The case for load/save/dir is harder as that code has to live in RAM but it can be copied into RAM as required.

Quote:
Another thought following on from what BigEd said was maybe the BASIC could read the program straight from ROM via a small RAM-based helper routine - but I appreciate that might be outside the spirit of the 4k/4k design choice.
Possible, but again it would need to do it via RAM. There are well defined bits of code to read the basic program text though, but it's already slow enough without adding a call to RAM, swap banks, fetch byte(s) swap banks back, return to ROM for every character. TinyBasic is not tokrnised..

Also, it does support a chain command - one thing I need for my never ending "Super Star Trek" game if I ever get round to finishing it. Need about half a K of RAM to hold the universe data and chain preserves variables @-Z so it's all do-able as long as the individual programs are short enough.

Cheers,

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: Project-28 - A somewhat Minimal 6502 system

Post by drogon »

And just a quick word of thanks - initially to Ed a few weeks back for helping me re-kindle my own interest in this and now recent comments. Lots of exciting work to do!

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Project-28 - A somewhat Minimal 6502 system

Post by BigEd »

Ah, all sounding interesting, and sorry for mild confusion! Glad I could help in some way.

Following George's idea, to interpret direct from the Basic source which is in a ROM bank, perhaps the interpreter could use a helper routine to copy just one text line of Basic into RAM and then proceed? I'll confess I'm a bit brain-foggy and haven't managed to build a mental model of the machine.

I do support the idea of a truly minimal machine as a possibility, though.
gfoot
Posts: 871
Joined: 09 Jul 2021

Re: Project-28 - A somewhat Minimal 6502 system

Post by gfoot »

One other thing I wanted to ask - could the pin read/write commands just be called "PIN"? i.e.:

Code: Select all

A = PIN 3
PIN 5 = 0
Then there's no need for a separate command to control direction, as it's built-in to whether the keyword is being used in a read or write context. Just a thought!
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: Project-28 - A somewhat Minimal 6502 system

Post by drogon »

BigEd wrote:
Ah, all sounding interesting, and sorry for mild confusion! Glad I could help in some way.

Following George's idea, to interpret direct from the Basic source which is in a ROM bank, perhaps the interpreter could use a helper routine to copy just one text line of Basic into RAM and then proceed? I'll confess I'm a bit brain-foggy and haven't managed to build a mental model of the machine.
Possibly.

Have to think of the advantage (more RAM for data?) vs. additional complexity of the interpreter and slow-down... Tricky to balance sometime..

Cheers,

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: Project-28 - A somewhat Minimal 6502 system

Post by drogon »

gfoot wrote:
One other thing I wanted to ask - could the pin read/write commands just be called "PIN"? i.e.:

Code: Select all

A = PIN 3
PIN 5 = 0
Then there's no need for a separate command to control direction, as it's built-in to whether the keyword is being used in a read or write context. Just a thought!
That's quite a nice idea. The whole DW, DR comes from the old wiring libraries (and my own wiringPi library) where they're digitalRead () and digitalWrite () (as well as pinMode ())

But I'll look into it. The syntax of PIN 5 = 0 goes against the grain of the existing interpreter though but since the syntax is built into every command...

Code: Select all

tryDW:          tStr    :+,             "DW"                    ; DW pin,val
                call    relExp
                tChar   synErr,         ','
                call    relExp
                do      popAE,doDW,stmtDoneNext
is what the intermediate language (IL - It's like a pseudo code implemented here in macros) looks like. Spot how easy it might be to change from DW pin, value into PIN pin =value ...

Of course, changing DW into PIN and DR into PIN will add 2 more bytes to the ROM code. Right now number of spare bytes = 0... That's how tight it is! Also in-lining the direction code - that's somewhat hacky right now and very highly optimised and the whole thing is even more hackily optimised to cater for the additional 2 output only pins of CA2 and CB2 as pins 16 and 17. I could remove the built in code for them - still usable via peek/poke though, but nice to have the same syntax for them to make them seamless.

So it could be a bit like the LED command: LED = 42 and var = LED ...

Added to the thought process list.. :)

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
gfoot
Posts: 871
Joined: 09 Jul 2021

Re: Project-28 - A somewhat Minimal 6502 system

Post by gfoot »

Maybe you could use "IO" instead of "PIN" to save the characters back! But I would have thought getting rid of the direction command would save a fair few bytes. And for syntax it is a departure from normal BASIC, I think, but you're already doing that for $A, ?A, !A (like BBC BASIC did) so it feels kind of natural to me.
Post Reply