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