skywaffle Posted September 22 Share Posted September 22 Hmm, I don't think I would have enough RAM to accomplish what I am looking to do, that's why I was hoping to quickly copy characters from video ram to an adjacent character. I was thinking maybe older Coleco games would have accomplished this using this method since ROM size was so limited. (Pepper II, or Smurfs) , but I could see utilizing the RAM if the game is simple enough. Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5536969 Share on other sites More sharing options...
skywaffle Posted September 22 Share Posted September 22 I found that using a partial buffer I can copy the screen more quickly than copying and relocating one character at a time. Grabbing groups of 6 rows of characters three times results in taking 6 frames to shift the screen over 8 frames (benchmarking via the frame counter) doing them one at a time. Would there possibly be a more efficient method than this? Buffering more of the display didn't speed up anything, so for the sake of memory conservation, I felt this was a happy medium. This is what I came up with. FOR #I=(32*4)+$1800 TO (32*16)+$1800 STEP 32*6 FOR J=0 TO 32*6-1 VBUFFER(J) = VPEEK(#I+J) NEXT SCREEN VBUFFER,0,#I-($1800-1),31,6,32 NEXT Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5537026 Share on other sites More sharing options...
Captain Cozmos Posted September 22 Share Posted September 22 (edited) Lately I RLE a compressed screen to RAM instead of VRAM. I make my changes there then manipulate the Pattern Table through the VDP registers. Point to the RAM Buffer then OUTI everything to VRAM Name Table during the NMI call. Works great as long as you do the prep. Edited September 22 by Captain Cozmos Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5537039 Share on other sites More sharing options...
artrag Posted September 22 Share Posted September 22 1 hour ago, skywaffle said: I found that using a partial buffer I can copy the screen more quickly than copying and relocating one character at a time. Grabbing groups of 6 rows of characters three times results in taking 6 frames to shift the screen over 8 frames (benchmarking via the frame counter) doing them one at a time. Would there possibly be a more efficient method than this? Buffering more of the display didn't speed up anything, so for the sake of memory conservation, I felt this was a happy medium. This is what I came up with. FOR #I=(32*4)+$1800 TO (32*16)+$1800 STEP 32*6 FOR J=0 TO 32*6-1 VBUFFER(J) = VPEEK(#I+J) NEXT SCREEN VBUFFER,0,#I-($1800-1),31,6,32 NEXT The loop would be much faster if you read from vram using INP() instead of vpeek(). Just read the first byte by setting the address in vpeek, use inp($BE) to read all the following data. The vdp will increment the address at each read. Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5537081 Share on other sites More sharing options...
artrag Posted September 22 Share Posted September 22 (edited) FOR J=0 TO 32*6-1 VBUFFER(J) = VPEEK(#I+J) NEXT can be coded more efficiently as VBUFFER(0) = VPEEK(#I) FOR J=1 TO 32*6-1 VBUFFER(J) = INP($BE) NEXT It is the best you can do before moving to asm Edited September 22 by artrag 1 Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5537084 Share on other sites More sharing options...
skywaffle Posted September 23 Share Posted September 23 Thanks for the insight and example! I was marvelling at what Konami was able to do with their MSX games, like Gradius/Nemesis 2 and 3 using the same VDP. It made me wonder if something similar could be done on the Coleco since it's more or less the same hardware. I do need to dig into Z80 ASM. I had gotten pretty comfortable with 6800 ASM, but it seems like a whole different world on the Z80. 1 Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5537207 Share on other sites More sharing options...
artrag Posted September 23 Share Posted September 23 (edited) Actually the code above can be interfered by the sprite update in the isr, because cvbasic updates them every frame. Edited September 23 by artrag Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5537291 Share on other sites More sharing options...
artrag Posted September 23 Share Posted September 23 Give me a couple of hours for a better solution Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5537293 Share on other sites More sharing options...
artrag Posted September 23 Share Posted September 23 5 hours ago, skywaffle said: Thanks for the insight and example! I was marvelling at what Konami was able to do with their MSX games, like Gradius/Nemesis 2 and 3 using the same VDP. It made me wonder if something similar could be done on the Coleco since it's more or less the same hardware. I do need to dig into Z80 ASM. I had gotten pretty comfortable with 6800 ASM, but it seems like a whole different world on the Z80. With a bit more ram you can get the same results you see on msx. The sgm module is the living proof of that. Anyway there is already a lot that can be done on stock colecovision exploiting its vram. E.g. in what cvbasic calls mode 2, you can have multiple tilesets and multiple PNTs and you can switch among them in few cycles Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5537306 Share on other sites More sharing options...
AnalogKid Posted September 25 Share Posted September 25 The following is what I came up with for scrolling the VRAM left for Scramble and it's using as few clock cycles as I could manage. My screen has a static non-scrolling line at the top and bottom, so you may need to adjust the numbers and size of the buffer if you're going full-screen. It breaks the copy into two phases to keep the RAM requirement reasonable while doing the fewest possible outs to the control port. If you need more free RAM, make it three. My case needed scroll_buffer to be 341 bytes. Some may squawk that I shouldn't have two blocks doing the same operation and should keep the ROM size down, on principle, but in my case I literally could not sacrifice the couple hundred clock cycles. This should leave you plenty of time for game logic, however in my case I'm also not calling the stock sound processing and am using my own because the stock routines, while very very handy, are VERY expensive cycle-wise. ld d,#31 ld c, #0xBE ; port ld a,#0x21 out (#0xBF),a ld a,#0x18 out (#0xBF),a ld hl, #_scroll_buffer ld e,#11 ; 11 lines of 31 ld b,#31 00001$: ini ; populate (hl) and increment hl, decrements b, sets z if b is 0 nop jp nz,00001$ ; char loop on b in a, (#0xBE) ;every 32nd character we read but do not put in hl dec e ; line loop ld b,d jr nz, 00001$ ; line loop on e ld a,#0x20 out (#0xBF),a ld a,#0x58 out (#0xBF),a ld hl, #_scroll_buffer ld e,#11 ; b is 31 xor a 00002$: outi ; read from (HL), writes to the (C) port, increment HL, decrement B, set Z if zero nop jp nz,00002$ ; char loop on b out (#0xBE), a ;every 31 we have to write 0 to port, a was set to 0 above dec e ; line loop ld b,d jr nz, 00002$ ; line loop on e ld a,#0x81 out (#0xBF),a ld a,#0x19 out (#0xBF),a ld hl, #_scroll_buffer ld e,#11 ; 11 lines of 31 ; b is 31 00003$: ini ; populate (hl) and increment hl, decrements b, sets z if b is 0 nop jp nz,00003$ ; char loop on b in a, (#0xBE) ;every 32nd character we read but do not put in hl dec e ; line loop ld b,d jr nz, 00003$ ; line loop on e ld a,#0x80 out (#0xBF),a ld a,#0x59 out (#0xBF),a ld hl, #_scroll_buffer ld e,#11 ; b is 31 xor a 00004$: outi ; read from (HL), writes to the (C) port, increment HL, decrement B, set Z if zero nop jp nz,00004$ ; char loop on b out (#0xBE), a ;every 31 we have to write 0 to port, a was set to 0 above dec e ; line loop ld b,d jr nz, 00004$ ; line loop on e Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5538667 Share on other sites More sharing options...
artrag Posted September 26 Share Posted September 26 (edited) Your solution will exceed the Vblank time and will show frame tearing. The best way is to allocate a whole game window in ram (if you can). Even with 1KB of ram you can have video buffer of eg 32x20=640 bytes where the z80 can work and that can be transferred to vram in one frame without frame tearing. If you need more ram for the game logic and you cannot allocate a whole frame buffer in ram, you can avoid frame tearing using two name tables. While you write to the first, you display the second. When you are ready, you switch the two pages without frame tearing and repeat the process. Edited September 26 by artrag Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5539022 Share on other sites More sharing options...
artrag Posted September 26 Share Posted September 26 This is an example that shows how to use two PNTs to have scrolling without frame tearing. Naturally the time spent to build in VRAM the hidden page can be more than one frame, but the final result is perfect (swapping pages takes almost no cycles). The ram used by this approach is practically zero. The speed is limited by the time you need to 'compose' the next frame in the hidden page maze_scroll (1).bas 1 Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5539030 Share on other sites More sharing options...
AnalogKid Posted September 29 Share Posted September 29 I forgot a rather important detail when I provided my solution, sorry I wrote the code a year ago and what I presented is only part of my smooth-scrolling solution. I'm flipping between screen 1 and 2 and the scroll of screen 1 is performed while screen 2 is active and then screen 2 is scrolled while screen 1 is active, so tearing isn't an issue. In my case I couldn't sacrifice 768 bytes for a screen buffer so I'm drawing the landscape on the fly and scrolling the VRAM itself. If I could have crammed the game in under 200ish bytes I probably could have opted for in-memory map but I'm a little skittish of the stack marching over my data 😄 Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5540610 Share on other sites More sharing options...
artrag Posted October 7 Share Posted October 7 When you say screen you mean Name Tables, do you ? Where do you allocate them in VRAM? Which video mode do you use? Quote Link to comment https://forums.atariage.com/topic/366226-cv-basic-scrolling/page/2/#findComment-5545197 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.