home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / C / TGE129D / 360X480.ASM < prev    next >
Assembly Source File  |  1993-09-02  |  37KB  |  1,745 lines

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