Jump to content
IGNORED

Newbie Programming Questions


Fushek

Recommended Posts

I have some newbie programming questions that I'm hoping some of you can help me out with. I've drawn some basic background screens for fun but I want to move onto other things so thus my questions:

 

1) Where is the best place to start learning about the MOBs? What libraries or macros exist that I should know about? Is there an example out there that only has ONE MOB on the screen that I can learn from?

2) On drawing a background, it seems like I have basically two colors per 8 x 8 block (foreground color and background color?). I'm pretty sure, looking at the work of others, that you can have more ... am I missing something?

3) For P-Machinery, are there other libraries/macros available or is it just more of a skeleton that facilitates the moving from one stage of the game to the next? Are all the commands the same as the examples that I look at?

 

Thanks for any advice!

 

(Just for fun, I'm attaching a "what if" screen for if Disney was still making games for the Intellivision ... it's for Tangled, which was a Rapunzel movie)

post-31049-0-36477600-1346089235_thumb.jpg

Link to comment
Share on other sites

I'll try to respond to your questions one by one below.

 

1) Where is the best place to start learning about the MOBs? What libraries or macros exist that I should know about? Is there an example out there that only has ONE MOB on the screen that I can learn from?

 

Unfortunately, there is not a single source of comprehensive information on MOBs (or Intellivision programming in general). I guess as an example of a single MOB on the screen you could use the demo-tutorial "Tag Along Todd," included in the SDK-1600. It shows the basic idea of moving a MOB around.

 

If you have some specific questions, I could try to answer them. I am planning on preparing a tutorial that will go with the next version of P-Machinery, to help in all this stuff.

 

2) On drawing a background, it seems like I have basically two colors per 8 x 8 block (foreground color and background color?). I'm pretty sure, looking at the work of others, that you can have more ... am I missing something?

 

You can only have two colors within an 8x8 block, either on the background (BACKTAB) or a MOB. However, you can layer MOBs on top of the background to give it more color. Unfortunately, every MOB you use to colorize the background is one less MOB you have for game interaction.

 

In Christmas Carol, for example, I reserve the MOBs for the game characters, so there is nothing left for the background. I then try to be creative with the backgrounds by cleverly reducing emphasis between the color boundaries of tiles. It takes some effort, but it is possible.

 

In static scenes like the title screen, I go all out and use MOBs to layer color or to hide some of those color boundaries. Take a look at the attached screen shot of the Christmas Carol title screen. Notice that the bottom-right edge of the tree bleeds into the left-most present. It's hard to tell where the tile boundaries lie between the light and dark greens, and the cyan.

 

By the way, you can only specify the "foreground" of a MOB. Its background color will be anything that "shines through" from the background behind it.

 

post-27318-0-44869600-1346093028_thumb.gif

 

3) For P-Machinery, are there other libraries/macros available or is it just more of a skeleton that facilitates the moving from one stage of the game to the next? Are all the commands the same as the examples that I look at?

 

P-Machinery comes with a whole set of macros and libraries, though unfortunately not for manipulating MOBs. The framework is pretty much the core of Christmas Carol. However, I removed the animation and sprite drivers because they were too specialized for Carol (and kind of crappy, really). I am planning on implementing a more generalized mechanism for this.

 

It does include some macros to handle graphics, but mostly for accessing the BACKTAB. Take a look at the "graphix.mac" macro. It includes convenient macros that allocate GRAM into "blocks" that are then assigned to MOBs. In Christmas Carol, the sprite driver would then address these blocks automatically. Hopefully P-Machinery will gain these features soon.

 

In general, as it stands right now, P-Machinery is mostly the skeleton that facilitates moving from one state of the game to the next. Though, it encapsulates the SDK-1600 TASKQ task queue manager and TIMER scheduler, and a modularized hand-controller input processor. It is merely the lowest level core of a game.

 

(Just for fun, I'm attaching a "what if" screen for if Disney was still making games for the Intellivision ... it's for Tangled, which was a Rapunzel movie)

 

Looks cool! (Especially with the title "Killer Zombies" LOL!) :)

 

-dZ.

Edited by DZ-Jay
  • Like 2
Link to comment
Share on other sites

Here's some theory on moving objects. The information below is synthesized from the document "stic.txt" included in the SDK-1600.

 

The STIC supports 8 Movable Object Blocks, or MOBs. Each one can move independently of the background or each other, and can be positioned anywhere in the playing field. The playing field is actually larger than the viewable area. As you may know, the display area consists of a 20 x 12 grid of cards, each 8 x 8 pixels, which gives a total display area of 160 x 96. It's actually 159 x 96, since the last column of pixels is not displayed.

 

The playing field extends by a full 8 pixels above and to the left of the display area, giving a total area of 167 x 105 pixels. The diagram below shows how the playing field relates to the viewable area:

 

post-27318-0-72133100-1346101278_thumb.png

 

The coordinates specified for a MOB correspond to its upper-right corner. This means that if you position an object at Y coordinate 0 it will be outside the viewable display. Incrementing the Y coordinate will smoothly transition the object into the screen. The same applies to the X coordinate.

 

The STIC offers three registers that defines the characteristics and position of each MOB. They are the X, Y, and A registers:

 

post-27318-0-47194100-1346101279_thumb.png

 

 

Below is the description of some of those fields, for a full description of each one, see the document "stic.txt" that accompanies the SDK-1600.

 

 

VISB
- If set, the MOB is visible. If clear, it will not show.

 

PRIO
- If set, the MOB appears behind the background. If clear, it shows on top.

 

GRAM/GROM
- If set, the image for the MOB comes from GRAM. Otherwise, it comes from GROM.

 

CARD #
- The index of the card to use for the MOB image, whether from GRAM or GROM.

 

 

There is one important catch regarding the STIC: it can only be accessed for a very brief period during the VBLANK interrupt. Because of this, it is common to keep a local copy of it in 16-bit System RAM to manipulate during normal operations, and then just block-copy the local version into the STIC registers at the top of VBLANK.

 

P-Machinery includes such a copy in the library file "stic_util.asm". It is called STIC_X. It also offers convenient routines to clear the STIC_X structure, and to block-copy, or post, it to the STIC. They are RESET_STIC and POST_STIC_X, respectively.

 

;; ========================================================================
;; RESET_STIC
;; Procedure to clear the STIC_X.
;;
;; INPUT for RESET_STIC
;; R5 Pointer to return address.
;;
;; OUTPUTS
;; R0 Zeroed
;; R1 Zeroed
;; R4 Points one element beyond destination array
;; ========================================================================

;; ========================================================================
;; POST_STIC_X
;; Procedure to post the STIC_X into the STIC.
;;
;; INPUT for UPDATE_STIC
;; R5 Pointer to return address.
;;
;; OUTPUTS
;; R0 Trashed.
;; R1 Trashed.
;; R4 Trashed.
;; ========================================================================

 

P-Machinery automatically calls POST_STIC_X on every VBLANK interrupt during the LEVEL.Play game state, with the assumption that MOBs will be used during game-play. If you plan on using MOBs during the title sequence, or any other game state, it is rather easy to modify their corresponding ISR routines to call POST_STIC_X as well.

 

Note that you must call POST_STIC_X at the very beginning of a VBLANK ISR, preferably before anything else. The window to access the STIC registers is much shorter than the window to access the GRAM in general.

 

-dZ.

 

EDIT: Sorry, I had to post some things as images because the STUPID forum software want to convert every single space into a tab character, even when using BBCode directly, and even when using the {code} tag. When will they fix this crap?!

Edited by DZ-Jay
  • Like 3
Link to comment
Share on other sites

Ok, here's a really simple example that puts exactly one MOB on the screen, and comments everything it's doing. It also puts a single red square in BACKTAB, so you can play with the "PRIO" bit. (PRIO controls whether a MOB appears in front of or behind the BACKTAB.)

 

Note: This recomputes the MOB's details every frame, which isn't really necessary. I wanted to keep the code absolutely simple. Experiment. Enjoy.

 

Note 2: This code requires cart.mac and assumes you have a recent enough jzintv that includes it. That way you can just unpack this in the "jzintv/examples" directory and go from there. Here are the most recent builds for Windows and OS X currently on my webserver:

 

http://spatula-city.org/~im14u2c/intv/dl/jzintv-20110907-win32.zip

http://spatula-city.org/~im14u2c/intv/dl/jzintv-20120826-osx.zip

 

If you'd like a more up-to-date build, I can make it easily enough.

 

 

one_mob.zip

  • Like 4
Link to comment
Share on other sites

Ok, here's a really simple example that puts exactly one MOB on the screen, and comments everything it's doing. It also puts a single red square in BACKTAB, so you can play with the "PRIO" bit. (PRIO controls whether a MOB appears in front of or behind the BACKTAB.)

 

Note: This recomputes the MOB's details every frame, which isn't really necessary. I wanted to keep the code absolutely simple. Experiment. Enjoy.

 

Note 2: This code requires cart.mac and assumes you have a recent enough jzintv that includes it. That way you can just unpack this in the "jzintv/examples" directory and go from there. Here are the most recent builds for Windows and OS X currently on my webserver:

 

http://spatula-city....10907-win32.zip

http://spatula-city....0120826-osx.zip

 

If you'd like a more up-to-date build, I can make it easily enough.

 

Thanks for the learning tool ... it's much appreciated! I'll play and see what I can do with it.

Link to comment
Share on other sites

Ok, here's a really simple example that puts exactly one MOB on the screen, and comments everything it's doing. It also puts a single red square in BACKTAB, so you can play with the "PRIO" bit. (PRIO controls whether a MOB appears in front of or behind the BACKTAB.)

 

Note: This recomputes the MOB's details every frame, which isn't really necessary. I wanted to keep the code absolutely simple. Experiment. Enjoy.

 

Note 2: This code requires cart.mac and assumes you have a recent enough jzintv that includes it. That way you can just unpack this in the "jzintv/examples" directory and go from there. Here are the most recent builds for Windows and OS X currently on my webserver:

 

http://spatula-city....10907-win32.zip

http://spatula-city....0120826-osx.zip

 

If you'd like a more up-to-date build, I can make it easily enough.

 

Thanks for the learning tool ... it's much appreciated! I'll play and see what I can do with it.

 

Another tool you might find useful is the "mob_test" inside SDK-1600. It lets you move MOBs around and see what at least some of the bits in all the registers do. It's a little quirky, but then which of my demos isn't? ;-)

 

The keypad buttons 1 thru 8 pick among the 8 MOBs. The DISC moves the MOB. The action buttons toggle the VISB, PRIO and INTR bits. The 9 and Clear buttons change the horizontal/vertical scroll registers. The 0 button cycles through a set of graphics patterns I have loaded in GRAM. And finally, the Enter button toggles whether the collision bits get cleared every frame or not.

 

The display shows the 8 MOBs, along with the values of the X, Y, A and C registers. You can watch X/Y change as you move the MOB around or toggle the VISB/INTR bits. You can watch A change as you cycle through the various GRAM cards I've preloaded or toggle the PRIO bit. And, you can watch the collision bits change as MOBs interact (or not, as determined by the INTR bit).

 

At the bottom of the screen are some colored-squares tiles. The shimmering tiles are set to color 7. The non-shimmering tiles are colors 0 through 6. You should be able to verify that the MOBs will set their background interaction bits on colored-squares colors 0-6 but not 7.

 

Let me know if you have any trouble building mob_test. It should be under jzintv-1.0-beta4/examples/mob_test/.

 

Enjoy!

Edited by intvnut
Link to comment
Share on other sites

  • 2 weeks later...

Thanks for all the examples ... I have a couple of questions when anyone has time:

 

In the OneMOB, after the X attributes are defined, they are written to MOB #0's X Register at $00. I'm assuming that the locations would be stored as follows:

 

X - MOB #0 to MOB #7 - $00 to $07

Y - MOB #0 to MOB #7 - $08 to $0F

A - MOB #0 to MOB #7 - $10 to $17

C - MOB #0 to MOB #7 - $18 to $1F

 

Am I on the right track here?

 

There seem to be a lot of things going on in reference to "locations". Is a specific location always used for the same thing? For instance, in the OneMOB example

 

;; Clear border extension and scrolling registers.

MVII #$30, R4 ; hdly, vdly and border extension

MVO R0, $30 ; \

MVO R0, $31 ; |- Reset border extension and

MVO R0, $32 ; / horiz/vert scroll regs

 

The Locations $30, $31 and $32, do they all have a set definition for ALL intv programming? i.e. is $31 always the horizonal scroll reg, etc. If so, is there a listing of locations and what they reference?

 

Thanks again for the examples. It's fun learning this and great to have knowledgeable people to help out!

Link to comment
Share on other sites

Thanks for all the examples ... I have a couple of questions when anyone has time:

 

In the OneMOB, after the X attributes are defined, they are written to MOB #0's X Register at $00. I'm assuming that the locations would be stored as follows:

 

X - MOB #0 to MOB #7 - $00 to $07

Y - MOB #0 to MOB #7 - $08 to $0F

A - MOB #0 to MOB #7 - $10 to $17

C - MOB #0 to MOB #7 - $18 to $1F

 

Am I on the right track here?

 

There seem to be a lot of things going on in reference to "locations". Is a specific location always used for the same thing? For instance, in the OneMOB example

 

;; Clear border extension and scrolling registers.

MVII #$30, R4 ; hdly, vdly and border extension

MVO R0, $30 ; \

MVO R0, $31 ; |- Reset border extension and

MVO R0, $32 ; / horiz/vert scroll regs

 

The Locations $30, $31 and $32, do they all have a set definition for ALL intv programming? i.e. is $31 always the horizonal scroll reg, etc. If so, is there a listing of locations and what they reference?

 

Thanks again for the examples. It's fun learning this and great to have knowledgeable people to help out!

Fushek -

 

You are on the right track. You're getting it!

 

If you look under your jzintv directory at the file: jzintv/doc/programming/stic.txt you will find some of this information spelled out:

 

This is a brief summary of the STIC register set. The operation of
these registers will be described in detail below. Note that the STIC
registers are only available during the VBLANK interval, or when the
display is blanked.
ADDRESSES		 DESCRIPTION
----------------- ----------------------------------------------
$0000 - $0007	 MOB X-position registers
$0008 - $000F	 MOB Y-position registers
$0010 - $0017	 MOB Attribute registers
$0018 - $001F	 MOB Collision registers
$0020			 Display enable
$0021			 Mode select
$0022 - $0027	 reserved
$0028 - $002B	 Color Stack 0 through 3
$002C			 Display border color
$002D - $002F	 reserved
$0030			 Horizontal Delay register
$0031			 Vertical Delay register
$0032			 Border extension (bit 0=left; bit 1=top)
$0033 - $007F	 Reserved

 

Check it out!

 

Catsfolly

Link to comment
Share on other sites

 

;; Clear border extension and scrolling registers.

MVII #$30, R4 ; hdly, vdly and border extension

MVO R0, $30 ; \

MVO R0, $31 ; |- Reset border extension and

MVO R0, $32 ; / horiz/vert scroll regs

 

The Locations $30, $31 and $32, do they all have a set definition for ALL intv programming? i.e. is $31 always the horizonal scroll reg, etc. If so, is there a listing of locations and what they reference?

 

Thanks again for the examples. It's fun learning this and great to have knowledgeable people to help out!

 

Catsfolly already explained where to find all these register addresses. The other files there also say where the PSG registers are, for example, and the overall memory map. I just wanted to comment on the snippet above: The "MVII #$30, R4" doesn't need to be there. I think I originally intended to write:

 

   MVII #$30, R4
   MVO@ R0,   R4
   MVO@ R0,   R4
   MVO@ R0,   R4

 

which would do the same as:

 

   MVO R0, $30
   MVO R0, $31
   MVO R0, $32

 

Either one works. The first one is slightly smaller, and the second one is slightly faster. But this one is just silly:

 

   MVII #$30, R4
   MVO  R0, $30
   MVO  R0, $31
   MVO  R0, $32

 

Sorry about that! :-)

Link to comment
Share on other sites

Thanks for all the examples ... I have a couple of questions when anyone has time:

 

In the OneMOB, after the X attributes are defined, they are written to MOB #0's X Register at $00. I'm assuming that the locations would be stored as follows:

 

X - MOB #0 to MOB #7 - $00 to $07

Y - MOB #0 to MOB #7 - $08 to $0F

A - MOB #0 to MOB #7 - $10 to $17

C - MOB #0 to MOB #7 - $18 to $1F

 

Am I on the right track here?

 

There seem to be a lot of things going on in reference to "locations". Is a specific location always used for the same thing? For instance, in the OneMOB example

 

;; Clear border extension and scrolling registers.

MVII #$30, R4 ; hdly, vdly and border extension

MVO R0, $30 ; \

MVO R0, $31 ; |- Reset border extension and

MVO R0, $32 ; / horiz/vert scroll regs

 

The Locations $30, $31 and $32, do they all have a set definition for ALL intv programming? i.e. is $31 always the horizonal scroll reg, etc. If so, is there a listing of locations and what they reference?

 

Thanks again for the examples. It's fun learning this and great to have knowledgeable people to help out!

 

Fushek,

 

You are on the right track. Basically, the Intellivision maps certain memory locations to all its peripherals. For the built-in stuff, like the STIC or PSG, the locations are always the same.

 

Check out the file "memory_map.txt" in the "doc/programming" folder of the SDK-1600; it specifies the full memory map.

 

You can also use the library file "gimini.asm" in the "library" directory of the SDK, which defines constants for almost all those locations for easy usage.

 

As for the MOBs, they each have an X, Y, A, and C registers. The registers are defined in memory as contiguous blocks, like this:

 

   $0000 - $0007 = X Registers
   $0008 - $000F = Y Registers
   $0010 - $0017 = A - Attribute Registers
   $0018 - $001F = C - Collision Registers

 

 

 

Each block contains one register of the class for each MOB, for instance:

 

   $0000 - $0007 = X Registers:
   $0000 = MOB 0 X Register
   $0001 = MOB 1 X Register
   $0002 = MOB 2 X Register
   $0003 = MOB 3 X Register
   ...
   $0007 = MOB 7 X Register

 

You can easily navigate through the structure, if you treat each register block as an array. In such case the MOB number becomes the index. For instance, suppose you want to access Register X of MOB #0 and Register A of MOB #5

 

   RegisterX[0] = STIC.mob0_x + 0
   RegisterA[5] = STIC.mob0_a + 5

Edited by DZ-Jay
Link to comment
Share on other sites

You guys rock!

 

OK ... I added gimini.asm at the start of the file just to play and at least change the colors using the C_XXX codes rather than try to remember the numbers (which is weird seeing as how I'm an accountant, you would think that I'm a numbers person!). When I change the color to anything in the second block of colors (colors 9 to 16) it changes my R to an S ... am I hitting some sort of an "overflow" for that to happen?

 

So, right now, my X coordinate is treated thus:

 

MVII #$55, R0

 

If I wanted to use the mob0_x code from gimini.asm, how would I do that? The closest thing that I can see is in the balls1.asm example:

 

BALLINIT PROC

@@x0 DECLE STIC.mobx_visb + STIC.mobx_intr

 

I understand that this makes the MOB visible and turns on the collision detection but I can't find in that example where it's assigning the x coordinate?

Link to comment
Share on other sites

You guys rock!

 

OK ... I added gimini.asm at the start of the file just to play and at least change the colors using the C_XXX codes rather than try to remember the numbers (which is weird seeing as how I'm an accountant, you would think that I'm a numbers person!). When I change the color to anything in the second block of colors (colors 9 to 16) it changes my R to an S ... am I hitting some sort of an "overflow" for that to happen?

 

Ah, you've hit the first fun quirk, the strange inconsistencies in bitfield layout. For the colors, the C_xxx constants work for putting colors in the color stack and border color registers. For everything else, though, it turns out that bit 3 of the color gets shoved way up in bit 12 of the word. I added the X_xxx constants to account for that. (Or, if you use "gen_cstk_card()" in stic.mac, all that complication gets hidden from you.)

 

You can see the bitfield layouts here on the Wiki.

 

So, right now, my X coordinate is treated thus:

 

MVII #$55, R0

 

If I wanted to use the mob0_x code from gimini.asm, how would I do that? The closest thing that I can see is in the balls1.asm example:

 

BALLINIT PROC

@@x0 DECLE STIC.mobx_visb + STIC.mobx_intr

 

I understand that this makes the MOB visible and turns on the collision detection but I can't find in that example where it's assigning the x coordinate?

 

The "BALLINIT" code sets up the initial values of the registers, without the coordinates filled in. Elsewhere, code such as the following replaces just the X coordinate part of the X register with a read-modify-write sequence:

 

           SWAP    R0                  ;\__ Retain integer portion of 
           ANDI    #$00FF, R0          ;/   X position
           MVI@    R3,     R1          ;\__ Get X register and clear old
           ANDI    #$FF00, R1          ;/   X position
           XORR    R0,     R1          ; Merge new X position
           MVO@    R1,     R3          ; Store new X register

Link to comment
Share on other sites

You guys rock!

 

OK ... I added gimini.asm at the start of the file just to play and at least change the colors using the C_XXX codes rather than try to remember the numbers (which is weird seeing as how I'm an accountant, you would think that I'm a numbers person!). When I change the color to anything in the second block of colors (colors 9 to 16) it changes my R to an S ... am I hitting some sort of an "overflow" for that to happen?

 

So, right now, my X coordinate is treated thus:

 

MVII #$55, R0

 

If I wanted to use the mob0_x code from gimini.asm, how would I do that? The closest thing that I can see is in the balls1.asm example:

 

BALLINIT PROC

@@x0 DECLE STIC.mobx_visb + STIC.mobx_intr

 

I understand that this makes the MOB visible and turns on the collision detection but I can't find in that example where it's assigning the x coordinate?

 

The C_xxx colours are strictly for the Color Stack. For MOBs and BACKTAB you want to use the X_xxx colours.

 

Regarding the MOB constants, you use STIC.mob0_x, you add to it the MOB number, and that gives you the address of the MOB's x register. Then you assign the value of the x coordinate to that address.

 

Keep in mind that the x position is only the lower 8 bits of the register. See the "stic.txt" file for the register format.

 

Here's an example:


   MVII    #STIC.mob0_x + 5, R1    ; get address for MOB 5 X register
   MVII    #50,    R2              ; new position (for later)

   MVI@    R1,     R0              ; get current register content
   ANDI    #$FF00, R0              ; clear last x coordinate
   ADDR    R2,     R0              ; merge new value
   MVO@    R0,     R1              ; Store new register content

Edited by DZ-Jay
Link to comment
Share on other sites

By the way, in the "gimini.asm" there is a constant for each of the MOBs' registers. I only suggested basing off MOB #0, because it is more convenient to generalize your code in sub-routines that way.

 

If you need to access a particular MOB's register, say #5's "x," you can use:

 

STIC.mob5_x

Edited by DZ-Jay
Link to comment
Share on other sites

I was playing with the Tutorial for Introducing Interrupts and working with the time elapsing demo. I was able to add days to the calculation and some colon's separating the days/hours/minutes/etc. Pretty cool demo ... the question that I have is this ... in playing with the program I thought that I would add something to the screen at the one minute mark, however, when I added it it worked, but it stopped the timer altogether. How can I get the item to show up but NOT affect the counter? Would I need to perform an additional interrupt sequence? Here's the portion of the code that I was playing with and the portion in red is what "kills" the timer. Any thoughts as to what I'm not understanding (and yes, I know that I have 10 tics in a second and 10 seconds in a minute ... otherwise, I'd sit here for ever watching!)

 

MYISR PROC

 

MVO R0, $20 ; Keep screen enabled.

 

MVI TIC, R0 ; Get current tic count into R0

MVI SEC, R1 ; Get current seconds count into R1

MVI MIN, R2 ; Get current minutes count into R2

MVI HOUR, R3 ; Get current hours count into R3

MVI DAY, R4 ; FUSHEK Added - Get current days count into R4

 

INCR R0 ; Increment tic count

CMPI #10, R0 ; Tic < 60?

BLT @@time_done ; Yes: Done updating time

 

CLRR R0 ; Reset tic count

INCR R1 ; Increment seconds count

CMPI #10, R1 ; Seconds < 60?

BLT @@time_done ; Yes: Done updating time

 

CALL PRINT.FLS

DECLE C_WHT, $200 + 6*20 + 3 ;Starts with Row 5, Column 2

STRING 'Surprise!', 0

 

CLRR R1 ; Reset seconds count

INCR R2 ; Increment minutes count

CMPI #3, R2 ; Minutes < 60?

BLT @@time_done ; Yes: Done updating time

 

CLRR R2 ; FUSHEK Added - Reset minutes count

INCR R3 ; FUSHEK Added - Increment Hours count

CMPI #24, R3 ; FUSHEK Added - Hours < 24?

BLT @@time_done ; FUSHEK Added - Yes: Done updating time

 

CLRR R3 ; FUSHEK Modified - Reset days count

INCR R4 ; FUSHEK Modified - Increment Days count

Link to comment
Share on other sites

I was playing with the Tutorial for Introducing Interrupts and working with the time elapsing demo. I was able to add days to the calculation and some colon's separating the days/hours/minutes/etc. Pretty cool demo ... the question that I have is this ... in playing with the program I thought that I would add something to the screen at the one minute mark, however, when I added it it worked, but it stopped the timer altogether. How can I get the item to show up but NOT affect the counter? Would I need to perform an additional interrupt sequence? Here's the portion of the code that I was playing with and the portion in red is what "kills" the timer. Any thoughts as to what I'm not understanding (and yes, I know that I have 10 tics in a second and 10 seconds in a minute ... otherwise, I'd sit here for ever watching!)

 

MYISR PROC

 

MVO R0, $20 ; Keep screen enabled.

 

MVI TIC, R0 ; Get current tic count into R0

MVI SEC, R1 ; Get current seconds count into R1

MVI MIN, R2 ; Get current minutes count into R2

MVI HOUR, R3 ; Get current hours count into R3

MVI DAY, R4 ; FUSHEK Added - Get current days count into R4

 

INCR R0 ; Increment tic count

CMPI #10, R0 ; Tic < 60?

BLT @@time_done ; Yes: Done updating time

 

CLRR R0 ; Reset tic count

INCR R1 ; Increment seconds count

CMPI #10, R1 ; Seconds < 60?

BLT @@time_done ; Yes: Done updating time

 

CALL PRINT.FLS

DECLE C_WHT, $200 + 6*20 + 3 ;Starts with Row 5, Column 2

STRING 'Surprise!', 0

 

CLRR R1 ; Reset seconds count

INCR R2 ; Increment minutes count

CMPI #3, R2 ; Minutes < 60?

BLT @@time_done ; Yes: Done updating time

 

CLRR R2 ; FUSHEK Added - Reset minutes count

INCR R3 ; FUSHEK Added - Increment Hours count

CMPI #24, R3 ; FUSHEK Added - Hours < 24?

BLT @@time_done ; FUSHEK Added - Yes: Done updating time

 

CLRR R3 ; FUSHEK Modified - Reset days count

INCR R4 ; FUSHEK Modified - Increment Days count

 

 

The call to PRINT.FLS likely trashes the other registers. You should take a look at PRINT.FLS and see what registers it says it modifies, and see which of those the rest of the ISR still needs. It looks like the ISR is using all of R0 through R4, and I believe PRINT.FLS also modifies most of these. So you'll need some PSHR/PULR around this call, or you can move the call down to after you've saved the updated time and do a check there. (e.g. check that seconds is 0 and call PRINT.FLS there.)

Link to comment
Share on other sites

Fushek,

 

I would also like to add that, as a matter of game design, perhaps a better approach is to have your normal "game logic" run outside the ISR.

 

If you are familiar with programming for other platforms at a higher level, think of the ISR as an "event handler" for time-sensitive stuff. This would include updating timers and counters (as you are doing) and accessing the STIC or GRAM. It should exclude any additional work, such as displaying to the screen or updating the rest of the game state.

 

The design of your game architecture obviously depends on your game requirements, and whatever you feel comfortable with. However, for the most part, it's a sane basic design to have a main game loop that maintains all the game state and updates all necessary objects outside the ISR.

 

Just my two cents. :)

 

-dZ.

Edited by DZ-Jay
Link to comment
Share on other sites

  • 2 weeks later...

I have a couple of color stack questions if anyone has a moment.

 

1) How do you advance the color stack after you set up the colors?

2) Am I reading right that you can only have four colors in the color stack? If so, can the colors in the color stack be changed throughout the game?

3) Are most games written in color stack mode?

4) In the documentation, it states that there are some limitations as to where the color stack color can be advanced. What is that limitation.

 

Thanks in advance for your help!

Link to comment
Share on other sites

I have a couple of color stack questions if anyone has a moment.

 

1) How do you advance the color stack after you set up the colors?

2) Am I reading right that you can only have four colors in the color stack? If so, can the colors in the color stack be changed throughout the game?

3) Are most games written in color stack mode?

4) In the documentation, it states that there are some limitations as to where the color stack color can be advanced. What is that limitation.

 

Thanks in advance for your help!

 

There's one bit in each BACKTAB word that advances the color stack. If it's set, then the color stack advances upon reaching that card. Otherwise it does not.

 

Color stack mode is shared with colored squares mode. That is to say there isn't a separate colored squares mode, but rather in color stack mode some tiles can display colored squares. These tiles cannot advance the color stack, because the bit that normally would advance the color stack holds one of the color bits for one of the colored squares. This is an issue only because color #7 for a colored square comes from the color stack, as opposed to displaying white.

 

Here's more details from the writeup I made at the Intellivision Wiki

 

Color Stack Mode

 

The program selects the STIC's Color Stack mode by reading from the STIC register at location $21 during VBlank Period 1. This sets the STIC in Color Stack mode. The STIC stays in this mode until the program accesses location $21 again. The following diagram shows the way the STIC interprets each word of BACKTAB in general while in this mode:

 

Stic_color_stack_word.png

Note that the behavior of the STIC is slightly different when cards come from GROM versus GRAM. Notably, foreground colors are restricted to the primary colors (0-7) for cards coming from GROM. Also, two additional bits become available as flags for cards coming from GRAM.

 

Stic_color_stack_grom.png

 

 

 

Stic_color_stack_gram.png

When rendering the background in color stack mode, the STIC selects the foreground color from the value stored in BACKTAB, and the background color from the current value on the top of the Color Stack. The Color Stack registers, at locations $28 - $2B define this stack of colors. The Color Stack is really more like a circular queue: Initially, the STIC picks the background color from the first entry on the stack. Whenever the STIC sees the 'Advance' bit set, it moves to the next entry on the stack prior to rendering the card. If the STIC was already on the last entry (at location $2B), it wraps back to the first entry.

In this mode, both foreground and background colors can come from the entire 16-color palette, at least for images from GRAM. This allows producing very colorful screens, but with some restriction on where the background color changes.

Color Stack mode also supports a special display mode for individual cards, called Colored Squares mode. Programs indicate which cards display as Colored Squares cards by setting bit 12 to '1' and bit 11 to '0'. This also means that programs cannot display cards from GROM with a pastel foreground color, since that is what this encoding would otherwise specify. The STIC interprets Colored Squares cards as follows:

 

Stic_colored_squares.png

Each quadrant of a Colored Square card can be one of 8 colors. The squares have these properties:

  • Colors 0 through 6 display directly from the primary color set.
  • Color 7 displays the current color on the top of the color stack.
  • Colors 0 through 6 behave like "on" pixels and interact with MOBs.
  • Color 7 does not interact with MOBs.
  • The color stack never advances on a Colored Square card.

 

And yes, there's only 4 colors in the color stack. These are stored in the lower 4 bits of each of the STIC registers at $28 to $2B. The display border color is in the lower 4 bits of $2C.

 

(I say "lower 4 bits", because bits 13 down to 4 always read as 1, and bits 15 and 14 always read as 0. Only bits 3 down to 0 are readable and writable.)

Edited by intvnut
Link to comment
Share on other sites

I have a couple of color stack questions if anyone has a moment.

 

1) How do you advance the color stack after you set up the colors?

 

Bit 13 of the BACKTAB word. Setting the bit causes all cards from that one on to switch to the next color in the stack.

 

It is circular, so advancing a fourth time will return it to the first color.

 

You can also use the constant "STIC.cs_advance" defined in the file "gimini.asm" of the SDK-1600.

 

2) Am I reading right that you can only have four colors in the color stack? If so, can the colors in the color stack be changed throughout the game?

 

Only 4 colors, correct. You can switch them, only during the VBLANK 1 period. However, the moment you change them, the screen will reflect the updated color sequence.

 

It's a cool way of doing color-cycling, except with only 4 colors. :)

 

3) Are most games written in color stack mode?

 

I don't know if "most." I use it because it seems to be more flexible in some ways, mostly because it allows all colors for foreground when using GRAM cards, and also it can address all of GROM.

 

4) In the documentation, it states that there are some limitations as to where the color stack color can be advanced. What is that limitation.

 

I'm not familiar with any limitation on advancing the color stack.

 

Thanks in advance for your help!

 

You're welcome! :)

Edited by DZ-Jay
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...