Jump to content
  • entries
    53
  • comments
    536
  • views
    68,393

A better chessboard


Guest

534 views

Sometimes designing kernels is more fun than actual game programming. Anyway, the idea of doing a better chess kernel has been on my mind for a while. I've been skeptical of the notion that chess could only be done with Venetian blinds or flickering, and this weekend I came up with a design that needs neither. Like my other board game kernels it relies heavily on PF graphics and multiple color changes.Unfortunately I could not figure out a way to use self-modifying code. The PF must be updated every line, and there was not enough time in a loop to retrieve new playfield data. The extra cycle needed for indexed addressing was just too much. What I did for this proof of concept instead was to repeat code. There are 12 groups of nearly identical code for each scanline. The only difference is the addresses from where the PF data is loaded.I can make the colors of the first two pieces variable, so I would need 64 routines to cover every combination. The grand total is about 27K. This chess kernel is theoretically possible, but I'd rather find a way to reduce the size.As usual, a screenshot of a single row and a mockup of the full board is attached.post-4140-1065293621_thumb.jpg

8 Comments


Recommended Comments

I would guess you're probably using sprites for the board squares and playfield for the pieces. Your color stores must occur 5-6 cycles apart (some five, some six). That leaves a fair amount of room for other stuff, but you need two load/store pairs for the playfield data (which will use up much of that room).

 

I personally happen to rather like the style of venetian flicker that David Crane invented; I would think it preferable to non-venetian playfield graphics for chess pieces. Nonetheless, your approach is interesting.

 

One thing I'd suggest looking into, though: you only need to do the COLUPF store if a piece is a different color from its predecessor. This fact should allow you to greatly reduce the number of different cases you need to handle since a non-store provides time to load registers. The different cases that can be handled by different types of code overlap in tricky ways, so you'd probably need some tables to help select which case applies to any particular color combination.

 

Another notion--not sure it would work well here given the slightly irregular timing requirements--is using the stack as a versatile branching method. I was thinking of doing this awhile ago for an eleven-invaders clone using Venetian blinds. The basic idea would be to have a code segment:

 

xinv5:
 nop 0
 jmp inv5
xinv4:
 nop 0
 jmp inv4
xinv3:
 nop 0
 jmp inv3
xinv2:
 nop 0
 jmp inv2
xinv1:
 nop 0
 jmp inv1
xinv0:
 nop 0
 jmp 
inv6:
 nop 0
 sta RESP1
inv5:
 nop 0
 sta RESP0
inv4:
 nop 0
 sta RESP1
inv3:
 nop 0
 sta RESP0
inv2:
 nop 0
 sta RESP1
inv1:
 nop 0
 sta RESP0
inv0:
 rts

 

The stack would be set up with a list of 'segments' of invaders, followed by a pointer to the code that should execute after showing the last invader. The stack pointer would be set to the byte before start of this list and an RTS executed. In worst case, the stack would need to hold four entries (there would be two stacks, one for the even rows and one for the odd rows).

Link to comment

Thanks, John.

I personally happen to rather like the style of venetian flicker that David Crane invented;

There's no denying that Venetian blinds worked brilliantly for your Strat-o-Gems title. I figured you would have some good ideas for my kernel. I'll have to study your code to have an inkling of how it works.

 

Here is a sample scanline for my chess kernel, so you can see how tight space is:

 

   
 ;assume left side
 ;of PF0 and PF1
 ; are stored, and
 ; PF2 is in Y 
 ;--------------new line
     STY PF2
     LDY $80
     STY COLUPF   
     sleep 14
     LDY $83      
     STY PF0       
     STX COLUPF   
     LDY $84      
     STA COLUPF   
     STY PF1      
     STX COLUPF    
     STA.W COLUPF 
     LDY $85       
     STX COLUPF 
     STY PF2      
     STA COLUPF   
     STX.w COLUPF  
     STX PF0; whether X is set to black or white, this clears PF0       
     LDY $86      
     STY PF1      
     LDY $87       
;---------------new line
; code repeats

 

It's true I have 14 cycles of downtime, but I'd need 25 to update the addresses for the playfield data (5 cycles to update 5 addresses for LDY).

Link to comment
There's no denying that Venetian blinds worked brilliantly for your Strat-o-Gems title. I figured you would have some good ideas for my kernel. I'll have to study your code to have an inkling of how it works.

 

The Strat-O-Gems title code is actually very simple. I don't change any color registers mid-line, and I don't even change the sprite 0 shape after the even scan lines (since the even lines end with "S" and the odd lines start with "S"). But I'll certainly grant that it looks cool.

Link to comment
Here is a sample scanline for my chess kernel, so you can see how tight space is:

It's true I have 14 cycles of downtime, but I'd need 25 to update the addresses for the playfield data (5 cycles to update 5 addresses for LDY).

 

I think a more fundamental problem is that you don't have nearly enough time to 'assemble' the playfield data during a frame, nor nearly enough space (on an unexpanded 2600) to hold it all even if you could use indexed accesses to fetch it.

Link to comment

Maybe a reflected PF would help. At least you would save two reads for and two writes to PF0.

 

Though the timing would become pretty critical, especially in the middle where you have to time the 2nd write to PF2 exactly.

 

EDIT: I am now convinced that the correct timing in the middle would become impossible.

Link to comment
I think a more fundamental problem is that you don't have nearly enough time to 'assemble' the playfield data during a frame, nor nearly enough space (on an unexpanded 2600) to hold it all even if you could use indexed accesses to fetch it.

I would update the PF data just before each row. I'd need 30 bytes to do it (5 columns*6 doubled scanlines). The quickest way I can think of to assemble the playfield data is to save the board with one byte holding the shapes for two pieces. If each byte corresponds to a PF column, then there would be 40 bytes (5 columns*8 rows). Each number could serve as an index to quickly retrieve playfield data from a table. If I used another 8 bytes to store the colors, I can hold the entire board position in 48 bytes.

 

The more I think about this kernel design, the more I think it's a case of "Just because you can do something doesn't mean you should." Maybe if Infogrammes were more permissive with their IP, it would be worth trying to merge this new kernel with the Video Chess A.I.

Link to comment
I would update the PF data just before each row. I'd need 30 bytes to do it (5 columns*6 doubled scanlines). The quickest way I can think of to assemble the playfield data is to save the board with one byte holding the shapes for two pieces. If each byte corresponds to a PF column, then there would be 40 bytes (5 columns*8 rows). Each number could serve as an index to quickly retrieve playfield data from a table. If I used another 8 bytes to store the colors, I can hold the entire board position in 48 bytes.

 

I guess there are somewhere around 80 cases you'd have to worry about in a chess game since the piece shape is independent of color (49 cases, times two for reflection, but some of those will be duplicates). But if you're not going to be using full vertical resolution, what's wrong with venetian blinds?

Link to comment
I guess there are somewhere around 80 cases you'd have to worry about in a chess game since the piece shape is independent of color (49 cases, times two for reflection, but some of those will be duplicates).  But if you're not going to be using full vertical resolution, what's wrong with venetian blinds?

I wouldn't go so far as to say Venetian blinds are wrong, but I do prefer solid pieces and wanted to challenge myself to draw them. The closest I came was a technique that works, but uses a huge amount of ROM.

Link to comment
Guest
Add a comment...

×   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...