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