Skip to content

Instantly share code, notes, and snippets.

@cust0m
Last active May 16, 2019 23:15
Show Gist options
  • Save cust0m/5da509c2d9cd0fbdf80b3056d795633b to your computer and use it in GitHub Desktop.
Save cust0m/5da509c2d9cd0fbdf80b3056d795633b to your computer and use it in GitHub Desktop.
#include <SDL.h>
#include <stdio.h>
#include <time.h>
// Screen dimension constants
const int SCREEN_WIDTH = 160;
const int SCREEN_HEIGHT = 160;
// Registers
uint16_t pc;
uint16_t sp;
uint16_t a;
uint16_t x;
uint16_t y;
uint16_t p;
// Memory
uint8_t* memory;
// Break Flag
int break_flag = 0;
// Instruction Functions
void brk();
void lda_imm();
void lda_zer();
void sta_zer();
void sta_abs();
void sta_iny();
void and_imm();
void adc_imm();
void jmp();
// Renderer of screen
SDL_Renderer *renderer;
// Instruction Table
void (*instructions[256])();
// Populate Instruction Table
void init_ins_table(){
for(int i = 0; i < 256; i++) {
instructions[i] = &brk;
}
instructions[0xA9] = &lda_imm;
instructions[0xA5] = &lda_zer;
instructions[0x85] = &sta_zer;
instructions[0x8D] = &sta_abs;
instructions[0x91] = &sta_iny;
instructions[0x29] = &and_imm;
instructions[0x69] = &adc_imm;
instructions[0x4c] = &jmp;
}
// Read from memmory
uint8_t read_mem(uint16_t address) {
if(address==0xfe){
uint8_t rand_return = (uint8_t) rand();
return rand_return;
}
return memory[address];
}
// Write in memory
void write_mem(uint16_t address, uint8_t value) {
memory[address] = value;
}
void reset_cpu(){
memory = malloc(65536);
memset(memory, 0, 65536);
// Initialize regiters
a = 0;
pc = 0x0600;
// Initialize program
/* memcpy(memory+0x0600, "\xA9\x01\x8d\x00\x02\xA9\x05\x8d\x01\x02\xA9\x08\x8d\x02\x02", 19); */
memcpy(memory+0x0600, "\xa5\xfe\x85\x00\xa5\xfe\x29\x03\x69\x02\x85\x01\xa5\xfe\x91\x00\x4c\x00\x06", 19);
/* memcpy(memory+pc, "\xa5\xfe\x85\x01\x91\x01\x4c\x00\x06", 0); */
}
// Instructions implementations
void brk(){
break_flag = 1;
}
void lda_imm(){
a = read_mem(++pc);
pc++;
}
void lda_zer(){
uint8_t mem_address = read_mem(++pc);
a = read_mem(mem_address);
pc++;
}
void sta_zer(){
write_mem(read_mem(++pc),a);
pc++;
}
void sta_abs(){
uint8_t low_address = read_mem(++pc);
uint8_t high_address = read_mem(++pc);
uint16_t mem_address = low_address + (high_address << 8);
write_mem(mem_address,a);
pc++;
}
void sta_iny(){
uint16_t base_address = read_mem(++pc);
uint16_t low_address = read_mem(base_address);
uint16_t high_address = read_mem(base_address + 1);
uint16_t mem_address = (low_address + (high_address << 8)) + y;
write_mem(mem_address,a);
pc++;
}
void and_imm(){
a = a & read_mem(++pc);
pc++;
}
void adc_imm(){
uint8_t m = read_mem(++pc);
a = a + m;
pc++;
}
void jmp(){
uint8_t low_address = read_mem(++pc);
uint8_t high_address = read_mem(++pc);
uint16_t mem_address = low_address + (high_address << 8);
pc = mem_address;
}
void set_renderer_color(uint8_t color){
color = color & 0x0F;
switch(color) {
case 0x0: SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
break;
case 0x1: SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
break;
case 0x2: SDL_SetRenderDrawColor(renderer, 136, 0, 255, 255);
break;
case 0x3: SDL_SetRenderDrawColor(renderer, 170, 255, 238, 255);
break;
case 0x4: SDL_SetRenderDrawColor(renderer, 204, 68, 204, 255);
break;
case 0x5: SDL_SetRenderDrawColor(renderer, 0, 204, 85, 255);
break;
case 0x6: SDL_SetRenderDrawColor(renderer, 0, 0, 170, 255);
break;
case 0x7: SDL_SetRenderDrawColor(renderer, 238, 238, 119, 255);
break;
case 0x8: SDL_SetRenderDrawColor(renderer, 221, 136, 85, 255);
break;
case 0x9: SDL_SetRenderDrawColor(renderer, 102, 68, 0, 255);
break;
case 0xa: SDL_SetRenderDrawColor(renderer, 255, 119, 199, 255);
break;
case 0xb: SDL_SetRenderDrawColor(renderer, 51, 51, 51, 255);
break;
case 0xc: SDL_SetRenderDrawColor(renderer, 119, 199, 119, 255);
break;
case 0xd: SDL_SetRenderDrawColor(renderer, 170, 255, 102, 255);
break;
case 0xe: SDL_SetRenderDrawColor(renderer, 0, 136, 255, 255);
break;
case 0xf: SDL_SetRenderDrawColor(renderer, 187, 187, 187, 255);
break;
}
}
void render_screen(){
for(uint16_t i = 0x200; i <= 0x5ff;i++){
uint16_t screen_pos = (i-512);
uint16_t line = (uint16_t)screen_pos/32;
uint16_t column = (uint16_t)(screen_pos-(line*32));
set_renderer_color(memory[i]);
SDL_RenderDrawPoint(renderer, column, line);
}
SDL_RenderPresent(renderer);
}
void run_cpu(){
SDL_Event event;
break_flag = 0;
/* for(;;){ */
while (1) {
/* SDL_RenderClear(renderer); */
if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
break;
/* printf("A: %04x \n", a); */
/* printf("PC: %04x \n", pc); */
if(break_flag==1)
break;
(*instructions[read_mem(pc)])();
render_screen();
}
}
int main( int argc, char* args[] )
{
srand(time(NULL));
SDL_Event event;
SDL_Window *window;
init_ins_table();
reset_cpu();
SDL_Init(SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, 0, &window, &renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
SDL_RenderSetScale(renderer, 5, 5);
/* render_screen(); */
run_cpu();
/* SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255); */
/* SDL_RenderDrawPoint(renderer, 0, 0); */
SDL_RenderPresent(renderer);
/* SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); */
/* SDL_RenderDrawPoint(renderer, 1, 0); */
while (1) {
if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
break;
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment