]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/blame - cbios/mm.180
stack
[z180-stamp-cpm3.git] / cbios / mm.180
CommitLineData
2a7e38b4
L
1 page 255\r
2 .z80\r
3\r
4\r
5 public mmuinit\r
6 public bnk2log,bnk2phy,hwl2phy,phy2log\r
7 public isv_sw\r
8 public b_ld_a,b_ld_hl,b_st_a,b_st_hl\r
9\r
10\r
11 extrn @cbnk\r
12 extrn ijphl\r
13\r
14\r
15 maclib z180reg.inc\r
16 maclib config.inc\r
17\r
18\r
19;----------------------------------------------------------------------\r
20; Memory Map 1:\r
21;\r
22; Common CAStart .. 0FFFF\r
23; Bank 0 00000 .. CAStart-1\r
24; Bank 1 10000 ..\r
25; Bank 2\r
26;\r
27; Memory Map 2:\r
28;\r
29; Common 18000 .. 1BFFF BANK1\r
30;\r
31; Bank 0 00000 .. 0BFFF 0\r
32; Bank 1 0C000 .. 17FFF 1*BNK_SIZE\r
33; Bank 2 1C000 .. 27FFF 2*BNK_SIZE + CMN_SIZE\r
34; Bank 3 28000 .. 33FFF 3*BNK_SIZE + CMN_SIZE\r
35; Bank n n*BNK_SIZE + (n < 2) ? 0 : CMN_SIZE\r
36;\r
37;----------------------------------------------------------------------\r
38\r
39 cseg\r
40\r
41mmuinit:\r
42 ld a,USR$CBAR\r
43 out0 (cbar),a\r
44 ret\r
45\r
46;--------------------------------------------------------------------\r
47; Return the BBR value for the given bank number\r
48;\r
49; in a: Bank number\r
50; out a: bbr value\r
51\r
52 if 0 ; Memory Map 1\r
53\r
54bnk2log:\r
55 or a ;\r
56 ret z ; Bank 0 is at physical address 0\r
57\r
58 dec a ;\r
59 push bc ;\r
60 ld c,a ;\r
61 ld b,BNK_SIZE ;\r
62 mlt bc ; bank size * bank number\r
63 ld a,c ;\r
64 add a,10h ; add bank0 + common\r
65 pop bc ;\r
66 ret ;\r
67\r
68 else ; Memory Map 2\r
69\r
70bnk2log:\r
71 or a\r
72 ret z ; Bank 0 is at physical address 0\r
73\r
74 push bc\r
75 ld c,a ;\r
76 ld b,BNK_SIZE ;\r
77 mlt bc ; bank size * bank number\r
78 cp 2 ;\r
79 ld a,c ;\r
80 pop bc\r
81 ret c\r
82 add a,CMN_SIZE\r
83 ret\r
84\r
85 endif\r
86\r
87 if 0 ; table version\r
88\r
89 push hl\r
90 ld hl,bnk_table ;\r
91 add a,l ;\r
92 ld l,a ;\r
93 jr nc,$+3 ;\r
94 inc h ;\r
95 ld a,(hl) ;\r
96 pop hl\r
97 ret\r
98\r
99 endif\r
100\r
101;--------------------------------------------------------------\r
102\r
103;in hl: Log. Address\r
104; a: Bank number\r
105;\r
106;out ahl: Phys. (linear) Address\r
107\r
108\r
109bnk2phy:\r
110 push bc\r
111 ld c,a\r
112 ld a,h\r
113 and a,0f0h\r
114 cp CA*16\r
115 ld a,c\r
116 pop bc\r
117 jr c,b2p_banked\r
118 ; address is in common\r
119 if 0 ; Memory Map 1\r
120 ld a,0 ; base is 0\r
121 else ; Memory Map 2\r
122 ld a,1 ; same as bank1\r
123 endif\r
124\r
125b2p_banked:\r
126 call bnk2log ; get address base\r
127\r
128 ; fall thru\r
129\r
130;--------------------------------------------------------------\r
131;\r
132; hl: Log. Address\r
133; a: Bank base (bbr)\r
134;\r
135; 2 0 0\r
136; 0 6 8 0\r
137; hl hhhhhhhhllllllll\r
138; a + bbbbbbbb\r
139;\r
140; OP: ahl = (a<<12) + (h<<8) + l\r
141;\r
142;out ahl: Phys. (linear) Address\r
143\r
144log2phy:\r
145 push bc ;\r
146l2p_i:\r
147 ld c,a ;\r
148 ld b,16 ;\r
149 mlt bc ; bc = a<<4\r
150 ld a,c ;\r
151 add a,h ;\r
152 ld h,a ;\r
153 ld a,b ;\r
154 adc a,0 ;\r
155 pop bc ;\r
156 ret ;\r
157\r
158;--------------------------------------------------------------\r
159;\r
160; hl: Log. Address\r
161;\r
162;\r
163; OP: ahl = (bankbase<<12) + (h<<8) + l\r
164;\r
165;out ahl: Phys. (linear) Address\r
166\r
167\r
168hwl2phy:\r
169 push bc ;\r
170 in0 c,(cbar) ;\r
171 ld a,h ;\r
172 or 00fh ; log. addr in common1?\r
173 cp c\r
174 jr c,hlp_1\r
175\r
176 in0 a,(cbr) ; yes, cbr is address base\r
177 jr hl2p_x\r
178hlp_1:\r
179 ld b,16 ; log. address in baked area?\r
180 mlt bc\r
181 ld a,h\r
182 cp c\r
183 jr c,hlp_2\r
184 in0 a,(bbr) ; yes, bbr is address base\r
185 jr hl2p_x\r
186hlp_2:\r
187 xor a ; common1\r
188hl2p_x:\r
189 jr nz,l2p_i\r
190\r
191 pop bc ; bank part is 0, no translation\r
192 ret ;\r
193\r
194\r
195;--------------------------------------------------------------\r
196; return logical bank 0 address for given physical address.\r
197;\r
198; in: ahl: pyhsical addres (20 bit)\r
199; out hl: logical address.\r
200; logical address is in bank 0 or common, no bank number returned\r
201;\r
202\r
203phy2log:\r
204 or a\r
205 ret z\r
206\r
207 push bc\r
208 push hl\r
209 ld l,h\r
210 ld h,0\r
211 ld bc,-16*SYS$CBR\r
212 add hl,bc\r
213 ld h,l\r
214 pop bc\r
215 ld l,c\r
216 pop bc\r
217 ret\r
218\r
219;--------------------------------------------------------------\r
220; Trampoline for routines in banked ram.\r
221; Switch stack pointer to "system" stack in top ram\r
222; Save cbar\r
223;\r
224 extrn bs$stack\r
225\r
226 cseg ; common!\r
227\r
228 public _b0call\r
229\r
230 if 0\r
231\r
232_b0call:\r
233 push af\r
234 in0 a,(bbr)\r
235 jr nz,b0c_doit\r
236 pop af\r
237\r
238 ex (sp),hl ;16\r
239 push de\r
240 ld e,(hl)\r
241 inc hl\r
242 ld d,(hl)\r
243 inc hl\r
244 ld (b0c_fast_go),de\r
245 pop de\r
246 ex (sp),hl ;16\r
247b0c_fast_go equ $+1\r
248 jp 0\r
249\r
250b0c_doit:\r
251 ld (b0_save_hl),hl\r
252 ld (b0_save_de),de\r
253 pop hl\r
254 ld (b0_save_af),hl\r
255\r
256 pop de ;get ptr to 'function address' in de\r
257 ld hl,2\r
258 add hl,de\r
259 push hl ;put return address on stack\r
260\r
261 if 0 ; link80\r
262\r
263 ld hl,0\r
264 add hl,sp ;\r
265 ld a,h\r
266 cp high (bs$stack-bs$stack$size) ;link80 can't process this\r
267 jr nc,$ + 5 ;skip if stack allready in common bios ram\r
268\r
269 else\r
270\r
271 ld hl,bs$stack-bs$stack$size\r
272 ld a,h\r
273 dec a\r
274 ld hl,0\r
275 add hl,sp ;\r
276 cp h\r
277 jr c,$ + 5 ;skip if stack allready in common bios ram\r
278 endif\r
279 ld sp,bs$stack ;\r
280\r
281 push hl ;save user stack pointer\r
282\r
283 in0 h,(bbr) ;\r
284 push hl ;\r
285 ld hl,b0c_ret\r
286 push hl\r
287 xor a\r
288 out0 (bbr),a ;\r
289 ex de,hl ;ptr\r
290 ld e,(hl) ;get 'function address'\r
291 inc hl ;\r
292 ld d,(hl) ;\r
293 push de ;put on (switched) stack\r
294\r
295 ld hl,(b0_save_af) ;get back users registers\r
296 push hl\r
297 pop af\r
298 ld de,(b0_save_de)\r
299 ld hl,(b0_save_hl)\r
300 ret ;go to function\r
301b0c_ret:\r
302 ld (b0_save_hl),hl\r
303\r
304 pop hl ;\r
305 out0 (bbr),h ;\r
306 pop hl ;\r
307 ld sp,hl ;\r
308 ld hl,(b0_save_hl)\r
309 ret ;\r
310 else\r
311\r
312_b0call:\r
313 push af\r
314 ld (b0_save_hl),hl\r
315 ld (b0_save_de),de\r
316 pop hl\r
317 ld (b0_save_af),hl\r
318\r
319 pop de ;get ptr to 'function address' in de\r
320 ld hl,2\r
321 add hl,de\r
322 push hl ;put return address on stack\r
323\r
324 if 0 ; link80\r
325\r
326 ld hl,0\r
327 add hl,sp ;\r
328 ld a,h\r
329 cp high (bs$stack-bs$stack$size) ;link80 can't process this\r
330 jr nc,$ + 5 ;skip if stack allready in common bios ram\r
331\r
332 else\r
333\r
334 ld hl,bs$stack-bs$stack$size\r
335 ld a,h\r
336 dec a\r
337 ld hl,0\r
338 add hl,sp ;\r
339 cp h\r
340 jr c,$ + 5 ;skip if stack allready in common bios ram\r
341 endif\r
342 ld sp,bs$stack ;\r
343\r
344 push hl ;save user stack pointer\r
345\r
346 in0 h,(bbr) ;\r
347 push hl ;\r
348 ld hl,b0c_ret\r
349 push hl\r
350 xor a\r
351 out0 (bbr),a ;\r
352 ex de,hl ;ptr\r
353 ld e,(hl) ;get 'function address'\r
354 inc hl ;\r
355 ld d,(hl) ;\r
356 push de ;put on (switched) stack\r
357\r
358 ld hl,(b0_save_af) ;get back users registers\r
359 push hl\r
360 pop af\r
361 ld de,(b0_save_de)\r
362 ld hl,(b0_save_hl)\r
363 ret ;go to function\r
364b0c_ret:\r
365 ld (b0_save_hl),hl\r
366\r
367 pop hl ;\r
368 out0 (bbr),h ;\r
369 pop hl ;\r
370 ld sp,hl ;\r
371 ld hl,(b0_save_hl)\r
372 ret ;\r
373 endif\r
374\r
375b0_save_hl: dw 0\r
376b0_save_de: dw 0\r
377b0_save_af: dw 0\r
378\r
379\r
380;--------------------------------------------------------------------\r
381; Trampoline for interrupt routines in banked ram.\r
382; Switch stack pointer to "system" stack in top ram\r
383; Save bbr\r
384\r
385 cseg\r
386\r
387 if 0\r
388\r
389isv_sw: ;\r
390 ex (sp),hl ;save hl, 'return adr' in hl\r
391 push de ;\r
392 push af ;\r
393 ex de,hl ;'return address' in de\r
394\r
395 if 0\r
396 if 0 ; link80\r
397\r
398 ld hl,0\r
399 add hl,sp ;\r
400 ld a,h\r
401 cp high (bs$stack-bs$stack$size) ;link80 can't process this\r
402 jr nc,$ + 5 ;skip if stack allready in common bios ram\r
403\r
404 else\r
405\r
406 ld hl,bs$stack-bs$stack$size\r
407 ld a,h\r
408 dec a\r
409 ld hl,0\r
410 add hl,sp ;\r
411 cp h\r
412 jr c,$ + 5 ;skip if stack allready in common bios ram\r
413 endif\r
414 ld sp,bs$stack ;\r
415 else\r
416 ld hl,0\r
417 add hl,sp\r
418 ld sp,istack\r
419 endif\r
420 push hl ;save user stack pointer\r
421 in0 h,(bbr) ;\r
422 push hl ;\r
423 xor a ;\r
424 out0 (bbr),a ;\r
425 ex de,hl ;\r
426 ld e,(hl) ;\r
427 inc hl ;\r
428 ld d,(hl) ;\r
429 ex de,hl ;\r
430 push bc ;\r
431 call ijphl ;\r
432\r
433 pop bc ;\r
434 pop hl ;\r
435 out0 (bbr),h ;\r
436 pop hl ;\r
437 ld sp,hl ;\r
438 pop af ;\r
439 pop de ;\r
440 pop hl ;\r
441 ei ;\r
442 ret ;\r
443\r
444 else\r
445\r
446isv_sw: ;\r
447 ex (sp),hl ;save hl, 'return adr' in hl\r
448\r
449 ld (istack),sp ;save user stack pointer\r
450 ld sp,istack\r
451 push de ;\r
452 push bc ;\r
453 push af ;\r
454 in0 a,(bbr) ;\r
455 push af ;\r
456 xor a ;\r
457 out0 (bbr),a ;\r
458 ld e,(hl) ;\r
459 inc hl ;\r
460 ld d,(hl) ;\r
461 ex de,hl ;\r
462 call ijphl ;\r
463\r
464 pop af ;\r
465 out0 (bbr),a ;\r
466 pop af ;\r
467 pop bc ;\r
468 pop de ;\r
469 ld sp,(istack) ;\r
470 pop hl ;\r
471 ei ;\r
472 ret ;\r
473\r
474 endif\r
475 ds 24\r
476istack:\r
477 dw 0\r
478\r
479 dseg\r
480\r
481;--------------------------------------------------------------------\r
482; Load byte/word from user ram\r
483;\r
484; de: src address in users bank\r
485; return\r
486; a: value (byte)\r
487; hl: value (word)\r
488\r
489b_ld_a:\r
490 push hl\r
491 or a ; clear carry == byte store\r
492 jr $+3\r
493b_ld_hl:\r
494 scf ; set carry == word store\r
495 push af ; save flag\r
496 push hl ; make space on stack\r
497\r
498 ld a,(@cbnk)\r
499 ld b,a ; b = src bank\r
500\r
501 ld hl,0\r
502 ld a,l\r
503 ld c,l ; c = dst bank (0)\r
504 add hl,sp ; hl = dst\r
505 adc a,1 ; a = count\r
506 ex de,hl\r
507 call dma_move\r
508 ex de,hl\r
509 pop hl\r
510 pop af\r
511 ret c\r
512 ld a,l\r
513 pop hl\r
514 ret\r
515\r
516;--------------------------------------------------------------------\r
517; Store byte/word to user ram\r
518;\r
519; de: dst address in users bank\r
520; a: value (byte)\r
521; hl: value (word)\r
522\r
523b_st_a:\r
524 push hl\r
525 ld l,a\r
526 or a ; clear carry == byte store\r
527 jr $+3\r
528b_st_hl:\r
529 scf ; set carry == word store\r
530 push af ; save flag\r
531 push hl ; put value on stack\r
532\r
533 ld a,(@cbnk) ;\r
534 ld c,a ; c = dst bank\r
535 ld a,0\r
536 ld l,a\r
537 ld h,a\r
538 ld b,a ; b = src bank (0)\r
539 add hl,sp ; hl = src\r
540 adc a,1 ; a = count\r
541\r
542 call dma_move\r
543\r
544 pop hl ; restore value\r
545 pop af ; carry\r
546 ret c\r
547 pop hl\r
548 ret\r
549\r
550;--------------------------------------------------------------------\r
551;\r
552; hl: src\r
553; de: dst\r
554; b: src bank\r
555; c: dst bank\r
556; a: count\r
557\r
558dma_move:\r
559 out0 (bcr0l),a ; setup DMA count\r
560 xor a\r
561 out0 (bcr0h),a\r
562\r
563 push hl\r
564 ld a,b\r
565 call bnk2phy\r
566 out0 (sar0l),l ; setup DMA src address\r
567 out0 (sar0h),h\r
568 out0 (sar0b),a\r
569\r
570 ld l,e\r
571 ld h,d\r
572 ld a,c\r
573 call bnk2phy\r
574 out0 (dar0l),l ; setup DMA dst address\r
575 out0 (dar0h),h\r
576 out0 (dar0b),a\r
577\r
578 ld a,M_MMOD ; DMA burst mode\r
579 out0 (dmode),a\r
580 ld a,M_DE0+M_NDWE1 ; enable DMA0\r
581 out0 (dstat),a ; move ...\r
582 pop hl\r
583 ret\r
584\r
585\r
586;====================================================================\r
587\r
588 cseg\r
589\r
590 if 0\r
591\r
592;--------------------------------------------------------------------\r
593; Return the BBR value for the given bank number\r
594\r
595bnk2bbr:\r
596 or a ; 4\r
597 ret z ; 5/10 | 11 14\r
598\r
599 push bc ;11 | 11\r
600 ld b,a ; 4\r
601 ld c,CA ; 6\r
602 mlt bc ;17 >45\r
603 ld a,c ; 4\r
604 add a,10h ; 6\r
605 pop bc ; 9 | 10\r
606 ret ; 9 | 10 76\r
607\r
608 push ix ;2 / 14 | 15\r
609 ld ix,bnktbl ;4 / 12 | 14\r
610 ld ($+3+2),a ;3 / 15 | 19\r
611 ld a,(ix+0) ;3 / 14 | 19\r
612 pop ix ;2 / 12 | 14\r
613 ret ;1 / 9 | 10 15 / 76|91\r
614\r
615 push hl ;1 / 11 | 11\r
616 ld hl,bnktbl ;3 / 9 | 10\r
617 add a,l ;1 / 4 | 4\r
618 ld l,a ;1 / 4 | 4\r
619 ld a,0 ;1 / 6 | 7\r
620 adc a,h ;1 / 4 | 4\r
621 ld h,a ;1 / 4 | 4\r
622 ld a,(hl) ;1 / 6 | 7\r
623 pop hl ;1 / 9 | 10\r
624 ret ;1 / 9 | 10 12 / 66|71\r
625\r
626 push hl ;1 / 11 | 11\r
627 add a,low bnktbl ;2 / 6 | 7\r
628 ld l,a ;1 / 4 | 4\r
629 ld a,0 ;1 / 6 | 7\r
630 adc a,high bnktbl ;2 / 6 | 7\r
631 ld h,a ;1 / 4 | 4\r
632 ld a,(hl) ;1 / 6 | 7\r
633 pop hl ;1 / 9 | 10\r
634 ret ;1 / 9 | 10 11 / 61|67\r
635\r
636 endif\r
637\r
638\r
639 end\r