GAME10 - Mysteries of the Forgotten Isles

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

Logic 2D game in VGA graphics, with PC Speaker sounds.
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, 0x06, 0x27, 0x43 12db 0x00, 0x7f, 0x13, 0x15 13db 0x35, 0x34, 0x00, 0x00 14db 0x00, 0xd1, 0x73, 0x06 15db 0x00, 0x4a, 0x45, 0x47 16db 0x4a, 0x2f, 0x47, 0x45 17db 0x00, 0x74, 0x02, 0x2e 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 27
; 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

BRUSH REFERENCES

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

BRUSHES DATA

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

TERRAIN TILES DATA

8x8 tiles for terrain Data: number of lines, palettDefaulte id, lines (8 pixels) of palette color id
341 342TerrainTiles: 343db 0x8, 0x05 344dw 0101011010111111b 345dw 0001010110111111b 346dw 0000010110101111b 347dw 0000010110101111b 348dw 0000010110101111b 349dw 0000010110101111b 350dw 0001010110111111b 351dw 0101011010111111b 352 353db 0x8, 0x05 354dw 0100000000000001b 355dw 0101000000000101b 356dw 0101010101010101b 357dw 1001010101010110b 358dw 1010101010101010b 359dw 1111101010101111b 360dw 1111111111111111b 361dw 1111111111111111b 362 363db 0x8, 0x5 364dw 0000000001010101b 365dw 0000010101010101b 366dw 0001010101101001b 367dw 0001011010101010b 368dw 0101011010101010b 369dw 0101101010101111b 370dw 0101101010111111b 371dw 0101011010111111b 372 373db 0x8, 0x5 374dw 0101011010111111b 375dw 0101011011111111b 376dw 0101101011111111b 377dw 1010101111111111b 378dw 1011111111111111b 379dw 1111111111111111b 380dw 1111111111111111b 381dw 1111111111111111b 382 383db 0x8, 0x6 384dw 1010101010101010b 385dw 1010101010011010b 386dw 1010011010111010b 387dw 1010111010101010b 388dw 1010101010101010b 389dw 1010101001101010b 390dw 1010101011101010b 391dw 1010101010101010b 392 393db 0x8, 0x6 394dw 1010101010101010b 395dw 1010101010011010b 396dw 1010011010011010b 397dw 0110011010111010b 398dw 0110111001101010b 399dw 1101101001101010b 400dw 1011101011100110b 401dw 1010101010101110b 402 403db 0x8, 0x6 404dw 1010101010101010b 405dw 0110100110001010b 406dw 0110101110011010b 407dw 1110001010011010b 408dw 1010011000111000b 409dw 1010111001101001b 410dw 1001101011101001b 411dw 1011101010101011b 412 413db 0x8, 0x0 414dw 0001010000000000b 415dw 0000000000010100b 416dw 0000111111100000b 417dw 0011111110101000b 418dw 1111101010101011b 419dw 0111101010111101b 420dw 0001010101010100b 421dw 0000000000000000b 422
; 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
426 427MetaTiles: 428db 00000000b, 00000000b, 00000000b, 00000000b 429db 00000010b, 00000010b, 00000101b, 00000101b 430db 00000001b, 00000101b, 00000001b, 00000101b 431db 00000011b, 00000010b, 00000001b, 00110110b 432db 00000101b, 00000110b, 00010110b, 00000101b 433db 00000110b, 00000111b, 00000111b, 00000111b 434db 00000100b, 00110101b, 00100101b, 00000111b 435db 00000100b, 00100110b, 00010111b, 00110100b 436db 00001000b, 00001000b, 00001000b, 00001000b 437db 00000100b, 00010100b, 00000110b, 00000111b 438db 00000100b, 00000111b, 00100100b, 00010111b 443

LEVEL DATA

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

MEMORY ADDRESSES

592 593_ENTITIES_ equ 0x1000 594_PLAYER_ENTITY_ID_ equ 0x1800 595_REQUEST_POSITION_ equ 0x1802 596_HOLDING_ID_ equ 0x1804 597_SCORE_ equ 0x1805 598_SCORE_TARGET_ equ 0x1806 599_GAME_TICK_ equ 0x1807 600_GAME_STATE_ equ 0x1809 601_WEB_LOCKED_ equ 0x180a 602_LAST_TICK_ equ 0x180b 603_CURRENT_TUNE_ equ 0x180d 604_NEXT_TUNE_ equ 0x180f 605_NOTE_TIMER_ equ 0x1811 606_NOTE_TEMPO_ equ 0x1812 607 608_DBUFFER_MEMORY_ equ 0x2000 609_VGA_MEMORY_ equ 0xA000 610_TICK_ equ 1Ah 611 612_ID_ equ 0 613_POS_ equ 1 614_SCREEN_POS equ 3 615_MIRROR_ equ 5 616_STATE_ equ 6 617_DIR_ equ 7 618
; 5 bytes per entity, 64 entites cap, 320 bytes ; 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 ; 64k bytes ; 64k bytes ; BIOS tick ; 1 byte ; 2 bytes ; 2 bytes ; 1 byte ; 1 bytes ; 1 byte

MAGIC NUMBERS

620 621ENTITY_SIZE equ 10 622MAX_ENTITIES equ 64 623LEVEL_START_POSITION equ 320*68+32 624COLOR_SKY equ 0x3b3b 625COLOR_WATER equ 0x3535 626SCORE_POSITION equ 320*24+32 627INTRO_TIME equ 240 628PRE_GAME_TIME equ 64 629POST_GAME_TIME equ 32 630 631ID_PLAYER equ 0 632ID_PALM equ 1 633ID_SNAKE equ 2 634ID_ROCK equ 3 635ID_SKULL equ 4 636ID_BRIDGE equ 5 637ID_CHEST equ 6 638ID_GOLD equ 7 639ID_SPIDER equ 10 640ID_CRAB equ 11 641ID_BUSH equ 12 642 643STATE_DEACTIVATED equ 0 644STATE_FOLLOW equ 2 645STATE_STATIC equ 4 646STATE_EXPLORING equ 8 647STATE_INTERACTIVE equ 16 648 649GSTATE_INTRO equ 2 650GSTATE_PREGAME equ 4 651GSTATE_GAME equ 8 652GSTATE_POSTGAME equ 16 653GSTATE_END equ 32 654GSTATE_WIN equ 64 655GSTATE_OUTRO equ 128 656 657WEB_LOCK equ 2 658 659BEEP_BITE equ 3 660BEEP_PICK equ 15 661BEEP_PUT equ 20 662BEEP_GOLD equ 5 663

INITIALIZATION

665 666start: 667 mov ax,0x13 668 int 0x10 669 670 push _DBUFFER_MEMORY_ 671 pop es 672 673 set_keyboard_rate: 674 xor ax, ax 675 xor bx, bx 676 mov ah, 03h 677 mov bl, 1Fh 678 int 16h 679 680restart_game: 681 mov word [_GAME_TICK_], 0x0 682 mov byte [_GAME_STATE_], GSTATE_INTRO 683 mov byte [_SCORE_], 0x0 684 mov byte [_HOLDING_ID_], 0x0 685 mov byte [_WEB_LOCKED_], 0x0 686 mov word [_CURRENT_TUNE_], tune_intro 687 mov word [_NEXT_TUNE_], tune_intro 688 mov byte [_NOTE_TIMER_], 0x0 689 690
; 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) ; loop intro tune

SPAWN ENTITIES

Expects: entities array from level data Returns: entities in memory array
694 695spawn_entities: 696 mov si, EntityData 697 mov di, _ENTITIES_ 698 699 .next_entitie: 700 mov bl, [si] 701 cmp bl, 0x0 702 jz .done 703 704 dec bl 705 706 inc si 707 mov al, [si] 708 inc si 709 mov cl, al 710 711 cmp bl, ID_GOLD 712 jnz .not_gold 713 mov [_SCORE_TARGET_], cl 714 .not_gold: 715 716 .next_in_group: 717 mov byte [di], bl 718 mov ax, [si] 719 mov [di+_POS_], ax 720 mov byte [di+_MIRROR_], 0x0 721 mov byte [di+_STATE_], STATE_STATIC 722 mov byte [di+_DIR_], 0x0 723 724 725 cmp bl, ID_SNAKE 726 jz .set_explore 727 cmp bl, ID_CRAB 728 jz .set_explore 729 cmp bl, ID_SPIDER 730 jz .set_explore 731 jmp .skip_explore 732 .set_explore: 733 mov byte [di+_STATE_], STATE_EXPLORING 734 .skip_explore: 735 736 cmp bl, ID_PALM 737 jz .set_rand_mirror 738 cmp bl, ID_BUSH 739 jz .set_rand_mirror 740 jnz .skip_mirror 741 .set_rand_mirror: 742 xor al, ah 743 and al, 0x01 744 mov byte [di+_MIRROR_], al 745 .skip_mirror: 746 747 cmp bl, ID_BRIDGE 748 jz .set_interactive 749 cmp bl, ID_GOLD 750 jz .set_interactive 751 cmp bl, ID_ROCK 752 jz .set_interactive 753 cmp bl, ID_CHEST 754 jz .set_interactive 755 jmp .skip_interactive 756 .set_interactive: 757 mov byte [di+_STATE_], STATE_INTERACTIVE 758 .skip_interactive: 759 760 add si, 0x02 761 add di, ENTITY_SIZE 762 loop .next_in_group 763 jmp .next_entitie 764 .done: 765 766mov word [_PLAYER_ENTITY_ID_], _ENTITIES_ 767
; 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 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

769 770game_loop: 771 xor di, di 772 xor si, si 773

DRAW BACKGROUND

jmp skip_more_ocean
775 776draw_bg: 777 mov ax, COLOR_SKY 778 mov dl, 0xa 779 .draw_sky: 780 mov cx, 320*3 781 rep stosw 782 inc ax 783 xchg al, ah 784 dec dl 785 jnz .draw_sky 786 787draw_ocean: 788 mov ax, COLOR_WATER 789 mov cx, 320*70 790 rep stosw 791 793draw_more_ocean: 794 mov si, Ocean1Brush 795 mov di, 320*62 796 mov ax, [_GAME_TICK_] 797 shr ax, 2 798 mov cx, 16 799 .draw_line: 800 push cx 801 802 mov cx, 40 803 .draw_next_tile: 804 805 test ax, 0x4 806 jz .skip_tile 807 808 mov si, Ocean1Brush 809 test cx, 0x2 810 jz .skip_brush_swap 811 mov si, Ocean2Brush 812 .skip_brush_swap: 813 814 call draw_sprite 815 816 .skip_tile: 817 add di, 8 818 add ax, 0x2 819 .skip_new_line: 820 821 loop .draw_next_tile 822 add di, 320*8 823 inc ax 824 pop cx 825 loop .draw_line 826skip_more_ocean: 827 828
; 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
830 831test byte [_GAME_STATE_], GSTATE_INTRO 832jz skip_game_state_intro 833 834 mov byte [_NOTE_TEMPO_], 2 835 call play_tune 836 838 839 mov di, 320*120 840 mov ax, [_GAME_TICK_] 841 shr ax, 1 842 add di, ax 843 cmp ax, INTRO_TIME 844 jg .start_game 845 mov bx, 0x1 846 call draw_ship 847 848 mov ah, 01h 849 int 16h 850 jz .no_key_press 851 .start_game: 852 853 mov byte [_GAME_STATE_], GSTATE_PREGAME 854 add byte [_GAME_STATE_], GSTATE_GAME 855 mov word [_GAME_TICK_], 0x0 856 .no_key_press: 857 858skip_game_state_intro: 859 860
; BIOS keyboard status function ; Call BIOS interrupt

PRE-GAME

862 863test byte [_GAME_STATE_], GSTATE_PREGAME 864jz skip_game_state_pregame 865 866pre_game: 867 call play_tune 868 869 mov di, 320*52 870 mov ax, [_GAME_TICK_] 871 cmp ax, PRE_GAME_TIME 872 jg .start_game 873 shr ax, 1 874 add di, ax 875 mov bx, 0x1 876 call draw_ship 877 jmp skip_game_state_pregame 878 879 .start_game: 880 mov byte [_GAME_STATE_], GSTATE_GAME 881 mov word [_GAME_TICK_], 0x0 882 883 .clear_kb_buffer: 884 mov ah, 0x01 885 int 0x16 886 jz .cleared 887 mov ah, 0x00 888 int 0x16 889 jmp .clear_kb_buffer 890 891 .cleared: 892 893skip_game_state_pregame: 894

GAME

896 897test byte [_GAME_STATE_], GSTATE_GAME 898jz skip_game_state_game 899 900

STOP SOUND

902stop_game_sound: 903 test byte [_GAME_STATE_], GSTATE_PREGAME 904 jnz .skip_stop_sound 905 test byte [_GAME_STATE_], GSTATE_POSTGAME 906 jnz .skip_stop_sound 907 in al, 0x61 908 and al, 0x0FC 909 out 0x61, al 910 .skip_stop_sound: 911
; Read the PIC chip ; Clear bit 0 to disable the speaker ; Write the updated value back to the PIC chip

DRAWING LEVEL

913 914 915draw_level: 916 mov si, LevelData 917 mov di, LEVEL_START_POSITION 918 xor cx, cx 919 .next_meta_tile: 920 push cx 921 push si 922 923 mov byte al, [si] 924 mov bl, al 925 shr bl, 0x4 926 and bl, 0x3 927 928 and ax, 0xf 929 jnz .not_empty 930 add di, 16 931 jmp .skip_meta_tile 932 .not_empty: 933 934 mov si, MetaTiles 935 shl ax, 0x2 936 add si, ax 937 938 mov dx, 0x0123 939 .check_y: 940 test bl, 2 941 jz .check_x 942 xchg dh, dl 943 .check_x: 944 test bl, 1 945 jz .push_tiles 946 ror dh, 4 947 ror dl, 4 948 949 .push_tiles: 950 mov cx, 4 951 .next_tile_push: 952 push dx 953 ror dx, 4 954 loop .next_tile_push 955 956 mov cx, 0x4 957 .next_tile: 958 pop dx 959 and dx, 0x7 960 push si 961 add si, dx 962 mov byte al, [si] 963 pop si 964 mov bh, al 965 shr bh, 4 966 and bh, 3 967 968 xor bh, bl 969 mov dl, bh 970 971 and ax, 0xf 972 dec ax 973 imul ax, 18 974 975 push si 976 mov si, TerrainTiles 977 add si, ax 978 call draw_sprite 979 pop si 980 981 add di, 8 982 983 cmp cx, 0x3 984 jnz .skip_set_new_line 985 add di, 320*8-16 986 .skip_set_new_line: 987 988 loop .next_tile 989 sub di, 320*8 990 .skip_meta_tile: 991 992 pop si 993 inc si 994 pop cx 995 inc cx 996 test cx, 0xf 997 jnz .no_new_line 998 add di, 320*16-(16*16) 999 .no_new_line: 1000 1001 cmp cx, 0x80 1002 jl .next_meta_tile 1003 1004 1005test byte [_GAME_STATE_], GSTATE_PREGAME 1006jnz skip_keyboard 1007test byte [_GAME_STATE_], GSTATE_POSTGAME 1008jnz skip_keyboard 1009
; 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

1011 1012draw_ship_in_game: 1013 mov di, 320*52+32 1014 xor bx, bx 1015 call draw_ship 1016

KEYBOARD INPUT

cmp cl, 0x0 jz .invalid_move jmp .check_move
1018 1019check_keyboard: 1020 mov ah, 01h 1021 int 16h 1022 jz .no_key_press 1023 1024 mov si, [_PLAYER_ENTITY_ID_] 1025 mov cx, [si+_POS_] 1026 1027 mov ah, 00h 1028 int 16h 1029 1030 .check_spacebar: 1031 cmp ah, 39h 1032 jne .check_up 1033 cmp byte [_HOLDING_ID_], 0x0 1034 jz .set_request_position_to_player 1035 mov byte [_HOLDING_ID_], 0x0 1036 jmp .no_key_press 1037 .set_request_position_to_player: 1038 mov word [_REQUEST_POSITION_], cx 1039 jmp .no_key_press 1040 .check_up: 1041 cmp ah, 48h 1042 jne .check_down 1043 cmp ch, 0x0 1044 jz .invalid_move 1045 dec ch 1046 jmp .check_move 1047 1048 .check_down: 1049 cmp ah, 50h 1050 jne .check_left 1051 inc ch 1052 jmp .check_move 1053 1054 .check_left: 1055 cmp ah, 4Bh 1056 jne .check_right 1059 dec cl 1060 mov byte [si+_MIRROR_], 0x1 1061 jmp .check_move 1062 1063 1064 .check_right: 1065 cmp ah, 4Dh 1066 jne .no_key_press 1067 inc cl 1068 mov byte [si+_MIRROR_], 0x0 1070 1071 .check_move: 1072 call check_friends 1073 jz .no_move 1074 call check_water_tile 1075 jz .no_move 1076 call check_bounds 1077 jz .no_move 1078 1079 .move: 1080 cmp byte [_WEB_LOCKED_], 0 1081 jz .skip_web_check 1082 dec byte [_WEB_LOCKED_] 1083 jmp .no_move 1084 .skip_web_check: 1085 mov word [si+_POS_], cx 1086 .no_move: 1087 mov word [_REQUEST_POSITION_], cx 1088 1089 .no_key_press: 1090 .invalid_move: 1091 1092skip_keyboard: 1093
; BIOS keyboard status function ; Call BIOS interrupt ; Jump if Zero Flag is set (no key pressed) ; Load player position into CX (Y in CH, X in CL) ; BIOS keyboard read function ; Call BIOS interrupt ; 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

1095 1096ai_entities: 1097 mov si, _ENTITIES_ 1098 mov cl, MAX_ENTITIES 1099 .next_entity: 1100 push cx 1101 1102 cmp byte [si+_STATE_], STATE_EXPLORING 1103 jnz .skip_explore 1104 mov ax, [_GAME_TICK_] 1105 add ax, cx 1106 test ax, 0x2 1107 jz .skip_explore 1108 1109 .explore: 1110 mov cx, [si+_POS_] 1111 mov al, [si+_DIR_] 1112 1113 .check_horizontal: 1114 cmp al, 0 1115 jnz .go_left 1116 .go_right: 1117 inc cl 1118 jmp .check_mirror 1119 .go_left: 1120 cmp al, 1 1121 jnz .check_vertical 1122 dec cl 1123 jmp .check_mirror 1124 1125 .check_vertical: 1126 cmp al, 2 1127 jnz .go_up 1128 .go_down: 1129 inc ch 1130 jmp .check_mirror 1131 .go_up: 1132 cmp al, 3 1133 jnz .check_mirror 1134 dec ch 1135 1136 .check_mirror: 1137 mov byte [si+_MIRROR_], 0x0 1138 cmp byte cl, [si+_POS_] 1139 jg .skip_mirror_x 1140 mov byte [si+_MIRROR_], 0x1 1141 .skip_mirror_x: 1142 1143 call check_bounds 1144 jz .can_not_move 1145 1146 call check_friends 1147 jz .can_not_move 1148 1149 call check_water_tile 1150 jz .can_not_move 1151 1152 .move_to_new_pos: 1153 mov word [si+_POS_], cx 1154 jmp .after_move 1155 1156 .can_not_move: 1157 1158 .check_if_crab: 1159 cmp byte [si+_ID_], ID_CRAB 1160 jnz .not_a_crab 1161 xor byte [si+_DIR_], 1 1162 jmp .skip_random_bounce 1163 .not_a_crab: 1164 1165 .random_bounce: 1166 in al, 0x40 1167 add ax, [_GAME_TICK_] 1168 and al, 0x3 1169 mov byte [si+_DIR_], al 1170 1171 .skip_random_bounce: 1172 1173 .check_if_player: 1174 cmp cx, [_REQUEST_POSITION_] 1175 jnz .no_bite 1176 cmp byte [_HOLDING_ID_], 0x0 1177 jnz .continue_game 1178 mov byte [_HOLDING_ID_], 0xff 1179 mov bl, BEEP_BITE 1180 call beep 1181 1182 cmp byte [si+_ID_], ID_SNAKE 1183 jz .snake_bite 1184 cmp byte [si+_ID_], ID_SPIDER 1185 jz .spider_web 1186 cmp byte [si+_ID_], ID_CRAB 1187 jz .crab_bite 1188 jmp .continue_game 1189 1190 .crab_bite: 1191 .snake_bite: 1192 mov byte [_GAME_STATE_], GSTATE_END 1193 mov word [_CURRENT_TUNE_], tune_end 1194 mov word [_NEXT_TUNE_], tune_end 1195 mov byte [_NOTE_TIMER_], 0x0 1196 mov byte [_NOTE_TEMPO_], 0xa 1197 jmp .skip_item 1198 1199 .spider_web: 1200 mov byte [_WEB_LOCKED_] , WEB_LOCK 1201 jmp .continue_game 1202 1203 .continue_game: 1204 mov byte [_HOLDING_ID_], 0x00 1205 jmp .skip_item 1206 .no_bite: 1207 .after_move: 1208 .skip_explore: 1209 1210 cmp byte [si+_STATE_], STATE_INTERACTIVE 1211 jnz .skip_item 1212 mov cx, [si+_POS_] 1213 cmp cx, [_REQUEST_POSITION_] 1214 jnz .skip_item 1215 1216 cmp byte [si+_ID_], ID_BRIDGE 1217 jz .check_bridge 1218 cmp byte [si+_ID_], ID_CHEST 1219 jnz .skip_check_interactions 1220 1221 .check_interactions: 1222 cmp byte [_HOLDING_ID_], ID_GOLD 1223 jnz .skip_item 1224 inc byte [_SCORE_] 1225 mov bl, BEEP_GOLD 1226 call beep 1227 jmp .clear_item 1228 1229 .check_bridge: 1230 cmp byte [_HOLDING_ID_], ID_ROCK 1231 jnz .skip_item 1232 mov byte [si+_STATE_], STATE_DEACTIVATED 1233 .clear_item: 1234 mov byte [_HOLDING_ID_], 0xff 1235 jmp .skip_item 1236 .skip_check_interactions: 1237 1238 cmp byte [_HOLDING_ID_], 0x0 1239 jnz .skip_item 1240 .pick_item: 1241 mov byte [si+_STATE_], STATE_FOLLOW 1242 mov word [_REQUEST_POSITION_], 0x0 1243 mov byte cl, [si+_ID_] 1244 mov byte [_HOLDING_ID_], cl 1245 mov bl, BEEP_PICK 1246 call beep 1247 .skip_item: 1248 1249 .put_item_back: 1250 cmp byte [si+_STATE_], STATE_FOLLOW 1251 jnz .no_follow 1252 1253 cmp byte [_HOLDING_ID_], 0x0 1254 jnz .check_kill 1255 mov byte [si+_STATE_], STATE_INTERACTIVE 1256 mov word [_REQUEST_POSITION_], 0x0 1257 jmp .beep 1258 1259 .check_kill: 1260 cmp byte [_HOLDING_ID_], 0xff 1261 jnz .skip_kill 1262 mov byte [si+_STATE_], STATE_DEACTIVATED 1263 mov byte [_HOLDING_ID_], 0x0 1264 .beep: 1265 mov bl, BEEP_PUT 1266 call beep 1267 .skip_kill: 1268 .no_follow: 1269 1270 add si, ENTITY_SIZE 1271 pop cx 1272 dec cx 1273 jnz .next_entity 1274 1275 1276
; Crab ; Snake ; Spider ; Check if player is holding something

SORT ENITIES

Sort entities by Y position Expects: entities array Returns: sorted entities array
1281 1282sort_entities: 1283 mov cl, MAX_ENTITIES-1 1284 .outer_loop: 1285 push cx 1286 mov si, _ENTITIES_ 1287 1288 .inner_loop: 1289 push cx 1290 mov bx, [si+_POS_] 1291 mov dx, [si+ENTITY_SIZE+_POS_] 1292 1293 cmp bh, dh 1294 jle .no_swap 1295 1296 mov di, si 1297 add di, ENTITY_SIZE 1298 1299 mov ax, [_PLAYER_ENTITY_ID_] 1300 cmp ax, si 1301 jne .check_next_entity 1302 mov [_PLAYER_ENTITY_ID_], di 1303 jmp .swap_entities 1304 .check_next_entity: 1305 cmp ax, di 1306 jne .swap_entities 1307 mov [_PLAYER_ENTITY_ID_], si 1308 .swap_entities: 1309 1310 mov cx, ENTITY_SIZE 1311 .swap_loop: 1312 mov al, [si] 1313 xchg al, [di] 1314 mov [si], al 1315 inc si 1316 inc di 1317 loop .swap_loop 1318 sub si, ENTITY_SIZE 1319 1320 .no_swap: 1321 add si, ENTITY_SIZE 1322 pop cx 1323 loop .inner_loop 1324 1325 pop cx 1326 loop .outer_loop 1327
; We'll do n-1 passes ; Get Y of current entity ; Get Y of next entity ; Compare Y values

DRAW ENITIES

open chest
1329 1330draw_entities: 1331 mov si, _ENTITIES_ 1332 mov cl, MAX_ENTITIES 1333 .next: 1334 push cx 1335 push si 1336 1337 cmp byte [si+_STATE_], STATE_DEACTIVATED 1338 jz .skip_entity 1339 1340 .hire_player: 1341 test byte [_GAME_STATE_], GSTATE_PREGAME 1342 jnz .hide_player 1343 test byte [_GAME_STATE_], GSTATE_POSTGAME 1344 jnz .hide_player 1345 jmp .skip_hide_player 1346 .hide_player: 1347 cmp byte [si+_ID_], ID_PLAYER 1348 jz .skip_entity 1349 cmp byte [si+_ID_], ID_CHEST 1350 jz .skip_entity 1351 .skip_hide_player: 1352 1353 mov cx, [si+_POS_] 1354 call conv_pos2mem 1355 1356 cmp byte [si+_STATE_], STATE_FOLLOW 1357 jnz .skip_follow 1358 push si 1359 mov si, [_PLAYER_ENTITY_ID_] 1360 mov cx, [si+_POS_] 1361 pop si 1362 mov word [si+_POS_], cx 1363 call conv_pos2mem 1364 sub di, 320*12 1365 .skip_follow: 1366 1367 mov byte al, [si] 1368 mov ah, al 1369 1370 cmp ah, ID_PLAYER 1371 jnz .skip_player_check 1372 cmp byte [_HOLDING_ID_], 0x0 1373 jz .skip_player_check 1374 mov al, 0x9 1375 .skip_player_check: 1376 1377 shl al, 0x2 1378 mov bx, BrushRefs 1379 add bl, al 1380 mov dx, [bx] 1381 push dx 1382 1383 add al, 0x2 1384 movzx bx, al 1385 add di, [BrushRefs + bx] 1386 mov dl, [si+_MIRROR_] 1387 1388 pop si 1389 call draw_sprite 1390 1391 cmp ah, ID_PLAYER 1392 jnz .skip_player_draw 1393 mov si, IndieBottomBrush 1394 add di, 320*7 1395 call draw_sprite 1396 cmp byte [_WEB_LOCKED_], 0 1397 jz .skip_web_draw 1398 mov si, WebBrush 1399 sub di, 320*6 1400 call draw_sprite 1401 .skip_web_draw: 1402 .skip_player_draw: 1403 1404 cmp ah, ID_GOLD 1405 jnz .skip_gold_draw 1406 mov ax, [_GAME_TICK_] 1407 add ax, cx 1408 and ax, 0x4 1409 cmp ax, 0x2 1410 jl .skip_gold_draw 1411 xor dl, dl 1412 mov si, GoldBrush 1413 call draw_sprite 1414 .skip_gold_draw: 1415 1416 cmp ah, ID_CRAB 1417 jnz .skip_crab 1418 mov dl, 0 1419 mov si, CrabClawBrush 1420 add di, 8 1421 call draw_sprite 1422 mov dl, 1 1423 sub di, 320+16 1424 call draw_sprite 1425 .skip_crab: 1426 1427 cmp ah, ID_CHEST 1428 jnz .skip_chest 1429 cmp byte [_HOLDING_ID_], ID_GOLD 1430 jnz .skip_open_chest 1431 1433 1434 mov si, ChestTopBrush 1435 sub di, 320*3+8 1436 call draw_sprite 1437 1438 mov si, ArrowBrush 1439 sub di, 320*8-8 1440 mov ax, [_GAME_TICK_] 1441 and ax, 0x1 1442 imul ax, 320*2 1443 add di, ax 1444 call draw_sprite 1445 jmp .skip_chest 1446 .skip_open_chest: 1447 mov si, ChestCloseBrush 1448 sub di, 320 1449 call draw_sprite 1450 .skip_chest: 1451 1452 .skip_entity: 1453 pop si 1454 add si, ENTITY_SIZE 1455 pop cx 1456 dec cx 1457 jg .next 1458 1459skip_draw_entities: 1460
; Convert position to memory ; Load player position into CX (Y in CH, X in CL) ; Save new position ; Convert position to memory ; Move above player ; 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 address ; no mirror

CHECK SCORE

1462 1463test byte [_GAME_STATE_], GSTATE_PREGAME 1464jnz skip_score 1465test byte [_GAME_STATE_], GSTATE_POSTGAME 1466jnz skip_score 1467 1468check_score: 1469 mov di, SCORE_POSITION 1470 mov al, [_SCORE_TARGET_] 1471 mov ah, [_SCORE_] 1472 cmp al, ah 1473 jg .continue_game 1474 add byte [_GAME_STATE_], GSTATE_POSTGAME 1475 mov word [_GAME_TICK_], 0x0 1476 mov word [_CURRENT_TUNE_], tune_win 1477 mov word [_NEXT_TUNE_], tune_win 1478 mov byte [_NOTE_TIMER_], 0x0 1479 mov byte [_NOTE_TEMPO_], 0x2 1480 .continue_game: 1481

DRAW SCORE

1483 1484draw_score: 1485 xor cl, cl 1486 .draw_spot: 1487 mov si, SlotBrush 1488 call draw_sprite 1489 cmp cl, ah 1490 jge .skip_gold_draw 1491 mov si, GoldBrush 1492 call draw_sprite 1493 .skip_gold_draw: 1494 add di, 0xa 1495 inc cl 1496 cmp al, cl 1497 jnz .draw_spot 1498 1499skip_score: 1500skip_game_state_game: 1501 1502

POST GAME

1504 1505test byte [_GAME_STATE_], GSTATE_POSTGAME 1506jz skip_game_state_postgame 1507draw_post_game: 1508 mov ax, [_GAME_TICK_] 1509 shr ax, 1 1510 cmp ax, POST_GAME_TIME 1511 jnz .move_ship 1512 mov byte [_GAME_STATE_], GSTATE_END+GSTATE_WIN 1513 .move_ship: 1514 mov di, 320*52+32 1515 add di, ax 1516 mov bx, 0x1 1517 call draw_ship 1518 call play_tune 1519 1520 1521skip_game_state_postgame: 1522

GAME END

1524 1525test byte [_GAME_STATE_], GSTATE_END 1526jz skip_game_state_end 1527 call play_tune 1528 mov di, 320*100+154 1529 mov si, SkullBrush 1530 test byte [_GAME_STATE_], GSTATE_WIN 1531 jz .draw_icon 1532 mov si, GoldBrush 1533 .draw_icon: 1534 call draw_sprite 1535skip_game_state_end: 1536 1537

VGA BLIT PROCEDURE

1539 1540vga_blit: 1541 push es 1542 push ds 1543 1544 push _VGA_MEMORY_ 1545 pop es 1546 push _DBUFFER_MEMORY_ 1547 pop ds 1548 mov cx,0x7D00 1549 xor si,si 1550 xor di,di 1551 rep movsw 1552 1553 pop ds 1554 pop es 1555 1556
; Set VGA memory ; as target ; Set doublebuffer memory ; as source ; Half of 320x200 pixels ; Clear SI ; Clear DI ; Push words (2x pixels)

GAME TICK

1558 1559wait_for_tick: 1560 xor ax, ax 1561 int _TICK_ 1562 mov bx, dx 1563.wait_loop: 1564 int _TICK_ 1565 cmp dx, bx 1566 je .wait_loop 1567 1568inc word [_GAME_TICK_] 1569 1570
; 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

1572 1573 in al, 0x60 1574 dec al 1575 jnz game_loop 1576
; Read keyboard ; Decrement AL (esc is 1, after decrement is 0) ; If not zero, loop again

TERMINATE PROGRAM

1578 1579 exit: 1580

BEEP STOP

1582 1583 in al, 0x61 1584 and al, 0x0FC 1585 out 0x61, al 1586 1587 mov ax, 0x4c00 1588 int 0x21 1589 ret 1590
; Read the PIC chip ; Clear bit 0 to disable the speaker ; Write the updated value back to the PIC chip ; Return to BIOS/DOS

BEEP PC SPEAKER

Set the speaker frequency Expects: BX - frequency value Return: - xor bh, bh
1595 1596beep: 1598 mov al, 0xB6 1599 out 0x43, al 1600 mov ah, bl 1601 out 0x42, al 1602 mov al, ah 1603 out 0x42, al 1604 in al, 0x61 1605 or al, 0x03 1606 out 0x61, al 1607ret 1608
; 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

CNVERT XY TO MEM

Expects: CX - position YY/XX Return: DI memory position
1612 1613conv_pos2mem: 1614 mov di, LEVEL_START_POSITION 1615 xor ax, ax 1616 mov al, ch 1617 imul ax, 320*8 1618 xor dh, dh 1619 mov dl, cl 1620 shl dx, 3 1621 add ax, dx 1622 add di, ax 1623ret 1624
; 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
1628 1629check_bounds: 1630 xor ax, ax 1631 cmp ch, 0x0f 1632 ja .return 1633 cmp cl, 0x1f 1634 ja .return 1635 inc ax 1636.return: 1637 test ax, 1 1638 ret 1639
; Assume bound hit (AX = 0) ; No bound hit (AX = 1) ; Set flags based on AX

CHECK FRIEDS

Expects: CX - Position YY/XX Return: AX - Zero if hit entity, 1 if clear
1643 1644check_friends: 1645 push si 1646 push cx 1647 xor bx, bx 1648 mov ax, cx 1649 1650 mov cl, MAX_ENTITIES 1651 mov si, _ENTITIES_ 1652 .next_entity: 1653 cmp byte [si+_STATE_], STATE_FOLLOW 1654 jle .skip_this_entity 1655 cmp word [si+_POS_], ax 1656 jnz .skip_this_entity 1657 inc bx 1658 jmp .done 1659 .skip_this_entity: 1660 add si, ENTITY_SIZE 1661 loop .next_entity 1662 1663 .done: 1664 pop cx 1665 pop si 1666 cmp bx, 0x1 1667ret 1668

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
1672 1673check_water_tile: 1674 mov ax, cx 1675 shr ah, 1 1676 shr al, 1 1677 movzx bx, ah 1678 shl bx, 4 1679 add bl, al 1680 add bx, LevelData 1681 mov al, [bx] 1682 test al, 0x40 1683ret 1684 1685play_tune: 1686 cmp byte [_NOTE_TIMER_], 0x0 1687 jz .new_note 1688 dec byte [_NOTE_TIMER_] 1689 jmp .done 1690 .new_note: 1691 inc word [_CURRENT_TUNE_] 1692 mov si, [_CURRENT_TUNE_] 1693 mov bl, [si] 1694 cmp bl, 0 1695 jnz .skip_loop 1696 mov ax, [_NEXT_TUNE_] 1697 mov word [_CURRENT_TUNE_], ax 1698 mov si, ax 1699 mov bl, [si] 1700 .skip_loop: 1701 mov byte al, [_NOTE_TEMPO_] 1702 mov byte [_NOTE_TIMER_], al 1703 call beep 1704 .done: 1705ret 1706 1707 1710 1711draw_ship: 1712 xor dx, dx 1713 1714 mov ax, [_GAME_TICK_] 1715 and ax, 0xf 1716 cmp ax, 0x6 1717 jl .skip_wave 1718 sub di, 320 1719 .skip_wave: 1720 mov si, ShipBackBrush 1721 call draw_sprite 1722 add di, 8 + 320*4 1723 mov si, ShipMiddleBrush 1724 call draw_sprite 1725 add di, 8 1726 mov si, ShipMiddleBrush 1727 call draw_sprite 1728 add di, 8 1729 mov si, ShipFrontBrush 1730 call draw_sprite 1731 1732 mov si, ShipSailBrush 1733 sub di, 12 + 320*5 1734 call draw_sprite 1735 add di, 320*2 - 4 1736 call draw_sprite 1737 sub di, 320*7 - 3 1738 call draw_sprite 1739 add di, 320*2 - 4 1740 call draw_sprite 1741 sub di, 320*6 - 1 1742 call draw_sprite 1743 1744 add di, 320*10 + 10 1745 call draw_sprite 1746 sub di, 320*4 + 2 1747 call draw_sprite 1748 1749 cmp bx, 0x1 1750 jnz .skip_wiosla 1751 xor dx, dx 1752 mov ax, [_GAME_TICK_] 1753 shr ax, 3 1754 and ax, 0x1 1755 add dl, al 1756 sub di, ax 1757 sub di, ax 1758 sub di, ax 1759 mov si, WioslaBrush 1760 add di, 320*15-7 1761 call draw_sprite 1762 add di, 8 1763 call draw_sprite 1764 .skip_wiosla: 1765ret 1766
; 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 Return: -
1772 1773draw_sprite: 1774 pusha 1775 xor cx, cx 1776 mov byte cl, [si] 1777 inc si 1778 1779 xor ax, ax 1780 mov byte al, [si] 1781 inc si 1782 1783 shl ax, 0x2 1784 mov bp, ax 1785 add bp, PaletteSets 1786 1787 test dl, 0x1 1788 jz .no_x_mirror 1789 add di, 0x7 1790 .no_x_mirror: 1791 1792 test dl, 0x2 1793 jz .no_y_mirror 1794 add si, cx 1795 add si, cx 1796 sub si, 0x2 1797 .no_y_mirror: 1798 1799 .plot_line: 1800 push cx 1801 mov ax, [si] 1802 xor bx, bx 1803 mov cl, 0x08 1804 push si 1805 .draw_pixel: 1806 push cx 1807 1808 rol ax, 2 1809 mov bx, ax 1810 and bx, 0x3 1811 1812 mov si, bp 1813 add si, bx 1814 mov byte bl, [si] 1815 1816 cmp bl, 0x0 1817 jz .skip_pixel 1818 mov byte [es:di], bl 1819 .skip_pixel: 1820 1821 inc di 1822 1823 mov bl, dl 1824 and bl, 0x1 1825 jz .no_x_mirror2 1826 dec di 1827 dec di 1828 .no_x_mirror2: 1829 1830 pop cx 1831 loop .draw_pixel 1832 1833 pop si 1834 add si, 0x2 1835 1836 mov bl, dl 1837 and bl, 0x2 1838 jz .no_y_mirror2 1839 sub si, 0x4 1840 .no_y_mirror2: 1841 1842 add di, 312 1843 1844 mov bl, dl 1845 and bl, 0x1 1846 jz .no_x_mirror3 1847 add di, 0x10 1848 .no_x_mirror3: 1849 1850 pop cx 1851 loop .plot_line 1852 popa 1853ret 1854
; lines ; Palette ; each set is 4x 1 byte ; 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
1856 1858

THE END

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