simulator

Building your first 6502-based project? We'll help you get started here.
SamCoVT
Posts: 344
Joined: 13 May 2018

Re: simulator

Post by SamCoVT »

Nora23169,
Simulators are quite complicated, but also quite rewarding once you get them working. Start simple, with just a few opcodes working, and then add the remaining opcodes a few at a time. You'll also need a way to test that your simulation is working properly, so you will want to write some test programs that only use the instructions your simulator knows at that point. Fortunately, the 6502 has a reasonable number of instructions, so it's very possible to get this working if you keep at it. I'm sure you'll learn a lot along the way.
BigDumbDinosaur wrote:
BTW, what do GitHub users do when they are in the middle of a programming project, need to check out a file for editing and their Internet service goes on the fritz?
You use the local copy in your local repository. Git is a bit different from SVN in that you have a local repository. You can change to different branches, pull an older version of a file, and commit your changes all to your local repo with no internet whatsoever. Only when you want others to be able to see your changes on a public server (like github, for example) do you push your changes from your local repository to the remote one. Most of the work happens locally with full version control/history. Once the internet is working again, you'd push your changes to the web based server.

The only time you'd be stuck is if you used one computer and published it to the web, and then wanted to pull to another computer to continue working, but that's a problem you'll have with anything that you store on the interwebs. If you have local access (eg. network or thumb drive) to a machine with a recent copy, you can clone (or fetch changes) from that repository over to the new machine and keep working locally. Overall, I find this generally superior to the way SVN does things. I use both SVN (work) and Git (home) - I prefer the SVN workflow, but Git is not that different.

For those that want to poke around a project, here's the quick method to just get a local copy that you can look at on your own computer without even having git installed:
Click the little arrow next to the "<>Code" button (top right above file/folder list), select Download Zip, enjoy on your computer.
User avatar
Yuri
Posts: 371
Joined: 28 Feb 2023
Location: Texas

Re: simulator

Post by Yuri »

rwiker wrote:
BigDumbDinosaur wrote:
[
BTW, what do GitHub users do wen they are in the middle of a programming project, need to check out a file for editing and their Internet service goes on the fritz?
git is a distributed version control system, so 99% of the time developers do not need to have access to github, or even internet. This is similar to subversion, but git simply is much more full-featured and works better.
In fact, you can still do commits, branch, checkout, merges, and view history, all locally when you are completely offline. Once you do get online you tell git to synchronize changes to/from the (a) server.

You can even have multiple different servers in different locations. So you could run a local server if you wish to have a second machine with a "backup" copy if you want. Or if you're a global organization you can have a more localized server for each region of your business and let the servers do the heavy bandwidth lifting instead of your users who might be on a limited connection.

And again, GitHub is just one such git hosting service. There are several others, and there's no requirement that you use any of them. Git is perfectly capable of standing on its own without GitHub.
nora23169
Posts: 43
Joined: 29 Oct 2024

Re: simulator

Post by nora23169 »

For now, this is all I can do as far as progress is concerned.
#define PC 0
int data_bus;
sark02
Posts: 241
Joined: 10 Nov 2015

Re: simulator

Post by sark02 »

nora23169 wrote:
For now, this is all I can do as far as progress is concerned.
#define PC 0
int data_bus;
A strong start. I look forward to seeing where this goes.
nora23169
Posts: 43
Joined: 29 Oct 2024

Re: simulator

Post by nora23169 »

There may still be some strange parts, but I have defined it.This is a CPU made with custom instructions called mos6503, but I will improve the quality in various parts so that it is similar to mos6502.:CODE:


#include <stdio.h>
#include <stdlib.h>

// memory size(Test)
#define MEM_SIZE 0xFFFF


// register
#define S 0
#define PC 0
#define A 0
#define P 0
// index register
#define Y 0
#define X 0


// flag register
#define C_FLAG 0
#define Z_FLAG 0
#define I_FLAG 0
#define D_FLAG 0
#define B_FLAG 0
#define V_FLAG 0
#define N_FLAG 0

// TEST Memory
int memory[MEM_SIZE];

// BUS

int data_bus;
int addr_bus;


// BUS Status
#define DATA_BUS_WRITE 0
#define DATA_BUS_READ 1




// BUS RW
void write_bus(int addr, int data)
{

}
int read_bus(int addr)
{

}

// 6502 RESET
void reset_6502()
{

}



int main()
{
return 0;
}
nora23169
Posts: 43
Joined: 29 Oct 2024

Re: simulator

Post by nora23169 »

There's still some terrible code right now so I'm fixing it myself. Please wait for a while.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: simulator

Post by GARTHWILSON »

nora23169 wrote:
This is a CPU made with custom instructions called mos6503
For personal use, I guess you could call it whatever you want to; but be aware there is already a 6503 (and '04, '05, '06, '07, '12, '13, '14, '15, and others).  See the MOS 65xx processors summary at http://6502.org/documents/datasheets/mo ... v_1985.pdf .  The 6502 is a 28-pin variation, omitting the pins for A12 through A15, Φ1 out, SYNC, RDY, SO, one of the Vss pins, and the N.C. pins.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: simulator

Post by BigDumbDinosaur »

rwiker wrote:
BigDumbDinosaur wrote:
[
BTW, what do GitHub users do wen they are in the middle of a programming project, need to check out a file for editing and their Internet service goes on the fritz?
git is a distributed version control system, so 99% of the time developers do not need to have access to github, or even internet.

What you are saying seems to say, “What’s the point of a GitHub-type service?  Just locally host your files.”  :D
x86?  We ain't got no x86.  We don't NEED no stinking x86!
rwiker
Posts: 294
Joined: 03 Mar 2011

Re: simulator

Post by rwiker »

BigDumbDinosaur wrote:
rwiker wrote:
BigDumbDinosaur wrote:
[
BTW, what do GitHub users do wen they are in the middle of a programming project, need to check out a file for editing and their Internet service goes on the fritz?
git is a distributed version control system, so 99% of the time developers do not need to have access to github, or even internet.

What you are saying seems to say, “What’s the point of a GitHub-type service?  Just locally host your files.”  :D
Whooosh.
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: simulator

Post by barnacle »

nora23169 wrote:
For now, this is all I can do as far as progress is concerned.
#define PC 0
int data_bus;
If it makes you feel any better, I _had_ a working 6502 simulator, and in the last fortnight I added a number of the 65c02 modes and instructions to it... which appear to work well, but somewhere along the line I broke it and now I can't find why... :roll:

This is intended for development on a laptop:
  • write and save source code - Geany
  • assemble to hex - AS65 (Frank Kingswood's assembler)
  • load hex into simulator, see where it breaks, rinse and repeat
And if you're considering a similar process, you might like to consider things like how to get input/output to and from it, breakpoints, loading code and so on. Other useful things: a viewer for the stack or random memory areas, an ability to see the processor registers and flags at any time, and the ability to single step or run to a breakpoint.

If it helps, my processor is defined

Code: Select all

typedef struct {
	uint8_t		acc;
	int16_t		pc;
	uint8_t		x;
	uint8_t		y;
	uint8_t		f;
	uint8_t		sp;
} REGS;
the modes:

Code: Select all

typedef enum {
    NONE,   // no instruction
	IMP,	// implicit
	ACC,	// a accumulator
	ABS,	// absolute
	ZP,		// zero page
	IMM,	// # immediate
	ABSX,	// absolute,x
	ABSY,	// absolute,y
	INDX,	// (indirect,x)
	INDY,	// (indirect),y
	INDZ,	// (indirect) zero page
	ZPX,	// zero page x
	ZPY,	// zero page y
	REL,	// relative
	IND		// (indirect)
} MODES;
and each instruction has a small structure that describes what it does, what its addressing mode is, and how to spell it (for the disassembler)

Code: Select all

typedef struct {
	// holds the data for a particular instruction
	// there will be 256 of these
	//OPCODES	opcode;		// the opcode itself is the position in the table
	MODES	mode;			// the addressing mode for this instance
	func	fn;				// and a function pointer to implement it
	char	name[8];		// an ascii name - most require only 4 bytes
							// instruction length in byte can be calculated from mode
} OPCODE_STRUCT;
Neil
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: simulator

Post by BigEd »

Can I suggest that anyone with a question or comment about code-hosting services could start a new thread? It would be really quite refreshing to see "what am I missing?" rather than "this makes no sense to me". It would also be refreshing to respect the topic of each thread here. Almost all of us can do it.
User avatar
Mike Naberezny
Site Admin
Posts: 293
Joined: 30 Aug 2002
Location: Northern California
Contact:

Re: simulator

Post by Mike Naberezny »

barnacle wrote:
If it makes you feel any better, I _had_ a working 6502 simulator, and in the last fortnight I added a number of the 65c02 modes and instructions to it... which appear to work well, but somewhere along the line I broke it and now I can't find why... :roll:
An approach I can recommend is writing unit tests. When I wrote mine, I wrote little tests like this one as I went along:

Code: Select all

def test_pla_pulls_top_byte_from_stack_into_a_and_updates_sp(self):
    mpu = self._make_mpu()
    # $0000 PLA
    mpu.memory[0x0000] = 0x68
    mpu.memory[0x01FF] = 0xAB
    mpu.sp = 0xFE
    mpu.step()
    self.assertEqual(0x0001, mpu.pc)
    self.assertEqual(0xAB,   mpu.a)
    self.assertEqual(0xFF,   mpu.sp)
Whenever I'd add a new instruction, I'd add some tests to verify it did what I thought it should do. Occasionally, I'd make a change that broke something and I'd know right away because the previously-working tests would fail.

There are also test suites like Klaus Dormann's but in the very beginning stages, running such a test suite is difficult because so many things are broken. I wrote my own unit tests until I thought I had it mostly working, then I tried to run larger programs.
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: simulator

Post by barnacle »

Yeah, before I started playing, the simulator worked fine... passed all Klaus' tests handily (and found a minor bug in transit).

The main loop is straight forward:

Code: Select all

	while (1)
	{
		if (showstate (&reg))
		{
			// sometimes showstate does things where we should not advance
			interpret (&reg);
		}
	}
where showstate generally displays the current processor status after each instruction and waits for a keypress.

There is a table arranged by opcode which holds the opcode and structure

Code: Select all

const OPCODE_STRUCT opcodes[256] = {		// every legal instruction, by opcode, with its addressing mode

/*00*/	{IMP,_brk,"brk"},	{INDX,ora,"ora"},	{NONE,NULL,"???"},	{NONE,NULL,"???"},
...
Interpret grabs the function pointer and mode

Code: Select all

void interpret (REGS * regs)
{
    // emulate an instruction using data from the opcode table
    // the opcode table structure includes function pointers to each instruction
	if (interrupts.irq && !I)
	{
		// interrupt is enabled and has happened
		interrupts.irq = false;							// in the real chip this would be level sensitive, but here's it's an edge trigger
		irq (regs);
	}
	else
	{
		uint8_t         op = readmem (regs->pc);        // get the instruction
		OPCODE_STRUCT   os = opcodes[op];               // find out what it was
		(*opcodes[op].fn) (regs, os.mode);				// and execute it
	}
}

and executes it accordingly, with individual functions that in general look like this

Code: Select all

void and (REGS * regs, MODES mode)
{
	// N, Z
	target = get_target_address (regs, mode);
	target_byte = readmem (target);
	regs->acc = regs->acc & target_byte;
	N = ((int8_t)regs->acc < 0);
 	Z = (0 == regs->acc);
}
Which is simple, robust, and easy to add further instructions (for example, I haven't added the TSB and RSB group at this point as I don't use them, and a couple of others. But if I try and execute a non-specified opcode then I get an immediate hard segfault, which is handy.

However... showstate is a bit complex. It's intended to provide either execution of a single instruction, with status, or trace to a (n effective) breakpoint, with status, or run to a breakpoint without status. When it's doing that latter, it handles output and input from the console - there's an emulated 6850 in there somewhere. When it's not, between single-stepping, it also traps a number of other keys to do the usual 'monitor' type stuff.

Somewhere in my changes, I broke the silent running behaviour... I think the issue is me not having chosen the best variable names five years ago when I originally wrote it. I'll fix it :mrgreen:

Neil
Post Reply