diff --git a/software/io/c64/c64.h b/software/io/c64/c64.h index 252a207b5..279a2d9c3 100644 --- a/software/io/c64/c64.h +++ b/software/io/c64/c64.h @@ -304,7 +304,10 @@ class C64 : public GenericHost, ConfigurableObject static void hard_stop(void); void resume(void); void freeze(void); - virtual void get_all_memory(uint8_t *) { /* NOT YET IMPLEMENTED */ }; + + virtual void get_all_memory(uint8_t *) { /* NOT YET IMPLEMENTED EXCEPT FOR U64*/ }; + virtual uint8_t peek(uint32_t) { /* NOT YET IMPLEMENTED EXCEPT FOR U64*/ }; + virtual void poke(uint32_t, uint8_t) { /* NOT YET IMPLEMENTED EXCEPT FOR U64*/ }; static uint8_t get_exrom_game(void) { return (C64_CLOCK_DETECT & 0x0C) >> 2; diff --git a/software/system/dump_hex.c b/software/system/dump_hex.c index 0ffac6f01..d042cf0c5 100644 --- a/software/system/dump_hex.c +++ b/software/system/dump_hex.c @@ -27,6 +27,8 @@ #define DUMP_BYTES 16 #endif +static const char hex_chars[] = "0123456789ABCDEF"; + void dump_hex_actual(void *pp, int len, int relative) { int w,t; @@ -124,3 +126,15 @@ void dump_hex_verify(void *pp1, void *pp2, int len) } } } + +void dump_hex_byte(char *buf, int offset, uint8_t byte) +{ + buf[offset] = hex_chars[(byte >> 4) & 0x0F]; + buf[offset + 1] = hex_chars[byte & 0x0F]; +} + +void dump_hex_word(char *buf, int offset, uint16_t word) +{ + dump_hex_byte(buf, offset, (word >> 8) & 0xFF); + dump_hex_byte(buf, offset + 2, word & 0xFF); +} diff --git a/software/system/dump_hex.h b/software/system/dump_hex.h index e249b82d1..8ea2a576a 100644 --- a/software/system/dump_hex.h +++ b/software/system/dump_hex.h @@ -33,6 +33,8 @@ void dump_hex_relative(void *pp, int len); void dump_hex_actual(void *pp, int len, int relative); void dump_hex_dirty(void *p, int len, uint8_t ptrn); void dump_hex_verify(void *pp1, void *pp2, int len); +void dump_hex_byte(char *buf, int offset, uint8_t byte); +void dump_hex_word(char *buf, int offset, uint16_t word); #ifdef __cplusplus } diff --git a/software/u64/u64_config.cc b/software/u64/u64_config.cc index 2a5fc424b..46abb90c8 100755 --- a/software/u64/u64_config.cc +++ b/software/u64/u64_config.cc @@ -128,9 +128,12 @@ static SemaphoreHandle_t resetSemaphore; #define CFG_BADLINES_EN 0x53 #define CFG_SUPERCPU_DET 0x54 +#define CFG_MONITOR 0x60 + #define CFG_SCAN_MODE_TEST 0xA8 #define CFG_VIC_TEST 0xA9 + uint8_t C64_EMUSID1_BASE_BAK; uint8_t C64_EMUSID2_BASE_BAK; uint8_t C64_SID1_BASE_BAK; @@ -1050,21 +1053,31 @@ int U64Config :: setSidEmuParams(ConfigItem *it) #define MENU_U64_WIFI_ENABLE 4 #define MENU_U64_WIFI_BOOT 5 #define MENU_U64_DETECT_SIDS 6 -#define MENU_U64_POKE 7 +#define MENU_U64_PEEK 7 +#define MENU_U64_POKE 8 +#define MENU_U64_MONITOR 9 void U64Config :: create_task_items(void) { TaskCategory *dev = TasksCollection :: getCategory("Developer", SORT_ORDER_DEVELOPER); + myActions.peek = new Action("Peek", SUBSYSID_U64, MENU_U64_PEEK); myActions.poke = new Action("Poke", SUBSYSID_U64, MENU_U64_POKE); + myActions.monitor = new Action("Monitor", SUBSYSID_U64, MENU_U64_MONITOR); myActions.saveedid = new Action("Save EDID to file", SUBSYSID_U64, MENU_U64_SAVEEDID); myActions.siddetect = new Action("Detect SIDs", SUBSYSID_U64, MENU_U64_DETECT_SIDS); myActions.wifioff = new Action("Disable WiFi", SUBSYSID_U64, MENU_U64_WIFI_DISABLE); myActions.wifion = new Action("Enable WiFi", SUBSYSID_U64, MENU_U64_WIFI_ENABLE); myActions.wifiboot = new Action("Enable WiFi Boot", SUBSYSID_U64, MENU_U64_WIFI_BOOT); - dev->append(myActions.saveedid ); + dev->append(myActions.saveedid); + +#if U64 + dev->append(myActions.peek); + dev->append(myActions.poke); + dev->append(myActions.monitor); +#endif + #if DEVELOPER > 0 - dev->append(myActions.poke ); dev->append(myActions.siddetect); dev->append(myActions.wifioff ); dev->append(myActions.wifion ); @@ -1077,6 +1090,24 @@ void U64Config :: update_task_items(bool writablePath, Path *p) myActions.saveedid->setDisabled(!writablePath); } +bool U64Config :: stop_c64() { + portENTER_CRITICAL(); + bool running = !(C64_STOP & C64_HAS_STOPPED); + if (running) { + C64 *machine = C64 :: getMachine(); + machine->stop(false); + } + return running; +} + +void U64Config :: resume_c64(bool stopped) { + if (stopped) { + C64 *machine = C64 :: getMachine(); + machine->start(); + } + portEXIT_CRITICAL(); +} + int U64Config :: executeCommand(SubsysCommand *cmd) { File *f = 0; @@ -1091,7 +1122,9 @@ int U64Config :: executeCommand(SubsysCommand *cmd) C64 *machine; I2C_Driver i2c; static char poke_buffer[16]; - uint32_t addr, value; + static char peek_buffer[16]; + static char peek_range_buffer[16]; + uint32_t addr, end_addr, value; switch(cmd->functionID) { case MENU_U64_SAVEEDID: @@ -1153,27 +1186,41 @@ int U64Config :: executeCommand(SubsysCommand *cmd) U64_WIFI_CONTROL = 7; break; + case MENU_U64_PEEK: + if (cmd->user_interface->string_box("Peek AAAA", peek_buffer, 16)) { + sscanf(peek_buffer, "%x", &addr); + + value = C64 :: getMachine()->peek(addr); + + char msg[20]; + sprintf(msg, "Peek(%4x)=%2x", addr, value); + cmd->user_interface->popup(msg, BUTTON_OK); + } + break; + case MENU_U64_POKE: if (cmd->user_interface->string_box("Poke AAAA,DD", poke_buffer, 16)) { - sscanf(poke_buffer, "%x,%x", &addr, &value); - C64 *machine = C64 :: getMachine(); - portENTER_CRITICAL(); - - if (!(C64_STOP & C64_HAS_STOPPED)) { - machine->stop(false); + C64 :: getMachine()->poke(addr, (uint8_t) value); + uint8_t verified_value = C64 :: getMachine()->peek(addr); - C64_POKE(addr, value); - - machine->resume(); - } else { - C64_POKE(addr, value); - } - portEXIT_CRITICAL(); + char msg[20]; + sprintf(msg, "Poke(%4x,%2x)=%2x", addr, value, verified_value); + cmd->user_interface->popup(msg, BUTTON_OK); } break; + case MENU_U64_MONITOR: + int ram_size = 64 * 1024; + uint8_t *pb = new uint8_t[ram_size]; + + C64 :: getMachine()->get_all_memory(pb); + + cmd->user_interface->run_hex_editor((const char *) pb, ram_size); + delete[] pb; + break; + case MENU_U64_DETECT_SIDS: machine = C64 :: getMachine(); machine->stop(false); @@ -1194,7 +1241,6 @@ int U64Config :: executeCommand(SubsysCommand *cmd) return 0; } - uint8_t U64Config :: GetSidType(int slot) { uint8_t val; diff --git a/software/u64/u64_config.h b/software/u64/u64_config.h index cabd2350e..d2642454f 100755 --- a/software/u64/u64_config.h +++ b/software/u64/u64_config.h @@ -25,7 +25,9 @@ extern U64Config u64_configurator; class U64Config : public ConfigurableObject, ObjectWithMenu, SubSystem { struct { + Action *peek; Action *poke; + Action *monitor; Action *saveedid; Action *siddetect; Action *wifioff; @@ -103,6 +105,8 @@ class U64Config : public ConfigurableObject, ObjectWithMenu, SubSystem void create_task_items(void); void update_task_items(bool writablePath, Path *p); int executeCommand(SubsysCommand *cmd); + bool stop_c64(); + void resume_c64(bool stopped); void effectuate_settings(); static int setPllOffset(ConfigItem *it); diff --git a/software/u64/u64_machine.cc b/software/u64/u64_machine.cc index 89bdb7bc9..8e4d964b3 100644 --- a/software/u64/u64_machine.cc +++ b/software/u64/u64_machine.cc @@ -3,24 +3,60 @@ #include "FreeRTOS.h" #include -void U64Machine :: get_all_memory(uint8_t *pb) -{ +bool U64Machine :: before_memory_access() { bool freezerMenu = isFrozen; - if (!freezerMenu) { stop(false); } portENTER_CRITICAL(); C64_DMA_MEMONLY = 1; - memcpy(pb, (uint8_t *)C64_MEMORY_BASE, 65536); + return freezerMenu; +} + +void U64Machine :: after_memory_access(uint8_t *pb, bool freezerMenu) { C64_DMA_MEMONLY = 0; portEXIT_CRITICAL(); - if (!freezerMenu) { resume(); - } else { // if we were in freezer menu, the backup of the 1K-4K RAM should be used - // restore memory + } else { + // if we were in freezer menu, the backup of the 1K-4K RAM should be used to restore memory memcpy(pb + 1024, screen_backup, 1024); memcpy(pb + 2048, ram_backup, 2048); } } + +void U64Machine :: get_all_memory(uint8_t *pb) +{ + bool freezerMenu = before_memory_access(); + memcpy(pb, (uint8_t *)C64_MEMORY_BASE, 65536); + after_memory_access(pb, freezerMenu); +} + +uint8_t U64Machine :: peek(uint32_t address) +{ + bool freezerMenu = before_memory_access(); + uint8_t *pb = new uint8_t[64 * 1024]; + get_all_memory(pb); + + uint8_t byte = *(pb + address); + printf("peek(%d + %d)=%d", pb, address, byte); + + after_memory_access(pb, freezerMenu); + delete[] pb; + return byte; +} + +void U64Machine :: poke(uint32_t address, uint8_t byte) +{ + bool freezerMenu = before_memory_access(); + uint8_t *pb = new uint8_t[64 * 1024]; + get_all_memory(pb); + + // TODO Ensure this works on freeze mode, not just in HDMI overlay mode + memset((void *) C64_MEMORY_BASE + address, byte, 1); + printf("poke(%d + %d)=%d", C64_MEMORY_BASE, address, byte); + + after_memory_access(pb, freezerMenu); + delete[] pb; +} + diff --git a/software/u64/u64_machine.h b/software/u64/u64_machine.h index 12008b731..4a814352d 100644 --- a/software/u64/u64_machine.h +++ b/software/u64/u64_machine.h @@ -8,9 +8,15 @@ class U64Machine : public C64 { U64Machine() { } ~U64Machine() { } + + bool before_memory_access(); + void after_memory_access(uint8_t *, bool); + void get_all_memory(uint8_t *pb); -public: + uint8_t peek(uint32_t address); + void poke(uint32_t address, uint8_t byte); +public: friend class C64; }; diff --git a/software/userinterface/ass_editor.cc b/software/userinterface/ass_editor.cc new file mode 100644 index 000000000..62f53120c --- /dev/null +++ b/software/userinterface/ass_editor.cc @@ -0,0 +1,58 @@ +#include "editor.h" +#include +#include + +static const char hex_chars[] = "0123456789ABCDEF"; + +// Assembly editor; currently only supports disassembly. +AssEditor :: AssEditor(UserInterface *ui, const char *text_buffer, int max_len) : Editor(ui, text_buffer, max_len) +{ +} + +void AssEditor :: line_breakdown(const char *text_buffer, int buffer_size) +{ + Line current; + int pos = 0; + linecount = 0; + + text->clear_list(); + while (pos < buffer_size) { + current.buffer = text_buffer + pos; + current.length = (buffer_size - pos > BYTES_PER_HEX_ROW) ? BYTES_PER_HEX_ROW : buffer_size - pos;; + text->append(current); + pos += current.length; + linecount++; + } +} + +inline void add_hex_byte(char *buf, int offset, uint8_t byte) +{ + buf[offset] = hex_chars[(byte >> 4) & 0x0F]; + buf[offset + 1] = hex_chars[byte & 0x0F]; +} + +inline void add_hex_word(char *buf, int offset, uint16_t word) +{ + add_hex_byte(buf, offset, (word >> 8) & 0xFF); + add_hex_byte(buf, offset + 2, word & 0xFF); +} + +void HexEditor :: draw(int line_idx, Line *line) +{ + #define HEX_COL_START 5 + #define TXT_COL_START (HEX_COL_START + (3 * BYTES_PER_HEX_ROW)) + + char hex_buf[CHARS_PER_HEX_ROW]; + memset(hex_buf, ' ', CHARS_PER_HEX_ROW); + add_hex_word(hex_buf, 0, line_idx * BYTES_PER_HEX_ROW); + + for (int i = 0; i < line->length; i++) { + uint8_t c = (uint8_t) line->buffer[i]; + add_hex_byte(hex_buf, HEX_COL_START + (3 * i), c); + // represent all non-printable characters as '.' based on the character set used by firmware version 3.10j + hex_buf[TXT_COL_START + i] = (char) ((c == 0 || c == 8 || c == 10 || c == 13 || (c >=20 && c <= 31) || (c >= 144 && c <= 159)) ? '.' : c); + } + + window->output_length(hex_buf, CHARS_PER_HEX_ROW); + window->repeat(' ', window->get_size_x() - CHARS_PER_HEX_ROW); +} diff --git a/software/userinterface/editor.cc b/software/userinterface/editor.cc index 5e0350d22..a1cc56a67 100644 --- a/software/userinterface/editor.cc +++ b/software/userinterface/editor.cc @@ -60,7 +60,7 @@ void Editor :: line_breakdown(const char *text_buffer, int buffer_size) // printf("Line length = %d\n", line_length); text->clear_list(); - while(text_buffer[pos] && pos < buffer_size) { + while(pos < buffer_size) { current.buffer = &text_buffer[pos]; current.length = -1; last_space = -1; @@ -68,13 +68,11 @@ void Editor :: line_breakdown(const char *text_buffer, int buffer_size) int max_line_length = (line_length > (buffer_size - pos)) ? buffer_size - pos : line_length; for(int i=0;iappend(current); linecount++; - if(last == 0) - return; i++; if((c[i] == 0x0a)&&(last == 0x0d)) i++; @@ -124,20 +122,26 @@ void Editor :: init(Screen *scr, Keyboard *key) void Editor :: draw(void) { - struct Line line; + struct Line line, *line_ptr; int width = window->get_size_x(); for(int i=0;imove_cursor(0, i); - line = (*text)[i + first_line]; + int line_idx = i + first_line; + line = (*text)[line_idx]; if (line.buffer) { - window->output_length(line.buffer, line.length); - window->repeat(' ', width - line.length); + draw(line_idx, &line); } else { window->repeat(' ', width); } } } +void Editor :: draw(int line_idx, Line *line) +{ + window->output_length(line->buffer, line->length); + window->repeat(' ', window->get_size_x() - line->length); +} + void Editor :: deinit() { if(window) @@ -182,7 +186,7 @@ int Editor :: handle_key(uint8_t c) draw(); } break; - case KEY_F1: // F1 -> page up + case KEY_F1: // page up case KEY_PAGEUP: first_line -= height + 1; if (first_line < 0) { @@ -190,7 +194,12 @@ int Editor :: handle_key(uint8_t c) } draw(); break; - case KEY_F7: // F7 -> page down + case KEY_F2: // start + case KEY_HOME: + first_line = 0; + draw(); + break; + case KEY_F7: // page down case KEY_PAGEDOWN: first_line += height - 1; if (first_line >= linecount - height) { @@ -200,6 +209,11 @@ int Editor :: handle_key(uint8_t c) } draw(); break; + case KEY_F8: // end + case KEY_END: + first_line = linecount - height; + draw(); + break; case KEY_BACK: // backspace break; case KEY_SPACE: // space diff --git a/software/userinterface/editor.h b/software/userinterface/editor.h index 1a43ef3ce..c52d8ffde 100644 --- a/software/userinterface/editor.h +++ b/software/userinterface/editor.h @@ -13,8 +13,6 @@ class UserInterface; class Editor : public UIObject { UserInterface *user_interface; - void line_breakdown(const char *text_buffer, int buffer_size); - void draw(); public: int line_length; int height; @@ -34,8 +32,29 @@ class Editor : public UIObject virtual void init(Screen *win, Keyboard *k); virtual void deinit(void); + virtual void line_breakdown(const char *text_buffer, int buffer_size); + virtual void draw(); + virtual void draw(int line_idx, Line *line); virtual int poll(int); virtual int handle_key(uint8_t); }; +class HexEditor : public Editor +{ + UserInterface *user_interface; + void line_breakdown(const char *text_buffer, int buffer_size); + void draw(int line_idx, Line *line); +public: + HexEditor(UserInterface *ui, const char *text_buffer, int max_len); +}; + +class AssEditor : public Editor +{ + UserInterface *user_interface; + void line_breakdown(const char *text_buffer, int buffer_size); + void draw(int line_idx, Line *line); +public: + AssEditor(UserInterface *ui, const char *text_buffer, int max_len); +}; + #endif diff --git a/software/userinterface/hex_editor.cc b/software/userinterface/hex_editor.cc new file mode 100644 index 000000000..3f82b6264 --- /dev/null +++ b/software/userinterface/hex_editor.cc @@ -0,0 +1,44 @@ +#include "editor.h" +#include +#include +#include + +HexEditor :: HexEditor(UserInterface *ui, const char *text_buffer, int max_len) : Editor(ui, text_buffer, max_len) +{ +} + +void HexEditor :: line_breakdown(const char *text_buffer, int buffer_size) +{ + Line current; + int pos = 0; + linecount = 0; + + text->clear_list(); + while (pos < buffer_size) { + current.buffer = text_buffer + pos; + current.length = (buffer_size - pos > BYTES_PER_HEX_ROW) ? BYTES_PER_HEX_ROW : buffer_size - pos;; + text->append(current); + pos += current.length; + linecount++; + } +} + +void HexEditor :: draw(int line_idx, Line *line) +{ + #define HEX_COL_START 5 + #define TXT_COL_START (HEX_COL_START + (3 * BYTES_PER_HEX_ROW)) + + char hex_buf[CHARS_PER_HEX_ROW]; + memset(hex_buf, ' ', CHARS_PER_HEX_ROW); + dump_hex_word(hex_buf, 0, line_idx * BYTES_PER_HEX_ROW); + + for (int i = 0; i < line->length; i++) { + uint8_t c = (uint8_t) line->buffer[i]; + dump_hex_byte(hex_buf, HEX_COL_START + (3 * i), c); + // represent all non-printable characters as '.' based on the character set used by firmware version 3.10j + hex_buf[TXT_COL_START + i] = (char) ((c == 0 || c == 8 || c == 10 || c == 13 || (c >=20 && c <= 31) || (c >= 144 && c <= 159)) ? '.' : c); + } + + window->output_length(hex_buf, CHARS_PER_HEX_ROW); + window->repeat(' ', window->get_size_x() - CHARS_PER_HEX_ROW); +} diff --git a/software/userinterface/user_file_interaction.cc b/software/userinterface/user_file_interaction.cc index bdb22b2a8..9f25d9862 100644 --- a/software/userinterface/user_file_interaction.cc +++ b/software/userinterface/user_file_interaction.cc @@ -13,6 +13,9 @@ #include "home_directory.h" #include "subsys.h" +#include "editor.h" + +#define MAX_FILE_SIZE_TO_VIEW 262144 // member int UserFileInteraction::fetch_context_items(BrowsableDirEntry *br, IndexedList &list) @@ -30,9 +33,10 @@ int UserFileInteraction::fetch_context_items(BrowsableDirEntry *br, IndexedList< list.append(new Action("Enter", UserFileInteraction::S_enter, 0)); count++; } - if ((info->size <= 262144) && (!(info->attrib & AM_DIR))) { + if ((info->size <= MAX_FILE_SIZE_TO_VIEW) && (!(info->attrib & AM_DIR))) { list.append(new Action("View", UserFileInteraction::S_view, 0)); - count++; + list.append(new Action("Hex View", UserFileInteraction::S_hex_view, 0)); + count += 2; } if (info->is_writable()) { list.append(new Action("Rename", UserFileInteraction::S_rename, 0)); @@ -131,7 +135,7 @@ int UserFileInteraction::S_delete(SubsysCommand *cmd) return 0; } -int UserFileInteraction::S_view(SubsysCommand *cmd) +int _view(SubsysCommand *cmd, EditorType editor_type) { FileManager *fm = FileManager::getFileManager(); File *f = 0; @@ -141,14 +145,31 @@ int UserFileInteraction::S_view(SubsysCommand *cmd) uint32_t size = f->get_size(); char *text_buf = new char[size + 1]; FRESULT fres = f->read(text_buf, size, &transferred); - printf("Res = %d. Read text buffer: %d bytes\n", fres, transferred); + printf("Res = %d. Read text buffer: %d bytes. File size: %d bytes\n", fres, transferred, size); text_buf[transferred] = 0; - cmd->user_interface->run_editor(text_buf, transferred); + switch (editor_type) { + case HEX_EDITOR: + cmd->user_interface->run_hex_editor(text_buf, transferred); + break; + default: + cmd->user_interface->run_editor(text_buf, transferred); + break; + } delete text_buf; } return 0; } +int UserFileInteraction::S_view(SubsysCommand *cmd) +{ + return _view(cmd, TEXT_EDITOR); +} + +int UserFileInteraction::S_hex_view(SubsysCommand *cmd) +{ + return _view(cmd, HEX_EDITOR); +} + int UserFileInteraction::S_createDir(SubsysCommand *cmd) { char buffer[64]; diff --git a/software/userinterface/user_file_interaction.h b/software/userinterface/user_file_interaction.h index bf7e6bf81..3119deec7 100644 --- a/software/userinterface/user_file_interaction.h +++ b/software/userinterface/user_file_interaction.h @@ -13,6 +13,8 @@ #include "subsys.h" #include "filemanager.h" +enum EditorType { TEXT_EDITOR, HEX_EDITOR}; + class Path; class Action; class BrowsableDirEntry; @@ -26,6 +28,7 @@ class UserFileInteraction : public SubSystem, ObjectWithMenu { static int S_rename(SubsysCommand *cmd); static int S_delete(SubsysCommand *cmd); static int S_view(SubsysCommand *cmd); + static int S_hex_view(SubsysCommand *cmd); static int S_createDir(SubsysCommand *cmd); static int S_runApp(SubsysCommand *cmd); diff --git a/software/userinterface/userinterface.cc b/software/userinterface/userinterface.cc index faa02717b..0ea64a36e 100644 --- a/software/userinterface/userinterface.cc +++ b/software/userinterface/userinterface.cc @@ -383,15 +383,24 @@ void UserInterface :: hide_progress(void) delete status_box; } -void UserInterface :: run_editor(const char *text_buf, int max_len) +void UserInterface :: run_editor(Editor *editor) { - Editor *edit = new Editor(this, text_buf, max_len); - edit->init(screen, keyboard); + editor->init(screen, keyboard); int ret; do { - ret = edit->poll(0); + ret = editor->poll(0); } while(!ret); - edit->deinit(); + editor->deinit(); +} + +void UserInterface :: run_editor(const char *text_buf, int max_len) +{ + run_editor(new Editor(this, text_buf, max_len)); +} + +void UserInterface :: run_hex_editor(const char *text_buf, int max_len) +{ + run_editor(new HexEditor(this, text_buf, max_len)); } int UserInterface :: enterSelection() diff --git a/software/userinterface/userinterface.h b/software/userinterface/userinterface.h index e7c14bc4d..0eeb1b212 100644 --- a/software/userinterface/userinterface.h +++ b/software/userinterface/userinterface.h @@ -28,6 +28,11 @@ #define CFG_USERIF_ULTICOPY_NAME 0x0B #define CFG_USERIF_FILENAME_OVERFLOW_SQUEEZE 0x0C +#define BYTES_PER_HEX_ROW 8 +#define CHARS_PER_HEX_ROW 37 + +class Editor; +class HexEditor; class UserInterface : public ConfigurableObject, public HostClient { private: @@ -45,6 +50,8 @@ class UserInterface : public ConfigurableObject, public HostClient void set_screen_title(void); bool pollFocussed(void); bool buttonDownFor(uint32_t ms); + void run_editor(Editor *); + UIStatusBox *status_box; public: int color_border, color_bg, color_fg, color_sel, color_sel_bg, config_save, filename_overflow_squeeze; @@ -83,6 +90,7 @@ class UserInterface : public ConfigurableObject, public HostClient int getPreferredType(void); void run_editor(const char *, int); + void run_hex_editor(const char *, int); void swapDisk(void); UIObject *get_root_object(void) { return ui_objects[0]; } diff --git a/target/u64/nios2/ultimate/Makefile b/target/u64/nios2/ultimate/Makefile index a3769e025..ba6344ad9 100755 --- a/target/u64/nios2/ultimate/Makefile +++ b/target/u64/nios2/ultimate/Makefile @@ -89,6 +89,7 @@ SRCS_CC = u2p_init.cc \ ui_elements.cc \ user_file_interaction.cc \ editor.cc \ + hex_editor.cc \ tree_browser.cc \ tree_browser_state.cc \ config_menu.cc \