1
0
mirror of https://github.com/pevans/erc-c.git synced 2024-08-21 00:29:00 +00:00

Documentation, lacking

This commit is contained in:
Peter Evans 2017-12-06 21:25:47 -06:00
parent ccd7a3f665
commit 8cd9c5ffab
4 changed files with 86 additions and 4 deletions

View File

@ -9,6 +9,10 @@ extern void log_write(int, const char *, ...);
extern void log_close();
extern void log_open(FILE *);
/*
* Here we have a couple of convenience macros that abstracts the log
* level number.
*/
#define log_critical(...) log_write(0, __VA_ARGS__)
#define log_error(...) log_write(0, __VA_ARGS__)

View File

@ -1,6 +1,3 @@
#ifndef _MOS6502_ENUMS_H_
#define _MOS6502_ENUMS_H_
/*
* mos6502.enums.h
* Enums and other symbols for use with the mos 6502
@ -11,6 +8,14 @@
* adding them to the global namespace throughout the application.
*/
#ifndef _MOS6502_ENUMS_H_
#define _MOS6502_ENUMS_H_
/*
* This defines all of the flags that are possible within the status (P)
* register. Note that there is intentionally _no_ definition for the
* 6th bit.
*/
enum status_flags {
CARRY = 1,
ZERO = 2,
@ -21,6 +26,12 @@ enum status_flags {
NEGATIVE = 128,
};
/*
* Here we define the various address modes that are possible. These do
* not map to any significant numbers that are documented for the 6502
* processor; the position of these symbols don't really matter, and are
* generally (except for `NOA`, no address mode) in alphabetical order.
*/
enum addr_mode {
NOA, // no address mode
ACC, // accumulator
@ -38,6 +49,12 @@ enum addr_mode {
ZPY, // zero page y-index
};
/*
* These define the various instructions as enum symbols; again, like
* for address modes, the values of these enums are not actually
* significant to the 6502 processor, and are only useful to we, the
* programmers.
*/
enum instruction {
ADC, // ADd with Carry
AND, // bitwise AND

View File

@ -29,6 +29,13 @@
// All of our address modes, instructions, etc. are defined here.
#include "mos6502.enums.h"
/*
* This is a table which defines what instruction each opcode is mapped
* to. All possible (256) values are defined here. You will note many
* cases where we use NOP where opcodes are not _technically_ defined;
* this may or may not be the best behavior. It's quite possible we should
* instead crash the program when we stumble upon such malformed opcodes
*/
static int instructions[] = {
// 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
BRK, ORA, NOP, NOP, NOP, ORA, ASL, NOP, PHP, ORA, ASL, NOP, NOP, ORA, ASL, NOP, // 0x
@ -49,10 +56,17 @@ static int instructions[] = {
BEQ, SBC, NOP, NOP, NOP, SBC, INC, NOP, SED, SBC, NOP, NOP, NOP, SBC, INC, NOP, // Fx
};
// I just don't want to type out the literal function name every time
/*
* A small convenience for defining instruction handlers below.
*/
#define INST_HANDLER(x) \
mos6502_handle_##x
/*
* Here's another table, this time mapping instruction codes to
* instruction handler functions. They are listed in the order defined
* in the instruction enum (in mos6502.enums.h).
*/
static mos6502_instruction_handler instruction_handlers[] = {
INST_HANDLER(adc),
INST_HANDLER(and),
@ -112,6 +126,11 @@ static mos6502_instruction_handler instruction_handlers[] = {
INST_HANDLER(tya),
};
/*
* Here we have a table that maps opcodes to the number of cycles each
* should cost. In cases where no opcode is defined, we set the number
* of cycles to zero.
*/
static int cycles[] = {
// 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
7, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 0, 4, 6, 0, // 0x
@ -185,6 +204,15 @@ mos6502_next_byte(mos6502 *cpu)
return byte;
}
/*
* Push a _16-bit_ number to the stack. Generally speaking, only
* addresses are pushed to the stack, such that would be contained in
* the PC register (which is 16-bit).
*
* The stack is contained within a single page of memory, so you would
* be right in observing that the stack can contain at most 128, not
* 256, addresses.
*/
void
mos6502_push_stack(mos6502 *cpu, vm_16bit addr)
{
@ -201,6 +229,9 @@ mos6502_push_stack(mos6502 *cpu, vm_16bit addr)
cpu->S += 2;
}
/*
* Pop an address from the stack and return that.
*/
vm_16bit
mos6502_pop_stack(mos6502 *cpu)
{
@ -216,12 +247,21 @@ mos6502_pop_stack(mos6502 *cpu)
vm_segment_get(cpu->memory, 0x0100 + cpu->S + 1);
}
/*
* Here we set the status register to a given status value, regardless
* of its past contents.
*/
void
mos6502_set_status(mos6502 *cpu, vm_8bit status)
{
cpu->P = status;
}
/*
* In contrast, the modify_status function will conditionally set the
* contents of certain bits, based upon the value of the operand. Those
* bits are the negative, overflow, carry, and zero flags.
*/
void
mos6502_modify_status(mos6502 *cpu, vm_8bit status, vm_8bit oper)
{
@ -254,12 +294,20 @@ mos6502_modify_status(mos6502 *cpu, vm_8bit status, vm_8bit oper)
}
}
/*
* Return the instruction that is mapped to a given opcode.
*/
int
mos6502_instruction(vm_8bit opcode)
{
return instructions[opcode];
}
/*
* Return the number of cycles an opcode may consume. The cpu is a
* required parameter, because the number of opcodes is conditional upon
* the effective address of the instruction we're executing.
*/
int
mos6502_cycles(mos6502 *cpu, vm_8bit opcode)
{

View File

@ -3,6 +3,9 @@
#include "log.h"
#include "vm_screen.h"
/*
* Return a new screen context. We also set the color to black.
*/
vm_screen_context *
vm_screen_new_context()
{
@ -18,12 +21,18 @@ vm_screen_new_context()
return context;
}
/*
* Free the contents of a screen context.
*/
void
vm_screen_free_context(vm_screen_context *context)
{
free(context);
}
/*
* Set the color of a screen context to a given RGBA value.
*/
void
vm_screen_set_color(vm_screen_context *context,
int red,
@ -37,6 +46,10 @@ vm_screen_set_color(vm_screen_context *context,
context->color_alpha = alpha;
}
/*
* Draw a rectangle on the screen at a given x/y position, with a given
* set of x/y dimensions, with a given screen context.
*/
void
vm_screen_draw_rect(vm_screen_context *context,
int xpos,