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

📄 xmain.asm

📁 视频游戏开发源码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	_ScrnLogicalByteWidth    dw 0   ; Logical width in bytes of screen
	_ScrnLogicalPixelWidth   dw 0   ; Logical width in pixels of screen
	_ScrnLogicalHeight       dw 0   ; Logical Height of screen

	_MaxScrollX              dw 0   ; Max X start position of Physical
					; screen within virtual screen (in
					; bytes)
	_MaxScrollY              dw 0   ; Max Y start position of Physical
					; screen within virtual screen

	_VisiblePageIdx          dw 0   ; Index of currently visible D.B.
					; page

	PageAddrTable label word
	_VisiblePageOffs         dw 0   ; Table containing starting offsets
	_HiddenPageOffs          dw 0   ; of the double buffer pages
	_WaitingPageOffs                 dw 0

	_TopClip                 dw 0   ; Clipping Rectangle
	_BottomClip              dw 0   ;
	_LeftClip                dw 0   ; Left/Right coordinates in bytes
	_RightClip               dw 0   ;
	_PhysicalStartByteX      dw 0   ; X byte coord of physical screen
					; relative to virtual virtual screen
	_PhysicalStartPixelX     dw 0   ; X pixel coord of physical screen
					; relative to virtual screen
	_PhysicalStartY          dw 0   ; Y pixel coord of physical screen
					; relative to virtual screen

; NEW
	_VsyncHandlerActive     dw      0
	_MouseRefreshFlag       dw      0
	_MouseVsyncHandler      dd      0
	_StartAddressFlag       dw      0
	_WaitingStartLow        dw      0
	_WaitingStartHigh       dw      0
	_WaitingPelPan          dw      0
	_VsyncPaletteStart      dw      0
	_VsyncPaletteCount      dw      0
	_VsyncPaletteBuffer     label  byte
				db  768  dup(?)


PARAMS_END label byte

PARAM_COUNT equ ($-PARAMS)


; Index/data pairs for CRT Controller registers that differ between
; mode 13h and mode X.

	;Pelpan values for 0,1,2,3 pixel panning to the left, respectively
	PelPanMask              db      000h,002h,004h,006h

DoubleScanFlag db ?     ; Flag to indicate double scanned mode

	.code

;-------------------------------------------------------------------------
; Local Logical Screen Width setting function
; cx = Requitrd Logical Width
;
; WARNING: no registers are preserved

SetLogicalScrWidth proc
	mov   dx,CRTC_INDEX
	mov   al,CRTC_OFFSET
	out   dx,al
	inc   dx

	mov   ax,cx
	cmp   ax,[_ScrnPhysicalPixelWidth]; Is logical width >= physical width
	jge   @@ValidLogicalWidth          ; yes - continue
	mov   ax,bx                        ; no - set logical width = physical

@@ValidLogicalWidth:
	shr   ax,3
	out   dx,al

	; The EXACT logical pixel width may not have been possible since
	; it should be divisible by 8. Round down to the closest possible
	; width and update the status variables

	shl   ax,1
	mov   bx,ax
	mov   [_ScrnLogicalByteWidth],ax  ; Store the byte width of virtual
	mov   [_RightClip],ax             ; Set default Right clip column
					  ; screen
	sub   ax,[_ScrnPhysicalByteWidth] ; Calculate and store Max X position
	shl   ax,2                        ; of physical screen in virtual
	mov   [_MaxScrollX],ax            ; screen in pixels
	mov   ax,bx                       ; set ax to byte width of virt scrn
	shl   ax,2                        ; convert to pixels
	mov   [_ScrnLogicalPixelWidth],ax ; store virt scrn pixel width
	mov   cx,ax                       ; save ax (return value)

	; calculate no. non split screen rows in video ram

	mov   ax,0ffffh                ; cx = Maximum video ram offset
	sub   dx,dx                    ; DX:AX is divide operand,  set DX = 0
	div   bx                       ; divide ax by ScrnLogicalByteWidth
	mov   [_ScrnLogicalHeight],ax  ; Save Screen Logical Height
	mov   [_BottomClip],ax         ; Set default bottom clip row
	sub   ax,[_ScrnPhysicalHeight] ; Update the maximum Y position of
	mov   [_MaxScrollY],ax         ; Physical screen in logical screen
	mov   ax,cx                    ; restore ax (return value)

	; calculate initial NonVisual
	mov  ax,[_ScrnLogicalByteWidth]
	mul  [_ScrnPhysicalHeight]
	mov  [_NonVisual_Offs],ax

@@Done: ret
SetLogicalScrWidth endp

clear_vram proc
		push  di
	mov   dx,SC_INDEX
	mov   ax,0f02h
	out   dx,ax               ; enable writes to all four planes
	mov   ax,SCREEN_SEG       ; now clear all display memory, 8 pixels
	mov   es,ax               ; at a time
	sub   di,di               ; point ES:DI to display memory

	WaitVsyncEnd

	sub   ax,ax               ; clear to zero-value pixels
	mov   cx,0FFFFh           ; # of words in display memory
	rep   stosw               ; clear all of display memory
		pop   di
	ret
clear_vram endp



;-----------------------------------------------------------------------
; Mode X graphics mode set with a virtual screen
;   logical screen width.
; C near-callable as:
;
;    int x_set_mode(unsigned int mode,unsigned int WidthInPixels);
;
; returns the actual width of the allocated virtual screen in pixels
; if a valid mode was selected otherwise returns -1
;
; Saves virtual screen pixel width in _ScrnLogicalPixelWidth.
; Saves virtual screen byte  width in _ScrnLogicalByteWidth.
; Physical screen dimensions are set in _ScrnPhysicalPixelWidth,
; _ScrnPhysicalByteWidth and _ScrnPhysicalHeight
;
;
; Modes:  0  = 320 x 200  (256 color)  NOTE: Some of these modes require
;         1  = 320 x 240  (256 color)     vertical size adjustment.
;         2  = 360 x 200  (256 color)
;         3  = 360 x 240  (256 color)
;         4  = 320 x 400  (256 color)
;         5  = 320 x 480  (256 color)
;         6  = 360 x 200  (256 color)
;         7  = 360 x 480  (256 color)
;         8  = 360 x 360  (256 color)
;         9  = 376 x 308  (256 color)
;         10 = 376 x 564  (256 color)
;
; Written by Themie Gouthas,
; parts adapted from M. Abrash code.
;------------------------------------------------------------------------
_x_set_mode proc
	ARG   mode:word,logicalscrwidth:word
	push  bp      ;preserve caller's stack frame
	mov   bp,sp

	push  si      ;preserve C register vars
	push  di      ; (don't count on BIOS preserving anything)

	cld
	mov   ax,ds
	mov   es,ax
	mov   di,offset PARAMS
	xor   ax,ax
	mov   cx,PARAM_COUNT
	rep   stosb

	mov   cx,[mode]
	cmp   cx,LAST_X_MODE        ; have we selected a valid mode
	jle   @@ValidMode           ; Yes !

	mov   [_InGraphics],FALSE   ; No return -1
	mov   ax,-1
	pop   di
	pop   si
	pop   bp
	ret

@@ValidMode:

	mov   [_CurrXMode],cx
	mov   [_InGraphics],TRUE

	xor   al,al
	cmp   cx,3
	jg    @@SetDoubleScanFlag
	mov   al,TRUE
@@SetDoubleScanFlag:
	mov   [DoubleScanFlag],al
	push  cx                    ; some bios's dont preserve cx

	call  clear_vram

	mov   ax,13h                ; let the BIOS set standard 256-color
	int   10h                   ;  mode (320x200 linear)


	pop   cx

	mov   dx,SC_INDEX
	mov   ax,0604h
	out   dx,ax                 ; disable chain4 mode
	mov   ax,0100h
	out   dx,ax                 ; synchronous reset while setting Misc
				    ;  Output for safety, even though clock
				    ;  unchanged

	mov   bx,offset ModeTable
	shl   cx,1
	add   bx,cx
	mov   si, word ptr [bx]
	lodsb

	or    al,al
	jz    @@DontSetDot
	mov   dx,MISC_OUTPUT
	out   dx,al               ; select the dot clock and Horiz
				  ;  scanning rate
@@DontSetDot:
	mov   dx,SC_INDEX
	mov   ax,0300h
	out   dx,ax               ; undo reset (restart sequencer)


	mov   dx,CRTC_INDEX       ; reprogram the CRT Controller
	mov   al,11h              ; VSync End reg contains register write
	out   dx,al               ; protect bit
	inc   dx                  ; CRT Controller Data register
	in    al,dx               ; get current VSync End register setting
	and   al,07fh             ; remove write protect on various
	out   dx,al               ; CRTC registers
	dec   dx                  ; CRT Controller Index
	cld
	xor   cx,cx
	lodsb
	mov   cl,al

@@SetCRTParmsLoop:
	lodsw                     ; get the next CRT Index/Data pair
	out   dx,ax               ; set the next CRT Index/Data pair
	loop  @@SetCRTParmsLoop

	mov   dx,SC_INDEX
	mov   ax,0f02h
	out   dx,ax               ; enable writes to all four planes
	mov   ax,SCREEN_SEG       ; now clear all display memory, 8 pixels
	mov   es,ax               ; at a time
	sub   di,di               ; point ES:DI to display memory
	sub   ax,ax               ; clear to zero-value pixels
	mov   cx,8000h            ; # of words in display memory
	rep   stosw               ; clear all of display memory

	;  Set pysical screen dimensions

	lodsw                               ; Load scrn pixel width
	mov   [_ScrnPhysicalPixelWidth],ax  ;  from tweak table and store
	mov   [_SplitScrnScanLine],ax       ; No splitscrn ==
					    ; splitscrn=PhysicalscrnHeight
	mov   bx,ax                         ; Copy width for later use
	shr   ax,2                          ; Convert to byte width
	mov   [_ScrnPhysicalByteWidth],ax   ; Store for later use
	lodsw                               ; Load Screen Phys. Height
	mov   [_ScrnPhysicalHeight],ax      ; Store for later use


	;  Mode X is set, now set the required logical page width.

	mov     cx,[logicalscrwidth]

	call    SetLogicalScrWidth

	pop     di      ;restore C register vars
	pop     si
	pop     bp      ;restore caller's stack frame
	ret
_x_set_mode endp

;----------------------------------------------------------------------
; Mode X (256 color mode) set default access video plane
;
; C near-callable as:
;    void x_select_default_plane(unsigned char plane);
;
; Enables Read/Write access to a plane using general memory access
; methods
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
_x_select_default_plane proc
ARG Plane:byte
	push bp
	mov  bp,sp       ; set up stack frame
	mov  cl,byte ptr [Plane]

	; SELECT WRITE PLANE
	and  cl,011b              ;CL = plane
	mov  ax,0100h + MAP_MASK  ;AL = index in SC of Map Mask reg
	shl  ah,cl                ;set only the bit for the required
				  ; plane to 1
	mov  dx,SC_INDEX          ;set the Map Mask to enable only the
	out  dx,ax                ; pixel's plane

	; SELECT READ PLANE
	mov  ah,cl                ;AH = plane
	mov  al,READ_MAP          ;AL = index in GC of the Read Map reg
	mov  dx,GC_INDEX          ;set the Read Map to read the pixel's
	out  dx,ax                ; plane

	pop  bp
	ret
_x_select_default_plane endp


;----------------------------------------------------------------------
; Mode X (256 color mode) Set Mode X split screen starting row
; The split screen resides on the bottom half of the screen and has a
; starting address of A000:0000
;
; C near-callable as:
;    void x_set_splitscreen(unsigned int line);
;
; Updates _Page0_Offs to reflect the existence of the split screen region
; ie _MainScrnOffset is set to the offset of the first pixel beyond the split
; screen region
;
; Written by Themie Gouthas
;----------------------------------------------------------------------

_x_set_splitscreen proc
	ARG Line:word
	push bp
	mov  bp,sp       ; set up stack frame
	push si

	xor  si,si       ; si=0 -> x virtual page start coord

	cmp  [_DoubleBufferActive],0
	jne   @@error

	cmp  [_SplitScrnActive],0
	je   @@NotPreviouslyCalled

@@error:
	mov  [_ErrorValue],ERROR
	pop  si
	pop  bp          ; Return if previously called
	ret

@@NotPreviouslyCalled:

	; Turn on split screen pal pen suppression, so the split screen
	; wo'nt be subject to pel panning as is the non split screen portion.

	mov  dx,INPUT_STATUS_0
	in   al,dx                  ; Reset the AC Index/Data toggle to
					;  index state
	mov  al,AC_MODE_CONTROL+20h ; Bit 5 set to prevent screen blanking
	mov  dx,AC_INDEX            ; Point AC to Index/Data register
	out  dx,al
	inc  dx                     ; Point to AC Data reg (for reads only)
	in   al,dx                  ; Get the current AC Mode Control reg
	or   al,20h                 ; Enable split scrn Pel panning suppress.
	dec  dx                     ; Point to AC Index/Data reg (for writes only)
	out  dx,al                  ; Write the new AC Mode Control setting
					;  with split screen pel panning
					;  suppression turned on

	mov  [_PhysicalStartByteX],ax   ; Set the Phisical screen start
	mov  [_PhysicalStartPixelX],ax  ; offset within virtual screen
	mov  [_PhysicalStartY],ax

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -