Home
Admin | Edit

Archismall - Acorn Archimedes 64 bytes

link

A real time animated mode 13 320x256 256 colors 64 bytes for Acorn Archimedes shown at Lovebyte 2025.

It uses the integer circle algorithm (32 bit range with a downscale pass) and show some kind of drifting Apollonian net, it is pretty similar to my 2021 TIC-80 entry HyperSpace but not a direct port.

The idea of this intro came after my RISC OS 128 bytes, i took the challenge to do something interesting visually in 64 bytes on early ARM (no Thumb !), i chose to tinker with the integer circle algorithm once again since ARM is very effective at it... i had some interesting results but settled on a downsized HyperSpace approach as i like the visuals.

The main "challenge" was to reduce the screen / draw setup code (32 bytes) to the minimum (16 bytes) so i removed the code that retrieve the screen address and it was replaced by a fixed address (constant) with early Acorn Archimedes / RISC OS as a target (needs different binaries for different HW / RISC OS), the fixed address approach is tricky as it breaks compatibility with different RISC OS versions / hardware but it was a minor hindrance given the size...

The setup can go even more minimal (8 bytes ?) by getting rid of the screen mode switch code, disadvantage is that the program will use the actual screen mode and the screen will be left uncleared.

Additional work came in adjusting shifts for nice visuals and downsizing the algorithm so that it fit into ~11 ARM instructions !

The algorithm use a two instruction integer circle approach instead of the three instruction approach of HyperSpace, it looks a bit more distorted but the shift is dissimilar to compensate, the drawing index is computed differently as the X offset is embedded into the screen address and i use an unsigned shift for the downscale to minimize computation.

The first version was a straight port of the JS code and used a loop, it is unneeded on hardware (and slower), loop removal leave enough bytes for a clean exit !

It is fairly fast and works well on early Archimedes hardware, some shifts may likely needs to be adjusted between models to adjust the visuals though. (varying cycles; waiting VSYNC may also works)

The video was recorded on A3010, the program visuals is different each time it is run due to relying on OS timer.

p5js prototype code

function setup() {
  createCanvas(320, 256)
  background(0)
}

// can be left uninitialized on hardware
let x = 0
let y = 0

function draw() {
  let f = frameCount // use OS timer on hardware
  let c = pal[(f >>> 4) & 255] // pal is an array of 256 objects that looks like : { r: n, g: n, b: n }

  loadPixels()
  for (let l = 0; l < 32768; l += 1) {
    x += y >> 1
    y -= x >> 1
    x -= f << 19

    let index = (32 + (x >>> 24) + (y >>> 24) * width) * 4

    pixels[index + 0] = c.r
    pixels[index + 1] = c.g
    pixels[index + 2] = c.b
  }
  updatePixels()
}

ARM code

swi OS_WriteI+22
swi OS_WriteI+13 ; mode 13

ldr r9,[r15,#44] ; screen address

mov r4,#320
.l
  swi "OS_ReadMonotonicTime"
  add r2,r2,r3,ASR #1
  sub r3,r3,r2,ASR #1
  sub r2,r2,r0,LSL #19
 
  mov r6,r3,LSR #24
  mla r7,r6,r4,r9
 
  mov r6,r0,LSR #4
  strb r6,[r7,r2,LSR #24]
 
  swi "OS_ReadEscapeState"
bcc l
swi "OS_Exit"

.screenAddr
;dcd &1fe8000+&20 ; >= 4MB RAM (RO 3.11)
;dcd &1fd8000+&20 ; A5000a 4MB (RO 3.11)
dcd &1fec000+&20 ; >= 512KB RAM (RO 3.11)

back to topLicence Creative Commons