Page 3 of 3

Re: simulator

Posted: Mon Dec 16, 2024 4:46 pm
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.

Re: simulator

Posted: Mon Dec 16, 2024 4:57 pm
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.

Re: simulator

Posted: Mon Dec 16, 2024 10:23 pm
by nora23169
For now, this is all I can do as far as progress is concerned.
#define PC 0
int data_bus;

Re: simulator

Posted: Mon Dec 16, 2024 11:06 pm
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.

Re: simulator

Posted: Tue Dec 17, 2024 12:04 am
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;
}

Re: simulator

Posted: Tue Dec 17, 2024 12:20 am
by nora23169
There's still some terrible code right now so I'm fixing it myself. Please wait for a while.

Re: simulator

Posted: Tue Dec 17, 2024 1:08 am
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.

Re: simulator

Posted: Tue Dec 17, 2024 1:30 am
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

Re: simulator

Posted: Tue Dec 17, 2024 5:28 am
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.

Re: simulator

Posted: Tue Dec 17, 2024 9:12 am
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

Re: simulator

Posted: Tue Dec 17, 2024 9:54 am
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.

Re: simulator

Posted: Tue Dec 17, 2024 5:07 pm
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.

Re: simulator

Posted: Wed Dec 18, 2024 10:45 am
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