My only assembly experience was from courses back in university and I forgot most of it, but one thing I remember is that you would pass arguments to subroutines via the stack. That last example finally looked like a real subroutine to be used in a bigger program, it's getting exciting :)
@@xerca slowly but surely we are getting to the payoff. I’d love to be able to do a simple advent of code problem using 6502 assembly , would be a personal achievement 😁
Sorta...Not really. in x86 you have MOV [SP+???], which lets you read relative to the stack pointer. in 6502, you don't. You can only be relative to X, Y or A. Unless you're willing to dedicate one of those and load it with the stack pointer every time (TSX, TSY), I suggest you use global structs/unions in page 0. (That's how Mario Bros work). To make matters worse, the stack is on page 1 making accessing the stack for RW purposes even harder
@@eitantal726 I see, the stack isn't as practical then. You are right I remembered this from x86 assembly from the systems programming class. We also did 8-bit programming in microprocessor lab, but that was just a cpu on a board with hex keys and 7-segment displays. We solved simple problems in assembly on paper, then keyed them in as machine code. To me, this full-fledged 8-bit pc programming still feels very mysterious, like a strange mixture of simple and complex.
@@xerca Stack in 6502 is used for function returns, and handy context preservation: returning X, Y, A registers to how you found them in the beginning of your function. Param passing is therefore through global, or register. Not sure if C 6502 compiler uses stack for arguments. If it does, the performance will suffer
@@xerca A lot of the time, people just reserve specific addresses in memory to persist values. Unless you're expecting a routine to be reentrant, this isn't a big deal. The value of a stack in higher level languages is to allow for reentrancy, but the programs you'll write on 8-bit and embedded systems normally aren't the kind that benefit much from that, so even compilers will just block off chunks of memory as scratch space in such a way that any routines won't have overlapping scratch space, which isn't difficult once you have a complete call graph. That means you don't need to lean on the stack as much. CC65 is worth looking at for what it does.
TBH, indirect addressing with JMP isn't super useful unless you're writing an OS and want to provide locations with jump vectors on various events (such as NMIs or IRQs on I/O events, &c.) or the like.
The 6502 would very much be hard mode for anything like AoC! Something like a 6809 or Z80 world be much easier 8-bit CPUs to work with, though personally I'd go for something like 68000 or ARMv2/ARMv3, as both of those at least have nice things like a decent set of 32-bit registers, multiplication, and so forth. The earlier ARM ISA is heavily inspired by the 6502, and it's something a person can keep in their head. A bonus is that if you run an Acorn Archimedes emulator, it has BBC BASIC as part of it, which has a built-in macro assembler! It's '80s/'90s technology, so I don't think it's cheating!
That's really cool, all of it! Def 32 bit registers would be nice since some of the values in AoC can be quite large. I'll worry about a project with the 6502 after I know more :) I want to check out all the British computers, Acorn, BBC, ZX80 Spectrum, all that stuff seems neat. Maybe Acorn and BBC are the same? No idea haha
My only assembly experience was from courses back in university and I forgot most of it, but one thing I remember is that you would pass arguments to subroutines via the stack. That last example finally looked like a real subroutine to be used in a bigger program, it's getting exciting :)
@@xerca slowly but surely we are getting to the payoff. I’d love to be able to do a simple advent of code problem using 6502 assembly , would be a personal achievement 😁
Sorta...Not really. in x86 you have MOV [SP+???], which lets you read relative to the stack pointer. in 6502, you don't. You can only be relative to X, Y or A. Unless you're willing to dedicate one of those and load it with the stack pointer every time (TSX, TSY), I suggest you use global structs/unions in page 0. (That's how Mario Bros work). To make matters worse, the stack is on page 1 making accessing the stack for RW purposes even harder
@@eitantal726 I see, the stack isn't as practical then. You are right I remembered this from x86 assembly from the systems programming class. We also did 8-bit programming in microprocessor lab, but that was just a cpu on a board with hex keys and 7-segment displays. We solved simple problems in assembly on paper, then keyed them in as machine code.
To me, this full-fledged 8-bit pc programming still feels very mysterious, like a strange mixture of simple and complex.
@@xerca Stack in 6502 is used for function returns, and handy context preservation: returning X, Y, A registers to how you found them in the beginning of your function. Param passing is therefore through global, or register. Not sure if C 6502 compiler uses stack for arguments. If it does, the performance will suffer
@@xerca A lot of the time, people just reserve specific addresses in memory to persist values. Unless you're expecting a routine to be reentrant, this isn't a big deal. The value of a stack in higher level languages is to allow for reentrancy, but the programs you'll write on 8-bit and embedded systems normally aren't the kind that benefit much from that, so even compilers will just block off chunks of memory as scratch space in such a way that any routines won't have overlapping scratch space, which isn't difficult once you have a complete call graph. That means you don't need to lean on the stack as much.
CC65 is worth looking at for what it does.
TBH, indirect addressing with JMP isn't super useful unless you're writing an OS and want to provide locations with jump vectors on various events (such as NMIs or IRQs on I/O events, &c.) or the like.
The 6502 would very much be hard mode for anything like AoC! Something like a 6809 or Z80 world be much easier 8-bit CPUs to work with, though personally I'd go for something like 68000 or ARMv2/ARMv3, as both of those at least have nice things like a decent set of 32-bit registers, multiplication, and so forth. The earlier ARM ISA is heavily inspired by the 6502, and it's something a person can keep in their head. A bonus is that if you run an Acorn Archimedes emulator, it has BBC BASIC as part of it, which has a built-in macro assembler! It's '80s/'90s technology, so I don't think it's cheating!
That's really cool, all of it! Def 32 bit registers would be nice since some of the values in AoC can be quite large. I'll worry about a project with the 6502 after I know more :) I want to check out all the British computers, Acorn, BBC, ZX80 Spectrum, all that stuff seems neat. Maybe Acorn and BBC are the same? No idea haha