Saturday, March 7, 2015

Tiny 6502 - a Javascript 6502 Emulator for the NES

6502 Processor Pinouts
It's been some time since I updated this blog. Work has been keeping me extremely busy. I just got off a very long term project and my brain is fried. So what does a computer nerd do for rest and relaxation? Why think about console game coding of course. For some time I have considered what it would take to code either a 6502, pronounced sixty-five-oh-two, emulator for the NES or a RISC emulator for the N64. During this time obviously, many platform emulators in javascript have hit the web. However, not a lot of tutorials on the web on how to write an emulator. I am going to write a series of blogs on writing a 6502 processor emulator, called Tiny6502, for edification and learning. I call it Tiny 6502 because we're going to build it in stages and in software modules.

Phase I we're going to build the Tiny 6502 emulator libraries, Phase II, we're going to build a virtual hobby programmer board, like the KIM-1, to program the virtual processor, and Phase III we're going to implement a ROM like library to allow the Tiny6502 emulator to run NES code. So why write a virtual emulator?

Because it beats the hell out of wire wrapping circuits any day!



Wire Wrapped NES Development Board
Besides, we have so much computing power in the palm of our hands everyday, it is mind blowing that I can code my cell phone in javascript and HTML 5. -And then run the same code on my monstrous PowerMac desktop, which has more processing power than the CRAY computer I was trained on in my college days! Ah, the brave new world we live in. This endeavor started with some great articles I found on the web for designing my virtual processor architecture. The NES and Atari dev forums and blogs are rich with information for back engineering. Some of these articles we're going to re-visit to implement some of their coding tutorials into the Tiny 6502. There are a lot of libraries we'er going to have to write along the way to get to the NES emulator up and running. The first order of business is where to begin.

The 6502 is a simple processor, it made Jobs and Wozniak very wealthy nerds in the 70's and 80's. Steve Jobs went on to become the icon of the computer nerd and he had countless millions. I don't think I 'll make millions of my Tiny 6502 virtual processor, that ship has sailed. However, in returning to my design mindset, I was going to first write code to emulate the accumulator and general purpose registers. Then it donned on my I would need memory to fetch and write to. So I next anticipated writing a memory library for the Tiny 6502. As I did more research on batting back and forth between the accumulator and general purpose registers, or writing the memory lib, it suddenly made more sense, after some research, to write the code for the 6502's status register first. Why? Well, because operations of the 6502 processor depended on states in the status bit register, which affected the operations in the accumulator and the X and Y general purpose registers.

6502 Microprocessor Architecture


The NES Dev Wiki has a fairly good explanation of the status register, sometimes called the P, for the Processor Status register. The task at hand, and our goal for coding, is outlined very clearly in this online article I found over at the Atari Archives.

Processor Status Register Bits
I am going to use the article at the Atari Archives site as my model for coding the Processor Status register. Obviously, our code is going to have to do some low level binary operations to toggle bits in our software emulated P register.

Toggling Bits in Javascript

I had to brush off my TTL logic skillz from days of old. But I managed to create a simple library for this. I needed a library to set an individual bit and at location n. I also needed to clear a a bit at location n. Finally I needed to test a bit a position n to determine if the bit was set. For a good refresher on simple bit toggling, read low level bit hacks you absolutely must know. I used this article to write my bit_lib.js library.

Setting Bits in Javascript

Here is some basic TTL logic, or to a programmer, bitwise logical operations, we will need to understand in order to set bits. From the low level bit hacking article, in order to set a bit we must perform the following procedure in our software.

In order to set bit at position n in a binary number we must create a binary mask. The binary mask is created by shifting bits n times to the left to reached the desired bit.

1<<0      00000001  
1<<1      00000010
1<<2      00000100
1<<3      00001000
1<<4      00010000
1<<5      00100000
1<<6      01000000
1<<7      10000000

If I want to set bit 5 in binary number, I must create a mask by rotating bits left 5 times.

bit mask for bit 5:   mask = 1<<5  = 00100000

As an example, let's set bit 5 in the binary number 1000 0000 (128 base 10 - decimal).

        1000 0000               128 decimal

We will need our bit mask for bit position 5, from the table above.

        0010 0000               1<<5

With these two values we will now set bit 5 in the binary number 128, using a logical OR operator.

TTL Logical OR

Let's apply the logical OR to our example of setting bit 5 in the binary number (128 deicmal).
The logical OR is represented in javascript with the "|" operator. I am using the TTL logical OR table above to determine the output of the operation.

         1000 0000               128 decimal
|        0010 0000               1<<5 (bit position 5 mask)
------------------------------------------------
        1010  0000               -this is the resulting binary number (160 decimal)

Our coding task for this is the following:

1. Create a mask for bit position n.

  mask = (1 << bit position)

2. Carry out a logical OR on the mask and the bits.

  binary number | mask;

3. Simplify the operation,

   binary number | (1 << bit position)

The javascript code for setbit(), from the bit_lib.js, library is shown in Listing 1.


Listing 1. Setting a bit in javascript
1:  /*------------------------------------------------------------------------  
2:  * function: setbit (bitstring, bitposition)  
3:  *  
4:  * description:  
5:  *  This javascript function sets the individual bit in a bitstring at  
6:  *  at bitposition in the bitstring.  
7:  *  
8:  * Example: Set bit position 2 in bit string 01111000  
9:  *  
10:  *   01111000  (120 in binary)   argument: bitstring = 01111000  
11:  *  | 00000100  (1<<2)       argument: bitposition = 2  
12:  *   --------  
13:  *   01111100            returns: this value  
14:  *  
15:  * Arguments:  
16:  *  bitstring: the binary representation of the bits to be modified   
17:  *  bitposition: the n-th bit to set  
18:  *------------------------------------------------------------------------*/  
19:  function setbit(bitstring, bitposition) {  
20:   // set bit  
21:   // num | (1<<bit);  
22:   return bitstring | (1<<bitposition);  
23:  }   

Clearing Bits in Javascript

The trick in clearing a bit at position n in a binary number requires creating a 1's complement mask.
From our previous example in setting bits. We only needed a basic mask on the bit position to set.
Remember, setting bit 5 in the decimal number 128 we created a bit mask.

mask = 1<<5  = 00100000

Now we our desire is to clear the bit. To do so we need an binary inverted mask, called a one's complement mask. The following are one's complement masks for bits 0-7.

~1            11111110  (same as ~(1<<0))
~(1<<1)   11111101
~(1<<2)   11111011
~(1<<3)   11110111
~(1<<4)   11101111
~(1<<5)   11011111
~(1<<6)   10111111
~(1<<7)   01111111


mask = one's complement of (1<<5) 
         = one's complement of 00100000
         =                                   11011111 

We flipped the bits in the binary number.

TTL Logical AND
Let's apply the logical AND to our example of clearing bit 5 in the binary number (128 deicmal).
The logical AND is represented in javascript with the "&" operator. I am using the TTL logical AND table above to determine the output of the operation.

         1111 0000               240 decimal
&      1101 1111               ~(1<<5 )  one's complement for bit position 5 mask
------------------------------------------------
         1101  0000               -this is the resulting binary number (208 decimal)


How do we accomplish this is javascript? We use the tilde ~ operator.

Our coding task for this is the following:

1. Create a one's complement mask for bit position n using the tilde ~ operator.

  mask = ~ (1 << bit position)

2. Carry out a logical AND on the one's complement mask and the bits.

  binary number & mask;

3. Simplify the operation,

   binary number & ~(1 << bit position)

The javascript code for clearbit(), from the bit_lib.js, library is shown in Listing 2.

Listing 2. Clearing a bit in javascript
1:  /*------------------------------------------------------------------------  
2:  * function: clearbit (bitstring, bitposition)  
3:  *  
4:  * description:  
5:  *  This javascript function clears the individual bit in a bitstring at  
6:  *  at bitposition in the bitstring.  
7:  *  
8:  * Example: Clear bit position 4 in bit string 01111111  
9:  *  
10:  *   01111111  (127 in binary)   argument: bitstring = 01111111  
11:  *  & 11101111  (~(1<<4))      argument: bitposition = 4  
12:  *   --------  
13:  *   01101111            returns: this value  
14:  *  
15:  * Arguments:  
16:  *  bitstring: the bit string to be modified   
17:  *  bitposition: the n-th bit to set  
18:  *------------------------------------------------------------------------*/  
19:  function clearbit(bitstring, bitposition) {  
20:   // unset bits  
21:   // num & ~(1<<bit);  
22:   return bitstring & ~(1<<bitposition);  
23:  }   

Listing 3. Checking to see if a bit is set in javascript
1:  /*------------------------------------------------------------------------  
2:  * function: isBitNSet (bitstring, bitposition)  
3:  *  
4:  * description:  
5:  *  This javascript function clears the individual bit in a bitstring at  
6:  *  at bitposition in the bitstring.  
7:  *  
8:  * Example: Test to see if bit position 0 in bit string 01100010 is set  
9:  *  
10:  *   01100010  (98 in binary) argument: bitstring = 01100010  
11:  * &  00000001          argument: bitposition = 0  
12:  *   --------  
13:  *   00000000          
14:  *  
15:  *  if (bitstring & (1<<bitposition)) {  
16:  *  n-th bit position is set  
17:  *  }  
18:  *  else {  
19:  *   n-th bit position is not set  
20:  *  }  
21:  *  
22:  * Arguments:  
23:  *  bitstring: the bit string to be modified   
24:  *  bitposition: the n-th bit to set  
25:  *  
26:  * Returns:  
27:  *  1 - if bit at bitposition is set. ZERO otherwise  
28:  *------------------------------------------------------------------------*/  
29:  function isBitNSet(bitstring, bitposition) {  
30:   if ( bitstring & (1<<bitposition) ) {  
31:        return 1;  
32:   }   
33:   // bit not set return FALSE!  
34:   return 0;  
35:  }   

Coding the P Register in Javascript

With some simple bit toggling tools we're going to start writing some code for our processor status register emulation. Our criteria is to set the following bits in the P register.

   Processor Status
   ----------------
   
   The processor status register is not directly accessible by any 6502 
   instruction.  Instead, there exist numerous instructions that test the 
   bits of the processor status register.  The flags within the register 
   are:
   
   
       bit ->   7                           0
              +---+---+---+---+---+---+---+---+
              | N | V |   | B | D | I | Z | C |  <-- flag, 0/1 = reset/set
              +---+---+---+---+---+---+---+---+
              
              
       N  =  NEGATIVE. Set if bit 7 of the accumulator is set.
       
       V  =  OVERFLOW. Set if the addition of two like-signed numbers 
             or the subtraction of two unlike-signed numbers produces 
             a result greater than +127 or less than -128.
             
       B  =  BRK COMMAND. Set if an interrupt caused by a BRK, reset if
             caused by an external interrupt.
             
       D  =  DECIMAL MODE. Set if decimal mode active.
       
       I  =  IRQ DISABLE.  Set if maskable interrupts are disabled.
             
       Z  =  ZERO.  Set if the result of the last operation (load/inc/dec/
             add/sub) was zero.
             
       C  =  CARRY. Set if the add produced a carry, or if the subtraction
             produced a borrow.  Also holds bits after a logical shift.
             

With this information we can start looking at coding the P register emulator.

Listing 4. The status register bit fields in javascript
1:  /*-------------------------------------------------------------------------------  
2:  *  
3:  *  
4:  *  6502 CPU Status Bit Register library  
5:  *  
6:  * notes: http://nesdev.com/6502.txt  
7:  * THE STATUS REGISTER  
8:  *  
9:  *  This register consists of eight "flags" (a flag = something that indi-  
10:  * cates whether something has, or has not occurred). Bits of this register  
11:  * are altered depending on the result of arithmetic and logical operations.  
12:  * These bits are described below:  
13:  *  
14:  *   Bit No.    7  6  5  4  3  2  1  0  
15:  *              S  V     B  D  I  Z  C  
16:  *  
17:  *  Bit0 - C - Carry flag: this holds the carry out of the most significant  
18:  *  bit in any arithmetic operation. In subtraction operations however, this  
19:  *  flag is cleared - set to 0 - if a borrow is required, set to 1 - if no  
20:  *  borrow is required. The carry flag is also used in shift and rotate  
21:  *  logical operations.  
22:  *  
23:  *  Bit1 - Z - Zero flag: this is set to 1 when any arithmetic or logical  
24:  *  operation produces a zero result, and is set to 0 if the result is  
25:  *  non-zero.  
26:  *  
27:  *  Bit 2 - I: this is an interrupt enable/disable flag. If it is set,  
28:  *  interrupts are disabled. If it is cleared, interrupts are enabled.  
29:  *  
30:  *  Bit 3 - D: this is the decimal mode status flag. When set, and an Add with  
31:  *  Carry or Subtract with Carry instruction is executed, the source values are  
32:  *  treated as valid BCD (Binary Coded Decimal, eg. 0x00-0x99 = 0-99) numbers.  
33:  *  The result generated is also a BCD number.  
34:  *  
35:  *  Bit 4 - B: this is set when a software interrupt (BRK instruction) is  
36:  *  executed.  
37:  *  
38:  *  Bit 5: not used. Supposed to be logical 1 at all times.  
39:  *  
40:  *  Bit 6 - V - Overflow flag: when an arithmetic operation produces a result  
41:  *  too large to be represented in a byte, V is set.  
42:  *  
43:  *  Bit 7 - S - Sign flag: this is set if the result of an operation is  
44:  *  negative, cleared if positive.  
45:  *  
46:  *  The most commonly used flags are C, Z, V, S.  
47:  *  
48:  *-------------------------------------------------------------------------------*/  
49:  var StatusRegister = 0;  
50:  var CBit = 0;  // Carry Flag   Bit 0  
51:  var ZBit = 1;  // Zero Flag   Bit 1  
52:  var IBit = 2;  // Interrupt Flag Bit 2  
53:  var DBit = 3;  // BCD Flag    Bit 3  - binary coded decimal  
54:  var BBit = 4;  // BRK Int Flag  Bit 4 - BRK instruction was executed  
55:  var NBit = 5;  // Not used    Bit 5 - not used, always set to 1  
56:  var VBit = 6;  // OVRFL Flag   Bit 6 - overflow flag  
57:  var SBit = 7;  // Sign flag   Bit 7 - set if result of operation is negative  

Now we can look at some code on how to set a bit in our status register emulator. You can see how our code for the status register is actually a help function using the setbit() function from the library, bitlib.js.

Listing 5. Setting bits in our P reg using javascript.

1:  /*-------------------------------------------------------------------------------  
2:  * function: SetStatusRegisterBit (bit_position)  
3:  *  
4:  * description:  
5:  *  This javascript function sets the individual bit flags   
6:  *  in the 6502 status register emulator.  
7:  *  
8:  *  CBit = 0;  // Carry Flag   Bit 0  
9:  *  ZBit = 1;  // Zero Flag   Bit 1  
10:  *  IBit = 2;  // Interrupt Flag Bit 2  
11:  *  DBit = 3;  // BCD Flag    Bit 3  - binary coded decimal  
12:  *  BBit = 4;  // BRK Int Flag  Bit 4 - BRK instruction was executed  
13:  *  NBit = 5;  // Not used    Bit 5 - not used, always set to 1  
14:  *  VBit = 6;  // OVRFL Flag   Bit 6 - overflow flag  
15:  *  SBit = 7;  // Sign flag   Bit 7 - set if result of operation is negative  
16:  *   
17:  * Example: Set ZBit in Status Register  
18:  *  
19:  *  SetStatusRegisterBit (Zbit);  
20:  *  ! Z-Bit SET DEBUG: 1111111100000010  
21:  *                  ^ Zbit set  
22:  *  
23:  * Arguments:  
24:  *  bit_position: the n-th bit to set (Processor flag bit position)  
25:  * Returns:  
26:  *  None - sets member variable StatusRegister  
27:  *-------------------------------------------------------------------------------*/  
28:  function SetStatusRegisterBit(bit_position){  
29:   StatusRegister = setbit(StatusRegister, bit_position);  
30:  }  


Using a helper function with clearbit() we can also clear bits in the P register.


Listing 6. Clearing bits in our P reg using javascript.

1:  /*-------------------------------------------------------------------------------  
2:  * function: ClearStatusRegisterBit (bit_position)  
3:  *  
4:  * description:  
5:  *  This javascript function clears the individual bit flags   
6:  *  in the 6502 status register emulator.  
7:  *  
8:  * Example: Clear ZBit in Status Register  
9:  *  
10:  *  ClearStatusRegisterBit (Zbit);  
11:  *  ! Z-Bit CLEAR DEBUG: 1111111100000000  
12:  *                   ^ Zbit clear  
13:  *  
14:  * Arguments:  
15:  *  bit_position: the n-th bit to set (Processor flag bit position)  
16:  * Returns:  
17:  *  None - sets member variable StatusRegister  
18:  *-------------------------------------------------------------------------------*/  
19:  function ClearStatusRegisterBit(bit_position) {  
20:       StatusRegister = clearbit(StatusRegister, bit_position);  
21:  }  
Listing 7. Checking to see if bits are set in our P reg using javascript.

1:  /*-------------------------------------------------------------------------------  
2:  * function: IsStatusRegisterBitSet (bit_position)  
3:  *  
4:  * description:  
5:  *  This javascript function tests to see if the individual bit flags   
6:  *  in the 6502 status register emulator are set.  
7:  *  
8:  * Example: Test to see if ZBit in Status Register is set.  
9:  *  
10:  *  SetStatusRegisterBit (Zbit);  
11:  *  ! Z-Bit SET DEBUG: 1111111100000010  
12:  *                  ^ Zbit set  
13:  *  bZbitSet = IsStatusRegisterBitSet(Zbit);   
14:  *  ! Z-Bit SET? DEBUG: 1  
15:  *  
16:  *  ClearStatusRegisterBit (Zbit);  
17:  *  ! Z-Bit CLEAR DEBUG: 1111111100000000  
18:  *                   ^ Zbit clear  
19:  *  bZbitSet = IsStatusRegisterBitSet(Zbit);   
20:  *  ! Z-Bit SET? DEBUG: 0  
21:  *  
22:  * Arguments:  
23:  *  bit_position: the n-th bit to set (Processor flag bit position)  
24:  * Returns:  
25:  *  1 - if bit is set, ZERO otherwise  
26:  *-------------------------------------------------------------------------------*/  
27:  function IsStatusRegisterBitSet(bit_position) {  
28:       return isBitNSet(StatusRegister, bit_position);  
29:  }  

That's it. Now we need some driver code to call from HTML. The HTML isn't pretty and polished. We're just using it so we can write to the browser and see values in the Chrome debugger.
Included in Source 1 is the sample HTML file I am using for testing.

This HTML file will generate the following output to your browser.

! C-Bit Set DEBUG: 1111111100000001
! Z-Bit Set DEBUG: 1111111100000011
! I-Bit Set DEBUG: 1111111100000111
! D-Bit Set DEBUG: 1111111100001111
! B-Bit Set DEBUG: 1111111100011111
! B-Bit Set DEBUG: 1111111100111111
! B-Bit Set DEBUG: 1111111101111111
! B-Bit Set DEBUG: 1111111111111111
! C-Bit CLR DEBUG: 1111111111111110
! C-Bit CLR DEBUG: 1111111111111110
! C-Bit2 SET DEBUG: 1111111111111111
! Z-Bit SET DEBUG: 1111111100000010
! Z-Bit SET? DEBUG: 1
! Z-Bit CLEAR DEBUG: 1111111100000000
! Z-Bit SET? DEBUG: 0
0000: a9 00 20 10 00 4c 2 00 00 00 00 00 00 00 00 40 e8 00 20 10 00 4c 2 00 00 00 00 00 00 00 00 40

Again this is code straight off the workbench. You will see the start of my design for the 8-bit memory. The bottom line of the output is my initial implementation of memory in the Tiny 6502.

Here is the complete source listing for the two javascript libraries and HTML driver file you will need to add to your sandbox to play along.

In the next installment we will start playing with memory and the accumulator.

Until then....   happy console hacking!

Mike

Source Listing 1. HTML driver code for testing Tiny6502.

1:  <html>  
2:  <head>  
3:  <!-- import javascript libraries -->  
4:  <script type="text/javascript"src="bit_lib.js"></script>  
5:  <script type="text/javascript"src="cpu6502.js"></script>  
6:  <script type="text/javascript">  
7:   function initStatusRegister() {  
8:   var radix = 2;  
9:   var mask = parseInt("0",radix);  
10:   var flag = 0xFF00;  
11:   StatusRegister = flag | mask;  
12:   }  
13:  initStatusRegister();  
14:  //SetCBit();  
15:  //SetStatusRegister(CBitMask);  
16:  StatusRegister = setbit(StatusRegister, 0);  
17:  document.write("!  C-Bit Set DEBUG: " + StatusRegister.toString(2) + "<br>");  
18:  /*  
19:  ClearCBit();  
20:  document.write("!  C-Bit Clr DEBUG: " + StatusRegister.toString(2) + "<br>");  
21:  */  
22:  //SetZBit();  
23:  SetStatusRegister(ZBitMask);  
24:  document.write("!  Z-Bit Set DEBUG: " + StatusRegister.toString(2) + "<br>");  
25:  //SetIBit();  
26:  SetStatusRegister(IBitMask);  
27:  document.write("!  I-Bit Set DEBUG: " + StatusRegister.toString(2) + "<br>");  
28:  //SetDBit();  
29:  SetStatusRegister(DBitMask);  
30:  document.write("!  D-Bit Set DEBUG: " + StatusRegister.toString(2) + "<br>");  
31:  //SetBBit();  
32:  SetStatusRegister(BBitMask);  
33:  document.write("!  B-Bit Set DEBUG: " + StatusRegister.toString(2) + "<br>");  
34:  //Set-Bit();  
35:  SetStatusRegister(mBitMask);  
36:  document.write("!  B-Bit Set DEBUG: " + StatusRegister.toString(2) + "<br>");  
37:  //SetBBit();  
38:  SetStatusRegister(VBitMask);  
39:  document.write("!  B-Bit Set DEBUG: " + StatusRegister.toString(2) + "<br>");  
40:  //SetBBit();  
41:  SetStatusRegister(NBitMask);  
42:  document.write("!  B-Bit Set DEBUG: " + StatusRegister.toString(2) + "<br>");  
43:  StatusRegister = clearbit(StatusRegister, 0);  
44:  document.write("!  C-Bit CLR DEBUG: " + StatusRegister.toString(2) + "<br>");  
45:  StatusRegister = clearbit(StatusRegister, 0);  
46:  document.write("!  C-Bit CLR DEBUG: " + StatusRegister.toString(2) + "<br>");  
47:  SetStatusRegisterBit(CBit);  
48:  document.write("!  C-Bit2 SET DEBUG: " + StatusRegister.toString(2) + "<br>");  
49:  initStatusRegister();  
50:  SetStatusRegisterBit(ZBit);  
51:  document.write("!  Z-Bit SET DEBUG: " + StatusRegister.toString(2) + "<br>");  
52:  document.write("!  Z-Bit SET? DEBUG: " + isBitNSet(StatusRegister, ZBit) + "<br>");  
53:  ClearStatusRegisterBit(ZBit);  
54:  document.write("!  Z-Bit CLEAR DEBUG: " + StatusRegister.toString(2) + "<br>");  
55:  document.write("!  Z-Bit SET? DEBUG: " + isBitNSet(StatusRegister, ZBit) + "<br>");  
56:  InitMemory ();  
57:  document.write(" " + memdump() + "<br>");  
58:  /*  
59:  toggle_bit(5);  
60:  document.write("!  DEBUG: " + get_bit_mask(5) + "<br>");  
61:  var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011  
62:  document.write("!  DEBUG: (mask)" + mask + " " + mask.toString(2) + "<br>");  
63:  */  
64:  </script>  
65:  </head>  
66:  <body>  
67:  </body>  
68:  </html>  


Source 2. bit_lib.js
1:  /*------------------------------------------------------------------------  
2:  * Name:    bit_lib.js  
3:  * Purpose:       javascript bit operator tools  
4:  *  
5:  * Author:   Michael Norton  
6:  *  
7:  * Created:   05/03/2015  
8:  * Copyright:  (c) Michael Norton 2015  
9:  * Licence:   <your licence>  
10:  *  
11:  * Notes:  
12:  *       Code based on bit hacks discussion at:  
13:  *  http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/  
14:  *  
15:  *------------------------------------------------------------------------*/  
16:  /*------------------------------------------------------------------------  
17:  * function: setbit (bitstring, bitposition)  
18:  *  
19:  * description:  
20:  *  This javascript function sets the individual bit in a bitstring at  
21:  *  at bitposition in the bitstring.  
22:  *  
23:  * Example: Set bit position 2 in bit string 01111000  
24:  *  
25:  *   01111000  (120 in binary)   argument: bitstring = 01111000  
26:  *  | 00000100  (1<<2)       argument: bitposition = 2  
27:  *   --------  
28:  *   01111100            returns: this value  
29:  *  
30:  * Arguments:  
31:  *  bitstring: the binary representation of the bits to be modified   
32:  *  bitposition: the n-th bit to set  
33:  *------------------------------------------------------------------------*/  
34:  function setbit(bitstring, bitposition) {  
35:   // set bit  
36:   // num | (1<<bit);  
37:   return bitstring | (1<<bitposition);  
38:  }   
39:  /*------------------------------------------------------------------------  
40:  * function: clearbit (bitstring, bitposition)  
41:  *  
42:  * description:  
43:  *  This javascript function clears the individual bit in a bitstring at  
44:  *  at bitposition in the bitstring.  
45:  *  
46:  * Example: Clear bit position 4 in bit string 01111111  
47:  *  
48:  *   01111111  (127 in binary)   argument: bitstring = 01111111  
49:  *  & 11101111  (~(1<<4))      argument: bitposition = 4  
50:  *   --------  
51:  *   01101111            returns: this value  
52:  *  
53:  * Arguments:  
54:  *  bitstring: the bit string to be modified   
55:  *  bitposition: the n-th bit to set  
56:  *------------------------------------------------------------------------*/  
57:  function clearbit(bitstring, bitposition) {  
58:   // unset bits  
59:   // num & ~(1<<bit);  
60:   return bitstring & ~(1<<bitposition);  
61:  }   
62:  /*------------------------------------------------------------------------  
63:  * function: isBitNSet (bitstring, bitposition)  
64:  *  
65:  * description:  
66:  *  This javascript function clears the individual bit in a bitstring at  
67:  *  at bitposition in the bitstring.  
68:  *  
69:  * Example: Test to see if bit position 0 in bit string 01100010 is set  
70:  *  
71:  *   01100010  (98 in binary) argument: bitstring = 01100010  
72:  * &  00000001          argument: bitposition = 0  
73:  *   --------  
74:  *   00000000          
75:  *  
76:  *  if (bitstring & (1<<bitposition)) {  
77:  *  n-th bit position is set  
78:  *  }  
79:  *  else {  
80:  *   n-th bit position is not set  
81:  *  }  
82:  *  
83:  * Arguments:  
84:  *  bitstring: the bit string to be modified   
85:  *  bitposition: the n-th bit to set  
86:  *  
87:  * Returns:  
88:  *  1 - if bit at bitposition is set. ZERO otherwise  
89:  *------------------------------------------------------------------------*/  
90:  function isBitNSet(bitstring, bitposition) {  
91:   if ( bitstring & (1<<bitposition) ) {  
92:        return 1;  
93:   }   
94:   // bit not set return FALSE!  
95:   return 0;  
96:  }   

Source 3. Tiny 6502 library


1:  /*-------------------------------------------------------------------------------  
2:  * Name:    cpu6502.js  
3:  * Purpose:       javascript Tiny 6502 processor emulator  
4:  *  
5:  * Author:   Michael Norton  
6:  *  
7:  * Created:   05/03/2015  
8:  * Copyright:  (c) Michael Norton 2015  
9:  * Licence:   <your licence>  
10:  *  
11:  * Notes:  
12:  * https://github.com/6502/js6502/blob/master/6502.js  
13:  *-------------------------------------------------------------------------------*/  
14:  // set the system memory to 8-bit with memsize of 65536 bytes  
15:  var MaxSystemMemory = 65536;  
16:  var mem8bit = new Uint8Array(MaxSystemMemory);  
17:  /*-------------------------------------------------------------------------------  
18:  *  
19:  *  
20:  *  6502 CPU Status Bit Register library  
21:  *  
22:  * notes: http://nesdev.com/6502.txt  
23:  * THE STATUS REGISTER  
24:  *  
25:  *  This register consists of eight "flags" (a flag = something that indi-  
26:  * cates whether something has, or has not occurred). Bits of this register  
27:  * are altered depending on the result of arithmetic and logical operations.  
28:  * These bits are described below:  
29:  *  
30:  *   Bit No.    7  6  5  4  3  2  1  0  
31:  *          S  V    B  D  I  Z  C  
32:  *  
33:  *  Bit0 - C - Carry flag: this holds the carry out of the most significant  
34:  *  bit in any arithmetic operation. In subtraction operations however, this  
35:  *  flag is cleared - set to 0 - if a borrow is required, set to 1 - if no  
36:  *  borrow is required. The carry flag is also used in shift and rotate  
37:  *  logical operations.  
38:  *  
39:  *  Bit1 - Z - Zero flag: this is set to 1 when any arithmetic or logical  
40:  *  operation produces a zero result, and is set to 0 if the result is  
41:  *  non-zero.  
42:  *  
43:  *  Bit 2 - I: this is an interrupt enable/disable flag. If it is set,  
44:  *  interrupts are disabled. If it is cleared, interrupts are enabled.  
45:  *  
46:  *  Bit 3 - D: this is the decimal mode status flag. When set, and an Add with  
47:  *  Carry or Subtract with Carry instruction is executed, the source values are  
48:  *  treated as valid BCD (Binary Coded Decimal, eg. 0x00-0x99 = 0-99) numbers.  
49:  *  The result generated is also a BCD number.  
50:  *  
51:  *  Bit 4 - B: this is set when a software interrupt (BRK instruction) is  
52:  *  executed.  
53:  *  
54:  *  Bit 5: not used. Supposed to be logical 1 at all times.  
55:  *  
56:  *  Bit 6 - V - Overflow flag: when an arithmetic operation produces a result  
57:  *  too large to be represented in a byte, V is set.  
58:  *  
59:  *  Bit 7 - S - Sign flag: this is set if the result of an operation is  
60:  *  negative, cleared if positive.  
61:  *  
62:  *  The most commonly used flags are C, Z, V, S.  
63:  *  
64:  *-------------------------------------------------------------------------------*/  
65:  var StatusRegister = 0;  
66:  var CBit = 0;  // Carry Flag   Bit 0  
67:  var ZBit = 1;  // Zero Flag   Bit 1  
68:  var IBit = 2;  // Interrupt Flag Bit 2  
69:  var DBit = 3;  // BCD Flag    Bit 3  - binary coded decimal  
70:  var BBit = 4;  // BRK Int Flag  Bit 4 - BRK instruction was executed  
71:  var NBit = 5;  // Not used    Bit 5 - not used, always set to 1  
72:  var VBit = 6;  // OVRFL Flag   Bit 6 - overflow flag  
73:  var SBit = 7;  // Sign flag   Bit 7 - set if result of operation is negative  
74:  /*-------------------------------------------------------------------------------  
75:  * function: SetStatusRegisterBit (bit_position)  
76:  *  
77:  * description:  
78:  *  This javascript function sets the individual bit flags   
79:  *  in the 6502 status register emulator.  
80:  *  
81:  *  CBit = 0;  // Carry Flag   Bit 0  
82:  *  ZBit = 1;  // Zero Flag   Bit 1  
83:  *  IBit = 2;  // Interrupt Flag Bit 2  
84:  *  DBit = 3;  // BCD Flag    Bit 3  - binary coded decimal  
85:  *  BBit = 4;  // BRK Int Flag  Bit 4 - BRK instruction was executed  
86:  *  NBit = 5;  // Not used    Bit 5 - not used, always set to 1  
87:  *  VBit = 6;  // OVRFL Flag   Bit 6 - overflow flag  
88:  *  SBit = 7;  // Sign flag   Bit 7 - set if result of operation is negative  
89:  *   
90:  * Example: Set ZBit in Status Register  
91:  *  
92:  *  SetStatusRegisterBit (Zbit);  
93:  *  ! Z-Bit SET DEBUG: 1111111100000010  
94:  *                  ^ Zbit set  
95:  *  
96:  * Arguments:  
97:  *  bit_position: the n-th bit to set (Processor flag bit position)  
98:  * Returns:  
99:  *  None - sets member variable StatusRegister  
100:  *-------------------------------------------------------------------------------*/  
101:  function SetStatusRegisterBit(bit_position){  
102:   StatusRegister = setbit(StatusRegister, bit_position);  
103:  }  
104:  /*-------------------------------------------------------------------------------  
105:  * function: ClearStatusRegisterBit (bit_position)  
106:  *  
107:  * description:  
108:  *  This javascript function clears the individual bit flags   
109:  *  in the 6502 status register emulator.  
110:  *  
111:  * Example: Clear ZBit in Status Register  
112:  *  
113:  *  ClearStatusRegisterBit (Zbit);  
114:  *  ! Z-Bit CLEAR DEBUG: 1111111100000000  
115:  *                   ^ Zbit clear  
116:  *  
117:  * Arguments:  
118:  *  bit_position: the n-th bit to set (Processor flag bit position)  
119:  * Returns:  
120:  *  None - sets member variable StatusRegister  
121:  *-------------------------------------------------------------------------------*/  
122:  function ClearStatusRegisterBit(bit_position) {  
123:       StatusRegister = clearbit(StatusRegister, bit_position);  
124:  }  
125:  /*-------------------------------------------------------------------------------  
126:  * function: IsStatusRegisterBitSet (bit_position)  
127:  *  
128:  * description:  
129:  *  This javascript function tests to see if the individual bit flags   
130:  *  in the 6502 status register emulator are set.  
131:  *  
132:  * Example: Test to see if ZBit in Status Register is set.  
133:  *  
134:  *  SetStatusRegisterBit (Zbit);  
135:  *  ! Z-Bit SET DEBUG: 1111111100000010  
136:  *                  ^ Zbit set  
137:  *  bZbitSet = IsStatusRegisterBitSet(Zbit);   
138:  *  ! Z-Bit SET? DEBUG: 1  
139:  *  
140:  *  ClearStatusRegisterBit (Zbit);  
141:  *  ! Z-Bit CLEAR DEBUG: 1111111100000000  
142:  *                   ^ Zbit clear  
143:  *  bZbitSet = IsStatusRegisterBitSet(Zbit);   
144:  *  ! Z-Bit SET? DEBUG: 0  
145:  *  
146:  * Arguments:  
147:  *  bit_position: the n-th bit to set (Processor flag bit position)  
148:  * Returns:  
149:  *  1 - if bit is set, ZERO otherwise  
150:  *-------------------------------------------------------------------------------*/  
151:  function IsStatusRegisterBitSet(bit_position) {  
152:       return isBitNSet(StatusRegister, bit_position);  
153:  }  
154:  /*************** TEST CODE *************/  
155:  function InitMemory () {  
156:       // 0000: start memory   
157:       mem8bit[0x0] = 0xa9;  
158:       mem8bit[0x1] = 0x0;  
159:       mem8bit[0x2] = 0x20;  
160:       mem8bit[0x3] = 0x10;  
161:       mem8bit[0x4] = 0x0;  
162:       mem8bit[0x5] = 0x4c;  
163:       mem8bit[0x6] = 0x02;  
164:       mem8bit[0x7] = 0x0;  
165:       mem8bit[0x8] = 0x0;  
166:       mem8bit[0x9] = 0x0;  
167:       mem8bit[0xa] = 0x0;  
168:       mem8bit[0xb] = 0x0;  
169:       mem8bit[0xc] = 0x0;  
170:       mem8bit[0xd] = 0x0;  
171:       mem8bit[0xe] = 0x0;  
172:       mem8bit[0xf] = 0x40;  
173:       //0010:  
174:       mem8bit[0x10] = 0xe8;  
175:       mem8bit[0x11] = 0x0;  
176:       mem8bit[0x12] = 0x20;  
177:       mem8bit[0x13] = 0x10;  
178:       mem8bit[0x14] = 0x0;  
179:       mem8bit[0x15] = 0x4c;  
180:       mem8bit[0x16] = 0x02;  
181:       mem8bit[0x17] = 0x0;  
182:       mem8bit[0x18] = 0x0;  
183:       mem8bit[0x19] = 0x0;  
184:       mem8bit[0x1a] = 0x0;  
185:       mem8bit[0x1b] = 0x0;  
186:       mem8bit[0x1c] = 0x0;  
187:       mem8bit[0x1d] = 0x0;  
188:       mem8bit[0x1e] = 0x0;  
189:       mem8bit[0x1f] = 0x40;  
190:  }  
191:  function memdump() {  
192:       var memdumpStr = "0000: ";  
193:       var memvalue = "";  
194:       for (memindex = 0; memindex < 32; memindex++) {  
195:            memvalue = mem8bit[memindex].toString(16);  
196:            if (memvalue == "0"){  
197:                 memvalue = "00"  
198:            }  
199:            memdumpStr = memdumpStr + " " + memvalue;  
200:       }  
201:       return memdumpStr;  
202:  }  

No comments:

Post a Comment