1include(`z88dk.m4')
2include(`config_private.inc')
3
4; -----------------------------------------------------------------------------
5; BIFROST*2 ENGINE by Einar Saukas
6; A Rainbow Graphics 20 Columns 8x1 Multicolor Engine for Animated Tiles
7; Adapted to z88dk by aralbrec
8; -----------------------------------------------------------------------------
9
10org 51625
11
12; -----------------------------------------------------------------------------
13; Start engine
14;
15; Destroys:
16;   AF
17;
18; Address:
19;   51625
20; -----------------------------------------------------------------------------
21
22PUBLIC asm_BIFROST2_start
23
24asm_BIFROST2_start:
25activate_engine:
26        di
27        ld      a, $fe
28        ld      i, a
29        im      2
30        ld      hl,main_engine
31        ld      ($fdfe),hl
32        ei
33        ret
34
35; -----------------------------------------------------------------------------
36; Stop engine
37; replaced
38; -----------------------------------------------------------------------------
39;
40;PUBLIC asm_BIFROST2_stop
41;
42;asm_BIFROST2_stop:
43;deactivate_engine:
44;        di
45;        ld      a, $3f
46;        ld      i, a
47;        im      1
48;        ei
49;        ret
50
51defs 51650 - 7 - 51625 - ASMPC
52
53; -----------------------------------------------------------------------------
54; Internal routine
55; -----------------------------------------------------------------------------
56skip_tile:
57        ld      b, 92
58delay_tile:
59        inc     hl
60        djnz    delay_tile
61        inc     hl
62        ret
63
64; -----------------------------------------------------------------------------
65; Instantly show/animate next 2 tile map positions in drawing order
66;
67; Destroys:
68;   AF, BC, DE, HL
69;
70; Address:
71;   51650
72; -----------------------------------------------------------------------------
73
74PUBLIC asm_BIFROST2_showNext2Tiles
75
76asm_BIFROST2_showNext2Tiles:
77show_next2:
78        call    show_next_tile
79
80; -----------------------------------------------------------------------------
81; Instantly show/animate next tile map position in drawing order
82;
83; Destroys:
84;   AF, BC, DE, HL
85;
86; Address:
87;   51653
88; -----------------------------------------------------------------------------
89
90PUBLIC asm_BIFROST2_showNextTile
91
92asm_BIFROST2_showNextTile:
93show_next_tile:
94        ld      de, $1001               ; D = lin (16,32,48..176), E = col (1,3,5..19)
95        ld      a, e
96        sub     +(10-__BIFROST2_TILE_ORDER)*2
97        ld      e, a
98        jr      nc, prev_lin
99        add     a, 20
100        ld      e, a
101        xor     a
102        jr      reset_lin
103prev_lin:
104        ld      a, d
105        sub     16
106        ld      d, a
107        cp      16
108reset_lin:
109        sbc     a, a
110        and     +((__BIFROST2_TOTAL_ROWS+1)/2)*16
111        add     a, d
112        ld      d, a
113        ld      (show_next_tile+1), de
114
115; -----------------------------------------------------------------------------
116; Instantly show/animate specified tile map position on screen
117;
118; Parameters:
119;   D: lin (16,32,48..176)
120;   E: col (1,3,5..19)
121;
122; Destroys:
123;   AF, BC, DE, HL
124;
125; Address:
126;   51683
127; -----------------------------------------------------------------------------
128
129PUBLIC asm_BIFROST2_showTilePosH
130PUBLIC _BIFROST2_tilemap
131
132asm_BIFROST2_showTilePosH:
133show_tile_pos:
134        ld      a, d                    ; A = 8*(lin/8)
135        rrca                            ; A = 4*(lin/8)
136        rrca                            ; A = 2*(lin/8)
137        add     a, d                    ; A = 10*(lin/8)
138        add     a, e                    ; A = 10*(lin/8)+col
139        sub     19                      ; A = 10*(lin/8)-20+(col+1)
140        rra                             ; A = 10*(lin/16)-10+(col+1)/2
141        ld      l, a
142defc _BIFROST2_tilemap = __BIFROST2_TILE_MAP
143        ld      h, __BIFROST2_TILE_MAP/256   ; HL = TILEMAP+10*(lin/16)-10+(col-1)/2
144
145get_tile:
146        ld      a,(hl)
147        cp      __BIFROST2_STATIC_MIN
148        jp      c, animate_tile
149        inc     a
150        jr      z, skip_tile
151        sub     1+__BIFROST2_STATIC_OVERLAP
152        jr      draw_tile
153animate_tile:
154        rrca
155IF (__BIFROST2_ANIM_GROUP = 4)
156        rrca
157        add     a, $40
158        rlca
159ELSE
160        nop
161        add     a, $80
162        nop
163ENDIF
164        rlca
165        ld      (hl), a
166
167; -----------------------------------------------------------------------------
168; Instantly draw tile at specified position on screen
169;
170; Parameters:
171;   A: tile number (0-255)
172;   D: lin (0-207)
173;   E: col (0-20)
174;
175; Destroys:
176;   AF, BC, DE, HL
177;
178; Address:
179;   51714
180; -----------------------------------------------------------------------------
181
182PUBLIC asm_BIFROST2_drawTileH
183PUBLIC _BIFROST2_TILE_IMAGES
184
185asm_BIFROST2_drawTileH:
186draw_tile:
187; calculate screen bitmap lookup address
188        ld      (exit_draw+1), sp
189        ld      h, lookup/512
190        ld      l, d                    ; HL = lookup/2+lin
191        add     hl, hl                  ; HL = lookup+2*lin
192        ld      sp, hl                  ; SP = lookup+2*lin
193
194; preserve values
195        ld      b, e                    ; B = col
196        ld      c, h
197
198; calculate tile image address
199        ld      l, 0                    ; AL = 256*tile
200        rra
201        rr      l                       ; AL = 128*tile
202        rra
203        rr      l                       ; AL = 64*tile
204        ld      h, a                    ; HL = 64*tile
205defc _BIFROST2_TILE_IMAGES = ASMPC + 1
206        ld      de, __BIFROST2_TILE_IMAGES
207        add     hl, de                  ; HL = TILE_IMAGES+64*tile
208
209; draw bitmap lines
210Z88DK_FOR(`LOOP', `1', `16',
211`
212        pop     de
213        ld      a, e
214        add     a, b
215        ld      e, a
216        ldi
217        ldi
218')
219; calculate multicolor attribute address
220        ex      de, hl                  ; DE = TILE_IMAGES+64*tile+32
221        rr      b                       ; B = INT(col/2)
222        ld      c, 235                  ; BC = 256*INT(col/2)+235
223        ld      h, b
224        ld      l, c                    ; HL = 256*INT(col/2)+235
225        srl     h
226        rr      l                       ; HL = 128*INT(col/2)+117
227        add     hl, bc                  ; HL = 384*INT(col/2)+352 = 384*INT(col/2)+384-32
228        add     hl, sp                  ; HL = SP+384*INT(col/2)+384-32 = (lookup+384)+lin*2+384*INT(col/2)
229        ld      sp, hl
230        ex      de, hl
231
232; distinguish between even/odd column
233        rra
234        jr      nc, draw_even_col
235
236; draw multicolor attributes starting at odd column
237Z88DK_FOR(`LOOP', `1', `15',
238`
239        pop     de
240        ldi
241        ldi
242')
243        pop     de
244        ldi
245        ld      a, (hl)
246        ld      (de), a
247exit_draw:
248        ld      sp, 0
249        ret
250
251draw_even_col:
252        ld      a, b                    ; A = INT(col/2)
253        cp      10
254        ld      de, -384
255        jr      z, draw_last_col
256
257; draw right side of tile
258Z88DK_FOR(`LOOP', `1', `16',
259`
260        inc     hl
261        pop     de
262        ldi
263')
264        and     a
265        jr      z, exit_draw
266
267        ld      de, -32
268        add     hl, de
269        ld      de, -(384+32)
270draw_last_col:
271        ex      de, hl
272        add     hl, sp
273        ld      sp, hl
274        ex      de, hl
275
276; draw left side of tile
277Z88DK_FOR(`LOOP', `1', `15',
278`
279        pop     de
280        inc     de
281        ldi
282        inc     hl
283')
284        pop     de
285        inc     de
286        ldi
287
288        jp      exit_draw
289
290; -----------------------------------------------------------------------------
291; Lookup tables
292; -----------------------------------------------------------------------------
293extra_buffer:
294Z88DK_FOR(`LOOP', `1', `22',
295`
296        defw      0                               ; columns 9 and 10 (6)
297        defw      0                               ; columns 7 and 8 (4)
298')
299lookup:
300Z88DK_FOR(`LOOP', `1', `16',
301`
302        defw      0
303')
304; lookup table with screen coordinates
305Z88DK_FOR(`ROWREPT', `0', `21',
306`
307Z88DK_FOR(`LINREPT', `0', `7',
308`
309IF (ROWREPT < __BIFROST2_TOTAL_ROWS)
310        defw      16384 + (((ROWREPT+1)/8)*2048) + (LINREPT*256) + (((ROWREPT+1)%8)*32)
311ELSE
312        defw      0
313ENDIF
314')
315')
316Z88DK_FOR(`LOOP', `1', `16',
317`
318        defw      0
319')
320; lookup table with attribute coordinates for columns 1 & 2
321Z88DK_FOR(`ROWREPT', `0', `21',
322`
323IF (ROWREPT < __BIFROST2_TOTAL_ROWS)
324        defw      setup_raster+((__BIFROST2_TOTAL_ROWS-1-ROWREPT)*43)+(((21-ROWREPT)/19)*(3-ROWREPT)*7)+40
325        defw      race_raster+(ROWREPT*333)+30
326        defw      race_raster+(ROWREPT*333)+73
327        defw      race_raster+(ROWREPT*333)+122
328IFDEF PLUS3
329        defw      race_raster+(ROWREPT*333)+164
330ELSE
331        defw      race_raster+(ROWREPT*333)+86
332ENDIF
333        defw      race_raster+(ROWREPT*333)+222
334        defw      race_raster+(ROWREPT*333)+260
335        defw      race_raster+(ROWREPT*333)+302
336ELSE
337Z88DK_FOR(`LOOP', `1', `8',
338`
339        defw      0
340')
341ENDIF
342')
343Z88DK_FOR(`LOOP', `1', `16',
344`
345        defw      0
346')
347; lookup table with attribute coordinates for columns 3 & 4
348Z88DK_FOR(`ROWREPT', `0', `21',
349`
350IF (ROWREPT < __BIFROST2_TOTAL_ROWS)
351        defw      setup_raster+((__BIFROST2_TOTAL_ROWS-1-ROWREPT)*43)+(((21-ROWREPT)/19)*(3-ROWREPT)*7)+36
352        defw      race_raster+(ROWREPT*333)+26
353        defw      race_raster+(ROWREPT*333)+76
354        defw      race_raster+(ROWREPT*333)+125
355        defw      race_raster+(ROWREPT*333)+167
356        defw      race_raster+(ROWREPT*333)+211
357        defw      race_raster+(ROWREPT*333)+48
358        defw      race_raster+(ROWREPT*333)+305
359ELSE
360Z88DK_FOR(`LOOP', `1', `8',
361`
362        defw      0
363')
364ENDIF
365')
366Z88DK_FOR(`LOOP', `1', `16',
367`
368        defw      0
369')
370; lookup table with attribute coordinates for columns 5 & 6
371Z88DK_FOR(`ROWREPT', `0', `21',
372`
373IF (ROWREPT < __BIFROST2_TOTAL_ROWS)
374        defw      setup_raster+((__BIFROST2_TOTAL_ROWS-1-ROWREPT)*43)+(((21-ROWREPT)/19)*(3-ROWREPT)*7)+30
375        defw      race_raster+(ROWREPT*333)+34
376        defw      race_raster+(ROWREPT*333)+79
377        defw      race_raster+(ROWREPT*333)+128
378IFDEF PLUS3
379        defw      race_raster+(ROWREPT*333)+83
380ELSE
381        defw      race_raster+(ROWREPT*333)+170
382ENDIF
383        defw      race_raster+(ROWREPT*333)+214
384        defw      race_raster+(ROWREPT*333)+256
385        defw      race_raster+(ROWREPT*333)+295
386ELSE
387Z88DK_FOR(`LOOP', `1', `8',
388`
389        defw      0
390')
391ENDIF
392')
393Z88DK_FOR(`LOOP', `1', `16',
394`
395        defw      0
396')
397; lookup table with attribute coordinates for columns 7 & 8
398Z88DK_FOR(`ROWREPT', `0', `21',
399`
400IF (ROWREPT < __BIFROST2_TOTAL_ROWS)
401        defw      setup_raster+((__BIFROST2_TOTAL_ROWS-1-ROWREPT)*43)+(((21-ROWREPT)/19)*(3-ROWREPT)*7)+27
402        defw      race_raster+(ROWREPT*333)+61
403        defw      race_raster+(ROWREPT*333)+108
404        defw      extra_buffer+(ROWREPT*4)+2
405        defw      race_raster+(ROWREPT*333)+193
406        defw      race_raster+(ROWREPT*333)+236
407        defw      race_raster+(ROWREPT*333)+278
408        defw      race_raster+(ROWREPT*333)+318
409ELSE
410Z88DK_FOR(`LOOP', `1', `8',
411`
412        defw      0
413')
414ENDIF
415')
416Z88DK_FOR(`LOOP', `1', `16',
417`
418        defw      0
419')
420; lookup table with attribute coordinates for columns 9 & 10
421Z88DK_FOR(`ROWREPT', `0', `21',
422`
423IF (ROWREPT < __BIFROST2_TOTAL_ROWS)
424        defw      setup_raster+((__BIFROST2_TOTAL_ROWS-1-ROWREPT)*43)+(((21-ROWREPT)/19)*(3-ROWREPT)*7)+24
425        defw      race_raster+(ROWREPT*333)+64
426        defw      race_raster+(ROWREPT*333)+10
427        defw      race_raster+(ROWREPT*333)+112
428        defw      race_raster+(ROWREPT*333)+154
429        defw      extra_buffer+(ROWREPT*4)
430        defw      race_raster+(ROWREPT*333)+240
431        defw      race_raster+(ROWREPT*333)+291
432ELSE
433Z88DK_FOR(`LOOP', `1', `8',
434`
435        defw      0
436')
437ENDIF
438')
439Z88DK_FOR(`LOOP', `1', `16',
440`
441        defw      0
442')
443; lookup table with attribute coordinates for columns 11 & 12
444Z88DK_FOR(`ROWREPT', `0', `21',
445`
446IF (ROWREPT < __BIFROST2_TOTAL_ROWS)
447        defw      setup_raster+((__BIFROST2_TOTAL_ROWS-1-ROWREPT)*43)+(((21-ROWREPT)/20)*(2-ROWREPT)*7)+(((21-ROWREPT)/19)*4)+20
448        defw      race_raster+(ROWREPT*333)+67
449        defw      race_raster+(ROWREPT*333)+13
450        defw      race_raster+(ROWREPT*333)+115
451        defw      race_raster+(ROWREPT*333)+157
452        defw      race_raster+(ROWREPT*333)+198
453        defw      race_raster+(ROWREPT*333)+243
454        defw      race_raster+(ROWREPT*333)+282
455ELSE
456Z88DK_FOR(`LOOP', `1', `8',
457`
458        defw      0
459')
460ENDIF
461')
462Z88DK_FOR(`LOOP', `1', `16',
463`
464        defw      0
465')
466; lookup table with attribute coordinates for columns 13 & 14
467Z88DK_FOR(`ROWREPT', `0', `21',
468`
469IF (ROWREPT < __BIFROST2_TOTAL_ROWS)
470        defw      setup_raster+((__BIFROST2_TOTAL_ROWS-1-ROWREPT)*43)+(((21-ROWREPT)/20)*(2-ROWREPT)*7)+(((21-ROWREPT)/19)*4)+16
471        defw      race_raster+(ROWREPT*333)+20
472        defw      race_raster+(ROWREPT*333)+16
473        defw      race_raster+(ROWREPT*333)+118
474        defw      race_raster+(ROWREPT*333)+160
475        defw      race_raster+(ROWREPT*333)+201
476        defw      race_raster+(ROWREPT*333)+246
477        defw      race_raster+(ROWREPT*333)+285
478ELSE
479Z88DK_FOR(`LOOP', `1', `8',
480`
481        defw      0
482')
483ENDIF
484')
485Z88DK_FOR(`LOOP', `1', `16',
486`
487        defw      0
488')
489; lookup table with attribute coordinates for columns 15 & 16
490Z88DK_FOR(`ROWREPT', `0', `21',
491`
492IF (ROWREPT < __BIFROST2_TOTAL_ROWS)
493        defw      setup_raster+((__BIFROST2_TOTAL_ROWS-1-ROWREPT)*43)+(((21-ROWREPT)/20)*(2-ROWREPT)*7)+(((21-ROWREPT)/19)*4)+10
494        defw      race_raster+(ROWREPT*333)+52
495        defw      race_raster+(ROWREPT*333)+92
496        defw      race_raster+(ROWREPT*333)+137
497IFDEF PLUS3
498        defw      race_raster+(ROWREPT*333)+174
499ELSE
500        defw      race_raster+(ROWREPT*333)+164
501ENDIF
502        defw      race_raster+(ROWREPT*333)+204
503        defw      race_raster+(ROWREPT*333)+250
504        defw      race_raster+(ROWREPT*333)+299
505ELSE
506Z88DK_FOR(`LOOP', `1', `8',
507`
508        defw      0
509')
510ENDIF
511')
512Z88DK_FOR(`LOOP', `1', `16',
513`
514        defw      0
515')
516; lookup table with attribute coordinates for columns 17 & 18
517Z88DK_FOR(`ROWREPT', `0', `21',
518`
519IF (ROWREPT < __BIFROST2_TOTAL_ROWS)
520        defw      setup_raster+((__BIFROST2_TOTAL_ROWS-1-ROWREPT)*43)+(((21-ROWREPT)/20)*(2-ROWREPT)*7)+(((21-ROWREPT)/19)*4)+7
521        defw      race_raster+(ROWREPT*333)+55
522        defw      race_raster+(ROWREPT*333)+95
523        defw      race_raster+(ROWREPT*333)+140
524IFDEF PLUS3
525        defw      race_raster+(ROWREPT*333)+177
526ELSE
527        defw      race_raster+(ROWREPT*333)+175
528ENDIF
529        defw      race_raster+(ROWREPT*333)+208
530        defw      race_raster+(ROWREPT*333)+253
531        defw      race_raster+(ROWREPT*333)+322
532ELSE
533Z88DK_FOR(`LOOP', `1', `8',
534`
535        defw      0
536')
537ENDIF
538')
539Z88DK_FOR(`LOOP', `1', `16',
540`
541        defw      0
542')
543; lookup table with attribute coordinates for columns 19 & 20
544Z88DK_FOR(`ROWREPT', `0', `21',
545`
546IF (ROWREPT < __BIFROST2_TOTAL_ROWS)
547        defw      setup_raster+((__BIFROST2_TOTAL_ROWS-1-ROWREPT)*43)+(((21-ROWREPT)/20)*(2-ROWREPT)*7)+(((21-ROWREPT)/19)*4)+4
548        defw      race_raster+(ROWREPT*333)+23
549        defw      race_raster+(ROWREPT*333)+98
550        defw      race_raster+(ROWREPT*333)+143
551IFDEF PLUS3
552        defw      race_raster+(ROWREPT*333)+180
553ELSE
554        defw      race_raster+(ROWREPT*333)+178
555ENDIF
556        defw      race_raster+(ROWREPT*333)+219
557        defw      race_raster+(ROWREPT*333)+275
558        defw      race_raster+(ROWREPT*333)+328
559ELSE
560Z88DK_FOR(`LOOP', `1', `8',
561`
562        defw      0
563')
564ENDIF
565')
566Z88DK_FOR(`LOOP', `1', `16',
567`
568        defw      0
569')
570
571; -----------------------------------------------------------------------------
572
573PUBLIC _BIFROST2_ISR_HOOK
574PUBLIC _BIFROST2_ISR_STOP
575
576main_engine:
577; preserve all registers
578        push    af
579        push    bc
580        push    de
581        push    hl
582        ex      af, af
583        exx
584        push    af
585        push    bc
586        push    de
587        push    hl
588        push    ix
589        push    iy
590
591; draw and animate next 5 tiles
592        call    show_next2
593        call    show_next2
594        call    show_next_tile
595
596; initial delay to synchronize with raster beam
597IF __BIFROST2_TOTAL_ROWS<22
598        ld      c, 22-__BIFROST2_TOTAL_ROWS
599skip_loop:
600        ld      b, 15
601        djnz    ASMPC
602        ld      a, (bc)
603        dec     c
604        jr      nz, skip_loop
605ENDIF
606
607; preserve stack pointer
608        ld      (exit_raster+1), sp
609
610; copy in advance first line of attributes for each row
611        ld      a, 8
612setup_raster:
613Z88DK_FOR(`ROWREPT', `0', `21',
614`
615IF (ROWREPT>=(22-__BIFROST2_TOTAL_ROWS))
616        ld      sp, $5822+((21-ROWREPT)*32)+19  ; reference columns 19 and 20
617        ld      hl, 0                           ; columns 19 and 20 (1)
618        ld      de, 0                           ; columns 17 and 18 (1)
619        ld      bc, 0                           ; columns 15 and 16 (1)
620        push    hl
621        push    de
622        push    bc
623        ld      bc, 0                           ; columns 13 and 14 (1)
624        push    bc
625        ld      bc, 0                           ; columns 11 and 12 (1)
626        push    bc
627
628IF ROWREPT>18
629; additional delay to synchronize with raster beam
630        ld      b, a
631        djnz    ASMPC
632ENDIF
633
634        ld      hl, 0                           ; columns 9 and 10 (1)
635        ld      de, 0                           ; columns 7 and 8 (1)
636        ld      bc, 0                           ; columns 5 and 6 (1)
637        push    hl
638        push    de
639        push    bc
640        ld      bc, 0                           ; columns 3 and 4 (1)
641        push    bc
642        ld      bc, 0                           ; columns 1 and 2 (1)
643        push    bc
644ENDIF
645
646IF ROWREPT>17
647; additional delay to synchronize with raster beam
648IF ROWREPT=18
649IFDEF PLUS3
650        ld      b, 36
651ELSE
652        ld      b, 32
653ENDIF
654        djnz    ASMPC
655ELSE
656IF ROWREPT=21
657IFDEF PLUS3
658        ld      b, a
659        inc     b
660ELSE
661        ld      b, 9                            ; 9 if ZX-Spectrum 48K, 10 if ZX-Spectrum 128K
662ENDIF
663        djnz    ASMPC
664ELSE
665        ld      b, a
666        djnz    ASMPC
667        add     hl, hl
668ENDIF
669ENDIF
670ENDIF
671')
672; race the raster beam to update attributes at the right time
673race_raster:
674Z88DK_FOR(`ROWREPT', `0', eval(__BIFROST2_TOTAL_ROWS-1),
675`
676        ; --- prepare "push af/af" for later
677        ld      sp, extra_buffer+(ROWREPT*4)    ; reference af/af values
678        pop     af                              ; columns 9 and 10 (6)
679        ex      af, af
680        pop     af                              ; columns 7 and 8 (4)
681
682        ; --- set attributes for 2nd raster scan ---
683        ld      sp, $5822+(ROWREPT*32)+5        ; reference columns 5 and 6
684        ld      hl, 0                           ; columns 9 and 10 (3)          #010
685        ld      de, 0                           ; columns 11 and 12 (3)         #013
686        ld      bc, 0                           ; columns 13 and 14 (3)         #016
687        exx
688        ld      hl, 0                           ; columns 13 and 14 (2)         #020
689        ld      de, 0                           ; columns 19 and 20 (2)         #023
690        ld      bc, 0                           ; columns 3 and 4 (2)           #026
691        ld      ix, 0                           ; columns 1 and 2 (2)           #030
692        ld      iy, 0                           ; columns 5 and 6 (2)           #034
693        ld      ($5820+(ROWREPT*32)+1), ix      ; columns 1 and 2
694        push    iy                              ; columns 5 and 6
695        push    bc                              ; columns 3 and 4
696        ld      sp, $5822+(ROWREPT*32)+19       ; reference columns 19 and 20
697        ld      ix, 0                           ; columns 3 and 4 (7)           #048
698        push    de                              ; columns 19 and 20
699        ld      de, 0                           ; columns 15 and 16 (2)         #052
700        ld      bc, 0                           ; columns 17 and 18 (2)         #055
701        push    bc                              ; columns 17 and 18
702        push    de                              ; columns 15 and 16
703        push    hl                              ; columns 13 and 14
704        ld      hl, 0                           ; columns 7 and 8 (2)           #061
705        ld      de, 0                           ; columns 9 and 10 (2)          #064
706        ld      bc, 0                           ; columns 11 and 12 (2)         #067
707        push    bc                              ; columns 11 and 12
708        push    de                              ; columns 9 and 10
709        push    hl                              ; columns 7 and 8
710
711        ; --- set attributes for 3rd raster scan ---
712        ld      hl, 0                           ; columns 1 and 2 (3)           #073
713        ld      de, 0                           ; columns 3 and 4 (3)           #076
714        ld      bc, 0                           ; columns 5 and 6 (3)           #079
715IFDEF PLUS3
716        ld      iy, 0                           ; columns 5 and 6 (5)           #083 (*)
717ENDIF
718        push    bc                              ; columns 5 and 6
719        push    de                              ; columns 3 and 4
720        push    hl                              ; columns 1 and 2
721IFDEF PLUS3
722ELSE
723        ld      iy, 0                           ; columns 1 and 2 (5)           #086 (*)
724ENDIF
725        ld      sp, $5822+(ROWREPT*32)+19       ; reference columns 19 and 20
726        ld      hl, 0                           ; columns 15 and 16 (3)         #092
727        ld      de, 0                           ; columns 17 and 18 (3)         #095
728        ld      bc, 0                           ; columns 19 and 20 (3)         #098
729        push    bc                              ; columns 19 and 20
730        push    de                              ; columns 17 and 18
731        push    hl                              ; columns 15 and 16
732        exx
733        push    bc                              ; columns 13 and 14
734        push    de                              ; columns 11 and 12
735        push    hl                              ; columns 9 and 10
736        ld      hl, 0                           ; columns 7 and 8 (3)           #108
737        push    hl                              ; columns 7 and 8
738
739        ; --- set attributes for 4th raster scan ---
740        ld      hl, 0                           ; columns 9 and 10 (4)          #112
741        ld      de, 0                           ; columns 11 and 12 (4)         #115
742        ld      bc, 0                           ; columns 13 and 14 (4)         #118
743        exx
744        ld      hl, 0                           ; columns 1 and 2 (4)           #122
745        ld      de, 0                           ; columns 3 and 4 (4)           #125
746        ld      bc, 0                           ; columns 5 and 6 (4)           #128
747        push    bc                              ; columns 5 and 6
748        push    de                              ; columns 3 and 4
749        push    hl                              ; columns 1 and 2
750        ld      sp, $5822+(ROWREPT*32)+19       ; reference columns 19 and 20
751        ld      hl, 0                           ; columns 15 and 16 (4)         #137
752        ld      de, 0                           ; columns 17 and 18 (4)         #140
753        ld      bc, 0                           ; columns 19 and 20 (4)         #143
754        push    bc                              ; columns 19 and 20
755        push    de                              ; columns 17 and 18
756        push    hl                              ; columns 15 and 16
757        exx
758        push    bc                              ; columns 13 and 14
759        push    de                              ; columns 11 and 12
760        push    hl                              ; columns 9 and 10
761        push    af                              ; columns 7 and 8
762
763        ; --- set attributes for 5th raster scan ---
764        ld      hl, 0                           ; columns 9 and 10 (5)          #154
765        ld      de, 0                           ; columns 11 and 12 (5)         #157
766        ld      bc, 0                           ; columns 13 and 14 (5)         #160
767        exx
768IFDEF PLUS3
769        ld      hl, 0                           ; columns 1 and 2 (5)           #164 (*)
770        ld      de, 0                           ; columns 3 and 4 (5)           #167 (*)
771        push    iy                              ; (*) columns 5 and 6
772        push    de                              ; (*) columns 3 and 4
773        push    hl                              ; (*) columns 1 and 2
774        ld      hl, 0                           ; (*) columns 15 and 16 (5)     #174 (*)
775        ld      de, 0                           ; (*) columns 17 and 18 (5)     #177 (*)
776        ld      bc, 0                           ; (*) columns 19 and 20 (5)     #180 (*)
777ELSE
778        ld      hl, 0                           ; columns 15 and 16 (5)         #164 (*)
779        ld      de, 0                           ; columns 3 and 4 (5)           #167 (*)
780        ld      bc, 0                           ; columns 5 and 6 (5)           #170 (*)
781        push    bc                              ; columns 5 and 6
782        push    de                              ; columns 3 and 4
783        ld      de, 0                           ; columns 17 and 18 (5)         #175 (*)
784        ld      bc, 0                           ; columns 19 and 20 (5)         #178 (*)
785        push    iy                              ; columns 1 and 2
786ENDIF
787        ld      sp, $5822+(ROWREPT*32)+19       ; reference columns 19 and 20
788        push    bc                              ; columns 19 and 20
789        push    de                              ; columns 17 and 18
790        push    hl                              ; columns 15 and 16
791        exx
792        push    bc                              ; columns 13 and 14
793        push    de                              ; columns 11 and 12
794        push    hl                              ; columns 9 and 10
795        ld      hl, 0                           ; columns 7 and 8 (5)           #193
796        ex      af, af
797        push    hl                              ; columns 7 and 8
798
799        ; --- set attributes for 6th raster scan ---
800        ld      hl, 0                           ; columns 11 and 12 (6)         #198
801        ld      de, 0                           ; columns 13 and 14 (6)         #201
802        ld      bc, 0                           ; columns 15 and 16 (6)         #204
803        exx
804        ld      hl, 0                           ; columns 17 and 18 (6)         #208
805        ld      de, 0                           ; columns 3 and 4 (6)           #211
806        ld      bc, 0                           ; columns 5 and 6 (6)           #214
807        push    bc                              ; columns 5 and 6
808        push    de                              ; columns 3 and 4
809        ld      de, 0                           ; columns 19 and 20 (6)         #219
810        ld      bc, 0                           ; columns 1 and 2 (6)           #222
811        push    bc                              ; columns 1 and 2
812        ld      sp, $5822+(ROWREPT*32)+19       ; reference columns 19 and 20
813        push    de                              ; columns 19 and 20
814        push    hl                              ; columns 17 and 18
815        exx
816        push    bc                              ; columns 15 and 16
817        push    de                              ; columns 13 and 14
818        push    hl                              ; columns 11 and 12
819        push    af                              ; columns 9 and 10
820        ld      hl, 0                           ; columns 7 and 8 (6)           #236
821        push    hl                              ; columns 7 and 8
822
823        ; --- set attributes for 7th raster scan ---
824        ld      hl, 0                           ; columns 9 and 10 (7)          #240
825        ld      de, 0                           ; columns 11 and 12 (7)         #243
826        ld      bc, 0                           ; columns 13 and 14 (7)         #246
827        exx
828        ld      hl, 0                           ; columns 15 and 16 (7)         #250
829        ld      de, 0                           ; columns 17 and 18 (7)         #253
830        ld      bc, 0                           ; columns 5 and 6 (7)           #256
831        push    bc                              ; columns 5 and 6
832        ld      bc, 0                           ; columns 1 and 2 (7)           #260
833        push    ix                              ; columns 3 and 4
834        push    bc                              ; columns 1 and 2
835        ld      sp, $5822+(ROWREPT*32)+17       ; reference columns 17 and 18
836        push    de                              ; columns 17 and 18
837        push    hl                              ; columns 15 and 16
838        exx
839        push    bc                              ; columns 13 and 14
840        push    de                              ; columns 11 and 12
841        push    hl                              ; columns 9 and 10
842        ld      hl, 0                           ; columns 19 and 20 (7)         #275
843        ld      de, 0                           ; columns 7 and 8 (7)           #278
844        push    de                              ; columns 7 and 8
845        ld      de, 0                           ; columns 11 and 12 (8)         #282
846        ld      bc, 0                           ; columns 13 and 14 (8)         #285
847        ld      ($5820+(ROWREPT*32)+19), hl     ; columns 19 and 20
848
849        ; --- set attributes for 8th raster scan ---
850        ld      hl, 0                           ; columns 9 and 10 (8)          #291
851        exx
852        ld      hl, 0                           ; columns 5 and 6 (8)           #295
853        push    hl                              ; columns 5 and 6
854        ld      hl, 0                           ; columns 15 and 16 (8)         #299
855        ld      de, 0                           ; columns 1 and 2 (8)           #302
856        ld      bc, 0                           ; columns 3 and 4 (8)           #305
857        push    bc                              ; columns 3 and 4
858        push    de                              ; columns 1 and 2
859        ld      sp, $5822+(ROWREPT*32)+15       ; reference columns 15 and 16
860        push    hl                              ; columns 15 and 16
861        exx
862        push    bc                              ; columns 13 and 14
863        push    de                              ; columns 11 and 12
864        push    hl                              ; columns 9 and 10
865        ld      hl, 0                           ; columns 7 and 8 (8)           #318
866        push    hl                              ; columns 7 and 8
867        ld      hl, 0                           ; columns 17 and 18 (8)         #322
868        ld      ($5820+(ROWREPT*32)+17), hl     ; columns 17 and 18
869        ld      hl, 0                           ; columns 19 and 20 (8)         #328
870        ld      ($5820+(ROWREPT*32)+19), hl     ; columns 19 and 20
871')
872exit_raster:
873; restore stack pointer
874        ld      sp, 0
875
876; available entry-point for additional interrupt routines
877_BIFROST2_ISR_HOOK:
878        ld      hl, 0
879
880; restore all registers
881        pop     iy
882        pop     ix
883        pop     hl
884        pop     de
885        pop     bc
886        pop     af
887        exx
888        ex      af, af
889        pop     hl
890        pop     de
891        pop     bc
892        pop     af
893
894_BIFROST2_ISR_STOP:
895        ei
896        reti
897
898; -----------------------------------------------------------------------------
899        defs 64829 - 51625 - ASMPC
900; -----------------------------------------------------------------------------
901; Instantly fill the tile attributes at specified position with specified value
902;
903; Parameters:
904;   C: attribute value (0-255)
905;   D: lin (0-207)
906;   E: col (0-20)
907;
908; Destroys:
909;   AF, DE, HL, AF'
910;
911; Address:
912;   64829
913; -----------------------------------------------------------------------------
914
915PUBLIC asm_BIFROST2_fillTileAttrH
916
917asm_BIFROST2_fillTileAttrH:
918fill_tile_attr:
919        ld      (exit_fill+1), sp
920
921        srl     e                               ; E = INT(col/2)
922        ld      a, e
923        ex      af, af
924        inc     e                               ; E = INT(col/2)+1
925        xor     a
926        ld      l, a                            ; L = 0
927        ld      a, e                            ; AL = 256*INT(col/2)+256
928        rra
929        rr      l                               ; AL = 128*INT(col/2)+128
930        add     a, e                            ; AL = 384*INT(col/2)+384
931        ld      h, a                            ; HL = 384*INT(col/2)+384
932
933        ld      e, d                            ; E = lin
934        ld      d, lookup/512                   ; DE = lookup/2+lin
935        add     hl, de                          ; HL = 384*INT(col/2)+384+lookup/2+lin
936        add     hl, de                          ; HL = 384*INT(col/2)+384+lookup+2*lin
937        ld      sp, hl
938
939        ex      af, af
940        jr      nc, fill_even_col
941
942; replace attrib with value
943Z88DK_FOR(`LOOP', `1', `16',
944`
945        pop     hl
946        ld      (hl), c
947        inc     hl
948        ld      (hl), c
949')
950exit_fill:
951        ld      sp, 0
952        ret
953
954fill_even_col:
955        cp      10
956        ld      hl, -384
957        jr      z, fill_last_col
958
959; fill right side of tile
960Z88DK_FOR(`LOOP', `1', `16',
961`
962        pop     hl
963        ld      (hl), c
964')
965        and     a
966        jr      z, exit_fill
967
968        ld      hl, -(384+32)
969fill_last_col:
970        add     hl, sp
971        ld      sp, hl
972
973; fill left side of tile
974Z88DK_FOR(`LOOP', `1', `16',
975`
976        pop     hl
977        inc     hl
978        ld      (hl), c
979')
980        jp      exit_fill
981
982; -----------------------------------------------------------------------------
983; Interrupt address at $fdfd
984; -----------------------------------------------------------------------------
985        jp      main_engine
986
987; -----------------------------------------------------------------------------
988; Jump vector table at addresses $fe00-$ff00
989; -----------------------------------------------------------------------------
990IFNDEF STRIPVECTOR
991        defs 257, 0xfd
992ELSE
993        defb    $fd
994ENDIF
995
996; -----------------------------------------------------------------------------
997