more cleanup - moved some stuff between files

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@28 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2014-03-11 14:22:32 +00:00
parent 538dd38861
commit e1516161ce
9 changed files with 128 additions and 103 deletions

View File

@ -186,11 +186,11 @@ static int perform_pass(void)
int ii;
// call modules' "pass init" functions
Output_passinit(); // disable output (until PC gets set)
CPU_passinit(default_cpu); // set default cpu values (PC undefined)
Output_passinit(); // disable output, PC undefined
CPU_passinit(default_cpu); // set default cpu type
// if start address was given on command line, use it:
if (start_address != ILLEGAL_START_ADDRESS)
CPU_set_pc(start_address, 0);
vcpu_set_pc(start_address, 0);
Encoding_passinit(); // set default encoding
Section_passinit(); // set initial zone (untitled)
// init variables

View File

@ -12,12 +12,12 @@
#include <math.h> // only for fp support
#include "platform.h"
#include "alu.h"
#include "cpu.h"
#include "dynabuf.h"
#include "encoding.h"
#include "global.h"
#include "input.h"
#include "label.h"
#include "output.h"
#include "section.h"
#include "tree.h"
@ -485,9 +485,11 @@ static void parse_octal_value(void) // Now GotByte = "&"
// Parse program counter ('*')
static void parse_program_counter(void) // Now GotByte = "*"
{
struct result_int_t pc;
GetByte();
// FIXME - read pc via function call, then move cpu struct from .h to .c file
PUSH_INTOPERAND(CPU_state.pc.intval, CPU_state.pc.flags | MVALUE_EXISTS);
vcpu_read_pc(&pc);
PUSH_INTOPERAND(pc.intval, pc.flags | MVALUE_EXISTS);
}

View File

@ -116,9 +116,10 @@ static enum eos PO_binary(void)
fclose(fd);
// if verbose, produce some output
if ((pass_count == 0) && (Process_verbosity > 1)) {
// FIXME - read "add_to_pc" via function call so struct can be moved from .h to .c file
int amount = vcpu_get_statement_size();
printf("Loaded %d (0x%04x) bytes from file offset %ld (0x%04lx).\n",
CPU_state.add_to_pc, CPU_state.add_to_pc, skip, skip);
amount, amount, skip, skip);
}
return ENSURE_EOS;
}

View File

@ -2,7 +2,7 @@
// Copyright (C) 1998-2014 Marco Baye
// Have a look at "acme.c" for further info
//
// CPU stuff
// CPU type stuff
#include "config.h"
#include "alu.h"
#include "cpu.h"
@ -15,7 +15,6 @@
// constants
// FIXME - move to new cpu_type.c file
static struct cpu_type cpu_type_6502 = {
keyword_is_6502mnemo,
CPUFLAG_INDIRECTJMPBUGGY, // JMP ($xxFF) is buggy
@ -55,7 +54,6 @@ static struct cpu_type cpu_type_65816 = {
// variables
// predefined stuff
// FIXME - move to cpu_type.c file
static struct node_t *CPU_tree = NULL; // tree to hold CPU types
static struct node_t CPUs[] = {
// PREDEFNODE("z80", &cpu_type_Z80),
@ -68,13 +66,12 @@ static struct node_t CPUs[] = {
// ^^^^ this marks the last element
};
// FIXME - make static
struct cpu CPU_state; // current CPU state
// insert byte until PC fits condition
// FIXME - move to basics.c
static enum eos PO_align(void)
{
// FIXME - read cpu state via function call!
intval_t and,
equal,
fill,
@ -101,7 +98,6 @@ static enum eos PO_align(void)
}
// FIXME - move to cpu_type.c file
// try to find CPU type held in DynaBuf. Returns whether succeeded.
// FIXME - why not return ptr (or NULL to indicate failure)?
int CPU_find_cpu_struct(const struct cpu_type **target)
@ -145,10 +141,11 @@ static enum eos PO_realpc(void)
// start offset assembly
// FIXME - split into PO (move to basics.c) and backend
// FIXME - split into PO (move to basics.c) and backend (move to output.c)
// TODO - add a label argument to assign the block size afterwards (for assemble-to-end-address)
static enum eos PO_pseudopc(void)
{
// FIXME - read pc using a function call!
intval_t new_pc,
new_offset;
int outer_flags = CPU_state.pc.flags;
@ -171,45 +168,6 @@ static enum eos PO_pseudopc(void)
}
// set program counter to defined value (FIXME - allow for undefined!)
// if start address was given on command line, main loop will call this before each pass.
// in addition to that, it will be called on each "* = VALUE".
void CPU_set_pc(intval_t new_pc, int segment_flags)
{
intval_t new_offset;
new_offset = (new_pc - CPU_state.pc.intval) & 0xffff;
CPU_state.pc.intval = new_pc;
CPU_state.pc.flags |= MVALUE_DEFINED; // FIXME - remove when allowing undefined!
// now tell output buffer to start a new segment
Output_start_segment(new_offset, segment_flags);
}
/*
FIXME - TODO:
general stuff: PC and mem ptr might be marked as "undefined" via flags field.
However, their "value" fields are still updated, so we can calculate differences.
on pass init:
if value given on command line, set PC and out ptr to that value
otherwise, set both to zero and mark as "undefined"
when ALU asks for "*":
return current PC (value and flags)
when encountering "!pseudopc VALUE { BLOCK }":
parse new value (NEW: might be undefined!)
remember difference between current and new value
set PC to new value
after BLOCK, use remembered difference to change PC back
when encountering "* = VALUE":
parse new value (NEW: might be undefined!)
calculate difference between current PC and new value
set PC to new value
tell outbuf to add difference to mem ptr (starting a new segment) - if new value is undefined, tell outbuf to disable output
Problem: always check for "undefined"; there are some problematic combinations.
I need a way to return the size of a generated code block even if PC undefined.
*/
// if cpu type and value match, set register length variable to value.
// if cpu type and value don't match, complain instead.
static void check_and_set_reg_length(int *var, int make_long)
@ -235,14 +193,14 @@ static enum eos set_register_length(int *var, int make_long)
}
// switch to long accu ("!al" pseudo opcode)
// switch to long accumulator ("!al" pseudo opcode)
static enum eos PO_al(void)
{
return set_register_length(&CPU_state.a_is_long, TRUE);
}
// switch to short accu ("!as" pseudo opcode)
// switch to short accumulator ("!as" pseudo opcode)
static enum eos PO_as(void)
{
return set_register_length(&CPU_state.a_is_long, FALSE);
@ -283,16 +241,10 @@ void CPU_passinit(const struct cpu_type *cpu_type)
{
// handle cpu type (default is 6502)
CPU_state.type = cpu_type ? cpu_type : &cpu_type_6502;
CPU_state.pc.flags = 0; // not defined yet
CPU_state.pc.intval = 0; // same as output's write_idx on pass init
CPU_state.add_to_pc = 0; // increase PC by this at end of statement
CPU_state.a_is_long = FALSE; // short accu
CPU_state.xy_are_long = FALSE; // short index regs
}
// create cpu type tree (is done early)
// FIXME - move to cpu_type.c
void CPUtype_init(void)
{
Tree_add_table(&CPU_tree, CPUs);

View File

@ -2,55 +2,33 @@
// Copyright (C) 1998-2014 Marco Baye
// Have a look at "acme.c" for further info
//
// CPU stuff
#ifndef cpu_H
#define cpu_H
// CPU type stuff
#ifndef cpu_type_H
#define cpu_type_H
#include "config.h"
// FIXME - create cpu_type.c file and move cpu type stuff to it
// CPU type structure definition
struct cpu_type {
// This function is not allowed to change GlobalDynaBuf
// because that's where the mnemonic is stored!
int (*keyword_is_mnemonic)(int);
int flags;
int flags; // see below for bit meanings
char default_align_value;
};
#define CPUFLAG_INDIRECTJMPBUGGY (1u << 0) // warn if "jmp ($xxff)" is assembled
#define CPUFLAG_SUPPORTSLONGREGS (1u << 1) // allow "!al" and "!rl" pseudo opcodes
#define CPUFLAG_AB_NEEDS_0_ARG (1u << 2) // warn if "lxa #$xx" uses non-zero arg
// current CPU state
// FIXME - move struct definition to .c file and change other .c files' accesses to fn calls
struct cpu {
const struct cpu_type *type; // current CPU type (default 6502)
struct result_int_t pc; // current program counter (pseudo value)
int add_to_pc; // add to PC after statement
int a_is_long;
int xy_are_long;
};
// variables
// FIXME - restrict visibility to cpu.c file
extern struct cpu CPU_state; // current CPU state
// FIXME - move to new cpu_type.h file
// create cpu type tree (is done early)
extern void CPUtype_init(void);
// register pseudo opcodes (done later)
extern void CPU_init(void);
// set default values for pass
// set default value for pass
extern void CPU_passinit(const struct cpu_type *cpu_type);
// set program counter to defined value (FIXME - allow undefined!)
extern void CPU_set_pc(intval_t new_pc, int flags);
// FIXME - move to new cpu_type.h file
// try to find CPU type held in DynaBuf. Returns whether succeeded.
// FIXME - why not simply return struct ptr, or NULL in case of failure?
extern int CPU_find_cpu_struct(const struct cpu_type **target);

View File

@ -299,10 +299,7 @@ void Parse_until_eob_or_eof(void)
}
}
} while (GotByte != CHAR_EOS); // until end-of-statement
// adjust program counter
// FIXME - next two lines should be a function call!
CPU_state.pc.intval = (CPU_state.pc.intval + CPU_state.add_to_pc) & 0xffff;
CPU_state.add_to_pc = 0;
vcpu_end_statement(); // adjust program counter
// go on with next byte
GetByte(); //NEXTANDSKIPSPACE();
}

View File

@ -9,11 +9,11 @@
#include <stdio.h>
#include "acme.h"
#include "alu.h"
#include "cpu.h"
#include "dynabuf.h"
#include "global.h"
#include "input.h"
#include "label.h"
#include "output.h"
#include "platform.h"
#include "section.h"
#include "tree.h"
@ -206,16 +206,17 @@ static struct node_t pseudo_opcodes[] = {
// GlobalDynaBuf holds the label name.
void Label_implicit_definition(zone_t zone, int stat_flags, int force_bit, int change)
{
struct result_t result;
struct label *label;
struct result_int_t pc;
struct result_t result;
struct label *label;
label = Label_find(zone, force_bit);
// implicit label definition (label)
if ((stat_flags & SF_FOUND_BLANK) && warn_on_indented_labels)
Throw_first_pass_warning("Implicit label definition not in leftmost column.");
// FIXME - read pc via function call!
result.flags = CPU_state.pc.flags & MVALUE_DEFINED;
result.val.intval = CPU_state.pc.intval;
vcpu_read_pc(&pc);
result.flags = pc.flags & MVALUE_DEFINED;
result.val.intval = pc.intval;
Label_set_value(label, &result, change);
}

View File

@ -49,10 +49,12 @@ struct output {
struct segment list_head; // head element of doubly-linked ring list
} segment;
};
static struct output default_output;
static struct output *out = &default_output;
// variables
static struct output default_output;
static struct output *out = &default_output;
// FIXME - make static
struct vcpu CPU_state; // current CPU state
// FIXME - move file format stuff to some other .c file!
// predefined stuff
@ -480,6 +482,13 @@ void Output_passinit(void)
out->segment.start = NO_SEGMENT_START; // TODO - "no active segment" could be made a segment flag!
out->segment.max = OUTBUFFERSIZE - 1;
out->segment.flags = 0;
//vcpu stuff:
CPU_state.pc.flags = 0; // not defined yet
CPU_state.pc.intval = 0; // same as output's write_idx on pass init
CPU_state.add_to_pc = 0; // increase PC by this at end of statement
CPU_state.a_is_long = FALSE; // short accu
CPU_state.xy_are_long = FALSE; // short index regs
}
@ -537,6 +546,46 @@ void Output_start_segment(intval_t address_change, int segment_flags)
// TODO - add "!skip AMOUNT" pseudo opcode as alternative to "* = * + AMOUNT" (needed for assemble-to-end-address)
// set program counter to defined value (FIXME - allow for undefined!)
// if start address was given on command line, main loop will call this before each pass.
// in addition to that, it will be called on each "* = VALUE".
void vcpu_set_pc(intval_t new_pc, int segment_flags)
{
intval_t new_offset;
new_offset = (new_pc - CPU_state.pc.intval) & 0xffff;
CPU_state.pc.intval = new_pc;
CPU_state.pc.flags |= MVALUE_DEFINED; // FIXME - remove when allowing undefined!
// now tell output buffer to start a new segment
Output_start_segment(new_offset, segment_flags);
}
/*
FIXME - TODO:
general stuff: PC and mem ptr might be marked as "undefined" via flags field.
However, their "value" fields are still updated, so we can calculate differences.
on pass init:
if value given on command line, set PC and out ptr to that value
otherwise, set both to zero and mark as "undefined"
when ALU asks for "*":
return current PC (value and flags)
when encountering "!pseudopc VALUE { BLOCK }":
parse new value (NEW: might be undefined!)
remember difference between current and new value
set PC to new value
after BLOCK, use remembered difference to change PC back
when encountering "* = VALUE":
parse new value (NEW: might be undefined!)
calculate difference between current PC and new value
set PC to new value
tell outbuf to add difference to mem ptr (starting a new segment) - if new value is undefined, tell outbuf to disable output
Problem: always check for "undefined"; there are some problematic combinations.
I need a way to return the size of a generated code block even if PC undefined.
*/
// called when "* = EXPRESSION" is parsed
// setting program counter via "* = VALUE"
// FIXME - move to basics.c
@ -560,7 +609,27 @@ void PO_setpc(void)
segment_flags |= (int) node_body;
}
CPU_set_pc(new_addr, segment_flags);
vcpu_set_pc(new_addr, segment_flags);
}
// get program counter
void vcpu_read_pc(struct result_int_t *target)
{
*target = CPU_state.pc;
}
// get size of current statement (until now) - needed for "!bin" verbose output
int vcpu_get_statement_size(void)
{
return CPU_state.add_to_pc;
}
// adjust program counter (called at end of each statement)
void vcpu_end_statement(void)
{
CPU_state.pc.intval = (CPU_state.pc.intval + CPU_state.add_to_pc) & 0xffff;
CPU_state.add_to_pc = 0;
}

View File

@ -11,10 +11,26 @@
#include "config.h"
// Constants
// constants
#define MEMINIT_USE_DEFAULT 256
// current CPU state
// FIXME - move struct definition to .c file and change other .c files' accesses to fn calls
struct vcpu {
const struct cpu_type *type; // current CPU type (default 6502) (FIXME - move out of struct again?)
struct result_int_t pc; // current program counter (pseudo value)
int add_to_pc; // add to PC after statement
int a_is_long;
int xy_are_long;
};
// variables
// FIXME - restrict visibility to .c file
extern struct vcpu CPU_state; // current CPU state
// Prototypes
// Init file format tree (is done early)
@ -46,5 +62,14 @@ extern void Output_start_segment(intval_t address_change, int segment_flags);
// Show start and end of current segment
extern void Output_end_segment(void);
// set program counter to defined value (FIXME - allow undefined!)
extern void vcpu_set_pc(intval_t new_pc, int flags);
// get program counter
extern void vcpu_read_pc(struct result_int_t *target);
// get size of current statement (until now) - needed for "!bin" verbose output
extern int vcpu_get_statement_size(void);
// adjust program counter (called at end of each statement)
extern void vcpu_end_statement(void);
#endif