Spelling, bugs, cleanup

This commit is contained in:
Stefan Wessels 2024-09-10 01:24:48 -07:00
parent 87c1b242c2
commit 93368af8f5
3 changed files with 38 additions and 47 deletions

View File

@ -10,7 +10,7 @@ My speaker code is beyond terrible, but I'll maybe figure that out later. Turn
| --- | --- | --- | ---
| 6502.c | The 6502 Machine | 6502.c | The 6502 Machine
| mminer.c | The 6502 Manic Miner compiled code | mminer.c | The 6502 Manic Miner compiled code
| mmm.c | The Apple II emulator (all 403 lines of it ;) | mmm.c | The Apple II emulator (around 400 lines :)
# Building the code # Building the code
The CMakeLists.txt file works for my installation. This is my note at the top which sums up my feelings and frustrations. The CMakeLists.txt file works for my installation. This is my note at the top which sums up my feelings and frustrations.

View File

@ -11,7 +11,7 @@ struct MEMORY_REGION {
uint8_t *memory; uint8_t *memory;
}; };
/* RAM_BANK is */ /* RAM contains an array of MEMORY_REGIONS which may (or not) be mapped into the 6502's 64K*/
typedef struct MEMORY_REGION RAM_BANK; typedef struct MEMORY_REGION RAM_BANK;
struct RAM { struct RAM {
RAM_BANK *ram_banks; RAM_BANK *ram_banks;
@ -119,10 +119,6 @@ void rom_add(ROMS *roms, uint8_t rom_num, uint32_t address, uint32_t length,
uint8_t pages_init(PAGES *pages, uint16_t num_pages); uint8_t pages_init(PAGES *pages, uint16_t num_pages);
void pages_map(PAGES *pages, uint32_t start_page, uint32_t num_pages, uint8_t *memory); void pages_map(PAGES *pages, uint32_t start_page, uint32_t num_pages, uint8_t *memory);
// Exposed so that HARTE tests can be loaded and checked
uint8_t read_from_memory(MACHINE *m, uint16_t address);
void write_to_memory(MACHINE *m, uint16_t address, uint8_t value);
// 1 time init // 1 time init
void cpu_init(CPU *cpu); void cpu_init(CPU *cpu);

View File

@ -22,7 +22,8 @@ uint8_t RAM_IO[RAM_SIZE]; // 64K of IO port "mask" (0 =
#define LOWSCR 0xC054 // Port that draw Hires from $2000 #define LOWSCR 0xC054 // Port that draw Hires from $2000
#define HISCR 0xC055 // Port that draws Hires from $4000 #define HISCR 0xC055 // Port that draws Hires from $4000
// The start of a line of pixels (192 rows). (Add to active Hires page ie $2000 or $4000) // The start of a line of pixels (192 rows) in HGR memory.
// (Add to active Hires page ie $2000 or $4000)
uint16_t row_start[] = { uint16_t row_start[] = {
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,
@ -74,14 +75,13 @@ SDL_Renderer *renderer;
SDL_Surface *surface; SDL_Surface *surface;
SDL_Texture *texture; SDL_Texture *texture;
int screen_updated = TARGET_FPS; // Counter - at TARGET_FPS forces screen update int screen_updated = TARGET_FPS; // Counter - at TARGET_FPS forces screen update
int active_page = 0x2000; // 0x2000 or 0x4000 - active hires memory page int active_page = 0x4000; // 0x2000 or 0x4000 - active hires memory page
// Global variables to emulate speaker clicks // Global variables to emulate speaker clicks
#define AMPLITUDE 28000
#define SAMPLE_RATE 44100 #define SAMPLE_RATE 44100
int audio_paused = 0; // Audio is paused (0) or playing (1) int audio_paused = 1; // Audio is paused (1) or playing (0)
int speaker_state = 0; // Tracks whether the speaker is in the "on" or "off" state int speaker_state = 0; // Tracks whether the speaker is in the "on" or "off" state
double frequency = 440.0; // Frequency in Hz (dynamically calculated ) double frequency = 440.0; // Frequency in Hz (dynamically calculated)
Uint64 last_toggle_time = 0; // Last time the speaker was toggled (in performance counter ticks) Uint64 last_toggle_time = 0; // Last time the speaker was toggled (in performance counter ticks)
Uint64 frequency_ticks = 0; // Frequency of the performance counter Uint64 frequency_ticks = 0; // Frequency of the performance counter
@ -146,44 +146,39 @@ void show_screen(uint16_t page) {
// Loop through each row // Loop through each row
for (y = 0; y < 192; y++) { for (y = 0; y < 192; y++) {
uint32_t *p = &pixels[y * surface->w]; // Get the pointer to the start of the row in the SDL surface // Get the pointer to the start of the row in the SDL surface
int address = page + row_start[y]; uint32_t *p = &pixels[y * surface->w];
// An index to "walk" the pixels in the surface
int px = 0; int px = 0;
// Get the address where this row starts in HGR memory
int address = page + row_start[y];
// Loop through every 2 bytes (40 iterations for each 192-pixel row) // Loop through every 2 bytes (40 iterations for each 280-pixel row - 140 color pixels)
for (int x = 0; x < 40; x += 2) { for (int x = 0; x < 40; x += 2) {
uint16_t col = (RAM_MAIN[address + x + 1] << 8) | RAM_MAIN[address + x]; // Combine two bytes into a 16-bit value // Combine two bytes into a 16-bit value for ease of extracting pixels
uint16_t col = (RAM_MAIN[address + x + 1] << 8) | RAM_MAIN[address + x];
// Extract pixels and high bits // Extract the phase bits
int p1 = (col & 0b0000000000000001) << 1 | (col & 0b0000000000000010) >> 1;
int p2 = (col & 0b0000000000000100) >> 1 | (col & 0b0000000000001000) >> 3;
int p3 = (col & 0b0000000000010000) >> 3 | (col & 0b0000000000100000) >> 5;
int p4 = (col & 0b0000000001000000) >> 5 | (col & 0b0000000100000000) >> 8;
int p5 = (col & 0b0000001000000000) >> 8 | (col & 0b0000010000000000) >> 10;
int p6 = (col & 0b0000100000000000) >> 10 | (col & 0b0001000000000000) >> 12;
int p7 = (col & 0b0010000000000000) >> 12 | (col & 0b0100000000000000) >> 14;
// High bits for color adjustment
int ph1 = (col & 0b0000000010000000) >> 5; int ph1 = (col & 0b0000000010000000) >> 5;
int ph2 = (col & 0b1000000000000000) >> 13; int ph2 = (col & 0b1000000000000000) >> 13;
// Precompute color indices for each pixel // Extract pixels and offset for phase bits
int idx1 = p1 + ph1; int p1 = ph1 + ((col & 0b0000000000000001) << 1 | (col & 0b0000000000000010) >> 1 );
int idx2 = p2 + ph1; int p2 = ph1 + ((col & 0b0000000000000100) >> 1 | (col & 0b0000000000001000) >> 3 );
int idx3 = p3 + ph1; int p3 = ph1 + ((col & 0b0000000000010000) >> 3 | (col & 0b0000000000100000) >> 5 );
int idx4 = p4 + ph1; int p4 = ph1 + ((col & 0b0000000001000000) >> 5 | (col & 0b0000000100000000) >> 8 );
int idx5 = p5 + ph2; int p5 = ph2 + ((col & 0b0000001000000000) >> 8 | (col & 0b0000010000000000) >> 10);
int idx6 = p6 + ph2; int p6 = ph2 + ((col & 0b0000100000000000) >> 10 | (col & 0b0001000000000000) >> 12);
int idx7 = p7 + ph2; int p7 = ph2 + ((col & 0b0010000000000000) >> 12 | (col & 0b0100000000000000) >> 14);
// Access the surface's pixels and set the pixel value from the palette // Set the pixel value from the palette
p[px++] = SDL_MapRGB(surface->format, palette[idx1].c[0], palette[idx1].c[1], palette[idx1].c[2]); p[px++] = SDL_MapRGB(surface->format, palette[p1].c[0], palette[p1].c[1], palette[p1].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[idx2].c[0], palette[idx2].c[1], palette[idx2].c[2]); p[px++] = SDL_MapRGB(surface->format, palette[p2].c[0], palette[p2].c[1], palette[p2].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[idx3].c[0], palette[idx3].c[1], palette[idx3].c[2]); p[px++] = SDL_MapRGB(surface->format, palette[p3].c[0], palette[p3].c[1], palette[p3].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[idx4].c[0], palette[idx4].c[1], palette[idx4].c[2]); p[px++] = SDL_MapRGB(surface->format, palette[p4].c[0], palette[p4].c[1], palette[p4].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[idx5].c[0], palette[idx5].c[1], palette[idx5].c[2]); p[px++] = SDL_MapRGB(surface->format, palette[p5].c[0], palette[p5].c[1], palette[p5].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[idx6].c[0], palette[idx6].c[1], palette[idx6].c[2]); p[px++] = SDL_MapRGB(surface->format, palette[p6].c[0], palette[p6].c[1], palette[p6].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[idx7].c[0], palette[idx7].c[1], palette[idx7].c[2]); p[px++] = SDL_MapRGB(surface->format, palette[p7].c[0], palette[p7].c[1], palette[p7].c[2]);
} }
} }
@ -196,7 +191,7 @@ void show_screen(uint16_t page) {
screen_updated = 0; screen_updated = 0;
} }
// Note the actual program counter and value read from RAM on a read // Handle the Apple II ports used by Manic Miner
uint8_t io_read_callback(MACHINE *m, uint16_t address) { uint8_t io_read_callback(MACHINE *m, uint16_t address) {
switch(address) { switch(address) {
case KBDSTRB: case KBDSTRB:
@ -217,7 +212,7 @@ uint8_t io_read_callback(MACHINE *m, uint16_t address) {
return m->read_pages.pages[address / PAGE_SIZE].memory[address % PAGE_SIZE]; return m->read_pages.pages[address / PAGE_SIZE].memory[address % PAGE_SIZE];
} }
// Note the actual program counter and value written to RAM on a write // Writing to these ports is the same as reading from them
void io_write_callback(MACHINE *m, uint16_t address, uint8_t value) { void io_write_callback(MACHINE *m, uint16_t address, uint8_t value) {
io_read_callback(m, address); io_read_callback(m, address);
} }
@ -275,7 +270,7 @@ int AppleII_configure(MACHINE *m) {
} }
// Set up SDL graphics and Audio // Set up SDL graphics and Audio
int initSDL() { int init_sdl() {
// Initialize SDL with video and audio // Initialize SDL with video and audio
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0) {
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
@ -308,7 +303,7 @@ int initSDL() {
return 0; return 0;
} }
// Now the Audio // Now init the Audio
SDL_AudioSpec wanted_spec; SDL_AudioSpec wanted_spec;
SDL_AudioSpec obtained_spec; SDL_AudioSpec obtained_spec;
@ -341,7 +336,7 @@ int main(int argc, char* argv[]) {
Uint64 start_time, end_time; Uint64 start_time, end_time;
Uint64 ticks_per_clock_cycl = frequency_ticks / CPU_FREQUENCY; // Ticks per microsecond Uint64 ticks_per_clock_cycl = frequency_ticks / CPU_FREQUENCY; // Ticks per microsecond
if(!initSDL()) { if(!init_sdl()) {
return 1; return 1;
} }
@ -381,7 +376,7 @@ int main(int argc, char* argv[]) {
// When the speaker is not being toggled, it needs to turn off // When the speaker is not being toggled, it needs to turn off
end_time = SDL_GetPerformanceCounter(); end_time = SDL_GetPerformanceCounter();
if(audio_paused && end_time - last_toggle_time > (frequency_ticks / 8)) { if(!audio_paused && end_time - last_toggle_time > (frequency_ticks / 8)) {
audio_paused = 1; audio_paused = 1;
SDL_PauseAudio(1); SDL_PauseAudio(1);
end_time = SDL_GetPerformanceCounter(); end_time = SDL_GetPerformanceCounter();