Mercurial > repos > blastem
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) |