Skip to content

Instantly share code, notes, and snippets.

@xk
Created July 16, 2019 13:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xk/1f455af5c9017150b8d6234743e9c2a3 to your computer and use it in GitHub Desktop.
Save xk/1f455af5c9017150b8d6234743e9c2a3 to your computer and use it in GitHub Desktop.
manchester decode 6502 asm
; Apple II TURBO CASSETTE LOADER
; 13569 bps @44100 sps
; 14769 bps @48000 sps
; Jorge Chamorro Bieling, SEPT 2017
; jorge@jorgechamorro.com
; Compile with: apple2.duckdns.org/assembler/
; Connect the PC to the Apple II cassette in port, set the volume at 50% or more.
; Transfer directly from the assembler page to the Apple II and then 820G
; Go to the demo page at: apple2.duckdns.org/turbodemo/
; Click on an image to xfer it
; On the Apple II the space bar resets the decoder an clears the HGR screen, ESC quits.
* = $820
buffer = $2000
spkr = $c030
cassette_out = $c020
cout = $fded
crout = $fd8e
hgr = $f3e2
bell = $ff3a
bits = 8
sync_min = 9
sync_max = 9
reset jsr bell
sta $c010
jsr skookum
entry jsr go
lda $c000
bmi key
bcs reset
jmp entry
key sta $c010
and #$7f
cmp #27 ;ESC is quit
bne key2 ;any other key is reset
sta $c053
sta $c051
rts
key2 cmp #83 ;S is send
bne key3
jsr send_hgr
jmp entry
key3 cmp #73 ;I es invertir
bne key4
sta cassette_out
jmp entry
key4 jmp reset
go jsr rst_bufr_base
jmp wait_sync
last_sample
.byte 0
decode ldx #0 ;x= buffer index
ldy #bits ;y= bit number
sec ;C means last edge was a clock
sample_lo lda $c060 ;4
bmi short_lo ;2..3
sl_1 lda $c060 ;4
bmi short_lo ;2..3
sl_2 lda $c060 ;4
bmi short_lo ;2..3
sl_3 lda $c060 ;4
bmi short_lo ;2..3
sl_4 lda $c060 ;4
bmi short_lo ;2..3
sl_5 lda $c060 ;4
bmi short_lo ;2..3
sl_6 lda $c060 ;4
bmi short_lo ;2..3
w_hi_clk lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_1 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_2 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_3 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_4 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_5 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_6 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_7 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_8 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_9 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_10 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_11 lda $c060 ;4
bmi clk_rising ;2..3
jmp eof_frame
short_lo bcc clk_rising
clc
jmp sh_1
clk_rising clc ;2 rising edge es un 0
.byte $3e ;7 rol buffer,x ;7
.byte <buffer
buffer_in_1
.byte >buffer
sec
dey
bne sh_2
inx
beq eof_frame
ldy #bits
jmp sh_3
short_hi bcc clk_falling ;2..3
clc ;2
jmp sl_1 ;3
clk_falling sec ;2 falling edge es un 1
.byte $3e ;7 rol buffer,x ;7
.byte <buffer
buffer_in_2
.byte >buffer
sec
dey ;2
bne sl_2 ;2..3
inx
beq eof_frame
ldy #bits
jmp sl_3 ;4
sample_hi lda $c060 ;4
bpl short_hi ;2..3
sh_1 lda $c060 ;4
bpl short_hi ;2..3
sh_2 lda $c060 ;4
bpl short_hi ;2..3
sh_3 lda $c060 ;4
bpl short_hi ;2..3
sh_4 lda $c060 ;4
bpl short_hi ;2..3
sh_5 lda $c060 ;4
bpl short_hi ;2..3
sh_6 lda $c060 ;4
bpl short_hi ;2..3
w_lo_clk lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_1 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_2 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_3 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_4 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_5 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_6 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_7 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_8 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_9 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_10 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_11 lda $c060 ;4
bpl clk_falling ;2..3
jmp eof_frame
eof_frame cpy #0
bne quit_err
cpx #0
bne quit_err
ok ldx buffer_in_1
inx
cpx #$40
beq quit_ok
stx buffer_in_1 ;self-modifying code FTW
stx buffer_in_2
jmp wait_sync
quit_err sec
rts
quit_ok clc
rts
;ALGORITMO DE SYNC:
;1.- buscar un falling edge
;2.- contar bucles hasta el próximo flanco
;3.- si son más de sync_max o menos de sync_min goto 1
;4.- si son entre sync_min y sync_max => ok, y si ocurren 2 seguidos => ok: Al final del segundo empiezan los datos.
;5.- si el último pulso da error probablemente la señal esté invertida.
;6.- los samples de los pulsos de sync serían LLLLLLLLHHHHHHHLL (8L7H2L)
wait_sync lda spkr
ldx #sync_min
lda $c060
sta last_sample
wait_edge lda $c000
bmi quit_err
no_key lda $c060
eor last_sample
bpl wait_edge
lda last_sample
bpl wait_sync ;buscamos falling edge
sync_1_1 dex
bmi sync_2 ;min length ok
lda $c060
bpl sync_1_1
bmi wait_sync ;too short
sync_2 ldx #sync_max
sync_2_1 dex
bmi wait_sync ;too long
lda $c060
bpl sync_2_1
bmi sync_3
;1st pulse (LO) ok
sync_3 ldx #sync_min
sync_3_1 dex
bmi sync_4 ;min length ok
lda $c060
bmi sync_3_1
bpl wait_sync ;too short
sync_4 ldx #sync_max
sync_4_1 dex
bmi wait_sync ;too long
lda $c060
bmi sync_4_1
jmp decode ;2nd pulse (HI) ok
rst_bufr_base
lda #>buffer
sta buffer_in_1
sta buffer_in_2
sta buffer_out
rts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment