comparison cpu_dsl.py @ 1759:6e4faa10f9ee

Store sync_cycle in context rather than in a local in CPU DSL. Fix the timing of a number of instructions in new Z80 core
author Michael Pavone <pavone@retrodev.com>
date Tue, 19 Feb 2019 22:51:33 -0800
parents 043cf458704c
children 7b6831305a6a
comparison
equal deleted inserted replaced
1757:bb4d19c7c047 1759:6e4faa10f9ee
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 669
670 def _updateSyncCImpl(prog, params): 670 def _updateSyncCImpl(prog, params):
671 return '\n\tsync_cycle = {sync}(context, target_cycle);'.format(sync=prog.sync_cycle) 671 return '\n\t{sync}(context, target_cycle);'.format(sync=prog.sync_cycle)
672 672
673 _opMap = { 673 _opMap = {
674 'mov': Op(lambda val: val).cUnaryOperator(''), 674 'mov': Op(lambda val: val).cUnaryOperator(''),
675 'not': Op(lambda val: ~val).cUnaryOperator('~'), 675 'not': Op(lambda val: ~val).cUnaryOperator('~'),
676 'lnot': Op(lambda val: 0 if val else 1).cUnaryOperator('!'), 676 'lnot': Op(lambda val: 0 if val else 1).cUnaryOperator('!'),
694 ), 694 ),
695 'cmp': Op().addImplementation('c', None, _cmpCImpl), 695 'cmp': Op().addImplementation('c', None, _cmpCImpl),
696 'sext': Op(_sext).addImplementation('c', 2, _sextCImpl), 696 'sext': Op(_sext).addImplementation('c', 2, _sextCImpl),
697 'ocall': Op().addImplementation('c', None, lambda prog, params: '\n\t{pre}{fun}({args});'.format( 697 'ocall': Op().addImplementation('c', None, lambda prog, params: '\n\t{pre}{fun}({args});'.format(
698 pre = prog.prefix, fun = params[0], args = ', '.join(['context'] + [str(p) for p in params[1:]]) 698 pre = prog.prefix, fun = params[0], args = ', '.join(['context'] + [str(p) for p in params[1:]])
699 ) + _updateSyncCImpl(prog, params)), 699 )),
700 'cycles': Op().addImplementation('c', None, 700 'cycles': Op().addImplementation('c', None,
701 lambda prog, params: '\n\tcontext->cycles += context->opts->gen.clock_divider * {0};'.format( 701 lambda prog, params: '\n\tcontext->cycles += context->opts->gen.clock_divider * {0};'.format(
702 params[0] 702 params[0]
703 ) 703 )
704 ), 704 ),
1031 self.regs = {} 1031 self.regs = {}
1032 self.pointers = {} 1032 self.pointers = {}
1033 self.regArrays = {} 1033 self.regArrays = {}
1034 self.regToArray = {} 1034 self.regToArray = {}
1035 self.addReg('cycles', 32) 1035 self.addReg('cycles', 32)
1036 self.addReg('sync_cycle', 32)
1036 1037
1037 def addReg(self, name, size): 1038 def addReg(self, name, size):
1038 self.regs[name] = size 1039 self.regs[name] = size
1039 1040
1040 def addPointer(self, name, size, count): 1041 def addPointer(self, name, size, count):
1385 1386
1386 def nextInstruction(self, otype): 1387 def nextInstruction(self, otype):
1387 output = [] 1388 output = []
1388 if self.dispatch == 'goto': 1389 if self.dispatch == 'goto':
1389 if self.interrupt in self.subroutines: 1390 if self.interrupt in self.subroutines:
1390 output.append('\n\tif (context->cycles >= sync_cycle) {') 1391 output.append('\n\tif (context->cycles >= context->sync_cycle) {')
1391 output.append('\n\tif (context->cycles >= target_cycle) { return; }') 1392 output.append('\n\tif (context->cycles >= target_cycle) { return; }')
1392 if self.interrupt in self.subroutines: 1393 if self.interrupt in self.subroutines:
1393 self.meta = {} 1394 self.meta = {}
1394 self.temp = {} 1395 self.temp = {}
1395 self.subroutines[self.interrupt].inline(self, [], output, otype, None) 1396 self.subroutines[self.interrupt].inline(self, [], output, otype, None)
1422 self._buildTable(otype, table, body, pieces) 1423 self._buildTable(otype, table, body, pieces)
1423 self._buildTable(otype, 'main', body, pieces) 1424 self._buildTable(otype, 'main', body, pieces)
1424 if self.dispatch == 'call' and self.body in self.subroutines: 1425 if self.dispatch == 'call' and self.body in self.subroutines:
1425 pieces.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type)) 1426 pieces.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type))
1426 pieces.append('\n{') 1427 pieces.append('\n{')
1427 pieces.append('\n\tuint32_t sync_cycle = {sync}(context, target_cycle);'.format(sync=self.sync_cycle)) 1428 pieces.append('\n\t{sync}(context, target_cycle);'.format(sync=self.sync_cycle))
1428 pieces.append('\n\twhile (context->cycles < target_cycle)') 1429 pieces.append('\n\twhile (context->cycles < target_cycle)')
1429 pieces.append('\n\t{') 1430 pieces.append('\n\t{')
1430 #TODO: Handle interrupts in call dispatch mode 1431 #TODO: Handle interrupts in call dispatch mode
1431 self.meta = {} 1432 self.meta = {}
1432 self.temp = {} 1433 self.temp = {}
1433 self.subroutines[self.body].inline(self, [], pieces, otype, None) 1434 self.subroutines[self.body].inline(self, [], pieces, otype, None)
1434 pieces.append('\n\t}') 1435 pieces.append('\n\t}')
1435 pieces.append('\n}') 1436 pieces.append('\n}')
1436 elif self.dispatch == 'goto': 1437 elif self.dispatch == 'goto':
1437 body.append('\n\tuint32_t sync_cycle = {sync}(context, target_cycle);'.format(sync=self.sync_cycle)) 1438 body.append('\n\t{sync}(context, target_cycle);'.format(sync=self.sync_cycle))
1438 body += self.nextInstruction(otype) 1439 body += self.nextInstruction(otype)
1439 pieces.append('\nunimplemented:') 1440 pieces.append('\nunimplemented:')
1440 pieces.append('\n\tfatal_error("Unimplemented instruction\\n");') 1441 pieces.append('\n\tfatal_error("Unimplemented instruction\\n");')
1441 pieces.append('\n}') 1442 pieces.append('\n}')
1442 return ''.join(body) + ''.join(pieces) 1443 return ''.join(body) + ''.join(pieces)