Jump to content
IGNORED

The OS7 Journey, let's use it!


tschak909

Recommended Posts

I've done the first pass of disassembly doing annotation of code blocks, labels, and cross references, using the OS7 absolute listings, and other sources as cross reference.

 

I have created a folder called sre/ in the GitHub repo:

https://github.com/tschak909/os7lib/tree/main/sre

 

It currently contains both an ASCII text output of the disassembly, along with a Ghidra ZIP file containing the entire project context. This can be imported with Ghidra:

https://ghidra-sre.org/

 

Here is an example screenshot from function graph viewer on PUT_OBJ, you can see roughly a third of it, and it's a huge function, but it's now much easier to see the flow and relationships between each part of it.

 

sre_function_graph.thumb.png.63a32f3d7a6d5d87b83a5395ecd63b49.png

 

-Thom

 

Link to comment
Share on other sites

UNK_B47C:

                DB 0F0H
                DB  1FH
                DB  18H
                DW DONKEY_KONG_PAT
                DW DONKEY_K_CENTER
                DW DONKEY_K_LEFT
                DW DONKEY_K_RIGHT
DONKEY_K_CENTER:

                DB 006,004
                DB  1FH, 20H, 21H, 22H, 23H, 1FH
                DB  24H, 25H, 26H, 27H, 28H, 29H
                DB  1FH, 2AH, 2BH, 2CH, 2DH, 1FH
                DB  2EH, 2FH, 30H, 31H, 32H, 33H
DONKEY_K_LEFT: 

                DB 006,004
                DB  34H, 35H, 36H, 37H, 1FH, 1FH
                DB  38H, 39H, 3AH, 3BH, 1FH, 1FH
                DB  3CH, 3DH, 3EH, 3FH, 40H, 1FH
                DB  41H, 42H, 43H, 44H, 45H, 1FH
DONKEY_K_RIGHT:

                DB 006,004
                DB  7BH, 7BH, 93H, 92H, 91H, 90H
                DB  7BH, 7BH, 97H, 96H, 95H, 94H
                DB  7BH, 9CH, 9BH, 9AH, 99H, 98H
                DB  7BH,0A1H,0A0H, 9FH, 9EH, 9DH
                DW UNK_B4DB
                DW $7190
                DB 0FFH
                DB 0BFH
UNK_B4DB:

                DB 0F0H
                DB  5EH
                DB    8
                DW FIRE_BARREL_PAT
                DW FIRE_BARREL
                DW FIRE_BARREL

 

This is somewhere around where your working


After I clean up a few things I will post my disassembly and then you can finish the pattern definitions from your research and merge the two works.
I think somewhere along the line you can get a whole picture.

I am finding both in Smurf and DK that there are parts that are important to the program but have no links to them outside of some Stack Pointer exchange.

 

Another disturbing issue are the Pascal entry points in Smurf which seems to have been taken out of DK 24k when they created DK 16k.
There are a couple of issues there and if I can resolve the missing data I can then remove all the PASCAL crap and have a cleaner Smurf.
And everyone wants a cleaner Smurf just ask my wife.

Edited by Captain Cozmos
Link to comment
Share on other sites

Spending today filling in object data from Donkey Kong (16K):

 

Let's take a good look at Donkey Kong, which is, a complex object. Complex objects are made up of one or more SEMI-MOBILE or SPRITE objects (MOBILE objects can't be a part of complex objects, I can understand why COLECO did NOT want to open that Pandora's box of edge cases!).

 

The composite object

image.png.65c0d017322ea81e24f1a613a47d73ee.png

The face 16x16 sprite object:

image.png.3752138563755e0e7e55b71e6ee8aa7f.png

And Donkey Kong's body, which lives on the background layer:

image.png.736df54e04123ceb74bce7d19e4fb5dc.png

As you can see, This complex object comprises two child objects:

                             COMPLEX_OBJECT_DONKEY_KONG                      XREF[1]:     FUN_ram_8b1a:8c39(*)  
        ram:b43d 45 b4           dw         B445h                                            COMPLEX OBJECT
                                                                                             ram:b445 Graphics
        ram:b43f cd 71           dw         71CDh                                            ram:71cd Status object
        ram:b441 64 b4           dw         B464h                                            ram:b464 1st Component
        ram:b443 76 b4           dw         B476h                                            ram:b476 2nd Component

 

From the ColecoVision Programmer's Guide Rev 5 (this is all in Appendix B):

image.thumb.png.48c7b3386fd84e0d2de59780f2751c63.png

The graphics object, and the two component child objects have addresses in ROM, while the status area (which governs the state of the object as a whole) is in RAM.

 

There are two child objects, so the graphics object looks like this:

                             DONKEY_KONG_GRAPHICS
        ram:b445 24              db         24h                                              Complex Obj with 2 components
        ram:b446 52 b4           addr       DONKEY_KONG_GRAPHICS_FRAME0                      Now a list of pointers to each f
                                                                                             with frame #s and pixel offsets 
        ram:b448 58 b4           addr       DONKEY_KONG_GRAPHICS_OFFSET0                     ...
        ram:b44a 54 b4           addr       DONKEY_KONG_GRAPHICS_FRAME1                      ...
        ram:b44c 5c b4           addr       DONKEY_KONG_GRAPHICS_OFFSET1                     ...
        ram:b44e 56 b4           addr       DONKEY_KONG_GRAPHICS_FRAME2                      ...
        ram:b450 60 b4           addr       DONKEY_JONG_GRAPHICS_OFFSET2                     ...end of list

 

The whole structure is explained here:

image.thumb.png.aa772eb910403e67327a11bcf8788156.png

Since we have two objects we're describing here, the MSN of OBJ_TYPE is 2, while the LSN is 4 (for complex object)

 

This is followed by a list of pointers to FRAME and OFFSET tables.

 

FRAME_X is simple, and simply a list of frame numbers for the child object, to use for the frame object of the parent. This is literally so that you can re-use frame objects for multiple frames, and potentially cut down on used ROM space. But in this case, there are separate frame objects for each individual child part.

 

                             DONKEY_KONG_GRAPHICS_FRAME0                     XREF[1]:     ram:b446(*)  
        ram:b452 00              db         0h                                               component 0 uses frame 0
        ram:b453 00              db         0h                                               component 1 uses frame 0
                             DONKEY_KONG_GRAPHICS_FRAME1                     XREF[1]:     ram:b44a(*)  
        ram:b454 01              db         1h                                               component 0 uses frame 1
        ram:b455 01              db         1h                                               component 1 uses frame 1
                             DONKEY_KONG_GRAPHICS_FRAME2                     XREF[1]:     ram:b44e(*)  
        ram:b456 02              db         2h                                               component 0 uses frame 2
        ram:b457 02              db         2h                                               component 1 uses frame 2

 

OFFSET_X is is similar, just a linear list of X and Y offsets for each frame of the parent object, the X and Y positions are relative to the X and Y position of the parent.

 

                             DONKEY_KONG_GRAPHICS_OFFSET0                    XREF[1]:     ram:b448(*)  
        ram:b458 10              db         10h                                              X offset frame 0 component 0
        ram:b459 00              db         0h                                               Y offset frame 0 component 0
        ram:b45a 00              db         0h                                               X offset frame 0 component 1
        ram:b45b 00              db         0h                                               Y offset frame 0 component 1
                             DONKEY_KONG_GRAPHICS_OFFSET1                    XREF[1]:     ram:b44c(*)  
        ram:b45c 00              db         0h                                               X offset frame 1 component 0
        ram:b45d 00              db         0h                                               Y offset frame 1 component 0
        ram:b45e 00              db         0h                                               X offset frame 1 component 1
        ram:b45f 00              db         0h                                               Y offset frame 1 component 1
                             DONKEY_JONG_GRAPHICS_OFFSET2                    XREF[1]:     ram:b450(*)  
        ram:b460 20              db         20h                                              X offset frame 2 component 0
        ram:b461 00              db         0h                                               Y offset frame 2 component 0
        ram:b462 00              db         0h                                               X offset frame 2 component 1
        ram:b463 00              db         0h                                               Y offset frame 2 component 1


Since the X and Y position of the face needs to change, depending on which frame is being displayed, component 0 has different offsets.

 

Once the composite object and its frames and offsets have been defined, we need the object definition for each of the children:

 

First, the head sprite, which needs to be a sprite,because it needs to be accurately positioned along single pixel boundaries:

                             DONKEY_KONG_HEAD_SPRITE_OBJECT
        ram:b464 69 b4           addr       DONKEY_KONG_HEAD_SPRITE_GRAPHICS                 ram:b469 GRAPHICS
        ram:b466 d4 71           char *     DONKEY_KONG_HEAD_SPRITE_STATUS                   ram:71d4 STATUS
        ram:b468 0c              db         Ch                                               START AT SPRITE INDEX 0x0C

 

Sprite objects are defined as:

image.thumb.png.3c5ef66776ff4efb55a34448647015b4.png

Of note here is the SPRITE_INDEX, which specifies the sprite slot (0-31) to use for this particular sprite, in this case, it's 0x0C, or sprite #12, and sure enough, if we look at the sprite dump in the VDP, we see in the 13th slot:

image.thumb.png.e460e325d7e9ec199648315b12edee9c.png

 

Which brings us to the GRAPHICS object:

image.thumb.png.6a9cd8f69a480710fea39cebaafa7398.png

and in context:

                             DONKEY_KONG_HEAD_SPRITE_GRAPHICS                XREF[1]:     ram:b464(*)  
        ram:b469 03              db         OBJ_TYPE_SPRITE
        ram:b46a b4              db         B4h                                              Donkey Kong's Face starts at spr
        ram:b46b b3 a6           addr       DONKEY_KONG_HEAD_GENERATORS                      pointer to generator bitmaps
        ram:b46d 14              db         DONKEY_KONG_HEAD_NUMGEN                          20 ($14) generators used
        ram:b46e 70 b4           addr       DONKEY_KONG_FRAME_TABLE                          pointer to frame table

 

Note the B4h, which corresponds exactly to the corresponding tile in the SPRITE GENERATOR table. ACTIVATE will use this as the destination for where to start copying generator data from the generators field immediately below it, along with NUMGEN which specifies how many of said  generators need to be copied. Since we are dealing with 16x16 sprites here, we need to copy a multiple of four generators for each and every frame of the sprite.

 

Finally, we have a pointer to the frame table for each possible sprite state:

image.thumb.png.7274e668f8108fca3086794c4a7175eb.png

and in context:

                             DONKEY_KONG_FRAME_TABLE                         XREF[1]:     ram:b46e(*)  
        ram:b470 0f              db         WHITE_ON_TRANSPARENT
        ram:b471 00              db         0h                                               $B4 straight ahead
        ram:b472 0f              db         WHITE_ON_TRANSPARENT
        ram:b473 04              db         4h                                               $B8 facing left
        ram:b474 0f              db         WHITE_ON_TRANSPARENT
        ram:b475 08              db         8h                                               $BC Facing right

 

As we saw in the images above, Donkey Kong's face foreground is white, and it stays that way for all three frames. The background color is transparent, thus the byte 0FH.

 

and if we look at the address for the generaators (A6B3, if you look at the listing bytes, or by double clicking DONKEY_KONG_HEAD_GENERATORS in Ghidra), we see:

image.thumb.png.c54e6e87666ab86baec760afaf8d5008.png

and if we look in this area with a binary pixel viewer, we see:

image.thumb.png.26b8fe87e69812a5dc6ebd46ac2fd20a.png

Each bit of sprite information is stored sequentially, in the order the VDP needs it.

 

This brings us to the SEMI-MOBILE object needed for the body.

 

Since the body doesn't move that much, and it's very large, it's implemented as a semi-mobile object, which is basically a collection of background tiles, that get loaded into the PATTERN NAME TABLE via the ACTIVATE call. Because no image processing is done on these tiles when they are put onto the background, they must be positioned along tile (8 pixel) boundaries, which is fine here.

 

The definition of the SMO object is as thus:

image.thumb.png.8d31cd8a387997fddffa3475000ebdcf.png

 

 And in context:

                             DONKEY_KONG_BODY_SMO
        ram:b476 7c b4           addr       DONKEY_KONG_BODY_GRAPHICS                        Donkey Kong Body Graphics
        ram:b478 b4 71           addr       DONKEY_KONG_BODY_STATUS                          Donkey Kong Body Status
        ram:b47a ff bf           addr       NOT_USED                                         Old Screen Data not used; disable.

 

We see pointers to the GRAPHICS and STATUS objects, just like we did with the sprite object. But since the semi-mobile objects operate on the background, there is an additional field called OLD_SCREEN, which functions as a backing store, temporarily saving tiles that get overwritten by the object, and restoring them when the object moves or the frame changes. You can even choose to put this either in VRAM (faster) or in RAM, which is very clever IMHO.

 

First, the SMO graphics object:

image.thumb.png.f330decc5528896f10ba3c7b8a1f9a56.png

And in Context:

                             DONKEY_KONG_BODY_GRAPHICS                       XREF[1]:     ram:b476(*)  
        ram:b47c f0              db         F0h                                              OBJ TYPE 0 (SMO) appearing in al
        ram:b47d 1f              db         1Fh                                              FIRST GEN USED IS $1F
        ram:b47e 18              ??         18h                                              Kong body needs 24 ($18) gens in
        ram:b47f cb a8           addr       DONKEY_JONG_BODY_GENERATORS                      Ptr to Kong Body Generators
        ram:b481 87 b4           addr       DONKEY_KONG_BODY_FRAME0                          Ptr to Donkey Kong Body Frame 0
        ram:b483 a1 b4           addr       DONKEY_KONG_BODY_FRAME1                          Ptr to Donkey Kong Body Frame 1
        ram:b485 bb b4           addr       DONKEY_KONG_BODY_FRAME2                          Ptr to Donkey Kong Body Frame 2

The object type, is F0, and if you read the note about the MSN for OBJ_TYPE above, you'll see that for mode 2 graphics, the upper three bits explicitly control which of the three M2 PATTERN GENERATORS to copy the tiles into, if you know that you're only going to be using the graphic on the upper third of the screen, you can set bit 7. They set all three of these bits here, so if we look at the PATTERN GENERATOR TABLES we see Donkey Kong's body copied, three times.

 image.thumb.png.99869214003bb9bec0c87dff8168c364.png

Bit 4 is also set, which specifies that only one color generator per tile will be used, this puts the same foreground/background for each individual tile specified.

 

0x1F specifies the first generator that is used by this SEMI MOBILE OBJECT, the generators are copied from the DONKEY_KONG_BODY_GENERATORS in the cartridge rom to this position in the PATTERN GENERATORS table.

 

NUMGEN specifies the number of 8x8 generator tiles to copy, in this case 24.

 

This is followed by a pointer to the area in the cartridge ROM (or system RAM) that will hold the PATTERN GENERATORS to copy over. They are arranged sequentially, and up to the NUMGEN specified.

 

And immediately after there are pointers to the individual FRAME objects, one for each frame needed.

 

The FRAME objects are specified as:

image.thumb.png.f6c1a22b8452b9a749a98fd088c443d8.png

And in context:

                             DONKEY_KONG_BODY_FRAME0                         XREF[1]:     ram:b481(*)  
        ram:b487 06              db         6h                                               Donkey Kong Body X extent for Fr
        ram:b488 04              db         4h                                               Donkey Kong Body Y extent for Fr
        ram:b489 1f              db         1Fh                                              Generator for X 0 Y 0
        ram:b48a 20              db         20h                                              Generator for X 1 Y 0
        ram:b48b 21              db         21h                                              Generator for X 2 Y 0
        ram:b48c 22              db         22h                                              Generator for X 3 Y 0
        ram:b48d 23              db         23h                                              Generator for X 4 Y 0
        ram:b48e 1f              db         1Fh                                              Generator for X 5 Y 0
        ram:b48f 24              db         24h                                              Generator for X 0 Y 1
        ram:b490 25              db         25h                                              Generator for X 1 Y 1
        ram:b491 26              db         26h                                              Generator for X 2 Y 1
        ram:b492 27              db         27h                                              Generator for X 3 Y 1
        ram:b493 28              db         28h                                              Generator for X 4 Y 1
        ram:b494 29              db         29h                                              Generator for X 5 Y 1
        ram:b495 1f              db         1Fh                                              Generator for X 0 Y 2
        ram:b496 2a              db         2Ah                                              Generator for X 1 Y 2
        ram:b497 2b              db         2Bh                                              Generator for X 2 Y 2
        ram:b498 2c              db         2Ch                                              Generator for X 3 Y 2
        ram:b499 2d              db         2Dh                                              Generator for X 4 Y 2
        ram:b49a 1f              db         1Fh                                              Generator for X 5 Y 2
        ram:b49b 2e              db         2Eh                                              Generator for X 0 Y 3
        ram:b49c 2f              db         2Fh                                              Generator for X 1 Y 3
        ram:b49d 30              db         30h                                              Generator for X 2 Y 3
        ram:b49e 31              db         31h                                              Generator for X 3 Y 3
        ram:b49f 32              db         32h                                              Generator for X 4 Y 3
        ram:b4a0 33              db         33h                                              Generator for X 5 Y 3
                             DONKEY_KONG_BODY_FRAME1                         XREF[1]:     ram:b483(*)  
        ram:b4a1 06              db         6h                                               Donkey Kong Body X Extent for Fr
        ram:b4a2 04              db         4h                                               Donkey Kong Body Y Extent for Fr
        ram:b4a3 34              db         34h                                              Generator for X 0 Y 0
        ram:b4a4 35              db         35h                                              Generator for X 1 Y 0
        ram:b4a5 36              db         36h                                              Generator for X 2 Y 0
        ram:b4a6 37              db         37h                                              Generator for X 3 Y 0
        ram:b4a7 1f              db         1Fh                                              Generator for X 4 Y 0
        ram:b4a8 1f              db         1Fh                                              Generator for X 5 Y 0
        ram:b4a9 38              db         38h                                              Generator for X 0 Y 1
        ram:b4aa 39              db         39h                                              Generator for X 1 Y 1
        ram:b4ab 3a              db         3Ah                                              Generator for X 2 Y 1
        ram:b4ac 3b              db         3Bh                                              Generator for X 3 Y 1
        ram:b4ad 1f              db         1Fh                                              Generator for X 4 Y 1
        ram:b4ae 1f              db         1Fh                                              Generator for X 5 Y 1
        ram:b4af 3c              db         3Ch                                              Generator for X 0 Y 2
        ram:b4b0 3d              db         3Dh                                              Generator for X 1 Y 2
        ram:b4b1 3e              db         3Eh                                              Generator for X 2 Y 2
        ram:b4b2 3f              db         3Fh                                              Generator for X 3 Y 2
        ram:b4b3 40              db         40h                                              Generator for X 4 Y 2
        ram:b4b4 1f              db         1Fh                                              Generator for X 5 Y 2
        ram:b4b5 41              db         41h                                              Generator for X 0 Y 3
        ram:b4b6 42              db         42h                                              Generator for X 1 Y 3
        ram:b4b7 43              db         43h                                              Generator for X 2 Y 3
        ram:b4b8 44              db         44h                                              Generator for X 3 Y 3
        ram:b4b9 45              db         45h                                              Generator for X 4 Y 3
        ram:b4ba 1f              db         1Fh                                              Generator for X 5 Y 3
                             DONKEY_KONG_BODY_FRAME2                         XREF[1]:     ram:b485(*)  
        ram:b4bb 06              db         6h                                               Donkey Kong Body X Extent for fr
        ram:b4bc 04              db         4h                                               Donkey Kong Body Y Extent for fr
        ram:b4bd 7b              db         7Bh                                              Generator for X 0 Y 0
        ram:b4be 7b              db         7Bh                                              Generator for X 1 Y 0
        ram:b4bf 93              db         93h                                              Generator for X 2 Y 0
        ram:b4c0 92              db         92h                                              Generator for X 3 Y 0
        ram:b4c1 91              db         91h                                              Generator for X 4 Y 0
        ram:b4c2 90              db         90h                                              Generator for X 5 Y 0
        ram:b4c3 7b              db         7Bh                                              Generator for X 0 Y 1
        ram:b4c4 7b              db         7Bh                                              Generator for X 1 Y 1
        ram:b4c5 97              db         97h                                              Generator for X 2 Y 1
        ram:b4c6 96              db         96h                                              Generator for X 3 Y 1
        ram:b4c7 95              db         95h                                              Generator for X 4 Y 1
        ram:b4c8 94              db         94h                                              Generator for X 5 Y 1
        ram:b4c9 7b              db         7Bh                                              Generator for X 0 Y 2
        ram:b4ca 9c              db         9Ch                                              Generator for X 1 Y 2
        ram:b4cb 9b              db         9Bh                                              Generator for X 2 Y 2
        ram:b4cc 9a              db         9Ah                                              Generator for X 3 Y 2
        ram:b4cd 99              db         99h                                              Generator for X 4 Y 2
        ram:b4ce 98              db         98h                                              Generator for X 5 Y 2
        ram:b4cf 7b              db         7Bh                                              Generator for X 0 Y 3
        ram:b4d0 a1              db         A1h                                              Generator for X 1 Y 3
        ram:b4d1 a0              db         A0h                                              Generator for X 2 Y 3
        ram:b4d2 9f              db         9Fh                                              Generator for X 3 Y 3
        ram:b4d3 9e              db         9Eh                                              Generator for X 4 Y 3
        ram:b4d4 9d              db         9Dh                                              Generator for X 5 Y 3

 

Each frame contains the X and Y extents for each frame, that is, the width and the height of the object for that frame, and this is followed by the names of each tile starting with 0,0 and ending with X_EXTENT and Y_EXTENT, going in row-order. If we look at the tiles, we see the left most pixels for DK's head :)

 image.thumb.png.265f34d24db71914d832ab5c2096b0e5.png

I will finish, with one last note. I didn't go over the STATUS object, because while they are slightly different for each object, they contain the same basic information that the programmer can manipulate to change the position of an object, its frame, etc. Modifying the status object, and calling PUT_OBJ again, will cause the object to change appropriately.

 

Whew, that was a lot, but I wanted to get this out there. 

 

More to come. :)

 

-Thom

 

 

  • Like 1
Link to comment
Share on other sites

If you had to put it in a particular format, this is the way I do it.

 

 DB 6, 4 corresponds to the actual frame

 

6 patterns across by 4 rows down

 

This represents the entire body

 

KONG_CENTER_FRAME_A:
    DB 6H,4H
    DB 1FH, 20H, 21H, 22H, 23H, 1FH
    DB 24H, 25H, 26H, 27H, 28H, 29H
    DB 1FH, 2AH, 2BH, 2CH, 2DH, 1FH
    DB 2EH, 2FH, 30H, 31H, 32H, 33H
KONG_LEFT_FRAME_B:
    DB 6H,4H
    DB 34H, 35H, 36H, 37H, 1FH, 1FH
    DB 38H, 39H, 3AH, 3BH, 1FH, 1FH
    DB 3CH, 3DH, 3EH, 3FH, 40H, 1FH
    DB 41H, 42H, 43H, 44H, 45H, 1FH
KONG_RIGHT_FRAME_C:
    DB 6H,4H
    DB 7BH, 7BH, 93H, 92H, 91H, 90H
    DB 7BH, 7BH, 97H, 96H, 95H, 94H
    DB 7BH, 9CH, 9BH, 9AH, 99H, 98H
    DB 7BH,0A1H,0A0H, 9FH, 9EH, 9DH

Link to comment
Share on other sites

9 minutes ago, Captain Cozmos said:

If you had to put it in a particular format, this is the way I do it.

 

 DB 6, 4 corresponds to the actual frame

 

6 patterns across by 4 rows down

 

This represents the entire body

 

KONG_CENTER_FRAME_A:
    DB 6H,4H
    DB 1FH, 20H, 21H, 22H, 23H, 1FH
    DB 24H, 25H, 26H, 27H, 28H, 29H
    DB 1FH, 2AH, 2BH, 2CH, 2DH, 1FH
    DB 2EH, 2FH, 30H, 31H, 32H, 33H
KONG_LEFT_FRAME_B:
    DB 6H,4H
    DB 34H, 35H, 36H, 37H, 1FH, 1FH
    DB 38H, 39H, 3AH, 3BH, 1FH, 1FH
    DB 3CH, 3DH, 3EH, 3FH, 40H, 1FH
    DB 41H, 42H, 43H, 44H, 45H, 1FH
KONG_RIGHT_FRAME_C:
    DB 6H,4H
    DB 7BH, 7BH, 93H, 92H, 91H, 90H
    DB 7BH, 7BH, 97H, 96H, 95H, 94H
    DB 7BH, 9CH, 9BH, 9AH, 99H, 98H
    DB 7BH,0A1H,0A0H, 9FH, 9EH, 9DH

I don't agree. The way I have presented it above, is more understandable in context.

... hmm.. maybe, but.. i'm thinking... I wanted to deliberately point out in comments how each name is explicitly laid out.

-Thom

Edited by tschak909
Link to comment
Share on other sites

I look at it as the first constant 6 as 6 across so when it prints to vram into the name table as in


1,2,3,4,5,6

then for each of the second constant it would add 32 to get to the next row.

 

1,2,3,4,5,6 + 32 (1)
1,2,3,4,5,6 + 32 (2)

1,2,3,4,5,6 + 32 (3)

1,2,3,4,5,6 + 32 (4)

In reality the math would look like

OFFSET  23 (place in name table) + 1,2,3,4,5,6 + 32 ect....
23 being a number I picked randomly it could be anything from 0 to 766

Being in Mode two, it would be 0-255 each third of the screen and the patterns/colors have to also be in the third being printed.
Each pattern has to have all 8 lines each of it's on color.

In mode I it is 0-766 and one set of patterns but each 8 patterns can have only one color to save VRAM for the design of the VDP

I'm just ranting at this point.

Edited by Captain Cozmos
Link to comment
Share on other sites

Just now, Captain Cozmos said:

I look at it as the first constant 6 as 6 across so when it prints to vram into the name table as in


1,2,3,4,5,6

then for each of the second constant it would add 32 to get to the next row.

 

1,2,3,4,5,6 + 32 (1)
1,2,3,4,5,6 + 32 (2)

1,2,3,4,5,6 + 32 (3)

1,2,3,4,5,6 + 32 (4)

In reality the math would look like

OFFSET  23 (place in name table) + 1,2,3,4,5,6 + 32 ect....
23 being a number I picked randomly it could be anything from 0 to 766

But being in Mode two, it would be 0-255 each third of the screen and the patterns/colors have to also be in the third being printed.
Each pattern has to have all 8 lines each of it's on color.

In mode I it is 0-766 and one set of patterns but each 8 patterns can have only one color to save VRAM for the design of the VDP

I'm just ranting at this point.

I know those moments. :)

-Thom

Link to comment
Share on other sites

An interesting note:

 

This is what the Smurf Character is made up of
 

SMURF_OBJECT:

                 DW byte_A091
                 DW $7298
                 DW SMURF_TABLE_A
                 DW SMURF_TABLE_B
                 DW SMURF_TABLE_C
                 DW SMURF_TABLE_D
                 DB 44h

Meaning this is a Complex Object made up of 4 animations hence the 44H  High 4 (frames) and Low 4 (complex)

The only thing making this a complex is that it is an animated sprite with no patterns attached.

So one would assume that all animated sprites would fall under the complex designation.

BTW, sent you a PM.

Edited by Captain Cozmos
Link to comment
Share on other sites

I have added examples to OS7LIB for the four table-level transforms:

 

* ROTATE_90

* REFLECT_VERTICAL

* REFLECT_HORIZONTAL

* ENLARGE (for each tile, make two of double size)

 

They are in the examples folder:

https://github.com/tschak909/os7lib/tree/main/examples

 

Note: These are relatively self explanatory, with one note, VERTICAL and HORIZONTAL refer to the AXIS by which the rotation takes place, so they may behave opposite of what you might think.

 

The interesting thing is that since these functions wrap GET and PUT_VRAM, they are table-aware, you can rotate, reflect, and enlarge the sprite and background pattern generators and name tables alike. With that said, it is your responsibility to order things so that they do come out right, especially in FRAME objects.

 

I did the ENLARGE example to show how to use it with semi mobile objects, and the interleaving of tiles that you have to do, to re-order things so they appear correctly.

 

enlarge.thumb.png.e5a129b913e50bf545d08ed188e00613.png

You can see the order of tiles in the EnlargedFrame object in https://github.com/tschak909/os7lib/blob/main/examples/enlarge/src/enlarge.c#L163

 

It's important to note, that ALL of these calls are not only table-aware, they are mode-aware, especially in relation to generator placement, and preserving and transposing color table information. The amount of care taken here to do this is truly astounding.

 

Furthermore, you can also see, precisely why ACTIVATE has a boolean option that determines whether generators are copied from ROM into the VDP RAM. It's not needed for the enlarged object, because the ENLARGE call does all the heavy lifting there, generating new tiles, we just need to fill in the objects with the appropriate generator numbers so that PUT_OBJ can display them (and ACTIVATE also does much needed initialization of the OLD SCREEN and STATUS objects)

https://github.com/tschak909/os7lib/blob/main/examples/enlarge/src/enlarge.c#L259

 

In each of these cases, the WORK BUFFER specified at the top of the cartridge ROM is used to perform the transforms, before they are transferred to VRAM. e.g. for the rotate and reflect transforms, 8 bytes of the work buffer are used, while enlarge uses a minimum of 16 bytes, or more depending on the number of generators to transfer.

 

Continuing onward.

-Thom

Link to comment
Share on other sites

Am currently working through displaying Donkey Kong as a complex object, code here:

https://github.com/tschak909/os7lib/tree/main/examples/complex_object

 

But thus far, am running into interesting issues :) I Can get the face sprite to display, the body? not so much. ;)

image.thumb.png.dbe5e859948ac8c4e3718b432146ee91.png

Anyone have any potential insight here?

 

It does seem that they did some very unusual tricks with the color table on the SMO, as there is seperate code to transfer color data, and the second frame of Donkey Kong's body is actually made of reflected sprites, thanks to REFLECT_VERTICAL.

 

                             **************************************************************
                             *                          FUNCTION                          *
                             **************************************************************
                             undefined FUN_ram_84a3()
             undefined         A:1            <RETURN>
                             FUN_ram_84a3                                    XREF[1]:     ram:8069(c)  
        ram:84a3 01 82 01        LD         BC,0x182
        ram:84a6 cd d9 1f        CALL       WRITE_REGISTER                                   void WRITE_REGISTER(uchar regist
        ram:84a9 3e 03           LD         A,PATTERN_GENERATOR_TABLE
        ram:84ab 21 d3 a7        LD         HL,0xa7d3
        ram:84ae cd 0f 99        CALL       put_vram_256_starting_at                         undefined put_vram_256_starting_
        ram:84b1 3e 04           LD         A,PATTERN_COLOR_TABLE
        ram:84b3 21 ab ab        LD         HL,0xabab
        ram:84b6 cd 0f 99        CALL       put_vram_256_starting_at                         undefined put_vram_256_starting_
        ram:84b9 3e 01           LD         A,SPRITE_GENERATOR_TABLE
        ram:84bb 21 13 a1        LD         HL,0xa113
        ram:84be 11 00 01        LD         DE,0x100
        ram:84c1 cd 1e 99        CALL       COPY_GENERATORS_TO_VDP                           undefined COPY_GENERATORS_TO_VDP()
        ram:84c4 cd 99 84        CALL       CLEAR_NAME_TABLE                                 undefined CLEAR_NAME_TABLE()
        ram:84c7 3e 03           LD         A,0x3
        ram:84c9 11 1f 00        LD         DE,0x1f
        ram:84cc 01 27 00        LD         BC,0x27
        ram:84cf 21 7b 00        LD         HL,0x7b
        ram:84d2 cd 6a 1f        CALL       REFLECT_VERTICAL                                 Reflect 39 Donkey kong body tiles
                                                                                             from 0x1f, and place starting in
        ram:84d5 c3 35 97        JP         TURN_ON_DISPLAY_WITH_SIZE1_SPRITES               undefined TURN_ON_DISPLAY_WITH_S
                             -- Flow Override: CALL_RETURN (CALL_TERMINATOR)

 

Anyone have any potential insight on this? Has anyone been through this before? 

 

cowall_1.thumb.png.e8860c1fd3758bc69b883d495f085e1e.pngcowall_3.thumb.png.f31916f74b792bef14c7eeeed5405e20.png

 

-Thom

 

Edited by tschak909
Link to comment
Share on other sites

1 hour ago, tschak909 said:

But thus far, am running into interesting issues :) I Can get the face sprite to display, the body? not so much. ;)

When loading mass amount of graphics or generating graphics with vertical reflect, makes sure that the nmi(interrupt) is off.  Seems like the color tables and tiles aren't loading completely. 

Link to comment
Share on other sites

11 minutes ago, tschak909 said:

Ah yes. That is probably it! Thank you!

 

-Thom

No problem.  nmi vram corruption is one of the pitfall when programming for the Colecovision.  You can do small vram write(approxiately 200-300 bytes, depending on what function you're doing) when it is enabled, you have to do the task before the screen finished status flag goes up. 

Link to comment
Share on other sites

12 minutes ago, Kiwi said:

No problem.  nmi vram corruption is one of the pitfall when programming for the Colecovision.  You can do small vram write(approxiately 200-300 bytes, depending on what function you're doing) when it is enabled, you have to do the task before the screen finished status flag goes up. 

This is one of the reasons there is a WRITER function, which literally handles deferred writes during the NMI. I'm trying to create examples to show how all of this is used.

 

From section 4

image.thumb.png.faaf3e58e5a34e0bf5c72b09e008de8a.png

 

-Thom

Edited by tschak909
  • Like 1
Link to comment
Share on other sites

I can not say for definite what the issue is.  However, I have noticed that if you do not initiate everything through the appropriate commands, patterns do not work.  Sprites are a different entity.

The PutOBJ command and the like do not function.

A ways back I tried to use examples in Tony Cruise's book and they would not work unless I called MODE1 or some deal like that first.
A lot of things he forgets to mention or just did not occur.

Most of the time VRAM is divided up as Patterns start at $0000, Color at $2000, Name table at $1800, Sprites at $3000 and Sprite attributes at $1B00

 

While that is the case, a game such as Smurf Rescue uses a much larger pattern setup and starts at $2000 while Color starts at $0000 I suspect because you are using the entire playfield as a blank screen and a different set of patterns for each of the 1/3rd screen.  While the latter is standard mode 2 where each of the 3rd area's are replicated.

 

Sprite addresses can change but I have yet to find a game that has.  They always use $3000 and $1B00 and will work on any screen other than text mode.


So, bringing that long story short, setting up manually may just have your patterns going to the wrong address because those commands are dependent on the previous tables being set up correctly.
 

I have disassembled a few of these games that will setup all the tables using MODE1 then change aspects of VRAM with Write Register after.

Edited by Captain Cozmos
Link to comment
Share on other sites

2 hours ago, Captain Cozmos said:

I can not say for definite what the issue is.  However, I have noticed that if you do not initiate everything through the appropriate commands, patterns do not work.  Sprites are a different entity.

The PutOBJ command and the like do not function.

A ways back I tried to use examples in Tony Cruise's book and they would not work unless I called MODE1 or some deal like that first.
A lot of things he forgets to mention or just did not occur.

Most of the time VRAM is divided up as Patterns start at $0000, Color at $2000, Name table at $1800, Sprites at $3000 and Sprite attributes at $1B00

 

While that is the case, a game such as Smurf Rescue uses a much larger pattern setup and starts at $2000 while Color starts at $0000 I suspect because you are using the entire playfield as a blank screen and a different set of patterns for each of the 1/3rd screen.  While the latter is standard mode 2 where each of the 3rd area's are replicated.

 

Sprite addresses can change but I have yet to find a game that has.  They always use $3000 and $1B00 and will work on any screen other than text mode.


So, bringing that long story short, setting up manually may just have your patterns going to the wrong address because those commands are dependent on the previous tables being set up correctly.
 

I have disassembled a few of these games that will setup all the tables using MODE1 then change aspects of VRAM with Write Register after.

I do exactly the same pattern:

in: https://github.com/tschak909/os7lib/blob/main/examples/complex_object/src/complex_object.c#L56

  mode2_with_size1_sprites(false);              // Set up, but keep screen BLANK

Which does this:

https://github.com/tschak909/os7lib/blob/main/examples/complex_object/src/complex_object.c#L35

void mode2_with_size1_sprites(bool bOnOff)
{
  mode_1();
  write_register(0x00,2); // SET M2
  write_register(0x01,bOnOff ? 0xE2 : 0xC2); // BLANK(bOnOff), 16K, INTERRUPTS
}

-Thom

Link to comment
Share on other sites

This is how I set up mode 2
If I use it this way I can follow directly from the TI TMS9928 manual by changing the bits per example in the book.

 

GRAPHICS_MODE:
    DI
    LD C, CTRL_PORT
    LD B, 10H
    LD HL, MODE_REGISTERS
    OTIR


MODE_REGISTERS:
    DB %00000010, 128+0    ; MODE REGISTER #0                ; bit 6 controls which mode, bit 7 is for external video
    DB %11000010, 128+1    ; MODE REGISTER #1                ; bit 6 is for 8x8 or 16x16 sprites, bit 7 is enlarge sprites
    DB %00000110, 128+2    ; NAME TABLE
    DB %11111111, 128+3    ; COLOR TABLE
    DB %00000011, 128+4    ; PATTERN TABLE
    DB %00110110, 128+5    ; SPRITES ATTRIBUTES
    DB %00000111, 128+6    ; SPRITES PATTERNS
    DB %00000000, 128+7    ; BACKGROUND COLOR

 

MODE 1 would be the same except for

    DB %00000000, 128+0    ; MODE REGISTER #0

 

To ENLARGE sprites you change bit 7 of register 1

    DB %11000011, 128+1    ; MODE REGISTER #1

 

 

 

I can't work with all that C gibberish.

Edited by Captain Cozmos
Link to comment
Share on other sites

2 minutes ago, Captain Cozmos said:

This is how I set up mode 2
If I use it this way I can follow directly from the TI TMS9928 manual by changing the bits per example in the book.

 

GRAPHICS_MODE:
    DI
    LD C, CTRL_PORT
    LD B, 10H
    LD HL, MODE_REGISTERS
    OTIR


MODE_REGISTERS:
    DB %00000010, 128+0    ; MODE REGISTER #0                ; bit 6 controls which mode, bit 7 is for external video
    DB %11000010, 128+1    ; MODE REGISTER #1                ; bit 6 is for 8x8 or 16x16 sprites, bit 7 is enlarge sprites
    DB %00000110, 128+2    ; NAME TABLE
    DB %11111111, 128+3    ; COLOR TABLE
    DB %00000011, 128+4    ; PATTERN TABLE
    DB %00110110, 128+5    ; SPRITES ATTRIBUTES
    DB %00000111, 128+6    ; SPRITES PATTERNS
    DB %00000000, 128+7    ; BACKGROUND COLOR

 

MODE 1 would be the same except for

    DB %00000000, 128+0    ; MODE REGISTER #0

 

To ENLARGE sprites you change bit 7 of register 1

    DB %11000011, 128+1    ; MODE REGISTER #1

 

 

 

I can't work with all that C gibberish.

you mean to tell me you literally can't read:

write_register(0x01,0xC2) ? ....

 

...

ok.

 

-Thom

Link to comment
Share on other sites

1 minute ago, tschak909 said:

you mean to tell me you literally can't read:

write_register(0x01,0xC2) ? ....

 

...

ok.

 

-Thom

That's long hand.
I am a simple, yet humble man.

In reality, when I am working on a game and go to bed I am thinking in assembly language to the point I have to get back up and write it down.

I took C, Pascal and Cobol when I first went to college then ADA, Lisp and Forth shortly after.

I'm happy with Z80, 6801 and 68000 assembly.

But yes, I can follow your work.

I just don't want to deviate from what I am proficient at in my latter days of existence.

Link to comment
Share on other sites

27 minutes ago, Captain Cozmos said:

That's long hand.
I am a simple, yet humble man.

In reality, when I am working on a game and go to bed I am thinking in assembly language to the point I have to get back up and write it down.

I took C, Pascal and Cobol when I first went to college then ADA, Lisp and Forth shortly after.

I'm happy with Z80, 6801 and 68000 assembly.

But yes, I can follow your work.

I just don't want to deviate from what I am proficient at in my latter days of existence.

fair enough. ;)

-Thom

Link to comment
Share on other sites

Still working through getting the semi-mobile objects displayed correctly.

 

Scratching my head, because:

 

* The graphic generators are being copied correctly to 0x1f - 0x45

* The color generators are being copied to the same  place in the color table (starting at 0x20F8)

and I've verified the tiles are indeed 0x1f to 0x45 that make up donkey kong, and on the name table

but the color values are being pulled from 0x2000 (color for generator 0x00), what the hell?!

 

Rom is attached

 

As is video showing condition

 

-Thom 

 

complex_object.rom

Link to comment
Share on other sites

This is the VRAM init for the 16k DK version

 

SETUP_VRAM:
                CALL    SUB_9A5E
                LD      A, 0D0H
                LD      B, 48H ; 'H'
                LD      HL, (OFF_8004)
                CALL    SUB_97FA
                LD      A, 0
                LD      DE, 0
                LD      IY, 12H
                CALL    PUT_VRAM
                LD      A, 10H
                CALL    INIT_SPR_NM_TBL
                CALL    RESET_SCORES
                LD      BC, 2
                CALL    WRITE_REGISTER
                LD      BC, 700H
                CALL    WRITE_REGISTER
                LD      A, 0
                LD      HL, 1C00H
                CALL    INIT_TABLE
                LD      A, 1
                LD      HL, 3800H
                CALL    INIT_TABLE
                LD      A, 2
                LD      HL, 1800H
                CALL    INIT_TABLE
                LD      A, 3
                LD      HL, 2000H
                CALL    INIT_TABLE
                LD      A, 4
                LD      HL, 0
                CALL    INIT_TABLE
                JP      DISABLE_NMI
; END OF FUNCTION SETUP_VRAM

Edited by Captain Cozmos
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...