Self modifying code

Programming the 6502 microprocessor and its relatives in assembly and other languages.
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

From Lambda the Ultimate blog: http://www.uni-koblenz.de/~laemmel/expression/
tomaitheous
Posts: 24
Joined: 22 Sep 2007

Post by tomaitheous »

dclxvi wrote:
I agree. One thing I've done when writing self-modifying code is only make one change at a time from non-self-modifying to self-modifying, then test that change. Then, if it goes off into the weeds and pretty much clobbers everything in RAM (hey, it happens :)), I know where to look, and it's usually not too difficult to spot my error. On a related note, another principle I try to adhere to is don't get too clever too quickly. In other words, if it's really wild, start with something simpler and make small changes. Using those principles, self-modifying code doesn't seem (to me) to be significantly more difficult to debug than other code.
Yeah, I take it in steps as well. I usually write out the code in unoptimized easy to understand version, then rewrite it from scratch for self modifying version. The emu debugger I use is great though and very accurate.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Self modifying code

Post by GARTHWILSON »

I was looking around to see what others have done with self-modifying code, toying with the idea of writing a 6502/816-oriented article on it. [Edit, 6/17/19: Written and posted.] The more I look, the more I think there's a good amount of power available there that most of us have only scratched the surface of. Besides needing to finish up some other things, I need a rest from writing, and I need to get back to building. But if someone else will write a good 6502/816-oriented article on self-modifying code, I would definitely like to link to it on my links page, because this material needs to be clearly documented and available to everyone. It should gather and organize as much knowledge as possible on the subject, and give links and credits. This topic here can be a collection point, although it will lack organization.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
Oneironaut
Posts: 734
Joined: 25 May 2015
Location: Gillies, Ontario, Canada
Contact:

Re: Self modifying code

Post by Oneironaut »

Coming from AVR, it's almost ironic to call it "Self Modifying Code" at all. I see the 6502 as being a processor with 256 fast registers and 65280 slow registers!
Code, or data... it doesn't matter. It's just 64K that can be used to accomplish a given task.

On the AVR, writing to the Program Memory does have its consequences, since you are dealing with Flash. Slow write times, wear leveling, etc.

I am just a 6502 newb, but in my fresh opinion, "Self Modifying Code" makes absolute sense when you consider how much optimization it offers - both speed and code size. Is it more complex?... garbage in, garbage out!

Brad
User avatar
BitWise
In Memoriam
Posts: 996
Joined: 02 Mar 2004
Location: Berkshire, UK
Contact:

Re: Self modifying code

Post by BitWise »

Most of the code I write is intended for ROM so self modifying code is not really applicable but I have used it a few times.
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs
User avatar
KC9UDX
Posts: 246
Joined: 07 Dec 2013
Location: The Kettle Moraine

Re: Self modifying code

Post by KC9UDX »

When I was first working with 6502 assembly, I didn't know any better, so, I wondered why anyone would bother using STA ($00),y unless the code was in ROM. I always used STA $0000 and changed the operand bytes to my destination location.

As a matter of principal, I just don't do that anymore.

Once in a while, I think about using it to effectively JSR indirect, but, I never actually end up doing it.
User avatar
Rob Finch
Posts: 465
Joined: 29 Dec 2002
Location: Canada
Contact:

Re: Self modifying code

Post by Rob Finch »

One place where I used self-modifying code extensively was in a graphics library for the PC. Rather than have a conditional to determine the raster op, I had the code hardcoding the raster op using self modification. It sped up the graphics enormously (by eliminating all the branches).
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Self modifying code

Post by GARTHWILSON »

Rob Finch wrote:
One place where I used self-modifying code extensively was in a graphics library for the PC. Rather than have a conditional to determine the raster op, I had the code hardcoding the raster op using self modification. It sped up the graphics enormously (by eliminating all the branches).
Mike Naberezny did something like that to scroll a window that was only part of the screen on the PET.
KC9UDX wrote:
When I was first working with 6502 assembly, I didn't know any better, so, I wondered why anyone would bother using STA ($00),y unless the code was in ROM. I always used STA $0000 and changed the operand bytes to my destination location.
The CMOS 6502 does have STA(zp), an indirect without the indexing, taking 5 clocks rather than 4 like STA abs.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
BigDumbDinosaur
Posts: 9426
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Self modifying code

Post by BigDumbDinosaur »

Rob Finch wrote:
One place where I used self-modifying code extensively was in a graphics library for the PC. Rather than have a conditional to determine the raster op, I had the code hardcoding the raster op using self modification. It sped up the graphics enormously (by eliminating all the branches).
I've been guilty of using self-modifying code over the years, but am always mindful of the potential booby traps such code can bring. Indeed, modifying an absolute address so as to avoid the time penalty of indirect access is an excellent way to speed up video access. The 65C816 in native mode lessens the value of such a tactic, however, since one can cover a 64K address space with a 16 bit index using something like LDA $00,X.

In the UNIX environment, self-modifying code is not allowed, although it was at one time. An attempt to write into the code segment of a running process causes a memory access violation, followed by a core dump and forced termination of the process.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
White Flame
Posts: 704
Joined: 24 Jul 2012

Re: Self modifying code

Post by White Flame »

Self-modification can speed up dispatch points, and I don't think that's a problem.

I also have some round-robin code in one of my projects. Each routine gets a pass per frame or per interrupt, depending on whatever's active. The first instruction of the routine is "BIT nextRoutine" when enabled, which gets self-modded to "JMP nextRoutine" when disabled. I do similar in interrupting AcheronVM. Rerouting flow of control is really low overhead this way, as no checks are involved in the standard case. Changing a single instruction opcode costs exactly the same as setting a variable/flag to a particular value.
pebmeister
Posts: 32
Joined: 19 Feb 2013
Location: Marlborough, Ma

Re: Self modifying code

Post by pebmeister »

Why wouldn't you use a macro that takes parameters instead of self modifying code? It is much cleaner and safer.
User avatar
BigDumbDinosaur
Posts: 9426
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Self modifying code

Post by BigDumbDinosaur »

pebmeister wrote:
Why wouldn't you use a macro that takes parameters instead of self modifying code? It is much cleaner and safer.
A macro is an assembly-time function. Self-modifying code is a run-time function.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
RichTW
Posts: 95
Joined: 06 Oct 2010
Location: Palma, Spain

Re: Self modifying code

Post by RichTW »

I've used loads of self-modifying code in my time, the target platform being the BBC Micro, running code out of RAM.

One example was a sprite routine which ran in the zero page which self-modified plenty of its own operands (the self-modified address being in zp as well, saving another cycle). Here's a snippet of the innermost bit of the loop:

Code: Select all

innerloop:
read:
    LDA $FFFF,Y    ; self-modified
    STA maskindex+1
maskindex:
    LDA masktable  ; page-aligned table
write:
    AND $FFFF,Y    ; self-modified
    ORA maskindex+1
    STA (write+1),Y
    INY

etc
That reads sprite data (from (read+1)), looks up a mask for it in a pre-prepared table, masks the screen background, ORs the data over the masked screen data, and writes it back. I figure that the self-modification there saves 4 cycles per byte, which for this particular game saved up to 4900 cycles per frame from just that, plus other more modest savings elsewhere - not bad!

I also remember using them to self-modify the branch destination when entering an IRQ service routine, so that consecutive timer interrupts would go to different places in the code without needing to explicitly check it.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Self modifying code

Post by barrym95838 »

That inner loop looks pretty intense, Rich! A self-modifying ISR is a cool idea as well, as long as you stay on top of things and don't get out of sync.

Mike B.
Post Reply