-
Episode 5: Writing data from the 6502 to the Pi Pico
02/20/2024 at 16:28 • 0 commentsIn the last episode we talked about the Input side of I/O on the JJ65C02 project, which involved the Pi Pico interfacing with the PS/2 Keyboard and sending the corresponding ASCII character to the 6502, via the VIA chip. In this episode we're looking at the Output side, where the 6502 needs to send data to the Pi Pico to then send out to the VGA monitor. We'll see how the Pi Pico reads from the 8 data lines and ensures compliance with the 6502 timing diagrams. We use a simple PIO program and the Pi Pico's interrupt system to fill our output buffer on route to the VGA subsystem.
-
Latest Video: all about the miniOS
01/30/2024 at 10:18 • 0 commentsIn this latest video, we'll focus on miniOS, the operating system for the JJ65C02 project, which implements RAM testing, XMODEM file transfers, running and loading RAM images (pre-compiled 6502 codebases), WOZMON, and a port of the EhBASIC interpreter. miniOS is pure 65c02 source code and is available on GitHub. It's a great OS/boot-loader for BE6502-inspired projects.
-
The JJ65C02 Video Series
01/12/2024 at 20:17 • 0 commentsEpisode 1 just dropped:
-
Thoughts on sprites
12/28/2023 at 14:14 • 0 commentsImplementation musings
Now that the main details regarding the integration of the 6502 SBC and the Pi Pico I/O support chip are worked out, and working, I find myself mulling over details on how to add in sprite functionality (I know, I know... I should be working on adding audio to the Pico, but that isn't as intriguing right now). On one hand, I again want to resist the urge to make the JJ65C02 effort a Pi Pico-based system, with the 6502 as an afterthought, and instead want to focus on providing just enough capability to make it useful, but still be true to the whole retro vibe. In other words, I don't want this project to turn into another example of the tail wagging the dog.
Due to the limitations imposed, the video setup is a single frame-buffer, bit-mapped display, and so any sprite (or tile) work needs to be able to quickly update the video buffer by drawing the sprite, but also quickly erase the sprite cleanly (restoring the background) as well as handle transparency. By this, I mean that sprites aren't drawn on top of the background (as a layer) but actually drawn IN the background.
Some systems handle this by modifying the actual scanline data before it's rendered on the screen:
- Grab the scanline data from the frame buffer (the background)
- Draw the corresponding row data for the sprite overtop that scanline data
- Push the edited scanline to the VGA rendering system to have it printed out on the screen
The advantage is that the actual frame buffer itself is never directly modified. The disadvantage is that this is pretty complex to fold into the current DMA driven design.
Instead I'm looking into the following flow:
- Grab the memory area that the sprite will be written to from the frame buffer (VRAM)
- Store that away (backup)
- Now using a mask, write the sprite to that area
- Store away the x,y coordinates of the recent write
- When moving the sprite, restore the original memory area from the stored backup
- Jump to 1
Sprite Details
A sprite size of 16x16 fits nicely into a 640x480 screen and provides enough detail and depth to be useful. The actual sprite data itself will use 1byte/pixel, even though we only use 4bits/pixel internally. This is done so we can autogenerate the mask data from the actual sprite itself; by using $FF as code for transparent "color", we can load in the actual sprite data itself, and via shifting a single byte to a nibble, create the real sprite dataset and mask internally to the Pico and store them there, instead of transforming these on the fly, which takes time. In essence, the sprite data is sent from the 6502 to the Pico, which then takes take of converting it to a native format that can then be directly written to VRAM.
There is one catch, and it is bothersome. Because we store (internally, on the Pico) 2 pixels per byte, the byte itself must be aligned with an even X coordinate. That is, if we wanted to draw the sprite starting at, say (1,100), then we would need the 2nd nibble of the 1st byte of that sprite data (the last 4bits) to be written to the 1st nibble of the corresponding VRAM byte (recall that pixel (0,100) and (1,100) are stored in a single byte). A simple hack is to simply force X to be even to ensure byte alignment, and that is likely the 1st route I'll try. Again, this is because we will be writing the sprite data to VRAM directly via DMA, and not pixel-by-pixel. There might be some way around this by extending masking transparency for the special case where X is odd, but it all depends on the performance impact of doing that.
Internal to the Pico, the sprite will be a struct with 5 fields:
- the color-encoded bitmap (8x16=128bytes)
- the mask (also 128bytes)
- the stored background (128bytes again)
- Stored X coordinate
- Stored Y
Altogether we're looking at ~390bytes per sprite stored on the Pico (padding??). Considering that we're only using ~153k of the Pi Pico RAM, that gives us room for plenty of sprites, though limiting it to something like 32 makes sense. Also, 8 bytes on the Pico corresponds to a long long (or int64_t) so we can use native variables here and bit shifts along with XORs.
I'm sure that there will be other gotchas along the way, but this is a good start for now...
-
Thoughts on BASIC
12/18/2023 at 14:08 • 0 commentsNow that a lot of the hardware work has been done on the latest revision of JJ65C02, it's time to circle back and dive into the software side of things. My previous logs have described the updates to my miniOS for the system, and the integration with the Pi Pico, but the next stage is to see how best to update EhBasic to add graphics capabilities. This meant another deep-dive into the source for EhBasic and some thoughts about it which seemed like a good idea to post.
As noted in an older log, EhBasic was chosen over some other BASIC alternatives that exist out there. I touched on some reasons for picking it, instead of the others, but there were other factors that went into that decision. First of all, although not ideal, EhBasic did, at least, have pretty clear licensing behind it. The others had (and still have, IMO) somewhat questionable IP provenance: what are the exact copyright considerations for these codebases? They don't seem to have been released into the Public Domain, or under an Open Source license, which really means that we actually don't have any rights to use them. Sure, MSBasic and others have been around for awhile, and some could (and have) argue that if Gates et.al. were going to complain or sue, they would have done so by now. But for someone who takes these things seriously, that isn't good enough.
I also mentioned how of all the others, EhBasic was the easiest to port over to the ca65 toolchain, a non-trivial concern. Since I've baselined that development tool for all my work, and since it seems that most other serious 6502 hackers use it as well, providing an up-to-date port seemed like a worthwhile effort.
And finally, the code itself is well-enough architectured that after some time looking it over and playing around with it, you get a good understanding of how it all works, which is important when you want to fix or enhance it.
Which leads me into the next "theme" of this post, which is modifying EhBasic to support LOAD and SAVE.
LOAD/SAVE
Now miniOS does not include any sort of file-system capability; it's expected that in addition to the actual console of the SBC (the PS/2 keyboard and VGA monitor), that any sort of file transfers will be done using the RS232/serial interface. This means that, at a core level, both LOAD and SAVE will use XMODEM as the actual xfer mechanism, and that all LOAD and SAVE need to do is setup the correct pointers so that XMODEM knows where to read or write. This itself was trivial.
The real trick was that EhBasic doesn't store the text version of the BASIC program, but rather stores away its tokenized version which has already been "translated" from its original text. In essence, when you SAVE the program, you don't get (receive) the text version of your program, but a sort of binary version of it, meaning you can't then take that file and edit it with a standard text editor to make changes. It also means that you can't write the BASIC program on the host machine and then load it to EhBasic to run as-is. LOAD and SAVE all operate on this internal version of the BASIC program, not the original source itself.
The simple way around this is to use the functionality of whatever terminal emulator you have and save/load the source of the program by doing a LIST and then a text capture of what is printed, or a slow text paste of the source at the EhBasic prompt (so it thinks you are typing in the program). This is ugly and I'm looking into how to instead implement PLOAD and PSAVE which work on the actual source.
GRAPHICS
Also as previously mentioned, I want to add to EhBasic the ability to use the graphics primitives provided by the Pi Pico support chip. Currently, one can easily call them using an extended set of ANSI/Xterm escape sequences (see here) but I was thinking that creating DRAW, PLOT, etc... BASIC commands might be easier. Adding the commands isn't really complicated, but the actual glue which then converts the BASIC parameters to the actual ANSI Escape sequence seems like a lot of work for no real benefit, especially since one can easily create a BASIC function to, for example, draw a line, and call that without an actual BASIC command itself.
In a similar way, I'm not sure if I need to create actual 6502 graphics library subroutine in miniOS that can be called directly; that would require another interface to the Pi Pico beyond the escape sequences, which to me would again be adding complexity for little real value. I need to think about this some more.
Onwards and upwards...
-
Pi Pico integrated with miniOS
12/09/2023 at 19:12 • 0 commentsThe PCB for my JJ65C02 SBC is fully populated and work was done on integrating my miniOS with the Pi Pico I/O support chip. It now fully uses the PS/2 keyboard and VGA output as the system "console". I updated the miniOS to drop the old memory hexdump feature in preference to a port of WOZMON. WOZMON itself was updated to fully support the ca65 toolset, auto-conversion of lowercase input to uppercase, and an easy Quit command to return to the miniOS main menu.
The system itself is running at 4MHz and is rock solid.
On my TODO is further improvements to the miniOS and EhBASIC interpreter (ie, adding native graphics) and some initial testing on sound output. I'll also be pushing the speed a bit more and see if I can get to 6MHz.
-
Faster "EEPROM"
12/08/2023 at 21:30 • 0 commentsLike many, as I've starting ramping up the clock speed on my 6502-based SBC, it's the limited speed of the EEPROM (the AT28C256) which is the main limiting factor. A great replacement is to switch over to the DS1230Y Nonvolatile SRAM chip, which is pin compatible with the AT28C256 but much, much faster.
Using the TL866II+ programmer, you can upload your "ROM" image quite easily as well:
minipro -p "DS1230Y(RW)" -w ./minios.rom
-
PCBs delivered!
11/24/2023 at 12:38 • 0 commentsMy order of PCBs just got delivered. They look fantastic and I'm quite happy with the quality and the speed of the shipment. Can't wait to start populating them.
-
Update Demo: Pi Pico I/O Support chip
11/20/2023 at 16:16 • 0 commentsLots of work done over the last week or so on the I/O support chip for the JJ65C02 project. As a reminder, this Pi Pico is used for PS/2 keyboard input handling as well as VGA output and terminal emulation.
Most of the work was on the ANSI/VT100 emulation side, adding in a blinking cursor, support for a large subset of Escape Sequences and more robust and reliable performance. I've also added in some extensions to the official Escape Sequences which allow me to draw graphics while in "terminal mode". These will be added to my port of EhBasic.
All code and resources are available under permissive Open Source licenses on GitHub.
-
Raspberry Pi Pico Video and PS/2 Keyboard
11/13/2023 at 18:01 • 0 commentsI've pretty much completed the core library code for the VGA out and PS/2 Keyboard input handling on the Pi Pico, to be used as an A/V support chip on my JJ65C02 system and figured it was time for an update and even a video.
The Pico outputs basic VGA at 640x480 with 16 colors. The entire frame is bit-mapped which allows for exacting graphics. The 16-color (4-bit) color palette is based on standard RGB with an extra Intensity bit, all of which are translated to the 0-0.7V VGA levels via a standard resistor ladder (I found that 470ohms for the RGB signals and 1kohms for the Intensity signal seems to work best).
The VGA library supports Hunter-Adams graphics library with some additions, such as multiple fonts, scrolling, and a simple "text mode". The overall goal is to support a useful subset of Xterm/VT100 escape codes in addition to graphics primitives.
I also use the Pico for PS/2 keyboard input handling, and the conversion of the scancodes to ASCII values (upper case, lower case, and control codes).
Now that the basics are in place, I'll be ordering PCBs and interfacing the Pico with the 6502 board itself. Keyboard input will be transferred from the Pico to a VIA chip (with IRQ handling) and ASCII will be sent to the Pico via a different VIA port with a simple DATA_READY signal pin. With the single GPIO pin left over on the Pico, I've connected that to a simple audio amp circuit, so that I can eventually add audio waveform creation to the Pico as well.
I'm avoiding the temptation to add a LOT of functionality to the Pico; it is, after all, a support chip, not the core of the system.
You can see some of the basics running in the below video demo.