Copper

Discuss ZX Spectrum Next Games, Tools and more.
User avatar
Maziac
Posts: 42
Joined: Sun Jul 09, 2017 5:56 am

Copper

Postby Maziac » Tue Oct 23, 2018 5:18 pm

Hi all,
I have a few questions regarding the Copper implementation.

Writing the index to the "Copper control bytes": is this the index at which the program should start or is it the index for the next write to the "Copper data" register?

If I write more than 2k data (1k instructions) to the "Copper data" register what happens?
Is it simply wrapped, i.e. are the next bytes written to position 0 of the copper program memory?

Is there any way to read the current position of the Copper's "program counter" i.e. at which line it is currently waiting.

With what clock is the copper working? I.e. what time does it take to proceed from one opcode to the next one.

I have read in the forum that it is possible to write to the Copper program while it is running.
Some kind of dual port behaviour. Is it true?. When exactly is the new list taken over.

And the last one:
Is it possible to fill the Copper program memory via DMA?

Alcoholics Anonymous
Posts: 390
Joined: Mon May 29, 2017 7:00 pm

Re: Copper

Postby Alcoholics Anonymous » Wed Oct 24, 2018 3:33 am

Maziac wrote:
Tue Oct 23, 2018 5:18 pm
Writing the index to the "Copper control bytes": is this the index at which the program should start or is it the index for the next write to the "Copper data" register?
That is the write address into the 2k copper memory for the z80 and note it is a byte address. The copper's internal instruction pointer is not accessible to the z80.
If I write more than 2k data (1k instructions) to the "Copper data" register what happens?
The address wraps around.
Is there any way to read the current position of the Copper's "program counter" i.e. at which line it is currently waiting.
No but you can know where the display line is by reading the raster position. The copper will be following the display because its instructions wait on specific lines and horizontal position. If the copper is waiting on line 200, position 0, then you can read the raster line and know where it is in the copper program if the raster line is at 200 or nearly at 200.

You also know when a ula interrupt occurs what line the display is on (and therefore you will know where the copper is in its program too). You can change the line where interrupt occurs if that is more convenient.
With what clock is the copper working? I.e. what time does it take to proceed from one opcode to the next one.
It's operating at a multiple of the cpu clock that is connected to the display generation. One copper instruction takes the same time as one 256-wide pixel sent to the display. There is a copper nop instruction (write 0 to register 0) that is actually half a 256 pixel (or one 512 pixel) in duration.
I have read in the forum that it is possible to write to the Copper program while it is running.
Some kind of dual port behaviour. Is it true?. When exactly is the new list taken over.
Yes you can write into the copper memory while the copper is running and the change is immediate. However each copper instruction is 2 bytes in length and the z80 can only write one byte at a time so if the copper happens to be waiting at a certain point, the z80 can only change half the copper instruction there so I don't know if that is going to be useful or not. So far that is not how the copper has been used.
Is it possible to fill the Copper program memory via DMA?
Yes. The interaction between the DMA and copper is the same as between the CPU and copper. The DMA replaces the CPU in the system when it is active.

People have been operating the copper in LOOP mode and using the DMA to fill the half of the copper program already passed so that the DMA keeps filling the copper instruction area with new instructions. This is how copper audio works, eg.

I think the TBBLUE register page is misleading on the copper mode bits. The description in z88dk is accurate:
https://github.com/z88dk/z88dk/blob/mas ... per.m4#L76

This page is a "light" version of the copper documentation. Because the video display characteristics change with video timing (hdmi versus vga 0, 1, 2, ...) there are some subtleties in how wide the display is and how many lines are in the display. The gory details were documented by Kev Brady and can be found in the tbblue repository: https://gitlab.com/thesmog358/tbblue/bl ... -v0.1c.TXT . But most of the time you don't need to know so much detail; if you are doing copper audio and want it to work on everyone's system then you might need to know it. And you should never put in a wait that won't occur on all video timings.

User avatar
Maziac
Posts: 42
Joined: Sun Jul 09, 2017 5:56 am

Re: Copper

Postby Maziac » Wed Oct 24, 2018 3:34 pm

Many thanks for the comprehensive answer.

What is the supposed way to read the current raster line?

There are 2 bytes for high and low byte at register 30 and 31.
I.e. it has to be read one byte at a time.
If the raster line changes just in between the 2 byte accesses the result would be completely wrong.

Is there a way around this or do I have to read the values in a loop until they don't change anymore ....

Ped7g
Posts: 12
Joined: Mon Jul 16, 2018 7:11 pm

Re: Copper

Postby Ped7g » Wed Oct 24, 2018 5:28 pm

I would read low byte and then high byte. In case it will flip between from FF->100, you will end with scanline 511, i.e. way beyond maximum possible value (and you can safely patch it back to 0x100 without further read, or you may loop once). As long as resulting value is within correct range, it should be almost actual (or one line behind if you did read it just on the edge).

EDIT2: somehow I completely ignored the fact, that it also goes the other way, from like 0x138 to 0x000, where you would end with value 0x038, but I'm so used to have VBL IRQ at the beginning of screen, that I automatically ignored that case as "I will never wait at that moment in a loop checking scanline".. So yeah, your original suggestion of reading in loop until it doesn't move is more correct.

Now reading the wiki page http://devnext.referata.com/wiki/Board_feature_control - there are "7 LSBs" mentioned, not 8? Must be a typo I guess? Doesn't make sense to me to split the value 1:7, when you need 9 bits to cover scanline range any way. Also the raster line interrupt is described as "7 LSBs".. weird.

EDIT: oh wait, it's raster line vs active video line... er... no.. it's like there are all ports twice, i.e. $1E and $30 like decimal wrongly shown as hexa, with two slightly different descriptions... seems that wiki page needs quite some pruning and fixing...

User avatar
mitja_i
Posts: 200
Joined: Tue May 30, 2017 6:27 am
Location: Ljubljana, Slovenia
Contact:

Re: Copper

Postby mitja_i » Thu Oct 25, 2018 9:08 am

Yes, the wiki is not updated with recent info.
Backer 423 @ 37% funded 29 days left
---
ZX Spectrum Next glossary

Alcoholics Anonymous
Posts: 390
Joined: Mon May 29, 2017 7:00 pm

Re: Copper

Postby Alcoholics Anonymous » Sun Nov 04, 2018 7:32 am

Maziac wrote:
Wed Oct 24, 2018 3:34 pm
There are 2 bytes for high and low byte at register 30 and 31.
I.e. it has to be read one byte at a time.
If the raster line changes just in between the 2 byte accesses the result would be completely wrong.

What is the supposed way to read the current raster line?
As you suspect, carefully :)

I think you can avoid reading two times if you read in a suitable order. If the line you're looking for is < 256 then reading the LSB for a match and then checking if the MSB=0 would probably work.


Who is online

Users browsing this forum: No registered users and 2 guests