Ejemplo n.º 1
0
static void opCVTS(void)
{
	float val1=u2f(GETREG(GET1));
	SET_OV(0);
	SET_Z((val1==0.0)?1:0);
	SET_S((val1<0.0)?1:0);
	SETREG(GET2,(INT32)val1);
}
Ejemplo n.º 2
0
static void opCVTW(void)
{
	//TODO: CY
	float val1=GETREG(GET1);
	SET_OV(0);
	SET_Z((val1==0.0)?1:0);
	SET_S((val1<0.0)?1:0);
	SETREG(GET2,f2u(val1));
}
Ejemplo n.º 3
0
static void opCMPF(void)
{
	float val1=u2f(GETREG(GET1));
	float val2=u2f(GETREG(GET2));
	SET_OV(0);
	SET_CY((val2<val1)?1:0);
	val2-=val1;
	SET_Z((val2==0.0)?1:0);
	SET_S((val2<0.0)?1:0);
}
Ejemplo n.º 4
0
static void opMULF(void)
{
	//TODO: CY
	float val1=u2f(GETREG(GET1));
	float val2=u2f(GETREG(GET2));
	SET_OV(0);
	val2*=val1;
	SET_Z((val2==0.0)?1:0);
	SET_S((val2<0.0)?1:0);
	SETREG(GET2,f2u(val2));
}
Ejemplo n.º 5
0
static void opDIVF(void)
{
	//TODO: CY
	float val1=u2f(GETREG(GET1));
	float val2=u2f(GETREG(GET2));
	SET_OV(0);
	if(val1!=0)
		val2/=val1;
	SET_Z((val2==0.0)?1:0);
	SET_S((val2<0.0)?1:0);
	SETREG(GET2,f2u(val2));
}
Ejemplo n.º 6
0
static UINT32 opMULUr(void)	// mulu r1,r2
{
	UINT32 op1=GETREG(GET1);
	UINT32 op2=GETREG(GET2);
	UINT64 tmp;
	tmp=(UINT64)op1*(UINT64)op2;
	op2=tmp&0xffffffff;
	tmp>>=32;
	CHECK_ZS(tmp);//z = bad!
	SET_Z( (tmp|op2)==0 );
	SET_OV((tmp!=0));
	SET_CY((tmp!=0));
	SETREG(GET2,op2);
	SETREG(30,tmp);
	return clkIF;
}
Ejemplo n.º 7
0
template<class Z> Obj dofplll(Obj gapmat, Obj lllargs, Obj svpargs)
{
  if (!IS_PLIST(gapmat)) return INTOBJ_INT(-1);
  Int numrows = LEN_PLIST(gapmat), numcols = -1;
  
  for (int i = 1; i <= numrows; i++) {
    Obj row = ELM_PLIST(gapmat,i);
    if (numcols == -1)
      numcols = LEN_PLIST(row);
    if (numcols != LEN_PLIST(row))
      return INTOBJ_INT(-1);
  }
  if (numcols <= 0)
    return INTOBJ_INT(-1);

  ZZ_mat<Z> mat(numrows, numcols);
  for (int i = 1; i <= numrows; i++)
    for (int j = 1; j <= numcols; j++)
      SET_INTOBJ(mat[i-1][j-1], ELM_PLIST(ELM_PLIST(gapmat,i),j));

  if (lllargs != Fail) {
    double delta = 0.99;
    double eta = 0.51;
    LLLMethod method = LM_WRAPPER;
    FloatType floatType = FT_DEFAULT;
    int precision = 0;
    int flags = LLL_DEFAULT;

    if (lllargs != True) {
      if (!IS_PLIST(lllargs) || LEN_PLIST(lllargs) != 6) return INTOBJ_INT(-20);

      Obj v = ELM_PLIST(lllargs,1);
      if (IS_MACFLOAT(v)) delta = VAL_MACFLOAT(v);
      else if (v != Fail) return INTOBJ_INT(-21);

      v = ELM_PLIST(lllargs,2);
      if (IS_MACFLOAT(v)) eta = VAL_MACFLOAT(v);
      else if (v != Fail) return INTOBJ_INT(-22);

      v = ELM_PLIST(lllargs,3);
      if (v == INTOBJ_INT(0)) method = LM_WRAPPER;
      else if (v == INTOBJ_INT(1)) method = LM_PROVED;
      else if (v == INTOBJ_INT(2)) method = LM_HEURISTIC;
      else if (v == INTOBJ_INT(3)) method = LM_FAST;
      else if (v != Fail) return INTOBJ_INT(-23);

      v = ELM_PLIST(lllargs,4);
      if (v == INTOBJ_INT(0)) floatType = FT_DEFAULT;
      else if (v == INTOBJ_INT(1)) floatType = FT_DOUBLE;
      else if (v == INTOBJ_INT(2)) floatType = FT_DPE;
      else if (v == INTOBJ_INT(3)) floatType = FT_MPFR;
      else if (v != Fail) return INTOBJ_INT(-24);

      v = ELM_PLIST(lllargs,5);
      if (IS_INTOBJ(v)) precision = INT_INTOBJ(v);
      else if (v != Fail) return INTOBJ_INT(-25);

      v = ELM_PLIST(lllargs,6);
      if (IS_INTOBJ(v)) flags = INT_INTOBJ(v);
      else if (v != Fail) return INTOBJ_INT(-26);
    }
    int result = lllReduction(mat, delta, eta, method, floatType, precision, flags);

    if (result != RED_SUCCESS)
      return INTOBJ_INT(10*result+1);
  }

  if (svpargs != Fail) {
    SVPMethod method = SVPM_PROVED;
    int flags = SVP_DEFAULT;

    // __asm__ ("int3");
    if (svpargs != True) {
      if (!IS_PLIST(svpargs) || LEN_PLIST(svpargs) != 2) return INTOBJ_INT(-30);

      Obj v = ELM_PLIST(svpargs,1);
      if (v == INTOBJ_INT(0)) method = SVPM_PROVED;
      else if (v == INTOBJ_INT(1)) method = SVPM_FAST;
      else if (v != Fail) return INTOBJ_INT(-31);

      v = ELM_PLIST(svpargs,2);
      if (IS_INTOBJ(v)) flags = INT_INTOBJ(v);
      else if (v != Fail) return INTOBJ_INT(-32);
    }

    vector<Integer> sol(numrows);
    IntMatrix svpmat(numrows,numcols);

    for (int i = 0; i < numrows; i++)
      for (int j = 0; j < numcols; j++)
	SET_Z(svpmat[i][j],mat[i][j]);

    int result = shortestVector(svpmat, sol, method, flags);

    if (result != RED_SUCCESS)
      return INTOBJ_INT(10*result+2);

    Obj gapvec;
    if (lllargs == Fail) { // return coordinates of shortest vector in mat
      gapvec = NEW_PLIST(T_PLIST,numrows);
      SET_LEN_PLIST(gapvec,numrows);
      for (int i = 1; i <= numrows; i++) {
	Obj v = GET_INTOBJ(sol[i-1]);
	SET_ELM_PLIST(gapvec,i,v);
      }
    } else { // return shortest vector
      gapvec = NEW_PLIST(T_PLIST,numcols);
      SET_LEN_PLIST(gapvec,numcols);
      for (int i = 1; i <= numcols; i++) {
	Integer s;
	s = 0;
	for (int j = 0; j < numrows; j++)
	  s.addmul(sol[j],svpmat[j][i-1]);
	Obj v = GET_INTOBJ(s);
	SET_ELM_PLIST(gapvec,i,v);
      }
    }
    return gapvec;
  }

  gapmat = NEW_PLIST(T_PLIST,numrows);
  SET_LEN_PLIST(gapmat,numrows);
  for (int i = 1; i <= numrows; i++) {
    Obj gaprow = NEW_PLIST(T_PLIST,numcols);
    SET_LEN_PLIST(gaprow,numcols);
    SET_ELM_PLIST(gapmat,i,gaprow);
    for (int j = 1; j <= numcols; j++) {
      Obj v = GET_INTOBJ(mat[i-1][j-1]);
      SET_ELM_PLIST(gaprow,j,v);
    }
  }
  return gapmat;
}
Ejemplo n.º 8
0
Archivo: mc6809.c Proyecto: jedie/XRoar
static void mc6809_run(struct MC6809 *cpu) {

	do {

		_Bool nmi_active = cpu->nmi && ((cpu->cycle - cpu->nmi_cycle) <= (UINT_MAX/2));
		_Bool firq_active = cpu->firq && ((cpu->cycle - cpu->firq_cycle) <= (UINT_MAX/2));
		_Bool irq_active = cpu->irq && ((cpu->cycle - cpu->irq_cycle) <= (UINT_MAX/2));

		// Prevent overflow
		if (firq_active) cpu->firq_cycle = cpu->cycle;
		if (irq_active) cpu->irq_cycle = cpu->cycle;

		switch (cpu->state) {

		case mc6809_state_reset:
			REG_DP = 0;
			REG_CC |= (CC_F | CC_I);
			cpu->nmi = 0;
			cpu->nmi_armed = 0;
			cpu->state = mc6809_state_reset_check_halt;
			// fall through

		case mc6809_state_reset_check_halt:
			if (cpu->halt) {
				NVMA_CYCLE;
				continue;
			}
			REG_PC = fetch_byte(cpu, MC6809_INT_VEC_RESET) << 8;
			REG_PC |= fetch_byte(cpu, MC6809_INT_VEC_RESET + 1);
			NVMA_CYCLE;
			cpu->state = mc6809_state_label_a;
			continue;

		// done_instruction case for backwards-compatibility
		case mc6809_state_done_instruction:
		case mc6809_state_label_a:
			if (cpu->halt) {
				NVMA_CYCLE;
				continue;
			}
			cpu->state = mc6809_state_label_b;
			// fall through

		case mc6809_state_label_b:
			if (cpu->nmi_armed && nmi_active) {
				peek_byte(cpu, REG_PC);
				peek_byte(cpu, REG_PC);
				stack_irq_registers(cpu, 1);
				cpu->state = mc6809_state_dispatch_irq;
				continue;
			}
			if (!(REG_CC & CC_F) && firq_active) {
				peek_byte(cpu, REG_PC);
				peek_byte(cpu, REG_PC);
				stack_irq_registers(cpu, 0);
				cpu->state = mc6809_state_dispatch_irq;
				continue;
			}
			if (!(REG_CC & CC_I) && irq_active) {
				peek_byte(cpu, REG_PC);
				peek_byte(cpu, REG_PC);
				stack_irq_registers(cpu, 1);
				cpu->state = mc6809_state_dispatch_irq;
				continue;
			}
			cpu->state = mc6809_state_next_instruction;
			// Instruction fetch hook called here so that machine
			// can be stopped beforehand.
			DELEGATE_SAFE_CALL0(cpu->instruction_hook);
			continue;

		case mc6809_state_dispatch_irq:
			if (cpu->nmi_armed && nmi_active) {
				cpu->nmi = 0;
				REG_CC |= (CC_F | CC_I);
				take_interrupt(cpu, CC_F|CC_I, MC6809_INT_VEC_NMI);
				cpu->state = mc6809_state_label_a;
				continue;
			}
			if (!(REG_CC & CC_F) && firq_active) {
				REG_CC |= (CC_F | CC_I);
				take_interrupt(cpu, CC_F|CC_I, MC6809_INT_VEC_FIRQ);
				cpu->state = mc6809_state_label_a;
				continue;
			}
			if (!(REG_CC & CC_I) && irq_active) {
				REG_CC |= CC_I;
				take_interrupt(cpu, CC_I, MC6809_INT_VEC_IRQ);
				cpu->state = mc6809_state_label_a;
				continue;
			}
			cpu->state = mc6809_state_cwai_check_halt;
			continue;

		case mc6809_state_cwai_check_halt:
			NVMA_CYCLE;
			if (cpu->halt) {
				continue;
			}
			cpu->state = mc6809_state_dispatch_irq;
			continue;

		case mc6809_state_sync:
			if (nmi_active || firq_active || irq_active) {
				NVMA_CYCLE;
				NVMA_CYCLE;
				instruction_posthook(cpu);
				cpu->state = mc6809_state_label_b;
				continue;
			}
			NVMA_CYCLE;
			if (cpu->halt)
				cpu->state = mc6809_state_sync_check_halt;
			continue;

		case mc6809_state_sync_check_halt:
			NVMA_CYCLE;
			if (!cpu->halt) {
				cpu->state = mc6809_state_sync;
			}
			continue;

		case mc6809_state_next_instruction:
			{
			unsigned op;
			// Fetch op-code and process
			op = byte_immediate(cpu);
			switch (op) {

			// 0x00 - 0x0f direct mode ops
			// 0x40 - 0x4f inherent A register ops
			// 0x50 - 0x5f inherent B register ops
			// 0x60 - 0x6f indexed mode ops
			// 0x70 - 0x7f extended mode ops
			case 0x00: case 0x01: case 0x02: case 0x03:
			case 0x04: case 0x05: case 0x06: case 0x07:
			case 0x08: case 0x09: case 0x0a: case 0x0b:
			case 0x0c: case 0x0d: case 0x0f:
			case 0x40: case 0x41: case 0x42: case 0x43:
			case 0x44: case 0x45: case 0x46: case 0x47:
			case 0x48: case 0x49: case 0x4a: case 0x4b:
			case 0x4c: case 0x4d: case 0x4f:
			case 0x50: case 0x51: case 0x52: case 0x53:
			case 0x54: case 0x55: case 0x56: case 0x57:
			case 0x58: case 0x59: case 0x5a: case 0x5b:
			case 0x5c: case 0x5d: case 0x5f:
			case 0x60: case 0x61: case 0x62: case 0x63:
			case 0x64: case 0x65: case 0x66: case 0x67:
			case 0x68: case 0x69: case 0x6a: case 0x6b:
			case 0x6c: case 0x6d: case 0x6f:
			case 0x70: case 0x71: case 0x72: case 0x73:
			case 0x74: case 0x75: case 0x76: case 0x77:
			case 0x78: case 0x79: case 0x7a: case 0x7b:
			case 0x7c: case 0x7d: case 0x7f: {
				uint16_t ea;
				unsigned tmp1;
				switch ((op >> 4) & 0xf) {
				case 0x0: ea = ea_direct(cpu); tmp1 = fetch_byte(cpu, ea); break;
				case 0x4: ea = 0; tmp1 = RREG_A; break;
				case 0x5: ea = 0; tmp1 = RREG_B; break;
				case 0x6: ea = ea_indexed(cpu); tmp1 = fetch_byte(cpu, ea); break;
				case 0x7: ea = ea_extended(cpu); tmp1 = fetch_byte(cpu, ea); break;
				default: ea = tmp1 = 0; break;
				}
				switch (op & 0xf) {
				case 0x1: // NEG illegal
				case 0x0: tmp1 = op_neg(cpu, tmp1); break; // NEG, NEGA, NEGB
				case 0x2: tmp1 = op_negcom(cpu, tmp1); break; // NEGCOM illegal
				case 0x3: tmp1 = op_com(cpu, tmp1); break; // COM, COMA, COMB
				case 0x5: // LSR illegal
				case 0x4: tmp1 = op_lsr(cpu, tmp1); break; // LSR, LSRA, LSRB
				case 0x6: tmp1 = op_ror(cpu, tmp1); break; // ROR, RORA, RORB
				case 0x7: tmp1 = op_asr(cpu, tmp1); break; // ASR, ASRA, ASRB
				case 0x8: tmp1 = op_asl(cpu, tmp1); break; // ASL, ASLA, ASLB
				case 0x9: tmp1 = op_rol(cpu, tmp1); break; // ROL, ROLA, ROLB
				case 0xb: // DEC illegal
				case 0xa: tmp1 = op_dec(cpu, tmp1); break; // DEC, DECA, DECB
				case 0xc: tmp1 = op_inc(cpu, tmp1); break; // INC, INCA, INCB
				case 0xd: tmp1 = op_tst(cpu, tmp1); break; // TST, TSTA, TSTB
				case 0xf: tmp1 = op_clr(cpu, tmp1); break; // CLR, CLRA, CLRB
				default: break;
				}
				switch (op & 0xf) {
				case 0xd: // TST
					NVMA_CYCLE;
					NVMA_CYCLE;
					break;
				default: // the rest need storing
					switch ((op >> 4) & 0xf) {
					default:
					case 0x0: case 0x6: case 0x7:
						NVMA_CYCLE;
						store_byte(cpu, ea, tmp1);
						break;
					case 0x4:
						WREG_A = tmp1;
						peek_byte(cpu, REG_PC);
						break;
					case 0x5:
						WREG_B = tmp1;
						peek_byte(cpu, REG_PC);
						break;
					}
				}
			} break;

			// 0x0e JMP direct
			// 0x6e JMP indexed
			// 0x7e JMP extended
			case 0x0e: case 0x6e: case 0x7e: {
				unsigned ea;
				switch ((op >> 4) & 0xf) {
				case 0x0: ea = ea_direct(cpu); break;
				case 0x6: ea = ea_indexed(cpu); break;
				case 0x7: ea = ea_extended(cpu); break;
				default: ea = 0; break;
				}
				REG_PC = ea;
			} break;

			// 0x10 Page 2
			case 0x10:
				cpu->state = mc6809_state_instruction_page_2;
				continue;
			// 0x11 Page 3
			case 0x11:
				cpu->state = mc6809_state_instruction_page_3;
				continue;
			// 0x12 NOP inherent
			case 0x12: peek_byte(cpu, REG_PC); break;
			// 0x13 SYNC inherent
			case 0x13:
				peek_byte(cpu, REG_PC);
				cpu->state = mc6809_state_sync;
				continue;
			// 0x14, 0x15 HCF? (illegal)
			case 0x14:
			case 0x15:
				cpu->state = mc6809_state_hcf;
				goto done_instruction;
			// 0x16 LBRA relative
			case 0x16: {
				uint16_t ea;
				ea = long_relative(cpu);
				REG_PC += ea;
				NVMA_CYCLE;
				NVMA_CYCLE;
			} break;
			// 0x17 LBSR relative
			case 0x17: {
				uint16_t ea;
				ea = long_relative(cpu);
				ea += REG_PC;
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
				push_word(cpu, &REG_S, REG_PC);
				REG_PC = ea;
			} break;
			// 0x18 Shift CC with mask inherent (illegal)
			case 0x18:
				REG_CC = (REG_CC << 1) & (CC_H | CC_Z);
				NVMA_CYCLE;
				peek_byte(cpu, REG_PC);
				break;
			// 0x19 DAA inherent
			case 0x19: {
				unsigned tmp = 0;
				if ((RREG_A&0x0f) >= 0x0a || REG_CC & CC_H) tmp |= 0x06;
				if (RREG_A >= 0x90 && (RREG_A&0x0f) >= 0x0a) tmp |= 0x60;
				if (RREG_A >= 0xa0 || REG_CC & CC_C) tmp |= 0x60;
				tmp += RREG_A;
				WREG_A = tmp;
				// CC.C NOT cleared, only set if appropriate
				CLR_NZV;
				SET_NZC8(tmp);
				peek_byte(cpu, REG_PC);
			} break;
			// 0x1a ORCC immediate
			case 0x1a: {
				unsigned data;
				data = byte_immediate(cpu);
				REG_CC |= data;
				peek_byte(cpu, REG_PC);
			} break;
			// 0x1b NOP inherent (illegal)
			case 0x1b: peek_byte(cpu, REG_PC); break;
			// 0x1c ANDCC immediate
			case 0x1c: {
				unsigned data;
				data = byte_immediate(cpu);
				REG_CC &= data;
				peek_byte(cpu, REG_PC);
			} break;
			// 0x1d SEX inherent
			case 0x1d:
				WREG_A = (RREG_B & 0x80) ? 0xff : 0;
				CLR_NZ;
				SET_NZ16(REG_D);
				peek_byte(cpu, REG_PC);
				break;
			// 0x1e EXG immediate
			case 0x1e: {
				unsigned postbyte;
				uint16_t tmp1, tmp2;
				postbyte = byte_immediate(cpu);
				switch (postbyte >> 4) {
					case 0x0: tmp1 = REG_D; break;
					case 0x1: tmp1 = REG_X; break;
					case 0x2: tmp1 = REG_Y; break;
					case 0x3: tmp1 = REG_U; break;
					case 0x4: tmp1 = REG_S; break;
					case 0x5: tmp1 = REG_PC; break;
					case 0x8: tmp1 = RREG_A | 0xff00; break;
					case 0x9: tmp1 = RREG_B | 0xff00; break;
					// TODO: verify this behaviour
					case 0xa: tmp1 = (REG_CC << 8) | REG_CC; break;
					case 0xb: tmp1 = (REG_DP << 8) | REG_DP; break;
					default: tmp1 = 0xffff; break;
				}
				switch (postbyte & 0xf) {
					case 0x0: tmp2 = REG_D; REG_D = tmp1; break;
					case 0x1: tmp2 = REG_X; REG_X = tmp1; break;
					case 0x2: tmp2 = REG_Y; REG_Y = tmp1; break;
					case 0x3: tmp2 = REG_U; REG_U = tmp1; break;
					case 0x4: tmp2 = REG_S; REG_S = tmp1; break;
					case 0x5: tmp2 = REG_PC; REG_PC = tmp1; break;
					case 0x8: tmp2 = RREG_A | 0xff00; WREG_A = tmp1; break;
					case 0x9: tmp2 = RREG_B | 0xff00; WREG_B = tmp1; break;
					// TODO: verify this behaviour
					case 0xa: tmp2 = (REG_CC << 8) | REG_CC; REG_CC = tmp1; break;
					case 0xb: tmp2 = (REG_DP << 8) | REG_DP; REG_DP = tmp1; break;
					default: tmp2 = 0xffff; break;
				}
				switch (postbyte >> 4) {
					case 0x0: REG_D = tmp2; break;
					case 0x1: REG_X = tmp2; break;
					case 0x2: REG_Y = tmp2; break;
					case 0x3: REG_U = tmp2; break;
					case 0x4: REG_S = tmp2; break;
					case 0x5: REG_PC = tmp2; break;
					case 0x8: WREG_A = tmp2; break;
					case 0x9: WREG_B = tmp2; break;
					case 0xa: REG_CC = tmp2; break;
					case 0xb: REG_DP = tmp2; break;
					default: break;
				}
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
			} break;
			// 0x1f TFR immediate
			case 0x1f: {
				unsigned postbyte;
				uint16_t tmp1;
				postbyte = byte_immediate(cpu);
				switch (postbyte >> 4) {
					case 0x0: tmp1 = REG_D; break;
					case 0x1: tmp1 = REG_X; break;
					case 0x2: tmp1 = REG_Y; break;
					case 0x3: tmp1 = REG_U; break;
					case 0x4: tmp1 = REG_S; break;
					case 0x5: tmp1 = REG_PC; break;
					case 0x8: tmp1 = RREG_A | 0xff00; break;
					case 0x9: tmp1 = RREG_B | 0xff00; break;
					// TODO: verify this behaviour
					case 0xa: tmp1 = (REG_CC << 8) | REG_CC; break;
					case 0xb: tmp1 = (REG_DP << 8) | REG_DP; break;
					default: tmp1 = 0xffff; break;
				}
				switch (postbyte & 0xf) {
					case 0x0: REG_D = tmp1; break;
					case 0x1: REG_X = tmp1; break;
					case 0x2: REG_Y = tmp1; break;
					case 0x3: REG_U = tmp1; break;
					case 0x4: REG_S = tmp1; break;
					case 0x5: REG_PC = tmp1; break;
					case 0x8: WREG_A = tmp1; break;
					case 0x9: WREG_B = tmp1; break;
					case 0xa: REG_CC = tmp1; break;
					case 0xb: REG_DP = tmp1; break;
					default: break;
				}
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
			} break;

			// 0x20 - 0x2f short branches
			case 0x20: case 0x21: case 0x22: case 0x23:
			case 0x24: case 0x25: case 0x26: case 0x27:
			case 0x28: case 0x29: case 0x2a: case 0x2b:
			case 0x2c: case 0x2d: case 0x2e: case 0x2f: {
				unsigned tmp = sex8(byte_immediate(cpu));
				NVMA_CYCLE;
				if (branch_condition(cpu, op))
					REG_PC += tmp;
			} break;

			// 0x30 LEAX indexed
			case 0x30:
				REG_X = ea_indexed(cpu);
				CLR_Z;
				SET_Z(REG_X);
				NVMA_CYCLE;
				break;
			// 0x31 LEAY indexed
			case 0x31:
				REG_Y = ea_indexed(cpu);
				CLR_Z;
				SET_Z(REG_Y);
				NVMA_CYCLE;
				break;
			// 0x32 LEAS indexed
			case 0x32:
				REG_S = ea_indexed(cpu);
				NVMA_CYCLE;
				cpu->nmi_armed = 1;  // XXX: Really?
				break;
			// 0x33 LEAU indexed
			case 0x33:
				REG_U = ea_indexed(cpu);
				NVMA_CYCLE;
				break;
			// 0x34 PSHS immediate
			case 0x34: psh(cpu, &REG_S, REG_U); break;
			// 0x35 PULS immediate
			case 0x35: pul(cpu, &REG_S, &REG_U); break;
			// 0x36 PSHU immediate
			case 0x36: psh(cpu, &REG_U, REG_S); break;
			// 0x37 PULU immediate
			case 0x37: pul(cpu, &REG_U, &REG_S); break;
			// 0x38 ANDCC immediate (illegal)
			case 0x38: {
				unsigned data;
				data = byte_immediate(cpu);
				REG_CC &= data;
				peek_byte(cpu, REG_PC);
				/* Differs from legal 0x1c version by
				 * taking one more cycle: */
				NVMA_CYCLE;
			} break;
			// 0x39 RTS inherent
			case 0x39:
				peek_byte(cpu, REG_PC);
				REG_PC = pull_word(cpu, &REG_S);
				NVMA_CYCLE;
				break;
			// 0x3a ABX inherent
			case 0x3a:
				REG_X += RREG_B;
				peek_byte(cpu, REG_PC);
				NVMA_CYCLE;
				break;
			// 0x3b RTI inherent
			case 0x3b:
				peek_byte(cpu, REG_PC);
				REG_CC = pull_byte(cpu, &REG_S);
				if (REG_CC & CC_E) {
					WREG_A = pull_byte(cpu, &REG_S);
					WREG_B = pull_byte(cpu, &REG_S);
					REG_DP = pull_byte(cpu, &REG_S);
					REG_X = pull_word(cpu, &REG_S);
					REG_Y = pull_word(cpu, &REG_S);
					REG_U = pull_word(cpu, &REG_S);
					REG_PC = pull_word(cpu, &REG_S);
				} else {
					REG_PC = pull_word(cpu, &REG_S);
				}
				cpu->nmi_armed = 1;
				peek_byte(cpu, REG_S);
				break;
			// 0x3c CWAI immediate
			case 0x3c: {
				unsigned data;
				data = byte_immediate(cpu);
				REG_CC &= data;
				peek_byte(cpu, REG_PC);
				NVMA_CYCLE;
				stack_irq_registers(cpu, 1);
				NVMA_CYCLE;
				cpu->state = mc6809_state_dispatch_irq;
				goto done_instruction;
			} break;
			// 0x3d MUL inherent
			case 0x3d: {
				unsigned tmp = RREG_A * RREG_B;
				REG_D = tmp;
				CLR_ZC;
				SET_Z(tmp);
				if (tmp & 0x80)
					REG_CC |= CC_C;
				peek_byte(cpu, REG_PC);
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
				NVMA_CYCLE;
			} break;
			// 0x3e RESET (illegal)
			case 0x3e:
				peek_byte(cpu, REG_PC);
				push_irq_registers(cpu);
				instruction_posthook(cpu);
				take_interrupt(cpu, CC_F|CC_I, MC6809_INT_VEC_RESET);
				cpu->state = mc6809_state_label_a;
				continue;
			// 0x3f SWI inherent
			case 0x3f:
				peek_byte(cpu, REG_PC);
				stack_irq_registers(cpu, 1);
				instruction_posthook(cpu);
				take_interrupt(cpu, CC_F|CC_I, MC6809_INT_VEC_SWI);
				cpu->state = mc6809_state_label_a;
				continue;

			// 0x80 - 0xbf A register arithmetic ops
			// 0xc0 - 0xff B register arithmetic ops
			case 0x80: case 0x81: case 0x82:
			case 0x84: case 0x85: case 0x86: case 0x87:
			case 0x88: case 0x89: case 0x8a: case 0x8b:
			case 0x90: case 0x91: case 0x92:
			case 0x94: case 0x95: case 0x96:
			case 0x98: case 0x99: case 0x9a: case 0x9b:
			case 0xa0: case 0xa1: case 0xa2:
			case 0xa4: case 0xa5: case 0xa6:
			case 0xa8: case 0xa9: case 0xaa: case 0xab:
			case 0xb0: case 0xb1: case 0xb2:
			case 0xb4: case 0xb5: case 0xb6:
			case 0xb8: case 0xb9: case 0xba: case 0xbb:
			case 0xc0: case 0xc1: case 0xc2:
			case 0xc4: case 0xc5: case 0xc6: case 0xc7:
			case 0xc8: case 0xc9: case 0xca: case 0xcb:
			case 0xd0: case 0xd1: case 0xd2:
			case 0xd4: case 0xd5: case 0xd6:
			case 0xd8: case 0xd9: case 0xda: case 0xdb:
			case 0xe0: case 0xe1: case 0xe2:
			case 0xe4: case 0xe5: case 0xe6:
			case 0xe8: case 0xe9: case 0xea: case 0xeb:
			case 0xf0: case 0xf1: case 0xf2:
			case 0xf4: case 0xf5: case 0xf6:
			case 0xf8: case 0xf9: case 0xfa: case 0xfb: {
				unsigned tmp1, tmp2;
				tmp1 = !(op & 0x40) ? RREG_A : RREG_B;
				switch ((op >> 4) & 3) {
				case 0: tmp2 = byte_immediate(cpu); break;
				case 1: tmp2 = byte_direct(cpu); break;
				case 2: tmp2 = byte_indexed(cpu); break;
				case 3: tmp2 = byte_extended(cpu); break;
				default: tmp2 = 0; break;
				}
				switch (op & 0xf) {
				case 0x0: tmp1 = op_sub(cpu, tmp1, tmp2); break; // SUBA, SUBB
				case 0x1: (void)op_sub(cpu, tmp1, tmp2); break; // CMPA, CMPB
				case 0x2: tmp1 = op_sbc(cpu, tmp1, tmp2); break; // SBCA, SBCB
				case 0x4: tmp1 = op_and(cpu, tmp1, tmp2); break; // ANDA, ANDB
				case 0x5: (void)op_and(cpu, tmp1, tmp2); break; // BITA, BITB
				case 0x6: tmp1 = op_ld(cpu, 0, tmp2); break; // LDA, LDB
				case 0x7: tmp1 = op_discard(cpu, tmp1, tmp2); break; // illegal
				case 0x8: tmp1 = op_eor(cpu, tmp1, tmp2); break; // EORA, EORB
				case 0x9: tmp1 = op_adc(cpu, tmp1, tmp2); break; // ADCA, ADCB
				case 0xa: tmp1 = op_or(cpu, tmp1, tmp2); break; // ORA, ORB
				case 0xb: tmp1 = op_add(cpu, tmp1, tmp2); break; // ADDA, ADDB
				default: break;
				}
				if (!(op & 0x40)) {
					WREG_A = tmp1;
				} else {
					WREG_B = tmp1;
				}
			} break;

			// 0x83, 0x93, 0xa3, 0xb3 SUBD
			// 0x8c, 0x9c, 0xac, 0xbc CMPX
			// 0xc3, 0xd3, 0xe3, 0xf3 ADDD
			case 0x83: case 0x93: case 0xa3: case 0xb3:
			case 0x8c: case 0x9c: case 0xac: case 0xbc:
			case 0xc3: case 0xd3: case 0xe3: case 0xf3: {
				unsigned tmp1, tmp2;
				tmp1 = !(op & 0x08) ? REG_D : REG_X;
				switch ((op >> 4) & 3) {
				case 0: tmp2 = word_immediate(cpu); break;
				case 1: tmp2 = word_direct(cpu); break;
				case 2: tmp2 = word_indexed(cpu); break;
				case 3: tmp2 = word_extended(cpu); break;
				default: tmp2 = 0; break;
				}
				switch (op & 0x4f) {
				case 0x03: tmp1 = op_sub16(cpu, tmp1, tmp2); break; // SUBD
				case 0x0c: (void)op_sub16(cpu, tmp1, tmp2); break; // CMPX
				case 0x43: tmp1 = op_add16(cpu, tmp1, tmp2); break; // ADDD
				default: break;
				}
				NVMA_CYCLE;
				if (!(op & 0x08)) {
					REG_D = tmp1;
				}
			} break;

			// 0x8d BSR
			// 0x9d, 0xad, 0xbd JSR
			case 0x8d: case 0x9d: case 0xad: case 0xbd: {
				unsigned ea;
				switch ((op >> 4) & 3) {
				case 0: ea = short_relative(cpu); ea += REG_PC; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; break;
				case 1: ea = ea_direct(cpu); peek_byte(cpu, ea); NVMA_CYCLE; break;
				case 2: ea = ea_indexed(cpu); peek_byte(cpu, ea); NVMA_CYCLE; break;
				case 3: ea = ea_extended(cpu); peek_byte(cpu, ea); NVMA_CYCLE; break;
				default: ea = 0; break;
				}
				push_word(cpu, &REG_S, REG_PC);
				REG_PC = ea;
			} break;

			// 0x8e, 0x9e, 0xae, 0xbe LDX
			// 0xcc, 0xdc, 0xec, 0xfc LDD
			// 0xce, 0xde, 0xee, 0xfe LDU
			case 0x8e: case 0x9e: case 0xae: case 0xbe:
			case 0xcc: case 0xdc: case 0xec: case 0xfc:
			case 0xce: case 0xde: case 0xee: case 0xfe: {
				unsigned tmp1, tmp2;
				switch ((op >> 4) & 3) {
				case 0: tmp2 = word_immediate(cpu); break;
				case 1: tmp2 = word_direct(cpu); break;
				case 2: tmp2 = word_indexed(cpu); break;
				case 3: tmp2 = word_extended(cpu); break;
				default: tmp2 = 0; break;
				}
				tmp1 = op_ld16(cpu, 0, tmp2);
				switch (op & 0x42) {
				case 0x02:
					REG_X = tmp1;
					break;
				case 0x40:
					REG_D = tmp1;
					break;
				case 0x42:
					REG_U = tmp1;
					break;
				default: break;
				}
			} break;

			// 0x97, 0xa7, 0xb7 STA
			// 0xd7, 0xe7, 0xf7 STB
			case 0x97: case 0xa7: case 0xb7:
			case 0xd7: case 0xe7: case 0xf7: {
				uint16_t ea;
				uint8_t tmp1;
				tmp1 = !(op & 0x40) ? RREG_A : RREG_B;
				switch ((op >> 4) & 3) {
				case 1: ea = ea_direct(cpu); break;
				case 2: ea = ea_indexed(cpu); break;
				case 3: ea = ea_extended(cpu); break;
				default: ea = 0; break;
				}
				store_byte(cpu, ea, tmp1);
				CLR_NZV;
				SET_NZ8(tmp1);
			} break;

			// 0x9f, 0xaf, 0xbf STX
			// 0xdd, 0xed, 0xfd STD
			// 0xdf, 0xef, 0xff STU
			case 0x9f: case 0xaf: case 0xbf:
			case 0xdd: case 0xed: case 0xfd:
			case 0xdf: case 0xef: case 0xff: {
				uint16_t ea, tmp1;
				switch (op & 0x42) {
				case 0x02: tmp1 = REG_X; break;
				case 0x40: tmp1 = REG_D; break;
				case 0x42: tmp1 = REG_U; break;
				default: tmp1 = 0; break;
				}
				switch ((op >> 4) & 3) {
				case 1: ea = ea_direct(cpu); break;
				case 2: ea = ea_indexed(cpu); break;
				case 3: ea = ea_extended(cpu); break;
				default: ea = 0; break;
				}
				CLR_NZV;
				SET_NZ16(tmp1);
				store_byte(cpu, ea, tmp1 >> 8);
				store_byte(cpu, ea+1, tmp1);
			} break;

			// 0x8f STX immediate (illegal)
			// 0xcf STU immediate (illegal)
			// Illegal instruction only part working
			case 0x8f: case 0xcf: {
				unsigned tmp1;
				tmp1 = !(op & 0x40) ? REG_X : REG_U;
				(void)fetch_byte(cpu, REG_PC);
				REG_PC++;
				store_byte(cpu, REG_PC, tmp1);
				REG_PC++;
				CLR_NZV;
				REG_CC |= CC_N;
			} break;

			// 0xcd HCF? (illegal)
			case 0xcd:
				cpu->state = mc6809_state_hcf;
				goto done_instruction;

			// Illegal instruction
			default:
				NVMA_CYCLE;
				break;
			}
			cpu->state = mc6809_state_label_a;
			goto done_instruction;
			}

		case mc6809_state_instruction_page_2:
			{
			unsigned op;
			op = byte_immediate(cpu);
			switch (op) {

			// 0x10, 0x11 Page 2
			case 0x10:
			case 0x11:
				cpu->state = mc6809_state_instruction_page_2;
				continue;

			// 0x1020 - 0x102f long branches
			case 0x20: case 0x21: case 0x22: case 0x23:
			case 0x24: case 0x25: case 0x26: case 0x27:
			case 0x28: case 0x29: case 0x2a: case 0x2b:
			case 0x2c: case 0x2d: case 0x2e: case 0x2f: {
				unsigned tmp = word_immediate(cpu);
				if (branch_condition(cpu, op)) {
					REG_PC += tmp;
					NVMA_CYCLE;
				}
				NVMA_CYCLE;
			} break;

			// 0x103f SWI2 inherent
			case 0x3f:
				peek_byte(cpu, REG_PC);
				stack_irq_registers(cpu, 1);
				instruction_posthook(cpu);
				take_interrupt(cpu, 0, MC6809_INT_VEC_SWI2);
				cpu->state = mc6809_state_label_a;
				continue;

			// 0x1083, 0x1093, 0x10a3, 0x10b3 CMPD
			// 0x108c, 0x109c, 0x10ac, 0x10bc CMPY
			case 0x83: case 0x93: case 0xa3: case 0xb3:
			case 0x8c: case 0x9c: case 0xac: case 0xbc: {
				unsigned tmp1, tmp2;
				tmp1 = !(op & 0x08) ? REG_D : REG_Y;
				switch ((op >> 4) & 3) {
				case 0: tmp2 = word_immediate(cpu); break;
				case 1: tmp2 = word_direct(cpu); break;
				case 2: tmp2 = word_indexed(cpu); break;
				case 3: tmp2 = word_extended(cpu); break;
				default: tmp2 = 0; break;
				}
				(void)op_sub16(cpu, tmp1, tmp2);
				NVMA_CYCLE;
			} break;

			// 0x108e, 0x109e, 0x10ae, 0x10be LDY
			// 0x10ce, 0x10de, 0x10ee, 0x10fe LDS
			case 0x8e: case 0x9e: case 0xae: case 0xbe:
			case 0xce: case 0xde: case 0xee: case 0xfe: {
				unsigned tmp1, tmp2;
				switch ((op >> 4) & 3) {
				case 0: tmp2 = word_immediate(cpu); break;
				case 1: tmp2 = word_direct(cpu); break;
				case 2: tmp2 = word_indexed(cpu); break;
				case 3: tmp2 = word_extended(cpu); break;
				default: tmp2 = 0; break;
				}
				tmp1 = op_ld16(cpu, 0, tmp2);
				if (!(op & 0x40)) {
					REG_Y = tmp1;
				} else {
					REG_S = tmp1;
					cpu->nmi_armed = 1;
				}
			} break;

			// 0x109f, 0x10af, 0x10bf STY
			// 0x10df, 0x10ef, 0x10ff STS
			case 0x9f: case 0xaf: case 0xbf:
			case 0xdf: case 0xef: case 0xff: {
				unsigned ea, tmp1;
				tmp1 = !(op & 0x40) ? REG_Y : REG_S;
				switch ((op >> 4) & 3) {
				case 1: ea = ea_direct(cpu); break;
				case 2: ea = ea_indexed(cpu); break;
				case 3: ea = ea_extended(cpu); break;
				default: ea = 0; break;
				}
				CLR_NZV;
				SET_NZ16(tmp1);
				store_byte(cpu, ea, tmp1 >> 8);
				store_byte(cpu, ea+1, tmp1);
			} break;

			// Illegal instruction
			default:
				NVMA_CYCLE;
				break;
			}
			cpu->state = mc6809_state_label_a;
			goto done_instruction;
			}

		case mc6809_state_instruction_page_3:
			{
			unsigned op;
			op = byte_immediate(cpu);
			switch (op) {

			// 0x10, 0x11 Page 3
			case 0x10:
			case 0x11:
				cpu->state = mc6809_state_instruction_page_3;
				continue;

			// 0x113F SWI3 inherent
			case 0x3f:
				peek_byte(cpu, REG_PC);
				stack_irq_registers(cpu, 1);
				instruction_posthook(cpu);
				take_interrupt(cpu, 0, MC6809_INT_VEC_SWI3);
				cpu->state = mc6809_state_label_a;
				continue;

			// 0x1183, 0x1193, 0x11a3, 0x11b3 CMPU
			// 0x118c, 0x119c, 0x11ac, 0x11bc CMPS
			case 0x83: case 0x93: case 0xa3: case 0xb3:
			case 0x8c: case 0x9c: case 0xac: case 0xbc: {
				unsigned tmp1, tmp2;
				tmp1 = !(op & 0x08) ? REG_U : REG_S;
				switch ((op >> 4) & 3) {
				case 0: tmp2 = word_immediate(cpu); break;
				case 1: tmp2 = word_direct(cpu); break;
				case 2: tmp2 = word_indexed(cpu); break;
				case 3: tmp2 = word_extended(cpu); break;
				default: tmp2 = 0; break;
				}
				(void)op_sub16(cpu, tmp1, tmp2);
				NVMA_CYCLE;
			} break;

			// Illegal instruction
			default:
				NVMA_CYCLE;
				break;
			}
			cpu->state = mc6809_state_label_a;
			goto done_instruction;
			}

		// Certain illegal instructions cause the CPU to lock up:
		case mc6809_state_hcf:
			NVMA_CYCLE;
			continue;

		}

done_instruction:
		instruction_posthook(cpu);
		continue;

	} while (cpu->running);

}
Ejemplo n.º 9
0
int Msmpot_compute(Msmpot *msm,
    float *epotmap,               /* electrostatic potential map
                                     assumed to be length mx*my*mz,
                                     stored flat in row-major order, i.e.,
                                     &ep[i,j,k] == ep + ((k*my+j)*mx+i) */
    int mx, int my, int mz,       /* map lattice dimensions */
    float lx, float ly, float lz, /* map lattice lengths */
    float x0, float y0, float z0, /* map origin (lower-left corner) */
    float vx, float vy, float vz, /* periodic cell lengths along x, y, z;
                                     set to 0 for non-periodic direction */
    const float *atom,            /* atoms stored x/y/z/q (length 4*natoms) */
    int natoms                    /* number of atoms */
    ) {
  int err;

  REPORT("Performing MSM calculation of electrostatic potential map.");

  err = Msmpot_check_params(msm, epotmap, mx, my, mz, lx, ly, lz,
      vx, vy, vz, atom, natoms);
  if (err != MSMPOT_SUCCESS) return ERROR(err);

  /* store user parameters */
  msm->atom = atom;
  msm->natoms = natoms;
  msm->epotmap = epotmap;
  msm->mx = mx;
  msm->my = my;
  msm->mz = mz;
  msm->lx = lx;
  msm->ly = ly;
  msm->lz = lz;
  msm->lx0 = x0;
  msm->ly0 = y0;
  msm->lz0 = z0;
  msm->dx = lx / mx;
  msm->dy = ly / my;
  msm->dz = lz / mz;
  msm->px = vx;
  msm->py = vy;
  msm->pz = vz;
  msm->isperiodic = 0;  /* reset flags for periodicity */
  /* zero length indicates nonperiodic direction */
  if (vx > 0) SET_X(msm->isperiodic);
  if (vy > 0) SET_Y(msm->isperiodic);
  if (vz > 0) SET_Z(msm->isperiodic);

  err = Msmpot_setup(msm);
  if (err != MSMPOT_SUCCESS) return ERROR(err);

  memset(epotmap, 0, mx*my*mz*sizeof(float));  /* clear epotmap */


#if !defined(MSMPOT_LONGRANGE_ONLY)
#ifdef MSMPOT_CUDA
  if (msm->use_cuda_shortrng) {
    err = Msmpot_cuda_compute_shortrng(msm->msmcuda);
    if (err && msm->cuda_optional) {  /* fall back on CPU */
#ifdef USE_BIN_HASHING
      err = Msmpot_compute_shortrng_bins(msm);
#else
      err = Msmpot_compute_shortrng_linklist(msm, msm->atom, msm->natoms);
#endif
      if (err) return ERROR(err);
    }
    else if (err) return ERROR(err);
  }
  else {
#ifdef USE_BIN_HASHING
    err = Msmpot_compute_shortrng_bins(msm);
#else
    err = Msmpot_compute_shortrng_linklist(msm, msm->atom, msm->natoms);
#endif /* USE_BIN_HASHING */
    if (err) return ERROR(err);
  }
#else
#ifdef USE_BIN_HASHING
  err = Msmpot_compute_shortrng_bins(msm);
#else
  err = Msmpot_compute_shortrng_linklist(msm, msm->atom, msm->natoms);
#endif /* USE_BIN_HASHING */
  if (err) return ERROR(err);
#endif
#endif

#if !defined(MSMPOT_SHORTRANGE_ONLY)
  err = Msmpot_compute_longrng(msm);
  if (err) return ERROR(err);
#endif

#ifdef MSMPOT_VERBOSE
#ifdef MSMPOT_CHECKMAPINDEX
  printf("epotmap[%d]=%g\n", MAPINDEX, epotmap[MAPINDEX]);
#endif
#endif

  return MSMPOT_SUCCESS;
}