home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / vmsnet / mqix / part02 < prev    next >
Internet Message Format  |  1992-04-07  |  29KB

  1. Path: uunet!wupost!waikato.ac.nz!ccc_rex
  2. From: ccc_rex@waikato.ac.nz
  3. Newsgroups: vmsnet.sources.games
  4. Subject: MQIX 2/2 (mulit-user QIX)
  5. Message-ID: <1992Apr9.151554.7337@waikato.ac.nz>
  6. Date: 9 Apr 92 15:15:54 +1200
  7. Organization: University of Waikato, Hamilton, New Zealand
  8. Lines: 999
  9.  
  10. -+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+
  11. X`09.ascii`09<esc>'<'`09`09; enter ANSI mode
  12. X`09.ascii`09<esc>'(B'`09`09; select ascii character set
  13. X`09.ascii`09<esc>'`5B2J'`09`09; erase entire screen
  14. X`09.ascii`09<esc>'`5B1;1H'`09`09; jump to top left corner
  15. X`09.ascii`09<10>`09`09`09; linefeed
  16. X.if ne $$SOCCER
  17. X`09.ascii`09<esc>'#3                 SOCCER' ; double-height top half
  18. X`09.ascii`09<13><10>
  19. X`09.ascii`09<esc>'#4                 SOCCER' ; double-height bottom half
  20. X.endc
  21. X.if ne $$MQIX
  22. X`09.ascii`09<esc>'#3                 MULTI QIX' ; double-height top half
  23. X`09.ascii`09<13><10>
  24. X`09.ascii`09<esc>'#4                 MULTI QIX' ; double-height bottom half
  25. X.endc
  26. X`09.ascii`09<13><10><10>
  27. X`09.ascii`09<esc>'#6        Thank you for playing'
  28. X`09.ascii`09<13><10><10>
  29. Xtext_len = . - text
  30. X`09.align`09long
  31. Xtext_end_game:
  32. X`09.long`092
  33. X`09.long`09text
  34. X`09.address 10$
  35. X10$:`09.long`09text_len
  36. X
  37. Xtext = .
  38. X`09.ascii`09<13><10><10>
  39. X`09.ascii`09'Game aborted because master '
  40. X`09.ascii`09'player'
  41. X`09.ascii`09' quitted'<13><10><10>
  42. Xtext_len = . - text
  43. X`09.align`09long
  44. Xtext_abort:
  45. X`09.long`092
  46. X`09.long`09text
  47. X`09.address 10$
  48. X10$:`09.long`09text_len
  49. X
  50. Xtext = .
  51. X`09.ascii`09<esc> 'Y' <31+24> <31+1>`09; col 1, row 24
  52. X`09.ascii`09<esc> 'G'`09`09`09; exit graphics
  53. X`09.ascii`09<7> ' Please wait for next game ...'
  54. X`09.ascii`09<esc> 'F'`09`09`09; enter graphics
  55. Xtext_len = . - text
  56. X`09.align`09long
  57. Xtext_wait:
  58. X`09.long`092
  59. X`09.long`09text
  60. X`09.address 10$
  61. X10$:`09.long`09text_len
  62. X
  63. X`09.align`09long
  64. Xusername_jpi:
  65. X`09.word`0912, jpi$_username
  66. X`09.address username_buf
  67. X`09.address username_siz
  68. X`09.long`090
  69. X
  70. X`09.align`09long
  71. Xstart_wait:
  72. X`09.long`09-10000000*5, -1`09`09; wait 5 seconds
  73. Xsecond_1:
  74. X`09.long`09-10000000*1, -1`09`09; wait 1 second
  75. Xsecond_2:
  76. X`09.long`09-10000000*2, -1`09`09; wait 2 seconds
  77. X
  78. X.if ne $$SOCCER
  79. Xupdate_wait:
  80. X`09.long`09-100000*40, -1`09`09; wait 40/100 ths of a second
  81. X.endc
  82. X
  83. X.if ne $$MQIX
  84. Xupdate_wait:
  85. X`09.long`09-100000*30, -1`09`09; wait 30/100 ths of a second
  86. X.endc
  87. X
  88. Xcheck_wait:
  89. X`09.long`09-10000000*5, -1`09`09; wait 5 seconds for checking
  90. Xvalid_move:
  91. X`09.long`09`5EB101110100`09`09; valid moves are 2,4,6,8 and 5!!
  92. Xstart_direction:
  93. X.if ne $$MQIX
  94. X`09.byte`092, 8, 2, 8, 2, 8, 6, 4`09; initial move directions for snake
  95. X.endc
  96. X;.if ne $$TANK
  97. X;`09.byte`096, 4, 4, 6, 2, 8, 6, 4`09;  for tank
  98. X;.endc
  99. X`09.align`09long
  100. Xadd_head_par:
  101. X`09.long`091`09`09`09; parameter list to Pascal routine
  102. X`09.address move`09`09`09; each players move
  103. Xupdate_par:
  104. X`09.long`092
  105. X`09.address outbuf
  106. X`09.address screen_len
  107. Xupdate_par2:`09`09`09; if we have died, then there is no head
  108. X`09.long`092`09`09; to change to a diamond, so write screen
  109. X`09.address screen_buf`09; update directly from global memory.
  110. X`09.address screen_len
  111. X
  112. X`09.psect`09$rwbuf`09wrt, noexe, noshr, pic, page
  113. X
  114. Xmbxname_len = 16
  115. Xmbxname:`09`09`09; room to hold the physical mbx name
  116. X`09.blkb`09mbxname_len
  117. Xmbxname_descr:
  118. X`09.word`09mbxname_len, 0
  119. X`09.long`09mbxname
  120. Xmbxiosb:
  121. X`09.long`090,0
  122. Xmbxbuf_siz = 32
  123. Xmbxbuf:
  124. X`09.blkb`09mbxbuf_siz
  125. X
  126. Xdibbuf:
  127. X`09.blkb`09dib$k_length
  128. X
  129. X`09.align`09long
  130. Xttiosb:
  131. X`09.long`090,0
  132. X
  133. Xsave_bit:`09.long
  134. X
  135. Xttmode:`09`09.blkq
  136. Xttmode_save:`09.blkq
  137. X
  138. Xttbuf_siz = 128
  139. Xttbuf:
  140. X`09.blkb`09ttbuf_siz
  141. X`09.align`09page
  142. X
  143. X.if ne $$MQIX
  144. Xtrans_table:
  145. X`09.blkb`09256`09`09; converts your number to diamond
  146. X.endc
  147. X
  148. Xoutbuf_siz = 2048
  149. Xoutbuf::
  150. X`09.blkb`09outbuf_siz
  151. X
  152. Xmap_range:
  153. X`09.address share_data
  154. X`09.address share_data+<512*3>
  155. Xret_range:
  156. X`09.long`090, 0
  157. X
  158. X
  159. X`09.psect`09$sharedata wrt, noexe, shr, pic, page
  160. Xshare_data:
  161. X
  162. Xgame_count:
  163. X`09.long`09`09`09; count of number of games played
  164. Xmaster_flag:
  165. X`09.long`09`09`09; = 1 if we are master snake
  166. Xabort:
  167. X`09.long`09`09`09; = 1 if all snakes should abort
  168. Xplayer_bits:
  169. X`09.long`09`09`09; bit set if that snake is playing
  170. Xplayers:
  171. X`09.long`09`09`09; bit set if that snake is reserved
  172. Xother_players:
  173. X`09.long`09`09`09; used by master snake to wait for other
  174. X`09`09`09`09; snakes to indicate operation completed
  175. Xmove_count:
  176. X`09.long`09`09`09; incremented every move.  Used for detecting
  177. X`09`09`09`09; other snakes hanging the game
  178. Xgame_going:
  179. X`09.long`09`09`09; <> 0 if a game is going
  180. Xyou_just_died:
  181. X`09.long`09`09`09; bit I set if snake I just died
  182. Xseed:
  183. X`09.long`09`09`09; random number seed
  184. Xstart_position:
  185. X`09.blkl`09snake`09`09; position of starting (1-8)
  186. X;
  187. X;`09`095
  188. X;    1`09+---------------+  3
  189. X;`09`7C`09`09`7C
  190. X;`09`7C`09`09`7C
  191. X;    7`09`7C`09`09`7C  8
  192. X;`09`7C`09`09`7C
  193. X;`09`7C`09`09`7C
  194. X;    4`09+---------------+  2
  195. X;`09`096
  196. X;
  197. Xscore:
  198. X`09.blkl`09snake`09`09; players' score
  199. Xn_games:
  200. X`09.blkl`09snake`09`09; # of games each player has played
  201. Xwins:
  202. X`09.blkl`09snake`09`09; # of wins for each player
  203. Xplayer_pos:
  204. X`09.blkl`09snake`09`09; starting position of each snake
  205. X`09.align`09quad
  206. Xmove:
  207. X.if ne $$SOCCER
  208. X`09.blkw`09snake`09`09; each players move (word)
  209. X.endc
  210. X.if ne $$MQIX
  211. X`09.blkb`09snake`09`09; each players move (word)
  212. X`09.blkb`09snake`09`09; we had some problems overwritting name
  213. X.endc
  214. Xname_size = 32
  215. Xname:
  216. X`09.blkb`09name_size * snake ; each snakes name (32 chars long)
  217. X. = . + 512 - < . - share_data >
  218. X`09.align`09long
  219. Xscreen_len:
  220. X`09.long`09`09`09; # chars to be output
  221. Xscreen_buf:
  222. X`09.blkb`092048`09`09; buffer containing screen update
  223. X. = . + <512*6> - < . - share_data >
  224. X
  225. X
  226. X`09.psect`09$rwdata`09wrt, noexe, noshr, pic, long
  227. X
  228. Xttchan:
  229. X`09.word
  230. Xmbxchan:
  231. X`09.word
  232. Xdata_ready:
  233. X`09.word
  234. Xmaster:
  235. X`09.word`09`09`09; = 1 if we are master snake
  236. Xcontrol_c_flag:
  237. X`09.word`09`09`09; non zero if `5EC typed
  238. Xdead:
  239. X`09.word`09`09`09; bit I set if snake I just died
  240. X`09.align`09long
  241. Xcluster_2:
  242. X`09.long
  243. Xcluster_3:
  244. X`09.long
  245. Xplayer:
  246. X`09.long
  247. Xplayer_efn:`09`09`09; my player efn in cluster 2
  248. X`09.long
  249. Xcurrent_players:
  250. X`09.long
  251. Xchars_left:`09`09`09; # of chars left in buffer
  252. X`09.long
  253. Xchar_pointer:
  254. X`09.long`09`09`09; address of next character
  255. Xlast_move_count:
  256. X`09.long
  257. Xusername_buf:
  258. X`09.ascii`09'            '`09;`09.blkb`0912
  259. Xusername_siz:
  260. X`09.long
  261. X
  262. Xoutbuf_qio:
  263. X`09$qio`09func=io$_writevblk!io$m_noformat,-
  264. X`09`09p1=outbuf
  265. Xoutput_qio:
  266. X`09$qio`09func=io$_writevblk!io$m_noformat
  267. X
  268. Xread_qio:
  269. X`09$qio`09func=io$_readvblk!io$m_noecho, -
  270. X`09`09iosb=ttiosb, efn=flag$v_io, -
  271. X`09`09p1=ttbuf, p2=1, -`09`09; read 1 char with wait
  272. X`09`09p4=term_blk`09`09`09; say no terminators
  273. X
  274. X;`09$qio`09func=io$_readvblk!io$m_timed!io$m_noecho, - ; !io$m_nofiltr,-
  275. X;`09`09iosb=ttiosb,-
  276. X;`09`09p1=ttbuf, p2=ttbuf_siz, p3=0`09; wait time = 0
  277. X
  278. Xterm_blk:
  279. X`09.long`090, 0`09`09; no terminators
  280. X
  281. Xexit_block:`09`09`09; exit handler block
  282. X`09.long
  283. X`09.address snake_exit
  284. X`09.long`091`09`09; 1 argument
  285. X`09.address 10$
  286. X10$:`09.long`09`09`09; exit reason
  287. X
  288. X
  289. X`09.psect`09$$code`09nowrt, exe, shr, pic, long
  290. X
  291. X`09.entry`09-
  292. XTTINIT, `5Em<>
  293. X;+
  294. X; Create a mailbox.  Assign a channel to terminal with an associated mailbox
  295. V.
  296. X;-
  297. X.if ne 0
  298. X`09$crembx_s`09chan=mbxchan, promsk=#`5ExFF00
  299. X`09bsbw`09`09error
  300. X`09$getchn_s`09chan=mbxchan, pribuf=dibbuf_descr
  301. X`09bsbw`09`09error
  302. X`09$fao_s`09`09ctrstr=mbxcnv, outbuf=mbxname_descr,-
  303. X`09`09`09outlen=mbxname_descr, p1=dibbuf+dib$w_unit
  304. X.endc
  305. X`09$assign_s`09devnam=ttname_descr, chan=ttchan
  306. X;`09`09`09mbxnam=mbxname_descr
  307. X`09bsbw`09error
  308. X`09movw`09ttchan, outbuf_qio+qio$_chan`09`09;store channel #
  309. X`09movw`09ttchan, output_qio+qio$_chan`09`09;store channel #
  310. X`09movw`09ttchan, read_qio+qio$_chan`09`09;store channel #
  311. X`09$qiow_s`09func=#io$_setmode!io$m_ctrlcast, chan=ttchan,-
  312. X`09`09p1=control_c
  313. X`09ret
  314. X
  315. X.if ne 0
  316. X`09$qiow_s func=#io$_sensemode, chan=ttchan, -
  317. X`09`09iosb=ttiosb, p1=ttmode`09; get terminal characteristics
  318. X`09bsbw`09error
  319. X`09movzwl`09ttiosb, r0
  320. X`09bsbw`09error
  321. X`09movq`09ttmode, ttmode_save
  322. X`09bbss`09#tt$v_escape, ttmode+4, 80$`09; want escape mode
  323. X80$:`09$qiow_s func=#io$_setmode, chan=ttchan, p1=ttmode
  324. X`09ret
  325. X.endc
  326. X
  327. X`09.entry`09-
  328. XTT1CHAR,`09`5Em<>
  329. X`09clrb`09ttbuf
  330. X`09$qiow_s`09func=#io$_readvblk!io$m_timed!io$m_noecho!io$m_nofiltr,-
  331. X`09`09chan=ttchan, iosb=ttiosb,-
  332. X`09`09p1=ttbuf, p2=#1, p3=#0`09; wait time = 0
  333. X`09cvtbl`09ttbuf, r0
  334. X`09cmpb`09r0, #13`09`09`09; is it <CR> ?
  335. X`09bneq`09100$
  336. X`09clrb`09data_ready
  337. X100$:`09ret
  338. X
  339. XTTREAD::
  340. X;`09blbs`09control_c_flag, 10$
  341. X
  342. X`09tstl`09ttiosb`09`09`09; did we read any characters ?
  343. X`09`09`09`09`09; has read completed ?
  344. X`09beql`09100$`09`09`09; br if no
  345. X`09movzbl`09ttbuf, r2`09`09; get character before next read
  346. X`09$qio_g`09read_qio`09 `09; start read of another character
  347. X;
  348. X;`09$qiow_s`09func=#io$_writevblk,chan=ttchan,-`09; debug write
  349. X;`09`09p1=ttbuf, p2=ttiosb+2, p4=#`5Ex1000
  350. X
  351. X`09movl`09r2, r0`09`09`09; copy character back into r0
  352. X`09cmpb`09r0, #`5EA/a/`09`09; is it lowercase
  353. X`09bgeq`0950$`09`09`09; br if yes
  354. X80$:
  355. X`09cmpb`09r0, #`5EA/ /
  356. X`09beql`0990$
  357. X`09cmpb`09r0, #`5EA/5/
  358. X`09beql`0990$
  359. X`09rsb
  360. X90$:
  361. X`09movb`09#`5EX80, r0
  362. X`09rsb
  363. X50$:
  364. X`09bicb2`09#`5EX20, r0`09`09; make into uppercase
  365. X`09brb`0980$`09`09`09; go check for "5", " "
  366. X100$:
  367. X`09clrl`09r0
  368. X`09rsb
  369. X
  370. X
  371. X`09.entry`09-
  372. XMBXREAD,`09`5Em<>
  373. X;+
  374. X; This is an AST routine which executes when the mailbox record has been rea
  375. Vd.
  376. X; The record itself is a status message which is assumed to say that
  377. X; unsolicited data is available at the terminal
  378. X;-
  379. X`09blbc`09mbxiosb, 100$`09`09; on error, dont re-que read
  380. X;`09we could have SS$_CANCEL or SS$_ABORT from the $CANCEL in the
  381. X;`09exit handler
  382. X`09movb`09#1, data_ready`09`09; indicate data is there
  383. X`09bsbw`09queue_mbxread`09`09; queue another read request
  384. X100$:
  385. X`09ret
  386. X
  387. XQUEUE_MBXREAD:
  388. X`09$qio_s`09efn=#2, func=#io$_readvblk, chan=mbxchan, iosb=mbxiosb,-
  389. X`09`09astadr=mbxread,-
  390. X`09`09p1=mbxbuf, p2=#mbxbuf_siz
  391. X`09blbc`09r0, 100$
  392. X`09rsb
  393. X100$:
  394. X`09bsbw`09error
  395. X`09rsb
  396. X
  397. XTTWRITE::
  398. X;+
  399. X;`09bsbw`09ttwrite
  400. X;`09r3 contains length of buffer to write
  401. X;`09the buffer is outbuf
  402. X;-
  403. X`09movl`09r3, outbuf_qio+qio$_p2`09`09; store length of buffer
  404. X`09$qiow_g`09outbuf_qio
  405. X`09blbc`09r0, 100$
  406. X`09rsb
  407. X100$:
  408. X`09bsbw`09error
  409. X`09rsb
  410. X
  411. X
  412. X`09.entry`09-
  413. Xsnake_screen, `5Em<r2,r3,r4,r5>
  414. X;+
  415. X;`09CALL SNAKE_SCREEN( array, length )
  416. X;`09BYTE ARRAY( LENGTH )
  417. X;`09copies string to update screen into shared memory
  418. X;-
  419. X`09movl`09@8(ap), r0`09`09; get length
  420. X`09movl`09r0, screen_len`09`09; store length
  421. X`09movc3`09r0, @4(ap), screen_buf`09; copy text
  422. X`09ret
  423. X
  424. X`09.entry`09-
  425. Xsnake_write, `5Em<r2,r3>
  426. X;+
  427. X;`09CALL SNAKE_WRITE( array, length )
  428. X;`09BYTE ARRAY( LENGTH )
  429. X;`09writes buffer to terminal in noformat mode
  430. X;-
  431. X`09movl`094(ap), r3`09`09`09; get address
  432. X`09movl`09@8(ap), r2`09`09`09; get length
  433. X50$:
  434. X`09movl`09r2, r0`09`09`09`09; copy length
  435. X`09cmpw`09r0, #512`09`09`09; is it too big
  436. X`09bleq`0980$`09`09`09`09; br if not
  437. X`09movl`09#512, r0
  438. X80$:
  439. X`09movl`09r3, output_qio+qio$_p1`09`09; store address of buffer
  440. X`09movl`09r0, output_qio+qio$_p2`09`09; store length of buffer
  441. X`09addl2`09r0, r3`09`09`09`09; update address
  442. X`09subl2`09r0, r2`09`09`09`09; update length
  443. X`09$qiow_g`09output_qio
  444. X`09blbc`09r0, 100$
  445. X`09tstl`09r2`09`09`09`09; anything else to write ?
  446. X`09bgtr`0950$`09`09`09`09; br if yes
  447. X`09ret
  448. X100$:
  449. X`09bsbw`09error
  450. X`09ret
  451. X
  452. X`09.entry`09-
  453. Xsnake_dead, `5Em<>
  454. X;+
  455. X;`09CALL SNAKE_DEAD( player # )
  456. X;-
  457. X`09subl3`09#1, @4(ap), r0`09`09`09; get # of snake who died
  458. X`09bbss`09r0, you_just_died, 100$`09`09; set flag saying he died
  459. X100$:`09ret
  460. X
  461. X
  462. X
  463. XCANCELTYPEAHEAD::
  464. X`09tstw`09ttchan`09`09; check channel is open
  465. X`09beql`09100$
  466. X`09$qiow_s`09func=#io$_readvblk!io$m_purge!io$m_timed,-
  467. X`09`09chan=ttchan, -
  468. X`09`09p1=ttbuf, p2=1, p3=0`09; do read with 0 length buffer (p2)
  469. X100$:`09ret`09`09`09`09; return with status in r0
  470. X
  471. XERROR:
  472. X`09blbs`09r0, 100$
  473. X`09pushl`09r0
  474. X`09calls`09#1, G`5Elib$signal
  475. X100$:
  476. X`09rsb
  477. X
  478. X`09.entry`09-
  479. Xcontrol_c, `5Em<>
  480. X`09movb`09#1, control_c_flag
  481. X`09ret
  482. X
  483. X
  484. X`09.page
  485. X`09.entry`09-
  486. XSNAKE_INIT, `5Em<r2,r3,r4,r5>`09`09`09`09; snake game
  487. X;+
  488. X;`09I = SNAKE_INIT( player # , game )
  489. X;`09returns I = 1 if you are master snake.
  490. X;`09returns your player # as a integer
  491. X;`09returns game = 1 if there is a game in progress
  492. X;-
  493. X
  494. X`09calls`09#0, ttinit`09`09`09; open terminal
  495. X;
  496. X`09$ascefc_s efn=#64, name=snake_desc_2`09; associate event flag cluster
  497. X`09bsbw`09error
  498. X;
  499. X;`09$open`09fab=snake_fab`09`09`09; open section file
  500. X;`09bsbw`09error
  501. X
  502. X`09$deltva_s inadr=map_range`09`09; delete memory were global
  503. X`09bsbw`09error`09`09`09`09;  memory will be mapped
  504. X`09$crmpsc_s inadr=map_range, flags=#sec$m_gbl!sec$m_wrt!sec$m_pagfil,-
  505. X`09`09gsdnam=snake_map_name, - ; chan=snake_fab+fab$l_stv,`20
  506. X`09`09pagcnt=#4
  507. X`09bsbw`09error
  508. X`09cmpl`09r0, #ss$_created`09`09; are we first to map section
  509. X`09bneq`0950$`09`09`09`09; no
  510. X`09movab`09share_data+4, r3
  511. X`09movc5`09#0, (r3), #0, #512-4, (r3)`09; clear everything except count
  512. X`09$clref_s efn=#flag$v_game+64`09`09; say not game
  513. X`09movl`09#39814571, seed`09`09`09; init random n.g. seed
  514. X`09movl`09#snake, r0`09`09`09; 8 snakes
  515. X20$:
  516. X`09movl`09r0, start_position-4`5Br0`5D`09; init start position
  517. X`09sobgtr`09r0, 20$
  518. X50$:
  519. X`09blbc`09abort, 60$`09`09`09; if not abort --> 60$
  520. X`09callg`09text_abort, snake_write
  521. X`09$exit_s #1
  522. X60$:
  523. X;`09$qio_g`09read_qio`09 `09; start read of another character
  524. X;`09the above line shifted into SNAKE_START
  525. X
  526. X;`09bsbw`09queue_mbxread`09`09`09; start terminal read
  527. X;
  528. X`09bbss`09#0, master_flag, 100$`09`09; see if a master snake exists
  529. X`09`09`09; this should be interlocked on a multi-processor
  530. X;+
  531. X; We will have to be the master snake
  532. X;-
  533. X`09movb`09#1, master`09`09`09; indicate we are master snake
  534. X`09$setef_s efn=#7`09`09`09`09; set for first call
  535. X100$:
  536. X;
  537. X`09clrl`09r1`09`09`09`09; start at player 0 (bit0=1)
  538. X150$:
  539. X`09bbcs`09r1, players, 200$`09`09; see if this snake is free
  540. X`09incl`09r1`09`09`09`09; go to next snake
  541. X`09cmpl`09r1, #snake`09`09`09; have we checked all snakes?
  542. X`09blss`09150$`09`09`09`09; no --> 150$
  543. X`09mnegl`09#1, r1`09`09`09`09; player = -1 means none
  544. X200$:
  545. X`09movl`09r1, player`09`09`09; store my snake number (0-7)
  546. X`09movl`09player, @4(ap)`09`09`09;  and return it
  547. X500$:
  548. X`09movzbl`09game_going, @8(ap)`09`09; return game going flag
  549. X
  550. X`09movl`09r1, r3
  551. X`09blss`09600$`09`09`09`09; no snakes available
  552. X`09$getjpi_s itmlst=username_jpi`09`09; get our username
  553. X`09mull2`09#name_size, r3`09`09`09; get offset to start of name
  554. X`09movc5`09username_siz, username_buf, #`5Ea/ /, #name_size, name(r3)
  555. X`09`09`09`09`09`09; copy username
  556. X600$:
  557. X`09$dclexh_s desblk=exit_block`09`09; declare exit handler
  558. X`09bsbw`09error
  559. X;+
  560. X;`09init translation table for converting all ascii chars for your
  561. X;`09snake to a diamond
  562. X;-
  563. X`09movab`09trans_table, r3
  564. X`09clrl`09r4
  565. X700$:
  566. X`09movb`09r4, (r3)+`09`09`09; store byte
  567. X`09aoblss`09#256, r4, 700$
  568. X`09movl`09player, r0`09`09`09; get our player #
  569. X`09blss`09800$`09`09`09`09; br if no players available
  570. X`09movb`09#`5EA/`60/, trans_table+`5EA/1/+`5EX80(r0)`09; convert us to diamo
  571. Vnd
  572. X`09movab`09trans_table+128, r3
  573. X`09movb`09#`5EA/1/, `5EA/a/(r3)
  574. X`09movb`09#`5EA/2/, `5EA/b/(r3)
  575. X`09movb`09#`5EA/3/, `5EA/c/(r3)
  576. X`09movb`09#`5EA/4/, `5EA/d/(r3)
  577. X`09movb`09#`5EA/5/, `5EA/e/(r3)
  578. X`09movb`09#`5EA/6/, `5EA/f/(r3)
  579. X`09movb`09#`5EA/7/, `5EA/g/(r3)
  580. X`09movb`09#`5EA/8/, `5EA/h/(r3)
  581. X`09movb`09#`5EA/ /, trans_table+`5EA/a/+`5EX80(r0)`09; convert us to space
  582. X800$:
  583. X
  584. X`09movzbl`09master, r0`09`09`09; return master snake status
  585. X`09ret
  586. X
  587. Xmaster_wait:
  588. X;+
  589. X; master snake has to wait some time for other snakes to start playing
  590. X; called from SNAKE_START
  591. X;-
  592. X`09incl`09game_count`09`09`09; say another game being played
  593. X220$:`09clrb`09player_bits`09`09`09; no other players
  594. X`09bbss`09player, player_bits, 400$`09; say I am playing
  595. X400$:
  596. X`09$clref_s efn=#flag$v_synch+64
  597. X
  598. X.if ne $$MQIX
  599. X;+
  600. X;`09randomise starting positions
  601. X;-
  602. X`09moval`09start_position, r4`09`09; starting position numbers
  603. X`09movl`09#1, r2`09`09`09`09; snake index (start at 1)
  604. X500$:
  605. X`09pushal`09seed`09`09`09`09; random number seed
  606. X`09calls`09#1, G`5Emth$random`09`09; random real in r0
  607. X`09addl3`09#1, r2, r3`09`09`09; snake + 1
  608. X`09cvtlf`09r3, r3`09`09`09`09; as real
  609. X`09mulf2`09r3, r0`09`09`09`09; get snake to change pos with
  610. X`09cvtfl`09r0, r0
  611. X`09movl`09(r4)`5Br0`5D, r1`09`09`09; swap these positions
  612. X`09movl`09(r4)`5Br2`5D, (r4)`5Br0`5D
  613. X`09movl`09r1, (r4)`5Br2`5D
  614. X`09aobleq`09#7, r2, 500$
  615. X;
  616. X`09moval`09start_position, r4
  617. X`09movab`09move, r3
  618. X`09movl`09#snake, r2`09`09`09; number of snakes
  619. X600$:
  620. X`09movl`09(r4)+, r0`09`09`09; get start position (1-8)
  621. X`09movb`09start_direction-1`5Br0`5D, (r3)+`09; copy start direction
  622. X`09sobgtr`09r2, 600$
  623. X.endc
  624. X
  625. X.if ne $$SOCCER
  626. X`09movab`09move, r3
  627. X`09clrq`09(r3)+`09`09`09`09; no move to start with
  628. X`09clrq`09(r3)+
  629. X.endc
  630. X;
  631. X`09$setimr_s efn=#flag$v_game+64,-`20
  632. X`09`09`09daytim=second_1`09`09; wait a time for other snakes
  633. X`09$waitfr_s efn=#flag$v_game+64`09`09; say that a game is going
  634. X`09movb`09#1, game_going`09`09`09; say game going
  635. X`09$clref_s efn=#flag$v_endofgame+64`09; say not end of game
  636. X`09$setef_s efn=#7`09`09`09`09; sets event flag for first
  637. X`09`09`09`09`09`09;  call to snake_wait
  638. X`09$setimr_s efn=#flag$v_synch+64,-`09`09
  639. X`09`09`09 daytim=start_wait
  640. X`09$waitfr_s efn=#flag$v_synch+64
  641. X`09; this allows other snakes to set bit saying they are playing
  642. X
  643. X`09rsb
  644. X
  645. X`09.entry`09-
  646. XSNAKE_START, `5Em<r2,r3,r4>
  647. X;+
  648. X;`09CALL SNAKE_START( PLAYERS , START_POSITION )
  649. X;`09INTEGER PLAYERS, START_POSITION(8)
  650. X;`09waits 5? seconds for other players to run game
  651. X;`09The master snake is assumed to have waited some additional time
  652. X;`09Returns PLAYERS, bit I <> 0 if that player is active
  653. X;`09START_POSITION(I) is the starting location of snake I, (1-8)
  654. X;-
  655. X`09$cancel_s chan=ttchan`09`09`09; cancel the outstanding read
  656. X
  657. X`09blbc`09master, 500$`09`09`09; are we master snake ?
  658. X`09bsbw`09master_wait
  659. X`09brb`09800$
  660. X200$:
  661. X`09$exit_s #1`09`09`09`09; game aborted so stop
  662. X500$:
  663. X`09$waitfr_s efn=#flag$v_game+64`09`09; wait until a game starts
  664. X`09blbs`09abort, 200$`09`09`09; if game stopped --> 200$
  665. X`09bbss`09player, player_bits, 600$`09; say I am playing
  666. X600$:`09$waitfr_s efn=#flag$v_synch+64`09`09; synchronise
  667. X`09blbs`09abort, 200$`09`09`09; if game stopped --> 200$
  668. X800$:
  669. X`09movzbl`09player_bits, r4`09`09`09; get player bits
  670. X`09ashl`09#flag$v_done, r4, other_players ; used by master snake
  671. X`09movl`09r4, @4(ap)`09`09`09; store player bits
  672. X`09clrl`09chars_left`09`09`09; cancel type ahead
  673. X`09clrb`09data_ready`09`09`09; make us do a read
  674. X;;`09calls`09#0, canceltypeahead
  675. X`09$qio_g`09read_qio`09 `09; start read of another character
  676. X
  677. X.if ne $$MQIX
  678. X;`09return starting positions
  679. X`09moval`09start_position, r0`09`09; address of new positions
  680. X`09movl`098(ap), r2`09`09`09; address of where to put them
  681. X`09movl`09#snake, r1`09`09`09; number of snakes
  682. X910$:
  683. X`09movl`09(r0)+, (r2)+
  684. X`09sobgtr`09r1, 910$
  685. X.endc
  686. X
  687. X;`09init starting directions
  688. X`09movaw`09move, r2`09`09`09; address of where to put them
  689. X`09movl`09#snake, r1`09`09`09; number of snakes
  690. X900$:
  691. X.if ne $$MQIX
  692. X`09movb`09#`5EA/9/, (r2)+`09`09`09; 9 = invalid move
  693. X.endc
  694. X
  695. X.if ne $$SOCCER
  696. X`09movw`09#5, (r2)+`09`09`09; 5 = stop
  697. X.endc
  698. X
  699. X`09sobgtr`09r1, 900$
  700. X
  701. X`09mnegl`09#1, last_move_count`09`09; invalidate last counter
  702. X
  703. X`09ret
  704. X
  705. X
  706. XSNAKE_WAIT::
  707. X;+
  708. X;`09BSBW SNAKE_WAIT
  709. X; `09wait until we are told to read players command(s)
  710. X;-
  711. X`09blbs`09master, 200$`09`09`09; are we master snake ?
  712. X`09$waitfr_s efn=#flag$v_read+64`09`09; if not then wait for flag
  713. X`09rsb
  714. X200$:`09; master snake waits and then sets flag for all players
  715. X`09$cantim_s reqidt=#check_timer`09`09; cancel checking timer
  716. X`09$waitfr_s efn=#7`09`09`09; wait for previous timer
  717. X`09$setimr_s efn=#8, daytim=check_wait, -
  718. X`09`09astadr=check_ast, reqidt=#check_timer ; set off checking timer
  719. X`09$setimr_s efn=#7, daytim=update_wait
  720. X`09$clref_s efn=#flag$v_update+64`09`09; clear next flag to wait on
  721. X`09movl`09#flag$v_done+64, r2`09`09; clear each players done flag
  722. X`09$clref_s efn=r2`09`09`09`09; player 0
  723. X`09incl`09r2
  724. X`09$clref_s efn=r2
  725. X`09incl`09r2
  726. X`09$clref_s efn=r2
  727. X`09incl`09r2
  728. X`09$clref_s efn=r2
  729. X`09incl`09r2
  730. X`09$clref_s efn=r2
  731. X`09incl`09r2
  732. X`09$clref_s efn=r2
  733. X`09incl`09r2
  734. X`09$clref_s efn=r2
  735. X`09incl`09r2
  736. X`09$clref_s efn=r2`09`09`09`09; player 7
  737. X;
  738. X`09$clref_s efn=#flag$v_synch+64
  739. X`09$setef_s efn=#flag$v_read+64`09`09; tell everybody to do read
  740. X`09rsb
  741. X
  742. X
  743. XSNAKE_READ::
  744. X;+
  745. X;`09BSBW SNAKE_READ
  746. X;`09read all users moves and store them into the byte array MOVES(*)
  747. X;-
  748. X`09bsbw`09ttread`09`09`09`09; read users commands, if any
  749. X`09movl`09player, r1`09`09`09; get our player number
  750. X
  751. X.if ne $$SOCCER
  752. X`09tstw`09r0`09`09`09`09; anything typed ?
  753. X`09beql`0910$`09`09`09`09; br if no
  754. X`09movw`09r0, move`5Br1`5D`09`09`09; store our move
  755. X.endc
  756. X
  757. X.if ne $$MQIX
  758. X`09tstb`09r0`09`09`09`09; anything typed ?
  759. X`09beql`0910$
  760. X`09blss`095$
  761. X`09movb`09r0, move`5Br1`5D`09`09`09; store our move
  762. X`09brb`0910$
  763. X5$:
  764. X`09bisb2`09r0, move`5Br1`5D`09`09`09; r0 = `5EX80 (set parity bit)
  765. X.endc
  766. X
  767. X10$:
  768. X`09addl3`09#flag$v_done+64, player, r1
  769. X`09$setef_s efn=r1`09`09`09`09; say that read is complete
  770. X900$:
  771. X`09blbc`09master, 1000$
  772. X`09$wfland_s efn=#64, mask=other_players`09; wait for all players to read
  773. X`09incl`09move_count`09`09`09; onto next move
  774. X`09$clref_s efn=#flag$v_read+64`09`09; clear next flag to wait on
  775. X`09$setef_s efn=#flag$v_update+64`09`09; tell everybody to update
  776. X`09brb`091050$
  777. X1000$:
  778. X`09$waitfr_s efn=#flag$v_update+64`09`09; wait for all reads to complete
  779. X`09blbs`09master_flag, 1050$`09`09; check for master snake OK
  780. X`09movl`09player, r1`09`09`09; get our player number
  781. X`09clrb`09move(r1)`09`09`09; store our move ( quit )
  782. X1050$:
  783. X`09rsb
  784. X
  785. X
  786. X`09.entry`09-
  787. XSNAKE_PLAY, `5Em<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
  788. X;+
  789. X;`09called once at the start of the game.
  790. X;`09I then call the Pascal routine ADD_HEAD to perform the moves.
  791. X;-
  792. X`09blbs`09master, 1000$`09`09; master snake does all the work
  793. X100$:
  794. X`09bsbw`09snake_wait
  795. X`09bsbw`09snake_read
  796. X`09$waitfr_s efn=#flag$v_synch+64`09; wait until screen update there
  797. X`09bsbw`09snake_update`09`09; update screen
  798. X`09brb`09100$
  799. X
  800. X900$:
  801. X`09clrb`09game_going`09`09; tell other snakes games finished
  802. X`09$setef_s efn=#flag$v_synch+64`09; wake other snakes up
  803. X`09bsbb`09snake_update`09`09; write out last move
  804. X`09ret
  805. X
  806. X1000$:`09; master snake moves every snake
  807. X`09bsbw`09snake_wait
  808. X`09bsbw`09snake_read
  809. X`09callg`09add_head_par, L`5Eadd_head ; call Pascal routine
  810. X`09`09`09`09`09; returns 1 if game still going
  811. X`09blbc`09r0, 900$`09`09; game has ended --> 900$
  812. X`09$setef_s efn=#flag$v_synch+64`09; wake other snakes up
  813. X`09bsbb`09snake_update`09`09; update our screen
  814. X`09brb`091000$
  815. X
  816. X
  817. X`09.enable local_block
  818. X500$:
  819. X`09$exit_s #1`09`09`09; game aborted, so exit image
  820. X
  821. Xsnake_update::
  822. X`09blbs`09abort, 500$
  823. X`09blbs`09dead, 80$`09`09; if we are dead, then no head
  824. X
  825. X.if ne $$SOCCER
  826. X`09movc3`09screen_len, screen_buf, outbuf`09; copy update string
  827. X.endc
  828. X
  829. X.if ne $$MQIX
  830. X;`09replace your snake head with a diamond symbol
  831. X`09movl`09screen_len, r0`09`09; get length of output string
  832. X`09movtc`09r0, screen_buf, #`5EA/ /, trans_table, r0, outbuf
  833. X.endc
  834. X
  835. X;`09movl`09player, r2`09`09; get my snake number
  836. X;`09addw2`09#`5EA/1/+`5EX80, r2`09`09; get number with parity bit set
  837. X;`09locc`09r2, screen_len, outbuf
  838. X;`09beql`0950$`09`09`09; could not find it !!!
  839. X;`09movb`09#`5EA/`60/, (r1)`09`09; change to diamond
  840. X50$:
  841. X`09callg`09update_par, snake_write
  842. X`09blbc`09game_going, 100$`09; bit clear if game has finished
  843. X`09bbsc`09player, you_just_died, 60$ ; see if we just died
  844. X`09rsb
  845. X60$:`09movb`09#1, dead`09`09; say we are dead
  846. X`09callg`09text_wait, snake_write`09; tell them to wait for next game_exit,
  847. X`09rsb
  848. X80$:`09; dont copy buffer if no head to update because we are dead
  849. X`09callg`09update_par2, snake_write
  850. X`09blbc`09game_going, 100$
  851. X`09rsb
  852. X100$:
  853. X`09$setimr_s efn=#6, daytim=second_1`09; so we can see last move
  854. X`09$waitfr_s efn=#6
  855. X`09ret`09`09`09`09; return from SNAKE_PLAY if end game
  856. X`09.disable local_block
  857. X
  858. X
  859. X`09.entry`09-
  860. XCHECK_AST, `5Em<r2,r3,r4>
  861. X;+
  862. X;`09called when check_timer expires (2 seconds)
  863. X;`09we should only get here if one of the other snakes has aborted
  864. X;`09or `5ES ed  .  Force the snake out of the game.
  865. X;-
  866. X`09$readef_s efn=#64, state=cluster_2`09; get done flags
  867. X`09extzv`09#flag$v_done, #snake, cluster_2, r2 ; get done flags
  868. X;`09movb`09other_players+1, r3`09`09; get other players
  869. X`09bicw3`09r2, other_players+1, r3`09`09; find players who have not
  870. X`09`09`09`09`09`09; responded
  871. X`09bicw2`09r3, other_players+1`09`09; and say they are dead
  872. X`09clrl`09r2`09`09`09`09; snake 0
  873. X100$:`09bbc`09r2, r3, 200$
  874. X`09clrb`09move(r2)`09`09`09; say snake has quitted
  875. X`09addl3`09#flag$v_done+64, r2, r0`09`09; get event flag
  876. X`09$setef_s efn=r0`09`09`09`09; set event flag so I will
  877. X`09`09`09`09`09`09; wake up on return from here
  878. X200$:`09aoblss`09#snake, r2, 100$`09`09; for all 8 snakes
  879. X
  880. X`09ret
  881. X
  882. X
  883. X`09.entry`09-
  884. XSNAKE_GAME_END, `5Em<>
  885. X;+
  886. X;`09synchronizes the end of the game
  887. X;-
  888. X`09clrb`09dead`09`09`09; we are not dead
  889. X`09blbc`09master, 500$`09`09; if not master snake --> 500$
  890. X`09$clref_s efn=#flag$v_game+64`09; say game not in progress
  891. X`09clrb`09game_going`09`09; and again
  892. X`09$setimr_s efn=#flag$v_endofgame+64, daytim=second_2
  893. X`09clrw`09you_just_died`09`09; reset died flags
  894. X500$:
  895. X`09$waitfr_s efn=#flag$v_endofgame+64 ; wait for end of game
  896. X`09blbs`09abort, 800$`09`09; if we should abort --> 800$
  897. X`09ret
  898. X800$:`09; we must abort. Probably because master snake stopped
  899. X`09$exit_s #1
  900. X
  901. X
  902. X`09.entry`09-
  903. XSNAKE_EXIT, `5Em<r2,r3,r4,r5>
  904. X;+
  905. X;`09called as an exit handler
  906. X;-
  907. X;`09$cancel_s chan=mbxchan`09`09; cancel mailbox read
  908. X
  909. X`09movl`09player, r3`09`09; get my snake number
  910. X`09blss`0980$`09`09`09; we never were playing
  911. X`09clrb`09move(r3)`09`09; make next move a quit
  912. X`09addl3`09#flag$v_done, r3, r2`09; get done bit
  913. X`09bbcc`09r2, other_players, 50$`09; stop master snake from waiting for me
  914. X50$:`09addl2`09#64, r2`09`09`09; make into event flag
  915. X`09$setef_s efn=r2`09`09`09; say input done
  916. X`09bbcc`09r3, players, 60$`09; say this snake available
  917. X60$:
  918. X`09clrl`09score`5Br3`5D`09`09; zero score
  919. X`09clrl`09n_games`5Br3`5D`09`09; zero # of games played
  920. X80$:
  921. X`09blbc`09master, 100$`09`09; are we master snake ?
  922. X`09movb`09#1, abort`09`09; tell all other snakes to abort
  923. X`09clrb`09master_flag`09`09; say no master snake
  924. X`09$setef_s efn=#flag$v_read+64`09; wake everybody up
  925. X`09$setef_s efn=#flag$v_update+64
  926. X`09$setef_s efn=#flag$v_endofgame+64
  927. X`09$setef_s efn=#flag$v_synch+64
  928. X`09$setef_s efn=#flag$v_game+64`09; for people waiting for a game
  929. X100$:
  930. X
  931. X;`09$qiow_s func=#io$_setmode, chan=ttchan, p1=ttmode ;reset terminal
  932. X
  933. X;`09clear screen and put out of graphics mode
  934. X`09callg`09text_end_game, snake_write
  935. X`09blbc`09abort, 200$`09`09; game is not being aborted --> 200$
  936. X`09callg`09text_abort, snake_write
  937. X200$:
  938. X`09$deltva_s inadr=ret_range`09; delete global section
  939. X;`09$dassgn_s chan=snake_fab+fab$l_stv ; deassign channel
  940. X
  941. X`09ret
  942. X
  943. X`09
  944. X`09.entry`09-
  945. XNAME_SET, `5Em<r2,r3,r4,r5>
  946. X;+
  947. X;`09CALL NAME_SET( name )
  948. X;`09set this players name
  949. X;-
  950. X`09mull3`09#name_size, player, r3`09; get our player number (0-7)
  951. X`09addl2`09#13, r3`09`09`09; skip username
  952. X`09movc3`09#name_size-13, @4(ap), name(r3) ; store name in shared memory
  953. X`09ret
  954. X
  955. X`09.entry`09-
  956. XNAME_GET, `5Em<r2,r3,r4,r5>
  957. X;+
  958. X;`09CALL NAME_GET( name , player # )
  959. X;`09returns the name of specified player (1-8)
  960. X;-
  961. X`09subl3`09#1, @8(ap), r1`09`09; get player number (0-7)
  962. X`09mull2`09#name_size, r1`09`09; offset to this players name
  963. X`09movc3`09#name_size, name(r1), @4(ap) ; return players name
  964. X`09ret
  965. X
  966. X`09.entry`09-
  967. XSCORE_SET, `5Em<>
  968. X;+
  969. X;`09CALL SCORE_SET( player #, score , # games , # wins )
  970. X;-
  971. Xplayer_arg = 4
  972. Xscore_arg = 8
  973. Xgames_arg = 12
  974. Xwins_arg = 16
  975. X`09subl3`09#1, @player_arg(ap), r1`09`09; get our player # (0-snake)
  976. X`09movl`09@score_arg(ap), score`5Br1`5D`09; store score
  977. X`09movl`09@games_arg(ap), n_games`5Br1`5D
  978. X`09movl`09@wins_arg(ap), wins`5Br1`5D
  979. X`09ret
  980. X
  981. X`09.entry`09-
  982. XSCORE_GET, `5Em<>
  983. X;+
  984. X;`09CALL SCORE_GET( player , score , # games , # wins )
  985. X;-
  986. X;player_arg = 4
  987. X;score_arg = 8
  988. X;games_arg = 12
  989. X;wins_arg = 16
  990. X`09subl3`09#1, @player_arg(ap), r1`09`09; get player # (0-snake)
  991. X`09movl`09score`5Br1`5D, @score_arg(ap)`09; return score
  992. X`09movl`09n_games`5Br1`5D, @games_arg(ap)`09; return # of games played
  993. X`09movl`09wins`5Br1`5D, @wins_arg(ap)`09`09; return # of wins
  994. X`09ret
  995. X
  996. X`09.entry`09-
  997. Xsnake_game_count, `5Em<>
  998. X;+
  999. X;`09CALL SNAKE_GAME_COUNT( # games )
  1000. X;`09returns # of games played (total)
  1001. X;-
  1002. X`09movl`09game_count, @4(ap)
  1003. X`09ret
  1004. X
  1005. X`09.end
  1006. $ CALL UNPACK MQIXM.MAR;13 1312308785
  1007. $ v=f$verify(v)
  1008. $ EXIT
  1009.