brett@smosjc.UUCP (Brett Coon) (07/06/90)
Is there an acceptable means to write self-modifying code on the Amiga? Assuming for the sake of argument that I have a good reason to do such a thing (and there's a good chance I don't), can I do it without risking future compatibility? My current plan is to select one of a few possible versions of the code at the beginning, and then patch the code to use the appropriate version. It would be done once, during initialization, so performance at this point is entirely unimportant. What I envision is an operating system call to clear the instruction cache, or do nothing if there is no cache. Surely something like this is done by the loader, right? Please, don't tell me the evils of self-modifying code, I'll only use it if I have to. Pretend this question is entirely academic. -brett -- |Brett Coon | uunet!smosjc!brett | |S-MOS Systems, Inc. | "You like 'em, anchovies?" | |San Jose, CA | -Runaway Train |
ckp@grebyn.com (Checkpoint Technologies) (07/06/90)
In article <293@smosjc.UUCP> brett@smosjc.UUCP (Brett Coon) writes: >Is there an acceptable means to write self-modifying code on the Amiga? > >Assuming for the sake of argument that I have a good reason to do such >a thing (and there's a good chance I don't), can I do it without risking >future compatibility? My current plan is to select one of a few possible >versions of the code at the beginning, and then patch the code to use the >appropriate version. It would be done once, during initialization, so >performance at this point is entirely unimportant. What I envision is an >operating system call to clear the instruction cache, or do nothing if there >is no cache. Surely something like this is done by the loader, right? > >Please, don't tell me the evils of self-modifying code, I'll only use it if >I have to. Pretend this question is entirely academic. OK, well, there's a purely theoretical way to do it that is free of danger from any kind of cache problems... Write your code out to a file in hunk format, then LoadSeg() it in. For better speed, write it to RAM:, that should work just as well. LoadSeg() must be capable of dealing with stale instruction cache in the presence of any large cache, or it won't work. On the 68030, I don't think it does, but then, after all the writing and reading, it's truly doubtful that there'd be any stale I-cache in the area of your new segment. Oh, and BTW, this will work under 1.3. The other suggestion, use the new 2.0 cache control function, will only work under 2.0 and later. And finally, of course... self-modifying code is not a good thing to do. -- First comes the logo: C H E C K P O I N T T E C H N O L O G I E S / / \\ / / Then, the disclaimer: All expressed opinions are, indeed, opinions. \ / o Now for the witty part: I'm pink, therefore, I'm spam! \/
forgeas@swinjm.UUCP (Jean-Michel Forgeas) (07/07/90)
In article <293@smosjc.UUCP> brett@smosjc.UUCP (Brett Coon) writes: >Is there an acceptable means to write self-modifying code on the Amiga? > >[...] My current plan is to select one of a few possible >versions of the code at the beginning, and then patch the code to use the >appropriate version. You have at least one other solution: use vectors. struct FuncNeeded { void (*func1)(); void (*func2)(); }; struct FuncNeeded Version1 = { Func1_1, Func1_2 }; struct FuncNeeded Version2 = { Func2_1, Func2_2 }; struct FuncNeeded *Version; init() { Version = (TheVersionYouWant ? &Version1 : &Version2 ) } program() { ... (*(Version->func1))(); ... retcode = (int*) (*(Version->func2))(); ... } > It would be done once, during initialization, so >performance at this point is entirely unimportant. It could be coded in asm like: init: ... lea Version1,a5 use a base register rts program: ... move.l func2vectoroffset(a5),a0 jsr (a0) ... rts -- \___/ Jean-Michel Forgeas \-/ cbmvax!cbmbsw!cbmsup!cbmfra!swinjm!forgeas | The Software Winery -^- And, where is the universe ?
daveh@cbmvax.commodore.com (Dave Haynie) (07/07/90)
In article <293@smosjc.UUCP> brett@smosjc.UUCP (Brett Coon) writes: >Is there an acceptable means to write self-modifying code on the Amiga? Overall, no. However, a side effect of using a 68000 CPU is that most, but not necessarily all, self-modifying code tricks work. So, if you test ExecBase->AttnFlags for 68000, and avoid the self modifying code if you find you're not running on the 68000. >Assuming for the sake of argument that I have a good reason to do such >a thing (and there's a good chance I don't), can I do it without risking >future compatibility? Well, as you said, there's a good chance that you don't. An extremely good chance. Because self-modifying code is never necessary. Sometimes it'll allow a very specific thing to be done faster. In the general case, it's foolish to risk limiting your product's market to old Amigas just to make things go slightly faster. Providing redundant routines for the same operation is probably the best thing you can do. As long as Motorola doesn't change the 68000 (which they certainly could, since they don't support self-modifying code either, but probably won't, since they have better things to do), you're OK if you run correct code when you find a 68020 or better in charge. >What I envision is an operating system call to clear the instruction cache, >or do nothing if there is no cache. Surely something like this is done by >the loader, right? Well, there is an OS call to clear the caches in 2.0, but that's still something you shouldn't use execept when necessary. And you should realize just what self-modifying code actually is. If you're choosing one of several subroutines, you most likely aren't self-modifying. Assignment of function pointers is done by hand in C all the time, and C++ actually formalizes a similar mechanism via its virtual function mechanism. The problem of self-modifying code occurs, from an application's point of view, when the application runs through a code chunk, modifys that code chunk, and then runs through it once again. >Please, don't tell me the evils of self-modifying code, I'll only use it if >I have to. Pretend this question is entirely academic. My advice is to never use self modifying code, but also to make sure you really know what constitutes self modifying code. -- Dave Haynie Commodore-Amiga (Amiga 3000) "The Crew That Never Rests" {uunet|pyramid|rutgers}!cbmvax!daveh PLINK: hazy BIX: hazy "I have been given the freedom to do as I see fit" -REM
vilkas@ultima.cs.uts.oz (Jhary a Conel) (07/09/90)
brett@smosjc.UUCP (Brett Coon) writes: >Is there an acceptable means to write self-modifying code on the Amiga? >Assuming for the sake of argument that I have a good reason to do such >a thing (and there's a good chance I don't), can I do it without risking >future compatibility? My current plan is to select one of a few possible >versions of the code at the beginning, and then patch the code to use the >appropriate version. It would be done once, during initialization, so >-brett Maybe I am off the track on this, but have you thought about using the DOS loadseg() command. I am not sure how to use it (never have myself) but if you have the different versions of the code in seperate code segments then you could select which one you want and then use loadseg() to bring it into memory and there would be no need for any self modifying anything. Just a suggestion. Jhary
jesup@cbmvax.commodore.com (Randell Jesup) (07/10/90)
In article <293@smosjc.UUCP> brett@smosjc.UUCP (Brett Coon) writes: >Is there an acceptable means to write self-modifying code on the Amiga? > >Assuming for the sake of argument that I have a good reason to do such >a thing (and there's a good chance I don't), can I do it without risking >future compatibility? My current plan is to select one of a few possible >versions of the code at the beginning, and then patch the code to use the >appropriate version. It would be done once, during initialization, so >performance at this point is entirely unimportant. What I envision is an >operating system call to clear the instruction cache, or do nothing if there >is no cache. Surely something like this is done by the loader, right? Well, if you _must_.... First, check the cpu type. If on an '030 or greater, check the OS version. If less than 36, use an '030 cache clear instruction. If greater or equal to 36, use CacheClearU (or CacheClearS from supervisor mode). Check the Autodocs on how to use it. Using CacheClearU/S means that if you are running on a post-030 processor or with external cache, the right things will happen. Under 2.0, LoadSeg uses this after patching relocation information, as does the scsi disk driver after doing dma. -- Randell Jesup, Keeper of AmigaDos, Commodore Engineering. {uunet|rutgers}!cbmvax!jesup, jesup@cbmvax.cbm.commodore.com BIX: rjesup Common phrase heard at Amiga Devcon '89: "It's in there!"
FelineGrace@cup.portal.com (Dana B Bourgeois) (07/12/90)
If the latest microprocessors don't allow self-modifying code does that spell the end of core-wars type games on modern computers? I guess I could keep that C64 around for corewars you betcha! Dana Bourgeois @ cup.portal.com
phorgan@cup.portal.com (Patrick John Horgan) (07/13/90)
Dana Bourgeois @ cup.portal.com said: |If the latest microprocessors don't allow self-modifying code does that |spell the end of core-wars type games on modern computers? I guess I |could keep that C64 around for corewars you betcha! Nope, Dana, we just simulate with CRobots:) Patrick