/*++ 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 #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> 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