CPCWiki forum

General Category => Amstrad CPC hardware => Topic started by: McArti0 on 20:36, 11 March 24

Poll
Question: Does CPC use the R-efresh Z80A register for refresh Internal RAM?
Option 1: Yes.
Option 2: No.
Title: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 20:36, 11 March 24
org #4000
di
ld bc,&bc06
out (c),c
ld bc,&bd00
out (c),c

ld bc,&bc01
out (c),c
ld bc,&bd00
out (c),c

ld ix,0

ld bc,&1
ld a,0
ld de,0
ld hl,10

.loop
add ix,bc
ld r,a
nop
nop
nop
jr nc,loop
ld r,a
sbc hl,de
ld r,a
jr nc,loop

ld bc,&bc06
out (c),c
ld bc,&bd00+25
out (c),c
ld bc,&bc01
out (c),c
ld bc,&bd00+40
out (c),c
halt
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: Gryzor on 20:46, 11 March 24
Two options allowed in the poll? 
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: andycadley on 21:16, 11 March 24
I don't think it does:

See https://www.cpcwiki.eu/forum/amstrad-cpc-hardware/crtc-settings-which-cause-ram-refresh-to-stop/
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 21:43, 11 March 24
Quote from: Gryzor on 20:46, 11 March 24Two options allowed in the poll?
Yes.  ;D so that someone can change their mind.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: Bryce on 21:46, 11 March 24
I'll just leave this here...

It's a paragraph taken from the great book "Understanding And Expanding Your AMSTRAD CPC 464 664 6128" by Alan Trevennor and published by Sigma Press (well worth reading). https://www.cpcwiki.eu/index.php/Understanding_and_Expanding_your_Amstrad_CPC464-664/6128

The entire book can be found in text and PDF format here:

https://archive.org/stream/understanding-and-expanding-your-amstrad-cpc-464-664-6128-alan-trevennoracme/Understanding_and_expanding_your_AMSTRAD_CPC464-664-6128%28Alan_TREVENNOR%29%28acme%29_djvu.txt

"The RAM chips 

The RAM consists of 8 chips. These are all 64K by 1 bit dynamic RAM chips,
type HM4864. Whilst they offer far higher capacity per chip than a static RAM
(for example the 6116 RAM which is a 2K by 8 bit, which you may have
seen used in magazine projects a lot), dynamic RAM chips need to be
continuously reminded of what they are remembering! This is because the
memory elements are actually tiny capacitors, which if they are not topped up
will lose their charge. This top up function is called refreshing them. (No
Lager jokes please!). The trick is to perform the RAM refresh when the
memory is not being accessed. In fact the Z80A has the facility to
automatically perform refresh, but in the CPC the gate array has been chosen
to do it. This is because the memory is also accessed by the VDU controller,
and the gate array has to ensure that the memory is not required by either
processor or VDU controller before refresh can occur. The memory refresh
process consists of pulsing two input lines to all the RAM chips. These are
called CAS (Column Address strobe) and RAS (Row address strobe). These
are pulsed whilst the row and column addresses are passed into the RAM
sequentially. The 4864 chips used have a cycle time of 200 nanoseconds."


Bryce.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: Gryzor on 09:40, 12 March 24
Quote from: McArti0 on 21:43, 11 March 24
Quote from: Gryzor on 20:46, 11 March 24Two options allowed in the poll?
Yes.  ;D so that someone can change their mind.
That's another option ("allow users to change their vote" or something), the option you enabled allows users to vote both yes and no at the same time :D
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 10:14, 12 March 24
But now they won't deny that they pressed NO. ;D  At least I think so
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: Bryce on 14:53, 12 March 24
Why would they want to deny something that I just confirmed above?

Bryce.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 15:34, 12 March 24
Because the code I showed shows that if you turn off the CRTC counter and turn off R, refreshing does not occur. 

But if we do not turn off R, refreshing works great, for all memory. Why? 

Because the memory is refreshed based on R from Z80 and the RAS signal in RAS-only memory mode.

And this happens for 60% of the time CPC is running in standard resolution.

Ps. Additionally, it is a surprise that in LowROM there are LD R,A and LD A,R commands, and more than once. :P
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: eto on 16:00, 12 March 24
Quote from: McArti0 on 15:34, 12 March 24But if we do not turn off R, refreshing works great, for all memory. Why?
Did you check "CRTC off, but R active" where your test code disables all interrupts, disables the CRTC and then enters an endless loop?



Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 16:07, 12 March 24
Quote from: eto on 16:00, 12 March 24where your test code disables all interrupts, disables the CRTC and then enters an endless loop?
On my CPC :D. I will prepare such a comparison on DSK.
The code shown is spectacular because it shows the contents of unrefreshed memory.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: Bryce on 16:16, 12 March 24
The CRTC is creating the addresses for the refresh, so any changes to the CRTC could effect the refreshing.

Bryce.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 16:26, 12 March 24
R6=0 R1=0 and CRTC nothing creating. When always set R=0 CPC crashing. When R is working CPC without CRTC working too.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: eto on 16:39, 12 March 24
I might be wrong but when I made my internal RAM expansion I this became my understanding of the refresh, which was the foundation to actually replace the internal RAM with bigger ICs:

The 4164 ICs are organized as a matrix of 128 rows and 512 columns of cells(bits). These cells need to be refreshed every 2ms at least. Each 512 cells in a row are refreshed, when the respective row is accessed (RAS signal + address lines). So what a computer needs to ensure is that within 2ms all 128 RAM rows are accessed at least once. It's not necessary to really read from RAM, it's just important that the RAS signal is there and 128 different ROW addresses have been accessed within those 2ms.  How the computer is doing that is is done is not relevant. You can use the RFSH signal to build a respective circuit that does that - or you can do it differently. Any access to the RAM will refresh cells and as long as you make sure all rows are accessed your RAM will be refreshed.

The Amstrad engineers now did quite a genius trick which ensures RAM refresh as a side effect of the GateArray accessing the RAM, which it will always do (unless someone explicitly disables it):

The lower address lines A0-A7 of the memory are usually mapped to the CAS sequence of RAM access, but in the CPC they are mapped to the RAS sequence. (Note: The higher lines A8-A15 are then mapped to the CAS sequence. For the physical storage in the RAM ICs this doesn't matter how exactly the bytes are stored as long as reads and writes to the same address also access the same byte in RAM.)

This unusual physical addressing has a nice side effect for RAM refresh: As long as RAM is accessed byte per byte for at least 128 bytes continuously all RAM rows will be refreshed properly - without the need for any special refresh logic.

And exactly this is, what the GateArray does as it accesses the screen RAM byte by byte for usually 16KB in a row. And as long as the GateArray reads the screen the RAM will be refreshed.

If you now turn off the GateArray access it doesn't necessarily mean that the RAM will no longer be refreshed as also CPU access to the RAM will also refresh the RAM. Again as long as the CPU reads from 128 continuous addresses (within the refresh period of 2ms) all RAM rows will be accessed - and refreshed. If I am not mistaken this does even work if the CPU reads from ROM as the address will be put on the RAM IC address pins during the RAS sequence - just the CAS is not executed - but that doesn't matter as only RAS is required to do the RAM refresh.

So as long as the computer is accessing "enough" bytes within the 2ms refresh window the RAM rows will be refreshed.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: eto on 16:48, 12 March 24
Quote from: McArti0 on 16:07, 12 March 24On my CPC :D. I will prepare such a comparison on DSK.
Sorry, I did not mean "where" you did that. But you need to compare both situations similarly: 

When you set the R-register to the same value you are doing that in an endless loop. When you do the same check without setting the R register you need to use the exact same code that disables the CRTC and goes into an endless loop (just not set the R register). 
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 17:26, 12 March 24
YES!  :D  eto win. Long 7ms between last screen line  no. 200 to first line no. 0,  memory is refreshing by z80 and his R register.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 17:38, 12 March 24
I try to answer it in a different way.

No the CPC in any normal operation never needs or considers the refresh register. Also the Gatearray is very closely managing the access to the ram.

How does the refresh work on a 4864 ?
If you put an address (8bit) to the RAM chip, and then strobe RAS signal, it will read the whole row into a buffer and writes it back into the cell. That is actually the refresh.

So if you do read every row through the required time, then the CPU putting addresses to the bus, would not be required.

However obviously with normal code, you cannot guarantee, that the CPU just by chance is reading all rows.

So that is (we are now forgetting about the CPC for a second here), why the CPU supports to output addresses to the addressbus, when it actually does not need it and then run the refresh with that. This would be required in other systems, as nothing else would read the RAM.

However in CPC, the CRTC is connected to the RAM in a way, that it output each of the 256 row addresse for every frame. So the refresh will be done every 20µs.

Also the Gatearray is handling the access of the Addressbus to the RAM. At CPU T-Cycles 3 and 4 (3 and 4 are normally the normal refresh cycle) the gatearray exclusively reserves the RAM access to the CRTC and Gatearray. CRTC is actually not reading it, but outputting the correct memory address.

Gatearray will read actually data in that timeframe.

So even if you would want to believe that the CPU refresh is doing anything, it is actually not able to ever output the address to the physical ram as it is blocked via the Multiplexer by command of the GateArray.

The GateArray is actually the Commander in the CPC  - not the CPU. The CPU needs to obey to the ruling of the GateArray.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 17:59, 12 March 24
Some more background, from Z80 User Manual:

QuoteMemory Refresh (R) Register. The Z80 CPU contains a memory refresh counter, enabling dynamic memories to be used with the same ease as static memories. Seven bits of this 8-bit register are automatically incremented after each instruction fetch. The eighth bit remains as programmed, resulting from an LD R, A instruction. The data in the refresh counter is sent out on the lower portion of the address bus along with a refresh control signal while the CPU is decoding and executing the fetched instruction. This mode of refresh is transparent to the programmer and does not slow the CPU operation. The programmer can load the R register for testing purposes, but this register is normally not used by the programmer. During refresh, the contents of the I Register are placed on the upper eight bits of the address bus.

Here is the corresponding timing diagram:
OpCodeFetch.jpg

So you can see, refresh is working in T-Cycles 3 and for of an M1 cycle (opcode fetch). 

Two other things to notice:
1. The RFSH line is not connected to any component in the CPC, only to the external bus. That would be needed, as if you do not strobe the RAS signal, you will not get the RAM to read anything into the buffer and therefore not being able to refresh it. Some extra logic is required to use that feature.
2. See the Gatearray timing, that exclusively openes a Window for the addresses of the CPU getting to the RAM.

Pls see the attached diagram. I shamelessly copied it from here https://bread80.com/2021/06/03/understanding-the-amstrad-cpc-video-ram-and-gate-array-subsystem/:

Blue is, the gatearry is using the RAM, red is, when the Gatearray is actually alowing the CPU to read from ram. But control (RAMRD and CPU line) is handled by the GateArray.

CPUvsGateArray.jpg
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 18:01, 12 March 24
All incorrect. T4 is for CPU. and CPU refresh work.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 18:05, 12 March 24
You are saying Zylog is incorrect about their timing? 

Read it yourself if you do not trust me copying it from the original manual.
https://www.zilog.com/docs/z80/um0080.pdf

I know you know better than anyone before you. We are all wrong.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 18:31, 12 March 24
ETO win this competition. Do not get excited. Write next post tomorrow ok?

Winner text:

Quote from: eto on 12.03.2024, 16:39:51
If you now turn off the GateArray access it doesn't necessarily mean that the RAM will no longer be refreshed as also CPU access to the RAM will also refresh the RAM. Again as long as the CPU reads from 128 continuous addresses (within the refresh period of 2ms) all RAM rows will be accessed - and refreshed. If I am not mistaken this does even work if the CPU reads from ROM as the address will be put on the RAM IC address pins during the RAS sequence - just the CAS is not executed - but that doesn't matter as only RAS is required to do the RAM refresh.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: eto on 18:42, 12 March 24
Quote from: McArti0 on 17:26, 12 March 24memory is refreshing by z80 and his R register.
no, it's not... that's what I tried to explain in my very long post (and what SerErris also explained in a different way): The r register does not have anything to do with the RAM refresh in the CPC. 

You can also check the schematics to see that the RFSH line of the CPU is not used anywhere in the CPC (except for the expansion bus).
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: eto on 18:44, 12 March 24
Quote from: McArti0 on 18:31, 12 March 24ETO win this competition. Do not get excited. Write next post tomorrow ok?

Winner text:

Quote from: eto on 12.03.2024, 16:39:51
If you now turn off the GateArray access it doesn't necessarily mean that the RAM will no longer be refreshed as also CPU access to the RAM will also refresh the RAM. Again as long as the CPU reads from 128 continuous addresses (within the refresh period of 2ms) all RAM rows will be accessed - and refreshed. If I am not mistaken this does even work if the CPU reads from ROM as the address will be put on the RAM IC address pins during the RAS sequence - just the CAS is not executed - but that doesn't matter as only RAS is required to do the RAM refresh.
but it's not the refresh feature of the CPU. This will only happen if the CPU "coincidentally" accesses the right addresses. And this coincidence is pretty high in the CPC as A0-A7 are connected to the RAM rows.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 18:51, 12 March 24
It is actually the loop you are running to test it.

Every read of the memory (so actually the loop) will read that row (the whole row). And this row will get refreshed. Your loop will have some bytes, which translates into memory rows (as ETO explained).

So if you are running aloop over a few bytes (lets say 10) you will already hit 10 rows in the CPC. If your loop is running over 127 bytes - you probably hit all rows.

So the loop itself will never recognize that anything is wrong as the loop itself does refresh the cells needed for the loop (and others).
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: eto on 19:32, 12 March 24
Quote from: SerErris on 18:51, 12 March 24is running over 127 bytes - you probably hit all rows.
if it runs over 128 bytes it will definitely hit all rows.


Quote from: McArti0 on 17:26, 12 March 24memory is refreshing by z80 and his R register.
Maybe another test you can do: Remove the Z80 from its socket. Bend up the RFSH pin and put the CPU back into its socket. Then try again. 
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 20:47, 12 March 24
Quote from: eto on 18:42, 12 March 24You can also check the schematics to see that the RFSH line of the CPU is not used anywhere in the CPC (except for the expansion bus).
Our memory not need RFSH line because they are "RAS-only" refresh. They only need ROW ADDRESS and RAS edge. thats all.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 21:09, 12 March 24

Quote from: SerErris on 18:51, 12 March 24So if you are running aloop over a few bytes (lets say 10) you will already hit 10 rows in the CPC. If your loop is running over 127 bytes - you probably hit all rows.

I took care of that. the loop is tight. Moreover, it is not 127 bytes but 256+126 because CPC has addresses connected to ROW A0-A6 in the order A2, A1, A4, A3, A6, A5, A8. Without A0 and A7, there is A8.

Refreshing works for me at R6=0. So what's wrong?
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: Bryce on 21:17, 12 March 24
Quote from: McArti0 on 18:31, 12 March 24ETO win this competition. Do not get excited. Write next post tomorrow ok?

Winner text:

Quote from: eto on 12.03.2024, 16:39:51
If you now turn off the GateArray access it doesn't necessarily mean that the RAM will no longer be refreshed as also CPU access to the RAM will also refresh the RAM. Again as long as the CPU reads from 128 continuous addresses (within the refresh period of 2ms) all RAM rows will be accessed - and refreshed. If I am not mistaken this does even work if the CPU reads from ROM as the address will be put on the RAM IC address pins during the RAS sequence - just the CAS is not executed - but that doesn't matter as only RAS is required to do the RAM refresh.

So what you are actually saying is that your aim, right from the start, was to ignore all the evidence presented before you by multiple people and documented in books until you found someone who vaguely confirmed your incorrect initial assumptions? You have a great future in politics ahead of you!

So now explain to us all what R157 and R158 are there for?

Bryce.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: andycadley on 21:49, 12 March 24
One thing I've often wondered but not entirely understood is this comment in the Arnold V documentation about the screen spli:

QuoteNote that care should be taken with programming this facility such that the screen split does not alter the function of address bits A1-A8 and the dynamic memory refresh is not upset.

Has anyone got an example of what you could do that would cause this issue? Or maybe @McArti0 can explain why it doesn't matter if the Z80 refresh mechanism is used.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 22:00, 12 March 24
I have code that returns even though CRTC is disabled and does not produce artifacts.
I showed code that produces artifacts when avoiding R increment.
I don't know what r157,158 are for, CPC also works without them.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: eto on 22:36, 12 March 24



I hope I (at least vaguely) disproved the initial assumption...

That this was seen as proof/confirmation is quite surprising to me.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 08:16, 13 March 24

Ah no, the 0 byte does not count  :D
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 08:34, 13 March 24
And yet it doesn't work. I thought I had an ace up my sleeve and I didn't.  :-\

When i set R6=0, screen has one scan line and refresh something.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 15:49, 13 March 24
Quote from: McArti0 on 20:47, 12 March 24
Quote from: eto on 18:42, 12 March 24You can also check the schematics to see that the RFSH line of the CPU is not used anywhere in the CPC (except for the expansion bus).
Our memory not need RFSH line because they are "RAS-only" refresh. They only need ROW ADDRESS and RAS edge. thats all.

Yes, but the CPU cannot strobe RAS. The GateArray does. And the GA does it based on /RD and /MREQ or on its own reads. /RFSH has no impact - is not connected to the GateArray and to anything else inside the CPC.

/RD is disabled during /RFSH.

you can see it in the timing diagram of the CPU but as well as the real operation of the gatearray:
CPUvsGateArray.jpg

The blue part is where the gatearray is accessing the RAM, and where it is actually reading the screen data.

You can see the following: GA sets RAS (one time) and then two times CAS. The reason for that is, that the CRTC has generated two addresses and only the lowest bit, so the next byte in RAM from the same column is retrieved. That is one of the features of the RAM, that it can burst read. So you only need to have a single RAS and can then read up to 512 bytes (256 bytes depending on the memory). This is unused in CPC other for the aspect of the Gatearray reading screen data.

You can also see NRD high (not active) at the same time - that is the CPU signal to read stuff which active low. So in this particular section it is not active or disabled.
What you also can see is that during the blue time, the NMREQ is going down (active). That is the actual time when the CPU wants to refresh. NRFSH is not captured  unfortunately, but would be active at the same time, as you can see in the CPU documentation.
So the logic is actually RD and MREQ active = RAS/CAS. But only if that is coming in in a specific time window (Sequencer).

But here, we actually do not have RD and MREQ active, but only MREQ, so it is getting ignrored by the GateArray.

So all in all, there is no technical way for the CPC to use the RFSH Line of the CPU and even the normal RD and MREQ lines are not directly connected to the RAM, but instead to the GateArray. And it will not use it to create the RAS signal here.

Your conclusion out of what you overserve, is just not correct and you need to alter the conclusion.

Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 16:22, 13 March 24
Here there is no M1 cycle, then the nCPU comes first and then refresh at the same time as the screen reading. Classic NOP. but of course the Z80 refresh is a competitor to reading RAM for the screen
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 17:20, 13 March 24
NCPU_ADDR is high - means it is not active (active low signal). Which means during the blue part, the CPU cannot access the ram, however during the red part it can access the RAM. 

More technically it means, during NCPU_ADDR active (low) the address lines of the CPU are multiplexed to the RAM  (ram) and all other times the CRTC address lines are connected to RAM.

The CPU can only read or write during the short period of time when the gate array puts NCPU_ADDR low. Which starts at second half of the image and ends 3/4 to the right of the image.

The Gatearray actually need to force the CPU to be in that slot, so that it does not write to the RAM (e.g. wants to write), but the address lines are currently connected to the CRTC and also NMWE is disabled (so nothing the CPU will do will get ever written into CPU). It does it with wait states, so that it always falls into the 4 clock cycle boundry and the CPU will ever read or write from Memory at this particular fixed window.

That is actually T2 of the CPU M cycle and after that the address lines are disconnected - so the address output of the refresh address genereated by the R register between T3 and T4 cannot reach the RAM. 

In CPC the CPU can not compete with screen reading and can not use its refresh technology for any task.



Title: Re: Does CPC use the R-efresh Z80A register?
Post by: Bread80 on 18:42, 13 March 24
One more thing to chew on: The R register is only a seven bit counter (bit 7 never updates). The 4164 DRAM requires 16-bit addresses. To quote from the datasheet (https://www.farnell.com/datasheets/1905614.pdf):

"Refresh A refresh operation must be performed at least every four milliseconds to retain data. Since the output buffer is in the high−impedance state unless CAS is applied, the RAS only refresh sequence avoids any output during refresh. Strobing each of the 256 row addresses (A0 through A7) with RAS causes all bits in each row to be refreshed. CAS can remain high (inactive) for this refresh sequence to conserve power."

The memory chips require an 8-bit refresh counter. The Z80 only provides a 7-bit refresh counter. Therefore the Z80 can't be the one driving the refresh.

(And to recap what's already been said: The CRTC and GA already provide a 14 bit counter, and this is already driving RAS of the RAMs. Why would the designers of the Amstrad ignore this and add extra circuitry to get the refresh from the Z80 (and they'd need to find extra time in the video cycle to do so?).)
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: eto on 19:45, 13 March 24
Quote from: Bread80 on 18:42, 13 March 24each of the 256 row addresses
quite many (most?) 4164 chips use only 7 bits for the rows, e.g. the Samsung KM4164B.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 20:15, 13 March 24
Quote from: eto on 16:39, 12 March 24The 4164 ICs are organized as a matrix of 128 rows and 512 columns of cells(bits). These cells need to be refreshed every 2ms at least. Each 512 cells in a row are refreshed, when the respective row is accessed (RAS signal + address lines). So what a computer needs to ensure is that within 2ms all 128 RAM
Just out of interest, I looked the datasheet of the 4164 up, and was wondering about this as well.
According to this datasheet https://www.silicon-ark.co.uk/datasheets/TMS4164-datasheet-texas-instruments.pdf
it is actually a 256 rows by 256 columns chip. 

So the chips build into the 464s (at least) would need full 8 bit for refresh.

However the Hitachi 4864 actually have a 128x512 organisation and can be refreshed in 128 cycles (actually can get refreshed by the R register of the Z80.

I think they just jammed everything in the CPCs, and that was possible because of Refresh is being done by GA/CRTC and they do not care if it needs 256 reads or 128 reads. 

In reality 256 reads are about 3,2 screen lines, which will take about 128 µs only.
And the 4164 already have a refresh time of 4ms ... which is plenty of time. So that is actually never a problem. 

Also the refresh of the CRTC is absolutely stable, vs. the CPU is refreshing only at M1 cycles and that would be very inconsistent depending on the code you actually execute. It would be in average every 3-4µs and so that would mean 256 rows (256 commands) would be about 1ms. Still a lot of air in there.



Title: Re: Does CPC use the R-efresh Z80A register?
Post by: andycadley on 20:51, 13 March 24
I suspect the real reason for using the GA is that the original design was based on the 6502, which needed external RAM refresh. So they'd probably already figured that out before switching the CPU over to the Z80 and why change something that already worked?
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 20:58, 13 March 24
But CRTC does not refresh at all for 7ms per frame.

Have any of you checked if the RAS for CRTC exists under every high nCAS state even when it is border?
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: dodogildo on 21:33, 13 March 24
I think if Roland Perry and William Poel got in a time machine and read this forum, their minds would explode. They would definitely kidnap some of you and take them back to their own time to exploit your talents and intelligence.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: Bread80 on 00:11, 14 March 24
Quote from: SerErris on 20:15, 13 March 24However the Hitachi 4864 actually have a 128x512 organisation and can be refreshed in 128 cycles (actually can get refreshed by the R register of the Z80.
I've read that the 7-bit refresh of the Z80 caused 'challenges' for computer designers when 64kbit DRAMs started to arrive. I'd guess Hitachi found a clever solution - refresh two lines off a single RAS.

BTW, one more thing I'm thinking about: A0 is driven by the GA. It's used to read the two video bytes during a cycle. It updates between the two video CAS cycles. There is no second RAS. If A0 where being used for CAS only bytes at even addresses would get refreshed!

I'm willing to bet that the A0 is sent to the RAMs during a CAS cycle. A RAS cycle is (probably) running off A1 to A8 (although could be other address lines). This would depend on the wiring of the multiplexers. If anyone wants to take a look at the schematics they're welcome.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: eto on 00:20, 14 March 24
Quote from: McArti0 on 20:58, 13 March 24But CRTC does not refresh at all for 7ms per frame.

Have any of you checked if the RAS for CRTC exists under every high nCAS state even when it is border?
See attached a screenshot from the 6845 datasheet: The CRTC address lines continue to run. This actually makes sense as the CRTC was (also) used in graphics cards where no CPU could do the RAM refreshes so the CRTC had to make sure all graphics RAM is always refreshed.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: eto on 00:24, 14 March 24
Quote from: Bread80 on 00:11, 14 March 24I'm willing to bet that the A0 is sent to the RAMs during a CAS cycle. A RAS cycle is (probably) running off A1 to A8 (although could be other address lines). This would depend on the wiring of the multiplexers. If anyone wants to take a look at the schematics they're welcome.
that's exactly what's happening
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: Bread80 on 00:39, 14 March 24
Quote from: McArti0 on 20:58, 13 March 24But CRTC does not refresh at all for 7ms per frame.

Have any of you checked if the RAS for CRTC exists under every high nCAS state even when it is border?
The GA is still generates all the video related signals during HSYNC, VSYNC and border periods as if nothing has changed.

I'm not an expert on the 6845 but the datasheet appears to show that the addresses (MA0-MA13) continue to count during those periods.
https://www.cpcwiki.eu/imgs/d/da/Mc6845.motorola.pdf

(Up until now I'd assumed the designers had missed a trick my not running the CPU at full speed during those periods. But if the video cycles are still required for memory refresh then they were simply being clever...)
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 10:14, 14 March 24
Quote from: McArti0 on 20:58, 13 March 24But CRTC does not refresh at all for 7ms per frame.

Have any of you checked if the RAS for CRTC exists under every high nCAS state even when it is border?

You are now mixing up blank cycles of a frame and CRTC counting. Even during the blank cycle the CRTC keeps counting, because how would it know otherwise if the blank phase needs to end?`

Beneath the counting and the addresses the CRTC is generating three signals.

VSYNC, HSYNC and DISPEN. All three are going into the GA and it is used there to create the correct timing of the video signal.

But the CRTC never stops counting.

Regarding the RAS signal.

Yes it is important that not only the CRTC is counting, but that the GA is continue to create a RAS signal.

And yes it does.

Internally the GA creates a sequence byte, that is pretty much independent of any other value in the CPC (there is one exception regarding interrupts).

The Sequence looks like this:
Bits  7654 3210   S7-S0
---------------
FF:   1111 1111
FE:   1111 1110
FC:   1111 1100
FB:   1111 1000
F0:   1111 0000
E0:   1110 0000
C0:   1100 0000
80:   1000 0000
00:   0000 0000
01:   0000 0001
03:   0000 0011
07:   0000 0111
0F:   0000 1111
1F:   0001 1111
3F:   0011 1111
7F:   0111 1111

FF:
.
.
.


The clock is running at 16Mhz. So it runs from one value to the next ever 1/16 µs. That is 4 times faster then the CPU signal.

This sequence is then used to create most of the other signals. That includes the CPU clock, the CRTC clock (and sound chip) the RAS signal and some others.

The RAS signal only depends on this sequence and the clock. The clock is used to trigger a flip-flop to stabilize the RAS output.

The function is S0 AND (NOT S2 OR S6)
So this is true for the following Values:
FF, 01,03, 7F. ... in other order 01-03 (2 clocks) and 7F-FF (2 clocks) the RAS high will be generated (not active) and from 07-3F (4 clocks) and  FE-00 (8 clocks) it will RAS low (active).

So yes. the GateArray is creating the RAS signal whatever happens to the other parts of the systems. It is not even dependent on the HSYNC/VSYNC signals.

CAS however is only created if it GA needs to read something or if there is a MREQ from the CPU. However the MREQ is also conditionally that it is NOT a Refresh (e.g. not during an M1 cycle after it has finished its opcode read). There is a particular piece of logic in the GA that actually filters this specific condition, to not get confused when a CAS signal is needed.

If you want to read the logic of the CAS signal, which is pretty much more complicated than the RAS signal, I can only recommend Gerald's schematics of the GateArray. Most is explained there, and I just described it in more words.


Addition:
CPU signal (which is used to switch from CRTC Address to CPU address is the following logic:
S1 NAND NOT S7
So when S1 = 1 and S7 = 0 CPUN gets low (active)
This is exactly the case during 03-7F, so for exactly 6 GA cycles, or for 6/16 or 0,375 µs each µs. That is the time window (and the only time window) when the CPU address bus is connected to the RAM. All other times, it is disconnected and the CRTC address bus is connected.

Also this logic is not depending on anything else than the internal Sequencer of the GateArray.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 10:23, 14 March 24
Double post
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 10:40, 14 March 24
BTW: The Toshiba TMM4164AP also has a 7*9 bit matrix. It is just internally taking one bit of the RAS and combining it with the 8 bit of CAS to achieve that.
https://www.datasheetarchive.com/datasheet?id=dccad5d93e48b7d136da4dc4f6d7cf660e1972&type=M&term=tmm4164

They have a very good datasheet showing how they do this internally:
TMM4164AP_Block.jpg
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: eto on 10:46, 14 March 24
Quote from: SerErris on 10:14, 14 March 24Gerald's schematics of the GateArray.
oh... were can we find that?
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: robcfg on 12:57, 14 March 24
You can find them in the Gate Array Decapped thread: https://www.cpcwiki.eu/forum/index.php?msg=170713

Or in codedchip's repository: https://github.com/codedchip/AMSGateArray 
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: martin464 on 14:32, 14 March 24
all this makes sense but one thing i don't understand - the video ram is being read full-time, 2 bytes each microsecond
the cpu is allocated its slot for the last part of that

how is a ram refresh squeezed into this time if the v-ram part is constant?

i thought i read somewhere it only refreshes if the z80 isn't accessing the ram I guess RD and WR being checked...
so it could be doing it selectively when cpu doesn't need memory access, if so i'm not sure how it handles it when external ram is paged in, maybe it switches that off too as part of it

so although it's under gate array control maybe it happens during the time the cpu usually has access to the ram?
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 14:45, 14 March 24
Quote from: martin464 on 14:32, 14 March 24how is a ram refresh squeezed into this time if the v-ram part is constant?
vram and all internal RAM is read at all time by GA based on the address from CRTC . This is enough for refresh all.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: andycadley on 14:50, 14 March 24
Reading a row of RAM is sufficient to refresh that row, when the GA doesn't need to read the row (because we're in the border area) it just refreshes it instead. Thus the RAM is always refreshed and the Z80 mechanism doesn't need to be involved.

If you set the GA up in such a way that it won't refresh the RAM itself, then it pretty much down to whether the Z80 ends up reading sufficient rows often enough to keep them all refreshed, because it's own mechanism isn't connected to the RAM.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 22:15, 14 March 24
I think we turning in circles now. All that has been extensively explained in the posts before.

The RAM is organized (depending on the ram) in 127 or 256 rows and 512 or 256 columns.

The refresh of the ram works if you put one of the row addresses to the adress bus and then strobe  the RAS signal.
The RAM in CPC is connected in a way, that the lowest 8 bit actually form the row address. 

So in worst case it takes 256 µs for the gate array to read all row addresses. (2/µs). 

about 2/3 of a µs (10/16µs) is used by the GA to read two bytes and the other 6/10s are available to the CPU to work with memory. 

There is no additional refresh as the read from the gate array and the way how refresh works for RAM is enough to refresh everything 16times of the required time. So that includes the full 64/128kb of RAM. 

Interestingly - the gate array does not read all the ram, it only reads the 4k addressed by the CRTC. The rest is never read, and esp the second bank of the 6128 is actually never read. It just gets the same RAS signals and therefore is getting refreshed the same way, but it never gets CAS signals from GateArray.  Some expections - bank switching.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 23:04, 14 March 24
Quote from: SerErris on 22:15, 14 March 24I think we turning in circles now.
Ok. Lets go far. So how does CPC use the R-efresh register?

https://github.com/Bread80/CPC6128-Firmware-Source/blob/main/6128ROM.disasm

It's like timer?

;; sample edge and check for escape
;; L = bit-sequence which is shifted after each edge detected
;; starts of as &55 (%01010101)

;; check for escape
2b3d 06f4      ld      b,&f4 ;; PPI port A
2b3f ed78      in      a,(c) ;; read keyboard data through PPI port A (connected to PSG port A)
2b41 e604      and     &04 ;; escape key pressed?
;; bit 2 is 0 if escape key pressed
2b43 c8        ret     z


;; precompensation?
2b44 ed5f      ld      a,r   ;;<<<<<<<<<<<<<<<<<<<<<<<  A,R <<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;; round up to divisible by 4
;; i.e.
;; 0->0,
;; 1->4,
;; 2->4,
;; 3->4,
;; 4->8,
;; 5->8
;; etc

2b46 c603      add     a,&03
2b48 0f        rrca ;; /2
2b49 0f        rrca ;; /4

2b4a e61f      and     &1f ;;

2b4c 4f        ld      c,a

2b4d 06f5      ld      b,&f5 ; PPI port B input (includes cassette data input)

;; -----------------------------------------------------
;; loop to count time between edges
;; C = time in 17us units (68T states)
;; carry set = edge arrived within time
;; carry clear = edge arrived too late

2b4f 79        ld      a,c ; [1] update edge timer
2b50 c602      add     a,&02 ; [2]
2b52 4f        ld      c,a ; [1]
2b53 380e      jr      c,&2b63          ; [3] overflow?

2b55 ed78      in      a,(c) ; [4] read cassette input data
2b57 ad        xor     l ; [1]
2b58 e680      and     &80 ; [2] isolate cassette input in bit 7
2b5a 20f3      jr      nz,&2b4f         ; [3] has bit 7 (cassette data input) changed state?

;; pulse successfully read

2b5c af        xor     a
2b5d ed4f      ld      r,a              ;;<<<<<<<<<<<<<<<<<<<<<<<  R,A <<<<<<<<<<<<<<<<<<<<<<<<<<<<<

2b5f cb0d      rrc     l ; toggles between 0 and 1

2b61 37        scf     
2b62 c9        ret     

;; time-out
2b63 af        xor     a
2b64 ed4f      ld      r,a                      ;;<<<<<<<<<<<<<<<<<<<<<<<  R,A <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2b66 3c        inc     a ; "read error a"
2b67 c9        ret     

;;========================================================================================
;; write data byte to cassette
;; A = data byte
2b68 d5        push    de
2b69 1e08      ld      e,&08 ;; number of bits
2b6b 57        ld      d,a

2b6c cb02      rlc     d ;; shift bit state into carry
2b6e cd782b    call    &2b78 ;; write bit to cassette
2b71 3003      jr      nc,&2b76         

2b73 1d        dec     e
2b74 20f6      jr      nz,&2b6c         ;; loop for next bit

2b76 d1        pop     de
2b77 c9        ret     

;;========================================================================================
;; write bit to cassette
;;
;; carry flag = state of bit
;; carry set = 1 data bit
;; carry clear = 0 data bit

2b78 ed4be8b1  ld      bc,(&b1e8)
2b7c 2aeab1    ld      hl,(&b1ea)
2b7f 9f        sbc     a,a
2b80 67        ld      h,a
2b81 2807      jr      z,&2b8a          ; (+&07)
2b83 7d        ld      a,l
2b84 87        add     a,a
2b85 80        add     a,b
2b86 6f        ld      l,a
2b87 79        ld      a,c
2b88 90        sub     b
2b89 4f        ld      c,a
2b8a 7d        ld      a,l
2b8b 32e8b1    ld      (&b1e8),a

;; write a low level
2b8e 2e0a      ld      l,&0a ; %00001010 = clear bit 5 (cassette write data)
2b90 cda72b    call    &2ba7

2b93 3806      jr      c,&2b9b          ; (+&06)
2b95 91        sub     c
2b96 300c      jr      nc,&2ba4         ; (+&0c)
2b98 2f        cpl     
2b99 3c        inc     a
2b9a 4f        ld      c,a
2b9b 7c        ld      a,h
2b9c cd002b    call    &2b00 ; update crc

;; write a high level
2b9f 2e0b      ld      l,&0b ; %00001011 = set bit 5 (cassette write data)
2ba1 cda72b    call    &2ba7

2ba4 3e01      ld      a,&01
2ba6 c9        ret     


;;=====================================================================
;; write level to cassette
;; uses PPI control bit set/clear function
;; L = PPI Control byte
;;   bit 7 = 0
;;   bit 3,2,1 = bit index
;;   bit 0: 1=bit set, 0=bit clear

2ba7 ed5f      ld      a,r                    ;;<<<<<<<<<<<<<<<<<<<<<<<  A,R <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2ba9 cb3f      srl     a
2bab 91        sub     c
2bac 3003      jr      nc,&2bb1         ;

;; delay in 4us (16T-state) units
;; total delay = ((A-1)*4) + 3

2bae 3c        inc     a ; [1]
2baf 20fd      jr      nz,&2bae         ; [3]

;; set low/high level
2bb1 06f7      ld      b,&f7 ; PPI control
2bb3 ed69      out     (c),l ; set control

2bb5 f5        push    af
2bb6 af        xor     a
2bb7 ed4f      ld      r,a                              ;;<<<<<<<<<<<<<<<<<<<<<<<  R,A <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2bb9 f1        pop     af
2bba c9        ret     
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 09:40, 15 March 24
need to delete to rework
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 14:42, 15 March 24
;********************************** Read Byte
                                    ; OUT: A: Byte
                                    ;      CY=0 for error
                                    ;      A: Error number
29B0    D5          PUSH    DE
29B1    1E 08       LD      E,08        ; Counter for 8 bits
29B3    2A CE B8    LD      HL,(B8CE)   ; Time limit/edge flag
29B6    CD D4 29    CALL    29D4        ; Wait for 1st edge of the bit
29B9    DC DD 29    CALL    C,29DD      ; Is it okay? Wait for 2nd edge
29BC    30 0D       JR      NC,29CB     ; Error?
29BE    7C          LD      A,H         ; Time counter limit
29BF    91          SUB     C           ; Subtract current time counter to get bit
29C0    9F          SBC     A           ; A=$FF for 1-bit
29C1    CB 12       RL      D           ; Rotate bit into byte
29C3    CD 90 29    CALL    2990        ; Set check-w. according to bit
29C6    1D          DEC     E           ; Bit counter
29C7    20 EA       JR      NZ,29B3     ; More bits?
29C9    7A          LD      A,D         ; Read byte
29CA    37          SCF                 ; CY=1 for no error
29CB    D1          POP     DE 
29CC    C9          RET                

;**********************************  Wait for next edge, ESC t.
                                    ; IN/OUT: L: Edge flag
                                    ;              L=$55 for negative edge
                                    ;              L=$AA for positive edge
                                    ;              (OUT for the other edge)
                                    ;      OUT: C: Time counter
                                    ;           CY=0, Z=1, A=0 for abort
                                    ;           CY=0, Z=0 for error then: A: Error number
29CD    06 F4       LD      B,F4        ; PIO, Port B
29CF    ED 78       IN      A,(C)       ; Keyboard feedback of the 8th row
29D1    E6 04       AND     04          ; Isolate ESC bit
29D3    C8          RET     Z           ; ESC pressed?

;********************************** Wait for next edge
                                    ; IN/OUT: L: Edge flag
                                    ;              L=$55 for negative edge
                                    ;              L=$AA for positive edge
                                    ;              (OUT for the other edge)
                                    ;      OUT: C: Time counter
                                    ;           CY=0, Z=0 for error then: A: Error number
29D4    ED 5F       LD      A,R         ; Time since last edge
29D6    C6 03       ADD     03 
29D8    0F          RRCA                ; Generate corresponding time counter value
29D9    0F          RRCA               

29DA    E6 1F       AND     1F
29DC    4F          LD      C,A         ; Put it as time counter into C

;********************************** Wait for 2nd edge in the bit
                                    ; IN/OUT: L: Edge flag
                                    ;              L=$55 for negative edge
                                    ;              L=$AA for positive edge
                                    ;              (OUT for the other edge)
                                    ;      C: Time counter
                                    ; OUT: CY=0, Z=0 for error then: A: Error number

29DD    06 F5       LD      B,F5        ; PIO, Port B
29DF    79          LD      A,C         ; Time counter
29E0    C6 02       ADD     02          ; Increment
29E2    4F          LD      C,A         ; Set again
29E3    38 0E       JR      C,29F3      ; Carry? Then time is too long -+
29E5    ED 78       IN      A,(C)       ; Load input bit from cassette  |
29E7    AD          XOR     L           ; Invert depending on edge flag |
29E8    E6 80       AND     80          ; Isolate input bit             |
29EA    20 F3       JR      NZ,29DF     ; Not the expected level?   ----+
29EC    AF          XOR     A           ;   Reset time counter          |
29ED    ED 4F       LD      R,A         ;   Reset register              |
29EF    CB 0D       RRC     L           ; Edge flag for next edge       |
29F1    37          SCF     A           ; CY=1 for no error             |
29F2    C9          RET                                                 |
;Error Handling                                                         |
29F3    AF          XOR                 ;   Reset time counter      <---+
29F4    ED 4F       LD      R,A         ;   Reset register
29F6    3C          INC     A           ; Error number = 1, CY=0
29F7    C9          RET              

;********************************** Output byte
                                    ; IN : A: Byte
                                    ; OUT: CY=0 for error; A: Error number

29F8    D5          PUSH    DE 
29F9    1E 08       LD      E,08        ; Counter for 8 Bits
29FB    57          LD      D,A         ; Byte
29FC    CB 02       RLC     D           ; Next bit
29FE    CD 08 2A    CALL    2A08        ; Write to tape
2A01    30 03       JR      NC,2A06     ; Error?
2A03    1D          DEC     E           ; Bit counter
2A04    20 F6       JR      NZ,29FC     ; More bits?
2A06    D1          POP     DE 
2A07    C9          RET                

;********************************** Write bit to tape
                                    ; IN : CY: Bit
                                    ; OUT: CY=0 for error; A: Error number.

2A08    ED 4B D0 B8 LD      BC,(B8D0)   ; Previous time value/correction value
2A0C    2A D2 B8    LD      HL,(B8D2)   ; Main time value to L
2A0F    9F          SBC     A           ; A=$FF if 1-bit
2A10    67          LD      H,A         ; Save for check-word
2A11    28 07       JR      Z,2A1A      ; Bit=0?
2A13    7D          LD      A,L         ; Otherwise, main time value
2A14    87          ADD     A           ; *2 as 1-bit is twice as long
2A15    80          ADD     B           ; Add correction value
2A16    6F          LD      L,A         ; As time value
2A17    79          LD      A,C         ; Time value of the previous bit
2A18    90          SUB     B           ; Subtract correction value
2A19    4F          LD      C,A         ; Reset
2A1A    7D          LD      A,L         ; New time value
2A1B    32 D0 B8    LD      (B8D0),A    ; Save for the next bit
2A1E    2E 0A       LD      L,0A        ; Port C b5 (WR DATA) cleared
2A20    CD 37 2A    CALL    2A37        ; Delay and output
2A23    38 06       JR      C,2A2B      ; No error?
2A25    91          SUB     C           ; Error time-original time value
2A26    30 0C       JR      NC,2A34     ; Error time too large?
2A28    2F          CPL                 ; Original time value-error time
2A29    3C          INC     A           ; (Magnitude of the difference)
2A2A    4F          LD      C,A         ; Set as new time value
2A2B    7C          LD      A,H         ; Flag for 0/1-bit
2A2C    CD 90 29    CALL    2990        ; Set check-word according to bit
2A2F    2E 0B       LD      L,0B        ; Port C b5 (WR DATA) set
2A31    CD 37 2A    CALL    2A37        ; Delay and output
2A34    3E 01       LD      A,01        ; Error number for "Write error a"
2A36    C9          RET                

;********************************** Output next half wave
                                    ; IN : L=$0A for negative edge
                                    ;      L=$0B for positive edge
                                    ;      C: Time value

2A37    ED 5F       LD      A,R         ; Divide refresh counter by 2
2A39    CB 3F       SRL     A           ; Subtract desired time value since the last half-wave
2A3B    91          SUB     C           ; Has the time already elapsed?
2A3C    30 03       JR      NC,2A41     ; If not, remaining time
2A3E    3C          INC     A           ; Otherwise, remaining time
2A3F    20 FD       JR      NZ,2A3E     ; Delay
2A41    06 F7       LD      B,F7        ; PIO, Control register
2A43    ED 69       OUT     (C),L       ; Set/clear Port C/b5
2A45    F5          PUSH    AF          ; Error flag
2A46    AF          XOR     A           ; Reset time counter
2A47    ED 4F       LD      R,A         ; Reset register
2A49    F1          POP     AF          ; Error flags
2A4A    C9          RET                

Okay, I checked a very good german fully commented ROM listing for the CPCs. The addresses are different (because they do the full comment on the 464 and only comment on differences for the other two models), but that is the exact same function.

So this is the tape read and write routines and R is used as a counter for correct timing. 

This is only possible because the CPC never uses anything the R register contains, so they can use it as a counter.

So they set it to 0 (reset operation as in 29ED) and then use it as a counter.

The only thing they need to achieve is, that both edges are the same time. So they use R to have a counter. As they are running the same code, it will have the same time IF the signal from tape is correct. 

How does it work:
The start to wait for an edge (which is a change of signal).
Then they reset the timer
Then they wait for the next edge and store the time (LD A,R)
Then they reset the time
Then they wait for the next edge. 

This is one bit. And the edge timer is pretty much constant during that operation, however each bit sets the timings new. So the duration of a high and low flank is recorded.

That is important, as a high bit only takes half the time of a low bit. (the Pulse frequency is exactly 2x for high to low).
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: rpalmer on 22:55, 15 March 24
It would appear they are using the R register as a timing control. This makes sense as it is normally unaffected by anything external to the Z80, also the 1/300th interrupt is seen as insufficient for timing to be used for speedy bit transfers.
Think about that as at 1/300th interrupt only allows for 300 bits/sec where as using the R register could get a far high bit rate.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: McArti0 on 00:50, 16 March 24
except that R doesn't tick tok evenly. 
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: andycadley on 00:52, 16 March 24
Quote from: McArti0 on 00:50, 16 March 24except that R doesn't tick tok evenly.
No, but it does tick predictably, especially if interrupts are disabled (as I assume they would be while tape loading). If you know what instructions are executing, R is a viable timing mechanism for something like this.
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 14:03, 16 March 24
Quote from: McArti0 on 00:50, 16 March 24except that R doesn't tick tok evenly.
That is true, but does not matter in this particular example, as a tick is running the code segment and a tock is running the same code segment again. So this is both the exact same commands in exact same order, so the time of both code segments will be the same.

But R is not good as a universal timer. You either need to count cycles and then ensure that both are the same with the same number of M1 cycles, or as in here, have the exact same code run again.

The more I read the ROM comment, the more I am impressed on what those guys have achieved.

Is it actually known how has written the ROM?
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: Bread80 on 12:51, 17 March 24
This article on The Register gives a lot of detail about all aspects of development.

https://www.theregister.com/2014/02/12/archaeologic_amstrad_cpc_464/
Title: Re: Does CPC use the R-efresh Z80A register?
Post by: SerErris on 00:49, 02 April 24
Quote from: Bread80 on 12:51, 17 March 24This article on The Register gives a lot of detail about all aspects of development.

https://www.theregister.com/2014/02/12/archaeologic_amstrad_cpc_464/
Thank you for this interesting article. It slipped on my by now.

I am thinking of archiving it to archive.org. Reaching out to the register
Powered by SMFPacks Menu Editor Mod