1include(`z88dk.m4') 2include(`config_private.inc') 3 4; ----------------------------------------------------------------------------- 5; BIFROST* ENGINE by Einar Saukas - v1.2/H 6; A Rainbow Graphics Support Engine for Animated Tiles 7; 8; Most 16x16 tiles created by Dave Hughes (R-Tape) 9; Adapted to z88dk by aralbrec 10; ----------------------------------------------------------------------------- 11 12SECTION BIFROSTH 13org $ded7 14 15PUBLIC _BIFROSTH_tilemap 16defc _BIFROSTH_tilemap = __BIFROSTH_TILE_MAP 17 18; ----------------------------------------------------------------------------- 19 20PUBLIC asm_BIFROSTH_drawBackTilesH 21 22asm_BIFROSTH_drawBackTilesH: 23draw_back_tiles: 24 bit 0, e 25 jr nz, draw_updown_tiles 26 push de 27 push bc 28 dec e 29 call draw_updown_tiles 30 pop bc 31 pop de 32 inc e 33draw_updown_tiles: 34 ld a, e 35 cp 19 36 ret nc 37 ld a, d 38 and $0f 39 jr z, draw_tile_pos 40 xor d 41 ld d, a 42 push de 43 push bc 44 call nz, draw_tile_pos 45 pop bc 46 pop de 47 ld a, d 48 add a, 16 49 ld d, a 50 51PUBLIC asm_BIFROSTH_drawTilePosH 52 53asm_BIFROSTH_drawTilePosH: 54draw_tile_pos: 55 ld a, d 56 cp 160 57 ret nc 58 rrca 59 rrca 60 rrca 61 add a, d 62 add a, e 63 sub 17 64 rra 65 ld l, a 66 ld h, __BIFROSTH_TILE_MAP/256 67 ld a,(hl) 68 ld hl, get_tile+2 69 cp (hl) 70 jp c, draw_tile 71 inc a 72 jp nz, get_tile+9 73 74; ----------------------------------------------------------------------------- 75 76PUBLIC asm_BIFROSTH_fillTileAttrH 77 78asm_BIFROSTH_fillTileAttrH: 79fill_tile_attr: 80 ld (exit_draw+1), sp 81 82; calculate multicolor attribute address 83 ld a, c 84 ld h, attribs/512 85 ld l, d 86 add hl, hl 87 ld bc, attribs-((attribs/512)*512) 88 add hl, bc 89 ld sp, hl 90 ld h, deltas/256 91 ld l, e 92 ld c, (hl) ; BC = delta (column offset) 93 dec b 94 inc l 95 ld l, (hl) ; HL = second delta (column offset) 96 ld h, b 97 sbc hl, bc 98 ex de, hl 99 100; replace attrib with value 101Z88DK_FOR(`LOOP', `1', `16', 102` 103 pop hl 104 add hl, bc 105 ld (hl), a 106 add hl, de 107 ld (hl), a 108') 109 jp exit_draw 110 111; ----------------------------------------------------------------------------- 112draw_at_last_col: 113; draw multicolor attributes of a tile starting at the last column in the multicolor area 114Z88DK_FOR(`LOOP', `1', `15', 115` 116 pop hl 117 ld c, a 118 add hl, bc 119 ex de, hl 120 ldi 121 inc hl 122 ex de, hl 123') 124 pop hl 125 ld c, a 126 add hl, bc 127 ex de, hl 128 jp ldi_exit_draw 129 130; ----------------------------------------------------------------------------- 131bitmaps: 132; lookup table with screen coordinates 133Z88DK_FOR(`LOOP', `1', `16', 134` 135 defw 0 136') 137Z88DK_FOR(`ROWREPT', `0', `17', 138` 139Z88DK_FOR(`LINREPT', `0', `7', 140` 141 defw 16384 + (((ROWREPT+1)/8)*2048) + (LINREPT*256) + (((ROWREPT+1)%8)*32) + __BIFROSTH_SHIFT_COLUMNS 142') 143') 144Z88DK_FOR(`LOOP', `1', `16', 145` 146 defw 0 147') 148; ----------------------------------------------------------------------------- 149attribs: 150; lookup table with multicolor attribute coordinates 151Z88DK_FOR(`LOOP', `1', `16', 152` 153 defw 0 154') 155Z88DK_FOR(`RACEREPT', `0', `143', 156` 157 defw race_raster + (RACEREPT * 41) 158') 159Z88DK_FOR(`LOOP', `1', `16', 160` 161 defw 0 162') 163; ----------------------------------------------------------------------------- 164 defb 0 165show_next3_delayed: 166 nop ; extra delay 167 nop ; extra delay 168 jp show_next3 169 170; ----------------------------------------------------------------------------- 171draw_sprites: 172 ld de, 0 ; first sprite: D = lin, E = col 173 ld bc, 0 ; first sprite: C = tile 174 call draw_sprite 175 ld de, 0 ; second sprite: D = lin, E = col 176 ld c, 0 ; second sprite: C = tile 177draw_sprite: 178; execute draw_tile with different delays depending on column 179 ld b, 81 ; delay for draw_at_odd_col 180 ld a, e 181 rrca 182 dec a 183 jr c, sprite_loop1 184 ld b, 44 ; delay for draw_at_even_col_inc 185 cp 5 186 jr c, sprite_loop2 187 ld b, 40 ; delay for draw_at_even_col_dec 188 cp 8 189 jr nz, sprite_loop 190 ld b, 86 ; delay for draw_at_last_col 191sprite_loop2: 192 sbc hl, hl ; extra delay 193sprite_loop1: 194 inc hl ; extra delay 195sprite_loop: 196 dec b 197 jr nz, sprite_loop 198skip_sprite_loop: 199 ld a, c 200 jp draw_tile 201 202; ----------------------------------------------------------------------------- 203draw_at_even_col_dec: 204; draw multicolor attributes of a tile starting at even column with non-increasing delta 205 cp 21 206 jp z, draw_at_last_col 207 ld c, a 208 inc l 209 sub (hl) ; (HL) = second delta (column offset) 210 jp c, draw_at_even_col_inc 211 inc a 212 ex af, af' 213 ld a, c 214Z88DK_FOR(`LOOP', `1', `15', 215` 216 pop hl 217 ld c, a 218 add hl, bc 219 ex de, hl 220 ldi 221 ex de, hl 222 ex af, af 223 ld c, a 224 sbc hl, bc 225 ex de, hl 226 ldi 227 ex de, hl 228 ex af, af 229') 230 pop hl 231 ld c, a 232 add hl, bc 233 ex de, hl 234 ldi 235 ex de, hl 236 ex af, af' 237 ld c, a 238 sbc hl, bc 239 ex de, hl 240 jp ldi_exit_draw 241 242; ----------------------------------------------------------------------------- 243deltas: 244; lookup table with deltas (column offsets) 245IF __BIFROSTH_SHIFT_COLUMNS=0 246 defb 4, 4, 5, 7, 8, 10, 11, 14, 15, 17, 18, 32, 33, 28, 29, 24, 25, 20, 21, 21 247ELSE 248 defb 4, 4, 5, 7, 8, 10, 11, 14, 15, 33, 34, 29, 30, 24, 25, 20, 21, 17, 18, 18 249ENDIF 250 251; ----------------------------------------------------------------------------- 252draw_at_even_col_inc: 253; draw multicolor attributes of a tile starting at even column with increasing delta 254 cpl 255 ex af, af' 256 ld a, c 257Z88DK_FOR(`LOOP', `1', `15', 258` 259 pop hl 260 261 ld c, a 262 add hl, bc 263 ex de, hl 264 ldi 265 ex de, hl 266 ex af, af 267 268 ld c, a 269 add hl, bc 270 ex de, hl 271 ldi 272 ex de, hl 273 ex af, af 274') 275 pop hl 276 ld c, a 277 add hl, bc 278 ex de, hl 279 ldi 280 ex de, hl 281 ex af, af' 282 ld c, a 283 add hl, bc 284 ex de, hl 285 jp ldi_exit_draw 286 287; ----------------------------------------------------------------------------- 288skip_tile: 289 ld b, $84 290delay_tile: 291 dec b 292 jr nz, delay_tile 293 ret 294 295; ----------------------------------------------------------------------------- 296show_next3: 297 call show_next_tile 298 call show_next_tile 299 300PUBLIC asm_BIFROSTH_showNextTile 301 302asm_BIFROSTH_showNextTile: 303show_next_tile: 304 ld de, $1001 ; D = lin (16,32,48..144), E = col (1,3,5..17) 305 ld a, e 306 sub +(9-__BIFROSTH_TILE_ORDER)*2 307 ld e, a 308 jr nc, prev_lin 309 add a, 18 310 ld e, a 311 xor a 312 jr reset_lin 313prev_lin: 314 ld a, d 315 sub 16 316 ld d, a 317 cp 16 318reset_lin: 319 sbc a, a 320 and 144 321 add a, d 322 ld d, a 323 ld (show_next_tile+1), de 324 325; ----------------------------------------------------------------------------- 326 327PUBLIC asm_BIFROSTH_showTilePosH 328 329asm_BIFROSTH_showTilePosH: 330show_tile_pos: ; D = lin (0..160), E = col (0..18) 331 ld a, d 332 rrca 333 rrca 334 rrca 335 add a, d 336 add a, e 337 sub 17 338 rra 339 ld l, a 340 ld h, __BIFROSTH_TILE_MAP/256 341 342get_tile: 343 ld a,(hl) 344 cp __BIFROSTH_STATIC_MIN 345 jp c, animate_tile 346 inc a 347 jr z, skip_tile 348 sub 1+__BIFROSTH_STATIC_OVERLAP 349 jr draw_tile 350animate_tile: 351 rrca 352IF __BIFROSTH_ANIM_GROUP=4 353 rrca 354 add a, $40 355 rlca 356ELSE 357 nop 358 add a, $80 359 nop 360ENDIF 361 rlca 362 ld (hl), a 363 364; ----------------------------------------------------------------------------- 365 366PUBLIC asm_BIFROSTH_drawTileH 367PUBLIC _BIFROSTH_TILE_IMAGES 368 369asm_BIFROSTH_drawTileH: 370draw_tile: ; D = lin, E = col, A = tile 371; calculate screen bitmap lookup address 372 ld (exit_draw+1), sp 373 ld h, bitmaps/512 374 ld l, d 375 add hl, hl 376 ld sp, hl 377 378; preserve values 379 ld b, e 380 ld c, h 381 382; calculate tile image address 383 ld l, 0 384 srl a 385 rr l 386 rra 387 rr l 388 ld h, a 389defc _BIFROSTH_TILE_IMAGES = ASMPC + 1 390 ld de, __BIFROSTH_TILE_IMAGES 391 add hl, de 392 393; draw bitmap lines 394Z88DK_FOR(`LOOP', `1', `16', 395` 396 pop de 397 ld a, e 398 add a, b 399 ld e, a 400 ldi 401 ldi 402') 403; calculate multicolor attribute address 404 ex de, hl 405 ld hl, attribs-bitmaps-32 406 add hl, sp 407 ld sp, hl 408 ld h, deltas/256 409 ld l, b 410 ld a, (hl) ; A = delta (column offset) 411 412; distinguish between even/odd column 413 ld b, 0 414 bit 0, l 415 jp z, draw_at_even_col_dec 416 417draw_at_odd_col: 418; draw multicolor attributes starting at odd column 419Z88DK_FOR(`LOOP', `1', `15', 420` 421 pop hl 422 ld c, a 423 add hl, bc 424 ex de, hl 425 ldi 426 ldi 427 ex de, hl 428') 429 pop hl 430 ld c, a 431 add hl, bc 432 ex de, hl 433 ldi 434ldi_exit_draw: 435 ldi 436 437exit_draw: 438 ld sp, 0 439 ret 440 441; ----------------------------------------------------------------------------- 442 443PUBLIC _BIFROSTH_ISR_HOOK 444 445main_engine: 446; preserve all registers 447 push af 448 push bc 449 push de 450 push hl 451 ex af, af' 452 exx 453 push af 454 push bc 455 push de 456 push hl 457 458tile_mapping_begin: 459; draw and animate first 3 tiles 460 call show_next3_delayed 461IF __BIFROSTH_ANIM_SPEED=4 462 ld a, $c6 463ELSE 464 ld a, $fe 465ENDIF 466 ld (animate_tile+2), a 467IF __BIFROSTH_SPRITE_MODE=0 468; draw (and perhaps animate) another 3 tiles 469 call show_next3 470ELSE 471; draw both sprite tiles 472 call draw_sprites 473ENDIF 474 ld a, $c6 475 ld (animate_tile+2), a 476tile_mapping_end: 477 478; synchronize with the raster beam 479 ld bc, $3805 480 ld a, 14 481 jr sync_raster 482delay_128k: 483 ld b, $3b 484 485sync_raster: 486 nop ; extra delay 487sync_raster_loop: 488 djnz sync_raster_loop 489 ld b, a 490 ld hl, ($4000) ; synchronize 491 dec c 492 jr nz, sync_raster 493 494; wait for the raster beam 495IF __BIFROSTH_SHIFT_COLUMNS=0 496 ld a, (bc) ; extra delay 497 ld b, 4 498ELSE 499 add hl, hl ; extra delay 500 ld b, 5 501ENDIF 502wait_raster: 503 djnz wait_raster 504 505; preserve stack pointer 506 ld (exit_raster+1), sp 507 508; race the raster beam to update attributes at the right time 509race_raster: 510Z88DK_FOR(`ROWREPT', `0', `17', 511` 512Z88DK_FOR(`LOOP', `1', `8', 513` 514IF __BIFROSTH_SHIFT_COLUMNS=0 515 ld sp, $5833+(32*ROWREPT) 516 ld bc, 0 ; columns 01 and 02 517 ld de, 0 ; columns 03 and 04 518 ld hl, 0 ; columns 05 and 06 519 exx 520 ld de, 0 ; columns 07 and 08 521 ld hl, 0 ; columns 09 and 10 522 ld bc, 0 ; columns 17 and 18 523 push bc 524 ld bc, 0 ; columns 15 and 16 525 push bc 526 ld bc, 0 ; columns 13 and 14 527 push bc 528 ld bc, 0 ; columns 11 and 12 529 push bc 530 push hl 531 push de 532 exx 533 push hl 534 push de 535 push bc 536ELSE 537 ld sp, $5837+(32*ROWREPT) 538 ld hl, 0 ; columns 05 and 06 539 ld de, 0 ; columns 07 and 08 540 ld bc, 0 ; columns 09 and 10 541 exx 542 ld hl, 0 ; columns 11 and 12 543 ld de, 0 ; columns 21 and 22 544 ld bc, 0 ; columns 19 and 20 545 push de 546 ld de, 0 ; columns 17 and 18 547 push bc 548 push de 549 ld de, 0 ; columns 15 and 16 550 push de 551 ld de, 0 ; columns 13 and 14 552 push de 553 push hl 554 exx 555 push bc 556 push de 557 push hl 558ENDIF 559') 560') 561exit_raster: 562; restore stack pointer 563 ld sp, 0 564; restore all registers 565 pop hl 566 pop de 567 pop bc 568 pop af 569 exx 570 ex af, af' 571 pop hl 572 pop de 573 pop bc 574 pop af 575 576_BIFROSTH_ISR_HOOK: 577 578 ei 579 reti 580 581; ----------------------------------------------------------------------------- 582; RAND USR 64995 to activate engine 583 584PUBLIC asm_BIFROSTH_start 585 586asm_BIFROSTH_start: 587 588 di 589 ld a, ($004c) 590 and 2 591 ld (delay_128k-1), a 592 ld a, $fe 593 ld i, a 594 im 2 595 ld hl,main_engine 596 ld ($fdfe),hl 597 ei 598 ret 599 600; ----------------------------------------------------------------------------- 601; RAND USR 65012 to deactivate engine 602; replaced 603; 604;PUBLIC asm_BIFROSTH_stop 605; 606;asm_BIFROSTH_stop: 607; 608; di 609; ld a, $3f 610; ld i, a 611; im 1 612; ei 613; ret 614 615defs $fdfd - $ded7 - ASMPC 616 617; ----------------------------------------------------------------------------- 618; interrupt address at $fdfd 619 jp main_engine 620 621; ----------------------------------------------------------------------------- 622; jump vector table at addresses $fe00-$ff00 623 defs 257, 0xfd 624; ----------------------------------------------------------------------------- 625