I find I keep on doing things like this:
raster_interrupt:
bgnd_color = * + 1
lda #$00
sta $d021
; rest of interrupt handler
so that I can do this kind of thing elsewhere in my program:
lda #$01
sta bgnd_color
This interrupt handler loads an immediate value into the accumulator, and then stores it in the hardware register that determines the background colour. Elsewhere in the program I modify that immediate value.
This saves a machine cycle in the interrupt handler, and does not use any zero page or other memory. Only the store instruction is a bit slower but that's okay; the background color doesn't change all that often.
The tricky part is maintaining the label that addresses the instruction's operand. As far as I can see, my options are:
what I did above, the
* + 1
which is hacky, unintuitive and more awkward for 16 bit quantities. Also it's less maintainable because the label is not in the same line as the address, which means version control won't treat them as one unit, and also seems like a breeding ground for gotofail bugs.label the instruction, and then refer to its operand with
label + 1
. This option I like slightly less because now the label names the instruction, not the value. That makes naming harder. Also I need to remember the+ 1
on every reference to the value.bgnd_color = raster_interrupt + 1
, riskier version of the first option.
I would much rather do this on the same line as the opcode (more maintainable, more version-control friendly), something like this:
raster_interrupt:
lda :bgnd_color
sta $d021
; rest of interrupt handler
(I just invented a syntax for the purposes of this question. The idea here is that bgnd_color
is still a label, but it's inline and denotes the address of the operand, 8 or 16 bits.). Self-modifying code is quite common on old micros, so I am surprised to not see any assemblers with features for conveniencing it. Have I overlooked any assembler that can do this?
ldBgColor_patch
, and if the value will be fetched from mutliple places in addition to the LDA that uses it (as is the case with e.g. pointer used by in MS-Basic's CHRGET), assign a symbol tobgColor .equ ldBgColor_patch+1
. That should be readable without assembler-specific knowledge, unlike approaches that exploit assembler-specific constructs.