/// \brief Erase to End of Line /// void H19::eraseEL() { eraseLine(posY_m); updated_m = true; }
/// /// \brief Process reverse index /// void H19::reverseIndex() { // Check for being on line 25 if (onLine25()) { /// \todo - is this right? or should we clear the 25th line? return; } // Make sure not first line if (posY_m) { // simply move up a row --posY_m; } else { // must be line 0 - have to scroll down. for (int y = (rowsMain_c - 1); y > 0; --y) { for (unsigned int x = 0; x < cols_c; ++x) { screen_m[x][y] = screen_m[x][y - 1]; } } eraseLine(0); } updated_m = true; }
void H19::reset() { /// \todo - make sure these modes are the defaults. /// \todo - some of these are affected by dipswitches - implement. mode_m = Normal; reverseVideo_m = false; graphicMode_m = false; insertMode_m = false; line25_m = false; holdScreen_m = false; cursorOff_m = false; altKeypadMode_m = false; keyboardEnabled_m = true; setSW401(sw401_m); setSW402(sw402_m); posX_m = 0; posY_m = 0; saveX_m = 0; saveY_m = 0; for (unsigned int y = 0; y < rows_c; ++y) { eraseLine(y); } // specify the special symbol to end the line. for (unsigned int x = 0; x < cols_c; ++x) { screen_m[x][rows_c] = 0x100; } }
/// \brief Erase to End of Page /// void H19::eraseEOP() { eraseEOL(); unsigned int y = posY_m + 1; /// \todo what about line 25? while (y < rowsMain_c) { eraseLine(y); ++y; } updated_m = true; }
/// \brief Erase to Beginning of display /// void H19::eraseBOD() { eraseBOL(); // if on line 25 just erase to beginning of line if (!onLine25()) { int y = posY_m - 1; while (y >= 0) { eraseLine(y); --y; } } updated_m = true; }
void Board::checkLine() { //old and efficent erase line code but it is buggy for //some reason /*int checkFromWhere = -1,stopAtWhere = 19; for(int i=0;i < 10;++i) { if(latitude[i] > checkFromWhere) checkFromWhere = latitude[i] - 1; if(latitude[i] < stopAtWhere && latitude[i] != -1) stopAtWhere = latitude[i] - 1; } while(checkFromWhere != stopAtWhere + 1) { for(int i = 0;i < 10;++i) { if(!slots[checkFromWhere][i]) { goto continueWhileLoop; } } eraseLine(checkFromWhere); --stopAtWhere; continue; continueWhileLoop: ++checkFromWhere; }*/ bool eraseLine2; for(int i=17;i >=0;--i) { eraseLine2 = true; for(int j=0;j<10;++j) { if(!slots[i][j]) eraseLine2 = false; } if(eraseLine2) { eraseLine(i); ++i; } } }
/// \brief delete line /// /// \todo - Determine how the REAL H89 does this on Line 25, the ROM listing is not clear. /// - a real H19 messes up with either an insert or delete line on line 25. /// - note tested with early H19, newer H19 roms should have this fixed. void H19::deleteLine() { // Go to the beginning of line posX_m = 0; // move all the lines up. for (unsigned int y = posY_m; y < (rowsMain_c - 1); ++y) { for (unsigned int x = 0; x < cols_c; ++x) { screen_m[x][y] = screen_m[x][y + 1]; } } // clear line 24. eraseLine((rowsMain_c - 1)); updated_m = true; }
/// \brief insert line /// void H19::insertLine() { /// \todo - Determine how the REAL H89 does this on Line 25, the ROM listing is not clear. /// - a real H19 messes up with either an insert or delete line on line 25. /// - note tested with early H19, newer H19 roms should have this fixed. for (unsigned int y = (rowsMain_c - 1); y > posY_m; --y) { for (unsigned int x = 0; x < cols_c; ++x) { screen_m[x][y] = screen_m[x][y - 1]; } } eraseLine(posY_m); posX_m = 0; updated_m = true; }
/// \brief Clear Display void H19::clearDisplay() { // if on line 25, then only erase line 25 if (onLine25()) { eraseEL(); /// \todo determine if 'posX_m = 0' is needed. } else { for (unsigned int y = 0; y < rowsMain_c; ++y) { eraseLine(y); } posX_m = 0; posY_m = 0; } updated_m = true; }
void H19::processCharacter(char ch) { // mask off the high bit just in case, the real H19 would not have it set. ch &= 0x7f; if (mode_m == Normal) { switch (ch) { case ascii::NUL: case ascii::SOH: case ascii::STX: case ascii::ETX: case ascii::EOT: case ascii::ENQ: case ascii::ACK: case ascii::VT: case ascii::FF: case ascii::SO: case ascii::SI: case ascii::DLE: case ascii::DC1: case ascii::DC2: case ascii::DC3: case ascii::DC4: case ascii::NAK: case ascii::SYN: case ascii::ETB: case ascii::EM: case ascii::SUB: case ascii::FS: case ascii::GS: case ascii::RS: case ascii::US: case ascii::DEL: // From manual, these characters are not processed by the terminal break; case ascii::BEL: // Rings the bell. /// \todo - implement ringing bell. consoleLog("<BEL>"); break; case ascii::BS: // Backspace consoleLog("<BS>"); processBS(); break; case ascii::HT: // Horizontal Tab consoleLog("<TAB>"); processTAB(); break; case ascii::LF: // Line Feed processLF(); if (autoCR_m) { processCR(); } consoleLog("\n"); break; case ascii::CR: // Carriage Return processCR(); if (autoLF_m) { processLF(); } break; case ascii::CAN: // Cancel. break; case ascii::ESC: // Escape mode_m = Escape; consoleLog("<ESC>"); break; default: // if Printable character display it. #if CONSOLE_LOG fprintf(console_out, "%c", ch); #endif displayCharacter(ch); break; } } else if (mode_m == Escape) { // Assume we go back to Normal, so only the few that don't need to set the mode. mode_m = Normal; switch (ch) { case ascii::CAN: // CAN - Cancel // return to Normal mode, already set. break; case ascii::ESC: // Escape // From the ROM listing, stay in this mode. mode_m = Escape; break; // Cursor Functions case 'H': // Cursor Home posX_m = posY_m = 0; updated_m = true; break; case 'C': // Cursor Forward cursorForward(); break; case 'D': // Cursor Backward processBS(); // same processing as cursor backward break; case 'B': // Cursor Down cursorDown(); break; case 'A': // Cursor Up cursorUp(); break; case 'I': // Reverse Index reverseIndex(); break; case 'n': // Cursor Position Report cursorPositionReport(); break; case 'j': // Save cursor position saveCursorPosition(); break; case 'k': // Restore cursor position restoreCursorPosition(); break; case 'Y': // Direct Cursor Addressing mode_m = DCA_1; break; // Erase and Editing case 'E': // Clear Display clearDisplay(); break; case 'b': // Erase Beginning of Display eraseBOD(); break; case 'J': // Erase to End of Page eraseEOP(); break; case 'l': // Erase entire Line eraseEL(); break; case 'o': // Erase Beginning Of Line eraseBOL(); break; case 'K': // Erase To End Of Line eraseEOL(); break; case 'L': // Insert Line insertLine(); break; case 'M': // Delete Line deleteLine(); break; case 'N': // Delete Character deleteChar(); break; case '@': // Enter Insert Character Mode insertMode_m = true; break; case 'O': // Exit Insert Character Mode insertMode_m = false; break; // Configuration case 'z': // Reset To Power-Up Configuration reset(); break; case 'r': // Modify the Baud Rate /// \todo - determine if we should support this. debugss(ssH19, ERROR, "Error Unimplemented Modify Baud\n"); break; case 'x': // Set Mode mode_m = SetMode; break; case 'y': // Reset Mode mode_m = ResetMode; break; case '<': // Enter ANSI Mode /// \todo - implement ANSI mode. // ROM - just sets the mode debugss(ssH19, ERROR, "Error Entering ANSI mode - unsupported\n"); break; // Modes of operation case '[': // Enter Hold Screen Mode holdScreen_m = true; break; case '\\': // Exit Hold Screen Mode holdScreen_m = false; break; case 'p': // Enter Reverse Video Mode reverseVideo_m = true; break; case 'q': // Exit Reverse Video Mode reverseVideo_m = false; break; case 'F': // Enter Graphics Mode graphicMode_m = true; break; case 'G': // Exit Graphics Mode graphicMode_m = false; break; case 't': // Enter Keypad Shifted Mode keypadShifted_m = true; break; case 'u': // Exit Keypad Shifted Mode // ROM - just sets the mode keypadShifted_m = false; break; case '=': // Enter Alternate Keypad Mode // ROM - just sets the mode keypadShifted_m = true; break; case '>': // Exit Alternate Keypad Mode // ROM - just sets the mode keypadShifted_m = false; break; // Additional Functions case '}': // Keyboard Disable /// \todo - determine whether to do this. keyboardEnabled_m = false; break; case '{': // Keyboard Enable keyboardEnabled_m = true; break; case 'v': // Wrap Around at End Of Line wrapEOL_m = true; break; case 'w': // Discard At End Of Line wrapEOL_m = false; break; case 'Z': // Identify as VT52 (Data: ESC / K) debugss(ssH19, ERROR, "Identify request\n"); sendData(ascii::ESC); sendData('/'); sendData('K'); break; case ']': // Transmit 25th Line transmitLine25(); break; case '#': // Transmit Page transmitPage(); break; default: debugss(ssH19, WARNING, "Unhandled ESC: %d\n", ch); /// \todo - verify this is how the H19 ROM does it. break; } } else if (mode_m == SetMode) { mode_m = Normal; switch (ch) { case '1': // Enable 25th line // From the ROM, it erases line 25 on the enable, but here we erase on the disable. line25_m = true; break; case '2': // No key click keyClick_m = true; break; case '3': // Hold screen mode holdScreen_m = true; break; case '4': // Block Cursor cursorBlock_m = true; updated_m = true; break; case '5': // Cursor Off cursorOff_m = true; updated_m = true; break; case '6': // Keypad Shifted keypadShifted_m = true; break; case '7': // Alternate Keypad mode altKeypadMode_m = true; break; case '8': // Auto LF autoLF_m = true; break; case '9': // Auto CR autoCR_m = true; break; default: /// \todo Need to process ch as if none of this happened... debugss(ssH19, WARNING, "Invalid set Mode: %c\n", ch); break; } } else if (mode_m == ResetMode) { mode_m = Normal; switch (ch) { case '1': // Disable 25th line eraseLine(rowsMain_c); line25_m = false; updated_m = true; break; case '2': // key click keyClick_m = false; break; case '3': // Hold screen mode holdScreen_m = false; break; case '4': // Block Cursor cursorBlock_m = false; updated_m = true; break; case '5': // Cursor On cursorOff_m = false; updated_m = true; break; case '6': // Keypad Unshifted keypadShifted_m = false; break; case '7': // Exit Alternate Keypad mode altKeypadMode_m = false; break; case '8': // No Auto LF autoLF_m = false; break; case '9': // No Auto CR autoCR_m = false; break; default: /// \todo Need to process ch as if none of this happened... debugss(ssH19, WARNING, "Invalid reset Mode: %c\n", ch); break; } } else if (mode_m == DCA_1) { // From actual H19, once the line is specified, the cursor // immediately moves to that line, so no need to save the // position and wait for the entire command. /// \todo verify that this is the same on newer H19s. if (ch == ascii::CAN) { // cancel mode_m = Normal; } else { // \todo handle error conditions int pos = ch - 31; // verify valid Position if (((pos > 0) && (pos < (signed) rows_c)) || ((pos == (signed) rows_c) && (line25_m))) { posY_m = pos - 1; } else { /// \todo check to see how a real h19 handles this. debugss(ssH19, INFO, "DCA invalid Y: %d\n", pos); } mode_m = DCA_2; } } else if (mode_m == DCA_2) { if (ch == ascii::CAN) { // cancel mode_m = Normal; } else { int pos = ch - 31; if ((pos > 0) && (pos < 81)) { posX_m = pos - 1; } else { posX_m = (cols_c - 1); } updated_m = true; mode_m = Normal; } } }
void Text::keystroke(const Event& event) { if (readOnly_) { return; } char buffer[8]; // needs to be dynamically adjusted int count = event.mapkey(buffer, 8); if (count <= 0) { return; } // return causes a newline if (buffer[0] == '\r') { buffer[0] = '\n'; } context_key(buffer[0]); if (buffer[0] == 2) // control-b { if (insertion_.column_ > 0) { --insertion_.column_; damage(insertion_); repair(); }else if (insertion_.line_ > 0) { damage(insertion_); --insertion_.line_; // now just like a control-e int index = text_->LineIndex(insertion_.line_); int end = text_->EndOfLine(index); insertion_.column_ = end - index; damage(insertion_); repair(); } return; } else if (buffer[0] == 1) // control-a { insertion_.column_ = 0; damage(insertion_); repair(); return; } else if (buffer[0] == 6) // control-f { int index = text_->LineIndex(insertion_.line_); int end = text_->EndOfLine(index); if (insertion_.column_ < end - index) { ++insertion_.column_; damage(insertion_); repair(); }else if (insertion_.line_ < text_->Height()-1) { damage(insertion_); ++insertion_.line_; // now just like control-a insertion_.column_ = 0; damage(insertion_); repair(); } return; } else if (buffer[0] == 5) // control-e { int index = text_->LineIndex(insertion_.line_); int end = text_->EndOfLine(index); insertion_.column_ = end - index; damage(insertion_); repair(); return; } else if (buffer[0] == 16) { // control-p if (insertion_.line_ > 0) { damage(insertion_); --insertion_.line_; insertion_.column_ = ctl_pn_col_; int index = text_->LineIndex(insertion_.line_); int col = text_->EndOfLine(index) - index; if (col < insertion_.column_){ insertion_.column_ = col; } damage(insertion_); repair(); } return; }else if (buffer[0] == 14) { // control-n if (insertion_.line_ < text_->Height()-1) { damage(insertion_); ++insertion_.line_; insertion_.column_ = ctl_pn_col_; int index = text_->LineIndex(insertion_.line_); int col = text_->EndOfLine(index) - index; if (col < insertion_.column_){ insertion_.column_ = col; } damage(insertion_); repair(); } return; }else if (escape_ == 1) { // escaped chars if (buffer[0] == '>') { // to end of buffer damage(insertion_); if (text_->Height() >0) { insertion_.line_ = text_->Height()-1; } else { insertion_.line_ = 0; } int index = text_->LineIndex(text_->EndOfText()); insertion_.column_ = text_->EndOfText()-index; damage(insertion_); repair(); }else if (buffer[0] == '<') {// to beginning of buffer damage(insertion_); insertion_.line_ = 0; insertion_.column_ = 0; damage(insertion_); repair(); } return; }else if (buffer[0] == 033) { // ignore the escape itself return; } else if (buffer[0] == 4) // ctrl-d { if (!delete_selection()) { // like a ctrl-f then backspace int index = text_->LineIndex(insertion_.line_); int end = text_->EndOfLine(index); if (insertion_.column_ < end - index) { ++insertion_.column_; backspace(); }else if (insertion_.line_ < text_->Height()-1) { ++insertion_.line_; // now just like control-a insertion_.column_ = 0; backspace(); } } } else if (buffer[0] == 21) { // control u eraseLine(); } else if ((buffer[0] == '\b') || (buffer[0] == 127)) { // backspace and delete if (!delete_selection()) { backspace(); } } else { delete_selection(); insertChars(buffer, count); } dirty(true); }