64 byte hell

  To deter anyone from spending 3 evenings trying endless tricks to fit "code that does something" in the 28 bytes left after the Amiga .exe header, I'll just write what I did. ;) 

Step 1 was to just start. Surely I can make at least something if I write tight code?

Problem 1: Nothing to display. Either spam video chip output registers with some combination of timing and data that doesn't look like an accident or start a copper, because if you try to re-use the CLI screen or even less open graphics library, you've run out of space before the init code is written.

Problem 2: Starting a copper doesn't fit in 28 bytes. Well yes, if it's an empty one...

Solution: code-as-copper. Find some harmless instruction that could possibly work as a wait, skip, or move. $180 is easy, but then...? At the end will be a MOVE $88,x or WAIT FFFF,FFFE which is not valid. Prefixing them with some 3/4-word harmless code-as-copper instruction to make the CPU fall through the coppercode without accident is just wasting bytes, or you have to poke it after, which is double waste.

I did make an intro that falls through entirely, but it ended up at 66 bytes.

Best first instruction was dc.w $180;bra.s CopEnd which gives a some blue background.

Problem 3: Dread-relocs, mon.

Writing to the copper caused a reloc which boosted the intro size to WAY beyond 64b. No space to lea Start(PC),a5 (some PC-relative base register)

Solution: Testing and testing and dumping registers on my Amigas with kickswitches.

d0=paramstr length (always 1 for an empty paramstr)
a1=paramstr ptr (always contains the 0 byte of the ASCIIZ string.)
a3=ptr to start of exe-4. Contains a zero longword.
a7=program's user stack pointer, always even.

The others seem unreliable, especially d2,a5,a6.

OK, let's start! Surely, if I come up with an idea it could look like something?

Problem 4: No, it won't. Also, it still won't fit the "change something onscreen" instruction.

Solution: Imagine perverse tricks to save bytes.

More code-as-copper, always this failed to gain bytes. It either gave no useful copper instructions, or to make the useful you had to "poke" them afterwards, wasting bytes.

Failing tricks:
- lea $dff084,a7 ;custom base reg
- pea Cop-(start-4)(a3) ;
(this works as described in the manual but also dumps regs a7,d0-a6 below the pushed address, trashing 32 customregs and sending the Amiga out of sync with dark gray stripes, peeping.)

- Misc. reordering of copperlist to fit a series of move.? ??,(a3)+ to replace harmless-instructions-as-second-word-of-copper-instruction with waits or moves that work.

- Add.l $01000002 to waits to make them move, instead of separate addq.? with offsets. (Didn't save space)

Working tricks:
+ Start copper, then pre-extend copperlist: move.w $180,(a3)+ and keep a3 for the wonderful last instruction that flashes beautiful colors on the screen... OR move.w $8fdf,(a3)+ and keep a3 for the wonderful effect of making random waitsyncs that look like shit
+ Loop copper at end with a dc.w $88 (not dc.w $88,0 - instead of the zero you put a label to code, since COPJMP is a trigger reg and data can be anything). Saves 2 bytes, enough for an addq.w #?,(a3).
+ Put code or copper as ASCII in paramstr and execute it ;) (Not used, since it is cheating)

Non-Copper 64 byte intros then??

Yes, possible, I released two. Any timing is up to the CPU and forget about syncing to raster in any way. Don't think there are more possible intro-ideas, I stole all two of them, sorry...

So, what happened?

I started out making a lot of efforts to get a copper-starting intro down below 66 bytes. When it didn't go further I had to rethink and checked the registers. When I got one working (looked like shit) I made a "minidemowrapper" so I could replace the bra.s LOOP with a mouse exit and restore copper etc, so I could assemble and run many combo-tries to get something that looked less like shit. Instead of rebooting every time :)

For the very first tries I used WinUAE, which was a mistake. When there's no room for normal coding but only perverse crapinstructions, some bugs are revealed.

Toni said that Blerkenwiegel will work in a future version and that wait-1-cycle-execution-1-cycle-less-if-evaluation-true (Eye(Q)Lazer crosspattern) could also be fixed. But neither are simple fixes.

Amiga is probably one of the very worst platforms to write tiny demos on, since it has bloated 68000 instructions, big header, no buffer and requires about 50-70 bytes code (+header) to set up a working bitplane buffer with some raster sync of effects.

If you think about making 64b exes, don't do what I did. Go to 256b instead. I hated every moment and only kept at it because I refuse to be defeated (and was stupid enough to think that at least one of the about 100 versions would not be worthless).


Comment this post

  • Required fields are marked with *.
  • Comments may be moderated.

If you have trouble reading the code, click on the code itself to generate a new random code.
Security Code: