⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmain.asm

📁 视频游戏开发源码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	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 + -