It is currently Thu Aug 17, 2017 6:37 am

All times are UTC - 7 hours



Forum rules


Related:



Post new topic Reply to topic  [ 25 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Wed Apr 26, 2017 2:42 pm 
Offline

Joined: Wed Apr 26, 2017 2:26 pm
Posts: 11
I started writing code for SNES for the first time today, though I've written a pong clone for NES once.

So I got myseld the SNES Programming Manual that is floating around the web and wrote a simple initialisation routine and basic code, that will display a green screen(most SNES tutorials seem to start with this).

Alas, my code won't work. After one hour of checking and re-checking my init routine, I turn to you in hope of finding someone who will find my error.

I work with the ca65 assembler, since I used that for my NES programming and I'm most comfortable with it.

so, here goes my code.

My "main" file:
Code:
; my first SNES ROM
.p816   ; 65816 processor
.i16    ; X/Y are 16 bits
;.a8     ; A is 8 bits

.segment "ROMREG"
    .include "RomRegisterData.inc"

.segment "VECTORS"
    .word 0, 0, 0, 0, 0, 0, 0, 0
    .word 0, 0, 0, 0, 0, NMI, reset, 0

.segment "CODE"
    .include "SNESInit.asm"
    .include "tiles.inc"

reset:
    jsr InitSNES

    ; set background to green
    lda #$1f
    sta $2122
    lda #$00
    sta $2122

    ; Max screen brightness
    lda #$0f
    sta $2100

forever:
    jmp forever

NMI:
    rti


my initalisation routine(I guess the error is somewhere here):
Code:
; init SNES according to SNES Programming Manual chapter 23
    .include "SNESRegisters.inc"
;----------------------------------------------------------
InitSNES:
    ; basic pre-init setup
    sei             ; disable interrupts
    clc             ; switch to...
    xce             ; ...native mode

    rep #$38        ; X,Y and A are 16 bits, decimal mode off

    ldx #$1fff      ; set up stack
    txs

    lda #$0000      ; set Data Register to zero
    tcd

    ; turn on forced blanking / turn of screen
    sep #$20        ; A is 8 bits
    lda #$8F
    sta INIDISP
    ;rep #$20        ; A is 16 bits
   
    ; clear Registers
    phk             ; Data Bank = Program Bank
    plb

    ldx #$2101
loop00:             ; Regs $2101 - $210c
    stz $00,x
    inx
    cpx #$210d
    bne loop00

loop01:             ; Regs $201d - $2114
    stz $00,x
    stz $00,x
    inx
    cpx #$2115
    bne loop01

    lda #$80        ; set VRAM mode
    sta $2115

    stz $2116
    stz $2117

        ; $2118 and $2119 need no initialisation

    stz $211a

    ldx #$211b
loop03:             ; Regs $211b - $2120
    stz $00,x
    stz $00,x
    inx
    cpx #$2121
    bne loop03

    stz $2121

        ; $2122 need no initialisation
   
    ldx #$2123
loop04:             ; Regs $2123 - $2133
    stz $00,x
    inx
    cpx #$2134
    bne loop04

    ldx #$4200
loop05:             ; Regs $4200 - $420d
    stz $00,x
    inx
    cpx #$420e
    bne loop05

    lda #$30        ; turn on fixed color addition
    sta $2130

    lda #$e0        ; turn on RGB
    sta $2132

    lda #$ff        ; turn on I/O port
    sta $4201

    ; set Main Registers
    ;lda #$1f        ; turn on all BGs and OBJ
    ;sta $212c

    ; set BG1 - 4 and OBJ

    ; OAM, CG Data setting with DMA
    jsr InitOAMandCG

    ; VRAM Data setting with DMA
    jsr InitVRAM

    ; release forced blanking
    lda #$0F
    sta INIDISP

    ; enable NMI and standard controller
    lda #$81
    sta $4200
    cli

    rts

;----------------------------------------------------------
; init OAM and CG RAM
InitOAMandCG:
    rts

;----------------------------------------------------------
; init VRAM
InitVRAM:
    rts


Those are the two most important files. Here are the other two mentioned.

SNESRegisters.inc (I plan to expand this...)
Code:
; register aliases

INIDISP             = $2100


ROMRegisterData.inc
Code:
; ROM Registration Data as specified in SNES Manual 1-2-25

.word       $ffff               ; maker code
.byte       $47, $52, $45, $4e  ; game code
.byte       $00, $00, $00, $00, $00, $00, $00
.byte       $00                 ; no expansion RAM
.byte       $00                 ; no special version
.byte       $00                 ; no special/sub cartridge
.byte       "MY FIRST TILES"    ; game title
.byte       $20, $20, $20, $20  ; game title fill
.byte       $30                 ; high speed, Mode 20
.byte       $00                 ; ROM only cartridge
.byte       $07                 ; 1Mb/128kB, NOT DOCUMENTED
.byte       $00                 ; 0B, no RAM
.byte       $00                 ; Japan
.byte       $33                 ; fixed value
.byte       $00                 ; revision number
.word       $aaaa               ; checksum
.word       $5555               ; complement checksum



Any help is greatly welcomed.


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 2:52 pm 
Offline
User avatar

Joined: Sat Jan 03, 2015 5:58 pm
Posts: 358
Location: ...
Could you post your cfg file for ld65?

_________________
Buy stuff from my brother's retro gaming store!


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 2:55 pm 
Offline

Joined: Wed Apr 26, 2017 2:26 pm
Posts: 11
nicklausw wrote:
Could you post your cfg file for ld65?


Yes, forgot that one, it's pretty basic:

Code:
# minimal SNES cartridge

MEMORY {
    ROM1:   start = $8000, size = $200000, fill = yes;
}

SEGMENTS {
    CODE:       load = ROM1,    align = $8000;
    ROMREG:     load = ROM1,    start = $ffb0;
    VECTORS:    load = ROM1,    start = $ffe0;
}



I even made a makefile:
Code:
CC = ca65
LD = ld65
LDCONF = -C lorom128.cfg
OBJECTS = MyFirstTile.o

MyFirstTile.smc: $(OBJECTS)
   $(LD) $(LDCONF) $(OBJECTS) -o $@

MyFirstTile.o: MyFirstTile.asm
   $(CC) $<

clean:
   rm *.o *.smc


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 2:55 pm 
Offline

Joined: Sun Mar 27, 2016 7:56 pm
Posts: 131
I notice that your init code already turns off forced blanking. That might be interfering with your writes to $2122, since they're probably not happening during Vblank/Hblank.


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 2:59 pm 
Offline

Joined: Wed Apr 26, 2017 2:26 pm
Posts: 11
Nicole wrote:
I notice that your init code already turns off forced blanking. That might be interfering with your writes to $2122, since they're probably not happening during Vblank/Hblank.


True, I moved it to NMI/VBlank, to no avail. Still a black screen.


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 3:05 pm 
Offline

Joined: Sun Mar 27, 2016 7:56 pm
Posts: 131
Another problem I see is that you use jsr to call your init code, but that's where you set up the stack, so rts won't return you back where you were, because the stack pointer is no longer pointing at the address you need to return to.

You should probably jmp to the init code, and jmp back instead. Alternatively, you could just have the vector point straight to InitSNES, and then jmp reset at the end of your init code.


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 3:24 pm 
Offline

Joined: Wed Apr 26, 2017 2:26 pm
Posts: 11
Nicole wrote:
Another problem I see is that you use jsr to call your init code, but that's where you set up the stack, so rts won't return you back where you were, because the stack pointer is no longer pointing at the address you need to return to.

You should probably jmp to the init code, and jmp back instead. Alternatively, you could just have the vector point straight to InitSNES, and then jmp reset at the end of your init code.


I did try that before, neither jmp nor jsr won't do the trick. I even tried moving all of the code into on file to avoid both op codes - still nothing.

I probably missed some small detail about how registers on the SNES work, the programming manual has a weird structure. Maybe I'll try to re-write one of the tutorials I found to work on ca65/ld65, that might help.


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 3:31 pm 
Offline
User avatar

Joined: Sat Jan 03, 2015 5:58 pm
Posts: 358
Location: ...
Not entirely sure if this is the problem but try using .smart at the beginning of your code. It tracks REPs and SEPs to properly size opcodes, whereas your code seems to assume that A is always 8 bit and X,Y are always 16 bit. A changes size during the init routine which could mess everything up.

_________________
Buy stuff from my brother's retro gaming store!


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 3:36 pm 
Offline
User avatar

Joined: Sat Jan 03, 2015 5:58 pm
Posts: 358
Location: ...
Another thing, your header has the title set to 18 bytes instead of 21. Fixing this made a red screen come up, not sure why that's happening but it's better than what was showing up before.

_________________
Buy stuff from my brother's retro gaming store!


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 3:43 pm 
Offline

Joined: Sun Mar 27, 2016 7:56 pm
Posts: 131
The color #$001f is in fact red, not green, and that's what's being written, so it sounds like it's actually working in that case.


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 3:46 pm 
Offline

Joined: Wed Apr 26, 2017 2:26 pm
Posts: 11
nicklausw wrote:
Another thing, your header has the title set to 18 bytes instead of 21. Fixing this made a red screen come up, not sure why that's happening but it's better than what was showing up before.


A red screen is what I want! I changed my header, but it still won't work, what emulator do you use?


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 3:50 pm 
Offline
User avatar

Joined: Sat Jan 03, 2015 5:58 pm
Posts: 358
Location: ...
After changing the starting vector to InitSNES jumping to reset, turning on smart mode, changing the name size and changing the ROM type in the header from $30 to $20 (you had it set to HiROM, I believe?), the code functions properly.

Not sure what emulator you're using but I recommend bsnes-plus. Its debugger is why I didn't say "the code works!" when the screen is red but the code is a constant loop of brk $00.

_________________
Buy stuff from my brother's retro gaming store!


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 4:01 pm 
Offline

Joined: Sun Mar 27, 2016 7:56 pm
Posts: 131
nicklausw wrote:
changing the ROM type in the header from $30 to $20 (you had it set to HiROM, I believe?)

Nah, $30 means fast LoROM, versus $20 for slow LoROM (whereas HiROM is $21 or $31). Having $30 there shouldn't be an issue.


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 4:02 pm 
Offline

Joined: Wed Apr 26, 2017 2:26 pm
Posts: 11
Wow, thank you! I never used .smart before, since it is my first 65816 code. A quick look up in the ca65 doc tells me I probably need to study the registers/architecture of the 65816 better - my guess right now is, I'm not using Data Bank and Program Bank registers properly.

That would also explain why PC keeps pointing to $00 / BRK.

Again, thank you all for your suggestions, you've been all very helpful! :P


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 4:09 pm 
Offline
User avatar

Joined: Sat Jan 03, 2015 5:58 pm
Posts: 358
Location: ...
Nicole wrote:
nicklausw wrote:
changing the ROM type in the header from $30 to $20 (you had it set to HiROM, I believe?)

Nah, $30 means fast LoROM, versus $20 for slow LoROM (whereas HiROM is $21 or $31). Having $30 there shouldn't be an issue.

Oh yeah, I thought there was a difference because I forgot to rebuild after changing the header...

Which brings me to a piece of advice, make sure your makefiles are aware of the reliance on your .inc files. Should be a quick %.s: %.inc and adding %.s as a dependency on your ROM.

Another tip that's pretty minor and more of a personal thing but I might as well mention it, please use the .sfc format instead of .smc. .smc is an old copier format that originally had a 512-byte header in front of it, but it doesn't seem to now, and the inconsistency is pretty gross so I'd rather everyone just use .sfc.

_________________
Buy stuff from my brother's retro gaming store!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 25 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: adam_smasher, Bing [Bot], nocash and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group