It takes a special kind of person that is both intelligent and has the ability to explain what is happening in a way anyone can understand. If I had Ben as a professor I would go back to school just to go back to school.
Sadly, teacher's skills in say UK, are not teaching. Primarily it is the teacher's ability in crowd control over a group of kids that don't want to be there partly because of the previous lessons's crowd control emphasis. The teacher spends most of their efforts on crowd control and this crowd control emphasis is guaranteed by the imbalance of 33 pupils to 1 teacher. Or worse. If the teacher has any spare energy, some teaching can occur They don't have the latest most intresting subjects in schools, only the bread n butter basics, the ones that don't need much practical work
@@mb106429 It seems to get better in College, since most teachers don't care if you come to class or not as long as you pay your tuition. Although a lot of college professors are so into their field that they have a hard time giving the context required for a normal person to understand what they're saying.
Did I understand everything? No. Do I feel an enormous amount of respect and admiration for the people/person who came up this? Yes. As well as for you who walked us through it? Yes.
The elegance of falling through the conditions so you can setup the machine, while eliminating branch instructions to reduce both size of the binary, and clock cycles is brilliant.
My high school's electronics lab had a KIM-1 back in the 70s, along with a Heathkit H8. But I don't think I understood any of it very well until I bought Ben's 6502 kit and watched the videos.
My computing days go back the late 70s so this video was fascinating to watch. I bought an Apple II+ in 1980 and used Wozmon a lot to learn how to program the 6502. Considering the lack of development tools at the time and how crude they were, imagine the amount of effort it took for Steve Wozniak to create Wozmon. Today I could write Wozmon using modern development tools, but even with such tools, I doubt I could code something that was as small as 256 bytes. In one of Wozniak's books, he wrote that he literally would hand-write code on paper in the form of Ones and Zeros. Hell, that is like The Matrix in terms of his mind works. :)
Super interesting, yes. Genius program. Great example of something that needs to live in the creator's mind in its entirety all at once, that's my favorite special case of programming.
That property is what makes programming hard. Most humans are too limited in 'brain ram' to do that, so we should get mind chips already (unironically)
Thanks for the walkthrough Ben. Extremely well executed and demonstrates how elegant this software is, the depth of talent that Woz has and how great an educator you are. I would love to see more of this kind of content. There is something about seeing elegant/efficient algorithms in assembly that really gets you thinking. In todays high level programming world you don’t see this a lot but it’s so valuable to look back and understand in order to look forward and design.
Thanks Ben, for flashing me back to the late '70s when I learned all this stuff (on an 8080 but that's not important right now). The pure joy of 'touching the metal' with your mind is something any young person should experience. Woz was like a Kung Fu master.
Which is why i hate the media because they always talked about Steve Jobs being the genius and not woz. Kind of makes me wonder who is the real genius behind tesla and spaceX when the media is pumping the facade of Elon Musk being the genius down our throats.
@@Vilakazi I think Elon has said before that his success is due to hiring the best people. Jobs was definitely a visionary person, and so is Elon. You need big picture people, and people who are all about the details. Woz is a detail oriented person, Jobs was the big picture guy; you wouldn't have Apple without either.
"fall-through" code has always been a bit of a brain-breaker for me.. I have an incredible amount of respect for Woz for his talent in code alone, to say nothing of his other achievements in life. Guy's a genuine genius when it comes to computers and code. Then you get to modern ASM and there's SO MANY symbols/ops to remember.. I'll stick to modern typed languages of the C-variety lol
Try looking at RISC-V. MIPS is my other favorite streamlined, modern-ish ISA. ARM8 is simpler than x86 by a wide margin, but more complicated than RISC-V by quite a bit. All risc ISAs have some quirks that are meant to make things easier for chip designers and compiler writers that make stuff weird for hand ASM (for RISC-V: setting a register to a specific value can take multiple instructions), but you should be able to rely on your assembler to handle that in nearly all cases. The other joy of RISC-V is the ISA specification was written by professors as a teaching tool, so they are extremely readable and include notes on why it's setup the way it is. ARM docs read like they were written by a committee of patent lawyers and engineers (because...well). The AMD64 docs are similar in form to ARM8 docs but more so and they've clearly evolved over time and accrued bugs and omissions as things changed subtly over many generations of updates and edits.
@@jefffrasca4054easyest assembler I've done in years is AVR... some IO modes on the bigger microcontrollers is a bit quirky... but it's still really nice. Looking forward to getting into MIPS sometime soon.
One option would be to programm the lower tier ARMs because they come with quite condensed instruction set. E.g. RPi Pico uses the M0+ variety which I found somewhat accessible to learn basic assembly on a modern platform.
@@jefffrasca4054 Interesting thought: since all CPU's execute software via machine code... - How important is is for a country/countries/The West etc safety to have experts in assembly? - If no one understands what an .exe (or equivalent) does then that might(!) be problematic for national/international security?
This was an incredible deep dive! Thank you so much for this effort. I am learning so much and am finding a much deeper appreciation for what we have today and the people who helped get us there.
I was just randomly checking in on this channel and caught a video less then 30 minutes after dropping from someone who rarely uploads, absolutely insane! I've never had that happen!
Just made my own 8 bit computer (in Logisim) from your videos, I have no words how high quality your videos are, thank you Ben. Keep making quality videos 🎉, I love your channel ❤
Thank you for name dropping "logisim"- I had been wondering if there was such a program, and now that I have it, there's a whole world of circuit designs I can try before I actually build them out with physical circuits. Thank you so very much for your comment kind internet stranger ❤️
@@mashrien I kinda knew someone would find it really useful, I was thinking the same until I discovered it in another course about designing a cpu on udemy where he used that but I didn't take that course because Ben's is the best.
I started programming in assembler in the 1980's. Most of the code I wrote was space limited and like the code demonstrated here was written in a way with byte pinching (like using branch instead of jump instructions) stacked subroutines (Multiple entry but only one exit point) etc. When other programmers who have never had to write code with space restraints, looked at my code, I wasn't called a genius.... I was actually told that I program like a moron!
It's a fine line. I think a subroutine with three entry points and one RTS is fine, as is omitting the CLC before doing an ADC, as long as you add a comment that the carry flag is known at this point in the code. Some of the tricks seem a bit janky though - I particularly dislike the method of selecting the mode and would try to avoid it if at all possible.
@@timsmith2525 What sins? The terminology is there to mean something, in this case that we know the adjacent code chunks have distinct roles but connected program flow. A typical use might e.g. be if the ABI requires a large epilogue, factoring it out of your subroutines. It's a well known problem, to the degree that Intel added new instructions for it in the 80186. That the branching itself became as costly was a far later development, with deep pipelines and instruction caches. An example of such a common epilogue on 6502 is pushya in durexforth.asm.
@@0LoneTech "I was actually told that I program like a moron!" "Just call it tail call optimization." My point is that many people will judge things based on what they're called. Without a pretentious name, "three entry points and one RTS" is a bad practice; however, if you call it "tall call optimization", those same people will suddenly nod, and go, "Hmm…, Yes, tall call optimization." "The terminology is there to mean something." Not always: Sometimes it's there so people can sound important. Which is what I thought you meant when you implied that giving it a pretentious name will avoid the "moron" comments.
I love the simplicity of Ben's explaining such an elegant design from old times. Really makes me think if we actually need all of those abstractions we forced ourselves into nowadays.
There's another nifty bit of optimization in there that had me confused for a bit. Just after XAMNEXT the code loads A from XAML and then compares it with L but the next two instructions load A from XAMH and subtracts H. The compare sets the flags as if a subtraction had been done, but then the SBC instruction overwrites those flag settings. I was confused as to why there was no branch instruction after the compare. Then I realized that the CMP instruction sets the carry flag if A >= L, and then the SBC instruction includes the carry in the subraction. It could have been done with two SBC instructions, but then the carry flag would have to be cleared before doing the first subtraction. Doing it this way saves an extra byte of code.
I’m glad this has been highlighted. After seeing the advancements that AlphaGo had on optimizing assembly for sorting functions, I’m glad Ben commented on it and drew the beautiful parallel to biological systems and their inherent coupling.
Thanks so much, a video on wozmon has been at the top of my wishlist for SOO long, both because so many old toads like myself rave about it, but also because Woz himself seems an interesting guy! Frankly, the only reason I haven’t pestered you about it before was because of a dream of finding the free time to make a video like this myself! But it would never have been as good as your work, so luckily for everyone you beat me to it! :-) Again thanks, you’re a star!!
I was momentarily confused by the ADC #6 at the end, since the actual offset you need to add to print hex digits A-F as letters is 7, not 6. But then I realised that the carry flag would always be set at that point from the previous compare instruction. Just another memory-saving 6502 trick: why waste a whole byte clearing the carry flag when you can just add one less?
I really love this video. I've been looking for this sort of content for something like, let's say the early Pokemon games or Windows source code leaks and that sort of thing -- someone who knows what they're doing and has a knack for explaining these sorts of things. Thank you for all of your hard work and the phenomenal video!
pannenkoek2012 is pretty great, focused quite a bit around Super Mario 64. Recently discovered his video on crashing the game using the pendulum, super cool and nicely presented.
I have absolutely no idea what you are talking about or most of the comments but it sounds VERY interesting and ive always been amazed about how computers actually WORK so thanks for the upload!!!
Thanks Ben ! This is so awesome and bare metal. I feel the old ways of coding were so neat and direct . If one understands such implementation details while programming , it really feels like you're programming . These days there are so many abstraction levels (interpreting scripts/codes) between the user and the machine , it doesn't even feel like you're programming any more . 90% of your job is done by libraries when you write a code.
I always knew Steve Wozniak was a genius but it's fascinating to see it laid out like this. For a future video, have you considered trying to explain his famous hardware Breakout implementation?
Back in the early 80s when I was learning 6502 on an ITT 2020 and then an Apple II, as a total beginner I found Wozniak's Sweet16 extremely useful. Another one of his little coding miracles, using only a few hundred bytes.
I always say that assembly programming was like making a fully functional car out of only legos. The feeling when something finally worked was amazing. I don’t get that rush from modern programming.
Great video, never really looked at the wozmon code before.. That initial setup so that after initialization of the hardware after a reset the register value is negative so triggers an escape character sequence and a further initialization to 0 is just so efficiently sublime. It's been 30 years or more since I wrote assembly somewhat full time, I like to think assembly by default is more refined than most high level languages but I'll admit that I never got close to that refined.
Sorry for my English. Interesting and simply explained monitor prog. Apple 1. I like Motorola's concept of microprocessors and especially the 6502. In 1988 I had a Commodore VIC-20 and did some assembly language programming. I like assembly language (6502 has a simple way) and I'm looking for solutions for 8-bit microcontrollers similar in programming, stm8s103f series.... I also like the successors of the 8051, stc15fxxx. Steve Wozniak is of Polish origin and I am Polish.
I loved to code x86 asm back when I was young and I think I was quite good at it ... but this is brilliant! I can't imagine coding like this. Just WOW, Woz! ... a thanks for nice explanation @Ben
Ahh the finer details of assembly programming, a lost art in my onion. Watching this video reminds me of when I was doing embedded programming with the HD64180 in the late 80's. Thanks for a trip down memory late and a great video!
Lost, but also obsolete since as they said, modern programs have so much features that you would not be able to optimize this way without making it impossible to change and you would likely end up with many edge case bugs, and of cause, you would never ever finish a program. Offloading the assembly level to the compiler for all but maybe some tiny, super optimized, parts allows for bigger programs. While I never did much assembly programming I did a lot of turbo pascal where I also used a lot of "clever" solutions to speed up screen handling and not only did it make the program some 2000 times faster than relying on the normal IO libraries, it also made the resulting program much smaller since turbo pascal used a compiler that removed unused parts of any module you included. It was never even close to this amazing but still, I would never try to do anything similar again, maintaining and extending that code was a beast.
A lot "clicked" for me on the last 2 videos. Been working on compiling some NES roms with 6502 assembly, and this really is similar to the how the APU and PPU registers work. This is just a little bit less abstract, as WOZMON is, in itself, a controller. The optimizations and dependencies really highlight some logic ideas that were still foreign to my brain. Thanks for the great content!
Judging by how the buffer is specified to 128 bytes, not 256, you could probably get a bit of surprising behaviour. My first guess is all it would do is react as if you'd hit enter at 128 characters, but I haven't checked the code. Another probable behaviour would be to only parse 0 or 1 character. Edit: 5:14 provides our answer. If you hit enough characters, the BPL NEXTCHAR branch will not be taken, and the monitor will behave as if you hit escape, printing \ and discarding the input buffer. The buffer will not overflow, and the maximum line length should be 127 characters. And as described at 7:30, this behaviour is how wozmon initializes to begin with.
I think a way to cause undefined behaviour would be to store something that overwrites the CR character at the end of your input line, e.g. "206:30"; this should cause wozmon to keep reading the uninitialized part of the buffer as commands. It might hit an unexpected character and fall into escape, repeat fragments of earlier commands, or read the whole page out of bounds. Each time it wraps around from 2ff to 200, it should trigger nothex, so you could get behaviours like writing some sequence of bytes over all memory or rerunning the same examine command in a loop.
(13:44) I don't think you ever did look at the run code (not that it's particularly complicated, but there is a quirk with attempting to examine and then run a block to be pointed out there). (33:34) It's not mentioned here, but TONEXTITEM uses a jump to NEXTITEM rather than a branch, despite NEXTITEM being within branching range, because no flag that can be used for for branch instructions has a consistent state for every way to reach TONEXTITEM. (The original 6502 doesn't have a "branch always" instruction.)
Appreciate the walkthrough Ben & have forgotten a lot of the machine code concepts I studied as a kid & in early college. You're an amazing explainer & although I worked more on Z80 assembly the dependencies many of us did way back when were more or less the norm as memory was super expensive (even > 64kB was thought of as "page memory" for those rich enough to afford it) so saving storage was key, especially when coding assembly code on paper via hexadecimal. Had coded a rudimentary version of Frogger on the Z80 based Exidy Sorcerer at school with a buddy & it took us ages to create it, but we wanted a solution as spending a fortune on 20c coins was expensive (one could get a pie or bag of lollies with 20c). Never got to code in Wozmon but remember the Sorcerer had a similar hex monitor when you removed the BASIC ROM pack cartridge. When I got to college & worked with MASM & the MPF-1 Micro-Professor & saw how much easier it was to have a proper assembler it was far easier to create cleaner code with far less stress. It is amazing what Wozniak was able to create as a young engineer. Appreciate your efforts on everything you've been showcasing & God bless
Very interesting as always, Ben! It will be funny if you contacte Apple customer support to ask for the wrong comment on the mode decoding, and then share their reaction!
As a former Advisor, you’d get an answer along the lines of ‘sorry but I can’t help you’. Advisors are barely informed that the terminal exists, something like this is essentially magic
That was really interesting, thanks! That last print routine reminds me of an interview question I got asked at a company (now defunct) called Harlequin who had a PostScript(TM) compatible interpreter that they sold to various people. They used a lot of optimizations using something called "Duff's device" which I'd never heard of before. The idea is just that you can often unroll loops (in C code) and it makes them a little faster because you can have, say four iterations sequentially and you avoid having to do the comparison and branch for the first three. Of course that only works for loops which are a multiple of four, but you can get around that by wrapping the body in a case statement and the first time you enter the loop you check the number of iterations mod 4 and branch into the body of the loop to do n+4m iterations. The thing I learned at that interview was that C case statement is effectively just a bunch of labelled gotos and that you can write C code that looks like it should be a syntax error but it works!!!
C compilers generate jump tables for switch statements. So the whole point of Duff's device was to jump into an offset that allowed it to do the last few operations which weren't an exact match to the number of operations done per loop because branching has always been really costly, so instead of copying one element at a time, they would count down N at a time, usually 8 but not always, and the tail would be accounted for by jumping to the point where only that amount of operations would be done to finish the last loop.
There are other incorrect comments in Woz's code. ASL cannot generate an odd number, so the comment of $7B for STOR is incorrect. My guess is that Woz's comments are from an earlier version of WozMon which used the '=' character for STOR mode. If Woz's earlier version used ROR of '=' with carry set (instead of ASL ':') it would result in a $7B mode as described by the comment.
Take my like and subscribe; you've earned it. I cut my teeth hand-assembling code for both the 6502 and 6809, using the high mem ML monitor to enter them. Debug, and then back to pencil and paper until it worked. Was such a luxury when I started using my first assembler. My coco3 had the monitor as well as OS9. I wrote a crude implementation of the game Balderdash that used the FIRQ to pallete switch just offset from the vsync to create the flashing effect on the diamonds. In OS9, I wrote quite a few assembly projects such as xmodem, ymodem, GIF decoding and floyd-steinberg dithering to send images to my NX1000 dot matrix printer. Those were the days. So, quite fluent in the tricks like subroutines calling themselves and sharing an RTS, Putting two BNE's in a row to create a waypoint for long branching, etc. Later, I finally got back to a project I'd wanted to do for ages. I worked out the ray tracing engine from scratch (i.e., no reverse engineering) for the old Wolf 3D engine, including texture mapping. Implemented this in 8086 (oh gods what an awful processor; I miss my big endian 6809) in dosbox back in 2009. This was quite a trip down memory lane. For me, this era was the high point of computers. I think that two semesters should be spent requiring programmers to work at this level to get a better understanding of how these whole systems work. Again, many thanks. Looking forward to browsing your current postings and keeping up with your channel.
Regarding your critique from the guise of a 21st century programmer at around 8:45, I'll add my own two cents: the abstraction flood seems standard (to me) for heavily-optimized code. If you look at the output of any modern compiler with optimization enabled, the resulting assembly is full of these strange "huh... that's... one way to do it" constructs. I'm willing to bet this code went through several dozen (if not more) revisions to get it to fit in a single page of memory.
24:33 I am pretty sure you can send him an errata and we will post you a check for 2.56 dollars! Oops, maybe this is another programmer! Wonderful video, as always!
Rumours are if you create a recursive infinite loop with wozcode, woz himself appears and bonks you on the head with an original apple II for not having better exit conditions.
This is were the good old times when you did not need no stinking structured programming. You squeezed every byte of machine memory and every CPU cycle and it was glorious.
This takes me back to the days when I used a terrible 6502 disassembler that would always do _something_ no matter what you entered. Error checking would have required code, code would have required precious bytes, so it just didn't do that. Every character was a command and every command had at least one synonym because apparently it did bit operations and branched (or was it jump indirect?) on the bits. Since the character to store characters had synonyms, you had to be careful not to accidentally type one of them and unintentionally store a byte: for example instead of printing _x_ bytes starting at a location, accidentally typing a store command would store _x_ at that location. UGH.
Wait... the value for store mode comes from a left shift on BA, the colon character. But that results in 74, not 7B. Am I missing something or is that another mistake? Doesn't matter cause it only checks the top two bits, but that had me confused.
I think you're right. Interestingly, 7b would be correct if we were rotating in a 1 and the character was = (equals) instead of : (colon); my guess is the command was changed at some point, probably to match the printout. I don't think it's a simple typo because it is repeated.
Wozniac was extremely good at machine programming. That's the only reason the Apple ][ was able to do so much with so little. Extremely efficient code. Same thing with the Apple disk drives. Extremely simple, and yet it all works, thanks to extremely tight machine code. The Woz could program the metal so extremely well, it isn't funny. As someone who had (in my early days) to hand assemble 6502 code for the Apple ][+, i appreciate tight coding. I was watching to see if there was anything that i could improve in that code, and am happy to say i can't see a single instance where i could shave even a byte off of that code. 248 bytes is crazy small for as much as the Wozmon does. Heck, the mini assembler from the integer basic was also amazing.
So why was the underscore character (5F) used for Backspace? I thought it used a commercial serial ASCII keyboard. That should have a typewriter-like BACKSPACE key in the upper-right that encodes either 08 or 7F.
Hey bro I was literally trying to figure out how the computer actually works and how does the electrical signals actually works and i was full confused and then your channel showed up.. and I swear there is no one who gives better explanation than you. I appreciate your job bro keep it up. and I also wanted to know how a 64 bit or 32 bit computer works can you please make series on making a 32 bit or a 64 bit computer?
literally, it's the same only more so....32 bit is just 8 bit x4.....four times as wide for the arithematic and logic unit, four times as wide on the data bus and four times as deep for the control unit.....making a 32 bit computer about 64x harder to vizualize....
Seriously? Can you imagine the wiring on a 32 or 64 bit breadboard? It would be a rat's nest. Nevermind that they don't have breadboards for the kinds of sockets that a 32 or 64-bit chip would require.
@@CATech1138 There's no need to make the control unit deeper; that comes with pipelining (for which I recommend James Sharman's Homebrew CPU series). Mostly wider systems just take more logic and longer to operate (longer carry chains mean deeper logic). The next architectural step is byte addressing, which complicates the bus interface a little (e.g. this is what sets an AlphaPC apart from an Alpha). It's also possible to make bit-serial processors, using e.g. bit slice ALUs and shift registers. Olof Kindgren's SERV design would be possible, but stupidly tedious, to build on breadboards. It has video presentations available for its architecture too.
this code is arcane! I understood all the hacks as you explained them, but i still can't believe it. I did SNES assembly as a kid, and i definitely don't miss having to debug crap like this. this reminds me of Exapunks, a game where you program in assembly code too. All the top scores on the leaderboard (for execution time and for number of bytes) are all like this, it's nuts! Anyone who's watching videos like this, you'd probably like Exapunks, go check it out 😄
Code like this was meat and veg to a programmer back in the late seventies. The carefree treatment of dependencies was due to the fact that literality nothing else was happening in this computer. The various state indicators will have been put into a known state by the first piece of code, the reset. Even in a monitor that enabled the developer to run code outside the monitor, the break routine would save all the registers and flags in a buffer (which usually would be echoed to the display). When the developer had finished examining that data, a key press would just restore the registers and using a copy of the PC on the stack, the monitor would "return" to the program being examined. In the days of single thread, cacheless CPUs with very little RAM, the Monitor/system developer owned every byte of the computer. BTW, the tricky coding, especially on Z80 (which had more bytes to many ops) it was not unknown to JSR INTO the bytes of an op code to "overload" a routine!
There are some clever bits in it to save on bytes, but it is rather straight forward 6502 assembly with some fairly standard tricks. BUT I assume Woz probably had to invent a lot of it to fit the monitor into 256 bytes.
While watching the video I wondered how much experience Woz had had with the 6502 at the time he wrote this and how long it took him to write, debug and shoehorn into a single page.
Some great ideas put to practice here for code optimization, like the "falling through" of the functions into the next and only one return especially. A lot of these aren't good for code readability and you wouldn't want megabytes of program written this way, but for 248 bytes it works just fine Look up the speech "Art of code" by Dylan Beattie, He talks about some amazing code and is very easy to listen to
Thanks Ben for the deep dive into Wozmon. I have a problem with my contentration due to Long Covid, but this I can understand completely. Inspired by your clear tutorials I hope to build a 6502 board myself somewhere in near the future when my energy comes back.
Somewhat reminiscent of the PDP-11 ODT. It was quite compact, too, as it had to fit in the the 1k words of microcode, along with the whole standard instruction set.
Triggering some memories from college on Assembly. As a computer engineer myself, I say that I probably take C++ for granted. I almost forgot how holistic Assembly is with hardware.
It takes a special kind of person that is both intelligent and has the ability to explain what is happening in a way anyone can understand. If I had Ben as a professor I would go back to school just to go back to school.
Same
Sadly, teacher's skills in say UK, are not teaching.
Primarily it is the teacher's ability in crowd control over a group of kids that don't want to be there partly because of the previous lessons's crowd control emphasis.
The teacher spends most of their efforts on crowd control and this crowd control emphasis is guaranteed by the imbalance of 33 pupils to 1 teacher. Or worse.
If the teacher has any spare energy, some teaching can occur
They don't have the latest most intresting subjects in schools, only the bread n butter basics, the ones that don't need much practical work
@@mb106429 It seems to get better in College, since most teachers don't care if you come to class or not as long as you pay your tuition. Although a lot of college professors are so into their field that they have a hard time giving the context required for a normal person to understand what they're saying.
Ben is an excellent teacher.
@@mb106429 True in the US, which is why I left teaching to go back to programming computers.
Did I understand everything? No.
Do I feel an enormous amount of respect and admiration for the people/person who came up this? Yes.
As well as for you who walked us through it? Yes.
My apologise for anything I misinterpreted or misunderstood, English is my second language and I am very drunk currently.
@@DefaultFlame ok
The elegance of falling through the conditions so you can setup the machine, while eliminating branch instructions to reduce both size of the binary, and clock cycles is brilliant.
I’ve run Wozmon on my KIM-1 for years but never thought to do a deep dive to think about how it works. Excellent deep dive Ben!
My high school's electronics lab had a KIM-1 back in the 70s, along with a Heathkit H8. But I don't think I understood any of it very well until I bought Ben's 6502 kit and watched the videos.
@@alexstrasheim5451 yeah, Ben's many series are the best resource I've ever seen for first principles computing learning
35:42 I believe it actually adds 7, because the carry bit is set. This skips the 6 non-digit symbols after the digits, and the @ before the letters.
Exactly, adding 6 would make it a C0, while it needs to be C1 to display an "A", so you're totally right.
@@Beus38. ,ADC add always with carry-flag
This makes you appreciate how clean 'GOTO' usage actually is. :-)
Hahaha, exactly.
That is a much more elegant ASCII > HEX conversion than I have been using in my 6502 assembly! Now I'm going to go update my code...
Hihi…-Update this
My computing days go back the late 70s so this video was fascinating to watch. I bought an Apple II+ in 1980 and used Wozmon a lot to learn how to program the 6502. Considering the lack of development tools at the time and how crude they were, imagine the amount of effort it took for Steve Wozniak to create Wozmon. Today I could write Wozmon using modern development tools, but even with such tools, I doubt I could code something that was as small as 256 bytes. In one of Wozniak's books, he wrote that he literally would hand-write code on paper in the form of Ones and Zeros. Hell, that is like The Matrix in terms of his mind works. :)
Super interesting, yes. Genius program. Great example of something that needs to live in the creator's mind in its entirety all at once, that's my favorite special case of programming.
That property is what makes programming hard. Most humans are too limited in 'brain ram' to do that, so we should get mind chips already (unironically)
This is the kind of stuff you see in Atari 2600 cartridges, crazy compact code.
Thanks for the walkthrough Ben. Extremely well executed and demonstrates how elegant this software is, the depth of talent that Woz has and how great an educator you are.
I would love to see more of this kind of content. There is something about seeing elegant/efficient algorithms in assembly that really gets you thinking.
In todays high level programming world you don’t see this a lot but it’s so valuable to look back and understand in order to look forward and design.
Thanks Ben, for flashing me back to the late '70s when I learned all this stuff (on an 8080 but that's not important right now).
The pure joy of 'touching the metal' with your mind is something any young person should experience.
Woz was like a Kung Fu master.
Not the content that wins UA-cam, but the content that feeds my brain, thus winning me. Thanks Ben!
Woz's software is as ingeniously optimized as his hardware designs. What a talented guy.
@@Jamey_ETHZurich_TUe_Rulez Evidently, you dislike Wozniak
Which is why i hate the media because they always talked about Steve Jobs being the genius and not woz. Kind of makes me wonder who is the real genius behind tesla and spaceX when the media is pumping the facade of Elon Musk being the genius down our throats.
@@ducksonplays4190 he's an Elon Musk fan. They hate actual geniuses because the fake one's reminds them of themselves.
@@Vilakazi I think Elon has said before that his success is due to hiring the best people. Jobs was definitely a visionary person, and so is Elon. You need big picture people, and people who are all about the details. Woz is a detail oriented person, Jobs was the big picture guy; you wouldn't have Apple without either.
If the 5000$ story about BREAKOUT is true, Steve Jobs is definitely the greater genius for talking Wozniak into apple.
"fall-through" code has always been a bit of a brain-breaker for me.. I have an incredible amount of respect for Woz for his talent in code alone, to say nothing of his other achievements in life. Guy's a genuine genius when it comes to computers and code.
Then you get to modern ASM and there's SO MANY symbols/ops to remember.. I'll stick to modern typed languages of the C-variety lol
Try looking at RISC-V. MIPS is my other favorite streamlined, modern-ish ISA. ARM8 is simpler than x86 by a wide margin, but more complicated than RISC-V by quite a bit. All risc ISAs have some quirks that are meant to make things easier for chip designers and compiler writers that make stuff weird for hand ASM (for RISC-V: setting a register to a specific value can take multiple instructions), but you should be able to rely on your assembler to handle that in nearly all cases.
The other joy of RISC-V is the ISA specification was written by professors as a teaching tool, so they are extremely readable and include notes on why it's setup the way it is.
ARM docs read like they were written by a committee of patent lawyers and engineers (because...well).
The AMD64 docs are similar in form to ARM8 docs but more so and they've clearly evolved over time and accrued bugs and omissions as things changed subtly over many generations of updates and edits.
@@jefffrasca4054easyest assembler I've done in years is AVR... some IO modes on the bigger microcontrollers is a bit quirky... but it's still really nice.
Looking forward to getting into MIPS sometime soon.
One option would be to programm the lower tier ARMs because they come with quite condensed instruction set. E.g. RPi Pico uses the M0+ variety which I found somewhat accessible to learn basic assembly on a modern platform.
If you want to learn assembly, the Game Boy is a great place to start. It's (mostly) Z80, but the concepts are the same.
@@jefffrasca4054 Interesting thought: since all CPU's execute software via machine code...
- How important is is for a country/countries/The West etc safety to have experts in assembly?
- If no one understands what an .exe (or equivalent) does then that might(!) be problematic for national/international security?
This was an incredible deep dive! Thank you so much for this effort. I am learning so much and am finding a much deeper appreciation for what we have today and the people who helped get us there.
I was just randomly checking in on this channel and caught a video less then 30 minutes after dropping from someone who rarely uploads, absolutely insane! I've never had that happen!
Just made my own 8 bit computer (in Logisim) from your videos, I have no words how high quality your videos are, thank you Ben. Keep making quality videos 🎉, I love your channel ❤
Thank you for name dropping "logisim"- I had been wondering if there was such a program, and now that I have it, there's a whole world of circuit designs I can try before I actually build them out with physical circuits.
Thank you so very much for your comment kind internet stranger ❤️
@@mashrien I kinda knew someone would find it really useful, I was thinking the same until I discovered it in another course about designing a cpu on udemy where he used that but I didn't take that course because Ben's is the best.
@@piyush9555 I didn't really realize Ben had a course anywhere but here on UA-cam
I build one in Minecraft because of his videos
@@mashrien nope, it was some other guy
I started programming in assembler in the 1980's. Most of the code I wrote was space limited and like the code demonstrated here was written in a way with byte pinching (like using branch instead of jump instructions) stacked subroutines (Multiple entry but only one exit point) etc. When other programmers who have never had to write code with space restraints, looked at my code, I wasn't called a genius.... I was actually told that I program like a moron!
It's a fine line. I think a subroutine with three entry points and one RTS is fine, as is omitting the CLC before doing an ADC, as long as you add a comment that the carry flag is known at this point in the code. Some of the tricks seem a bit janky though - I particularly dislike the method of selecting the mode and would try to avoid it if at all possible.
Just call it tail call optimization.
@@0LoneTech Yes, pretentious terminology covers a multitude of sins.
@@timsmith2525 What sins? The terminology is there to mean something, in this case that we know the adjacent code chunks have distinct roles but connected program flow. A typical use might e.g. be if the ABI requires a large epilogue, factoring it out of your subroutines. It's a well known problem, to the degree that Intel added new instructions for it in the 80186. That the branching itself became as costly was a far later development, with deep pipelines and instruction caches.
An example of such a common epilogue on 6502 is pushya in durexforth.asm.
@@0LoneTech "I was actually told that I program like a moron!" "Just call it tail call optimization." My point is that many people will judge things based on what they're called.
Without a pretentious name, "three entry points and one RTS" is a bad practice; however, if you call it "tall call optimization", those same people will suddenly nod, and go, "Hmm…, Yes, tall call optimization."
"The terminology is there to mean something." Not always: Sometimes it's there so people can sound important. Which is what I thought you meant when you implied that giving it a pretentious name will avoid the "moron" comments.
I love the simplicity of Ben's explaining such an elegant design from old times. Really makes me think if we actually need all of those abstractions we forced ourselves into nowadays.
Thanks!
No problem!
There's another nifty bit of optimization in there that had me confused for a bit.
Just after XAMNEXT the code loads A from XAML and then compares it with L but the next two instructions load A from XAMH and subtracts H.
The compare sets the flags as if a subtraction had been done, but then the SBC instruction overwrites those flag settings.
I was confused as to why there was no branch instruction after the compare.
Then I realized that the CMP instruction sets the carry flag if A >= L, and then the SBC instruction includes the carry in the subraction.
It could have been done with two SBC instructions, but then the carry flag would have to be cleared before doing the first subtraction.
Doing it this way saves an extra byte of code.
9:36 does anyone else love when Ben goes down the philosophical rabbit hole?
I’m glad this has been highlighted. After seeing the advancements that AlphaGo had on optimizing assembly for sorting functions, I’m glad Ben commented on it and drew the beautiful parallel to biological systems and their inherent coupling.
Thanks so much, a video on wozmon has been at the top of my wishlist for SOO long, both because so many old toads like myself rave about it, but also because Woz himself seems an interesting guy! Frankly, the only reason I haven’t pestered you about it before was because of a dream of finding the free time to make a video like this myself! But it would never have been as good as your work, so luckily for everyone you beat me to it! :-) Again thanks, you’re a star!!
Brilliant work by both Wozniak and you, Ben. Your videos are always a treat.
Pure genius. Your explanation is amazing.
I know it's gonna be a good day when Ben uploads, great video as always!
Incredibly elegant code. Woz is the man!
I was momentarily confused by the ADC #6 at the end, since the actual offset you need to add to print hex digits A-F as letters is 7, not 6. But then I realised that the carry flag would always be set at that point from the previous compare instruction. Just another memory-saving 6502 trick: why waste a whole byte clearing the carry flag when you can just add one less?
I enjoyed the rare glimpse we got into the Waxing Philosophical side of Ben Eater (right before 10:00)...
I really love this video. I've been looking for this sort of content for something like, let's say the early Pokemon games or Windows source code leaks and that sort of thing -- someone who knows what they're doing and has a knack for explaining these sorts of things. Thank you for all of your hard work and the phenomenal video!
pannenkoek2012 is pretty great, focused quite a bit around Super Mario 64.
Recently discovered his video on crashing the game using the pendulum, super cool and nicely presented.
Thank you for trying to win youtube like this.
I have absolutely no idea what you are talking about or most of the comments but it sounds VERY interesting and ive always been amazed about how computers actually WORK so thanks for the upload!!!
Thanks Ben ! This is so awesome and bare metal. I feel the old ways of coding were so neat and direct . If one understands such implementation details while programming , it really feels like you're programming . These days there are so many abstraction levels (interpreting scripts/codes) between the user and the machine , it doesn't even feel like you're programming any more . 90% of your job is done by libraries when you write a code.
I thought Rocco from Udemy was an amazing coding teacher, but you are just insane. Wow. I'd absolutely pay for your courses.
Great code and great explanation! I had to pull my head a few decades back :-)
I always knew Steve Wozniak was a genius but it's fascinating to see it laid out like this. For a future video, have you considered trying to explain his famous hardware Breakout implementation?
Very well explained, Woz was very skilled 🙂
Woz is a genius. I wonder how long these subtle nuances were stored in his head until someone said hey, we need to write this down.
Nice one, Ben! Enjoyed that!
Back in the early 80s when I was learning 6502 on an ITT 2020 and then an Apple II, as a total beginner I found Wozniak's Sweet16 extremely useful. Another one of his little coding miracles, using only a few hundred bytes.
40 years ago I was quite happy coding in assembler!
I always say that assembly programming was like making a fully functional car out of only legos. The feeling when something finally worked was amazing. I don’t get that rush from modern programming.
Great video, never really looked at the wozmon code before.. That initial setup so that after initialization of the hardware after a reset the register value is negative so triggers an escape character sequence and a further initialization to 0 is just so efficiently sublime.
It's been 30 years or more since I wrote assembly somewhat full time, I like to think assembly by default is more refined than most high level languages but I'll admit that I never got close to that refined.
"Leaky abstraction" is such a good description.
Sorry for my English.
Interesting and simply explained monitor prog. Apple 1.
I like Motorola's concept of microprocessors and especially the 6502. In 1988 I had a Commodore VIC-20 and did some assembly language programming.
I like assembly language (6502 has a simple way) and I'm looking for solutions for 8-bit microcontrollers similar in programming, stm8s103f series....
I also like the successors of the 8051, stc15fxxx.
Steve Wozniak is of Polish origin and I am Polish.
I loved to code x86 asm back when I was young and I think I was quite good at it ... but this is brilliant! I can't imagine coding like this. Just WOW, Woz! ... a thanks for nice explanation @Ben
Very nostalgic seeing 6502 again :) Nice presentation!
I hope Woz gets to watch this and would love to hear his take on the breakdown.
Please make it happen. A vid of Woz assembling the bread-board 6502?
This is an *excellent* video Ben. One of the best things that I've seen in a long time. Thankyou!
Love the way you break these things down and go through it all fully
Ahh the finer details of assembly programming, a lost art in my onion. Watching this video reminds me of when I was doing embedded programming with the HD64180 in the late 80's. Thanks for a trip down memory late and a great video!
Lost, but also obsolete since as they said, modern programs have so much features that you would not be able to optimize this way without making it impossible to change and you would likely end up with many edge case bugs, and of cause, you would never ever finish a program.
Offloading the assembly level to the compiler for all but maybe some tiny, super optimized, parts allows for bigger programs.
While I never did much assembly programming I did a lot of turbo pascal where I also used a lot of "clever" solutions to speed up screen handling and not only did it make the program some 2000 times faster than relying on the normal IO libraries, it also made the resulting program much smaller since turbo pascal used a compiler that removed unused parts of any module you included.
It was never even close to this amazing but still, I would never try to do anything similar again, maintaining and extending that code was a beast.
Ben without doubt, you deserve to teach on MIT!!!
Like Always Great Video ive never learned AS much from UA-cam then in your vids
Awesome code explanation Ben, thank you 🥰
Most fascinating piece of code ever explained to me!
A lot "clicked" for me on the last 2 videos. Been working on compiling some NES roms with 6502 assembly, and this really is similar to the how the APU and PPU registers work. This is just a little bit less abstract, as WOZMON is, in itself, a controller. The optimizations and dependencies really highlight some logic ideas that were still foreign to my brain. Thanks for the great content!
4:07 Could you crash wozmon or cause undefined behaviour by overflowing that buffer?
Judging by how the buffer is specified to 128 bytes, not 256, you could probably get a bit of surprising behaviour. My first guess is all it would do is react as if you'd hit enter at 128 characters, but I haven't checked the code. Another probable behaviour would be to only parse 0 or 1 character.
Edit: 5:14 provides our answer. If you hit enough characters, the BPL NEXTCHAR branch will not be taken, and the monitor will behave as if you hit escape, printing \ and discarding the input buffer. The buffer will not overflow, and the maximum line length should be 127 characters. And as described at 7:30, this behaviour is how wozmon initializes to begin with.
If I'm understanding correctly, typing beyond the buffer would trigger an immediate ESCAPE, safely resetting wozmon to a blank state.
I think a way to cause undefined behaviour would be to store something that overwrites the CR character at the end of your input line, e.g. "206:30"; this should cause wozmon to keep reading the uninitialized part of the buffer as commands. It might hit an unexpected character and fall into escape, repeat fragments of earlier commands, or read the whole page out of bounds. Each time it wraps around from 2ff to 200, it should trigger nothex, so you could get behaviours like writing some sequence of bytes over all memory or rerunning the same examine command in a loop.
Resetting the parse point variable was a known trick to have the Apple II monitor repeat a command infinitely (you had to reset to break the loop).
(13:44) I don't think you ever did look at the run code (not that it's particularly complicated, but there is a quirk with attempting to examine and then run a block to be pointed out there).
(33:34) It's not mentioned here, but TONEXTITEM uses a jump to NEXTITEM rather than a branch, despite NEXTITEM being within branching range, because no flag that can be used for for branch instructions has a consistent state for every way to reach TONEXTITEM. (The original 6502 doesn't have a "branch always" instruction.)
Appreciate the walkthrough Ben & have forgotten a lot of the machine code concepts I studied as a kid & in early college.
You're an amazing explainer & although I worked more on Z80 assembly the dependencies many of us did way back when were more or less the norm as memory was super expensive (even > 64kB was thought of as "page memory" for those rich enough to afford it) so saving storage was key, especially when coding assembly code on paper via hexadecimal.
Had coded a rudimentary version of Frogger on the Z80 based Exidy Sorcerer at school with a buddy & it took us ages to create it, but we wanted a solution as spending a fortune on 20c coins was expensive (one could get a pie or bag of lollies with 20c).
Never got to code in Wozmon but remember the Sorcerer had a similar hex monitor when you removed the BASIC ROM pack cartridge.
When I got to college & worked with MASM & the MPF-1 Micro-Professor & saw how much easier it was to have a proper assembler it was far easier to create cleaner code with far less stress.
It is amazing what Wozniak was able to create as a young engineer.
Appreciate your efforts on everything you've been showcasing & God bless
Keep it up BEN ! love your videos much more interesting and informative than most.
Thank you for this walk through this maze. Can't decide if it's mad or genius. Probably both!
Back in the day when you jumped around doing a happy dance when you had an inspiration on how to save a single clock cycle.
Dangit Ben!
Thanks for half an hour of pure nostalgia.
& reminding me how old I am. :P
Very interesting as always, Ben! It will be funny if you contacte Apple customer support to ask for the wrong comment on the mode decoding, and then share their reaction!
Probably something like "support for this model is discontinued, please upgrade to the latest iMac for only $9999..."
As a former Advisor, you’d get an answer along the lines of ‘sorry but I can’t help you’. Advisors are barely informed that the terminal exists, something like this is essentially magic
That was really interesting, thanks! That last print routine reminds me of an interview question I got asked at a company (now defunct) called Harlequin who had a PostScript(TM) compatible interpreter that they sold to various people. They used a lot of optimizations using something called "Duff's device" which I'd never heard of before. The idea is just that you can often unroll loops (in C code) and it makes them a little faster because you can have, say four iterations sequentially and you avoid having to do the comparison and branch for the first three. Of course that only works for loops which are a multiple of four, but you can get around that by wrapping the body in a case statement and the first time you enter the loop you check the number of iterations mod 4 and branch into the body of the loop to do n+4m iterations. The thing I learned at that interview was that C case statement is effectively just a bunch of labelled gotos and that you can write C code that looks like it should be a syntax error but it works!!!
C compilers generate jump tables for switch statements. So the whole point of Duff's device was to jump into an offset that allowed it to do the last few operations which weren't an exact match to the number of operations done per loop because branching has always been really costly, so instead of copying one element at a time, they would count down N at a time, usually 8 but not always, and the tail would be accounted for by jumping to the point where only that amount of operations would be done to finish the last loop.
There are other incorrect comments in Woz's code. ASL cannot generate an odd number, so the comment of $7B for STOR is incorrect. My guess is that Woz's comments are from an earlier version of WozMon which used the '=' character for STOR mode. If Woz's earlier version used ROR of '=' with carry set (instead of ASL ':') it would result in a $7B mode as described by the comment.
Thanks!
Take my like and subscribe; you've earned it.
I cut my teeth hand-assembling code for both the 6502 and 6809, using the high mem ML monitor to enter them. Debug, and then back to pencil and paper until it worked. Was such a luxury when I started using my first assembler.
My coco3 had the monitor as well as OS9. I wrote a crude implementation of the game Balderdash that used the FIRQ to pallete switch just offset from the vsync to create the flashing effect on the diamonds.
In OS9, I wrote quite a few assembly projects such as xmodem, ymodem, GIF decoding and floyd-steinberg dithering to send images to my NX1000 dot matrix printer. Those were the days.
So, quite fluent in the tricks like subroutines calling themselves and sharing an RTS, Putting two BNE's in a row to create a waypoint for long branching, etc.
Later, I finally got back to a project I'd wanted to do for ages. I worked out the ray tracing engine from scratch (i.e., no reverse engineering) for the old Wolf 3D engine, including texture mapping. Implemented this in 8086 (oh gods what an awful processor; I miss my big endian 6809) in dosbox back in 2009.
This was quite a trip down memory lane. For me, this era was the high point of computers. I think that two semesters should be spent requiring programmers to work at this level to get a better understanding of how these whole systems work.
Again, many thanks. Looking forward to browsing your current postings and keeping up with your channel.
Google just offered me a job as a software engineer because someone at UA-cam told them I watched every single Ben Eater video.
Regarding your critique from the guise of a 21st century programmer at around 8:45, I'll add my own two cents: the abstraction flood seems standard (to me) for heavily-optimized code. If you look at the output of any modern compiler with optimization enabled, the resulting assembly is full of these strange "huh... that's... one way to do it" constructs.
I'm willing to bet this code went through several dozen (if not more) revisions to get it to fit in a single page of memory.
24:33 I am pretty sure you can send him an errata and we will post you a check for 2.56 dollars! Oops, maybe this is another programmer!
Wonderful video, as always!
You are thinking of Donald Knuth and The Art of Computer Programming.
Ben, this was a really fantastic video. I really appreciate it. I've been early watching all of your videos for a while! :)
thanks for the video. It brings me back to high school when we did learn to code on the Apple II
This is Great! Thanks for the deep dive! I feel smarter already. But also somehow dumber... Woz really produced with the APPLE 1 and 2.
Rewriting this for my own CPU I made in verilog, so this is useful ;)
What a joy-ride. thanks a lot.
Rumours are if you create a recursive infinite loop with wozcode, woz himself appears and bonks you on the head with an original apple II for not having better exit conditions.
09:46 I was so looking forward to seeing you inspect 0200-027F !
I worked through the code a couple of month ago but I max understood 60%. Cool explaination.
This is were the good old times when you did not need no stinking structured programming. You squeezed every byte of machine memory and every CPU cycle and it was glorious.
This takes me back to the days when I used a terrible 6502 disassembler that would always do _something_ no matter what you entered. Error checking would have required code, code would have required precious bytes, so it just didn't do that. Every character was a command and every command had at least one synonym because apparently it did bit operations and branched (or was it jump indirect?) on the bits. Since the character to store characters had synonyms, you had to be careful not to accidentally type one of them and unintentionally store a byte: for example instead of printing _x_ bytes starting at a location, accidentally typing a store command would store _x_ at that location. UGH.
I couldn't find anything decent at the time so I wrote my own machine code monitor for the 6502. I didn't have an assembler. Everything was in hex.
Your thoughts at 9:04 were super interesting !
Your channel made me try to learn assembly
Can anyone explain 13:00 why after ASL, A will become 7B not 74?? A is originally BA and BA
Wait... the value for store mode comes from a left shift on BA, the colon character. But that results in 74, not 7B. Am I missing something or is that another mistake? Doesn't matter cause it only checks the top two bits, but that had me confused.
I think you're right. Interestingly, 7b would be correct if we were rotating in a 1 and the character was = (equals) instead of : (colon); my guess is the command was changed at some point, probably to match the printout. I don't think it's a simple typo because it is repeated.
Yeah, it looks like another typo in the comments. It's actually 74 and you're right that it doesn't matter.
I've always been puzzled by the mnemonic used for the 6502's shift left operation. Surely LSL would make much more sense.
@@johnm2012 It's likely inherited from some other processor, e.g. 6800 which is slightly older and has ASL/ASR/LSR/ROL/ROR.
@@0LoneTech That would make some sense, though I would still wonder why ASL was chosen as the mnemonic for the 6800 instead of LSL.
Wozniak= Genius !
Wozniac was extremely good at machine programming. That's the only reason the Apple ][ was able to do so much with so little. Extremely efficient code. Same thing with the Apple disk drives. Extremely simple, and yet it all works, thanks to extremely tight machine code. The Woz could program the metal so extremely well, it isn't funny.
As someone who had (in my early days) to hand assemble 6502 code for the Apple ][+, i appreciate tight coding. I was watching to see if there was anything that i could improve in that code, and am happy to say i can't see a single instance where i could shave even a byte off of that code. 248 bytes is crazy small for as much as the Wozmon does.
Heck, the mini assembler from the integer basic was also amazing.
Back in the early 80s I always wondered how that mini disassembler worked, perhaps Ben can make a deep dive into that as well!
So why was the underscore character (5F) used for Backspace? I thought it used a commercial serial ASCII keyboard. That should have a typewriter-like BACKSPACE key in the upper-right that encodes either 08 or 7F.
Hey bro I was literally trying to figure out how the computer actually works and how does the electrical signals actually works and i was full confused and then your channel showed up.. and I swear there is no one who gives better explanation than you.
I appreciate your job bro keep it up.
and I also wanted to know how a 64 bit or 32 bit computer works can you please make series on making a 32 bit or a 64 bit computer?
literally, it's the same only more so....32 bit is just 8 bit x4.....four times as wide for the arithematic and logic unit, four times as wide on the data bus and four times as deep for the control unit.....making a 32 bit computer about 64x harder to vizualize....
Seriously? Can you imagine the wiring on a 32 or 64 bit breadboard? It would be a rat's nest. Nevermind that they don't have breadboards for the kinds of sockets that a 32 or 64-bit chip would require.
@@CATech1138 There's no need to make the control unit deeper; that comes with pipelining (for which I recommend James Sharman's Homebrew CPU series). Mostly wider systems just take more logic and longer to operate (longer carry chains mean deeper logic). The next architectural step is byte addressing, which complicates the bus interface a little (e.g. this is what sets an AlphaPC apart from an Alpha).
It's also possible to make bit-serial processors, using e.g. bit slice ALUs and shift registers. Olof Kindgren's SERV design would be possible, but stupidly tedious, to build on breadboards. It has video presentations available for its architecture too.
Thank you. This is an amazing breakdown.
"I couldn't find anyone else who pointed out this was wrong"... Us watching like: "I know right! So easy to spot!"
this code is arcane! I understood all the hacks as you explained them, but i still can't believe it. I did SNES assembly as a kid, and i definitely don't miss having to debug crap like this.
this reminds me of Exapunks, a game where you program in assembly code too. All the top scores on the leaderboard (for execution time and for number of bytes) are all like this, it's nuts! Anyone who's watching videos like this, you'd probably like Exapunks, go check it out 😄
Code like this was meat and veg to a programmer back in the late seventies. The carefree treatment of dependencies was due to the fact that literality nothing else was happening in this computer. The various state indicators will have been put into a known state by the first piece of code, the reset. Even in a monitor that enabled the developer to run code outside the monitor, the break routine would save all the registers and flags in a buffer (which usually would be echoed to the display). When the developer had finished examining that data, a key press would just restore the registers and using a copy of the PC on the stack, the monitor would "return" to the program being examined. In the days of single thread, cacheless CPUs with very little RAM, the Monitor/system developer owned every byte of the computer. BTW, the tricky coding, especially on Z80 (which had more bytes to many ops) it was not unknown to JSR INTO the bytes of an op code to "overload" a routine!
so beautiful. i want to give woz a hug.
There are some clever bits in it to save on bytes, but it is rather straight forward 6502 assembly with some fairly standard tricks. BUT I assume Woz probably had to invent a lot of it to fit the monitor into 256 bytes.
Yeah, they're standard tricks NOW :) Coming up with what will become the future's standard tricks is indeed the tricky part!
While watching the video I wondered how much experience Woz had had with the 6502 at the time he wrote this and how long it took him to write, debug and shoehorn into a single page.
"Babe, wake up, Ben just uploaded a new video"
Some great ideas put to practice here for code optimization, like the "falling through" of the functions into the next and only one return especially. A lot of these aren't good for code readability and you wouldn't want megabytes of program written this way, but for 248 bytes it works just fine
Look up the speech "Art of code" by Dylan Beattie, He talks about some amazing code and is very easy to listen to
Thanks Ben for the deep dive into Wozmon. I have a problem with my contentration due to Long Covid, but this I can understand completely. Inspired by your clear tutorials I hope to build a 6502 board myself somewhere in near the future when my energy comes back.
Inspiring, don't ever give up on yourr drreams, even if you have to reschedule them, again.. ;]
@@OurSpaceshipEarth Thanks.
This really makes me want to go back and play Exapunks again
The 6502 was my favorite processor. My first A.I. was written by me, in this nomenclature.
Somewhat reminiscent of the PDP-11 ODT. It was quite compact, too, as it had to fit in the the 1k words of microcode, along with the whole standard instruction set.
Triggering some memories from college on Assembly. As a computer engineer myself, I say that I probably take C++ for granted. I almost forgot how holistic Assembly is with hardware.