Mixing two different graphic modes

Hardware Hacking, Programming and Game Solutions/Cheats
pser1
Posts: 1655
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Mixing two different graphic modes

Post by pser1 »

Hello,

I know that a few of you have got to show in the screen a part in a PMODE and the rest in another resolution ...

I am interested in having the upper 3/4 of the screen devoted to PMODE3 or maybe SG24 (144 pixels high) and the rest (48 pixels high) for PMODE4
To make things easier, this proportion may be changed along the execution of the program.
The program will work at a slow speed, so no timing problems ... not an action game!

Could anyone give me any hint to program the routine that would control this PMODEs combination, if it is affordable, of course?

thanks a lot in advance
regards
pere
sorchard
Posts: 530
Joined: Sat Jun 07, 2014 9:43 pm
Location: Norwich UK

Re: Mixing two different graphic modes

Post by sorchard »

I haven't tried it on a real Dragon, but the attached example should give something like the effect you're after. (It works on xroar so it stands a chance)

It probably needs adjustment to split the screen in the exact place required.

It can be a bit of a pain to do any useful work at the same time as showing a split screen because the timing must be maintained. The higher up the screen the split is placed, the easier it is because you can do whatever you want between the split and the next vsync.

I remember there was a split screen program in Dragon User that was supposed to run at the same time as BASIC but it never worked for me. Perhaps it can be revisited and fixed...
Attachments
splits.zip
(756 Bytes) Downloaded 277 times
Stew
pser1
Posts: 1655
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Re: Mixing two different graphic modes

Post by pser1 »

thanks a lot, sorchard

you are right, having to wait for the interrupts with sync opcode will consume most of the cpu time
The only problem of this piece of code is that it never gets out of the loop, so anything else will be able to run ...
I have executed it from a Basic program that waits for a key, but it never gets control after executing the routine.

Maybe converting this into an interrupt routine could help a bit giving some time to the other program that will be running concurrecntly.

Your idea is very interesting, so if the IRQ-routine for HSYNC was short enough, just update counter and act when limit is reached much as a timer,
maybe it could live and let run another independent piece of code.

I will try to experiment with this

kind regards
pere
sorchard
Posts: 530
Joined: Sat Jun 07, 2014 9:43 pm
Location: Norwich UK

Re: Mixing two different graphic modes

Post by sorchard »

I enjoy a challenge so I had a quick go at implementing a split screen as an irq routine. It nearly works so I'll see if I can do better during my lunch break ;-)
Stew
pser1
Posts: 1655
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Re: Mixing two different graphic modes

Post by pser1 »

Hello,

I got to convert it into an IRQ-handler routine ... but it gets some flicker :cry:
I attach a zipped vdk image that contains the source in DRM format, the binary and a Basic test program
The test program loads the bin file, installs it and then pokes memory with $55 (upper half of the screen), so that in PMODE3 part
shows a yellow color and in PMODE4 results in alternate bars (b-w)
Pressing the "S" key after this, a white square is drawn in PMODE4 area
Again with "S" it paints a red rectangle in PMODE3 area
next "S" will uninstall the IRQ-hadler and go back to basic

If you press the Break key, the screen will show up garbled, but if you press:
EXEC&H4000 and enter, it will uninstall the routine and go back to std basic

How could I avoid the dreaded flickering?
Besides, there is an unstability in the PMODE3 to PMODE4 transition, it seems that the change is not produced
at the same horizontal line all of the times ... any idea?

thanks beforehand
regards
pere

Ps sorchard, your version has no flickering at all nor problems in the boundary from PMODE3 to PMODE4
but I don't know how to get the same result with an IRQ-handler ...
Attachments
10 - PMODE3-4.zip
(9.58 KiB) Downloaded 291 times
pser1
Posts: 1655
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Re: Mixing two different graphic modes

Post by pser1 »

Hello sorchard,

I posted my last message, but began to write it before you posted you own, so I hadn't read it.
I appreciate your help in this challenging problem!

cheers
pere
pser1
Posts: 1655
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Re: Mixing two different graphic modes

Post by pser1 »

keeping into account that the DRM source has no comments at all,
I copy here the commented PC file:

If anyone can help getting rid of the flickering / unstable boundary, any advice would be greatly appreciated.

Code: Select all

*
*  PMODE34 - test for two simultaneous graphic modes
*
         ORG      $4000
         put      $4000
*
itype		equ      $f7			* INTERRUPT ENABLED: 0=V - 1=H - $FF change to PMODE4
count    equ      $f8			* counter to change PMODE
*
instal   ORCC     #$50     	* Disable IRQ/FIRQ interrupts
         LDX      #ISR			* get new IRQ-dispatch routine			
         CMPX		$010D			* is it already installed?
         BEQ      UNINST		* uninstall it - disable control
*
ENABLE   CLR      <ITYPE     	* VSYNC ENABLED
       	STA   	$FFC0			* clear SAM V0
       	STA   	$FFC3			* set   SAM V1
       	STA   	$FFC5			* set   SAM V2
       	STA   	$FFC6			* start of graph memory = $0C00
       	STA   	$FFC9				*
       	STA   	$FFCB				*
       	STA   	$FFCC				*
       	STA   	$FFCE				*
       	STA   	$FFD0				*
       	STA   	$FFD2				*
		 	LDA      $FF03    	* enable Frame Sync Interrupt
         ORA      #$01				*
         STA      $FF03				*
         LDA      $FF01    	* Disable Horizontal Sync Interrupt
         ANDA     #$FE				*
         STA      $FF01				*
         BRA      CHGVEC		* change to the new IRQ-dispatcher into vector
*
UNINST   LDX      #$9D3D		* get std default value
         LDA      $FF01   		* disable Horizontal Sync Interrupt
         ANDA     #$FE				*
         STA      $FF01				*
         LDA      $FF03   		* enable Frame Sync Interrupt
         ORA      #$01				*
         STA      $FF03				*
*
CHGVEC   STX      $010D   		* set IRQ dispatch routine
         ANDCC    #$AF    		* enable IRQ/FIRQ interrupts
         RTS              		* return to caller
*
isr      orcc     #$50			* disable interrupts (avoids unwanted changes-flickering)
			tst      <itype		* which IRQ source is enabled?
			bmi      chghsy      * do the change to pmode4
			bne      hsync			* zero, so HSYNC
*
vsync		lda      $ff02			* clear VSYNC IRQ flag
			lda      $ff22       * get actual configuration
			anda     #$07			* save 3 lower bits
			adda     #$e0			* set PIA1 = 1110 0--- (colorset 0)
			sta      $ff22			* set PMODE3
         lda      $FF01   		* enable HSync Interrupt
         ora      #$01				*
         sta      $FF01				*
         lda		#100			* number of sync pulses to count
         sta      <count		* save counter
         inc      <itype      * flag for HSYNC
			bra      goout       * go out
*
hsync		lda      $FF00   		* clear HSYNC IRQ flag
			dec      <count		* decrement counter
			tst      <count		* reached zero?
			bne      goout			* no, go out
			neg		<itype		* next one will change PMODE (to reduce cycle count)
         bra      goout			* go out
*         
chghsy	lda      $FF00   		* clear HSYNC IRQ flag         
       	lda      $ff22       * get actual configuration 
       	anda     #$07        * save 3 lower bits
			adda     #$f8        * set PIA1 = 1111 1--- (colorset 1)
			sta      $ff22       * set PMODE4
         lda      $FF01   		* disable HSync Interrupt
         anda     #$fe				*
         sta      $FF01				*
         clr		<itype		* flag for VSYNC
goout    andcc    #$af			* enable interrupts
			rti						* it's faster ... but loses SOUND - PLAY compatibility
*goout    jmp      $9D3D   	* Jump to BASIC's Interrupt Service Routine (Update TIMER etc)
*
regards
pere
sorchard
Posts: 530
Joined: Sat Jun 07, 2014 9:43 pm
Location: Norwich UK

Re: Mixing two different graphic modes

Post by sorchard »

The main problem seems to be due to the fact that the sync signals can appear anywhere during execution of an instruction but the irq handler cannot begin until the instruction is finished.

This means that the screen position is different each time the irq is called. Some instructions are a lot longer than others so there is potential for a lot of variation i.e. enough to push the mode change to the next line. This causes the start line and the end line to jump up and down one position and if they move in opposite directions it makes for a very jittery display.

We can use the sync instruction to lock to the next hsync to get a consistent horizontal position but we also need to stabilise the vertical position by inserting just the right number of cycles to ensure that we always lock onto the same scanline.

It's fine tuning the delays that I'm struggling with at the moment.

This is what C64 demo coders refer to as getting a 'stable raster'. The 6502 doesn't have a sync instruction so no idea how they do it.

All good fun anyway ;)
Stew
pser1
Posts: 1655
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Re: Mixing two different graphic modes

Post by pser1 »

hello sorchard,

as I coudn't make it perform without great flickering and the boundary moving visibly, I have decided to send all files to my Dragon64 system (with drives).
Surprisingly things are much, much better on the real hardware.
Runing the test basic program, I have noticed just 1 flick while the program was inside the long loop pokeing memory cells.
But from that point on, it draws without problems and when it loops waiting for a key, the screen stays perfect, no boundary moves, no flickering at all :)

It is not the prefect solution, then there is a flick possibility if the 'other' program executes a long sentence (?)

If you could send the VDK to a real disk, I would appreciate if you could tell me how does it work in your equipment ...

cheers
pere

Ps I enclose last version of my assembler file
Attachments
PMODE34x commented.zip
(1.08 KiB) Downloaded 283 times
sorchard
Posts: 530
Joined: Sat Jun 07, 2014 9:43 pm
Location: Norwich UK

Re: Mixing two different graphic modes

Post by sorchard »

pser1 wrote:Surprisingly things are much, much better on the real hardware.
I've got to thank you. I would have probably spent a couple of evenings trying to get this to work in xroar. Instead it was just the push I needed to get my D64 out of the loft and fire it up. It still works... yay!

So the first thing the D64 did after 10 years in the dark was load Flagon Bird from my phone. I've got to say this game is awesome on the emulator and even better on the real thing! It's slightly easier to play on real hardware as well, but I'm not sure why. Anyway, I digress...

I then tried your latest split screen source code and yes, I can confirm it is considerably more stable on real hardware, almost perfect in fact. (Good job by the way. Hopefully it only needs a small adjustment to get this 100% perfect)

So it looks like irq latency is more variable on xroar than on real hardware. Perhaps it's possible to devise some tests to reveal where the differences are...
Stew
Post Reply