comparison cpu_dsl.py @ 1752:d6d4c006a7b3

Initial attempt at interrupts in new Z80 core and integrating it into main executable
author Michael Pavone <pavone@retrodev.com>
date Sun, 10 Feb 2019 11:58:23 -0800
parents 01236179fc71
children 33ec5df77fac
comparison
equal deleted inserted replaced
1751:c5d4e1d14dac 1752:d6d4c006a7b3
664 else: 664 else:
665 dst = params[2] 665 dst = params[2]
666 return decl + '\n\t{dst} = {a} >> {b} | {a} << ({size} + 1 - {b}) | ({check} ? 1 : 0) << ({size}-{b});'.format(dst = dst, 666 return decl + '\n\t{dst} = {a} >> {b} | {a} << ({size} + 1 - {b}) | ({check} ? 1 : 0) << ({size}-{b});'.format(dst = dst,
667 a = params[0], b = params[1], size=size, check=carryCheck 667 a = params[0], b = params[1], size=size, check=carryCheck
668 ) 668 )
669
670 def _updateSyncCImpl(prog, params):
671 return '\n\tsync_cycle = {sync}(context, target_cycle);'.format(sync=prog.sync_cycle)
669 672
670 _opMap = { 673 _opMap = {
671 'mov': Op(lambda val: val).cUnaryOperator(''), 674 'mov': Op(lambda val: val).cUnaryOperator(''),
672 'not': Op(lambda val: ~val).cUnaryOperator('~'), 675 'not': Op(lambda val: ~val).cUnaryOperator('~'),
673 'lnot': Op(lambda val: 0 if val else 1).cUnaryOperator('!'), 676 'lnot': Op(lambda val: 0 if val else 1).cUnaryOperator('!'),
709 ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} - {sz} ? {sz} * 2 : 1;'.format( 712 ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} - {sz} ? {sz} * 2 : 1;'.format(
710 dst = params[2], sz = params[0], val = params[1] 713 dst = params[2], sz = params[0], val = params[1]
711 )), 714 )),
712 'xchg': Op().addImplementation('c', (0,1), _xchgCImpl), 715 'xchg': Op().addImplementation('c', (0,1), _xchgCImpl),
713 'dispatch': Op().addImplementation('c', None, _dispatchCImpl), 716 'dispatch': Op().addImplementation('c', None, _dispatchCImpl),
714 'update_flags': Op().addImplementation('c', None, _updateFlagsCImpl) 717 'update_flags': Op().addImplementation('c', None, _updateFlagsCImpl),
718 'update_sync': Op().addImplementation('c', None, _updateSyncCImpl)
715 } 719 }
716 720
717 #represents a simple DSL instruction 721 #represents a simple DSL instruction
718 class NormalOp: 722 class NormalOp:
719 def __init__(self, parts): 723 def __init__(self, parts):
1026 def __init__(self): 1030 def __init__(self):
1027 self.regs = {} 1031 self.regs = {}
1028 self.pointers = {} 1032 self.pointers = {}
1029 self.regArrays = {} 1033 self.regArrays = {}
1030 self.regToArray = {} 1034 self.regToArray = {}
1035 self.addReg('cycles', 32)
1031 1036
1032 def addReg(self, name, size): 1037 def addReg(self, name, size):
1033 self.regs[name] = size 1038 self.regs[name] = size
1034 1039
1035 def addPointer(self, name, size, count): 1040 def addPointer(self, name, size, count):
1288 self.prefix = info.get('prefix', [''])[0] 1293 self.prefix = info.get('prefix', [''])[0]
1289 self.opsize = int(info.get('opcode_size', ['8'])[0]) 1294 self.opsize = int(info.get('opcode_size', ['8'])[0])
1290 self.extra_tables = info.get('extra_tables', []) 1295 self.extra_tables = info.get('extra_tables', [])
1291 self.context_type = self.prefix + 'context' 1296 self.context_type = self.prefix + 'context'
1292 self.body = info.get('body', [None])[0] 1297 self.body = info.get('body', [None])[0]
1298 self.interrupt = info.get('interrupt', [None])[0]
1299 self.sync_cycle = info.get('sync_cycle', [None])[0]
1293 self.includes = info.get('include', []) 1300 self.includes = info.get('include', [])
1294 self.flags = flags 1301 self.flags = flags
1295 self.lastDst = None 1302 self.lastDst = None
1296 self.scopes = [] 1303 self.scopes = []
1297 self.currentScope = None 1304 self.currentScope = None
1322 hFile.write('\n\ntypedef struct {') 1329 hFile.write('\n\ntypedef struct {')
1323 hFile.write('\n\tcpu_options gen;') 1330 hFile.write('\n\tcpu_options gen;')
1324 hFile.write('\n}} {0}options;'.format(self.prefix)) 1331 hFile.write('\n}} {0}options;'.format(self.prefix))
1325 hFile.write('\n\ntypedef struct {') 1332 hFile.write('\n\ntypedef struct {')
1326 hFile.write('\n\t{0}options *opts;'.format(self.prefix)) 1333 hFile.write('\n\t{0}options *opts;'.format(self.prefix))
1327 hFile.write('\n\tuint32_t cycles;')
1328 self.regs.writeHeader(otype, hFile) 1334 self.regs.writeHeader(otype, hFile)
1329 hFile.write('\n}} {0}context;'.format(self.prefix)) 1335 hFile.write('\n}} {0}context;'.format(self.prefix))
1330 hFile.write('\n') 1336 hFile.write('\n')
1331 hFile.write('\nvoid {pre}execute({type} *context, uint32_t target_cycle);'.format(pre = self.prefix, type = self.context_type)) 1337 hFile.write('\nvoid {pre}execute({type} *context, uint32_t target_cycle);'.format(pre = self.prefix, type = self.context_type))
1332 for decl in self.declares: 1338 for decl in self.declares:
1378 body.extend(pieces) 1384 body.extend(pieces)
1379 1385
1380 def nextInstruction(self, otype): 1386 def nextInstruction(self, otype):
1381 output = [] 1387 output = []
1382 if self.dispatch == 'goto': 1388 if self.dispatch == 'goto':
1389 if self.interrupt in self.subroutines:
1390 output.append('\n\tif (context->cycles >= sync_cycle) {')
1383 output.append('\n\tif (context->cycles >= target_cycle) { return; }') 1391 output.append('\n\tif (context->cycles >= target_cycle) { return; }')
1392 if self.interrupt in self.subroutines:
1393 self.meta = {}
1394 self.temp = {}
1395 self.subroutines[self.interrupt].inline(self, [], output, otype, None)
1396 output.append('\n\t}')
1397
1384 self.meta = {} 1398 self.meta = {}
1385 self.temp = {} 1399 self.temp = {}
1386 self.subroutines[self.body].inline(self, [], output, otype, None) 1400 self.subroutines[self.body].inline(self, [], output, otype, None)
1387 return output 1401 return output
1388 1402
1408 self._buildTable(otype, table, body, pieces) 1422 self._buildTable(otype, table, body, pieces)
1409 self._buildTable(otype, 'main', body, pieces) 1423 self._buildTable(otype, 'main', body, pieces)
1410 if self.dispatch == 'call' and self.body in self.subroutines: 1424 if self.dispatch == 'call' and self.body in self.subroutines:
1411 pieces.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type)) 1425 pieces.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type))
1412 pieces.append('\n{') 1426 pieces.append('\n{')
1427 pieces.append('\n\tuint32_t sync_cycle = {sync}(context, target_cycle);'.format(sync=self.sync_cycle))
1413 pieces.append('\n\twhile (context->cycles < target_cycle)') 1428 pieces.append('\n\twhile (context->cycles < target_cycle)')
1414 pieces.append('\n\t{') 1429 pieces.append('\n\t{')
1430 #TODO: Handle interrupts in call dispatch mode
1415 self.meta = {} 1431 self.meta = {}
1416 self.temp = {} 1432 self.temp = {}
1417 self.subroutines[self.body].inline(self, [], pieces, otype, None) 1433 self.subroutines[self.body].inline(self, [], pieces, otype, None)
1418 pieces.append('\n\t}') 1434 pieces.append('\n\t}')
1419 pieces.append('\n}') 1435 pieces.append('\n}')
1420 elif self.dispatch == 'goto': 1436 elif self.dispatch == 'goto':
1437 body.append('\n\tuint32_t sync_cycle = {sync}(context, target_cycle);'.format(sync=self.sync_cycle))
1421 body += self.nextInstruction(otype) 1438 body += self.nextInstruction(otype)
1422 pieces.append('\nunimplemented:') 1439 pieces.append('\nunimplemented:')
1423 pieces.append('\n\tfatal_error("Unimplemented instruction\\n");') 1440 pieces.append('\n\tfatal_error("Unimplemented instruction\\n");')
1424 pieces.append('\n}') 1441 pieces.append('\n}')
1425 return ''.join(body) + ''.join(pieces) 1442 return ''.join(body) + ''.join(pieces)