fix indentation before it is too late

This commit is contained in:
Wolfgang Thaller
2014-09-15 00:43:30 +02:00
parent 02c92021ab
commit 822c9f3dbf
12 changed files with 908 additions and 910 deletions

View File

@@ -24,28 +24,28 @@
class Console class Console
{ {
public: public:
Console(GrafPtr port, Rect r); Console(GrafPtr port, Rect r);
~Console(); ~Console();
void Draw(); void Draw();
void putch(char c); void putch(char c);
std::string ReadLine(); std::string ReadLine();
static Console *currentInstance; static Console *currentInstance;
private: private:
GrafPtr consolePort; GrafPtr consolePort;
Rect bounds; Rect bounds;
std::vector<char> chars; std::vector<char> chars;
short cellSizeX; short cellSizeX;
short cellSizeY; short cellSizeY;
short rows, cols;
short cursorX, cursorY; short rows, cols;
Rect CellRect(short x, short y); short cursorX, cursorY;
void DrawCell(short x, short y);
void ScrollUp(short n = 1); Rect CellRect(short x, short y);
void DrawCell(short x, short y);
void ScrollUp(short n = 1);
}; };

View File

@@ -1,20 +1,20 @@
/* /*
Copyright 2012 Wolfgang Thaller. Copyright 2012 Wolfgang Thaller.
This file is part of Retro68. This file is part of Retro68.
Retro68 is free software: you can redistribute it and/or modify Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Retro68 is distributed in the hope that it will be useful, Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>. along with Retro68. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdio.h> #include <stdio.h>
@@ -37,7 +37,7 @@ QDGlobals qd;
__attribute((constructor)) __attribute((constructor))
void cons() void cons()
{ {
SysBeep(20); SysBeep(20);
} }
//float something = 6.0; //float something = 6.0;
@@ -48,7 +48,7 @@ class Foo
void foobar() void foobar()
{ {
throw Foo(); throw Foo();
} }
void foobaz() void foobaz()
@@ -59,10 +59,10 @@ extern ssize_t (*__write_hook)(int fd, const void*buf, size_t count);
extern "C" ssize_t consolewrite(int fd, const void *buf, size_t count) extern "C" ssize_t consolewrite(int fd, const void *buf, size_t count)
{ {
const char *p = (const char*)buf; const char *p = (const char*)buf;
for(int i = 0; i < count; i++) for(int i = 0; i < count; i++)
Console::currentInstance->putch(*p++); Console::currentInstance->putch(*p++);
return count; return count;
} }
extern ssize_t (*__read_hook)(int fd, void*buf, size_t count); extern ssize_t (*__read_hook)(int fd, void*buf, size_t count);
@@ -78,67 +78,67 @@ extern "C" ssize_t consoleread(int fd, void *buf, size_t count)
count = consoleBuf.size(); count = consoleBuf.size();
memcpy(buf, consoleBuf.data(), count); memcpy(buf, consoleBuf.data(), count);
consoleBuf = consoleBuf.substr(count); consoleBuf = consoleBuf.substr(count);
return count; return count;
} }
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
//GrafPort port; //GrafPort port;
WindowPtr win; WindowPtr win;
InitGraf(&qd.thePort); InitGraf(&qd.thePort);
InitFonts(); InitFonts();
InitWindows(); InitWindows();
InitMenus(); InitMenus();
Rect r; Rect r;
SetRect(&r, qd.screenBits.bounds.left + 5, qd.screenBits.bounds.top + 45, qd.screenBits.bounds.right - 5, qd.screenBits.bounds.bottom -5); SetRect(&r, qd.screenBits.bounds.left + 5, qd.screenBits.bounds.top + 45, qd.screenBits.bounds.right - 5, qd.screenBits.bounds.bottom -5);
win = NewWindow(NULL, &r, PSTR("Retro68 Console"), true, 0, (WindowPtr)-1, false, 0); win = NewWindow(NULL, &r, PSTR("Retro68 Console"), true, 0, (WindowPtr)-1, false, 0);
SetPort(win); SetPort(win);
EraseRect(&win->portRect); EraseRect(&win->portRect);
new char[32]; new char[32];
Console console(win, win->portRect); Console console(win, win->portRect);
__write_hook = &consolewrite; __write_hook = &consolewrite;
__read_hook = &consoleread; __read_hook = &consoleread;
printf("Hello, world.\n"); printf("Hello, world.\n");
std::cout << "Hello, world, again.\n"; std::cout << "Hello, world, again.\n";
printf("Say something: "); printf("Say something: ");
fflush(stdout); fflush(stdout);
printf("You said: %s\n", console.ReadLine().c_str()); printf("You said: %s\n", console.ReadLine().c_str());
char buffer[100]; char buffer[100];
printf("Say something else: "); printf("Say something else: ");
fflush(stdout); fflush(stdout);
fgets(buffer, 100, stdin); fgets(buffer, 100, stdin);
printf("You said: %s\n", buffer); printf("You said: %s\n", buffer);
for(int i = 0; i < 5; i++) for(int i = 0; i < 5; i++)
{ {
int n = i == 0 ? 1 : 100; int n = i == 0 ? 1 : 100;
printf("Exception speed test (%3d iterations): ", n); fflush(stdout); printf("Exception speed test (%3d iterations): ", n); fflush(stdout);
long start = TickCount(); long start = TickCount();
for(int j = 0; j < n; j++) for(int j = 0; j < n; j++)
{ {
try { foobar(); } catch(...) {} try { foobar(); } catch(...) {}
} }
long end = TickCount(); long end = TickCount();
printf("%g ms per throw/catch\n",(end-start)*1000 / 60.0 / n); printf("%g ms per throw/catch\n",(end-start)*1000 / 60.0 / n);
} }
const int n = 3; const int n = 3;
printf("Click mouse %d times...\n", n); printf("Click mouse %d times...\n", n);
for(int i = 0; i < n; i++) for(int i = 0; i < n; i++)
{ {
while(!Button()) while(!Button())
; ;
while(Button()) while(Button())
; ;
printf("Click #%d\n", i+1); printf("Click #%d\n", i+1);
} }
FlushEvents(everyEvent, 0); FlushEvents(everyEvent, 0);
return 0; return 0;
} }

View File

@@ -1,20 +1,20 @@
/* /*
Copyright 2012 Wolfgang Thaller. Copyright 2012 Wolfgang Thaller.
This file is part of Retro68. This file is part of Retro68.
Retro68 is free software: you can redistribute it and/or modify Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Retro68 is distributed in the hope that it will be useful, Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>. along with Retro68. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <fstream> #include <fstream>
@@ -32,406 +32,406 @@ std::string commandPath;
void wrapMacBinary(std::string macBinaryFile, std::string diskImagePath) void wrapMacBinary(std::string macBinaryFile, std::string diskImagePath)
{ {
int size = static_cast<int>( int size = static_cast<int>(
std::ifstream(macBinaryFile.c_str()).seekg(0,std::ios::end).tellg() std::ifstream(macBinaryFile.c_str()).seekg(0,std::ios::end).tellg()
); );
size += 20 * 1024; size += 20 * 1024;
size += 800*1024 - size % (800*1024); size += 800*1024 - size % (800*1024);
std::ofstream(diskImagePath.c_str(), std::ios::binary | std::ios::trunc).seekp(size-1).put(0); std::ofstream(diskImagePath.c_str(), std::ios::binary | std::ios::trunc).seekp(size-1).put(0);
std::system((commandPath + "hformat " + diskImagePath + " > /dev/null").c_str()); std::system((commandPath + "hformat " + diskImagePath + " > /dev/null").c_str());
std::system((commandPath + "hcopy -m " + macBinaryFile + " :").c_str()); std::system((commandPath + "hcopy -m " + macBinaryFile + " :").c_str());
} }
class Resource class Resource
{ {
std::string type; std::string type;
int id; int id;
std::string name; std::string name;
std::string data; std::string data;
public: public:
Resource(std::string type, int id, std::string data) Resource(std::string type, int id, std::string data)
: type(type), id(id), data(data) {} : type(type), id(id), data(data) {}
const std::string& getData() const { return data; } const std::string& getData() const { return data; }
inline std::string getType() const { return type; } inline std::string getType() const { return type; }
inline int getID() const { return id; } inline int getID() const { return id; }
}; };
class Fork class Fork
{ {
public: public:
virtual void writeFork(std::ostream& out) const { } virtual void writeFork(std::ostream& out) const { }
virtual ~Fork() {} virtual ~Fork() {}
}; };
class Resources : public Fork class Resources : public Fork
{ {
std::vector<Resource> resources; std::vector<Resource> resources;
public: public:
void writeFork(std::ostream& out) const; void writeFork(std::ostream& out) const;
void addResource(Resource res) { resources.push_back(res); } void addResource(Resource res) { resources.push_back(res); }
}; };
void byte(std::ostream& out, int byte) void byte(std::ostream& out, int byte)
{ {
out.put((unsigned char)byte); out.put((unsigned char)byte);
} }
void word(std::ostream& out, int word) void word(std::ostream& out, int word)
{ {
byte(out,(word >> 8) & 0xFF); byte(out,(word >> 8) & 0xFF);
byte(out,word & 0xFF); byte(out,word & 0xFF);
} }
void ostype(std::ostream& out, std::string type) void ostype(std::ostream& out, std::string type)
{ {
assert(type.size() == 4); assert(type.size() == 4);
out << type; out << type;
} }
void longword(std::ostream& out, int longword) void longword(std::ostream& out, int longword)
{ {
byte(out,(longword >> 24) & 0xFF); byte(out,(longword >> 24) & 0xFF);
byte(out,(longword >> 16) & 0xFF); byte(out,(longword >> 16) & 0xFF);
byte(out,(longword >> 8) & 0xFF); byte(out,(longword >> 8) & 0xFF);
byte(out,longword & 0xFF); byte(out,longword & 0xFF);
} }
void Resources::writeFork(std::ostream& out) const void Resources::writeFork(std::ostream& out) const
{ {
std::streampos start = out.tellp(); std::streampos start = out.tellp();
longword(out,0x100); longword(out,0x100);
longword(out,0); longword(out,0);
longword(out,0); longword(out,0);
longword(out,0); longword(out,0);
out.seekp(start + std::streampos(0x100)); out.seekp(start + std::streampos(0x100));
std::map< std::string, std::map<int, int> > resourceInfos; std::map< std::string, std::map<int, int> > resourceInfos;
std::streampos datastart = out.tellp(); std::streampos datastart = out.tellp();
for(std::vector<Resource>::const_iterator p = resources.begin(); p != resources.end(); ++p) for(std::vector<Resource>::const_iterator p = resources.begin(); p != resources.end(); ++p)
{ {
const std::string& data = p->getData(); const std::string& data = p->getData();
resourceInfos[ p->getType() ][ p->getID() ] = out.tellp() - datastart; resourceInfos[ p->getType() ][ p->getID() ] = out.tellp() - datastart;
longword(out, data.size()); longword(out, data.size());
out << data; out << data;
} }
std::streampos dataend = out.tellp(); std::streampos dataend = out.tellp();
// while(out.tellp() % 0x100) // while(out.tellp() % 0x100)
// out.put(0); // out.put(0);
std::streampos resmap = out.tellp(); std::streampos resmap = out.tellp();
out.seekp(16+4+2+2, std::ios::cur); out.seekp(16+4+2+2, std::ios::cur);
word(out,16+4+2+2+2+2); // offset to resource type list word(out,16+4+2+2+2+2); // offset to resource type list
std::streampos resnameOffset = out.tellp(); std::streampos resnameOffset = out.tellp();
word(out,0); word(out,0);
std::streampos typelist = out.tellp(); std::streampos typelist = out.tellp();
word(out,resourceInfos.size() - 1); word(out,resourceInfos.size() - 1);
for(std::map< std::string, std::map<int, int> >::iterator p = resourceInfos.begin(); for(std::map< std::string, std::map<int, int> >::iterator p = resourceInfos.begin();
p != resourceInfos.end(); ++p) p != resourceInfos.end(); ++p)
{ {
if(p->second.size()) if(p->second.size())
{ {
ostype(out,p->first); ostype(out,p->first);
word(out,p->second.size()-1); word(out,p->second.size()-1);
word(out,0); // replaced later word(out,0); // replaced later
} }
} }
int typeIndex = 0; int typeIndex = 0;
for(std::map< std::string, std::map<int, int> >::iterator p = resourceInfos.begin(); for(std::map< std::string, std::map<int, int> >::iterator p = resourceInfos.begin();
p != resourceInfos.end(); ++p) p != resourceInfos.end(); ++p)
{ {
if(p->second.size()) if(p->second.size())
{ {
std::streampos pos = out.tellp(); std::streampos pos = out.tellp();
out.seekp((int)typelist + 2 + 8 * typeIndex + 6); out.seekp((int)typelist + 2 + 8 * typeIndex + 6);
word(out, pos - typelist); word(out, pos - typelist);
out.seekp(pos); out.seekp(pos);
typeIndex++; typeIndex++;
for(std::map<int,int>::iterator q = p->second.begin(); q != p->second.end(); ++q) for(std::map<int,int>::iterator q = p->second.begin(); q != p->second.end(); ++q)
{ {
word(out,q->first); word(out,q->first);
word(out,-1); word(out,-1);
longword(out,q->second); longword(out,q->second);
longword(out,0); longword(out,0);
} }
} }
} }
std::streampos resnames = out.tellp(); std::streampos resnames = out.tellp();
out.seekp(resnameOffset); out.seekp(resnameOffset);
word(out, resnames - resmap); word(out, resnames - resmap);
out.seekp(resnames); out.seekp(resnames);
std::streampos end = out.tellp(); std::streampos end = out.tellp();
out.seekp(start + std::streampos(4)); out.seekp(start + std::streampos(4));
longword(out, resmap - start); longword(out, resmap - start);
longword(out, dataend - start - std::streampos(0x100)); longword(out, dataend - start - std::streampos(0x100));
longword(out, end - resmap); longword(out, end - resmap);
out.seekp(end); out.seekp(end);
} }
// CRC 16 table lookup array // CRC 16 table lookup array
static unsigned short CRC16Table[256] = static unsigned short CRC16Table[256] =
{0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0}; 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0};
// CalculateCRC // CalculateCRC
static unsigned short CalculateCRC(unsigned short CRC, const char* dataBlock, int dataSize) static unsigned short CalculateCRC(unsigned short CRC, const char* dataBlock, int dataSize)
{ {
while (dataSize) while (dataSize)
{ {
CRC = (CRC << 8) ^ CRC16Table[((*dataBlock) ^ (CRC >> 8)) & 0x00FF]; CRC = (CRC << 8) ^ CRC16Table[((*dataBlock) ^ (CRC >> 8)) & 0x00FF];
dataBlock++; dataBlock++;
dataSize--; dataSize--;
} }
return CRC; return CRC;
} }
void writeMacBinary(std::ostream& out, std::string filename, void writeMacBinary(std::ostream& out, std::string filename,
std::string type, std::string creator, std::string type, std::string creator,
const Fork& rsrc, const Fork& data) const Fork& rsrc, const Fork& data)
{ {
out.seekp(128); out.seekp(128);
data.writeFork(out); data.writeFork(out);
std::streampos dataend = out.tellp(); std::streampos dataend = out.tellp();
std::streampos rsrcstart = ((int)dataend + 0x7F) & ~0x7F; std::streampos rsrcstart = ((int)dataend + 0x7F) & ~0x7F;
rsrc.writeFork(out); rsrc.writeFork(out);
std::streampos rsrcend = out.tellp(); std::streampos rsrcend = out.tellp();
while((int)out.tellp() % 128) while((int)out.tellp() % 128)
byte(out,0); byte(out,0);
std::ostringstream header; std::ostringstream header;
byte(header, 0); byte(header, 0);
byte(header, filename.size()); byte(header, filename.size());
header << filename; header << filename;
while((int)header.tellp() < 65) while((int)header.tellp() < 65)
byte(header,0); byte(header,0);
ostype(header, type); ostype(header, type);
ostype(header, creator); ostype(header, creator);
byte(header, 0); // flags byte(header, 0); // flags
byte(header, 0); byte(header, 0);
word(header, 0); // position.v word(header, 0); // position.v
word(header, 0); // position.h word(header, 0); // position.h
word(header, 0); // folder id word(header, 0); // folder id
byte(header, 0); // protected flag byte(header, 0); // protected flag
byte(header, 0); byte(header, 0);
longword(header, ((int)dataend - 128)); longword(header, ((int)dataend - 128));
longword(header, (int) (rsrcend - rsrcstart)); longword(header, (int) (rsrcend - rsrcstart));
longword(header, 0); // creation date longword(header, 0); // creation date
longword(header, 0); // modification date longword(header, 0); // modification date
while((int)header.tellp() < 124) while((int)header.tellp() < 124)
byte(header,0); byte(header,0);
out.seekp(0); out.seekp(0);
std::string headerData = header.str(); std::string headerData = header.str();
// out.write(&headerData[0], headerData.size()); // out.write(&headerData[0], headerData.size());
out << headerData; out << headerData;
word(out, CalculateCRC(0, &headerData[0], headerData.size())); word(out, CalculateCRC(0, &headerData[0], headerData.size()));
word(out, 0); word(out, 0);
//longword(out,0); //longword(out,0);
out.seekp(0, std::ios::end); out.seekp(0, std::ios::end);
} }
std::string fromhex(std::string hex) std::string fromhex(std::string hex)
{ {
std::string bin; std::string bin;
int nibble; int nibble;
bool haveNibble = false; bool haveNibble = false;
for(std::string::iterator p = hex.begin(); p != hex.end(); ++p) for(std::string::iterator p = hex.begin(); p != hex.end(); ++p)
{ {
if(std::isspace(*p)) if(std::isspace(*p))
continue; continue;
assert(isdigit(*p) || (tolower(*p) >= 'a' && tolower(*p) <= 'f')); assert(isdigit(*p) || (tolower(*p) >= 'a' && tolower(*p) <= 'f'));
int digit; int digit;
if(isdigit(*p)) if(isdigit(*p))
digit = *p - '0'; digit = *p - '0';
else else
digit = tolower(*p) - 'a' + 0xA; digit = tolower(*p) - 'a' + 0xA;
if(haveNibble) if(haveNibble)
{ {
bin += (char) ((nibble << 4) | digit); bin += (char) ((nibble << 4) | digit);
haveNibble = false; haveNibble = false;
} }
else else
{ {
nibble = digit; nibble = digit;
haveNibble = true; haveNibble = true;
} }
} }
return bin; return bin;
} }
std::string readfile(std::string fn) std::string readfile(std::string fn)
{ {
std::ifstream in(fn.c_str(), std::ios::in|std::ios::binary); std::ifstream in(fn.c_str(), std::ios::in|std::ios::binary);
return std::string(std::istreambuf_iterator<char>(in), return std::string(std::istreambuf_iterator<char>(in),
std::istreambuf_iterator<char>()); std::istreambuf_iterator<char>());
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
Resources rsrc; Resources rsrc;
//Resource res("TEXT", 128, "Hello, world."); //Resource res("TEXT", 128, "Hello, world.");
//rsrc.addResource(res); //rsrc.addResource(res);
std::string outFileName = "Test"; std::string outFileName = "Test";
std::string binFileName = "Test.bin"; std::string binFileName = "Test.bin";
std::string dskFileName = "Test.dsk"; std::string dskFileName = "Test.dsk";
std::string curRType = "CODE"; std::string curRType = "CODE";
bool breakOnEntry = false; bool breakOnEntry = false;
unsigned short sizeFlags = 0x80; // 32-bit clean unsigned short sizeFlags = 0x80; // 32-bit clean
unsigned long minimumSize = 384 * 1024; unsigned long minimumSize = 384 * 1024;
unsigned long preferredSize = 384 * 1024; unsigned long preferredSize = 384 * 1024;
if(char *lastSlash = std::strrchr(argv[0], '/')) if(char *lastSlash = std::strrchr(argv[0], '/'))
{ {
commandPath = std::string(argv[0], lastSlash + 1); commandPath = std::string(argv[0], lastSlash + 1);
} }
for(int i = 1; i < argc;) for(int i = 1; i < argc;)
{ {
std::string arg(argv[i++]); std::string arg(argv[i++]);
if(arg == "-o") if(arg == "-o")
{ {
assert(i < argc); assert(i < argc);
outFileName = argv[i++]; outFileName = argv[i++];
binFileName = outFileName + ".bin"; binFileName = outFileName + ".bin";
dskFileName = outFileName + ".dsk"; dskFileName = outFileName + ".dsk";
} }
else if(arg == "-t") else if(arg == "-t")
{ {
assert(i < argc); assert(i < argc);
curRType = argv[i++]; curRType = argv[i++];
} }
else if(arg == "-r") else if(arg == "-r")
{ {
assert(i < argc); assert(i < argc);
int id = atoi(argv[i++]); int id = atoi(argv[i++]);
assert(i < argc); assert(i < argc);
std::string fn = argv[i++]; std::string fn = argv[i++];
rsrc.addResource(Resource(curRType, id, readfile(fn))); rsrc.addResource(Resource(curRType, id, readfile(fn)));
} }
else if(arg == "-c") else if(arg == "-c")
{ {
assert(i < argc); assert(i < argc);
std::string fn = argv[i++]; std::string fn = argv[i++];
std::string flt = readfile(fn); std::string flt = readfile(fn);
rsrc.addResource(Resource("CODE", 0, rsrc.addResource(Resource("CODE", 0,
fromhex( fromhex(
"00000028 00000000 00000008 00000020" "00000028 00000000 00000008 00000020"
"0000 3F3C 0001 A9F0" "0000 3F3C 0001 A9F0"
) )
)); ));
long entrypoint = (static_cast<unsigned char>(flt[ 8]) << 24) long entrypoint = (static_cast<unsigned char>(flt[ 8]) << 24)
| (static_cast<unsigned char>(flt[ 9]) << 16) | (static_cast<unsigned char>(flt[ 9]) << 16)
| (static_cast<unsigned char>(flt[10]) << 8) | (static_cast<unsigned char>(flt[10]) << 8)
| (static_cast<unsigned char>(flt[11])) | (static_cast<unsigned char>(flt[11]))
; ;
std::ostringstream code1; std::ostringstream code1;
word(code1, 0); word(code1, 0);
word(code1, 1); word(code1, 1);
if(breakOnEntry) if(breakOnEntry)
word(code1, 0xa9ff); word(code1, 0xa9ff);
longword(code1, 0x61000002); // bsr *+2 longword(code1, 0x61000002); // bsr *+2
word(code1, 0x0697); // addi.l #_, (a7) word(code1, 0x0697); // addi.l #_, (a7)
longword(code1, entrypoint + 8); longword(code1, entrypoint + 8);
word(code1, 0x4e75); // rts word(code1, 0x4e75); // rts
code1 << flt; code1 << flt;
rsrc.addResource(Resource("CODE", 1, code1.str())); rsrc.addResource(Resource("CODE", 1, code1.str()));
if(code1.str().size() + 64*1024 > minimumSize) if(code1.str().size() + 64*1024 > minimumSize)
minimumSize = code1.str().size() + 64*1024; minimumSize = code1.str().size() + 64*1024;
if(minimumSize > preferredSize) if(minimumSize > preferredSize)
preferredSize = minimumSize; preferredSize = minimumSize;
} }
else if(arg == "-b") else if(arg == "-b")
breakOnEntry = true; breakOnEntry = true;
else if(arg == "--minimum") else if(arg == "--minimum")
{ {
assert(i < argc); assert(i < argc);
int k = atoi(argv[i++]); int k = atoi(argv[i++]);
minimumSize = k*1024; minimumSize = k*1024;
if(preferredSize < minimumSize) if(preferredSize < minimumSize)
preferredSize = minimumSize; preferredSize = minimumSize;
} }
else if(arg == "--preferred") else if(arg == "--preferred")
{ {
assert(i < argc); assert(i < argc);
int k = atoi(argv[i++]); int k = atoi(argv[i++]);
preferredSize = k*1024; preferredSize = k*1024;
} }
else if(arg == "--flags") else if(arg == "--flags")
{ {
assert(i < argc); assert(i < argc);
std::istringstream in(argv[i++]); std::istringstream in(argv[i++]);
in >> std::hex >> sizeFlags; in >> std::hex >> sizeFlags;
} }
else else
{ {
std::cout << "unrecognized flag\n"; std::cout << "unrecognized flag\n";
return 1; return 1;
} }
} }
{ {
std::ostringstream size_1; std::ostringstream size_1;
word(size_1, sizeFlags); word(size_1, sizeFlags);
longword(size_1, minimumSize); longword(size_1, minimumSize);
longword(size_1, preferredSize); longword(size_1, preferredSize);
rsrc.addResource(Resource("SIZE", -1, size_1.str())); rsrc.addResource(Resource("SIZE", -1, size_1.str()));
} }
{ {
std::ofstream out(binFileName.c_str()); std::ofstream out(binFileName.c_str());
writeMacBinary(out, outFileName, "APPL", "????", writeMacBinary(out, outFileName, "APPL", "????",
rsrc, Fork()); rsrc, Fork());
} }
wrapMacBinary(binFileName, dskFileName); wrapMacBinary(binFileName, dskFileName);
return 0; return 0;
} }

View File

@@ -43,7 +43,7 @@ data Item = CharItem Char
type Register = String type Register = String
data ParameterRegs = ParameterRegs (Maybe Register) [Register] data ParameterRegs = ParameterRegs (Maybe Register) [Register]
deriving(Show) deriving(Show)
tp = makeTokenParser javaStyle tp = makeTokenParser javaStyle
@@ -55,52 +55,52 @@ item = (char '\r' >> return (CharItem '\n'))
<|> fmap CharItem anyChar <|> fmap CharItem anyChar
balancedText stopAtComma = fmap (foldr ($) "") $ balancedText stopAtComma = fmap (foldr ($) "") $
many (fmap (++) paranthesized <|> fmap (:) (noneOf (if stopAtComma then "()," else "()"))) many (fmap (++) paranthesized <|> fmap (:) (noneOf (if stopAtComma then "()," else "()")))
where paranthesized = char '(' >> balancedText False >>= \xs -> char ')' >> return ('(' : xs ++ ")") where paranthesized = char '(' >> balancedText False >>= \xs -> char ')' >> return ('(' : xs ++ ")")
trim = dropWhile isSpace . reverse . dropWhile isSpace . reverse trim = dropWhile isSpace . reverse . dropWhile isSpace . reverse
cleanup = unwords . words . trim cleanup = unwords . words . trim
returnType = do returnType = do
t <- identifier tp t <- identifier tp
ptrs <- many (reservedOp tp "*" >> return '*') ptrs <- many (reservedOp tp "*" >> return '*')
return $ t ++ ptrs return $ t ++ ptrs
externApiDeclaration = do externApiDeclaration = do
rettype <- (reserved tp "EXTERN_API" >> (fmap trim $ parens tp (balancedText False))) rettype <- (reserved tp "EXTERN_API" >> (fmap trim $ parens tp (balancedText False)))
<|> (reserved tp "pascal" >> returnType) <|> (reserved tp "pascal" >> returnType)
name <- identifier tp name <- identifier tp
arguments <- fmap (map cleanup) $ parens tp (commaSep tp $ balancedText True) arguments <- fmap (map cleanup) $ parens tp (commaSep tp $ balancedText True)
let hexwords = commaSep tp hexword let hexwords = commaSep tp hexword
macroinline = do macroinline = do
inlinekey <- identifier tp inlinekey <- identifier tp
guard ("WORDINLINE" `isSuffixOf` inlinekey) guard ("WORDINLINE" `isSuffixOf` inlinekey)
parens tp hexwords parens tp hexwords
plaininline = do plaininline = do
reservedOp tp "=" reservedOp tp "="
braces tp hexwords braces tp hexwords
inlines <- macroinline <|> plaininline <|> return [] inlines <- macroinline <|> plaininline <|> return []
semi tp semi tp
let arguments' | arguments == ["void"] = [] let arguments' | arguments == ["void"] = []
| otherwise = arguments | otherwise = arguments
argumentNames = map (trim . reverse . takeWhile isAlphaNum . reverse . trim) arguments' argumentNames = map (trim . reverse . takeWhile isAlphaNum . reverse . trim) arguments'
argumentTypes = map (trim . reverse . dropWhile isAlphaNum . reverse . trim) arguments' argumentTypes = map (trim . reverse . dropWhile isAlphaNum . reverse . trim) arguments'
return $ FunctionItem rettype name argumentTypes argumentNames inlines Nothing return $ FunctionItem rettype name argumentTypes argumentNames inlines Nothing
pragmaParameter = do pragmaParameter = do
reservedOp tp "#" reservedOp tp "#"
reserved tp "pragma" reserved tp "pragma"
reserved tp "parameter" reserved tp "parameter"
retval <- optionMaybe reg retval <- optionMaybe reg
name <- identifier tp name <- identifier tp
args <- parens tp (commaSep tp reg) args <- parens tp (commaSep tp reg)
-- args <- option [] $ parens tp (fmap return $ reg) -- args <- option [] $ parens tp (fmap return $ reg)
-- let args = [] -- let args = []
return $ PragmaParameterItem name (ParameterRegs retval args) return $ PragmaParameterItem name (ParameterRegs retval args)
reg = (reserved tp "__A0" >> return "%%a0") reg = (reserved tp "__A0" >> return "%%a0")
<|>(reserved tp "__A1" >> return "%%a1") <|>(reserved tp "__A1" >> return "%%a1")
@@ -127,186 +127,184 @@ outputItem typeMap (CharItem c) = [c]
-- outputItem (FunctionItem rettype name argumentTypes argumentNames words) = "<fun>" -- outputItem (FunctionItem rettype name argumentTypes argumentNames words) = "<fun>"
outputItem typeMap (FunctionItem rettype name argumentTypes argumentNames words Nothing) outputItem typeMap (FunctionItem rettype name argumentTypes argumentNames words Nothing)
| True, not (null words), Just retcat <- classifyType typeMap rettype | True, not (null words), Just retcat <- classifyType typeMap rettype
= let = let
helper = PP.text "__magic_inline_" <> PP.text name helper = PP.text "__magic_inline_" <> PP.text name
magic = PP.text "__magic_inline_" <> PP.hcat (PP.punctuate (PP.char '_') (map (PP.text . hexword) words')) magic = PP.text "__magic_inline_" <> PP.hcat (PP.punctuate (PP.char '_') (map (PP.text . hexword) words'))
hexword w = replicate (4 - length s) '0' ++ s where s = showHex w "" hexword w = replicate (4 - length s) '0' ++ s where s = showHex w ""
magicArgTypes = case retcat of magicArgTypes = case retcat of
ByteType -> reverse $ "char" : argumentTypes ByteType -> reverse $ "char" : argumentTypes
WordType -> reverse $ "short" : argumentTypes WordType -> reverse $ "short" : argumentTypes
LongType -> reverse $ "long" : argumentTypes LongType -> reverse $ "long" : argumentTypes
PointerType -> reverse $ "long" : argumentTypes PointerType -> reverse $ "long" : argumentTypes
VoidType -> reverse argumentTypes VoidType -> reverse argumentTypes
magicArgValues = case retcat of magicArgValues = case retcat of
VoidType -> reverse argumentNames VoidType -> reverse argumentNames
_ -> reverse $ "0" : argumentNames _ -> reverse $ "0" : argumentNames
words' = case retcat of words' = case retcat of
VoidType -> words VoidType -> words
ByteType -> words ++ [ 0x101f ] -- move.b (a7)+,d0 ByteType -> words ++ [ 0x101f ] -- move.b (a7)+,d0
WordType -> words ++ [ 0x301f ] -- move.w (a7)+,d0 WordType -> words ++ [ 0x301f ] -- move.w (a7)+,d0
LongType -> words ++ [ 0x201f ] -- move.l (a7)+,d0 LongType -> words ++ [ 0x201f ] -- move.l (a7)+,d0
PointerType -> words ++ [ 0x201f ] -- move.l (a7)+,d0 PointerType -> words ++ [ 0x201f ] -- move.l (a7)+,d0
in PP.render $ in PP.render $
PP.text rettype <+> PP.text "__attribute__((stdcall))" <+> helper PP.text rettype <+> PP.text "__attribute__((stdcall))" <+> helper
<> PP.parens (PP.hsep $ PP.punctuate PP.comma $ map PP.text magicArgTypes) <> PP.parens (PP.hsep $ PP.punctuate PP.comma $ map PP.text magicArgTypes)
<+> PP.text("__asm__") <> PP.parens ( PP.doubleQuotes magic ) <+> PP.text("__asm__") <> PP.parens ( PP.doubleQuotes magic )
<> PP.semi <> PP.semi
$+$ $+$
PP.text "static inline" <+> PP.text rettype <+> PP.text name PP.text "static inline" <+> PP.text rettype <+> PP.text name
<+> PP.parens (PP.hsep $ PP.punctuate PP.comma $ zipWith (\t n -> PP.text t <+> PP.text n) argumentTypes argumentNames) $$ <+> PP.parens (PP.hsep $ PP.punctuate PP.comma $ zipWith (\t n -> PP.text t <+> PP.text n) argumentTypes argumentNames) $$
PP.text "{" $+$ (PP.nest 4 $ PP.text "{" $+$ (PP.nest 4 $
(if retcat == VoidType then PP.empty else PP.text "return") <+> (if retcat == VoidType then PP.empty else PP.text "return") <+>
helper <> PP.parens (PP.hsep $ PP.punctuate PP.comma $ map PP.text magicArgValues) <> PP.semi helper <> PP.parens (PP.hsep $ PP.punctuate PP.comma $ map PP.text magicArgValues) <> PP.semi
) $+$ PP.text "}\n\n" ) $+$ PP.text "}\n\n"
outputItem typeMap (FunctionItem rettype name argumentTypes argumentNames words mbParamRegs) = outputItem typeMap (FunctionItem rettype name argumentTypes argumentNames words mbParamRegs) =
PP.render $ PP.render $
linkage <+> PP.text rettype <+> PP.text name linkage <+> PP.text rettype <+> PP.text name
<+> PP.parens (PP.hsep $ PP.punctuate PP.comma $ zipWith (\t n -> PP.text t <+> PP.text n) argumentTypes argumentNames) $$ <+> PP.parens (PP.hsep $ PP.punctuate PP.comma $ zipWith (\t n -> PP.text t <+> PP.text n) argumentTypes argumentNames) $$
if isJust mbCategories && not (null words) if isJust mbCategories && not (null words)
then then
PP.text "{" $+$ (PP.nest 4 $ PP.text "{" $+$ (PP.nest 4 $
addReturnValue $ addReturnValue $
PP.text "__asm__ __volatile__ (" $+$ PP.text "__asm__ __volatile__ (" $+$
PP.nest 4 ( PP.nest 4 (
PP.nest 4 (PP.vcat asmStatements) $+$ PP.nest 4 (PP.vcat asmStatements) $+$
showConstraints outs $+$ showConstraints outs $+$
showConstraints ins $+$ showConstraints ins $+$
PP.text ": \"%a0\", \"%a1\", \"%d0\", \"%d1\", \"%d2\", \"memory\", \"cc\"" PP.text ": \"%a0\", \"%a1\", \"%d0\", \"%d1\", \"%d2\", \"memory\", \"cc\""
<> (if tooltrap then PP.text ", \"%a5\"" else PP.empty) <> (if tooltrap then PP.text ", \"%a5\"" else PP.empty)
) )
$+$ PP.text ");" $+$ PP.text ");"
) $+$ PP.text "}\n\n" ) $+$ PP.text "}\n\n"
else else
PP.semi $+$ PP.semi $+$
PP.text "//" <+> PP.text (show words) $+$ PP.text "//" <+> PP.text (show words) $+$
PP.text "//" <+> PP.text rettype <+> PP.text (show $ (classifyType typeMap) rettype) $+$ PP.text "//" <+> PP.text rettype <+> PP.text (show $ (classifyType typeMap) rettype) $+$
PP.text "//" <+> PP.text (show argumentTypes) <+> PP.text (show $ map (classifyType typeMap) argumentTypes) $+$ PP.text "//" <+> PP.text (show argumentTypes) <+> PP.text (show $ map (classifyType typeMap) argumentTypes) $+$
PP.text "\n" -- couldn't convert type PP.text "\n" -- couldn't convert type
where where
tooltrap = True -- trapnum >= 0xA800 tooltrap = True -- trapnum >= 0xA800
linkage | null words = PP.text "extern" linkage | null words = PP.text "extern"
| otherwise = PP.text "static inline" | otherwise = PP.text "static inline"
mbCategories = do mbCategories = do
retcat <- classifyType typeMap rettype retcat <- classifyType typeMap rettype
argcats <- mapM (classifyType typeMap) argumentTypes argcats <- mapM (classifyType typeMap) argumentTypes
return (retcat, argcats) return (retcat, argcats)
Just (returnCategory, argumentCategories) = mbCategories Just (returnCategory, argumentCategories) = mbCategories
returnsValue = returnCategory /= VoidType returnsValue = returnCategory /= VoidType
addReturnValue body addReturnValue body
| returnsValue = (PP.text rettype <+> PP.text "_ret;") $+$ | returnsValue = (PP.text rettype <+> PP.text "_ret;") $+$
body $+$ body $+$
PP.text "return _ret;" PP.text "return _ret;"
| otherwise = body | otherwise = body
outs | returnsValue = [PP.text "\"=g\"(_ret)"] outs | returnsValue = [PP.text "\"=g\"(_ret)"]
| otherwise = [] | otherwise = []
ins = zipWith inputConstraint argumentCategories argumentNames ins = zipWith inputConstraint argumentCategories argumentNames
inputConstraint PointerType name = PP.text "\"m\"(*(char*)" <> PP.text name <> PP.text ")" inputConstraint PointerType name = PP.text "\"m\"(*(char*)" <> PP.text name <> PP.text ")"
inputConstraint VoidType name = error $ "Void Parameter: " ++ name inputConstraint VoidType name = error $ "Void Parameter: " ++ name
inputConstraint _ name = PP.text "\"g\"(" <> PP.text name <> PP.text ")" inputConstraint _ name = PP.text "\"g\"(" <> PP.text name <> PP.text ")"
showConstraints constraints = PP.text ":" <+> PP.hsep (PP.punctuate PP.comma $ constraints) showConstraints constraints = PP.text ":" <+> PP.hsep (PP.punctuate PP.comma $ constraints)
asmStatements = asmStatements =
-- (if tooltrap then [-- PP.text "\"move.l %%a5, %%a4\\n\"", subq ++
-- PP.text "\"move.l 0x904.w, %%a5\\n\""] else []) ++ pushes ++
subq ++ map (\trapnum -> PP.text "\"dc.w" <+> PP.text "0x" <> PP.text (showHex trapnum "")
pushes ++ <> PP.text "\\n\\t\"") words
map (\trapnum -> PP.text "\"dc.w" <+> PP.text "0x" <> PP.text (showHex trapnum "") <> PP.text "\\n\\t\"") words ++ pop
++ pop
-- ++ (if tooltrap then [PP.text "\"move.l %%a4, %%a5\\n\""] else []) (subq, pop) = case returnCategory of
VoidType -> ([], [])
(subq, pop) = case returnCategory of _ -> (ifpascal [PP.text "\"subq #" <> PP.int size <> PP.text ", %%sp\\n\\t\""],
VoidType -> ([], []) [PP.text "\"move" <> szLetter <+> src <+> PP.text ", %0\\n\\t\""])
_ -> (ifpascal [PP.text "\"subq #" <> PP.int size <> PP.text ", %%sp\\n\\t\""], where
[PP.text "\"move" <> szLetter <+> src <+> PP.text ", %0\\n\\t\""]) size = case returnCategory of
where PointerType -> 4 ; LongType -> 4 ; WordType -> 2 ; ByteType -> 2 {- keep stack aligned -}
size = case returnCategory of
PointerType -> 4 ; LongType -> 4 ; WordType -> 2 ; ByteType -> 2 {- keep stack aligned -} szLetter = PP.text $ case returnCategory of
PointerType -> ".l" ; LongType -> ".l" ; WordType -> ".w" ; ByteType -> ".b"
szLetter = PP.text $ case returnCategory of src = case mbParamRegs of
PointerType -> ".l" ; LongType -> ".l" ; WordType -> ".w" ; ByteType -> ".b" Nothing -> PP.text "%%sp@+"
src = case mbParamRegs of Just (ParameterRegs (Just r) _) -> PP.text r
Nothing -> PP.text "%%sp@+" Just (ParameterRegs Nothing _) -> error $ "no reg for return value: " ++ name
Just (ParameterRegs (Just r) _) -> PP.text r
Just (ParameterRegs Nothing _) -> error $ "no reg for return value: " ++ name ifpascal x = case mbParamRegs of Nothing -> x ; Just _ -> []
ifpascal x = case mbParamRegs of Nothing -> x ; Just _ -> [] pushes = case mbParamRegs of
Nothing -> zipWith (mkPush Nothing) argumentCategories
pushes = case mbParamRegs of Just (ParameterRegs _ regs) -> zipWith3 mkPush (map Just regs) argumentCategories
Nothing -> zipWith (mkPush Nothing) argumentCategories $
Just (ParameterRegs _ regs) -> zipWith3 mkPush (map Just regs) argumentCategories map (\i -> PP.char '%' <> PP.int i) $
$ (if returnsValue then [1..] else [0..])
map (\i -> PP.char '%' <> PP.int i) $
(if returnsValue then [1..] else [0..]) endtxt = PP.text "\\n\\t\""
mkPush Nothing PointerType operand = PP.text "\"pea" <+> operand <> endtxt
endtxt = PP.text "\\n\\t\"" mkPush (Just reg) PointerType operand = PP.text "\"lea" <+> operand <> PP.comma <+> PP.text reg <> endtxt
mkPush Nothing PointerType operand = PP.text "\"pea" <+> operand <> endtxt mkPush mbReg size operand =
mkPush (Just reg) PointerType operand = PP.text "\"lea" <+> operand <> PP.comma <+> PP.text reg <> endtxt PP.text "\"move" <> PP.text sz <+> operand <> PP.comma <+> dst <> endtxt
mkPush mbReg size operand = where
PP.text "\"move" <> PP.text sz <+> operand <> PP.comma <+> dst <> endtxt sz = case size of
where LongType -> ".l" ; WordType -> ".w" ; ByteType -> ".b"
sz = case size of dst = case mbReg of
LongType -> ".l" ; WordType -> ".w" ; ByteType -> ".b" Nothing -> PP.text "%%sp@-"
dst = case mbReg of Just reg -> PP.text reg
Nothing -> PP.text "%%sp@-"
Just reg -> PP.text reg
outputItem _ _ = "" outputItem _ _ = ""
collectPragmas xs = evalState (mapM doit xs) Map.empty collectPragmas xs = evalState (mapM doit xs) Map.empty
where where
doit x@(PragmaParameterItem name params) = modify (Map.insert name params) >> return x doit x@(PragmaParameterItem name params) = modify (Map.insert name params) >> return x
doit (FunctionItem rettype name argumentTypes argumentNames inlines _) = do doit (FunctionItem rettype name argumentTypes argumentNames inlines _) = do
m <- get m <- get
return $ FunctionItem rettype name argumentTypes argumentNames inlines (Map.lookup name m) return $ FunctionItem rettype name argumentTypes argumentNames inlines (Map.lookup name m)
doit x = return x doit x = return x
parseTypeMap tm = Map.fromList $ map handleLine $ lines tm parseTypeMap tm = Map.fromList $ map handleLine $ lines tm
where where
handleLine tml = case words tml of handleLine tml = case words tml of
(x : xs) -> (trim $ unwords xs, case x of (x : xs) -> (trim $ unwords xs, case x of
"B" -> ByteType ; "W" -> WordType ; "L" -> LongType ; "P" -> PointerType) "B" -> ByteType ; "W" -> WordType ; "L" -> LongType ; "P" -> PointerType)
processFile inputDir outputDir file processFile inputDir outputDir file
| ".h" `isSuffixOf` file = do | ".h" `isSuffixOf` file = do
print $ (outputDir </> takeFileName file) print $ (outputDir </> takeFileName file)
-- readFile (inputDir </> file) -- readFile (inputDir </> file)
f <- openFile (inputDir </> file) ReadMode f <- openFile (inputDir </> file) ReadMode
hSetEncoding f latin1 hSetEncoding f latin1
txt <- hGetContents f txt <- hGetContents f
let parseResult = parse (many item) file txt let parseResult = parse (many item) file txt
typeMap <- fmap parseTypeMap $ readFile "../Retro68/types.txt" typeMap <- fmap parseTypeMap $ readFile "../Retro68/types.txt"
case parseResult of case parseResult of
Right items -> do Right items -> do
outf <- openFile (outputDir </> file) WriteMode outf <- openFile (outputDir </> file) WriteMode
hSetEncoding outf latin1 hSetEncoding outf latin1
when (file == "ConditionalMacros.h") $ do when (file == "ConditionalMacros.h") $ do
hPutStrLn outf $ unlines [ hPutStrLn outf $ unlines [
"#define TARGET_CPU_68K 1", "#define TARGET_CPU_68K 1",
"#define TYPE_LONGLONG 1", "#define TYPE_LONGLONG 1",
"#define pascal", "#define pascal",
"#ifdef __cplusplus", "#ifdef __cplusplus",
"#define TYPE_BOOL 1", "#define TYPE_BOOL 1",
"#endif" "#endif"
] ]
hPutStr outf $ concatMap (outputItem typeMap) $ collectPragmas $ items hPutStr outf $ concatMap (outputItem typeMap) $ collectPragmas $ items
hClose outf hClose outf
Left err -> putStrLn $ file ++ ": " ++ show err Left err -> putStrLn $ file ++ ": " ++ show err
| otherwise = do | otherwise = do
putStrLn $ "Unknown: " ++ file putStrLn $ "Unknown: " ++ file
main = do main = do
[inputDir,outputDir] <- getArgs [inputDir,outputDir] <- getArgs
files <- getDirectoryContents inputDir files <- getDirectoryContents inputDir
Control.Exception.try (createDirectory outputDir) :: IO (Either Control.Exception.IOException ()) Control.Exception.try (createDirectory outputDir) :: IO (Either Control.Exception.IOException ())
mapM (processFile inputDir outputDir) files mapM (processFile inputDir outputDir) files
return () return ()

View File

@@ -1,19 +1,19 @@
# Copyright 2012 Wolfgang Thaller. # Copyright 2012 Wolfgang Thaller.
# #
# This file is part of Retro68. # This file is part of Retro68.
# #
# Retro68 is free software: you can redistribute it and/or modify # Retro68 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# Retro68 is distributed in the hope that it will be useful, # Retro68 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Retro68. If not, see <http://www.gnu.org/licenses/>. # along with Retro68. If not, see <http://www.gnu.org/licenses/>.
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
@@ -23,13 +23,13 @@ endif()
include_directories(../App2) include_directories(../App2)
add_executable(Raytracer MACOSX_BUNDLE add_executable(Raytracer MACOSX_BUNDLE
raytracer.cc raytracer.cc
) )
add_executable(Raytracer2 MACOSX_BUNDLE add_executable(Raytracer2 MACOSX_BUNDLE
raytracer2.cc raytracer2.cc
fixed.h fixed.h
fixed.cc fixed.cc
) )
if(APPLE) if(APPLE)
target_link_libraries(Raytracer "-framework Carbon") target_link_libraries(Raytracer "-framework Carbon")
@@ -38,23 +38,23 @@ else()
add_executable(FixedBenchmark fixedbenchmark.cc ../App2/Console.cc ../App2/Console.h fixed.h fixed.cc) add_executable(FixedBenchmark fixedbenchmark.cc ../App2/Console.cc ../App2/Console.h fixed.h fixed.cc)
target_link_libraries(FixedBenchmark retrocrt) target_link_libraries(FixedBenchmark retrocrt)
add_custom_command( add_custom_command(
OUTPUT FixedBenchmark.bin OUTPUT FixedBenchmark.bin
COMMAND ${MAKE_APPL} -c FixedBenchmark -o FixedBenchmark COMMAND ${MAKE_APPL} -c FixedBenchmark -o FixedBenchmark
DEPENDS FixedBenchmark) DEPENDS FixedBenchmark)
add_custom_target(FixedBenchmarkAPPL ALL DEPENDS FixedBenchmark.bin) add_custom_target(FixedBenchmarkAPPL ALL DEPENDS FixedBenchmark.bin)
target_link_libraries(Raytracer retrocrt) target_link_libraries(Raytracer retrocrt)
add_custom_command( add_custom_command(
OUTPUT Raytracer.bin OUTPUT Raytracer.bin
COMMAND ${MAKE_APPL} -c Raytracer -o Raytracer COMMAND ${MAKE_APPL} -c Raytracer -o Raytracer
DEPENDS Raytracer) DEPENDS Raytracer)
add_custom_target(RaytracerAPPL ALL DEPENDS Raytracer.bin) add_custom_target(RaytracerAPPL ALL DEPENDS Raytracer.bin)
target_link_libraries(Raytracer2 retrocrt) target_link_libraries(Raytracer2 retrocrt)
add_custom_command( add_custom_command(
OUTPUT Raytracer2.bin OUTPUT Raytracer2.bin
COMMAND ${MAKE_APPL} -c Raytracer2 -o Raytracer2 COMMAND ${MAKE_APPL} -c Raytracer2 -o Raytracer2
DEPENDS Raytracer2) DEPENDS Raytracer2)
add_custom_target(Raytracer2APPL ALL DEPENDS Raytracer2.bin) add_custom_target(Raytracer2APPL ALL DEPENDS Raytracer2.bin)
endif() endif()

View File

@@ -24,25 +24,25 @@
inline std::int32_t muls(std::int16_t x, std::int16_t y) inline std::int32_t muls(std::int16_t x, std::int16_t y)
{ {
return (std::int32_t)x*y; return (std::int32_t)x*y;
} }
inline std::uint32_t mulu(std::uint16_t x, std::uint16_t y) inline std::uint32_t mulu(std::uint16_t x, std::uint16_t y)
{ {
//return (std::uint32_t)x * y; //return (std::uint32_t)x * y;
std::uint32_t res; std::uint32_t res;
__asm("mulu %1, %0" : "=d"(res) : "d"(x), "0"(y)); __asm("mulu %1, %0" : "=d"(res) : "d"(x), "0"(y));
return res; return res;
} }
inline std::int32_t mulsu(std::int16_t x, std::uint16_t y) inline std::int32_t mulsu(std::int16_t x, std::uint16_t y)
{ {
//return (std::int32_t)a * (std::uint32_t)b; //return (std::int32_t)a * (std::uint32_t)b;
std::int32_t res; std::int32_t res;
__asm("mulu %1, %0" : "=d"(res) : "d"(x), "0"(y)); __asm("mulu %1, %0" : "=d"(res) : "d"(x), "0"(y));
if(x < 0) if(x < 0)
res -= ((std::uint32_t)y) << 16; res -= ((std::uint32_t)y) << 16;
return res; return res;
} }
#define COUNT_OP(var) ++var #define COUNT_OP(var) ++var
@@ -67,15 +67,14 @@ public:
COUNT_OP(nMul); COUNT_OP(nMul);
//return fixed((static_cast<long long>(val) * o.val) >> 16, raw()); //return fixed((static_cast<long long>(val) * o.val) >> 16, raw());
int16_t a = val >> 16; int16_t a = val >> 16;
int16_t c = o.val >> 16; int16_t c = o.val >> 16;
uint16_t b = val; uint16_t b = val;
uint16_t d = o.val; uint16_t d = o.val;
return fixed(((a*c) << 16) return fixed(((a*c) << 16)
+ mulsu(a,d) + mulsu(c,b) + mulsu(a,d) + mulsu(c,b)
+ (mulu(b,d) >> 16),raw()); + (mulu(b,d) >> 16),raw());
} }
fixed operator/(fixed o) const { COUNT_OP(nDiv); return fixed((static_cast<long long>(val) << 16) / o.val, raw()); } fixed operator/(fixed o) const { COUNT_OP(nDiv); return fixed((static_cast<long long>(val) << 16) / o.val, raw()); }
@@ -109,11 +108,11 @@ fixed operator*(int x, fixed f) { return fixed(f.val * x, fixed::raw()); }*/
inline fixed operator*(fixed f, int c) inline fixed operator*(fixed f, int c)
{ {
std::int16_t a = f.val >> 16; std::int16_t a = f.val >> 16;
std::uint16_t b = f.val; std::uint16_t b = f.val;
COUNT_OP(fixed::nIMul); COUNT_OP(fixed::nIMul);
return fixed(((a*c) << 16) return fixed(((a*c) << 16)
+ mulsu(c,b),fixed::raw()); + mulsu(c,b),fixed::raw());
} }
inline fixed operator*(int x, fixed f) { return f*x; } inline fixed operator*(int x, fixed f) { return f*x; }

View File

@@ -1,20 +1,20 @@
/* /*
Copyright 2012 Wolfgang Thaller. Copyright 2012 Wolfgang Thaller.
This file is part of Retro68. This file is part of Retro68.
Retro68 is free software: you can redistribute it and/or modify Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Retro68 is distributed in the hope that it will be useful, Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>. along with Retro68. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <iostream> #include <iostream>
@@ -37,10 +37,10 @@ extern ssize_t (*__write_hook)(int fd, const void*buf, size_t count);
extern "C" ssize_t consolewrite(int fd, const void *buf, size_t count) extern "C" ssize_t consolewrite(int fd, const void *buf, size_t count)
{ {
const char *p = (const char*)buf; const char *p = (const char*)buf;
for(int i = 0; i < count; i++) for(int i = 0; i < count; i++)
Console::currentInstance->putch(*p++); Console::currentInstance->putch(*p++);
return count; return count;
} }
#include "fixed.h" #include "fixed.h"
@@ -54,69 +54,69 @@ public:
}; };
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
//GrafPort port; //GrafPort port;
WindowPtr win; WindowPtr win;
InitGraf(&qd.thePort); InitGraf(&qd.thePort);
InitFonts(); InitFonts();
InitWindows(); InitWindows();
InitMenus(); InitMenus();
Rect r; Rect r;
SetRect(&r, qd.screenBits.bounds.left + 5, qd.screenBits.bounds.top + 45, qd.screenBits.bounds.right - 5, qd.screenBits.bounds.bottom -5); SetRect(&r, qd.screenBits.bounds.left + 5, qd.screenBits.bounds.top + 45, qd.screenBits.bounds.right - 5, qd.screenBits.bounds.bottom -5);
win = NewWindow(NULL, &r, PSTR("Retro68 Console"), true, 0, (WindowPtr)-1, false, 0); win = NewWindow(NULL, &r, PSTR("Retro68 Console"), true, 0, (WindowPtr)-1, false, 0);
SetPort(win); SetPort(win);
EraseRect(&win->portRect); EraseRect(&win->portRect);
new char[32]; new char[32];
Console console(win, win->portRect); Console console(win, win->portRect);
__write_hook = &consolewrite; __write_hook = &consolewrite;
std::cout << "Hello, world.\n"; std::cout << "Hello, world.\n";
std::cout << "Generating numbers..." << std::flush; std::cout << "Generating numbers..." << std::flush;
const int n = 1000; const int n = 1000;
std::vector<fixed> numbers(n); std::vector<fixed> numbers(n);
for(int i = 0; i < numbers.size(); i++) for(int i = 0; i < numbers.size(); i++)
numbers[i] = fixed(std::rand(), fixed::raw()); numbers[i] = fixed(std::rand(), fixed::raw());
std::vector<fixed> outputs(n); std::vector<fixed> outputs(n);
std::cout << "done.\n"; std::cout << "done.\n";
std::cout << "Testing Multiplication..." << std::flush; std::cout << "Testing Multiplication..." << std::flush;
{ {
timer t; timer t;
for(int i = 0; i < n; i++) for(int i = 0; i < n; i++)
{ {
outputs[i] = numbers[i] * numbers[n - i - 1]; outputs[i] = numbers[i] * numbers[n - i - 1];
} }
std::cout << 1000 * t.elapsed() / n << "ms\n"; std::cout << 1000 * t.elapsed() / n << "ms\n";
} }
std::cout << "Testing Division..." << std::flush; std::cout << "Testing Division..." << std::flush;
{ {
timer t; timer t;
for(int i = 0; i < n; i++) for(int i = 0; i < n; i++)
{ {
outputs[i] = numbers[i] / numbers[n - i - 1]; outputs[i] = numbers[i] / numbers[n - i - 1];
} }
std::cout << 1000 * t.elapsed() / n << "ms\n"; std::cout << 1000 * t.elapsed() / n << "ms\n";
} }
std::cout << "Testing Square Root..." << std::flush; std::cout << "Testing Square Root..." << std::flush;
{ {
timer t; timer t;
for(int i = 0; i < n; i++) for(int i = 0; i < n; i++)
{ {
outputs[i] = sqrt(numbers[i]); outputs[i] = sqrt(numbers[i]);
} }
std::cout << 1000 * t.elapsed() / n << "ms\n"; std::cout << 1000 * t.elapsed() / n << "ms\n";
} }
std::cout << "Press Enter to Exit ;-)\n"; std::cout << "Press Enter to Exit ;-)\n";
console.ReadLine(); console.ReadLine();
return 0; return 0;
} }

View File

@@ -1,31 +1,32 @@
# Copyright 2012 Wolfgang Thaller. # Copyright 2012 Wolfgang Thaller.
# #
# This file is part of Retro68. # This file is part of Retro68.
# #
# Retro68 is free software: you can redistribute it and/or modify # Retro68 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# Retro68 is distributed in the hope that it will be useful, # Retro68 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Retro68. If not, see <http://www.gnu.org/licenses/>. # along with Retro68. If not, see <http://www.gnu.org/licenses/>.
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
add_library(retrocrt_multi add_library(retrocrt_multi
start.c start.c
malloc.c malloc.c
syscalls.c syscalls.c
) )
add_custom_command( add_custom_command(
OUTPUT retrocrt.o OUTPUT retrocrt.o
DEPENDS retrocrt_multi DEPENDS retrocrt_multi
COMMAND ${CMAKE_LINKER} -r -o retrocrt.o --whole-archive libretrocrt_multi.a COMMAND ${CMAKE_LINKER} -r -o retrocrt.o
) --whole-archive libretrocrt_multi.a
)
add_library(retrocrt retrocrt.o glue.c) add_library(retrocrt retrocrt.o glue.c)
#add_custom_target(retrocrt_o ALL DEPENDS retrocrt.o) #add_custom_target(retrocrt_o ALL DEPENDS retrocrt.o)
install(TARGETS retrocrt DESTINATION lib) install(TARGETS retrocrt DESTINATION lib)

View File

@@ -1,34 +1,34 @@
/* /*
Copyright 2012 Wolfgang Thaller. Copyright 2012 Wolfgang Thaller.
This file is part of Retro68. This file is part of Retro68.
Retro68 is free software: you can redistribute it and/or modify Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Retro68 is distributed in the hope that it will be useful, Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>. along with Retro68. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <MacMemory.h> #include <MacMemory.h>
Size GetPtrSize(Ptr ptr) Size GetPtrSize(Ptr ptr)
{ {
long tmp; long tmp;
__asm__ __volatile__( __asm__ __volatile__(
"move.l %1, %%a0\n\t" "move.l %1, %%a0\n\t"
"dc.w 0xA021\n\t" "dc.w 0xA021\n\t"
"move.l %%d0, %1" "move.l %%d0, %1"
: "=g"(tmp) : "g"(ptr) : "%%a0", "%%d0"); : "=g"(tmp) : "g"(ptr) : "%%a0", "%%d0");
if(tmp > 0) if(tmp > 0)
return (Size) tmp; return (Size) tmp;
else else
return 0; return 0;
} }

View File

@@ -1,20 +1,20 @@
/* /*
Copyright 2012 Wolfgang Thaller. Copyright 2012 Wolfgang Thaller.
This file is part of Retro68. This file is part of Retro68.
Retro68 is free software: you can redistribute it and/or modify Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Retro68 is distributed in the hope that it will be useful, Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>. along with Retro68. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdlib.h> #include <stdlib.h>
@@ -27,70 +27,70 @@ void referenceMyMalloc() {}
void *_malloc_r(struct _reent *reent_ptr, size_t sz) void *_malloc_r(struct _reent *reent_ptr, size_t sz)
{ {
return NewPtr(sz); // TODO: set errno return NewPtr(sz); // TODO: set errno
} }
void *_calloc_r(struct _reent *reent_ptr, size_t sz, size_t sz2) void *_calloc_r(struct _reent *reent_ptr, size_t sz, size_t sz2)
{ {
return NewPtrClear(sz*sz2); // TODO: set errno return NewPtrClear(sz*sz2); // TODO: set errno
} }
void _free_r(struct _reent *reent_ptr, void *ptr) void _free_r(struct _reent *reent_ptr, void *ptr)
{ {
if(ptr != NULL) if(ptr != NULL)
DisposePtr(ptr); DisposePtr(ptr);
} }
void *_realloc_r(struct _reent *reent_ptr, void *ptr, size_t sz) void *_realloc_r(struct _reent *reent_ptr, void *ptr, size_t sz)
{ {
if(ptr == NULL) if(ptr == NULL)
{ {
return NewPtr(sz); return NewPtr(sz);
} }
else else
{ {
MemError(); MemError();
SetPtrSize(ptr, sz); SetPtrSize(ptr, sz);
if(MemError()) if(MemError())
{ {
size_t oldSz = GetPtrSize(ptr); size_t oldSz = GetPtrSize(ptr);
if(sz > oldSz) if(sz > oldSz)
{ {
void *newPtr = NewPtr(sz); void *newPtr = NewPtr(sz);
if(!newPtr) if(!newPtr)
{ {
errno = ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
memcpy(newPtr, ptr, oldSz); memcpy(newPtr, ptr, oldSz);
return newPtr; return newPtr;
} }
else else
{ {
errno = ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
} }
else else
return ptr; return ptr;
} }
} }
void *malloc(size_t sz) void *malloc(size_t sz)
{ {
return _malloc_r(_REENT, sz); return _malloc_r(_REENT, sz);
} }
void free(void *p) void free(void *p)
{ {
_free_r(_REENT, p); _free_r(_REENT, p);
} }
void *realloc(void *ptr, size_t sz) void *realloc(void *ptr, size_t sz)
{ {
return _realloc_r(_REENT, ptr, sz); return _realloc_r(_REENT, ptr, sz);
} }
void *calloc(size_t sz1, size_t sz2) void *calloc(size_t sz1, size_t sz2)
{ {
return _calloc_r(_REENT, sz1, sz2); return _calloc_r(_REENT, sz1, sz2);
} }

View File

@@ -1,20 +1,20 @@
/* /*
Copyright 2012 Wolfgang Thaller. Copyright 2012 Wolfgang Thaller.
This file is part of Retro68. This file is part of Retro68.
Retro68 is free software: you can redistribute it and/or modify Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Retro68 is distributed in the hope that it will be useful, Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>. along with Retro68. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdint.h> #include <stdint.h>
@@ -31,19 +31,19 @@ struct flat_hdr {
char magic[4]; char magic[4];
unsigned long rev; /* version */ unsigned long rev; /* version */
unsigned long entry; /* Offset of first executable instruction unsigned long entry; /* Offset of first executable instruction
with text segment from beginning of file */ with text segment from beginning of file */
unsigned long data_start; /* Offset of data segment from beginning of unsigned long data_start; /* Offset of data segment from beginning of
file */ file */
unsigned long data_end; /* Offset of end of data segment unsigned long data_end; /* Offset of end of data segment
from beginning of file */ from beginning of file */
unsigned long bss_end; /* Offset of end of bss segment from beginning unsigned long bss_end; /* Offset of end of bss segment from beginning
of file */ of file */
/* (It is assumed that data_end through bss_end forms the bss segment.) */ /* (It is assumed that data_end through bss_end forms the bss segment.) */
unsigned long stack_size; /* Size of stack, in bytes */ unsigned long stack_size; /* Size of stack, in bytes */
unsigned long reloc_start; /* Offset of relocation records from unsigned long reloc_start; /* Offset of relocation records from
beginning of file */ beginning of file */
unsigned long reloc_count; /* Number of relocation records */ unsigned long reloc_count; /* Number of relocation records */
unsigned long flags; unsigned long flags;
unsigned long filler[6]; /* Reserved, set to zero */ unsigned long filler[6]; /* Reserved, set to zero */
@@ -75,24 +75,24 @@ void _start()
env.processor = 0; env.processor = 0;
__asm__ __volatile__ ( __asm__ __volatile__ (
"move.w #2, %%d0\n\t" // versionRequested "move.w #2, %%d0\n\t" // versionRequested
"lea %0, %%a0\n\t" // &env "lea %0, %%a0\n\t" // &env
"dc.w 0xa090\n\t" // _SysEnvirons "dc.w 0xa090\n\t" // _SysEnvirons
: :
: "m"(env) : "m"(env)
: "%a0", "%a1", "%d0", "%d1", "%d2", "memory", "cc" : "%a0", "%a1", "%d0", "%d1", "%d2", "memory", "cc"
); );
bss_size = header->bss_end - header->data_end; bss_size = header->bss_end - header->data_end;
//Ptr bss = NewPtrClear(bss_size); //Ptr bss = NewPtrClear(bss_size);
__asm__ __volatile__ ( __asm__ __volatile__ (
"move.l %1, %%d0\n\t" "move.l %1, %%d0\n\t"
"dc.w 0xa31e\n\t" // _NewPtrClear "dc.w 0xa31e\n\t" // _NewPtrClear
"move.l %%a0 , %0\n\t" "move.l %%a0 , %0\n\t"
: "=g"(bss) : "=g"(bss)
: "g"(bss_size) : "g"(bss_size)
: "%a0", "%a1", "%d0", "%d1", "%d2", "memory", "cc" : "%a0", "%a1", "%d0", "%d1", "%d2", "memory", "cc"
); );
long n = header->reloc_count; long n = header->reloc_count;
long *relocs = (long*)( (char*)header + header->reloc_start ); long *relocs = (long*)( (char*)header + header->reloc_start );

View File

@@ -1,20 +1,20 @@
/* /*
Copyright 2012 Wolfgang Thaller. Copyright 2012 Wolfgang Thaller.
This file is part of Retro68. This file is part of Retro68.
Retro68 is free software: you can redistribute it and/or modify Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Retro68 is distributed in the hope that it will be useful, Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>. along with Retro68. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <sys/types.h> #include <sys/types.h>
@@ -26,17 +26,17 @@
int isatty(int fd) { return fd >= 0 && fd <= 2; } int isatty(int fd) { return fd >= 0 && fd <= 2; }
void *sbrk(long increment) void *sbrk(long increment)
{ {
Debugger(); Debugger();
return NewPtrClear(increment); return NewPtrClear(increment);
} }
void _exit(int status) void _exit(int status)
{ {
if(status != 0) if(status != 0)
Debugger(); Debugger();
ExitToShell(); ExitToShell();
for(;;) for(;;)
; ;
} }
ssize_t (*__write_hook)(int fd, const void*buf, size_t count) = NULL; ssize_t (*__write_hook)(int fd, const void*buf, size_t count) = NULL;
@@ -44,48 +44,48 @@ ssize_t (*__read_hook)(int fd, void*buf, size_t count) = NULL;
ssize_t write(int fd, const void *buf, size_t count) ssize_t write(int fd, const void *buf, size_t count)
{ {
if(__write_hook) if(__write_hook)
return (*__write_hook)(fd,buf,count); return (*__write_hook)(fd,buf,count);
return -1; return -1;
} }
ssize_t read(int fd, void *buf, size_t count) ssize_t read(int fd, void *buf, size_t count)
{ {
if(__read_hook) if(__read_hook)
return (*__read_hook)(fd,buf,count); return (*__read_hook)(fd,buf,count);
return -1; return -1;
} }
int open(const char* name, int flags, mode_t mode) int open(const char* name, int flags, mode_t mode)
{ {
__asm__ __volatile__ ("dc.w 0xa9ff"); __asm__ __volatile__ ("dc.w 0xa9ff");
return -1; return -1;
} }
int close(int fd) int close(int fd)
{ {
return -1; return -1;
} }
int fstat(int fd, struct stat *buf) int fstat(int fd, struct stat *buf)
{ {
return -1; return -1;
} }
off_t lseek(int fd, off_t offset, int whence) off_t lseek(int fd, off_t offset, int whence)
{ {
return (off_t) -1; return (off_t) -1;
} }
int kill(pid_t pid, int sig) int kill(pid_t pid, int sig)
{ {
if(pid == 42) if(pid == 42)
_exit(42); _exit(42);
else else
return -1; return -1;
} }
pid_t getpid(void) pid_t getpid(void)
{ {
return 42; return 42;
} }