Created
November 24, 2017 18:27
-
-
Save DavidLudwig/b0c18a80f7082e298adc7b9766c74468 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ShowBitmap_Mac68k.cpp | |
// by David Ludwig <[email protected]> | |
// | |
// Shows a 1-bit, XBM bitmap on an emulated (via pce-macplus) 4 MB Mac Plus. | |
// | |
// Compiled with g++ flags: | |
// -Os -o romtest.o -fno-builtin -m68000 -nostdlib -mpcrel -Xlinker --oformat=binary | |
// | |
// Kudos to Jon Sharp, for blog post with details on useful gcc compiler flags: | |
// http://jonsharp.net/retrocomputing/bare-metal-macintosh-programming-part-2/ | |
#include <stdint.h> | |
#include <algorithm> | |
// #include the picture-to-display, via use of a 1-bit XBM bitmap, a file | |
// format that encodes pictures as plain C code. | |
#include "Picture.xbm" | |
// | |
// Hardware-related variables | |
// | |
// ScrnBase: Points to the start of the display-buffer | |
// Credits here to http://www.osdata.com/system/physical/memmap.htm#MacPlusvideo | |
// | |
// uint8_t * ScrnBase = (uint8_t *) 0xFA700; // Mac Plus, 1 MB RAM, Main | |
// uint8_t * ScrnBase = (uint8_t *) 0xF2700; // Mac Plus, 1 MB RAM, Alternate | |
// uint8_t * ScrnBase = (uint8_t *) 0x1FA700; // Mac Plus, 2 MB RAM, Main | |
// uint8_t * ScrnBase = (uint8_t *) 0x1F2700; // Mac Plus, 2 MB RAM, Alternate | |
// uint8_t * ScrnBase = (uint8_t *) 0x27A700; // Mac Plus, 2.5 MB RAM, Main | |
// uint8_t * ScrnBase = (uint8_t *) 0x272700; // Mac Plus, 2.5 MB RAM, Alternate | |
uint8_t * ScrnBase = (uint8_t *) 0x3FA700; // Mac Plus, 4 MB RAM, Main | |
// uint8_t * ScrnBase = (uint8_t *) 0x3F2700; // Mac Plus, 4 MB RAM, Alternate | |
// Screen Dimensions | |
const int ScrnWidth = 512; | |
const int ScrnHeight = 342; | |
// VIA1 memory addresses and offsets | |
uint8_t * const vBase = (uint8_t *) 0xEFE1FE; // base address to VIA1 | |
const int vDirA = 512 * 3; // offset from vBase, to VIA data register A | |
// | |
// Utility functions | |
// | |
// Reverses order of bits in a given byte | |
static uint8_t ReverseBits(uint8_t b) { | |
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; | |
b = (b & 0xCC) >> 2 | (b & 0x33) << 2; | |
b = (b & 0xAA) >> 1 | (b & 0x55) << 1; | |
return b; | |
} | |
// | |
// main() function | |
// | |
int main(int argc, char **argv) { | |
// Setup the 68k CPU's Stack Pointer (register "sp", aka. "a7") | |
__asm__ ( | |
"movea.l #00100000,%%sp\n\t" | |
: /* outputs */ | |
: /* inputs */ | |
: "sp" /* clobbered regs */ | |
); | |
// Setup VIA1 Data Register A. Not doing this causes the PCE emulator | |
// to not fully setup its internal, RAM-tracking, data structures. | |
vBase[vDirA] = 0x3F; | |
// Fill screen with white | |
for (int i = 0; i < ((ScrnWidth * ScrnHeight) >> 3); ++i) { | |
ScrnBase[i] = 0x00; | |
} | |
// Draw Picture at top-left of screen | |
const int drawHeight = std::min(Picture_height, ScrnHeight); | |
const int drawWidth = std::min(Picture_width, ScrnWidth); | |
for (int y = 0; y < drawHeight; ++y) { | |
for (int x = 0; x < (drawWidth >> 3); ++x) { | |
// The XBM image's bits are reversed. This may be an artifact of | |
// XBM itself, or by The Gimp's XBM exporter, or how Mac Plus's like | |
// its sits. Any which way, reversing the bits gets the correct | |
// value to display. | |
const uint8_t b = ReverseBits(Picture_bits[(y * (Picture_width >> 3)) + x]); | |
ScrnBase[(y * (ScrnWidth >> 3)) + x] = b; | |
} | |
} | |
// Sit in a no-op loop | |
while (1) { | |
__asm__ ( | |
"nop\n\t" | |
); | |
} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment