added 'helicopter" sprite
[enJine.git] / main.zas
blob453e2b5b9b2726dfb13557113cff91c6315e87ed
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
63   ;call buildPushers
65   ei
66   halt
67   xor  a
68   ld   (intrCnt),a
70 MainLoop:
71   call buildPushers
72   ld   a,(intrCnt)
73   cp   1
74   jr   nc,$+3
75   halt
76   ;
77   ld   hl,IntrHandlerSmall
78   ld   (#FFF5),hl
79   xor  a
80   ld   (intrCnt),a
81   halt
82   ;
83   call blitMap
84   ld   hl,IntrHandler
85   ld   (#FFF5),hl
86   call blitHeli
87   ;
88 .waitformove:
89   call WinStick.readMoves
90   jr   z,MainLoop
92 .somethingpressed:
93   ; C,A: state (LRUDF; F is #01)
94   bit  4,c
95   jr   z,.notleft
96   ld   a,(plrXOffset)
97   sub  a,1
98   jr   nc,.leftok
99   ld   a,(mapX)
100   dec  a
101   and  #3f
102   ld   (mapX),a
103   ld   a,7
104 .leftok:
105   ld   (plrXOffset),a
106 .notleft:
108   bit  3,c
109   jr   z,.notright
110   ld   a,(plrXOffset)
111   inc  a
112   and  #07
113   jr   nz,.rightok
114   ld   a,(mapX)
115   inc  a
116   and  #3f
117   ld   (mapX),a
118   xor  a
119 .rightok:
120   ld   (plrXOffset),a
121 .notright:
123   bit  2,c
124   jr   z,.notup
125   ld   a,(plrYOffset)
126   sub  a,1
127   jr   nc,.upok
128   ld   a,(mapY)
129   dec  a
130   and  #3f
131   ld   (mapY),a
132   ld   a,7
133 .upok:
134   ld   (plrYOffset),a
135 .notup:
137   bit  1,c
138   jr   z,.notdown
139   ld   a,(plrYOffset)
140   inc  a
141   and  #07
142   jr   nz,.downok
143   ld   a,(mapY)
144   inc  a
145   and  #3f
146   ld   (mapY),a
147   xor  a
148 .downok:
149   ld   (plrYOffset),a
150 .notdown:
152   jp   MainLoop
155 prepareAttrs:
156   ld   hl,#5800
157   ld   de,#5801
158   ld   bc,767
159   ld   (hl),0
160   ldir
161   ld   hl,#5800+3
162   ld   b,16
163   ld   a,6
164 .fillit:
165   push bc
166   ld   (.filladdr),hl
167 .filladdr: equ $+1
168   ld   de,0
169   inc  de
170   ld   bc,26
171   ld   (hl),a
172   ldir
173   ld   hl,(.filladdr)
174   ld   de,32
175   add  hl,de
176   pop  bc
177   djnz .fillit
178   cp   a,6
179   ret  nz
180   ld   a,1
181   ld   b,8
182   jr   .fillit
183   ;ret
185   include <winstick>
188 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
190 PutLetter:
191   ld   l,a
192   ld   h,0
193   add  hl,hl
194   add  hl,hl
195   add  hl,hl
196   ld   de,#3C00
197   add  hl,de
198   ld   de,#4000+4096+6*32+30
199   ld   b,4
200   ld   c,d
201 .loop0:
202   ld   a,(hl)
203   rrca
204   or   (hl)
205   ld   (de),a
206   inc  hl
207   inc  d
208   inc  d
209   djnz .loop0
210   ld   a,e
211   add  a,32
212   ld   e,a
213   ld   a,0
214   adc  a,c
215   ld   d,a
216   ld   b,4
217 .loop1:
218   ld   a,(hl)
219   rrca
220   or   (hl)
221   ld   (de),a
222   inc  hl
223   inc  d
224   inc  d
225   djnz .loop1
226   ret
228 PutLetterRev:
229   ld   l,a
230   ld   h,0
231   add  hl,hl
232   add  hl,hl
233   add  hl,hl
234   ld   de,#3C00
235   add  hl,de
236   ld   de,#4000+4096+6*32+30
237   ld   b,4
238   ld   c,d
239 .loop0:
240   ld   a,(hl)
241   rrca
242   or   (hl)
243   ;
244   push de
245   ld   e,a
246   xor  a
247   DUP 8
248   rl   e
249   rra
250   EDUP
251   pop  de
252   ;
253   ld   (de),a
254   inc  hl
255   inc  d
256   inc  d
257   djnz .loop0
258   ld   a,e
259   add  a,32
260   ld   e,a
261   ld   a,0
262   adc  a,c
263   ld   d,a
264   ld   b,4
265 .loop1:
266   ld   a,(hl)
267   rrca
268   or   (hl)
269   ;
270   push de
271   ld   e,a
272   xor  a
273   DUP 8
274   rl   e
275   rra
276   EDUP
277   pop  de
278   ;
279   ld   (de),a
280   inc  hl
281   inc  d
282   inc  d
283   djnz .loop1
284   ret
286 ScrollLetters:
287   ld   hl,#4000+4096+6*32+30
288   ld   c,2
289 .scrollLine:
290   push hl
291   ld   b,28
292   ld   e,0
293 .scrollByte:
294   ld   a,(hl)
295   ld   d,a
296   rl   e
297   rla
298   rl   e
299   rla
300   ld   (hl),a
301   ld   e,d
302   dec  hl
303   djnz .scrollByte
304   ;
305   pop  hl
306   inc  h
307   ld   a,h
308   and  #07
309   jr   nz,.scrollLine
310   ld   a,l
311   sub  #E0
312   ld   l,a
313   sbc  a,a
314   and  #F8
315   add  a,h
316   ld   h,a
317   ;
318   dec  c
319   jr   nz,.scrollLine
320   ret
322 IntrHandlerSmall:
323   ei
324   ret
326 IntrHandler:
327   push  af
328 @intrCnt: equ $+1
329   ld    a,0
330   inc   a
331   ld    (intrCnt),a
332   ;
333   push  bc,de,hl
334 @scrollStep: equ $+1
335   ld    a,1
336   dec   a
337   jr    nz,.notPut
338 .takeNextChar:
339 @scrollTextPtr: equ $+1
340   ld    hl,scrollText-1
341   inc   hl
342   ld    a,(hl)
343   or    a
344   jr    nz,.letterok
345   ld    hl,scrollText
346   ld    a,(hl)
347 .letterok:
348   ld    (scrollTextPtr),hl
349   cp    1
350   jr    nz,.notone
351   ld    hl,PutLetterRev
352 .newPrinter:
353   ld    (.putLetterAddr),hl
354   jr    .takeNextChar
355 .notone:
356   cp    2
357   jr    nz,.nottwo
358   ld    hl,PutLetter
359   jr    .newPrinter
360 .nottwo:
361 .putLetterAddr: equ $+1
362   call  PutLetter
363   ld    a,4
364 .notPut:
365   ld    (scrollStep),a
366   call  ScrollLetters
367   ;
368   pop   hl,de,bc
369 @intrQuit:
370   pop   af
371   ei
372   ret
374 scrollText:
375   defm "            "
376   defm "Welcome to ", 1, "eniJne", 2, " demo -- 8-dir blitting engine!  "
377   defm "You can use cursor keys or OPQA to move around.  "
378   defm "Some enJine techinfo: "
379   defm "level blitting with 2px horizontal step and 1px vertical step; "
380   defm "level map size limited only by free memory (i used 64x64 FireFly map in this demo); "
381   defm "rebuilding blitter data and blitting the map takes one frame (+/- some ticks %-); "
382   defm "map is stored in plain left-to-right up-to-down format, so checks against map tiles are easy; "
383   defm "map redrawn each 2 frames, so one can easily do tile animations by switching tile sets; "
384   defm "more that one tile set per level allowed (but you will need memory to store pre-shifted tiles); "
385   defm "and much more (and probably much less than you expecting, 'cause Speccy is not your multicore PC %-).  "
386   defm "Code: Ketmar // Vampire Avalon       "
387   defm "Code: ", 1, "fffimS affoJ", 2, "       "
388   defm "Coming soon this summer: fast-paced game made with enJine (or at least i hope it is coming...). "
389   defm "enJine sources will be released too!          "
390   defm "Dedicated to ", 1, "fffimS affoJ", 2, "."
391   defm "                "
392   defb 0
393   defm "JOFFA!"
395 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
396 ;; build shifted tiles
398 prepareShiftedTiles:
399   IF 0
400     ; tiles are not packed
401     ld   de,shiftedTilesBuf
402     push de
403     ; first: unshifted
404     ld   hl,tilesBase
405     ld   bc,6*16*4
406     ldir
407     pop  hl
408   ELSE
409     ; tiles are packed
410     ld   hl,shiftedTilesBuf
411     ld   de,shiftedTilesBuf+6*16*4
412   ENDIF
413   ;
414   ld   a,3  ; 3 shifts left
415 .shiftNextSet:
416   ex   af,af'
417   ; HL: addr of previous tileset
418   ; DE: addr of current tileset
419   push de
420   push de
421   ld   bc,6*16*4
422   ldir
423   ; previous tiles copied, now shift
424   pop  hl      ; start of the current block
425   ld   c,16*4  ; lines
426 .shiftNextLine:
427   ld   e,b     ; B is always 0 here
428   ld   b,6
429 .shiftNextByte:
430   ld   a,(hl)
431   ld   d,a
432   rr   e
433   rra
434   rr   e
435   rra
436   ld   (hl),a
437   inc  hl
438   ld   e,d
439   djnz .shiftNextByte
440   dec  c
441   jr   nz,.shiftNextLine
442   ex   de,hl  ; now DE is the new dest address
443   pop  hl     ; current set address
444   ex   af,af'
445   dec  a
446   jr   nz,.shiftNextSet
447   ret
449 exo_mapbasebits: equ #4000  ; 156 bytes
450   include <deexo.inc>
452 tilesBase00:
453   incbin "bdata/tiles_blobs.exo"
454 map00:
455   incbin "bdata/map00.exo"
457 mapData: equ #8000
458 mapSize: equ #0800
460   org  #8800
461 pusherStart: equ $  ; #8800
462                     ; max pusher end will be: #8eff
464   org  #8f00
465 scrRowsTable: ds 128*2
467   ; #9000
468 shiftedTilesBuf: ds 16*4*6*4
469   ; #9600
471 tileBlockOffsets:
472   dw shiftedTilesBuf+0*6*16
473   dw shiftedTilesBuf+1*6*16
474   dw shiftedTilesBuf+2*6*16
475   dw shiftedTilesBuf+3*6*16
477 ;0  1  2  3
478 ;bc de af hl
479 pushCodes:
480   db 0E5h,0E5h  ; 0 : push hl, push hl : 33
481   db 0D5h,0C5h  ; 1 : push de, push bc : 01
482   db 0D5h,0D5h  ; 2 : push de, push de : 11
483   db 0F5h,0D5h  ; 3 : push af, push de : 12
484   db 0C5h,0E5h  ; 4 : push bc, push hl : 30
485   db 0E5h,0F5h  ; 5 : push hl, push af : 23
486   db 0F5h,0C5h  ; 6 : push af, push bc : 02
487   db 0E5h,0C5h  ; 7 : push hl, push bc : 03
488   db 0F5h,0E5h  ; 8 : push af, push hl : 32
489   db 0F5h,0F5h  ; 9 : push af, push af : 22
490   db 0C5h,0C5h  ;10 : push bc, push bc : 00
491   db 0D5h,0F5h  ;11 : push de, push af : 21
492   db 0C5h,0D5h  ;12 : push bc, push de : 10
493   db 0E5h,0D5h  ;13 : push hl, push de : 13
494   db 0D5h,0E5h  ;14 : push de, push hl : 31
495   db 0C5h,0F5h  ;15 : push bc, push af : 20
497 ; jump table for screen pushers
498 ; addr, tilesofs, 2ndtilesofs
499 pusherJumpTable:
500   ds 3*2*9
502 shiftedTilesOfsTable:
503   dw  3*6*16*4
504   dw  2*6*16*4
505   dw  1*6*16*4
506   dw  0*6*16*4
509 plrXOffset: db 0  ; player X offset in the tile (0-7): in 2 pixels
510 plrYOffset: db 0  ; player Y offset in the tile (0-28; step: 4); (0-7): in 2 pixels
511 mapX: db 0
512 mapY: db 0
514 savedSP: dw 0
515 relGfxSavedSP: dw 0
517   defm "JOFFA!"
519 heliPhase: db 0
521   include "helispr.zas"
523 blitHeli:
524   ld   de,heliframe0
525   ld   a,(heliPhase)
526   xor  #01
527   ld   (heliPhase),a
528   jp   nz,.hf0ok
529   ld   de,heliframe1
530 .hf0ok:
531   ; first 8 lines
532   ld   b,4
533   ld   hl,#40EE
534 .loop0:
535   DUP 6
536   ld   a,(de)
537   or   (hl)
538   ld   (hl),a
539   inc  de
540   inc  l
541   EDUP
542   inc  h
543   DUP 6
544   dec  l
545   ld   a,(de)
546   or   (hl)
547   ld   (hl),a
548   inc  de
549   EDUP
550   inc  h
551   djnz .loop0
552   ; second 8 lines
553   ;ld   hl,#480E
554   ld   h,#48
555   ld   b,4
556 .loop1:
557   DUP 6
558   ld   a,(de)
559   or   (hl)
560   ld   (hl),a
561   inc  de
562   inc  l
563   EDUP
564   inc  h
565   DUP 6
566   dec  l
567   ld   a,(de)
568   or   (hl)
569   ld   (hl),a
570   inc  de
571   EDUP
572   inc  h
573   djnz .loop1
574   ret
576 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
577 ;; blit map onto the screen using prebuild 'pushers'
579 blitMap:
580   xor  a
581   inc  b ; reset Z flag
582   ; A is the index in screen line table
583   ; also it is used as 'stop flag', due
584   ; to the fact that we have to render
585   ; only 2/3 of the screen, which is
586   ; exactly 128 lines
587   ld   l,a
588   ld   h,a
589   ;ld   hl,%0001000100010001
590   ; HL is always 0 for 'pushers'
591   ; we can load it with some 'background' graphix
592   ; for funny fx
593   ex   af,af'  ; switch to 'working' A
594   exx          ; switched to 'loop' register set
595   ld   (savedSP),sp
596   ; calculate number of visible lines in top tile
597   ld   bc,(plrXOffset)
598   ld   a,8
599   sub  b      ; plrYOffset
600   add  a,a
601   ld   (blitMapRowCountVar),a
602   ;
603   ld   a,c    ; plrXOffset
604   cp   4
605   ld   a,2Ch  ; INC L
606   jr   c,$+4
607   ld   a,0    ; NOP
608   ld   (blitMapShiftCmd),a
609   ; calc tilegfx addr (we have set of shifted tiles)
610   ld   a,c ; stored plrXOffset
611   and  3
612   add  a,a
613   add  a,shiftedTilesOfsTable%256
614   ld   l,a
615   IF (shiftedTilesOfsTable+5)/256 != shiftedTilesOfsTable/256
616     ld   a,shiftedTilesOfsTable/256
617     adc  a,0
618     ld   h,a
619     ld   a,(hl)
620     inc  hl
621   ELSE
622     ld   h,shiftedTilesOfsTable/256
623     ld   a,(hl)
624     inc  l
625   ENDIF
626   ld   h,(hl)
627   ld   l,a
628   ld   (blitMapGfxOfs),hl
629   ;
630   ex   de,hl
631   ; DE: tiles offset
632   ld   hl,pusherJumpTable
633   ld   c,(hl)
634   inc  l
635   ld   b,(hl)
636   inc  l
637   ld   (pusherAddress),bc
638   ; load tile gfx offset to IY
639   ld   c,(hl)
640   inc  l
641   ld   b,(hl)
642   inc  l
643   ld   yl,c
644   ld   yh,b
645   ; load 2nd tile gfx offset to IX
646   ld   c,(hl)
647   inc  l
648   ld   b,(hl)
649   inc  l
650   ld   xl,c
651   ld   xh,b
652   ; shift tile gfx addresses according to player Y offset
653   ld   a,(plrYOffset)
654   add  a,a  ; *2
655   ld   c,a
656   add  a,a  ; *4
657   add  a,c  ; *6
658   ld   b,0
659   ld   c,a
660   ex   de,hl
661   add  hl,bc
662   add  hl,bc
663   ex   de,hl
664   ;
665   add  iy,de
666   add  ix,de
667   ;
668   ex   de,hl
669   ; HL: tile gfx base address
670   ; DE: trash
671 blitMapRowCountVar: equ $+1
672   ld   b,0
673   ; start drawing current row
674 blitMapNextLine:
675   ex   af,af'
676   jp   z,blitMapDone
677   ; load screen line address
678   ld   l,a
679   ld   h,scrRowsTable/256
680   ; move to next table item
681   inc  a
682   inc  a
683   ex   af,af'
684   ; load address
685   ld   sp,hl
686   pop  hl
687 blitMapShiftCmd:
688   nop  ; or inc l
689   exx
690   ; load tile graphics
691   ld   sp,iy
692   pop  bc
693   pop  de
694   pop  af
695   exx
696   ld   sp,hl       ; put screen address to SP
697   exx
698 pusherAddress: equ $+1
699   jp   0           ; self-patching code; jump to 'pusher'
700 blitMapPusherDone: ; 'pushers' will return here
701   ld   de,6        ; tiles gfx are 6x16
702   add  iy,de
703   add  ix,de
704   exx
705   djnz blitMapNextLine
706   ; move to next map row
707   ; DE: table with 'pusher' addresses and tile offsets
708   ; get next 'pusher' address
709   ld   a,(de)
710   ld   (pusherAddress),a
711   inc  e
712   ld   a,(de)
713   ld   (pusherAddress+1),a
714   inc  e
715 blitMapGfxOfs: equ $+1
716   ld   bc,0               ; tile grafix offset
717   ; get tile gfx addresses
718   ld   a,(de)
719   ld   yl,a
720   inc  e
721   ld   a,(de)
722   ld   yh,a
723   inc  e
724   add  iy,bc
725   ld   a,(de)
726   ld   xl,a
727   inc  e
728   ld   a,(de)
729   ld   xh,a
730   inc  e
731   add  ix,bc
732   ld   b,16  ; 16 lines of next tile row
733   jp   blitMapNextLine
734   ;
735 blitMapDone:
736   ld   sp,(savedSP)
737   ret
740 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
741 ;; part of code to get new graphics
742 ;; intended for copying
743 codeReloadTileGfx:
744   ld   (relGfxSavedSP),sp  ; 4 bytes
745   ld   sp,ix          ; 2 bytes
746   pop  bc             ; 1 byte
747   pop  de             ; 1 byte
748   pop  af             ; 1 byte
749   ld   sp,(relGfxSavedSP)  ; 4 bytes
750   ; total: 13 bytes
751 codeReloadTileGfxLen: equ $-codeReloadTileGfx
754 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
755 ;; calculate address in the map
756 ;; IN:
757 ;;   H: y
758 ;;   L: x
759 ;; OUT:
760 ;;   HL: map address
761 ;;   AF: dead
762 calcMapAddr:
763   srl  l
764   ld   a,h
765   rrca
766   rrca
767   rrca
768   ld   h,a
769   and  0E0h
770   or   l
771   ld   l,a
772   ld   a,h
773   and  1Fh
774   add  a,80h
775   ld   h,a
776   ret
779 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
781 buildPushers:
782   ld   hl,(mapX)
783   call calcMapAddr
784   or   a
785   ; up one row due to 'next map row' below
786   ld   bc,32
787   sbc  hl,bc
788   ld   (bldCurMapAddr),hl
789   ;
790   ld   hl,pusherStart
791   ld   (.bldPusherStartAddrVar),hl
792   ;
793   ld   hl,pusherJumpTable
794   ld   b,9  ; 9 tile rows
795 .bldPusherNextRow:
796   push bc
797   ; store current 'pusher' address
798 .bldPusherStartAddrVar: equ $+1
799   ld   de,0
800   ld   (hl),e
801   inc  l
802   ld   (hl),d
803   inc  l
804   push hl
805   push de
806   exx
807 @bldCurMapAddr: equ $+1
808   ; next map row
809   ld   hl,0
810   ld   de,32
811   add  hl,de
812   ; wrap y
813   ld   a,h
814   and  7
815   add  a,80h
816   ld   h,a
817   ;
818   ld   (bldCurMapAddr),hl
819   ; pop 'pusher' address
820   pop  de
821   ld   a,0FFh
822   ld   (bldCurTileBlockX2Var),a
823   ld   b,8  ; 8 bytes/16 tiles
824   ;
825   ld   a,(mapX)
826   and  1
827   jp   z,.bldEvenX
828   ; odd x
829 .bldNextMapByte:
830   ld   a,(hl)  ; map data
831   or   a
832   jr   nz,.bldNonEmptyTile
833   ld   a,#E5   ; PUSH HL (2 empty tiles)
834   ld   (de),a
835   inc  e
836 .bldStorePushAndBackOneMapByte:
837   ld   (de),a
838   inc  de
839   ; back one map byte, with wrapping
840   ld   a,l
841   and  0E0h
842   ld   c,a
843   ld   a,l
844   dec  a
845   and  1Fh
846   add  a,c
847   ld   l,a
848   djnz .bldNextMapByte
849   jp   .bldPusherDone
850 ; ---------------------------------------------------------------------------
851 .bldEvenX:
852   ; put only one tile instead of two
853   ld   a,(hl)  ; map data
854   or   a
855   jr   nz,.bldNonEmptyTileEX
856   ld   a,#E5   ; PUSH HL (empty tile)
857   jp   .bldStorePushAndBackOneMapByte
858 .bldNonEmptyTileEX:
859   and  0F0h
860   srl  a
861   srl  a
862   srl  a
863   ld   (bldCurTileBlockX2Var),a
864   call bldStoreTileBlockOffset
865   ld   a,(hl)  ; map data
866   push hl
867   and  0Fh     ; block type
868   add  a,a
869   add  a,pushCodes%256
870   ld   l,a
871   ld   h,pushCodes/256
872   jp   .bldCopyOnePush
873 ; ---------------------------------------------------------------------------
874 .bldNonEmptyTile:
875   and  0F0h
876   srl  a
877   srl  a
878   srl  a
879   ld   (bldCurTileBlockX2Var),a
880   call bldStoreTileBlockOffset
881   ld   a,(hl)
882   push hl
883   jr   .bldWeAreNotEmptyAnyway
884 .bldDoNextTiles:
885   ld   a,(hl)
886   push hl
887   or   a
888   jr   z,.bldItIsEmpty
889   push af
890   and  0F0h
891   srl  a
892   srl  a
893   srl  a
894   ld   c,a  ; new tileset
895 bldCurTileBlockX2Var: equ $+1
896   ld   a,0
897   cp   c
898   jp   z,.bldSameTileBlock
899   ld   a,c
900   ld   (bldCurTileBlockX2Var),a
901   call bldStoreTileBlockOffset
902   ; copy 'gfx switch' code
903   ld   a,b
904   push hl
905   ld   hl,codeReloadTileGfx
906   DUP  codeReloadTileGfxLen
907   ldi
908   EDUP
909   pop  hl
910   ld   b,a
911 .bldSameTileBlock:
912   pop  af
913 .bldWeAreNotEmptyAnyway:
914   and  0Fh
915 .bldItIsEmpty:
916   add  a,a
917   add  a,pushCodes%256
918   ld   l,a
919   ld   a,pushCodes/256
920   adc  a,0
921   ld   h,a
922   ld   a,(hl)
923   ld   (de),a
924   inc  de
925 .bldCopyOnePush:
926   inc  l
927   ld   a,(hl)
928   ld   (de),a
929   inc  de
930   pop  hl
931   ; previous map byte, with wrapping
932   ld   a,l
933   and  0E0h
934   ld   c,a
935   ld   a,l
936   dec  a
937   and  1Fh
938   add  a,c
939   ld   l,a
940   djnz .bldDoNextTiles
941 .bldPusherDone:
942   dec  de          ; remove one push (border)
943   ld   a,(mapX)
944   and  1
945   jr   z,$+3       ; skip next command
946   dec  de          ; remove another push (map is shifted by one tile)
947   ex   de,hl       ; HL: 'pusher' end
948   ; insert final JP
949   ld   (hl),0C3h   ; JP
950   inc  hl
951   ld   (hl),blitMapPusherDone%256
952   inc  hl
953   ld   (hl),blitMapPusherDone/256
954   inc  hl
955   ld   (.bldPusherStartAddrVar),hl  ; save this address
956   pop  hl          ; 'pusher' table
957   ; next table item
958   ld   a,l
959   add  a,4
960   ld   l,a
961   pop  bc
962   dec  b
963   jp   nz,.bldPusherNextRow
964   ret
966 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
968 bldStoreTileBlockOffset:
969   ;  A: tile block, 0-3
970   exx
971   ; DE: 'pusher' address
972   ; HL: pusher table
973   ex   de,hl
974   ; get tile block offset
975   ld   l,tileBlockOffsets%256
976   add  a,l
977   ;
978   ld   l,a
979   ld   a,tileBlockOffsets/256
980   adc  a,0
981   ld   h,a
982   ;
983   ld   c,(hl)
984   inc  hl
985   ld   b,(hl)
986   ex   de,hl
987   ; HL: pusher table
988   ; store tile block offset
989   ld   (hl),c
990   inc  hl
991   ld   (hl),b
992   inc  hl
993   exx
994   ret
997 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
999 ;; throwaways
1000   org  #8000
1001 firstTimeInit:
1002   di
1003   ld   sp,myfirstbyte
1004   ;; set paging
1005   ld   bc,#7FFD
1006   ld   a,020
1007   out  (c),a
1008   ;;
1009   ;ld   a,intrTable/256
1010   ld   a,#39
1011   ld   i,a
1012   ld   a,#18
1013   ld   (#FFFF),a  ; jr
1014   ld   a,#C3      ; jp
1015   ld   (#FFF4),a
1016   ld   hl,IntrHandler
1017   ld   (#FFF5),hl
1018   im   2
1019   ei
1020   xor  a
1021   ld   hl,#5800
1022   ld   de,#5801
1023   ld   bc,767
1024   halt
1025   di
1026   ld   (hl),a
1027   out  (254),a
1028   ldir
1029   ;call BuildScrLineTable
1031 BuildScrLineTable:
1032   ld   hl,scrRowsTable
1033   ld   de,#401E
1034   ld   b,128
1035 .lineloop:
1036   ld   (hl),e
1037   inc  l
1038   ld   (hl),d
1039   inc  l
1040   ; line down
1041   inc  d
1042   ld   a,d
1043   and  #07
1044   jr   nz,.downdone
1045   ld   a,e
1046   sub  #E0
1047   ld   e,a
1048   sbc  a,a
1049   and  #F8
1050   add  a,d
1051   ld   d,a
1052 .downdone:
1053   djnz .lineloop
1054   ;ret
1055   jp   mainEntry