]> cloudbase.mooo.com Git - z180-stamp.git/blob - Z180/r3init.180
c99b624225b7465b809de7e5f53891d7fe0d72dd
[z180-stamp.git] / Z180 / r3init.180
1 page 255
2 .z80
3
4 extrn ddtz,bpent
5 extrn $stack
6 extrn $coninit,$cists,$ci
7
8 extrn romend
9
10
11 global isv_sw
12
13 include config.inc
14 include z180reg.inc
15 include z180.lib
16
17 CR equ 0dh
18
19
20
21 ;----------------------------------------------------------------------
22
23 cseg
24
25 jp start
26
27 ; restart vectors
28
29 rsti defl 1
30 rept 7
31 db 0, 0, 0, 0, 0
32 jp bpent
33 rsti defl rsti+1
34 endm
35
36 ;----------------------------------------------------------------------
37
38 if ROMSYS
39 $crom: defb c$rom ;
40 else
41 db 0 ;
42 endif
43
44 dmclrt: ;clear ram per dma
45 db dmct_e-dmclrt-2 ;
46 db sar0l ;first port
47 dw nullbyte ;src (fixed)
48 nullbyte:
49 db 000h ;src
50 dw romend ;dst (inc), start after "rom" code
51 db 00h ;dst
52 dw 0-romend ;count (64k)
53 dmct_e:
54
55
56 INIWAITS defl CWAITIO
57 if ROMSYS
58 INIWAITS defl INIWAITS+CWAITROM
59 endif
60
61 hwini0:
62 db 3 ;count
63 db rcr,CREFSH ;configure DRAM refresh
64 db dcntl,INIWAITS ;wait states
65 db cbar,SYS$CBAR
66
67 ;----------------------------------------------------------------------
68
69 start:
70 push af ;003c
71 in0 a,(itc) ;003d Illegal opcode trap?
72 jp p,??st01 ;0040
73 pop af ;0043
74 jp bpent ;0044 yes, handle
75
76 ??st01:
77 ld a,i ;0047 I register == 0 ?
78 jr z,??st02 ;004b yes, harware reset
79 pop af ;004d
80 jp bpent ;004e no, allready set up
81
82 ??st02:
83 di ;0058
84 ld a,CREFSH
85 out0 (rcr),a ; configure DRAM refresh
86 ld a,CWAITIO
87 out0 (dcntl),a ; wait states
88
89 ; search warm start mark
90
91 ld ix,mark_55AA ;00b8 ; top of common area
92 ld a,SYS$CBAR ;
93 out0 (cbar),a ;
94 ld a,071h ;00bc
95 ex af,af' ;00be ;for cbr = 0x70 downto 0x40
96 swsm_l:
97 ex af,af' ;00bf
98 dec a ;00c0
99 cp 03fh ;00c1
100 jr z,kstart ;00c3 ; break (mark not found)
101 out0 (cbr),a ;00c5
102 ex af,af' ;00c8
103 ld a,0aah ;00c9
104 cp (ix+000h) ;00cb
105 jr nz,swsm_l ;00ce
106 cp (ix+002h) ;00d0
107 jr nz,swsm_l ;00d3
108 cpl ;00d5
109 cp (ix+001h) ;00d6
110 jr nz,swsm_l ;00d9
111 cp (ix+003h) ;00db
112 jr nz,swsm_l ;00de
113 ld sp,$stack ;00e0 mark found, check
114 call checkcrc_alv ;00e3
115 jp z,wstart ;00e6 check ok,
116
117 ;
118 ; ram not ok, initialize -- kstart --
119
120 kstart:
121
122 ld a,088h ;00e9 0000-7fff: common 0
123 out0 (cbar),a ;00eb 8000-ffff: common 1
124 ld ix,08000h ;00f3
125 ld a,0 ;00f1 start at 008000 (2. phys. 32k block)
126 ??f_0:
127 out0 (cbr),a ;00f9
128
129 ld (ix+0),a ;0103
130 cpl
131 ld (ix+1),a ;0103
132 cpl
133 add a,8 ;010a next 'bank'
134 cp 078h ;010c stop at 078000
135 jr nz,??f_0 ;010e
136
137 ld de,8000h ;0114 first block not tested, but mark as ok
138 ld a,0 ;00f1 start at 008000 (2. phys. 32k block)
139 ??cp_0:
140 out0 (cbr),a ;011c
141 ld c,a
142 xor (ix+0)
143 ld b,a
144 ld a,c
145 cpl
146 xor (ix+1)
147 or b
148 jr nz,??cp_1
149 scf
150 ??cp_1:
151 rr d
152 rr e
153 ld a,c
154 add a,8
155 cp 078h ; stop at 078000
156 jr nz,??cp_0
157
158 ;
159 ; ram test found 1 or more error free blocks (32k)
160 ;
161
162 ramok:
163 ld a,SYS$CBAR ;01c8
164 out0 (cbar),a ;01ca
165 ld h,d
166 ld l,e
167 ld c,070h ;01ce highest block
168 ld b,15 ;01d0
169 ??sr_1:
170 add hl,hl
171 jr c,alloc ;01d4 highest "error free" block
172 ld a,c ;01d6
173 sub 008h ;01d7
174 ld c,a ;01d9
175 djnz ??sr_1 ;01da
176
177 slp ;01dc should never be reached
178
179 alloc:
180 out0 (cbr),c ;01de
181 ld sp,$stack ;01e1
182
183 ; Clear RAM using DMA0
184
185 ld hl,dmclrt ;load DMA registers
186 call io.ini.m
187 ld a,0cbh ;01ef dst +1, src fixed, burst
188 out0 (dmode),a ;01f1
189
190 ld b,512/64
191 ld a,062h ;01f4 enable dma0,
192 ??cl_1:
193 out0 (dstat),a ;01f9 clear (up to) 64k
194 djnz ??cl_1 ; end of RAM?
195
196 ; Init bank manager
197
198 ld hl,banktabsys ;020f
199 ld (hl),c ; Common area
200 inc hl ;0213
201 ld (hl),c ; System work area
202 inc hl ;0215 Point to bank 0 entry
203 ld b,BANKS ;0216
204 l0218h:
205 ld (hl),0ffh ;0218 Mark all banks as unassigned
206 inc hl ;021a
207 djnz l0218h ;021b
208
209 ld hl,memalv ;
210 ld b,8 ; 8*4k ie. first 32k
211 ??a_0:
212 ld (hl),0e0h ; mark as sys ("rom"/monitor)
213 inc hl
214 djnz ??a_0
215
216 rr d ; shift out bit for block 0
217 rr e ;
218 ld c,15 ;022c 15*32k remaining blocks
219 l022eh:
220 ld a,0feh ; 0xfe == block with error(s)
221 rr d ;
222 rr e
223 adc a,0 ; ==> 0xff : block ok
224 ld b,32/4 ; 32k == 8 * 4k
225 l0236h:
226 ld (hl),a ;
227 inc hl ;
228 djnz l0236h ;
229 dec c ;
230 jr nz,l022eh ;next 32k block
231
232 ld hl,memalv+0ch ;memalv+0ch
233 ld a,(banktabsys) ;
234 call add_hl_a
235 ld b,3 ;
236 l024ah:
237 ld (hl),0ech ;alloc system ram
238 inc hl ;
239 djnz l024ah ;
240 ld (hl),0efh ;alloc common
241 call gencrc_alv
242
243 ld hl,0000h ;bank #
244 ld bc,0f0fh ; size (?) (4k blocks)
245 xor a ;
246 call sub_0420h ;alloc mem for bank 0
247 ld c,l ;
248 or a ;
249 call z,sub_04b5h ;
250
251 ld hl,0101h ;
252 ld bc,0f0fh ;
253 xor a ;
254 call sub_0420h ;
255 ld c,l ;
256 or a ;
257 call z,sub_04b5h ;
258
259 ld hl,055AAh ;set warm start mark
260 ld (mark_55AA),hl ;
261 ld (mark_55AA+2),hl;
262
263 ;
264 ; crc ok -- wstart --
265 ;
266 wstart:
267 call sysram_init ;027f
268 call ivtab_init
269
270 call prt0_init
271
272
273 call bufferinit
274
275
276 call $coninit
277
278
279
280
281 im 2 ;?030e
282 ei ;0282
283
284 call $cists ;0284
285 call $cists ;0287
286 or a ;028a
287 call nz,$ci ;028d
288
289 ld a,(banktab) ;
290 ld e,a ;
291 jp ddtz ;0290
292
293
294 ;
295 ;----------------------------------------------------------------------
296 ;
297
298 extrn msginit,msg.sout,msg_fifo
299 extrn tx.buf,rx.buf
300
301
302 ;TODO: Make a ringbuffer module.
303
304 global buf.init
305
306 buf.init:
307 ld (ix+o.in_idx),0
308 ld (ix+o.out_idx),0
309 ld (ix+o.mask),a
310 ret
311
312 ;----------------------------------------------------------------------
313
314 bufferinit:
315 call msginit
316
317 ld hl,buffers
318 ld bc,0300h
319 bfi_1:
320 ld e,(hl)
321 inc hl
322 ld d,(hl)
323 inc hl
324 push hl
325 in0 a,cbr
326 call log2phys
327 ld (bufdat+1),hl
328 ld (bufdat+3),a
329 ld a,c
330 ld (bufdat+0),a
331 ld hl,inimsg
332 call msg.sout
333 pop hl
334 inc c
335 djnz bfi_1
336 ret
337
338 rept 20
339 db 0
340 endm
341
342 buffers:
343 dw msg_fifo
344 dw tx.buf
345 dw rx.buf
346
347 inimsg:
348 db inimsg_e - $ -2
349 db PMSG
350 db 81h
351 db inimsg_e - $ -1
352 db 0
353 bufdat:
354 db 0
355 dw 0
356 db 0
357 inimsg_e
358
359 ;
360 ;----------------------------------------------------------------------
361 ;
362
363 sysram_init:
364 ld hl,sysramw
365 ld de,topcodsys
366 ld bc,sysrame-sysramw
367 ldir
368
369 ret
370
371 ;----------------------------------------------------------------------
372
373 ivtab_init:
374 ld hl,ivtab ;
375 ld a,h ;
376 ld i,a ;
377 out0 (il),l ;
378
379 ; Let all vectors point to spurious int routines.
380
381 ld d,high sp.int0
382 ld a,low sp.int0
383 ld b,9
384 ivt_i1:
385 ld (hl),a
386 inc l
387 ld (hl),d
388 inc l
389 add a,sp.int.len
390 djnz ivt_i1
391 ret
392
393
394 prt0_init:
395 ld a,i
396 ld h,a
397 in0 a,(il)
398 and 0E0h
399 or IV$PRT0
400 ld l,a
401 ld (hl),low iprt0
402 inc hl
403 ld (hl),high iprt0
404 ld hl,prt0itab
405 call io.ini.m
406 ret
407
408 prt0itab:
409 db prt0it_e-prt0itab-2
410 db tmdr0l
411 dw PRT_TC10MS
412 dw PRT_TC10MS
413 db M_TIE0+M_TDE0 ;enable timer 0 interrupt and down count.
414 prt0it_e:
415
416 ;
417 ;----------------------------------------------------------------------
418 ;
419
420 io.ini:
421 push bc
422 ld b,0 ;high byte port adress
423 ld a,(hl) ;count
424 inc hl
425 ioi_1:
426 ld c,(hl) ;port address
427 inc hl
428 outi
429 inc b ;outi decrements b
430 dec a
431 jr nz,ioi_1
432 pop bc
433 ret
434
435 io.ini.m:
436 push bc
437 ld b,(hl)
438 inc hl
439 ld c,(hl)
440 inc hl
441 otimr
442 pop bc
443 ret
444
445 io.ini.l:
446 ;
447
448 ;----------------------------------------------------------------------
449 ;
450
451 ; compute crc
452 ; hl: start adr
453 ; bc: len
454 ; bc returns crc val
455
456 do_crc16:
457 ld de,0FFFFh
458 crc1:
459 ld a,(hl)
460 xor e
461 ld e,a
462 rrca
463 rrca
464 rrca
465 rrca
466 and 0Fh
467 xor e
468 ld e,a
469 rrca
470 rrca
471 rrca
472 push af
473 and 1Fh
474 xor d
475 ld d,a
476 pop af
477 push af
478 rrca
479 and 0F0h
480 xor d
481 ld d,a
482 pop af
483 and 0E0h
484 xor e
485 ld e,d
486 ld d,a
487 cpi
488 jp pe,crc1
489 or e ;z-flag
490 ret
491
492
493 gencrc_alv:
494 push hl ;03f6
495 push de ;03f7
496 push bc
497 push af ;03f8
498 ld hl,banktabsys ;03f9
499 ld bc,crc_len ;03fc
500 call do_crc16 ;03ff
501 ld (hl),e
502 inc hl
503 ld (hl),d
504 pop af ;0406
505 pop bc
506 pop de ;0407
507 pop hl ;0408
508 ret ;0409
509
510 checkcrc_alv:
511 push hl ;040a
512 push de
513 push bc ;040b
514 ld hl,banktabsys ;040d
515 ld bc,crc_len+2 ;0410
516 call do_crc16 ;0413
517 pop bc ;041d
518 pop de
519 pop hl ;041e
520 ret ;041f
521
522 ;
523 ; alloc
524 ;
525 ; h: max bank #
526 ; l: min bank #
527 ; b: max size
528 ; c: min size
529 ;
530 ; ret:
531 ; a: 0 == ok
532 ; 1 ==
533 ; 2 == no bank # in requested range
534 ; ff == crc error
535 ;
536
537 sub_0420h:
538 call checkcrc_alv ;0420
539 jr nz,l049ch ;0424 crc error, tables corrupt
540
541 call sub_049dh ;0427 bank # in req. range available?
542 jr c,l0499h ;042a
543 push ix ;042c
544 push iy ;042e
545 push de ;0430
546 push hl ;0431
547 push bc ;0432
548 ld c,b ;0433
549 ld b,alv_len+1 ;0434
550 ld d,0 ;0436
551 ld hl,memalv-1 ;0438
552 jr l0441h ;043b
553
554 ; find free blocks
555
556 l043dh:
557 ld a,(hl) ;043d
558 inc a ;043e free blocks are marked 0ffh
559 jr z,l0446h ;043f
560 l0441h:
561 inc hl ;0441
562 djnz l043dh ;0442
563 jr l0464h ;0444
564 l0446h:
565 push hl ;0446
566 pop ix ;0447 free blocks start here
567 ld e,000h ;0449
568 jr l0451h ;044b
569 l044dh: ; count free blocks
570 ld a,(hl) ;044d
571 inc a ;044e
572 jr nz,l0457h ;044f
573 l0451h:
574 inc e ;0451
575 inc hl ;0452
576 djnz l044dh ;0453
577 jr l0464h ;0455
578
579 ; end of free blocks run.
580
581 l0457h:
582 ld a,d ;0457
583 cp e ;0458 nr of blocks >= requested ?
584 jr nc,l0441h ;0459
585
586 ld d,e ;045b
587 push ix ;045c
588 pop iy ;045e
589 ld a,d ;0460
590 cp c ;0461
591 jr c,l0441h ;0462
592 l0464h:
593 pop bc ;0464
594 ld a,d ;0465
595 cp b ;0466
596 jr c,l046ch ;0467
597 ld d,b ;0469
598 jr l0471h ;046a
599 l046ch:
600 cp c ;046c
601 jr nc,l0471h ;046d
602 ld d,000h ;046f
603 l0471h:
604 ld a,d ;0471
605 push iy ;0472
606 pop hl ;0474
607 ld de,memalv ;0475
608 or a ;0478
609 sbc hl,de ;0479
610 ld b,l ;047b
611 ld c,a ;047c
612 pop hl ;047d
613 l047eh:
614 or a ;047e
615 jr z,l0489h ;047f
616 ld (iy+0),l ;0481
617 inc iy ;0484
618 dec a ;0486
619 jr l047eh ;0487
620 l0489h:
621 pop de ;0489
622 pop iy ;048a
623 pop ix ;048c
624 call gencrc_alv ;048e
625 ld a,c ;0491
626 or a ;0492
627 ld a,000h ;0493
628 ret nz ;0495
629 or 001h ;0496
630 ret ;0498
631
632 l0499h:
633 ld a,2 ;0499
634 l049ch:
635 or a
636 ret ;049c
637
638
639 ; search a free bank number in range
640 ; h: max #
641 ; l: min #
642 ; ret:
643 ; l: bank number available
644 ; nc, if found, bank nr. in l
645 ; cy, if none found
646
647 sub_049dh:
648 push de ;049d
649 push bc ;049e
650 ex de,hl ;049f
651 dec e ;04a0
652 l04a1h:
653 inc e ;04a1 test next #
654 ld a,d ;04a2
655 cp e ;04a3
656 jr c,l04b1h ;04a4
657 ld a,e ;04a6
658 ld hl,memalv ;04a7
659 ld bc,alv_len ;04aa
660 cpir ;04ad bank# allready allocated?
661 jr z,l04a1h ;04af if yes, search for next
662 l04b1h:
663 ex de,hl ;04b1
664 pop bc ;04b2
665 pop de ;04b3
666 ret ;04b4
667
668
669 sub_04b5h:
670 ld a,l ;04b5
671 cp 012h ;04b6
672 ccf ;04b8
673 ret c ;04b9
674 push hl ;04ba
675 ld hl,banktab ;04bb
676 call add_hl_a
677 ld (hl),b ;04c3
678 call gencrc_alv ;04c4
679 pop hl ;04c7
680 or a ;04c8 clear carry
681 ret ;04c9
682
683
684 ;--------------------------------------------------------------
685 ;
686 ; de: Log. Address
687 ; a: Bank number
688 ;
689 ;out ahl: Phys. (linear) Address
690
691
692 bnk2phys:
693 push hl
694 ld hl,banktab
695 call add_hl_a
696 ld a,(hl)
697 pop hl
698
699 ; fall thru
700 ;--------------------------------------------------------------
701 ;
702 ; de: Log. Address
703 ; a: Bank (bbr)
704 ;
705 ; OP: ahl = (a<<12) + (d<<8) + e
706 ;
707 ;out ehl: Phys. (linear) Address
708
709
710 log2phys:
711 push bc ;
712 ld c,a ;
713 ld b,16 ;
714 mlt bc ;bc = a<<4
715 ld l,d ;
716 ld h,0 ;
717 add hl,bc ;bc + d == a<<4 + d
718 ld a,h ;
719 ld h,l ;
720 ld l,e ;
721 pop bc ;
722 ret ;
723
724
725 ;--------------------------------------------------------------
726 ;
727 ;return:
728 ; hl = hl + a
729 ; Flags undefined
730 ;
731
732 add_hl_a:
733 add a,l
734 ld l,a
735 ret nc
736 inc h
737 ret
738
739 ; ---------------------------------------------------------
740
741 sysramw:
742
743 .phase isvsw_loc
744 topcodsys:
745
746 ; Trampoline for interrupt routines in banked ram.
747 ; Switch stack pointer to "system" stack in top ram
748 ; Save cbar
749
750 isv_sw: ;
751 ex (sp),hl ; save hl, return adr in hl
752 push de ;
753 push af ;
754 ex de,hl ;
755 ld hl,0 ;
756 add hl,sp ;
757 ld a,h ;
758 cp 0f8h ;
759 jr nc,isw_1 ;
760 ld sp,$stack ;
761 isw_1:
762 push hl ;
763 in0 h,(cbar) ;
764 push hl ;
765 ld a,SYS$CBAR ;
766 out0 (cbar),a ;
767 ex de,hl ;
768 ld e,(hl) ;
769 inc hl ;
770 ld d,(hl) ;
771 ex de,hl ;
772 push bc ;
773 call jphl ;
774
775 pop bc ;
776 pop hl ;
777 out0 (cbar),h ;
778 pop hl ;
779 ld sp,hl ;
780 pop af ;
781 pop de ;
782 pop hl ;
783 ei ;
784 ret ;
785 jphl:
786 jp (hl) ;
787
788 ; ---------------------------------------------------------
789
790 iprt0:
791 push af
792 push hl
793 in0 a,(tcr)
794 in0 a,(tmdr0l)
795 in0 a,(tmdr0h)
796 ld a,(tim_ms)
797 inc a
798 cp 100
799 jr nz,iprt_1
800 xor a
801 ld hl,(tim_s)
802 inc hl
803 ld (tim_s),hl
804 iprt_1:
805 ld (tim_ms),a
806 pop hl
807 pop af
808 ei
809 ret
810
811 ; ---------------------------------------------------------
812
813 sp.int0:
814 ld a,0d0h
815 jr sp.i.1
816 sp.int.len equ $-sp.int0
817 ld a,0d1h
818 jr sp.i.1
819 ld a,0d2h
820 jr sp.i.1
821 ld a,0d3h
822 jr sp.i.1
823 ld a,0d4h
824 jr sp.i.1
825 ld a,0d5h
826 jr sp.i.1
827 ld a,0d6h
828 jr sp.i.1
829 ld a,0d7h
830 jr sp.i.1
831 ld a,0d8h
832 sp.i.1:
833 ; out (80h),a
834 halt
835
836 curph defl $
837 .dephase
838 sysrame:
839 .phase curph
840 tim_ms: db 0
841 tim_s: dw 0
842 .dephase
843
844 ;-----------------------------------------------------
845
846 dseg
847
848 ds 1
849 banktabsys:
850 ds 1 ;0c001h
851 ds 1 ;0c002h
852 banktab:
853 ds BANKS ;0c003h
854 memalv:
855 ds 512/4 ;Number of 4k blocks
856 alv_len equ $-memalv
857 crc_len equ $-banktabsys
858
859 crc_memalv:
860 ds 2 ;
861
862 cseg
863
864 ;.phase 0ffc0h
865 ;ivtab equ 0ffc0h ; 0ffc0h ;int vector table
866 ;.dephase
867
868 ;.phase 0fffch
869 mark_55AA equ 0fffch
870 ;ds 4 ; 0fffch
871 ;.dephase
872
873
874 end
875