Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - Horizontal scroll / palette change mid-frame

Reply to topic
Author Message
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Horizontal scroll / palette change mid-frame
Post Posted: Thu Sep 04, 2014 2:12 pm
Last edited by sverx on Thu Sep 04, 2014 3:21 pm; edited 1 time in total
I'm sure I read it's possible to change the background horizontal scroll register mid-frame... I do that over and over during the active screen phase but... no, I just get the whole image scrolling. With MEKA, Emulicious, SMSPlus.

So it looks like I'm doing something incredibly wrong, but the code is just a simple test loop

[code removed]

Suggestions?

edit: sorry... it was a stupid bug.

Let's reuse this topic :)

I'd like to also do a mid-frame (whole) (second) palette change.
Since I need to change 16 values I believe I can achieve this in two scanlines, right?
Is there any sample code already available? I'm just not so sure about the timing for the OUT I need...
  View user's profile Send private message Visit poster's website
  • Joined: 08 Dec 2013
  • Posts: 200
Reply with quote
Post Posted: Thu Sep 04, 2014 6:14 pm
I know that Sonic 1 changes palette mid-frame (for the water split in Labyrinth), you could look at that.

I'd still like to see your code as I'm pondering the possibility of adding a raster wave water effect to the screen in Sonic 1.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14685
  • Location: London
Reply with quote
Post Posted: Thu Sep 04, 2014 8:45 pm
When I tried it, I just spammed the palette RAM and it seemed happy enough, if glitchy - there's always some corruption and you can't seem to do 16 colours in a single line. The hard part is getting it to appear at a specific line - either you set interrupts at every line, which wastes a lot of CPU, or you have to do the three value shuffle to hit the right line with minimal wastage.

A water effect would be possible in Sonic but it would slow it down a lot... and it seems pretty on the edge of slowdown as it is.
  View user's profile Send private message Visit poster's website
  • Joined: 08 Dec 2013
  • Posts: 200
Reply with quote
Post Posted: Thu Sep 04, 2014 9:00 pm
Here's the routine that does the palette upload during the frame: https://github.com/Kroc/Sonic1-Z80-ASM/blob/master/S1.sms.asm#L766 Here's the actual loop in question: https://github.com/Kroc/Sonic1-Z80-ASM/blob/master/S1.sms.asm#L819 it uses quite tight timing!

Maxim wrote
A water effect would be possible in Sonic but it would slow it down a lot... and it seems pretty on the edge of slowdown as it is.


I think the slowdown comes from poor order of execution and I believe that once I've got the full codebase disassembled I will be able to remove all slowdown in the game via general optimisations, lookup tables for shifts and some major rearchitecting of the order of execution.

Doing a wavey effect is likely out of the realms of possibility, but I'm thinking that time can actually be saved by using every scanline to do something -- upload the scroll buffer, do the wavey effect, upload tiles, &c. so that the vblank has a lot less to do.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Sep 05, 2014 9:31 am
Kroc wrote
I'd still like to see your code as I'm pondering the possibility of adding a raster wave water effect to the screen in Sonic 1.


My code is a mess ATM and I hardly believe it will ever become a nice piece of code. The matter is that what I'm trying to code is something a little bit "borderline" for my habits... I want to apply a sort of 'wavy' effect on the central part of the screen only (preserving horizontal scroll in the upper and lower 8 pixels of the frame) while I'd like to also have the palette changed when 'entering' and 'leaving' this central part.
Theoretically I should be able to achieve it, since there are two scanlines that are using only color 0 which are separating the upper and lower borders from the central part...
Well, I'll let you know if I succeed in making it work (on hardware too!)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Sep 05, 2014 12:31 pm
Kroc wrote
Here's the routine that does the palette upload during the frame: https://github.com/Kroc/Sonic1-Z80-ASM/blob/master/S1.sms.asm#L766 Here's the actual loop in question: https://github.com/Kroc/Sonic1-Z80-ASM/blob/master/S1.sms.asm#L819 it uses quite tight timing!


Interesting! I don't get the NOP in the loop... if it's true that we have 10 slots each active line and that we have 228 cycles per line (see this), we just need to be sure that OUT are at least 23 cycles apart, right?

   ld a,(hl)      7
   out (n),a     11  --
   inc hl         6
   nop            4
   ld a,(hl)      7
   out (n),a     11  -- distance = 28
   inc hl         6
   djnz          13
                 --
                 65


Or is there something I'm missing?
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Sep 05, 2014 1:21 pm
It seems to work quite nicely on emulators, but it's taking more than 2 scanlines to change 16 colors (it's pushing one color approximately each 32,5 cycles, so it's changing 7 colors per scanline)
On the other hand, if I push one byte each 23 cycles (say I write a code that does this exactly...) I'd be able to push almost 10 colors per line (228/23=9.9) thus making it possible to change a whole 16 colors palette in less than 2 scanlines, but I don't want to venture in this effort before having discussed this here.
The question is: would it work or not? If there's no chance, what's the reason?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14685
  • Location: London
Reply with quote
Post Posted: Fri Sep 05, 2014 5:01 pm
Here's the code I used in "ono":
    exx
      ; blat palette, assume everything is set for it
      .rept 16
      outi
      .endr


And here's the report of how it works in real life:

http://www.smspower.org/forums/viewtopic.php?p=57183#57183

Quote
All the coloured squares you create flash constantly, theres single fixed in place pixels scattered around the screen, and lastly about two blocks width on the right side of the screen never has any coloured blocks appear in it.


So... don't do that.

It ought to be possible to delay this up to precisely 23 cycles - outi is 16, so inserting a "sub 0" might do the trick. (Also, it sounds cool.) Source is available if someone wants to try...

I suspect this will correct the flashing and missing colours, but I believe the scattered pixels correspond to the bus collision and are unavoidable. If you are changing a single colour per line interrupt, you can time it so the bus collision is outside the display area, but when changing all of them, you need to do something to mask these.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Sep 06, 2014 2:08 pm
Maxim wrote
Here's the code I used in "ono"
[...]
So... don't do that.


Ok, I won't :)
I read there's one access slot every 4 pixel on passive lines, so there are 85 slots per line (342/4=85.5) and I read that there are only 10 slots on active lines, so I suspect that there's an access every 32 pixels (342/32=10.6875). This means that every 22 CPU cycles (288/10.6875=21.3) should be possible to write to the VDP.
The question is: is the VDP port latched?
I mean, is it important at which exact moment I write to that port or it doesn't matter as long as at least 22 CPU cycles have passed since I had written last?
  View user's profile Send private message Visit poster's website
  • Joined: 31 Oct 2007
  • Posts: 853
  • Location: Estonia, Rapla city
Reply with quote
Post Posted: Sat Sep 06, 2014 5:51 pm
These scattered pixels are the access slots where CRAM or VRAM update can happen. They are 32 pixels apart and that is where the 22 cycles value indeed comes from.
The port holds a one single value. You do a write and it sticks there until it is emptied by the access slot. When you write too fast your old value is lost and that is exactly how the data corruption happens when writing stuff too fast during active scan. On MD, in MD mode, VDP holds CPU on a leash and it also have 4 element FIFO so you can never create an overflow condition with data corruption, VDP puts CPU on hold until it is ready to take new data. This can lead to slowdowns but at least you have one less thing to worry about that is more severe :P

I am actually not 100% sure there are 10 active slots per line, but practice seems to show there's at least 10, and there's definitely 8.
I am getting some hardware soon that will let me look at stuff closer to see if there's more fun going on in blanking area or not, maybe there's few more slots but using them will require quite precise code.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Sep 09, 2014 9:42 am
Maxim wrote
It ought to be possible to delay this up to precisely 23 cycles - outi is 16, so inserting a "sub 0" might do the trick. (Also, it sounds cool.) Source is available if someone wants to try...


I followed your suggestion and tried to 'patch' Ono. So I did one version with
     ; blat palette, assume everything is set for it
      .rept 16
      outi
      sub 0
      .endr

which would add 7 cycles to the 16 required by OUTI, and I also made a version with
     ; blat palette, assume everything is set for it
      .rept 16
      outi
      dec de
      .endr

to add 6 cycles instead of 7... well, unfortunately both of them just keep on flashing boxes color like the original version.

I guess I can try with longer waits and see if I find the best value...

Additionally, in my code I'm using the 'Sonic 1' loop version, the one which takes 65 cycles to push 2 bytes... and it seems it's working most of times, but it also happen it failed few times (I see some wrong color flashing on my TV every few seconds...) which is very strange :|
  View user's profile Send private message Visit poster's website
  • Joined: 08 Dec 2013
  • Posts: 200
Reply with quote
Post Posted: Tue Sep 09, 2014 11:20 am
It could be that, for the Sonic 1 loop, the time the loop begins is highly sensitive. Try placing NOPs before the loop and see if you can 'sync' the loop and stop the flashing.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Sep 09, 2014 11:48 am
Kroc wrote
It could be that, for the Sonic 1 loop, the time the loop begins is highly sensitive.


That's exactly what I was trying to understand when I asked this few days ago, but the answer (or how I understood that) was kind of "it doesn't really matter when you do write to the CRAM as long as enough time has passed since last write".
How could I sync without using line interrupts? I currently have a loop which checks Vcounter and changes the palette when it becomes = 8 ...
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14685
  • Location: London
Reply with quote
Post Posted: Tue Sep 09, 2014 2:03 pm
Interesting that the 23 cycle timing doesn't work in practice. (Assuming the code is not failing in some other way to produce the flashing...)

As for polling vs. line interrupts to get phase alignment: even line interrupts are timing insensitive, as they can only occur between instructions. If the interrupted code is "nop nop nop" then it could be late by 3 cycles (as each instruction takes 4). If the CPU is stuck in an "dec (ix+0)" (or one of the many other 23-cycle opcodes) then it could be late by 22 cycles. Polling will have your loop length as the worst-case cycle offset. If you stick a breakpoint in the line interrupt code and then examine the "iperiod" in Meka, you'll see the value fluctuates between hits.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Sep 09, 2014 2:28 pm
Here's the code I'm using (well, the 1st half...)
waitForVBlank ensures we're in VBlank, then I wait for line 0, set VDPAddress and the needed values for HL and B (counter).
So, I wait for scanline 8, the loop that checks that is 28 cycles long (if there's a faster way please tell me...) then the code taken from Sonic 1 goes...

_intLoop:
  call waitForVBlank

-:in a,(VDPVCounter)               ; wait frame start
  or a
  jr nz,-
 
  ; prepare something while we wait...
  SetVDPAddress SpritePaletteAddress
  ld hl,SpecialPalette
  ld b,16/2                        ; each loop cycle moves 2 bytes

-:in a,(VDPVCounter)               ; wait line 8
  cp 8
  jp m,-

-:ld a,(hl)                        ;   7
  out (VDPDataPort),a              ;  11
  inc hl                           ;   6
  nop                              ;   4
  ld a,(hl)                        ;   7
  out (VDPDataPort),a              ;  11
  inc hl                           ;   6
  djnz -                           ;  13
                                   ;  --
                                   ;  65


I'm changing the second (sprite) palette... sometimes I see one frame with sprites...

edit: ... oh wait... maybe I found my problem :| It could be totally unrelated, and just another silly bug of mine (not in the pasted code...)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Sep 09, 2014 9:17 pm
Latest 'Ono' tests report ;)
With 24 cycles each loop (OUTI + 2x NOP) it still doesn't work correctly.
With 28 cycles (OUTI + 3x NOP) there are no more colors flashing. There's still a lot of scattered pixels around (looks like there are 8 'columns' of them, separated vertically by approx 16 pixels...)
I will run more tests tomorrow, hopefully.

As for my own program, it works. The problem was that I had my music function call at around line 184, right after restoring the original palette, and of course sometimes PSGlib functions require more than 8 scanlines, thus skipping a frame...
Here also there are 8 white 'pixels' appearing around scanline 182, the line where I start restoring original palette. I'd gladly accept suggestions to remove them.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14685
  • Location: London
Reply with quote
Post Posted: Tue Sep 09, 2014 9:35 pm
When you write to the palette, it screws up the read for the currently displayed pixel. That's the dots you see, it even affects the VBlank area. They might be the AND of the value written and the value being read, which would tend towards white. The only "fix" is to time your writes to be offscreen, or to draw noisy white graphics in the same place to make them hard to see.
  View user's profile Send private message Visit poster's website
  • Joined: 31 Oct 2007
  • Posts: 853
  • Location: Estonia, Rapla city
Reply with quote
Post Posted: Wed Sep 10, 2014 12:18 am
The dot is exact color being written. CRAM is single port, the data of the write is used by the color read because there's no way to delay anything.
You could draw images on the screen like that but the CPU is kinda slow to get any useful resolution like that, plus it is not easy to get synchronized to raster.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Sep 10, 2014 8:06 am
Maxim wrote
They might be the AND of the value written and the value being read, which would tend towards white.


You mean OR, it would tend towards black with AND...

TmEE wrote
The dot is exact color being written


Not sure about that, to me they seem all white instead of the 16 various colors I'm writing to the sprite palette.

BTW it seems to me there's no way to avoid that, if I want to change palette during active display and change all 16 colors in two scanlines...
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14685
  • Location: London
Reply with quote
Post Posted: Wed Sep 10, 2014 1:09 pm
sverx wrote
You mean OR, it would tend towards black with AND...

You're right, I always get them wrong at the first attempt.

The point about the unavoidable pixels is that games that do change more than one (?) colour on a line interrupt have to mask them, hence the water surface effects in Sonic.
  View user's profile Send private message Visit poster's website
  • Joined: 28 Sep 1999
  • Posts: 1197
Reply with quote
Post Posted: Wed Sep 10, 2014 1:46 pm
In terms of the Ono display, could you alternate the palette bit in tiles for each row, so that you could spend one row loading the palette for the next row? So row N uses palette 0, row N+1 uses palette 1, and you write 16 colors into palette 1 on row N while displaying the colors already loaded in palette 0..

That way you could update the palette leisurely over the (16?) lines that make up a row and have no graphical problems other than the dots from CRAM writes.

With some careful delays you might even be able to line up the dots a bit so it would look less like random flashing pixels. Or is that what Ono already does?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14685
  • Location: London
Reply with quote
Post Posted: Wed Sep 10, 2014 3:49 pm
The sprite palette is mostly in use for the sprites, so there's not enough space to double-buffer a palette swap in this way.

My original design for ono was to write the palette as fast as possible and see what happened. This had some obvious shortcomings.

Here comes some speculation...

The goal is to set the palette entry for 16 squares over the course of as little time as possible, to give a "grid" effect by palette swaps. There are 228 cycles per line and we seem to be able to update about once every 28 cycles. There are 342 "virtual" pixels per line, only 256 of which are visible, so there's approximately 1.33 screen pixels per Z80 clock; so there's about 37 screen pixels between palette writes. This means we can update about 8 palette entries per line, and about six of them will show up as pixels on the screen.

If we play with the timing a bit, we could try to make it so the pixel being "hit" by the write is for the index we are writing, so the "noise" will be (mostly) invisible (the pixels will show up over sprites). There's a fair bit of jitter in the line interrupt timing, and we have 16-pixel windows to hit, but I think it might be feasible to mask the noise like this. The result will still take three lines to update all 16 palette entries.

(Random aside: maybe you could spam a palette entry during active display to make a snow, or rain, effect? It's effectively an extra layer in front of the other three "layers".)

Since we can't update all 16 entries in one row, we could stagger the grid cells across multiple lines in a visually pleasing way. The code which determines which square to change the colour of when an enemy is hit will have to be more complicated for this to work.

So then there's another option: lose more of the grid-like nature of the grid. Stagger the squares somewhat algorithmically so instead of updating 8 per row, we could reduce that to three - with careful (manual) timing, and not too much jitter, we could fit two palette writes into the off-screen part of the display (~57 cycles by my maths). Thus we'd take 8 rows to update the whole palette. This is potentially awful for a true raster split, or a water effect, but I can imagine a wonky-looking grid with offset columns for ono, and no palette noise at all.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Sep 11, 2014 8:40 am
The answer is (or seems to be) 26.
I mean with 26 cycles between VRAM writes it still looks we don't get any write skipped, with only 25 instead we do (at least on my PAL SMS II... I believe NTSC would be the same, I'm not sure about first revision VDP...)
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14685
  • Location: London
Reply with quote
Post Posted: Thu Sep 11, 2014 10:04 am
OK, so new maths:

- 228 cycles per line means you can change 8 entries per line, 16 entries will take 1.8 lines
- You can squeeze three updates into the offscreen area if you are careful with the timing. This leaves only 5 cycles of "padding" around the writes, so line interrupt jitter may cause issues sometimes. That would mean six lines to update 16 palette entries, 11 lines to update all 32
- On the Game Gear you have much more "offscreen" time, but while the line interrupt triggers early, it's probably not early enough to easily catch the very start of the offscreen area with your palette write. But you could trigger the line interrupt one line before you want to start and burn CPU to reach the next line. Then you have about 121 CPU cycles, thus you can fit in 5 offscreen updates per line, with 17 cycles "padding", which doesn't compensate for the double-size palette entries meaning you need to write twice as much data: so it's 7 lines to update 16 entries, 13 lines to update all 32.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Sep 11, 2014 11:11 am
Maxim wrote
You can squeeze three updates into the offscreen area if you are careful with the timing.


Well, actually it also might be possible that the access in the offscreen area could be even faster... in my tests I wasn't really taking care of which part of the scanline the raster was (onscreen or offscreen)

As for my own needs, I'm fine with changing 16 colors in no more than 2 scanlines (and I'll simply ignore those 'white-ish' pixels)
  View user's profile Send private message Visit poster's website
  • Joined: 01 Jan 2014
  • Posts: 331
Reply with quote
Post Posted: Fri Sep 12, 2014 5:34 am
Information in this thread should be put somewhere in development section of the website. Cycle profile of Z80 to VDP in it's various modes and states is invaluable.
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14685
  • Location: London
Reply with quote
Post Posted: Fri Sep 12, 2014 7:07 am
Feel free, it's open access.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Sep 12, 2014 7:41 am
  ; prepare something while we wait...
  SetVDPAddress SpritePaletteAddress
  ld hl,SpecialPalette
  ld b,16
  ld c,VDPDataPort                 ; we're going to OUTI 16 times

-:in a,(VDPVCounter)               ; wait line 8, as I want to change palette from there only
  cp 8
  jp m,-

-:outi                ; 16
  jp nz,-             ; 10


here's the code that works for me, using a 26 cycles loop to write to CRAM as fast as I can but slow enough to avoid skipping bytes. I wonder why in Sonic 1 code they decided to use a slower cycle, maybe the VDP of the first revision was slower?
I have no other hardware but my SMS II, so if somebody can test this with the previous model...
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Oct 18, 2014 2:26 pm
Searching the forum about other stuff I found this post where Maxim was already investigating and finding the same info in 2003...
It also kinda clears up why Sonic CRAM update is using a 28 cycles wait... it probably comes from some official documentation (at least GG docs mentioned 28 cycles...)
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14685
  • Location: London
Reply with quote
Post Posted: Sat Oct 18, 2014 6:18 pm
The linked post was about VRAM writes, not CRAM, but the same timing probably applies.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Oct 19, 2014 10:55 am
Right.
On the contrary, it seems that writing to a VDP register or to set VRAM/CRAM write address doesn't need any special attention... or am I overlooking this?
  View user's profile Send private message Visit poster's website
  • Joined: 28 Sep 1999
  • Posts: 1197
Reply with quote
Post Posted: Sun Oct 19, 2014 6:49 pm
sverx wrote
Right.
On the contrary, it seems that writing to a VDP register or to set VRAM/CRAM write address doesn't need any special attention... or am I overlooking this?


I've found that updating VDP registers too rapidly can cause data to get overwritten or missed. It's been a problem only when doing raster effects (specifically: writing during the active display) where I tried to change 3 to 5 registers sequentially. Adding some NOPs fixed the problem.

But it's something that is done very infrequently, so it's not a common problem. I'd advise just testing it on the real thing and then adding delays as needed to space out the writes more evenly.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Oct 19, 2014 7:07 pm
Charles MacDonald wrote
It's been a problem only when doing raster effects (specifically: writing during the active display) where I tried to change 3 to 5 registers sequentially. Adding some NOPs fixed the problem.


Can you share a piece of source code? I'd like to run some tests in your very same conditions...
  View user's profile Send private message Visit poster's website
  • Joined: 28 Sep 1999
  • Posts: 1197
Reply with quote
Post Posted: Sun Oct 19, 2014 8:23 pm
Quote
Can you share a piece of source code? I'd like to run some tests in your very same conditions...


Sure, I can get to it next week. If it matters this was for a TMS9918 legacy mode program, hope that's not an issue.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Nov 13, 2014 3:56 pm
I wonder if any special attention is needed when setting the VDP address during the active phase.
I mean, I believe many of us share this macro (I took it from Maxim's tutorial...)

.define VDPControlPort      $bf
.macro SetVDPAddress args addr
  ld a,<addr
  out (VDPControlPort),a
  ld a,>addr
  out (VDPControlPort),a
.endm

which in fact writes twice to port $BF with very short delay in between (out:11, ld:7 = 18 cycles)

I never had any problem TBH, I just wondering if it's just luck or if it's that port working 'faster' than VDPDataPort ($be)
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14685
  • Location: London
Reply with quote
Post Posted: Thu Nov 13, 2014 4:19 pm
I'd always assumed that was OK because it's not touching the VDP's internal data bus. Only when actually accessing VRAM or CRAM does it have to contend with the video generator's own need to read that data.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3758
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Nov 13, 2014 4:36 pm
I guess you're right! I wonder if there's a leaked block diagram of the VDP somewhere...
I guess then that the internal bus isn't used for setting the address but it's used to access the VDP registers, and that would explain also why Charles had to add some nop to change few registers in a row.
  View user's profile Send private message Visit poster's website
Reply to topic



Back to the top of this page

Back to SMS Power!