Timer.asm 18 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106
  1. include_macros equ 1
  2. include_deb_mac equ 1
  3. include_flags equ 1
  4. include_keyboard_codes equ 1
  5. include_error_codes equ 1
  6. include_language_codes equ 1
  7. include include.asm
  8. start32data
  9. align 4
  10. public game_50hz_count
  11. public code16_seg
  12. public int8_vector
  13. public int9_vector
  14. public int24_vector
  15. extrn __x386_zero_base_selector:word ;data selector
  16. stabilise_count dd 4 ;no of 1/50 seconds to wait
  17. timer_data_start dd ?
  18. int8_vector dd ? ;original protected mode offset
  19. dd ? ;original protected mode cs value
  20. dd ? ;original real mode vector
  21. int9_vector dd ? ;original protected mode offset
  22. dd ? ;original protected mode cs value
  23. dd ? ;original real mode vector
  24. int24_vector dd ? ;original protected mode offset
  25. dd ? ;original protected mode cs value
  26. dd ? ;original real mode vector
  27. ds_val dw ? ;storage for handler ds
  28. code16_seg dw ? ;16 bit code segment
  29. ifndef with_replay
  30. random dd 12345678h
  31. endif
  32. timer_stack db 1000 dup (?)
  33. timer_stack_end dd 0
  34. music_command_return_value dd 0
  35. game_50hz_count dd ? ;needs renaming
  36. relative_50hz_count dd ?
  37. ifdef with_screen_saver
  38. sssss_count dd ? ;screen saver counter
  39. endif
  40. small_count db 3 ;convert 50Hz - 18.2 Hz
  41. big_count db 0
  42. cur_mus_cmd db ? ;the command music_command is processing
  43. align 4
  44. tseq_frames dd 0
  45. tseq_data dd 0
  46. tseq_counter dd 0
  47. ifdef intro_halt
  48. intro_halted dd 0
  49. endif
  50. ; Keyboard control
  51. ifndef no_keyboard ;if no keyboard then key equates > 255, won't fit int a byte
  52. key_status dw 0 ;bit 0: shift down
  53. ks_shift equ 0
  54. ks_control equ 1
  55. ks_alt equ 2
  56. key_buffer db key_buffer_size dup (0) ;buffer for key presses / releases
  57. align 4
  58. key_buffer_start dd key_buffer
  59. key_buffer_end dd key_buffer
  60. key_table2 db 128 dup (0) ;key table, which keys are down or up
  61. ; my conversion table
  62. ; {key} , shift {key} , cntrl {key} , alt {key}
  63. my_asctab db 0,0,0,0
  64. db 27,27,27,27
  65. db '1','!',0,key_alt_1
  66. db '2','"',0,key_alt_2
  67. db '3','œ',0,key_alt_3
  68. db '4','$',0,0
  69. db '5','%',0,0
  70. db '6','^',0,0
  71. db '7','&',0,0
  72. db '8','*',0,0
  73. db '9','(',0,0 ;10
  74. db '0',')',0,0
  75. db '-','_',0,0
  76. db '=','+',0,0
  77. db 8,8,8,8
  78. db 9,9,9,9
  79. db 'q','Q',17,0
  80. db 'w','W',23,0
  81. db 'e','E',5,0
  82. db 'r','R',18,0
  83. ; 20
  84. db 't','T',20,0
  85. db 'y','Y',25,0
  86. db 'u','U',21,0
  87. db 'i','I',9,0
  88. db 'o','O',15,0
  89. db 'p','P',16,0
  90. db '[','{',0,0
  91. db ']','}',0,0
  92. db 13,13,13,13
  93. db 0,0,0,0 ;control
  94. db 'a','A',1,0 ;30
  95. db 's','S',19,0
  96. db 'd','D',4,0
  97. db 'f','F',6,0
  98. db 'g','G',7,0
  99. db 'h','H',8,0
  100. db 'j','J',10,0
  101. db 'k','K',11,0
  102. db 'l','L',12,0
  103. db ';',':',0,0
  104. ; 40
  105. db "'",'@',0,0
  106. db '`','ª',0,0
  107. db 0,0,0,0 ;left shift
  108. db '#','~',0,0
  109. db 'z','Z',26,0
  110. db 'x','X',24,0
  111. db 'c','C',3,0
  112. db 'v','V',22,0
  113. db 'b','B',2,0
  114. db 'n','N',14,0
  115. ; 50
  116. db 'm','M',13,0
  117. db ',','<',0,0
  118. db '.','>',0,0
  119. db '/','?',0,0
  120. db 0,0,0,0 ;right shift
  121. db '*','*',0,0
  122. db 0,0,0,0 ;alt
  123. db ' ',' ',' ',' '
  124. db 0,0,0,0 ;caps lock
  125. db key_f1,key_f1,key_f1,key_f1 ;59
  126. ; 60
  127. db key_f2,key_f2,key_f2,key_f2
  128. db key_f3,key_f3,key_f3,key_f3
  129. db key_f4,key_f4,key_f4,key_f4
  130. db key_f5,key_f5,key_f5,key_f5
  131. db key_f6,key_f6,key_f6,key_f6
  132. db key_f7,key_f7,key_f7,key_f7
  133. db key_f8,key_f8,key_f8,key_f8
  134. db key_f9,key_f9,key_f9,key_f9
  135. db key_f10,key_f10,key_f10,key_f10
  136. db 0,0,0,0 ;num lock
  137. ; 70
  138. db key_scroll_lock,key_scroll_lock,key_scroll_lock,key_scroll_lock
  139. db 0,0,0,0 ;home
  140. db 0,0,0,0 ;up arrow
  141. db 0,0,0,0 ;page up
  142. db '-','-',0,0
  143. db 0,0,0,0 ;left arrow
  144. db 0,0,0,0 ;middle of key pad
  145. db 0,0,0,0 ;right arrow
  146. db '+','+',0,0
  147. db 0,0,0,0 ;end
  148. ; 80
  149. db 0,0,0,0 ;down arrow
  150. db 0,0,0,0 ;page down
  151. db 0,0,0,0 ;insert
  152. db key_delete,key_delete,key_delete,key_delete ;delete
  153. db 0,0,0,0
  154. db 0,0,0,0
  155. db '\','|',0,0
  156. db key_f11,key_f11,key_f11,key_f11
  157. db key_f12,key_f12,key_f12,key_f12
  158. db 0,0,0,0
  159. endif
  160. sec_code macro a,b,c,d,e,f
  161. db f,e,d,c,b,a
  162. endm
  163. security_codes db 0 dup (0)
  164. sec_code 7,0,4,7,2,3
  165. sec_code 5,2,0,2,2,8
  166. sec_code 2,9,3,9,4,4
  167. sec_code 2,9,3,8,5,2
  168. sec_code 2,5,7,3,0,3
  169. sec_code 1,1,3,3,2,2
  170. sec_code 1,1,3,6,6,8
  171. sec_code 1,2,7,8,1,3
  172. sec_code 4,9,2,1,3,2
  173. sec_code 1,8,0,4,0,0
  174. sec_code 5,2,0,3,9,4
  175. sec_code 1,2,7,1,7,4
  176. sec_code 3,0,5,6,6,2
  177. sec_code 3,8,6,2,5,3
  178. sec_code 7,0,4,4,1,7
  179. sec_code 2,8,4,7,6,4
  180. sec_code 3,8,6,6,5,1
  181. sec_code 8,1,5,9,3,1
  182. sec_code 2,8,4,2,9,1
  183. sec_code 2,5,7,9,2,5
  184. align 4
  185. timer_data_end dd ?
  186. end32data
  187. ifdef with_replay
  188. start32save_data
  189. random dd 12345678h
  190. end32save_data
  191. endif
  192. start32code
  193. start_timer_sequence proc
  194. ; Start off a timer sequence
  195. ; esi points to sequence data
  196. movzx eax,bpt[esi] ;get no of frames
  197. inc esi
  198. ;dec eax
  199. mov [tseq_data],esi
  200. mov [tseq_counter],sequence_count
  201. mov [tseq_frames],eax
  202. ret
  203. start_timer_sequence endp
  204. do_timer_sequence proc
  205. ; Do a timer sequence frame
  206. test [tseq_frames],-1 ;is there a sequence
  207. je no_seq
  208. ifdef intro_halt
  209. test [intro_halted],-1
  210. jne no_seq
  211. endif
  212. dec [tseq_counter]
  213. jne no_seq
  214. mov [tseq_counter],sequence_count
  215. push es
  216. mov es,[screen_segment]
  217. clear edi
  218. clear ecx
  219. clear eax
  220. mov esi,[tseq_data]
  221. do_frame: lodsb ;no to skip
  222. add edi,eax
  223. cmp al,-1
  224. je do_frame
  225. diffy: lodsb ;no to do
  226. mov cl,al
  227. rep movsb
  228. cmp al,-1
  229. je diffy
  230. cmp edi,game_screen_height*game_screen_width
  231. jc do_frame
  232. pop es
  233. mov [tseq_data],esi
  234. dec [tseq_frames]
  235. no_seq: ret
  236. do_timer_sequence endp
  237. stabilise proc
  238. ifndef no_timer ;Real timing loop
  239. mov eax,[stabilise_count]
  240. stabilise_loop: cmp eax,[game_50hz_count]
  241. jnbe stabilise_loop
  242. mov [game_50hz_count],0
  243. else
  244. mov eax,[stabilise_count]
  245. sub eax,1
  246. jbe stab_dun
  247. stab_loop: push eax
  248. call frame
  249. pop eax
  250. floop eax,stab_loop
  251. stab_dun:
  252. endif
  253. ret
  254. stabilise endp
  255. wait_50hz proc
  256. ; loop until a timer interupt occurs
  257. ifndef no_timer
  258. btr [system_flags],sf_timer_tick
  259. jnc wait_50hz
  260. endif
  261. ret
  262. wait_50hz endp
  263. wait_relative proc
  264. ; wait until relative_50hz_count exceeds eax, then reset it
  265. ; Return if escape pressed
  266. push eax
  267. call fetch_key
  268. je no_key
  269. cmp ax,27
  270. je escape
  271. cmp ax,key_f5
  272. je escape
  273. no_key: pop eax
  274. ifndef no_timer
  275. cmp [relative_50hz_count],eax
  276. jc wait_relative
  277. endif
  278. mov [relative_50hz_count],0 ;keep on for a minimum time
  279. clc
  280. ret
  281. escape: mov ebx,eax
  282. pop eax
  283. stc
  284. ret
  285. wait_relative endp
  286. set_stabilise proc
  287. ; eax is stabilise count
  288. mov [stabilise_count],eax
  289. ret
  290. set_stabilise endp
  291. init_timer proc
  292. push es
  293. mov [ds_val],ds ;save default ds
  294. ifndef no_timer
  295. push cs
  296. pop es ;lock timer handler memory
  297. mov ax,252bh
  298. mov bx,501h
  299. mov ecx,offset DGROUP:timer_handler
  300. mov edx,offset DGROUP:timer_handler_end
  301. sub edx,ecx
  302. int 21h
  303. jc it_error
  304. push ds
  305. pop es ;lock timer handler data
  306. mov ax,252bh
  307. mov bx,501h
  308. mov ecx,offset DGROUP:timer_data_start
  309. mov edx,offset DGROUP:timer_data_end
  310. sub edx,ecx
  311. int 21h
  312. jc it_error
  313. mov ax,2502h ;get protected mode vector
  314. mov cl,8
  315. int 21h
  316. mov int8_vector[0],ebx
  317. mov int8_vector[4],es
  318. mov ax,2503h ;get real mode pointer
  319. int 21h
  320. mov int8_vector[8],ebx
  321. mov ax,2506h ;hook real and protected mode interrupt
  322. push ds
  323. push cs
  324. pop ds
  325. mov edx,offset timer_handler
  326. int 21h
  327. pop ds
  328. ;--------------------------------------------------------------------------------------------------
  329. ; What the #@$! is this!!!!
  330. mov cx,23864 ;set pc clock to give 50hz interrupts
  331. mov al,36h
  332. out 43h,al
  333. jmp short f1
  334. f1: jmp short f2
  335. f2: mov al,cl
  336. out 40h,al
  337. jmp short f3
  338. f3: jmp short f4
  339. f4: mov al,ch
  340. out 40h,al
  341. bts [system_flags],sf_timer
  342. endif
  343. ifndef no_keyboard
  344. ; Hook the keyboard interupt while we are at it
  345. mov ax,2502h ;get protected mode vector
  346. mov cl,9
  347. int 21h
  348. mov int9_vector[0],ebx
  349. mov int9_vector[4],es
  350. mov ax,2503h ;get real mode pointer
  351. int 21h
  352. mov int9_vector[8],ebx
  353. mov ax,2506h ;hook real and protected mode interrupt
  354. push ds
  355. push cs
  356. pop ds
  357. mov edx,offset keyboard_handler
  358. int 21h
  359. pop ds
  360. bts [system_flags],sf_keyboard
  361. ; Swap z and y for german version
  362. cmp [_language],german_code
  363. jne not_germ
  364. mov bpt (44*4)[my_asctab],'y'
  365. mov bpt (44*4+1)[my_asctab],'Y'
  366. mov bpt (21*4)[my_asctab],'z'
  367. mov bpt (21*4+1)[my_asctab],'Z'
  368. not_germ:
  369. endif
  370. ; Hook the critical error interupt while we are at it
  371. mov ax,2502h ;get protected mode vector
  372. mov cl,24h
  373. int 21h
  374. mov int24_vector[0],ebx
  375. mov int24_vector[4],es
  376. mov ax,2503h ;get real mode pointer
  377. int 21h
  378. mov int24_vector[8],ebx
  379. mov ax,2506h ;hook real and protected mode interrupt
  380. push ds
  381. push cs
  382. pop ds
  383. mov edx,offset crit_err_handler
  384. int 21h
  385. pop ds
  386. bts [system_flags],sf_crit_err
  387. pop es
  388. ret
  389. it_error: cherror al,e,al,em_internal_error
  390. init_timer endp
  391. timer_handler proc
  392. pushf
  393. push eax
  394. push es
  395. ;mov ax,ss
  396. ;mov es,ax
  397. ;mov eax,esp
  398. ;
  399. ;mov ss,cs:[ds_val] ;use cs to load ss
  400. ;mov esp,offset timer_stack_end
  401. push_all
  402. cld
  403. mov ds,cs:[ds_val] ;use cs to load ds
  404. bts [system_flags],sf_timer_tick
  405. ;--------------------------------------------------------------------------------------------------
  406. ; Poll music driver
  407. mov eax,300h
  408. call music_command
  409. ;--------------------------------------------------------------------------------------------------
  410. ; Game timing
  411. inc [game_50hz_count] ;absolute count (stabilise)
  412. inc [relative_50hz_count] ;relative count (intro)
  413. ifdef with_screen_saver
  414. inc [sssss_count]
  415. endif
  416. ;--------------------------------------------------------------------------------------------------
  417. no_security: call do_timer_sequence
  418. ;--------------------------------------------------------------------------------------------------
  419. ; change 50Hz to 18.2 Hz
  420. ; This worked in Lure, I think
  421. sub [small_count],1
  422. jne no_timmy
  423. mov al,2
  424. cmp [big_count],68
  425. jnc ni_timmy
  426. add al,1
  427. ni_timmy: mov [small_count],al
  428. add [big_count],1
  429. cmp [big_count],91
  430. jc nu_timmy
  431. mov [big_count],0
  432. nu_timmy:
  433. ifndef with_replay
  434. call do_random
  435. endif
  436. pop_all
  437. ;mov esp,eax
  438. ;mov ax,es
  439. ;mov ss,ax
  440. pop es
  441. pop eax
  442. popf
  443. jmp fword ptr cs:int8_vector ;do system bits & things
  444. no_timmy: mov al,20h ;Hmmmmm?????
  445. out 20h,al
  446. na_timmy: pop_all
  447. ;mov esp,eax
  448. ;mov ax,es
  449. ;mov ss,ax
  450. pop es
  451. pop eax
  452. popf
  453. iretd
  454. timer_handler endp
  455. do_random proc
  456. mov eax,[random]
  457. imul eax,eax,41c64e6dh
  458. add eax,3039h
  459. mov [random],eax
  460. ret
  461. do_random endp
  462. music_command proc
  463. ; only works when driver is initialised
  464. push_all
  465. ;ifdef debug_42
  466. ; cmp ah,3
  467. ; je jjjj
  468. ; printf2 "music command %x %x %x %x",eax,ebx,ecx,edx
  469. ;jjjj:
  470. ;endif
  471. bt [system_flags],sf_music_bin
  472. jnc no_driver
  473. ifdef with_replay ;don't do sounds if speed replaying
  474. cmp ah,5
  475. jne do_up
  476. call check_replay_skip
  477. jc no_driver
  478. do_up:
  479. endif
  480. sti
  481. mov [cur_mus_cmd],ah ;save command so that music_command_return_val stays clean
  482. movzx esi,[code16_seg] ;pass data
  483. shl esi,4 ;absolute address
  484. mov es,__x386_zero_base_selector ;point to base memory
  485. mov es:mc_ax[esi],ax
  486. mov es:mc_bx[esi],bx
  487. mov es:mc_cx[esi],cx
  488. mov es:mc_dx[esi],dx
  489. mov bx,[code16_seg] ;now call driver init code
  490. shl ebx,16
  491. mov bx,offset music_command_16
  492. clear ecx ;no parameters
  493. mov ax,250eh
  494. int 21h
  495. cmp [cur_mus_cmd],0ch ;only permit return values for check fx channel
  496. jne no_driver
  497. mov [wpt music_command_return_value],ax
  498. ;printf "ret %x",eax
  499. no_driver: pop_all
  500. ret
  501. music_command endp
  502. ifndef no_keyboard ;if no keyboard then tables and fing not defined
  503. keyboard_handler proc
  504. push ds
  505. mov ds,cs:[ds_val] ;use cs to load ds
  506. push eax
  507. push ebx
  508. push ecx
  509. ifdef with_screen_saver
  510. mov [sssss_count],0
  511. endif
  512. in al,60h ; keyboard data
  513. mov bl,al
  514. in al,61h ; keyboard control
  515. mov ah,al
  516. or al,80h
  517. out 61h,al
  518. xchg ah,al
  519. out 61h,al ; keyboard has been reset
  520. mov al,bl
  521. movzx eax,al
  522. ; Move the pressed/released flag into ah and invert it
  523. shl eax,1
  524. shr al,1
  525. xor ah,1
  526. ; update the key indicator
  527. movzx ebx,al
  528. mov bpt [offset key_table2+ebx],ah
  529. ; ebx is key, ah = 1 for pressed, 0 for released
  530. ; Check for the shift keys
  531. cmp bl,42 ;r shift
  532. je status_change
  533. cmp bl,54
  534. je status_change
  535. cmp bl,29 ;control
  536. je status_change
  537. cmp bl,56 ;alt
  538. je status_change
  539. jmp norm_key
  540. status_change: ;check shift
  541. btr [key_status],ks_shift ;clear shift
  542. test bpt 42[key_table2],-1 ;and check keys
  543. jne shift_down
  544. test bpt 54[key_table2],-1
  545. je no_shift
  546. shift_down: bts [key_status],ks_shift ;set shift
  547. no_shift: ;check control key
  548. btr [key_status],ks_control
  549. test bpt 29[key_table2],-1 ;and check keys
  550. je no_control
  551. bts [key_status],ks_control
  552. ifdef intro_halt
  553. mov [intro_halted],1
  554. endif
  555. no_control: ;check alt key
  556. btr [key_status],ks_alt
  557. test bpt 56[key_table2],-1 ;ans check keys
  558. je no_alt
  559. bts [key_status],ks_alt
  560. ifdef intro_halt
  561. mov [intro_halted],0
  562. endif
  563. no_alt: jmp send_ekoi
  564. norm_key: ;don't do anything if the key was released
  565. jife ah,send_ekoi
  566. ; put key into buffer with status
  567. mov ah,bpt[key_status]
  568. mov ebx,[key_buffer_end] ;key goes here
  569. mov ecx,ebx ;calculate next position
  570. add ecx,2
  571. cmp ecx,offset key_buffer+key_buffer_size ;check for overflow
  572. jc noovf
  573. mov ecx,offset key_buffer
  574. noovf: cmp ecx,[key_buffer_start] ;have we filled the buffer
  575. je buffer_full
  576. mov [ebx],ax ;if not put key in
  577. mov [key_buffer_end],ecx ;and update end position
  578. buffer_full:
  579. send_ekoi: mov al,61h
  580. out 20h,al
  581. pop ecx
  582. pop ebx
  583. pop eax
  584. pop ds
  585. iretd
  586. keyboard_handler endp
  587. endif
  588. timer_handler_end::
  589. fetch_key proc
  590. ifndef no_keyboard
  591. push ebx
  592. ; check the keyboard handler and calculate keys
  593. mov ebx,[key_buffer_start]
  594. cmp ebx,[key_buffer_end]
  595. je no_key
  596. mov ax,[ebx]
  597. add ebx,2
  598. cmp ebx,offset key_buffer+key_buffer_size
  599. jc noovf
  600. mov ebx,offset key_buffer
  601. noovf: mov [key_buffer_start],ebx
  602. ; al holds key, ah holds key status
  603. movzx ebx,ah
  604. movzx eax,al
  605. shl eax,2
  606. ; Check the key status, shift then control then alt
  607. bt ebx,ks_shift
  608. jnc no_shift
  609. inc eax
  610. jmp status_done
  611. no_shift: bt ebx,ks_control
  612. jnc no_cntrl
  613. add eax,2
  614. jmp status_done
  615. no_cntrl: bt ebx,ks_alt
  616. jnc status_done
  617. add eax,3
  618. status_done: ;check for a conversion
  619. test bpt[offset my_asctab+eax],-1
  620. je no_conversion
  621. movzx eax,bpt [offset my_asctab+eax] ;get the key
  622. ; check here for cntrl alt delete
  623. cmp al,key_delete
  624. jne not_cad
  625. and bl,6
  626. cmp bl,6
  627. jne not_cad
  628. program_error em_game_over
  629. not_cad: or al,al ;clear z flag
  630. jmp fetch_key_end
  631. no_conversion: ;key is a funny one
  632. shr eax,2
  633. no_key: clear eax
  634. fetch_key_end: pop ebx
  635. ret
  636. else ;no_keyboard
  637. ; fetch a key press from the keyboard
  638. push esi
  639. mov ah,6
  640. mov dl,-1
  641. dos_int
  642. je no_key
  643. and eax,0ffh ; 0 means another key waiting
  644. jne no_key ;!=0 means ordinary key
  645. mov ah,6
  646. mov dl,-1
  647. dos_int
  648. movzx eax,al ;add 256 making sure zero flag is clear
  649. or ah,1
  650. no_key: pop esi
  651. ret
  652. endif
  653. fetch_key endp
  654. flush_key_buffer proc
  655. ifndef no_keyboard
  656. mov [key_buffer_start],offset key_buffer
  657. mov [key_buffer_end],offset key_buffer
  658. ret
  659. else ;no_keyboard
  660. call fetch_key
  661. jne flush_key_buffer
  662. ret
  663. endif
  664. flush_key_buffer endp
  665. crit_err_handler proc
  666. clear eax
  667. iretd
  668. crit_err_handler endp
  669. noitcetorp_kcehc proc
  670. ; Check Security code
  671. mov eax,[enter_digits] ;are we entering digits?
  672. jife eax,no_security
  673. ifndef cd_version_prot
  674. test [linc_digit_6],-1
  675. je no_security
  676. endif
  677. cmp [console_type],5
  678. je reactor_code
  679. ifdef cd_version_prot
  680. jmp cd_fix
  681. endif
  682. ; eax holds the number of the code we are looking for + 1
  683. dec eax
  684. mov esi,6
  685. imul esi,eax
  686. add esi,offset security_codes
  687. mov edi,offset linc_digit_1
  688. mov ecx,6
  689. sec_check: lodsb
  690. clear ah
  691. add ax,141h
  692. cmp ax,[edi]
  693. jne not_ok
  694. lea edi,4[edi]
  695. loop sec_check
  696. cd_fix: mov [fs_command],337
  697. jmp sec_don
  698. reactor_code: mov [fs_command],379
  699. jmp sec_don
  700. not_ok: mov [fs_command],240
  701. sec_don: mov [enter_digits],0
  702. no_security: ret
  703. noitcetorp_kcehc endp
  704. end32code
  705. start16code
  706. public music_driver
  707. public music_bin_seg
  708. music_driver dw 0 ;offset and
  709. music_bin_seg dw 0 ;segment of binary code
  710. sound db 0
  711. channel db 0
  712. voc_seg dw 0
  713. voc_fx_seg dw 0
  714. mc_ax dw 0 ;music command parameters
  715. mc_bx dw 0
  716. mc_cx dw 0
  717. mc_dx dw 0
  718. music_command_16 proc
  719. ; Additional commands
  720. ; ah = 100 mc_bx holds segment of voc data
  721. ; ah = 101 play voc data
  722. ; ah = 102 mc_bx holds segment of voc fx data
  723. ; ah = 103 play voc fx data
  724. mov ax,cs:[mc_ax]
  725. mov bx,cs:[mc_bx]
  726. mov cx,cs:[mc_cx]
  727. mov dx,cs:[mc_dx]
  728. cmp ah,100
  729. jc no_extra
  730. je set_voc_seg
  731. cmp ah,102
  732. jc play_voc
  733. je set_voc_fx_seg
  734. cmp ah,104
  735. jc play_voc_fx
  736. jmp no_extra
  737. set_voc_seg: ;mc_bx holds segment of voc data
  738. mov ax,cs:[mc_bx]
  739. mov cs:[voc_seg],ax
  740. clear ax
  741. retf
  742. play_voc: ;play voc data
  743. mov ax,5ffh
  744. mov bx,cs:[voc_seg]
  745. mov es,bx
  746. clear bx
  747. mov cx,07fh
  748. jmp no_extra
  749. set_voc_fx_seg: ;mc_bx holds segment of voc data
  750. mov ax,cs:[mc_bx]
  751. mov cs:[voc_fx_seg],ax
  752. clear ax
  753. retf
  754. play_voc_fx: ;play voc data
  755. mov ax,5feh
  756. mov bx,cs:[voc_fx_seg]
  757. mov es,bx
  758. clear bx
  759. mov cx,17fh
  760. jmp no_extra
  761. no_extra: call dword ptr cs:[music_driver]
  762. command_end: retf
  763. music_command_16 endp
  764. end16code
  765. end
  766.