Coder Social home page Coder Social logo

6502.js's Introduction

6502.js

Cycle-accurate 6502 emulator in Javascript

BUILDING

Run npm install first to retrieve all dependencies. Running npm start builds both the minified and the development version of 6502.js. npm run build:production and npm run build:production build the minified and development version separately.

6502.js's People

Contributors

torlus avatar superdoxin avatar xotmatrix avatar

Stargazers

 avatar Pierpaolo Pierozzi avatar  avatar  avatar Paul Chana avatar Michiel Erasmus avatar Niklas Hedlund avatar Michael Matejko avatar Joe avatar  avatar nino-porcino avatar  avatar Alessandro Miliucci avatar Brit Butler avatar  avatar PyDever avatar Luc Rubio avatar Fırat Küçük avatar  avatar Stefano Furiosi avatar jadon avatar Michael Anthony avatar Bernardo Andreeti avatar letoh avatar  avatar

Watchers

 avatar James Cloos avatar Michael Anthony avatar  avatar Michael Matejko avatar PyDever avatar

6502.js's Issues

Question about LSR

Hello,

The documentation I found online about LSR says:

LSR shifts all bits right one position. 0 is shifted into bit 7 and the original bit 0 is shifted into the Carry. 
Flags Z and N are set according to the result.

your code does:

CPU6502.prototype.lsr = function() {
	this.tmp = this.read(this.addr);
	this.tmp = ((this.tmp & 1) << 8) | (this.tmp >> 1);
	this.fnzc(this.tmp);
	this.tmp &= 0xFF;
}

I kinda understand why it works with your implementation, but it seems pretty counter-intuitive.
Why not store bit 7 in C directly and call fnz, instead of left shifting bit 0 eight times and call fznc?
Also, why do you mask tmp with 0xFF at the end? rmw is called after lsr and does this masking anyway, so this line seems redundant...

But maybe it's just an optimization that I don't understand.
In this case, I'd like to know more about it.

Thanks! :)

JSR and RTS are broken

According to a 6502 programming manual (http://archive.6502.org/datasheets/synertek_programming_manual.pdf, page 106) JSR is supposed to push PC+2 (where PC points at the JSR instruction). In other words, the return address points to the byte before the next instruction. RTS is supposed to pop PC, increment PC, and then continue execution.

The current JSR/RTS implementation in this library pushes PC+3, so that the return address points at the next instruction, and RTS just pops PC.

This breaks, for example, MS-BASIC. MS-BASIC uses an address LUT for its VM. It looks up the BASIC VM opcode in an address LUT, pushes that address onto the stack, and then calls RTS. All the addresses in that table are -1, because MS-BASIC expects the 6502's RTS instruction to pop PC off the stack and increment it.

I had a heck of a time debugging that...

If you would like, I can fork and do a pull request to save you effort. However, it would be difficult for me to test the changes in my application, since I'm using a refactored version of your code (refactored into ASM.JS).

By the way, thank you for this resource. It's a really neat implementation of the 6502, and its cycle accuracy was useful in my application.

Fix BRK, JSR, PHP, PLA, RTI, RTS

I'm making some tests using several 6502 impl, then I took yours and manage to run the tests that I have on it. It's all on branch https://github.com/gutomaia/wedNESday/tree/torlus_6502_js

The problem that I notice must be related to the CPU status byte. Since most of the instructions that have the problem, relies on them.

Example PHP instruction:

yours, get the status inside the instruction as:

CPU6502.prototype.php = function() {
    var v = this.N << 7;
    v |= this.V << 6;
    v |= 3 << 4;
    v |= this.D << 3;
    v |= this.I << 2;
    v |= this.Z << 1;
    v |= this.C;
    this.write(this.S + 0x100, v);
    this.S = (this.S - 1) & 0xFF;
    this.cycles++;
}

Take a look on James Tauber (@jtauber) approach, he extrated the status function, on his code we got:

    def status_as_byte(self):
        return (self.carry_flag |
                self.zero_flag << 1 |
                self.interrupt_disable_flag << 2 |
                self.decimal_mode_flag << 3 |
                self.break_flag << 4 |
                1 << 5 |
                self.overflow_flag << 6 |
                self.sign_flag << 7)

    def push_byte(self, byte):
        self.write_byte(self.STACK_PAGE + self.stack_pointer, byte)
        self.stack_pointer = (self.stack_pointer - 1) % 0x100

    def PHP(self):
        self.cycles += 1
        self.push_byte(self.status_as_byte())

The behavior itself, it's the same, only difference seems to be related to the status byte.

On tests on wedNESday, tests that were falling was:

    def test_php(self):
        self.cpu_set_register('P', 0xff)
        self.cpu_pc(0x0100)
        self.memory_set(0x0100, 0x08)

        self.execute()

        self.assertEqual(self.cpu_pull_byte(), 0xff)

BTW, if the proper config, both James Tauber's 6502 and py65 works quite fine! If I got time, I will send a PR about this!

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.