| www.retrosoftware.co.uk http://www.retrosoftware.co.uk/forum/ |
|
| Starting out in 6502 - code snippets and examples http://www.retrosoftware.co.uk/forum/viewtopic.php?f=73&t=99 |
Page 1 of 4 |
| Author: | rival [ Wed May 07, 2008 9:35 am ] |
| Post subject: | Starting out in 6502 - code snippets and examples |
Hi Everyone, I'm a decent programmer (C/C++/C#/Java) and a long time BBC devotee. I'd love to be able to join in here and do some 6502 coding, but I'm suffering from not having the right kind of resources. I've been through the programming docs on this site, and they don't seem to have the right focus. I'll freely admit that I don't 'get' assembler at the moment. I played with 6502 a little bit back in the day, and I can do really basic stuff (adding two numbers together, testing conditions, jumping to a different location) but I can't find a decent resource which will help me understand basic things I want to do on the BBC. I can't find a good reference to show me how to put a sprite on screen, or even how do draw a specific colour at a specfic point on screen. I can't see how to get the BBC to play a sound in 6502. I've got tons of screen scrolling routines, but nothing to tell me how to do sprite collision. Can we start to collect to examples of how to do these basic functions in 6502, and I'm sure there are many people like me who would like to take them either as building blocks or as a reference to do certain things in a game. Thanks |
|
| Author: | DaveF [ Wed May 07, 2008 10:06 am ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
Hello If you get C/C++ you'll be OK with 6502. Although you say you can do basic stuff like adding two numbers, testing conditions and so on, that's really all 6502 is! So at a very simple level you could do: Code: y register = 7 accumulator = pixel value do { Store accumulator to screen with an offset of the Y register Decrement y } while ( y>=0 ) Mode 2 is a reasonable place to start, it has the most colours, and is memory mapped to 0x3000. It also has 2 pixels per byte. Note these aren't stored in the upper and lower nibbles as perhaps you'd expect, but interleaved, so the left pixel is set by: 1010 1010 and the right pixel set by 0101 0101 So, to get 2 red pixels, your value would be: 1 OR 2 = 3. So: Code: ; Low byte of 0x3000 LDA #&00 STA &70 ; High byte of 0x3000 LDA #&30 STA &71 ; Loop counter and offset LDY #7 ; Pixel value LDA #3 .loop ; Do the store STA (&70),Y ; Decrement loop counter DEY ; If >= 0, loop BPL loop ;Return RTS Assemble this code to 0x900, pop into mode2, and CALL &900. You should see a small red blob in the top left! All a sprite routine is really is an extension of this sort of stuff. The real problem comes with the horrible memory layout of the BBC screen, you can see this explained in the advanced user guide on here somewhere. Let us know how you get on with that and we can take it from there! Dave |
|
| Author: | SteveO [ Wed May 07, 2008 1:56 pm ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
If you downlaod Swift it explains a little about how pixels are stored in a mode 2 screen in the attached documentation "Swift Sprite Data Formats". As Dave says The advanced user is essential to understand the screen layout though. |
|
| Author: | rival [ Thu May 08, 2008 9:43 am ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
Firstly, thanks Dave and Steve for helping me here. Dave, your comments are very helpful. It is beginning to make sense. Steve, I've tried to build this in Swift, but without success. When I try to build, I get the error 'Could not find assembler at C:\P65\p65.py' - I've triple checked, and this is the right location. I can execute p65.py from the command line however, so I know it works. I've built it successfully in BeebASM (with minor modification) and I get the red blob, just as you describe. It was slightly different than I imagined; the pixels were arranged vertically when I was expecting them to arrange horizontally, but this is my error. I've downloaded the New Advanced User Guide, and I'm beginning to trawl through that now. I guess that the next step is to define a sprite using EQUB and then get it to copy that data to screen memory. Thanks again. |
|
| Author: | DaveF [ Thu May 08, 2008 10:00 am ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
Glad to be of help. The pixels going down is due to the way the video memory works on the BBC (I told you it was a pain!) If you alter the code to do 9 iterations instead of 8 (ie change the LDY #7 to LDY #8), then you will see your vertical red line and another 2 pixels just to the right at the top. This is because the video memory is based around (8x8) characters, so it's very easy to have a small loop to plot (for example) a sprite representing a letter 'A'. So, to see an 8x8 red block, simply change the LDY #8 to LDY #31. This will give you a total of 64 pixels (remember there's 2 pixels per byte), in otherwords, 8x8! |
|
| Author: | SteveO [ Thu May 08, 2008 10:06 am ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
rival wrote: Steve, I've tried to build this in Swift, but without success. When I try to build, I get the error 'Could not find assembler at C:\P65\p65.py' - I've triple checked, and this is the right location. I can execute p65.py from the command line however, so I know it works. Just double checking but you should have two entries for the set up of P65. The "Executable location" should be set to your python executable (Python.exe). The "Script File Location" should be set to the p65 python script, so your entry "C:\P65\p65.py" should be set in the ""Script File Location" field. Check these and get back to me P.S. you can use BeebASM with Swift if you wish. There's a profile for it in the assemblers set up screen. |
|
| Author: | rival [ Fri May 09, 2008 11:33 am ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
Firstly Steve - I've changed the settings as you've suggested and everything is fine. I'm compiling in Swift. I seem to have a problem with Windows Media Player though, and I can't play your tutorial videos at the moment. So, I've been working on the program a little bit. Code: .ORG $900 init: LDA #$00 ;the low byte of the initial address STA $70 ;store at &70 LDA #$40 ;the high btye of the initial address STA $71 ;store at &71 LDY #15 ;the amount of pixels to show / 2 LDA #11 ;the byte value to enter into the address to show a yellow pixel and a red pixel main: JMP plot ;draw the picture JMP move ; Move the picture on 2 pixels, 1 byte JMP main ;start the loop again plot: STA ($70), Y DEY BPL plot RTS move: LDA $70 ;read back the low-byte TAX ;move it to the X register INX ;increase it by one TXA ;move it back to A STA $70 ;save it back to where it came from RTS I'm plotting a yellow and red pair of pixels towards the middle of the screen. I've tried to write a routine which will increase the lowbyte, and there is clearly stuff I don't understand. I've downloaded the New Advanced User Guide, but it isn't searchable and wading through the scans (whilst incredibly useful) is sending my eyes funny. What I want it to do is to move the block I'm plotting across the screen. I've a routine 'move' which increase the value stored in the low byte by one. I then should loop back to the beginning of 'main' to execute it again with the new value. It seems that this infinate loop isn't looping at all, and execution ends after the first display. What am I missing? It seems that the line JMP main doesn't do anything. Thanks Sam |
|
| Author: | DaveF [ Fri May 09, 2008 12:22 pm ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
Hello It should perhaps read: Code: main: JSR plot ;draw the picture JSR move ; Move the picture on 2 pixels, 1 byte JMP main ;start the loop again So your subroutines are called then the main is looped back to. JMP is like a goto, while JSR is like a function call. There is a good 6502 instruction reference here. You might also find it useful to wait for the vertical sync, so: Code: main: JSR plot ;draw the picture JSR move ; Move the picture on 2 pixels, 1 byte LDA #19 JSR &FFF4 ; OS_Byte 19 (wait for vsync) JMP main ;start the loop again Also, your entire 'move' routine could just compact to: Code: INC $70 As on the 6502 you can increment memory addresses. You'll probably also want to setup your A and Y registers again on your plot function: Code: plot: LDA #11 LDY #15 plotLoop: STA ($70), Y DEY BPL plotLoop RTS Assemble that lot in and give it another whazz! Dave |
|
| Author: | rival [ Fri May 09, 2008 1:06 pm ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
Thanks Dave - I really should get on with my real work. This is like learning a foreign (y'know, normal) language in that all my stupid mistakes are in public for anyone in earshot to laugh at. Never mind, I'm learning loads. The 6502 reference is very useful, much handier than the NAUG for opcodes. I've updated the program Code: .ORG $900 init: ;LDA #22 ; VDU 22 - set mode ;JMP $FFEE ;OSWRCH ;LDA #2 ; MODE 2 ;JMP $FFEE ; OSWRCH LDA #$00 ;the low byte of the initial address STA $70 ;store at &70 LDA #$40 ;the high btye of the initial address STA $71 ;store at &71 main: JSR plot ;draw the picture JSR move LDA #19 JSR $FFF4 JMP main ;start the loop again plot: LDY #8 ;the amount of pixels to show / 2 LDA #11 ;the byte value to enter into the address to show a yellow pixel and a red pixel plotloop: STA ($70), Y DEY BPL plotloop RTS move: LDA $70 ADC #8 STA $70 RTS There are two areas I want to look at. Firstly, I'm trying to change to mode 2 in code: Code: ;LDA #22 ; VDU 22 - set mode ;JMP $FFEE ;OSWRCH ;LDA #2 ; MODE 2 ;JMP $FFEE ; OSWRCH This is commented out, because it is obviously wrong. I appear to be going to mode 6. I've cribbed this from Christopher Dewhurst's analysis of siege, and clearly shows the dangers in cut and pasting code you don't understand. What have I done wrong here? Secondly, the move routine. Code: move: LDA $70 ADC #8 STA $70 RTS I replaced it with a simple INC as you suggested, but it was very slow. I think that this was because I was over painting the same 'character block' several times. I've increased the value in &70 by 8, and it appears to work and is faster, but not as fast as I'd expect. Any advice? Thanks Sam |
|
| Author: | rival [ Fri May 09, 2008 1:16 pm ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
OK - Got the first one! I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. I will learn the difference between JMP and JSR. |
|
| Author: | DaveF [ Fri May 09, 2008 1:42 pm ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
rival wrote: I replaced it with a simple INC as you suggested, but it was very slow. I think that this was because I was over painting the same 'character block' several times. I've increased the value in &70 by 8, and it appears to work and is faster, but not as fast as I'd expect. Any advice? Did you put the call to OSByte 19 in? That will slow it down. rival wrote: Thanks Dave - I really should get on with my real work. This is like learning a foreign (y'know, normal) language in that all my stupid mistakes are in public for anyone in earshot to laugh at. Never mind, I'm learning loads. Well, as they say, the only stupid question is the one that doesn't get asked |
|
| Author: | SteveO [ Fri May 09, 2008 3:20 pm ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
rival wrote: Firstly Steve - I've changed the settings as you've suggested and everything is fine. I'm compiling in Swift. I seem to have a problem with Windows Media Player though, and I can't play your tutorial videos at the moment. Are you Vista. Apparantly Microsoft removed a common codec stopping files being played. Should work ok in realplayer etc. Can't remember which one but was discussed on here I think Also, I think the old "Advanced User Guide" is a PDF, so you can search it. Might be worth a download. I refer to that the most actually and use the "New" one for Master specific stuff, although I do have a paper copy of that so don't have to put up with scanned version. |
|
| Author: | FrancisL [ Fri May 09, 2008 3:25 pm ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
SteveO wrote: rival wrote: Firstly Steve - I've changed the settings as you've suggested and everything is fine. I'm compiling in Swift. I seem to have a problem with Windows Media Player though, and I can't play your tutorial videos at the moment. Are you Vista. Apparantly Microsoft removed a common codec stopping files being played. Should work ok in realplayer etc. Can't remember which one but was discussed on here I think There were also codecs removed between the original release of XP and XP with service pack 1. Kind regards, Francis. |
|
| Author: | rival [ Fri May 09, 2008 3:48 pm ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
I've got Windows XPx64, but I'm having problems with Audible and other file formats. I need to kind of re-install WMP, but it doesn't seem easy to do. Which is a shame, because I don't really get on with other media players; I find WMP easily the best suited to me. Also, I suspect that I've got a paper copy of the AUG in storage in London. I'll dig it out next time I'm in the UK. |
|
| Author: | rival [ Sun May 11, 2008 9:04 am ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
Steve - I've a pile of suggestions for Swift. I'll sort them out into an email for you. Dave - slowness was caused by waiting for VSync. I've taken it out. OK, so I've been snatching 5 minutes here and there. This is my latest version Code: .ORG $900 init: LDA #22 ; VDU 22 - set mode JSR $FFEE ;OSWRCH LDA #2 ; MODE 2 JSR $FFEE ; OSWRCH LDA #5 JSR $FFEE JSR reset ; reset to top left LDA #1; default byte value STA $72 main: JSR plot ;draw the picture JSR move JMP main ;start the loop again plot: LDY #8 ;the amount of pixels to show / 2 LDA $72 ;the byte value to enter into the address plotloop: STA ($70), Y DEY BPL plotloop RTS move: LDA $70 ADC #8 STA $70 BVS movehi RTS movehi: LDA #0 STA $70 INC $71 ;Add 1 to the hi byte LDA $71 CMP #$7F BEQ reset ;move back to top left if we've moved the high byte to &80 RTS reset: LDA #$00 ;the low byte of the initial address STA $70 ;store at &70 LDA #$40 ;the high btye of the initial address STA $71 ;store at &71 INC $72 ;move the colour on RTS end: NOP So the idea is that it paints the byte in &72 to every byte on screen. When its done a full screen, it increases the value in &72 and starts again. It isn't working properly, and a picture paints a thousand words. ![]() The theory is that I'm doing this by adding 8 to the low byte after every plot routine, and then checking the overflow bit. If I've overflowed, I increase the high byte by one. When I increase the high byte, I test to see if I've got to the end of the screen memory. If so, I reset the start location back to &3000, increase the value in &72 and start again. Can someone point out the obvious error I've made? Thanks |
|
| Author: | JonW [ Sun May 11, 2008 10:03 am ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
You need to check the carry flag, not the overflow flag when doing additions. You also need to clear the carry flag before doing the add as well. Try changing your move routine to : Code: LDA $70 CLC ADC #8 STA $70 BCS movehi RTS Jon. |
|
| Author: | rival [ Sun May 11, 2008 12:54 pm ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
Thanks Jon, that's magic. I've now got a full screen of flashing colours! |
|
| Author: | SteveO [ Sun May 11, 2008 1:03 pm ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
As Jon said, but it still isn't quite right, You need to make the following changes. Firstly your not starting at $3000 (you know you have to) but you've accidentally done a typo by putting in Code: LDA #$40 ;the high byte of the initial address should be #$30 That will get it starting at the beginning of the screen. The the other issue is that it doesn't fill the screen. You've written Code: CMP #$7F But by compring with this value means the last 256 bytes of screen memory won't get written to, just change to Code: CMP #$80 in fact these lines; Code: LDA $71 CMP #$7F BEQ reset ;move back to top left if we've moved the high byte to &80 can be replaced with Code: BMI reset several cycles saved. This works because You want to test when you get to $80, just luckily anything below this value does not have the top bit set (bit 7). When it hits $80 (via your inc $71) then bit 7 becomes set and therefore sets the negative flag. also, not an error as such but the lines; Code: movehi: LDA #0 STA $70 Need not be there at all, you can remove them and the code does the same. This is because the $70 value starts at 0 and you add 8 each time, therefore when the carry gets set the value in $70 will actually be 0 anyway, so you can save yourself some machine cycles So to put it together all these lines; Code: LDA #0 STA $70 INC $71 ;Add 1 to the hi byte LDA $71 CMP #$7F BEQ reset ;move back to top left if we've moved the high byte to &80 can be replaced by; Code: INC $71 ;Add 1 to the hi byte BMI reset ;move back to top left if we've moved the high byte to &80 and that will save you quite a few cycles. P.S. I look forward to your suggestions for Swift |
|
| Author: | rival [ Sun May 11, 2008 1:39 pm ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
Solid gold. Quote: LDA #$40 ;the high byte of the initial address should be #$30 That will get it starting at the beginning of the screen. The the other issue is that it doesn't fill the screen. You've written CMP #$7F Yep, I'd picked these up. They were just values I was playing with. Quote: LDA #0 STA $70 INC $71 ;Add 1 to the hi byte LDA $71 CMP #$7F BEQ reset ;move back to top left if we've moved the high byte to &80 can be replaced by; INC $71 ;Add 1 to the hi byte BMI reset ;move back to top left if we've moved the high byte to &80 Magic, thank you. I'd never have thought to see what the decimal value of &80 was. As it is 128, then bit 7 is set and I can see if it would represent a negative number - fantastic. Quote: and lastly, not an error as such but the lines; movehi: LDA #0 STA $70 Need not be there at all, I suspected that this was the case, but I've fallen foul of assumptions and impossible cases too many times in the past, so I stuck them in to be certain. I've stripped them out now. I'll try to put something together soon about Swift. |
|
| Author: | SteveO [ Sun May 11, 2008 1:47 pm ] |
| Post subject: | Re: Starting out in 6502 - code snippets and examples |
Quote: Magic, thank you. I'd never have thought to see what the decimal value of &80 was. As it is 128, then bit 7 is set and I can see if it would represent a negative number - fantastic. |
|
| Page 1 of 4 | All times are UTC [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|