Page 1 of 3

Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Wed Jan 07, 2015 12:35 pm
by That_Nintendo_Guy
Hey guys. This is my first post, so... yeah, I hope I don't sound too n00bish or anything. :| Also, I'm not very good at keeping forum posts compact, so if you get bored with reading this probably over-winded post, just JMP down to theTL:DR section at the bottom...

Anyway, so, recently I started becoming interested in programming games for the NES (obviously). My original wish was to make games for the N64, which I'll probably get around to eventually, but which I also can't do right now because all the compilers I've found are for PC, and all I have ATM is an Android tablet :roll: . Fortunately enough for me, someone else on this site did an indirect jump to my rescue (haha, see what I did there) and compiled a copy of ASM6 that will work for Android with a command line tool. Not *exactly* what I was looking for, but at least I can make retro Nintendo games. Plus, it gives me an excuse to learn a new programming language :D Besides, the homebrew scene for the N64 seems to be pretty bunk, and I'm afraid that if I ever have any trouble with something along that front, I wont be able to receive too terribly much aid.

So, after doing some looking about, I found Bunnyboy's Nerdy Nights tutorials, which from what I've read\heard are some of the best. So, I read them, and they indeed are very good at explaining things related to NES programming (and 6502 programming in general). But of course, reading something doesn't matter a bit (or a byte) unless you can actually put what you read to use. Aaand unfortunately for me, the Nerdy Nights tutorials are designed for NESASM, not ASM6. Which is what I'm writing here about.

So, I downloaded a ZIP file that contained the source for this NN sound engine tutorial. I'm a pretty big fan of chiptune music, so I wanted to write my own tunes and get them bumping right away. Unfortunately I can't for the life of me get the code to correctly assemble mainly because it uses a lot of NESASM specific directives (.bank, inesprg, etc). Not to mention the slightly different syntax for things like indirection. I tried reworking the code quite a bit to make it more ASM6 friendly, but it still doesn't assemble correctly. What the program is SUPPOSED to be is a simple music player that lets you listen to your songs and change songs with the controller. At best, all I get when I assemble it and run it in an emulator is a black screen and this annoying sound on the noise channel. I know the code itself isn't bad (unless I screwed it up somehow by tinkering with it), so the issue is probably with how the assembler is building it, meaning the directives I'm using are probably off. Here's a copy of the main file. There are includes in there, but those don't have much of anything that would get in the way. PS: sorry if it looks a little messy. I commented out the NESASM code and left it in there so that I could see what my own stuff needed to look like.

TL:DR: ;reader got bored, so they'll read this
I need help with modifying a Nerdy Nights source code file so that it assembles in ASM6. I've included a copy of the file so that you can see what's up.

Edit: Damn, the file browser on my tab won't open when I click Choose File. Looks like I'll have to copy-paste it in a separate post :(

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Wed Jan 07, 2015 12:38 pm
by That_Nintendo_Guy
K, here is the code, from "drums.ask":

Code: Select all

    .inesprg 2 ;2x 16kb PRG code
    .ineschr 1 ;1x 8kb CHR data
    .inesmap 0 ; mapper 0 = NROM, no bank swapping
    .inesmir 1 ;background mirroring (vertical mirroring = horizontal scrolling)

    .rsset $0000
joypad1 .rs 1           ;button states for the current frame
joypad1_old .rs 1       ;last frame's button states
joypad1_pressed .rs 1   ;current frame's off_to_on transitions
sleeping .rs 1          ;main program sets this and waits for the NMI to clear it.  Ensures the main program is run only once per frame.  
                        ;   for more information, see Disch's document: http://nesdevhandbook.googlepages.com/theframe.html
needdraw .rs 1          ;drawing flag.
dbuffer_index .rs 1     ;current position in the drawing buffer
ptr1 .rs 2              ;a pointer
sound_ptr .rs 2
sound_ptr2 .rs 2
current_song .rs 1
    
;----- first 8k bank of PRG-ROM
    .bank 0
    .org $8000  ;we have two 16k PRG banks now.  We will stick our sound engine in the first one, which starts at $8000.
    
    .include "sound_engine.asm"

;----- second 8k bank of PRG-ROM    
    .bank 1
    .org $A000
    
;----- third 8k bank of PRG-ROM    
    .bank 2
    .org $C000
    
irq:
    rti
NMI:
    pha     ;save registers
    txa
    pha
    tya
    pha
    
    ;do sprite DMA
    ;update palettes if needed
    ;draw stuff on the screen
    
    lda needdraw
    beq .drawing_done   ;if drawing flag is clear, skip drawing
    lda $2002           ;else, draw
    jsr draw_dbuffer
    lda #$00            ;finished drawing, so clear drawing flag
    sta needdraw
    
.drawing_done:    
    lda #$00
    sta $2005
    sta $2005   ;set scroll
    
    jsr sound_play_frame    ;run our sound engine after all drawing code is done.
                            ;this ensures our sound engine gets run once per frame.
                            
    lda #$00
    sta sleeping            ;wake up the main program
    
    pla     ;restore registers
    tay
    pla
    tax
    pla
    rti

RESET:
    sei
    cld
    ldx #$FF
    txs
    inx
    
vblankwait1:
    bit $2002
    bpl vblankwait1
    
clearmem:
    lda #$00
    sta $0000, x
    sta $0100, x
    sta $0300, x
    sta $0400, x
    sta $0500, x
    sta $0600, x
    sta $0700, x
    lda #$FE
    sta $0200, x
    inx
    bne clearmem
    
 vblankwait2:
    bit $2002
    bpl vblankwait2
    
;set a couple palette colors.  This demo only uses two
    lda $2002   ;reset PPU HI/LO latch
    
    lda #$3F
    sta $2006
    lda #$00
    sta $2006   ;palette data starts at $3F00
    
    lda #$0F    ;black
    sta $2007
    lda #$30    ;white
    sta $2007
    
    jsr draw_background
    
;Enable sound channels
    jsr sound_init
    
    lda #$01
    sta current_song
    ;jsr sound_load
    
    lda #$88
    sta $2000   ;enable NMIs
    lda #$18
    sta $2001   ;turn PPU on

forever:
    inc sleeping ;go to sleep (wait for NMI).
.loop:
    lda sleeping
    bne .loop ;wait for NMI to clear the sleeping flag and wake us up
    
    ;when NMI wakes us up, handle input, fill the drawing buffer and go back to sleep
    jsr read_joypad
    jsr handle_input
    jsr prepare_dbuffer
    jmp forever ;go back to sleep
    
    
;----------------------------
; read_joypad will capture the current button state and store it in joypad1.  
;       Off-to-on transitions will be stored in joypad1_pressed
read_joypad:
    lda joypad1
    sta joypad1_old ;save last frame's joypad button states
    
    lda #$01
    sta $4016
    lda #$00
    sta $4016
    
    ldx #$08
.loop:    
    lda $4016
    lsr a
    rol joypad1  ;A, B, select, start, up, down, left, right
    dex
    bne .loop
    
    lda joypad1_old ;what was pressed last frame.  EOR to flip all the bits to find ...
    eor #$FF    ;what was not pressed last frame
    and joypad1 ;what is pressed this frame
    sta joypad1_pressed ;stores off-to-on transitions
    
    rts

;---------------------
; handle_input will perform actions based on input:
;   up - play current song
;   down - stop playing the song
;   left - cycle down a song
;   right - cycle up a song
handle_input:
    lda joypad1_pressed
    and #$0F ;check d-pad only
    beq .done
.check_up:
    and #$08 ;up
    beq .check_down
    lda current_song
    jsr sound_load
.check_down:
    lda joypad1_pressed
    and #$04 ;down
    beq .check_left
    lda #$00
    jsr sound_load
.check_left:
    lda joypad1_pressed
    and #$02 ;left
    beq .check_right
    jsr song_down
.check_right:
    lda joypad1_pressed
    and #$01 ;right
    beq .done
    jsr song_up    
.done:
    rts

;--------------------
; song_down will move selection down a song.  Song 1 wraps around to last song
song_down:
    dec current_song
    lda current_song
    bne .done
    lda #NUM_SONGS-1    ;last song.  We wrapped from Song 1
    sta current_song
.done:
    rts
    
;----------------------
; song_up will move selection up a song.  Last song will wrap to song 1   
song_up:
    inc current_song
    lda current_song
    cmp #NUM_SONGS          ;did we move past the last song?
    bne .done           ;if not, no problem
    lda #$01            ;but if we did, wrap around to song 1
    sta current_song
.done:
    rts
    
;-------------------------------
; prepare_dbuffer fills the drawing buffer with the text strings we need 
prepare_dbuffer:    
    ;write either "playing" or "not playing" to the dbuffer
    lda stream_status
    ora stream_status+1
    ora stream_status+2
    ora stream_status+3
    ora stream_status+4
    ora stream_status+5
    and #$01
    beq .sound_not_playing  ;if all streams disabled, write "NOT PLAYING" on the screen
    lda sound_disable_flag
    bne .sound_not_playing  ;if the disable flag is set, we want to write "NOT PLAYING" too
.sound_playing:
    lda #LOW(text_playing)  ;set ptr1 to point to beginning of text string
    sta ptr1
    lda #HIGH(text_playing)
    sta ptr1+1
    jmp .dbuffer
.sound_not_playing:
    lda #LOW(text_not_playing)
    sta ptr1
    lda #HIGH(text_not_playing)
    sta ptr1+1
.dbuffer:
    lda #$21    ;target PPU address.  add_to_dbuffer expects the HI byte in A and the LO byte in Y
    ldy #$0B
    jsr add_to_dbuffer
    
    jsr song_num_to_dbuffer
    
    lda #$01
    sta needdraw    ;set drawing flag so the NMI knows to draw
    
    rts

;-------------------------
; add_to_dbuffer will convert a text string into a dbuffer string and add it to the drawing buffer.
;   add_to_dbuffer expects:
;       HI byte of the target PPU address in A, 
;       LO byte of the target PPU address in Y
;       pointer to the source text string in ptr1
;   dbuffer string format:
;       byte 0: length of data (ie, length of the text string)
;       byte 1-2: target PPU address (HI byte first)
;       byte 3-n: bytes to copy
;   Note:   dbuffer starts at $0100.  This is the stack page.  The
;               stack counts backwards from $1FF, and this program is small enough that there
;               will never be a conflcit.  But for larger programs, watch out.
add_to_dbuffer:
    ldx dbuffer_index
    sta $0101, x    ;write target PPU address to dbuffer
    tya
    sta $0102, x
    
    ldy #$00
.loop:
    lda [ptr1], y
    cmp #$FF
    beq .done
    sta $0103, x    ;copy the text string to dbuffer,
    iny
    inx
    bne .loop
.done:
    ldx dbuffer_index
    tya
    sta $0100, x        ;store string length at the beginning of the string header
    
    clc
    adc dbuffer_index
    adc #$03        
    sta dbuffer_index   ;update buffer index.  new index = old index + 3-byte header + string length
    
    tax
    lda #$00
    sta $0100, x        ;stick a 0 on the end to terminate dbuffer.
    rts

;----------------------------------------------
; song_num_to_dbuffer tells the drawing buffer to write the currently selected song number on the screen.
song_num_to_dbuffer:
    ldx dbuffer_index
    lda #$01        ;write one byte
    sta $0100, x
    lda #$21        ;destination PPU $214A
    sta $0101, x
    lda #$4A
    sta $0102, x
    lda current_song ;which byte to write
    sta $0103, x
    lda #$00         ;terminate the dbuffer with 0
    sta $0104,x
    txa              ;update our index
    clc
    adc #$04
    sta dbuffer_index
    rts
    
;------------------------
; draw_dbuffer will write the contents of the drawing buffer to the PPU
;       dbuffer is made up of a series of drawing strings.  dbuffer is 0-terminated.
;       See add_to_dbuffer for drawing string format.
draw_dbuffer:
    ldy #$00
.header_loop:
    lda $0100, y
    beq .done       ;if 0, we are at the end of the dbuffer, so quit
    tax             ;else this is how many bytes we want to copy to the PPU
    iny
    lda $0100, y    ;set the target PPU address
    sta $2006
    iny
    lda $0100, y
    sta $2006
    iny
.copy_loop:
    lda $0100, y    ;copy the contents of the drawing string to PPU
    sta $2007
    iny
    dex
    bne .copy_loop
    beq .header_loop    ;when we finish copying, see if there is another drawing string.    
.done:
    ldy #$00
    sty dbuffer_index   ;reset index and "empty" the dbuffer by sticking a zero in the first position
    sty $0100
    rts

;----------------------------
; draw_background will draw some background strings on the screen
;   this hard-coded routine is called only once in RESET
draw_background:

    lda #$21
    sta $2006
    lda #$04
    sta $2006
    ldy #$00
.loop:
    lda text_sound, y
    bmi .sound_done
    sta $2007
    iny
    bne .loop
.sound_done:
    lda #$21
    sta $2006
    lda #$44
    sta $2006
    ldy #$00
.loop2:
    lda text_song, y
    bmi .done
    sta $2007
    iny
    bne .loop2
.done:
    rts
    
;----- fourth 8k bank of PRG-ROM    
    .bank 3
    .org $E000

;these are our text strings.  They are all terminated by $FF

text_song:
    .byte $22, $1E, $1D, $16, $0D, $FF ;"SONG:"
    
text_sound:
    .byte $22, $1E, $24, $1D, $13, $0D, $FF ;"SOUND:"
text_not_playing:
    .byte $1D, $1E, $23, $00 ;"NOT "
text_playing:
    .byte $1F, $1B, $10, $28, $18, $1D, $16, $00, $00, $00, $00, $FF ;"PLAYING    "

    
;---- vectors
    .org $FFFA     ;first of the three vectors starts here
    .dw NMI        ;when an NMI happens (once per frame if enabled) the 
                   ;processor will jump to the label NMI:
    .dw RESET      ;when the processor first turns on or is reset, it will jump
                   ;to the label RESET:
    .dw irq        ;external interrupt IRQ is not used in this tutorial
    
    .bank 4
    .org $0000
    .incbin "drums.chr"

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Wed Jan 07, 2015 1:49 pm
by mikaelmoizt
Oh. I personally think it would be a lot easier to help if you uploaded your black screen version of this, possibly with everything needed to run it. A black screen version that assembles is a lot less work than getting the code you posted to work (yes, I tried for about half an hour, but it is just so many local labels and missing source file "sound_engine.asm" alone gives a lot of undef'd variables to complicate things.

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Wed Jan 07, 2015 4:38 pm
by That_Nintendo_Guy
Oh. I personally think it would be a lot easier to help if you uploaded your black screen version of this, possibly with everything needed to run it. A black screen version that assembles is a lot less work than getting the code you posted to work (yes, I tried for about half an hour, but it is just so many local labels and missing source file "sound_engine.asm" alone gives a lot of undef'd variables to complicate things.
Yeeeeah, not having all the code can complicate things just a little bit lol. And yeah, BB could've went a little lighter on the local labelling. Oh well, I fixed that in my version (which took a good couple of hours).

Anyway, here is my version of the main file and sound engine. There's also CHR that goes with it, but its not really that important, you can use pretty much any 8K CHR you want, as long as its 8K.

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Wed Jan 07, 2015 4:41 pm
by tokumaru
The ASM6 templates I posted a few years ago should give you some tips on how to make this conversion.

The header must be created using .db/.byte/whatever statements, instead of .inesprg and such. You can copy that part stright out of my template, along with the constants at the very top, which you can change according to your configuration.

Then there's .rsset, which can be replaced with .enum, and you need a matching .ende after the variables are declared. Instead of .rs, you must use .dsb to reserve bytes for variables.

ASM6 doesn't work with banks like NESASM does, so get rid of .bank statements. You can keep the .org as is, but in ASM6 you can also use .base to set or reset the PC, so it's useful when you use bankswitching and have different code that will be mapped to the same address. You don't need the .org $A000 in ASM6, because it doesn't force you to use 8KB banks, so you don't have to explicitely make that section blank. You can keep it if you still wish to divide the PRG into 4 8KB banks though.

As for the ASM code itself, there are a few differences: indirection is represented with (), not [], so change all xxx [xx], y instructions into xxx (xx), y. Instead of #LOW() and #HIGH(), use < and > to get the low and high bytes of a 16-bit word. Use "@", not "." at the start of temporary labels.

After the vectors, remove the .org $0000 or replace it with .base $0000. Resetting the PC here is only necessary if you plan on accessing tiles in the pattern table using labels, but that's hardly ever the case.

Now, about sound_engine.asm, is that in ASM6 format already? If it isn't you'll have to convert it as well. EDIT: Oh, I that it's already in ASM6 format, which is probably the reason you want to modify your program, so that you can use that sound engine.

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Wed Jan 07, 2015 4:55 pm
by That_Nintendo_Guy
The header must be created using .db/.byte/whatever statements, instead of .inesprg and such. You can copy that part stright out of my template, along with the constants at the very top, which you can change according to your configuration.

Then there's .rsset, which can be replaced with .enum, and you need a matching .ende after the variables are declared. Instead of .rs, you must use .dsb to reserve bytes for variables.

ASM6 doesn't work with banks like NESASM does, so get rid of .bank statements. You can keep the .org as is, but in ASM6 you can also use .base to set or reset the PC, so it's useful when you use bankswitching and have different code that will be mapped to the same address. You don't need the .org $A000 in ASM6, because it doesn't force you to use 8KB banks, so you don't have to explicitely make that section blank. You can keep it if you still wish to divide the PRG into 4 8KB banks though.

As for the ASM code itself, there are a few differences: indirection is represented with (), not [], so change all xxx [xx], y instructions into xxx (xx), y. Instead of #LOW() and #HIGH(), use < and > to get the low and high bytes of a 16-bit word. Use "@", not "." at the start of temporary labels.

After the vectors, remove the .org $0000 or replace it with .base $0000. Resetting the PC here is only necessary if you plan on accessing tiles in the pattern table using labels, but that's hardly ever the case.

Now, about sound_engine.asm, is that in ASM6 format already? If it isn't you'll have to convert it as well. EDIT: Oh, I that it's already in ASM6 format, which is probably the reason you want to modify your program, so that you can use that sound engine.
Actually, I already knew about all this stuff, like about the .reset ->enum thing and changing the header info and what not. If you look at the version of the source that I just posted you can see that. Also, I replaced all local label declarations with unique label names that are non local (which has the added benefit of making the code that much easier to look through). Obviously though, its not working, so I've done something wrong somewhere. Please feel free to enlighten me on what that is. And while you're doing that, I can go take a peek at those templates of yours. Oh, and BTW, was it you that made that one colored raycasting engine demo that I saw in this one Youtube video? If so, good job! I had no idea the NES was capable of such things.
EDIT: Well, based on your template, I can definetly say that I most likely declared the variables the wrong way. According to the README, you define them like this: "foo: db 0" but in your template they are defined like "variable .DSB 3". I should probably get to changing at least that much.There are probably other things, but I don't have time for those at the moment.

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Wed Jan 07, 2015 6:39 pm
by tokumaru
That_Nintendo_Guy wrote:Also, I replaced all local label declarations with unique label names that are non local (which has the added benefit of making the code that much easier to look through).
Local labels are pretty useful... I'd absolutely hate if I had to think of unique names for all labels! Well, you can keep using local labels (in the newest version of ASM6, there's an older version that doesn't have local labels), just have them start with "@".
Obviously though, its not working, so I've done something wrong somewhere. Please feel free to enlighten me on what that is.
I can't see anything wrong at first glance, but I can't assemble it myself because the sound engine includes a bunch of files I don't have. My advice is that you look at the errors being reported by the assembler. What does it say when it fails to create your ROM? Or does it create the ROM but it doesn't work? In this case, is the ROM the correct size (16 + 32768 + 8192 = 40976 bytes)? I really can't tell much from "it's not working".
Oh, and BTW, was it you that made that one colored raycasting engine demo that I saw in this one Youtube video? If so, good job! I had no idea the NES was capable of such things.
Yeah, I did make a raycasting demo. In fact we've been discussing different approaches to raycasting since Celius posted a new demo he made.
EDIT: Well, based on your template, I can definetly say that I most likely declared the variables the wrong way. According to the README, you define them like this: "foo: db 0" but in your template they are defined like "variable .DSB 3". I should probably get to changing at least that much.
The .db method should work too, it's just not recommended (I didn't even notice this was in the readme, I wouldn't encourage the use of that method) because .db declares a value, and you can't put a value in RAM like that. This means that the number that comes after .db is meaningless, it doesn't go anywhere or does anything, and this is confusing. also, if you wanted to declare a 16-bit variable you'd have to do .db 0, 0 or .dw 0, which just adds to the confusion. What about arrays? .db 0, 0, 0, 0, 0, 0, 0, 0? Hell no. .dsb and .dsw are the directives that should be used for reserving bytes.

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Wed Jan 07, 2015 8:36 pm
by koitsu
I'd suggest using the -l (dash-lowercase-ELL) or -L (dash-uppercase-ELL) flag to generate a listing, and then go through that. If something is being assembled not quite how you expect (thus generating code that doesn't work how you intended), it'd be in there.

Also try running the code under an emulator (e.g. FCEUX) and see what happens, as well as setting a breakpoint at the location the RESET vector points to (assuming you know what address that is in ROM (listing file should help)) and step through things to see what may be misbehaving.

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Thu Jan 08, 2015 7:25 am
by tepples
In FCEUX, you can set a reset breakpoint without needing to look at the listing file.
  1. Open FCEUX for Windows.
  2. Open your ROM.
  3. Debug > Debugger
  4. In the debugger window, click Step Into to stop the program.
  5. In the game window, NES > Reset.
  6. In the debugger window, click Step Into again, and the PC will be at the reset vector.
  7. If expected code isn't here, then either your assembler is configured incorrectly or you've done something wrong in mapper support.
The "Run Line" and "128 Lines" buttons will be your friend when skipping past spinning on $2002 reads in your init code.

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Thu Jan 08, 2015 12:09 pm
by rainwarrior
You can also type in "RESET" (or "NMI", or "IRQ") as an address in the FCEUX debugger and it will automatically be changed to the value currently in the reset vector.

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Thu Jan 08, 2015 12:18 pm
by tokumaru
rainwarrior wrote:You can also type in "RESET" (or "NMI", or "IRQ") as an address in the FCEUX debugger and it will automatically be changed to the value currently in the reset vector.
I did not know that, thanks! Now I can stop scrolling all the way down the disassembly to check out the vectors.

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Thu Jan 08, 2015 1:24 pm
by mikaelmoizt

Code: Select all

; contents of sound_engine_ASM6

    .include "sound_opcodes.asm"    ;our opcode subroutines, jump table and aliases
    .include "note_table.i" ;period lookup table for notes
    .include "note_length_table.i"
    .include "vol_envelopes.i"
    .include "song0.i"  ;holds the data for song 0 (header and data streams)
    .include "song1.i"  ;holds the data for song 1
    .include "song2.i"
    .include "song3.i"
    .include "song4.i"
    .include "song5.i"
    .include "song6.i"
    .include "song7.i"
    .include "song8.i"
Still unable to assemble this :wink:

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Thu Jan 08, 2015 2:21 pm
by That_Nintendo_Guy
Ok ok, so HERE is a full ZIP of all the files, including ALL of the includes this time. Unfortunately, now that I've tried to set up the file the way Tokumaru showed in his template, I keep getting "Value Out of Range" errors during assembly for the second song data (Song1.i) :(
*Oh, and for songs 3 and 6, along with one error apiece for both 7 and 8...

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Thu Jan 08, 2015 3:02 pm
by That_Nintendo_Guy
Oh, and about FCEU. As I said before, this Android tablet is all I have right now. I mean, I guess I could use the PCs at my town's library, but that would require that FCEU not need any sort of install process, which I highly doubt it doesn't... Or, if there happens to be an NES emulator for Androids that boasts a realtime debugger, please be my guest and elaborate.

Re: Need Help Converting A Nerdy Nights Tutorial to ASM6

Posted: Thu Jan 08, 2015 3:25 pm
by koitsu
That_Nintendo_Guy wrote:Oh, and about FCEU. As I said before, this Android tablet is all I have right now. I mean, I guess I could use the PCs at my town's library, but that would require that FCEU not need any sort of install process, which I highly doubt it doesn't... Or, if there happens to be an NES emulator for Androids that boasts a realtime debugger, please be my guest and elaborate.
FCEUX is what's called a "standalone app". It does not require installation. You can unpack the .7z/.zip file into a local directory of your choice and run it from there. Settings/etc. get stored in fceux.cfg (written to the same dir as the .exe). Debug statefiles, if enabled in the debugger, get stored in the same directory as the ROM.

As for the "Value out of range" errors, that's because the code is using .include (a.k.a. .incsrc) rather than .incbin (a.k.a. .bin). In asm6, .include is intended to include source code, and safe to say songX.i are actual binary files. Hence the error.

I assume you've read the README.TXT that comes with asm6? All assembler directives are described there. Those should be easier to fix than actual 6502 syntax changes between assemblers, and the iNES header ordeal (which tokumaru already helped address). There aren't that many directives (compared to other assemblers I'm used to), so it isn't that long of a read, and it's very easy to refer to.

P.S. -- How is it you're able to run asm6, which is a Win32 executable, on Android then?

P.P.S. -- Since your driving force here is making NES music, is there some reason you're going through all this pain when FamiTracker already provides you what you need (it can export both .NSF, .NES, as well as .BIN files if you wanted to make your own stuff)? Music code/sequencers are painful. I guess now we're back to the Win32 vs. Android thing. I think you're going to find doing full-on NES development on Android to be a lot more tedious/ridiculous than if you actually had a small workstation. Would a netbook interest you? Say, a Dell Inspiron Mini 10? I have one I was given a few months ago which works but is lacking an AC adapter (which I can buy somewhere I'm sure), and I'd be happy to donate it to you. It runs Windows XP.