home *** CD-ROM | disk | FTP | other *** search
/ VGA Spectrum 1 / UGASpectrum.cdr / utility / grafwk52.exe / VGA640.A86 < prev    next >
Text File  |  1991-01-07  |  18KB  |  871 lines

  1.         COMMENT %
  2.  
  3.     GRAPHIC WORKSHOP standard VGA, 640x480 screen driver
  4.     COPYRIGHT (C) 1990 ALCHEMY MINDWORKS INC.
  5.     VERSION 1.1
  6.  
  7.     portions copyright (C) 1990 Gregory D. Weeks
  8.     permision granted for Alchemy Mindworks to distribute.
  9.  
  10.     This driver was adapted from the skeletal driver
  11.     supplied with graphic workshop 3.4.  It will drive
  12.     a standard VGA card to 320x480 and do the bitblits
  13.     in such a manner that it looks like a 640x480 screen
  14.     is available.  Nothing is free.  There really isn't
  15.     640 columns, but it still looks better than 320x200.
  16.  
  17.     This driver is designed to be assembled with A86.
  18.  
  19.  
  20.         %
  21.  
  22. VERSION        EQU    1        ;VERSION NUMBER
  23. SUBVERSION    EQU    1        ;SUBVERSION NUMBER
  24.  
  25. _AOFF        EQU    6        ;STACK OFFSET
  26.  
  27. ; these are the maximum possible screen sizes
  28. TLI_WIDE        EQU     640    ;maximum screen width in pixels
  29. TLI_DEEP        EQU     480     ;maximum screen depth in lines
  30. TLI_SCREENSEG   EQU     0A000H  ;segment of tseng card video buffer
  31. TLI_BYTES       EQU     128     ;maximum width of planar modes in bytes
  32.  
  33. ;THIS MACRO SELECTS AN EGA PLANE
  34. EGAPLANE        MACRO
  35.         MOV    AL,2
  36.         MOV    DX,03C4H
  37.         OUT    DX,AL
  38.         INC    DX
  39.         MOV     AL,#1
  40.         OUT    DX,AL
  41.         #EM
  42.  
  43.         ORG     0000H           ;ORIGIN FOR LOADABLE DRIVER
  44.  
  45.         DB    'ALCHDRV2'    ;SIGNATURE - DON'T CHANGE THIS
  46.  
  47. ;THE FOLLOWING ARE THE POINTERS TO THE CALLABLE ROUTINES AND THE COMMON
  48. ;DATA. THE SEGMENTS ARE FILLED IN BY GRAPHIC WORKSHOP. DON'T CHANGE ANYTHING.
  49. DISPATCH:
  50.         DW      VGA_on          ;FAR POINTER TO VGA MODE SELECT
  51.         DW      ?
  52. line_address    DW      VGA_line        ;FAR POINTER TO VGA LINE DISPLAY
  53.         DW    ?
  54.         DW      VGA_off         ;FAR POINTER TO VGA MODE DESELECT
  55.         DW    ?
  56.         DW    VGA_PALETTE    ;FAR POINTER TO VGA PALETTE SET
  57.         DW    ?
  58.         DW    VGA_OVERSCAN    ;FAR POINTER TO VGA OVERSCAN SET
  59.         DW    ?
  60.         DW      EGA_on          ;FAR POINTER TO EGA MODE SELECT
  61.         DW      ?
  62.         DW    EGA_LINE    ;FAR POINTER TO EGA LINE DISPLAY
  63.         DW    ?
  64.         DW      EGA_off         ;FAR POINTER TO EGA MODE DESELECT
  65.         DW    ?
  66.         DW    EGA_PALETTE    ;FAR POINTER TO EGA PALETTE SET
  67.         DW    ?
  68.         DW      MONO_on         ;FAR POINTER TO MONO MODE SELECT
  69.         DW      ?
  70.         DW    MONO_FRAME    ;FAR POINTER TO MONO PAGE DISPLAY
  71.         DW    ?
  72.         DW    MONO_LINE    ;FAR POINTER TO MONO LINE DISPLAY
  73.         DW    ?
  74.         DW      MONO_off        ;FAR POINTER TO MONO MODE DESELECT
  75.         DW    ?
  76.         DW    0,0        ;NULL ONE
  77.         DW    0,0        ;NULL TWO
  78.         DW    0,0        ;NULL THREE
  79.         DW    0,0        ;NULL FOUR
  80.  
  81. V_VGAWIDE       DW      TLI_WIDE        ;VGA SCREEN WIDTH
  82. V_VGADEEP       DW      TLI_DEEP        ;VGA SCREEN DEPTH
  83. V_VGASCRNSEG    DW      TLI_SCREENSEG   ;VGA SCREEN SEGMENT
  84. V_EGAWIDE       DW      TLI_WIDE        ;EGA SCREEN WIDTH
  85. V_EGADEEP       DW      TLI_DEEP        ;EGA SCREEN DEPTH
  86. V_EGABYTES      DW      TLI_BYTES       ;EGA SCREEN BYTES
  87. V_EGASCRNSEG    DW      TLI_SCREENSEG   ;EGA SCREEN SEGMENT
  88. V_MONOWIDE      DW      TLI_WIDE       ;MONO SCREEN WIDTH
  89. V_MONODEEP      DW      TLI_DEEP       ;MONO SCREEN DEPTH
  90. V_MONOBYTES     DW      TLI_BYTES      ;BYTE WIDTH ON MONOCHROME SCREEN
  91. V_MONOSCRNSEG   DW      TLI_SCREENSEG  ;MONOCHROME SCREEN SEGMENT
  92.  
  93. ;THESE VERSION NUMBERS REFLECT THE DRIVER TEMPLATE VERSION AND THE
  94. ;VERSION OF THE DRIVER ITSELF. YOU CAN CHANGE THE SUBVERSION VALUE
  95. ;TO REFLECT CHANGES IN YOUR DRIVER. THE VERSION VALUE MUST REMAIN
  96. ;UNCHANGED OR GRAPHIC WORKSHOP MAY REJECT YOUR DRIVER.
  97.         DW    VERSION
  98.         DW    SUBVERSION
  99.  
  100. ;THE DESCRIPTION APPEARS IN THE F10 "ABOUT" BOX IN GRAPHIC
  101. ;WORKSHOP WHEN AN EXTERNAL DRIVER IS BEING USED. IT CAN'T
  102. ;EXCEED 24 CHARACTERS AND MUST BE NULL TERMINATED
  103.    DB      'VGA in pseudo 640x480',0
  104.  
  105. Installed dw 00000h  ; moniter,memory - descriptions at end of file
  106.  
  107. ;THIS ROUTINE SELECTS THE VGA 256 COLOUR MODE
  108. ;THE HEIGHT AND WIDTH OF THE IMAGE ARE ON THE STACK - THESE
  109. ;MAY BE USEFUL IF YOU WANT TO PICK ONE OF SEVERAL AVAILABLE
  110. ;MODES BASED ON THE AREA OF THE PICTURE TO BE DISPLAYED
  111. VGA_on:
  112.    push bp
  113.    mov bp,sp
  114.    push ds
  115.    mov ds,cs
  116.  
  117.    mov ax,[bp+_AOFF]   ; cols
  118.    mov bx,[bp+_AOFF+2] ; rows
  119.    mov si,VGA_mode
  120.    call pick_mode
  121.    mov V_VGAWIDE,ax
  122.    mov V_VGADEEP,bx
  123.  
  124.    cmp cx,13h
  125.    je >l5
  126.    mov ax,Strange_line
  127.    mov line_address,ax
  128.    call Set_320x480Mode
  129.  
  130.    mov ax,V_VGAWIDE
  131.    shr ax,1  ; width/4
  132.    shr ax,1
  133.    shr ax,1  ; every other column
  134.    mov cx,V_VGADEEP     ;depth of screen in the current mode
  135.    sub dx,dx
  136.    mov si,SCREENTABLE
  137.    mov [si],dx
  138.    add si,2
  139.    dec cx
  140. l2:
  141.    add dx,ax
  142.    mov [si],dx
  143.    add si,2
  144.    loop l2
  145.  
  146.    jmp >l9
  147. l5:
  148.    mov ax,cx
  149.    int 10h
  150.    mov ax,VGA_line
  151.    mov line_address,ax
  152.  
  153.    mov cx,V_VGADEEP     ;depth of screen in the current mode
  154.    sub dx,dx
  155.    mov si,SCREENTABLE
  156.    mov [si],dx
  157.    add si,2
  158.    dec cx
  159. l2:
  160.    add dx,V_VGAWIDE
  161.    mov [si],dx
  162.    add si,2
  163.    loop l2
  164. l9:
  165.    pop ds,bp
  166.    retf
  167.  
  168. Strange_line:
  169.    push bp
  170.    mov bp,sp
  171.    push ds
  172.    push es
  173.  
  174.    mov si,[bp + _AOFF + 0]     ;OFFSET OF SOURCE
  175.    mov ds,[bp + _AOFF + 2]     ;SEGMENT OF SOURCE
  176.  
  177.    mov bx,[bp + _AOFF + 6]     ;GET LINE NUMBER
  178.    cmp bx,cs:V_VGADEEP
  179.    if ge jmp Strange_line_exit
  180.  
  181.    shl bx,1
  182.    mov di,cs:[screentable + bx]
  183.    cld
  184.    mov cx,[bp + _AOFF + 4]
  185.    cmp cx,0
  186.    je Strange_line_exit
  187.    cmp cx,cs:V_VGAWIDE
  188.    jl >l1
  189.    mov cx,cs:V_VGAWIDE
  190. l1:
  191.    mov ax,cs:V_VGASCRNSEG
  192.    mov es,ax
  193.  
  194.    shr cx,1
  195.    shr cx,1
  196.    shr cx,1
  197.    EGAPLANE 1
  198.    push si,di,cx
  199. l3:
  200.    movsb
  201.    add si,7
  202.    loop l3
  203.  
  204.    EGAPLANE 2
  205.    pop cx,di,si
  206.    add si,2
  207.    push si,di,cx
  208. l3:
  209.    movsb
  210.    add si,7
  211.    loop l3
  212.  
  213.    EGAPLANE 4
  214.    pop cx,di,si
  215.    add si,2
  216.    push si,di,cx
  217. l3:
  218.    movsb
  219.    add si,7
  220.    loop l3
  221.  
  222.    EGAPLANE 8
  223.    pop cx,di,si
  224.    add si,2
  225. l3:
  226.    movsb
  227.    add si,7
  228.    loop l3
  229.    EGAPLANE 0FH
  230.  
  231. Strange_line_exit:
  232.    pop es,ds,bp
  233.    retf
  234.  
  235. ;THIS ROUTINE DISPLAYS A VGA LINE
  236. ;THE FIRST ARGUMENT ON THE STACK (2 WORDS) IS A FAR POINTER TO
  237. ;THE LINE. THE SECOND ARGUMENT IS THE LENGTH OF THE LINE IN PIXELS
  238. VGA_line:
  239.    push bp
  240.    mov bp,sp
  241.    push ds
  242.    push es
  243.  
  244.    mov si,[bp + _AOFF + 0]     ;OFFSET OF SOURCE
  245.    mov ds,[bp + _AOFF + 2]     ;SEGMENT OF SOURCE
  246.  
  247.    mov bx,[bp + _AOFF + 6]     ;GET LINE NUMBER
  248.    cmp bx,cs:V_VGADEEP
  249.    jge VGA_line_exit
  250.  
  251.    shl bx,1
  252.    mov di,cs:[screentable + bx]
  253.    cld
  254.    mov cx,[bp + _AOFF + 4]
  255.    cmp cx,0
  256.    je VGA_line_exit
  257.    cmp cx,cs:V_VGAWIDE
  258.    jl >l1
  259.    mov cx,cs:V_VGAWIDE
  260. l1:
  261.    mov ax,cs:V_VGASCRNSEG
  262.    mov es,ax
  263.    rep movsb
  264.  
  265. VGA_line_exit:
  266.    pop es,ds,bp
  267.    retf
  268.  
  269. ;THIS ROUTINE SETS THE VGA PALETTE
  270. ;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO
  271. ;THE PALETTE DATA. THE SECOND ARGUMENT IS THE NUMBER OF COLOURS.
  272. VGA_PALETTE:
  273.    call cs:[check_gray]
  274.         PUSH    BP
  275.         MOV    BP,SP
  276.         PUSH    DS
  277.  
  278.         MOV    SI,[BP + _AOFF + 0]    ;OFFSET OF SOURCE
  279.         MOV    DS,[BP + _AOFF + 2]    ;SEGMENT OF SOURCE
  280.  
  281.         MOV    CX,[BP + _AOFF + 4]    ;NUMBER OF COLOURS
  282.  
  283.                 CMP    CX,0            ;CHECK FOR NASTIES
  284.         JG    GVP0
  285.         JMP    GVPX
  286.  
  287.         ;WE'LL SET THE PALLETTE USING DIRECT REGISTERS RATHER
  288.         ;THAN A BIOS CALL AS IT LOOKS NICER, however if
  289.         ;gray scale summing is active, we'll use the BIOS
  290.  
  291. GVP0:
  292.    cmp cs:b gray_VGA,0
  293.    je >l2
  294.    push si,cx
  295.    mov es,ds
  296.    mov di,si
  297. l1:
  298.    lodsb
  299.    shr al,1
  300.    shr al,1
  301.    stosb
  302.    lodsb
  303.    shr al,1
  304.    shr al,1
  305.    stosb
  306.    lodsb
  307.    shr al,1
  308.    shr al,1
  309.    stosb
  310.    loop l1
  311.    pop cx,si
  312.    mov dx,si
  313.    mov bx,0
  314.    mov ax,1012h
  315.    int 10h
  316.    jmp GVPX
  317. l2:
  318.         MOV     DX,03C6H
  319.         MOV    AL,0FFH
  320.         OUT    DX,AL
  321.  
  322.         MOV    BX,0
  323.  
  324. GVP1:        PUSH    CX
  325.         MOV    DX,03C8H
  326.         MOV    AL,BL
  327.         INC    BX
  328.         OUT    DX,AL
  329.  
  330.         INC    DX
  331.  
  332.         LODSB
  333.         SHR    AL,1
  334.         SHR    AL,1
  335.         OUT    DX,AL
  336.  
  337.         LODSB
  338.         SHR    AL,1
  339.         SHR    AL,1
  340.         OUT    DX,AL
  341.  
  342.         LODSB
  343.         SHR    AL,1
  344.         SHR    AL,1
  345.         OUT    DX,AL
  346.  
  347.         POP    CX
  348.         LOOP    GVP1
  349.  
  350.  
  351. GVPX:
  352.         POP    DS
  353.         POP    BP
  354.         RETF
  355. check_gray dw do_check_gray
  356. gray_VGA db 0
  357.  
  358. ; test for gray scale summing
  359. do_check_gray:
  360.    push ax,bx,cx,dx,es,ds,di
  361.    mov ax,1b00h
  362.    mov es,cs
  363.    mov di,gray_test_area
  364.    mov bx,0
  365.    int 10h
  366.    mov al,es:[gray_test_area+2dh]
  367.    and al,00000010xb
  368.    mov cs:gray_VGA,al
  369.    mov ax,gray_ret
  370.    mov cs:check_gray,ax
  371.    pop di,ds,es,dx,cx,bx,ax
  372. gray_ret:
  373.    ret
  374.  
  375.  
  376.  
  377.  
  378. ;THIS ROUTINE SETS THE VGA OVERSCAN.
  379. ;THE FIRST STACK ARGUMENT IS THE COLOUR NUMBER.
  380. VGA_OVERSCAN:
  381.         PUSH    BP
  382.         MOV    BP,SP
  383.         MOV    AX,1001H
  384.         MOV    BX,[BP + _AOFF + 0]
  385.         XCHG    BH,BL
  386.         INT    10H
  387.         POP    BP
  388.         RETF
  389.  
  390. ;THIS ROUTINE SELECTS THE EGA 16 COLOUR MODE
  391. ;THE HEIGHT AND WIDTH OF THE IMAGE ARE ON THE STACK - THESE
  392. ;MAY BE USEFUL IF YOU WANT TO PICK ONE OF SEVERAL AVAILABLE
  393. ;MODES BASED ON THE AREA OF THE PICTURE TO BE DISPLAYED
  394. EGA_on:
  395.    push bp
  396.    mov bp,sp
  397.    push ds
  398.    mov ds,cs
  399.  
  400.    mov ax,[bp+_AOFF]   ; cols
  401.    mov bx,[bp+_AOFF+2] ; rows
  402.    mov si,EGA_mode
  403.    call pick_mode
  404.    mov V_EGAWIDE,ax
  405.    mov V_EGADEEP,bx
  406.  
  407.    add ax,7
  408.    shr ax,1
  409.    shr ax,1
  410.    shr ax,1
  411.    mov V_EGABYTES,AX
  412.  
  413.    mov ax,cx
  414.    int 10h
  415.  
  416.    mov cx,V_EGADEEP     ;depth of screen in the current mode
  417.    sub dx,dx
  418.    mov bx,dx
  419.    mov si,SCREENTABLE
  420.    mov [si],dx
  421.    add si,2
  422.    dec cx
  423. l2:
  424.    add dx,V_EGABYTES
  425. l1:
  426.    mov [si],dx
  427.    add si,2
  428.    loop l2
  429.  
  430.    pop ds,bp
  431.    retf
  432.  
  433.  
  434. ;THIS ROUTINE DISPLAYS AN EGA LINE
  435. ;THE FIRST ARGUMENT ON THE STACK (2 WORDS) IS A FAR POINTER TO
  436. ;THE LINE. THE SECOND ARGUMENT IS THE LENGTH OF THE LINE IN BYTES
  437. EGA_LINE:
  438.         PUSH    BP
  439.         MOV    BP,SP
  440.         PUSH    DS
  441.         PUSH    ES
  442.  
  443.         MOV    SI,[BP + _AOFF + 0]    ;OFFSET OF SOURCE
  444.         MOV    DS,[BP + _AOFF + 2]    ;SEGMENT OF SOURCE
  445.         MOV     BX,[BP + _AOFF + 6]    ;GET LINE NUMBER
  446.         CMP     BX,cs:V_EGADEEP
  447.    if GE jmp long  SHOWEGAX
  448.  
  449.  
  450.         SHL    BX,1
  451.         MOV    DI,CS:[SCREENTABLE+BX]
  452.  
  453.         MOV    AX,0A000H
  454.         MOV    ES,AX
  455.         MOV     BX,[BP + _AOFF + 4]     ;LENGTH OF MOVE IN BYTES
  456.  
  457.         MOV     CX,BX       ; this part does an even # of bytes
  458.         EGAPLANE    1
  459.         CLD
  460.         PUSH    DI
  461.    rep movsb
  462.         POP    DI
  463.  
  464.         MOV    CX,BX
  465.         EGAPLANE    2
  466.         PUSH    DI
  467.    rep movsb
  468.         POP    DI
  469.  
  470.         MOV    CX,BX
  471.         EGAPLANE    4
  472.         PUSH    DI
  473.    rep movsb
  474.         POP    DI
  475.  
  476.         MOV    CX,BX
  477.         EGAPLANE    8
  478.         PUSH    DI
  479.    rep movsb
  480.         POP    DI
  481.         EGAPLANE        0FH
  482.  
  483. SHOWEGAX:    POP    ES
  484.         POP    DS
  485.         POP    BP
  486.         RETF
  487.  
  488. ;THIS ROUTINE SETS THE EGA PALETTE
  489. ;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO
  490. ;THE PALETTE DATA. THE SECOND ARGUMENT IS THE NUMBER OF COLOURS.
  491. EGA_PALETTE:
  492.         PUSH    BP
  493.         MOV    BP,SP
  494.         PUSH    DS
  495.  
  496.         MOV    SI,[BP + _AOFF + 0]    ;OFFSET OF SOURCE
  497.         MOV    DS,[BP + _AOFF + 2]    ;SEGMENT OF SOURCE
  498.  
  499.         MOV    CX,[BP + _AOFF + 4]    ;NUMBER OF COLOURS
  500.         SUB    BX,BX
  501.                 CMP    CX,16
  502.         JLE    EGA_PALETTE1
  503.         MOV    CX,16
  504.  
  505. EGA_PALETTE1:    MOV    BH,[SI]
  506.         MOV    AX,1000H
  507.         INT    10H
  508.         INC    BL
  509.         INC    SI
  510.         LOOP    EGA_PALETTE1
  511.  
  512.         POP    DS
  513.         POP    BP
  514.         RETF
  515.  
  516.  
  517. ;THIS ROUTINE SELECTS THE 2 COLOUR MODE
  518. ;THE HEIGHT AND WIDTH OF THE IMAGE ARE ON THE STACK - THESE
  519. ;MAY BE USEFUL IF YOU WANT TO PICK ONE OF SEVERAL AVAILABLE
  520. ;MODES BASED ON THE AREA OF THE PICTURE TO BE DISPLAYED
  521. MONO_on:
  522.    push bp
  523.    mov bp,sp
  524.    push ds
  525.    mov ds,cs
  526.  
  527.    mov ax,[bp+_AOFF]   ; cols
  528.    mov bx,[bp+_AOFF+2] ; rows
  529.    mov si,MONO_mode
  530.    call pick_mode
  531.    mov V_MONOWIDE,ax
  532.    mov V_MONODEEP,bx
  533.  
  534.    add ax,7
  535.    shr ax,1
  536.    shr ax,1
  537.    shr ax,1
  538.    mov V_MONOBYTES,AX
  539.  
  540.    mov ax,cx
  541.    int 10h
  542.  
  543.    mov cx,V_MONODEEP     ;depth of screen in the current mode
  544.    sub dx,dx
  545.    mov bx,dx
  546.    mov si,SCREENTABLE
  547.    mov [si],dx
  548.    add si,2
  549.    dec cx
  550. l2:
  551.    add dx,V_MONOBYTES
  552.    mov [si],dx
  553.    add si,2
  554.    loop l2
  555.  
  556.    pop ds,bp
  557.    retf
  558.  
  559.  
  560.  
  561. UPDATE_MOVE    EQU    2
  562. UPDATE_PAD    EQU    4
  563. UPDATE_ADJUST    EQU    6
  564.  
  565. ;THIS ROUTINE DISPLAYS A FULL MONOCHROME PAGE
  566. ;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO THE PAGE
  567. ;THE SECOND ARGUMENT IS THE WIDTH OF THE BITMAP (IN BYTES)
  568. ;THE THIRD ARGUMENT IS THE NUMBER OF LINES TO DISPLAY
  569. ;NOTE: THE SOURCE BUFFER MAY BE BIGGER THAN 64K.
  570. MONO_FRAME:
  571.         PUSH    BP
  572.         MOV    BP,SP
  573.         SUB    SP,UPDATE_ADJUST
  574.         PUSH    DS
  575.         PUSH    ES
  576.  
  577.         MOV     AX,cs:V_MONOSCRNSEG       ;POINT TO THE SCREEN
  578.         MOV    ES,AX
  579.         MOV    AX,[BP + _AOFF + 4]        ;GET THE WIDTH OF MOVE
  580.         MOV    [BP - UPDATE_MOVE],AX    ;SAVE IT LOCALLY
  581.         MOV    WORD PTR [BP - UPDATE_PAD],0    ;SET ADJUSTMENT
  582.  
  583.         CMP     AX,cs:V_MONOBYTES           ;IF THE MOVE IS LESS THAN
  584.         JL    UPDATE0            ;SCREEN WIDTH, GO FOR IT
  585.  
  586.         SUB     AX,cs:V_MONOBYTES           ;ELSE, SET MOVE WIDTH
  587.         MOV    [BP - UPDATE_PAD],AX    ;...AND THE AMOUNT TO
  588.  
  589.         MOV     AX,cs:V_MONOBYTES           ;...ADJUST THE POINTER
  590.         MOV    [BP - UPDATE_MOVE],AX    ;...AFTER EACH LINE
  591.  
  592. UPDATE0:    MOV    SI,[BP + _AOFF + 0]    ;OFFSET OF BITMAP
  593.         MOV    DS,[BP + _AOFF + 2]    ;SEGMENT OF BITMAP
  594.         MOV    CX,[BP + _AOFF + 6]    ;NUMBER OF LINES
  595.  
  596.         CLD                ;CLEAR DIRECTION FLAG
  597.         SUB    BX,BX
  598.  
  599. UPDATE1:        PUSH    CX                      ;SAVE COUNT (LINE NUMBER)
  600.  
  601.  
  602.         MOV    DI,CS:[SCREENTABLE + BX]
  603.         ADD    BX,2            ;POINT TO NEXT LINE
  604.  
  605.         MOV     CX,[BP - UPDATE_MOVE]   ;GET THE MOVE SIZE
  606.  
  607.    rep movsb
  608.  
  609.         ADD    SI,[BP - UPDATE_PAD]    ;ADJUST THE POINTER
  610.  
  611.         CMP    SI,0F800H        ;ARE WE WITHIN 2K OF TOP?
  612.         JL      UPDATE2            ;IF NOT, CARRY ON
  613.  
  614.         MOV    AX,SI            ;SEE HOW MANY SEGMENTS ARE
  615.         MOV    CL,4            ;...IN SI (SI DIV 4)
  616.         SHR    AX,CL
  617.  
  618.         MOV    CX,DS            ;ADD THEM TO THE DATA SEGMENT
  619.         ADD    CX,AX            ;...(YOU CAN'T JUST ADD DS,AX)
  620.         MOV    DS,CX
  621.         AND    SI,000FH        ;ADJUST SI (SI MOD 16)
  622.  
  623. UPDATE2:    POP    CX            ;GET COUNT BACK
  624.         LOOP    UPDATE1                    ;DECREMENT AND LOOP
  625.  
  626.         POP    ES
  627.         POP    DS
  628.  
  629.         ADD    SP,UPDATE_ADJUST
  630.         POP    BP
  631.  
  632.         RETF
  633.  
  634. ;THIS ROUTINE DISPLAYS A SINGLE MONOCHROME LINE
  635. ;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO THE LINE
  636. ;THE SECOND ARGUMENT IS THE LINE NUMBER
  637. ;THE THIRD ARGUMENT IS THE WIDTH OF THE BITMAP (IN BYTES)
  638. MONO_LINE:
  639.         PUSH    BP
  640.         MOV    BP,SP
  641.  
  642.         PUSH    DS
  643.         PUSH    ES
  644.  
  645.         MOV     AX,cs:V_MONOSCRNSEG       ;POINT TO THE SCREEN
  646.         MOV    ES,AX
  647.  
  648.         MOV    CX,[BP + _AOFF + 6]        ;GET THE WIDTH OF MOVE
  649.         CMP    CX,0
  650.         JE    MONO_LINE2
  651.         CMP     CX,cs:V_MONOBYTES
  652.         JL    MONO_LINE1
  653.         MOV     CX,cs:V_MONOBYTES
  654.  
  655. MONO_LINE1:    MOV    SI,[BP + _AOFF + 0]    ;OFFSET OF BITMAP
  656.         MOV    DS,[BP + _AOFF + 2]    ;SEGMENT OF BITMAP
  657.         MOV     BX,[BP + _AOFF + 4]     ;NUMBER OF LINE
  658.  
  659.  
  660.         SHL    BX,1
  661.  
  662.         CLD                ;CLEAR DIRECTION FLAG
  663.         MOV     DI,CS:[SCREENTABLE + BX]
  664.  
  665.    rep movsb
  666.  
  667. MONO_LINE2:    POP    ES
  668.         POP    DS
  669.  
  670.         POP    BP
  671.         RETF
  672.  
  673.  
  674. ; This routine selects text mode after all the graphics  modes
  675. ; are finished.
  676. VGA_off:
  677. EGA_off:
  678. MONO_off:
  679.    mov ax,0003h
  680.    int 10h
  681.    retf
  682.  
  683. ;
  684. ;
  685. ;this part goes through all available modes to try to find one that is
  686. ; larger than the picture or the same size as the picture.
  687. pick_mode:
  688. l3:
  689.    cmp ax,[si]
  690.    ja >l1
  691.    cmp bx,[si+2]
  692.    jbe >l2
  693. l1:
  694.    add si,10
  695.    cmp w[si],0
  696.    jne l3
  697.    sub si,10
  698. l2:
  699. ; this part goes backwards through the list of modes to make sure the card
  700. ; and monitor can handle the mode.
  701.    mov cx,Installed
  702.    sub dx,dx
  703.    mov dl,ch  ; cx is memory available
  704.    mov ch,dh  ; dx is the monitor
  705. l2:
  706.    cmp cx,[si+4]
  707.    jl >l1
  708.    cmp dx,3
  709.    je >l4  ; any mode monitor
  710.    cmp dx,[si+6]
  711.    je >l4  ; monitor and required are the same
  712.    cmp w[si+6],0
  713.    je >l4  ; VGA monitor is all that's needed
  714. l1:
  715.    sub si,10
  716.    jmp l2
  717. l4:
  718.    mov ax,[si]
  719.    mov bx,[si+2]
  720.    mov cx,[si+8]
  721.    ret
  722. ;
  723. ;
  724. Set_320x480Mode:
  725.    push ds
  726.    mov ds,cs
  727.    mov ax,12h
  728.    int 10h    ;let BIOS clear memory and set vertical registers
  729.    call save_sync
  730.  
  731.    MOV     AX,13h
  732.    INT     10h
  733.    call load_sync
  734.  
  735. ;disable chain 4
  736.    MOV     DX,03C4h
  737.    MOV     AL,4
  738.    OUT     DX,AL
  739.    MOV     DX,03C5h
  740.    MOV     AL,6
  741.    OUT     DX,AL
  742. ;unprotect crtc registers
  743.    MOV     DX,03D4h
  744.    MOV     AL,11h
  745.    OUT     DX,AL
  746.    MOV     DX,03D5h
  747.    IN      AL,DX
  748.    AND     AL,7
  749.    PUSH    AX
  750.    MOV     DX,03D4h
  751.    MOV     AL,11h
  752.    OUT     DX,AL
  753.    POP     AX
  754.    MOV     DX,03D5h
  755.    OUT     DX,AL
  756. ;load crtc registers
  757.    MOV     DX,03D4h
  758.    MOV     AL,6
  759.    OUT     DX,AL
  760.    MOV     DX,03D5h
  761.    MOV     AL,0DH
  762.    OUT     DX,AL
  763.    MOV     DX,03D4h
  764.    MOV     AL,7
  765.    OUT     DX,AL
  766.    MOV     DX,03D5h
  767.    MOV     AL,3Eh
  768.    OUT     DX,AL
  769.    MOV     DX,03D4h
  770.    MOV     AL,9
  771.    OUT     DX,AL
  772.    MOV     DX,03D5h
  773.    MOV     AL,40h
  774.    OUT     DX,AL
  775.    MOV     DX,03D4h
  776.    MOV     AL,10h
  777.    OUT     DX,AL
  778.    MOV     DX,03D5h
  779.    MOV     AL,0EAh
  780.    OUT     DX,AL
  781.    MOV     DX,03D4h
  782.    MOV     AL,12h
  783.    OUT     DX,AL
  784.    MOV     DX,03D5h
  785.    MOV     AL,0DFh
  786.    OUT     DX,AL
  787.    MOV     DX,03D4h
  788.    MOV     AL,14h
  789.    OUT     DX,AL
  790.    MOV     DX,03D5h
  791.    MOV     AL,0
  792.    OUT     DX,AL
  793.    MOV     DX,03D4h
  794.    MOV     AL,15h
  795.    OUT     DX,AL
  796.    MOV     DX,03D5h
  797.    MOV     AL,0E7h
  798.    OUT     DX,AL
  799.    MOV     DX,03D4h
  800.    MOV     AL,16h
  801.    OUT     DX,AL
  802.    MOV     DX,03D5h
  803.    MOV     AL,6
  804.    OUT     DX,AL
  805.    MOV     DX,03D4h
  806.    MOV     AL,17h
  807.    OUT     DX,AL
  808.    MOV     DX,03D5h
  809.    MOV     AL,0E3h
  810.    OUT     DX,AL
  811.    MOV     DX,03D4h
  812.    MOV     AL,11h
  813.    OUT     DX,AL
  814.    MOV     DX,03D5h
  815.    MOV     AL,0ACh
  816.    OUT     DX,AL
  817.    pop ds
  818.    RET
  819. ;
  820. save_sync:
  821.    mov dx,3cch
  822.    in al,dx
  823.    mov sync_save_byte,al
  824. ;
  825. load_sync:
  826.    mov ah,sync_save_byte
  827.    and al,0c0h
  828.    mov dx,03cch
  829.    in al,dx
  830.    jmp $+2
  831.    and al,00111111xb
  832.    or al,ah
  833.    mov dx,03c2h
  834.    out dx,al
  835.    ret
  836. ;
  837. sync_save_byte db 0
  838.  
  839.    even
  840.  
  841. ;THIS IS A LINE START LOOKUP TABLE
  842. gray_test_area: db 40h dup(?)
  843. SCREENTABLE:     DW      TLI_DEEP DUP(?)        ;LINE START TABLE
  844.  
  845. ;These are the modes supported.  the tables have the format:
  846. ;   columns,rows,memory,monitor,mode
  847. ; where memory is   0   256k
  848. ;                   1   512k
  849. ;                   2   1024k
  850. ;
  851. ; and monitor is  0  standard VGA
  852. ;                 1  800x600 capable Multisync
  853. ;                 2  1024x768 interlace capable 8514 equivalent
  854. ;                 3  1024x768 interlace capable multisync
  855. ;
  856. VGA_mode:
  857.    dw  320,200,0,0,13h
  858.    dw  640,480,0,0,2eh
  859.    dw  0
  860.  
  861. EGA_mode:
  862.    dw  320,200,0,0,0dh
  863.    dw  640,350,0,0,10h
  864.    dw  640,480,0,0,12h
  865.    dw  0
  866.  
  867. MONO_mode:
  868.    dw  640,350,0,0,10h
  869.    dw  640,480,0,0,11h
  870.    dw  0
  871.