home *** CD-ROM | disk | FTP | other *** search
/ VGA Spectrum 1 / UGASpectrum.cdr / utility / grafwk52.exe / GRAFDRV.ASM < prev    next >
Assembly Source File  |  1990-04-28  |  13KB  |  574 lines

  1.         COMMENT %
  2.  
  3.     GRAPHIC WORKSHOP VGA SCREEN DRIVER
  4.     COPYRIGHT (C) 1990 ALCHEMY MINDWORKS INC.
  5.     VERSION 1.1
  6.  
  7.     This is a skeletal driver for use as the
  8.     basis for writing custom SVGA loadable drivers
  9.     for Graphic Workshop. You will require the
  10.     hardware specific information about your
  11.     card to customize this driver.
  12.  
  13.     As it stands, the driver implements the code for
  14.     a stock VGA card running in mode 13H for 256
  15.     colour images, mode 12H for 16 colour images
  16.     and mode 11H for monochrome images.
  17.  
  18.     To generate a driver from this file, it must
  19.     be assembled using MASM, linked and converted
  20.     to a binary file with EXE2BIN.
  21.  
  22.     The binary driver file must be less than 64K in size...
  23.     not a likely problem.
  24.  
  25.     Best of cosmic luck...
  26.  
  27.         %
  28.  
  29. VERSION        EQU    1        ;VERSION NUMBER
  30. SUBVERSION    EQU    1        ;SUBVERSION NUMBER
  31.  
  32. _AOFF        EQU    6        ;STACK OFFSET
  33.  
  34. VGA_WIDE    EQU    320        ;WIDTH OF VGA SCREEN IN PIXELS
  35. VGA_DEEP    EQU    200        ;DEPTH OF VGA SCREEN IN PIXELS
  36. VGA_SCREENSEG    EQU    0A000H        ;SEGMENT OF VGA SCREEN
  37. EGA_WIDE    EQU    640        ;WIDTH OF EGA SCREEN IN PIXELS
  38. EGA_DEEP    EQU    480        ;DEPTH OF EGA SCREEN IN PIXELS
  39. EGA_BYTES    EQU    80        ;WIDTH OF EGA SCREEN IN BYTES
  40. EGA_SCREENSEG    EQU    0A000H        ;SEGMENT OF EGA SCREEN
  41. MONO_WIDE    EQU    640        ;WIDTH OF MONO SCREEN IN PIXELS
  42. MONO_DEEP    EQU    480        ;DEPTH OF MONO SCREEN IN PIXELS
  43. MONO_BYTES    EQU    80        ;WIDTH OF MONO SCREEN IN BYTES
  44. MONO_SCREENSEG    EQU    0A000H        ;SEGMENT OF MONO SCREEN
  45.  
  46. ;THIS MACRO SELECTS AN EGA PLANE
  47. EGAPLANE        MACRO    ARG1
  48.         MOV    AL,2
  49.         MOV    DX,03C4H
  50.         OUT    DX,AL
  51.         INC    DX
  52.         MOV    AL,ARG1
  53.         OUT    DX,AL
  54.         ENDM
  55.  
  56. CODE        SEGMENT PARA PUBLIC 'CODE'
  57.         ASSUME    CS:CODE
  58.  
  59.         ORG    0000H        ;ORIGIN FOR LOADABLE DRIVER
  60.  
  61.         DB    'ALCHDRV2'    ;SIGNATURE - DON'T CHANGE THIS
  62.  
  63. ;THE FOLLOWING ARE THE POINTERS TO THE CALLABLE ROUTINES AND THE COMMON
  64. ;DATA. THE SEGMENTS ARE FILLED IN BY GRAPHIC WORKSHOP. DON'T CHANGE ANYTHING.
  65. DISPATCH    PROC    FAR
  66.         DW      VGA_ON        ;FAR POINTER TO VGA MODE SELECT
  67.         DW      ?
  68.         DW    VGA_LINE    ;FAR POINTER TO VGA LINE DISPLAY
  69.         DW    ?
  70.         DW    VGA_OFF        ;FAR POINTER TO VGA MODE DESELECT
  71.         DW    ?
  72.         DW    VGA_PALETTE    ;FAR POINTER TO VGA PALETTE SET
  73.         DW    ?
  74.         DW    VGA_OVERSCAN    ;FAR POINTER TO VGA OVERSCAN SET
  75.         DW    ?
  76.         DW      EGA_ON        ;FAR POINTER TO EGA MODE SELECT
  77.         DW      ?
  78.         DW    EGA_LINE    ;FAR POINTER TO EGA LINE DISPLAY
  79.         DW    ?
  80.         DW    EGA_OFF        ;FAR POINTER TO EGA MODE DESELECT
  81.         DW    ?
  82.         DW    EGA_PALETTE    ;FAR POINTER TO EGA PALETTE SET
  83.         DW    ?
  84.         DW      MONO_ON        ;FAR POINTER TO MONO MODE SELECT
  85.         DW      ?
  86.         DW    MONO_FRAME    ;FAR POINTER TO MONO PAGE DISPLAY
  87.         DW    ?
  88.         DW    MONO_LINE    ;FAR POINTER TO MONO LINE DISPLAY
  89.         DW    ?
  90.         DW    MONO_OFF    ;FAR POINTER TO MONO MODE DESELECT
  91.         DW    ?
  92.         DW    0,0        ;NULL ONE
  93.         DW    0,0        ;NULL TWO
  94.         DW    0,0        ;NULL THREE
  95.         DW    0,0        ;NULL FOUR
  96.  
  97. V_VGAWIDE    DW    VGA_WIDE    ;VGA SCREEN WIDTH
  98. V_VGADEEP    DW    VGA_DEEP    ;VGA SCREEN DEPTH
  99. V_VGASCRNSEG    DW    VGA_SCREENSEG    ;VGA SCREEN SEGMENT
  100. V_EGAWIDE    DW    EGA_WIDE    ;EGA SCREEN WIDTH
  101. V_EGADEEP    DW    EGA_DEEP    ;EGA SCREEN DEPTH
  102. V_EGABYTES    DW    EGA_BYTES    ;EGA SCREEN BYTES
  103. V_EGASCRNSEG    DW    EGA_SCREENSEG    ;EGA SCREEN SEGMENT
  104. V_MONOWIDE    DW    MONO_WIDE    ;MONO SCREEN WIDTH
  105. V_MONODEEP    DW    MONO_DEEP    ;MONO SCREEN DEPTH
  106. V_MONOBYTES    DW    MONO_BYTES    ;BYTE WIDTH ON MONOCHROME SCREEN
  107. V_MONOSCRNSEG    DW    MONO_SCREENSEG    ;MONOCHROME SCREEN SEGMENT
  108.  
  109. ;THESE VERSION NUMBERS REFLECT THE DRIVER TEMPLATE VERSION AND THE
  110. ;VERSION OF THE DRIVER ITSELF. YOU CAN CHANGE THE SUBVERSION VALUE
  111. ;TO REFLECT CHANGES IN YOUR DRIVER. THE VERSION VALUE MUST REMAIN
  112. ;UNCHANGED OR GRAPHIC WORKSHOP MAY REJECT YOUR DRIVER.
  113.         DW    VERSION
  114.         DW    SUBVERSION
  115.  
  116. ;THE DESCRIPTION APPEARS IN THE F10 "ABOUT" BOX IN GRAPHIC
  117. ;WORKSHOP WHEN AN EXTERNAL DRIVER IS BEING USED. IT CAN'T
  118. ;EXCEED 24 CHARACTERS AND MUST BE NULL TERMINATED
  119.         DB      'Standard VGA 320 x 200 ',0
  120. DISPATCH        ENDP
  121.  
  122. ;THIS ROUTINE SELECTS THE VGA 256 COLOUR MODE
  123. ;THE HEIGHT AND WIDTH OF THE IMAGE ARE ON THE STACK - THESE
  124. ;MAY BE USEFUL IF YOU WANT TO PICK ONE OF SEVERAL AVAILABLE
  125. ;MODES BASED ON THE AREA OF THE PICTURE TO BE DISPLAYED
  126. VGA_ON        PROC    NEAR
  127.         PUSH    DS
  128.         MOV    AX,CS
  129.         MOV    DS,AX
  130.         MOV    CX,VGA_DEEP        ;DEPTH OF SCREEN
  131.         SUB    DX,DX
  132.         MOV    SI,OFFSET SCREENTABLE
  133.  
  134. VGA_ON1:    PUSH    DX
  135.         MOV    AX,VGA_WIDE        ;WIDTH OF SCREEEN
  136.         MUL    DX
  137.         MOV    [SI],AX
  138.         ADD    SI,2
  139.         POP    DX
  140.         INC    DX
  141.         LOOP    VGA_ON1
  142.  
  143.         MOV    AX,0013H
  144.         INT    10H
  145.         POP    DS
  146.         RETF
  147. VGA_ON        ENDP
  148.  
  149. ;THIS ROUTINE DISPLAYS A VGA LINE
  150. ;THE FIRST ARGUMENT ON THE STACK (2 WORDS) IS A FAR POINTER TO
  151. ;THE LINE. THE SECOND ARGUMENT IS THE LENGTH OF THE LINE IN PIXELS
  152. VGA_LINE    PROC    NEAR
  153.         PUSH    BP
  154.         MOV    BP,SP
  155.         PUSH    DS
  156.         PUSH    ES
  157.  
  158.         MOV    SI,[BP + _AOFF + 0]    ;OFFSET OF SOURCE
  159.         MOV    DS,[BP + _AOFF + 2]    ;SEGMENT OF SOURCE
  160.  
  161.         MOV     BX,[BP + _AOFF + 6]    ;GET LINE NUMBER
  162.         CMP    BX,VGA_DEEP
  163.         JGE    SHOWVGAX
  164.  
  165.         SHL    BX,1
  166.         MOV    DI,CS:[SCREENTABLE+BX]
  167.  
  168.         CLD
  169.         MOV    CX,[BP + _AOFF + 4]    ;LENGTH OF MOVE IN BYTES
  170.         CMP    CX,0
  171.         JE    SHOWVGAX        ;CHECK FOR NASTIES
  172.         CMP    CX,VGA_WIDE
  173.         JL      SHOWVGA1
  174.         MOV    CX,VGA_WIDE
  175. SHOWVGA1:    MOV    AX,VGA_SCREENSEG
  176.         MOV    ES,AX
  177.     REPNE    MOVSB
  178.  
  179. SHOWVGAX:    POP    ES
  180.         POP    DS
  181.         POP    BP
  182.         RETF
  183. VGA_LINE    ENDP
  184.  
  185. ;THIS ROUTINE DESELECTS THE VGA 256 COLOUR MODE
  186. VGA_OFF        PROC    NEAR
  187.         MOV    AX,1200H
  188.         MOV    BX,0031H
  189.         INT    10H
  190.  
  191.         MOV    AX,0003H
  192.         INT    10H
  193.         RETF
  194. VGA_OFF        ENDP
  195.  
  196. ;THIS ROUTINE SETS THE VGA PALETTE
  197. ;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO
  198. ;THE PALETTE DATA. THE SECOND ARGUMENT IS THE NUMBER OF COLOURS.
  199. VGA_PALETTE    PROC    NEAR
  200.         PUSH    BP
  201.         MOV    BP,SP
  202.         PUSH    DS
  203.         PUSH    ES
  204.         MOV    AX,CS
  205.         MOV    ES,AX
  206.  
  207.         MOV    SI,[BP + _AOFF + 0]    ;OFFSET OF SOURCE
  208.         MOV    DS,[BP + _AOFF + 2]    ;SEGMENT OF SOURCE
  209.  
  210.         MOV    CX,[BP + _AOFF + 4]    ;NUMBER OF COLOURS
  211.         MOV    DI,OFFSET VGAPALETTE
  212.  
  213.                 CMP    CX,0            ;CHECK FOR NASTIES
  214.         JG    GVP0
  215.         JMP    GVPX
  216.  
  217.         ;WE'LL SET THE PALLETTE USING DIRECT REGISTERS RATHER
  218.         ;THAN A BIOS CALL AS IT LOOKS NIVER
  219.  
  220. GVP0:        MOV    DX,03C6H
  221.         MOV    AL,0FFH
  222.         OUT    DX,AL
  223.  
  224.         MOV    BX,0
  225.  
  226. GVP1:        PUSH    CX
  227.         MOV    DX,03C8H
  228.         MOV    AL,BL
  229.         INC    BX
  230.         OUT    DX,AL
  231.  
  232.         INC    DX
  233.  
  234.         LODSB
  235.         SHR    AL,1
  236.         SHR    AL,1
  237.         OUT    DX,AL
  238.  
  239.         LODSB
  240.         SHR    AL,1
  241.         SHR    AL,1
  242.         OUT    DX,AL
  243.  
  244.         LODSB
  245.         SHR    AL,1
  246.         SHR    AL,1
  247.         OUT    DX,AL
  248.  
  249.         POP    CX
  250.         LOOP    GVP1
  251.  
  252.  
  253.         COMMENT &
  254.  
  255. GVP0:           PUSH    CX
  256.         LODSB
  257.         SHR    AL,1
  258.         SHR    AL,1
  259.         STOSB
  260.         LODSB
  261.         SHR    AL,1
  262.         SHR    AL,1
  263.         STOSB
  264.         LODSB
  265.         SHR    AL,1
  266.         SHR    AL,1
  267.         STOSB
  268.  
  269.         POP    CX
  270.         LOOP    GVP0
  271.  
  272.         MOV    AX,1012H                ;POINT TO THE PALETTE
  273.         MOV    BX,0000H
  274.         MOV    CX,256
  275.         MOV    DX,OFFSET VGAPALETTE
  276.         INT    10H
  277.  
  278.             &
  279.  
  280. GVPX:       POP    ES
  281.         POP    DS
  282.         POP    BP
  283.         RETF
  284. VGA_PALETTE    ENDP
  285.  
  286. ;THIS ROUTINE SETS THE VGA OVERSCAN.
  287. ;THE FIRST STACK ARGUMENT IS THE COLOUR NUMBER.
  288. VGA_OVERSCAN    PROC    NEAR
  289.         PUSH    BP
  290.         MOV    BP,SP
  291.         MOV    AX,1001H
  292.         MOV    BX,[BP + _AOFF + 0]
  293.         XCHG    BH,BL
  294.         INT    10H
  295.         POP    BP
  296.         RETF
  297. VGA_OVERSCAN    ENDP
  298.  
  299. ;THIS ROUTINE SELECTS THE EGA 16 COLOUR MODE
  300. ;THE HEIGHT AND WIDTH OF THE IMAGE ARE ON THE STACK - THESE
  301. ;MAY BE USEFUL IF YOU WANT TO PICK ONE OF SEVERAL AVAILABLE
  302. ;MODES BASED ON THE AREA OF THE PICTURE TO BE DISPLAYED
  303. EGA_ON        PROC    NEAR
  304.         PUSH    DS
  305.         MOV    AX,CS
  306.         MOV    DS,AX
  307.         MOV    CX,EGA_DEEP        ;DEPTH OF SCREEN
  308.         SUB    DX,DX
  309.         MOV    SI,OFFSET SCREENTABLE
  310.  
  311. EGA_ON1:    PUSH    DX
  312.         MOV    AX,EGA_BYTES        ;WIDTH OF SCREEEN
  313.         MUL    DX
  314.         MOV    [SI],AX
  315.         ADD    SI,2
  316.         POP    DX
  317.         INC    DX
  318.         LOOP    EGA_ON1
  319.  
  320.         MOV    AX,0012H
  321.         INT    10H
  322.         POP    DS
  323.         RETF
  324. EGA_ON        ENDP
  325.  
  326. ;THIS ROUTINE DISPLAYS AN EGA LINE
  327. ;THE FIRST ARGUMENT ON THE STACK (2 WORDS) IS A FAR POINTER TO
  328. ;THE LINE. THE SECOND ARGUMENT IS THE LENGTH OF THE LINE IN BYTES
  329. EGA_LINE    PROC    NEAR
  330.         PUSH    BP
  331.         MOV    BP,SP
  332.         PUSH    DS
  333.         PUSH    ES
  334.  
  335.         MOV    SI,[BP + _AOFF + 0]    ;OFFSET OF SOURCE
  336.         MOV    DS,[BP + _AOFF + 2]    ;SEGMENT OF SOURCE
  337.         MOV     BX,[BP + _AOFF + 6]    ;GET LINE NUMBER
  338.         CMP    BX,EGA_DEEP
  339.         JGE    SHOWEGAX
  340.  
  341.         SHL    BX,1
  342.         MOV    DI,CS:[SCREENTABLE+BX]
  343.  
  344.         MOV    AX,0A000H
  345.         MOV    ES,AX
  346.         MOV    BX,[BP + _AOFF + 4]    ;LENGTH OF MOVE IN BYTES
  347.  
  348.         MOV    CX,BX
  349.         EGAPLANE    1
  350.         CLD
  351.         PUSH    DI
  352.     REPNE    MOVSB
  353.         POP    DI
  354.  
  355.         MOV    CX,BX
  356.         EGAPLANE    2
  357.         PUSH    DI
  358.     REPNE    MOVSB
  359.         POP    DI
  360.  
  361.         MOV    CX,BX
  362.         EGAPLANE    4
  363.         PUSH    DI
  364.     REPNE    MOVSB
  365.         POP    DI
  366.  
  367.         MOV    CX,BX
  368.         EGAPLANE    8
  369.         PUSH    DI
  370.     REPNE    MOVSB
  371.         POP    DI
  372.         EGAPLANE    0FH
  373.  
  374. SHOWEGAX:    POP    ES
  375.         POP    DS
  376.         POP    BP
  377.         RETF
  378. EGA_LINE    ENDP
  379.  
  380. ;THIS ROUTINE SETS THE EGA PALETTE
  381. ;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO
  382. ;THE PALETTE DATA. THE SECOND ARGUMENT IS THE NUMBER OF COLOURS.
  383. EGA_PALETTE    PROC    NEAR
  384.         PUSH    BP
  385.         MOV    BP,SP
  386.         PUSH    DS
  387.  
  388.         MOV    SI,[BP + _AOFF + 0]    ;OFFSET OF SOURCE
  389.         MOV    DS,[BP + _AOFF + 2]    ;SEGMENT OF SOURCE
  390.  
  391.         MOV    CX,[BP + _AOFF + 4]    ;NUMBER OF COLOURS
  392.         SUB    BX,BX
  393.                 CMP    CX,16
  394.         JLE    EGA_PALETTE1
  395.         MOV    CX,16
  396.  
  397. EGA_PALETTE1:    MOV    BH,[SI]
  398.         MOV    AX,1000H
  399.         INT    10H
  400.         INC    BL
  401.         INC    SI
  402.         LOOP    EGA_PALETTE1
  403.  
  404.         POP    DS
  405.         POP    BP
  406.         RETF
  407. EGA_PALETTE    ENDP
  408.  
  409. ;THIS ROUTINE DESELECTS THE EGA 16 COLOUR MODE
  410. EGA_OFF        PROC    NEAR
  411.         MOV    AX,0003H
  412.         INT    10H
  413.         RETF
  414. EGA_OFF        ENDP
  415.  
  416. ;THIS ROUTINE SELECTS THE 2 COLOUR MODE
  417. ;THE HEIGHT AND WIDTH OF THE IMAGE ARE ON THE STACK - THESE
  418. ;MAY BE USEFUL IF YOU WANT TO PICK ONE OF SEVERAL AVAILABLE
  419. ;MODES BASED ON THE AREA OF THE PICTURE TO BE DISPLAYED
  420. MONO_ON        PROC    NEAR
  421.         PUSH    DS
  422.         PUSH    ES
  423.         MOV    AX,CS
  424.         MOV    DS,AX
  425.         MOV    ES,AX
  426.         MOV    AX,0011H
  427.         INT    10H
  428.  
  429.         MOV    CX,MONO_DEEP
  430.         SUB    DX,DX
  431.         MOV    SI,OFFSET SCREENTABLE
  432.  
  433. MONO_ON1:    PUSH    DX
  434.         MOV    AX,MONO_BYTES
  435.         MUL    DX
  436.         MOV    [SI],AX
  437.         ADD    SI,2
  438.         POP    DX
  439.         INC    DX
  440.         LOOP    MONO_ON1
  441.  
  442.         POP     ES
  443.         POP    DS
  444.         SUB    AX,AX
  445.         RETF
  446. MONO_ON        ENDP
  447.  
  448. UPDATE_MOVE    EQU    2
  449. UPDATE_PAD    EQU    4
  450. UPDATE_ADJUST    EQU    6
  451.  
  452. ;THIS ROUTINE DISPLAYS A FULL MONOCHROME PAGE
  453. ;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO THE PAGE
  454. ;THE SECOND ARGUMENT IS THE WIDTH OF THE BITMAP (IN BYTES)
  455. ;THE THIRD ARGUMENT IS THE NUMBER OF LINES TO DISPLAY
  456. ;NOTE: THE SOURCE BUFFER MAY BE BIGGER THAN 64K.
  457. MONO_FRAME    PROC    NEAR
  458.         PUSH    BP
  459.         MOV    BP,SP
  460.         SUB    SP,UPDATE_ADJUST
  461.         PUSH    DS
  462.         PUSH    ES
  463.  
  464.         MOV    AX,MONO_SCREENSEG    ;POINT TO THE SCREEN
  465.         MOV    ES,AX
  466.         MOV    AX,[BP + _AOFF + 4]        ;GET THE WIDTH OF MOVE
  467.         MOV    [BP - UPDATE_MOVE],AX    ;SAVE IT LOCALLY
  468.         MOV    WORD PTR [BP - UPDATE_PAD],0    ;SET ADJUSTMENT
  469.  
  470.         CMP    AX,MONO_BYTES        ;IF THE MOVE IS LESS THAN
  471.         JL    UPDATE0            ;SCREEN WIDTH, GO FOR IT
  472.  
  473.         SUB    AX,MONO_BYTES        ;ELSE, SET MOVE WIDTH
  474.         MOV    [BP - UPDATE_PAD],AX    ;...AND THE AMOUNT TO
  475.  
  476.         MOV    AX,MONO_BYTES        ;...ADJUST THE POINTER
  477.         MOV    [BP - UPDATE_MOVE],AX    ;...AFTER EACH LINE
  478.  
  479. UPDATE0:    MOV    SI,[BP + _AOFF + 0]    ;OFFSET OF BITMAP
  480.         MOV    DS,[BP + _AOFF + 2]    ;SEGMENT OF BITMAP
  481.         MOV    CX,[BP + _AOFF + 6]    ;NUMBER OF LINES
  482.  
  483.         CLD                ;CLEAR DIRECTION FLAG
  484.         SUB    BX,BX
  485.  
  486. UPDATE1:    PUSH    CX            ;SAVE COUNT (LINE NUMBER)
  487.  
  488.         MOV    DI,CS:[SCREENTABLE + BX]
  489.         ADD    BX,2            ;POINT TO NEXT LINE
  490.  
  491.         MOV    CX,[BP - UPDATE_MOVE]    ;GET THE MOVE SIZE
  492.     REPNE    MOVSB                ;DO THE MOVE
  493.  
  494.         ADD    SI,[BP - UPDATE_PAD]    ;ADJUST THE POINTER
  495.  
  496.         CMP    SI,0F800H        ;ARE WE WITHIN 2K OF TOP?
  497.         JL      UPDATE2            ;IF NOT, CARRY ON
  498.  
  499.         MOV    AX,SI            ;SEE HOW MANY SEGMENTS ARE
  500.         MOV    CL,4            ;...IN SI (SI DIV 4)
  501.         SHR    AX,CL
  502.  
  503.         MOV    CX,DS            ;ADD THEM TO THE DATA SEGMENT
  504.         ADD    CX,AX            ;...(YOU CAN'T JUST ADD DS,AX)
  505.         MOV    DS,CX
  506.         AND    SI,000FH        ;ADJUST SI (SI MOD 16)
  507.  
  508. UPDATE2:    POP    CX            ;GET COUNT BACK
  509.         LOOP    UPDATE1                    ;DECREMENT AND LOOP
  510.  
  511.         POP    ES
  512.         POP    DS
  513.  
  514.         ADD    SP,UPDATE_ADJUST
  515.         POP    BP
  516.  
  517.         RETF
  518. MONO_FRAME    ENDP
  519.  
  520. ;THIS ROUTINE DISPLAYS A SINGLE MONOCHROME LINE
  521. ;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO THE LINE
  522. ;THE SECOND ARGUMENT IS THE LINE NUMBER
  523. ;THE THIRD ARGUMENT IS THE WIDTH OF THE BITMAP (IN BYTES)
  524. MONO_LINE    PROC    NEAR
  525.         PUSH    BP
  526.         MOV    BP,SP
  527.  
  528.         PUSH    DS
  529.         PUSH    ES
  530.  
  531.         MOV    AX,MONO_SCREENSEG    ;POINT TO THE SCREEN
  532.         MOV    ES,AX
  533.  
  534.         MOV    CX,[BP + _AOFF + 6]        ;GET THE WIDTH OF MOVE
  535.         CMP    CX,0
  536.         JE    MONO_LINE2
  537.         CMP    CX,MONO_BYTES
  538.         JL    MONO_LINE1
  539.         MOV    CX,MONO_BYTES
  540.  
  541. MONO_LINE1:    MOV    SI,[BP + _AOFF + 0]    ;OFFSET OF BITMAP
  542.         MOV    DS,[BP + _AOFF + 2]    ;SEGMENT OF BITMAP
  543.         MOV    BX,[BP + _AOFF + 4]    ;NUMBER OF LINE
  544.         SHL    BX,1
  545.  
  546.         CLD                ;CLEAR DIRECTION FLAG
  547.         MOV    DI,CS:[SCREENTABLE + BX]
  548.     REPNE    MOVSB                ;DO THE MOVE
  549.  
  550. MONO_LINE2:    POP    ES
  551.         POP    DS
  552.  
  553.         POP    BP
  554.         RETF
  555. MONO_LINE    ENDP
  556.  
  557. ;THIS ROUTINE DESELECTS THE 2 COLOUR MODE
  558. MONO_OFF    PROC    NEAR
  559.         MOV    AX,0003H
  560.         INT    10H
  561.         SUB    AX,AX
  562.         RETF
  563. MONO_OFF    ENDP
  564.  
  565. ;THIS IS A LINE START LOOKUP TABLE
  566.  
  567. SCREENTABLE    DW    MONO_DEEP DUP(?)    ;LINE START TABLE
  568.  
  569. ;THIS IS WHERE THE VGA PALETTE IS STORED
  570. VGAPALETTE    DB    768 DUP(?)        ;PALETTE
  571. CODE        ENDS
  572.         END
  573.  
  574.