edit: oh you saw my post pre-edit? I'm wondering here if you can set the I/O bank elsewhere and the RAM page into MPR1 to use zero page as $0000. I need to try this later, sadly it doesn't matter in case you're using the CD/SCD bios since I think that it depends on the "default" bank arrangement to work properly. Does ST0/ST1/ST2 go through the mapper or does it map directly to the actual physical addresses? Hmm.
I didn't make another post instead because I don't want to derail this even further.
They are trying to fix this problem with ca65 by adding a directive that can set the Zero Page to wherever you want, this would fix the 65816 Direct Page problems as well. But apparently the assumption that the Zero Page is always $0000 is deeply rooted in its code, so it isn't very easy to fix.
Not needed. The assembler doesn't need to know where the direct page (zero page) is located. The programmer just needs to use zero page addressing...and the system should correctly map it to the actual direct page (zero page), wherever it is. I fail to see the problem.adding a directive that can set the Zero Page to wherever you want
Or is the problem using absolute addresses for $0000? Just put an a: in front of it.
If I define a variable in .zeropage, it will usually be accessed with direct page addressing modes. But if I try to use it with an addressing mode that supports only absolute addressing, such as those in JMP (aaaa) or LDA aaaa,Y, ca65 will instead generate instructions with an operand of $0000-$00FF instead of $2000-$20FF. This causes the CPU to access I/O, such as the VDC/VCE, instead of the intended variable.
If I instead define a variable in an absolute segment at $2000-$20FF, most accesses thereto will be inefficient because the CPU has to spend a memory cycle reading the $20 byte. In addition, many addressing modes, such as that in LDA (dd),Y, cause ca65 to produce a range error and fail to produce an object code file because the address is not in the range $0000-$00FF.
What I want to be able to do is define a variable, access it with direct page addressing modes, and have accesses using absolute-only addressing modes (particularly aaaa,Y) use $2000.
ca65 will generate zeropage instructions for absolute values, or symbols (using .res) in the ZEROPAGE segment (or any other segment with the : zeropage qualifier), or symbols whose zeropage status is not yet known (e.g. if they're defined later in the file, they're presumed absolute because it's a one-pass assembler and can't go back later). Otherwise it uses absolute.
I think there are some memory mapped registers in the $0000 page for PCe that need to be addressed absolutely, but there's lots of ways to force absolute addressing:
- Prefix addresses with a:
- Use mirrors at $0100 page instead?
- Create a segment for them and use .res to align appropriate symbols to the registers.
Alternatively, you can put them in a zeropage segment that "thinks" it's at $0000, and since they'll generate ZP instructions the accesses will go to the correct place. (Similarly, you could use 8-bit absolute addresses (e.g. $03 instead of $0003) and get the same result.) I think the main problem with this is there might be cases where ca65 presumes it's safe to promote an 8-bit address to a 16-bit address? (Not sure, but I suspect it's a possibility.) Also if you want to manually use absolute addressing for any of these you'll need to extend them yourself (e.g. $2000 | variable).
I think the real problem is just having to know what variables belong on the DP and which don't. Over a long project you may want to move stuff back and forth, etc. and doing so basically breaks code that needs to be revised. Ideally you would be able to abstract that information away... which is easy to do in ca65 when the ZP is where the assembler thinks it is.
Curiously, I think NESASM might have the opposite problem on the NES, having no automatic ZP addressing and requiring the error-prone < to generate ZP instructions at all. (Though the original assembler it's derived from was a PCe assembler, so the original version probably properly suppoerts PCe's DP?)
According to the Magickit's readme file, NESASM and PCEAS was made from modifying a generic 6502 assembler. It was first named "AS", but later it was split into PCEAS and NESASM, with the later having all the PC Engine-specefic instructions removed, and iNES header directives added. PCEAS also got a bunch of directives and options for PCE header (which is unnecessary with emulators and modern flashcards), CD assembly and support for the consumer-level devkit "Develo BOX".
PCEAS uses the same syntax as NESASM, including the staple-brackets  for indirect addressing and the required < for zero page addressing. But lately forks of it has done away with the infamous .bank directives (which do makes more sense on PC Engine than on NES but still are unnecessary constrains) and added <, > and ^ as aliases for the LOW(), HIGH() and BANK() functions, to make it a bit more like other assemblers.
It probably is the best assembler for PC Engine right now, and I recommend Elmer's fork (grab the pceas.exe file in the bin directory), that's what I'm using anyway and it has all of the above mentioned improvements properly implemented.
Some people actually prefer the < for ZP addressing, and personally I haven't had any problems with it after I got used to it. It makes it clear that ZP addressing mode is used, and unlike ASM6, it allows to use other addressing modes with ZP registers if you really want to.
Code: Select all
PlayerFieldAnimation: LDA PlayerFieldDirection CLC ADC PlayerFieldFrame TAX LDY #$01 - LDA herofield, x STA SpriteRam, y INX INY LDA herofield, x STA SpriteRam, y INX INY INY INY CPY #$11 BNE - RTS
Code: Select all
Dir_South = $00 Dir_North = $10 Dir_East = $20 Dir_West = $30 FieldFrame1 = $00 FieldFrame2 = $08
Code: Select all
herofield: ;south1 south2 .db $00, %00000000, $01, %00000000, $10, %00000000, $11, %00000000, $02, %00000000, $01, %00000000, $12, %00000000, $13, %00000000 ;north1 north2 .db $04, %00000000, $05, %00000000, $14, %00000000, $15, %00000000, $04, %00000000, $07, %00000000, $16, %00000000, $17, %00000000 ;east1 east2 .db $08, %00000000, $09, %00000000, $18, %00000000, $19, %00000000, $08, %00000000, $0B, %00000000, $1A, %00000000, $1B, %00000000 ;west1 west2 .db $0C, %00000000, $0D, %00000000, $1C, %00000000, $1A, %01000000, $0E, %00000000, $0D, %00000000, $1E, %00000000, $18, %01000000
As I understand, NSS only allows you to see how your map will look but you can't really export it in a format that ASM6 will read, right? Are there any better tools to do map stuff?
Also, few questions about doing a map. Would you guys use 16x16 or 32x32 chunks as metatiles for an overworld RPG map?
How about vertical/horizontal flipping of single 8x8 BG tiles? Impossible because attribute tables correspond to the whole 16x16 chunk?
How did you save and open? You should use the All -> Save and All -> Open menus.Friendly_Noob wrote:By the way, I'd like to use NES Screen Tool for mapping but every time I save a project and try to open it I get an error (attachment).
Try reading the readme.txt file.I have no idea how to make a metasprite either, it just doesn't react with anything I click in that section.
Not true. It outputs basic binary files, which you can read in no problem with .incbin in asm6.As I understand, NSS only allows you to see how your map will look but you can't really export it in a format that ASM6 will read, right?
Not possible on NES (without creating a new tile for the flipped version).How about vertical/horizontal flipping of single 8x8 BG tiles? Impossible because attribute tables correspond to the whole 16x16 chunk?