News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_ervin

CRTC question

Started by ervin, 14:36, 22 March 11

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

ervin

Hi all.

In the Chunky Pixel Collision thread, phi2x mentioned the info (bolded) below.
Can anyone point me in the right direction for how I might go about doing something like this?
Thanks in advance!

It is also possible to do the rasterline height stretching by hardware   instead of using the z80. That would give you tremendous speedup.You   should check the CPC demo called "Overflow's Backtro". The technique   used there is based on the following CRTC trick: if R1 has a higher   value than R0 then the CRTC video repeats the same line again and again.Don't   know how practical it would be for a game though. That technique needs   precise synchronizing of your code with the CRTC, switching R1 value   every four rasterlines.


arnoldemu

#1
Quote from: ervin on 14:36, 22 March 11
Hi all.

In the Chunky Pixel Collision thread, phi2x mentioned the info (bolded) below.
Can anyone point me in the right direction for how I might go about doing something like this?
Thanks in advance!

It is also possible to do the rasterline height stretching by hardware   instead of using the z80. That would give you tremendous speedup.You   should check the CPC demo called "Overflow's Backtro". The technique   used there is based on the following CRTC trick: if R1 has a higher   value than R0 then the CRTC video repeats the same line again and again.Don't   know how practical it would be for a game though. That technique needs   precise synchronizing of your code with the CRTC, switching R1 value   every four rasterlines.



try this in basic to get an idea of what the effect is:

OUT &BC00,0:OUT &BD00,63
OUT &BC00,1:OUT &BD00,65

you will see the same char line repeated.

So, I think the effect is then extended to:

OUT &BC00,9:OUT &BD00,0

Where the height of each char is now a scanline.
But now you really need to go to asm to do the effect correctly.

Now you need to be careful with your cycles, and setup r1 so you toggle between a value which will cause it to repeat (R1>R0) or a value which is smaller which causes it to update.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

ervin

Fantastic! I'll give it a go.
Thanks for your help.

arnoldemu

Quote from: ervin on 15:14, 22 March 11
Fantastic! I'll give it a go.
Thanks for your help.
Your welcome.

If you need some asm code to do the scanline version, I'll see what I can find.
I know I made some code that did this a while ago.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

ervin

I certainly wouldn't say no to such an offer!
If you are able to find it, I'd love to have a look at the code.

Thanks again.

Optimus

This is intresting to me also.
But I don't know why this didn't work for me.


OUT &BC00,0:OUT &BD00,3
OUT &BC00,1:OUT &BD00,65


At least in basic and in winape32. I get a black screen :(


What's wrong? Maybe wrong value? I'll have to check some CRTC docs again to understand further these techniques..

Optimus

#6
My mistake. I was trying this on Winape32 with it's default CPC+ configuration.
In pure CPC6128 it works :)


Update: Not my mistake I guess. I have opened a pure CPC6128 emulator and typed the code from this forum again and I have now seen 3 was edited to be 63 just in time :)


My thoughts: So, does this mean that the yline scaling doesn't need any special splitting? Just carefull syncing and changing these two values per line? Damn,. it seems easier than I thought. I might try..

arnoldemu

Quote from: Optimus on 16:08, 22 March 11
This is intresting to me also.
But I don't know why this didn't work for me.


OUT &BC00,0:OUT &BD00,3
OUT &BC00,1:OUT &BD00,65


At least in basic and in winape32. I get a black screen :(


What's wrong? Maybe wrong value? I'll have to check some CRTC docs again to understand further these techniques..
sorry. My mistake it should have been 63 not 3.

Ok I'll try to explain.

R0 is the total number of chars for each line.
a char is 2 bytes.
R2 is the position at which the horizontal sync should occur, normally set to 46.
So with my previous values, horizontal sync never occured, and the monitor couldn't display it.
R1 is the displayed number.

Inside the crtc there is a horizontal char counter.
It's incremented each cycle (1Mhz).
When it reaches R2 value, the hsync begins. It then lasts for the length programmed into R3 (lower 4-bits).
When it reaches R0, the line ends and it starts again from zero.
When it reaches R1, this is when the border begins, but also 2 things can happen.
I'll come back to this.

Also inside the crtc is a "raster counter". It increments each time the horizontal counter reaches R0.
And goes up to the value defined in R9. (But, worth noting is that not all it's outputs come to the CPC video hardware, so you see lines repeating).

So for the repeating effect, the counter never reaches R1, the border never begins and the line repeats.

Internal inside the CRTC is a char address (output as MA from the chip).
This char counter is reloaded and lines repeat.

If horizontal counter reaches R1, and raster counter = R9, then R1 is added on to the char address and the next char line begins.

This is the general horizonal mechanism.

The vertical one, counts the number of these char lines, matches against R7 in a similar way, R6 for the border and resets when it gets to R4.

There is more to it with R5 comming into play, but these don't effect what we have seen.

So the effect we see is that the horizontal counter never reaches R1 (it reaches R0 before R1, and resets back to zero), char address resets and lines repeat.

Really the crtc is a load of counters and compares.

Finally the MA and RA outputs from the crtc are used to generate an address which the gate-array reads. it then processes it depending on the mode.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

Phi2x

#8
.

Optimus

#9

Update: I have used R2 and R3 to center my small 64byte width screens in my past demos. Sometimes I was using stuff from the CRTC without knowing their true meaning. Now I guess that in the scheme of grim, the real left side of the screen in the CPC monitor is starting when the HSYNC exits and after the vsync exits the grey area is the upper side of the border again. I think that's it. I am still wondering what the effect of shortening the sync width would be though..


---

Thank you both. With some carefull read of arnolds explanation and the scheme at grims site I think I figured out more of how the regs work together to provide a cpc screen setup. I also understood now how this char/line repeating happens. But I have some questions.


What is safe? For example, R2 and R3 will move and scale the HSYNC. If I move the HSYNC but still stay inside the grey area (the border as depicted in grim's scheme) will it be ok? Vsync will still happen I guess but a bit earlier or later. If I change with R3 the width of the vsync and make it very thin (2-3 chars let's say) will it proove problematic?


What happens if some values go too big? If R1 goes 65 in our example the char repeating happens but now I have a width of 130 bytes I think. Or is there a limit? But if I have a very short graphics I want to repeat with a size of say 80bytes and so I keep R1 at 40 and make R0 38 then would it be wrong?


Right now, as I understand it should be safer to play with R1 or R6 as long as you are within the limits but the regs which control h or v sync or the R0 and R4 for the total could be tricky? At least I know R4 is used for screen splitting. But maybe R0 shouldn't be moved?


Ok, these are my guesses. What do you say about some of these questions? I think I'll have to play with these things a bit to see what is allowed and what is not or read some old discussions where people tried to explain some tricks with the CRTC then and I couldn't get it. Maybe I will now.

Phi2x

#10
.

Optimus

My mistake, I wanted to say R2 and R7 (I haven't touched R3) for moving the screen window.
But this is what I wanted to hear, what is considered bad idea to touch.

ervin

#12
Wow... this is all going right over my head.
I've gone through Grim's CRTC page, and I've got no idea what it's on about.  :(
I've been through the posts in this thread and I'm equally confused.

What I want to do sounds fairly simple, but I don't know if I'll be able to figure it out.
For my Chunky Pixel Collision game, it would be excellent to do this for each "chunky scanline":
- draw a real scanline
- repeat it 3 more times

So I get 4 real scanlines for the price of one, effectively.
It sounds like it is something that is possible using CRTC R0 and R1, but I just don't get it...

For a start, I don't know how to synchronise code with the CRTC.
Can anyone help?  :-[

Executioner

Quote from: ervin on 23:52, 22 March 11
What I want to do sounds fairly simple, but I don't know if I'll be able to figure it out.
For my Chunky Pixel Collision game, it would be excellent to do this for each "chunky scanline":
- draw a real scanline
- repeat it 3 more times

This is possible using a combination of register 1 and setting register 9 to 0 (Register 0 should always be 63). There are a number of problems here:

1. You mess up the vertical scan line count, so you'll have to work it out so you make up the lost character/scan lines at the end of the frame.

2. You need to be synchronised with the CRTC. This is easy enough (see below), but you need to stay synchronised with it so you can change register 1 back to it's original value before the horizontal display count is reached on every 4th line, and get it to move onto the next character line, rather than repeating the same scan line for 200 lines. In doing this on a standard CPC, you can't generate interrupts every 4 scan lines, so unless you can have the Z80 busy doing something that always takes a consistent number of cycles between each 4 lines then you'll lose almost height * 64 microseconds or so per frame (ie. 200 * 64 = 12800) or over half your normal processing time.

Quote
For a start, I don't know how to synchronise code with the CRTC.

Yes, that bit is easy: either write your routine as an interrupt routine and count the interrupts from the frame flyback, or wait for the frame flyback and use HALT instructions to get synchronised.

...


for the interrupt version (will call doscans at the start of the frame):


push af
push bc
ld b,#f5
in a,(c)
rra
.intno equ $+1
ld a,0
inc a
jr nc,notffb
xor a
.notffb
ld (intno),a
.notffb
cp 2
call z,doscans
pop hl
pop bc
pop af
ei
ret


And for the HALT version, (you should have a very simple interrupt routine or ei:ret at #38.


di
ld b,#f5
.waitffb
in a,(c)
rra
jr nc,waitffb
ei
halt
halt  ; Now we're synchronised


Cheers,
Richard

ervin

Wow - that's brilliant information!
Thanks Richard.

I'll see if I can figure it out!

FatAgnus

#15
Fast question about R3: which values are "less incompatible" for half char shift, &85-&86 or &f5-&f6?
Some people says "keep unused Vsync-related bits high, &F0", another says "keep Vsync-related bits as default &80"


I'm using &f5-&f6 and the game was tested by friends over CPC464 and CPC6128+ without reporting any problem, but I'm not very sure about the best pair.


Thanks in advance.

PS How many posts are needed if I want to "fix" that "annoying bug" of SPECCY RANK??!!!

arnoldemu

Quote from: FatAgnus on 10:19, 30 March 11
Fast question about R3: which values are "less incompatible" for half char shift, &85-&86 or &f5-&f6?
Some people says "keep unused Vsync-related bits high, &F0", another says "keep Vsync-related bits as default &80"


I'm using &f5-&f6 and the game was tested by friends over CPC464 and CPC6128+ without reporting any problem, but I'm not very sure about the best pair.


Thanks in advance.

PS How many posts are needed if I want to "fix" that "annoying bug" of SPECCY RANK??!!!
Both are fine. Some CRTCs have a fixed vsync anyway, but for the others this is ok.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

matahari

Hi,

I'm following this thread for a few days, and I would like to thank for the great info! I love CRTC bending ;-)

With regards to ervin's initial question and following replies, I am trying to create a similar case; but this time a screen with only 1 pixel height. So, I wrote down the following piece of code for a test drive. It seems I've managed to set the display with 1 pix height, but unfortunately it's out of sync!!! Any recommendations?

Kind Regards,
matahari

;------ 1 pix scrheight test ------

org &3000
run &3000

ld a,1
call &bc0e

;------ CRTC Setup -------------

ld bc,&bc00 + 0
out (c),c
ld bc,&bd00 + 63
out (c),c

ld bc,&bc00 + 1
out (c),c
ld bc,&bd00 + 65
out (c),c

ld bc,&bc00 + 4
out (c),c
ld bc,&bd00 + 1
out (c),c

ld bc,&bc00 + 7
out (c),c
ld bc,&bd00 + 1
out (c),c

ld bc,&bc00 + 9
out (c),c
ld bc,&bd00 + 0
out (c),c

di
im 1
ld hl,&c9fb
ld (&38),hl
ei

ld hl,&c000 + 40

;------- Main Loop ----------------

Loop:

ld bc,&f5
WaitVB: in a,(c)
rra
jr nc,WaitVB

REPEAT 50
ld (hl),&ff
defs 64-2
REND

REPEAT 50
ld (hl),&0f
defs 64-2
REND

jp Loop

arnoldemu

#18
Quote from: matahari on 13:37, 30 March 11
Hi,

I'm following this thread for a few days, and I would like to thank for the great info! I love CRTC bending ;-)

With regards to ervin's initial question and following replies, I am trying to create a similar case; but this time a screen with only 1 pixel height. So, I wrote down the following piece of code for a test drive. It seems I've managed to set the display with 1 pix height, but unfortunately it's out of sync!!! Any recommendations?

Kind Regards,
matahari

;------ 1 pix scrheight test ------

org &3000
run &3000

ld a,1
call &bc0e

;------ CRTC Setup -------------

ld bc,&bc00 + 0
out (c),c
ld bc,&bd00 + 63
out (c),c

ld bc,&bc00 + 1
out (c),c
ld bc,&bd00 + 65
out (c),c

ld bc,&bc00 + 4
out (c),c
ld bc,&bd00 + 1
out (c),c

ld bc,&bc00 + 7
out (c),c
ld bc,&bd00 + 1
out (c),c

ld bc,&bc00 + 9
out (c),c
ld bc,&bd00 + 0
out (c),c

di
im 1
ld hl,&c9fb
ld (&38),hl
ei

ld hl,&c000 + 40

;------- Main Loop ----------------

Loop:

ld bc,&f5
WaitVB: in a,(c)
rra
jr nc,WaitVB

REPEAT 50
ld (hl),&ff
defs 64-2
REND

REPEAT 50
ld (hl),&0f
defs 64-2
REND

jp Loop

it is better if you do this after your vsync wait:

ld bc,&bc07
out (c),c
ld bc,&bdff
out (c),c

to stop vsync being triggered, then something like this just before your jp:

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

but you also need to count 312 lines or so to ensure the effect is working correct before you restore vsync operation.

*but* this kind of thing needs to be tested on all crtcs to ensure you get the same response with all.

I think also you may need this:

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

I think you had 2 pixel lines height?

Also, you may actually need to set R9, R4 to some sensible values near the end to ensure it syncs up correct, but I can't remember without doing more testing.

so something more along these lines:


loop:
ld b,&f5
.l1 in a,(c)
rra
jr nc,l1

ld bc,&bc07
out (c),c
ld bc,&bdff
out (c),c

ld bc,&bc04
out (c),c
ld bc,&bc00
out (c),c

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


halt

halt

halt

halt

halt

halt

;; possibly here you may need this:

ld bc,&bc04
out (c),c
ld bc,&bd00+8       ;; <- this value needs tweaking
out (c),c

ld bc,&bc09
out (c),c
ld bc,&bd00+7
out (c),c


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

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

matahari

Dear arnoldemu,

Thanks for the FAST reply!

According to your recommendations, I am working on it.
Still not able to sync it, but keeping fingers crossed...

Yes, definitely needs to be tested on various CRTCs.

Regards,
matahari

matahari

Done   :)

In addition to arnoldemu's recommendations, I had to tweak more (and simplify) to make it work.
Not tested on real a CPC, yet! I'll try that tonight.

Posting the final code...

Kind Regards,
matahari

;------ 1 pix scrheight test ------

org &3000
run &3000

ld a,1
call &bc0e

;------ CRTC Setup ----------------

ld bc,&bc00 + 0
out (c),c
ld bc,&bd00 + 63
out (c),c

ld bc,&bc00 + 1
out (c),c
ld bc,&bd00 + 65
out (c),c

ld bc,&bc00 + 4
out (c),c
ld bc,&bd00 + 0
out (c),c
   
di
im 1
ld hl,&c9fb
ld (&38),hl

;------ Destination ScrAddr -------

ld hl,&c000 + 40

;------ Main Loop -----------------

Loop:
ld bc,&f5
WaitVB: in a,(c)
rra
jr nc,WaitVB
ei

ld bc,&bc00 + 7
out (c),c
ld bc,&bd00 + 255
out (c),c

ld bc,&bc00 + 9
out (c),c
ld bc,&bd00 + 0
out (c),c

ld (hl),&ff
halt
halt
halt

ld (hl),&0f
halt
halt
halt

ld bc,&bc00 + 9
out (c),c
ld bc,&bd00 + 8
out (c),c

ld bc,&bc00 + 7
out (c),c
ld bc,&bd00 + 0
out (c),c

jp Loop

ervin

Alrighty... this is driving me nuts.
After much head scratching and brain aching, I just can't get my head around how to do this.

I can't think of a reasonable algorithm to include these CRTC tricks in a real-time game.
Especially one where so much of the code is performed with interrupts turned off.

I'll just have to do leave my fat pixels in software.
Luckily it is all working pretty quickly, so I'm happy to go this way.

Powered by SMFPacks Menu Editor Mod