ID_RF_A.ASM 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  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. ; ID_RF_A.ASM
  18. IDEAL
  19. MODEL MEDIUM,C
  20. INCLUDE "ID_ASM.EQU"
  21. ;============================================================================
  22. TILESWIDE = 21
  23. TILESHIGH = 14
  24. UPDATESIZE = (TILESWIDE+1)*TILESHIGH+1
  25. DATASEG
  26. EXTRN screenseg:WORD
  27. EXTRN updateptr:WORD
  28. EXTRN updatestart:WORD
  29. EXTRN masterofs:WORD ;start of master tile port
  30. EXTRN bufferofs:WORD ;start of current buffer port
  31. EXTRN screenstart:WORD ;starts of three screens (0/1/master) in EGA mem
  32. EXTRN grsegs:WORD
  33. EXTRN mapsegs:WORD
  34. EXTRN originmap:WORD
  35. EXTRN updatemapofs:WORD
  36. EXTRN tinf:WORD ;seg pointer to map header and tile info
  37. EXTRN blockstarts:WORD ;offsets from bufferofs for each update block
  38. planemask db ?
  39. planenum db ?
  40. CODESEG
  41. screenstartcs dw ? ;in code segment for accesability
  42. IFE GRMODE-CGAGR
  43. ;============================================================================
  44. ;
  45. ; CGA refresh routines
  46. ;
  47. ;============================================================================
  48. TILEWIDTH = 4
  49. ;=================
  50. ;
  51. ; RFL_NewTile
  52. ;
  53. ; Draws a composit two plane tile to the master screen and sets the update
  54. ; spot to 1 in both update pages, forcing the tile to be copied to the
  55. ; view pages the next two refreshes
  56. ;
  57. ; Called to draw newlly scrolled on strips and animating tiles
  58. ;
  59. ;=================
  60. PROC RFL_NewTile updateoffset:WORD
  61. PUBLIC RFL_NewTile
  62. USES SI,DI
  63. ;
  64. ; mark both update lists at this spot
  65. ;
  66. mov di,[updateoffset]
  67. mov bx,[updateptr] ;start of update matrix
  68. mov [BYTE bx+di],1
  69. mov dx,SCREENWIDTH-TILEWIDTH ;add to get to start of next line
  70. ;
  71. ; set di to the location in screenseg to draw the tile
  72. ;
  73. shl di,1
  74. mov si,[updatemapofs+di] ;offset in map from origin
  75. add si,[originmap]
  76. mov di,[blockstarts+di] ;screen location for tile
  77. add di,[masterofs]
  78. ;
  79. ; set BX to the foreground tile number and SI to the background number
  80. ; If either BX or SI = 0xFFFF, the tile does not need to be masked together
  81. ; as one of the planes totally eclipses the other
  82. ;
  83. mov es,[mapsegs+2] ;foreground plane
  84. mov bx,[es:si]
  85. mov es,[mapsegs] ;background plane
  86. mov si,[es:si]
  87. mov es,[screenseg]
  88. or bx,bx
  89. jz @@singletile
  90. jmp @@maskeddraw ;draw both together
  91. ;=============
  92. ;
  93. ; Draw single background tile from main memory
  94. ;
  95. ;=============
  96. @@singletile:
  97. shl si,1
  98. mov ds,[grsegs+STARTTILE16*2+si]
  99. xor si,si ;block is segment aligned
  100. REPT 15
  101. movsw
  102. movsw
  103. add di,dx
  104. ENDM
  105. movsw
  106. movsw
  107. mov ax,ss
  108. mov ds,ax ;restore turbo's data segment
  109. ret
  110. ;=========
  111. ;
  112. ; Draw a masked tile combo
  113. ; Interupts are disabled and the stack segment is reassigned
  114. ;
  115. ;=========
  116. @@maskeddraw:
  117. cli ; don't allow ints when SS is set
  118. shl bx,1
  119. mov ss,[grsegs+STARTTILE16M*2+bx]
  120. shl si,1
  121. mov ds,[grsegs+STARTTILE16*2+si]
  122. xor si,si ;first word of tile data
  123. REPT 16
  124. mov ax,[si] ;background tile
  125. and ax,[ss:si] ;mask
  126. or ax,[ss:si+64] ;masked data
  127. stosw
  128. mov ax,[si+2] ;background tile
  129. and ax,[ss:si+2] ;mask
  130. or ax,[ss:si+66] ;masked data
  131. stosw
  132. add si,4
  133. add di,dx
  134. ENDM
  135. mov ax,@DATA
  136. mov ss,ax
  137. sti
  138. mov ds,ax
  139. ret
  140. ENDP
  141. ENDIF
  142. IFE GRMODE-EGAGR
  143. ;===========================================================================
  144. ;
  145. ; EGA refresh routines
  146. ;
  147. ;===========================================================================
  148. TILEWIDTH = 2
  149. ;=================
  150. ;
  151. ; RFL_NewTile
  152. ;
  153. ; Draws a composit two plane tile to the master screen and sets the update
  154. ; spot to 1 in both update pages, forcing the tile to be copied to the
  155. ; view pages the next two refreshes
  156. ;
  157. ; Called to draw newlly scrolled on strips and animating tiles
  158. ;
  159. ; Assumes write mode 0
  160. ;
  161. ;=================
  162. PROC RFL_NewTile updateoffset:WORD
  163. PUBLIC RFL_NewTile
  164. USES SI,DI
  165. ;
  166. ; mark both update lists at this spot
  167. ;
  168. mov di,[updateoffset]
  169. mov bx,[updatestart] ;page 0 pointer
  170. mov [BYTE bx+di],1
  171. mov bx,[updatestart+2] ;page 1 pointer
  172. mov [BYTE bx+di],1
  173. ;
  174. ; set screenstartcs to the location in screenseg to draw the tile
  175. ;
  176. shl di,1
  177. mov si,[updatemapofs+di] ;offset in map from origin
  178. add si,[originmap]
  179. mov di,[blockstarts+di] ;screen location for tile
  180. add di,[masterofs]
  181. mov [cs:screenstartcs],di
  182. ;
  183. ; set BX to the foreground tile number and SI to the background number
  184. ; If either BX or SI = 0xFFFF, the tile does not need to be masked together
  185. ; as one of the planes totally eclipses the other
  186. ;
  187. mov es,[mapsegs+2] ;foreground plane
  188. mov bx,[es:si]
  189. mov es,[mapsegs] ;background plane
  190. mov si,[es:si]
  191. mov es,[screenseg]
  192. mov dx,SC_INDEX ;for stepping through map mask planes
  193. or bx,bx
  194. jz @@singletile
  195. jmp @@maskeddraw ;draw both together
  196. ;=========
  197. ;
  198. ; No foreground tile, so draw a single background tile.
  199. ;
  200. ;=========
  201. @@singletile:
  202. mov bx,SCREENWIDTH-2 ;add to get to start of next line
  203. shl si,1
  204. mov ax,[cs:screenstartcs]
  205. mov ds,[grsegs+STARTTILE16*2+si]
  206. xor si,si ;block is segment aligned
  207. mov ax,SC_MAPMASK+0001b*256 ;map mask for plane 0
  208. mov cx,4 ;draw four planes
  209. @@planeloop:
  210. mov dx,SC_INDEX
  211. WORDOUT
  212. mov di,[cs:screenstartcs] ;start at same place in all planes
  213. REPT 15
  214. movsw
  215. add di,bx
  216. ENDM
  217. movsw
  218. shl ah,1 ;shift plane mask over for next plane
  219. loop @@planeloop
  220. mov ax,ss
  221. mov ds,ax ;restore turbo's data segment
  222. ret
  223. ;=========
  224. ;
  225. ; Draw a masked tile combo
  226. ; Interupts are disabled and the stack segment is reassigned
  227. ;
  228. ;=========
  229. @@maskeddraw:
  230. cli ; don't allow ints when SS is set
  231. shl bx,1
  232. mov ss,[grsegs+STARTTILE16M*2+bx]
  233. shl si,1
  234. mov ds,[grsegs+STARTTILE16*2+si]
  235. xor si,si ;first word of tile data
  236. mov ax,SC_MAPMASK+0001b*256 ;map mask for plane 0
  237. mov di,[cs:screenstartcs]
  238. @@planeloopm:
  239. WORDOUT
  240. tileofs = 0
  241. lineoffset = 0
  242. REPT 16
  243. mov bx,[si+tileofs] ;background tile
  244. and bx,[ss:tileofs] ;mask
  245. or bx,[ss:si+tileofs+32] ;masked data
  246. mov [es:di+lineoffset],bx
  247. tileofs = tileofs + 2
  248. lineoffset = lineoffset + SCREENWIDTH
  249. ENDM
  250. add si,32
  251. shl ah,1 ;shift plane mask over for next plane
  252. cmp ah,10000b
  253. je @@done ;drawn all four planes
  254. jmp @@planeloopm
  255. @@done:
  256. mov ax,@DATA
  257. mov ss,ax
  258. sti
  259. mov ds,ax
  260. ret
  261. ENDP
  262. ENDIF
  263. IFE GRMODE-VGAGR
  264. ;============================================================================
  265. ;
  266. ; VGA refresh routines
  267. ;
  268. ;============================================================================
  269. ENDIF
  270. ;============================================================================
  271. ;
  272. ; reasonably common refresh routines
  273. ;
  274. ;============================================================================
  275. ;=================
  276. ;
  277. ; RFL_UpdateTiles
  278. ;
  279. ; Scans through the update matrix pointed to by updateptr, looking for 1s.
  280. ; A 1 represents a tile that needs to be copied from the master screen to the
  281. ; current screen (a new row or an animated tiled). If more than one adjacent
  282. ; tile in a horizontal row needs to be copied, they will be copied as a group.
  283. ;
  284. ; Assumes write mode 1
  285. ;
  286. ;=================
  287. ; AX 0/1 for scasb, temp for segment register transfers
  288. ; BX width for block copies
  289. ; CX REP counter
  290. ; DX line width deltas
  291. ; SI source for copies
  292. ; DI scas dest / movsb dest
  293. ; BP pointer to UPDATETERMINATE
  294. ;
  295. ; DS
  296. ; ES
  297. ; SS
  298. PROC RFL_UpdateTiles
  299. PUBLIC RFL_UpdateTiles
  300. USES SI,DI,BP
  301. jmp SHORT @@realstart
  302. @@done:
  303. ;
  304. ; all tiles have been scanned
  305. ;
  306. ret
  307. @@realstart:
  308. mov di,[updateptr]
  309. mov bp,(TILESWIDE+1)*TILESHIGH+1
  310. add bp,di ; when di = bx, all tiles have been scanned
  311. push di
  312. mov cx,-1 ; definately scan the entire thing
  313. ;
  314. ; scan for a 1 in the update list, meaning a tile needs to be copied
  315. ; from the master screen to the current screen
  316. ;
  317. @@findtile:
  318. pop di ; place to continue scaning from
  319. mov ax,ss
  320. mov es,ax ; search in the data segment
  321. mov ds,ax
  322. mov al,1
  323. repne scasb
  324. cmp di,bp
  325. je @@done
  326. cmp [BYTE di],al
  327. jne @@singletile
  328. jmp @@tileblock
  329. ;============
  330. ;
  331. ; copy a single tile
  332. ;
  333. ;============
  334. EVEN
  335. @@singletile:
  336. inc di ; we know the next tile is nothing
  337. push di ; save off the spot being scanned
  338. sub di,[updateptr]
  339. shl di,1
  340. mov di,[blockstarts-4+di] ; start of tile location on screen
  341. mov si,di
  342. add di,[bufferofs] ; dest in current screen
  343. add si,[masterofs] ; source in master screen
  344. mov dx,SCREENWIDTH-TILEWIDTH
  345. mov ax,[screenseg]
  346. mov ds,ax
  347. mov es,ax
  348. ;--------------------------
  349. IFE GRMODE-CGAGR
  350. REPT 15
  351. movsw
  352. movsw
  353. add si,dx
  354. add di,dx
  355. ENDM
  356. movsw
  357. movsw
  358. ENDIF
  359. ;--------------------------
  360. IFE GRMODE-EGAGR
  361. REPT 15
  362. movsb
  363. movsb
  364. add si,dx
  365. add di,dx
  366. ENDM
  367. movsb
  368. movsb
  369. ENDIF
  370. ;--------------------------
  371. jmp @@findtile
  372. ;============
  373. ;
  374. ; more than one tile in a row needs to be updated, so do it as a group
  375. ;
  376. ;============
  377. EVEN
  378. @@tileblock:
  379. mov dx,di ; hold starting position + 1 in dx
  380. inc di ; we know the next tile also gets updated
  381. repe scasb ; see how many more in a row
  382. push di ; save off the spot being scanned
  383. mov bx,di
  384. sub bx,dx ; number of tiles in a row
  385. shl bx,1 ; number of bytes / row
  386. mov di,dx ; lookup position of start tile
  387. sub di,[updateptr]
  388. shl di,1
  389. mov di,[blockstarts-2+di] ; start of tile location
  390. mov si,di
  391. add di,[bufferofs] ; dest in current screen
  392. add si,[masterofs] ; source in master screen
  393. mov dx,SCREENWIDTH
  394. sub dx,bx ; offset to next line on screen
  395. IFE GRMODE-CGAGR
  396. sub dx,bx ; bx is words wide in CGA tiles
  397. ENDIF
  398. mov ax,[screenseg]
  399. mov ds,ax
  400. mov es,ax
  401. REPT 15
  402. mov cx,bx
  403. IFE GRMODE-CGAGR
  404. rep movsw
  405. ENDIF
  406. IFE GRMODE-EGAGR
  407. rep movsb
  408. ENDIF
  409. add si,dx
  410. add di,dx
  411. ENDM
  412. mov cx,bx
  413. IFE GRMODE-CGAGR
  414. rep movsw
  415. ENDIF
  416. IFE GRMODE-EGAGR
  417. rep movsb
  418. ENDIF
  419. dec cx ; was 0 from last rep movsb, now $ffff for scasb
  420. jmp @@findtile
  421. ENDP
  422. ;============================================================================
  423. ;=================
  424. ;
  425. ; RFL_MaskForegroundTiles
  426. ;
  427. ; Scan through update looking for 3's. If the foreground tile there is a
  428. ; masked foreground tile, draw it to the screen
  429. ;
  430. ;=================
  431. PROC RFL_MaskForegroundTiles
  432. PUBLIC RFL_MaskForegroundTiles
  433. USES SI,DI,BP
  434. jmp SHORT @@realstart
  435. @@done:
  436. ;
  437. ; all tiles have been scanned
  438. ;
  439. ret
  440. @@realstart:
  441. mov di,[updateptr]
  442. mov bp,(TILESWIDE+1)*TILESHIGH+2
  443. add bp,di ; when di = bx, all tiles have been scanned
  444. push di
  445. mov cx,-1 ; definately scan the entire thing
  446. ;
  447. ; scan for a 3 in the update list
  448. ;
  449. @@findtile:
  450. mov ax,ss
  451. mov es,ax ; scan in the data segment
  452. mov al,3
  453. pop di ; place to continue scaning from
  454. repne scasb
  455. cmp di,bp
  456. je @@done
  457. ;============
  458. ;
  459. ; found a tile, see if it needs to be masked on
  460. ;
  461. ;============
  462. push di
  463. sub di,[updateptr]
  464. shl di,1
  465. mov si,[updatemapofs-2+di] ; offset from originmap
  466. add si,[originmap]
  467. mov es,[mapsegs+2] ; foreground map plane segment
  468. mov si,[es:si] ; foreground tile number
  469. or si,si
  470. jz @@findtile ; 0 = no foreground tile
  471. mov bx,si
  472. add bx,INTILE ;INTILE tile info table
  473. mov es,[tinf]
  474. test [BYTE PTR es:bx],80h ;high bit = masked tile
  475. jz @@findtile
  476. ;-------------------
  477. IFE GRMODE-CGAGR
  478. ;=================
  479. ;
  480. ; mask the tile CGA
  481. ;
  482. ;=================
  483. mov di,[blockstarts-2+di]
  484. add di,[bufferofs]
  485. mov es,[screenseg]
  486. shl si,1
  487. mov ds,[grsegs+STARTTILE16M*2+si]
  488. mov bx,64 ;data starts 64 bytes after mask
  489. xor si,si
  490. lineoffset = 0
  491. REPT 16
  492. mov ax,[es:di+lineoffset] ;background
  493. and ax,[si] ;mask
  494. or ax,[si+bx] ;masked data
  495. mov [es:di+lineoffset],ax ;background
  496. inc si
  497. inc si
  498. mov ax,[es:di+lineoffset+2] ;background
  499. and ax,[si] ;mask
  500. or ax,[si+bx] ;masked data
  501. mov [es:di+lineoffset+2],ax ;background
  502. inc si
  503. inc si
  504. lineoffset = lineoffset + SCREENWIDTH
  505. ENDM
  506. ENDIF
  507. ;-------------------
  508. IFE GRMODE-EGAGR
  509. ;=================
  510. ;
  511. ; mask the tile
  512. ;
  513. ;=================
  514. mov [BYTE planemask],1
  515. mov [BYTE planenum],0
  516. mov di,[blockstarts-2+di]
  517. add di,[bufferofs]
  518. mov [cs:screenstartcs],di
  519. mov es,[screenseg]
  520. shl si,1
  521. mov ds,[grsegs+STARTTILE16M*2+si]
  522. mov bx,32 ;data starts 32 bytes after mask
  523. @@planeloopm:
  524. mov dx,SC_INDEX
  525. mov al,SC_MAPMASK
  526. mov ah,[ss:planemask]
  527. WORDOUT
  528. mov dx,GC_INDEX
  529. mov al,GC_READMAP
  530. mov ah,[ss:planenum]
  531. WORDOUT
  532. xor si,si
  533. mov di,[cs:screenstartcs]
  534. lineoffset = 0
  535. REPT 16
  536. mov cx,[es:di+lineoffset] ;background
  537. and cx,[si] ;mask
  538. or cx,[si+bx] ;masked data
  539. inc si
  540. inc si
  541. mov [es:di+lineoffset],cx
  542. lineoffset = lineoffset + SCREENWIDTH
  543. ENDM
  544. add bx,32 ;the mask is now further away
  545. inc [ss:planenum]
  546. shl [ss:planemask],1 ;shift plane mask over for next plane
  547. cmp [ss:planemask],10000b ;done all four planes?
  548. je @@drawn ;drawn all four planes
  549. jmp @@planeloopm
  550. @@drawn:
  551. ENDIF
  552. ;-------------------
  553. mov ax,ss
  554. mov ds,ax
  555. mov cx,-1 ;definately scan the entire thing
  556. jmp @@findtile
  557. ENDP
  558. END