Preliminary CPU implementation
This commit is contained in:
		
							parent
							
								
									70f0f2a318
								
							
						
					
					
						commit
						94486ecf02
					
				| 
						 | 
					@ -291,7 +291,7 @@ let run = async function() {
 | 
				
			||||||
        if (!file.name.endsWith(".woff2"))
 | 
					        if (!file.name.endsWith(".woff2"))
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        let family = "/" + file.name;
 | 
					        let family = "/" + file.name;
 | 
				
			||||||
        family = family.substring(family.lastIndexOf("/") + 1, family.length - 6);
 | 
					        family = family.substring(family.lastIndexOf("/")+1, family.length-6);
 | 
				
			||||||
        let font = new FontFace(family, file.data);
 | 
					        let font = new FontFace(family, file.data);
 | 
				
			||||||
        await font.load();
 | 
					        await font.load();
 | 
				
			||||||
        document.fonts.add(font);
 | 
					        document.fonts.add(font);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										62
									
								
								core/bus.c
								
								
								
								
							
							
						
						
									
										62
									
								
								core/bus.c
								
								
								
								
							| 
						 | 
					@ -1,6 +1,10 @@
 | 
				
			||||||
/* This file is included into vb.c and cannot be compiled on its own. */
 | 
					/* This file is included into vb.c and cannot be compiled on its own. */
 | 
				
			||||||
#ifdef VBAPI
 | 
					#ifdef VBAPI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************** Utility Functions *****************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Read a data unit from a memory buffer */
 | 
					/* Read a data unit from a memory buffer */
 | 
				
			||||||
static int32_t busReadMemory(uint8_t *mem, int type) {
 | 
					static int32_t busReadMemory(uint8_t *mem, int type) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,31 +32,6 @@ static int32_t busReadMemory(uint8_t *mem, int type) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Read a data unit from the bus */
 | 
					 | 
				
			||||||
static int32_t busRead(VB *emu, uint32_t address, int type, int debug) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Force address alignment */
 | 
					 | 
				
			||||||
    address &= ~((uint32_t) TYPE_SIZES[type] - 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Process by address range */
 | 
					 | 
				
			||||||
    switch (address >> 24 & 7) {
 | 
					 | 
				
			||||||
        case 0 : return 0; /* VIP */
 | 
					 | 
				
			||||||
        case 1 : debug = debug; return 0; /* VSU */
 | 
					 | 
				
			||||||
        case 2 : return 0; /* Miscellaneous hardware */
 | 
					 | 
				
			||||||
        case 3 : return 0; /* Unmapped */
 | 
					 | 
				
			||||||
        case 4 : return 0; /* Game pak expansion */
 | 
					 | 
				
			||||||
        case 5 : return /* WRAM */
 | 
					 | 
				
			||||||
            busReadMemory(&emu->wram[address & 0xFFFF], type);
 | 
					 | 
				
			||||||
        case 6 : return emu->cart.sram == NULL ? 0 : /* Game pak RAM */
 | 
					 | 
				
			||||||
            busReadMemory(&emu->cart.sram
 | 
					 | 
				
			||||||
                [address & (emu->cart.sramSize - 1)], type);
 | 
					 | 
				
			||||||
        default: return emu->cart.rom  == NULL ? 0 : /* Game pak ROM */
 | 
					 | 
				
			||||||
            busReadMemory(&emu->cart.rom
 | 
					 | 
				
			||||||
                [address & (emu->cart.romSize  - 1)], type);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Write a data unit to a memory buffer */
 | 
					/* Write a data unit to a memory buffer */
 | 
				
			||||||
static void busWriteMemory(uint8_t *mem, int type, int32_t value) {
 | 
					static void busWriteMemory(uint8_t *mem, int type, int32_t value) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,7 +56,36 @@ static void busWriteMemory(uint8_t *mem, int type, int32_t value) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        mem[0] = value;
 | 
					        mem[0] = value;
 | 
				
			||||||
    #endif
 | 
					    #endif
 | 
				
			||||||
 
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************** Module Functions ******************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Read a data unit from the bus */
 | 
				
			||||||
 | 
					static int32_t busRead(VB *emu, uint32_t address, int type, int debug) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Force address alignment */
 | 
				
			||||||
 | 
					    address &= ~((uint32_t) TYPE_SIZES[type] - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Process by address range */
 | 
				
			||||||
 | 
					    switch (address >> 24 & 7) {
 | 
				
			||||||
 | 
					        case 0 : return 0; /* VIP */
 | 
				
			||||||
 | 
					        case 1 : debug = debug; return 0; /* VSU */
 | 
				
			||||||
 | 
					        case 2 : return 0; /* Miscellaneous hardware */
 | 
				
			||||||
 | 
					        case 3 : return 0; /* Unmapped */
 | 
				
			||||||
 | 
					        case 4 : return 0; /* Game pak expansion */
 | 
				
			||||||
 | 
					        case 5 : return /* WRAM */
 | 
				
			||||||
 | 
					            busReadMemory(&emu->wram[address & 0xFFFF], type);
 | 
				
			||||||
 | 
					        case 6 : return emu->cart.sram == NULL ? 0 : /* Game pak RAM */
 | 
				
			||||||
 | 
					            busReadMemory(&emu->cart.sram
 | 
				
			||||||
 | 
					                [address & (emu->cart.sramSize - 1)], type);
 | 
				
			||||||
 | 
					        default: return emu->cart.rom  == NULL ? 0 : /* Game pak ROM */
 | 
				
			||||||
 | 
					            busReadMemory(&emu->cart.rom
 | 
				
			||||||
 | 
					                [address & (emu->cart.romSize  - 1)], type);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Write a data unit to the bus */
 | 
					/* Write a data unit to the bus */
 | 
				
			||||||
| 
						 | 
					@ -110,4 +118,6 @@ static void busWrite(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* VBAPI */
 | 
					#endif /* VBAPI */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1589
									
								
								core/cpu.c
								
								
								
								
							
							
						
						
									
										1589
									
								
								core/cpu.c
								
								
								
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										144
									
								
								core/vb.c
								
								
								
								
							
							
						
						
									
										144
									
								
								core/vb.c
								
								
								
								
							| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
#define VBAPI
 | 
					#define VBAPI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Header includes */
 | 
					/* Header includes */
 | 
				
			||||||
 | 
					#include <float.h>
 | 
				
			||||||
#include <vb.h>
 | 
					#include <vb.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +16,7 @@ static const uint8_t TYPE_SIZES[] = { 1, 1, 2, 2, 4 };
 | 
				
			||||||
/********************************** Macros ***********************************/
 | 
					/********************************** Macros ***********************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Sign-extend a value of some number of bits to 32 bits */
 | 
					/* Sign-extend a value of some number of bits to 32 bits */
 | 
				
			||||||
#define SignExtend(v,b) ( (v) | (((v) & 1 << b - 1) ? ~(int32_t)0 << b : 0) )
 | 
					#define SignExtend(v,b) ((v) | (((v) & ((1<<(b)) - 1)) ? ~(int32_t)0<<(b) : 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,11 +24,78 @@ static const uint8_t TYPE_SIZES[] = { 1, 1, 2, 2, 4 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Component includes */
 | 
					/* Component includes */
 | 
				
			||||||
#include "bus.c"
 | 
					#include "bus.c"
 | 
				
			||||||
 | 
					#include "cpu.c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************** Module Functions ******************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Process a simulation for some number of clocks */
 | 
				
			||||||
 | 
					static int sysEmulate(VB *emu, uint32_t clocks) {
 | 
				
			||||||
 | 
					    int broke;
 | 
				
			||||||
 | 
					    broke = cpuEmulate(emu, clocks);
 | 
				
			||||||
 | 
					    return broke;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Determine the number of clocks before a break condititon could occur */
 | 
				
			||||||
 | 
					static uint32_t sysUntil(VB *emu, uint32_t clocks) {
 | 
				
			||||||
 | 
					    clocks = cpuUntil(emu, clocks);
 | 
				
			||||||
 | 
					    return clocks;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/******************************* API Functions *******************************/
 | 
					/******************************* API Functions *******************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Associate two simulations as peers */
 | 
				
			||||||
 | 
					void vbConnect(VB *emu1, VB *emu2) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Disconnect any existing link associations */
 | 
				
			||||||
 | 
					    if (emu1->peer != NULL && emu1->peer != emu2)
 | 
				
			||||||
 | 
					        emu1->peer->peer = NULL;
 | 
				
			||||||
 | 
					    if (emu2->peer != NULL && emu2->peer != emu1)
 | 
				
			||||||
 | 
					        emu2->peer->peer = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Link the two simulations */
 | 
				
			||||||
 | 
					    emu1->peer = emu2;
 | 
				
			||||||
 | 
					    emu2->peer = emu1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Disassociate linked peers */
 | 
				
			||||||
 | 
					void vbDisconnect(VB *emu) {
 | 
				
			||||||
 | 
					    if (emu->peer != NULL)
 | 
				
			||||||
 | 
					        emu->peer->peer = NULL;
 | 
				
			||||||
 | 
					    emu->peer = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Process one or two simulations */
 | 
				
			||||||
 | 
					int vbEmulate(VB *emu1, VB *emu2, uint32_t *clocks) {
 | 
				
			||||||
 | 
					    int      broke; /* The simulation requested an application break */
 | 
				
			||||||
 | 
					    uint32_t until; /* Maximum clocks before a break could happen */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Processing one simulaiton */
 | 
				
			||||||
 | 
					    if (emu2 == NULL) {
 | 
				
			||||||
 | 
					        do {
 | 
				
			||||||
 | 
					            until    = sysUntil  (emu1, *clocks);
 | 
				
			||||||
 | 
					            broke    = sysEmulate(emu1, until  );
 | 
				
			||||||
 | 
					            *clocks -= until;
 | 
				
			||||||
 | 
					        } while (!broke && *clocks > 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Processing two simulations */
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        do {
 | 
				
			||||||
 | 
					            until    = sysUntil  (emu1, *clocks);
 | 
				
			||||||
 | 
					            until    = sysUntil  (emu2, until  );
 | 
				
			||||||
 | 
					            broke    = sysEmulate(emu1, until  );
 | 
				
			||||||
 | 
					            broke   |= sysEmulate(emu2, until  );
 | 
				
			||||||
 | 
					            *clocks -= until;
 | 
				
			||||||
 | 
					        } while (!broke && *clocks > 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return broke;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Retrieve the value of PC */
 | 
					/* Retrieve the value of PC */
 | 
				
			||||||
uint32_t vbGetProgramCounter(VB *emu, int type) {
 | 
					uint32_t vbGetProgramCounter(VB *emu, int type) {
 | 
				
			||||||
    switch (type) {
 | 
					    switch (type) {
 | 
				
			||||||
| 
						 | 
					@ -97,13 +165,23 @@ uint32_t vbGetSystemRegister(VB *emu, int id) {
 | 
				
			||||||
/* Prepare a simulation state instance for use */
 | 
					/* Prepare a simulation state instance for use */
 | 
				
			||||||
void vbInit(VB *emu) {
 | 
					void vbInit(VB *emu) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Breakpoint callbacks */
 | 
				
			||||||
 | 
					    emu->onException = NULL;
 | 
				
			||||||
 | 
					    emu->onExecute   = NULL;
 | 
				
			||||||
 | 
					    emu->onFetch     = NULL;
 | 
				
			||||||
 | 
					    emu->onRead      = NULL;
 | 
				
			||||||
 | 
					    emu->onWrite     = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* System */
 | 
				
			||||||
 | 
					    emu->peer = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Cartridge */
 | 
					    /* Cartridge */
 | 
				
			||||||
    emu->cart.rom      = NULL;
 | 
					    emu->cart.rom      = NULL;
 | 
				
			||||||
    emu->cart.romSize  = 0;
 | 
					    emu->cart.romSize  = 0;
 | 
				
			||||||
    emu->cart.sram     = NULL;
 | 
					    emu->cart.sram     = NULL;
 | 
				
			||||||
    emu->cart.sramSize = 0;
 | 
					    emu->cart.sramSize = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* All others */
 | 
					    /* Everything else */
 | 
				
			||||||
    vbReset(emu);
 | 
					    vbReset(emu);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,7 +196,7 @@ void vbReset(VB *emu) {
 | 
				
			||||||
    uint32_t x; /* Iterator */
 | 
					    uint32_t x; /* Iterator */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* CPU registers */
 | 
					    /* CPU registers */
 | 
				
			||||||
    emu->cpu.pc = 0xFFFFFFF0;
 | 
					    vbSetProgramCounter(emu,         0xFFFFFFF0);
 | 
				
			||||||
    vbSetSystemRegister(emu, VB_ECR, 0x0000FFF0);
 | 
					    vbSetSystemRegister(emu, VB_ECR, 0x0000FFF0);
 | 
				
			||||||
    vbSetSystemRegister(emu, VB_PSW, 0x00008000);
 | 
					    vbSetSystemRegister(emu, VB_PSW, 0x00008000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -132,8 +210,19 @@ void vbReset(VB *emu) {
 | 
				
			||||||
    emu->cpu.fepsw  = 0x00000000;
 | 
					    emu->cpu.fepsw  = 0x00000000;
 | 
				
			||||||
    emu->cpu.sr29   = 0x00000000;
 | 
					    emu->cpu.sr29   = 0x00000000;
 | 
				
			||||||
    emu->cpu.sr31   = 0x00000000;
 | 
					    emu->cpu.sr31   = 0x00000000;
 | 
				
			||||||
    emu->cpu.pcFrom = 0xFFFFFFF0;
 | 
					
 | 
				
			||||||
    emu->cpu.pcTo   = 0xFFFFFFF0;
 | 
					    /* History tracking */
 | 
				
			||||||
 | 
					    emu->cpu.eipcFrom = 0xFFFFFFF0;
 | 
				
			||||||
 | 
					    emu->cpu.eipcTo   = 0xFFFFFFF0;
 | 
				
			||||||
 | 
					    emu->cpu.fepcFrom = 0xFFFFFFF0;
 | 
				
			||||||
 | 
					    emu->cpu.fepcTo   = 0xFFFFFFF0;
 | 
				
			||||||
 | 
					    emu->cpu.pcFrom   = 0xFFFFFFF0;
 | 
				
			||||||
 | 
					    emu->cpu.pcTo     = 0xFFFFFFF0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Other CPU state */
 | 
				
			||||||
 | 
					    emu->cpu.state = CPU_FETCH;
 | 
				
			||||||
 | 
					    for (x = 0; x < 5; x++)
 | 
				
			||||||
 | 
					        emu->cpu.irq[x] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* WRAM (the hardware does not do this) */
 | 
					    /* WRAM (the hardware does not do this) */
 | 
				
			||||||
    for (x = 0; x < 0x10000; x++)
 | 
					    for (x = 0; x < 0x10000; x++)
 | 
				
			||||||
| 
						 | 
					@ -142,9 +231,11 @@ void vbReset(VB *emu) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Specify a new value for PC */
 | 
					/* Specify a new value for PC */
 | 
				
			||||||
uint32_t vbSetProgramCounter(VB *emu, uint32_t value) {
 | 
					uint32_t vbSetProgramCounter(VB *emu, uint32_t value) {
 | 
				
			||||||
    value &= 0xFFFFFFFE;
 | 
					    value             &= 0xFFFFFFFE;
 | 
				
			||||||
    emu->cpu.pc = value;
 | 
					    emu->cpu.fetch     = 0;
 | 
				
			||||||
    /* Set stage to fecth=0 */
 | 
					    emu->cpu.pc        = value;
 | 
				
			||||||
 | 
					    emu->cpu.state     = CPU_FETCH;
 | 
				
			||||||
 | 
					    emu->cpu.substring = 0;
 | 
				
			||||||
    return value;
 | 
					    return value;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -181,42 +272,7 @@ int vbSetSRAM(VB *emu, void *sram, uint32_t size) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Specify a new value for a system register */
 | 
					/* Specify a new value for a system register */
 | 
				
			||||||
uint32_t vbSetSystemRegister(VB *emu, int id, uint32_t value) {
 | 
					uint32_t vbSetSystemRegister(VB *emu, int id, uint32_t value) {
 | 
				
			||||||
    switch (id) {
 | 
					    return cpuSetSystemRegister(emu, id, value, 1);
 | 
				
			||||||
        case VB_ADTRE: return emu->cpu.adtre = value & 0xFFFFFFFE;
 | 
					 | 
				
			||||||
        case VB_EIPC : return emu->cpu.eipc  = value & 0xFFFFFFFE;
 | 
					 | 
				
			||||||
        case VB_EIPSW: return emu->cpu.eipsw = value & 0x000FF3FF;
 | 
					 | 
				
			||||||
        case VB_FEPC : return emu->cpu.fepc  = value & 0xFFFFFFFE;
 | 
					 | 
				
			||||||
        case VB_FEPSW: return emu->cpu.fepsw = value & 0x000FF3FF;
 | 
					 | 
				
			||||||
        case VB_PIR  : return 0x00005346;
 | 
					 | 
				
			||||||
        case VB_TKCW : return 0x000000E0;
 | 
					 | 
				
			||||||
        case 29      : return emu->cpu.sr29  = value & 0x00000001;
 | 
					 | 
				
			||||||
        case 31      : return emu->cpu.sr31  = value;
 | 
					 | 
				
			||||||
        case VB_CHCW :
 | 
					 | 
				
			||||||
            emu->cpu.chcw.ice = value >> 1 & 1;
 | 
					 | 
				
			||||||
            return value & 0x00000002;
 | 
					 | 
				
			||||||
        case VB_ECR  :
 | 
					 | 
				
			||||||
            emu->cpu.ecr.fecc = value >> 16;
 | 
					 | 
				
			||||||
            emu->cpu.ecr.eicc = value;
 | 
					 | 
				
			||||||
            return value;
 | 
					 | 
				
			||||||
        case VB_PSW  :
 | 
					 | 
				
			||||||
            emu->cpu.psw.i   = value >> 16 & 15;
 | 
					 | 
				
			||||||
            emu->cpu.psw.np  = value >> 15 &  1;
 | 
					 | 
				
			||||||
            emu->cpu.psw.ep  = value >> 14 &  1;
 | 
					 | 
				
			||||||
            emu->cpu.psw.ae  = value >> 13 &  1;
 | 
					 | 
				
			||||||
            emu->cpu.psw.id  = value >> 12 &  1;
 | 
					 | 
				
			||||||
            emu->cpu.psw.fro = value >>  9 &  1;
 | 
					 | 
				
			||||||
            emu->cpu.psw.fiv = value >>  8 &  1;
 | 
					 | 
				
			||||||
            emu->cpu.psw.fzd = value >>  7 &  1;
 | 
					 | 
				
			||||||
            emu->cpu.psw.fov = value >>  6 &  1;
 | 
					 | 
				
			||||||
            emu->cpu.psw.fud = value >>  5 &  1;
 | 
					 | 
				
			||||||
            emu->cpu.psw.fpr = value >>  4 &  1;
 | 
					 | 
				
			||||||
            emu->cpu.psw.cy  = value >>  3 &  1;
 | 
					 | 
				
			||||||
            emu->cpu.psw.ov  = value >>  2 &  1;
 | 
					 | 
				
			||||||
            emu->cpu.psw.s   = value >>  1 &  1;
 | 
					 | 
				
			||||||
            emu->cpu.psw.z   = value       &  1;
 | 
					 | 
				
			||||||
            return value & 0x000FF3FF;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Write a data unit to the bus */
 | 
					/* Write a data unit to the bus */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										76
									
								
								core/vb.h
								
								
								
								
							
							
						
						
									
										76
									
								
								core/vb.h
								
								
								
								
							| 
						 | 
					@ -18,11 +18,12 @@ extern "C" {
 | 
				
			||||||
/********************************* Constants *********************************/
 | 
					/********************************* Constants *********************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Memory access types */
 | 
					/* Memory access types */
 | 
				
			||||||
#define VB_S8  0
 | 
					#define VB_CANCEL -1
 | 
				
			||||||
#define VB_U8  1
 | 
					#define VB_S8      0
 | 
				
			||||||
#define VB_S16 2
 | 
					#define VB_U8      1
 | 
				
			||||||
#define VB_U16 3
 | 
					#define VB_S16     2
 | 
				
			||||||
#define VB_S32 4
 | 
					#define VB_U16     3
 | 
				
			||||||
 | 
					#define VB_S32     4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* System register IDs */
 | 
					/* System register IDs */
 | 
				
			||||||
#define VB_ADTRE 25
 | 
					#define VB_ADTRE 25
 | 
				
			||||||
| 
						 | 
					@ -45,8 +46,38 @@ extern "C" {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*********************************** Types ***********************************/
 | 
					/*********************************** Types ***********************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Simulation state */
 | 
					/* Forward references */
 | 
				
			||||||
typedef struct VB VB;
 | 
					typedef struct VB VB;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Memory access */
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    uint32_t address; /* Bus address being accessed */
 | 
				
			||||||
 | 
					    uint32_t clocks;  /* Number of clocks required to complete */
 | 
				
			||||||
 | 
					    int32_t  value;   /* Value read (callback's responsibility) or to write */
 | 
				
			||||||
 | 
					    int8_t   type;    /* Data type of value */
 | 
				
			||||||
 | 
					} VB_ACCESS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* CPU instruction */
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Public fields */
 | 
				
			||||||
 | 
					    uint32_t address; /* Bus address */
 | 
				
			||||||
 | 
					    uint16_t bits[2]; /* Binary instruction code */
 | 
				
			||||||
 | 
					    uint8_t  size;    /* Size in bytes of the instruction */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Implementation fields */
 | 
				
			||||||
 | 
					    int32_t aux[2]; /* Auxiliary storage for CAXI and bit strings */
 | 
				
			||||||
 | 
					    uint8_t id;     /* Internal operation ID */
 | 
				
			||||||
 | 
					} VB_INSTRUCTION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Breakpoint callbacks */
 | 
				
			||||||
 | 
					typedef int (*VB_EXCEPTIONPROC)(VB *, uint16_t);
 | 
				
			||||||
 | 
					typedef int (*VB_EXECUTEPROC  )(VB *, VB_INSTRUCTION *);
 | 
				
			||||||
 | 
					typedef int (*VB_FETCHPROC    )(VB *, int, VB_ACCESS *);
 | 
				
			||||||
 | 
					typedef int (*VB_READPROC     )(VB *, VB_ACCESS *);
 | 
				
			||||||
 | 
					typedef int (*VB_WRITEPROC    )(VB *, VB_ACCESS *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Simulation state */
 | 
				
			||||||
struct VB {
 | 
					struct VB {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Game pak */
 | 
					    /* Game pak */
 | 
				
			||||||
| 
						 | 
					@ -101,17 +132,37 @@ struct VB {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Other registers */
 | 
					        /* Other registers */
 | 
				
			||||||
        uint32_t pc;          /* Program counter */
 | 
					        uint32_t pc;          /* Program counter */
 | 
				
			||||||
        uint32_t pcFrom;      /* Source of most recent jump */
 | 
					 | 
				
			||||||
        uint32_t pcTo;        /* Destination of most recent jump */
 | 
					 | 
				
			||||||
        int32_t  program[32]; /* program registers */
 | 
					        int32_t  program[32]; /* program registers */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* History tracking */
 | 
				
			||||||
 | 
					        uint32_t eipcFrom; /* Source of most recent jump */
 | 
				
			||||||
 | 
					        uint32_t eipcTo;   /* Destination of most recent jump */
 | 
				
			||||||
 | 
					        uint32_t fepcFrom; /* Source of most recent jump */
 | 
				
			||||||
 | 
					        uint32_t fepcTo;   /* Destination of most recent jump */
 | 
				
			||||||
 | 
					        uint32_t pcFrom;   /* Source of most recent jump */
 | 
				
			||||||
 | 
					        uint32_t pcTo;     /* Destination of most recent jump */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Other fields */
 | 
					        /* Other fields */
 | 
				
			||||||
        uint32_t clocks; /* Clocks until next action */
 | 
					        VB_ACCESS      access;    /* Memory access descriptor */
 | 
				
			||||||
        uint8_t  fetch;  /* Index of fetch unit */
 | 
					        VB_INSTRUCTION inst;      /* Instruction descriptor */
 | 
				
			||||||
        uint8_t  state;  /* Operations state */
 | 
					        uint8_t        irq[5];    /* Interrupt request lines */
 | 
				
			||||||
 | 
					        uint8_t        busWait;   /* Waiting on a memory access */
 | 
				
			||||||
 | 
					        uint16_t       causeCode; /* Exception cause code */
 | 
				
			||||||
 | 
					        uint32_t       clocks;    /* Clocks until next action */
 | 
				
			||||||
 | 
					        int16_t        fetch;     /* Index of fetch unit */
 | 
				
			||||||
 | 
					        uint8_t        state;     /* Operations state */
 | 
				
			||||||
 | 
					        uint8_t        substring; /* A bit string operation is in progress */
 | 
				
			||||||
    } cpu;
 | 
					    } cpu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Breakpoint callbacks */
 | 
				
			||||||
 | 
					    VB_EXCEPTIONPROC onException; /* CPU exception */
 | 
				
			||||||
 | 
					    VB_EXECUTEPROC   onExecute;   /* Instruction execute */
 | 
				
			||||||
 | 
					    VB_FETCHPROC     onFetch;     /* Instruction fetch */
 | 
				
			||||||
 | 
					    VB_READPROC      onRead;      /* Memory read */
 | 
				
			||||||
 | 
					    VB_WRITEPROC     onWrite;     /* Memory write */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Other fields */
 | 
					    /* Other fields */
 | 
				
			||||||
 | 
					    VB     *peer;          /* Communications peer */
 | 
				
			||||||
    uint8_t wram[0x10000]; /* Main memory */
 | 
					    uint8_t wram[0x10000]; /* Main memory */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,6 +170,9 @@ struct VB {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**************************** Function Prototypes ****************************/
 | 
					/**************************** Function Prototypes ****************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VBAPI void     vbConnect            (VB *emu1, VB *emu2);
 | 
				
			||||||
 | 
					VBAPI void     vbDisconnect         (VB *emu);
 | 
				
			||||||
 | 
					VBAPI int      vbEmulate            (VB *emu1, VB *emu2, uint32_t *clocks);
 | 
				
			||||||
VBAPI uint32_t vbGetProgramCounter  (VB *emu, int type);
 | 
					VBAPI uint32_t vbGetProgramCounter  (VB *emu, int type);
 | 
				
			||||||
VBAPI int32_t  vbGetProgramRegister (VB *emu, int id);
 | 
					VBAPI int32_t  vbGetProgramRegister (VB *emu, int id);
 | 
				
			||||||
VBAPI void*    vbGetROM             (VB *emu, uint32_t *size);
 | 
					VBAPI void*    vbGetROM             (VB *emu, uint32_t *size);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
Copyright (C) 2021 Planet Virtual Boy
 | 
					Copyright (C) 2021 Guy Perfect
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This software is provided 'as-is', without any express or implied
 | 
					This software is provided 'as-is', without any express or implied
 | 
				
			||||||
warranty.  In no event will the authors be held liable for any damages
 | 
					warranty.  In no event will the authors be held liable for any damages
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								makefile
								
								
								
								
							
							
						
						
									
										2
									
								
								makefile
								
								
								
								
							| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
.PHONY: help
 | 
					.PHONY: help
 | 
				
			||||||
help:
 | 
					help:
 | 
				
			||||||
	@echo
 | 
						@echo
 | 
				
			||||||
	@echo "Virtual Boy Emulator - September 10, 2021"
 | 
						@echo "Virtual Boy Emulator - September 18, 2021"
 | 
				
			||||||
	@echo
 | 
						@echo
 | 
				
			||||||
	@echo "Target build environment is any Debian with the following packages:"
 | 
						@echo "Target build environment is any Debian with the following packages:"
 | 
				
			||||||
	@echo "  emscripten"
 | 
						@echo "  emscripten"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue