Cocotb tests.
diff --git a/cocotb_tests/Makefile b/cocotb_tests/Makefile
new file mode 100644
index 0000000..63d8c80
--- /dev/null
+++ b/cocotb_tests/Makefile
@@ -0,0 +1,13 @@
+SIM ?= icarus
+TOPLEVEL_LANG ?= verilog
+
+# normal simulation
+VERILOG_SOURCES += $(PWD)/tb.v $(PWD)/synthesized.v
+
+# TOPLEVEL is the name of the toplevel module in your Verilog or VHDL file
+TOPLEVEL = tb
+
+# MODULE is the basename of the Python test file
+MODULE = test
+
+include $(shell cocotb-config --makefiles)/Makefile.sim
diff --git a/cocotb_tests/as2650.v b/cocotb_tests/as2650.v
new file mode 120000
index 0000000..be03868
--- /dev/null
+++ b/cocotb_tests/as2650.v
@@ -0,0 +1 @@
+../verilog/rtl/as2650.v
\ No newline at end of file
diff --git a/cocotb_tests/synth.sh b/cocotb_tests/synth.sh
new file mode 100644
index 0000000..5595d8d
--- /dev/null
+++ b/cocotb_tests/synth.sh
@@ -0,0 +1 @@
+./yosys_e -p "read_verilog as2650.v; synth -top as2650; write_verilog synthesized.v;" && clear
diff --git a/cocotb_tests/tb.v b/cocotb_tests/tb.v
new file mode 100644
index 0000000..59914c9
--- /dev/null
+++ b/cocotb_tests/tb.v
@@ -0,0 +1,43 @@
+`default_nettype none
+`timescale 1ns/1ps
+
+module tb (
+	input reset,
+	input clk,
+	input sense,
+
+	output [12:0] adr,
+	output rw,
+	output opreq,
+	output m_io,
+	output d_c,
+	output flag,
+	output wrp,
+
+	input [7:0] dbus_in,
+	output [7:0] dbus_out,
+	output oeb
+	);
+	
+	initial begin
+		$dumpfile ("tb.vcd");
+		$dumpvars (0, tb);
+		#1;
+	end
+
+	as2650 as2650 (
+		.reset(reset),
+		.clk(clk),
+		.sense(sense),
+		.adr(adr),
+		.rw(rw),
+		.opreq(opreq),
+		.m_io(m_io),
+		.d_c(d_c),
+		.flag(flag),
+		.dbus_in(dbus_in),
+		.dbus_out(dbus_out),
+		.oeb(oeb),
+		.wrp(wrp)
+	);
+endmodule
diff --git a/cocotb_tests/test.asm b/cocotb_tests/test.asm
new file mode 100644
index 0000000..3bf4a03
--- /dev/null
+++ b/cocotb_tests/test.asm
@@ -0,0 +1,409 @@
+PSL_CC1          equ 0b10000000
+PSL_CC0          equ 0b01000000
+PSL_IDC          equ 0b00100000
+PSL_BANK         equ 0b00010000
+PSL_WITH_CARRY   equ 0b00001000
+PSL_OVERFLOW     equ 0b00000100
+PSL_LOGICAL_COMP equ 0b00000010
+PSL_CARRY_FLAG   equ 0b00000001
+
+mem_end equ 8191
+
+org 0
+programentry:
+	lodi,r0 0x16
+	strz,r1
+	
+	stra,r1 mem_end
+	
+	lodi,r3 0xFF
+	stra,r3 mem_end-1
+	
+	lodi,r2 2
+	stra,r0 mem_end-4,r2
+	
+	lodi,r0 data>>8%256
+	stra,r0 mem_end-6
+	lodi,r0 data%256
+	stra,r0 mem_end-5
+	loda,r2 *mem_end-6
+	lodz,r2
+	lodi,r1 4
+	stra,r0 mem_end-10,r1-
+	lodz,r1
+	stra,r0 mem_end-10,r1-
+	eorz,r0
+	strz,r3
+	loda,r0 *mem_end-6,r3+
+	strz,r1
+	stra,r1 mem_end-9
+	
+relative_data_0:
+	nop
+	nop
+	lodi,r1 66
+	strr,r1 relative_data_0
+	eorz r0
+	lodr,r3 relative_data_0
+	stra,r3 mem_end-10
+	
+	lodi,r0 data+2>>8%256
+	strr,r0 relative_data_0
+	lodi,r0 data+2%256
+	strr,r0 relative_data_0+1
+	lodr,r3 *relative_data_0
+	stra,r3 mem_end-11
+	
+	lodi,r0 0xFF
+	eora,r0 data+3
+	stra,r0 mem_end-12
+	
+	lodi,r3 0b10001010
+	iori,r3 0b10000101
+	stra,r3 mem_end-13
+	
+relative_data_1:
+	nop
+	lodi,r0 16
+	strr,r0 relative_data_1
+	lodi,r2 8
+	addr,r2 relative_data_1
+	stra,r2 mem_end-14
+	
+	lodi,r1 0xFF
+	addi,r1 3
+	stra,r1 mem_end-15
+	eorz,r0
+	addi,r0 1
+	stra,r0 mem_end-16
+	
+	ppsl PSL_WITH_CARRY
+	lodi,r1 0xFF
+	addi,r1 3
+	stra,r1 mem_end-17
+	eorz,r0
+	addi,r0 1
+	stra,r0 mem_end-18
+	cpsl PSL_WITH_CARRY
+	lodi,r1 0xFF
+	addi,r1 3
+	stra,r1 mem_end-19
+	eorz,r0
+	addi,r0 1
+	stra,r0 mem_end-20
+	
+	lodi,r0 16
+	suba,r0 data+4
+	stra,r0 mem_end-21
+	
+	lodi,r3 5
+	subi,r3 8
+	stra,r3 mem_end-22
+	lodi,r0 15
+	lodi,r1 0
+	subz,r1
+	stra,r0 mem_end-23
+	
+	ppsl PSL_WITH_CARRY
+	ppsl PSL_CARRY_FLAG
+	lodi,r3 5
+	subi,r3 8
+	stra,r3 mem_end-24
+	lodi,r0 15
+	lodi,r1 0
+	subz,r1
+	stra,r0 mem_end-25
+	
+	cpsl PSL_CARRY_FLAG
+	lodi,r0 5
+	addi,r0 5
+	stra,r0 mem_end-26
+	addz,r0
+	stra,r0 mem_end-27
+	cpsl PSL_WITH_CARRY
+	
+	redd,r0
+	redd,r1
+	redd,r2
+	redd,r3
+	addz,r1
+	addz,r2
+	addz,r3
+	
+	stra,r0 mem_end-28
+	
+	lodi,r0 100
+	redc,r3
+	redc,r3
+	redc,r3
+	subz,r3
+	
+	stra,r0 mem_end-29
+	
+	lodi,r1 55
+	lodi,r2 66
+	lodi,r3 10
+	wrtd,r1
+	wrtd,r2
+	wrtd,r3
+	
+	lodi,r1 12
+	lodi,r2 38
+	lodi,r3 33
+	wrtc,r1
+	wrtc,r2
+	wrtc,r3
+	
+	lodi,r0 0b00001111
+	rrr,r0
+	stra,r0 mem_end-30
+	rrl,r0
+	stra,r0 mem_end-31
+	
+	ppsl PSL_WITH_CARRY
+	cpsl PSL_CARRY_FLAG
+	rrr,r0
+	stra,r0 mem_end-32
+	rrr,r0
+	stra,r0 mem_end-33
+	eorz,r0
+	rrl,r0
+	stra,r0 mem_end-34
+	rrl,r0
+	stra,r0 mem_end-35
+	
+	lodi,r1 128
+	rrl,r1
+	spsl
+	stra,r0 mem_end-36
+	strz,r2
+	andi,r0 0b11110110
+	lpsl
+	spsl
+	stra,r0 mem_end-37
+	lodz,r2
+	lpsl
+	tpsl 0b00001001
+	spsl
+	andi,r0 0b11000000
+	stra,r0 mem_end-38
+	tpsl 2
+	spsl
+	andi,r0 0b11000000
+	stra,r0 mem_end-39
+	cpsl PSL_WITH_CARRY
+	
+	lodi,r0 0b00001011
+	strz,r1
+	strz,r2
+	db 0xF6 ; tmi,r2 (not recognized by my assembler yet)
+	db 0b00000001
+	spsl
+	andi,r0 0b11000000
+	stra,r0 mem_end-40
+	db 0xF5 ; tmi,r1 (not recognized by my assembler yet)
+	db 0b11100001
+	spsl
+	andi,r0 0b11000000
+	stra,r0 mem_end-41
+	
+	lodi,r0 55
+	bctr,un skip_1
+	eorz,r0
+skip_1:
+	stra,r0 mem_end-42
+
+	lodi,r1 6
+	stra,r0 mem_end-444,r1-
+	stra,r1 mem_end-43
+	stra,r0 mem_end-444,r1-
+	stra,r1 mem_end-44
+	stra,r0 mem_end-444,r1-
+	stra,r1 mem_end-45
+loop:
+	stra,r0 mem_end-444,r1-
+	brnr,r1 loop
+	
+	lodi,r3 2
+	lodi,r0 55
+back_1:
+	bcfa,1 skip_2
+	lodi,r0 103
+skip_2:
+	stra,r0 mem_end-47,r3-
+	lodi,r0 180
+	brna,r3 back_1
+
+	lodi,r3 99
+	lodi,r0 200
+	subz,r3
+	spsl
+	andi,r0 0b11000000
+	stra,r0 mem_end-48
+	
+	lodi,r2 120
+	adda,r2 data+7
+	bcta,2 skip_3
+	lodi,r2 0
+skip_3:
+	stra,r2 mem_end-49
+	
+	lodi,r0 5
+	lodi,r3 0
+loop_2:
+	addi,r3 1
+	bdra,r0 loop_2
+	stra,r3 mem_end-50
+	
+	lodi,r1 248
+	lodi,r2 0
+loop_3:
+	addi,r2 1
+	bira,r1 loop_3
+	stra,r2 mem_end-51
+	
+	lodi,r0 5
+	lodi,r3 0
+loop_4:
+	addi,r3 1
+	bdrr,r0 loop_4
+	stra,r3 mem_end-52
+	
+	lodi,r1 248
+	lodi,r2 0
+loop_5:
+	addi,r2 1
+	birr,r1 loop_5
+	stra,r2 mem_end-53
+	
+	lodi,r2 55
+	comi,r2 55
+	spsl
+	andi,r0 0b11000000
+	stra,r0 mem_end-54
+	
+	lodi,r3 7
+	coma,r3 data+8
+	spsl
+	andi,r0 0b11000000
+	stra,r0 mem_end-55
+	
+	ppsl PSL_LOGICAL_COMP
+	lodi,r3 7
+	coma,r3 data+8
+	spsl
+	andi,r0 0b11000000
+	stra,r0 mem_end-56
+	cpsl PSL_LOGICAL_COMP
+	
+	loda,r2 data+8
+	eorz,r0
+	comz,r2
+	spsl
+	andi,r0 0b11000000
+	stra,r0 mem_end-57
+	
+	ppsl PSL_LOGICAL_COMP
+	comz,r2
+	spsl
+	andi,r0 0b11000000
+	stra,r0 mem_end-58
+	
+	lodz,r2
+	comz,r2
+	spsl
+	andi,r0 0b11000000
+	stra,r0 mem_end-59
+	cpsl PSL_LOGICAL_COMP
+	
+	lodi,r1 1
+	lodi,r2 2
+	lodi,r3 3
+	ppsl PSL_BANK
+	lodi,r1 4
+	lodi,r2 5
+	lodi,r3 6
+	cpsl PSL_BANK
+	
+	stra,r1 mem_end-60
+	stra,r2 mem_end-61
+	stra,r3 mem_end-62
+	ppsl PSL_BANK
+	stra,r1 mem_end-63
+	stra,r2 mem_end-64
+	stra,r3 mem_end-65
+	cpsl PSL_BANK
+	
+	bcta,un sub_1_end
+a_subroutine_1:
+	lodi,r0 5
+	addi,r0 10
+	addz,r1
+	retc,un
+sub_1_end:
+	lodi,r1 1
+	bstr,un a_subroutine_1
+	stra,r0 mem_end-66
+	eorz,r0
+	strz,r1
+	bsta,un a_subroutine_1
+	stra,r0 mem_end-67
+	bctr,un sub_2_end
+a_subroutine_2:
+	lodi,r3 6
+	comi,r2 0
+	retc,eq
+	lodi,r3 7
+	retc,un
+sub_2_end:
+	lodi,r2 5
+	bstr,un a_subroutine_2
+	stra,r3 mem_end-68
+	lodi,r2 0
+	bsta,un a_subroutine_2
+	stra,r3 mem_end-69
+	
+	lodi,r2 5
+	lodi,r3 8
+	bsta,un mul_8x8_8
+	stra,r0 mem_end-70
+	
+	lodi,r0 5
+	lodi,r1 8
+	db 0x90
+	stra,r2 mem_end-71
+	
+	halt
+	
+mul_8x8_8:
+	spsl
+	lodi,r1 8
+	eorz r0
+	ppsl PSL_WITH_CARRY
+mul_8x8_8_loop:
+	rrr,r2
+	;tpsl PSL_CARRY_FLAG
+	db 183 ;Same instruction, but alternative encoding
+	db 1
+	bcfr,0 mul_8x8_8_no_carry
+	cpsl PSL_CARRY_FLAG
+	addz r3
+mul_8x8_8_no_carry:
+	rrl,r3
+	andi,r3 254
+	bdrr,r1 mul_8x8_8_loop
+	strz r1
+	lpsl
+	lodz r1
+	retc,un
+	
+data:
+	db 70
+	db 6
+	db 11
+	db 0xAA
+	db 8
+	db 0
+	db 0
+	db 100
+	db 200
diff --git a/cocotb_tests/test.py b/cocotb_tests/test.py
new file mode 100644
index 0000000..166666f
--- /dev/null
+++ b/cocotb_tests/test.py
@@ -0,0 +1,132 @@
+import cocotb
+import random
+from cocotb.clock import Clock
+from cocotb.triggers import Timer, ClockCycles
+
+@cocotb.test()
+async def test_cpu(dut):
+	dut._log.info("start")
+	
+	memory = [0] * 8192
+	
+	with open("test.bin", mode='rb') as file:
+		for i in range(0, 8192):
+			a = file.read(1)
+			if len(a) > 0:
+				memory[i] = a[0]
+	
+	dut.sense.value = 0
+	dut.dbus_in.value = 0
+	dut.reset.value = 1
+	clock = Clock(dut.clk, 1, units="us")
+	cocotb.start_soon(clock.start())
+	await ClockCycles(dut.clk, 3)
+	dut.reset.value = 0
+
+	d_counter = 0
+	c_counter = 0
+	expected_io_out_d = [55, 66, 10]
+	expected_io_out_c = [12, 38, 33]
+	d_out_counter = 0
+	c_out_counter = 0
+	tt = 0
+	while dut.as2650.halted == 0:
+		await Timer(0.25, units="us")
+		tt += 1
+		dut.dbus_in.value = 0
+		if dut.oeb.value == 0:
+			if dut.rw.value == 1 and dut.opreq.value == 1 and dut.wrp.value == 1:
+				if dut.m_io == 1:
+					memory[dut.adr.value] = dut.dbus_out.value
+				else:
+					if dut.wrp.value == 1:
+						if dut.d_c.value == 1:
+							assert dut.dbus_out.value == expected_io_out_d[d_out_counter]
+							if tt % 5 == 4:
+								d_out_counter += 1
+						else:
+							assert dut.dbus_out.value == expected_io_out_c[c_out_counter]
+							if tt % 5 == 4:
+								c_out_counter += 1
+		else:
+			if dut.rw.value == 0 and dut.opreq.value == 1:
+				if dut.m_io.value == 1:
+					dut.dbus_in.value = memory[dut.adr.value]
+				else:
+					if dut.d_c.value == 1:
+						dut.dbus_in.value = d_counter
+						if tt % 4 == 3:
+							d_counter += 1
+					else:
+						dut.dbus_in.value = c_counter
+						if tt % 4 == 3:
+							c_counter += 2
+	
+	assert memory[8191] == 0x16
+	assert memory[8190] == 0xFF
+	assert memory[8189] == 0x16
+	assert memory[8191-7] == 70
+	assert memory[8191-8] == 3
+	assert memory[8191-9] == 6
+	assert memory[8191-10] == 66
+	assert memory[8191-11] == 11
+	assert memory[8191-12] == 0b01010101
+	assert memory[8191-13] == 0b10001111
+	assert memory[8191-14] == 24
+	assert memory[8191-15] == 2
+	assert memory[8191-16] == 1
+	assert memory[8191-17] == 2
+	assert memory[8191-18] == 2
+	assert memory[8191-19] == 2
+	assert memory[8191-20] == 1
+	assert memory[8191-21] == 8
+	assert memory[8191-22] == 0b11111101
+	assert memory[8191-23] == 15
+	assert memory[8191-24] == 0b11111101
+	assert memory[8191-25] == 14
+	assert memory[8191-26] == 10
+	assert memory[8191-27] == 20
+	assert memory[8191-28] == 6
+	assert memory[8191-29] == 96
+	assert memory[8191-30] == 0b10000111
+	assert memory[8191-31] == 0b00001111
+	assert memory[8191-32] == 0b00000111
+	assert memory[8191-33] == 0b10000011
+	assert memory[8191-34] == 0b00000001
+	assert memory[8191-35] == 0b00000010
+	assert memory[8191-36] == 0b00001001
+	assert memory[8191-37] == 0
+	assert memory[8191-38] == 0
+	assert memory[8191-39] == 0b10000000
+	assert memory[8191-40] == 0
+	assert memory[8191-41] == 0b10000000
+	assert memory[8191-42] == 55
+	assert memory[8191-43] == 5
+	assert memory[8191-44] == 4
+	assert memory[8191-45] == 3
+	assert memory[8191-46] == 103
+	assert memory[8191-47] == 180
+	assert memory[8191-48] == 0b01000000
+	assert memory[8191-49] == 220
+	assert memory[8191-50] == 5
+	assert memory[8191-51] == 8
+	assert memory[8191-52] == 5
+	assert memory[8191-53] == 8
+	assert memory[8191-54] == 0
+	assert memory[8191-55] == 0b01000000
+	assert memory[8191-56] == 0b10000000
+	assert memory[8191-57] == 0b01000000
+	assert memory[8191-58] == 0b10000000
+	assert memory[8191-59] == 0
+	assert memory[8191-60] == 1
+	assert memory[8191-61] == 2
+	assert memory[8191-62] == 3
+	assert memory[8191-63] == 4
+	assert memory[8191-64] == 5
+	assert memory[8191-65] == 6
+	assert memory[8191-66] == 16
+	assert memory[8191-67] == 15
+	assert memory[8191-68] == 7
+	assert memory[8191-69] == 6
+	assert memory[8191-70] == 40
+	assert memory[8191-71] == 40
diff --git a/cocotb_tests/test.sh b/cocotb_tests/test.sh
new file mode 100644
index 0000000..4554b4a
--- /dev/null
+++ b/cocotb_tests/test.sh
@@ -0,0 +1 @@
+./2650Tools asm test.asm && make
diff --git a/verilog/rtl/as2650.v b/verilog/rtl/as2650.v
index acb2d3d..052f562 100644
--- a/verilog/rtl/as2650.v
+++ b/verilog/rtl/as2650.v
@@ -332,7 +332,7 @@
 							*	Misc instructions
 							*/
 							if(cycle == 2) begin
-								if(ins_reg == 'h90 || ins_reg == 'h91) begin //Hijacking undocumented opcodes to add a multiply instruction
+								if(ins_reg == 'h90 || ins_reg == 'h91) begin //Using undocumented opcodes to add a multiply instruction
 									//(psl[4] ? r123_2[2] : r123[2]);
 									if(psl[4]) begin
 										r123_2[1] <= r0 * r123_2[0];