This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

NESASM - TASM

NESASM - TASM
by on (#68439)
Hi all,

I need an assembler for 16-bit MSDOS, only one I found is TASM. Apparently some changes are needed to iNES-header (I've only used NESASM for programming NES), any tips for the header and possible other changes.

Here are examples of original NESASM code I've used (I work only with sound):

HEADER:

Code:

   .inesprg 1
   .ineschr 1
   .inesmir 0
   .inesmap 0
   .org $8000
   .bank 0
   .bank 1
   .org $FFFA
   .dw 0
        .dw start
   .dw 0
   .bank 0
   .org $C000


VBLANK (timing):

Code:

loop1
vwait
   lda $2002
   bpl vwait
   dex
   bne loop1
   rts


I compiled just header with NESASM, rest (usual NESASM) code, then combined the files (copy /b header.nes+dasdfd.nes file.nes), I hear that sound is switched on, then nothing. No errors in compiling.

Thanks for advance !


-jp

by on (#68442)
TASM is a nice assembler, but you will need to change quite a bit to make it work. For example, turn the header into a proper sequence of .db bytes instead of whatever there was before. Also add Colons : to the end of all labels.

TASM has label length limits, so watch out. I think the limit is 15 characters, not sure though. Remember to invoke Tasm in 6502 mode (-t65 command line option).

I think TASM 3.2 is a win32 console program, TASM 3.1 is the last DOS version.

By the way, you can run many Win32 console programs in DOS mode using the HXDOS extender.

by on (#68443)
Thanks, good advices, I need to translate the header first. I'm using TASM 3.1 in PocketPC, it works without problems (compiles as usually), just need to find the differences between NESASM and TASM.

Thanks !

-jp


ps. Seems that 3.1 use only -65 (without t) option.



Dwedit wrote:
TASM is a nice assembler, but you will need to change quite a bit to make it work. For example, turn the header into a proper sequence of .db bytes instead of whatever there was before.

TASM has label length limits, so watch out. I think the limit is 15 characters, not sure though. Remember to invoke Tasm in 6502 mode (-t65 command line option).

I think TASM 3.2 is a win32 console program, TASM 3.1 is the last DOS version.

By the way, you can run many Win32 console programs in DOS mode using the HXDOS extender.

by on (#68452)
Another thing I often do, is keep the header as a seperate 16-byte file, then in my .bat file that builds it, it does a "copy /b header+rom rom.nes" type of operation. But that's largely because having the header built-in is a disadvantage for me. When I use my ROM emulator for testing, the header is of no use.

by on (#68488)
I tried this, but didn't worked. How did you compiled the header ? I compiled the header with nesasm, rest with TASM, added with "copy /b ...", but still it doesn't work.


Thanks !



Memblers wrote:
Another thing I often do, is keep the header as a seperate 16-byte file, then in my .bat file that builds it, it does a "copy /b header+rom rom.nes" type of operation. But that's largely because having the header built-in is a disadvantage for me. When I use my ROM emulator for testing, the header is of no use.

by on (#68489)
You can just make a header with a hex editor.

by on (#68493)
Tried this too, made a 16-byte header of the working .nes-file. Compiling with

Code:

tasm -65 -b file.asm file.nes

copy /b header+file.nes file1.nes




Still not working :(





Dwedit wrote:
You can just make a header with a hex editor.
[/code]

by on (#68494)
You need spaces, because + is a legal character in a filename.
Re: NESASM - TASM
by on (#68495)
jp48 wrote:
Hi all,

I need an assembler for 16-bit MSDOS, only one I found is TASM.

There's also a 16-bit version of DASM out there. Google finds it.

by on (#68496)
Seems to work with and without spaces, the files are identical when checking with hex editor. Also, if I remember correctly + wasn't legal char in filenames in 16-bit DOS.

Anyway, thanks, all tips are appreciated !


-jp

Dwedit wrote:
You need spaces, because + is a legal character in a filename.
Re: NESASM - TASM
by on (#68497)
Thanks, found it, the code compiles without errors, but doesn't work with header added directly with "copy /b"-method.

Any hints to the iNES-header, so far:

Code:

 processor 6502
 ORG $8000



Not much yet. :).

This would be much easier if I got any error messages but all compiles without problems, not getting any errors. Anyway, the problem must be in the header, code compiles with NESASM, TASM and DASM.


-jp


thefox wrote:
There's also a 16-bit version of DASM out there. Google finds it.

by on (#68503)
How about your filesize, does it match up exactly with what the header says? You using CHR-ROM or CHR-RAM? If the emulator loads it without complaining about the size being wrong, the next thing to look at is the vectors, are they in the right place? Many times in FCEU if I didn't know WTF was going on, it helps to just go into the debugger, hit step so it pauses, then hit reset and step to see if it starts up properly.

We might have to see the complete source and build method to help you out.

edit: I think I see the problem maybe, your NESASM header (in your first post) is saying it's a 16kB ROM, but you are starting at $8000, then advancing to $FFFA for the vectors (this will result in a 32kB ROM in any normal assembler, dunno about nesasm..). You'll want to start at $C000 for 16kB (though technically you can put the vectors at $BFFA, no one usually does that).

by on (#68509)
Yeah, I think we need to see more code. I find it weird that in the code you listed as "HEADER" we can see your CPU vectors. Those vectors are not part of the header, and if by any chance you took that out of your program, that could mean you are generating a vectorless (!) ROM, which would obviously never work.

Also, it's nice that you have your NMI and IRQ vectors pointing to $0000. If you are not using those (and the fact that you are not using NMIs is not a good sign, because they are the best way to keep track of time), at least have them point to an RTI instruction somewhere in the ROM, to reduce the chances of your program crashing.

by on (#68518)
OK, good to know, and thanks all of information so far !

I compose experimental music using old consoles as sound sources, using simple vblank routine as timer is adequate, don't need more as the sound file or live settings is (heavily) modified. I use other languages to generate NESASM code, each NES-file is used once for one composition, then new program, another composition etc. I use NES, but others as well: SMS, Genesis, Atari 2600, 5200, GB, MSX and so on, different any languages I find those machines.

NES-files consist three components (the header is originally from some tutorial, tried to find without luck). It seems I posted the older version of the header, here's what I've used with NESASM currently:

Code:

   .inesprg 1
   .ineschr 0
   .inesmir 1
   .inesmap 0
   .bank 1
   .org $fffa
   .dw 0
   .dw start
   .dw 0
   .bank 0
   .org $8000


Second component is timing:

Code:

loop1:
vwait:
   lda $2002
   bpl vwait
   dex
   bne loop1
   rts



Then the last component, it consist just of direct writing to sound registers, depending what I'm working, but this is a short sample which contain what is needed (I hope):

Code:

start:
   lda #15
   sta $4015    ; all four channels
start1:
   lda #70
   sta $4000
   lda #84
   sta $4001
   lda #167
   sta $4002
   lda #205
   sta $4003

        ....         ; more writing to sound registers

   ldx #16   
   jsr loop1 ;calling vblank

        ....          ; same continues until a loop is formed

        jmp start1 ; endless loop




That's all, header, enabling necessary sound channels, writing directly to sound registers, looped vblank for timing and back to start. Simple, clumsy, direct, but exactly what I need.

Thanks !


-jp

by on (#68521)
tokumaru wrote:
Yeah, I think we need to see more code. I find it weird that in the code you listed as "HEADER" we can see your CPU vectors. Those vectors are not part of the header

Someone who has previously dabbled in Super NES, Sega Genesis, or Game Boy might have been confused this way. All these platforms have a block of vectors right next to an internal header; see, for example, the SNES header. Even some later NES games have an embryonic form of the SNES-style header (what's that ZELDA at the end of the PRG of SMB2 (U)?). But iNES format is different in that the 16-byte board descriptor at the start of the ROM file isn't mapped anywhere that the CPU can see; it's solely an invention of pirates and independent archivists.

by on (#68524)
jp48 wrote:
Code:
   .org $fffa
   .dw 0
   .dw start
   .dw 0

The problem is that this part has nothing to do with the iNES header. These are the CPU vectors, that unlike the header, which goes at the start of the file, should be at the end of the ROM. These vectors have absolutely nothing to do with the header, and I find it very weird that you treat them like they are the same thing.

My guess is that you are producing a ROM with invalid vectors at the end, which causes your program to crash (because the CPU jumps to a location that contains invalid code instead of jumping to your "start" label). Try putting the code above at the end of the source code to put the vectors in the correct place.

Since I'm not familiar with the assembler you're using and I haven't seen your exact source file(s), I can't be any more specific.

by on (#68525)
I've "copied" the iNES header from this tutorial:

http://patater.com/gbaguy/day2n.htm

It was a bit difficult, according the tutorial, to know what part was header, what code (without any prior knowledge of NESASM). I thought these lines were part of the header (which was weird in my mind too, I've programmed Atari 6502 machines, for instance with XASM the "header" is simply one line: ORG "address" (for 8-bit Atari computers), for Atari 2600 with DASM two lines. With the "header" I've used with NESASM everything has worked without problems, I tried to move these four lines at the end of the code, nothing happens, no sound. The program as I described previous post is practically complete source code and it doesn't crash, it works with NESASM, my problem is: how to write iNES header, correct iNES header for DASM or XASM or TASM, these I've found that works in 16-bit MS-DOS, with DASM I've made a first program using only PocketPC for creating, compiling and running it, Atari 2600 .bin, pDOSBOX and PocketVCS. Now I would like to do same (my original target) NES, using DASM/XASM/TASM and PocketNESter.

Thanks for your help !


-jp



tokumaru wrote:
jp48 wrote:
Code:
   
        .org $fffa
   .dw 0
   .dw start
   .dw 0

The problem is that this part has nothing to do with the iNES header. These are the CPU vectors, that unlike the header, which goes at the start of the file, should be at the end of the ROM. These vectors have absolutely nothing to do with the header, and I find it very weird that you treat them like they are the same thing.

My guess is that you are producing a ROM with invalid vectors at the end, which causes your program to crash (because the CPU jumps to a location that contains invalid code instead of jumping to your "start" label). Try putting the code above at the end of the source code to put the vectors in the correct place.

Since I'm not familiar with the assembler you're using and I haven't seen your exact source file(s), I can't be any more specific.

by on (#68526)
OK, getting closer, found a better NESASM manual, now I probably know better what's the problem with DASM:

1. iNES header (is it 16 bytes, so it can be solved by hex editor and copy /b).

2. Banking: how it is done in DASM.

Moving those four lines Tokumaru mentioned to the end didn't worked as it needed one line more ie.

Code:

    .bank 1
    .org $fffa
    .dw 0
    .dw start
    .dw 0



Now it works in NESASM with the header:

Code:

   .inesprg 1
   .ineschr 0
   .inesmir 1
   .inesmap 0


and adding

Code:
     .bank 0
     .org $8000


before "start"-label. So now the vectors (NMI, reset and IRQ) are at the end (really not a part of the header as I though), now I need to know how to handle the banking with DASM/TASM.

Thanks for your patience, soon this is over :) .


-jp

by on (#68527)
jp48 wrote:
now I need to know how to handle the banking with DASM/TASM.

I'm not familiar with DASM/TASM, but most assemblers do not need this explicit bank configuration NESASM does...

It could be as simple as this:
Code:
   ;HEADER HERE

   .org $8000

   ;PRORAM HERE

   .org $FFFA

   ;VECTORS HERE

by on (#68528)
Exactly, it is simple, just doesn't work. You're (and probably me too) close, in DASM:

Code:
    processor 6502
    org $8000

    .... program

    org $FFFA
    .word 0
    .word start ; reset
    .word 0


Nothing else should be needed (of course correct iNES-header), still doesn't work. I need to study this more, found one example and read more manual.

Thanks !


-jp


tokumaru wrote:
I'm not familiar with DASM/TASM, but most assemblers do not need this explicit bank configuration NESASM does...

It could be as simple as this:
Code:
   ;HEADER HERE

   .org $8000

   ;PRORAM HERE

   .org $FFFA

   ;VECTORS HERE

by on (#68550)
Remember the iNES header has nothing to do with the NES itself, the ROM might be perfect as it is. Only the emulator will use the header, and if it says there's 1 PRG bank and your code origin is at $8000 as it in the posted code, the emulator isn't going to see the vectors, it might only see the first 16kB ($8000-$BFFF) no matter how big the ROM is. If you put stuff in the ROM, then load it an emulator like FCEU and use the memory viewer, you will be able to see what the CPU sees to verify what's happening.

The 16kB PRG size bank is simply what the iNES emulator went with. Turns out there's only one game that uses an 8kB PRG-ROM (AFAIK), Galaxian. So it's arbitrary but works for most stuff.

edit: I should also clarify that what NESASM calls banks is unique to NESASM and is unrelated to mapper banks, and iNES bank numbers.

by on (#68552)
Memblers has a point. There seems to be an inconsistency regarding the ROM size. If your code goes from $8000 to $FFFF, that means you have 32KB of PRG-ROM, which means that the PRG-ROM count field in the header should be 2 (for 2 16KB banks).

by on (#68561)
Memblers and Tokumaru,

It was exactly that, 32KB ROM, code was longer than 16KB, just changed offset 4 of the header from 1 to 2, works now, perfectly !

A LOT of thanks of your patience and tips in solving this !!!


-jp