REP #$30 ; Sets A, X and Y to 16-bit mode
PHB
PHD
PHA
PHX
PHY
SEP #$20 ; Sets A to 8-bit mode
JSR CopyOAMBuf
(...)
CopyOAMBuf:
"---- assembler still knows that A is 16 bits and assembles A as 16 bit"
I am asking because I don't understand why assembler "remembers" SEP # $ 30 set earlier than "SEP # $ 20" set just before jsr jump?
(...)
RTS
snes assembly - beginnings, a few questions (wla-65816)
Moderator: Moderators
- For making cartridges of your Super NES games, see Reproduction.
Re: snes assembly - beginnings, a few questions (wla-65816)
Re: snes assembly - beginnings, a few questions (wla-65816)
Re: snes assembly - beginnings, a few questions (wla-65816)
Will using together with SEP / REP additionally "hinting operand" eg LDA.W / LDA.B ... ..LDX.W etc, work similarly to using .ACCU 8 / .ACCU 16 / .INDEX 8 etc directives?
So far I have no major problems in the code - just experimenting what and how it works. I try to stick to A8 / XY16 and only WHEN I NEEDED - I change the processor mode to another, and going back to A8 / XY16.
EDIT:
It's probably all clear:
This also works, so just change LDA to "LDA.B" to tell the assembler about A8:REP #$30 ; Sets A, X and Y to 16-bit mode
PHB
PHD
PHA
PHX
PHY
SEP #$20 ; Sets A to 8-bit mode
JSR CopyOAMBuf
(...)
CopyOAMBuf:
.ACCU 8 ; Now it is working.
;;; SEP #$20 ; Sets A to 8-bit mode (### I am moving before I jump into this function ###)
STZ $2102 ; set OAM address to 0
STZ $2103
LDY #$0400
STY $4300
LDY #$1C00
STY $4302 ; source offset
LDY #$0220
STY $4305 ; number of bytes to transfer
LDA #$7E
STA $4304
LDA #$01
STA $420B ; start DMA transfer
RTS
REP #$30 ; Sets A, X and Y to 16-bit mode
PHB
PHD
PHA
PHX
PHY
SEP #$20 ; Sets A to 8-bit mode
JSR CopyOAMBuf
(...)
CopyOAMBuf:
;;;;.ACCU 8
;;; SEP #$20 ; Sets A to 8-bit mode (### I am moving before I jump into this function ###)
STZ $2102 ; set OAM address to 0
STZ $2103
LDY #$0400
STY $4300
LDY #$1C00
STY $4302 ; source offset
LDY #$0220
STY $4305 ; number of bytes to transfer
LDA.B #$7E
STA $4304
LDA.B #$01
STA $420B ; start DMA transfer
RTS
- Attachments
-
- output.smc
- (256 KiB) Downloaded 34 times
-
- Posts: 1565
- Joined: Tue Feb 07, 2017 2:03 am
Re: snes assembly - beginnings, a few questions (wla-65816)
The issue you have is you think the assembler follows you code path, it doesn't. So you say
Code: Select all
.ACCU 8
jsr my function
No, the assembler does not simulate, run, or understand your code. It starts at the top of the file and it goes line by line down the file. It never jumps, stalls, looks ahead, just line by line.
Code: Select all
VBlank:
Code: Select all
REP #%00110000 ; select 16 bit registers (REP #$30)
Code: Select all
PHB
Code: Select all
PHD
Code: Select all
PHA
Code: Select all
PHX
Code: Select all
PHY
Code: Select all
SEP #$20
Code: Select all
JSR CopyOAMBuf
Code: Select all
LDA $4210
Code: Select all
REP #%00110000 ; select 16 bit registers (REP #$30)
Code: Select all
PLY
Code: Select all
PLX
Code: Select all
PLA
Code: Select all
PLD
Code: Select all
PLB
Code: Select all
RTI
Code: Select all
CopyOAMBuff:
Code: Select all
STZ $2102
Code: Select all
STZ $2103
Code: Select all
LDY #$0400
Code: Select all
STY $4300
Code: Select all
LDY #$1C00
Code: Select all
STY $4302 ; source offset
Code: Select all
LDY #$0220
Code: Select all
STY $4305 ; number of bytes to transfer
Code: Select all
LDA #$7E
Code: Select all
STA $4304
Code: Select all
LDA #$01
Code: Select all
STA $420B ; start DMA transfer
So always set the accumulator and index sizes before each function, as you can change it accidentally with a small code change and then it could just break every function after it.
-
- Posts: 1565
- Joined: Tue Feb 07, 2017 2:03 am
Re: snes assembly - beginnings, a few questions (wla-65816)
Code: Select all
SEP #$30
...code...
PHP
REP #$30
...code...
PLP
.. this is actually 8axy but the assembler doesn't understand PHP/PLP tracking,
.. so the assembler still thinks you have 16bit axy as the last Auto command was REP.
Code: Select all
SEP #$30
...code...
PHP
REP #$30
...code...
PLP
.accu8
.index8
...code...
Re: snes assembly - beginnings, a few questions (wla-65816)
I know how assembler works and I know that it doesn't follow my thinking, it just translates line by line into machine code.Oziphantom wrote: ↑Fri Mar 25, 2022 10:33 pm The issue you have is you think the assembler follows you code path, it doesn't.
My question concerns only the operation of the 8/16 modes of this processor, which is unclear to me due to the first contact with such a solution.
-
- Posts: 1565
- Joined: Tue Feb 07, 2017 2:03 am
Re: snes assembly - beginnings, a few questions (wla-65816)
If M flag is 1 the CPU reads 8 bits values on the accumulator operations and memory operations. If it's 0 it does 16 bit operations.
If X flag is 1 the CPU reads 8 bits values on the index operations . If it's 0 it does 16 bit operations.
Only changing the M or X flags will change the way the CPU operates in 8 or 16 bit data mode. M X flags or modified by the REP and SEP commands, or the PLP command. So for example you can do
Code: Select all
lda #$30
pha
plp
There is nothing in the instruction it self that determines if the data is to be 8bit or 16 bit, only the status flags determine it. Some instructions are not affected by the M,X and will always interact with a certain number of bytes, but those are rare.
for example LDA #00
So 8bit immediate is A9 00
and 16bit immediate is A9 00 00
how many bytes it writes depends upon the perceived size state by the assembler, and how many it expects to read is determined by the CPU and its current status flags.
So if the assembler puts A9 00 00 but the CPU is in 8bit mode it will read LDA #00 BRK
Re: snes assembly - beginnings, a few questions (wla-65816)
I don't think the high bytes of the index registers X and Y are named as there are no instructions for swapping them or so.
Re: snes assembly - beginnings, a few questions (wla-65816)
Also, when transferring values between registers, it's the destination that determines the size of the transfer. TXA with 16-bit index registers and 8-bit accumulator will only change A and leave B as it is. TAX under the same circumstances will replace the entire current value of X with the value of C. TXA with 8-bit index registers and 16-bit accumulator will set the bottom byte of C to X and zero the top byte.
Re: snes assembly - beginnings, a few questions (wla-65816)
Re: snes assembly - beginnings, a few questions (wla-65816)
Code: Select all
.ENUM $0000 ; wram 00x0000
wariable0 DB
wariable1 DB
(...)
.ENDE
Re: snes assembly - beginnings, a few questions (wla-65816)
I'm pretty sure you can .DEFINE anything you want. If you must make a list of variables and sizes, apparently .RAMSECTION is designed to do this, but I've never used it.
Why are you making a list of variables in high RAM anyway? Have you run out of space in shadow RAM?
Also, $010000 isn't the high WRAM bank. It's bank $01 of the SNES memory map, of which the top half is ROM and the bottom half is generally identical to bank $00, including the 8 KB WRAM mirror. To address anything beyond the bottom 8 KB of WRAM, you need banks $7E and $7F (or the port at $2180, obviously, but accessing variables through that is probably suboptimal in most cases).
Re: snes assembly - beginnings, a few questions (wla-65816)
I thought the wram banks are as follows:
$ 000000-001FFF
$ 010000-011FFF
$ 020000-021FFF ...
$ 3F0000-3F1FFF.
- rainwarrior
- Posts: 8734
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: snes assembly - beginnings, a few questions (wla-65816)
No, those are all mirrors of the same block of RAM.
That first 8kb of RAM ("Low RAM") is available in half of all banks. This means it can conveniently be accessed without having to change the data bank register (B) when using LoROM (or a LoROM area of HiROM).
The remaining 120k of RAM is available exclusively at $7E2000-7FFFF, which means you either have to change the data bank to access it, or use far/long addressing (which takes an extra byte per instruction, and there are fewer available operations).
Maybe these diagrams would be helpful: Wiki: Memory map
Re: snes assembly - beginnings, a few questions (wla-65816)
Code: Select all
.ENUM $7E2000
variable DB
.ENDE
or.
.DEFINE variable $7E2000
For example, when I set a variable, as above in 7E2000, and perform a simple operation on it:
Code: Select all
INC variable
main.asm:642: INPUT_NUMBER: Out of 16-bit range.
main.asm:642: ERROR: Couldn't parse "inc".
But when I do it this way it all works:
Code: Select all
LDA variable
INC A
STA variable
Are there any restrictions on using higher banks against the low one (0000-1FFF)?