stack-based heli output
[enJine.git] / main.zas
blob669af429108420b6737633eaa8eae103e8eeac6c
1 SCR_PART_OFS equ 0
3   deffmt runtap
5   org  #6000
6 myfirstbyte:
8   jp   firstTimeInit
10 mainEntry:
11   ld   hl,map00
12   ld   de,mapData
13   call deexo
15   ld   hl,tilesBase00
16   ld   de,shiftedTilesBuf
17   call deexo
18   call prepareShiftedTiles
20   ld   hl,#4000
21   ld   de,#4001
22   ld   bc,6143
23   ld   (hl),0
24   ldir
26   call prepareAttrs
28   ld   hl,0
29   ld   de,#4000+4096
30   ld   b,6
31 .rndFillLoopLine:
32   push bc
33 .rndFillLoop:
34   push de
35   ld   bc,32
36   ldir
37   pop  de
38   inc  d
39   ld   a,d
40   and  #07
41   jr   nz,.rndFillLoop
42   ld   a,e
43   sub  #E0
44   ld   e,a
45   sbc  a,a
46   and  #F8
47   add  a,d
48   ld   d,a
49   pop  bc
50   djnz .rndFillLoopLine
52   ld   hl,#5800+22*32+3
53   ld   de,#5800+22*32+4
54   ld   bc,26
55   ld   (hl),0107
56   ldir
57   ld   hl,#5800+23*32+3
58   ld   de,#5800+23*32+4
59   ld   bc,26
60   ld   (hl),7
61   ldir
64   ld   hl,IntrHandlerSmall
65   ld   (#FFF5),hl
67   call buildPushers
69 MainLoop:
70   ei
71   nop
72   halt
73   ;call buildPushers
74   ld   hl,14000
75   call delay
76   di   ; sadly, we can skip one intr here
77   call blitMap
78   ; here we have ~14000 tstates to put sprites
79   ld   hl,#40EE
80 mainHeliBlidSubr: equ $+1
81   call blitHeliAt
83   ld   hl,#4000
84   call blitHeliAt
85   ld   hl,#4008
86   call blitHeliAt
87   ld   hl,#4010
88   call blitHeliAt
89   ld   hl,#4018
90   call blitHeliAt
91   ;
92   call buildPushers
93   ;
94 .waitformove:
95   call WinStick.readMoves
96   jr   nz,.somethingpressed
97 .goonml:
98   ei
99   ;nop
100   ;halt
101   ld   hl,10000
102   call delay
103   jr   MainLoop
105 .somethingpressed:
106   ; C,A: state (LRUDF; F is #01)
107   xor  a
108   bit  4,c
109   jr   z,.notleft
110   ld   a,(plrXOffset)
111   sub  a,1
112   jr   nc,.leftok
113   ld   a,(mapX)
114   dec  a
115   and  #3f
116   ld   (mapX),a
117   ld   a,7
118 .leftok:
119   ld   (plrXOffset),a
120   ld   a,(leftCnt)
121   inc  a
122   jr   nz,.notleft
123   ld   a,2
124 .notleft:
125   ld   (leftCnt),a
127   xor  a
128   bit  3,c
129   jr   z,.notright
130   ld   a,(plrXOffset)
131   inc  a
132   and  #07
133   jr   nz,.rightok
134   ld   a,(mapX)
135   inc  a
136   and  #3f
137   ld   (mapX),a
138   xor  a
139 .rightok:
140   ld   (plrXOffset),a
141   ld   a,(rightCnt)
142   inc  a
143   jr   nz,.notright
144   ld   a,2
145 .notright:
146   ld   (rightCnt),a
148   bit  2,c
149   jr   z,.notup
150   ld   a,(plrYOffset)
151   sub  a,1
152   jr   nc,.upok
153   ld   a,(mapY)
154   dec  a
155   and  #3f
156   ld   (mapY),a
157   ld   a,7
158 .upok:
159   ld   (plrYOffset),a
160 .notup:
162   bit  1,c
163   jr   z,.notdown
164   ld   a,(plrYOffset)
165   inc  a
166   and  #07
167   jr   nz,.downok
168   ld   a,(mapY)
169   inc  a
170   and  #3f
171   ld   (mapY),a
172   xor  a
173 .downok:
174   ld   (plrYOffset),a
175 .notdown:
177   ; check direction
178   ld   hl,(leftCnt)
179   ld   a,h
180   or   a
181   jr   z,.notLeftDir
182   ld   hl,blitHeliAt1
183   sub  a,2
184   jr   c,.dirsDone
185   ld   hl,blitHeliAt2
186   jr   .dirsDone
188 .notLeftDir:
189   ld   a,l
190   or   a
191   jr   z,.notRightDir
193 .notRightDir:
194   ld   hl,blitHeliAt
196 .dirsDone:
197   ld   (mainHeliBlidSubr),hl
199   jp   .goonml
202 prepareAttrs:
203   ld   hl,#5800
204   ld   de,#5801
205   ld   bc,767
206   ld   (hl),0
207   ldir
208   ld   hl,#5800+3
209   ld   b,16
210   ld   a,6
211 .fillit:
212   push bc
213   ld   (.filladdr),hl
214 .filladdr: equ $+1
215   ld   de,0
216   inc  de
217   ld   bc,26
218   ld   (hl),a
219   ldir
220   ld   hl,(.filladdr)
221   ld   de,32
222   add  hl,de
223   pop  bc
224   djnz .fillit
225   cp   a,6
226   ret  nz
227   ld   a,1
228   ld   b,8
229   jr   .fillit
230   ;ret
232 leftCnt: db 0
233 rightCnt: db 0
235   include <winstick>
236   include "delay.zas"
239 IntrHandler:
240 IntrHandlerSmall:
241   ei
242   ret
244   defb "JOFFA!"
246 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
247 ;; build shifted tiles
249 prepareShiftedTiles:
250   IF 0
251     ; tiles are not packed
252     ld   de,shiftedTilesBuf
253     push de
254     ; first: unshifted
255     ld   hl,tilesBase
256     ld   bc,6*16*4
257     ldir
258     pop  hl
259   ELSE
260     ; tiles are packed
261     ld   hl,shiftedTilesBuf
262     ld   de,shiftedTilesBuf+6*16*4
263   ENDIF
264   ;
265   ld   a,3  ; 3 shifts left
266 .shiftNextSet:
267   ex   af,af'
268   ; HL: addr of previous tileset
269   ; DE: addr of current tileset
270   push de
271   push de
272   ld   bc,6*16*4
273   ldir
274   ; previous tiles copied, now shift
275   pop  hl      ; start of the current block
276   ld   c,16*4  ; lines
277 .shiftNextLine:
278   ld   e,b     ; B is always 0 here
279   ld   b,6
280 .shiftNextByte:
281   ld   a,(hl)
282   ld   d,a
283   rr   e
284   rra
285   rr   e
286   rra
287   ld   (hl),a
288   inc  hl
289   ld   e,d
290   djnz .shiftNextByte
291   dec  c
292   jr   nz,.shiftNextLine
293   ex   de,hl  ; now DE is the new dest address
294   pop  hl     ; current set address
295   ex   af,af'
296   dec  a
297   jr   nz,.shiftNextSet
298   ret
300 exo_mapbasebits: equ #4000  ; 156 bytes
301   include <deexo.inc>
303 tilesBase00:
304   incbin "bdata/tiles_blobs.exo"
305 map00:
306   incbin "bdata/map00.exo"
308 mapData: equ #8000
309 mapSize: equ #0800
311   org  #8800
312 pusherStart: equ $  ; #8800
313                     ; max pusher end will be: #8eff
315   org  #8f00
316 scrRowsTable: ds 128*2
318   ; #9000
319 shiftedTilesBuf: ds 16*4*6*4
320   ; #9600
322 tileBlockOffsets:
323   dw shiftedTilesBuf+0*6*16
324   dw shiftedTilesBuf+1*6*16
325   dw shiftedTilesBuf+2*6*16
326   dw shiftedTilesBuf+3*6*16
328 ;0  1  2  3
329 ;bc de af hl
330 pushCodes:
331   db 0E5h,0E5h  ; 0 : push hl, push hl : 33
332   db 0D5h,0C5h  ; 1 : push de, push bc : 01
333   db 0D5h,0D5h  ; 2 : push de, push de : 11
334   db 0F5h,0D5h  ; 3 : push af, push de : 12
335   db 0C5h,0E5h  ; 4 : push bc, push hl : 30
336   db 0E5h,0F5h  ; 5 : push hl, push af : 23
337   db 0F5h,0C5h  ; 6 : push af, push bc : 02
338   db 0E5h,0C5h  ; 7 : push hl, push bc : 03
339   db 0F5h,0E5h  ; 8 : push af, push hl : 32
340   db 0F5h,0F5h  ; 9 : push af, push af : 22
341   db 0C5h,0C5h  ;10 : push bc, push bc : 00
342   db 0D5h,0F5h  ;11 : push de, push af : 21
343   db 0C5h,0D5h  ;12 : push bc, push de : 10
344   db 0E5h,0D5h  ;13 : push hl, push de : 13
345   db 0D5h,0E5h  ;14 : push de, push hl : 31
346   db 0C5h,0F5h  ;15 : push bc, push af : 20
348 ; jump table for screen pushers
349 ; addr, tilesofs, 2ndtilesofs
350 pusherJumpTable:
351   ds 3*2*9
353 shiftedTilesOfsTable:
354   dw  3*6*16*4
355   dw  2*6*16*4
356   dw  1*6*16*4
357   dw  0*6*16*4
360 plrXOffset: db 0  ; player X offset in the tile (0-7): in 2 pixels
361 plrYOffset: db 0  ; player Y offset in the tile (0-28; step: 4); (0-7): in 2 pixels
362 mapX: db 0
363 mapY: db 0
365 savedSP: dw 0
366 relGfxSavedSP: dw 0
368   defm "JOFFA!"
370 heliPhase: db 0
372   include "helispr.zas"
374 blitHeliAt:
375 blitHeliAt1:
376 blitHeliAt2:
377   ld   (savedSP),sp
378   ld   sp,heliframe0
379   ld   a,(heliPhase)
380   xor  #01
381   ld   (heliPhase),a
382   jp   nz,.hf0ok
383   ld   sp,heliframe1
384 .hf0ok:
386   ld   b,18/2
387 .loop0:
388   ; left-to-right stripe
389   DUP 3
390   pop  de
391   ld   a,e
392   or   (hl)
393   ld   (hl),a
394   inc  l
395   ld   a,d
396   or   (hl)
397   ld   (hl),a
398   inc  l
399   EDUP
400   org  $-1  ; overwrite last 'inc l'
401   ; right-to-left stripe
402   inc  h
403   ld   a,h
404   and  #07
405   jp   nz,.blh_dshort0
406   ld   a,l
407   sub  #E0
408   ld   l,a
409   sbc  a,a
410   and  #F8
411   add  a,h
412   ld   h,a
413 .blh_dshort0:
415   DUP 3
416   pop  de
417   ld   a,e
418   or   (hl)
419   ld   (hl),a
420   dec  l
421   ld   a,d
422   or   (hl)
423   ld   (hl),a
424   dec  l
425   EDUP
426   org  $-1  ; overwrite last 'dec l'
427   dec  b
428   jp   z,.done
429   inc  h
430   ld   a,h
431   and  #07
432   jp   nz,.blh_dshort1
433   ld   a,l
434   sub  #E0
435   ld   l,a
436   sbc  a,a
437   and  #F8
438   add  a,h
439   ld   h,a
440 .blh_dshort1:
441   jp   .loop0
443 .done:
444   ld   sp,(savedSP)
445   ret
448 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
449 ;; blit map onto the screen using prebuild 'pushers'
451 blitMap:
452   xor  a
453   ; A is the index in screen line table
454   ; also it is used as 'stop flag', due
455   ; to the fact that we have to render
456   ; only 2/3 of the screen, which is
457   ; exactly 128 lines
458   ld   l,a
459   ld   h,a
460   ;ld   hl,%0001000100010001
461   ; HL is always 0 for 'pushers'
462   ; we can load it with some 'background' graphix
463   ; for funny fx
464   ; reset Z flag
465   ld   b,a
466   inc  b
467   ex   af,af'  ; switch to 'working' A
468   exx          ; switched to 'loop' register set
469   ld   (savedSP),sp
470   ; calculate number of visible lines in top tile
471   ld   bc,(plrXOffset)
472   ld   a,8
473   sub  b      ; plrYOffset
474   add  a,a
475   ld   (blitMapRowCountVar),a
476   ;
477   ld   a,c    ; plrXOffset
478   cp   4
479   ld   a,2Ch  ; INC L
480   jr   c,$+3
481   xor  a      ; NOP
482   ld   (blitMapShiftCmd),a
483   ; calc tilegfx addr (we have set of shifted tiles)
484   ld   a,c ; stored plrXOffset
485   and  3
486   add  a,a
487   add  a,shiftedTilesOfsTable%256
488   ld   l,a
489   IF sameseg(shiftedTilesOfsTable, shiftedTilesOfsTable+5)
490     ld   h,shiftedTilesOfsTable/256
491     ld   a,(hl)
492     inc  l
493   ELSE
494     ld   a,shiftedTilesOfsTable/256
495     adc  a,0
496     ld   h,a
497     ld   a,(hl)
498     inc  hl
499   ENDIF
500   ld   h,(hl)
501   ld   l,a
502   ld   (blitMapGfxOfs),hl
503   ;
504   ex   de,hl
505   ; DE: tiles offset
506   ld   hl,pusherJumpTable
507   ld   c,(hl)
508   inc  l
509   ld   b,(hl)
510   inc  l
511   ld   (pusherAddress),bc
512   ; load tile gfx offset to IY
513   ld   c,(hl)
514   inc  l
515   ld   b,(hl)
516   inc  l
517   ld   yl,c
518   ld   yh,b
519   ; load 2nd tile gfx offset to IX
520   ld   c,(hl)
521   inc  l
522   ld   b,(hl)
523   inc  l
524   ld   xl,c
525   ld   xh,b
526   ; shift tile gfx addresses according to player Y offset
527   ld   a,(plrYOffset)
528   add  a,a  ; *2
529   ld   c,a
530   add  a,a  ; *4
531   add  a,c  ; *6
532   ld   b,0
533   ld   c,a
534   ex   de,hl
535   add  hl,bc
536   add  hl,bc
537   ex   de,hl
538   ;
539   add  iy,de
540   add  ix,de
541   ;
542   ex   de,hl
543   ; HL: tile gfx base address
544   ; DE: trash
545 blitMapRowCountVar: equ $+1
546   ld   b,0
547   ; start drawing current row
548 blitMapNextLine:
549   ex   af,af'
550   jp   z,blitMapDone
551   ; load screen line address
552   ld   l,a
553   ld   h,scrRowsTable/256
554   ; move to next table item
555   inc  a
556   inc  a
557   ex   af,af'
558   ; load address
559   ld   sp,hl
560   pop  hl
561 blitMapShiftCmd:
562   nop  ; or inc l
563   exx
564   ; load tile graphics
565   ld   sp,iy
566   pop  bc
567   pop  de
568   pop  af
569   exx
570   ld   sp,hl       ; put screen address to SP
571   exx
572 pusherAddress: equ $+1
573   jp   0           ; self-patching code; jump to 'pusher'
574 blitMapPusherDone: ; 'pushers' will return here
575   ld   de,6        ; tiles gfx are 6x16
576   add  iy,de
577   add  ix,de
578   exx
579   djnz blitMapNextLine
580   ; move to next map row
581   ; DE: table with 'pusher' addresses and tile offsets
582   ; get next 'pusher' address
583   ld   a,(de)
584   ld   (pusherAddress),a
585   inc  e
586   ld   a,(de)
587   ld   (pusherAddress+1),a
588   inc  e
589 blitMapGfxOfs: equ $+1
590   ld   bc,0               ; tile grafix offset
591   ; get tile gfx addresses
592   ld   a,(de)
593   ld   yl,a
594   inc  e
595   ld   a,(de)
596   ld   yh,a
597   inc  e
598   add  iy,bc
599   ld   a,(de)
600   ld   xl,a
601   inc  e
602   ld   a,(de)
603   ld   xh,a
604   inc  e
605   add  ix,bc
606   ld   b,16  ; 16 lines of next tile row
607   jp   blitMapNextLine
608   ;
609 blitMapDone:
610   ld   sp,(savedSP)
611   ret
614 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
615 ;; part of code to get new graphics
616 ;; intended for copying
617 codeReloadTileGfx:
618   ld   (relGfxSavedSP),sp  ; 4 bytes
619   ld   sp,ix          ; 2 bytes
620   pop  bc             ; 1 byte
621   pop  de             ; 1 byte
622   pop  af             ; 1 byte
623   ld   sp,(relGfxSavedSP)  ; 4 bytes
624   ; total: 13 bytes
625 codeReloadTileGfxLen: equ $-codeReloadTileGfx
628 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
629 ;; calculate address in the map
630 ;; IN:
631 ;;   H: y
632 ;;   L: x
633 ;; OUT:
634 ;;   HL: map address
635 ;;   AF: dead
636 calcMapAddr:
637   srl  l
638   ld   a,h
639   rrca
640   rrca
641   rrca
642   ld   h,a
643   and  0E0h
644   or   l
645   ld   l,a
646   ld   a,h
647   and  1Fh
648   add  a,80h
649   ld   h,a
650   ret
653 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
655 buildPushers:
656   ld   hl,(mapX)
657   call calcMapAddr
658   or   a
659   ; up one row due to 'next map row' below
660   ld   bc,32
661   sbc  hl,bc
662   ld   (bldCurMapAddr),hl
663   ;
664   ld   hl,pusherStart
665   ld   (.bldPusherStartAddrVar),hl
666   ;
667   ld   hl,pusherJumpTable
668   ld   b,9  ; 9 tile rows
669 .bldPusherNextRow:
670   push bc
671   ; store current 'pusher' address
672 .bldPusherStartAddrVar: equ $+1
673   ld   de,0
674   ld   (hl),e
675   inc  l
676   ld   (hl),d
677   inc  l
678   push hl
679   push de
680   exx
681 @bldCurMapAddr: equ $+1
682   ; next map row
683   ld   hl,0
684   ld   de,32
685   add  hl,de
686   ; wrap y
687   ld   a,h
688   and  7
689   add  a,80h
690   ld   h,a
691   ;
692   ld   (bldCurMapAddr),hl
693   ; pop 'pusher' address
694   pop  de
695   ld   a,0FFh
696   ld   (bldCurTileBlockX2Var),a
697   ld   b,8  ; 8 bytes/16 tiles
698   ;
699   ld   a,(mapX)
700   and  1
701   jp   z,.bldEvenX
702   ; odd x
703 .bldNextMapByte:
704   ld   a,(hl)  ; map data
705   or   a
706   jr   nz,.bldNonEmptyTile
707   ld   a,#E5   ; PUSH HL (2 empty tiles)
708   ld   (de),a
709   inc  e
710 .bldStorePushAndBackOneMapByte:
711   ld   (de),a
712   inc  de
713   ; back one map byte, with wrapping
714   ld   a,l
715   and  0E0h
716   ld   c,a
717   ld   a,l
718   dec  a
719   and  1Fh
720   add  a,c
721   ld   l,a
722   djnz .bldNextMapByte
723   jp   .bldPusherDone
724 ; ---------------------------------------------------------------------------
725 .bldEvenX:
726   ; put only one tile instead of two
727   ld   a,(hl)  ; map data
728   or   a
729   jr   nz,.bldNonEmptyTileEX
730   ld   a,#E5   ; PUSH HL (empty tile)
731   jp   .bldStorePushAndBackOneMapByte
732 .bldNonEmptyTileEX:
733   and  0F0h
734   srl  a
735   srl  a
736   srl  a
737   ld   (bldCurTileBlockX2Var),a
738   call bldStoreTileBlockOffset
739   ld   a,(hl)  ; map data
740   push hl
741   and  0Fh     ; block type
742   add  a,a
743   add  a,pushCodes%256
744   ld   l,a
745   ld   h,pushCodes/256
746   jp   .bldCopyOnePush
747 ; ---------------------------------------------------------------------------
748 .bldNonEmptyTile:
749   and  0F0h
750   srl  a
751   srl  a
752   srl  a
753   ld   (bldCurTileBlockX2Var),a
754   call bldStoreTileBlockOffset
755   ld   a,(hl)
756   push hl
757   jr   .bldWeAreNotEmptyAnyway
758 .bldDoNextTiles:
759   ld   a,(hl)
760   push hl
761   or   a
762   jr   z,.bldItIsEmpty
763   push af
764   and  0F0h
765   srl  a
766   srl  a
767   srl  a
768   ld   c,a  ; new tileset
769 bldCurTileBlockX2Var: equ $+1
770   ld   a,0
771   cp   c
772   jp   z,.bldSameTileBlock
773   ld   a,c
774   ld   (bldCurTileBlockX2Var),a
775   call bldStoreTileBlockOffset
776   ; copy 'gfx switch' code
777   ld   a,b
778   push hl
779   ld   hl,codeReloadTileGfx
780   DUP  codeReloadTileGfxLen
781   ldi
782   EDUP
783   pop  hl
784   ld   b,a
785 .bldSameTileBlock:
786   pop  af
787 .bldWeAreNotEmptyAnyway:
788   and  0Fh
789 .bldItIsEmpty:
790   add  a,a
791   add  a,pushCodes%256
792   ld   l,a
793   ld   a,pushCodes/256
794   adc  a,0
795   ld   h,a
796   ld   a,(hl)
797   ld   (de),a
798   inc  de
799 .bldCopyOnePush:
800   inc  l
801   ld   a,(hl)
802   ld   (de),a
803   inc  de
804   pop  hl
805   ; previous map byte, with wrapping
806   ld   a,l
807   and  0E0h
808   ld   c,a
809   ld   a,l
810   dec  a
811   and  1Fh
812   add  a,c
813   ld   l,a
814   djnz .bldDoNextTiles
815 .bldPusherDone:
816   dec  de          ; remove one push (border)
817   ld   a,(mapX)
818   and  1
819   jr   z,$+3       ; skip next command
820   dec  de          ; remove another push (map is shifted by one tile)
821   ex   de,hl       ; HL: 'pusher' end
822   ; insert final JP
823   ld   (hl),0C3h   ; JP
824   inc  hl
825   ld   (hl),blitMapPusherDone%256
826   inc  hl
827   ld   (hl),blitMapPusherDone/256
828   inc  hl
829   ld   (.bldPusherStartAddrVar),hl  ; save this address
830   pop  hl          ; 'pusher' table
831   ; next table item
832   ld   a,l
833   add  a,4
834   ld   l,a
835   pop  bc
836   dec  b
837   jp   nz,.bldPusherNextRow
838   ret
840 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
842 bldStoreTileBlockOffset:
843   ;  A: tile block, 0-3
844   exx
845   ; DE: 'pusher' address
846   ; HL: pusher table
847   ex   de,hl
848   ; get tile block offset
849   ld   l,tileBlockOffsets%256
850   add  a,l
851   ;
852   ld   l,a
853   ld   a,tileBlockOffsets/256
854   adc  a,0
855   ld   h,a
856   ;
857   ld   c,(hl)
858   inc  hl
859   ld   b,(hl)
860   ex   de,hl
861   ; HL: pusher table
862   ; store tile block offset
863   ld   (hl),c
864   inc  hl
865   ld   (hl),b
866   inc  hl
867   exx
868   ret
871 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
873 ;; throwaways
874   org  #8000
875 firstTimeInit:
876   di
877   ld   sp,myfirstbyte
878   ;; set paging
879   ld   bc,#7FFD
880   ld   a,020
881   out  (c),a
882   ;;
883   ;ld   a,intrTable/256
884   ld   a,#39
885   ld   i,a
886   ld   a,#18
887   ld   (#FFFF),a  ; jr
888   ld   a,#C3      ; jp
889   ld   (#FFF4),a
890   ld   hl,IntrHandler
891   ld   (#FFF5),hl
892   im   2
893   ei
894   xor  a
895   ld   hl,#5800
896   ld   de,#5801
897   ld   bc,767
898   halt
899   di
900   ld   (hl),a
901   out  (254),a
902   ldir
903   ;call BuildScrLineTable
905 BuildScrLineTable:
906   ld   hl,scrRowsTable
907   ld   de,#401E
908   ld   b,128
909 .lineloop:
910   ld   (hl),e
911   inc  l
912   ld   (hl),d
913   inc  l
914   ; line down
915   inc  d
916   ld   a,d
917   and  #07
918   jr   nz,.downdone
919   ld   a,e
920   sub  #E0
921   ld   e,a
922   sbc  a,a
923   and  #F8
924   add  a,d
925   ld   d,a
926 .downdone:
927   djnz .lineloop
928   ;ret
929   jp   mainEntry