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 - devkitSMS - develop your homebrew in C

Reply to topic Goto page Previous  1, 2, 3 ... 9, 10, 11, 12, 13, 14, 15, 16  Next
Author Message
  • Joined: 04 Jul 2010
  • Posts: 539
  • Location: Angers, France
Reply with quote
Post Posted: Sat Dec 10, 2022 10:49 am
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).
Capture d’écran 2022-12-10 à 11.32.31.png (14.12 KB)
Transfert 20 tiles + SAT 64 sprites
Capture d’écran 2022-12-10 à 11.32.31.png
Capture d’écran 2022-12-10 à 11.32.12.png (13.31 KB)
Transfert 24 tiles + SAT 64 sprites
Capture d’écran 2022-12-10 à 11.32.12.png

  View user's profile Send private message
  • Joined: 18 Jul 2020
  • Posts: 367
Reply with quote
Post Posted: Sat Dec 10, 2022 1:44 pm
ichigobankai wrote
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.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Dec 10, 2022 5:25 pm
willbritton wrote
sverx wrote
...but copying a full SAT (64 sprites) is roughly equivalent to copy data worth 3 tiles

Just checking for the record, shouldn't this be 6 tiles rather than 3 (192/32)?


whoops. you're right. My bad!
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Dec 10, 2022 5:30 pm
ichigobankai wrote
read precalculated data in RAM and send them in VRAM (via bloc of 64 OUTIs).


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.
  View user's profile Send private message Visit poster's website
  • Joined: 30 Dec 2022
  • Posts: 2
  • Location: France
Reply with quote
Post Posted: Fri Dec 30, 2022 5:18 pm
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
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Fri Dec 30, 2022 6:47 pm
Can you share your code? I see reference to a symbol SMS_print that doesn't exist at devkitSMS
  View user's profile Send private message
  • Joined: 06 Mar 2022
  • Posts: 596
  • Location: London, UK
Reply with quote
Post Posted: Fri Dec 30, 2022 7:06 pm
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?
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Dec 30, 2022 7:46 pm
JyCet wrote
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


Might be a mistake on my part. I will check that ASAP.
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Sat Dec 31, 2022 6:45 am
willbritton wrote
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?


Um, you're right, it was renamed from SMS_printString 4 months ago...
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Dec 31, 2022 9:34 am
@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 ;)
  View user's profile Send private message Visit poster's website
  • Joined: 30 Dec 2022
  • Posts: 2
  • Location: France
Reply with quote
Post Posted: Sat Dec 31, 2022 10:51 am
sverx wrote
@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 :)
  View user's profile Send private message
  • Joined: 09 Jan 2012
  • Posts: 67
  • Location: Germany
Reply with quote
Post Posted: Thu Feb 02, 2023 11:10 pm
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.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Feb 03, 2023 8:44 am
dark wrote
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...
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Feb 07, 2023 2:44 pm
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...
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
New ZX7 function broken?
Post Posted: Fri Feb 10, 2023 3:55 pm
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.
Captura de pantalla_20230210_164458.png (12.7 KB)
Broken screen
Captura de pantalla_20230210_164458.png
Captura de pantalla_20230210_165523.png (6.92 KB)
Previous screen
Captura de pantalla_20230210_165523.png
game.zip (25.02 KB)
The map file

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Feb 10, 2023 4:03 pm
eruiz00 wrote
... maybe the unzip function can have some incompatibility with my zx7s??? I suppose does not, because the first function works!


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?
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Fri Feb 10, 2023 4:27 pm
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
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Feb 10, 2023 5:03 pm
eruiz00 wrote
will try with the compressión tool fron Maxim.... Does anyone knows if this compresor respect such limitation?


it should...

Let us know if that way doesn't work correctly either, we'll find some other solution.
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Fri Feb 10, 2023 10:52 pm
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!!!
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Test sandbox
Post Posted: Sat Feb 11, 2023 7:39 am
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!
Captura de pantalla_20230211_082949.png (14.72 KB)
Comparative
Captura de pantalla_20230211_082949.png
zx7test.rar (22.31 KB)
program

  View user's profile Send private message
  • Joined: 01 Feb 2014
  • Posts: 847
Reply with quote
Post Posted: Sat Feb 11, 2023 2:50 pm
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.)
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sat Feb 11, 2023 3:04 pm
Kagesan wrote
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
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Feb 11, 2023 4:21 pm
eruiz00 wrote
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 :(


this is a bummer. :(

I will fix the decompressor in SMSlib as soon as possible.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Feb 11, 2023 5:37 pm
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.
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sat Feb 11, 2023 8:03 pm
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!!!
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Not quite
Post Posted: Sun Feb 12, 2023 7:10 am
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


font.png (2.21 KB)
Original image
font.png
Captura de pantalla_20230212_000717.png (25.5 KB)
SVERX VERSION
Captura de pantalla_20230212_000717.png
Captura de pantalla_20230212_000916.png (25.34 KB)
eruiz00 version
Captura de pantalla_20230212_000916.png

  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 12, 2023 7:42 am
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!
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 12, 2023 7:49 am
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...
Captura de pantalla_20230212_084530.png (53.62 KB)
Color displacement
Captura de pantalla_20230212_084530.png

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Feb 12, 2023 9:50 am
eruiz00 wrote
Ummm... not quite.
With almost all the images in game, will find artifacts :(


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.
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 12, 2023 10:02 am
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)
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Feb 12, 2023 10:18 am
unfortunately yes, I got no difference with either.

but give me a few minutes, maybe I have an idea...
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Feb 12, 2023 10:25 am
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.
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 12, 2023 10:34 am
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
zx7test.rar (98.06 KB)

  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 12, 2023 10:41 am
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;
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 12, 2023 10:44 am
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)
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Feb 12, 2023 11:00 am
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...
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 12, 2023 11:22 am
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???
zx7testZ88DK.zip (19.01 KB)

  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 12, 2023 11:43 am
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!)
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Feb 12, 2023 2:24 pm
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!
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Not quite
Post Posted: Sun Feb 12, 2023 3:00 pm
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!
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Feb 12, 2023 3:25 pm
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...
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 12, 2023 3:48 pm
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)
newtest.rar (31.38 KB)
new project with Sverx function and eruiz00 function

  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 12, 2023 3:54 pm
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
Captura de pantalla_20230212_165041.png (23.31 KB)
First eruiz00, Second Sverx smslib.lib
Captura de pantalla_20230212_165041.png

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Feb 12, 2023 3:57 pm
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
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14687
  • Location: London
Reply with quote
Post Posted: Sun Feb 12, 2023 4:52 pm
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.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Feb 12, 2023 5:09 pm
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!
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Feb 12, 2023 5:41 pm
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.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14687
  • Location: London
Reply with quote
Post Posted: Sun Feb 12, 2023 6:02 pm
I get corrupted pixels in Meka sometimes too...
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 545
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 12, 2023 6:57 pm
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!!!
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Feb 13, 2023 9:08 am
eruiz00 wrote
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.
  View user's profile Send private message Visit poster's website
Reply to topic Goto page Previous  1, 2, 3 ... 9, 10, 11, 12, 13, 14, 15, 16  Next



Back to the top of this page

Back to SMS Power!