/*++ Copyright (c) 1993 Microsoft Corporation Module Name: romsetup.c Abstract: This is the setup program to update the DUO flash prom Author: Lluis Abello (lluis) Environment: ARC Firmware Notes: This module must be linked between 2MB and 4 MB Kesg0 addresses. The executable must be non relocatable. Revision History: --*/ #include "fwp.h" #include "duobase.h" #ifndef DUO #define FLASH_ENABLE_VIRTUAL_BASE 0xE000D500 #endif #define KeGetDcacheFillSize() 64 ULONG InitKeyboardController( ); ULONG InitKeyboard( ); BOOLEAN SendKbdCommand( IN UCHAR Command ); BOOLEAN GetKbdData( PUCHAR C, ULONG msec ); BOOLEAN SendKbdData( IN UCHAR Data ); UCHAR KbdBuffer[3]; ULONG KbdBufferWIndex = 0; ULONG KbdBufferRIndex = 0; // // Keyboard static variables. // BOOLEAN KbdCtrl = FALSE; BOOLEAN Scan0xE0 = FALSE; // 1111 1 1111122222222 2 2333333333344 4 44444445555 5 5 55 // Character # 234567890123 4 5678901234567 8 9012345678901 2 34567890123 4 5 67 PCHAR NormalLookup = "1234567890-=\b\0qwertyuiop[]\n\0asdfghjkl;'`\0\\zxcvbnm,./\0\0\0 "; PCHAR ShiftedLookup = "!@#$%^&*()_+\b\0QWERTYUIOP{}\n\0ASDFGHJKL:\"~\0\|ZXCVBNM<>?\0\0\0 "; BOOLEAN FwLeftShift = FALSE; BOOLEAN FwRightShift = FALSE; BOOLEAN FwControl = FALSE; BOOLEAN FwAlt = FALSE; BOOLEAN FwCapsLock = FALSE; #define StoreKeyboardChar(C) KbdBuffer[KbdBufferWIndex++] = C extern ULONG end; PULONG ImageBuffer; ULONG ImageSize; CHAR GetChar( IN VOID ); VOID LoadProm( IN PCHAR DiskName ); BOOLEAN ReadRawFile( IN PUCHAR Name ); BOOLEAN ProgramFlashProm( IN PULONG ImageBuffer, IN ULONG ImageSize ); VOID ResetSystem ( IN VOID ); VOID WaitForKey( ); VOID Romsetup( IN ULONG Argc, IN PCHAR *Argv ) /*++ Routine Description: This is the entry point of the executable that is loaded by the base prom. This routine does the following: Initializes the display. Loads the file with the Flash Prom image. Erases the Flash prom. Puts the loaded image in the flash prom. Resets the machine. Arguments: Argc - Supplies the number of arguments. Argv - Supplies the arguments The first argument supplies the arc pathname of the floppy disk If the program was loaded from "run a program" then the path also contains the name of the executable. Return Value: Never returns. Resets the machine. --*/ { UCHAR PathName[128]; PCHAR Choices[2]; LONG DefaultChoice = 1; LONG NumberOfMenuChoices = 2; LONG Index; UCHAR Character; PCHAR Pointer, EndPointer; DisplayBootInitialize(); FwSetScreenColor( ArcColorWhite, ArcColorBlue); FwSetScreenAttributes( TRUE, FALSE, FALSE); FwClearScreen(); // // Initialize the keyboard. // InitKeyboardController(); InitKeyboard(); // // Extract the arc disk name from Argv[0] if it has a file name atached. // Copy the string and put a '\0' after the last ')' is found. // strcpy(PathName,Argv[0]); Pointer = EndPointer = PathName; while (*Pointer) { if (*Pointer == ')') { EndPointer = Pointer; } Pointer++; } EndPointer++; *EndPointer = '\0'; // // Clear translation mode. // SendKbdCommand(KBD_CTR_READ_COMMAND); GetKbdData(&Character,100); Character = (Character & 0xBF); SendKbdCommand(KBD_CTR_WRITE_COMMAND); SendKbdData(Character); Choices[0] = "Update PROM"; Choices[1] = "Exit"; while (TRUE) { // // Display the menu. // FwSetPosition( 0, 0); FwPrint("Duo EEPROM Update program. Version 1.0"); FwSetPosition( 3, 0); FwPrint(" Actions:\r\n"); for (Index = 0; Index < NumberOfMenuChoices; Index++ ) { FwSetPosition( Index + 5, 5); if (Index == DefaultChoice) { FwSetScreenAttributes( TRUE, FALSE, TRUE); } FwPrint(Choices[Index]); FwSetScreenAttributes( TRUE, FALSE, FALSE); } FwSetPosition(NumberOfMenuChoices + 6, 0); FwPrint(" Use the arrow keys to select.\r\n"); FwPrint(" Press Enter to choose.\r\n"); FwPrint("\r\n"); // // Display the bitmap. // FwSetScreenColor( ArcColorCyan, ArcColorBlue); JxBmp(); FwSetScreenColor( ArcColorWhite, ArcColorBlue); // // Get input // do { Character = GetChar(); switch (Character) { case ASCII_ESC: Character = GetChar(); if (Character != '[') { break; } case ASCII_CSI: Character = GetChar(); FwSetPosition( DefaultChoice + 5, 5); FwPrint(Choices[DefaultChoice]); switch (Character) { case 'A': case 'D': DefaultChoice--; if (DefaultChoice < 0) { DefaultChoice = NumberOfMenuChoices-1; } break; case 'B': case 'C': DefaultChoice++; if (DefaultChoice == NumberOfMenuChoices) { DefaultChoice = 0; } break; case 'H': DefaultChoice = 0; break; default: break; } FwSetPosition( DefaultChoice + 5, 5); FwSetScreenAttributes( TRUE, FALSE, TRUE); FwPrint(Choices[DefaultChoice]); FwSetScreenAttributes( TRUE, FALSE, FALSE); continue; default: break; } } while ((Character != '\n') && (Character != '\r')); if (DefaultChoice == 0) { FwSetPosition(NumberOfMenuChoices + 6, 0); FwClearLine(); FwSetPosition(NumberOfMenuChoices + 7, 0); FwClearLine(); FwSetPosition(NumberOfMenuChoices + 6, 0); strcat(PathName,"duoprom.raw"); if (ReadRawFile(PathName) == TRUE) { if (ProgramFlashProm(ImageBuffer,ImageSize) == FALSE) { FwPrint("The EEPROM update process failed.\r\nPress any key to continue."); WaitForKey(); } } else { FwPrint("The EEPROM has not been updated.\r\nPress any key to continue."); WaitForKey(); } FwSetPosition(NumberOfMenuChoices + 6, 0); FwClearLine(); FwSetPosition(NumberOfMenuChoices + 7, 0); FwClearLine(); FwSetPosition(NumberOfMenuChoices + 8, 0); FwClearLine(); FwSetPosition(NumberOfMenuChoices + 9, 0); FwClearLine(); } if (DefaultChoice == 2) { strcpy(PathName,"scsi()disk(2)fdisk()"); LoadProm(PathName); } if (DefaultChoice == 1) { ResetSystem(); } } } VOID LoadProm( IN PCHAR DiskName ) /*++ Routine Description: This routine opens the root directory and finds the files with extension ".RAW" if there is more than one, a menu is display and the user can choose the file to load, otherwise the file found is loaded. If there are no files with the .RAW extension an error message is printed. Arguments: DiskName Arc path name of the floppy disk. Return Value: None. --*/ { DIRECTORY_ENTRY DirEntry[8]; LONG Index; ULONG Fid; LONG Count = 8; ARC_STATUS Status; LONG DefaultChoice = 0; LONG NumberOfMenuChoices = 0; CHAR PathName[64]; CHAR Choices[7][13]; UCHAR Character; // // Open the disk root // strcat(DiskName,"\\"); if (Status = ArcOpen(DiskName,ArcOpenReadOnly,&Fid) != ESUCCESS) { FwPrint("Error opening %s. Status %lx\r\n",DiskName,Status); WaitForKey(); FwPrint("Attempting to load duoprom.raw\r\n"); strcpy(PathName,DiskName); strcat(PathName,"duoprom.raw"); if (ReadRawFile(PathName) == TRUE) { ProgramFlashProm(ImageBuffer,ImageSize); return; } else { FwPrint("File Error.\r\nThe EEPROM has not been updated.\r\nPress any key to continue."); WaitForKey(); return; } } // // Scan for files with .raw extension and build the menu choices. // while ((Count == 8) && (NumberOfMenuChoices != 6)) { if (Status = ArcGetDirectoryEntry(Fid,DirEntry,7,&Count) != ESUCCESS) { FwPrint("Error reading directory. Status %lx\r\n",Status); break; } else { // // Build the choices. // for (Index=0;Index= 16) && (Scan <= 25)) || ((Scan >= 30) && (Scan <= 38)) || ((Scan >= 44) && (Scan <= 50))) { if (((FwLeftShift || FwRightShift) && !FwCapsLock) || (!(FwLeftShift || FwRightShift) && FwCapsLock)) { Char = ShiftedLookup[Scan - 2]; } else { Char = NormalLookup[Scan - 2]; } } else { if ((Scan > 1) && (Scan < 58)) { // // Its ASCII but not alpha, so don't shift on CapsLock. // if (FwLeftShift || FwRightShift) { Char = ShiftedLookup[Scan - 2]; } else { Char = NormalLookup[Scan - 2]; } } } // // If a character, store it in buffer. // if (Char) { StoreKeyboardChar(Char); return; } break; } if (FwControlCharacter) { StoreKeyboardChar(ASCII_CSI); StoreKeyboardChar(FwControlCharacter); if (FwControlCharacter == 'O') { StoreKeyboardChar(FwFunctionCharacter); } return; } } } CHAR GetChar( IN VOID ) /*++ Routine Description: This routine reads a character from the keyboard. Arguments: None. Return Value: Character. --*/ { UCHAR ScanCode; // // Check if we have something in the buffer and return it if we do. // while (TRUE) { if (KbdBufferWIndex) { ScanCode = KbdBuffer[KbdBufferRIndex]; KbdBufferRIndex++; KbdBufferWIndex--; if (KbdBufferWIndex == 0) { KbdBufferRIndex = 0; } return ScanCode; } // // There is nothing in the buffer. Wait for a key to be pressed. // for (;;) { if (!GetKbdData(&ScanCode,2000)) { break; } } // // Translate the scan code. // TranslateScanCode(ScanCode); } }