]> cloudbase.mooo.com Git - z180-stamp.git/blob - z180/r3init.180
1936c9be0bd5de4704823fcceff31871d69f3c2c
[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 call $coninit
284
285 call bufferinit
286
287
288
289 im 2 ;?030e
290 ei ;0282
291
292 call $cists ;0284
293 call $cists ;0287
294 or a ;028a
295 call nz,$ci ;028d
296
297 ld a,(banktab) ;
298 ld e,a ;
299 jp ddtz ;0290
300
301 ;
302 ;----------------------------------------------------------------------
303 ;
304
305 ;TODO: Make a ringbuffer module.
306
307 global buf.init
308
309 buf.init:
310 ld (ix+o.in_idx),0
311 ld (ix+o.out_idx),0
312 ld (ix+o.mask),a
313 ret
314
315 ;----------------------------------------------------------------------
316
317 extrn msginit,msg_tx_fifo,msg_rx_fifo
318 extrn msg.sout
319
320 bufferinit:
321
322 ld de,msg_tx_fifo
323 in0 a,cbr
324 call log2phys
325 ld (40h+0),hl
326 ld (40h+2),a
327
328 ld (bufdat+1),hl
329 ld (bufdat+3),a
330 xor a
331 ld (bufdat+0),a
332 ld hl,inimsg
333 call msg.sout
334
335 ld de,msg_rx_fifo
336 in0 a,cbr
337 call log2phys
338 ld (bufdat+1),hl
339 ld (bufdat+3),a
340 ld a,1
341 ld (bufdat+0),a
342 ld hl,inimsg
343 call msg.sout
344
345 ret
346
347 inimsg:
348 db inimsg_e - $ - 1
349 db 81h
350 db inimsg_e - $ - 1
351 db 0
352 bufdat:
353 db 0
354 dw 0
355 db 0
356 inimsg_e:
357
358 ;----------------------------------------------------------------------
359 ;
360 if 0
361
362 extrn msginit,msg.sout,msg_fifo
363 extrn tx.buf,rx.buf
364
365
366 bufferinit:
367 call msginit
368
369 ld hl,buffers
370 ld bc,0300h ; b:count, c:buffer nr
371 bfi_1:
372 ld e,(hl)
373 inc hl
374 ld d,(hl)
375 inc hl
376 push hl
377 in0 a,cbr
378 call log2phys
379 ld (bufdat+1),hl
380 ld (bufdat+3),a
381 ld a,c
382 ld (bufdat+0),a
383 ld hl,inimsg
384 call msg.sout
385 pop hl
386 inc c
387 djnz bfi_1
388 ret
389
390 rept 20
391 db 0
392 endm
393
394 buffers:
395 dw msg_fifo
396 dw tx.buf
397 dw rx.buf
398
399 inimsg:
400 db inimsg_e - $ -2
401 db PMSG
402 db 81h
403 db inimsg_e - $ -1
404 db 0
405 bufdat:
406 db 0
407 dw 0
408 db 0
409 inimsg_e:
410
411 endif
412
413 ;
414 ;----------------------------------------------------------------------
415 ;
416
417 sysram_init:
418 ld hl,sysramw
419 ld de,topcodsys
420 ld bc,sysrame-sysramw
421 ldir
422
423 ret
424
425 ;----------------------------------------------------------------------
426
427 ivtab_init:
428 ld hl,ivtab ;
429 ld a,h ;
430 ld i,a ;
431 out0 (il),l ;
432
433 ; Let all vectors point to spurious int routines.
434
435 ld d,high sp.int0
436 ld a,low sp.int0
437 ld b,9
438 ivt_i1:
439 ld (hl),a
440 inc l
441 ld (hl),d
442 inc l
443 add a,sp.int.len
444 djnz ivt_i1
445 ret
446
447 ;----------------------------------------------------------------------
448
449 prt0_init:
450 ld a,i
451 ld h,a
452 in0 a,(il)
453 and 0E0h
454 or IV$PRT0
455 ld l,a
456 ld (hl),low iprt0
457 inc hl
458 ld (hl),high iprt0
459 ld hl,prt0itab
460 call io.ini.m
461 ret
462
463 prt0itab:
464 db prt0it_e-prt0itab-2
465 db tmdr0l
466 dw PRT_TC10MS
467 dw PRT_TC10MS
468 db M_TIE0+M_TDE0 ;enable timer 0 interrupt and down count.
469 prt0it_e:
470
471
472 ;
473 ;----------------------------------------------------------------------
474 ;
475
476 io.ini:
477 push bc
478 ld b,0 ;high byte port adress
479 ld a,(hl) ;count
480 inc hl
481 ioi_1:
482 ld c,(hl) ;port address
483 inc hl
484 outi
485 inc b ;outi decrements b
486 dec a
487 jr nz,ioi_1
488 pop bc
489 ret
490
491 io.ini.m:
492 push bc
493 ld b,(hl)
494 inc hl
495 ld c,(hl)
496 inc hl
497 otimr
498 pop bc
499 ret
500
501 io.ini.l:
502 ;
503
504 ;----------------------------------------------------------------------
505 ;
506
507 ; compute crc
508 ; hl: start adr
509 ; bc: len
510 ; bc returns crc val
511
512 do_crc16:
513 ld de,0FFFFh
514 crc1:
515 ld a,(hl)
516 xor e
517 ld e,a
518 rrca
519 rrca
520 rrca
521 rrca
522 and 0Fh
523 xor e
524 ld e,a
525 rrca
526 rrca
527 rrca
528 push af
529 and 1Fh
530 xor d
531 ld d,a
532 pop af
533 push af
534 rrca
535 and 0F0h
536 xor d
537 ld d,a
538 pop af
539 and 0E0h
540 xor e
541 ld e,d
542 ld d,a
543 cpi
544 jp pe,crc1
545 or e ;z-flag
546 ret
547
548
549 gencrc_alv:
550 push hl ;03f6
551 push de ;03f7
552 push bc
553 push af ;03f8
554 ld hl,banktabsys ;03f9
555 ld bc,crc_len ;03fc
556 call do_crc16 ;03ff
557 ld (hl),e
558 inc hl
559 ld (hl),d
560 pop af ;0406
561 pop bc
562 pop de ;0407
563 pop hl ;0408
564 ret ;0409
565
566 checkcrc_alv:
567 push hl ;040a
568 push de
569 push bc ;040b
570 ld hl,banktabsys ;040d
571 ld bc,crc_len+2 ;0410
572 call do_crc16 ;0413
573 pop bc ;041d
574 pop de
575 pop hl ;041e
576 ret ;041f
577
578 ;----------------------------------------------------------------------
579
580 ;
581 ; alloc
582 ;
583 ; h: max bank #
584 ; l: min bank #
585 ; b: max size
586 ; c: min size
587 ;
588 ; ret:
589 ; a: 0 == ok
590 ; 1 ==
591 ; 2 == no bank # in requested range
592 ; ff == crc error
593 ;
594
595 sub_0420h:
596 call checkcrc_alv ;0420
597 jr nz,l049ch ;0424 crc error, tables corrupt
598
599 call sub_049dh ;0427 bank # in req. range available?
600 jr c,l0499h ;042a
601 push ix ;042c
602 push iy ;042e
603 push de ;0430
604 push hl ;0431
605 push bc ;0432
606 ld c,b ;0433
607 ld b,alv_len+1 ;0434
608 ld d,0 ;0436
609 ld hl,memalv-1 ;0438
610 jr l0441h ;043b
611
612 ; find free blocks
613
614 l043dh:
615 ld a,(hl) ;043d
616 inc a ;043e free blocks are marked 0ffh
617 jr z,l0446h ;043f
618 l0441h:
619 inc hl ;0441
620 djnz l043dh ;0442
621 jr l0464h ;0444
622 l0446h:
623 push hl ;0446
624 pop ix ;0447 free blocks start here
625 ld e,000h ;0449
626 jr l0451h ;044b
627 l044dh: ; count free blocks
628 ld a,(hl) ;044d
629 inc a ;044e
630 jr nz,l0457h ;044f
631 l0451h:
632 inc e ;0451
633 inc hl ;0452
634 djnz l044dh ;0453
635 jr l0464h ;0455
636
637 ; end of free blocks run.
638
639 l0457h:
640 ld a,d ;0457
641 cp e ;0458 nr of blocks >= requested ?
642 jr nc,l0441h ;0459
643
644 ld d,e ;045b
645 push ix ;045c
646 pop iy ;045e
647 ld a,d ;0460
648 cp c ;0461
649 jr c,l0441h ;0462
650 l0464h:
651 pop bc ;0464
652 ld a,d ;0465
653 cp b ;0466
654 jr c,l046ch ;0467
655 ld d,b ;0469
656 jr l0471h ;046a
657 l046ch:
658 cp c ;046c
659 jr nc,l0471h ;046d
660 ld d,000h ;046f
661 l0471h:
662 ld a,d ;0471
663 push iy ;0472
664 pop hl ;0474
665 ld de,memalv ;0475
666 or a ;0478
667 sbc hl,de ;0479
668 ld b,l ;047b
669 ld c,a ;047c
670 pop hl ;047d
671 l047eh:
672 or a ;047e
673 jr z,l0489h ;047f
674 ld (iy+0),l ;0481
675 inc iy ;0484
676 dec a ;0486
677 jr l047eh ;0487
678 l0489h:
679 pop de ;0489
680 pop iy ;048a
681 pop ix ;048c
682 call gencrc_alv ;048e
683 ld a,c ;0491
684 or a ;0492
685 ld a,000h ;0493
686 ret nz ;0495
687 or 001h ;0496
688 ret ;0498
689
690 l0499h:
691 ld a,2 ;0499
692 l049ch:
693 or a
694 ret ;049c
695
696
697 ; search a free bank number in range
698 ; h: max #
699 ; l: min #
700 ; ret:
701 ; l: bank number available
702 ; nc, if found, bank nr. in l
703 ; cy, if none found
704
705 sub_049dh:
706 push de ;049d
707 push bc ;049e
708 ex de,hl ;049f
709 dec e ;04a0
710 l04a1h:
711 inc e ;04a1 test next #
712 ld a,d ;04a2
713 cp e ;04a3
714 jr c,l04b1h ;04a4
715 ld a,e ;04a6
716 ld hl,memalv ;04a7
717 ld bc,alv_len ;04aa
718 cpir ;04ad bank# allready allocated?
719 jr z,l04a1h ;04af if yes, search for next
720 l04b1h:
721 ex de,hl ;04b1
722 pop bc ;04b2
723 pop de ;04b3
724 ret ;04b4
725
726
727 sub_04b5h:
728 ld a,l ;04b5
729 cp 012h ;04b6
730 ccf ;04b8
731 ret c ;04b9
732 push hl ;04ba
733 ld hl,banktab ;04bb
734 call add_hl_a
735 ld (hl),b ;04c3
736 call gencrc_alv ;04c4
737 pop hl ;04c7
738 or a ;04c8 clear carry
739 ret ;04c9
740
741
742 ;--------------------------------------------------------------
743 ;
744 ; de: Log. Address
745 ; a: Bank number
746 ;
747 ;out ahl: Phys. (linear) Address
748
749
750 bnk2phys:
751 push hl
752 ld hl,banktab
753 call add_hl_a
754 ld a,(hl)
755 pop hl
756
757 ; fall thru
758 ;--------------------------------------------------------------
759 ;
760 ; de: Log. Address
761 ; a: Bank (bbr)
762 ;
763 ; OP: ahl = (a<<12) + (d<<8) + e
764 ;
765 ;out ahl: Phys. (linear) Address
766
767
768 log2phys:
769 push bc ;
770 ld c,a ;
771 ld b,16 ;
772 mlt bc ;bc = a<<4
773 ld l,d ;
774 ld h,0 ;
775 add hl,bc ;bc + d == a<<4 + d
776 ld a,h ;
777 ld h,l ;
778 ld l,e ;
779 pop bc ;
780 ret ;
781
782
783 ;--------------------------------------------------------------
784 ;
785 ;return:
786 ; hl = hl + a
787 ; Flags undefined
788 ;
789
790 add_hl_a:
791 add a,l
792 ld l,a
793 ret nc
794 inc h
795 ret
796
797 ; ---------------------------------------------------------
798
799 sysramw:
800
801 .phase isvsw_loc
802 topcodsys:
803
804 ; Trampoline for interrupt routines in banked ram.
805 ; Switch stack pointer to "system" stack in top ram
806 ; Save cbar
807
808 isv_sw: ;
809 ex (sp),hl ; save hl, return adr in hl
810 push de ;
811 push af ;
812 ex de,hl ;
813 ld hl,0 ;
814 add hl,sp ;
815 ld a,h ;
816 cp 0f8h ;
817 jr nc,isw_1 ;
818 ld sp,$stack ;
819 isw_1:
820 push hl ;
821 in0 h,(cbar) ;
822 push hl ;
823 ld a,SYS$CBAR ;
824 out0 (cbar),a ;
825 ex de,hl ;
826 ld e,(hl) ;
827 inc hl ;
828 ld d,(hl) ;
829 ex de,hl ;
830 push bc ;
831 call jphl ;
832
833 pop bc ;
834 pop hl ;
835 out0 (cbar),h ;
836 pop hl ;
837 ld sp,hl ;
838 pop af ;
839 pop de ;
840 pop hl ;
841 ei ;
842 ret ;
843 jphl:
844 jp (hl) ;
845
846 ; ---------------------------------------------------------
847
848
849 iprt0:
850 push af
851 push hl
852 in0 a,(tcr)
853 in0 a,(tmdr0l)
854 in0 a,(tmdr0h)
855 ld a,(tim_ms)
856 inc a
857 cp 100
858 jr nz,iprt_1
859 xor a
860 ld hl,(tim_s)
861 inc hl
862 ld (tim_s),hl
863 iprt_1:
864 ld (tim_ms),a
865 pop hl
866 pop af
867 ei
868 ret
869
870 ; ---------------------------------------------------------
871
872 sp.int0:
873 ld a,0d0h
874 jr sp.i.1
875 sp.int.len equ $-sp.int0
876 ld a,0d1h
877 jr sp.i.1
878 ld a,0d2h
879 jr sp.i.1
880 ld a,0d3h
881 jr sp.i.1
882 ld a,0d4h
883 jr sp.i.1
884 ld a,0d5h
885 jr sp.i.1
886 ld a,0d6h
887 jr sp.i.1
888 ld a,0d7h
889 jr sp.i.1
890 ld a,0d8h
891 sp.i.1:
892 ; out (80h),a
893 halt
894
895 curph defl $
896 .dephase
897 sysrame:
898 .phase curph
899 tim_ms: db 0
900 tim_s: dw 0
901 .dephase
902
903 ;-----------------------------------------------------
904
905 dseg
906
907 ds 1
908 banktabsys:
909 ds 1 ;0c001h
910 ds 1 ;0c002h
911 banktab:
912 ds BANKS ;0c003h
913 memalv:
914 ds 512/4 ;Number of 4k blocks
915 alv_len equ $-memalv
916 crc_len equ $-banktabsys
917
918 crc_memalv:
919 ds 2 ;
920
921 cseg
922
923 ;.phase 0ffc0h
924 ;ivtab equ 0ffc0h ; 0ffc0h ;int vector table
925 ;.dephase
926
927 ;.phase 0fffch
928 mark_55AA equ 0fffch
929 ;ds 4 ; 0fffch
930 ;.dephase
931
932
933 end
934