forked from dwsJason/f256_pexec
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmmu.s
More file actions
275 lines (240 loc) · 4.19 KB
/
Copy pathmmu.s
File metadata and controls
275 lines (240 loc) · 4.19 KB
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
;
; mmu helper module
;
; Don't try to use $E000, or $0000
; for either of these block ranges
; if you want to use $C000, you'll have
; to make sure to set the mmu up for this yourself
READ_BLOCK = $8000
WRITE_BLOCK = $6000
READ_MMU = mmu+READ_BLOCK/8192
WRITE_MMU = mmu+WRITE_BLOCK/8192
; Zero Page defines
mmu_ctrl = 0
io_ctrl = 1
; reserved addresses 2-7 for future expansion, use at your own peril
mmu = 8
mmu0 = 8
mmu1 = 9
mmu2 = 10
mmu3 = 11
mmu4 = 12
mmu5 = 13
mmu6 = 14
mmu7 = 15
; System Bus Pointer's
pSource = $10
pDest = pSource+2
old_mmu_ctrl = pDest+2
old_io_ctrl = old_mmu_ctrl+1
old_mmu0 = old_io_ctrl+1
;
; Take the current mmu config, and allow write access
;
mmu_unlock
lda mmu_ctrl
sta old_mmu_ctrl
lda io_ctrl
sta old_io_ctrl
lda mmu_ctrl
and #$3
sta temp0 ; active MLUT
asl
asl
asl
asl
ora temp0 ; active MLUT, copied to the EDIT LUT
ora #$80 ; Enable MMU edit - we are editing the active (spooky)
sta mmu_ctrl
ldx #7
_save lda mmu0,x
sta old_mmu0,x
dex
bpl _save
rts
;
; Restore mmu to it's previous state (prior to calling unlock)
;
mmu_lock
ldx #7
_fix lda old_mmu0,x
sta mmu0,x
dex
bpl _fix
lda old_io_ctrl
sta io_ctrl
lda old_mmu_ctrl
sta mmu_ctrl
rts
mmu_lock_end
; Set system bus address for reading
;
; A = LOW
; X = MED
; Y = HIGH
;
set_read_address
sta pSource ; System Bus Address
;stx pSource+1
sty READ_MMU
; Convert BUS Address, into an 8k block number
;lda pSource+1
txa
asl
rol READ_MMU
asl
rol READ_MMU
asl
rol READ_MMU ; READ_MMU contains the 8k block #
;lda pSource+1 ; Adjust pSource, so it's pointing to CPU mapped
txa
and #$1F ; memory
ora #>READ_BLOCK
sta pSource+1
rts
;------------------------------------------------------------------------------
; Return the current system bus reading address
; A = LOW
; X = MED
; Y = HIGH
;
get_read_address
stz temp0 ; convert from block+offset, to master bus address
lda READ_MMU
lsr
ror temp0
lsr
ror temp0
lsr
ror temp0
tay
lda pSource+1
and #$1F
ora temp0
tax
lda pSource
rts
;------------------------------------------------------------------------------
; Return the current system bus writing address
; A = LOW
; X = MED
; Y = HIGH
;
get_write_address
stz temp0 ; convert from block+offset, to master bus address
lda WRITE_MMU
lsr
ror temp0
lsr
ror temp0
lsr
ror temp0
tay
lda pDest+1
and #$1F
ora temp0
tax
lda pDest
rts
; Set system bus address for writing
;
; A = LOW
; X = MED
; Y = HIGH
;
set_write_address
sta pDest ; System Bus Address
;stx pDest+1
sty WRITE_MMU
; Convert BUS Address, into an 8k block number
;lda pDest+1
txa
asl
rol WRITE_MMU
asl
rol WRITE_MMU
asl
rol WRITE_MMU
;lda pDest+1 ; Adjust pDest, so it's pointing to CPU mapped memory
txa
and #$1F
ora #>WRITE_BLOCK
sta pDest+1
rts
;
; Read byte at the current read address
; and auto-increment
;
; only changes A
;
readbyte
lda (pSource)
inc pSource
bne _done
phx
ldx pSource+1
inx
cpx #>(READ_BLOCK+$2000)
bcc _no_wrap
inc READ_MMU ; next mmu 8k block
ldx #>READ_BLOCK ; next read needs to wrap to next block
_no_wrap
stx pSource+1
plx
_done
rts
;
; Write byte at the current write address
; and auto-increment
;
writebyte
sta (pDest)
inc pDest
bne _done
phx
ldx pDest+1
inx
cpx #>(WRITE_BLOCK+$2000)
bcc _no_wrap
inc WRITE_MMU ; next mmu 8k block
ldx #>WRITE_BLOCK ; next write needs to wrap to next block
_no_wrap
stx pDest+1
plx
_done
rts
;
; Determine how many bytes it's possible to write into the write window, max 128
;
bytes_can_write
lda pDest+1
cmp #>(WRITE_BLOCK+$1F00)
bne _use_128
lda pDest
bpl _use_128 ; A (pointer) is less than 128, there's room for yet another 128 bytes
; Subtract A from 256, in 8 bit two's complement this is the same as negate
eor #$FF
clc
adc #1
rts
_use_128
lda #128
rts
;
; Increment pDest by A
;
increment_dest
clc
adc pDest
sta pDest
bcc _done
lda pDest+1
inc a
cmp #>(WRITE_BLOCK+$2000)
bne _no_wrap
inc WRITE_MMU
lda #>WRITE_BLOCK
_no_wrap
sta pDest+1
_done
rts