1include(`z88dk.m4') 2include(`config_private.inc') 3 4; ----------------------------------------------------------------------------- 5; BIFROST* ENGINE by Einar Saukas - v1.2/L 6; A Rainbow Graphics Support Engine for Animated Tiles 7; 8; Based on the ZXodus Engine by Andrew Owen 9; Most 16x16 tiles created by Dave Hughes (R-Tape) 10; 11; Adapted to z88dk by aralbrec 12; ----------------------------------------------------------------------------- 13 14SECTION BIFROSTL 15org $e501 16 17; ----------------------------------------------------------------------------- 18attribs: 19Z88DK_FOR(`ROWREPT', `0', `17', 20` 21 defw race_raster + (ROWREPT * 8 * 41) 22') 23; ----------------------------------------------------------------------------- 24 25PUBLIC asm_BIFROSTL_fillTileAttrL 26 27asm_BIFROSTL_fillTileAttrL: 28fill_tile_attr: 29 30; calculate multicolor attribute address 31 ld h, attribs/256 32 ld l, e 33 set 6, l 34 ld a, (hl) ; A = delta (column offset) 35 ld l, d 36 sla l 37 ld d, (hl) 38 dec l 39 add a, (hl) 40 ld l, a 41 adc a, d 42 sub l 43 ld h, a 44 45; replace attrib with value C 46 ld de, 40 47 ld b, 16 48fill_loop: 49 ld (hl), c 50 inc hl 51 ld (hl), c 52 add hl, de 53 djnz fill_loop 54 ret 55 56; ----------------------------------------------------------------------------- 57deltas: 58 defb 4, 5, 7, 8, 10, 11, 14, 15, 17, 18, 32, 33, 28, 29, 24, 25, 20, 21, 20 59; ----------------------------------------------------------------------------- 60 61skip_tile: 62 ld b, $71 63delay_skip: 64 djnz delay_skip 65 sbc hl, hl ; extra delay 66 ret 67 68; ----------------------------------------------------------------------------- 69 70show_next3_delayed1: 71 nop ; extra delay 72show_next3_delayed2: 73 ld bc, $8f00 74delay_show: 75 djnz delay_show 76 call show_next_tile 77 call show_next_tile 78 79PUBLIC asm_BIFROSTL_showNextTile 80 81asm_BIFROSTL_showNextTile: 82show_next_tile: 83 ld de, $0101 ; D = row, E = col (1,3,5..17) 84 ld a, e 85 sub __BIFROSTL_TILE_ORDER * 2 86 ld e, a 87 sbc a, a 88 and 18 89 add a, e 90 ld e, a 91 sbc a, a 92 ld c, a 93 add a, a 94 add a, d 95 ld d, a 96 sbc a, a 97 xor c 98 and 18 99 add a, d 100 ld d, a 101 ld (show_next_tile+1), de 102 103; ----------------------------------------------------------------------------- 104 105PUBLIC asm_BIFROSTL_showTilePosL 106PUBLIC _BIFROSTL_tilemap 107 108defc _BIFROSTL_tilemap = __BIFROSTL_TILE_MAP 109 110asm_BIFROSTL_showTilePosL: 111show_tile_pos: ; D = row, E = col 112 ld a, d 113 rlca 114 rlca 115 rlca 116 add a, d 117 add a, e 118 sub 8 119 rra 120 ld l, a 121 ld h, __BIFROSTL_TILE_MAP/256 122 123get_tile: 124 ld a,(hl) 125 cp __BIFROSTL_STATIC_MIN 126 jp c, animate_tile 127 inc a 128 jr z, skip_tile 129 sub 1+__BIFROSTL_STATIC_OVERLAP 130 jr draw_tile 131animate_tile: 132 rrca 133IF __BIFROSTL_ANIM_GROUP=4 134 rrca 135 add a, $40 136 rlca 137ELSE 138 nop 139 add a, $80 140 nop 141ENDIF 142 rlca 143 ld (hl), a 144 145; ----------------------------------------------------------------------------- 146 147PUBLIC asm_BIFROSTL_drawTileL 148PUBLIC _BIFROSTL_TILE_IMAGES 149 150asm_BIFROSTL_drawTileL: 151draw_tile: ; D = row, E = col, A = tile 152 153; calculate tile image address 154 ld (exit_draw+1), sp 155 ld l, 0 156 srl a 157 rr l 158 rra 159 rr l 160 ld h, a 161defc _BIFROSTL_TILE_IMAGES = ASMPC + 1 162 ld bc, __BIFROSTL_TILE_IMAGES 163 add hl, bc 164 ld sp, hl 165 166; calculate screen bitmap address 167 ld a, d ; DE = 000RRrrr 000ccccc 168 and %00000111 169 rrca 170 rrca 171 rrca 172 or e 173 ld l, a ; L = rrrccccc 174 ld a, d 175 and %00011000 176 or %01000000 177 ld h, a ; H = 010RR000 178 179; draw first bitmap row 180Z88DK_FOR(`LOOP', `1', `7', 181` 182 pop bc 183 ld (hl),c 184 inc l 185 ld (hl),b 186 dec l 187 inc h 188') 189 pop bc 190 ld (hl),c 191 inc l 192 ld (hl),b 193; move to next bitmap row 194 ld bc, 31 195 add hl, bc 196 ld a, h 197 and 248 198 ld h, a 199; draw second bitmap row 200Z88DK_FOR(`LOOP', `1', `7', 201` 202 pop bc 203 ld (hl),c 204 inc l 205 ld (hl),b 206 dec l 207 inc h 208') 209 pop bc 210 ld (hl),c 211 inc l 212 ld (hl),b 213 214; calculate multicolor attribute address 215 ld h, attribs/256 216 ld l, e 217 set 6, l 218 ld a, (hl) ; A = delta (column offset) 219 ld l, d 220 sla l 221 ld d, (hl) 222 dec l 223 add a, (hl) 224 ld l, a 225 adc a, d 226 sub l 227 ld h, a 228 229; draw multicolor attribute 230 ld de, 40 231Z88DK_FOR(`LOOP', `1', `15', 232` 233 pop bc 234 ld (hl), c 235 inc hl 236 ld (hl), b 237 add hl, de 238') 239 pop bc 240 ld (hl), c 241 inc hl 242 ld (hl), b 243 244exit_draw: 245 ld sp, 0 246 ret 247 248; ----------------------------------------------------------------------------- 249 250PUBLIC _BIFROSTL_ISR_HOOK 251 252main_engine: 253; preserve all registers 254 push af 255 push bc 256 push de 257 push hl 258 ex af, af' 259 exx 260 push af 261 push bc 262 push de 263 push hl 264 265tile_mapping_begin: 266; draw and animate first 3 tiles 267 call show_next3_delayed1 268IF __BIFROSTL_ANIM_SPEED=4 269 ld a, $c6 270ELSE 271 ld a, $fe 272ENDIF 273 ld (animate_tile+2), a 274; draw (and perhaps animate) another 3 tiles 275 call show_next3_delayed2 276 ld a, $c6 277 ld (animate_tile+2), a 278tile_mapping_end: 279 280; synchronize with the raster beam 281 ld bc, $3805 282 ld a, 14 283 jr sync_raster 284delay_128k: 285 ld b, $3b 286 287sync_raster: 288 nop ; extra delay 289sync_raster_loop: 290 djnz sync_raster_loop 291 ld b, a 292 ld hl, ($4000) ; synchronize 293 dec c 294 jr nz, sync_raster 295 296; wait for the raster beam 297 ld a, (bc) ; extra delay 298 ld b, 4 299wait_raster: 300 djnz wait_raster 301 302; preserve stack pointer 303 ld (exit_raster+1), sp 304 305; race the raster beam to update attributes at the right time 306race_raster: 307Z88DK_FOR(`ROWREPT', `0', `17', 308` 309Z88DK_FOR(`LOOP', `1', `8', 310` 311 ld sp, $5833+(32*ROWREPT) 312 ld bc, 0 ; columns 01 and 02 313 ld de, 0 ; columns 03 and 04 314 ld hl, 0 ; columns 05 and 06 315 exx 316 ld de, 0 ; columns 07 and 08 317 ld hl, 0 ; columns 09 and 10 318 ld bc, 0 ; columns 17 and 18 319 push bc 320 ld bc, 0 ; columns 15 and 16 321 push bc 322 ld bc, 0 ; columns 13 and 14 323 push bc 324 ld bc, 0 ; columns 11 and 12 325 push bc 326 push hl 327 push de 328 exx 329 push hl 330 push de 331 push bc 332') 333') 334exit_raster: 335; restore stack pointer 336 ld sp, 0 337; restore all registers 338 pop hl 339 pop de 340 pop bc 341 pop af 342 exx 343 ex af, af' 344 pop hl 345 pop de 346 pop bc 347 pop af 348_BIFROSTL_ISR_HOOK: 349 ei 350 reti 351 352; ----------------------------------------------------------------------------- 353; RAND USR 64995 to activate engine 354 355PUBLIC asm_BIFROSTL_start 356 357asm_BIFROSTL_start: 358 359 di 360 ld a, ($004c) 361 and 2 362 ld (delay_128k-1), a 363 ld a, $fe 364 ld i, a 365 im 2 366 ld hl,main_engine 367 ld ($fdfe),hl 368 ei 369 ret 370 371; ----------------------------------------------------------------------------- 372; RAND USR 65012 to deactivate engine 373; replaced 374; 375;PUBLIC asm_BIFROSTL_stop 376; 377;asm_BIFROSTL_stop: 378; 379; di 380; ld a, $3f 381; ld i, a 382; im 1 383; ei 384; ret 385; 386 387defs $fdfd - $e501 - ASMPC 388 389; ----------------------------------------------------------------------------- 390; interrupt address at $fdfd 391 jp main_engine 392 393; ----------------------------------------------------------------------------- 394; jump vector table at addresses $fe00-$ff00 395 396 defs 257, 0xfd 397 398; ----------------------------------------------------------------------------- 399