Firmware and infrastructure for a 6502 portable

Let's talk about anything related to the 6502 microprocessor.
No True Scotsman
Posts: 127
Joined: 22 Mar 2023

Firmware and infrastructure for a 6502 portable

Post by No True Scotsman »

Previously, I mentioned my goal of creating an online environment suitable for 8-bit computers:
No True Scotsman wrote:
Beyond just building a portable computer, I envision an ecosystem to support it that will include both local and online services. The device won't be "always connected" in the way a smartphone is. Rather, the ESP32's WiFi capabilities will be used to connect to a simple Telnet BBS running on my desktop computer at home. The BBS will initially be a simple remote file storage system, but will evolve over time to provide other services, such as an IMAP/SMTP proxy. It may even become a full multi-user BBS at some point.

The overall aesthetic of the text-mode user interface will be influenced by dialup BBS design, which may help explain the design strategy. Data sent from the 65C02 to the terminal display will be parsed for ANSI escape sequences, which will be translated into commands to the TFT driver, e.g., to set text foreground and background colors, move the cursor, and delete things. Said driver also has codepage 437 support, which makes it perfect for this application. As you'd expect, data from the BBS will be likewise marked up with ANSI sequences.

Long story short, I intend to integrate local programs and online services in a cohesive environment that has an old school BBS look and feel.
We talked mainly about hardware in that thread. I'd like to now flesh out the picture a little more, and discuss the software that will power it. As the complete system will involve other systems in a addition to the 6502 portable itself, some of the code presented here will be in languages other than those that will run on a 6502. For that reason, I've posted this thread in the General Discussion forum, rather than Programming. If the mods think it belongs there instead, feel free to move it.

Foremost in my mind in recent days has been a software loader. This part of the 6502 firmware would send an in-band file request over the terminal connection to the onboard ESP32 that runs the terminal and controls the SD card slot and WiFi connection.

Coincidentally, AlexeyM82 recently mentioned a loader he wrote for his 6502 SBC that loads files over a serial connection, which I'd very much like to see. Thanks in advance!

My preliminary research into creating a loader turned up the Sixty502 project on Github. That package was expressly designed to work with the hardware in Ben Eater's breadboard computer kit, and does not reflect the way I'd write client-server software. It requires that the server and client computers be connected via an Arduino Mega and ten or so Dupont wires. The user must manually initiate both ends of the transfer. My software will transfer files the way one would actually download a file in real life.

The Sixty502 server, "sender.js," is written in JavaScript and runs on Node.js. Node.js is one of the countless unnecessary platforms du jour that cropped up in the late 2000s and 2010s. Although JavaScript is my favorite language, and Microsoft's sever object bindings in the original Active Server Pages were well designed, the latest trends in software abstraction make simple things like creating a TCP socket unnecessarily tedious. Programmers are way too literalistic where design patterns are concerned. I almost wish they'd never been taught. Wanna know how I write a page controller or section front controller for a WebMVC site? I write a switch statement, because that's all a controller really is. I use PHP on the server side because it's "unixy," by which I mean it implements scriptable versions of Unix system calls that closely parallel their C counterparts. You shouldn't have to instantiate a bunch of objects and pass them to each other to do this:

Code: Select all

$socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
@socket_bind($socket, $address, $port);
@socket_listen($socket);
@socket_set_nonblock($socket);
I've omitted error handling code for clarity here, but you get the idea.

Incidentally, if you've tried to connect to an Arduino from a Linux terminal and failed, that's because it's weird. I forget where I learned this, but here's how to do it:

Code: Select all

if (strtolower($type) == "arduino") {
  $command = "/bin/stty -F  {$device} {$baudRate} {$dataBits} {$this->stopBits} {$localEcho} ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts";
}
else {
  $command = "/bin/stty -F {$device} {$baudRate} sane raw {$dataBits} {$stopBits} hupcl cread clocal {$localEcho} -onlcr";
}
exec($command);
Notice that the catch-all "sane" argument to stty doesn't work for Arduino. I guess the Arduino is insane. :shock:

But I digress.

As I mentioned elsewhere, I'm inclined to forego an onboard BASIC interpreter altogether, as writing programs on the desktop and downloading them over WiFi seems a more natural workflow. Therefore, the main 6502 firmware components would appear to be as follows:
  • * terminal I/O
    * command interpreter, main menu, or hybrid
    * in-band serial file transfer protocol, possibly a custom CSI extension
    * loader
    * text editor
    * monitor
As an example of a hybrid command interpreter, on the Model 100 you can either select a file or program from the main menu or type in the filename at a prompt below the menu.

Since the terminal will have a CSI parser for the UI anyway, it may as well handle filesystem and WiFi commands too.
No True Scotsman
Posts: 127
Joined: 22 Mar 2023

Re: Firmware and infrastructure for a 6502 portable

Post by No True Scotsman »

In the absence of a VIA, the question of where to get a timer for the interrupt to feed the DAC arose. Boy, you VIA guys are living the life, with timers galore.

I do have a VIA on hand, and a couple of open IO slots in the decoder, so I could add a VIA. But I don't want to.

In keeping with the goal of making do with minimal hardware, I looked at the timer/counter on the SCC2692 UART. If I understand the datasheet correctly, this timer may be used by the baud rate generator in lieu of a crystal. I'm using a crystal. The datasheet further asserts that the chip can be programmed to hold OP3 high until the counter reaches zero, then pull it low. It doesn't say I can't use the timer and output for other things if the UART isn't using it. It sounds like as good a way as any to trigger /IRQ.

If all else fails, I can set something up on the ESP32.

You may be wondering why I don't just do the audio on the ESP32, since it's managing all of the other peripherals. There's a whole two-wire inter-chip protocol (I2S) just for that.

Well, sound chips are a case where I do want to have direct control of the hardware. I'm going to experiment with quite a few of them. It's not a foregone conclusion that the DAC will be the sound system I end up using.

While I was pondering that, a call came in from HQ, requesting that a block diagram for this system be posted in the other thread. So look for that shortly.
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: Firmware and infrastructure for a 6502 portable

Post by drogon »

I like your goals and ideas you have outlined there - not a million miles from my own Ruby projects; In essence a self-hosting system capable of local software development just like we did "back then", and that started with a 65C02 with 64K RAM and an AVR - (ATmega 1284p) which can access the top 256 bytes of RAM and acts as a serial port and filing system handler (local SD card). The original intent was for composite video too at 320x240 - and that did work well, but slowed the whole thing down too much, so plan B was put into place...

I started with a monitor and MSBasic (EhBASIC and others) but meh... Who wants that old fashioned stuff...

So going back to what I was really after was a self-contained system that I could use to edit and run programs on-top of a little operating system so what I ended up with was something that resembled the Acorn MOS on the BBC Micro so closely that it could run BBC Basic and other Acornsoft ROMs directly... (Such as Comal and BCPL)

My board does have a VIA, but initially the timer interrupt came from the AVR, so technically the AVR is optional.

The one thing I did want was a compiled language - I had BCPL which worked well on the 6502 (and I'd used it way back on the BBC Micro) So that sort of fulfilled the desire for a compiled, locally edited language.

So your concept of a little self contained system is sound.

Software loader? That's the challenge - I "cheated" by using the AVR to talk to an SD card. The 6502 talks to the AVR via the shared RAM (Just the bottom 134 bytes after it's booted as the rest is OS and hardware vectors) - the 6502 pokes a command there, executes a WAI instruction, the AVR sees the Rdy line go low, reads the command from the RAM, does the command and returns control back to the 6502. Files are transferred 128 (or less) bytes at a time. Latency is relatively high, but I get about 34KB/sec overall transfer rate. There is no ROM on the 6502 side, but boot time (loading a 200 byte 1st stage bootstrap then that loads the 12KB OS is well under a second, then another half second to load Basic, BCPL, or whatever - like my editor which is written in C and cross compiled.

Serial is essentially for the terminal IO now, but I can transfer files over it, although that happens directly from the AVR - the 6502 sends a file-get command and the AVR does it - but only if the AVR is taking to my own terminal program that runs under Linux. This terminal program handles graphics in the same way a BBC Micro does it, so some BBC Basic programs will run with graphics over the serial line.

I like the idea of Wi-Fi and I've toyed with it - the ESPs don't have enough GPIO for the style of interfacing I'm using though (I need 20 pins, 8 data, 8 address and 4 or 5 control lines) but a separate SPI connected Wi-Fi interface is a possibility - it's just working out how to realise it sensibly from 6502 land. (Or BCPL land in my case)

My path took me from 16-bit BCPL on the 65c02 to 32-bit BCPL on the 65c816 with most of the OS re-written in BCPL (and now to RISC-V with almost the entire OS written in BCPL with the rest being assembler. (There was a diversion via ARM32, but I don't talk about that ;-)

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
No True Scotsman
Posts: 127
Joined: 22 Mar 2023

Re: Firmware and infrastructure for a 6502 portable

Post by No True Scotsman »

The Raspberry Pi Pico W has WiFi, and should have enough pins to do anything you want. People are using them for VGA and to emulate RAM and ROM. I originally planned to use a Pico, but the ones I have don't have WiFi. That's why I went with the ESP32. I'm gonna be doing a lot of "cheating" with it.
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: Firmware and infrastructure for a 6502 portable

Post by drogon »

No True Scotsman wrote:
The Raspberry Pi Pico W has WiFi, and should have enough pins to do anything you want. People are using them for VGA and to emulate RAM and ROM. I originally planned to use a Pico, but the ones I have don't have WiFi. That's why I went with the ESP32. I'm gonna be doing a lot of "cheating" with it.
I'm currently using a Pico2 (rp2350) however no 65xxx in sight - my project migrated from the 02 to the 816 to RISC-V (via an ARM32 diversion) - same OS, same binaries, same old... Just faster and more modern. The Pico2 has native hdmi capabilities too... And on my 'todo' list is a 6502 emulator for it.

I don't see what you're doing with the ESP (Or what I did with the AVR) as "cheating" - it's using what's available - at the heart you still have the '02 doing the real work on the system...

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
No True Scotsman
Posts: 127
Joined: 22 Mar 2023

Re: Firmware and infrastructure for a 6502 portable

Post by No True Scotsman »

I suppose where you draw the line depends on how much of a retro purist you are. I know putting a Linux SBC in a case and running a 6502 emulator on it wouldn't work for me. It would have telltale signs of a Linux computer running an emulator, however hard I tried to hide them.
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: Firmware and infrastructure for a 6502 portable

Post by drogon »

No True Scotsman wrote:
I suppose where you draw the line depends on how much of a retro purist you are. I know putting a Linux SBC in a case and running a 6502 emulator on it wouldn't work for me. It would have telltale signs of a Linux computer running an emulator, however hard I tried to hide them.
I'm with you there - my project is different though - it's turned from hardware to ... well, more hardware with the same software, just bigger, faster, etc. ...

I sort of imagined a different timeline - so the '02 then the '816 (even though far, far better CPUs were there at the time), but then ... Well in the real world there was ARM but in my world I wanted an alternative, hence RISC-V which was born from the Berkeley RISCs of the early 80s ... I wrote an RV32IM emulator on my '816 system and used that to test/bootstrap my OS before moving to real hardware.

I still have the '02 and '816 systems and they still work. One day I'll do a demo...

Back to the hardware emulators though - there are some excellent systems out there - such as the Altair 8800 emulators - which are almost impossible to tell from the real thing, Mk14 systems, PDP8, PDP11, PDP10 (Although they're easy to tell apart from the real things as you can pick them up :) But you get the drift... Not sure I know of any 6502/816 systems that aren't though.

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Firmware and infrastructure for a 6502 portable

Post by BigDumbDinosaur »

No True Scotsman wrote:
In the absence of a VIA, the question of where to get a timer for the interrupt to feed the DAC arose...I looked at the timer/counter on the SCC2692 UART. If I understand the datasheet correctly, this timer may be used by the baud rate generator in lieu of a crystal...
You’ve slightly misunderstood the counter/timer’s (C/T) relationship to the time-base (what you are calling a “crystal”).

The X1 signal that is the DUART’s time-base is required, not optional, and must come from a crystal circuit with passives, a can oscillator, or some other source that can produce a symmetric 3.6864 MHz square wave with an approximate high-going amplitude equal to VCC.  I highly recommend the use of an HCMOS can oscillator in this role.  A crystal-with-passives circuit can be touchy to design and lay out, and will likely cost you as much in parts and PCB real estate as the inherently more-stable can oscillator.

With the SCC269... series of DUARTs, the C/T may be used as a counter or a timer, or an alternative time-base for driving the bit-rate generator.  The latter role would only be used if you needed a communications rate that could not be established with one of the built-in bit-rate tables.

In your application, running the C/T as a timer would allow the DUART to generate a fixed-rate IRQ analogous to what can be done with a VIA’s timer.  In (free-running) timer mode, the C/T’s periodic rate is a submultiple of the X1 clock rate (3.6864 MHz), with the upper limit equal to X1 ÷ 4.  This is the arrangement I use in my POC units to generate the 100-Hz jiffy IRQ responsible for overall system timing and timekeeping—C/T preload value I use is 18432.

Quote:
The datasheet further asserts that the chip can be programmed to hold OP3 high until the counter reaches zero, then pull it low. It doesn't say I can't use the timer and output for other things if the UART isn't using it. It sounds like as good a way as any to trigger /IRQ.
The OP3 output, when the OP3 output select bit pattern is %01, may be used as an indicator of a C/T IRQ in hardware (but don’t wire it to the MPU’s IRQB), giving you an alternative to reading the interrupt status register (ISR) and masking for bit 3.  You would wire OP3 to something (e.g., a VIA or even a simple inverting line driver, e.g. a 74ACT540) and when an IRQ occurs, test OP3’s state.  Note that when OP3 is programmed to follow C/T status, it becomes an open-collector output and must be pulled up to VCC with a suitable resistor (2.2 K to 3.3.K recommended).

Incidentally, you will be better served in this application with the more advanced 28L92 DUART.  The 2692 doesn’t have a transmitter FIFO and will generate an IRQ storm during sustained output.  The 28L92 has a 16-deep FIFO on both receivers and transmitters, which greatly eases the MPU’s interrupt processing load.  Although NXP has discontinued the 28L92, the TI equivalent remains available.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
No True Scotsman
Posts: 127
Joined: 22 Mar 2023

Re: Firmware and infrastructure for a 6502 portable

Post by No True Scotsman »

No True Scotsman wrote:
While I was pondering that, a call came in from HQ, requesting that a block diagram for this system be posted in the other thread. So look for that shortly.
The block diagram is up.
BigDumbDinosaur wrote:
In your application, running the C/T as a timer would allow the DUART to generate a fixed-rate IRQ analogous to what can be done with a VIA’s timer.  In (free-running) timer mode, the C/T’s periodic rate is a submultiple of the X1 clock rate (3.6864 MHz), with the upper limit equal to X1 ÷ 4.  This is the arrangement I use in my POC units to generate the 100-Hz jiffy IRQ responsible for overall system timing and timekeeping—C/T preload value I use is 18432.
So, all caveats aside, it should be a simple matter to get a recurring interrupt at a rate of 44.1kHz or thereabouts, right?
BigDumbDinosaur wrote:
Note that when OP3 is programmed to follow C/T status, it becomes an open-collector output and must be pulled up to VCC with a suitable resistor (2.2 K to 3.3.K recommended).
I was just reading about that on Garth's site.
BigDumbDinosaur wrote:
I highly recommend the use of an HCMOS can oscillator in this role.  A crystal-with-passives circuit can be touchy to design and lay out, and will likely cost you as much in parts and PCB real estate as the inherently more-stable can oscillator.
BigDumbDinosaur wrote:
Incidentally, you will be better served in this application with the more advanced 28L92 DUART....
Oh boy. I already have the 2892 and 3.6864 MHz crystal. I've been thinking I should've bought an ACIA or two instead, as it's difficult to find practical anecdotal information about using the 2892 outside of the datasheets and application notes. But, as a serial port fanatic, getting two UARTS in one package was too good to pass up.

Regarding non-standard bitrates, I had hoped to include MIDI among the uses of the second UART, but an application note I read said a 3 MHz oscillator would be needed for that. The first UART is permanently connected to the terminal at a standard table bitrate, so I'd have to be able to use standard and non-standard rates concurrently.
No True Scotsman
Posts: 127
Joined: 22 Mar 2023

Re: Firmware and infrastructure for a 6502 portable

Post by No True Scotsman »

Since I'm about to order 74HC139s for the decoder, I'm going to get the exact Saronix can oscillator recommended in the 2892 datasheet. I'd previously had it in my cart, but removed it when I found the crystals in my parts box.

I'm also looking at an alternate UART, the 16C550, which I think is well known and widely discussed in the DIY community. It also has 16-byte FIFO buffers, and appears to be tolerant of crystal / RC network clocks. I'll nevertheless probably just get a 1.8432 MHz can oscillator, for sanity.
jgharston
Posts: 181
Joined: 22 Feb 2004

Re: Firmware and infrastructure for a 6502 portable

Post by jgharston »

No True Scotsman wrote:
The overall aesthetic of the text-mode user interface will be influenced by dialup BBS design, which may help explain the design strategy. Data sent from the 65C02 to the terminal display will be parsed for ANSI escape sequences, which will be translated into commands to the TFT driver, e.g., to set text foreground and background colors, move the cursor, and delete things. Said driver also has codepage 437 support, which makes it perfect for this application. As you'd expect, data from the BBS will be likewise marked up with ANSI sequences.
When doing terminal I/O support for PDP11 BASIC I did extensive research into ANSI/VT character sequences. Loads and loads of available documentation missed huge chunks out, I wanted a COMPLETE list of ABSO. LUTELY. *EVERYTHING* - *INCLUDING* gaps. Not just "we've omitted some stuff we oh so superiorly consider of no interest to you", but *WHAT* is in those gaps. In particular, *input* sequences were a right pain to track down. And, specifically, SORTED IN ORDER! Why on earth is so much documentation in random order?

So, to ensure the knowledge was preserved, I recorded it:
Display output sequence: https://mdfs.net/Docs/Comp/Comms/ANSICodes
Keyboard input sequences: https://mdfs.net/Docs/Comp/Comms/ANSIKeys

Several times I've tried to put this information into the Wikipedia articles - which is one of the worst offenders for "these are a handful, we can't be arsed to list any others" - but it keeps getting edited out, so I've given up.

I also investigated what the optimal subset of output sequences a system should stick to to ensure maximal compatibility:
https://mdfs.net/Docs/Comp/Comms/ANSIVDU
Input processing can't restrict what it recognises as it has no control over what is input; output processing can restrict what it outputs as it's in control of what's being output.

I have also coded up demo code of processing ANSI input and output sequences:
https://mdfs.net/Docs/Comp/Comms/ANSI.htm
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: Firmware and infrastructure for a 6502 portable

Post by drogon »

jgharston wrote:
When doing terminal I/O support for PDP11 BASIC I did extensive research into ANSI/VT character sequences. Loads and loads of available documentation missed huge chunks out, I wanted a COMPLETE list of ABSO. LUTELY. *EVERYTHING* - *INCLUDING* gaps. Not just "we've omitted some stuff we oh so superiorly consider of no interest to you", but *WHAT* is in those gaps. In particular, *input* sequences were a right pain to track down. And, specifically, SORTED IN ORDER! Why on earth is so much documentation in random order?
It's a royal mess...

Having recently looked at all my ANSI stuff again - last time I fiddled with it was getting my '816 system talking to my Wyse-60 terminal - that did what I wanted it to do, but for convenience sake, I wanted to use minicom on my Linux box... That won't take the scroll up/down commands. Putty will, but I don't want to run Putty as it opens a new window. Drat and double drat!

(so I re-wrote a bit of my editor to re-draw the screen on a scroll up command)

And lets not get into the colour shenanigans, nor the hoops you need to jump through to get the terminal size... (cursor to 999,999 then ask where it's at)

-Gordon
Last edited by drogon on Sat Feb 21, 2026 7:33 am, edited 1 time in total.
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
No True Scotsman
Posts: 127
Joined: 22 Mar 2023

Re: Firmware and infrastructure for a 6502 portable

Post by No True Scotsman »

jgharston wrote:
Loads and loads of available documentation missed huge chunks out, I wanted a COMPLETE list of ABSO. LUTELY. *EVERYTHING* - *INCLUDING* gaps.
I only learned yesterday that ASCII characters 17 and 19 are the conventional characters for XON/XOFF. The charts just say "device control." To be fair though, the ASCII standard doesn't specify a use.

I'll take a look at your ANSI stuff. It sounds like it'll be helpful. Thanks!
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Firmware and infrastructure for a 6502 portable

Post by GARTHWILSON »

Thanks JGH.  I added it to my links page.
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
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Firmware and infrastructure for a 6502 portable

Post by BigDumbDinosaur »

No True Scotsman wrote:
So, all caveats aside, it should be a simple matter to get a recurring interrupt at a rate of 44.1kHz or thereabouts, right?
Yes.  The formula for computing the correct timer preload is...

Code: Select all

ctpl = (x1freq ÷ 2) ÷ hz

...where x1freq is your X1 oscillator frequency, nominally 3,686,400 Hz, hz is the desired interrupt rate, and ctpl is the 16-bit value to be loaded into the counter/timer registers.  Note that these registers are big-endian.  If using the 65C816 in native mode, you can load ctpl into the accumulator, reverse endianess with the XBA instruction, and then write the result into the DUART’s CTPU register as a 16-bit operation.

Quote:
Regarding non-standard bitrates, I had hoped to include MIDI among the uses of the second UART, but an application note I read said a 3 MHz oscillator would be needed for that. The first UART is permanently connected to the terminal at a standard table bitrate, so I'd have to be able to use standard and non-standard rates concurrently.
Setting up mixed rates with the 28L92 is straightforward.  Something that you could do is to run the DUART with the standard 3.6864 MHz oscillator and use the standard bit-rate table to drive the terminal interface.  Using a separate oscillator, you can provide a non-standard clock signal to the counter/timer through the IP2 pin, and then use the C/T to set up your MIDI bit rate by using it to drive the second channel’s receiver and transmitter bit rate generators.  The 28L92 is very flexible in that regard.  All of this is explained in the data sheet.

————————————————————
Edit: Fixed a sentence in which hz somehow disappeared.
Last edited by BigDumbDinosaur on Sun Feb 22, 2026 6:09 pm, edited 1 time in total.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
Post Reply