CPCWiki forum

General Category => Programming => Topic started by: Arnaud on 10:32, 26 January 21

Title: CRTC synchronization
Post by: Arnaud on 10:32, 26 January 21
Hi,
here a screenshot of my problem.
[attach=1,msg197295]

I want to change the Horizontal Displayed from 32 to 40 characters (and centered it) on interruption, i guess i have to make configuration the CRTC between HSYNC ON and HSYNC OFF but i am not sure.

Here my interrupt function, i added inline asm to make a synchro wait.

void sInterruptHandler(void){
static u8 sInterrupt = 0;
if (sInterrupt == 0)
{
cpct_setPALColour(0, 0x5C);
cpct_setCRTCReg(2, 42);
cpct_setCRTCReg(1, 32);
}
else if (sInterrupt == 4)
{
cpct_setPALColour(0, 0x57);
__asm
ld b,#15
0124$:
djnz 0124$
__endasm;
cpct_setCRTCReg(2, 46);
cpct_setCRTCReg(1, 40);

}
else if (sInterrupt == 5)
cpct_setPALColour(0, 0x5E);

if (++sInterrupt == 6)
sInterrupt = 0;
}


Thanks.
Title: Re: CRTC synchronization
Post by: roudoudou on 10:35, 26 January 21
goal: change the HSYNC position with register 2

requirement: 64us between every HSYNC
solution: make one CRTC line shorter or longer (register 0) than 64us to shift HSYNC position without changing 64us between 2 HSYNC


Title: Re: CRTC synchronization
Post by: Arnaud on 16:09, 26 January 21
Not too bad but not perfect  :D

[attach=1,msg197314]

I used inline assembly to go faster. I tried several value on wait loop the best is 72 Nop.

// SET R2 = 46 AND R1 = 40
if (sInterrupt == 4)
{
__asm
;; REG 0 = 59
ld   b, #0xBC 
ld   c, #00 
out (c), c 

ld   b, #0xBD
ld   c, #59    ;; = 63 - (42 - 46)
out (c), c

;; WAIT 68 NOP (72 NOP)
ld b, #18 ;; [2]
0125$:
djnz 0125$ ;; [4*18]

;; REG 0 = 63
ld   b, #0xBC
ld   c, #00 
out (c), c

ld   b,  #0xBD
ld   c, #63   
out (c), c

;; REG 2 = 46
ld   b, #0xBC 
ld   c, #02 
out (c), c 

ld   b, #0xBD
ld   c, #46   
out (c), c

;; REG 1 = 40
ld   b, #0xBC
ld   c, #01 
out (c), c 

ld   b, #0xBD
ld   c, #40   
out (c), c
__endasm;

cpct_setPALColour(0, 0x57);
}
// SET R2 = 42 AND R1 = 32
else if (sInterrupt == 0)
{
cpct_setCRTCReg(2, 42);
cpct_setCRTCReg(1, 32);
cpct_setPALColour(0, 0x5C);
}
Title: Re: CRTC synchronization
Post by: roudoudou on 16:22, 26 January 21
Quote from: Arnaud on 16:09, 26 January 21
Not too bad but not perfect  :D

you're changing the first register wayyy too late because of many many PUSH (i guess telera backups?)
then there is your waiting loop (way too long because 68 nops is the total, you must substract what you are doing so you skip an entire line before changing the other registers
as your first register 0 change is very close to the end of the line, you may wait only 16 nops
then you change register 2 and  register 0 again before the new line (register 1 also but that's not critical)


Title: Re: CRTC synchronization
Post by: Arnaud on 16:59, 26 January 21
Perfect !
[attach=1]

But i removed all PUSH from interruption backup.
Title: Re: CRTC synchronization
Post by: roudoudou on 17:08, 26 January 21
Quote from: Arnaud on 16:59, 26 January 21
Perfect !


But i removed all PUSH from interruption backup.
heeeeeeeeeeyyy, you must save at least what you are modifying in the interruption!
do you use an emulator which show you where you are on the display? (with a cross or something like this)
Title: Re: CRTC synchronization
Post by: Arnaud on 17:29, 26 January 21
Quote from: roudoudou on 17:08, 26 January 21
heeeeeeeeeeyyy, you must save at least what you are modifying in the interruption!
It was for testing  ;D

Quote from: roudoudou on 17:08, 26 January 21
do you use an emulator which show you where you are on the display? (with a cross or something like this)
I used Winape
Title: Re: CRTC synchronization
Post by: Arnaud on 17:52, 26 January 21
Finally it works with the PUSH, i found the right timing.
It takes one more line before changing color, but it's really OK and i think i can't do better in C.

[attach=1,msg197321]

Thanks for the help !

Edit : and it works on my real CPC+
Title: Re: CRTC synchronization
Post by: SpDizzy on 19:13, 26 January 21
Sorry, Arnaud

Did that last try worked also on your emulator? Not at home, so I couldn't test it on real hardware, but WinApe shows for me same problem as detailed on original post.

Maybe a problem on my side, or had you uploaded original error code or removed push instructions from safeInterruptHandlerHook ?

Had tried my own test (not perfect), which also upload.

PD: Do you plan on a HUD wider than the actual gameplay screen? Or just a test?
Title: Re: CRTC synchronization
Post by: Arnaud on 19:42, 26 January 21
Hi @SpDizzy (https://www.cpcwiki.eu/forum/index.php?action=profile;u=2740),
your code is OK here a screenshot.

[attach=1]

Quote from: SpDizzy on 19:13, 26 January 21PD: Do you plan on a HUD wider than the actual gameplay screen? Or just a test?
Yes i want to have a screen in 32 char in order to speed up drawing and keep 40 char for HUD for not have a whole tiny game screen.
Title: Re: CRTC synchronization
Post by: SpDizzy on 20:16, 26 January 21
Thanks so much for your response Arnaud,

Quote from: Arnaud on 19:42, 26 January 21Yes i want to have a screen in 32 char in order to speed up drawing and keep 40 char for HUD for not have a whole tiny game screen.
If I'm correct, you can make use of spare memory then, on that smaller screen area.
Had allways enjoyed your games, keep on the good work!  ;)
Title: Re: CRTC synchronization
Post by: Arnaud on 20:19, 26 January 21
Quote from: SpDizzy on 20:16, 26 January 21
If I'm correct, you can make use of spare memory then, on that smaller screen area.
Yes it takes less memory and it's faster to draw. But screen is really smaller.

Quote from: SpDizzy on 20:16, 26 January 21
Had allways enjoyed your games, keep on the good work!  ;)
Thanks !
Title: Re: CRTC synchronization
Post by: Ast on 20:58, 26 January 21

Here is what to do if you want to do it in asm :




;
; Code by Ast^iMPACT
;
   org #a000


;
   di
   ld hl,#c9fb ; kill int
   ld (#38),hl
   ei
;
   ld bc,#7F10
   ld a,#4c
   out (c),c
   out (c),a
;
main
   call vbl
;
   ld hl,#0120 ; #40 chars in screen 1
   call crtc
   ld hl,#022a ; Center 1st screen
   call crtc
   
;
   ld hl,#07ff ; kill vsync
   call crtc
;
   ld b,0 ; wait 32 lines
   djnz $
   djnz $
;
   ld hl,#0400+25-1 ; First screen height
   call crtc
   
;
   ei
   halt
   ld b,22*8 +4 ; wait some times before the second screen
bc0   defs 60,0
   djnz bc0


;
   ld hl,#0128 ; Set #50 chars for the second screen
   call crtc
;
   defs 16,0 ; resynchronize the screen
   ld hl,#003F-4
   call crtc
;
   ld hl,#022E
   call crtc
;
   ld hl,#003F
   call crtc
;
   ld hl,#0400+14-1
   call crtc
   ld hl,#0700+14-4
   call crtc
;
   jp main




;
;   h=reg | l=valeur
;
crtc   ld b,#bc
   out (c),h
   inc b
   out (c),l
   ret
;
vbl    ld b,#f5
   in a,(c)
   rra
   jr nc,vbl+2
   ret



Hope it would help some people.
Bye !
Title: Re: CRTC synchronization
Post by: roudoudou on 21:06, 26 January 21
Quote from: Ast on 20:58, 26 January 21
Here is what to do if you want to do it in asm :
is the blue line on the right of the screen ok?  :P
Title: Re: CRTC synchronization
Post by: Ast on 21:08, 26 January 21
Quote from: roudoudou on 21:06, 26 January 21
is the blue line on the right of the screen ok?  :P


yes! but bien vu  :-X
Title: Re: CRTC synchronization
Post by: funkheld on 23:13, 26 January 21

Perfect !

can you please insert the complete code for cpctelera here that works for the cpc6128?


greeting
Title: Re: CRTC synchronization
Post by: Ast on 23:44, 26 January 21

For Roudoudou with Loves (Of course!).

org #a000
;
;       Code by Ast^iMPACT
;
di
ld hl,#c9fb ; kill int
ld (#38),hl
ei
;
ld bc,#7F10
ld a,#4c
out (c),c
out (c),a
;
main
call vbl
;
ld hl,#0120 ; set 1st screen to #40 chars
call crtc
ld hl,#022a ; center first screen
call crtc

;
ld hl,#07ff ; kill vbl
call crtc
;
ld b,0
djnz $
djnz $
;
ld hl,#0400+25-1 ; 1st screen Height
call crtc

;
ei
halt
ld b,22*8 +2
bc0 defs 60,0
djnz bc0
;
defs 46,0 ; wait some times to fix what Roudoudou has seen.
;
ld bc,#bc3F-4
defw #71ed
inc b
out (c),c
;
ld hl,#022E ; center 2nd Screen
call crtc
;
ld hl,#003F
call crtc
;
ld hl,#0128 ; set 2nd screento #50 chars
call crtc
;
ld hl,#0400+14-1 ; set 2nd screen Height
call crtc
ld hl,#0700+14-4 ; set New vbl position
call crtc
;
jp main
;
; h=reg | l=valeur
;
crtc ld b,#bc
out (c),h
inc b
out (c),l
ret
;
vbl ld b,#f5
in a,(c)
rra
jr nc,vbl+2
ret
Title: Re: CRTC synchronization
Post by: megachur on 07:43, 27 January 21
Hello Ast,
I haven't tried this on real hardware  but this is what I got on my CPCEPower emulator...

I've done 2 sna for testing purpose with WinAPE before testing on my CPCEPower emulator :


on 6128, CRTC 0,1,2 seems to have HSYNC issue but not on crtc4 ?!

on 6128+, CRTC3 ok (seems as crtc4 ;-)) !

--> Real hardware test is may be needed to confirm this ?!
Title: Re: CRTC synchronization
Post by: roudoudou on 08:12, 27 January 21
i think this exercise needs some visuals explanations, maybe a stream next time  ;D
Quote from: megachur on 07:43, 27 January 21
Hello Ast,
I haven't tried this on real hardware  but this is what I got on my CPCEPower emulator...
Anyway, @Ast (https://www.cpcwiki.eu/forum/index.php?action=profile;u=573)  miss the point => he killed interrupts! We want this routine using INT !!!

Title: Re: CRTC synchronization
Post by: funkheld on 14:34, 27 January 21
CPCEPower emulator  is deficient.
so you can't do a test here.

see image (sprite from cpctelera)
other cpc emulators work without this error.

key : QWES

greeting
Powered by SMFPacks Menu Editor Mod