snes assembly - beginnings, a few questions (wla-65816)
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
Re: snes assembly - beginnings, a few questions (wla-65816)
The 65816 book is available online. It will answer that and many other questions. (yes, long is 24-bit)
Re: snes assembly - beginnings, a few questions (wla-65816)
It looks like you understood palettes correctly. Color numbers depends on if you use the palette for a 4bpp or 2bpp character (so a 4bpp color 4 is the same as a 2bpp color 0 as you said).
Re: snes assembly - beginnings, a few questions (wla-65816)
What is the point of using e.g. LDA.W / STA.W in WLA-65816? At first I thought that using ".W / .B" (hinting operand) would make the assembler automatically set the correct 8/16 processor mode during compilation. But I still have to set SEP / REP before such an operation.
Re: snes assembly - beginnings, a few questions (wla-65816)
There are different opcodes that share the same name, but take different address lengths. LDA.W $#### means use absolute addressing, LDA.L $###### is long addressing, LDA.B $## is direct page. This is useful to e.g. prevent the assembler from assuming that LDA $0047 is supposed to be direct page, because the number fits in a byte.
Re: snes assembly - beginnings, a few questions (wla-65816)
Thanks.
One more problem I noticed is that the "default" screen is shifted one line up. Many Homebrews do exactly the same, and the screen is shifted up one line.
Maybe a silly little thing, but I wonder why this is happening..
Writing to BG1 skroll vertical register fixed it, but I would like to know if it is normal?
lda #$FF
sta $210E
lda #$00
sta $210E
Is this normal and you need to manually align the screen to make it perfectly even?
One more problem I noticed is that the "default" screen is shifted one line up. Many Homebrews do exactly the same, and the screen is shifted up one line.
Maybe a silly little thing, but I wonder why this is happening..
Writing to BG1 skroll vertical register fixed it, but I would like to know if it is normal?
lda #$FF
sta $210E
lda #$00
sta $210E
Is this normal and you need to manually align the screen to make it perfectly even?
- Attachments
-
- test.smc
- (256 KiB) Downloaded 24 times
Re: snes assembly - beginnings, a few questions (wla-65816)
Line 0 doesn't render. It's for scanning OAM so the first displayed line will have sprites on it. This means that neutral Y scroll is actually -1.
This is also why overscan mode is 239 lines high instead of 240.
This is also why overscan mode is 239 lines high instead of 240.
-
- Posts: 1565
- Joined: Tue Feb 07, 2017 2:03 am
Re: snes assembly - beginnings, a few questions (wla-65816)
WLA has a separate linker which has no idea how to make or adjust code. So in the cases where the assembler doesn't know where a symbol is, it then has no idea of how big it has to make the address, because the address isn't finalized until the linking stage. Thus you need to tell the assembler what size of the address you want it to actually use.sdm wrote: ↑Mon Mar 21, 2022 3:55 am What is the point of using e.g. LDA.W / STA.W in WLA-65816? At first I thought that using ".W / .B" (hinting operand) would make the assembler automatically set the correct 8/16 processor mode during compilation. But I still have to set SEP / REP before such an operation.
Re: snes assembly - beginnings, a few questions (wla-65816)
I cannot yet fully understand how register protection works after a VBLANK interrupt is performed. Is the processor working state 8/16 bit automatically secured at the time of interrupt execution and resumed automatically at the time of execution of "RTI"?
For example, in the CPU-Loop I have a code that is to be executed in full 8-bit mode (SEP $ 30), after a while a VBLANK interrupt is performed, which often has "rep # $ 30" at the beginning (before PUSH instructions) - I don't know what is the purpose of it. ? (And won't that affect the previously broken code in Cpu-Loop that was set to full 8bit?)
cpu loop code:
Examples of VBLANK functions:
For example, in the CPU-Loop I have a code that is to be executed in full 8-bit mode (SEP $ 30), after a while a VBLANK interrupt is performed, which often has "rep # $ 30" at the beginning (before PUSH instructions) - I don't know what is the purpose of it. ? (And won't that affect the previously broken code in Cpu-Loop that was set to full 8bit?)
cpu loop code:
Code: Select all
sep #$30 ; all 8-bit
<---- vblank has occurred
; some 8-bit code
Examples of VBLANK functions:
Code: Select all
VBlank:
rep #$30 ; A/Mem=16bits, X/Y=16bits (what's the purpose ??)
phb
pha
phx
phy
phd
sep #$20 ; mem/A = 8 bit, X/Y = 16 bit
lda #$00 ; set DataBank = $00
pha
plb
; update the joypad data
JSR GetInput
lda $4210 ; clear NMI Flag
rep #$30 ; A/Mem=16bits, X/Y=16bits
pld
ply
plx
pla
plb
rti
Code: Select all
nmi:
rep #$10 ; X/Y 16-bit ( ??)
sep #$20 ; A 8-bit (??)
phd
pha
phx
phy
; Do stuff that needs to be done during V-Blank
lda $4210 ; reset NMI flag
ply
plx
pla
pld
return_int:
rti
Re: snes assembly - beginnings, a few questions (wla-65816)
The interrupt and RTI behavior is also covered in detail in the 65816 book. *hint hint*
Re: snes assembly - beginnings, a few questions (wla-65816)
Yes the 8-/16-bit modes are saved at an NMI. They are the X (bit 4) and M (bit 5) flags in the P register, and the P register is pushed to stack automatically at NMI and restored at RTI (just like with the 6502).
-
- Posts: 611
- Joined: Mon Jan 23, 2006 7:47 am
- Location: Germany
- Contact:
Re: snes assembly - beginnings, a few questions (wla-65816)
And there's a surprisingly detailed article on Wikipedia: https://en.wikipedia.org/wiki/Interrupt ... processors
My current setup:
Super Famicom ("2/1/3" SNS-CPU-GPM-02) → SCART → OSSC → StarTech USB3HDCAP → AmaRecTV 3.10
Super Famicom ("2/1/3" SNS-CPU-GPM-02) → SCART → OSSC → StarTech USB3HDCAP → AmaRecTV 3.10
Re: snes assembly - beginnings, a few questions (wla-65816)
Will there be any difference when REP # $ 30 is set before PHB / PHD ? Is it better to do this before pushing the A / X / Y registers onto the stack? (does it matter at all)
Or:
Code: Select all
VBlank:
REP #$30 ; A/mem=16 bits, X/Y=16 bits (to push all 16 bits)
PHB
PHD
PHA
PHX
PHY
(...)
Code: Select all
VBlank:
PHB
PHD
REP #$30 ; A/mem=16 bits, X/Y=16 bits (to push all 16 bits)
PHA
PHX
PHY
(...)
Re: snes assembly - beginnings, a few questions (wla-65816)
PHB and PHD have nothing to do with M and X so that wouldn't matter.
PHA, PHX and PHY pushes either 8-bit or 16-bit depending on M and X, so that does matter.
Using REP or SEP together with a PHP or PLP also matters of course, since those pushes or pulls the processor register.
PHA, PHX and PHY pushes either 8-bit or 16-bit depending on M and X, so that does matter.
Using REP or SEP together with a PHP or PLP also matters of course, since those pushes or pulls the processor register.
Re: snes assembly - beginnings, a few questions (wla-65816)
Does changing the processor operating mode 8/16 bit before jumping to any function cause problems in the operation of the mode change? I noticed that changing before jumping to a function a at the beginning of that function causes a difference in how the mode change works. For example, the function CopyOAMBuff I set SEP 20 before jumping to this function and at the beginning:
Code: Select all
;--------------------
VBlank:
REP #%00110000 ; select 16 bit registers (REP #$30)
PHB ; save current data bank
PHD ; save direct page pointer
PHA ; save accumulator
PHX ; save X-register
PHY ; save Y-register
SEP #$20 ; ### will not work properly (It works when it is at the beginning of this function) ###
JSR CopyOAMBuf
LDA $4210 ; Clear NMI flag
REP #%00110000 ; select 16 bit registers (REP #$30)
PLY ; restore Y-register
PLX ; restore X-register
PLA ; restore accumulator
PLD ; restore direct page pointer
PLB ; restore current data bank
RTI ; resume interrupted task
;--------------------
CopyOAMBuff:
;;; 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
-
- Posts: 1565
- Joined: Tue Feb 07, 2017 2:03 am
Re: snes assembly - beginnings, a few questions (wla-65816)
assemblers are not magic and don't follow your jumps, jsrs branches etc to work out the correct size.
So
Please see my "Taming the 65816 video" for best practices and things to be wary of when using the 65816 and how to avoid falling into the traps. https://youtu.be/vbw0Fp5fqtE
So
Code: Select all
;--------------------
VBlank:
REP #%00110000 ; select 16 bit registers (REP #$30)
---- assembler knows that A is 16 bits and assembles A as 16 bit
PHB ; save current data bank
PHD ; save direct page pointer
PHA ; save accumulator
PHX ; save X-register
PHY ; save Y-register
SEP #$20 ; ### will not work properly (It works when it is at the beginning of this function) ###
---- assembler knows that A is 8 bits and assembles A as 8bit
JSR CopyOAMBuf
LDA $4210 ; Clear NMI flag
REP #%00110000 ; select 16 bit registers (REP #$30)
---- assembler knows that A is 16 bits and assembles A as 16 bit
PLY ; restore Y-register
PLX ; restore X-register
PLA ; restore accumulator
PLD ; restore direct page pointer
PLB ; restore current data bank
RTI ; resume interrupted task
;--------------------
CopyOAMBuff:
---- assembler still knows that A is 16 bits and assembles A as 16 bit
;;; SEP #$20 ; Sets A to 8-bit mode (### I am moving before I jump into this function ###)
BUT THIS CODE EXPECTS IT TO BE 8BITS
So it will be assembled as if A is 16 bits but ran when A is 8bits which will go wrong
you need to add the command to inform WLA-DX that A is 8 bits here.
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