I am building a laptop using some MCUs to emulate a 6502, 256kb memory, SID-sound and filesystem.
To make the experience fit your profile, pick a username and tell us what interests you.
I've rebuilt keyboards before. Liking/wanting thin and split keyboards necessitates doing that, there are none ready to buy. Lately I've wondered about minimizing the number of keys as well. Suddenly I got the urge to try it out, and that lead to a new experimental PZ1-keyboard!
It communicates via standard serial, not USB or PS/2 connection. This makes it a LOT less bothersome to receive data from :)
Now I only have to figure out a good way to make some keycaps or overlay. It is definitely much smaller than the real keyboard I've used so far. We'll just see which I prefer down the line.
Since I've worked on the HW aspects of the project I started to question my choice to divide the 64KiB memory space into 8 banks of 8KiB each. I guess 8x8 had a nice ring to it...
The HW is now designed with 4x 16KiB banks, and the SW has changed accordingly. It lead to significantly fewer number of cycles required in thread switching, and the code actually looks much cleaner since the banks are fewer. It also feels like 4 is a very good number to use, 1 for the scheduler/OS, 1 for the main code/stack/ZP for each thread, and 2 more to make swapping/copying in each thread painless. Fewer banks would be cumbersome, more banks are not really necessary very often.
One downside is the increased waste when doing small threads, but that is not a real problem with all the memory available in this system.
Well, I seem to have the HW bug.
I could not let go of figuring out how to do the PZ1 in real HW, and have been working at solving the bank switching. I started sketching it with 74-chips (done), and now I am using the rather arcane program WinCUPL to design a solution with an Atmel atf750c-chip that solves the bank switching. It's not really powerful enough to be a CPLD, but a bit better than PAL/GAL.
WinCUPL is really bad at giving hints about what is wrong, so too much time has been spent on trying to get a syntactically correct description. I now have a description and simulation vectors that seem to do what I want. I am really tempted to order parts now, but I'll mull on it for a while first.
The only reason I chose the atf750c was because I've got a Dataman S4 programmer that supports the chip :)
I've claimed that this computer is possible to build, it is not only a SW dream. Well, to see if my claims still hold true I've had a go at making a schematic for the memory and bank-switching logic. Using available 74HC-logic and a 512KiB SRAM, I've used 18 chips to make it equivalent to the SW-implementation. While doing this I realise that it id indeed possible to do in HW, but anything faster than 2MHz would probably not work because of all the propagation delays. It would also take up quite some space, even if using surface mounted chips.
If I really want to do this in real HW, an FPGA or CPLD would be a much better choice. Or a ROM of some sort, together with the registers.
Latest improvement: battery and power/charge circuitry so that PZ1 for the first time is a truly stand-alone laptop! It was a while since I measured the power requirements, but based on those old numbers (~1.5W) the battery should last at least 12h.
I also took the opportunity to zip-tie everything.
For the 6502-emulation I've used source from fake6502 and miker00lz Arduino 6502 which seems to be based on fake6502 as well. They both had some small issues that I've improved as I've used the code, but one aspect I never fixed was ADC/SBC decimal mode. Today I started verifying the emulation with a test suite found at https://github.com/Klaus2m5/6502_65C02_functional_tests/tree/master
Klaus has worked very hard on testing the functionality of the op-codes, and has had some very interesting discussions with several persons on the 6502.org-forum
I have now run the full test suite and fixed the ADC/SBC errors, so now I can say with much better certainty that the 6502-emulation works.
The inner workings of ADC/SBC is not very easy to grasp, I had to search for a while before I found an implementation that was already verified and modify my code from there. Thanks to Marek Carcz VM6502: https://github.com/makarcz/vm6502 for a correct and verified ADC/SBC!
I have refactored a lot of the code, including cleaning up and moving the basic to lower memory. ehBasic may be free and powerful, but it is also quite a mess in places.
I can now load 2 instances of basic, each using a separate serial port. Both are running in fully separated 64KiB memory windows, except for the HW ports. The main reason to run 2 basics is to test thread communication, which I'll start on next.
The memory allocator works the way I want it now. Here's an example with all commands run in basic.
REM load 4 threads via serial port tload1 tload1 tload1 tload1 REM print info about the threads Thread nr Slot time Blocks 0 20 1 2 3 4 5 6 7 8 1 10 9 2 10 10 3 10 11 4 10 12 REM kill 2 threads tkill1 tkill3 REM load a 64KiB thread tload8 REM raise slot time for thread 0, ehBasic tslotw0,80 REM print info about the threads Thread nr Slot time Blocks 0 80 1 2 3 4 5 6 7 8 2 10 10 4 10 12 5 10 9 11 13 14 15 16 17 18
Killing thread 1 & 3 creates holes in the block-pool. Thread 5 gets non-consecutive blocks allocated, but it does not matter because the memory is run in the linear 64KiB CPU-space. Banked memory can be good to get rid of memory fragmentation problems.
In other words, I've got (simple) virtual memory management in place :)
OK, I've coded more on the multitasking scheduler and filmed a short video demo. Nothing fancy, but shows off what it can do at this moment. All the scheduler functions are available from Basic, so the demo is done in Basic. The threads are pure 6502 assembler. The SID-player at the end is a standard PSID binary played in a separate 64KiB environment. The text threads are given 8KiB each. Lots more memory to go :D
I've been coding 6502-assembler for a while now, working on the system code. It's interesting to plan all the bits, and see how it works out in reality. So far so good.
Latest functionality I made was an S19-loader so it is easier to start new threads without juggling with the SD-card. The S19 format is surprisingly powerful, but can also be implemented VERY compactly if corners are cut. I'll have to revisit this in the future, to add the corners.
Focus now is on making os-code to be able to load/start/stop/manipulate threads. I've decided the commands for this will be available from Basic, bringing a truly 80's retro vibe. It's also quite usable. Beginnings of re-entrant os routines have been coded, but are not fully tested.
Basic will run as thread 0 and it will be possible to run more threads. Only zero page memory and cpu-cycles are limiting the number of practically usable threads.
In a weak moment I was thinking about trying out cc65 to write code in C. That idea is postponed since I started this project to code 6502 assembler.
Become a member to follow this project and never miss any updates