Skip to content

Instantly share code, notes, and snippets.

@leiradel
Created March 5, 2026 18:10
Show Gist options
  • Select an option

  • Save leiradel/dfa70ca201db7119ba891f6d7a97b2e5 to your computer and use it in GitHub Desktop.

Select an option

Save leiradel/dfa70ca201db7119ba891f6d7a97b2e5 to your computer and use it in GitHub Desktop.
A small function that creates a listing of a ZX Spectrum BASIC program
// Original code by Mike Daley
// License: MIT
std::string listbasic(const Memory& mem, uint64_t offset) {
uint64_t size = mem.size();
std::string listing;
while (offset + 4 <= size) {
uint16_t const lineNumber = mem.peekU16BE(offset);
uint16_t const lineLength = mem.peekU16LE(offset + 2);
if (lineNumber > 9999 || lineLength == 0) {
break;
}
uint64_t const bodyStart = offset + 4;
uint64_t const lineEnd = bodyStart + lineLength;
if (lineEnd > size) {
break;
}
std::string text;
uint64_t pos = bodyStart;
while (pos < lineEnd) {
uint8_t const byte = mem.peek(pos);
if (byte == 0x0d) {
break;
}
// Number marker: skip 0x0e + 5-byte floating point
if (byte == 0x0e) {
pos += 6;
continue;
}
// Colour control codes (INK..OVER): 1 param byte
if (byte >= 0x10 && byte <= 0x15) {
pos += 2;
continue;
}
// AT/TAB control: 2 param bytes
if (byte >= 0x16 && byte <= 0x17) {
pos += 3;
continue;
}
// Token (0xa5-0xff)
if (byte >= 0xa5) {
const char* keyword = tokenToKeyword(byte);
if (keyword != nullptr) {
if (!text.empty() && text.back() != ' ') {
text += ' ';
}
text += keyword;
size_t const kwLen = std::strlen(keyword);
char last = keyword[kwLen - 1];
if ((last >= 'A' && last <= 'Z') || last == '$' || last == '#') {
text += ' ';
}
}
pos++;
continue;
}
// Printable ASCII
if (byte >= 0x20 && byte < 0x80) {
text += (char)byte;
pos++;
continue;
}
// Skip other control codes
pos++;
}
// Trim leading/trailing spaces
size_t start = text.find_first_not_of(' ');
size_t end = text.find_last_not_of(' ');
listing += std::to_string(lineNumber);
listing += ' ';
if (start != std::string::npos) {
listing.append(text, start, end - start + 1);
}
listing += '\n';
offset = lineEnd;
}
return listing;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment