Skip to content

Commit

Permalink
Merge pull request #17 from JC3/dev
Browse files Browse the repository at this point in the history
1.7.0
  • Loading branch information
JC3 authored Apr 27, 2023
2 parents 461536f + 432827d commit bd142ce
Show file tree
Hide file tree
Showing 11 changed files with 356 additions and 113 deletions.
56 changes: 42 additions & 14 deletions circuits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ using std::runtime_error;

namespace Circuits {

Blueprint * ROM (int addressBits, int dataBits, ROMDataLSBSide dataLSB, ROMAddress0Side addr0Side, const QVector<quint64> &data) {
Blueprint * ROM (int addressBits, int dataBits, ROMDataLSBSide dataLSB, ROMAddress0Side addr0Side, const QVector<quint64> &data, bool omitEmpty) {

const Blueprint::Ink trace = Blueprint::Trace1;
const Blueprint::Ink trace = Blueprint::Trace5;

if (omitEmpty && addr0Side == Far)
throw runtime_error("Empty columns can only be omitted if address 0 is set to input side. Sorry.");

// things will go nuts if bit counts are too high but for now just let
// things go nuts. maybe overflow checking some day.
quint64 addresses = 1ULL << addressBits;
int width = 3 + 2 * addresses + 1;
int height = 1 + 4 * (addressBits - 1) + 2 * dataBits;
int height = (omitEmpty ? 3 : 1) + 4 * (addressBits - 1) + 2 * dataBits;
qDebug() << "rom will be" << width << "x" << height;

Blueprint *bp = new Blueprint(width, height);
Expand All @@ -24,10 +27,20 @@ Blueprint * ROM (int addressBits, int dataBits, ROMDataLSBSide dataLSB, ROMAddre
row = height - 1;
for (int a = 0; a < addressBits; ++ a) {
if (a == 0) {
bp->set(0, row, Blueprint::Read);
bp->set(1, row, addr0Side == Far ? Blueprint::Buffer : Blueprint::Not);
bp->set(2, row, Blueprint::Write);
row -= 1;
if (omitEmpty) {
bp->set(1, row-2, Blueprint::Not);
bp->set(2, row-2, Blueprint::Write);
bp->set(0, row-1, trace);
bp->set(1, row-1, Blueprint::Read);
bp->set(1, row, Blueprint::Buffer);
bp->set(2, row, Blueprint::Write);
row -= 3;
} else {
bp->set(0, row, Blueprint::Read);
bp->set(1, row, addr0Side == Far ? Blueprint::Buffer : Blueprint::Not);
bp->set(2, row, Blueprint::Write);
row -= 1;
}
} else {
bp->set(1, row-3, Blueprint::Not);
bp->set(2, row-3, Blueprint::Write);
Expand Down Expand Up @@ -56,18 +69,19 @@ Blueprint * ROM (int addressBits, int dataBits, ROMDataLSBSide dataLSB, ROMAddre
}
}

// outputs
for (int bit = 0; bit < dataBits; ++ bit)
bp->set(width - 1, bit * 2, trace);
int lastColumn = 0;

// address and data bits
// to do: truncate if data vector smaller than address space
col = (addr0Side == Far ? (width - 2) : (width - 2 * addresses) );
bool isnor = (addr0Side == Far);
for (quint64 address = 0; address < addresses; ++ address) {

// ---- data bits
quint64 curdata = data.value(address);
if (omitEmpty && curdata == 0)
continue;

// ---- data bits
row = (dataLSB == Top ? 0 : (2 * (dataBits - 1)));
for (int bit = 0; bit < dataBits; ++ bit) {
if (curdata & (1ULL << bit))
Expand All @@ -84,10 +98,10 @@ Blueprint * ROM (int addressBits, int dataBits, ROMDataLSBSide dataLSB, ROMAddre
// i *could* simplify these to logical expressions, but this is why i suck at vcb.
bool rbuf = isnor ? (one ? false : true) : (one ? true : false);
bool rnot = !rbuf;
// there is no not row for the first bit
if (bit == 0) {
// there is no not row for the first bit when !omitEmpty
if (bit == 0 && !omitEmpty) {
/*assert(rbuf);
* if (rbuf)*/ bp->set(col, row, Blueprint::Read);
if (rbuf)*/ bp->set(col, row, Blueprint::Read);
row -= 2;
} else {
if (rbuf) bp->set(col, row, Blueprint::Read);
Expand All @@ -98,10 +112,24 @@ Blueprint * ROM (int addressBits, int dataBits, ROMDataLSBSide dataLSB, ROMAddre
isnor = !isnor;

// ---- advance
if (col > lastColumn) lastColumn = col;
col += (addr0Side == Far ? -2 : 2);

}

// remove extra columns if requested
if (omitEmpty) {
assert(addr0Side == Near);
for (int col = lastColumn + 1; col < width; ++ col)
for (int row = 0; row < height; ++ row) {
bp->set(col, row, Blueprint::Empty);
}
}

// outputs
for (int bit = 0; bit < dataBits; ++ bit)
bp->set(lastColumn + 1, bit * 2, trace);

return bp;

}
Expand Down
2 changes: 1 addition & 1 deletion circuits.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Circuits {
enum ROMDataLSBSide { Bottom=0, Top=1 };
enum ROMAddress0Side { Near=0, Far=1 };

Blueprint * ROM (int addressBits, int dataBits, ROMDataLSBSide dataLSB, ROMAddress0Side addr0Side, const QVector<quint64> &data);
Blueprint * ROM (int addressBits, int dataBits, ROMDataLSBSide dataLSB, ROMAddress0Side addr0Side, const QVector<quint64> &data, bool omitEmpty);
Blueprint * Text (QImage font, QString fontCharset, int kerning, QString text, Blueprint::Ink logicInk = Blueprint::Annotation, Blueprint::Ink decoOnInk = Blueprint::Invalid, Blueprint::Ink decoOffInk = Blueprint::Invalid);

}
Expand Down
33 changes: 33 additions & 0 deletions compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,39 @@ QStringList Compiler::analyzeCircuit (const AnalysisSettings &settings) const {
}


QStringList Compiler::analyzeBlueprint (const AnalysisSettings &settings, const Blueprint *blueprint) {

QStringList results;

const auto print = [&] (int x, int y, QString message) {
qDebug() << "bp analysis:" << x << y << message;
results.append(QString("%1, %2: %3").arg(x).arg(y).arg(message));
};

if (settings.checkCrosses) {
// super hacky, screw performance
for (int y = 0; y < blueprint->height(); ++ y) {
for (int x = 0; x < blueprint->width(); ++ x) {
try {
Component c = Comp(blueprint->get(x, y));
if (IsEmpty(c) || IsCross(c)) continue;
const auto sameas = [&](int px, int py) { Component o = Comp(blueprint->get(px, py)); return Same(c, o); };
if (sameas(x,y-1) && sameas(x,y+1) &&
sameas(x-1,y) && sameas(x+1,y) &&
!sameas(x-1,y-1) && !sameas(x+1,y-1) && !sameas(x-1,y+1) && !sameas(x+1,y+1))
{
print(x, y, "potentially missing cross");
}
} catch (...) { /* out of range coords; skip */ }
}
}
}

return results;

}


Compiler::ComplexGraph Compiler::buildComplexGraph (const SimpleGraph &sgraph) {

ComplexGraph nodes;
Expand Down
4 changes: 3 additions & 1 deletion compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,12 @@ class Compiler : public QObject {
struct AnalysisSettings {
bool checkTraces;
bool checkGates;
AnalysisSettings () : checkTraces(true), checkGates(true) { }
bool checkCrosses;
AnalysisSettings () : checkTraces(true), checkGates(true), checkCrosses(true) { }
};

QStringList analyzeCircuit (const AnalysisSettings &settings) const;
static QStringList analyzeBlueprint (const AnalysisSettings &settings, const Blueprint *blueprint);

private:

Expand Down
1 change: 1 addition & 0 deletions deploy.bat
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
cd vcbtool-win64
cp ..\release\vcbtool.exe .
cp ..\font_3x4.png .
cp ..\font_3x5.png .
cp ..\font_4x5.png .
cp ..\font_5x7.png .
Expand Down
Binary file added font_3x4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions fonts.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"3x4 (Boolean)": {
"file": "font_3x4.png",
"charset": "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.!?()[],:+-*/\\=^'\"|\u00AC "
},
"3x5": {
"file": "font_3x5.png",
"charset": "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789.!:+-*/\\=()[]|^&_<>\"'@~#,?%{}`\u00AC"
Expand Down
92 changes: 90 additions & 2 deletions mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ MainWindow::MainWindow(QWidget *parent)

ui_->setupUi(this);
ui_->lblROMWarning->setText("");
on_chkROMCSV_toggled(ui_->chkROMCSV->isChecked());
setWindowTitle(windowTitle() + " " + VCBTOOL_VERSION);

int defFontIndex = 0;
QFile fontsJson("fonts.json");
if (!fontsJson.open(QFile::ReadOnly | QFile::Text))
QMessageBox::critical(this, "Error", "Error loading fonts.json: " + fontsJson.errorString());
else {
QJsonObject data = QJsonDocument::fromJson(fontsJson.readAll()).object();
int index = 0;
for (QString name : data.keys()) {
QJsonObject jdesc = data[name].toObject();
FontDesc desc;
Expand All @@ -37,8 +40,11 @@ MainWindow::MainWindow(QWidget *parent)
desc.kerning = jdesc["kerning"].toInt(0);
fonts_[name] = desc;
ui_->cbTextFont->addItem(name);
if (name == "3x5") defFontIndex = index;
++ index;
}
}
ui_->cbTextFont->setCurrentIndex(defFontIndex);

QSettings s;
ui_->tabWidget->setCurrentIndex(s.value("tab", 0).toInt());
Expand Down Expand Up @@ -184,6 +190,8 @@ void MainWindow::on_btnROMGenerate_clicked()
int addrBits = ui_->spnROMAddrBits->value();
Circuits::ROMDataLSBSide dataLSB = (Circuits::ROMDataLSBSide)ui_->cbROMDataLSB->currentIndex();
Circuits::ROMAddress0Side addr0Side = (Circuits::ROMAddress0Side)ui_->cbAddress0->currentIndex();
int skipRows = ui_->spnROMSkipRows->value();
bool omitEmpty = ui_->chkROMOmit->isChecked();

QVector<quint64> data;

Expand All @@ -198,6 +206,8 @@ void MainWindow::on_btnROMGenerate_clicked()
QTextStream in(&csv);
QStringList row;
while (readCSVRow(in, &row)) {
if (skipRows-- > 0)
continue;
if (row.empty())
continue;
int address = row[0].toInt();
Expand Down Expand Up @@ -240,7 +250,7 @@ void MainWindow::on_btnROMGenerate_clicked()

}

Blueprint *bp = Circuits::ROM(addrBits, dataBits, dataLSB, addr0Side, data);
Blueprint *bp = Circuits::ROM(addrBits, dataBits, dataLSB, addr0Side, data, omitEmpty);
ui_->txtROMBP->setPlainText(bp->bpString());
delete bp;

Expand All @@ -254,6 +264,7 @@ void MainWindow::on_chkROMCSV_toggled(bool checked)
{
ui_->cbROMByteOrder->setEnabled(ui_->spnROMWordSize->value() > 1 && !checked);
ui_->spnROMWordSize->setEnabled(!checked);
ui_->spnROMSkipRows->setEnabled(checked);
}


Expand All @@ -269,6 +280,12 @@ void MainWindow::on_spnROMDataBits_valueChanged(int arg1)
}


void MainWindow::on_cbAddress0_activated(int index)
{
ui_->chkROMOmit->setEnabled(index == (int)Circuits::Near);
}


void MainWindow::on_btnNetlistCheck_clicked()
{
try {
Expand All @@ -277,7 +294,14 @@ void MainWindow::on_btnNetlistCheck_clicked()
Compiler::AnalysisSettings s;
s.checkTraces = ui_->chkUnconnectedTraces->isChecked();
s.checkGates = ui_->chk2InputGates->isChecked();
ui_->txtNetlistOut->setPlainText(c.analyzeCircuit(s).join("\n"));
s.checkCrosses = ui_->chkMissingCrosses->isChecked();
//ui_->txtNetlistOut->setPlainText(c.analyzeCircuit(s).join("\n"));
QStringList messages = c.analyzeCircuit(s);
messages += Compiler::analyzeBlueprint(s, &bp);
QString indexed;
for (int k = 0; k < messages.size(); ++ k)
indexed += QString::asprintf("%3d) %s\n", k + 1, messages[k].toLatin1().constData());
ui_->txtNetlistOut->setPlainText(indexed);
} catch (const std::exception &x) {
QMessageBox::critical(this, "Error", x.what());
}
Expand Down Expand Up @@ -410,3 +434,67 @@ void MainWindow::on_btnROMCSVHelp_clicked()
QMessageBox::information(this, "CSV File Format", "Each row represents an entry. The first column must contain the 0-based decimal address of the entry. Each remaining column contains a 0 or a 1. The last column will be the LSB of the data.");
}


void MainWindow::on_btnMiscGray8_clicked()
{
QStringList colors;
for (int g = 0; g <= 255; ++ g)
colors.append(QString::asprintf("%02x%02x%02x", g, g, g));
ui_->txtMisc->setPlainText(colors.join(", "));
}


void MainWindow::on_btnMiscRGB332_clicked()
{
static const auto rescale = [] (int v, int oldmax, int newmax) {
return qRound((float)newmax * (float)v / (float)oldmax);
};
QStringList colors;
for (int k = 0; k <= 255; ++ k) {
int r = rescale((k >> 5) & 7, 7, 255);
int g = rescale((k >> 2) & 7, 7, 255);
int b = rescale((k >> 0) & 3, 3, 255);
colors.append(QString::asprintf("%02x%02x%02x", r, g, b));
}
ui_->txtMisc->setPlainText(colors.join(", "));
}


void MainWindow::on_btnMiscX11_clicked()
{
const char palette[] =
"000000, 800000, 008000, 808000, 000080, 800080, 008080, c0c0c0, "
"808080, ff0000, 00ff00, ffff00, 0000ff, ff00ff, 00ffff, ffffff, "
"000000, 00005f, 000087, 0000af, 0000d7, 0000ff, 005f00, 005f5f, "
"005f87, 005faf, 005fd7, 005fff, 008700, 00875f, 008787, 0087af, "
"0087d7, 0087ff, 00af00, 00af5f, 00af87, 00afaf, 00afd7, 00afff, "
"00d700, 00d75f, 00d787, 00d7af, 00d7d7, 00d7ff, 00ff00, 00ff5f, "
"00ff87, 00ffaf, 00ffd7, 00ffff, 5f0000, 5f005f, 5f0087, 5f00af, "
"5f00d7, 5f00ff, 5f5f00, 5f5f5f, 5f5f87, 5f5faf, 5f5fd7, 5f5fff, "
"5f8700, 5f875f, 5f8787, 5f87af, 5f87d7, 5f87ff, 5faf00, 5faf5f, "
"5faf87, 5fafaf, 5fafd7, 5fafff, 5fd700, 5fd75f, 5fd787, 5fd7af, "
"5fd7d7, 5fd7ff, 5fff00, 5fff5f, 5fff87, 5fffaf, 5fffd7, 5fffff, "
"870000, 87005f, 870087, 8700af, 8700d7, 8700ff, 875f00, 875f5f, "
"875f87, 875faf, 875fd7, 875fff, 878700, 87875f, 878787, 8787af, "
"8787d7, 8787ff, 87af00, 87af5f, 87af87, 87afaf, 87afd7, 87afff, "
"87d700, 87d75f, 87d787, 87d7af, 87d7d7, 87d7ff, 87ff00, 87ff5f, "
"87ff87, 87ffaf, 87ffd7, 87ffff, af0000, af005f, af0087, af00af, "
"af00d7, af00ff, af5f00, af5f5f, af5f87, af5faf, af5fd7, af5fff, "
"af8700, af875f, af8787, af87af, af87d7, af87ff, afaf00, afaf5f, "
"afaf87, afafaf, afafd7, afafff, afd700, afd75f, afd787, afd7af, "
"afd7d7, afd7ff, afff00, afff5f, afff87, afffaf, afffd7, afffff, "
"d70000, d7005f, d70087, d700af, d700d7, d700ff, d75f00, d75f5f, "
"d75f87, d75faf, d75fd7, d75fff, d78700, d7875f, d78787, d787af, "
"d787d7, d787ff, d7af00, d7af5f, d7af87, d7afaf, d7afd7, d7afff, "
"d7d700, d7d75f, d7d787, d7d7af, d7d7d7, d7d7ff, d7ff00, d7ff5f, "
"d7ff87, d7ffaf, d7ffd7, d7ffff, ff0000, ff005f, ff0087, ff00af, "
"ff00d7, ff00ff, ff5f00, ff5f5f, ff5f87, ff5faf, ff5fd7, ff5fff, "
"ff8700, ff875f, ff8787, ff87af, ff87d7, ff87ff, ffaf00, ffaf5f, "
"ffaf87, ffafaf, ffafd7, ffafff, ffd700, ffd75f, ffd787, ffd7af, "
"ffd7d7, ffd7ff, ffff00, ffff5f, ffff87, ffffaf, ffffd7, ffffff, "
"080808, 121212, 1c1c1c, 262626, 303030, 3a3a3a, 444444, 4e4e4e, "
"585858, 626262, 6c6c6c, 767676, 808080, 8a8a8a, 949494, 9e9e9e, "
"a8a8a8, b2b2b2, bcbcbc, c6c6c6, d0d0d0, dadada, e4e4e4, eeeeee";
ui_->txtMisc->setPlainText(palette);
}

8 changes: 8 additions & 0 deletions mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ private slots:

void on_btnROMCSVHelp_clicked();

void on_btnMiscGray8_clicked();

void on_btnMiscRGB332_clicked();

void on_cbAddress0_activated(int index);

void on_btnMiscX11_clicked();

private:

struct FontDesc {
Expand Down
Loading

0 comments on commit bd142ce

Please sign in to comment.