+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XMAIN\r
-;\r
-; Initialization, panning and split screen functions for all MODE X 256\r
-; Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; MODIFICATIONS:\r
-; 26-9-92: Pel panning code added\r
-; Dates forgotten: Numerous ;^)\r
-; 05-10-93: Timer synchronized vsync handling extensions\r
-; and tripple buffering - Tore Jahn Bastiansen\r
-; (toreba@ifi.uio.no) for the\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-include xlib.inc\r
-include xmain.inc\r
-\r
-\r
- .data\r
-\r
-\r
-; Mode X CRTC register tweaks for various resolutions\r
-\r
-\r
-LABEL X256Y200 word\r
- db 0e3h ; dot clock\r
- db 8 ; Number of CRTC Registers to update\r
- dw 05f00h ; horz total\r
- dw 03f01h ; horz displayed\r
- dw 04202h ; start horz blanking\r
- dw 09f03h ; end horz blanking\r
- dw 04c04h ; start h sync\r
- dw 00005h ; end h sync\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 256\r
- dw 200\r
-\r
-\r
-LABEL X256Y240 word\r
- db 0e3h ; dot clock\r
- db 16 ; Number of CRTC Registers to update\r
- dw 05f00h ; horz total\r
- dw 03f01h ; horz displayed\r
- dw 04202h ; start horz blanking\r
- dw 09f03h ; end horz blanking\r
- dw 04c04h ; start h sync\r
- dw 00005h ; end h sync\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04109h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 256\r
- dw 240\r
-\r
-\r
-X320Y200 label word\r
- db 00 ; 0e3h ; dot clock\r
- db 02 ; Number of CRTC Registers to update\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 320 ; width\r
- dw 200 ; height\r
-\r
-X320Y240 label word\r
- db 0e3h ; dot clock\r
- db 10 ; Number of CRTC Registers to update\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04109h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 320 ; width\r
- dw 240 ; height\r
-\r
-X360Y200 label word\r
- db 0e7h ; dot clock\r
- db 08 ; Number of CRTC Registers to update\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 360 ; width\r
- dw 200 ; height\r
-\r
-X360Y240 label word\r
- db 0e7h ; dot clock\r
- db 17 ; Number of CRTC Registers to update\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04109h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 02d13h ; offset;\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 360\r
- dw 240\r
-\r
-X376Y282 label word\r
- db 0e7h\r
- db 18\r
- dw 06e00h ; horz total\r
- dw 05d01h ; horz displayed\r
- dw 05e02h ; start horz blanking\r
- dw 09103h ; end horz blanking\r
- dw 06204h ; start h sync\r
- dw 08f05h ; end h sync\r
- dw 06206h ; vertical total\r
- dw 0f007h ; overflow\r
- dw 06109h ; cell height\r
- dw 0310fh ;\r
- dw 03710h ; v sync start\r
- dw 08911h ; v sync end and protect cr0-cr7\r
- dw 03312h ; vertical displayed\r
- dw 02f13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 03c15h ; v blank start\r
- dw 05c16h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 376\r
- dw 282\r
-\r
-LABEL X256Y400 word\r
- db 0e3h ; dot clock\r
- db 8 ; Number of CRTC Registers to update\r
- dw 05f00h ; horz total\r
- dw 03f01h ; horz displayed\r
- dw 04202h ; start horz blanking\r
- dw 09f03h ; end horz blanking\r
- dw 04c04h ; start h sync\r
- dw 00005h ; end h sync\r
- dw 04009h ; cell height\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 256\r
- dw 400\r
-\r
-\r
-LABEL X256Y480 word\r
- db 0e3h ; dot clock\r
- db 16 ; Number of CRTC Registers to update\r
- dw 05f00h ; horz total\r
- dw 03f01h ; horz displayed\r
- dw 04202h ; start horz blanking\r
- dw 09f03h ; end horz blanking\r
- dw 04c04h ; start h sync\r
- dw 00005h ; end h sync\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04009h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 256\r
- dw 480\r
-\r
-\r
-\r
-X320Y400 label word\r
- db 0e3h ; dot clock\r
- db 03 ; Number of CRTC Registers to update\r
- dw 04009h ; cell height\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 320 ; width\r
- dw 400 ; height\r
-\r
-X320Y480 label word\r
- db 0e3h ; dotclock\r
- db 10 ; Number of CRTC Registers to update\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04009h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 320 ; width\r
- dw 480 ; height\r
-\r
-X360Y400 label word\r
- db 0e7h ; dot clock\r
- db 09 ; Number of CRTC Registers to update\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 04009h ; cell height\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 360 ; width\r
- dw 400 ; height\r
-\r
-\r
-\r
-X360Y480 label word\r
- db 0e7h\r
- db 17\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow\r
- dw 04009h ; cell height\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 02d13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 360\r
- dw 480\r
-\r
-X360Y360 label word\r
- db 0e7h\r
- db 15\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 04009h ; cell height\r
- dw 08810h ; v sync start\r
- dw 08511h ; v sync end and protect cr0-cr7\r
- dw 06712h ; vertical displayed\r
- dw 02d13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 06d15h ; v blank start\r
- dw 0ba16h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 360\r
- dw 360\r
-\r
-\r
-X376Y308 label word\r
- db 0e7h\r
- db 18\r
- dw 06e00h ; horz total\r
- dw 05d01h ; horz displayed\r
- dw 05e02h ; start horz blanking\r
- dw 09103h ; end horz blanking\r
- dw 06204h ; start h sync\r
- dw 08f05h ; end h sync\r
- dw 06206h ; vertical total\r
- dw 00f07h ; overflow\r
- dw 04009h ;\r
- dw 0310fh ;\r
- dw 03710h ; v sync start\r
- dw 08911h ; v sync end and protect cr0-cr7\r
- dw 03312h ; vertical displayed\r
- dw 02f13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 03c15h ; v blank start\r
- dw 05c16h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 376\r
- dw 308\r
-\r
-X376Y564 label word\r
- db 0e7h\r
- db 18\r
- dw 06e00h ; horz total\r
- dw 05d01h ; horz displayed\r
- dw 05e02h ; start horz blanking\r
- dw 09103h ; end horz blanking\r
- dw 06204h ; start h sync\r
- dw 08f05h ; end h sync\r
- dw 06206h ; vertical total\r
- dw 0f007h ; overflow\r
- dw 06009h ;\r
- dw 0310fh ;\r
- dw 03710h ; v sync start\r
- dw 08911h ; v sync end and protect cr0-cr7\r
- dw 03312h ; vertical displayed\r
- dw 02f13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 03c15h ; v blank start\r
- dw 05c16h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 376\r
- dw 564\r
-\r
-LAST_X_MODE equ 13\r
-ModeTable label word ; Mode X tweak table\r
- dw offset X320Y200\r
- dw offset X320Y240\r
- dw offset X360Y200\r
- dw offset X360Y240\r
- dw offset X376Y282\r
- dw offset X320Y400\r
- dw offset X320Y480\r
- dw offset X360Y400\r
- dw offset X360Y480\r
- dw offset X360Y360\r
- dw offset X376Y308\r
- dw offset X376Y564\r
- dw offset X256Y200\r
- dw offset X256Y240\r
-\r
-\r
-PARAMS label byte\r
-\r
- _CurrXMode dw 0 ; Current graphics mode index\r
- _InGraphics db 0 ; Flag indicating graphics activity\r
- _ScrnPhysicalByteWidth dw 0 ; Physical width in bytes of screen\r
- _ScrnPhysicalPixelWidth dw 0 ; Physical width in pixels of screen\r
- _ScrnPhysicalHeight dw 0 ; Physical Height of screen\r
- _ErrorValue db 0 ; Set after function calls\r
-\r
-\r
- _SplitScrnActive db 0 ; Flag indicating Split scrn activity\r
- _DoubleBufferActive dw 0 ; Flag indicating double buffering\r
- _TrippleBufferActive dw 0 ; Flag indicating tripple buffering\r
-\r
- _SplitScrnScanLine dw 0 ; Split Screen's starting scan line\r
- _SplitScrnVisibleHeight dw 0 ; Split Screen's height on screen\r
-\r
- _SplitScrnOffs dw 0 ; Offset in video ram of Split Screen\r
- ; always = 0\r
- _Page0_Offs dw 0 ; Ofset in video ram of Main virtual\r
- ; screen ( = 0 if no split screen\r
- ; otherwise = offset of first byte\r
- ; after split screen\r
- _Page1_Offs dw 0 ; Ofset in video ram of Second virtual\r
- ; screen ( = 0 if no split screen\r
- ; otherwise = offset of first byte\r
- ; after split screen\r
- ; = Page0_Offs if Doubble buffering\r
- ; not enabled\r
- _Page2_Offs dw 0\r
-\r
- _NonVisual_Offs dw 0 ; Ofset in video ram of first byte\r
- ; of non visible ram\r
- _ScrnLogicalByteWidth dw 0 ; Logical width in bytes of screen\r
- _ScrnLogicalPixelWidth dw 0 ; Logical width in pixels of screen\r
- _ScrnLogicalHeight dw 0 ; Logical Height of screen\r
-\r
- _MaxScrollX dw 0 ; Max X start position of Physical\r
- ; screen within virtual screen (in\r
- ; bytes)\r
- _MaxScrollY dw 0 ; Max Y start position of Physical\r
- ; screen within virtual screen\r
-\r
- _VisiblePageIdx dw 0 ; Index of currently visible D.B.\r
- ; page\r
-\r
- PageAddrTable label word\r
- _VisiblePageOffs dw 0 ; Table containing starting offsets\r
- _HiddenPageOffs dw 0 ; of the double buffer pages\r
- _WaitingPageOffs dw 0\r
-\r
- _TopClip dw 0 ; Clipping Rectangle\r
- _BottomClip dw 0 ;\r
- _LeftClip dw 0 ; Left/Right coordinates in bytes\r
- _RightClip dw 0 ;\r
- _PhysicalStartByteX dw 0 ; X byte coord of physical screen\r
- ; relative to virtual virtual screen\r
- _PhysicalStartPixelX dw 0 ; X pixel coord of physical screen\r
- ; relative to virtual screen\r
- _PhysicalStartY dw 0 ; Y pixel coord of physical screen\r
- ; relative to virtual screen\r
-\r
-; NEW\r
- _VsyncHandlerActive dw 0\r
- _MouseRefreshFlag dw 0\r
- _MouseVsyncHandler dd 0\r
- _StartAddressFlag dw 0\r
- _WaitingStartLow dw 0\r
- _WaitingStartHigh dw 0\r
- _WaitingPelPan dw 0\r
- _VsyncPaletteStart dw 0\r
- _VsyncPaletteCount dw 0\r
- _VsyncPaletteBuffer label byte\r
- db 768 dup(?)\r
-\r
-\r
-PARAMS_END label byte\r
-\r
-PARAM_COUNT equ ($-PARAMS)\r
-\r
-\r
-; Index/data pairs for CRT Controller registers that differ between\r
-; mode 13h and mode X.\r
-\r
- ;Pelpan values for 0,1,2,3 pixel panning to the left, respectively\r
- PelPanMask db 000h,002h,004h,006h\r
-\r
-DoubleScanFlag db ? ; Flag to indicate double scanned mode\r
-\r
- .code\r
-\r
-;-------------------------------------------------------------------------\r
-; Local Logical Screen Width setting function\r
-; cx = Requitrd Logical Width\r
-;\r
-; WARNING: no registers are preserved\r
-\r
-SetLogicalScrWidth proc\r
- mov dx,CRTC_INDEX\r
- mov al,CRTC_OFFSET\r
- out dx,al\r
- inc dx\r
-\r
- mov ax,cx\r
- cmp ax,[_ScrnPhysicalPixelWidth]; Is logical width >= physical width\r
- jge @@ValidLogicalWidth ; yes - continue\r
- mov ax,bx ; no - set logical width = physical\r
-\r
-@@ValidLogicalWidth:\r
- shr ax,3\r
- out dx,al\r
-\r
- ; The EXACT logical pixel width may not have been possible since\r
- ; it should be divisible by 8. Round down to the closest possible\r
- ; width and update the status variables\r
-\r
- shl ax,1\r
- mov bx,ax\r
- mov [_ScrnLogicalByteWidth],ax ; Store the byte width of virtual\r
- mov [_RightClip],ax ; Set default Right clip column\r
- ; screen\r
- sub ax,[_ScrnPhysicalByteWidth] ; Calculate and store Max X position\r
- shl ax,2 ; of physical screen in virtual\r
- mov [_MaxScrollX],ax ; screen in pixels\r
- mov ax,bx ; set ax to byte width of virt scrn\r
- shl ax,2 ; convert to pixels\r
- mov [_ScrnLogicalPixelWidth],ax ; store virt scrn pixel width\r
- mov cx,ax ; save ax (return value)\r
-\r
- ; calculate no. non split screen rows in video ram\r
-\r
- mov ax,0ffffh ; cx = Maximum video ram offset\r
- sub dx,dx ; DX:AX is divide operand, set DX = 0\r
- div bx ; divide ax by ScrnLogicalByteWidth\r
- mov [_ScrnLogicalHeight],ax ; Save Screen Logical Height\r
- mov [_BottomClip],ax ; Set default bottom clip row\r
- sub ax,[_ScrnPhysicalHeight] ; Update the maximum Y position of\r
- mov [_MaxScrollY],ax ; Physical screen in logical screen\r
- mov ax,cx ; restore ax (return value)\r
-\r
- ; calculate initial NonVisual\r
- mov ax,[_ScrnLogicalByteWidth]\r
- mul [_ScrnPhysicalHeight]\r
- mov [_NonVisual_Offs],ax\r
-\r
-@@Done: ret\r
-SetLogicalScrWidth endp\r
-\r
-clear_vram proc\r
- push di\r
- mov dx,SC_INDEX\r
- mov ax,0f02h\r
- out dx,ax ; enable writes to all four planes\r
- mov ax,SCREEN_SEG ; now clear all display memory, 8 pixels\r
- mov es,ax ; at a time\r
- sub di,di ; point ES:DI to display memory\r
-\r
- WaitVsyncEnd\r
-\r
- sub ax,ax ; clear to zero-value pixels\r
- mov cx,0FFFFh ; # of words in display memory\r
- rep stosw ; clear all of display memory\r
- pop di\r
- ret\r
-clear_vram endp\r
-\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X graphics mode set with a virtual screen\r
-; logical screen width.\r
-; C near-callable as:\r
-;\r
-; int x_set_mode(unsigned int mode,unsigned int WidthInPixels);\r
-;\r
-; returns the actual width of the allocated virtual screen in pixels\r
-; if a valid mode was selected otherwise returns -1\r
-;\r
-; Saves virtual screen pixel width in _ScrnLogicalPixelWidth.\r
-; Saves virtual screen byte width in _ScrnLogicalByteWidth.\r
-; Physical screen dimensions are set in _ScrnPhysicalPixelWidth,\r
-; _ScrnPhysicalByteWidth and _ScrnPhysicalHeight\r
-;\r
-;\r
-; Modes: 0 = 320 x 200 (256 color) NOTE: Some of these modes require\r
-; 1 = 320 x 240 (256 color) vertical size adjustment.\r
-; 2 = 360 x 200 (256 color)\r
-; 3 = 360 x 240 (256 color)\r
-; 4 = 320 x 400 (256 color)\r
-; 5 = 320 x 480 (256 color)\r
-; 6 = 360 x 200 (256 color)\r
-; 7 = 360 x 480 (256 color)\r
-; 8 = 360 x 360 (256 color)\r
-; 9 = 376 x 308 (256 color)\r
-; 10 = 376 x 564 (256 color)\r
-;\r
-; Written by Themie Gouthas,\r
-; parts adapted from M. Abrash code.\r
-;------------------------------------------------------------------------\r
-_x_set_mode proc\r
- ARG mode:word,logicalscrwidth:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp\r
-\r
- push si ;preserve C register vars\r
- push di ; (don't count on BIOS preserving anything)\r
-\r
- cld\r
- mov ax,ds\r
- mov es,ax\r
- mov di,offset PARAMS\r
- xor ax,ax\r
- mov cx,PARAM_COUNT\r
- rep stosb\r
-\r
- mov cx,[mode]\r
- cmp cx,LAST_X_MODE ; have we selected a valid mode\r
- jle @@ValidMode ; Yes !\r
-\r
- mov [_InGraphics],FALSE ; No return -1\r
- mov ax,-1\r
- pop di\r
- pop si\r
- pop bp\r
- ret\r
-\r
-@@ValidMode:\r
-\r
- mov [_CurrXMode],cx\r
- mov [_InGraphics],TRUE\r
-\r
- xor al,al\r
- cmp cx,3\r
- jg @@SetDoubleScanFlag\r
- mov al,TRUE\r
-@@SetDoubleScanFlag:\r
- mov [DoubleScanFlag],al\r
- push cx ; some bios's dont preserve cx\r
-\r
- call clear_vram\r
-\r
- mov ax,13h ; let the BIOS set standard 256-color\r
- int 10h ; mode (320x200 linear)\r
-\r
-\r
- pop cx\r
-\r
- mov dx,SC_INDEX\r
- mov ax,0604h\r
- out dx,ax ; disable chain4 mode\r
- mov ax,0100h\r
- out dx,ax ; synchronous reset while setting Misc\r
- ; Output for safety, even though clock\r
- ; unchanged\r
-\r
- mov bx,offset ModeTable\r
- shl cx,1\r
- add bx,cx\r
- mov si, word ptr [bx]\r
- lodsb\r
-\r
- or al,al\r
- jz @@DontSetDot\r
- mov dx,MISC_OUTPUT\r
- out dx,al ; select the dot clock and Horiz\r
- ; scanning rate\r
-@@DontSetDot:\r
- mov dx,SC_INDEX\r
- mov ax,0300h\r
- out dx,ax ; undo reset (restart sequencer)\r
-\r
-\r
- mov dx,CRTC_INDEX ; reprogram the CRT Controller\r
- mov al,11h ; VSync End reg contains register write\r
- out dx,al ; protect bit\r
- inc dx ; CRT Controller Data register\r
- in al,dx ; get current VSync End register setting\r
- and al,07fh ; remove write protect on various\r
- out dx,al ; CRTC registers\r
- dec dx ; CRT Controller Index\r
- cld\r
- xor cx,cx\r
- lodsb\r
- mov cl,al\r
-\r
-@@SetCRTParmsLoop:\r
- lodsw ; get the next CRT Index/Data pair\r
- out dx,ax ; set the next CRT Index/Data pair\r
- loop @@SetCRTParmsLoop\r
-\r
- mov dx,SC_INDEX\r
- mov ax,0f02h\r
- out dx,ax ; enable writes to all four planes\r
- mov ax,SCREEN_SEG ; now clear all display memory, 8 pixels\r
- mov es,ax ; at a time\r
- sub di,di ; point ES:DI to display memory\r
- sub ax,ax ; clear to zero-value pixels\r
- mov cx,8000h ; # of words in display memory\r
- rep stosw ; clear all of display memory\r
-\r
- ; Set pysical screen dimensions\r
-\r
- lodsw ; Load scrn pixel width\r
- mov [_ScrnPhysicalPixelWidth],ax ; from tweak table and store\r
- mov [_SplitScrnScanLine],ax ; No splitscrn ==\r
- ; splitscrn=PhysicalscrnHeight\r
- mov bx,ax ; Copy width for later use\r
- shr ax,2 ; Convert to byte width\r
- mov [_ScrnPhysicalByteWidth],ax ; Store for later use\r
- lodsw ; Load Screen Phys. Height\r
- mov [_ScrnPhysicalHeight],ax ; Store for later use\r
-\r
-\r
- ; Mode X is set, now set the required logical page width.\r
-\r
- mov cx,[logicalscrwidth]\r
-\r
- call SetLogicalScrWidth\r
-\r
- pop di ;restore C register vars\r
- pop si\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_set_mode endp\r
-\r
-;----------------------------------------------------------------------\r
-; Mode X (256 color mode) set default access video plane\r
-;\r
-; C near-callable as:\r
-; void x_select_default_plane(unsigned char plane);\r
-;\r
-; Enables Read/Write access to a plane using general memory access\r
-; methods\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_select_default_plane proc\r
-ARG Plane:byte\r
- push bp\r
- mov bp,sp ; set up stack frame\r
- mov cl,byte ptr [Plane]\r
-\r
- ; SELECT WRITE PLANE\r
- and cl,011b ;CL = plane\r
- mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg\r
- shl ah,cl ;set only the bit for the required\r
- ; plane to 1\r
- mov dx,SC_INDEX ;set the Map Mask to enable only the\r
- out dx,ax ; pixel's plane\r
-\r
- ; SELECT READ PLANE\r
- mov ah,cl ;AH = plane\r
- mov al,READ_MAP ;AL = index in GC of the Read Map reg\r
- mov dx,GC_INDEX ;set the Read Map to read the pixel's\r
- out dx,ax ; plane\r
-\r
- pop bp\r
- ret\r
-_x_select_default_plane endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Mode X (256 color mode) Set Mode X split screen starting row\r
-; The split screen resides on the bottom half of the screen and has a\r
-; starting address of A000:0000\r
-;\r
-; C near-callable as:\r
-; void x_set_splitscreen(unsigned int line);\r
-;\r
-; Updates _Page0_Offs to reflect the existence of the split screen region\r
-; ie _MainScrnOffset is set to the offset of the first pixel beyond the split\r
-; screen region\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-\r
-_x_set_splitscreen proc\r
- ARG Line:word\r
- push bp\r
- mov bp,sp ; set up stack frame\r
- push si\r
-\r
- xor si,si ; si=0 -> x virtual page start coord\r
-\r
- cmp [_DoubleBufferActive],0\r
- jne @@error\r
-\r
- cmp [_SplitScrnActive],0\r
- je @@NotPreviouslyCalled\r
-\r
-@@error:\r
- mov [_ErrorValue],ERROR\r
- pop si\r
- pop bp ; Return if previously called\r
- ret\r
-\r
-@@NotPreviouslyCalled:\r
-\r
- ; Turn on split screen pal pen suppression, so the split screen\r
- ; wo'nt be subject to pel panning as is the non split screen portion.\r
-\r
- mov dx,INPUT_STATUS_0\r
- in al,dx ; Reset the AC Index/Data toggle to\r
- ; index state\r
- mov al,AC_MODE_CONTROL+20h ; Bit 5 set to prevent screen blanking\r
- mov dx,AC_INDEX ; Point AC to Index/Data register\r
- out dx,al\r
- inc dx ; Point to AC Data reg (for reads only)\r
- in al,dx ; Get the current AC Mode Control reg\r
- or al,20h ; Enable split scrn Pel panning suppress.\r
- dec dx ; Point to AC Index/Data reg (for writes only)\r
- out dx,al ; Write the new AC Mode Control setting\r
- ; with split screen pel panning\r
- ; suppression turned on\r
-\r
- mov [_PhysicalStartByteX],ax ; Set the Phisical screen start\r
- mov [_PhysicalStartPixelX],ax ; offset within virtual screen\r
- mov [_PhysicalStartY],ax\r
- mov [_SplitScrnActive],TRUE\r
- mov ax,[Line]\r
- jns @@NotNeg ; Check that Split Scrn start scan line is +ve\r
-\r
- mov ax,0 ; Since -ve set to 0\r
-\r
-@@NotNeg:\r
- mov [_SplitScrnScanLine],ax ; save the scanline\r
-\r
-\r
-\r
- or [DoubleScanFlag],0\r
- jz @@NotDoubleScanned\r
- shl ax,1\r
- dec ax\r
-@@NotDoubleScanned:\r
- ;mov cl,[DoubleScanFlag]\r
- ;shl ax,cl ; Mode X 200 and 240 line modes are actually\r
- ; 400 and 480 lines that are double scanned\r
- ; so for start scanline multiply required ModeX\r
- ; scan line by 2 if its a double scanned mode\r
-\r
-\r
- mov bx,ax ; save the scanline\r
-\r
-\r
- WaitVsyncStart ; wait for vertical retrace\r
-\r
- cli ; Dont allow register setting to be interrupted\r
- mov dx,CRTC_INDEX\r
- mov ah,bl\r
- mov al,LINE_COMPARE\r
- out dx,ax ; Bits 7-0 of the split screen scan line\r
-\r
- mov ah,bh\r
- and ah,1\r
- shl ah,4\r
- mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split\r
- out dx,al ; screen scan line,\r
- inc dx ; So using readability of VGA registers\r
- in al,dx ; Read the OVERFLOW register, and set the\r
- and al, not 10h ; bit corresponding to Bit 8 (above)\r
- or al,ah\r
- out dx,al\r
-\r
- dec dx\r
- mov ah,bh\r
- and ah,2\r
- ror ah,3\r
- mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =\r
- out dx,al ; Bit 9 of split screen scan line\r
- inc dx ; As we did before, update the apropriate\r
- in al,dx ; bit without disturbing the rest\r
- and al, not 40h\r
- or al,ah\r
- out dx,al\r
- sti ; Registers are set, so interrupts are safe\r
-\r
- mov ax,[_ScrnPhysicalHeight] ; Determine where the first byte\r
- sub ax,[_SplitScrnScanLine] ; of the non split screen video ram\r
- mov [_SplitScrnVisibleHeight],ax ; starts and store it for reference\r
-\r
- mov bx,[_ScrnLogicalByteWidth]\r
- mul bx\r
- mov [_Page0_Offs],ax\r
- mov [_Page1_Offs],ax\r
- mov [_Page2_Offs],ax\r
-\r
- ; calculate no. non split screen rows in video ram\r
- mov cx,0ffffh ; cx = Maximum video ram offset\r
- sub cx,ax ; cx = cx - _Page0_Offs\r
- xchg cx,ax ; swap cx and ax\r
- sub dx,dx ; DX:AX is divide operand, set DX = 0\r
- div bx ; divide ax (prev cx) by\r
- ; ScrnLogicalByteWidth\r
-\r
- mov [_ScrnLogicalHeight],ax ; Save Screen Logical Height\r
- cmp ax,[_BottomClip]\r
- jle @@BottomClipOK ; Adjust Clip Rectangle if necessary\r
- mov [_BottomClip],ax\r
-@@BottomClipOK:\r
- sub ax,[_SplitScrnScanLine] ; Update the maximum Y position of\r
- mov [_MaxScrollY],ax ; Physical screen in logical screen\r
-\r
- xchg cx,ax ; restore original ax (MainScrnOfs)\r
- mov bh,al ; Set the visible screen start address\r
- mov ch,ah ; to the top left corner of the virtual\r
- jmp StartAddrEntry ; screen\r
-_x_set_splitscreen endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Page flip primer\r
-; No clipping is performed.\r
-; C near-callable as:\r
-;\r
-; void x_page_flip(unsigned int x, unsigned int y);\r
-;\r
-; Swaps visible and hidden page offsets and then executes the SetStartAddr\r
-; to achieve a page flip.\r
-;\r
-; SEE x_set_start_addr below\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-_x_page_flip proc\r
- ARG x:word,y:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- push si\r
-\r
- mov si,[x]\r
- mov ax,[_ScrnLogicalByteWidth] ; Calculate Offset increment\r
- mov cx,[y]\r
- mul cx ; for Y\r
- cmp [_DoubleBufferActive],TRUE ; Do we have double buffering ?\r
- je @@DoubleBuffer\r
- cmp [_TrippleBufferActive],TRUE\r
- jne PageFlipEntry1\r
-\r
-; TrippleBuffer\r
- mov bx,[_HiddenPageOffs]\r
- xchg bx,[_VisiblePageOffs]\r
- xchg bx,[_WaitingPageOffs]\r
- mov [_HiddenPageOffs],bx\r
- mov bx,[_VisiblePageIdx]\r
- inc bx\r
- cmp bx,3\r
- jne @@IdxOk\r
- xor bx,bx\r
-@@IdxOk:\r
- mov [_VisiblePageIdx],bx\r
- jmp short PageFlipEntry2\r
-@@DoubleBuffer:\r
- mov bx,[_HiddenPageOffs]\r
- xchg bx,[_VisiblePageOffs] ; Swap the Page Offsete\r
- xchg [_HiddenPageOffs],bx\r
- xor [_VisiblePageIdx],01h ; Set the Visible page index\r
- jmp short PageFlipEntry2\r
-_x_page_flip endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Set Mode X non split screen start address\r
-; of logical screen.\r
-; C near-callable as:\r
-;\r
-; void x_set_start_addr(unsigned int x, unsigned int y);\r
-;\r
-; Params: StartOffset is offset of first byte of logical screen ram\r
-; (Useful if you want to double buffer by splitting your non\r
-; split screen video ram into 2 pages)\r
-; X,Y coordinates of the top left hand corner of the physical screen\r
-; within the logical screen\r
-; X must not exceed (Logical screen width - Physical screen width)\r
-; Y must not exceed (Logical screen height - Physical screen height)\r
-;\r
-;\r
-; Written by Themie Gouthas,\r
-; Parts addapted from M. Abrash code published in DDJ Mag.\r
-;------------------------------------------------------------------------\r
-_x_set_start_addr proc\r
- ARG x:word,y:word\r
- push bp\r
- mov bp,sp\r
- push si\r
-\r
- mov si,[x]\r
- mov ax,[_ScrnLogicalByteWidth] ; Calculate Offset increment\r
- mov cx,[y] ; for Y\r
- mul cx\r
- cmp [_DoubleBufferActive],TRUE ; Do we have double buffering ?\r
- je @@PageResolution\r
- cmp [_TrippleBufferActive],TRUE\r
- je @@PageResolution\r
-PageFlipEntry1:\r
- add ax,[_Page0_Offs] ; no - add page 0 offset\r
- jmp short @@AddColumn\r
-\r
-PageFlipEntry2:\r
-\r
- mov [_PhysicalStartPixelX],si\r
- mov [_PhysicalStartY],cx\r
-\r
-@@PageResolution:\r
- add ax,[_VisiblePageOffs] ; Add visible page offset\r
-\r
-@@AddColumn:\r
- mov cx,si\r
- shr cx,2\r
- mov [_PhysicalStartByteX],cx\r
- add ax,cx ; add the column offset for X\r
- mov bh,al ; setup CRTC start addr regs and\r
- ; values in word registers for\r
- mov ch,ah ; fast word outs\r
-\r
-StartAddrEntry:\r
- mov bl,ADDR_LOW\r
- mov cl,ADDR_HIGH\r
- and si,0003h ; select pel pan register value for the\r
- mov ah,PelPanMask[si] ; required x coordinate\r
- mov al,PEL_PANNING+20h\r
- mov si,ax\r
-\r
- cmp [_VsyncHandlerActive],TRUE\r
- jne @@NoVsyncHandler\r
-; NEW STUFF\r
-@@WaitLast:\r
- cmp [_StartAddressFlag],0\r
- jne @@WaitLast\r
- cli\r
- mov [_WaitingStartLow],bx\r
- mov [_WaitingStartHigh],cx\r
- mov [_WaitingPelPan],si\r
- mov [_StartAddressFlag],1\r
- sti\r
- jmp short @@Return\r
-\r
-@@NoVsyncHandler:\r
- mov dx,INPUT_STATUS_0 ;Wait for trailing edge of Vsync pulse\r
-@@WaitDE:\r
- in al,dx\r
- test al,01h\r
- jnz @@WaitDE ;display enable is active low (0 = active)\r
-\r
- mov dx,CRTC_INDEX\r
- mov ax,bx\r
- cli\r
- out dx,ax ;start address low\r
- mov ax,cx\r
- out dx,ax ;start address high\r
- sti\r
-\r
-; Now wait for vertical sync, so the other page will be invisible when\r
-; we start drawing to it.\r
- mov dx,INPUT_STATUS_0 ;Wait for trailing edge of Vsync pulse\r
-@@WaitVS:\r
- in al,dx\r
- test al,08h\r
- jz @@WaitVS ;display enable is active low (0 = active)\r
-\r
-\r
- mov dx,AC_INDEX\r
- mov ax,si ; Point the attribute controller to pel pan\r
- cli\r
- out dx,al ; reg. Bit 5 also set to prevent blanking\r
- mov al,ah\r
- out dx,al ; load new Pel Pan setting.\r
- sti\r
-\r
-@@Return:\r
- mov [_ErrorValue],OK\r
- pop si\r
- pop bp\r
- ret\r
-_x_set_start_addr endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Mode X split screen hide\r
-; C near-callable as:\r
-;\r
-; void x_hide_splitscreen()\r
-;\r
-; Hides an existing split screen by setting its starting scan line to\r
-; the last physical screen scan line\r
-;\r
-; WARNING: Only to be used if SplitScrnLine has been previously called\r
-; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for\r
-; the initial split screen is reserved and the size limitations\r
-; of these modes means any change in the split screen scan line\r
-; will encroach on the split screen ram\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-_x_hide_splitscreen proc\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_SplitScrnActive],TRUE\r
- je @@SplitScreenEnabled\r
-\r
-@@error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@SplitScreenEnabled:\r
- cmp [_CurrXMode],4 ; Do nothing for Modes > 2\r
- jg @@error\r
- mov bx,[_ScrnPhysicalHeight]\r
-\r
- mov ax,[_ScrnLogicalHeight]\r
- sub ax,bx\r
- mov [_MaxScrollY],ax\r
- xor ax,ax\r
- mov [_SplitScrnVisibleHeight],ax\r
-\r
- or [DoubleScanFlag],0\r
- jz @@NotDoubleScanned\r
- shl bx,1\r
- dec bx\r
-@@NotDoubleScanned:\r
- ;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes\r
- ;shl bx,cl\r
-\r
- WaitVsyncStart ; wait for vertical retrace\r
-\r
- cli ; Dont allow register setting to be interrupted\r
- mov dx,CRTC_INDEX\r
- mov ah,bl\r
- mov al,LINE_COMPARE\r
- out dx,ax ; Bits 7-0 of the split screen scan line\r
-\r
- mov ah,bh\r
- and ah,1\r
- shl ah,4\r
- mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split\r
- out dx,al ; screen scan line,\r
- inc dx ; So using readability of VGA registers\r
- in al,dx ; Read the OVERFLOW register, and set the\r
- and al, not 10h ; bit corresponding to Bit 8 (above)\r
- or al,ah\r
- out dx,al\r
-\r
- dec dx\r
- mov ah,bh\r
- and ah,2\r
- ror ah,3\r
- mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =\r
- out dx,al ; Bit 9 of split screen scan line\r
- inc dx ; As we did before, update the apropriate\r
- in al,dx ; bit without disturbing the rest\r
- and al, not 40h\r
- or al,ah\r
- out dx,al\r
- sti ; Registers are set, so interrupts are safe\r
-\r
-@@done:\r
-\r
- mov [_ErrorValue],OK\r
- pop bp\r
- ret\r
-_x_hide_splitscreen endp\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Mode X split screen show\r
-; C near-callable as:\r
-;\r
-; void x_show_splitscreen()\r
-;\r
-; Restores split screen start scan line to the initial split screen\r
-; starting scan line as set by SplitScrnLine.\r
-;\r
-; WARNING: Only to be used if SplitScrnLine has been previously called\r
-; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for\r
-; the initial split screen is reserved and the size limitations\r
-; of these modes means any change in the split screen scan line\r
-; will encroach on the split screen ram\r
-; Update: Now disabled for these modes\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-\r
-_x_show_splitscreen proc\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_SplitScrnActive],TRUE\r
- je @@SplitScreenEnabled\r
-\r
-@@error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@SplitScreenEnabled:\r
- cmp [_CurrXMode],4 ; Do nothing for Modes > 2\r
- jg @@error\r
-\r
- mov bx,[_SplitScrnScanLine]\r
- mov ax,[_ScrnLogicalHeight] ; Update Max Scroll Y\r
- sub ax,bx\r
- mov [_MaxScrollY],ax\r
-\r
- mov ax,[_ScrnPhysicalHeight]\r
- sub ax,bx\r
- mov [_SplitScrnVisibleHeight],ax\r
-\r
- or [DoubleScanFlag],0\r
- jz @@NotDoubleScanned\r
- shl bx,1\r
- dec bx\r
-@@NotDoubleScanned:\r
- ;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes\r
- ;shl bx,cl\r
- WaitVsyncStart ; wait for vertical retrace\r
-\r
- cli ; Dont allow register setting to be interrupted\r
- mov dx,CRTC_INDEX\r
- mov ah,bl\r
- mov al,LINE_COMPARE\r
- out dx,ax ; Bits 7-0 of the split screen scan line\r
-\r
- mov ah,bh\r
- and ah,1\r
- shl ah,4\r
- mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split\r
- out dx,al ; screen scan line,\r
- inc dx ; So using readability of VGA registers\r
- in al,dx ; Read the OVERFLOW register, and set the\r
- and al, not 10h ; bit corresponding to Bit 8 (above)\r
- or al,ah\r
- out dx,al\r
-\r
- dec dx\r
- mov ah,bh\r
- and ah,2\r
- ror ah,3\r
- mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =\r
- out dx,al ; Bit 9 of split screen scan line\r
- inc dx ; As we did before, update the apropriate\r
- in al,dx ; bit without disturbing the rest\r
- and al, not 40h\r
- or al,ah\r
- out dx,al\r
- sti ; Registers are set, so interrupts are safe\r
-\r
-@@Done:\r
- mov [_ErrorValue],0\r
- pop bp\r
- ret\r
-_x_show_splitscreen endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Modify Mode X split screen starting scan line\r
-; C near-callable as:\r
-;\r
-; void x_adjust_splitscreen(unsigned int ScanLine)\r
-;\r
-; Sets the split screen start scan line to a new scan line. Valid scan lines\r
-; are between the initial split screen starting scan line and the last\r
-; physical screen scan line.\r
-;\r
-; WARNING: Only to be used if SplitScrnLine has been previously called\r
-; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for\r
-; the initial split screen is reserved and the size limitations\r
-; of these modes means any change in the split screen scan line\r
-; will encroach on the split screen ram\r
-; Update: Now disabled for these modes\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-\r
-_x_adjust_splitscreen proc\r
- ARG ScanLine\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_SplitScrnActive],TRUE\r
- je @@SplitScreenEnabled\r
-\r
-@@error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@SplitScreenEnabled:\r
- cmp [_CurrXMode],4 ; Do nothing for Modes > 2\r
- jg @@error\r
- mov bx,[ScanLine] ; Is the required starting scan line\r
- cmp bx,[_SplitScrnScanLine] ; valid ?\r
- js @@Done ; No - Then do nothing\r
-\r
-@@ValidScanLine:\r
-\r
- mov ax,[_ScrnLogicalHeight] ; Update Max Scroll Y\r
- sub ax,bx\r
- mov [_MaxScrollY],ax\r
-\r
- mov ax,[_ScrnPhysicalHeight]\r
- sub ax,bx\r
- mov [_SplitScrnVisibleHeight],ax\r
-\r
- or [DoubleScanFlag],0\r
- jz @@NotDoubleScanned\r
- shl bx,1\r
- dec bx\r
-@@NotDoubleScanned:\r
- ;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes\r
- ;shl bx,cl\r
-\r
- WaitVsyncStart ; wait for vertical retrace\r
-\r
- cli ; Dont allow register setting to be interrupted\r
-\r
- mov dx,CRTC_INDEX\r
- mov ah,bl\r
- mov al,LINE_COMPARE\r
- out dx,ax ; Bits 7-0 of the split screen scan line\r
-\r
- mov ah,bh\r
- and ah,1\r
- shl ah,4\r
- mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split\r
- out dx,al ; screen scan line,\r
- inc dx ; So using readability of VGA registers\r
- in al,dx ; Read the OVERFLOW register, and set the\r
- and al, not 10h ; bit corresponding to Bit 8 (above)\r
- or al,ah\r
- out dx,al\r
-\r
- dec dx\r
- mov ah,bh\r
- and ah,2\r
- ror ah,3\r
- mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =\r
- out dx,al ; Bit 9 of split screen scan line\r
- inc dx ; As we did before, update the apropriate\r
- in al,dx ; bit without disturbing the rest\r
- and al, not 40h\r
- or al,ah\r
- out dx,al\r
- sti ; Registers are set, so interrupts are safe\r
-@@Done:\r
- mov [_ErrorValue],OK\r
- pop bp\r
- ret\r
-_x_adjust_splitscreen endp\r
-\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Enable DoubleBuffering on non split screen area\r
-; C near-callable as:\r
-;\r
-; int x_set_doublebuffer(unsigned int PageHeight);\r
-;\r
-; Params: PageHeight is the height of the virtual screen to double buffer\r
-; Returns the closest possible height to the specified.\r
-;\r
-; Sets up two double buffering virtual pages\r
-; GLOBAL variables set:\r
-;\r
-; _Page1_Offs Offset of second virtual page\r
-; _NonVisual_Offs Offset of first non visible video ram byte\r
-; _DoubleBufferActive Flag\r
-; _PageAddrTable Table of Double buffering pages start offsets\r
-; _ScrnLogicalHeight Logical height of the double buffering pages\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-\r
-_x_set_doublebuffer proc\r
- ARG PageHeight:word\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_DoubleBufferActive],0\r
- je @@OkToContinue\r
-@error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@OkToContinue:\r
- mov [_VisiblePageIdx],0 ; Set visible Page to 0\r
- mov ax,[_ScrnLogicalHeight] ; Set Maximum D.B. Page height to\r
- shr ax,1 ; _ScrnLogicalHeight / 2\r
-\r
- mov bx,[PageHeight] ; Is the require D.B. Page Height\r
- cmp ax,bx ; > the Maximum D.B. Page Height ?\r
-\r
- js @@InvalidHeight ; no - jump\r
- mov ax,bx ; yes - Set the D.B. Page height to\r
- ; to the maximum allowed.\r
-\r
-@@InvalidHeight:\r
- mov [_ScrnLogicalHeight],ax ; Update logical screen height to\r
- ; reflect the height of a D.B. page\r
- cmp ax,[_BottomClip]\r
- jle @@BottomClipOK ; Adjust Clip Rectangle if necessary\r
- mov [_BottomClip],ax\r
-@@BottomClipOK:\r
- push ax\r
- mul [_ScrnLogicalByteWidth] ; Calculate the offset of the second\r
- mov cx,ax ; D.B. Page in video ram\r
- mov bx,[_Page0_Offs]\r
- mov [_VisiblePageOffs],bx\r
-\r
- add ax,bx\r
- mov [_Page1_Offs],ax ; Save it\r
- mov [_HiddenPageOffs],ax\r
-\r
- add ax,cx ; Calculate the offset of first byte\r
- mov [_NonVisual_Offs],ax ; beyond the D.B. pages and save it\r
- mov [_DoubleBufferActive],TRUE ; Set flag indicating D.B'ing mode on\r
-\r
- pop ax\r
- sub ax,[_ScrnPhysicalHeight]\r
- add ax,[_SplitScrnVisibleHeight]\r
- mov [_MaxScrollY],ax\r
-\r
- mov ax,dx ; return the D.B. pages' height\r
- mov [_ErrorValue],OK\r
- pop bp\r
- ret\r
-_x_set_doublebuffer endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Enable TrippleBuffering on non split screen area\r
-; C near-callable as:\r
-;\r
-; int x_set_tripplebuffer(unsigned int PageHeight);\r
-;\r
-; Params: PageHeight is the height of the virtual screen to tripple buffer\r
-; Returns the closest possible height to the specified.\r
-;\r
-; Sets up two tripple buffering virtual pages\r
-; GLOBAL variables set:\r
-;\r
-; _Page1_Offs Offset of second virtual page\r
-; _Page2_Offs Offset of third virtual page\r
-; _NonVisual_Offs Offset of first non visible video ram byte\r
-; _DoubleBufferActive Flag\r
-; _PageAddrTable Table of Double buffering pages start offsets\r
-; _ScrnLogicalHeight Logical height of the double buffering pages\r
-;\r
-;\r
-; Almost written by Tore Bastiansen (cut & paste from _x_set_doublebuffer)\r
-;------------------------------------------------------------------------\r
-\r
-_x_set_tripplebuffer proc\r
- ARG PageHeight:word\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_DoubleBufferActive],0\r
- jne @@Error\r
- cmp [_TrippleBufferActive],0\r
- je @@OkToContinue\r
-@@Error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@OkToContinue:\r
- mov [_VisiblePageIdx],0 ; Set visible Page to 0\r
- mov ax,[_ScrnLogicalHeight] ; Set Maximum T.B. Page height to\r
- mov bx,3\r
- xor dx,dx\r
- idiv bx ; _ScrnLogicalHeight / 3\r
-\r
- mov bx,[PageHeight] ; Is the require T.B. Page Height\r
- cmp ax,bx ; > the Maximum T.B. Page Height ?\r
-\r
- js @@InvalidHeight ; no - jump\r
- mov ax,bx ; yes - Set the T.B. Page height to\r
- ; to the maximum allowed.\r
-\r
-@@InvalidHeight:\r
- mov [_ScrnLogicalHeight],ax ; Update logical screen height to\r
- ; reflect the height of a T.B. page\r
- cmp ax,[_BottomClip]\r
- jle @@BottomClipOK ; Adjust Clip Rectangle if necessary\r
- mov [_BottomClip],ax\r
-@@BottomClipOK:\r
- push ax\r
- mul [_ScrnLogicalByteWidth] ; Calculate the offset of the second\r
- mov cx,ax ; D.B. Page in video ram\r
- mov bx,[_Page0_Offs]\r
- mov [_VisiblePageOffs],bx\r
-\r
- add ax,bx\r
- mov [_Page1_Offs],ax ; Save it\r
- mov [_HiddenPageOffs],ax\r
-\r
- add ax,cx\r
- mov [_Page2_Offs],ax ; Save the other it ?\r
- mov [_WaitingPageOffs],ax\r
-\r
- add ax,cx ; Calculate the offset of first byte\r
- mov [_NonVisual_Offs],ax ; beyond the D.B. pages and save it\r
- mov [_TrippleBufferActive],TRUE ; Set flag indicating T.B'ing mode on\r
-\r
- pop ax\r
- sub ax,[_ScrnPhysicalHeight]\r
- add ax,[_SplitScrnVisibleHeight]\r
- mov [_MaxScrollY],ax\r
-\r
- mov ax,dx ; return the D.B. pages' height\r
- mov [_ErrorValue],OK\r
- pop bp\r
- ret\r
-_x_set_tripplebuffer endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Set Clipping rectangle\r
-; C callable as:\r
-;\r
-;\r
-; int x_set_cliprect(WORD left,WORD top, WORD right, WORD bottom);\r
-;\r
-;\r
-; NOTE clipping is byte oriented. "left" and "right" are in bytes not pixels.\r
-; Only selected functions perform any clipping at all.\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-_x_set_cliprect proc\r
-ARG left:word,top:word,right:word,bottom:word\r
- push bp\r
- mov bp,sp\r
- mov ax,[left]\r
- mov bx,[right]\r
- cmp bx,ax\r
- jns @@CorrectXOrder\r
- xchg bx,ax\r
-@@CorrectXOrder:\r
- mov [_LeftClip],ax\r
- mov [_RightClip],bx\r
- mov ax,[top]\r
- mov bx,[bottom]\r
- cmp bx,ax\r
- jns @@CorrectYOrder\r
- xchg bx,ax\r
-@@CorrectYOrder:\r
- mov [_TopClip],ax\r
- mov [_BottomClip],bx\r
- pop bp\r
- ret\r
-_x_set_cliprect endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Return to text mode\r
-;\r
-_x_text_mode proc\r
- push bp\r
- call clear_vram\r
- mov ax,03h ; Restore Text Mode\r
- int 10h\r
-\r
- pop bp\r
- ret\r
-_x_text_mode endp\r
-\r
-;-----------------------------------------------------------------------\r
-; Wait for Vertical sync\r
-_x_wait_vsync proc\r
- push bp\r
- WaitVsyncStart\r
- pop bp\r
- ret\r
-_x_wait_vsync endp\r
-\r
-\r
- end\r