⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irobot.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************

  machine.c

  Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
  I/O ports)

***************************************************************************/

#include "driver.h"
#include "cpuintrf.h"

extern void run_video(void);
extern void irobot_poly_clear(void);
extern int irvg_running;

unsigned char *irobot_nvRAM;
extern unsigned char *comRAM1,*comRAM2,*mbRAM,*mbROM;
static unsigned char irobot_control_num = 0;
static unsigned char irobot_statwr;
static unsigned char irobot_out0;
static unsigned char irobot_outx,irobot_mpage;

unsigned char irobot_comswap;
unsigned char irobot_bufsel;
unsigned char irobot_alphamap;

/* I-Robot Mathbox

    Based on 4 2901 chips slice processors connected to form a 16-bit ALU

    Microcode roms:
    6N: bits 0..3: Address of ALU A register
    5P: bits 0..3: Address of ALU B register
    6M: bits 0..3: ALU Function bits 5..8
    7N: bits 0..3: ALU Function bits 1..4
    8N: bits 0,1: Memory write timing
        bit 2: Hardware multiply mode
        bit 3: ALU Function bit 0
    6P: bits 0,1: Direct addressing bits 0,1
        bits 2,3: Jump address bits 0,1
    8M: bits 0..3: Jump address bits 6..9
    9N: bits 0..3: Jump address bits 2..5
    8P: bits 0..3: Memory address bits 2..5
    9M: bit 0: Shift control
        bits 1..3: Jump type
            0 = No Jump
            1 = On carry
            2 = On zero
            3 = On positive
            4 = On negative
            5 = Unconditional
            6 = Jump to Subroutine
            7 = Return from Subroutine
    7M: Bit 0: Mathbox memory enable
        Bit 1: Latch data to address bus
        Bit 2: Carry in select
        Bit 3: Carry in value
        (if 2,3 = 11 then mathbox is done)
    9P: Bit 0: Hardware divide enable
        Bits 1,2: Memory select
        Bit 3: Memory R/W
    7P: Bits 0,1: Direct addressing bits 6,7
        Bits 2,3: Unused
*/

/* Mathbox variable */

int irmb_running;
static int irmb_PC;
static int irmb_oldPC;

static unsigned int irmb_Q;
static unsigned int irmb_F;
static unsigned int irmb_Y;
static unsigned int irmb_regs[16];
static unsigned int irmb_stack[16];

static int irmb_sp;
static unsigned int irmb_pmadd;
static unsigned int irmb_latch;

static unsigned char irmb_nflag;
static unsigned char irmb_vflag;
static unsigned char irmb_cflag;
static unsigned char irmb_zflag;
static unsigned char irmb_CI;

#define FL_MULT	0x01
#define FL_shift 0x02
#define FL_MBMEMDEC 0x04
#define FL_ADDEN 0x08
#define FL_DPSEL 0x10
#define FL_carry 0x20
#define FL_DIV 0x40
#define FL_MBRW 0x80

/* flags:
	0: MULT
	1: Shift control
	2: MBMEMDEC
	3: ADDEN
	4: DPSEL
	5: Carry
	6: DIV
	7: MBR/W
*/

typedef struct {
    unsigned char areg;
    unsigned char breg;
	int func;
	unsigned int flags;
    unsigned char diradd;
	int nxtadd;
    unsigned char mab;
    unsigned char jtype;
    unsigned char ramsel;
} irmb_ops;

irmb_ops mbops[1024];

int irmb_exec(void);

unsigned int irmb_din(void) {
    unsigned int d=0;
	unsigned int ad;
	int diren;

    if (!(mbops[irmb_PC].flags & FL_MBMEMDEC) && (mbops[irmb_PC].flags & FL_MBRW)) {

        if (mbops[irmb_PC].ramsel == 0) {  /* DIREN = 1 */
			diren = 1;
            ad = mbops[irmb_PC].mab << 2;
            ad = ad | (mbops[irmb_PC].diradd & 0xC0);
            ad = ad | (irmb_latch & 0x1000);
		}
		else { 							 /* DIREN = 0 */
			diren = 0;
            ad = irmb_latch & 0x1FF8;
            ad = ad | (irmb_pmadd & 0x04);
		}

        if (mbops[irmb_PC].ramsel & 0x02)
            ad = ad | (irmb_pmadd & 0x03);
		else
            ad = ad | (mbops[irmb_PC].diradd & 0x03);

        if (diren == 1 || (irmb_latch & 0x6000) == 0) {   /* MB RAM read */
			ad = (ad & 0xFFF) << 1;
			d = (mbRAM[ad] << 8) | mbRAM[ad+1];
		}
		else {			/* MB ROM read */
			ad = (ad & 0x1FFF) << 1;
            if (irmb_latch & 0x4000) {  /* CEMATH = 1 */
                if (irmb_latch & 0x2000)
					d = (mbROM[ad+0x8000] << 8) | mbROM[ad+0x8001];
				else
					d = (mbROM[ad+0x4000] << 8) | mbROM[ad+0x4001];
			}
			else {  /* CEMATH = 0 */
					d = (mbROM[ad] << 8) | mbROM[ad+1];
			}
		}
	}
	return d;
}

void irmb_dout(unsigned int d) {
	unsigned int ad;
	int diren;

	/* Write to video com ram */
    if (mbops[irmb_PC].ramsel == 3) {
        ad = irmb_latch & 0x1FF8;
        ad = ad | (irmb_pmadd & 0x07);
		ad = (ad & 0x7FF) << 1;
        if (irobot_comswap) {
			comRAM2[ad] = (d & 0xFF00) >> 8;
			comRAM2[ad+1] = d & 0x00FF;
		}
		else {
			comRAM1[ad] = (d & 0xFF00) >> 8;
			comRAM1[ad+1] = d & 0x00FF;
		}
	}

	/* Write to mathox ram */
    if (!(mbops[irmb_PC].flags & FL_MBMEMDEC)) {
        if (mbops[irmb_PC].ramsel == 0) {  /* DIREN = 1 */
			diren = 1;
            ad = mbops[irmb_PC].mab << 2;
            ad = ad | (mbops[irmb_PC].diradd & 0xC0);
            ad = ad | (irmb_latch & 0x1000);
		}
		else { 							 /* DIREN = 0 */
			diren = 0;
            ad = irmb_latch & 0x1FF8;
            ad = ad | (irmb_pmadd & 0x04);
		}

        if (mbops[irmb_PC].ramsel & 0x02)
            ad = ad | (irmb_pmadd & 0x03);
		else
            ad = ad | (mbops[irmb_PC].diradd & 0x03);

		ad = (ad & 0xFFF) << 1;
        if (diren == 1 || (irmb_latch & 0x6000) == 0) {   /* MB RAM write */
			mbRAM[ad] = (d & 0xFF00) >> 8;
			mbRAM[ad+1] = (d & 0x00FF);
		}
	}
}

/* Convert microcode roms to a more usable form */

void load_oproms(void) {
	int i;
    unsigned char *MB = Machine->memory_region[2];

	for (i=0; i<1024; i++) {
        mbops[i].areg = MB[0xC000 + i] & 0x0F;
        mbops[i].breg = MB[0xC400 + i] & 0x0F;
        mbops[i].func = (MB[0xC800 + i] & 0x0F) << 5;
        mbops[i].func |= ((MB[0xCC00 +i] & 0x0F) << 1);
        mbops[i].func |= (MB[0xD000 + i] & 0x08) >> 3;
        mbops[i].flags = (MB[0xD000 + i] & 0x04) >> 2;
        mbops[i].nxtadd = (MB[0xD400 + i] & 0x0C) >> 2;
        mbops[i].diradd = MB[0xD400 +i] & 0x03;
        mbops[i].nxtadd |= ((MB[0xD800 + i] & 0x0F) << 6);
        mbops[i].nxtadd |= ((MB[0xDC00 + i] & 0x0F) << 2);
        mbops[i].mab = (MB[0xE000 + i] & 0x0F);
        mbops[i].jtype = (MB[0xE400 + i] & 0x0E) >> 1;
        mbops[i].flags |= (MB[0xE400 + i] & 0x01) << 1;
        mbops[i].flags |= (MB[0xE800 + i] & 0x0F) << 2;
        mbops[i].flags |= (MB[0xEC00 + i] & 0x01) << 6;
        mbops[i].flags |= (MB[0xEC00 + i] & 0x08) << 4;
        mbops[i].ramsel = (MB[0xEC00 + i] & 0x06) >> 1;
        mbops[i].diradd |= (MB[0xF000 + i] & 0x03) << 6;
	}
}

/* Init mathbox (only called once) */

void irmb_init(void) {
	int i;

	for(i=0; i<16; i++) {
        irmb_regs[i]=0x00;
        irmb_stack[i]=0x00;
	}
    irmb_PC=irmb_Q=irmb_F=irmb_Y=irmb_sp=0;
    irmb_nflag=irmb_cflag=irmb_zflag=0;
    irmb_pmadd=0;
    irmb_running=0;
    irmb_oldPC=0;
	load_oproms();
}

/* Run mathbox */
void irmb_run(void) {
	int i;

    irmb_oldPC=irmb_PC=irmb_sp=i=0;
	while (!i) {
        i = irmb_exec();
	}
}

/* Execute instruction */

void do_jump(void) {
    irmb_PC = mbops[irmb_PC].nxtadd;
}

int irmb_exec(void) {
	int fu;
    unsigned int R,S,F;
	unsigned int MDB;
    unsigned long result;

    result = 0;
    R=S=F=0;

    /* Get function code */
    fu = mbops[irmb_PC].func;

    /* Check for done */
    if ((mbops[irmb_PC].flags & FL_DPSEL) && (mbops[irmb_PC].flags & FL_carry)) {
		return 1;
	}


	/* Modify function for MULT */
    if (!(mbops[irmb_oldPC].flags & FL_MULT)) {
    	fu = fu ^ 0x02;
    }
    else {
        if (!(irmb_Q & 0x01)) {
			fu = fu | 0x02;
		}
		else {
			fu = fu ^ 0x02;
		}
    }

	/* Modify function for DIV */
    if ((mbops[irmb_oldPC].flags & FL_DIV) || irmb_nflag) {
    	fu = fu ^ 0x08;
    }
    if (!(mbops[irmb_oldPC].flags & FL_DIV) && !irmb_nflag) {
    	fu = fu | 0x08;
    }

	/* Get registers to work on */
	switch (fu & 0x07) {
		case 0:
            R = irmb_regs[mbops[irmb_PC].areg];
            S = irmb_Q;
			break;
		case 1:
            R = irmb_regs[mbops[irmb_PC].areg];
            S = irmb_regs[mbops[irmb_PC].breg];
			break;
		case 2:
			R = 0;
            S = irmb_Q;
			break;
		case 3:
			R = 0;
            S = irmb_regs[mbops[irmb_PC].breg];
			break;
		case 4:
			R = 0;
            S = irmb_regs[mbops[irmb_PC].areg];
			break;
		case 5:
            R = irmb_din();
            S = irmb_regs[mbops[irmb_PC].areg];
			break;
		case 6:
            R = irmb_din();
            S = irmb_Q;
			break;
		case 7:
            R = irmb_din();
			S = 0;
			break;
	}

	/* determine carry in */
    irmb_CI=0;
    if (mbops[irmb_PC].flags & FL_DPSEL) {
        irmb_CI = irmb_cflag;
	}
	else {
        if (mbops[irmb_PC].flags & FL_carry) irmb_CI = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -