+++ /dev/null
-;-----------------------------------------------------------\r
-;\r
-; MXSM.ASM - Set/change mode functions\r
-; Copyright (c) 1993,1994 by Alessandro Scotti\r
-;\r
-;-----------------------------------------------------------\r
-WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxChangeMode\r
-PUBLIC mxGetAspect\r
-PUBLIC mxGetScreenSize\r
-PUBLIC mxSetMode\r
-\r
-PUBLIC mx_ScreenWidth\r
-PUBLIC mx_ScreenHeight\r
-PUBLIC mx_BytesPerLine\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mxSetSysClipRegion : FAR\r
-\r
-EXTRN mx_VideoSegment : WORD\r
-EXTRN mx_CodeSegment : WORD\r
-\r
-mx_ScreenWidth DW ? ; Current screen width\r
-mx_ScreenHeight DW ?\r
-mx_AspectX DW ? ; Aspect ratio for current mode\r
-mx_AspectY DW ?\r
-mx_BytesPerLine DW 0 ; Bytes per line\r
-\r
-;\r
-; Tables for setting video modes, sources:\r
-; - MODEX.ASM, Matt Pritchard\r
-; - Dr. Dobb's Journal, Michael Abrash\r
-; - Fractint VIDEO.ASM module\r
-;\r
-TBL_SingleLine LABEL WORD ; CRTC\r
- DW 04009h ; Cell height: 1 scan line\r
- DW 00014h ; Double word mode off\r
- DW 0E317h ; Byte mode on\r
- DW 0\r
-TBL_DoubleLine LABEL WORD ; CRTC\r
- DW 04109h ; Cell height: 2 scan lines\r
- DW 00014h\r
- DW 0E317h\r
- DW 0\r
-TBL_Width320 LABEL WORD ; CRTC\r
- DW 05F00h ; Horizontal total\r
- DW 04F01h ; Horizontal displayed\r
- DW 05002h ; Start horizontal blanking\r
- DW 08203h ; End horizontal blanking\r
- DW 05404h ; Start horizontal sync\r
- DW 08005h ; End horizontal sync\r
- DW 02813h ; Row address\r
- DW 0\r
-TBL_Width360 LABEL WORD ; CRTC\r
- DW 06B00h ; Horizontal total\r
- DW 05901h ; Horizontal displayed\r
- DW 05A02h ; Start horizontal blanking\r
- DW 08E03h ; End horizontal blanking\r
- DW 05E04h ; Start horizontal sync\r
- DW 08A05h ; End horizontal sync\r
- DW 02D13h ; Row address\r
- DW 0\r
-TBL_Height175 LABEL WORD ; CRTC\r
- DW 0BF06h ; Vertical total\r
- DW 01F07h ; Overflow\r
- DW 08310h ; Start vertical sync\r
- DW 08511h ; End vertical sync\r
- DW 05D12h ; Vertical displayed\r
- DW 06315h ; Start vertical blanking\r
- DW 0BA16h ; End vertical blanking\r
- DW 0\r
-TBL_Height200 LABEL WORD ; CRTC\r
- DW 0BF06h ; Vertical total\r
- DW 01F07h ; Overflow\r
- DW 09C10h ; Start vertical sync\r
- DW 08E11h ; End vertical sync\r
- DW 08F12h ; Vertical displayed\r
- DW 09615h ; Start vertical blanking\r
- DW 0B916h ; End vertical blanking\r
- DW 0\r
-TBL_Height240 LABEL WORD ; CRTC\r
- DW 00D06h ; Vertical total\r
- DW 03E07h ; Overflow\r
- DW 0EA10h ; Start vertical sync\r
- DW 08C11h ; End vertical sync\r
- DW 0DF12h ; Vertical displayed\r
- DW 0E715h ; Start vertical blanking\r
- DW 00616h ; End vertical blanking\r
- DW 0\r
-TBL_Tweak400x600:\r
- DW 07400h\r
- DW 06301h\r
- DW 06402h\r
- DW 09703h\r
- DW 06804h\r
- DW 09505h\r
- DW 08606h\r
- DW 0F007h\r
- DW 06009h\r
- DW 0310Fh\r
- DW 05B10h\r
- DW 08D11h\r
- DW 05712h\r
- DW 03213h\r
- DW 00014h\r
- DW 06015h\r
- DW 08016h\r
- DW 0E317h\r
- DW 0\r
-\r
-TBL_320x200:\r
- DB 63h ; 400 scan lines, 25 MHz clock\r
- DW 6, 5 ; Aspect: 6/5 = 1.2:1\r
- DW 320, 200 ; Size\r
- DW TBL_Width320, TBL_Height200, TBL_DoubleLine, 0\r
- DW 819 ; Max height\r
-TBL_320x240:\r
- DB 0E3h ; 400 scan lines, 25 MHz clock\r
- DW 1, 1 ; Aspect: 1/1 = 1:1\r
- DW 320, 240 ; Size\r
- DW TBL_Width320, TBL_Height240, TBL_DoubleLine, 0\r
- DW 819 ; Max height\r
-TBL_320x400:\r
- DB 63h ; 480 scan lines, 25 MHz clock\r
- DW 6, 10 ; Aspect: 6/10 = 0.6:1\r
- DW 320, 400 ; Size\r
- DW TBL_Width320, TBL_Height200, TBL_SingleLine, 0\r
- DW 819 ; Max height\r
-TBL_320x480:\r
- DB 0E3h ; 480 scan lines, 25 MHz clock\r
- DW 1, 2 ; Aspect: 1/2 = 0.5:1\r
- DW 320, 480 ; Size\r
- DW TBL_Width320, TBL_Height240, TBL_SingleLine, 0\r
- DW 819 ; Max height\r
-TBL_360x200:\r
- DB 067h ; 400 scan lines, 28 MHz clock\r
- DW 27, 20 ; Aspect: 27/20 = 1.35:1\r
- DW 360, 200 ; Size\r
- DW TBL_Width360, TBL_Height200, TBL_DoubleLine, 0\r
- DW 728 ; Max height\r
-TBL_360x240:\r
- DB 0E7h ; 480 scan lines, 28 MHz clock\r
- DW 9, 8 ; Aspect: 9/8 = 1.125:1\r
- DW 360, 240 ; Size\r
- DW TBL_Width360, TBL_Height240, TBL_DoubleLine, 0\r
- DW 728 ; Max height\r
-TBL_360x400:\r
- DB 067h ; 400 scan lines, 28 MHz clock\r
- DW 27, 40 ; Aspect: 27/40 = 0.675:1\r
- DW 360, 400 ; Size\r
- DW TBL_Width360, TBL_Height200, TBL_SingleLine, 0\r
- DW 728 ; Max height\r
-TBL_360x480:\r
- DB 0E7h ; 480 scan lines, 28 MHz clock\r
- DW 9, 16 ; Aspect: 9/16 = 0.5625:1\r
- DW 360, 480 ; Size\r
- DW TBL_Width360, TBL_Height240, TBL_SingleLine, 0\r
- DW 728 ; Max height\r
-TBL_320x175:\r
- DB 0A3h\r
- DW 0, 0 ; Aspect:\r
- DW 320, 175\r
- DW TBL_Width320, TBL_Height175, TBL_DoubleLine, 0\r
- DW 819\r
-TBL_320x350:\r
- DB 0A3h\r
- DW 0, 0 ; Aspect:\r
- DW 320, 175\r
- DW TBL_Width320, TBL_Height175, TBL_SingleLine, 0\r
- DW 819\r
-TBL_360x175:\r
- DB 0A7h\r
- DW 0, 0 ; Aspect:\r
- DW 360, 480 ; Size\r
- DW TBL_Width360, TBL_Height175, TBL_DoubleLine, 0\r
- DW 728 ; Max height\r
-TBL_360x350:\r
- DB 0A7h\r
- DW 0, 0 ; Aspect:\r
- DW 360, 480 ; Size\r
- DW TBL_Width360, TBL_Height175, TBL_SingleLine, 0\r
- DW 728 ; Max height\r
-TBL_400x600:\r
- DB 0E7h ; 28 MHz clock\r
- DW 1, 2 ; Aspect: 1/2 = 0.5:1\r
- DW 400, 600 ; Size\r
- DW TBL_Tweak400x600, 0\r
- DW 655 ; Max height\r
-\r
-TBL_Mode LABEL WORD\r
- DW TBL_320x175\r
- DW TBL_320x200\r
- DW TBL_320x240\r
- DW TBL_320x350\r
- DW TBL_320x400\r
- DW TBL_320x480\r
- DW TBL_360x175\r
- DW TBL_360x200\r
- DW TBL_360x240\r
- DW TBL_360x350\r
- DW TBL_360x400\r
- DW TBL_360x480\r
- DW TBL_400x600\r
-\r
-MAXVMODE EQU ($-OFFSET TBL_Mode) / 2\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Enables 80x25 color text mode\r
-;\r
-subText PROC NEAR\r
- ASSUME ds:MX_TEXT\r
- mov ax, 0003h\r
- int 10h ; Call BIOS set mode\r
-\r
- mov [mx_ScreenHeight], 0\r
- mov [mx_BytesPerLine], 0\r
- ret\r
-subText ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Enables the selected graphics mode.\r
-;\r
-; Input:\r
-; Mode = mode to select (MX_???x???)\r
-; Output:\r
-; none\r
-;\r
-mxSetMode PROC FAR\r
- ARG Mode:WORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds, si, es, di\r
-\r
-; Set DS to code segment alias\r
- mov ds, [mx_CodeSegment]\r
- ASSUME ds:MX_TEXT\r
-\r
- mov si, [Mode]\r
- cmp si, MAXVMODE ; Is it a valid mode?\r
- ja @@Exit ; No, exit\r
- test si, si ; Text mode?\r
- jnz @@Set ; No, handle it\r
-\r
- call subText ; Back to text mode\r
- jmp @@Exit ; Exit now\r
-\r
-; Set video mode\r
-@@Set:\r
- dec si ; Skip text mode\r
- shl si, 1\r
- mov si, TBL_Mode[si]\r
- cld\r
-\r
-; Use BIOS to set 320x200x256 linear mode\r
- push si ; Save SI\r
- mov ax, 0013h\r
- int 10h ; Use BIOS to set 320x200 linear mode\r
- pop si ; Restore SI\r
-\r
- mov dx, TS\r
- mov ax, 0604h\r
- out dx, ax ; Disable chain-4 mode\r
- mov ax, 0100h\r
- out dx, ax ; Reset\r
- mov dx, MISC\r
- lodsb\r
- out dx, al ; New timing/size\r
- mov dx, TS\r
- mov ax, 0300h\r
- out dx, ax ; Restart sequencer\r
-\r
-; Unlock CRTC registers 0-7\r
- mov dx, CRTC\r
- mov al, 11h\r
- out dx, al ; Vertical sync end register\r
- inc dx\r
- in al, dx\r
- and al, 7Fh ; Clear write protect bit\r
- out dx, al\r
-\r
- lodsw ; Get X aspect\r
- mov [mx_AspectX], ax\r
- lodsw ; Get Y aspect\r
- mov [mx_AspectY], ax\r
- lodsw ; Get screen width\r
- mov [mx_ScreenWidth], ax\r
- shr ax, 1\r
- shr ax, 1 ; Divide by four to get bytes per line\r
- mov [mx_BytesPerLine], ax\r
- lodsw ; Get screen height\r
- mov [mx_ScreenHeight], ax\r
-\r
-; Set CRTC registers\r
- mov bx, si\r
- mov dx, CRTC\r
-@@TableLoop:\r
- mov si, ds:[bx] ; DS:SI -> table of CRTC registers\r
- inc bx\r
- inc bx ; DS:BX -> offset of next table\r
- test si, si ; Last table?\r
- jz @@EndLoop ; Yes, exit loop\r
-@@Loop:\r
- lodsw ; Get CRTC register index and value\r
- test ax, ax ; End of table?\r
- jz @@TableLoop ; Yes, go to next table\r
- out dx, ax ; Set register AL to value AH\r
- jmp @@Loop ; Get next register/value\r
-@@EndLoop:\r
-\r
-; Set virtual screen and system clip region\r
- push [mx_ScreenWidth]\r
- push WORD PTR ds:[bx]\r
- call mxSetSysClipRegion\r
-\r
-; Clear video memory\r
- mov dx, TS\r
- mov ax, 0F02h\r
- out dx, ax ; Enable all planes\r
- mov es, [mx_VideoSegment]\r
- xor di, di\r
- mov cx, 8000h\r
- xor ax, ax\r
- rep stosw\r
-\r
-@@Done:\r
-; Lock CRTC registers 0-7 (some cards need this)\r
- mov dx, CRTC\r
- mov al, 11h\r
- out dx, al ; Vertical sync end register\r
- inc dx\r
- in al, dx\r
- or al, 80h ; Set write protect bit\r
- out dx, al\r
-\r
-@@Exit:\r
- xor ax, ax\r
- mov ax, [mx_ScreenWidth]\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxSetMode ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Changes from the current mode the selected graphics mode.\r
-;\r
-; Input:\r
-; Mode = mode to select (MX_???x???)\r
-; Output:\r
-; none\r
-; Notes:\r
-; this function assumes that mxSetMode and mxSetVirtualScreen\r
-; have been called first. View size is rearranged to match the\r
-; specified mode, but video memory is not cleared.\r
-; Differences from mxSetMode:\r
-; - video BIOS is not called to initialize graphics;\r
-; - row address register is not modified;\r
-; - video memory is not cleared;\r
-; - mx_BytesPerLine is not modified;\r
-; - system clip region is not modified.\r
-;\r
-mxChangeMode PROC FAR\r
- ARG Mode:WORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
- .push ds, si, es, di\r
-\r
-; Set DS to code segment alias\r
- mov ds, [mx_CodeSegment]\r
- ASSUME ds:MX_TEXT\r
-\r
- mov si, [Mode]\r
- cmp si, MAXVMODE ; Is it a valid mode?\r
- ja @@Exit ; No, exit\r
- test si, si ; Text mode?\r
- jz @@Exit ; Yes, exit\r
-\r
- dec si ; Skip text mode\r
- shl si, 1\r
- mov si, TBL_Mode[si]\r
- cld\r
-\r
- mov dx, TS\r
- mov ax, 0604h\r
- out dx, ax ; Disable chain-4 mode\r
- mov ax, 0100h\r
- out dx, ax ; Reset\r
- mov dx, MISC\r
- lodsb\r
- out dx, al ; New timing/size\r
- mov dx, TS\r
- mov ax, 0300h\r
- out dx, ax ; Restart sequencer\r
-\r
-; Unlock CRTC registers 0-7\r
- mov dx, CRTC\r
- mov al, 11h\r
- out dx, al ; Vertical sync end register\r
- inc dx\r
- in al, dx\r
- and al, 7Fh ; Clear write protect bit\r
- out dx, al\r
-\r
- lodsw ; Get X aspect\r
- mov [mx_AspectX], ax\r
- lodsw ; Get Y aspect\r
- mov [mx_AspectY], ax\r
- lodsw ; Get screen width\r
- mov [mx_ScreenWidth], ax\r
- lodsw ; Get screen height\r
- mov [mx_ScreenHeight], ax\r
-\r
-; Set CRTC registers\r
- mov bx, si\r
- mov dx, CRTC\r
-@@TableLoop:\r
- mov si, ds:[bx] ; DS:SI -> table of CRTC registers\r
- inc bx\r
- inc bx ; DS:BX -> offset of next table\r
- test si, si ; Last table?\r
- jz @@EndLoop ; Yes, exit loop\r
-@@Loop:\r
- lodsw ; Get CRTC register index and value\r
- test ax, ax ; End of table?\r
- jz @@TableLoop ; Yes, go to next table\r
- cmp al, 13h ; Row address register?\r
- je @@Loop ; Yes, ignore it\r
- out dx, ax ; Set register AL to value AH\r
- jmp @@Loop ; Get next register/value\r
-@@EndLoop:\r
-\r
-; Lock CRTC registers 0-7 (some cards need this)\r
- mov dx, CRTC\r
- mov al, 11h\r
- out dx, al ; Vertical sync end register\r
- inc dx\r
- in al, dx\r
- or al, 80h ; Set write protect bit\r
- out dx, al\r
-\r
-@@Exit:\r
- xor ax, ax\r
- mov ax, [mx_ScreenWidth]\r
- .pop ds, si, es, di\r
- .leave ARG_SIZE\r
-mxChangeMode ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Returns the aspect ratio for the current mode.\r
-;\r
-; Input:\r
-; AspectX = pointer to aspect X\r
-; AspectY = pointer to aspect Y\r
-;\r
-; A rectangle of width AspectX and height AspectY looks like a square.\r
-;\r
-mxGetAspect PROC FAR\r
- ARG AspectY:DWORD, \\r
- AspectX:DWORD = ARG_SIZE\r
- .enter 0\r
- .push ds, si\r
- ASSUME ds:NOTHING\r
-\r
- lds si, [AspectX]\r
- mov ax, [mx_AspectX]\r
- mov ds:[si], ax\r
- lds si, [AspectY]\r
- mov ax, [mx_AspectY]\r
- mov ds:[si], ax\r
-\r
- .pop ds, si\r
- .leave ARG_SIZE\r
-mxGetAspect ENDP\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Returns the current screen size.\r
-;\r
-; Input:\r
-; Width = pointer to screen width\r
-; Height = pointer to screen height\r
-;\r
-mxGetScreenSize PROC FAR\r
- ARG SizeY:DWORD, \\r
- SizeX:DWORD = ARG_SIZE\r
- .enter 0\r
- .push ds, si\r
- ASSUME ds:NOTHING\r
-\r
- lds si, [SizeX]\r
- mov ax, [mx_ScreenWidth]\r
- mov ds:[si], ax\r
- lds si, [SizeY]\r
- mov ax, [mx_ScreenHeight]\r
- mov ds:[si], ax\r
-\r
- .pop ds, si\r
- .leave ARG_SIZE\r
-mxGetScreenSize ENDP\r
-\r
-MX_TEXT ENDS\r
-END\r