Could you try something simple Toni (on real hardware and compare with emu) and see if you get the same results as me? Take over hardware, set a new int ptr (in my case, VBL), and in the int you have a counter that is increased each time it's called.
No matter how many times I clear requests (just before, just after setting the vector, or both) the counter is never 0 when AsmOne debugger hits it first time. In my case, the int is set just before VBL (rasterline $132 or something), so I'm sure the hardware has no reason to call it once before the VBL and once when the VBL occurs a few rasterlines later... |
Quote:
|
Quote:
Code:
move.l counter(pc),d0 |
Red Screen Of Debugging. :)
The reason I posted this at all was that I couldn't see any problems with the few lines in question. Will probably reveal some interesting behavior, I'll look into it. And Toni, this is on an A500 OCS/kick 2.0, AsmOne 1.02E debugger. |
Another undocumented feature I found today (I am sure someone else must have found this long long time ago..)
If HPOS equals horizontal DIWSTOP when COLOR0 (background) is written by copper, change is visible after extra delay of 2 lores pixels. This explains Leander "border" (in right side) which can't be possible without undocumented features :) (edit: it may not be that simple after all but clearly there is "impossible" 2 lores pixel difference) EDIT2: above explanation is totally wrong (as usual). Extra 2 lores pixel position is always in same horizontal position (even without bitplanes disabled) so I think this is the position for "extra" 0.5 cycle (PAL is 227.5 color clocks) that causes the delay. Argh, half-cycles require hacks.. EDIT3: in NTSC mode (long/short line toggle active) there is nice "sawtooth" pattern which confirms it really is end of line "syncronization point". |
Wouah nice finding Toni :D
|
1 Attachment(s)
Hi Toni,
The problem observed by you is caused by an "unusable" cycle for the copper. Since the copper uses every other cycle and every scan line has odd number of memory access cycles (at least in PAL) there is a situation when two accesses could happen back to back. In such a case one of these cycles is "blocked". If the copper wants to access the memory bus two cycles before the first refresh slot that access is not performed (e.g. colour register is not written) but the actual transfer takes place in the next cycle (the one before the first refresh cycle). Since every memory access takes two low resolution pixels the observed delay is of that amount. Also the opcode fetch is affected by this behaviour and the "empty" cycles in WAIT and SKIP instructions. Interesting thing is that the /DBR is set in this "blocked" cycle effectively blocking any potential blitter or CPU access (this is important for cycle exact emulation). The RGA bus is idle. This cycle is not existent for the copper except one situation: When COPJMPx register is written the copper fetches its next opcode in the second cycle after write or misses that cycle by being blocked by higher priority DMA access. Next it requires a bus access to reload its program counter from location register. Actually there is no data transfer to/from the memory but the /DBR is set to allow the internal transfer of location register (the DMA pointer registers share the same ALU to manipulate them that's why there can't be any other DMA transfer). The RGA is idle during this cycle. If the second cycle after COPJMPx write is the aforementioned second cycle before the first refresh cycle it's counted as usable and the copper pointer register is updated in the next cycle. During both these cycles the /DBR is set and the RGA is idle. Below there is attached a screen shot illustrating described bus accesses. The copper executes following program: MOVE #$0FFF,COLOR0 ($180) MOVE #$0000,COLOR0 ($180) MOVE #$0000,COPJMP1 ($088) ($08C is the copper instruction register) |
Quote:
EDIT: this can explain few demos that have copper waits like 32DF FFFE + move. (which should be the exact position that causes 1 cycle delay and also slowing down the blitter by 1 cycle) |
1 Attachment(s)
I have made some tests in the NTSC mode. It seems that during long lines (228 CCK long) there is no "unusable" or "blocked" cycles. All 114 cycles are usable by the copper if not blocked by the bitplane DMA.
|
Quote:
|
Quote:
You need to wait for next line's hpos 3 or 7 (I forgot again) or you will see color change on far right border (real A500 + 1081-style monitor with adjusted width) |
I think you're correct with HPOS 07 Toni - I normally wait for 07 to avoid the 'step' colour change at right edge...
|
Quote:
My TVs displayed 320x256 as "right-adjusted in 352 pixels width", and they had limited adjustments. My C1081 revealed buggy scroller charplot routines :) but was the same resolution from factory. At last you could center the picture properly! :) There's some information in the max overscan thread how many pixels are visible on C1081 after being ...adjusted. |
Quote:
|
Why would anyone select a horizontal position, set background color, and "enjoy" the ugly joint? There are many demos with this "effect" - do you really think they saw it? Do you really think they saw buggy scroller-charplots outside $d8?
If it wasn't clear, I was talking about how much of the overscan was shown on a TV then. Maybe from $2c to $d2 (estimate). Maybe I'm missing something, because I don't catch your drift Toni :) We've already established why $07 or something is a correct wait. |
Quote:
EDIT: and in NTSC it is even more visible due to not having that extra missed cycle and first Amiga designs were NTSC only. Sorry but you can't win :D |
TV on its way over, tested on my C1081.
Position $df is (by eyesight) 4 lores pixels outside a standard 320x256 display using $38 to $d0. A 352 screen would display extra pixels in the left margin on a standard TV, but (most of) the $d0 to $d8 pixels would go outside the right edge. If I adjust the C1081 to match the TV adjustment, the "coppershade step" is juuust inside the plastic edge. This is what I mean by the $df step being visible or invisible. Outside or inside the right edge. Leander has no $df steps. I think TVs had a physical black "mask" also to cover up even more, I will know tomorrow. |
Finally new undocumented feature, there is real undocumented functional difference between OCS and ECS Denise.
DIWSTRT hpos value zero or one: OCS Denise detects this and enables horizontal display window. ECS Denise ignores it (previous horizontal state remains), only 2 and larger work. I think this is "cheap" ECS Denise bug fix because there is also some kind of OCS Denise bug/feature: if vertical display window is already enabled (DIWSTRT vpos already matched in earlier lines) and DIWSTRT vertical position matches again in later lines (for example was changed with copper) and DIWSTRT hpos value is zero or one: vertical display window state changes to some kind of frozen state and display gets blanked until next frame. For example TSP demo disk 2 (Hulkamania) and Majic 12 - Ray of Hope 2 have blank screens if using ECS Denise. Then there is Kefrens Megademo 8 (snake in Snake Bite part partially remains on screen when ending the part), which works with both Denise versions: OCS Denise because of "frozen state" feature and ECS Denise because hpos=0 gets ignored. This is perfect example of "only working accidentally" :D |
1 Attachment(s)
This is because horizontal counter inside Denise counts from 2 to 455 (short PAL line). It never is equal to 0 or 1. It seems that the ECS Denise uses an SR flip-flop with "equal" comparators to set or reset horizontal display window while its OCS counterpart uses two "less-greater" comparators which constantly compare the horizontal position value against hpos values in DIWSTART and DIWSTOP registers.
If you try to read VHPOSR register in Agnus you can't read values 4, 6, 8, 10. It means the refresh slots are allocated to these positions. As Tony has already discovered the vpos counter doesn't change when hpos counter rolls over. It happens a little bit later. Consequently Copper's WAIT xx01 and WAIT xx03 have the same timing. As the only mean of resetting Denise's hpos counter (or rather setting it to 2) is a write of STRHOR, STRLONG or STREQU registers during the first refresh slot it's obvious that the hpos counters in Denise and Agnus are not in sync. I guess the one in Agnus is advanced by 4. The attached picture illustrates my guesses. There is no vertical part of DIWSTRT/DIWSTOP registers inside Denise. The vertical blanking is done by writing appropriate strobe register during refresh slots. Another undocumented feature: Bits 15-8 of register $07C (LISAID) on AGA machines are loaded from an external shift register. The six most significant bits can be configured by jumpers (at least on an A4000) while bits 9 and 8 are hardwired to GND. These two bits are read by V39+ graphics library during activation of AGA display modes (initiated by SetPatch) and copied after negation to MemType field of graphics library base. If they are not zero the AGA display modes are not enabled although an AGA Lisa id is present in the low byte. An ECS Denise returns all ones in the high byte of $07C register, the default value on AGA machines is $FC but WinUAE always returns $00. |
Quote:
Unfortunately it is practically impossible to confirm without knowing internals of the chip :( Quote:
Perhaps old Denise gets confused when strobe and diwstrt hpos are too close together? Quote:
Confirmed, A1200 returns 0x00F8, ECS Denise 0xFFFC (was 0x00FC in UAE) |
All times are GMT +2. The time now is 17:37. |
Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.