3 ; Release Date : may 2000
4 ; Filename : worm.86p (5kb)
6 ; Email Address : shiar@mailroom.com
8 ; Web Page : www.games3.net/shiar
9 ; Description : ruling multiplayer game for 86 (most like Nibbles)
10 ; Where to get this game : games3.net/shiar (home of Worm)
11 ; Other games by author(s) : Shiar: Nemesis beta
12 ; Additional Credits to : Matthew Shepcar (wrote original Peaworm, end'98)
13 ; Jonah Cohen (wrote some parts of worm)
15 ;-----------------------------
16 ;----------- TO-DO -----------
17 ;-----------------------------
21 ; 2% * fix deaths linkplay and transmit game/level data
22 ; 2% * make linkplay available for all gametypes (not just deathmatch)
23 ; 1% * fix pea XOR problem in ctf (+dom?)
25 ; 1% * domination?: take control points by running over them and hold them
27 ; * complete readme (+custom level info)
28 ; 2% * ... (pollish, &&&)
32 ;100% = bugs fixed + levels done
34 ;-----------------------------
35 ;-----------------------------
36 ;--------- W O R M ---------
37 ;-----------------------------
38 ;-----------------------------
40 #define buffer ;use display buffer (otherwise write directly to screen)
41 #define readymask ;"grays" out the field before starting a level
43 ;#define readytext ;displays "prepare" before level starts
44 ;#define invincible ;worms cannot die =)
51 #include "ti86asm.inc"
55 _divHLby10 = $4044 ;hl=hl/10
56 _divAby10 = $4DAF ;a=a/10
57 _HLTIMES10 = $41BF ;hl=hl*10
59 _clrWindow = $4A86 ;clear screen
60 _asapvar = $D6FC ;own name (worm)
61 _MOV4B = $429B ;4x ld (de),(hl)
62 _MOV5B = $4297 ;5x ld (de),(hl)
63 _mov9b = $4283 ;9x ld (de),(hl)
64 _ldHLind = $4010 ;ld hl,(hl)
65 _swapt_ = $45F3 ;ex_ahl_bde
66 _Get_Word_ahl = $521D ;ld de,(ahl)
67 _Set_Word_ahl = $5221 ;ld (ahl),de
68 _INC_PTR_AHL = $4637 ;ahl=ahl+1
69 _AHL_PLUS_2_PG3 = $4C3F ;ahl=ahl+2
70 _SET_ABS_SRC_ADDR = $4647 ;set source for mm.ldir =ahl
71 _LOAD_ABS_SRC_ADDR = $5209 ;ahl = mm.ldir source
72 _SET_ABS_DEST_ADDR = $5285 ;set destination for mm.ldir = ahl
73 _SET_MM_NUM_BYTES = $464F ;number of bytes for mm.ldir = ahl
74 _mm_ldir = $52ED ;24bit ldir
75 _RAM_PAGE_1 = $47E3 ;set $8000+ to page 1
77 _PTEMP_END = $D29A ;end of VAT
78 _load_ram_ahl = $462F ;ahl->page+hl
79 _writeb_inc_ahl = $5567 ;ld (ahl),c
80 _jforce = $409C ;TI-OS stack restored
81 _EXLP = $4493 ;swap (hl),(de) b times
83 ;-----------------------------
84 ;------- data storage -------
85 ;-----------------------------
89 ScrBuffer = $8820 ;-A7FF (20*FF=1FE0)
90 worm2p = $A800 ;-ABFF (400) %10101O00
91 worm1 = $AC00 ;-AC1D (31d)
92 worm2 = $AC1F ;-AC3B (1F)
93 worm3 = $AC3E ;-AC59 (1F)
94 worm4 = $AC5D ;-AC77 (1F)
95 balls = $AC7C ;-ACFF (3x43d)
96 SinCosTable = $AD00 ;-AE00 (4x40)
97 ;free $AE01 ;-AFFF (1FF)
98 worm1p = $B000 ;-B7FF (800) %1011O000
99 worm3p = $B800 ;-BBFF (400) %10111O00
100 ;free $BF91 ;-BFFF (6F)
102 ;program $D748 ;-E7FF (106D+4A)
103 ;free $E800 ;-EFFF (800)
104 worm4p = $F000 ;-F3FF (400) %11110O00
105 leveldata = $F400 ;-FA70 (<=671)
111 templevels = $BC00 ;(3*strings) @init
112 namelength = $BC00 ;(1) @menu
114 DispBuffer = $BC00 ;(10x57d) @game
119 ;-----------------------------
120 ;------- program start -------
121 ;-----------------------------
135 .db "WORM by SHIAR -- pre-beta 91%",0
138 .db %10010110,%01101111
139 .db %10110101,%01001011
140 .db %01110011,%01001001
141 .db %00000011,%10000000
142 .db %00000001,%11100000
143 .db %00111000,%11111000
144 .db %01111110,%00111111
145 .db %11101111,%00001111
146 .db %11000011,%10000000
149 levelhead2 = 91 ;worm levels header = "91"
157 ld hl,$BFFF ;VAT start
160 ld de,(_PTEMP_END+1) ;VAT end
193 ex de,hl ;ld ahl,(hl)
194 cal _AHL_PLUS_2_PG3 ;string id
195 cal _Get_Word_ahl ;ld de,(ahl)
200 jr nz,searchnext ;not worm
218 cal _Get_Word_ahl ;ld de,(ahl++)
223 ld a,e ;set new level
245 jp z,_clrWindow ;no ext files: exit
253 cal _puts ;"< Select levels: >"
272 cal _load_ram_ahl ;hl=ahl
273 ld b,(hl) ;b=title size
275 cal _putps ;destr=abchl
293 cp K_ENTER-K_EXIT+256
305 ld (leveldataSize),de
314 cal _SET_ABS_SRC_ADDR
317 cal _SET_ABS_DEST_ADDR
321 cal _SET_MM_NUM_BYTES
324 cal _LOAD_ABS_SRC_ADDR ;->ahl
330 res 2,(iy+13) ;appAutoScroll
334 ;-----------------------------
335 ;----- build trig tables -----
336 ;-----------------------------
361 ;-----------------------------
362 ;---------- menu -------------
363 ;-----------------------------
391 cal _puts ;Level <00>
398 cal _puts ;Singleplayer
410 jp LetsGetThisPartyOn ;1/3/4
424 jp nz,LetsGetThisPartyOn
432 ld d,(hl) ;max level for sel.game
486 jr dispnrworms ;mainMenu
491 jr c,_mainMenu ;type 0/1
500 ld a,(hl) ;hl=nrworms
507 jr _dispcurlevel ;mainMenu
564 cal _puts ;"Enter name player "
655 jr nz,waitnokeypressed
659 .db 0,".<>!",0,0,0,0 ;down,L,R,up
660 .db 0,"XTOJE0",0 ;enter..clear
661 .db " WSNID9",0 ;(-)..custom
662 .db "ZVRMHC8",0 ;dot..del
663 .db "YUQLGB7#" ;0..xvar
664 .db $D9,"-PKFA6'" ;on..alpha
665 .db "54321*",0,$D0 ;F5..more
669 skiplevel: ;@hl - destr:ab - alter:hl
674 ld b,(hl) ;spritesize
685 inc b ;multiplayer lvl
687 inc b ;skip other 3 worms (9 bytes)
709 ld a,(hl) ;lines/boxes
720 ;-----------------------------
721 ;-------- start game ---------
722 ;-----------------------------
726 ld (CheckExit),a ;set exit state
748 ld de,$FF64 ;virt.infinate
754 cal _ldHLind ;ld hl,(hl)
759 dec d ;levels to skip
781 ; jp nz,linkiniterror
828 ; jp nz,linkiniterror
839 ;-----------------------------
840 ;--------- game over ---------
841 ;-----------------------------
847 ld a,4 ;4x (all worms)
860 ex de,hl ;de=wormX+head
864 jr nz,createwormsloop
871 pop hl ;begin of current level
883 ;show end msg or smtn
885 psh bc ;where to go afterwards
886 inc hl ;location of ending-code
887 jp (hl) ;go there ("call")
909 ld b,0 ;bc=sprite size
910 add hl,bc ;hl=behind sprite
960 ld bc,(worm2-worm1)-5
965 ;-------- draw level ---------
1096 ;-----------------------------
1098 psh hl ; >> levelp new
1133 ld hl,4+(txtposReady*256)
1144 jr z,initfinished ;no link
1147 ld (worm2+input),a ;worm 2 via link
1149 ld (Speed),a ;max.speed
1150 SwapPos: ;$18 xx -> $F6 xx
1154 ld (worm2+left),a ;1
1157 ld b,4 ;+heading +pos
1158 cal _EXLP ;swap positions
1163 cal _EXLP ;swap positions
1172 ;-----------------------------
1173 ;----------- LOOP ------------
1174 ;-----------------------------
1193 jr nz,screeninvertloop
1209 cal nz,handlethoseneatlittleballs
1222 ;-----------------------------
1223 ;---------- keys -------------
1224 ;-----------------------------
1239 rla ;=$17 (c=EXIT-key)
1250 ld (ix+delay),respawndelay
1269 ret nz ;HandleWorm done
1273 ld a,$A7 ;exit@end of turn
1274 ld (CheckExit),a ;set exit state
1310 cp (hl) ;input=0 = link
1335 ld a,(hl) ;worm+died
1343 cal _ldHLind ;ld hl,(hl)
1344 cal showHL ;worm+score
1350 dnz displayWormStats
1353 or a ;singleplayer (0) only
1354 jr nz,hilevelcheckdone
1359 jr c,hilevelcheckdone
1360 ld (hl),a ;save local
1365 hilvlposhl =$-2 ;save external
1366 cal _writeb_inc_ahl ;ld (ahl),c
1371 jr z,hiscorecheckdone
1373 cal loadhiscoreposinahl
1374 cal _Get_Word_ahl ;de=old_hi
1382 jr c,NotNewHigh ;New<Old
1383 jr nz,newhigh ;New>Old
1387 jr nc,NotNewHigh ;new<old
1391 cal loadhiscoreposinahl
1392 cal _Set_Word_ahl ;de->(ahl)
1395 NotNewHigh: ;de=current hiscore
1416 ;x123456789012345678901
1417 ;1----- GAME OVER -----
1422 ;6Worm#02 @ 05 00120
1428 rst 20h ;_ABS_MOV10TOOP1
1434 cal _SET_ABS_DEST_ADDR
1438 cal _SET_ABS_SRC_ADDR
1439 ld hl,end-_asm_exec_ram
1440 cal _SET_MM_NUM_BYTES
1448 loadhiscoreposinahl:
1453 externalhiscoresavepos:
1461 dnz addlevelposition
1464 ;-----------------------------
1465 ;----------- worm ------------
1466 ;-----------------------------
1471 cal saverespawncounter
1477 jr DoesWormTailEqualsWormHead ;chk4 size=0
1488 DoesWormTailEqualsWormHead:
1490 jr nz,removewormloop
1494 jr nz,safewormsizedone
1502 ld (ix+tail),e ;head=tail/size=0
1508 jr nz,saverespawncounter
1526 inkeys: ;use jp not call!
1573 ;------- handle worm ---------
1605 ;-------- move worm ----------
1633 notmoveY: ;bc=newpos
1640 pop hl ; << pos (old)
1658 ;--------- worm hit ----------
1664 cal z,checkhitotherworm
1666 and _datamultpeas ;&&bit
1670 jp z,WormDead ;no food
1677 cal DrawPea ;remove pea
1689 jp nz,Drawworm ;continue
1695 jp nz,Exit ;stack restored
1706 cal IncScore ;score+(40*level)
1710 pop hl ; << levelp new
1714 chkpeahit: ;hl=peapos
1743 ld hl,(peaspos) ;1st pea
1749 ld hl,(peaspos+2) ;2nd pea
1752 pop hl ;(peapos) 1st pea
1753 jp c,stopworm ;own pea hit
1755 ld a,e ;peek a (that x86 asm for pop\push ;)
1758 ld hl,(peaspos+2) ;2nd pea
1771 cal DrawPea ;restore own flag
1772 jr sillylabel ;inv both\die
1774 hitflag: ;correct pea hit
1792 ret ;Z=yes: no flag taken
1794 ;-----------------------------
1813 jr nz,nextotherwormbit
1838 .db $dd,$7d ;ld a,lx
1841 jr nz,chkworm2 ; ret nz
1866 ;-------- draw worm ----------
1874 cal z,checkhitlapline
1919 ;-----------------------------
1920 ;---------- ball -------------
1921 ;-----------------------------
1923 handlethoseneatlittleballs:
1969 bit 1,d ;1=up; 0=down
1999 letsmovetheotherway:
2014 ;-----------------------------
2015 ;----------- procs -----------
2016 ;-----------------------------
2020 ld a,%10000000 ;all key-masks
2023 inc a ;cp %11111111 (no keys pressed)
2024 jr nz,releasekeys ;keep waitin
2025 cal GET_KEY ;clear buffer
2071 jr nz,NewPea ;pixel found
2078 ;all ok; empty space
2087 ;----------- score -----------
2107 jr z,scorecommon ;hl/1000 not increased
2115 jr c,showstats ;<0=0
2253 ;-----------------------------
2371 ld (ShiftRightCounter),a
2373 ld (ShiftRightChunk),a
2387 ShiftRightCounter = $-1
2409 ld (ShiftLeftCounter),a
2411 ld (ShiftLeftChunk),a
2413 jr nc,ShiftLeftSameByte
2432 ShiftLeftCounter = $-1
2443 jr nz,ShiftRowsRight
2477 ;----------- draw ------------
2491 CheckPixel: ;at bc in d
2498 ;CLEM's FIND_PIXEL (131+? cycles; 28+4 bytes)
2499 ;(b,c) to hl:a; "destroyes" ahl
2501 FindPixel: ;(b,c) to hl:a
2534 PutSprite: ;||@(b,c)
2535 ;by SHIAR only ix saved
2687 drawbox: ;(d,e)-(h,l)
2697 ;-----------------------------
2698 ;----------- link ------------
2699 ;-----------------------------
2726 ;---- SEND ---- 8 bits in a
2727 ;-------------- destr:bcdehl
2730 ld b,8+1 ;bits to send
2733 rr c ;bit to send (in cf)
2734 ld a,D0LD1H ;0: lower white
2736 ld a,D0HD1L ;1: lower red
2738 out (7),a ;lower one (send bit)
2741 cal checklink ;other calc must lower other whire
2744 ld a,D0HD1H ;ok to raise both
2749 cp %11 ;both raised (by other calc)
2751 dnz sendloop ;repeat for all bits
2758 ;---- RECV ---- 8 bits to a
2759 ;-------------- destr:bcdehl
2772 ld b,8 ;bits to receive
2777 jr z,LinkFailed ;both low = error
2779 jr z,WaitRecBit ;both on = nothing sent
2781 rra ;received bit in cf
2784 jr c,savebit ;lower white as well
2786 ld d,D0HD1L ;lower red
2791 out (7),a ;lower other (both low)
2795 ; jr z,waitackrecv ;wait for one to go high
2800 out (7),a ;raise both
2801 dnz receiveloop ;repeat for all bits
2803 ld a,c ;a=byte received
2806 ;-----------------------------
2807 ;---------- levels -----------
2808 ;-----------------------------
2811 .db 5,4,15,15,0,0 ;peas,speed,growth,begin_size,sprite,balls
2812 .db 0,2,63 ;start d, y, x
2813 .db 128,57 ;field width (128-255), height (57-255)
2814 .db 0,0 ;no additional lines, boxes
2821 .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
2825 ;-----------------------------
2826 ;---------- data -------------
2827 ;-----------------------------
2830 .db %00011110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
2831 .db %00111110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
2832 .db %01110000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
2833 .db %01100000,%01111100,%00000001,%11111111,%00000000,%11110000,%01111001,%11100000
2834 .db %11100000,%11111110,%00000011,%11111111,%10000011,%11111000,%11111111,%11110000
2835 .db %11000001,%11000111,%00000111,%00000001,%11000111,%10011001,%11001111,%00111000
2836 .db %11000001,%10000011,%00000110,%00000000,%11100110,%00000001,%10011111,%10011000
2837 .db %11000001,%10000011,%00000110,%11000000,%01101110,%00000011,%10111001,%11011100
2838 .db %11000001,%11000111,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100
2839 .db %11000000,%11000110,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100
2840 .db %11100000,%11101110,%00001110,%11000000,%01101100,%00000011,%00111001,%11001100
2841 .db %01100000,%01111100,%00001100,%11000000,%01101100,%00000011,%00011111,%10001100
2842 .db %01110000,%00111000,%00011100,%11100000,%11101110,%00000011,%00001111,%00001100
2843 .db %00111000,%11111110,%00111000,%01110001,%11000110,%00000011,%10000000,%00011100
2844 .db %00011111,%11101111,%11110000,%00111111,%10000111,%00000001,%10000000,%00011000
2845 .db %00001111,%10000011,%11100000,%00011111,%00000011,%00000001,%10000000,%00011000
2847 txtMenu: .db "by Shiar",0
2848 .db "Have fun!",0 ;4th menu item
2849 .db "Level ",$CF,"??",5,0 ;3rd
2850 .db "Worms ",$CF,"?",5,0 ;2nd
2851 txtGame: .db "Singleplayer",0 ;0 (1st)
2852 txtGame2: .db "Peaworm ",0 ;1 (next 1st)
2853 .db "Deathmatch",0 ;2
2854 .db "Foodmatch ",0 ;3
2855 .db "LinkMatch",0 ;4
2858 .db "Domination",0 ;7
2859 txtLevsel: .db $CF," Select levels: ",5,0
2860 txtName: .db "Enter name player ",0
2861 txtWaiting: .db "Waiting...",0
2862 txtReceive: .db "Receiving..." ;,0
2865 .db 0, 3, 6, 9, 12, 15, 18, 21
2866 .db 24, 27, 30, 33, 36, 39, 42, 45
2867 .db 48, 51, 54, 57, 59, 62, 65, 67
2868 .db 70, 73, 75, 78, 80, 82, 85, 87
2869 .db 89, 91, 94, 96, 98,100,102,103
2870 .db 105,107,108,110,112,113,114,116
2871 .db 117,118,119,120,121,122,123,123
2872 .db 124,125,125,126,126,126,126,126
2875 txtLevel: .db "Level ",0
2876 txtWorms: .db "Worms: 0",0 ;follows txtLevel
2877 txtDied: .db "Died ",0
2878 txtScore: .db "Score",0 ;follows txtDied
2879 txtLeft: .db " left",0 ;follows txtScore
2880 txthiscore:.db "HiScore:",0
2881 txtReady: .db "Prepare!",0
2883 txtGO: .db "----- GAME OVER -----",0
2887 _datalink = %00000001 ;linkplay
2888 _datalivel = %00000010 ;lives=0 limit
2889 _datafoodl = %00000100 ;left=0 limit
2890 _datanextl = %00001000 ;next level if left=0
2891 _datasingl = %00001000 ;singleplayer=1
2892 _datafood = %00010000 ;food present
2893 _________ = %00100000 ;
2894 _datadie = %01000000 ;worm dies on impact
2895 _datascore = %10000000 ;score>=100 limit
2896 _datamultpeas = %00100000
2899 datasingle: .db %01011110
2901 datapeas: .db %01011010
2903 datadeathm: .db %01000010
2905 datafoodm: .db %11010000
2907 datalinkm: .db %01000011
2909 datarace: .db %10000000
2911 datactf: .db %11100000
2913 datadomin: .db %01000000 ;==(8 modes)
2915 datalevels: .dw LevelDef, LevelDef
2916 .dw LevelDefM,LevelDefM
2917 .dw LevelDefM,LevelDefM
2918 .dw LevelDefM,LevelDefM
2919 nrlevels: .db 2,2,2,2,2,2,2,2
2921 worm1set: .dw worm1p,worm1p
2922 .db %11110111,3,%00,%01111110,%10,%100 ;< >
2923 worm1name: .db "worm #01",0
2924 worm2set: .dw worm2p,worm2p
2925 .db %11111011,3,%11,%00111111,%10000,%1000 ;f1 f2
2926 worm2name: .db "worm #02",0
2927 worm3set: .dw worm3p,worm3p
2928 .db %11111011,3,0,%01011111,%10,%100 ;sto ,
2929 worm3name: .db "worm #03",0
2930 worm4set: .dw worm4p,worm4p
2931 .db %11111011,3,0,%01111101,%10,%1 ;enter +
2932 worm4name: .db "worm #04",0
2938 peasprite: .db %01100000
2952 head = 12 ;4B (head=tail)
2953 tail = 14 ;also@next level
2969 ;-----------------------------
2970 ;----------- end -------------
2971 ;-----------------------------