Update to my tutorial in C
Moderator: Moderators
Update to my tutorial in C
I haven't changed my website yet, but it should be very soon.
I did manage to finish the example code this past weekend, and posted everything on github.
https://github.com/nesdoug?tab=repositories
Feel free to comment, if you have any issues / see any problems. Thanks.
Here's the support libraries I wrote "nesdoug.s" and "nesdoug.h"
https://github.com/nesdoug/01_Hello/tree/master/LIB
I did manage to finish the example code this past weekend, and posted everything on github.
https://github.com/nesdoug?tab=repositories
Feel free to comment, if you have any issues / see any problems. Thanks.
Here's the support libraries I wrote "nesdoug.s" and "nesdoug.h"
https://github.com/nesdoug/01_Hello/tree/master/LIB
nesdoug.com -- blog/tutorial on programming for the NES
Re: Update to my tutorial in C
Good to see an update!
I'm looking at the lib code to see if there is any method that could be used in C that I don't have yet One thing I would like to know is that neslib has a history for update. Is the history from Shiru or from your own fix? Since I use some of the methods inside, if there was some important fix I will be more than happy to update the affected method.
I will check the example once I have some time.
I'm looking at the lib code to see if there is any method that could be used in C that I don't have yet One thing I would like to know is that neslib has a history for update. Is the history from Shiru or from your own fix? Since I use some of the methods inside, if there was some important fix I will be more than happy to update the affected method.
I will check the example once I have some time.
Re: Update to my tutorial in C
Changes I made to neslib.h...
added the word "const" on many of the prototypes, to quiet some warnings.
split() now takes 1 argument (X) instead of 2.
in neslib.s
added ldx #0 to end of rand8, per calima's suggestion.
added "export _flush_vram_update_nmi" so I could use the flush function without needing to pass a pointer.
split adjusted to take 1 argument.
The version history, I don't know who added the last items, maybe "veg" whoever that is.
added the word "const" on many of the prototypes, to quiet some warnings.
split() now takes 1 argument (X) instead of 2.
in neslib.s
added ldx #0 to end of rand8, per calima's suggestion.
added "export _flush_vram_update_nmi" so I could use the flush function without needing to pass a pointer.
split adjusted to take 1 argument.
The version history, I don't know who added the last items, maybe "veg" whoever that is.
nesdoug.com -- blog/tutorial on programming for the NES
Re: Update to my tutorial in C
I see.
Since I'm using rand8 sparsely, could you kindly explain why the need to set x to #0? For now I do not see the impact of not setting it for an 8 bit value returned in A. Where does the value of X affect rand8? Maybe it's something related with cc65 internal on return value that I'm not very familiar yet.
Since I'm using rand8 sparsely, could you kindly explain why the need to set x to #0? For now I do not see the impact of not setting it for an 8 bit value returned in A. Where does the value of X affect rand8? Maybe it's something related with cc65 internal on return value that I'm not very familiar yet.
- rainwarrior
- Posts: 8734
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Update to my tutorial in C
Any assembly function that is called as a C function must return a 16 bit value in A/X, even if the function is defined as returning unsigned char. This is just a limitation of the compiler, it assumes that any 8-bit return value is automatically promoted to a 16-bit int, and relies on the assembly function to do this. (Otherwise a leftover value in X has the potential to generate incorrect results.)
http://cc65.github.io/doc/cc65-intern.html#ss1.3
http://cc65.github.io/doc/cc65-intern.html#ss1.3
Re: Update to my tutorial in C
Oh, I think I read something about that but since I usually do not return value I didn't put much attention and completely forgot about it. That was when I started to learn the innards of cc65 to know how to use methods.
I will review my code just in case I have some issues. I know that the metatitle attribute code return an 8 bit value and I didn't set the X. Good think I asked about that, I have now found another source of possible bugs!
Thanks!
I will review my code just in case I have some issues. I know that the metatitle attribute code return an 8 bit value and I didn't set the X. Good think I asked about that, I have now found another source of possible bugs!
Thanks!
- battagline
- Posts: 152
- Joined: Wed Sep 05, 2018 11:13 am
- Location: Colorado
- Contact:
Re: Update to my tutorial in C
Great tutorial Doug,
I'm new to NES Dev. I had been using NESASM3, but had been running into problems organizing my code with it. You have me really excited about using C and ca65/cc65
Thanks for the tutorials,
Rick
I'm new to NES Dev. I had been using NESASM3, but had been running into problems organizing my code with it. You have me really excited about using C and ca65/cc65
Thanks for the tutorials,
Rick
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
Re: Update to my tutorial in C
Well, on that note, I deleted the old tutorial, and am rewriting it (I have rough drafts done).
Give me a week or 2 to get it back in shape.
Give me a week or 2 to get it back in shape.
nesdoug.com -- blog/tutorial on programming for the NES
Re: Update to my tutorial in C
Thanks for your work.
About the split function, I have a rough version which somewhat works with the Y parameter. At least it fits my needs (vertical scrolling with top status bar using vertical mirroring). I'm sure it could be done better (it's a bit shaky), but my kung fu is not strong enough.
About the split function, I have a rough version which somewhat works with the Y parameter. At least it fits my needs (vertical scrolling with top status bar using vertical mirroring). I'm sure it could be done better (it's a bit shaky), but my kung fu is not strong enough.
Code: Select all
;;void __fastcall__ split(unsigned int x,unsigned int y);
_split:
; Extract SCROLL_Y1, SCROLL_X1, WRITE1 from parameters.
sta <TEMP
txa
bne @1
lda <TEMP
cmp #240
bcs @1
sta <SCROLL_Y1
lda #0
sta <TEMP
beq @2 ;bra
@1:
sec
lda <TEMP
sbc #240
sta <SCROLL_Y1
lda #8 ;; Bit 3
sta <TEMP
@2:
jsr popax
sta <SCROLL_X1
txa
and #$01
asl a
asl a ;; Bit 2
ora <TEMP ;; From Y
sta <WRITE1 ;; Store!
; Calculate WRITE2 = ((Y & $F8) << 2) | (X >> 3)
lda <SCROLL_Y1
and #$F8
asl a
asl a
sta <TEMP ;; TEMP = (Y & $F8) << 2
lda <SCROLL_X1
lsr a
lsr a
lsr a ;; A = (X >> 3)
ora <TEMP ;; A = (X >> 3) | ((Y & $F8) << 2)
sta <WRITE2 ;; Store!
; Wait for sprite 0 hit
@3:
bit PPU_STATUS
bvs @3
@4:
bit PPU_STATUS
bvc @4
; Set scroll value
lda PPU_STATUS
lda <WRITE1
sta PPU_ADDR
lda <SCROLL_Y1
sta PPU_SCROLL
lda <SCROLL_X1
ldx <WRITE2
sta PPU_SCROLL
stx PPU_ADDR
rts
- Attachments
-
- poc.zip
- (63.66 KiB) Downloaded 494 times
Re: Update to my tutorial in C
look at my function _xy_split in nesdoug.s
It's similar.
It's similar.
nesdoug.com -- blog/tutorial on programming for the NES
Re: Update to my tutorial in C
I had issues with return value with X not set to 0 for pad too so this thread helped for that. thanks!
I don't want to sound rude but if it does I apologize in advance. I just want to know the motive behind such approach for labels in the above example. Maybe it should be a subject for another thread but this always scratch an itch everytime I see it.
It always puzzle me when peoples uses either anonymous label or numbered one inside logic. From my point of view, even though the code is simple, it just obfuscate it for the next user that will read it. It may be obvious the day you wrote it but it won't in the years later.
For example, instead of using : and just jmp with :-, usually I will write something based on the context. So if I'm processing metatile, I may write
I could have just wrote @1 or : but you have no idea how much it helped me re-read my code I did a long time ago. I think named label are useful, however verbose they are.
Again, I apologize if it sounded rude.
I don't want to sound rude but if it does I apologize in advance. I just want to know the motive behind such approach for labels in the above example. Maybe it should be a subject for another thread but this always scratch an itch everytime I see it.
It always puzzle me when peoples uses either anonymous label or numbered one inside logic. From my point of view, even though the code is simple, it just obfuscate it for the next user that will read it. It may be obvious the day you wrote it but it won't in the years later.
For example, instead of using : and just jmp with :-, usually I will write something based on the context. So if I'm processing metatile, I may write
Code: Select all
whileMetatileLeft:
xxxx ; code that process metatile here
...
inx
bne whileMetatileLeft
Again, I apologize if it sounded rude.
Re: Update to my tutorial in C
Hmm, I forgot to fix pad_poll() and others. Will maybe have to add some more ldx #0I had issues with return value with X not set to 0 for pad too
nesdoug.com -- blog/tutorial on programming for the NES
Re: Update to my tutorial in C
No, what you are saying makes complete sense.Banshaku wrote:I had issues with return value with X not set to 0 for pad too so this thread helped for that. thanks!
I don't want to sound rude but if it does I apologize in advance. I just want to know the motive behind such approach for labels in the above example. Maybe it should be a subject for another thread but this always scratch an itch everytime I see it.
It always puzzle me when peoples uses either anonymous label or numbered one inside logic. From my point of view, even though the code is simple, it just obfuscate it for the next user that will read it. It may be obvious the day you wrote it but it won't in the years later.
For example, instead of using : and just jmp with :-, usually I will write something based on the context. So if I'm processing metatile, I may write
I could have just wrote @1 or : but you have no idea how much it helped me re-read my code I did a long time ago. I think named label are useful, however verbose they are.Code: Select all
whileMetatileLeft: xxxx ; code that process metatile here ... inx bne whileMetatileLeft
Again, I apologize if it sounded rude.
I was just completing an already existing function so I guess I adhered to the existing code style. The annonymous labels - I think they are used so you can cut and paste a routine to another project without having to care about identifier collisions. Other than that, I don't find any advantages. I'm not an assembly coder, tho'
Re: Update to my tutorial in C
One way to avoid collision in cc65 is to create scopes like .proc for procedures or even define local scopes to wraps things. For example, let say you have a function with some label like this:
processData is scoped to subMyFunction and will not clash if you define it again in another procedure. You can even call that part is you require just to "process the data" from another procedure without the beginning code with:
and now you just jumped there. Another case, those zpTemp variable that means nothing when seen but you need to use them anyway? Scope them!
and now you zpTemp has more meaning as the "local counter". Easier to read the code. This is just vary basic stuff. There is more advanced scope that makes you code quite "interesting" but now I try to avoid that
Sorry to have hijacked the thread m(_ _)m
Code: Select all
.proc subMyFunction
; init code here
processData:
; xxx
bne processData
rts
.endproc
Code: Select all
jmp subMyFunction::processData
Code: Select all
; void __fastcall __ function2(unsigned char counter)
;
; process data. receive value in A
;
.proc subFunction2
; ------- local scope begin -------
.scope local
counter = zpTemp ; counter points on zpTemp
.endscope
; ------- local scope end -------
; save parameter for later use
sta local::counter
....
loop:
; do stuff on it
lda #$23
cmp local::counter
bne loop
rts
.endproc
Sorry to have hijacked the thread m(_ _)m
Re: Update to my tutorial in C
Ok, the new tutorial is up an 99% finished.
And all the code is on github.
https://github.com/nesdoug
And all the code is on github.
https://github.com/nesdoug
nesdoug.com -- blog/tutorial on programming for the NES