1406 lines
27 KiB
C
1406 lines
27 KiB
C
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dndispjp.c
|
|
|
|
Abstract:
|
|
|
|
DOS-based NT setup program video display routines for DOS/V.
|
|
|
|
Author:
|
|
|
|
Ted Miller (tedm) 30-March-1992
|
|
|
|
Revision History:
|
|
|
|
Originally dndisp.c.
|
|
Modified 18-Feb-1995 (tedm) for DOS/V support, based on NT-J team's
|
|
adaptation.
|
|
|
|
--*/
|
|
|
|
#ifdef JAPAN
|
|
|
|
#ifdef DOS_V
|
|
|
|
#include "winnt.h"
|
|
#include <string.h>
|
|
|
|
|
|
#define SCREEN_WIDTH 80
|
|
#define SCREEN_HEIGHT 25
|
|
|
|
#define STATUS_HEIGHT 1
|
|
#define STATUS_LEFT_MARGIN 2
|
|
#define HEADER_HEIGHT 3
|
|
|
|
#define CHARACTER_MAX 256
|
|
|
|
#if NEC_98
|
|
extern
|
|
VOID
|
|
RestoreBootcode(VOID);
|
|
VOID
|
|
Screen_Buffer_Attr(
|
|
SHORT x,
|
|
SHORT y,
|
|
UCHAR attr
|
|
);
|
|
|
|
extern CursorOnFlag; // For Cursor OFF
|
|
#endif // NEC_98
|
|
|
|
//
|
|
// Display attributes
|
|
//
|
|
|
|
#if NEC_988
|
|
|
|
#define ATT_FG_RED (0x40 | 0x01)
|
|
#define ATT_FG_GREEN (0x80 | 0x01)
|
|
#define ATT_FG_BLUE (0x20 | 0x01)
|
|
#define ATT_FG_CYAN (ATT_FG_BLUE | ATT_FG_GREEN)
|
|
#define ATT_FG_MAGENTA (ATT_FG_RED | ATT_FG_BLUE)
|
|
#define ATT_FG_YELLOW (ATT_FG_RED | ATT_FG_GREEN)
|
|
#define ATT_FG_WHITE (ATT_FG_RED | ATT_FG_GREEN | ATT_FG_BLUE)
|
|
#define ATT_FG_BLACK (0x00 | 0x01)
|
|
#define ATT_REVERSE 0x05
|
|
#define ATT_BRINK 0x03
|
|
|
|
#define ATT_BG_RED 0x00
|
|
#define ATT_BG_GREEN 0x00
|
|
#define ATT_BG_BLUE 0x00
|
|
#define ATT_BG_CYAN 0x00
|
|
#define ATT_BG_MAGENTA 0x00
|
|
#define ATT_BG_YELLOW 0x00
|
|
#define ATT_BG_WHITE 0x00
|
|
#define ATT_BG_BLACK 0x00
|
|
|
|
#define ATT_FG_INTENSE 0x00
|
|
#define ATT_BG_INTENSE 0x00
|
|
|
|
#define DEFAULT_ATTRIBUTE (ATT_FG_CYAN | ATT_REVERSE)
|
|
#define STATUS_ATTRIBUTE (ATT_FG_WHITE | ATT_REVERSE)
|
|
#define EDIT_ATTRIBUTE (ATT_FG_WHITE | ATT_REVERSE)
|
|
#define EXITDLG_ATTRIBUTE (ATT_FG_WHITE | ATT_REVERSE)
|
|
#define GAUGE_ATTRIBUTE (ATT_FG_YELLOW | ATT_REVERSE)
|
|
|
|
#else // NEC_98
|
|
|
|
#define ATT_FG_BLACK 0
|
|
#define ATT_FG_BLUE 1
|
|
#define ATT_FG_GREEN 2
|
|
#define ATT_FG_CYAN 3
|
|
#define ATT_FG_RED 4
|
|
#define ATT_FG_MAGENTA 5
|
|
#define ATT_FG_YELLOW 6
|
|
#define ATT_FG_WHITE 7
|
|
|
|
#define ATT_BG_BLACK (ATT_FG_BLACK << 4)
|
|
#define ATT_BG_BLUE (ATT_FG_BLUE << 4)
|
|
#define ATT_BG_GREEN (ATT_FG_GREEN << 4)
|
|
#define ATT_BG_CYAN (ATT_FG_CYAN << 4)
|
|
#define ATT_BG_RED (ATT_FG_RED << 4)
|
|
#define ATT_BG_MAGENTA (ATT_FG_MAGENTA << 4)
|
|
#define ATT_BG_YELLOW (ATT_FG_YELLOW << 4)
|
|
#define ATT_BG_WHITE (ATT_FG_WHITE << 4)
|
|
|
|
#define ATT_FG_INTENSE 8
|
|
#define ATT_BG_INTENSE (ATT_FG_INTENSE << 4)
|
|
|
|
#define DEFAULT_ATTRIBUTE (ATT_FG_WHITE | ATT_BG_BLUE)
|
|
#define STATUS_ATTRIBUTE (ATT_FG_BLACK | ATT_BG_WHITE)
|
|
#define EDIT_ATTRIBUTE (ATT_FG_BLACK | ATT_BG_WHITE)
|
|
#define EXITDLG_ATTRIBUTE (ATT_FG_RED | ATT_BG_WHITE)
|
|
#if NEC_98
|
|
#define GAUGE_ATTRIBUTE (ATT_BG_YELLOW)
|
|
#else
|
|
#define GAUGE_ATTRIBUTE (ATT_BG_BLUE | ATT_FG_YELLOW | ATT_FG_INTENSE)
|
|
#endif // NEC_98
|
|
|
|
#endif // NEC_98
|
|
|
|
//
|
|
// This value gets initialized in DnInitializeDisplay.
|
|
//
|
|
#if NEC_98
|
|
|
|
#define SCREEN_BUFFER ((UCHAR _far *)0xa0000000) // Normal Mode Text Vram
|
|
|
|
#define SCREEN_BUFFER_CHR1(x,y) *((SCREEN_BUFFER + (2*((x)+(SCREEN_WIDTH*(y)))))+0)
|
|
#define SCREEN_BUFFER_CHR2(x,y) *((SCREEN_BUFFER + (2*((x)+(SCREEN_WIDTH*(y)))))+1)
|
|
UCHAR SCREEN_BUFFER_ATTRB[80][25];
|
|
BOOLEAN CursorIsActuallyOn;
|
|
|
|
#define IsANK(c) (!((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfe)))
|
|
|
|
#else // NEC_98
|
|
UCHAR _far *ScreenAddress;
|
|
#define SCREEN_BUFFER (ScreenAddress)
|
|
|
|
#define SCREEN_BUFFER_CHR(x,y) *(SCREEN_BUFFER + (2*((x)+(SCREEN_WIDTH*(y)))))
|
|
#define SCREEN_BUFFER_ATT(x,y) *(SCREEN_BUFFER + (2*((x)+(SCREEN_WIDTH*(y))))+1)
|
|
|
|
//
|
|
// Macro to update a char location from the Pseudo text RAM to the display.
|
|
//
|
|
#define UPDATE_SCREEN_BUFFER(x,y,z) DnpUpdateBuffer(&SCREEN_BUFFER_CHR(x,y),z)
|
|
|
|
BOOLEAN CursorIsActuallyOn;
|
|
|
|
//
|
|
// DBCS support
|
|
//
|
|
BOOLEAN DbcsTable[CHARACTER_MAX];
|
|
#define ISDBCS(chr) DbcsTable[(chr)]
|
|
#endif // NEC_98
|
|
|
|
#if NEC_98
|
|
#else // NEC_98
|
|
VOID
|
|
DnpInitializeDbcsTable(
|
|
VOID
|
|
);
|
|
#endif // NEC_98
|
|
|
|
//
|
|
// Make these near because they are used in _asm blocks
|
|
//
|
|
UCHAR _near CurrentAttribute;
|
|
UCHAR _near ScreenX;
|
|
UCHAR _near ScreenY;
|
|
|
|
BOOLEAN CursorOn;
|
|
|
|
#if NEC_98
|
|
#else // NEC_98
|
|
UCHAR _far *
|
|
DnpGetVideoAddress(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
DnpUpdateBuffer(
|
|
UCHAR _far *VideoAddress,
|
|
int CharNum
|
|
);
|
|
#endif // NEC_98
|
|
|
|
VOID
|
|
DnpBlankScreenArea(
|
|
IN UCHAR Attribute,
|
|
IN UCHAR Left,
|
|
IN UCHAR Right,
|
|
IN UCHAR Top,
|
|
IN UCHAR Bottom
|
|
);
|
|
|
|
|
|
VOID
|
|
DnInitializeDisplay(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Put the display in a known state (80x25 standard text mode) and
|
|
initialize the display package.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
#if NEC_98
|
|
#else // NEC_98
|
|
ScreenAddress = DnpGetVideoAddress();
|
|
DnpInitializeDbcsTable();
|
|
#endif // NEC_98
|
|
CurrentAttribute = DEFAULT_ATTRIBUTE;
|
|
CursorOn = FALSE;
|
|
|
|
//
|
|
// Set the display to standard 80x25 mode
|
|
//
|
|
#if NEC_98
|
|
_asm {
|
|
mov ax,0a00h // set CRT mode to 80 x 25
|
|
int 18h
|
|
push ds
|
|
push cx
|
|
push bx
|
|
mov ax,0a800h
|
|
mov ds,ax
|
|
mov cx,3fffh
|
|
blp:
|
|
mov bx,cx
|
|
mov ds:[bx],0
|
|
loop blp
|
|
mov ax,0b000h
|
|
mov ds,ax
|
|
mov cx,3fffh
|
|
rlp:
|
|
mov bx,cx
|
|
mov ds:[bx],0
|
|
loop rlp
|
|
mov ax,0b800h
|
|
mov ds,ax
|
|
mov cx,3fffh
|
|
glp:
|
|
mov bx,cx
|
|
mov ds:[bx],0
|
|
loop glp
|
|
mov ax,0e000h
|
|
mov ds,ax
|
|
mov cx,3fffh
|
|
ilp:
|
|
mov bx,cx
|
|
mov ds:[bx],0
|
|
loop ilp
|
|
|
|
mov ah,042h
|
|
mov ch,0c0h
|
|
int 18h
|
|
mov ax,8
|
|
out 68h,al
|
|
mov ax,1
|
|
out 6ah,al
|
|
mov ax,41h
|
|
out 6ah,al
|
|
mov ax,0dh
|
|
out 0a2h,al
|
|
pop bx
|
|
pop cx
|
|
pop ds
|
|
}
|
|
#else // NEC_98
|
|
_asm {
|
|
mov ax,3 // set video mode to 3
|
|
int 10h
|
|
}
|
|
#endif // NEC_98
|
|
//
|
|
// Clear the entire screen
|
|
//
|
|
|
|
DnpBlankScreenArea(CurrentAttribute,0,SCREEN_WIDTH-1,0,SCREEN_HEIGHT-1);
|
|
DnPositionCursor(0,0);
|
|
|
|
//
|
|
// Shut the cursor off.
|
|
//
|
|
#if NEC_98
|
|
_asm {
|
|
mov ah,12h // function -- cursor off
|
|
int 18h
|
|
}
|
|
#else // NEC_98
|
|
_asm {
|
|
mov ah,2 // function -- position cursor
|
|
mov bh,0 // display page
|
|
mov dh,SCREEN_HEIGHT
|
|
mov dl,0
|
|
int 10h
|
|
}
|
|
#endif // NEC_98
|
|
|
|
CursorIsActuallyOn = FALSE;
|
|
}
|
|
|
|
|
|
VOID
|
|
DnClearClientArea(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Clear the client area of the screen, ie, the area between the header
|
|
and status line.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DnpBlankScreenArea( CurrentAttribute,
|
|
0,
|
|
SCREEN_WIDTH-1,
|
|
HEADER_HEIGHT,
|
|
SCREEN_HEIGHT - STATUS_HEIGHT - 1
|
|
);
|
|
|
|
DnPositionCursor(0,HEADER_HEIGHT);
|
|
}
|
|
|
|
|
|
VOID
|
|
DnSetGaugeAttribute(
|
|
IN BOOLEAN Set
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Prepare for drawing the thermometer portion of a gas gauge.
|
|
|
|
Arguments:
|
|
|
|
Set - if TRUE, prepare for drawing the thermometer. If FALSE, restore
|
|
the state for normal drawing.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
static UCHAR SavedAttribute = 0;
|
|
|
|
if(Set) {
|
|
if(!SavedAttribute) {
|
|
SavedAttribute = CurrentAttribute;
|
|
CurrentAttribute = GAUGE_ATTRIBUTE;
|
|
}
|
|
} else {
|
|
if(SavedAttribute) {
|
|
CurrentAttribute = SavedAttribute;
|
|
SavedAttribute = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
DnPositionCursor(
|
|
IN UCHAR X,
|
|
IN UCHAR Y
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Position the cursor.
|
|
|
|
Arguments:
|
|
|
|
X,Y - cursor coords
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
#if NEC_98
|
|
USHORT Cursor;
|
|
#endif // NEC_98
|
|
|
|
if(X >= SCREEN_WIDTH) {
|
|
X = 0;
|
|
Y++;
|
|
}
|
|
|
|
if(Y >= SCREEN_HEIGHT) {
|
|
Y = HEADER_HEIGHT;
|
|
}
|
|
|
|
ScreenX = X;
|
|
ScreenY = Y;
|
|
|
|
//
|
|
// Invoke BIOS
|
|
//
|
|
|
|
#if NEC_98
|
|
Cursor = ((ScreenX + (SCREEN_WIDTH * ScreenY)) * 2 + (USHORT)SCREEN_BUFFER);
|
|
if(CursorOnFlag) {
|
|
_asm {
|
|
mov ah,13h // function -- position cursor
|
|
mov dx,Cursor
|
|
int 18h
|
|
|
|
mov ah,11h // function -- cursor on
|
|
int 18h
|
|
}
|
|
CursorIsActuallyOn = TRUE;
|
|
} else {
|
|
_asm {
|
|
mov ah,13h // function -- position cursor
|
|
mov dx,Cursor
|
|
int 18h
|
|
|
|
mov ah,12h // function -- cursor off
|
|
int 18h
|
|
}
|
|
CursorIsActuallyOn = FALSE;
|
|
}
|
|
#else // NEC_98
|
|
_asm {
|
|
mov ah,2 // function -- position cursor
|
|
mov bh,0 // display page
|
|
mov dh,ScreenY
|
|
mov dl,ScreenX
|
|
int 10h
|
|
}
|
|
|
|
CursorIsActuallyOn = TRUE;
|
|
#endif // NEC_98
|
|
}
|
|
|
|
|
|
VOID
|
|
DnWriteChar(
|
|
IN CHAR chr
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Write a character in the current attribute at the current position.
|
|
|
|
Arguments:
|
|
|
|
chr - Character to write
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if(chr == '\n') {
|
|
ScreenX = 0;
|
|
ScreenY++;
|
|
return;
|
|
}
|
|
#if NEC_98
|
|
if ( ( ScreenX < SCREEN_WIDTH ) && ( ScreenY < SCREEN_HEIGHT ) ) {
|
|
SCREEN_BUFFER_CHR1(ScreenX,ScreenY) = chr;
|
|
SCREEN_BUFFER_CHR2(ScreenX,ScreenY) = 0x00;
|
|
Screen_Buffer_Attr(ScreenX,ScreenY, CurrentAttribute);
|
|
}
|
|
|
|
if(!CursorOn && CursorIsActuallyOn) {
|
|
CursorIsActuallyOn = FALSE;
|
|
_asm {
|
|
mov ah,12h // function -- cursor off
|
|
int 18h
|
|
}
|
|
}
|
|
#else // NEC_98
|
|
|
|
if ( ( ScreenX < SCREEN_WIDTH ) && ( ScreenY < SCREEN_HEIGHT ) ) {
|
|
SCREEN_BUFFER_CHR(ScreenX,ScreenY) = chr;
|
|
SCREEN_BUFFER_ATT(ScreenX,ScreenY) = CurrentAttribute;
|
|
UPDATE_SCREEN_BUFFER(ScreenX, ScreenY,1);
|
|
}
|
|
|
|
//
|
|
// shut cursor off if necessary
|
|
//
|
|
if(!CursorOn && CursorIsActuallyOn) {
|
|
CursorIsActuallyOn = FALSE;
|
|
_asm {
|
|
mov ah,2 // function -- position cursor
|
|
mov bh,0 // display page
|
|
mov dh,SCREEN_HEIGHT
|
|
mov dl,0
|
|
int 10h
|
|
}
|
|
}
|
|
#endif // NEC_98
|
|
}
|
|
|
|
|
|
VOID
|
|
DnWriteWChar(
|
|
#if NEC_98
|
|
IN PUCHAR chr
|
|
#else // NEC_98
|
|
IN PCHAR chr
|
|
#endif // NEC_98
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Write a DBCS character in the current attribute at the current position.
|
|
|
|
Arguments:
|
|
|
|
wchr - DBCS Character to write
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
#if NEC_98
|
|
PUCHAR code = chr;
|
|
UCHAR moji_1st,moji_2nd;
|
|
USHORT sjis;
|
|
|
|
moji_1st = *code;
|
|
code++;
|
|
moji_2nd = *code;
|
|
code++;
|
|
|
|
// Make Shift JIS
|
|
sjis = (USHORT)moji_1st;
|
|
sjis = (sjis << 8) + (USHORT)moji_2nd;
|
|
|
|
// Shift JIS -> JIS code exchange
|
|
moji_1st -= ((moji_1st <= 0x9f) ? 0x71 : 0xb1);
|
|
moji_1st = (UCHAR)(moji_1st * 2 + 1);
|
|
if (moji_2nd > 0x7f){ moji_2nd--; }
|
|
if (moji_2nd >= 0x9e){ moji_2nd -= 0x7d; moji_1st++; }
|
|
else { moji_2nd -= 0x1f; }
|
|
|
|
// Create custom JIS code
|
|
moji_1st += 0x60;
|
|
|
|
// Grpah Mode Check
|
|
if (memcmp(&sjis,"\340\340",2) == 0){
|
|
SCREEN_BUFFER_CHR1(ScreenX,ScreenY) = (UCHAR)(sjis >> 8);
|
|
SCREEN_BUFFER_CHR2(ScreenX,ScreenY) = 0x00;
|
|
Screen_Buffer_Attr(ScreenX,ScreenY, CurrentAttribute);
|
|
SCREEN_BUFFER_CHR1(ScreenX+1,ScreenY) = (UCHAR)(sjis & 0xff);
|
|
SCREEN_BUFFER_CHR2(ScreenX+1,ScreenY) = 0x00;
|
|
Screen_Buffer_Attr(ScreenX+1,ScreenY, CurrentAttribute);
|
|
}
|
|
else {
|
|
SCREEN_BUFFER_CHR1(ScreenX,ScreenY) = moji_1st;
|
|
SCREEN_BUFFER_CHR2(ScreenX,ScreenY) = moji_2nd;
|
|
Screen_Buffer_Attr(ScreenX,ScreenY, CurrentAttribute);
|
|
SCREEN_BUFFER_CHR1(ScreenX+1,ScreenY) = (UCHAR)(moji_1st - 0x80);
|
|
SCREEN_BUFFER_CHR2(ScreenX+1,ScreenY) = moji_2nd;
|
|
Screen_Buffer_Attr(ScreenX+1,ScreenY, CurrentAttribute);
|
|
}
|
|
//
|
|
// shut cursor off if necessary
|
|
//
|
|
if(!CursorOn && CursorIsActuallyOn) {
|
|
CursorIsActuallyOn = FALSE;
|
|
_asm {
|
|
mov ah,12h // function -- cursor off
|
|
int 18h
|
|
}
|
|
}
|
|
#else // NEC_98
|
|
SCREEN_BUFFER_CHR(ScreenX,ScreenY) = *chr;
|
|
SCREEN_BUFFER_ATT(ScreenX,ScreenY) = CurrentAttribute;
|
|
SCREEN_BUFFER_CHR(ScreenX+1,ScreenY) = *(chr+1);
|
|
SCREEN_BUFFER_ATT(ScreenX+1,ScreenY) = CurrentAttribute;
|
|
UPDATE_SCREEN_BUFFER(ScreenX,ScreenY,2);
|
|
|
|
//
|
|
// shut cursor off if necessary
|
|
//
|
|
if(!CursorOn && CursorIsActuallyOn) {
|
|
CursorIsActuallyOn = FALSE;
|
|
_asm {
|
|
mov ah,2 // function -- position cursor
|
|
mov bh,0 // display page
|
|
mov dh,SCREEN_HEIGHT // screen height
|
|
mov dl,0
|
|
int 10h
|
|
}
|
|
}
|
|
#endif // NEC_98
|
|
}
|
|
|
|
|
|
VOID
|
|
DnWriteString(
|
|
IN PCHAR String
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Write a string on the client area in the current position and
|
|
adjust the current position. The string is written in the current
|
|
attribute.
|
|
|
|
Arguments:
|
|
|
|
String - null terminated string to write.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PCHAR p;
|
|
|
|
#if NEC_98
|
|
for(p=String; *p; p++) {
|
|
if(!IsANK((UCHAR)*p)) {
|
|
DnWriteWChar((PUCHAR)p);
|
|
p++ ;
|
|
ScreenX += 2 ;
|
|
} else {
|
|
DnWriteChar(*p);
|
|
if(*p != '\n') {
|
|
ScreenX++;
|
|
}
|
|
}
|
|
}
|
|
#else // NEC_98
|
|
|
|
for(p=String; *p; p++) {
|
|
if(ISDBCS((UCHAR)*p)) {
|
|
DnWriteWChar(p);
|
|
p++;
|
|
ScreenX += 2;
|
|
} else {
|
|
DnWriteChar(*p);
|
|
if(*p != '\n') {
|
|
ScreenX++;
|
|
}
|
|
}
|
|
}
|
|
#endif // NEC_98
|
|
}
|
|
|
|
|
|
VOID
|
|
DnWriteStatusText(
|
|
IN PCHAR FormatString OPTIONAL,
|
|
...
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Update the status area
|
|
|
|
Arguments:
|
|
|
|
FormatString - if present, supplies a printf format string for the
|
|
rest of the arguments. Otherwise the status area is cleared out.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
va_list arglist;
|
|
static CHAR String[SCREEN_WIDTH+1];
|
|
int StringLength;
|
|
UCHAR SavedAttribute;
|
|
|
|
//
|
|
// First, clear out the status area.
|
|
//
|
|
|
|
DnpBlankScreenArea( STATUS_ATTRIBUTE,
|
|
0,
|
|
SCREEN_WIDTH-1,
|
|
SCREEN_HEIGHT-STATUS_HEIGHT,
|
|
SCREEN_HEIGHT-1
|
|
);
|
|
|
|
if(FormatString) {
|
|
|
|
va_start(arglist,FormatString);
|
|
StringLength = vsnprintf(String,sizeof(String),FormatString,arglist);
|
|
String[sizeof(String)-1] = '\0';
|
|
|
|
SavedAttribute = CurrentAttribute;
|
|
CurrentAttribute = STATUS_ATTRIBUTE;
|
|
|
|
DnPositionCursor(STATUS_LEFT_MARGIN,SCREEN_HEIGHT - STATUS_HEIGHT);
|
|
|
|
DnWriteString(String);
|
|
|
|
CurrentAttribute = SavedAttribute;
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
DnSetCopyStatusText(
|
|
IN PCHAR Caption,
|
|
IN PCHAR Filename
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Write or erase a copying message in the lower right part of the screen.
|
|
|
|
Arguments:
|
|
|
|
Filename - name of file currently being copied. If NULL, erases the
|
|
copy status area.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
unsigned CopyStatusAreaLen;
|
|
CHAR StatusText[100];
|
|
|
|
//
|
|
// The 13 is for 8.3 and a space
|
|
//
|
|
|
|
CopyStatusAreaLen = strlen(Caption) + 13;
|
|
|
|
//
|
|
// First erase the status area.
|
|
//
|
|
|
|
DnpBlankScreenArea( STATUS_ATTRIBUTE,
|
|
(UCHAR)(SCREEN_WIDTH - CopyStatusAreaLen),
|
|
SCREEN_WIDTH - 1,
|
|
SCREEN_HEIGHT - STATUS_HEIGHT,
|
|
SCREEN_HEIGHT - 1
|
|
);
|
|
|
|
if(Filename) {
|
|
|
|
UCHAR SavedAttribute;
|
|
UCHAR SavedX,SavedY;
|
|
|
|
SavedAttribute = CurrentAttribute;
|
|
SavedX = ScreenX;
|
|
SavedY = ScreenY;
|
|
|
|
CurrentAttribute = STATUS_ATTRIBUTE;
|
|
DnPositionCursor((UCHAR)(SCREEN_WIDTH-CopyStatusAreaLen),SCREEN_HEIGHT-1);
|
|
|
|
memset(StatusText,0,sizeof(StatusText));
|
|
strcpy(StatusText,Caption);
|
|
strncpy(StatusText + strlen(StatusText),Filename,12);
|
|
|
|
DnWriteString(StatusText);
|
|
|
|
CurrentAttribute = SavedAttribute;
|
|
ScreenX = SavedX;
|
|
ScreenY = SavedY;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
DnStartEditField(
|
|
IN BOOLEAN CreateField,
|
|
IN UCHAR X,
|
|
IN UCHAR Y,
|
|
IN UCHAR W
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets up the display package to start handling an edit field.
|
|
|
|
Arguments:
|
|
|
|
CreateField - if TRUE, caller is starting an edit field interaction.
|
|
If FALSE, he is ending one.
|
|
|
|
X,Y,W - supply coords and width in chars of the edit field.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
static UCHAR SavedAttribute = 255;
|
|
|
|
CursorOn = CreateField;
|
|
|
|
if(CreateField) {
|
|
|
|
if(SavedAttribute == 255) {
|
|
SavedAttribute = CurrentAttribute;
|
|
CurrentAttribute = EDIT_ATTRIBUTE;
|
|
}
|
|
|
|
DnpBlankScreenArea(EDIT_ATTRIBUTE,X,(UCHAR)(X+W-1),Y,Y);
|
|
|
|
} else {
|
|
|
|
if(SavedAttribute != 255) {
|
|
CurrentAttribute = SavedAttribute;
|
|
SavedAttribute = 255;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
DnExitDialog(
|
|
VOID
|
|
)
|
|
{
|
|
unsigned W,H,X,Y,i;
|
|
PUCHAR CharSave;
|
|
PUCHAR AttSave;
|
|
ULONG Key,ValidKeys[3] = { ASCI_CR,DN_KEY_F3,0 };
|
|
UCHAR SavedX,SavedY,SavedAttribute;
|
|
BOOLEAN SavedCursorState = CursorOn;
|
|
|
|
SavedAttribute = CurrentAttribute;
|
|
CurrentAttribute = EXITDLG_ATTRIBUTE;
|
|
|
|
SavedX = ScreenX;
|
|
SavedY = ScreenY;
|
|
|
|
//
|
|
// Shut the cursor off.
|
|
//
|
|
CursorIsActuallyOn = FALSE;
|
|
CursorOn = FALSE;
|
|
#if NEC_98
|
|
_asm {
|
|
mov ah,12h // function -- cursor off
|
|
int 18h
|
|
}
|
|
#else // NEC_98
|
|
_asm {
|
|
mov ah,2 // function -- position cursor
|
|
mov bh,0 // display page
|
|
mov dh,SCREEN_HEIGHT
|
|
mov dl,0
|
|
int 10h
|
|
}
|
|
#endif // NEC_98
|
|
|
|
//
|
|
// Count lines in the dialog and determine its width.
|
|
//
|
|
for(H=0; DnsExitDialog.Strings[H]; H++);
|
|
W = strlen(DnsExitDialog.Strings[0]);
|
|
#if NEC_98
|
|
W += 2;
|
|
#endif // NEC_98
|
|
|
|
//
|
|
// allocate two buffers for character save and attribute save
|
|
//
|
|
#if NEC_98
|
|
CharSave = MALLOC((W*H+2)*2,TRUE);
|
|
AttSave = MALLOC((W*H+2)*2,TRUE);
|
|
#else // NEC_98
|
|
CharSave = MALLOC(W*H,TRUE);
|
|
AttSave = MALLOC(W*H,TRUE);
|
|
#endif // NEC_98
|
|
|
|
//
|
|
// save the screen patch
|
|
//
|
|
#if NEC_98
|
|
for(Y=0; Y<H; Y++) {
|
|
for(X=0; X < (W+2) ;X++) {
|
|
|
|
UCHAR attr,chr1,chr2;
|
|
UCHAR x,y;
|
|
|
|
x = (UCHAR)(X + (DnsExitDialog.X - 1));
|
|
y = (UCHAR)(Y + DnsExitDialog.Y);
|
|
|
|
chr1 = SCREEN_BUFFER_CHR1(x,y);
|
|
chr2 = SCREEN_BUFFER_CHR2(x,y);
|
|
attr = SCREEN_BUFFER_ATTRB[x][y];
|
|
|
|
CharSave[(Y*W*2)+(X*2)] = chr1;
|
|
CharSave[(Y*W*2)+(X*2+1)] = chr2;
|
|
AttSave [(Y*W*2)+(X*2)] = attr;
|
|
|
|
if((X == 0) && (chr2 != 0)){
|
|
SCREEN_BUFFER_CHR1(x,y) = ' ';
|
|
SCREEN_BUFFER_CHR2(x,y) = 0x00;
|
|
}
|
|
if((X == (W-1)) && (chr2 != 0)){
|
|
if(((CharSave[(Y*W*2)+((X-1)*2+0)] - (UCHAR)0x80) == chr1) &&
|
|
( CharSave[(Y*W*2)+((X-1)*2+1)] == chr2)){
|
|
SCREEN_BUFFER_CHR1(x,y) = ' ';
|
|
SCREEN_BUFFER_CHR2(x,y) = 0x00;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#else // NEC_98
|
|
for(Y=0; Y<H; Y++) {
|
|
for(X=0; X<W; X++) {
|
|
|
|
UCHAR att,chr;
|
|
UCHAR x,y;
|
|
|
|
x = (UCHAR)(X + DnsExitDialog.X);
|
|
y = (UCHAR)(Y + DnsExitDialog.Y);
|
|
|
|
chr = SCREEN_BUFFER_CHR(x,y);
|
|
att = SCREEN_BUFFER_ATT(x,y);
|
|
|
|
CharSave[Y*W+X] = chr;
|
|
AttSave[Y*W+X] = att;
|
|
}
|
|
}
|
|
#endif // NEC_98
|
|
|
|
//
|
|
// Put up the dialog
|
|
//
|
|
|
|
for(i=0; i<H; i++) {
|
|
DnPositionCursor(DnsExitDialog.X,(UCHAR)(DnsExitDialog.Y+i));
|
|
DnWriteString(DnsExitDialog.Strings[i]);
|
|
}
|
|
|
|
CurrentAttribute = SavedAttribute;
|
|
|
|
//
|
|
// Wait for a valid keypress
|
|
//
|
|
|
|
Key = DnGetValidKey(ValidKeys);
|
|
if(Key == DN_KEY_F3) {
|
|
#if NEC_98
|
|
//
|
|
// On floppyless setup if user have canceled setup or setup be stopped
|
|
// by error occurred,previous OS can't boot to be written boot code
|
|
// and boot loader.
|
|
//
|
|
RestoreBootcode();
|
|
#endif // NEC_98
|
|
DnExit(1);
|
|
}
|
|
|
|
//
|
|
// Restore the patch
|
|
//
|
|
#if NEC_98
|
|
for(Y=0; Y<H; Y++) {
|
|
for(X=0; X < (W+2); X++) {
|
|
|
|
UCHAR attr,chr1,chr2;
|
|
UCHAR x,y;
|
|
|
|
x = (UCHAR)(X + (DnsExitDialog.X - 1));
|
|
y = (UCHAR)(Y + DnsExitDialog.Y);
|
|
|
|
chr1 = CharSave[(Y*W*2)+(X*2)];
|
|
chr2 = CharSave[(Y*W*2)+(X*2+1)];
|
|
attr = AttSave [(Y*W*2)+(X*2)];
|
|
|
|
SCREEN_BUFFER_CHR1(x,y) = chr1;
|
|
SCREEN_BUFFER_CHR2(x,y) = chr2;
|
|
Screen_Buffer_Attr(x,y, attr);
|
|
}
|
|
}
|
|
#else // NEC_98
|
|
for(Y=0; Y<H; Y++) {
|
|
for(X=0; X<W; X++) {
|
|
|
|
UCHAR att,chr;
|
|
UCHAR x,y;
|
|
|
|
x = (UCHAR)(X + DnsExitDialog.X);
|
|
y = (UCHAR)(Y + DnsExitDialog.Y);
|
|
|
|
chr = CharSave[Y*W+X];
|
|
att = AttSave[Y*W+X];
|
|
|
|
SCREEN_BUFFER_CHR(x,y) = chr;
|
|
SCREEN_BUFFER_ATT(x,y) = att;
|
|
|
|
if((0 == X) && ISDBCS((UCHAR)SCREEN_BUFFER_CHR(x-1,y))) {
|
|
UPDATE_SCREEN_BUFFER(x-1,y,2);
|
|
} else if (ISDBCS((UCHAR)chr)) {
|
|
X++ ;
|
|
x = (UCHAR)(X + DnsExitDialog.X);
|
|
y = (UCHAR)(Y + DnsExitDialog.Y);
|
|
chr = CharSave[Y*W+X];
|
|
att = AttSave[Y*W+X];
|
|
SCREEN_BUFFER_CHR(x,y) = chr;
|
|
SCREEN_BUFFER_ATT(x,y) = att;
|
|
UPDATE_SCREEN_BUFFER(x-1,y,2);
|
|
} else {
|
|
UPDATE_SCREEN_BUFFER(x,y,1);
|
|
}
|
|
}
|
|
}
|
|
#endif // NEC_98
|
|
|
|
FREE(CharSave);
|
|
FREE(AttSave);
|
|
|
|
CursorOn = SavedCursorState;
|
|
|
|
if(CursorOn) {
|
|
DnPositionCursor(SavedX,SavedY);
|
|
} else {
|
|
ScreenX = SavedX;
|
|
ScreenY = SavedY;
|
|
#if NEC_98
|
|
_asm {
|
|
mov ah,12h // function -- cursor off
|
|
int 18h
|
|
}
|
|
#else // NEC_98
|
|
_asm {
|
|
mov ah,2
|
|
mov bh,0
|
|
mov dh,SCREEN_HEIGHT;
|
|
mov dl,0
|
|
int 10h
|
|
}
|
|
#endif // NEC_98
|
|
CursorIsActuallyOn = FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Internal support routines
|
|
//
|
|
VOID
|
|
DnpBlankScreenArea(
|
|
IN UCHAR Attribute,
|
|
IN UCHAR Left,
|
|
IN UCHAR Right,
|
|
IN UCHAR Top,
|
|
IN UCHAR Bottom
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Invoke the BIOS to blank a region of the screen.
|
|
|
|
Arguments:
|
|
|
|
Attribute - screen attribute to use to blank the region
|
|
|
|
Left,Right,Top,Bottom - coords of region to blank
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
UCHAR x,y;
|
|
|
|
#if NEC_98
|
|
for(y=Top; y<=Bottom; y++) {
|
|
for(x=Left; x<=Right; x++) {
|
|
SCREEN_BUFFER_CHR1(x,y) = ' ';
|
|
SCREEN_BUFFER_CHR2(x,y) = 0x00;
|
|
Screen_Buffer_Attr(x,y, Attribute);
|
|
}
|
|
}
|
|
#else // NEC_98
|
|
for(y=Top; y<=Bottom; y++) {
|
|
for(x=Left; x<=Right; x++) {
|
|
SCREEN_BUFFER_CHR(x,y) = ' ';
|
|
SCREEN_BUFFER_ATT(x,y) = Attribute;
|
|
UPDATE_SCREEN_BUFFER(x,y,1);
|
|
}
|
|
}
|
|
#endif // NEC_98
|
|
}
|
|
|
|
|
|
#if NEC_98
|
|
#else // NEC_98
|
|
|
|
//
|
|
// Disable 4035 warning - no return value, since
|
|
// the register state is set correctly with the
|
|
// required return value
|
|
//
|
|
|
|
#pragma warning( disable : 4035 )
|
|
|
|
UCHAR _far *
|
|
DnpGetVideoAddress(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function retrieves the location of the Video Text Ram if one exists,
|
|
else will retrieve the location of the Pseudo (virtual) Text Ram.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Either the Video Text RAM or Pseudo Text RAM address.
|
|
|
|
--*/
|
|
|
|
{
|
|
_asm {
|
|
push es
|
|
push di
|
|
mov ax, 0b800h
|
|
mov es, ax
|
|
xor di, di
|
|
mov ax, 0fe00h
|
|
int 10h
|
|
mov dx, es
|
|
mov ax, di
|
|
pop di
|
|
pop es
|
|
}
|
|
}
|
|
|
|
|
|
UCHAR _far *
|
|
DnpGetDbcsTable(
|
|
VOID
|
|
)
|
|
{
|
|
_asm {
|
|
push ds
|
|
push si
|
|
mov ax, 06300h
|
|
int 21h
|
|
mov dx, ds
|
|
mov ax, si
|
|
pop si
|
|
pop ds
|
|
}
|
|
}
|
|
|
|
//
|
|
// Reset the 4035 warning state back to the
|
|
// default state
|
|
//
|
|
#pragma warning( default : 4035 )
|
|
|
|
|
|
VOID
|
|
DnpUpdateBuffer(
|
|
UCHAR _far *VideoAddress,
|
|
int CharNum
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Updates one character in the Pseudo Text RAM to the display. This
|
|
function will have NO effect if the address points to the actual
|
|
text RAM, usually B800:0000H+ in US mode.
|
|
|
|
Arguments:
|
|
|
|
The address location of where the character is in the text RAM.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
_asm {
|
|
push es
|
|
push di
|
|
mov ax, word ptr 6[bp]
|
|
mov es, ax
|
|
mov di, word ptr 4[bp]
|
|
mov cx, CharNum
|
|
mov ax, 0ff00h
|
|
int 10h
|
|
pop di
|
|
pop es
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
DnpInitializeDbcsTable(
|
|
VOID
|
|
)
|
|
{
|
|
UCHAR _far *p;
|
|
UCHAR _far *Table;
|
|
int i;
|
|
|
|
Table = DnpGetDbcsTable();
|
|
for(p=Table; *p; p+=2) {
|
|
for(i = (int)*p; i<=(int)*(p+1); i++) {
|
|
DbcsTable[i] = TRUE;
|
|
}
|
|
}
|
|
}
|
|
#endif // NEC_98
|
|
|
|
int
|
|
DnGetGaugeChar(
|
|
VOID
|
|
)
|
|
{
|
|
#if NEC_98
|
|
return(0x20);
|
|
#else // NEC_98
|
|
return(0x14); //shaded square in cp932
|
|
#endif // NEC_98
|
|
}
|
|
#if NEC_98
|
|
VOID
|
|
Screen_Buffer_Attr(
|
|
SHORT x,
|
|
SHORT y,
|
|
UCHAR attr
|
|
)
|
|
{
|
|
UCHAR _far *pfgc;
|
|
SHORT fgc;
|
|
SHORT pc98col[] = { 0x5, 0x25, 0x85, 0x0a5, 0x045, 0x65, 0x0c5, 0x0e5};
|
|
|
|
|
|
SCREEN_BUFFER_ATTRB[x][y] = attr;
|
|
*((SCREEN_BUFFER + (2*((x)+(SCREEN_WIDTH*(y)))))+0x2000) = pc98col[((attr & 0x70) >> 4)];
|
|
pfgc = y * 80 * 16 + x;
|
|
fgc = attr & 0x0f;
|
|
|
|
_asm {
|
|
push ds
|
|
push cx
|
|
push bx
|
|
mov ax, 0a800h
|
|
mov ds,ax
|
|
mov cx,16
|
|
mov bx, pfgc
|
|
mov ax, fgc
|
|
and ax, 1;
|
|
mov al, 0
|
|
jz bfil
|
|
mov al,0ffh
|
|
|
|
bfil:
|
|
mov ds:[bx],al
|
|
add bx, 80
|
|
loop bfil
|
|
|
|
mov ax, 0b800h
|
|
mov ds,ax
|
|
mov cx,16
|
|
mov bx, pfgc
|
|
mov ax, fgc
|
|
and ax, 2;
|
|
mov al,0
|
|
jz gfil
|
|
mov al,0ffh
|
|
gfil:
|
|
mov ds:[bx],al
|
|
add bx, 80
|
|
loop gfil
|
|
|
|
mov ax, 0b000h
|
|
mov ds,ax
|
|
mov cx,16
|
|
mov bx, pfgc
|
|
mov ax, fgc
|
|
and ax, 4
|
|
mov al,0
|
|
jz rfil
|
|
mov al,0ffh
|
|
rfil:
|
|
mov ds:[bx],al
|
|
add bx, 80
|
|
loop rfil
|
|
|
|
mov ax, 0e000h
|
|
mov ds,ax
|
|
mov cx,16
|
|
mov bx, pfgc
|
|
mov ax, fgc
|
|
and ax, 8
|
|
mov al,0
|
|
jz ifil
|
|
mov al,0ffh
|
|
ifil:
|
|
mov ds:[bx],0ffh
|
|
add bx, 80
|
|
loop ifil
|
|
|
|
pop bx
|
|
pop cx
|
|
pop ds
|
|
}
|
|
|
|
|
|
}
|
|
|
|
int
|
|
WriteBackGrounf(
|
|
SHORT color
|
|
)
|
|
{
|
|
return(0);
|
|
}
|
|
#endif // NEC_98
|
|
|
|
#else
|
|
//
|
|
// Not compiling for DOS/V (ie, we're building the Japanese
|
|
// version of the 'standard' winnt.exe)
|
|
//
|
|
#include ".\dndisp.c"
|
|
#endif // def DOS_V
|
|
|
|
#else
|
|
#error Trying to use Japanese display routines but not compiling Japanese version!
|
|
#endif // def JAPAN
|