2^n Color News
#1
Posted 24 October 2004 - 12:27 PM
I wrote a new demo now, where some improovements have been made in color emulation method:
- using fast LCD refresh now; causes much less flickering than before (however, you can switch between fast and slow by SHIFT key)
- the default timer parameters have been adjusted better now (set t1..t6 to 0 to load them)
So 4 and 8 color modes work perfect now (on my calc at least), 16 colors are flickering unimprotant, but
EVEN 32 AND 64 COLORS DO NOT FLICKER MUCH MORE THAN 16 DO!!!
(You may, however, adjust the parameters for your calc by F1 and F2 keys; the adjustment steps are 16 times finer this time then in the last demo, so you should find a frequency that will match). Thus, you can view pictures very good even in 64 colors mode now.
Note, that you should not turn of the calc anymore to get the second test screen, but: Additionally, there are 4 test screens now, available with keys F3 through F6, where F3 and F4 are the ones you know already, F5 is another pattern, and
F6 shows a bitmap - it is the first 64 colors bitmap available for AFX allover!!! (should look like you see above; you also may view it in less than 64 color mode discarding some colors then)
It consits of the following 6 single layers:
I converted it manually, because I was not willingly to write a converter before knowing if it would work or not. But now I'm going to write one
On my AFX the image really works in 64 color mode, it's quite cool
Just try it and give me some feedback! (you find it also at http://www.pageofmarco.de/afx_eng.php3.
When you finish it by ESC, it puts out some timing data. If you find any timer setting by F1/F2 that looks better, it would be great if you could give me the timing data
---------
The next steps I'm going to do now are:
- to write an image converter that converts 2,4,8,16,32 and 64 color images (it?s not very comfortable to split the layers manually, however)
- to measure out the displays frequency, maybe even better timing parameters are achievable this way (Thank you, Deimos! I'll try it your way)
- I'll try to combine timing with interrupt 1C (1C initials a page flipping sequence, whereas the sequence itself is controlled by non interrupt timing; this way up to 50 cycles were possible per second, and the rest of the program doesn't need to carry about timing, having 2/3 of the CPU ressources left for own use in spite of)
One thing I?d not try yet is how emulation reacts on moving graphics, if colors are still stable then or not
#2
Posted 24 October 2004 - 12:38 PM
#3
Posted 24 October 2004 - 12:43 PM
#4
Posted 25 October 2004 - 04:50 AM
#5
Posted 25 October 2004 - 05:20 PM
Only 6 layers for 64 colors
but please, please, PLEASE cease this use of cfx ....
U loose too much time
Use f100 and gcomm, life will be better
Test
---------------------
Rom 1.03, it sux lol
Anyway, great effort on 8 colors, they're pretty nice, even flickering (all with automated timings), and 32/64 modes are quite impressive, even if quality isn't really nice
Keep on the good work, maybe I'll afford a rom 1.01 =)
---------------------
Hmmm after a few tests I got nice result with 16 colors at 36.1Hz frequency
Hope that'll help
#6
Posted 26 October 2004 - 03:46 PM
Btw, does your memzone lib create save buffers in the 144KB user space or in the programs mem? Additional space in the 144KB mem was quite cool...
@C@siomax: Yeah, I noticed already... I need about 3 minutes to upload Add Ins to my calc, but f100 and gcomm sadly don't work on my computer
But for the new demo I`ll also upload the EXE at least now.
Thx for the info, showing it should work with all calcs, but different settings (altough meanwhile I noticed giving me the frequency the program puts out has no use for, because it's calced too unexact; the new calibration tool will be better)
------------------------
I tried to find out now the display's frequency with Deimos' method, and got 155 Hz for slow - and 310 Hz for fast sweeping mode (hope that I interpreted the results correctly). But there was one really strange discovering I made:
If you use the same timing parameters in fast sweeping mode as in slow mode, timing cycles are about 6.3% longer then, altough nothing but the content of port 4 (e.g., displays frequency) has been changed then. Thus, if display is in fast sweeping mode, a programm has 6.3% less CPU ressources than it has in slow mode.
The only way I could explain this was, when the display had an IRQ that was called each time the display begins or ends with a refresh cycle (in fast sweeping mode the IRQ would be called more often than and thus leave less ressources left for the program). That would be great, because it would provide a way achieving perfect synchronisation with the display.
So I began scanning for interrupts that are frequently called (scanned all 255), but am not REALLY happy with my result. Amongst some interrupts around 78 (called on keystroke), I found only two that were called frequently: Interrupts 1C (the timer) and 53. Interrupt 53 is that what is mentioned to force an "update of the display" in Oliver Coupelons Guide, but it's called 50 times a second only, no matter weather you use fast or slow sweeping mode, or if you even stop it.
That seemed really strange to me, so I passed int 53's code through a disassembler. I listed below what I got. What this interrupt does is not (as mentioned in Oliver's guide) to update the display, but it seems to be the timer's IRQ, because it calls int 1C (the timer interrupt).
Here is what it does:
- Call Interrupt 1C (thus, 1C is not the timer IRQ, but called by it)
- refresh the display one time in 10.24 seconds (have no idea what this should be good for)
- (probably) read out the keyboard's touch lines
- do some other stuff (not analized the whole code)
int 53's code 00000000 50 push ax //save registers 00000001 53 push bx 00000002 51 push cx 00000003 52 push dx 00000004 56 push si 00000005 57 push di 00000006 55 push bp 00000007 1E push ds 00000008 06 push es 00000009 CD1C int 0x1c //call int 1C (timer interrupt) 0000000B B84000 mov ax,0x40 //test, if BIOS timerticks variable 0000000E 8ED8 mov ds,ax //is aligned to 200h 00000010 F7066C00FF01 test word [0x6c],0x1ff 00000016 7504 jnz 0x1c 00000018 B424 mov ah,0x24 //if so, force a display refresh, thus, force a display refresh once in 10.24 seconds. 0000001A CD7C int 0x7c 0000001C B84000 mov ax,0x40 0000001F 8ED8 mov ds,ax 00000021 A1AC00 mov ax,[0xac] 00000024 85C0 test ax,ax //not sure what now happenes, but note that prots 13 and 14 are known to be the, 00000026 7457 jz 0x7f //keyboard ports. Probably, the AFX's keyboard has no own IRQ, thus, the touch lines are 00000028 E713 out 0x13,ax //scanned frequently: 50 times a second, and then passed to other ints "emulating" 0000002A B90A00 mov cx,0xa //a keyboard IRQ 0000002D E2FE loop 0x2d 0000002F 8A26AE00 mov ah,[0xae] 00000033 813EAC000002 cmp word [0xac],0x200 00000039 741C jz 0x57 0000003B B90A00 mov cx,0xa 0000003E E413 in al,0x13 00000040 84C4 test ah,al 00000042 7403 jz 0x47 00000044 E9CD00 jmp 0x114 00000047 E85B01 call 0x1a5 0000004A E2F2 loop 0x3e
Thus, the LCD sadly has no IRQ providing perfect synchronisation - at least I found none.
(Altough wondering, why display sweeping takes CPU ressources then).
------------------------
So the bad news is, that we have to measure out the timing parameters ourselves, and furthermore 2^n color emulation ever will take 1/3 of the CPU ressources (except anyone finds a way
to program the timer directly via I/O; probably it's possible, but there are no docs mentioning it), whereas color emulation timed directly by the display IRQ would need only unimportant ressources.
One good news, however, is, that calibrating timing parameters for your calc is not that complicated anymore; I wrote a tool now based upon Deimos' idea (thx again), but did not upload it yet.
#7
Posted 26 October 2004 - 04:29 PM
It does, that's why we generally allocate new memzones to load the sprites of our gamesBtw, does your memzone lib create save buffers in the 144KB user space or in the programs mem? Additional space in the 144KB mem was quite cool...
There is something I don't understand in your prog... The method you use to switch between the layers can only be used for "static pictures" and not for the display of a real game that would need a high framerate, so I don't understand why you're speaking about the CPU usage... btw we already know the highest frequency you can find on this calc is 50 times/second, so I don't know if you will find something fast enough to switch the layers automatically while the program is running...
Plus, such a program often requires double buffering so we need more memory to manage the graphics (fortunately the memzones are useful for it); there is also the time needed to copy the buffers to the screen that will be greater if we use many layers.
So I think your method is OK for static pictures, but for real time programs it will be hard to keep the framerate at a "reasonable" value...
Another solution I see, is to understand how to command the DMA controller of the screen (with some sequences like those you can find in Olivier Coupelon's guide), and then we could maybe find a better solution than dealing with the actual c3 mode
#8
Posted 26 October 2004 - 05:13 PM
Should work also for moving graphics and real time programs (e.g., games), also double buffering. Not tested yet, but it's planned to work this like:The method you use to switch between the layers can only be used for "static pictures" and not for the display of a real game ... highest frequency you can find on this calc is 50 times/second. Plus, such a program often requires double buffering
You have a game with a framerate, let's say 25fps, for example, and do double buffering, where one buffer (a) is shown but not drawn to, and buffer b is drawn to but not shown; when ready building your frame, just swap buffers a and b (so you have no flickering when building a frame; we know this already from standart graphic modes).
Now, the buffer to be shown (a) consists of the 6 layers (--> seperated into 6 single buffers), where the emulation method switches between this single buffers only (and ignores buffer b ). It?s true that int 1C is called 50 times a second only, but that?s why I want to combine interrupt timing with non interrupted - timing this way:
- You have a game loop that does not carry about timing or color emulation and
- You have int 1C that initializes a full color emulation cycle, and returns when finished
- A color emulation cycle is based upon non interrupted timing, thus based upon a loop where we have to adjust timing parameters for. As the last buffer the cycle shows is the longest (thus, 2/3 of overall cycle time), it can return and does not need to wait until the last buffers time is elapsed, because the new cycle will be initialized by int 1C again
- that?s why the games loop has 2/3 of CPU ressources left for own use (draw graphics in the currently unshown buffer b and other gaming routines), and does not need to carry about color emulation
Because you have exactly 50 emulation cycles per second then, it also should be fast enough to display moving graphics with no flickering effects occuring. I'm in implementing that at the moment (the only problem is, that 50/s is no multiple of 310/s what is the displays frequency, but I already have an idea how to solve this).
#9
Posted 26 October 2004 - 06:56 PM
Btw, does your memzone lib create save buffers in the 144KB user space or in the programs mem? Additional space in the 144KB mem was quite cool...
The memzone lib is able to create safe memory zones in the user area of the AFX (the 144Kb), like basic files, or anything the calc use to store data. This lib is often used to provide a permanent "save game" possibily in games or to create safe temporary buffer to store sprites or anything else that exceed the 56Kb limit of a program.
Read the readme here: http://www.2072produ...e106.txt&text=1
#10
Posted 26 October 2004 - 07:15 PM
That's quite different from the examples you showed us, because in your examples the emulation cycle occurs certainly much more than 50 times per second, and i still think that 50 times/sec is too low...Because you have exactly 50 emulation cycles per second then, it also should be fast enough to display moving graphics with no flickering effects occuring.
#11
Posted 27 October 2004 - 04:56 AM
#12
Posted 27 October 2004 - 08:53 AM
That's right, and actually it is still flickering because the frequency of this interrupt is too low. The solution that I've used tu suppress this effect was to alternate the different combinations for each pixel, even if they have the same color. For example for darkgray with my 3 layers I can use 110 or 011, and in fact when you fill the screen with this color you will allways have something like 011 - 110 - 011 - 110 - ... , so you cannot see its flickeringyou'd also use int 1C in your gx lib
Perhaps you could use this method too, but naturally you won't have 2^n colors anymore because you will need at least 2 combinations for each gray... And the format of the pictures or the sprites won't be the same as the "normal" format we use for db mode
#13
Posted 27 October 2004 - 02:11 PM
For example, on a 60Hz monitor, you can easily notice the flickering of the screen (on a cathodic monitor I mean)
So In my opinion, I reckon that decreasing the value of 50 times/s should help, but u shouldn't decrease under 16 refreshes a second. Try 32/s, that'll provide some interesting results I think.
Or even a value around 48/s, not 50/s, that may give some flickerless pictures.
Anyway that's only an idea, but you really ought to test it before laughing lol
#14
Posted 27 October 2004 - 03:11 PM
#15
Posted 27 October 2004 - 07:04 PM
How do you mean that?decreasing the value of 50 times/s should help, but u shouldn't decrease under 16 refreshes a second. Try 32/s, that'll provide some interesting results I think.
Did you find a way to set the timing intervalls of int 1C??
#16
Posted 28 October 2004 - 01:19 PM
for example, you will have somthing like that: 01101011000 ...
where each number means a call to 1C, but each value allows or not the code to be executed.
Like this you'll be able to adjust very precisely number of calls ... and when they appear, knowing that a normally constitued human brain records each picture for about 0.12s.
and we have: 1/0.12 = 8.333 (let's take 8)
That's why I suggested a value like 32, cause 8*4 = 32
We can also choose another multiple, but not too high !!
Anyway, using the method below, you can even define a table in which you'll be able to make rotating 0 and 1 values in order to have nice synchronisation with player's eye.
But this is only my opinion ^^ (can be completely false)
#17
Posted 28 October 2004 - 02:06 PM
But this sadly won't work at all
The reason is, that the timing cycles take different times then. Lets say 20/s for example, your counter value for int 1C would be 20/50 = 0.4 then. Thus:
Int 1C (50/s)
0.0 --> call
0.4 --> not call
0.8 --> not call
1.2 --> call,
1.6 --> not call
2.0 --> call
1.4 --> not call
1.8 --> not call
2.2 --> call
So time between calls would take 3/50s for even, and 2/50s for odd calls. Thus, the average time for a cycle would be 2.5/50s = 1/20s (so you have an average of 20 cycles/s).
You?re compleately right that humans can?t recognice the different timing cycles (and view constantly 20/s thus), but that?s sadly not enough.
Because a perfect synchronisation with the LCD display is even not achieved then. For the above example, even calls would have 310*3/50 = 18.6 refreshs, odd ones 310*2/50 = 12.4.
You see now what the problem is: to prevent the screen from flickering, we would need an integer refresh rate per call, excatly 18 or exactly 19 for example, and that?s not possible with pure interrupt timing (would be possible with 10/s only, but that?s to slow). That?s also why 4nic8 got an even worse result by that.
However, I?m trying int 1C (interrupted + non interrupted timing) combined with int 7C now, maybe that?ll work flickerfree
#18
Posted 29 October 2004 - 06:42 AM
I don't know if bitwhiose is still arround but if he is not I can give his cmm library to you. I think he won't mind as long as you give credit to him. I can give this to you.
I think it is easier to port ASM to Pascal instead of C to pascal since you
could use the inline assembler ...
#19
Posted 29 October 2004 - 08:54 PM
Maybe you should also try with int 4A, I think it is also called frequently, because it handles the Automatic Power Off (disabling this interruption corrects the problem of APO when int 9 is disabled)
#20
Posted 12 November 2004 - 08:55 PM
#21
Posted 14 November 2004 - 01:02 PM
But I?ll continue it soon
#22
Posted 04 January 2005 - 05:48 PM
Maybe this should be put on the Casiocalc.org page (if there will ever be one... if someone is interrested in making it ... volunteers are welcome )
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users