Jump to content
IGNORED

ColecoVision development kit


opcode

Recommended Posts

So, opcode, did you get my e-mail?  :)

977175[/snapback]

 

Hi Luc,

 

Yeah, I did. Man, that's fantastic! I will write you about it in a few minutes...

Before, I want to share something...

 

My SEM emulator is starting to show. Right now it is already able to run almost all CV games, modes graphic 1 and 2 are implemented, as well as sprites.

In case you don't know that, modes Graphic 1 and 2 were used with almost all CV games, mainly Graphic 2. There are other two modes: text and multicolor. I will implement these later.

 

The first new feature I would like to discuss is color. The original TMS9928 was limited to 16 fixed colors. The CV9956 is able to display up to 256 colors on screen, from 512 colors available. Colors are organized in palettes, 16 colors each. So the CV9956 has 16 palettes. These palettes will be fully exploited in the new modes Graphic 3 and 4. But the old Graphic 1 and 2 can also take advantage from it. First of all, when the CV9956 is turned on, it will load the default CV colors in palettes 0 and 1. It's necessary for backward compatibility. But why two palettes, if the original CV has just one? First, I would like to say that the new default palette looks a bit better than the original "watered" colors. Colors now are brighter and you get better contrast among different hues of a same color. Check the attached DK screenshot: the two topmost screenshots are from the new CV9956 while the two bottommost are from the original CV.

Ok, back to the question about why two palettes are loaded with default colors during reset. That is because in the CV9956 background and sprites use separated palettes. Since both are load with the same default values during reset, old games will never know. New games though can take advantage from it. Just check my second screenshot set, Magical Tree: top-left screenshot is from original CV, top-right is from the SEM, bottom-left is from the SEM but running a modified version of that game, which loaded a partial palette optimization (see code bellow) and finally bottom-right is a mockup of how a hope MT will look after all colors have been optimized. Better, it isn't a different "program", it is the same game which now checks if the SEM is present then change all colors appropriately. So MT (due in January) will be the first SEM-ready game.

Now, how can a programmer change the default palettes? Really simple: the CV9956 has two special I/O ports for palette manipulation, mapped in the Z80 I/O addresses 74h and 75h.

Port 74h sets palette address, while port 75h read/write data from/to palettes. To set the palette address, you need to send two bytes thought port 74h:

first byte says the color # and RGB - 0 0 C C C C R R, where C bits are color # (0 - 15) and R bits are RGB (0-2, 3 is invalid)

second byte says the palette # plus mode - A W 0 0 P P P P, where P is palette # (0 - 15), W is write (1=Write, 0=Read), A is Auto Increment Inhibit because the palette address pointer will automaticlly increment after each access, so set it to 1 if you want to disable AI.

 

After sending both address bytes, read or write data from port 75h. The CV9956 has two separated address pointers, one for read and another for write. So once you have set both pointers, you can read and write without the need of any further address setting. You can for example set both pointers to palette 0 color 0, then read color data, apply change and load data back. It is very handsome and allows easy palette manipulation, useful when creating some nice effects like fade-ins and fade-outs.

 

Here is the only thing I added to MT so far in order to produce the screenshot bellow:

 

LD_PAL:	LD A,18H
 OUT (74H),A	;SET COLOR #06H
 LD A,40H
 OUT (74H),A	;SET PALETTE # 00H, WRITE ADDRESS
 LD B,0CH                    ;# OF BYTES
 LD C,75H                    ;PALETTE DATA PORT ADDRESS
 LD HL,PAL_INFO          ;COLOR TABLE POINTER
 OUTIR                        ;TRANSFER COLORS
 RET
PAL_INFO:	DEFB 03H,02H,01H
 DEFB 04H,06H,07H
 DEFB 05H,03H,01H
 DEFB 06H,04H,02H

 

More info soon...

 

Eduardo

post-1432-1133915549_thumb.jpg

post-1432-1133915567_thumb.jpg

Link to comment
Share on other sites

My SEM emulator is starting to show.

Huh? You mean it's pregnant??? :-o

 

(See, you're not the only one who can make bad jokes. Heh.) :P

 

Right now it is already able to run almost all CV games, modes graphic 1 and 2 are implemented, as well as sprites.

In case you don't know that, modes Graphic 1 and 2 were used with almost all CV games, mainly Graphic 2. There are other two modes: text and multicolor. I will implement these later.

Text mode could be useful for those who'd want to do Infocom-type text games...

 

The first new feature I would like to discuss is color. The original TMS9928 was limited to 16 fixed colors. The CV9956 is able to display up to 256 colors on screen, from 512 colors available. Colors are organized in palettes, 16 colors each. So the CV9956 has 16 palettes. These palettes will be fully exploited in the new modes Graphic 3 and 4. But the old Graphic 1 and 2 can also take advantage from it.

Kewl! :D

 

 

First of all, when the CV9956 is turned on, it will load the default CV colors in palettes 0 and 1. It's necessary for backward compatibility. But why two palettes, if the original CV has just one? First, I would like to say that the new default palette looks a bit better than the original "watered" colors. Colors now are brighter and you get better contrast among different hues of a same color. Check the attached DK screenshot: the two topmost screenshots are from the new CV9956 while the two bottommost are from the original CV.

They indeed look much better. Although I've always felt that regular TV screens produced better CV colors than PC monitors...

 

Ok, back to the question about why two palettes are loaded with default colors during reset. That is because in the CV9956 background and sprites use separated palettes. Since both are load with the same default values during reset, old games will never know. New games though can take advantage from it. Just check my second screenshot set, Magical Tree: top-left screenshot is from original CV, top-right is from the SEM, bottom-left is from the SEM but running a modified version of that game, which loaded a partial palette optimization (see code bellow) and finally bottom-right is a mockup of how a hope MT will look after all colors have been optimized.

That reminds me: Will the SEM use the extra 16K of RAM together with the 1K of base RAM, or will the 1K become "obsolete"?

 

Better, it isn't a different "program", it is the same game which now checks if the SEM is present then change all colors appropriately. So MT (due in January) will be the first SEM-ready game.

But old CV games will only use the slightly upgraded set of 16 colors. Still, it's very cool. :)

 

Here is the only thing I added to MT so far in order to produce the screenshot bellow:

 

LD_PAL:	LD A,18H
 OUT (74H),A;SET COLOR #06H
 LD A,40H
 OUT (74H),A;SET PALETTE # 00H, WRITE ADDRESS
 LD B,0CH                    ;# OF BYTES
 LD C,75H                    ;PALETTE DATA PORT ADDRESS
 LD HL,PAL_INFO          ;COLOR TABLE POINTER
 OUTIR                        ;TRANSFER COLORS
 RET
PAL_INFO:	DEFB 03H,02H,01H
 DEFB 04H,06H,07H
 DEFB 05H,03H,01H
 DEFB 06H,04H,02H

Ah, so this is the kind of code that our dev kit will generate... :D

Link to comment
Share on other sites

Right now it is already able to run almost all CV games, modes graphic 1 and 2 are implemented, as well as sprites.

In case you don't know that, modes Graphic 1 and 2 were used with almost all CV games, mainly Graphic 2. There are other two modes: text and multicolor. I will implement these later.

Text mode could be useful for those who'd want to do Infocom-type text games...

 

Text mode is too rigid, just a color for text and another for background. I don't see a good reason for use it, unless you really need 40 column...

 

Ok, back to the question about why two palettes are loaded with default colors during reset. That is because in the CV9956 background and sprites use separated palettes. Since both are load with the same default values during reset, old games will never know. New games though can take advantage from it. Just check my second screenshot set, Magical Tree: top-left screenshot is from original CV, top-right is from the SEM, bottom-left is from the SEM but running a modified version of that game, which loaded a partial palette optimization (see code bellow) and finally bottom-right is a mockup of how a hope MT will look after all colors have been optimized.

That reminds me: Will the SEM use the extra 16K of RAM together with the 1K of base RAM, or will the 1K become "obsolete"?

 

The programmer can decide if he/she wants to use the 1K or not. I would use it for the stack, for example... :)

 

Better, it isn't a different "program", it is the same game which now checks if the SEM is present then change all colors appropriately. So MT (due in January) will be the first SEM-ready game.

But old CV games will only use the slightly upgraded set of 16 colors. Still, it's very cool. :)

 

Well, that is why I want to include a palette editor with the SEM. During boot you can load the palette editor, then edit color palette, save it then load a game using the new palette. If the game isn't SEM aware, you can freely change its palette.

 

Eduardo

Link to comment
Share on other sites

Well, that is why I want to include a palette editor with the SEM. During boot you can load the palette editor, then edit color palette, save it then load a game using the new palette. If the game isn't SEM aware, you can freely change its palette.

977951[/snapback]

Save it? Is this change persistent, or is it lost when you turn the system off?

Link to comment
Share on other sites

Well, that is why I want to include a palette editor with the SEM. During boot you can load the palette editor, then edit color palette, save it then load a game using the new palette. If the game isn't SEM aware, you can freely change its palette.

977951[/snapback]

Save it? Is this change persistent, or is it lost when you turn the system off?

977959[/snapback]

 

Save it in the SD card, with the .pal extension.

 

Eduardo

Link to comment
Share on other sites

Save it in the SD card, with the .pal extension.

977966[/snapback]

 

So I assume there will be something in the SEM BIOS to do this for any game. Will the SEM also be able to save game data in the same way? Would be perfect for RPG games, for one thing...

 

Also, one suggestion for your palette editor: Be sure to offer a way to enter a palette specification using a number-based password. That way, players can quickly enter a pallette code using the standard keypad, and players can also exchange pallette codes between each other (by e-mail, or whatever). The Super Game Boy device (for Super-NES) had a similar pallette number code system, and it was VERY useful.

Edited by Pixelboy
Link to comment
Share on other sites

Instead of doing what? Sorry, I still don't get it...

982443[/snapback]

It's been a week since Eduardo last posted in this thread, and he hasn't replied to my e-mail either. I don't know the guy very well, so I'm just wondering what he's doing that's keeping him away. He was rather quick to reply before...

Link to comment
Share on other sites

Instead of doing what? Sorry, I still don't get it...

982443[/snapback]

It's been a week since Eduardo last posted in this thread, and he hasn't replied to my e-mail either. I don't know the guy very well, so I'm just wondering what he's doing that's keeping him away. He was rather quick to reply before...

982465[/snapback]

 

I am sorry I didn't reply before. I am sick, got the flu, and I am still recovering from it. I didn't have the chance to do a lot of stuff in the last few days, as my brain was frying in fever....

However I managed to finish adding all standard CV features to my CV+SEM emulator. Nathan suggested me to name it the ColecoVision87 or just Vision87, in order to save us of problems with RWB.

However, in order to save some precious time, I implemented CV87 as a MESS driver, so I am not sure if I can distribute it right away. Probably it would be a good idea if I contact the MESS team first. Anyway I can say that my driver is better than the current CV driver, since it can accurately emulate some games which the previous driver can't, like Defender and Matt Patrol.

Also, I have included all settings in the CV9956 driver which affect legacy video modes. Palette was one. Then hardware scroll, which I tested with a modified version of Sky Jaguar. So I have all new control registers defined and access to them is already possible through ports mapped to 70h and 71h in the Z80 I/O map.

Register #8 is a complimentary mode register, with several functions: bit 0 is PAL/NTSC (so we don't need two different versions of CV9956), bit 1 is sprite disable (which disable all sprites on screen), bit 2 is 8 sprites per scanline (works with legacy video modes only, say goodbye to flickering), bit 3 is mode4, which activates the new graphic modes 3 and 4, bits 4 and 5 are two new interrupt modes, scanline interrupt and command interrupt.

Register #9 is the scanline interruption register. Just set the scanline number here is the VDP will generate an interruption when this scanline is displayed.

Register #10 is vertical scroll

Register #11 is character horizontal scroll; it says how many characters (8 pixels wide) you want to scroll the screen to the left.

Register #12 is smooth horizontal scroll (0-7), which says how many pixels you want to scroll the screen to the left.

Register #13 is background base address (bits 0-3). It says the VDP which 16Kb page it should use to starting reading background graphic data. So in legacy modes it means that you have now 16 graphic pages, instead just one, which was the case with the old TMS9928.

Register #14 is sprite base address (bits 0-3). Same as R#13

 

All the above registers are reset to 0 when the VDP is started or reset, so it means full backward compatibility with all CV games.

Now comes the interesting bit.... the CV9956 has 4 sets of the above registers, 2 complete sets and 2 partial sets, and here is why. The CV9956 offers a feature which I am calling "context zones". The CV9956 screen is in fact a rectangular area divided into 4 zones. These 4 zones are obtained by dividing the screen with a horizontal line, then a vertical line. The exact coordinates of both the vertical and horizontal lines can be configured. Zone 1 is the top-left zone, then zone 2 is the top-right zone, zone 3 is the bottom-left zone and zone 4 is the bottom right-zone.

 

For each zone you can use a different set of registers, though you should use complete register sets (sets #0 and #1) to the left-sided zones and partial sets (sets #2 and #3) to right-sided zones. However you can use the same set with two or more zones.

 

In plain English which these all means: Each zone can be programmed to have different video properties, like scroll and pattern pages, i.e., each zone can be controlled independently from the other zones. You can have a zone which is static while the others are scrolling, for example. If you use the same register set with multiple zones, all these zones will act the same, or if you prefer, they will be an extension of each other.

Register #15 (which is not part of any set), defines which register set will be used with each zone (2 bits per zone).

Register #31 (which is not part of any set), defines the horizontal line which divides the screen in zones.

Register #47 (which is not part of any set), defines the vertical column (in 8 pixel units) which divides the screen in zones

All these 3 registers are reset to 0 once the VDP is reset.

 

Let’s check some cases:

 

1) DK, the packed-in CV game: DK is completely unaware of such things like the register sets. No problem at all! When the CV+SEM are turned on, VDP registers #15, #31 and #47 are all reset to 0. Setting R#15 to zero means that all screen zones will be controlled by register set #0, which is the default register set. The original TMS9928 allowed access to control registers using an I/O port which is mapped to address BFh in the Z80 I/O memory map. In the CV9956 this port will allow access just to registers 0 to 7 in register set #0, which are the only registers in the original TMS9928. Therefore, it isn't possible for a legacy program to have access to an "expanded" register, even by mistake. So any legacy game will run just fine.

 

2) Magical Tree: lets suppose we want to add smooth scroll to Magical Tree. Well, if you have seen a screenshot of MT before, you know that the screen layout has a score area in the top (which is fixed) and a scrolling background. If it was the NES or the SMS you would set a scanline interrupt (a feature also present in the CV9956) then change the scroll attribute once the scanline dividing the score area from the playfield is reached. It is CPU consuming and in usually this screen split isn't very stable. With context zones is it's a 100% CPU free process, the screen split is 100% stable and most important, it is several times easier to implement. Set the register #31 (the zone horizontal line register) to the scanline # where you want your screen to be divided. You can leave column register as 0, so you just have zones 1 and 3. Now set register #15 to use register set #0 with zone 1 and register set #1 with zone 3. In order to make your scrolling background easier to implement it would be better if you use a different page with your score area. Now just keep setting the scroll register in set #0 to make your background scroll. Zone 1 will mask the character line that is being added to the background while it scrolls.

 

3) Sky Jaguar: While in case 2 it was possible to do the same thing using scanline interrupt, with SJ it isn't possible. SJ uses a vertical score area, a black panel which takes several screen columns to the right. The NES can’t do this at all, while the SMS can do, but in a very rigid, limited way. I created a custom version of SJ to check if it would work the way I was hoping and, well, it worked. I will distribute the binary once I manage to distribute my CV87 emulator. Zones 2 and 4, which are the right-sided zones, are more limited than left-sided zones. Zones 2 and 4 will inherit all properties from their respective left-sided zones, except scroll and background page. It means you can’t use two different screen modes in the same scanline, for example.

 

4) I could suggest a lot of cool examples for using the context zones, like a two players simultaneous racing game (or even a four player), strategy games, etc. The zones can even be redefined on the fly to produce very interesting effects.

 

Well, I am skipping a lot of technical details here. Once the emulator is available I would offer far better documentation.

Now the main question is: would the above features be possible considering the technological limitations of the late 80s? IMHO, the answer is yes. In the 2nd half of the 80s, the biggest concern was memory bandwidth not IC complexity. I mean, memory bandwidth was determining what a VDP could do and what it couldn’t. The CV9956 has 8 times more memory bandwidth when reading from VRAM than the original TMS9928. It is possible by doubling the VDP clock (nothing special here, as the NES had already twice the clock of the TMS9928) while reducing the number of cycles necessaries for a read from 4 to just 1. The new features added to the CV9956 in legacy mode means just a few extra VRAM access per scanline: context zones and hardware scroll add 6 extra reads per scanline (from previous 96 total reads in the TMS9928, a mere 6% increase). 8 sprites per scanline would add 24 memory accesses in the worst case, a 43% increase. While the original 152 reads accesses per scanline would leave the TMS9928 with very little free time to even allow writes to the VRAM by the user, in the CV9956 the 182 accesses are just 14% of the total number of possible VRAM reads per scanline. It will give the blitter a lot of free cycles to work….

 

Ok, I think the fever is coming back. Time to go bed…

 

Eduardo

Link to comment
Share on other sites

Ok, I think the fever is coming back. Time to go bed…

982608[/snapback]

Wow, no kidding! Take it easy, Eduardo! The expression "No rest for the wicked" doesn't apply to you. Not when you're sick, anyway. :D

 

About your latest post, I'd say the SEM is looking more awesome every time I learn something new about it, and it seems the amount of features in our CV dev kit associated with the SEM will be far more massive than those for the basic CV. Which is fine by me. :)

 

Good job! Now get some rest!

Link to comment
Share on other sites

Ok, I think the fever is coming back. Time to go bed…

982608[/snapback]

Wow, no kidding! Take it easy, Eduardo! The expression "No rest for the wicked" doesn't apply to you. Not when you're sick, anyway. :D

 

About your latest post, I'd say the SEM is looking more awesome every time I learn something new about it, and it seems the amount of features in our CV dev kit associated with the SEM will be far more massive than those for the basic CV. Which is fine by me. :)

982636[/snapback]

 

Yeah, but lets concentrate on the standard CV stuff first. If we do it right, I think it would be easy to extend the language to use the new features later.

 

Oh, I think I still have an email from you to reply... :)

 

Eduardo

Link to comment
Share on other sites

Yeah, but lets concentrate on the standard CV stuff first. If we do it right, I think it would be easy to extend the language to use the new features later.

 

Right. Speaking of which, I guess now would be a good time to stop asking questions (although I still have a ton of them) and start contributing something more concrete to this thread. So allow me to throw some ideas around...

 

The central idea of the functions described below is to use a sort of "built-in" object simply called "cv", which is an entry point to several sub-objects like "io" and "ctrl", which themselves hold specialized functions. It's a way to keep the code clean from the programmer's point of view.

 

 

IO:

 

cv.io.gmode1.initialize()

--> Initializes Graphic Mode 1.

--> Returns nothing.

 

cv.io.gmode1.loadColorTable(<byte_id>)

<byte_id> = name of registered array of 32 bytes in RAM or ROM

--> Loads the entire color table for Graphics Mode 1.

--> Returns nothing.

 

cv.io.gmode1.setTileColors(<num_group>, <color_1>, <color_2>)

<num_group> = group number between 0 and 31

<color_1> = color #1 between 0 and 15

<color_2> = color #2 between 0 and 15

--> Sets the colors of a group of 8 tiles under Graphic Mode 1.

--> Returns nothing.

 

cv.io.gmode1.loadNameTable(<byte_id>)

<byte_id> = name of registered array of 768 bytes in RAM or ROM

--> Copies 768 bytes from <byte_id> into Graphic Mode 1's name table.

--> Returns nothing.

 

cv.io.gmode1.loadPatternTable(<byte_id>, <bg_or_spr>)

<byte_id> = name of registered array of 2048 bytes in RAM or ROM

<bg_or_spr> = 0 for background patterns, 1 for sprite patterns

--> Loads 2048 bytes from <byte_id> into Graphic Mode 1's pattern table. If <bg_or_spr> = 0, the data is loaded into the background pattern table, else if <bg_or_spr> = 2, then the data is loaded into the sprite pattern table.

--> Returns nothing.

 

cv.io.gmode1.setSprite(<sprite_number>, <x_coord>, <y_coord>,

<pattern_number>, <color_1>, <color_2>)

<sprite_number> = sprite number between 0 and 31

<x_coord> = x coordinate of sprite, between -32767 and 32767

<y_coord> = y coordinate of sprite, between -32767 and 32767

<pattern_number> = pattern tile number between 0 and 255

<color_1> = color #1 between 0 and 15

<color_2> = color #2 between 0 and 15

--> Sets the attributes of a sprite under Graphic Mode 1.

--> Returns nothing.

 

cv.io.gmode2.initialize()

--> Initializes Graphic Mode 2.

--> Returns nothing.

 

cv.io.gmode2.setTileLineColors(<num_group>, <num_line>, <color_1>, <color_2>)

<num_group> = tile group number between 0 and 31

<num_line> = pixel line number between 0 and 7

<color_1> = color #1 between 0 and 15

<color_2> = color #2 between 0 and 15

--> Sets the colors of a group of 8 tiles under Graphic Mode 2.

--> Returns nothing

 

cv.io.gmode2.setTileColors(<num_group>, <line0_col1>, <line0_col2>,

<line1_col1>, <line1_col2>,

<line2_col1>, <line2_col2>,

<line3_col1>, <line3_col2>,

<line4_col1>, <line4_col2>,

<line5_col1>, <line5_col2>,

<line6_col1>, <line6_col2>,

<line7_col1>, <line7_col2>)

<num_group> = tile group number between 0 and 31

<line0_col1> = color #1 (between 0 and 15) of pixel line #0

<line0_col2> = color #2 (between 0 and 15) of pixel line #0

<line1_col1> = color #1 (between 0 and 15) of pixel line #1

<line1_col2> = color #2 (between 0 and 15) of pixel line #1

<line2_col1> = color #1 (between 0 and 15) of pixel line #2

<line2_col2> = color #2 (between 0 and 15) of pixel line #2

<line3_col1> = color #1 (between 0 and 15) of pixel line #3

<line3_col2> = color #2 (between 0 and 15) of pixel line #3

<line4_col1> = color #1 (between 0 and 15) of pixel line #4

<line4_col2> = color #2 (between 0 and 15) of pixel line #4

<line5_col1> = color #1 (between 0 and 15) of pixel line #5

<line5_col2> = color #2 (between 0 and 15) of pixel line #5

<line6_col1> = color #1 (between 0 and 15) of pixel line #6

<line6_col2> = color #2 (between 0 and 15) of pixel line #6

<line7_col1> = color #1 (between 0 and 15) of pixel line #7

<line7_col2> = color #2 (between 0 and 15) of pixel line #7

--> Sets all 8 color pairs of a group of 8 tiles in Graphic Mode 2.

--> Returns nothing.

 

cv.io.gmode2.setSprite(<sprite_number>, <x_coord>, <y_coord>,

<pattern_number>, <line0_col1>, <line0_col2>,

<line1_col1>, <line1_col2>,

<line2_col1>, <line2_col2>,

<line3_col1>, <line3_col2>,

<line4_col1>, <line4_col2>,

<line5_col1>, <line5_col2>,

<line6_col1>, <line6_col2>,

<line7_col1>, <line7_col2>)

<sprite_number> = sprite number between 0 and 31

<x_coord> = x coordinate of sprite, between -32767 and 32767

<y_coord> = y coordinate of sprite, between -32767 and 32767

<pattern_number> = pattern tile number between 0 and 255

<line0_col1> = color #1 (between 0 and 15) of pixel line #0

<line0_col2> = color #2 (between 0 and 15) of pixel line #0

<line1_col1> = color #1 (between 0 and 15) of pixel line #1

<line1_col2> = color #2 (between 0 and 15) of pixel line #1

<line2_col1> = color #1 (between 0 and 15) of pixel line #2

<line2_col2> = color #2 (between 0 and 15) of pixel line #2

<line3_col1> = color #1 (between 0 and 15) of pixel line #3

<line3_col2> = color #2 (between 0 and 15) of pixel line #3

<line4_col1> = color #1 (between 0 and 15) of pixel line #4

<line4_col2> = color #2 (between 0 and 15) of pixel line #4

<line5_col1> = color #1 (between 0 and 15) of pixel line #5

<line5_col2> = color #2 (between 0 and 15) of pixel line #5

<line6_col1> = color #1 (between 0 and 15) of pixel line #6

<line6_col2> = color #2 (between 0 and 15) of pixel line #6

<line7_col1> = color #1 (between 0 and 15) of pixel line #7

<line7_col2> = color #2 (between 0 and 15) of pixel line #7

--> Sets the attributes of a sprite under Graphic Mode 2.

--> Returns nothing.

 

 

MISCELLANEOUS:

 

cv.mem.copyBytes(<src_address>, <dest_address>, <number_of_bytes>)

<src_address> = address of first byte to copy (in RAM or ROM)

<dest_address> = address of first byte to copy to (in RAM)

<number_of_bytes> = number of bytes to copy

--> Copies <number_of_bytes> bytes from one memory address (in RAM or ROM) to another (in RAM only, obviously).

--> Returns nothing.

 

cv.timer.get()

--> Returns the current value of the internal clock (which is based on the video refresh NMI) as an integer value.

 

cv.timer.reset(<value>)

<value> = integer value used to reset the timer (usually zero)

--> Sets the internal clock to a specific value.

 

cv.random.setSeed(<value>)

<value> = integer value to use as seed on the next call to "cv.random.get()"

--> Sets the seed of the built-in random number generator. Note that this seed is also modified each time the joystick is moved or the keypad is pressed on either controller, which helps in making the random number generator truly random.

 

cv.random.get(<max_value>)

--> Generates (and returns) a random number between 0 and <max_value>.

 

 

CTRL:

 

cv.ctrl.keyPressed(<port_number>)

<port_number> = 1 for controller port #1 or 2 for controller port #2

--> Returns true if a keypad key was registered as "pressed" during the last NMI loop.

--> Returns false otherwise.

 

cv.ctrl.keyDepressed(<port_number>)

<port_number> = 1 for controller port #1 or 2 for controller port #2

--> Returns true if a keypad key was registered as "depressed" during the last NMI loop.

--> Returns false otherwise.

 

cv.ctrl.keypadGet(<port_number>)

<port_number> = 1 for controller #1, 2 for controller #2, 0 for both ports

--> Returns 0 if last key pressed was key '0'

--> Returns 1 if last key pressed was key '1'

--> Returns 2 if last key pressed was key '2'

--> Returns 3 if last key pressed was key '3'

--> Returns 4 if last key pressed was key '4'

--> Returns 5 if last key pressed was key '5'

--> Returns 6 if last key pressed was key '6'

--> Returns 7 if last key pressed was key '7'

--> Returns 8 if last key pressed was key '8'

--> Returns 9 if last key pressed was key '9'

--> Returns 10 if last key pressed was key '#'

--> Returns 11 if last key pressed was key '*'

 

cv.ctrl.keypadFlush(<port_number>)

<port_number> = 1 for controller #1, 2 for controller #2, 0 for both ports

--> Discards all previously recorded keypad information on port.

--> Returns nothing.

 

cv.ctrl.joystickState(<port_number>)

<port_number> = 1 for controller port #1, 2 for controller port #2

--> Returns 0 if joystick was not moved in any direction by the player

--> Returns 1 if joystick was moved upward

--> Returns 2 if joystick was moved up/right (diagonal)

--> Returns 3 if joystick was moved left

--> Returns 4 if joystick was moved down/right (diagonal)

--> Returns 5 if joystick was moved down

--> Returns 6 if joystick was moved down/left (diagonal)

--> Returns 7 if joystick was moved right

--> Returns 8 if joystick was moved up/right (diagonal)

 

cv.ctrl.buttonPressed(<port_number>, <button_number>)

<port_number> = 1 for controller port #1 or 2 for controller port #2

<button_number> = 0 for left button (or top button on Super Controller)

1 for right button (or second button on Super Controller)

2 for third button on Super Controller

3 for fourth button on Super Controller

--> Returns true if the specified button was registered as "pressed" during the last NMI loop.

--> Returns false otherwise.

 

cv.ctrl.buttonDepressed(<port_number>, <button_number>)

<port_number> = 1 for controller port #1 or 2 for controller port #2

<button_number> = 0 for left button (or top button on Super Controller)

1 for right button (or second button on Super Controller)

2 for third button on Super Controller

3 for fourth button on Super Controller

--> Returns true if the specified button was registered as "depressed" during the last NMI loop.

--> Returns false otherwise.

 

cv.ctrl.lock(<port number>)

<port_number> = 1 for controller #1, 2 for controller #2, 0 for both ports

--> Makes the state engine ignore controller input on specified port until cv.ctrl.unlock() is called.

--> Returns nothing.

 

cv.ctrl.unlock(<port number>)

<port_number> = 1 for controller #1, 2 for controller #2, 0 for both ports

--> Restores checking controller input on each NMI loop for the specified port.

--> Returns nothing.

 

cv.ctrl.trackballState(<port_number>)

<port_number> = 1 for controller port #1 or 2 for controller port #2

--> Returns the last recorded state of the trackball (on the Roller Controller).

 

cv.ctrl.steeringWheelState(<port_number>)

<port_number> = 1 for controller port #1 or 2 for controller port #2

--> Returns the last recorded state of the steering wheel (on Expansion Module #2).

 

cv.ctrl.gasPedalState(<port_number>)

<port_number> = 1 for controller port #1 or 2 for controller port #2

--> Returns the last recorded state of the gas pedal (on Expansion Module #2).

 

cv.ctrl.spinnerState(<port_number>)

<port_number> = 1 for controller port #1 or 2 for controller port #2

--> Returns the last recorded state of the Super Controller spinner on the specified port.

 

I'm sure there will be some adjustments and many more functions to add to the list above, but the beauty of it is that we can separate the CV stuff from the SEM stuff easely. For example:

 

sem.gmode4.initialize()

 

Oh, I think I still have an email from you to reply... :)

982806[/snapback]

Haven't received a reply yet. ;)

Edited by Pixelboy
Link to comment
Share on other sites

You might want to see if you can utilize YACC for this in any way. I was trying to work out an improved Basic Programming cart for VCS with a little better language a while back, and ended up messing with Yacc before scrapping the project--it helped a lot, and probably would moreso for this more complicated language.

 

Just my $.02 :) As an admitted programming langauge theory nerd, I like the looks of the language, feels Java-ish, but if everything is part of the CV "class" then why does it have to be written with every... erm... "function call"? Isn't that a little redundantly redundant? (sorry, couldnt resist the "redundant" joke)

Edited by ~llama
Link to comment
Share on other sites

You might want to see if you can utilize YACC for this in any way. I was trying to work out an improved Basic Programming cart for VCS with a little better language a while back, and ended up messing with Yacc before scrapping the project--it helped a lot, and probably would moreso for this more complicated language.

My experience of YACC has been that it generates nice stuff, but the parser it produces doesn't work very well. What I mean is that when a programmer makes some kind of syntax error in his code, the parser will sometimes produce incorrect error messages, or indicate errors on the incorrect line number of the source code. Frankly, I'd rather work on my own parser, if only for the fun of it. :)

 

 

Just my $.02 :) As an admitted programming language theory nerd, I like the looks of the language, feels Java-ish, but if everything is part of the CV "class" then why does it have to be written with every... erm... "function call"? Isn't that a little redundantly redundant? (sorry, couldnt resist the "redundant" joke)

983235[/snapback]

Well, the idea is just to give the language some consistency. For example, all functions related to Graphic Mode 1 fall under "cv.gmode1", which means that if the programmer wants to define a new function called "setTileColor()", he can do it without conflicting with the basic pre-defined functions of the language.

 

Also, not everything falls under the "cv" master object. All of the functions related to Eduardo's SEM will be regrouped under the "sem" master object, which means that if the game programmer wants to make a game for the basic CV hardware, all he has to do is refrain from using any pre-defined function that starts with "sem.".

 

As far as the IDE is concerned, the proposed syntax also offers some advantages when it come to automatic word completion, which will be a readily available feature if we use SpeedBasic as a basis of our IDE. (Which reminds me: I'll have to study SpeedBasic under the hood one of these days...)

Link to comment
Share on other sites

I really feel better today, so I was writing some documentation about the SEM when the idea of new bitmapped, framebuffer based video modes started to look not so good to me. I mean, they seemed such a great idea months ago, they were so powerful and flexible... I started to wonder if someone beside me would be able to use those beasts. The blitter makes things so much more complex and eat cycles for lunch. Suddenly I realised that I would do a lot better if I go with tiles. CV people are already used to them....

Well, back to the drawing board... :(

 

Eduardo

Link to comment
Share on other sites

I really feel better today, so I was writing some documentation about the SEM when the idea of new bitmapped, framebuffer based video modes started to look not so good to me. I mean, they seemed such a great idea months ago, they were so powerful and flexible... I started to wonder if someone beside me would be able to use those beasts. The blitter makes things so much more complex and eat cycles for lunch. Suddenly I realised that I would do a lot better if I go with tiles. CV people are already used to them....

983267[/snapback]

You won't hear any complains from me about using tiles, but are you still planning to offer split-screen features, with independent scrolling? If yes, how will sprites behave in split-screen situations?

Link to comment
Share on other sites

  • 3 weeks later...

Hi!

 

So 2005 is coming to an end and it is now time to start planning 2006. Next year I am planning to take my CV projects to new directions. Ok, Magical Tree will be released this January, then Pac-Man Collection sometime before June, then maybe a game or two in the 2nd half of the year. But my attention is now shifting to two very interesting projects: the BasicVision development tool and the CV87/SEM module. I am about to complete my implementation of the CV87 in software emulated form, and hope to start FPGA implementation before March. The CV87 will include a complete CV-in-a-chip plus the SEM module. Personally I think that 2006 will bring a lot of fun… :)

 

You won't hear any complains from me about using tiles, but are you still planning to offer split-screen features, with independent scrolling? If yes, how will sprites behave in split-screen situations?

 

Sprites can be turned on or off for each panel, but you can't have independent sprites for each panel. I mean, sprites are a completely independent plane. I was thinkink and I believe that Command would be a nice choice as a first game for the CV9956. The specs seems to be very similar...

 

Eduardo

Link to comment
Share on other sites

Hi!

 

So 2005 is coming to an end and it is now time to start planning 2006. Next year I am planning to take my CV projects to new directions. Ok, Magical Tree will be released this January, then Pac-Man Collection sometime before June, then maybe a game or two in the 2nd half of the year. But my attention is now shifting to two very interesting projects: the BasicVision development tool and the CV87/SEM module. I am about to complete my implementation of the CV87 in software emulated form, and hope to start FPGA implementation before March. The CV87 will include a complete CV-in-a-chip plus the SEM module. Personally I think that 2006 will bring a lot of fun… :)

And it will also be a year of learning experiences. I know it will be for me. :cool:

 

 

You won't hear any complains from me about using tiles, but are you still planning to offer split-screen features, with independent scrolling? If yes, how will sprites behave in split-screen situations?

 

Sprites can be turned on or off for each panel, but you can't have independent sprites for each panel. I mean, sprites are a completely independent plane.

So you can't have a sprite partly displayed off the edge of a sub-screen in a split-screen situation? That doesn't sound very useful... :|

 

 

I was thinkink and I believe that Command would be a nice choice as a first game for the CV9956. The specs seems to be very similar...

"Command"? What's that?

Link to comment
Share on other sites

You won't hear any complains from me about using tiles, but are you still planning to offer split-screen features, with independent scrolling? If yes, how will sprites behave in split-screen situations?

 

Sprites can be turned on or off for each panel, but you can't have independent sprites for each panel. I mean, sprites are a completely independent plane.

So you can't have a sprite partly displayed off the edge of a sub-screen in a split-screen situation? That doesn't sound very useful... :|

 

No, you can. I was meaning that you can't use a different sprite attribute table for each panel

 

I was thinkink and I believe that Command would be a nice choice as a first game for the CV9956. The specs seems to be very similar...

"Command"? What's that?

991768[/snapback]

 

Duh! Commando.... Sorry... :P

 

Eduardo

Link to comment
Share on other sites

Here are some specs of the "new" CV9956, now tile based:

 

Main Features

 

- Custom video fully backward compatible with Texas TMS9928

- 64KB of VRAM, 32KB of sprite RAM, 256 x 9bits of colorRAM (CRAM)

- 16 palettes with 16 colors

- Two new screen modes, tile based (tile pattern is 8x8 pixels)

o Graphics 3 - 256x224, 2 planes. Plane A is 4 bits per pixel (16 colors per tile), 1024 patterns. Plane B is 3 bits per pixel (8 colors per tile), 1024 patterns

o Graphics 4 - 256x224, 1 plane. Plane A is 8 bits per pixel (64 colors per tile from 256 available), 1024 patterns

- Planes can be vertically split, with resulting left and right panels having different properties.

- Hardware smooth scroll.

- Programmable scanline interruption.

- New sprite mode 2 - 96 sprites on screen from 256 patterns (16x16 pixels), 4 bits per pixel, 16 sprites per scanline max.

- Tiles and Sprites can use any palette, flip bits added to allow mirroring in X and Y axis.

- Very fast DMA for transferring data blocks between RAM/VRAM and VRAM areas.

- The display processor can execute a “display program”, which is stored in VRAM. Display processor can change display properties at scanline basis.

- New set of 4 I/O ports, for VDP register access, VRAM access and CRAM access.

 

Timing

 

The CV9956 VDP has 4 times more memory bandwidth than the original TMS9928. It is possible by doubling the master clock, from 10.75MHz to 21.58MHz, as well as using a faster VRAM memory.

With such bandwidth the CV9956 can display two independent tile planes, as well as 96 sprites on screen at the same time. Additionally it allows the new Display Processor to use16 memory cycles per scanline. VRAM access by the CPU has now doubled from 11 accesses per scanline maximum to 22 accesses. The new DMA will help to alleviate transfers to the VRAM by the main CPU, and at the same time will improve transfer speed. During active scan DMA speed is the same as the main CPU, but during HBlank it can be 6~8 times faster.

 

Registers

 

The CV9956 has 31 video registers, including the original 8, plus two status registers.

 

DMA

 

DMA can transfer data block from RAM/ROM to VRAM, VRAM to VRAM and fill VRAM. When transferring from RAM/ROM, the main Z80 will be taken out of the bus. It's possible even for the SEM, since the CV has all necessary lines in the expansion port. The other two modes don't stop the main processor, however the Z80 can't access VRAM during DMA.

 

Display Processor

 

Can load new data to registers in a line by line basis. The display program can utilize up to 16 bytes per scanline and need to be shorter than 2KB

 

 

I will post a complete document here soon. Unfortunately my main doc is heavily formatted, not allowing me to copy&paste it here.

Once you check the new specs, it will be clear that the CV9956 is more powerful than the SMS VDP, generally more powerful than the PC-Engine/TurboGraphx VDP and generally a bit inferior the MegaDrive/Genesis VDP.

 

Eduardo

Link to comment
Share on other sites

While reading those specs for the CV87 (which look very promissing BTW), a question popped into my mind: Would it be very complicated to add support for the ADAM datasette games? It's far from being an important requirement, but it would be fun if the SEM had just enough ADAM support to play Super Buck Rogers, Dragon's Lair, Super Donkey Kong, Super Donkey Kong Jr. and Super Zaxxon. I once played Dragon's Lair on the AdamEm emulator, so I know it's possible... :D

Link to comment
Share on other sites

While reading those specs for the CV87 (which look very promissing BTW), a question popped into my mind: Would it be very complicated to add support for the ADAM datasette games? It's far from being an important requirement, but it would be fun if the SEM had just enough ADAM support to play Super Buck Rogers, Dragon's Lair, Super Donkey Kong, Super Donkey Kong Jr. and Super Zaxxon. I once played Dragon's Lair on the AdamEm emulator, so I know it's possible... :D

991977[/snapback]

 

 

I don't have enough technical details about the ADAM, so I don't know. Probably it isn't possible, since the ADAM, like the SEM, disables the internal CV memory and I/O mapping IC's, leading to a possible conflict with the new SEM mapping. The question is, can I disable memory and I/O mapping using the ADAM's expansion port? Even in case it is possible, you would end loosing almost all ADAM capabilities.

 

BTW, my plans are to starting selling CV87 kits later this year. Initially it will run all CV games. SEM capabilities will be added later, as a downloable upgrade (for free). The board will come with a Spartan3 FPGA, a CompactFlash or SD card slot, 2 joystick ports, VGA and composite video, stereo audio, cartridge slot and expansion port.

 

Eduardo

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...