1include(`z88dk.m4')
2include(`config_private.inc')
3
4; -----------------------------------------------------------------------------
5; NIRVANA+ ENGINE (32 columns) - by Einar Saukas
6; A Bicolor (Multicolor 8x2) Full-Screen Engine
7; Adapted to z88dk by aralbrec
8; -----------------------------------------------------------------------------
9
10SECTION NIRVANAP
11
12PUBLIC org_nirvanap
13
14IF ((__NIRVANAP_OPTIONS & 0x3) = 0x3)
15defc org_nirvanap = 56073
16ELSE
17IF (__NIRVANAP_OPTIONS & 0x1)
18defc org_nirvanap = 56085
19ELSE
20defc org_nirvanap = 56323
21ENDIF
22ENDIF
23
24org org_nirvanap
25
26IF ((__NIRVANAP_OPTIONS & 0x3) = 0x3)
27
28; -----------------------------------------------------------------------------
29; Internal routine that executes NIRVANA_drawT, but taking as long as
30; NIRVANA_drawW. This way, each wide sprite can freely switch between both,
31; without affecting timing.
32; -----------------------------------------------------------------------------
33
34PUBLIC asm_NIRVANAP_drawTW
35
36asm_NIRVANAP_drawTW:
37; preserve stack pointer
38        ld      (exit_wide+1), sp       ; delay 20T in 4 bytes
39        ld      bc, $2e00               ; delay 10T
40delay_sprite:
41        djnz    delay_sprite            ; delay 593T
42        jp      asm_NIRVANAP_drawT      ; execute NIRVANA_drawT with delay 10T
43
44ENDIF
45
46IF (__NIRVANAP_OPTIONS & 0x1)
47
48; -----------------------------------------------------------------------------
49; Draw wide tile (24x16 pixels) at specified position (in 2345T)
50;
51; Params:
52;     A = wide tile index (0-255)
53;     D = pixel line (0-200, even values only)
54;     E = char column (0-29)
55;
56; Address: 56085
57;
58; IMPORTANT: This routine is disabled by default, recompile this file
59;            declaring 'ENABLE_WIDE_DRAW' before calling it!!!
60;
61; WARNING: Computer will crash if an interrupt occurs during execution!
62; -----------------------------------------------------------------------------
63
64PUBLIC asm_NIRVANAP_drawW
65PUBLIC _NIRVANAP_WIDE_IMAGES
66
67asm_NIRVANAP_drawW:
68; preserve stack pointer
69        ld      (exit_wide+1), sp
70
71; calculate screen bitmap lookup address
72        ld      h, bitmaps/256
73        ld      l, d
74        ld      sp, hl
75
76; preserve values
77        ld      b, e
78        ld      c, h
79
80; calculate tile image address
81        ld      h, 0
82        ld      l, a
83        ld      e, h
84        add     hl, hl
85        add     hl, hl
86        add     hl, hl
87        rra
88        rr      e
89        rra
90        rr      e
91        ld      d, a
92        add     hl, de
93defc _NIRVANAP_WIDE_IMAGES = ASMPC + 1
94        ld      de, __NIRVANAP_WIDE_IMAGES
95        add     hl, de
96
97; draw bitmap lines
98Z88DK_FOR(`LOOP', `1', `8',
99`
100        pop     de
101        ld      a, e
102        add     a, b
103        ld      e, a
104        ldi
105        ldi
106        ld      a, (hl)
107        ld      (de), a
108        inc     hl
109        dec     e
110        dec     e
111        inc     d
112        ldi
113        ldi
114        ldi
115')
116; calculate routine attribute addresses
117        ex      de, hl
118        ld      hl, attribs - bitmaps - 16
119        add     hl, sp
120        ld      sp, hl
121
122; set routine attribute offsets
123        ld      h, deltas/256
124        ld      l, b
125        inc     l
126        ld      a, (hl)
127        ld      (wide_1st+2), a
128        inc     l
129        ld      a, (hl)
130        ld      (wide_2nd+2), a
131        inc     l
132        ld      a, (hl)
133        ld      (wide_3rd+2), a
134
135; set routine attributes
136        ld      b, 8
137loop_wide:
138        pop     ix
139        ld      a, (de)
140        inc     de
141wide_1st:
142        ld      (ix+0), a
143        ld      a, (de)
144        inc     de
145wide_2nd:
146        ld      (ix+0), a
147        ld      a, (de)
148        inc     de
149wide_3rd:
150        ld      (ix+0), a
151        djnz    loop_wide
152
153exit_wide:
154; restore stack pointer
155        ld      sp, 0
156        ret
157
158ENDIF
159
160; -----------------------------------------------------------------------------
161; Print a 8x8 character at specified position, afterwards paint it with a
162; provided sequence of 4 attribute values (in 617T for positions matching
163; standard character rows, in 646T otherwise)
164;
165; Params:
166;     A = character code (0-255)
167;     BC = attributes address
168;     D = pixel line (16-192, even values only)
169;     E = char column (0-31)
170;
171; Address: 56323
172; -----------------------------------------------------------------------------
173
174PUBLIC asm_NIRVANAP_printC
175PUBLIC _NIRVANAP_CHAR_TABLE
176
177asm_NIRVANAP_printC:
178; preserve paintC parameters
179        push    de
180        push    bc
181
182; calculate initial screen bitmap address
183        ld      h, bitmaps/256
184        ld      l, d
185        ld      d, (hl)
186        inc     l
187        ld      h, (hl)
188        ld      l, d
189        ld      d, 0
190        add     hl, de
191        ex      de, hl
192
193; calculate initial character address
194        ld      l, a
195        add     hl, hl
196        add     hl, hl
197        add     hl, hl
198defc _NIRVANAP_CHAR_TABLE = ASMPC + 1
199        ld      bc, __NIRVANAP_CHAR_TABLE
200        add     hl, bc
201
202; draw bitmap lines
203Z88DK_FOR(`LOOP', `1', `3',
204`
205        ld      a, (hl)
206        ld      (de), a
207        inc     hl
208        inc     d
209
210        ld      a, (hl)
211        ld      (de), a
212        inc     hl
213        inc     d
214
215        ld      a, d
216        and     7
217        jr      nz, ASMPC+11
218        ld      a, e
219        sub     -32
220        ld      e, a
221        sbc     a, a
222        and     -8
223        add     a, d
224        ld      d, a
225')
226        ld      a, (hl)
227        ld      (de), a
228        inc     hl
229        inc     d
230        ld      a, (hl)
231        ld      (de), a
232
233; restore paintC parameters
234        pop     bc
235        pop     de
236
237; -----------------------------------------------------------------------------
238; Paint specified 8x8 block with a sequence of 4 attribute values (in 211T)
239;
240; Params:
241;     BC = attributes address
242;     D = pixel line (16-192, even values only)
243;     E = char column (0-31)
244;
245; Address: 56418
246; -----------------------------------------------------------------------------
247
248PUBLIC asm_NIRVANAP_paintC
249
250asm_NIRVANAP_paintC:
251; calculate initial routine attribute address
252        ld      h, 0
253        ld      l, d
254        ld      d, deltas/256
255        inc     e
256        ld      a, (de)
257        ld      de, attribs
258        add     hl, de
259        add     a, (hl)
260        ld      e, a
261        inc     l
262        adc     a, (hl)
263        sub     e
264        ld      d, a
265        ex      de, hl
266
267; update attributes
268        ld      de, 82
269
270        ld      a, (bc)
271        ld      (hl), a
272        inc     bc
273        add     hl, de
274
275        ld      a, (bc)
276        ld      (hl), a
277        inc     bc
278        add     hl, de
279
280        ld      a, (bc)
281        ld      (hl), a
282        inc     bc
283        add     hl, de
284
285        ld      a, (bc)
286        ld      (hl), a
287        ret
288
289; -----------------------------------------------------------------------------
290
291PUBLIC _NIRVANAP_ISR_HOOK
292PUBLIC _NIRVANAP_ISR_STOP
293
294main_engine:
295; preserve all registers
296        push    af
297        push    bc
298        push    de
299        push    hl
300        ex      af, af'
301        exx
302        push    af
303        push    bc
304        push    de
305        push    hl
306        push    ix
307        push    iy
308
309IF ((__NIRVANAP_OPTIONS & 0x3) = 0x3)
310
311; draw 6 wide tiles
312        ld      de, 0                   ; D = pixel line, E = char column
313        ld      a, 0                    ; A = tile
314        call    asm_NIRVANAP_drawW
315Z88DK_FOR(`LOOP', `1', `5',
316`
317        ld      de, 0                   ; D = pixel line, E = char column
318        ld      a, 0                    ; A = tile
319        call    asm_NIRVANAP_drawW+4
320')
321        jr      skip_wide
322Z88DK_FOR(`LOOP', `1', `7',
323`
324        nop
325')
326skip_wide:
327Z88DK_FOR(`LOOP', `1', `7',
328`
329        nop                             ; extra delay
330')
331
332; wait for the raster beam
333        ld      b, 55-22
334        jr      delay_wide
335delay_128k:
336delay_wide:
337        ld      b, 57-22
338
339ELSE
340
341; draw 8 tiles
342Z88DK_FOR(`LOOP', `1', `6',
343`
344        ld      de, 0                   ; D = pixel line, E = char column
345        ld      a, 0                    ; A = tile
346        call    asm_NIRVANAP_drawT
347')
348Z88DK_FOR(`LOOP', `1', `2',
349`
350        ld      de, 0                   ; D = pixel line, E = char column
351        ld      a, 0                    ; A = tile
352        call    asm_NIRVANAP_drawT+4
353')
354
355; wait for the raster beam
356        ld      b, 55
357        jr      delay_128k
358delay_128k:
359        ld      b, 57
360
361ENDIF
362
363wait_raster:
364        djnz    wait_raster
365
366; preserve stack pointer
367        ld      (exit_raster+1), sp
368
369IF (__SPECTRUM & __SPECTRUM_PENTAGON)
370
371; synchronize with raster beam
372; pentagon timing
373
374        ld      b, 92                       ; extra delay
375        djnz   ASMPC                        ; extra delay
376        djnz   ASMPC                        ; extra delay
377        nop                                 ; extra delay
378        nop                                 ; extra delay
379        jp      race_raster
380
381        defs 56693 - org_nirvanap - ASMPC
382
383; race the raster beam to update attributes on screen at the right time
384race_raster:
385        ld      a, 4
386Z88DK_FOR(`ROWREPT', `0', eval(__NIRVANAP_TOTAL_ROWS-1),
387`
388Z88DK_FOR(`LINREPT', `0', `3',
389`
390        ld      c, a                        ; extra delay
391        dec     c                           ; extra delay
392        jr      nz, ASMPC-1                 ; extra delay
393        inc     bc                          ; extra delay
394
395        ld      sp, $5822+(ROWREPT*32)+6    ; reference columns 6 and 7
396        ld      hl, 0                       ; attributes for columns 14 and 15
397        ld      de, 0                       ; attributes for columns 16 and 17
398        ld      bc, 0                       ; attributes for columns 18 and 19
399        exx
400        ld      hl, 0                       ; attributes for columns 0 and 1
401        ld      de, 0                       ; attributes for columns 4 and 5
402        ld      bc, 0                       ; attributes for columns 6 and 7
403        ld      ($5820+(ROWREPT*32)), hl    ; update columns 0 and 1
404        ld      hl, 0                       ; attributes for columns 2 and 3
405        push    bc                          ; update columns 6 and 7
406        push    de                          ; update columns 4 and 5
407        push    hl                          ; update columns 2 and 3
408        ld      sp, $5822+(ROWREPT*32)+24   ; reference columns 24 and 25
409        ld      hl, 0                       ; attributes for columns 20 and 21
410        ld      de, 0                       ; attributes for columns 22 and 23
411        ld      bc, 0                       ; attributes for columns 24 and 25
412        push    bc                          ; update columns 24 and 25
413        push    de                          ; update columns 22 and 23
414        push    hl                          ; update columns 20 and 21
415        exx
416        push    bc                          ; update columns 18 and 19
417        push    de                          ; update columns 16 and 17
418        push    hl                          ; update columns 14 and 15
419        ld      hl, 0                       ; attributes for columns 8 and 9
420        ld      de, 0                       ; attributes for columns 10 and 11
421        ld      bc, 0                       ; attributes for columns 12 and 13
422        push    bc                          ; update columns 12 and 13
423        push    de                          ; update columns 10 and 11
424        push    hl                          ; update columns 8 and 9
425        ld      sp, $5822+(ROWREPT*32)+30   ; reference columns 30 and 31
426        ld      hl, 0                       ; attributes for columns 26 and 27
427        ld      de, 0                       ; attributes for columns 28 and 29
428        ld      bc, 0                       ; attributes for columns 30 and 31
429        push    bc                          ; update columns 30 and 31
430        push    de                          ; update columns 28 and 29
431        push    hl                          ; update columns 26 and 27
432')
433')
434
435ELSE
436
437; synchronize with raster beam while updating first attribute pair of each row
438; spectrum 48k/128k timing
439Z88DK_FOR(`ROWREPT', `0', `22',
440`
441IF ((ROWREPT = 4) || (ROWREPT = 9) || (ROWREPT = 14))
442        ld      b, 3
443        djnz    ASMPC                   ; extra delay
444ELSE
445IF (ROWREPT = 20)
446        nop                             ; extra delay
447ENDIF
448ENDIF
449
450        ld      hl, (race_raster+(ROWREPT*328)+25)
451IF (ROWREPT < __NIRVANAP_TOTAL_ROWS)
452        ld      ($5820+(ROWREPT*32)), hl
453ELSE
454        ld      hl, ($5820+(ROWREPT*32))
455ENDIF
456')
457
458; race the raster beam to update attributes on screen at the right time
459race_raster:
460Z88DK_FOR(`ROWREPT', `0', eval(__NIRVANAP_TOTAL_ROWS-1),
461`
462Z88DK_FOR(`LINREPT', `0', `3',
463`
464        ld      ix, 0                       ; attributes for columns 14 and 15
465        ld      iy, 0                       ; attributes for columns 22 and 23
466        ld      bc, 0                       ; attributes for columns 8 and 9
467        ld      de, 0                       ; attributes for columns 10 and 11
468        ld      hl, 0                       ; attributes for columns 12 and 13
469        exx
470        ld      bc, 0                       ; attributes for columns 16 and 17
471        ld      de, 0                       ; attributes for columns 18 and 19
472        ld      hl, 0                       ; attributes for columns 0 and 1
473IF (LINREPT = 0)
474        ld      sp, $5822+(ROWREPT*32)+24   ; reference columns 24 and 25 on next row
475        push    hl                          ; trash columns 24 and 25 (fixed below)
476ELSE
477        ld      a, (hl)                     ; extra delay
478        ld      ($5820+(ROWREPT*32)), hl    ; update columns 0 and 1
479ENDIF
480        ld      hl, 0                       ; attributes for columns 2 and 3
481        ld      ($5820+(ROWREPT*32)+2), hl  ; update columns 2 and 3
482        ld      hl, 0                       ; attributes for columns 4 and 5
483        ld      ($5820+(ROWREPT*32)+4),hl   ; update columns 4 and 5
484        ld      hl, 0                       ; attributes for columns 20 and 21
485        push    iy                          ; update columns 22 and 23
486        push    hl                          ; update columns 20 and 21
487        push    de                          ; update columns 18 and 19
488        push    bc                          ; update columns 16 and 17
489        exx
490        push    ix                          ; update columns 14 and 15
491        push    hl                          ; update columns 12 and 13
492        push    de                          ; update columns 10 and 11
493        push    bc                          ; update columns 8 and 9
494        ld      hl, 0                       ; attributes for columns 6 and 7
495        push    hl                          ; update columns 6 and 7
496        ld      sp, $5822+(ROWREPT*32)+28   ; reference columns 28 and 29
497        ld      bc, 0                       ; attributes for columns 24 and 25
498        ld      de, 0                       ; attributes for columns 26 and 27
499        ld      hl, 0                       ; attributes for columns 28 and 29
500        push    hl                          ; update columns 28 and 29
501        push    de                          ; update columns 26 and 27
502        push    bc                          ; update columns 24 and 25
503        ld      hl, 0                       ; attributes for columns 30 and 31
504        ld      ($5820+(ROWREPT*32)+30),hl  ; update columns 30 and 31
505')
506')
507
508ENDIF
509
510exit_raster:
511; restore stack pointer
512        ld      sp, 0
513
514; available entry-point for additional interrupt routines
515_NIRVANAP_ISR_HOOK:
516        ld      hl, 0
517
518; restore all registers
519        pop     iy
520        pop     ix
521        pop     hl
522        pop     de
523        pop     bc
524        pop     af
525        exx
526        ex      af, af'
527        pop     hl
528        pop     de
529        pop     bc
530        pop     af
531
532_NIRVANAP_ISR_STOP:
533        ei
534        reti
535
536; -----------------------------------------------------------------------------
537; Insert Space Here
538; -----------------------------------------------------------------------------
539
540defs 64262 - org_nirvanap - ASMPC
541
542; -----------------------------------------------------------------------------
543; Draw tile at specified position (in 1712T)
544;
545; Params:
546;     A = tile index (0-255)
547;     D = pixel line (0-200, even values only)
548;     E = char column (0-30)
549;
550; Address: 64262
551;
552; WARNING: Computer will crash if an interrupt occurs during execution!
553; -----------------------------------------------------------------------------
554
555PUBLIC asm_NIRVANAP_drawT
556PUBLIC _NIRVANAP_TILE_IMAGES
557
558asm_NIRVANAP_drawT:
559; preserve stack pointer
560        ld      (exit_draw+1), sp
561
562; calculate screen bitmap lookup address
563        ld      h, bitmaps/256
564        ld      l, d
565        ld      sp, hl
566
567; preserve values
568        ld      b, e
569        ld      c, h
570
571; calculate tile image address
572        ld      h, 0
573        ld      l, a
574        ld      d, h
575        ld      e, l
576        add     hl, hl
577        add     hl, de
578        add     hl, hl
579        add     hl, hl
580        add     hl, hl
581        add     hl, hl
582defc _NIRVANAP_TILE_IMAGES = ASMPC + 1
583        ld      de, __NIRVANAP_TILE_IMAGES
584        add     hl, de
585
586; draw bitmap lines
587Z88DK_FOR(`LOOP', `1', `8',
588`
589        pop     de
590        ld      a, e
591        add     a, b
592        ld      e, a
593        ldi
594        ld      a, (hl)
595        ld      (de), a
596        inc     hl
597        dec     e
598        inc     d
599        ldi
600        ldi
601')
602
603; calculate routine attribute address
604        ex      de, hl
605
606        ld      h, deltas/256
607        ld      l, b
608        inc     l
609        ld      c, (hl)
610        inc     l
611        ld      a, (hl)
612        ex      af, af'
613
614        ld      hl, attribs - bitmaps - 16
615        ld      b, h
616        add     hl, sp
617        ld      sp, hl
618
619; set 1st column of routine attributes
620Z88DK_FOR(`LOOP', `1', `8',
621`
622        pop     hl
623        add     hl, bc
624        ld      a, (de)
625        ld      (hl), a
626        inc     de
627')
628        ex      af, af'
629        ld      c, a
630        ld      hl, -16
631        add     hl, sp
632        ld      sp, hl
633
634; set 2nd column of routine attributes
635Z88DK_FOR(`LOOP', `1', `7',
636`
637        pop     hl
638        add     hl, bc
639        ld      a, (de)
640        ld      (hl), a
641        inc     de
642')
643        pop     hl
644        add     hl, bc
645        ld      a, (de)
646        ld      (hl), a
647
648exit_draw:
649; restore stack pointer
650        ld      sp, 0
651        ret
652
653; -----------------------------------------------------------------------------
654bitmaps:
655; lookup table with screen coordinates
656Z88DK_FOR(`LOOP', `1', `8',
657`
658        defw      0
659')
660Z88DK_FOR(`ROWREPT', `0', eval(__NIRVANAP_TOTAL_ROWS-1),
661`
662Z88DK_FOR(`LIN2REPT', `0', `3',
663`
664        defw      16384 + (((ROWREPT+1)/8)*2048) + (LIN2REPT*512) + (((ROWREPT+1)%8)*32)
665')
666')
667
668Z88DK_FOR(`LOOP', `1', eval(4*(23-__NIRVANAP_TOTAL_ROWS)),
669`
670        defw      0
671')
672; -----------------------------------------------------------------------------
673attribs:
674; lookup table with render attribute coordinates
675Z88DK_FOR(`LOOP', `1', `8',
676`
677        defw      0
678')
679Z88DK_FOR(`RACEREPT', `0', eval(4*__NIRVANAP_TOTAL_ROWS-1),
680`
681        defw      race_raster + (RACEREPT*82)
682')
683Z88DK_FOR(`LOOP', `1', eval(4*(23-__NIRVANAP_TOTAL_ROWS)),
684`
685        defw      0
686')
687Z88DK_FOR(`LOOP', `1', `8',
688`
689        defw      0
690')
691; -----------------------------------------------------------------------------
692; Insert Space Here
693; -----------------------------------------------------------------------------
694
695defs 64928 - org_nirvanap - ASMPC
696
697; -----------------------------------------------------------------------------
698; Fill specified tile position with attribute value (in 502T)
699;
700; Params:
701;     A = attribute value (0-255)
702;     D = pixel line (0-200, even values only)
703;     E = char column (0-30)
704;
705; Address: 64928
706;
707; WARNING: Computer will crash if an interrupt occurs during execution!
708; -----------------------------------------------------------------------------
709
710PUBLIC asm_NIRVANAP_fillT
711
712asm_NIRVANAP_fillT:
713; preserve stack pointer
714        ld      (exit_fill+1), sp
715
716; calculate first routine attribute address
717        ld      hl, attribs
718        ld      b, 0
719        ld      c, d                    ; pixel line
720        add     hl, bc
721        ld      sp, hl
722
723        ld      h, deltas/256
724        ld      l, e                    ; char column
725        inc     l
726        ld      c, (hl)                 ; BC = 1st delta (column offset)
727        inc     l
728        ld      l, (hl)                 ; HL = 2nd delta (column offset)
729        ld      h, b
730        sbc     hl, bc
731        ex      de, hl                  ; DE = difference between column offsets
732
733; update attribute addresses to specified value
734Z88DK_FOR(`LOOP', `1', `8',
735`
736        pop     hl
737        add     hl, bc
738        ld      (hl), a
739        add     hl, de
740        ld      (hl), a
741')
742exit_fill:
743; restore stack pointer
744        ld      sp, 0
745        ret
746
747; -----------------------------------------------------------------------------
748; Activate NIRVANA engine.
749;
750; Address: 64995
751; -----------------------------------------------------------------------------
752
753PUBLIC asm_NIRVANAP_start
754
755asm_NIRVANAP_start:
756        di
757IF ((__SPECTRUM & __SPECTRUM_PENTAGON) = 0)
758        ld      a, ($004c)
759        and     2
760        ld      (delay_128k-1), a
761ENDIF
762        ld      a, $fe
763        ld      i, a
764        im      2
765        ld      hl,main_engine
766        ld      ($fdfe),hl
767        ei
768        ret
769
770; -----------------------------------------------------------------------------
771; Deactivate NIRVANA engine.
772; replaced
773; -----------------------------------------------------------------------------
774;
775;PUBLIC asm_NIRVANAP_stop
776;
777;asm_NIRVANAP_stop:
778;        di
779;        ld      a, $3f
780;        ld      i, a
781;        im      1
782;        ei
783;        ret
784
785; -----------------------------------------------------------------------------
786; Insert Space Here
787; -----------------------------------------------------------------------------
788
789defs 0xfdfd - org_nirvanap - ASMPC
790
791; -----------------------------------------------------------------------------
792; interrupt address at $fdfd
793        jp      main_engine
794
795; -----------------------------------------------------------------------------
796; jump vector table at addresses $fe00-$ff00
797        defs 257, 0xfd
798
799; -----------------------------------------------------------------------------
800deltas:
801IF (__SPECTRUM & __SPECTRUM_PENTAGON)
802; lookup table with deltas (column offsets)
803; pentagon
804        defb      21, 22, 33, 34, 24, 25, 27, 28, 58, 59, 61, 62, 64, 65, 11, 12
805        defb      14, 15, 17, 18, 42, 43, 45, 46, 48, 49, 73, 74, 76, 77, 79, 80
806ELSE
807; lookup table with deltas (column offsets)
808        defb      25, 26, 32, 33, 38, 39, 58, 59, 9, 10, 12, 13, 15, 16, 2, 3
809        defb      19, 20, 22, 23, 44, 45, 6, 7, 65, 66, 68, 69, 71, 72, 77, 78
810ENDIF
811; -----------------------------------------------------------------------------
812; Fill specified 8x8 block with attribute value (in 165T)
813;
814; Params:
815;     C = attribute value (0-255)
816;     D = pixel line (16-192, even values only)
817;     E = char column (0-31)
818;
819; Address: 65313
820; -----------------------------------------------------------------------------
821
822PUBLIC asm_NIRVANAP_fillC
823
824asm_NIRVANAP_fillC:
825; calculate initial routine attribute address
826        ld      h, 0
827        ld      l, d
828        ld      d, deltas/256
829        inc     e
830        ld      a, (de)
831        ld      de, attribs
832        add     hl, de
833        add     a, (hl)
834        ld      e, a
835        inc     l
836        adc     a, (hl)
837        sub     e
838        ld      d, a
839        ex      de, hl
840
841; update attributes
842        ld      de, 82
843
844        ld      (hl), c
845        add     hl, de
846
847        ld      (hl), c
848        add     hl, de
849
850        ld      (hl), c
851        add     hl, de
852
853        ld      (hl), c
854        ret
855
856; -----------------------------------------------------------------------------
857; Retrieve a sequence of 4 attribute values from specified 8x8 block (in 211T)
858;
859; Params:
860;     D = pixel line (16-192, even values only)
861;     E = char column (0-31)
862;     BC = attributes address
863;
864; Address: 65342
865; -----------------------------------------------------------------------------
866
867PUBLIC asm_NIRVANAP_readC
868
869asm_NIRVANAP_readC:
870; calculate initial routine attribute address
871        ld      h, 0
872        ld      l, d
873        ld      d, deltas/256
874        inc     e
875        ld      a, (de)
876        ld      de, attribs
877        add     hl, de
878        add     a, (hl)
879        ld      e, a
880        inc     l
881        adc     a, (hl)
882        sub     e
883        ld      d, a
884        ex      de, hl
885
886; read attributes
887        ld      de, 82
888
889        ld      a, (hl)
890        ld      (bc), a
891        inc     bc
892        add     hl, de
893
894        ld      a, (hl)
895        ld      (bc), a
896        inc     bc
897        add     hl, de
898
899        ld      a, (hl)
900        ld      (bc), a
901        inc     bc
902        add     hl, de
903
904        ld      a, (hl)
905        ld      (bc), a
906        ret
907