use more well-defined int types

This commit is contained in:
Brad Grantham 2020-12-16 23:03:43 -08:00
parent fb7d31d814
commit 3c1b43f2ad
4 changed files with 206 additions and 165 deletions

View File

@ -13,5 +13,7 @@ all: apple2e
apple2e: $(OBJECTS) apple2e: $(OBJECTS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $@ $(LDLIBS) $(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $@ $(LDLIBS)
apple2e.o: cpu6502.h
clean: clean:
rm $(OBJECTS) rm $(OBJECTS)

View File

@ -14,11 +14,53 @@
#include <thread> #include <thread>
#include <functional> #include <functional>
#include <signal.h> #include <signal.h>
#include <unistd.h>
#ifndef M_PI #ifndef M_PI
#define M_PI 3.14159 #define M_PI 3.14159
#endif #endif
typedef uint64_t clk_t;
struct system_clock
{
clk_t clock_cpu = 0; // Actual CPU and memory clocks, variable rate
clk_t clock_14mhz = 0; // Fixed 14.31818MHz clock
clk_t phase_hpe = 0; // Phase of CPU clock within horizontal lines
operator clk_t() const { return clock_14mhz; }
void add_cpu_cycles(clk_t elapsed_cpu)
{
clock_cpu += elapsed_cpu;
clock_14mhz += elapsed_cpu * 14 + (elapsed_cpu + phase_hpe) / 65 * 2;
phase_hpe = (phase_hpe + elapsed_cpu) % 65;
if(0) printf("added %llu, new cpu clock %llu, 14mhz clock %llu, phase %llu\n", elapsed_cpu, clock_cpu, clock_14mhz, phase_hpe);
}
} clk;
#define printf PrintToLine3
clk_t clockRangeStart = 2427489692 - 100000;
clk_t clockRangeEnd = 2427489692 + 1000;
void PrintToLine3(const char *fmt, ...)
{
if(clk < clockRangeStart) {
return;
}
if(clk > clockRangeEnd) {
abort();
}
static char buffer[36];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
write(0, buffer, strlen(buffer));
}
// Brad's 6502 // Brad's 6502
#include "cpu6502.h" #include "cpu6502.h"
@ -37,15 +79,16 @@ using namespace std;
#define LK_HACK 0 #define LK_HACK 0
constexpr unsigned int DEBUG_ERROR = 0x01; constexpr uint32_t DEBUG_ERROR = 0x01;
constexpr unsigned int DEBUG_WARN = 0x02; constexpr uint32_t DEBUG_WARN = 0x02;
constexpr unsigned int DEBUG_DECODE = 0x04; constexpr uint32_t DEBUG_DECODE = 0x04;
constexpr unsigned int DEBUG_STATE = 0x08; constexpr uint32_t DEBUG_STATE = 0x08;
constexpr unsigned int DEBUG_RW = 0x10; constexpr uint32_t DEBUG_RW = 0x10;
constexpr unsigned int DEBUG_BUS = 0x20; constexpr uint32_t DEBUG_BUS = 0x20;
constexpr unsigned int DEBUG_FLOPPY = 0x40; constexpr uint32_t DEBUG_FLOPPY = 0x40;
constexpr unsigned int DEBUG_SWITCH = 0x80; constexpr uint32_t DEBUG_SWITCH = 0x80;
volatile unsigned int debug = DEBUG_ERROR | DEBUG_WARN; // | DEBUG_DECODE | DEBUG_STATE | DEBUG_RW; constexpr uint32_t DEBUG_CLOCK = 0x100;
volatile unsigned int debug = DEBUG_ERROR | DEBUG_WARN; // DEBUG_DECODE | DEBUG_RW | DEBUG_STATE | DEBUG_CLOCK; // | DEBUG_DECODE | DEBUG_STATE | DEBUG_RW;
bool delete_is_left_arrow = true; bool delete_is_left_arrow = true;
volatile bool exit_on_banking = false; volatile bool exit_on_banking = false;
@ -64,26 +107,10 @@ const float paddle_max_pulse_seconds = .00282;
// Map from memory address to name of function (from the ld65 map file). // Map from memory address to name of function (from the ld65 map file).
static map<int,string> address_to_function_name; static map<int,string> address_to_function_name;
typedef unsigned long long clk_t;
struct system_clock
{
clk_t clock_cpu = 0; // Actual CPU and memory clocks, variable rate
clk_t clock_14mhz = 0; // Fixed 14.31818MHz clock
clk_t phase_hpe = 0; // Phase of CPU clock within horizontal lines
operator clk_t() const { return clock_14mhz; }
void add_cpu_cycles(clk_t elapsed_cpu)
{
clock_cpu += elapsed_cpu;
clock_14mhz += elapsed_cpu * 14 + (elapsed_cpu + phase_hpe) / 65 * 2;
phase_hpe = (phase_hpe + elapsed_cpu) % 65;
if(0) printf("added %llu, new cpu clock %llu, 14mhz clock %llu, phase %llu\n", elapsed_cpu, clock_cpu, clock_14mhz, phase_hpe);
}
} clk;
const int machine_clock_rate = 14318180; const int machine_clock_rate = 14318180;
bool read_blob(const char *name, unsigned char *b, size_t sz) bool read_blob(const char *name, uint8_t *b, size_t sz)
{ {
FILE *fp = fopen(name, "rb"); FILE *fp = fopen(name, "rb");
if(fp == NULL) { if(fp == NULL) {
@ -211,7 +238,7 @@ enum MemoryType {RAM, ROM};
struct backed_region : region struct backed_region : region
{ {
vector<unsigned char> memory; vector<uint8_t> memory;
MemoryType type; MemoryType type;
enabled_func read_enabled; enabled_func read_enabled;
enabled_func write_enabled; enabled_func write_enabled;
@ -245,7 +272,7 @@ struct backed_region : region
return (addr >= base) && (addr < base + size); return (addr >= base) && (addr < base + size);
} }
bool read(int addr, unsigned char& data) bool read(int addr, uint8_t& data)
{ {
if(contains(addr) && read_enabled()) { if(contains(addr) && read_enabled()) {
data = memory[addr - base]; data = memory[addr - base];
@ -254,7 +281,7 @@ struct backed_region : region
return false; return false;
} }
bool write(int addr, unsigned char data) bool write(int addr, uint8_t data)
{ {
if((type == RAM) && contains(addr) && write_enabled()) { if((type == RAM) && contains(addr) && write_enabled()) {
memory[addr - base] = data; memory[addr - base] = data;
@ -278,7 +305,7 @@ constexpr int sectorSize = 256;
constexpr int sectorsPerTrack = 16; constexpr int sectorsPerTrack = 16;
constexpr int tracksPerFloppy = 35; constexpr int tracksPerFloppy = 35;
const unsigned char sectorHeader[21] = const uint8_t sectorHeader[21] =
{ {
0xD5, 0xAA, 0x96, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0xD5, 0xAA, 0x96, 0xFF, 0xFE, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xDE, 0xAA, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xDE, 0xAA, 0xFF, 0xFF, 0xFF,
@ -294,7 +321,7 @@ const int sectorSkewProDOS[16] =
0x0, 0x8, 0x1, 0x9, 0x2, 0xA, 0x3, 0xB, 0x4, 0xC, 0x5, 0xD, 0x6, 0xE, 0x7, 0xF 0x0, 0x8, 0x1, 0x9, 0x2, 0xA, 0x3, 0xB, 0x4, 0xC, 0x5, 0xD, 0x6, 0xE, 0x7, 0xF
}; };
const unsigned char sectorFooter[48] = const uint8_t sectorFooter[48] =
{ {
0xDE, 0xAA, 0xEB, 0xFF, 0xEB, 0xFF, 0xFF, 0xFF, 0xDE, 0xAA, 0xEB, 0xFF, 0xEB, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
@ -303,7 +330,7 @@ const unsigned char sectorFooter[48] =
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
}; };
const unsigned char SixBitsToBytes[0x40] = const uint8_t SixBitsToBytes[0x40] =
{ {
0x96, 0x97, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA6, 0x96, 0x97, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA6,
0xA7, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB3, 0xA7, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB3,
@ -372,20 +399,20 @@ void nybblizeSector(int trackIndex, int sectorIndex, const uint8_t *sectorBytes,
// p += 48; // p += 48;
} }
bool nybblizeTrackFromFile(FILE *floppyImageFile, int trackIndex, unsigned char *nybblizedTrack, const int *skew) bool nybblizeTrackFromFile(FILE *floppyImageFile, int trackIndex, uint8_t *nybblizedTrack, const int *skew)
{ {
memset(nybblizedTrack, 0xFF, trackGapSize); // Write gap 1, 64 bytes (self-sync) memset(nybblizedTrack, 0xFF, trackGapSize); // Write gap 1, 64 bytes (self-sync)
for(unsigned char sectorIndex = 0; sectorIndex < 16; sectorIndex++) for(int sectorIndex = 0; sectorIndex < 16; sectorIndex++)
{ {
long sectorOffset = (skew[sectorIndex] + trackIndex * sectorsPerTrack) * sectorSize; uint32_t sectorOffset = (skew[sectorIndex] + trackIndex * sectorsPerTrack) * sectorSize;
int seeked = fseek(floppyImageFile, sectorOffset, SEEK_SET); int seeked = fseek(floppyImageFile, sectorOffset, SEEK_SET);
if(seeked == -1) { if(seeked == -1) {
fprintf(stderr, "failed to seek to sector in floppy disk image\n"); fprintf(stderr, "failed to seek to sector in floppy disk image\n");
return false; return false;
} }
unsigned char sectorBytes[256]; uint8_t sectorBytes[256];
size_t wasRead = fread(sectorBytes, 1, sectorSize, floppyImageFile); size_t wasRead = fread(sectorBytes, 1, sectorSize, floppyImageFile);
if(wasRead != sectorSize) { if(wasRead != sectorSize) {
fprintf(stderr, "failed to read sector from floppy disk image\n"); fprintf(stderr, "failed to read sector from floppy disk image\n");
@ -414,7 +441,7 @@ struct DISKIIboard : board_base
static constexpr int Q7L = 0xC0EE; // IO strobe for clear static constexpr int Q7L = 0xC0EE; // IO strobe for clear
static constexpr int Q7H = 0xC0EF; // IO strobe for shift static constexpr int Q7H = 0xC0EF; // IO strobe for shift
const map<unsigned int, string> io = { const map<uint32_t, string> io = {
{0xC0E0, "CA0OFF"}, {0xC0E0, "CA0OFF"},
{0xC0E1, "CA0ON"}, {0xC0E1, "CA0ON"},
{0xC0E2, "CA1OFF"}, {0xC0E2, "CA1OFF"},
@ -444,7 +471,7 @@ struct DISKIIboard : board_base
int driveSelected = 0; int driveSelected = 0;
bool driveMotorEnabled[2]; bool driveMotorEnabled[2];
enum {READ, WRITE} headMode = READ; enum {READ, WRITE} headMode = READ;
unsigned char dataLatch = 0x00; uint8_t dataLatch = 0x00;
int headStepperPhase[2][4] = { {0, 0, 0, 0}, {0, 0, 0, 0} }; int headStepperPhase[2][4] = { {0, 0, 0, 0}, {0, 0, 0, 0} };
int headStepperMostRecentPhase[2] = {0, 0}; int headStepperMostRecentPhase[2] = {0, 0};
int currentTrackNumber[2] = {0, 0}; // physical track number - DOS and ProDOS only use even tracks int currentTrackNumber[2] = {0, 0}; // physical track number - DOS and ProDOS only use even tracks
@ -454,7 +481,7 @@ struct DISKIIboard : board_base
bool trackBytesOutOfDate = true; bool trackBytesOutOfDate = true;
int nybblizedTrackIndex = -1; int nybblizedTrackIndex = -1;
int nybblizedDriveIndex = -1; int nybblizedDriveIndex = -1;
unsigned int trackByteIndex = 0; uint32_t trackByteIndex = 0;
void set_floppy(int number, const char *name) // number 0 or 1; name = NULL to eject void set_floppy(int number, const char *name) // number 0 or 1; name = NULL to eject
{ {
@ -494,7 +521,7 @@ struct DISKIIboard : board_base
typedef std::function<void (int number, bool activity)> floppy_activity_func; typedef std::function<void (int number, bool activity)> floppy_activity_func;
floppy_activity_func floppy_activity; floppy_activity_func floppy_activity;
DISKIIboard(const unsigned char diskII_rom[256], const char *floppy0_name, const char *floppy1_name, floppy_activity_func floppy_activity_) : DISKIIboard(const uint8_t diskII_rom[256], const char *floppy0_name, const char *floppy1_name, floppy_activity_func floppy_activity_) :
floppy_activity(floppy_activity_) floppy_activity(floppy_activity_)
{ {
std::copy(diskII_rom, diskII_rom + 0x100, rom_C600.memory.begin()); std::copy(diskII_rom, diskII_rom + 0x100, rom_C600.memory.begin());
@ -506,7 +533,7 @@ struct DISKIIboard : board_base
} }
} }
unsigned char readNextTrackByte() uint8_t readNextTrackByte()
{ {
if(headMode != READ || !driveMotorEnabled[driveSelected] || !floppyPresent[driveSelected]) if(headMode != READ || !driveMotorEnabled[driveSelected] || !floppyPresent[driveSelected])
return 0x00; return 0x00;
@ -545,7 +572,7 @@ struct DISKIIboard : board_base
return true; return true;
} }
void controlTrackMotor(unsigned int addr) void controlTrackMotor(uint32_t addr)
{ {
int phase = (addr & 0x7) >> 1; int phase = (addr & 0x7) >> 1;
int state = addr & 0x1; int state = addr & 0x1;
@ -588,7 +615,7 @@ struct DISKIIboard : board_base
} }
} }
virtual bool write(int addr, unsigned char data) virtual bool write(int addr, uint8_t data)
{ {
if(addr < 0xC0E0 || addr > 0xC0EF) if(addr < 0xC0E0 || addr > 0xC0EF)
return false; return false;
@ -596,7 +623,7 @@ struct DISKIIboard : board_base
return false; return false;
} }
virtual bool read(int addr, unsigned char &data) virtual bool read(int addr, uint8_t &data)
{ {
if(rom_C600.read(addr, data)) { if(rom_C600.read(addr, data)) {
if(debug & DEBUG_RW) printf("DiskII read 0x%04X -> %02X\n", addr, data); if(debug & DEBUG_RW) printf("DiskII read 0x%04X -> %02X\n", addr, data);
@ -677,7 +704,7 @@ struct Mockingboard : board_base
{ {
} }
virtual bool write(int addr, unsigned char data) virtual bool write(int addr, uint8_t data)
{ {
if((addr >= 0xC400) && (addr <= 0xC4FF)) { if((addr >= 0xC400) && (addr <= 0xC4FF)) {
if(debug & DEBUG_RW) printf("Mockingboard write 0x%02X to 0x%04X ignored\n", data, addr); if(debug & DEBUG_RW) printf("Mockingboard write 0x%02X to 0x%04X ignored\n", data, addr);
@ -685,7 +712,7 @@ struct Mockingboard : board_base
} }
return false; return false;
} }
virtual bool read(int addr, unsigned char &data) virtual bool read(int addr, uint8_t &data)
{ {
if((addr >= 0xC400) && (addr <= 0xC4FF)) { if((addr >= 0xC400) && (addr <= 0xC4FF)) {
if(debug & DEBUG_RW) printf("Mockingboard read at 0x%04X ignored\n", addr); if(debug & DEBUG_RW) printf("Mockingboard read at 0x%04X ignored\n", addr);
@ -699,7 +726,7 @@ struct Mockingboard : board_base
const int waveform_length = 44100 / 1000 / 2; // half of a wave at 4000 Hz const int waveform_length = 44100 / 1000 / 2; // half of a wave at 4000 Hz
const float waveform_max_amplitude = .35f; const float waveform_max_amplitude = .35f;
static unsigned char waveform[waveform_length]; static uint8_t waveform[waveform_length];
static void initialize_audio_waveform() __attribute__((constructor)); static void initialize_audio_waveform() __attribute__((constructor));
void initialize_audio_waveform() void initialize_audio_waveform()
@ -948,19 +975,19 @@ struct MAINboard : board_base
0xC00A, 0xC00B, 0xC00A, 0xC00B,
}; };
deque<unsigned char> keyboard_buffer; deque<uint8_t> keyboard_buffer;
static const int sample_rate = 44100; static const int sample_rate = 44100;
static const size_t audio_buffer_size = sample_rate / 100; static const size_t audio_buffer_size = sample_rate / 100;
char audio_buffer[audio_buffer_size]; uint8_t audio_buffer[audio_buffer_size];
long long audio_buffer_start_sample = 0; uint64_t audio_buffer_start_sample = 0;
long long audio_buffer_next_sample = 0; uint64_t audio_buffer_next_sample = 0;
unsigned char speaker_level; uint8_t speaker_level;
bool speaker_transitioning_to_high = false; bool speaker_transitioning_to_high = false;
int where_in_waveform = 0; int where_in_waveform = 0;
#if LK_HACK #if LK_HACK
unsigned char *disassemble_buffer = 0; uint8_t *disassemble_buffer = 0;
int disassemble_state = 0; int disassemble_state = 0;
int disassemble_index = 0; int disassemble_index = 0;
int disassemble_size = 0; int disassemble_size = 0;
@ -969,11 +996,11 @@ struct MAINboard : board_base
void fill_flush_audio() void fill_flush_audio()
{ {
long long current_sample = clk * sample_rate / machine_clock_rate; uint64_t current_sample = clk * sample_rate / machine_clock_rate;
for(long long i = audio_buffer_next_sample; i < current_sample; i++) { for(uint64_t i = audio_buffer_next_sample; i < current_sample; i++) {
if(where_in_waveform < waveform_length) { if(where_in_waveform < waveform_length) {
unsigned char level = waveform[where_in_waveform++]; uint8_t level = waveform[where_in_waveform++];
speaker_level = speaker_transitioning_to_high ? level : (255 - level); speaker_level = speaker_transitioning_to_high ? level : (255 - level);
} }
@ -1000,7 +1027,7 @@ struct MAINboard : board_base
fill_flush_audio(); fill_flush_audio();
} }
void enqueue_key(unsigned char k) void enqueue_key(uint8_t k)
{ {
keyboard_buffer.push_back(k); keyboard_buffer.push_back(k);
} }
@ -1028,14 +1055,14 @@ struct MAINboard : board_base
} }
} }
typedef std::function<bool (int addr, bool aux, unsigned char data)> display_write_func; typedef std::function<bool (int addr, bool aux, uint8_t data)> display_write_func;
display_write_func display_write; display_write_func display_write;
typedef std::function<void (char *audiobuffer, size_t dist)> audio_flush_func; typedef std::function<void (uint8_t *audiobuffer, size_t dist)> audio_flush_func;
audio_flush_func audio_flush; audio_flush_func audio_flush;
typedef std::function<tuple<float, bool> (int num)> get_paddle_func; typedef std::function<tuple<float, bool> (int num)> get_paddle_func;
get_paddle_func get_paddle; get_paddle_func get_paddle;
clk_t paddles_clock_out[4]; clk_t paddles_clock_out[4];
MAINboard(system_clock& clk_, const unsigned char rom_image[32768], display_write_func display_write_, audio_flush_func audio_flush_, get_paddle_func get_paddle_) : MAINboard(system_clock& clk_, const uint8_t rom_image[32768], display_write_func display_write_, audio_flush_func audio_flush_, get_paddle_func get_paddle_) :
clk(clk_), clk(clk_),
internal_C800_ROM_selected(true), internal_C800_ROM_selected(true),
speaker_level(waveform[0]), speaker_level(waveform[0]),
@ -1087,7 +1114,7 @@ struct MAINboard : board_base
} }
} }
bool read(int addr, unsigned char &data) bool read(int addr, uint8_t &data)
{ {
if(debug & DEBUG_RW) printf("MAIN board read\n"); if(debug & DEBUG_RW) printf("MAIN board read\n");
for(auto b : boards) { for(auto b : boards) {
@ -1109,7 +1136,7 @@ struct MAINboard : board_base
SoftSwitch* sw = switches_by_address[addr - 0xC000]; SoftSwitch* sw = switches_by_address[addr - 0xC000];
if(sw != nullptr) { if(sw != nullptr) {
unsigned char result = 0xFF; uint8_t result = 0xFF;
// Special case for floating bus for reading video scanout // Special case for floating bus for reading video scanout
// XXX doesn't handle 80-column nor AUX // XXX doesn't handle 80-column nor AUX
@ -1283,7 +1310,7 @@ struct MAINboard : board_base
} }
return false; return false;
} }
bool write(int addr, unsigned char data) bool write(int addr, uint8_t data)
{ {
#if LK_HACK #if LK_HACK
if(addr == 0xBFFE) { if(addr == 0xBFFE) {
@ -1306,7 +1333,7 @@ struct MAINboard : board_base
case 1: case 1:
// MSB of size. // MSB of size.
disassemble_size |= data << 8; disassemble_size |= data << 8;
disassemble_buffer = new unsigned char[disassemble_size]; disassemble_buffer = new uint8_t[disassemble_size];
disassemble_index = 0; disassemble_index = 0;
printf("Size of buffer: %d bytes\n", disassemble_size); printf("Size of buffer: %d bytes\n", disassemble_size);
@ -1462,30 +1489,38 @@ struct MAINboard : board_base
struct bus_frontend struct bus_frontend
{ {
MAINboard* board; MAINboard* board;
map<int, vector<unsigned char> > writes; map<int, vector<uint8_t> > writes;
map<int, vector<unsigned char> > reads; map<int, vector<uint8_t> > reads;
unsigned char read(int addr) uint8_t read(uint16_t addr)
{ {
unsigned char data = 0xaa; uint8_t data = 0xaa;
if(board->read(addr & 0xFFFF, data)) { if(board->read(addr & 0xFFFF, data)) {
if(debug & DEBUG_BUS) printf("read %04X returned %02X\n", addr & 0xFFFF, data); if(debug & DEBUG_BUS)
{
printf("read %04X returned %02X\n", addr & 0xFFFF, data);
}
// reads[addr & 0xFFFF].push_back(data); // reads[addr & 0xFFFF].push_back(data);
return data; return data;
} }
if(debug & DEBUG_ERROR) if(debug & DEBUG_ERROR) {
fprintf(stderr, "no ownership of read at %04X\n", addr & 0xFFFF); fprintf(stderr, "no ownership of read at %04X\n", addr & 0xFFFF);
}
return 0xAA; return 0xAA;
} }
void write(int addr, unsigned char data) void write(uint16_t addr, uint8_t data)
{ {
if(board->write(addr & 0xFFFF, data)) { if(board->write(addr & 0xFFFF, data)) {
if(debug & DEBUG_BUS) printf("write %04X %02X\n", addr & 0xFFFF, data); if(debug & DEBUG_BUS)
{
printf("write %04X %02X\n", addr & 0xFFFF, data);
}
// writes[addr & 0xFFFF].push_back(data); // writes[addr & 0xFFFF].push_back(data);
return; return;
} }
if(debug & DEBUG_ERROR) if(debug & DEBUG_ERROR) {
fprintf(stderr, "no ownership of write %02X at %04X\n", data, addr & 0xFFFF); fprintf(stderr, "no ownership of write %02X at %04X\n", data, addr & 0xFFFF);
}
} }
void reset() void reset()
@ -1547,7 +1582,7 @@ string read_bus_and_disassemble(bus_frontend &bus, int pc)
{ {
int bytes; int bytes;
string dis; string dis;
unsigned char buf[4]; uint8_t buf[4];
buf[0] = bus.read(pc + 0); buf[0] = bus.read(pc + 0);
buf[1] = bus.read(pc + 1); buf[1] = bus.read(pc + 1);
buf[2] = bus.read(pc + 2); buf[2] = bus.read(pc + 2);
@ -1560,10 +1595,10 @@ int millis_per_slice = 16;
struct key_to_ascii struct key_to_ascii
{ {
unsigned char no_shift_no_control; uint8_t no_shift_no_control;
unsigned char yes_shift_no_control; uint8_t yes_shift_no_control;
unsigned char no_shift_yes_control; uint8_t no_shift_yes_control;
unsigned char yes_shift_yes_control; uint8_t yes_shift_yes_control;
}; };
map<int, key_to_ascii> interface_key_to_apple2e = map<int, key_to_ascii> interface_key_to_apple2e =
@ -1635,7 +1670,7 @@ enum APPLE2Einterface::EventType process_events(MAINboard *board, bus_frontend&
diskIIboard->set_floppy(e.value, e.str); diskIIboard->set_floppy(e.value, e.str);
free(e.str); free(e.str);
} else if(e.type == APPLE2Einterface::PASTE) { } else if(e.type == APPLE2Einterface::PASTE) {
for(unsigned int i = 0; i < strlen(e.str); i++) for(uint32_t i = 0; i < strlen(e.str); i++)
if(e.str[i] == '\n') if(e.str[i] == '\n')
board->enqueue_key('\r'); board->enqueue_key('\r');
else else
@ -1734,12 +1769,12 @@ extern uint16_t pc;
template<class CLK, class BUS> template<class CLK, class BUS>
void print_cpu_state(const CPU6502<CLK, BUS>& cpu) void print_cpu_state(const CPU6502<CLK, BUS>& cpu)
{ {
unsigned char s0 = bus.read(0x100 + cpu.s + 0); uint8_t s0 = bus.read(0x100 + cpu.s + 0);
unsigned char s1 = bus.read(0x100 + cpu.s + 1); uint8_t s1 = bus.read(0x100 + cpu.s + 1);
unsigned char s2 = bus.read(0x100 + cpu.s + 2); uint8_t s2 = bus.read(0x100 + cpu.s + 2);
unsigned char pc0 = bus.read(cpu.pc + 0); uint8_t pc0 = bus.read(cpu.pc + 0);
unsigned char pc1 = bus.read(cpu.pc + 1); uint8_t pc1 = bus.read(cpu.pc + 1);
unsigned char pc2 = bus.read(cpu.pc + 2); uint8_t pc2 = bus.read(cpu.pc + 2);
printf("6502: A:%02X X:%02X Y:%02X P:", cpu.a, cpu.x, cpu.y); printf("6502: A:%02X X:%02X Y:%02X P:", cpu.a, cpu.x, cpu.y);
printf("%s", (cpu.p & cpu.N) ? "N" : "n"); printf("%s", (cpu.p & cpu.N) ? "N" : "n");
printf("%s", (cpu.p & cpu.V) ? "V" : "v"); printf("%s", (cpu.p & cpu.V) ? "V" : "v");
@ -1749,10 +1784,11 @@ void print_cpu_state(const CPU6502<CLK, BUS>& cpu)
printf("%s", (cpu.p & cpu.I) ? "I" : "i"); printf("%s", (cpu.p & cpu.I) ? "I" : "i");
printf("%s", (cpu.p & cpu.Z) ? "Z" : "z"); printf("%s", (cpu.p & cpu.Z) ? "Z" : "z");
printf("%s ", (cpu.p & cpu.C) ? "C" : "c"); printf("%s ", (cpu.p & cpu.C) ? "C" : "c");
printf("S:%02X (%02X %02X %02X ...) PC:%04X (%02X %02X %02X ...)\n", cpu.s, s0, s1, s2, cpu.pc, pc0, pc1, pc2); printf("S:%02X (%02X %02X %02X ...) ", cpu.s, s0, s1, s2);
printf("PC:%04X (%02X %02X %02X ...)\n", cpu.pc, pc0, pc1, pc2);
} }
template <class TYPE, unsigned int LENGTH> template <class TYPE, uint32_t LENGTH>
struct averaged_sequence struct averaged_sequence
{ {
int where; int where;
@ -1762,7 +1798,7 @@ struct averaged_sequence
averaged_sequence() : averaged_sequence() :
where(-1) where(-1)
{ {
for(unsigned int i = 0; i < LENGTH; i++) for(uint32_t i = 0; i < LENGTH; i++)
list[i] = 0; list[i] = 0;
sum = 0; sum = 0;
} }
@ -1770,7 +1806,7 @@ struct averaged_sequence
void add(TYPE value) void add(TYPE value)
{ {
if(where == -1) { if(where == -1) {
for(unsigned int i = 0; i < LENGTH; i++) for(uint32_t i = 0; i < LENGTH; i++)
list[i] = value; list[i] = value;
sum = value * LENGTH; sum = value * LENGTH;
where = 0; where = 0;
@ -1860,13 +1896,13 @@ int main(int argc, char **argv)
} }
const char *romname = argv[0]; const char *romname = argv[0];
unsigned char b[32768]; uint8_t b[32768];
if(!read_blob(romname, b, sizeof(b))) { if(!read_blob(romname, b, sizeof(b))) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
unsigned char diskII_rom[256]; uint8_t diskII_rom[256];
if(diskII_rom_name != NULL) { if(diskII_rom_name != NULL) {
if(!read_blob(diskII_rom_name, diskII_rom, sizeof(diskII_rom))) if(!read_blob(diskII_rom_name, diskII_rom, sizeof(diskII_rom)))
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -1879,15 +1915,15 @@ int main(int argc, char **argv)
MAINboard* mainboard; MAINboard* mainboard;
MAINboard::display_write_func display = [](int addr, bool aux, unsigned char data)->bool{return APPLE2Einterface::write(addr, aux, data);}; MAINboard::display_write_func display = [](uint16_t addr, bool aux, uint8_t data)->bool{return APPLE2Einterface::write(addr, aux, data);};
MAINboard::get_paddle_func paddle = [](int num)->tuple<float, bool>{return APPLE2Einterface::get_paddle(num);}; MAINboard::get_paddle_func paddle = [](int num)->tuple<float, bool>{return APPLE2Einterface::get_paddle(num);};
MAINboard::audio_flush_func audio; MAINboard::audio_flush_func audio;
if(mute) if(mute)
audio = [](char *buf, size_t sz){ }; audio = [](uint8_t *buf, size_t sz){ };
else else
audio = [](char *buf, size_t sz){ if(!run_fast) APPLE2Einterface::enqueue_audio_samples(buf, sz); }; audio = [](uint8_t *buf, size_t sz){ if(!run_fast) APPLE2Einterface::enqueue_audio_samples(buf, sz); };
mainboard = new MAINboard(clk, b, display, audio, paddle); mainboard = new MAINboard(clk, b, display, audio, paddle);
bus.board = mainboard; bus.board = mainboard;
@ -1977,6 +2013,9 @@ int main(int argc, char **argv)
if(debug & DEBUG_STATE) if(debug & DEBUG_STATE)
print_cpu_state(cpu); print_cpu_state(cpu);
} }
if(debug & DEBUG_CLOCK) {
printf("clock = %lu, %lu\n", (uint32_t)(clk / (1LLU << 32)), (uint32_t)(clk % (1LLU << 32)));
}
} }
mainboard->sync(); mainboard->sync();
@ -2029,7 +2068,7 @@ int main(int argc, char **argv)
exit_on_banking = true; exit_on_banking = true;
continue; continue;
} else if(strncmp(line, "debug", 5) == 0) { } else if(strncmp(line, "debug", 5) == 0) {
sscanf(line + 6, "%d", &debug); sscanf(line + 6, "%u", &debug);
printf("debug set to %02X\n", debug); printf("debug set to %02X\n", debug);
continue; continue;
} else if(strcmp(line, "reset") == 0) { } else if(strcmp(line, "reset") == 0) {

View File

@ -42,10 +42,10 @@ using namespace std;
namespace APPLE2Einterface namespace APPLE2Einterface
{ {
const int apple2_screen_width = 280; constexpr uint32_t apple2_screen_width = 280;
const int apple2_screen_height = 192; constexpr uint32_t apple2_screen_height = 192;
const int recording_scale = 2; constexpr int recording_scale = 2;
const int recording_frame_duration_hundredths = 5; constexpr uint32_t recording_frame_duration_hundredths = 5;
chrono::time_point<chrono::system_clock> start_time; chrono::time_point<chrono::system_clock> start_time;
@ -58,8 +58,8 @@ int joystick_axis1 = -1;
int joystick_button0 = -1; int joystick_button0 = -1;
int joystick_button1 = -1; int joystick_button1 = -1;
extern int font_offset; extern uint16_t font_offset;
extern const unsigned char font_bytes[96 * 7 * 8]; extern const uint8_t font_bytes[96 * 7 * 8];
static int gWindowWidth, gWindowHeight; static int gWindowWidth, gWindowHeight;
@ -96,14 +96,14 @@ event dequeue_event()
} }
opengl_texture font_texture; opengl_texture font_texture;
const int fonttexture_w = 7; constexpr uint32_t fonttexture_w = 7;
const int fonttexture_h = 8 * 96; constexpr uint32_t fonttexture_h = 8 * 96;
opengl_texture textport_texture[2][2]; // [aux][page] opengl_texture textport_texture[2][2]; // [aux][page]
GLuint text_program; GLuint text_program;
const int textport_w = 40; constexpr uint32_t textport_w = 40;
const int textport_h = 24; constexpr uint32_t textport_h = 24;
GLuint textport_texture_location; GLuint textport_texture_location;
GLuint textport_texture_coord_scale_location; GLuint textport_texture_coord_scale_location;
GLuint textport_blink_location; GLuint textport_blink_location;
@ -135,8 +135,8 @@ GLuint lores_x_offset_location;
GLuint lores_y_offset_location; GLuint lores_y_offset_location;
GLuint lores_to_screen_location; GLuint lores_to_screen_location;
const int hires_w = 320; // MSBit is color chooser, Apple ][ weirdness const uint32_t hires_w = 320; // MSBit is color chooser, Apple ][ weirdness
const int hires_h = 192; const uint32_t hires_h = 192;
opengl_texture hires_texture[2]; opengl_texture hires_texture[2];
GLuint hires_program; GLuint hires_program;
@ -170,7 +170,7 @@ tuple<float,bool> get_paddle(int num)
return make_tuple(paddle_values[num], paddle_buttons[num]); return make_tuple(paddle_values[num], paddle_buttons[num]);
} }
const int raster_coords_attrib = 0; const uint32_t raster_coords_attrib = 0;
static const char *hires_vertex_shader = R"( static const char *hires_vertex_shader = R"(
uniform mat3 to_screen; uniform mat3 to_screen;
@ -485,7 +485,7 @@ void set_image_shader(float to_screen[9], const opengl_texture& texture, float x
void initialize_screen_areas() void initialize_screen_areas()
{ {
for(int i = 0; i < apple2_screen_height; i++) { for(uint32_t i = 0; i < apple2_screen_height; i++) {
line_to_area[i].push_back({make_rectangle_array_buffer(0, i, apple2_screen_width, 1), raster_coords_attrib, 2, GL_FLOAT, GL_FALSE, 0}); line_to_area[i].push_back({make_rectangle_array_buffer(0, i, apple2_screen_width, 1), raster_coords_attrib, 2, GL_FLOAT, GL_FALSE, 0});
} }
} }
@ -632,7 +632,7 @@ struct apple2screen : public widget
h = h_; h = h_;
long long elapsed_millis = now * 1000; long long elapsed_millis = now * 1000;
for(int i = 0; i < apple2_screen_height; i++) { for(uint32_t i = 0; i < apple2_screen_height; i++) {
const ModeSettings& settings = line_to_mode[i]; const ModeSettings& settings = line_to_mode[i];
set_shader(to_screen, settings.mode, (i < 160) ? false : settings.mixed, settings.page, settings.vid80, (elapsed_millis / 300) % 2, x, y); set_shader(to_screen, settings.mode, (i < 160) ? false : settings.mixed, settings.page, settings.vid80, (elapsed_millis / 300) % 2, x, y);
@ -723,9 +723,9 @@ struct image_widget : public widget
{ {
opengl_texture image; opengl_texture image;
vertex_array rectangle; vertex_array rectangle;
int w, h; int32_t w, h;
image_widget(int w_, int h_, unsigned char *buffer) : image_widget(int32_t w_, int32_t h_, uint8_t *buffer) :
w(w_), w(w_),
h(h_) h(h_)
{ {
@ -760,7 +760,7 @@ struct text_widget : public widget
{ {
content = content_; content = content_;
// construct string texture // construct string texture
unique_ptr<unsigned char> bytes(new unsigned char[content.size() + 1]); unique_ptr<uint8_t> bytes(new uint8_t[content.size() + 1]);
int i = 0; int i = 0;
for(auto c : content) { for(auto c : content) {
if(c >= ' ' && c <= '?') if(c >= ' ' && c <= '?')
@ -1120,7 +1120,7 @@ void initialize_gl(void)
CheckOpenGL(__FILE__, __LINE__); CheckOpenGL(__FILE__, __LINE__);
} }
unsigned char disk_in_on_bitmap[] = { uint8_t disk_in_on_bitmap[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 40, 40 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 40, 40
255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 255, // 40, 40 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 255, // 40, 40
255, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, // 40, 40 255, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, // 40, 40
@ -1146,7 +1146,7 @@ unsigned char disk_in_on_bitmap[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 40, 40 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 40, 40
}; };
unsigned char disk_out_bitmap[] = { uint8_t disk_out_bitmap[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 40, 40 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 40, 40
255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 255, // 40, 40 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 255, // 40, 40
255, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, // 40, 40 255, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, // 40, 40
@ -1172,7 +1172,7 @@ unsigned char disk_out_bitmap[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 40, 40 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 40, 40
}; };
unsigned char disk_in_off_bitmap[] = { uint8_t disk_in_off_bitmap[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 40, 40 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 40, 40
255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 255, // 40, 40 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 255, // 40, 40
255, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, // 40, 40 255, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, // 40, 40
@ -1397,9 +1397,9 @@ tuple<float, float> window_to_widget(float x, float y)
return make_tuple(wx, wy); return make_tuple(wx, wy);
} }
void save_rgba_to_ppm(const unsigned char *rgba8_pixels, int width, int height, const char *filename) void save_rgba_to_ppm(const uint8_t *rgba8_pixels, uint32_t width, uint32_t height, const char *filename)
{ {
int row_bytes = width * 4; size_t row_bytes = width * 4;
FILE *fp = fopen(filename, "w"); FILE *fp = fopen(filename, "w");
fprintf(fp, "P6 %d %d 255\n", width, height); fprintf(fp, "P6 %d %d 255\n", width, height);
@ -1413,7 +1413,7 @@ void save_rgba_to_ppm(const unsigned char *rgba8_pixels, int width, int height,
void add_rendertarget_to_gif(double now, render_target *rt) void add_rendertarget_to_gif(double now, render_target *rt)
{ {
static unsigned char image_recorded[apple2_screen_width * recording_scale * apple2_screen_height * recording_scale * 4]; static uint8_t image_recorded[apple2_screen_width * recording_scale * apple2_screen_height * recording_scale * 4];
rt->start_rendering(); rt->start_rendering();
@ -1590,7 +1590,7 @@ static void scroll(GLFWwindow *window, double dx, double dy)
{ {
} }
const int pixel_scale = 3; constexpr uint32_t pixel_scale = 3;
void load_joystick_setup() void load_joystick_setup()
{ {
@ -1623,9 +1623,9 @@ void drop_callback(GLFWwindow* window, int count, const char** paths)
ui->drop(elapsed.count(), wx, wy, count, paths); ui->drop(elapsed.count(), wx, wy, count, paths);
} }
void enqueue_audio_samples(char *buf, size_t sz) void enqueue_audio_samples(uint8_t *buf, size_t sz)
{ {
ao_play(aodev, buf, sz); ao_play(aodev, (char*)buf, sz);
} }
ao_device *open_ao() ao_device *open_ao()
@ -1714,15 +1714,15 @@ void apply_writes(void);
// of frames worth of mode changes anyway. // of frames worth of mode changes anyway.
void map_mode_to_lines(const ModePoint& p, unsigned long long to_byte) void map_mode_to_lines(const ModePoint& p, unsigned long long to_byte)
{ {
unsigned int byte = get<0>(p); uint64_t byte = get<0>(p);
const ModeSettings& settings = get<1>(p); const ModeSettings& settings = get<1>(p);
int line = (byte + 17029) / 65; uint64_t line = (byte + 17029) / 65;
int to_line = (to_byte + 17029) / 65; uint64_t to_line = (to_byte + 17029) / 65;
for(int l = line; l < to_line; l++) { for(uint64_t l = line; l < to_line; l++) {
int line_in_frame = l % 262; uint64_t line_in_frame = l % 262;
if(0)printf("to_byte %llu, line %d : mode %s\n", to_byte, line_in_frame, (settings.mode == APPLE2Einterface::TEXT) ? "TEXT" : ((settings.mode == APPLE2Einterface::LORES) ? "LORES" : "HIRES")); if(0)printf("to_byte %llu, line %llu: mode %s\n", to_byte, line_in_frame, (settings.mode == APPLE2Einterface::TEXT) ? "TEXT" : ((settings.mode == APPLE2Einterface::LORES) ? "LORES" : "HIRES"));
if(line_in_frame < 192) if(line_in_frame < 192)
line_to_mode[line_in_frame] = settings; line_to_mode[line_in_frame] = settings;
} }
@ -1741,7 +1741,7 @@ void map_history_to_lines(const ModeHistory& history, unsigned long long current
auto& current = history[i]; auto& current = history[i];
auto& next = history[i + 1]; auto& next = history[i + 1];
unsigned int byte2 = get<0>(next); uint64_t byte2 = get<0>(next);
map_mode_to_lines(current, byte2); map_mode_to_lines(current, byte2);
} }
@ -1799,7 +1799,7 @@ void iterate(const ModeHistory& history, unsigned long long current_byte, float
int axis_count, button_count; int axis_count, button_count;
const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &axis_count); const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &axis_count);
const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &button_count); const uint8_t* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &button_count);
{ {
static bool checkedJoystickProbing = false; static bool checkedJoystickProbing = false;
@ -1863,30 +1863,30 @@ void shutdown()
glfwTerminate(); glfwTerminate();
} }
static const int text_page1_base = 0x400; constexpr uint16_t text_page1_base = 0x400;
static const int text_page2_base = 0x800; constexpr uint16_t text_page2_base = 0x800;
static const int text_page_size = 0x400; constexpr uint16_t text_page_size = 0x400;
static const int hires_page1_base = 0x2000; constexpr uint16_t hires_page1_base = 0x2000;
static const int hires_page2_base = 0x4000; constexpr uint16_t hires_page2_base = 0x4000;
static const int hires_page_size = 8192; constexpr uint16_t hires_page_size = 8192;
extern int text_row_base_offsets[24]; extern uint16_t text_row_base_offsets[24];
extern int hires_memory_to_scanout_address[8192]; extern uint16_t hires_memory_to_scanout_address[8192];
typedef pair<int, bool> address_auxpage; typedef pair<uint16_t, bool> address_auxpage;
map< address_auxpage, unsigned char> writes; map<address_auxpage, uint8_t> writes;
int collisions = 0; int collisions = 0;
void write2(int addr, bool aux, unsigned char data) void write2(uint16_t addr, bool aux, uint8_t data)
{ {
// We know text page 1 and 2 are contiguous // We know text page 1 and 2 are contiguous
if((addr >= text_page1_base) && (addr < text_page2_base + text_page_size)) { if((addr >= text_page1_base) && (addr < text_page2_base + text_page_size)) {
int page = (addr >= text_page2_base) ? 1 : 0; uint16_t page = (addr >= text_page2_base) ? 1 : 0;
int within_page = addr - text_page1_base - page * text_page_size; uint16_t within_page = addr - text_page1_base - page * text_page_size;
for(int row = 0; row < 24; row++) { for(int row = 0; row < 24; row++) {
int row_offset = text_row_base_offsets[row]; uint16_t row_offset = text_row_base_offsets[row];
if((within_page >= row_offset) && (within_page < row_offset + 40)) { if((within_page >= row_offset) && (within_page < row_offset + 40)) {
int col = within_page - row_offset; uint16_t col = within_page - row_offset;
glBindTexture(GL_TEXTURE_2D, textport_texture[aux ? 1 : 0][page]); glBindTexture(GL_TEXTURE_2D, textport_texture[aux ? 1 : 0][page]);
glTexSubImage2D(GL_TEXTURE_2D, 0, col, row, 1, 1, GL_RED, GL_UNSIGNED_BYTE, &data); glTexSubImage2D(GL_TEXTURE_2D, 0, col, row, 1, 1, GL_RED, GL_UNSIGNED_BYTE, &data);
CheckOpenGL(__FILE__, __LINE__); CheckOpenGL(__FILE__, __LINE__);
@ -1895,15 +1895,15 @@ void write2(int addr, bool aux, unsigned char data)
} else if(((addr >= hires_page1_base) && (addr < hires_page1_base + hires_page_size)) || ((addr >= hires_page2_base) && (addr < hires_page2_base + hires_page_size))) { } else if(((addr >= hires_page1_base) && (addr < hires_page1_base + hires_page_size)) || ((addr >= hires_page2_base) && (addr < hires_page2_base + hires_page_size))) {
int page = (addr < hires_page2_base) ? 0 : 1; uint16_t page = (addr < hires_page2_base) ? 0 : 1;
int page_base = (page == 0) ? hires_page1_base : hires_page2_base; uint16_t page_base = (page == 0) ? hires_page1_base : hires_page2_base;
int within_page = addr - page_base; uint16_t within_page = addr - page_base;
int scanout_address = hires_memory_to_scanout_address[within_page]; uint16_t scanout_address = hires_memory_to_scanout_address[within_page];
int row = scanout_address / 40; uint16_t row = scanout_address / 40;
int col = scanout_address % 40; uint16_t col = scanout_address % 40;
glBindTexture(GL_TEXTURE_2D, hires_texture[page]); glBindTexture(GL_TEXTURE_2D, hires_texture[page]);
if(page == 0) hgr_page1[addr - 0x2000] = data; // XXX hack if(page == 0) hgr_page1[addr - 0x2000] = data; // XXX hack
unsigned char pixels[8]; uint8_t pixels[8];
for(int i = 0; i < 8 ; i++) for(int i = 0; i < 8 ; i++)
pixels[i] = ((data & (1 << i)) ? 255 : 0); pixels[i] = ((data & (1 << i)) ? 255 : 0);
glTexSubImage2D(GL_TEXTURE_2D, 0, col * 8, row, 8, 1, GL_RED, GL_UNSIGNED_BYTE, pixels); glTexSubImage2D(GL_TEXTURE_2D, 0, col * 8, row, 8, 1, GL_RED, GL_UNSIGNED_BYTE, pixels);
@ -1914,7 +1914,7 @@ void write2(int addr, bool aux, unsigned char data)
void apply_writes(void) void apply_writes(void)
{ {
for(auto it : writes) { for(auto it : writes) {
int addr; uint16_t addr;
bool aux; bool aux;
tie(addr, aux) = it.first; tie(addr, aux) = it.first;
write2(addr, aux, it.second); write2(addr, aux, it.second);
@ -1923,7 +1923,7 @@ void apply_writes(void)
collisions = 0; collisions = 0;
} }
bool write(int addr, bool aux, unsigned char data) bool write(uint16_t addr, bool aux, uint8_t data)
{ {
// We know text page 1 and 2 are contiguous // We know text page 1 and 2 are contiguous
if((addr >= text_page1_base) && (addr < text_page2_base + text_page_size)) { if((addr >= text_page1_base) && (addr < text_page2_base + text_page_size)) {
@ -1943,7 +1943,7 @@ bool write(int addr, bool aux, unsigned char data)
return false; return false;
} }
int text_row_base_offsets[24] = uint16_t text_row_base_offsets[24] =
{ {
0x000, 0x000,
0x080, 0x080,
@ -1971,7 +1971,7 @@ int text_row_base_offsets[24] =
0x3D0, 0x3D0,
}; };
static int hires_row_base_offsets[192] = static uint16_t hires_row_base_offsets[192] =
{ {
0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00,
0x0080, 0x0480, 0x0880, 0x0C80, 0x1080, 0x1480, 0x1880, 0x1C80, 0x0080, 0x0480, 0x0880, 0x0C80, 0x1080, 0x1480, 0x1880, 0x1C80,
@ -1999,21 +1999,21 @@ static int hires_row_base_offsets[192] =
0x03D0, 0x07D0, 0x0BD0, 0x0FD0, 0x13D0, 0x17D0, 0x1BD0, 0x1FD0, 0x03D0, 0x07D0, 0x0BD0, 0x0FD0, 0x13D0, 0x17D0, 0x1BD0, 0x1FD0,
}; };
int hires_memory_to_scanout_address[8192]; uint16_t hires_memory_to_scanout_address[8192];
static void initialize_memory_to_scanout() __attribute__((constructor)); static void initialize_memory_to_scanout() __attribute__((constructor));
void initialize_memory_to_scanout() void initialize_memory_to_scanout()
{ {
for(int row = 0; row < 192; row++) { for(uint16_t row = 0; row < 192; row++) {
int row_address = hires_row_base_offsets[row]; uint16_t row_address = hires_row_base_offsets[row];
for(int byte = 0; byte < 40; byte++) { for(uint16_t byte = 0; byte < 40; byte++) {
hires_memory_to_scanout_address[row_address + byte] = row * 40 + byte; hires_memory_to_scanout_address[row_address + byte] = row * 40 + byte;
} }
} }
} }
int font_offset = 32; uint16_t font_offset = 32;
const unsigned char font_bytes[96 * 7 * 8] = { const uint8_t font_bytes[96 * 7 * 8] = {
// 32 : // 32 :
0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,

View File

@ -83,16 +83,16 @@ struct ModeSettings
} }
}; };
typedef std::tuple<unsigned long long, ModeSettings> ModePoint; typedef std::tuple<uint64_t, ModeSettings> ModePoint;
typedef std::vector<ModePoint> ModeHistory; typedef std::vector<ModePoint> ModeHistory;
bool write(int addr, bool aux, unsigned char data); bool write(uint16_t addr, bool aux, uint8_t data);
std::tuple<float,bool> get_paddle(int num); std::tuple<float,bool> get_paddle(int num);
void show_floppy_activity(int number, bool activity); void show_floppy_activity(int number, bool activity);
void enqueue_audio_samples(char *buf, size_t sz); void enqueue_audio_samples(uint8_t *buf, size_t sz);
void start(bool run_fast, bool add_floppies, bool floppy0_inserted, bool floppy1_inserted); void start(bool run_fast, bool add_floppies, bool floppy0_inserted, bool floppy1_inserted);
void iterate(const ModeHistory& history, unsigned long long current_byte_in_frame, float megahertz); // display void iterate(const ModeHistory& history, unsigned long long current_byte_in_frame, float megahertz); // display