home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / C / TGE129D / 320X200.ASM < prev    next >
Assembly Source File  |  1993-09-12  |  40KB  |  1,877 lines

  1. ; 320x200x256
  2. ; Loadable driver for The Graphics Engine
  3. ; Copyright (c) 1993 by Matthew Hildebrand
  4. ; Turbo Assembler syntax
  5.  
  6. IDEAL
  7. MODEL LARGE TGE320X200_TEXT
  8. P386N
  9.  
  10.  
  11. SCREEN_WIDE    =    320
  12. SCREEN_DEEP    =    200
  13. NUM_COLOURS    =    256
  14.  
  15.  
  16.                 CODESEG TGE320X200_TEXT
  17.         ORG    0
  18.  
  19. ;*** Signature
  20.             db    'TGE3'
  21. ;*** Non-I/O functions
  22. _initGraphics        dw    initGraphics        ; initGraphics
  23.             dw    ?
  24. _deInitGraphics        dw    0            ; deInitGraphics
  25.             dw    ?
  26. _setPaletteReg        dw    setPaletteReg        ; setPaletteReg
  27.             dw    ?
  28. _getPaletteReg        dw    getPaletteReg        ; getPaletteReg
  29.             dw    ?
  30. _setBlockPalette    dw    setBlockPalette        ; setBlockPalette
  31.             dw    ?
  32. _getBlockPalette    dw    getBlockPalette        ; getBlockPalette
  33.             dw    ?
  34. _colourCloseTo        dw    0            ; colourCloseTo
  35.             dw    ?
  36. _colourCloseToX        dw    0            ; colourCloseToX
  37.             dw    ?
  38. _imageSize        dw    0            ; imageSize
  39.             dw    ?
  40. _imageSizeDim        dw    0            ; imageSizeDim
  41.             dw    ?
  42. _setPage        dw    0            ; setPage (not implemented yet)
  43.             dw    ?
  44.  
  45. ;*** Currently active I/O functions (filled in by loadGraphDriver())
  46.             dd    20    DUP(?)
  47.  
  48. ;*** Input functions
  49. _getImage_scr        dw    getImage_scr        ; getImage
  50.             dw    ?
  51. _getImage_mem        dw    0
  52.             dw    ?
  53. _getLine_scr        dw    getLine_scr              ; getLine
  54.             dw    ?
  55. _getLine_mem        dw    getLine_mem
  56.             dw    ?
  57. _getPixel_scr        dw    getPixel_scr        ; getPixel
  58.             dw    ?
  59. _getPixel_mem        dw    getPixel_mem
  60.             dw    ?
  61.  
  62. ;*** Output functions
  63. _putImage_scr_copy    dw    putImage        ; putImage
  64.             dw    ?
  65. _putImage_scr_and    dw    0
  66.             dw    ?
  67. _putImage_scr_not    dw    0
  68.             dw    ?
  69. _putImage_scr_or    dw    0
  70.             dw    ?
  71. _putImage_scr_xor    dw    0
  72.             dw    ?
  73. _putImage_mem_copy    dw    0
  74.             dw    ?
  75. _putImage_mem_and    dw    0
  76.             dw    ?
  77. _putImage_mem_not    dw    0
  78.             dw    ?
  79. _putImage_mem_or    dw    0
  80.             dw    ?
  81. _putImage_mem_xor    dw    0
  82.             dw    ?
  83. _putImageInv_scr_copy    dw    putImageInv        ; putImageInv
  84.             dw    ?
  85. _putImageInv_scr_and    dw    0
  86.             dw    ?
  87. _putImageInv_scr_not    dw      0
  88.             dw    ?
  89. _putImageInv_scr_or    dw      0
  90.             dw    ?
  91. _putImageInv_scr_xor    dw    0
  92.             dw    ?
  93. _putImageInv_mem_copy    dw    0
  94.             dw    ?
  95. _putImageInv_mem_and    dw    0
  96.             dw    ?
  97. _putImageInv_mem_not    dw    0
  98.             dw    ?
  99. _putImageInv_mem_or    dw    0
  100.             dw    ?
  101. _putImageInv_mem_xor    dw    0
  102.             dw    ?
  103. _putLine_scr_copy       dw      putLine_scr_copy        ; putLine
  104.             dw    ?
  105. _putLine_scr_and          dw      0
  106.             dw    ?
  107. _putLine_scr_not          dw      0
  108.             dw    ?
  109. _putLine_scr_or          dw      0
  110.             dw    ?
  111. _putLine_scr_xor          dw    0
  112.             dw    ?
  113. _putLine_mem_copy    dw    putLine_mem_copy
  114.             dw    ?
  115. _putLine_mem_and    dw      0
  116.             dw    ?
  117. _putLine_mem_not    dw      0
  118.             dw    ?
  119. _putLine_mem_or        dw      0
  120.             dw    ?
  121. _putLine_mem_xor    dw    0
  122.             dw    ?
  123. _putLineInv_scr_copy       dw    0            ; putLineInv
  124.             dw    ?
  125. _putLineInv_scr_and       dw    0
  126.             dw    ?
  127. _putLineInv_scr_not       dw    0
  128.             dw    ?
  129. _putLineInv_scr_or       dw    0
  130.             dw    ?
  131. _putLineInv_scr_xor       dw    0
  132.             dw    ?
  133. _putLineInv_mem_copy    dw    putLineInv_mem_copy
  134.             dw    ?
  135. _putLineInv_mem_and    dw    0
  136.             dw    ?
  137. _putLineInv_mem_not    dw    0
  138.             dw    ?
  139. _putLineInv_mem_or    dw    0
  140.             dw    ?
  141. _putLineInv_mem_xor    dw    0
  142.             dw    ?
  143. _putPixel_scr_copy    dw    putPixel_scr_copy    ; putPixel
  144.             dw    ?
  145. _putPixel_scr_and    dw      putPixel_scr_and
  146.             dw    ?
  147. _putPixel_scr_not    dw      putPixel_scr_not
  148.             dw    ?
  149. _putPixel_scr_or    dw      putPixel_scr_or
  150.             dw    ?
  151. _putPixel_scr_xor    dw    putPixel_scr_xor
  152.             dw    ?
  153. _putPixel_mem_copy    dw    putPixel_mem_copy
  154.             dw    ?
  155. _putPixel_mem_and    dw      putPixel_mem_and
  156.             dw    ?
  157. _putPixel_mem_not    dw    putPixel_mem_not
  158.             dw    ?
  159. _putPixel_mem_or    dw    putPixel_mem_or
  160.             dw    ?
  161. _putPixel_mem_xor    dw    putPixel_mem_xor
  162.             dw    ?
  163. _line_scr_copy        dw    line            ; line
  164.             dw    ?
  165. _line_scr_and        dw      0
  166.             dw    ?
  167. _line_scr_not        dw      0
  168.             dw    ?
  169. _line_scr_or        dw      0
  170.             dw    ?
  171. _line_scr_xor        dw    0
  172.             dw    ?
  173. _line_mem_copy        dw    0
  174.             dw    ?
  175. _line_mem_and        dw    0
  176.             dw    ?
  177. _line_mem_not        dw    0
  178.             dw    ?
  179. _line_mem_or        dw    0
  180.             dw    ?
  181. _line_mem_xor        dw    0
  182.             dw    ?
  183. _horizLine_scr_copy    dw    horizLine_scr_copy    ; horizLine
  184.             dw    ?
  185. _horizLine_scr_and    dw      0
  186.             dw    ?
  187. _horizLine_scr_not    dw      0
  188.             dw    ?
  189. _horizLine_scr_or    dw      0
  190.             dw    ?
  191. _horizLine_scr_xor    dw    0
  192.             dw    ?
  193. _horizLine_mem_copy    dw    horizLine_mem_copy
  194.             dw    ?
  195. _horizLine_mem_and    dw      0
  196.             dw    ?
  197. _horizLine_mem_not    dw      0
  198.             dw    ?
  199. _horizLine_mem_or    dw      0
  200.             dw    ?
  201. _horizLine_mem_xor    dw    0
  202.             dw    ?
  203. _vertLine_scr_copy    dw    0             ; vertLine
  204.             dw    ?
  205. _vertLine_scr_and    dw    0
  206.             dw    ?
  207. _vertLine_scr_not    dw    0
  208.             dw    ?
  209. _vertLine_scr_or    dw    0
  210.             dw    ?
  211. _vertLine_scr_xor    dw    0
  212.             dw    ?
  213. _vertLine_mem_copy    dw    0
  214.             dw    ?
  215. _vertLine_mem_and    dw    0
  216.             dw    ?
  217. _vertLine_mem_not    dw    0
  218.             dw    ?
  219. _vertLine_mem_or    dw    0
  220.             dw    ?
  221. _vertLine_mem_xor    dw    0
  222.             dw    ?
  223. _drawRect_scr_copy    dw    0            ; drawRect
  224.             dw    ?
  225. _drawRect_scr_and    dw    0
  226.             dw    ?
  227. _drawRect_scr_not    dw    0
  228.             dw    ?
  229. _drawRect_scr_or    dw    0
  230.             dw    ?
  231. _drawRect_scr_xor    dw    0
  232.             dw    ?
  233. _drawRect_mem_copy    dw    0
  234.             dw    ?
  235. _drawRect_mem_and    dw    0
  236.             dw    ?
  237. _drawRect_mem_not    dw    0
  238.             dw    ?
  239. _drawRect_mem_or    dw    0
  240.             dw    ?
  241. _drawRect_mem_xor    dw    0
  242.             dw    ?
  243. _filledRect_scr_copy    dw    filledRect        ; filledRect
  244.             dw    ?
  245. _filledRect_scr_and    dw      0
  246.             dw    ?
  247. _filledRect_scr_not    dw      0
  248.             dw    ?
  249. _filledRect_scr_or    dw      0
  250.             dw    ?
  251. _filledRect_scr_xor    dw    0
  252.             dw    ?
  253. _filledRect_mem_copy    dw    0
  254.             dw    ?
  255. _filledRect_mem_and    dw    0
  256.             dw    ?
  257. _filledRect_mem_not    dw    0
  258.             dw    ?
  259. _filledRect_mem_or    dw    0
  260.             dw    ?
  261. _filledRect_mem_xor    dw    0
  262.             dw    ?
  263. _clearGraphics_scr_copy    dw    clearGraphics        ; clearGraphics
  264.             dw    ?
  265. _clearGraphics_scr_and    dw      0
  266.             dw    ?
  267. _clearGraphics_scr_not    dw      0
  268.             dw    ?
  269. _clearGraphics_scr_or    dw      0
  270.             dw    ?
  271. _clearGraphics_scr_xor    dw    0
  272.             dw    ?
  273. _clearGraphics_mem_copy    dw    0
  274.             dw    ?
  275. _clearGraphics_mem_and    dw    0
  276.             dw    ?
  277. _clearGraphics_mem_not    dw    0
  278.             dw    ?
  279. _clearGraphics_mem_or    dw    0
  280.             dw    ?
  281. _clearGraphics_mem_xor    dw    0
  282.             dw    ?
  283. _ellipse_scr_copy    dw    0            ; ellipse
  284.             dw    ?
  285. _ellipse_scr_and    dw    0
  286.             dw    ?
  287. _ellipse_scr_not    dw    0
  288.             dw    ?
  289. _ellipse_scr_or        dw    0
  290.             dw    ?
  291. _ellipse_scr_xor    dw    0
  292.             dw    ?
  293. _ellipse_mem_copy    dw    0
  294.             dw    ?
  295. _ellipse_mem_and    dw    0
  296.             dw    ?
  297. _ellipse_mem_not    dw    0
  298.             dw    ?
  299. _ellipse_mem_or        dw    0
  300.             dw    ?
  301. _ellipse_mem_xor    dw    0
  302.             dw    ?
  303. _filledEllipse_scr_copy    dw    0            ; filledEllipse
  304.             dw    ?
  305. _filledEllipse_scr_and    dw    0
  306.             dw    ?
  307. _filledEllipse_scr_not    dw    0
  308.             dw    ?
  309. _filledEllipse_scr_or    dw    0
  310.             dw    ?
  311. _filledEllipse_scr_xor    dw    0
  312.             dw    ?
  313. _filledEllipse_mem_copy    dw    0
  314.             dw    ?
  315. _filledEllipse_mem_and    dw    0
  316.             dw    ?
  317. _filledEllipse_mem_not    dw    0
  318.             dw    ?
  319. _filledEllipse_mem_or    dw    0
  320.             dw    ?
  321. _filledEllipse_mem_xor    dw    0
  322.             dw    ?
  323. _circle_scr_copy    dw    0            ; circle
  324.             dw    ?
  325. _circle_scr_and        dw    0
  326.             dw    ?
  327. _circle_scr_not        dw    0
  328.             dw    ?
  329. _circle_scr_or        dw    0
  330.             dw    ?
  331. _circle_scr_xor        dw    0
  332.             dw    ?
  333. _circle_mem_copy    dw    0
  334.             dw    ?
  335. _circle_mem_and        dw    0
  336.             dw    ?
  337. _circle_mem_not        dw    0
  338.             dw    ?
  339. _circle_mem_or        dw    0
  340.             dw    ?
  341. _circle_mem_xor        dw    0
  342.             dw    ?
  343. _filledCircle_scr_copy    dw    0            ; filledCircle
  344.             dw    ?
  345. _filledCircle_scr_and    dw    0
  346.             dw    ?
  347. _filledCircle_scr_not    dw    0
  348.             dw    ?
  349. _filledCircle_scr_or    dw    0
  350.             dw    ?
  351. _filledCircle_scr_xor    dw    0
  352.             dw    ?
  353. _filledCircle_mem_copy    dw    0
  354.             dw    ?
  355. _filledCircle_mem_and    dw    0
  356.             dw    ?
  357. _filledCircle_mem_not    dw    0
  358.             dw    ?
  359. _filledCircle_mem_or    dw    0
  360.             dw    ?
  361. _filledCircle_mem_xor    dw    0
  362.             dw    ?
  363. _fillRegion_scr_copy    dw    0            ; fillRegion
  364.             dw    ?
  365. _fillRegion_scr_and    dw    0
  366.             dw    ?
  367. _fillRegion_scr_not    dw    0
  368.             dw    ?
  369. _fillRegion_scr_or    dw    0
  370.             dw    ?
  371. _fillRegion_scr_xor    dw    0
  372.             dw    ?
  373. _fillRegion_mem_copy    dw    0
  374.             dw    ?
  375. _fillRegion_mem_and    dw    0
  376.             dw    ?
  377. _fillRegion_mem_not    dw    0
  378.             dw    ?
  379. _fillRegion_mem_or    dw    0
  380.             dw    ?
  381. _fillRegion_mem_xor    dw    0
  382.             dw    ?
  383. _fillLine_scr_copy    dw    horizLine_scr_copy    ; fillLine
  384.             dw    ?
  385. _fillLine_scr_and    dw      0
  386.             dw    ?
  387. _fillLine_scr_not    dw      0
  388.             dw    ?
  389. _fillLine_scr_or    dw      0
  390.             dw    ?
  391. _fillLine_scr_xor    dw    0
  392.             dw    ?
  393. _fillLine_mem_copy    dw    horizLine_mem_copy
  394.             dw    ?
  395. _fillLine_mem_and    dw      0
  396.             dw    ?
  397. _fillLine_mem_not    dw      0
  398.             dw    ?
  399. _fillLine_mem_or    dw      0
  400.             dw    ?
  401. _fillLine_mem_xor    dw    0
  402.             dw    ?
  403. ;*** Mode information
  404. scrnMaxX        dw    319    ; physical dimensions
  405. scrnMaxY        dw    199
  406. maxColour        dw    255    ; maximum colour number
  407. xRatio                   dw    8    ; aspect ratio 8:5 (320:200 in
  408. yRatio            dw    5    ;   lowest terms)
  409. bitsPerPixel        dw    8    ; 8 bits per pixel
  410. inMaxX            dw    319    ; current input screen dimensions
  411. inMaxY            dw    199
  412. outMaxX            dw    319    ; current output screen dimensions
  413. outMaxY            dw    199
  414. inScreenWide        dw    ?    ; needed only for virtual screens
  415. outScreenWide        dw    ?
  416. ;*** Viewport information
  417. inViewportULX        dw    0
  418. inViewportULY        dw    0
  419. inViewportLRX        dw    319
  420. inViewportLRY        dw    199
  421. outViewportULX        dw    0
  422. outViewportULY        dw    0
  423. outViewportLRX        dw    319
  424. outViewportLRY        dw    199
  425. ;*** Paging information
  426. pagingSupported        dw    ?    ; not implemented yet
  427. curPage            dw    ?    ; not implemented yet
  428. maxPage            dw    ?    ; not implemented yet
  429. ;*** Force (image width MOD imageWideAdjust) = 0.
  430. imageWideAdjust        dw    ?    ; not implemented yet
  431. ;*** Current and screen addresses
  432.     LABEL    inAddr    DWORD        ; current input address
  433. inOff    dw    0
  434. inSeg    dw    0A000h
  435.     LABEL    outAddr    DWORD        ; current output address
  436. outOff    dw    0
  437. outSeg    dw    0A000h
  438.     LABEL    scrAddr    DWORD        ; screen address
  439. scrOff    dw    0
  440. scrSeg    dw    0A000h
  441. ;*** Copyright string
  442.     db    'The Graphics Engine -- Copyright (c) 1993 by Matthew Hildebrand'
  443.  
  444.  
  445. inited        db    0               ; already initialized flag
  446. tempPalette    db      768    DUP(?)    ; for palette data
  447. lineOffs    dw    200    DUP(?)    ; line start offset table
  448.  
  449.  
  450. ;*****
  451. ;***** initGraphics
  452. ;*****
  453.  
  454. PROC    C    initGraphics
  455.   cmp    [inited],0
  456.   je    @@L1                ; skip if already done
  457.  
  458.   mov    ax,0013h            ; short initialization:
  459.   int    10h                ; turn on graphics and leave
  460.   mov    ax,1
  461.   retf
  462.  
  463.     @@L1:
  464.   push    di                ; first initialization
  465.   mov    [inited],1
  466.  
  467.   mov    ax,1200h            ; enable default palette loading
  468.   mov    bl,31h
  469.   int    10h
  470.   mov    ax,0013h            ; turn on 320x200x256
  471.   int    10h
  472.  
  473.   mov    di,OFFSET lineOffs        ; set up line start offset table
  474.   mov    ax,cs
  475.   mov    es,ax
  476.   mov    cx,200
  477.   xor    bx,bx
  478.   cld
  479.     @@LLoop:
  480.   mov    ax,320
  481.   mul    bx
  482.   inc    bx
  483.   stosw
  484.   loop    @@LLoop
  485.  
  486.   mov    ax,1                ; return success flag
  487.   pop    di
  488.   retf
  489. ENDP
  490.  
  491.  
  492. ;*****
  493. ;***** putImage
  494. ;*****
  495.  
  496. PROC    C    putImage
  497.     ARG    x:WORD,y:WORD,image:DWORD
  498.     LOCAL    @@destAdd:WORD,@@srcAdd:WORD,@@xSize:WORD
  499.   push    ds si di
  500.  
  501.   mov    [@@destAdd],320
  502.   mov    [@@srcAdd],0
  503.  
  504.   lds    si,[image]
  505.   les    di,[outAddr]
  506.   cld
  507.  
  508.   lodsw                    ; xsize
  509.   or    ax,ax
  510.   jz    @@Exit
  511.   mov    cx,ax
  512.   mov    [@@xSize],cx
  513.   lodsw                    ; ysize
  514.   or    ax,ax
  515.   jz    @@Exit
  516.   mov    dx,ax
  517.  
  518.   mov    ax,[x]
  519.   cmp    ax,[outViewportLRX]        ; check x <= OUTVIEWPORTLRX
  520.   jg    @@Exit
  521.   cmp    ax,[outViewportULX]        ; check x >= OUTVIEWPORTULX
  522.   jl    @@xLessThanMin
  523.  
  524.     @@checkxMax:
  525.   mov    ax,[x]
  526.   add    ax,cx            ; right edge of image
  527.   cmp    ax,[outViewportLRX]
  528.   jg    @@truncateRightImage    ; truncate if necessary
  529.  
  530.     @@checkyMin:
  531.   mov    ax,[y]
  532.   cmp    ax,[outViewportLRY]        ; check y <= OUTVIEWPORTLRY
  533.   jg    @@Exit
  534.   cmp    ax,[outViewportULY]        ; check y >= OUTVIEWPORTULY
  535.   jl    @@yLessThanMin
  536.  
  537.     @@checkyMax:
  538.   mov    ax,[y]
  539.   add    ax,dx            ; bottom of image
  540.   cmp    ax,[outViewportLRY]
  541.   jg    @@truncateBottomImage    ; truncate if necessary
  542.  
  543.   jmp    short    @@drawImage    ; jump to draw logic
  544.  
  545.     @@xLessThanMin:            ; clip x to 0
  546.   mov    bx,[outViewportULX]
  547.   mov    [x],bx
  548.   sub    bx,ax
  549.   add    si,bx
  550.   sub    cx,bx
  551.   cmp    cx,0
  552.   jle    @@Exit            ; quit if offscreen
  553.   add    [@@srcAdd],bx
  554.   jmp    short    @@checkxMax
  555.  
  556.     @@Exit:                ; quit putImage()
  557.   pop    di si ds
  558.   leave
  559.   retf
  560.  
  561.     @@truncateRightImage:        ; truncate the excess of right edge
  562.   sub    ax,[outViewportLRX]    ; ax=right edge from before
  563.   dec    ax
  564.   sub    cx,ax
  565.   add    [@@srcAdd],ax
  566.   jmp    short    @@checkyMin
  567.  
  568.     @@yLessThanMin:            ; clip y to OUTVIEWPORTULY
  569.   mov    bx,[outViewportULY]
  570.   mov    [y],bx
  571.   sub    bx,ax
  572.   sub    dx,bx
  573.   cmp    dx,0
  574.   jle    @@Exit            ; quit if offscreen
  575.   push    dx cx
  576.   mov    ax,bx
  577.   mov    cx,[@@xSize]
  578.   mul    cx
  579.   pop    cx dx
  580.   add    si,ax
  581.   jmp    short    @@checkyMax
  582.  
  583.     @@truncateBottomImage:        ; clip y to OUTVIEWPORTLRY
  584.   sub    ax,[outViewportLRY]
  585.   dec    ax
  586.   sub    dx,ax
  587.   cmp    dx,0            ; quit if no lines left
  588.   jle    @@Exit            ; fall through to @@drawImage
  589.  
  590.     @@drawImage:            ; label for @@yGreaterThanMax jmp
  591.   push    dx                ; calculate pixel address
  592.   mov    dx,[x]
  593.   mov    ax,[y]
  594.   xchg    ah,al            ; ax=256*y
  595.   add    dx,ax            ; dx=256*y+x
  596.   shr    ax,2            ; ax=64*y
  597.   add    dx,ax            ; dx=320*y+x
  598.   mov    di,dx
  599.   pop    dx
  600.  
  601.   mov    ax,[@@destAdd]
  602.   sub    ax,cx                ; update destAdd
  603.  
  604.   mov    bx,cx                ; BX = CX
  605.   jmp    short    @@LoopB            ; jump to loop entry point
  606.     @@LoopA:
  607.   mov    cx,bx                ; CX = line length in bytes
  608.   add    di,ax                ; update DI
  609.   add    si,[@@srcAdd]            ; update SI
  610.     @@LoopB:
  611.   push    cx                ; store CX
  612.   shr    cx,2                ; CX = line length in dwords
  613.   rep    movsd                ; move the dwords
  614.   pop    cx                ; restore CX
  615.   and    cx,0000000000000011b        ; CX = number of residual bytes
  616.   rep    movsb                ; move the residual bytes, if any
  617.   dec    dx                ; decrement loop counter
  618.   jnz    @@LoopA                ; restart loop if necesary
  619.   jmp    short    @@Exit            ; done loop, quit
  620. ENDP
  621.  
  622.  
  623. ;*****
  624. ;***** putImageInv
  625. ;*****
  626.  
  627. PROC    C    putImageInv
  628.     ARG    x:WORD,y:WORD,image:DWORD
  629.     LOCAL    @@destAdd:WORD,@@srcAdd:WORD,@@xSize:WORD
  630.   push    ds si di
  631.  
  632.   mov    [@@destAdd],320
  633.   mov    [@@srcAdd],0
  634.  
  635.   lds    si,[image]
  636.   les    di,[outAddr]
  637.   cld
  638.  
  639.   lodsw                    ; xsize
  640.   or    ax,ax
  641.   jz    @@Exit
  642.   mov    cx,ax
  643.   mov    [@@xSize],cx
  644.   lodsw                    ; ysize
  645.   or    ax,ax
  646.   jz    @@Exit
  647.   mov    dx,ax
  648.  
  649.   mov    ax,[x]
  650.   cmp    ax,[outViewportLRX]        ; check x <= OUTVIEWPORTLRX
  651.   jg    @@Exit
  652.   cmp    ax,[outViewportULX]        ; check x >= OUTVIEWPORTULX
  653.   jl    @@xLessThanMin
  654.  
  655.     @@checkxMax:
  656.   mov    ax,[x]
  657.   add    ax,cx            ; right edge of image
  658.   cmp    ax,[outViewportLRX]
  659.   jg    @@truncateRightImage    ; truncate if necessary
  660.  
  661.     @@checkyMin:
  662.   mov    ax,[y]
  663.   cmp    ax,[outViewportLRY]        ; check y <= OUTVIEWPORTLRY
  664.   jg    @@Exit
  665.   cmp    ax,[outViewportULY]        ; check y >= OUTVIEWPORTULY
  666.   jl    @@yLessThanMin
  667.  
  668.     @@checkyMax:
  669.   mov    ax,[y]
  670.   add    ax,dx            ; bottom of image
  671.   cmp    ax,[outViewportLRY]
  672.   jg    @@truncateBottomImage    ; truncate if necessary
  673.  
  674.   jmp    short    @@drawImage    ; jump to draw logic
  675.  
  676.     @@xLessThanMin:            ; clip x to 0
  677.   mov    bx,[outViewportULX]
  678.   mov    [x],bx
  679.   sub    bx,ax
  680.   add    si,bx
  681.   sub    cx,bx
  682.   cmp    cx,0
  683.   jle    @@Exit            ; quit if offscreen
  684.   add    [@@srcAdd],bx
  685.   jmp    short    @@checkxMax
  686.  
  687.     @@Exit:                ; quit putImage()
  688.   pop    di si ds
  689.   leave
  690.   retf
  691.  
  692.     @@truncateRightImage:        ; truncate the excess of right edge
  693.   sub    ax,[outViewportLRX]    ; ax=right edge from before
  694.   dec    ax
  695.   sub    cx,ax
  696.   add    [@@srcAdd],ax
  697.   jmp    short    @@checkyMin
  698.  
  699.     @@yLessThanMin:            ; clip y to OUTVIEWPORTULY
  700.   mov    bx,[outViewportULY]
  701.   mov    [y],bx
  702.   sub    bx,ax
  703.   sub    dx,bx
  704.   cmp    dx,0
  705.   jle    @@Exit            ; quit if offscreen
  706.   push    dx cx
  707.   mov    ax,bx
  708.   mov    cx,[@@xSize]
  709.   mul    cx
  710.   pop    cx dx
  711.   add    si,ax
  712.   jmp    short    @@checkyMax
  713.  
  714.     @@truncateBottomImage:        ; clip y to OUTVIEWPORTLRY
  715.   sub    ax,[outViewportLRY]
  716.   dec    ax
  717.   sub    dx,ax
  718.   cmp    dx,0            ; quit if no lines left
  719.   jle    @@Exit            ; fall through to @@drawImage
  720.  
  721.     @@drawImage:            ; label for @@yGreaterThanMax jmp
  722. ; calculate the pixel address
  723.   push    dx
  724.   mov    dx,[x]
  725.   mov    ax,[y]
  726.   xchg    ah,al            ; ax=256*y
  727.   add    dx,ax            ; dx=256*y+x
  728.   shr    ax,2            ; ax=64*y
  729.   add    dx,ax            ; dx=320*y+x
  730.   mov    di,dx
  731.   pop    dx
  732.  
  733.   sub    [@@destAdd],cx            ; update destAdd
  734.   mov    bx,cx
  735.   jmp    short    @@xLoop
  736.     @@yLoop:
  737.   add    di,[@@destAdd]
  738.   add    si,[@@srcAdd]
  739.   mov    cx,bx
  740.  
  741.     @@xLoop:
  742.   lodsb
  743.   or    al,al
  744.   jz    @@Invisible
  745.   stosb
  746.   loop    @@xLoop
  747.   dec    dx
  748.   jnz    @@yLoop
  749.   jmp    short    @@Exit
  750.  
  751.     @@Invisible:
  752.   inc    di
  753.   loop    @@xLoop
  754.  
  755.   dec    dx
  756.   jnz    @@yLoop
  757.   jmp    short    @@Exit
  758. ENDP
  759.  
  760.  
  761. ;*****
  762. ;***** getImage
  763. ;*****
  764.  
  765. PROC    C    getImage_scr
  766.     ARG    x1:WORD,y1:WORD,x2:WORD,y2:WORD,image:DWORD
  767.   push    ds si di
  768.  
  769.   mov    bx,[inViewportULX]        ; preload for speed
  770.   mov    cx,[inViewportLRX]
  771.  
  772.   mov    ax,[x1]                ; clip x1
  773.   cmp    ax,bx
  774.   jge    @@L1b
  775.   mov    [x1],bx
  776.   jmp    short    @@L2a
  777.     @@L1b:
  778.   cmp    ax,cx
  779.   jle    @@L2a
  780.   mov    [x1],cx
  781.  
  782.     @@L2a:
  783.   mov    ax,[x2]                ; clip x2
  784.   cmp    ax,bx
  785.   jge    @@L2b
  786.   mov    [x2],bx
  787.   jmp    short  @@L3a
  788.     @@L2b:
  789.   cmp    ax,cx
  790.   jle    @@L3a
  791.   mov    [x2],cx
  792.  
  793.     @@L3a:
  794.   mov    bx,[inViewportULY]        ; preload for speed
  795.   mov    cx,[inViewportLRY]
  796.  
  797.   mov    ax,[y1]                ; clip y1
  798.   cmp   ax,bx
  799.   jge    @@L3b
  800.   mov    [y1],bx
  801.   jmp    short    @@L4a
  802.     @@L3b:
  803.   cmp    ax,cx
  804.   jle    @@L4a
  805.   mov    [y1],cx
  806.  
  807.     @@L4a:
  808.   mov    ax,[y2]                ; clip y2
  809.   cmp    ax,bx
  810.   jge    @@L4b
  811.   mov    [y2],bx
  812.   jmp    short    @@L5
  813.     @@L4b:
  814.   cmp    ax,cx
  815.   jle    @@L5
  816.   mov    [y2],cx
  817.  
  818.     @@L5:
  819.   mov    ax,[x2]                ; make sure x2>=x1
  820.   cmp    ax,[x1]
  821.   jge    @@L6
  822.   mov    dx,[x1]
  823.   mov    [x2],dx
  824.   mov    [x1],ax
  825.     @@L6:
  826.   mov    ax,[y2]                ; make sure y2>=y1
  827.   cmp    ax,[y1]
  828.   jge    @@L7
  829.   mov    dx,[y1]
  830.   mov    [y2],dx
  831.   mov    [y1],ax
  832.  
  833.     @@L7:
  834.   cld
  835.   lds    si,[inAddr]            ; set up DS:SI
  836.   mov    bx,[y1]
  837.   shl    bx,1
  838.   add    si,[lineOffs+bx]
  839.   add    si,[x1]
  840.  
  841.   les    di,[image]            ; set up ES:DI
  842.   mov    ax,[x2]
  843.   sub    ax,[x1]
  844.   inc    ax
  845.   push    ax
  846.   stosw                    ; store image width
  847.   mov    ax,[y2]
  848.   sub    ax,[y1]
  849.   inc    ax
  850.   stosw                    ; store image depth
  851.  
  852.   mov    ax,[x2]                ; calculate srcAdd
  853.   sub    ax,[x1]
  854.   mov    dx,319
  855.   sub    dx,ax
  856.   push    dx                ; save srcAdd for later
  857.  
  858.   mov    ax,[y2]                ; y loop counter
  859.   sub    ax,[y1]
  860.   mov    dx,ax
  861.   inc    dx
  862.  
  863.   pop    ax                ; pop srcAdd
  864.   pop    cx                ; pop image width
  865.  
  866.   mov    bx,cx                ; BX = CX
  867.   jmp    short    @@LoopB            ; jump to loop entry point
  868.     @@LoopA:
  869.   mov    cx,bx                ; CX = line length in bytes
  870.   add    si,ax                ; update SI
  871.     @@LoopB:
  872.   push    cx                ; store CX
  873.   shr    cx,2                ; CX = line length in dwords
  874.   rep    movsd                ; move the dwords
  875.   pop    cx                ; restore CX
  876.   and    cx,0000000000000011b        ; CX = number of residual bytes
  877.   rep    movsb                ; move the residual bytes, if any
  878.   dec    dx                ; decrement loop counter
  879.   jnz    @@LoopA                ; restart loop if necesary
  880.  
  881.   pop    di si ds            ; restore registers
  882.   leave                    ; clean up call stack
  883.   retf                    ; return
  884. ENDP
  885.  
  886.  
  887. ;*****
  888. ;***** putLine
  889. ;*****
  890.  
  891. PROC    C       putLine_scr_copy
  892.     ARG    lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  893.   push    ds si di
  894.   cld
  895.   mov   ax,0A000h
  896.   mov   es,ax
  897.   xor   di,di
  898.   lds    si,[buf]
  899.  
  900.   mov    bx,[lineNum]
  901.   shl    bx,1
  902.   add    di,[cs:lineOffs+bx]
  903.   add    di,[xOff]
  904.   mov    cx,[lineLen]
  905.   rep   movsb
  906.  
  907.   pop    di si ds
  908.   leave
  909.   retf
  910. ENDP
  911. ;PROC    C    putLine_scr_copy
  912. ;    ARG    lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DWORD
  913. ;  push    ds si di
  914. ;
  915. ;  cld
  916. ;  mov    ax,0A000h
  917. ;  mov    es,ax
  918. ;  lds    si,[buf]
  919. ;
  920. ;  mov    bx,[lineNum]
  921. ;  shl    bx,1
  922. ;  mov    di,[lineOffs+bx]
  923. ;  add    di,[xOff]
  924. ;  mov    cx,[lineLen]
  925. ;
  926. ;  mov   dx,cx                           ; DX = CX
  927. ;  shr    cx,2                ; CX = line length in dwords
  928. ;  rep    movsd                ; copy the dwords
  929. ;  mov    cx,dx                ; CX = line length in bytes
  930. ;  and    cx,0000000000000011b        ; CX = number of residual bytes
  931. ;  rep    movsb                ; copy the residual bytes, if any
  932. ;
  933. ;  pop    di si ds            ; restore registers
  934. ;  leave                    ; clean up call stack
  935. ;  retf                    ; return
  936. ;ENDP
  937.  
  938. PROC    C    putLine_mem_copy
  939.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DWORD
  940.   push    ds si di            ; save these registers
  941.  
  942.   xor    eax,eax                ; clear EAX
  943.   xor    edx,edx                ; clear EDX
  944.   xor    edi,edi                ; clear EDI
  945.  
  946.   les    di,[outAddr]            ; load output address
  947.   mov    ax,[y]
  948.   mov    dx,[outScreenWide]
  949.   mul    edx                    ; EDX:EAX = offset - EDI - x
  950.   add    edi,eax                ; EDI = offset - x
  951.   mov    dx,[xOff]
  952.   add    edi,edx                ; EDI = offset
  953.   mov    edx,edi                ; EDX = offset
  954.   shr    edx,4                ; EDX = # of paragraphs (segments)
  955.   add    dx,[outSeg]            ; DX = new segment
  956.   mov    es,dx                ; ES = new segment
  957.   and    di,0000000000001111b             ; DI = offset within new segment
  958.  
  959.   lds    si,[buf]            ; load input address
  960.   mov    dx,si                ; DX = offset
  961.   shr    dx,4                ; DX = # of paragraphs (segments)
  962.   mov    ax,ds                ; AX = DS
  963.   add    ax,dx                ; AX = new DS
  964.   mov    ds,ax                ; DS = new DS
  965.   and    si,0000000000001111b        ; SI = offset within new segment
  966.  
  967.   cld
  968.   mov    cx,[lineLen]            ; CX = line length
  969.   mov    dx,cx                ; DX = line length
  970.   shr    cx,2                ; CX = line length in dwords
  971.   rep    movsd                     ; move the dwords if necessary
  972.   mov    cx,dx                ; CX = line length in bytes
  973.   and    cx,0000000000000011b        ; CX = any residual bytes
  974.   rep    movsb                ; move the bytes if necessary
  975.  
  976.   pop    di si ds            ; restore registers
  977.   leave                    ; clean up
  978.   retf                    ; return
  979. ENDP
  980.  
  981.  
  982. ;*****
  983. ;***** putLineInv
  984. ;*****
  985.  
  986. PROC    C    putLineInv_mem_copy
  987.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DWORD
  988.   push    ds si di            ; save these registers
  989.  
  990.   xor    eax,eax                ; clear EAX
  991.   xor    edx,edx                ; clear EDX
  992.   xor    edi,edi                ; clear EDI
  993.  
  994.   les    di,[outAddr]            ; load output address
  995.   mov    ax,[y]
  996.   mov    dx,[outScreenWide]
  997.   mul    edx                    ; EDX:EAX = offset - EDI - x
  998.   add    edi,eax                ; EDI = offset - x
  999.   mov    dx,[xOff]
  1000.   add    edi,edx                ; EDI = offset
  1001.   mov    edx,edi                ; EDX = offset
  1002.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1003.   add    dx,[outSeg]            ; DX = new segment
  1004.   mov    es,dx                ; ES = new segment
  1005.   and    di,0000000000001111b             ; DI = offset within new segment
  1006.  
  1007.   lds    si,[buf]            ; load input address
  1008.   mov    dx,si                ; DX = offset
  1009.   shr    dx,4                ; DX = # of paragraphs (segments)
  1010.   mov    ax,ds                ; AX = DS
  1011.   add    ax,dx                ; AX = new DS
  1012.   mov    ds,ax                ; DS = new DS
  1013.   and    si,0000000000001111b        ; SI = offset within new segment
  1014.  
  1015.   cld
  1016.   mov    cx,[lineLen]            ; CX = line length
  1017.  
  1018.     @@loopStart:
  1019.   lodsb                    ; grab a pixel
  1020.   or    al,al                ; is it a zero pixel?
  1021.   jz    @@invisible            ; yes, don't copy it
  1022.   stosb                    ; no, copy it ...
  1023.   loop    @@loopStart            ; ... and start loop again
  1024.   jmp    short    @@loopDone        ; quit loop when completed
  1025.     @@invisible:
  1026.   inc    di                ; skip past pixel ...
  1027.   loop    @@loopStart            ; ... and start loop again
  1028.  
  1029.     @@loopDone:
  1030.   pop    di si ds            ; restore registers
  1031.   leave                    ; clean up
  1032.   retf                    ; return
  1033. ENDP
  1034.  
  1035.  
  1036. ;*****
  1037. ;***** getLine
  1038. ;*****
  1039.  
  1040. PROC    C    getLine_scr
  1041.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DWORD
  1042.   cld
  1043.   push    ds si di
  1044.   les    di,[buf]
  1045.   lds    si,[inAddr]
  1046.  
  1047.   mov    bx,[lineNum]
  1048.   shl    bx,1
  1049.   add    si,[lineOffs+bx]
  1050.   add    si,[xOff]
  1051.   mov    cx,[lineLen]
  1052.  
  1053.   mov    dx,cx                ; DX = CX
  1054.   shr    cx,2                ; CX = line length in dwords
  1055.   rep    movsd                ; copy the dwords
  1056.   mov    cx,dx                ; CX = line length in bytes
  1057.   and    cx,0000000000000011b        ; CX = number of residual bytes
  1058.   rep    movsb                ; copy the residual bytes, if any
  1059.  
  1060.   pop    di si ds            ; restore registers
  1061.   leave                    ; clean up call stack
  1062.   retf                    ; return
  1063. ENDP
  1064.  
  1065. PROC    C    getLine_mem
  1066.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DWORD
  1067.   push    ds si di            ; save these registers
  1068.  
  1069.   xor    eax,eax                ; clear EAX
  1070.   xor    edx,edx                ; clear EDX
  1071.   xor    esi,esi                ; clear ESI
  1072.  
  1073.   les    si,[inAddr]            ; load input address
  1074.   mov    ax,[y]
  1075.   mov    dx,[inScreenWide]
  1076.   mul    edx                    ; EDX:EAX = offset - ESI - x
  1077.   add    esi,eax                ; ESI = offset - x
  1078.   mov    dx,[xOff]
  1079.   add    esi,edx                ; ESI = offset
  1080.   mov    edx,esi                ; EDX = offset
  1081.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1082.   add    dx,[inSeg]            ; DX = new segment
  1083.   mov    ds,dx                ; ES = new segment
  1084.   and    si,0000000000001111b             ; SI = offset within new segment
  1085.  
  1086.   les    di,[buf]            ; load output address
  1087.   mov    dx,di                ; DX = offset
  1088.   shr    dx,4                ; DX = # of paragraphs (segments)
  1089.   mov    ax,es                ; AX = ES
  1090.   add    ax,dx                ; AX = new ES
  1091.   mov    es,ax                ; ES = new ES
  1092.   and    di,0000000000001111b        ; DI = offset within new segment
  1093.  
  1094.   cld
  1095.   mov    cx,[lineLen]            ; CX = line length
  1096.   mov    dx,cx                ; DX = line length
  1097.   shr    cx,2                ; CX = line length in dwords
  1098.   rep    movsd                     ; move the dwords if necessary
  1099.   mov    cx,dx                ; CX = line length in bytes
  1100.   and    cx,0000000000000011b        ; CX = any residual bytes
  1101.   rep    movsb                ; move the bytes if necessary
  1102.  
  1103.   pop    di si ds            ; restore registers
  1104.   leave                    ; clean up
  1105.   retf                    ; return
  1106. ENDP
  1107.  
  1108.  
  1109. ;*****
  1110. ;***** putPixel
  1111. ;*****
  1112.  
  1113. ; Copy a pixel to the screen
  1114. PROC    C    putPixel_scr_copy
  1115.     ARG    x:WORD,y:WORD,colour:BYTE
  1116.   mov   ax,0A000h
  1117.   mov    es,ax
  1118.   mov    bx,[y]
  1119.   shl    bx,1
  1120.   mov    bx,[lineOffs+bx]
  1121.   add    bx,[x]
  1122.   mov    al,[colour]
  1123.   mov    [es:bx],al
  1124.   leave
  1125.   retf
  1126. ENDP
  1127.  
  1128. ; AND a pixel to the screen
  1129. PROC    C    putPixel_scr_and
  1130.     ARG    x:WORD,y:WORD,colour:BYTE
  1131.   mov   ax,0A000h
  1132.   mov    es,ax
  1133.   mov    bx,[y]
  1134.   shl    bx,1
  1135.   mov    bx,[lineOffs+bx]
  1136.   add    bx,[x]
  1137.   mov    al,[es:bx]
  1138.   and    al,[colour]
  1139.   mov    [es:bx],al
  1140.   leave
  1141.   retf
  1142. ENDP
  1143.  
  1144. ; NOT a pixel to the screen
  1145. PROC    C    putPixel_scr_not
  1146.     ARG    x:WORD,y:WORD,colour:BYTE
  1147.   mov   ax,0A000h
  1148.   mov    es,ax
  1149.   mov    bx,[y]
  1150.   shl    bx,1
  1151.   mov    bx,[lineOffs+bx]
  1152.   add    bx,[x]
  1153.   mov    al,[colour]
  1154.   not    al
  1155.   mov    [es:bx],al
  1156.   leave
  1157.   retf
  1158. ENDP
  1159.  
  1160. ; OR a pixel to the screen
  1161. PROC    C    putPixel_scr_or
  1162.     ARG    x:WORD,y:WORD,colour:BYTE
  1163.   mov   ax,0A000h
  1164.   mov    es,ax
  1165.   mov    bx,[y]
  1166.   shl    bx,1
  1167.   mov    bx,[lineOffs+bx]
  1168.   add    bx,[x]
  1169.   mov    al,[es:bx]
  1170.   or    al,[colour]
  1171.   mov    [es:bx],al
  1172.   leave
  1173.   retf
  1174. ENDP
  1175.  
  1176. ; XOR a pixel to the screen
  1177. PROC    C    putPixel_scr_xor
  1178.     ARG    x:WORD,y:WORD,colour:BYTE
  1179.   mov   ax,0A000h
  1180.   mov    es,ax
  1181.   mov    bx,[y]
  1182.   shl    bx,1
  1183.   mov    bx,[lineOffs+bx]
  1184.   add    bx,[x]
  1185.   mov    al,[es:bx]
  1186.   xor    al,[colour]
  1187.   mov    [es:bx],al
  1188.   leave
  1189.   retf
  1190. ENDP
  1191.  
  1192. ; Copy a pixel to memory
  1193. PROC    C    putPixel_mem_copy
  1194.     ARG    x:WORD,y:WORD,colour:BYTE
  1195.   xor    eax,eax                ; clear EAX
  1196.   xor    ebx,ebx                ; clear EBX
  1197.   xor    edx,edx                ; clear EDX
  1198.  
  1199.   les    bx,[outAddr]            ; load output address
  1200.   mov    ax,[y]
  1201.   mov    dx,[outScreenWide]
  1202.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1203.   add    ebx,eax                ; EBX = offset - x
  1204.   mov    dx,[x]
  1205.   add    ebx,edx                ; EBX = offset
  1206.  
  1207.   mov    edx,ebx                ; EDX = offset
  1208.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1209.   add    dx,[outSeg]            ; DX = new segment
  1210.   mov    es,dx                ; ES = new segment
  1211.   and    bx,0000000000001111b             ; BX = offset within new segment
  1212.  
  1213.   mov    al,[colour]            ; colour in AL
  1214.   mov    [es:bx],al            ; store pixel
  1215.   leave                    ; clean up
  1216.   retf                    ; return
  1217. ENDP
  1218.  
  1219. ; AND a pixel to memory
  1220. PROC    C    putPixel_mem_and
  1221.     ARG    x:WORD,y:WORD,colour:BYTE
  1222.   xor    eax,eax                ; clear EAX
  1223.   xor    ebx,ebx                ; clear EBX
  1224.   xor    edx,edx                ; clear EDX
  1225.  
  1226.   les    bx,[outAddr]            ; load output address
  1227.   mov    ax,[y]
  1228.   mov    dx,[outScreenWide]
  1229.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1230.   add    ebx,eax                ; EBX = offset - x
  1231.   mov    dx,[x]
  1232.   add    ebx,edx                ; EBX = offset
  1233.  
  1234.   mov    edx,ebx                ; EDX = offset
  1235.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1236.   add    dx,[outSeg]            ; DX = new segment
  1237.   mov    es,dx                ; ES = new segment
  1238.   and    bx,0000000000001111b             ; BX = offset within new segment
  1239.  
  1240.   mov    al,[colour]            ; colour in AL
  1241.   and    [es:bx],al            ; AND pixel
  1242.   leave                    ; clean up
  1243.   retf                    ; return
  1244. ENDP
  1245.  
  1246. ; NOT a pixel to memory
  1247. PROC    C    putPixel_mem_not
  1248.     ARG    x:WORD,y:WORD,colour:BYTE
  1249.   xor    eax,eax                ; clear EAX
  1250.   xor    ebx,ebx                ; clear EBX
  1251.   xor    edx,edx                ; clear EDX
  1252.  
  1253.   les    bx,[outAddr]            ; load output address
  1254.   mov    ax,[y]
  1255.   mov    dx,[outScreenWide]
  1256.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1257.   add    ebx,eax                ; EBX = offset - x
  1258.   mov    dx,[x]
  1259.   add    ebx,edx                ; EBX = offset
  1260.  
  1261.   mov    edx,ebx                ; EDX = offset
  1262.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1263.   add    dx,[outSeg]            ; DX = new segment
  1264.   mov    es,dx                ; ES = new segment
  1265.   and    bx,0000000000001111b             ; BX = offset within new segment
  1266.  
  1267.   mov    al,[colour]            ; colour in AL
  1268.   not    al                ; NOT it
  1269.   mov    [es:bx],al            ; store NOTed pixel
  1270.   leave                    ; clean up
  1271.   retf                    ; return
  1272. ENDP
  1273.  
  1274. ; OR a pixel to memory
  1275. PROC    C    putPixel_mem_or
  1276.     ARG    x:WORD,y:WORD,colour:BYTE
  1277.   xor    eax,eax                ; clear EAX
  1278.   xor    ebx,ebx                ; clear EBX
  1279.   xor    edx,edx                ; clear EDX
  1280.  
  1281.   les    bx,[outAddr]            ; load output address
  1282.   mov    ax,[y]
  1283.   mov    dx,[outScreenWide]
  1284.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1285.   add    ebx,eax                ; EBX = offset - x
  1286.   mov    dx,[x]
  1287.   add    ebx,edx                ; EBX = offset
  1288.  
  1289.   mov    edx,ebx                ; EDX = offset
  1290.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1291.   add    dx,[outSeg]            ; DX = new segment
  1292.   mov    es,dx                ; ES = new segment
  1293.   and    bx,0000000000001111b             ; BX = offset within new segment
  1294.  
  1295.   mov    al,[colour]            ; colour in AL
  1296.   or    [es:bx],al            ; OR pixel
  1297.   leave                    ; clean up
  1298.   retf                    ; return
  1299. ENDP
  1300.  
  1301. ; XOR a pixel to memory
  1302. PROC    C    putPixel_mem_xor
  1303.     ARG    x:WORD,y:WORD,colour:BYTE
  1304.   xor    eax,eax                ; clear EAX
  1305.   xor    ebx,ebx                ; clear EBX
  1306.   xor    edx,edx                ; clear EDX
  1307.  
  1308.   les    bx,[outAddr]            ; load output address
  1309.   mov    ax,[y]
  1310.   mov    dx,[outScreenWide]
  1311.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1312.   add    ebx,eax                ; EBX = offset - x
  1313.   mov    dx,[x]
  1314.   add    ebx,edx                ; EBX = offset
  1315.  
  1316.   mov    edx,ebx                ; EDX = offset
  1317.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1318.   add    dx,[outSeg]            ; DX = new segment
  1319.   mov    es,dx                ; ES = new segment
  1320.   and    bx,0000000000001111b             ; BX = offset within new segment
  1321.  
  1322.   mov    al,[colour]            ; colour in AL
  1323.   xor    [es:bx],al            ; XOR pixel
  1324.   leave                    ; clean up
  1325.   retf                    ; return
  1326. ENDP
  1327.  
  1328.  
  1329. ;*****
  1330. ;***** getPixel
  1331. ;*****
  1332.  
  1333. ; Get a pixel from the screen
  1334. PROC    C    getPixel_scr
  1335.     ARG    x:WORD,y:WORD
  1336.   mov    ax,0A000h
  1337.   mov    es,ax
  1338.   mov    bx,[y]
  1339.   shl    bx,1
  1340.   mov    bx,[lineOffs+bx]
  1341.   add    bx,[x]
  1342.   mov    al,[es:bx]
  1343.   xor    ah,ah
  1344.   leave
  1345.   retf
  1346. ENDP
  1347.  
  1348. ; Get a pixel from memory
  1349. PROC    C    getPixel_mem
  1350.     ARG    x:WORD,y:WORD
  1351.   xor    eax,eax                ; clear EAX
  1352.   xor    ebx,ebx                ; clear EBX
  1353.   xor    edx,edx                ; clear EDX
  1354.  
  1355.   les    bx,[inAddr]            ; load input address
  1356.   mov    ax,[y]
  1357.   mov    dx,[inScreenWide]
  1358.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1359.   add    ebx,eax                ; EBX = offset - x
  1360.   mov    dx,[x]
  1361.   add    ebx,edx                ; EBX = offset
  1362.  
  1363.   mov    edx,ebx                ; EDX = offset
  1364.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1365.   add    dx,[inSeg]            ; DX = new segment
  1366.   mov    es,dx                ; ES = new segment
  1367.   and    bx,0000000000001111b             ; BX = offset within new segment
  1368.  
  1369.   xor    ax,ax                ; clear AX
  1370.   mov    al,[es:bx]            ; store pixel in AX for return
  1371.   leave                    ; clean up
  1372.   retf                    ; return
  1373. ENDP
  1374.  
  1375.  
  1376. ;*****
  1377. ;***** line
  1378. ;*****
  1379.  
  1380. ; The following line routine is a modified version of code in Richard
  1381. ; Wilton's book "Programmer's Guide to PC and PS/2 Video Systems".
  1382. SCREENSEG    EQU    0A000h
  1383.  
  1384. MACRO    PIXELADDR
  1385.   xchg    ah,al            ; ax=256*y
  1386.   add    bx,ax            ; bx=256*y+x
  1387.   shr    ax,2
  1388.   add    bx,ax            ; bx=320*y+x (+ offset in buffer if needed.)
  1389.   mov    ax,SCREENSEG
  1390.   mov    es,ax            ; es:bx=address of pixel
  1391. ENDM
  1392.  
  1393.     MASM
  1394.  
  1395. ; void line(x1,y1,x2,y2,colour)
  1396. ; int x1,y1,x2,y2;
  1397. ; unsigned char colour;
  1398. ARGx1        EQU    word ptr [bp+6]
  1399. ARGy1        EQU    word ptr [bp+8]
  1400. ARGx2        EQU    word ptr [bp+10]
  1401. ARGy2        EQU    word ptr [bp+12]
  1402. ARGcolour    EQU    byte ptr [bp+14]
  1403. VARincr1    EQU    word ptr [bp-2]
  1404. VARincr2    EQU    word ptr [bp-4]
  1405. VARroutine    EQU    word ptr [bp-6]
  1406. line    PROC    FAR
  1407.     push    bp
  1408.         mov    bp,sp
  1409.         sub    sp,6
  1410.         push    si
  1411.         push    di
  1412.  
  1413. ; check for vertical lines
  1414.     mov    si,320                ; initial y-increment
  1415.         mov    cx,ARGx2
  1416.     sub    cx,ARGx1            ; cx=x2-x1
  1417.     jz    vertLine
  1418.  
  1419. ; force x1 < x2
  1420.     jns    L01                ; jump if x1<x2
  1421.         neg    cx                ; cx=x1-x2
  1422.     mov    bx,ARGx2            ; exchange x1 and x2
  1423.         xchg    bx,ARGx1
  1424.     mov    ARGx2,bx
  1425.         mov    bx,ARGy2            ; exchange y1 and y2
  1426.         xchg    bx,ARGy1
  1427.         mov    ARGy2,bx
  1428.  
  1429. ; calculate dy=abs(y2-y1)
  1430. L01:    mov    bx,ARGy2
  1431.         sub    bx,ARGy1            ; bx=y2-y1
  1432.     jz    @@horizLine
  1433.     jns    L03                ; jump if slope is positive
  1434.     neg    bx                ; bx=y1-y2
  1435.         neg    si                ; negate y-increment
  1436.  
  1437. ; select appropriate routine for slope of line
  1438. L03:    push    si
  1439.     mov    VARroutine,offset loSlopeLine
  1440.         cmp    bx,cx
  1441.         jle    L04                ; jump if dy<=dx (slope <=1)
  1442.     mov     VARroutine,offset hiSlopeLine
  1443.         xchg    bx,cx                ; exchange dy and dx
  1444.  
  1445. ; calculate initial decision variable and increments
  1446. L04:    shl    bx,1                ; bx=2*dy
  1447.     mov    VARincr1,bx            ; incr1=2*dy
  1448.         sub    bx,cx
  1449.         mov    si,bx                ; si=d=2*dy-dx
  1450.         sub    bx,cx
  1451.         mov    VARincr2,bx            ; incr2=2*(dy-dx)
  1452.  
  1453. ; calculate first pixel address
  1454.     push    cx
  1455.         mov    ax,ARGy1
  1456.     mov    bx,ARGx1
  1457.     PIXELADDR
  1458.         mov    di,bx
  1459.     pop    cx
  1460.         inc    cx                ; cx=# of pixels to draw
  1461.         pop    bx                ; bx=y-increment
  1462.     jmp    VARroutine            ; jump to appropriate routine
  1463.  
  1464. ; routine for vertical lines
  1465. vertLine:    mov    ax,ARGy1
  1466.         mov    bx,ARGy2
  1467.                 mov    cx,bx
  1468.                 sub    cx,ax            ; cx=dy
  1469.                 jge    L31            ; jump if dy>=0
  1470.                 neg    cx            ; force dy>=0
  1471.                 mov    ax,bx            ; ax=y2
  1472. L31:    inc    cx                ; cx=# of pixels to draw
  1473.     mov    bx,ARGx1            ; bx=x
  1474.     PIXELADDR                ; es:bx
  1475.         mov    di,bx                ; es:di
  1476.     dec    si                ; si=bytes/line-1
  1477.     mov    al,ARGcolour
  1478.  
  1479. L32:    stosb
  1480.     add    di,si                ; next line
  1481.         loop    L32
  1482.     jmp    short    Lexit
  1483.  
  1484. ; routine for horizontal lines (slope=0)
  1485. @@horizLine:    push    cx
  1486.         mov    ax,ARGy1
  1487.                 mov    bx,ARGx1
  1488.                 PIXELADDR            ; es:bx
  1489.                 mov    di,bx            ; es:di
  1490.                 pop    cx
  1491.                 inc    cx            ; cx=# of pixels to draw
  1492.                 mov    al,ARGcolour
  1493.         rep    stosb
  1494.         jmp    short    Lexit
  1495.  
  1496. ; routine for dy<=dx (slope<=1)            ; es:di -> video buffer
  1497.                         ; bx=y-increment
  1498.                                                 ; cx =# of pixels to draw
  1499.                         ; si=decision variable
  1500. loSlopeLine:    mov    al,ARGcolour
  1501.  
  1502. L11:    stosb                    ; put pixel, increment x
  1503.     or    si,si                ; test sign of d
  1504.     jns    L12                ; jump id d>=0
  1505.         add    si,VARincr1            ; d=d+incr1
  1506.         loop    L11
  1507.         jmp    short    Lexit
  1508.  
  1509. L12:    add    si,VARincr2            ; d=d+incr2
  1510.     add    di,bx                ; increment y
  1511.         loop    L11
  1512.         jmp    short    Lexit
  1513.  
  1514. ; routine for dy>dx (slope >1)            ; es:di -> video buffer
  1515.                         ; bx=y-increment
  1516.                         ; cx=# of pixels to draw
  1517.                         ; si=decision variable
  1518. hiSlopeLine:    mov    al,ARGcolour
  1519.  
  1520. L21:    stosb                    ; put pixel, increment x
  1521.     add    di,bx                ; increment y
  1522.  
  1523. L22:    or    si,si                ; test sign of d
  1524.     jns    L23                ; jump if d>=0
  1525.     add    si,VARincr1            ; d=d+incr1
  1526.     dec    di                ; dec x (inc by stosb)
  1527.     loop    L21
  1528.     jmp    short    Lexit
  1529.  
  1530. L23:    add    si,VARincr2            ; d=d+incr2
  1531.     loop    L21
  1532.  
  1533. Lexit:    pop    di
  1534.     pop    si
  1535.     mov    sp,bp
  1536.     pop    bp
  1537.     ret
  1538. line    ENDP
  1539.  
  1540.     IDEAL
  1541.  
  1542.  
  1543. ;*****
  1544. ;***** horizLine
  1545. ;*****
  1546.  
  1547. PROC    C    horizLine_scr_copy
  1548.     ARG    y:WORD, x1:WORD, x2:WORD, colour:BYTE
  1549.   push    di
  1550.  
  1551.   les    di,[outAddr]            ; load output address
  1552.   mov    bx,[y]                ; BX = y-coordinate
  1553.   mov    ax,[x1]                ; CX = # of pixels
  1554.   mov    cx,[x2]
  1555.   sub    cx,ax
  1556.   inc    cx
  1557.  
  1558.   shl    bx,1                ; DI = output address
  1559.   add    di,[lineOffs+bx]
  1560.   add    di,ax
  1561.  
  1562.   mov    al,[colour]            ; AL = colour
  1563.   mov    ah,al                ; AH = colour
  1564.   mov    dx,ax                ; DX = colour:colour
  1565.   shl    eax,16                ; EAX = colour:colour:?:?
  1566.   mov    ax,dx                ; EAX = colour:colour:colour:colour
  1567.   mov    dx,cx                ; DX = CX
  1568.   shr    cx,2                ; CX = line length in dwords
  1569.   rep    stosd                ; store the dwords
  1570.   mov    cx,dx                ; CX = line length in bytes
  1571.   and    cx,0000000000000011b        ; CX = number of residual bytes
  1572.   rep    stosb                ; store the residual bytes, if any
  1573.  
  1574.   pop    di                ; restore DI
  1575.   leave                    ; clean up the stack
  1576.   retf                    ; return
  1577. ENDP
  1578.  
  1579. PROC    C    horizLine_mem_copy
  1580.     ARG    y:WORD, x1:WORD, x2:WORD, colour:BYTE
  1581.   push    edi                ; store EDI
  1582.  
  1583.   xor    eax,eax                ; clear EAX
  1584.   xor    edi,edi                ; clear EDI
  1585.   xor    edx,edx                ; clear EDX
  1586.  
  1587.   les    di,[outAddr]            ; load output address
  1588.   mov    ax,[y]
  1589.   mov    dx,[outScreenWide]
  1590.   mul    edx                    ; EDX:EAX = offset - EDI - x
  1591.   add    edi,eax                ; EDI = offset - x
  1592.   mov    dx,[x1]
  1593.   add    edi,edx                ; EDI = offset
  1594.   mov    edx,edi                ; EDX = offset
  1595.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1596.   add    dx,[outSeg]            ; DX = new segment
  1597.   mov    es,dx                ; ES = new segment
  1598.   and    di,0000000000001111b             ; DI = offset within new segment
  1599.  
  1600.   mov    al,[colour]            ; colour in AL
  1601.   mov    ah,al                ; colour in AH
  1602.   mov    bx,ax
  1603.   shl    eax,16
  1604.   mov    ax,bx                 ; colour in each byte of EAX
  1605.  
  1606.   mov    cx,[x2]
  1607.   sub    cx,[x1]
  1608.   inc    cx                ; CX = line length in pixels
  1609.   mov    dx,cx                ; DX = line length in bytes
  1610.  
  1611.   shr    cx,2                ; CX = line length in dwords
  1612.   rep    stosd                ; store four bytes at a time
  1613.   mov    cx,dx                ; CX = line length in pixels
  1614.   and    cx,0000000000000011b        ; CX = any remaining bytes
  1615.   rep    stosb                ; store the remaining bytes
  1616.  
  1617.   pop    edi                    ; restore EDI
  1618.   leave                    ; clean up
  1619.   retf                    ; return
  1620. ENDP
  1621.  
  1622.  
  1623. ;*****
  1624. ;***** filledRect
  1625. ;*****
  1626.  
  1627. PROC    C    filledRect
  1628.     ARG    x1:WORD, y1:WORD, x2:WORD, y2:WORD, colour:BYTE
  1629.   push    di si
  1630.   les    di,[outAddr]
  1631.  
  1632.   mov    ax,[y1]        ; y coords
  1633.   mov    bx,[y2]
  1634.   cmp    ax,bx
  1635.   jbe    @@L1
  1636.   xchg    ax,bx
  1637.  
  1638.     @@L1:
  1639.   sub    bx,ax                ; ySize in BX
  1640.   inc    bx
  1641.   mov    si,320                ; update DI
  1642.   mul    si
  1643.   add    di,ax
  1644.  
  1645.   mov    dx,[x1]        ; x coords
  1646.   mov    cx,[x2]
  1647.   cmp    dx,cx
  1648.   jbe    @@L2
  1649.   xchg    cx,dx
  1650.  
  1651.     @@L2:
  1652.   add    di,dx
  1653.  
  1654.   sub    cx,dx                ; xSize in CX
  1655.   inc    cx
  1656.  
  1657.   sub    si,cx                ; xAdd in SI
  1658.  
  1659.   push    dx                ; store DX
  1660.   mov    al,[colour]            ; AL = colour
  1661.   mov    ah,al                ; AH = colour
  1662.   mov    dx,ax                ; DX = colour:colour
  1663.   shl    eax,16                ; EAX = colour:colour:?:?
  1664.   mov    ax,dx                ; EAX = colour:colour:colour:colour
  1665.   pop    dx                ; restore DX
  1666.  
  1667.   cld                    ; clear direction flag
  1668.   mov    dx,cx                ; BX = CX
  1669.   jmp    short    @@LoopB            ; jump to loop entry point
  1670.     @@LoopA:
  1671.   mov    cx,dx                ; CX = line length in bytes
  1672.   add    di,si                ; update DI
  1673.     @@LoopB:
  1674.   push    cx                ; store CX
  1675.   shr    cx,2                ; CX = line length in dwords
  1676.   rep    stosd                ; store the dwords
  1677.   pop    cx                ; restore CX
  1678.   and    cx,0000000000000011b        ; CX = number of residual bytes
  1679.   rep    stosb                ; store the residual bytes, if any
  1680.   dec    bx                ; decrement loop counter
  1681.   jnz    @@LoopA                ; restart loop if necesary
  1682.  
  1683.   pop    si di                ; restore registers
  1684.   leave                           ; clean up call stack
  1685.   retf                    ; return
  1686. ENDP
  1687.  
  1688.  
  1689. ;*****
  1690. ;***** setPaletteReg
  1691. ;*****
  1692.  
  1693. PROC    C    setPaletteReg
  1694.     ARG    palNum:WORD,red:BYTE,green:BYTE,blue:BYTE
  1695.   mov    bx,[palNum]
  1696.  
  1697.   mov    dh,[red]            ; red
  1698.   shr    dh,2
  1699.   jnc    @@L1
  1700.   cmp    dh,63
  1701.   je    @@L1
  1702.   inc    dh
  1703.  
  1704.     @@L1:
  1705.   mov    ch,[green]            ; green
  1706.   shr    ch,2
  1707.   jnc    @@L2
  1708.   cmp    ch,63
  1709.   je    @@L2
  1710.   inc    ch
  1711.  
  1712.     @@L2:
  1713.   mov    cl,[blue]            ; blue
  1714.   shr    cl,2
  1715.   jnc    @@L3
  1716.   cmp    cl,63
  1717.   je    @@L3
  1718.   inc    cl
  1719.  
  1720.     @@L3:
  1721.   mov    ax,1010h
  1722.   int    10h
  1723.   leave
  1724.   retf
  1725. ENDP
  1726.  
  1727.  
  1728. ;*****
  1729. ;***** getPaletteReg
  1730. ;*****
  1731.  
  1732. PROC    C    getPaletteReg
  1733.     ARG    palNum:WORD,red:DWORD,green:DWORD,blue:DWORD
  1734.   push    ds si
  1735.   mov    ax,1015h
  1736.   mov    bx,[palNum]
  1737.   int    10h
  1738.   lds    si,[red]
  1739.   shl    dh,2
  1740.   mov    [ds:si],dh
  1741.   lds    si,[green]
  1742.   shl    ch,2
  1743.   mov    [ds:si],ch
  1744.   lds    si,[blue]
  1745.   shl    cl,2
  1746.   mov    [ds:si],cl
  1747.   pop    si ds
  1748.   leave
  1749.   retf
  1750. ENDP
  1751.  
  1752.  
  1753. ;*****
  1754. ;***** setBlockPalette
  1755. ;*****
  1756.  
  1757. PROC    C    setBlockPalette
  1758.     ARG    firstReg:WORD,lastReg:WORD,paletteData:DWORD
  1759.   push    ds si di
  1760.   lds    si,[paletteData]
  1761.   push    cs
  1762.   pop    es
  1763.   mov    di,OFFSET tempPalette
  1764.   mov    cx,[lastReg]
  1765.   inc    cx
  1766.   push    cx
  1767.   cld
  1768.  
  1769.     @@LLoop:
  1770.   lodsb            ; red
  1771.   shr    al,2
  1772.   jnc    @@L1
  1773.   cmp    al,63
  1774.   je    @@L1
  1775.   inc    al
  1776.     @@L1:
  1777.   stosb
  1778.   lodsb            ; green
  1779.   shr    al,2
  1780.   jnc    @@L2
  1781.   cmp    al,63
  1782.   je    @@L2
  1783.   inc    al
  1784.     @@L2:
  1785.   stosb
  1786.   lodsb            ; blue
  1787.   shr    al,2
  1788.   jnc    @@L3
  1789.   cmp    al,63
  1790.   je    @@L3
  1791.   inc    al
  1792.     @@L3:
  1793.   stosb
  1794.   loop    @@LLoop
  1795.  
  1796.   mov    ax,1012h
  1797.   mov    bx,[firstReg]            ; first colour reg
  1798.   pop    cx                ; # of colour regs
  1799.   mov    dx,OFFSET tempPalette        ; ES = CS
  1800.   int    10h
  1801.  
  1802.     @@LExit:
  1803.   pop    di si ds
  1804.   leave
  1805.   retf
  1806. ENDP
  1807.  
  1808.  
  1809. ;*****
  1810. ;***** getBlockPalette
  1811. ;*****
  1812.  
  1813. PROC    C    getBlockPalette
  1814.     ARG    firstReg:WORD,lastReg:WORD,paletteData:DWORD
  1815.   push    ds si di
  1816.   mov    ax,1017h
  1817.   mov    bx,[firstReg]
  1818.   mov    cx,[lastReg]
  1819.   inc    cx
  1820.   push    cs
  1821.   pop    es
  1822.   mov    dx,OFFSET tempPalette
  1823.   int    10h
  1824.  
  1825.   les    di,[paletteData]
  1826.   mov    ax,cs
  1827.   mov    ds,ax
  1828.   mov    si,OFFSET tempPalette
  1829.   mov    cx,[lastReg]
  1830.   inc    cx
  1831.   cld
  1832.  
  1833.     @@L1:
  1834.   lodsb
  1835.   shl    al,2
  1836.   stosb        ; red
  1837.   lodsb
  1838.   shl    al,2
  1839.   stosb        ; green
  1840.   lodsb
  1841.   shl    al,2
  1842.   stosb        ; blue
  1843.   loop    @@L1
  1844.  
  1845.     @@LExit:
  1846.   pop    di si ds
  1847.   leave
  1848.   retf
  1849. ENDP
  1850.  
  1851.  
  1852. ;*****
  1853. ;***** clearGraphics
  1854. ;*****
  1855.  
  1856. PROC    C    clearGraphics
  1857.     ARG    colour:BYTE
  1858.   push    di
  1859.   mov    ax,0A000h            ; point ES:DI to screen
  1860.   mov    es,ax
  1861.   xor    di,di
  1862.   mov    al,[colour]            ; EAX = colour:colour:colour:colour
  1863.   mov    ah,al
  1864.   mov    bx,ax
  1865.   shl    eax,16
  1866.   mov    ax,bx
  1867.   mov    cx,16000            ; clear the screen
  1868.   cld
  1869.   rep    stosd
  1870.   pop    di
  1871.   leave
  1872.   retf
  1873. ENDP
  1874.  
  1875. ENDS
  1876. END
  1877.