Imagine v1

Found on:
"Ah Diddums"
"Cosmic Cruiser"

Loader files:
ROM Header
Contains no filename, loader code uses that space.
ROM Data
Area loads to $0300-0334 and forces an autostart to $0341

Encoding:
Endianess:LSbF
Threshold:~$161-$179
Lead-in:1 bit / 2 pulses
Sync:None

Structure:
Header:None
Checksum:None
Header:
No header means that start and end addresses are hardcoded into the loader.

$036a    lda #$ff    Start low byte. Offset 0x2f
$036c    sta $ac
$036e    lda #$0f    Start high byte. Offset 0x33
$036a    sta $ad

$03f3/$03f0    cmp #$d0    End high address. Offset 0xb8 or 0xb7

End low address will always be zero. The end address is exclusive. Start address above is actual program address -1, the first address is just to store the pilot bit as part of loader initialization.

Encoding:
Loader uses two pulses per bit.
The total duration of first plus the second pulse is always the the same.
Timer B is used to measure the duration of both pulses and Timer A measures duration of second pulse. A bit is decoded based on the duration of the second pulse.

Pulse 1 (Even):
Timer B's current value is stored in memory, $0400 is added to the value and is then divided by 2.
Timer A and B is then initialized to $400 and started.
Pulse 2 (Odd):
Timer A's value is fetched and the stored Timer B value subtracted from it.
If A<B a 1 bit is ROR:ed into the current byte value.

So the threshold is based on the actual duration of both pulses and could potentially be changed any time during load and differ between releases.

Statistics:
Ah Diddums

EvenOddBit
473 µs ($3a)298 µs ($24)0
268 µs ($21498 µs ($3d)1

Even+Odd average=769 µs
 
Cosmic Cruiser

EvenOddBit
494 µs ($3d)305 µs ($26)0
271 µs ($21)524 µs ($41)1

Even+Odd average=798 µs
.label loadingDone =   $93
.label bitCount    =   $9c
.label SCROLY      = $d011
.label EXTCOL      = $d020
.label TIMALO      = $dc04
.label TIMAHI      = $dc05
.label TIMBLO      = $dc06
.label TIMBHI      = $dc07
.label CIAICR      = $dc0d
.label CIACRA      = $dc0e
.label CIACRB      = $dc0f
.label CI2ICR      = $dd0d

.pc=$033c

.byte $03,$00,$03,$33,$03

// Autostart code jumps here
START:lda$01
 and#$1f
 sta$01
 // Delay Loop
 ldx#$ff
d2:ldy#$ff
d1:dey
 bned1
 dex
 bned2

 sei
 // Clear all timer interrupts and service any pending
 lda#$7f
 staCI2ICR
 staCIAICR
 ldaCIAICR
 ldaCI2ICR
 // New IRQ vector $039d
 lda#$9d
 sta$0314
 lda#$03
 sta$0315

 // Set load address $0fff
 lda#$ff
 sta$ac
 lda#$0f
 sta$ad
 // Crude screen blank
 ldaSCROLY
 and#$08
 staSCROLY
 lda#$90
 staCIAICR// Timer A: Enable FLAG interrupt
 ldx#$01
 stxbitCount
 sty$fe// Y is zero from delay loop
 styTIMALO// Timer A Low
 styTIMBLO// Timer B Low
 styloadingDone// Reset loading done flag
 lda#$04
 staTIMAHI// Timer A High
 staTIMBHI// Timer B High
 cli// Enable IRQ

 // Wait for loading to finish
waitLoad:ldaloadingDone
 beqwaitLoad
 jmp$8800// Game start address

 #####
 # IRQ
 #####
IRQ:ldaCIAICR// Service CIAICR, ignoring result
 ldy#0
 //Invert $fe, will cause different behaviour for even and odd pulses
 lda$fe
 eor#$ff
 sta$fe
 bploddPulse
 // Even pulses
 styCIACRB// Stops Timer B, sets it to count CPU cycles
 ldaTIMBLO// Fetch Timer B Low
 sta$fc
 ldaTIMBHI// Fetch Timer B High
 sta$fb
 lda#$19
 staCIACRA// Timer A: Load latched value,one-shot mode, start
 staCIACRB// Timer B: Load latched value,one-shot mode, start
 clc
 // Add $400 to fetched Timer B value and divide it by 2
 lda#$04
 adc$fb
 lsr
 sta$fb
 ror$fc
 incEXTCOL// Border color flash
 jmp$febc// Pulls Y,X,A from stacks and RTI

 // Odd pulses
oddPulse:styCIACRA// Timer A: Load latched value,one-shot mode, start
 sec
 // Fetch Timer A value and Subtract the stored Timer B / 2 value
 ldaTIMALO
 sbc$fc
 ldaTIMAHI
 sbc$fb
 // Bit = 1 if Timer B/2 > Timer A
 ror$fd
 decbitCount
 bnecontLoad// Check if byte finished
 ldx#$08
 stxbitCount// Reset bitcount
 lda$fd
 sta($ac),y
 // Increase load address
 inc$ac
 bneC_03f1
 inc$ad
C_03f1:lda$ad
 cmp#$d0// Check for end address $d000 (exclusive)
 bcccontLoad
 incloadingDone// Mark loading as finished
contLoad:jmp$febc// Pulls Y,X,A from stacks and RTI