ID_VW_AE.ASM 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901
  1. ; Catacomb Apocalypse 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. ;=================================
  18. ;
  19. ; EGA view manager routines
  20. ;
  21. ;=================================
  22. ;============================================================================
  23. ;
  24. ; All EGA drawing routines that write out words need to have alternate forms
  25. ; for starting on even and odd addresses, because writing a word at segment
  26. ; offset 0xffff causes an exception! To work around this, write a single
  27. ; byte out to make the address even, so it wraps cleanly at the end.
  28. ;
  29. ; All of these routines assume read/write mode 0, and will allways return
  30. ; in that state.
  31. ; The direction flag should be clear
  32. ; readmap/writemask is left in an undefined state
  33. ;
  34. ;============================================================================
  35. ;============================================================================
  36. ;
  37. ; VW_Plot (int x,y,color)
  38. ;
  39. ;============================================================================
  40. DATASEG
  41. plotpixels db 128,64,32,16,8,4,2,1
  42. CODESEG
  43. PROC VW_Plot x:WORD, y:WORD, color:WORD
  44. PUBLIC VW_Plot
  45. USES SI,DI
  46. mov es,[screenseg]
  47. mov dx,SC_INDEX
  48. mov ax,SC_MAPMASK+15*256
  49. WORDOUT
  50. mov dx,GC_INDEX
  51. mov ax,GC_MODE+2*256 ;write mode 2
  52. WORDOUT
  53. mov di,[bufferofs]
  54. mov bx,[y]
  55. shl bx,1
  56. add di,[ylookup+bx]
  57. mov bx,[x]
  58. mov ax,bx
  59. shr ax,1
  60. shr ax,1
  61. shr ax,1
  62. add di,ax ; di = byte on screen
  63. and bx,7
  64. mov ah,[plotpixels+bx]
  65. mov al,GC_BITMASK ;mask off other pixels
  66. WORDOUT
  67. mov bl,[BYTE color]
  68. xchg bl,[es:di] ; load latches and write pixel
  69. mov dx,GC_INDEX
  70. mov ah,0ffh ;no bit mask
  71. WORDOUT
  72. mov ax,GC_MODE+0*256 ;write mode 0
  73. WORDOUT
  74. ret
  75. ENDP
  76. ;============================================================================
  77. ;
  78. ; VW_Vlin (int yl,yh,x,color)
  79. ;
  80. ;============================================================================
  81. PROC VW_Vlin yl:WORD, yh:WORD, x:WORD, color:WORD
  82. PUBLIC VW_Vlin
  83. USES SI,DI
  84. mov es,[screenseg]
  85. mov dx,SC_INDEX
  86. mov ax,SC_MAPMASK+15*256
  87. WORDOUT
  88. mov dx,GC_INDEX
  89. mov ax,GC_MODE+2*256 ;write mode 2
  90. WORDOUT
  91. mov di,[bufferofs]
  92. mov bx,[yl]
  93. shl bx,1
  94. add di,[ylookup+bx]
  95. mov bx,[x]
  96. mov ax,bx
  97. shr ax,1
  98. shr ax,1
  99. shr ax,1
  100. add di,ax ; di = byte on screen
  101. and bx,7
  102. mov ah,[plotpixels+bx]
  103. mov al,GC_BITMASK ;mask off other pixels
  104. WORDOUT
  105. mov cx,[yh]
  106. sub cx,[yl]
  107. inc cx ;number of pixels to plot
  108. mov bh,[BYTE color]
  109. mov dx,[linewidth]
  110. @@plot:
  111. mov bl,bh
  112. xchg bl,[es:di] ; load latches and write pixel
  113. add di,dx
  114. loop @@plot
  115. mov dx,GC_INDEX
  116. mov ah,0ffh ;no bit mask
  117. WORDOUT
  118. mov ax,GC_MODE+0*256 ;write mode 0
  119. WORDOUT
  120. ret
  121. ENDP
  122. ;============================================================================
  123. ;===================
  124. ;
  125. ; VW_DrawTile8
  126. ;
  127. ; xcoord in bytes (8 pixels), ycoord in pixels
  128. ; All Tile8s are in one grseg, so an offset is calculated inside it
  129. ;
  130. ;===================
  131. PROC VW_DrawTile8 xcoord:WORD, ycoord:WORD, tile:WORD
  132. PUBLIC VW_DrawTile8
  133. USES SI,DI
  134. mov es,[screenseg]
  135. mov di,[bufferofs]
  136. add di,[xcoord]
  137. mov bx,[ycoord]
  138. shl bx,1
  139. add di,[ylookup+bx]
  140. mov [ss:screendest],di ;screen destination
  141. mov bx,[linewidth]
  142. dec bx
  143. mov si,[tile]
  144. shl si,1
  145. shl si,1
  146. shl si,1
  147. shl si,1
  148. shl si,1
  149. mov ds,[grsegs+STARTTILE8*2] ; segment for all tile8s
  150. mov cx,4 ;planes to draw
  151. mov ah,0001b ;map mask
  152. mov dx,SC_INDEX
  153. mov al,SC_MAPMASK
  154. ;
  155. ; start drawing
  156. ;
  157. @@planeloop:
  158. WORDOUT
  159. shl ah,1 ;shift plane mask over for next plane
  160. mov di,[ss:screendest] ;start at same place in all planes
  161. REPT 7
  162. movsb
  163. add di,bx
  164. ENDM
  165. movsb
  166. loop @@planeloop
  167. mov ax,ss
  168. mov ds,ax ;restore turbo's data segment
  169. ret
  170. ENDP
  171. ;============================================================================
  172. ;
  173. ; VW_MaskBlock
  174. ;
  175. ; Draws a masked block shape to the screen. bufferofs is NOT accounted for.
  176. ; The mask comes first, then four planes of data.
  177. ;
  178. ;============================================================================
  179. DATASEG
  180. UNWOUNDMASKS = 10
  181. maskroutines dw mask0,mask0,mask1E,mask1E,mask2E,mask2O,mask3E,mask3O
  182. dw mask4E,mask4O,mask5E,mask5O,mask6E,mask6O
  183. dw mask7E,mask7O,mask8E,mask8O,mask9E,mask9O
  184. dw mask10E,mask10O
  185. routinetouse dw ?
  186. CODESEG
  187. PROC VW_MaskBlock segm:WORD, ofs:WORD, dest:WORD, wide:WORD, height:WORD, planesize:WORD
  188. PUBLIC VW_MaskBlock
  189. USES SI,DI
  190. mov es,[screenseg]
  191. mov [BYTE planemask],1
  192. mov [BYTE planenum],0
  193. mov di,[wide]
  194. mov dx,[linewidth]
  195. sub dx,[wide]
  196. mov [linedelta],dx ;amount to add after drawing each line
  197. mov bx,[planesize] ; si+bx = data location
  198. cmp di,UNWOUNDMASKS
  199. jbe @@unwoundroutine
  200. mov [routinetouse],OFFSET generalmask
  201. jmp NEAR @@startloop
  202. ;=================
  203. ;
  204. ; use the unwound routines
  205. ;
  206. ;=================
  207. @@unwoundroutine:
  208. mov cx,[dest]
  209. shr cx,1
  210. rcl di,1 ;shift a 1 in if destination is odd
  211. shl di,1 ;to index into a word width table
  212. mov ax,[maskroutines+di] ;call the right routine
  213. mov [routinetouse],ax
  214. @@startloop:
  215. mov ds,[segm]
  216. @@drawplane:
  217. mov dx,SC_INDEX
  218. mov al,SC_MAPMASK
  219. mov ah,[ss:planemask]
  220. WORDOUT
  221. mov dx,GC_INDEX
  222. mov al,GC_READMAP
  223. mov ah,[ss:planenum]
  224. WORDOUT
  225. mov si,[ofs] ;start back at the top of the mask
  226. mov di,[dest] ;start at same place in all planes
  227. mov cx,[height] ;scan lines to draw
  228. mov dx,[ss:linedelta]
  229. jmp [ss:routinetouse] ;draw one plane
  230. planereturn: ;routine jmps back here
  231. add bx,[ss:planesize] ;start of mask = start of next plane
  232. inc [ss:planenum]
  233. shl [ss:planemask],1 ;shift plane mask over for next plane
  234. cmp [ss:planemask],10000b ;done all four planes?
  235. jne @@drawplane
  236. mask0:
  237. mov ax,ss
  238. mov ds,ax
  239. ret ;width of 0 = no drawing
  240. ;==============
  241. ;
  242. ; General purpose masked block drawing. This could be optimised into
  243. ; four routines to use words, but few play loop sprites should be this big!
  244. ;
  245. ;==============
  246. generalmask:
  247. mov dx,cx
  248. @@lineloopgen:
  249. mov cx,[wide]
  250. @@byteloop:
  251. mov al,[es:di]
  252. and al,[si]
  253. or al,[bx+si]
  254. inc si
  255. stosb
  256. loop @@byteloop
  257. add di,[ss:linedelta]
  258. dec dx
  259. jnz @@lineloopgen
  260. jmp planereturn
  261. ;=================
  262. ;
  263. ; Horizontally unwound routines to draw certain masked blocks faster
  264. ;
  265. ;=================
  266. MACRO MASKBYTE
  267. mov al,[es:di]
  268. and al,[si]
  269. or al,[bx+si]
  270. inc si
  271. stosb
  272. ENDM
  273. MACRO MASKWORD
  274. mov ax,[es:di]
  275. and ax,[si]
  276. or ax,[bx+si]
  277. inc si
  278. inc si
  279. stosw
  280. ENDM
  281. MACRO SPRITELOOP addr
  282. add di,dx
  283. loop addr
  284. jmp planereturn
  285. ENDM
  286. EVEN
  287. mask1E:
  288. MASKBYTE
  289. SPRITELOOP mask1E
  290. EVEN
  291. mask2E:
  292. MASKWORD
  293. SPRITELOOP mask2E
  294. EVEN
  295. mask2O:
  296. MASKBYTE
  297. MASKBYTE
  298. SPRITELOOP mask2O
  299. EVEN
  300. mask3E:
  301. MASKWORD
  302. MASKBYTE
  303. SPRITELOOP mask3E
  304. EVEN
  305. mask3O:
  306. MASKBYTE
  307. MASKWORD
  308. SPRITELOOP mask3O
  309. EVEN
  310. mask4E:
  311. MASKWORD
  312. MASKWORD
  313. SPRITELOOP mask4E
  314. EVEN
  315. mask4O:
  316. MASKBYTE
  317. MASKWORD
  318. MASKBYTE
  319. SPRITELOOP mask4O
  320. EVEN
  321. mask5E:
  322. MASKWORD
  323. MASKWORD
  324. MASKBYTE
  325. SPRITELOOP mask5E
  326. EVEN
  327. mask5O:
  328. MASKBYTE
  329. MASKWORD
  330. MASKWORD
  331. SPRITELOOP mask5O
  332. EVEN
  333. mask6E:
  334. MASKWORD
  335. MASKWORD
  336. MASKWORD
  337. SPRITELOOP mask6E
  338. EVEN
  339. mask6O:
  340. MASKBYTE
  341. MASKWORD
  342. MASKWORD
  343. MASKBYTE
  344. SPRITELOOP mask6O
  345. EVEN
  346. mask7E:
  347. MASKWORD
  348. MASKWORD
  349. MASKWORD
  350. MASKBYTE
  351. SPRITELOOP mask7E
  352. EVEN
  353. mask7O:
  354. MASKBYTE
  355. MASKWORD
  356. MASKWORD
  357. MASKWORD
  358. SPRITELOOP mask7O
  359. EVEN
  360. mask8E:
  361. MASKWORD
  362. MASKWORD
  363. MASKWORD
  364. MASKWORD
  365. SPRITELOOP mask8E
  366. EVEN
  367. mask8O:
  368. MASKBYTE
  369. MASKWORD
  370. MASKWORD
  371. MASKWORD
  372. MASKBYTE
  373. SPRITELOOP mask8O
  374. EVEN
  375. mask9E:
  376. MASKWORD
  377. MASKWORD
  378. MASKWORD
  379. MASKWORD
  380. MASKBYTE
  381. SPRITELOOP mask9E
  382. EVEN
  383. mask9O:
  384. MASKBYTE
  385. MASKWORD
  386. MASKWORD
  387. MASKWORD
  388. MASKWORD
  389. SPRITELOOP mask9O
  390. EVEN
  391. mask10E:
  392. MASKWORD
  393. MASKWORD
  394. MASKWORD
  395. MASKWORD
  396. MASKWORD
  397. SPRITELOOP mask10E
  398. EVEN
  399. mask10O:
  400. MASKBYTE
  401. MASKWORD
  402. MASKWORD
  403. MASKWORD
  404. MASKWORD
  405. MASKBYTE
  406. SPRITELOOP mask10O
  407. ENDP
  408. ;============================================================================
  409. ;
  410. ; VW_ScreenToScreen
  411. ;
  412. ; Basic block copy routine. Copies one block of screen memory to another,
  413. ; using write mode 1 (sets it and returns with write mode 0). bufferofs is
  414. ; NOT accounted for.
  415. ;
  416. ;============================================================================
  417. PROC VW_ScreenToScreen source:WORD, dest:WORD, wide:WORD, height:WORD
  418. PUBLIC VW_ScreenToScreen
  419. USES SI,DI
  420. pushf
  421. cli
  422. mov dx,SC_INDEX
  423. mov ax,SC_MAPMASK+15*256
  424. WORDOUT
  425. mov dx,GC_INDEX
  426. mov ax,GC_MODE+1*256
  427. WORDOUT
  428. popf
  429. mov bx,[linewidth]
  430. sub bx,[wide]
  431. mov ax,[screenseg]
  432. mov es,ax
  433. mov ds,ax
  434. mov si,[source]
  435. mov di,[dest] ;start at same place in all planes
  436. mov dx,[height] ;scan lines to draw
  437. mov ax,[wide]
  438. @@lineloop:
  439. mov cx,ax
  440. rep movsb
  441. add si,bx
  442. add di,bx
  443. dec dx
  444. jnz @@lineloop
  445. mov dx,GC_INDEX
  446. mov ax,GC_MODE+0*256
  447. WORDOUT
  448. mov ax,ss
  449. mov ds,ax ;restore turbo's data segment
  450. ret
  451. ENDP
  452. ;============================================================================
  453. ;
  454. ; VW_MemToScreen
  455. ;
  456. ; Basic block drawing routine. Takes a block shape at segment pointer source
  457. ; with four planes of width by height data, and draws it to dest in the
  458. ; virtual screen, based on linewidth. bufferofs is NOT accounted for.
  459. ; There are four drawing routines to provide the best optimized code while
  460. ; accounting for odd segment wrappings due to the floating screens.
  461. ;
  462. ;============================================================================
  463. DATASEG
  464. memtoscreentable dw eventoeven,eventoodd,oddtoeven,oddtoodd
  465. CODESEG
  466. PROC VW_MemToScreen source:WORD, dest:WORD, wide:WORD, height:WORD
  467. PUBLIC VW_MemToScreen
  468. USES SI,DI
  469. mov es,[screenseg]
  470. mov bx,[linewidth]
  471. sub bx,[wide]
  472. mov ds,[source]
  473. xor si,si ;block is segment aligned
  474. xor di,di
  475. shr [wide],1 ;change wide to words, and see if carry is set
  476. rcl di,1 ;1 if wide is odd
  477. mov ax,[dest]
  478. shr ax,1
  479. rcl di,1 ;shift a 1 in if destination is odd
  480. shl di,1 ;to index into a word width table
  481. mov ax,SC_MAPMASK+0001b*256 ;map mask for plane 0
  482. jmp [ss:memtoscreentable+di] ;call the right routine
  483. ;==============
  484. ;
  485. ; Copy an even width block to an even video address
  486. ;
  487. ;==============
  488. eventoeven:
  489. mov dx,SC_INDEX
  490. WORDOUT
  491. mov di,[dest] ;start at same place in all planes
  492. mov dx,[height] ;scan lines to draw
  493. @@lineloopEE:
  494. mov cx,[wide]
  495. rep movsw
  496. add di,bx
  497. dec dx
  498. jnz @@lineloopEE
  499. shl ah,1 ;shift plane mask over for next plane
  500. cmp ah,10000b ;done all four planes?
  501. jne eventoeven
  502. mov ax,ss
  503. mov ds,ax ;restore turbo's data segment
  504. ret
  505. ;==============
  506. ;
  507. ; Copy an odd width block to an even video address
  508. ;
  509. ;==============
  510. oddtoeven:
  511. mov dx,SC_INDEX
  512. WORDOUT
  513. mov di,[dest] ;start at same place in all planes
  514. mov dx,[height] ;scan lines to draw
  515. @@lineloopOE:
  516. mov cx,[wide]
  517. rep movsw
  518. movsb ;copy the last byte
  519. add di,bx
  520. dec dx
  521. jnz @@lineloopOE
  522. shl ah,1 ;shift plane mask over for next plane
  523. cmp ah,10000b ;done all four planes?
  524. jne oddtoeven
  525. mov ax,ss
  526. mov ds,ax ;restore turbo's data segment
  527. ret
  528. ;==============
  529. ;
  530. ; Copy an even width block to an odd video address
  531. ;
  532. ;==============
  533. eventoodd:
  534. dec [wide] ;one word has to be handled seperately
  535. EOplaneloop:
  536. mov dx,SC_INDEX
  537. WORDOUT
  538. mov di,[dest] ;start at same place in all planes
  539. mov dx,[height] ;scan lines to draw
  540. @@lineloopEO:
  541. movsb
  542. mov cx,[wide]
  543. rep movsw
  544. movsb
  545. add di,bx
  546. dec dx
  547. jnz @@lineloopEO
  548. shl ah,1 ;shift plane mask over for next plane
  549. cmp ah,10000b ;done all four planes?
  550. jne EOplaneloop
  551. mov ax,ss
  552. mov ds,ax ;restore turbo's data segment
  553. ret
  554. ;==============
  555. ;
  556. ; Copy an odd width block to an odd video address
  557. ;
  558. ;==============
  559. oddtoodd:
  560. mov dx,SC_INDEX
  561. WORDOUT
  562. mov di,[dest] ;start at same place in all planes
  563. mov dx,[height] ;scan lines to draw
  564. @@lineloopOO:
  565. movsb
  566. mov cx,[wide]
  567. rep movsw
  568. add di,bx
  569. dec dx
  570. jnz @@lineloopOO
  571. shl ah,1 ;shift plane mask over for next plane
  572. cmp ah,10000b ;done all four planes?
  573. jne oddtoodd
  574. mov ax,ss
  575. mov ds,ax ;restore turbo's data segment
  576. ret
  577. ENDP
  578. ; MDM (GAMERS EDGE) begin
  579. MACRO XPAND_BYTE
  580. test al,128 ; handle bit 7
  581. jne @@over7
  582. or [BYTE PTR es:di],11000000b
  583. @@over7:
  584. test al,64 ; handle bit 6
  585. jne @@over6
  586. or [BYTE PTR es:di],00110000b
  587. @@over6:
  588. test al,32 ; handle bit 5
  589. jne @@over5
  590. or [BYTE PTR es:di],00001100b
  591. @@over5:
  592. test al,16 ; handle bit 4
  593. jne @@over4
  594. or [BYTE PTR es:di],00000011b
  595. @@over4:
  596. inc di ; inc destination
  597. test al,8 ; handle bit 3
  598. jne @@over3
  599. or [BYTE PTR es:di],11000000b
  600. @@over3:
  601. test al,4 ; handle bit 2
  602. jne @@over2
  603. or [BYTE PTR es:di],00110000b
  604. @@over2:
  605. test al,2 ; handle bit 1
  606. jne @@over1
  607. or [BYTE PTR es:di],00001100b
  608. @@over1:
  609. test al,1 ; handle bit 0
  610. jne @@over0
  611. or [BYTE PTR es:di],00000011b
  612. @@over0:
  613. inc si ; inc source
  614. inc di ; inc destination
  615. ENDM
  616. ;============================================================================
  617. ;
  618. ; VW_MemToScreen2x
  619. ;
  620. ; Basic block drawing routine. Takes a block shape at segment pointer source
  621. ; with four planes of width by height data, and draws it to dest in the
  622. ; virtual screen, based on linewidth. bufferofs is NOT accounted for.
  623. ; There are four drawing routines to provide the best optimized code while
  624. ; accounting for odd segment wrappings due to the floating screens.
  625. ;
  626. ;============================================================================
  627. DATASEG
  628. xpandhorz db 00000000b,00000011b,00001100b,00001111b
  629. db 00110000b,00110011b,00111100b,00111111b
  630. db 11000000b,11000011b,11001100b,11001111b
  631. db 11110000b,11110011b,11111100b,11111111b
  632. CODESEG
  633. PROC VW_MemToScreen2x source:WORD, dest:WORD, wide:WORD, height:WORD
  634. PUBLIC VW_MemToScreen2x
  635. USES SI,DI
  636. mov es,[screenseg]
  637. mov bx,[linewidth]
  638. sub bx,[wide]
  639. sub bx,[wide]
  640. mov ds,[source]
  641. xor si,si ;block is segment aligned
  642. mov ah,0001b ;map mask for plane 0
  643. @@depthloop:
  644. mov al,SC_MAPMASK ;restore map mask in al
  645. mov dx,SC_INDEX
  646. WORDOUT
  647. mov di,[dest] ;start at same place in all planes
  648. mov dx,[height] ;scan lines to draw
  649. @@heightloop:
  650. mov cx,[wide]
  651. @@widthloop:
  652. ; handle first nybble
  653. ;
  654. push di
  655. mov di,[si]
  656. shr di,1
  657. shr di,1
  658. shr di,1
  659. shr di,1
  660. and di,15
  661. mov al,[ss:xpandhorz+di]
  662. pop di
  663. mov [es:di],al
  664. inc di
  665. ; handle second nybble
  666. ;
  667. push di
  668. mov di,[si]
  669. and di,15
  670. mov al,[ss:xpandhorz+di]
  671. pop di
  672. mov [es:di],al
  673. inc si
  674. inc di
  675. dec cx
  676. jne @@widthloop
  677. add di,bx
  678. dec dx
  679. jnz @@heightloop
  680. shl ah,1 ;shift plane mask over for next plane
  681. cmp ah,10000b ;done all four planes?
  682. jne @@depthloop
  683. mov ax,ss
  684. mov ds,ax ;restore turbo's data segment
  685. ret
  686. ENDP
  687. ; MDM (GAMERS EDGE) end
  688. ;===========================================================================
  689. ;
  690. ; VW_ScreenToMem
  691. ;
  692. ; Copies a block of video memory to main memory, in order from planes 0-3.
  693. ; This could be optimized along the lines of VW_MemToScreen to take advantage
  694. ; of word copies, but this is an infrequently called routine.
  695. ;
  696. ;===========================================================================
  697. PROC VW_ScreenToMem source:WORD, dest:WORD, wide:WORD, height:WORD
  698. PUBLIC VW_ScreenToMem
  699. USES SI,DI
  700. mov es,[dest]
  701. mov bx,[linewidth]
  702. sub bx,[wide]
  703. mov ds,[screenseg]
  704. mov ax,GC_READMAP ;read map for plane 0
  705. xor di,di
  706. @@planeloop:
  707. mov dx,GC_INDEX
  708. WORDOUT
  709. mov si,[source] ;start at same place in all planes
  710. mov dx,[height] ;scan lines to draw
  711. @@lineloop:
  712. mov cx,[wide]
  713. rep movsb
  714. add si,bx
  715. dec dx
  716. jnz @@lineloop
  717. inc ah
  718. cmp ah,4 ;done all four planes?
  719. jne @@planeloop
  720. mov ax,ss
  721. mov ds,ax ;restore turbo's data segment
  722. ret
  723. ENDP
  724. ;============================================================================
  725. ;
  726. ; VWL_UpdateScreenBlocks
  727. ;
  728. ; Scans through the update matrix and copies any areas that have changed
  729. ; to the visable screen, then zeros the update array
  730. ;
  731. ;============================================================================
  732. ; AX 0/1 for scasb, temp for segment register transfers
  733. ; BX width for block copies
  734. ; CX REP counter
  735. ; DX line width deltas
  736. ; SI source for copies
  737. ; DI scas dest / movsb dest
  738. ; BP pointer to end of bufferblocks
  739. PROC VWL_UpdateScreenBlocks
  740. PUBLIC VWL_UpdateScreenBlocks
  741. USES SI,DI,BP
  742. jmp SHORT @@realstart
  743. @@done:
  744. ;
  745. ; all tiles have been scanned
  746. ;
  747. mov dx,GC_INDEX ; restore write mode 0
  748. mov ax,GC_MODE+0*256
  749. WORDOUT
  750. xor ax,ax ; clear out the update matrix
  751. mov cx,UPDATEWIDE*UPDATEHIGH/2
  752. mov di,[updateptr]
  753. rep stosw
  754. ret
  755. @@realstart:
  756. mov dx,SC_INDEX
  757. mov ax,SC_MAPMASK+15*256
  758. WORDOUT
  759. mov dx,GC_INDEX
  760. mov ax,GC_MODE+1*256
  761. WORDOUT
  762. mov di,[updateptr] ; start of floating update screen
  763. mov bp,di
  764. add bp,UPDATEWIDE*UPDATEHIGH+1 ; when di = bp, all tiles have been scanned
  765. push di
  766. mov cx,-1 ; definately scan the entire thing
  767. ;
  768. ; scan for a 1 in the update list, meaning a tile needs to be copied
  769. ; from the master screen to the current screen
  770. ;
  771. @@findtile:
  772. pop di ; place to continue scaning from
  773. mov ax,ss
  774. mov es,ax ; search in the data segment
  775. mov ds,ax
  776. mov al,1
  777. repne scasb
  778. cmp di,bp
  779. jae @@done
  780. cmp [BYTE di],al
  781. jne @@singletile
  782. jmp @@tileblock
  783. ;============
  784. ;
  785. ; copy a single tile
  786. ;
  787. ;============
  788. @@singletile:
  789. inc di ; we know the next tile is nothing
  790. push di ; save off the spot being scanned
  791. sub di,[updateptr]
  792. shl di,1
  793. mov di,[blockstarts-4+di] ; start of tile location on screen
  794. mov si,di
  795. add si,[bufferofs]
  796. add di,[displayofs]
  797. mov dx,[linewidth]
  798. sub dx,2
  799. mov ax,[screenseg]
  800. mov ds,ax
  801. mov es,ax
  802. REPT 15
  803. movsb
  804. movsb
  805. add si,dx
  806. add di,dx
  807. ENDM
  808. movsb
  809. movsb
  810. jmp @@findtile
  811. ;============
  812. ;
  813. ; more than one tile in a row needs to be updated, so do it as a group
  814. ;
  815. ;============
  816. EVEN
  817. @@tileblock:
  818. mov dx,di ; hold starting position + 1 in dx
  819. inc di ; we know the next tile also gets updated
  820. repe scasb ; see how many more in a row
  821. push di ; save off the spot being scanned
  822. mov bx,di
  823. sub bx,dx ; number of tiles in a row
  824. shl bx,1 ; number of bytes / row
  825. mov di,dx ; lookup position of start tile
  826. sub di,[updateptr]
  827. shl di,1
  828. mov di,[blockstarts-2+di] ; start of tile location
  829. mov si,di
  830. add si,[bufferofs]
  831. add di,[displayofs]
  832. mov dx,[linewidth]
  833. sub dx,bx ; offset to next line on screen
  834. mov ax,[screenseg]
  835. mov ds,ax
  836. mov es,ax
  837. REPT 15
  838. mov cx,bx
  839. rep movsb
  840. add si,dx
  841. add di,dx
  842. ENDM
  843. mov cx,bx
  844. rep movsb
  845. dec cx ; was 0 from last rep movsb, now $ffff for scasb
  846. jmp @@findtile
  847. ENDP
  848. ;===========================================================================
  849. ;
  850. ; MISC EGA ROUTINES
  851. ;
  852. ;===========================================================================
  853. ;==============
  854. ;
  855. ; VW_SetScreen
  856. ;
  857. ;==============
  858. PROC VW_SetScreen crtc:WORD, pel:WORD
  859. PUBLIC VW_SetScreen
  860. if waitforvbl
  861. mov dx,STATUS_REGISTER_1
  862. ;
  863. ; wait util the CRTC just starts scaning a diplayed line to set the CRTC start
  864. ;
  865. cli
  866. @@waitnodisplay:
  867. in al,dx
  868. test al,1
  869. jz @@waitnodisplay
  870. ; the display is now disabled (in a HBL / VBL)
  871. @@waitdisplay:
  872. in al,dx
  873. test al,1 ;1 = display is disabled (HBL / VBL)
  874. jnz @@waitdisplay
  875. ; the display was just enabled, so a full scan line is available for CRTC set
  876. endif
  877. ;
  878. ; set CRTC start
  879. ;
  880. ; for some reason, my XT's EGA card doesn't like word outs to the CRTC
  881. ; index...
  882. ;
  883. mov cx,[crtc]
  884. mov dx,CRTC_INDEX
  885. mov al,0ch ;start address high register
  886. out dx,al
  887. inc dx
  888. mov al,ch
  889. out dx,al
  890. dec dx
  891. mov al,0dh ;start address low register
  892. out dx,al
  893. mov al,cl
  894. inc dx
  895. out dx,al
  896. if waitforvbl
  897. ;
  898. ; wait for a vertical retrace to set pel panning
  899. ;
  900. mov dx,STATUS_REGISTER_1
  901. @@waitvbl:
  902. sti ;service interrupts
  903. jmp $+2
  904. cli
  905. in al,dx
  906. test al,00001000b ;look for vertical retrace
  907. jz @@waitvbl
  908. endif
  909. ;
  910. ; set horizontal panning
  911. ;
  912. mov dx,ATR_INDEX
  913. mov al,ATR_PELPAN or 20h
  914. out dx,al
  915. jmp $+2
  916. mov al,[BYTE pel] ;pel pan value
  917. out dx,al
  918. sti
  919. ret
  920. ENDP
  921. if NUMFONT+NUMFONTM
  922. ;===========================================================================
  923. ;
  924. ; GENERAL FONT DRAWING ROUTINES
  925. ;
  926. ;===========================================================================
  927. DATASEG
  928. px dw ? ; proportional character drawing coordinates
  929. py dw ?
  930. pdrawmode db 11000b ; 8 = OR, 24 = XOR, put in GC_DATAROTATE
  931. fontcolor db 15 ;0-15 mapmask value
  932. PUBLIC px,py,pdrawmode,fontcolor
  933. ;
  934. ; offsets in font structure
  935. ;
  936. pcharheight = 0 ;lines high
  937. charloc = 2 ;pointers to every character
  938. charwidth = 514 ;every character's width in pixels
  939. propchar dw ? ; the character number to shift
  940. stringptr dw ?,?
  941. BUFFWIDTH = 82 ; MDM (GAMERS EDGE) - increased from 50
  942. BUFFHEIGHT = 20 ; must be twice as high as font for masked fonts
  943. databuffer db BUFFWIDTH*BUFFHEIGHT dup (?)
  944. bufferwidth dw ? ; bytes with valid info / line
  945. bufferheight dw ? ; number of lines currently used
  946. bufferbyte dw ?
  947. bufferbit dw ?
  948. screenspot dw ? ; where the buffer is going
  949. bufferextra dw ? ; add at end of a line copy
  950. screenextra dw ?
  951. PUBLIC bufferwidth,bufferheight,screenspot
  952. CODESEG
  953. ;======================
  954. ;
  955. ; Macros to table shift a byte of font
  956. ;
  957. ;======================
  958. MACRO SHIFTNOXOR
  959. mov al,[es:bx] ; source
  960. xor ah,ah
  961. shl ax,1
  962. mov si,ax
  963. mov ax,[bp+si] ; table shift into two bytes
  964. or [di],al ; or with first byte
  965. inc di
  966. mov [di],ah ; replace next byte
  967. inc bx ; next source byte
  968. ENDM
  969. MACRO SHIFTWITHXOR
  970. mov al,[es:bx] ; source
  971. xor ah,ah
  972. shl ax,1
  973. mov si,ax
  974. mov ax,[bp+si] ; table shift into two bytes
  975. not ax
  976. and [di],al ; and with first byte
  977. inc di
  978. mov [di],ah ; replace next byte
  979. inc bx ; next source byte
  980. ENDM
  981. ;=======================
  982. ;
  983. ; BufferToScreen
  984. ;
  985. ; Pass buffer start in SI (somewhere in databuffer)
  986. ; Draws the buffer to the EGA screen in the current write mode
  987. ;
  988. ;========================
  989. PROC BufferToScreen NEAR
  990. mov es,[screenseg]
  991. mov di,[screenspot]
  992. mov bx,[bufferwidth] ;calculate offsets for end of each line
  993. or bx,bx
  994. jnz @@isthere
  995. ret ;nothing to draw
  996. @@isthere:
  997. mov ax,[linewidth]
  998. sub ax,bx
  999. mov [screenextra],ax
  1000. mov ax,BUFFWIDTH
  1001. sub ax,bx
  1002. mov [bufferextra],ax
  1003. mov bx,[bufferheight] ;lines to copy
  1004. @@lineloop:
  1005. mov cx,[bufferwidth] ;bytes to copy
  1006. @@byteloop:
  1007. lodsb ;get a byte from the buffer
  1008. xchg [es:di],al ;load latches and store back to screen
  1009. inc di
  1010. loop @@byteloop
  1011. add si,[bufferextra]
  1012. add di,[screenextra]
  1013. dec bx
  1014. jnz @@lineloop
  1015. ret
  1016. ENDP
  1017. ;============================================================================
  1018. ;
  1019. ; NON MASKED FONT DRAWING ROUTINES
  1020. ;
  1021. ;============================================================================
  1022. if numfont
  1023. DATASEG
  1024. shiftdrawtable dw 0,shift1wide,shift2wide,shift3wide,shift4wide
  1025. dw shift5wide
  1026. CODESEG
  1027. ;==================
  1028. ;
  1029. ; ShiftPropChar
  1030. ;
  1031. ; Call with BX = character number (0-255)
  1032. ; Draws one character to the buffer at bufferbyte/bufferbit, and adjusts
  1033. ; them to the new position
  1034. ;
  1035. ;==================
  1036. PROC ShiftPropChar NEAR
  1037. mov si,[fontnumber]
  1038. shl si,1
  1039. mov es,[grsegs+STARTFONT*2+si] ;segment of font to use
  1040. ;
  1041. ; find character location, width, and height
  1042. ;
  1043. mov si,[es:charwidth+bx]
  1044. and si,0ffh ;SI hold width in pixels
  1045. shl bx,1
  1046. mov bx,[es:charloc+bx] ;BX holds pointer to character data
  1047. ;
  1048. ; look up which shift table to use, based on bufferbit
  1049. ;
  1050. mov di,[bufferbit]
  1051. shl di,1
  1052. mov bp,[shifttabletable+di] ;BP holds pointer to shift table
  1053. mov di,OFFSET databuffer
  1054. add di,[bufferbyte] ;DI holds pointer to buffer
  1055. ;
  1056. ; advance position by character width
  1057. ;
  1058. mov cx,[bufferbit]
  1059. add cx,si ;new bit position
  1060. mov ax,cx
  1061. and ax,7
  1062. mov [bufferbit],ax ;new bit position
  1063. mov ax,cx
  1064. shr ax,1
  1065. shr ax,1
  1066. shr ax,1
  1067. add [bufferbyte],ax ;new byte position
  1068. add si,7
  1069. shr si,1
  1070. shr si,1
  1071. shr si,1 ;bytes the character is wide
  1072. shl si,1 ;*2 to look up in shiftdrawtable
  1073. mov cx,[es:pcharheight]
  1074. mov dx,BUFFWIDTH
  1075. jmp [ss:shiftdrawtable+si] ;procedure to draw this width
  1076. ;
  1077. ; one byte character
  1078. ;
  1079. shift1wide:
  1080. dec dx
  1081. EVEN
  1082. @@loop1:
  1083. SHIFTNOXOR
  1084. add di,dx ; next line in buffer
  1085. loop @@loop1
  1086. ret
  1087. ;
  1088. ; two byte character
  1089. ;
  1090. shift2wide:
  1091. dec dx
  1092. dec dx
  1093. EVEN
  1094. @@loop2:
  1095. SHIFTNOXOR
  1096. SHIFTNOXOR
  1097. add di,dx ; next line in buffer
  1098. loop @@loop2
  1099. ret
  1100. ;
  1101. ; three byte character
  1102. ;
  1103. shift3wide:
  1104. sub dx,3
  1105. EVEN
  1106. @@loop3:
  1107. SHIFTNOXOR
  1108. SHIFTNOXOR
  1109. SHIFTNOXOR
  1110. add di,dx ; next line in buffer
  1111. loop @@loop3
  1112. ret
  1113. ;
  1114. ; four byte character
  1115. ;
  1116. shift4wide:
  1117. sub dx,4
  1118. EVEN
  1119. @@loop4:
  1120. SHIFTNOXOR
  1121. SHIFTNOXOR
  1122. SHIFTNOXOR
  1123. SHIFTNOXOR
  1124. add di,dx ; next line in buffer
  1125. loop @@loop4
  1126. ret
  1127. ;
  1128. ; five byte character
  1129. ;
  1130. shift5wide:
  1131. sub dx,5
  1132. EVEN
  1133. @@loop5:
  1134. SHIFTNOXOR
  1135. SHIFTNOXOR
  1136. SHIFTNOXOR
  1137. SHIFTNOXOR
  1138. add di,dx ; next line in buffer
  1139. loop @@loop5
  1140. ret
  1141. ENDP
  1142. ;============================================================================
  1143. ;==================
  1144. ;
  1145. ; VW_DrawPropString
  1146. ;
  1147. ; Draws a C string of characters at px/py and advances px
  1148. ;
  1149. ; Assumes write mode 0
  1150. ;
  1151. ;==================
  1152. CODESEG
  1153. PROC VW_DrawPropString string:DWORD
  1154. PUBLIC VW_DrawPropString
  1155. USES SI,DI
  1156. ;
  1157. ; proportional spaceing, which clears the buffer ahead of it, so only
  1158. ; clear the first collumn
  1159. ;
  1160. mov al,0
  1161. line = 0
  1162. REPT BUFFHEIGHT
  1163. mov [BYTE databuffer+BUFFWIDTH*line],al
  1164. line = line+1
  1165. ENDM
  1166. ;
  1167. ; shift the characters into the buffer
  1168. ;
  1169. @@shiftchars:
  1170. mov ax,[px]
  1171. and ax,7
  1172. mov [bufferbit],ax
  1173. mov [bufferbyte],0
  1174. mov ax,[WORD string]
  1175. mov [stringptr],ax
  1176. mov ax,[WORD string+2]
  1177. mov [stringptr+2],ax
  1178. @@shiftone:
  1179. mov es,[stringptr+2]
  1180. mov bx,[stringptr]
  1181. inc [stringptr]
  1182. mov bx,[es:bx]
  1183. xor bh,bh
  1184. or bl,bl
  1185. jz @@allshifted
  1186. call ShiftPropChar
  1187. jmp @@shiftone
  1188. @@allshifted:
  1189. ;
  1190. ; calculate position to draw buffer on screen
  1191. ;
  1192. mov bx,[py]
  1193. shl bx,1
  1194. mov di,[ylookup+bx]
  1195. add di,[bufferofs]
  1196. add di,[panadjust]
  1197. mov ax,[px]
  1198. shr ax,1
  1199. shr ax,1
  1200. shr ax,1 ;x location in bytes
  1201. add di,ax
  1202. mov [screenspot],di
  1203. ;
  1204. ; advance px
  1205. ;
  1206. mov ax,[bufferbyte]
  1207. shl ax,1
  1208. shl ax,1
  1209. shl ax,1
  1210. or ax,[bufferbit]
  1211. add [px],ax
  1212. ;
  1213. ; draw it
  1214. ;
  1215. ; set xor/or mode
  1216. mov dx,GC_INDEX
  1217. mov al,GC_DATAROTATE
  1218. mov ah,[pdrawmode]
  1219. WORDOUT
  1220. ; set mapmask to color
  1221. mov dx,SC_INDEX
  1222. mov al,SC_MAPMASK
  1223. mov ah,[fontcolor]
  1224. WORDOUT
  1225. mov ax,[bufferbyte]
  1226. test [bufferbit],7
  1227. jz @@go
  1228. inc ax ;so the partial byte also gets drawn
  1229. @@go:
  1230. mov [bufferwidth],ax
  1231. mov si,[fontnumber]
  1232. shl si,1
  1233. mov es,[grsegs+STARTFONT*2+si]
  1234. mov ax,[es:pcharheight]
  1235. mov [bufferheight],ax
  1236. mov si,OFFSET databuffer
  1237. call BufferToScreen
  1238. ; set copy mode
  1239. mov dx,GC_INDEX
  1240. mov ax,GC_DATAROTATE
  1241. WORDOUT
  1242. ; set mapmask to all
  1243. mov dx,SC_INDEX
  1244. mov ax,SC_MAPMASK + 15*256
  1245. WORDOUT
  1246. ret
  1247. ENDP
  1248. endif ;numfont
  1249. ;============================================================================
  1250. ;
  1251. ; MASKED FONT DRAWING ROUTINES
  1252. ;
  1253. ;============================================================================
  1254. if numfontm
  1255. DATASEG
  1256. mshiftdrawtable dw 0,mshift1wide,mshift2wide,mshift3wide
  1257. CODESEG
  1258. ;==================
  1259. ;
  1260. ; ShiftMPropChar
  1261. ;
  1262. ; Call with BX = character number (0-255)
  1263. ; Draws one character to the buffer at bufferbyte/bufferbit, and adjusts
  1264. ; them to the new position
  1265. ;
  1266. ;==================
  1267. PROC ShiftMPropChar NEAR
  1268. mov si,[fontnumber]
  1269. shl si,1
  1270. mov es,[grsegs+STARTFONTM*2+si] ;segment of font to use
  1271. ;
  1272. ; find character location, width, and height
  1273. ;
  1274. mov si,[es:charwidth+bx]
  1275. and si,0ffh ;SI hold width in pixels
  1276. shl bx,1
  1277. mov bx,[es:charloc+bx] ;BX holds pointer to character data
  1278. ;
  1279. ; look up which shift table to use, based on bufferbit
  1280. ;
  1281. mov di,[bufferbit]
  1282. shl di,1
  1283. mov bp,[shifttabletable+di] ;BP holds pointer to shift table
  1284. mov di,OFFSET databuffer
  1285. add di,[bufferbyte] ;DI holds pointer to buffer
  1286. mov cx,[bufferbit]
  1287. add cx,si ;new bit position
  1288. mov ax,cx
  1289. and ax,7
  1290. mov [bufferbit],ax ;new bit position
  1291. mov ax,cx
  1292. shr ax,1
  1293. shr ax,1
  1294. shr ax,1
  1295. add [bufferbyte],ax ;new byte position
  1296. add si,7
  1297. shr si,1
  1298. shr si,1
  1299. shr si,1 ;bytes the character is wide
  1300. shl si,1 ;*2 to look up in shiftdrawtable
  1301. mov cx,[es:pcharheight]
  1302. mov dx,BUFFWIDTH
  1303. jmp [ss:mshiftdrawtable+si] ;procedure to draw this width
  1304. ;
  1305. ; one byte character
  1306. ;
  1307. mshift1wide:
  1308. dec dx
  1309. EVEN
  1310. @@loop1m:
  1311. SHIFTWITHXOR
  1312. add di,dx ; next line in buffer
  1313. loop @@loop1m
  1314. mov cx,[es:pcharheight]
  1315. EVEN
  1316. @@loop1:
  1317. SHIFTNOXOR
  1318. add di,dx ; next line in buffer
  1319. loop @@loop1
  1320. ret
  1321. ;
  1322. ; two byte character
  1323. ;
  1324. mshift2wide:
  1325. dec dx
  1326. dec dx
  1327. EVEN
  1328. @@loop2m:
  1329. SHIFTWITHXOR
  1330. SHIFTWITHXOR
  1331. add di,dx ; next line in buffer
  1332. loop @@loop2m
  1333. mov cx,[es:pcharheight]
  1334. EVEN
  1335. @@loop2:
  1336. SHIFTNOXOR
  1337. SHIFTNOXOR
  1338. add di,dx ; next line in buffer
  1339. loop @@loop2
  1340. ret
  1341. ;
  1342. ; three byte character
  1343. ;
  1344. mshift3wide:
  1345. sub dx,3
  1346. EVEN
  1347. @@loop3m:
  1348. SHIFTWITHXOR
  1349. SHIFTWITHXOR
  1350. SHIFTWITHXOR
  1351. add di,dx ; next line in buffer
  1352. loop @@loop3m
  1353. mov cx,[es:pcharheight]
  1354. EVEN
  1355. @@loop3:
  1356. SHIFTNOXOR
  1357. SHIFTNOXOR
  1358. SHIFTNOXOR
  1359. add di,dx ; next line in buffer
  1360. loop @@loop3
  1361. ret
  1362. ENDP
  1363. ;============================================================================
  1364. ;==================
  1365. ;
  1366. ; VW_DrawMPropString
  1367. ;
  1368. ; Draws a C string of characters at px/py and advances px
  1369. ;
  1370. ; Assumes write mode 0
  1371. ;
  1372. ;==================
  1373. PROC VW_DrawMPropString string:DWORD
  1374. PUBLIC VW_DrawMPropString
  1375. USES SI,DI
  1376. ;
  1377. ; clear out the first byte of the buffer, the rest will automatically be
  1378. ; cleared as characters are drawn into it
  1379. ;
  1380. mov si,[fontnumber]
  1381. shl si,1
  1382. mov es,[grsegs+STARTFONTM*2+si]
  1383. mov dx,[es:pcharheight]
  1384. mov di,OFFSET databuffer
  1385. mov ax,ds
  1386. mov es,ax
  1387. mov bx,BUFFWIDTH-1
  1388. mov cx,dx
  1389. mov al,0ffh
  1390. @@maskfill:
  1391. stosb ; fill the mask part with $ff
  1392. add di,bx
  1393. loop @@maskfill
  1394. mov cx,dx
  1395. xor al,al
  1396. @@datafill:
  1397. stosb ; fill the data part with $0
  1398. add di,bx
  1399. loop @@datafill
  1400. ;
  1401. ; shift the characters into the buffer
  1402. ;
  1403. mov ax,[px]
  1404. and ax,7
  1405. mov [bufferbit],ax
  1406. mov [bufferbyte],0
  1407. mov ax,[WORD string]
  1408. mov [stringptr],ax
  1409. mov ax,[WORD string+2]
  1410. mov [stringptr+2],ax
  1411. @@shiftone:
  1412. mov es,[stringptr+2]
  1413. mov bx,[stringptr]
  1414. inc [stringptr]
  1415. mov bx,[es:bx]
  1416. xor bh,bh
  1417. or bl,bl
  1418. jz @@allshifted
  1419. call ShiftMPropChar
  1420. jmp @@shiftone
  1421. @@allshifted:
  1422. ;
  1423. ; calculate position to draw buffer on screen
  1424. ;
  1425. mov bx,[py]
  1426. shl bx,1
  1427. mov di,[ylookup+bx]
  1428. add di,[bufferofs]
  1429. add di,[panadjust]
  1430. mov ax,[px]
  1431. shr ax,1
  1432. shr ax,1
  1433. shr ax,1 ;x location in bytes
  1434. add di,ax
  1435. mov [screenspot],di
  1436. ;
  1437. ; advance px
  1438. ;
  1439. mov ax,[bufferbyte]
  1440. shl ax,1
  1441. shl ax,1
  1442. shl ax,1
  1443. or ax,[bufferbit]
  1444. add [px],ax
  1445. ;
  1446. ; draw it
  1447. ;
  1448. mov ax,[bufferbyte]
  1449. test [bufferbit],7
  1450. jz @@go
  1451. inc ax ;so the partial byte also gets drawn
  1452. @@go:
  1453. mov [bufferwidth],ax
  1454. mov es,[grsegs+STARTFONTM*2]
  1455. mov ax,[es:pcharheight]
  1456. mov [bufferheight],ax
  1457. ; set AND mode to punch out the mask
  1458. mov dx,GC_INDEX
  1459. mov ax,GC_DATAROTATE + 8*256
  1460. WORDOUT
  1461. ; set mapmask to all
  1462. mov dx,SC_INDEX
  1463. mov ax,SC_MAPMASK + 15*256
  1464. WORDOUT
  1465. mov si,OFFSET databuffer
  1466. call BufferToScreen
  1467. ; set OR mode to fill in the color
  1468. mov dx,GC_INDEX
  1469. mov ax,GC_DATAROTATE + 16*256
  1470. WORDOUT
  1471. ; set mapmask to color
  1472. mov dx,SC_INDEX
  1473. mov al,SC_MAPMASK
  1474. mov ah,[fontcolor]
  1475. WORDOUT
  1476. call BufferToScreen ; SI is still in the right position in buffer
  1477. ; set copy mode
  1478. mov dx,GC_INDEX
  1479. mov ax,GC_DATAROTATE
  1480. WORDOUT
  1481. ; set mapmask to all
  1482. mov dx,SC_INDEX
  1483. mov ax,SC_MAPMASK + 15*256
  1484. WORDOUT
  1485. ret
  1486. ENDP
  1487. endif ; if numfontm
  1488. endif ; if fonts