c64-livecoding/host/loader.s

150 lines
2.6 KiB
ArmAsm

;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
;; This program reads a data stream from the joystick port and saves it in memory.
;; The datastream format is as sutch:
;;
;; ############################################
;; 16-bit byte-length (big endian) | data
;; ############################################
;; The data comes from CTRL1 bit 0 and the clock is at bit 1
;; The stream starts when the clock is pulled high, after that comes a
;; 16-bit big endian number that matches the byte-lenght of the data that will get sent.
;; When the hole stream has ended the clock is pulled low until the next stream!
;; The data is then stored in ram with the first byte in progdest and the last in progdest + byte-length
;; At the end the program run the code stored at progdest with a jmp!
;; More documentation on the Joystick port can be found here: https://www.c64-wiki.com/wiki/Joystick
progdest = $fe
CLKMASK = %00000010
CTRL1 = $DC01
setup_loader:
;; Bank out character ROM, I/O in
lda #%00000100
ora $01
sta $01
lda #$00
sta progdest
lda #$c0
sta progdest+1
rts
maybe_download_userprog:
;; Bank out character ROM, I/O in
lda #%00000100
ora $01
sta $01
lda #CLKMASK
bit CTRL1
bne download_userprog
lda #$00
rts
download_userprog:
.scope userprog_downloader
sei
lda #$00
sta progdest
lda #$c0
sta progdest+1
;; change border color for debugging purposes
ldx #$02 ; X needed for more than that debug color
stx $d020
ldy #$00
jmp new_byte
wait_for_bit_start:
lda #CLKMASK
@loop:
bit CTRL1
beq @loop
lda #$06
sta $d020
lda #CLKMASK
bit CTRL1
beq error
lda CTRL1
lsr
ror BYTE
bcc wait_for_bit_end
txa ; get the zero flag from X
beq @normal
dex
lda BYTE
sta LEN,x
txa
bne @notdone
;; Computing stop address
clc
lda LEN
adc z:progdest
sta stop
lda LEN+1
adc z:progdest+1
sta stop+1
jmp @notdone
@normal:
;; Byte finished, storing
lda BYTE
sta (progdest), y
inc z:progdest
bne @noinchi
inc z:progdest+1
@noinchi:
;; Comparing progdest against stop address
lda z:progdest
cmp stop
bne @notdone
lda z:progdest+1
cmp stop+1
bne @notdone
jmp done
@notdone:
new_byte:
;; BYTE is the byte being read from the stream. The bits are shifted from the left
;; When we shift out this 1 in BYTE below we save the BYTE to memory.
lda #%10000000
sta BYTE
wait_for_bit_end:
lda #CLKMASK
@loop:
bit CTRL1
bne @loop
;; Debug show the clock is low
lda #$02
sta $d020
jmp wait_for_bit_start
done:
lda #$01
cli
clc
rts
error:
;; TODO
cli
sec
jmp $c000
rts
BYTE = $400
LEN = $402
stop: .word $0000
loaded: .byte 0
.endscope