Emily's Z80 assembler for the Gameboy.
Revision | b5e4f452f17581fdc39d0dc4a09daf6643b88681 (tree) |
---|---|
Zeit | 2021-02-09 11:46:58 |
Autor | AlaskanEmily <emily@alas...> |
Commiter | AlaskanEmily |
Add relative addressing for jr opcodes
@@ -116,6 +116,10 @@ class Block: | ||
116 | 116 | self._pushReloc(l, self.relocs8l) |
117 | 117 | self.pushByte(0) |
118 | 118 | |
119 | + def pushRelocRel(self, l): | |
120 | + self._pushReloc(l, self.relocsRel) | |
121 | + self.pushByte(0) | |
122 | + | |
119 | 123 | def pushASCII(self, s): |
120 | 124 | self.ascii.append((len(self.data), len(s))) |
121 | 125 | for c in s: |
@@ -151,6 +155,15 @@ class Block: | ||
151 | 155 | for addr in self.relocs8l[l]: |
152 | 156 | dest = self.resolveReloc(l, addr, all_blocks) |
153 | 157 | self.data[addr] = dest & 0xFF |
158 | + for l in self.relocsRel: | |
159 | + for addr in self.relocsRel[l]: | |
160 | + dest = self.resolveReloc(l, addr, all_blocks) - 1 | |
161 | + # Validate the distance... | |
162 | + abs_addr = self.base + addr | |
163 | + if dest - 128 > abs_addr or dest + 127 < abs_addr: | |
164 | + self.error("Relative jump is too far") | |
165 | + else: | |
166 | + self.data[addr] = (dest - abs_addr) & 0xFF | |
154 | 167 | |
155 | 168 | def evalBinop(self, expr, i, oplist, func): |
156 | 169 | i, val = func(self, expr, i) |
@@ -294,7 +307,12 @@ SOME_ARGS = { | ||
294 | 307 | "l":0x85, |
295 | 308 | "(hl)":0x86, |
296 | 309 | "a":0x87, |
297 | - "hl":{ "sp":0x39 }, | |
310 | + "hl":{ | |
311 | + "bc":0x09, | |
312 | + "de":0x19, | |
313 | + "hl":0x29, | |
314 | + "sp":0x39 | |
315 | + }, | |
298 | 316 | "sp":{ "r8":0xE9 }, |
299 | 317 | "d8":0xC6 |
300 | 318 | }, |
@@ -500,12 +518,15 @@ SOME_ARGS["ld"]["e"]["d8"] = 0x1E | ||
500 | 518 | SOME_ARGS["ld"]["l"]["d8"] = 0x2E |
501 | 519 | SOME_ARGS["ld"]["a"]["d8"] = 0x3E |
502 | 520 | |
503 | -def locateOperand(op, ptr, allow=(8,16)): | |
504 | - for p in "adri": | |
521 | +def locateOperand(op, ptr, allow=(8,16,'r')): | |
522 | + prefix_opts = "adi" | |
523 | + if 'r' in allow: | |
524 | + prefix_opts += 'r' | |
525 | + for p in prefix_opts: | |
505 | 526 | opts = [] |
506 | 527 | if 16 in allow: |
507 | 528 | opts.append(("16", Block.pushShort)) |
508 | - if 8 in allow: | |
529 | + if 8 in allow or p == 'r': | |
509 | 530 | opts.append(("8", Block.pushByte)) |
510 | 531 | for t in opts: |
511 | 532 | s, func = t |
@@ -516,6 +537,7 @@ def locateOperand(op, ptr, allow=(8,16)): | ||
516 | 537 | o = "(" + o + ")" |
517 | 538 | if o in op: |
518 | 539 | return (o, func) |
540 | + | |
519 | 541 | print("Error in " + str(op)) |
520 | 542 | return (None, None) |
521 | 543 |
@@ -538,14 +560,14 @@ def writeOpcode(mnemonic, block, ops, i, operands): | ||
538 | 560 | num = block.eval(operand[1:-1]) |
539 | 561 | # print("INFO: Evaluated " + operand[1:-1] + " as " + hex(num)) |
540 | 562 | else: |
541 | - if operand[0] in "<>=": | |
563 | + if operand[0] in "<>=@": | |
542 | 564 | c = operand[0] |
543 | 565 | operand = operand[1:] |
544 | 566 | operand = c + block.equ.get(operand, operand) |
545 | 567 | else: |
546 | 568 | operand = block.equ.get(operand, operand) |
547 | 569 | try: |
548 | - if operand[0] in "<>=": | |
570 | + if operand[0] in "<>=@": | |
549 | 571 | c = operand[0] |
550 | 572 | num = int(operand[1:], 0) |
551 | 573 | if c == '>': |
@@ -571,11 +593,14 @@ def writeOpcode(mnemonic, block, ops, i, operands): | ||
571 | 593 | elif operand[0] == '<': |
572 | 594 | pushReloc = Block.pushReloc8l |
573 | 595 | allow = [8] |
596 | + elif operand[0] == '@': | |
597 | + pushReloc = Block.pushRelocRel | |
598 | + allow = ['r'] | |
574 | 599 | else: |
575 | 600 | pushReloc = Block.pushReloc16 |
576 | 601 | allow = [16] |
577 | 602 | |
578 | - if operand[0] in "=<>": | |
603 | + if operand[0] in "=<>@": | |
579 | 604 | operand = operand[1:] |
580 | 605 | |
581 | 606 | key, func = locateOperand(ops, ptr, allow) |