It is currently Mon Nov 12, 2018 8:17 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: Thu Apr 13, 2006 11:27 am 
Offline

Joined: Mon Nov 01, 2004 7:33 am
Posts: 29
Greets, I want to write some small sine-scrolling demo, for which I calculated the sine-values with a small c++ program (the values look strange to me...) and pasted them into a value in bank 0. First, the values were to many to fit in one .db so I used three lines of .db to store the values in. When increasing the offset for the indirect addressing this shouldn't matter when the three .db are one behind the other. Now there is some code to load bckgrnd data, initialise ppu and so on. While VBlank I use a timer to slow the program down a bit, then I load the new scrolling value with
Code:
   ldy counter
   lda [sintable],y   ;while y increasing every drawn frame
   sta temp

Then there is only
Code:
   lda temp
   sta $2005
   lda #0
   sta $2005
;turn screen on
   lda #%00001000
   sta $2000
   lda #%10011110
   sta $2001

   jmp waitblank

remaining. When assembling and loading the programm, it seems that scrolling only switches between 10 and something around 255, but does not use the values in the sintable. When loading a constant value or the temp-value for the timer in $2005 it works. The problem seems to be my indirect addressing. Can somebody please tell me what's wrong?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 13, 2006 11:42 am 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1849
It sounds like you want Absolute,X/Y mode, not Indirect,Y. If 'sintable' is a label to the start of the table itself, you'll just want to load sintable+Y ... not (sintable)+Y.

Indirect,Y mode would be used if you have a pointer to the start of the table... rather than accessing the table directly.

so this is probably what you meant to go with:
Code:
  ldy counter
  lda sintable,Y
  sta tmp


Or rather... ldx / Absolute,X would be a more 'typical' approach.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 13, 2006 12:21 pm 
Offline

Joined: Mon Nov 01, 2004 7:33 am
Posts: 29
Tried it, no changes.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 13, 2006 12:38 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1849
Well then I'm afraid I can't help you without seeing more of the source.

Could you upload it to a page and link it here or something?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 13, 2006 12:46 pm 
Offline

Joined: Mon Nov 01, 2004 7:33 am
Posts: 29
Thanks, that's very kind that you'll be looking at the whole code, thought first it would be too big to post here (didn't want to spam)
Code:
   .inesprg 1   ; one (1) bank of program code
   .ineschr 1   ; one (1) bank of picture data
   .inesmap 0   ; we use mapper 0
   .inesmir 1   ; Mirror setting always 1.

   .bank 1   ; following goes in bank 1
   .org $FFFA  ; start at $FFFA
   .dw 0    ; dw stands for Define Word and we give 0 as address for NMI routine
   .dw Start ; give address of start of our code for execution on reset of NES.
   .dw 0   ; give 0 for address of VBlank interrupt handler, we tell PPU not to
   ; make an interrupt for VBlank.

   .bank 0   ; bank 0 - our place for code.
   .org $0000
addrLO   .db 0
addrHI   .db 0

counter   .db 0
temp   .db 0
timer   .db 0

sintable   .db 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 56, 60, 64, 68, 73, 77, 81, 86, 90
;sintable2   .db 94, 98;, 103, 107, 111, 115, 120, 124, 128, 133, 137, 141, 145, 150, 154, 158,
sintable3   .db 162, 167, 171, 175, 180, 184, 188, 192, 197, 201, 205, 210, 214, 218, 222; as said these values look wrong to me
;227, 231, 235, 239, 244, 248, 252, 256
   .org $0200


   .org $8000  ; code starts at $8000
   
Start: 
   lda #%00001000  ; do the setup of PPU
   sta $2000       ; that we
   lda #%10011110  ; talked about
   sta $2001       ; on a previous day

   ldx #$00    ; clear X

   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.


;Background/Titelbild laden
   ldx #0
   lda #$20  ; set the destination address in PPU memory
     sta $2006  ; should be $2000
     stx $2006
     lda #low(nametable1)   ; put the high and low bytes of the address "backg"
     sta addrLO        ; into the variables so we can use indirect addressing.
     lda #high(nametable1)
     sta addrHI

   ldx #4  ; number of 256-byte chunks to load
     ldy #0
loopTable1:
     lda [addrLO],y
     sta $2007     ; load 256 bytes
     iny
     bne loopTable1
;--------------------
     inc addrHI  ; increment high byte of address backg to next 256 byte chunk
     dex        ; one chunk done so X = X - 1.
     bne loopTable1   ; if X isn't zero, do again


   ldx #0
   lda #$24  ; set the destination address in PPU memory
     sta $2006  ; should be $2000
     stx $2006
     lda #low(nametable2)   ; put the high and low bytes of the address "backg"
     sta addrLO        ; into the variables so we can use indirect addressing.
     lda #high(nametable2)
     sta addrHI

   ldx #4  ; number of 256-byte chunks to load
     ldy #0
loopTable2:
     lda [addrLO],y
     sta $2007     ; load 256 bytes
     iny
     bne loopTable2
;--------------------
     inc addrHI  ; increment high byte of address backg to next 256 byte chunk
     dex        ; one chunk done so X = X - 1.
     bne loopTable2  ; if X isn't zero, do again



   lda #0
   sta counter
   sta timer

waitblank:         ; this is the wait for VBlank code from above
   lda $2002  ; load A with value at location $2002
   bpl waitblank  ; if bit 7 is not set (not VBlank) keep checking

   lda #$00   ; these lines tell $2003
   sta $2003  ; to tell
   lda #$00   ; $2004 to start
   sta $2003  ; at $0000.

;Screen abschalten
   lda #$00
   sta $2001

   lda #%00001000
   sta $2000
   lda #%10011110
   sta $2001



   lda timer
   cmp #20
   beq resettimer
   inc timer
   jmp dontresettimer
resettimer:
   lda #0
   sta timer
   jmp screenon
dontresettimer
   lda counter
   cmp #15
   beq resetcounter
   ldy counter
   lda sintable,y
   sta temp
   inc counter

   jmp screenon
resetcounter:
   lda #0
   sta counter
   sta temp

screenon:
   lda temp
   sta $2005
   lda #0
   sta $2005
;Screen anschalten
   lda #%00001000
   sta $2000
   lda #%10011110
   sta $2001

   jmp waitblank

tilepal: .incbin "scroll.pal"
nametable1: .incbin "scroll.nam"
nametable2: .incbin "scroll2.nam"

   .bank 2   ; switch to bank 2
   .org $0000  ; start at $0000
   .incbin "scroll.bkg"
   .incbin "scroll.spr"


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 13, 2006 1:53 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1849
L0p1n wrote:
thought first it would be too big to post here


Well... I didn't really want you to paste the thing here -- that's why I said maybe upload it to a page or something and just post a link. =P Guess I should've been more specific... but oh well. It's not TOO huge.

Anyway... the problem that stands out right away is that you're trying to .db in RAM ($0000-07FF) which doesn't work. Your assembled file will only contain ROM (that's why they're called "ROMs"). So anything you put in RAM via a .db line will not be visible to any emulator (or to the actual system).

Put that sine table in ROM. You wouldn't want something like that in RAM anyway.


And yes... your sine table doesn't look anything like a sine wave to me either. (Not to mention chunks of it are commented out... is that intentional?)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 14, 2006 9:20 am 
Offline

Joined: Mon Nov 01, 2004 7:33 am
Posts: 29
thx, I already thought it was that rom/ram difference. But why doesn't nesasm warn me while assembling when I write values to ram when they won't be in the rom image?
The sinwave is really wrong, but i don't know how to calculate the values I need. I've just written a small c++ prog with a for-loop which uses sin(); values of the variable used in the loop, which I then multiply by 100 and divide by 360 (or *360/100, forgot it). Don't have the program anymore but I think the loop went from 1 to 60 or something around that and the values in the sintable .db are those my program printed then. Can you help me with the calculation of the sine-values?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 14, 2006 9:39 am 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1849
L0p1N wrote:
But why doesn't nesasm warn me while assembling when I write values to ram when they won't be in the rom image?


Beats me. The typical 6502 assembler wouldn't know the difference (since any address could be RAM/ROM depending on the system)... but since nesasm specifically targets the NES you'd think it would know. Oh well.

Just remember:

$0000-07FF = RAM (space for your variables)
$8000-FFFF = ROM (space for everything else)



Quote:
The sinwave is really wrong, but i don't know how to calculate the values I need. I've just written a small c++ prog with a for-loop which uses sin(); values of the variable used in the loop, which I then multiply by 100 and divide by 360 (or *360/100, forgot it).


Assuming you want values from 1-255 (where sin(0) = 128), something like the following will work (note: haven't tested this, but it'd probably work):

Code:
int i;
for(i = 0; i < table_size; i++)
{
  sine_table[i] = (BYTE)(  sin(2 * PI * i / table_size) * 127 ) + 128;
}


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 14, 2006 9:55 am 
Offline

Joined: Mon Nov 01, 2004 7:33 am
Posts: 29
Compiled the code (using Borland C++ Builder 5). I got some errors: It doesn't know "PI" (it's called "M_PI" in Borland), fixed it. The second error was that the compiler didn't know "(BYTE)", which seems to me like a typecast from float to byte. Never did a typecast to byte (only from c-string to ansi-string for windows programming), wondering why it won't work. Deleting the "(BYTE)"-Part from the code it compiles and shows values which seem correct to me. But is there a reason the wave starts with 128? I want a horizontal sine-wave-scroll from 0 to 255. Just leave the "+128" away?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 14, 2006 10:12 am 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3578
Location: Indianapolis
For generating sine tables, this program is great:
http://nesdev.com/rollcost.zip


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 14, 2006 11:17 am 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1849
L0p1N wrote:
Compiled the code (using Borland C++ Builder 5). I got some errors: It doesn't know "PI" (it's called "M_PI" in Borland), fixed it.


I didn't know about M_PI, actually. I usually just #define my own PI.

Quote:
The second error was that the compiler didn't know "(BYTE)", which seems to me like a typecast from float to byte. Never did a typecast to byte (only from c-string to ansi-string for windows programming), wondering why it won't work.


again I ususally typedef my own var types for fixed var sizes. Although I suppose you could typecast it as (unsigned char) instead.

I make it a habit to typecast when converting var types. Especially when going floating-point->integer like in the above code

Quote:
But is there a reason the wave starts with 128? I want a horizontal sine-wave-scroll from 0 to 255. Just leave the "+128" away?


sine starts at the "center line" -- which in this case would be 128. If you want to start at a different point in the wave, you'll have to offset the position:

Code:
  sine_table[i] = (BYTE)(  sin(2 * PI * i / table_size + (3* PI / 2)) * 127 ) + 128;


see added (3*PI/2). This will start it 3/4ths of the way through the sine wave (which will put it at -1).

That should start the table with a value of $01 (the minimum you'll get since the range is 01-FF... if you want the range 00-FE then add 127 at the end instead of 128... making the range 00-FF would be a bit more extra work I don't care to think about right now)

Whatever you do, do NOT just remove the +128 at the end, as that will "break" the table in half.


Or go with Membler's suggestion and take the easy way out, heh ;D.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC - 7 hours


Who is online

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