#[1]nesdoug » Feed [2]nesdoug » Comments Feed [3]nesdoug » 65816 Basics Comments Feed [4]SNES Overview [5]alternate [6]alternate [7]nesdoug [8]WordPress.com [9]Skip to content [10]nesdoug NES Programming with cc65 65816 Basics Programming the SNES in assembly, using the ca65 assembler. Assembly Language Basics When computer code is compiled, in a higher level language, it is converted to a binary code (machine code) that the CPU can read and run. Binary code is very hard to read and write. So, they developed a system of mnemonics to make it easier to understand, called assembly language. There are many different assembly languages, each targeting a specific CPU. We are targeting the 65816 (65c816) which is a more advanced version of the popular 6502 chip. The best way to learn 65816 assembly is to first learn 6502. But first, lets review the basics. . Number Systems Binary. Under the hood, all computers process binary numbers. A series of 1s and 0s. In the binary system, each column is 2x the value of the number to the right. 0001 = 1 0010 = 2 0100 = 4 1000 = 8 You then add all the 1’s up 0011 = 2+1 = 3 0101 = 4+1 = 5 0111 = 4+2+1 = 7 1111 = 8+4+2+1 = 15 Each of these digits is called a bit. Typically, there are 8 bits in a byte. So you can have numbers from 0000 0000 = 0 to 1111 1111 = 255 Since it is difficult to read binary, we will use hexadecimal instead. Hexadecimal is a base 16 numbering system. Every digit is 16x the number to the right. We use the normal numbers from 0-9 and then letters A-F for the values 10,11,12,13,14,15. In many assembly languages, we use $ to indicate hex numbers. $0 = 0 $1 = 1 $2 = 2 $3 = 3 $4 = 4 $5 = 5 $6 = 6 $7 = 7 $8 = 8 $9 = 9 $A = 10 $B = 11 $C = 12 $D = 13 $E = 14 $F = 15 $F is the same as binary 1111. The next column of numbers is multiples of 16. $00 = 16*0 = 0 _____ $80 = 16*8 = 128 $10 = 16*1 = 16 _____ $90 = 16*9 = 144 $20 = 16*2 = 32 ____ $A0 = 16*10 = 160 $30 = 16*3 = 48 ____ $B0 = 16*11 = 176 $40 = 16*4 = 64 ____ $C0 = 16*12 = 192 $50 = 16*5 = 80 ____ $D0 = 16*13 = 208 $60 = 16*6 = 96 ____ $E0 = 16*14 = 224 $70 = 16*7 = 112 ____ $F0 = 16*15 = 240 $F0 is the same as binary 1111 0000. add that to $0F (0000 1111) to get $FF = 1111 1111 So you see, you can represent 8 bit binary numbers with 2 hex digits. From $00 to $FF (0 – 255). To get the assembler to output the value 100 you could write… .byte 100 or .byte $64 . 16 bit numbers Typically (on retro systems) you use 16 bit numbers for memory addresses. Memory addresses are locations where pieces of information can be stored and read later. So, you could write a byte of data to address $1000, and later read from $1000 to get that data. The registers on the SNES can be set to either 8 bit or 16 bit modes. 16 bit mode means it can move information 16 bits at a time, and process the information 16 bits at a time. 16 bit registers means that it will read a byte from an address, and another from the address+1. Same with writing 16 bits. It will write (low order byte) to the address and (high order byte) to address+1. In binary, a 16 bit value can go from 0000 0000 0000 0000 = 0 to 1111 1111 1111 1111 = 65535 In hex values, that’s $0000 to $FFFF. Let’s say we have the value $1234. The 12 is the most significant byte (MSB), and the 34 is the least significant byte (LSB). To calculate it’s value by hand we can multiply each column by multiples of 16. $1234 4 x 1 = 4 3 x 16 = 48 2 x 256 = 512 1 x 4096 = 4096 4096 + 512 + 48 + 4 = 4660 To output a 16 bit value $ABCD, you could write .word $ABCD (outputs $cd then $ab, little endian style) Don’t forget the $. We can also get the upper byte or lower byte of a 16 bit value using the < and > symbols before the value. Let’s say label List2 is at address $1234 .byte >List2 will output a $12 (the MSB) .byte $123456 (outputs $34) .byte <$123456 (outputs $56) But we don’t want to write our program entirely using byte statements. That would be crazy. We will use assembly language, and the assembler will convert our three letter mnemonics into bytes for us. LDA #$12 (load the A register with the value $12) will be converted by the assembler into this machine code that the 65816 CPU can execute… $A9 $12 . 65816 CPU Details There are 3 registers to work with A (the accumulator) for most calculations and purposes X and Y (index registers) for accessing arrays and counting loops. A,X, and Y can be set to either 8 bit or 16 bit. The accumulator is sometimes called C when it is in 16 bit mode. Setting the Accumulator to 8 bit does not destroy the upper byte, you can access it with XBA (swap high and low bytes). However, setting the Index registers to 8 bit will delete the upper bytes of X and Y. There is a 16-bit stack pointer (SP or S) for the hardware stack. If you call a function (subroutine) it will store the return address on the stack, and when the function ends, it will pop the return address back to continue the main program. The stack always exists on bank zero (00). Processor Status Flags (P), to determine if a value is negative, zero, greater/lesser/equal to, etc. Used to control the flow of the program, like if/then statements. Also the register size (8 bit or 16 bit) are set/reset as status flags. *(see below) There is a 16-bit direct page (DP) register, which is like the zero page on the 6502 system, except that it is now movable. Typically, people leave it set to $0000 so that it works the same as the 6502. Zero page is a way to reduce ROM size, by only using 1 byte to refer to an address. The DP always exists on bank zero (00). The Program Bank Register (PBR or K) is the bank byte (highest byte) of the 24 bit address of where the program is running. Together, with the program counter (PC) the CPU will execute the program at this location. The PBR does NOT increment when the PC overflows from FFFF to 0000, so you can’t have code that flows from one bank to another. You can’t directly set the PBR, but jumping long will change it, and you can push it to the stack to be used by the… Data Bank Register (DBR or B) is the bank byte (highest byte) of the 24 bit address of where absolute addressing (16 bit) reads and writes. Usually you want to set it to the same as where your program is running. You do it with this… PHK (push program bank to stack) PLB (pull from stack to data bank) But you can also set it to another bank, to use absolute addressing to access that bank’s addresses. There is also a hidden switch to change the processor from Native Mode (all 65816 instructions) to Emulation Mode (only 6502 instructions, minus bugs and minus unofficial opcodes). The CPU powers on in Emulation Mode, so you will usually see CLC (clear the carry flag) XCE (transfer carry flag to CPU mode) near the start, to put it in Native Mode. . Status Flags NVMXDIZC – – – B – – – – (emulation mode only) N negative flag, set if an operation sets the highest bit of a register V overflow flag, for signed math operations M Accumulator size, set for 8-bit, zero for 16-bit X Index register size, set for 8-bit, zero for 16-bit D decimal flag, for decimal (instead of hexadecimal) math I IRQ disable flag, set to block IRQ interrupts Z zero flag, set if an operation sets a register to zero . . . . or if a comparison is equal C carry flag, for addition/subtraction overflow B break flag, if software break BRK used. . Where does the program start? It always boots in bank zero, in emulation mode, and pulls an address (vector) off the Emulation Mode Reset Vector located at $00FFFC and $00FFFD, then jumps to that address (always jumping to bank zero). Your program should set it to Native Mode, after which these are the important vectors. IRQ $00FFEE-00FFEF (interrupt vector) NMI $00FFEA-00FFEB (non-maskable interrupt vector) If an interrupt happens, it will jump to the address located here (always jumping to bank zero). There is no Reset Vector in Native Mode. Hitting reset will automatically put it back into Emulation Mode, and it will use that Reset Vector. But more on those later. I highly recommend you learn more about 6502 assembly before continuing. Here are some links that are helpful. [11]http://www.6502.org/tutorials/6502opcodes.html [12]https://skilldrick.github.io/easy6502/ [13]https://archive.org/details/6502_Assembly_Language_Programming_by_L ance_Leventhal/mode/1up and 65816 assembly reference here. [14]https://wiki.superfamicom.org/65816-reference and for the very bold, the really really big detailed book on the subject. [15]http://archive.6502.org/datasheets/wdc_65816_programming_manual.pdf Share this: * [16]Twitter * [17]Facebook * Like this: Like Loading... [18]April 3, 2020April 4, 2020 [19]dougfraker Leave a Reply [20]Cancel reply Enter your comment here... ____________________________________________________________ ____________________________________________________________ ____________________________________________________________ ____________________________________________________________ Fill in your details below or click an icon to log in: * * * * [21]Gravatar Email (required) (Address never made public) ____________________ Name (required) ____________________ Website ____________________ WordPress.com Logo You are commenting using your WordPress.com account. ( [22]Log Out / [23]Change ) Google photo You are commenting using your Google account. ( [24]Log Out / [25]Change ) Twitter picture You are commenting using your Twitter account. ( [26]Log Out / [27]Change ) Facebook photo You are commenting using your Facebook account. ( [28]Log Out / [29]Change ) [30]Cancel Connecting to %s [ ] Notify me of new comments via email. [ ] Notify me of new posts via email. Post Comment Post navigation [31]Previous Previous post: SNES Overview Search for: ____________________ Search Recent Posts * [32]65816 Basics * [33]SNES Overview * [34]SNES Projects * [35]24. Advanced Mapper – MMC3 * [36]Review – 150 Classic NES Games for GBA Recent Comments Marcus on [37]24. Advanced Mapper –… [38]dougfraker on [39]23. Advanced mapper MMC1 [40]dougfraker on [41]23. Advanced mapper MMC1 Aeris on [42]23. Advanced mapper MMC1 Aeris on [43]23. Advanced mapper MMC1 Archives * [44]April 2020 * [45]March 2020 * [46]November 2019 * [47]October 2019 * [48]September 2019 * [49]April 2019 * [50]September 2018 * [51]July 2018 * [52]June 2018 * [53]March 2018 * [54]October 2017 * [55]September 2017 * [56]April 2017 * [57]March 2016 * [58]January 2016 * [59]December 2015 Categories * [60]Uncategorized Meta * [61]Register * [62]Log in * [63]Entries feed * [64]Comments feed * [65]WordPress.com [66]Blog at WordPress.com. Close and accept Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use. To find out more, including how to control cookies, see here: [67]Cookie Policy IFRAME: [68]likes-master %d bloggers like this: References Visible links 1. https://nesdoug.com/feed/ 2. https://nesdoug.com/comments/feed/ 3. https://nesdoug.com/2020/04/03/65816-basics/feed/ 4. https://nesdoug.com/2020/04/02/snes-overview/ 5. https://public-api.wordpress.com/oembed/?format=json&url=https://nesdoug.com/2020/04/03/65816-basics/&for=wpcom-auto-discovery 6. https://public-api.wordpress.com/oembed/?format=xml&url=https://nesdoug.com/2020/04/03/65816-basics/&for=wpcom-auto-discovery 7. https://nesdoug.com/osd.xml 8. https://s1.wp.com/opensearch.xml 9. https://nesdoug.com/2020/04/03/65816-basics/#content 10. https://nesdoug.com/ 11. http://www.6502.org/tutorials/6502opcodes.html 12. https://skilldrick.github.io/easy6502/ 13. https://archive.org/details/6502_Assembly_Language_Programming_by_Lance_Leventhal/mode/1up 14. https://wiki.superfamicom.org/65816-reference 15. http://archive.6502.org/datasheets/wdc_65816_programming_manual.pdf 16. https://nesdoug.com/2020/04/03/65816-basics/?share=twitter 17. https://nesdoug.com/2020/04/03/65816-basics/?share=facebook 18. https://nesdoug.com/2020/04/03/65816-basics/ 19. https://nesdoug.com/author/dougfraker/ 20. https://nesdoug.com/2020/04/03/65816-basics/#respond 21. https://gravatar.com/site/signup/ 22. javascript:HighlanderComments.doExternalLogout( 'wordpress' ); 23. https://nesdoug.com/2020/04/03/65816-basics/ 24. javascript:HighlanderComments.doExternalLogout( 'googleplus' ); 25. https://nesdoug.com/2020/04/03/65816-basics/ 26. javascript:HighlanderComments.doExternalLogout( 'twitter' ); 27. https://nesdoug.com/2020/04/03/65816-basics/ 28. javascript:HighlanderComments.doExternalLogout( 'facebook' ); 29. https://nesdoug.com/2020/04/03/65816-basics/ 30. javascript:HighlanderComments.cancelExternalWindow(); 31. https://nesdoug.com/2020/04/02/snes-overview/ 32. https://nesdoug.com/2020/04/03/65816-basics/ 33. https://nesdoug.com/2020/04/02/snes-overview/ 34. https://nesdoug.com/2020/03/19/snes-projects/ 35. https://nesdoug.com/2019/11/11/23-advanced-mapper-mmc3/ 36. https://nesdoug.com/2019/10/31/review-150-classic-nes-games-for-gba/ 37. https://nesdoug.com/2019/11/11/23-advanced-mapper-mmc3/comment-page-1/#comment-12577 38. https://nesdoug.wordpress.com/ 39. https://nesdoug.com/2019/10/02/22-advanced-mapper-mmc1/comment-page-1/#comment-12081 40. https://nesdoug.wordpress.com/ 41. https://nesdoug.com/2019/10/02/22-advanced-mapper-mmc1/comment-page-1/#comment-12080 42. https://nesdoug.com/2019/10/02/22-advanced-mapper-mmc1/comment-page-1/#comment-12077 43. https://nesdoug.com/2019/10/02/22-advanced-mapper-mmc1/comment-page-1/#comment-12076 44. https://nesdoug.com/2020/04/ 45. https://nesdoug.com/2020/03/ 46. https://nesdoug.com/2019/11/ 47. https://nesdoug.com/2019/10/ 48. https://nesdoug.com/2019/09/ 49. https://nesdoug.com/2019/04/ 50. https://nesdoug.com/2018/09/ 51. https://nesdoug.com/2018/07/ 52. https://nesdoug.com/2018/06/ 53. https://nesdoug.com/2018/03/ 54. https://nesdoug.com/2017/10/ 55. https://nesdoug.com/2017/09/ 56. https://nesdoug.com/2017/04/ 57. https://nesdoug.com/2016/03/ 58. https://nesdoug.com/2016/01/ 59. https://nesdoug.com/2015/12/ 60. https://nesdoug.com/category/uncategorized/ 61. https://wordpress.com/start?ref=wplogin 62. https://nesdoug.wordpress.com/wp-login.php 63. https://nesdoug.com/feed/ 64. https://nesdoug.com/comments/feed/ 65. https://wordpress.com/ 66. https://wordpress.com/?ref=footer_blog 67. https://automattic.com/cookies 68. https://widgets.wp.com/likes/master.html?ver=20190321#ver=20190321 Hidden links: 70. https://nesdoug.com/2020/04/03/65816-basics/#comment-form-guest 71. https://nesdoug.com/2020/04/03/65816-basics/#comment-form-load-service:WordPress.com 72. https://nesdoug.com/2020/04/03/65816-basics/#comment-form-load-service:Twitter 73. https://nesdoug.com/2020/04/03/65816-basics/#comment-form-load-service:Facebook 74. https://nesdoug.wordpress.com/ 75. https://nesdoug.wordpress.com/