I've got another issue, seems to be to do with tables and rom segments.
First off, here's my memory.cfg I don't think it's related, but the only thing I've really changed is I don't use BSSX to reserve oam space. I designate it as BSS2 and write uc65 code that manipulates sprite oam memory.
So I switched things around to this:Here is my memory.cfg file. *comments* aren't actually in my file, added for explanation of how I use what.
Code:
MEMORY {
BSS0: start = $0000, size = $0100; *Zero Page*
STAK: start = $0100, size = $0100; *Stack*
BSS2: start = $0200, size = $0100; *sprite OAM memory spriteRam[]
BSS3: start = $0300, size = $0100; *meta sprite objects. I wanted my variables in a fixed location, so sram.s puts them here*
BSS1: start = $0400, size = $0400; *"default" ram space, allocated as the compiler sees fit.*
HEAD: start = $0000, size = $0010, fill = yes;
ROM0: start = $8000, size = $7FFA, fill = yes;
VECT: start = $FFFA, size = $0006, fill = yes;
ROM1: start = $0000, size = $2000, fill = yes;
}
SEGMENTS {
BSS0: load = BSS0, type = bss, optional = yes;
BSS2: load = BSS2, type = bss, optional = yes;
BSS3: load = BSS3, type = bss, optional = yes;
BSS1: load = BSS1, type = bss, optional = yes;
HEAD: load = HEAD, type = ro;
ROM0: load = ROM0, type = ro, optional = yes;
VECT: load = VECT, type = ro;
ROM1: load = ROM1, type = ro, optional = yes;
}
FILES {
%O: format = bin;
}
So first, a minor comment. Perhaps this is the way it's supposed to be. But it caught me off guard. I found that if I don't declare 'ram 1' in the beginning of my file, all allocated ram ends up in the zero page. So the 'default' (aka no delcaration) puts variables into ZP... But this isn't where the issue is which I found.
The problem is I've created a table in rom 0. But even though I declare rom 0, the compiled assembly doesn't declare which segment of rom to put the table into.
Code:
;-------------------------------------
;Meta-Sprite Character size and tiles
;-------------------------------------
; composite type (struct) used to initialize meta sprites
type metaSpriteCharacter ;meta sprite init variables
byte firstTile ;first sprite tile number, basis of tiles and graphics
byte numSpr ;number of sprites in metasprite object (hard math for x/ySize above)
byte xSize ;number tiles to be updated in x directoin
byte ySize ;8x16 sprites count as one sprite
end type
;;table for sprite data for character definitions
;VERY IMPORTANT that the indexes of this table line up with character constants
; ie HERO=0, is first entry in table
rom 0
table msChar of metaSpriteCharacter ;must have more than one row!
;recommend copying comment line to msStart table so character defn's and oam location are proper.
;HERO = 0 ;2x3 hero
firstTile=$00,numSpr=4,xSize=16,ySize=16
;BADDIE1= 1 ;2x2 baddie
firstTile=$20,numSpr=4,xSize=16,ySize=16
;GOODIE1= 2 ;2x2 goodie
firstTile=$10,numSpr=4,xSize=16,ySize=16
;BADDIE2= 3 ;2x1 baddie
firstTile=$29,numSpr=2,xSize=16,ySize=8
;GOODIE2= 4 ;2x2 goodie
firstTile=$18,numSpr=4,xSize=16,ySize=16
;BULLET1= 5 ;single sprite 8x8 pixels
firstTile=$27,numSpr=1,xSize=8,ySize=8
;THING1 = 6 ;tall double sprite 8x16 pixels
firstTile=$2D,numSpr=2,xSize=8,ySize=16
;BOSS = 7 ;3x3 BIG meta sprite
firstTile=$24,numSpr=9,xSize=32,ySize=32
end table
But when I compile this, I get an error:
Code:
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>java -jar ..\uc65.jar source\global.uc
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>java -jar ..\uc65.jar source\nes.uc
source\nes.uc(166): Warning: Possible loss of precision
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>java -jar ..\uc65.jar source\sprite.uc
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>java -jar ..\uc65.jar source\main.uc
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>java -jar ..\uc65.jar source\data.uc
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>path=path;..\cc65\
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>set CC65_HOME=..
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>ca65 lib\crt0.s
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>ca65 source\global.s
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>ca65 source\sram.s
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>ca65 source\nes.s
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>ca65 source\sprite.s
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>ca65 source\main.s
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>ca65 source\data.s
C:\Users\Paul\Dropbox\nesdev\dig_deeper5>ld65 -o dig_deeper.nes lib\crt0.o sourc
e\global.o source\sram.o source\nes.o source\sprite.o source\main.o source\data.
o -C lib\memory.cfg
ld65.exe: Error: Missing memory area assignment for segment `CODE'
Somehow segment "CODE" is being choosen...
I found out the issue is with my xSize and ySize entries of the table...
Looking at the compiled assembly:
Code:
; Assembly generated by uc65
; File: source\sprite.uc
; Built Time: Tue Dec 31 20:49:12 MST 2013
.DBG FILE, "source\sprite.uc", 18155, 1388548144
.IMPORT metaSprite_ySize
.IMPORTZP vBlankFlag
.IMPORT metaSprite_xSize
.IMPORT metaSprite_aux
.IMPORT metaSprite_character
.IMPORT metaSprite_ySpeed
.IMPORTZP gameState
.IMPORTZP buttons2
.IMPORTZP buttons1
.IMPORT metaSprite_state
.IMPORT metaSprite_xSpeed
.IMPORT spriteRam
.IMPORT metaSprite_oam
msChar_ySize: ;;;;; Hey, these guys don't have a designated ROM segment like the other entries...
.byte $10, $10, $10, $08, $10, $08, $10, $20
.DBG SYM, "msChar_ySize", "00", STATIC, "msChar_ySize"
msChar_xSize:
.byte $10, $10, $10, $10, $10, $08, $08, $20
.DBG SYM, "msChar_xSize", "00", STATIC, "msChar_xSize"
.SEGMENT "BSS0": zeropage
sprPtr2: .RES 0
.DBG SYM, "sprPtr2", "00", STATIC, "sprPtr2"
sprPtr2_a: .RES 1
.DBG SYM, "sprPtr2_a", "00", STATIC, "sprPtr2_a"
sprPtr2_b: .RES 1
.DBG SYM, "sprPtr2_b", "00", STATIC, "sprPtr2_b"
sprPtr1: .RES 0
.DBG SYM, "sprPtr1", "00", STATIC, "sprPtr1"
sprPtr1_a: .RES 1
.DBG SYM, "sprPtr1_a", "00", STATIC, "sprPtr1_a"
sprPtr1_b: .RES 1
.DBG SYM, "sprPtr1_b", "00", STATIC, "sprPtr1_b"
.SEGMENT "ROM0"
msChar_numSpr: ;;;;;;These entries of the table are assigned to ROM as they should be
.byte $04, $04, $04, $02, $04, $01, $02, $09
.DBG SYM, "msChar_numSpr", "00", STATIC, "msChar_numSpr"
msStart_oam:
.byte $00, $20, $30, $ff, $30, $30, $30, $30, $30, $30, $ff
.DBG SYM, "msStart_oam", "00", STATIC, "msStart_oam"
msStart_state:
.byte $02, $02, $02, $00, $02, $02, $02, $02, $02, $02, $00
.DBG SYM, "msStart_state", "00", STATIC, "msStart_state"
msChar_firstTile:
.byte $00, $20, $10, $29, $18, $27, $2d, $24
.DBG SYM, "msChar_firstTile", "00", STATIC, "msChar_firstTile"
msStart_palette:
.byte $01, $02, $03, $00, $02, $03, $02, $01, $00, $00, $00
.DBG SYM, "msStart_palette", "00", STATIC, "msStart_palette"
So I manually modified the assembly which produced the desired result:
Code:
.IMPORT metaSprite_xSpeed
.IMPORT spriteRam
.IMPORT metaSprite_oam
.SEGMENT "ROM0" ;;;;;I manually added this line in to fix the issue. No errors. program works as expected.
msChar_ySize:
.byte $10, $10, $10, $08, $10, $08, $10, $20
.DBG SYM, "msChar_ySize", "00", STATIC, "msChar_ySize"
msChar_xSize:
.byte $10, $10, $10, $10, $10, $08, $08, $20
.DBG SYM, "msChar_xSize", "00", STATIC, "msChar_xSize"
.SEGMENT "BSS0": zeropage
sprPtr2: .RES 0
.DBG SYM, "sprPtr2", "00", STATIC, "sprPtr2"
sprPtr2_a: .RES 1
.DBG SYM, "sprPtr2_a", "00", STATIC, "sprPtr2_a"
sprPtr2_b: .RES 1
.DBG SYM, "sprPtr2_b", "00", STATIC, "sprPtr2_b"
sprPtr1: .RES 0
.DBG SYM, "sprPtr1", "00", STATIC, "sprPtr1"
sprPtr1_a: .RES 1
.DBG SYM, "sprPtr1_a", "00", STATIC, "sprPtr1_a"
sprPtr1_b: .RES 1
.DBG SYM, "sprPtr1_b", "00", STATIC, "sprPtr1_b"
.SEGMENT "ROM0"
msChar_numSpr:
.byte $04, $04, $04, $02, $04, $01, $02, $09
.DBG SYM, "msChar_numSpr", "00", STATIC, "msChar_numSpr"
msStart_oam:
.byte $00, $20, $30, $ff, $30, $30, $30, $30,
Also, while we're on the topic of tables...
- It took me awhile to figure out how to use them. It was pretty much trial and error trying to make sense of the errors when compiling until I realized how to instantiate them. I'd recommend adding a simple example to the documentation.
- It's a bummer that tables entries can't be assigned by the use of constant types.
I wish I could do this with my "HERO" constant:
Code:
table msChar of metaSpriteCharacter ;must have more than one row!
;HERO = 0 ;2x3 hero
firstTile=HERO,numSpr=4,xSize=16,ySize=16
- It's also a bummer that I can't set address type variables to equal the address of a table entry.
I tried this:
Code:
fast address ptr
ptr = @metaSprite.state[msprID]
and got this:
Code:
source\sprite.uc(96): Error: Identifiers may not contain the dot character
Compilation failed
So in order to set pointers to tables I moved 'fixed' tables I have a 'fake' sram.uc file which is used for importing, but then I use my manually generated sram.s file instead of having uc65 compile it for me. That way I know tables are fixed addresses, then I create constants for those entries and then use those constants to set address variables to point to said tables...
Lastly, here's a copy of my code:
https://dl.dropboxusercontent.com/u/183 ... broken.zip There are properly named .s files of broken compiled sprite.s and manually fixed sprite.s