First program!

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
First program!
by on (#18044)
Hi!
I've been on this code piece over and over again and seems like I just can't get it to work, it should but it doesn't, I'm stuck! Was just wondering if there would be someone her who would take a look at it and see what I got wrong... I'd be happy to discuss it so If you want give me your email and I'll post the code and linking files to you, by doing so I won't have to post it here.
//Robert

by on (#18046)
My e-mail is always visible in my profile, though I think it would just be easier to use the [/code] tags here on the forum. It's better to have more than one person checking it out anyway for a couple of reasons. 1) One person may not see the mistake but another will... 2) Someone may learn something ;)

by on (#18070)
Hm... good point, anyway i'll send you the lot(with files and stuff) and post it here too;

Code:
;------------------------------------------------------------
;Important to say, I've not made all of this code by myself,
;some parts are copied from toturials and stuff...
;------------------------------------------------------------

;||-----Start-----||
   .inesprg 1
   .inesmap 0
   .inesmir 1
   .ineschr 1
   
   .bank 1
   .org $FFFA
   .dw 0
   .dw Start
   .dw 0
   
   .bank 0
   .org $0000
   
   .org $0300
Sprite1_Y:   .db 20      ; rear
Sprite1_T:   .db 1      ; part
Sprite1_S:   .db 0      ; of
Sprite1_X:   .db 20      ; car

Sprite2_Y:   .db 20      ; front
Sprite2_T:   .db 2      ; part
Sprite2_S:   .db 0      ; of
Sprite2_X:   .db 21      ; car

   .org $8000
Start:

   lda #%00001000  ;
   sta $2000       ;
   lda #%00011110  ; Our typical PPU Setup code.
   sta $2001       ;
   
   ldx #$00       ; clear X            ;; start of pallete loading code

   lda #$3F       ; have $2006 tell
   sta $2006      ; $2007 to start
   lda #$00       ; at $3F00 (pallete).
   sta $2006

loadpal:                ; this is a freaky loop
   lda tilepal, x  ; that gives 32 numbers
   sta $2007       ; to $2007, ending when
   inx             ; X is 32, meaning we
   cpx #32         ; are done.
   bne loadpal     ; if X isn't =32, goto "loadpal:" line.

infinite:
waitblank:
   lda #3
   sta $4014
   
   lda #$01      ; these
   sta $4016     ; lines
   lda #$00      ; setup/strobe the
   sta $4016     ; keypad.

;||-----joystick_1-----||

   lda $4016   ; A-button
   lda $4016   ; B-button
   lda $4016   ; Select-button
   lda $4016   ; Start-button
   lda $4016   ; Up-button
   and #1
   bne up_button
   lda $4016   ; Down-button
   and #1
   bne down_button
   lda $4016   ; Left-button
   and #1
   bne left_button
   lda $4016   ; Right-button
   and #1
   bne right_button
   jmp no_button

up_button:
   lda Sprite1_Y   ; move
   sbc #1      ; car
   sta Sprite1_Y   ; up
   lda Sprite2_Y   ; -
   sbc #1      ; -
   sta Sprite2_Y   ; -
   jmp no_button

down_button:
   lda Sprite1_Y   ; move
   adc #1      ; car
   sta Sprite1_Y   ; down
   lda Sprite2_Y   ; -
   adc #1      ; -
   sta Sprite2_Y   ; -
   jmp no_button

left_button:
   lda Sprite1_X   ; move
   sbc #1      ; car
   sta Sprite1_X   ; left
   lda Sprite2_X   ; -
   sbc #1      ; -
   sta Sprite2_X   ; -
   jmp no_button

right_button:
   lda Sprite2_X   ; move
   adc #1      ; car
   sta Sprite2_X   ; right
   lda Sprite1_X   ; -
   adc #1      ; -
   sta Sprite1_X   ; -

no_button
   jmp infinite

;||-----Joystick1-end-||

tilepal:
   .incbin "bil.pal"

   .bank 2
   .org $0000
   .incbin "bil.bkg"
   .incbin "bil.spr"

;||-----End-----||

by on (#18071)
deepak wrote:
Code:
   .org $0300
Sprite1_Y:   .db 20      ; rear
Sprite1_T:   .db 1      ; part
Sprite1_S:   .db 0      ; of
Sprite1_X:   .db 20      ; car

Sprite2_Y:   .db 20      ; front
Sprite2_T:   .db 2      ; part
Sprite2_S:   .db 0      ; of
Sprite2_X:   .db 21      ; car

Hum... for a start, you can't .db stuff in RAM. whatever you want to put in $0000-$07FF (RAM) must be copied from ROM (wich starts at $8000) with code, it can't just be defined there. You could define this just as you're doing it now, but somewhere in ROM. Then you can just read this data and copy to RAM at $0300.

There are a couple of other things wrong with the code:
1. you are not waiting for VBlanks anywhere in the code. It is important, for example, to wait at least 2 VBlanks before doing any PPU operations, because it takes it some time to be ready for use.
2. you are doing all PPU operations with rendering on (bits 3 and 4 of $2001). You can't do most PPU operations while it's rendering. So you should either wait for VBlank before sending stuff to the PPU (if you know your writes will not go beyond VBlank time) or disable rendering altogether (clear bits 3 and 4 of $2001) so that you have all the time in the world to do whatever you want, and when you're done, then you enable rendering.
3. it is good practice to start you code with SEI (to disable interrupts) and CLD (disable decimal arithmetics), just to be safe. It is also good practice to initialize the stack with $FF right in the beginning of the program.

I guess this is it for now. Once you add a background to this program, don't forget to set $2005 correctly befeore enabling rendering (and preferably every frame after that), so that your picture stays steady.

by on (#18075)
For the record, all of the faults mentioned are directly due to this demo being from the GbaGuy tutorials. It is highly recommended that you do not use them, as they are loaded with errors and don't actually run properly on an NES. There are other tutorials available (such as NES 101, which I highly recommend), though they tend to assume that you already know 6502 assembly fairly well.

by on (#18080)
You should use NMI for some stuff. Especially the sprite-DMA write (STA $4014). I know tokumaru already said so, I wanted to clarify that that's a PPU operation too.

Be sure to do that fairly early on in the NMI too. Lots of my programs didn't work because I was doing it too late (and the DMA takes 513 cpu cycles).

Quote:
For the record, all of the faults mentioned are directly due to this demo being from the GbaGuy tutorials. It is highly recommended that you do not use them, as they are loaded with errors and don't actually run properly on an NES.


I learned at first from the Mouser source code, which is as bad, if not worse. So I think there's some value in it, just gotta be aware of it's compatibility though as you say. Kinda shows what to do and how to not do it at the same time, heheh. :)