paint.asm
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:27k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. PAGE 56,132
  2. TITLE PAINT - iAPX 88/86 PAINT STATEMENT SUPPORT
  3. ;***
  4. ; PAINT - iAPX 88/86 PAINT STATEMENT SUPPORT
  5. ;
  6. ; Copyright <C> 1986, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ;
  10. ; BASIC Syntax mapping to included runtime entry points:
  11. ;
  12. ; - PAINT Statement - Calls B$PAIN or B$PNTC, depending on 'paint' attribute
  13. ;
  14. ;     PAINT (x,y) [[,paint [,boundary] ,background]]
  15. ; |     |
  16. ; |  Coord routines     B$PAIN (if "paint" is numeric attribute)
  17. ; |        or
  18. ; |     B$PNTC (if "paint" is tile string)
  19. ; |        |
  20. ; +------------------------------+
  21. ;
  22. ;******************************************************************************
  23. INCLUDE switch.inc
  24. INCLUDE rmacros.inc ; Runtime Macro Defintions
  25. USESEG _DATA
  26. USESEG _BSS
  27. USESEG GR_TEXT 
  28. INCLUDE seg.inc  ;define segments
  29. INCLUDE baslibma.inc
  30. INCLUDE idmac.inc
  31. INCLUDE string.inc
  32. sBegin _DATA
  33. externW B$AC
  34. sEnd _DATA
  35. sBegin _BSS
  36. ;
  37. ;****************************************************************************
  38. ; External low-level function vectors
  39. ;****************************************************************************
  40. ;
  41. externW b$LeftC
  42. externW b$ChkDownC
  43. externW b$ChkUpC
  44. externW b$ScanL
  45. externW b$ScanR
  46. externW b$MapXYC
  47. externW b$SetTile
  48. externW b$PaintBound
  49. externW B$C1SAVE  ;defined in GWDATA.ASM
  50. externW B$C2SAVE  ;defined in GWDATA.ASM
  51. externW B$C3SAVE  ;defined in GWDATA.ASM
  52. externW B$MOVCNT  ;defined in GWDATA.ASM
  53. externW B$SKPCNT  ;defined in GWDATA.ASM
  54. externB B$LFPROG  ;defined in GWDATA.ASM
  55. externB B$RTPROG  ;defined in GWDATA.ASM
  56. externB B$PDIREC  ;defined in GWDATA.ASM
  57. externW B$GXPOS ;defined in GWDATA.ASM
  58. externW B$GYPOS ;defined in GWDATA.ASM
  59. externW B$GX_OLD  ;defined in GWDATA.ASM
  60. externW B$GY_OLD  ;defined in GWDATA.ASM
  61. externW B$BGTLOC  ;defined in GWDATA.ASM
  62. externB b$Buf3 ; > 16-byte buffer, defined in GWINI.ASM
  63. $BGTNUL EQU b$Buf3
  64. externB B$TILFLG  ;defined in GWDATA.ASM
  65. externB B$TIPROG  ;defined in GWDATA.ASM
  66. externB B$TILLEN  ;GWDATA - length of fground tile string (0-rel)
  67. externB B$TILNDX  ;GWDATA - index to pixel of fground tile string
  68. externB B$TILPTR  ;GWDATA - byte ptr to fground tile string
  69. externW B$TILLOC  ;GWDATA - pointer to start of fground tile str
  70. externB B$TILHGT  ;GWDATA - height of foreground tile
  71. externB B$GRPLAN  ;GWDATA - number of graphics planes
  72. externW B$PQLEN ;defined in GWDATA.ASM
  73. externW B$PQNUM ;defined in GWDATA.ASM
  74. externW B$PQGET ;defined in GWDATA.ASM
  75. externW B$PQPUT ;defined in GWDATA.ASM
  76. externB b$Buf1 ; foreground tile string buffer
  77. externB b$VTYP  ;defined in GLOBAL.INC
  78. sEnd _BSS
  79. .RADIX 10
  80. assumes CS,GR_TEXT
  81. sBegin GR_TEXT 
  82. PUBLIC B$PAINTBEG
  83. externNP B$STALCTMP
  84. externNP B$STALCMAXTMPNC ; Allocate max string w/o compaction
  85. externNP B$INVIEW
  86. externNP B$COORD1
  87. externNP B$CLRATR
  88. ;low-level routines:
  89. externNP B$StoreC
  90. externNP B$FetchC
  91. externNP B$PaintInit
  92. externNP B$GETFBC
  93. externNP B$TileMod
  94. externNP B$STALCMAXTMP
  95. externNP B$STDALCTMP
  96. externNP B$SCINIT ; Performs screen initialization
  97. externNP B$ERR_FC
  98. externNP B$ERR_OM
  99. PAGE
  100. SUBTTL PAINT ALGORITHM
  101. B$PAINTBEG: ;Begin painting
  102. CALL [b$PaintBound] ;Set Left and Right "C" for this line
  103. MOV SI,1 ;ENTRY COUNT IS ONE (SKIP NO BORDER)
  104. CALL SCANR1 ;SCAN RIGHT FROM INITIAL POSITION
  105. JZ PNTEXT ;STARTED ON BORDER - GET TXTPTR & QUIT
  106. PUSH BX ;SAVE NO. OF POINTS PAINTED TO RIGHT
  107. CALL SCANL1 ;NOW SCAN LEFT FROM INITIAL POS.
  108. POP SI ;GET RIGHT SCAN COUNT.
  109. ADD SI,BX ;ADD TO LEFT SCAN COUNT
  110. MOV DL,64 ;MAKE ENTRY FOR GOING DOWN
  111. CALL ENTST1
  112. MOV DL,0C0H  ;CAUSE PAINTING UP
  113. OR DL,B$TILNDX ;Add Tile index
  114. JMP SHORT STPAIN ;START PAINTING.
  115. PNTEXT:  ;Exit PAINT statement
  116. MOV B$TILFLG,0 ;Turn Tiling off
  117. RET
  118. ;Register usage: (approximately)
  119. ; In main paint loop: SI=B$SKPCNT, BX=B$MOVCNT, DL=Direction/Tile Index
  120. ; In SCANR1,SCANL1:   AX=Word 1 of graphics cursor,BX=Word 2,CX=Word 3
  121. ; MAIN PAINT LOOP
  122. PNTLOP:
  123. PNTLP1:
  124. CALL GETQ ;Get one entry from queue
  125. CALL B$StoreC
  126. STPAIN:
  127. MOV AL,DL ;GET DIRECTION
  128. AND AL,63 ;Isolate Tile index
  129. MOV B$TILNDX,AL ;and store it
  130. MOV AH,B$GRPLAN ;get number of graphics planes
  131. MUL AH ;product is in AX
  132. MOV B$TILPTR,AL ;get real offset to fground tile string
  133. MOV AL,DL ;reget direction byte
  134. AND AL,0C0H  ;Isolate direction bits
  135. MOV B$PDIREC,AL
  136. ADD AL,AL ;SEE WHETHER TO GO UP, DOWN, OR QUIT
  137. JZ PNTEXT ;IF ZERO, ALL DONE.
  138. JNB PDOWN ;IF POSITIVE, GO DOWN FIRST
  139. CALL [b$ChkUpC] ;MOVE UP BEFORE SCANNING
  140. JB PNTLP1 ;Off viewport - get next entry
  141. CALL TILNDD ;Decrement tile index
  142. JMP SHORT PNTLP2
  143. PDOWN:
  144. CALL [b$ChkDownC] ;SEE IF AT BOTTOM & MOVE DOWN IF NOT
  145. JB PNTLP1 ;Off viewport - get next entry
  146. CALL TILNDI ;Increment tile index
  147. PNTLP2:
  148. CALL [b$PaintBound] ;Set Left and Right "C" for this line
  149. CALL SCANR1 ;SCAN RIGHT & SKIP UP TO B$SKPCNT BORDER
  150. JZ PNTLP1 ;IF NO POINTS PAINTED, GET NEXT ENTRY
  151. CALL SCANL1 ;NOW SCAN LEFT FROM START POINT
  152. MOV SI,BX ;[SI] = LEFT B$MOVCNT
  153. TEST B$TIPROG,255 ;Is this a background tile?
  154. JNZ TPROG1 ;Yes: skip already painted check
  155. OR CL,CL ;SEE IF LINE WAS ALREADY PAINTED
  156. JZ PNTLP3 ;IT WAS - DON'T MAKE OVERHANG ENTRY
  157. TPROG1:
  158. CMP BX,1 ;SEE IF LEFT B$MOVCNT WAS .GT. 1
  159. JLE PNTLP3 ;No: go make entry for left+right move count
  160. ;Yes: make entry in opposite direction for
  161. ;overhang
  162. MOV AL,B$PDIREC
  163. XOR AL,128
  164. AND AL,0C0H  ;Isolate new direction
  165. OR AL,B$TILNDX ;Reverse direction and/or tile index
  166. ;++added 1 line (faster than doing it all in DL!)
  167. MOV DL,AL
  168. CALL B$FetchC ;Get current point address
  169. CALL PUTQ
  170. PNTLP3:
  171. ADD SI,WORD PTR B$MOVCNT ;ADD COUNT PAINTED DURING RIGHT SCAN TO LEFT B$MOVCNT
  172. CALL ENTSLR ;GO MAKE ENTRY.
  173. ;added 1 line
  174. MOV CX,WORD PTR B$C3SAVE
  175. MOV BX,WORD PTR B$C2SAVE ;SET CURRENT LOCATION BACK TO END
  176. MOV AX,WORD PTR B$C1SAVE ;OF RIGHT SCAN.
  177. CALL B$StoreC
  178. PNTLP4:
  179. MOV SI,WORD PTR B$SKPCNT ;CALC B$SKPCNT - B$MOVCNT TO SEE IF
  180. SUB SI,WORD PTR B$MOVCNT ;ANY MORE BORDER TO SKIP
  181. JZ GOPLOP ;NO MORE - END OF THIS SCAN
  182. JB PNTLP6 ;RIGHT OVERHANG - SEE IF ENTRY NEEDED
  183. CALL SCANR1 ;HERE IF NEED TO CONTINUE RIGHT SCAN
  184. JZ GOPLOP ;NO MORE POINTS.
  185. TEST B$TIPROG,255 ;Is this a background tile?
  186. JNZ TPROG0 ;Yes: enter regardless if already painted or not
  187. OR CL,CL ;SEE IF LINE ALREADY PAINTED
  188. JZ PNTLP4 ;YES, DON'T ENTER ANYTHING
  189. TPROG0:
  190. MOV SI,BX ;ENTRY COUNT TO [SI]
  191. ;added 1 line
  192. MOV CX,WORD PTR B$C3SAVE
  193. MOV BX,WORD PTR B$C2SAVE ;MAKE ENTRY AT LOCATION SAVED BY ScanR
  194. MOV AX,WORD PTR B$C1SAVE ;SO WE CAN ENTER A POSITIVE B$SKPCNT
  195. MOV DL,B$PDIREC
  196. CALL ENTSTK ;MAKE ENTRY
  197. JMP SHORT PNTLP4 ;CONTINUE UNTIL B$SKPCNT .LE. 0
  198. PNTLP6:
  199. CMP SI,WORD PTR -1 ;If B$SKPCNT-B$MOVCNT .LT. -1
  200. JGE GOPLOP ;No: overhang too small for entry
  201. NEG SI ;Yes: Make right overhang entry
  202. DEC SI ;     of at least one point wide overhang
  203. MOV CX,SI ; LeftC protects CX
  204. RTOVH1:
  205. CALL [b$LeftC] ;START IS -(B$SKPCNT-B$MOVCNT)-1 TO LEFT
  206. LOOP RTOVH1
  207. MOV AL,B$PDIREC ;MAKE ENTRY IN OPPOSITE DIRECTION
  208. XOR AL,128
  209. ;++added 1 line (faster than doing it all in DL!)
  210. MOV DL,AL
  211. CALL ENTST1 ;MAKE ENTRY
  212. GOPLOP:
  213. JMP PNTLOP ;GO PROCESS NEXT ENTRY
  214. ENTSLR:
  215. MOV AL,B$LFPROG ;DON'T STACK IF LINE ALREADY PAINTED
  216. OR AL,B$RTPROG
  217. OR AL,B$TIPROG
  218. JNZ ENTST0
  219. RET ;Z IF SCAN LINE ALREADY PAINTED
  220. ENTST0:
  221. MOV DL,B$PDIREC
  222. ENTST1:
  223. CALL B$FetchC ;LOAD REGS WITH CURRENT "C"
  224. ENTSTK:
  225. OR DL,B$TILNDX ;Add tile index to direction
  226. ENTST9:
  227. JMP PUTQ
  228. SCANR1:
  229. ;added 1 line
  230. MOV DX,SI ;Can't change entry conditions for ScanR now...
  231. CALL [b$ScanR] ;PERFORM LOW LEVEL RIGHT SCAN
  232. MOV WORD PTR B$SKPCNT,DX ;SAVE UPDATED B$SKPCNT
  233. MOV WORD PTR B$MOVCNT,BX ;SAVE B$MOVCNT
  234. ;added 3 lines
  235. MOV WORD PTR B$C1SAVE,AX ;Save the "first non-BRDATR pixel
  236. MOV WORD PTR B$C2SAVE,SI ; found during scan" in temp
  237. MOV WORD PTR B$C3SAVE,DI
  238. OR BX,BX ;SET CC'S ON B$MOVCNT
  239. MOV AL,CL ;GET ALREADY-PAINTED FLAG FROM [C]
  240. MOV B$RTPROG,AL
  241. RET
  242. SCANL1:
  243. CALL B$FetchC ;GET CURRENT LOCATION
  244. ;added 1 line
  245. PUSH CX
  246. PUSH BX ;AND SWAP WITH CSV
  247. PUSH AX
  248. ;added 1 line
  249. MOV CX,WORD PTR B$C3SAVE
  250. MOV BX,WORD PTR B$C2SAVE
  251. MOV AX,WORD PTR B$C1SAVE
  252. CALL B$StoreC ;REPOS AT BEGINNING OF SCAN
  253. POP AX ;REGET PLACE WHERE RT SCN STOPPED
  254. POP BX
  255. ;added 2 lines
  256. POP CX
  257. MOV WORD PTR B$C3SAVE,CX
  258. MOV WORD PTR B$C2SAVE,BX ;AND SAVE IT IN TEMP LOCATION
  259. MOV WORD PTR B$C1SAVE,AX
  260. CALL [b$ScanL] ;NOW DO LOW LEVEL LEFT SCAN
  261. MOV AL,CL ;GET ALREADY-PAINTED FLAG FROM [C]
  262. MOV B$LFPROG,AL ;WHETHER IT WAS ALREADY PAINTED (faster than
  263. ;  doing MOV B$LFPROG,CL!)
  264. RET
  265. PAGE
  266. SUBTTL PAINT AND TILE SUPPORT ROUTINES
  267. ; Little helpers for PAINT and TILE
  268. ;
  269. ;FGSTRINI initialize foreground string
  270. ;
  271. ;Purpose:
  272. ;   Check string for validity:  its length must be less than 256 and
  273. ;   greater than 0.  Fill string buffer b$Buf1 with paint tile padded on the
  274. ;   right with zeros.  Initialize B$TILLOC to point at b$Buf1.  Initialize
  275. ;   B$GRPLAN to the number of graphics planes.  Stores rounded up tile
  276. ;   length in B$TILLEN and pixel height of tile in B$TILHGT (must be less
  277. ;   than or equal to 64).
  278. ;
  279. ;Entry:
  280. ; BX = ptr to string descriptor
  281. ;
  282. ;Exit:
  283. ; variables updated as noted
  284. ;
  285. ;Modifies:
  286. ; CX,SI,DI
  287. ;
  288. FGSTRINI: ;initialize paint string
  289. MOV CX,WORD PTR 0[BX] ;[CX]= len
  290. MOV SI,WORD PTR 2[BX] ;[SI]= addr
  291. OR CH,CH ;Is CH=0?
  292. JNE MATERR ;Length must be .LE. 255
  293. MOV DI,OFFSET DGROUP:b$Buf1 ;DI points to b$Buf1
  294. MOV WORD PTR B$TILLOC,DI ;Store adr
  295. PUSH CX ;Save string length
  296. CLD ;Clear direction flag
  297. ;Repeat until CX=0:
  298. REP MOVSB ;Put Fill String in b$Buf1
  299. POP CX ;Restore  string length
  300. PUSH CX ;Resave string length
  301. SUB CX,256d  ;CX:=CX-256
  302. NEG CX ;CX:=-CX=remainder of BUF
  303. XOR AL,AL ;Clear AL
  304. ;Repeat until CL=0:
  305. REP STOSB ;Fill the rest of BUF with zeros
  306. ;tile string is now saved in the temp buffer so temp string can be deallocated
  307. CALL B$STDALCTMP ; deallocate temp string pointed to by BX
  308. ;Check tile height
  309. CALL B$TileMod ;Get number of graphics planes
  310. POP CX ;Restore CL
  311. MOV B$GRPLAN,AL ;in this screen mode
  312. JCXZ MATERR ;See if at least one byte in tile string
  313. XCHG AX,CX
  314. DEC AX
  315. DIV CL ;AX=(B$TILLEN-1)/B$GRPLAN
  316. XOR AH,AH
  317. INC AX ;AX=INT((B$TILLEN-1)/B$GRPLAN)+1=height in pixels rounded up
  318. CMP AL,65
  319. JNB MATERR ;Tile can only be 64 pixels long (IBM compatibility)
  320. MOV B$TILHGT,AL ;Save pixel height of tile (always.LE.64)
  321. MUL CL ;AX=INT(((B$TILLEN-1)/B$GRPLAN)+1)*B$GRPLAN
  322. DEC AX ;make 0 based, guaranteed 1 or more
  323. OR AH,AH ;Rounded up length must be .le. 255
  324. JNZ materr ;Yes: this must be a multiplane with four or more planes
  325. MOV B$TILLEN,AL ;Store rounded up length
  326. RET ;return to caller
  327. MATERR:
  328. MOV B$TILFLG,0 ;Turn Tiling off
  329. JMP B$ERR_FC
  330. ;***
  331. ; BGSTRINI - initialize background tile string
  332. ; Purpose:
  333. ; Insures that string length is between 1 and 255 inclusive.
  334. ; Initializes background string to specified background string.
  335. ;
  336. ; Entry:
  337. ; BX = ptr to string descriptor
  338. ; $BGTNUL = ptr to background tile string area
  339. ; Exit:
  340. ; None.
  341. ; Modifies:
  342. ; SI,DI,CX
  343. ;****
  344. BGSTRINI:
  345. MOV CX,[BX]  ;[CX]= len
  346. OR CH,CH
  347. JNE materr ;Max len is 255
  348. JCXZ materr ;See if at least one byte in background string
  349. CMP CL,B$GRPLAN ;Ignore any extra bytes
  350. JBE FILL_BGSTR
  351. MOV CL,B$GRPLAN
  352. FILL_BGSTR: ;Fill background string
  353. MOV SI,WORD PTR 2[BX] ;[SI]= addr
  354. MOV DI,OFFSET DGROUP:$BGTNUL ;Point DI at backgrd tile area
  355. CLD ;Clear direction flag
  356. REP MOVSB ;Fill with as much as user gave,
  357. ;rest are chr$(0)
  358. JMP B$STDALCTMP ; deallocate temp string pointed to by BX
  359. ;***
  360. ; B$ClrBgStr - clear background string area
  361. ; Purpose:
  362. ; Initialize background string area by filling with zeros.
  363. ; Make sure there are no more than 16 graphics planes.
  364. ;
  365. ; Entry:
  366. ; $BGTNUL points to background string area
  367. ; Exit:
  368. ; None.
  369. ; Modifies:
  370. ; CX,DI,AX.
  371. ;****
  372. cProc B$ClrBgStr,<NEAR> ;Clear background string
  373. cBegin
  374. MOV CX,16
  375. CMP CL,B$GRPLAN ;Only allocated space for at most 16 planes
  376. JB MATERR ;function call error
  377. MOV DI,OFFSET DGROUP:$BGTNUL
  378. XOR AL,AL
  379. CLD
  380. REP STOSB ;Fill 16 bytes with CHR$(0)
  381. MOV B$BGTLOC,OFFSET DGROUP:$BGTNUL ;No BG tile, use null (00)
  382. cEnd
  383. ; Set starting tile index to Starting Y axis and
  384. ; store in B$TILNDX.
  385. ; Set B$TILNDX to (Y MOD pixel height)*B$GRPLAN
  386. ;
  387. ;Entry - [DX] = Starting Y line
  388. ;
  389. ; Uses: [BX]
  390. cProc B$SetTileIndex,<NEAR>
  391. cBegin
  392. CMP B$TILFLG,0
  393. JZ STIND2 ;nothing if not tile
  394. PUSH AX
  395. PUSH DX ;Protect DX
  396. MOV BX,DX ;[BX]=Y coord
  397. MOV DL,B$TILHGT ;[DX]= height of tile
  398. XOR DH,DH
  399. STIND1:
  400. SUB BX,DX
  401. JNB STIND1 ;Find Y MOD pixel height
  402. ADD BX,DX ;+len since overflowed
  403. MOV B$TILNDX,BL ;get index of tile pixel
  404. MOV AL,B$GRPLAN
  405. XOR AH,AH
  406. MUL BL ;AX=(Y MOD pixel height)*B$GRPLAN
  407. MOV B$TILPTR,AL ;store fground tile string offset
  408. POP DX ;get  Y coord
  409. POP AX
  410. STIND2:
  411. cEnd
  412. ; Scan Fill argument,  set Fill color attr if numeric
  413. ; or set up tile attr if string.
  414. ; If string, check that its length .LE. 64*number of graphics planes
  415. ; and round up length to even multiple of number of graphics planes.
  416. ; MATCH3 Checks 3 consecutive lines in TILE$ for match
  417. ; with the background color or tile.  If 3 lines
  418. ; are there, then give Illegal Function Call error.
  419. ; If this was not done, PAINT might infinite loop.
  420. ; Uses AX,BX,CX,DX,SI,DI
  421. MATCH3:
  422. CMP B$TILFLG,0
  423. JZ MATC3X ;Do nothing if Tile wasn't given
  424. XOR DH,DH
  425. MOV DL,B$GRPLAN ;DX=tile "width"
  426. MOV SI,WORD PTR B$TILLOC ;SI=pointer to tile string
  427. XOR AH,AH
  428. MOV AL,B$TILLEN
  429. ADD AX,SI ;AX=end of tile string
  430. CLD
  431. MAT3LP:
  432. CMP SI,AX ;Done entire tile string yet?
  433. JA MATC3X ;Yes:
  434. MOV DI,WORD PTR B$BGTLOC
  435. CALL CMPST ;Matched 3 tiles in a row?
  436. JE PNTERR ;Yes: barf
  437. ADD SI,DX ;No: look at next set in tile string
  438. JMP SHORT MAT3LP ;Loop
  439. MATC3X:
  440. RET
  441. CMPST:
  442. PUSH SI ;Save tile string pointer
  443. MOV BX,3
  444. PUSH ES
  445. PUSH DS
  446. POP ES
  447. CMPST2:
  448. MOV CL,DL ;Look for 3 in a row matches of B$GRPLAN bytes
  449. XOR CH,CH
  450. CMPST0: CMPSB ;Compare [SI],[DI]
  451. JNE CMPST1 ;Different already, exit with Z clear
  452. CALL WRAPSI
  453. LOOP CMPST0 ;Matched B$GRPLAN in a row yet?
  454. MOV DI,WORD PTR B$BGTLOC ;Yes: reset background pointer
  455. DEC BX ;Matched 3 sets of B$GRPLAN in a row?
  456. JNZ CMPST2 ;No:
  457. ;Yes: exit with Z set
  458. CMPST1:
  459. POP ES
  460. POP SI
  461. RET
  462. WRAPSI:
  463. CMP SI,AX ;Wrap around to beginning of tile string yet?
  464. JBE NoWrap ;No:
  465. MOV SI,WORD PTR B$TILLOC ;Yes: back to go
  466. NoWrap: RET
  467. ;***
  468. ; TILATR
  469. ; Set ATRBYT from tile and set B$TIPROG if current tile
  470. ; attribute equals BG tile attribute.
  471. ; USES BX,DI
  472. ;****
  473. TILATR:
  474. CMP B$TILFLG,0
  475. MOV BL,B$TILPTR
  476. JNZ B$TILAT1 ;Update ATRBYT
  477. RET ;do nothing if not tile
  478. ;***
  479. ; TILNDD
  480. ; Decrement Tile index
  481. ; and store tile in ATRBYT if B$TILFLG True...
  482. ; USES AX,BX
  483. ;****
  484. TILNDD:
  485. CMP B$TILFLG,0
  486. JNZ TILNDD1  ;do nothing if not tile
  487. RET
  488. TILNDD1:
  489. DEC B$TILNDX  ;index is one less
  490. MOV BL,B$TILPTR ;get offset to fground tile string
  491. OR BL,BL ;At beginning of tile string?
  492. JNZ TILDN1 ;Brif not underflowing
  493. MOV BL,B$TILHGT ;get tile height
  494. DEC BL ;make 0-relative
  495. MOV B$TILNDX,BL ;put into index
  496. MOV BL,B$TILLEN ;else wrap to top end
  497. INC BL ;make 1 based
  498. TILDN1:
  499. SUB BL,B$GRPLAN ;Decrement index to beginning of prev tile
  500. JMP SHORT TILND2 ;Update index, ATRBYT
  501. PNTERR:
  502. MOV B$TILFLG,0 ;Turn Tiling off
  503. JMP B$ERR_FC
  504. ;***
  505. ; TILNDI
  506. ; Increment Tile index (called after DOWNC)
  507. ; and store tile in ATRBYT if B$TILFLG True...
  508. ; USES AX,BX
  509. ;****
  510. TILNDI:
  511. CMP B$TILFLG,0
  512. JNZ TILNDI1  ;do nothing if not tile
  513. RET
  514. TILNDI1:
  515. INC B$TILNDX  ;increment tile pixel index
  516. MOV BL,B$TILPTR ;get fground tile byte offset
  517. ADD BL,B$GRPLAN ;Increment index to beginning of next tile
  518. CMP BL,B$TILLEN
  519. JBE TILND2 ;Brif not overflowing
  520. XOR BL,BL ;else wrap to bottom end
  521. MOV B$TILNDX,BL ;also clear tile pixel index
  522. TILND2:
  523. MOV B$TILPTR,BL ;update tile byte offset pointer
  524. ;***
  525. ; B$TILAT1
  526. ;
  527. ;****
  528. cProc B$TILAT1,<NEAR>,<SI>
  529. cBegin
  530. MOV BH,0 ;[BL]=[BL]*GRPLAN, [BH]=0
  531. ADD BX,WORD PTR B$TILLOC
  532. MOV SI,BX ;SI points into tile string
  533. MOV DI,WORD PTR B$BGTLOC ;DI points into background string
  534. MOV B$TIPROG,0 ;Clear progress flag
  535. XOR BH,BH
  536. TILAT2: INC BH
  537. CMP BH,B$GRPLAN
  538. JA TILAT4 ;For BH = 1 to gplanes
  539. MOV BL,[SI]  ;Get curr tile attr
  540. PUSH BX
  541. CALL [b$SetTile] ;Set OEM's 'ATRBYT' to tile attr
  542. POP BX
  543. CMP BL,[DI]  ;Compare FG attr to BG attr
  544. JNZ TILAT3 ;Brif not equal
  545. INC B$TIPROG  ;Count matches
  546. TILAT3:
  547. INC SI ;Check next planes bytes
  548. INC DI
  549. JMP SHORT TILAT2 ;next BH
  550. TILAT4:
  551. MOV BL,B$TIPROG
  552. MOV B$TIPROG,0
  553. CMP BL,B$GRPLAN ;Did all FG match BG?
  554. JNE TILAT6 ;No:  not all matched so say none did.
  555. MOV B$TIPROG,1 ;Yes: flag all matched
  556. TILAT6:
  557. cEnd
  558. PAGE
  559. SUBTTL PAINT QUEUE ROUTINES
  560. cProc B$INTQNOCPCT,<PUBLIC,NEAR>,<BX,DX>
  561. cBegin
  562. ; PUSH BX ;save registers...
  563. ; PUSH DX
  564. ; cCALL B$STGETFRESIZ ;get size of free string
  565. ; OR BX,BX ;test if no free string
  566. ; JZ PQOMER ;if not, give out of memory error
  567. ; cCALL B$STALCTMP ; Allocate all string space as temporary
  568. cCALL B$STALCMAXTMPNC ; Allocate max-string w/o compaction
  569. JMP SHORT INTQUE_COMMON ;jump to common code point
  570. cEnd <nogen> ; End of B$INTQNOCPCT
  571. PUBLIC B$INTQUE
  572. B$INTQUE:
  573. PUSH BX ;Save x coord
  574. PUSH DX ;SAVE Y COORD
  575. CALL B$STALCMAXTMP ;allocate maximum temporary string
  576. INTQUE_COMMON:
  577. MOV AX,0[BX] ;AX:=size of free string space
  578. MOV CX,2[BX] ;CX:=location of free string space
  579. CMP AX,9 ;is temp string too small?
  580. JB TEMP_TOO_SMALL ;if so, do not subtract
  581. SUB AX,9 ;give string room for test
  582. TEMP_TOO_SMALL:
  583. ;Note: B$GY_OLD is the previous x coord accumulator.  Since this variable is
  584. ;never used in the PAINT statement, it is used here to save the location
  585. ;of the temporary string being used for the paint queue.
  586. MOV B$GY_OLD,CX ;save string location in B$GY_OLD
  587. ADD CX,AX ;CX points just past end of free string
  588. DEC CX ;CX=highest byte of in-use string space
  589. ;omit check for overflow
  590. ;Note: B$GX_OLD is the previous y coord accumulator.  Since this variable is
  591. ;never used in the PAINT statement, it is used here to save the pointer to
  592. ;the end of the temporary string being used for the paint queue.
  593. MOV B$GX_OLD,CX ;Save this value in B$GX_OLD
  594. CALL B$STDALCTMP ;mark temp string as deallocated
  595. CMP AX,18d
  596. JNB INTQU3 ;Ok if at least 18 bytes (2 entries)
  597. PQOMER:
  598. JMP B$ERR_OM   ; else Out of Memory
  599. INTQU3:
  600. MOV WORD PTR B$PQLEN,AX ;len is free size
  601. MOV WORD PTR B$PQNUM,0 ;present number is 0
  602. XCHG AX,DX ;AX:=beginning of usable free space
  603. MOV WORD PTR B$PQGET,AX ;Init head
  604. MOV WORD PTR B$PQPUT,AX ; and tail
  605. POP DX ;Restore y coord
  606. POP BX ;Restore X coord
  607. RET
  608. ; PUTQ - Enqueue entry in paint queue
  609. ; Entry - AX,BX,CX = OEM's graphics cursor
  610. ;   SI = B$SKPCNT
  611. ;   DL = Direction (and tiling) flag
  612. ; Exit - B$PQNUM,B$PQPUT updated
  613. ; AX,DI Used
  614. DbPub PUTQ
  615. PUTQ:
  616. PUSH ES
  617. PUSH DS
  618. POP ES
  619. PUSH DX
  620. ;added 1 line
  621. PUSH SI
  622. PUSH CX
  623. PUSH BX
  624. ;added 1 line
  625. PUSH AX
  626. ADD WORD PTR B$PQNUM,9d ;len= len+9
  627. MOV AX,WORD PTR B$PQLEN
  628. CMP WORD PTR B$PQNUM,AX
  629. JNB PQOMER ;Out of Memory if at end or higher
  630. MOV AX,WORD PTR B$PQPUT ;[AX]= queue ptr
  631. CALL WRAP ;check wrap
  632. MOV DI,AX ;[DI]= queue ptr
  633. POP AX
  634. CLD
  635. STOS WORD PTR [SI] ;Graphics cursor
  636. POP AX
  637. STOS WORD PTR [SI] ;Graphics cursor
  638. POP AX
  639. STOS WORD PTR [SI] ;Graphics cursor
  640. POP AX
  641. STOS WORD PTR [SI] ;B$SKPCNT
  642. ;added 2 lines
  643. POP AX
  644. STOSB ;Direction flag
  645. MOV WORD PTR B$PQPUT,DI
  646. POP ES
  647. RET
  648. WRAP:
  649. PUSH AX
  650. ADD AX,9
  651. ;Note: B$GX_OLD is the previous x coord accumulator.  Since this variable is
  652. ;never used in the PAINT statement, it is used here to save the location
  653. ;of the temporary string being used for the paint queue.
  654. CMP AX,WORD PTR B$GX_OLD ;Are we at end of free space?
  655. POP AX ;Restore AX
  656. JB WRAPX ;Brif not off end of queue
  657. ;Note: B$GY_OLD is the previous y coord accumulator.  Since this variable is
  658. ;never used in the PAINT statement, it is used here to save the pointer to
  659. ;the end of the temporary string being used for the paint queue.  This
  660. ;value is set at the beginning of B$INTQUE.
  661. MOV AX,B$GY_OLD ;else set to beginning of queue
  662. WRAPX:
  663. RET
  664. ; GETQ - Dequeue entry from paint queue
  665. ; Entry - none
  666. ; Exit - AX,BX,CX = OEM's graphics cursor
  667. ;   SI = B$SKPCNT
  668. ;   DL = Direction (and tiling) flag
  669. ;   B$PQNUM,B$PQGET updated
  670. ; No other registers used.
  671. DbPub GETQ
  672. GETQ:
  673. MOV DL,0 ;preset "Direction=0" in case no entries
  674. CMP WORD PTR B$PQNUM,0
  675. JZ GETQX ;Brif empty
  676. SUB WORD PTR B$PQNUM,9d ;len = len-9
  677. MOV AX,WORD PTR B$PQGET ;[AX]= dequeue ptr
  678. CALL WRAP ;check wrap
  679. MOV SI,AX ;[SI]= dequeue ptr
  680. ;added 3 lines
  681. CLD
  682. LODS WORD PTR [SI] ;Graphics cursor
  683. PUSH AX
  684. LODS WORD PTR [SI] ;Graphics cursor
  685. MOV BX,AX
  686. LODS WORD PTR [SI] ;Graphics cursor
  687. MOV CX,AX
  688. LODS WORD PTR [SI] ;B$SKPCNT
  689. PUSH AX
  690. ;added 2 lines
  691. LODSB ;Direction flag
  692. MOV DL,AL
  693. MOV WORD PTR B$PQGET,SI
  694. ;added 2 lines
  695. POP SI ;SI = B$SKPCNT
  696. POP AX
  697. GETQX:
  698. RET
  699. PAGE
  700. SUBTTL COMPILER ENTRY POINTS FOR PAINT
  701. ; PAINT - FILL AN AREA WITH COLOR
  702. ;
  703. ; SYNTAX: PAINT [STEP](X,Y)[,<iexp>[,iexp]]|[,<sexp>[,<iexp>[,<sexp>]]]
  704. ; where <iexp>=integer expression, <sexp>=string expression
  705. ;
  706. ;***
  707. ;B$PAIN - Process PAINT statement without tiling
  708. ;
  709. ;Purpose:
  710. ; This routine will be called by the parsing routine PAINT in PRSG86
  711. ; in the interpreter version or by the compiler in the compiler version
  712. ; if the PAINT statement scanned does not contain a paint tile
  713. ; attribute but uses a integer paint color instead.  The call to
  714. ; BNDS_CHK tests the start coordinates of the PAINT against the current
  715. ; viewport boundaries.  The paint and border colors are checked for
  716. ; validity before the jump to B$PAINTBEG begins the actual painting.
  717. ;
  718. ;Entry:
  719. ; Color = paint color spec or -1 if default
  720. ; Border = border color spec or -1 if default
  721. ;Exit:
  722. ; None.
  723. ;Uses:
  724. ; Per convention
  725. ;Exceptions:
  726. ; Control may be transfered to B$ERR_FC
  727. ;****
  728. cProc B$PAIN,<PUBLIC,FAR>,<SI,DI> 
  729. parmW Color
  730. parmW Border
  731. cBegin
  732. CALL B$SCINIT ; init screen if not already done
  733. cCall B$COORD1 ;do any necessary translations
  734. MOV BX,Color ;[BX] = paint color
  735. MOV DX,Border ;[DX] = border color
  736. CALL OLD_PA1  ; Perform
  737. cEnd
  738. OLD_PA1: ; Entry point for PAINT with no tiling
  739. MOV B$TILFLG,0 ;tiling is not active
  740. MOV B$TIPROG,0
  741. CALL B$INTQUE  ;Init the Queue
  742. PUSH DX ;Save border color
  743. CALL BNDS_CHK ;Check if coordinates are inside
  744. ;screen or viewport
  745. JC MAPIT
  746. JMP DONT_PAINT ;Don't PAINT if coordinates out of bounds
  747. MAPIT:
  748. push bx ;preserve bx across call to MapXYC
  749. CALL [b$MapXYC] ;Graphics Cursor:=(CX,DX)
  750. pop ax ;restore paint color
  751. POP DX ;Restore border color
  752. CALL B$CLRATR  ;Returns paint color attribute in AL
  753. CMP DX,-1 ;Is border color defaulted?
  754. JZ BRDCHK ;Yes: AL contains valid paint color which is
  755. ;border color default when no tiling
  756. MOV AX,DX ;AX:=border color
  757. BRDCHK:  ;check for valid border color
  758. CALL B$PaintInit ;OEM check for legal border color
  759. JC ERR_PAINT ;carry set if invalid border color
  760. JMP B$PAINTBEG ;Go begin painting
  761. ;***
  762. ;B$PNTC - Process PAINT statement with tiling option
  763. ;
  764. ;Purpose:
  765. ; This routine will be called if the PAINT statement scanned contains
  766. ; a paint tile attribute instead of an integer paint color.  The
  767. ; call to BNDS_CHK checks to see if the PAINT coordinates are within
  768. ; bounds of the current viewport (the screen if there is no viewport).
  769. ; The call to FGSTRINI initializes a buffer area (b$Buf1) to the tile
  770. ; specified in the PAINT statement or to the default value.  B$ClrBgStr
  771. ; initializes the default background string.  TILEINIT checks for a
  772. ; valid border color, initializes B$TILNDX to index the appropriate byte
  773. ; of the tile string, initializes ATRBYT (variable containing tile
  774. ; mask) and checks for three consecutive matches between the foreground
  775. ; and background tiles.  If everything is ok the jump to B$PAINTBEG is
  776. ; taken to begin the actual painting procedure.
  777. ;Entry:
  778. ; sdTile = sd for tiling string
  779. ; Border = border spec or -1 if default
  780. ; sdBkgd = sd for background string or -1 if none
  781. ;Exit:
  782. ; None.
  783. ;Uses:
  784. ; None.
  785. ;Exceptions:
  786. ; B$ERR_FC
  787. ;****
  788. cProc B$PNTC,<PUBLIC,FAR>,<ES,SI,DI>
  789. parmSD sdTile
  790. parmW Border
  791. parmSD sdBkgd
  792. cBegin
  793. CALL B$SCINIT ; init screen if not already done
  794. cCall B$COORD1 ;do any necessary translations
  795. GetpSD BX,sdTile ;[BX] = psdTile
  796. GetpSD CX,sdBkgd ;[CX] = psdBkgd
  797. MOV DX,Border ;[DX] = border color
  798. PUSH DS ; set es=ds
  799. POP ES
  800. CALL OLD_PA2  ; Perform
  801. cEnd
  802. ERR_PAINT:
  803. MOV B$TILFLG,0 ;Turn Tiling off
  804. JMP B$ERR_FC
  805. OLD_PA2: ; Entry point for PAINT with tiling
  806. MOV B$TILFLG,-1 ;Tile is active
  807. PUSH DX ;Save border color
  808. PUSH CX ;Save ptr to backgrd string descriptor
  809. CALL B$INTQUE  ;Init the Queue
  810. CALL BNDS_CHK ;Check if coordinates are inside screen or viewport
  811. JNC POPNRET  ;coords out of bounds: don't do PAINT
  812. push bx ;preserve bx across mapxyc call
  813. CALL [b$MapXYC] ;Graphics Cursor:=(CX,DX)
  814. pop bx ;restore ptr to fg string desc
  815. CALL FGSTRINI ;Initialize foreground paint string
  816. POP BX ;Restore ptr to background string descriptor
  817. CALL B$ClrBgStr ;initialize null string for background
  818. CMP BX,-1 ;is background string defaulted?
  819. JZ TILEINIT ;yes: branch to tile ATRBYT initialization
  820. CALL BGSTRINI ;initialize background string
  821. CALL MATCH3 ;check for three consecutive matching
  822. ;bytes in paint tile and background
  823. ;tile and abort if found
  824. JC ERR_PAINT ;Three matches found: issue error
  825. TILEINIT: ;Tile initialization
  826. POP AX ;Restore border color attribute
  827. CMP AX,-1 ;Is border color defaulted?
  828. JNZ BORDER_CHK ;NO: Go check for valid border color
  829. STC ;Set carry
  830. CALL B$GETFBC  ;Get foreground color in AL
  831. BORDER_CHK:
  832. CALL B$PaintInit ;OEM routine to check for valid border color
  833. MOV DX,WORD PTR B$GYPOS ;DX:=current y coord
  834. CALL B$SetTileIndex ;set B$TILNDX to proper byte of tile string
  835. CALL TILATR ;set up tiling mask in ATRBYT
  836. JMP B$PAINTBEG ;Valid border: go begin painting
  837. POPNRET: ;Pop stack and abort PAINT statement
  838. POP CX ;pop backgrd string ptr
  839. DONT_PAINT:
  840. POP DX ;pop border color
  841. MOV B$TILFLG,0 ;clear tiling flag
  842. RET ;Return
  843. ;***
  844. ; BNDS_CHK - routine checks for valid PAINT coordinates,
  845. ; Purpose:
  846. ; To see if the coordinates specified in the PAINT statement
  847. ; are within the current viewport.  May be called from B$PAIN
  848. ; or B$PNTC.
  849. ;
  850. ; If clipping is supported:
  851. ; If the coordinates are inside the viewport, then continue
  852. ; to process the PAINT statement, otherwise, return with
  853. ; carry clear to indicate that PAINT statement should be
  854. ; aborted without issuing an error message.
  855. ; If clipping is not supported:
  856. ; If the coordinates are inside the viewport, then continue
  857. ; to process the PAINT statement, otherwise, issue a
  858. ; function call error.
  859. ;
  860. ; Entry:
  861. ; None.
  862. ; Exit:
  863. ; Graphics cursor updated if coordinates inside current viewport.
  864. ; Modifies:
  865. ; AX,CX,DX.
  866. ;****
  867. BNDS_CHK:
  868. MOV CX,WORD PTR B$GXPOS ;CX:=Graphics accumulator x position
  869. MOV DX,WORD PTR B$GYPOS ;DX:=Graphics accumulator y position
  870. PUSH BX ;Save paint parameter
  871. CALL B$INVIEW  ;Returns carry set if coords within
  872. ;current viewport
  873. POP BX ;Restore paint parameter
  874. RET ;return with carry flag
  875. sEnd GR_TEXT 
  876. END