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

  1. ; 320x240x256 (requires register-compatible VGA+)
  2. ; Loadable driver for The Graphics Engine
  3. ; Copyright (c) 1993 by Matthew Hildebrand
  4. ; Turbo Assembler syntax
  5.  
  6. IDEAL
  7. MODEL LARGE TGE320X240_TEXT
  8. P386N
  9.  
  10.  
  11. SCREEN_WIDE    =    320
  12. SCREEN_DEEP    =    240
  13. NUM_COLOURS    =    256
  14.  
  15.  
  16.         CODESEG TGE320X240_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    0            ; 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    0            ; 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    0            ; 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    0            ; 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    0            ; 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_scr_copy    ; 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    239
  406. maxColour        dw    255    ; maximum colour number
  407. xRatio                   dw    4    ; aspect ratio 4:3 (320:240 in
  408. yRatio            dw    3    ;   lowest terms)
  409. bitsPerPixel        dw    8    ; 8 bits per pixel
  410. inMaxX            dw    319    ; current input screen dimensions
  411. inMaxY            dw    239
  412. outMaxX            dw    319    ; current output screen dimensions
  413. outMaxY            dw    239
  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    239
  421. outViewportULX        dw    0
  422. outViewportULY        dw    0
  423. outViewportLRX        dw    319
  424. outViewportLRY        dw    239
  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
  446. colourPalette    db    768    DUP(?)
  447. lineOffs    dw    240    DUP(?)
  448.  
  449. ; Plane masks for horizLine
  450. leftEdgeMask    db    1111b, 1110b, 1100b, 1000b
  451. rightEdgeMask    db    0001b, 0011b, 0111b, 1111b
  452.  
  453.  
  454. SC_INDEX    EQU    3C4h    ; Sequence Controller Index
  455. GC_INDEX    EQU    3CEh    ; Graphics Controller Index register
  456. CRTC_INDEX    EQU    3D4h    ; CRT Controller Index
  457. MISC_OUTPUT    EQU    3C2h    ; Miscellaneous Output register
  458. MAP_MASK    EQU     02h     ; index in SC of Map Mask register
  459. READ_MAP    EQU    4    ; Read Map register index in GC
  460. MEMORY_MODE    EQU    4    ; Memory mode register in SC
  461. GRAPHICS_MODE    EQU    5    ; Graphics Mode register index in GC
  462. MISCELLANEOUS    EQU    6    ; Miscellaneous register index in GC
  463. MAX_SCAN_LINE    EQU    9          ; Maximum Scan Line reg index in CRTC
  464. START_ADDR_HIGH    EQU    0Ch    ; Start Address High reg index in CRTC
  465. UNDERLINE    EQU    14h    ; Underline Location reg index in CRTC
  466. MODE_CONTROL    EQU    17h    ; Mode Control register index in CRTC
  467. INPUT_STATUS_1  EQU     03DAh   ; Input Status 1 register
  468. START_ADDR_HIGH EQU    0Ch     ; start address high byte
  469. START_ADDR_LOW  EQU    0Dh     ; start address low byte
  470. WORD_OUTS_OK    EQU    1    ; Set to 0 for VGAs that can't handle
  471.                 ; word OUTs to indexed VGA registers
  472.  
  473.  
  474. MACRO    OUT_WORD
  475. if WORD_OUTS_OK
  476.   out    dx,ax
  477. else
  478.   out    dx,al
  479.   inc    dx
  480.   xchg    ah,al
  481.   out    dx,al
  482.   dec    dx
  483.   xchg    ah,al
  484. endif
  485. ENDM
  486.  
  487.  
  488. ;*****
  489. ;***** initGraphics
  490. ;*****
  491.  
  492. PROC    C    initGraphics
  493.   push    si di
  494.  
  495.   mov   ax,0013h            ; set mode 13h
  496.   int   10h
  497.  
  498.   mov   dx,SC_INDEX
  499.   mov   ax,0604h
  500.   out   dx,ax               ; disable chain4 mode
  501.   mov   ax,0100h
  502.   out   dx,ax               ; synchronous reset while setting
  503.                       ; Misc Output for safety, even
  504.                     ; though clock unchanged
  505.  
  506.   mov   dx,MISC_OUTPUT
  507.   mov   al,0E3h
  508.   out   dx,al                ; select 25 MHz dot clock & 60 Hz
  509.                       ; scanning rate
  510.  
  511.   mov   dx,SC_INDEX
  512.   mov   ax,0300h
  513.   out   dx,ax                ; undo reset (restart sequencer)
  514.  
  515.   mov   dx,CRTC_INDEX             ; reprogram the CRT Controller
  516.   mov   al,11h              ; VSync End reg contains register
  517.   out   dx,al               ; write protect bit
  518.   inc   dx                  ; CRT Controller Data register
  519.   in    al,dx               ; get current VSync End register setting
  520.   and   al,7Fh              ; remove write protect on various
  521.   out   dx,al               ; CRTC registers
  522.   dec   dx                  ; CRT Controller Index
  523.  
  524.   mov    ax,00D06h            ; set CRT parameters
  525.   out    dx,ax
  526.   mov    ax,03E07h
  527.   out    dx,ax
  528.   mov    ax,04109h
  529.   out    dx,ax
  530.   mov    ax,0EA10h
  531.   out    dx,ax
  532.   mov    ax,0AC11h
  533.   out    dx,ax
  534.   mov    ax,0DF12h
  535.   out    dx,ax
  536.   mov    ax,00014h
  537.   out    dx,ax
  538.   mov    ax,0E715h
  539.   out    dx,ax
  540.   mov    ax,00616h
  541.   out    dx,ax
  542.   mov    ax,0E317h
  543.   out    dx,ax
  544.  
  545.   mov   dx,SC_INDEX
  546.   mov   ax,0F02h
  547.   out   dx,ax               ; enable writes to all four planes
  548.   mov   ax,0A000h              ; now clear all display memory, 8
  549.   mov   es,ax                     ; pixels at a time
  550.   xor   di,di               ; point ES:DI to display memory
  551.   xor   ax,ax               ; clear to zero-value pixels
  552.   mov   cx,8000h             ; # of words in display memory
  553.   rep   stosw               ; clear all of display memory
  554.  
  555.   cmp    [inited],0            ; restore palette if necessary
  556.   je    @@notInited
  557.   pop    di si
  558.   mov    ax,1
  559.   retf
  560.  
  561.     @@notInited:
  562.   mov    [inited],1
  563.   mov    si,OFFSET lineOffs
  564.   mov    cx,SCREEN_DEEP
  565.   xor    bx,bx
  566.  
  567.     @@LLoop:
  568.   mov    ax,SCREEN_WIDE/4
  569.   mul    bx
  570.   mov    [cs:si],ax
  571.   add    si,2
  572.   inc    bx
  573.   loop    @@LLoop
  574.  
  575.   pop   di si
  576.   mov    ax,1
  577.   retf
  578. ENDP
  579.  
  580.  
  581. ;*****
  582. ;***** putLine
  583. ;*****
  584.  
  585. PROC    C    putLine_scr_copy
  586.     ARG    lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DWORD
  587.         LOCAL    x2:WORD
  588.   push    ds si di
  589.  
  590.   mov    bx,[lineNum]            ; start address in ES:DI
  591.   shl    bx,1
  592.   mov    di,[lineOffs+bx]
  593.   mov    dx,[xOff]
  594.   shr    dx,2
  595.   add    di,dx
  596.   mov    ax,0A000h
  597.   mov    es,ax
  598.   lds    si,[buf]            ; source in DS:SI
  599.   cld
  600.  
  601.   mov    bx,[xOff]
  602.   add    bx,[lineLen]            ; calculate x2
  603.   dec    bx
  604.   mov    [x2],bx
  605.  
  606.   mov    cx,[lineLen]            ; line is short
  607.   cmp    cx,4
  608. JUMPS
  609.   jle    @@ShortLine
  610. NOJUMPS
  611.  
  612.   mov    cx,[xOff]            ; calculate starting plane
  613.   mov    bx,cx
  614.   mov    ax,0102h
  615.   and    cl,3
  616.   shl    ah,cl
  617.   mov    dx,SC_INDEX
  618.   OUT_WORD
  619.   push    si
  620.   mov    bx,[x2]
  621.   mov    cx,[xOff]
  622.       @@Loop1:
  623.   cmp    cx,bx
  624.   jg    @@Loop1Done
  625.   lodsb
  626.   stosb
  627.   add    cx,4
  628.   add    si,3
  629.   jmp    short    @@Loop1
  630.  
  631.     @@Loop1Done:
  632.   pop    si
  633.   inc    si
  634.   push    si
  635.   mov    bx,[xOff]
  636.   inc    bx
  637.   mov    cx,bx
  638.   mov    ax,0102h
  639.   and    cl,3
  640.   shl    ah,cl
  641.   mov    dx,SC_INDEX
  642.   OUT_WORD
  643.   mov    cx,bx
  644.   mov    bx,[lineNum]            ; start address in ES:DI
  645.   shl    bx,1
  646.   mov    di,[lineOffs+bx]
  647.   shr    cx,2
  648.   add    di,cx
  649.   mov    bx,[x2]
  650.   mov    cx,[xOff]
  651.   inc    cx
  652.       @@Loop2:
  653.   cmp    cx,bx
  654.   jg    @@Loop2Done
  655.   lodsb
  656.   stosb
  657.   add    cx,4
  658.   add    si,3
  659.   jmp    short    @@Loop2
  660.  
  661.       @@Loop2Done:
  662.   pop    si
  663.   inc    si
  664.   push    si
  665.   mov    bx,[xOff]
  666.   add    bx,2
  667.   mov    cx,bx
  668.   mov    ax,0102h
  669.   and    cl,3
  670.   shl    ah,cl
  671.   mov    dx,SC_INDEX
  672.   OUT_WORD
  673.   mov    cx,bx
  674.   mov    bx,[lineNum]
  675.   shl    bx,1
  676.   mov    di,[lineOffs+bx]
  677.   shr    cx,2
  678.   add    di,cx
  679.   mov    bx,[x2]
  680.   mov    cx,[xOff]
  681.   add    cx,2
  682.       @@Loop3:
  683.   cmp    cx,bx
  684.   jg    @@Loop3Done
  685.   lodsb
  686.   stosb
  687.   add    cx,4
  688.   add    si,3
  689.   jmp    short    @@Loop3
  690.  
  691.     @@Loop3Done:
  692.   pop    si
  693.   inc    si
  694.   mov    bx,[xOff]
  695.   add    bx,3
  696.   mov    cx,bx
  697.   mov    ax,0102h
  698.   and    cl,3
  699.   shl    ah,cl
  700.   mov    dx,SC_INDEX
  701.   OUT_WORD
  702.   mov    cx,bx
  703.   mov    bx,[lineNum]
  704.   shl    bx,1
  705.   mov    di,[lineOffs+bx]
  706.   shr    cx,2
  707.   add    di,cx
  708.   mov    bx,[x2]
  709.   mov    cx,[xOff]
  710.   add    cx,3
  711.     @@Loop4:
  712.   cmp    cx,bx
  713.   jg    @@Exit
  714.   lodsb
  715.   stosb
  716.   add    cx,4
  717.   add    si,3
  718.   jmp    short    @@Loop4
  719.  
  720.       @@ShortLine:
  721.   mov    cx,[xOff]
  722.   mov    bx,cx
  723.   and    cl,3
  724.   mov    ax,0102h
  725.   shl    ah,cl
  726.   mov    dx,SC_INDEX
  727.   OUT_WORD
  728.   mov    cx,bx
  729.   shr    bx,2
  730.   mov    di,bx
  731.   mov    bx,[lineNum]
  732.   shl    bx,1
  733.   add    di,[lineOffs+bx]
  734.   movsb
  735.   cmp    cx,[x2]
  736.   jge    @@Exit
  737.   inc    [xOff]
  738.   jmp    short    @@ShortLine
  739.  
  740.       @@Exit:
  741.   pop   di si ds
  742.   leave
  743.   retf
  744. ENDP
  745.  
  746. PROC    C    putLine_mem_copy
  747.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DWORD
  748.   push    ds si di            ; save these registers
  749.  
  750.   xor    eax,eax                ; clear EAX
  751.   xor    edx,edx                ; clear EDX
  752.   xor    edi,edi                ; clear EDI
  753.  
  754.   les    di,[outAddr]            ; load output address
  755.   mov    ax,[y]
  756.   mov    dx,[outScreenWide]
  757.   mul    edx                    ; EDX:EAX = offset - EDI - x
  758.   add    edi,eax                ; EDI = offset - x
  759.   mov    dx,[xOff]
  760.   add    edi,edx                ; EDI = offset
  761.   mov    edx,edi                ; EDX = offset
  762.   shr    edx,4                ; EDX = # of paragraphs (segments)
  763.   add    dx,[outSeg]            ; DX = new segment
  764.   mov    es,dx                ; ES = new segment
  765.   and    di,0000000000001111b             ; DI = offset within new segment
  766.  
  767.   lds    si,[buf]            ; load input address
  768.   mov    dx,si                ; DX = offset
  769.   shr    dx,4                ; DX = # of paragraphs (segments)
  770.   mov    ax,ds                ; AX = DS
  771.   add    ax,dx                ; AX = new DS
  772.   mov    ds,ax                ; DS = new DS
  773.   and    si,0000000000001111b        ; SI = offset within new segment
  774.  
  775.   cld
  776.   mov    cx,[lineLen]            ; CX = line length
  777.   mov    dx,cx                ; DX = line length
  778.   shr    cx,2                ; CX = line length in dwords
  779.   rep    movsd                     ; move the dwords if necessary
  780.   mov    cx,dx                ; CX = line length in bytes
  781.   and    cx,0000000000000011b        ; CX = any residual bytes
  782.   rep    movsb                ; move the bytes if necessary
  783.  
  784.   pop    di si ds            ; restore registers
  785.   leave                    ; clean up
  786.   retf                    ; return
  787. ENDP
  788.  
  789.  
  790. ;*****
  791. ;***** putLineInv
  792. ;*****
  793.  
  794. PROC    C    putLineInv_mem_copy
  795.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DWORD
  796.   push    ds si di            ; save these registers
  797.  
  798.   xor    eax,eax                ; clear EAX
  799.   xor    edx,edx                ; clear EDX
  800.   xor    edi,edi                ; clear EDI
  801.  
  802.   les    di,[outAddr]            ; load output address
  803.   mov    ax,[y]
  804.   mov    dx,[outScreenWide]
  805.   mul    edx                    ; EDX:EAX = offset - EDI - x
  806.   add    edi,eax                ; EDI = offset - x
  807.   mov    dx,[xOff]
  808.   add    edi,edx                ; EDI = offset
  809.   mov    edx,edi                ; EDX = offset
  810.   shr    edx,4                ; EDX = # of paragraphs (segments)
  811.   add    dx,[outSeg]            ; DX = new segment
  812.   mov    es,dx                ; ES = new segment
  813.   and    di,0000000000001111b             ; DI = offset within new segment
  814.  
  815.   lds    si,[buf]            ; load input address
  816.   mov    dx,si                ; DX = offset
  817.   shr    dx,4                ; DX = # of paragraphs (segments)
  818.   mov    ax,ds                ; AX = DS
  819.   add    ax,dx                ; AX = new DS
  820.   mov    ds,ax                ; DS = new DS
  821.   and    si,0000000000001111b        ; SI = offset within new segment
  822.  
  823.   cld
  824.   mov    cx,[lineLen]            ; CX = line length
  825.  
  826.     @@loopStart:
  827.   lodsb                    ; grab a pixel
  828.   or    al,al                ; is it a zero pixel?
  829.   jz    @@invisible            ; yes, don't copy it
  830.   stosb                    ; no, copy it ...
  831.   loop    @@loopStart            ; ... and start loop again
  832.   jmp    short    @@loopDone        ; quit loop when completed
  833.     @@invisible:
  834.   inc    di                ; skip past pixel ...
  835.   loop    @@loopStart            ; ... and start loop again
  836.  
  837.     @@loopDone:
  838.   pop    di si ds            ; restore registers
  839.   leave                    ; clean up
  840.   retf                    ; return
  841. ENDP
  842.  
  843.  
  844. ;*****
  845. ;***** getLine
  846. ;*****
  847.  
  848. PROC    C    getLine_scr
  849.     ARG    lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DWORD
  850.     LOCAL    x2:WORD
  851.   push    ds si di
  852.  
  853.   mov    bx,[lineNum]            ; start address in ES:DI
  854.   shl    bx,1
  855.   mov    si,[lineOffs+bx]
  856.   mov    dx,[xOff]
  857.   shr    dx,2
  858.   add    si,dx
  859.   mov    ax,0A000h
  860.   mov    ds,ax
  861.   les    di,[buf]            ; buffer addr in DS:SI
  862.   cld
  863.  
  864.   mov    bx,[xOff]
  865.   add    bx,[lineLen]            ; calculate x2
  866.   dec    bx
  867.   mov    [x2],bx
  868.  
  869.   mov    cx,[lineLen]            ; line is short
  870.   cmp    cx,4
  871. JUMPS
  872.   jle    @@ShortLine
  873. NOJUMPS
  874.  
  875.   mov    ax,[xOff]            ; calculate starting plane
  876.   mov    bx,ax
  877.   and    al,3
  878.   mov    ah,al
  879.   mov    al,READ_MAP
  880.   mov    dx,GC_INDEX
  881.   OUT_WORD
  882.   push    di
  883.   mov    bx,[x2]
  884.   mov    cx,[xOff]
  885.     @@Loop1:
  886.   cmp    cx,bx
  887.   jg    @@Loop1Done
  888.   lodsb
  889.   stosb
  890.   add    cx,4
  891.   add    di,3
  892.   jmp    short    @@Loop1
  893.  
  894.     @@Loop1Done:
  895.   pop    di
  896.   inc    di
  897.   push    di
  898.   mov    bx,[xOff]
  899.   inc    bx
  900.   mov    ax,bx
  901.   and    al,3
  902.   mov    ah,al
  903.   mov    al,READ_MAP
  904.   mov    dx,GC_INDEX
  905.   OUT_WORD
  906.   mov    cx,bx
  907.   mov    bx,[lineNum]            ; start address in ES:DI
  908.   shl    bx,1
  909.   mov    si,[lineOffs+bx]
  910.   shr    cx,2
  911.   add    si,cx
  912.   mov    bx,[x2]
  913.   mov    cx,[xOff]
  914.   inc    cx
  915.     @@Loop2:
  916.   cmp    cx,bx
  917.   jg    @@Loop2Done
  918.   lodsb
  919.   stosb
  920.   add    cx,4
  921.   add    di,3
  922.   jmp    short    @@Loop2
  923.  
  924.     @@Loop2Done:
  925.   pop    di
  926.   inc    di
  927.   push    di
  928.   mov    bx,[xOff]
  929.   add    bx,2
  930.   mov    ax,bx
  931.   and    al,3
  932.   mov    ah,al
  933.   mov    al,READ_MAP
  934.   mov    dx,GC_INDEX
  935.   OUT_WORD
  936.   mov    cx,bx
  937.   mov    bx,[lineNum]
  938.   shl    bx,1
  939.   mov    si,[lineOffs+bx]
  940.   shr    cx,2
  941.   add    si,cx
  942.   mov    bx,[x2]
  943.   mov    cx,[xOff]
  944.   add    cx,2
  945.     @@Loop3:
  946.   cmp    cx,bx
  947.   jg    @@Loop3Done
  948.   lodsb
  949.   stosb
  950.   add    cx,4
  951.   add    di,3
  952.   jmp    short    @@Loop3
  953.  
  954.     @@Loop3Done:
  955.   pop    di
  956.   inc    di
  957.   mov    bx,[xOff]
  958.   add    bx,3
  959.   mov    ax,bx
  960.   and    al,3
  961.   mov    ah,al
  962.   mov    al,READ_MAP
  963.   mov    dx,GC_INDEX
  964.   OUT_WORD
  965.   mov    cx,bx
  966.   mov    bx,[lineNum]
  967.   shl    bx,1
  968.   mov    si,[lineOffs+bx]
  969.   shr    cx,2
  970.   add    si,cx
  971.   mov    bx,[x2]
  972.   mov    cx,[xOff]
  973.   add    cx,3
  974.     @@Loop4:
  975.   cmp    cx,bx
  976.   jg    @@Exit
  977.   lodsb
  978.   stosb
  979.   add    cx,4
  980.   add    di,3
  981.   jmp    short    @@Loop4
  982.  
  983.     @@ShortLine:
  984.   mov    ax,[xOff]
  985.   mov    bx,ax
  986.   and    al,3
  987.   mov    ah,al
  988.   mov    al,READ_MAP
  989.   mov    dx,GC_INDEX
  990.   OUT_WORD
  991.   mov    cx,bx
  992.   shr    bx,2
  993.   mov    si,bx
  994.   mov    bx,[lineNum]
  995.   shl    bx,1
  996.   add    si,[lineOffs+bx]
  997.   movsb
  998.   cmp    cx,[x2]
  999.   jge    @@Exit
  1000.   inc    [xOff]
  1001.   jmp    short    @@ShortLine
  1002.  
  1003.     @@Exit:
  1004.   pop   di si ds
  1005.   leave
  1006.   retf
  1007. ENDP
  1008.  
  1009. PROC    C    getLine_mem
  1010.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DWORD
  1011.   push    ds si di            ; save these registers
  1012.  
  1013.   xor    eax,eax                ; clear EAX
  1014.   xor    edx,edx                ; clear EDX
  1015.   xor    esi,esi                ; clear ESI
  1016.  
  1017.   les    si,[inAddr]            ; load input address
  1018.   mov    ax,[y]
  1019.   mov    dx,[inScreenWide]
  1020.   mul    edx                    ; EDX:EAX = offset - ESI - x
  1021.   add    esi,eax                ; ESI = offset - x
  1022.   mov    dx,[xOff]
  1023.   add    esi,edx                ; ESI = offset
  1024.   mov    edx,esi                ; EDX = offset
  1025.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1026.   add    dx,[inSeg]            ; DX = new segment
  1027.   mov    ds,dx                ; ES = new segment
  1028.   and    si,0000000000001111b             ; SI = offset within new segment
  1029.  
  1030.   les    di,[buf]            ; load output address
  1031.   mov    dx,di                ; DX = offset
  1032.   shr    dx,4                ; DX = # of paragraphs (segments)
  1033.   mov    ax,es                ; AX = ES
  1034.   add    ax,dx                ; AX = new ES
  1035.   mov    es,ax                ; ES = new ES
  1036.   and    di,0000000000001111b        ; DI = offset within new segment
  1037.  
  1038.   cld
  1039.   mov    cx,[lineLen]            ; CX = line length
  1040.   mov    dx,cx                ; DX = line length
  1041.   shr    cx,2                ; CX = line length in dwords
  1042.   rep    movsd                     ; move the dwords if necessary
  1043.   mov    cx,dx                ; CX = line length in bytes
  1044.   and    cx,0000000000000011b        ; CX = any residual bytes
  1045.   rep    movsb                ; move the bytes if necessary
  1046.  
  1047.   pop    di si ds            ; restore registers
  1048.   leave                    ; clean up
  1049.   retf                    ; return
  1050. ENDP
  1051.  
  1052.  
  1053. ;*****
  1054. ;***** putPixel
  1055. ;*****
  1056.  
  1057. ; Copy a pixel to the screen
  1058. PROC    C    putPixel_scr_copy
  1059.     ARG    x:WORD, y:WORD, colour:BYTE
  1060.   mov    ax,0A000h            ; point ES:BX to screen
  1061.   mov    es,ax
  1062.   mov    bx,[y]                ; point BX to start of desired row
  1063.   shl    bx,1
  1064.   mov    bx,[lineOffs+bx]
  1065.   mov    dx,[x]                ; DX = x coordinate of pixel
  1066.   mov    cx,dx                ; CX = x coordinate of pixel
  1067.   shr    dx,2                ; DX = x coordinate of pixel / 4
  1068.   add    bx,dx                ; ES:BX points to pixel
  1069.   and    cl,3                ; get the plane # of the pixel
  1070.   mov    ax,102h                ; set the bit corresponding to ...
  1071.   shl    ah,cl                ; ... the pixel's plane
  1072.   mov    dx,SC_INDEX
  1073.   OUT_WORD
  1074.   mov    al,[colour]            ; AL = pixel value
  1075.   mov    [es:bx],al            ; store pixel value
  1076.   leave                    ; clean up call stack
  1077.   retf                    ; return
  1078. ENDP
  1079.  
  1080. ; AND a pixel to the screen
  1081. PROC    C    putPixel_scr_and
  1082.     ARG    x:WORD, y:WORD, colour:BYTE
  1083.   mov    ax,0A000h            ; point ES:BX to screen
  1084.   mov    es,ax
  1085.   mov    bx,[y]                ; point BX to start of desired row
  1086.   shl    bx,1
  1087.   mov    bx,[lineOffs+bx]
  1088.   mov    dx,[x]                ; DX = x coordinate of pixel
  1089.   mov    cx,dx                ; CX = x coordinate of pixel
  1090.   shr    dx,2                ; DX = x coordinate of pixel / 4
  1091.   add    bx,dx                ; ES:BX points to pixel
  1092.   and    cl,3                ; get the plane # of the pixel
  1093.   mov    ax,102h                ; set the bit corresponding to ...
  1094.   shl    ah,cl                ; ... the pixel's plane
  1095.   mov    dx,SC_INDEX
  1096.   OUT_WORD
  1097.   mov    al,[colour]            ; AL = pixel value
  1098.   and    [es:bx],al            ; AND pixel value
  1099.   leave                    ; clean up call stack
  1100.   retf                    ; return
  1101. ENDP
  1102.  
  1103. ; NOT a pixel to the screen
  1104. PROC    C    putPixel_scr_not
  1105.     ARG    x:WORD, y:WORD, colour:BYTE
  1106.   mov    ax,0A000h            ; point ES:BX to screen
  1107.   mov    es,ax
  1108.   mov    bx,[y]                ; point BX to start of desired row
  1109.   shl    bx,1
  1110.   mov    bx,[lineOffs+bx]
  1111.   mov    dx,[x]                ; DX = x coordinate of pixel
  1112.   mov    cx,dx                ; CX = x coordinate of pixel
  1113.   shr    dx,2                ; DX = x coordinate of pixel / 4
  1114.   add    bx,dx                ; ES:BX points to pixel
  1115.   and    cl,3                ; get the plane # of the pixel
  1116.   mov    ax,102h                ; set the bit corresponding to ...
  1117.   shl    ah,cl                ; ... the pixel's plane
  1118.   mov    dx,SC_INDEX
  1119.   OUT_WORD
  1120.   mov    al,[colour]            ; AL = pixel value
  1121.   not    al                ; NOT pixel value
  1122.   mov    [es:bx],al            ; store NOTed pixel value
  1123.   leave                    ; clean up call stack
  1124.   retf                    ; return
  1125. ENDP
  1126.  
  1127. ; OR a pixel to the screen
  1128. PROC    C    putPixel_scr_or
  1129.     ARG    x:WORD, y:WORD, colour:BYTE
  1130.   mov    ax,0A000h            ; point ES:BX to screen
  1131.   mov    es,ax
  1132.   mov    bx,[y]                ; point BX to start of desired row
  1133.   shl    bx,1
  1134.   mov    bx,[lineOffs+bx]
  1135.   mov    dx,[x]                ; DX = x coordinate of pixel
  1136.   mov    cx,dx                ; CX = x coordinate of pixel
  1137.   shr    dx,2                ; DX = x coordinate of pixel / 4
  1138.   add    bx,dx                ; ES:BX points to pixel
  1139.   and    cl,3                ; get the plane # of the pixel
  1140.   mov    ax,102h                ; set the bit corresponding to ...
  1141.   shl    ah,cl                ; ... the pixel's plane
  1142.   mov    dx,SC_INDEX
  1143.   OUT_WORD
  1144.   mov    al,[colour]            ; AL = pixel value
  1145.   or    [es:bx],al            ; OR pixel value
  1146.   leave                    ; clean up call stack
  1147.   retf                    ; return
  1148. ENDP
  1149.  
  1150. ; XOR a pixel to the screen
  1151. PROC    C    putPixel_scr_xor
  1152.     ARG    x:WORD, y:WORD, colour:BYTE
  1153.   mov    ax,0A000h            ; point ES:BX to screen
  1154.   mov    es,ax
  1155.   mov    bx,[y]                ; point BX to start of desired row
  1156.   shl    bx,1
  1157.   mov    bx,[lineOffs+bx]
  1158.   mov    dx,[x]                ; DX = x coordinate of pixel
  1159.   mov    cx,dx                ; CX = x coordinate of pixel
  1160.   shr    dx,2                ; DX = x coordinate of pixel / 4
  1161.   add    bx,dx                ; ES:BX points to pixel
  1162.   and    cl,3                ; get the plane # of the pixel
  1163.   mov    ax,102h                ; set the bit corresponding to ...
  1164.   shl    ah,cl                ; ... the pixel's plane
  1165.   mov    dx,SC_INDEX
  1166.   OUT_WORD
  1167.   mov    al,[colour]            ; AL = pixel value
  1168.   xor    [es:bx],al            ; XOR pixel value
  1169.   leave                    ; clean up call stack
  1170.   retf                    ; return
  1171. ENDP
  1172.  
  1173. ; Copy a pixel to memory
  1174. PROC    C    putPixel_mem_copy
  1175.     ARG    x:WORD,y:WORD,colour:BYTE
  1176.   xor    eax,eax                ; clear EAX
  1177.   xor    ebx,ebx                ; clear EBX
  1178.   xor    edx,edx                ; clear EDX
  1179.  
  1180.   les    bx,[outAddr]            ; load output address
  1181.   mov    ax,[y]
  1182.   mov    dx,[outScreenWide]
  1183.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1184.   add    ebx,eax                ; EBX = offset - x
  1185.   mov    dx,[x]
  1186.   add    ebx,edx                ; EBX = offset
  1187.  
  1188.   mov    edx,ebx                ; EDX = offset
  1189.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1190.   add    dx,[outSeg]            ; DX = new segment
  1191.   mov    es,dx                ; ES = new segment
  1192.   and    bx,0000000000001111b             ; BX = offset within new segment
  1193.  
  1194.   mov    al,[colour]            ; colour in AL
  1195.   mov    [es:bx],al            ; store pixel
  1196.   leave                    ; clean up
  1197.   retf                    ; return
  1198. ENDP
  1199.  
  1200. ; AND a pixel to memory
  1201. PROC    C    putPixel_mem_and
  1202.     ARG    x:WORD,y:WORD,colour:BYTE
  1203.   xor    eax,eax                ; clear EAX
  1204.   xor    ebx,ebx                ; clear EBX
  1205.   xor    edx,edx                ; clear EDX
  1206.  
  1207.   les    bx,[outAddr]            ; load output address
  1208.   mov    ax,[y]
  1209.   mov    dx,[outScreenWide]
  1210.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1211.   add    ebx,eax                ; EBX = offset - x
  1212.   mov    dx,[x]
  1213.   add    ebx,edx                ; EBX = offset
  1214.  
  1215.   mov    edx,ebx                ; EDX = offset
  1216.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1217.   add    dx,[outSeg]            ; DX = new segment
  1218.   mov    es,dx                ; ES = new segment
  1219.   and    bx,0000000000001111b             ; BX = offset within new segment
  1220.  
  1221.   mov    al,[colour]            ; colour in AL
  1222.   and    [es:bx],al            ; AND pixel
  1223.   leave                    ; clean up
  1224.   retf                    ; return
  1225. ENDP
  1226.  
  1227. ; NOT a pixel to memory
  1228. PROC    C    putPixel_mem_not
  1229.     ARG    x:WORD,y:WORD,colour:BYTE
  1230.   xor    eax,eax                ; clear EAX
  1231.   xor    ebx,ebx                ; clear EBX
  1232.   xor    edx,edx                ; clear EDX
  1233.  
  1234.   les    bx,[outAddr]            ; load output address
  1235.   mov    ax,[y]
  1236.   mov    dx,[outScreenWide]
  1237.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1238.   add    ebx,eax                ; EBX = offset - x
  1239.   mov    dx,[x]
  1240.   add    ebx,edx                ; EBX = offset
  1241.  
  1242.   mov    edx,ebx                ; EDX = offset
  1243.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1244.   add    dx,[outSeg]            ; DX = new segment
  1245.   mov    es,dx                ; ES = new segment
  1246.   and    bx,0000000000001111b             ; BX = offset within new segment
  1247.  
  1248.   mov    al,[colour]            ; colour in AL
  1249.   not    al                ; NOT it
  1250.   mov    [es:bx],al            ; store NOTed pixel
  1251.   leave                    ; clean up
  1252.   retf                    ; return
  1253. ENDP
  1254.  
  1255. ; OR a pixel to memory
  1256. PROC    C    putPixel_mem_or
  1257.     ARG    x:WORD,y:WORD,colour:BYTE
  1258.   xor    eax,eax                ; clear EAX
  1259.   xor    ebx,ebx                ; clear EBX
  1260.   xor    edx,edx                ; clear EDX
  1261.  
  1262.   les    bx,[outAddr]            ; load output address
  1263.   mov    ax,[y]
  1264.   mov    dx,[outScreenWide]
  1265.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1266.   add    ebx,eax                ; EBX = offset - x
  1267.   mov    dx,[x]
  1268.   add    ebx,edx                ; EBX = offset
  1269.  
  1270.   mov    edx,ebx                ; EDX = offset
  1271.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1272.   add    dx,[outSeg]            ; DX = new segment
  1273.   mov    es,dx                ; ES = new segment
  1274.   and    bx,0000000000001111b             ; BX = offset within new segment
  1275.  
  1276.   mov    al,[colour]            ; colour in AL
  1277.   or    [es:bx],al            ; OR pixel
  1278.   leave                    ; clean up
  1279.   retf                    ; return
  1280. ENDP
  1281.  
  1282. ; XOR a pixel to memory
  1283. PROC    C    putPixel_mem_xor
  1284.     ARG    x:WORD,y:WORD,colour:BYTE
  1285.   xor    eax,eax                ; clear EAX
  1286.   xor    ebx,ebx                ; clear EBX
  1287.   xor    edx,edx                ; clear EDX
  1288.  
  1289.   les    bx,[outAddr]            ; load output address
  1290.   mov    ax,[y]
  1291.   mov    dx,[outScreenWide]
  1292.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1293.   add    ebx,eax                ; EBX = offset - x
  1294.   mov    dx,[x]
  1295.   add    ebx,edx                ; EBX = offset
  1296.  
  1297.   mov    edx,ebx                ; EDX = offset
  1298.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1299.   add    dx,[outSeg]            ; DX = new segment
  1300.   mov    es,dx                ; ES = new segment
  1301.   and    bx,0000000000001111b             ; BX = offset within new segment
  1302.  
  1303.   mov    al,[colour]            ; colour in AL
  1304.   xor    [es:bx],al            ; XOR pixel
  1305.   leave                    ; clean up
  1306.   retf                    ; return
  1307. ENDP
  1308.  
  1309.  
  1310. ;*****
  1311. ;***** getPixel
  1312. ;*****
  1313.  
  1314. ; Get a pixel from the screen
  1315. PROC    C    getPixel_scr
  1316.     ARG    x:WORD, y:WORD
  1317.   push    di
  1318.  
  1319.   mov    ax,0A000h
  1320.   mov    es,ax
  1321.   mov    bx,[y]                ; point to start of desired row
  1322.   shl    bx,1
  1323.   mov    bx,[lineOffs+bx]
  1324.   mov    dx,[x]
  1325.   mov    cx,dx                ; store x coord
  1326.   shr    dx,2
  1327.   add    bx,dx
  1328.   mov    di,bx                ; ES:DI points to pixel
  1329.   and    cl,3                ; get the plane # of the pixel
  1330.   mov    al,READ_MAP
  1331.   mov    ah,cl
  1332.   mov    dx,GC_INDEX            ; set the bit corresponding to plane
  1333.   OUT_WORD
  1334.   xor    ax,ax
  1335.   mov    al,[es:di]
  1336.  
  1337.   pop    di
  1338.   leave
  1339.   retf
  1340. ENDP
  1341.  
  1342. ; Get a pixel from memory
  1343. PROC    C    getPixel_mem
  1344.     ARG    x:WORD,y:WORD
  1345.   xor    eax,eax                ; clear EAX
  1346.   xor    ebx,ebx                ; clear EBX
  1347.   xor    edx,edx                ; clear EDX
  1348.  
  1349.   les    bx,[inAddr]            ; load input address
  1350.   mov    ax,[y]
  1351.   mov    dx,[inScreenWide]
  1352.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1353.   add    ebx,eax                ; EBX = offset - x
  1354.   mov    dx,[x]
  1355.   add    ebx,edx                ; EBX = offset
  1356.  
  1357.   mov    edx,ebx                ; EDX = offset
  1358.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1359.   add    dx,[inSeg]            ; DX = new segment
  1360.   mov    es,dx                ; ES = new segment
  1361.   and    bx,0000000000001111b             ; BX = offset within new segment
  1362.  
  1363.   xor    ax,ax                ; clear AX
  1364.   mov    al,[es:bx]            ; store pixel in AX for return
  1365.   leave                    ; clean up
  1366.   retf                    ; return
  1367. ENDP
  1368.  
  1369.  
  1370. ;*****
  1371. ;***** horizLine
  1372. ;*****
  1373.  
  1374. PROC    C    horizLine_scr_copy
  1375.     ARG    y:WORD, x1:WORD, x2:WORD, colour:BYTE
  1376.     LOCAL    adj1:WORD, adj2:WORD
  1377.   push    si di
  1378.   cld
  1379.  
  1380.   mov    ax,[x1]                ; set up adj1
  1381.   and    ax,3
  1382.   jz    @@adj1A
  1383.   mov    bx,4
  1384.   sub    bx,ax
  1385.   mov    ax,[x1]
  1386.   add    ax,bx
  1387.   mov    [adj1],ax
  1388.   jmp    short    @@adj1B
  1389.     @@adj1A:
  1390.   mov    ax,[x1]
  1391.   mov    [adj1],ax
  1392.     @@adj1B:
  1393.  
  1394.   mov    ax,[x2]                ; set up adj2
  1395.   mov    [adj2],ax
  1396.   and    ax,3
  1397.   sub    [adj2],ax
  1398.  
  1399.   mov    ax,[x1]                ; ensure x1 <= x2
  1400.   cmp    ax,[x2]
  1401.   jbe    @@setup
  1402.   mov    bx,[x2]
  1403.   mov    [x1],bx
  1404.   mov    [x2],ax
  1405.  
  1406.     @@setup:
  1407.   mov    ax,0A000h            ; set ES:DI to line start address
  1408.   mov    es,ax
  1409.   mov    bx,[y]
  1410.   shl    bx,1
  1411.   mov    di,[lineOffs+bx]
  1412.   mov    bx,[x1]                ; current x counter
  1413.   shr    bx,2
  1414.   add    di,bx
  1415.  
  1416.   mov    cx,[adj2]            ; CX = # of 4-pixel sets starting
  1417.   shr    cx,2                            ; on plane 0
  1418.   mov    bx,[adj1]
  1419.   shr    bx,2
  1420.   sub    cx,bx
  1421.  
  1422.   cmp    cx,1
  1423.   jl    @@shortLine
  1424.  
  1425.   ; Draw the left edge
  1426.   mov    ax,[x1]                ; get plane number of pixel #1
  1427.   and    ax,3
  1428.   jz    @@planeZeroStart        ; starts at plane zero
  1429.   mov    si,ax                ; set for pixels
  1430.   mov    ah,[leftEdgeMask+si]
  1431.   mov    al,MAP_MASK
  1432.   mov    dx,SC_INDEX
  1433.   OUT_WORD
  1434.   mov    al,[colour]
  1435.   stosb
  1436.  
  1437.   ; Draw the interior stretch
  1438.     @@planeZeroStart:
  1439.   mov    ax,0F02h            ; enable writes to all planes
  1440.   mov    dx,SC_INDEX
  1441.   OUT_WORD
  1442.   mov    al,[colour]            ; EAX = colour:colour:colour:colour
  1443.   mov    ah,al
  1444.   mov    dx,ax
  1445.   shl    eax,16
  1446.   mov    ax,dx
  1447.   mov    dx,cx                ; DX = CX
  1448.   shr    cx,2                ; CX = line length in dwords
  1449.   rep    stosd                ; store the dwords
  1450.   mov    cx,dx                ; CX = line length in bytes
  1451.   and    cx,0000000000000011b        ; CX = number of residual bytes
  1452.   rep    stosb                ; store the residual bytes
  1453.  
  1454.   ; Draw the right edge
  1455.     @@rightEdge:
  1456.   mov    ax,[x2]                ; get plane number of last pixel
  1457.   and    ax,3
  1458.   mov    si,ax                ; set for pixels
  1459.   mov    ah,[rightEdgeMask+si]
  1460.   mov    al,MAP_MASK
  1461.   mov    dx,SC_INDEX
  1462.   OUT_WORD
  1463.   mov    al,[colour]
  1464.   stosb
  1465.  
  1466.     @@Exit:
  1467.   pop    di si                ; clean up and go home
  1468.   leave
  1469.   retf
  1470.  
  1471.     @@shortLine:            ; for very small lines
  1472.   mov    al,[colour]
  1473.   mov    cx,[x1]
  1474.   mov    dx,[y]
  1475.     @@Loop:
  1476.   push    ax cx dx            ; slow loop until done
  1477.   call    putPixel_scr_copy C, cx, dx, ax
  1478.   pop    dx cx ax
  1479.   inc    cx
  1480.   cmp    cx,[x2]
  1481.   jle    @@Loop
  1482.  
  1483.   pop     di si
  1484.   leave
  1485.   retf
  1486. ENDP
  1487.  
  1488. PROC    C    horizLine_mem_copy
  1489.     ARG    y:WORD, x1:WORD, x2:WORD, colour:BYTE
  1490.   push    edi                ; store EDI
  1491.  
  1492.   xor    eax,eax                ; clear EAX
  1493.   xor    edi,edi                ; clear EDI
  1494.   xor    edx,edx                ; clear EDX
  1495.  
  1496.   les    di,[outAddr]            ; load output address
  1497.   mov    ax,[y]
  1498.   mov    dx,[outScreenWide]
  1499.   mul    edx                    ; EDX:EAX = offset - EDI - x
  1500.   add    edi,eax                ; EDI = offset - x
  1501.   mov    dx,[x1]
  1502.   add    edi,edx                ; EDI = offset
  1503.   mov    edx,edi                ; EDX = offset
  1504.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1505.   add    dx,[outSeg]            ; DX = new segment
  1506.   mov    es,dx                ; ES = new segment
  1507.   and    di,0000000000001111b             ; DI = offset within new segment
  1508.  
  1509.   mov    al,[colour]            ; colour in AL
  1510.   mov    ah,al                ; colour in AH
  1511.   mov    bx,ax
  1512.   shl    eax,16
  1513.   mov    ax,bx                 ; colour in each byte of EAX
  1514.  
  1515.   mov    cx,[x2]
  1516.   sub    cx,[x1]
  1517.   inc    cx                ; CX = line length in pixels
  1518.   mov    dx,cx                ; DX = line length in bytes
  1519.  
  1520.   shr    cx,2                ; CX = line length in dwords
  1521.   rep    stosd                ; store four bytes at a time
  1522.   mov    cx,dx                ; CX = line length in pixels
  1523.   and    cx,0000000000000011b        ; CX = any remaining bytes
  1524.   rep    stosb                ; store the remaining bytes
  1525.  
  1526.   pop    edi                    ; restore EDI
  1527.   leave                    ; clean up
  1528.   retf                    ; return
  1529. ENDP
  1530.  
  1531.  
  1532. ;*****
  1533. ;***** setPaletteReg
  1534. ;*****
  1535.  
  1536. PROC    C    setPaletteReg
  1537.     ARG    palNum:WORD,red:BYTE,green:BYTE,blue:BYTE
  1538.   mov    bx,[palNum]
  1539.  
  1540.   mov    dx,3C8h                ; set for the right palette register
  1541.   mov    ax,[palNum]
  1542.   out    dx,al
  1543.   inc    dx
  1544.  
  1545.   mov    al,[red]            ; red
  1546.   shr    al,2
  1547.   jnc    @@L1
  1548.   cmp    al,63
  1549.   je    @@L1
  1550.   inc    al
  1551.     @@L1:
  1552.   out    dx,al
  1553.  
  1554.   mov    al,[green]            ; green
  1555.   shr    al,2
  1556.   jnc    @@L2
  1557.   cmp    al,63
  1558.   je    @@L2
  1559.   inc    al
  1560.     @@L2:
  1561.   out    dx,al
  1562.  
  1563.   mov    al,[blue]            ; blue
  1564.   shr    al,2
  1565.   jnc    @@L3
  1566.   cmp    al,63
  1567.   je    @@L3
  1568.   inc    al
  1569.     @@L3:
  1570.   out    dx,al
  1571.  
  1572.   leave
  1573.   retf
  1574. ENDP
  1575.  
  1576.  
  1577. ;*****
  1578. ;***** getPaletteReg
  1579. ;*****
  1580.  
  1581. PROC    C    getPaletteReg
  1582.     ARG    palNum:WORD,red:DWORD,green:DWORD,blue:DWORD
  1583.   push    ds si
  1584.  
  1585.   mov    dx,3C7h                ; set for right palette register
  1586.   mov    ax,[palNum]
  1587.   out    dx,al
  1588.   mov    dx,3C9h
  1589.  
  1590.   in    al,dx                ; red
  1591.   lds    si,[red]
  1592.   shl    al,2
  1593.   mov    [ds:si],al
  1594.   in    al,dx                ; green
  1595.   lds    si,[green]
  1596.   shl    al,2
  1597.   mov    [ds:si],al
  1598.   in    al,dx                ; blue
  1599.   lds    si,[blue]
  1600.   shl    al,2
  1601.   mov    [ds:si],al
  1602.  
  1603.   pop    si ds
  1604.   leave
  1605.   retf
  1606. ENDP
  1607.  
  1608.  
  1609. ;*****
  1610. ;***** setBlockPalette
  1611. ;*****
  1612.  
  1613. PROC    C    setBlockPalette
  1614.     ARG    firstReg:WORD,lastReg:WORD,paletteData:DWORD
  1615.   push    ds si
  1616.  
  1617.   lds    si,[paletteData]        ; set up
  1618.   mov    dx,3C8h
  1619.   mov    ax,[firstReg]
  1620.   out    dx,al
  1621.   inc    dx
  1622.   mov    cx,[lastReg]            ; CX = number of registers
  1623.   sub    cx,ax
  1624.   inc    cx
  1625.   cld
  1626.  
  1627.     @@LLoop:
  1628.   lodsb            ; red
  1629.   shr    al,2
  1630.   jnc    @@L1
  1631.   cmp    al,63
  1632.   je    @@L1
  1633.   inc    al
  1634.       @@L1:
  1635.   out    dx,al
  1636.  
  1637.   lodsb            ; green
  1638.   shr    al,2
  1639.   jnc    @@L2
  1640.   cmp    al,63
  1641.   je    @@L2
  1642.   inc    al
  1643.       @@L2:
  1644.   out    dx,al
  1645.  
  1646.   lodsb            ; blue
  1647.   shr    al,2
  1648.   jnc    @@L3
  1649.   cmp    al,63
  1650.   je    @@L3
  1651.   inc    al
  1652.       @@L3:
  1653.   out    dx,al
  1654.  
  1655.   loop    @@LLoop
  1656.  
  1657.     @@LExit:
  1658.   pop    si ds
  1659.   leave
  1660.   retf
  1661. ENDP
  1662.  
  1663.  
  1664. ;*****
  1665. ;***** getBlockPalette
  1666. ;*****
  1667.  
  1668. PROC    C    getBlockPalette
  1669.     ARG    firstReg:WORD,lastReg:WORD,paletteData:DWORD
  1670.   push    di
  1671.  
  1672.   les    di,[paletteData]        ; set up
  1673.   mov    dx,3C7h
  1674.   mov    ax,[firstReg]
  1675.   out    dx,al
  1676.   mov    dx,3C9h
  1677.   mov    cx,[lastReg]            ; CX = number of registers
  1678.   sub    cx,ax
  1679.   inc    cx
  1680.   cld
  1681.  
  1682.     @@L1:
  1683.   in    al,dx
  1684.   shl    al,2
  1685.   stosb            ; red
  1686.   in    al,dx
  1687.   shl    al,2
  1688.   stosb            ; green
  1689.   in    al,dx
  1690.   shl    al,2
  1691.   stosb            ; blue
  1692.   loop    @@L1
  1693.  
  1694.     @@LExit:
  1695.   pop    di
  1696.   leave
  1697.   retf
  1698. ENDP
  1699.  
  1700.  
  1701. ;*****
  1702. ;***** clearGraphics
  1703. ;*****
  1704.  
  1705. PROC    C    clearGraphics_scr_copy
  1706.     ARG    colour:BYTE
  1707.   push    di                ; store DI
  1708.  
  1709.   mov   dx,SC_INDEX            ; enable writes to all four planes
  1710.   mov   ax,0F02h
  1711.   out   dx,ax
  1712.  
  1713.   mov    ax,0A000h            ; point ES:DI to screen
  1714.   mov    es,ax
  1715.   xor    di,di
  1716.   mov    al,[colour]            ; EAX = colour:colour:colour:colour
  1717.   mov    ah,al
  1718.   mov    bx,ax
  1719.   shl    eax,16
  1720.   mov    ax,bx
  1721.   mov    cx,4800                ; clear the screen
  1722.   cld
  1723.   rep    stosd
  1724.  
  1725.   pop    di                ; restore DI
  1726.   leave                    ; clean up call stack
  1727.   retf                    ; return
  1728. ENDP
  1729.  
  1730.  
  1731.     ENDS
  1732. END
  1733.