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