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