It is currently Tue Oct 15, 2019 11:42 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 53 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
PostPosted: Fri Feb 22, 2019 12:16 pm 
Offline
User avatar

Joined: Tue Feb 19, 2019 11:54 pm
Posts: 23
Location: Planet Earth, Milky Way
FrankenGraphics wrote:
Yeah Michael is using ca65, and his tutorials are really nice to follow.

Did you figure out how to use .segments?

.segment seems to be something I haven't although reading about it I think it jumps to other parts of the rom?

https://www.cc65.org/doc/ca65-11.html
it's near the bottom it seems to be a really good source of what things do and mean.

Edit: is it like functions in normal programming?


Top
 Profile  
 
PostPosted: Fri Feb 22, 2019 12:49 pm 
Offline
Formerly WheelInventor
User avatar

Joined: Thu Apr 14, 2016 2:55 am
Posts: 2024
Location: Gothenburg, Sweden
Quote:
is it like functions in normal programming?
No, functions are all done in assembly. You pass arguments to functions through the axy registers, sometimes some flags, and temp memory allocations in the zero page, and call them with jsr and jmp.

Quote:
.segment seems to be something I haven't although reading about it I think it jumps to other parts of the rom?

Sort of... we need to talk about what jumps to different parts (segments) of the rom. I think you're aware of the normal program counter, ie, the cpu register keeping score of where in the program we are during runtime. This is not what jumps.

There is also a second concept of "program counter", somewhat confusingly. This the program counter of your assembler and/or linker, which lays down code and data into your rom image file at build time. This is what jumps around. Maybe think of it as a needle in a programmable sewing machine. The .segment directive creates a sort of label. In your linker config file, you associate those special labels with exact "coordinates" on the cloth. The linker will instruct the needle to jump to these predefined positions of the cloth and lay something down there.

Vectors, for example, are always at the very end of ROM, or even repeated last in every bank in some cases where the last portion of the address range is bank switchable. So it's neat to instead of defining the address of the vectors manually with padding, simply write your three vectors under the segment called vectors and the linker will take care of the rest for you.

Also be sure to check out the linker documentation on the same page.

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Fri Feb 22, 2019 1:35 pm 
Offline
User avatar

Joined: Tue Feb 19, 2019 11:54 pm
Posts: 23
Location: Planet Earth, Milky Way
FrankenGraphics wrote:
Quote:
is it like functions in normal programming?
No, functions are all done in assembly. You pass arguments to functions through the axy registers, sometimes some flags, and temp memory allocations in the zero page, and call them with jsr and jmp.

Quote:
.segment seems to be something I haven't although reading about it I think it jumps to other parts of the rom?

Sort of... we need to talk about what jumps to different parts (segments) of the rom. I think you're aware of the normal program counter, ie, the cpu register keeping score of where in the program we are during runtime. This is not what jumps.

There is also a second concept of "program counter", somewhat confusingly. This the program counter of your assembler and/or linker, which lays down code and data into your rom image file at build time. This is what jumps around. Maybe think of it as a needle in a programmable sewing machine. The .segment directive creates a sort of label. In your linker config file, you associate those special labels with exact "coordinates" on the cloth. The linker will instruct the needle to jump to these predefined positions of the cloth and lay something down there.

Vectors, for example, are always at the very end of ROM, or even repeated last in every bank in some cases where the last portion of the address range is bank switchable. So it's neat to instead of defining the address of the vectors manually with padding, simply write your three vectors under the segment called vectors and the linker will take care of the rest for you.

Also be sure to check out the linker documentation on the same page.


Oh so it's something where you would place code into to make different bytes be assigned to different things. However it is also something that can then later use this data to be used once again.


Top
 Profile  
 
PostPosted: Fri Feb 22, 2019 1:47 pm 
Offline
Formerly WheelInventor
User avatar

Joined: Thu Apr 14, 2016 2:55 am
Posts: 2024
Location: Gothenburg, Sweden
If you want to repeat code & data, you need to use .repeat or .macro

Let's say you want to increase x by four, using the inx instruction.

that'd be:
inx
inx
inx
inx

or, to have better code density/readability, you could do it like this in ca65:

.repeat 4
inx
.endrepeat

macros work more like the stampclone tool of various paint programs.

.macro name
;some code goes here
.endmacro

then each time you type name on a line, that code will be clonestamped there. You can pass arguments to macros as well.

edit: changed syntax to follow ca65.

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Fri Feb 22, 2019 2:37 pm 
Offline
User avatar

Joined: Tue Feb 19, 2019 11:54 pm
Posts: 23
Location: Planet Earth, Milky Way
FrankenGraphics wrote:
If you want to repeat code & data, you need to use .repeat or .macro

Let's say you want to increase x by four, using the inx instruction.

that'd be:
inx
inx
inx
inx

or, to have better code density/readability, you could do it like this in ca65:

.repeat 4
inx
.endrepeat

macros work more like the stampclone tool of various paint programs.

.macro name
;some code goes here
.endmacro

then each time you type name on a line, that code will be clonestamped there. You can pass arguments to macros as well.

edit: changed syntax to follow ca65.


Where might I get the header file / basic head for a nes at? Like I understand some of it mostly that it uses
Code:

$00
$01
$02
ect..



Top
 Profile  
 
PostPosted: Fri Feb 22, 2019 2:47 pm 
Offline
Formerly WheelInventor
User avatar

Joined: Thu Apr 14, 2016 2:55 am
Posts: 2024
Location: Gothenburg, Sweden
Typically, you keep your header either at the top of your main document*, or in a separate file, and use the .include directive to insert it at that point in code during build time.

*i do it like this:

defines (constants, structs, zero page reservations and what else)
header (this is the first thing that actually is laid down in your rom image file)
code and what else
vectors


You can find how a header is structured here:
https://wiki.nesdev.com/w/index.php/INES

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Sat Feb 23, 2019 12:51 am 
Offline
User avatar

Joined: Tue Feb 19, 2019 11:54 pm
Posts: 23
Location: Planet Earth, Milky Way
FrankenGraphics wrote:
Typically, you keep your header either at the top of your main document*, or in a separate file, and use the .include directive to insert it at that point in code during build time.

*i do it like this:

defines (constants, structs, zero page reservations and what else)
header (this is the first thing that actually is laid down in your rom image file)
code and what else
vectors


You can find how a header is structured here:
https://wiki.nesdev.com/w/index.php/INES


Wait wait wait I think I got it so I am basically writing to memory for Input, Display, and Sound? So when I write my header I use a memory address to call a byte to update the screens display.


Top
 Profile  
 
PostPosted: Sat Feb 23, 2019 1:07 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11416
Location: Rio de Janeiro - Brazil
test_matsu wrote:
Wait wait wait I think I got it so I am basically writing to memory for Input, Display, and Sound?

Almost. It's not really memory, but memory-mapped registers. The 6502 doesn't have any dedicated means of communicating with other hardware, so machines that use it have to watch the address bus and "catch" any accesses to special addresses and redirect those to different pieces of hardware.

Quote:
So when I write my header I use a memory address to call a byte to update the screens display.

No, nothing like that. The header is just a bunch of information that lets emulators know what kind of cartridge they need to emulate in order to run your game. It specifies things like how big the ROMs are, which mapper chip/configuration it uses, whether there's extra RAM present, and so on. Without that, emulators (and flash carts like the PiwerPak or the Everdrive N8) can't tell what kind of environment to setup for your game.


Top
 Profile  
 
PostPosted: Sat Feb 23, 2019 1:36 am 
Offline
User avatar

Joined: Tue Feb 19, 2019 11:54 pm
Posts: 23
Location: Planet Earth, Milky Way
tokumaru wrote:
test_matsu wrote:
Wait wait wait I think I got it so I am basically writing to memory for Input, Display, and Sound?

Almost. It's not really memory, but memory-mapped registers. The 6502 doesn't have any dedicated means of communicating with other hardware, so machines that use it have to watch the address bus and "catch" any accesses to special addresses and redirect those to different pieces of hardware.

Quote:
So when I write my header I use a memory address to call a byte to update the screens display.

No, nothing like that. The header is just a bunch of information that lets emulators know what kind of cartridge they need to emulate in order to run your game. It specifies things like how big the ROMs are, which mapper chip/configuration it uses, whether there's extra RAM present, and so on. Without that, emulators (and flash carts like the PiwerPak or the Everdrive N8) can't tell what kind of environment to setup for your game.


Where can I find example code for a header? All I find is bytes and not exactly user-friendly (In my case.. I am better with code examples)


Top
 Profile  
 
PostPosted: Sat Feb 23, 2019 7:05 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 21634
Location: NE Indiana, USA (NTSC)
I wrote a set of ca65 macros that generates an NES 2.0 header.

_________________
Pin Eight | Twitter | GitHub | Patreon


Top
 Profile  
 
PostPosted: Sun Feb 24, 2019 10:31 am 
Offline
User avatar

Joined: Tue Feb 19, 2019 11:54 pm
Posts: 23
Location: Planet Earth, Milky Way
tepples wrote:


It took me forever but found a header

Code:
HEADER:
.use Global,*
.use Ppu
.use Vblank
.use Game

.segment "HEADER"

.byte "NES"
.byte $1a
.byte $02       ; 4 - 2*16k PRG ROM
.byte $01       ; 5 - 8k CHR ROM
.byte %00000001   ; 6 - mapper
.byte $00       ; 7
.byte $00       ; 8 -
.byte $00       ; 9 - NTSC
.byte $00
; Filler
.byte $00,$00,$00,$00,$00



I don't know if it's similar in anyway but does this work?


Top
 Profile  
 
PostPosted: Sun Feb 24, 2019 11:24 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2574
Location: DIGDUG
Do you want mapper #1? I would have assumed #0.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Sun Feb 24, 2019 5:32 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 21634
Location: NE Indiana, USA (NTSC)
Byte 6 = $01 means mapper low nibble 0 and vertical mirroring. Combined with byte 7, which specifies a mapper high nibble also 0, the mapper is 0 (NROM).

_________________
Pin Eight | Twitter | GitHub | Patreon


Top
 Profile  
 
PostPosted: Mon Feb 25, 2019 8:42 am 
Offline
User avatar

Joined: Tue Feb 19, 2019 11:54 pm
Posts: 23
Location: Planet Earth, Milky Way
tepples wrote:
Byte 6 = $01 means mapper low nibble 0 and vertical mirroring. Combined with byte 7, which specifies a mapper high nibble also 0, the mapper is 0 (NROM).


I believe this is better?

Code:
; iNES identifier
.byte "NES"
.byte $1a
; Number of PRG-ROM blocks
.byte $01
; Number of CHR-ROM blocks
.byte $01
; ROM control bytes: Horizontal mirroring, no SRAM
; or trainer, Mapper #0
.byte $00, $00
; Filler
.byte $00,$00,$00,$00,$00,$00,$00,$00


Top
 Profile  
 
PostPosted: Mon Feb 25, 2019 10:12 am 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 1206
Location: Hokkaido, Japan
Yes now it looks like a header for NROM.

This wiki page explains the basics about programming NROM. The eighth byte in the header example is 8 instead of 0 like yours, but that only means it is using a NES 2.0 header instead of an iNES header like you use. Either is fine in most cases.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 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