Hi everyone.
This is probably the last thing I can try to make Chunky Pixel Curator a bit faster.
It's already running at a very nice speed, but... you know... there's gotta be more that can be done!
Does anyone know if it is possible to figure out which raster line the screen refresh is up to at any time?
If it is possible, how would I go about doing it?
Thanks for any help.
There is one relative simple thing which can give you a bit of help.
You can check which interrupt (0, 1, 2, 3, 4 or 5) was the last one, this gives you an idea where the beam is, actually this is 1/6 precise only, but will help already.
How I do it?
- When an interrupt occurs I check for frame fly back, (one simple IN command) and in case the frame flies back the interrupt counter (some variable you put somewhere in your program) get's set to "0".
All other interrupts increase the interrupt counter by one, so it can be between 0 and 5.
On Plus and with PlayCity there are other possibilities though.
Thanks TFM.
That is indeed very very useful!
I'll try to figure out how to do it...
Too hard... I can't figure it out. :'(
I've been researching Z80 interrupts on several forums (but mostly CPC stuff of course).
I thought I'd have some luck with the interrupts article written by NoRecess some time ago, but I can't even get that working.
Ultimately I want to avoid the need to wait for vsync, as that is adding a small overhead to the running of my program.
But of course, I need a way to stop flickering... it's all too hard!!!
Just wondering which bit you're getting stuck on...?
Quote from: ervin on 14:15, 19 December 14
Ultimately I want to avoid the need to wait for vsync, as that is adding a small overhead to the running of my program.
You don't have to wait for vsync, just check it when an interrupt appears. I search some code....
Here we go:
ORG &8000 ;Example
;In this example the interrupt must jump to INEN
;You can assemble "JP INEN" to address &0038
;Interrupt management entry!
INEN PUSH AF:PUSH BC:PUSH DE:PUSH HL ;save registers!
LD B,&F5:IN A,(C):RRCA ;Check if VSYNC just happens!
LD A,(AKTINT) ;Aktueller/current Interrupt 0-5
JR NC,NOFRA ;No FRAME! (= No VSYNC)
INT0 ... ;Interrupt 0 (beginning of picture) routine here!
JR EXINT ;Jump to EXit INTerrupt routine!
;No FRAME
NOFRA INC A:LD (AKTINT),A ;Increase inerrupt number by 1
ADD A,A:LD L,A:LD H,INTBAS/256 ;L = Interrupt number (1-5) * 2 ; H = Highbyte Table of ponters to interrupt routines
LD A,(HL):INC L:LD H,(HL):LD L,A ;HL = Pointer to INTerrupt 1-5 routine
JP (HL) ;call interrupt 1-5 (see before)
;sub programs for interrupts 1-5
INT1 ...
JR EXINT
INT2 ...
JR EXINT
INT3 ...
JR EXINT
INT4 ...
JR EXINT
INT5 ...
;EXit the INTerrupt, restore registers!
EXINT POP HL:POP DE:POP BC:POP AF:EI:RETI ;Ende des Interrupts
INT6 XOR A,A:LD (AKTINT),A:JR EXINT ;One Interrupt too much!!!
DS $/256*256+256-$ ;Fill memory up to next page start (1-255 bytes)
;Because INTBAS has to be at the beginning of a page!!!
;---=== Variables ===---;
INTBAS DW INT0,INT1,INT2,INT3,INT4,INT5,INT6 ;Pointer to raster interrupt 1-5
AKTINT DB &00 ;Actual/current Interrupt 0-5
LIST
DUMP
Quote from: ervin on 23:28, 17 December 14
Does anyone know if it is possible to figure out which raster line the screen refresh is up to at any time?
If it is possible, how would I go about doing it?
Not really an answer to your question, but this reminds me about the special registers 16 and 17 of the CRTC. I read years ago that their content represents an address.
Since these are labelled "light pen" I suppose they are only useful when a light pen is in use...
CRTC - CPCWiki (http://www.cpcwiki.eu/index.php/CRTC#The_6845_Registers)
CPCRULEZ ★ CODING ★ wacci CPC : AZ of CPC Chips - Part. 1{UK} (http://cpcrulez.fr/coding_wacci_CRTC_part1.htm)
Has anyone experience about it ?
That's right. They represent the screen address when a lightpen gets hit by the scan line beam. Not of help here though. :)
Thanks so much for your help TFM. 8)
I'll try to figure it out.
Quote from: kelp7 on 15:15, 19 December 14
Just wondering which bit you're getting stuck on...?
Oops, sorry kelp7. I just realised I didn't reply to your question.
It was the concept of interrupts that I was finding confusing.
I've spent more time over the weekend reading about them, and they make more sense now.
I'm gonna have another go, but I think TFM's example is more appropriate, as NoRecess' code seems to rely on synchronising with vsync, and I'm trying to avoid having to wait for vsync.
One advice, if you want to know where exactly each interrupt comes in graphically speaking, you can use winape, there is a checkbox in the debug - registers menu that marks them as lines in the border. Take in account that there is one that you don't see.
Quote from: opqa on 03:47, 22 December 14
One advice, if you want to know where exactly each interrupt comes in graphically speaking, you can use winape, there is a checkbox in the debug - registers menu that marks them as lines in the border. Take in account that there is one that you don't see.
Thanks opqa - I'd forgotten about that.
It's useful for planning stuff.
Luckily, I've figured out how to write an interrupt handler!
8)
Unfortunately, I can't rely on the interrupts being fired 300 times per second, as my program disables/enables interrupts a number of times in the main loop. This means that I can't keep an accurate count of which of the 6 interrupts the screen refresh is up to. :(
Consequently, it seems that I'm left with waiting for vsync at the start of each frame.
Ah well, it's not too much of a speed hit, so I'll just live with it.
Thanks everyone for your help.
This has been a really interesting topic, and I finally understand how interrupts work after all these years.
Ok, take a PlayCity and with its NMI feature you can do everything about the beam. :) :) :)
Quote from: ervin on 04:40, 22 December 14
Unfortunately, I can't rely on the interrupts being fired 300 times per second, as my program disables/enables interrupts a number of times in the main loop. This means that I can't keep an accurate count of which of the 6 interrupts the screen refresh is up to. :(
Ralferoo has explained some subtle things on https://github.com/ralferoo/breaking-baud/blob/master/docs/technical.txt (https://github.com/ralferoo/breaking-baud/blob/master/docs/technical.txt) .
QuoteWe rely on the fact that once the interrupt is raised, even if interrupts are
disabled at the time, as long as we handle the interrupt within 32 video lines
everything will behave normally. An interrupt can therefore be processed like
this:
This was demoed in "Breaking Baud" this year (an amazing piece of work) and may be of interest to your need.
Thanks for that! I'll give it a good look when I get back from holidays!