forked from EtchedPixels/FUZIX
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmsx2.s
386 lines (340 loc) · 7.81 KB
/
msx2.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
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
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
;
; MSX2 hardware support
;
.module msx2
; exported symbols
.globl init_early
.globl init_hardware
.globl interrupt_handler
.globl plt_interrupt_all
.globl _program_vectors
.globl map_kernel
.globl map_kernel_restore
.globl map_process
.globl _map_kernel
.globl map_process_always
.globl map_kernel_di
.globl map_process_di
.globl map_process_always_di
.globl map_save_kernel
.globl map_restore
.globl enaslt
.globl _mapslot_bank1
.globl _mapslot_bank2
.globl _need_resched
.globl _bufpool
.globl _int_disabled
.globl _udata
; video driver
.globl _vtinit
; exported debugging tools
.globl _plt_monitor
.globl outchar
.globl _tty_inproc
.globl unix_syscall_entry
.globl _plt_reboot
.globl nmi_handler
.globl null_handler
; debug symbols
.globl outcharhex
.globl outhl, outde, outbc
.globl outnewline
.globl outstring
.globl outstringhex
.globl _slotrom
.globl _slotram
.globl _vdpport
.globl _infobits
.globl _machine_type
;
; vdp - we must initialize this bit early for the vt
;
.globl _vdpinit
.include "kernel.def"
.include "../kernel-z80.def"
.area _BUFFERS
_bufpool:
.ds BUFSIZE * NBUFS
; -----------------------------------------------------------------------------
; COMMON MEMORY BANK (0xF000 upwards)
; -----------------------------------------------------------------------------
.area _COMMONMEM
; Ideally return to any debugger/monitor
_plt_monitor:
di
halt
_plt_reboot:
;FIXME: TODO
di
halt
_need_resched:
.db 0
_int_disabled:
.db 1
; -----------------------------------------------------------------------------
; KERNEL MEMORY BANK (below 0xF000, only accessible when the kernel is mapped)
; -----------------------------------------------------------------------------
.area _CODE
init_early:
ret
init_hardware:
; set up interrupt vectors for the kernel mapped low page and
; data area
ld hl, #0
push hl
call _program_vectors
pop hl
ld a, #'Z'
out (0x2F), a
call _vdpinit
ld a, #'I'
out (0x2F), a
im 1 ; set CPU interrupt mode
call _vtinit ; init the console video
ld a, #'X'
out (0x2F), a
ret
;------------------------------------------------------------------------------
; COMMON MEMORY PROCEDURES FOLLOW
.area _COMMONMEM
plt_interrupt_all:
ld bc,(_vdpport)
in a, (c)
ret
_program_vectors:
; we are called, with interrupts disabled, by both newproc() and crt0
; will exit with interrupts off
di ; just to be sure
pop de ; temporarily store return address
pop hl ; function argument -- base page number
push hl ; put stack back as it was
push de
; At this point the common block has already been copied
call map_process
; write zeroes across all vectors
; on MSX this is probably the wrong thing to do!!! FIXME
ld hl, #0
ld de, #1
ld bc, #0x007f ; program first 0x80 bytes only
ld (hl), #0x00
ldir
; now install the interrupt vector at 0x0038
ld a, #0xC3 ; JP instruction
ld (0x0038), a
ld hl, #interrupt_handler
ld (0x0039), hl
; set restart vector for Fuzix system calls
ld (0x0030), a ; (rst 30h is unix function call vector)
ld hl, #unix_syscall_entry
ld (0x0031), hl
ld (0x0000), a
ld hl, #null_handler ; to Our Trap Handler
ld (0x0001), hl
ld (0x0066), a ; Set vector for NMI
ld hl, #nmi_handler
ld (0x0067), hl
jr map_kernel
;
; All registers preserved
;
map_process_always:
map_process_always_di:
push hl
ld hl, #_udata + U_DATA__U_PAGE
call map_process_2
pop hl
ret
;
; HL is the page table to use, A is eaten, HL is eaten
;
map_process:
map_process_di:
ld a, h
or l
jr nz, map_process_2
;
; Map in the kernel below the current common, go via the helper
; so our cached copy is correct.
;
_map_kernel:
map_kernel_restore:
map_kernel_di:
map_kernel:
push hl
ld hl, #map_kernel_data
call map_process_2
pop hl
ret
map_process_2:
push de
push bc
push af
ld de, #map_table ; Write only so cache in RAM
ld (de), a
ld bc, #4
ldir
dec hl
dec hl
dec hl
dec hl
ld c, #0xFC
ld b, #4
outi
inc c
outi
inc c
outi
pop af
pop bc
pop de
ret
;
; Restore a saved mapping. We are guaranteed that we won't switch
; common copy between save and restore. Preserve all registers
;
map_restore:
push hl
ld hl,#map_savearea
call map_process_2 ; Put the mapper back right
pop hl
ret
;
; Save the current mapping.
;
map_save_kernel:
push hl
ld hl, (map_table)
ld (map_savearea), hl
ld hl, (map_table + 2)
ld (map_savearea + 2), hl
ld hl, #map_kernel_data
call map_process_2
pop hl
ret
;
; Slot mapping functions.
;
; necessary to access memory mapped io ports used by certain devices
; (e.g ide, sd devices)
;
; These need to go in bank0; cannot be in the common area because
; they do switch bank3 to access the subslot register. And neither
; can be in bank1 or 2 because those are the ones usually used to
; map the io ports.
;
.area _CODE
_mapslot_bank1:
ld hl,#0x4000
jr enaslt
_mapslot_bank2:
ld hl,#0x8000
enaslt:
call setprm ; calculate bit pattern and mask code
jp m, mapsec ; if expanded set secondary first
in a,(0xa8)
and c
or b
out (0xa8),a ; set primary slot
ret
mapsec:
push hl
; here need to store the slot that is being set....
call setexp ; set secondary slot
pop hl
jr enaslt
; calculate bit pattern and mask
setprm:
di
push af
ld a,h
rlca
rlca
and #3
ld e,a ; bank number
ld a,#0xC0
setprm1:
rlca
rlca
dec e
jp p, setprm1
ld e,a ; mask pattern
cpl
ld c,a ; inverted mask pattern
pop af
push af
and #3 ; extract xxxxxxPP
inc a
ld b,a
ld a,#0xAB
setprm2:
add a,#0x55
djnz setprm2
ld d,a ; primary slot bit pattern
and e
ld b,a
pop af
and a ; if expanded slot set sign flag
ret
; set secondary slot
setexp:
push af
ld a,d
and #0xC0 ; get slot number for bank 3
ld c,a
pop af
push af
ld d,a
in a,(0xa8)
ld b,a
and #0x3F
or c
out (0xa8),a ; set bank 3 to target slot
ld a,d
rrca
rrca
and #3
ld d,a
ld a,#0xAB ; secondary slot to bit pattern
setexp1:
add a,#0x55
dec d
jp p,setexp1
and e
ld d,a
ld a,e
cpl
ld h,a
ld a,(0xffff) ; read and update secondary slot register
cpl
ld l,a
and h ; strip off old bits
or d ; add new bits
ld (0xffff),a
ld a,b
out (0xa8),a ; restore status
pop af
and #3
ret
.area _COMMONMEM
map_table:
.db 0,0,0,0
map_savearea:
.db 0,0,0,0
map_kernel_data:
.db 3,2,1,4
_slotrom:
.db 0
_slotram:
.db 0
_vdpport:
.dw 0
_infobits:
.dw 0
_machine_type:
.db 0
; emulator debug port for now
outchar:
push af
out (0x2F), a
pop af
ret