home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / EGA_VGA / XGADEMO.ZIP / XGAMODES.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-01-26  |  31.8 KB  |  1,181 lines

  1. ;
  2. ;    XGA adapter support routines, version 0.5
  3. ;        by Bert Tyler of Tyler Software
  4. ;        CIS ID:  73477,433
  5. ;    Copyright 1990 Tyler Software
  6. ;    (except, of course, for those parts copied right out of IBM's
  7. ;    "Preliminary XGA Video Subsystem Hardware Users Guide")
  8. ;    Free for use in commercial, shareware or freeware applications
  9. ;
  10. ;    Routines in this module:
  11. ;
  12. ;    int xga_detect()
  13. ;        returns    0 if no XGA adapter found
  14. ;            non-zero if XGA adapter found
  15. ;        bits:    0 - XGA adapter found
  16. ;            1 - XGA monitor is color, not mono
  17. ;            2 - XGA monitor is high-rez - capable of 1024x768
  18. ;            3 - XGA adapter has 1MB of RAM
  19. ;            4 - XGA adapter is in a dual-monitor setup
  20. ;        (IE, return code of 7 means XGA adapter with 512K of RAM
  21. ;        connected to a high-rez color monitor in a single-
  22. ;        monitor setup)
  23. ;
  24. ;    int xga_mode(int mode)
  25. ;        mode =    0 to enter normal VGA text mode (BIOS mode 3)
  26. ;            1 to enter 132-col VGA text mode
  27. ;            2 to enter 1024x768x256 graphics mode
  28. ;            3 to enter 1024x768x16 graphics mode
  29. ;            4 to enter 640x480x256 graphics mode
  30. ;            5 to enter 640x480x65536 graphics mode
  31. ;        returns    0 on failure
  32. ;            1 on success
  33. ;        (NOTE!  You *must* use 'xga_mode(0)' to exit any of the
  34. ;        other modes and get back to standard VGA operation, even
  35. ;        on a dual-monitor (XGA & VGA) setup!  On a dual-monitor
  36. ;        setup, 'xga_mode(0)' leaves the XGA image intact, but
  37. ;        disables the XGA adapter's 64K aperture at A000:0000)
  38. ;
  39. ;    void xga_putpixel(int row, int col, int color)
  40. ;        writes pixel (row, col) using color
  41. ;        (all pixel counts start at 0, and [0][0] is in the UL corner)
  42. ;
  43. ;    int xga_getpixel(int row, int col)
  44. ;        returns    color of pixel at (row, col)
  45. ;        (all pixel counts start at 0, and [0][0] is in the UL corner)
  46. ;
  47. ;    void xga_putline(int row, int firstcol, int lastcol, char *pixels)
  48. ;        sends the line segment directly to the video
  49. ;        (all pixel counts start at 0, and [0][0] is in the UL corner)
  50. ;        (IE, xga_putline(3,7,12,*pixels) sends pixel[0] thru pixel[5]
  51. ;        to the 8th thru 13th pixel in the fourth row)
  52. ;
  53. ;    void xga_getline(int row, int firstcol, int lastcol, char *pixels)
  54. ;        reads the line segment directly from the video
  55. ;        (all pixel counts start at 0, and [0][0] is in the UL corner)
  56. ;        (IE, xga_putline(3,7,12,*pixels) fills pixel[0] thru pixel[5]
  57. ;        from the 8th thru 13th pixel in the fourth row)
  58. ;
  59. ;    void xga_setpalette(char *palette)
  60. ;        where 'palette' points to a 768-byte array of RGB values
  61. ;            (values from 0-255, not the VGA's internal 0-63!)
  62. ;
  63.  
  64.     .MODEL    medium,c
  65.  
  66.  
  67.     .DATA
  68.  
  69. public        xga_isinmode        ; (only public for Fractint purposes)
  70. public        xga_clearvideo        ; (only public for Fractint purposes)
  71.  
  72. xga_pos_base    dw    0        ; MCA Pos Base value
  73. xga_cardid    dw    0        ; MCA Card ID value
  74. xga_reg_base    dw    -1        ; XGA IO Reg Base (-1 means dunno yet)
  75. xga_1mb        dd    0        ; XGA 1MB aperture address
  76. xga_4mb        dd    0        ; XGA 4MB aperture address
  77. xga_result    dw    0        ; XGA_detect result code
  78. xga_isinmode    dw    0        ; XGA is in this mode right now
  79. xga_clearvideo    db    0        ; set to 80h to prevent video-clearing
  80.  
  81. xga_dotwrite    dw    0        ; write-a-dot routine:    mode-specific
  82. xga_dotread     dw    0        ; read-a-dot routine:    mode-specific
  83. xga_linewrite    dw    0        ; write-a-line routine: mode-specific
  84. xga_lineread    dw    0        ; read-a-line routine: mode-specific
  85. xga_curbk    dw    0        ; bank number
  86. xga_xdots    dw    0        ; pixels per scan line
  87. xga_linelen    dw    0        ; line segment length
  88. xga_offset    dw    0        ; line segment offset
  89.  
  90.     .CODE
  91.  
  92. ;        Graphics mode setup values
  93. ;        1024x768x256 v
  94. ;        1024x768x16  ------v
  95. ;        640x480x256  ------------v
  96. ;        640x480x65536 -----------------v
  97. ;
  98. xga_val    db    004h, 000h, 000h, 000h, 000h, 000h    ; interrupt enable
  99.     db    005h, 000h, 0ffh, 0ffh, 0ffh, 0ffh    ; interrupt status
  100.     db    000h, 000h, 004h, 004h, 004h, 004h    ; operating mode
  101.     db    00ah, 064h, 000h, 000h, 000h, 000h    ; palette mask
  102.     db    001h, 000h, 001h, 001h, 001h, 001h    ; vid mem aper cntl
  103.     db    008h, 000h, 000h, 000h, 000h, 000h    ; vid mem aper indx
  104.     db    006h, 000h, 000h, 000h, 000h, 000h    ; virt mem ctl
  105.     db    009h, 000h, 003h, 002h, 003h, 004h    ; mem access mode
  106.     db    00ah, 050h, 001h, 001h, 001h, 001h    ; disp mode 1
  107.     db    00ah, 050h, 000h, 000h, 000h, 000h    ; disp mode 1
  108.     db    00ah, 010h, 09dh, 09dh, 063h, 063h    ; horiz tot lo.
  109.     db    00ah, 011h, 000h, 000h, 000h, 000h    ; horiz tot hi.
  110.     db    00ah, 012h, 07fh, 07fh, 04fh, 04fh    ; hor disp end lo
  111.     db    00ah, 013h, 000h, 000h, 000h, 000h    ; hor disp end hi
  112.     db    00ah, 014h, 07fh, 07fh, 04fh, 04fh    ; hor blank start lo
  113.     db    00ah, 015h, 000h, 000h, 000h, 000h    ; hor blank start hi
  114.     db    00ah, 016h, 09dh, 09dh, 063h, 063h    ; hor blank end lo
  115.     db    00ah, 017h, 000h, 000h, 000h, 000h    ; hor blank end hi
  116.     db    00ah, 018h, 087h, 087h, 055h, 055h    ; hor sync start lo
  117.     db    00ah, 019h, 000h, 000h, 000h, 000h    ; hor sync start hi
  118.     db    00ah, 01ah, 09ch, 09ch, 061h, 061h    ; hor sync end lo
  119.     db    00ah, 01bh, 000h, 000h, 000h, 000h    ; hor sync end hi
  120.     db    00ah, 01ch, 040h, 040h, 000h, 000h    ; hor sync pos
  121.     db    00ah, 01eh, 004h, 004h, 000h, 000h    ; hor sync pos
  122.     db    00ah, 020h, 030h, 030h, 00ch, 00ch    ; vert tot lo
  123.     db    00ah, 021h, 003h, 003h, 002h, 002h    ; vert tot hi
  124.     db    00ah, 022h, 0ffh, 0ffh, 0dfh, 0dfh    ; vert disp end lo
  125.     db    00ah, 023h, 002h, 002h, 001h, 001h    ; vert disp end hi
  126.     db    00ah, 024h, 0ffh, 0ffh, 0dfh, 0dfh    ; vert blank start lo
  127.     db    00ah, 025h, 002h, 002h, 001h, 001h    ; vert blank start hi
  128.     db    00ah, 026h, 030h, 030h, 00ch, 00ch    ; vert blank end lo
  129.     db    00ah, 027h, 003h, 003h, 002h, 002h    ; vert blank end hi
  130.     db    00ah, 028h, 000h, 000h, 0eah, 0eah    ; vert sync start lo
  131.     db    00ah, 029h, 003h, 003h, 001h, 001h    ; vert sync start hi
  132.     db    00ah, 02ah, 008h, 008h, 0ech, 0ech    ; vert sync end
  133.     db    00ah, 02ch, 0ffh, 0ffh, 0ffh, 0ffh    ; vert line comp lo
  134.     db    00ah, 02dh, 0ffh, 0ffh, 0ffh, 0ffh    ; vert line comp hi
  135.     db    00ah, 036h, 000h, 000h, 000h, 000h    ; sprite cntl
  136.     db    00ah, 040h, 000h, 000h, 000h, 000h    ; start addr lo
  137.     db    00ah, 041h, 000h, 000h, 000h, 000h    ; start addr me
  138.     db    00ah, 042h, 000h, 000h, 000h, 000h    ; start addr hi
  139.     db    00ah, 043h, 080h, 040h, 050h, 0a0h    ; buffer pitch lo
  140.     db    00ah, 044h, 000h, 000h, 000h, 000h    ; buffer pitch hi
  141.     db    00ah, 054h, 00dh, 00dh, 000h, 000h    ; clock sel
  142.     db    00ah, 051h, 003h, 002h, 003h, 004h    ; display mode 2
  143.     db    00ah, 070h, 000h, 000h, 000h, 000h    ; ext clock sel
  144.     db    00ah, 050h, 00fh, 00fh, 0c7h, 0c7h    ; display mode 1
  145.     db    00ah, 055h, 000h, 000h, 000h, 000h    ; Border Color
  146. ;    db    00ah, 060h, 000h, 000h, 000h, 000h    ; Sprite Pal Lo
  147. ;    db    00ah, 061h, 000h, 000h, 000h, 000h    ; Sprite Pal hi
  148. ;    db    00ah, 062h, 000h, 000h, 000h, 000h    ; Sprite Pre Lo
  149. ;    db    00ah, 063h, 000h, 000h, 000h, 000h    ; Sprite Pre hi
  150. ;    db    00ah, 064h, 0ffh, 0ffh, 0ffh, 0ffh    ; Palette Mask
  151.     db    0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh    ; end of the list
  152.  
  153. xga_newbank    proc            ; XGA-specific bank-switching routine
  154.     cmp    xga_isinmode,2        ; are we in an XGA-specific mode?
  155.     jl    return            ;  nope.  bail out.
  156.     mov    xga_curbk,ax        ; save the new current bank value
  157.     mov    dx,xga_reg_base        ; Select Page
  158.     add    dx,08h
  159.     out    dx,al            ; assumes bank number is in al
  160. return:    ret
  161. xga_newbank    endp
  162.  
  163. xga_nullroutine    proc    near
  164.     mov    ax,0
  165.     ret
  166. xga_nullroutine    endp
  167.  
  168. xga_normalinewrite    proc    near    ; Normal Line
  169. normal_line1:
  170.     push    ax            ; save stop col
  171.     mov    al,[si]         ; retrieve the color
  172.     cmp    xga_isinmode,5        ; 16-bit mode?
  173.     jne    normal_line2
  174.     mov    ax,[si]            ; yup - adjust
  175.     inc    si
  176. normal_line2:
  177.     push    cx            ; save the counter around the call
  178.     push    dx            ; save column around the call
  179.     push    si            ; save the pointer around the call also
  180.     call    xga_dotwrite        ; write the dot via the approved method
  181.     pop    si            ; restore the pointer
  182.     pop    dx            ; restore the column
  183.     pop    cx            ; restore the counter
  184.     inc    si            ; bump it up
  185.     inc    cx            ; bump it up
  186.     pop    ax            ; retrieve number of dots
  187.     cmp    cx,ax            ; more to go?
  188.     jle    normal_line1        ; yup.    do it.
  189.     ret
  190. xga_normalinewrite    endp
  191.  
  192. xga_normalineread    proc    near        ; Normal Line
  193.     mov    bx,0a000h
  194.     mov    es,bx
  195. normal_lineread1:
  196.     push    ax            ; save stop col
  197.     push    cx            ; save the counter around the call
  198.     push    dx            ; save column around the call
  199.     push    di            ; save the pointer around the call also
  200.     call    xga_dotread         ; read the dot via the approved method
  201.     pop    di            ; restore the pointer
  202.     pop    dx            ; restore the column
  203.     pop    cx            ; restore the counter
  204.     mov    bx,di            ; locate the actual pixel color
  205.     mov    [bx],al         ; retrieve the color
  206.     cmp    xga_isinmode,5        ; 16-bit mode?
  207.     jne    normal_line2
  208.     mov    [bx],ax            ; yup - adjust
  209.     inc    di
  210. normal_line2:
  211.     inc    di            ; bump it up
  212.     inc    cx            ; bump it up
  213.     pop    ax            ; retrieve number of dots
  214.     cmp    cx,ax            ; more to go?
  215.     jle    normal_lineread1    ; yup.    do it.
  216.     ret
  217. xga_normalineread    endp
  218.  
  219. xga_sameseg    proc    near        ; line segment support
  220.     cmp    xga_isinmode,5        ; 64K color mode?
  221.     jne    xga_sk1
  222.     add    ax,ax            ; two bytes / pixel
  223.     add    cx,cx
  224. xga_sk1:
  225.     mov    bx,ax            ; calculate the line segment len
  226.     sub    bx,cx
  227.     mov    xga_linelen,bx
  228.     mov    ax,xga_xdots        ; calculate the first pixel bank
  229.     mul    dx
  230.     add    ax,cx
  231.     adc    dx,0
  232.     mov    bx,dx            ; save the bank address
  233.     mov    xga_offset,ax        ; save the destination
  234.     add    ax,xga_linelen        ; calculate the last pixel bank
  235.     adc    dx,0
  236.     cmp    dx,bx            ; same bank?
  237.     jne    xga_sk2            ;  nope
  238.     mov    ax,dx            ; xga_newbank expects bank in al
  239.     call    far ptr xga_newbank
  240.     cmp    ax,ax            ; set flag: same bank
  241. xga_sk2:ret
  242. xga_sameseg    endp
  243.  
  244. xga_16linewrite    proc    near        ; 16-color Line Write
  245.     mov    bx,ax            ; calculate the # of columns
  246.     sub    bx,cx
  247.     mov    ax,xga_xdots        ; this many dots / line
  248.     mul    dx            ; times this many lines - ans in dx:ax
  249.     push    cx            ; save the X-value for a tad
  250.     shr    cx,1            ; and adjust for two bits per pixel
  251.     add    ax,cx            ; plus this many x-dots
  252.     adc    dx,0            ; answer in dx:ax - dl=bank, ax=offset
  253.     mov    di,ax            ; save offset in DI
  254.     pop    cx            ; restore the X-value
  255.     mov    ax,dx            ; xga_newbank expects bank in al
  256. new_bank:
  257.     call    far ptr xga_newbank
  258. same_bank:
  259.     mov    ah,es:[di]        ; grab the old byte value
  260.     mov    al,[si]            ; and the new color value
  261.     and    al,0fh            ; isolate the bits we want
  262.     test    cx,1            ; odd pixel address?
  263.     jnz    xga_sk1            ;  yup
  264.     and    ah,0f0h            ; isolate the low-order
  265.     jmp    short    xga_sk2
  266. xga_sk1:and    ah,0fh            ; isolate the high-order
  267.     shl    al,1
  268.     shl    al,1
  269.     shl    al,1
  270.     shl    al,1
  271. xga_sk2:or    al,ah            ; combine the two nibbles
  272.     mov    es:[di],al        ; write the dot
  273.     inc    si            ; increment the source addr
  274.     dec    bx            ; more to go?
  275.     jz    done            ; nope
  276.     inc    cx            ; next pixel
  277.     test    cx,1            ; odd pixel?
  278.     jnz    same_bank        ;  yup
  279.     inc    di            ; increment the destination
  280.     cmp    di,0            ; segment wrap?
  281.     jnz    same_bank        ;  nope
  282.     mov    ax,xga_curbk        ; update the bank cvalue
  283.     inc    ax
  284.     jmp    new_bank
  285. done:    ret
  286. xga_16linewrite        endp
  287.  
  288. xga_256linewrite    proc    near    ; 256-color, 64K color line write
  289.     push    dx            ; save a few registers
  290.     push    cx
  291.     push    ax
  292.     call    xga_sameseg
  293.     jne    slow            ; go slow if banks changed
  294.     mov    cx,xga_linelen        ; do it the fast way
  295.     mov    di,xga_offset
  296.     cld
  297.     shr    cx,1
  298.     rep    movsw
  299.     rcl    cx,1
  300.     rep    movsb
  301.     pop    ax            ; restore the registers
  302.     pop    cx
  303.     pop    dx
  304.     ret
  305. slow:    pop    ax            ; call the slow routine
  306.     pop    cx
  307.     pop    dx
  308.     call    xga_normalinewrite
  309.     ret
  310. xga_256linewrite    endp
  311.  
  312. xga_256lineread    proc    near        ; 256-color, 64K color line write
  313.     push    dx            ; save a few registers
  314.     push    cx
  315.     push    ax
  316.     call    xga_sameseg
  317.     jne    slow            ; go slow if banks changed
  318.     mov    cx,xga_linelen        ; do it the fast way
  319.     mov    si,xga_offset
  320.     push    ds
  321.     pop    es
  322.     mov    ax,0a000h
  323.     mov    ds,ax
  324.     cld
  325.     shr    cx,1
  326.     rep    movsw
  327.     rcl    cx,1
  328.     rep    movsb
  329.     push    es
  330.     pop    ds
  331.     pop    ax            ; restore the registers
  332.     pop    cx
  333.     pop    dx
  334.     ret
  335. slow:    pop    ax            ; call the slow routine
  336.     pop    cx
  337.     pop    dx
  338.     call    xga_normalineread
  339.     ret
  340. xga_256lineread    endp
  341.  
  342. xga_super256addr    proc near    ; can be put in-line but shared by
  343.                     ; read and write routines
  344.     clc                ; clear carry flag
  345.     push    ax            ; save this for a tad
  346.     mov    ax,xga_xdots        ; this many dots / line
  347.     mul    dx            ; times this many lines - ans in dx:ax
  348.     add    ax,cx            ; plus this many x-dots
  349.     adc    dx,0            ; answer in dx:ax - dl=bank, ax=offset
  350.     mov    bx,ax            ; save this in BX
  351.     cmp    dx,xga_curbk        ; see if bank changed
  352.     je    same_bank        ; jump if old bank ok
  353.     mov    ax,dx            ; xga_newbank expects bank in al
  354.     call    far ptr xga_newbank
  355. same_bank:
  356.     pop    ax            ; restore AX
  357.     ret
  358. xga_super256addr    endp
  359.  
  360. xga_super64kaddr    proc near    ; can be put in-line but shared by
  361.                     ; read and write routines
  362.     clc                ; clear carry flag
  363.     push    ax            ; save this for a tad
  364.     mov    ax,xga_xdots        ; this many dots / line
  365.     mul    dx            ; times this many lines - ans in dx:ax
  366.     add    ax,cx            ; plus this many x-dots
  367.     adc    dx,0            ; answer in dx:ax - dl=bank, ax=offset
  368.     add    ax,cx            ; plus this many x-dots
  369.     adc    dx,0            ; answer in dx:ax - dl=bank, ax=offset
  370.     mov    bx,ax            ; save this in BX
  371.     cmp    dx,xga_curbk        ; see if bank changed
  372.     je    same_bank        ; jump if old bank ok
  373.     mov    ax,dx            ; xga_newbank expects bank in al
  374.     call    far ptr xga_newbank
  375. same_bank:
  376.     pop    ax            ; restore AX
  377.     ret
  378. xga_super64kaddr    endp
  379.  
  380. xga_super16addr    proc near        ; can be put in-line but shared by
  381.                     ; read and write routines
  382.     clc                ; clear carry flag
  383.     push    ax            ; save this for a tad
  384.     mov    ax,xga_xdots        ; this many dots / line
  385.     mul    dx            ; times this many lines - ans in dx:ax
  386.     push    cx            ; save the X-value for a tad
  387.     shr    cx,1            ; and adjust for two bits per pixel
  388.     add    ax,cx            ; plus this many x-dots
  389.     adc    dx,0            ; answer in dx:ax - dl=bank, ax=offset
  390.     pop    cx            ; restore the X-value
  391.     mov    bx,ax            ; save this in BX
  392.     cmp    dx,xga_curbk        ; see if bank changed
  393.     je    same_bank        ; jump if old bank ok
  394.     mov    ax,dx            ; xga_newbank expects bank in al
  395.     call    far ptr xga_newbank
  396. same_bank:
  397.     pop    ax            ; restore AX
  398.     ret
  399. xga_super16addr    endp
  400.  
  401. xga_256write    proc near        ; XGA 256 colors write-a-dot
  402.     call    xga_super256addr    ; calculate address and switch banks
  403.     mov    es:[bx],al        ; write the dot
  404.     ret                ; we done.
  405. xga_256write    endp
  406.  
  407. xga_256read    proc near        ; XGA 256 colors read-a-dot
  408.     call    xga_super256addr    ; calculate address and switch banks
  409.     mov    al,es:[bx]        ; read the dot
  410.     mov    ah,0            ; convert to an int
  411.     ret                ; we done.
  412. xga_256read    endp
  413.  
  414. xga_64kwrite    proc near        ; XGA 256 colors write-a-dot
  415.     call    xga_super64kaddr    ; calculate address and switch banks
  416.     mov    es:[bx],ax        ; write the dot
  417.     ret                ; we done.
  418. xga_64kwrite    endp
  419.  
  420. xga_64kread    proc near        ; XGA 256 colors read-a-dot
  421.     call    xga_super64kaddr    ; calculate address and switch banks
  422.     mov    ax,es:[bx]        ; read the dot
  423.     ret                ; we done.
  424. xga_64kread    endp
  425.  
  426. xga_16write    proc near        ; XGA 256 colors write-a-dot
  427.     call    xga_super16addr        ; calculate address and switch banks
  428.     mov    ah,es:[bx]        ; grab the old byte value
  429.     and    al,0fh            ; isolate the bits we want
  430.     test    cx,1            ; odd pixel address?
  431.     jnz    xga_sk1            ;  yup
  432.     and    ah,0f0h            ; isolate the low-order
  433.     jmp    short    xga_sk2
  434. xga_sk1:and    ah,0fh            ; isolate the high-order
  435.     shl    al,1
  436.     shl    al,1
  437.     shl    al,1
  438.     shl    al,1
  439. xga_sk2:or    al,ah            ; combine the two nibbles
  440.     mov    es:[bx],al        ; write the dot
  441.     ret                ; we done.
  442. xga_16write    endp
  443.  
  444. xga_16read    proc near        ; XGA 256 colors read-a-dot
  445.     call    xga_super16addr        ; calculate address and switch banks
  446.     mov    al,es:[bx]        ; read the dot
  447.     test    cx,1            ; odd number of pixels?
  448.     jz    xga_sk1            ;  nope
  449.     shr    ax,1            ; adjust for odd pixel count
  450.     shr    ax,1
  451.     shr    ax,1
  452.     shr    ax,1
  453. xga_sk1:and    ax,0fh            ; isolate the byte value
  454.     ret                ; we done.
  455. xga_16read    endp
  456.  
  457. xga_clear    proc    uses es si di    ; clear the XGA memory
  458.     cmp    xga_clearvideo,0    ; should we really do this?
  459.     jne    return            ;  nope.  skip it.
  460.     mov    bx,xga_result        ; find out how much memory we have
  461.     and    bx,08h            ;  in 64K pages
  462.     add    bx,08h
  463.     mov    ax,0a000h        ; set up to clear 0a0000-0affff
  464.     push    ax
  465.     pop    es
  466. xloop:    mov    ax,bx            ; initialize the bank addr
  467.     call    xga_newbank
  468.     mov    ax,0
  469.     mov    cx,16384        ; clear out 32K
  470.     mov    di,0
  471.     rep    stosw
  472.     mov    cx,16384        ; clear out 32K
  473.     rep    stosw
  474.     dec    bx            ; another page?
  475.     cmp    bx,0
  476.     jge    xloop
  477. return:    ret
  478. xga_clear    endp
  479.  
  480. xga_setpalette    proc    uses es si di, palette:word    ; set the XGA palette
  481.     cmp    xga_isinmode,2        ; are we in an XGA graphics mode?
  482.     jl    return            ;  nope
  483.  
  484.     mov    dx,xga_reg_base        ; wait for a retrace
  485.     add    dx,5
  486.     mov    al,1            ; clear the start-of-blanking
  487.     out    dx,al
  488. bloop:    in    al,dx
  489.     test    al,01h            ; blanking started?
  490.     jz    bloop            ;  nope - try again
  491.  
  492.     mov    dx,xga_reg_base        ; set up for a palette load
  493.     add    dx,0ah
  494.     mov    ax,0064h        ; make invisible
  495.     out    dx,ax
  496.     mov    ax,0055h        ; border color
  497.     out    dx,ax
  498.     mov    ax,0066h        ; palette mode
  499.     out    dx,ax
  500.     mov    ax,0060h        ; start at palette 0
  501.     out    dx,ax
  502.     mov    ax,0061h
  503.     out    dx,ax
  504.  
  505.     mov    si,palette
  506.     mov    cx,768
  507.     mov    ax,065h            ; palette update
  508.     out    dx,al
  509.     inc    dx            ; palette data
  510. .186
  511.     rep    outsb
  512. .8086
  513.     dec    dx
  514.  
  515.     mov    ax,0ff64h        ; make visible
  516.     out    dx,ax
  517.  
  518. return:    ret
  519. xga_setpalette    endp
  520.  
  521. xga_detect    proc    uses es di si
  522.  
  523.     cmp    xga_reg_base,-2        ; has the XGA detector already failed?
  524.     jne    xga_sk1            ; ne = not yet
  525.     jmp    xga_notfound        ; e = yes, fail again
  526. xga_sk1:cmp    xga_reg_base,-1        ; have we already found the XGA?
  527.     je    xga_loc            ; e = no
  528.     jmp    xga_found        ; yes, process it
  529.  
  530. xga_loc:mov    ah,35h            ; DOS get interrupt vector
  531.     mov    al,15h            ; Int 15h
  532.     int    21h            ; returns vector in es:bx
  533.     mov    ax,es            ; segment part
  534.     or    ax,ax            ; undefined vector?
  535.     jnz    xga_sk2            ; nz = no, OK so far
  536.     jmp    xga_notfound        ; z = yes - not an MCA machine
  537. xga_sk2:mov    dx,-1            ; start with an invalid POS address
  538.     mov    ax,0c400h        ; look for POS base address
  539.     int    15h            ;  (Microchannel machines only)
  540.     jnc    xga_sk3            ; nc = success
  541.     jmp    xga_notfound        ; error - not an MC machine
  542. xga_sk3:mov    xga_pos_base,dx        ; save pos_base_address
  543.     xor    cx,cx            ; check all MCA slots & motherboard
  544.     cmp    dx,-1            ; do we have a good POS?
  545.     jne    xga_lp1            ; ne = yes, proceed with MCA checks
  546.     jmp    xga_notfound        ; no, fail
  547.  
  548. xga_lp1:cli                ; no interrupts, please
  549.     cmp    cx,0            ; treat the motherboard differently?
  550.     jne    xga_sk4            ; ne = yes
  551.     mov    al,0dfh            ; enable the motherboard for setup
  552.     mov    dx,94h
  553.     out    dx,al
  554.     jmp    short xga_sk5
  555. xga_sk4:mov    ax,0c401h        ; enable an MCA slot for setup
  556.     mov    bx,cx            ;  this slot
  557.     int    15h
  558. xga_sk5:mov    dx,xga_pos_base        ; get pos record for the slot ID
  559.     in    ax,dx
  560.     mov    xga_cardid,ax
  561.     add    dx,2            ; compute IO Res Base
  562.     in    al,dx            ;  get POS data byte1
  563.     mov    byte ptr xga_1mb,al    ;   save it temporarily
  564.     inc    dx            ; switch to byte 2
  565.     in    al,dx            ;  get POS data
  566.     mov    byte ptr xga_1mb+1,al    ;   save it temporarily
  567.     inc    dx            ; switch to byte 3
  568.     in    al,dx            ;  get POS data
  569.     mov    byte ptr xga_1mb+2,al    ;   save it temporarily
  570.     inc    dx            ; switch to byte 4
  571.     in    al,dx            ;  get POS data
  572.     mov    byte ptr xga_1mb+3,al    ;   save it temporarily
  573.     cmp    cx,0            ; treat the motherboard differently
  574.     jne    xga_sk6            ; ne = yes
  575.     mov    al,0ffh            ; enable the motherboard for normal
  576.     out    094h,al
  577.     jmp    short xga_sk7
  578. xga_sk6:mov    ax,0c402h        ; enable the MCA slot for normal
  579.     mov    bx,cx            ;  this slot
  580.     int    15h
  581. xga_sk7:sti                ; interrupts on again
  582.  
  583.     mov    ax,xga_cardid        ; is an XGA adapter on this slot?
  584.     cmp    ax,08fd8h
  585.     jae    xga_sk8            ; ae = yes
  586.     jmp    xga_lp2            ; try another slot
  587. xga_sk8:cmp    ax,08fdbh        ; still within range?
  588.     jbe    xga_sk9            ; be = yes
  589.     jmp    xga_lp2            ; no, try another slot
  590.  
  591. xga_sk9:mov    al,byte ptr xga_1mb    ;  restore POS data byte 1
  592.     and    ax,0eh            ;  muck about with it to get reg base
  593.     shl    ax,1
  594.     shl    ax,1
  595.     shl    ax,1
  596.     add    ax,2100h
  597.     mov    xga_reg_base,ax
  598.     mov    dx,xga_reg_base        ; is there a monitor on this slot?
  599.     add    dx,0ah
  600.     mov    al,052h
  601.     out    dx,al
  602.     mov    dx,xga_reg_base
  603.     add    dx,0bh
  604.     in    al,dx
  605.     and    al,0fh
  606.     cmp    al,00h            ; illegal value, returned under Win 3.0
  607.     je    xga_lp2
  608.     cmp    al,0fh
  609.     jne    xga_isthere        ; ne = yes
  610.  
  611. xga_lp2:inc    cx            ; try another adapter?
  612.     cmp    cx,9            ; done all slots?
  613.     ja    xga_ska            ; a = yes
  614.     jmp    xga_lp1            ; no, try another slot
  615.  
  616. xga_ska:jmp    xga_notfound        ; forget it - no XGA here
  617.  
  618. xga_isthere:
  619.     and    ax,06h            ; strip off the low & high bit
  620.     xor    ax,05h            ; reverse the 3rd & low bits
  621.     mov    xga_result,ax        ; save the result flag
  622.  
  623.     mov    dx,xga_reg_base        ; is this XGA in VGA mode?
  624.     in    al,dx
  625.     test    al,1
  626.     jnz    xga_skb            ; nz = yes - single-monitor setup
  627.     or    xga_result,10h        ;  dual-monitor setup
  628. xga_skb:
  629.  
  630.     mov    ah,byte ptr xga_1mb+2    ; retrieve POS data byte 3
  631.     and    ax,0fe00h        ; eliminate the low-order bits
  632.     mov    bl,byte ptr xga_1mb    ; retrieve POS data byte 1
  633.     and    bx,0eh            ; strip it down to the IODA
  634.     mov    cx,5            ; shift it up 5 bits
  635.     shl    bx,cl
  636.     or    ax,bx            ; compute the 4MB aperture value
  637.     mov    word ptr xga_4mb+2,ax    ; save the result
  638.  
  639.     mov    al, byte ptr xga_1mb+3    ; retrieve POS data byte 4
  640.     and    ax,0fh            ; select the 1MB aperture bits
  641.     mov    cx,4            ; shift it up 4 bits
  642.     shl    ax,cl
  643.     mov    word ptr xga_1mb+2,ax    ; save the result
  644.     mov    ax,0
  645.     mov    word ptr xga_1mb,ax 
  646.  
  647.     mov    dx,xga_reg_base        ; Interrupt Disable
  648.     add    dx,4
  649.     xor    al,al
  650.     out    dx,al
  651.  
  652.     mov    dx,xga_reg_base        ; Switch to Extended Mode
  653. ;;    add    dx,00h
  654.     mov    al,4
  655.     out    dx,al
  656.  
  657.     mov    dx,xga_reg_base        ; Aperture Control
  658.     add    dx,01h
  659.     mov    al,1
  660.     out    dx,al
  661.  
  662.     mov    dx,xga_reg_base        ; disable Palette Mask
  663.     add    dx,0ah
  664.     mov    ax,0064h
  665.     out    dx,ax
  666.  
  667.     mov    xga_isinmode,2        ; pretend we're already in graphics
  668.     mov    al,12            ; select page 12
  669.     call    xga_newbank
  670.  
  671.     push    es            ; see if this page has any memory
  672.     mov    ax,0a000h
  673.     push    ax
  674.     pop    es
  675.     mov    ah,000a5h
  676.     mov    es:0,al
  677.     mov    es:1,ah
  678.     cmp    es:0,al
  679.     jne    xga_512
  680.     add    xga_result,8        ; 1MB RAM found
  681. xga_512:pop    es
  682.  
  683.     mov    al,0            ; select page 0
  684.     call    xga_newbank
  685.     mov    xga_isinmode,0        ; replace the "in-graphics" flag
  686.  
  687.     mov    dx,xga_reg_base        ; Palette Mask
  688.     add    dx,0ah
  689.     mov    ax,0ff64h
  690.     out    dx,ax
  691.  
  692.     test    xga_result,10h        ; dual monitor setup?
  693.     jnz    xga_found        ;  yup - don't restore as a VGA
  694.  
  695.     mov    dx,xga_reg_base        ; Switch to VGA Mode
  696. ;;    add    dx,00h
  697.     mov    al,1
  698.     out    dx,al
  699.  
  700.     mov    dx,03c3h        ; Enable VGA Address Code
  701.     mov    al,1
  702.     out    dx,al
  703.  
  704.     jmp    short    xga_found
  705.  
  706. xga_notfound:
  707.     mov    xga_reg_base,-2        ; set failure flag
  708. xga_found:
  709.     mov    ax,xga_result        ; return the result
  710.     ret
  711.  
  712. xga_detect    endp
  713.  
  714. xga_mode    proc    uses es di si, mode:word
  715.  
  716.     mov    ax, offset xga_nullroutine    ; null out the pixel rtns
  717.     mov    xga_dotwrite,ax
  718.     mov    xga_dotread,ax
  719.     mov    xga_linewrite,ax
  720.     mov    xga_lineread,ax
  721.     mov    ax,offset xga_normalinewrite
  722.     mov    xga_linewrite,ax
  723.     mov    ax,offset xga_normalineread
  724.     mov    xga_lineread,ax
  725.     mov    xga_curbk,-1        ; preload impossible bank number
  726.  
  727.     call    xga_detect        ; is an XGA adapter present?
  728.     cmp    ax,0
  729.     jne    whichmode
  730.     jmp    nope            ;  nope
  731. whichmode:
  732.     cmp    mode,0            ; 80-col VGA text mode?
  733.     jne    whichmode1
  734.     jmp    mode_0            ;  yup
  735. whichmode1:
  736.     cmp    mode,1            ; 132-col VGA text mode?
  737.     jne    whichmode2
  738.     jmp    mode_1            ;  yup
  739. whichmode2:
  740.     cmp    mode,2            ; 1024x768x256 mode?
  741.     jne    whichmode3
  742.     mov    xga_xdots,1024        ; set the dots/scan line
  743.     mov    bx, offset xga_256read    ; set the pixel rtns
  744.     mov    xga_dotread,bx
  745.     mov    bx, offset xga_256write    ; set the pixel rtns
  746.     mov    xga_dotwrite,bx
  747.     mov    bx, offset xga_256linewrite    ; set the pixel rtns
  748.     mov    xga_linewrite,bx
  749.     mov    bx, offset xga_256lineread    ; set the pixel rtns
  750.     mov    xga_lineread,bx
  751.     and    al,0dh            ; 1MB RAM and high-rez adapter?
  752.     cmp    al,0dh
  753.     je    xga_sk1            ;  yup
  754.     jmp    nope            ;  nope
  755. xga_sk1:jmp    mode_3
  756. whichmode3:
  757.     cmp    mode,3            ; 1024x768x16 mode?
  758.     jne    whichmode4
  759.     mov    xga_xdots,512        ; set the dots/scan line
  760.     mov    bx, offset xga_16read    ; set the pixel rtns
  761.     mov    xga_dotread,bx
  762.     mov    bx, offset xga_16write    ; set the pixel rtns
  763.     mov    xga_dotwrite,bx
  764.     mov    bx, offset xga_16linewrite    ; set the pixel rtns
  765.     mov    xga_linewrite,bx
  766.     and    al,05h            ; high-rez adapter?
  767.     cmp    al,05h
  768.     je    mode_3            ;  yup
  769.     jmp    nope            ;  nope
  770. whichmode4:
  771.     cmp    mode,4            ; 640x480x256 mode?
  772.     jne    whichmode5
  773.     mov    xga_xdots,640        ; set the dots/scan line
  774.     mov    bx, offset xga_256read    ; set the pixel rtns
  775.     mov    xga_dotread,bx
  776.     mov    bx, offset xga_256write    ; set the pixel rtns
  777.     mov    xga_dotwrite,bx
  778.     mov    bx, offset xga_256linewrite    ; set the pixel rtns
  779.     mov    xga_linewrite,bx
  780.     mov    bx, offset xga_256lineread    ; set the pixel rtns
  781.     mov    xga_lineread,bx
  782.     jmp    mode_3            ;  yup
  783. whichmode5:
  784.     cmp    mode,5            ; 640x480x65536 mode?
  785.     jne    whichmode6
  786.     mov    xga_xdots,1280        ; set the dots/scan line
  787.     mov    bx, offset xga_64kread    ; set the pixel rtns
  788.     mov    xga_dotread,bx
  789.     mov    bx, offset xga_64kwrite    ; set the pixel rtns
  790.     mov    xga_dotwrite,bx
  791.     mov    bx, offset xga_256linewrite    ; set the pixel rtns
  792.     mov    xga_linewrite,bx
  793.     mov    bx, offset xga_256lineread    ; set the pixel rtns
  794.     mov    xga_lineread,bx
  795.     and    al,09h            ; 1MB RAM?
  796.     cmp    al,09h
  797.     je    mode_3            ;  yup
  798.     jmp    nope            ;  nope
  799. whichmode6:
  800.     jmp    nope            ; bad or unsupportable mode
  801.  
  802. mode_3:    mov    dx,03c3h        ; Enable VGA Address Code
  803.     mov    al,1
  804.     out    dx,al
  805.  
  806.     mov    si,offset xga_val    ; point to start of values table
  807.     mov    bx,mode            ; use mode as an offset
  808. model1: mov    dx,xga_reg_base        ; get the base pointer
  809.     mov    ah,0            ; get the increment
  810.     mov    al,cs:0[si]
  811.     cmp    al,0ffh            ; end of the table?
  812.     je    model2            ;  yup
  813.     add    dx,ax
  814.     cmp    al,0ah            ; check for access type
  815.     je    modsk2
  816.     mov    al,cs:0[si+bx]        ; get the value and OUT it
  817.     out    dx,al
  818.     jmp    short modsk3
  819. modsk2:    mov    al,cs:1[si]        ; get the value and OUT it
  820.     mov    ah,cs:0[si+bx]
  821.     out    dx,ax
  822. modsk3:    add    si,6            ; try again
  823.     jmp    short model1
  824. model2:
  825.  
  826.     mov    xga_isinmode,2        ; pretend we're already in graphics
  827.     call    xga_clear        ; clear out the memory
  828.     mov    xga_curbk,-1        ; reset the bank counter
  829.  
  830.     mov    dx,xga_reg_base        ; set up for final loads
  831.     add    dx,0ah
  832.     cmp    mode,5            ; "true color" klooge
  833.     jne    modsk4
  834.  
  835.     mov    ax,0064h        ; make invisible
  836.     out    dx,ax
  837.     mov    ax,8055h        ; border color
  838.     out    dx,ax
  839.     mov    ax,0066h        ; palette mode
  840.     out    dx,ax
  841.     mov    ax,0060h        ; start at palette 0
  842.     out    dx,ax
  843.     mov    ax,0061h        ; ""
  844.     out    dx,ax
  845.  
  846.     mov    cx,0            ; ready to update the palette
  847.     mov    al,065h            ; palette update
  848.     out    dx,al
  849.     inc    dx            ; palette data
  850. model3:    out    dx,al            ; red value
  851.     out    dx,al            ; green value
  852.     mov    al,cl            ; klooge up the blue value
  853.     and    al,1fh
  854.     add    al,al
  855.     out    dx,al            ; blue value
  856.     inc    cx            ; another palette value to go?
  857.     cmp    cx,128
  858.     jb    model3
  859.     dec    dx            ; back to normal
  860.  
  861. modsk4:    mov    ax,0ff64h        ; make visible
  862.     out    dx,ax
  863.     jmp    ok
  864.  
  865. mode_0:                    ; Set 80 column mode
  866.     mov    dx,xga_reg_base        ; Aperture Control
  867.     add    dx,01h
  868.     xor    al,al            ; (disable the XGA 64K aperture)
  869.     out    dx,al
  870.  
  871.     mov    dx,xga_reg_base        ; Interrupt Disable
  872.     add    dx,4
  873.     xor    al,al
  874.     out    dx,al
  875.  
  876.     mov    dx,xga_reg_base        ; Clear Interrupts
  877.     add    dx,5
  878.     mov    al,0ffh
  879.     out    dx,al
  880.  
  881.     test    xga_result,10h        ; dual monitor setup?
  882.     jz    mode_0a
  883.     jmp    nope            ;  yup - don't restore as a VGA
  884. mode_0a:
  885.  
  886.     mov    dx,xga_reg_base        ; Palette Mask
  887.     add    dx,0ah
  888.     mov    ax,0ff64h        ; (Disable the XGA palette)
  889.     out    dx,ax
  890.  
  891.     mov    dx,xga_reg_base        ; Enable VFB, Prepare for Reset
  892.     add    dx,0ah
  893.     mov    ax,1550h
  894.     out    dx,ax
  895.  
  896.     mov    dx,xga_reg_base        ; Enable VFB, reset CRTC
  897.     add    dx,0ah
  898.     mov    ax,1450h
  899.     out    dx,ax
  900.  
  901.     mov    dx,xga_reg_base        ; Normal Scale Factors
  902.     add    dx,0ah
  903.     mov    ax,0051h
  904.     out    dx,ax
  905.  
  906.     mov    dx,xga_reg_base        ; Select VGA Oscillator
  907.     add    dx,0ah
  908.     mov    ax,0454h
  909.     out    dx,ax
  910.  
  911.     mov    dx,xga_reg_base        ; Ext Oscillator (VGA)
  912.     add    dx,0ah
  913.     mov    ax,7f70h
  914.     out    dx,ax
  915.  
  916.     mov    dx,xga_reg_base        ; Ensure no Vsynch Interrupts
  917.     add    dx,0ah
  918.     mov    ax,202ah
  919.     out    dx,ax
  920.  
  921.     mov    dx,xga_reg_base        ; Switch to VGA Mode
  922. ;;    add    dx,00h
  923.     mov    al,1
  924.     out    dx,al
  925.  
  926.     mov    dx,03c3h        ; Enable VGA Address Code
  927.     mov    al,1
  928.     out    dx,al
  929.  
  930.     mov    ax,1202h        ; select 400 scan lines
  931.     mov    bl,30h
  932.     int    10h
  933.     mov    ax,0+3            ; set video mode 3
  934.     or    al,xga_clearvideo    ; (might supress video-clearing)
  935.     int    10h
  936.  
  937.     jmp    ok            ; we're done
  938.  
  939. mode_1:                    ; 132-col VGA text mode
  940.     test    xga_result,10h        ; dual monitor setup?
  941.     jz    mode_1a
  942.     jmp    nope            ;  yup - don't restore as a VGA
  943. mode_1a:
  944.     mov    dx,xga_reg_base
  945.     add    dx,0ah
  946.     mov    ax,1550h        ; prepare CRTC for Reset
  947.     out    dx,ax
  948.     mov    ax,1450h        ; Reset CRTC
  949.     out    dx,ax
  950.     mov    ax,0454h        ; Select VGA Oscillator
  951.     out    dx,ax
  952.     mov    ax,1202h        ; select 400 scan lines
  953.     mov    bl,30h
  954.     int    10h
  955.     mov    ax,0+3            ; set video mode 3
  956.     or    al,xga_clearvideo    ; (might supress video-clearing)
  957.     int    10h
  958.  
  959.     mov    dx,xga_reg_base        ; Prepare CRTC for Reset
  960.     add    dx,0ah
  961.     mov    al,50h
  962.     out    dx,al
  963.     inc    dx
  964.     in    al,dx
  965.     or    al,1
  966.     out    dx,al
  967.  
  968.     mov    dx,xga_reg_base        ; Prepare CRTC for Reset
  969.     add    dx,0ah
  970.     mov    al,50h
  971.     out    dx,al
  972.     inc    dx
  973.     in    al,dx
  974.     and    al,0fdh
  975.     out    dx,al
  976.  
  977.     mov    dx,xga_reg_base        ; Reset CRTC
  978.     add    dx,0ah
  979.     mov    al,50h
  980.     out    dx,al
  981.     inc    dx
  982.     in    al,dx
  983.     and    al,0fch
  984.     out    dx,al
  985.  
  986.     mov    dx,xga_reg_base        ; 132 column text mode
  987.     mov    al,3
  988.     out    dx,al
  989.  
  990.     mov    dx,xga_reg_base        ; 132 column clock freq select
  991.     add    dx,0ah
  992.     mov    ax,0154h
  993.     out    dx,ax
  994.     mov    ax,8070h        ; Select internal 132 col clock
  995.     out    dx,ax
  996.  
  997.     mov    dx,xga_reg_base        ; Disable VFB
  998.     add    dx,0ah
  999.     mov    al,50h
  1000.     out    dx,al
  1001.     inc    dx
  1002.     in    al,dx
  1003.     and    al,0efh
  1004.     out    dx,al
  1005.  
  1006.     mov    dx,03d4h        ; Enable VGA CRTC reg update
  1007.     mov    ax,11h
  1008.     out    dx,al
  1009.     inc    dx
  1010.     in    al,dx
  1011.     and    al,7fh
  1012.     out    dx,al
  1013.  
  1014.     mov    dx,03d4h        ; Variations on VGA CRTC synchs
  1015.     mov    ax,0            ; (I swear, that's what the manual
  1016.     out    dx,al            ; says...)
  1017.     inc    dx
  1018.     mov    ax,0a4h
  1019.     out    dx,al
  1020.  
  1021.     mov    dx,03d4h        ; Variations on VGA CRTC synchs
  1022.     mov    ax,1
  1023.     out    dx,al
  1024.     inc    dx
  1025.     mov    ax,83h
  1026.     out    dx,al
  1027.  
  1028.     mov    dx,03d4h        ; Variations on VGA CRTC synchs
  1029.     mov    ax,2
  1030.     out    dx,al
  1031.     inc    dx
  1032.     mov    ax,84h
  1033.     out    dx,al
  1034.  
  1035.     mov    dx,03d4h        ; Variations on VGA CRTC synchs
  1036.     mov    ax,3
  1037.     out    dx,al
  1038.     inc    dx
  1039.     mov    ax,83h
  1040.     out    dx,al
  1041.  
  1042.     mov    dx,03d4h        ; Variations on VGA CRTC synchs
  1043.     mov    ax,4
  1044.     out    dx,al
  1045.     inc    dx
  1046.     mov    ax,90h
  1047.     out    dx,al
  1048.  
  1049.     mov    dx,03d4h        ; Variations on VGA CRTC synchs
  1050.     mov    ax,5
  1051.     out    dx,al
  1052.     inc    dx
  1053.     mov    ax,80h
  1054.     out    dx,al
  1055.  
  1056.     mov    dx,xga_reg_base        ; Variations on VGA CRTC synchs
  1057.     add    dx,0ah
  1058.     mov    ax,0a31ah
  1059.     out    dx,ax
  1060.     mov    ax,001bh
  1061.     out    dx,ax
  1062.  
  1063.     mov    dx,03d4h        ; Variations on VGA CRTC synchs
  1064.     mov    ax,13h
  1065.     out    dx,al
  1066.     inc    dx
  1067.     mov    ax,42h
  1068.     out    dx,al
  1069.  
  1070.     mov    dx,03d4h        ; Disable VGA CRTC reg update
  1071.     mov    al,11h
  1072.     out    dx,al
  1073.     inc    dx
  1074.     in    al,dx
  1075.     or    al,80h
  1076.     out    dx,al
  1077.  
  1078.     mov    dx,xga_reg_base        ; Remove CTRC Reset
  1079.     add    dx,0ah
  1080.     mov    al,50h
  1081.     out    dx,al
  1082.     inc    dx
  1083.     in    al,dx
  1084.     or    al,3
  1085.     out    dx,al
  1086.  
  1087.     mov    dx,03c4h        ; 8 bit characters
  1088.     mov    ax,1
  1089.     out    dx,al
  1090.     inc    dx
  1091.     in    al,dx
  1092.     or    al,1
  1093.     out    dx,al
  1094.  
  1095.     mov    dx,03dah        ; Read sets Attr Ctlr flip flop
  1096.     in    al,dx
  1097.  
  1098.     mov    dx,003c0h        ; Sets Attr Ctlr
  1099.     mov    al,13h
  1100.     out    dx,al
  1101.     xor    al,al            ; Reg 13 to 00h
  1102.     out    dx,al
  1103.     mov    al,20h            ; Restore Palette
  1104.     out    dx,al
  1105.  
  1106.     mov    ax,40h            ; tell the BIOS we have 132 columns
  1107.     mov    es,ax
  1108.     mov    byte ptr es:[4ah],132    ; set Bios screen width data area
  1109.     jmp    ok            ; all done!
  1110.  
  1111. nope:
  1112.     mov    ax, offset xga_nullroutine    ; null out the pixel rtns
  1113.     mov    xga_dotwrite,ax
  1114.     mov    xga_dotread,ax
  1115.     mov    xga_linewrite,ax
  1116.     mov    xga_lineread,ax
  1117.     mov    xga_isinmode,0
  1118.     mov    ax,0            ; return failure
  1119.     ret
  1120. ok:
  1121.     mov    ax,mode            ; remember the mode we're in
  1122.     mov    xga_isinmode,ax
  1123.     mov    ax,1            ; return OK
  1124.     ret
  1125. xga_mode    endp
  1126.  
  1127. ; **************** Function xga_getpixel(xdot, ydot) *******************
  1128.  
  1129. ;    Return the color on the screen at the (xdot,ydot) point
  1130.  
  1131. xga_getpixel    proc    uses di si es, xdot:word, ydot:word
  1132.     mov    ax,0a000h        ; EGA, VGA, MCGA starts here
  1133.     mov    es,ax            ; save it here during this routine
  1134.     mov    cx,xdot         ; load up the registers
  1135.     mov    dx,ydot         ;  for the video routine
  1136.     call    xga_dotread         ; read the dot via the approved method
  1137.     ret                ; we done.
  1138. xga_getpixel    endp
  1139.  
  1140. ; ************** Function xga_putpixel(xdot, ydot, color) *******************
  1141.  
  1142. ;    write the color on the screen at the (xdot,ydot) point
  1143.  
  1144. xga_putpixel    proc    uses di si es, xdot:word, ydot:word, xcolor:word
  1145.     mov    ax,0a000h        ; EGA, VGA, MCGA starts here
  1146.     mov    es,ax            ; save it here during this routine
  1147.     mov    cx,xdot         ; load up the registers
  1148.     mov    dx,ydot         ;  for the video routine
  1149.     mov    ax,xcolor        ;  ...
  1150.     call    xga_dotwrite        ; write the dot via the approved method
  1151.     ret                ; we done.
  1152. xga_putpixel    endp
  1153.  
  1154. xga_getline    proc uses di si es, row:word, startcol:word, stopcol:word, pixels:word
  1155.     mov    cx,startcol        ; first column
  1156.     mov    dx,row            ; this row
  1157.     mov    ax, stopcol        ; last pixel to read
  1158.     cmp    ax,cx            ; anything to do?
  1159.     jle    xga_sk1            ;  nope
  1160.     mov    di,offset pixels    ; get the color for dot 'x'
  1161.     call    xga_lineread        ; mode-specific lineread routine
  1162. xga_sk1:xor    ax,ax            ; return 0
  1163.     ret
  1164. xga_getline    endp
  1165.  
  1166. xga_putline    proc uses di si es, row:word, startcol:word, stopcol:word, pixels:word
  1167.     mov    cx,startcol        ; first column
  1168.     mov    dx,row            ; this row
  1169.     mov    ax,0a000h        ; EGA, VGA, MCGA, XGA starts here
  1170.     mov    es,ax            ; save it here during this routine
  1171.     mov    ax, stopcol        ; last column
  1172.     cmp    ax,cx            ; anything to do?
  1173.     jle    xga_sk1            ;  nope
  1174.     mov    si,offset pixels    ; put the color for dot 'x'
  1175.     call    xga_linewrite        ; mode-specific linewrite routine
  1176. xga_sk1:xor    ax,ax            ; return 0
  1177.     ret
  1178. xga_putline    endp
  1179.  
  1180.     end
  1181.