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

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