Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- 6502 Lua emulator
- by J. Aldo G. de F. Junior 2014 jorgealdojr@hotmail.com
- derived from javascript source by
- by N. Landsteiner 2005, e-tradion.net
- wich is derived from the c source by
- Earle F. Philhower III, Commodore 64 Emulator v0.3, (C) 1993-4
- extended for exact cycle times [N. Landsteiner, 2005]
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- For the GNU General Public License see the Free Software Foundation,
- Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- Thanks to "chip" for a bugfix in function BranchRelAddr().
- fixed a bug regarding byte ranges in functions opDECR and opINCR -
- thanks to James Larson for reporting. (2008-09-05)
- --]]
- emu6502 = {
- -- Global conf
- Debug = false
- ExternalLoop = true
- StopOnIterrupt = true
- -- Constants
- ResetTo = 0xfffc
- IrqTo = 0xfffe
- NMITo = 0xfffa
- -- Flags
- fCAR = 1
- fZER = 2
- fINT = 4
- fDEC = 8
- fBKC = 16
- fOVF = 64
- fNEG = 128
- -- regs & memory
- A = 0
- X = 0
- Y = 0
- Flags = 0
- SP = 0
- PC = ResetTo
- RAM = {}
- BreakFlag = false
- ExCycles = 0
- AddCycles = 0
- function ByteAt(addr)
- return RAM[addr] or 0
- end
- function WordAt(addr)
- return ByteAt(addr) + ByteAt(0xffff and (addr + 1)) * 256
- end
- function ImmediateByte()
- return ByteAt(PC)
- end
- function ZeroPageAddr()
- return ByteAt(PC)
- end
- function ZeroPageXAddr()
- return 255 and (x + ByteAt(PC))
- end
- function ZeroPageYAddr()
- return 255 and (y + ByteAt(PC))
- end
- function IndirectXAddr()
- return WordAt(255 and (ByteAt(PC) + x))
- end
- function IndirectYAddr()
- if AddCycles > 0 then
- local a1 = WordAt(ByteAt(PC))
- local a2 = (a1 + y) and 0xffff
- if ((a1 and 0xff00) ~= (a2 and 0xff00)) then
- ExtraCyles = ExtraCyles + 1
- end
- return a2;
- else
- return (WordAt(ByteAt(PC)) + Y) and 0xffff
- end
- end
- function AbsoluteAddr()
- return WordAt(PC)
- end
- function AbsoluteXAddr()
- if AddCycles > 0 then
- local a1 = WordAt(PC)
- local a2 = (a1 + X) and 0xffff
- if ((a1 and 0xff00) ~= (a2 and 0xff00)) then
- ExtraCyles = ExtraCyles + 1
- end
- return a2
- else
- return (WordAt(PC) + X) and 0xffff
- end
- end
- function AbsoluteYAddr()
- if AddCycles > 0 then
- local a1 = WordAt(PC)
- local a2 = (a1 + Y) and 0xffff
- if ((a1 and 0xff00) ~= (a2 and 0xff00)) then
- ExtraCyles = ExtraCyles + 1
- end
- return a2
- else
- return (WordAt(PC) + Y) and 0xffff;
- end
- end
- function BranchRelAddr()
- ExCycles = ExCycles + 1
- Local addr = ImmediateByte()
- PC = PC + 1;
- if addr and 128 then
- addr = PC - ((bit32.bxor(addr, 255) + 1)
- else
- addr = PC + addr
- end
- if ((pc and 0xff00) ~= (addr and 0xff00)) then
- ExCycles = ExCycles + 1
- end
- pc = addr and 0xffff
- end
- -- stack
- function stPush(z)
- RAM[SP + 256] = Z and 255
- SP = SP - 1
- SP = SP and 255
- end
- function stPop()
- SP = SP + 1
- SP = SP and 255
- return ByteAt(SP + 256)
- end
- function stPushWord(z)
- stPush(bit32.rshift(z, 8) and 255)
- stPush(z and 255)
- end
- function stPopWord()
- local z = stPop()
- z = z + 256 * stPop()
- return z
- end
- -- operations
- function FlagsNZ(z)
- Flags = Flags and not (fZER + fNEG)
- if z == 0 then
- Flags = Flags or fZER
- else
- Flags = Flags or (Z and 128)
- end
- end
- function opORA(x)
- A = A or ByteAt(x)
- FlagsNZ(A)
- end
- function opASL(x)
- local addr = x()
- local tbyte = ByteAt(addr)
- Flags = Flags and not (fCAR + fNEG + fZER)
- if tbyte and 128 then
- Flags = Flags or fCAR
- end
- if tbyte == bit32.lshift(tbyte, 1) then
- Flags = Flags or (tbyte and 128)
- else
- Flags = Flags or fZER
- end
- RAM[addr] = tbyte
- end
- function opLSR(x) {
- local addr = x()
- local tbyte = ByteAt(addr)
- Flags = Flags and not (fCAR+fNEG+fZER)
- Flags = Flags or (tbyte and 1)
- if tbyte == bit32.rshit(tbyte,1) then
- else
- Flags = Flags or fZER
- end
- RAM[addr] = tbyte
- end
- function opBCL(x)
- if Flags and x then
- PC = PC + 1
- else
- BranchRelAddr()
- end
- end
- function opBST(x)
- if flags and x then
- BranchRelAddr()
- else
- PC = PC + 1
- end
- end
- function opCLR(x) {
- flags &=~x;
- }
- function opSET(x) {
- flags |= x;
- }
- function opAND(x) {
- a &= ByteAt(x());
- FlagsNZ(a);
- }
- function opBIT(x) {
- var tbyte=ByteAt(x());
- flags &=~(fZER+fNEG+fOVF);
- if ((a&tbyte)==0) flags |=fZER;
- flags |=tbyte&(128+64);
- }
- function opROL(x) {
- var addr=x();
- var tbyte=ByteAt(addr);
- if (flags&fCAR) {
- if (tbyte&128) {}
- else {
- flags &=~fCAR;
- }
- tbyte=(tbyte<<1)|1;
- }
- else {
- if (tbyte&128) flags|=fCAR;
- tbyte=tbyte<<1;
- }
- FlagsNZ(tbyte);
- RAM[addr]=tbyte;
- }
- function opEOR(x) {
- a^=ByteAt(x());
- FlagsNZ(a);
- }
- function opADC(x) {
- var data=ByteAt(x());
- if (flags&fDEC) {
- data = bcd2dec[data]+bcd2dec[a]+((flags&fCAR)?1:0);
- flags &= ~(fCAR+fOVF+fNEG+fZER);
- if (data>99) {
- flags|=fCAR+fOVF;
- data -=100;
- }
- if (data==0) {
- flags|=fZER;
- }
- else {
- flags |=data&128;
- }
- a=dec2bcd[data];
- }
- else {
- data += a+((flags&fCAR)?1:0);
- flags &= ~(fCAR+fOVF+fNEG+fZER);
- if (data>255) {
- flags|=fOVF+fCAR;
- data &=255;
- }
- if (data==0) {
- flags|=fZER;
- }
- else {
- flags |=data&128;
- }
- a=data;
- }
- }
- function opROR(x) {
- var addr=x();
- var tbyte=ByteAt(addr);
- if (flags&fCAR){
- if (tbyte&1) {}
- else flags&=~fCAR;
- tbyte=(tbyte>>1)|128;
- }
- else{
- if (tbyte&1) flags|=fCAR;
- tbyte=tbyte>>1;
- };
- FlagsNZ(tbyte);
- RAM[addr]=tbyte;
- }
- function opSTA(x) {
- RAM[x()]=a;
- }
- function opSTY(x) {
- RAM[x()]=y;
- }
- function opSTX(y) {
- RAM[y()]=x;
- }
- function opCPY(x) {
- var tbyte=ByteAt(x());
- flags &=~(fCAR+fZER+fNEG);
- if (y==tbyte) {
- flags |=fCAR+fZER;
- }
- else if (y>tbyte) {
- flags |=fCAR;
- }
- else {
- flags |=fNEG;
- }
- }
- function opCPX(y) {
- var tbyte=ByteAt(y());
- flags &=~(fCAR+fZER+fNEG);
- if (x==tbyte) {
- flags |=fCAR+fZER;
- }
- else if (x>tbyte) {
- flags |=fCAR;
- }
- else {
- flags |=fNEG;
- }
- }
- function opCMP(x) {
- var tbyte=ByteAt(x());
- flags &=~(fCAR+fZER+fNEG);
- if (a==tbyte) {
- flags |=fCAR+fZER;
- }
- else if (a>tbyte) {
- flags |=fCAR;
- }
- else {
- flags |=fNEG;
- }
- }
- function opSBC(x) {
- var data=ByteAt(x());
- if (flags&fDEC) {
- data = bcd2dec[a]-bcd2dec[data]-((flags&fCAR)?0:1);
- flags &= ~(fCAR+fZER+fNEG+fOVF);
- if (data==0) {
- flags |=fZER+fCAR;
- }
- else if (data>0) {
- flags |=fCAR;
- }
- else {
- flags|=fNEG;
- data +=100;
- }
- a=dec2bcd[data];
- }
- else {
- data = a-data-((flags&fCAR)?0:1);
- flags &=~(fCAR+fZER+fOVF+fNEG);
- if (data==0) {
- flags |=fZER+fCAR;
- }
- else if (data>0) {
- flags |=fCAR;
- }
- else {
- flags|=fOVF;
- }
- flags |=data&128;
- a=data&255;
- }
- }
- function opDECR(x) {
- var addr=x();
- var tbyte=(ByteAt(addr)-1)&255;
- flags &=~(fZER+fNEG);
- if (tbyte) {
- flags |=tbyte&128;
- }
- else {
- flags|=fZER;
- }
- RAM[addr]=tbyte;
- }
- function opINCR(x) {
- var addr=x();
- var tbyte=(ByteAt(addr)+1)&255;
- flags &=~(fZER+fNEG);
- if (tbyte) {
- flags |=tbyte&128;
- }
- else {
- flags|=fZER;
- }
- RAM[addr]=tbyte;
- }
- function opLDA(x) {
- a=ByteAt(x());
- FlagsNZ(a);
- }
- function opLDY(x) {
- y=ByteAt(x());
- FlagsNZ(y);
- }
- function opLDX(y) {
- x=ByteAt(y());
- FlagsNZ(x);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement