summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile22
-rw-r--r--backend.c32
-rw-r--r--backend.h1
-rwxr-xr-xcpu_dsl.py282
-rw-r--r--m68k.cpu770
-rw-r--r--trans.c18
6 files changed, 1057 insertions, 68 deletions
diff --git a/Makefile b/Makefile
index 468d6f4..17b9246 100644
--- a/Makefile
+++ b/Makefile
@@ -178,22 +178,23 @@ endif
endif
TRANSOBJS=gen.o backend.o $(MEM) arena.o tern.o
-M68KOBJS=68kinst.o m68k_core.o
+M68KOBJS=68kinst.o
+
+ifdef NEW_CORE
+Z80OBJS=z80.o z80inst.o
+M68KOBJS+= m68k.o
+CFLAGS+= -DNEW_CORE
+else
+Z80OBJS=z80inst.o z80_to_x86.o
ifeq ($(CPU),x86_64)
-M68KOBJS+= m68k_core_x86.o
+M68KOBJS+= m68k_core.o m68k_core_x86.o
TRANSOBJS+= gen_x86.o backend_x86.o
else
ifeq ($(CPU),i686)
-M68KOBJS+= m68k_core_x86.o
+M68KOBJS+= m68k_core.o m68k_core_x86.o
TRANSOBJS+= gen_x86.o backend_x86.o
endif
endif
-
-ifdef NEW_CORE
-Z80OBJS=z80.o z80inst.o
-CFLAGS+= -DNEW_CORE
-else
-Z80OBJS=z80inst.o z80_to_x86.o
endif
AUDIOOBJS=ym2612.o psg.o wave.o
CONFIGOBJS=config.o tern.o util.o paths.o
@@ -339,6 +340,9 @@ offsets : offsets.c z80_to_x86.h m68k_core.h
vos_prog_info : vos_prog_info.o vos_program_module.o
$(CC) -o vos_prog_info vos_prog_info.o vos_program_module.o
+m68k.c : m68k.cpu cpu_dsl.py
+ ./cpu_dsl.py -d call $< > $@
+
%.c : %.cpu cpu_dsl.py
./cpu_dsl.py -d goto $< > $@
diff --git a/backend.c b/backend.c
index f95e604..4629c16 100644
--- a/backend.c
+++ b/backend.c
@@ -154,6 +154,38 @@ uint16_t read_word(uint32_t address, void **mem_pointers, cpu_options *opts, voi
return 0xFFFF;
}
+void write_word(uint32_t address, uint16_t value, void **mem_pointers, cpu_options *opts, void *context)
+{
+ memmap_chunk const *chunk = find_map_chunk(address, opts, 0, NULL);
+ if (!chunk) {
+ return;
+ }
+ uint32_t offset = (address - chunk->start) & chunk->mask;
+ if (chunk->flags & MMAP_WRITE) {
+ uint8_t *base;
+ if (chunk->flags & MMAP_PTR_IDX) {
+ base = mem_pointers[chunk->ptr_index];
+ } else {
+ base = chunk->buffer;
+ }
+ if (base) {
+ if ((chunk->flags & MMAP_ONLY_ODD) || (chunk->flags & MMAP_ONLY_EVEN)) {
+ offset /= 2;
+ if (chunk->flags & MMAP_ONLY_EVEN) {
+ value >>= 16;
+ }
+ base[offset] = value;
+ } else {
+ *(uint16_t *)(base + offset) = value;
+ }
+ return;
+ }
+ }
+ if ((!(chunk->flags & MMAP_WRITE) || (chunk->flags & MMAP_FUNC_NULL)) && chunk->write_16) {
+ chunk->write_16(offset, context, value);
+ }
+}
+
uint8_t read_byte(uint32_t address, void **mem_pointers, cpu_options *opts, void *context)
{
memmap_chunk const *chunk = find_map_chunk(address, opts, 0, NULL);
diff --git a/backend.h b/backend.h
index af07c3e..9f2cf5e 100644
--- a/backend.h
+++ b/backend.h
@@ -97,6 +97,7 @@ code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk const * memmap, uint32_t n
void * get_native_pointer(uint32_t address, void ** mem_pointers, cpu_options * opts);
void * get_native_write_pointer(uint32_t address, void ** mem_pointers, cpu_options * opts);
uint16_t read_word(uint32_t address, void **mem_pointers, cpu_options *opts, void *context);
+void write_word(uint32_t address, uint16_t value, void **mem_pointers, cpu_options *opts, void *context);
uint8_t read_byte(uint32_t address, void **mem_pointers, cpu_options *opts, void *context);
void write_byte(uint32_t address, uint8_t value, void **mem_pointers, cpu_options *opts, void *context);
memmap_chunk const *find_map_chunk(uint32_t address, cpu_options *opts, uint16_t flags, uint32_t *size_sum);
diff --git a/cpu_dsl.py b/cpu_dsl.py
index 611dd96..d8bd7a8 100755
--- a/cpu_dsl.py
+++ b/cpu_dsl.py
@@ -48,6 +48,7 @@ class Instruction(Block):
self.regValues = {}
self.varyingBits = 0
self.invalidFieldValues = {}
+ self.invalidCombos = []
self.newLocals = []
for field in fields:
self.varyingBits += fields[field][1]
@@ -58,9 +59,17 @@ class Instruction(Block):
size = int(op.params[1])
self.locals[name] = size
elif op.op == 'invalid':
- name = op.params[0]
- value = int(op.params[1])
- self.invalidFieldValues.setdefault(name, set()).add(value)
+ if len(op.params) < 3:
+ name = op.params[0]
+ value = int(op.params[1])
+ self.invalidFieldValues.setdefault(name, set()).add(value)
+ else:
+ vmap = {}
+ for i in range(0, len(op.params), 2):
+ name = op.params[i]
+ value = int(op.params[i+1])
+ vmap[name] = value
+ self.invalidCombos.append(vmap)
else:
self.implementation.append(op)
@@ -89,12 +98,29 @@ class Instruction(Block):
for i in range(0, 1 << self.varyingBits):
iword = self.value
doIt = True
+ combos = []
+ for combo in self.invalidCombos:
+ combos.append(dict(combo))
for field in self.fields:
shift,bits = self.fields[field]
val = i & ((1 << bits) - 1)
if field in self.invalidFieldValues and val in self.invalidFieldValues[field]:
doIt = False
break
+ nextcombos = []
+ for combo in combos:
+ if field in combo:
+ if combo[field] == val:
+ del combo[field]
+ if not combo:
+ doIt = False
+ break
+ else:
+ continue
+ nextcombos.append(combo)
+ combos = nextcombos
+ if not doIt:
+ break
i >>= bits
iword |= val << shift
if doIt:
@@ -132,7 +158,7 @@ class Instruction(Block):
self.processOps(prog, fieldVals, output, otype, self.implementation)
if prog.dispatch == 'call':
- begin = '\nvoid ' + self.generateName(value) + '(' + prog.context_type + ' *context)\n{'
+ begin = '\nvoid ' + self.generateName(value) + '(' + prog.context_type + ' *context, uint32_t target_cycle)\n{'
elif prog.dispatch == 'goto':
begin = '\n' + self.generateName(value) + ': {'
else:
@@ -143,6 +169,8 @@ class Instruction(Block):
output.append(prog.flags.disperseFlags(prog, otype))
for var in self.newLocals:
begin += '\n\tuint{sz}_t {name};'.format(sz=self.locals[var], name=var)
+ for size in prog.temp:
+ begin += '\n\tuint{sz}_t gen_tmp{sz}__;'.format(sz=size)
prog.popScope()
if prog.dispatch == 'goto':
output += prog.nextInstruction(otype)
@@ -237,6 +265,20 @@ class Op:
else:
a = params[0]
b = params[1]
+ needsSizeAdjust = False
+ if len(params) > 3:
+ size = params[3]
+ if size == 0:
+ size = 8
+ elif size == 1:
+ size = 16
+ else:
+ size = 32
+ prog.lastSize = size
+ destSize = prog.paramSize(rawParams[2])
+ if destSize > size:
+ needsSizeAdjust = True
+ prog.sizeAdjust = size
needsCarry = needsOflow = needsHalf = False
if flagUpdates:
for flag in flagUpdates:
@@ -248,20 +290,35 @@ class Op:
elif calc == 'overflow':
needsOflow = True
decl = ''
- if needsCarry or needsOflow or needsHalf:
- size = prog.paramSize(rawParams[2])
+ if needsCarry or needsOflow or needsHalf or (flagUpdates and needsSizeAdjust):
+ if len(params) <= 3:
+ size = prog.paramSize(rawParams[2])
if needsCarry and op != 'lsr':
size *= 2
decl,name = prog.getTemp(size)
dst = prog.carryFlowDst = name
prog.lastA = a
prog.lastB = b
+ if size == 64:
+ a = '((uint64_t){a})'.format(a=a)
+ b = '((uint64_t){b})'.format(b=b)
prog.lastBFlow = b if op == '-' else '(~{b})'.format(b=b)
+ elif needsSizeAdjust:
+ decl,name = prog.getTemp(size)
+ dst = params[2]
+ return '{decl}\n\t{tmp} = ({a} & {mask}) {op} ({b} & {mask});\n\t{dst} = ({dst} & ~{mask}) | {tmp};'.format(
+ decl = decl, tmp = name, a = a, b = b, op = op, dst = dst, mask = ((1 << size) - 1)
+ )
else:
dst = params[2]
- return decl + '\n\t{dst} = {a} {op} {b};'.format(
- dst = dst, a = a, b = b, op = op
- )
+ if needsSizeAdjust:
+ return decl + '\n\t{dst} = ({a} & {mask}) {op} ({b} & {mask});'.format(
+ dst = dst, a = a, b = b, op = op, mask = (1 << prog.sizeAdjust) - 1
+ )
+ else:
+ return decl + '\n\t{dst} = {a} {op} {b};'.format(
+ dst = dst, a = a, b = b, op = op
+ )
self.impls['c'] = _impl
self.outOp = (2,)
return self
@@ -269,6 +326,20 @@ class Op:
def _impl(prog, params, rawParams, flagUpdates):
dst = params[1]
decl = ''
+ needsSizeAdjust = False
+ if len(params) > 2:
+ size = params[2]
+ if size == 0:
+ size = 8
+ elif size == 1:
+ size = 16
+ else:
+ size = 32
+ prog.lastSize = size
+ destSize = prog.paramSize(rawParams[1])
+ if destSize > size:
+ needsSizeAdjust = True
+ prog.sizeAdjust = size
if op == '-':
if flagUpdates:
for flag in flagUpdates:
@@ -279,7 +350,7 @@ class Op:
needsHalf = True
elif calc == 'overflow':
needsOflow = True
- if needsCarry or needsOflow or needsHalf:
+ if needsCarry or needsOflow or needsHalf or (flagUpdates and needsSizeAdjust):
size = prog.paramSize(rawParams[1])
if needsCarry:
size *= 2
@@ -288,9 +359,14 @@ class Op:
prog.lastA = 0
prog.lastB = params[0]
prog.lastBFlow = params[0]
- return decl + '\n\t{dst} = {op}{a};'.format(
- dst = dst, a = params[0], op = op
- )
+ if needsSizeAdjust:
+ return decl + '\n\t{dst} = ({dst} & ~{mask}) | (({op}{a}) & {mask});'.format(
+ dst = dst, a = params[0], op = op, mask = (1 << prog.sizeAdjust) - 1
+ )
+ else:
+ return decl + '\n\t{dst} = {op}{a};'.format(
+ dst = dst, a = params[0], op = op
+ )
self.impls['c'] = _impl
self.outOp = (1,)
return self
@@ -336,7 +412,7 @@ def _dispatchCImpl(prog, params):
else:
table = params[1]
if prog.dispatch == 'call':
- return '\n\timpl_{tbl}[{op}](context);'.format(tbl = table, op = params[0])
+ return '\n\timpl_{tbl}[{op}](context, target_cycle);'.format(tbl = table, op = params[0])
elif prog.dispatch == 'goto':
return '\n\tgoto *impl_{tbl}[{op}];'.format(tbl = table, op = params[0])
else:
@@ -358,25 +434,25 @@ def _updateFlagsCImpl(prog, params, rawParams):
if calc == 'bit' or calc == 'sign' or calc == 'carry' or calc == 'half' or calc == 'overflow':
myRes = lastDst
if calc == 'sign':
- resultBit = prog.paramSize(prog.lastDst) - 1
+ resultBit = prog.getLastSize() - 1
elif calc == 'carry':
if prog.lastOp.op in ('asr', 'lsr'):
resultBit = 0
myRes = prog.lastA
else:
- resultBit = prog.paramSize(prog.lastDst)
+ resultBit = prog.getLastSize()
if prog.lastOp.op == 'ror':
resultBit -= 1
elif calc == 'half':
- resultBit = prog.paramSize(prog.lastDst) - 4
+ resultBit = prog.getLastSize() - 4
myRes = '({a} ^ {b} ^ {res})'.format(a = prog.lastA, b = prog.lastB, res = lastDst)
elif calc == 'overflow':
- resultBit = prog.paramSize(prog.lastDst) - 1
+ resultBit = prog.getLastSize() - 1
myRes = '((({a} ^ {b})) & ({a} ^ {res}))'.format(a = prog.lastA, b = prog.lastBFlow, res = lastDst)
else:
#Note: offsetting this by the operation size - 8 makes sense for the Z80
#but might not for other CPUs with this kind of fixed bit flag behavior
- resultBit = int(resultBit) + prog.paramSize(prog.lastDst) - 8
+ resultBit = int(resultBit) + prog.getLastSize() - 8
if type(storage) is tuple:
reg,storageBit = storage
if storageBit == resultBit:
@@ -401,7 +477,7 @@ def _updateFlagsCImpl(prog, params, rawParams):
output.append('\n\t{reg} = {res} & {mask}U;'.format(reg=reg, res=myRes, mask = 1 << resultBit))
elif calc == 'zero':
if prog.carryFlowDst:
- realSize = prog.paramSize(prog.lastDst)
+ realSize = prog.getLastSize()
if realSize != prog.paramSize(prog.carryFlowDst):
lastDst = '({res} & {mask})'.format(res=lastDst, mask = (1 << realSize) - 1)
if type(storage) is tuple:
@@ -417,7 +493,7 @@ def _updateFlagsCImpl(prog, params, rawParams):
))
elif calc == 'parity':
parity = storage
- paritySize = prog.paramSize(prog.lastDst)
+ paritySize = prog.getLastSize()
if prog.carryFlowDst:
parityDst = paritySrc = prog.carryFlowDst
else:
@@ -441,7 +517,13 @@ def _updateFlagsCImpl(prog, params, rawParams):
))
if prog.carryFlowDst:
if prog.lastOp.op != 'cmp':
- output.append('\n\t{dst} = {tmpdst};'.format(dst = prog.resolveParam(prog.lastDst, prog.currentScope, {}), tmpdst = prog.carryFlowDst))
+ if prog.sizeAdjust:
+ output.append('\n\t{dst} = ({dst} & ~{mask}) | ({tmpdst} & {mask});'.format(
+ dst = prog.resolveParam(prog.lastDst, prog.currentScope, {}), tmpdst = prog.carryFlowDst, mask = ((1 << prog.sizeAdjust) - 1)
+ ))
+ prog.sizeAdjust = None
+ else:
+ output.append('\n\t{dst} = {tmpdst};'.format(dst = prog.resolveParam(prog.lastDst, prog.currentScope, {}), tmpdst = prog.carryFlowDst))
prog.carryFlowDst = None
if parity:
if paritySize > 8:
@@ -500,6 +582,17 @@ def _cmpCImpl(prog, params, rawParams, flagUpdates):
if not scope.resolveLocal(tmpvar):
scope.addLocal(tmpvar, size)
prog.lastDst = rawParams[1]
+ if len(params) > 2:
+ size = params[2]
+ if size == 0:
+ size = 8
+ elif size == 1:
+ size = 16
+ else:
+ size = 32
+ prog.lastSize = size
+ else:
+ prog.lastSize = None
return '\n\t{var} = {b} - {a};'.format(var = tmpvar, a = params[0], b = params[1])
def _asrCImpl(prog, params, rawParams, flagUpdates):
@@ -523,22 +616,23 @@ def _asrCImpl(prog, params, rawParams, flagUpdates):
def _sext(size, src):
if size == 16:
- return src | 0xFF00 if src & 0x80 else src
+ return src | 0xFF00 if src & 0x80 else src & 0x7F
else:
- return src | 0xFFFF0000 if src & 0x8000 else src
+ return src | 0xFFFF0000 if src & 0x8000 else src & 0x7FFF
def _sextCImpl(prog, params, rawParms):
if params[0] == 16:
- fmt = '\n\t{dst} = {src} & 0x80 ? {src} | 0xFF00 : {src};'
+ fmt = '\n\t{dst} = {src} & 0x80 ? {src} | 0xFF00 : {src} & 0x7F;'
else:
- fmt = '\n\t{dst} = {src} & 0x8000 ? {src} | 0xFFFF0000 : {src};'
+ fmt = '\n\t{dst} = {src} & 0x8000 ? {src} | 0xFFFF0000 : {src} & 0x7FFF;'
return fmt.format(src=params[1], dst=params[2])
def _getCarryCheck(prog):
carryFlag = None
- for flag in prog.flags.flagCalc:
+ for flag in prog.flags.flagOrder:
if prog.flags.flagCalc[flag] == 'carry':
carryFlag = flag
+ break
if carryFlag is None:
raise Exception('adc requires a defined carry flag')
carryStorage = prog.flags.getStorage(carryFlag)
@@ -550,6 +644,20 @@ def _getCarryCheck(prog):
return prog.resolveReg(carryStorage, None, (), False)
def _adcCImpl(prog, params, rawParams, flagUpdates):
+ needsSizeAdjust = False
+ if len(params) > 3:
+ size = params[3]
+ if size == 0:
+ size = 8
+ elif size == 1:
+ size = 16
+ else:
+ size = 32
+ prog.lastSize = size
+ destSize = prog.paramSize(rawParams[2])
+ if destSize > size:
+ needsSizeAdjust = True
+ prog.sizeAdjust = size
needsCarry = needsOflow = needsHalf = False
if flagUpdates:
for flag in flagUpdates:
@@ -562,8 +670,10 @@ def _adcCImpl(prog, params, rawParams, flagUpdates):
needsOflow = True
decl = ''
carryCheck = _getCarryCheck(prog)
- if needsCarry or needsOflow or needsHalf:
- size = prog.paramSize(rawParams[2])
+ vals = '1 : 0'
+ if needsCarry or needsOflow or needsHalf or (flagUpdates and needsSizeAdjust):
+ if len(params) <= 3:
+ size = prog.paramSize(rawParams[2])
if needsCarry:
size *= 2
decl,name = prog.getTemp(size)
@@ -571,13 +681,37 @@ def _adcCImpl(prog, params, rawParams, flagUpdates):
prog.lastA = params[0]
prog.lastB = params[1]
prog.lastBFlow = '(~{b})'.format(b=params[1])
+ if size == 64:
+ params[0] = '((uint64_t){a})'.format(a=params[0])
+ params[1] = '((uint64_t){b})'.format(b=params[1])
+ vals = '((uint64_t)1) : ((uint64_t)0)'
+ elif needsSizeAdjust:
+ decl,name = prog.getTemp(size)
+ dst = params[2]
+ return '{decl}\n\t{tmp} = ({a} & {mask}) + ({b} & {mask}) + ({check} ? 1 : 0);\n\t{dst} = ({dst} & ~{mask}) | {tmp};'.format(
+ decl = decl, tmp = name, a = a, b = b, op = op, dst = dst, mask = ((1 << size) - 1), check = carryCheck
+ )
else:
dst = params[2]
- return decl + '\n\t{dst} = {a} + {b} + ({check} ? 1 : 0);'.format(dst = dst,
- a = params[0], b = params[1], check = carryCheck
+ return decl + '\n\t{dst} = {a} + {b} + ({check} ? {vals});'.format(dst = dst,
+ a = params[0], b = params[1], check = carryCheck, vals = vals
)
def _sbcCImpl(prog, params, rawParams, flagUpdates):
+ needsSizeAdjust = False
+ if len(params) > 3:
+ size = params[3]
+ if size == 0:
+ size = 8
+ elif size == 1:
+ size = 16
+ else:
+ size = 32
+ prog.lastSize = size
+ destSize = prog.paramSize(rawParams[2])
+ if destSize > size:
+ needsSizeAdjust = True
+ prog.sizeAdjust = size
needsCarry = needsOflow = needsHalf = False
if flagUpdates:
for flag in flagUpdates:
@@ -590,7 +724,8 @@ def _sbcCImpl(prog, params, rawParams, flagUpdates):
needsOflow = True
decl = ''
carryCheck = _getCarryCheck(prog)
- if needsCarry or needsOflow or needsHalf:
+ vals = '1 : 0'
+ if needsCarry or needsOflow or needsHalf or (flagUpdates and needsSizeAdjust):
size = prog.paramSize(rawParams[2])
if needsCarry:
size *= 2
@@ -599,10 +734,20 @@ def _sbcCImpl(prog, params, rawParams, flagUpdates):
prog.lastA = params[1]
prog.lastB = params[0]
prog.lastBFlow = params[0]
+ if size == 64:
+ params[1] = '((uint64_t){a})'.format(a=params[1])
+ params[0] = '((uint64_t){b})'.format(b=params[0])
+ vals = '((uint64_t)1) : ((uint64_t)0)'
+ elif needsSizeAdjust:
+ decl,name = prog.getTemp(size)
+ dst = params[2]
+ return '{decl}\n\t{tmp} = ({b} & {mask}) - ({a} & {mask}) - ({check} ? 1 : 0);\n\t{dst} = ({dst} & ~{mask}) | {tmp};'.format(
+ decl = decl, tmp = name, a = params[0], b = params[1], op = op, dst = dst, mask = ((1 << size) - 1), check = carryCheck
+ )
else:
dst = params[2]
- return decl + '\n\t{dst} = {b} - {a} - ({check} ? 1 : 0);'.format(dst = dst,
- a = params[0], b = params[1], check=_getCarryCheck(prog)
+ return decl + '\n\t{dst} = {b} - {a} - ({check} ? {vals});'.format(dst = dst,
+ a = params[0], b = params[1], check=_getCarryCheck(prog), vals = vals
)
def _rolCImpl(prog, params, rawParams, flagUpdates):
@@ -697,6 +842,9 @@ _opMap = {
'ocall': Op().addImplementation('c', None, lambda prog, params: '\n\t{pre}{fun}({args});'.format(
pre = prog.prefix, fun = params[0], args = ', '.join(['context'] + [str(p) for p in params[1:]])
)),
+ 'pcall': Op().addImplementation('c', None, lambda prog, params: '\n\t(({typ}){fun})({args});'.format(
+ typ = params[1], fun = params[0], args = ', '.join([str(p) for p in params[2:]])
+ )),
'cycles': Op().addImplementation('c', None,
lambda prog, params: '\n\tcontext->cycles += context->opts->gen.clock_divider * {0};'.format(
params[0]
@@ -704,12 +852,12 @@ _opMap = {
),
'addsize': Op(
lambda a, b: b + (2 * a if a else 1)
- ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} + {sz} ? {sz} * 2 : 1;'.format(
+ ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} + ({sz} ? {sz} * 2 : 1);'.format(
dst = params[2], sz = params[0], val = params[1]
)),
'decsize': Op(
lambda a, b: b - (2 * a if a else 1)
- ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} - {sz} ? {sz} * 2 : 1;'.format(
+ ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} - ({sz} ? {sz} * 2 : 1);'.format(
dst = params[2], sz = params[0], val = params[1]
)),
'xchg': Op().addImplementation('c', (0,1), _xchgCImpl),
@@ -729,8 +877,8 @@ class NormalOp:
allParamsConst = flagUpdates is None and not prog.conditional
opDef = _opMap.get(self.op)
for param in self.params:
- allowConst = (self.op in prog.subroutines or len(procParams) != len(self.params) - 1) and param in parent.regValues
isDst = (not opDef is None) and len(procParams) in opDef.outOp
+ allowConst = (self.op in prog.subroutines or not isDst) and param in parent.regValues
if isDst and self.op == 'xchg':
#xchg uses its regs as both source and destination
#we need to resolve as both so that disperse/coalesce flag stuff gets done
@@ -794,6 +942,10 @@ class NormalOp:
else:
if param in fieldVals:
param = fieldVals[param]
+ else:
+ maybeLocal = parent.resolveLocal(param)
+ if maybeLocal and maybeLocal in parent.regValues:
+ param = parent.regValues[maybeLocal]
procParams.append(param)
prog.subroutines[self.op].inline(prog, procParams, output, otype, parent)
else:
@@ -872,7 +1024,7 @@ class Switch(ChildBlock):
output.append('\n\tswitch(' + param + ')')
output.append('\n\t{')
for case in self.cases:
- temp = prog.temp.copy()
+ #temp = prog.temp.copy()
self.current_locals = self.case_locals[case]
self.regValues = dict(self.parent.regValues)
output.append('\n\tcase {0}U: '.format(case) + '{')
@@ -881,16 +1033,16 @@ class Switch(ChildBlock):
self.processOps(prog, fieldVals, output, otype, self.cases[case])
output.append('\n\tbreak;')
output.append('\n\t}')
- prog.temp = temp
+ #prog.temp = temp
if self.default:
- temp = prog.temp.copy()
+ #temp = prog.temp.copy()
self.current_locals = self.default_locals
self.regValues = dict(self.parent.regValues)
output.append('\n\tdefault: {')
for local in self.default_locals:
output.append('\n\tuint{0}_t {1};'.format(self.default_locals[local], local))
self.processOps(prog, fieldVals, output, otype, self.default)
- prog.temp = temp
+ #prog.temp = temp
output.append('\n\t}')
prog.conditional = oldCond
prog.popScope()
@@ -915,10 +1067,15 @@ def _geuCImpl(prog, parent, fieldVals, output):
raise Exception(">=U not implemented in the general case yet")
def _eqCImpl(prog, parent, fieldVals, output):
- return '\n\tif (!{a}) {'.format(a=prog.resolveParam(prog.lastDst, None, {}))
+ if prog.lastOp.op == 'cmp':
+ output.pop()
+ params = [prog.resolveParam(p, parent, fieldVals) for p in prog.lastOp.params]
+ return '\n\tif ({a} == {b}) '.format(a=params[1], b = params[0]) + '{'
+ else:
+ return '\n\tif (!{a}) {{'.format(a=prog.resolveParam(prog.lastDst, None, {}))
def _neqCImpl(prog, parent, fieldVals, output):
- return '\n\tif ({a}) {'.format(a=prog.resolveParam(prog.lastDst, None, {}))
+ return '\n\tif ({a}) {{'.format(a=prog.resolveParam(prog.lastDst, None, {}))
_ifCmpImpl = {
'c': {
@@ -986,21 +1143,21 @@ class If(ChildBlock):
def generate(self, prog, parent, fieldVals, output, otype, flagUpdates):
self.regValues = parent.regValues
- try:
+ if self.cond in prog.booleans:
self._genConstParam(prog.checkBool(self.cond), prog, fieldVals, output, otype)
- except Exception:
+ else:
if self.cond in _ifCmpImpl[otype]:
oldCond = prog.conditional
prog.conditional = True
- temp = prog.temp.copy()
+ #temp = prog.temp.copy()
output.append(_ifCmpImpl[otype][self.cond](prog, parent, fieldVals, output))
self._genTrueBody(prog, fieldVals, output, otype)
- prog.temp = temp
+ #prog.temp = temp
if self.elseBody:
- temp = prog.temp.copy()
+ #temp = prog.temp.copy()
output.append('\n\t} else {')
self._genFalseBody(prog, fieldVals, output, otype)
- prog.temp = temp
+ #prog.temp = temp
output.append('\n\t}')
prog.conditional = oldCond
else:
@@ -1008,17 +1165,17 @@ class If(ChildBlock):
if type(cond) is int:
self._genConstParam(cond, prog, fieldVals, output, otype)
else:
- temp = prog.temp.copy()
+ #temp = prog.temp.copy()
output.append('\n\tif ({cond}) '.format(cond=cond) + '{')
oldCond = prog.conditional
prog.conditional = True
self._genTrueBody(prog, fieldVals, output, otype)
- prog.temp = temp
+ #prog.temp = temp
if self.elseBody:
- temp = prog.temp.copy()
+ #temp = prog.temp.copy()
output.append('\n\t} else {')
self._genFalseBody(prog, fieldVals, output, otype)
- prog.temp = temp
+ #prog.temp = temp
output.append('\n\t}')
prog.conditional = oldCond
@@ -1129,6 +1286,7 @@ class Flags:
self.flagBits = {}
self.flagCalc = {}
self.flagStorage = {}
+ self.flagOrder = []
self.flagReg = None
self.storageToFlags = {}
self.maxBit = -1
@@ -1153,6 +1311,7 @@ class Flags:
self.flagStorage[flag] = storage
storage,_,storebit = storage.partition('.')
self.storageToFlags.setdefault(storage, []).append((storebit, flag))
+ self.flagOrder.append(flag)
return self
def getStorage(self, flag):
@@ -1312,8 +1471,10 @@ class Program:
self.lastA = None
self.lastB = None
self.lastBFlow = None
+ self.sizeAdjust = None
self.conditional = False
self.declares = []
+ self.lastSize = None
def __str__(self):
pieces = []
@@ -1411,11 +1572,11 @@ class Program:
for include in self.includes:
body.append('#include "{0}"\n'.format(include))
if self.dispatch == 'call':
- body.append('\nstatic void unimplemented({pre}context *context)'.format(pre = self.prefix))
+ body.append('\nstatic void unimplemented({pre}context *context, uint32_t target_cycle)'.format(pre = self.prefix))
body.append('\n{')
body.append('\n\tfatal_error("Unimplemented instruction\\n");')
body.append('\n}\n')
- body.append('\ntypedef void (*impl_fun)({pre}context *context);'.format(pre=self.prefix))
+ body.append('\ntypedef void (*impl_fun)({pre}context *context, uint32_t target_cycle);'.format(pre=self.prefix))
for table in self.extra_tables:
body.append('\nstatic impl_fun impl_{name}[{sz}];'.format(name = table, sz=(1 << self.opsize)))
body.append('\nstatic impl_fun impl_main[{sz}];'.format(sz=(1 << self.opsize)))
@@ -1455,7 +1616,7 @@ class Program:
if size in self.temp:
return ('', self.temp[size])
self.temp[size] = 'gen_tmp{sz}__'.format(sz=size);
- return ('\n\tuint{sz}_t gen_tmp{sz}__;'.format(sz=size), self.temp[size])
+ return ('', self.temp[size])
def resolveParam(self, param, parent, fieldVals, allowConstant=True, isdst=False):
keepGoing = True
@@ -1477,6 +1638,7 @@ class Program:
if maybeLocal:
if isdst:
self.lastDst = param
+ self.lastSize = None
return maybeLocal
if param in fieldVals:
param = fieldVals[param]
@@ -1487,8 +1649,11 @@ class Program:
keepGoing = True
elif self.isReg(param):
return self.resolveReg(param, parent, fieldVals, isdst)
+ elif param in self.regs.pointers:
+ return 'context->' + param
if isdst:
self.lastDst = param
+ self.lastSize = None
return param
def isReg(self, name):
@@ -1551,6 +1716,11 @@ class Program:
return self.regs.regs[name]
return 32
+ def getLastSize(self):
+ if self.lastSize:
+ return self.lastSize
+ return self.paramSize(self.lastDst)
+
def pushScope(self, scope):
self.scopes.append(scope)
self.currentScope = scope
diff --git a/m68k.cpu b/m68k.cpu
new file mode 100644
index 0000000..9e33a31
--- /dev/null
+++ b/m68k.cpu
@@ -0,0 +1,770 @@
+info
+ prefix m68k_
+ opcode_size 16
+ body m68k_run_op
+ header m68k.h
+ interrupt m68k_interrupt
+ include m68k_util.c
+ sync_cycle m68k_sync_cycle
+
+declare
+ typedef m68k_context *(*m68k_reset_handler)(m68k_context *context);
+ void init_m68k_opts(m68k_options *opts, memmap_chunk * memmap, uint32_t num_chunks, uint32_t clock_divider);
+ m68k_context *init_68k_context(m68k_options * opts, m68k_reset_handler reset_handler);
+ void m68k_reset(m68k_context *context);
+ void m68k_print_regs(m68k_context *context);
+
+regs
+ dregs 32 d0 d1 d2 d3 d4 d5 d6 d7
+ aregs 32 a0 a1 a2 a3 a4 a5 a6 a7
+ pc 32
+ other_sp 32
+ scratch1 32
+ scratch2 32
+ int_cycle 32
+ prefetch 16
+ int_priority 8
+ int_num 8
+ int_pending 8
+ int_pending_num 8
+ int_ack 8
+ status 8
+ ccr 8
+ xflag 8
+ nflag 8
+ zflag 8
+ vflag 8
+ cflag 8
+ reset_handler ptrvoid
+ mem_pointers ptrvoid 8
+
+flags
+ register ccr
+ X 4 carry xflag
+ N 3 sign nflag
+ Z 2 zero zflag
+ V 1 overflow vflag
+ C 0 carry cflag
+
+m68k_prefetch
+ if dynarec
+
+ ccall m68k_read16_noinc context pc
+ mov result prefetch
+
+ end
+
+ if interp
+
+ mov pc scratch1
+ ocall read_16
+ mov scratch1 prefetch
+
+ end
+
+ add 2 pc pc
+
+check_user_mode_swap_ssp_usp
+ local tmp 8
+ and 0x20 status tmp
+ if tmp
+ else
+
+ xchg other_sp a7
+
+ end
+
+m68k_get_sr
+ lsl status 8 scratch1
+ or ccr scratch1 scratch1
+
+m68k_write32_lowfirst
+ arg value 32
+ add 2 scratch2 scratch2
+ mov value scratch1
+ ocall write_16
+
+ sub 2 scratch2 scratch2
+ lsr value 16 scratch1
+ ocall write_16
+
+m68k_write32
+ arg value 32
+ local tmp 32
+ mov value tmp
+ lsr value 16 scratch1
+ ocall write_16
+
+ add 2 scratch2 scratch2
+ mov tmp scratch1
+ ocall write_16
+
+m68k_read32
+ local tmp 32
+ add 2 scratch1 tmp
+ ocall read_16
+ xchg scratch1 tmp
+ ocall read_16
+ lsl tmp 16 tmp
+ or tmp scratch1 scratch1
+
+m68k_interrupt
+ cmp int_cycle cycles
+ if >=U
+
+ #INT_PENDING_NONE
+ cmp 255 int_pending
+ if =
+
+ mov int_priority int_pending
+ mov int_num int_pending_num
+
+ else
+
+ #INT_PENDING_SR_CHANGE
+ cmp 254 int_pending
+ if =
+
+ mov int_priority int_pending
+ mov int_num int_pending_num
+
+ else
+
+ check_user_mode_swap_ssp_usp
+
+ cycles 6
+ #save status reg
+ sub 6 a7 a7
+ m68k_get_sr
+ mov a7 scratch2
+ ocall write_16
+
+ #update status register
+ and 0x78 status status
+ or int_priority status status
+ or 0x20 status status
+
+ #Interrupt ack cycle
+ mov int_pending int_ack
+ if int_pending_num
+ cycles 4
+ else
+ #TODO: do the whole E clock variable latency nonsense
+ cycles 13
+ add 24 int_pending int_pending_num
+ end
+
+ #save pc
+ add 2 a7 scratch2
+ m68k_write32_lowfirst pc
+
+ lsl int_pending_num 2 scratch1
+ m68k_read32
+ mov scratch1 pc
+ update_sync
+ end
+
+m68k_run_op
+ dispatch prefetch
+
+m68k_mem_src
+ arg address 32
+ arg size 16
+ arg isdst 8
+ mov address scratch1
+ if isdst
+ mov address scratch2
+ meta ismem 1
+ end
+ switch size
+
+ case 0
+ ocall read_8
+
+ case 1
+ ocall read_16
+
+ case 2
+ m68k_read32
+
+ end
+ meta op scratch1
+
+m68k_write_size
+ arg size 16
+ arg lowfirst 8
+ switch size
+ case 0
+ ocall write_8
+
+ case 1
+ ocall write_16
+
+ case 2
+ if lowfirst
+ m68k_write32_lowfirst scratch1
+ else
+ m68k_write32 scratch1
+ end
+ end
+
+m68k_index_word
+ m68k_prefetch
+ local disp 32
+ and prefetch 255 disp
+ sext 16 disp disp
+ sext 32 disp disp
+ local index 16
+ lsr prefetch 12 index
+ local isareg 16
+ and index 8 isareg
+ and index 7 index
+ local islong 16
+ and prefetch 2048 islong
+
+ switch isareg
+ case 0
+ switch islong
+ case 0
+ sext 32 dregs.index scratch1
+ case 2048
+ mov dregs.index scratch1
+ end
+ case 8
+ switch islong
+ case 0
+ sext 32 aregs.index scratch1
+ case 2048
+ mov aregs.index scratch1
+ end
+ end
+ add disp scratch1 scratch1
+
+m68k_fetch_op_ea
+ arg mode 16
+ arg reg 16
+ arg Z 16
+ arg isdst 8
+ switch mode
+
+ case 0
+ #data reg direct
+ meta op dregs.reg
+ if isdst
+ meta ismem 0
+ end
+
+ case 1
+ #address reg direct
+ meta op aregs.reg
+ if isdst
+ meta ismem 0
+ end
+
+ case 2
+ #address reg indirect
+ m68k_mem_src aregs.reg Z isdst
+
+ case 3
+ #postincrement
+ m68k_mem_src aregs.reg Z isdst
+ switch reg
+ case 7
+ if Z
+ addsize Z aregs.reg aregs.reg
+ else
+ addsize 1 aregs.reg aregs.reg
+ end
+ default
+ addsize Z aregs.reg aregs.reg
+ end
+
+ case 4
+ #predecrement
+ switch reg
+ case 7
+ if Z
+ decsize Z aregs.reg aregs.reg
+ else
+ decsize 1 aregs.reg aregs.reg
+ end
+ default
+ decsize Z aregs.reg aregs.reg
+ end
+ cycles 2
+ m68k_mem_src aregs.reg Z isdst
+
+ case 5
+ #displacement
+ m68k_prefetch
+ sext 32 prefetch scratch1
+ add scratch1 aregs.reg scratch1
+ m68k_mem_src scratch1 Z isdst
+
+ case 6
+ #indexed
+ m68k_index_word
+ add aregs.reg scratch1 scratch1
+
+ m68k_mem_src scratch1 Z isdst
+ case 7
+ #pc-relative and absolute modes
+
+ switch reg
+ case 0
+ #absolute short
+ m68k_prefetch
+ sext 32 prefetch scratch1
+ m68k_mem_src scratch1 Z isdst
+
+ case 1
+ #absolute long
+ local address 32
+ m68k_prefetch
+ lsl prefetch 16 address
+ m68k_prefetch
+ or prefetch address scratch1
+ m68k_mem_src scratch1 Z isdst
+
+ case 2
+ #pc displaceent
+ m68k_prefetch
+ sext 32 prefetch scratch1
+ add scratch1 pc scratch1
+ sub 2 scratch1 scratch1
+ m68k_mem_src scratch1 Z isdst
+
+ case 3
+ #pc indexed
+ m68k_index_word
+ add pc scratch1 scratch1
+ sub 2 scratch1 scratch1
+ m68k_mem_src scratch1 Z isdst
+
+ case 4
+ #immediate
+ switch Z
+ case 2
+ local tmp32 32
+ m68k_prefetch
+ lsl prefetch 16 tmp32
+ m68k_prefetch
+ or prefetch tmp32 scratch1
+
+ default
+ m68k_prefetch
+ mov prefetch scratch1
+ end
+ meta op scratch1
+
+ end
+
+ end
+
+m68k_fetch_src_ea
+ arg mode 16
+ arg reg 16
+ arg Z 16
+ m68k_fetch_op_ea mode reg Z 0
+ meta src op
+ switch mode
+ case 0
+ meta src_is_mem 0
+ case 1
+ meta src_is_mem 0
+ default
+ meta src_is_mem 1
+ end
+
+m68k_fetch_dst_ea
+ arg mode 16
+ arg reg 16
+ arg Z 16
+ m68k_fetch_op_ea mode reg Z 1
+ meta dst op
+
+m68k_save_dst
+ arg Z 16
+ if ismem
+ m68k_write_size Z 0
+ end
+
+1101DDD0ZZMMMRRR add_ea_dn
+ invalid M 7 R 5
+ invalid M 7 R 6
+ invalid M 7 R 7
+ invalid Z 3
+ m68k_fetch_src_ea M R Z
+
+ add src dregs.D dregs.D Z
+ update_flags XNZVC
+ m68k_prefetch
+
+1101DDD1ZZMMMRRR add_dn_ea
+ invalid M 7 R 2
+ invalid M 7 R 3
+ invalid M 7 R 4
+ invalid M 7 R 5
+ invalid M 7 R 6
+ invalid M 7 R 7
+ invalid Z 3
+ m68k_fetch_dst_ea M R Z
+
+ add dregs.D dst dst Z
+ update_flags XNZVC
+ m68k_save_dst Z
+ m68k_prefetch
+
+1101AAAZ11MMMRRR adda
+ invalid M 7 R 5
+ invalid M 7 R 6
+ invalid M 7 R 7
+ local size 16
+ local ext_src 32
+ if Z
+ mov 2 size
+ else
+ mov 1 size
+ end
+ m68k_fetch_src_ea M R size
+ switch size
+ case 1
+ sext 32 src ext_src
+ meta src ext_src
+ end
+
+ add src aregs.A aregs.A
+ m68k_prefetch
+
+00000110ZZMMMRRR addi
+ local immed 32
+ invalid Z 3
+ invalid M 7 R 2
+ invalid M 7 R 3
+ invalid M 7 R 4
+ invalid M 7 R 5
+ invalid M 7 R 6
+ invalid M 7 R 7
+ #fetch immediate operand
+ m68k_prefetch
+ switch Z
+ case 2
+ lsl prefetch 16 immed
+ m68k_prefetch
+ or prefetch immed immed
+ default
+ mov prefetch immed
+ end
+ #fetch dst EA
+ m68k_fetch_dst_ea M R Z
+
+ add immed dst dst Z
+ update_flags XNZVC
+ m68k_save_dst Z
+ m68k_prefetch
+
+0101III0ZZMMMRRR addq
+ invalid Z 3
+ invalid M 7 R 2
+ invalid M 7 R 3
+ invalid M 7 R 4
+ invalid M 7 R 5
+ invalid M 7 R 6
+ invalid M 7 R 7
+ local src 32
+ switch I
+ case 0
+ mov 8 src
+ default
+ mov I src
+ end
+
+ m68k_fetch_dst_ea M R Z
+ switch M
+ case 1
+ add src dst dst Z
+ default
+ add src dst dst Z
+ update_flags XNZVC
+ end
+ m68k_save_dst Z
+ m68k_prefetch
+
+1101DDD1ZZ000SSS addx_dy_dx
+ invalid Z 3
+ adc dregs.S dregs.D dregs.D Z
+ update_flags XNVC
+ switch Z
+ case 0
+ local tmp8 8
+ mov dregs.D tmp8
+ if tmp8
+ update_flags Z0
+ end
+ case 1
+ local tmp16 16
+ mov dregs.D tmp16
+ if tmp16
+ update_flags Z0
+ end
+ case 2
+ if dregs.D
+ update_flags Z0
+ end
+ end
+ m68k_prefetch
+
+1101DDD1ZZ001SSS addx_ay_ax
+ invalid Z 3
+ if Z
+ decsize Z aregs.S aregs.S
+ else
+ switch S
+ case 7
+ sub 2 aregs.S aregs.S
+ default
+ decsize Z aregs.S aregs.S
+ end
+ end
+ mov aregs.S scratch1
+ switch Z
+ case 0
+ ocall read_8
+ case 1
+ ocall read_16
+ case 2
+ m68k_read32
+ end
+ mov scratch1 scratch2
+ if Z
+ decsize Z aregs.D aregs.D
+ else
+ switch D
+ case 7
+ sub 2 aregs.D aregs.D
+ default
+ decsize Z aregs.D aregs.D
+ end
+ end
+ mov aregs.D scratch1
+ switch Z
+ case 0
+ ocall read_8
+ case 1
+ ocall read_16
+ case 2
+ m68k_read32
+ end
+ adc scratch2 scratch1 scratch1 Z
+ update_flags XNVC
+ switch Z
+ case 0
+ local tmp8 8
+ mov dregs.D tmp8
+ if tmp8
+ update_flags Z0
+ end
+ case 1
+ local tmp16 16
+ mov dregs.D tmp16
+ if tmp16
+ update_flags Z0
+ end
+ case 2
+ if dregs.D
+ update_flags Z0
+ end
+ end
+ mov aregs.D scratch2
+ m68k_write_size Z 0
+ m68k_prefetch
+
+
+00ZZRRRMMMEEESSS move
+ invalid Z 0
+ invalid M 1
+ invalid M 7 #not actually invalid, but will be handled separately due to DSL limitations
+ invalid E 7 S 5
+ invalid E 7 S 6
+ invalid E 7 S 7
+ local size 8
+ local memsrc 32
+ #move uses a different size format than most instructions
+ switch Z
+ case 1
+ mov 0 size
+ case 2
+ mov 2 size
+ case 3
+ mov 1 size
+ end
+ m68k_fetch_src_ea E S size
+
+ if src_is_mem
+ #avoid clobbering src if we need scratch1
+ mov src memsrc
+ meta src memsrc
+ end
+
+ cmp 0 src size
+ update_flags NZV0C0
+
+ switch M
+ case 0
+ mov src dregs.R size
+
+ case 2
+ mov aregs.R scratch2
+ mov src scratch1
+ m68k_write_size size 0
+
+ case 3
+ mov aregs.R scratch2
+ mov src scratch1
+ switch R
+ case 7
+ if size
+ addsize size aregs.R aregs.R
+ else
+ addsize 1 aregs.R aregs.R
+ end
+ default
+ addsize size aregs.R aregs.R
+ end
+ m68k_write_size size 0
+
+ case 4
+ mov src scratch1
+ switch R
+ case 7
+ if size
+ decsize size aregs.R aregs.R
+ else
+ decsize 1 aregs.R aregs.R
+ end
+ default
+ decsize size aregs.R aregs.R
+ end
+ mov aregs.R scratch2
+ m68k_write_size size 1
+
+ case 5
+ m68k_prefetch
+ sext 32 prefetch scratch2
+ add aregs.R scratch2 scratch2
+ mov src scratch1
+ m68k_write_size size 0
+
+ case 6
+ m68k_index_word
+ add aregs.R scratch1 scratch2
+ mov src scratch1
+ m68k_write_size size 0
+ end
+ m68k_prefetch
+
+
+00ZZ00M111EEESSS move_abs
+ invalid E 7 S 5
+ invalid E 7 S 6
+ invalid E 7 S 7
+ invalid Z 0
+ local size 8
+ local memsrc 32
+ #move uses a different size format than most instructions
+ switch Z
+ case 1
+ mov 0 size
+ case 2
+ mov 2 size
+ case 3
+ mov 1 size
+ end
+ m68k_fetch_src_ea E S size
+
+ if src_is_mem
+ #avoid clobbering src if we need scratch1
+ mov src memsrc
+ meta src memsrc
+ end
+
+ cmp 0 src size
+ update_flags NZV0C0
+
+ switch M
+ case 0
+ m68k_prefetch
+ sext 32 prefetch scratch2
+
+ case 1
+ m68k_prefetch
+ lsl prefetch 16 scratch2
+ m68k_prefetch
+ or prefetch scratch2 scratch2
+ end
+ mov src scratch1
+ m68k_write_size size 0
+ m68k_prefetch
+
+00ZZRRR001EEESSS movea
+ local size 8
+ invalid Z 0
+ invalid Z 1
+ invalid E 7 S 5
+ invalid E 7 S 6
+ invalid E 7 S 7
+ switch Z
+ case 2
+ mov 2 size
+ case 3
+ mov 1 size
+ end
+ m68k_fetch_src_ea E S size
+ switch Z
+ case 2
+ mov src aregs.R
+ case 3
+ sext 32 src aregs.R
+ end
+ m68k_prefetch
+
+0100010011MMMRRR move_to_ccr
+ invalid M 1
+ invalid M 7 R 5
+ invalid M 7 R 6
+ invalid M 7 R 7
+ m68k_fetch_src_ea M R 1
+ mov scratch1 ccr
+ m68k_prefetch
+
+0100011011MMMRRR move_to_sr
+ invalid M 1
+ invalid M 7 R 5
+ invalid M 7 R 6
+ invalid M 7 R 7
+ m68k_fetch_src_ea M R 1
+ mov scratch1 ccr
+ lsr scratch1 8 status
+ update_sync
+ m68k_prefetch
+
+0100000011MMMRRR move_from_sr
+ invalid M 1
+ invalid M 7 R 2
+ invalid M 7 R 3
+ invalid M 7 R 4
+ invalid M 7 R 5
+ invalid M 7 R 6
+ invalid M 7 R 7
+ m68k_fetch_dst_ea M R 1
+ lsl status 8 scratch1
+ or ccr scratch1 scratch1
+ mov scratch1 dst
+ m68k_save_dst 1
+ m68k_prefetch
+
+0100111001110000 reset
+ cycles 124
+ if reset_handler
+ pcall reset_handler m68k_reset_handler context
+ end
diff --git a/trans.c b/trans.c
index 32193ca..1992e88 100644
--- a/trans.c
+++ b/trans.c
@@ -4,7 +4,11 @@
BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
*/
#include "68kinst.h"
+#ifdef NEW_CORE
+#include "m68k.h"
+#else
#include "m68k_core.h"
+#endif
#include "mem.h"
#include <stdio.h>
#include <stdlib.h>
@@ -19,6 +23,7 @@ void render_infobox(char * title, char * buf)
{
}
+#ifndef NEW_CORE
m68k_context * sync_components(m68k_context * context, uint32_t address)
{
if (context->current_cycle > 0x80000000) {
@@ -29,6 +34,7 @@ m68k_context * sync_components(m68k_context * context, uint32_t address)
}
return context;
}
+#endif
m68k_context *reset_handler(m68k_context *context)
{
@@ -74,11 +80,17 @@ int main(int argc, char ** argv)
m68k_context * context = init_68k_context(&opts, reset_handler);
context->mem_pointers[0] = memmap[0].buffer;
context->mem_pointers[1] = memmap[1].buffer;
+#ifndef NEW_CORE
context->target_cycle = context->sync_cycle = 0x80000000;
- uint32_t address;
- address = filebuf[2] << 16 | filebuf[3];
- translate_m68k_stream(address, context);
+#endif
m68k_reset(context);
+#ifdef NEW_CORE
+ for (;;)
+ {
+ m68k_execute(context, 0x80000000);
+ context->cycles = 0;
+ }
+#endif
return 0;
}