Serguei2 Posted February 1, 2019 Share Posted February 1, 2019 I tried to make a 16x16 sprite and I messed up. #include <coleco.h> #include <getput1.h> const byte gtsSprites[] = { 0x00, 0x03, 0x0F, 0x19, 0x36, 0x3F, 0x7F, 0x7F, 0x7F, 0x70, 0x30, 0x38, 0x1E, 0x0F, 0x03, 0x00, 0x00, 0xE0, 0xF8, 0xCC, 0xB6, 0xFE, 0xFF, 0xFF, 0xFF, 0x07, 0x06, 0x0E, 0x3C, 0xF8, 0xE0, 0x00}; void nmi(void) {} void main(void) { sprites_16x16(); screen_mode_2_text(); paper(0x1); rle2vram (gtsSprites,0x3800); sprites[0].x=100; sprites[0].y=100; sprites[0].colour=11; sprites[0].pattern=0; updatesprites(0,1); cls(); screen_on(); pause(); } I got no error but my sprite looks half-good. Quote Link to comment Share on other sites More sharing options...
+nanochess Posted February 1, 2019 Share Posted February 1, 2019 The rle2vram function expects a compressed data table as input. You should use: put_vram(0x3800, gts_sprites, 32); Quote Link to comment Share on other sites More sharing options...
Kiwi Posted February 1, 2019 Share Posted February 1, 2019 (edited) The rlevram function expects a compressed data table as input. You should use: put_vram(0x3800, gts_sprites, 32); Yup. If you're going to do a huge vram write like loading a full pattern color, sprite, and tables, then you need to use disable_nmi(); before loading sprites. Small write isn't needed for disable nmi but the write should have delay(1) before doing vram write so the raster beam is at the top of the screen, and not the bottom when NMI can occur and mess up the write. Example: screen_mode_2_text(); disable_nmi(); rle2vram(pkSPRITE,0x3800); rle2vram(pkPATTERN,0x0000); duplicate_pattern(); rle2vram(pkCOLOR,0x2000); rle2vram(sampleNAME,0x1800); screen_on(); enable_nmi(); game=0; while(game==1){ delay(1); if joypad_1&FIRE1){a==0;) }//gameloop enable_nmi(); before the gameloop is important. So the OS7 sound engine and the controller function will work. Make sure the game loop have at least 1 delay(1); so it keep the game at 60 fps. It's like WAIT for Intybasic or other basic program. I uses Daniel's tools to make and compress pattern, color, name, and sprite table to RLE. I believe there's graphic tool for the TI/99 and MSX that should be compatible with Colecovision's TMS9918A chip. And I use updatesprites(0,64); instead of updatesprites(0,1); because it became an issue if I needed more than 16 sprites which the all the sprite would flash in cycle. So updatesprites(0,64); fixes that problem. Edited February 1, 2019 by Kiwi Quote Link to comment Share on other sites More sharing options...
ChildOfCv Posted February 1, 2019 Share Posted February 1, 2019 Yup. If you're going to do a huge vram write like loading a full pattern color, sprite, and tables, then you need to use disable_nmi(); before loading sprites. Small write isn't needed for disable nmi but the write should have delay(1) before doing vram write so the raster beam is at the top of the screen, and not the bottom when NMI can occur and mess up the write. Just wondering, is this the case due to the TMS hardware itself, or is it because of what the interrupt processing library does that you may not know about? Looking at the manual, I see no explicit mention of register inconsistency due to the interrupt signal. So it seems to me that if you provided all of the low-level routines yourself instead of linking to a game library, you could be reasonably sure of what everything looks like. For reference, the BIOS NMI routine just jumps to a known location in ROM space, so all you have to do is provide your own code there. Quote Link to comment Share on other sites More sharing options...
Kiwi Posted February 1, 2019 Share Posted February 1, 2019 Just wondering, is this the case due to the TMS hardware itself, or is it because of what the interrupt processing library does that you may not know about? Looking at the manual, I see no explicit mention of register inconsistency due to the interrupt signal. So it seems to me that if you provided all of the low-level routines yourself instead of linking to a game library, you could be reasonably sure of what everything looks like. For reference, the BIOS NMI routine just jumps to a known location in ROM space, so all you have to do is provide your own code there. There is OS7 stuff that the Colecovision BIOS does before running the NMI{} branch. So I'm unsure 100% why VRAM corrupt happens, but I usually guess when it happen and avoid that happening. Programmers who program for this system may run into this issue and I wanted them to be aware about that and not get frustrated. Tursi and other programmer can explain it better than I can. I usually leave that bracket empty, unless I need something happening all across the program or use pause() which the stuff in NMI{} will occur like sprite animation,etc. Quote Link to comment Share on other sites More sharing options...
Serguei2 Posted February 1, 2019 Author Share Posted February 1, 2019 The rle2vram function expects a compressed data table as input. You should use: put_vram(0x3800, gts_sprites, 32); Yup. If you're going to do a huge vram write like loading a full pattern color, sprite, and tables, then you need to use disable_nmi(); before loading sprites. Small write isn't needed for disable nmi but the write should have delay(1) before doing vram write so the raster beam is at the top of the screen, and not the bottom when NMI can occur and mess up the write. Example: screen_mode_2_text(); disable_nmi(); rle2vram(pkSPRITE,0x3800); rle2vram(pkPATTERN,0x0000); duplicate_pattern(); rle2vram(pkCOLOR,0x2000); rle2vram(sampleNAME,0x1800); screen_on(); enable_nmi(); game=0; while(game==1){ delay(1); if joypad_1&FIRE1){a==0;) }//gameloop enable_nmi(); before the gameloop is important. So the OS7 sound engine and the controller function will work. Make sure the game loop have at least 1 delay(1); so it keep the game at 60 fps. It's like WAIT for Intybasic or other basic program. I uses Daniel's tools to make and compress pattern, color, name, and sprite table to RLE. I believe there's graphic tool for the TI/99 and MSX that should be compatible with Colecovision's TMS9918A chip. And I use updatesprites(0,64); instead of updatesprites(0,1); because it became an issue if I needed more than 16 sprites which the all the sprite would flash in cycle. So updatesprites(0,64); fixes that problem. Thanks both of you. It works. I noted this sprite data is uncompressed. It means it takes more resources than compressed sprites. Is there a way to make sprites 16x16 compressed? Or maybe I should stick 8x8 sprites to save ram/vram? Quote Link to comment Share on other sites More sharing options...
ChildOfCv Posted February 1, 2019 Share Posted February 1, 2019 There is OS7 stuff that the Colecovision BIOS does before running the NMI{} branch. So I'm unsure 100% why VRAM corrupt happens, but I usually guess when it happen and avoid that happening. Programmers who program for this system may run into this issue and I wanted them to be aware about that and not get frustrated. Tursi and other programmer can explain it better than I can. I usually leave that bracket empty, unless I need something happening all across the program or use pause() which the stuff in NMI{} will occur like sprite animation,etc. Well, not quite. What the Colecovision BIOS does, according to the programmer's reference absolute listings (see page 12 of appendix J) is jump to the ROM space at label NMI_INT_VECT. Looking back up at page 7, NMI_INT_VECT = 0x8021 which is in your programming space. There is room for 3 bytes there which should be a jump to a convenient location. If you use a library such as Daniel's, it will place its own code at that location which does some convenience stuff for you and eventually calls nmi(). So that's why other stuff happens first for that case: ;; CARTRIDGE HEADER (IN ROM) .area _HEADER(ABS) .org 0x8000 .db 0x55, 0xaa ; no default colecovision title screen => 55 AA .dw 0 ; no copy of sprite table, etc. .dw 0 ; all unused .dw _buffer32 ; work buffer .dw 0 ; ?? .dw start_program ; start address for game coding .db 0xc9,0,0 ; no RST 08 support .db 0xc9,0,0 ; no RST 10 support .db 0xc9,0,0 ; no RST 18 support .db 0xc9,0,0 ; no RST 20 support .db 0xc9,0,0 ; no RST 28 support .db 0xc9,0,0 ; no RST 30 support .db 0xc9,0,0 ; no RST 38 support (spinner) jp _nmi_asm ;; CODE STARTS HERE WITH NMI .area _CODE _nmi_asm: push af ld a,#1 ld (_nmi_flag),a ; set NMI flag ;;; call 0x1fdc ; get VDP status ... Well, the initial call to get VDP status pretty much messes with your TMS regs. Admittedly, you have to read the status in order to enable the next interrupt. So that does answer my original question, at least. As an alternative, if you provide your own ROM space and don't rely on a game library, you have full control over what the NMI does. So theoretically, you could run your entire game loop from the NMI, and then you don't have to worry if the NMI interferes with you. Maybe someone should come up with an Arduino-style library where init() is called once to set up the game and loop() is called by the NMI 1 Quote Link to comment Share on other sites More sharing options...
Kiwi Posted February 2, 2019 Share Posted February 2, 2019 (edited) Maybe someone should come up with an Arduino-style library where init() is called once to set up the game and loop() is called by the NMI I'm ok. Thanks both of you. It works. bandicam 2019-02-01 18-00-48-442.png I noted this sprite data is uncompressed. It means it takes more resources than compressed sprites. Is there a way to make sprites 16x16 compressed? It really depends on the sprite. Each sprite would be 32bytes each. You can RLE compress the sprite sheet. Dictionary-like compression like pletter will compress sprite better than RLE. You do have 32KB of ROM space without bankswitching, so I wouldn't worry about compression until you're close to that limit. I usually have my tileset RLE and sprite compressed. If I need more space, then I'll start pletter compress the graphic data. Or maybe I should stick 8x8 sprites to save ram/vram? You would be saving ROM space. The graphic get uncompress to the VRAM. Edited February 2, 2019 by Kiwi Quote Link to comment Share on other sites More sharing options...
ChildOfCv Posted February 2, 2019 Share Posted February 2, 2019 I noted this sprite data is uncompressed. It means it takes more resources than compressed sprites. Is there a way to make sprites 16x16 compressed? Or maybe I should stick 8x8 sprites to save ram/vram? Thanks both of you. rle2vram is a library function, so you can easily use it for whatever outputs you want. The compression scheme is: ff = end of run. Return. <0x80 = this many literal bytes (literal bytes immediately follow) >=0x80 = (value & 0x7f + 1) repetitions of the next byte. Pretty simple. If you have a lot of repetitive bytes, this helps. Otherwise it will increase the number of bytes you need. He also provides an rle2ram function which decompresses to RAM. Quote Link to comment Share on other sites More sharing options...
Mike Harris Posted February 2, 2019 Share Posted February 2, 2019 (edited) Could always use Z80 Assembly. My game is still under construction, no compression and so far I have 60 rooms, 9 Animated characters and 13 objects and all using 23 16x16 sprite and 200 8x8 tile patterns. so far under 14k I am not trying to toot my own horn. I am just trying to convey that z80 assembler allows more freedom. IF you can figure out the bugs. I had a memory leak that took me a good 8 hours of staring at the same code over and over. Edited February 2, 2019 by Mike Harris Quote Link to comment Share on other sites More sharing options...
Serguei2 Posted February 2, 2019 Author Share Posted February 2, 2019 Could always use Z80 Assembly. My game is still under construction, no compression and so far I have 60 rooms, 9 Animated characters and 13 objects and all using 23 16x16 sprite and 200 8x8 tile patterns. so far under 14k I am not trying to toot my own horn. I am just trying to convey that z80 assembler allows more freedom. IF you can figure out the bugs. I had a memory leak that took me a good 8 hours of staring at the same code over and over. I like making games with basic-like languages. Assemblers are too confuse for me and probably get lost easily. 1 Quote Link to comment 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.