home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / program / c / XLIB04C.ZIP / XMAIN.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-03-11  |  38.6 KB  |  1,302 lines

  1. ;-----------------------------------------------------------------------
  2. ; MODULE XMAIN
  3. ;
  4. ; Initialization, panning and split screen functions for all MODE X 256
  5. ; Color resolutions
  6. ;
  7. ; Compile with Tasm.
  8. ; C callable.
  9. ;
  10. ;
  11. ; ****** XLIB - Mode X graphics library                ****************
  12. ; ******                                               ****************
  13. ; ****** Written By Themie Gouthas                     ****************
  14. ;
  15. ; egg@dstos3.dsto.gov.au
  16. ; teg@bart.dsto.gov.au
  17. ;
  18. ; MODIFICATIONS:
  19. ;  26-9-92:          Pel panning code added
  20. ;  Dates forgotten:  Numerous ;^)
  21. ;-----------------------------------------------------------------------
  22.  
  23.  
  24. include xlib.inc
  25. include xmain.inc
  26.  
  27.  
  28.     .data
  29.  
  30.  
  31. ; Mode X CRTC register tweaks for various resolutions
  32.  
  33.  
  34. X320Y200 label  word
  35.     db      00      ; 0e3h    ; dot clock
  36.     db      02      ; Number of CRTC Registers to update
  37.     dw      00014h  ; turn off dword mode
  38.     dw      0e317h  ; turn on byte mode
  39.     dw      320     ; width
  40.     dw      200     ; height
  41.  
  42. X320Y240 label  word
  43.     db      0e3h    ; dot clock
  44.     db      10      ; Number of CRTC Registers to update
  45.     dw      00d06h  ; vertical total
  46.     dw      03e07h  ; overflow (bit 8 of vertical counts)
  47.     dw      04109h  ; cell height (2 to double-scan)
  48.     dw      0ea10h  ; v sync start
  49.     dw      0ac11h  ; v sync end and protect cr0-cr7
  50.     dw      0df12h  ; vertical displayed
  51.     dw      00014h  ; turn off dword mode
  52.     dw      0e715h  ; v blank start
  53.     dw      00616h  ; v blank end
  54.     dw      0e317h  ; turn on byte mode
  55.     dw      320     ; width
  56.     dw      240     ; height
  57.  
  58. X360Y200 label  word
  59.     db      0e7h    ; dot clock
  60.     db      08      ; Number of CRTC Registers to update
  61.     dw      06b00h  ; horz total
  62.     dw      05901h  ; horz displayed
  63.     dw      05a02h  ; start horz blanking
  64.     dw      08e03h  ; end horz blanking
  65.     dw      05e04h  ; start h sync
  66.     dw      08a05h  ; end h sync
  67.     dw      00014h  ; turn off dword mode
  68.     dw      0e317h  ; turn on byte mode
  69.     dw      360     ; width
  70.     dw      200     ; height
  71.  
  72. X360Y240  label word
  73.     db      0e7h    ; dot clock
  74.     db      17      ; Number of CRTC Registers to update
  75.     dw    06b00h    ; horz total
  76.     dw    05901h    ; horz displayed
  77.     dw    05a02h    ; start horz blanking
  78.     dw    08e03h    ; end horz blanking
  79.     dw    05e04h    ; start h sync
  80.     dw    08a05h    ; end h sync
  81.     dw      00d06h  ; vertical total
  82.     dw      03e07h  ; overflow (bit 8 of vertical counts)
  83.     dw      04109h  ; cell height (2 to double-scan)
  84.     dw      0ea10h  ; v sync start
  85.     dw      0ac11h  ; v sync end and protect cr0-cr7
  86.     dw      0df12h  ; vertical displayed
  87.     dw    02d13h    ; offset;
  88.     dw      00014h  ; turn off dword mode
  89.     dw      0e715h  ; v blank start
  90.     dw      00616h  ; v blank end
  91.     dw      0e317h  ; turn on byte mode
  92.     dw      360
  93.     dw      240
  94.  
  95. X376Y282 label word
  96.     db      0e7h
  97.     db      18
  98.     dw    06e00h    ; horz total
  99.     dw    05d01h    ; horz displayed
  100.     dw    05e02h    ; start horz blanking
  101.     dw    09103h    ; end horz blanking
  102.     dw    06204h    ; start h sync
  103.     dw    08f05h    ; end h sync
  104.     dw    06206h    ; vertical total
  105.     dw    0f007h    ; overflow
  106.     dw      06109h  ; cell height
  107.     dw      0310fh  ;
  108.     dw    03710h    ; v sync start
  109.     dw    08911h    ; v sync end and protect cr0-cr7
  110.     dw    03312h    ; vertical displayed
  111.     dw    02f13h    ; offset
  112.     dw    00014h    ; turn off dword mode
  113.     dw    03c15h    ; v blank start
  114.     dw    05c16h    ; v blank end
  115.     dw    0e317h    ; turn on byte mode
  116.     dw      376
  117.     dw      564
  118.  
  119.  
  120. X320Y400 label  word
  121.     db      0e3h    ; dot clock
  122.     db      03      ; Number of CRTC Registers to update
  123.     dw    04009h    ; cell height
  124.     dw      00014h  ; turn off dword mode
  125.     dw      0e317h  ; turn on byte mode
  126.     dw      320     ; width
  127.     dw      400     ; height
  128.  
  129. X320Y480 label  word
  130.     db      0e3h    ; dotclock
  131.     db      10      ; Number of CRTC Registers to update
  132.     dw      00d06h  ; vertical total
  133.     dw      03e07h  ; overflow (bit 8 of vertical counts)
  134.     dw      04009h  ; cell height (2 to double-scan)
  135.     dw      0ea10h  ; v sync start
  136.     dw      0ac11h  ; v sync end and protect cr0-cr7
  137.     dw      0df12h  ; vertical displayed
  138.     dw      00014h  ; turn off dword mode
  139.     dw      0e715h  ; v blank start
  140.     dw      00616h  ; v blank end
  141.     dw      0e317h  ; turn on byte mode
  142.     dw      320     ; width
  143.     dw      480     ; height
  144.  
  145. X360Y400 label  word
  146.     db      0e7h    ; dot clock
  147.     db      09      ; Number of CRTC Registers to update
  148.     dw      06b00h  ; horz total
  149.     dw      05901h  ; horz displayed
  150.     dw      05a02h  ; start horz blanking
  151.     dw      08e03h  ; end horz blanking
  152.     dw      05e04h  ; start h sync
  153.     dw      08a05h  ; end h sync
  154.     dw    04009h    ; cell height
  155.     dw      00014h  ; turn off dword mode
  156.     dw      0e317h  ; turn on byte mode
  157.     dw      360     ; width
  158.     dw      400     ; height
  159.  
  160.  
  161.  
  162. X360Y480  label word
  163.     db      0e7h
  164.     db      17
  165.     dw    06b00h    ; horz total
  166.     dw    05901h    ; horz displayed
  167.     dw    05a02h    ; start horz blanking
  168.     dw    08e03h    ; end horz blanking
  169.     dw    05e04h    ; start h sync
  170.     dw    08a05h    ; end h sync
  171.     dw    00d06h    ; vertical total
  172.     dw    03e07h    ; overflow
  173.     dw    04009h    ; cell height
  174.     dw    0ea10h    ; v sync start
  175.     dw    0ac11h    ; v sync end and protect cr0-cr7
  176.     dw    0df12h    ; vertical displayed
  177.     dw    02d13h    ; offset
  178.     dw    00014h    ; turn off dword mode
  179.     dw    0e715h    ; v blank start
  180.     dw    00616h    ; v blank end
  181.     dw    0e317h    ; turn on byte mode
  182.     dw      360
  183.     dw      480
  184.  
  185. X360Y360  label word
  186.     db      0e7h
  187.     db      15
  188.     dw    06b00h    ; horz total
  189.     dw    05901h    ; horz displayed
  190.         dw    05a02h    ; start horz blanking
  191.     dw    08e03h    ; end horz blanking
  192.     dw    05e04h    ; start h sync
  193.     dw    08a05h    ; end h sync
  194.     dw    04009h    ; cell height
  195.     dw    08810h    ; v sync start
  196.     dw    08511h    ; v sync end and protect cr0-cr7
  197.     dw    06712h    ; vertical displayed
  198.     dw      02d13h  ; offset
  199.     dw    00014h    ; turn off dword mode
  200.     dw    06d15h    ; v blank start
  201.     dw    0ba16h    ; v blank end
  202.     dw    0e317h    ; turn on byte mode
  203.     dw      360
  204.     dw      360
  205.  
  206.  
  207. X376Y308 label word
  208.     db      0e7h
  209.     db      18
  210.     dw    06e00h    ; horz total
  211.     dw    05d01h    ; horz displayed
  212.     dw    05e02h    ; start horz blanking
  213.     dw    09103h    ; end horz blanking
  214.     dw    06204h    ; start h sync
  215.     dw    08f05h    ; end h sync
  216.     dw    06206h    ; vertical total
  217.     dw    00f07h    ; overflow
  218.     dw      04009h  ;
  219.     dw      0310fh  ;
  220.     dw    03710h    ; v sync start
  221.     dw    08911h    ; v sync end and protect cr0-cr7
  222.     dw    03312h    ; vertical displayed
  223.     dw    02f13h    ; offset
  224.     dw    00014h    ; turn off dword mode
  225.     dw    03c15h    ; v blank start
  226.     dw    05c16h    ; v blank end
  227.     dw    0e317h    ; turn on byte mode
  228.     dw      376
  229.     dw      308
  230.  
  231. X376Y564 label word
  232.     db      0e7h
  233.     db      18
  234.     dw    06e00h    ; horz total
  235.     dw    05d01h    ; horz displayed
  236.     dw    05e02h    ; start horz blanking
  237.     dw    09103h    ; end horz blanking
  238.     dw    06204h    ; start h sync
  239.     dw    08f05h    ; end h sync
  240.     dw    06206h    ; vertical total
  241.     dw    0f007h    ; overflow
  242.     dw      06009h  ;
  243.     dw      0310fh  ;
  244.     dw    03710h    ; v sync start
  245.     dw    08911h    ; v sync end and protect cr0-cr7
  246.     dw    03312h    ; vertical displayed
  247.     dw    02f13h    ; offset
  248.     dw    00014h    ; turn off dword mode
  249.     dw    03c15h    ; v blank start
  250.     dw    05c16h    ; v blank end
  251.     dw    0e317h    ; turn on byte mode
  252.     dw      376
  253.     dw      564
  254.  
  255. LAST_X_MODE         equ    11
  256. ModeTable label word    ; Mode X tweak table
  257.     dw      offset X320Y200
  258.     dw      offset X320Y240
  259.     dw      offset X360Y200
  260.     dw      offset X360Y240
  261.     dw      offset X376Y282
  262.     dw      offset X320Y400
  263.     dw      offset X320Y480
  264.     dw      offset X360Y400
  265.     dw      offset X360Y480
  266.     dw      offset X360Y360
  267.     dw      offset X376Y308
  268.     dw      offset X376Y564
  269.  
  270.  
  271. PARAMS label byte
  272.  
  273.     _CurrXMode               dw 0   ; Current graphics mode index
  274.     _InGraphics              db 0   ; Flag indicating graphics activity
  275.     _ScrnPhysicalByteWidth   dw 0   ; Physical width in bytes of screen
  276.     _ScrnPhysicalPixelWidth  dw 0   ; Physical width in pixels of screen
  277.     _ScrnPhysicalHeight      dw 0   ; Physical Height of screen
  278.     _ErrorValue              db 0   ; Set after function calls
  279.  
  280.  
  281.     _SplitScrnActive         db 0   ; Flag indicating Split scrn activity
  282.     _DoubleBufferActive      dw 0   ; Flag indicating double buffering
  283.  
  284.     _SplitScrnScanLine       dw 0   ; Split Screen's starting scan line
  285.     _SplitScrnVisibleHeight  dw 0   ; Split Screen's height on screen
  286.  
  287.     _SplitScrnOffs           dw 0   ; Offset in video ram of Split Screen
  288.                     ; always = 0
  289.     _Page0_Offs              dw 0   ; Ofset in video ram of Main virtual
  290.                     ; screen ( = 0 if no split screen
  291.                     ; otherwise = offset of first byte
  292.                     ; after split screen
  293.     _Page1_Offs              dw 0   ; Ofset in video ram of Second virtual
  294.                     ; screen ( = 0 if no split screen
  295.                     ; otherwise = offset of first byte
  296.                     ; after split screen
  297.                     ; = Page0_Offs if Doubble buffering
  298.                     ; not enabled
  299.     _NonVisual_Offs          dw 0   ; Ofset in video ram of first byte
  300.                     ; of non visible ram
  301.     _ScrnLogicalByteWidth    dw 0   ; Logical width in bytes of screen
  302.     _ScrnLogicalPixelWidth   dw 0   ; Logical width in pixels of screen
  303.     _ScrnLogicalHeight       dw 0   ; Logical Height of screen
  304.  
  305.     _MaxScrollX              dw 0   ; Max X start position of Physical
  306.                     ; screen within virtual screen (in
  307.                     ; bytes)
  308.     _MaxScrollY              dw 0   ; Max Y start position of Physical
  309.                     ; screen within virtual screen
  310.  
  311.     _VisiblePageIdx          dw 0   ; Index of currently visible D.B.
  312.                     ; page
  313.  
  314.     PageAddrTable label word
  315.     _VisiblePageOffs     dw 0   ; Table containing starting offsets
  316.     _HiddenPageOffs         dw 0   ; of the double buffer pages
  317.  
  318.         _TopClip                 dw 0   ; Clipping Rectangle
  319.         _BottomClip              dw 0   ;
  320.         _LeftClip                dw 0   ; Left/Right coordinates in bytes
  321.         _RightClip               dw 0   ;
  322.     _PhysicalStartByteX      dw 0   ; X byte coord of physical screen
  323.                     ; relative to virtual virtual screen
  324.     _PhysicalStartPixelX     dw 0   ; X pixel coord of physical screen
  325.                     ; relative to virtual screen
  326.     _PhysicalStartY          dw 0   ; Y pixel coord of physical screen
  327.                     ; relative to virtual screen
  328.  
  329. PARAMS_END label byte
  330.  
  331. PARAM_COUNT equ ($-PARAMS)
  332.  
  333.  
  334. ; Index/data pairs for CRT Controller registers that differ between
  335. ; mode 13h and mode X.
  336.  
  337.     ;Pelpan values for 0,1,2,3 pixel panning to the left, respectively
  338.     PelPanMask              db      000h,002h,004h,006h
  339.  
  340. DoubleScanFlag db ?     ; Flag to indicate double scanned mode
  341.  
  342.     .code
  343.  
  344. ;-------------------------------------------------------------------------
  345. ; Local Logical Screen Width setting function
  346. ; cx = Requitrd Logical Width
  347. ;
  348. ; WARNING: no registers are preserved
  349.  
  350. SetLogicalScrWidth proc
  351.     mov   dx,CRTC_INDEX
  352.     mov   al,CRTC_OFFSET
  353.     out   dx,al
  354.     inc   dx
  355.  
  356.     mov   ax,cx
  357.     cmp   ax,[_ScrnPhysicalPixelWidth]; Is logical width >= physical width
  358.     jge   @@ValidLogicalWidth          ; yes - continue
  359.     mov   ax,bx                        ; no - set logical width = physical
  360.  
  361. @@ValidLogicalWidth:
  362.     shr   ax,3
  363.     out   dx,al
  364.  
  365.     ; The EXACT logical pixel width may not have been possible since
  366.     ; it should be divisible by 8. Round down to the closest possible
  367.     ; width and update the status variables
  368.  
  369.     shl   ax,1
  370.     mov   bx,ax
  371.     mov   [_ScrnLogicalByteWidth],ax  ; Store the byte width of virtual
  372.         mov   [_RightClip],ax             ; Set default Right clip column
  373.                       ; screen
  374.     sub   ax,[_ScrnPhysicalByteWidth] ; Calculate and store Max X position
  375.     shl   ax,2                        ; of physical screen in virtual
  376.     mov   [_MaxScrollX],ax            ; screen in pixels
  377.     mov   ax,bx                       ; set ax to byte width of virt scrn
  378.     shl   ax,2                        ; convert to pixels
  379.     mov   [_ScrnLogicalPixelWidth],ax ; store virt scrn pixel width
  380.     mov   cx,ax                       ; save ax (return value)
  381.  
  382.     ; calculate no. non split screen rows in video ram
  383.  
  384.     mov   ax,0ffffh                ; cx = Maximum video ram offset
  385.     sub   dx,dx                    ; DX:AX is divide operand,  set DX = 0
  386.     div   bx                       ; divide ax by ScrnLogicalByteWidth
  387.     mov   [_ScrnLogicalHeight],ax  ; Save Screen Logical Height
  388.         mov   [_BottomClip],ax         ; Set default bottom clip row
  389.     sub   ax,[_ScrnPhysicalHeight] ; Update the maximum Y position of
  390.     mov   [_MaxScrollY],ax         ; Physical screen in logical screen
  391.     mov   ax,cx                    ; restore ax (return value)
  392.  
  393.     ; calculate initial NonVisual
  394.     mov  ax,[_ScrnLogicalByteWidth]
  395.     mul  [_ScrnPhysicalHeight]
  396.     mov  [_NonVisual_Offs],ax
  397.  
  398. @@Done: ret
  399. SetLogicalScrWidth endp
  400.  
  401.  
  402.  
  403.  
  404. ;-----------------------------------------------------------------------
  405. ; Mode X graphics mode set with a virtual screen
  406. ;   logical screen width.
  407. ; C near-callable as:
  408. ;
  409. ;    int x_set_mode(unsigned int mode,unsigned int WidthInPixels);
  410. ;
  411. ; returns the actual width of the allocated virtual screen in pixels
  412. ; if a valid mode was selected otherwise returns -1
  413. ;
  414. ; Saves virtual screen pixel width in _ScrnLogicalPixelWidth.
  415. ; Saves virtual screen byte  width in _ScrnLogicalByteWidth.
  416. ; Physical screen dimensions are set in _ScrnPhysicalPixelWidth,
  417. ; _ScrnPhysicalByteWidth and _ScrnPhysicalHeight
  418. ;
  419. ;
  420. ; Modes:  0  = 320 x 200  (256 color)  NOTE: Some of these modes require
  421. ;      1  = 320 x 240  (256 color)     vertical size adjustment.
  422. ;         2  = 360 x 200  (256 color)
  423. ;         3  = 360 x 240  (256 color)
  424. ;         4  = 320 x 400  (256 color)
  425. ;      5  = 320 x 480  (256 color)
  426. ;         6  = 360 x 200  (256 color)
  427. ;         7  = 360 x 480  (256 color)
  428. ;         8  = 360 x 360  (256 color)
  429. ;         9  = 376 x 308  (256 color)
  430. ;        10 = 376 x 564  (256 color)
  431. ;
  432. ; Written by Themie Gouthas,
  433. ; parts adapted from M. Abrash code.
  434. ;------------------------------------------------------------------------
  435. _x_set_mode proc
  436.     ARG   mode:word,logicalscrwidth:word
  437.     push  bp      ;preserve caller's stack frame
  438.     mov   bp,sp
  439.  
  440.     push  si      ;preserve C register vars
  441.     push  di      ; (don't count on BIOS preserving anything)
  442.  
  443.     cld
  444.     mov   ax,ds
  445.     mov   es,ax
  446.     mov   di,offset PARAMS
  447.     xor   ax,ax
  448.     mov   cx,PARAM_COUNT
  449.     rep   stosb
  450.  
  451.     mov   cx,[mode]
  452.     cmp   cx,LAST_X_MODE        ; have we selected a valid mode
  453.     jle   @@ValidMode           ; Yes !
  454.  
  455.     mov   [_InGraphics],FALSE   ; No return -1
  456.     mov   ax,-1
  457.     pop   di
  458.     pop   si
  459.     pop   bp
  460.     ret
  461.  
  462. @@ValidMode:
  463.  
  464.     mov   [_CurrXMode],cx
  465.     mov   [_InGraphics],TRUE
  466.  
  467.     xor   al,al
  468.     cmp   cx,3
  469.     jg    @@SetDoubleScanFlag
  470.     mov   al,TRUE
  471. @@SetDoubleScanFlag:
  472.     mov   [DoubleScanFlag],al
  473.  
  474.     push  cx                    ; some bios's dont preserve cx
  475.     mov   ax,13h                ; let the BIOS set standard 256-color
  476.     int   10h                   ;  mode (320x200 linear)
  477.     pop   cx
  478.  
  479.     mov   dx,SC_INDEX
  480.     mov   ax,0604h
  481.     out   dx,ax                 ; disable chain4 mode
  482.     mov   ax,0100h
  483.     out   dx,ax                ; synchronous reset while setting Misc
  484.                     ;  Output for safety, even though clock
  485.                     ;  unchanged
  486.  
  487.     mov   bx,offset ModeTable
  488.     shl   cx,1
  489.     add   bx,cx
  490.     mov   si, word ptr [bx]
  491.     lodsb
  492.  
  493.     or    al,al
  494.     jz    @@DontSetDot
  495.     mov   dx,MISC_OUTPUT
  496.     out   dx,al               ; select the dot clock and Horiz
  497.                   ;  scanning rate
  498. @@DontSetDot:
  499.     mov   dx,SC_INDEX
  500.     mov   ax,0300h
  501.     out   dx,ax           ; undo reset (restart sequencer)
  502.  
  503.  
  504.     mov   dx,CRTC_INDEX       ; reprogram the CRT Controller
  505.     mov   al,11h              ; VSync End reg contains register write
  506.     out   dx,al               ; protect bit
  507.     inc   dx                  ; CRT Controller Data register
  508.     in    al,dx               ; get current VSync End register setting
  509.     and   al,07fh             ; remove write protect on various
  510.     out   dx,al               ; CRTC registers
  511.     dec   dx                  ; CRT Controller Index
  512.     cld
  513.     xor   cx,cx
  514.     lodsb
  515.     mov   cl,al
  516.  
  517. @@SetCRTParmsLoop:
  518.     lodsw                     ; get the next CRT Index/Data pair
  519.     out   dx,ax              ; set the next CRT Index/Data pair
  520.     loop  @@SetCRTParmsLoop
  521.  
  522.     mov   dx,SC_INDEX
  523.     mov   ax,0f02h
  524.     out   dx,ax          ; enable writes to all four planes
  525.     mov   ax,SCREEN_SEG       ; now clear all display memory, 8 pixels
  526.     mov   es,ax               ; at a time
  527.     sub   di,di               ; point ES:DI to display memory
  528.     sub   ax,ax               ; clear to zero-value pixels
  529.     mov   cx,8000h            ; # of words in display memory
  530.     rep   stosw               ; clear all of display memory
  531.  
  532.     ;Fix for single line
  533.  
  534.     ;mov   dx,CRTC_INDEX
  535.     ;mov   al,MAX_SCAN_LINE
  536.     ;out   dx,al
  537.     ;inc   dx
  538.     ;mov   al,0C0h
  539.     ;out   dx,al
  540.  
  541.     ;  Set pysical screen dimensions
  542.  
  543.     lodsw                               ; Load scrn pixel width
  544.     mov   [_ScrnPhysicalPixelWidth],ax  ;  from tweak table and store
  545.     mov   [_SplitScrnScanLine],ax       ; No splitscrn ==
  546.                         ; splitscrn=PhysicalscrnHeight
  547.     mov   bx,ax                         ; Copy width for later use
  548.     shr   ax,2                          ; Convert to byte width
  549.     mov   [_ScrnPhysicalByteWidth],ax   ; Store for later use
  550.     lodsw                               ; Load Screen Phys. Height
  551.     mov   [_ScrnPhysicalHeight],ax      ; Store for later use
  552.  
  553.  
  554.     ;  Mode X is set, now set the required logical page width.
  555.  
  556.     mov     cx,[logicalscrwidth]
  557.  
  558.     call    SetLogicalScrWidth
  559.  
  560.     pop     di      ;restore C register vars
  561.     pop     si
  562.     pop     bp      ;restore caller's stack frame
  563.     ret
  564. _x_set_mode endp
  565.  
  566. ;----------------------------------------------------------------------
  567. ; Mode X (256 color mode) set default access video plane
  568. ;
  569. ; C near-callable as:
  570. ;    void x_select_default_plane(unsigned char plane);
  571. ;
  572. ; Enables Read/Write access to a plane using general memory access
  573. ; methods
  574. ;
  575. ; Written by Themie Gouthas
  576. ;----------------------------------------------------------------------
  577. _x_select_default_plane proc
  578. ARG Plane:byte
  579.         push bp
  580.     mov  bp,sp       ; set up stack frame
  581.         mov  cl,byte ptr [Plane]
  582.  
  583.         ; SELECT WRITE PLANE
  584.     and  cl,011b              ;CL = plane
  585.     mov  ax,0100h + MAP_MASK  ;AL = index in SC of Map Mask reg
  586.     shl  ah,cl                ;set only the bit for the required
  587.                   ; plane to 1
  588.     mov  dx,SC_INDEX          ;set the Map Mask to enable only the
  589.     out  dx,ax                ; pixel's plane
  590.  
  591.         ; SELECT READ PLANE
  592.         mov  ah,cl                ;AH = plane
  593.     mov  al,READ_MAP          ;AL = index in GC of the Read Map reg
  594.     mov  dx,GC_INDEX          ;set the Read Map to read the pixel's
  595.     out  dx,ax              ; plane
  596.  
  597.         pop  bp
  598.         ret
  599. _x_select_default_plane endp
  600.  
  601.  
  602. ;----------------------------------------------------------------------
  603. ; Mode X (256 color mode) Set Mode X split screen starting row
  604. ; The split screen resides on the bottom half of the screen and has a
  605. ; starting address of A000:0000
  606. ;
  607. ; C near-callable as:
  608. ;    void x_set_splitscreen(unsigned int line);
  609. ;
  610. ; Updates _Page0_Offs to reflect the existence of the split screen region
  611. ; ie _MainScrnOffset is set to the offset of the first pixel beyond the split
  612. ; screen region
  613. ;
  614. ; Written by Themie Gouthas
  615. ;----------------------------------------------------------------------
  616.  
  617. _x_set_splitscreen proc
  618.     ARG Line:word
  619.     push bp
  620.     mov  bp,sp       ; set up stack frame
  621.     push si
  622.  
  623.     xor  si,si       ; si=0 -> x virtual page start coord
  624.  
  625.     cmp  [_DoubleBufferActive],0
  626.     jne   @@error
  627.  
  628.     cmp  [_SplitScrnActive],0
  629.     je   @@NotPreviouslyCalled
  630.  
  631. @@error:
  632.     mov  [_ErrorValue],ERROR
  633.     pop  si
  634.     pop  bp          ; Return if previously called
  635.     ret
  636.  
  637. @@NotPreviouslyCalled:
  638.  
  639.     ; Turn on split screen pal pen suppression, so the split screen
  640.     ; wo'nt be subject to pel panning as is the non split screen portion.
  641.  
  642.     mov  dx,INPUT_STATUS_0
  643.     in   al,dx                  ; Reset the AC Index/Data toggle to
  644.                     ;  index state
  645.     mov  al,AC_MODE_CONTROL+20h ; Bit 5 set to prevent screen blanking
  646.     mov  dx,AC_INDEX        ; Point AC to Index/Data register
  647.     out  dx,al
  648.     inc  dx                     ; Point to AC Data reg (for reads only)
  649.     in   al,dx                  ; Get the current AC Mode Control reg
  650.     or   al,20h                 ; Enable split scrn Pel panning suppress.
  651.     dec  dx                     ; Point to AC Index/Data reg (for writes only)
  652.     out  dx,al                  ; Write the new AC Mode Control setting
  653.                     ;  with split screen pel panning
  654.                     ;  suppression turned on
  655.  
  656.     mov  [_PhysicalStartByteX],ax   ; Set the Phisical screen start
  657.     mov  [_PhysicalStartPixelX],ax  ; offset within virtual screen
  658.     mov  [_PhysicalStartY],ax
  659.     mov  [_SplitScrnActive],TRUE
  660.     mov  ax,[Line]
  661.     jns  @@NotNeg    ; Check that Split Scrn start scan line is +ve
  662.  
  663.     mov  ax,0        ; Since -ve set to 0
  664.  
  665. @@NotNeg:
  666.     mov  [_SplitScrnScanLine],ax   ; save the scanline
  667.  
  668.  
  669.  
  670.     or    [DoubleScanFlag],0
  671.     jz    @@NotDoubleScanned
  672.     shl   ax,1
  673.     dec   ax
  674. @@NotDoubleScanned:
  675.     ;mov  cl,[DoubleScanFlag]
  676.     ;shl  ax,cl            ; Mode X 200 and 240 line modes are actually
  677.                   ; 400 and 480 lines that are double scanned
  678.                   ; so for start scanline multiply required ModeX
  679.                   ; scan line by 2 if its a double scanned mode
  680.  
  681.  
  682.     mov  bx,ax             ; save the scanline
  683.  
  684.  
  685.     WaitVsyncStart        ; wait for vertical retrace
  686.  
  687.     cli                   ; Dont allow register setting to be interrupted
  688.     mov  dx,CRTC_INDEX
  689.     mov  ah,bl
  690.     mov  al,LINE_COMPARE
  691.     out  dx,ax          ; Bits 7-0 of the split screen scan line
  692.  
  693.     mov  ah,bh
  694.     and  ah,1
  695.     shl  ah,4
  696.     mov  al,OVERFLOW     ; Bit 4 of overflow register = Bit 8 of split
  697.     out  dx,al           ; screen scan line,
  698.     inc  dx              ; So using readability of VGA registers
  699.     in   al,dx           ; Read the OVERFLOW register, and set the
  700.     and  al, not 10h     ; bit corresponding to Bit 8 (above)
  701.     or   al,ah
  702.     out  dx,al
  703.  
  704.     dec  dx
  705.     mov  ah,bh
  706.     and  ah,2
  707.     ror  ah,3
  708.     mov  al,MAX_SCAN_LINE  ; Bit 6 of max scan line register =
  709.     out  dx,al             ; Bit 9 of split screen scan line
  710.     inc  dx                ; As we did before, update the apropriate
  711.     in   al,dx             ; bit without disturbing the rest
  712.     and  al, not 40h
  713.     or   al,ah
  714.     out  dx,al
  715.     sti                    ; Registers are set, so interrupts are safe
  716.  
  717.     mov  ax,[_ScrnPhysicalHeight]     ; Determine where the first byte
  718.     sub  ax,[_SplitScrnScanLine]      ; of the non split screen video ram
  719.     mov  [_SplitScrnVisibleHeight],bx ; starts and store it for reference
  720.  
  721.     mov  bx,[_ScrnLogicalByteWidth]
  722.     mul  bx
  723.     mov  [_Page0_Offs],ax
  724.     mov  [_Page1_Offs],ax
  725.  
  726.     ; calculate no. non split screen rows in video ram
  727.     mov  cx,0ffffh             ; cx = Maximum video ram offset
  728.     sub  cx,ax                 ; cx = cx - _Page0_Offs
  729.     xchg cx,ax                 ; swap cx and ax
  730.     sub  dx,dx                 ; DX:AX is divide operand,  set DX = 0
  731.     div  bx                    ; divide ax (prev cx) by
  732.                    ; ScrnLogicalByteWidth
  733.  
  734.     mov  [_ScrnLogicalHeight],ax     ; Save Screen Logical Height
  735.         cmp   ax,[_BottomClip]
  736.     jle   @@BottomClipOK             ; Adjust Clip Rectangle if necessary
  737.         mov   [_BottomClip],ax
  738. @@BottomClipOK:
  739.     sub  ax,[_SplitScrnScanLine]     ; Update the maximum Y position of
  740.     mov  [_MaxScrollY],ax             ; Physical screen in logical screen
  741.  
  742.     xchg cx,ax                    ; restore original ax (MainScrnOfs)
  743.     mov  bh,al                    ; Set the visible screen start address
  744.     mov  ch,ah                    ; to the top left corner of the virtual
  745.     jmp  short StartAddrEntry     ; screen
  746. _x_set_splitscreen     endp
  747.  
  748.  
  749. ;-----------------------------------------------------------------------
  750. ; Mode X (256 color mode) Page flip primer
  751. ; No clipping is performed.
  752. ; C near-callable as:
  753. ;
  754. ;    void x_page_flip(unsigned int x, unsigned int y);
  755. ;
  756. ; Swaps visible and hidden page offsets and then executes the SetStartAddr
  757. ; to achieve a page flip.
  758. ;
  759. ; SEE x_set_start_addr below
  760. ;
  761. ; Written by Themie Gouthas
  762. ;------------------------------------------------------------------------
  763.  
  764. _x_page_flip proc
  765.     ARG x:word,y:word
  766.     push  bp                  ;preserve caller's stack frame
  767.     mov   bp,sp               ;point to local stack frame
  768.     push  si
  769.  
  770.     mov  si,[x]
  771.     mov  ax,[_ScrnLogicalByteWidth]     ; Calculate Offset increment
  772.     mov  cx,[y]
  773.     mul  cx                             ; for Y
  774.     cmp  [_DoubleBufferActive],TRUE     ; Do we have double buffering ?
  775.     jne  PageFlipEntry1
  776.  
  777.     mov  bx,[_HiddenPageOffs]
  778.     xchg bx,[_VisiblePageOffs]          ; Swap the Page Offsete
  779.     xchg [_HiddenPageOffs],bx
  780.     xor  [_VisiblePageIdx],01h          ; Set the Visible page index
  781.     jmp  short PageFlipEntry2
  782. _x_page_flip endp
  783.  
  784.  
  785. ;-----------------------------------------------------------------------
  786. ; Mode X (256 color mode) Set Mode X non split screen start address
  787. ;   of logical screen.
  788. ; C near-callable as:
  789. ;
  790. ;    void x_set_start_addr(unsigned int x, unsigned int y);
  791. ;
  792. ; Params: StartOffset is offset of first byte of logical screen ram
  793. ;           (Useful if you want to double buffer by splitting your non
  794. ;            split screen video ram into 2 pages)
  795. ;        X,Y coordinates of the top left hand corner of the physical screen
  796. ;           within the logical screen
  797. ;           X must not exceed (Logical screen width - Physical screen width)
  798. ;           Y must not exceed (Logical screen height - Physical screen height)
  799. ;
  800. ;
  801. ; Written by Themie Gouthas,
  802. ; Parts addapted from M. Abrash code published in DDJ Mag.
  803. ;------------------------------------------------------------------------
  804. _x_set_start_addr proc
  805.     ARG x:word,y:word
  806.     push bp
  807.     mov  bp,sp
  808.     push si
  809.  
  810.     mov  si,[x]
  811.     mov  ax,[_ScrnLogicalByteWidth]     ; Calculate Offset increment
  812.     mov  cx,[y]                         ; for Y
  813.     mul  cx
  814.     cmp  [_DoubleBufferActive],TRUE     ; Do we have double buffering ?
  815.     je   @@PageResolution
  816. PageFlipEntry1:
  817.     add  ax,[_Page0_Offs]               ; no - add page 0 offset
  818.     jmp  short @@AddColumn
  819.  
  820. PageFlipEntry2:
  821.  
  822.     mov  [_PhysicalStartPixelX],si
  823.     mov  [_PhysicalStartY],cx
  824.  
  825. @@PageResolution:
  826.     add  ax,[_VisiblePageOffs]          ; Add visible page offset
  827.  
  828. @@AddColumn:
  829.     mov  cx,si
  830.     shr  cx,2
  831.     mov  [_PhysicalStartByteX],cx
  832.     add  ax,cx                          ; add the column offset for X
  833.     mov  bh,al                          ; setup CRTC start addr regs and
  834.                         ; values in word registers for
  835.     mov  ch,ah                          ; fast word outs
  836.  
  837. StartAddrEntry:
  838.     mov  bl,ADDR_LOW
  839.     mov  cl,ADDR_HIGH
  840.     and  si,0003h             ; select pel pan register value for the
  841.     mov  ah,PelPanMask[si]    ; required x coordinate
  842.     mov  al,PEL_PANNING+20h
  843.     mov  si,ax
  844.  
  845.     mov  dx,INPUT_STATUS_0    ;Wait for trailing edge of Vsync pulse
  846. @@WaitDE:
  847.     in   al,dx
  848.     test al,01h
  849.     jnz  @@WaitDE            ;display enable is active low (0 = active)
  850.  
  851.     mov  dx,CRTC_INDEX
  852.     mov  ax,bx
  853.     out  dx,ax               ;start address low
  854.     mov  ax,cx
  855.     out  dx,ax               ;start address high
  856.  
  857.     mov  dx,AC_INDEX
  858.     mov  ax,si                ; Point the attribute controller to pel pan
  859.     out  dx,al                ; reg. Bit 5 also set to prevent blanking
  860.     mov  al,ah
  861.     out  dx,al                ; load new Pel Pan setting.
  862.  
  863.  
  864. ; Now wait for vertical sync, so the other page will be invisible when
  865. ; we start drawing to it.
  866.     mov  dx,INPUT_STATUS_0    ;Wait for trailing edge of Vsync pulse
  867. @@WaitVS:
  868.     in   al,dx
  869.     test al,08h
  870.     jz @@WaitVS           ;display enable is active low (0 = active)
  871.  
  872.     mov  [_ErrorValue],OK
  873.     pop  si
  874.     pop  bp
  875.     ret
  876. _x_set_start_addr  endp
  877.  
  878.  
  879. ;-----------------------------------------------------------------------
  880. ; Mode X (256 color mode) Mode X split screen hide
  881. ; C near-callable as:
  882. ;
  883. ;    void x_hide_splitscreen()
  884. ;
  885. ; Hides an existing split screen by setting its starting scan line to
  886. ; the last physical screen scan line
  887. ;
  888. ; WARNING: Only to be used if SplitScrnLine has been previously called
  889. ; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for
  890. ;       the initial split screen is reserved and the size limitations
  891. ;       of these modes means any change in the split screen scan line
  892. ;          will encroach on the split screen ram
  893. ;
  894. ; Written by Themie Gouthas
  895. ;------------------------------------------------------------------------
  896.  
  897. _x_hide_splitscreen proc
  898.     push bp
  899.     mov  bp,sp
  900.  
  901.     cmp  [_SplitScrnActive],TRUE
  902.     je   @@SplitScreenEnabled
  903.  
  904. @@error:
  905.         mov  [_ErrorValue],ERROR
  906.     pop  bp
  907.     ret
  908.  
  909. @@SplitScreenEnabled:
  910.     cmp  [_CurrXMode],4          ; Do nothing for Modes > 2
  911.     jg   @@error
  912.     mov  bx,[_ScrnPhysicalHeight]
  913.  
  914.         mov  ax,[_ScrnLogicalHeight]
  915.     sub  ax,bx
  916.     mov  [_MaxScrollY],ax
  917.     xor  ax,ax
  918.     mov  [_SplitScrnVisibleHeight],ax
  919.  
  920.     or    [DoubleScanFlag],0
  921.     jz    @@NotDoubleScanned
  922.     shl   bx,1
  923.     dec   bx
  924. @@NotDoubleScanned:
  925.     ;mov  cl,[DoubleScanFlag]  ; Compensate for double scanned modes
  926.     ;shl  bx,cl
  927.  
  928.     WaitVsyncStart               ; wait for vertical retrace
  929.  
  930.     cli                 ; Dont allow register setting to be interrupted
  931.     mov  dx,CRTC_INDEX
  932.     mov  ah,bl
  933.     mov  al,LINE_COMPARE
  934.     out  dx,ax          ; Bits 7-0 of the split screen scan line
  935.  
  936.     mov  ah,bh
  937.     and  ah,1
  938.     shl  ah,4
  939.     mov  al,OVERFLOW  ; Bit 4 of overflow register = Bit 8 of split
  940.     out  dx,al        ; screen scan line,
  941.     inc  dx           ; So using readability of VGA registers
  942.     in   al,dx        ; Read the OVERFLOW register, and set the
  943.     and  al, not 10h  ; bit corresponding to Bit 8 (above)
  944.     or   al,ah
  945.     out  dx,al
  946.  
  947.     dec  dx
  948.     mov  ah,bh
  949.     and  ah,2
  950.     ror  ah,3
  951.     mov  al,MAX_SCAN_LINE  ; Bit 6 of max scan line register =
  952.     out  dx,al             ; Bit 9 of split screen scan line
  953.     inc  dx                ; As we did before, update the apropriate
  954.     in   al,dx             ; bit without disturbing the rest
  955.     and  al, not 40h
  956.     or   al,ah
  957.     out  dx,al
  958.     sti                  ; Registers are set, so interrupts are safe
  959.  
  960. @@done:
  961.  
  962.         mov  [_ErrorValue],OK
  963.     pop  bp
  964.     ret
  965. _x_hide_splitscreen endp
  966.  
  967. ;-----------------------------------------------------------------------
  968. ; Mode X (256 color mode) Mode X split screen show
  969. ; C near-callable as:
  970. ;
  971. ;    void x_show_splitscreen()
  972. ;
  973. ; Restores split screen start scan line to the initial split screen
  974. ; starting scan line as set by SplitScrnLine.
  975. ;
  976. ; WARNING: Only to be used if SplitScrnLine has been previously called
  977. ; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for
  978. ;       the initial split screen is reserved and the size limitations
  979. ;       of these modes means any change in the split screen scan line
  980. ;          will encroach on the split screen ram
  981. ;          Update: Now disabled for these modes
  982. ;
  983. ; Written by Themie Gouthas
  984. ;------------------------------------------------------------------------
  985.  
  986.  
  987. _x_show_splitscreen proc
  988.     push bp
  989.     mov  bp,sp
  990.  
  991.     cmp  [_SplitScrnActive],TRUE
  992.     je   @@SplitScreenEnabled
  993.  
  994. @@error:
  995.         mov  [_ErrorValue],ERROR
  996.     pop  bp
  997.     ret
  998.  
  999. @@SplitScreenEnabled:
  1000.     cmp  [_CurrXMode],4          ; Do nothing for Modes > 2
  1001.     jg   @@error
  1002.  
  1003.     mov  bx,[_SplitScrnScanLine]
  1004.     mov  ax,[_ScrnLogicalHeight] ; Update Max Scroll Y
  1005.     sub  ax,bx
  1006.         mov  [_MaxScrollY],ax
  1007.  
  1008.     mov  ax,[_ScrnPhysicalHeight]
  1009.     sub  ax,bx
  1010.     mov  [_SplitScrnVisibleHeight],ax
  1011.  
  1012.     or    [DoubleScanFlag],0
  1013.     jz    @@NotDoubleScanned
  1014.     shl   bx,1
  1015.     dec   bx
  1016. @@NotDoubleScanned:
  1017.     ;mov  cl,[DoubleScanFlag]  ; Compensate for double scanned modes
  1018.     ;shl  bx,cl
  1019.     WaitVsyncStart               ; wait for vertical retrace
  1020.  
  1021.     cli                 ; Dont allow register setting to be interrupted
  1022.     mov  dx,CRTC_INDEX
  1023.     mov  ah,bl
  1024.     mov  al,LINE_COMPARE
  1025.     out  dx,ax                ; Bits 7-0 of the split screen scan line
  1026.  
  1027.     mov  ah,bh
  1028.     and  ah,1
  1029.     shl  ah,4
  1030.     mov  al,OVERFLOW  ; Bit 4 of overflow register = Bit 8 of split
  1031.     out  dx,al        ; screen scan line,
  1032.     inc  dx           ; So using readability of VGA registers
  1033.     in   al,dx        ; Read the OVERFLOW register, and set the
  1034.     and  al, not 10h  ; bit corresponding to Bit 8 (above)
  1035.     or   al,ah
  1036.     out  dx,al
  1037.  
  1038.     dec  dx
  1039.     mov  ah,bh
  1040.     and  ah,2
  1041.     ror  ah,3
  1042.     mov  al,MAX_SCAN_LINE  ; Bit 6 of max scan line register =
  1043.     out  dx,al             ; Bit 9 of split screen scan line
  1044.     inc  dx                ; As we did before, update the apropriate
  1045.     in   al,dx             ; bit without disturbing the rest
  1046.     and  al, not 40h
  1047.     or   al,ah
  1048.     out  dx,al
  1049.     sti                  ; Registers are set, so interrupts are safe
  1050.  
  1051. @@Done:
  1052.         mov  [_ErrorValue],0
  1053.     pop  bp
  1054.     ret
  1055. _x_show_splitscreen endp
  1056.  
  1057.  
  1058. ;-----------------------------------------------------------------------
  1059. ; Mode X (256 color mode) Modify Mode X split screen starting scan line
  1060. ; C near-callable as:
  1061. ;
  1062. ;    void x_adjust_splitscreen(unsigned int ScanLine)
  1063. ;
  1064. ; Sets the split screen start scan line to a new scan line. Valid scan lines
  1065. ; are between the initial split screen starting scan line and the last
  1066. ; physical screen scan line.
  1067. ;
  1068. ; WARNING: Only to be used if SplitScrnLine has been previously called
  1069. ; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for
  1070. ;       the initial split screen is reserved and the size limitations
  1071. ;       of these modes means any change in the split screen scan line
  1072. ;          will encroach on the split screen ram
  1073. ;          Update: Now disabled for these modes
  1074. ;
  1075. ;
  1076. ; Written by Themie Gouthas
  1077. ;------------------------------------------------------------------------
  1078.  
  1079.  
  1080. _x_adjust_splitscreen proc
  1081.     ARG   ScanLine
  1082.     push bp
  1083.     mov  bp,sp
  1084.  
  1085.     cmp  [_SplitScrnActive],TRUE
  1086.     je   @@SplitScreenEnabled
  1087.  
  1088. @@error:
  1089.         mov  [_ErrorValue],ERROR
  1090.     pop  bp
  1091.     ret
  1092.  
  1093. @@SplitScreenEnabled:
  1094.     cmp  [_CurrXMode],4          ; Do nothing for Modes > 2
  1095.     jg   @@error
  1096.     mov  bx,[ScanLine]            ; Is the required starting scan line
  1097.     cmp  bx,[_SplitScrnScanLine]  ; valid ?
  1098.     js   @@Done                   ; No - Then do nothing
  1099.  
  1100. @@ValidScanLine:
  1101.  
  1102.         mov  ax,[_ScrnLogicalHeight] ; Update Max Scroll Y
  1103.     sub  ax,bx
  1104.         mov  [_MaxScrollY],ax
  1105.  
  1106.     mov  ax,[_ScrnPhysicalHeight]
  1107.     sub  ax,bx
  1108.     mov  [_SplitScrnVisibleHeight],ax
  1109.  
  1110.         or    [DoubleScanFlag],0
  1111.     jz    @@NotDoubleScanned
  1112.     shl   bx,1
  1113.     dec   bx
  1114. @@NotDoubleScanned:
  1115.     ;mov  cl,[DoubleScanFlag]   ; Compensate for double scanned modes
  1116.     ;shl  bx,cl
  1117.  
  1118.     WaitVsyncStart      ; wait for vertical retrace
  1119.  
  1120.     cli                 ; Dont allow register setting to be interrupted
  1121.  
  1122.     mov  dx,CRTC_INDEX
  1123.     mov  ah,bl
  1124.     mov  al,LINE_COMPARE
  1125.     out  dx,ax          ; Bits 7-0 of the split screen scan line
  1126.  
  1127.     mov  ah,bh
  1128.     and  ah,1
  1129.     shl  ah,4
  1130.     mov  al,OVERFLOW  ; Bit 4 of overflow register = Bit 8 of split
  1131.     out  dx,al        ; screen scan line,
  1132.     inc  dx           ; So using readability of VGA registers
  1133.     in   al,dx        ; Read the OVERFLOW register, and set the
  1134.     and  al, not 10h  ; bit corresponding to Bit 8 (above)
  1135.     or   al,ah
  1136.     out  dx,al
  1137.  
  1138.     dec  dx
  1139.     mov  ah,bh
  1140.     and  ah,2
  1141.     ror  ah,3
  1142.     mov  al,MAX_SCAN_LINE  ; Bit 6 of max scan line register =
  1143.     out  dx,al             ; Bit 9 of split screen scan line
  1144.     inc  dx                ; As we did before, update the apropriate
  1145.     in   al,dx             ; bit without disturbing the rest
  1146.     and  al, not 40h
  1147.     or   al,ah
  1148.     out  dx,al
  1149.     sti                    ; Registers are set, so interrupts are safe
  1150. @@Done:
  1151.         mov  [_ErrorValue],OK
  1152.     pop   bp
  1153.     ret
  1154. _x_adjust_splitscreen endp
  1155.  
  1156.  
  1157.  
  1158. ;-----------------------------------------------------------------------
  1159. ; Mode X (256 color mode) Enable DoubleBuffering on non split screen area
  1160. ; C near-callable as:
  1161. ;
  1162. ;    int x_set_doublebuffer(unsigned int PageHeight);
  1163. ;
  1164. ; Params: PageHeight is the height of the virtual screen to double buffer
  1165. ;         Returns the closest possible height to the specified.
  1166. ;
  1167. ; Sets up two double buffering virtual pages
  1168. ; GLOBAL variables set:
  1169. ;
  1170. ;      _Page1_Offs        Offset of second virtual page
  1171. ;      _NonVisual_Offs          Offset of first non visible video ram byte
  1172. ;      _DoubleBufferActive      Flag
  1173. ;      _PageAddrTable           Table of Double buffering pages start offsets
  1174. ;      _ScrnLogicalHeight       Logical height of the double buffering pages
  1175. ;
  1176. ;
  1177. ; Written by Themie Gouthas
  1178. ;------------------------------------------------------------------------
  1179.  
  1180.  
  1181. _x_set_doublebuffer proc
  1182.        ARG PageHeight:word
  1183.        push  bp
  1184.        mov   bp,sp
  1185.  
  1186.        cmp   [_DoubleBufferActive],0
  1187.        je    @@OkToContinue
  1188. @error:
  1189.        mov   [_ErrorValue],ERROR
  1190.        pop   bp
  1191.        ret
  1192.  
  1193. @@OkToContinue:
  1194.        mov   [_VisiblePageIdx],0     ; Set visible Page to 0
  1195.        mov   ax,[_ScrnLogicalHeight] ; Set Maximum D.B. Page height to
  1196.        shr   ax,1                    ;   _ScrnLogicalHeight / 2
  1197.  
  1198.        mov   bx,[PageHeight]         ; Is the require D.B. Page Height
  1199.        cmp   ax,bx                   ;  > the Maximum  D.B. Page Height ?
  1200.  
  1201.        js    @@InvalidHeight         ; no  - jump
  1202.        mov   ax,bx                   ; yes - Set the D.B. Page height to
  1203.                      ;       to the maximum allowed.
  1204.  
  1205. @@InvalidHeight:
  1206.        mov   [_ScrnLogicalHeight],ax    ; Update logical screen height to
  1207.                     ;  reflect the height of a D.B. page
  1208.        cmp   ax,[_BottomClip]
  1209.        jle   @@BottomClipOK             ; Adjust Clip Rectangle if necessary
  1210.        mov   [_BottomClip],ax
  1211. @@BottomClipOK:
  1212.        mov   dx,ax
  1213.        mul   [_ScrnLogicalByteWidth]    ; Calculate the offset of the second
  1214.        mov   cx,ax                    ;  D.B. Page in video ram
  1215.        mov   bx,[_Page0_Offs]
  1216.        mov   [_VisiblePageOffs],bx
  1217.  
  1218.        add   ax,bx
  1219.        mov   [_Page1_Offs],ax           ; Save it
  1220.        mov   [_HiddenPageOffs],ax
  1221.  
  1222.        add   ax,cx                      ; Calculate the offset of first byte
  1223.        mov   [_NonVisual_Offs],ax       ;  beyond the D.B. pages and save it
  1224.        mov   [_DoubleBufferActive],TRUE ; Set flag indicating D.B'ing mode on
  1225.  
  1226.        mov   ax,dx
  1227.        sub   ax,[_ScrnPhysicalHeight]
  1228.        add   ax,[_SplitScrnVisibleHeight]
  1229.        mov   [_MaxScrollY],ax
  1230.  
  1231.        mov   ax,dx                      ; return the D.B. pages' height
  1232.        mov   [_ErrorValue],OK
  1233.        pop   bp
  1234.        ret
  1235. _x_set_doublebuffer endp
  1236.  
  1237.  
  1238. ;-----------------------------------------------------------------------
  1239. ; Set Clipping rectangle
  1240. ; C callable as:
  1241. ;
  1242. ;
  1243. ;    int x_set_cliprect(WORD left,WORD top, WORD right, WORD bottom);
  1244. ;
  1245. ;
  1246. ; NOTE clipping is byte oriented. "left" and "right" are in bytes not pixels.
  1247. ;    Only selected functions perform any clipping at all.
  1248. ;
  1249. ; Written by Themie Gouthas
  1250. ;------------------------------------------------------------------------
  1251.  
  1252. _x_set_cliprect proc
  1253. ARG left:word,top:word,right:word,bottom:word
  1254.        push  bp
  1255.        mov   bp,sp
  1256.        mov   ax,[left]
  1257.        mov   bx,[right]
  1258.        cmp   bx,ax
  1259.        jns   @@CorrectXOrder
  1260.        xchg  bx,ax
  1261. @@CorrectXOrder:
  1262.        mov   [_LeftClip],ax
  1263.        mov   [_RightClip],bx
  1264.        mov   ax,[top]
  1265.        mov   bx,[bottom]
  1266.        cmp   bx,ax
  1267.        jns   @@CorrectYOrder
  1268.        xchg  bx,ax
  1269. @@CorrectYOrder:
  1270.        mov   [_TopClip],ax
  1271.        mov   [_BottomClip],bx
  1272.        pop   bp
  1273.        ret
  1274. _x_set_cliprect endp
  1275.  
  1276.  
  1277. ;----------------------------------------------------------------------
  1278. ; Return to text mode
  1279. ;
  1280. _x_text_mode proc
  1281.        push  bp
  1282.  
  1283.        mov   ax,03h        ; Restore Text Mode
  1284.        int   10h
  1285.  
  1286.        pop   bp
  1287.        ret
  1288. _x_text_mode endp
  1289.  
  1290. ;-----------------------------------------------------------------------
  1291. ; Wait for Vertical sync
  1292. _x_wait_vsync proc
  1293.     push  bp
  1294.     WaitVsyncStart
  1295.     pop   bp
  1296.     ret
  1297. _x_wait_vsync endp
  1298.  
  1299.  
  1300.     end
  1301.  
  1302.