-
Notifications
You must be signed in to change notification settings - Fork 1
/
tasks.asm
205 lines (177 loc) · 2.89 KB
/
tasks.asm
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#include CONFIGFILE
#include "harness.def"
#define SEG(x) .assert *<x,"overrun":.dsb(x-*):.assert *=x,"oops"
#ifdef C64
; Commodore 64 version
; these are OK to use until we start the VM
zp0 = $fb
zp1 = $fd
.word $0801
* = $0801
; BASIC header "2010 SYS2061"
.byt $0b, $08, $da, $07, $9e, $32
.byt $30, $36, $31, $00, $00, $00
.assert *=2061,"header is wrong length"
; all keys repeat
lda #128
sta 650
#else
; Apple II version
; these are OK to use until we start the VM
zp0 = $fa
zp1 = $fc
; "CALL 2051"
* = $0803
#endif
; initialize both processor states
; start in CPU 0
cold lda #0
sta FLAG
sta pc
sta preg
sta cpu0p
sta cpu0pc
sta cpu1p
sta cpu1pc
lda #2
sta pc+1
sta cpu0pc+1
sta cpu1pc+1
lda #$ff
sta sptr
sta cpu0s
sta cpu1s
lup ; check if user has requested to switch tasks by pressing a key
; holding the key will switch back and forth
#ifdef C64
; this repeats because we changed 650
jsr $ffe4
cmp #0
bne swap
jmp run
#else
lda $c000
bmi :+
jmp run
: lda #0
sta 49168
#endif
; user requested swap, do the context switch
; these are simple-minded implementations but easy to follow
; they also don't depend on zero page locations being contiguous
swap lda FLAG
bne swap10
swap01 ; move task 0 off CPU, put task 1 on CPU
lda areg
ldx xreg
ldy yreg
sta cpu0a
stx cpu0x
sty cpu0y
lda preg
ldx sptr
ldy pc
sta cpu0p
stx cpu0s
sty cpu0pc
ldy pc+1
sty cpu0pc+1
lda cpu1a
ldx cpu1x
ldy cpu1y
sta areg
stx xreg
sty yreg
lda cpu1p
ldx cpu1s
ldy cpu1pc
sta preg
stx sptr
sty pc
ldy cpu1pc+1
sty pc+1
lda #1
sta FLAG
jmp run
swap10 ; move task 1 off CPU, put task 0 on CPU
lda areg
ldx xreg
ldy yreg
sta cpu1a
stx cpu1x
sty cpu1y
lda preg
ldx sptr
ldy pc
sta cpu1p
stx cpu1s
sty cpu1pc
ldy pc+1
sty cpu1pc+1
lda cpu0a
ldx cpu0x
ldy cpu0y
sta areg
stx xreg
sty yreg
lda cpu0p
ldx cpu0s
ldy cpu0pc
sta preg
stx sptr
sty pc
ldy cpu0pc+1
sty pc+1
lda #0
sta FLAG
run jsr VMU
; if we get a stack underflow, treat as clean termination status
cmp #R_STACKUNDER
bne chekok
dun rts ; propagates up
; otherwise we don't handle any return status other than OK
chekok cmp #R_OK
beq chekpc
; err out, wait for a rescue
bail sta $d020
inc $d020
jmp bail
; check for a call to $ffd2 and redirect to Kernal call
chekpc lda pc+1
cmp #>CHROUT
bne lupj
lda pc
cmp #<CHROUT
bne lupj
kffd2 lda areg
jsr CHROUT ; propagates up
jsr DORTS
cmp #R_STACKUNDER
beq dun
lupj jmp lup
; saved processor states
cpu0a .byt 0
cpu0x .byt 0
cpu0y .byt 0
cpu0p .byt 0
cpu0s .byt 0
cpu0pc .word 0
cpu1a .byt 0
cpu1x .byt 0
cpu1y .byt 0
cpu1p .byt 0
cpu1s .byt 0
cpu1pc .word 0
; images
SEG(HARNESS)
.bin 0,0,"harness.o"
SEG(VMSADDR)
.bin 0,0,"6o6.o"
; first task
; zero page and stack at EMURAM
SEG(EMURAM+$0200)
.bin 0,0,"payload1.o"
; second task
; zero page and stack at EMURAM+$0300
SEG(EMURAM+$0500)
.bin 0,0,"payload2.o"