-+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+ X`1B`5B2;30H`60`1B`5B3;30Hx`1B`5B4;30Hx X`1B`5B2;30Hlqq`60 X`1B`5B2;33Hqq`60 X`1B`5B2;35Hqq`60 X`1B`5B2;37Hqq`60 X`1B`5B2;39Hqq`60 X`1B`5B2;41Hqq`60 X`1B`5B2;43Hqq`60 X`1B`5B2;45Hqq`60 X`1B`5B2;47Hqq`60 X`1B`5B2;49Hqq`60 X`1B`5B2;51Hqq`60 X`1B`5B2;53Hqq`60 X`1B`5B2;55Hqq`60 X`1B`5B2;57Hqq`60 X`1B`5B2;59Hk`1B`5B3;58H`60j X`1B`5B3;56H`60qq X`1B`5B3;54H`60qq X`1B`5B3;52H`60qq X`1B`5B3;50H`60qq X`1B`5B3;48H`60qq X`1B`5B3;46H`60qq X`1B`5B3;44H`60qq X`1B`5B3;42H`60qq X`1B`5B3;40H`60qq X`1B`5B3;40Hl`1B`5B4;40Hx`1B`5B5;40H`60 X`1B`5B5;40Hx`1B`5B6;40Hx`1B`5B7;40H`60 X`1B`5B7;40Hx`1B`5B8;40Hx`1B`5B9;40H`60 X`1B`5B9;40Hx`1B`5B10;40Hx`1B`5B11;40H`60 X`1B`5B11;40Hx`1B`5B12;40Hx`1B`5B13;40H`60 X`1B`5B13;40Hx`1B`5B14;40Hx`1B`5B15;40H`60 X`1B`5B15;40Hx`1B`5B16;40Hx`1B`5B17;40H`60 X`1B`5B17;40Hx`1B`5B18;40Hx`1B`5B19;40H`60 X`1B`5B19;40Hmq`60 X`1B`5B19;42Hqq`60 X`1B`5B19;44Hqq`60 X`1B`5B19;46Hqq`60 X`1B`5B19;48Hqq`60 X`1B`5B19;50Hqq`60 X`1B`5B19;52Hqq`60 X`1B`5B19;54Hqq`60 X`1B`5B19;56Hqq`60 X`1B`5B19;58Hqq`60 X`1B`5B19;60Hqq`60 X`1B`5B19;62Hqq`60 X`1B`5B19;64Hqq`60 X`1B`5B19;66Hqq`60 X`1B`5B19;68Hqq`60 X`1B`5B19;70Hqq`60 X`1B`5B19;72Hqq`60 X`1B`5B19;74Hqq`60 X`1B`5B17;76H`60`1B`5B18;76Hx`1B`5B19;76Hj X`1B`5B17;74H`60qk X`1B`5B17;72H`60qq X`1B`5B17;70H`60qq X`1B`5B17;68H`60qq X`1B`5B15;68H`60`1B`5B16;68Hx`1B`5B17;68Hm X`1B`5B15;66H`60qk X`1B`5B15;64H`60qq X`1B`5B15;62H`60qq X`1B`5B15;60H`60qq X`1B`5B15;58H`60qq X`1B`5B15;56H`60qq X`1B`5B15;54H`60qq X`1B`5B15;52H`60qq X`1B`5B15;50H`60qq X`1B`5B15;48H`60qq X`1B`5B15;46H`60qq X`1B`5B13;44H`60`1B`5B14;44Hx`1B`5B15;44Hmqq X`1B`5B11;44H`60`1B`5B12;44Hx`1B`5B13;44Hx X`1B`5B10;43H`60`1B`5B11;43Hmk X`1B`5B8;43H`60`1B`5B9;43Hx`1B`5B10;43Hx X`1B`5B6;43H`60`1B`5B7;43Hx`1B`5B8;43Hx X`1B`5B6;43Hlq`60 X`1B`5B6;45Hqq`60 X`1B`5B6;47Hqq`60 X`1B`5B6;49Hqq`60 X`1B`5B6;51Hqq`60 X`1B`5B6;53Hqq`60 X`1B`5B6;55Hqq`60 X`1B`5B6;57Hqq`60 X`1B`5B6;59Hqq`60 X`1B`5B6;61Hk`1B`5B7;61Hx`1B`5B8;61H`60 X`1B`5B8;61Hmqq`60 X`1B`5B8;64Hqq`60 X`1B`5B8;66Hqq`60 X`1B`5B8;68Hqq`60 X`1B`5B8;70Hqq`60 X`1B`5B8;72Hqq`60 X`1B`5B6;74H`60`1B`5B7;74Hx`1B`5B8;74Hj X`1B`5B4;74H`60`1B`5B5;74Hx`1B`5B6;74Hx X`1B`5B2;74H`60`1B`5B3;74Hx`1B`5B4;74Hx X`1B`5B2;72H`60qk X`1B`5B2;70H`60qq X`1B`5B2;68H`60qq X`1B`5B2;66H`60qq X`1B`5B2;64H`60qq X`1B`5B2;62H`60qq X`1B`5B2;60H`60qq X`1B`5B2;59H`60q X`1B`5B3;60H`1B`5B7m `1B`5B4;41H V `1B`5B5;41H `20 X`1B`5B5;67H `1B`5B6;41H `1B`5B6;62H `1B`5B7;41H `1B`5B7;6 V2H `1B`5B8;41H `20 X`1B`5B9;41H `1B`5B10;41H `1B`5B11;41H `1B`5B12;41H `1B`5B13;41H `1B`5 VB14;41H `1B`5B15;41H `1B`5B16;41H `20 X`1B`5B16;59H `1B`5B17;41H `1B`5B18;41H V `20 X`1B`5B0m X`1B`5B2;59Hw`60 X`1B`5B2;60Hq`60 X`1B`5B2;61Hq`60 X`1B`5B2;62Hq`60 X`1B`5B2;63Hq`60 X`1B`5B2;64Hq`60 X`1B`5B2;65Hq`60 X`1B`5B2;66Hq`60 X`1B`5B2;67Hq`60 X`1B`5B2;68Hq`60 X`1B`5B2;69Hqq`60 X`1B`5B2;71Hq`60 X`1B`5B2;72Hq`60 X`1B`5B2;73Hq`60 X`1B`5B2;74Hk`1B`5B3;74H`60 X`1B`5B3;74Hx`1B`5B4;74H`60 X`1B`5B4;74Hx`1B`5B5;74H`60 X`1B`5B5;74Hx`1B`5B6;74H`60 X`1B`5B6;74Hx`1B`5B7;74H`60 X`1B`5B7;74Hx`1B`5B8;74H`60 X`1B`5B8;74Hu`1B`5B9;74H`60 X`1B`5B9;74Hx`1B`5B10;74H`60 X`1B`5B10;74Hx`1B`5B11;74H`60 X`1B`5B11;74Hx`1B`5B12;74H`60 X`1B`5B12;74Hx`1B`5B13;74H`60 X`1B`5B13;74Hx`1B`5B14;74H`60 X`1B`5B14;74Hx`1B`5B15;74H`60 X`1B`5B15;74Hx`1B`5B16;74H`60 X`1B`5B16;74Hx`1B`5B17;74H`60 $ CALL UNPACK MQIXH.SCN;1 1797764174 $ create 'f' X`09.title`09MULTIM`09Multi user game control X;+ X;`09if $$MQIX is non zero X; X;`09if $$SOCCER is non zero X;- X X`09$$SOCCER= 0 X`09$$MQIX = 1 X X.if ndf $$MQIX X`09$$SOCCER= 1 X`09$$MQIX = 0 X.endc X X X`09$dibdef X`09$iodef X`09$qiodef X`09$secdef X`09$jpidef X X`09.default displacement word X Xesc`09`09= 27 X Xsnake`09`09= 8`09`09; number of snakes X X;`09meaning of event flags in cluster 2 X Xflag$v_master`09= 0`09`09; set if a master snake exists Xflag$v_read`09= 1`09`09; set if all snakes should read command Xflag$v_update`09= 2`09`09; set if all snakes should update screen Xflag$v_game`09= 3`09`09; set if game is in progress Xflag$v_endofgame= 4`09`09; set if we have reached the end of the game Xflag$v_synch`09= 5 Xflag$v_done`09= 8`09`09; set if operation (read,update) is complete X Xcheck_timer`09= 13`09`09; check timer id X Xflag$v_io`09= 9`09`09; event flag in cluster 0 (set on read completion) X X X`09.psect`09$rodata`09nowrt, noexe, shr, pic, long X Xttname_descr: X`09.ascid`09/TT/ X Xmbxcnv: X`09.ascid`09/_MBA!UW:/`09; convert mbx unit number to physical name X Xmbxbuf_descr: X`09.word`09mbxbuf_siz, 0 X`09.long`09mbxbuf X Xdibbuf_descr: X`09.word`09dib$k_length, 0 X`09.long`09dibbuf X X`09.align long Xsnake_desc_2: X.if ne $$SOCCER X`09.ascid`09/SOCCER_1/`09`09; name of snake event flags X.endc X.if ne $$MQIX X`09.ascid`09/MQIX_1/ X.endc X X`09.align`09long Xsnake_map_name: X.if ne $$SOCCER X`09.ascid`09/SOCCER_DATA/ X.endc X.if ne $$MQIX X`09.ascid`09/MQIX_DATA/ X.endc X Xtext = . X`09.ascii`09'<'`09`09; enter ANSI mode X`09.ascii`09'(B'`09`09; select ascii character set X`09.ascii`09'`5B2J'`09`09; erase entire screen X`09.ascii`09'`5B1;1H'`09`09; jump to top left corner X`09.ascii`09<10>`09`09`09; linefeed X.if ne $$SOCCER X`09.ascii`09'#3 SOCCER' ; double-height top half X`09.ascii`09<13><10> X`09.ascii`09'#4 SOCCER' ; double-height bottom half X.endc X.if ne $$MQIX X`09.ascii`09'#3 MULTI QIX' ; double-height top half X`09.ascii`09<13><10> X`09.ascii`09'#4 MULTI QIX' ; double-height bottom half X.endc X`09.ascii`09<13><10><10> X`09.ascii`09'#6 Thank you for playing' X`09.ascii`09<13><10><10> Xtext_len = . - text X`09.align`09long Xtext_end_game: X`09.long`092 X`09.long`09text X`09.address 10$ X10$:`09.long`09text_len X Xtext = . X`09.ascii`09<13><10><10> X`09.ascii`09'Game aborted because master ' X`09.ascii`09'player' X`09.ascii`09' quitted'<13><10><10> Xtext_len = . - text X`09.align`09long Xtext_abort: X`09.long`092 X`09.long`09text X`09.address 10$ X10$:`09.long`09text_len X Xtext = . X`09.ascii`09 'Y' <31+24> <31+1>`09; col 1, row 24 X`09.ascii`09 'G'`09`09`09; exit graphics X`09.ascii`09<7> ' Please wait for next game ...' X`09.ascii`09 'F'`09`09`09; enter graphics Xtext_len = . - text X`09.align`09long Xtext_wait: X`09.long`092 X`09.long`09text X`09.address 10$ X10$:`09.long`09text_len X X`09.align`09long Xusername_jpi: X`09.word`0912, jpi$_username X`09.address username_buf X`09.address username_siz X`09.long`090 X X`09.align`09long Xstart_wait: X`09.long`09-10000000*5, -1`09`09; wait 5 seconds Xsecond_1: X`09.long`09-10000000*1, -1`09`09; wait 1 second Xsecond_2: X`09.long`09-10000000*2, -1`09`09; wait 2 seconds X X.if ne $$SOCCER Xupdate_wait: X`09.long`09-100000*40, -1`09`09; wait 40/100 ths of a second X.endc X X.if ne $$MQIX Xupdate_wait: X`09.long`09-100000*30, -1`09`09; wait 30/100 ths of a second X.endc X Xcheck_wait: X`09.long`09-10000000*5, -1`09`09; wait 5 seconds for checking Xvalid_move: X`09.long`09`5EB101110100`09`09; valid moves are 2,4,6,8 and 5!! Xstart_direction: X.if ne $$MQIX X`09.byte`092, 8, 2, 8, 2, 8, 6, 4`09; initial move directions for snake X.endc X;.if ne $$TANK X;`09.byte`096, 4, 4, 6, 2, 8, 6, 4`09; for tank X;.endc X`09.align`09long Xadd_head_par: X`09.long`091`09`09`09; parameter list to Pascal routine X`09.address move`09`09`09; each players move Xupdate_par: X`09.long`092 X`09.address outbuf X`09.address screen_len Xupdate_par2:`09`09`09; if we have died, then there is no head X`09.long`092`09`09; to change to a diamond, so write screen X`09.address screen_buf`09; update directly from global memory. X`09.address screen_len X X`09.psect`09$rwbuf`09wrt, noexe, noshr, pic, page X Xmbxname_len = 16 Xmbxname:`09`09`09; room to hold the physical mbx name X`09.blkb`09mbxname_len Xmbxname_descr: X`09.word`09mbxname_len, 0 X`09.long`09mbxname Xmbxiosb: X`09.long`090,0 Xmbxbuf_siz = 32 Xmbxbuf: X`09.blkb`09mbxbuf_siz X Xdibbuf: X`09.blkb`09dib$k_length X X`09.align`09long Xttiosb: X`09.long`090,0 X Xsave_bit:`09.long X Xttmode:`09`09.blkq Xttmode_save:`09.blkq X Xttbuf_siz = 128 Xttbuf: X`09.blkb`09ttbuf_siz X`09.align`09page X X.if ne $$MQIX Xtrans_table: X`09.blkb`09256`09`09; converts your number to diamond X.endc X Xoutbuf_siz = 2048 Xoutbuf:: X`09.blkb`09outbuf_siz X Xmap_range: X`09.address share_data X`09.address share_data+<512*3> Xret_range: X`09.long`090, 0 X X X`09.psect`09$sharedata wrt, noexe, shr, pic, page Xshare_data: X Xgame_count: X`09.long`09`09`09; count of number of games played Xmaster_flag: X`09.long`09`09`09; = 1 if we are master snake Xabort: X`09.long`09`09`09; = 1 if all snakes should abort Xplayer_bits: X`09.long`09`09`09; bit set if that snake is playing Xplayers: X`09.long`09`09`09; bit set if that snake is reserved Xother_players: X`09.long`09`09`09; used by master snake to wait for other X`09`09`09`09; snakes to indicate operation completed Xmove_count: X`09.long`09`09`09; incremented every move. Used for detecting X`09`09`09`09; other snakes hanging the game Xgame_going: X`09.long`09`09`09; <> 0 if a game is going Xyou_just_died: X`09.long`09`09`09; bit I set if snake I just died Xseed: X`09.long`09`09`09; random number seed Xstart_position: X`09.blkl`09snake`09`09; position of starting (1-8) X; X;`09`095 X; 1`09+---------------+ 3 X;`09`7C`09`09`7C X;`09`7C`09`09`7C X; 7`09`7C`09`09`7C 8 X;`09`7C`09`09`7C X;`09`7C`09`09`7C X; 4`09+---------------+ 2 X;`09`096 X; Xscore: X`09.blkl`09snake`09`09; players' score Xn_games: X`09.blkl`09snake`09`09; # of games each player has played Xwins: X`09.blkl`09snake`09`09; # of wins for each player Xplayer_pos: X`09.blkl`09snake`09`09; starting position of each snake X`09.align`09quad Xmove: X.if ne $$SOCCER X`09.blkw`09snake`09`09; each players move (word) X.endc X.if ne $$MQIX X`09.blkb`09snake`09`09; each players move (word) X`09.blkb`09snake`09`09; we had some problems overwritting name X.endc Xname_size = 32 Xname: X`09.blkb`09name_size * snake ; each snakes name (32 chars long) X. = . + 512 - < . - share_data > X`09.align`09long Xscreen_len: X`09.long`09`09`09; # chars to be output Xscreen_buf: X`09.blkb`092048`09`09; buffer containing screen update X. = . + <512*6> - < . - share_data > X X X`09.psect`09$rwdata`09wrt, noexe, noshr, pic, long X Xttchan: X`09.word Xmbxchan: X`09.word Xdata_ready: X`09.word Xmaster: X`09.word`09`09`09; = 1 if we are master snake Xcontrol_c_flag: X`09.word`09`09`09; non zero if `5EC typed Xdead: X`09.word`09`09`09; bit I set if snake I just died X`09.align`09long Xcluster_2: X`09.long Xcluster_3: X`09.long Xplayer: X`09.long Xplayer_efn:`09`09`09; my player efn in cluster 2 X`09.long Xcurrent_players: X`09.long Xchars_left:`09`09`09; # of chars left in buffer X`09.long Xchar_pointer: X`09.long`09`09`09; address of next character Xlast_move_count: X`09.long Xusername_buf: X`09.ascii`09' '`09;`09.blkb`0912 Xusername_siz: X`09.long X Xoutbuf_qio: X`09$qio`09func=io$_writevblk!io$m_noformat,- X`09`09p1=outbuf Xoutput_qio: X`09$qio`09func=io$_writevblk!io$m_noformat X Xread_qio: X`09$qio`09func=io$_readvblk!io$m_noecho, - X`09`09iosb=ttiosb, efn=flag$v_io, - X`09`09p1=ttbuf, p2=1, -`09`09; read 1 char with wait X`09`09p4=term_blk`09`09`09; say no terminators X X;`09$qio`09func=io$_readvblk!io$m_timed!io$m_noecho, - ; !io$m_nofiltr,- X;`09`09iosb=ttiosb,- X;`09`09p1=ttbuf, p2=ttbuf_siz, p3=0`09; wait time = 0 X Xterm_blk: X`09.long`090, 0`09`09; no terminators X Xexit_block:`09`09`09; exit handler block X`09.long X`09.address snake_exit X`09.long`091`09`09; 1 argument X`09.address 10$ X10$:`09.long`09`09`09; exit reason X X X`09.psect`09$$code`09nowrt, exe, shr, pic, long X X`09.entry`09- XTTINIT, `5Em<> X;+ X; Create a mailbox. Assign a channel to terminal with an associated mailbox V. X;- X.if ne 0 X`09$crembx_s`09chan=mbxchan, promsk=#`5ExFF00 X`09bsbw`09`09error X`09$getchn_s`09chan=mbxchan, pribuf=dibbuf_descr X`09bsbw`09`09error X`09$fao_s`09`09ctrstr=mbxcnv, outbuf=mbxname_descr,- X`09`09`09outlen=mbxname_descr, p1=dibbuf+dib$w_unit X.endc X`09$assign_s`09devnam=ttname_descr, chan=ttchan X;`09`09`09mbxnam=mbxname_descr X`09bsbw`09error X`09movw`09ttchan, outbuf_qio+qio$_chan`09`09;store channel # X`09movw`09ttchan, output_qio+qio$_chan`09`09;store channel # X`09movw`09ttchan, read_qio+qio$_chan`09`09;store channel # X`09$qiow_s`09func=#io$_setmode!io$m_ctrlcast, chan=ttchan,- X`09`09p1=control_c X`09ret X X.if ne 0 X`09$qiow_s func=#io$_sensemode, chan=ttchan, - X`09`09iosb=ttiosb, p1=ttmode`09; get terminal characteristics X`09bsbw`09error X`09movzwl`09ttiosb, r0 X`09bsbw`09error X`09movq`09ttmode, ttmode_save X`09bbss`09#tt$v_escape, ttmode+4, 80$`09; want escape mode X80$:`09$qiow_s func=#io$_setmode, chan=ttchan, p1=ttmode X`09ret X.endc X X`09.entry`09- XTT1CHAR,`09`5Em<> X`09clrb`09ttbuf X`09$qiow_s`09func=#io$_readvblk!io$m_timed!io$m_noecho!io$m_nofiltr,- X`09`09chan=ttchan, iosb=ttiosb,- X`09`09p1=ttbuf, p2=#1, p3=#0`09; wait time = 0 X`09cvtbl`09ttbuf, r0 X`09cmpb`09r0, #13`09`09`09; is it ? X`09bneq`09100$ X`09clrb`09data_ready X100$:`09ret X XTTREAD:: X;`09blbs`09control_c_flag, 10$ X X`09tstl`09ttiosb`09`09`09; did we read any characters ? X`09`09`09`09`09; has read completed ? X`09beql`09100$`09`09`09; br if no X`09movzbl`09ttbuf, r2`09`09; get character before next read X`09$qio_g`09read_qio`09 `09; start read of another character X; X;`09$qiow_s`09func=#io$_writevblk,chan=ttchan,-`09; debug write X;`09`09p1=ttbuf, p2=ttiosb+2, p4=#`5Ex1000 X X`09movl`09r2, r0`09`09`09; copy character back into r0 X`09cmpb`09r0, #`5EA/a/`09`09; is it lowercase X`09bgeq`0950$`09`09`09; br if yes X80$: X`09cmpb`09r0, #`5EA/ / X`09beql`0990$ X`09cmpb`09r0, #`5EA/5/ X`09beql`0990$ X`09rsb X90$: X`09movb`09#`5EX80, r0 X`09rsb X50$: X`09bicb2`09#`5EX20, r0`09`09; make into uppercase +-+-+-+-+-+-+-+- END OF PART 4 +-+-+-+-+-+-+-+-