changeset 1715:4fd84c3efc72

Implement 16-bit addition in new Z80 core along with necessary CPU DSL fixes to make them work right
author Michael Pavone <pavone@retrodev.com>
date Tue, 29 Jan 2019 23:56:48 -0800
parents e170a0f75c4f
children 04cafe626118
files cpu_dsl.py z80.cpu z80_util.c
diffstat 3 files changed, 97 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/cpu_dsl.py	Tue Jan 29 22:17:15 2019 -0800
+++ b/cpu_dsl.py	Tue Jan 29 23:56:48 2019 -0800
@@ -55,7 +55,7 @@
 	def addOp(self, op):
 		if op.op == 'local':
 			name = op.params[0]
-			size = op.params[1]
+			size = int(op.params[1])
 			self.locals[name] = size
 		elif op.op == 'invalid':
 			name = op.params[0]
@@ -312,13 +312,15 @@
 			elif calc == 'carry':
 				resultBit = prog.paramSize(prog.lastDst)
 			elif calc == 'half':
-				resultBit = 4
+				resultBit = prog.paramSize(prog.lastDst) - 4
 				myRes = '({a} ^ {b} ^ {res})'.format(a = prog.lastA, b = prog.lastB, res = lastDst)
 			elif calc == 'overflow':
 				resultBit = prog.paramSize(prog.lastDst) - 1
 				myRes = '((({a} ^ {b})) & ({a} ^ {res}))'.format(a = prog.lastA, b = prog.lastBFlow, res = lastDst)
 			else:
-				resultBit = int(resultBit)
+				#Note: offsetting this by the operation size - 8 makes sense for the Z80
+				#but might not for other CPUs with this kind of fixed bit flag behavior
+				resultBit = int(resultBit) + prog.paramSize(prog.lastDst) - 8
 			if type(storage) is tuple:
 				reg,storageBit = storage
 				reg = prog.resolveParam(reg, None, {})
@@ -339,7 +341,11 @@
 					))
 			else:
 				reg = prog.resolveParam(storage, None, {})
-				output.append('\n\t{reg} = {res} & {mask}U;'.format(reg=reg, res=myRes, mask = 1 << resultBit))
+				maxBit = prog.paramSize(storage) - 1
+				if resultBit > maxBit:
+					output.append('\n\t{reg} = {res} >> {shift} & {mask}U;'.format(reg=reg, res=myRes, shift = resultBit - maxBit, mask = 1 << maxBit))
+				else:
+					output.append('\n\t{reg} = {res} & {mask}U;'.format(reg=reg, res=myRes, mask = 1 << resultBit))
 		elif calc == 'zero':
 			if type(storage) is tuple:
 				reg,storageBit = storage
@@ -1176,6 +1182,8 @@
 						return parent.regValues[param]
 					maybeLocal = parent.resolveLocal(param)
 					if maybeLocal:
+						if isdst:
+							self.lastDst = param
 						return maybeLocal
 				if param in fieldVals:
 					param = fieldVals[param]
@@ -1183,7 +1191,9 @@
 					param = self.meta[param]
 					keepGoing = True
 				elif self.isReg(param):
-					param = self.resolveReg(param, parent, fieldVals, isdst)
+					return self.resolveReg(param, parent, fieldVals, isdst)
+		if isdst:
+			self.lastDst = param
 		return param
 	
 	def isReg(self, name):
@@ -1233,9 +1243,12 @@
 	
 	
 	def paramSize(self, name):
-		size = self.currentScope.localSize(name)
-		if size:
-			return size
+		if name in self.meta:
+			return self.paramSize(self.meta[name])
+		for i in range(len(self.scopes) -1, -1, -1):
+			size = self.scopes[i].localSize(name)
+			if size:
+				return size
 		begin,sep,_ = name.partition('.')
 		if sep and self.regs.isRegArray(begin):
 			return self.regs.regArrays[begin][0]
--- a/z80.cpu	Tue Jan 29 22:17:15 2019 -0800
+++ b/z80.cpu	Tue Jan 29 23:56:48 2019 -0800
@@ -525,6 +525,43 @@
 	add a scratch1 a
 	update_flags SZYHVXN0C
 	
+z80_add16_hl
+	arg src 16
+	lsl h 8 hlt
+	or l hlt hlt
+	add 1 hlt wz
+	add src hlt hlt
+	update_flags YHXN0C
+	mov hlt l
+	lsr hlt 8 h
+	
+00001001 add_hl_bc
+	local hlw 16
+	local bcw 16
+	meta hlt hlw
+	lsl b 8 bcw
+	or c bcw bcw
+	z80_add16_hl bcw
+	
+00011001 add_hl_de
+	local hlw 16
+	local dew 16
+	meta hlt hlw
+	lsl d 8 dew
+	or e dew dew
+	z80_add16_hl dew
+	
+00101001 add_hl_hl
+	local hlw 16
+	meta hlt hlw
+	z80_add16_hl hlw
+
+	
+00111001 add_hl_sp
+	local hlw 16
+	meta hlt hlw
+	z80_add16_hl sp
+	
 10001RRR adc_reg
 	adc a main.R a
 	update_flags SZYHVXN0C
@@ -538,6 +575,43 @@
 	z80_fetch_immed
 	adc a scratch1 a
 	update_flags SZYHVXN0C
+	
+z80_adc16_hl
+	arg src 16
+	lsl h 8 hlt
+	or l hlt hlt
+	add 1 hlt wz
+	adc src hlt hlt
+	update_flags SZYHVXN0C
+	mov hlt l
+	lsr hlt 8 h
+	
+ed 01001010 adc_hl_bc
+	local hlw 16
+	local bcw 16
+	meta hlt hlw
+	lsl b 8 bcw
+	or c bcw bcw
+	z80_adc16_hl bcw
+	
+ed 01011010 adc_hl_de
+	local hlw 16
+	local dew 16
+	meta hlt hlw
+	lsl d 8 dew
+	or e dew dew
+	z80_adc16_hl dew
+	
+ed 01101010 adc_hl_hl
+	local hlw 16
+	meta hlt hlw
+	z80_adc16_hl hlw
+
+	
+ed 01111010 adc_hl_sp
+	local hlw 16
+	meta hlt hlw
+	z80_adc16_hl sp
 
 10010RRR sub_reg
 	sub main.R a a
--- a/z80_util.c	Tue Jan 29 22:17:15 2019 -0800
+++ b/z80_util.c	Tue Jan 29 23:56:48 2019 -0800
@@ -1,11 +1,13 @@
 
 void z80_read_8(z80_context *context)
 {
+	context->cycles += 3 * context->opts->gen.clock_divider;
 	context->scratch1 = read_byte(context->scratch1, NULL, &context->opts->gen, context);
 }
 
 void z80_write_8(z80_context *context)
 {
+	context->cycles += 3 * context->opts->gen.clock_divider;
 	write_byte(context->scratch2, context->scratch1, NULL, &context->opts->gen, context);
 }