some changes
[enJine.git] / main.zas
blob200fa880ab9a4a4740069b2b335577717c49a4f6
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   de,heliframe0
378   ld   a,(heliPhase)
379   xor  #01
380   ld   (heliPhase),a
381   jp   nz,.hf0ok
382   ld   de,heliframe1
383 .hf0ok:
384   ; first 8 lines
385   ld   b,4
386 .loop0:
387   DUP 6
388   ld   a,(de)
389   or   (hl)
390   ld   (hl),a
391   inc  de
392   inc  l
393   EDUP
394   inc  h
395   DUP 6
396   dec  l
397   ld   a,(de)
398   or   (hl)
399   ld   (hl),a
400   inc  de
401   EDUP
402   inc  h
403   djnz .loop0
405   ; second 8 lines
406   ld   a,l
407   sub  #E0  ; add 32
408   ld   l,a
409   sbc  a,a
410   and  #F8
411   add  a,h
412   ld   h,a
414   ld   b,4
415 .loop1:
416   DUP 6
417   ld   a,(de)
418   or   (hl)
419   ld   (hl),a
420   inc  de
421   inc  l
422   EDUP
423   inc  h
424   DUP 6
425   dec  l
426   ld   a,(de)
427   or   (hl)
428   ld   (hl),a
429   inc  de
430   EDUP
431   inc  h
432   djnz .loop1
434   ; last 2 lines
435   ld   a,l
436   sub  #E0  ; add 32
437   ld   l,a
438   sbc  a,a
439   and  #F8
440   add  a,h
441   ld   h,a
442   DUP 6
443   ld   a,(de)
444   or   (hl)
445   ld   (hl),a
446   inc  de
447   inc  l
448   EDUP
449   inc  h
450   DUP 6
451   dec  l
452   ld   a,(de)
453   or   (hl)
454   ld   (hl),a
455   inc  de
456   EDUP
458   ret
461 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
462 ;; blit map onto the screen using prebuild 'pushers'
464 blitMap:
465   xor  a
466   ; A is the index in screen line table
467   ; also it is used as 'stop flag', due
468   ; to the fact that we have to render
469   ; only 2/3 of the screen, which is
470   ; exactly 128 lines
471   ld   l,a
472   ld   h,a
473   ;ld   hl,%0001000100010001
474   ; HL is always 0 for 'pushers'
475   ; we can load it with some 'background' graphix
476   ; for funny fx
477   ; reset Z flag
478   ld   b,a
479   inc  b
480   ex   af,af'  ; switch to 'working' A
481   exx          ; switched to 'loop' register set
482   ld   (savedSP),sp
483   ; calculate number of visible lines in top tile
484   ld   bc,(plrXOffset)
485   ld   a,8
486   sub  b      ; plrYOffset
487   add  a,a
488   ld   (blitMapRowCountVar),a
489   ;
490   ld   a,c    ; plrXOffset
491   cp   4
492   ld   a,2Ch  ; INC L
493   jr   c,$+3
494   xor  a      ; NOP
495   ld   (blitMapShiftCmd),a
496   ; calc tilegfx addr (we have set of shifted tiles)
497   ld   a,c ; stored plrXOffset
498   and  3
499   add  a,a
500   add  a,shiftedTilesOfsTable%256
501   ld   l,a
502   IF sameseg(shiftedTilesOfsTable, shiftedTilesOfsTable+5)
503     ld   h,shiftedTilesOfsTable/256
504     ld   a,(hl)
505     inc  l
506   ELSE
507     ld   a,shiftedTilesOfsTable/256
508     adc  a,0
509     ld   h,a
510     ld   a,(hl)
511     inc  hl
512   ENDIF
513   ld   h,(hl)
514   ld   l,a
515   ld   (blitMapGfxOfs),hl
516   ;
517   ex   de,hl
518   ; DE: tiles offset
519   ld   hl,pusherJumpTable
520   ld   c,(hl)
521   inc  l
522   ld   b,(hl)
523   inc  l
524   ld   (pusherAddress),bc
525   ; load tile gfx offset to IY
526   ld   c,(hl)
527   inc  l
528   ld   b,(hl)
529   inc  l
530   ld   yl,c
531   ld   yh,b
532   ; load 2nd tile gfx offset to IX
533   ld   c,(hl)
534   inc  l
535   ld   b,(hl)
536   inc  l
537   ld   xl,c
538   ld   xh,b
539   ; shift tile gfx addresses according to player Y offset
540   ld   a,(plrYOffset)
541   add  a,a  ; *2
542   ld   c,a
543   add  a,a  ; *4
544   add  a,c  ; *6
545   ld   b,0
546   ld   c,a
547   ex   de,hl
548   add  hl,bc
549   add  hl,bc
550   ex   de,hl
551   ;
552   add  iy,de
553   add  ix,de
554   ;
555   ex   de,hl
556   ; HL: tile gfx base address
557   ; DE: trash
558 blitMapRowCountVar: equ $+1
559   ld   b,0
560   ; start drawing current row
561 blitMapNextLine:
562   ex   af,af'
563   jp   z,blitMapDone
564   ; load screen line address
565   ld   l,a
566   ld   h,scrRowsTable/256
567   ; move to next table item
568   inc  a
569   inc  a
570   ex   af,af'
571   ; load address
572   ld   sp,hl
573   pop  hl
574 blitMapShiftCmd:
575   nop  ; or inc l
576   exx
577   ; load tile graphics
578   ld   sp,iy
579   pop  bc
580   pop  de
581   pop  af
582   exx
583   ld   sp,hl       ; put screen address to SP
584   exx
585 pusherAddress: equ $+1
586   jp   0           ; self-patching code; jump to 'pusher'
587 blitMapPusherDone: ; 'pushers' will return here
588   ld   de,6        ; tiles gfx are 6x16
589   add  iy,de
590   add  ix,de
591   exx
592   djnz blitMapNextLine
593   ; move to next map row
594   ; DE: table with 'pusher' addresses and tile offsets
595   ; get next 'pusher' address
596   ld   a,(de)
597   ld   (pusherAddress),a
598   inc  e
599   ld   a,(de)
600   ld   (pusherAddress+1),a
601   inc  e
602 blitMapGfxOfs: equ $+1
603   ld   bc,0               ; tile grafix offset
604   ; get tile gfx addresses
605   ld   a,(de)
606   ld   yl,a
607   inc  e
608   ld   a,(de)
609   ld   yh,a
610   inc  e
611   add  iy,bc
612   ld   a,(de)
613   ld   xl,a
614   inc  e
615   ld   a,(de)
616   ld   xh,a
617   inc  e
618   add  ix,bc
619   ld   b,16  ; 16 lines of next tile row
620   jp   blitMapNextLine
621   ;
622 blitMapDone:
623   ld   sp,(savedSP)
624   ret
627 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
628 ;; part of code to get new graphics
629 ;; intended for copying
630 codeReloadTileGfx:
631   ld   (relGfxSavedSP),sp  ; 4 bytes
632   ld   sp,ix          ; 2 bytes
633   pop  bc             ; 1 byte
634   pop  de             ; 1 byte
635   pop  af             ; 1 byte
636   ld   sp,(relGfxSavedSP)  ; 4 bytes
637   ; total: 13 bytes
638 codeReloadTileGfxLen: equ $-codeReloadTileGfx
641 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
642 ;; calculate address in the map
643 ;; IN:
644 ;;   H: y
645 ;;   L: x
646 ;; OUT:
647 ;;   HL: map address
648 ;;   AF: dead
649 calcMapAddr:
650   srl  l
651   ld   a,h
652   rrca
653   rrca
654   rrca
655   ld   h,a
656   and  0E0h
657   or   l
658   ld   l,a
659   ld   a,h
660   and  1Fh
661   add  a,80h
662   ld   h,a
663   ret
666 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
668 buildPushers:
669   ld   hl,(mapX)
670   call calcMapAddr
671   or   a
672   ; up one row due to 'next map row' below
673   ld   bc,32
674   sbc  hl,bc
675   ld   (bldCurMapAddr),hl
676   ;
677   ld   hl,pusherStart
678   ld   (.bldPusherStartAddrVar),hl
679   ;
680   ld   hl,pusherJumpTable
681   ld   b,9  ; 9 tile rows
682 .bldPusherNextRow:
683   push bc
684   ; store current 'pusher' address
685 .bldPusherStartAddrVar: equ $+1
686   ld   de,0
687   ld   (hl),e
688   inc  l
689   ld   (hl),d
690   inc  l
691   push hl
692   push de
693   exx
694 @bldCurMapAddr: equ $+1
695   ; next map row
696   ld   hl,0
697   ld   de,32
698   add  hl,de
699   ; wrap y
700   ld   a,h
701   and  7
702   add  a,80h
703   ld   h,a
704   ;
705   ld   (bldCurMapAddr),hl
706   ; pop 'pusher' address
707   pop  de
708   ld   a,0FFh
709   ld   (bldCurTileBlockX2Var),a
710   ld   b,8  ; 8 bytes/16 tiles
711   ;
712   ld   a,(mapX)
713   and  1
714   jp   z,.bldEvenX
715   ; odd x
716 .bldNextMapByte:
717   ld   a,(hl)  ; map data
718   or   a
719   jr   nz,.bldNonEmptyTile
720   ld   a,#E5   ; PUSH HL (2 empty tiles)
721   ld   (de),a
722   inc  e
723 .bldStorePushAndBackOneMapByte:
724   ld   (de),a
725   inc  de
726   ; back one map byte, with wrapping
727   ld   a,l
728   and  0E0h
729   ld   c,a
730   ld   a,l
731   dec  a
732   and  1Fh
733   add  a,c
734   ld   l,a
735   djnz .bldNextMapByte
736   jp   .bldPusherDone
737 ; ---------------------------------------------------------------------------
738 .bldEvenX:
739   ; put only one tile instead of two
740   ld   a,(hl)  ; map data
741   or   a
742   jr   nz,.bldNonEmptyTileEX
743   ld   a,#E5   ; PUSH HL (empty tile)
744   jp   .bldStorePushAndBackOneMapByte
745 .bldNonEmptyTileEX:
746   and  0F0h
747   srl  a
748   srl  a
749   srl  a
750   ld   (bldCurTileBlockX2Var),a
751   call bldStoreTileBlockOffset
752   ld   a,(hl)  ; map data
753   push hl
754   and  0Fh     ; block type
755   add  a,a
756   add  a,pushCodes%256
757   ld   l,a
758   ld   h,pushCodes/256
759   jp   .bldCopyOnePush
760 ; ---------------------------------------------------------------------------
761 .bldNonEmptyTile:
762   and  0F0h
763   srl  a
764   srl  a
765   srl  a
766   ld   (bldCurTileBlockX2Var),a
767   call bldStoreTileBlockOffset
768   ld   a,(hl)
769   push hl
770   jr   .bldWeAreNotEmptyAnyway
771 .bldDoNextTiles:
772   ld   a,(hl)
773   push hl
774   or   a
775   jr   z,.bldItIsEmpty
776   push af
777   and  0F0h
778   srl  a
779   srl  a
780   srl  a
781   ld   c,a  ; new tileset
782 bldCurTileBlockX2Var: equ $+1
783   ld   a,0
784   cp   c
785   jp   z,.bldSameTileBlock
786   ld   a,c
787   ld   (bldCurTileBlockX2Var),a
788   call bldStoreTileBlockOffset
789   ; copy 'gfx switch' code
790   ld   a,b
791   push hl
792   ld   hl,codeReloadTileGfx
793   DUP  codeReloadTileGfxLen
794   ldi
795   EDUP
796   pop  hl
797   ld   b,a
798 .bldSameTileBlock:
799   pop  af
800 .bldWeAreNotEmptyAnyway:
801   and  0Fh
802 .bldItIsEmpty:
803   add  a,a
804   add  a,pushCodes%256
805   ld   l,a
806   ld   a,pushCodes/256
807   adc  a,0
808   ld   h,a
809   ld   a,(hl)
810   ld   (de),a
811   inc  de
812 .bldCopyOnePush:
813   inc  l
814   ld   a,(hl)
815   ld   (de),a
816   inc  de
817   pop  hl
818   ; previous map byte, with wrapping
819   ld   a,l
820   and  0E0h
821   ld   c,a
822   ld   a,l
823   dec  a
824   and  1Fh
825   add  a,c
826   ld   l,a
827   djnz .bldDoNextTiles
828 .bldPusherDone:
829   dec  de          ; remove one push (border)
830   ld   a,(mapX)
831   and  1
832   jr   z,$+3       ; skip next command
833   dec  de          ; remove another push (map is shifted by one tile)
834   ex   de,hl       ; HL: 'pusher' end
835   ; insert final JP
836   ld   (hl),0C3h   ; JP
837   inc  hl
838   ld   (hl),blitMapPusherDone%256
839   inc  hl
840   ld   (hl),blitMapPusherDone/256
841   inc  hl
842   ld   (.bldPusherStartAddrVar),hl  ; save this address
843   pop  hl          ; 'pusher' table
844   ; next table item
845   ld   a,l
846   add  a,4
847   ld   l,a
848   pop  bc
849   dec  b
850   jp   nz,.bldPusherNextRow
851   ret
853 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
855 bldStoreTileBlockOffset:
856   ;  A: tile block, 0-3
857   exx
858   ; DE: 'pusher' address
859   ; HL: pusher table
860   ex   de,hl
861   ; get tile block offset
862   ld   l,tileBlockOffsets%256
863   add  a,l
864   ;
865   ld   l,a
866   ld   a,tileBlockOffsets/256
867   adc  a,0
868   ld   h,a
869   ;
870   ld   c,(hl)
871   inc  hl
872   ld   b,(hl)
873   ex   de,hl
874   ; HL: pusher table
875   ; store tile block offset
876   ld   (hl),c
877   inc  hl
878   ld   (hl),b
879   inc  hl
880   exx
881   ret
884 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
886 ;; throwaways
887   org  #8000
888 firstTimeInit:
889   di
890   ld   sp,myfirstbyte
891   ;; set paging
892   ld   bc,#7FFD
893   ld   a,020
894   out  (c),a
895   ;;
896   ;ld   a,intrTable/256
897   ld   a,#39
898   ld   i,a
899   ld   a,#18
900   ld   (#FFFF),a  ; jr
901   ld   a,#C3      ; jp
902   ld   (#FFF4),a
903   ld   hl,IntrHandler
904   ld   (#FFF5),hl
905   im   2
906   ei
907   xor  a
908   ld   hl,#5800
909   ld   de,#5801
910   ld   bc,767
911   halt
912   di
913   ld   (hl),a
914   out  (254),a
915   ldir
916   ;call BuildScrLineTable
918 BuildScrLineTable:
919   ld   hl,scrRowsTable
920   ld   de,#401E
921   ld   b,128
922 .lineloop:
923   ld   (hl),e
924   inc  l
925   ld   (hl),d
926   inc  l
927   ; line down
928   inc  d
929   ld   a,d
930   and  #07
931   jr   nz,.downdone
932   ld   a,e
933   sub  #E0
934   ld   e,a
935   sbc  a,a
936   and  #F8
937   add  a,d
938   ld   d,a
939 .downdone:
940   djnz .lineloop
941   ;ret
942   jp   mainEntry