📄 xmain.asm
字号:
_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 + -