示例#1
0
// insert byte until PC fits condition
static enum eos_t PO_align(void) {
	intval_t	and,
			equal,
			fill,
			test	= CPU_pc.intval;

	// make sure PC is defined.
	if ((CPU_pc.flags & MVALUE_DEFINED) == 0) {
		Throw_error(exception_pc_undefined);
		CPU_pc.flags |= MVALUE_DEFINED;	// do not complain again
		return SKIP_REMAINDER;
	}

	and = ALU_defined_int();
	if (!Input_accept_comma())
		Throw_error(exception_syntax);
	equal = ALU_defined_int();
	if (Input_accept_comma())
		fill = ALU_any_int();
	else
		fill = CPU_now->default_align_value;
	while ((test++ & and) != equal)
		Output_8b(fill);
	return ENSURE_EOS;
}
示例#2
0
// start offset assembly
static enum eos_t PO_pseudopc(void)
{
// future algo: remember outer memaddress and outer pseudopc
	int		outer_state	= uses_pseudo_pc;
	intval_t	new_pc,
			outer_offset	= current_offset;
	int		outer_flags	= CPU_pc.flags;

	// set new
	new_pc = ALU_defined_int();	// FIXME - allow for undefined pseudopc!
	current_offset = (current_offset + new_pc - CPU_pc.intval) & 0xffff;
	CPU_pc.intval = new_pc;
	CPU_pc.flags |= MVALUE_DEFINED;	// FIXME - remove!
	uses_pseudo_pc = TRUE;
	// if there's a block, parse that and then restore old value!
	if (Parse_optional_block()) {
		// restore old
		uses_pseudo_pc = outer_state;
		CPU_pc.flags = outer_flags;
		CPU_pc.intval = (outer_offset + CPU_pc.intval - current_offset) & 0xffff;
		current_offset = outer_offset;
// future algo: new outer pseudopc = (old outer pseudopc + (current memaddress - outer memaddress)) & 0xffff
	} else {
		Throw_first_pass_warning(Warning_old_offset_assembly);
	}
	return ENSURE_EOS;
}
示例#3
0
// Looping assembly ("!for"). Has to be re-entrant.
static enum eos_t PO_for(void) {// Now GotByte = illegal char
	input_t		loop_input,
			*outer_input;
	result_t	loop_counter;
	intval_t	maximum;
	char*		loop_body;// pointer to loop's body block
	label_t*	label;
	zone_t		zone;
	int		force_bit,
			loop_start;// line number of "!for" pseudo opcode

	if(Input_read_zone_and_keyword(&zone) == 0)	// skips spaces before
		return(SKIP_REMAINDER);
	// Now GotByte = illegal char
	force_bit = Input_get_force_bit();	// skips spaces after
	label = Label_find(zone, force_bit);
	if(Input_accept_comma() == FALSE) {
		Throw_error(exception_syntax);
		return(SKIP_REMAINDER);
	}
	maximum = ALU_defined_int();
	if(maximum < 0)
		Throw_serious_error("Loop count is negative.");
	if(GotByte != CHAR_SOB)
		Throw_serious_error(exception_no_left_brace);
	// remember line number of loop pseudo opcode
	loop_start = Input_now->line_number;
	// read loop body into DynaBuf and get copy
	loop_body = Input_skip_or_store_block(TRUE);	// changes line number!
	// switching input makes us lose GotByte. But we know it's '}' anyway!
	// set up new input
	loop_input = *Input_now;// copy current input structure into new
	loop_input.source_is_ram = TRUE;	// set new byte source
	// remember old input
	outer_input = Input_now;
	// activate new input
	// (not yet useable; pointer and line number are still missing)
	Input_now = &loop_input;
	// init counter
	loop_counter.flags = MVALUE_DEFINED | MVALUE_EXISTS;
	loop_counter.val.intval = 0;
	// if count == 0, skip loop
	if(maximum) {
		do {
			loop_counter.val.intval++;// increment counter
			Label_set_value(label, &loop_counter, TRUE);
			parse_ram_block(loop_start, loop_body);
		} while(loop_counter.val.intval < maximum);
	} else
		Label_set_value(label, &loop_counter, TRUE);
	// Free memory
	free(loop_body);
	// restore previous input:
	Input_now = outer_input;
	// GotByte of OuterInput would be '}' (if it would still exist)
	GetByte();	// fetch next byte
	return(ENSURE_EOS);
}
示例#4
0
// Conditional assembly ("!if"). Has to be re-entrant.
static enum eos_t PO_if(void) {// Now GotByte = illegal char
	intval_t	cond;

	cond = ALU_defined_int();
	if(GotByte != CHAR_SOB)
		Throw_serious_error(exception_no_left_brace);
	parse_block_else_block(!!cond);
	return(ENSURE_EOS);
}
示例#5
0
文件: basics.c 项目: martinpiper/ACME
// Reserve space by sending bytes of given value ("!fi" / "!fill" pseudo opcode)
static enum eos_t PO_fill(void) {
	intval_t	fill	= FILLVALUE_FILL,
			size	= ALU_defined_int();

	if(Input_accept_comma())
		fill = ALU_any_int();
	while(size--)
		Output_8b(fill);
	return(ENSURE_EOS);
}
示例#6
0
// Check a condition expression
static bool check_condition(loopcond_t* condition) {
	intval_t	expression;

	// First, check whether there actually *is* a condition
	if(condition->body == NULL)
		return(TRUE);	// non-existant conditions are always true
	// set up input for expression evaluation
	Input_now->line_number = condition->line;
	Input_now->src.ram_ptr = condition->body;
	GetByte();	// proceed with next char
	expression = ALU_defined_int();
	if(GotByte)
		Throw_serious_error(exception_syntax);
	if(condition->type == ID_UNTIL)
		return(!expression);
	return(!!expression);
}
示例#7
0
文件: cpu.c 项目: Jedzia/acm3
// Start offset assembly
static enum eos_t PO_pseudopc(void) {
	bool		outer_state	= uses_pseudo_pc;
	intval_t	new_pc,
			outer_offset	= current_offset;
	int		outer_flags	= CPU_pc.flags;

	// set new
	new_pc = ALU_defined_int();
	current_offset = (current_offset + new_pc - CPU_pc.intval) & 0xffff;
	CPU_pc.intval = new_pc;
	CPU_pc.flags |= MVALUE_DEFINED | MVALUE_IS_ADDRESS;
	uses_pseudo_pc = TRUE;
	// If there's a block, parse that and then restore old value!
	if(Parse_optional_block()) {
		// restore old
		uses_pseudo_pc = outer_state;
		CPU_pc.flags = outer_flags;
		CPU_pc.intval = (outer_offset + CPU_pc.intval - current_offset) & 0xffff;
		current_offset = outer_offset;
	} else
		Throw_first_pass_warning(Warning_old_offset_assembly);
	return(ENSURE_EOS);
}