Bun Runner Devlog -- 2025-01-10

January 10, 2025

Not much in the way of visuals to show this week. My focus has been to flesh out more of the unit test suite, allowing me to fix a few bugs in the process as well as perform some nice optimizations on some oft-called code.

I also discovered a good, extensible approach to building switch statements in assember without using a big list of CMP/BEQ statements, which requires writing lots of code and is also costly execution-wise. Any code I’ve run into that uses the CMP/BEQ approach I’ve been converting to this new approach, which is another reason for no real visuals this week.

The approach comes from a post on English Amiga Board: https://eab.abime.net/showpost.php?p=1548231&postcount=7

The example in the post is specific to the original asker’s use case, so I’ll provide a more generic example for DevPac, along with a unit test written in CuTest for SAS/C:

; switch.asm

  ENUM ; MyChoices
  EITEM ItemOne
  EITEM ItemTwo
  EITEM ItemThree

  ; make accessible to C
  XDEF _MySwitch

; @inreg D0 enum MyChoices
; @outreg D0 final value
_MySwitch:
  ADD.W D0,D0                   ; jumpTable entries are word sized
  MOVE.W .jumpTable(pc,D0.W),D0 ; get the offset from .jumpTargets
  JMP .jumpTargets(pc,D0.W)     ; go!

.jumpTable:
  ; these are in enum order
  DC.W .itemOne-.jumpTargets
  DC.W .itemTwo-.jumpTargets
  DC.W .itemThree-.jumpTargets

.jumpTargets:
.itemOne:
  MOVE.L #4,D0
  RTS

.itemTwo:
  MOVE.L #20,D0
  RTS

.itemThree:
  MOVE.L #50,D0
  RTS
// switch_test.c
#include "cutest.h"

enum MyChoices {
  ItemOne,
  ItemTwo,
  ItemThree
};

// this looks for an exported _MySwitch symbol
uint32_t __asm MySwitch(register __d0 uint32_t myChoice);

void T_switch(CuTest *tc) {
  uinit32_t result;

  result = MySwitch(ItemOne);
  CuAssertIntEquals(tc, 4, result);

  result = MySwitch(ItemTwo);
  CuAssertIntEquals(tc, 20, result);

  result = MySwitch(ItemThree);
  CuAssertIntEquals(tc, 50, result);
}

void switchSuite(CuSuite *suite) {
  SUITE_ADD_TEST(suite, T_switch);
}