PCRLIB_A.ASM 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440
  1. ; The Catacomb Source Code
  2. ; Copyright (C) 1993-2014 Flat Rock Software
  3. ;
  4. ; This program is free software; you can redistribute it and/or modify
  5. ; it under the terms of the GNU General Public License as published by
  6. ; the Free Software Foundation; either version 2 of the License, or
  7. ; (at your option) any later version.
  8. ;
  9. ; This program is distributed in the hope that it will be useful,
  10. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ; GNU General Public License for more details.
  13. ;
  14. ; You should have received a copy of the GNU General Public License along
  15. ; with this program; if not, write to the Free Software Foundation, Inc.,
  16. ; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. IDEAL
  18. MODEL SMALL,C
  19. ;
  20. ;offsets into .SPK file at segment SPKRfile, offset 0
  21. ;
  22. ;sound records each take up 16 bytes, and start at $10, and continue to $3F0
  23. snd_start equ 0
  24. snd_priority equ 2
  25. snd_samples equ 3
  26. snd_name equ 4
  27. ;
  28. ; EGA registers
  29. ;
  30. SCindex equ 3C4h
  31. SCmapmask equ 2
  32. GCindex equ 3CEh
  33. GCmode equ 5
  34. DATASEG
  35. ;
  36. ; stuff for pics and sprites
  37. ;
  38. STRUC picstruct ; sprite info extracted by refresh
  39. width dw ?
  40. height dw ?
  41. shapeptr dw ?
  42. ENDS
  43. EXTRN pictable: picstruct ; array of picture info
  44. EXTRN charptr:WORD
  45. EXTRN tileptr:WORD
  46. EXTRN picptr:WORD
  47. EXTRN spriteptr:WORD ;paraligned pointers
  48. EXTRN grmode:WORD
  49. EXTRN crtcaddr:WORD
  50. ;
  51. ; stuff for pics and sprites
  52. ;
  53. STRUC picstruct ; sprite info extracted by refresh
  54. width dw ?
  55. height dw ?
  56. shapeptr dw ?
  57. ENDS
  58. EXTRN imageinfo: picstruct ; array of picture info
  59. SPKactive dw 0 ;set non zero when started
  60. SoundData dd ? ;two word pointer to SPKR file, PARA aligned
  61. soundmode dw 1 ;0=nosound, 1=SPKR, 2= adlib...
  62. OldInt8 dd ? ;StartupSPK saves here, Shutdown restores
  63. ExtraInts db ? ;number of PlaySPKR's to a regular int 8
  64. Intcount db ? ;counter for extraints, call OldInt8 at 0
  65. sndspeed dw ? ;timer count speed
  66. SndPtr dw ? ;Pointer to frequency of current sound
  67. SndPriority db ? ;current sound's priority
  68. pausesndptr dw ?
  69. pausepriority db ?
  70. pauseextraints db ?
  71. pauseintcount db ?
  72. pausespeed dw ?
  73. _dontplay dw 0 ;set to 1 to avoid all interrupt and timer stuff
  74. xormask dw 0 ;to invert characters
  75. _yshift dw 0 ;to shift char lines
  76. screenseg dw 0a000h ;changes with grmode, page flips, & scrolls
  77. PUBLIC soundmode,SoundData,xormask,screenseg,_dontplay
  78. CODESEG
  79. PUBLIC CGAylookup,EGAylookup,VGAylookup
  80. ;========
  81. ;
  82. ; YLOOKUP has the offsets from screen mem of each screen line (multiples of 8)
  83. ;
  84. ;========
  85. CGAylookup dw 0,8192, 80,8272, 160,8352, 240,8432, 320,8512, 400,8592, 480,8672
  86. dw 560,8752, 640,8832, 720,8912, 800,8992, 880,9072, 960,9152,1040,9232
  87. dw 1120,9312,1200,9392,1280,9472,1360,9552,1440,9632,1520,9712,1600,9792
  88. dw 1680,9872,1760,9952,1840,10032,1920,10112,2000,10192,2080,10272,2160,10352
  89. dw 2240,10432,2320,10512,2400,10592,2480,10672,2560,10752,2640,10832,2720,10912
  90. dw 2800,10992,2880,11072,2960,11152,3040,11232,3120,11312,3200,11392,3280,11472
  91. dw 3360,11552,3440,11632,3520,11712,3600,11792,3680,11872,3760,11952,3840,12032
  92. dw 3920,12112,4000,12192,4080,12272,4160,12352,4240,12432,4320,12512,4400,12592
  93. dw 4480,12672,4560,12752,4640,12832,4720,12912,4800,12992,4880,13072,4960,13152
  94. dw 5040,13232,5120,13312,5200,13392,5280,13472,5360,13552,5440,13632,5520,13712
  95. dw 5600,13792,5680,13872,5760,13952,5840,14032,5920,14112,6000,14192,6080,14272
  96. dw 6160,14352,6240,14432,6320,14512,6400,14592,6480,14672,6560,14752,6640,14832
  97. dw 6720,14912,6800,14992,6880,15072,6960,15152,7040,15232,7120,15312,7200,15392
  98. dw 7280,15472,7360,15552,7440,15632,7520,15712,7600,15792,7680,15872,7760,15952
  99. dw 7840,16032,7920,16112
  100. EGAylookup dw 0, 40, 80, 120, 160, 200, 240, 280, 320, 360, 400, 440, 480, 520
  101. dw 560, 600, 640, 680, 720, 760, 800, 840, 880, 920, 960,1000,1040,1080
  102. dw 1120,1160,1200,1240,1280,1320,1360,1400,1440,1480,1520,1560,1600,1640
  103. dw 1680,1720,1760,1800,1840,1880,1920,1960,2000,2040,2080,2120,2160,2200
  104. dw 2240,2280,2320,2360,2400,2440,2480,2520,2560,2600,2640,2680,2720,2760
  105. dw 2800,2840,2880,2920,2960,3000,3040,3080,3120,3160,3200,3240,3280,3320
  106. dw 3360,3400,3440,3480,3520,3560,3600,3640,3680,3720,3760,3800,3840,3880
  107. dw 3920,3960,4000,4040,4080,4120,4160,4200,4240,4280,4320,4360,4400,4440
  108. dw 4480,4520,4560,4600,4640,4680,4720,4760,4800,4840,4880,4920,4960,5000
  109. dw 5040,5080,5120,5160,5200,5240,5280,5320,5360,5400,5440,5480,5520,5560
  110. dw 5600,5640,5680,5720,5760,5800,5840,5880,5920,5960,6000,6040,6080,6120
  111. dw 6160,6200,6240,6280,6320,6360,6400,6440,6480,6520,6560,6600,6640,6680
  112. dw 6720,6760,6800,6840,6880,6920,6960,7000,7040,7080,7120,7160,7200,7240
  113. dw 7280,7320,7360,7400,7440,7480,7520,7560,7600,7640,7680,7720,7760,7800
  114. dw 7840,7880,7920,7960,8000,8040,8080,8120,8160,8200,8240,8280,8320,8360
  115. dw 8400,8440,8480,8520,8560,8600,8640,8680,8720,8760,8800,8840,8880,8920
  116. dw 8960,9000,9040,9080,9120,9160,9200,9240,9280,9320,9360,9400,9440,9480
  117. dw 9520,9560,9600,9640,9680,9720,9760,9800,9840,9880,9920,9960,10000,10040
  118. dw 10080,10120,10160,10200
  119. VGAylookup dw 0, 320, 640, 960,1280,1600,1920,2240,2560,2880,3200,3520,3840,4160
  120. dw 4480,4800,5120,5440,5760,6080,6400,6720,7040,7360,7680,8000,8320,8640
  121. dw 8960,9280,9600,9920,10240,10560,10880,11200,11520,11840,12160,12480,12800,13120
  122. dw 13440,13760,14080,14400,14720,15040,15360,15680,16000,16320,16640,16960,17280,17600
  123. dw 17920,18240,18560,18880,19200,19520,19840,20160,20480,20800,21120,21440,21760,22080
  124. dw 22400,22720,23040,23360,23680,24000,24320,24640,24960,25280,25600,25920,26240,26560
  125. dw 26880,27200,27520,27840,28160,28480,28800,29120,29440,29760,30080,30400,30720,31040
  126. dw 31360,31680,32000,32320,32640,-32576,-32256,-31936,-31616,-31296,-30976,-30656,-30336,-30016
  127. dw -29696,-29376,-29056,-28736,-28416,-28096,-27776,-27456,-27136,-26816,-26496,-26176,-25856,-25536
  128. dw -25216,-24896,-24576,-24256,-23936,-23616,-23296,-22976,-22656,-22336,-22016,-21696,-21376,-21056
  129. dw -20736,-20416,-20096,-19776,-19456,-19136,-18816,-18496,-18176,-17856,-17536,-17216,-16896,-16576
  130. dw -16256,-15936,-15616,-15296,-14976,-14656,-14336,-14016,-13696,-13376,-13056,-12736,-12416,-12096
  131. dw -11776,-11456,-11136,-10816,-10496,-10176,-9856,-9536,-9216,-8896,-8576,-8256,-7936,-7616
  132. dw -7296,-6976,-6656,-6336,-6016,-5696,-5376,-5056,-4736,-4416,-4096,-3776,-3456,-3136
  133. dw -2816,-2496,-2176,-1856
  134. ;=======================================================================
  135. ;========
  136. ;
  137. ; StartupSound
  138. ;
  139. ; Sets up the new INT 8 ISR and various internal pointers.
  140. ; Assumes that the calling program has pointer SOUNDDATA to something
  141. ; meaningful...
  142. ;
  143. ;========
  144. PROC StartupSound
  145. PUBLIC StartupSound
  146. test [_dontplay],0ffffh
  147. je @@dowork
  148. ret
  149. @@dowork:
  150. test [SPKactive],0FFFFh ;see if library is active
  151. jne @@started ;library was allready started
  152. @@start:
  153. call NEAR PTR StopSound ;make sure nothing is playing
  154. mov ax,3508h ;call bios to get int 8
  155. int 21h
  156. mov [WORD oldint8],bx
  157. mov ax,es
  158. mov [WORD oldint8+2],ax
  159. mov ax,1
  160. mov [extraints],al ;the timer is still going at the
  161. mov [intcount],al ;normal rate now
  162. push ds
  163. push cs
  164. pop ds
  165. lea dx,[UpdateSPKR]
  166. mov ax,2508h ;call bios to set int 8
  167. int 21h
  168. pop ds
  169. inc [SPKactive] ;sound routines are now active
  170. @@started:
  171. mov ax,1
  172. mov [soundmode],ax ;set soundmode to SPKR
  173. ret
  174. ENDP
  175. ;=======================================================================
  176. ;========
  177. ;
  178. ; ShutdownSound
  179. ;
  180. ;========
  181. PROC ShutdownSound
  182. PUBLIC ShutdownSound
  183. test [_dontplay],0ffffh
  184. je @@dowork
  185. ret
  186. @@dowork:
  187. mov al,36h ;tell the timer chip we are going to
  188. out 43h,al ;change the speed of timer 0
  189. mov al,0 ;system expects 0000 for rate
  190. out 40h,al ;low
  191. out 40h,al ;high
  192. mov ax,[SPKactive]
  193. cmp ax,0
  194. je @@done ;sound library wasn't started...
  195. push ds
  196. mov dx,[WORD Oldint8]
  197. mov ax,[WORD Oldint8+2]
  198. mov ds,ax
  199. mov ax,2508h ;call bios to set int 8
  200. int 21h
  201. pop ds
  202. mov [SPKactive],0 ;sound routines are now inactive
  203. in al,61h ;get peripheral (speaker) port value
  204. and al,11111101b ;turn speaker off
  205. out 61h,al
  206. @@done:
  207. ret
  208. ENDP
  209. ;=========================================================================
  210. ;===========
  211. ;
  212. ; PlaySound (soundnum)
  213. ;
  214. ; If the sound's priority is >= the current priority, SoundPtr, SndPriority,
  215. ; and the timer speed are changed
  216. ;
  217. ;===========
  218. PROC PlaySound playnum:WORD
  219. PUBLIC PlaySound
  220. test [_dontplay],0ffffh
  221. je @@dowork
  222. ret
  223. @@dowork:
  224. mov ax,[playnum] ;index into the sound headers
  225. push si
  226. mov si,ax
  227. shl si,1
  228. shl si,1
  229. shl si,1
  230. shl si,1
  231. mov ax,[WORD SoundData+2]
  232. mov es,ax ;point es: to the spkr file
  233. mov al,[es:si+snd_Priority] ;priority table (one byte each)
  234. cmp al,[SndPriority]
  235. jb @@playdone ;current sound has higher priority
  236. mov [SndPriority],al
  237. mov ax,[es:si+snd_Start] ;offset in .SPK file
  238. mov [SndPtr],ax ;store it in the sound playing table
  239. mov bl,[es:si+snd_samples] ;samples / regular timer tick (1-255)
  240. mov [extraints],bl ;an OldInt8 will be called after this
  241. mov [intcount],bl ;many UpdateSPKR times have been called
  242. cmp bl,1 ;sample rate of 0 or 1 = 0000 for timer
  243. ja @@oktodiv
  244. xor bx,bx
  245. jmp @@settimer
  246. @@oktodiv:
  247. xor bh,bh
  248. xor ax,ax
  249. mov dx,1
  250. div bx ;$10000 / samples = timer rate
  251. mov bx,ax
  252. mov [sndspeed],bx ;save off the timer rate
  253. @@settimer:
  254. mov al,36h ;tell the timer chip we are going to
  255. out 43h,al ;change the speed of timer 0
  256. mov al,bl ;low byte of sample rate
  257. out 40h,al
  258. mov al,bh ;high byte of sample rate
  259. out 40h,al
  260. @@playdone:
  261. pop si
  262. ret
  263. ENDP
  264. ;======================================================================
  265. ;===========
  266. ;
  267. ; StopSound
  268. ;
  269. ;===========
  270. PROC StopSound
  271. PUBLIC StopSound
  272. test [_dontplay],0ffffh
  273. je @@dowork
  274. ret
  275. @@dowork:
  276. xor ax,ax ;set to 0
  277. mov [SndPtr],ax
  278. mov [SndPriority],al
  279. mov [sndspeed],ax
  280. in al,61h ;get peripheral (speaker) port value
  281. and al,11111101b ;turn speaker off
  282. out 61h,al
  283. mov al,36h ;tell the timer chip we are going to
  284. out 43h,al ;change the speed of timer 0
  285. mov al,0 ;back to normal clock speed
  286. out 40h,al
  287. out 40h,al
  288. inc al
  289. mov [extraints],al ;one bios int / int8
  290. mov [intcount],al
  291. ret
  292. ENDP
  293. ;======================================================================
  294. ;===========
  295. ;
  296. ; PauseSound
  297. ;
  298. ;===========
  299. PROC PauseSound
  300. PUBLIC PauseSound
  301. test [_dontplay],0ffffh
  302. je @@dowork
  303. ret
  304. @@dowork:
  305. mov ax,[SndPtr] ;save off the current values
  306. mov [pausesndptr],ax
  307. mov al,[SndPriority]
  308. mov [pausepriority],al
  309. mov al,[extraints]
  310. mov [pauseextraints],al
  311. mov al,[intcount]
  312. mov [pauseintcount],al
  313. mov ax,[sndspeed]
  314. mov [pausespeed],ax
  315. call StopSound
  316. ret
  317. ENDP
  318. ;======================================================================
  319. ;===========
  320. ;
  321. ; ContinueSound
  322. ;
  323. ;===========
  324. PROC ContinueSound
  325. PUBLIC ContinueSound
  326. test [_dontplay],0ffffh
  327. je @@dowork
  328. ret
  329. @@dowork:
  330. mov ax,[pausesndptr]
  331. mov [SndPtr],ax ;restore the old values
  332. mov al,[pausepriority]
  333. mov [SndPriority],al
  334. mov al,[pauseextraints]
  335. mov [extraints],al
  336. mov al,[pauseintcount]
  337. mov [intcount],al
  338. mov bx,[pausespeed]
  339. mov al,36h ;tell the timer chip we are going to
  340. out 43h,al ;change the speed of timer 0
  341. mov al,bl ;low byte of sample rate
  342. out 40h,al
  343. mov al,bh ;high byte of sample rate
  344. out 40h,al
  345. ret
  346. ENDP
  347. ;======================================================================
  348. ;========
  349. ;
  350. ; WaitendSound
  351. ; Just waits around until the current sound stops playing
  352. ;
  353. ;========
  354. PROC WaitEndSound
  355. PUBLIC WaitEndSound
  356. test [_dontplay],0ffffh
  357. je @@dowork
  358. ret
  359. @@dowork:
  360. pushf
  361. call FAR PTR UpdateSPKR ;in case a sound was just started and hasn't
  362. ;been hit by an INT yet
  363. @@wait:
  364. mov ax,[sndptr]
  365. cmp ax,0 ;when the ptr is 0, nothing is on
  366. jne @@wait
  367. ret
  368. ENDP
  369. ;=========================================================================
  370. ;========
  371. ;
  372. ; UpdateSPKR
  373. ; only called by interrupt $8!
  374. ;
  375. ;=========
  376. PROC UpdateSPKR FAR
  377. push ax
  378. push bx
  379. push cx
  380. push si
  381. push ds
  382. push es
  383. mov ax,_DATA
  384. mov ds,ax ;ds to this data segment
  385. mov ax,[WORD SoundData+2]
  386. mov es,ax ;es to sound file
  387. mov al,20h
  388. out 20h,al ;we got the interrupt here
  389. dec [intcount] ;see if it is time for a BIOS int 8...
  390. jne @@dosounds
  391. mov al,[extraints]
  392. mov [intcount],al ;reset interrupt counter
  393. pushf ;so the IRET from bios returns right
  394. call [OldInt8] ;call the old BIOS timer routine
  395. @@dosounds:
  396. ;
  397. ; play the speaker
  398. ;
  399. mov si,[SndPtr]
  400. cmp si,0
  401. je @@nosound ;nothing playing
  402. mov bx,[es:si]
  403. inc [SndPtr]
  404. inc [SndPtr]
  405. cmp bx,0
  406. je @@nosound ;a zero frequency is no sound, but don't stop
  407. cmp bx,-1 ;a -1 frequency is end of sound
  408. jne @@playfreq
  409. call StopSound
  410. jmp @@doneplay
  411. @@nosound:
  412. in al,61h ;get peripheral (speaker) port value
  413. and al,11111100b ;turn speaker off
  414. out 61h,al
  415. jmp @@doneplay
  416. @@playfreq:
  417. test [soundmode],0FFh ;if soundon=0, don't play anything
  418. je @@nosound
  419. mov al,10110110b ;write to channel 2 (speaker) timer
  420. out 43h,al
  421. mov al,bl
  422. out 42h,al ;low byte
  423. mov al,bh
  424. out 42h,al ;high byte
  425. in al,61h ;get peripheral (speaker) port value
  426. or al,00000011b ;turn speaker on to timer
  427. out 61h,al
  428. @@doneplay:
  429. pop es
  430. pop ds
  431. pop si
  432. pop cx
  433. pop bx
  434. pop ax
  435. iret
  436. ENDP
  437. ;==========================================================================
  438. ;========================================================================
  439. DATASEG
  440. rndindex dw ?
  441. rndtable db 0, 8, 109, 220, 222, 241, 149, 107, 75, 248, 254, 140, 16, 66
  442. db 74, 21, 211, 47, 80, 242, 154, 27, 205, 128, 161, 89, 77, 36
  443. db 95, 110, 85, 48, 212, 140, 211, 249, 22, 79, 200, 50, 28, 188
  444. db 52, 140, 202, 120, 68, 145, 62, 70, 184, 190, 91, 197, 152, 224
  445. db 149, 104, 25, 178, 252, 182, 202, 182, 141, 197, 4, 81, 181, 242
  446. db 145, 42, 39, 227, 156, 198, 225, 193, 219, 93, 122, 175, 249, 0
  447. db 175, 143, 70, 239, 46, 246, 163, 53, 163, 109, 168, 135, 2, 235
  448. db 25, 92, 20, 145, 138, 77, 69, 166, 78, 176, 173, 212, 166, 113
  449. db 94, 161, 41, 50, 239, 49, 111, 164, 70, 60, 2, 37, 171, 75
  450. db 136, 156, 11, 56, 42, 146, 138, 229, 73, 146, 77, 61, 98, 196
  451. db 135, 106, 63, 197, 195, 86, 96, 203, 113, 101, 170, 247, 181, 113
  452. db 80, 250, 108, 7, 255, 237, 129, 226, 79, 107, 112, 166, 103, 241
  453. db 24, 223, 239, 120, 198, 58, 60, 82, 128, 3, 184, 66, 143, 224
  454. db 145, 224, 81, 206, 163, 45, 63, 90, 168, 114, 59, 33, 159, 95
  455. db 28, 139, 123, 98, 125, 196, 15, 70, 194, 253, 54, 14, 109, 226
  456. db 71, 17, 161, 93, 186, 87, 244, 138, 20, 52, 123, 251, 26, 36
  457. db 17, 46, 52, 231, 232, 76, 31, 221, 84, 37, 216, 165, 212, 106
  458. db 197, 242, 98, 43, 39, 175, 254, 145, 190, 84, 118, 222, 187, 136
  459. db 120, 163, 236, 249
  460. ;
  461. ; Random # Generator vars
  462. ;
  463. indexi dw ? ;Rnd#Generator
  464. indexj dw ?
  465. LastRnd dw ?
  466. RndArray dw 17 dup (?)
  467. baseRndArray dw 1,1,2,3,5,8,13,21,54,75,129,204
  468. dw 323,527,850,1377,2227
  469. CODESEG
  470. ;=================================================
  471. ;
  472. ; Init RND generator
  473. ; if randomize is false, the counter is set to 0
  474. ;
  475. ; 11-Sep-90 LR FIX initialization to use TIME!
  476. ;=================================================
  477. PROC initrnd randomize:word
  478. public initrnd
  479. push si
  480. push di
  481. mov ax,ds
  482. mov es,ax
  483. mov di,offset RndArray
  484. mov si,offset baseRndArray
  485. mov cx,17
  486. cld
  487. rep movsw ;set up the table (which is constantly changed)
  488. mov [LastRnd],0
  489. mov [indexi],17*2
  490. mov [indexj],5*2
  491. mov ax,[randomize]
  492. cmp ax,0
  493. je @@setit ;if randomize is true, really random
  494. mov ah,2ch
  495. int 21h ;GetSystemTime
  496. mov [RndArray+34-2],dx
  497. xor dx,cx ;init w/seconds values
  498. mov [RndArray+10-2],dx
  499. @@setit:
  500. mov ax,0ffffh
  501. push ax
  502. call Random ;warm up generator!
  503. pop ax
  504. pop di
  505. pop si
  506. ret
  507. ENDP
  508. ;=================================================
  509. ;
  510. ; Return a random # between 0-?
  511. ; Exit : AX = 0-max value
  512. ;
  513. ; 11-Sep-90 LR -modify to save registers!
  514. ;=================================================
  515. PROC random maxval:WORD
  516. public random
  517. push si
  518. push bx ;save registers so we work OK!
  519. push cx
  520. push dx
  521. mov ax,[maxval]
  522. push ax ;save max value
  523. ;
  524. ; create a mask to cut down on the # of SUBTRACTS!
  525. ;
  526. mov dx,0ffffh ;full-mask
  527. @@0:
  528. shl ax,1
  529. jc @@0a
  530. shr dx,1
  531. jmp @@0
  532. @@0a:
  533. mov bx,[indexi] ;this routine was converted from
  534. mov si,[indexj] ;the Random macro on Merlin GS
  535. mov ax,[RndArray-2+bx]
  536. adc ax,[RndArray-2+si]
  537. mov [RndArray-2+bx],ax
  538. add ax,[LastRnd]
  539. mov [LastRnd],ax
  540. dec bx
  541. dec bx
  542. jne @@1
  543. mov bx,17*2
  544. @@1:
  545. dec si
  546. dec si
  547. jne @@2
  548. mov si,17*2
  549. @@2:
  550. mov [indexi],bx
  551. mov [indexj],si
  552. pop cx ;loop -- returns value in range
  553. and ax,dx ;AND our mask!
  554. @@3:
  555. cmp ax,cx ;SUBTRACT to be within range
  556. jbe @@4
  557. shr ax,1
  558. @@4:
  559. pop dx
  560. pop cx ;restore registers
  561. pop bx
  562. pop si
  563. ret
  564. ENDP
  565. ;===========================================================================
  566. ;=================================================
  567. ;
  568. ; Init table based RND generator
  569. ; if randomize is false, the counter is set to 0
  570. ;
  571. ;=================================================
  572. PROC initrndt randomize:word
  573. uses si,di
  574. public initrndt
  575. mov ax,[randomize]
  576. cmp ax,0
  577. ; jne @@timeit ;if randomize is true, really random
  578. mov dx,0 ;set to a definate value
  579. jmp @@setit
  580. @@timeit:
  581. mov ah,2ch
  582. int 21h ;GetSystemTime
  583. and dx,0ffh
  584. @@setit:
  585. mov [rndindex],dx
  586. ret
  587. ENDP
  588. ;=================================================
  589. ;
  590. ; Return a random # between 0-255
  591. ; Exit : AX = value
  592. ;
  593. ;=================================================
  594. PROC rndt
  595. public rndt
  596. mov bx,[rndindex]
  597. inc bx
  598. and bx,0ffh
  599. mov [rndindex],bx
  600. mov al,[rndtable+BX]
  601. xor ah,ah
  602. ret
  603. ENDP
  604. ;===========================================================================
  605. ;========
  606. ;
  607. ; WAITVBL
  608. ;
  609. ;========
  610. PROC WaitVBL
  611. PUBLIC WaitVBL
  612. push si
  613. push di
  614. mov dx,[crtcaddr]
  615. add dx,6
  616. waitvbl1:
  617. in al,dx
  618. test al,00001000b ;look for vbl
  619. jnz waitvbl1
  620. waitvbl2:
  621. in al,dx
  622. test al,00001000b ;look for vbl
  623. jz waitvbl2
  624. pop di
  625. pop si
  626. ret
  627. ENDP
  628. ;=======================================================================
  629. ;====================
  630. ;
  631. ; EGAplane
  632. ; Sets read/write mode 0 and selects the given plane (0-3)
  633. ; for reading and writing
  634. ;
  635. ;====================
  636. PROC EGAplane plane:WORD
  637. PUBLIC EGAplane
  638. mov dx,GCindex
  639. mov ax,GCmode
  640. out dx,ax ;set read / write mode 0
  641. mov dx,GCindex
  642. mov al,4 ;read map select
  643. mov ah,[BYTE plane] ;read from this plane number
  644. out dx,ax
  645. mov dx,SCindex
  646. mov al,SCmapmask
  647. mov ah,1
  648. mov cl,[BYTE plane] ;write to this plane only
  649. shl ah,cl
  650. out dx,ax
  651. ret
  652. ENDP
  653. ;=======================================================================
  654. ;====================
  655. ;
  656. ; EGAlatch
  657. ; Sets write mode 1 with all planes selected
  658. ;
  659. ;====================
  660. PROC EGAlatch plane:WORD
  661. PUBLIC EGAlatch
  662. mov dx,GCindex
  663. mov ax,1*256 + GCmode
  664. out dx,ax ;set read 0 / write mode 1
  665. mov dx,SCindex
  666. mov ax,15*256 + SCmapmask ;write to all planes
  667. out dx,ax
  668. ret
  669. ENDP
  670. ;=======================================================================
  671. ;============
  672. ;
  673. ; drawchar
  674. ; Calls CGAcharout / EGAcharout / VGAcharout
  675. ; based on grmode
  676. ;
  677. ;============
  678. PROC drawchar xcoordinate:WORD, ycoordinate:WORD, char:WORD
  679. PUBLIC drawchar
  680. push si
  681. push di
  682. mov ax,[screenseg]
  683. mov es,ax
  684. mov si,[char] ;low level routines get stuff in registers
  685. mov di,[xcoordinate]
  686. mov bx,[ycoordinate]
  687. shl bx,1
  688. shl bx,1
  689. shl bx,1
  690. shl bx,1
  691. add bx,[_yshift] ;allow printing on non-char lines
  692. mov ax,[grmode]
  693. cmp ax,1 ;CGA mode
  694. jne @@notcga
  695. call CgaCharout
  696. pop di
  697. pop si
  698. ret
  699. @@notcga:
  700. cmp ax,2 ;EGA mode
  701. jne @@notega
  702. call EgaCharout
  703. pop di
  704. pop si
  705. ret
  706. @@notega:
  707. cmp ax,3 ;VGA mode
  708. jne @@done
  709. call VgaCharout
  710. @@done:
  711. pop di
  712. pop si
  713. ret
  714. ENDP
  715. ;===========================================================================
  716. ;============
  717. ;
  718. ; CGAcharout
  719. ; SI= character; DI= xcoordinate; BX= ycoordinate*2
  720. ;
  721. ;============
  722. PROC CgaCharOut
  723. shl si,1
  724. shl si,1
  725. shl si,1
  726. shl si,1 ;char * 16 = tile's offset in PICS
  727. shl di,1 ;x * 2 + ylookup[y] = screen location
  728. add di,[CGAylookup+bx] ;BX is pointer into YLOOKUP
  729. mov bx,[xormask] ;so chars can be inverted
  730. mov ax,[WORD charptr+2]
  731. mov ds,ax ;segment of tile pictures (PARA'd)
  732. cld
  733. lodsw ;load in a row of the tile's picture
  734. xor ax,bx
  735. stosw
  736. add di,1FFEh
  737. lodsw
  738. xor ax,bx
  739. stosw
  740. sub di,1FB2h
  741. lodsw
  742. xor ax,bx
  743. stosw
  744. add di,1FFEh
  745. lodsw
  746. xor ax,bx
  747. stosw
  748. sub di,1FB2h
  749. lodsw
  750. xor ax,bx
  751. stosw
  752. add di,1FFEh
  753. lodsw
  754. xor ax,bx
  755. stosw
  756. sub di,1FB2h
  757. lodsw
  758. xor ax,bx
  759. stosw
  760. add di,1FFEh
  761. lodsw
  762. xor ax,bx
  763. stosw
  764. mov ax,_DATA
  765. mov ds,ax ;restore turbo's data segment
  766. ret
  767. ENDP
  768. ;=======================================================================
  769. ;============
  770. ;
  771. ; EGAcharout
  772. ; SI= character; DI= xcoordinate; BX= ycoordinate
  773. ;
  774. ;============
  775. PROC EgaCharOut
  776. shl si,1
  777. shl si,1
  778. shl si,1 ;char * 8 = tile's offset in PICS
  779. add di,[EGAylookup+bx] ;BX is pointer into YLOOKUP
  780. mov cx,ds
  781. mov dx,GCindex
  782. mov ax,GCmode
  783. out dx,ax ;set read / write mode 0
  784. cld
  785. mov bx,si ;so the planes can be drawn the same
  786. mov cx,di
  787. mov dx,GCindex
  788. mov ax,0*256+4 ;read map select
  789. out dx,ax
  790. mov dx,SCindex
  791. mov ax,1*256+SCmapmask
  792. out dx,ax
  793. mov dx,[xormask] ;so chars can be inverted
  794. mov ax,[charptr+2]
  795. mov ds,ax ;segment of tile pictures (PARA'd)
  796. lodsb
  797. xor al,dl
  798. stosb
  799. add di,39
  800. lodsb
  801. xor al,dl
  802. stosb
  803. add di,39
  804. lodsb
  805. xor al,dl
  806. stosb
  807. add di,39
  808. lodsb
  809. xor al,dl
  810. stosb
  811. add di,39
  812. lodsb
  813. xor al,dl
  814. stosb
  815. add di,39
  816. lodsb
  817. xor al,dl
  818. stosb
  819. add di,39
  820. lodsb
  821. xor al,dl
  822. stosb
  823. add di,39
  824. lodsb
  825. xor al,dl
  826. stosb
  827. add di,39
  828. mov si,bx
  829. mov di,cx
  830. push dx
  831. mov dx,GCindex
  832. mov ax,1*256+4 ;read map select
  833. out dx,ax
  834. mov dx,SCindex
  835. mov ax,2*256+SCmapmask ;write mask
  836. out dx,ax
  837. pop dx
  838. lodsb
  839. xor al,dl
  840. stosb
  841. add di,39
  842. lodsb
  843. xor al,dl
  844. stosb
  845. add di,39
  846. lodsb
  847. xor al,dl
  848. stosb
  849. add di,39
  850. lodsb
  851. xor al,dl
  852. stosb
  853. add di,39
  854. lodsb
  855. xor al,dl
  856. stosb
  857. add di,39
  858. lodsb
  859. xor al,dl
  860. stosb
  861. add di,39
  862. lodsb
  863. xor al,dl
  864. stosb
  865. add di,39
  866. lodsb
  867. xor al,dl
  868. stosb
  869. add di,39
  870. mov si,bx
  871. mov di,cx
  872. push dx
  873. mov dx,GCindex
  874. mov ax,2*256+4 ;read map select
  875. out dx,ax
  876. mov dx,SCindex
  877. mov ax,4*256+SCmapmask ;write mask
  878. out dx,ax
  879. pop dx
  880. lodsb
  881. xor al,dl
  882. stosb
  883. add di,39
  884. lodsb
  885. xor al,dl
  886. stosb
  887. add di,39
  888. lodsb
  889. xor al,dl
  890. stosb
  891. add di,39
  892. lodsb
  893. xor al,dl
  894. stosb
  895. add di,39
  896. lodsb
  897. xor al,dl
  898. stosb
  899. add di,39
  900. lodsb
  901. xor al,dl
  902. stosb
  903. add di,39
  904. lodsb
  905. xor al,dl
  906. stosb
  907. add di,39
  908. lodsb
  909. xor al,dl
  910. stosb
  911. add di,39
  912. mov si,bx
  913. mov di,cx
  914. push dx
  915. mov dx,GCindex
  916. mov ax,3*256+4 ;read map select
  917. out dx,ax
  918. mov dx,SCindex
  919. mov ax,8*256+SCmapmask ;write mask
  920. out dx,ax
  921. pop dx
  922. lodsb
  923. xor al,dl
  924. stosb
  925. add di,39
  926. lodsb
  927. xor al,dl
  928. stosb
  929. add di,39
  930. lodsb
  931. xor al,dl
  932. stosb
  933. add di,39
  934. lodsb
  935. xor al,dl
  936. stosb
  937. add di,39
  938. lodsb
  939. xor al,dl
  940. stosb
  941. add di,39
  942. lodsb
  943. xor al,dl
  944. stosb
  945. add di,39
  946. lodsb
  947. xor al,dl
  948. stosb
  949. add di,39
  950. lodsb
  951. xor al,dl
  952. stosb
  953. add di,39
  954. mov dx,SCindex
  955. mov ax,15*256 + SCmapmask ;write to all planes
  956. out dx,ax
  957. mov ax,_DATA
  958. mov ds,ax ;restore turbo's data segment
  959. ret
  960. ENDP
  961. ;=======================================================================
  962. ;============
  963. ;
  964. ; VGAcharout
  965. ; SI= character; DI= xcoordinate; BX= ycoordinate
  966. ;
  967. ;============
  968. PROC VgaCharOut
  969. shl si,1
  970. shl si,1
  971. shl si,1
  972. shl si,1
  973. shl si,1
  974. shl si,1 ;char * 64 = tile's offset in PICS
  975. shl di,1
  976. shl di,1
  977. shl di,1 ;x * 8 + ylookup[y] = screen location
  978. add di,[VGAylookup+bx] ;BX is pointer into YLOOKUP
  979. mov bx,[xormask] ;so chars can be inverted
  980. mov ax,[WORD charptr+2]
  981. mov ds,ax ;segment of tile pictures (PARA'd)
  982. cld
  983. lodsw ;load in a row of the tile's picture
  984. xor ax,bx
  985. stosw
  986. lodsw
  987. xor ax,bx
  988. stosw
  989. lodsw
  990. xor ax,bx
  991. stosw
  992. lodsw
  993. xor ax,bx
  994. stosw
  995. add di,312
  996. lodsw ;load in a row of the tile's picture
  997. xor ax,bx
  998. stosw
  999. lodsw
  1000. xor ax,bx
  1001. stosw
  1002. lodsw
  1003. xor ax,bx
  1004. stosw
  1005. lodsw
  1006. xor ax,bx
  1007. stosw
  1008. add di,312
  1009. lodsw ;load in a row of the tile's picture
  1010. xor ax,bx
  1011. stosw
  1012. lodsw
  1013. xor ax,bx
  1014. stosw
  1015. lodsw
  1016. xor ax,bx
  1017. stosw
  1018. lodsw
  1019. xor ax,bx
  1020. stosw
  1021. add di,312
  1022. lodsw ;load in a row of the tile's picture
  1023. xor ax,bx
  1024. stosw
  1025. lodsw
  1026. xor ax,bx
  1027. stosw
  1028. lodsw
  1029. xor ax,bx
  1030. stosw
  1031. lodsw
  1032. xor ax,bx
  1033. stosw
  1034. add di,312
  1035. lodsw ;load in a row of the tile's picture
  1036. xor ax,bx
  1037. stosw
  1038. lodsw
  1039. xor ax,bx
  1040. stosw
  1041. lodsw
  1042. xor ax,bx
  1043. stosw
  1044. lodsw
  1045. xor ax,bx
  1046. stosw
  1047. add di,312
  1048. lodsw ;load in a row of the tile's picture
  1049. xor ax,bx
  1050. stosw
  1051. lodsw
  1052. xor ax,bx
  1053. stosw
  1054. lodsw
  1055. xor ax,bx
  1056. stosw
  1057. lodsw
  1058. xor ax,bx
  1059. stosw
  1060. add di,312
  1061. lodsw ;load in a row of the tile's picture
  1062. xor ax,bx
  1063. stosw
  1064. lodsw
  1065. xor ax,bx
  1066. stosw
  1067. lodsw
  1068. xor ax,bx
  1069. stosw
  1070. lodsw
  1071. xor ax,bx
  1072. stosw
  1073. add di,312
  1074. lodsw ;load in a row of the tile's picture
  1075. xor ax,bx
  1076. stosw
  1077. lodsw
  1078. xor ax,bx
  1079. stosw
  1080. lodsw
  1081. xor ax,bx
  1082. stosw
  1083. lodsw
  1084. xor ax,bx
  1085. stosw
  1086. mov ax,_DATA
  1087. mov ds,ax ;restore turbo's data segment
  1088. ret
  1089. ENDP
  1090. ;=======================================================================
  1091. ;============
  1092. ;
  1093. ; drawtile
  1094. ; Just drops a 16*16 tile onto the screen
  1095. ; Calls CGAtileout / EGAtileout / VGAtileout
  1096. ; based on grmode
  1097. ;
  1098. ;============
  1099. PROC drawtile xcoordinate:WORD, ycoordinate:WORD, tile:WORD
  1100. PUBLIC drawtile
  1101. push si
  1102. push di
  1103. cld
  1104. mov ax,[screenseg]
  1105. mov es,ax
  1106. mov si,[tile]
  1107. mov di,[xcoordinate] ;low level routines get stuff in registers
  1108. mov bx,[ycoordinate]
  1109. shl bx,1
  1110. mov ax,[grmode]
  1111. mov cx,[WORD tileptr+2]
  1112. mov ds,cx ;segment of pictures (PARA'd)
  1113. cmp ax,1 ;CGA mode
  1114. jne @@notcga
  1115. call CGAtileout
  1116. jmp @@done
  1117. @@notcga:
  1118. cmp ax,2 ;EGA mode
  1119. jne @@notega
  1120. call EGAtileout
  1121. jmp @@done
  1122. @@notega:
  1123. cmp ax,3 ;VGA mode
  1124. jne @@done
  1125. call VGAtileout
  1126. @@done:
  1127. mov ax,_DATA
  1128. mov ds,ax ;restore turbo's data segment
  1129. pop di
  1130. pop si
  1131. ret
  1132. ENDP
  1133. ;=======================
  1134. ;
  1135. ; CGAtileout
  1136. ; SI= tile #, BX=y, DI=x
  1137. ;
  1138. ;=======================
  1139. PROC CGAtileout
  1140. PUBLIC CGAtileout
  1141. shl si,1
  1142. shl si,1
  1143. shl si,1
  1144. shl si,1
  1145. shl si,1
  1146. shl si,1
  1147. shl bx,1
  1148. add di,[CGAylookup + BX] ;destination on screen
  1149. movsw
  1150. movsw
  1151. add di,8188
  1152. movsw
  1153. movsw
  1154. sub di,8116
  1155. movsw
  1156. movsw
  1157. add di,8188
  1158. movsw
  1159. movsw
  1160. sub di,8116
  1161. movsw
  1162. movsw
  1163. add di,8188
  1164. movsw
  1165. movsw
  1166. sub di,8116
  1167. movsw
  1168. movsw
  1169. add di,8188
  1170. movsw
  1171. movsw
  1172. sub di,8116
  1173. movsw
  1174. movsw
  1175. add di,8188
  1176. movsw
  1177. movsw
  1178. sub di,8116
  1179. movsw
  1180. movsw
  1181. add di,8188
  1182. movsw
  1183. movsw
  1184. sub di,8116
  1185. movsw
  1186. movsw
  1187. add di,8188
  1188. movsw
  1189. movsw
  1190. sub di,8116
  1191. movsw
  1192. movsw
  1193. add di,8188
  1194. movsw
  1195. movsw
  1196. ret
  1197. ENDP
  1198. ;=======================
  1199. ;
  1200. ; EGAtileout
  1201. ; SI= tile #, BX=y, DI=x
  1202. ;
  1203. ;=======================
  1204. PROC EGAtileout
  1205. PUBLIC EGAtileout
  1206. shl si,1
  1207. shl si,1
  1208. shl si,1
  1209. shl si,1
  1210. shl si,1
  1211. add di,[EGAylookup + BX] ;destination on screen
  1212. mov dx,SCindex
  1213. mov al,SCmapmask
  1214. out dx,al
  1215. mov al,1111b
  1216. inc dx
  1217. out dx,al
  1218. mov dx,GCindex
  1219. mov al,GCmode
  1220. out dx,al
  1221. mov al,1
  1222. inc dx
  1223. out dx,al
  1224. movsb
  1225. movsb
  1226. add di,38
  1227. movsb
  1228. movsb
  1229. add di,38
  1230. movsb
  1231. movsb
  1232. add di,38
  1233. movsb
  1234. movsb
  1235. add di,38
  1236. movsb
  1237. movsb
  1238. add di,38
  1239. movsb
  1240. movsb
  1241. add di,38
  1242. movsb
  1243. movsb
  1244. add di,38
  1245. movsb
  1246. movsb
  1247. add di,38
  1248. movsb
  1249. movsb
  1250. add di,38
  1251. movsb
  1252. movsb
  1253. add di,38
  1254. movsb
  1255. movsb
  1256. add di,38
  1257. movsb
  1258. movsb
  1259. add di,38
  1260. movsb
  1261. movsb
  1262. add di,38
  1263. movsb
  1264. movsb
  1265. add di,38
  1266. movsb
  1267. movsb
  1268. add di,38
  1269. movsb
  1270. movsb
  1271. ret
  1272. ENDP
  1273. ;=======================
  1274. ;
  1275. ; VGAtileout
  1276. ; SI= tile #, BX=y, DI=x
  1277. ;
  1278. ;=======================
  1279. PROC VGAtileout
  1280. PUBLIC VGAtileout
  1281. mov ah,al
  1282. xor al,al ;fast multiply by 256
  1283. add di,[VGAylookup + BX] ;destination on screen
  1284. movsw
  1285. movsw
  1286. movsw
  1287. movsw
  1288. movsw
  1289. movsw
  1290. movsw
  1291. movsw
  1292. add di,304
  1293. movsw
  1294. movsw
  1295. movsw
  1296. movsw
  1297. movsw
  1298. movsw
  1299. movsw
  1300. movsw
  1301. add di,304
  1302. movsw
  1303. movsw
  1304. movsw
  1305. movsw
  1306. movsw
  1307. movsw
  1308. movsw
  1309. movsw
  1310. add di,304
  1311. movsw
  1312. movsw
  1313. movsw
  1314. movsw
  1315. movsw
  1316. movsw
  1317. movsw
  1318. movsw
  1319. add di,304
  1320. movsw
  1321. movsw
  1322. movsw
  1323. movsw
  1324. movsw
  1325. movsw
  1326. movsw
  1327. movsw
  1328. add di,304
  1329. movsw
  1330. movsw
  1331. movsw
  1332. movsw
  1333. movsw
  1334. movsw
  1335. movsw
  1336. movsw
  1337. add di,304
  1338. movsw
  1339. movsw
  1340. movsw
  1341. movsw
  1342. movsw
  1343. movsw
  1344. movsw
  1345. movsw
  1346. add di,304
  1347. movsw
  1348. movsw
  1349. movsw
  1350. movsw
  1351. movsw
  1352. movsw
  1353. movsw
  1354. movsw
  1355. add di,304
  1356. movsw
  1357. movsw
  1358. movsw
  1359. movsw
  1360. movsw
  1361. movsw
  1362. movsw
  1363. movsw
  1364. add di,304
  1365. movsw
  1366. movsw
  1367. movsw
  1368. movsw
  1369. movsw
  1370. movsw
  1371. movsw
  1372. movsw
  1373. add di,304
  1374. movsw
  1375. movsw
  1376. movsw
  1377. movsw
  1378. movsw
  1379. movsw
  1380. movsw
  1381. movsw
  1382. add di,304
  1383. movsw
  1384. movsw
  1385. movsw
  1386. movsw
  1387. movsw
  1388. movsw
  1389. movsw
  1390. movsw
  1391. add di,304
  1392. movsw
  1393. movsw
  1394. movsw
  1395. movsw
  1396. movsw
  1397. movsw
  1398. movsw
  1399. movsw
  1400. add di,304
  1401. movsw
  1402. movsw
  1403. movsw
  1404. movsw
  1405. movsw
  1406. movsw
  1407. movsw
  1408. movsw
  1409. add di,304
  1410. movsw
  1411. movsw
  1412. movsw
  1413. movsw
  1414. movsw
  1415. movsw
  1416. movsw
  1417. movsw
  1418. add di,304
  1419. movsw
  1420. movsw
  1421. movsw
  1422. movsw
  1423. movsw
  1424. movsw
  1425. movsw
  1426. movsw
  1427. ret
  1428. ENDP
  1429. ;=======================================================================
  1430. ;============
  1431. ;
  1432. ; drawpic
  1433. ; Just drops a width/depth block onto the screen with no masking
  1434. ; Calls CGAdrawpic / EGAdrawpic / VGAdrawpic
  1435. ; based on grmode
  1436. ;
  1437. ;============
  1438. PROC drawpic xcoordinate:WORD, ycoordinate:WORD, pic:WORD
  1439. PUBLIC drawpic
  1440. push si
  1441. push di
  1442. cld
  1443. mov si,[pic]
  1444. shl si,1
  1445. shl si,1
  1446. shl si,1
  1447. shl si,1 ;pictable records are 16 bytes
  1448. mov ax,[si+pictable.width]
  1449. mov [WORD cs:picwidth],ax
  1450. mov ax,[si+pictable.height]
  1451. mov [WORD cs:picheight],ax
  1452. mov si,[si+pictable.shapeptr]
  1453. mov ax,[screenseg]
  1454. mov es,ax
  1455. mov di,[xcoordinate] ;low level routines get stuff in registers
  1456. mov bx,[ycoordinate]
  1457. shl bx,1 ;because it will be indexed into a table
  1458. mov ax,[grmode]
  1459. mov cx,[WORD picptr+2]
  1460. mov ds,cx ;segment of pictures (PARA'd)
  1461. cmp ax,1 ;CGA mode
  1462. jne @@notcga
  1463. call CgaDrawpic
  1464. jmp @@done
  1465. @@notcga:
  1466. cmp ax,2 ;EGA mode
  1467. jne @@notega
  1468. call EgaDrawpic
  1469. jmp @@done
  1470. @@notega:
  1471. cmp ax,3 ;VGA mode
  1472. jne @@done
  1473. call VgaDrawpic
  1474. @@done:
  1475. mov ax,_DATA
  1476. mov ds,ax ;restore turbo's data segment
  1477. pop di
  1478. pop si
  1479. ret
  1480. ENDP
  1481. picwidth dw ? ;used by all modes
  1482. picxcoord dw ?
  1483. picheight dw ?
  1484. ;===========================================================================
  1485. ;============
  1486. ;
  1487. ; CgaDrawpic
  1488. ; SI= source; DI= xcoordinate; BX= ycoordinate*2
  1489. ;
  1490. ;============
  1491. PROC CgaDrawpic
  1492. shr di,1 ;x / 4 + ylookup[y] = screen location
  1493. shr di,1
  1494. mov [WORD cs:picxcoord],di
  1495. @@drawrow:
  1496. mov cx,[WORD cs:picwidth] ;number of words to write
  1497. mov di,[WORD cs:CGAylookup+bx]
  1498. add bx,2
  1499. add di,[WORD cs:picxcoord]
  1500. @@drawword:
  1501. movsb
  1502. loop @@drawword
  1503. dec [WORD cs:picheight]
  1504. jnz @@drawrow
  1505. ret
  1506. ENDP
  1507. ;=======================================================================
  1508. ;============
  1509. ;
  1510. ; EgaDrawpic
  1511. ; SI= source; DI= xcoordinate; BX= ycoordinate
  1512. ;
  1513. ;============
  1514. PROC EgaDrawpic
  1515. mov ax,105h
  1516. mov dx,3ceh ;set write mode 1
  1517. out dx,ax
  1518. shr di,1 ;x / 8 + ylookup[y] = screen location
  1519. shr di,1
  1520. shr di,1
  1521. mov [WORD cs:picxcoord],di
  1522. mov ax,0A000h ;segment of screen memory
  1523. mov es,ax
  1524. @@drawrow:
  1525. mov cx,[WORD cs:picwidth] ;number of bytes to write
  1526. mov di,[WORD cs:EGAylookup+bx]
  1527. add bx,2
  1528. add di,[WORD cs:picxcoord]
  1529. @@drawword:
  1530. movsb
  1531. loop @@drawword
  1532. dec [WORD cs:picheight]
  1533. jnz @@drawrow
  1534. ret
  1535. ENDP
  1536. ;=======================================================================
  1537. ;============
  1538. ;
  1539. ; VgaDrawpic
  1540. ; SI= source; DI= xcoordinate; BX= ycoordinate
  1541. ;
  1542. ;============
  1543. PROC VgaDrawpic
  1544. mov [WORD cs:picxcoord],di
  1545. @@drawrow:
  1546. mov cx,[WORD cs:picwidth] ;number of words to write
  1547. mov di,[WORD cs:VGAylookup+bx]
  1548. add bx,2
  1549. add di,[WORD cs:picxcoord]
  1550. @@drawword:
  1551. movsb
  1552. loop @@drawword
  1553. dec [WORD cs:picheight]
  1554. jnz @@drawrow
  1555. ret
  1556. ENDP
  1557. ;===========================================================================
  1558. MASM
  1559. ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  1560. ;
  1561. ; Name: VideoID
  1562. ;
  1563. ; Function: Detects the presence of various video subsystems
  1564. ;
  1565. ; int VideoID;
  1566. ;
  1567. ; Subsystem ID values:
  1568. ; 0 = (none)
  1569. ; 1 = MDA
  1570. ; 2 = CGA
  1571. ; 3 = EGA
  1572. ; 4 = MCGA
  1573. ; 5 = VGA
  1574. ; 80h = HGC
  1575. ; 81h = HGC+
  1576. ; 82h = Hercules InColor
  1577. ;
  1578. ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  1579. ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  1580. ;
  1581. ; Equates
  1582. ;
  1583. ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  1584. VIDstruct STRUC ; corresponds to C data structure
  1585. Video0Type DB ? ; first subsystem type
  1586. Display0Type DB ? ; display attached to first subsystem
  1587. Video1Type DB ? ; second subsystem type
  1588. Display1Type DB ? ; display attached to second subsystem
  1589. VIDstruct ENDS
  1590. Device0 EQU word ptr Video0Type[di]
  1591. Device1 EQU word ptr Video1Type[di]
  1592. MDA EQU 1 ; subsystem types
  1593. CGA EQU 2
  1594. EGA EQU 3
  1595. MCGA EQU 4
  1596. VGA EQU 5
  1597. HGC EQU 80h
  1598. HGCPlus EQU 81h
  1599. InColor EQU 82h
  1600. MDADisplay EQU 1 ; display types
  1601. CGADisplay EQU 2
  1602. EGAColorDisplay EQU 3
  1603. PS2MonoDisplay EQU 4
  1604. PS2ColorDisplay EQU 5
  1605. TRUE EQU 1
  1606. FALSE EQU 0
  1607. ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  1608. ;
  1609. ; Program
  1610. ;
  1611. ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  1612. Results VIDstruct <> ;results go here!
  1613. EGADisplays DB CGADisplay ; 0000b, 0001b (EGA switch values)
  1614. DB EGAColorDisplay ; 0010b, 0011b
  1615. DB MDADisplay ; 0100b, 0101b
  1616. DB CGADisplay ; 0110b, 0111b
  1617. DB EGAColorDisplay ; 1000b, 1001b
  1618. DB MDADisplay ; 1010b, 1011b
  1619. DCCtable DB 0,0 ; translate table for INT 10h func 1Ah
  1620. DB MDA,MDADisplay
  1621. DB CGA,CGADisplay
  1622. DB 0,0
  1623. DB EGA,EGAColorDisplay
  1624. DB EGA,MDADisplay
  1625. DB 0,0
  1626. DB VGA,PS2MonoDisplay
  1627. DB VGA,PS2ColorDisplay
  1628. DB 0,0
  1629. DB MCGA,EGAColorDisplay
  1630. DB MCGA,PS2MonoDisplay
  1631. DB MCGA,PS2ColorDisplay
  1632. TestSequence DB TRUE ; this list of flags and addresses
  1633. DW FindPS2 ; determines the order in which this
  1634. ; program looks for the various
  1635. EGAflag DB ? ; subsystems
  1636. DW FindEGA
  1637. CGAflag DB ?
  1638. DW FindCGA
  1639. Monoflag DB ?
  1640. DW FindMono
  1641. NumberOfTests EQU ($-TestSequence)/3
  1642. PUBLIC VideoID
  1643. VideoID PROC near
  1644. push bp ; preserve caller registers
  1645. mov bp,sp
  1646. push ds
  1647. push si
  1648. push di
  1649. push cs
  1650. pop ds
  1651. ASSUME DS:@Code
  1652. ; initialize the data structure that will contain the results
  1653. lea di,Results ; DS:DI -> start of data structure
  1654. mov Device0,0 ; zero these variables
  1655. mov Device1,0
  1656. ; look for the various subsystems using the subroutines whose addresses are
  1657. ; tabulated in TestSequence; each subroutine sets flags in TestSequence
  1658. ; to indicate whether subsequent subroutines need to be called
  1659. mov byte ptr CGAflag,TRUE
  1660. mov byte ptr EGAflag,TRUE
  1661. mov byte ptr Monoflag,TRUE
  1662. mov cx,NumberOfTests
  1663. mov si,offset TestSequence
  1664. @@L01: lodsb ; AL := flag
  1665. test al,al
  1666. lodsw ; AX := subroutine address
  1667. jz @@L02 ; skip subroutine if flag is false
  1668. push si
  1669. push cx
  1670. call ax ; call subroutine to detect subsystem
  1671. pop cx
  1672. pop si
  1673. @@L02: loop @@L01
  1674. ; determine which subsystem is active
  1675. call FindActive
  1676. mov al,Results.Video0Type
  1677. mov ah,0 ; was: Results.Display0Type
  1678. pop di ; restore caller registers and return
  1679. pop si
  1680. pop ds
  1681. mov sp,bp
  1682. pop bp
  1683. ret
  1684. VideoID ENDP
  1685. ;
  1686. ; FindPS2
  1687. ;
  1688. ; This subroutine uses INT 10H function 1Ah to determine the video BIOS
  1689. ; Display Combination Code (DCC) for each video subsystem present.
  1690. ;
  1691. FindPS2 PROC near
  1692. mov ax,1A00h
  1693. int 10h ; call video BIOS for info
  1694. cmp al,1Ah
  1695. jne @@L13 ; exit if function not supported (i.e.,
  1696. ; no MCGA or VGA in system)
  1697. ; convert BIOS DCCs into specific subsystems & displays
  1698. mov cx,bx
  1699. xor bh,bh ; BX := DCC for active subsystem
  1700. or ch,ch
  1701. jz @@L11 ; jump if only one subsystem present
  1702. mov bl,ch ; BX := inactive DCC
  1703. add bx,bx
  1704. mov ax,[bx+offset DCCtable]
  1705. mov Device1,ax
  1706. mov bl,cl
  1707. xor bh,bh ; BX := active DCC
  1708. @@L11: add bx,bx
  1709. mov ax,[bx+offset DCCtable]
  1710. mov Device0,ax
  1711. ; reset flags for subsystems that have been ruled out
  1712. mov byte ptr CGAflag,FALSE
  1713. mov byte ptr EGAflag,FALSE
  1714. mov byte ptr Monoflag,FALSE
  1715. lea bx,Video0Type[di] ; if the BIOS reported an MDA ...
  1716. cmp byte ptr [bx],MDA
  1717. je @@L12
  1718. lea bx,Video1Type[di]
  1719. cmp byte ptr [bx],MDA
  1720. jne @@L13
  1721. @@L12: mov word ptr [bx],0 ; ... Hercules can't be ruled out
  1722. mov byte ptr Monoflag,TRUE
  1723. @@L13: ret
  1724. FindPS2 ENDP
  1725. ;
  1726. ; FindEGA
  1727. ;
  1728. ; Look for an EGA. This is done by making a call to an EGA BIOS function
  1729. ; which doesn't exist in the default (MDA, CGA) BIOS.
  1730. FindEGA PROC near ; Caller: AH = flags
  1731. ; Returns: AH = flags
  1732. ; Video0Type and
  1733. ; Display0Type updated
  1734. mov bl,10h ; BL := 10h (return EGA info)
  1735. mov ah,12h ; AH := INT 10H function number
  1736. int 10h ; call EGA BIOS for info
  1737. ; if EGA BIOS is present,
  1738. ; BL <> 10H
  1739. ; CL = switch setting
  1740. cmp bl,10h
  1741. je @@L22 ; jump if EGA BIOS not present
  1742. mov al,cl
  1743. shr al,1 ; AL := switches/2
  1744. mov bx,offset EGADisplays
  1745. xlat ; determine display type from switches
  1746. mov ah,al ; AH := display type
  1747. mov al,EGA ; AL := subystem type
  1748. call FoundDevice
  1749. cmp ah,MDADisplay
  1750. je @@L21 ; jump if EGA has a monochrome display
  1751. mov CGAflag,FALSE ; no CGA if EGA has color display
  1752. jmp short @@L22
  1753. @@L21: mov Monoflag,FALSE ; EGA has a mono display, so MDA and
  1754. ; Hercules are ruled out
  1755. @@L22: ret
  1756. FindEGA ENDP
  1757. ;
  1758. ; FindCGA
  1759. ;
  1760. ; This is done by looking for the CGA's 6845 CRTC at I/O port 3D4H.
  1761. ;
  1762. FindCGA PROC near ; Returns: VIDstruct updated
  1763. mov dx,3D4h ; DX := CRTC address port
  1764. call Find6845
  1765. jc @@L31 ; jump if not present
  1766. mov al,CGA
  1767. mov ah,CGADisplay
  1768. call FoundDevice
  1769. @@L31: ret
  1770. FindCGA ENDP
  1771. ;
  1772. ; FindMono
  1773. ;
  1774. ; This is done by looking for the MDA's 6845 CRTC at I/O port 3B4H. If
  1775. ; a 6845 is found, the subroutine distinguishes between an MDA
  1776. ; and a Hercules adapter by monitoring bit 7 of the CRT Status byte.
  1777. ; This bit changes on Hercules adapters but does not change on an MDA.
  1778. ;
  1779. ; The various Hercules adapters are identified by bits 4 through 6 of
  1780. ; the CRT Status value:
  1781. ;
  1782. ; 000b = HGC
  1783. ; 001b = HGC+
  1784. ; 101b = InColor card
  1785. ;
  1786. FindMono PROC near ; Returns: VIDstruct updated
  1787. mov dx,3B4h ; DX := CRTC address port
  1788. call Find6845
  1789. jc @@L44 ; jump if not present
  1790. mov dl,0BAh ; DX := 3BAh (status port)
  1791. in al,dx
  1792. and al,80h
  1793. mov ah,al ; AH := bit 7 (vertical sync on HGC)
  1794. mov cx,8000h ; do this 32768 times
  1795. @@L41: in al,dx
  1796. and al,80h ; isolate bit 7
  1797. cmp ah,al
  1798. loope @@L41 ; wait for bit 7 to change
  1799. jne @@L42 ; if bit 7 changed, it's a Hercules
  1800. mov al,MDA ; if bit 7 didn't change, it's an MDA
  1801. mov ah,MDADisplay
  1802. call FoundDevice
  1803. jmp short @@L44
  1804. @@L42: in al,dx
  1805. mov dl,al ; DL := value from status port
  1806. and dl,01110000b ; mask bits 4 thru 6
  1807. mov ah,MDADisplay ; assume it's a monochrome display
  1808. mov al,HGCPlus ; look for an HGC+
  1809. cmp dl,00010000b
  1810. je @@L43 ; jump if it's an HGC+
  1811. mov al,HGC ; look for an InColor card or HGC
  1812. cmp dl,01010000b
  1813. jne @@L43 ; jump if it's not an InColor card
  1814. mov al,InColor ; it's an InColor card
  1815. mov ah,EGAColorDisplay
  1816. @@L43: call FoundDevice
  1817. @@L44: ret
  1818. FindMono ENDP
  1819. ;
  1820. ; Find6845
  1821. ;
  1822. ; This routine detects the presence of the CRTC on a MDA, CGA or HGC.
  1823. ; The technique is to write and read register 0Fh of the chip (cursor
  1824. ; low). If the same value is read as written, assume the chip is
  1825. ; present at the specified port addr.
  1826. ;
  1827. Find6845 PROC near ; Caller: DX = port addr
  1828. ; Returns: cf set if not present
  1829. mov al,0Fh
  1830. out dx,al ; select 6845 reg 0Fh (Cursor Low)
  1831. inc dx
  1832. in al,dx ; AL := current Cursor Low value
  1833. mov ah,al ; preserve in AH
  1834. mov al,66h ; AL := arbitrary value
  1835. out dx,al ; try to write to 6845
  1836. mov cx,100h
  1837. @@L51: loop @@L51 ; wait for 6845 to respond
  1838. in al,dx
  1839. xchg ah,al ; AH := returned value
  1840. ; AL := original value
  1841. out dx,al ; restore original value
  1842. cmp ah,66h ; test whether 6845 responded
  1843. je @@L52 ; jump if it did (cf is reset)
  1844. stc ; set carry flag if no 6845 present
  1845. @@L52: ret
  1846. Find6845 ENDP
  1847. ;
  1848. ; FindActive
  1849. ;
  1850. ; This subroutine stores the currently active device as Device0. The
  1851. ; current video mode determines which subsystem is active.
  1852. ;
  1853. FindActive PROC near
  1854. cmp word ptr Device1,0
  1855. je @@L63 ; exit if only one subsystem
  1856. cmp Video0Type[di],4 ; exit if MCGA or VGA present
  1857. jge @@L63 ; (INT 10H function 1AH
  1858. cmp Video1Type[di],4 ; already did the work)
  1859. jge @@L63
  1860. mov ah,0Fh
  1861. int 10h ; AL := current BIOS video mode
  1862. and al,7
  1863. cmp al,7 ; jump if monochrome
  1864. je @@L61 ; (mode 7 or 0Fh)
  1865. cmp Display0Type[di],MDADisplay
  1866. jne @@L63 ; exit if Display0 is color
  1867. jmp short @@L62
  1868. @@L61: cmp Display0Type[di],MDADisplay
  1869. je @@L63 ; exit if Display0 is monochrome
  1870. @@L62: mov ax,Device0 ; make Device0 currently active
  1871. xchg ax,Device1
  1872. mov Device0,ax
  1873. @@L63: ret
  1874. FindActive ENDP
  1875. ;
  1876. ; FoundDevice
  1877. ;
  1878. ; This routine updates the list of subsystems.
  1879. ;
  1880. FoundDevice PROC near ; Caller: AH = display #
  1881. ; AL = subsystem #
  1882. ; Destroys: BX
  1883. lea bx,Video0Type[di]
  1884. cmp byte ptr [bx],0
  1885. je @@L71 ; jump if 1st subsystem
  1886. lea bx,Video1Type[di] ; must be 2nd subsystem
  1887. @@L71: mov [bx],ax ; update list entry
  1888. ret
  1889. FoundDevice ENDP
  1890. ;============================================================================
  1891. IDEAL
  1892. DATASEG
  1893. tickcount dw ?
  1894. timecall dw ?
  1895. timeax dw ?
  1896. timebx dw ?
  1897. timecx dw ?
  1898. timedx dw ?
  1899. timesi dw ?
  1900. timedi dw ?
  1901. timebp dw ?
  1902. timees dw ?
  1903. PUBLIC timecall,timeax,timebx,timecx,timedx,timesi,timedi,timebp,timees
  1904. CODESEG
  1905. ;=============
  1906. ;
  1907. ; TIMESUB
  1908. ; Returns the number of iterations of the given subroutine
  1909. ; are possible in 1/18 second
  1910. ;
  1911. ;=============
  1912. PROC timesub ticks:WORD
  1913. USES si,di,bp
  1914. PUBLIC timesub
  1915. mov ax,[ticks]
  1916. mov [tickcount],ax
  1917. mov ax,351ch ;call bios to get int 1c
  1918. int 21h
  1919. mov [cs:@@old1c],bx
  1920. mov ax,es
  1921. mov [cs:@@old1c+2],ax
  1922. push ds
  1923. push cs
  1924. pop ds
  1925. lea dx,[@@intermark]
  1926. mov ax,251ch ;call bios to set int 1c
  1927. int 21h
  1928. pop ds
  1929. call stopsound ;make sure the timer is going normal speed
  1930. xor ax,ax
  1931. mov [cs:@@counter],ax ;set counter to 0
  1932. mov [cs:@@mark],ax ;will be inc to 1 after int 1c
  1933. @@wait1:
  1934. mov ax,[cs:@@mark] ;wait for the interrupt to go off once
  1935. cmp ax,0
  1936. je @@wait1
  1937. @@countmore:
  1938. xor ax,ax
  1939. mov [cs:@@mark],ax ;will be inc to 1 after int 1c
  1940. @@count:
  1941. push bp
  1942. mov ax,[timees]
  1943. mov es,ax
  1944. mov ax,[timeax]
  1945. mov bx,[timebx]
  1946. mov cx,[timecx]
  1947. mov dx,[timedx]
  1948. mov si,[timesi]
  1949. mov di,[timedi]
  1950. mov bp,[timebp]
  1951. call [timecall]
  1952. pop bp
  1953. inc [cs:@@counter]
  1954. mov ax,[cs:@@mark] ;has the interrupt gone off again?
  1955. or ax,ax
  1956. je @@count
  1957. dec [tickcount]
  1958. jne @@countmore
  1959. push ds
  1960. mov ax,[cs:@@old1c+2]
  1961. mov ds,ax
  1962. mov dx,[cs:@@old1c]
  1963. mov ax,251ch ;call bios to set int 1c
  1964. int 21h
  1965. pop ds
  1966. mov ax,[cs:@@counter] ;return value
  1967. ret
  1968. @@intermark:
  1969. inc [WORD cs:@@mark]
  1970. jmp [DWORD cs:@@old1C]
  1971. @@old1C dw 0,0 ;old [1Ch*4]
  1972. @@counter dw 0
  1973. @@mark dw 0 ;set to 1 when the int has occured
  1974. ENDP
  1975. END