📄 xmain.asm
字号:
sub ax,bx
mov [_MaxScrollY],ax
mov ax,[_ScrnPhysicalHeight]
sub ax,bx
mov [_SplitScrnVisibleHeight],ax
or [DoubleScanFlag],0
jz @@NotDoubleScanned
shl bx,1
dec bx
@@NotDoubleScanned:
;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes
;shl bx,cl
WaitVsyncStart ; wait for vertical retrace
cli ; Dont allow register setting to be interrupted
mov dx,CRTC_INDEX
mov ah,bl
mov al,LINE_COMPARE
out dx,ax ; Bits 7-0 of the split screen scan line
mov ah,bh
and ah,1
shl ah,4
mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split
out dx,al ; screen scan line,
inc dx ; So using readability of VGA registers
in al,dx ; Read the OVERFLOW register, and set the
and al, not 10h ; bit corresponding to Bit 8 (above)
or al,ah
out dx,al
dec dx
mov ah,bh
and ah,2
ror ah,3
mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =
out dx,al ; Bit 9 of split screen scan line
inc dx ; As we did before, update the apropriate
in al,dx ; bit without disturbing the rest
and al, not 40h
or al,ah
out dx,al
sti ; Registers are set, so interrupts are safe
@@Done:
mov [_ErrorValue],0
pop bp
ret
_x_show_splitscreen endp
;-----------------------------------------------------------------------
; Mode X (256 color mode) Modify Mode X split screen starting scan line
; C near-callable as:
;
; void x_adjust_splitscreen(unsigned int ScanLine)
;
; Sets the split screen start scan line to a new scan line. Valid scan lines
; are between the initial split screen starting scan line and the last
; physical screen scan line.
;
; WARNING: Only to be used if SplitScrnLine has been previously called
; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for
; the initial split screen is reserved and the size limitations
; of these modes means any change in the split screen scan line
; will encroach on the split screen ram
; Update: Now disabled for these modes
;
;
; Written by Themie Gouthas
;------------------------------------------------------------------------
_x_adjust_splitscreen proc
ARG ScanLine
push bp
mov bp,sp
cmp [_SplitScrnActive],TRUE
je @@SplitScreenEnabled
@@error:
mov [_ErrorValue],ERROR
pop bp
ret
@@SplitScreenEnabled:
cmp [_CurrXMode],4 ; Do nothing for Modes > 2
jg @@error
mov bx,[ScanLine] ; Is the required starting scan line
cmp bx,[_SplitScrnScanLine] ; valid ?
js @@Done ; No - Then do nothing
@@ValidScanLine:
mov ax,[_ScrnLogicalHeight] ; Update Max Scroll Y
sub ax,bx
mov [_MaxScrollY],ax
mov ax,[_ScrnPhysicalHeight]
sub ax,bx
mov [_SplitScrnVisibleHeight],ax
or [DoubleScanFlag],0
jz @@NotDoubleScanned
shl bx,1
dec bx
@@NotDoubleScanned:
;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes
;shl bx,cl
WaitVsyncStart ; wait for vertical retrace
cli ; Dont allow register setting to be interrupted
mov dx,CRTC_INDEX
mov ah,bl
mov al,LINE_COMPARE
out dx,ax ; Bits 7-0 of the split screen scan line
mov ah,bh
and ah,1
shl ah,4
mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split
out dx,al ; screen scan line,
inc dx ; So using readability of VGA registers
in al,dx ; Read the OVERFLOW register, and set the
and al, not 10h ; bit corresponding to Bit 8 (above)
or al,ah
out dx,al
dec dx
mov ah,bh
and ah,2
ror ah,3
mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =
out dx,al ; Bit 9 of split screen scan line
inc dx ; As we did before, update the apropriate
in al,dx ; bit without disturbing the rest
and al, not 40h
or al,ah
out dx,al
sti ; Registers are set, so interrupts are safe
@@Done:
mov [_ErrorValue],OK
pop bp
ret
_x_adjust_splitscreen endp
;-----------------------------------------------------------------------
; Mode X (256 color mode) Enable DoubleBuffering on non split screen area
; C near-callable as:
;
; int x_set_doublebuffer(unsigned int PageHeight);
;
; Params: PageHeight is the height of the virtual screen to double buffer
; Returns the closest possible height to the specified.
;
; Sets up two double buffering virtual pages
; GLOBAL variables set:
;
; _Page1_Offs Offset of second virtual page
; _NonVisual_Offs Offset of first non visible video ram byte
; _DoubleBufferActive Flag
; _PageAddrTable Table of Double buffering pages start offsets
; _ScrnLogicalHeight Logical height of the double buffering pages
;
;
; Written by Themie Gouthas
;------------------------------------------------------------------------
_x_set_doublebuffer proc
ARG PageHeight:word
push bp
mov bp,sp
cmp [_DoubleBufferActive],0
je @@OkToContinue
@error:
mov [_ErrorValue],ERROR
pop bp
ret
@@OkToContinue:
mov [_VisiblePageIdx],0 ; Set visible Page to 0
mov ax,[_ScrnLogicalHeight] ; Set Maximum D.B. Page height to
shr ax,1 ; _ScrnLogicalHeight / 2
mov bx,[PageHeight] ; Is the require D.B. Page Height
cmp ax,bx ; > the Maximum D.B. Page Height ?
js @@InvalidHeight ; no - jump
mov ax,bx ; yes - Set the D.B. Page height to
; to the maximum allowed.
@@InvalidHeight:
mov [_ScrnLogicalHeight],ax ; Update logical screen height to
; reflect the height of a D.B. page
cmp ax,[_BottomClip]
jle @@BottomClipOK ; Adjust Clip Rectangle if necessary
mov [_BottomClip],ax
@@BottomClipOK:
push ax
mul [_ScrnLogicalByteWidth] ; Calculate the offset of the second
mov cx,ax ; D.B. Page in video ram
mov bx,[_Page0_Offs]
mov [_VisiblePageOffs],bx
add ax,bx
mov [_Page1_Offs],ax ; Save it
mov [_HiddenPageOffs],ax
add ax,cx ; Calculate the offset of first byte
mov [_NonVisual_Offs],ax ; beyond the D.B. pages and save it
mov [_DoubleBufferActive],TRUE ; Set flag indicating D.B'ing mode on
pop ax
sub ax,[_ScrnPhysicalHeight]
add ax,[_SplitScrnVisibleHeight]
mov [_MaxScrollY],ax
mov ax,dx ; return the D.B. pages' height
mov [_ErrorValue],OK
pop bp
ret
_x_set_doublebuffer endp
;-----------------------------------------------------------------------
; Mode X (256 color mode) Enable TrippleBuffering on non split screen area
; C near-callable as:
;
; int x_set_tripplebuffer(unsigned int PageHeight);
;
; Params: PageHeight is the height of the virtual screen to tripple buffer
; Returns the closest possible height to the specified.
;
; Sets up two tripple buffering virtual pages
; GLOBAL variables set:
;
; _Page1_Offs Offset of second virtual page
; _Page2_Offs Offset of third virtual page
; _NonVisual_Offs Offset of first non visible video ram byte
; _DoubleBufferActive Flag
; _PageAddrTable Table of Double buffering pages start offsets
; _ScrnLogicalHeight Logical height of the double buffering pages
;
;
; Almost written by Tore Bastiansen (cut & paste from _x_set_doublebuffer)
;------------------------------------------------------------------------
_x_set_tripplebuffer proc
ARG PageHeight:word
push bp
mov bp,sp
cmp [_DoubleBufferActive],0
jne @@Error
cmp [_TrippleBufferActive],0
je @@OkToContinue
@@Error:
mov [_ErrorValue],ERROR
pop bp
ret
@@OkToContinue:
mov [_VisiblePageIdx],0 ; Set visible Page to 0
mov ax,[_ScrnLogicalHeight] ; Set Maximum T.B. Page height to
mov bx,3
xor dx,dx
idiv bx ; _ScrnLogicalHeight / 3
mov bx,[PageHeight] ; Is the require T.B. Page Height
cmp ax,bx ; > the Maximum T.B. Page Height ?
js @@InvalidHeight ; no - jump
mov ax,bx ; yes - Set the T.B. Page height to
; to the maximum allowed.
@@InvalidHeight:
mov [_ScrnLogicalHeight],ax ; Update logical screen height to
; reflect the height of a T.B. page
cmp ax,[_BottomClip]
jle @@BottomClipOK ; Adjust Clip Rectangle if necessary
mov [_BottomClip],ax
@@BottomClipOK:
push ax
mul [_ScrnLogicalByteWidth] ; Calculate the offset of the second
mov cx,ax ; D.B. Page in video ram
mov bx,[_Page0_Offs]
mov [_VisiblePageOffs],bx
add ax,bx
mov [_Page1_Offs],ax ; Save it
mov [_HiddenPageOffs],ax
add ax,cx
mov [_Page2_Offs],ax ; Save the other it ?
mov [_WaitingPageOffs],ax
add ax,cx ; Calculate the offset of first byte
mov [_NonVisual_Offs],ax ; beyond the D.B. pages and save it
mov [_TrippleBufferActive],TRUE ; Set flag indicating T.B'ing mode on
pop ax
sub ax,[_ScrnPhysicalHeight]
add ax,[_SplitScrnVisibleHeight]
mov [_MaxScrollY],ax
mov ax,dx ; return the D.B. pages' height
mov [_ErrorValue],OK
pop bp
ret
_x_set_tripplebuffer endp
;-----------------------------------------------------------------------
; Set Clipping rectangle
; C callable as:
;
;
; int x_set_cliprect(WORD left,WORD top, WORD right, WORD bottom);
;
;
; NOTE clipping is byte oriented. "left" and "right" are in bytes not pixels.
; Only selected functions perform any clipping at all.
;
; Written by Themie Gouthas
;------------------------------------------------------------------------
_x_set_cliprect proc
ARG left:word,top:word,right:word,bottom:word
push bp
mov bp,sp
mov ax,[left]
mov bx,[right]
cmp bx,ax
jns @@CorrectXOrder
xchg bx,ax
@@CorrectXOrder:
mov [_LeftClip],ax
mov [_RightClip],bx
mov ax,[top]
mov bx,[bottom]
cmp bx,ax
jns @@CorrectYOrder
xchg bx,ax
@@CorrectYOrder:
mov [_TopClip],ax
mov [_BottomClip],bx
pop bp
ret
_x_set_cliprect endp
;----------------------------------------------------------------------
; Return to text mode
;
_x_text_mode proc
push bp
call clear_vram
mov ax,03h ; Restore Text Mode
int 10h
pop bp
ret
_x_text_mode endp
;-----------------------------------------------------------------------
; Wait for Vertical sync
_x_wait_vsync proc
push bp
WaitVsyncStart
pop bp
ret
_x_wait_vsync endp
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -