GAME10 - Mysteries of the Forgotten Isles

2048b VERSION, x86 BIOS, P1X BOOTLOADER in boot.asm

Logic 2D game in VGA graphics, w PC Speaker sound.
Size category: 4096 bytes / 4KB
Bootloader: 512 bytes
Author: Krzysztof Krystian Jankowski
Web: smol.p1x.in/assembly/#forgotten-isles
License: MIT

COLOR PALETTES

Set of four colors per palette. 0x00 is transparency; use 0x10 for black.
1org 0x100 2use16 3 4jmp start 5 8 9PaletteSets: 10db 0x00, 0x34, 0x16, 0x1a 11db 0x00, 0xba, 0x06, 0x42 12db 0x00, 0xba, 0xbd, 0x72 13db 0x35, 0x34, 0x00, 0x00 14db 0x00, 0xd1, 0x73, 0x06 15db 0x00, 0x4a, 0x45, 0x2e 16db 0x4a, 0x48, 0x2e, 0x46 17db 0x00, 0x72, 0x78, 0x02 18db 0x00, 0x27, 0x2a, 0x2b 19db 0x00, 0x2b, 0x2c, 0x5b 20db 0x00, 0x16, 0x17, 0x19 21db 0x00, 0x1b, 0x1d, 0x1e 22db 0x00, 0x14, 0x16, 0x1f 23db 0x00, 0x1c, 0x1e, 0x1f 24db 0x35, 0x4e, 0xff, 0xff 25db 0x00, 0x04, 0x0c, 0x1f 26db 0x00, 0x71, 0x06, 0x2a 27db 0x00, 0x00, 0x75, 0x00 28
; 0x0 Grays ; 0x1 Indie top ; 0x2 Indie bottom ; 0x3 Bridge ; 0x4 Chest ; 0x5 Terrain 1 - shore ; 0x6 Terrain 2 - in land ; 0x7 Palm & Bush ; 0x8 Snake ; 0x9 Gold Coin ; 0xa Rock ; 0xb Sail ; 0xc Spider ; 0xd Web ; 0xe Ocean ; 0x0f Crab ; 0x10 Chest ; 0x11 Shadow

BRUSH REFERENCES

Brush data offset table Data: offset to brush data, Y shift
32 33BrushRefs: 34dw IndieBottomBrush, -320*4 35dw PalmBrush, -320*10 36dw SnakeBrush, -320*2 37dw RockBrush, -320 38dw SkullBrush, 0 39dw BridgeBrush, 0 40dw ChestBrush, -320*4 41dw Gold2Brush, 320 42dw GoldBrush, 320 43dw IndieTop2Brush, -320*5 44dw SpiderBrush, -320*3 45dw CrabBrush, -320*2 46dw BushBrush, -320 47

BRUSHES DATA

Set of 8xY brushes for entities Data: number of lines, palettDefaulte id, lines (8 pixels) of palette color id
51 52ShadowBrush: 53db 0x3, 0x11 54dw 0010101010101000b 55dw 1010101010101010b 56dw 0010101010101000b 57 58 59IndieTopBrush: 60db 0xa, 0x1 61dw 0000001001010000b 62dw 0000010101010100b 63dw 0000001011110000b 64dw 0000001110110000b 65dw 0000011110100000b 66dw 0000000011000000b 67dw 0000000000000000b 68dw 0000110000000000b 69dw 0000110000000000b 70dw 0000001100000000b 71 72IndieTop2Brush: 73db 0x7, 0x1 74dw 0000100010000000b 75dw 0000110101010000b 76dw 0000110101010100b 77dw 0000111011110000b 78dw 0000001110110000b 79dw 0000000010100000b 80dw 0000010000000000b 81 82IndieBottomBrush: 83db 0xa, 0x2 84dw 0011100000000000b 85dw 1101101100000000b 86dw 0101100110000000b 87dw 0101101010000000b 88dw 0010101010000000b 89dw 0000010111000000b 90dw 0010101010000000b 91dw 0010100010000000b 92dw 0011000011000000b 93dw 0001010001010000b 94 95IndieBottomFrame2Brush: 96dw 0011011100000000b 97dw 1101100110000000b 98dw 0101101010000000b 99dw 0101101010000000b 100dw 0001010111000000b 101dw 0111101010000000b 102dw 0100000010000100b 103dw 0000000000110100b 104dw 0, 0 105 106SnakeBrush: 107db 0x8, 0x8 108dw 0000000011011101b 109dw 0000001111111111b 110dw 0000001110001011b 111dw 0000001010110001b 112dw 0011000010101100b 113dw 0000100001101000b 114dw 0000010001010100b 115dw 0000110101010000b 116 117 118SpiderBrush: 119db 0xa, 0xc 120dw 0010101000000000b 121dw 1001010101000000b 122dw 0101011010100100b 123dw 0101110101011101b 124dw 1001101101111001b 125dw 0001010110010100b 126dw 0010100101011000b 127dw 0100010001000100b 128dw 1000100001000010b 129dw 0100010010000001b 130 131WebBrush: 132db 0x8, 0xd 133dw 0000001100000000b 134dw 0100111011000100b 135dw 0010001000100000b 136dw 1100011101001000b 137dw 0101110010010110b 138dw 1000011001001100b 139dw 0010000100100000b 140dw 0100110110000100b 141 142ChestBrush: 143db 0xa, 0x10 144dw 0001010000010100b 145dw 1011110101111101b 146dw 1001011010010111b 147dw 1101010101010111b 148dw 1101010101010111b 149dw 1011110101111110b 150dw 1001011111010110b 151dw 1001010101010110b 152dw 0110101010101001b 153dw 0001010101010100b 154 155ChestCloseBrush: 156db 0x8, 0x10 157dw 0000101010100000b 158dw 0010111111111000b 159dw 1011111111111110b 160dw 1110111111111011b 161dw 1011010101011110b 162dw 1101101010100111b 163dw 0111111111111101b 164dw 1001011111010110b 165 166ChestTopBrush: 167db 0x9, 0x10 168dw 0000011111000000b 169dw 0001111010111000b 170dw 0001111001101011b 171dw 0001111001010110b 172dw 0001111001010101b 173dw 0001011110010101b 174dw 0000100101111001b 175dw 0000001010010111b 176dw 0000000000101001b 177 178PalmBrush: 179db 0x11, 0x7 180dw 0000101011101011b 181dw 0010111010111110b 182dw 1011101011101011b 183dw 1010111110111011b 184dw 1011111010111110b 185dw 1011101010101110b 186dw 1110111001101110b 187dw 0011000101111011b 188dw 0000001001000000b 189dw 0000010101000000b 190dw 0000100100001100b 191dw 1100011100110000b 192dw 0010111000100011b 193dw 1110011101001000b 194dw 1001100101001000b 195dw 0100101000100100b 196dw 0000000100000000b 197 198BushBrush: 199db 0x8, 0x7 200dw 0000001000000000b 201dw 0000101110000000b 202dw 1100101011100011b 203dw 1011111011101110b 204dw 1110111110111011b 205dw 0111101110111101b 206dw 1110011011011011b 207dw 0011100101101100b 208 209BridgeBrush: 210db 0x8, 0x3 211dw 0101000001010000b 212dw 0000000000000000b 213dw 0000010101010000b 214dw 0101000000000101b 215dw 0101000000000101b 216dw 0000010101010000b 217dw 0000000000000000b 218dw 0000010100000101b 219 220RockBrush: 221db 0x8, 0xa 222dw 0000101111100000b 223dw 0010111111111000b 224dw 0010111110101110b 225dw 1011101010011010b 226dw 1010100101010110b 227dw 1010010101010110b 228dw 0110100101011001b 229dw 0001101010100100b 230 231GoldBrush: 232db 0x6, 0x9 233dw 0000111111110000b 234dw 0011101111101100b 235dw 1110111010111011b 236dw 1010111010101010b 237dw 0001101110100100b 238dw 0000010101010000b 239 240Gold2Brush: 241db 0x6, 0x9 242dw 0000001100000000b 243dw 0000001100000000b 244dw 0000001000000000b 245dw 0000001000000000b 246dw 0000000100000000b 247dw 0000000100000000b 248 249SlotBrush: 250db 0x7, 0xa 251dw 1001010000010110b 252dw 0100000000000001b 253dw 0000000000000000b 254dw 0000000000000000b 255dw 0000000000000000b 256dw 0100000000000001b 257dw 1001010000010110b 258 259ArrowBrush: 260db 0x7, 0x1 261dw 0000001110000000b 262dw 0000001110000000b 263dw 0000001110000000b 264dw 0011111110100100b 265dw 0010111110100100b 266dw 0000101110010000b 267dw 0000001001000000b 268 269SkullBrush: 270db 0x7, 0x0a 271dw 0000010101010000b 272dw 0001010101010100b 273dw 0001110111010100b 274dw 0001010101010100b 275dw 0100010101010001b 276dw 0001010101010100b 277dw 0100000101000001b 278 279ShipBackBrush: 280db 0xc, 0x4 281dw 0000011111110000b 282dw 0111110101011100b 283dw 1101010101011101b 284dw 0111110101011011b 285dw 1001011111101011b 286dw 0110100110110110b 287dw 0101101001111010b 288dw 0001011010101101b 289dw 0110100110101110b 290dw 0001101001010101b 291dw 0000010110100110b 292dw 0000000001010101b 293 294ShipMiddleBrush: 295db 0x8, 0x4 296dw 0000000010110000b 297dw 1111111110111111b 298dw 0110010110110101b 299dw 1001010101010110b 300dw 1111111010111011b 301dw 0101010101010101b 302dw 0111100101111001b 303dw 0101010101010101b 304 305ShipFrontBrush: 306db 0x8, 0x4 307dw 0001111111110100b 308dw 1111100101011111b 309dw 1010011111111010b 310dw 0111110101100100b 311dw 1101011010010000b 312dw 0110101001000000b 313dw 1010100100000000b 314dw 0101000000000000b 315 316ShipSailBrush: 317db 0x8, 0xb 318dw 0000000011101100b 319dw 0000111010111111b 320dw 1110111011111010b 321dw 1010111111101001b 322dw 0111101010010100b 323dw 0111100101000000b 324dw 1010010000000000b 325dw 0101000000000000b 326 327WioslaBrush: 328db 0x4, 0x4 329dw 1100110011000000b 330dw 1000100010000000b 331dw 0010001000100000b 332dw 0001000100010000b 333 334Ocean1Brush: 335db 0x3, 0xe 336dw 0000010101000000b 337dw 0101000000010100b 338dw 0000000000000101b 339 340Ocean2Brush: 341db 0x2, 0xe 342dw 0101000000010100b 343dw 0000010101000000b 344 345CrabBrush: 346db 0x8, 0x0f 347dw 0000000000101110b 348dw 0000101110000100b 349dw 0000000100000100b 350dw 0000010000010000b 351dw 0010011010011000b 352dw 1010100101101001b 353dw 1001010101010110b 354dw 0100010000010000b 355 356CrabClawBrush: 357db 0x6, 0x0f 358dw 0000100100000000b 359dw 0010010000100000b 360dw 0001010110100000b 361dw 0001011010100000b 362dw 0001010101000000b 363dw 0101000000000000b 364 365 366
; Non movable - bridge spot

TERRAIN TILES DATA

8x8 tiles for terrain Data: number of lines, palettDefaulte id, lines (8 pixels) of palette color id
370 371TerrainTiles: 372db 0x8, 0x05 373dw 0101011010111111b 374dw 0001010110111111b 375dw 0000010110101111b 376dw 0000010110101111b 377dw 0000010110101111b 378dw 0000010110101111b 379dw 0001010110111111b 380dw 0101011010111111b 381 382db 0x8, 0x05 383dw 0100000000000001b 384dw 0101000000000101b 385dw 0101010101010101b 386dw 1001010101010110b 387dw 1010101010101010b 388dw 1111101010101111b 389dw 1111111111111111b 390dw 1111111111111111b 391 392db 0x8, 0x5 393dw 0000000001010101b 394dw 0000010101010101b 395dw 0001010101101001b 396dw 0001011010101010b 397dw 0101011010101010b 398dw 0101101010101111b 399dw 0101101010111111b 400dw 0101011010111111b 401 402db 0x8, 0x5 403dw 0101011010111111b 404dw 0101011011111111b 405dw 0101101011111111b 406dw 1010101111111111b 407dw 1011111111111111b 408dw 1111111111111111b 409dw 1111111111111111b 410dw 1111111111111111b 411 412db 0x8, 0x6 413dw 1010101010101010b 414dw 1010101010011010b 415dw 1010011010111010b 416dw 1010111010101010b 417dw 1010101010101010b 418dw 1010101001101010b 419dw 1010101011101010b 420dw 1010101010101010b 421 422db 0x8, 0x6 423dw 1010101010101010b 424dw 1010101010011010b 425dw 1010011010011010b 426dw 0110011010111010b 427dw 0110111001101010b 428dw 1101101001101010b 429dw 1011101011100110b 430dw 1010101010101110b 431 432db 0x8, 0x6 433dw 1010101010101010b 434dw 0110100110001010b 435dw 0110101110011010b 436dw 1110001010011010b 437dw 1010011000111000b 438dw 1010111001101001b 439dw 1001101011101001b 440dw 1011101010101011b 441 442db 0x8, 0x0 443dw 0001010000000000b 444dw 0000000000010100b 445dw 0000111111100000b 446dw 0011111110101000b 447dw 1111101010101011b 448dw 0111101010111101b 449dw 0001010101010100b 450dw 0000000000000000b 451
; 0x1 Shore left bank ; 0x2 Shore top bank ; 0x3 Shore corner outside ; 0x4 Shore corner filler inside ; 0x5 Ground light ; 0x6 Ground medium ; 0x7 Ground dense ; 0x8 Bridge Movable

META-TILES DECLARATION

4x4 meta-tiles for level Data: 4x4 tiles id free slot free slot free slot free slot
455 456MetaTiles: 457db 00000000b, 00000000b, 00000000b, 00000000b 458db 00000010b, 00000010b, 00000101b, 00000101b 459db 00000001b, 00000101b, 00000001b, 00000101b 460db 00000011b, 00000010b, 00000001b, 00110110b 461db 00000101b, 00000110b, 00010110b, 00000101b 462db 00000110b, 00000111b, 00000111b, 00000111b 463db 00000100b, 00110101b, 00100101b, 00000111b 464db 00000100b, 00100110b, 00010111b, 00110100b 465db 00001000b, 00001000b, 00001000b, 00001000b 466db 00000100b, 00010100b, 00000110b, 00000111b 467db 00000100b, 00000111b, 00100100b, 00010111b 472

LEVEL DATA

16x8 level data Data: 4x4 meta-tiles id Nibble is meta-tile id, 2 bits ar nibbles XY mirroring, 1 bit movable
477 478LevelData: 479db 01000011b, 01000001b, 01010011b, 00000000b 480db 00000000b, 01000011b, 01000001b, 01010011b 481db 00000000b, 00000000b, 00000000b, 00000000b 482db 01001000b, 01001000b, 01000011b, 01010011b 483db 01000010b, 01100101b, 01010010b, 01001000b 484db 01000011b, 01000110b, 01110110b, 01110011b 485db 01001000b, 01000011b, 01010011b, 00000000b 486db 00000000b, 01000011b, 01000111b, 01110011b 487db 01100011b, 01100001b, 01110011b, 00000000b 488db 01100011b, 01101001b, 01110011b, 00000000b 489db 00000000b, 01100011b, 01010111b, 01010011b 490db 00000000b, 01100011b, 01110011b, 01001000b 491db 00000000b, 00000000b, 00000000b, 00000000b 492db 01000011b, 01001001b, 01010011b, 01000011b 493db 01010011b, 00000000b, 01100011b, 01010111b 494db 01010011b, 00000000b, 01001000b, 00000000b 495db 01000011b, 01010011b, 01001000b, 00000000b 496db 01100011b, 01100110b, 01011010b, 01100001b 497db 01110011b, 00000000b, 00000000b, 01100011b 498db 01010111b, 01010011b, 01000011b, 01010011b 499db 01000010b, 01010110b, 01010011b, 00000000b 500db 00000000b, 01100011b, 01110011b, 00000000b 501db 00000000b, 01000011b, 01010011b, 01001000b 502db 01000010b, 01010110b, 01000110b, 01010010b 503db 01100011b, 01100001b, 01010111b, 01000001b 504db 01010011b, 00000000b, 00000000b, 01000011b 505db 01000001b, 01000110b, 01010010b, 00000000b 506db 01100011b, 01100001b, 01100110b, 01010010b 507db 01001000b, 01001000b, 01100011b, 01100001b 508db 01110011b, 01001000b, 01001000b, 01100011b 509db 01100001b, 01100001b, 01110011b, 00000000b 510db 00000000b, 01001000b, 01100011b, 01110011b 511 512EntityData: 513db 1, 1 514dw 0x0002 515db 2, 14 516dw 0x0103 517dw 0x020a 518dw 0x030a 519dw 0x040a 520dw 0x0509 521dw 0x050d 522dw 0x051a 523dw 0x051b 524dw 0x060a 525dw 0x060c 526dw 0x070d 527dw 0x080e 528dw 0x081a 529dw 0x0910 530db 13, 14 531dw 0x0916 532dw 0x091a 533dw 0x0a0d 534dw 0x0a14 535dw 0x0a15 536dw 0x0a1b 537dw 0x0b0c 538dw 0x0c01 539dw 0x0c0f 540dw 0x0d02 541dw 0x0d08 542dw 0x0d0e 543dw 0x0e06 544dw 0x0f07 545db 3, 2 546dw 0x081e 547dw 0x0c04 548db 11, 2 549dw 0x000c 550dw 0x0e07 551db 12, 1 552dw 0x0c11 553db 4, 8 554dw 0x021b 555dw 0x031a 556dw 0x031e 557dw 0x0404 558dw 0x060b 559dw 0x0616 560dw 0x090e 561dw 0x0c1e 562db 6, 16 563dw 0x0207 564dw 0x0210 565dw 0x0211 566dw 0x0307 567dw 0x0310 568dw 0x061c 569dw 0x061d 570dw 0x071c 571dw 0x071d 572dw 0x0b16 573dw 0x0b17 574dw 0x0e0a 575dw 0x0e0b 576dw 0x0e0d 577dw 0x0f0a 578dw 0x0f0d 579db 7, 1 580dw 0x0001 581db 8, 5 582dw 0x0104 583dw 0x010b 584dw 0x0710 585dw 0x0a01 586dw 0x0d12 587db 0x0 588 589tune_intro: 590db 5 ,7 ,8 ,7 ,5 ,8 ,10 ,8 ,7 ,5 ,7 ,8 ,7 ,5 ,3 ,5 591db 8 ,10 ,12 ,10 ,8 ,7 ,8 ,10 ,12 ,10 ,8 ,7 ,8 ,5 ,3 ,5 592db 10 ,12 ,14 ,12 ,10 ,8 ,10 ,12 ,14 ,12 ,10 ,8 ,7 ,5 ,7 ,8 593db 12 ,14 ,15 ,14 ,12 ,10 ,12 ,14 ,15 ,14 ,12 ,10 ,8 ,7 ,8 ,10 594db 5 ,7 ,8 ,7 ,5 ,8 ,10 ,8 ,7 ,5 ,7 ,8 ,7 ,5 ,3 ,5 595db 8 ,10 ,12 ,10 ,8 ,7 ,8 ,10 ,12 ,10 ,8 ,7 ,8 ,5 ,3 ,5 596db 10 ,12 ,14 ,12 ,10 ,8 ,10 ,12 ,14 ,12 ,10 ,8 ,7 ,5 ,7 ,8 597db 12 ,14 ,15 ,14 ,12 ,10 ,12 ,14 ,15 ,14 ,12 ,10 ,8 ,7 ,8 ,10 598db 0 599 600tune_end: 601db 12, 10, 8, 10, 7, 6 , 5, 6 602db 8 , 7 , 5, 4 , 3, 5 , 6, 4 603db 6 , 5 , 4, 3 , 2, 3 , 5, 2 604db 5 , 4 , 3, 2 , 1, 2 , 1, 1 605db 12, 10, 8, 10, 7, 6 , 5, 6 606db 8 , 7 , 5, 4 , 3, 5 , 6, 4 607db 0 608 609tune_win: 610db 13, 15, 17, 15, 13, 12, 10, 12 611db 13, 15, 17, 15, 13, 19, 17, 15 612db 12, 14, 16, 14, 12, 15, 13, 12 613db 10, 12, 14, 12, 10, 9 , 8 , 10 614db 13, 15, 17, 15, 13, 12, 10, 12 615db 13, 15, 17, 15, 13, 19, 17, 15 616db 12, 14, 16, 14, 12, 15, 13, 12 617db 10, 12, 14, 12, 10, 9 , 8 , 10 618db 0 619
; End of entities

MEMORY ADDRESSES

621 622 623_PLAYER_ENTITY_ID_ equ 0x1000 624_REQUEST_POSITION_ equ 0x1002 625_HOLDING_ID_ equ 0x1004 626_SCORE_ equ 0x1005 627_SCORE_TARGET_ equ 0x1006 628_GAME_TICK_ equ 0x1007 629_GAME_STATE_ equ 0x1009 630_WEB_LOCKED_ equ 0x100a 631_LAST_TICK_ equ 0x100b 632_CURRENT_TUNE_ equ 0x100d 633_NEXT_TUNE_ equ 0x100f 634_NOTE_TIMER_ equ 0x1011 635_NOTE_TEMPO_ equ 0x1012 636_ENTITIES_ equ 0x1200 637 638_DBUFFER_MEMORY_ equ 0x3000 639_VGA_MEMORY_ equ 0xA000 640_TICK_ equ 1Ah 641 642_ID_ equ 0 643_POS_ equ 1 644_POS_OLD_ equ 3 645_SCREEN_POS_ equ 5 646_MIRROR_ equ 7 647_STATE_ equ 8 648_DIR_ equ 9 649_ANIM_ equ 10 650
; 2 bytes ; 2 bytes ; 1 byte ; 1 byte ; 1 byte ; 2 bytes ; 1 byte ; 1 byte ; 2 bytes ; 2 bytes ; 2 bytes ; 1 byte ; 1 byte ; 11 bytes per entity, 64 entites cap, 320 bytes ; 64k bytes ; 64k bytes ; BIOS tick ; 1 byte ; 2 bytes ; 2 bytes ; 2 bytes ; 1 byte ; 1 bytes ; 1 byte ; 1 byte ; 11 bytes total

MAGIC NUMBERS

652 653ENTITY_SIZE equ 11 654MAX_ENTITIES equ 64 655ENTITIES_SPEED equ 2 656LEVEL_START_POSITION equ 320*68+32 657COLOR_SKY equ 0x3b3b 658COLOR_WATER equ 0x3535 659SCORE_POSITION equ 320*24+32 660INTRO_TIME equ 240 661PRE_GAME_TIME equ 64 662POST_GAME_TIME equ 32 663 664ID_PLAYER equ 0 665ID_PALM equ 1 666ID_SNAKE equ 2 667ID_ROCK equ 3 668ID_SKULL equ 4 669ID_BRIDGE equ 5 670ID_CHEST equ 6 671ID_GOLD equ 7 672ID_SPIDER equ 10 673ID_CRAB equ 11 674ID_BUSH equ 12 675 676STATE_DEACTIVATED equ 0 677STATE_FOLLOW equ 2 678STATE_STATIC equ 4 679STATE_EXPLORING equ 8 680STATE_INTERACTIVE equ 16 681 682GSTATE_INTRO equ 2 683GSTATE_PREGAME equ 4 684GSTATE_GAME equ 8 685GSTATE_POSTGAME equ 16 686GSTATE_END equ 32 687GSTATE_WIN equ 64 688GSTATE_OUTRO equ 128 689 690WEB_LOCK equ 2 691 692BEEP_BITE equ 3 693BEEP_PICK equ 15 694BEEP_PUT equ 20 695BEEP_GOLD equ 5 696BEEP_STEP equ 25 697BEEP_WEB equ 30 698

INITIALIZATION

700 701start: 702 mov ax,0x13 703 int 0x10 704 705 push _DBUFFER_MEMORY_ 706 pop es 707 708 set_keyboard_rate: 709 xor ax, ax 710 xor bx, bx 711 mov ah, 03h 712 mov bl, 1Fh 713 int 16h 714 715restart_game: 716 mov word [_GAME_TICK_], 0x0 717 mov byte [_GAME_STATE_], GSTATE_INTRO 718 mov byte [_SCORE_], 0x0 719 mov byte [_HOLDING_ID_], 0x0 720 mov byte [_WEB_LOCKED_], 0x0 721 mov word [_CURRENT_TUNE_], tune_intro 722 mov word [_NEXT_TUNE_], tune_intro 723 mov byte [_NOTE_TIMER_], 0x0 724 725
; Init VGA 320x200x256 ; Video BIOS interrupt ; Set doublebuffer memory ; as target ; BIOS function to set typematic rate and delay ; BL = 31 (0x1F) for maximum repeat rate (30 Hz) and 0 delay ; Call BIOS ; loop intro tune

SPAWN ENTITIES

Expects: entities array from level data Returns: entities in memory array
729 730spawn_entities: 731 mov si, EntityData 732 mov di, _ENTITIES_ 733 734 .next_entitie: 735 mov bl, [si] 736 cmp bl, 0x0 737 jz .done 738 739 dec bl 740 741 inc si 742 mov al, [si] 743 inc si 744 mov cl, al 745 746 cmp bl, ID_GOLD 747 jnz .not_gold 748 mov [_SCORE_TARGET_], cl 749 .not_gold: 750 751 .next_in_group: 752 mov byte [di], bl 753 mov ax, [si] 754 mov [di+_POS_], ax 755 mov [di+_POS_OLD_], ax 756 757 push cx 758 push di 759 mov cx, ax 760 call conv_pos2mem 761 mov ax, di 762 pop di 763 pop cx 764 mov [di+_SCREEN_POS_], ax 765 766 mov byte [di+_MIRROR_], 0x0 767 mov byte [di+_STATE_], STATE_STATIC 768 mov byte [di+_DIR_], 0x0 769 mov byte [di+_ANIM_], 0x0 770 771 cmp bl, ID_SNAKE 772 jz .set_explore 773 cmp bl, ID_CRAB 774 jz .set_explore 775 cmp bl, ID_SPIDER 776 jz .set_explore 777 jmp .skip_explore 778 .set_explore: 779 mov byte [di+_STATE_], STATE_EXPLORING 780 .skip_explore: 781 782 cmp bl, ID_PALM 783 jz .set_rand_mirror 784 cmp bl, ID_BUSH 785 jz .set_rand_mirror 786 jnz .skip_mirror 787 .set_rand_mirror: 788 xor al, ah 789 and al, 0x01 790 mov byte [di+_MIRROR_], al 791 .skip_mirror: 792 793 cmp bl, ID_BRIDGE 794 jz .set_interactive 795 cmp bl, ID_GOLD 796 jz .set_interactive 797 cmp bl, ID_ROCK 798 jz .set_interactive 799 cmp bl, ID_CHEST 800 jz .set_interactive 801 jmp .skip_interactive 802 .set_interactive: 803 mov byte [di+_STATE_], STATE_INTERACTIVE 804 .skip_interactive: 805 806 add si, 0x02 807 add di, ENTITY_SIZE 808 loop .next_in_group 809 jmp .next_entitie 810 .done: 811 812mov word [_PLAYER_ENTITY_ID_], _ENTITIES_ 813
; Get first word (ID) ; Check for last entity marker ; Conv level id to game id ; Get amount in group ; mov to the next word (first entitie in group) ; Set loop ; Check if gold coin ; Count each gold as score target ; Save sprite id ; Get position ; Save position ; Save old position ; Save mirror (none) ; Save basic state ; Save basic state ; Set explore state to alive entities ; Random X mirror, for foliage ; Set interactive entities ; Move to the next entity in code ; Move to the next entity in memory ; Set player entity id to first entity

GAME LOGIC

815 816game_loop: 817 xor di, di 818 xor si, si 819

DRAW BACKGROUND

jmp skip_more_ocean
821 822draw_bg: 823 mov ax, COLOR_SKY 824 mov dl, 0xa 825 .draw_sky: 826 mov cx, 320*3 827 rep stosw 828 inc ax 829 xchg al, ah 830 dec dl 831 jnz .draw_sky 832 833draw_ocean: 834 mov ax, COLOR_WATER 835 mov cx, 320*70 836 rep stosw 837 839draw_more_ocean: 840 xor dx,dx 841 mov si, Ocean1Brush 842 mov di, 320*62 843 mov ax, [_GAME_TICK_] 844 shr ax, 2 845 mov cx, 16 846 .draw_line: 847 push cx 848 849 mov cx, 40 850 .draw_next_tile: 851 852 test ax, 0x4 853 jz .skip_tile 854 855 mov si, Ocean1Brush 856 test cx, 0x2 857 jz .skip_brush_swap 858 mov si, Ocean2Brush 859 .skip_brush_swap: 860 861 call draw_sprite 862 863 .skip_tile: 864 add di, 8 865 add ax, 0x2 866 .skip_new_line: 867 868 loop .draw_next_tile 869 add di, 320*8 870 inc ax 871 pop cx 872 loop .draw_line 873skip_more_ocean: 874 875
; Set starting sky color ; 10 bars to draw ; 3 pixels high ; Write to the doublebuffer ; Increment color index for next bar ; Swap colors ; 70 lines of ocean

INTRO

ship moving
877 878test byte [_GAME_STATE_], GSTATE_INTRO 879jz skip_game_state_intro 880 881 mov byte [_NOTE_TEMPO_], 2 882 call play_tune 883 885 886 mov di, 320*120 887 mov ax, [_GAME_TICK_] 888 shr ax, 1 889 add di, ax 890 cmp ax, INTRO_TIME 891 jg .start_game 892 mov bx, 0x1 893 call draw_ship 894 895 mov ah, 01h 896 int 16h 897 jz .no_key_press 898 .start_game: 899 900 mov byte [_GAME_STATE_], GSTATE_PREGAME 901 add byte [_GAME_STATE_], GSTATE_GAME 902 mov word [_GAME_TICK_], 0x0 903 .no_key_press: 904 905skip_game_state_intro: 906 907
; BIOS keyboard status function ; Call BIOS interrupt

PRE-GAME

909 910test byte [_GAME_STATE_], GSTATE_PREGAME 911jz skip_game_state_pregame 912 913pre_game: 914 call play_tune 915 916 mov di, 320*52 917 mov ax, [_GAME_TICK_] 918 cmp ax, PRE_GAME_TIME 919 jg .start_game 920 shr ax, 1 921 add di, ax 922 mov bx, 0x1 923 call draw_ship 924 jmp skip_game_state_pregame 925 926 .start_game: 927 mov byte [_GAME_STATE_], GSTATE_GAME 928 mov word [_GAME_TICK_], 0x0 929 930 .clear_kb_buffer: 931 mov ah, 0x01 932 int 0x16 933 jz .cleared 934 mov ah, 0x00 935 int 0x16 936 jmp .clear_kb_buffer 937 938 .cleared: 939 940skip_game_state_pregame: 941

GAME

943 944test byte [_GAME_STATE_], GSTATE_GAME 945jz skip_game_state_game 946

STOP SOUND

948stop_game_sound: 949 test byte [_GAME_STATE_], GSTATE_PREGAME 950 jnz .skip_stop_sound 951 test byte [_GAME_STATE_], GSTATE_POSTGAME 952 jnz .skip_stop_sound 953 call stop_beep 954 .skip_stop_sound: 955

DRAWING LEVEL

957 958 959draw_level: 960 mov si, LevelData 961 mov di, LEVEL_START_POSITION 962 xor cx, cx 963 .next_meta_tile: 964 push cx 965 push si 966 967 mov byte al, [si] 968 mov bl, al 969 shr bl, 0x4 970 and bl, 0x3 971 972 and ax, 0xf 973 jnz .not_empty 974 add di, 16 975 jmp .skip_meta_tile 976 .not_empty: 977 978 mov si, MetaTiles 979 shl ax, 0x2 980 add si, ax 981 982 mov dx, 0x0123 983 .check_y: 984 test bl, 2 985 jz .check_x 986 xchg dh, dl 987 .check_x: 988 test bl, 1 989 jz .push_tiles 990 ror dh, 4 991 ror dl, 4 992 993 .push_tiles: 994 mov cx, 4 995 .next_tile_push: 996 push dx 997 ror dx, 4 998 loop .next_tile_push 999 1000 mov cx, 0x4 1001 .next_tile: 1002 pop dx 1003 and dx, 0x7 1004 push si 1005 add si, dx 1006 mov byte al, [si] 1007 pop si 1008 mov bh, al 1009 shr bh, 4 1010 and bh, 3 1011 1012 xor bh, bl 1013 mov dl, bh 1014 1015 and ax, 0xf 1016 dec ax 1017 imul ax, 18 1018 1019 push si 1020 mov si, TerrainTiles 1021 add si, ax 1022 call draw_sprite 1023 pop si 1024 1025 add di, 8 1026 1027 cmp cx, 0x3 1028 jnz .skip_set_new_line 1029 add di, 320*8-16 1030 .skip_set_new_line: 1031 1032 loop .next_tile 1033 sub di, 320*8 1034 .skip_meta_tile: 1035 1036 pop si 1037 inc si 1038 pop cx 1039 inc cx 1040 test cx, 0xf 1041 jnz .no_new_line 1042 add di, 320*16-(16*16) 1043 .no_new_line: 1044 1045 cmp cx, 0x80 1046 jl .next_meta_tile 1047 1048 1049test byte [_GAME_STATE_], GSTATE_PREGAME 1050jnz skip_keyboard 1051test byte [_GAME_STATE_], GSTATE_POSTGAME 1052jnz skip_keyboard 1053
; Read level cell ; Make a copy ; Remove first nible ; Read XY mirroring - BL ; Read first nibble - AX ; ID*4 Move to position; 4 bytes per tile ; Meta-tile address ; Default order: 0, 1, 2, 3 ; Swap top and bottom rows (Order: 2, 3, 0, 1) ; Swap nibbles in dh (tiles in positions 0 and 1) ; Swap nibbles in dl (tiles in positions 2 and 3) ; 4 tiles to push ; Push the tile ID ; Rotate dx to get the next tile ID in place ; 2x2 tiles ; Get tile order ; Read meta-tile with order ; Extract the upper 4 bits ; Mask to get the mirror flags (both X and Y) ; invert original tile mirror by meta-tile mirror ; set final mirror for tile ; First nibble ; We do not have tile 0, shifting values ; Move to position ; Word wrap ; Move to the next display line ; 128 = 16*8

DRAW SHIP

1055 1056draw_ship_in_game: 1057 mov di, 320*52+32 1058 xor bx, bx 1059 call draw_ship 1060

KEYBOARD INPUT

cmp cl, 0x0 jz .invalid_move jmp .check_move
1062 1063check_keyboard: 1064 mov ah, 01h 1065 int 16h 1066 jz .no_key_press 1067 1068 mov ah, 00h 1069 int 16h 1070 1071 mov si, [_PLAYER_ENTITY_ID_] 1072 mov cx, [si+_POS_] 1073 mov bx, [si+_POS_OLD_] 1074 cmp cx, bx 1075 jnz .no_key_press 1076 1077 1078 .check_spacebar: 1079 cmp ah, 39h 1080 jne .check_up 1081 cmp byte [_HOLDING_ID_], 0x0 1082 jz .set_request_position_to_player 1083 mov byte [_HOLDING_ID_], 0x0 1084 jmp .no_key_press 1085 .set_request_position_to_player: 1086 mov word [_REQUEST_POSITION_], cx 1087 jmp .no_key_press 1088 .check_up: 1089 cmp ah, 48h 1090 jne .check_down 1091 cmp ch, 0x0 1092 jz .invalid_move 1093 dec ch 1094 jmp .check_move 1095 1096 .check_down: 1097 cmp ah, 50h 1098 jne .check_left 1099 inc ch 1100 jmp .check_move 1101 1102 .check_left: 1103 cmp ah, 4Bh 1104 jne .check_right 1107 dec cl 1108 mov byte [si+_MIRROR_], 0x1 1109 jmp .check_move 1110 1111 1112 .check_right: 1113 cmp ah, 4Dh 1114 jne .no_key_press 1115 inc cl 1116 mov byte [si+_MIRROR_], 0x0 1118 1119 .check_move: 1120 call check_friends 1121 jz .no_move 1122 call check_water_tile 1123 jz .no_move 1124 call check_bounds 1125 jz .no_move 1126 1127 .move: 1128 cmp byte [_WEB_LOCKED_], 0 1129 jz .skip_web_check 1130 dec byte [_WEB_LOCKED_] 1131 mov bl, BEEP_WEB 1132 call beep 1133 jmp .no_move 1134 .skip_web_check: 1135 mov word [si+_POS_], cx 1136 mov bl, BEEP_STEP 1137 call beep 1138 1139 .no_move: 1140 mov word [_REQUEST_POSITION_], cx 1141 1142 .no_key_press: 1143 .invalid_move: 1144 1145skip_keyboard: 1146
; BIOS keyboard status function ; Call BIOS interrupt ; Jump if Zero Flag is set (no key pressed) ; BIOS keyboard read function ; Call BIOS interrupt ; Load player position into CX (Y in CH, X in CL) ; Compare scan code with spacebar ; Compare scan code with up arrow ; Compare scan code with down arrow ; Compare scan code with left arrow ; Compare scan code with right arrow

AI ENITIES

1148 1149ai_entities: 1150 mov si, _ENTITIES_ 1151 mov cl, MAX_ENTITIES 1152 .next_entity: 1153 push cx 1154 1155 cmp byte [si+_STATE_], STATE_EXPLORING 1156 jnz .skip_explore 1157 1158 mov ax, [si+_POS_] 1159 mov bx, [si+_POS_OLD_] 1160 cmp ax, bx 1161 jnz .skip_explore 1162 1163 .explore: 1164 mov cx, [si+_POS_] 1165 mov al, [si+_DIR_] 1166 1167 .check_horizontal: 1168 cmp al, 0 1169 jnz .go_left 1170 .go_right: 1171 inc cl 1172 jmp .check_mirror 1173 .go_left: 1174 cmp al, 1 1175 jnz .check_vertical 1176 dec cl 1177 jmp .check_mirror 1178 1179 .check_vertical: 1180 cmp al, 2 1181 jnz .go_up 1182 .go_down: 1183 inc ch 1184 jmp .check_mirror 1185 .go_up: 1186 cmp al, 3 1187 jnz .check_mirror 1188 dec ch 1189 1190 .check_mirror: 1191 mov byte [si+_MIRROR_], 0x0 1192 cmp byte cl, [si+_POS_] 1193 jg .skip_mirror_x 1194 mov byte [si+_MIRROR_], 0x1 1195 .skip_mirror_x: 1196 1197 call check_bounds 1198 jz .can_not_move 1199 1200 call check_friends 1201 jz .can_not_move 1202 1203 call check_water_tile 1204 jz .can_not_move 1205 1206 .move_to_new_pos: 1207 mov word [si+_POS_], cx 1208 jmp .after_move 1209 1210 .can_not_move: 1211 1212 .check_if_crab: 1213 cmp byte [si+_ID_], ID_CRAB 1214 jnz .not_a_crab 1215 xor byte [si+_DIR_], 1 1216 jmp .skip_random_bounce 1217 .not_a_crab: 1218 1219 .random_bounce: 1220 in al, 0x40 1221 add ax, [_GAME_TICK_] 1222 and al, 0x3 1223 mov byte [si+_DIR_], al 1224 1225 .skip_random_bounce: 1226 1227 .check_if_player: 1228 cmp cx, [_REQUEST_POSITION_] 1229 jnz .no_bite 1230 cmp byte [_HOLDING_ID_], 0x0 1231 jnz .continue_game 1232 mov byte [_HOLDING_ID_], 0xff 1233 mov bl, BEEP_BITE 1234 call beep 1235 1236 cmp byte [si+_ID_], ID_SNAKE 1237 jz .snake_bite 1238 cmp byte [si+_ID_], ID_SPIDER 1239 jz .spider_web 1240 cmp byte [si+_ID_], ID_CRAB 1241 jz .crab_bite 1242 jmp .continue_game 1243 1244 .crab_bite: 1245 .snake_bite: 1246 mov byte [_GAME_STATE_], GSTATE_END 1247 mov word [_CURRENT_TUNE_], tune_end 1248 mov word [_NEXT_TUNE_], tune_end 1249 mov byte [_NOTE_TIMER_], 0x0 1250 mov byte [_NOTE_TEMPO_], 0xa 1251 jmp .skip_item 1252 1253 .spider_web: 1254 mov byte [_WEB_LOCKED_] , WEB_LOCK 1255 jmp .continue_game 1256 1257 .continue_game: 1258 mov byte [_HOLDING_ID_], 0x00 1259 jmp .skip_item 1260 .no_bite: 1261 .after_move: 1262 .skip_explore: 1263 1264 cmp byte [si+_STATE_], STATE_INTERACTIVE 1265 jnz .skip_item 1266 mov cx, [si+_POS_] 1267 cmp cx, [_REQUEST_POSITION_] 1268 jnz .skip_item 1269 1270 cmp byte [si+_ID_], ID_BRIDGE 1271 jz .check_bridge 1272 cmp byte [si+_ID_], ID_CHEST 1273 jnz .skip_check_interactions 1274 1275 .check_interactions: 1276 cmp byte [_HOLDING_ID_], ID_GOLD 1277 jnz .skip_item 1278 inc byte [_SCORE_] 1279 mov bl, BEEP_GOLD 1280 call beep 1281 jmp .clear_item 1282 1283 .check_bridge: 1284 cmp byte [_HOLDING_ID_], ID_ROCK 1285 jnz .skip_item 1286 mov byte [si+_STATE_], STATE_DEACTIVATED 1287 .clear_item: 1288 mov byte [_HOLDING_ID_], 0xff 1289 jmp .skip_item 1290 .skip_check_interactions: 1291 1292 cmp byte [_HOLDING_ID_], 0x0 1293 jnz .skip_item 1294 .pick_item: 1295 mov byte [si+_STATE_], STATE_FOLLOW 1296 mov word [_REQUEST_POSITION_], 0x0 1297 mov byte cl, [si+_ID_] 1298 mov byte [_HOLDING_ID_], cl 1299 mov bl, BEEP_PICK 1300 call beep 1301 .skip_item: 1302 1303 .put_item_back: 1304 cmp byte [si+_STATE_], STATE_FOLLOW 1305 jnz .no_follow 1306 1307 cmp byte [_HOLDING_ID_], 0x0 1308 jnz .check_kill 1309 mov byte [si+_STATE_], STATE_INTERACTIVE 1310 mov word [_REQUEST_POSITION_], 0x0 1311 jmp .beep 1312 1313 .check_kill: 1314 cmp byte [_HOLDING_ID_], 0xff 1315 jnz .skip_kill 1316 mov byte [si+_STATE_], STATE_DEACTIVATED 1317 mov byte [_HOLDING_ID_], 0x0 1318 .beep: 1319 mov bl, BEEP_PUT 1320 call beep 1321 .skip_kill: 1322 .no_follow: 1323 1324 add si, ENTITY_SIZE 1325 pop cx 1326 dec cx 1327 jnz .next_entity 1328 1329 1330
; Crab ; Snake ; Spider ; Check if player is holding something

SORT ENITIES

Sort entities by Y position Expects: entities array Returns: sorted entities array
1335 1336sort_entities: 1337 mov cl, MAX_ENTITIES-1 1338 .outer_loop: 1339 push cx 1340 mov si, _ENTITIES_ 1341 1342 .inner_loop: 1343 push cx 1344 mov bx, [si+_POS_] 1345 mov dx, [si+ENTITY_SIZE+_POS_] 1346 1347 cmp bh, dh 1348 jle .no_swap 1349 1350 mov di, si 1351 add di, ENTITY_SIZE 1352 1353 mov ax, [_PLAYER_ENTITY_ID_] 1354 cmp ax, si 1355 jne .check_next_entity 1356 mov [_PLAYER_ENTITY_ID_], di 1357 jmp .swap_entities 1358 .check_next_entity: 1359 cmp ax, di 1360 jne .swap_entities 1361 mov [_PLAYER_ENTITY_ID_], si 1362 .swap_entities: 1363 1364 mov cx, ENTITY_SIZE 1365 .swap_loop: 1366 mov al, [si] 1367 xchg al, [di] 1368 mov [si], al 1369 inc si 1370 inc di 1371 loop .swap_loop 1372 sub si, ENTITY_SIZE 1373 1374 .no_swap: 1375 add si, ENTITY_SIZE 1376 pop cx 1377 loop .inner_loop 1378 1379 pop cx 1380 loop .outer_loop 1381
; We'll do n-1 passes ; Get Y of current entity ; Get Y of next entity ; Compare Y values

DRAW ENITIES

smooth move here
1383 1384draw_entities: 1385 mov si, _ENTITIES_ 1386 mov cl, MAX_ENTITIES 1387 .next: 1388 push cx 1389 push si 1390 1391 cmp byte [si+_STATE_], STATE_DEACTIVATED 1392 jz .skip_entity 1393 1394 test byte [_GAME_STATE_], GSTATE_PREGAME 1395 jnz .hide_player 1396 test byte [_GAME_STATE_], GSTATE_POSTGAME 1397 jnz .hide_player 1398 jmp .skip_hide_player 1399 .hide_player: 1400 cmp byte [si+_ID_], ID_PLAYER 1401 jz .skip_entity 1402 cmp byte [si+_ID_], ID_CHEST 1403 jz .skip_entity 1404 .skip_hide_player: 1405 1407 mov ax, [si+_POS_OLD_] 1408 mov cx, [si+_POS_] 1409 cmp cx, ax 1410 jz .in_position 1411 1412 xor bx, bx 1413 1414 cmp al, cl 1415 jl .move_left 1416 jg .move_right 1417 cmp ah, ch 1418 jl .move_down 1419 jg .move_up 1420 1421 jmp .in_position 1422 1423 .move_left: 1424 add bx, ENTITIES_SPEED 1425 jmp .save_move 1426 1427 .move_right: 1428 sub bx, ENTITIES_SPEED 1429 jmp .save_move 1430 1431 .move_down: 1432 add bx, 320*ENTITIES_SPEED 1433 jmp .save_move 1434 1435 .move_up: 1436 sub bx, 320*ENTITIES_SPEED 1437 jmp .save_move 1438 1439 .save_move: 1440 mov cx, [si+_POS_] 1441 call conv_pos2mem 1442 mov dx, di 1443 add [si+_SCREEN_POS_], bx 1444 mov di, [si+_SCREEN_POS_] 1445 cmp dx, di 1446 jnz .pos_calculated 1447 mov cx, [si+_POS_] 1448 mov [si+_POS_OLD_], cx 1449 mov byte [si+_ANIM_], 0x0 1450 cmp byte [si+_ID_], ID_PLAYER 1451 jnz .skip_step_beep 1452 mov bl, BEEP_STEP 1453 call beep 1454 .skip_step_beep: 1455 1456 1457 .in_position: 1458 call conv_pos2mem 1459 .pos_calculated: 1460 cmp byte [si+_STATE_], STATE_FOLLOW 1461 jnz .skip_follow 1462 push si 1463 mov si, [_PLAYER_ENTITY_ID_] 1464 mov cx, [si+_POS_] 1465 mov di, [si+_SCREEN_POS_] 1466 sub di, 320*14 1467 pop si 1468 mov word [si+_POS_], cx 1469 jmp .skip_draw_shadow 1470 .skip_follow: 1471 1472 1473 .draw_shadow: 1474 test byte [si+_STATE_], STATE_EXPLORING 1475 jnz .skip_draw_shadow 1476 cmp byte [si+_ID_], ID_PLAYER 1477 jz .skip_draw_shadow 1478 cmp byte [si+_ID_], ID_BRIDGE 1479 jz .skip_draw_shadow 1480 push si 1481 push di 1482 mov si, ShadowBrush 1483 add di, 320*5+1 1484 call draw_sprite 1485 pop di 1486 pop si 1487 .skip_draw_shadow: 1488 1489 mov byte al, [si] 1490 mov ah, al 1491 1492 shl al, 0x2 1493 mov bx, BrushRefs 1494 add bl, al 1495 mov dx, [bx] 1496 1497 push dx 1498 1499 add al, 0x2 1500 movzx bx, al 1501 add di, [BrushRefs + bx] 1502 mov dl, [si+_MIRROR_] 1503 1504 cmp ah, ID_PLAYER 1505 jnz .skip_player_anim 1506 mov ax, [si+_POS_] 1507 cmp ax, [si+_POS_OLD_] 1508 mov ah, ID_PLAYER 1509 jz .skip_player_anim 1510 xor byte [si+_ANIM_], 0x1 1511 .skip_player_anim: 1512 1513 mov dh, [si+_ANIM_] 1514 1515 pop si 1516 call draw_sprite 1517 1518 cmp ah, ID_PLAYER 1519 jnz .skip_player_draw 1520 mov si, IndieTopBrush 1521 sub di, 320*4 1522 1523 cmp dh, 0x1 1524 jnz .skip_anim_move 1525 add di, 320 1526 .skip_anim_move: 1527 1528 cmp byte [_HOLDING_ID_], 0x0 1529 jz .skip_player_holding 1530 mov si, IndieTop2Brush 1531 .skip_player_holding: 1532 1533 xor dh, dh 1534 call draw_sprite 1535 1536 cmp byte [_WEB_LOCKED_], 0 1537 jz .skip_web_draw 1538 mov si, WebBrush 1539 add di, 320*6 1540 call draw_sprite 1541 .skip_web_draw: 1542 .skip_player_draw: 1543 1544 cmp ah, ID_GOLD 1545 jnz .skip_gold_draw 1546 mov ax, [_GAME_TICK_] 1547 add ax, cx 1548 and ax, 0x4 1549 cmp ax, 0x2 1550 jl .skip_gold_draw 1551 xor dx, dx 1552 mov si, GoldBrush 1553 call draw_sprite 1554 .skip_gold_draw: 1555 1556 cmp ah, ID_CRAB 1557 jnz .skip_crab 1558 mov dx, 0 1559 mov si, CrabClawBrush 1560 add di, 8 1561 call draw_sprite 1562 mov dx, 1 1563 sub di, 320+16 1564 call draw_sprite 1565 .skip_crab: 1566 1567 cmp ah, ID_CHEST 1568 jnz .skip_chest 1569 xor dx,dx 1570 cmp byte [_HOLDING_ID_], ID_GOLD 1571 jnz .skip_open_chest 1572 mov si, ChestTopBrush 1573 sub di, 320*3+8 1574 call draw_sprite 1575 1576 mov si, ArrowBrush 1577 sub di, 320*8-8 1578 mov ax, [_GAME_TICK_] 1579 and ax, 0x1 1580 imul ax, 320*2 1581 add di, ax 1582 call draw_sprite 1583 jmp .skip_chest 1584 .skip_open_chest: 1585 mov si, ChestCloseBrush 1586 sub di, 320 1587 call draw_sprite 1588 .skip_chest: 1589 1590 .skip_entity: 1591 pop si 1592 add si, ENTITY_SIZE 1593 pop cx 1594 dec cx 1595 jg .next 1596 1597skip_draw_entities: 1598
; screen pos in DI ; Load player position into CX (Y in CH, X in CL) ; Move above player ; Save new position to holding item ; Get brush id in AL ; Save a copy in AH ; Get brush reference table ; Shift to ref (id*2 bytes) ; Get brush data address ; Save address for SI ; offest is at next byte (+2) ; Get address to BX ; Get shift and apply to destination position ; Get brush mirror flag ; Get anination frame ; Get address ; move head down on second frame ; no mirror

CHECK SCORE

1600 1601test byte [_GAME_STATE_], GSTATE_PREGAME 1602jnz skip_score 1603test byte [_GAME_STATE_], GSTATE_POSTGAME 1604jnz skip_score 1605 1606check_score: 1607 mov di, SCORE_POSITION 1608 mov al, [_SCORE_TARGET_] 1609 mov ah, [_SCORE_] 1610 cmp al, ah 1611 jg .continue_game 1612 add byte [_GAME_STATE_], GSTATE_POSTGAME 1613 mov word [_GAME_TICK_], 0x0 1614 mov word [_CURRENT_TUNE_], tune_win 1615 mov word [_NEXT_TUNE_], tune_win 1616 mov byte [_NOTE_TIMER_], 0x0 1617 mov byte [_NOTE_TEMPO_], 0x2 1618 .continue_game: 1619

DRAW SCORE

1621 1622draw_score: 1623 xor cl, cl 1624 .draw_spot: 1625 mov si, SlotBrush 1626 call draw_sprite 1627 cmp cl, ah 1628 jge .skip_gold_draw 1629 mov si, GoldBrush 1630 call draw_sprite 1631 .skip_gold_draw: 1632 add di, 0xa 1633 inc cl 1634 cmp al, cl 1635 jnz .draw_spot 1636 1637skip_score: 1638skip_game_state_game: 1639 1640

POST GAME

1642 1643test byte [_GAME_STATE_], GSTATE_POSTGAME 1644jz skip_game_state_postgame 1645draw_post_game: 1646 mov ax, [_GAME_TICK_] 1647 shr ax, 1 1648 cmp ax, POST_GAME_TIME 1649 jnz .move_ship 1650 mov byte [_GAME_STATE_], GSTATE_END+GSTATE_WIN 1651 .move_ship: 1652 mov di, 320*52+32 1653 add di, ax 1654 mov bx, 0x1 1655 call draw_ship 1656 call play_tune 1657 1658 1659skip_game_state_postgame: 1660

GAME END

1662 1663test byte [_GAME_STATE_], GSTATE_END 1664jz skip_game_state_end 1665 call play_tune 1666 mov di, 320*100+154 1667 mov si, SkullBrush 1668 test byte [_GAME_STATE_], GSTATE_WIN 1669 jz .draw_icon 1670 mov si, GoldBrush 1671 .draw_icon: 1672 call draw_sprite 1673skip_game_state_end: 1674 1675

VGA BLIT PROCEDURE

1677 1678vga_blit: 1679 push es 1680 push ds 1681 1682 push _VGA_MEMORY_ 1683 pop es 1684 push _DBUFFER_MEMORY_ 1685 pop ds 1686 mov cx,0x7D00 1687 xor si,si 1688 xor di,di 1689 rep movsw 1690 1691 pop ds 1692 pop es 1693 1694
; Set VGA memory ; as target ; Set doublebuffer memory ; as source ; Half of 320x200 pixels ; Clear SI ; Clear DI ; Push words (2x pixels)

GAME TICK

1696 1697wait_for_tick: 1698 xor ax, ax 1699 int _TICK_ 1700 mov bx, dx 1701.wait_loop: 1702 int _TICK_ 1703 cmp dx, bx 1704 je .wait_loop 1705 1706inc word [_GAME_TICK_] 1707
; Function 00h: Read system timer counter ; Returns tick count in CX:DX ; Store the current tick count ; Read the tick count again ; Loop until the tick count changes ; Increment game tick

ESC OR LOOP

1709 1710 in al, 0x60 1711 dec al 1712 jnz game_loop 1713
; Read keyboard ; Decrement AL (esc is 1, after decrement is 0) ; If not zero, loop again

TERMINATE PROGRAM

1715 1716 exit: 1717

BEEP STOP

1719 1720 call stop_beep 1721 mov ax, 0x4c00 1722 int 0x21 1723 ret 1724 1725
; Return to BIOS/DOS

BEEP PC SPEAKER

Set the speaker frequency Expects: BX - frequency value Return: - xor bh, bh
1730 1731beep: 1733 mov al, 0xB6 1734 out 0x43, al 1735 mov ah, bl 1736 out 0x42, al 1737 mov al, ah 1738 out 0x42, al 1739 in al, 0x61 1740 or al, 0x03 1741 out 0x61, al 1742ret 1743 1744stop_beep: 1745 in al, 0x61 1746 and al, 0x0FC 1747 out 0x61, al 1748ret 1749
; Command to set the speaker frequency ; Write the command to the PIT chip ; Frequency value ; Write the low byte of the frequency value ; Write the high byte of the frequency value ; Read the PIC chip ; Set bit 0 to enable the speaker ; Write the updated value back to the PIC chip ; Read the PIC chip ; Clear bit 0 to disable the speaker ; Write the updated value back to the PIC chip

CNVERT XY TO MEM

Expects: CX - position YY/XX Return: DI memory position
1753 1754conv_pos2mem: 1755 mov di, LEVEL_START_POSITION 1756 xor ax, ax 1757 mov al, ch 1758 imul ax, 320*8 1759 xor dh, dh 1760 mov dl, cl 1761 shl dx, 3 1762 add ax, dx 1763 add di, ax 1764ret 1765
; Clear AX ; Move Y coordinate to AL ; Clear DH ; Move X coordinate to DL ; DX = X * 8 ; AX = Y * 2560 + X * 8 ; Move result to DI

CHECK BOUNDS

Expects: CX - Position YY/XX (CH: Y coordinate, CL: X coordinate) Returns: AX - Zero if hit bound, 1 if no bounds at this location
1769 1770check_bounds: 1771 xor ax, ax 1772 cmp ch, 0x0f 1773 ja .return 1774 cmp cl, 0x1f 1775 ja .return 1776 inc ax 1777.return: 1778 test ax, 1 1779 ret 1780
; Assume bound hit (AX = 0) ; No bound hit (AX = 1) ; Set flags based on AX

CHECK FRIEDS

Expects: CX - Position YY/XX DL - skip check Return: AX - Zero if hit entity, 1 if clear
1785 1786check_friends: 1787 push si 1788 push cx 1789 xor bx, bx 1790 mov ax, cx 1791 1792 mov cx, MAX_ENTITIES 1793 mov si, _ENTITIES_ 1794 .next_entity: 1795 cmp byte [si+_STATE_], STATE_FOLLOW 1796 jle .skip_this_entity 1797 cmp word [si+_POS_], ax 1798 jz .hit 1799 .skip_this_entity: 1800 add si, ENTITY_SIZE 1801 loop .next_entity 1802 1803 jmp .done 1804 1805 .hit: 1806 mov bx, 0x1 1807 cmp bx, 0x1 1808 1809 .done: 1810 pop cx 1811 pop si 1812 1813ret 1814

CHECK WATER TILE

Expects: CX - Player position (CH: Y 0-15, CL: X 0-31) Returns: AL - 0 if water (0xF), 1 otherwise skip in: bx - wiosla
1818 1819check_water_tile: 1820 mov ax, cx 1821 shr ah, 1 1822 shr al, 1 1823 movzx bx, ah 1824 shl bx, 4 1825 add bl, al 1826 add bx, LevelData 1827 mov al, [bx] 1828 test al, 0x40 1829ret 1830 1831play_tune: 1832 cmp byte [_NOTE_TIMER_], 0x0 1833 jz .new_note 1834 dec byte [_NOTE_TIMER_] 1835 jmp .done 1836 .new_note: 1837 inc word [_CURRENT_TUNE_] 1838 mov si, [_CURRENT_TUNE_] 1839 mov bl, [si] 1840 cmp bl, 0 1841 jnz .skip_loop 1842 mov ax, [_NEXT_TUNE_] 1843 mov word [_CURRENT_TUNE_], ax 1844 mov si, ax 1845 mov bl, [si] 1846 .skip_loop: 1847 mov byte al, [_NOTE_TEMPO_] 1848 mov byte [_NOTE_TIMER_], al 1849 call beep 1850 .done: 1851ret 1852 1853 1856 1857draw_ship: 1858 xor dx, dx 1859 1860 mov ax, [_GAME_TICK_] 1861 and ax, 0xf 1862 cmp ax, 0x6 1863 jl .skip_wave 1864 sub di, 320 1865 .skip_wave: 1866 mov si, ShipBackBrush 1867 call draw_sprite 1868 add di, 8 + 320*4 1869 mov si, ShipMiddleBrush 1870 call draw_sprite 1871 add di, 8 1872 mov si, ShipMiddleBrush 1873 call draw_sprite 1874 add di, 8 1875 mov si, ShipFrontBrush 1876 call draw_sprite 1877 1878 mov si, ShipSailBrush 1879 sub di, 12 + 320*5 1880 call draw_sprite 1881 add di, 320*2 - 4 1882 call draw_sprite 1883 sub di, 320*7 - 3 1884 call draw_sprite 1885 add di, 320*2 - 4 1886 call draw_sprite 1887 sub di, 320*6 - 1 1888 call draw_sprite 1889 1890 add di, 320*10 + 10 1891 call draw_sprite 1892 sub di, 320*4 + 2 1893 call draw_sprite 1894 1895 cmp bx, 0x1 1896 jnz .skip_wiosla 1897 xor dx, dx 1898 mov ax, [_GAME_TICK_] 1899 shr ax, 3 1900 and ax, 0x1 1901 add dl, al 1902 sub di, ax 1903 sub di, ax 1904 sub di, ax 1905 mov si, WioslaBrush 1906 add di, 320*15-7 1907 call draw_sprite 1908 add di, 8 1909 call draw_sprite 1910 .skip_wiosla: 1911ret 1912
; Copy position to AX ; Y / 2 ; X / 2 to convert to tile position ; Multily by 16 tiles wide ; Y / 2 * 16 + X / 2 ; Read tile ; Check if movable (7th bit set) ; Loop to begining of the tune

DRAW SPRITE PROCEDURE

Expects: DI - positon (linear) DL - settings: 0 normal, 1 mirrored x, 2 mirrored y, 3 mirrored x&y DH - frame number Return: -
1919 1920draw_sprite: 1921 pusha 1922 xor cx, cx 1923 mov byte cl, [si] 1924 1925 inc si 1926 1927 xor ax, ax 1928 mov byte al, [si] 1929 inc si 1930 1931 shl ax, 0x2 1932 mov bp, ax 1933 add bp, PaletteSets 1934 1935 movzx ax, dh 1936 imul ax, cx 1937 shl ax, 0x1 1938 add si, ax 1939 1940 test dl, 0x1 1941 jz .no_x_mirror 1942 add di, 0x7 1943 .no_x_mirror: 1944 1945 test dl, 0x2 1946 jz .no_y_mirror 1947 add si, cx 1948 add si, cx 1949 sub si, 0x2 1950 .no_y_mirror: 1951 1952 .plot_line: 1953 push cx 1954 mov ax, [si] 1955 xor bx, bx 1956 mov cl, 0x08 1957 push si 1958 .draw_pixel: 1959 push cx 1960 1961 rol ax, 2 1962 mov bx, ax 1963 and bx, 0x3 1964 1965 mov si, bp 1966 add si, bx 1967 mov byte bl, [si] 1968 1969 cmp bl, 0x0 1970 jz .skip_pixel 1971 mov byte [es:di], bl 1972 .skip_pixel: 1973 1974 inc di 1975 1976 mov bl, dl 1977 and bl, 0x1 1978 jz .no_x_mirror2 1979 dec di 1980 dec di 1981 .no_x_mirror2: 1982 1983 pop cx 1984 loop .draw_pixel 1985 1986 pop si 1987 add si, 0x2 1988 1989 mov bl, dl 1990 and bl, 0x2 1991 jz .no_y_mirror2 1992 sub si, 0x4 1993 .no_y_mirror2: 1994 1995 add di, 312 1996 1997 mov bl, dl 1998 and bl, 0x1 1999 jz .no_x_mirror3 2000 add di, 0x10 2001 .no_x_mirror3: 2002 2003 pop cx 2004 loop .plot_line 2005 popa 2006ret 2007
; lines ; Palette ; each set is 4x 1 byte ; Get frame ; muliply by lines ; *2 bytes per line ; Mobe to the frame memory position ; Check x mirror ; Move point to the last right pixel ; Check ; Move to the last position ; Back one word ; Save lines couter ; Get sprite line ; 8 pixels in line ; Palette Set ; Palette color ; Get color from the palette ; transparency ; Write pixel color ; Or skip this pixel - alpha color ; Move destination to next pixel (+1) ; Jump if not ; Remove previous shift (now it's 0) ; Move destination 1px left (-1) ; Move to the next sprite line data ; Move to next line in destination ; If mirrored adjust next line position ; Restore line counter

SAFETY CHECK

times 0x7FD - ($ - $$) db 0x0 ; Pad to 2048 bytes
2009 2011

THE END

Thanks for reading the source code! Visit http://smol.p1x.in for more.
2015 2016Logo: 2017db "P1X"
; Use HEX viewer to see P1X at the end of binary