|
ForumsSega Master System / Mark III / Game GearSG-1000 / SC-3000 / SF-7000 / OMV |
Home - Forums - Games - Scans - Maps - Cheats - Credits Music - Videos - Development - Hacks - Translations - Homebrew |
![]() |
Goto page Previous 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 Next |
Author | Message |
---|---|
|
![]() |
24 is "too much", it will eat ± all your vblank time...which is complicated as you also have to update the SAT. (more like 20 or better 18, depend on SAT size to update). For something with no interaction, there's no real problem, but we're speaking about a game.
- SAT update will eat eq. to 6 tiles transfert (for the maximum) ; 64 sprites (64y, 128xt). you can update the sat in active display "BUT" transfert will be far more slower. Keeping as much as possible active display part for calculation (movement, collision, ia, etc) is a good thing. - another point you'll also have to update music/sfx, can be with an int or at the start of the vblank, but must always be at the same scanline, each frame. see captures. - upd 24 tiles + SAT (64 sprites) overflow in active part as the SAT transfert function is not made for active display, some data in SAT are corrupted. - upd 20 tiles + SAT (64 sprites) finish just before the active part The SAT transfert is as fast as possible ; read precalculated data in RAM and send them in VRAM (via bloc of 64 OUTIs). |
|
![]() ![]() |
|
|
![]() |
I realized later I had only streamed 20 in my test later on, but I didn't feel like coming back in here to correct myself. You are correct though. |
|
![]() ![]() |
|
|
![]() |
whoops. you're right. My bad! |
|
![]() ![]() ![]() |
|
|
![]() |
in devkitSMS' crt0 there's a block of 128 OUTIs to perform a copy of 4 tiles (128 bytes) in one single call, or the whole second (X+N) part of the SAT. |
|
![]() ![]() ![]() |
|
|
![]() |
Hello all, I'm trying to started to compile a simple hello world available in example but I've this message and in MEKA I cant see hello world 2/3 and 3/3
Only printf seems to work fine C:\DEV\SMS\examples\hello_sms>sdcc -o hello.ihx -mz80 --data-loc 0xC000 --no-std-crt0 crt0_sms.rel main.rel SMSlib.lib
?ASlink-Warning-Undefined Global '_SMS_print' referenced by module 'main' C:\DEV\SMS\examples\hello_sms>pause Step one and 3 of compilation work fine. I didnt found any information about this error Sorry for this noob question |
|
![]() ![]() |
|
|
![]() |
Can you share your code? I see reference to a symbol SMS_print that doesn't exist at devkitSMS | |
![]() ![]() |
|
|
![]() |
There is an SMS_print function in SMSlib, and the compile stage passed, so it's some kind of problem linking.
Where is SMSlib.lib, relative to your working directory? |
|
![]() ![]() ![]() |
|
|
![]() |
Might be a mistake on my part. I will check that ASAP. |
|
![]() ![]() ![]() |
|
|
![]() |
Um, you're right, it was renamed from SMS_printString 4 months ago... |
|
![]() ![]() |
|
|
![]() |
@JyCet: it was again an issue on my part, sorry. Please download the libraries again, I just uploaded the fix. Thanks for the heads up!
@kusfo: SMS_printString was the name Raphnet proposed, it never got into SMSlib with that name, so there haven't been any rename actually ;) |
|
![]() ![]() ![]() |
|
|
![]() |
Wow thanks all for your support and quick reply , I'll go try that :) |
|
![]() ![]() |
|
|
![]() |
How do I retrieve the tile no in the tilemap for a specific coordinate?
It looks like that I can read that from the VRAM. |
|
![]() ![]() ![]() |
|
|
![]() |
reading from VRAM is a slow operation and may be slower than getting that information from its source in case its source is compressed or that content is generated on the fly, there's a function to read back from VRAM: void SMS_readVRAM(void *dst, unsigned int src, unsigned int size)
note that a single tilemap entry is 2 bytes... |
|
![]() ![]() ![]() |
|
|
![]() |
I just added some other functions and macro for convenience.
So you can retrieve subsequent entries in the tilemap using: unsigned int tile,tile2,tile3;
SMS_readNextTilefromXY(x,y); // x,y are column and row of the tilemap entry we want to read back tile = SMS_getTile(); // retrieve the pointed tile tile2 = SMS_getTile(); // retrieve the next tile tile3 = SMS_getTile(); // retrieve the even subsequent tile ... edit: I also added the SMS_getTileatXY(x,y)
macro to get a single tile from location x,y this is handy if you need to read only one entry, but I do suggest not using that if you need to read multiple successive entries as the aforementioned method is way faster... |
|
![]() ![]() ![]() |
|
|
New ZX7 function broken?
![]() |
Sorry, Sverx, a questions, please:
Have changed my loadtilesfunction from: void LoadTiles(const unsigned char *data,unsigned char bank,unsigned int base,unsigned int size) { // Rom bank pushBank(bank); // Decompress... to datalake (a temp 4kb ram array) SMS_decompressZX7(data,lake); // Load uncompressed tiles SMS_loadTiles(lake,base,size); // Change to previous bank popBank(); } to void LoadTiles(const unsigned char *data,unsigned char bank,unsigned int base,unsigned int size) { // Rom bank pushBank(bank); // Decompress and load, all in one :) thanks Sverx! SMS_loadZX7compressedTilesatAddr (data,TILEtoADDR(base)); // Change to previous bank popBank(); } got this result you can see in the image... ... maybe the unzip function can have some incompatibility with my zx7s??? I suppose does not, because the first function works! ... maybe my frame InterruptHandler function is causing some fault??? has been working right over the last five years! if need something... code from the project, or have a test to share, could be of utility. Regards! Note: SDCC 4.2.0 #13081. smslib: github version from yesterday. |
|
![]() ![]() |
|
|
![]() |
I suspect it's because of: * ======================================================================
* This version only supports match lengths up to 255. This enables * it to be smaller and faster, but it is not 100% compatible. * ===================================================================== did you create your ZX7s using Maxim's BMP2Tile converter? |
|
![]() ![]() ![]() |
|
|
![]() |
Lets see
No. I am not. I am using the zx7 compresor bundled with z88dk, in bin fólder. I supposed that, if the game works with the standard to ram función... Should work as well with the vram one... But maybe i am wrong. I am going to travel now... But in 3 hours will stay at home again and will try with the compressión tool fron Maxim.... Does anyone knows if this compresor respect such limitation??? Regards |
|
![]() ![]() |
|
|
![]() |
it should... Let us know if that way doesn't work correctly either, we'll find some other solution. |
|
![]() ![]() ![]() |
|
|
![]() |
Let's see
I have checked some files, and I have to say that the output from maxim tool (saving tiles with zx7 extension) and from the zx7 compressor are identical (chequed with winmerge, same size, same content, equals :( Looking at the SMSLib code, I found that the only function which seems to work is SMS_decompressZX7. Tested the unsafe and does not work, too. PD: I explain why I think it could be of utility some safe functions to fill tiles... In the new game, I am using more tiles than I have free... so I need to load them without turning off the screen, by example, when I get to a boss which is drawn in the background (about 160 tiles). Actually, I have about 64kb of tilesets saved without compression, and It works without trouble, from bank to vram... But, as I like to keep the rom not so fat, I would like to use a zx7->vram safe function. I cannot use a tmp ram array to do zx7->ram->vram because the ram is almost full with other data (the background tilemap and all the enemies, shoots, player shoots, and other metadata needed to cache some things and keep the things fast, mainly). I have tried to change the function, something like this: #pragma save #pragma disable_warning 85 void SMS_loadZX7compressedTilesatAddr (const void *src, unsigned int dst) __na*ed __sdcccall(1) { __asm ld c, #0xbf ; Set VRAM address di out (c),e out (c),d ei dec c ; data port ld a, #0x80 dzx7tvram_copy_byte_loop: outi ; increments hl inc de dzx7tvram_main_loop: add a, a ; check next bit call z, dzx7tvram_load_bits ; no more bits left? jr nc, dzx7tvram_copy_byte_loop ; next bit indicates either literal or sequence ; determine number of bits used for length (Elias gamma coding) push de ld bc, #0 ld d, b dzx7tvram_len_size_loop: inc d add a, a ; check next bit call z, dzx7tvram_load_bits ; no more bits left? jr nc, dzx7tvram_len_size_loop dzx7tvram_len_value_loop: ; determine length add a, a ; check next bit call z, dzx7tvram_load_bits ; no more bits left? rl c rl b jr c, dzx7tvram_exit ; check end marker dec d jr nz, dzx7tvram_len_value_loop inc bc ; adjust length ; determine offset ld e, (hl) ; load offset flag (1 bit) + offset value (7 bits) inc hl .db #0xcb, #0x33 ; opcode for undocumented instruction "SLL E" aka "SLS E" jr nc, dzx7tvram_offset_end ; if offset flag is set, load 4 extra bits ld d,#0x10 dzx7vram_rld_next_bit: add a, a ; check next bit call z, dzx7tvram_load_bits ; no more bits left? rl d ; insert first bit into D jr nc, dzx7vram_rld_next_bit inc d ; equivalent to adding 128 to DE srl d dzx7tvram_offset_end: rr e ; insert inverted fourth bit into E ; copy previous sequence ex (sp), hl ; store source, restore destination push hl ; store destination sbc hl, de ; HL = destination - offset - 1 pop de ; DE = destination ; ldir vram -> vram push af ; need to preserve carry ; Make hl a read address res 6, h inc c ; ld c, $bf _ldir_vram: di ; 4 = 29, safe on every GG out (c),l out (c),h ei ; 4 inc iy ; 10 dec iy ; 10 in a,(#0xbe) ; 4 (surely safe cycles) = 28, safe on every GG di out (c),e out (c),d ei out (#0xbe),a inc hl ; 6 inc de ; 6 djnz _ldir_vram ; 13 dec c pop af dzx7tvram_exit: pop hl ; restore source address (compressed data) jp nc, dzx7tvram_main_loop dzx7tvram_load_bits: ld a, (hl) ; load another group of 8 bits inc hl rla ret ; because this function is na*ed __endasm; } #pragma restore ... but it jumps to WaitVBlank (maybe jumps to a random pos, I don't know), don't know why, after the SLL. Note: Please, SMSPower admin, remove the work na*ed from the list of spam words!!! |
|
![]() ![]() |
|
|
Test sandbox
![]() |
I have made a simple sandbox to address this,
In the left, the working well version: SMS_decompressZX7(fonttiles_zx7,lake); SMS_loadTiles(lake,8,32*40); SMS_loadTileMapArea (4, 4, fonttilemap_bin,8,5); In the right, the failing one: SMS_loadZX7compressedTilesatAddr_B(fonttiles_zx7,TILEtoADDR(64)); SMS_loadTileMapArea (20, 4, fonttilemapb_bin,8,5); m to build and run (sdcc&emulicious&assets2banks&ihxtosms in path required) Hope it helps! |
|
![]() ![]() |
|
|
![]() |
Have you considered using a different compression method for the failing assets? They won’t save nearly as much ROM space, but they’ll probably work faster and don’t have to use as much RAM (if at all). You can even get as basic as PS compression and it would still be better than uncompressed data. (I have actually never used else and it worked out fine for me.) | |
![]() ![]() |
|
|
![]() |
Yeah!, I know there are so many methods.... in fact... the trouble is not that trouble... I have a 416kb rom, which could fit on 384kb with those assets compressed... but It works with 416kb. I am thinking to continue adding content to the project up to the 27 or march, so maybe the game will reach 464-480kb, even 512... let's see. I think this is an intellectual concern.... Why, having a zx7->ram function in SMS lib already working , it seems it is not possible to have a safe or unsafe function to do this to vram without a temp ram array. In fact, in z88dk we have the src for this functions, which work well (Silver valley, galactic revenge), but, don't know why, when I take the code from z88dk and translate to sdcc (download the sandbox project I uploaded this morning) It seems to fail. I am not an expert at hardware and/or assembly. I am not speaking about the reduced functions which have the 256 bytes limit... In z88dk there are functions without that limit. Consider this as a "nice to have" :D |
|
![]() ![]() |
|
|
![]() |
this is a bummer. :( I will fix the decompressor in SMSlib as soon as possible. |
|
![]() ![]() ![]() |
|
|
![]() |
Hopefully it's fixed now. I don't have a big selection of ZX7 compressed tilesets to run tests on, but the few I have all decompresses correctly.
So, SMS_loadZX7compressedTilesatAddr has been rewritten and I also decided to remove UNSAFE_SMS_loadZX7compressedTilesatAddr so please switch to the 'safe' version should you have used this. Decompression from ZX7 is now even slower, but at least it should work... well, I hope! A sidenote: I suspect I have to spend some time creating a better compression scheme for Master System tilesets... but if you are not so desperate for ROM space and you want a compression scheme that gives you 30% saving (on average) and the fastest decompression currently available, give a look at my stc0. |
|
![]() ![]() ![]() |
|
|
![]() |
I am going to test extensively your new function. I am going to recompile the game and play it (I have about 30 cases of use for this function), and I will report here the result...
I suppose the stc0 will be faster, like you say, but, sincerely, I find rapid enough the zx7 decompresiion for my purposes this year. ... but if, for the next year, I make an shmup, like I want to do someday, a good one, fast and variate, those things should be of importance. Thanks Sverx, knew you would not fail with this!!! |
|
![]() ![]() |
|
|
Not quite
![]() |
Ummm... not quite.
With almost all the images in game, will find artifacts :( I send the image, which is not a font, it is a large image with 108 tiles. In the Sverx version image, you can see the results with the new algorithm. Playing with your code... I have been obtaining better results, but not the proper ones. see the eruiz version. It seems that the length calculation is properly done, and the timing issues i found in your routine are fixed (in an amateurish way) and only fails with the colors when you have to draw a block. Regards #pragma save #pragma disable_warning 85 void SMS_loadZX7compressedTilesatAddr_MIKE (const void *src, unsigned int dst) __naked __sdcccall(1) { /* ===================================================================== * by Einar Saukas, Antonio Villena & Metalbrain * modified for sms vram by aralbrec * modified for asm by Maxim * C wrapper/made interrupt safe/VDP timing safe by sverx * ====================================================================== * This version only supports match lengths up to 255. This enables * it to be smaller and faster, but it is not 100% compatible. ===================================================================== */ __asm ld c,#0xbf ; Set VRAM address di out (c),e out (c),d ei dec c ; data port ld a,#0x80 ; Signal bit for flags byte (1<<7) dzx7s_copy_byte_loop: outi ; copy literal byte inc de dzx7s_main_loop: call dzx7s_next_bit jr nc,dzx7s_copy_byte_loop ; next bit indicates either literal or sequence ; determine number of bits used for length (Elias gamma coding) push de ld bc,#0 ld d,b dzx7s_len_size_loop: inc d call dzx7s_next_bit jr nc,dzx7s_len_size_loop ; determine length dzx7s_len_value_loop: call nc,dzx7s_next_bit rl c rl b jr c,l_ret dzx7t_len_value_start: dec d jr nz,dzx7s_len_value_loop inc bc ; adjust length ; determine offset ld e, (hl) ; load offset flag (1 bit) + offset value (7 bits) inc hl sla e inc e jr nc,dzx7s_offset_end ; if offset flag is set, load 4 extra bits ld d, #0x10 ; bit marker to load 4 bits dzx7s_rld_next_bit: call dzx7s_next_bit rl d ; insert next bit into D jr nc,dzx7s_rld_next_bit ; repeat 4 times, until bit marker is out inc d ; add 128 to DE srl d ; retrieve fourth bit from D dzx7s_offset_end: rr e ; insert fourth bit into E ; copy previous sequence ex (sp),hl ; store source, restore destination push hl ; store destination sbc hl,de ; HL = destination - offset - 1 pop de ; DE = destination push af ; *********************** set 6,d dec bc inc b inc c ld a,c no_adjust: ld c,#0xbf outer_loop: push bc ld b,a ;di inner_loop: nop ; 4 nop ; 4 nop ; 4 = 31 out (c),l ; 11 push bc ; 11 pop bc ; 10 = 32 out (c),h ; 11 ;ei ; inc hl ; 6 ; xor a ; 4 ; ret nz ; 5 nop nop nop nop ; 4 = 30 in a,(#0xbe) ; 11 push bc ; 11 pop bc ; 10 = 32 ;di out (c),e ; 11 push bc ; 11 pop bc ; 10 = 32 out (c),d ; 11 push bc ; 11 pop bc ; 10 = 32 out (#0xbe),a ;11 ;ei inc de ; 6 djnz inner_loop ; 13 ld a,b pop bc djnz outer_loop ;ei ld c,b res 6,d ; *********************** pop af ld c,#0xbe pop hl ; restore source address (compressed data) jr nc, dzx7s_main_loop dzx7s_next_bit: add a,a ; check next bit ret nz ; no more bits left? ld a,(hl) ; load another group of 8 bits inc hl rla ret l_ret: pop hl ret __endasm; } #pragma restore |
|
![]() ![]() |
|
|
![]() Last edited by eruiz00 on Sun Feb 12, 2023 8:19 am; edited 1 time in total |
In fact, I think the trouble should be around the outi loop at the beginning of the function... but I am comparing this to its z88dk counterpart and not feel any strange :(
dzx7s_copy_byte_loop: outi ; copy literal byte inc de dzx7s_main_loop: call dzx7s_next_bit jr nc,dzx7s_copy_byte_loop ; next bit indicates either literal or sequence Note: I was wrong with this. Don't let this fool you! |
|
![]() ![]() |
|
|
![]() |
Yeah!
It seems to be a color displacement and nothing else in the outis... Let's see in the white part of the disk, the colors are changed: from 9,10 to 1,2 in the external side of the glass table, same: from 5,9 to 4,8 outside, the black part: from 5 to a white line (1) and everything else 0 :( This is becoming something like a pastime :D Investigating... |
|
![]() ![]() |
|
|
![]() |
I'll look into this ASAP. A quick test you can do: if the corruption happens in Emulicious but not in MEKA, it's a VDP timing issue. If the corruption happens with both, it's a problem with the algorithm. |
|
![]() ![]() ![]() |
|
|
![]() |
Yeah, in emulitious and meka exactly the same result, Looking at the rendered tiles... i have to say that there are (in my function) displacements, of two types, at least:
displacement in values (+5,-4, +1,...) displacement in offsets (generally +-1 tile row, 4 bytes, in resume) |
|
![]() ![]() |
|
|
![]() |
unfortunately yes, I got no difference with either.
but give me a few minutes, maybe I have an idea... |
|
![]() ![]() ![]() |
|
|
![]() Last edited by sverx on Sun Feb 12, 2023 2:25 pm; edited 1 time in total |
I suspect there is a bug in the original code, I tried fixing it here but I don't see any difference with my own zx7 compressed tilesets (they were not failing decompression before this fix and they are not failing decompression now but maybe it makes some difference with your sets)
edit: if this fails, please PM me one of your zx7 compressed tilesets that fail so to that I can try debugging on that. edit2: attachment removed ... it was buggy anyway. |
|
![]() ![]() ![]() |
|
|
![]() |
Sure!
I am going to test z88dk... let's see... I' ll post results. In the zip, in the assets folder you have all the files. The zx7 one is the tiles.bin compressed by maxim tool |
|
![]() ![]() |
|
|
![]() |
I have remade all the function (from 0 to 100%), from the z88dk source code an I have get the same image, with the same errors as with my function, so It could be possible the z88dk has a bug.... I am goind to check my silvervalley z88dk (2017) _DEVELOPMENT folder to see the code, as I remember this function is what I used that time.
__asm call asm_sms_vram_write_de ld c, #0xbe ld a, #0x80 dzx7s_copy_byte_loop: outi inc de dzx7s_main_loop: call dzx7s_next_bit jr nc, dzx7s_copy_byte_loop ; next bit indicates either literal or sequence ; determine number of bits used for length (Elias gamma coding) push de ld bc, #0 ld d, b dzx7s_len_size_loop: inc d call dzx7s_next_bit jr nc, dzx7s_len_size_loop ; determine length dzx7s_len_value_loop: call nc, dzx7s_next_bit rl c rl b jp c, l_ret dec d jr nz, dzx7s_len_value_loop inc bc ; adjust length ; determine offset ld e, (hl) ; load offset flag (1 bit) + offset value (7 bits) inc hl sla e inc e jr nc, dzx7s_offset_end ; if offset flag is set, load 4 extra bits ld d, #0x10 ; bit marker to load 4 bits dzx7s_rld_next_bit: call dzx7s_next_bit rl d ; insert next bit into D jr nc, dzx7s_rld_next_bit ; repeat 4 times, until bit marker is out inc d ; add 128 to DE srl d ; retrieve fourth bit from D dzx7s_offset_end: rr e ; insert fourth bit into E ; copy previous sequence ex (sp), hl ; store source, restore destination push hl ; store destination sbc hl, de ; HL = destination - offset - 1 pop de ; DE = destination push af call asm_sms_memcpy_vram_to_vram pop af ld c, #0xbe pop hl ; restore source address (compressed data) jr nc, dzx7s_main_loop dzx7s_next_bit: add a, a ; check next bit ret nz ; no more bits left? ld a, (hl) ; load another group of 8 bits inc hl rla ret l_ret: pop hl ret asm_sms_vram_write_de: ; enter : de = vram address ; ; uses : af di ld a,e out (#0xbf),a ld a,d or #0x40 out (#0xbf),a ei ret asm_sms_memcpy_vram_to_vram: ; memcpy within vram ; ; enter : hl = void *src in vram ; de = void *dst in vram ; bc = unsigned int n > 0 ; ; exit : hl = void *src, &byte after last read ; de = void *dst, &byte after last written ; bc = 0 ; ; uses : af, bc, de, hl set 6,d dec bc inc b inc c ld a,c no_adjust: ld c, #0xbf outer_loop: push bc ld b,a di inner_loop: ; must yield opportunities for an interrupt to occur out (c),l out (c),h inc hl xor a ret nz in a,(#0xbe) ei nop nop di out (c),e out (c),d out (#0xbe),a inc de djnz inner_loop ld a,b pop bc djnz outer_loop ei ld c,b res 6,d ret __endasm; |
|
![]() ![]() |
|
|
![]() |
Yeah, in Galactic revenge I am using
// Decompress sms_dzx7_standard_vram(psg,(base<<5)); and it works (it uses my z88dk 2017 compiler... I am going to check the code) |
|
![]() ![]() |
|
|
![]() |
OK I see the same issue you're seeing now, and my fix doesn't fix anything :|
So, to recap: - Maxim's BMP2Tile exporter outputs exactly the same ZX7 as the 'official' compressor tool, so the issue does not lie within the exporter - The issue occurs both on Emulicious and MEKA, so it's not about VDP timing constraints (if that was the issue, it would just work perfectly on MEKA and not work fine on Emulicious) So it looks like the new code (that should give complete ZX7 compatibility) fails - but is the z88dk code working correctly at this point? I wonder... |
|
![]() ![]() ![]() |
|
|
![]() |
I resume:
If i copy the z88dk (the old version) src code in _DEVELOPMENT folder, it will work exactly as our sdcc version (FAIL). I have compiled the code replacing sdcc calls with z88dk ones, and build with z88dk, and It works. So.... I suspect the z88dk compiler uses a binary, instead of the sources of the _DEVELOPMENT folder, a binary which works well.. I am sending the z88dk bulit version, which works OK :D I think we could build a proper function in SDCC, using the asm from the Z88DK build. PD Post the main.sym file SORRY, my fault.. I have sent the sdcc version.... Shame that the z88dk compiler does not include the library -> asm code in the asm file... maybe from Emulicious Debug window??? |
|
![]() ![]() |
|
|
![]() |
I have debugged the full function of the working z88dk version, and have to say:
1. The code in the SMS_loadZX7compressedTilesatAddr_MIKE 2. The code in the _DEVELOPMENT files of z88dk, for the sms_dzx7_standard_vram asm_sms_memcpy_vram_to_vram asm_sms_vram_write_de 3. The code debugged in the working z88dk version of Emulicious They, all, the three fonts of code... ARE EQUALS!!!! ...but the sdcc compiled version does not work... and the z88dk does. Oh my god! pd. maybe the constants for the ports in the out functions are bad??? I mean, in the z88dk the emulicious tells you they are 0xbf, by example (for the command)... but in the sdcc i am seeing $c5 for the same line... (and they are constants!) |
|
![]() ![]() |
|
|
![]() |
Fixed now - at least it works with the test image you sent me.
You can download the library again from GitHub. It turned out the issue was with the VRAM destination address. With SMSlib you would pass an address that had the VRAM write bit set. Now I'm explicitly handling that so it does no longer matter. I hope this works for every other ZX7 compressed file you have! |
|
![]() ![]() ![]() |
|
|
Not quite
![]() |
Ummmm....
Your new version from half an hour ago DOES NOT WORK!!!!!!! I mean, artifacts... but, hey, I now that, after this weekend, consideer myself an Assembly & Master System VDP tech architect, I have fixed your pushed function: __asm ld c,#0xbf ; VDP control port set 6,d ; set VRAM write bit di ; set VRAM address out (c),e out (c),d ei res 6,d ; remove VRAM write bit dec c ; data port ld a,#0x80 ; Signal bit for flags byte (1<<7) dzx7s_copy_byte_loop: outi ; copy literal byte inc de dzx7s_main_loop: call dzx7s_next_bit jr nc,dzx7s_copy_byte_loop ; next bit indicates either literal or sequence ; determine number of bits used for length (Elias gamma coding) push de ld bc,#0 ld d,b dzx7s_len_size_loop: inc d call dzx7s_next_bit jr nc,dzx7s_len_size_loop ; determine length dzx7s_len_value_loop: call nc,dzx7s_next_bit rl c rl b jp c,l_ret dec d jr nz,dzx7s_len_value_loop inc bc ; adjust length ; determine offset ld e, (hl) ; load offset flag (1 bit) + offset value (7 bits) inc hl sla e inc e jr nc,dzx7s_offset_end ; if offset flag is set, load 4 extra bits ld d, #0x10 ; bit marker to load 4 bits dzx7s_rld_next_bit: call dzx7s_next_bit rl d ; insert next bit into D jr nc,dzx7s_rld_next_bit ; repeat 4 times, until bit marker is out inc d ; add 128 to DE srl d ; retrieve fourth bit from D dzx7s_offset_end: rr e ; insert fourth bit into E ; copy previous sequence ex (sp),hl ; store source, restore destination push hl ; store destination sbc hl,de ; HL = destination - offset - 1 pop de ; DE = destination push af ; *********************** set 6,d dec bc inc b inc c ld a,c ld c,#0xbf outer_loop: push bc ld b,a inner_loop: nop ; 4 nop ; 4 di ; 4 = 27 (safe on every Game Gear) out (c),l push bc pop bc out (c),h push bc pop bc ei ; 4 inc hl ; 6 xor a ; 4 ret nz ; 5 (this ret will never happen, it is just to wait 5 cycles) nop ; 4 nop ; 4 = 27 (safe on every Game Gear) in a,(#0xbe) di push bc pop bc out (c),e push bc pop bc out (c),d ei out (#0xbe),a inc de ; 6 djnz inner_loop ; 13 ld a,b pop bc djnz outer_loop ld c,b res 6,d ; *********************** pop af ld c,#0xbe pop hl ; restore source address (compressed data) jr nc, dzx7s_main_loop dzx7s_next_bit: add a,a ; check next bit ret nz ; no more bits left? ld a,(hl) ; load another group of 8 bits inc hl rla ret l_ret: pop hl ret __endasm; I only have put some push&pop between outs to keep the 29 cycles between vdp opcodes. If you want, I send you the failing code and the working one, to check, but the function I have posted here it works, definitely. Regards... and thanks for your quick response! |
|
![]() ![]() |
|
|
![]() |
OK so this is definitely very weird - it doesn't make much sense.
First, there's no delay needed between writes to the command port so those out (c),l
push bc pop bc out (c),h and out (c),e
push bc pop bc out (c),d won't help - try to remove them and see if it still works. Also, Emulicious doesn't complain of any invalid VDP access... |
|
![]() ![]() ![]() |
|
|
![]() |
Let's see...
I send you a new project. If you run the sms file (built from the main.c, with the m.bat script) the top image (faulty) is with your github smslib.lib file the bottom image is with the function included in main.c, with those push-pop between outs, Maybe an emulicious bug??? (things get serious :D) |
|
![]() ![]() |
|
|
![]() |
Even worst xD, if I change the order of the tiles decompression (first the eruiz00 function, and second the smslib.lib file) the image produced by the smslib.lib is slightly different to the image generated if it is be called first...
pd. I dont want to make your life a drama, I consider you a good friend. If this is impossible to fix, I will switch to stm/psgcomp, or return to the temp ram array for the unzipping. Was only curiosity for the zx7 vram issue.... xD |
|
![]() ![]() |
|
|
![]() |
I am VERY VERY very puzzled. I could make the decompression break on MEKA (which doesn't enforce any VDP timing constraints) just by adding NOPs.
There's definitely something weird going on with this code. It's getting really interesting :D :D |
|
![]() ![]() ![]() |
|
|
![]() |
Isn’t it the same issue we discussed elsewhere - namely that the code does not set the VRAM address before each read or write, while interrupts are disabled; so the state of the VDP is liable to change at any time? For example, if you write the first byte of a write address, then an interrupt comes and reads the status; the second address write won’t get the intended result?
The only way to make interrupt safe code is to disable interrupts either the whole time, or around set address/read or write, on the grounds that an interrupt may leave the VDP in an undefined state. |
|
![]() ![]() ![]() |
|
|
![]() |
I also suspected some problem coming from the interrupts, more so because, as I said, I could make the image corrupt by simply adding NOPs to the code :|
But... I don't get what could be wrong. I have DI/EI to ensure the two writes to the VDP address port are NEVER interrupted and I also make sure not to read/write to VDP in my interrupt (apart from reading the status port which, as said, can't happen between the two writes). Also I double checked my interrupts aren't trashing any CPU register by mistake. I push (and later pop) AF and HL and I'm using only those in my ISR. So - that's why I'm so puzzled and I can't really figure out what's going on. :| edit: I just made a quick test running the whole code with disabled interrupt... I get corruption on MEKA anyway! |
|
![]() ![]() ![]() |
|
|
![]() |
So now I could make that work perfectly with Emulicious, but I'm still getting corruption on MEKA (a few pixels, occasionally).
BTW, the problem seems like you can't write to the VDP control port too soon after reading from the data port. I actually didn't know there was this issue, I thought once you wait enough for the data to be ready in the VDP buffer then the IN operation wouldn't cause the VDP to be unavailable again later. But indeed it makes sense, as after the CPU performs the IN operation, the VDP has to read the next byte from VRAM. So I updated the library again, since it's working in Emulicious, and I will pretend the issue with MEKA it's a bug there... unless proven otherwise. |
|
![]() ![]() ![]() |
|
|
![]() |
I get corrupted pixels in Meka sometimes too... | |
![]() ![]() ![]() |
|
|
![]() |
Even worst... When I use the working función into the game itself... I get random errors...(each time the game renders a energy capsule... If it's diferent than the previous (there are two colors)... Will load the four tiles fron the zx7... And It fails... I have a interrupt handler with the music playing and real time frame based unsafe update of Up to 12 sprites for the player...
The fact is that, if i use the zx7 to ram... And then the sms_loadtiles function everyrhing works perfect!!! |
|
![]() ![]() |
|
|
![]() |
I start to suspect we have a different issue here... Are you updating the sprites for the player in a interrupt handler? If so, this is the issue. If the interrupt handler messes with the VDP and if it interrupts another function that messes with it too, that's when the trouble begins. The VDP has no 'context' and thus a transfer can't be interrupted by another operation and resumed later. The only way to make such a thing work would be to make all the transfers uninterruptible (or at least broken in atomic chunks) and that's not what SMSlib does as such an approach is very heavy and rarely useful. What I suggest if you still need to load tiles to VRAM while the interrupts are on, is to stagger the loading into small chunks that can be performed in a short time so that the interrupting code won't ever run on them. |
|
![]() ![]() ![]() |
![]() |
Goto page Previous 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 Next |