UniPCemu cycle accurate 8088 implementation

Emulation of old PCs, PC hardware, or PC peripherals.

Re: UniPCemu cycle accurate 8088 implementation

Postby superfury » 2017-5-02 @ 05:35

Well, those 5 cycles becoming 8 is logical: After 5 cycles, wait for T1 to start the transfer.
I don't know why it inserts 6 cycles between reads and writes, though. Totals 27 cycles in absolute counts(5+6+4x4).

Will it always start the I-phase at T3?
Edit: Will BIU requests on T1 start on the very same cycle, finishing on T4? Or will it always start the next T1 cycle(being received by the BIU on T2)?
superfury
l33t
 
Posts: 3228
Joined: 2014-3-08 @ 11:25
Location: Netherlands

Re: UniPCemu cycle accurate 8088 implementation

Postby reenigne » 2017-5-02 @ 06:19

superfury wrote:Well, those 5 cycles becoming 8 is logical: After 5 cycles, wait for T1 to start the transfer.


That's not it - in the sniffer log I linked to, the bus is idle for two of those 8 cycles, so it could start at cycle 6 instead of cycle 8. Looking at some other sniffer logs, POPs always seem to wait for 2 cycles after the end of the last prefetch before starting the stack transfer - so, something to do with coordinating access to the bus between the EU and the prefetcher perhaps?

superfury wrote:Will it always start the I-phase at T3?


I'm sure you've asked this before, and the answer's still no.
User avatar
reenigne
Oldbie
 
Posts: 509
Joined: 2006-11-30 @ 05:13
Location: Cornwall, UK

Re: UniPCemu cycle accurate 8088 implementation

Postby superfury » 2017-5-02 @ 08:26

I've just implemented a 2 cycle delay before every POP instruction starts. Every following POP(e.g. RETF instruction) will immediately read the next 4 cycles without delay, after which the instruction cycles themselves are applied(remaining documented RETF cycles being 17-4(Intersegment with constant) or 18-4(Intersegment)) EU cycles.

Does this also apply to the second POPW of the RETF instruction? Or does the second POPW execute immediately after the first one(spending 8 cycles to do the two stack POPs on a 8086)?
Edit: 8088 MPH cycle count increases to 1649 now.
superfury
l33t
 
Posts: 3228
Joined: 2014-3-08 @ 11:25
Location: Netherlands

Re: UniPCemu cycle accurate 8088 implementation

Postby reenigne » 2017-5-02 @ 09:09

superfury wrote:I've just implemented a 2 cycle delay before every POP instruction starts. Every following POP(e.g. RETF instruction) will immediately read the next 4 cycles without delay, after which the instruction cycles themselves are applied(remaining documented RETF cycles being 17-4(Intersegment with constant) or 18-4(Intersegment)) EU cycles.

Does this also apply to the second POPW of the RETF instruction? Or does the second POPW execute immediately after the first one(spending 8 cycles to do the two stack POPs on a 8086)?


Here's a sniffer log of a RETF executing with a full prefetch queue and idle bus:

Code: Select all
20FFF Ip...  00FE6 FF 00 FC .......                          I CB           RETF
20FF3 .C...  00FE6 FF 00 FC .......  T1
00FE7 .C...  00FE7 FF 00 FC .......  T2
20FE7 .C...  00FE7 FF 00 FC ..r....  T3
20FFF .p...  00FE7 FF 00 FC ..r....  T4    FF <-f [   00FE7]
20FFF .r...  00FE7 FF 00 FC .......  T1
10B78 .r...  10A78 FF 00 FC .......  T2
10B78 .r...  10A78 FF 00 FC ..r....  T3
10B1F .p...  10A78 1F 00 FC ..r....  T4    1F <-- [SS 10A78]
10B1F .r...  10A78 1F 00 FC .......  T1
10B79 .r...  10A79 1F 00 FC .......  T2
10A79 .r...  10A79 FF 00 FC ..r....  T3
10A05 .p...  10A79 05 00 FC ..r....  T4    05 <-- [SS 10A79]
10A05 .p...  10A79 05 00 FC .......
10A05 .p...  10A79 05 00 FC .......
10A05 .p...  10A79 05 00 FC .......
10A05 .p...  10A79 05 00 FC .......
10A05 .p...  10A79 05 00 FC .......
10A05 .r...  10A79 05 00 FC .......  T1
10B7A .r...  10A7A 05 00 FC .......  T2
10B7A .r...  10A7A FF 00 FC ..r....  T3
10BA8 .p...  10A7A A8 00 FC ..r....  T4    A8 <-- [SS 10A7A]
10BA8 .r...  10A7A A8 00 FC .......  T1
10B7B .r...  10A7B A8 00 FC .......  T2
10B7B .r...  10A7B FF 00 FC ..r....  T3
10A00 .p...  10A7B 00 00 FC ..r....  T4    00 <-- [SS 10A7B]
10A00 .p...  10A7B 00 00 FC .......
10A00 Ep...  10A7B 00 00 FC .......                          E
10A00 .C...  10A7B 00 00 FC .......  T1
00E9F .C...  00F9F 00 00 FC .......  T2
20E9F .C...  00F9F FD 00 FC ..r....  T3
20E98 .p...  00F9F 98 00 FC ..r....  T4    98 <-f [   00F9F]
20E98 .C...  00F9F 98 00 FC .......  T1
00FA0 .C...  00FA0 98 00 FC .......  T2
20FA0 IC...  00FA0 FF 00 FC ..r....  T3                      I 98           CBW


So there's no 2-cycle delay in this case, but there is a 5-cycle delay between the two POPs.
User avatar
reenigne
Oldbie
 
Posts: 509
Joined: 2006-11-30 @ 05:13
Location: Cornwall, UK

Re: UniPCemu cycle accurate 8088 implementation

Postby superfury » 2017-5-02 @ 09:20

So after T4 it just idles the complete bus for 5 cycles(no idea what that actually is, since it hasn't gotten any DMA or anything noted at that point)?

Executing the standalone version of the credits seems to run from segment 1122h in my case. So an UniPCemu breakpoint at 1122:025D should result in the correct log.

The new and improved log now also logs the current T-states(BIU) and S-states(DMA) that executed at the current clock. Of course, the debugger log(and entire debugger in general) executes between the BIU clock handling and DMA(and other hardware) handling. So the debugger logs the state before the DMA updates to a new state based on the BIU's response, but after the BIU has handled that very same clock.
superfury
l33t
 
Posts: 3228
Joined: 2014-3-08 @ 11:25
Location: Netherlands

Re: UniPCemu cycle accurate 8088 implementation

Postby superfury » 2017-5-02 @ 09:34

Here's the latest log on the standalone executable of the 8088 MPH credits:
https://www.dropbox.com/s/byny06he285zv ... 0.zip?dl=0

It now contains the new S-state and T-state logs.
superfury
l33t
 
Posts: 3228
Joined: 2014-3-08 @ 11:25
Location: Netherlands

Re: UniPCemu cycle accurate 8088 implementation

Postby reenigne » 2017-5-02 @ 09:36

superfury wrote:So after T4 it just idles the complete bus for 5 cycles


Right.

superfury wrote:(no idea what that actually is, since it hasn't gotten any DMA or anything noted at that point)?


Well, the BIU and the bus are waiting for the EU to do something - it's not an externally-imposed delay.
User avatar
reenigne
Oldbie
 
Posts: 509
Joined: 2006-11-30 @ 05:13
Location: Cornwall, UK

Re: UniPCemu cycle accurate 8088 implementation

Postby reenigne » 2017-5-02 @ 09:49

superfury wrote:Here's the latest log on the standalone executable of the 8088 MPH credits:
https://www.dropbox.com/s/byny06he285zv ... 0.zip?dl=0

It now contains the new S-state and T-state logs.


This log shows the same problem as the last one - the prefetch of the second byte of the "MOV CL,xx" instruction occurs after the stores of the "POP W[CS:BX]" instruction.

I realize that you're using these logs to debug more than just the 8088 cycle accuracy, but perhaps it would be useful to have a special mode that saves logs in a "1 line per cycle" format like the bus sniffer logs. Then it would be easier to directly compare your logs with bus sniffer logs and see where they're different.
User avatar
reenigne
Oldbie
 
Posts: 509
Joined: 2006-11-30 @ 05:13
Location: Cornwall, UK

Re: UniPCemu cycle accurate 8088 implementation

Postby superfury » 2017-5-02 @ 17:38

I've implemented shorthand memory access logging and added support for single-line debugging now(just very long lines due to the many cycle informations being logged).

I now get the following result when logging the start of the Turbo XT BIOS v3.0(as a simple example of what it's logging now):
Code: Select all
00:00:06:71.06835: BIU T2: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07301: BIU T3: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07331: BIU T4: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07398: BIU T1: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 1, BIU DMA cycles: 0 Physical(r):000FFFF0=EA(ê); Paged(r):000FFFF0=EA(ê); Normal(r):000FFFF0=EA(ê)
00:00:06:71.07426: BIU T2: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07455: BIU T3: EU&BIU cycles: 1, Operation cycles: 1, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 1, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07481: BIU T4: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07518: BIU T1: EU&BIU cycles: 1, Operation cycles: 1, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 1, BIU DMA cycles: 0 Physical(r):000FFFF1=5B([); Paged(r):000FFFF1=5B([); Normal(r):000FFFF1=5B([)
00:00:06:71.07548: BIU T2: EU&BIU cycles: 1, Operation cycles: 1, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 1, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07576: BIU T3: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07603: BIU T4: EU&BIU cycles: 1, Operation cycles: 1, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07639: BIU T1: EU&BIU cycles: 1, Operation cycles: 1, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 1, BIU DMA cycles: 0 Physical(r):000FFFF2=E0(à); Paged(r):000FFFF2=E0(à); Normal(r):000FFFF2=E0(à)
00:00:06:71.07666: BIU T2: EU&BIU cycles: 1, Operation cycles: 1, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 1, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07693: BIU T3: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07720: BIU T4: EU&BIU cycles: 1, Operation cycles: 1, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07756: BIU T1: EU&BIU cycles: 1, Operation cycles: 1, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 1, BIU DMA cycles: 0 Physical(r):000FFFF3=00( ); Paged(r):000FFFF3=00( ); Normal(r):000FFFF3=00( )
00:00:06:71.07784: BIU T2: EU&BIU cycles: 1, Operation cycles: 1, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 1, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07811: BIU T3: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07838: BIU T4: EU&BIU cycles: 1, Operation cycles: 1, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07874: BIU T1: EU&BIU cycles: 1, Operation cycles: 1, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 1, BIU DMA cycles: 0 Physical(r):000FFFF4=F0(ð); Paged(r):000FFFF4=F0(ð); Normal(r):000FFFF4=F0(ð)
00:00:06:71.07922: BIU T2: EU&BIU cycles: 1, Operation cycles: 15, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 1, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0 FFFF:0000 (EA5BE000F0)JMP F000:E05B
00:00:06:71.07948: BIU T3: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.07975: BIU T4: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08012: BIU T1: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 1, BIU DMA cycles: 0 Physical(r):000FE05B=FA(ú); Paged(r):000FE05B=FA(ú); Normal(r):000FE05B=FA(ú)
00:00:06:71.08039: BIU T2: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08065: BIU T3: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08092: BIU T4: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08128: BIU T1: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 1, BIU DMA cycles: 0 Physical(r):000FE05C=FC(ü); Paged(r):000FE05C=FC(ü); Normal(r):000FE05C=FC(ü)
00:00:06:71.08155: BIU T2: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08181: BIU T3: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08209: BIU T4: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08245: BIU T1: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 1, BIU DMA cycles: 0 Physical(r):000FE05D=B0(°); Paged(r):000FE05D=B0(°); Normal(r):000FE05D=B0(°)
00:00:06:71.08272: BIU T2: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08299: BIU T3: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08325: BIU T4: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08389: BIU T1: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 1, BIU DMA cycles: 0 Physical(r):000FE05E=00( ); Paged(r):000FE05E=00( ); Normal(r):000FE05E=00( )
00:00:06:71.08419: BIU T2: EU&BIU cycles: 1, Operation cycles: 2, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 1, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0 F000:E05B (FA)CLI
00:00:06:71.08446: BIU T3: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08473: BIU T4: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08512: BIU T1: EU&BIU cycles: 1, Operation cycles: 2, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 1, BIU prefetching cycles(1 each): 1, BIU DMA cycles: 0 F000:E05C (FC)CLD Physical(r):000FE05F=E6(æ); Paged(r):000FE05F=E6(æ); Normal(r):000FE05F=E6(æ)
00:00:06:71.08539: BIU T2: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08565: BIU T3: EU&BIU cycles: 1, Operation cycles: 0, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 0, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0
00:00:06:71.08597: BIU T4: EU&BIU cycles: 1, Operation cycles: 4, HW interrupt cycles: 0, Prefix cycles: 0, Exception cycles: 0, MMU read cycles: 0, MMU write cycles: 0, I/O bus cycles: 0, Prefetching cycles: 2, BIU prefetching cycles(1 each): 0, BIU DMA cycles: 0 F000:E05D (B000)MOVB AL, 00


Is that what you meant? It essentially starts with the current running time(always logged for all logging purposes), followed by cycle information, instruction(when finished executing only), memory accesses. The memory access follow the order from layer 3(RAM) down to 1(BIU, on writes) or 1(memory) up to 3(RAM, on reads).

Edit: The freshly generated single-line log of the credits running as the standalone executable(although the timings are still unchanged):
https://www.dropbox.com/s/msuvh62drm5x1 ... 3.zip?dl=0

Edit: I've implemented idle BUS cycles into the BIU. It will spend cycles doing nothing at all, blocking the EU from doing anything that cycle. The debugger will log the BIU state "---" for those. Although it isn't implemented into the CPU EU to give those timings yet.
superfury
l33t
 
Posts: 3228
Joined: 2014-3-08 @ 11:25
Location: Netherlands

Re: UniPCemu cycle accurate 8088 implementation

Postby reenigne » 2017-5-02 @ 18:43

superfury wrote:Is that what you meant?


Closer... Now, if you trim out everything except the bus state (T1-T4/S0-S4 etc), the instruction and the bus transfer type/address/data you'll have something that's much more compact and much closer to the bus sniffer's output. Then it would be easier to compare the two.

Btw, I noticed in this latest log that there don't appear to be any lines on which the bus is idle. Is that a problem with your emulation not doing any idle cycles, or your logging code not outputting lines for the idle cycles?

I also noticed that the timestamp on the left is the same for some adjacent pairs of cycles. Not sure what's going on there.

Another thing I noticed is that you have the BIU bus state (T1-T4) and the DMA bus state (S0-S4) in the same column. The bus sniffer has them in different columns, because the BIU bus accesses and DMA bus accesses can overlap to a certain extent. S0 can occur simultaneously with T1, T2 or idle, but not with T3 or T4. The BIU bus will be in a wait (Tw) state for up to 6 cycles during a DMA, in order for there to be at least 4 cycles between an S4 and the subsequent T4.
User avatar
reenigne
Oldbie
 
Posts: 509
Joined: 2006-11-30 @ 05:13
Location: Cornwall, UK

Re: UniPCemu cycle accurate 8088 implementation

Postby superfury » 2017-5-02 @ 20:16

The EU isn't generating any BUS idle nor BIU stall signals yet. With my commits just now(while I'm typing this), it's possible to start generating those two signals(still unsignaled by the EU itself, which drives BIU and BUS base timings). BUS stalls halt all activity by the CPU(BIU and EU alike). BIU stalls only do that for the BIU(for things like jumps etc.), keeping the EU active.

It's just not called yet(BUS idling), but now supported by all modules. I just need to know what parts of what instructions to stall and I can implement them in the EU(8086 core to be exact, so opcodes_8086.c in UniPCemu's source code) just like the other step timings(although the step timings base index(to provide the current step) after it would need to be increased by one for each added delay at the instruction(internal or not) code).

Edit: whoops, BIU stalls are used for jumps already. I'll need to remove those from adding to the EU cycles, as they're part of those already(e.g. cycles_OP==16 and cycles_stallBIU==16 resulting in 16 stalling BIU cycles only(instead of 32 BIU cycles of which 16 stalling(, with no memory accesses).
superfury
l33t
 
Posts: 3228
Joined: 2014-3-08 @ 11:25
Location: Netherlands

Re: UniPCemu cycle accurate 8088 implementation

Postby reenigne » 2017-5-02 @ 20:22

superfury wrote:The EU isn't generating any BUS idle nor BIU stall signals yet.


So what does your emulator currently do when the prefetch queue is full and the EU is busy with a long-running calculation (like a multiply or divide) which doesn't do any bus operations?
User avatar
reenigne
Oldbie
 
Posts: 509
Joined: 2006-11-30 @ 05:13
Location: Cornwall, UK

Re: UniPCemu cycle accurate 8088 implementation

Postby superfury » 2017-5-02 @ 20:33

reenigne wrote:
superfury wrote:The EU isn't generating any BUS idle nor BIU stall signals yet.


So what does your emulator currently do when the prefetch queue is full and the EU is busy with a long-running calculation (like a multiply or divide) which doesn't do any bus operations?


The EU is busy all that time, while the BIU releases the bus after the last instruction/memory fetch(modr/m), then proceeds to do nothing(walking T-states without fetching anything from memory or storing anything. The DMA controller(s) are free to take control of the BUS anytime. Once the prefetch is read again(any walking T-cycle), fetching to PIQ will resume on the very first T1 afterwards. So if the walking ended up at T3 after 150 cycles(finishing instruction), after 2 cycles a new instruction byte is fetching(assuming DMA hasn't taken control over the BUS) on T1.
superfury
l33t
 
Posts: 3228
Joined: 2014-3-08 @ 11:25
Location: Netherlands

Re: UniPCemu cycle accurate 8088 implementation

Postby reenigne » 2017-5-02 @ 20:46

superfury wrote:The EU is busy all that time, while the BIU releases the bus after the last instruction/memory fetch(modr/m), then proceeds to do nothing(walking T-states without fetching anything from memory or storing anything. The DMA controller(s) are free to take control of the BUS anytime. Once the prefetch is read again(any walking T-cycle), fetching to PIQ will resume on the very first T1 afterwards. So if the walking ended up at T3 after 150 cycles(finishing instruction), after 2 cycles a new instruction byte is fetching(assuming DMA hasn't taken control over the BUS) on T1.


I think this betrays a misunderstanding about how the T states work. Each set of T states (i.e. T1, T2, T3, [0 or more Tw], T4) corresponds to exactly one bus transfer. If no bus transfer is occurring then the T state is none of these (the column is blank in bus sniffer logs, call it Tidle if you like). When the next bus transfer is requested (either by the EU or by DMA) and the bus is idle, the transfer starts immediately, it doesn't need to wait for a T1 cycle to come around again. In other words, the T states don't form a "clock signal", they're sequencing for parts of a transfer which can start on any CPU cycle.

Since the bus is usually busy, it does seem like a T1 always immediately follows a T4, but this is no longer the case when there are idle cycles.
User avatar
reenigne
Oldbie
 
Posts: 509
Joined: 2006-11-30 @ 05:13
Location: Cornwall, UK

Re: UniPCemu cycle accurate 8088 implementation

Postby superfury » 2017-5-02 @ 21:16

So if I understand it correctly, I should make it keep T1 state while nothing is to be done? Thus starting any transfers(Instruction or data) the very same cycle something's ready to process. So keep it stuck at T1 state until something's requested(or DMA takes over) instead of the current inactive walking?

Edit: My latest commit: https://bitbucket.org/superfury/unipcem ... ?at=master

Now it keeps T1 state ready when nothing is left to be done. All other functions work as before, but when it has nothing to do anymore, it will be kept at T1 until it has something to do again(with idle BUS while waiting).
superfury
l33t
 
Posts: 3228
Joined: 2014-3-08 @ 11:25
Location: Netherlands

Re: UniPCemu cycle accurate 8088 implementation

Postby reenigne » 2017-5-03 @ 06:54

superfury wrote:So if I understand it correctly, I should make it keep T1 state while nothing is to be done? Thus starting any transfers(Instruction or data) the very same cycle something's ready to process. So keep it stuck at T1 state until something's requested(or DMA takes over) instead of the current inactive walking?


There is a difference between T1 and idle. I'm not sure if it makes any difference for emulation or not, but I think it's confusing to equate the two.
User avatar
reenigne
Oldbie
 
Posts: 509
Joined: 2006-11-30 @ 05:13
Location: Cornwall, UK

Re: UniPCemu cycle accurate 8088 implementation

Postby superfury » 2017-5-03 @ 07:18

It's essentially the same? Idle is/becomes T1 when there's something to do(first state of transfer), idle otherwise.

Edit: I've modified the BIU to fix the problems with BUS control on T1/T3(it kept having an inactive BUS in the middle of transfers during the BIOS execution, causing it to infinitely do nothing forever).
https://bitbucket.org/superfury/unipcem ... ?at=master

8088 MPH now reports 1643 cycles.
superfury
l33t
 
Posts: 3228
Joined: 2014-3-08 @ 11:25
Location: Netherlands

Re: UniPCemu cycle accurate 8088 implementation

Postby superfury » 2017-5-03 @ 10:14

I've made a new log(with the new simplified timings):
https://www.dropbox.com/s/di8u0d73unag9 ... 7.zip?dl=0

It now leaves out all those cycle information, using only the first part (T-, S- or W-state) and leaving all other cycle timings that were set by the CPU.
T1 is now kept in that state(being either T1 or idle, depending on what it has to do) until a new request or the prefetch buffer is read by the EU.

Edit: I've modified the BIU to report stalling the BUS when it doesn't have anything to do (when DMA isn't in SI-state).
superfury
l33t
 
Posts: 3228
Joined: 2014-3-08 @ 11:25
Location: Netherlands

Re: UniPCemu cycle accurate 8088 implementation

Postby reenigne » 2017-5-03 @ 11:34

superfury wrote:It's essentially the same? Idle is/becomes T1 when there's something to do(first state of transfer), idle otherwise.


On the real hardware, the T1 state is when the address to access is placed on the bus. So if the EU needs to start a bus access, it will be able to if the current bus state is idle but not if the current bus state is T1 (from a prefetch operation).

superfury wrote:I've made a new log(with the new simplified timings):
https://www.dropbox.com/s/di8u0d73unag9 ... 7.zip?dl=0

It now leaves out all those cycle information, using only the first part (T-, S- or W-state) and leaving all other cycle timings that were set by the CPU.


It still seems to be counting T1..T4 during bus idle, meaning that (between each pair of DMAs) accesses only occur every 4th cycle.

superfury wrote:T1 is now kept in that state(being either T1 or idle, depending on what it has to do)


Under what conditions are you keeping the bus in the T1 state and under what conditions are you keeping it in the idle state? I don't think the real hardware has that distinction (since on the real hardware a T1 state is always 1 cycle long).
User avatar
reenigne
Oldbie
 
Posts: 509
Joined: 2006-11-30 @ 05:13
Location: Cornwall, UK

Re: UniPCemu cycle accurate 8088 implementation

Postby superfury » 2017-5-03 @ 11:51

reenigne wrote:
superfury wrote:It's essentially the same? Idle is/becomes T1 when there's something to do(first state of transfer), idle otherwise.


On the real hardware, the T1 state is when the address to access is placed on the bus. So if the EU needs to start a bus access, it will be able to if the current bus state is idle but not if the current bus state is T1 (from a prefetch operation).

superfury wrote:I've made a new log(with the new simplified timings):
https://www.dropbox.com/s/di8u0d73unag9 ... 7.zip?dl=0

It now leaves out all those cycle information, using only the first part (T-, S- or W-state) and leaving all other cycle timings that were set by the CPU.


It still seems to be counting T1..T4 during bus idle, meaning that (between each pair of DMAs) accesses only occur every 4th cycle.

superfury wrote:T1 is now kept in that state(being either T1 or idle, depending on what it has to do)


Under what conditions are you keeping the bus in the T1 state and under what conditions are you keeping it in the idle state? I don't think the real hardware has that distinction (since on the real hardware a T1 state is always 1 cycle long).


When it has nothing to do(no BIU memory/BUS requests and prefetch buffer is full), it will execute a NOP cycle(BUS being idle, now reporting "BIU --" instead of T-state. It's still in T1 state, for simple compatibility). Otherwise, a T1 cycle(and onwards) is executed, which will transfer from memory on T1 and then wait until it executes T4, which will terminate the access and report the retrieved data back to the EU. Basically an if-else operation on T1( if (needstransfer) { T1 } else { idle BUS cycle } ). The new "--" state is essentially the sniffer log's empty parts.

I'm now generating a new log with the new logic. The three parts are seperated with tabs now. First are the timestamp(which always follows the same format) of the emulator itself(compared to when it was started) and followed by the current state. The second column specifies the instruction that's finished executing(if any, empty otherwise). The third column contains all done memory accesses.

The new log:
https://www.dropbox.com/s/bnomz63l2v9id ... 7.zip?dl=0

Although all T-states and idle BIU states are overridden by BUS stalls, Waitstate RAM stalls and DMA stalls, in that order of priority. BUS stalls give the same result in the log as the idle BIU state(states 1(BUS stall) and 2(BIU has nothing to do) both resolve to the -- case in the log).
superfury
l33t
 
Posts: 3228
Joined: 2014-3-08 @ 11:25
Location: Netherlands

PreviousNext

Return to PC Emulation

Who is online

Users browsing this forum: No registered users and 1 guest