You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6657 lines
186 KiB
6657 lines
186 KiB
|
|
TITLE Video interrupt 10h
|
|
|
|
;=======================================================================;
|
|
; (C)Copyright Qnix Computer Co. Ltd. 1992 ;
|
|
; This program contains proprietary and confidential information. ;
|
|
; All rights reserved. ;
|
|
;=======================================================================;
|
|
|
|
;=======================================================================;
|
|
; ;
|
|
; SPECIFICATION for video ;
|
|
; ;
|
|
;=======================================================================;
|
|
;
|
|
; Video card : MGA
|
|
; CGA
|
|
; EGA-mono
|
|
; EGA-color
|
|
; VGA
|
|
; Font card
|
|
; Dual monitor
|
|
; 한글/영문 video card
|
|
;
|
|
; Code/spec. : KS C 5842 - 1991
|
|
; 상용 한글 조합형, KSSM 한자
|
|
; 청계천 한글
|
|
;
|
|
; Video mode : 2/3 640*400 16 H/TE/TG
|
|
; (8*16font) 7 640*400 B/W H/TE/TG
|
|
; 40h 640*400 B/W G
|
|
; 60h 640*400 16 G
|
|
; 70h 640*400 B/W G
|
|
; 11h 640*480 B/W G
|
|
; 12h 640*480 16 G
|
|
;
|
|
; Video mode : 2/3 960*600 16 H
|
|
; (12*24font) 7 960*600 B/W H
|
|
; * H = 한글 text mode
|
|
; TE = Text emulation mode
|
|
; TG = Text emulation mode(not refresh)
|
|
; G = Graphics mode
|
|
;
|
|
; Font box : 8*16
|
|
;
|
|
; 문자자형의 종류
|
|
; : 16 * 16 한자 font - 'HJ16.PAT'
|
|
|
|
|
|
;========================================================================;
|
|
; ;
|
|
; VIDEO INTERRUPT 10H ;
|
|
; ;
|
|
;========================================================================;
|
|
;
|
|
; Video service routine들의 움직임을 일목요연하게 표기하며 가능한한
|
|
; 짧고 간결하게 표기한다.
|
|
;
|
|
; Reserved register : BP = stack pointer
|
|
; DS = CS
|
|
; ES = DataSeg
|
|
;
|
|
;
|
|
; Int10(AX, BX, CX, DX, SI, DI, ES)
|
|
; {
|
|
; if ([CodeStat] != HangeulMode), goto [OldInt10], Iret;
|
|
; sti
|
|
; cld
|
|
; if (AH=0,0fch,0fdh) || HangeulVideoMode
|
|
; {
|
|
; +[VideoActive]; /* INT10의 nesting감시 */
|
|
; Save BX,CX,DX,SI,DI,ES,DS,BP; /* AX = destory */
|
|
; BP = SP; /* save stack pointer */
|
|
; ES = DataSeg; /* default */
|
|
; DS = CodeSeg; /* default */
|
|
; switch(AH)
|
|
; case 0 : ModeSet(AL/-);
|
|
; break;
|
|
; case 1 : SetCurType(CX/-);
|
|
; break;
|
|
; case 2 : SetCurPos(BH,DX/-);
|
|
; break;
|
|
; case 3 : GetCurPos(BH/CX,DX);
|
|
; break;
|
|
; case 5 : SetPage(AL/-);
|
|
; break;
|
|
; case 6 : ScrollUp(AL,BH,CX,DX/-);
|
|
; break;
|
|
; case 7 : ScrollDown(AL,BH,CX,DX/-);
|
|
; break;
|
|
; case 8 : ReadCharAttr(BH/AX);
|
|
; break;
|
|
; case 9 : WriteCharAttr(AL,BX,CX/-);
|
|
; break;
|
|
; case 0ah : WriteChar(AL,BX,CX/-);
|
|
; break;
|
|
; case 0ch : WritePixel(AL,BH,CX,DX/-);
|
|
; break;
|
|
; case 0dh : ReadPixel(BH,CX,DX/AL);
|
|
; break;
|
|
; case 0eh : WriteTty(AL,BL/-);
|
|
; break;
|
|
; case 0fh : GetMode(-/AX,BH);
|
|
; break;
|
|
; case 0f6h : BlockMove(AL,BX,CX,DX/-);
|
|
; break;
|
|
; case 0f7h : BlockCopy(BX,CX,DX/-);
|
|
; break;
|
|
; case 0f8h : GetCharType(-/AL);
|
|
; break;
|
|
; case 0fch : FontCtrl(AL,*/*);
|
|
; break;
|
|
; case 0fdh : GetInfor(-/AL,BX,ES);
|
|
; break;
|
|
; case 0feh : WriteTtyInterim(AL,BL/-);
|
|
; break;
|
|
; default : Restore BX,CX,DX,SI,DI,ES,DS,BP;
|
|
; goto [OldInt10];
|
|
; UserEOP(-/-);
|
|
; Restore BX,CX,DX,SI,DI,ES,DS,BP;
|
|
; -[VideoActive];
|
|
; }
|
|
; else goto [OldInt10];
|
|
; iret;
|
|
; }
|
|
|
|
CODE SEGMENT PUBLIC WORD 'CODE'
|
|
ASSUME CS:CODE,DS:CODE,ES:DATA
|
|
|
|
INCLUDE EQU.INC
|
|
INCLUDE DATA.INC
|
|
|
|
; CursorStat
|
|
CursorOn = 00000001b
|
|
|
|
PUBLIC Int10
|
|
Int10:
|
|
if Debug
|
|
pushf
|
|
cli
|
|
push ax
|
|
push bx
|
|
mov ax,cs:[DebugData]
|
|
mov bx,ax
|
|
and bx,0f00h
|
|
and ax,0f0ffh
|
|
add bx,100h
|
|
and bx,0f00h
|
|
or ax,bx
|
|
out 10h,ax
|
|
mov cs:[DebugData],ax
|
|
pop bx
|
|
pop ax
|
|
popf
|
|
endif ; if Debug
|
|
cmp ah,01ch
|
|
jnz @f
|
|
jmp Return1ch
|
|
@@:
|
|
cmp ah,00h
|
|
jz @f
|
|
cmp ah,0fch
|
|
jz @f
|
|
cmp ah,0fdh
|
|
jz @f
|
|
test cs:[CodeStat],HangeulMode or HangeulVideoMode
|
|
jz EngInt10Do
|
|
jpo EngInt10Do
|
|
@@:
|
|
sti
|
|
cld
|
|
inc cs:[VideoActive]
|
|
@push bx,cx,dx,si,di,es,ds,bp
|
|
xor bp,bp
|
|
mov es,bp
|
|
mov bp,cs
|
|
mov ds,bp
|
|
mov bp,sp
|
|
mov si,ax
|
|
mov al,ah
|
|
xor ah,ah
|
|
add al,(10h-4)
|
|
xchg si,ax
|
|
cmp si,(23h-4)
|
|
ja EngInt10
|
|
shl si,1
|
|
call [si+JumpTbl]
|
|
@pop bp,ds,es,di,si,dx,cx,bx
|
|
dec cs:[VideoActive]
|
|
if Debug
|
|
pushf
|
|
cli
|
|
push ax
|
|
push bx
|
|
mov ax,cs:[DebugData]
|
|
mov bx,ax
|
|
and bx,0f00h
|
|
and ax,0f0ffh
|
|
sub bx,100h
|
|
and bx,0f00h
|
|
or ax,bx
|
|
out 10h,ax
|
|
mov cs:[DebugData],ax
|
|
pop bx
|
|
pop ax
|
|
popf
|
|
endif ; if Debug
|
|
iret
|
|
|
|
VdDummyRet:
|
|
add sp,2
|
|
EngInt10:
|
|
@pop bp,ds,es,di,si,dx,cx,bx
|
|
dec cs:[VideoActive]
|
|
EngInt10Do:
|
|
; KSE VGA mode 6 & AX = 1003h
|
|
cmp ax,1003h
|
|
jnz @f
|
|
push ax
|
|
push es
|
|
xor ax,ax
|
|
mov es,ax
|
|
cmp [rCrtMode],6
|
|
pop es
|
|
pop ax
|
|
jnz @f
|
|
iret
|
|
@@:
|
|
if Debug
|
|
pushf
|
|
call cs:[OldVideo]
|
|
pushf
|
|
cli
|
|
push ax
|
|
push bx
|
|
mov ax,cs:[DebugData]
|
|
mov bx,ax
|
|
and bx,0f00h
|
|
and ax,0f0ffh
|
|
sub bx,100h
|
|
and bx,0f00h
|
|
or ax,bx
|
|
out 10h,ax
|
|
mov cs:[DebugData],ax
|
|
pop bx
|
|
pop ax
|
|
popf
|
|
iret
|
|
else
|
|
jmp cs:[OldVideo]
|
|
endif ; if Debug
|
|
|
|
Return1ch:
|
|
pushf
|
|
call cs:[OldVideo]
|
|
mov al,01ch
|
|
iret
|
|
|
|
JumpTbl label word ; to be set at init by invoking SetMode
|
|
dw offset ControlCode ; ah=f4
|
|
dw offset CodeChange ; ah=f5
|
|
dw offset BlockMove ; ah=f6
|
|
dw offset BlockCopy ; ah=f7
|
|
dw offset GetCharType ; ah=f8
|
|
dw offset VdDummyRet ; ah=f9
|
|
dw offset VdDummyRet ; ah=fa
|
|
dw offset VdDummyRet ; ah=fb
|
|
dw offset FontCtrl ; ah=fc
|
|
dw offset GetInfor ; ah=fd
|
|
dw offset WriteTtyInterim ; ah=fe
|
|
dw offset VdDummyRet ; ah=ff (x)
|
|
|
|
dw offset ModeSet ; ah=0
|
|
dw offset SetCurType ; ah=1
|
|
dw offset SetCurPosAll ; ah=2
|
|
dw offset GetCurPos ; ah=3
|
|
dw offset VdDummyRet ; ah=4
|
|
dw offset SetPage ; ah=5
|
|
dw offset ScrollUp ; ah=6
|
|
dw offset ScrollDown ; ah=7
|
|
dw offset ReadCharAttr ; ah=8
|
|
dw offset WriteCharAttr ; ah=9
|
|
dw offset WriteChar ; ah=0a
|
|
dw offset VdDummyRet ; ah=0b
|
|
dw offset WritePixel ; ah=0c
|
|
dw offset ReadPixel ; ah=0d
|
|
dw offset WriteTty ; ah=0e
|
|
dw offset GetMode ; ah=0f
|
|
dw offset Attribute ; ah=10
|
|
dw offset VdDummyRet ; ah=11
|
|
dw offset VdDummyRet ; ah=12
|
|
dw offset WriteString ; ah=13
|
|
|
|
|
|
;=======================================================================
|
|
; << ModeSet >>
|
|
; FUNCTION = set video mode
|
|
; INPUT : AH = 00h
|
|
; AL = mode value & MSB
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
;
|
|
; video card에 따른 mode의 분류(mode-ID)
|
|
; 0 - 한글 video card, mode 2/3/7, MGA/CGA/EGA/VGA
|
|
; 1 - text emulation mode 7, MGA
|
|
; 2 - text emulation mode 2/3, CGA
|
|
; 3 - text emulation mode 7, EGA/VGA
|
|
; 4 - text emulation mode 2/3, EGA/VGA
|
|
; 5 - mode 40/70
|
|
; 6 - mode 60/11/12, EGA/VGA
|
|
;
|
|
; video card의 분류
|
|
; 0 - MGA
|
|
; 1 - CGA
|
|
; 2 - EGA mono
|
|
; 3 - EGA color
|
|
; 4 - MCGA
|
|
; 5 - VGA
|
|
;
|
|
; video card와 mode에 따른 modeset방법 분류
|
|
; 0 - 한글 video card, mode 2/3/7, MGA/CGA
|
|
; 1 - 한글 video card, mode 2/3/7, EGA/VGA
|
|
; 2 - grp mode or TE mode, MGA
|
|
; 3 - grp mode or TE mode, CGA
|
|
; 4 - grp mode or TE mode, EGA/VGA
|
|
;
|
|
; video buffer에 관한 정보 분류
|
|
; 0 - 80*25, 8*16 font
|
|
; 1 - 80*30, 8*16 font
|
|
;
|
|
; 상황에 따른 video mode set의 종류(TEXT mode)
|
|
; 0 - 한글 card, single monitor - TEXT, 8 page
|
|
; 1 - 한글 card, dual monitor - TEXT, 8 page
|
|
; 2 - 영문 card, single monitor - TE , 8 page (not CGA)
|
|
; 3 - 영문 card, dual monitor - grp , 1 page
|
|
;
|
|
|
|
|
|
;========================================================================
|
|
; << ModeSet >>
|
|
; FUNCTION = initialize the video mode
|
|
; INPUT : AL
|
|
; OUTPUT : none
|
|
; PROTECT : SS, SP
|
|
;
|
|
; ModeSet(AL/-)
|
|
; {
|
|
; save AX;
|
|
; ClearCursor(-/-);
|
|
; [ModeStat] = 0;
|
|
; [KbStat] = [KbStat] && not HanKeyinMode;
|
|
; [CodeStat] = [CodeStat] && not HangeulVideoMode;
|
|
; [CurMode] = AL;
|
|
; AL = AL && 01111111b;
|
|
; PreModeset(AL/AL); /* monitor type에 따라 equip/crtc addr set */
|
|
; HanCardReset(-/-);
|
|
; if (SearchMode(AL/AL,SI,carry) == CY)
|
|
; {
|
|
; Resrore AX;
|
|
; Restore BX,CX,DX,SI,DI,ES,DS,BP;
|
|
; goto [OldInt10];
|
|
; }
|
|
; Restore BX; /* = AX */
|
|
; [KbStat] = HanKeyinMode;
|
|
; [CodeStat] = [CodeStat] || HangeulVideoMode;
|
|
; NorModeset(AL,SI/SI);
|
|
; SettingVariables(SI/SI);
|
|
; InitVideoBuffer(SI/-);
|
|
; [CurMode] = [CurMode] && 01111111b;
|
|
; HanCardSet(-/-); /* 한글 card enable */
|
|
; }
|
|
;
|
|
ModeSet:
|
|
if Hwin31sw
|
|
jmp WinModeSet
|
|
endif ; Hwin31sw
|
|
ModeSet2:
|
|
push ax
|
|
call ClearCursor
|
|
mov [ModeStat],0
|
|
and [KbStat],not HanKeyinMode
|
|
and [CodeStat],not HangeulVideoMode
|
|
mov [CurMode],al
|
|
and al,01111111b
|
|
call PreModeset
|
|
call HanCardReset
|
|
call SearchMode
|
|
jnc ModeSetH
|
|
if KseVga
|
|
test cs:[KseCard],00000001b
|
|
jz @f
|
|
pop ax
|
|
push ax
|
|
cmp al,038h
|
|
jnz @f
|
|
call HanCardReSetGr
|
|
call kseveop
|
|
@@:
|
|
endif ; if KseVga
|
|
pop ax
|
|
pushf
|
|
call cs:[OldVideo]
|
|
ret
|
|
ModeSetH:
|
|
pop bx ; AX
|
|
or [KbStat],HanKeyinMode
|
|
or [CodeStat],HangeulVideoMode
|
|
test cs:[Card1st],VgaCard
|
|
jz @f
|
|
call ChgParmE2H
|
|
@@:
|
|
call NorModeset
|
|
test cs:[Card1st],VgaCard
|
|
jz @f
|
|
call ChgParmH2E
|
|
@@:
|
|
call SettingVariables
|
|
call InitVideoBuffer
|
|
and [CurMode],01111111b
|
|
call HanCardSet
|
|
ret
|
|
|
|
if KseVga
|
|
HanCardReSetGr:
|
|
call KseVgaKey
|
|
mov al,37h
|
|
out dx,al
|
|
inc dl
|
|
in al,dx
|
|
and al,11111110b
|
|
or al,00000011b
|
|
out dx,al
|
|
ret
|
|
endif ; KseVga
|
|
|
|
ChgParmH2E:
|
|
@push es,ds,di
|
|
ASSUME DS:DATA
|
|
xor di,di
|
|
mov ds,di
|
|
les di,cs:[OldVdParms]
|
|
mov word ptr [rVdParm],di
|
|
mov word ptr [rVdParm+2],es
|
|
test cs:[Card1st],VgaCard
|
|
jz @f
|
|
les di,cs:[OldSavePtr]
|
|
les di,es:[di]
|
|
mov word ptr cs:[HanSavePtr],di
|
|
mov word ptr cs:[HanSavePtr+2],es
|
|
@@:
|
|
ASSUME DS:CODE
|
|
@pop di,ds,es
|
|
ret
|
|
|
|
ChgParmE2H:
|
|
@push ds,di
|
|
ASSUME DS:DATA
|
|
xor di,di
|
|
mov ds,di
|
|
mov word ptr [rVdParm],offset VideoParms
|
|
mov word ptr [rVdParm+2],cs
|
|
test cs:[Card1st],VgaCard
|
|
jz @f
|
|
mov word ptr cs:[HanSavePtr],offset VideoParmsTbl
|
|
mov word ptr cs:[HanSavePtr+2],cs
|
|
@@:
|
|
ASSUME DS:CODE
|
|
@pop di,ds
|
|
ret
|
|
|
|
;------------------------------------------------------------------------
|
|
; << PreModeSet >>
|
|
; FUNCTION = initialize video card state
|
|
; INPUT : AL
|
|
; OUTPUT : AL
|
|
; PROTECT : DS, ES, AL
|
|
;
|
|
; PreModeSet(AL/AL)
|
|
; {
|
|
; if (([Card1st] == DualMnt) && ([Card1st] != ES:[rEquip]))
|
|
; {
|
|
; XCHG [GetHan1st],[GetHan2nd];
|
|
; XCHG [GetUdc1st],[GetUdc2nd];
|
|
; XCHG [PutUdc1st],[PutUdc2nd];
|
|
; XCHG [HanOn1st],[HanOn2nd];
|
|
; XCHG [HanOff1st],[HanOff2nd];
|
|
; XCHG [Card1st],[Card2nd];
|
|
; }
|
|
; else
|
|
; {
|
|
; if ([Card1st] == EgaCardM)
|
|
; {
|
|
; ES:[rEquip] = mono equip;
|
|
; ES:[rAddr6845] = 3b4h;
|
|
; OUT 3c2h,62h;
|
|
; }
|
|
; if ([Card1st] == EgaCardC)
|
|
; {
|
|
; ES:[rEquip] = color equip;
|
|
; ES:[rAddr6845] = 3d4h;
|
|
; OUT 3c2h,63h;
|
|
; }
|
|
; }
|
|
; }
|
|
;
|
|
PreModeSet:
|
|
test [Card1st],DualMnt
|
|
jz PreModeSetSingle
|
|
xor ah,ah
|
|
test [Card1st],ColorMnt
|
|
jz @f
|
|
xor ah,1
|
|
@@:
|
|
test [rEquip],00110000b
|
|
jpe @f
|
|
xor ah,1
|
|
@@:
|
|
or ah,ah
|
|
jz @f
|
|
call XchgCardParms
|
|
@@:
|
|
ret
|
|
XchgCardParms:
|
|
mov bx,[GetHan1st]
|
|
xchg bx,[GetHan2nd]
|
|
mov [GetHan1st],bx
|
|
mov bx,[GetUdc1st]
|
|
xchg bx,[GetUdc2nd]
|
|
mov [GetUdc1st],bx
|
|
mov bx,[PutUdc1st]
|
|
xchg bx,[PutUdc2nd]
|
|
mov [PutUdc1st],bx
|
|
mov bx,[HanOn1st]
|
|
xchg bx,[HanOn2nd]
|
|
mov [HanOn1st],bx
|
|
mov bx,[HanOff1st]
|
|
xchg bx,[HanOff2nd]
|
|
mov [HanOff1st],bx
|
|
mov bl,[Card1st]
|
|
xchg bl,[Card2nd]
|
|
mov [Card1st],bl
|
|
ret
|
|
PreModeSetSingle:
|
|
push ax
|
|
mov ah,[Card1st]
|
|
and ah,CardType
|
|
cmp ah,EgaCardM
|
|
jnz @f
|
|
or [rEquip],00110000b
|
|
mov [rAddr6845],3b4h
|
|
mov dx,GrpIndex
|
|
mov al,62h
|
|
out dx,al
|
|
@@:
|
|
cmp ah,EgaCardC
|
|
jnz @f
|
|
and [rEquip],11101111b
|
|
or [rEquip],00100000b
|
|
mov [rAddr6845],3d4h
|
|
mov dx,3c2h
|
|
mov al,63h
|
|
out dx,al
|
|
@@:
|
|
pop ax
|
|
ret
|
|
|
|
;------------------------------------------------------------------------
|
|
; << SearchMode >>
|
|
; FUNCTION = search video mode & get parms pointer
|
|
; INPUT : AL = mode value(W/O MSB)
|
|
; OUTPUT : AL, SI, carry(set = english mode)
|
|
; PROTECT : DS, ES, AL
|
|
;
|
|
; SearchMode(AL/AL,SI,carry)
|
|
; {
|
|
; switch([Card1st])
|
|
; {
|
|
; case MgaCard:
|
|
; if (AL != 7/40h/70h), AL = 7;
|
|
; break;
|
|
; case CgaCard:
|
|
; if (AL != 0-6/40h), AL = 3;
|
|
; break;
|
|
; case EgaCardM:
|
|
; if (AL != 7/0fh/40h/70h), AL = 7;
|
|
; break;
|
|
; case EgaCardC:
|
|
; if (AL != 0-6/0dh/0eh/10h/40h/70h/60h), AL = 3;
|
|
; break;
|
|
; case VgaCard:
|
|
; case McgaCard:
|
|
; if (AL != 0-6/0dh-13h/40h/70h/60h), AL = 3;
|
|
; }
|
|
; if (AL == 2), AL = 3;
|
|
; if ([Card1st] == DualMnt)
|
|
; {
|
|
; if (([rEquip] == mono) && (AL == 40h))
|
|
; AL = 7;
|
|
; if (([rEquip] == color) && (AL == 70h))
|
|
; AL = 3;
|
|
; }
|
|
; if (([Card1st] != HanCard) && (AL == 3/7))
|
|
; {
|
|
; AL = AL || 10h;
|
|
; if ([Card1st] == DualMnt), AL = AL || 80h;
|
|
; }
|
|
; switch([card1st])
|
|
; {
|
|
; case MgaCard:
|
|
; SI = MgaModeTbl;
|
|
; break;
|
|
; case CgaCard:
|
|
; SI = CgaModeTbl;
|
|
; break;
|
|
; case EgaCardM:
|
|
; case EgaCardC:
|
|
; SI = EgaModeTbl;
|
|
; break;
|
|
; case VgaCard:
|
|
; case McgaCard:
|
|
; SI = VgaModeTbl;
|
|
; }
|
|
; /* search AL */
|
|
; /* if match, NC */
|
|
; /* if not, CY */
|
|
; }
|
|
;
|
|
SearchMode:
|
|
test [CodeStat],HangeulMode
|
|
jz SearchModeErr
|
|
test [Card1st],DualMnt
|
|
jz SearchModeDual
|
|
cmp al,7
|
|
jz @f
|
|
cmp al,0fh
|
|
jz @f
|
|
cmp al,70h
|
|
jz @f
|
|
test [rEquip],00110000b
|
|
jpo SearchModeDual ; jump if color mode & color equip
|
|
mov al,7
|
|
mov [CurMode],al
|
|
jmp short SearchModeDual
|
|
@@:
|
|
test [rEquip],00110000b
|
|
jpe SearchModeDual ; jump if mono mode & mono equip
|
|
mov al,3
|
|
mov [CurMode],al
|
|
SearchModeDual:
|
|
mov bl,[Card1st]
|
|
and bx,CardType
|
|
mov si,[bx+ModeTable]
|
|
@@:
|
|
cmp [si],al
|
|
jz SearchModeAdj
|
|
cmp byte ptr [si],-1
|
|
jz SearchModeDefault
|
|
cmp byte ptr [si],-2
|
|
jz SearchModeErr
|
|
inc si
|
|
jmp short @b
|
|
SearchModeErr:
|
|
stc
|
|
ret
|
|
SearchModeDefault:
|
|
mov al,7
|
|
test [Card1st],ColorMnt
|
|
jz @f
|
|
mov al,3
|
|
@@:
|
|
mov [CurMode],al
|
|
SearchModeAdj:
|
|
cmp al,2
|
|
jnz @f
|
|
mov al,3
|
|
@@:
|
|
test [Card1st],DualMnt
|
|
jz SearchModeAdj2
|
|
cmp al,40h
|
|
jnz @f
|
|
test [rEquip],00110000b
|
|
jpo @f
|
|
mov al,70h
|
|
mov [CurMode],al
|
|
@@:
|
|
cmp al,70h
|
|
jnz SearchModeAdj2
|
|
test [rEquip],00110000b
|
|
jpe SearchModeAdj2
|
|
mov al,40h
|
|
mov [CurMode],al
|
|
SearchModeAdj2:
|
|
mov ah,al
|
|
cmp ah,3
|
|
jz @f
|
|
cmp ah,7
|
|
jnz SearchModeDo
|
|
@@:
|
|
test [CodeStat],Chab or WSung7
|
|
jnz @f
|
|
test [Card1st],HanCard
|
|
jnz SearchModeDo
|
|
@@:
|
|
or ah,80h
|
|
test [Card1st],DualMnt
|
|
jz SearchModeDo
|
|
or ah,10h
|
|
SearchModeDo:
|
|
mov bl,[Card1st]
|
|
and bx,CardType
|
|
shl bx,1
|
|
mov si,[bx+ModeParmsTbl]
|
|
add bx,2
|
|
mov cx,[bx+ModeParmsTbl]
|
|
mov bx,ModeTblLng
|
|
@@:
|
|
cmp [si],ah
|
|
jz @f
|
|
add si,bx
|
|
loop @b
|
|
jmp SearchModeErr
|
|
@@:
|
|
clc
|
|
ret
|
|
ModeTable label word
|
|
dw offset MgaAllModeTbl
|
|
dw offset CgaAllModeTbl
|
|
dw offset EgaMAllModeTbl
|
|
dw offset EgaCAllModeTbl
|
|
dw offset McgaAllModeTbl
|
|
dw offset VgaAllModeTbl
|
|
|
|
MgaAllModeTbl db 7, 40h, 70h, -1
|
|
CgaAllModeTbl db 0, 1, 2, 3, 4, 5, 6, 40h, -1
|
|
|
|
ModeParmsTbl label word
|
|
dw offset MgaModeTbl
|
|
dw 5
|
|
dw offset CgaModeTbl
|
|
dw 4
|
|
dw offset EgaModeTbl
|
|
dw 9
|
|
dw offset EgaModeTbl
|
|
dw 9
|
|
dw offset VgaModeTbl
|
|
dw 11
|
|
dw offset VgaModeTbl
|
|
dw 11
|
|
|
|
MgaModeTbl label byte
|
|
db 07h,0*2,07h,0b0h,0b0h,10h,000h,00000000b,25 ; han
|
|
dw 0, 0,0b0ch
|
|
ModeTblLng = $-MgaModeTbl
|
|
db 87h,1*2,07h,0b0h,0b8h,10h,080h,10000100b,25 ; single
|
|
dw 38h,38ah,0b0ch
|
|
db 97h,1*2,07h,000h,0b0h,00h,080h,00000100b,25 ; dual
|
|
dw 38h,10ah,0b0ch
|
|
db 40h,5*2,07h,000h,0b8h,00h,080h,01100100b,25 ;
|
|
dw 38h,38ah,2e0fh
|
|
db 70h,5*2,07h,000h,0b0h,00h,080h,00100100b,25 ;
|
|
dw 38h,10ah,2e0fh
|
|
|
|
CgaModeTbl label byte
|
|
db 03h,0*2,03h,0b8h,0b8h,10h,000h,01001000b,25 ; han
|
|
dw 0,0,0607h
|
|
db 83h,2*2,06h,000h,0b8h,00h,080h,01000100b,25 ; single
|
|
dw 38h,0,0607h
|
|
db 93h,2*2,06h,000h,0b8h,00h,080h,01000100b,25 ; dual
|
|
dw 38h,0,0607h
|
|
db 40h,5*2,06h,000h,0b8h,00h,080h,01100100b,25 ;
|
|
dw 38h,0,2e0fh
|
|
|
|
;------------------------------------------------------------------------
|
|
; << NorModeset >>
|
|
; FUNCTION = video mode setting
|
|
; INPUT : AL, SI
|
|
; OUTPUT : SI
|
|
; PROTECT : DS, ES, SI
|
|
;
|
|
; NorModeset(AL,SI/SI)
|
|
; {
|
|
; if (([Card1st] == CgaCard) || ([Card1st] == MgaCard))
|
|
; {
|
|
; if ([SI+sRealMode] == 3/7)
|
|
; {
|
|
; ModeSetMonoText(SI/-);
|
|
; }
|
|
; else
|
|
; {
|
|
; ModeSetMonoGrp(SI/-);
|
|
; }
|
|
; }
|
|
; else
|
|
; {
|
|
; if ([SI+sRealMode] == 3/7)
|
|
; {
|
|
; ModeSetVgaText(SI/-);
|
|
; }
|
|
; else
|
|
; {
|
|
; ModeSetVgaGrp(SI/-);
|
|
; }
|
|
; }
|
|
; }
|
|
;
|
|
NorModeset:
|
|
mov al,[si+sRealMode]
|
|
mov ah,[CurMode]
|
|
and ah,10000000B
|
|
or al,ah
|
|
xor ah,ah
|
|
mov bh,[si+sMode]
|
|
mov bl,[Card1st]
|
|
and bl,CardType
|
|
cmp bl,CgaCard
|
|
ja NorModesetVga
|
|
cmp bh,3
|
|
jz @f
|
|
cmp bh,7
|
|
jz @f
|
|
jmp ModeSetMonoGrp
|
|
@@:
|
|
jmp ModeSetMonoText
|
|
NorModesetVga:
|
|
cmp bh,3
|
|
jz @f
|
|
cmp bh,7
|
|
jz @f
|
|
jmp ModeSetVgaGrp
|
|
@@:
|
|
jmp ModeSetVgaText
|
|
ModeSetMonoText:
|
|
pushf
|
|
call [OldVideo]
|
|
mov [Port3bf],0
|
|
ret
|
|
ModeSetMonoGrp:
|
|
mov di,word ptr [rVdParm]
|
|
add di,[si+sAdjParms]
|
|
xchg di,word ptr [rVdParm]
|
|
pushf
|
|
call [OldVideo]
|
|
xchg di,word ptr [rVdParm]
|
|
mov bx,[si].sParms
|
|
or bx,bx
|
|
jz @f
|
|
mov dx,3bfh
|
|
mov al,00000011b
|
|
out dx,al
|
|
mov dl,0b8h
|
|
mov al,bl
|
|
out dx,al
|
|
mov [rCrtModeSet],al
|
|
mov dl,0bfh
|
|
mov al,bh
|
|
mov [Port3bf],al
|
|
out dx,al
|
|
@@:
|
|
ret
|
|
|
|
;------------------------------------------------------------------------
|
|
; << SettingVariables >>
|
|
; FUNCTION = initialize variables
|
|
; INPUT : SI
|
|
; OUTPUT : SI
|
|
; PROTECT : DS, ES, SI
|
|
;
|
|
; SettingVariables(SI/SI)
|
|
; {
|
|
; set flages
|
|
; [HjStat] = [HjStat] || [OrgHjStat];
|
|
; if ([CodeStat] == Chab), [HjStat] = [HjStat] && not (UdcLoaded or UdcArea);
|
|
; if ([CodeStat] == WSung7), [HjStat] = [HjStat] && not (UdcLoaded or UdcArea or HjLoaded);
|
|
; [ModeStat] = [SI+sStatus];
|
|
; [DisplayStat] = [DisplayStat] && not RunEsc;
|
|
; [ModeId] = [SI+sModeId];
|
|
; [KbStat] = [KbStat] && not (HEStat or JJStat);
|
|
; [HanStat] = 0;
|
|
; [HjMenuStat] = 0;
|
|
;
|
|
; set internal constant
|
|
; [MaxPage] = 1;
|
|
; if ([ModeStat] == MultiPage), [MaxPage] = 8;
|
|
; [MaxRows] = [SI+sRows];
|
|
; [HjMenuLine] = [SI+sRows] - 1;
|
|
; [CurPos] = 0;
|
|
; [CurPage] = 0;
|
|
; [TextPos1Addr] = 0;
|
|
; [TextPos2Addr] = 0;
|
|
; [GrpPosAddr] = 0;
|
|
;
|
|
; set ROM BIOS data area
|
|
; AL = [CurMode];
|
|
; if(AL != 1000000B)
|
|
; {
|
|
; [rInfo] == [rInfo] || 10000000B;
|
|
; }
|
|
; AL = AL && 01111111b;
|
|
; ES:[rCrtMode] = AL;
|
|
; ES:[rPoints] = 16;
|
|
; ES:[rCrtCols] = 80;
|
|
; ES:[rRows] = [MaxRows] - 1;
|
|
; ES:[rCrtLen] = [SI+CodeSize];
|
|
; if (ES:[rCrtLen] == 0), ES:[rCrtLen] = [SI+GrpSize];
|
|
; ES:[rCurType] = [SI+sCurType];
|
|
;
|
|
; set code buffer address
|
|
; BH = [SI+sCodeVram];
|
|
; BL = 0;
|
|
; AX = 0
|
|
; if (BX == 0)
|
|
; {
|
|
; AX = [CodeBuf2Addr];
|
|
; BX = [CodeBuf2Addr+2];
|
|
; }
|
|
; [CodeBuf1Addr] = AX;
|
|
; [CodeBuf1Addr+2] = BX;
|
|
;
|
|
; Set EQUIP flag
|
|
; if ([Card1st] != DualMnt)
|
|
; {
|
|
; if ([ModeStat] == ColorMode)
|
|
; /* set color equip */
|
|
; else
|
|
; /* set mono equip */
|
|
; }
|
|
; }
|
|
;
|
|
SettingVariables:
|
|
; set flages
|
|
mov ah,[OrgHjStat]
|
|
or [HjStat],ah
|
|
test [CodeStat],WSung7
|
|
jz @f
|
|
and [HjStat],not (UdcLoaded or UdcArea or HjLoaded )
|
|
@@:
|
|
mov ah,[si+sStatus]
|
|
test [KseCard],Page1Fix
|
|
jz @f
|
|
and ah,not MultiPage
|
|
@@:
|
|
mov [ModeStat],ah
|
|
and [DisplayStat],not RunEsc
|
|
mov ah,[si+sModeId]
|
|
mov [ModeId],ah
|
|
if WINNT
|
|
else
|
|
and [KbStat],not (HEStat or JJStat)
|
|
endif
|
|
mov [HanStat],0
|
|
mov [HjMenuStat],0
|
|
; set internal constant
|
|
mov [MaxPage],1
|
|
test [ModeStat],MultiPage
|
|
jz @f
|
|
mov [MaxPage],8
|
|
@@:
|
|
mov ah,[si+sRows]
|
|
mov [MaxRows],ah
|
|
dec ah
|
|
mov [HjMenuLine],ah
|
|
mov [CurPos],0
|
|
mov [CurPage],0
|
|
mov [TextPos1Addr],0
|
|
mov [TextPos2Addr],0
|
|
mov [GrpPosAddr],0
|
|
; set ROM BIOS data area
|
|
mov ah,[CurMode]
|
|
and [rInfo],01111111B
|
|
mov al,ah
|
|
and al,10000000B
|
|
or [rInfo],al
|
|
and ah,01111111b
|
|
mov [rCrtMode],ah
|
|
mov [rPoints],16
|
|
mov [rCrtCols],80
|
|
mov bl,[MaxRows]
|
|
dec bl
|
|
mov [rRows],bl
|
|
mov bh,[si+sCodeSize]
|
|
or bh,bh
|
|
jnz @f
|
|
mov bh,[si+sGrpSize]
|
|
@@:
|
|
xor bl,bl
|
|
mov [rCrtLen],bx
|
|
mov bx,[si+sCurType]
|
|
mov [rCurType],bx
|
|
; set code buffer address
|
|
mov bh,[si+sCodeVram]
|
|
xor bl,bl
|
|
xor ax,ax
|
|
or bx,bx
|
|
jnz @f
|
|
mov ax,word ptr [CodeBuf2Addr]
|
|
mov bx,word ptr [CodeBuf2Addr+2]
|
|
@@:
|
|
mov word ptr [CodeBuf1Addr],ax
|
|
mov word ptr [CodeBuf1Addr+2],bx
|
|
; set grp buffer address
|
|
mov bh,[si+sGrpVram]
|
|
xor bl,bl
|
|
or bx,bx
|
|
jz @f
|
|
mov word ptr [GrpBufAddr],0
|
|
mov word ptr [GrpBufAddr+2],bx
|
|
@@:
|
|
; Set EQUIP flag
|
|
test [Card1st],DualMnt
|
|
jnz @f
|
|
or [rEquip],00110000b
|
|
test [ModeStat],ColorMode
|
|
jz @f
|
|
and [rEquip],11101111b
|
|
@@:
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << InitVideoBuffer >>
|
|
; FUNCTION = initialize video buffer(1st code, 2nd code and grp buffer)
|
|
; INPUT : SI
|
|
; OUTPUT : none
|
|
; PROTECT : DS, ES
|
|
;
|
|
; InitVideoBuffer(SI/-)
|
|
; {
|
|
; if ([CurMode] == 10000000b)
|
|
; {
|
|
; AX = 720h;
|
|
; LES DI,[CodeBuf1Addr];
|
|
; CX = 8000h;
|
|
; if ([SI+sCodeSize] == 0), CX = [CodeBufSize];
|
|
; CX = CX/2;
|
|
; REP STOSW;
|
|
; LES DI,[CodeBuf2Addr];
|
|
; CX = [CodeBufSize]/2;
|
|
; REP STOSW;
|
|
; if ([SI+sGrpSize] != 0)
|
|
; {
|
|
; LES DI,[GrpBufAddr];
|
|
; CH = [SI+sGrpSize];
|
|
; CL = 0;
|
|
; CX = CX/2;
|
|
; AX = 0;
|
|
; REP STOSW;
|
|
; }
|
|
; }
|
|
; }
|
|
;
|
|
InitVideoBuffer:
|
|
test [CurMode],10000000b
|
|
jnz InitVideoBufferEnd
|
|
push es
|
|
mov ax,720h
|
|
les di,[CodeBuf1Addr]
|
|
mov cx,8000h
|
|
cmp [si+sCodeSize],0
|
|
jnz @f
|
|
mov cx,[CodeBufSize]
|
|
@@:
|
|
shr cx,1
|
|
if HotKey
|
|
test [KbStat],ReqEnvrChg
|
|
jz @f
|
|
test [KbMisc],RunningHot
|
|
jz @f
|
|
or di,di
|
|
jnz InitGrpBuffer
|
|
rep stosw
|
|
jmp short InitGrpBuffer
|
|
@@:
|
|
endif ; if HotKey
|
|
rep stosw
|
|
les di,[CodeBuf2Addr]
|
|
mov cx,[CodeBufSize]
|
|
shr cx,1
|
|
rep stosw
|
|
InitGrpBuffer:
|
|
mov ch,[si+sGrpSize]
|
|
or ch,ch
|
|
jz @f
|
|
les di,[GrpBufAddr]
|
|
xor cl,cl
|
|
shr cx,1
|
|
xor ax,ax
|
|
rep stosw
|
|
@@:
|
|
pop es
|
|
InitVideoBufferEnd:
|
|
ret
|
|
|
|
;========================================================================
|
|
; << SetCurType >>
|
|
; FUNCTION = set cursor type
|
|
; INPUT : AH = 01h
|
|
; CH = cursor start, CL = cursor end
|
|
; (CH) 7 6 5 4 3 2 1 0
|
|
; | | | | | | | |
|
|
; | | | +-+-+-+-+--- cursor start
|
|
; | | +------------- 0 : cursor on, 1 : off
|
|
; +-+--------------- not used
|
|
; (CL) 7 6 5 4 3 2 1 0
|
|
; | | | | |
|
|
; +-+-+-+-+--- cursor end
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
; SetCurType(CX/-)
|
|
; {
|
|
; ClearCursor(-/-);
|
|
; switch([ModeId])
|
|
; case 0 : ; 한글 card, TEXT mode 2/3/7
|
|
; call [OldInt10];
|
|
; break;
|
|
; case 2 : ; TE mode 7, MGA
|
|
; case 4 : ; TE mode 2/3, CGA
|
|
; case 6 : ; TE mode 7, EGA/VGA
|
|
; case 8 : ; TE mode 2/3, EGA/VGA
|
|
; case 10 : ; mode 40/70
|
|
; case 12 : ; mode 60/11/12, EGA/VGA
|
|
; ES:[rCurType] = CX;
|
|
; }
|
|
|
|
SetCurType:
|
|
call ClearCursor
|
|
pushf
|
|
call [OldVideo]
|
|
mov [rCurType],cx
|
|
cmp [Modeid],2*0
|
|
jnz SetCurTypeEnd
|
|
test [rInfo],00000001b
|
|
jz SetCurTypeEnd
|
|
test [Card1st],00001100b
|
|
jz SetCurTypeEnd ; jump if not EGA or VGA card
|
|
cmp ch,cl
|
|
ja @f
|
|
mov ax,cx
|
|
and cx,0f0fh
|
|
cmp cl,5
|
|
jb SetCurTypeMonoCL
|
|
inc cl
|
|
cmp cl,10
|
|
jb SetCurTypeMonoCL
|
|
inc cl
|
|
SetCurTypeMonoCL:
|
|
cmp ch,5
|
|
jb SetCurTypeMonoCH
|
|
inc ch
|
|
cmp ch,10
|
|
jb SetCurTypeMonoCH
|
|
inc ch
|
|
SetCurTypeMonoCH:
|
|
mov dh,ah
|
|
and dh,20h
|
|
or ch,dh
|
|
test [ModeStat],ColorMode
|
|
jz @f
|
|
mov cx,ax
|
|
and cx,0707h
|
|
shl cx,1
|
|
mov dh,ah
|
|
and dh,20h
|
|
or ch,dh
|
|
@@:
|
|
mov dx,[rAddr6845]
|
|
mov al,0ah
|
|
mov ah,ch
|
|
out dx,ax
|
|
inc al
|
|
mov ah,cl
|
|
out dx,ax
|
|
SetCurTypeEnd:
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << SetCurPos >>
|
|
; FUNCTION = set cursor position
|
|
; INPUT : AH = 02h
|
|
; BH = page #, DX = cursor position
|
|
; OUTPUT : none
|
|
; PROTECT : AX, BX, CX, DX, ES, DS
|
|
; SetCurPos(BH,DX/-)
|
|
; {
|
|
; if ([MaxPage] == 1), BH = 0;
|
|
; if (BH >= [MaxPage]), BH = [CurPage];
|
|
; if (DL >= 80), return;
|
|
; if (DH >= [MaxRows]), return;
|
|
; save AX, BX;
|
|
; ClearCursor(-/-);
|
|
; if ([ModeId = 0*2)
|
|
; AH = 2;
|
|
; call [OldInt10];
|
|
; ES:[BH*2+rCurPos] = DX;
|
|
; restore AX,BX;
|
|
; }
|
|
|
|
SetCurPosAll:
|
|
cmp [ModeId],0*2
|
|
jne SetCurPos
|
|
jmp VdDummyRet
|
|
SetCurPos:
|
|
cmp [MaxPage],1
|
|
ja @f
|
|
xor bh,bh
|
|
@@:
|
|
cmp bh,[MaxPage]
|
|
jb @f
|
|
mov bh,[CurPage]
|
|
@@:
|
|
@push ax,bx
|
|
call ClearCursor
|
|
cmp [ModeId],0*2
|
|
jne @f
|
|
mov ah,2
|
|
pushf
|
|
call [OldVideo]
|
|
@@:
|
|
xchg bh,bl
|
|
xor bh,bh
|
|
shl bx,1
|
|
mov [bx+rCurPos],dx
|
|
@pop bx,ax
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << GetCurPos >>
|
|
; FUNCTION = get cursor position
|
|
; INPUT : AH = 03h
|
|
; BH = page #
|
|
; OUTPUT : CX = cursor type, DX = cursor position
|
|
; PROTECT : none
|
|
; GetCurPos(BH/CX,DX)
|
|
; {
|
|
; if ([MaxPage] == 1), BH = 0;
|
|
; if (BH >= [MaxPage]), BH = [CurPage];
|
|
; SS:[BP+rCX] = ES:[rCurType];
|
|
; SS:[BP+rDX] = ES:[BH*2 + rCurPos];
|
|
; }
|
|
|
|
GetCurPos:
|
|
cmp [MaxPage],1
|
|
ja @f
|
|
xor bh,bh
|
|
@@:
|
|
cmp bh,[MaxPage]
|
|
jb @f
|
|
|
|
mov bh,[CurPage]
|
|
@@:
|
|
mov ax,[rCurType]
|
|
mov [bp+rCX],ax
|
|
xchg bh,bl
|
|
xor bh,bh
|
|
shl bx,1
|
|
mov ax,[bx+rCurPos]
|
|
mov [bp+rDX],ax
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << SetPage >>
|
|
; FUNCTION = set display page
|
|
; INPUT : AH = 05h
|
|
; AL = page #
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
; SetPage(AL/-)
|
|
; {
|
|
; if (AL >= [MaxPage]), return;
|
|
; if (AL = [CurPage] || [MaxPage] = 1), return;
|
|
; [HanStat] = [HanStat] && not Han1st;
|
|
; ClearCursor(-/-);
|
|
; if ([ModeId] = 0*2)
|
|
; {
|
|
; call [OldInt10];
|
|
; AL = ES:[rCurPage];
|
|
; }
|
|
; ES:[rCurPage] = AL;
|
|
; [CurPage] = AL;
|
|
; ES:[rCrtStart] = AL * ES:[rCrtLen];
|
|
; }
|
|
|
|
SetPage:
|
|
cmp al,[MaxPage]
|
|
jae SetPageExit
|
|
cmp al,[CurPage]
|
|
jz SetPageExit
|
|
cmp [MaxPage],1
|
|
jz SetPageExit
|
|
and [HanStat],not Han1st
|
|
call ClearCursor
|
|
cmp [ModeId],0*2
|
|
jnz @f
|
|
pushf
|
|
call [OldVideo]
|
|
mov al,[rCurPage]
|
|
@@:
|
|
mov [rCurPage],al
|
|
mov [CurPage],al
|
|
xor ah,ah
|
|
mul [rCrtLen]
|
|
mov [rCrtStart],ax
|
|
SetPageExit:
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << ReadCharAttr >>
|
|
; FUNCTION = read character & attribute at current cursor position
|
|
; INPUT : AH = 08h
|
|
; BH = page #
|
|
; OUTPUT : AL = char, AH = attribute(grp mode = don't care)
|
|
; PROTECT : none
|
|
; ReadCharAttr(BH/AL,AH)
|
|
; {
|
|
; if ([MaxPage] == 1), BH = 0;
|
|
; if (BH >= [MaxPage]), BH = [CurPage];
|
|
; DX = [BH*2+rCurPos];
|
|
; SI = DH*80*2+DL*2;
|
|
; AX = [CodeBuf1Addr:[SI + [rCrtLen] * BH]];
|
|
; }
|
|
|
|
ReadCharAttr:
|
|
cmp [MaxPage],1
|
|
ja @f
|
|
xor bh,bh
|
|
@@:
|
|
cmp bh,[MaxPage]
|
|
jb @f
|
|
mov bh,[CurPage]
|
|
@@:
|
|
mov bl,bh
|
|
xor bh,bh
|
|
shl bx,1
|
|
mov dx,[bx+rCurPos]
|
|
mov ax,80
|
|
mul dh
|
|
xor dh,dh
|
|
add ax,dx
|
|
shl ax,1
|
|
mov si,ax
|
|
mov ax,[rCrtLen]
|
|
shr bx,1
|
|
mul bx
|
|
add ax,si
|
|
lds si,[CodeBuf1Addr]
|
|
add si,ax
|
|
lodsw ; AX = Cahracter : Attribute
|
|
@@:
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << GetMode >>
|
|
; FUNCTION = get mode, page and columns
|
|
; INPUT : AH = 0Fh
|
|
; OUTPUT : AL = video mode, AH = columns, BH = current page
|
|
; PROTECT : none
|
|
; GetMode(-/AL,AH,BH)
|
|
; {
|
|
; call [OldInt10];
|
|
; AL = [CurMode] + buffer clear information(0:487 bit7);
|
|
; SS:[BP+rBX] = BX
|
|
; }
|
|
|
|
GetMode:
|
|
pushf
|
|
call [OldVideo]
|
|
mov al,[rCrtMode]
|
|
mov bl,[rInfo]
|
|
and bl,10000000b ; buffer clear information
|
|
or al,bl
|
|
mov cx,ss:[bp+rBX]
|
|
mov bl,cl
|
|
mov ss:[bp+rBX],bx
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << Attribute >>
|
|
; Function = Skip if english ext. video card and video mode 2, 3, 7, 40, 70
|
|
; in EGA/VGA/MCGA card.
|
|
; INPUT : AH = 010h
|
|
; AL = 03h
|
|
; BL = blink/intensity toggle ( 0 : enable intensity, 1 : enable blinking)
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
Attribute:
|
|
test [ModeStat],EmuCursor
|
|
jz GoToVdRom
|
|
test [ModeStat],GrpMode
|
|
jnz GoToVdRom
|
|
cmp ax,1002h
|
|
jz @f
|
|
cmp ax,1003h ; intensity function ?
|
|
jnz GoToVdRom
|
|
@@:
|
|
ret
|
|
JmpVdDummyjj:
|
|
jmp JmpVdDummy
|
|
GoToVdRom:
|
|
if KseVga
|
|
test cs:[KseCard],00000001b
|
|
jz JmpVdDummyjj
|
|
cmp [ModeId],0
|
|
jnz JmpVdDummyjj
|
|
cmp al,1
|
|
jz @f
|
|
cmp al,2
|
|
jnz JmpVdDummyjj
|
|
@@:
|
|
push ax
|
|
push bx
|
|
push dx
|
|
mov ah,4 ; border chip on
|
|
mov dx,03CCh
|
|
in al,dx
|
|
test al,80h ; VS Negative ?
|
|
jnz @f ; No Positive
|
|
or ah,1 ; border_0
|
|
@@: ; border_1
|
|
test al,40h ; HS Negative ?
|
|
jnz @f ; No Positive
|
|
or ah,2
|
|
@@: ; border_2
|
|
mov dx,257h
|
|
in al,dx
|
|
mov al,2 ; index 2 control reg
|
|
out dx,al
|
|
mov al,ah
|
|
out dx,al
|
|
in al,dx
|
|
mov al,0 ; index 0 border position
|
|
out dx,al
|
|
mov al,94h
|
|
out dx,al
|
|
in al,dx
|
|
mov al,1 ; index 0 border width
|
|
out dx,al
|
|
mov al,8
|
|
out dx,al
|
|
in al,dx
|
|
mov al,3 ; index 0 border color sampling position
|
|
out dx,al
|
|
mov al,8
|
|
out dx,al
|
|
pop dx
|
|
pop bx
|
|
pop ax
|
|
endif ;KseVga
|
|
cmp ax,1001h
|
|
jz @f
|
|
cmp ax,1002h
|
|
jz @f
|
|
jmp JmpVdDummy
|
|
@@:
|
|
mov bl,010h
|
|
cmp [CurMode],060h
|
|
jz @f
|
|
cmp [CurMode],040h
|
|
jz @f
|
|
mov bl,00fh
|
|
cmp [CurMode],070h
|
|
jz @f
|
|
jmp JmpVdDummy
|
|
@@:
|
|
mov ES:[rCrtMode],bl
|
|
add sp,2
|
|
@pop bp,ds,es,di,si,dx,cx,bx
|
|
pushf
|
|
call cs:[OldVideo]
|
|
dec cs:[VideoActive]
|
|
@push ax,es
|
|
xor ax,ax
|
|
mov es,ax
|
|
mov al,CS:[CurMode]
|
|
mov ES:[rCrtMode],al
|
|
@pop es,ax
|
|
iret
|
|
JmpVdDummy:
|
|
jmp VdDummyRet ; go to ROM bios
|
|
|
|
|
|
;========================================================================
|
|
; << WriteCharAttr >>
|
|
; FUNCTION = write character & attribute at given page
|
|
; INPUT : AH = 09h
|
|
; AL = char, BL = attr, BH = page, CX = counter
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
;========================================================================
|
|
; << WriteChar >>
|
|
; FUNCTION = write character at given page with current attribute
|
|
; INPUT : AH = 0Ah
|
|
; AL = char, (BL = attr), BH = page, CX = counter
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
; WriteCharAttr(AL,BX,CX/-)
|
|
; WriteChar(AL,BX,CX/-)
|
|
; {
|
|
; CalcCurPosPage(BH/DX,[TextPos1Addr],[TextPos2Addr],[GrpPosAddr]);
|
|
; if ([DisplayStat] == RunEsc), jump EscSequence(AX,BX,CX,DX/-);
|
|
; if (AL = EscKey) && (CX = 1), jump EscSequence(AX,BX,CX,DX/-);
|
|
; if ([MaxPage] == 1), BH = 0;
|
|
; if (BH >= [MaxPage]), BH = [CurPage];
|
|
; WriteCharAll(AL,AH,BL,BH,CX,DX/-);
|
|
; }
|
|
|
|
WriteCharAttr:
|
|
WriteChar:
|
|
cmp [MaxPage],1
|
|
ja @f
|
|
xor bh,bh
|
|
@@:
|
|
cmp bh,[MaxPage]
|
|
jb @f
|
|
mov bh,[CurPage]
|
|
@@:
|
|
call CalcCurPosPage
|
|
test [DisplayStat],RunEsc
|
|
jz @f
|
|
jmp EscSequence
|
|
@@:
|
|
cmp al,EscKey
|
|
jne WriteCharEsc
|
|
cmp cx,1
|
|
jne WriteCharEsc
|
|
jmp EscSequence
|
|
WriteCharEsc:
|
|
call WriteCharAll
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << WriteTty >>
|
|
; FUNCTION = write character with cursor moving
|
|
; INPUT : AH = 0Eh
|
|
; AL = charr, (BL = attr)
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
;========================================================================
|
|
; << WriteTtyInterim >>
|
|
; FUNCTION = write char and cursor move with interim char
|
|
; INPUT : AH = 0FEh
|
|
; AL = char, (BL = attr)
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
;
|
|
; WriteTty(AL,BL/-)
|
|
; WriteTtyInterim(AL,BL/-)
|
|
; {
|
|
; BH = [CurPage];
|
|
; CalcCurPosPage(BH/DX,[TextPos1Addr],[TextPos2Addr],[GrpPosAddr]);
|
|
; switch(AL)
|
|
; case CR :
|
|
; if ([HanStat] == Han1st), DispEnglishOld(-/-);
|
|
; [HanStat] = [HanStat] && not Han1st;
|
|
; DL = 0;
|
|
; SetCurPos(BH,DX/-);
|
|
; break;
|
|
; case LF :
|
|
; if ([HanStat] == Han1st), DispEnglishOld(-/-);
|
|
; [HanStat] = [HanStat] && not Han1st;
|
|
; if (DH = [MaxRows]-1), FullScroll(BH/-);
|
|
; if (DH < [MaxRows]-1), DH = DH+1;
|
|
; SetCurPos(BH,DX/-);
|
|
; break;
|
|
; case BELL :
|
|
; AX = 0e07h;
|
|
; call [OldInt10];
|
|
; break;
|
|
; case BS :
|
|
; if (DL = 0), return;
|
|
; if ([HanStat] == Han1st), DispEnglishOld(-/-);
|
|
; [HanStat] = [HanStat] && not Han1st;
|
|
; DL = DL-1
|
|
; SetCurPos(BH,DX/-);
|
|
; break;
|
|
; default :
|
|
; CX = 1;
|
|
; if (AH == 0eh)
|
|
; {
|
|
; WriteCharAll(AL,AH,BL,BH,CX,DX/-);
|
|
; +DL;
|
|
; if (DL >= 80)
|
|
; {
|
|
; DL = 0;
|
|
; +DH;
|
|
; if (DH >= [MaxRows])
|
|
; FullScroll(BH/-);
|
|
; -DH;
|
|
; }
|
|
; SetCurPos(BH,DX/-);
|
|
; }
|
|
; else
|
|
; {
|
|
; AH = 0eh;
|
|
; [OldHanStat] = [HanStat];
|
|
; WriteCharAll(AL,AH,BL,BH,CX,DX/-);
|
|
; DL = DL+1;
|
|
; if ([HanStat] != Han1st) &&
|
|
; ([OldHanStat] == Han1st)), DL = DL-2;
|
|
; SetCurPos(BH,DX/-);
|
|
; }
|
|
WriteTty:
|
|
WriteTtyInterim:
|
|
mov bh,[CurPage]
|
|
call CalcCurPosPage
|
|
cmp al,CR
|
|
jne WriteTtyLF
|
|
test [HanStat],Han1st
|
|
jz @f
|
|
call DispEnglishOld
|
|
and [HanStat], not Han1st
|
|
@@:
|
|
xor dl,dl
|
|
call SetCurPos
|
|
ret
|
|
|
|
WriteTtyLF:
|
|
cmp al,LF
|
|
jne WriteTtyBELL
|
|
test [HanStat],Han1st
|
|
jz @f
|
|
call DispEnglishOld
|
|
and [HanStat],not Han1st
|
|
@@:
|
|
inc dh
|
|
cmp dh,[MaxRows]
|
|
jne @f
|
|
dec dh
|
|
jmp FullScroll
|
|
@@:
|
|
call SetCurPos
|
|
ret
|
|
|
|
WriteTtyBELL:
|
|
cmp al,BELL
|
|
jne @f
|
|
mov ax,0e07h
|
|
pushf
|
|
call [OldVideo]
|
|
ret
|
|
@@:
|
|
cmp al,BS
|
|
jne WriteTtyDefault
|
|
or dl,dl
|
|
jz WriteTtyTmpExit
|
|
test [HanStat],Han1st
|
|
jz @f
|
|
call DispEnglishOld
|
|
and [HanStat], not Han1st
|
|
@@:
|
|
dec dl
|
|
call SetCurPos
|
|
WriteTtyTmpExit:
|
|
ret
|
|
|
|
WriteTtyDefault:
|
|
mov cx,1
|
|
cmp ah,0Eh
|
|
jnz WriteTtyFE
|
|
call WriteCharAll
|
|
inc dl
|
|
cmp dl,80
|
|
jb @f
|
|
xor dl,dl
|
|
inc dh
|
|
cmp dh,[MaxRows]
|
|
jnz @f
|
|
dec dh
|
|
call FullScroll
|
|
@@:
|
|
call SetCurPos
|
|
ret
|
|
|
|
WriteTtyFE:
|
|
;
|
|
; old Han1st new Han1st
|
|
; 0 0 none
|
|
; 0 1 inc
|
|
; 1 0 dec
|
|
; 1 1 dec
|
|
;
|
|
mov ah,[HanStat]
|
|
mov [OldHanStat],ah
|
|
mov ah,0eh
|
|
call WriteCharAll
|
|
test [OldHanStat],Han1st ; 00, 01, 10, 11
|
|
jz @f
|
|
dec dl ; 10, 11
|
|
jmp short TtySeyCurPos
|
|
@@:
|
|
test [HanStat],Han1st ; 00, 01
|
|
jz TtySeyCurPos
|
|
inc dl ; 01
|
|
TtySeyCurPos:
|
|
call SetCurPos
|
|
WriteStringEnd:
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << WriteString >>
|
|
; FUNCTION = write string
|
|
; INPUT : AH = 13h, AL = function
|
|
; BH = page, BL = attr(AL=0,1), CX = counter, DX = curpos
|
|
; ES:BP = string pointer
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
WriteString:
|
|
cmp al,3
|
|
ja WriteStringEnd
|
|
jcxz WriteStringEnd
|
|
mov si,[bp+rBP]
|
|
mov ds,[bp+rES]
|
|
mov di,bx
|
|
mov bl,bh
|
|
xchg di,bx
|
|
and di,0fh
|
|
shl di,1
|
|
push [di+rCurPos] ; save curpos
|
|
mov di,ax
|
|
mov ah,2
|
|
int 10h
|
|
WriteStrLoop:
|
|
; BL = attr(AL=0,1), BH = page, DX = curpos, DS:SI = string position
|
|
; ES = data segment, DI = function
|
|
lodsb
|
|
test di,00000010b
|
|
jz @f
|
|
xchg al,bl
|
|
lodsb
|
|
xchg al,bl
|
|
@@:
|
|
push cx
|
|
push si
|
|
push ds
|
|
mov cx,cs
|
|
mov ds,cx
|
|
cmp al,cr
|
|
jz WriteStr0E
|
|
cmp al,lf
|
|
jz WriteStr0E
|
|
cmp al,bell
|
|
jz WriteStr0E
|
|
cmp al,bs
|
|
jz WriteStr0E
|
|
test [HanStat],Han1st
|
|
jnz WriteStrEng
|
|
call CheckCodeRange1st
|
|
jc WriteStrEng
|
|
cmp dl,80-1
|
|
jb WriteStrEng
|
|
test [CodeStat],WSung7
|
|
jnz WriteStrEng
|
|
xor dl,dl
|
|
inc dh
|
|
cmp dh,[MaxRows]
|
|
jnz @f
|
|
dec dh
|
|
call FullScroll
|
|
@@:
|
|
call SetCurPos
|
|
WriteStrEng:
|
|
mov cx,1
|
|
mov ah,9
|
|
int 10h
|
|
inc dl
|
|
cmp dl,80
|
|
jb @f
|
|
xor dl,dl
|
|
inc dh
|
|
cmp dh,[MaxRows]
|
|
jnz @f
|
|
dec dh
|
|
call FullScroll
|
|
@@:
|
|
call SetCurPos
|
|
jmp short @f
|
|
WriteStr0E:
|
|
mov ah,0eh
|
|
int 10h
|
|
mov ah,3
|
|
int 10h
|
|
@@:
|
|
pop ds
|
|
pop si
|
|
pop cx
|
|
loop WriteStrLoop
|
|
pop dx ; restore curpos
|
|
test di,00000001b
|
|
jnz @f
|
|
mov ah,2
|
|
int 10h
|
|
@@:
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << WriteCharAll >>
|
|
; FUNCTION = write hangeul/english char
|
|
; INPUT : AH = 9/0ah/0eh function
|
|
; AL = char, (BL = attr), BH = page, CX = counter, DX = cursor pos
|
|
; OUTPUT : none
|
|
; PROTECT : BH, DX, DS, ES
|
|
;
|
|
; WriteCharAll(AL,AH,BL,BH,CX,DX/-)
|
|
; {
|
|
; GetAttr(AH,BL,BH/BL);
|
|
; if (CheckCodeRangeWord(AX/carry)=DBCS(NC) && ([HanStat] == Han1st)
|
|
; && ([OldCurPos] = DX) && ([OldPage] = BH))
|
|
; DispHangeul(AL,BL,BH/-);
|
|
; else
|
|
; {
|
|
; if ([HanStat] == Han1st)
|
|
; DispEnglishOld(-/-);
|
|
; if (CheckCodeRange1st(AL/carry) = DBCS(NC))
|
|
; {
|
|
; if ((DL >= 80-1)
|
|
; {
|
|
; if ([CodeStat] == WSung7)
|
|
; goto DispEnglishNew(AL,BX,CX/-);
|
|
; else
|
|
; {
|
|
; DL = 0;
|
|
; +DH;
|
|
; if (DH >= [MaxRows])
|
|
; {
|
|
; FullScroll(BH/-);
|
|
; -DH;
|
|
; }
|
|
; SetCurPos(BH,DX/-);
|
|
; CalcCurPosPage(BH/DX,[TextPos1Addr],[TextPos2Addr],[GrpPosAddr]);
|
|
; }
|
|
; }
|
|
; /* save AL,BL,BH,CX,DH,DL+1,[TextPos1Addr],[TextPos2Addr],
|
|
; [GrpPosAddr] to old */
|
|
; if ([CodeStat] == WSung7), DispEnglishNew(AL,BX,CX/-);
|
|
; [HanStat] = [HanStat] || Han1st;
|
|
; }
|
|
; else
|
|
; DispEnglishNew(AL,BX,CX/-);
|
|
; }
|
|
; }
|
|
|
|
WriteCharAll:
|
|
call GetAttr
|
|
test [HanStat],Han1st
|
|
jz DispHanEnglish
|
|
cmp [OldCurPos],dx
|
|
jnz @f
|
|
cmp [OldPage],bh
|
|
jnz @f
|
|
push ax
|
|
mov ah,[OldChar]
|
|
call CheckCodeRangeWord
|
|
pop ax
|
|
jc @f
|
|
jmp DispHangeul
|
|
@@:
|
|
call DIspEnglishOld
|
|
and [HanStat],not Han1st
|
|
DispHanEnglish:
|
|
call CheckCodeRange1st
|
|
jc DispEnglish
|
|
call CheckCurPos1st
|
|
jc @f
|
|
jmp DispHangeul
|
|
@@:
|
|
cmp dl,80-1
|
|
jb DispSaveAddr
|
|
cmp ah,0ah
|
|
jbe DispEnglish
|
|
test [CodeStat],WSung7
|
|
jnz DispEnglish
|
|
xor dl,dl
|
|
inc dh
|
|
cmp dh,[MaxRows]
|
|
jnz @f
|
|
dec dh
|
|
call FullScroll
|
|
@@:
|
|
call SetCurPos
|
|
call CalcCurPosPage
|
|
DispSaveAddr:
|
|
mov [OldChar],al
|
|
mov [OldAttr],bl
|
|
mov [OldPage],bh
|
|
mov [OldCounter],cx
|
|
mov [OldCurPos],dx
|
|
inc [OldCurPos]
|
|
mov di,[TextPos1Addr]
|
|
mov [OldTextPos1Addr],di
|
|
mov di,[TextPos2Addr]
|
|
mov [OldTextPos2Addr],di
|
|
mov di,[GrpPosAddr]
|
|
mov [OldGrpPosAddr],di
|
|
test [CodeStat],WSung7
|
|
jz @f
|
|
call DispEnglishNew
|
|
@@:
|
|
or [HanStat],Han1st
|
|
ret
|
|
DispEnglish:
|
|
call DispEnglishNew
|
|
ret
|
|
|
|
CheckCurPos1st:
|
|
test [CodeStat],Chab or WSung7
|
|
jnz CheckCurPos1stR
|
|
test [Card1st],HanCard
|
|
jnz CheckCurPos1stR
|
|
cmp dl,0
|
|
jz CheckCurPos1stR
|
|
@push ds,si,ax,bx,cx,dx
|
|
mov cl,dl
|
|
sub cl,1
|
|
std
|
|
lds si,[CodeBuf1Addr]
|
|
add si,cs:[TextPos1Addr]
|
|
lodsw
|
|
xor ch,ch
|
|
xor bl,bl
|
|
lodsw
|
|
mov dx,ax
|
|
call CheckHanType
|
|
and al,00000011b
|
|
cld
|
|
cmp al,00000001b
|
|
jnz @f
|
|
mov [OldChar],dl
|
|
mov [OldAttr],dh
|
|
mov cx,01
|
|
mov [OldCounter],cx
|
|
@pop dx,cx,bx,ax
|
|
mov [OldPage],bh
|
|
mov [OldCurPos],dx
|
|
mov si,[TextPos1Addr]
|
|
sub si,2
|
|
mov [OldTextPos1Addr],di
|
|
mov si,[TextPos2Addr]
|
|
sub si,2
|
|
mov [OldTextPos2Addr],di
|
|
mov si,[GrpPosAddr]
|
|
sub si,2
|
|
mov [OldGrpPosAddr],di
|
|
@pop si,ds
|
|
clc
|
|
ret
|
|
@@:
|
|
@pop dx,cx,bx,ax,si,ds
|
|
CheckCurPos1stR:
|
|
stc
|
|
ret
|
|
|
|
;------------------------------------------------------------------------
|
|
; << EscSequence >>
|
|
; FUNCTION = write english char
|
|
; INPUT : AL = char, BL = attr, BH = page, CX = counter, DX = cursor pos
|
|
; OUTPUT : none
|
|
; PROTECT : AX, BX, CX, DX, DS, ES
|
|
;
|
|
; EscSequence(AX,BX,CX,DX/-)
|
|
; {
|
|
; if ([DisplayStat] == RunEsc)
|
|
; {
|
|
; switch([EscIndex])
|
|
; case 0:
|
|
; if (AL == '$'), EscIndex=1*2, break;
|
|
; if (AL == '('), EscIndex=3*2, break;
|
|
; DispEnglishOld(-/-);
|
|
; [EscIndex] = 0;
|
|
; [DisplayStat] = [DisplayStat] && not RunEsc;
|
|
; jmp WriteCharEsc;
|
|
; case 2:
|
|
; if (AL == ')'), [EscIndex] = 2*2, break;
|
|
; [EscIndex] = 0;
|
|
; [DisplayStat] = [DisplayStat] && not RunEsc;
|
|
; jmp WriteCharEsc;
|
|
; case 4:
|
|
; if (AL == '1'), /* set hangeul key in mode */
|
|
; [EscIndex] = 0;
|
|
; [DisplayStat] = [DisplayStat] && not RunEsc;
|
|
; jmp WriteCharEsc;
|
|
; case 6:
|
|
; if (AL == '2'), /* reset hangeul key in mode */
|
|
; [EscIndex] = 0;
|
|
; [DisplayStat] = [DisplayStat] && not RunEsc;
|
|
; jmp WriteCharEsc;
|
|
; }
|
|
; else
|
|
; /* save AL,BL,BH,CX,DX
|
|
; [TextPos1Addr],[TextPos2Addr],[GrpPosAddr] to old */
|
|
; [DisplayStat] = [DisplayStat] || RunEsc;
|
|
; [EscIndex] = 0;
|
|
; }
|
|
|
|
EscSequence:
|
|
test [DisplayStat],RunEsc
|
|
jz RunEscStart
|
|
mov si,[EscIndex]
|
|
jmp [si+EscSeqJmpTbl]
|
|
|
|
EscSeqJmpTbl Label Word
|
|
dw offset EscIndexDollar
|
|
dw offset EscIndexLeftBr
|
|
dw offset EscIndex1
|
|
dw offset EscIndex2
|
|
|
|
RunEscStart:
|
|
mov [OldChar],al
|
|
mov [OldAttr],bl
|
|
mov [OldPage],bh
|
|
mov [OldCounter],cx
|
|
mov [OldCurPos],dx
|
|
mov di,[TextPos1Addr]
|
|
mov [OldTextPos1Addr],di
|
|
mov di,[TextPos2Addr]
|
|
mov [OldTextPos2Addr],di
|
|
mov di,[GrpPosAddr]
|
|
mov [OldGrpPosAddr],di
|
|
or [DisplayStat],RunEsc
|
|
mov [EscIndex],0
|
|
ret
|
|
EscIndexDollar:
|
|
cmp al,'$'
|
|
jne @f
|
|
mov [EscIndex],1*2
|
|
ret
|
|
@@:
|
|
cmp al,'('
|
|
jne @f
|
|
mov [EscIndex],3*2
|
|
ret
|
|
@@:
|
|
call DispEnglishOld
|
|
EscBreak:
|
|
mov [EscIndex],0
|
|
and [DisplayStat],not RunEsc
|
|
jmp WriteCharEsc
|
|
EscIndexLeftBr:
|
|
cmp al,')'
|
|
jne EscBreak
|
|
mov [EscIndex],2*2
|
|
ret
|
|
EscIndex1:
|
|
cmp al,'1'
|
|
jne EscBreak
|
|
or [KbStat],HEStat ; Hangeul On
|
|
mov [EscIndex],0
|
|
and [DisplayStat],not RunEsc
|
|
ret
|
|
EscIndex2:
|
|
cmp al,'2'
|
|
jne EscBreak
|
|
and [KbStat],not HEStat ; Hangeul Off
|
|
mov [EscIndex],0
|
|
and [DisplayStat],not RunEsc
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << CalcCurPosPage >>
|
|
; FUNCTION = calculation cursor position
|
|
; INPUT : BH
|
|
; OUTPUT : DX
|
|
; : [TextPos1Addr],[TextPos2Addr],[GrpPosAddr]
|
|
; PROTECT : AX,BX,CX
|
|
;
|
|
; CalcCurPosPage(BH/DX,[TextPos1Addr],[TextPos2Addr],[GrpPosAddr])
|
|
; {
|
|
; save AX,BX,CX;
|
|
; CX = ES:[BH*2+rCurPos];
|
|
; [TextPos1Addr] = CH*80*2+CL*2+ES:[rCrtLen]*BH;
|
|
; [TextPos2Addr] = CH*80*2+CL*2;
|
|
; if ([ModeId] == HgcGrpMode(ModeId=2/4/10)
|
|
; {
|
|
; [GrpPosAddr] = CH*80*4+CL;
|
|
; }
|
|
; [GrpPosAddr] = CH*80*16+CL;
|
|
; [CurPos] = CX;
|
|
; DX = CX;
|
|
; restore AX,BX,CX;
|
|
; }
|
|
|
|
CalcCurPosPage:
|
|
@push ax,bx,cx
|
|
mov bl,bh
|
|
xor bh,bh
|
|
shl bx,1
|
|
mov cx,[bx+rCurPos]
|
|
mov [CurPos],cx
|
|
mov al,80
|
|
mul ch
|
|
mov dx,cx ; GrpPosAddr을 계산하기위해 저장
|
|
xor dh,dh
|
|
add ax,dx
|
|
shl ax,1
|
|
mov [TextPos1Addr],ax
|
|
mov [TextPos2Addr],ax
|
|
mov ax,[rCrtLen]
|
|
shr bx,1
|
|
mul bx
|
|
add [TextPos1Addr],ax
|
|
mov ax,80*4
|
|
cmp [ModeId],4
|
|
jbe @f
|
|
cmp [ModeId],5*2
|
|
jz @f
|
|
mov ax,80*16
|
|
@@:
|
|
mov dl,ch
|
|
xor dh,dh
|
|
mul dx
|
|
xor ch,ch
|
|
add ax,cx
|
|
mov [GrpPosAddr],ax
|
|
mov dx,[CurPos]
|
|
@pop cx,bx,ax
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << GetAttr >>
|
|
; FUNCTION = get attribute
|
|
; INPUT : AH = 9/0ah/0eh function
|
|
; BH = page#
|
|
; BL = attribute
|
|
; OUTPUT : BL = attribute
|
|
; PROTECT : AX,BH,CX,DX,DS,ES,SI
|
|
; {
|
|
; if (([ModeStat] != GrpMode) || (AH != 9))
|
|
; {
|
|
; save DS,SI;
|
|
; BL = CodeBuf1Addr:[[CodeBuf1Addr]+[TextPos1Addr]+1];
|
|
; restore DS,SI;
|
|
; }
|
|
; }
|
|
; GetAttr(AH,BL,BH/BL)
|
|
|
|
GetAttr:
|
|
test [ModeStat],GrpMode
|
|
jnz @f
|
|
cmp ah,09h
|
|
jz @f
|
|
@push di,es
|
|
les di,[CodeBuf1Addr]
|
|
add di,[TextPos1Addr]
|
|
mov bl,es:[di+1]
|
|
@pop es,di
|
|
@@:
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << WritePixel >>
|
|
; FUNCTION = write graphics pixel
|
|
; INPUT : AH = 0Ch
|
|
; AL = color, BH = page, CX = graphics columns, DX = graphics rows
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
; WritePixel(AL,BH,CX,DX/-)
|
|
; {
|
|
; switch([ModeId])
|
|
; case 0 : ; 한글 card, TEXT mode 2/3/7
|
|
; case 2 : ; TE mode 7, MGA
|
|
; case 4 : ; TE mode 2/3, CGA
|
|
; case 6 : ; TE mode 7, EGA/VGA
|
|
; case 8 : ; TE mode 2/3, EGA/VGA
|
|
; break;
|
|
; case 10 : ; mode 40/70
|
|
; MgaWritePixel(AL,CX,DX/-);
|
|
; break;
|
|
; case 12 : ; mode 60/11/12, EGA/VGA
|
|
; VgaWritePixel(AL,CX,DX/-);
|
|
; break;
|
|
; }
|
|
|
|
WritePixel:
|
|
les di,[GrpBufAddr]
|
|
xchg si,bx
|
|
mov bl,[ModeId]
|
|
xor bh,bh
|
|
xchg si,bx
|
|
jmp [si+WritePixelJmpTbl]
|
|
|
|
WritePixelJmpTbl Label Word
|
|
dw offset WrtPxlHanCardText
|
|
dw offset WrtPxlMgaTE
|
|
dw offset WrtPxlCgaTE
|
|
dw offset WrtPxlEgaVgaTE7
|
|
dw offset WrtPxlEgaVgaTE2_3
|
|
dw offset MgaWritePixel
|
|
dw offset VgaWritePixel
|
|
|
|
WrtPxlHanCardText:
|
|
WrtPxlMgaTE:
|
|
WrtPxlCgaTE:
|
|
WrtPxlEgaVgaTE7:
|
|
WrtPxlEgaVgaTE2_3:
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << ReadPixel >>
|
|
; FUNCTION = write graphics pixel
|
|
; INPUT : BH = page, CX = graphics columns, DX = graphics rows
|
|
; OUTPUT : AL = color
|
|
; PROTECT : none
|
|
; ReadPixel(BH,CX,DX/)
|
|
; {
|
|
; switch([ModeId])
|
|
; case 0 : ; 한글 card, TEXT mode 2/3/7
|
|
; case 2 : ; TE mode 7, MGA
|
|
; case 4 : ; TE mode 2/3, CGA
|
|
; case 6 : ; TE mode 7, EGA/VGA
|
|
; case 8 : ; TE mode 2/3, EGA/VGA
|
|
; break;
|
|
; case 10 : ; mode 40/70
|
|
; MgaReadPixel(BH,CX,DX/AL);
|
|
; break;
|
|
; case 12 : ; mode 60/11/12, EGA/VGA
|
|
; VgaReadPixel(BH,CX,DX/AL);
|
|
; break;
|
|
; }
|
|
|
|
ReadPixel:
|
|
les di,[GrpBufAddr]
|
|
xchg si,bx
|
|
mov bl,[ModeId]
|
|
xor bh,bh
|
|
xchg si,bx
|
|
jmp [si+ReadPixelJmpTbl]
|
|
|
|
ReadPixelJmpTbl Label Word
|
|
dw offset RdPxlHanCardText
|
|
dw offset RdPxlMgaTE
|
|
dw offset RdPxlCgaTE
|
|
dw offset RdPxlEgaVgaTE7
|
|
dw offset RdPxlEgaVgaTE2_3
|
|
dw offset MgaReadPixel
|
|
dw offset VgaReadPixel
|
|
|
|
RdPxlHanCardText:
|
|
RdPxlMgaTE:
|
|
RdPxlCgaTE:
|
|
RdPxlEgaVgaTE7:
|
|
RdPxlEgaVgaTE2_3:
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << ScrollUp >>
|
|
; FUNCTION = window scroll up
|
|
; INPUT : AH = 06h
|
|
; AL = scroll line #, CX = window start, DX = window end
|
|
; BH = attribute to be used on blank lines
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
;========================================================================
|
|
; << ScrollDown >>
|
|
; FUNCTION = window scroll down
|
|
; INPUT : AH = 07h
|
|
; AL = scroll line #, CX = window start, DX = window end
|
|
; BH = attribute to be used on blank lines
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
; ScrollUp(AL,BH,CX,DX/-)
|
|
; ScrollDown(AL,BH,CX,DX/-)
|
|
; {
|
|
; if (CL > DL), xchg CL,DL;
|
|
; if (CH > DH), xchg CH,DH;
|
|
; if (DL >= 80), return;
|
|
; if (DH >= [MaxRows]), return;
|
|
; if (AL > (DL-CL)), AL=(DL-CL); /* scroll line counter */
|
|
; if ([ModeStat] == GrpMode)
|
|
; {
|
|
; if (BH = 0), BH = 7;
|
|
; if (BH = -1), BH = 70h;
|
|
; }
|
|
; [HanStat] = [HanStat] && not Han1st;
|
|
; TextEmu(-/-);
|
|
; ClearCursor(-/-);
|
|
; save CX;
|
|
; CalcScrollParms(AL,CX,DX/...);
|
|
; TextBufferScroll(1st code buffer's segment:offset/-);
|
|
; if ([ModeStat] == TextEmulation), TextBufferScroll(2nd code buffer's segment:offset/-);
|
|
; restore CX;
|
|
; switch([ModeId])
|
|
; case 0 : ; 한글 card, TEXT mode 2/3/7
|
|
; break;
|
|
; case 2 : ; TE mode 7, MGA
|
|
; case 4 : ; TE mode 2/3, CGA
|
|
; case 10 : ; mode 40/70
|
|
; MgaGrpScroll(.../-);
|
|
; break;
|
|
; case 6 : ; TE mode 7, EGA/VGA
|
|
; case 8 : ; TE mode 2/3, EGA/VGA
|
|
; case 12 : ; mode 60/11/12, EGA/VGA
|
|
; VgaGrpScroll(.../-);
|
|
; break;
|
|
; }
|
|
|
|
ScrollUp:
|
|
ScrollDown:
|
|
and [DisplayStat],not Han1st
|
|
and [DisplayStat],not RunEsc ; reset ESC sequence
|
|
call ClearCursor
|
|
mov cs:[ScrUpDnFlag],1
|
|
cmp ah,6
|
|
jz @f
|
|
mov cs:[ScrUpDnFlag],2
|
|
@@:
|
|
cmp cl,dl
|
|
jb @f
|
|
xchg cl,dl
|
|
@@:
|
|
cmp ch,dh
|
|
jb @f
|
|
xchg ch,dh
|
|
@@:
|
|
cmp dl,80
|
|
jb @f
|
|
mov dl,80-1
|
|
@@:
|
|
cmp dh,[MaxRows]
|
|
jb @f
|
|
mov dh,[MaxRows]
|
|
dec dh
|
|
@@:
|
|
mov bl,dh
|
|
sub bl,ch
|
|
inc bl
|
|
cmp bl,al
|
|
jae @f
|
|
mov al,bl
|
|
@@:
|
|
or al,al
|
|
jnz @f
|
|
mov al,bl
|
|
@@:
|
|
cmp [ModeId],5*2 ; 5 - mode 40/70
|
|
jnz NotBlank
|
|
or bh,bh
|
|
jne @f
|
|
mov bh,7 ; 0 -> 7
|
|
jmp NotBlank
|
|
@@:
|
|
cmp bh,-1
|
|
jne NotBlank
|
|
mov bh,70h ; FF -> 70h
|
|
NotBlank:
|
|
call TextEmu
|
|
call CalcScrollParms
|
|
push bx
|
|
mov bx,[rCrtStart]
|
|
les ax,[CodeBuf1Addr]
|
|
add ax,bx
|
|
pop bx
|
|
call TextBufferScroll ; 1st code buffer
|
|
test [ModeStat],TextEmulation
|
|
jz @f
|
|
les ax,[CodeBuf2Addr]
|
|
call TextBufferScroll ; 2nd code buffer
|
|
@@:
|
|
mov al,[ModeId]
|
|
xor ah,ah
|
|
mov si,ax
|
|
call [si+ScrollUpDownJmpTbl]
|
|
ScrollUpDownExit:
|
|
ScrUpDownHanCardText:
|
|
ret
|
|
|
|
ScrollUpDownJmpTbl Label Word
|
|
dw offset ScrUpDownHanCardText
|
|
dw offset MgaGrpScroll
|
|
dw offset MgaGrpScroll
|
|
dw offset VgaGrpScroll
|
|
dw offset VgaGrpScroll
|
|
dw offset MgaGrpScroll
|
|
dw offset VgaGrpScroll
|
|
|
|
|
|
;========================================================================
|
|
; << CodeChange >>
|
|
; FUNCTION = 코드변환기능
|
|
; INPUT : AH = 0F5h
|
|
; input : AL = 00h ; 입력된 완성형코드를 조합형코드로 변환
|
|
; BX = 완성형코드
|
|
; output: AL = 00H=success ,BX = 변환된 조합형코드
|
|
; AL = FFH=fail
|
|
; input : AL = 01h ; 입력된 조합형코드를 완성형코드로 변환
|
|
; BX = 조합형코드
|
|
; output: AL = 00H=success ,BX = 변환된 완성형코드
|
|
; AL = FEH 완성형에 포함되지 않은 한글 음절임
|
|
; BX = 입력된 문자의 초성에 해당하는 한글낱자코드
|
|
; CX = 입력된 문자의 중성에 해당하는 한글낱자코드
|
|
; DX = 입력된 문자의 종성에 해당하는 한글낱자코드
|
|
; AL = FFH=fail(입력값이 정당하지 않음.)
|
|
; input : AL = 02h ; 완성형 음절자료를 조합형코드로 변환
|
|
; BX = 초성에 해당하는 한글낱자코드
|
|
; CX = 중성에 해당하는 한글낱자코드
|
|
; DX = 종성에 해당하는 한글낱자코드
|
|
; output: AL = 00H success ,BX = 변환된 조합형코드
|
|
; AL = FFH fail
|
|
; PROTECT : none
|
|
fFillCode = 84h
|
|
vFillCode = 40h
|
|
lFillCode = 01h
|
|
|
|
CodeChange:
|
|
cmp al,02h
|
|
ja CodeChgErr
|
|
xor ah,ah
|
|
mov si,ax
|
|
shl si,1
|
|
mov ax,bx
|
|
jmp [si+CodeChangeTbl]
|
|
|
|
CodeChangeTbl Label word
|
|
dw offset Ks2ChCall
|
|
dw offset Ch2KsCall
|
|
dw offset KsComp2ChCall
|
|
|
|
Ks2ChCall:
|
|
call ChgKs2Ch
|
|
jc CodeChgErr
|
|
jmp CodeChgSuc
|
|
|
|
Ch2KsCall:
|
|
call CheckCodeRangeCh
|
|
jc CodeChgErr
|
|
call ChgCh2Ks
|
|
jnc CodeChgSuc
|
|
jmp SplitCompKS
|
|
|
|
KsComp2ChCall:
|
|
call CheckCodeRangeWs
|
|
jc CodeChgErr
|
|
call Ks2Ch
|
|
jc CodeChgErr
|
|
xchg ax,cx
|
|
call Ks2Ch
|
|
jc CodeChgErr
|
|
xchg ax,dx
|
|
mov bl,lFillCode
|
|
cmp ax,0a4d4h
|
|
jz @f
|
|
cmp ax,0a4a1h
|
|
jb CodeChgErr
|
|
cmp ax,0a4beh
|
|
ja CodeChgErr
|
|
call Ks2Chcompn
|
|
jc CodeChgErr
|
|
|
|
@@:
|
|
and ch,11111100b
|
|
and dh,10000011b
|
|
and dl,11100000b
|
|
and bl,00011111b
|
|
xor bh,bh
|
|
or bx,dx
|
|
or bh,ch
|
|
mov ax,bx
|
|
CodeChgSuc:
|
|
mov [bp+rBX],ax
|
|
xor al,al
|
|
ret
|
|
CodeChgErr:
|
|
mov al,0ffh
|
|
ret
|
|
|
|
;------------------
|
|
SplitCompKS:
|
|
mov ax,bx
|
|
mov dx,ax
|
|
and ah,10000011b ;중성
|
|
and al,11100000b
|
|
or ah,fFillCode
|
|
or al,lFillCode
|
|
call Ch2Ks
|
|
jc CodeChgErr
|
|
mov cx,ax
|
|
mov ax,dx ;초성
|
|
and ah,11111100b
|
|
mov al,0
|
|
or al,(vFillCode or lFillCode)
|
|
call Ch2Ks
|
|
jc CodeChgErr
|
|
xchg dx,ax
|
|
mov bx,0a4d4h
|
|
mov ah,0
|
|
and al,00011111b
|
|
cmp al,lFillCode
|
|
jz @f
|
|
or ah,fFillCode
|
|
or al,vFillCode
|
|
call Ch2Ks
|
|
mov bx,ax
|
|
@@:
|
|
mov [bp+rBX],dx
|
|
mov [bp+rCX],cx
|
|
mov [bp+rDX],bx
|
|
mov al,0feh
|
|
ret
|
|
|
|
Ks2Chcompn:
|
|
mov bl,al
|
|
sub bl,05fh
|
|
cmp al,0a8h
|
|
je ChcompErr
|
|
jb @f
|
|
sub bl,1
|
|
cmp al,0b2h
|
|
jb @f
|
|
add bl,1
|
|
cmp al,0b3h
|
|
je ChcompErr
|
|
jb @f
|
|
sub bl,1
|
|
cmp al,0b9h
|
|
je ChcompErr
|
|
jb @f
|
|
sub bl,1
|
|
@@:
|
|
clc
|
|
ret
|
|
ChcompErr:
|
|
stc
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << ControlCode >>
|
|
; FUNCTION = 복수부호계 사용관련기능
|
|
; INPUT : AH = 0F4h
|
|
; input : AL = 00h
|
|
; output: AL = 00H = 시스템의 사용코드 체계가 완성형
|
|
; AL = 01H = 시스템의 사용코드 체계가 완성형및 조합형
|
|
; BL = 00H : 완성형부호계
|
|
; BL = 01H : 조합형부호계
|
|
; AL = 02H = 시스템의 사용코드 체계가 조합형
|
|
; PROTECT : none
|
|
ControlCode:
|
|
cmp al,00h
|
|
jne ControlCodeRet
|
|
test [CodeStat],ChabLoad
|
|
jz ControlCodeRet
|
|
mov bx,[bp+rBX]
|
|
mov al,1
|
|
xor bl,bl
|
|
test [CodeStat],WSung7 or Chab
|
|
jz @f
|
|
mov bl,01h
|
|
test [CodeStat],Chab
|
|
jnz @f
|
|
mov bl,02h
|
|
@@:
|
|
mov [bp+rBX],bx
|
|
ControlCodeRet:
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << BlockMove >>
|
|
; FUNCTION = block move
|
|
; INPUT : AH = 0F6h
|
|
; AL = attr, BX = target position, CX:DX = windows
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
;========================================================================
|
|
; << BlockCopy >>
|
|
; FUNCTION = block copy
|
|
; INPUT : AH = 0F7h
|
|
; AL = attr, BX = target position, CX:DX = windows
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
; BlockMove(AL,BX,CX,DX/-)
|
|
; BlockCopy(BX,CX,DX/-)
|
|
; {
|
|
; [DispStat] = [DispStat] && not Han1st
|
|
; [DispStat] = [DispStat] && not RunEsc
|
|
; if ( [ModeStat] = GrpMode ), return;
|
|
; ClearCursor(-/-);
|
|
; if (DH >= [MaxRows]), return; /* range over */
|
|
; if (DL >= 80), return; /* range over */
|
|
; if ((DL-CL+BL) >= 80), return; /* range over */
|
|
; if ((DH-CH+BH) >= [MaxRows]), return; /* range over */
|
|
; if (CL > DL), return;
|
|
; if (CH > DH), return;
|
|
; if (BX = CX), return;
|
|
; ParseBlock(-/-);
|
|
; Save CX,BX;
|
|
; CalcTextBlock(-/-);
|
|
; DS:SI = [CodeBuf1Addr + rCrtStart]
|
|
; BlockText(1st code buffer's segment:offset/-);
|
|
; if ([ModeStat] == TextEmulation), BlockText(2nd code buffer's segment:offset/-);
|
|
; switch([ModeId])
|
|
; case 0 : ; 한글 card, TEXT mode 2/3/7
|
|
; break;
|
|
; case 2 : ; TE mode 7, MGA
|
|
; case 4 : ; TE mode 2/3, CGA
|
|
; MgaGrpBlock(BX/-);
|
|
; break;
|
|
; case 6 : ; TE mode 7, EGA/VGA
|
|
; case 8 : ; TE mode 2/3, EGA/VGA
|
|
; VgaGrpBlock(BX/-);
|
|
; case 10 : ; mode 40/70
|
|
; case 12 : ; mode 60/11/12, EGA/VGA
|
|
; }
|
|
|
|
BlockMove:
|
|
BlockCopy:
|
|
and [DisplayStat],not Han1st
|
|
and [DisplayStat],not RunEsc ; reset ESC sequence
|
|
test [ModeStat],GrpMode
|
|
jnz BlockEnd
|
|
call ClearCursor
|
|
cmp dh,25
|
|
jae BlockEnd
|
|
cmp dl,80
|
|
jae BlockEnd
|
|
mov bp,ax
|
|
mov si,dx
|
|
sub dx,cx
|
|
mov ax,dx
|
|
add dx,bx
|
|
cmp dh,25
|
|
jae BlockEnd
|
|
cmp dl,80
|
|
jae BlockEnd
|
|
mov dx,si
|
|
cmp dl,cl
|
|
jc BlockEnd
|
|
cmp dh,ch
|
|
jc BlockEnd
|
|
cmp bx,cx
|
|
jz BlockEnd
|
|
call ParseBlock
|
|
push cx
|
|
push bx
|
|
call CalcTextBlock
|
|
lds ax,[CodeBuf1Addr]
|
|
add ax,es:[rCrtStart]
|
|
call BlockText
|
|
test [ModeStat],TextEmulation
|
|
jz @f
|
|
lds ax,[CodeBuf2Addr]
|
|
call BlockText
|
|
@@:
|
|
push bx
|
|
mov bl,cs:[ModeId]
|
|
xor bh,bh
|
|
jmp [bx+BlockMoveCopyJmpTbl]
|
|
|
|
BlkMvCpHanCardText:
|
|
BlkMvCpMode40_70:
|
|
BlkMvCpMode60_11_12:
|
|
@pop bx,bx,cx
|
|
BlockEnd:
|
|
ret
|
|
|
|
BlockMoveCopyJmpTbl Label Word
|
|
dw offset BlkMvCpHanCardText
|
|
dw offset MgaGrpBlock
|
|
dw offset MgaGrpBlock
|
|
dw offset VgaGrpBlock
|
|
dw offset VgaGrpBlock
|
|
dw offset BlkMvCpMode40_70
|
|
dw offset BlkMvCpMode60_11_12
|
|
|
|
;================================================
|
|
ParseBlock:
|
|
mov [BlockAdj],0
|
|
cmp bh,ch
|
|
jb Block12
|
|
Block34:
|
|
and bp,0bfffh
|
|
cmp bl,cl
|
|
jb Block3
|
|
Block4:
|
|
add bx,ax
|
|
xchg cx,dx
|
|
and bp,7fffh ; set STD
|
|
std
|
|
jmp short @f
|
|
Block3:
|
|
mov [BlockAdj],-(80*4)
|
|
xchg ch,dh
|
|
add bh,ah
|
|
jmp short @f
|
|
Block12:
|
|
cmp bl,cl
|
|
jb @f
|
|
Block2:
|
|
mov [BlockAdj],80*4
|
|
add bl,al
|
|
xchg cl,dl
|
|
and bp,7fffh ; set STD
|
|
std
|
|
@@:
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << GetCharType >>
|
|
; FUNCTION = get char type at current cursor position
|
|
; INPUT : AH = 0F8h
|
|
; OUTPUT : AL = char type
|
|
; PROTECT : none
|
|
; (AL) bit 76543210
|
|
; ||
|
|
; |+---> # of bytes of char
|
|
; | 0: 1 byte character
|
|
; | 1: 2 byte character
|
|
; +----> ordinal # of 2 byte char
|
|
; 0: 1st byte of 2 byte character
|
|
; 1: 2nd byte of 2 byte character
|
|
; GetCharType(-/AL)
|
|
; {
|
|
; if ([CodeStat] != (Chab || WSung7))
|
|
; {
|
|
; BH = ES:[rCurPage];
|
|
; CalcCurPosPage(BH/DX,[TextPos1Addr],[TextPos2Addr],[GrpPosAddr]);
|
|
; CL = DL;
|
|
; CH = 0;
|
|
; BL = 0;
|
|
; STD;
|
|
; DS : SI = [CodeBuf1Addr];
|
|
; while ( CX == 0, CX-)
|
|
; {
|
|
; LODSW;
|
|
; if (CheckCodeRange1st(AL/carry) == DBCS(NC))
|
|
; {
|
|
; BL = BL || 1;
|
|
; XOR BL,2;
|
|
; }
|
|
; }
|
|
; AL = BL;
|
|
; }
|
|
; }
|
|
|
|
GetCharType:
|
|
mov bl,al
|
|
test [CodeStat],Chab or WSung7
|
|
jnz GetCharTypeEnd
|
|
mov bh,[rCurPage]
|
|
call CalcCurPosPage
|
|
std
|
|
lds si,[CodeBuf1Addr]
|
|
add si,cs:[TextPos1Addr]
|
|
mov cl,dl
|
|
xor ch,ch
|
|
xor bl,bl
|
|
lodsw
|
|
CheckHanType:
|
|
call CheckCodeRange1st
|
|
mov al,0
|
|
jc GetCharTypeEnd
|
|
or bl,00000001b
|
|
@@:
|
|
lodsw
|
|
call CheckCodeRange1st
|
|
jc @f
|
|
xor bl,00000010b
|
|
loop @b
|
|
@@:
|
|
mov al,bl
|
|
GetCharTypeEnd:
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << FontCtrl >>
|
|
; FUNCTION = see sub function
|
|
; INPUT : AH = 0FCh
|
|
; AL = sub function
|
|
; OUTPUT : see sub function
|
|
; PROTECT : none
|
|
; input (ah)=FCH read/write font from/to char pattern
|
|
; (문자자형 또는 문자상자의 크기 읽기)
|
|
; (cx) char to read/write font(ch=0 if 1 byte char on read)
|
|
; input (al)=0 read font for given code
|
|
; (es:bx) pointer of character pattern buffer
|
|
; output (al)=0 successfully operation
|
|
; (es:bx) pointer of character pattern buffer
|
|
; (al)=ff error, corresponding pattern can't be read
|
|
; input (al)=1 read size of char box
|
|
; output (ah,al) (horizontal size, vertical size)
|
|
; input (al)=2 write font for given 2 byte code (UDC only)
|
|
; (es:bx) pointer of character pattern buffer
|
|
; output (al)=0 successfully operation
|
|
; (al)=ff error, corresponding pattern can't be written
|
|
; FontCtrl(AL/AL)
|
|
; {
|
|
; switch(AL)
|
|
; case 0 :
|
|
; ES = SS:[BP+rES];
|
|
; DI = SS:[BP+rBX];
|
|
; if CH = 0
|
|
; {
|
|
; if (GetPatternEng(CL,ES,DI/carry)=error(CY)), AL = -1;
|
|
; else AL = 0;
|
|
; }
|
|
; else
|
|
; {
|
|
; if (GetPattern(CX,ES,DI/carry)=error(CY)), AL = -1;
|
|
; else AL = 0;
|
|
; }
|
|
; break;
|
|
; case 1 :
|
|
; AL = 16;
|
|
; AH = 16;
|
|
; break;
|
|
; case 2 :
|
|
; DS = SS:[BP+rES];
|
|
; SI = SS:[BP+rBX];
|
|
; if (PutPattern(CX,DS,SI/carry)=error(CY)), AL = -1;
|
|
; else AL = 0;
|
|
; break;
|
|
; default : AL = -1;
|
|
; }
|
|
|
|
FontCtrl:
|
|
cmp al,1
|
|
jae FontCtrlSub1
|
|
mov es,[bp+rES]
|
|
mov di,[bp+rBX]
|
|
or ch,ch
|
|
jnz NotEng16
|
|
call GetPatternEng
|
|
jc @f
|
|
xor al,al
|
|
ret
|
|
@@:
|
|
mov al,-1
|
|
ret
|
|
NotEng16:
|
|
call GetPattern
|
|
jc @b
|
|
xor al,al
|
|
ret
|
|
FontCtrlSub1:
|
|
jne FontCtrlSub2
|
|
mov al,10h
|
|
mov ah,al
|
|
ret
|
|
FontCtrlSub2:
|
|
cmp al,2
|
|
ja @b
|
|
mov ds,[bp+rES]
|
|
mov si,[bp+rBX]
|
|
call PutPattern
|
|
jc @b
|
|
xor al,al
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
; << GetInfor >>
|
|
; FUNCTION = get hangeul BIOS information
|
|
; INPUT : AH = 0FDh
|
|
; AL = 00
|
|
; OUTPUT : AL = 0fdh, ES:BX = BIOS data address
|
|
; PROTECT : none
|
|
; GetInfor(-/AL,ES,BX)
|
|
; {
|
|
; if AL = 0, break;
|
|
; SS:[BP+rES] = CS;
|
|
; SS:[BP+rBX] = offset public data;
|
|
; AL = AH;
|
|
; }
|
|
|
|
GetInfor:
|
|
or al,al
|
|
jnz @f
|
|
mov [bp+rES],cs
|
|
mov word ptr [bp+rBX],offset PublicData
|
|
mov al,ah
|
|
@@:
|
|
ret
|
|
|
|
|
|
;========================================================================
|
|
;
|
|
; VIDEO SUB-ROUTINES
|
|
;
|
|
;------------------------------------------------------------------------
|
|
; << CheckCodeRangeWord >>
|
|
; FUNCTION = check code range for word
|
|
; INPUT : AX = Code
|
|
; OUTPUT : AX = Code
|
|
; : carry - NC ( success )
|
|
; : - CY ( code range over )
|
|
; PROTECT : AL,BX,DX,DS,ES
|
|
;
|
|
; CheckCodeRangeWord(AX/AX,carry)
|
|
; {
|
|
; switch([CodeStat])
|
|
; case WSung :
|
|
; if ((0a1h=<AH=<0feh) && (0a1h=<AL=<0feh)), NC, break;
|
|
; CY;
|
|
; break;
|
|
; case CHab :
|
|
; if ((84h=<AH<=0d3h) && (041h=<AL=<07eh)), NC, break;
|
|
; if ((84h=<AH<=0d3h) && (081h=<AL=<0feh)), NC, break;
|
|
; if ((d9h=<AH<=0deh) && (031h=<AL=<07eh)), NC, break;
|
|
; if ((d9h=<AH<=0deh) && (091h=<AL=<0feh)), NC, break;
|
|
; if ((e0h=<AH<=0f9h) && (031h=<AL=<07eh)), NC, break;
|
|
; if ((e0h=<AH<=0f9h) && (091h=<AL=<0feh)), NC, break;
|
|
; if ((feh=AH) && (031h=<AL=<07eh)), NC, break;
|
|
; if ((feh=AH) && (091h=<AL=<0feh)), NC, break;
|
|
; CY;
|
|
; break;
|
|
; case WSung7 :
|
|
; if (5fh=<AH=<60h) && (21h=<AL=<7eh), NC, return;
|
|
; if (7bh=<AH=<7eh) && (21h=<AL=<7eh), NC, break;
|
|
; if (61h=<AH=<7ah) && (40h=<AL=<5fh), NC, return;
|
|
; CY;
|
|
; }
|
|
|
|
CheckCodeRangeWdfe:
|
|
test cs:[CodeStat],Chab or WSung7
|
|
jnz NoWSung
|
|
cmp ah,0feh
|
|
ja @f
|
|
cmp ah,0a1h
|
|
jb @f
|
|
cmp al,0feh
|
|
ja @f
|
|
cmp al,0a1h
|
|
jb @f
|
|
ret
|
|
CheckCodeRangeWord:
|
|
test cs:[CodeStat],Chab or WSung7
|
|
jnz NoWSung
|
|
CheckCodeRangeWs:
|
|
cmp ah,0feh
|
|
ja @f
|
|
cmp ah,0a1h
|
|
jb @f
|
|
cmp al,0ffh
|
|
ja @f
|
|
cmp al,0a1h
|
|
jb @f
|
|
ret
|
|
@@:
|
|
stc
|
|
ret
|
|
NoWSung:
|
|
test cs:[CodeStat],CHab
|
|
jz NoCHab
|
|
CheckCodeRangeCh:
|
|
cmp ah,084h
|
|
jb @b
|
|
cmp ah,0d3h
|
|
ja @f
|
|
cmp al,041h
|
|
jb CheckFail
|
|
cmp al,07eh
|
|
jbe CheckSuc
|
|
cmp al,81h
|
|
jb CheckFail
|
|
cmp al,0feh
|
|
ja CheckFail
|
|
jmp CheckSuc
|
|
@@:
|
|
cmp al,031h
|
|
jb CheckFail
|
|
cmp al,0feh
|
|
ja CheckFail
|
|
cmp al,07eh
|
|
jbe @f
|
|
cmp al,091h
|
|
jb CheckFail
|
|
@@:
|
|
cmp ah,0d8h
|
|
jb CheckFail
|
|
cmp ah,0deh
|
|
jbe CheckSuc
|
|
cmp ah,0e0h
|
|
jb CheckFail
|
|
cmp ah,0f9h
|
|
jbe CheckSuc
|
|
CheckFail:
|
|
stc
|
|
ret
|
|
CheckSuc:
|
|
clc
|
|
ret
|
|
NoCHab: ; WanSung 7Bit Code
|
|
cmp ah,5fh
|
|
jb CheckFail
|
|
cmp ah,7eh
|
|
ja CheckFail
|
|
cmp ah,61h
|
|
jb @f
|
|
cmp ah,7ah
|
|
jbe WSung72
|
|
@@:
|
|
cmp al,7Eh
|
|
ja @f
|
|
cmp al,21h
|
|
jb @f
|
|
ret
|
|
WSung72:
|
|
cmp al,5Fh
|
|
ja @f
|
|
cmp al,40h
|
|
jb @f
|
|
ret
|
|
@@:
|
|
stc
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << CheckCodeRange1st >>
|
|
; FUNCTION = check code range for byte
|
|
; INPUT : AL = Code
|
|
; OUTPUT : AL = Code
|
|
; : carry - NC ( success )
|
|
; : - CY ( code range over )
|
|
; PROTECT : AL,BX,DX,DS,ES
|
|
;
|
|
; CheckCodeRange1st(AL/AL,carry)
|
|
; {
|
|
; switch([CodeStat])
|
|
; case WSung :
|
|
; if (0a1h=<AL=<0feh), NC, break;
|
|
; CY;
|
|
; break;
|
|
; case CHob :
|
|
; if (84h=<AL=<0d3h), NC, break;
|
|
; if (d9h=<AL=<0deh), NC, break;
|
|
; if (e0h=<AL=<0f9h), NC, break;
|
|
; CY;
|
|
; break;
|
|
; case WSung7 :
|
|
; if (5fh=<AL=<7eh), NC, break;
|
|
; CY;
|
|
; }
|
|
|
|
CheckCodeRange1st:
|
|
test cs:[CodeStat],Chab or WSung7
|
|
jnz NotWSung1st
|
|
cmp al,0feh
|
|
ja CCFail
|
|
cmp al,0a1h
|
|
jb CCFail
|
|
ret
|
|
CCFail:
|
|
stc
|
|
ret
|
|
NotWSung1st:
|
|
test cs:[CodeStat],CHab
|
|
jz NotCHab
|
|
cmp al,0f9h
|
|
ja CCFail
|
|
cmp al,0e0h
|
|
jae CCSuc
|
|
cmp al,0deh
|
|
ja CCFail
|
|
cmp al,0d8h
|
|
jae CCSuc
|
|
cmp al,0d3h
|
|
ja CCFail
|
|
cmp al,084h
|
|
jb CCFail
|
|
CCSuc:
|
|
clc
|
|
ret
|
|
NotCHab: ; WanSung 7Bit Code
|
|
cmp al,7eh
|
|
ja CCFail
|
|
cmp al,5fh
|
|
jb CCFail
|
|
ret
|
|
|
|
;------------------------------------------------------------------------
|
|
; << ClearCursor >>, << ToggleCursor >>
|
|
; FUNCTION = cursor clear/toggle
|
|
; INPUT : none
|
|
; OUTPUT : none
|
|
; PROTECT : ALL
|
|
; CursorCursor(-/-)
|
|
; {
|
|
; if (CursorStat] == CursorOn)
|
|
; ToggleCursor(-/-)
|
|
; save AX,BX,CX,DX,DI,ES;
|
|
; switch([ModeId])
|
|
; case 2 : ; TE mode 7, MGA
|
|
; case 4 : ; TE mode 2/3, CGA
|
|
; case 10 : ; mode 40/70
|
|
; ToggleMonoCursor(-/-);
|
|
; break;
|
|
; case 6 : ; TE mode 7, EGA/VGA
|
|
; case 8 : ; TE mode 2/3, EGA/VGA
|
|
; ToggleColorCursor(-/-);
|
|
; case 0 : ; 한글 card, TEXT mode 2/3
|
|
; case 12 : ; mode 60/11/12, EGA/VGA
|
|
; restore AX,BX,CX,DX,DI,ES;
|
|
; }
|
|
|
|
ClearCursor:
|
|
test [CursorStat],CursorOn
|
|
jz ToggleCursorEnd
|
|
ToggleCursor:
|
|
test [ModeStat],EmuCursor
|
|
jz ToggleCursorEnd
|
|
@push ax,bx,cx,dx,di,es
|
|
pushf
|
|
cld
|
|
mov bl,[ModeId]
|
|
xor bh,bh
|
|
call [bx+ToggleCursorJmpTbl]
|
|
popf
|
|
@pop es,di,dx,cx,bx,ax
|
|
ToggleCursorEnd:
|
|
ToggleCursorHanCard:
|
|
ret
|
|
ToggleCursorJmpTbl Label Word
|
|
dw offset ToggleCursorHanCard
|
|
dw offset ToggleMonoCursor
|
|
dw offset ToggleMonoCursor
|
|
dw offset ToggleColorCursor
|
|
dw offset ToggleColorCursor
|
|
dw offset ToggleMonoCursor
|
|
dw offset ToggleCursorHanCard
|
|
|
|
;------------------------------------------------------------------------
|
|
; << ToggleMonoCursor >>
|
|
; FUNCTION = mono cursor toggle
|
|
; INPUT : none
|
|
; OUTPUT : none
|
|
; PROTECT : DS,SI
|
|
; ToggleMonoCursor(-/-)
|
|
|
|
ToggleMonoCursor:
|
|
cli
|
|
mov cx,[rCurType] ; BIOS Cursor Type Information Read
|
|
cmp ch,20h ; Check Not Display Cursor Type
|
|
jae ToggleMonoCursorExit
|
|
and cx,0f0fh ; Get Low 4 Bits
|
|
sub cl,ch
|
|
jc ToggleMonoCursorExit
|
|
inc cl
|
|
mov dx,[OrgCurPos]
|
|
test [CursorStat],CursorOn
|
|
jnz @f
|
|
mov bl,[CurPage]
|
|
xor bh,bh
|
|
shl bx,1
|
|
mov dx,[bx+rCurPos]
|
|
mov [OrgCurPos],dx
|
|
@@:
|
|
cmp dl,80
|
|
jae ToggleMonoCursorExit
|
|
cmp dh,[MaxRows]
|
|
jae ToggleMonoCursorExit
|
|
les di,[GrpBufAddr]
|
|
mov ax,80
|
|
mul dh
|
|
shl ax,1
|
|
shl ax,1
|
|
xor dh,dh
|
|
add ax,dx
|
|
add di,ax ; 80 * 4 * Rows +Cols
|
|
shr ch,1
|
|
jnc @f
|
|
add di,2000h ; Next Scan Line=Scan Line Length Add
|
|
@@:
|
|
shr ch,1
|
|
jnc @f
|
|
add di,2000h*2 ; Next Scan Line
|
|
@@:
|
|
shr ch,1
|
|
jnc @f
|
|
add di,50h
|
|
@@:
|
|
shr ch,1
|
|
jnc @f
|
|
add di,50h*2
|
|
@@:
|
|
mov al,0ffh ; Mask Data
|
|
@@:
|
|
xor es:[di],al
|
|
add di,2000h
|
|
js ToggleMonoCursorAdjust
|
|
loop @b
|
|
MonoCursorExit:
|
|
xor [CursorStat],CursorOn
|
|
ToggleMonoCursorExit:
|
|
sti
|
|
ret
|
|
ToggleMonoCursorAdjust:
|
|
sub di,8000h-50h
|
|
loop @b
|
|
jmp MonoCursorExit
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << FullScroll >>
|
|
; FUNCTION = full scroll
|
|
; INPUT : BH = page #
|
|
; OUTPUT : none
|
|
; PROTECT : AX, BX, CX, DX, DS, ES
|
|
; FullScroll(BH/-)
|
|
; {
|
|
; save AX,BX,CX,DX,ES,DS;
|
|
; ES:DI = [CodeBuf1Addr];
|
|
; DI = DI + ES:[rCrtStart];
|
|
; FullScrollText(ES,DI/BL);
|
|
; if (BH == [CurPage])
|
|
; {
|
|
; if ([ModeStat] == TextEmulation)
|
|
; {
|
|
; ES:DI = [CodeBuf2Addr];
|
|
; FullScrollText(ES,DI/BL);
|
|
; }
|
|
; ES:DI = [GrpBufAddr];
|
|
; switch([ModeId])
|
|
; case 0 : ; 한글 card, TEXT mode 2/3/7
|
|
; break;
|
|
; case 2 : ; TE mode 7, MGA
|
|
; case 4 : ; TE mode 2/3, CGA
|
|
; case 10 : ; mode 40/70
|
|
; FullScrollMono([GrpBufAddr]/-);
|
|
; break;
|
|
; case 6 : ; TE mode 7, EGA/VGA
|
|
; FullScrollColor([GrpBufAddr]/-);
|
|
; break;
|
|
; case 8 : ; TE mode 2/3, EGA/VGA
|
|
; case 12 : ; mode 60/11/12, EGA/VGA
|
|
; FullScrollColor([GrpBufAddr]/-);
|
|
; }
|
|
; restore AX,BX,CX,DX,DS,ES
|
|
; }
|
|
|
|
FullScroll:
|
|
@push ax,bx,cx,dx,es,ds
|
|
mov ax,[rCrtStart]
|
|
les di,[CodeBuf1Addr]
|
|
add di,ax
|
|
call FullScrollText
|
|
cmp [CurPage],bh
|
|
jnz FullScrollEnd
|
|
test [ModeStat],TextEmulation
|
|
jz @f
|
|
les di,[CodeBuf2Addr]
|
|
call FullScrollText
|
|
@@:
|
|
call ClearCursor
|
|
mov al,[ModeId]
|
|
xor ah,ah
|
|
mov si,ax
|
|
les di,[GrpBufAddr]
|
|
call [si+FullScrollJmpTbl]
|
|
|
|
FullScrollEnd:
|
|
@pop ds,es,dx,cx,bx,ax
|
|
FullScrHanCardText:
|
|
ret
|
|
|
|
FullScrollJmpTbl Label Word
|
|
dw offset FullScrHanCardText
|
|
dw offset FullScrollMono
|
|
dw offset FullScrollMono
|
|
dw offset FullScrollColor
|
|
dw offset FullScrollColor
|
|
dw offset FullScrollMono
|
|
dw offset FullScrollColor
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << MakeHanAttr >>
|
|
; FUNCTION = make hangeul character attribute
|
|
; INPUT : BL = Attr
|
|
; : DS:SI = source pattern
|
|
; OUTPUT : BL = Attr
|
|
; AL = Background Attr
|
|
; PROTECT : ALL
|
|
;
|
|
; MakeHanAttr(BL,DS,SI/AL,BL)
|
|
; BL register값 변동없이 background attr을 AL register에 setting
|
|
; MGA/CGA/40/70 인 경우는 pattern까지 modify함
|
|
; {
|
|
; switch([ModeId])
|
|
; case 0 : ; 한글 card, TEXT mode 2/3/7
|
|
; AL = BH shr 4;
|
|
; break;
|
|
; case 2 : ; TE mode 7, MGA
|
|
; case 10 : ; mode 40/70
|
|
; /* pattern modify = reverse,underline,none-display */
|
|
; break;
|
|
; case 4 : ; TE mode 2/3, CGA
|
|
; /* pattern modify = reverse,none-display */
|
|
; break;
|
|
; case 6 : ; TE mode 7, EGA/VGA
|
|
; AL = BH shr 4;
|
|
; /* AL/BH attr을 modify */
|
|
; /* pattern modify */
|
|
; break;
|
|
; case 8 : ; TE mode 2/3, EGA/VGA
|
|
; AL = BH shr 4;
|
|
; break;
|
|
; case 12 : ; mode 60/11/12, EGA/VGA
|
|
; }
|
|
|
|
MakeHanAttr:
|
|
push bx
|
|
mov bl,[ModeId]
|
|
xor bh,bh
|
|
jmp [bx+MakeHanAttrJmpTbl]
|
|
|
|
MakeHanAttrJmpTbl Label Word
|
|
dw offset MkHanAttrHanCardText
|
|
dw offset MkHanAttrMgaTE
|
|
dw offset MkHanAttrCgaTE
|
|
dw offset MkHanAttrEgaVgaTE7
|
|
dw offset MkHanAttrEgaVgaTE23
|
|
dw offset MkHanAttrMode40_70
|
|
dw offset MkHanAttrMode60_11_12
|
|
|
|
MkHanAttrHanCardText:
|
|
MkHanAttrEgaVgaTE23:
|
|
pop bx
|
|
mov bh,bl
|
|
shr bh,1
|
|
shr bh,1
|
|
shr bh,1
|
|
shr bh,1
|
|
mov al,bh
|
|
ret
|
|
|
|
MkHanAttrMgaTE:
|
|
MkHanAttrMode40_70:
|
|
pop bx
|
|
mov bh,bl
|
|
test bh,00001000b
|
|
jz @f
|
|
call MakeHanAttrHigh
|
|
@@:
|
|
test bh,01110111b
|
|
jz MakeHanAttrNonDisp
|
|
and bh,01110111b
|
|
cmp bh,70h
|
|
jz MakeHanAttrReverse
|
|
and bh,00000111b
|
|
cmp bh,1
|
|
jnz @f
|
|
or word ptr [si+30],-1
|
|
@@:
|
|
ret
|
|
MakeHanAttrReverse:
|
|
@push bx,cx,si
|
|
mov bx,2
|
|
mov cx,10h
|
|
@@:
|
|
not Word Ptr [si] ; 1
|
|
add si,bx
|
|
loop @b
|
|
@pop si,cx,bx
|
|
ret
|
|
MakeHanAttrNonDisp:
|
|
@push ax,cx,di,es
|
|
mov cx,10h
|
|
mov ax,ds
|
|
mov es,ax
|
|
mov di,si
|
|
xor ax,ax
|
|
rep stosw
|
|
@pop es,di,cx,ax
|
|
ret
|
|
MakeHanAttrHigh:
|
|
@push ax,bx,cx,si
|
|
mov cx,10h
|
|
mov bx,2
|
|
@@:
|
|
mov ax,[si]
|
|
shr al,1 ; High Byte
|
|
rcr ah,1 ; Low Byte
|
|
or [si],ax
|
|
add si,bx
|
|
loop @b
|
|
@pop si,cx,bx,ax
|
|
ret
|
|
|
|
MkHanAttrCgaTE:
|
|
pop bx
|
|
mov bh,bl
|
|
test bh,00001000b
|
|
jz @f
|
|
call MakeHanAttrHigh
|
|
@@:
|
|
test bh,01110111b
|
|
jz MakeHanAttrNonDisp
|
|
and bh,01110111b
|
|
cmp bh,70h
|
|
jz MakeHanAttrReverse
|
|
ret
|
|
|
|
MkHanAttrEgaVgaTE7:
|
|
pop bx
|
|
mov bh,0
|
|
test bl,01110111B
|
|
jz @f
|
|
mov bh,1
|
|
test bl,01111000B
|
|
jz @f
|
|
mov bh,bl
|
|
and bh,01111000B
|
|
cmp bh,00001000B
|
|
mov bh,4
|
|
jz @f
|
|
mov bh,10h
|
|
test bl,00000111B
|
|
jz @f
|
|
mov bh,11h
|
|
test bl,00001000B
|
|
jz @f
|
|
mov bh,40h
|
|
@@:
|
|
push bx
|
|
mov bh,bl
|
|
and bh,01110111B
|
|
cmp bh,00000001B
|
|
jnz @f
|
|
or Word Ptr [si+30],0FFFFh
|
|
@@:
|
|
pop bx
|
|
mov bl,bh
|
|
mov al,bh
|
|
shr al,1
|
|
shr al,1
|
|
shr al,1
|
|
shr al,1
|
|
ret
|
|
|
|
MkHanAttrMode60_11_12:
|
|
pop bx
|
|
xor al,al
|
|
;MkNonDsiplay:
|
|
; test bl,00001111b
|
|
; jnz @f
|
|
; @push bx,ax
|
|
; mov ah,0fh
|
|
; int 10h
|
|
; and al,01111111b
|
|
; cmp al,011h
|
|
; @pop ax,bx
|
|
; jnz @f
|
|
; @push ax,cx,es,di
|
|
; mov ax,ds
|
|
; mov es,ax
|
|
; mov di,si
|
|
; mov cx,16
|
|
; xor ax,ax
|
|
; rep stosw
|
|
; @pop di,es,cx,ax
|
|
;@@:
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << MakeEngAttr >>
|
|
; FUNCTION = make english character attribute
|
|
; INPUT : BL = Attr
|
|
; : DS:SI = source pattern
|
|
; OUTPUT : BL = Attr
|
|
; AL = Background Attr
|
|
; PROTECT : ALL
|
|
;
|
|
; MakeEngAttr(BL,DS,SI/AL,BL)
|
|
; BL register값 변동없이 background attr을 AL register에 setting
|
|
; MGA/CGA/40/70 인 경우는 pattern까지 modify함
|
|
; {
|
|
; switch([ModeId])
|
|
; case 0 : ; 한글 card, TEXT mode 2/3/7
|
|
; AL = BH shr 4;
|
|
; break;
|
|
; case 2 : ; TE mode 7, MGA
|
|
; case 10 : ; mode 40/70
|
|
; /* pattern modify = reverse,underline,none-display */
|
|
; break;
|
|
; case 4 : ; TE mode 2/3, CGA
|
|
; /* pattern modify = reverse,none-display */
|
|
; break;
|
|
; case 6 : ; TE mode 7, EGA/VGA
|
|
; AL = BH shr 4;
|
|
; /* AL/BH attr을 modify */
|
|
; /* pattern modify */
|
|
; break;
|
|
; case 8 : ; TE mode 2/3, EGA/VGA
|
|
; AL = BH shr 4;
|
|
; break;
|
|
; case 12 : ; mode 60/11/12, EGA/VGA
|
|
; }
|
|
|
|
MakeEngAttr:
|
|
push bx
|
|
mov bl,[ModeId]
|
|
xor bh,bh
|
|
jmp [bx+MakeEngAttrJmpTbl]
|
|
|
|
MakeEngAttrJmpTbl Label Word
|
|
dw offset MkEngAttrHanCardText
|
|
dw offset MkEngAttrMgaTE
|
|
dw offset MkEngAttrCgaTE
|
|
dw offset MkEngAttrEgaVgaTE7
|
|
dw offset MkEngAttrEgaVgaTE23
|
|
dw offset MkEngAttrMode40_70
|
|
dw offset MkEngAttrMode60_11_12
|
|
|
|
MkEngAttrHanCardText:
|
|
MkEngAttrEgaVgaTE23:
|
|
pop bx
|
|
mov bh,bl
|
|
shr bh,1
|
|
shr bh,1
|
|
shr bh,1
|
|
shr bh,1
|
|
mov al,bh
|
|
ret
|
|
|
|
MkEngAttrMgaTE:
|
|
MkEngAttrMode40_70:
|
|
pop bx
|
|
mov bh,bl
|
|
test bh,00001000b
|
|
jz @f
|
|
call MakeEngAttrHigh
|
|
@@:
|
|
test bh,01110111b
|
|
jz MakeEngAttrNonDisp
|
|
and bh,01110111b
|
|
cmp bh,70h
|
|
jz MakeEngAttrReverse
|
|
and bh,00000111b
|
|
cmp bh,1
|
|
jnz @f
|
|
or byte ptr [si+15],-1
|
|
@@:
|
|
ret
|
|
MakeEngAttrReverse:
|
|
@push si,cx
|
|
mov cx,10h
|
|
@@:
|
|
not Byte Ptr [si]
|
|
inc si
|
|
loop @b
|
|
@pop cx,si
|
|
ret
|
|
MakeEngAttrNonDisp:
|
|
@push ax,cx,di,es
|
|
mov cx,08h
|
|
mov ax,ds
|
|
mov es,ax
|
|
mov di,si
|
|
xor ax,ax
|
|
rep stosw
|
|
@pop es,di,cx,ax
|
|
ret
|
|
MakeEngAttrHigh:
|
|
@push ax,bx,cx,si
|
|
mov cx,08h
|
|
mov bx,2
|
|
@@:
|
|
mov ax,[si]
|
|
shr al,1
|
|
shr ah,1
|
|
or [si],ax ; First & Second Byte
|
|
add si,bx
|
|
loop @b
|
|
@pop si,cx,bx,ax
|
|
ret
|
|
|
|
MkEngAttrCgaTE:
|
|
pop bx
|
|
mov bh,bl
|
|
test bh,00001000b
|
|
jz @f
|
|
call MakeEngAttrHigh
|
|
@@:
|
|
test bh,01110111b
|
|
jz MakeEngAttrNonDisp
|
|
and bh,01110111b
|
|
cmp bh,70h
|
|
jz MakeEngAttrReverse
|
|
ret
|
|
|
|
MkEngAttrEgaVgaTE7:
|
|
pop bx
|
|
mov bh,0
|
|
test bl,01110111B
|
|
jz @f
|
|
mov bh,1
|
|
test bl,01111000B
|
|
jz @f
|
|
mov bh,bl
|
|
and bh,01111000B
|
|
cmp bh,00001000B
|
|
mov bh,4
|
|
jz @f
|
|
mov bh,10h
|
|
test bl,00000111B
|
|
jz @f
|
|
mov bh,11h
|
|
test bl,00001000B
|
|
jz @f
|
|
mov bh,40h
|
|
@@:
|
|
push bx
|
|
mov bh,bl
|
|
and bh,01110111B
|
|
cmp bh,00000001B
|
|
jnz @f
|
|
or Word Ptr [si+15],0FFh
|
|
@@:
|
|
pop bx
|
|
mov bl,bh
|
|
mov al,bh
|
|
shr al,1
|
|
shr al,1
|
|
shr al,1
|
|
shr al,1
|
|
ret
|
|
|
|
MkEngAttrMode60_11_12:
|
|
pop bx
|
|
xor al,al
|
|
; call MkNonDsiplay
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << DispHangeul >>
|
|
; FUNCTION = write hangeul char
|
|
; INPUT : AL = char, BL = attr, BH = page, DX = cursor position
|
|
; OUTPUT : none
|
|
; PROTECT : BH, DX, DS, ES
|
|
;
|
|
; DispHangeul(AL,BL,BH/-)
|
|
; {
|
|
; Save BX,DX,ES,DS;
|
|
; [HanStat] = [HanStat] && not Han1st;
|
|
; ES:DI = [CodeBuf1Addr];
|
|
; DI = DI + [OldTextPos1Addr];
|
|
; AH = BL;
|
|
; CL = [OldChar];
|
|
; CH = [OldAttr];
|
|
; XCHG AX,CX;
|
|
; STOSW;
|
|
; XCHG AX,CX;
|
|
; STOSW;
|
|
; if ([CurPage] == BH)
|
|
; {
|
|
; [CursorStat] = [CursorStat] && not CursorOn;
|
|
; if ([ModeStat] == TextEmulation)
|
|
; {
|
|
; ES:DI = [CodeBuf2Addr];
|
|
; DI = DI + [OldTextPos2Addr];
|
|
; XCHG AX,CX;
|
|
; STOSW;
|
|
; XCHG AX,CX;
|
|
; STOSW;
|
|
; }
|
|
; XCHG CH,CL;
|
|
; CL = AL;
|
|
; ES = CS;
|
|
; DI = offset PatternBuffer;
|
|
; GetPattern(CX,ES,DI/carry);
|
|
; SI = DI;
|
|
; AL = [ModeId];
|
|
; AH = 0;
|
|
; DI = AX;
|
|
; ES:AX = [GrpBufAddr];
|
|
; AX = AX + [OldGrpPosAddr];
|
|
; switch([ModeId])
|
|
; case 0 : ; 한글 card, TEXT mode 2/3/7
|
|
; break;
|
|
; case 2 : ; TE mode 7, MGA
|
|
; case 4 : ; TE mode 2/3, CGA
|
|
; DispHanMono(BL,DS,SI,ES,AX/-);
|
|
; break;
|
|
; case 6 : ; TE mode 7, EGA/VGA
|
|
; case 8 : ; TE mode 2/3, EGA/VGA
|
|
; DispHanColor(BL,DS,SI,ES,AX/-);
|
|
; break;
|
|
; case 10 : ; mode 40/70
|
|
; DispHanMonoXor(BL,DS,SI,ES,AX/-);
|
|
; break;
|
|
; case 12 : ; mode 60/11/12, EGA/VGA
|
|
; DispHanColorXor(BL,DS,SI,ES,AX/-);
|
|
; break;
|
|
; }
|
|
; restore BX,DX,ES,DS;
|
|
; }
|
|
|
|
DispHangeul:
|
|
@push bx,dx,es,ds
|
|
and [HanStat],not Han1st
|
|
cmp dl,80
|
|
jae DispHangeulExit
|
|
cmp dh,[MaxRows]
|
|
jae DispHangeulExit
|
|
les di,[CodeBuf1Addr]
|
|
add di,[OldTextPos1Addr]
|
|
mov ah,bl
|
|
mov cl,[OldChar]
|
|
mov ch,[OldAttr]
|
|
xchg ax,cx
|
|
stosw
|
|
xchg ax,cx
|
|
stosw
|
|
cmp [CurPage],bh
|
|
jnz DispHangeulExit
|
|
cmp [ModeId],0
|
|
jz DispHangeulExit
|
|
and [CursorStat],not CursorOn
|
|
test [ModeStat],TextEmulation
|
|
jz @f
|
|
les di,[CodeBuf2Addr]
|
|
add di,[OldTextPos2Addr]
|
|
xchg ax,cx
|
|
stosw
|
|
xchg ax,cx
|
|
stosw
|
|
@@:
|
|
xchg ch,cl
|
|
mov cl,al
|
|
mov ax,cs
|
|
mov es,ax
|
|
mov di,offset PatternBuf
|
|
call GetPattern
|
|
mov si,di
|
|
mov al,[ModeId]
|
|
xor ah,ah
|
|
mov di,ax
|
|
les ax,[GrpBufAddr]
|
|
add ax,[OldGrpPosAddr]
|
|
call [di+DispHangeulJmpTbl]
|
|
DispHangeulExit:
|
|
@pop ds,es,dx,bx
|
|
DispHanHanCardText:
|
|
ret
|
|
DispHangeulJmpTbl Label Word
|
|
dw offset DispHanHanCardText
|
|
dw offset DispHanMono
|
|
dw offset DispHanMono
|
|
dw offset DispHanColor
|
|
dw offset DispHanColor
|
|
dw offset DispHanMonoXor
|
|
dw offset DispHanColorXor
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << DispEnglishNew >>
|
|
; FUNCTION = write english char
|
|
; INPUT : AL = char, BL = attr, BH = page, CX = counter, DX = cursor position
|
|
; OUTPUT : none
|
|
; PROTECT : BH, DX, DS, ES
|
|
;
|
|
; DispEnglishNew(AL,BL,BH,CX/-)
|
|
; {
|
|
; Save BX,DX,ES,DS;
|
|
; SI = 80*25;
|
|
; if ([MaxRows] == 30), SI = 80*30;
|
|
; SI = SI - [TextPos1Addr]/2;
|
|
; if (CX > SI), CX = SI;
|
|
; [HanStat] = [HanStat] && not Han1st;
|
|
; ES:DI = [CodeBuf1Addr];
|
|
; DI = DI + [TextPos1Addr];
|
|
; SI = CX;
|
|
; AH = BL;
|
|
; REP STOSW;
|
|
; if ([CurPage] == BH)
|
|
; {
|
|
; [CursorStat] = [CursorStat] && not CursorOn;
|
|
; if ([ModeStat] == TextEmulation)
|
|
; {
|
|
; ES:DI = [CodeBuf2Addr];
|
|
; DI = DI + [TextPos2Addr];
|
|
; CX = SI;
|
|
; REP STOSW;
|
|
; }
|
|
; ES = CS;
|
|
; DI = offset PatternBuffer;
|
|
; CL = AL;
|
|
; GetPatternEng(CL,ES,DI/carry);
|
|
; CX = SI;
|
|
; SI = DI;
|
|
; AL = [ModeId];
|
|
; AH = 0;
|
|
; DI = AX;
|
|
; ES:AX = [GrpBufAddr];
|
|
; AX = AX + [GrpPosAddr];
|
|
; switch([ModeId])
|
|
; case 0 : ; 한글 card, TEXT mode 2/3/7
|
|
; break;
|
|
; case 2 : ; TE mode 7, MGA
|
|
; case 4 : ; TE mode 2/3, CGA
|
|
; DispEngMonoMulti(BL,DS,SI,ES,AX/-);
|
|
; break;
|
|
; case 6 : ; TE mode 7, EGA/VGA
|
|
; case 8 : ; TE mode 2/3, EGA/VGA
|
|
; DispEngColorMulti(BL,DS,SI,ES,AX/-);
|
|
; break;
|
|
; case 10 : ; mode 40/70
|
|
; DispEngMonoXorMulti(BL,DS,SI,ES,AX/-);
|
|
; break;
|
|
; case 12 : ; mode 60/11/12, EGA/VGA
|
|
; DispEngColorXorMulti(BL,DS,SI,ES,AX/-);
|
|
; break;
|
|
; }
|
|
; restore BX,DX,ES,DS;
|
|
; }
|
|
DispEnglishExitj:
|
|
jmp DispEnglishExit
|
|
|
|
DispEnglishNew:
|
|
@push bx,dx,es,ds
|
|
cmp dl,80
|
|
jae DispEnglishExitj
|
|
cmp dh,[MaxRows]
|
|
jae DispEnglishExit
|
|
mov si,80*25
|
|
cmp [MaxRows],25
|
|
jbe @f
|
|
mov si,80*30
|
|
@@:
|
|
mov di,[TextPos1Addr]
|
|
shr di,1
|
|
sub si,di
|
|
cmp cx,si
|
|
jbe @f
|
|
mov cx,si
|
|
@@:
|
|
and [HanStat],not Han1st
|
|
les di,[CodeBuf1Addr]
|
|
add di,[TextPos1Addr]
|
|
mov si,cx
|
|
mov ah,bl
|
|
rep stosw
|
|
cmp [CurPage],bh
|
|
jnz DispEnglishExit
|
|
cmp [ModeId],0
|
|
jz DispEnglishExit
|
|
and [CursorStat],not CursorOn
|
|
test [ModeStat],TextEmulation
|
|
jz @f
|
|
les di,[CodeBuf2Addr]
|
|
add di,[TextPos2Addr]
|
|
mov cx,si
|
|
rep stosw
|
|
@@:
|
|
mov di,cs
|
|
mov es,di
|
|
mov di,offset PatternBuf
|
|
mov cl,al
|
|
call GetPatternEng
|
|
mov cx,si
|
|
mov si,di
|
|
mov al,[ModeId]
|
|
xor ah,ah
|
|
mov di,ax
|
|
les ax,[GrpBufAddr]
|
|
add ax,[GrpPosAddr]
|
|
call [di+DispEnglishNewJmpTbl]
|
|
DispEnglishExit:
|
|
@pop ds,es,dx,bx
|
|
DispEngHanCardText:
|
|
ret
|
|
DispEnglishNewJmpTbl Label Word
|
|
dw offset DispEngHanCardText
|
|
dw offset DispEngMonoMulti
|
|
dw offset DispEngMonoMulti
|
|
dw offset DispEngColorMulti
|
|
dw offset DispEngColorMulti
|
|
dw offset DispEngMonoXorMulti
|
|
dw offset DispEngColorXorMulti
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << DispEnglishOld >>
|
|
; FUNCTION = write english char
|
|
; INPUT : none
|
|
; OUTPUT : none
|
|
; PROTECT : AX, BX, CX, DX, DS, ES
|
|
;
|
|
; DispEnglishOld(-/-)
|
|
; {
|
|
; /* save AL,BL,BH,CX,DX */
|
|
; /* xchg [TextPos1Addr],[TextPos2Addr],[GrpPosAddr] to old */
|
|
; /* get [OldChar],[OldPage],[OldAttr],[OldCounter] */
|
|
; DispEnglishNew(AL,BL,BH,CX/-);
|
|
; /* restore AL,BL,BH,CX,DX */
|
|
; /* xchg [TextPos1Addr],[TextPos2Addr],[GrpPosAddr] to old */
|
|
; }
|
|
|
|
DispEnglishOld:
|
|
@push ax,bx,cx,dx
|
|
push word ptr [CursorStat]
|
|
mov ax,[OldTextPos1Addr]
|
|
xchg [TextPos1Addr],ax
|
|
mov [OldTextPos1Addr],ax
|
|
mov ax,[OldTextPos2Addr]
|
|
xchg [TextPos2Addr],ax
|
|
mov [OldTextPos2Addr],ax
|
|
mov ax,[OldGrpPosAddr]
|
|
xchg [GrpPosAddr],ax
|
|
mov [OldGrpPosAddr],ax
|
|
mov al,[OldChar]
|
|
mov bl,[OldAttr]
|
|
mov bh,[OldPage]
|
|
mov cx,[OldCounter]
|
|
mov dx,[OldCurPos]
|
|
call DispEnglishNew
|
|
mov ax,[OldTextPos1Addr]
|
|
xchg [TextPos1Addr],ax
|
|
mov [OldTextPos1Addr],ax
|
|
mov ax,[OldTextPos2Addr]
|
|
xchg [TextPos2Addr],ax
|
|
mov [OldTextPos2Addr],ax
|
|
mov ax,[OldGrpPosAddr]
|
|
xchg [GrpPosAddr],ax
|
|
mov [OldGrpPosAddr],ax
|
|
pop ax
|
|
mov [CursorStat],al
|
|
@pop dx,cx,bx,ax
|
|
ret
|
|
|
|
|
|
;=======================================================================
|
|
; << GetPattern >>
|
|
; FUNCTION = get hangeul pattern
|
|
; INPUT : CX = code, ES:DI = pattern buffer
|
|
; OUTPUT : carry(if error)
|
|
; PROTECT : ALL
|
|
;
|
|
; GetPattern(CX,ES,DI/carry)
|
|
; {
|
|
; GetPattern(CX,ES,DI/carry);
|
|
; }
|
|
|
|
GetPattern:
|
|
@push ax,bx,cx,dx,si,di,ds,es
|
|
mov ax,cs
|
|
mov ds,ax
|
|
mov ax,cx
|
|
; UDC
|
|
test [CodeStat],WSung7
|
|
jnz GetHanPat
|
|
test [CodeStat],Chab
|
|
jz @f
|
|
cmp ah,0d8h
|
|
jnz GetHanPat
|
|
call ChgCh2Ks
|
|
mov cx,ax
|
|
@@:
|
|
call UdcRange
|
|
jc GetHanPat
|
|
test [HjStat],UdcArea
|
|
jz GetPatternErr
|
|
call [GetUdc1st]
|
|
jmp short GetPatternEnd
|
|
GetHanPat:
|
|
call CheckCodeRangeWdfe
|
|
jc GetPatternErr
|
|
test [CodeStat],WSung7
|
|
jz @f
|
|
call ChgCh72Ks
|
|
jc GetPatternErr
|
|
@@:
|
|
test [CodeStat],Chab
|
|
jz @f
|
|
test [CodeStat],InstPatGen
|
|
jz GetHanPatCode
|
|
cmp ah,0d3h
|
|
ja GetHanPatCode
|
|
call [PatGenAddr]
|
|
jc GetPatternErr
|
|
jmp short GetPatternEnd
|
|
GetHanPatCode:
|
|
call ChgCh2Ks
|
|
jc GetPatternErr
|
|
@@:
|
|
mov cx,ax
|
|
test [CodeStat],InstPatGen
|
|
jz GetPatHanCard
|
|
cmp ah,0a4h
|
|
jne CheckHangeul
|
|
cmp al,0a1h
|
|
jb CheckHangeul
|
|
cmp al,0d3h
|
|
jbe @f
|
|
CheckHangeul:
|
|
cmp ah,0b0h
|
|
jb GetPatHanCard
|
|
cmp ah,0c8h
|
|
ja GetPatHanCard
|
|
@@:
|
|
call [PatGenAddr]
|
|
jc GetPatternErr
|
|
jmp short GetPatternEnd
|
|
GetPatHanCard:
|
|
call [GetHan1st]
|
|
jc GetPatternErr
|
|
GetPatternEnd:
|
|
clc
|
|
jmp short @f
|
|
GetPatternErr:
|
|
mov si,offset ErrHanFont
|
|
mov cx,16*2
|
|
rep movsb
|
|
stc
|
|
@@:
|
|
@pop es,ds,di,si,dx,cx,bx,ax
|
|
ret
|
|
|
|
UdcRange:
|
|
cmp ah,0c9h
|
|
jz @f
|
|
cmp ah,0feh
|
|
jnz UdcRangeErr
|
|
@@:
|
|
cmp al,0a1h
|
|
jb UdcRangeErr
|
|
cmp al,0feh
|
|
ja UdcRangeErr
|
|
clc
|
|
ret
|
|
UdcRangeErr:
|
|
stc
|
|
ret
|
|
ErrHanFont dw 0fe7fh, 240h, 240h, 240h, 240h, 240h, 240h, 240h
|
|
dw 240h, 240h, 240h, 240h, 240h, 240h, 240h, 0fe7fh
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << PutPattern >>
|
|
; FUNCTION = put hangeul pattern
|
|
; INPUT : CX = code, DS:SI = pattern buffer
|
|
; OUTPUT : carry(if error)
|
|
; PROTECT : ALL
|
|
;
|
|
; PutPattern(CX,DS,SI/carry)
|
|
;
|
|
PutPattern:
|
|
@push ax,bx,cx,dx,si,di,ds,es
|
|
mov ax,cx
|
|
test cs:[HjStat],UdcArea
|
|
jz PutPatternErr
|
|
test cs:[CodeStat],Chab
|
|
jz @f
|
|
call ChgCh2Ks
|
|
mov cx,ax
|
|
@@:
|
|
call UdcRange
|
|
jc PutPatternErr
|
|
push ax
|
|
mov dx,3c4h ; sequence index register
|
|
mov al,1
|
|
out dx,al
|
|
inc dl
|
|
in al,dx
|
|
or al,20h ; disable screen
|
|
out dx,al
|
|
pop ax
|
|
mov cx,ax
|
|
push cx
|
|
push si
|
|
push ds
|
|
call cs:[PutUdc1st]
|
|
pop ds
|
|
pop si
|
|
pop cx
|
|
test cs:[Card1st],DualMnt
|
|
jz @f
|
|
call cs:[PutUdc2nd]
|
|
@@:
|
|
mov dx,3c4h ; sequence index register
|
|
mov al,1
|
|
out dx,al
|
|
inc dl
|
|
in al,dx
|
|
and al,not 20h ; enable screen
|
|
out dx,al
|
|
clc
|
|
jmp short @f
|
|
PutPatternErr:
|
|
stc
|
|
@@:
|
|
@pop es,ds,di,si,dx,cx,bx,ax
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << GetPatternEng >>
|
|
; FUNCTION = get english pattern
|
|
; INPUT : CL = code, ES:DI = pattern buffer
|
|
; OUTPUT : carry(if error)
|
|
; PROTECT : ALL
|
|
;
|
|
; GetPatternEng(CL,ES,DI/carry)
|
|
;
|
|
GetPatternEng:
|
|
@push ax,cx,di,si,ds
|
|
mov ax,cs
|
|
mov ds,ax
|
|
xor ch,ch
|
|
shl cx,1
|
|
shl cx,1
|
|
shl cx,1
|
|
shl cx,1
|
|
mov si,cx
|
|
add si,offset EngFont
|
|
mov cx,16
|
|
rep movsb
|
|
GetPatEngEnd:
|
|
@pop ds,si,di,cx,ax
|
|
ret
|
|
|
|
public HanCardSet, HanCardReset, pHanCardReset
|
|
;------------------------------------------------------------------------
|
|
; << HanCardSet >>
|
|
; FUNCTION = set active hangeul card
|
|
; INPUT : none
|
|
; OUTPUT : none
|
|
; PROTECT : ALL
|
|
;
|
|
; HanCardSet(-/-)
|
|
; {
|
|
; if (CS:[Card1st] == HanCard)
|
|
; {
|
|
; save AX,DX;
|
|
; /* call CS:[HanOn1st];
|
|
; restore AX,DX;
|
|
; }
|
|
; }
|
|
;
|
|
HanCardSet:
|
|
test cs:[Card1st],HanCard
|
|
jz HanCardSetEnd
|
|
test cs:[CodeStat],HangeulMode
|
|
jz HanCardSetEnd
|
|
if KseVga
|
|
test cs:[KseCard],00000001b
|
|
jz @f
|
|
test cs:[CodeStat],Chab or WSung7
|
|
jnz HanCardSetEnd
|
|
test cs:[ModeStat],GrpMode
|
|
jnz HanCardSetEnd
|
|
@@:
|
|
endif ; if KseVga
|
|
@push ax,dx
|
|
call cs:[HanOn1st]
|
|
@pop dx,ax
|
|
HanCardSetEnd:
|
|
ret
|
|
|
|
;------------------------------------------------------------------------
|
|
; << HanCardReset >>
|
|
; FUNCTION = reset active hangeul card
|
|
; INPUT : none
|
|
; OUTPUT : none
|
|
; PROTECT : ALL
|
|
;
|
|
; HanCardReset(-/-)
|
|
; {
|
|
; if (CS:[Card1st] == HanCard)
|
|
; {
|
|
; save AX,DX;
|
|
; /* call CS:[HanOff1st];
|
|
; restore AX,DX;
|
|
; }
|
|
; }
|
|
;
|
|
HanCardReset:
|
|
test cs:[Card1st],HanCard
|
|
jz @f
|
|
@push ax,dx
|
|
call cs:[HanOff1st]
|
|
@pop dx,ax
|
|
@@:
|
|
ret
|
|
|
|
;------------------------------------------------------------------------
|
|
; << pHanCardReset >>
|
|
; FUNCTION = reset inactive hangeul card
|
|
; INPUT : none
|
|
; OUTPUT : none
|
|
; PROTECT : ALL
|
|
;
|
|
; pHanCardReset(-/-)
|
|
; {
|
|
; if (CS:[Card2nd] == HanCard)
|
|
; {
|
|
; save AX,DX;
|
|
; /* call CS:[HanOff2nd];
|
|
; restore AX,DX;
|
|
; }
|
|
; }
|
|
;
|
|
pHanCardReset:
|
|
test cs:[Card2nd],DualMnt
|
|
jz @f
|
|
test cs:[Card2nd],HanCard
|
|
jz @f
|
|
@push ax,dx
|
|
call cs:[HanOff2nd]
|
|
@pop dx,ax
|
|
@@:
|
|
ret
|
|
|
|
|
|
;=======================================================================
|
|
public GetFontHanExt, GetFontUdcExt, PutFontUdcExt
|
|
GetFontUdcExt:
|
|
xor ax,ax
|
|
cmp ch,0c9h
|
|
jz @f
|
|
mov al,94
|
|
@@:
|
|
xor ch,ch
|
|
sub cl,0a1h
|
|
add cx,ax
|
|
mov al,32
|
|
mul cx
|
|
add ax,[UdcAddr]
|
|
adc dl,[UdcAddrH]
|
|
mov bx,32/2
|
|
jmp short GetFontExtDo
|
|
GetFontHanExtErr:
|
|
stc
|
|
ret
|
|
GetFontHanExt:
|
|
cmp ch,0adh
|
|
jb @f
|
|
cmp ch,0b0h
|
|
jb GetFontHanExtErr
|
|
sub ch,29
|
|
@@:
|
|
sub cx,0a1a1h
|
|
mov al,94
|
|
mul ch
|
|
xor ch,ch
|
|
add cx,ax
|
|
mov ax,32
|
|
mul cx
|
|
add ax,[HanAddr]
|
|
adc dl,[HanAddrH]
|
|
mov bx,32/2
|
|
GetFontExtDo:
|
|
mov si,offset GdtDataTbl
|
|
mov [si+GdtSL],ax
|
|
mov [si+GdtSH],dl
|
|
mov dx,es
|
|
mov cl,4
|
|
shr dh,cl
|
|
mov ax,es
|
|
shl ax,cl
|
|
add ax,di
|
|
adc dh,0
|
|
mov [si+GdtDL],ax
|
|
mov [si+GdtDH],dh
|
|
GetFontExtCall:
|
|
mov ax,cs
|
|
mov es,ax
|
|
mov cx,bx
|
|
mov ah,87h
|
|
int 15h
|
|
ret
|
|
PutFontUdcExt:
|
|
xor ax,ax
|
|
cmp ch,0c9h
|
|
jz @f
|
|
mov al,94
|
|
@@:
|
|
xor ch,ch
|
|
sub cl,0a1h
|
|
add cx,ax
|
|
mov al,32
|
|
mul cx
|
|
add ax,cs:[UdcAddr]
|
|
adc dl,cs:[UdcAddrH]
|
|
mov bx,32/2
|
|
mov di,offset GdtDataTbl
|
|
mov cs:[di+GdtDL],ax
|
|
mov cs:[di+GdtDH],dl
|
|
mov dx,ds
|
|
mov cl,4
|
|
shr dh,cl
|
|
mov ax,ds
|
|
shl ax,cl
|
|
add ax,si
|
|
adc dh,0
|
|
mov cs:[di+GdtSL],ax
|
|
mov cs:[di+GdtSH],dh
|
|
mov si,di
|
|
jmp GetFontExtCall
|
|
public Int15Srv, GdtDataTbl
|
|
Int15Srv:
|
|
pushf
|
|
cmp ah,88H ; extended memory size determine?
|
|
je @f
|
|
popf
|
|
jmp cs:[OldInt15]
|
|
@@:
|
|
popf
|
|
mov ax,cs:[MaxMemSize]
|
|
iret
|
|
GdtDataTbl label word
|
|
db 16 dup(?) ; 00 - 0f
|
|
dw -1 ; 10 - 11
|
|
db 3 dup(?) ; 12 - 14
|
|
db 93h ; 15
|
|
db 2 dup(?) ; 16 - 17
|
|
dw -1 ; 18 - 19
|
|
db 3 dup(?) ; 1a - 1c
|
|
db 93h ; 1d
|
|
db 2 dup(?) ; 1e - 1f
|
|
db 16 dup(?) ; 20 - 2f
|
|
|
|
;----------------------------------------
|
|
public GetFontHanEms, GetFontUdcEms, PutFontUdcEms
|
|
GetFontUdcEms:
|
|
xor ax,ax
|
|
cmp ch,0c9h
|
|
jz @f
|
|
mov al,94
|
|
@@:
|
|
xor ch,ch
|
|
sub cl,0a1h
|
|
add cx,ax
|
|
mov al,32
|
|
mul cx
|
|
add ax,[UdcAddr]
|
|
adc dl,0
|
|
shl dl,1
|
|
shl dl,1
|
|
add dl,[UdcAddrH]
|
|
mov cx,32
|
|
jmp short GetFontEmsDo
|
|
GetFontHanEms:
|
|
cmp ch,0adh
|
|
jb @f
|
|
cmp ch,0b0h
|
|
jb GetFontHanEmsErr
|
|
sub ch,29
|
|
@@:
|
|
sub cx,0a1a1h
|
|
mov al,94
|
|
mul ch
|
|
xor ch,ch
|
|
add cx,ax
|
|
mov ax,32
|
|
mul cx
|
|
add ax,[HanAddr]
|
|
adc dl,0
|
|
shl dl,1
|
|
shl dl,1
|
|
add dl,[HanAddrH]
|
|
mov cx,32
|
|
GetFontEmsDo:
|
|
cmp ax,16384
|
|
jb @f
|
|
sub ax,16384
|
|
inc dl
|
|
jmp short GetFontEmsDo
|
|
@@:
|
|
mov si,ax
|
|
mov bl,dl
|
|
xor bh,bh
|
|
mov [CurEmsPage],bx
|
|
mov ds,[EmsSeg]
|
|
mov dx,cs:[EmsHandle]
|
|
mov ah,47h
|
|
int 67h
|
|
jmp short SetEmsPage
|
|
@@:
|
|
cmp si,16384
|
|
jae NextEmsPage
|
|
movsb
|
|
dec cx
|
|
jz GetFontEmsDoEnd
|
|
jmp short @b
|
|
NextEmsPage:
|
|
xor si,si
|
|
mov bx,cs:[CurEmsPage]
|
|
inc bx
|
|
SetEmsPage:
|
|
mov ax,4400h ; set page
|
|
int 67h
|
|
or ah,ah
|
|
jz @b
|
|
mov ah,48h
|
|
int 67h
|
|
GetFontHanEmsErr:
|
|
stc
|
|
ret
|
|
GetFontEmsDoEnd:
|
|
mov ah,48h
|
|
int 67h
|
|
clc
|
|
ret
|
|
PutFontUdcEms:
|
|
xor ax,ax
|
|
cmp ch,0c9h
|
|
jz @f
|
|
mov al,94
|
|
@@:
|
|
xor ch,ch
|
|
sub cl,0a1h
|
|
add cx,ax
|
|
mov al,32
|
|
mul cx
|
|
add ax,cs:[UdcAddr]
|
|
adc dl,0
|
|
shl dl,1
|
|
shl dl,1
|
|
add dl,cs:[UdcAddrH]
|
|
mov cx,32
|
|
@@:
|
|
cmp ax,16384
|
|
jb @f
|
|
sub ax,16384
|
|
inc dl
|
|
jmp short @b
|
|
@@:
|
|
mov di,ax
|
|
mov bl,dl
|
|
xor bh,bh
|
|
mov cs:[CurEmsPage],bx
|
|
mov es,cs:[EmsSeg]
|
|
mov dx,cs:[EmsHandle]
|
|
mov ah,47h
|
|
int 67h
|
|
jmp short SetPutEmsPage
|
|
@@:
|
|
cmp di,16384
|
|
jae NextPutEmsPage
|
|
movsb
|
|
dec cx
|
|
jz PutFontEmsDoEnd
|
|
jmp short @b
|
|
NextPutEmsPage:
|
|
xor di,di
|
|
mov bx,cs:[CurEmsPage]
|
|
inc bx
|
|
SetPutEmsPage:
|
|
mov ax,4400h ; set page
|
|
int 67h
|
|
or ah,ah
|
|
jz @b
|
|
mov ah,48h
|
|
int 67h
|
|
stc
|
|
ret
|
|
PutFontEmsDoEnd:
|
|
mov ah,48h
|
|
int 67h
|
|
clc
|
|
ret
|
|
|
|
;----------------------------------------
|
|
public GetFontHanReal, GetFontUdcReal, PutFontUdcReal
|
|
GetFontUdcReal:
|
|
xor ax,ax
|
|
cmp ch,0c9h
|
|
jz @f
|
|
mov al,94
|
|
@@:
|
|
xor ch,ch
|
|
sub cl,0a1h
|
|
add al,cl
|
|
mov cl,5
|
|
shl ax,cl
|
|
add ax,[UdcAddr]
|
|
mov si,ax
|
|
and si,0fh
|
|
mov cl,4
|
|
shr ax,cl
|
|
mov cx,cs
|
|
add ax,cx
|
|
mov ds,ax
|
|
mov cx,32/2
|
|
rep movsw
|
|
clc
|
|
@@:
|
|
ret
|
|
GetFontHanReal:
|
|
cmp ch,0adh
|
|
jb @f
|
|
cmp ch,0b0h
|
|
jb @b ; set carry
|
|
sub ch,29
|
|
@@:
|
|
sub cx,0a1a1h
|
|
mov al,94
|
|
mul ch
|
|
xor ch,ch
|
|
add ax,cx
|
|
mov cx,32
|
|
mul cx
|
|
add ax,[HanAddr]
|
|
adc dl,0
|
|
mov si,ax
|
|
and si,0fh
|
|
mov cl,4
|
|
shr ax,cl
|
|
shl dl,cl
|
|
or ah,dl
|
|
mov cx,cs
|
|
add ax,cx
|
|
mov ds,ax
|
|
mov cx,32/2
|
|
rep movsw
|
|
clc
|
|
ret
|
|
PutFontUdcReal:
|
|
xor ax,ax
|
|
cmp ch,0c9h
|
|
jz @f
|
|
mov al,94
|
|
@@:
|
|
xor ch,ch
|
|
sub cl,0a1h
|
|
add al,cl
|
|
mov cl,5
|
|
shl ax,cl
|
|
add ax,cs:[UdcAddr]
|
|
mov di,ax
|
|
and di,0fh
|
|
mov cl,4
|
|
shr ax,cl
|
|
mov cx,cs
|
|
add ax,cx
|
|
mov es,ax
|
|
mov cx,32/2
|
|
rep movsw
|
|
clc
|
|
ret
|
|
|
|
|
|
;=======================================================================
|
|
; MGA/CGA video card porting area
|
|
;
|
|
; MGA card
|
|
public HanOnMga, HanOffMga, GetFontMga, PutFontMga
|
|
GetFontMga:
|
|
mov si,0b800h-2
|
|
mov ds,si
|
|
sub si,si
|
|
cli ; for proper operation
|
|
mov ax,cx
|
|
mov dx,3b6H ; point to 3b6 port
|
|
out dx,ax ; out high byte
|
|
mov cx,16 ; repeat word counter
|
|
rep movsw ; move pattern into es:di
|
|
inc dl
|
|
out dx,al
|
|
sti
|
|
clc
|
|
ret
|
|
PutFontMga:
|
|
mov ax,cx ; save codes
|
|
mov dx,3b6H ; point to 3b6 port
|
|
cli
|
|
out dx,ax
|
|
mov di,0b800h-2
|
|
mov es,di
|
|
xor di,di
|
|
mov cx,16
|
|
rep movsw ; move pattern to put_through RAM
|
|
inc dl
|
|
out dx,al
|
|
sti
|
|
clc
|
|
ret
|
|
HanOnMga:
|
|
mov dx,3bdH ; point to 3bd port
|
|
mov al,00000001B ; data to output
|
|
out dx,al
|
|
ret
|
|
HanOffMga:
|
|
mov dx,3bdH ; point to 3bd port
|
|
xor al,al ; data to output
|
|
out dx,al
|
|
ret
|
|
;
|
|
; CGA card
|
|
public HanOnCga, HanOffCga, GetFontCga, PutFontCga
|
|
GetFontCga:
|
|
mov si,0b800h
|
|
mov ds,si
|
|
UDC_Check:
|
|
cmp ch,0c9h ; First UDC Area ?
|
|
je @f
|
|
cmp ch,0feh ; Second UDC Area ?
|
|
je @f
|
|
jmp Short GetText
|
|
@@:
|
|
sub ax,ax ; Calc. Ref Address
|
|
mov al,cl ; get code
|
|
sub al,80H
|
|
and ch,00010000B
|
|
mov cl,5
|
|
shl ax,cl ; * 32
|
|
or ah,ch
|
|
Mov Si,Ax ; Set Ref. Address
|
|
Mov AH,81h ; Select Bank 1
|
|
Jmp Short GetGraph
|
|
GetText:
|
|
sub cl,80H
|
|
mov ax,cx ; get code
|
|
and ah,01111111b
|
|
shr ah,1 ; get bank #
|
|
shr ah,1
|
|
shr ah,1
|
|
or ah,10000000B
|
|
and ch,7
|
|
sub cl,cl
|
|
shr cx,1
|
|
add cl,al
|
|
mov si,cx
|
|
mov cl,5 ; AH = Bank Select Value
|
|
shl si,cl ; Si = get relative addr within a bank
|
|
GetGraph:
|
|
xor cx,cx
|
|
mov dx,3daH ; point to 3da port
|
|
@@:
|
|
dec cx
|
|
jz @f
|
|
in al,dx
|
|
test al,00001000B ; dots on?
|
|
jz @b
|
|
@@:
|
|
cli
|
|
sub dl,4 ; point to 3d6 port
|
|
mov al,ah ; select bank #
|
|
out dx,al
|
|
mov cx,16
|
|
rep movsw
|
|
mov al,11000000B ; select bank 0 & enable Hangeul mode
|
|
out dx,al
|
|
sti ; enable interrupts
|
|
clc
|
|
ret
|
|
PutFontCga:
|
|
sub ax,ax
|
|
mov al,cl ; get code
|
|
sub al,80H
|
|
and ch,00010000B
|
|
mov cl,5
|
|
shl ax,cl ; * 32
|
|
or ah,ch
|
|
mov di,0b800h
|
|
mov es,di
|
|
mov di,ax ; FontWinSeg:(0 or 1000H)+(cl-80H)*32
|
|
mov dx,3daH ; point to 3da port
|
|
@@:
|
|
in al,dx
|
|
test al,00001000B ; dots off?
|
|
jnz @b
|
|
cli ; disable interrupts
|
|
@@:
|
|
in al,dx
|
|
test al,00001000B ; dots on?
|
|
jz @b
|
|
sub dl,2 ; point to 3d8 port
|
|
mov al,21H ; bit 3 <- 0
|
|
out dx,al ; disable video signal
|
|
sub dl,2 ; point to 3d6 port
|
|
mov al,81H ; select bank 1
|
|
out dx,al
|
|
mov cx,16
|
|
rep movsw
|
|
mov al,10000000B ; select bank 0 & enable Hangeul mode
|
|
out dx,al
|
|
add dl,2 ; point to 3d8 port
|
|
mov cx,ds
|
|
xor ax,ax
|
|
mov ds,ax
|
|
mov al,[rCrtModeSet] ; get modeset value
|
|
out dx,al ; enable video signal
|
|
mov ds,cx
|
|
sti ; enable interrupts
|
|
clc
|
|
ret
|
|
HanOnCga:
|
|
mov dx,3d6H ; point to 3d6 port
|
|
mov al,10000000B ; data to output
|
|
out dx,al
|
|
cmp [ModeId],0*2
|
|
jz @f
|
|
mov al,11000000b
|
|
out dx,al
|
|
@@:
|
|
ret
|
|
HanOffCga:
|
|
mov dx,3d6H ; point to 3d6 port
|
|
xor al,al ; data to output
|
|
out dx,al
|
|
ret
|
|
;
|
|
; font card
|
|
public HanOnFont, HanOffFont, GetFontFont, PutFontFont
|
|
GetFontFont:
|
|
mov si,0b800h-2
|
|
mov ds,si
|
|
sub si,si
|
|
cli ; for proper operation
|
|
mov ax,cx
|
|
mov dx,3b6H ; point to 3b6 port
|
|
out dx,ax ; out high byte
|
|
mov cx,16 ; repeat word counter
|
|
rep movsw ; move pattern into es:di
|
|
inc dl
|
|
out dx,al
|
|
sti
|
|
clc
|
|
ret
|
|
PutFontFont:
|
|
mov ax,cx ; save codes
|
|
mov dx,3b6H ; point to 3b6 port
|
|
cli
|
|
out dx,ax
|
|
mov di,0b800h-2
|
|
mov es,di
|
|
xor di,di
|
|
mov cx,16
|
|
rep movsw ; move pattern to put_through RAM
|
|
inc dl
|
|
out dx,al
|
|
sti
|
|
HanOnFont:
|
|
HanOffFont:
|
|
clc
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << DispEngMonoMulti >>
|
|
; FUNCTION = english character multi-display in mono
|
|
; INPUT : ES:AX = graphics buffer position, CX = counter, BL = attr
|
|
; DS:SI = pattern
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
; DispEngMonoMulti(BL,CX,DS,SI,ES,AX/-)
|
|
; {
|
|
; if (CX = 1),DispEngMono(BL,DS,SI,ES,DI/-);
|
|
; else
|
|
; {
|
|
; if (CX = 0), return;
|
|
; DI = AX;
|
|
; Call MakeEngAttr ;
|
|
; while (CX = 0, CX-)
|
|
; /* save register */
|
|
; DispEngMono(BL,DS,SI,ES,DI/-);
|
|
; /* restore register */
|
|
; /* recalc memory address */
|
|
; }
|
|
; }
|
|
|
|
DispEngMonoMulti:
|
|
cmp cx,1
|
|
jne @f
|
|
call DispEngMono
|
|
ret
|
|
@@:
|
|
jcxz DispEngMonoMultiExit
|
|
mov dl,Byte Ptr [CurPos]
|
|
mov di,ax
|
|
CALL MakeEngAttr
|
|
DispEngMonoMultiLoop:
|
|
@push bx,cx,dx,di,si
|
|
call DispEngMonoDo
|
|
@pop si,di,dx,cx,bx
|
|
inc di
|
|
inc dl
|
|
cmp dl,80
|
|
jb @f
|
|
xor dl,dl
|
|
add di,80*3
|
|
@@:
|
|
loop DispEngMonoMultiLoop
|
|
DispEngMonoMultiExit:
|
|
ret
|
|
|
|
;------------------------------------------------------------------------
|
|
; << DispEngMonoXorMulti >>
|
|
; FUNCTION = english character multi-display in mono ( XOR )
|
|
; INPUT : ES:AX = graphics buffer position, CX = counter, BL = attr
|
|
; DS:SI = pattern
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
;
|
|
; DispEngMonoXorMulti(BL,CX,DS,SI,ES,AX/-)
|
|
; {
|
|
; if (CX = 1),DispEngMonoXor(BL,DS,SI,ES,DI/-);
|
|
; else
|
|
; if (CX = 0), return;
|
|
; DI = AX;
|
|
; Call MakeEngAttr;
|
|
; while (CX = 0, CX-)
|
|
; /* save register */
|
|
; DispEngMonoXor(BL,DS,SI,ES,DI/-);
|
|
; /* restore register */
|
|
; /* recalc memory address */
|
|
; }
|
|
|
|
DispEngMonoXorMulti:
|
|
test bl,80h
|
|
jz DispEngMonoMulti
|
|
cmp cx,1
|
|
jne @f
|
|
call DispEngMonoXor
|
|
ret
|
|
@@:
|
|
jcxz DispEngMonoXorMultiExit
|
|
mov dl,Byte Ptr [CurPos]
|
|
mov di,ax
|
|
CALL MakeEngAttr
|
|
DispEngMonoXorMultiLoop:
|
|
@push bx,cx,dx,di,si
|
|
call DispEngMonoXorDo
|
|
@pop si,di,dx,cx,bx
|
|
inc di
|
|
inc dl
|
|
cmp dl,80
|
|
jb @f
|
|
xor dl,dl
|
|
add di,80*3
|
|
@@:
|
|
loop DispEngMonoXorMultiLoop
|
|
DispEngMonoXorMultiExit:
|
|
ret
|
|
|
|
|
|
; 이 sub-routine들은 내부에서 attribute control 기능을 가져야함
|
|
;------------------------------------------------------------------------
|
|
; << DispHanMono >>
|
|
; FUNCTION = Font Image Display Routine for Double Byte Font (16*16)
|
|
; INPUT ES:AX = Video RAM Segment:Offset
|
|
; DS:SI = Font Data Segment:Offset
|
|
; BL = Attribute
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
;
|
|
; DispHanMono(BL,DS,SI,ES,AX/-)
|
|
|
|
DispHanMono:
|
|
mov di,ax
|
|
CALL MakeHanAttr
|
|
MOV AX,(2000h-2) ; Next Scan Line Value
|
|
MOV BX,(2000h*3-50h+2) ; First Scan Line Return Value
|
|
MOVSW
|
|
ADD DI,AX
|
|
MOVSW
|
|
ADD DI,AX
|
|
MOVSW
|
|
ADD DI,AX
|
|
MOVSW
|
|
SUB DI,BX
|
|
MOVSW
|
|
ADD DI,AX
|
|
MOVSW
|
|
ADD DI,AX
|
|
MOVSW
|
|
ADD DI,AX
|
|
MOVSW
|
|
SUB DI,BX
|
|
MOVSW
|
|
ADD DI,AX
|
|
MOVSW
|
|
ADD DI,AX
|
|
MOVSW
|
|
ADD DI,AX
|
|
MOVSW
|
|
SUB DI,BX
|
|
MOVSW
|
|
ADD DI,AX
|
|
MOVSW
|
|
ADD DI,AX
|
|
MOVSW
|
|
ADD DI,AX
|
|
MOVSW
|
|
RET
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << DispHanMonoXor >>
|
|
; FUNCTION = Font Image Display Routine for Double Byte Font (16*16)
|
|
; INPUT ES:AX = Video RAM Segment:Offset
|
|
; DS:SI = Font Data Segment:Offset
|
|
; BL = Attribute
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
;
|
|
; DispHanMonoXor(BL,DS,SI,ES,AX/-)
|
|
|
|
DispHanMonoXor:
|
|
test bl,80h
|
|
jz DispHanMono
|
|
mov di,ax
|
|
CALL MakeHanAttr
|
|
MOV CX,2000h ; Next Scan Line Value
|
|
MOV BX,(2000h*3-50h) ; First Scan Line Return Value
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
ADD DI,CX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
ADD DI,CX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
ADD DI,CX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
SUB DI,BX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
ADD DI,CX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
ADD DI,CX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
ADD DI,CX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
SUB DI,BX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
ADD DI,CX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
ADD DI,CX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
ADD DI,CX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
SUB DI,BX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
ADD DI,CX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
ADD DI,CX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
ADD DI,CX
|
|
LODSW
|
|
XOR ES:[DI],AX
|
|
RET
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << DispEngMono >>
|
|
; FUNCTION = Font Image Display Routine for One Byte Font
|
|
; INPUT ES:AX = Video RAM Segment:Offset
|
|
; DS:SI = Font Data Segment:Offset
|
|
; BL = Attribute
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
;
|
|
; DispEngMono(BL,DS,SI,ES,AX/-)
|
|
|
|
DispEngMono:
|
|
mov di,ax
|
|
CALL MakeEngAttr
|
|
DispEngMonoDo:
|
|
MOV AX,(2000h-1) ; Next Scan Line Value
|
|
MOV BX,(2000h*3-50h+1) ; First Scan Line Return Value
|
|
MOVSB
|
|
ADD DI,AX
|
|
MOVSB
|
|
ADD DI,AX
|
|
MOVSB
|
|
ADD DI,AX
|
|
MOVSB
|
|
SUB DI,BX
|
|
MOVSB
|
|
ADD DI,AX
|
|
MOVSB
|
|
ADD DI,AX
|
|
MOVSB
|
|
ADD DI,AX
|
|
MOVSB
|
|
SUB DI,BX
|
|
MOVSB
|
|
ADD DI,AX
|
|
MOVSB
|
|
ADD DI,AX
|
|
MOVSB
|
|
ADD DI,AX
|
|
MOVSB
|
|
SUB DI,BX
|
|
MOVSB
|
|
ADD DI,AX
|
|
MOVSB
|
|
ADD DI,AX
|
|
MOVSB
|
|
ADD DI,AX
|
|
MOVSB
|
|
RET
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << DispEngMonoXor >>
|
|
; FUNCTION = Font Image Display Routine for One Byte Font
|
|
; INPUT ES:AX = Video RAM Segment:Offset
|
|
; DS:SI = Font Data Segment:Offset
|
|
; BL = Attribute
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
;
|
|
; DispEngMonoXor(BL,DS,SI,ES,AX/-)
|
|
|
|
DispEngMonoXor:
|
|
test bl,80h
|
|
jz DispEngMono
|
|
mov di,ax
|
|
CALL MakeEngAttr
|
|
DispEngMonoXorDo:
|
|
MOV CX,2000h ; Next Scan Line Value
|
|
MOV BX,(2000h*3-50h) ; First Scan Line Return Value
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
ADD DI,CX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
ADD DI,CX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
ADD DI,CX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
SUB DI,BX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
ADD DI,CX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
ADD DI,CX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
ADD DI,CX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
SUB DI,BX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
ADD DI,CX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
ADD DI,CX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
ADD DI,CX
|
|
LODSB
|
|
XOR Es:[DI],AL
|
|
SUB DI,BX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
ADD DI,CX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
ADD DI,CX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
ADD DI,CX
|
|
LODSB
|
|
XOR ES:[DI],AL
|
|
RET
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << CalcScrollParms >>
|
|
; FUNCTION = Scroll을 위한 파라미터의 계산
|
|
; INPUT : AH = Function
|
|
; : AL = Scroll Line count
|
|
; : BH = Blank line Attr
|
|
; : CH:CL = Left Upper Row : Column
|
|
; : DH:DL = Right Lower Row : Column
|
|
; OUTPUT : BL = Scroll Line count ( Y' )
|
|
; : DH = Move count ( Y )
|
|
; : DL = Window width ( X )
|
|
; : BP = 80 - DL ( X' )
|
|
; : DI = CH*80*2 + CL
|
|
; : SI = (CH+AL)*80*2 + CL
|
|
; PROTECT : none
|
|
; -----------------------------------------
|
|
; X X'
|
|
; --------><------------------><---------
|
|
;
|
|
; (CH,CL)
|
|
; ---- --------------------
|
|
; di
|
|
; al
|
|
;
|
|
; y -------------------
|
|
; si
|
|
;
|
|
;
|
|
; si
|
|
; ---- --------------------(DH-AL,DL)
|
|
;
|
|
; y' al
|
|
; di
|
|
; ---- --------------------
|
|
; (DH,DL)
|
|
; ------------------------------------------
|
|
;
|
|
; SCROLL UP SCROLL DOWN
|
|
; -------------------------------------------------------
|
|
; CLD STD
|
|
; XCHG CX,DX
|
|
; NEG AL
|
|
; --------------------------------------------------------
|
|
; X = DL - CL X = DL - CL
|
|
; if AL >= 80H , -X if AL >= 80H , -X
|
|
; X' = 80 - X X' = 80 - X
|
|
; if AL >= 80H , -X' if AL >= 80H , -X'
|
|
; Y = DH - CH - AL Y = DH - CH - AL
|
|
; DI = CH * 80*2 + CL DI = CH * 80*2 + CL
|
|
; SI = (CH+AL)*80*2 + CL SI = (CH+AL)*80*2 + CL
|
|
;
|
|
;
|
|
|
|
CalcScrollParms:
|
|
cmp ah,06h
|
|
jz @f ; scroll up
|
|
std ; decrement order
|
|
xchg cx,dx
|
|
neg al
|
|
@@:
|
|
push cx
|
|
mov bl,al ; BL = Y'
|
|
sub dl,cl ; DL = X
|
|
jns @f
|
|
neg dl
|
|
@@:
|
|
inc dl
|
|
sub dh,ch ; Y + Y'
|
|
jns @f
|
|
neg dh
|
|
@@:
|
|
inc dh
|
|
mov al,bl
|
|
or al,al
|
|
jns @f
|
|
neg al
|
|
@@:
|
|
sub dh,al ; Y
|
|
mov bp,80
|
|
mov al,dl
|
|
xor ah,ah
|
|
sub bp,ax ; BP = X'
|
|
shl bp,1 ; word size
|
|
mov al,80
|
|
mul ch
|
|
xor ch,ch
|
|
mov di,ax
|
|
add di,cx ; (ch*80)*2 + cl
|
|
shl di,1
|
|
mov si,di
|
|
|
|
mov al,bl
|
|
or al,al
|
|
jns @f
|
|
neg al
|
|
@@:
|
|
mov ah,80*2
|
|
mul ah
|
|
mov cl,bl
|
|
or cl,cl
|
|
jns @f
|
|
sub si,ax
|
|
jmp short Continue
|
|
@@:
|
|
add si,ax
|
|
Continue:
|
|
or bl,bl
|
|
jns @f
|
|
neg bp
|
|
@@:
|
|
pop cx
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << TextBufferScroll >>
|
|
; FUNCTION = Text Buffer의 Scroll
|
|
; INPUT : ES:AX = CodeBuffer의 세그먼트와 옵셋
|
|
; : BH = Blank line attribute
|
|
; : BL = Scroll Line count ( Y' )
|
|
; : DH = Move count ( Y )
|
|
; : DL = Window width ( X )
|
|
; : BP = 80 - DL ( X' )
|
|
; : DI = CH*80*2 + CL
|
|
; : SI = (CH+AL)*80*2 + CL
|
|
; OUTPUT : none
|
|
; PROTECT : BX,CX,DX,DS,SI,DI
|
|
|
|
TextBufferScroll:
|
|
@push bx,cx,dx,ds,di,si
|
|
or bl,bl
|
|
jns @f
|
|
neg bl ; Positive
|
|
@@:
|
|
add di,ax ; ES:DI = destination
|
|
add si,ax ; DS:SI = source
|
|
mov cx,es
|
|
mov ds,cx
|
|
xor ch,ch
|
|
or dh,dh
|
|
jz MgaTextFill
|
|
@@:
|
|
mov cl,dl ; restore width
|
|
rep movsw
|
|
add si,bp
|
|
add di,bp
|
|
dec dh
|
|
jnz @b
|
|
MgaTextFill:
|
|
mov ah,bh ; restore attribute
|
|
mov al,' ' ; space character
|
|
@@:
|
|
mov cl,dl
|
|
rep stosw ; AX = attribute : ' '
|
|
add di,bp
|
|
dec bl
|
|
jnz @b
|
|
@pop si,di,ds,dx,cx,bx
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << MgaGrpScroll >>
|
|
; FUNCTION = Mono Graphic Screen Scroll
|
|
; INPUT : BH = Blank line Attr
|
|
; : BL = Scroll Line count ( Y' )
|
|
; : DH = Move count ( Y )
|
|
; : DL = Window width ( X )
|
|
; : CX = Row : Column
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
|
|
MgaGrpScroll:
|
|
les di,[GrpBufAddr]
|
|
mov ax,es
|
|
mov ds,ax ; ES = DS
|
|
mov bp,cx
|
|
xchg cx,dx ; save DX
|
|
mov ax,80*4
|
|
mov dl,dh
|
|
xor dh,dh
|
|
mul dx
|
|
mov dx,bp
|
|
xor dh,dh
|
|
add ax,dx
|
|
add di,ax
|
|
mov si,di
|
|
|
|
mov dl,bl
|
|
or dl,dl
|
|
jns @f
|
|
neg dl
|
|
@@:
|
|
mov bp,80*4
|
|
mov al,dl
|
|
xor ah,ah
|
|
mul bp
|
|
or bl,bl
|
|
jns @f
|
|
sub si,ax
|
|
jmp short MF3
|
|
@@:
|
|
add si,ax
|
|
MF3:
|
|
xchg cx,dx ; restore DX
|
|
|
|
xor ah,ah
|
|
mov al,dl ; restore width
|
|
mov bp,2000h
|
|
or bl,bl
|
|
jns @f
|
|
add bp,ax
|
|
jmp short MF4
|
|
@@:
|
|
sub bp,ax ; 2000h-window width:next scan line
|
|
MF4:
|
|
xor al,al
|
|
or bh,bh
|
|
jz MF1
|
|
cmp bh,0ffh
|
|
jz MF2
|
|
and bh,77h
|
|
cmp bh,70h
|
|
jz MF2
|
|
and bh,00000111b
|
|
cmp bh,1 ; undeline
|
|
jnz MF1
|
|
or cs:[ScrUpDnFlag],10000000b
|
|
jmp Short MF1
|
|
MF2:
|
|
not al ; al=0ffh
|
|
MF1:
|
|
mov ah,bl ; set fill count
|
|
mov ch,bl
|
|
mov bx,(8000h-50h)
|
|
or ah,ah
|
|
jns @f
|
|
neg ah
|
|
@@:
|
|
push ax
|
|
sub bx,bp
|
|
xor ch,ch
|
|
or dh,dh
|
|
jnz MonoScrollLoop
|
|
jmp MonoFill
|
|
|
|
MonoScrollLoop:
|
|
mov cl,dl ; 1
|
|
rep movsb
|
|
add si,bp
|
|
add di,bp
|
|
mov cl,dl ; 2
|
|
rep movsb
|
|
add si,bp
|
|
add di,bp
|
|
mov cl,dl ; 3
|
|
rep movsb
|
|
add si,bp
|
|
add di,bp
|
|
mov cl,dl ; 4
|
|
rep movsb
|
|
sub si,bx
|
|
sub di,bx
|
|
|
|
mov cl,dl ; 5
|
|
rep movsb
|
|
add si,bp
|
|
add di,bp
|
|
mov cl,dl ; 6
|
|
rep movsb
|
|
add si,bp
|
|
add di,bp
|
|
mov cl,dl ; 7
|
|
rep movsb
|
|
add si,bp
|
|
add di,bp
|
|
mov cl,dl ; 8
|
|
rep movsb
|
|
sub si,bx
|
|
sub di,bx
|
|
|
|
mov cl,dl ; 9
|
|
rep movsb
|
|
add si,bp
|
|
add di,bp
|
|
mov cl,dl ; 10
|
|
rep movsb
|
|
add si,bp
|
|
add di,bp
|
|
mov cl,dl ; 11
|
|
rep movsb
|
|
add si,bp
|
|
add di,bp
|
|
mov cl,dl ; 12
|
|
rep movsb
|
|
sub si,bx
|
|
sub di,bx
|
|
|
|
mov cl,dl ; 13
|
|
rep movsb
|
|
add si,bp
|
|
add di,bp
|
|
mov cl,dl ; 14
|
|
rep movsb
|
|
add si,bp
|
|
add di,bp
|
|
mov cl,dl ; 15
|
|
rep movsb
|
|
add si,bp
|
|
add di,bp
|
|
mov cl,dl ; 16
|
|
rep movsb
|
|
sub si,bx
|
|
sub di,bx
|
|
or ah,ah
|
|
test cs:[ScrUpDnFlag],00000010b
|
|
jz @f ; down
|
|
sub si,80*4*2
|
|
sub di,80*4*2
|
|
@@:
|
|
dec dh ; decrement scroll Height
|
|
jz MonoFill
|
|
jmp MonoScrollLoop
|
|
MonoFill:
|
|
pop ax
|
|
MonoFillLoop:
|
|
mov cl,dl ; 1
|
|
rep stosb
|
|
add di,bp
|
|
mov cl,dl ; 2
|
|
rep stosb
|
|
add di,bp
|
|
mov cl,dl ; 3
|
|
rep stosb
|
|
add di,bp
|
|
mov cl,dl ; 4
|
|
rep stosb
|
|
sub di,bx
|
|
|
|
mov cl,dl ; 5
|
|
rep stosb
|
|
add di,bp
|
|
mov cl,dl ; 6
|
|
rep stosb
|
|
add di,bp
|
|
mov cl,dl ; 7
|
|
rep stosb
|
|
add di,bp
|
|
mov cl,dl ; 8
|
|
rep stosb
|
|
sub di,bx
|
|
|
|
mov cl,dl ; 9
|
|
rep stosb
|
|
add di,bp
|
|
mov cl,dl ; 10
|
|
rep stosb
|
|
add di,bp
|
|
mov cl,dl ; 11
|
|
rep stosb
|
|
add di,bp
|
|
mov cl,dl ; 12
|
|
rep stosb
|
|
sub di,bx
|
|
|
|
mov cl,dl ; 13
|
|
rep stosb
|
|
add di,bp
|
|
mov cl,dl ; 14
|
|
rep stosb
|
|
add di,bp
|
|
mov cl,dl ; 15
|
|
rep stosb
|
|
add di,bp
|
|
test cs:[ScrUpDnFlag],80h ; scroll down/undeline
|
|
jz @f
|
|
mov al,0ffh
|
|
mov cl,dl ; 16
|
|
rep stosb
|
|
xor al,al
|
|
jmp Short Normal1
|
|
@@:
|
|
mov cl,dl ; 16
|
|
rep stosb
|
|
Normal1:
|
|
sub di,bx
|
|
test cs:[ScrUpDnFlag],00000010b
|
|
jz @f
|
|
sub di,80*4*2
|
|
@@:
|
|
dec ah ; decrement scroll count
|
|
jz @f
|
|
jmp MonoFillLoop
|
|
@@:
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << MgaWritePixel >>
|
|
; FUNCTION = write pixel
|
|
; INPUT : DX row number
|
|
; : CX column number
|
|
; : AL color value
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
; if bit 7 of al = 1, then color value is XORed
|
|
; with the current contents of the dot
|
|
; MgaWritePixel(AL,CX,DX/-)
|
|
|
|
MgaWritePixel:
|
|
mov bh,al ; save color value
|
|
call MgaGetPos
|
|
test bh,10000000b ; is bit 7 set?
|
|
jz MgaWriteDotNormal
|
|
and bh,00000001B ; maskout other than color bit
|
|
ror bh,1 ; reside to MSB
|
|
shr bh,cl ; get target bit position in that byte
|
|
xor al,bh ; XORing color value of raw bit
|
|
stosb ; write dot
|
|
ret
|
|
|
|
MgaWriteDotNormal:
|
|
and bh,00000001B ; maskout other than color bit
|
|
ror bh,1 ; reside to MSB
|
|
shr bh,cl ; get target bit position in that byte
|
|
not bl ; inverse masking bits (1's complement)
|
|
and al,bl ; maskout target bit
|
|
or al,bh ; set color value into target bit
|
|
stosb ; write dot
|
|
ret
|
|
|
|
MgaGetPos:
|
|
mov di,dx ; save row number
|
|
mov ax,80
|
|
shr dx,1 ; rows/4
|
|
shr dx,1
|
|
mul dl
|
|
mov dx,di ; restore row number
|
|
mov di,ax ; rows/4 * 80
|
|
and dx,0000000000000011B ; rows mod 4
|
|
ror dx,1 ; mapping to x000H(0/2000H/4000H/6000H)
|
|
ror dx,1
|
|
ror dx,1
|
|
add di,dx ; target VRAM addr for given rows
|
|
mov ax,cx ; get column number
|
|
shr ax,1 ; cols/8
|
|
shr ax,1
|
|
shr ax,1
|
|
add di,ax ; target VRAM addr for given rows/cols
|
|
and cx,00000111B ; get remainder
|
|
mov ax,80h
|
|
shr ax,cl ; get target bit position in that byte
|
|
mov bl,al ; save it
|
|
mov al,es:[di] ; get target byte
|
|
ret
|
|
|
|
;------------------------------------------------------------------------
|
|
; << MgaReadPixel >>
|
|
; FUNCTION = read pixel
|
|
; INPUT : DX row number
|
|
; : CX column number
|
|
; OUTPUT : AL returned color value the dot read
|
|
; PROTECT : none
|
|
;
|
|
;MgaReadPixel(BH,CX,DX/-)
|
|
|
|
MgaReadPixel:
|
|
call MgaGetPos
|
|
and al,bl ; extract target bit
|
|
not cl
|
|
and cl,00000111B ; get shift counter (cl=7-cl)
|
|
shr al,cl ; return color value
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << CalcTextBlock >>
|
|
; FUNCTION = parm. calculation for block move/copy
|
|
; INPUT : BX = Target
|
|
; : CX = UL
|
|
; : DX = LR
|
|
; : BP = Move/Copy : Attr
|
|
; OUTPUT : SI = Source position
|
|
; DI = Target position
|
|
; DL = Window weidth ( X )
|
|
; DH = Window height ( Y )
|
|
; BP = Screen width - Window width ( X' )
|
|
; BH:BL = Move/Copy : Attr
|
|
; PROTECT : none
|
|
; CalcBlockText(BX,CX,DX/-)
|
|
;
|
|
; -------------------------------------------
|
|
; X X'
|
|
; --------><------------------><
|
|
;
|
|
; (CH,CL) (CH,DL)
|
|
; ---- --------------------
|
|
;
|
|
;
|
|
; y (BH,BL) (BH,DL-CL+BL)
|
|
; ---------�----------
|
|
;
|
|
;
|
|
; ---- ----------�--------
|
|
; (DH,CL) (DH,DL)
|
|
;
|
|
;
|
|
; --------------------
|
|
; (DH-CH+BH,BL) (DH-CH+BH,DL-CL-BL)
|
|
;
|
|
; ---------------------------------------------
|
|
;
|
|
; CASE1(Tail to Left) BH > CH
|
|
; BL >= CL
|
|
; STD
|
|
; Y (BlkHeight) = DH - CH
|
|
; X'(NextLine) = - (80 - X)
|
|
; X (BlkWidth) = DL - CL
|
|
; SI = DH * 80 * 2 + DL
|
|
; DI = (DH - CH + BH) * 80 * 2 + (DL - CL + BL)
|
|
;
|
|
; CASE2(Left to Head) BH =< CH
|
|
; BL > CL
|
|
; STD
|
|
; Y (BlkHeight) = DH - CH
|
|
; X'(NextLine) = 80 + X
|
|
; X (BlkWidth) = DL - CL
|
|
; SI = CH * 80 * 2 + DL
|
|
; DI = BH * 80 * 2 + (DL - CL + BL)
|
|
;
|
|
; CASE3(Head to Right) BH < CH
|
|
; BL =< CL
|
|
; CLD
|
|
; Y (BlkHeight) = DH - CH
|
|
; X'(NextLine) = 80 - X
|
|
; X (BlkWidth) = DL - CL
|
|
; SI = CH * 80 * 2 + CL
|
|
; DI = BH * 80 * 2 + BL
|
|
;
|
|
; CASE4(Left to Tail) BH >= CH
|
|
; BL < CL
|
|
; CLD
|
|
; Y (BlkHeight) = DH - CH
|
|
; X'(NextLine) = - (80 + X)
|
|
; X (BlkWidth) = DL - CL
|
|
; SI = DH * 80 * 2 + CL
|
|
; DI = (DH - CH + BH) * 80 * 2 + BL
|
|
;
|
|
|
|
CalcTextBlock:
|
|
sub dl,cl
|
|
jnc @f
|
|
neg dl
|
|
@@:
|
|
inc dl ; x
|
|
sub dh,ch
|
|
jnc @f
|
|
neg dh
|
|
@@:
|
|
inc dh ; y
|
|
mov al,80
|
|
mul bh
|
|
xor bh,bh
|
|
mov di,ax
|
|
add di,bx ; DI
|
|
shl di,1
|
|
mov al,80
|
|
mul ch
|
|
xor ch,ch
|
|
mov si,ax
|
|
add si,cx ; SI
|
|
shl si,1
|
|
mov bx,80
|
|
sub bl,dl
|
|
shl bx,1
|
|
xchg bx,bp
|
|
or bh,bh
|
|
js @f ; jump if MSB = 1
|
|
neg bp
|
|
@@:
|
|
add bp,[BlockAdj]
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << BlockText >>
|
|
; FUNCTION = text buffer block move Move/Copy
|
|
; INPUT : SI = Source position
|
|
; DI = Target position
|
|
; DL = Window weidth ( X )
|
|
; DH = Window height ( Y )
|
|
; BP = Screen width - Window width ( X' )
|
|
; BH:BL = Move/Copy : Attr
|
|
; OUTPUT : none
|
|
; PROTECT : DS,SI,DI,DX,BX,BP
|
|
; BlockText(segment:offset/-)
|
|
|
|
BlockText:
|
|
@push si,di,dx
|
|
add di,ax
|
|
add si,ax
|
|
mov ax,ds
|
|
mov es,ax
|
|
xor ch,ch
|
|
test bh,1
|
|
jnz @f
|
|
mov ch,bl
|
|
mov cl,20h
|
|
@@:
|
|
test bh,1
|
|
jz BlockTextMove
|
|
mov cl,dl
|
|
rep movsw
|
|
jmp short BlockTextEnd
|
|
BlockTextMove:
|
|
push dx
|
|
BlockTextMoveLp:
|
|
mov ax,[si]
|
|
stosw
|
|
xchg si,di
|
|
mov ax,cx
|
|
stosw
|
|
xchg si,di
|
|
dec dl
|
|
jnz BlockTextMoveLp
|
|
pop dx
|
|
BlockTextEnd:
|
|
add di,bp ; BP = x'
|
|
add si,bp ; BP = x'
|
|
dec dh ; DH = y
|
|
jnz @b
|
|
mov ax,cs
|
|
mov ds,ax
|
|
@pop dx,di,si
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << MgaGrpBlock >>
|
|
; FUNCTION = graphic buffer block move/copy
|
|
; INPUT : DI = Target ( BX )
|
|
; SI = Source ( CX )
|
|
; DL = Window weidth ( X )
|
|
; DH = Window height ( Y )
|
|
; BP = Screen width - Window width ( X' )
|
|
; BH:BL = Move/Copy : Attr
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
; MgaGrpBlock(bx,dx,bp/-)
|
|
|
|
MgaGrpBlock:
|
|
@pop bx,di
|
|
mov ax,di
|
|
mov al,ah
|
|
mov ah,80
|
|
mul ah
|
|
shl ax,1
|
|
shl ax,1
|
|
and di,0ffh
|
|
add di,ax
|
|
pop si
|
|
mov ax,si
|
|
mov al,ah
|
|
mov ah,80
|
|
mul ah
|
|
shl ax,1
|
|
shl ax,1
|
|
and si,0ffh
|
|
add si,ax ; DI
|
|
sub bp,[BlockAdj]
|
|
sar [BlockAdj],1
|
|
neg [BlockAdj]
|
|
sar bp,1 ; make byte length
|
|
add bp,2000h-80
|
|
add [BlockAdj],8000h-80
|
|
or bh,bh
|
|
js @f ; jump if MSB = 1
|
|
add bp,80*2
|
|
add [BlockAdj],80*2
|
|
@@:
|
|
test bh,40h
|
|
jnz @f
|
|
add di,(4-1)*80
|
|
add si,(4-1)*80
|
|
@@:
|
|
les ax,[GrpBufAddr]
|
|
mov ax,es
|
|
mov ds,ax
|
|
xchg bl,bh
|
|
push bx
|
|
and bh,01110111B
|
|
mov ax,-1
|
|
cmp bh,70h
|
|
jz @f
|
|
inc al
|
|
cmp bh,1
|
|
jz @f
|
|
inc ah
|
|
@@:
|
|
pop bx
|
|
xchg ax,bx
|
|
mov ah,al
|
|
test ah,1
|
|
jz @f
|
|
xor ch,ch
|
|
@@:
|
|
call BlockMono4Line
|
|
call BlockMono4Line
|
|
call BlockMono4Line
|
|
call BlockLine
|
|
add di,bp ; BX = x'
|
|
add si,bp ; BX = x'
|
|
call BlockLine
|
|
add di,bp
|
|
add si,bp
|
|
call BlockLine
|
|
add di,bp
|
|
add si,bp
|
|
xchg bl,bh
|
|
call BlockLine
|
|
xchg bl,bh
|
|
add di,bp
|
|
add si,bp
|
|
sub di,cs:[BlockAdj]
|
|
sub si,cs:[BlockAdj]
|
|
dec dh ; AX = y
|
|
jnz @b
|
|
mov ax,cs
|
|
mov ds,ax
|
|
ret
|
|
;-------------------------------
|
|
BlockMono4Line:
|
|
call BlockLine
|
|
add di,bp
|
|
add si,bp
|
|
call BlockLine
|
|
add di,bp
|
|
add si,bp
|
|
call BlockLine
|
|
add di,bp
|
|
add si,bp
|
|
call BlockLine
|
|
add di,bp
|
|
add si,bp
|
|
sub di,cs:[BlockAdj]
|
|
sub si,cs:[BlockAdj]
|
|
ret
|
|
;-------------------------------
|
|
BlockLine:
|
|
test ah,1
|
|
jz BlockGrpMove
|
|
mov cl,dl
|
|
rep movsb
|
|
ret
|
|
BlockGrpMove:
|
|
push dx
|
|
@@:
|
|
mov al,[si]
|
|
stosb
|
|
xchg si,di
|
|
mov al,bl
|
|
stosb
|
|
xchg si,di
|
|
dec dl
|
|
jnz @b
|
|
pop dx
|
|
ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << FullScrollText >>
|
|
; FUNCTION = text buffer full scroll
|
|
; INPUT : ES:DI = text buffer, BL = attribute
|
|
; OUTPUT : none
|
|
; PROTECT : BH
|
|
;
|
|
; FullScrollText(ES,DI/BL)
|
|
;
|
|
FullScrollText:
|
|
mov dx,ds
|
|
mov ax,es
|
|
mov ds,ax
|
|
mov si,di
|
|
mov ax,80*2
|
|
add si,ax
|
|
shr al,1
|
|
mov ah,byte ptr cs:[MaxRows]
|
|
dec ah
|
|
mul ah
|
|
mov cx,ax
|
|
rep movsw
|
|
mov bl,[di+1]
|
|
mov ah,bl
|
|
mov al,' '
|
|
mov cl,80*2/2
|
|
rep stosw
|
|
mov ds,dx
|
|
ret
|
|
|
|
;------------------------------------------------------------------------
|
|
; << FullScrollMono >>
|
|
; FUNCTION = mono buffer full scroll
|
|
; INPUT : ES:DI = graphics buffer, BL = attribute
|
|
; OUTPUT : none
|
|
; PROTECT : none
|
|
;
|
|
; FullScrollMono(ES,DI,BL/-)
|
|
;
|
|
FullScrollMono:
|
|
mov ax,es
|
|
mov ds,ax
|
|
mov si,di
|
|
add si,80*16/4
|
|
mov dx,2000h-80
|
|
mov cx,24*16/4
|
|
@@:
|
|
push cx
|
|
mov cl,80/2
|
|
rep movsw
|
|
add di,dx
|
|
add si,dx
|
|
mov cl,80/2
|
|
rep movsw
|
|
add di,dx
|
|
add si,dx
|
|
mov cl,80/2
|
|
rep movsw
|
|
add di,dx
|
|
add si,dx
|
|
mov cl,80/2
|
|
rep movsw
|
|
sub di,6000h
|
|
sub si,6000h
|
|
pop cx
|
|
loop @b
|
|
mov ax,-1
|
|
and bl,01110111b
|
|
cmp bl,70
|
|
jz @f
|
|
xor al,al
|
|
and bl,00000111b
|
|
cmp bl,1
|
|
jz @f
|
|
xor ah,ah
|
|
@@:
|
|
mov bx,2000h-80
|
|
mov cl,4
|
|
@@:
|
|
push cx
|
|
mov cl,80
|
|
rep stosb
|
|
add di,bx
|
|
mov cl,80
|
|
rep stosb
|
|
add di,bx
|
|
mov cl,80
|
|
rep stosb
|
|
add di,bx
|
|
mov cl,80
|
|
rep stosb
|
|
sub di,6000h
|
|
pop cx
|
|
loop @b
|
|
ret
|
|
|
|
|
|
;=======================================================================
|
|
public VideoParms, Cga40h, Mda70h, Cga23h, Mda07h, CrtcSet, RegSize
|
|
VideoParms label byte
|
|
db 38H,28H,2dH,0aH,1fH,06H,19H,1cH,02H,07H,06H,07H,0,0,0,0
|
|
Cga23H db 71H,50H,5aH,0aH,1fH,06H,19H,1cH,02H,07H,06H,07H,0,0,0,0
|
|
db 38H,28H,2dH,0aH,7fH,06H,64H,70H,02H,01H,06H,07H,0,0,0,0
|
|
Mda07H db 61H,50H,52H,0fH,19H,06H,19H,19H,02H,0fH,0bH,0cH,0,0,0,0
|
|
RegSize dw 2048, 4096, 16384, 4096
|
|
NoCols db 40, 40, 80, 80, 40, 40, 80, 80
|
|
CrtcSet db 2cH,28H,2dH,29H,2aH,2eH,1eH,29H
|
|
Cga40H db 38H,28H,2dH,0aH,7fH,06H,64H,70H,02H,01H,2eH,0fH,0,0,0,0
|
|
Mda70H db 33H,28H,2aH,07H,68H,02H,64H,65H,02H,03H,2eH,0fH,0,0,0,0
|
|
dw 0, 0, 32768, 32768
|
|
db 0, 0, 80, 80, 0, 0, 80, 80
|
|
CrtcSetGrp db 0, 0, 1EH, 1EH, 0, 0, 1EH, 0AH
|
|
|
|
|
|
;========================================================================;
|
|
; ;
|
|
; REAL TIME INTERRUPT 08H ;
|
|
; ;
|
|
;========================================================================;
|
|
; FUNCTION = text emulation & cursor display
|
|
; INPUT : none
|
|
; OUTPUT : none (cursor on/off)
|
|
; PROTECT :
|
|
; Int8()
|
|
; +CS:[TextEmuTick]
|
|
; /* call [OldRtcInt] */
|
|
; if (CS:[VideoActive] == 0)
|
|
; {
|
|
; save AX,DS,ES;
|
|
; DS = CS;
|
|
; ES = 0;
|
|
; +[VideoActive];
|
|
; TextEmu(-/-);
|
|
; AL = ES:[rTimerLow];
|
|
; if (AL == 4, && [CursorStat] == CursorOn), ToggleCursor(-/-);
|
|
; -[VideoActive]
|
|
; restore AX,DS,ES;
|
|
; }
|
|
; iret;
|
|
|
|
PUBLIC Int8
|
|
Int8:
|
|
if Debug
|
|
pushf
|
|
cli
|
|
push ax
|
|
push bx
|
|
mov ax,cs:[DebugData]
|
|
mov bx,ax
|
|
and bx,0fh
|
|
and ax,0fff0h
|
|
add bx,1
|
|
and bx,0fh
|
|
or ax,bx
|
|
out 10h,ax
|
|
mov cs:[DebugData],ax
|
|
pop bx
|
|
pop ax
|
|
popf
|
|
endif ; if Debug
|
|
if WINNT
|
|
cmp cs:[ActiveCodePage], WanSungCP ; If ACP is US, don't call Text Emulation
|
|
jz @f ; For NT 5.0
|
|
inc cs:[TimerTick]
|
|
pushf
|
|
call cs:[OldRtcInt]
|
|
jmp short RealTimeIntBye
|
|
@@:
|
|
endif
|
|
inc cs:[TimerTick]
|
|
pushf
|
|
call cs:[OldRtcInt]
|
|
cmp cs:[VideoActive],0
|
|
jz @f
|
|
jmp short RealTimeIntBye
|
|
@@:
|
|
@push ax,es,ds
|
|
mov ax,cs
|
|
mov ds,ax
|
|
xor ax,ax
|
|
mov es,ax
|
|
inc [VideoActive]
|
|
mov al,byte ptr es:[rTimerLow]
|
|
and al,2
|
|
or al,[CursorStat]
|
|
test al,(2 or CursorOn)
|
|
jpo @f
|
|
call ToggleCursor
|
|
@@:
|
|
cmp [TimerTick],3
|
|
jb @f
|
|
pushf
|
|
sti
|
|
call TextEmu
|
|
popf
|
|
mov [TimerTick],0
|
|
@@:
|
|
@pop ds,es,ax
|
|
dec cs:[VideoActive]
|
|
RealTimeIntBye:
|
|
if Debug
|
|
pushf
|
|
cli
|
|
push ax
|
|
push bx
|
|
mov ax,cs:[DebugData]
|
|
mov bx,ax
|
|
and bx,0fh
|
|
and ax,0fff0h
|
|
sub bx,1
|
|
and bx,0fh
|
|
or ax,bx
|
|
out 10h,ax
|
|
mov cs:[DebugData],ax
|
|
pop bx
|
|
pop ax
|
|
popf
|
|
endif ; if Debug
|
|
iret
|
|
|
|
dw 512 dup(0)
|
|
BiosStack dw 0
|
|
StackSs dw 0
|
|
StackSp dw 0
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
; << TextEmu >>
|
|
; TextEmu(-/-)
|
|
; {
|
|
; if (TextEmulation)
|
|
; {
|
|
; /* save all register */
|
|
; /* compare code buffer */
|
|
; if defferent value, TextEmuChar(AX,ES,DI,BP/-);
|
|
; /* restore all register */
|
|
; }
|
|
; }
|
|
|
|
TextEmu:
|
|
test [ModeStat],TextEmulation
|
|
jz NotScan
|
|
cmp [VideoActive],1
|
|
jbe GotoScan
|
|
NotScan:
|
|
ret
|
|
|
|
GotoScan:
|
|
cli
|
|
push ax
|
|
mov cs:[StackSs],ss
|
|
mov cs:[StackSp],sp
|
|
mov ax,cs
|
|
mov ss,ax
|
|
mov sp,offset BiosStack
|
|
sti
|
|
@push bx,cx,dx,si,di,es,ds,bp
|
|
pushf
|
|
cld
|
|
inc [VideoActive]
|
|
mov bl,80
|
|
mov cx,[rCrtStart]
|
|
les di,[CodeBuf2Addr]
|
|
lds si,[CodeBuf1Addr]
|
|
shr cx,1
|
|
shr cx,1
|
|
shr cx,1
|
|
shr cx,1
|
|
mov dx,ds
|
|
add cx,dx
|
|
mov ds,cx
|
|
xor ch,ch
|
|
mov cl,25
|
|
ScanScreenLoop:
|
|
mov ax,[si]
|
|
call CheckCodeRange1st
|
|
jnc ScanCheckHan
|
|
ScanEngCode:
|
|
cmpsw
|
|
jz ScanScreenEnd
|
|
mov bp,0
|
|
call TextEmuChar
|
|
jmp ScanScreenEnd
|
|
ScanCheckHan:
|
|
cmp bl,1
|
|
jbe ScanEngCode
|
|
mov dx,[si+2]
|
|
mov ah,al
|
|
mov al,dl
|
|
call CheckCodeRangeWord
|
|
jc ScanEngCode
|
|
cmpsw
|
|
jnz WriteCharTe
|
|
cmp dx,es:[di]
|
|
jnz WriteCharTe
|
|
cmpsw
|
|
dec bl
|
|
jmp ScanScreenEnd
|
|
WriteCharTe:
|
|
mov bp,1
|
|
call TextEmuChar
|
|
cmpsw
|
|
dec bl
|
|
ScanScreenEnd:
|
|
dec bl
|
|
jnz ScanScreenLoop
|
|
mov bl,80
|
|
loop ScanScreenLoop
|
|
ScanExit:
|
|
dec cs:[VideoActive]
|
|
popf
|
|
@pop bp,ds,es,di,si,dx,cx,bx
|
|
cli
|
|
mov ss,cs:[StackSs]
|
|
mov sp,cs:[StackSp]
|
|
sti
|
|
pop ax
|
|
ret
|
|
|
|
;------------------------------------------------------------------------
|
|
; << TextEmuChar >>
|
|
;
|
|
;TextEmuChar(AX,ES,DI,BP/-)
|
|
; {
|
|
; if (english char)
|
|
; GetPatternEng(ES,DI/carry)
|
|
; {
|
|
; if (VGA card)
|
|
; DispEngColor(BL,DS,SI,ES,DI/-);
|
|
; else
|
|
; DispEngMono(BL,DS,SI,ES,DI/-);
|
|
; }
|
|
; else
|
|
; GetPattern(ES,DI/carry)
|
|
; {
|
|
; if (VGA card)
|
|
; DispHanColor(BL,DS,SI,ES,DI/-);
|
|
; else
|
|
; DispHanMono(BL,DS,SI,ES,DI/-);
|
|
; }
|
|
; }
|
|
PUBLIC TextEmuChar
|
|
|
|
TextEmuChar:
|
|
@push bx,cx,si,di,es,ds
|
|
dec si
|
|
dec si
|
|
mov ax,si
|
|
shr ax,1
|
|
mov dl,80
|
|
div dl
|
|
test cs:[Card1st],00001100b
|
|
jnz @f
|
|
call MonoVideoOffset
|
|
jmp PuttoEsDi
|
|
@@:
|
|
call ColorVideoOffset
|
|
PuttoEsDi:
|
|
mov cx,[si+2]
|
|
mov si,[si]
|
|
mov bx,seg Data
|
|
mov ds,bx
|
|
mov bl,ds:[rCurPage]
|
|
shl bx,1
|
|
cmp dx,ds:[bx+rCurPos]
|
|
jne @f
|
|
and cs:[CursorStat],not CursorOn
|
|
@@:
|
|
mov bx,si
|
|
cmp bp,0
|
|
jz EngTextEmuChar
|
|
cmp dl,80-1
|
|
jb HanTextEmuChar
|
|
EngTextEmuChar:
|
|
xor cx,cx
|
|
mov cl,bl
|
|
mov es:[di-2],bx
|
|
mov bl,bh
|
|
mov si,cs
|
|
mov es,si
|
|
mov di,offset PatternBuf
|
|
call GetPatternEng
|
|
mov si,es
|
|
mov ds,si
|
|
mov si,di
|
|
les di,cs:[GrpBufAddr]
|
|
add ax,di
|
|
test cs:[Card1st],00001100b
|
|
jnz @f
|
|
call DispEngMono
|
|
jmp TextEmuCharRet
|
|
@@:
|
|
call DispEngColor
|
|
jmp TextEmuCharRet
|
|
HanTextEmuChar:
|
|
mov es:[di-2],bx
|
|
mov es:[di],cx
|
|
xchg ch,bl
|
|
mov si,cs
|
|
mov es,si
|
|
mov di,offset PatternBuf
|
|
call GetPattern
|
|
mov si,es
|
|
mov ds,si
|
|
mov si,di
|
|
les di,cs:[GrpBufAddr]
|
|
add ax,di
|
|
test cs:[Card1st],00001100b
|
|
jnz @f
|
|
call DispHanMono
|
|
jmp TextEmuCharRet
|
|
@@:
|
|
call DispHanColor
|
|
TextEmuCharRet:
|
|
@pop ds,es,di,si,cx,bx
|
|
ret
|
|
|
|
MonoVideoOffset:
|
|
mov cx,si
|
|
xchg ah,al
|
|
mov dx,ax
|
|
sub ah,ah
|
|
sub cx,ax
|
|
sub cx,ax
|
|
shl cx,1
|
|
add ax,cx
|
|
ret
|
|
|
|
ColorVideoOffset:
|
|
mov dx,ax
|
|
xchg dl,dh
|
|
xor ah,ah
|
|
mov cl,4
|
|
shl ax,cl
|
|
mov bx,80
|
|
mov cx,dx
|
|
mul bx
|
|
mov dx,cx
|
|
add al,dl
|
|
adc ah,0
|
|
ret
|
|
|
|
if hdos60
|
|
public ChangeCodeR
|
|
ChangeCodeR:
|
|
@push bx,cx,dx,si,di,es,ds,ax
|
|
mov bx,cs
|
|
mov ds,bx
|
|
mov es,bx
|
|
mov bl,[CodeStat]
|
|
mov [OldCodeStat],bl
|
|
and [CodeStat],not (HangeulMode or Chab or WSung or WSung7)
|
|
cmp al,2 ;al=2 english
|
|
jz @f ;al=1 chohab
|
|
shl al,1 ;al=0 wansung
|
|
or al,HangeulMode
|
|
or [CodeStat],al
|
|
@@:
|
|
mov al, 0ffh ; [CHM001]
|
|
cmp [BilingCall], al ; [CHM001]
|
|
jz GoDirectSet ; [CHM001]
|
|
mov al,[CodeStat]
|
|
cmp [OldCodeStat],al
|
|
jz @f
|
|
GoDirectSet:
|
|
mov ah, 0 ; [CHM001]
|
|
mov [BilingCall], ah ; [CHM001]
|
|
or [KbMisc],RunningHot
|
|
or [KbStat],ReqEnvrChg
|
|
inc [VideoActive]
|
|
mov ah,0fh
|
|
int 10h
|
|
call ChgEnvrDo
|
|
dec [VideoActive]
|
|
and [KbStat],not ReqEnvrChg
|
|
and [KbMisc],not RunningHot
|
|
@@:
|
|
@pop ax,ds,es,di,si,dx,cx,bx
|
|
ChangeCodeRoutineRet:
|
|
ret
|
|
endif ;hdos60
|
|
|
|
|
|
if Hwin31Sw
|
|
;========================================================================;
|
|
; ;
|
|
; DOS INTERRUPT 2FH, 88H ;
|
|
; ;
|
|
;========================================================================;
|
|
; FUNCTION = Code stat conversion program
|
|
; INPUT : AH=88H
|
|
; AL=0:완성
|
|
; 1:조합
|
|
; 2:영문
|
|
; OUTPUT : none (cursor on/off)
|
|
; PROTECT : none
|
|
;------------------------------------------------------------------------
|
|
public int2f
|
|
SIS Db 3, 10
|
|
SISnext dd ?
|
|
dd 0
|
|
dd 0
|
|
dw offset IDP
|
|
IDPseg dw 0
|
|
|
|
IDP dw offset StartInst
|
|
Iseg dw 0
|
|
dw SizeInst
|
|
dd 0
|
|
dw 0
|
|
|
|
hWin31Flag db 0
|
|
VxdAddr dd 0
|
|
|
|
;hWin31Flag
|
|
ValidVxd = 00000001b
|
|
FullDosMode = 00000010b
|
|
OnMemReq = 00000100b
|
|
|
|
;------------------------------------------------------------------------
|
|
WinModeSet:
|
|
test [hWin31Flag],ValidVxd
|
|
jz WinOrg
|
|
test [CodeStat],HangeulMode
|
|
jz WinMemRel
|
|
mov bl,al
|
|
and bl,01111111b
|
|
test [hWin31Flag],FullDosMode
|
|
jz WinBox
|
|
call CmpModeVal
|
|
jz WinMemAlloc
|
|
WinMemRel:
|
|
call WinMem2
|
|
WinOrg:
|
|
call ModeSet2
|
|
WinModeSetRet:
|
|
ret
|
|
WinMemAlloc:
|
|
test [CodeStat],Chab or Wsung7
|
|
jnz @f
|
|
test [Card1st],HanCard
|
|
jnz WinMemRel
|
|
test [Card1st],DualMnt
|
|
jnz WinMemRel
|
|
@@:
|
|
call WinMem1
|
|
call ModeSet2
|
|
call Set64k
|
|
ret
|
|
WinBox:
|
|
cmp bl,60h
|
|
jz WinMode60
|
|
cmp bl,40h
|
|
jz WinModeSetRet
|
|
cmp bl,70h
|
|
jz WinModeSetRet
|
|
test [CodeStat],Chab or Wsung7
|
|
jnz @f
|
|
test [Card1st],HanCard
|
|
jnz WinMemRel
|
|
test [Card1st],DualMnt
|
|
jnz WinMemRel
|
|
@@:
|
|
push word ptr [CodeStat]
|
|
and [CodeStat],not HangeulMode
|
|
call WinMem2
|
|
call ModeSet2
|
|
pop ax
|
|
mov [CodeStat],al
|
|
or [KbStat],HanKeyinMode
|
|
and [CodeStat],not HangeulVideoMode
|
|
CALL callKBSE
|
|
ret
|
|
WinMode60:
|
|
call WinMem2
|
|
and al,10000000b
|
|
or al,12h
|
|
call ModeSet2
|
|
push es
|
|
xor ax,ax
|
|
mov es,ax
|
|
mov es:[rCrtMode],60h
|
|
mov es:[rRows],25-1
|
|
mov [MaxRows],25
|
|
mov [HjMenuLine],24
|
|
pop es
|
|
ret
|
|
|
|
callKBSE:
|
|
mov ah,[OrgHjStat]
|
|
or [HjStat],ah
|
|
and [KbStat],not (HEStat or JJStat)
|
|
mov [HanStat],0
|
|
mov [HjMenuStat],0
|
|
mov [HjMenuLine],24
|
|
RET
|
|
|
|
;------------------------------------------------------------------------
|
|
Int2f:
|
|
pushf
|
|
if WINNT
|
|
cmp ah,0aeh ; For NT 5.0
|
|
jnz Int2fh16xx
|
|
|
|
push ax
|
|
push bx
|
|
|
|
mov ax, 4f01h
|
|
xor bx, bx
|
|
int 2fh ;Check active code page
|
|
|
|
mov cs:[ActiveCodePage],bx
|
|
cmp cs:[ActiveCodePage], WanSungCP
|
|
jz @f
|
|
and cs:[KbStat],not HanKeyinMode
|
|
pop bx
|
|
pop ax
|
|
jmp Int2fh16xx
|
|
@@:
|
|
or cs:[KbStat],HanKeyinMode
|
|
pop bx
|
|
pop ax
|
|
Int2fh16xx:
|
|
endif
|
|
|
|
cmp ah,16h
|
|
jz @f
|
|
popf
|
|
jmp cs:[OldInt2f]
|
|
@@:
|
|
call cs:[OldInt2f]
|
|
cmp ax,1605h
|
|
jnz Int2fh1606
|
|
test dx,1
|
|
jnz @f
|
|
mov cs:[IDPSeg],cs
|
|
mov cs:[Iseg],cs
|
|
mov word ptr cs:[SISNext],bx
|
|
mov word ptr cs:[SISNext+2],es
|
|
mov bx,offset SIS
|
|
push cs
|
|
pop es
|
|
@@:
|
|
iret
|
|
Int2fh1606:
|
|
cmp ax,1606h
|
|
jnz @f
|
|
mov cs:[hWin31Flag],0
|
|
iret
|
|
@@:
|
|
cmp ax,1608h
|
|
jnz @f
|
|
call Int2fh1608
|
|
iret
|
|
@@:
|
|
iret
|
|
|
|
Int2fh1608:
|
|
@push ax,bx,di,es
|
|
xor di,di
|
|
mov es,di
|
|
mov ax,1684h
|
|
if WINNT
|
|
mov bx,0065h ; From Win97 mshbios.com
|
|
else
|
|
mov bx,0028h
|
|
endif
|
|
int 2fh
|
|
mov word ptr cs:[VxdAddr],di
|
|
mov word ptr cs:[VxdAddr+2],es
|
|
mov ax,es
|
|
or ax,di
|
|
jz @f
|
|
mov ax,cs
|
|
mov es,ax
|
|
lea bx,cs:[Win31Proc]
|
|
xor ax,ax
|
|
call cs:[VxdAddr]
|
|
cmp ax,0100h
|
|
jb @f
|
|
or cs:[hWin31Flag],ValidVxd
|
|
@@:
|
|
@pop es,di,bx,ax
|
|
ret
|
|
|
|
;------------------------------------------------------------------------
|
|
Win31Proc:
|
|
@push ax,bx,cx,dx,si,di,bp,ds,es
|
|
pushf
|
|
mov ax,cs
|
|
mov ds,ax
|
|
mov es,ax
|
|
cmp dx,0
|
|
jnz extTESet
|
|
TextmodeSet:
|
|
and [hWin31Flag],not FullDosMode
|
|
jmp @f
|
|
GrpSet:
|
|
or al,080h
|
|
int 10h
|
|
jmp Win31ProcRet
|
|
extTESet:
|
|
cmp dx,1
|
|
jnz CmpDx2
|
|
or [hWin31Flag],FullDosMode
|
|
@@:
|
|
mov ah,0fh
|
|
int 10h ; get page #
|
|
mov bl,al
|
|
and bl,01111111b
|
|
call CmpModeVal
|
|
jnz GrpSet
|
|
push ax
|
|
or [KbMisc],RunningHot
|
|
or [KbStat],ReqEnvrChg
|
|
inc [VideoActive]
|
|
call SaveCodeBuffer
|
|
pop ax
|
|
mov ah,00h
|
|
int 10h
|
|
call RestoreCodeBuffer
|
|
dec [VideoActive]
|
|
and [KbStat],not ReqEnvrChg
|
|
and [KbMisc],not RunningHot
|
|
jmp Win31ProcRet
|
|
CmpDx2:
|
|
cmp dx,2
|
|
jnz @f
|
|
or [hWin31Flag],FullDosMode
|
|
jmp Win31ProcRet
|
|
@@:
|
|
cmp dx,3
|
|
jnz Win31ProcRet
|
|
and [hWin31Flag],not FullDosMode
|
|
jmp Win31ProcRet
|
|
Win31ProcRet:
|
|
popf
|
|
@pop es,ds,bp,di,si,dx,cx,bx,ax
|
|
retf
|
|
|
|
Set64k:
|
|
@push ax,dx
|
|
test [Card1st],00001100b
|
|
jz @f
|
|
mov dx,03ceh
|
|
mov al,06h
|
|
out dx,al
|
|
inc dx
|
|
in al,dx
|
|
test al,00001100b
|
|
jnz @f
|
|
or al,00000100b
|
|
out dx,al
|
|
@@:
|
|
@pop dx,ax
|
|
ret
|
|
WinMem1:
|
|
push ax
|
|
mov ax,0001
|
|
call [VxdAddr]
|
|
or [hWin31Flag],OnMemReq
|
|
pop ax
|
|
@@:
|
|
ret
|
|
WinMem2:
|
|
test [hWin31Flag],OnMemReq
|
|
jz @f
|
|
push ax
|
|
mov ax,0002
|
|
call [VxdAddr]
|
|
and [hWin31Flag],not OnMemReq
|
|
pop ax
|
|
@@:
|
|
ret
|
|
|
|
CmpModeVal:
|
|
cmp bl,2
|
|
jz @f
|
|
cmp bl,3
|
|
jz @f
|
|
cmp bl,7
|
|
@@:
|
|
ret
|
|
;=======================================================================
|
|
endif ; Hwin31Sw
|
|
|
|
public EngFont, VgaService, ChgCode, VideoEnd, HotKeySrv ; for .MAP file
|
|
|
|
HotKeySrv:
|
|
INCLUDE DUAL.INC
|
|
|
|
EngFont label byte
|
|
;INCLUDE ENG.PAT
|
|
INCLUDE ascii.inc
|
|
|
|
VgaService:
|
|
INCLUDE VGA.INC
|
|
|
|
ChgCode:
|
|
INCLUDE CHAB.INC
|
|
|
|
VideoEnd label byte
|
|
|
|
CODE ENDS
|
|
END
|
|
|