📄 screen.asm
字号:
;* available registers :
;* BX = work register
;* AL, AH = work
;* exit : n/a
;* * NOTE: for overlapping windows, check that psOverlap:DI is pointing to
;* * our window (pwndDraw).
DRAW_ROUTINES PROC NEAR
;* * TextOut Variants
TO_dmTFB: ;* Text + attributes
lodsb
CheckWnd TO_dmTFB_next
mov bx,bp ;* set bh = attribute
mov bl,al ;* set bl = character
ifdef BUILTIN_SNOW
mov dx,3DAh ;* CGA video status port
StartDrawCrit
endif ;BUILTIN_SNOW
mov ax,bx
stosw ;* only time for 1 store
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
TO_dmTFB_next:
loop TO_dmTFB
ret
TO_dmT: ;* Text only
lodsb ;* get byte
CheckWnd TO_dmT_next
mov bl,al
ifdef BUILTIN_SNOW
mov dx,3DAh
StartDrawCrit
endif ;BUILTIN_SNOW
mov al,bl
stosb
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
inc di
TO_dmT_next:
loop TO_dmT
ret
ifndef DRAW_MODE_MINIMIZE
TO_dmTF: ;* leave background alone
mov bh,ah
l1_tf: lodsb
CheckWnd TO_dmTF_next
mov bx,bp ;* bh = attribute
mov bl,al
ifdef BUILTIN_SNOW
mov dx,3DAh
StartDrawCrit
endif ;BUILTIN_SNOW
mov ah,es:[di+1]
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
and ah,0F0H
or bh,ah
ifdef BUILTIN_SNOW
StartDrawCrit
endif ;BUILTIN_SNOW
mov ax,bx
stosw
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
TO_dmTF_next:
loop l1_tf
ret
TO_dmB: ;* background only
CheckWnd TO_dmB_next
mov bx,bp ; bh has new bg in hi nybble
and bh,0F0H ; change background only
inc di
ifdef BUILTIN_SNOW
mov dx,3DAh
StartDrawCrit
endif ;BUILTIN_SNOW
mov al,es:[di] ; al = old attribute
and al,0Fh ; al = old foreground only
or al,bh ; al = old fore & new back
stosb ;* only time for 1 store
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
TO_dmB_next:
loop TO_dmB
ret
TO_dmTMb: ;* character + map background
CheckWnd TO_dmTMb_next
ifdef BUILTIN_SNOW
mov dx,3DAh
StartDrawCrit
endif ;BUILTIN_SNOW
mov bl,es:[di+1]
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
lodsb ;* get character in AL
and bx,00F0H
shr bx,1
shr bx,1
shr bx,1
shr bx,1
add bx,bp
mov ah,ds:[bx] ;* look up new attribute
mov bx,ax
ifdef BUILTIN_SNOW
StartDrawCrit
endif ;BUILTIN_SNOW
mov ax,bx
stosw
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
TO_dmTMb_next:
loop TO_dmTMb
ret
FR_dmMf:
TO_dmMf: ;* map foreground
CheckWnd FR_dmMf_next
inc di
ifdef BUILTIN_SNOW
mov dx,3DAh
StartDrawCrit
endif ;BUILTIN_SNOW
mov bl,es:[di]
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
and bx,000FH
add bx,bp
mov bl,ds:[bx] ;* look up new attribute
ifdef BUILTIN_SNOW
StartDrawCrit
endif ;BUILTIN_SNOW
mov al,bl
stosb
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
FR_dmMf_next:
loop TO_dmMf
ret
TO_dmMfb: ;* Map attribute: old background maps to new background,
; old foreground maps to new foreground.
; Note: the tables for these guys are 16 + 16 bytes each.
inc di
ifdef BUILTIN_SNOW
mov dx,3DAh
StartDrawCrit
endif ;BUILTIN_SNOW
mov bl,es:[di] ;* get old attribute
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
and bx,000FH ;* mask to foreground
add bx,bp
mov bl,ds:[bx] ;* look up new foreground
push bx ;* save BL = new foreground
ifdef BUILTIN_SNOW
StartDrawCrit
endif ;BUILTIN_SNOW
mov bl,es:[di] ;* get old attribute
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
and bx,00F0H ;* mask to background
shr bx,1
shr bx,1
shr bx,1
shr bx,1
add bx,bp ;* bx = &rgca[background]
add bx,16 ;* bg's follow fg's in array.
ifdef BUILTIN_SNOW
StartDrawCrit
endif ;BUILTIN_SNOW
pop ax ;* restore AL = new fground
or al,ds:[bx] ;* Merge in new background
stosb
ifdef BUILTIN_SNOW
EndDrawCrit
dec cx
or cx,cx
jz @F
jmp TO_dmMfb
@@:
ELSE ;NOT DEFINED BUILTIN_SNOW
loop TO_dmMfb
endif ;BUILTIN_SNOW
ret
TO_dmMAttr: ;* Map entire attribute: old attr maps to new attr.
; Note that the tables for these guys are 256 bytes each.
inc di
ifdef BUILTIN_SNOW
mov dx,3DAh
StartDrawCrit
endif ;BUILTIN_SNOW
xor bx,bx ; BH = 0 for indexing.
mov bl,es:[di] ;* get old attribute
add bx,bp
mov al,ds:[bx] ;* look up new attribute
stosb
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
loop TO_dmMAttr
ret
endif ; !DRAW_MODE_MINIMIZE
;*****************************************************************************
;* * Fill Rectangle Variants
FR_dmTFB: ;* normal
mov ax,si ;* al = character
mov bx,bp ;* bh = attribute
mov bl,al ;* bx = ca:ch
FR_dmTFB_1:
CheckWnd FR_dmTFB_next
ifdef BUILTIN_SNOW
mov dx,3DAh
StartDrawCrit
endif ;BUILTIN_SNOW
mov ax,bx
stosw ;* store one
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
FR_dmTFB_next:
loop FR_dmTFB_1
ret
ifndef DRAW_MODE_MINIMIZE
FR_dmT: ;* text only
mov bx,si ;* bl = character
jmp short FR_dmFB_1
endif ; !DRAW_MODE_MINIMIZE
FR_dmFB: ;* ca only
mov bx,bp ;* bh = attribute
mov bl,bh ;* bl = value to store
inc di ;* point to ca
;* * this breaks the window test!!!!
FR_dmFB_1:
CheckWnd FR_dmFB_next
ifdef BUILTIN_SNOW
mov dx,3DAh
StartDrawCrit
endif ;BUILTIN_SNOW
mov al,bl
stosb ;* store one
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
inc di ;* to next ca
FR_dmFB_next:
loop FR_dmFB_1
ret
ifndef DRAW_MODE_MINIMIZE
FR_dmB: ;* fill background only
mov bx,bp ;* bh = attribute
and bh,0F0H ;* change background only
mov bl,00FH ;* keep mask
jmp short FR_dmF_1
FR_dmF: ;* fill foreground only
mov bx,bp ;* bh = attribute
and bh,00FH ;* change foreground only
mov bl,0F0H ;* keep mask
FR_dmF_1:
inc di ;* point to ca
;* * this breaks the window test!!!!
push bp ;* bp used for temp
FR_dmF_2:
CheckWnd FR_dmF_next
ifdef BUILTIN_SNOW
mov dx,3DAh
StartDrawCrit
endif ;BUILTIN_SNOW
mov al,es:[di] ;* get old background
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
and al,bl ;* keep half
or al,bh ;* replace half
mov bp,ax
ifdef BUILTIN_SNOW
StartDrawCrit
endif ;BUILTIN_SNOW
mov ax,bp
stosb
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
inc di
FR_dmF_next:
loop FR_dmF_2
pop bp ;* restored trashed bp
ret
FR_dmTMb: ;* character + map background
CheckWnd FR_dmTMb_next
ifdef BUILTIN_SNOW
mov dx,3DAh
StartDrawCrit
endif ;BUILTIN_SNOW
mov bl,es:[di+1] ;* get old attribute
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
and bx,00F0H ;* mask background
shr bx,1
shr bx,1
shr bx,1
shr bx,1
add bx,bp ;* bx = &rgca[background]
mov ax,si ;* load character (into al)
mov ah,ds:[bx] ;* look up new attribute
mov bx,ax
ifdef BUILTIN_SNOW
StartDrawCrit
endif ;BUILTIN_SNOW
mov ax,bx
stosw
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
FR_dmTMb_next:
loop FR_dmTMb
ret
FR_dmMb: ;* map background only
CheckWnd FR_dmMb_next
inc di ;* point to attribute
ifdef BUILTIN_SNOW
mov dx,3DAh
StartDrawCrit
endif ;BUILTIN_SNOW
mov bl,es:[di] ;* get old attribute
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
and bx,00F0H ;* mask background
shr bx,1
shr bx,1
shr bx,1
shr bx,1
add bx,bp ;* bx = &rgca[background]
mov bl,ds:[bx] ;* look up new attribute
ifdef BUILTIN_SNOW
StartDrawCrit
endif ;BUILTIN_SNOW
mov al,bl
stosb
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
FR_dmMb_next:
loop FR_dmMb
ret
endif ; !DRAW_MODE_MINIMIZE
;*****************************************************************************
;* * DBCS Fill Rectangle Variants (text modify only)
;* * all entry points should start with "shr cx,1"
ifdef KANJI
FR_dmTFB_DBCS: ;* normal
shr cx,1
mov dx,si ;* dx = DB character (dl first)
mov bx,bp ;* bh = attribute
mov bl,dl ;* BX = first ca:ch
mov dl,dh
mov dh,bh ;* DX = second ca:ch
FR_dmTFB_1_DBCS:
CheckWnd FR_dmTFB_next_DBCS
ifdef BUILTIN_SNOW
push cx
mov cx,dx
mov dx,3DAh
StartDrawCrit
mov ax,bx
stosw ;* store first character
mov ax,cx
stosw ;* store second character
EndDrawCrit
pop cx
ELSE ; !BUILTIN_SNOW
mov ax,bx
stosw ;* store first character
mov ax,dx
stosw ;* store second character
endif ;BUILTIN_SNOW
FR_dmTFB_next_DBCS:
loop FR_dmTFB_1_DBCS
ret
ifndef DRAW_MODE_MINIMIZE
FR_dmT_DBCS: ;* text only
shr cx,1
mov bx,si ;* bl = 1st, bh = 2nd
FR_dmFB_1_DBCS:
CheckWnd FR_dmFB_next_DBCS
ifdef BUILTIN_SNOW
mov dx,3DAh
StartDrawCrit
endif ;BUILTIN_SNOW
mov al,bl
stosb ;* store one
inc di ;* to next ca
mov al,bh
stosb ;* store one
ifdef BUILTIN_SNOW
EndDrawCrit
endif ;BUILTIN_SNOW
inc di ;* to next ca
FR_dmFB_next_DBCS:
loop FR_dmFB_1_DBCS
ret
endif ; !DRAW_MODE_MINIMIZE
endif ;KANJI
;*****************************************************************************
ifndef DRAW_MODE_MINIMIZE
;* ???? UNIMPLEMENTED !!!!!!
TO_dmF:
TO_dmTB:
TO_dmTMf:
TO_dmMb:
FR_dmTF:
FR_dmTB:
FR_dmTMf:
FR_dmMfb:
FR_dmMAttr:
ifdef KANJI
FR_dmTF_DBCS:
FR_dmTB_DBCS:
FR_dmTMf_DBCS:
FR_dmTMb_DBCS:
endif ;KANJI
;??????
endif ; !DRAW_MODE_MINIMIZE
InvalidMode:
ifdef DEBUG
cCall CowAssertFailed
DB "Invalid draw mode $"
endif ;DEBUG
ret
DRAW_ROUTINES ENDP ;* all near
;*****************************************************************************
;********** EndScreen **********
;* entry: fClear => clear screen
;* * Exit procedure - clear the screen
;* exit: n/a
cPublic EndScreen,<PUBLIC, ATOMIC>
parmW fClear
cBegin EndScreen
StartPublic
mov cx,fClear
jcxz dont_clear
ifdef REVIEW
mov al,caOld
ELSE
mov al,7
endif ;!REVIEW
mov ah,al ;* duplicate for MONO
xchg ax,[rgsa] ;* change isa == 0
push ax ;* save old
xor ax,ax
mov bx,' '
xor cx,cx
xor dx,dx
mov cl,axMac
mov dl,ayMac
ifdef WINDOW_OVERLAP
xor ax,ax
mov pwndCur,ax
endif ;WINDOW_OVERLAP
cCall FillArc,<ax,ax,cx,dx,bx,ax> ;* fill all with ' ' isaDefault
pop word ptr [rgsa] ;* restore old isaDefault
xor ax,ax
cCall insj.lpfnMoveHwCursCsdInsj,<ax,ax,sp> ;* top of screen & on
dont_clear:
;* * kill the screen driver
cCall insj.lpfnTermCsdInsj ;* ()
StopPublic
cEnd EndScreen
;*****************************************************************************
;********** ImodeGuessCurrent **********
;* entry: n/a
;* * call driver to guess current mode
;* exit: AX = imode (or -1 (imodeUnkown) if not known)
labelFP <PUBLIC, ImodeGuessCurrent>
jmp insj.lpfnImodeGuessCurrentCsdInsj
;********** FQueryInst **********
;* entry:
;* pinst : pointer to INST structure to fill
;* imode : index of mode to test
;* * Get information about modes available
;* * just call the INSJ procedure
;* exit: AX != 0 => ok (*pinst filled in)
;* == 0 => error (imode too high or can't query)
IFDEF DEBUG
cPublic FQueryInst,<PUBLIC>
parmW pinst
parmW imode
cBegin FQueryInst
cCall insj.lpfnFQueryInstCsdInsj,<pinst,imode>
or ax,ax ; If bogus mode,
jz fqi_done ; can't check inst.
mov bx,pinst
test [bx].finstInst,finstExtendedMono ; If ExtendedMono,
jz @F ; then must have
test [bx].finstInst,finstAttrFont ; AttrFont.
jz bust
@@:
test [bx].finstInst,finstAttrFont
jz fqi_done
test [bx].finstInst,finstMonochrome ; If AttrFont, then
jz bust ; must have Mono
test [bx].finstInst,finstText ; and Text.
jnz fqi_done
bust:
cCall CowAssertFailed
DB "FQueryInst fInst bits not in sync.$"
fqi_done:
cEnd FQueryInst
ELSE ;!DEBUG
labelFP <PUBLIC, FQueryInst>
jmp insj.lpfnFQueryInstCsdInsj
ENDIF ;!DEBUG
;********** FGetColorPalette **********
;* entry: co color
;* pcoi color combination index (returned)
;* rgcov RGB palette info (returned)
;* * get current palette setting for co
;* exit: AX = 0 => no color palette available, pcoi, rgcov
labelFP <PUBLIC, FGetColorPalette>
jmp insj.lpfnFGetColorPaletteCsdInsj
;********** SetColorPalette **********
;* entry: co color
;* coi color combination index
;* rgcov RGB palette info
;* * set current palette setting for co, does nothing if no color palette
;* exit: n/a
labelFP <PUBLIC, SetColorPalette>
jmp insj.lpfnSetColorPaletteCsdInsj
;********** MoveHardwareCursor **********
;* entry: axCurs, ayCurs = new absolute cursor position
;* fOn => whether on or off
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -