News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Amstrad Plus and IM2 bug

Started by arnoldemu, 17:59, 08 July 17

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

Duke

Quote from: Longshot on 23:23, 26 July 17
Thanks for the test.
The only possibility to have a reset with A2 in this code will be an interrupt on dma1 or dma2
To confirm that, i've made an update. red for dma2, white for dma1 (blue dma0/yellow:pri or r52)
I get black border, then blue.

dragon

#126
Quote from: Duke on 23:44, 26 July 17
I get black border, then blue.

Yeah true, i have made a mistach with blue, because cpc starts with border in blue XD. I have expanded the 4:3.
test3=test2.

But i have made now interesting experiment.

With the cpc running the test. If i select directorys in m4 web interface, the border in cpc flickering to yelow when i select one directory.

Duke

Quote from: dragon on 00:03, 27 July 17
But i have made now interesting experiment.

With the cpc running the test. If i select directorys in m4 web interface, the border in cpc flickering to yelow when i select one directory.
That would send a BUSRQ and probably skew the test.

dragon

#128
In the schematics gx4000 is connected little diferent that the plus, they swap one logic gate in the ic, and it changue the 5v source.To signal  controls. But probably is because board layout.

Longshot

QuoteWith the cpc running the test. If i select directorys in m4 web interface, the border in cpc flickering to yelow when i select one directory.
In the A2 test, if interrupt is delayed of 1 usec, it's not a "add a,(ix+1)" (==> blue) which is interrupted, but a "nop" (==> yellow)
[ but maybe it's another event on the bus ]
In the general case, in A2 test, the interrupt is not delayed with add a,(ix+1) because the int request occurs exactly on the same usec than "ld b,a"
The bug seems not to be triggered with the interrupt delay, but with the instruction itself (arnoldemu first suggestion) when bit A13 of the instruction is 0.
It seems difficult to avoid a bug triggered by the instruction and to create a code where interrupt occurs only on some specific instruction.
The best way to avoid the bug is to locate code in 8 areas of &1000 bytes (50% of ram).
If A13 is confirmed on all amstrad plus, needs now to know if it's the same for rom, extra-ram, and block 3 mapped in 4000 (C3 mode)


Rhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!!

arnoldemu

#130
I think I need to balance the number of nops?

4 before, 0 after
3 before, 1 after

then I will get either blue or yellow I think.

Do I need to set nbnop to 4 for add a,(ix+1)??
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

Quote from: Duke on 00:12, 27 July 17
That would send a BUSRQ and probably skew the test.
interesting. M4 uses BUSRQ and holds CPU like Z80-DMA would?
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

Longshot

#132
Quote from: arnoldemu on 09:04, 27 July 17
did you see my results from your test with add a,(ix+0)?
with 0 nops, blue
with 1 nop, blue and yellow flashing like a K7 loader
with 2 nop, blue and yellow alternate but fixed.
with 3 nop, blue and yellow alternate but fixed


The test synchronize the interrupt for an exact micro-second in the code. Flashing is not expected.
Full blue or full yellow.
Have you modified nbnopinst ? (best name would be "nop number before the interrupt with the 4 nop before"  ;D )
instruction ==> add a,(ix+1)
With 0 nop (from "ouf"), nbnopinst=1
With 1 nop (from "ouf"), nbnopinst=2
With 2 nop (from "ouf"), nbnopinst=3
With 3 nop (from "ouf"), nbnopinst=4
With 4 nop (from "ouf"), nbnopinst=5
If not, the interrupt doesn't trigger exactly at the same point between 2 interrupt
Rhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!!

roudoudou

Quote from: Longshot on 08:58, 27 July 17
If A13 is confirmed on all amstrad plus, needs now to know if it's the same for rom, extra-ram, and block 3 mapped in 4000 (C3 mode)


I confirm it's the same for lower ROM execution, but i did not test extra-ram in C2, Cx mode or ROM above #4000

arnoldemu

Quote from: Longshot on 09:16, 27 July 17

The test synchronize the interrupt for an exact micro-second in the code. Flashing is not expected.
Full blue or full yellow.
Have you modified nbnopinst ? (best name would be "nop number before the interrupt with the 4 nop before"  ;D )
instruction ==> add a,(ix+1)
With 0 nop (from "ouf"), nbnopinst=1
With 1 nop (from "ouf"), nbnopinst=2
With 2 nop (from "ouf"), nbnopinst=3
With 3 nop (from "ouf"), nbnopinst=4
With 4 nop (from "ouf"), nbnopinst=5
If not, the interrupt doesn't trigger exactly at the same point between 2 interrupt
No I didn't. I will do that.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

dragon

#135
Quote from: arnoldemu on 09:06, 27 July 17
interesting. M4 uses BUSRQ and holds CPU like Z80-DMA would?


Really it also affect the c4cpc to when you are in cpr loader menu. In the same way as running test.


But, the only signals involved are a13,wait,iorq,reset as input, and nrioq as output.


The connection to the other controls signals is only to take +5v to make the and with the diode.


https://electronics.stackexchange.com/questions/131860/diode-logic-gates

robcfg


Longshot

Quotebut i did not test extra-ram in C2, Cx mod

Attached a new version (T1/T2 for C1 mode and T3/T4 for C3 mode)

See source for 4 tests
;
; TEST T1 (code in bank 7 mapped in &C000, code in &C000 bit A13=0)       
; runc         equ &c000
; ramselect     equ &c1
; Expected --> FULL BLUE BORDER (dma bug)
;
; TEST T2 (code in bank 7 mapped in &c000, code in &E000 bit A13=1)       
; runc         equ &e000
; ramselect     equ &c1
; Expected --> FULL YELLOW BORDER (no dma bug)
;
; TEST T3 (code in bank 7 mapped in &4000, code in &4000 bit A13=0)       
; runc         equ &4000
; ramselect     equ &c3
; Expected --> FULL BLUE BORDER (dma bug)
;
; TEST T4 (code in bank 7 mapped in &4000, code in &6000 bit A13=1)       
; runc         equ &6000
; ramselect     equ &c3
; Expected --> FULL YELLOW BORDER (no dma bug)
;
Rhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!!

dragon

Quote from: gerald on 19:36, 26 July 17
In fact this circuit is masking IORQn when WAITn is low and A13 is 0.
That is, IORQn cycle to ASIC is shortened when A13 is low : ie when you do an IN or OUT to DFxx, aka the ROM mapping register.
It looks like the access is has been reduced to only take IO into account during ASIC time (ie when wait is low), and not when the effective cycle from the Z80 point of view is done.
Why did Amstrad have done this ? It may be a bug in the ROM mapping management ?

Now why is this a problem for the interrupt ack ?
The IRQ ack cycle is : M1 low / IORQ low and address bus = PC.
So if you get the IRQ when the PC has A13 low, the IORQ will be shorter and will not be valid during the CPU time (ie when WAITn is high).
Does the ASIC still get the IRQ ACK and drive the bus until the Z80 read it ? If not, the bus is floating and we have chance to grab garbage instead of the IRQ vector.

Now looking at mother board (464/6128Plus or GX4000) there is a collection of added resistors or diode or nothing, it looks like Amstrad had trouble finding a sweet spot for this fix.
LK106 hint that Amstrad expected to fix this internally later.

Now what of we close LK106 after removing IC106 ? Who knows, but the CPC may not work as expected if it's related to ROM mapping.


I view it with a,new true table.


Basically. Niorq should be 0 in four cases.


All combination of a13,wait + iorq=0 and reset=1. But the circuit cut the 0,0  case and put 1 instead 0

MaV

Quote from: arnoldemu on 19:20, 26 July 17
LD B,A is 1 opcode read. Bug doesn't happen if only opcode read.
In another test you used LD (DE),A, that is 1 opcode read and 1 memory write.

ADD A,(IX+1)

is DD,86,nn, it is 1 opcode read, 86 could be 1 opcode read or 1 memory read, then 1 memory read for nn.  I need to look at that z80 recreation to know what happens. Then finally 1 memory read for (ix+1).
Probably not quite relevant to the discussion per se, but could be helpful:

Both the prefix and the opcode are M1 cycles (instruction- or opcode-fetch).
It is easy to test because the R-register increases after each M1 cycle, and the prefix instructions cause the R-register to increase by two; by one for the prefix-byte and again by one for the opcode-byte.

So this gives us:
ADD A, (IX+1)
DD, 86, 01 = M1, M1, Read, ...


There's however a strange situation when there are two prefix-bytes involved. The offset-byte directly follows the two prefix-bytes and the opcode-byte is last:
RLC (IX + 1)
DD, CB, 01, 06 = M1, M1, Read, Read(faux M1), Read, Write
The R-register is increased by two only, which means that the actual opcode-byte (the fourth and last) must be considered a read cycle.
So, the Z80 seems to consider every following byte after the second prefix a Read or Write once it stops fetching M1's because of the offset-byte, and it doesn't revert back to fetching M1's but Read bytes, even if it is an instruction b-te.
(There's the possibility, of course, that the instruction byte is also an M1-cycle but the R-register is not increased for whatever reason.)
Black Mesa Transit Announcement System:
"Work safe, work smart. Your future depends on it."

Duke

#140
Quote from: Longshot on 10:27, 27 July 17
Attached a new version (T1/T2 for C1 mode and T3/T4 for C3 mode)
For me all 4 tests are as expected:
T1 Blue
T2 Yellow
T3 Blue
T4 Yellow

@arnoldemu
Yes, M4 uses BUSRQ, when kicking the command that was out'ed. Then the M4 copies responses into the mapped M4 rom (which is really ram) and releases BUSRQ so the z80 can read it.

arnoldemu

I didn't change the 4 nops.
nbnopinst = 1, yellow at top, then blue, then yellow. no movement. (change at every 52 lines)
nbnopinst = 2, blue at top, then yellow then blue. no movement. (change at every 52 lines)
nbnopinst = 3, blue, yellow, blue x 104 lines, yellow 52 lines, blue (maybe 104 lines.. split by upper and lower border), no movement.
nbnopinst = 4, blue/yellow k7 loading moving
nbnopinst = 5, blue.

I set nbnopinst to 4. I then put some nops before, some nops after.
1 before, 3 after = yellow
2 before, 2 after = yellow
3 before, 1 after = yellow

I set nbnopinst to 1. I then put some nops before, some after.
1 nop before, 3 after = k7 loading
2 nop before, 2 after = blue ~104 lines, yellow 52, blue ~104 lines. blue starts. no movement.
3 nop before, 1 after = blue, yellow, blue yellow, 52 lines each. no movement.

One of these combinations must be right  ???
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

I tried RMR2 moving ROM to &8000. Same as RAM.

Execute from &8000-&9fff from ROM, bug.
Execute from &a000-&bfff from ROM, no bug.

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

roudoudou

Quote from: arnoldemu on 19:43, 27 July 17
I tried RMR2 moving ROM to &8000. Same as RAM.

Execute from &8000-&9fff from ROM, bug.
Execute from &a000-&bfff from ROM, no bug.


WTF  :o   :'( :'( :'( :laugh:

Longshot

QuoteOne of these combinations must be right
:o
You need some explanations  ;)
In this configuration (with 4 nop), you must set "nbnopinst" to number nop of instruction (add a,(ix+1)==>5) nbnopinst=5:
ouf
            nop            ; 1 -- 33
            nop            ; 1 -- 34
            nop            ; 1 -- 35
            nop            ; 1 -- 36
instruction     add a,(ix+1)        ; instruction to test

Instruction takes 5 usec (us1, us2, us3, us4, us5)
In this config, interrupt triggers at us2, but is delayed after us5

-------------------------------------------
BUT, if you need to see what happens when interrupt trigger at us3, you need to set nbnopinst=4 and delete 1 nop
ouf
            nop            ; 1 -- 33
            nop            ; 1 -- 34
            nop            ; 1 -- 35
instruction     add a,(ix+1)        ; instruction to test

-------------------------------------------
if you need to see what happens when interrupt trigger at us4, you need to set nbnopinst=3 and delete 2 nop
ouf
            nop            ; 1 -- 33
            nop            ; 1 -- 34
instruction     add a,(ix+1)        ; instruction to test

-------------------------------------------
if you need to see what happens when interrupt trigger at us5, you need to set nbnopinst=2 and delete 3 nop
ouf
            nop            ; 1 -- 33
instruction     add a,(ix+1)        ; instruction to test

-------------------------------------------
if you need to see what happens when interrupt trigger juste after the instruction (at us6), you need to set nbnopinst=1 and delete 4 nop
ouf
instruction     add a,(ix+1)        ; instruction to test
-------------------------------------------
Enregistrer
Rhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!!

arnoldemu

Quote from: roudoudou on 19:55, 27 July 17

WTF  :o   :'( :'( :'( :laugh:
LOL.

My code booted the cart at 0000. It then copied a small function to 4000 which set RMR2 to move page 0 of cart to &8000. Then I called the code here.

First test it called to &8200 (&200 in page 0).
Then it called &a200 (&2200 in page 0).

Same result as we see for code in RAM at this location.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

Quote from: Longshot on 19:57, 27 July 17
:o
You need some explanations  ;)
This is for me ->  :picard: :picard2:
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

Longshot

#147
QuoteThis is for me

In every cases, the result must be stable, because each interrupt occurs on the same instruction, whatever the usec lost in the previous interrupt
The adjustment with "nop" & "nbnopinst" give the ability to trigger the interrupt at different "time" of the instruction.

At that point, A13 is confirmed in Extra Ram (bank 7 in block 3), C3 (bank 3 in block 1), ROM, RAM.
No Amstrad Plus found where the bug occurs with A13=1

=====================================================
With this configuration, the expected result is YELLOW
ouf
instruction     add a,(ix+1)        ; instruction to test

=====================================================
With this configuration, the result is BLUE
ouf
            nop            ; 1 -- 33
            nop            ; 1 -- 34
            nop            ; 1 -- 35
            nop            ; 1 -- 36
instruction     add a,(ix+1)        ; instruction to test

=====================================================
With other configurations, it can show when the bug occurs
Rhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!!

dragon

#148
Clear, because 13=1 make the niorq work as normal.

This is my truth table scanned.
No laughter, I know the lyrics are bad, it's for me: D
The second line a13=0 wait=0 is the line the cirtuit change should be 0 and is 1 in z80 nomal cycle.
So the most interesting next step was the gerald tells, a logic analizer and a lk6 test.

And another thing is we no know the changes to the circuit between board versions. So i think with software test can be good know what revision is the plus or the gx4000.
We can have made the test in the same revision.

arnoldemu

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

Powered by SMFPacks Menu Editor Mod