Nukey Shay Posted February 13, 2019 Share Posted February 13, 2019 (edited) With a more complicated banking scheme, you don't need to alter the pointers. Just switch banks. That's also the easiest way to animate. Edited February 13, 2019 by Nukey Shay Quote Link to comment Share on other sites More sharing options...
Lillapojkenpåön Posted February 22, 2019 Author Share Posted February 22, 2019 (edited) Once you reach the end of the table, if you are reading from a pointer, you could incremens the high bit of the pointer to be able to read from the next page of data. Pointers is the last thing I need to learn, and I'm really having trouble with it! Is this how it works?.. you point one byte to the beginning of the data and another byte to the end (256 bytes further down) and put them together to a 16 bit variable (called table in this example) and then CLC LDA #<table ADC #1 ; if result is > 255 then carry gets set (and the pointer ends up on the next page) STA ; to what?? LDA #>table ADC #0 ; if carry is set, then the high byte somehow ends up 256 bytes further down the table so the pointers are on the same page?? AND #$0F ; doesn't this turn off the last four bits? why??? STA ; to what?? do I store the result to another 16 bit variable? so I need to use four bytes to do this? or can #<table and #>table just be constant values of where the table is? and I'm suppose to store that to my 16 bit variable which I then use as the pointer? how do I use a 16 bit pointer??? Please someone help me get this. With a more complicated banking scheme, you don't need to alter the pointers. Just switch banks. That's also the easiest way to animate. That doesn't sound easy at all!!!! Edited February 22, 2019 by Lillapojkenpåön Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted February 23, 2019 Share Posted February 23, 2019 Machine Language For Beginners Chapter 4: Addressing, Indirect Y, page 49 Chapter 5: Arithmetic, Adding Numbers Larger Than 255, page 57 2 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted February 23, 2019 Share Posted February 23, 2019 Pointers are easier than you think they are. Memory addresses are 16-bit, and a pointer is two consecutive bytes that hold a memory address. The pointer may be used to access the data at the address stored in the pointer. An advantage of using a pointer vs using the address directly is that the address pointed to can be changed, and the same pointer can still be used to access the data. So, here's an example for data for player graphics: Player0GfxPtr ds 2 ; two bytes player0frame0 .byte %0001000 .byte %0001000 .byte %0111110 .byte %0001000 .byte %0001000 player0frame1 .byte %0100010 .byte %0010100 .byte %0001000 .byte %0010100 .byte %0100010 lda #<player0frame0 ; low byte of player0frame0 sta Player0GfxPtr ; store in first byte of pointer lda #>player0frame0 ; high byte of player0frame0 sta Player0GfxPtr+1 ; store in second byte of pointer ldy #4 playergfxloop sta WSYNC lda (Player0GfxPtr),y ; load from address stored in pointer (player0frame0) with offset sta GRP0 dey bpl playergfxloop lda #<player0frame1 ; low byte of player0frame1 sta Player0GfxPtr ; store in first byte of pointer lda #>player0frame1 ; high byte of player0frame0 sta Player0GfxPtr+1 ; store in second byte of pointer playergfxloop2 sta WSYNC lda (Player0GfxPtr),y ; load from address stored in pointer (player0frame1) with offset sta GRP0 dey bpl playergfxloop2 In this case, you would read data from Player0GfxPtr, and if you wanted to switch frames of animation, you would update the pointer to point to the table with the appropriate graphics. 1 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted February 23, 2019 Share Posted February 23, 2019 Now in the case of a table with more than 256 bytes of data, you could set the pointer to the address of the table as normal: lda #<reallybigtable ; low byte of reallybigtable sta DataPtr ; store in first byte of pointer lda #>reallybigtable ; high byte of reallybigtable sta DataPtr+1 ; store in second byte of pointer You can access the first 256 bytes in the table with (DataPtr),y If you needed to access the next 256 bytes, you could add 1 to the high byte of DataPtr, and then read from it in the same way. inc DataPtr+1 ; Increment high byte of DataPtr ldy #0 lda (DataPtr),y ; load byte 256 bytes from start of table I hope that makes a little more sense. Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted February 23, 2019 Share Posted February 23, 2019 That doesn't sound easy at all!!!! Actually, it is. In order to animate -everything- in a game, you really only need to know which Ram location holds the frame counter and 9 bytes of Rom space. Take a game like Venture. Pretty boring gfx, right? lda $DD ; the frame counter in Venture and #$07 ; only keep the 3 low bits bne NoSwitch ; do not branch every 8th frame only sta $FFF8 ; F8 bankswitch hotspot NoSwitch Insert this code at some point in the program which is executed on every frame...such as to lead in to the display kernel where the INTIM timer is checked. Then turn the game into an 8k F8 version by doubling it (2 copies of the Rom pasted back-to-back). Use a bithacker to alter the sta $FFF8 instruction in the first copy to be $FFF9 instead (the other F8 hotspot). Now you can alter anything in the Rom to look different in each of the 2 banks. Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted February 23, 2019 Share Posted February 23, 2019 (edited) F6 version (16k, 4 frames of animation) lda $DD and #$06 lsr tax sta $FFF6,x Edited February 23, 2019 by Nukey Shay Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted February 23, 2019 Share Posted February 23, 2019 Pointers is the last thing I need to learn, and I'm really having trouble with it! reply #20 might help. Quote Link to comment Share on other sites More sharing options...
Lillapojkenpåön Posted February 24, 2019 Author Share Posted February 24, 2019 Thanks alot everybody!!! I get it now finally!! Now in the case of a table with more than 256 bytes of data, you could set the pointer to the address of the table as normal: lda #<reallybigtable ; low byte of reallybigtable sta DataPtr ; store in first byte of pointer lda #>reallybigtable ; high byte of reallybigtable sta DataPtr+1 ; store in second byte of pointer You can access the first 256 bytes in the table with (DataPtr),y If you needed to access the next 256 bytes, you could add 1 to the high byte of DataPtr, and then read from it in the same way. inc DataPtr+1 ; Increment high byte of DataPtr ldy #0 lda (DataPtr),y ; load byte 256 bytes from start of table I hope that makes a little more sense. I'm having a little bit of trouble figuring out when to inc and dec the high byte when reading two bytes at a time from the table?? I've tried everything but when scrolling quickly back and forth over the 256 edge the playfield gets a little messed up sometimes. I tried to dec the high byte when index was zero and set the index to 254, and inc at 254 and set index to zero, that didn't work, I guess going back and forth can result in the index being 255? Tried a thousand ways to solve that without success. so I tried incrementing the pointer between the two table reads so the first byte could be 255 and second byte 0 of the next 256 bytes, but didn't get that working correctly either.. .scrollleft ldy Index lda (DataPtr),y sta temp2 iny lda (DataPtr),y sta temp3 inc Index rts .scrollright ldy Index lda (DataPtr),y sta temp2 iny lda (DataPtr),y sta temp3 dec Index rts Any tips on where to put the index check, what to check for, and what to set it to? Quote Link to comment Share on other sites More sharing options...
Lillapojkenpåön Posted May 23, 2019 Author Share Posted May 23, 2019 Can you do an equivalent to this table in ram and still only use eleven consecutive bytes? .byte $86,0,0,0 .byte $88,0,0,0 .byte $86,0,0,0 .byte $88,0,0,0 .byte $86,0,0,0 .byte $88,0,0,0 .byte $86,0,0,0 .byte $88,0,0,0 .byte $86,0,0,0 .byte $88,0,0,0 .byte $86,0,0,0 Quote Link to comment Share on other sites More sharing options...
Lillapojkenpåön Posted July 15, 2019 Author Share Posted July 15, 2019 Hmm how do I ask this.. Let's say you could shoot enemies all over the screen, and that when an enemy is shot something travels from it's location down to the score, but I want it to allways take one second to travel there even if it's far away or close to the score, you would have to calculate a 8.8 speed that makes the thing reach it's destination within said time, possible? anybody know of some similar code? Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted July 22, 2019 Share Posted July 22, 2019 you're asking for a divide by 60 for a NTSC or PAL60 game. 6507 doesn't have a divide feature, but it does have a shift feature which is the same as divide by 2. If you do that 6 times that's a divide by 64, which is close enough. So I would start with something like this: ;RAM usage stephigh ds 1 steplow ds 1 ; call with Y holding the distance to move to get to the score DivBy64: sty stephigh ldy #0 sty steplow ldy #6 Div64Loop: lsr stephigh ror steplow dey bne Div64Loop 1 Quote Link to comment Share on other sites More sharing options...
bogax Posted July 23, 2019 Share Posted July 23, 2019 how about sta lo lda #0 sta hi asl lo rol hi asl lo rol hi 1 Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted July 23, 2019 Share Posted July 23, 2019 Yep - since this is a newbies forum it's helpful to start with the straightforward answer, then follow up with the optimization. ;RAM usage stephigh ds 1 steplow ds 1 ; call with Y holding the distance to move to get to the score ; (# / 256) * 2 * 2 = # / 64 DivBy64: sty steplow ; these 3 instructions are a divide by 256 ldy #0 sty stephigh asl steplow ; these 2 instructions are times 2 rol stephigh asl steplow ; these 2 instructions are times 2 rol stephigh 1 Quote Link to comment Share on other sites More sharing options...
Lillapojkenpåön Posted November 4, 2019 Author Share Posted November 4, 2019 I forgot to say THANKS! that worked great! I'm working on a bB kernel, but the code (level data, logic etc.) in bB needs to end up in different places in the kernel, are there any preprcessor commands that can change where code ends up? or a way to split up the generated assembly from bB to different parts? The DPCplus include file has this bB.asm ; DPC frequencies DPC_waveforms.asm ; rest of bB stuff, ending with graphics bB2.asm but I can't find how it's split into two parts? Quote Link to comment Share on other sites More sharing options...
Lillapojkenpåön Posted May 19, 2020 Author Share Posted May 19, 2020 I have a problem that's driving me nuts, I have a table that looks like this 255,255,63,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,34,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,34,0,4,32,0,4,32,0 4,32,0,4,32,0,4,32,0,4,32,0,4,33,0,4,33,0,4,33,0,4,33,0,4,32,0,4,32,0,4,32,0,4,32,0,4,48,0,4,56,0,4,60,0,4,60,0,4,0,0,4,0,0,0,0,0,128,0,0,128,0,0,128 0,0,128,0,0,0,0,0,0,60,0,0,60,0,16,60,0,16,60,0,16,32,0,16,32,0,0,32,0,4,32,0,4,32,16,132,32,16,132,32,16,132,32,16,132,0,16,132,0,16,132,0,16,132,32,16,132,32,0,4,32,0,4,32 0,4,32,0,4,32,0,4,32,0,4,32,0,4,33,0,4,33,0,4,33,0,4,33,0,4,33,0,4,33,0,4,33,0,4,33,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32 0,0,0,0 0,4,32,0,0,32,0,0,32,128,1,56,128,1,56,128,1,56,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,32,4,32,32,4,32,32,4,32,32,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0 4,32,0,4,32,0,4,32,0,4,48,0,4,32,0,4,36,0,0,32,0,0,33,0,0,32,0,64,32,0,0,32,0,0,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4 32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32 0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,0,0,4,0,0,4,0,0,4,32,0,4,32 0,0,0,0 0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,0,32,0,0,32,0,0,32,0,0,0,0,0,0,0,1,0,0,1,32,0,1,32,0,1,32,0 1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,0,32,0,0,0,0,0,0,64,0,0,64,0,32,0,0,32,0,0,32,0,0,32,0,1,32,0,1,32,0,1 32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,0,32,0,0,32,0,0,32,0,0,32,0,0,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32 0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8 0,0,0,0 0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0 4,32,0,4,32,0,4,32,0,4,32,0,4,0,0,4,0,0,4,0,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,0 32,0,0,32,0,0,32,0,0,0,0,0,0,0,1,0,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,0,32,0,0,0 0,0,0,64,0,0,64,0,32,0,0,32,0,0,32,0,0,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32 0,0,0,0 0,0,32,0,0,32,0,0,32,0,0,32,0,0,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,8,0,4,8,0,4,8,0 4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4 32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32 0,4,32,0,4,0,0,4,0,0,4,0,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,0,32,0,0,32 0,0,0,0 0,0,32,0,0,0,0,0,0,0,1,0,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,0,32,0,0,0,0,0,0,64 0,0,64,0,32,0,0,32,0,0,32,0,0,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,1,32,0,0,32,0,0,32,0,0 32,0,0,32,0,0,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,32,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8 0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,0,4,8,255,255,15 0,0,0,0 It's playfield data, and the last four bytes on each page is just padding to keep it aligned, 63 values on each line plus four padding bytes = 256 I had to do it like that because I read three values at a time, so when the index is 251 I increment the page and set Index to 0 I can scroll perfectly to the left like that, but the problem is when scrolling back, the data is for the pixels to be turned on after scrolling the screen, so every three values is a playfield column, so ofcourse when scrolling the other way, I now need to read the data that's 99 (width 32 x height 3 + one column 3) positions before Index, pretty easy lda Index sbc #distance tay but when Index is less than 99 and the left column is on the previous page you need to also skip the padding bytes right? I tried it like this lda Index cmp #distance bcs .skip ; skip if Index is bigger or equal to distance dec Page ; decrement Page if Index is smaller than distance sec sbc #distance + 4 jmp .123 .skip sec sbc #distance .123 tay Anything wrong with that code? or else I'll post more of it The problem I'm seeing is that sometimes the playfield moves up, then back down again, so seems to have to do with the distance. Quote Link to comment Share on other sites More sharing options...
Lillapojkenpåön Posted May 19, 2020 Author Share Posted May 19, 2020 (edited) Would it help to upload a bin? EDIT: Solved it, I was forgetting to set Index to 251 when 0, when scrolling that way Edited May 19, 2020 by Lillapojkenpåön Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted May 19, 2020 Share Posted May 19, 2020 Useful tip: You can align to a page boundary in DASM by just using " align 256" in the source code. No need to add padding bytes manually. 1 Quote Link to comment Share on other sites More sharing options...
Lillapojkenpåön Posted May 19, 2020 Author Share Posted May 19, 2020 I can use it in the middle of a table? Quote Link to comment Share on other sites More sharing options...
Lillapojkenpåön Posted May 19, 2020 Author Share Posted May 19, 2020 (edited) Well no one knows it's a table except me now that I think about it ? cool tip ? Edited May 19, 2020 by Lillapojkenpåön Quote Link to comment Share on other sites More sharing options...
Lillapojkenpåön Posted May 20, 2020 Author Share Posted May 20, 2020 2 hours ago, Andrew Davie said: Useful tip: You can align to a page boundary in DASM by just using " align 256" in the source code. No need to add padding bytes manually. ldx #2 jmp .bs5 ;there's a couple free bytes between here align 133 bs5 lda bankswitch_hotspot-1,x rts If I remove the jmp to .bs5 will the program counter jump to .bs5 by itself or will it take time doing a couple nop's first? Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted May 20, 2020 Share Posted May 20, 2020 "align 133" is bizarre. Normally "align" is used to align to a 256 byte boundary. A 133 byte boundary is... weird. "align x" does not put in "x" bytes. Instead, it puts in as many bytes as needed to get to a multiple of "x" in the ROM. So, "align 256" will put in as many padding bytes as needed to finish the current page, and get to the start of the next one. In answer to your actual question - no, you cannot to this. The area skipped by the align should be considered "garbage" and you don't execute it as code. You will need to jump over it. 1 Quote Link to comment Share on other sites More sharing options...
Lillapojkenpåön Posted May 20, 2020 Author Share Posted May 20, 2020 Ok thanks. I'm a bizarre dude ? It's for a bB thing, and 133 bytes are allready used in bank 2 by the kernel, so that's where the bankswitch code ends up if you put it first thing in that bank, it just so happens the code I'm bankswitching to fits allmost perfectly above it in the other banks, ldx #2 jmp .bs5 is the end of that code where I return, I just realised I can put the align before that codeblock to just fall into the return. Quote Link to comment Share on other sites More sharing options...
Lillapojkenpåön Posted May 21, 2020 Author Share Posted May 21, 2020 On 5/20/2020 at 2:18 AM, Lillapojkenpåön said: ldx #2 jmp .bs5 ;there's a couple free bytes between here align 133 bs5 lda bankswitch_hotspot-1,x rts If I remove the jmp to .bs5 will the program counter jump to .bs5 by itself or will it take time doing a couple nop's first? Actually #<bs5 is 164, so why am I not aligning 164? I must have understood why when I did it, but now I don't??? Or I checked the wrong address and it was a lucky accident it worked? But why is it working? _bank6data ; #< = 133 lda (DataPtr),y sta DF0PUSH ;210 iny lda (DataPtr),y sta DF0PUSH ;209 if PFRESOLUTION == 22 iny lda (DataPtr),y sta DF0PUSH endif ;ldx #2 jmp .bs6 align 133 .bs6 ; #< = 164 lda $1FF7 rts Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted May 21, 2020 Share Posted May 21, 2020 2 hours ago, Lillapojkenpåön said: Actually #<bs5 is 164, so why am I not aligning 164? I must have understood why when I did it, but now I don't??? Or I checked the wrong address and it was a lucky accident it worked? But why is it working? _bank6data ; #< = 133 lda (DataPtr),y sta DF0PUSH ;210 iny lda (DataPtr),y sta DF0PUSH ;209 if PFRESOLUTION == 22 iny lda (DataPtr),y sta DF0PUSH endif ;ldx #2 jmp .bs6 align 133 .bs6 ; #< = 164 lda $1FF7 rts I totally don't understand your usage of "align" or what you're trying to do here. If it's to get bankswitching code in the right place, then I've not seen it done using aligns. It might work. Generate a listing file, and have a look at the assembly. That will clearly show you what is where. I have only ever used "align" to get to page boundaries. The "align 133" would, I assume, align to the 133rd byte in the current page, except where you're already past that, in which case it will be the 133rd byte in the NEXT page. It's still bizarre usage to me, tough. You code, as shown, does not seem to have much of any idea where it is related to page boundaries. Not saying it's wrong - it's just very foreign to me, this usage. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.