All pastes #112537 Raw Edit

p

public text v1 · immutable
·published 2006-08-03 00:29 UTC
rendered paste body
#import <fcntl.h>                       // For open()
#import <sys/types.h>
#import <sys/stat.h>                    // For fstat() "to get he file length"
#import <sys/mman.h>                    // For mmap()
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
#import <unistd.h>                      // close()

//#ifdef HAVE_DEBUG
#define DEBUG_PRINT(format , ... ) printf ( "[DEBUG " __FILE__ ":%d] " format "\n" , __LINE__, ## __VA_ARGS__ );
//#else
//#define DEBUG_PRINT( format , args... )
//#endif

#define bswap16(x) (((((short)(x)) >> 8) & 0xff) | ((((short)(x)) & 0xff) << 8))
#define n1(x) (x&0xF000>>12)
#define n2(x) (x&0x0F00>> 8)
#define n3(x) (x&0x00F0>> 4)
#define n4(x) (x&0x000F    )

void process8(short opcode);
void dumpreg(void);

unsigned char V[16];    // CPU registers
unsigned short *rom;    // rom file
unsigned short opcode;  // current opcode
unsigned int ip;        // instruction pointer

int main(int a, char**b)
{
        int fd;
        struct stat statbuf;     // for the file length

        fd = open("Chip8Test",O_RDONLY);
        if (fd == -1) return 1;  //TODO return value explanation

        fstat(fd,&statbuf);
        rom = mmap(NULL, statbuf.st_size , PROT_READ, MAP_PRIVATE, fd, 0);
        if (rom == MAP_FAILED) return 3;

        DEBUG_PRINT("Opened and mmap()'d rom file");

        while ( 1 )
        {
                short type;

                memcpy(&opcode,rom +ip,2);
                opcode = bswap16(opcode);
                type = opcode & 0xF000;

                /* parse the opcode here */
                switch(type) {
                        case 0x8000 : process8(opcode);
                        case 0x1000 : ip = (opcode & 0x0FFF) -1 ; break;                //1NNN Jump to the address NNN of the file
                        case 0x3000 :if(V[n2(opcode)]== (opcode&0x00FF)) ip++; break;   //3XKK Skip next instruction if VX == KK
                        case 0x6000 : V[ n2(opcode) ] = (opcode&0x00FF); break;         //6XKK VX = KK
                        case 0x7000 : V[ n2(opcode) ]+= (opcode&0x00FF); break;         //7XKK VX = VX + KK
                        case 0xC000 : V[ n2(opcode) ] = rand() + (opcode&0x00FF); break;//CXKK VX = Random number AND KK
                        case 0x0000 : goto out;
                        default : DEBUG_PRINT("Unknown opcode ip:%d opcode:%x",ip,opcode)

                }
                ip++;
        }
out:
        /* Dump the registers */
        dumpreg();
        // cleanup
        munmap(rom,statbuf.st_size);
        close(fd);
        return 0;
}

void process8(short opcode)
{
        short type = opcode & 0x000F;
        /* parse the opcode here */
        switch(type) {
                case 0 : V[ n2(opcode) ]  = V[ n3(opcode) ]; break;     //8XY0 VX = VY
                case 1 : V[ n2(opcode) ] |= V[ n3(opcode) ]; break;     //8XY1 VX = VX OR VY
                case 2 : V[ n2(opcode) ] &= V[ n3(opcode) ]; break;     //8XY2 VX = VX AND VY
                case 3 : V[ n2(opcode) ] ^= V[ n3(opcode) ]; break;     //8XY3 VX = VX XOR VY
                case 4 : V[ n2(opcode) ] += V[ n3(opcode) ];            //8XY4 VX = VX + VY,
                        if ( V[ n2(opcode) ] < V[ n3(opcode) ] )        //      Sets VF to 1 if there is a carry, 0 if there isn't
                                V[15] = 1;
                        else
                                V[15] = 0;
                        break;
                case 5 : V[ n2(opcode) ] -= V[ n3(opcode) ];            //8XY5 VX = VX - VY,
                         if ( V[ n2(opcode) ] > V[ n3(opcode) ] )       //      VF is set to 0 if there is a borrow, 1 if there isn't.
                                 V[15] = 0;
                         else
                                 V[15] = 1;
                         break;
                case 6 : V[15] = opcode&0x0001; V[ n2(opcode) ] >>= 1; break;   //8X06 VX = VX SHIFT RIGHT 1, VF is set to the lost bit.
                case 7 : V[ n2(opcode) ] = V[ n3(opcode) ] - V[ n2(opcode) ];   //8XY7 VX = VY - VX,
                         if ( V[ n2(opcode) ] < V[ n3(opcode) ] )               //      VF is set to 0 if there is a borrow, 1 if there isn't.
                                V[15] = 0;
                         else
                                V[15] = 1;
                         break;
                case 0xE: V[15] = opcode&0x8000; V[ n2(opcode) ] <<= 1; break;  //8X0E VX = VX SHIFT LEFT 1 , VF is set to the lost bit.
                default : DEBUG_PRINT("Unknown opcode ip:%d opcode:%x",ip,opcode)
        }
}

void dumpreg(void)
{
        int i;
        for(i=0; i<16; i++)
                printf("Register V%x : 0x%x\n",i,V[i]);
}