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 - How about developing SG games in C?

Reply to topic Goto page 1, 2  Next
Author Message
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
How about developing SG games in C?
Post Posted: Mon Nov 30, 2015 1:03 pm
I love the SG, and I love the fact that is relatively easy to port from SG to Coleco and MSX1. I've been studying the VDP and I find it quite straightforward to understand, so I thought why not?

Writing a simple, barebones library to handle uploading stuff to VRAM, placing patterns in the nametable and moving sprites around shouldn't be very hard, but I'm stuck at the beginning:

- Creating a suitable crt0.
- Building the actual cartridge image files.

I understand that you organize segments in the crt0 file, place the header and stuff like that, but I'm completely lost. I'm good at reading docs, though. I have the excelent work by sverx on the sms to start with, it should be somewhat simmilar taking in account that the sms is backwards compatible and the sg is a much less complex machine.

About sound/music, I understand that PSGlib should work as the sound chip is the same?

Any pointers?
  View user's profile Send private message
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Mon Nov 30, 2015 1:20 pm
The VDP chips are so simmilar that many portions of sverx's SMSlib could be used without having to change a comma.
  View user's profile Send private message
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Mon Nov 30, 2015 2:07 pm
I'm designing the VRAM memory map. If I'm not mistaken, this should work (complete with inital registers - I'm following the path set by sverx so I can reuse most of his code for the SMS):

// My VRAM memory map:
/*
    $0000   +--------+
            |   PG   |  ($1800 bytes, pattern generator table)
    $1800   +--------+
            |   PN   |  ($0300 bytes, nametable)
    $1B00   +--------+       
            |   SA   |  ($0080 bytes, sprite attribute table)
    $1B80   +--------+
            |        |  ($0480 bytes free)
    $2000   +--------+
            |   CT   |  ($1800 bytes, colour table)
    $3800   +--------+
            |   SG   |  ($0800 bytes, sprite generator table)
            +--------+
*/

// TMS9918A registers
const unsigned char VDPReg_init [11] = {
    0x02,       // Mode 2
    0xe2,       // 16K, ON, INT, -, -, -, 16x16, -
    0x06,       // PN bits 13-10 = 0 1 1 0         (address = $1800)
    0xff,       // CT bits 13-7  = 1 x x x x x x x (address = $2000)
    0x03,       // PG bits 13-11 = 0 x x           (address = $0000)
    0x36,       // SA bits 13-7  = 0 1 1 0 1 1 0   (address = $1B00)
    0x07,       // SG bits 13-11 = 1 1 1           (address = $3800)
    0xf1        // text / backdrop
};
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Nov 30, 2015 4:25 pm
I'm a complete SG newbie but -if hardware is very similar- we could just add some conditional defines and make SMSlib suitable for SG programming too.
If you can provide a comprehensive list of hardware differences we can work from there :)
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14738
  • Location: London
Reply with quote
Post Posted: Mon Nov 30, 2015 5:17 pm
Differences are:

- Only legacy video modes are available. You may not support these at all yet, but they work identically on the Master System.
- The sound chip has a different noise pattern
- You only have 1KB RAM

That's pretty much it until you start complicating it by wanting SC-3000 support.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Nov 30, 2015 8:49 pm
You mean same I/O ports, ROM/RAM maps, mappers, etc?
Legacy video modes is something I didn't plan to add to SMSlib, but if there's demand for this, why not?
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Tue Dec 01, 2015 8:27 am
Last edited by na_th_an on Tue Dec 01, 2015 8:31 am; edited 1 time in total
As far as I know, the SG and the SMS are so simmilar than even a barebones SMSlib with legacy video modes support and a couple of changes would work. Controllers are accessed through the same ports. PSG is mapped to the same ports. Even RAM is mapped in the same place, but there's just 2Kb of it.

I don't know about mappers - I know there are games which use mappers for the SG, but I don't know if the standard SEGA mapper was used, I'd say most are custom mappers, but correct me if I'm wrong. Anyways, the games I have in mind would fit in 32K :)

Graphics-wise, the only real difference is how pattern data is organized, that sprite pattern data is a separata 2Kb table, and that there are just 32 sprites and the attribute table has a different layout.

Ports are the same, VDP registers are a subset of those found in the SMS, and the PSG works the same (I didn't know about the different noise pattern, but I consider that difference minor).

My original plans were to take SMSlib and substitute the functions covering the differences, mainly:

- Pattern uploading to VRAM (there's 256 patterns per screen third, with two separate 8 byte bitmaps: one in the pattern table, one in the colour table; patterns used for sprites are on a different table, 256 patterns, 1 bit per pixel, 8 bytes per pattern).
- Sprite creation and placement (Sprite Attribute table is different - but even the "don't process any more sprites in the SAT" special value works, Y = $D0)
- Initialization (register configuration for the memory map posted above, MODE 2 on, 16x16 sprites, not magnified).

I was aiming for a clean version, with plans of proposing a merge using #defines once I had everything working.

... But I'm lacking basic knowledge on how to build the crt0 or generate the .sg cartridge image files.

I'm interested on the SG 'cause I love the machine, and because of the fact that porting to the SMS, the MSX1, or the Coleco is a piece of cake.
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14738
  • Location: London
Reply with quote
Post Posted: Tue Dec 01, 2015 8:30 am
Careful, the SC-3000 has 2KB of RAM but the SG-1000 only 1KB.

I think you might need to add some PPI initialisation to the crt0, too. I'm not very familiar with that part.
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Tue Dec 01, 2015 8:32 am
It seems that most of the documentation I've read have the SG-1000 and the SC-3000 mixed, then :-/

I can work with 1Kb, anyways :D
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Dec 01, 2015 9:14 am
na_th_an wrote
I was aiming for a clean version, with plans of proposing a merge using #defines once I had everything working.

... But I'm lacking basic knowledge on how to build the crt0 or generate the .sg cartridge image files.


Ok, so you might start from my SMSlib, remove what's unneeded there and change the things that are different so that you end up with, say, a SGlib.c and SGlib.h with SG specific functions.

As for crt0 and image files, if the hardware is very similar, I guess you can use devkitSMS crt0 and ihx2sms utility too.
Does SG Z80 processor boots up at $0000? Does it work in Interrupt Mode 1 only? Are IRQ and NMI mapped to the usual addresses? Then you might just change two things in crt0: stack pointer start value and the size of RAM memory you need to initialize:

[...]
   .module crt0
   .globl   _main

   .area   _HEADER (ABS)
   ;; Reset vector
   .org    0
   di            ; disable interrupt
        im 1            ; interrupt mode 1 (this won't change)
   jp   init

        .org    0x38                    ; handle IRQ
        jp _SMS_isr

        .org     0x66                   ; handle NMI
        jp _SMS_nmi_isr

   .org    0x70
init:
        ld sp, #0xdff0         ; set stack pointer at end of RAM   ***CHANGE THIS***

; MAPPER INITALIZATION - BEGIN

        ld de, #0xfffc         ; initialize mappers
        xor a            
        ld (de),a         ; [0xfffc]=$00
        ld b,#3
mapper_loop:
        inc de
        ld (de),a         ; [0xfffd]=$00,[0xfffe]=$01,[0xffff]=$02
        inc a
        djnz mapper_loop

; MAPPER INITALIZATION - END
       
        xor a            ; clear RAM (to value 0x00)
        ld hl,#0xc000         ;   by setting value 0 to $c000 and
   ld (hl),a         ;   to $c000 and
        ld de,#0xc001         ;   copying (LDIR) it to next byte
        ld bc,#0x1ff0         ;   for 8 KB minus 16 bytes   ***CHANGE THIS***
        ldir            ;   do that
[...]


Also, if mappers work in a different manner, and if you don't probably need them, you could remove initialization (I marked that block in the code)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Dec 01, 2015 9:18 am
Maxim wrote
I think you might need to add some PPI initialisation to the crt0, too.


PPI? :|
  View user's profile Send private message Visit poster's website
  • Joined: 31 Oct 2007
  • Posts: 853
  • Location: Estonia, Rapla city
Reply with quote
Post Posted: Tue Dec 01, 2015 10:48 am
the good old 8255 chip. It is in charge of keyboard and couple other functions on the SC.
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Tue Dec 01, 2015 11:24 am
Thanks for the pointers. I'll give it a go. I'm currently researching the .sg file format, it should be simmilar to the .sms file format... or the same. That would make things easier ;)
  View user's profile Send private message
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Tue Dec 01, 2015 11:37 am
I've been reading emulator sources as I can't find any docs, and it seems that SMS, GG, and SG ROM images are all straight binary dumps with an optional 512 bytes header (which is there for legacy reasons and skipped by emulators).

So I guess I can use ihx2sms.

I'll keep you posted.

EDIT: A question of complete noobishness: while I'm at it, I'm assembling the crt0.s file with...

sdasz80 -o -g lib\crt0_sg1000.s


Is that correct?
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Dec 01, 2015 12:34 pm
TmEE wrote
the good old 8255 chip. It is in charge of keyboard and couple other functions on the SC.


Ok, then I guess we need some init code in crt0. Any snippet?

na_th_an wrote

sdasz80 -o -g lib\crt0_sg1000.s

Is that correct?


It's fine. Also ihx2sms should work fine, as there's no strange header needed into the ROM (as for the SMS).
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Tue Dec 01, 2015 1:11 pm
Heh - I'm almost there. Got image and something which may look like what I'm trying to paint, but still bugged.

Maybe it's because the tms9918a needs the interrupts off when writing to the VRAM. I'll check that.

EDIT: It wasn't that. I must be missing something. The pattern data I upload to VRAM seems wrong. It's like it's writing a zero right after every bit pattern. That, or I got the format wrong. I'll double-check.

EDIT 2: Nah, that was just me being stupid. Heh. Now on to the sprites (already done, just need to test)
hey!.png (7.02 KB)
hey!.png

  View user's profile Send private message
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Tue Dec 01, 2015 2:06 pm
Well, tested tiles, sprites and controller. Everything seems to work fine :)

Take a glance :D

You have to rename crt0_sg1000.rel to cr0.rel and place it in you sdcc\lib\z80 directory. I tried to compile using the "--no-std-crt0" command line switch but it didn't work - it compiled fine but ni ihx file was generated (don't know why).

I just added the stuff to SMSlib, using a define. "TARGET_SG" enables the changes. I don't have time right now to document them, but they are quite straightforward.

Next thing to test is music.
fist-test-sg1000.zip (19.03 KB)

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Dec 01, 2015 9:33 pm
Nice and very interesting result! :)

na_th_an wrote
I tried to compile using the "--no-std-crt0" command line switch but it didn't work.


I couldn't make that work either, when I first tried long ago. But I guess I should spend some time understanding how to fix that, if the devkit is going to provide two distinct crt0.rel, one for each target system (well, three if you count GG too...)
[edit: no, I forgot I made that work, actually]

As for your own SMSlib, I wait your final version and I'll work on seamlessly integrate the SG parts into the devkit. Also, it might be interesting to add the functions that work on legacy video modes on the SMS, but I need some more time to understand how these modes work.

(Are you addressing only one specific legacy video mode?)
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Wed Dec 02, 2015 7:00 am
Yes, I'm addressing Mode 2 here. Mode 0 and 1 are not very interesting as the capabilities are quite limited (Mode 1 is a "text mode" and doesn't even have sprites). I understand that modes 0 and 1 were designed with computers which mounted the TMS9918a with just 4Kb of VRAM in mind.

Those could be supported for the sake of completeness (they are farily less complex than Mode 2), but I don't find them very interesting (one could argue that Mode 2 isn't very interesting, either).

The SMSlib version included does integrate the new code with the SMS code via #defines, but I reckon the integration has been made in a quick'n'dirty-make-it-work fashion, it should be reworked.

The problem with integrating Mode 2 to be used with the SMS is that the patters are stored in a different way, plus the nametable is byte-based rather than word-based. Maybe a full integration would cost in efficiency?

That said, the SMS and the SG are so simmilar (and compatible!), so using the library configured as "TARGET_SG" and the SMS crt0 would produce completely usable SMS binaries working in Mode 2. Indeed, the .SG files as they are (complete with the SG-1000 crt0) work straight away in the SMS (at least in the emulator).

Mode 2, in a nutshell, can be described as:

- 768 bytes nametable, 1 byte per tile, 32x24
- Each tile is 8x8 pixels. Each pixel line has two distinct colours, being named "foreground" and "background".
- Each tile is rendered by the VDP looking up two distinct tables: the pattern generator table, and the colour generator table.
- The pattern generator table has 8 bytes per pattern. Each byte describe a 8 pixel row in the pattern. bit 1 is rendered as the foreground colour, bit 0 as the background colour.
- There's a separate pair of 256 patterns PGT and CGT for each third of the screen!
- The colour generator table is assigned 1:1 with the pattern generator table. There's 8 bytes per pattern. Each byte describes colour information for an 8 pixel row in the pattern. bits 7-4 define the foreground colour, bits 3-0 the background colour.
- There are 15 fixed colours 1 to 15. 0 means transparent. Pixels of colour 0 show the backdrop colour (register 0x07) or an external analog image (genlock - unavailable in the SG-1000).
- There are 32 sprites, max 4 per line. They can be 8x8 or 16x16 (via register 0x01), or magnified (same register).
- Sprites are rendered in one of the 15 colours.
- There's a separate 256 pattern table for sprites. For 16x16 sprites 4 subsequent patterns are used, column-ordered.
- Each pattern in the sprite table is 1bit as well: 8 bytes per pattern. bit 1 is rendered using the sprite colour, bit 0 is transparent.
- Y = 208 means "don't process more sprites", as in the SMS.
- There's HW sprite collision detection plus a sprite overflow flag, but I have to still research them [*]

And that's about it.

The intersting thing is that you have a different 256 set of paterns for each screen third, plus 256 patterns for the sprite. That makes a grand total of 1024 different patterns.

Having 256 patterns per third makes 768 for the whole screen, that's a different pattern for each cell in the nametable.

If you examine the silly demo I posted, I upload the same pattern and colour information for all three thirds so I have the patterns available anywhere on screen.

[*] Max 4 sprites per line is very few. I've thought of a quick'n'dirty solution I shall implement in my games, though: If sprite overflow flag is on, only even sprites in my list of sprites are added to the sat on even frames, odd sprites on odd frames. That will produce flicker (alternating odd and even sprites) but should help avoid the disappearance of sprites. I think the best way to achieve this is inside the addSprite functions in the library, so maybe I will add a #define to activate or deactivate such feature in SG mode.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Dec 02, 2015 9:16 am
I'm wondering if it's better to create a separate lib (SGlib?) for all these functions or if it's better to integrate all this into SMSlib using functions with different names, as the SMS also could use Mode2 eventually...
So a TARGET_SG define would remove the functions that can't work on a SG, and some other define, NO_MODE2_SUPPORT (or such) can be eventually used to remove the functions that address this specific mode.
Still, there are other 3 'official' legacy mode (plus some 'unofficial'), and we might want to use these as well...

Anyway I guess I'll first see the result of your efforts :D
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Wed Dec 02, 2015 9:33 am
I certainly don't know what would be better. I doubt anybody wants to create a SMS game using Mode 2, but I could be wrong.

Separating the libs would make the code more readable, but most of the code is shared. I'd rather keep them together.

I quite like your proposal of TARGET_SG removing non suitable functions and NO_MODE2_SUPPORT removing mode 2 support from the SMS/GG targets.

Meanwhile, I'm trying to implement automatic sprite flickering... But somehow I can't seem to detect when the sprite overflow happens. You had a read to the status port in the ISR which sets an appropriate variable, but such variable is always 0. I don't know when the flag is cleared, though. Maybe that's why this portion of your code was commented out :)

I'll research more on this.

EDIT: It seems that the flags are cleared whenever the port is read, so I'll make sure it's just read once per flag.

EDIT: But, thinking twice... Maybe the flags related to sprites should be read and stored right after copying the SAT table to VRAM.

EDIT: Nope, the port is read in the ISR and that's where I placed my code. It works now. I'm writing a demo to check some stuff and then I'll upload a new version.
  View user's profile Send private message
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Wed Dec 02, 2015 9:55 am
Ok, it's done. In the second demo, very originally titled "second.sg", you'll see five sprites. Four of them are lined in the bottom of the screen. The fifth can be moved around using the D-pad. Once this fifth sprite enters the same line of the remaining four, the overflow is detected and sprites start to flicker. Sprites with an odd index inside the SAT array are rendered during odd frames, sprites with an even index during even frames.

To achieve this I had to add a flip-flop variable which alternates between 0 and 1 in each frame.

There are better solutions which only introduce partial flickering (only the involved sprites), but this one is simple yet effective.

Appart from this, I think I'm done - I just have to test whether PSGlib works in SG mode (and find a good emulator to test it - I'm using Kega Fusion which is allegedly in a sort of SMS mode and I don't know if it emulates the PSG differences).

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Dec 02, 2015 10:19 am
na_th_an wrote
I'm trying to implement automatic sprite flickering... But somehow I can't seem to detect when the sprite overflow happens. You had a read to the status port in the ISR which sets an appropriate variable, but such variable is always 0. I don't know when the flag is cleared, though. Maybe that's why this portion of your code was commented out :)


No, it's commented out because I decided I didn't need to store the value of these flags, since I wrote no functions which uses them. I just shouldn't leave code leftovers in a library I released to the public...

As for adding SG support into SMSlib... I already changed my mind, and you also got a point:

Quote
I doubt anybody wants to create a SMS game using Mode 2, but I could be wrong.


So I realized actually would be better to have a separate SGlib.c and SGlib.h so that:
- if you target the SG you just use SGlib (and the specific crt0, which will init the VDP to Mode2 too...)
- if you target the SMS/GG you just use SMSlib
- if you target the SMS and you want to use legacy video modes, you use both SMSlib and SGlib

all this means that the SG functions should have different names, but it's not hard to change SMS_somefunction() to SG_somefunction()...

If you care to try implementing the very first version of SGlib... I will surely give you full support :)

(auto-anti-flicker support IMHO should be under conditional define, as I suspect some people would prefer a different approach... I can take care of that BTW)

edit: I suggest you try Emulicious and MEKA :)
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Wed Dec 02, 2015 10:37 am
That's fine, I'll create a separate SGlib.c/h :)

And yes, the auto flicker has to be activated using a #define.

I'll keep you posted.
  View user's profile Send private message
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Wed Dec 02, 2015 11:47 am
Well, first public, clean version. I hope. At least it seems to work ;)
SGlib--0.0.1.zip (16.46 KB)

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Dec 02, 2015 12:54 pm
Do you want me to carry on from here?
I mean, I will break your code fixing SG_setSpriteMode() (because IMHO the VDP should start with 8x8 sprites upon init... and the screen should be off... etc.)
Maybe you prefer to fix this yourself and I will relieve later?
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Wed Dec 02, 2015 1:01 pm
I'd rather have you doing the fixes. I'm not a HW or library guy and don't have the correct mindset. I'm sure you'll do a much better job. I loved your SMSlib's "turnOnFeature" and "turnOffFeature", I think those should be there.

I'm saying this 'cause this was just a break from my main project and I'm not sure if I will be able to pay this the amount of attention it deserves. I'm certainly not using it for some time. In the meantime, I have to explore the alternatives to convert sprites and tiles and if they don't suit my needs, add yet another target to my mkts utility (for example, to convert multicolour sprites to several sprites linked in a metasprite structure).

I'd be delighted if this piece of code becomes part of SMSdevkit. Not strictly SMS, but the closest relative you can find.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Dec 02, 2015 1:34 pm
Ok, I'll wreck your code as soon as possible ;)
If you're ok with devkiSMS license (unlicense) I think SGlib can be part of it... why not, uh? :)
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Wed Dec 02, 2015 2:08 pm
Of course I am. Besides, most of the code is yours. I just added some colour.
  View user's profile Send private message
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Thu Dec 03, 2015 8:15 am
As a side note, I've tested adding music using PSGlib and everything seems to sound right, not sure about the noise pattern differences. Haven't tried sound effects yet, but our game Moggy's title music seems to play right.

EDIT: SFX also plays nicely. I guess the differencies between the SG and the SMS PSGs are rather subtle.

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Dec 03, 2015 9:45 am
You might notice a slight detuning if you use noise channel in 'cyclic' noise mode, probably. That's my best bet, at least ;)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Dec 03, 2015 10:32 am
devkitSMS/SGlib
I hope I didn't break too many things... and it's still very beta, it doesn't support any scrolling, I don't know if SG-1000 has palettes, if it has a pause button, and so on... I'm just blindly following na_th_an so if any problem arises you should eventually complain to him :p
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Thu Dec 03, 2015 1:32 pm
As far as I know, no scrolling. All scrolling must be performed by software rewriting the whole nametable or specially arranged pattern data.

Also, no palettes. The TMS9918a palette is fixed. Note that "black" is colour #1; colour #0 is always transparent, even for background tiles (the backdrop colour defined in register #7 is shown instead).

All I have found about the Pause button is this:

Quote
Non Maskable Interrupts

A NMI occurs when the Pause button is pressed. It's behaviour is the same as standard interrupt, except that the jumping location is 0x66.


So I guess it's exactly the same as with the SMS
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Dec 03, 2015 2:29 pm
OK, thanks.
By chance do you know if it had a 'reset' key (as on the first SMS) or if it support light phaser? I couldn't find any info on this.

edit: are there some 'common' names associated with each SG-1000 color? I mean, like it was in the 80s for PCs CGA/text mode colors (black, blue, green, cyan, red, etc...)
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Fri Dec 04, 2015 7:20 am
The TMS9918a was used in popular computers such as the TI99/4a, the MSX1 standard, or the Spectravideo.

From the MSX1 community, this is the colour chart - complete with colour names - I've always seen floating around. Maybe those are kind of "official" colour names:

0 Transparent
1 Black
2 Medium green
3 Light green
4 Dark blue
5 Light blue
6 Dark red
7 Cyan
8 Medium red
9 Light red
A Dark yellow
B Light yellow
C Dark green
D Magenta
E Gray
F White


As for the light gun, I guess it wasn't available until the Mark 3 was released. I can't find any mention either and the game Bank Panic doesn't seem to be played using a light gun in this video: (this video is captured from real hardware and in case it was played with a light gun with every shot you would notice a distinct flash to detect if the player had hit, which is not there).
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14738
  • Location: London
Reply with quote
Post Posted: Fri Dec 04, 2015 8:17 am
The colour names are official, from the TMS9918a docs. There's a huge amount of information on this chip, see http://www.smspower.org/Development/VDP-Index for some of it. There are also some fairly advanced derivations of the colour values, for example at http://bifi.msxnet.org/msxnet/tech/tms9918a.txt

Note also that the SMS colours used in legacy video modes are fairly bad approximations of the TMS9918a colours, so much care is needed to target the graphics to the colours of the system.
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Fri Dec 04, 2015 9:52 am
Maxim wrote
http://bifi.msxnet.org/msxnet/tech/tms9918a.txt


That's exactly de documentation I've used while developing SGlib :)
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Dec 04, 2015 3:00 pm
Thanks! :)
It should be usable now. I'll work more on this when demand arise :)
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Fri Dec 04, 2015 9:59 pm
Awesome, thanks for your efforts!

By the way, I forgot to mention that I named the extra attribute in the SAT functions "attr" instead of "colour" 'cause bits 0-3 contain the colour but if you raise bit 7 (EC - Early Clock bit) sprites are rendered 32 pixels to the left so they can get past X = 0 and be rendered partially (normally that just happens when X > 240, to the right of the screen). This way you have a 256+32 pixels range and with some clever coding you can make your sprites "get out of the screen" smoothly.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Dec 06, 2015 11:56 am
na_th_an wrote
I forgot to mention that I named the extra attribute in the SAT functions "attr" instead of "colour" 'cause bits 0-3 contain the colour but if you raise bit 7 (EC - Early Clock bit) sprites are rendered 32 pixels to the left [...]


It's fine :) If you feel we should change or add something let me know.
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Wed Dec 23, 2015 9:32 am
Needing to update pattern data per frame, I needed to port some more SMSlib functions. Still untested, but soon to be (just copy/pasted then changed some identifiers/modified slightly the SAT format).

/* VRAM unsafe functions. Fast, but dangerous! */
void UNSAFE_SG_copySpritestoSAT (void) {
  SG_set_address_VRAM(SATADDRESS);
  __asm
    ld c,#_VDPDataPort
    ld hl,#_SpriteTable
#if MAXSPRITES==32
    call _outi_block-MAXSPRITES*4
#else
    call _outi_block-(MAXSPRITES+1)*4
#endif
  __endasm;
}

void UNSAFE_SG_VRAMmemcpy32 (unsigned int dst, void *src) {
  SG_set_address_VRAM(dst);
  __asm
    ld c,#_VDPDataPort
    ld l, 2 (iy)
    ld h, 3 (iy)
    call _outi_block-32*2
  __endasm;
}

void UNSAFE_SG_VRAMmemcpy64 (unsigned int dst, void *src) {
  SG_set_address_VRAM(dst);
  __asm
    ld c,#_VDPDataPort
    ld l, 2 (iy)
    ld h, 3 (iy)
    call _outi_block-64*2
  __endasm;
}

void UNSAFE_SG_VRAMmemcpy128 (unsigned int dst, void *src) {
  SG_set_address_VRAM(dst);
  __asm
    ld c,#_VDPDataPort
    ld l, 2 (iy)
    ld h, 3 (iy)
    call _outi_block-128*2
  __endasm;
}
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Dec 23, 2015 10:08 am
So you are working on an SG game! :D
Thanks for the code. Since I'm actually refactoring these functions I won't add them right away to the repository, but you can add them to your copy and let me know if you find any bug (hopefully not, since it's the same code I put in SMSlib...)

edit: also, I just realized that
call _outi_block-MAXSPRITES*4

it's wrong. OUTI is a 2-byte opcode, so to move MAXSPRITES*4 bytes you have to
call _outi_block-(MAXSPRITES*4)*2


but you can't do that, since there are only 128 OUTI instructions in crt0.
I think you have to split that into two parts (when MAXSPRITES>=16)

#if MAXSPRITES==32
     call _outi_block-MAXSPRITES*4
     call _outi_block-MAXSPRITES*4
#else if MAXSPRITES>=16 
     call _outi_block-16*4*2;
     call _outi_block-((MAXSPRITES-16)*4+1)*2
#else 
     call _outi_block-((MAXSPRITES)*4+1)*2     
#endif


(untested!)
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Wed Dec 23, 2015 12:14 pm
You are right, I have to change that.

But 128 OUTIs would suffice: there's just 32 sprites in the SAT for the TMS9918a, 4*32 = 128. Unless I'm missing something completely obvious. Let me think a while :D

MAXSPRITES*4*8 = 256, maybe that's the problem?

Yeah, I might me working on something. I'm finishing a NES game which will be ported to SEGA 8-bit, that means the SG and the SMS.

If I can update the pattern data for the sprites in time, it will look great in the SG :) 16x24 2-colours sprites. Hope I don't run out of space in ROM.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Dec 23, 2015 1:01 pm
na_th_an wrote
But 128 OUTIs would suffice: there's just 32 sprites in the SAT for the TMS9918a, 4*32 = 128.


Wow, I'm an idiot.

edit: your code btw should account for the OUTI opcode, which is 2 bytes, so:

#if MAXSPRITES==32
     call _outi_block-MAXSPRITES*4*2
#else
     call _outi_block-(MAXSPRITES*4+1)*2
#endif
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Wed Dec 23, 2015 2:43 pm
Fixed, thanks.

I can also say that this works great. I'm updating pattern data for sprites each frame in a SG-1000 and everything looks gorgeous :D
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Dec 23, 2015 2:57 pm
Feeling like it's too easy? ;)
BTW, aren't SG sprites pattern just 8 bytes each? You can update four of them in the same time it takes to update one on a SMS...
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Wed Dec 23, 2015 3:29 pm
Each pattern is 1bit depth, so yeah, 8 bytes per pattern (4 patterns per 16x16 sprite, tho).

I update a total of 128+128+32 bytes each frame and it works great.
  View user's profile Send private message
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Fri Dec 25, 2015 10:31 pm
Hello.

I'm still working on porting my NES game to the SG1000 (and later the SMS). It's going well (with some problems making it run fast enough to fit each frame in a NTSC frame) but I've found that the game freezes in some levels. Using MEKA and dumping the regs, it seems that register 1 has been tampered with and has a value of $11000011, that means IRQ disabled, so "WaitForVBlank" just sits there waiting forever.

The only tampering I do with the register is enabling 16x16 sprites at the beginning of my program, and I don't know what can be changing the value.

There's some serious debugging to do. I'll report when I find the cause.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3825
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Dec 25, 2015 10:36 pm
na_th_an wrote
I've found that the game freezes in some levels. Using MEKA and dumping the regs, it seems that register 1 has been tampered with and has a value of $11000011, that means IRQ disabled


I'd place a conditional break on I/O on VDP port when writing that value and find the offending code, for instance with MEKA.
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Fri Dec 25, 2015 10:43 pm
Thanks for the info.

It could be as well a TMS9918a thing about when you can write to regs and things like that. I've several "screens" (title, round XX, gameplay, game over...) and all of them turn on the display in the beginning and off at the end. Maybe if that happens during an interrupt things are corrupted as in other system, or is your library taking care of such things?

EDIT: I'll be logging my progress here. I've found that $C3 is written to port $BF by this code:

;SGlib.c:153: VDPReg[HI(feature)]|=LO(feature);
   ld   e,5 (ix)
   ld   d,#0x00
   ld   hl,#_VDPReg
   add   hl,de
   ld   c,(hl)
   ld   a,4 (ix)
   ld   -2 (ix),a
   ld   -1 (ix),#0x00
   ld   b,#0x00
   ld   a,c
   or   a, -2 (ix)
   ld   c,a
   ld   a,b
   or   a, -1 (ix)
   ld   b,a
   ld   (hl),c
;SGlib.c:154: SG_write_to_VDPRegister(HI(feature), VDPReg[HI(feature)]);
   di
   ld   a,c
   out   (_VDPControlPort),a
   ld   a,e
   set   7, a
   ld   h,a
   out   (_VDPControlPort),a
   ei
   ld   sp, ix
   pop   ix
   ret


which is part of SG_VDPturnOnFeature. So something is corrupting the array VDPReg, most likely. More to come...
  View user's profile Send private message
Reply to topic Goto page 1, 2  Next



Back to the top of this page

Back to SMS Power!