Add log window and QDebug redirections

This commit is contained in:
Anthony Rabine 2023-04-25 11:55:51 +02:00
parent adb6c7ccc0
commit 2377da1c54
9 changed files with 157 additions and 6 deletions

View file

@ -132,11 +132,15 @@ static inline void leu16_put(std::vector<std::uint8_t> &container, uint16_t data
} }
#define GET_REG(name, ra) if (!GetRegister(name, ra)) {\ #define GET_REG(name, ra) if (!GetRegister(name, ra)) {\
std::cout << "ERROR! Bad register name: " << name << std::endl;\ std::stringstream ss; \
ss << "ERROR! Bad register name: " << name << std::endl;\
m_lastError = ss.str(); \
return false; } return false; }
#define CHIP32_CHECK(instr, cond, error) if (!(cond)) { \ #define CHIP32_CHECK(instr, cond, error) if (!(cond)) { \
std::cout << "error line: " << instr.line << ": " << error << std::endl; \ std::stringstream ss; \
ss << "error line: " << instr.line << ": " << error << std::endl; \
m_lastError = ss.str(); \
return false; } \ return false; } \
// ============================================================================= // =============================================================================
@ -457,7 +461,7 @@ bool Assembler::Parse(const std::string &data)
std::string label = instr.args[argsIndex]; std::string label = instr.args[argsIndex];
CHIP32_CHECK(instr, m_labels.count(label) > 0, "label not found: " << label); CHIP32_CHECK(instr, m_labels.count(label) > 0, "label not found: " << label);
uint16_t addr = m_labels[label].addr; uint16_t addr = m_labels[label].addr;
std::cout << "LABEL: " << label << " , addr: " << addr << std::endl; // std::cout << "LABEL: " << label << " , addr: " << addr << std::endl;
instr.compiledArgs[argsIndex] = addr & 0xFF; instr.compiledArgs[argsIndex] = addr & 0xFF;
instr.compiledArgs[argsIndex+1] = (addr >> 8U) & 0xFF; instr.compiledArgs[argsIndex+1] = (addr >> 8U) & 0xFF;
if (instr.code.opcode == OP_LCONS) { if (instr.code.opcode == OP_LCONS) {

View file

@ -104,12 +104,16 @@ public:
bool GetRegister(const std::string &regName, uint8_t &reg); bool GetRegister(const std::string &regName, uint8_t &reg);
bool GetRegisterName(uint8_t reg, std::string &regName); bool GetRegisterName(uint8_t reg, std::string &regName);
std::string GetLastError() { return m_lastError; }
private: private:
bool CompileMnemonicArguments(Instr &instr); bool CompileMnemonicArguments(Instr &instr);
// label, address // label, address
std::map<std::string, Instr> m_labels; std::map<std::string, Instr> m_labels;
std::string m_lastError;
std::vector<Instr> m_instructions; std::vector<Instr> m_instructions;
bool CompileConstantArguments(Instr &instr); bool CompileConstantArguments(Instr &instr);
}; };

View file

@ -43,6 +43,8 @@ set(PROJECT_SOURCES
src/nodeeditor_dock.cpp src/nodeeditor_dock.cpp
src/osthmi_dock.h src/osthmi_dock.h
src/osthmi_dock.cpp src/osthmi_dock.cpp
src/log_dock.h
src/log_dock.cpp
src/vm_dock.h src/vm_dock.h
src/vm_dock.cpp src/vm_dock.cpp
src/code_editor.h src/code_editor.h

View file

@ -0,0 +1,34 @@
#include "log_dock.h"
LogDock::LogDock()
: QDockWidget(tr("Logs"))
{
setObjectName("OstHmiDock"); // used to save the state
m_logUi.setupUi(this);
}
void LogDock::Append(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
// const char *file = context.file ? context.file : "";
// const char *function = context.function ? context.function : "";
switch (type) {
// case QtDebugMsg:
// fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
// break;
// case QtInfoMsg:
// fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
// break;
// case QtWarningMsg:
// fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
// break;
case QtCriticalMsg:
m_logUi.logText->appendHtml("<font color=\"Red\">" + msg + "</font>");
break;
// case QtFatalMsg:
// fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
default:
m_logUi.logText->appendHtml("<font color=\"Aqua\">" + msg + "</font>");
break;
}
}

View file

@ -0,0 +1,18 @@
#ifndef LOGDOCK_H
#define LOGDOCK_H
#include <QDockWidget>
#include "ui_ost-log.h"
class LogDock : public QDockWidget
{
public:
LogDock();
void Append(QtMsgType type, const QMessageLogContext &context, const QString &msg);
private:
Ui::ostLog m_logUi;
};
#endif // LOGDOCK_H

View file

@ -21,6 +21,7 @@
#include <QTreeWidget> #include <QTreeWidget>
#include <QHeaderView> #include <QHeaderView>
#include <QSettings> #include <QSettings>
#include <QtDebug>
#include <QtNodes/BasicGraphicsScene> #include <QtNodes/BasicGraphicsScene>
#include <QtNodes/ConnectionStyle> #include <QtNodes/ConnectionStyle>
@ -42,10 +43,17 @@ using QtNodes::StyleCollection;
int nodeX = 0.0; int nodeX = 0.0;
typedef void (*message_output_t)(QtMsgType , const QMessageLogContext &, const QString &);
MainWindow::MainWindow() MainWindow::MainWindow()
: m_model(m_project) : m_model(m_project)
, m_scene(m_model) , m_scene(m_model)
{ {
Callback<void(QtMsgType , const QMessageLogContext &, const QString &)>::func = std::bind(&MainWindow::MessageOutput, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
auto cb = static_cast<message_output_t>(Callback<void(QtMsgType , const QMessageLogContext &, const QString &)>::callback);
qInstallMessageHandler(cb);
m_toolbar = new ToolBar(); m_toolbar = new ToolBar();
m_scene.setDropShadowEffect(false); m_scene.setDropShadowEffect(false);
m_scene.nodeGeometry().setMarginsRatio(0.02); m_scene.nodeGeometry().setMarginsRatio(0.02);
@ -53,6 +61,9 @@ MainWindow::MainWindow()
addToolBar(m_toolbar); addToolBar(m_toolbar);
createStatusBar(); createStatusBar();
m_logDock = new LogDock();
addDockWidget(Qt::DockWidgetArea::BottomDockWidgetArea, m_logDock);
m_nodeEditorDock = new NodeEditorDock(&m_scene); m_nodeEditorDock = new NodeEditorDock(&m_scene);
addDockWidget(Qt::DockWidgetArea::LeftDockWidgetArea, m_nodeEditorDock); addDockWidget(Qt::DockWidgetArea::LeftDockWidgetArea, m_nodeEditorDock);
m_toolbar->addAction(m_nodeEditorDock->toggleViewAction()); m_toolbar->addAction(m_nodeEditorDock->toggleViewAction());
@ -101,7 +112,6 @@ MainWindow::MainWindow()
m_romView = new MemoryViewDock("RomViewDock", "ROM"); m_romView = new MemoryViewDock("RomViewDock", "ROM");
addDockWidget(Qt::DockWidgetArea::RightDockWidgetArea, m_romView); addDockWidget(Qt::DockWidgetArea::RightDockWidgetArea, m_romView);
m_chooseFileDialog = new QDialog(this); m_chooseFileDialog = new QDialog(this);
m_chooseFileUi.setupUi(m_chooseFileDialog); m_chooseFileUi.setupUi(m_chooseFileDialog);
m_chooseFileDialog->close(); m_chooseFileDialog->close();
@ -148,9 +158,14 @@ MainWindow::MainWindow()
Callback<uint8_t(uint8_t)>::func = std::bind(&MainWindow::Syscall, this, std::placeholders::_1); Callback<uint8_t(uint8_t)>::func = std::bind(&MainWindow::Syscall, this, std::placeholders::_1);
m_chip32_ctx.syscall = static_cast<syscall_t>(Callback<uint8_t(uint8_t)>::callback); m_chip32_ctx.syscall = static_cast<syscall_t>(Callback<uint8_t(uint8_t)>::callback);
readSettings(); readSettings();
qDebug() << "Started StoryTeller Editor";
}
void MainWindow::MessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
m_logDock->Append(type, context, msg);
} }
void MainWindow::readSettings() void MainWindow::readSettings()
@ -359,6 +374,14 @@ void MainWindow::buildScript()
updateAll(); updateAll();
DebugContext::DumpCodeAssembler(m_assembler); DebugContext::DumpCodeAssembler(m_assembler);
} }
else
{
qCritical() << m_assembler.GetLastError().c_str();
}
}
else
{
qCritical() << m_assembler.GetLastError().c_str();
} }
} }

View file

@ -42,6 +42,7 @@ using QtNodes::NodeDelegateModelRegistry;
#include "memory_view_dock.h" #include "memory_view_dock.h"
#include "osthmi_dock.h" #include "osthmi_dock.h"
#include "nodeeditor_dock.h" #include "nodeeditor_dock.h"
#include "log_dock.h"
#include "toolbar.h" #include "toolbar.h"
struct DebugContext struct DebugContext
@ -132,6 +133,7 @@ private:
VmDock *m_vmDock{nullptr}; VmDock *m_vmDock{nullptr};
MemoryViewDock *m_ramView{nullptr}; MemoryViewDock *m_ramView{nullptr};
MemoryViewDock *m_romView{nullptr}; MemoryViewDock *m_romView{nullptr};
LogDock *m_logDock{nullptr};
QDialog *m_chooseFileDialog; QDialog *m_chooseFileDialog;
Ui::chooseFileDIalog m_chooseFileUi; Ui::chooseFileDIalog m_chooseFileUi;
@ -162,6 +164,7 @@ private:
QString GetFileName(uint32_t addr); QString GetFileName(uint32_t addr);
bool event(QEvent *event); bool event(QEvent *event);
void MessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
}; };
#endif // MAIN_WINDOW_H #endif // MAIN_WINDOW_H

View file

@ -3,6 +3,7 @@
#include <QPixmap> #include <QPixmap>
OstHmiDock::OstHmiDock() OstHmiDock::OstHmiDock()
: QDockWidget(tr("StoryTeller HMI"))
{ {
setObjectName("OstHmiDock"); // used to save the state setObjectName("OstHmiDock"); // used to save the state
m_uiOstDisplay.setupUi(this); m_uiOstDisplay.setupUi(this);

View file

@ -1,6 +1,7 @@
#include "script_editor_dock.h" #include "script_editor_dock.h"
static const std::string test1 = R"(; jump over the data, to our entry label static const std::string test1 = R"(
; jump over the data, to our entry label
jump .entry jump .entry
; Constant elements are separated by commas ; Constant elements are separated by commas
@ -21,6 +22,66 @@ $RamData1 DV32 1 ; one 32-bit integer
lcons r1, $soundChoice ; set to 0 if no sound lcons r1, $soundChoice ; set to 0 if no sound
syscall 1 syscall 1
mov r1, sp ; save sp address in R1 (first element)
lcons r0, .MEDIA_02
push r0
lcons r0, .MEDIA_03
push r0
lcons r2, 3 ; 3 iterations
jmp .media
; Generic media choice manager
.media:
; Les adresses des différents medias sont dans la stack
; Arguments:
; r1: address of the first media address
; r2: nombre d'itérations
; Local:
; r0: loop counter
; r3: increment
; r4: current media address
.media_loop_start:
mov r0, r2 ; i = 3
mov r4, r1 ; current_media = @media
.media_loop:
lcons r3, 1
sub r0, r3 ; i--
lcons r3, 4
add r4, r3 ; @++
skipnz r0 ; if (r0) goto start_loop;
jmp .media_loop_start
push sp
push r0
push r1
call r4
pop r1
pop r0
pop sp
; TODO: wait for event
jmp .media_loop
.MEDIA_02:
lcons r0, $imageBird ; image name address in ROM located in R0 (null terminated)
lcons r1, $soundChoice ; set to 0 if no sound
syscall 1
ret
.MEDIA_03:
lcons r0, $imageBird ; image name address in ROM located in R0 (null terminated)
lcons r1, $soundChoice ; set to 0 if no sound
syscall 1
ret
.SYSCALL_TEST:
; syscall test: wait for event ; syscall test: wait for event
lcons r0, 0xFF ; wait for all event, blocking lcons r0, 0xFF ; wait for all event, blocking
syscall 2 syscall 2
@ -43,6 +104,7 @@ $RamData1 DV32 1 ; one 32-bit integer
mov R0,R2 ; copy R2 into R0 (NO blank space between , and R2) mov R0,R2 ; copy R2 into R0 (NO blank space between , and R2)
halt halt
)"; )";