home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / tegl_ii / svga / grevga16.asm < prev    next >
Encoding:
Assembly Source File  |  1991-10-22  |  87.5 KB  |  4,426 lines

  1.  
  2.         include grphdrvr.inc
  3.  
  4. ;-----------------------------------------------------------------------------;
  5. ;               TEGL Windows ToolKit II                  ;
  6. ;          Copyright (C) 1990, TEGL Systems Corporation              ;
  7. ;                All Rights Reserved.                  ;
  8. ;-----------------------------------------------------------------------------;
  9.  
  10.         .code
  11.  
  12.         db   'RT',8,8,'TGI Device Driver (EGA640x350x16/VGA640x480x16) 1.00 - Dec 15 1990',13,10
  13.         db   'Copyright (c) 1989,1990 TEGL Systems Corporation',13,10
  14.         db   01ah         ; end of file for TYPE
  15.         db   00          ; end of Copyright Header
  16.  
  17.         db   8,'GREVGA16',0   ; driver module name
  18.  
  19.         ; EGA 640x350
  20. mode0:        db    13,'EGA640x350x16',0,0,0,0,0,0,0,0
  21.         dw    0         ; Mode Number
  22.         dw    639         ; Device Full Resolution in X
  23.         dw    349         ; Device Full Resolution in Y
  24.         dw    8         ; Standard char size X
  25.         dw    8         ; Standard char size Y
  26.         dw    15         ; Number of colors
  27.         dw    2         ; Number of pages
  28.         dw    16         ; max palette
  29.         dw    0         ; buffer offset for 2 page, Active page
  30.         dw    0A000h         ; Screen Segment
  31.         dw    80         ; bytes per line
  32.         dw    7750         ; x aspect
  33.         dw    10000         ; y aspect
  34.         dd    0         ; Driver Pointer
  35.         dd    0         ; Driver Name Pointer
  36.         dd    0         ; Driver Jump Table
  37.         dd    0         ; Graphics Work Buffer
  38.         dw    0         ; Graphics Buffer Size
  39.         dw    0         ; Read/Write modes
  40.         db    0         ; transparency on-$ff/off-$00
  41.         db    0         ; jagged characters
  42.         dd    0         ; pointer to font table
  43.         db    1         ; allow EGA palette changes
  44.         db    0         ; allow VGA 256 palette changes
  45.         db    1         ; proportional font switch
  46.         dw    0ffffh         ; fillmask for lines
  47.         dw    0         ; viewport - minx
  48.         dw    0         ; viewport - miny
  49.         dw    639         ; viewport - maxx
  50.         dw    349         ; viewport - maxy
  51.         db    0         ; viewport - clipping on/off
  52.         dw    15         ; Mouse color
  53.         dw    0         ; Mouse hotspot
  54.         dw    0         ; Mouse hotspot
  55.         dd    0         ; Mouse Cursor Mask
  56.         dd    0         ; Next VideoMode
  57.  
  58. mode1:        db    13,'VGA640x480x16',0,0,0,0,0,0,0,0
  59.         dw    1         ; Mode Number
  60.         dw    639         ; Device Full Resolution in X
  61.         dw    479         ; Device Full Resolution in Y
  62.         dw    8         ; Standard char size X
  63.         dw    8         ; Standard char size Y
  64.         dw    15         ; Number of colors
  65.         dw    1         ; Number of pages
  66.         dw    16         ; max palette
  67.         dw    0         ; buffer offset for 2 page, Active page
  68.         dw    0A000h         ; Screen Segment
  69.         dw    80         ; bytes per line
  70.         dw    10000         ; x aspect
  71.         dw    10000         ; y aspect
  72.         dd    0         ; Driver Pointer
  73.         dd    0         ; Driver Name Pointer
  74.         dd    0         ; Driver Jump Table
  75.         dd    0         ; Graphics Work Buffer
  76.         dw    0         ; Graphics Buffer Size
  77.         dw    0         ; Read/Write modes
  78.         db    0         ; transparency on-$ff/off-$00
  79.         db    0         ; jagged characters
  80.         dd    0         ; pointer to font table
  81.         db    1         ; allow EGA palette changes
  82.         db    0         ; allow VGA 256 palette changes
  83.         db    1         ; proportional font switch
  84.         dw    0ffffh         ; fillmask for lines
  85.         dw    0         ; viewport - minx
  86.         dw    0         ; viewport - miny
  87.         dw    639         ; viewport - maxx
  88.         dw    479         ; viewport - maxy
  89.         db    0         ; viewport - clipping on/off
  90.         dw    15         ; Mouse color
  91.         dw    0         ; Mouse hotspot
  92.         dw    0         ; Mouse hotspot
  93.         dd    0         ; Mouse Cursor Mask
  94.         dd    0         ; Next VideoMode
  95.  
  96. mode2:        db    14,'SVGA800x600x16',0,0,0,0,0,0,0
  97.         dw    2         ; Mode Number
  98.         dw    799         ; Device Full Resolution in X
  99.         dw    599         ; Device Full Resolution in Y
  100.         dw    8         ; Standard char size X
  101.         dw    14         ; Standard char size Y
  102.         dw    15         ; Number of colors
  103.         dw    1         ; Number of pages
  104.         dw    16         ; max palette
  105.         dw    0         ; buffer offset for 2 page, Active page
  106.         dw    0A000h         ; Screen Segment
  107.         dw    100         ; bytes per line
  108.         dw    10000         ; x aspect
  109.         dw    10000         ; y aspect
  110.         dd    0         ; Driver Pointer
  111.         dd    0         ; Driver Name Pointer
  112.         dd    0         ; Driver Jump Table
  113.         dd    0         ; Graphics Work Buffer
  114.         dw    0         ; Graphics Buffer Size
  115.         dw    0         ; Read/Write modes
  116.         db    0         ; transparency on-$ff/off-$00
  117.         db    0         ; jagged characters
  118.         dd    0         ; pointer to font table
  119.         db    1         ; allow EGA palette changes
  120.         db    0         ; allow VGA 256 palette changes
  121.         db    1         ; proportional font switch
  122.         dw    0ffffh         ; fillmask for lines
  123.         dw    0         ; viewport - minx
  124.         dw    0         ; viewport - miny
  125.         dw    799         ; viewport - maxx
  126.         dw    599         ; viewport - maxy
  127.         db    0         ; viewport - clipping on/off
  128.         dw    15         ; Mouse color
  129.         dw    0         ; Mouse hotspot
  130.         dw    0         ; Mouse hotspot
  131.         dd    0         ; Mouse Cursor Mask
  132.         dd    0         ; Next VideoMode
  133.  
  134. mode3:        db    15,'TWVGA800x600x16',0,0,0,0,0,0
  135.         dw    3         ; Mode Number
  136.         dw    799         ; Device Full Resolution in X
  137.         dw    599         ; Device Full Resolution in Y
  138.         dw    8         ; Standard char size X
  139.         dw    14         ; Standard char size Y
  140.         dw    15         ; Number of colors
  141.         dw    1         ; Number of pages
  142.         dw    16         ; max palette
  143.         dw    0         ; buffer offset for 2 page, Active page
  144.         dw    0A000h         ; Screen Segment
  145.         dw    100         ; bytes per line
  146.         dw    10000         ; x aspect
  147.         dw    10000         ; y aspect
  148.         dd    0         ; Driver Pointer
  149.         dd    0         ; Driver Name Pointer
  150.         dd    0         ; Driver Jump Table
  151.         dd    0         ; Graphics Work Buffer
  152.         dw    0         ; Graphics Buffer Size
  153.         dw    0         ; Read/Write modes
  154.         db    0         ; transparency on-$ff/off-$00
  155.         db    0         ; jagged characters
  156.         dd    0         ; pointer to font table
  157.         db    1         ; allow EGA palette changes
  158.         db    0         ; allow VGA 256 palette changes
  159.         db    1         ; proportional font switch
  160.         dw    0ffffh         ; fillmask for lines
  161.         dw    0         ; viewport - minx
  162.         dw    0         ; viewport - miny
  163.         dw    799         ; viewport - maxx
  164.         dw    599         ; viewport - maxy
  165.         db    0         ; viewport - clipping on/off
  166.         dw    15         ; Mouse color
  167.         dw    0         ; Mouse hotspot
  168.         dw    0         ; Mouse hotspot
  169.         dd    0         ; Mouse Cursor Mask
  170.         dd    0         ; Next VideoMode
  171.  
  172. mode4:        db    15,'TWVGA800x564x16',0,0,0,0,0,0
  173.         dw    4         ; Mode Number
  174.         dw    799         ; Device Full Resolution in X
  175.         dw    563         ; Device Full Resolution in Y
  176.         dw    8         ; Standard char size X
  177.         dw    14         ; Standard char size Y
  178.         dw    15         ; Number of colors
  179.         dw    1         ; Number of pages
  180.         dw    16         ; max palette
  181.         dw    0         ; buffer offset for 2 page, Active page
  182.         dw    0A000h         ; Screen Segment
  183.         dw    100         ; bytes per line
  184.         dw    10000         ; x aspect
  185.         dw    10000         ; y aspect
  186.         dd    0         ; Driver Pointer
  187.         dd    0         ; Driver Name Pointer
  188.         dd    0         ; Driver Jump Table
  189.         dd    0         ; Graphics Work Buffer
  190.         dw    0         ; Graphics Buffer Size
  191.         dw    0         ; Read/Write modes
  192.         db    0         ; transparency on-$ff/off-$00
  193.         db    0         ; jagged characters
  194.         dd    0         ; pointer to font table
  195.         db    1         ; allow EGA palette changes
  196.         db    0         ; allow VGA 256 palette changes
  197.         db    1         ; proportional font switch
  198.         dw    0ffffh         ; fillmask for lines
  199.         dw    0         ; viewport - minx
  200.         dw    0         ; viewport - miny
  201.         dw    799         ; viewport - maxx
  202.         dw    563         ; viewport - maxy
  203.         db    0         ; viewport - clipping on/off
  204.         dw    15         ; Mouse color
  205.         dw    0         ; Mouse hotspot
  206.         dw    0         ; Mouse hotspot
  207.         dd    0         ; Mouse Cursor Mask
  208.         dd    0         ; Next VideoMode
  209.  
  210. mode5:        db    15,'TWVGA752x564x16',0,0,0,0,0,0
  211.         dw    5         ; Mode Number
  212.         dw    751         ; Device Full Resolution in X
  213.         dw    563         ; Device Full Resolution in Y
  214.         dw    8         ; Standard char size X
  215.         dw    14         ; Standard char size Y
  216.         dw    15         ; Number of colors
  217.         dw    1         ; Number of pages
  218.         dw    16         ; max palette
  219.         dw    0         ; buffer offset for 2 page, Active page
  220.         dw    0A000h         ; Screen Segment
  221.         dw    94         ; bytes per line
  222.         dw    10000         ; x aspect
  223.         dw    10000         ; y aspect
  224.         dd    0         ; Driver Pointer
  225.         dd    0         ; Driver Name Pointer
  226.         dd    0         ; Driver Jump Table
  227.         dd    0         ; Graphics Work Buffer
  228.         dw    0         ; Graphics Buffer Size
  229.         dw    0         ; Read/Write modes
  230.         db    0         ; transparency on-$ff/off-$00
  231.         db    0         ; jagged characters
  232.         dd    0         ; pointer to font table
  233.         db    1         ; allow EGA palette changes
  234.         db    0         ; allow VGA 256 palette changes
  235.         db    1         ; proportional font switch
  236.         dw    0ffffh         ; fillmask for lines
  237.         dw    0         ; viewport - minx
  238.         dw    0         ; viewport - miny
  239.         dw    751         ; viewport - maxx
  240.         dw    563         ; viewport - maxy
  241.         db    0         ; viewport - clipping on/off
  242.         dw    15         ; Mouse color
  243.         dw    0         ; Mouse hotspot
  244.         dw    0         ; Mouse hotspot
  245.         dd    0         ; Mouse Cursor Mask
  246.         dd    0         ; Next VideoMode
  247.  
  248. modeend:    dw    0ffffh         ; 0ffff - last mode
  249.  
  250.         dw   initvideomode   ; mode:word,TEGLTable:dword,initflg:byte
  251.         dw   setxlattable    ; XlatTable:dword
  252.         dw   setvideotable   ; TEGLTable:dword
  253.         dw   getvideotable   ; returns pointer to TEGLTable
  254.         dw   imagesize         ; argx1:word,argy1:word,argx2:word,argy2:word
  255.         dw   fastline         ; argx1:word,argy1:word,argx2:word,argy2:word,color:word
  256.         dw   scanborder      ; argx:word,argy:word,bordercolor:word,scan:word
  257.         dw   putpixs         ; argx:word,argy:word,color:word
  258.         dw   getpixs         ; argx:word,argy:word
  259.         dw   getbiti         ; argx0:word,argy0:word,argx1:word,argy1:word,addrbuf:dword
  260.         dw   putbiti         ; argx:word,argy:word,addrbuf:dword,rmwb:word
  261.         dw   extractimg      ; argx0:word,argy0:word,argx1:word,argy1:word,addrbuf1:dword,addrbuf2:dword
  262.         dw   overlayimg      ; argx0:word,argy0:word,addrbuf1:dword,addrbuf2:dword
  263.         dw   extractpixs     ; argx0:word,argy0:word,addrbuff:dword
  264.         dw   wrtchar         ; argc:word,argx:word,argy:word,argfgd:word
  265.         dw   mcursoroff      ;
  266.         dw   mcursoron         ; argx:word,argy:word
  267.         dw   msetpos         ; argx:word,argy:word
  268.         dw   movevideopixels ; argx0:word,argy0:word,argx1:word,argy1:word,argx2:word,argy2:word,vertlines:word,horzlines:word,spage:word,tpage:word
  269.         dw   setvpage         ; pagen:word
  270.         dw   setapage         ; pagen:word
  271.  
  272.         db   16 dup (0) ;required for driver alignment
  273.  
  274. ; 3 bytes/row * 17rows * 4 color planes + 5 byte header
  275. mcursorsavearea db   280 dup (0)
  276. mflag        dw   0
  277. scradrofs    dw   0
  278. scradrseg    dw   0
  279. TDTable     dd   0
  280. XLTable     dd   0
  281.  
  282. vesashift    db   0
  283. vga512flag    dw   ?
  284. vga1024flag    dw   ?
  285. svgatype    dw   0
  286. bankadr     dw   ?
  287.  
  288. x_cirrus    equ    1
  289. x_everex    equ    2
  290. x_paradise    equ    3
  291. x_tseng     equ    4
  292. x_trident    equ    5
  293. x_t8900     equ    6
  294. x_ativga    equ    7
  295. x_aheada    equ    8
  296. x_aheadb    equ    9
  297. x_oaktech    equ    10
  298. x_video7    equ    11
  299. x_chipstech    equ    12
  300. x_tseng4    equ    13
  301. x_genoa     equ    14
  302. x_ncr        equ    15
  303. x_compaq    equ    16
  304. x_vesa        equ    17
  305.  
  306. initvideomode    proc    far
  307.  
  308.         push    ds
  309.         push    si
  310.         lds    si,cs:TDTable
  311.         mov    bx,ds:[si].vmodenum
  312.         pop    si
  313.         pop    ds
  314.  
  315.         mov    ax,ds
  316.         or    ax,ax
  317.         mov    ax,-10
  318.         jz    initvideodone
  319.  
  320.         or    bx,bx
  321.         jnz    nxtevgamode1
  322.         call    SetEGA640x350
  323.         jmp    short initvideodone
  324.  
  325. nxtevgamode1:    cmp    bx,1
  326.         jne    nxtevgamode2
  327.         call    SetVGA640x480
  328.         jmp    short initvideodone
  329.  
  330. nxtevgamode2:    cmp    bx,2
  331.         jne    nxtevgamode3
  332.         call    SetSVGA800x600
  333.         jmp    short initvideodone
  334.  
  335. nxtevgamode3:    cmp    bx,3
  336.         jne    nxtevgamode4
  337.         call    TWVGA800x600
  338.         jmp    short initvideodone
  339.  
  340. nxtevgamode4:    cmp    bx,4
  341.         jne    nxtevgamode5
  342.         call    TWVGA800x564
  343.         jmp    short initvideodone
  344.  
  345. nxtevgamode5:    cmp    bx,5
  346.         jne    initvideodone
  347.         call    TWVGA752x564
  348.  
  349. initvideodone:    ret
  350. initvideomode    endp
  351.  
  352.  
  353. SetEGA640x350    proc    near
  354.         mov    ax,010h
  355.         int    10h
  356.         xor    ax,ax
  357.         ret
  358. SetEGA640x350    endp
  359.  
  360. SetVGA640x480    proc    near
  361.         mov    ax,012h
  362.         int    10h
  363.         xor    ax,ax
  364.         ret
  365. SetVGA640x480    endp
  366.  
  367. SetSVGA800x600    proc    near
  368.         mov    ax,cs:svgatype
  369.         cmp    ax,0
  370.         jnz    gottype
  371.  
  372.         call    whichsvga
  373.         mov    ax,cs:svgatype
  374.         cmp    ax,0
  375.  
  376. gottype:    jb    nosvga800
  377.         mov    cx,ax
  378.  
  379.         cmp    cx,x_genoa
  380.         mov    ax,79h
  381.         je    set800
  382.  
  383.         cmp    cx,x_paradise
  384.         mov    ax,58h
  385.         je    set800
  386.         cmp    cx,x_compaq
  387.         je    set800
  388.  
  389.         cmp    cx,x_ativga
  390.         mov    ax,54h
  391.         je    set800
  392.  
  393.         cmp    cx,x_everex
  394.         mov    ax,70h
  395.         mov    bl,02h
  396.         je    set800
  397.  
  398.         cmp    cx,x_trident
  399.         mov    ax,5bh
  400.         je    set800
  401.         cmp    cx,x_t8900
  402.         je    set800
  403.  
  404.         cmp    cx,x_video7
  405.         mov    ax,6f05h
  406.         mov    bl,62h
  407.         je    set800
  408.  
  409.         cmp    cx,x_chipstech
  410.         mov    ax,70h
  411.         je    set800
  412.  
  413.         cmp    cx,x_tseng4
  414.         mov    ax,29h
  415.         je    set800
  416.         cmp    cx,x_tseng
  417.         je    set800
  418.  
  419.         cmp    cx,x_aheada
  420.         mov    ax,6ah
  421.         je    set800
  422.         cmp    cx,x_aheadb
  423.         je    set800
  424.  
  425.         cmp    cx,x_oaktech
  426.         mov    ax,52h
  427.         je    set800
  428.  
  429.         cmp    cx,x_ncr
  430.         mov    ax,58h
  431.         je    set800
  432.  
  433. ;        cmp    cx,x_cirrus    ;cirrus doesn't have a 800x600(16)
  434.         mov    ax,-2
  435.         jmp    short nosvga800
  436.  
  437. set800:     int    10h
  438.         xor    ax,ax
  439. nosvga800:    ret
  440. SetSVGA800x600    endp
  441.  
  442.  
  443. crtcparm800x600 db    074h ; horisontal total time (0)
  444.         db    063h ; horisontal display end (1)
  445.         db    064h ; start horisontal blank (2)
  446.         db    097h ; end horisontal blank (3)
  447.         db    068h ; start horisontal retrace (4)
  448.         db    095h ; end horisontal retrace (5)
  449.         db    086h ; vertical total (6)
  450.         db    0F0h ; overflow register (7)
  451.         db    000h, 060h, 000h, 000h ; misc
  452.         db    000h, 000h, 002h, 085h
  453.         db    05Bh ; vertical retrace start (10)
  454.         db    08Dh ; vertical retrace end
  455.         db    057h    ; vertical display end
  456.         db    032h ; offset register
  457.         db    000h
  458.         db    060h ; start vertical blank
  459.         db    080h ; end vertical blank
  460.         db    0E3h ; mode control
  461.         db    0FFh
  462.  
  463. crtcparm800x564 db    074h ; horisontal total time (0)
  464.         db    063h ; horisontal display end (1)
  465.         db    064h ; start horisontal blank (2)
  466.         db    097h ; end horisontal blank (3)
  467.         db    068h ; start horisontal retrace (4)
  468.         db    095h ; end horisontal retrace (5)
  469.         db    062h ; vertical total (6)
  470.         db    0F0h ; overflow register (7)
  471.         db    000h, 060h, 000h, 000h ; misc
  472.         db    000h, 000h, 002h, 061h
  473.         db    037h ; vertical retrace start (10)
  474.         db    089h ; vertical retrace end
  475.         db    033h    ; vertical display end
  476.         db    032h ; offset register
  477.         db    000h
  478.         db    03Ch ; start vertical blank
  479.         db    05Ch ; end vertical blank
  480.         db    0E3h ; mode control
  481.         db    0FFh
  482.  
  483.  
  484. crtcparm752x564 db    06Eh ; horisontal total time (0)
  485.         db    05Dh ; horisontal display end (1)
  486.         db    05Eh ; start horisontal blank (2)
  487.         db    091h ; end horisontal blank (3)
  488.         db    062h ; start horisontal retrace (4)
  489.         db    08Fh ; end horisontal retrace (5)
  490.         db    062h ; vertical total (6)
  491.         db    0F0h ; overflow register (7)
  492.         db    000h, 060h, 000h, 000h ; misc
  493.         db    000h, 000h, 002h, 061h
  494.         db    037h ; vertical retrace start (10)
  495.         db    089h ; vertical retrace end
  496.         db    033h    ; vertical display end
  497.         db    02Fh ; offset register
  498.         db    000h
  499.         db    03Ch ; start vertical blank
  500.         db    05Ch ; end vertical blank
  501.         db    0E3h ; mode control
  502.         db    0FFh
  503.  
  504. TWVGA800x600    proc    near
  505.         push    ds
  506.         push    si
  507.         push    es
  508.         push    di
  509.  
  510.         lds    si,cs:TDTable
  511.         add    si,crtcparm800x600-Mode3
  512.         mov    dx,600
  513.         mov    ax,800
  514.         call    setvgaparms
  515.         xor    ax,ax
  516.  
  517.         pop    di
  518.         pop    es
  519.         pop    si
  520.         pop    ds
  521.         ret
  522. TWVGA800x600    endp
  523.  
  524.  
  525. TWVGA800x564    proc    near
  526.         push    ds
  527.         push    si
  528.         push    es
  529.         push    di
  530.  
  531.         lds    si,cs:TDTable
  532.         add    si,crtcparm800x564-Mode4
  533.         mov    dx,564
  534.         mov    ax,800
  535.         call    setvgaparms
  536.         xor    ax,ax
  537.  
  538.         pop    di
  539.         pop    es
  540.         pop    si
  541.         pop    ds
  542.         ret
  543. TWVGA800x564    endp
  544.  
  545.  
  546. TWVGA752x564    proc    near
  547.         push    ds
  548.         push    si
  549.         push    es
  550.         push    di
  551.  
  552.         lds    si,cs:TDTable
  553.         add    si,crtcparm752x564-Mode5
  554.         mov    dx,564
  555.         mov    ax,752
  556.         call    setvgaparms
  557.         xor    ax,ax
  558.  
  559.         pop    di
  560.         pop    es
  561.         pop    si
  562.         pop    ds
  563.         ret
  564. TWVGA752x564    endp
  565.  
  566.  
  567. SetVGAParms    proc    near
  568.         push    ax        ;cols
  569.         push    dx        ;rows
  570.  
  571.         mov    ax,12h        ; set video mode to 12
  572.         int    10h
  573.  
  574.         mov    ax,40h        ; Video BIOS DATA area
  575.         mov    es,ax
  576.  
  577.         pop    dx
  578.         pop    ax
  579.  
  580.         mov    cl,3
  581.         shr    ax,cl        ; div 8
  582.         shr    dx,cl        ; div 8
  583.  
  584. ;        push    ax
  585. ;        push    dx
  586. ;        mov    ax,1124h        ; load ROM 8*16 characters
  587. ;        mov    bx,0
  588. ;        mov    dh,0
  589. ;        shr    dl,1
  590. ;        int    10h
  591. ;        pop    dx
  592. ;        pop    ax
  593.  
  594.         mov    word ptr es:[4ah],ax    ;columns
  595.         mul    dl
  596.         mov    word ptr es:[4ch],ax    ;screen size
  597.  
  598.         mov    dx,word ptr es:[63h]
  599.         add    dx,6
  600. vrdly1:     in    al,dx        ; wait for vertical retrace off
  601.         test    al,8
  602.         jnz    vrdly1
  603.  
  604. vrdly2:     in    al,dx        ; wait for vertical retrace on
  605.         test    al,8
  606.         jz    vrdly2
  607.  
  608.         cli            ; turn off all interrupts
  609.         mov    dx,03c4h    ; Sequencer Synchronous reset
  610.         mov    ax,0100h    ; set sequencer reset
  611.         out    dx,ax
  612.  
  613.         mov    dx,03c2h    ; Update Misc Output Reg
  614.         mov    al,0E7h
  615.         out    dx,al
  616.  
  617.         mov    dx,03c4h    ; Sequencer Synchronous reset
  618.         mov    ax,0300h    ; clear sequencer reset
  619.         out    dx,ax
  620.  
  621.         mov    dx,word ptr es:[63h]    ; 6845
  622.         mov    al,11h            ; deprotect registers 0-7
  623.         mov    ah,byte ptr ds:[si+11h]
  624.         and    ah,7fh
  625.         out    dx,ax
  626.  
  627.         mov    cx,18h
  628.         mov    bx,0
  629. crtcloop:    mov    al,bl
  630.         mov    ah,byte ptr ds:[bx+si]
  631.         out    dx,ax
  632.         inc    bx
  633.         loop    crtcloop
  634.         sti
  635.         ret
  636. SetVGAParms    endp
  637.  
  638.  
  639.  
  640.  
  641.  
  642. setxlattable    proc    far XlatTable:dword
  643.         push    es
  644.         push    di
  645.  
  646.         les    di,XlatTable
  647.         mov    word ptr cs:XLTable,di
  648.         mov    word ptr cs:XLTable+2,es
  649.  
  650.         pop    di
  651.         pop    es
  652.         ret
  653. setxlattable    endp
  654.  
  655.  
  656. setvideotable    proc    far TEGLTable:dword
  657.         push    es
  658.         push    di
  659.  
  660.         les    di,TEGLTable
  661.         mov    word ptr cs:TDTable,di
  662.         mov    word ptr cs:TDTable+2,es
  663.  
  664.         pop    di
  665.         pop    es
  666.         ret
  667. setvideotable    endp
  668.  
  669. getvideotable    proc    far
  670.  
  671.         mov    ax,word ptr cs:TDTable
  672.         mov    dx,word ptr cs:TDTable+2
  673.  
  674.         ret
  675. getvideotable    endp
  676.  
  677. imagesize    proc    far argx1:word,argy1:word,argx2:word,argy2:word
  678.         push    bx
  679.  
  680.         mov    ax,argx2            ;x1-x+1
  681.         sub    ax,argx1
  682.         inc    ax
  683.  
  684.         mov    dx,ax
  685.         mov    cl,3                ; /8
  686.         shr    ax,cl
  687.  
  688.         and    dl,07h                ;check for byte
  689.         jz    hisz01                ;boundary
  690.         inc    ax
  691. hisz01:     mov    bx,argy2            ;y1-y+1
  692.         sub    bx,argy1
  693.         inc    bx
  694.         mul    bx                ;rows * bytes per row
  695.  
  696.         shl    ax,1                ;multiply by 4
  697.         rcl    dx,1
  698.         shl    ax,1
  699.         rcl    dx,1
  700.  
  701.         add    ax,6                ;add 6 for header
  702.         adc    dx,0
  703.  
  704.         pop    bx
  705.         ret
  706. imagesize    endp
  707.  
  708.  
  709. fastline    proc    far argx1:word,argy1:word,argx2:word,argy2:word,color:word
  710.         local    varvertincr:word,varincr1:word,varincr2:word,varroutine:word
  711.         local    rmwb:word,fillmask:byte,bpline:word,transparent:byte
  712.  
  713.         push    ds
  714.         push    si
  715.         push    es
  716.         push    di
  717.  
  718.         cld
  719.  
  720.         lds    si,cs:TDtable
  721.         mov    ax,ds:[si].rmwbits
  722.         mov    rmwb,ax
  723.  
  724.         mov    ax,ds:[si].vbytesperline
  725.         mov    bpline,ax
  726.  
  727.         mov    ax,ds:[si].teglfillmask
  728.         mov    fillmask,al
  729.  
  730.         mov    al,ds:[si].transparency
  731.         mov    transparent,al
  732.  
  733. ; configure the graphics controller
  734.  
  735.         mov    dx,3ceh     ; dx := graphics controller port addr
  736.  
  737.         mov    ah,byte ptr [color] ; ah := pixel value
  738.         xor    al,al        ; al := set/reset register number
  739.         out    dx,ax
  740.  
  741.         mov    ax,0f01h    ; ah := 1111b (bit plane mask for
  742.                     ;  enable set/reset
  743.         out    dx,ax        ; al := enable set/reset register #
  744.  
  745.         mov    ah,byte ptr [rmwb] ; bits 3 and 4 of ah := function
  746.         mov    al,3        ; al := data rotate/func select reg #
  747.         out    dx,ax
  748.  
  749. ; check for vertical line
  750.  
  751.         mov    si,bpline    ; increment for video buffer
  752.  
  753.         mov    cx,argx2
  754.         sub    cx,argx1    ; cx := x2 - x1
  755.         jnz    nvertline10    ; jump if not vertical line
  756.  
  757.  
  758. ; routine for vertical lines
  759.         mov    ax,argy1    ; ax := y1
  760.         mov    bx,argy2    ; bx := y2
  761.         mov    cx,bx
  762.         sub    cx,ax        ; cx := dy
  763.         jge    l31        ; jump if dy >= 0
  764.  
  765.         neg    cx        ; force dy >= 0
  766.         mov    ax,bx        ; ax := y2
  767.  
  768. l31:        inc    cx        ; cx := # of pixels to draw
  769.         mov    bx,argx1    ; bx := x
  770.         push    cx        ; preserve this register
  771.         call    activeaddr    ; ah := bit mask
  772.                     ; es:bx -> video buffer
  773.                     ; cl := # bits to shift left
  774. ; set up graphics controller
  775.  
  776.         shl    ah,cl        ; ah := bit mask in proper position
  777.         rol    fillmask,cl    ; ***********fillmask
  778. ;        rol    fillmask,1    ; ***********fillmask
  779.  
  780.         mov    al,8        ; al := bit mask reg number
  781.         out    dx,ax
  782.  
  783.         pop    cx        ; restore this register
  784.  
  785. ; draw the line
  786.  
  787. l32:        test    ah,fillmask
  788.         jz    l32a
  789.         or    es:[bx],al    ; set pixel
  790. l32a:        add    bx,si        ; increment to next line
  791. ;        rol    fillmask,1
  792.         ror    fillmask,1
  793.         loop    l32
  794.  
  795.         jmp    lexit
  796.  
  797.  
  798. ; force x1 < x2
  799.  
  800. nvertline10:    jns    l01        ; jump if x2 > x1
  801.  
  802.         neg    cx        ; cx := x1 - x2
  803.  
  804.         mov    bx,argx2    ; exchange x1 and x2
  805.         xchg    bx,argx1
  806.         mov    argx2,bx
  807.  
  808.         mov    bx,argy2    ; exchange y1 and y2
  809.         xchg    bx,argy1
  810.         mov    argy2,bx
  811.  
  812. ; calculate dy = abs(y2-y1)
  813.  
  814. l01:        mov    bx,argy2
  815.         sub    bx,argy1    ; bx := y2 - y1
  816.         jz    horizline10    ; jump if horizontal line
  817.  
  818.         jns    l03        ; jump if slope is positive
  819.  
  820.         neg    bx        ; bx := y1 - y2
  821.         neg    si        ; negate increment for buffer interleave
  822.  
  823. ; select appropriate routine for slope of line
  824.  
  825. l03:        mov    varvertincr,si    ; save vertical increment
  826.  
  827.         mov    varroutine,0
  828.         cmp    bx,cx
  829.         jle    l04        ; jump if dy <= dx (slope <= 1)
  830.         mov    varroutine,1
  831.         xchg    bx,cx        ; exchange dy and dx
  832.  
  833. ; calculate initial decision variable and increments
  834.  
  835. l04:        shl    bx,1        ; bx := 2 * dy
  836.         mov    varincr1,bx    ; incr1 := 2 * dy
  837.         sub    bx,cx
  838.         mov    si,bx        ; si := d = 2 * dy - dx
  839.         sub    bx,cx
  840.         mov    varincr2,bx    ; incr2 := 2 * (dy - dx)
  841.  
  842. ; calculate first pixel address
  843.  
  844.         push    cx        ; preserve this register
  845.         mov    ax,argy1    ; ax := y
  846.         mov    bx,argx1    ; bx := x
  847.         call    activeaddr    ; ah := bit mask
  848.                     ; es:bx -> buffer
  849.                     ; cl := # bits to shift left
  850.  
  851.         rol    fillmask,cl    ; ***********fillmask
  852. ;        ror    fillmask,1    ; ***********fillmask
  853.  
  854.         mov    di,bx        ; es:di -> buffer
  855.         shl    ah,cl        ; ah := bit mask in proper position
  856.         mov    bl,ah        ; ah,bl := bit mask
  857.         mov    al,8        ; al := bit mask register number
  858.  
  859.         pop    cx        ; restore this register
  860.         inc    cx        ; cx := # of pixels to draw
  861.  
  862.         test    varroutine,1    ; jump to appropriate routine for slope
  863.         jnz    jmphislopeline
  864.         jmp    loslopeline10
  865. jmphislopeline: jmp    hislopeline10
  866.  
  867.  
  868.  
  869.  
  870. ; routine for horizontal lines (slope = 0)
  871.  
  872. horizline10:
  873.         push    ds        ; preserve ds
  874.  
  875.         mov    ax,argy1
  876.         mov    bx,argx1
  877.         call    activeaddr    ; ah := bit mask
  878.                     ; es:bx -> video buffer
  879.                     ; cl := # bits to shift left
  880.         mov    di,bx        ; es:di -> buffer
  881.  
  882.         mov    dh,ah        ; dh := unshifted bit mask for leftmost
  883.                     ;     byte
  884.         not    dh
  885.         shl    dh,cl        ; dh := reverse bit mask for first byte
  886.         not    dh        ; dh := bit mask for first byte
  887.  
  888.         test    transparent,0ffh
  889.         jnz    backfill    ; leave the mask alone if pattern fill
  890.         ror    fillmask,cl    ; ***********fillmask
  891.         ror    fillmask,1    ; ***********fillmask
  892.  
  893. backfill:    mov    cx,argx2
  894.         and    cl,7
  895.         xor    cl,7        ; cl := number of bits to shift left
  896.         mov    dl,0ffh     ; dl := unshifted bit mask for
  897.                     ;     rightmost byte
  898.         shl    dl,cl        ; dl := bit mask for last byte
  899.  
  900. ; determine byte offset of first and last pixel in the line
  901.  
  902.         mov    ax,argx2    ; ax := x2
  903.         mov    bx,argx1    ; bx := x1
  904.  
  905.         mov    cl,3        ; number of bits to shift to
  906.                         ;  convert pixels to bytes
  907.  
  908.         shr    ax,cl        ; ax := byte offset of x2
  909.         shr    bx,cl        ; bx := byte offset of x1
  910.         mov    cx,ax
  911.         sub    cx,bx        ; cx := (# bytes in line) - 1
  912.  
  913. ; get graphics controller port address into dx
  914.  
  915.         mov    bx,dx        ; bh := bit mask for first byte
  916.                     ; bl := bit mask for last byte
  917.         mov    dx,3ceh     ; dx := graphics controller port
  918.         mov    al,8        ; al := bit mask register number
  919.  
  920. ; make video buffer addressible through ds:si
  921.  
  922.         push    es
  923.         pop    ds
  924.         mov    si,di        ; ds:si -> video buffer
  925.  
  926.         push    di
  927.         push    cx
  928.  
  929. ; set pixels in leftmost byte of the line
  930.  
  931.         or    bh,bh
  932.         js    l43        ; jump if byte-aligned (x1 is leftmost
  933.                     ;  pixel in byte)
  934.         or    cx,cx
  935.         jnz    l42        ; jump if more than one byte in the line
  936.  
  937.         and    bl,bh        ; bl := bit mask for the line
  938.         jmp    short l44
  939.  
  940. l42:        mov    ah,bh        ; ah := bit mask for 1st byte
  941.         and    ah,fillmask
  942.         out    dx,ax        ; update graphics controller
  943.  
  944.         movsb            ; update bit planes
  945.         dec    cx
  946.  
  947. ; use a fast 8086 machine instruction to draw the remainder of the line
  948.  
  949. l43:        mov    ah,11111111b    ; ah := bit mask
  950.         and    ah,fillmask
  951.         out    dx,ax        ; update bit mask register
  952.  
  953.         rep    movsb        ; update all pixels in the line
  954.  
  955. ; set pixels in the rightmost byte of the line
  956.  
  957. l44:        mov    ah,bl        ; ah := bit mask for last byte
  958.         and    ah,fillmask
  959.         out    dx,ax        ; update graphics controller
  960.  
  961.         movsb            ; update bit planes
  962.  
  963.  
  964. ;---------
  965. ;   es:di/ds:si - pointer to same video buffer address
  966. ;   bx        - bh/bl - bit mask for first/last byte
  967. ;   dx        - 3ceh graphics controller port
  968. ;   cx        - number of bytes to write
  969. ;   al        - contains 8 - bit mask register number
  970. ;---------
  971.         pop    cx
  972.         pop    di
  973.  
  974.         test    transparent,0ffh
  975.         jz    oksolid
  976.         cmp    fillmask,0ffh
  977.         jz    oksolid
  978.  
  979.         mov    si,di
  980.         xor    ax,ax        ; ah := black
  981.         out    dx,ax        ; al := set/reset register number
  982.         not    fillmask
  983.         mov    al,8
  984.  
  985. ; set pixels in leftmost byte of the line
  986.         or    bh,bh
  987.         js    l43f        ; jump if byte-aligned (x1 is leftmost
  988.                     ;  pixel in byte)
  989.         or    cx,cx
  990.         jnz    l42f        ; jump if more than one byte in the line
  991.  
  992.         and    bl,bh        ; bl := bit mask for the line
  993.         jmp    short l44f
  994.  
  995. l42f:        mov    ah,bh        ; ah := bit mask for 1st byte
  996.         and    ah,fillmask
  997.         out    dx,ax        ; update graphics controller
  998.  
  999.         movsb            ; update bit planes
  1000.         dec    cx
  1001.  
  1002. ; use a fast 8086 machine instruction to draw the remainder of the line
  1003.  
  1004. l43f:        mov    ah,11111111b    ; ah := bit mask
  1005.         and    ah,fillmask
  1006.         out    dx,ax        ; update bit mask register
  1007.  
  1008.         rep    movsb        ; update all pixels in the line
  1009.  
  1010. ; set pixels in the rightmost byte of the line
  1011.  
  1012. l44f:        mov    ah,bl        ; ah := bit mask for last byte
  1013.         and    ah,fillmask
  1014.         out    dx,ax        ; update graphics controller
  1015.  
  1016.         movsb            ; update bit planes
  1017.  
  1018.  
  1019. oksolid:    pop    ds        ; restore ds
  1020.         jmp    lexit
  1021.  
  1022.  
  1023. ;---------
  1024. ; routine for dy <= dx (slope <= 1)    ; es:di -> video buffer
  1025.                     ; al = bit mask register number
  1026.                     ; bl = bit mask for 1st pixel
  1027.                     ; cx = #pixels to draw
  1028.                     ; dx = graphics controller port addr
  1029.                     ; si = decision variable
  1030. loslopeline10:
  1031.  
  1032. l10:        mov    ah,bl        ; ah := bit mask for next pixel
  1033.  
  1034. l11:        or    ah,bl        ; mask current pixel position
  1035.         ror    bl,1        ; rotate pixel value
  1036.         jc    l14        ; jump if bit mask rotated to
  1037.                     ;  leftmost pixel position
  1038.  
  1039. ; bit mask not shifted out
  1040.  
  1041.         or    si,si        ; test sign of d
  1042.         jns    l12        ; jump if d >= 0
  1043.  
  1044.         add    si,varincr1    ; d := d + incr1
  1045.         loop    l11
  1046.  
  1047.         and    ah,fillmask    ; ***********fillmask
  1048.         out    dx,ax        ; update bit mask register
  1049.         or    es:[di],al    ; set remaining pixel(s)
  1050.         jmp    short lexit
  1051.  
  1052. l12:        add    si,varincr2    ; d := d + incr2
  1053.         mov    bh,ah
  1054.         and    ah,fillmask    ; ***********fillmask
  1055.         out    dx,ax        ; update bit mask register
  1056.  
  1057.         or    es:[di],al    ; update bit planes
  1058.         mov    ah,bh
  1059.  
  1060.         add    di,varvertincr    ; increment y
  1061.         loop    l10
  1062.         jmp    short lexit
  1063.  
  1064. ; bit mask shifted out
  1065.  
  1066. l14:        mov    bh,ah        ; ***********fillmask
  1067.         and    ah,fillmask    ; ***********fillmask
  1068.         out    dx,ax        ; update bit mask register ...
  1069.         mov    ah,bh
  1070.  
  1071.         or    es:[di],al    ; update bit planes
  1072.         inc    di        ; increment x
  1073.  
  1074.         or    si,si        ; test sign of d
  1075.         jns    l15        ; jump if non-negative
  1076.  
  1077.         add    si,varincr1    ; d := d + incr1
  1078.         loop    l10
  1079.         jmp    short lexit
  1080.  
  1081. l15:        add    si,varincr2    ; d := d + incr2
  1082.         add    di,varvertincr    ; vertical increment
  1083.         loop    l10
  1084.         jmp    short lexit
  1085.  
  1086.  
  1087. ; routine for dy > dx (slope > 1)    ; es:di -> video buffer
  1088.                     ; ah = bit mask for 1st pixel
  1089.                     ; al = bit mask register number
  1090.                     ; cx = #pixels to draw
  1091.                     ; dx = graphics controller port addr
  1092.                     ; si = decision variable
  1093. hislopeline10:
  1094. ;        mov    bx,varvertincr    ; bx := y-increment
  1095.  
  1096. l21:        mov    bh,ah
  1097.         and    ah,fillmask    ; ***********fillmask
  1098.         out    dx,ax        ; update bit mask register
  1099.         or    es:[di],al    ; update bit planes
  1100.         mov    ah,bh
  1101.  
  1102.         add    di,varvertincr    ; increment y
  1103. ;        add    di,bx        ; increment y
  1104.  
  1105. l22:        or    si,si        ; test sign of d
  1106.         jns    l23        ; jump if d >= 0
  1107.  
  1108.         add    si,varincr1    ; d := d + incr1
  1109.         loop    l21
  1110.         jmp    short lexit
  1111.  
  1112.  
  1113. l23:        add    si,varincr2    ; d := d + incr2
  1114.  
  1115.         ror    ah,1        ; rotate bit mask
  1116.         adc    di,0        ; increment di if when mask rotated to
  1117.                     ;  leftmost pixel position
  1118.  
  1119.         loop    l21
  1120.  
  1121.  
  1122. ; restore default graphics controller state and return to caller
  1123.  
  1124. lexit:        xor    ax,ax        ; ah := 0, al := 0
  1125.         out    dx,ax        ; restore set/reset register
  1126.  
  1127.         inc    ax        ; ah := 0, al := 1
  1128.         out    dx,ax        ; restore enable set/reset register
  1129.  
  1130.         mov    al,3        ; ah := 0, al := 3
  1131.         out    dx,ax        ; al := data rotate/func select reg #
  1132.  
  1133.         mov    ax,0ff08h    ; ah := 1111111b, al := 8
  1134.         out    dx,ax        ; restore bit mask register
  1135.  
  1136.         pop    di
  1137.         pop    es
  1138.         pop    si
  1139.         pop    ds
  1140.         ret
  1141.  
  1142. fastline    endp
  1143.  
  1144.  
  1145. putpixs     proc    far argx:word,argy:word,color:word
  1146.         local    rmwb:word
  1147.  
  1148.         push    ds
  1149.         push    si
  1150.         push    es
  1151.         push    di
  1152.  
  1153.         lds    si,cs:TDtable
  1154.         mov    ax,ds:[si].rmwbits
  1155.         mov    rmwb,ax
  1156.  
  1157.         mov    al,ds:[si].clipped
  1158.         or    al,al
  1159.         jz    noclippix
  1160.  
  1161.         mov    ax,ds:[si].wminy
  1162.         cmp    argy,ax
  1163.         jl    noputpixs
  1164.  
  1165.         mov    ax,ds:[si].wmaxy
  1166.         cmp    argy,ax
  1167.         jg    noputpixs
  1168.  
  1169.         mov    ax,ds:[si].wminx
  1170.         cmp    argx,ax
  1171.         jl    noputpixs
  1172.  
  1173.         mov    ax,ds:[si].wmaxx
  1174.         cmp    argx,ax
  1175.         jg    noputpixs
  1176.  
  1177. noclippix:    mov    ax,argy     ; ax := y
  1178.         mov    bx,argx     ; bx := x
  1179.         call    activeaddr    ; ah := bit mask
  1180.                     ; es:bx -> buffer
  1181.                     ; cl := # bits to shift left
  1182.  
  1183. ; set graphics controller bit mask register
  1184.  
  1185.         shl    ah,cl        ; ah := bit mask in proper position
  1186.         mov    dx,3ceh     ; gc address register port
  1187.         mov    al,8        ; al := bit mask register number
  1188.         out    dx,ax
  1189.  
  1190. ; set graphics controller mode register
  1191.  
  1192.         mov    ax,205h     ; al :=  mode register number
  1193.                     ; ah :=  write mode 2 (bits 0,1)
  1194.                     ;     read mode 0 (bit 3)
  1195.         out    dx,ax
  1196.  
  1197. ; set data rotate/function select register
  1198.  
  1199.         mov    ah,byte ptr [rmwb] ; ah := read-modify-write bits
  1200.         mov    al,3        ; al := data rotate/function select reg
  1201.         out    dx,ax
  1202.  
  1203. ; set the pixel value
  1204.  
  1205.         mov    al,es:[bx]    ; latch one byte from each bit plane
  1206.         mov    al,byte ptr [color] ; al := pixel value
  1207.         mov    es:[bx],al    ; update all bit planes
  1208.  
  1209. ; restore default graphics controller registers
  1210.  
  1211.         mov    ax,0ff08h    ; default bit mask
  1212.         out    dx,ax
  1213.  
  1214.         mov    ax,0005     ; default mode register
  1215.         out    dx,ax
  1216.  
  1217.         mov    ax,0003     ; default function select
  1218.         out    dx,ax
  1219.  
  1220. noputpixs:    pop    di
  1221.         pop    es
  1222.         pop    si
  1223.         pop    ds
  1224.         ret
  1225.  
  1226. putpixs     endp
  1227.  
  1228.  
  1229. scanborder    proc    far argx:word,argy:word,bordercolor:word,scan:word
  1230.         local    swminx:word,swmaxx:word,bwminx:word,bwmaxx:word
  1231.         push    ds
  1232.         push    si
  1233.         push    es
  1234.         push    di
  1235.  
  1236.         mov    cl,3
  1237.         lds    si,cs:TDtable
  1238.         mov    ax,ds:[si].wminx
  1239.         mov    swminx,ax
  1240.         shr    ax,cl
  1241.         mov    bwminx,ax
  1242.         mov    ax,ds:[si].wmaxx
  1243.         mov    swmaxx,ax
  1244.         shr    ax,cl
  1245.         mov    bwmaxx,ax
  1246.  
  1247.  
  1248.         mov    ax,argy     ; ax := y
  1249.         xor    bx,bx        ; bx := x = 0
  1250.         call    activeaddr    ; ah := bit mask
  1251.                     ; es:bx -> buffer
  1252.                     ; cl := #bits to shift
  1253.         mov    di,bx        ; es:di -> buffer
  1254.  
  1255.         mov    ax,argx
  1256.         mov    si,ax
  1257.         mov    cl,3
  1258.         shr    si,cl
  1259.         add    di,si
  1260.  
  1261.  
  1262.         mov    dx,3ceh     ; dx := graphics controller port
  1263.         mov    ah,byte ptr [bordercolor]  ; ah := color for comparing
  1264.         mov    al,2        ; al := color compare register
  1265.         out    dx,ax
  1266.  
  1267.         mov    ax,805h     ; ah := 00001000b (read mode 1)
  1268.         out    dx,ax        ; al := mode reg number
  1269.  
  1270.         mov    ax,0f07h    ; ah := 00000111b (color compare reg)
  1271.         out    dx,ax
  1272.  
  1273.         test    scan,8000h
  1274.         jz    forwscan
  1275.  
  1276.         ; inspect first byte
  1277. backscan:    mov    cx,argx         ;create mask to check
  1278.         not    cl            ;first byte
  1279.         and    cl,7
  1280.         mov    ch,0ffh
  1281.         shl    ch,cl
  1282.  
  1283.         mov    al,es:[di]
  1284.         dec    di
  1285.         and    al,ch
  1286.         jnz    scanl05
  1287.  
  1288.         ;scan remainder of line for border pixels
  1289.         mov    cx,si
  1290.         inc    cx
  1291.         sub    cx,bwminx
  1292.         jle    scanl05
  1293.         jcxz    scanl05
  1294.  
  1295.         std
  1296.         repe    scasb
  1297.         mov    al,es:[di+1]
  1298.         cld
  1299.  
  1300. scanl05:    sub    di,bx
  1301.         inc    di
  1302.         mov    cl,3
  1303.         shl    di,cl
  1304.         mov    cx,7
  1305.  
  1306. scanl06:    shr    al,1
  1307.         jc    scanl07
  1308.         loop    scanl06
  1309.  
  1310. scanl07:    add    di,cx
  1311.         jmp    scanl08
  1312.  
  1313.  
  1314.  
  1315.         ; inspect first byte
  1316. forwscan:    mov    cx,argx         ;create mask to check
  1317.         and    cl,7            ;first byte
  1318.         mov    ch,0ffh
  1319.         shr    ch,cl
  1320.  
  1321.         mov    al,es:[di]
  1322.         inc    di
  1323.         and    al,ch
  1324.         jnz    scanl01
  1325.  
  1326.         ;scan remainder of line for border pixels
  1327.  
  1328.         mov    cx,bwmaxx
  1329.         inc    cx
  1330.         sub    cx,si
  1331.         jle    scanl01
  1332.         jcxz    scanl01
  1333.         dec    cx
  1334.  
  1335.         cld
  1336.         repe    scasb
  1337.         mov    al,es:[di-1]
  1338.  
  1339. scanl01:    sub    di,bx
  1340.         mov    cl,3
  1341.         shl    di,cl
  1342.         mov    cx,8
  1343.  
  1344. scanl02:    shl    al,1
  1345.         jc    scanl03
  1346.         loop    scanl02
  1347.  
  1348. scanl03:    sub    di,cx
  1349.  
  1350. scanl08:    mov    ax,2
  1351.         out    dx,ax
  1352.  
  1353.         mov    al,5
  1354.         out    dx,ax
  1355.  
  1356.         mov    ax,swminx
  1357.         dec    ax
  1358.         cmp    di,ax
  1359.         jle    scanl04
  1360.         mov    ax,swmaxx
  1361.         inc    ax
  1362.         cmp    di,ax
  1363.         jge    scanl04
  1364.  
  1365.         mov    ax,di
  1366. scanl04:
  1367.         pop    di
  1368.         pop    es
  1369.         pop    si
  1370.         pop    ds
  1371.         ret
  1372. scanborder    endp
  1373.  
  1374.  
  1375. getpixs     proc    far argx:word,argy:word
  1376.         push    si
  1377.  
  1378.         mov    ax,argy     ; ax := y
  1379.         mov    bx,argx     ; bx := x
  1380.         call    activeaddr    ; ah := bit mask
  1381.                     ; es:bx -> buffer
  1382.                     ; cl := #bits to shift
  1383.  
  1384.         mov    ch,ah
  1385.         shl    ch,cl        ; ch := bit mask in proper position
  1386.  
  1387.         mov    si,bx        ; es:si -> regen buffer byte
  1388.         xor    bl,bl        ; bl is used to accumulate the pixel value
  1389.  
  1390.         mov    dx,3ceh     ; dx := graphics controller port
  1391.         mov    ax,304h     ; ah := initial bit plane number
  1392.                     ; al := read map select register number
  1393.  
  1394. getpl01:    out    dx,ax        ; select bit plane
  1395.         mov    bh,es:[si]    ; bh := byte from current bit plane
  1396.         and    bh,ch        ; mask one bit
  1397.         neg    bh        ; bit 7 of bh := 1 (if masked bit = 1)
  1398.                     ; bit 7 of bh := 0 (if masked bit = 0)
  1399.         rol    bx,1        ; bit 0 of bl := next bit from pixel value
  1400.         dec    ah        ; ah := next bit plane number
  1401.         jge    getpl01
  1402.  
  1403.         mov    al,bl        ; al := pixel value
  1404.         xor    ah,ah        ; ax := pixel value
  1405.         pop    si
  1406.         ret
  1407. getpixs     endp
  1408.  
  1409.  
  1410. getbiti     proc    far argx0:word,argy0:word,argx1:word,argy1:word,addrbuf:dword
  1411.         local    varpixelrows:word,varpixelrowlen:word,bpline:word,varpixelcontlen:word
  1412.  
  1413.         push    ds
  1414.         push    si
  1415.         push    di
  1416.  
  1417.         cld
  1418.  
  1419.         lds    si,cs:TDtable
  1420.         mov    ax,ds:[si].vbytesperline
  1421.         mov    bpline,ax
  1422.  
  1423. ; compute dimensions of bit block
  1424.  
  1425.         mov    ax,argx1
  1426.         sub    ax,argx0
  1427.         mov    cx,0ff07h
  1428.  
  1429.         and    cl,al
  1430.  
  1431.         xor    cl,7
  1432.         shl    ch,cl
  1433.         mov    cl,ch
  1434.         push    cx
  1435.  
  1436.         mov    cl,3
  1437.         shr    ax,cl
  1438.         inc    ax
  1439.         push    ax
  1440.  
  1441.         mov    ax,argy1
  1442.         sub    ax,argy0
  1443.         inc    ax
  1444.         push    ax
  1445.  
  1446. ; establish addressing
  1447.  
  1448.         mov    ax,argy0
  1449.         mov    bx,argx0
  1450.         call    activeaddr
  1451.         xor    cl,7
  1452.         push    es
  1453.         pop    ds
  1454.         mov    si,bx
  1455.  
  1456.         les    di,addrbuf
  1457.  
  1458. ; build 5-byte bit block header
  1459.  
  1460.         pop    ax
  1461.         mov    varpixelrows,ax
  1462.         stosw
  1463.         pop    ax
  1464.         mov    varpixelrowlen,ax
  1465.         stosw
  1466.         pop    ax
  1467.         mov    ch,al
  1468.         stosb
  1469.  
  1470. ; set up graphics controller
  1471.  
  1472.         mov    dx,3ceh     ; dx := graphics controller i/o port
  1473.  
  1474.         mov    ax,0005     ; ah := 0 (read mode 0, write mode 0)
  1475.         out    dx,ax        ; al := 5 (mode register)
  1476.  
  1477.         mov    ax,0304h    ; ah := 3 (plane #3)
  1478. ;        mov    ax,0004h    ; ah := 3 (plane #3)
  1479.                     ; al := 4 (read map select)
  1480.  
  1481.         mov    bx,bpline
  1482.         sub    bx,varpixelrowlen
  1483.         mov    varpixelcontlen,bx
  1484.  
  1485.         or    cl,cl        ; bit shifts?
  1486.         jnz    getbl06
  1487.  
  1488. ; copy from video buffer to system ram
  1489. ; routine for byte-aligned bit blocks
  1490.  
  1491.         mov    cx,varpixelrowlen
  1492. ;        shr    cx,1        ; divide by 2
  1493.  
  1494. getbl01:    out    dx,ax
  1495.         push    si
  1496.         mov    bx,varpixelrows
  1497.  
  1498. getbl02:    push    cx
  1499.  
  1500.         shr    cx,1
  1501.         rep    movsw
  1502.         adc    cx,0
  1503.         rep    movsb
  1504.  
  1505. getbl04:    pop    cx
  1506.         add    si,varpixelcontlen
  1507.  
  1508.         dec    bx
  1509.         jnz    getbl02
  1510.  
  1511.         normalize es,di,si    ;pointer to stored bit block
  1512.                     ;use si as temporary storage
  1513.         pop    si
  1514.         dec    ah
  1515.         jns    getbl01
  1516.  
  1517.         jmp    lexit1
  1518.  
  1519.  
  1520. ; copy from video buffer to system ram
  1521. ; routine for non-aligned bit blocks
  1522.  
  1523. getbl06:    out    dx,ax            ;next bit plane
  1524.         push    ax            ;save ax - plane & register
  1525.         push    dx            ;save dx - controller
  1526.         push    si            ;save si - start of bit block
  1527.  
  1528.         mov    dx,varpixelrows
  1529. getbl07:    mov    bx,varpixelrowlen
  1530.  
  1531. getbl08:    lodsw                ;ax - used for rotating pixels
  1532.         dec    si
  1533.         rol    ax,cl
  1534.         stosb
  1535.  
  1536.         dec    bx
  1537.         jnz    getbl08
  1538.  
  1539.         add    si,varpixelcontlen
  1540.         dec    dx
  1541.         jnz    getbl07
  1542.  
  1543.         normalize es,di,si    ;pointer to stored bit block
  1544.                     ;use si as temporary storage
  1545.  
  1546.         pop    si
  1547.         pop    dx
  1548.         pop    ax
  1549.         dec    ah
  1550.         jns    getbl06
  1551.  
  1552. lexit1:     pop    di
  1553.         pop    si
  1554.         pop    ds
  1555.         ret
  1556.  
  1557. getbiti     endp
  1558.  
  1559.  
  1560. putbiti     proc    far argx:word,argy:word,addrbuf:dword,rmwb:word
  1561.         local    varpixelrows:word,varpixelrowlen:word
  1562.         local    varstartmask:word,varrowcount:word
  1563.         local    varendmaskl:word,varendmaskr:word,bpline:word
  1564.  
  1565.         ; rmwbits -   normalput        00h
  1566.         ;          xorput           18h
  1567.         ;          orput           10h
  1568.         ;          andput           08h
  1569.         ;          notput           80h
  1570.  
  1571.         push    ds
  1572.         push    si
  1573.         push    di
  1574.  
  1575.         cld
  1576.         lds    si,cs:TDtable
  1577.         mov    ax,ds:[si].vbytesperline
  1578.         mov    bpline,ax
  1579.  
  1580. ; extablish addressing
  1581.  
  1582.         mov    ax,argy
  1583.         mov    bx,argx
  1584.         call    activeaddr
  1585.         inc    cl
  1586.         and    cl,7
  1587.         mov    di,bx
  1588.  
  1589.         lds    si,addrbuf
  1590.  
  1591. ; obtain dimensions of bit block from header
  1592.  
  1593.         lodsw
  1594.         mov    varpixelrows,ax
  1595.         lodsw
  1596.         mov    varpixelrowlen,ax
  1597.         lodsb
  1598.         mov    ch,al
  1599.  
  1600. ; set up graphics controller
  1601.  
  1602.         mov    dx,3ceh     ; dx := graphics controller i/o port
  1603.  
  1604.         mov    ah,byte ptr [rmwb] ; ah := value for data rotate/function
  1605.         and    ah,18h
  1606.         mov    al,3        ;    select register
  1607.         out    dx,ax        ; 18h is xor
  1608.  
  1609.         mov    ax,0805h    ; ah := 8 (read mode 1, write mode 0)
  1610.         out    dx,ax        ; al := 5 (mode register)
  1611.  
  1612.         mov    ax,0007     ; ah := 0 (don't care for all maps;
  1613.         out    dx,ax        ;   cpu reads always return 0ffh)
  1614.                     ; al := 7 (color don't care reg number)
  1615.  
  1616.         mov    ax,0ff08h    ; ah := 0ffh (value for bit mask reg)
  1617.         out    dx,ax        ; set up bit mask reg
  1618.  
  1619.         mov    dl,0c4h     ; dx := 3c4h (sequence i/o port)
  1620.  
  1621.         mov    ax,0802h    ; ah := 1000b (value for map mask reg)
  1622.                     ; al := 2 (map mask register number)
  1623.  
  1624.         cmp    byte ptr [rmwb],18h
  1625.         jne    putbl09
  1626.         jmp    putbl15
  1627.  
  1628. putbl09:    or    cl,cl        ; check if we need to shift the image
  1629.         jne    putbl15     ; if so then everything in image
  1630.                     ; needs to shifted
  1631.  
  1632.         ; otherwise we will use fast byte-aligned block moves
  1633.         ; routine for byte-aligned bit blocks
  1634.  
  1635.         mov    byte ptr [varendmaskl],ch  ; save the mask if not 0ffh
  1636.         test    ch,1        ; check if right side is even
  1637.         mov    cx,varpixelrowlen
  1638.         jnz    putbl10
  1639.         dec    cx
  1640.  
  1641. putbl10:    out    dx,ax
  1642.         push    ax
  1643.         push    di
  1644.         mov    bx,varpixelrows
  1645.  
  1646. putbl11:    push    di
  1647.         push    cx
  1648.  
  1649.         test    byte ptr [rmwb],80h
  1650.         jz    normal
  1651.  
  1652.         shr    cx,1        ; divide by 2
  1653.         jcxz    putbl12a
  1654. notnorm:    lodsw
  1655.         not    ax
  1656.         stosw
  1657.         loop    notnorm
  1658. putbl12a:    lodsb
  1659.         not    al
  1660.         jnc    putbl12b
  1661.         stosb
  1662.         lodsb
  1663.         not    al
  1664.         jmp    short putbl12b
  1665.  
  1666. normal:     shr    cx,1
  1667.         rep    movsw
  1668.         adc    cx,0
  1669.         rep    movsb
  1670.         lodsb
  1671.  
  1672. putbl12b:    dec    si
  1673.         mov    cl,byte ptr [varendmaskl]
  1674.         test    cl,1
  1675.         jnz    putbl13
  1676.  
  1677.         inc    si
  1678.  
  1679.         xchg    cl,al
  1680.         mov    ah,al
  1681.         mov    al,8
  1682.         mov    dl,0ceh
  1683.         out    dx,ax
  1684.  
  1685.         and    es:[di],cl
  1686.         mov    ah,0ffh
  1687.         out    dx,ax
  1688.         mov    dl,0c4h
  1689.  
  1690. putbl13:    pop    cx
  1691.         pop    di
  1692.         add    di,bpline
  1693.         dec    bx
  1694.         jnz    putbl11
  1695.  
  1696.         ;normalize ds,si pointer to stored bit block
  1697.         normalize ds,si,ax    ;pointer to stored bit block
  1698.                     ;use ax as temporary storage
  1699.  
  1700.         pop    di
  1701.         pop    ax
  1702.         shr    ah,1
  1703.         jnz    putbl10
  1704.         jmp    lexit2
  1705.  
  1706. ; routine for non-aligned bit blocks
  1707.  
  1708. putbl15:    push    ax            ; bit plane and function code 8
  1709.         mov    bx,0ffh
  1710.         mov    al,ch            ; end of row bit pattern
  1711.         cbw
  1712.  
  1713.         cmp    varpixelrowlen,1
  1714.         jne    putbl16
  1715.  
  1716.         mov    bl,ch
  1717.         mov    ah,ch
  1718.         xor    al,al
  1719.  
  1720. putbl16:    shl    ax,cl
  1721.         shl    bx,cl
  1722.  
  1723.         mov    bl,al
  1724.         mov    al,8
  1725.         mov    varendmaskl,ax
  1726.         mov    ah,bl
  1727.         mov    varendmaskr,ax
  1728.         mov    ah,bh
  1729.         mov    varstartmask,ax
  1730.  
  1731.  
  1732.         xor    ch,ch            ; ch is set to 00h if FGNORM
  1733.         test    byte ptr [rmwb],80h    ; otherwise 0FFh if FGNOT
  1734.         jz    oknot001
  1735.         not    ch
  1736.  
  1737. oknot001:    mov    bx,varpixelrowlen
  1738.         pop    ax            ; bit plane and function code 8
  1739.  
  1740. ; set pixels row by row in the bit planes
  1741.  
  1742. putbl17:    out    dx,ax
  1743.         push    ax
  1744.         push    di
  1745.         mov    dl,0ceh
  1746.  
  1747.         mov    ax,varpixelrows
  1748.         mov    varrowcount,ax        ; # of rows
  1749.  
  1750. putbl18:    push    di
  1751.         push    si
  1752.         push    bx            ; # of bytes/row
  1753.  
  1754.         mov    ax,varstartmask
  1755.         out    dx,ax
  1756.  
  1757.         lodsw
  1758.         dec    si
  1759.  
  1760.         xor    ah,ch            ; xors 00h or ffh dependant
  1761.         xor    al,ch            ; on RMWB for FGNOT
  1762.  
  1763. ;norm001:
  1764.         or    cl,cl
  1765.         jnz    putbl19
  1766.  
  1767.         dec    bx
  1768.         jnz    putbl20
  1769.         jmp    short putbl22
  1770.  
  1771. putbl19:    rol    ax,cl
  1772.  
  1773.         and    es:[di],ah
  1774.         inc    di
  1775.  
  1776.         dec    bx
  1777.  
  1778. putbl20:    push    ax
  1779.         mov    ax,0ff08h
  1780.         out    dx,ax
  1781.         pop    ax
  1782.  
  1783.         dec    bx
  1784.         jng    putbl22
  1785.  
  1786. ; set pixels in middle of row
  1787.  
  1788. putbl21:    and    es:[di],al
  1789.         inc    di
  1790.  
  1791.         lodsw
  1792.         dec    si
  1793.  
  1794.         xor    ah,ch            ; xors 00h or ffh dependant
  1795.         xor    al,ch            ; on RMWB for FGNOT
  1796.  
  1797. ;norm002:
  1798.         rol    ax,cl
  1799.         dec    bx
  1800.         jnz    putbl21
  1801.  
  1802. ; set pixels at end of row
  1803.  
  1804. putbl22:    mov    bx,ax
  1805.         mov    ax,varendmaskl
  1806.  
  1807.         out    dx,ax
  1808.         and    es:[di],bl
  1809.         inc    di
  1810.  
  1811.         mov    ax,varendmaskr
  1812.         out    dx,ax
  1813.         and    es:[di],bh
  1814.  
  1815.         pop    bx            ; # of bytes/row
  1816.         pop    si
  1817.         pop    di
  1818.  
  1819.         add    si,bx
  1820.         add    di,bpline
  1821.  
  1822.         dec    varrowcount
  1823.         jnz    putbl18
  1824.  
  1825.         ;normalize ds,si pointer to stored bit block
  1826.         normalize ds,si,ax    ;pointer to stored bit block
  1827.                     ;use ax as temporary storage
  1828.  
  1829.         pop    di
  1830.         pop    ax
  1831.         mov    dl,0c4h     ; dx := 3c4h (sequence i/o port)
  1832.         shr    ah,1
  1833.         jnz    putbl17
  1834.  
  1835. ; restore graphics controller and sequencer to their default states
  1836.  
  1837. lexit2:     mov    ax,0f02h
  1838.         out    dx,ax
  1839.  
  1840.         mov    dl,0ceh
  1841.         mov    ax,003
  1842.         out    dx,ax
  1843.  
  1844.         mov    ax,0005
  1845.         out    dx,ax
  1846.  
  1847.         mov    ax,0f07h
  1848.         out    dx,ax
  1849.  
  1850.         mov    ax,0ff08h
  1851.         out    dx,ax
  1852.  
  1853.         pop    di
  1854.         pop    si
  1855.         pop    ds
  1856.         ret
  1857.  
  1858. putbiti     endp
  1859.  
  1860.  
  1861. extractimg    proc    far argx0:word,argy0:word,argx1:word,argy1:word,addrbuf1:dword,addrbuf2:dword
  1862.         local    var1pixelrows : word, var1pixelrowlen  : word
  1863.         local    var2pixelrows : word, var2pixelrowlen  : word
  1864.         local    nextplaneofs  : word
  1865.  
  1866.         push    ds
  1867.         push    si
  1868.         push    es
  1869.         push    di
  1870.  
  1871.         les    di,addrbuf1
  1872.         lds    si,addrbuf2
  1873.  
  1874.         cld
  1875.         lodsw                ; var2pixelrows
  1876.         mov    var2pixelrows,ax
  1877.         lodsw                ; var2pixelrows
  1878.         mov    var2pixelrowlen,ax
  1879.         lodsb
  1880.  
  1881.  
  1882. ; compute dimensions of bit block
  1883. ; build 5-byte bit block header
  1884.  
  1885.         ; number of pixel rows
  1886.         mov    ax,argy1
  1887.         sub    ax,argy0
  1888.         inc    ax
  1889.         mov    var1pixelrows,ax
  1890.         stosw
  1891.  
  1892.         ; number of bytes per row
  1893.         mov    ax,argx1
  1894.         sub    ax,argx0
  1895.         push    ax
  1896.         mov    cl,3            ; divide by 8 pix per byte
  1897.         shr    ax,cl
  1898.         inc    ax            ; ax := number of bytes per row
  1899.         mov    var1pixelrowlen,ax
  1900.         stosw
  1901.         pop    ax
  1902.  
  1903.         ; last byte in row bit mask
  1904.         mov    cx,0ff07h        ; ch := unshifted bit mask
  1905.                         ; cl := and mask for al
  1906.         and    cl,al            ; cl := remaining pixels in
  1907.                         ; last byte of row
  1908.         xor    cl,7
  1909.         shl    ch,cl            ; create the last byte mask
  1910.  
  1911.         mov    al,ch
  1912.         stosb
  1913.  
  1914.  
  1915. ; establish bit block2 size
  1916.         mov    ax,var2pixelrowlen
  1917.         mov    dx,var2pixelrows
  1918.         mul    dx
  1919.         mov    nextplaneofs,ax
  1920.  
  1921. ; establish addressing
  1922.  
  1923.         mov    ax,argy0
  1924.         mov    bx,argx0
  1925.         mov    cl,bl
  1926.  
  1927.         mov    dx,var2pixelrowlen
  1928.         mul    dx            ; multiply rows by bytesperrow
  1929.  
  1930.         shr    bx,1            ; divide x coordinate by 8
  1931.         shr    bx,1
  1932.         shr    bx,1
  1933.         add    bx,ax            ; add to address
  1934.         add    si,bx
  1935.  
  1936.         and    cl,7            ; bits remainder
  1937.  
  1938. ; copy from bit block2 to bit block1
  1939.  
  1940.         ;normalize ds,si pointer to stored bit block
  1941.         normalize ds,si,ax    ;pointer to stored bit block
  1942.                     ;use ax as temporary storage
  1943.         ;normalize es,di pointer to stored bit block
  1944.         normalize es,di,ax    ;pointer to stored bit block
  1945.                     ;use ax as temporary storage
  1946.  
  1947.  
  1948.         mov    ax,4            ; four bit planes
  1949.         mov    dx,var1pixelrows
  1950.  
  1951. extrc06:    push    ax
  1952.         push    dx
  1953.         push    si
  1954.  
  1955. extrc07:    mov    bx,var1pixelrowlen
  1956.         push    si
  1957.  
  1958. extrc08:    lodsw
  1959.         dec    si
  1960.         rol    ax,cl
  1961.         stosb
  1962.         dec    bx
  1963.         jnz    extrc08
  1964.  
  1965.         and    es:[di-1],ch
  1966.         pop    si
  1967.         add    si,var2pixelrowlen
  1968.  
  1969.         dec    dx
  1970.         jnz    extrc07
  1971.  
  1972.         pop    si
  1973.         pop    dx
  1974.  
  1975.         add    si,nextplaneofs
  1976.  
  1977.         ;normalize ds,si pointer to stored bit block
  1978.         normalize ds,si,ax    ;pointer to stored bit block
  1979.                     ;use ax as temporary storage
  1980.         ;normalize es,di pointer to stored bit block
  1981.         normalize es,di,ax    ;pointer to stored bit block
  1982.                     ;use ax as temporary storage
  1983.  
  1984.         pop    ax
  1985.         dec    ax
  1986.         jnz    extrc06
  1987.  
  1988.         pop    di
  1989.         pop    es
  1990.         pop    si
  1991.         pop    ds
  1992.         ret
  1993.  
  1994. extractimg    endp
  1995.  
  1996.  
  1997.  
  1998. overlayimg    proc    far argx0:word,argy0:word,addrbuf1:dword,addrbuf2:dword
  1999.         local    var1pixelrows : word, var1pixelrowlen  : word
  2000.         local    var2pixelrows : word, var2pixelrowlen  : word
  2001.         local    nextplaneofs  : word
  2002.  
  2003.         local    varstartmask  : byte, varendmaskl      : byte
  2004.         local    varendmaskr   : byte, screenmask       : byte
  2005.  
  2006.         push    ds
  2007.         push    si
  2008.         push    es
  2009.         push    di
  2010.  
  2011.         cld
  2012.  
  2013.         lds    si,addrbuf2
  2014.         lodsw            ; var2pixelrows
  2015.         mov    var2pixelrows,ax
  2016.         lodsw            ; var2pixelrows
  2017.         mov    var2pixelrowlen,ax
  2018.         lodsb
  2019.  
  2020.         push    ds
  2021.         push    si
  2022.         pop    di        ; es:di -> addrbuf2
  2023.         pop    es
  2024.  
  2025.         lds    si,addrbuf1
  2026.         lodsw            ; var1pixelrows
  2027.         mov    var1pixelrows,ax
  2028.         lodsw            ; var1pixelrows
  2029.         mov    var1pixelrowlen,ax
  2030.         lodsb
  2031.         mov    ch,al        ; ds:si -> addrbuf1
  2032.                     ; ch    -> last byte mask
  2033.  
  2034. ; establish bit block2 size
  2035.         mov    ax,var2pixelrowlen
  2036.         mov    dx,var2pixelrows
  2037.         mul    dx
  2038.         mov    nextplaneofs,ax ; addrbuf2 size
  2039.  
  2040. ; establish addressing
  2041.  
  2042.         mov    ax,argy0
  2043.         mov    bx,argx0
  2044.         mov    cl,bl
  2045.  
  2046.         mov    dx,var2pixelrowlen
  2047.         mul    dx        ; multiply rows by bytesperrow
  2048.  
  2049.         shr    bx,1        ; divide x coordinate by 8
  2050.         shr    bx,1
  2051.         shr    bx,1
  2052.         add    bx,ax
  2053.         add    di,bx        ; add to address of addrbuf2
  2054.  
  2055.         and    cl,7
  2056.         xor    cl,7
  2057.         inc    cl
  2058.         and    cl,7        ; bits remainder
  2059.                 push    ax
  2060.         ;normalize es,di pointer to stored bit block
  2061.         normalize es,di,ax    ;pointer to stored bit block
  2062.                     ;use ax as temporary storage
  2063.         ;normalize ds,si pointer to stored bit block
  2064.         normalize ds,si,ax    ;pointer to stored bit block
  2065.                     ;use ax as temporary storage
  2066.                 pop     ax
  2067.  
  2068.         cmp    cx,0ff00h
  2069.         jne    overl15
  2070.  
  2071. ; routine for byte-aligned bit blocks
  2072.         mov    cx,var1pixelrowlen
  2073.         mov    dx,4
  2074.  
  2075. overl10:    push    di
  2076.         mov    bx,var1pixelrows
  2077.  
  2078. overl11:    push    di
  2079.         push    cx
  2080.  
  2081.         shr    cx,1
  2082.         rep    movsw
  2083.         adc    cx,0
  2084.         rep    movsb
  2085.  
  2086.         pop    cx
  2087.         pop    di
  2088.         add    di,var2pixelrowlen
  2089.         dec    bx
  2090.         jnz    overl11
  2091.  
  2092.         pop    di
  2093.         add    di,nextplaneofs
  2094.  
  2095.         ;normalize es,di pointer to stored bit block
  2096.         normalize es,di,ax    ;pointer to stored bit block
  2097.                     ;use ax as temporary storage
  2098.         ;normalize ds,si pointer to stored bit block
  2099.         normalize ds,si,ax    ;pointer to stored bit block
  2100.                     ;use ax as temporary storage
  2101.  
  2102.         dec    dx
  2103.         jnz    overl10
  2104.         jmp    overlexit
  2105.  
  2106.  
  2107. ; copy from bit block2 to bit block1
  2108.  
  2109. overl15:    mov    bx,0ffh     ; bh := 0 (mask for first byte in row
  2110.                     ; bl := 0ffh
  2111.         mov    al,ch        ; al := mask for last byte in pixel row
  2112.         cbw            ; ah := 0ffh (mask for last-1 byte)
  2113.  
  2114.         cmp    var1pixelrowlen,1
  2115.         jne    overl16     ; jump if more than one byte per row
  2116.  
  2117.         mov    bl,ch
  2118.         mov    ah,ch        ; ah := mask for last-1 byte
  2119.         xor    al,al        ; al := 0 (mask for last byte)
  2120.  
  2121. overl16:    shl    ax,cl        ; shift masks into position
  2122.         shl    bx,cl
  2123.  
  2124.  
  2125. ;        use not to invert mask
  2126.         not    ax
  2127.         mov    varendmaskl,ah
  2128.         mov    varendmaskr,al
  2129.         not    bh
  2130.         mov    varstartmask,bh
  2131.  
  2132.         mov    bx,var1pixelrowlen
  2133.  
  2134. ; set pixels row by row in the bit planes
  2135.  
  2136.         mov    ax,4        ; 4 planes
  2137. overl17:    push    ax
  2138.         push    di
  2139.  
  2140.         mov    ax,var1pixelrows
  2141.  
  2142. overl18:    push    ax
  2143.         push    di        ; offset of start of pixel row
  2144.         push    si        ; offset of row in bit block
  2145.         push    bx        ; bytes per pixel row
  2146.  
  2147.         mov    al,varstartmask ; mask first byte of row
  2148.         mov    screenmask,al
  2149.  
  2150.         lodsw            ; ah := 2nd byte of pixels
  2151.                     ; al := 1st byte of pixels
  2152.         dec    si        ; ds:si -> 2nd byte of pixels
  2153.         or    cl,cl
  2154.         jnz    overl19     ; jump if not left-aligned
  2155.  
  2156.         dec    bx        ; bx := bytes per row - 1
  2157.         jnz    overl20     ; jump if at least 2 bytes per row
  2158.         jmp    short overl22    ; jump if only one byte per row
  2159.  
  2160. overl19:    rol    ax,cl        ; ah := left part of 1st byte,
  2161.                     ;    right part of 2nd byte
  2162.  
  2163.         mov    dl,screenmask
  2164.         push    ax
  2165.         and    es:[di],dl
  2166.         not    dl
  2167.         and    ah,dl
  2168.         or    es:[di],ah    ; or pixels for left part of first byte
  2169.         pop    ax
  2170.  
  2171.         inc    di
  2172.         dec    bx        ; bx := bytes per row - 2
  2173.  
  2174. overl20:    ; set up bit mask for succeeding bytes
  2175.  
  2176.         mov    screenmask,0
  2177.  
  2178.         dec    bx
  2179.         jng    overl22     ; jump if only 1 or 2 bytes in pixel
  2180.  
  2181. ; set pixels in middle of row
  2182.  
  2183. overl21:    mov    dl,screenmask
  2184.         and    es:[di],dl    ; set pixels in right part of current
  2185.         not    dl
  2186.         and    al,dl
  2187.         or    es:[di],al    ; set pixels in right part of current
  2188.         inc    di        ; byte and left part of next byte
  2189.  
  2190.         lodsw            ; ah := next+1 byte of pixels
  2191.         dec    si        ; al := next byte of pixels
  2192.         rol    ax,cl        ; ah := left part of next byte, right
  2193.                     ;    part of next+1 byte
  2194.         dec    bx
  2195.         jnz    overl21     ; loop across pixel row
  2196.  
  2197. ; set pixels at end of row
  2198.  
  2199. overl22:    mov    bx,ax
  2200.         mov    al,varendmaskl
  2201.         and    es:[di],al
  2202.         not    al
  2203.         and    bl,al
  2204.         or    es:[di],bl
  2205.  
  2206.         mov    al,varendmaskr
  2207.         and    es:[di+1],al
  2208.         not    al
  2209.         and    bh,al
  2210.         or    es:[di+1],bh
  2211.  
  2212.         pop    bx
  2213.         pop    si
  2214.         add    si,bx
  2215.         pop    di
  2216.         add    di,var2pixelrowlen
  2217.         pop    ax
  2218.         dec    ax
  2219.         jnz    overl18
  2220.  
  2221.         pop    di
  2222.         add    di,nextplaneofs
  2223.  
  2224.         call    ovlnormalze
  2225.  
  2226.         pop    ax
  2227.         dec    ax
  2228.         jnz    overl17
  2229.  
  2230. overlexit:    pop    di
  2231.         pop    es
  2232.         pop    si
  2233.         pop    ds
  2234.         ret
  2235.  
  2236. overlayimg    endp
  2237.  
  2238.  
  2239. ovlnormalze    proc    near
  2240.         ;normalize ds,si pointer to stored bit block
  2241.         normalize ds,si,ax    ;pointer to stored bit block
  2242.                     ;use ax as temporary storage
  2243.         ;normalize es,di pointer to stored bit block
  2244.         normalize es,di,ax    ;pointer to stored bit block
  2245.                     ;use ax as temporary storage
  2246.         ret
  2247. ovlnormalze    endp
  2248.  
  2249.  
  2250.  
  2251. extractpixs    proc    far argx0:word,argy0:word,addrbuff:dword
  2252.         local    varpixelrows:word,varpixelrowlen:word
  2253.         local    nextplaneofs:word
  2254.  
  2255.         push    ds
  2256.         push    si
  2257.         lds    si,addrbuff
  2258.  
  2259.         cld
  2260.         lodsw                ; varpixelrows
  2261.         mov    varpixelrows,ax
  2262.         lodsw                ; varpixelrows
  2263.         mov    varpixelrowlen,ax
  2264.         lodsb
  2265.  
  2266.  
  2267. ; establish bit block2 size
  2268.         mov    ax,varpixelrowlen
  2269.         mov    dx,varpixelrows
  2270.         mul    dx
  2271.         mov    nextplaneofs,ax
  2272.  
  2273. ; establish addressing
  2274.  
  2275.         mov    ax,argy0
  2276.         mov    dx,varpixelrowlen
  2277.         mul    dx            ; multiply rows by bytesperrow
  2278.         add    si,ax
  2279.  
  2280.         mov    bx,argx0
  2281.         mov    cl,bl
  2282.         shr    bx,1            ; divide x coordinate by 8
  2283.         shr    bx,1
  2284.         shr    bx,1
  2285.         add    si,bx            ; add to address
  2286.  
  2287.         and    cl,7            ; bits remainder
  2288.  
  2289.         xor    cl,7
  2290.         mov    ch,1
  2291.         shl    ch,cl        ; ch:=bit mask in proper position
  2292.  
  2293.         xor    cl,7
  2294.         xor    bl,bl        ; bl is used to accumulate the pixel value
  2295.  
  2296.         mov    dl,4        ; four bit planes
  2297. extrbit:    mov    bh,ds:[si]    ; bh := byte from current bit plane
  2298.         and    bh,ch        ; mask one bit
  2299.         shl    bh,cl
  2300.         rol    bx,1        ; bit 0 of bl := next bit from pixel value
  2301.         add    si,nextplaneofs
  2302.  
  2303.         ;normalize ds,si pointer to stored bit block
  2304.         normalize ds,si,ax    ;pointer to stored bit block
  2305.                     ;use ax as temporary storage
  2306.  
  2307.         dec    dl
  2308.         jnz    extrbit
  2309.  
  2310.         mov    al,bl        ; al := pixel value
  2311.         xor    ah,ah        ; ax := pixel value
  2312.  
  2313.         pop    si
  2314.         pop    ds
  2315.         ret
  2316.  
  2317. extractpixs    endp
  2318.  
  2319. wrtchar     proc    far argc:word,argx:word,argy:word,argfgd:word,argbgd:word
  2320.         local    varshift:word,jaggy:word,transparent:byte,charshift:byte
  2321.         local    rmwb:word,bpline:word,bpchar:byte,lastbytemask:byte
  2322.  
  2323.         push    ds
  2324.         push    si
  2325.         push    es
  2326.         push    di
  2327.  
  2328. ; set up character definition table addressing
  2329.  
  2330.         lds    si,cs:TDtable
  2331.         les    di,ds:[si].fonttable
  2332.  
  2333.         mov    ax,argc     ; al := character code
  2334.         xor    ah,ah
  2335.         cmp    al,es:[di].FontAsciiStart
  2336.         jb    nowrtjmp
  2337.         cmp    al,es:[di].FontAsciiEnd
  2338.         jbe    okwrtjmp
  2339.  
  2340. nowrtjmp:    jmp    nowrt
  2341. okwrtjmp:
  2342.  
  2343.         mov    ax,ds:[si].rmwbits
  2344.         mov    rmwb,ax
  2345.  
  2346.         mov    ax,ds:[si].vbytesperline
  2347.         mov    bpline,ax
  2348.  
  2349.         mov    al,ds:[si].transparency
  2350.         mov    transparent,al
  2351.  
  2352.         xor    ax,ax
  2353.         mov    al,ds:[si].jagged
  2354.         and    al,1
  2355.         xchg    al,ah
  2356.         mov    jaggy,ax
  2357.  
  2358. ;        xor    cx,cx
  2359. ;        mov    cl,es:[di].fontwidth    ;calculate last byte mask
  2360. ;        and    cl,7
  2361. ;        xor    cl,7
  2362. ;        mov    ch,0ffh
  2363. ;        shl    ch,cl
  2364. ;        mov    lastbytemask,ch
  2365. ;
  2366. ;        mov    al,ds:[si].proportional
  2367. ;        or    al,al
  2368. ;        jnz    okpropjmp
  2369. ;
  2370. ;        ;otherwise check if proportional character needs alignment
  2371. ;        xor    ax,ax
  2372. ;        mov    al,es:[di].fontwidth
  2373. ;        xor    bx,bx
  2374. ;        mov    bl,byte ptr [argc]      ;character
  2375. ;        sub    al,es:[di][bx].Fontbytewidth ;index into width table
  2376. ;        shr    al,1            ;divide by two
  2377. ;        mov    charshift,al
  2378. ;        add    argx,ax         ;add it to argx
  2379.  
  2380. ; calculate first pixel address
  2381. okpropjmp:    push    es
  2382.  
  2383.         mov    ax,argy     ; ax := y
  2384.         mov    bx,argx     ; bx := x
  2385.         call    activeaddr    ; es:bx -> buffer
  2386.                     ; cl := # bits to shift left to mask
  2387.                     ;  pixel
  2388.         inc    cx
  2389.         and    cl,7        ; cl := # bits to shift to mask char
  2390.  
  2391.         mov    ch,0ffh
  2392.         shl    ch,cl        ; ch := bit mask for right side of char
  2393.         mov    varshift,cx
  2394.  
  2395.         push    es        ; transfer es to ds
  2396.         pop    ds
  2397.         mov    si,bx        ; si := video buffer offset
  2398.  
  2399. ; set up character definition table addressing
  2400.  
  2401.         pop    es
  2402.  
  2403.         xor    ax,ax
  2404.         mov    al,es:[di].FontHeight ;Multiply fontheight by fontwidth
  2405.         mov    cx,ax
  2406. ;        dec    cx
  2407.  
  2408.         xor    bx,bx
  2409.         mov    bl,es:[di].fontbytewidth
  2410.         mov    bpchar,bl
  2411.         mul    bx
  2412.  
  2413.         mov    dx,argc     ; dl := character code
  2414.         sub    dl,es:[di].FontAsciiStart
  2415.         mul    dx        ; ax := offset into char def table
  2416.                     ;  (points * char code)
  2417.  
  2418.         add    di,255 + size TEGLFontInfo ;skip font table info
  2419.         add    di,ax        ; add character offset
  2420.  
  2421. ; set up graphics controller registers
  2422.         mov    dx,3ceh     ; graphics controller address reg port
  2423.         mov    ax,0a05h    ; al :=  mode register number
  2424.                     ; ah :=  write mode 2 (bits 0-1)
  2425.                     ;     read mode 1 (bit 4)
  2426.         out    dx,ax
  2427.  
  2428.         mov    ah,byte ptr [rmwb] ; ah := read-modify-write bits
  2429.         mov    al,3        ; al := data rotate/function select reg
  2430.         out    dx,ax
  2431.  
  2432.         mov    ax,0007     ; ah := color don't care bits
  2433.                     ; al := color don't care reg number
  2434.         out    dx,ax        ; "don't care" for all bit planes
  2435.  
  2436. ; select output routine depending on whether character is byte-aligned
  2437.  
  2438.         mov    bl,byte ptr [argfgd] ; bl := foreground pixel value
  2439.         mov    bh,byte ptr [argbgd] ; bh := background pixel value
  2440.  
  2441.         mov    ch,bpchar    ; bytes per character
  2442.         xor    ax,ax
  2443.         mov    al,ch        ; number of bytes per char width
  2444.         sub    bpline,ax
  2445.  
  2446.         test    byte ptr [varshift],0ffh ; test # bits to shift
  2447.         jne    l20        ; jump if character is not byte-aligned
  2448.  
  2449.  
  2450. ;------------------------------------------------
  2451. ; routine for byte-aligned characters
  2452. ;------------------------------------------------
  2453.  
  2454.         mov    al,8        ; al := bit mask register number
  2455. wrtcl10a:    xchg    cl,byte ptr jaggy ; jaggies
  2456. wrtcl10:    mov    ah,es:[di]    ; ah := pattern
  2457.  
  2458.         shr    ah,cl
  2459.  
  2460. jag1done:    out    dx,ax        ; update bit mask register
  2461.         and    [si],bl     ; update foreground pixels
  2462.  
  2463.         not    ah
  2464.         and    ah,transparent    ; transparent bits are either $ff or $00
  2465.         out    dx,ax
  2466.         and    [si],bh     ; update background pixels
  2467.  
  2468.         inc    di        ; es:di -> next byte in char def table
  2469.         inc    si
  2470.         dec    ch
  2471.         jnz    wrtcl10
  2472.  
  2473.         mov    ch,bpchar    ; bytes per character
  2474.         add    si,bpline    ; increment to next line in video buffer
  2475.  
  2476.         xchg    cl,byte ptr jaggy+1
  2477.         xchg    cl,byte ptr jaggy
  2478.         dec    cl
  2479.         jnz    wrtcl10a
  2480.         jmp    short wrtcexit
  2481.  
  2482. ;------------------------------------------------
  2483. ; routine for non-byte-aligned characters
  2484. ;------------------------------------------------
  2485.  
  2486. l20:        push    cx        ; preserve loop counter
  2487.         mov    cx,varshift    ; ch := mask for left side of character
  2488.                     ; cl := # bits to shift left
  2489. ; left side of character
  2490.  
  2491.         mov    al,es:[di]    ; al := bits for next row of pixels
  2492.         xor    ah,ah
  2493.  
  2494.         xchg    cl,byte ptr jaggy
  2495.         shr    ax,cl
  2496.         xchg    cl,byte ptr jaggy
  2497.  
  2498. jag2done:    shl    ax,cl        ; ah := bits for left side of char
  2499.                     ; al := bits for right side of char
  2500.  
  2501.         push    ax        ; save bits for right side on stack
  2502.         mov    al,8        ; al := bit mask register number
  2503.         out    dx,ax        ; set bit mask for foreground pixels
  2504.         and    [si],bl     ; update foreground pixels
  2505.  
  2506.         not    ch        ; ch mask for left side of char
  2507.         xor    ah,ch        ; ah bits for background
  2508.         and    ah,transparent    ; transparent bits are either $ff or $00
  2509.         out    dx,ax
  2510.         and    [si],bh     ; update background pixels
  2511.  
  2512. ; right side of character
  2513.  
  2514.         pop    ax
  2515.         mov    ah,al        ; ah := bits for right side of char
  2516.         mov    al,8
  2517.         out    dx,ax        ; set bit mask
  2518.         inc    si        ; ds:si -> right side of char in buffer
  2519.         and    [si],bl     ; update foreground pixels
  2520.  
  2521.         not    ch        ; ch mask for right side of char
  2522.         xor    ah,ch        ; ah bits for background
  2523.         and    ah,transparent    ; transparent bits are either $ff or $00
  2524.         out    dx,ax
  2525.         and    [si],bh     ; update background pixels
  2526.  
  2527.         pop    cx
  2528.         inc    di        ; es:di -> next byte in char def table
  2529.         dec    ch
  2530.         jnz    l20
  2531.  
  2532. ; increment to next row of pixels in character
  2533.         mov    ch,bpchar    ; bytes per character
  2534.         add    si,bpline    ; ds:si -> next line in video buffer
  2535.  
  2536.         xchg    cx,jaggy
  2537.         xchg    cl,ch
  2538.         xchg    cx,jaggy
  2539.  
  2540.         dec    cl
  2541.         jnz    l20
  2542.  
  2543. ;------------------------------------------------
  2544. ; restore default graphics controller registers
  2545. ;------------------------------------------------
  2546. wrtcexit:    mov    ax,0ff08h    ; default bit mask
  2547.         out    dx,ax
  2548.  
  2549.         mov    ax,0005     ; default mode register
  2550.         out    dx,ax
  2551.  
  2552.         mov    ax,0003     ; default data rotate/function select
  2553.         out    dx,ax
  2554.  
  2555.         mov    ax,0f07h    ; default color don't care
  2556.         out    dx,ax
  2557.  
  2558. nowrt:        pop    di
  2559.         pop    es
  2560.         pop    si
  2561.         pop    ds
  2562.  
  2563.         ret
  2564.  
  2565. wrtchar     endp
  2566.  
  2567. activeaddr    proc    near
  2568.  
  2569.         mov    cl,bl
  2570.         push    ds
  2571.         push    si
  2572.         push    dx
  2573.  
  2574.         lds    si,cs:TDtable
  2575.         mov    dx,ds:[si].vbytesperline
  2576.         mul    dx
  2577.  
  2578.         pop    dx
  2579.         shr    bx,1
  2580.         shr    bx,1
  2581.         shr    bx,1
  2582.         add    bx,ax
  2583.  
  2584.         mov    ax,ds:[si].activepage
  2585.         shr    ax,1
  2586.         shr    ax,1
  2587.         shr    ax,1
  2588.         shr    ax,1
  2589.         add    ax,0a000h
  2590.         mov    es,ax
  2591.         pop    si
  2592.         pop    ds
  2593.  
  2594.         and    cl,7
  2595.         xor    cl,7
  2596.         mov    ah,1
  2597.         ret
  2598.  
  2599. activeaddr    endp
  2600.  
  2601.  
  2602. mcursoroff    proc    far
  2603.  
  2604.         push    es
  2605.         push    di
  2606.         push    ds
  2607.         push    si
  2608.  
  2609. ; replace mouse cursor area
  2610.  
  2611.         test    cs:mflag,1
  2612.         jz    nomoff
  2613.  
  2614.         mov    cs:mflag,0
  2615.  
  2616. ;    modify putbiti to put an array of 3x16 bytes for four planes
  2617.         les    di,dword ptr cs:scradrofs
  2618.         push    cs
  2619.         pop    ds
  2620.         mov    si,offset mcursorsavearea
  2621.         call    mputblock
  2622.  
  2623. nomoff:     pop    si        ; restore caller registers and return
  2624.         pop    ds
  2625.         pop    di
  2626.         pop    es
  2627.         ret
  2628.  
  2629. mcursoroff    endp
  2630.  
  2631.  
  2632.  
  2633. mcursoron    proc    far argx:word,argy:word
  2634.         local    varshift:word,wordmask:word,mscolor:byte,bpline:word
  2635.  
  2636.         push    es
  2637.         push    di
  2638.         push    ds
  2639.         push    si
  2640.  
  2641. ; save mouse cursor area
  2642.         lds    si,cs:TDtable
  2643.         mov    ax,ds:[si].vbytesperline
  2644.         mov    bpline,ax
  2645.  
  2646.         mov    ax,ds:[si].mousecolor
  2647.         mov    mscolor,al
  2648.  
  2649.         mov    ax,argy     ; ax := y
  2650.         sub    ax,ds:[si].mousehotspot_yofs
  2651.         jnc    hotset1
  2652.         mov    ax,argy
  2653.  
  2654. hotset1:    mov    bx,argx     ; bx := x
  2655.         sub    bx,ds:[si].mousehotspot_xofs
  2656.         jnc    hotset2
  2657.         mov    bx,argx
  2658.  
  2659. hotset2:    call    visualaddr    ; es:bx -> buffer
  2660.         inc    cx
  2661.         and    cl,7        ; cl := # bits to shift to mask char
  2662.         mov    ch,0ffh
  2663.         shl    ch,cl        ; ch := bit mask for right side of char
  2664.         mov    varshift,cx
  2665.  
  2666.         mov    cs:scradrseg,es
  2667.         mov    cs:scradrofs,bx
  2668.         mov    cs:mflag,1    ; mouse cursor on
  2669.  
  2670.  
  2671.         push    es
  2672.         push    cs
  2673.         pop    es
  2674.         pop    ds
  2675.  
  2676.         mov    si,bx
  2677.         mov    di,offset mcursorsavearea
  2678.         call    mgetblock
  2679.  
  2680.  
  2681. ; set up mouse cursor table addressing
  2682.  
  2683.         les    di,cs:TDtable
  2684.         les    di,es:[di].mousemask
  2685.         mov    cx,16        ; number of pixel rows in cursor
  2686.  
  2687. ; set up graphics controller registers
  2688.  
  2689.         mov    dx,3ceh     ; graphics controller address reg port
  2690.  
  2691.         mov    ax,0a05h    ; al :=  mode register number
  2692.                     ; ah :=  write mode 2 (bits 0-1)
  2693.                     ;     read mode 1 (bit 4)
  2694.         out    dx,ax
  2695.  
  2696.         mov    ah,0        ; ah := read-modify-write bits
  2697.         mov    al,3        ; al := data rotate/function select reg
  2698.         out    dx,ax
  2699.  
  2700.         mov    ax,0007     ; ah := color don't care bits
  2701.                     ; al := color don't care reg number
  2702.         out    dx,ax        ; "don't care" for all bit planes
  2703.  
  2704. ; select output routine depending on whether character is byte-aligned
  2705.  
  2706.         test    byte ptr [varshift],0ffh ; test # bits to shift
  2707.         jne    mcl20        ; jump if character is not byte-aligned
  2708.  
  2709.  
  2710. ; routine for byte-aligned characters
  2711.  
  2712.  
  2713. ;    add code here to save three bytes at ds:[si] for four planes
  2714. ;    call subroutine
  2715. mcl10:        mov    ax,es:[di]
  2716.         not    ax
  2717.         push    ax
  2718.         mov    al,8
  2719.         out    dx,ax
  2720.         and    byte ptr [si],0
  2721.  
  2722.         pop    ax
  2723.         mov    ah,al
  2724.         mov    al,8
  2725.         out    dx,ax
  2726.         and    byte ptr [si+1],0
  2727.  
  2728.         mov    bl,mscolor
  2729.         mov    ax,es:[di+32]
  2730.         push    ax
  2731.         mov    al,8
  2732.         out    dx,ax
  2733.         and    byte ptr [si],bl
  2734.  
  2735.         pop    ax
  2736.         mov    ah,al
  2737.         mov    al,8
  2738.         out    dx,ax
  2739.         and    byte ptr [si+1],bl
  2740.  
  2741.         inc    di
  2742.         inc    di
  2743.  
  2744.         add    si,bpline
  2745.         loop    mcl10
  2746.         jmp    short mclexit
  2747.  
  2748.  
  2749. ; routine for non-byte-aligned characters
  2750.  
  2751.  
  2752. ;    add code here to save three bytes at ds:[si] for four planes
  2753. ;    call subroutine
  2754. mcl20:        push    cx        ; preserve loop counter
  2755.         mov    cx,varshift    ; ch := mask for left side of character
  2756.                     ; cl := # bits to shift left
  2757. ; left side of mask
  2758.         mov    ax,es:[di]
  2759.         not    ax
  2760.         push    ax
  2761.  
  2762.         mov    al,ah
  2763.         xor    ah,ah
  2764.         shl    ax,cl        ; ah := bits for left side of char
  2765.                     ; al := bits for right side of char
  2766.         push    ax
  2767.         mov    al,8
  2768.         out    dx,ax
  2769.         and    byte ptr [si],0
  2770.  
  2771.         pop    ax
  2772.         mov    ah,al
  2773.         mov    al,8
  2774.         out    dx,ax
  2775.         and    byte ptr [si+1],0
  2776.  
  2777.         pop    ax
  2778.         xor    ah,ah
  2779.         shl    ax,cl        ; ah := bits for left side of char
  2780.                     ; al := bits for right side of char
  2781.         push    ax
  2782.         mov    al,8
  2783.         out    dx,ax
  2784.         and    byte ptr [si+1],0
  2785.  
  2786.         pop    ax
  2787.         mov    ah,al
  2788.         mov    al,8
  2789.         out    dx,ax
  2790.         and    byte ptr [si+2],0
  2791.  
  2792.  
  2793. ; colorize
  2794.         mov    ax,es:[di+32]
  2795.  
  2796.         push    ax
  2797.         mov    al,ah
  2798.         xor    ah,ah
  2799.         shl    ax,cl        ; ah := bits for left side of char
  2800.                     ; al := bits for right side of char
  2801.         mov    bl,mscolor
  2802.         push    ax
  2803.         mov    al,8
  2804.         out    dx,ax
  2805.         and    byte ptr [si],bl
  2806.         pop    ax
  2807.  
  2808.         mov    ah,al
  2809.         mov    al,8
  2810.         out    dx,ax
  2811.         and    byte ptr [si+1],bl
  2812.         pop    ax
  2813.  
  2814.         xor    ah,ah
  2815.         shl    ax,cl        ; ah := bits for left side of char
  2816.                     ; al := bits for right side of char
  2817.         push    ax
  2818.         mov    al,8
  2819.         out    dx,ax
  2820.         and    byte ptr [si+1],bl
  2821.         pop    ax
  2822.         mov    ah,al
  2823.         mov    al,8
  2824.         out    dx,ax
  2825.         and    byte ptr [si+2],bl
  2826.  
  2827. ; increment to next row of pixels in character
  2828.         inc    di
  2829.         inc    di
  2830.         add    si,bpline    ; ds:si -> next line in video buffer
  2831.  
  2832.         pop    cx
  2833.         loop    mcl20
  2834.  
  2835.  
  2836. ; restore default graphics controller registers
  2837.  
  2838. mclexit:    mov    ax,0ff08h    ; default bit mask
  2839.         out    dx,ax
  2840.  
  2841.         mov    ax,0005     ; default mode register
  2842.         out    dx,ax
  2843.  
  2844.         mov    ax,0003     ; default data rotate/function select
  2845.         out    dx,ax
  2846.  
  2847.         mov    ax,0f07h    ; default color don't care
  2848.         out    dx,ax
  2849.  
  2850.         pop    si        ; restore caller registers and return
  2851.         pop    ds
  2852.         pop    di
  2853.         pop    es
  2854.         ret
  2855.  
  2856. mcursoron    endp
  2857.  
  2858. msetpos     proc    far argx:word,argy:word
  2859.         push    ds
  2860.  
  2861.         test    cs:mflag,1
  2862.         jz    nomset
  2863.  
  2864.         call    mcursoroff
  2865.  
  2866.         mov    ax,argx
  2867.         push    ax
  2868.         mov    ax,argy
  2869.         push    ax
  2870.         call    mcursoron
  2871.  
  2872. nomset:     pop    ds
  2873.         ret
  2874. msetpos     endp
  2875.  
  2876.  
  2877. ; assume ds:si=addrbuf    es:di=screenadr
  2878. mputblock    proc    near
  2879.         push    si
  2880.         push    di
  2881.         push    bx
  2882.  
  2883.         mov    dx,ds
  2884.         mov    ax,si
  2885.         lds    si,cs:TDtable
  2886.         mov    bx,ds:[si].vbytesperline
  2887.         mov    si,ax
  2888.         mov    ds,dx
  2889.  
  2890. ; set up graphics controller
  2891.         mov    dx,3ceh     ; dx := graphics controller i/o port
  2892.  
  2893.         mov    ax,0003h    ; ah := normal put
  2894.         out    dx,ax        ; al := 3 select register
  2895.  
  2896.         mov    ax,0805h    ; ah := 8 (read mode 1, write mode 0)
  2897.         out    dx,ax        ; al := 5 (mode register)
  2898.  
  2899.         mov    ax,0007     ; ah := 0 (don't care for all maps;
  2900.         out    dx,ax        ;   cpu reads always return 0ffh)
  2901.                     ; al := 7 (color don't care reg number)
  2902.  
  2903.         mov    ax,0ff08h    ; ah := 0ffh (value for bit mask reg)
  2904.         out    dx,ax        ; set up bit mask reg
  2905.  
  2906.         mov    dl,0c4h     ; dx := 3c4h (sequence i/o port)
  2907.  
  2908.         mov    cx,16
  2909. mcputbl10:    mov    ax,0802h    ; ah := 1000b (value for map mask reg)
  2910.                     ; al := 2 (map mask register number)
  2911.  
  2912.         cld
  2913. mcputbl11:    out    dx,ax
  2914.         push    di
  2915.  
  2916.         movsw
  2917.         movsb
  2918.  
  2919.         pop    di
  2920.         shr    ah,1
  2921.         jnz    mcputbl11
  2922.  
  2923.         add    di,bx
  2924.         loop    mcputbl10
  2925.  
  2926. ; restore graphics controller and sequencer to their default states
  2927.         mov    ax,0f02h
  2928.         out    dx,ax
  2929.  
  2930.         mov    dl,0ceh
  2931.         mov    ax,003
  2932.         out    dx,ax
  2933.  
  2934.         mov    ax,0005
  2935.         out    dx,ax
  2936.  
  2937.         mov    ax,0f07h
  2938.         out    dx,ax
  2939.  
  2940.         mov    ax,0ff08h
  2941.         out    dx,ax
  2942.  
  2943.         pop    bx
  2944.         pop    di
  2945.         pop    si
  2946.         ret
  2947.  
  2948. mputblock    endp
  2949.  
  2950.  
  2951. ; assume es:di=addrbuf    ds:si=screenadr
  2952. mgetblock    proc    near
  2953.  
  2954.         cld
  2955.         push    si
  2956.         push    di
  2957.         push    bx
  2958.  
  2959.         mov    dx,ds
  2960.         mov    ax,si
  2961.         lds    si,cs:TDtable
  2962.         mov    bx,ds:[si].vbytesperline
  2963.         mov    si,ax
  2964.         mov    ds,dx
  2965.  
  2966. ; set up graphics controller
  2967.  
  2968.         mov    dx,3ceh     ; dx := graphics controller i/o port
  2969.         mov    ax,0005     ; ah := 0 (read mode 0, write mode 0)
  2970.         out    dx,ax        ; al := 5 (mode register)
  2971.  
  2972.         mov    cx,16
  2973. mcgetbl01:    mov    ax,0304h    ; ah := 3 (plane #3)
  2974.                     ; al := 4 (read map select)
  2975. mcgetbl02:    out    dx,ax
  2976.         push    si
  2977.  
  2978.         movsw
  2979.         movsb
  2980.  
  2981.         pop    si
  2982.         dec    ah
  2983.         jns    mcgetbl02
  2984.  
  2985.         add    si,bx
  2986.         loop    mcgetbl01
  2987.  
  2988.         pop    bx
  2989.         pop    di
  2990.         pop    si
  2991.         ret
  2992. mgetblock    endp
  2993.  
  2994.  
  2995. visualaddr    proc    near
  2996.  
  2997.         mov    cl,bl
  2998.         push    ds
  2999.         push    dx
  3000.  
  3001.         push    si
  3002.         lds    si,cs:TDtable
  3003.         mov    dx,ds:[si].vbytesperline
  3004.         pop    si
  3005.         mul    dx
  3006.  
  3007.         pop    dx
  3008.         shr    bx,1
  3009.         shr    bx,1
  3010.         shr    bx,1
  3011.         add    bx,ax
  3012.  
  3013.         mov    ax,40h
  3014.         mov    ds,ax
  3015.         mov    ax,ds:[4eh]
  3016.         shr    ax,1
  3017.         shr    ax,1
  3018.         shr    ax,1
  3019.         shr    ax,1
  3020.         add    ax,0a000h
  3021.         mov    es,ax
  3022.         pop    ds
  3023.  
  3024.         and    cl,7
  3025.         xor    cl,7
  3026.         mov    ah,1
  3027.         ret
  3028.  
  3029. visualaddr    endp
  3030.  
  3031.  
  3032. movevideopixels proc    far argx0:word,argy0:word,argx1:word,argy1:word,argx2:word,argy2:word,vertlines:word,horzlines:word,spage:dword,tpage:dword
  3033.         local    bpline:word,varpixelrows:word,varpixelrowlen:word
  3034.         local    varstartmask:word,varendmaskl:word,varendmaskr:word
  3035.         local    sourcescr:dword,sourceshft:byte,lastbytemask:byte
  3036.         local    targetscr:dword,targetshft:byte,workbuffer:dword
  3037.         local    varpixelcontlen:word
  3038.  
  3039.         push    ds
  3040.         push    es
  3041.         push    si
  3042.         push    di
  3043.  
  3044. ;-----------------------------------------------
  3045.         cld
  3046.  
  3047.         lds    si,cs:TDtable
  3048.         mov    ax,ds:[si].vbytesperline
  3049.         mov    bpline,ax
  3050.  
  3051.         les    di,ds:[si].vgraphbuffer
  3052.         mov    word ptr [workbuffer],di
  3053.         mov    word ptr [workbuffer+2],es
  3054.  
  3055.  
  3056. ;-----------------------------------------------
  3057.         mov    ax,horzlines
  3058.         or    ax,ax
  3059.         jz    noadj_89
  3060.         mov    ax,horzlines
  3061.         test    ah,80h
  3062.         jz    notneg1     ;scroll left?    ;   +-+--------+
  3063.                             ;   | <<<< -1  |
  3064.                             ;   +-+--------+
  3065.         mov    bx,argx0
  3066.         sub    bx,ax
  3067.         mov    argx0,bx
  3068.         jmp    short noadj_89
  3069.  
  3070. notneg1:    mov    bx,argx2    ;scroll right?    ;   +--------+-+
  3071.         add    bx,ax                ;   | 1   >>>> |
  3072.         mov    argx2,bx            ;   +--------+-+
  3073.  
  3074.         mov    bx,argx1
  3075.         sub    bx,ax
  3076.         mov    argx1,bx
  3077.  
  3078. noadj_89:
  3079.  
  3080.         mov    al,byte ptr [argx0]
  3081.         mov    ah,byte ptr [argx2]
  3082.         and    ax,0707h
  3083.         cmp    ah,al
  3084.         jne    movevideobits
  3085.         jmp    movevideobytes
  3086.  
  3087. ;-----------------------------------------------
  3088. movevideobits:    mov    ax,argx1
  3089.         sub    ax,argx0
  3090.         mov    cx,0ff07h
  3091.         and    cl,al
  3092.         xor    cl,7
  3093.         shl    ch,cl        ;last byte mask in ch
  3094.         mov    lastbytemask,ch
  3095.  
  3096.         shr    ax,1        ;number of bytes to mov
  3097.         shr    ax,1
  3098.         shr    ax,1
  3099.         inc    ax
  3100.         mov    varpixelrowlen,ax
  3101.  
  3102.         mov    ax,argy1    ;number of lines
  3103.         sub    ax,argy0    ;number of lines
  3104.         inc    ax
  3105.  
  3106. ;-----------------------------------------------
  3107. ; extablish addressing
  3108.         test    vertlines,8000h
  3109.         jnz    bottomupmove
  3110.  
  3111.         sub    ax,vertlines
  3112.         mov    varpixelrows,ax
  3113.  
  3114.         mov    ax,argy0    ;source     ;   +----------+
  3115.         add    ax,vertlines            ;   +----/\----+
  3116.         mov    bx,argx0            ;   |           |
  3117.                             ;   |           |
  3118.                             ;   +----------+
  3119.         mov    cl,bl
  3120.         mov    dx,bpline
  3121.         mul    dx
  3122.         shr    bx,1
  3123.         shr    bx,1
  3124.         shr    bx,1
  3125.         add    bx,ax
  3126.  
  3127.         mov    ax,word ptr [spage]
  3128.         and    ax,000fh
  3129.         add    bx,ax
  3130.  
  3131.         mov    ax,word ptr [spage]
  3132.         shr    ax,1
  3133.         shr    ax,1
  3134.         shr    ax,1
  3135.         shr    ax,1
  3136. ;        add    ax,0a000h
  3137.         add    ax,word ptr [spage+2]
  3138.  
  3139.         mov    word ptr [sourcescr],bx
  3140.         mov    word ptr [sourcescr+2],ax
  3141.  
  3142.         and    cl,7
  3143.         mov    sourceshft,cl
  3144.  
  3145. ;-------
  3146.         mov    ax,argy2    ;target
  3147.         mov    bx,argx2
  3148.  
  3149.         mov    cl,bl
  3150.         mov    dx,bpline
  3151.         mul    dx
  3152.         shr    bx,1
  3153.         shr    bx,1
  3154.         shr    bx,1
  3155.         add    bx,ax
  3156.  
  3157.         mov    ax,word ptr [tpage]
  3158.         and    ax,000fh
  3159.         add    bx,ax
  3160.  
  3161.         mov    ax,word ptr [tpage]
  3162.         shr    ax,1
  3163.         shr    ax,1
  3164.         shr    ax,1
  3165.         shr    ax,1
  3166.         add    ax,word ptr [tpage+2]
  3167.  
  3168.         mov    word ptr [targetscr],bx
  3169.         mov    word ptr [targetscr+2],ax
  3170.  
  3171.         xor    cl,7
  3172.         inc    cl
  3173.         and    cl,7
  3174.         mov    targetshft,cl
  3175.  
  3176.         jmp    movevideobl_23
  3177.  
  3178. bottomupmove:    add    ax,vertlines
  3179.         mov    varpixelrows,ax
  3180.  
  3181.         mov    ax,argy0    ;source     ;   +----------+
  3182.         add    ax,varpixelrows         ;   |           |
  3183.         dec    ax                ;   |           |
  3184.         mov    bx,argx0            ;   +----\/----+
  3185.                             ;   +----------+
  3186.         mov    cl,bl
  3187.         mov    dx,bpline
  3188.         mul    dx
  3189.  
  3190.         shr    bx,1
  3191.         shr    bx,1
  3192.         shr    bx,1
  3193.         add    bx,ax
  3194.  
  3195.         mov    ax,word ptr [spage]
  3196.         and    ax,000fh
  3197.         add    bx,ax
  3198.  
  3199.         mov    ax,word ptr [spage]
  3200.         shr    ax,1
  3201.         shr    ax,1
  3202.         shr    ax,1
  3203.         shr    ax,1
  3204. ;        add    ax,0a000h
  3205.         add    ax,word ptr [spage+2]
  3206.  
  3207.         mov    word ptr [sourcescr],bx
  3208.         mov    word ptr [sourcescr+2],ax
  3209.         and    cl,7
  3210.         mov    sourceshft,cl
  3211.  
  3212.         mov    ax,argy1
  3213.         sub    ax,argy0
  3214.         add    ax,argy2
  3215.         mov    bx,argx2    ;target
  3216.  
  3217.         mov    cl,bl
  3218.         mov    dx,bpline
  3219.         mul    dx
  3220.  
  3221.         shr    bx,1
  3222.         shr    bx,1
  3223.         shr    bx,1
  3224.         add    bx,ax
  3225.  
  3226.         mov    ax,word ptr [tpage]
  3227.         and    ax,000fh
  3228.         add    bx,ax
  3229.  
  3230.         mov    ax,word ptr [tpage]
  3231.         shr    ax,1
  3232.         shr    ax,1
  3233.         shr    ax,1
  3234.         shr    ax,1
  3235.         add    ax,word ptr [tpage+2]
  3236.  
  3237.         mov    word ptr [targetscr],bx
  3238.         mov    word ptr [targetscr+2],ax
  3239.         xor    cl,7
  3240.         inc    cl
  3241.         and    cl,7
  3242.         mov    targetshft,cl
  3243.  
  3244.         xor    ax,ax
  3245.         sub    ax,bpline        ; negate bpline
  3246.         mov    bpline,ax
  3247.  
  3248.  
  3249. ;-----------------------------------------------
  3250. movevideobl_23:
  3251.         mov    cl,targetshft
  3252.         mov    ch,lastbytemask
  3253.         mov    bx,0ffh     ; bx = 00000000 11111111
  3254.         mov    al,ch        ; al = 11110000
  3255.         cbw            ; ax = 11111111 11110000
  3256.  
  3257.         cmp    varpixelrowlen,1 ;if only 1 byte to move then
  3258.         jne    movevideobl_16
  3259.  
  3260.                     ; create start and end mask based
  3261.                     ; on one byte
  3262.         mov    bl,ch        ; bx = 00000000 11110000
  3263.         mov    ah,ch        ;
  3264.         xor    al,al        ; ax = 11110000 00000000
  3265.  
  3266. movevideobl_16: shl    ax,cl
  3267.         shl    bx,cl
  3268.  
  3269.         mov    bl,al        ; al=endmask right
  3270.         mov    al,8        ; ah=endmask left
  3271.         mov    varendmaskl,ax
  3272.         mov    ah,bl        ;
  3273.         mov    varendmaskr,ax
  3274.         mov    ah,bh        ; bh=startmask
  3275.         mov    varstartmask,ax
  3276.  
  3277.  
  3278.         ; set up graphics controller
  3279.         mov    dx,3ceh     ; dx := graphics controller i/o port
  3280.  
  3281.         mov    ax,0005     ; ah := 0 (read mode 0, write mode 0)
  3282.         out    dx,ax        ; al := 5 (mode register)
  3283.  
  3284.         mov    ax,3        ; ah := value for data rotate/function
  3285.         out    dx,ax        ; 0 is normal put
  3286.  
  3287.  
  3288. ;-----------------------------------------------
  3289. movevideobl_22: mov    ax,0ff08h    ; ah := 0ffh (value for bit mask reg)
  3290.         out    dx,ax        ; set up bit mask reg
  3291.  
  3292.         mov    ax,0802h    ; ah := 1000b (value for map mask reg)
  3293.                     ; al := 2 (map mask register number)
  3294.         mov    bx,0304h    ; ah := 3 (plane #3)
  3295.                     ; al := 4 (read map select)
  3296.  
  3297. movevideobl_01: push    ax        ; plane for writing
  3298.         push    bx        ; plane for reading
  3299.         lds    si,sourcescr
  3300.         les    di,workbuffer
  3301.  
  3302.         mov    dl,0c4h     ; dx := 3c4h (sequence i/o port)
  3303.         out    dx,ax
  3304.  
  3305.         mov    dl,0ceh     ; dx := graphics controller i/o port
  3306.         mov    ax,bx
  3307.         out    dx,ax
  3308.  
  3309.         mov    bx,varpixelrowlen
  3310.         mov    cl,sourceshft
  3311.  
  3312.         or    cl,cl        ; bit shifts?
  3313.         jz    mvetobuf_06
  3314.  
  3315.  
  3316.         ; routine for non-aligned bit blocks
  3317. mvetobuf_04:    lodsw
  3318.         dec    si
  3319.         rol    ax,cl
  3320.         stosb
  3321.         dec    bx
  3322.         jnz    mvetobuf_04
  3323.         jmp    short mvetoscr_09
  3324.  
  3325.         ; routine for byte-aligned bit blocks
  3326. mvetobuf_06:    mov    cx,bx
  3327.         shr    cx,1
  3328.         rep    movsw
  3329.         adc    cx,0
  3330.         rep    movsb
  3331.  
  3332. mvetoscr_09:    lds    si,workbuffer
  3333.         les    di,targetscr
  3334.  
  3335.         mov    bx,varpixelrowlen
  3336.         mov    ch,lastbytemask
  3337.         mov    cl,targetshft
  3338.  
  3339.         cmp    cx,0ff00h    ; start and end must be byte aligned
  3340.         jne    mvetoscr_17
  3341.  
  3342.         ; routine for byte-aligned bit blocks
  3343.         mov    cx,bx
  3344.         shr    cx,1
  3345.         rep    movsw
  3346.         adc    cx,0
  3347.         rep    movsb
  3348.         jmp    mvetoscr_20
  3349.  
  3350.  
  3351.         ; routine for non-aligned bit blocks
  3352. mvetoscr_17:
  3353.         mov    ax,varstartmask     ; eg. 00000111
  3354.         out    dx,ax
  3355.  
  3356.         lodsw                ; eg. 10101110 11111111
  3357.         dec    si            ;      <junk>    8 bits
  3358.         or    cl,cl            ; shift?
  3359.         jnz    mvetoscr_shf        ; go shift
  3360.  
  3361.         dec    bx            ; no shift, just dec bx
  3362.         jnz    mvetoscr_mid        ; more bytes
  3363.         jmp    short mvetoscr_end    ; do end bytes
  3364.  
  3365. mvetoscr_shf:    rol    ax,cl            ; eg. 01110111 11111101
  3366.         mov    ch,es:[di]        ; latch byte
  3367.         mov    es:[di],ah        ; and screen 00000111
  3368.         inc    di
  3369.         dec    bx            ; bx = 0
  3370.  
  3371. mvetoscr_mid:    dec    bx            ; bx < 0
  3372.         jng    mvetoscr_end
  3373.  
  3374.         push    ax
  3375.         mov    ax,0ff08h        ; set mask to 0ffh
  3376.         out    dx,ax
  3377.         pop    ax
  3378.  
  3379. mvetoscr_loop:    mov    es:[di],al
  3380.         inc    di
  3381.         lodsw
  3382.         dec    si
  3383.         rol    ax,cl
  3384.         dec    bx
  3385.         jnz    mvetoscr_loop
  3386.  
  3387.         ; set pixels at end of row
  3388. mvetoscr_end:    mov    bx,ax
  3389.         mov    ax,varendmaskl
  3390.         out    dx,ax
  3391.         mov    ch,es:[di]        ;latch byte
  3392.         mov    es:[di],bl        ; eg. 11111000
  3393.         inc    di
  3394.         mov    ax,varendmaskr        ; eg. 00000000
  3395.         out    dx,ax
  3396.         mov    ch,es:[di]        ;latch byte
  3397.         mov    es:[di],bh
  3398. ;-----------------------------------------------------move buffer to screen
  3399.  
  3400. mvetoscr_20:
  3401.         pop    bx
  3402.         pop    ax
  3403.         shr    ah,1
  3404.         dec    bh
  3405.         js    mvetoscr_30
  3406.         jmp    movevideobl_01
  3407.  
  3408. mvetoscr_30:    mov    ax,bpline
  3409.         add    word ptr [targetscr],ax
  3410.         add    word ptr [sourcescr],ax
  3411.         dec    varpixelrows
  3412.         jz    movevideobl_02
  3413.         jmp    movevideobl_22
  3414. movevideobl_02: jmp    vertmove_12
  3415.  
  3416.  
  3417. ; movevideobytes allows for direct latch block moves of pixel lines, rather
  3418. ; than having to (move and shift) a block of pixels to memory and back.
  3419.  
  3420. movevideobytes: mov    ax,argx1
  3421.         mov    cx,0ff07h
  3422.         and    cl,al
  3423.         xor    cl,7
  3424.         shl    ch,cl        ;mask for last byte
  3425.         mov    cl,8
  3426.         mov    varendmaskl,cx
  3427.         push    cx
  3428.  
  3429.         mov    bx,argx0
  3430.         mov    cx,0ff07h
  3431.         and    cl,bl
  3432.         shr    ch,cl        ;mask for start byte
  3433.         mov    cl,8
  3434.         mov    varstartmask,cx
  3435.  
  3436.         pop    cx
  3437.         shr    bx,1        ;number of bytes to mov
  3438.         shr    bx,1
  3439.         shr    bx,1
  3440.         shr    ax,1
  3441.         shr    ax,1
  3442.         shr    ax,1
  3443.         sub    ax,bx
  3444.         shl    ch,1
  3445.         adc    ax,0        ;1 byte   - start and end bytes same
  3446.                     ;2 bytes  - start and end bytes
  3447.                     ;>2 bytes - start, mid, end bytes
  3448.         mov    varpixelrowlen,ax
  3449.  
  3450.         cmp    ax,1        ;if 1 byte then
  3451.         jne    vertmove_01
  3452.         mov    ax,varstartmask
  3453.         and    ax,varendmaskl    ;combine both mask together
  3454.         mov    varstartmask,ax
  3455.         mov    varendmaskl,0
  3456.  
  3457. vertmove_01:    mov    ax,varstartmask
  3458.         xor    ah,0ffh
  3459.         jnz    vertmove_07
  3460.         mov    varstartmask,ax
  3461. vertmove_07:    mov    ax,varendmaskl
  3462.         xor    ah,0ffh
  3463.         jnz    vertmove_08
  3464.         mov    varendmaskl,ax
  3465. vertmove_08:
  3466.         mov    ax,argy1    ;number of lines
  3467.         sub    ax,argy0
  3468.         inc    ax
  3469.  
  3470. ;-----------------------------------------------
  3471. ; extablish addressing
  3472.         test    vertlines,8000h
  3473.         jnz    vertmove_00
  3474.  
  3475.         sub    ax,vertlines    ;subtract number of lines to scroll
  3476.         mov    varpixelrows,ax
  3477.  
  3478.         mov    ax,argy0    ;source     ;   +----------+
  3479.         add    ax,vertlines            ;   +----/\----+
  3480.         mov    bx,argx0            ;   |           |
  3481.                             ;   |           |
  3482.                             ;   +----------+
  3483.         mov    dx,bpline
  3484.         mul    dx
  3485.         shr    bx,1
  3486.         shr    bx,1
  3487.         shr    bx,1
  3488.         add    bx,ax
  3489.  
  3490.         mov    ax,word ptr [spage]
  3491.         and    ax,000fh
  3492.         add    bx,ax
  3493.  
  3494.         mov    ax,word ptr [spage]
  3495.         shr    ax,1
  3496.         shr    ax,1
  3497.         shr    ax,1
  3498.         shr    ax,1
  3499. ;        add    ax,0a000h
  3500.         add    ax,word ptr [spage+2]
  3501.         mov    ds,ax
  3502.         mov    si,bx
  3503.  
  3504.         mov    ax,argy2    ;target
  3505.         mov    bx,argx2
  3506.  
  3507.         mov    dx,bpline
  3508.         mul    dx
  3509.         shr    bx,1
  3510.         shr    bx,1
  3511.         shr    bx,1
  3512.         add    bx,ax
  3513.  
  3514.         mov    ax,word ptr [tpage]
  3515.         and    ax,000fh
  3516.         add    bx,ax
  3517.  
  3518.         mov    ax,word ptr [tpage]
  3519.         shr    ax,1
  3520.         shr    ax,1
  3521.         shr    ax,1
  3522.         shr    ax,1
  3523.         add    ax,word ptr [tpage+2]
  3524.  
  3525.         mov    es,ax
  3526.         mov    di,bx
  3527.  
  3528.  
  3529.         mov    bx,bpline
  3530.         sub    bx,varpixelrowlen
  3531.         mov    varpixelcontlen,bx
  3532.  
  3533.         jmp    short vertmove_31
  3534.  
  3535.  
  3536. vertmove_00:    add    ax,vertlines    ;subtract number of lines to scroll
  3537.         mov    varpixelrows,ax
  3538.  
  3539.         mov    ax,argy0    ;source     ;   +----------+
  3540.         add    ax,varpixelrows         ;   |           |
  3541.         dec    ax                ;   |           |
  3542.         mov    bx,argx0            ;   +----\/----+
  3543.                             ;   +----------+
  3544.  
  3545.         mov    dx,bpline
  3546.         mul    dx
  3547.         shr    bx,1
  3548.         shr    bx,1
  3549.         shr    bx,1
  3550.         add    bx,ax
  3551.  
  3552.         mov    ax,word ptr [spage]
  3553.         and    ax,000fh
  3554.         add    bx,ax
  3555.  
  3556.         mov    ax,word ptr [spage]
  3557.         shr    ax,1
  3558.         shr    ax,1
  3559.         shr    ax,1
  3560.         shr    ax,1
  3561. ;        add    ax,0a000h
  3562.         add    ax,word ptr [spage+2]
  3563.         mov    ds,ax
  3564.         mov    si,bx
  3565.  
  3566.         mov    ax,argy1
  3567.         sub    ax,argy0
  3568.         add    ax,argy2
  3569.         mov    bx,argx2    ;target
  3570.  
  3571.         mov    dx,bpline
  3572.         mul    dx
  3573.         shr    bx,1
  3574.         shr    bx,1
  3575.         shr    bx,1
  3576.         add    bx,ax
  3577.  
  3578.         mov    ax,word ptr [tpage]
  3579.         and    ax,000fh
  3580.         add    bx,ax
  3581.  
  3582.         mov    ax,word ptr [tpage]
  3583.         shr    ax,1
  3584.         shr    ax,1
  3585.         shr    ax,1
  3586.         shr    ax,1
  3587.         add    ax,word ptr [tpage+2]
  3588.  
  3589.         mov    es,ax
  3590.         mov    di,bx
  3591.  
  3592.         mov    ax,bpline
  3593.         not    ax
  3594.         inc    ax
  3595.         sub    ax,varpixelrowlen
  3596.         mov    varpixelcontlen,ax
  3597.  
  3598. ;-----------------------------------------------
  3599. vertmove_31:    mov    dx,3ceh     ; dx := graphics controller i/o port
  3600.  
  3601.         ; check if we need to move backwards
  3602.  
  3603.         mov    ax,argy0
  3604.         cmp    ax,argy2        ;compare vertical y's
  3605.         jne    vertmove_02        ;jump if not same line
  3606.  
  3607.         mov    ax,word ptr [spage]    ;compare base video segs
  3608.         cmp    ax,word ptr [tpage]
  3609.         jne    vertmove_02        ;jump if different pages
  3610.  
  3611.         mov    ax,word ptr [spage+2]    ;compare base video segs
  3612.         cmp    ax,word ptr [tpage+2]
  3613.         jne    vertmove_02        ;jump if different pages
  3614.  
  3615.         mov    ax,argx0        ;compare end and start segments
  3616.         cmp    ax,argx2
  3617.         jge    vertmove_02        ;jump if tail < begining
  3618.  
  3619.         std
  3620.         mov    ax,varpixelrowlen
  3621.         dec    ax
  3622.         add    si,ax
  3623.         add    di,ax
  3624.         inc    ax
  3625.  
  3626.         add    ax,bpline
  3627.         mov    varpixelcontlen,ax
  3628.         jmp    vertmove_20
  3629.  
  3630. vertmove_02:    mov    cx,varpixelrowlen
  3631.  
  3632.         mov    ax,varstartmask  ; ah := 0ffh (value for bit mask reg)
  3633.         or    ah,ah
  3634.         jz    vertmove_09
  3635.  
  3636.         ; set up graphics controller
  3637.         mov    dl,0ceh     ; dx := graphics controller i/o port
  3638.         out    dx,ax        ; set up bit mask reg
  3639.  
  3640.         mov    ax,0005     ; ah := 0 (read mode 0, write mode 0)
  3641.         out    dx,ax        ; al := 5 (mode register)
  3642.  
  3643.         mov    bx,0802h    ; bh := 1000b (value for map mask reg)
  3644.                     ; bl := 2 (map mask register number)
  3645.         mov    ax,0304h    ; ah := 3 (plane #3)
  3646.                     ; al := 4 (read map select)
  3647.  
  3648. vertmove_03:
  3649.         mov    dl,0ceh     ; dx := graphics controller i/o port
  3650.         out    dx,ax        ; set read map select
  3651.  
  3652.         mov    dl,0c4h     ; dx := 3c4h (sequence i/o port)
  3653.         xchg    ax,bx
  3654.         out    dx,ax
  3655.         xchg    ax,bx
  3656.  
  3657.         mov    dl,ds:[si]    ; get start byte
  3658.         or    es:[di],dl    ; latch destination bytes
  3659.         mov    es:[di],dl    ; mask new info
  3660.  
  3661.         shr    bh,1
  3662.         dec    ah
  3663.         jns    vertmove_03
  3664.  
  3665.         dec    cx        ; 1 byte   - start and end bytes same
  3666.         jcxz    vertmove_06    ; 2 bytes  - start and end bytes
  3667.                     ;>2 bytes  - start, mid, end bytes
  3668.         inc    si
  3669.         inc    di
  3670.  
  3671. vertmove_09:    test    varendmaskl+1,0ffh
  3672.         jz    vertmove_10
  3673.         dec    cx
  3674. vertmove_10:    jcxz    vertmove_04    ;do end part of scroll
  3675.  
  3676. ; middle part of direct memory scroll
  3677.  
  3678.         ; the sequencer must be set back to all planes
  3679.         mov    dl,0c4h     ; dx := 3c4h (sequence i/o port)
  3680.         mov    ax,0f02h    ; bh := 1111b (value for map mask reg)
  3681.         out    dx,ax        ; bl := 2 (map mask register number)
  3682.  
  3683.         ; set bit mask. The book is incorrect in stating that
  3684.         ; write mode 1 ignores the bit mask.
  3685.         mov    dl,0ceh     ; dx := graphics controller i/o port
  3686.         mov    ax,0008h    ; ah := 000h (ignore bits, use latches)
  3687.         out    dx,ax        ; set up bit mask reg
  3688.  
  3689.         mov    ax,0105     ; ah := 0 (read mode 0, write mode 1)
  3690.         out    dx,ax        ; al := 5 (mode register)
  3691.  
  3692.         rep    movsb
  3693.  
  3694. ; end part of direct memory scroll
  3695. vertmove_04:
  3696.         mov    ax,varendmaskl    ; ah := 0ffh (value for bit mask reg)
  3697.         or    ah,ah
  3698.         jz    vertmove_06
  3699.  
  3700.         mov    dl,0ceh     ; dx := graphics controller i/o port
  3701.         out    dx,ax        ; set up bit mask reg
  3702.  
  3703.         mov    ax,0005     ; ah := 0 (read mode 0, write mode 0)
  3704.         out    dx,ax        ; al := 5 (mode register)
  3705.  
  3706.         mov    bx,0802h    ; bh := 1000b (value for map mask reg)
  3707.                     ; bl := 2 (map mask register number)
  3708.         mov    ax,0304h    ; ah := 3 (plane #3)
  3709.                     ; al := 4 (read map select)
  3710.  
  3711. vertmove_05:    mov    dl,0ceh     ; dx := graphics controller i/o port
  3712.         out    dx,ax        ; set read map select
  3713.  
  3714.         mov    dl,0c4h     ; dx := 3c4h (sequence i/o port)
  3715.         xchg    ax,bx
  3716.         out    dx,ax
  3717.         xchg    ax,bx
  3718.  
  3719.         mov    dl,ds:[si]    ; get start byte
  3720.         or    es:[di],dl    ; latch destination bytes
  3721.         mov    es:[di],dl    ; mask new info
  3722.  
  3723.         shr    bh,1
  3724.         dec    ah
  3725.         jns    vertmove_05
  3726.  
  3727.         inc    si
  3728.         inc    di
  3729.  
  3730. vertmove_06:    ;mov     ax,varpixelcontlen
  3731.         add    si,varpixelcontlen
  3732.         add    di,varpixelcontlen
  3733.         dec    varpixelrows
  3734.         jz    vertmove_12_F
  3735.         jmp    vertmove_02
  3736. vertmove_12_F:    jmp    vertmove_12
  3737.  
  3738.  
  3739. ;-----------------------------------------------
  3740. vertmove_20:    mov    cx,varpixelrowlen
  3741.  
  3742.         mov    ax,varendmaskl    ; ah := 0ffh (value for bit mask reg)
  3743.         or    ah,ah
  3744.         jz    vertmove_21
  3745.  
  3746.         ; set up graphics controller
  3747.         mov    dl,0ceh     ; dx := graphics controller i/o port
  3748.         out    dx,ax        ; set up bit mask reg
  3749.  
  3750.         mov    ax,0005     ; ah := 0 (read mode 0, write mode 0)
  3751.         out    dx,ax        ; al := 5 (mode register)
  3752.  
  3753.         mov    bx,0802h    ; bh := 1000b (value for map mask reg)
  3754.                     ; bl := 2 (map mask register number)
  3755.         mov    ax,0304h    ; ah := 3 (plane #3)
  3756.                     ; al := 4 (read map select)
  3757.  
  3758. vertmove_22:    mov    dl,0ceh     ; dx := graphics controller i/o port
  3759.         out    dx,ax        ; set read map select
  3760.  
  3761.         mov    dl,0c4h     ; dx := 3c4h (sequence i/o port)
  3762.         xchg    ax,bx
  3763.         out    dx,ax
  3764.         xchg    ax,bx
  3765.  
  3766.         mov    dl,ds:[si]    ; get start byte
  3767.         or    es:[di],dl    ; latch destination bytes
  3768.         mov    es:[di],dl    ; mask new info
  3769.  
  3770.         shr    bh,1
  3771.         dec    ah
  3772.         jns    vertmove_22
  3773.  
  3774.         dec    cx        ; 1 byte   - start and end bytes same
  3775.         jcxz    vertmove_23    ; 2 bytes  - start and end bytes
  3776.                     ;>2 bytes  - start, mid, end bytes
  3777.  
  3778.         dec    si
  3779.         dec    di
  3780.  
  3781. vertmove_21:    test    varstartmask+1,0ffh
  3782.         jz    vertmove_24
  3783.         dec    cx
  3784. vertmove_24:    jcxz    vertmove_25    ;do begining part of scroll
  3785.  
  3786. ; middle part of direct memory scroll
  3787.         mov    dl,0c4h     ; dx := 3c4h (sequence i/o port)
  3788.         mov    ax,0f02h    ; bh := 1111b (value for map mask reg)
  3789.         out    dx,ax        ; bl := 2 (map mask register number)
  3790.  
  3791.         mov    dl,0ceh     ; dx := graphics controller i/o port
  3792.         mov    ax,0008h    ; ah := 0ffh (value for bit mask reg)
  3793.         out    dx,ax        ; set up bit mask reg
  3794.  
  3795.         mov    ax,0105     ; ah := 0 (read mode 0, write mode 1)
  3796.         out    dx,ax        ; al := 5 (mode register)
  3797.  
  3798.         rep    movsb        ; movsb backwards to start byte
  3799.  
  3800. ; end part of direct memory scroll
  3801. vertmove_25:
  3802.         mov    ax,varstartmask ; ah := 0ffh (value for bit mask reg)
  3803.         test    ah,0ffh
  3804.         jz    vertmove_23
  3805.  
  3806.         mov    dl,0ceh     ; dx := graphics controller i/o port
  3807.         out    dx,ax        ; set up bit mask reg
  3808.  
  3809.         mov    ax,0005     ; ah := 0 (read mode 0, write mode 0)
  3810.         out    dx,ax        ; al := 5 (mode register)
  3811.  
  3812.         mov    bx,0802h    ; bh := 1000b (value for map mask reg)
  3813.                     ; bl := 2 (map mask register number)
  3814.         mov    ax,0304h    ; ah := 3 (plane #3)
  3815.                     ; al := 4 (read map select)
  3816.  
  3817. vertmove_26:    mov    dl,0ceh     ; dx := graphics controller i/o port
  3818.         out    dx,ax        ; set read map select
  3819.  
  3820.         mov    dl,0c4h     ; dx := 3c4h (sequence i/o port)
  3821.         xchg    ax,bx
  3822.         out    dx,ax
  3823.         xchg    ax,bx
  3824.  
  3825.         mov    dl,ds:[si]    ; get start byte
  3826.         or    es:[di],dl    ; latch destination bytes
  3827.         mov    es:[di],dl    ; mask new info
  3828.  
  3829.         shr    bh,1
  3830.         dec    ah
  3831.         jns    vertmove_26
  3832.  
  3833.         dec    si
  3834.         dec    di
  3835.  
  3836. vertmove_23:
  3837.         add    si,varpixelcontlen
  3838.         add    di,varpixelcontlen
  3839.         dec    varpixelrows
  3840.         jz    vertmove_12
  3841.         jmp    vertmove_20
  3842.  
  3843.  
  3844.  
  3845. ; restore screen controller
  3846. vertmove_12:    mov    dx,3c4h     ; dx := 3c4h (sequence i/o port)
  3847.         mov    ax,0f02h
  3848.         out    dx,ax
  3849.  
  3850.         mov    dl,0ceh
  3851.         mov    ax,003
  3852.         out    dx,ax
  3853.  
  3854.         mov    ax,0005
  3855.         out    dx,ax
  3856.  
  3857.         mov    ax,0f07h
  3858.         out    dx,ax
  3859.  
  3860.         mov    ax,0ff08h
  3861.         out    dx,ax
  3862.  
  3863.         cld
  3864.  
  3865.         pop    di
  3866.         pop    si
  3867.         pop    es
  3868.         pop    ds
  3869.         ret
  3870.  
  3871. movevideopixels endp
  3872.  
  3873. setvpage    proc    far pagen:word
  3874.         push    ds
  3875.         push    si
  3876.         push    es
  3877.         push    di
  3878.  
  3879.         lds    si,cs:TDtable
  3880.         mov    ax,pagen
  3881.         cmp    ax,ds:[si].vmaxpages
  3882.         jg    novpage
  3883.  
  3884.         mov    bx,40h
  3885.         mov    ds,bx
  3886.         mov    si,62h
  3887.         mov    ds:[si],al
  3888.         mov    si,4eh
  3889.         xor    bx,bx
  3890.         or    al,al
  3891.         jz    vpageit
  3892.         mov    bx,8000h
  3893. vpageit:    mov    ds:[si],bx
  3894.  
  3895.         mov    ah,5
  3896.         int    10h
  3897.  
  3898. novpage:    pop    di
  3899.         pop    es
  3900.         pop    si
  3901.         pop    ds
  3902.         ret
  3903. setvpage    endp
  3904.  
  3905. setapage    proc    far pagen:word
  3906.         push    ds
  3907.         push    si
  3908.         push    es
  3909.         push    di
  3910.  
  3911.         lds    si,cs:TDtable
  3912.         mov    ax,pagen
  3913.         cmp    ax,ds:[si].vmaxpages
  3914.         jg    noapage
  3915.  
  3916.         or    al,al        ; if 0 then mov 0 to activepage
  3917.         mov    ds:[si].activepage,0
  3918.         jz    noapage
  3919.         mov    ds:[si].activepage,8000h
  3920.  
  3921. noapage:    pop    di
  3922.         pop    es
  3923.         pop    si
  3924.         pop    ds
  3925.         ret
  3926. setapage    endp
  3927.  
  3928. ;----------------------------------------------------------------------------;
  3929. ;                                         ;
  3930. ;----------------------------------------------------------------------------;
  3931. whichsvga    proc    near
  3932.         push    es
  3933.         push    di
  3934.         push    ds
  3935.         push    si
  3936.         push    dx
  3937.         push    cx
  3938.         push    bx
  3939.  
  3940.         mov    cs:vga512flag,0
  3941.         mov    cs:vga1024flag,0
  3942.         mov    cs:svgatype,-2
  3943.  
  3944.         call    getvgatype
  3945.         mov    ax,cs:svgatype
  3946.  
  3947.         pop    bx
  3948.         pop    cx
  3949.         pop    dx
  3950.         pop    si
  3951.         pop    ds
  3952.         pop    di
  3953.         pop    es
  3954.         ret
  3955. whichsvga    endp
  3956.  
  3957. ;----------------------------------------------------------------------------;
  3958. ;                                         ;
  3959. ;----------------------------------------------------------------------------;
  3960. nojmp    macro
  3961.     local    lbl
  3962.     jmp    lbl
  3963. lbl:
  3964.     endm
  3965.  
  3966.  
  3967. getvgatype    proc    near
  3968.         mov    si,1
  3969.         mov    ax,0c000h
  3970.         mov    es,ax
  3971.         cmp    word ptr es:[40h],'13'  ;ATI Signiture on the Video BIOS
  3972.         jnz    noati
  3973.  
  3974.         mov    cs:svgatype,x_ativga
  3975.         cli
  3976.         mov    dx,1ceh
  3977.         mov    al,0bbh
  3978.         out    dx,al
  3979.         inc    dl
  3980.         in    al,dx
  3981.         sti
  3982.         and    al,20h
  3983.         jz    no512
  3984.         mov    cs:vga512flag,1
  3985. no512:        jmp    fini
  3986.  
  3987. noati:        mov    ax,7000h        ;Test for Everex
  3988.         xor    bx,bx
  3989.         cld
  3990.         int    10h
  3991.         cmp    al,70h
  3992.         jnz    noev
  3993.  
  3994.         mov    cs:svgatype,x_everex
  3995.         and    ch,11000000b        ;how much memory on board
  3996.         jz    skp
  3997.         mov    cs:vga512flag,1
  3998. skp:                        ;fall through for Everex boards using Trident or Tseng4000
  3999.  
  4000. noev:        mov    ax,0bf03h        ;Test for Compaq
  4001.         xor    bx,bx
  4002.         mov    cx,bx
  4003.         int    10h
  4004.         cmp    ax,0bf03h
  4005.         jnz    nocp
  4006.         test    cl,40h            ;is 640x480x256 available?
  4007.         jz    nocp
  4008.         mov    cs:svgatype,x_compaq
  4009.         mov    cs:vga512flag,1
  4010.         jmp    fini
  4011.  
  4012. nocp:        mov    dx,3c4h         ;Test for NCR 77C22E
  4013.         mov    ax,0ff05h
  4014.         call    _isport2
  4015.         jnz    noncr
  4016.         mov    ax,5            ;Disable extended registers
  4017.         out    dx,ax
  4018.         mov    ax,0ff10h        ;Try to write to extended register 10
  4019.         call    _isport2        ;If it writes then not NCR
  4020.         jz    noncr
  4021.         mov    ax,105h         ;Enable extended registers
  4022.         out    dx,ax
  4023.         mov    ax,0ff10h
  4024.         call    _isport2
  4025.         jnz    noncr            ;If it does NOT write then not NCR
  4026.         mov    cs:svgatype,x_ncr
  4027.         mov    cs:vga512flag,1
  4028.         jmp    fini
  4029.  
  4030. noncr:        mov    dx,3c4h         ;Test for Trident
  4031.         mov    al,0bh
  4032.         out    dx,al
  4033.         inc    dl
  4034.         in    al,dx
  4035.         cmp    al,06h
  4036.         ja    notri
  4037.         cmp    al,2
  4038.         jb    notri
  4039.         mov    cs:svgatype,x_trident
  4040.         cmp    al,3
  4041.         jb    no89
  4042.         mov    cs:svgatype,x_t8900
  4043.         mov    dx,3d5h
  4044.         mov    al,1fh
  4045.         out    dx,al
  4046.         inc    dx
  4047.         in    al,dx
  4048.         and    al,3
  4049.         cmp    al,1
  4050.         jb    notmem
  4051.         mov    cs:vga512flag,1
  4052.         je    notmem
  4053.         mov    cs:vga1024flag,1
  4054. notmem:     jmp    fini
  4055.  
  4056. no89:        mov    cs:vga512flag,1
  4057.         jmp    fini
  4058.  
  4059. notri:        mov    ax,6f00h        ;Test for Video 7
  4060.         xor    bx,bx
  4061.         cld
  4062.         int    10h
  4063.         cmp    bx,'V7'
  4064.         jnz    nov7
  4065.         mov    cs:svgatype,x_video7
  4066.         mov    ax,6f07h
  4067.         cld
  4068.         int    10h
  4069.         and    ah,7fh
  4070.         cmp    ah,1
  4071.         jbe    skp2
  4072.         mov    cs:vga512flag,1
  4073. skp2:        cmp    ah,3
  4074.         jbe    skp3
  4075.         mov    cs:vga1024flag,1
  4076. skp3:        jmp    fini
  4077.  
  4078. nov7:        mov    dx,3d4h         ;Test for GENOA GVGA
  4079.         mov    ax,032eh        ;check for Herchi Register
  4080.         call    _isport2
  4081.         jnz    nogn
  4082.         mov    dx,3c4h         ;check for memory segment register
  4083.         mov    ax,3f06h
  4084.         call    _isport2
  4085.         jnz    nogn
  4086.         mov    cs:svgatype,x_genoa
  4087.         mov    cs:vga512flag,1
  4088.         jmp    fini
  4089.  
  4090. nogn:        call    _cirrus         ;Test for Cirrus
  4091.         cmp    cs:svgatype,x_cirrus
  4092.         jne    noci
  4093.         jmp    fini
  4094.  
  4095. noci:        mov    dx,3ceh         ;Test for Paradise
  4096.         mov    al,9            ;check Bank switch register
  4097.         out    dx,al
  4098.         inc    dx
  4099.         in    al,dx
  4100.         dec    dx
  4101.         or    al,al
  4102.         jnz    nopd
  4103.  
  4104.         mov    ax,50fh         ;turn off write protect on VGA registers
  4105.         out    dx,ax
  4106.         mov    cx,1
  4107.         mov    dx,3ceh         ;Test for Paradise
  4108.         call    _chkbk
  4109.         jc    nopd            ;if bank 0 and 1 same not paradise
  4110.         mov    cs:svgatype,x_paradise
  4111.         mov    dx,3ceh
  4112.         mov    al,0bh            ;512k detect from Bob Berry
  4113.         out    dx,al
  4114.         inc    dx
  4115.         in    al,dx
  4116.         test    al,80h            ;if top bit set then 512k
  4117.         jz    nop512
  4118.         mov    cs:vga512flag,1
  4119. nop512:     jmp    fini
  4120.  
  4121. nopd:        mov    ax,5f00h        ;Test for Chips & Tech
  4122.         xor    bx,bx
  4123.         cld
  4124.         int    10h
  4125.         cmp    al,5fh
  4126.         jnz    noct
  4127.         mov    cs:svgatype,x_chipstech
  4128.         cmp    bh,1
  4129.         jb    skp4
  4130.         mov    cs:vga512flag,1
  4131. skp4:        jmp    fini
  4132.  
  4133. noct:        mov    ch,0
  4134.         mov    dx,3d4h         ;check for Tseng 4000 series
  4135.         mov    ax,0f33h
  4136.         call    _isport2
  4137.         jnz    not4
  4138.         mov    ch,1
  4139.  
  4140.         mov    dx,3bfh         ;Enable access to extended registers
  4141.         mov    al,3
  4142.         out    dx,al
  4143.         mov    dx,3d8h
  4144.         mov    al,0a0h
  4145.         out    dx,al
  4146.         jmp    short yes4
  4147.  
  4148. not4:        mov    dx,3d4h         ;Test for Tseng 3000 or 4000
  4149.         mov    ax,1f25h        ;is the Overflow High register there?
  4150.         call    _isport2
  4151.         jnz    nots
  4152.         mov    al,03fh         ;bottom six bits only
  4153.         jmp    short yes3
  4154. yes4:        mov    al,0ffh
  4155. yes3:        mov    dx,3cdh         ;test bank switch register
  4156.         call    _isport1
  4157.         jnz    nots
  4158.         mov    cs:svgatype,x_tseng
  4159.         cmp    ch,0
  4160.         jnz    t4mem
  4161.         mov    cs:vga512flag,1
  4162.         jmp    fini
  4163.  
  4164. t4mem:        mov    dx,3d4h         ;Tseng 4000 memory detect 1meg
  4165.         mov    al,37h
  4166.         out    dx,al
  4167.         inc    dx
  4168.         in    al,dx
  4169.         test    al,1000b        ;if using 64kx4 RAMs then no more than 256k
  4170.         jz    nomem
  4171.         and    al,3
  4172.         cmp    al,1            ;if 8 bit wide bus then only two 256kx4 RAMs
  4173.         jbe    nomem
  4174.         mov    cs:vga512flag,1
  4175.         cmp    al,2            ;if 16 bit wide bus then four 256kx4 RAMs
  4176.         je    nomem
  4177.         mov    cs:vga1024flag,1    ;full meg with eight 256kx4 RAMs
  4178. nomem:        mov    cs:svgatype,x_tseng4
  4179.         jmp    fini
  4180.  
  4181. nots:
  4182.         mov    dx,3ceh         ;Test for Above A or B chipsets
  4183.         mov    ax,200fh
  4184.         out    dx,ax
  4185.         inc    dx
  4186.         nojmp
  4187.         in    al,dx
  4188.         cmp    al,21h
  4189.         jz    verb
  4190.         cmp    al,20h
  4191.         jnz    noab
  4192.         mov    cs:svgatype,x_aheada
  4193.         mov    cs:vga512flag,1
  4194.         jmp    short fini
  4195.  
  4196. verb:        mov    cs:svgatype,x_aheadb
  4197.         mov    cs:vga512flag,1
  4198.         jmp    short fini
  4199.  
  4200. noab:        mov    dx,3deh         ;Test for Oak Technology
  4201.         mov    ax,0ff11h        ;look for bank switch register
  4202.         call    _isport2
  4203.         jz    oakok
  4204.  
  4205.         push    es
  4206.         push    di
  4207.         push    cx
  4208.  
  4209.         cld
  4210.         mov    ax,0c000h
  4211.         mov    es,ax
  4212.         xor    di,di
  4213.         mov    cx,256
  4214.  
  4215.         mov    al,'O'
  4216. findoak:    repne    scasb
  4217.         jcxz    notoak
  4218.  
  4219.         cmp    byte ptr es:[di],'A'
  4220.         jne    findoak
  4221.  
  4222.         cmp    byte ptr es:[di+1],'K'
  4223.         jne    findoak
  4224.  
  4225.         pop    cx
  4226.         pop    di
  4227.         pop    es
  4228.         jmp    short oakok
  4229.  
  4230.  
  4231. notoak:     pop    cx
  4232.         pop    di
  4233.         pop    es
  4234.         jmp    short nooak
  4235.  
  4236. oakok:        mov    cs:svgatype,x_oaktech
  4237.         mov    al,0dh
  4238.         out    dx,al
  4239.         inc    dx
  4240.         nojmp
  4241.         in    al,dx
  4242.         test    al,80h
  4243.         jz    no4ram
  4244.         mov    cs:vga512flag,1
  4245. no4ram:     jmp    short fini
  4246.  
  4247. nooak:        mov    si,0
  4248.  
  4249. fini:        mov    ax,si
  4250.         ret
  4251. getvgatype    endp
  4252.  
  4253.  
  4254. _cirrus     proc near
  4255.         mov    dx,3d4h     ; assume 3dx addressing
  4256.         mov    al,0ch        ; screen a start address hi
  4257.         out    dx,al        ; select index
  4258.         inc    dx        ; point to data
  4259.         mov    ah,al        ; save index in ah
  4260.         in    al,dx        ; get screen a start address hi
  4261.         xchg    ah,al        ; swap index and data
  4262.         push    ax        ; save old value
  4263.         push    dx        ; save crtc address
  4264.         xor    al,al        ; clear crc
  4265.         out    dx,al        ; and out to the crtc
  4266.  
  4267.         mov    al,1fh        ; Eagle ID register
  4268.         dec    dx        ; back    to index
  4269.         out    dx,al        ; select index
  4270.         inc    dx        ; point to data
  4271.         in    al,dx        ; read the id register
  4272.         mov    bh,al        ; and save it in bh
  4273.  
  4274.         mov    cl,4        ; nibble swap rotate count
  4275.         mov    dx,3c4h     ; sequencer/extensions
  4276.         mov    bl,6        ; extensions enable register
  4277.  
  4278.         ror    bh,cl        ; compute extensions disable value
  4279.         mov    ax,bx        ; extensions disable
  4280.         out    dx,ax        ; disable extensions
  4281.         inc    dx        ; point to data
  4282.         in    al,dx        ; read enable flag
  4283.         or    al,al        ; disabled ?
  4284.         jnz    exit        ; nope, not an cirrus
  4285.  
  4286.         ror    bh,cl        ; compute extensions enable value
  4287.         dec    dx        ; point to index
  4288.         mov    ax,bx        ; extensions enable
  4289.         out    dx,ax        ; enable extensions
  4290.         inc    dx        ; point to data
  4291.         in    al,dx        ; read enable flag
  4292.         cmp    al,1        ; enabled ?
  4293.         jne    exit        ; nope, not an cirrus
  4294.         mov    cs:svgatype,x_cirrus
  4295.  
  4296. exit:        pop    dx        ; restore crtc address
  4297.         dec    dx        ; point to index
  4298.         pop    ax        ; recover crc index and data
  4299.         out    dx,ax        ; restore crc value
  4300.         ret
  4301. _cirrus     endp
  4302.  
  4303. _chkbk        proc    near        ;bank switch check routine
  4304.         push    es
  4305.         mov    di,0b800h
  4306.         mov    es,di
  4307.         xor    di,di
  4308.         mov    bx,1234h
  4309.         call    _gochk
  4310.         jnz    badchk
  4311.         mov    bx,4321h
  4312.         call    _gochk
  4313.         jnz    badchk
  4314.         clc
  4315.         pop    es
  4316.         ret
  4317. badchk:     stc
  4318.         pop    es
  4319.         ret
  4320. _chkbk        endp
  4321.  
  4322. _gochk        proc    near
  4323.         push    si
  4324.         push    es
  4325.         mov    si,bx
  4326.  
  4327.         mov    al,cl
  4328.         call    _pdrsub
  4329.         xchg    bl,es:[di]
  4330.         mov    al,ch
  4331.         call    _pdrsub
  4332.         xchg    bh,es:[di]
  4333.  
  4334.         xchg    si,bx
  4335.  
  4336.         mov    al,cl
  4337.         call    _pdrsub
  4338.         xor    bl,es:[di]
  4339.         mov    al,ch
  4340.         call    _pdrsub
  4341.         xor    bh,es:[di]
  4342.  
  4343.         xchg    si,bx
  4344.  
  4345.         mov    al,ch
  4346.         call    _pdrsub
  4347.         mov    es:[di],bh
  4348.         mov    al,cl
  4349.         call    _pdrsub
  4350.         mov    es:[di],bl
  4351.  
  4352.         mov    al,0
  4353.         call    _pdrsub
  4354.         or    si,si
  4355.         pop    es
  4356.         pop    si
  4357.         ret
  4358. _gochk        endp
  4359.  
  4360.  
  4361. _pdrsub     proc    near        ;Paradise
  4362.         mov    ah,al
  4363.         mov    al,9
  4364.         out    dx,ax
  4365.         ret
  4366. _pdrsub     endp
  4367.  
  4368.  
  4369. _isport2    proc   near
  4370.         push    bx
  4371.         mov    bx,ax
  4372.         out    dx,al
  4373.         mov    ah,al
  4374.         inc    dx
  4375.         in    al,dx
  4376.         dec    dx
  4377.         xchg    al,ah
  4378.         push    ax
  4379.         mov    ax,bx
  4380.         out    dx,ax
  4381.         out    dx,al
  4382.         mov    ah,al
  4383.         inc    dx
  4384.         in    al,dx
  4385.         dec    dx
  4386.         and    al,bh
  4387.         cmp    al,bh
  4388.         jnz    noport2
  4389.         mov    al,ah
  4390.         mov    ah,0
  4391.         out    dx,ax
  4392.         out    dx,al
  4393.         mov    ah,al
  4394.         inc    dx
  4395.         in    al,dx
  4396.         dec    dx
  4397.         and    al,bh
  4398.         cmp    al,0
  4399. noport2:    pop    ax
  4400.         out    dx,ax
  4401.         pop    bx
  4402.         ret
  4403. _isport2    endp
  4404.  
  4405. _isport1    proc   near
  4406.         mov    ah,al
  4407.         in    al,dx
  4408.         push    ax
  4409.         mov    al,ah
  4410.         out    dx,al
  4411.         in    al,dx
  4412.         and    al,ah
  4413.         cmp    al,ah
  4414.         jnz    noport1
  4415.         mov    al,0
  4416.         out    dx,al
  4417.         in    al,dx
  4418.         and    al,ah
  4419.         cmp    al,0
  4420. noport1:    pop    ax
  4421.         out    dx,al
  4422.         ret
  4423. _isport1    endp
  4424.  
  4425.         end
  4426.