-
Notifications
You must be signed in to change notification settings - Fork 1
/
load8000.s
114 lines (98 loc) · 3.89 KB
/
load8000.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
cout := $FDED ; character out sub
prbyte := $FDDA ; print byte in hex
tapein := $C060 ; read tape interface
.if DIRECT
* = $280
entry = $2A0
endaddr = $300
; zero page parameters
begload = $FA ; begin load location LSB/MSB
endload0 = $FC ; end load location LSB/MSB
mon_entry:
lda begload ; load begin LSB location
sta store+1 ; store it for automodified location
sta sumloop+1 ; store it for automodified location
lda begload+1 ; load begin MSB location
sta store+2 ; store it for automodified location
sta sumloop+2 ; store it for automodified location
lda endload0
sta endload
lda endload0+1
sta endload+1
jmp inline_entry
.fill entry - *,0
.else
lda begload ; load begin LSB location
sta store+1 ; store it for automodified location
sta sumloop+1 ; store it for automodified location
lda begload+1 ; load begin MSB location
sta store+2 ; store it for automodified location
sta sumloop+2 ; store it for automodified location
.fi
.include "apple_enc.inc"
.enc "apple"
inline_entry:
ldx #0 ; X is used in ROL instr at store:
nsync:
bit tapein ; wait for high level
bpl nsync
next_byte:
lda #1 ; A = bit counter
next_bit:
ldy #0 ; Y = #cycles at low level after high
psync:
bit tapein ; wait loop for low level
bmi psync
ploop:
iny ; 2 cycles
bit tapein ; 4 cycles
bpl ploop ; high level found, Y gets #cycles at low level
; 2 +1 if branch, +1 if in another page
; total ~9 cycles
cpy #64 ; 2 cycles if Y >= 64 (<= 770Hz) = ending detect
bge endcode ; 2(3)
cpy #20 ; 2 cycles if Y >= 20 (<= 2000Hz) ignore and next bit
bge next_bit ; 2(3)
; between 7 and 20 (2000-6000 Hz) -> 1
; between 0 and 7 (6000-12000 Hz) -> 0
cpy #7 ; 2, if Y<, then clear carry, if Y>= set carry
; in next line, C will enter in current address
store: ; warning: automodified code in store+1/store+2
rol $FFFF,x ; 7, roll carry bit 1/0 into store
asl ; 2 at bit 7, A = 0
bne next_bit ; 2(3)
inx ; 2 cycles
bne next_byte ; 2(3)
inc store+2 ; 6 cycles
jmp next_byte ; 3 cycles
; 37/42 subtotal max
endcode:
lda #$ff ; init checksum
sumloop: ; warning: automodified code in sumloop+1/sumloop+2
eor $FFFF
tax ; saves checksum in X
inc sumloop+1 ; incr LSB
bne nexteor
inc sumloop+2 ; incr MSB
nexteor:
lda endload ; 16 bits compare
cmp sumloop+1 ;
lda endload+1
sbc sumloop+2
txa ; restore checksum
bge sumloop ; while (endload) >= (sumloop+1)
beq exit ; checksum OK, exit
error:
lda #'K'
jsr cout
lda #'O'
jsr cout
exit:
rts
.if DIRECT
endload .word 0 ; end load location LSB/MSB
.fill endaddr - *,0
.else
begload .word 0
endload .word 0
.fi