mirror of
https://github.com/mrkite/regs.git
synced 2025-02-18 02:30:33 +00:00
bumped segment size, use better unicode arrows
This commit is contained in:
parent
2dbbc8866e
commit
ba9cf271a2
5
Makefile
5
Makefile
@ -1,11 +1,14 @@
|
||||
CC=clang
|
||||
CFLAGS=-Wall
|
||||
|
||||
all: 2mg regs
|
||||
all: 2mg regs dsk
|
||||
|
||||
2mg: FORCE
|
||||
$(MAKE) -C src ../2mg
|
||||
|
||||
dsk: FORCE
|
||||
$(MAKE) -C src ../dsk
|
||||
|
||||
regs: FORCE src/iigs.h
|
||||
$(MAKE) -C src ../regs
|
||||
|
||||
|
@ -787,6 +787,105 @@ ShieldCursor() {
|
||||
UnshieldCursor() {
|
||||
-4, $e01e9c
|
||||
}
|
||||
IRQSCAN() {
|
||||
-4, $e10028
|
||||
}
|
||||
IRQSOUND() {
|
||||
-4, $e1002c
|
||||
}
|
||||
IRQVBL() {
|
||||
-4, $e10030
|
||||
}
|
||||
IRQMOUSE() {
|
||||
-4, $e10034
|
||||
}
|
||||
IRQQTR() {
|
||||
-4, $e10038
|
||||
}
|
||||
IRQKBD() {
|
||||
-4, $e1003c
|
||||
}
|
||||
IRQRESPONSE() {
|
||||
-4, $e10040
|
||||
}
|
||||
IRQSRQ() {
|
||||
-4, $e10044
|
||||
}
|
||||
IRQDSKACC() {
|
||||
-4, $e10048
|
||||
}
|
||||
IRQFLUSH() {
|
||||
-4, $e1004c
|
||||
}
|
||||
IRQMICRO() {
|
||||
-4, $e10050
|
||||
}
|
||||
IRQ1SEC() {
|
||||
-4, $e10054
|
||||
}
|
||||
IRQEXT() {
|
||||
-4, $e10058
|
||||
}
|
||||
IRQOTHER() {
|
||||
-4, $e1005c
|
||||
}
|
||||
CUPDATE() {
|
||||
-4, $e10060
|
||||
}
|
||||
INCBUSYFLG() {
|
||||
-4, $e10064
|
||||
}
|
||||
DECBUSYFLG() {
|
||||
-4, $e10068
|
||||
}
|
||||
BELLVECTOR() {
|
||||
-4, $e1006c
|
||||
}
|
||||
BREAKVECTOR() {
|
||||
-4, $e10070
|
||||
}
|
||||
TRACEVECTOR() {
|
||||
-4, $e10074
|
||||
}
|
||||
STEPVECTOR() {
|
||||
-4, $e10078
|
||||
}
|
||||
TOWRITEBR() {
|
||||
-4, $e10080
|
||||
}
|
||||
TOREADBR() {
|
||||
-4, $e10084
|
||||
}
|
||||
TOWRITETIME() {
|
||||
-4, $e10088
|
||||
}
|
||||
TOREADTIME() {
|
||||
-4, $e1008c
|
||||
}
|
||||
TOCTRLPANEL() {
|
||||
-4, $e10090
|
||||
}
|
||||
TOBRAMSETUP() {
|
||||
-4, $e10094
|
||||
}
|
||||
TOPRINTMSG8() {
|
||||
-4, $e10098
|
||||
}
|
||||
TOPRINTMSG16() {
|
||||
-4, $e1009c
|
||||
}
|
||||
CTRLYVECTOR() {
|
||||
-4, $e100a0
|
||||
}
|
||||
TOTEXTPG2DA() {
|
||||
-4, $e100a4
|
||||
}
|
||||
PRO16MLI() {
|
||||
-4, $e100a8
|
||||
}
|
||||
MSGPOINTER() {
|
||||
-4, $e100c0
|
||||
}
|
||||
SystemVolume() {
|
||||
-4, $e100ca
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
OBJS = main.o omf.o handle.o map.o disasm.o api.o scanner.o
|
||||
OBJS2mg = 2mg.o handle.o
|
||||
OBJSdsk = dsk.o handle.o
|
||||
CXX = clang++
|
||||
CXXFLAGS = -g -Wall -std=c++11
|
||||
|
||||
@ -8,7 +9,10 @@ ifeq ($(UNAME), Darwin)
|
||||
LDFLAGS = -largp
|
||||
endif
|
||||
|
||||
all: ../regs ../2mg
|
||||
all: ../regs ../2mg ../dsk
|
||||
|
||||
../dsk: $(OBJSdsk)
|
||||
$(CXX) $(CXXFLAGS) $(LIBS) -o $@ $(LDFLAGS) $^
|
||||
|
||||
../2mg: $(OBJS2mg)
|
||||
$(CXX) $(CXXFLAGS) $(LIBS) -o $@ $(LDFLAGS) $^
|
||||
@ -20,4 +24,4 @@ all: ../regs ../2mg
|
||||
$(CXX) -c $(CXXFLAGS) -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f ../regs ../2mg $(OBJS) $(OBJS2mg)
|
||||
rm -f ../regs ../2mg ../dsk $(OBJS) $(OBJS2mg) $(OBJSdsk)
|
||||
|
233
src/dsk.cc
Normal file
233
src/dsk.cc
Normal file
@ -0,0 +1,233 @@
|
||||
/** @copyright 2020 Sean Kasun */
|
||||
|
||||
#include <argp.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <locale>
|
||||
#include <fstream>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include "handle.h"
|
||||
|
||||
const char *argp_program_version = "dsk 0.1";
|
||||
const char *argp_program_bug_address = "sean@seancode.com";
|
||||
static char doc[] = "Extract DOS3.3 disk images";
|
||||
static char args_doc[] = "DISKIMAGE";
|
||||
static struct argp_option options[] = {
|
||||
{"list", 'l', 0, 0, "List files"},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct arguments {
|
||||
const char *diskimage;
|
||||
bool list;
|
||||
};
|
||||
|
||||
static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
||||
struct arguments *arguments = static_cast<struct arguments *>(state->input);
|
||||
switch (key) {
|
||||
case 'l':
|
||||
arguments->list = true;
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (state->arg_num >= 1) {
|
||||
argp_usage(state);
|
||||
}
|
||||
arguments->diskimage = arg;
|
||||
break;
|
||||
case ARGP_KEY_END:
|
||||
if (state->arg_num < 1) {
|
||||
argp_usage(state);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct argp argp = { options, parse_opt, args_doc, doc };
|
||||
|
||||
static std::string readFilename(Handle h, int len) {
|
||||
static const char *digits = "0123456789abcdef";
|
||||
std::string r;
|
||||
for (int i = 0; i < len; i++) {
|
||||
uint8_t ch = h->r8();
|
||||
if (isalnum(ch) || ch == '_' || ch == '.' || ch == ' ') {
|
||||
r += static_cast<char>(ch);
|
||||
} else {
|
||||
r += 'x';
|
||||
uint8_t hi = ch >> 4;
|
||||
uint8_t lo = ch & 0xf;
|
||||
r += digits[hi];
|
||||
r += digits[lo];
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static const char *types[] = {
|
||||
"TXT", // 00
|
||||
"INT", // 01
|
||||
"BAS", // 02
|
||||
nullptr, // 03
|
||||
"BIN", // 04
|
||||
nullptr, // 05
|
||||
nullptr, // 06
|
||||
nullptr, // 07
|
||||
"S", // 08
|
||||
nullptr, // 09
|
||||
nullptr, // 0a
|
||||
nullptr, // 0b
|
||||
nullptr, // 0c
|
||||
nullptr, // 0d
|
||||
nullptr, // 0e
|
||||
nullptr, // 0f
|
||||
"REL", // 10
|
||||
};
|
||||
|
||||
#define numTypes (sizeof(types) / sizeof(types[0]))
|
||||
|
||||
static uint16_t doFile(uint8_t track, uint8_t sector, uint8_t type,
|
||||
std::string name, uint16_t length, Handle h) {
|
||||
auto data = std::vector<uint8_t>((length + 1) * 256);
|
||||
auto listTrack = track;
|
||||
auto listSector = sector;
|
||||
while (listTrack) {
|
||||
h->seek(listTrack * 16 * 256 + listSector * 256 + 1);
|
||||
listTrack = h->r8();
|
||||
listSector = h->r8();
|
||||
h->skip(2);
|
||||
auto offset = h->r16();
|
||||
h->skip(5);
|
||||
std::vector<uint8_t> pairs;
|
||||
for (auto i = 0; i < 0x7a * 2; i++) {
|
||||
pairs.push_back(h->r8());
|
||||
}
|
||||
for (auto i = 0; i < pairs.size(); i += 2) {
|
||||
if (pairs[i] == 0) {
|
||||
continue;
|
||||
}
|
||||
h->seek(pairs[i] * 256 * 16 + pairs[i + 1] * 256);
|
||||
auto v = h->readBytes(256);
|
||||
std::copy(v.begin(), v.end(), data.begin() + offset);
|
||||
offset += 256;
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 0x00: // text, run until null
|
||||
for (auto i = 0; i < data.size(); i++) {
|
||||
if (data[i] == '\0') {
|
||||
data.resize(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x01: // int basic
|
||||
case 0x02: // applesoft basic
|
||||
{
|
||||
auto wrap = TheHandle::createFromArray(data);
|
||||
auto len = wrap->r16();
|
||||
data = wrap->readBytes(len);
|
||||
}
|
||||
break;
|
||||
case 0x04: // binary
|
||||
{
|
||||
auto wrap = TheHandle::createFromArray(data);
|
||||
auto meta = wrap->r16();
|
||||
if (name.empty()) { // we just want the meta data
|
||||
return meta;
|
||||
}
|
||||
auto len = wrap->r16();
|
||||
data = wrap->readBytes(len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
std::ofstream f(name, std::ios::out | std::ios::binary | std::ios::trunc);
|
||||
if (!f.is_open()) {
|
||||
std::cerr << "Failed to create " << name << std::endl;
|
||||
return -1;
|
||||
}
|
||||
f.write((const char *)&data[0], data.size());
|
||||
f.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void catalog(uint8_t track, uint8_t sector, Handle h, int depth) {
|
||||
h->seek(track * 16 * 256 + sector * 256 + 1);
|
||||
auto nextTrack = h->r8();
|
||||
auto nextSector = h->r8();
|
||||
h->skip(8);
|
||||
auto ofs = h->tell();
|
||||
for (auto i = 0; i < 7; i++) {
|
||||
h->seek(ofs + i * 35);
|
||||
auto ftrack = h->r8();
|
||||
auto fsector = h->r8();
|
||||
auto type = h->r8() & 0x7f;
|
||||
auto name = readFilename(h, 30);
|
||||
auto length = h->r16();
|
||||
if (ftrack != 0xff && ftrack != 0x00) {
|
||||
if (depth < 0) {
|
||||
doFile(ftrack, fsector, type, name, length, h);
|
||||
} else {
|
||||
std::cout << name << std::endl << "Type: ";
|
||||
if (type < numTypes && types[type] != nullptr) {
|
||||
std::cout << types[type] << std::endl;
|
||||
} else {
|
||||
std::cout << static_cast<int>(type);
|
||||
if (type == 0x04) { // binary
|
||||
std::cout << std::hex << "("
|
||||
<< doFile(ftrack, fsector, type, "", length, h)
|
||||
<< ")" << std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << "Blocks: " << length << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nextTrack != 0) {
|
||||
catalog(nextTrack, nextSector, h, depth);
|
||||
}
|
||||
}
|
||||
|
||||
class MyPunct : public std::numpunct<char> {
|
||||
protected:
|
||||
virtual char do_thousands_sep() const { return ','; }
|
||||
virtual std::string do_grouping() const { return "\03"; }
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct arguments arguments;
|
||||
arguments.list = false;
|
||||
|
||||
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
||||
|
||||
std::cout.imbue(std::locale(std::locale::classic(), new MyPunct));
|
||||
|
||||
auto h = TheHandle::createFromFile(arguments.diskimage);
|
||||
if (!h->isOpen()) {
|
||||
std::cerr << "Failed to open " << arguments.diskimage << std::endl;
|
||||
return -1;
|
||||
}
|
||||
if (h->length != 143360) {
|
||||
std::cerr << arguments.diskimage << " is not a valid DOS 3.3 disk image"
|
||||
<< std::endl;
|
||||
return -1;
|
||||
}
|
||||
h->seek(17 * 16 * 256 + 1);
|
||||
auto catTrack = h->r8();
|
||||
auto catSector = h->r8();
|
||||
h->skip(0x24);
|
||||
auto pairs = h->r8();
|
||||
h->skip(0xc);
|
||||
auto numTracks = h->r8();
|
||||
auto numSectors = h->r8();
|
||||
if (pairs != 0x7a || numTracks != 35 || numSectors != 16 ||
|
||||
catTrack >= numTracks || catSector >= numSectors) {
|
||||
std::cerr << arguments.diskimage << " is not a valid DOS 3.3 disk image"
|
||||
<< std::endl;
|
||||
return -1;
|
||||
}
|
||||
catalog(catTrack, catSector, h, arguments.list ? 0 : -1);
|
||||
}
|
30142
src/iigs.h
30142
src/iigs.h
File diff suppressed because it is too large
Load Diff
@ -125,13 +125,13 @@ bool OMF::mapSegments() {
|
||||
for (auto &seg : segments) {
|
||||
if (seg.org) { // segment wants to be somewhere specific, no direct map
|
||||
canDirectMap = false;
|
||||
} else if (seg.length > 0xffff) { // segment too long for a single bank
|
||||
} else if (seg.length > 0xfffff) { // segment too long for a single bank
|
||||
canDirectMap = false;
|
||||
}
|
||||
}
|
||||
if (canDirectMap) {
|
||||
for (auto &seg : segments) {
|
||||
seg.mapped = seg.segnum << 16;
|
||||
seg.mapped = seg.segnum << 20;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ bool Scanner::disassemble(std::ostream &f, uint32_t from, uint32_t to,
|
||||
std::string preds;
|
||||
for (auto pred : b->preds) {
|
||||
if (pred->address + pred->length != b->address && count++ < 7) {
|
||||
preds += (pred->address < b->address) ? u8"\u2b06 " : u8"\u2b07 ";
|
||||
preds += (pred->address < b->address) ? u8"\u25b2 " : u8"\u25bc ";
|
||||
preds += hex(pred->address + pred->length - pred->branchLen, 6);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user