Design Design

Found on:
"Halls of the Things, The"

Loader files:
ROM Header
Contains turbo loader code
ROM Data
Autostart and turbo loader code

Encoding:
Endianess:MSbF
Threshold:0x168, 0x24e
Lead-in:10 x 0x00
Sync:None

Data byte:8 data bits + 1 stop bit

Structure:
Header:Yes, 4 bytes
Checksum:Yes
Threshold:
The 0x168 threshold is used to distinguish between '0' and '1' bits.
The 0x24e threshold is used for the stop bit.

Header:
00-01 Load address (Low-High order)
02-03 Load end address (Low-High order) (Exclusive)

Checksum:
Sum of all data bytes. First byte after data is the checksum byte.
.pc = $033c

D033c:.byte$03,$a5,$02,$13,$03
.text "HALLS "
.byte $20


setup:sei
 lda$01
 and#$df
 sta$01
 lda#$7f
 sta$dc0d
 sta$dd0d
 lda#$a5// Set IRQ vector 0x02a5.
 sta$0314
 lda#$02
 sta$0315
 lda#0
 sta$be
 sta$d01a
 sta$a4
 sta$a3
 sta$dc05
 lda#$90
 sta$dc0d
 lda#$ff
 sta$dc07// Timer B = 0xFFFF
 sta$dc06
 lda#$0a
 sta$dc04// Timer A = 0x000a
 lda#$59
 sta$dc0f
 lda#$11
 sta$dc0e
 cli
 rts

// Autostart code jumps here
C0397:jsr$f817// Test cassette buttons and handle user messages
 jsrsetup
// Wait for 10 0x00 bytes in a row
C039d:ldx#$0a
C039f:jsr$02d1// Load byte
 sta$be
 bneC039d
 dex
 bneC039f

 jsr$02d1// Load byte, Load start address low
 sta$c1
 jsr$02d1// Load byte, Load start address high
 sta$c2
 jsr$02d1// Load byte, Load end address low
 sta$ae
 jsr$02d1// Load byte, Load end address high
 sta$af
C03bd:ldy#0
 jsr$02d1// Load byte
 sta($c1),y
 inc$c1
 bneC03ca
 inc$c2
C03ca:sec
 lda$ae
 sbc$c1
 lda$af
 sbc$c2
 bcsC03bd
 lda$be
 tay
 jsr$02d1// Load byte
 sta$be
 cpy$be
 beqC03ef
// Checksum failure, print error message and hang computer
 ldx#$0e
C03e3:lda$03f0,x
 jsr$ffd2
 dex
 bplC03e3
C03ec:jmpC03ec// Hang

C03ef:rts

// Reversed "N OFF ERROR\n".
// Routine starts from 0x3fe but that is outside loaded area
D03f0:.byte$0d,$d2,$cf,$d2,$d2,$c5,$20,$c6,$c6,$cf,$20,$ce
.pc = $02a5

// IRQ routine
C02a5:lda$dc0d
 lda$d020
 eor#$06
 sta$d020
 lda$dc06// Timer B low byte
 ldy#$59
 sty$dc0f// Timer B start, one-shot, cound Timer A countdowns
 ldy#$11
 sty$dc0e// Timer A start
 eor#$ff// Invert read Timer B low byte value = How many times Counter A has counted down from 0x0a
 cmp#$3b
 bcsC02ca// >= 0x3b*0x0a = 0x024e, end of byte marker
 cmp#$24
 rol$a4// >= 0x24*0x0a = 0x0168 => '1' bit, ROL = MSbF loader
 jmp$febc// Pull all registers and RTI

C02ca:lda#$ff// Flag byte as done
 sta$a3
 jmp$febc// Pull all registers and RTI

C02d1:lda$a3// Wait for byte to finish loading
 beqC02d1
 lda$a4// Fetch loaded byte
 pha
 clc
 adc$be// Add to checksum
 sta$be
 lda#0// Clear loaded byte and byte done flag
 sta$a3
 sta$a4
 pla
 rts

// Autostart address
C2e5:lda#$90// Color black
 jsr$ffd2
 lda#$93// Clear screen
 jsr$ffd2
 lda#$05// Color white
 jsr$ffd2
 lda#0
 sta$d020
 sta$d021
 jmpC0302

C02ff:nop

D0300:.word$02e5

C0302:lda#$12
 sta$d018
 jsr$0397// Code in cassette buffer, Load
 jsr$0397
 jsr$0397
 jmp($fffc)