Bank-switching like the KimKlone does would be possible to support via a cartridge on the C64. Alternatively - though I don't think any of them have been pushed to that size, the CBM REU's did memory transfers fast enough that they actually were faster than using the CPU (because they could use every available bus-cycle for the actual data transfer).
So you would likely need custom/new hardware, but in terms of how, it's a solved problem.
That's all right, this is an event driven parser so at no point does it actually need a full representation of the document in addressable memory to parse it.
As surprising as it sounds, this might actually have a practical use --- with the 6502 being such a tiny core it ends up in a lot of obscure MCUs, possibly with IoT-ish/toys/etc. high-volume low-cost applications, and the seeming unwillingness of a certain subset of developers to use more efficient binary protocols, I wouldn't be surprised if someone does end up needing to get a 6502 to parse JSON.
The 8051 and Z80 fill similar roles today --- when even the cheapest ARM core is too expensive.
I have a few STM32 projects where I need bidir communication between the microcontroller and the PC. The microcontroller has on the order of 10-20kB of RAM total and around 100kB of Flash.
After trying several other solutions I ended up with JSON over USB serial.
I tried several of the binary JSON-like variants, but they were all a PITA to port or ended up eating a lot of space, either in RAM or Flash or both. For this project I wasn't too concerned about message size or performance as such, as long as it could be read or generated in small portions.
I ended up adapting two JSON libraries, a one for parsing and for generating. The parser was SAX-like, so worked just fine for incremental parsing. Worked quite well, in total considerably smaller both in RAM and Flash than the alternatives.
Sure but I wasn't after fast parsing, I was after a somewhat flexible data exchange format that didn't take a lot of space (both data and code), and ideally was easy to debug.
A custom binary protocol would certainly be smaller but would take a lot more time to develop and debug.
Enter a JSON wrapper format for specifying assembly applications, compete with a NodeJS transpiler toolchain a la Babel.
Seriously though, it's been a while since I've had to work with assembly or IDA but JSON is great as an interoperable data format. Sure, it's not maximally efficient, but what needs to be?
As it happens, I'm coding on the 6502 for fun (demo maker :-)). And of course, I want to build my own super coll tools to help my development. However, I always come to the same conclusion : developping tools makes sense only if other people will use it (ie the effort I put in that must be amortized).
Now, if you say the 6502 is still a thing, then I may have some incentive to complete these tools...
> The 8051 and Z80 fill similar roles today --- when even the cheapest ARM core is too expensive.
This is a bit of a reach.
There is no world in which these and JSON appropriately intersect. If you’re parsing json then you’re probably dealing with enough need for sanitization that you have already fucked up if you’re at the point of an 8 bit MCU — how did the json get there in the first place?
The 6502 used to be a General purpose CPU, so for some retro hacking stuff that may be different.
> JSON65 supports incremental parsing, so you can freely feed it any sized chunks of input, and you don't need to have the whole file in memory at once.
It boggles the mind that we have a high quality JSON parser that supports this on such a constrained system, where many of the high-level language libraries that run on massively faster hardware don't.
Because it is slower? Many performant JSON parsers optimize parsing by batching, so it isn't constrained by possibly much slower I/O bottleneck. Also JSON65 itself does have a string size limit of 255 bytes.
Is the 6502 the peak of hobbyists writing assembly? I think it fills a fantastic niche of being well-documented while also not being completely terrible to write by hand.
I just spent the day writing 6502 assembly for my homebrew computer. I finished writing an in-place command line parser for a ROM monitor.
The 6502 has a lot going for it -- very small instruction set, simple instruction timing, etc.
But it's also a challenge because it's only got 3 registers, a fixed stack location, the zeropage, and some other strange properties. It's taken a little while to figure out how to use it effectively.
Personally I prefer the Z80 --- it has the advantage of many more registers, addressing modes more suited to HLLs, and a stack that is not limited to a fixed 256-byte portion of the address space. Of course it also needs more than twice the number of transistors and thus die area, which may be why the 6502 is still so widespread.
Z80 instruction set is nicer, but the Z80 was also half the speed per clock cycle, less responsive to interrupts, and more expensive. Hence why the 6502 got slapped in a lot more home computers and the like.
Actually the 6502 designers really intended it more for control systems / embedded.
Although Z80 has lower IPC, it had a roughly 2x clock speed so performance was about the same Z80 slightly faster for most applications.
It would be rare however for there to be a direct "bake off" between the two CPUs -- any given design organization was either an 8080/Z80 shop or a 6800/6502/6809 shop. There weren't sufficiently great differences in price/performance between the two to make it worthwhile changing.
You could get a BBC Model B (6502 2MHz), add the 3MHz 6502 board, add the 6MHz Z80B board, and do a "bake off" between all three (obvs. scaling for clock speed.)
Then add the 8MHz ARM1 board and watch it smoke the rest into dust, I suppose.
The 6502 was also in the right place at the right time in the wave of the great "homebrew computer club" era. There were so many DIY kits built around 6502 and 6502 clones. Some of the earliest mass produced (and mass consumed) "home computers" were all built around 6502 and 6502 clones. Not to mention how large a number of early game consoles were also built on those chips or their clones/offspring.
At least a little of hobbyists writing assembly in 6502 comes from nostalgia for early Apple, early Nintendo, early Commodore, etc.
Also, yeah as someone who's undergrad included a MOS 6502 "micro-controller" lab and Motorola 68k "microprocessor" lab courses, I can tell you from hands on experience that the 6502 really was in a fantastic place for writing clean, easy to debug assembly. That was a big time crunch factor in dealing with breadboarded machines where debugging the hardware was an equal or greater challenge. Given the choice between the two assembly languages I know which one I'd pick up again.
there's something incredibly comfortable about being able to view the instruction set along with affected flags and supported address modes in its entirety on something about the size of an index card
RISC-V has its own ISA summary card, AIUI. Plot twist: there are no address modes (since it's a load-store architecture, all loads and stores are explicit) and no flags to keep track of (since compare-and-branch instructions are used instead of flags, to make higher-performance implementations easier).
I don't even know hoe x86 experts got there. I'm constantly learning about all sorts of strange instruction that look like random strings and perform seemingly odd calculations.
Intel has kept their ISAs roughly-consistent with each other since 1972. Of course, in doing this, they have created a behemoth. You can't make something smaller when your goal is eternal (in)consistency.
You could probably get the entire (original, ARM1-3ish) ARM instruction set onto an index card with a little creative freedom. Possibly even a single side?
edit: Forgot to explicitly clarify that it was ARM
I do admit, given a choice I would rather program the 6809. I loved the 6502 and it was the first processor I learned assembly, but I still think the 6809 is better.
If you asked me to write a JSON parser in 6502 assembly, I would put the fairly short and unambiguous JSON grammar into lex and yacc to get a parser in C, then compile that to 6502 assembly. Then maybe glance through the assembly code, although I doubt very much that I know anything about assembly that the compiler doesn't.
Of course the author is a highly skilled person who also did this for his enjoyment. But am I missing some way in which what he did would be more than incrementally better than what I would do? Aren't these tools pretty much as good as the best humans at solving this problem?
There are some assembly languages that are pretty straightforward to write code in, and if you're organized it is not too onerous a task.
That said, 6502 is probably one of the LEAST featureful assembly languages I've ever used. I remember finding out it didn't have an ADD instruction - you clear carry, then add with carry.
Processors like the 6502 aren't considered very C friendly for a variety of reasons, but mostly because the register size isn't big enough for the most common data types like int or char *. You often end up with terrible ASM.
The "Library organization" section [1] explains that the json65.s file is the core of the library and the only code necessary to build the library. The additional C code provides a handy tree structure and a callback to pass to the parsing engine.
However, because SAX is a callback-oriented parsing method, you can design your own data structure and write your own callback functions and do without this tree structure.
The additional C code provides similar nice-to-haves, such as string pool interning, a function to print out the aforementioned tree structure, and a wrapper function to parse json from a file.
It's not misleading. It's a JSON parser written in 6502 assembly language. The C stuff is just things you may or may not want to do with a JSON parser (json65-file.c to parse the content of a given FILE, json65-tree.c to deserialize JSON into a tree data structure).
I would be careful to use this without validating and normalizing the unicode prior to passing it to this parser. Not saying that it's a bad design, but big flashing security warnings should be used so that people are aware that higher order unicode can and usually is normalized prior to JSON parsing (so that, e.g. producers that use full width quotation marks can have their json parsed correctly rather than not have the double quotes recognized) and this consumer can only handle fully normalized and validated UTF8
I always assume the worst! There will be some auto engineer trying to backport some functionality and will be googling "JSON Assembly" and will port this code.
It won't and should not be used in mission-critical applications, but just for extra fun, one may still want it to be as correct as possible. Right now I'm writing a cryptography library in PDP-11 assembly while investigating tools for its formal verification. Cryptoline looks like a promising candidate.
Never underestimate the longevity of systems, since new systems tend to be built on top of old systems.
Though I do not know any, I'm pretty sure in 2021 there *are* mission/security-critical applications running on 6502s in a number of places in the world.
The 6502 is one of the few processors validated for embedded medical devices. From https://www.westerndesigncenter.com/
".. the 65xx microprocessors protect millions of lives annually within embedded heart defibrillation and pacing systems. "
Can't get more mission-critical than that I suppose..
Its core, implemented in 6502 assembly, is a streaming parser and emits a series of events to signal the boundary of objects or arrays and atomic values. For example `[1, {"a": true}]` will emit something like `abegin; number 1; obegin; okey "a"; true; oend; aend; end`. There is a supplementary C library that parses this into a recursive structure (you will typically need to do the linear search for keys then).
You could use the CC65 compiler to compile C to 6502 assembly, although, even C generally uses a (relatively) obscene amount of memory on an 8-bit system.
For comparison, here is a single-file JSON parser I wrote for resource constrained systems, but which more targets things like 32-bit Cortex M systems rather than 8-bit: