Closed Rodrigodd closed 7 months ago
I am taking this issue into processing as it looks more critical. There are inaccuracies in the description of datalatch on the wiki, it will be corrected now. In fact it contains 2 DLatch (dynamic, using FET gates), acting as transparent latch = BusKeepers. The datalatch also contains a precharge for the internal data bus (DL).
Updated approximation of DataLatch schematic for Logisim (#244 )
I've localized the cause of the conflict:
It turns out that the internal bus (DL) is driven by two circuits at once - DataLatch and DataBridge. DataLatch places a transparent latch value on the bus, and DataBridge places a "DV" value (ALU Operand2) on the bus.
That is, there is no solution to the "ground wins" conflict.
The solution I see is to combine 2 DataLatch+DataBridge modules into one to correctly multiplex the buses inside.
@ogamespec Can you use Verilog assignment strength here? I am not very familiar with it, but I see it being used in dmg-sim
(and that Verilator does not support all strength levels).
Can you use Verilog assignment strength here?
I doubt that I will set the signal strength correctly, because it is more related to the analog domain, and I don't specialize in analog electronics at all.
Merged DataLatch & DataBridge into single instance: #246
It's gotten better, but it's still not great:
Instead of writing A -> DV bus -> 0xBC, for some reason 0 is written to the DV bus.
Actually, I think that I have fixed this issue and the problem is already in the register block (connections between registers and buses). It is better to move to #240 and check the correctness of the whole register block within that issue.
@Rodrigodd Please see if you have any questions left on this topic?
For DataMux I will also draw a combined transistor circuit with explanations of what and how it connects (but this is for the wiki).
I did a comprehensive analysis of the connection of the internal buses to the external data bus and put together a visual schematic of DataLatch+DataBridge, which is now called DataMux (databus multiplexer):
The interaction mechanism of bidirectional buses in SM83 is described in this section: https://github.com/emu-russia/dmgcpu/blob/main/buses.md#bidirectional-bus-multiplexing
I believe the write is now blocked from the other problem I noticed:
The value of register A is stored in ReqA/r1q, inverted. This value can be put in the abus or bbus (and Aout, but just affect ALU logic), but during write neither of them are used,
s2_op_alu8
(w[3]
) ands3_oe_areg_to_rbus
(x[35]
) are both 0.
Which may come from the decoder.
But this specific issue may be fixed. I will test later if any other instruction can now write to memory, and how extensive is the decoding problem.
Okay, then I'll close this Issue and switch to regblock fixes.
@Rodrigodd Fixed, edits online.
Yep, tested it on dmg-sim
and it can now a CALL
and RET
pair works. The next problem appear to be it taking the wrong branch in a conditional return. Will open a issue/PR once I investigated it more. Thanks!
In #238 I noticed that during instructions that should write to memory, it doesn't output a value to the external bus, it was kept in high impedance. Below is the summary of my investigation, as contained in
investigating.md
in the linked PR.LD (HL), A
Data bus stays in high impedance
DataLatch
is the only one connected to the external data busD
. Although it is called a "latch" it does not hold any data, it just forwards data from other data buses; that isRes
(the result of the ALU) andDL
(the internal databus).But
datalatch.md
states that it can only output values toDL
, and load from eitherD
orRes
. But this should not be the case, because we need to output to the external bus, andDataLatch
is the only one connected to it.Also, it specifies
DL
bus asinout
, but never assignz
to it. In fact, during the write (WR
high)DataBridge
also writes toDL
, makingDL
go to invalid statex
. Actually, a lot of things tries to write toDL
.(Strangely,
DataBridge
only writes0
orz
bits toDL
. MaybeDL
has a pull-up somewhere? Oh, maybe that is whatBusPrecharge
does, not sure if verilog will simulate that. Oh, this is handle by the use ofBusKeeper
.)The value of register
A
is stored inReqA
/r1q
, inverted. This value can be put in theabus
orbbus
(andAout
, but just affect ALU logic), but during write neither of them are used,s2_op_alu8
(w[3]
) ands3_oe_areg_to_rbus
(x[35]
) are both 0.In screenshot, the execution of the instruction
LD (HL), A
(77
).