├── N64MipsDevHowto ├── n64.bib └── n64.lyx ├── Patents ├── US20010016517.pdf ├── US6239810.High_performance_low_cost_video_game_sys.pdf └── US6331856.Video_game_system_with_coprocessor_provi.pdf ├── README.md ├── cart └── oscill.html ├── cd64 ├── cd64_misc ├── cd64_protocols ├── comms_link └── ppa_workings ├── controller └── lablecckpt1.pdf ├── lockout ├── n64importmod.txt ├── n64pifmod.html └── n64securitychipmodmm6.jpg ├── mips ├── 007-2489-001.pdf ├── 007-2597-001.pdf ├── 007-2816-004.pdf ├── 007-2816-005.pdf ├── Errata R4000-R4400 Microprocessor users manual 2nd edition.pdf ├── MIPS-N32-ABI-Handbook.pdf ├── R4300_datasheet.Rev0.3.pdf ├── R4300i_Prod_Ov.ps.gz ├── U10116EJ6V0DS00.pdf ├── U10116EJ7V0DS00.pdf ├── mips-isa.pdf ├── tutorial │ ├── InstructionSets3.PDF │ ├── data.pdf │ └── mips_instructions.pdf └── vr4300.html ├── misc ├── Nintendo_64_Game_Console-BPT.pdf ├── bootcode_start_addresses.txt ├── eeprom.txt ├── mipscheck.manpage.html ├── n64_dma_pathways.dia ├── n64dox-0.5.txt ├── n64dox.txt ├── n64info.txt └── trainer.txt ├── n64ops ├── controll.txt ├── n64ops#a.txt ├── n64ops#b.txt ├── n64ops#c.txt ├── n64ops#d.txt ├── n64ops#e.txt ├── n64ops#f.txt ├── n64ops#g.txt ├── n64ops#h.txt ├── rcp.txt ├── readme.txt └── sound.txt ├── rambus └── n64_rdram_datasheet.pdf ├── rcp └── ucode_example.html ├── tutorial ├── day1n64.htm ├── day2n64.htm ├── day3n64.htm ├── day4n64.htm ├── day5n64.htm ├── day6n64.htm ├── day7n64.htm ├── day8n64.htm ├── day9n64.htm └── n64asm.htm └── z64 ├── z64_arch.txt ├── z64hw_dextrose.html ├── z64hw_dextrose_1.html └── z64hw_dextrose_2.html /N64MipsDevHowto/n64.bib: -------------------------------------------------------------------------------- 1 | % This file was created with JabRef 2.3.1. 2 | % Encoding: ANSI_X3.4-1968 3 | 4 | @OTHER{beyond3d-forum, 5 | owner = {underwoo}, 6 | timestamp = {2009.04.27} 7 | } 8 | 9 | @comment{jabref-meta: selector_publisher:} 10 | 11 | @comment{jabref-meta: selector_author:} 12 | 13 | @comment{jabref-meta: selector_journal:} 14 | 15 | @comment{jabref-meta: selector_keywords:} 16 | 17 | -------------------------------------------------------------------------------- /Patents/US20010016517.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/Patents/US20010016517.pdf -------------------------------------------------------------------------------- /Patents/US6239810.High_performance_low_cost_video_game_sys.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/Patents/US6239810.High_performance_low_cost_video_game_sys.pdf -------------------------------------------------------------------------------- /Patents/US6331856.Video_game_system_with_coprocessor_provi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/Patents/US6331856.Video_game_system_with_coprocessor_provi.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | n64docs 2 | ============================ 3 | If you're looking for docs on the N64... congrats, you're at the right place. Sadly, 4 | nobody cared to clean this pile of junk up, so if you want something you'll have to 5 | wade through all the cruft. 6 | 7 | Ideally, this will all wind up in a more organized form on the website, but "ain't 8 | nobody got time for that". 9 | -------------------------------------------------------------------------------- /cart/oscill.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Oscilloscope Data 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | Search
16 | Projects
17 | 31 | Tidbits
32 | Vita
33 | 34 |
35 | Alex's Abode 36 |
37 | Last Updated: 2000.02.03
38 | © 2000 Alexander Reeder
39 | Access #1068 40 |
41 | 42 | 43 |
44 | 45 | 46 | 47 |
48 | [ Picture of the Cartridge Reader ]

49 |

50 | Using the data from when I traced the pins on the cartridge reader, I compared it to 51 | my findings using an oscilloscope. The scope I was using could only go up to 20 Mhz, 52 | while the N64 bus is functioning at 93.75. Therefore I can only speculate about many 53 | of the data lines, and their functions. Data - Low/High means that that data line stays 54 | Low/High while it is idle. Low means it might be data, or Vss. High is Data or Vcc.

55 |

56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 |
Pin # Leads to: Oscilloscope Reading:
1 Vss Low
2 Vss Low
3 RCP Pin 58 Low
4 RCP Pin 54 Low
5 RCP Pin 52 Data - Low
6 Vss Data - Low
7 RCP Pin 50 Data - Low
8 RCP Pin 46 Data - Low
9 Vcc Data - Low
10 RCP Pin 44 Data - Low
11 RCP Pin 40 Low
12 RCP Pin 38 Low
13 Vss Data - Low
14 Vcc (12V from SW1 Pin 7) Data - Low
15 RCP Pin 34 High
16 RCP Pin 32 Low
17 Vcc High
18 U6 Pin 5 High
19 U6 Pin 1 Data - High
20 R4300i Pin 110 (ColdReset*) Data - High
21 Vss Data - Low
22 Vss Data - Low
23 Vss Data - Low
24 R21 to Vss (200 Ohms) Data - High
25 Vcc (12V from SW1 Pin 7) Vcc - 12V
26 Vcc (12V from SW1 Pin 7) Vcc - 12V
27 Vss Data - Low
28 RCP Pin 57 Data - Low
29 RCP Pin 53 Data - Low
30 RCP Pin 51 Data - Low
31 Vss Data - High
32 RCP Pin 47 Data - High
33 RCP Pin 45 Data - High
34 Vcc Data - High
35 RCP Pin 41 Sync
36 RCP Pin 39 Data - Low
37 RCP Pin 35 Data - High
38 Vcc (12V from SW1 Pin 7) Data - High (I/O?)
39 Vcc (12V from SW1 Pin 7) Data - High
40 RCP Pin 33 Data/Sync/I/O?
41 RCP Pin 31 Low
42 Vcc Low
43 U6 Pin 3 Low
44 R4300i Pin 57 (JTCK) Low
45 U6 Pin 7 Low
46 U4 Pin 14 Low
47 Vss Low
48 Vss Low
205 |
206 |
207 | [ Picture of N64's bus with my cable ]

208 |

209 | [ Interface your PC and a N64 ]

210 |
211 | 212 | 241 | 242 | 243 | -------------------------------------------------------------------------------- /cd64/cd64_misc: -------------------------------------------------------------------------------- 1 | Colin, I disassembled the cd64 rom and figured out how to access the comm port and DRAM (still gotta work on the cdrom drive!), it totally rocks I wrote a program that emulates the cd64comm.exe on the n64, so I first transfer my program, then transfer a demo.rom using the comm port, then relocate it in the DRAM and switch mode, jump to the start address and wow it doesnt work :-( 2 | 3 | I disassembled most of the boot code and it looks like I need to emulate that to actually get the transferred rom running in dram. Once thats done (looks pretty easy) I will be able to do everything the cd64 bios does except acess the cdrom drive. Maybe I will write my own bios ;-) 4 | 5 | Gotta say the cd64 rox for coding! I used to use the z64 but never touch it now. uhm the z64 bios contains a rom called z64bios.rom (surprising that..) I guess it would be possible to disassemble that and figure out how to use the shared memory with the 386 but it means coding your own bios in dos etc. which is a bit of a pain. 6 | 7 | It shouldnt be too difficult to get other devices talking to a pc if you interface a pio chip or something to the n64. 8 | 9 | On a related note I saw some source code on dextrose which contained references to a DN64 card? It looked like it was setting up ras and cas stuff but I'm pretty certain you cant do this with any of the backup systems, anyone know what it was? 10 | 11 | I thought the same thing, it should be possible to modify some stuff and get the debugger started as a thread once the n64 is initialised, and then modify the standard lib functions (and replace them in the rom) to record stuff to the debugger. I don't know if it would be possible to do a psyq style debugger in software only (single stepping etc.) This is for hacking roms, for coding your own stuff it might be possible to port the gnu debugger but thats a lot of work... 12 | 13 | 14 | Originally posted by browser: 15 | Can someone please tell me what is the difference in the clear CD64 and the black CD64. Please Respond to this topic. 16 | 17 | 18 | The black CD64 were built 128Mbits of DRAM and a portable CDROM 19 | reader. Depending on the age of the device, it may have the 1.1 PCB or 20 | the 1.2: the difference is that the 1.1 PCB tries to gather is power 21 | from the N64, whereas the 1.2 PCB always requires an external PSU. 22 | 23 | Anyway you can replace the portable CDROM with any other kind of ATAPI 24 | cdrom, and you can upgrade the memory to 256M replacing the simm with 25 | a 32 megabytes 5v EDO simm. 26 | -------------------------------------------------------------------------------- /cd64/cd64_protocols: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/cd64/cd64_protocols -------------------------------------------------------------------------------- /cd64/comms_link: -------------------------------------------------------------------------------- 1 | SD0-SD7 2 | AEN 3 | SA1-SA9 4 | IOR 5 | IOW 6 | IRQ3,4,5,6,7,9 (NC) 7 | 8 | 74LS373 are actually 74LS374. 9 | 10 | When AEN is low and a correct address is decoded (0x3[0-3][02]) 11 | for status port, then ff (busy) or fe (idle) is driven on data lines, depending 12 | if PCX is high or low. For data port, if AEN low and address decoded, then 13 | when IOR driven low, latched data is placed on data lines; when IOW driven low, 14 | data lines are latched. 15 | 16 | When DATAWR is asserted from target, (STATUS_REG D0) line is lowered. 17 | This lowers busy flag (... and asserts IRQ. How is IRQ cleared?) 18 | 19 | capacitors? resistors? 20 | -------------------------------------------------------------------------------- /cd64/ppa_workings: -------------------------------------------------------------------------------- 1 | flipflop2: ~Q1 is connected to reset Q2 2 | 3 | when NINIT or NSELECT are high, latch is powered on, flipflop1 powered on, busy is set 4 | when STROBE is high, latch is powered on, flipflop1 powered on, and flipflop2->clock2, busy is set 5 | 6 | NINIT, NSELECT, STROBE low => latch off, flipflip1 off 7 | 8 | AUTOFD => flipflop2->reset1, makes busy go high (disable) 9 | 10 | BUSY <= flipflop2->q1 11 | 12 | DATAWR from CD64 side enables latch, flipflop2->clock1 13 | 14 | DATARD from CD64 side: 15 | enables flipflop1, flipflop2, flipflop2->set2,set1, flipflop2->data2,data1 16 | 17 | PCX from CD64: 18 | tied to flipflop2->q2 19 | 20 | Flipflop2 always on 21 | 22 | 0x04: Init (set), Select high: Latch power on, flipflop1 power on 23 | 24 | --------------- 25 | 26 | Data transfer cycle: 27 | 28 | Check to make sure not busy from a previous read. (would mean that PCWR never got asserted) 29 | 30 | 0x04 -> 0x26: Select high, Init High (set), autofeed low (set), and strobe High (17, 16, 14, 1): 31 | Set reverse mode (CD64 writes to data) 32 | Reset Q1 on flipflop2: 33 | busy goes low (0x80 is on - busy) until PCWR is asserted (and a high is then clocked in) 34 | Resets Q2 with Low: if PCRD is high, PCX goes low 35 | 36 | Guessing here that CD64 sees PCX low, places data to write on pins and asserts PCWR 37 | 38 | PCWR from CD64: 39 | Clock latch, CD64 data goes onto pins 40 | Clock Q1 on flipflop2: Set busy high (meaning 0x80 is off - not busy) 41 | 42 | PC would read the data here 43 | 44 | 0x26 -> 0x04: 45 | Set normal mode (PC writes to data) 46 | Set Q1 on flipflop2 back to high for edge trigger 47 | 48 | 0x04 -> 0x05: (strobe goes low) 49 | flipflop1->cl, flipflop2->cl2 go low 50 | 51 | 0x05 -> 0x04: (strobe goes back high) 52 | clocks flipflop1 making PC Data available to cd64 53 | flipflop2->clock2, sets PCX high 54 | 55 | Guessing that CD64 sees PCX high, deasserts PCWR and reads the byte 56 | 57 | ----------------- 58 | 59 | Power on: 60 | DATARD high 61 | LCDRS high 62 | -------------------------------------------------------------------------------- /controller/lablecckpt1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/controller/lablecckpt1.pdf -------------------------------------------------------------------------------- /lockout/n64importmod.txt: -------------------------------------------------------------------------------- 1 | [n64 import mod] 2 | 3 | for PAL and NTSC consoles 4 | 5 | you might wonder what an "import mod" is,basically,it's an 6 | internal modification inside the n64 that lets you play import games 7 | on your console without the need of an adaptor or somethin else. 8 | i never found infos on the net about such a mod,dunno why,perhaps because 9 | only europeans suffer from this problem,between japanese and 10 | american carts,there is no lockout incompatiblity,just the tabs in the cart slot 11 | that need to be cut away,so propably im the first to do this 12 | tell me if im wrong on that one... 13 | this mod is complete and runs ALL NTSC AND PAL CARTS(obviously ;) on a PAL- or NTSC-N64. 14 | 15 | You need the following parts: 16 | 17 | NINTENDO64 ;-) pal and ntsc version 18 | good soldering skills 19 | 5 2-way switches 20 | screwdrivers for nintendo systems(since you aint got them,ill explain you how to make them yourself ;-) 21 | some desolder pump or what its called.is not neccessary,but VERY useful,i recommend you get one for about $5 in ur electronics store 22 | 23 | the mod works like this: 24 | 25 | basically you just cut out the security-chip [PIF(P)-NUS] out of a pal-n64 and connect most pins to the equivalent pins of the ntsc security-chip [PIF-NUS] of a ntsc-n64.the pins 26 | that were not connected are seperated and soldered via 5 two-way switches to the pcb. 27 | now you can switch between pal and ntsc n64 settings and there are NO limitations,EVERY single cart will work ;) 28 | be warned: 29 | you should only do this mod if you are experienced with soldering and stuff!! 30 | while doing this mod,you mess around with the pins of smd-chips,that will break if you bend 31 | them more than 2 times.(if they do,you even need to open the chip itself and this is REALLY tricky,trust me >:-[ ) 32 | 33 | ok,you should do it like this: 34 | open both n64 (how to build a nintendo screwdriver is explained in the cheap mod guide). 35 | now you have 2 choices: 36 | take out the PIF-NUS of a pal n64(use a needle and a soldering iron to lift up the pins) and solder it directly onto the ntsc-pif,but i cant recommend this one,cause its very likely that you break a pin. 37 | for me,the best choice was to desolder both,the ntsc and the pal PIF-NUS,solder both on seperate pcb ( you can buy readymade boards for all kinds of smd-chips in your fav electronic store) and run wires from these pcbs.that means you arent in danger of breaking any pins on the PIFs,cause these little babys are worth a whole n64,you know ;) 38 | 39 | 40 | once this is done,run wires from a pifs pins that are marked green on the pic to their equivalent pins on the other pif and the pcb(bad explanation,sorry ;) 41 | for example you run a wire from PIF(P)-NUS pin 1 to pin 1 of PIF-NUS and to pin 1 on the pcb,so all pin 1s are hooked up together. 42 | run wires from the pins marked white to ground somewhere on the n64 board. 43 | the other pins running from pif-nus and pif(P)-nus are connected to the pcb via a relais and a 2 way switch(or a jk flip flop + button if ur cool dude ;) 44 | 45 | to switch all lines at once (theres no relais in the diagram coz i was too lazy,but u know how to wire them lines up ;) 46 | 47 | so you can decide if the n64 uses the pins of the pal or the ntsc pif. 48 | 49 | the pink pins on the pcbs are not connected. 50 | 51 | thats it, you are done now. 52 | mail me for further questions :) 53 | 54 | btw,since your pal n64 is not working anymore,you can send it to nintendo of europe 55 | 56 | and tell them to fix it,it isnt expensive. 57 | 58 | 59 | 60 | always remember,this mod was invented by ME(i searched the whole net and didnt find anything like this,perhaps something similar exist somewhere,but this mod is 100% from my brain ;) 61 | if you wanna put it on your page,you are free to do so,as long as you inform me and GIVE 62 | ME FULL CREDITS ;) 63 | ohh,and of course i'm in no way responsible if you damage your n64 or something. 64 | 65 | -------------------------------------------------------------------------------- /lockout/n64pifmod.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | dragonforce's mods 8 | 9 | 10 | 11 | 14 |
15 | 16 | 18 | 19 | 43 | 180 | 181 |
21 | 22 | 24 | 25 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 36 | 37 | 38 | 40 | 41 |
42 |

 

44 |

l33t import mod

46 |

for PAL and NTSC consoles

48 |

you might wonder what an 50 | "import mod" is,basically,it's an
51 | internal modification inside the n64 that lets you play 52 | import games
53 | on your console without the need of an adaptor or 54 | somethin else.
55 | i never found infos on the net about such a mod,dunno 56 | why,perhaps because
57 | only europeans suffer from this problem,between japanese 58 | and
59 | american carts,there is no lockout incompatiblity,just 60 | the tabs in the cart slot
61 | that need to be cut away,so propably im the first to do 62 | this
63 | tell me if im wrong on that one...
64 | this mod is complete and runs ALL NTSC AND PAL 65 | CARTS(obviously ;) on a PAL- or NTSC-N64.
66 |
67 | You need the following parts:

68 |
70 | 71 | 74 | 75 | 76 | 78 | 79 | 80 | 82 | 83 | 84 | 88 | 89 | 90 | 95 | 96 |
NINTENDO64 ;-) pal and 73 | ntsc version
good soldering skills
5 2-way switches
screwdrivers for 86 | nintendo systems(since you aint got them,ill 87 | explain you how to make them yourself ;-)
some desolder pump or 92 | what its called.is not neccessary,but VERY 93 | useful,i recommend you get one for about $5 in ur 94 | electronics store
97 |

the mod works like 99 | this:
100 |
101 | basically you just cut out the security-chip [PIF(P)-NUS] 102 | out of a pal-n64 and connect most pins to the equivalent 103 | pins of the ntsc security-chip [PIF-NUS] of a 104 | ntsc-n64.the pins
105 | that were not connected are seperated and soldered via 5 106 | two-way switches to the pcb.
107 | now you can switch between pal and ntsc n64 settings and 108 | there are NO limitations,EVERY single cart will work ;)
109 | be warned:
110 | you should only do this mod if you are experienced with 111 | soldering and stuff!!
112 | while doing this mod,you mess around with the pins of 113 | smd-chips,that will break if you bend
114 | them more than 2 times.(if they do,you even need to open 115 | the chip itself and this is REALLY tricky,trust me 116 | >:-[ )
117 |
118 | ok,you should do it like this:
119 | open both n64 (how to build a nintendo screwdriver is 120 | explained in the cheap mod guide).
121 | now you have 2 choices:
122 | take out the PIF-NUS of a pal n64(use a needle and a 123 | soldering iron to lift up the pins) and solder it 124 | directly onto the ntsc-pif,but i cant recommend this 125 | one,cause its very likely that you break a pin.
126 | for me,the best choice was to desolder both,the ntsc and 127 | the pal PIF-NUS,solder both on seperate pcb ( you can buy 128 | readymade boards for all kinds of smd-chips in your fav 129 | electronic store) and run wires from these pcbs.that 130 | means you arent in danger of breaking any pins on the 131 | PIFs,cause these little babys are worth a whole n64,you 132 | know ;)

133 |


136 | once this is done,run wires from a pifs pins that are 137 | marked green on the pic to their equivalent pins on the 138 | other pif and the pcb(bad explanation,sorry ;)
139 | for example you run a wire from PIF(P)-NUS pin 1 to pin 1 140 | of PIF-NUS and to pin 1 on the pcb,so all pin 1s are 141 | hooked up together.
142 | run wires from the pins marked white to ground somewhere 143 | on the n64 board.
144 | the other pins running from pif-nus and pif(P)-nus are 145 | connected to the pcb via a relais and a 2 way switch(or a 146 | jk flip flop + button if ur cool dude ;)

147 |

to switch all lines at once 149 | (theres no relais in the diagram coz i was too lazy,but u 150 | know how to wire them lines up ;)

151 |

so you can decide if the n64 153 | uses the pins of the pal or the ntsc pif.

154 |

the pink pins on the pcbs are 156 | not connected.
157 |
158 | thats it, you are done now.
159 | mail me for further questions :)

160 |

btw,since your pal n64 is not 162 | working anymore,you can send it to nintendo of europe

163 |

and tell them to fix it,it 165 | isnt expensive.

166 |


168 |
169 | always remember,this mod was invented by ME(i searched 170 | the whole net and didnt find anything like this,perhaps 171 | something similar exist somewhere,but this mod is 100% 172 | from my brain ;)
173 | if you wanna put it on your page,you are free to do so,as 174 | long as you inform me and GIVE
175 | ME FULL CREDITS ;)
176 | ohh,and of course i'm in no way responsible if you damage 177 | your n64 or something.
178 |

179 |
182 |
183 | 184 | 185 | -------------------------------------------------------------------------------- /lockout/n64securitychipmodmm6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/lockout/n64securitychipmodmm6.jpg -------------------------------------------------------------------------------- /mips/007-2489-001.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/007-2489-001.pdf -------------------------------------------------------------------------------- /mips/007-2597-001.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/007-2597-001.pdf -------------------------------------------------------------------------------- /mips/007-2816-004.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/007-2816-004.pdf -------------------------------------------------------------------------------- /mips/007-2816-005.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/007-2816-005.pdf -------------------------------------------------------------------------------- /mips/Errata R4000-R4400 Microprocessor users manual 2nd edition.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/Errata R4000-R4400 Microprocessor users manual 2nd edition.pdf -------------------------------------------------------------------------------- /mips/MIPS-N32-ABI-Handbook.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/MIPS-N32-ABI-Handbook.pdf -------------------------------------------------------------------------------- /mips/R4300_datasheet.Rev0.3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/R4300_datasheet.Rev0.3.pdf -------------------------------------------------------------------------------- /mips/R4300i_Prod_Ov.ps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/R4300i_Prod_Ov.ps.gz -------------------------------------------------------------------------------- /mips/U10116EJ6V0DS00.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/U10116EJ6V0DS00.pdf -------------------------------------------------------------------------------- /mips/U10116EJ7V0DS00.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/U10116EJ7V0DS00.pdf -------------------------------------------------------------------------------- /mips/mips-isa.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/mips-isa.pdf -------------------------------------------------------------------------------- /mips/tutorial/InstructionSets3.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/tutorial/InstructionSets3.PDF -------------------------------------------------------------------------------- /mips/tutorial/data.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/tutorial/data.pdf -------------------------------------------------------------------------------- /mips/tutorial/mips_instructions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/mips/tutorial/mips_instructions.pdf -------------------------------------------------------------------------------- /misc/Nintendo_64_Game_Console-BPT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/misc/Nintendo_64_Game_Console-BPT.pdf -------------------------------------------------------------------------------- /misc/bootcode_start_addresses.txt: -------------------------------------------------------------------------------- 1 | Start address of program needs to be modified per program: 2 | 3 | 6101 : ??????? (for now N64CICC doesen't change the EP adress) 4 | 6102 : nothing 5 | 6103 : Add $100000 ($80000400 would be $80100400 instead) 6 | 6105 : nothing 7 | 6106 : Add $200000 ($80000400 would be $80200400 instead). 8 | 9 | To disassembly existing bootcode: 10 | n64-objdump -b binary -m mips -EB -D boot/6105 11 | 12 | -------------------------------------------------------------------------------- /misc/eeprom.txt: -------------------------------------------------------------------------------- 1 | As everybody knows (?) the standard 512 bytes EEPROM has 2 2 | commands,allowing read and write of the data: 3 | 4 | user -> 0x04 5 | eeprom -> <8 bytes> 6 | 7 | which reads 8 bytes from the page . 8 | 9 | user -> 0x05 <8 bytes> 10 | eeprom -> 11 | 12 | which writes 8 bytes to the page . 13 | 14 | Now, with the 512bytes eeprom, the page ranges from 0 to 63; 15 | technically the allows for up to 256 pages which would mean 16 | 2048 bytes -- the size of the "larger" eeprom... Is this the case? 17 | That is a 2K eeprom behaves like the 512Bytes, with more pages or it 18 | has a different command set? 19 | 20 | The eeprom also responds to the 0x00 command with the 21 | status 0x00 0x80 0x00. The 2k eeprom does the same? 22 | 23 | You just need a scope and some patience, if you have a logic analyzer 24 | is even easier (I don't have that...). The EEPROM protocol is very 25 | simple and not very fast, so it's easy to follow (being a synchronous 26 | protocol you also have the triggering clocks...) 27 | 28 | The EEPROM is accessed thru the memory like the controller pads, 29 | but I have never understood how you address the eeprom (the joypads 30 | are addressed by the offset inside the pif memory)... 31 | 32 | 33 | Well, the PIF memory is located at 1FC007C0. To find the instructions which write this, you can search for LUI reg,1FC0, which is coded as 3Cxx1FC0 in hex. I will point out that that particular sequence (3Cxx1FC0) appears 6 times in Mario64 and 5 times in Pod Racer, so it should not be hard to locate the relevent sections of code and disassemble it to see how it works. 34 | 35 | -- 36 | yes that means u can write a max of 2048 bytes. but i think most eeproms are 1024 or 512. not sure about that. But these larger chips return a status of 00c0000 instead of 008000. 37 | As for mempack eeprom, contact me on efnet and i'll try to explain it. 38 | -LaC- 39 | -------------------------------------------------------------------------------- /misc/mipscheck.manpage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SGI TPL View (mipscheck) 6 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 | 42 | 43 | 44 | 45 | 63 | 64 | 65 | 66 | 68 | 69 | 70 | 71 | 77 |
www.sgi.com 46 | 47 | 48 | 49 | 56 | 60 | 61 |
62 |
[Products][Industries][Developers][Support][Serious Fun]
78 |
79 | 80 | 81 | 82 | 83 | 84 |
SGI Techpubs Library
85 | 86 |

IRIX 6.5  »  Man Pages
find in page

87 | 88 | 109 | 110 |

111 |

112 | MIPSCHECK(1)
113 | 
114 |  NAME
115 | 
116 |      mipscheck, r8kpp, r5kpp, u64check - Examines binaries for instruction
117 |      sequences
118 | 
119 |  SYNOPSIS
120 | 
121 |      mipscheck [-v]  [-condition[:action...] ... ] files
122 | 
123 |      r8kpp [-v]  [-condition[:action...] ... ] files
124 | 
125 |      r5kpp [-v]  [-condition[:action...] ... ] files
126 | 
127 |      u64check [-v]  [-condition[:action...] ... ] files
128 | 
129 |  DESCRIPTION
130 | 
131 |      mipscheck examines binaries for instruction sequences that may have
132 |      processor specific behavior.  It reports which conditions it found,
133 |      and in certain cases, will modify the sequence so that the binary
134 |      behaves consistently on all platforms.  On exit, mipscheck returns an
135 |      exit status which is the number of occurrences of the specified
136 |      condition(s) found.
137 | 
138 |      The -v option generates verbose output, including the address of each
139 |      problem found.
140 | 
141 |      Specifying mipscheck operates on object files, archives files,
142 |      executables, and DSOs.  Specifying r8kpp, r5kpp, u64check are
143 |      alternative ways of invoking mipscheck which imply default values
144 |      designed specifically for the specified architecture.
145 | 
146 |    Conditions
147 |      -pref[:action...]   Look for and remove prefetch instructions.
148 | 
149 |                          The pref and prefx prefetch instructions are part
150 |                          of the mips4 instruction set.  They are fully
151 |                          implemented on the r10000 and the r5000 but are
152 |                          not supported on r8000 based machines.  See the
153 |                          r8000 errata sheet for more details.
154 | 
155 |                          The default actions are:  -
156 |                          pref:check:noforce:repair
157 | 
158 |      -mfhilo[:action...] Look for instructions that reference the HI or LO
159 |                          registers and are one or two instructions after a
160 |                          mfhi or mflo instruction.
161 | 
162 |                          The mips1, mips2, and mips3 instruction sets
163 |                          specify that there is a two instruction hazard
164 |                          between a mflo instruction and a following
165 |                          instruction that references the LO register.  This
166 |                          hazard was removed from the mips4 instruction set
167 |                          (that is, it was up to the processor to supply the
168 |                          hardware interlock).  The r8000 and the r10000
169 |                          have this hardware interlock but the r5000 does
170 |                          not; this requires the compiler to continue to
171 |                          enforce the scheduling hazard.
172 | 
173 |                          It is possible that Irix 6.1 64bit binaries may
174 |                          have this relaxed instruction scheduling sequence.
175 |                          As of Irix 6.2, all SGI compilers generate code
176 |                          that does not depend upon the processor handling
177 |                          the hardware interlock, but rather the compilers
178 |                          schedule the instructions to avoid it.  See the
179 |                          r5000 errata sheet for more details.
180 | 
181 |                          The default actions are:  -
182 |                          mfhilo:check:noforce:norepair
183 | 
184 |      -cvtl[:action...]   Look for cvt.s.l and cvt.d.l instructions.  These
185 |                          instructions convert 64-bit integers to single or
186 |                          double floating point format.
187 | 
188 |                          Revision [1.1] of the r5000 can misexecute cvt.s.l
189 |                          and cvt.d.l instructions when the 64-bit integer
190 |                          input data is in either of the following ranges:
191 | 
192 |           0x7FF0 0000 0000 0000    to    0x7FFF FFFF FFFF FFFF
193 |           0x8000 0000 0000 0000    to    0x800F FFFF FFFF FFFF
194 | 
195 |                          When input data is in the preceding ranges, these
196 |                          instructions are supposed to trap into the kernel
197 |                          where they will be emulated in software.
198 |                          Unfortunately, they do not trap and they generate
199 |                          an incorrect result.  These instructions are
200 |                          fairly rare and are found in mips3 and mips4
201 |                          executables only; they are never in mips1 or mips2
202 |                          programs.  There is a work-around for this
203 |                          problem, implemented entirely within the operating
204 |                          system kernel, which should be invisible to all
205 |                          user programs.  See the r5000 errata sheet for
206 |                          more details.
207 | 
208 |                          The default actions are:  -
209 |                          cvtl:check:noforce:norepair
210 | 
211 |      -fmulmul[:action]   Look for a floating point multiply immediately
212 |                          followed by a floating point or integer multiply.
213 | 
214 |                          Very early versions of the r4300 (used only in the
215 |                          Nintendo Ultra64 Game Player) could mis-execute
216 |                          the second multiply instruction when the first
217 |                          multiply encountered a NaN or an Infinity operand.
218 |                          See the r4300 errata sheet for more details.
219 | 
220 |                          The default actions are:  -
221 |                          fmulmul:check:noforce:norepair
222 | 
223 |      -idivmul[:action]   Look for integer divides and multiplies in
224 |                          branch-delay slots or preceding a branch-target.
225 | 
226 |                          On the r10000, under extremely rare conditions, if
227 |                          an integer multiply or integer divide is
228 |                          interrupted, the EPC (Exception Program Counter)
229 |                          will point to the instruction following the
230 |                          multiply/divide and the HI register will not be
231 |                          updated.  There is a work-around for this problem
232 |                          implemented entirely within the operating system
233 |                          kernel, which should be invisible to all user
234 |                          programs.  See the r10000 errata sheet for more
235 |                          details.
236 | 
237 |                          The default actions are:  -
238 |                          idivmul:check:noforce:norepair
239 | 
240 |    Actions
241 |      Each condition has an optional colon (:) separated list of actions
242 |      associated with it.  action can be any of the following:
243 | 
244 |      check          Check for the specified condition (default action).
245 | 
246 |      nocheck        Do not check for the specified condition.
247 | 
248 |      force          Examine the instruction sections for the condition even
249 |                     if mipscheck has other means of determining that the
250 |                     condition does not exist.  For example, an instruction
251 |                     sequence involving mips4 instructions could not exist
252 |                     in a mips3 executable.  force instructs mipscheck to
253 |                     search for the condition anyway.
254 | 
255 |      noforce        Do not examine the instruction sequences unless
256 |                     necessary (default action).
257 | 
258 |      repair         Modify the instruction sequence so that it does not hit
259 |                     the specified condition.  This action is valid only
260 |                     with the -pref condition.
261 | 
262 |      norepair       Do not modify the code (default action).
263 | 
264 |      If a condition is specified with no actions, mipscheck assumes the
265 |      default actions.  For example, specifying -mfhilo is equivalent to
266 |      -mfhilo:check:noforce:norepair.
267 | 
268 |    Unexpected Behaviors
269 |      The -fmulmul option may give a false positive in the case of a
270 |      floating point multiply instruction in a branch delay slot.  The
271 |      mipscheck program does not look at the target of the branch and so
272 |      must assume that the branch target may be another multiply
273 |      instruction.
274 | 
275 |      The -pref:force option will almost always give false positives because
276 |      it will report on every prefetch instruction found instead of just the
277 |      combinations of prefetches that can lead to mis-execution on an r8000.
278 | 
279 |      Because mipscheck cannot examine input data for data-dependent
280 |      problems, it must report on instruction sequences that may fail under
281 |      the proper conditions.  For example, mipscheck will report all cvt.d.l
282 |      instructions, not just the ones that may get bad input data.
283 | 
284 |      Similarly, because mipscheck cannot know about tlb-miss and cache-miss
285 |      behavior, it must report on instruction sequences that might trigger
286 |      the r4000 branch-at-end-of-page problem even though the actual
287 |      conditions required to hit it are quite rare.
288 | 
289 |  NOTES
290 | 
291 |      "Is this anything to be concerned about?"  is a valid question.  In
292 |      general, the answer is no.  But SGI developers and some customers who
293 |      have access to early revisions of systems may need this tool to help
294 |      identify and/or repair problems.  The following are some relevant
295 |      cases:
296 | 
297 |      1. Irix 6.1 binaries compiled with -n32 -mips4 that are moved to an
298 |         r5000 system should be checked with r5kpp. There should be no such
299 |         binaries in the field; but because experimental systems and
300 |         experimental compilers were available, it is possible that such
301 |         binaries exist.
302 | 
303 |      2. The Irix 6.2 (and later) operating systems for r8000s will
304 |         automatically patch any running program to remove the prefetch
305 |         instructions.  This will not affect the performance on an r8000 but
306 |         it will avoid the r8000 prefetch problem.  In rare cases, the
307 |         kernel will not be able to avoid the problem and will request that
308 |         the user run the binary through r8kpp to execute the repair
309 |         permanently.
310 | 
311 |      3. Ultra64 game developers should always run u64check to locate cases
312 |         where their assembly code violates the game player's hardware
313 |         restrictions.
314 | 
315 |      4. Irix 6.2 binaries compiled using -mips3 or -mips4, using 64-bit
316 |         integers, and running on Revision [1.1] of the r5000 may, in rare
317 |         cases, encounter the cvtl problem.  The kernel handles this case
318 |         but incurs a small overhead for checking on this condition.  The
319 |         overhead should be negligible.  If r5kpp finds no problem in an
320 |         executable, it will mark the executable as "clean", which helps the
321 |         kernel eliminate the overhead.
322 | 
323 |      5. On all MIPS processors, when an instruction is interrupted, the EPC
324 |         (Exception Program Counter) points to the interrupted instruction.
325 |         The exception to that rule is when the interrupted instruction is
326 |         in a branch-delay slot, in which case the EPC points to the
327 |         previous branch instruction.  On an r10000, if the kernel ever
328 |         detects a "bad" EPC for an interrupted integer multiply or integer
329 |         divide, the kernel will silently (and at no measurable performance
330 |         cost) repair the EPC  and the damaged HI register.  If the
331 |         interrupted instruction is in a branch-delay slot of an
332 |         unconditional branch, the kernel may not be able to repair the EPC
333 |         and will abort the program, reporting the result in the SYSLOG.
334 | 
335 |      To make it easier for the kernel to detect and repair the EPC in these
336 |      cases, the compiler will not put an integer multiply or divide in a
337 |      branch delay slot of an unconditional branch, nor will it make the
338 |      following instruction a branch target.  Versions 6.2 through 7.2 of
339 |      the SGI compilers occasionally break these rules when generating code
340 |      -mips4.  This is not a problem but it makes it more difficult for the
341 |      kernel to detect and repair the problem.  Compiler versions 7.2.1 and
342 |      later always obey these two rules.
343 | 
344 |  EXIT CODES
345 | 
346 |      mipscheck terminates with an exit code set to the number of conditions
347 |      found.  For example, if it found 10 -mfhilo problems, it would
348 |      terminate with an exit code of 10.  In the case of r8kpp, this may be
349 |      a little misleading because the command has not only found each of the
350 |      problem conditions but it has repaired them as well.  If you were to
351 |      run r8kpp on the binary a second time, no conditions would be reported
352 |      because the binary has been patched.
353 | 
354 |  EXAMPLES
355 | 
356 |      The following example shows how to build a mips4 binary and verify
357 |      that there are no prefetch instructions:
358 | 
359 |           % cc -mips4 -n32 -o bean bean.c
360 |           % mipscheck -pref:check:norepair bean
361 |           % echo $status
362 | 
363 |      The following example shows how to compile a file to be linked into an
364 |      Ultra64 Game program and verify that there are no dangerous multiply
365 |      pairs:
366 | 
367 |           % cc -mips2 -32 -c bean.c
368 |           % mipscheck -fmulmul:check:norepair bean.o
369 |           % echo $status
370 | 
371 |      This example examines the location of the cvtl problem(s) in the
372 |      /bin/sh program.
373 | 
374 |           % mipscheck -v -cvtl:check:norepair:force /bin/sh
375 |           mipscheck [1.6]
376 |           /bin/sh: r5000 cvt.d.l cvt.s.l  problem at 0x100138d0
377 |           cvtl found   : 1
378 | 
379 |      By invoking r8kpp, you are specifying that all r8000 specific
380 |      conditions should be checked for and repaired.  This is equivalent to
381 |      specifying the following:
382 | 
383 |           % mipscheck -pref:check:noforce:repair  myprog
384 | 
385 |      By invoking r5kpp, you are specifying that all r5000 specific
386 |      conditions should be checked for and reported.  This is equivalent to
387 |      specifying the following:
388 | 
389 |           % mipscheck -mfhilo:check:noforce:norepair  \
390 |                  -cvtl:check:noforce:repair myprog
391 | 
392 |      By invoking u64check, you are specifying that all r4300 specific
393 |      conditions should be checked for and reported.  This is equivalent to
394 |      specifying the following:
395 | 
396 |           % mipscheck -fmulmul:check:noforce:norepair  myprog
397 | 
398 |  FILES
399 | 
400 |      /usr/sbin/mipscheck   mipscheck executable
401 | 
402 |      /usr/sbin/r8kpp       Symbolic link to /usr/sbin/mipscheck
403 | 
404 |      /usr/sbin/r5kpp       Symbolic link to /usr/sbin/mipscheck
405 | 
406 |      /usr/sbin/u64check    Symbolic link to /usr/sbin/mipscheck
407 | 
408 |  SEE ALSO
409 | 
410 |      elfdump(1)
411 | 
412 |      http://www.mips.com for information on chips.
413 | 
414 | 
415 | 
416 | 
417 |

418 | 419 |


420 | 421 |

422 | 423 | 424 | home/search | 425 | what's new | 426 | feedback | 427 | help 428 | 429 | 430 |
431 |

432 | 433 |

434 | 435 | terms of use | 436 | privacy policy | 437 | contact us | 438 | Copyright © 1993-2004 Silicon Graphics, Inc. All rights reserved. | 439 | trademark information 440 | 441 | 442 |
443 | 444 | 445 |
446 | 447 | 448 | 449 | 462 | 463 | 471 |
450 | Please rate this page:
451 | Excellent 452 |
453 | Above Average 454 |
455 | Average 456 |
457 | Below Average 458 |
459 | Poor 460 |
461 |
  464 | 465 | What would make this page or web site better?
466 | 467 |
468 | 469 |
470 |
472 |
473 | 474 |
475 |

476 | 477 | 478 | 479 | 480 | -------------------------------------------------------------------------------- /misc/n64_dma_pathways.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/misc/n64_dma_pathways.dia -------------------------------------------------------------------------------- /misc/n64dox-0.5.txt: -------------------------------------------------------------------------------- 1 | LaC's n64 hardware dox... v0.5 (public release) 2 | 3 | --------------- 4 | release notes 5 | --------------- 6 | This little doc is my attempt to make the n64 coding scene a little 7 | better I hope. It is a compilation of stuff i've been working on for some 8 | months... a result of alot of reversing of several games compiled with 9 | libultra, and some help from certain people. It is mainly for people who 10 | wish to code without using a developement library (like libultra). It is 11 | specfically for doing intros,trainers, etc... to attach to roms. It is very 12 | simplistic, and assumes you have some knowledge already. In other words this 13 | doc isnt really meant for people just starting. You should probably have read 14 | the libultra docs and be familiar with the n64 hardware... and the purpose of 15 | things like the AI,PI,SI,VI etc... 16 | I suppose some emulation author could find use of this too. 17 | Some people will probably be mad I released this doc, but I guess since 18 | nothing is really happening in the n64 scene it might get things moving? 19 | Especially from people that really want to hack. Also I have noticed some 20 | really crappy and inaccurate info being released which basically looks like 21 | stuff ripped from czn intros or something and contains no real knowledge. Yes 22 | all you freedom of information people... you want info... hack it yourself. 23 | Or read this doc, then hack some more ;) 24 | Also I can't guarantee the 100% accuracy of any of this document. Also I liked 25 | to be greeted if you are using my dox or my source code in your work. 26 | 27 | NOTE: 28 | SOME symbols in the follow text will reference symbols #define'd in RCP.H 29 | or r4300.h so make sure you look there when you are confused. Yes I know t 30 | hey are part of the standard devkit and some people dont have it... but i'm 31 | sure you can find these files if you really need to. 32 | 33 | -VI (video interface) 34 | 35 | Accessing the video on the n64 is very easy (like most things in this doc) 36 | 37 | * initialization: 38 | The video hardware is initialized by simply writing all the necessary 39 | values to the vi regs. I'm only going to discuss one mode here, but u 40 | can easily find the values for other modes by just printing out reg 41 | values to the screen after initing your favorite mode with libultra. 42 | You can also alter values of course to make your own modes. That I will 43 | not discuss here. The one i'm discussing is the simple 320x240 RGBA 44 | 16bit non-antialiasing mode. 45 | 46 | The base address of the VI regs are mapped at 0xa4400000, so to simply 47 | write a value to a reg in r4300 asm would be like this: 48 | ;;this is just an example but it happens to be the write to the 49 | ;;VI_H_WIDTH_REG defined in RCP.H 50 | lui at,0xa440 ;at=0xa4400000 51 | li t0,0x140 ;t0=0x140 52 | sw t0,0x8(at) ;write t0 to reg at $at+0x8 53 | 54 | in C: 55 | 56 | IO_WRITE(VI_H_WIDTH_REG,0x140); //IO_WRITE and IO_READ are in r4300.h 57 | 58 | Ok to initialize this mode here are the values to write for each reg: 59 | 60 | -> (VI_CONTROL_REG, 0x0000320e) 61 | -> (VI_DRAM_ADDR_REG,0) 62 | -> (VI_H_WIDTH_REG,0x140) 63 | -> (VI_V_INTR_REG,0x2) 64 | -> (VI_V_CURRENT_LINE_REG,0x0) 65 | -> (VI_TIMING_REG,0x03e52239) 66 | -> (VI_V_SYNC_REG,0x0000020d) 67 | -> (VI_H_SYNC_REG,0x00000c15) 68 | -> (VI_H_SYNC_LEAP_REG,0x0c150c15) 69 | -> (VI_H_VIDEO_REG,0x006c02ec) 70 | -> (VI_V_VIDEO_REG,0x002501ff) 71 | -> (VI_V_BURST_REG,0x000e0204) 72 | -> (VI_X_SCALE_REG,0x200); 73 | -> (VI_Y_SCALE_REG,0x01000400) 74 | 75 | All the values are pretty obvious and dont need much explaining. And with 76 | a little hacking you can come up with your own modes. 77 | 78 | If you've managed to get this far you know that the video screen is just 79 | showing zebra stripes or some garbage. The reason for this is you have 80 | not set the frame buffer for this video mode. This is what 81 | osViSwapBuffer() is for (if you have used libultra). to set your frame 82 | buffer simply write the rdram address of the buffer to VI_DRAM_ADDR_REG 83 | or just change the init code to have it set it up. 84 | Now you can simply write your graphics to the buffer and they'll be 85 | updated. 86 | 87 | NOTE: There is ALOT of other things you can tweek, change, by messing with 88 | the VI regs... mess around... figure it out. 89 | Also note that there can be cache problems with the video if you are using 90 | a virtual address like 0x80200000 in your VI_DRAM_ADDR_REG, try using the 91 | physical address 0xa0200000 instead or make sure you are writing back and 92 | invalidatiing the cache lines. if you are confused about physical and 93 | virtual addresses or how the cache works, read the r4300 man... and if you 94 | still don't understand it totally, join the club. 95 | 96 | * end init 97 | 98 | * vertical retrace wait: 99 | pseudo code: 100 | while ( VI_CURRENT_REG != 512 ) {wait} // I got this value from bpoint 101 | * end retrace wait 102 | 103 | -AI (audio interface) 104 | 105 | The audio interface is probably the easiest thing to do. 106 | 107 | * initialization: 108 | 109 | None needed. Altho I suppose you can include setting the sound frequency 110 | and/or enabling the AI_CONTROL_REG as initialization (step #4 below) 111 | 112 | * end init 113 | 114 | * setting frequency: 115 | 116 | 1. Set the dac rate 117 | write to AI_DACRATE_REG this value: (VI_NTSC_CLOCK/freq)-1 118 | ^could be pal 119 | 2. Set the bitrate (4bit, 8bit, or 16bit) 120 | write to the AI_BITRATE_REG the value: bitrate-1 121 | 122 | * end frequency 123 | 124 | * sending sound buffer 125 | 126 | 1. Before sending a buffer, its a good idea to make sure one isnt already 127 | being played. Simply read AI_STATUS_REG then AND it with 128 | AI_STATUS_FIFO_FULL. if the result is true... then wait. 129 | 130 | 2. Write the 64bit aligned address of the sound buffer to AI_DRAM_ADDR_REG 131 | 132 | 3. Write the length of the buffer be played to AI_LEN_REG 133 | NOTE: this length must be multiple of 8, no larger than 262144 bytes. 134 | 135 | 4. Write AI_CONTROL_DMA_ON to the AI_CONTROL_REG (only needed once) 136 | 137 | * end sound buffer 138 | 139 | NOTE: If you have read the libultra manuals you will notice when it 140 | discusses the AI routines (osAi.man) it says the AI regs are double 141 | buffered. This is important to realize that you can send one buffer 142 | while another is playing. Also note that the AI_LEN_REG counts down 143 | to 0 as the current buffer is being played. This can be useful to tell 144 | how much of the buffer is left. 145 | 146 | -PI (peripheral interface) 147 | 148 | * init pif: ( you should do this before you do anything! ) 149 | 150 | 1. Simply write 0x8 to PIF_RAM_START+0x3c 151 | 152 | * end init pif 153 | 154 | * PI DMA transfer 155 | 156 | 1. Wait for previous dma transfer to finish (see next explanation) 157 | 2. Write the physical dram address of the dma transfer to PI_DRAM_ADDR_REG 158 | NOTE: To convert from a virtual address to physical, simply 159 | AND the address with 0x1fffffff. 160 | 3. Write the physical cart address to PI_CART_ADDR_REG. 161 | 4. Write the length-1 of the dma transfer to PI_WR_LEN_REG 162 | this is from cart->rdram change this to RD ^ for the other way 163 | also note you must write a 0x2 to PI_STATUS_REG in order to write to 164 | the cart space (0xb0000000) 165 | NOTE: The cart addr must be 2 byte aligned, and the rdram addres must 166 | 8-byte aligned. Once again make sure you write back the cache lines 167 | and invalidate the cache lines if needed, or you will run into 168 | trouble. 169 | 170 | * end PI DMA transfer 171 | 172 | * PI DMA wait 173 | 174 | 1. Read PI_STATUS_REG then AND it with 0x3, if its true... then wait until 175 | it is not true. 176 | 177 | NOTE: Look at RCP.H for more information on the PI_STATUS_REG and the PI 178 | in general. 179 | 180 | 181 | * end PI DMA wait 182 | 183 | -reading and writing the new sram chip (DS1) - 184 | 185 | Sram is mapped at 0xa8000000. 186 | The trick is that you cannot write to it directly, you must us the PI. 187 | Actually it is possible to write to it directly, but I dont know how because 188 | it needs to be timed carefully. 189 | Its a little tricky which requires writing some values into some PI regs 190 | to initialize the PI correctly for the type of transfer protocol the sram 191 | needs for successful data transfer. 192 | 193 | * Init the PI for sram 194 | 195 | 1. write 0x05 to the PI_BSD_DOM2_LAT_REG. 196 | 2. write 0x0c to the PI_BSD_DOM2_PWD_REG. 197 | 3. write 0x0d to the PI_BSD_DOM2_PGS_REG. 198 | 4. write 0x02 to the PI_BSD_DOM2_RLS_REG. 199 | 200 | * End init PI for sram 201 | 202 | Now you should be able to use the PI to transfer between rdram and sram. 203 | (refer to the dox above concerning PI, but replace the ROM address with 204 | sram address 0xa8000000). 205 | 206 | 207 | -SI (serial interface) 208 | 209 | The SI is very similar to the PI for obvious reasons. It is used mainly for 210 | accessing the joyport and pifram... which will be dicussed in the next 211 | section. 212 | 213 | * SI DMA transfer 214 | 1. Wait for previous dma transfer to finish (see next explanation) 215 | 216 | 2. Write the physical dram address of the dma transfer to SI_DRAM_ADDR_REG 217 | 218 | 3. Write PIF_RAM_START to the SI_PIF_ADDR_RD64B_REG or the 219 | SI_PIF_ADDR_WR64B_REG, depending on what you wish to do (read or write). 220 | This will cause a 64B read or write between pif_ram and rdram. 221 | 222 | NOTE: The SI addr must be 2 byte aligned, and the rdram addres must 223 | 8-byte aligned. Once again make sure you write back the cache lines 224 | and invalidate the cache lines if needed, or you will run into 225 | trouble. 226 | 227 | * end SI DMA tranfer 228 | 229 | * SI DMA wait 230 | 231 | 1. Read SI_STATUS_REG then AND it with 0x3, if its true... then wait until 232 | it is not true. 233 | 234 | NOTE: Look at RCP.H for more information on the SI_STATUS_REG and the SI 235 | in general. 236 | 237 | * end SI DMA wait 238 | 239 | -PIF Usage- (controller reading/detection) 240 | 241 | If you have done research and peeked at the RCP.h file you should 242 | already know some things about the pif. The SI is used to send commands 243 | to the pif ram that tell the pif what to do. The SI is also used to read 244 | the results of those commands back. You can tell the pif to do alot of 245 | stuff. for instance... reading joysticks, reading mempacks, detecting 246 | joysticks, detecting mempacks, activating the rumblepack, detecting the 247 | rumble pack, reading cartridge eeprom... etc. In this version of the 248 | document I will only cover reading joysticks and detection. 249 | 250 | Below is a very brief and not so detailed view of pif command structure 251 | and an example of using them to perform some operations. 252 | 253 | first this is how pif ram is setup: 254 | 255 | [64byte block] at 0xbfc007c0 (1fc007c0) 256 | { command data recv 257 | channel 1 - 00 00 00 00 : 00 00 00 00 - 8 bytes 258 | channel 2 - 00 00 00 00 : 00 00 00 00 - 8 bytes 259 | channel 3 - 00 00 00 00 : 00 00 00 00 - 8 bytes 260 | channel 4 - 00 00 00 00 : 00 00 00 00 - 8 bytes 261 | channel 5 - 00 00 00 00 : 00 00 00 00 - 8 bytes 262 | 00 00 00 00 : 00 00 00 00 - 8 bytes (dummy data) 263 | 00 00 00 00 : 00 00 00 00 - 8 bytes (dummy data) 264 | 00 00 00 00 : 00 00 00 00 - 8 bytes (dummy data) 265 | } ^^pif status control byte 266 | 267 | This is how you should visualize it for operations I describe below. For 268 | other stuff it is setup differently... but in all cases it is just 269 | 64 bytes. 270 | 271 | Each channel can contain a command in the first 4 bytes (the left column). 272 | 273 | Each command has a structure like so: 274 | 275 | byte 1 = 0xff for new command | 0xfe for end of commands 276 | byte 2 = number of bytes to send 277 | byte 3 = number of bytes to recieve 278 | byte 4 = Command Type 279 | 280 | Command Types: 281 | 282 | 00 = get status 283 | 01 = read button values 284 | 02 = read from mempack 285 | 03 = write to mempack 286 | ff = reset controller 287 | 04 = read eeprom 288 | 05 = write eeprom 289 | 290 | Here is an example on how to build a command for reading a joystick: 291 | 292 | * Init the joysticks for reading 293 | 294 | send the pif command block to pif_ram using the SI DMA 295 | -----------------------------++------------------------------ 296 | such a block to read 4 joys: || such a block to read 1 joy: 297 | [64byte block] || [64byte block] 298 | { command data || { 299 | joy1 ff010401 - ffffffff || joy1 ff010401 - ffffffff 300 | joy2 ff010401 - ffffffff || 00000000 - ffffffff 301 | joy3 ff010401 - ffffffff || 00000000 - ffffffff 302 | joy4 ff010401 - ffffffff || 00000000 - ffffffff 303 | fe000000 - 00000000 || fe000000 - 00000000 304 | 00000000 - 00000000 || 00000000 - 00000000 305 | 00000000 - 00000000 || 00000000 - 00000000 306 | 00000000 - 00000001 || 00000000 - 00000001 307 | } || } 308 | ----------------------------++------------------------------ 309 | after sending this the joystick values will now be updated in pif RAM 310 | NOTE: make sure you put the ffffffff in the data column, otherwise it 311 | will cause errors. 312 | 313 | ff010401 is the command that reads the joystick values. 314 | | 315 | ff is basically a flag for a new command. 316 | 01 says we are going to send 1 byte (the command type). 317 | 04 says we are going to read 4 bytes (into the data column) 318 | 01 is the command type (read button values). 319 | 320 | You will notice the 5th channel command is fe, this command signals 321 | the end of the command block. The 00000001 tells the pif there is a new 322 | command block to be processed. Without this the command block will not 323 | be executed. 324 | 325 | * end Init joysticks 326 | 327 | 328 | * Read Joysticks 329 | The joy values can be read from the spaces marked by 0xFFFFFFFF in the 330 | block above. Of course you must first DMA from pif ram back to rdram. 331 | Or you can just read the data directly by making a pointer to 332 | 0xbfc007c0 (start of the pif_ram), although I would not recommend that 333 | method. 334 | Here would be a sufficient C code to read in a controller's values: 335 | 336 | void siReadJoy(int cont,OSContPad *p) 337 | { 338 | unsigned char pif_block[64]; 339 | si_DMA_from_pif (pif_block); 340 | memcpy (p,pif_block+((cont*8)+4),4); 341 | } 342 | 343 | The OSContPad structure is in the libultra header file OS.H 344 | 345 | * end Read Joysticks 346 | 347 | * Detecting if Joysticks are connected 348 | 349 | This is very easy and can be done after you send any command to read 350 | or write something to the controllers. Whenever you try and execute a 351 | command on a channel and that device on the channel (like a joystick) 352 | is not present the pif will write an error value to the command column 353 | that the error occured in. For instance... lets say you did the example 354 | above and you tried to read controller values. Well if you tried to 355 | read the controller values for all four joystick channels you will 356 | notice that if you don't have a joystick physically plugged in to the 357 | port(s) you are reading from, then no values will appear. Well I think 358 | this is an obvious result. But also notice that the pif will put an 359 | error value into the upper 4 bits of the 3rd byte in the command column. 360 | 361 | The Error values are as follows: 362 | 363 | 0 - no error, operation successful. 364 | 8 - error, device not present for specified command. 365 | 4 - error, unable to send/recieve the number bytes for command type. 366 | 367 | 368 | This would be an example of the result of trying to read 4 controllers 369 | (like in above example) and only a joystick in port 3 is connected: 370 | 371 | -----------------------------------+ 372 | [64byte block] read from pif ram | 373 | { command data | 374 | joy1 ff018401 - ffffffff <--- 8 is the error code for device 375 | joy2 ff018401 - ffffffff | not present. 376 | joy3 ff010401 - 00000000 <--- read was successful on this 377 | joy4 ff018401 - ffffffff | channel, no buttons being pressed 378 | fe000000 - 00000000 | 379 | 00000000 - 00000000 | 380 | 00000000 - 00000000 | 381 | 00000000 - 00000000 | 382 | } | 383 | -----------------------------------+ 384 | 385 | This would be an example of the result of trying to read 5 bytes for the 386 | read joystick command: (all 4 joysticks are connected) 387 | 388 | -----------------------------------+ 389 | [64byte block] sent to pif ram | 390 | { command data | 391 | joy1 ff010501 - ffffffff <--- 392 | joy2 ff010501 - ffffffff <--- note we tried to read 5 instead 393 | joy3 ff010501 - ffffffff <--- of 4. The device only allows you 394 | joy4 ff010501 - ffffffff <--- to read 4 bytes with that command 395 | fe000000 - 00000000 | 396 | 00000000 - 00000000 | 397 | 00000000 - 00000000 | 398 | 00000000 - 00000001 | 399 | } | 400 | -----------------------------------+ 401 | -----------------------------------+ 402 | [64byte block] read from pif ram | 403 | { command data | 404 | joy1 ff014501 - 00000000 <--- (note that no buttons are being 405 | joy2 ff014501 - 00000000 <--- pressed on any controller) 406 | joy3 ff014501 - 00000000 <--- notice the 4. It is the error 407 | joy4 ff014501 - 00000000 <--- code for send/recieve. 408 | fe000000 - 00000000 | 409 | 00000000 - 00000000 | 410 | 00000000 - 00000000 | 411 | 00000000 - 00000000 | 412 | } | 413 | ----------------------------------+ 414 | 415 | NOTE: Even though we tried to read an extra byte for the buttons values 416 | the button values will still appear... but the error code will 417 | still be generated because there is only 4 bytes to be read, not 418 | 5. 419 | 420 | * end Detecting if Joysticks are connected 421 | 422 | * Getting controller status 423 | 424 | ff010300 is the command used to get the controller status. 425 | | 426 | ff is basically a flag for a new command. 427 | 01 says we are going to send 1 byte (the command type). 428 | 03 says we are going to read 3 bytes (into the data column) 429 | 00 is the command type (get controller status). 430 | 431 | Here is and example of reading the status from 4 controllers 432 | Only the first two controllers are actually plugged in. 433 | There is a pack in the 1st controller and there is no pack in the second 434 | controller. 435 | 436 | -----------------------------------+ 437 | [64byte block] sent to pif ram | 438 | { command data | 439 | joy1 ff010300 - ffffffff | 440 | joy2 ff010300 - ffffffff | 441 | joy3 ff010300 - ffffffff | 442 | joy4 ff010300 - ffffffff | 443 | fe000000 - 00000000 | 444 | 00000000 - 00000000 | 445 | 00000000 - 00000000 | 446 | 00000000 - 00000001 | 447 | } | 448 | -----------------------------------+ 449 | -----------------------------------+ 450 | [64byte block] read from pif ram | 451 | { command data | 452 | joy1 ff010300 - 050001ff <--- notice only 3 bytes were read 453 | joy2 ff010300 - 050002ff <--- that is why the last byte is 454 | joy3 ff018300 - ffffffff | still ff 455 | joy4 ff018300 - ffffffff | 456 | fe000000 - 00000000 | 457 | 00000000 - 00000000 | 458 | 00000000 - 00000000 | 459 | 00000000 - 00000000 | 460 | } | 461 | ----------------------------------+ 462 | 463 | The first two bytes in the data column is the controller type. I'm not 464 | exactly sure what use this is... do steering wheels have a different 465 | controller type? ;) I dunno. 466 | The 3rd byte is useful. Its for detecting if there is something plugged 467 | into the mempack slot on the controller. 468 | 1 = pack present 469 | 2 = nothing plugged in 470 | 471 | * end Getting controller status 472 | 473 | * reading/writing cart eeprom 474 | 475 | COMING NEXT RELEASE 476 | 477 | * end reading/writing cart eeprom 478 | 479 | * reading/writing mempack eeprom 480 | 481 | COMING NEXT RELEASE 482 | 483 | * end reading/writing mempack eeprom 484 | 485 | 486 | 487 | -------- 488 | Future 489 | -------- 490 | I know this document isnt much as it stands but I plan on adding some rsp 491 | info into it and of course any other info I currently havent included as time 492 | permits. 493 | Also all my source code for the stuff in this doc might get released. 494 | but right now everything is meant to build with SN's assembler and linker. i 495 | wish to recode it so it compiles with a freeware assembler... so once I do 496 | that I will release source... or maybe before ;) 497 | 498 | __-----------------------------------------------__ 499 | greets to people who helped me with some stuff! 500 | __-----------------------------------------------__ 501 | 502 | nagra, bpoint, hartec, jovis, wild_fire, datawiz 503 | 504 | 505 | 506 | Questions & Comments: about anything except where to get a devkit or libultra 507 | or roms or header file or whatever. In other words if you have a question 508 | about stuff in this doc and you are fairly intelligent, or you have a question 509 | about how to implement things in your n64 program or emulator... 510 | 511 | contact LaC on IRC efnet in #n64dev 512 | or if you must: 513 | 514 | EMAIL: LaC@dextrose.com 515 | 516 | 517 | 518 | -EOF- 519 | -------------------------------------------------------------------------------- /misc/trainer.txt: -------------------------------------------------------------------------------- 1 | __/\__ 2 | ___\ /___ 3 | :_) (_: 4 | | | . 5 | | +{N64}+ | | 6 | | | _. . thE LiGhtFoRCE - FAStER thAN LiGht . 7 | | ____ | .___)| siNce 1987 8 | : ______ \__/ :______ | |____ ____ _________ __ ________ _____ ______ 9 | . \ /_____./ __/__| | _| \.) __/ _ \_ / _/ __/_ 10 | . / / | _) | _ \_ | _/ \ / /. \_. _/ | 11 | : \__________|____\ ___|____| |_____|____|________\_____|______|_______| 12 | | : \/ -Mo!/aL|____|[C O N S O L E D I V I S I O N] 13 | | | 14 | | | How to make a N64 Trainer Documentation by: 15 | |_ _| >>>>> Icarus <<<<< 16 | : )___ ___( : 17 | /_ _\ 18 | \/ 19 | 20 | 21 | Ladies and gentleman, 22 | Welcome to my "How to make a N64-Trainer" documentation. 23 | 24 | The reason why i did this doc is very simple: i am quitting 25 | all my activities in the "n64-scene" for many reasons, i think 26 | you don't care for so i won't go into that any further. 27 | Furthermore it would be nice to see more groups doing trainers. 28 | So i hope this will help some dudes to start! 29 | 30 | So however, let's come to the real documentation. 31 | 32 | First i want to explain how my trainers are working.. 33 | I think you all know the hardware game-enhancers like 34 | "Action Replay", "Gameshark", "Gamebuster" and so on... 35 | with this hardware stuff you can enter codes like this e.g.: 36 | 37 | 8003567C 0067 38 | 39 | 40 | If YES i will explain what the fuck this codes mean: 41 | Explanation: 42 | ~~~~~~~~~~~~ 43 | 8003567C 0067 <-- Value to be written 44 | ~~~~~~~~ **** 45 | ^ 46 | | 47 | Memorylocation in N64 RAM 48 | 49 | If you enter such a code the Gameshark hardware or whatever 50 | will do the following: It updates the MEMORYLOCATION with 51 | the VALUE very often (don't know exactly how often i a second 52 | but this doesn't matter now! :-) ) 53 | 54 | And exactly this is how my trainers work. So in a strictly 55 | definition my trainers are no REAL trainers, like i did them 56 | on e.g. the Amiga. On Amiga for example it was better to 57 | find the ROUTINE in the GAMECODE which was responsible for 58 | subtracting your Lives or Health etc.. and once you found 59 | this routine, you had the possibility to kill it with a NOP 60 | or something.. 61 | 62 | On N64 you can say its emulating a Gameshark. 63 | Unfortunately I must do it like this way but the fact is that 64 | i just dont have this much possiblities with hard and software 65 | like on my good ol' Amiga;) NMI-shit and stuff.. 66 | 67 | But the result is the same so... its not a clean way but it 68 | works also. 69 | 70 | So basically what we have to emulate a Gameshark and this is 71 | very easy!: 72 | 73 | 1. We need a routine which is called VERY OFTEN to replace 74 | VALUES in N64-MEMORY while the user is playing the game. 75 | 76 | Okay, if you still know what i am talking about, CONTINUE READING! 77 | If you don't know what i am talking about, QUIT READING NOW:) 78 | 79 | 80 | So first step: 81 | HOW TO FIND A PLACE FOR YOUR "UPDATE-ROUNTINE" IN THE N64-GAMECODE: 82 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 83 | 84 | We must try to find a routine in the GAMEROM which is called 85 | very often.. here we can hook up our own UPDATE-CODE which will 86 | do the rest (=the "trainer" itself). 87 | 88 | Personally i use "OsViSwap" but you also can use 89 | "WriteBackDCacheAll", or "__osRestoreInt"... i just tested my 90 | trainers with the above mentioned three functions and it works 91 | perfectly. 92 | 93 | To find this routines get the tool "LFE" from www.dextorse.com 94 | (LFE = [Libary-Function-Extractor] (c) Ravemax of Dextrose) 95 | 96 | Then get the library "libultra.lib" from the PSY-Q-N64-Devkit.. 97 | 98 | Swap your gamerom now to Z64/CD64 format and make a backup of 99 | the rom... now RESIZE the ROM to 8 Megabit and use LFE to find 100 | out where the functions are in the ROM. 101 | 102 | The commandline for this is: 103 | 104 | LFE.EXE [ROM.Z64] libultra.lib 105 | 106 | This will take a while now.. - then LFE gives u back a ".COD" 107 | file! 108 | 109 | Here i included such a .COD file just for example: 110 | 111 | [============BEGIN TEST.COD==============] 112 | 0x8005e860,osSetIntMask 113 | 0x8005e980,osWritebackDCacheAll <--- THIS ONE MAYBE 114 | 0x8005fee0,alSynDelete 115 | 0x800660b0,osGetCount 116 | 0x800660c0,__osGetSR 117 | 0x80066150,__osDisableInt 118 | 0x80066170,__osRestoreInt <--- THIS ONE MAYBE, TOO 119 | 0x80066190,__osProbeTLB 120 | 0x80066250,__osSetCompare 121 | 0x80066260,__osSetFpcCsr 122 | 0x80066270,__osSetSR 123 | 0x80066280,osMapTLBRdb 124 | 0x800663b0,osGetThreadPri 125 | 0x80068dc0,alFilterNew 126 | 0x8006d560,__osGetCause 127 | 0x8008e876,__osThreadTail 128 | 0x8008e87e,__osRunQueue 129 | 0x8008e882,__osActiveQueue 130 | 0x8008e886,__osRunningThread 131 | 0x8008e88a,__osFaultedThread 132 | 0x80091f20,osViModeNtscLpn1 133 | 0x80091f70,osViModeNtscLpf1 134 | [=============END TEST.COD===============] 135 | 136 | So now search for one of the above mentioned functions. 137 | Hmm... in this game we dont have a OSViSwap.. so we could 138 | use the "osWritebackDCacheAll"-Function for our example. 139 | 140 | Now take the resized 8-Mbit-ROM again and disassemble it with 141 | N64PSX by NAGRA! (get it from www.blackbag.org or 142 | www.dextrose.com) 143 | 144 | The commandline will look like this: 145 | 146 | N64PSX.EXE -n64 [ROM.Z64] >ROM.ASM 147 | 148 | This nice tool will use the .COD file created by LFE 149 | and will mix it together with the disassembled code so you can 150 | exactly see where the functions begin.. my example will bring 151 | ROM.ASM as a result. 152 | 153 | Now, open "ROM.ASM" in your favorite editor and search for 154 | the function we want to use ("osWritebackDCacheAll"). 155 | 156 | [============BEGIN ROM.ASM==============] 157 | 8005e974: 00000000 .... nop 158 | 8005e978: 00000000 .... nop 159 | 8005e97c: 00000000 .... nop 160 | 8005e980: 3c088000 <... lui $t0,32768 ; osWritebackDCacheAll 161 | 8005e984: 240a2000 $. . li $t2,0x2000 162 | 8005e988: 010a4821 ..H! addu $t1,$t0,$t2 163 | 8005e98c: 2529fff0 %).. addiu $t1,$t1,0xfffffff0 164 | 8005e990: bd010000 .... cache 0x1,0x0000($t0) 165 | 8005e994: 0109082b ...+ sltu $at,$t0,$t1 166 | 8005e998: 1420fffd . .. bnez $at,0x8005e990 167 | 8005e99c: 25080010 %... addiu $t0,$t0,0x0010 168 | 8005e9a0: 03e00008 .... jr $ra <--THIS IS THE END OF THE FUNCTION! 169 | 8005e9a4: 00000000 .... nop 170 | 8005e9a8: 00000000 .... nop 171 | [=============END ROM.ASM===============] 172 | 173 | 174 | Now, we must search for the end of the function, this must 175 | be a "jr $ra". Once you found it, keep the memory-address 176 | where it is located. (In our example its: $8005e9a0) 177 | At this address we will hook up our trainer-routine. 178 | Let's move to the next chapter! 179 | 180 | THE TRAINER-ROUTINE 181 | ~~~~~~~~~~~~~~~~~~~ 182 | 183 | Okay, here we go with the main-routine which is responsible for 184 | updating the values in N64 RAM! 185 | 186 | This routine is very simple 187 | 188 | Just Imagine you got a Gameshark-Code like this: 189 | 190 | 8003567F 0064 191 | 192 | As i said above this means for the Gameshark nothing else than: 193 | WRITE THE VALUE $0064 TO ADRESS $8003567F. 194 | 195 | So here a neat code which will do this for us in ASSEMBLER and 196 | this will be the code which will be hooked to the Function we 197 | found before, to go sure our routine will be executed every 198 | time the function osWriteBackDCacheAll is called. 199 | 200 | 201 | sub sp,28 ;Get som Stackspace 202 | sw s0,0(sp) ;Better save this regs 203 | sw t0,4(sp) ;coz our routine below 204 | sw t1,8(sp) ;will trash them! 205 | sw t2,12(sp) ;t1 and t2 is for additional stuff 206 | 207 | 208 | li t0,$8003567F ;Memory-Address 209 | li s0,$64 ;Value 210 | nop 211 | sb s0,(t0) ;Write it into Memory. 212 | 213 | 214 | lw s0,0(sp) ;Okay.. lets restore the 215 | lw t0,4(sp) ;regs..! 216 | lw t1,8(sp) 217 | lw t2,12(sp) 218 | add sp,28 ;Free our Stackspace! 219 | nop 220 | jr ra ;This will jump back 221 | nop ;to osWriteBackDCacheAll! 222 | 223 | 224 | That's IT! 225 | 226 | 227 | CODING A "LOADER" FOR HOOKING UP OUR TRAINER-ROUTINE. 228 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 229 | 230 | Above we just coded our trainer-routine. But now we 231 | must attach this routine to the "osWritebackDCacheAll"-Function 232 | we found in the gamerom in order to get the trainer working. 233 | 234 | This is a very simple routine, too so take a look at the 235 | following ASM code: 236 | 237 | 238 | org $BXXXXXXX ;Orged in ROM see explanation 239 | 240 | la t0,patchstart ;patchstart 241 | li t1,$A0000200 ;This is place our Trainerroutine 242 | ;will stay 243 | la t2,patchend-patchstart+4 ;Lenght to copy 244 | loop: 245 | lw t3,(t0) ;this loop will copy our 246 | sw t3,(t1) ;patchroutine to $A0000200 247 | add t0,t0,4 ;so easy. 248 | add t1,t1,4 249 | bne t2,zero,loop 250 | sub t2,t2,4 251 | 252 | li t0,$A005E9A0 ; our osWritebackDCacheAll function!! 253 | 254 | li t1,$3c088000 ; Patch the function 255 | sw t1,(t0) 256 | li t1,$35080200 ; Patch the function 257 | sw t1,4(t0) 258 | li t1,$01000008 259 | sw t1,8(t0) 260 | 261 | li ra,$b0000008 ;This is the universial backjump 262 | lw ra,(ra) ;routine.. explanation follows. 263 | nop 264 | add ra,ra,$10 265 | nop 266 | jr ra ;Back to the game!! 267 | nop 268 | 269 | patchstart: 270 | ;here is the patchroutine (see above) :) 271 | patchend: 272 | 273 | 274 | Okay, what does this routine now? 275 | 276 | First of all i have to say something about the "org". Before you assemble 277 | this little loader you must search in the Gamerom for a nice unused 278 | place. Take your favorite hex-editor and load up your gamerom again 279 | and take a look.. - if you found freespace at e.g. $7FC000 in the 280 | rom and want to place your loader there, you have to ORG it to $B07FC000. 281 | 282 | Then our neat code will copy our "Trainerroutine" (patchstart) to a 283 | safe memory-location. (its $A0000200) 284 | 285 | After that it will patch the routine located at $A005E9A0. Yeees, you 286 | are right.. this $A005E9A0 is our osWritebackDCacheAll, we found 287 | some chapters ago! but be sure to replace the "8" with an "A". 288 | (We found $8005E9A0 and we will patch $A005E9A0)!!! 289 | 290 | Yeah, all done!, our trainerroutine is in a safe-memoryloaction where it 291 | can operate from, the osWritebackDCacheAll points now to our 292 | trainer-routine, so it will be called everytime the Function is called. 293 | 294 | So we can jump back to Gamecode: I have made a nice routine, which will 295 | do it universial, so no need to change something for every game. 296 | 297 | 298 | LAST WORDS AND OTHER STUFF 299 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 300 | 301 | So.. finally we made it! we have the Trainer. The only thing you have 302 | to do now is to patch the ROM-Start at $1000, save the orig-code from 303 | this location, jump to your loaderroutine ($B07FC000) and before you 304 | jump back, execute the orig-code you saved from $1000. And OF COZ, doing 305 | a nice trainermenu in Assembler (get Titaniks excellent sources from 306 | www.dextrose.com or get my trainermenu-source at dextrose.com, too) 307 | Thats it.. get movin'!!!!!!!!!! 308 | 309 | I hope i helped you with this document a little bit. Maybe this method 310 | will be nonsense, if new hardware appeares, where you can set Breakpoints 311 | and other usefull stuff.. But in this current point of time i think its 312 | a good way to do trainers.. - not the best way... but WORKS:) 313 | 314 | All infos, n64-sources etc can be obtained from www.paradogs.com, too. 315 | 316 | To make trainers is an ART not a RACE! :D 317 | 318 | Signed, Icarus of Paradox/Lightforce/Crystal/TRSi/Vision/LSD/Hellfire 319 | 320 | AUGUST - 1999! 321 | 322 | Greetings to all my friends in the scene.. stay cool. 323 | To all the others... FUCK OFF! 324 | 325 | -------------------------------------------------------------------------------- /n64ops/controll.txt: -------------------------------------------------------------------------------- 1 | This file contains information from Titanik and Niki W. Waibel, 2 | i have not put it together, but the info is just copied from e-mails from 3 | them both. 4 | 5 | 6 | -------------------------------------------------------------------------- 7 | Titanik: 8 | -------------------------------------------------------------------------- 9 | Those routines are a RIP of the code from TITANIK/CrazyNation, 10 | it's the not way the "normal" games read the joypad. 11 | 12 | 13 | You first have to set 2 places in memory that contains 64 bytes of 14 | certain values, lets call them pif1 and pif2. 15 | they contain the values : 16 | 17 | pif1: DW $FF010401 18 | DW $00000000 19 | DW $FF010401 20 | DW $00000000 21 | DW $FF010401 22 | DW $00000000 23 | DW $FF010401 24 | DW $00000000 25 | DW $FE000000 26 | DW $00000000 27 | DW $00000000 28 | DW $00000000 29 | DW $00000000 30 | DW $00000000 31 | DW $00000000 32 | DW $00000001 33 | 34 | pif2: DW 0,0,0,0,0,0,0,0 ;by words we mean 32bits! 35 | DW 0,0,0,0,0,0,0,0 ;I think this is 64 bytes.. 36 | 37 | You need to initialize this register before starting (your program will 38 | run few a few seconds then die if not done) 39 | 40 | addiu t0,r0,8 41 | lui at,$BFC0 42 | sw t0,$07FC(at) ;CLEAR BUTTONS 43 | move #8,$BFC007FC 44 | 45 | now when you start your program and begin your main loop the begginning 46 | of the loop should begin with (if you want to read joysticks): 47 | 48 | START: 49 | lui t2,$0031 ;t2 = if org is 80310000 then $0031 50 | ; if org is 80200000 then $0020 51 | 52 | ;I myself am still confused bout 53 | ;how ram is mirrored in the system 54 | ;but this is how it is 55 | 56 | ori t2,t2,pif1 ;lower 16 bits pointer to pif1 57 | lui at,$A480 ;SI DRAM ADDR. at=$A4800000 58 | sw t2,$0000(at) ; pif1 59 | lui t2,$1FC0 60 | ori t2,t2,$07C0 ;t2=$1fc007c0 61 | lui at,$A480 62 | sw t2,$0010(at) ;64B DRAM -> PIF ;poke them thar 63 | ;registers arrrrr 64 | 65 | [...do your stuff in here, then when ready to 66 | loop back do this to test josticks...] 67 | 68 | lui t2,$0031 ;look familiar 69 | ori t2,t2,pif2 70 | lui at,$A480 ;SI DRAM ADDR 71 | sw t2,$0000(at) ;$31pif2 72 | lui t2,$1FC0 73 | ori t2,t2,$07C0 ;PIF joychannel 74 | lui at,$A480 75 | sw t2,$0004(at) ;64B PIF->DRAM ;peek values to dram ? i 76 | ;guess this is necassary 77 | lui t1,$BFC0 78 | lbu t1,$07FF(t1) ;BYTE(JOY)-T1 ;for some reason this 79 | ;is done but I dont know why! 80 | lui t0,$BFC0 ;the value is disregarded 81 | 82 | lhu t0,$07C4(t0) ;**HWORD(JOY)->T0** 83 | nop 84 | beq t0,r0,START ;***we have our joystick value in t0*** 85 | 86 | nop ;if no buttons mashed then start over 87 | 88 | andi t1,t0,$4000 ;each bit represents a button so 89 | ;start testing them 90 | 91 | beq t1,r0,next1 ;I used to know what each bit represented 92 | ; (what button) but I lost the info 93 | nop ;andi $4000 /$8000 A/B $100/$200 left/right etc... 94 | ; I think this is right I 95 | 96 | [routine] ;might have it backwords or somethin 97 | 98 | next1: etc.. etc.. 99 | ;there are a couple of bits that i 100 | ;dont know what they do. 101 | ;havent figured out where the 102 | ;analog joy data is. 103 | 104 | 105 | 106 | 107 | =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 108 | From: Ben Stembridge 109 | To: anarko 110 | Subject: some stuff for n64ops#E 111 | -------------------------------------------------------------------------------- 112 | 113 | at 0x1FC0 07C4 - 07c5 is the status of the controller, each bit is 1 when 114 | the button is mashed, 0 otherwise. 115 | 07C4 (HALFWORD-16 BITS) = STATUS OF CONTROLLER 116 | %X X X X X X X X X X X X X X X X 117 | A B Z ST U D L R ? ? PL PR CU CD CL CR 118 | A,B,Z =BUTTONS 119 | ST = START 120 | U,D,L,R = JOYPAD 121 | ?,? = UNKNOWN 122 | PL,PR = PAN LEFT , PAN RIGHT BUTTONS 123 | CU,CD,CL,CR = C BUTTONS |UP,DOWN,LEFT,RIGHT 124 | 125 | 126 | 127 | Ben Stembridge 128 | Mech. ENG. 129 | Auburn University 130 | stembbe@mail.auburn.edu 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------- 136 | Niki W. Waibel: 137 | -------------------------------------------------------------------------- 138 | additional controller info: 139 | 140 | init controller: 141 | rdram -> pif 142 | ff010300 143 | ffffffff ... for each controller 144 | fe000000 ... at the end (after controller 4) 145 | 146 | than pif ram is set to: 147 | ????EE?? 148 | TTTTSS?? ... for each controller 149 | 150 | ?? ... ? zero (0x00) 151 | EE ... error field 152 | 0x80: no response (no controller connected) 153 | 0x40: Overrun error (?) 154 | 0x00: no error (controller connected) 155 | TTTT 156 | ... type field 157 | 0x0001 absolute 158 | 0x0002 relative 159 | 0x0004 joyport 160 | 0x8000 eeprom !!! 161 | SS ... status field 162 | 0x01 card on 163 | 0x02 card pull 164 | 0x04 addr crc err 165 | 0x80 eeprom busy 166 | 167 | 168 | get controller data: 169 | rdram -> pif 170 | ff010400 171 | ffffffff ... for each controller 172 | fe000000 ... at the end (after controller 4) 173 | 174 | than pif ram is set to (!!!attention!!! pif ram is actualized every read): 175 | 0xbfc007c0: ????EE?? 176 | 0xbfc007c4: BBBBXXYY 177 | 0xbfc007c8: | 178 | 0xbfc007cc: |_same as above but for controller 2 179 | ... 180 | BBBB ... buttons (you have that in controll.txt) 181 | XX ... stick x pos [-128..127] or 0x80 (left) .. 0x00 (middle) .. 0x7f (right) 182 | YY ... stick y pos [-128..127] or 0x80 (down) .. 0x00 (middle) .. 0x7f (up) 183 | !!!attention!!! 184 | all pur versions seem NOT to have implemented the SIGNED XX and YY bytes 185 | correct. 186 | 0x80 0x81 0x82 ... 0xff 0x00 0x01 .. 0x7c 0x7e 0x7f 187 | -128 -127 -126 -1 0 1 125 126 127 188 | left pos middle pos right pos 189 | down pos middle pos up pos 190 | !!!attention!!! -------------------------------------------------------------------------------- /n64ops/n64ops#a.txt: -------------------------------------------------------------------------------- 1 | Nintendo 64 Toolkit: opcodes v1.1 by anarko 2 | 3 | Part A: Brief list of R4300i opcodes released on 1999-04-21 4 | ---------------------------------------------------------------------------- 5 | 6 | 7 | **************************************************************************** 8 | ** Explanations ** 9 | **************************************************************************** 10 | rs = 5-bit source register specifier 11 | rt = 5-bit target (source/destination) register or branch condition 12 | rd = 5-bit destination register specifier 13 | sa = 5-bit shift amount 14 | 15 | fs = 5-bit floating point source register specifier 16 | ft = 5-bit floating point target (source/destination) 17 | register or branch condition 18 | fd = 5-bit floating point destination register specifier 19 | 20 | base = 5-bit value 21 | imm = 16 bit immediate value 22 | offset = 16 bit branch displacement or address displacement 23 | target = 26 bit jump target address 24 | 25 | = Equal to > Greater than >= Greater than or equal to 26 | <> Not equal to < Less than <= Less than or equal to 27 | 28 | **************************************************************************** 29 | ** Load and Store Instructions ** 30 | **************************************************************************** 31 | LB rt,offset(base) Load Byte 32 | LBU rt,offset(base) Load Byte Unsigned 33 | LD rt,offset(base) Load Doubleword 34 | LDL rt,offset(base) Load Doubleword Left 35 | LDR rt,offset(base) Load Doubleword Right 36 | LH rt,offset(base) Load Halfword 37 | LHU rt,offset(base) Load Halfword Unsigned 38 | LL rt,offset(base) Load Linked word 39 | LLD rt,offset(base) Load Linked Doubleword 40 | LW rt,offset(base) Load Word 41 | LWL rt,offset(base) Load Word Left 42 | LWR rt,offset(base) Load Word Right 43 | LWU rt,offset(base) Load Word Unsigned 44 | SB rt,offset(base) Store Byte 45 | SC rt,offset(base) Store Conditional word 46 | SCD rt,offset(base) Store Conditional Doubleword 47 | SD rt,offset(base) Store Doubleword 48 | SDL rt,offset(base) Store Doubleword Left 49 | SDR rt,offset(base) Store Doubleword Right 50 | SH rt,offset(base) Store Halfword 51 | SW rt,offset(base) Store Word 52 | SWL rt,offset(base) Store Word Left 53 | SWR rt,offset(base) Store Word Right 54 | SYNC SYNChronize shared memory 55 | 56 | **************************************************************************** 57 | ** Atithmetic Instructions ** 58 | **************************************************************************** 59 | ADD rd,rs,rt ADD word 60 | ADDI rt,rs,imm ADD Immediate word 61 | ADDIU rt,rs,imm Add Immediate Unsigned word 62 | ADDU rd,rs,rt Add Unsigned word 63 | AND rd,rs,rt AND 64 | ANDI rt,rs,imm AND Immediate 65 | DADD rd,rs,rt Doubleword ADD 66 | DADDI rt,rs,imm Doubleword ADD Immediate 67 | DADDIU rt,rs,imm Doubleword ADD Immediate Unsigned 68 | DADDU rd,rs,rt Doubleword ADD Unsigned 69 | DDIV rs,rt Doubleword DIVide 70 | DDIVU rs,rt Doubleword DIVide Unsigned 71 | DIV rs,rt DIVide word 72 | DIVU rs,rt DIVide Unsigned word 73 | DMULT rs,rt Doubleword MULTiply 74 | DMULTU rs,rt Doubleword MULTiply Unsigned 75 | DSLL rd,rt,sa Doubleword Shift Left Logical 76 | DSLL32 rd,rt,sa Doubleword Shift Left Logical +32 77 | DSLLV rd,rt,rs Doubleword Shift Left Logical Variable 78 | DSRA rd,rt,sa Doubleword Shift Right Arithmetic 79 | DSRA32 rd,rt,sa Doubleword Shift Right Arithmetic +32 80 | DSRAV rd,rt,rs Doubleword Shift Right Arithmetic Variable 81 | DSRL rd,rt,sa Doubleword Shift Right Logical 82 | DSRL32 rd,rt,sa Doubleword Shift Right Logical +32 83 | DSRLV rd,rt,rs Doubleword Shift Right Logical Variable 84 | DSUB rd,rs,rt Doubleword SUBtract 85 | DSUBU rd,rs,rt Doubleword SUBtract Unsigned 86 | LUI rt,imm Load Upper Immediate 87 | MFHI rd Move From HI register 88 | MFLO rd Move From LO register 89 | MTHI rd Move To HI register 90 | MTLO rd Move To LO register 91 | MULT rs,rt MULTiply word 92 | MULTU rs,rt MULTiply Unsigned word 93 | NOR rd,rs,rt Not OR 94 | OR rd,rs,rt OR 95 | ORI rt,rs,imm OR Immediate 96 | SLL rd,rt,sa Shift word Left Logical 97 | SLLV rd,rt,rs Shift word Left Logical Variable 98 | SLT rd,rs,rt Set on Less Than 99 | SLTI rt,rs,imm Set on Less Than Immediate 100 | SLTIU rt,rs,imm Set on Less Than Immediate Unsigned 101 | SLTU rd,rs,rt Set on Less Than Unsigned 102 | SRA rd,rt,sa Shift word Right Arithmetic 103 | SRAV rd,rt,rs Shift word Right Arithmetic Variable 104 | SRL rd,rt,sa Shift word Right Logical 105 | SRLV rd,rt,rs Shift word Right Logical Variable 106 | SUB rd,rs,rt SUBtract word 107 | SUBU rd,rs,rt SUBtract Unsigned word 108 | XOR rd,rs,rt eXclusive OR 109 | XORI rt,rs,imm eXclusive OR Immediate 110 | 111 | **************************************************************************** 112 | ** Jump and Branch Instructions ** 113 | **************************************************************************** 114 | BEQ rs,rt,offset Branch on = 115 | BEQL rs,rt,offset Branch on EQual Likely 116 | BGEZ rs,offset Branch on >= Zero 117 | BGEZAL rs,offset Branch on >= Zero And Link 118 | BGEZALL rs,offset Branch on >= Zero And Link Likely 119 | BGEZL rs,offset Branch on >= Equal to Zero Likely 120 | BGTZ rs,offset Branch on > Zero 121 | BGTZL rs,offset Branch on > Zero Likely 122 | BLEZ rs,offset Branch on <= Equal to Zero 123 | BLEZL rs,offset Branch on <= Zero Likely 124 | BLTZ rs,offset Branch on < Zero 125 | BLTZAL rs,offset Branch on < Zero And Link 126 | BLTZALL rs,offset Branch on < Zero And Link Likely 127 | BLTZL rs,offset Branch on < Zero Likely 128 | BNE rs,rt,offset Branch on <> 129 | BNEL rs,rt,offset Branch on <> Likely 130 | J target Jump 131 | JAL target Jump And Link 132 | JALR rs,rd Jump And Link Register 133 | JR rs Jump Register 134 | 135 | **************************************************************************** 136 | ** Special Instructions ** 137 | **************************************************************************** 138 | BREAK offset BREAKpoint 139 | SYSCALL offset SYStem CALL 140 | 141 | **************************************************************************** 142 | ** Exception Instructions ** 143 | **************************************************************************** 144 | TEQ rs,rt Trap if = 145 | TEQI rs,imm Trap if = Immediate 146 | TGE rs,rt Trap if >= 147 | TGEI rs,imm Trap if >= Immediate 148 | TGEIU rs,imm Trap if >= Immediate Unsigned 149 | TGEU rs,rt Trap if >= Unsigned 150 | TLT rs,rt Trap if < 151 | TLTI rs,imm Trap if < Immediate 152 | TLTIU rs,imm Trap if < Immediate Unsigned 153 | TLTU rs,rt Trap if < Unsigned 154 | TNE rs,rt Trap if <> 155 | TNEI rs,imm Trap if <> Immediate 156 | 157 | **************************************************************************** 158 | ** System Control Processor (COP0) Instructions ** 159 | **************************************************************************** 160 | CACHE op,offset(base) CACHE 161 | ERET Return from Exception 162 | MFC0 rt,fs Move Word From CP0 163 | MTC0 rt,fs Move Word To CP0 164 | TLBP Probe TLB for Matching Entry 165 | TLBR Read Indexed TLB Entry 166 | TLBWI Write Indexed TLB Entry 167 | TLBWR Write Random TLB Entry 168 | 169 | **************************************************************************** 170 | ** Floating-point Unit, FPU (COP1) instructions ** 171 | **************************************************************************** 172 | ABS.fmt fd,fs floating-point ABSolute value 173 | ADD.fmt fd,fs,ft floating-point ADD 174 | BC1F offset Branch on FP False 175 | BC1FL offset Branch on FP False Likely 176 | BC1T offset Branch on FP True 177 | BC1TL offset Branch on FP True Likely 178 | C.cond.fmt fs,ft floating-point floating point Compare 179 | CEIL.L.fmt fd,fs floating-point CEILing convert to Long fixed-point 180 | CEIL.W.fmt fd,fs floating-point CEILing convert to Word fixed-point 181 | CFC1 rt,fs Move control word From Floating-Point 182 | CTC1 rt,fs Move control word To Floating-Point 183 | CVT.D.fmt fd,fs floating-point ConVerT to Double floating-point 184 | CVT.L.fmt fd,fs floating-point ConVerT to Long fixed-point 185 | CVT.S.fmt fd,fs floating-point ConVerT to Single floating-point 186 | CVT.W.fmt fd,fs floating-point ConVerT to Word fixed-point 187 | DIV.fmt fd,fs,ft floating-point DIVide 188 | DMFC1 rt,fs Doubleword Move From Floating-Point 189 | DMTC1 rt,fs Doubleword Move To Floating-Point 190 | FLOOR.L.fmt fd,fs floating-point FLOOR convert to Long fixed-point 191 | FLOOR.W.fmt fd,fs floating-point FLOOR convert to Word fixed-point 192 | LDC1 ft,offset(base) Load Doubleword to Floating-Point 193 | LWC1 ft,offset(base) Load Word to Floating-Point 194 | MFC1 rt,fs Move Word From Floating-Point 195 | MOV.fmt fd,fs floating-point MOVe 196 | MTC1 rt,fs Move Word To Floating-Point 197 | MUL.fmt fd,fs,ft floating-point MULtiply 198 | NEG.fmt fd,fs floating-point NEGate 199 | ROUND.L.fmt fd,fs floating-point ROUND to Long fixed-point 200 | ROUND.W.fmt fd,fs floating-point ROUND to Word fixed-point 201 | SDC1 ft,offset(base) Store Doubleword from Floating-Point 202 | SQRT.fmt fd,fs floating-point SQuare RooT 203 | SUB.fmt fd,fs,ft floating-point SUBtract 204 | SWC1 ft,offset(base) Store Word from Floating-Point 205 | TRUNC.L.fmt fd,fs floating-point TRUNCate to Long fixed-point 206 | TRUNC.W.fmt fd,fs floating-point TRUNCate to Word fixed-point 207 | 208 | **************************************************************************** 209 | ** Pseudo opcodes ** 210 | **************************************************************************** 211 | NOP Assembles to SLL r0, r0, 0 212 | MOVE rd, rs Assembles to ADD rd, r0, rs 213 | NEG rd, rt Assembles to SUB rd, r0, rt 214 | NEGU rd, rs Assembles to SUBU rd, r0, rs 215 | BNEZ rs, offset Assembles to BNE rs, r0, offset 216 | BNEZL rs, offset Assembles to BNEL rs, r0, offset 217 | BEQZ rs, offset Assembles to BEQ rs, r0, offset 218 | BEQZL rs, offset Assembles to BEQL rs, r0, offset 219 | B offset Assembles to BEQ r0, r0, offset 220 | BAL offset Assembles to BGEZAL r0, offset 221 | LI rt, imm Assembles to ORI rt, r0, imm (if imm is 16 bit) 222 | or ADDIU rt, r0, imm 223 | or LUI rt, high_16 224 | ORI rt, rt, low_16 (if imm is 32 bit) 225 | S.S ft, offset(base) Assembles to SWC1 ft, offset(base) 226 | L.S ft, offset(base) Assembles to LWC1 ft, offset(base) 227 | -------------------------------------------------------------------------------- /n64ops/n64ops#c.txt: -------------------------------------------------------------------------------- 1 | Nintendo 64 Toolkit: opcodes v1.1 by anarko 2 | 3 | Part C: R4300i opcode matrix released on 1999-04-21 4 | ---------------------------------------------------------------------------- 5 | 6 | 7 | **************************************************************************** 8 | ** Main CPU ** 9 | **************************************************************************** 10 | 11 | CPU: Instructions encoded by opcode field. 12 | 31---------26---------------------------------------------------0 13 | | opcode | | 14 | ------6---------------------------------------------------------- 15 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 16 | 000 | *1 | *2 | J | JAL | BEQ | BNE | BLEZ | BGTZ | 17 | 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI | 18 | 010 | *3 | *4 | --- | --- | BEQL | BNEL | BLEZL | BGTZL | 19 | 011 | DADDI |DADDIU | LDL | LDR | --- | --- | --- | --- | 20 | 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU | 21 | 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE | 22 | 110 | LL | LWC1 | --- | --- | LLD | LDC1 | LDC2 | LD | 23 | 111 | SC | SWC1 | --- | --- | SCD | SDC1 | SDC2 | SD | 24 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 25 | *1 = SPECIAL, see SPECIAL list *2 = REGIMM, see REGIMM list 26 | *3 = COP0 *4 = COP1 27 | 28 | SPECIAL: Instr. encoded by function field when opcode field = SPECIAL. 29 | 31---------26------------------------------------------5--------0 30 | | = SPECIAL | | function| 31 | ------6----------------------------------------------------6----- 32 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 33 | 000 | SLL | --- | SRL | SRA | SLLV | --- | SRLV | SRAV | 34 | 001 | JR | JALR | --- | --- |SYSCALL| BREAK | --- | SYNC | 35 | 010 | MFHI | MTHI | MFLO | MTLO | DSLLV | --- | DSRLV | DSRAV | 36 | 011 | MULT | MULTU | DIV | DIVU | DMULT | DMULTU| DDIV | DDIVU | 37 | 100 | ADD | ADDU | SUB | SUBU | AND | OR | XOR | NOR | 38 | 101 | --- | --- | SLT | SLTU | DADD | DADDU | DSUB | DSUBU | 39 | 110 | TGE | TGEU | TLT | TLTU | TEQ | --- | TNE | --- | 40 | 111 | DSLL | --- | DSRL | DSRA |DSLL32 | --- |DSRL32 |DSRA32 | 41 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 42 | 43 | REGIMM: Instructions encoded by the rt field when opcode field = REGIMM. 44 | 31---------26----------20-------16------------------------------0 45 | | = REGIMM | | rt | | 46 | ------6---------------------5------------------------------------ 47 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 48 | 00 | BLTZ | BGEZ | BLTZL | BGEZL | --- | --- | --- | --- | 49 | 01 | TGEI | TGEIU | TLTI | TLTIU | TEQI | --- | TNEI | --- | 50 | 10 | BLTZAL| BGEZAL|BLTZALL|BGEZALL| --- | --- | --- | --- | 51 | 11 | --- | --- | --- | --- | --- | --- | --- | --- | 52 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 53 | 54 | 55 | **************************************************************************** 56 | ** COP0 ** 57 | **************************************************************************** 58 | 59 | COP0: Instructions encoded by the fmt field when opcode = COP0. 60 | 31--------26-25------21 ----------------------------------------0 61 | | = COP0 | fmt | | 62 | ------6----------5----------------------------------------------- 63 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 64 | 00 | MFC0 | --- | --- | --- | MTC0 | --- | --- | --- | 65 | 01 | --- | --- | --- | --- | --- | --- | --- | --- | 66 | 10 | *1 | --- | --- | --- | --- | --- | --- | --- | 67 | 11 | --- | --- | --- | --- | --- | --- | --- | --- | 68 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 69 | *1 = TLB instr, see TLB list 70 | 71 | TLB: Instructions encoded by the function field when opcode 72 | = COP0 and fmt = TLB. 73 | 31--------26-25------21 -------------------------------5--------0 74 | | = COP0 | = TLB | | function| 75 | ------6----------5-----------------------------------------6----- 76 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 77 | 000 | --- | TLBR | TLBWI | --- | --- | --- | TLBWR | --- | 78 | 001 | TLBP | --- | --- | --- | --- | --- | --- | --- | 79 | 010 | --- | --- | --- | --- | --- | --- | --- | --- | 80 | 011 | ERET | --- | --- | --- | --- | --- | --- | --- | 81 | 100 | --- | --- | --- | --- | --- | --- | --- | --- | 82 | 101 | --- | --- | --- | --- | --- | --- | --- | --- | 83 | 110 | --- | --- | --- | --- | --- | --- | --- | --- | 84 | 111 | --- | --- | --- | --- | --- | --- | --- | --- | 85 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 86 | 87 | 88 | **************************************************************************** 89 | ** COP1 - Floating Point Unit (FPU) ** 90 | **************************************************************************** 91 | 92 | COP1: Instructions encoded by the fmt field when opcode = COP1. 93 | 31--------26-25------21 ----------------------------------------0 94 | | = COP1 | fmt | | 95 | ------6----------5----------------------------------------------- 96 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 97 | 00 | MFC1 | DMFC1 | CFC1 | --- | MTC1 | DMTC1 | CTC1 | --- | 98 | 01 | *1 | --- | --- | --- | --- | --- | --- | --- | 99 | 10 | *2 | *3 | --- | --- | *4 | *5 | --- | --- | 100 | 11 | --- | --- | --- | --- | --- | --- | --- | --- | 101 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 102 | *1 = BC instructions, see BC1 list 103 | *2 = S instr, see FPU list *3 = D instr, see FPU list 104 | *4 = W instr, see FPU list *5 = L instr, see FPU list 105 | 106 | BC1: Instructions encoded by the nd and tf fields when opcode 107 | = COP1 and fmt = BC 108 | 31--------26-25------21 ---17--16-------------------------------0 109 | | = COP1 | = BC | |nd|tf| | 110 | ------6----------5-----------1--1-------------------------------- 111 | |---0---|---1---| tf 112 | 0 | BC1F | BC1T | 113 | 1 | BC1FL | BC1TL | 114 | nd |-------|-------| 115 | 116 | FPU: Instructions encoded by the function field when opcode = COP1 117 | and fmt = S 118 | 31--------26-25------21 -------------------------------5--------0 119 | | = COP1 | = S | | function| 120 | ------6----------5-----------------------------------------6----- 121 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 122 | 000 | ADD | SUB | MUL | DIV | SQRT | ABS | MOV | NEG | 123 | 001 |ROUND.L|TRUNC.L| CEIL.L|FLOOR.L|ROUND.W|TRUNC.W| CEIL.W|FLOOR.W| 124 | 010 | --- | --- | --- | --- | --- | --- | --- | --- | 125 | 011 | --- | --- | --- | --- | --- | --- | --- | --- | 126 | 100 | --- | CVT.D | --- | --- | CVT.W | CVT.L | --- | --- | 127 | 101 | --- | --- | --- | --- | --- | --- | --- | --- | 128 | 110 | C.F | C.UN | C.EQ | C.UEQ | C.OLT | C.ULT | C.OLE | C.ULE | 129 | 111 | C.SF | C.NGLE| C.SEQ | C.NGL | C.LT | C.NGE | C.LE | C.NGT | 130 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 131 | 132 | FPU: Instructions encoded by the function field when opcode = COP1 133 | and fmt = D 134 | 31--------26-25------21 -------------------------------5--------0 135 | | = COP1 | = D | | function| 136 | ------6----------5-----------------------------------------6----- 137 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 138 | 000 | ADD | SUB | MUL | DIV | SQRT | ABS | MOV | NEG | 139 | 001 |ROUND.L|TRUNC.L| CEIL.L|FLOOR.L|ROUND.W|TRUNC.W| CEIL.W|FLOOR.W| 140 | 010 | --- | --- | --- | --- | --- | --- | --- | --- | 141 | 011 | --- | --- | --- | --- | --- | --- | --- | --- | 142 | 100 | CVT.S | --- | --- | --- | CVT.W | CVT.L | --- | --- | 143 | 101 | --- | --- | --- | --- | --- | --- | --- | --- | 144 | 110 | C.F | C.UN | C.EQ | C.UEQ | C.OLT | C.ULT | C.OLE | C.ULE | 145 | 111 | C.SF | C.NGLE| C.SEQ | C.NGL | C.LT | C.NGE | C.LE | C.NGT | 146 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 147 | 148 | FPU: Instructions encoded by the function field when opcode = COP1 149 | and fmt = W 150 | 31--------26-25------21 -------------------------------5--------0 151 | | = COP1 | = W | | function| 152 | ------6----------5-----------------------------------------6----- 153 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 154 | 000 | --- | --- | --- | --- | --- | --- | --- | --- | 155 | 001 | --- | --- | --- | --- | --- | --- | --- | --- | 156 | 010 | --- | --- | --- | --- | --- | --- | --- | --- | 157 | 011 | --- | --- | --- | --- | --- | --- | --- | --- | 158 | 100 | CVT.S | CVT.D | --- | --- | --- | --- | --- | --- | 159 | 101 | --- | --- | --- | --- | --- | --- | --- | --- | 160 | 110 | --- | --- | --- | --- | --- | --- | --- | --- | 161 | 111 | --- | --- | --- | --- | --- | --- | --- | --- | 162 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 163 | 164 | FPU: Instructions encoded by the function field when opcode = COP1 165 | and fmt = L 166 | 31--------26-25------21 -------------------------------5--------0 167 | | = COP1 | = L | | function| 168 | ------6----------5-----------------------------------------6----- 169 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 170 | 000 | --- | --- | --- | --- | --- | --- | --- | --- | 171 | 001 | --- | --- | --- | --- | --- | --- | --- | --- | 172 | 010 | --- | --- | --- | --- | --- | --- | --- | --- | 173 | 011 | --- | --- | --- | --- | --- | --- | --- | --- | 174 | 100 | CVT.S | CVT.D | --- | --- | --- | --- | --- | --- | 175 | 101 | --- | --- | --- | --- | --- | --- | --- | --- | 176 | 110 | --- | --- | --- | --- | --- | --- | --- | --- | 177 | 111 | --- | --- | --- | --- | --- | --- | --- | --- | 178 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 179 | -------------------------------------------------------------------------------- /n64ops/n64ops#d.txt: -------------------------------------------------------------------------------- 1 | Nintendo 64 Toolkit: opcodes v1.1 by anarko 2 | 3 | Part D: Brief list of RSP opcodes released on 1999-04-21 4 | ---------------------------------------------------------------------------- 5 | 6 | All information on the RSP was provided by my friend Zilmar. 7 | Names of the opcodes are just guessings, also maybe not all of these opcodes 8 | really exist on the Nintendo 64, since information on the opcodes are from 9 | the SGI hardware. Bear with us, updates will cover the RSP more correctly. 10 | 11 | **************************************************************************** 12 | ** Explanations ** 13 | **************************************************************************** 14 | v = The destination vector register, where the result will be placed. 15 | del = Specifies the destination element to be used. 16 | offset = 16-bit additional offset to use from a base register. 17 | base = The base GPR to use for load/store operations. 18 | v = Source vector register. 19 | v = Source vector register. 20 | el = Specifies the element to be used on a source vector register. 21 | 22 | **************************************************************************** 23 | ** Load and Store Instructions ** 24 | **************************************************************************** 25 | LBV $v[del], offset(base) Load byte to vector 26 | LSV $v[del], offset(base) Load short (halfword) to vector 27 | LLV $v[del], offset(base) Load long (word) to vector 28 | LDV $v[del], offset(base) Load double (doubleword) to vector 29 | LQV $v[del], offset(base) Load quad (quadword) to vector 30 | LRV $v[del], offset(base) Load rest to vector 31 | LPV $v[del], offset(base) Load packed to vector 32 | LUV $v[del], offset(base) Load unpacked to vector 33 | LHV $v[del], offset(base) Load half to vector 34 | LFV $v[del], offset(base) Load fourth to vector 35 | LWV $v[del], offset(base) Load wrap to vector 36 | LTV $v[del], offset(base) Load transpose to vector 37 | 38 | SBV $v[del], offset(base) Store byte from vector 39 | SSV $v[del], offset(base) Store short (halfword) from vector 40 | SLV $v[del], offset(base) Store long (word) from vector 41 | SDV $v[del], offset(base) Store double (doubleword) from vector 42 | SQV $v[del], offset(base) Store quad (quadword) from vector 43 | SRV $v[del], offset(base) Store rest from vector 44 | SPV $v[del], offset(base) Store packed from vector 45 | SUV $v[del], offset(base) Store unpacked from vector 46 | SHV $v[del], offset(base) Store half from vector 47 | SFV $v[del], offset(base) Store fourth from vector 48 | SWV $v[del], offset(base) Store wrap from vector 49 | STV $v[del], offset(base) Store transpose from vector 50 | 51 | 52 | 53 | **************************************************************************** 54 | ** Vector Instructions ** 55 | **************************************************************************** 56 | VMULF $v, $v, $v[el] Vector (Frac) Multiply 57 | VMULU $v, $v, $v[el] Vector (Unsigned Frac) Multiply 58 | VRNDP $v, $v, $v[el] Vector DCT Round (+) 59 | VMULQ $v, $v, $v[el] Vector (Integer) Multiply 60 | VMUDL $v, $v, $v[el] Vector low multiply 61 | VMUDM $v, $v, $v[el] Vector mid-m multiply 62 | VMUDN $v, $v, $v[el] Vector mid-n multiply 63 | VMUDH $v, $v, $v[el] Vector high multiply 64 | VMACF $v, $v, $v[el] Vector (Frac) Multiply Accumulate 65 | VMACU $v, $v, $v[el] Vector (Unsigned Frac) Multiply Accumulate 66 | VRNDN $v, $v, $v[el] Vector DCT Round (-) 67 | VMACQ $v, $v, $v[el] Vector (Integer) Multiply Accumulate 68 | VMADL $v, $v, $v[el] Vector low multiply accumulate 69 | VMADM $v, $v, $v[el] Vector mid-m multiply accumulate 70 | VMADN $v, $v, $v[el] Vector mid-n multiply accumulate 71 | VMADH $v, $v, $v[el] Vector high multiply accumulate 72 | 73 | 74 | I don't have instruction encoding on the following: 75 | 76 | VADD $v, $v, $v[el] Vector Add 77 | VSUB $v, $v, $v[el] Vector Subtract 78 | VABS $v, $v, $v[el] Vector Absolute Value 79 | VADDC $v, $v, $v[el] Vector ADDC 80 | VSUBC $v, $v, $v[el] Vector SUBC 81 | 82 | VLT ? Vector Less Than 83 | VEQ ? Vector Equal To 84 | VNE ? Vector Not Equal To 85 | VGE ? Vector Greater Than or Equal To 86 | VCL ? Vector Clip Low 87 | VCH ? Vector Clip High 88 | VCR ? Vector, 1's Complement Clip 89 | VMRG ? Vector Merge 90 | 91 | VAND ? Vector Logical AND 92 | VNAND ? Vector Logical NOT AND 93 | VOR ? Vector Logical OR 94 | VNOR ? Vector Logical NOT OR 95 | VXOR ? Vector Logical Exclusive OR 96 | VNXOR ? Vector Logical NOT Exclusive OR 97 | 98 | VRCP ? Single Precision, Lookup Source, Write Result 99 | VRCPL ? Lookup Source and Previous, Write Result 100 | VRCPH ? Set Source, Write Previous Result 101 | VMOV ? Vector Move 102 | VRSQ ? Single Precision, Lookup Source, Write Result 103 | VRSQL ? Lookup Source and Previous, Write Result 104 | VRSQH ? Set Source, Write Previous Result 105 | -------------------------------------------------------------------------------- /n64ops/n64ops#e.txt: -------------------------------------------------------------------------------- 1 | Nintendo 64 Toolkit: opcodes v1.1 by anarko 2 | 3 | Part E: Detailed list of RSP opcodes released on 1999-04-21 4 | ---------------------------------------------------------------------------- 5 | 6 | All information on the RSP was provided by my friend Zilmar. 7 | 8 | **************************************************************************** 9 | ** Registers ** 10 | **************************************************************************** 11 | Main GPR registers: 12 | ------------------- 13 | 00h = r0/reg0 08h = t0/reg8 10h = s0/reg16 18h = t8/reg24 14 | 01h = at/reg1 09h = t1/reg9 11h = s1/reg17 19h = t9/reg25 15 | 02h = v0/reg2 0Ah = t2/reg10 12h = s2/reg18 1Ah = k0/reg26 16 | 03h = v1/reg3 0Bh = t3/reg11 13h = s3/reg19 1Bh = k1/reg27 17 | 04h = a0/reg4 0Ch = t4/reg12 14h = s4/reg20 1Ch = gp/reg28 18 | 05h = a1/reg5 0Dh = t5/reg13 15h = s5/reg21 1Dh = sp/reg29 19 | 06h = a2/reg6 0Eh = t6/reg14 16h = s6/reg22 1Eh = s8/reg30 20 | 07h = a3/reg7 0Fh = t7/reg15 17h = s7/reg23 1Fh = ra/reg31 21 | 22 | Vector registers: 23 | ----------------- 24 | 00h = $v0 08h = $v8 10h = $v16 18h = $v24 25 | 01h = $v1 09h = $v9 11h = $v17 19h = $v25 26 | 02h = $v2 0Ah = $v10 12h = $v18 1Ah = $v26 27 | 03h = $v3 0Bh = $v11 13h = $v19 1Bh = $v27 28 | 04h = $v4 0Ch = $v12 14h = $v20 1Ch = $v28 29 | 05h = $v5 0Dh = $v13 15h = $v21 1Dh = $v29 30 | 06h = $v6 0Eh = $v14 16h = $v22 1Eh = $v30 31 | 07h = $v7 0Fh = $v15 17h = $v23 1Fh = $v31 32 | 33 | 34 | **************************************************************************** 35 | ** Load and Store Instructions ** 36 | **************************************************************************** 37 | +-----------+---------------------------------------------------+ 38 | | LBV | Load byte to vector | 39 | +-----------+---------+---------+---------+-------+-+-----------+ 40 | | 110010 | base | dest | 00000 | del |0| offset | 41 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 42 | Format: LBV $v[del], offset(base) 43 | 44 | +-----------+---------------------------------------------------+ 45 | | LSV | Load short (halfword) to vector | 46 | +-----------+---------+---------+---------+-------+-+-----------+ 47 | | 110010 | base | dest | 00001 | del |0| offset | 48 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 49 | Format: LSV $v[del], offset(base) 50 | 51 | +-----------+---------------------------------------------------+ 52 | | LLV | Load long (word) to vector | 53 | +-----------+---------+---------+---------+-------+-+-----------+ 54 | | 110010 | base | dest | 00010 | del |0| offset | 55 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 56 | Format: LLV $v[del], offset(base) 57 | 58 | +-----------+---------------------------------------------------+ 59 | | LDV | Load double to vector | 60 | +-----------+---------+---------+---------+-------+-+-----------+ 61 | | 110010 | base | dest | 00011 | del |0| offset | 62 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 63 | Format: LDV $v[del], offset(base) 64 | 65 | +-----------+---------------------------------------------------+ 66 | | LQV | Load quadword to vector | 67 | +-----------+---------+---------+---------+-------+-+-----------+ 68 | | 110010 | base | dest | 00100 | del |0| offset | 69 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 70 | Format: LQV $v[del], offset(base) 71 | 72 | +-----------+---------------------------------------------------+ 73 | | LRV | Load rest to vector | 74 | +-----------+---------+---------+---------+-------+-+-----------+ 75 | | 110010 | base | dest | 00101 | del |0| offset | 76 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 77 | Format: LRV $v[del], offset(base) 78 | 79 | +-----------+---------------------------------------------------+ 80 | | LPV | Load packed to vector | 81 | +-----------+---------+---------+---------+-------+-+-----------+ 82 | | 110010 | base | dest | 00110 | del |0| offset | 83 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 84 | Format: LPV $v[del], offset(base) 85 | 86 | +-----------+---------------------------------------------------+ 87 | | LUV | Load unpacked to vector | 88 | +-----------+---------+---------+---------+-------+-+-----------+ 89 | | 110010 | base | dest | 00111 | del |0| offset | 90 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 91 | Format: LUV $v[del], offset(base) 92 | 93 | +-----------+---------------------------------------------------+ 94 | | LHV | Load half to vector | 95 | +-----------+---------+---------+---------+-------+-+-----------+ 96 | | 110010 | base | dest | 01000 | del |0| offset | 97 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 98 | Format: LHV $v[del], offset(base) 99 | 100 | +-----------+---------------------------------------------------+ 101 | | LFV | Load fourth to vector | 102 | +-----------+---------+---------+---------+-------+-+-----------+ 103 | | 110010 | base | dest | 01001 | del |0| offset | 104 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 105 | Format: LFV $v[del], offset(base) 106 | 107 | +-----------+---------------------------------------------------+ 108 | | LWV | Load wrap to vector | 109 | +-----------+---------+---------+---------+-------+-+-----------+ 110 | | 110010 | base | dest | 01010 | del |0| offset | 111 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 112 | Format: LWV $v[del], offset(base) 113 | 114 | +-----------+---------------------------------------------------+ 115 | | LTV | Load transpose to vector | 116 | +-----------+---------+---------+---------+-------+-+-----------+ 117 | | 110010 | base | dest | 01011 | del |0| offset | 118 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 119 | Format: LTV $v[del], offset(base) 120 | 121 | +-----------+---------------------------------------------------+ 122 | | SBV | Store byte from vector | 123 | +-----------+---------+---------+---------+-------+-+-----------+ 124 | | 110010 | base | dest | 00000 | del |0| offset | 125 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 126 | Format: SBV $v[del], offset(base) 127 | 128 | +-----------+---------------------------------------------------+ 129 | | SSV | Store short (halfword) from vector | 130 | +-----------+---------+---------+---------+-------+-+-----------+ 131 | | 110010 | base | dest | 00001 | del |0| offset | 132 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 133 | Format: SSV $v[del], offset(base) 134 | 135 | +-----------+---------------------------------------------------+ 136 | | SLV | Store long (word) from vector | 137 | +-----------+---------+---------+---------+-------+-+-----------+ 138 | | 110010 | base | dest | 00010 | del |0| offset | 139 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 140 | Format: SLV $v[del], offset(base) 141 | 142 | +-----------+---------------------------------------------------+ 143 | | SDV | Store double (doubleword) from vector | 144 | +-----------+---------+---------+---------+-------+-+-----------+ 145 | | 110010 | base | dest | 00011 | del |0| offset | 146 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 147 | Format: SDV $v[del], offset(base) 148 | 149 | +-----------+---------------------------------------------------+ 150 | | SQV | Store quad (quadword) from vector | 151 | +-----------+---------+---------+---------+-------+-+-----------+ 152 | | 110010 | base | dest | 00100 | del |0| offset | 153 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 154 | Format: SQV $v[del], offset(base) 155 | 156 | +-----------+---------------------------------------------------+ 157 | | SRV | Store rest from vector | 158 | +-----------+---------+---------+---------+-------+-+-----------+ 159 | | 110010 | base | dest | 00101 | del |0| offset | 160 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 161 | Format: SRV $v[del], offset(base) 162 | 163 | +-----------+---------------------------------------------------+ 164 | | SPV | Store packed from vector | 165 | +-----------+---------+---------+---------+-------+-+-----------+ 166 | | 110010 | base | dest | 00110 | del |0| offset | 167 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 168 | Format: SPV $v[del], offset(base) 169 | 170 | +-----------+---------------------------------------------------+ 171 | | SUV | Store unpacked from vector | 172 | +-----------+---------+---------+---------+-------+-+-----------+ 173 | | 110010 | base | dest | 00111 | del |0| offset | 174 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 175 | Format: SUV $v[del], offset(base) 176 | 177 | +-----------+---------------------------------------------------+ 178 | | SHV | Store half from vector | 179 | +-----------+---------+---------+---------+-------+-+-----------+ 180 | | 110010 | base | dest | 01000 | del |0| offset | 181 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 182 | Format: SHV $v[del], offset(base) 183 | 184 | +-----------+---------------------------------------------------+ 185 | | SFV | Store fourth from vector | 186 | +-----------+---------+---------+---------+-------+-+-----------+ 187 | | 110010 | base | dest | 01001 | del |0| offset | 188 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 189 | Format: SFV $v[del], offset(base) 190 | 191 | +-----------+---------------------------------------------------+ 192 | | SWV | Store wrap from vector | 193 | +-----------+---------+---------+---------+-------+-+-----------+ 194 | | 110010 | base | dest | 01010 | del |0| offset | 195 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 196 | Format: SWV $v[del], offset(base) 197 | 198 | +-----------+---------------------------------------------------+ 199 | | STV | Store transpose from vector | 200 | +-----------+---------+---------+---------+-------+-+-----------+ 201 | | 110010 | base | dest | 01011 | del |0| offset | 202 | +-----6-----+----5----+----5----+----5----+---4---+1+-----6-----+ 203 | Format: STV $v[del], offset(base) 204 | 205 | 206 | 207 | **************************************************************************** 208 | ** Vector instructions ** 209 | **************************************************************************** 210 | ----------------------------------------------------------------- 211 | | VMULF | Vector (Frac) Multiply | 212 | |-----------|---------------------------------------------------| 213 | | 010010 |1| el | s2 | s1 | dest | 000000 | 214 | ------6------1----4--------5---------5---------5----------6------ 215 | Format: VMULF $v, $v, $v[el] 216 | 217 | ----------------------------------------------------------------- 218 | | VMULU | Vector (Unsigned Frac) Multiply | 219 | |-----------|---------------------------------------------------| 220 | | 010010 |1| el | s2 | s1 | dest | 000001 | 221 | ------6------1----4--------5---------5---------5----------6------ 222 | Format: VMULU $v, $v, $v[el] 223 | 224 | ----------------------------------------------------------------- 225 | | VRNDP | Vector DCT Round (+) | 226 | |-----------|---------------------------------------------------| 227 | | 010010 |1| el | s2 | s1 | dest | 000010 | 228 | ------6------1----4--------5---------5---------5----------6------ 229 | Format: VRNDP $v, $v, $v[el] 230 | 231 | ----------------------------------------------------------------- 232 | | VMULQ | Vector (Integer) Multiply | 233 | |-----------|---------------------------------------------------| 234 | | 010010 |1| el | s2 | s1 | dest | 000011 | 235 | ------6------1----4--------5---------5---------5----------6------ 236 | Format: VMULQ $v, $v, $v[el] 237 | 238 | ----------------------------------------------------------------- 239 | | VMUDL | Vector low multiply | 240 | |-----------|---------------------------------------------------| 241 | | 010010 |1| el | s2 | s1 | dest | 000100 | 242 | ------6------1----4--------5---------5---------5----------6------ 243 | Format: VMUDL $v, $v, $v[el] 244 | 245 | ----------------------------------------------------------------- 246 | | VMUDM | Vector mid-m multiply | 247 | |-----------|---------------------------------------------------| 248 | | 010010 |1| el | s2 | s1 | dest | 000101 | 249 | ------6------1----4--------5---------5---------5----------6------ 250 | Format: VMUDM $v, $v, $v[el] 251 | 252 | ----------------------------------------------------------------- 253 | | VMUDN | Vector mid-n multiply | 254 | |-----------|---------------------------------------------------| 255 | | 010010 |1| el | s2 | s1 | dest | 000110 | 256 | ------6------1----4--------5---------5---------5----------6------ 257 | Format: VMUDN $v, $v, $v[el] 258 | 259 | ----------------------------------------------------------------- 260 | | VMUDH | Vector high multiply | 261 | |-----------|---------------------------------------------------| 262 | | 010010 |1| el | s2 | s1 | dest | 000111 | 263 | ------6------1----4--------5---------5---------5----------6------ 264 | Format: VMUDH $v, $v, $v[el] 265 | 266 | ----------------------------------------------------------------- 267 | | VMACF | Vector (Frac) Multiply Accumulate | 268 | |-----------|---------------------------------------------------| 269 | | 010010 |1| el | s2 | s1 | dest | 001000 | 270 | ------6------1----4--------5---------5---------5----------6------ 271 | Format: VMACF $v, $v, $v[el] 272 | 273 | ----------------------------------------------------------------- 274 | | VMACU | Vector (Unsigned Frac) Multiply Accumulate | 275 | |-----------|---------------------------------------------------| 276 | | 010010 |1| el | s2 | s1 | dest | 001001 | 277 | ------6------1----4--------5---------5---------5----------6------ 278 | Format: VMACU $v, $v, $v[el] 279 | 280 | ----------------------------------------------------------------- 281 | | VRNDN | Vector DCT Round (-) | 282 | |-----------|---------------------------------------------------| 283 | | 010010 |1| el | s2 | s1 | dest | 001010 | 284 | ------6------1----4--------5---------5---------5----------6------ 285 | Format: VRNDN $v, $v, $v[el] 286 | 287 | ----------------------------------------------------------------- 288 | | VMACQ | Vector (Integer) Multiply Accumulate | 289 | |-----------|---------------------------------------------------| 290 | | 010010 |1| el | s2 | s1 | dest | 001011 | 291 | ------6------1----4--------5---------5---------5----------6------ 292 | Format: VMACQ $v, $v, $v[el] 293 | 294 | ----------------------------------------------------------------- 295 | | VMADL | Vector low multiply accumulate | 296 | |-----------|---------------------------------------------------| 297 | | 010010 |1| el | s2 | s1 | dest | 001100 | 298 | ------6------1----4--------5---------5---------5----------6------ 299 | Format: VMADL $v, $v, $v[el] 300 | 301 | ----------------------------------------------------------------- 302 | | VMADM | Vector mid-m multiply accumulate | 303 | |-----------|---------------------------------------------------| 304 | | 010010 |1| el | s2 | s1 | dest | 001101 | 305 | ------6------1----4--------5---------5---------5----------6------ 306 | Format: VMADM $v, $v, $v[el] 307 | 308 | ----------------------------------------------------------------- 309 | | VMADN | Vector mid-n multiply accumulate | 310 | |-----------|---------------------------------------------------| 311 | | 010010 |1| el | s2 | s1 | dest | 001110 | 312 | ------6------1----4--------5---------5---------5----------6------ 313 | Format: VMADN $v, $v, $v[el] 314 | 315 | ----------------------------------------------------------------- 316 | | VMADH | Vector high multiply accumulate | 317 | |-----------|---------------------------------------------------| 318 | | 010010 |1| el | s2 | s1 | dest | 001111 | 319 | ------6------1----4--------5---------5---------5----------6------ 320 | Format: VMADH $v, $v, $v[el] 321 | -------------------------------------------------------------------------------- /n64ops/n64ops#f.txt: -------------------------------------------------------------------------------- 1 | Nintendo 64 Toolkit: opcodes v1.1 by anarko 2 | 3 | Part F: RSP opcode matrix released on 1999-04-21 4 | ---------------------------------------------------------------------------- 5 | 6 | All information on the RSP was provided by my friend Zilmar. 7 | 8 | **************************************************************************** 9 | ** Main CPU ** 10 | **************************************************************************** 11 | 12 | CPU: Instructions encoded by opcode field. 13 | 31---------26---------------------------------------------------0 14 | | opcode | | 15 | ------6---------------------------------------------------------- 16 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 17 | 000 | *1 | *2 | J | JAL | BEQ | BNE | BLEZ | BGTZ | 18 | 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI | 19 | 010 | *3 | --- | *4 | --- | --- | --- | --- | --- | 20 | 011 | --- | --- | --- | --- | --- | --- | --- | --- | 21 | 100 | LB | LH | --- | LW | LBU | LHU | --- | --- | 22 | 101 | SB | SH | --- | SW | --- | --- | --- | --- | 23 | 110 | --- | --- | *LWC2 | --- | --- | --- | --- | --- | 24 | 111 | --- | --- | *SWC2 | --- | --- | --- | --- | --- | 25 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 26 | *1 = SPECIAL, see SPECIAL list *2 = REGIMM, see REGIMM list 27 | *3 = COP0 *4 = COP2 28 | *LWC2 = RSP Load instructions *SWC2 = RSP Store instructions 29 | 30 | SPECIAL: Instr. encoded by function field when opcode field = SPECIAL. 31 | 31---------26-----------------------------------------5---------0 32 | | = SPECIAL | | function| 33 | ------6----------------------------------------------------6----- 34 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 35 | 000 | SLL | --- | SRL | SRA | SLLV | --- | SRLV | SRAV | 36 | 001 | JR | JALR | --- | --- | --- | BREAK | --- | --- | 37 | 010 | --- | --- | --- | --- | --- | --- | --- | --- | 38 | 011 | --- | --- | --- | --- | --- | --- | --- | --- | 39 | 100 | ADD | ADDU | SUB | SUBU | AND | OR | XOR | NOR | 40 | 101 | --- | --- | SLT | SLTU | --- | --- | --- | --- | 41 | 110 | --- | --- | --- | --- | --- | --- | --- | --- | 42 | 111 | --- | --- | --- | --- | --- | --- | --- | --- | 43 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 44 | 45 | REGIMM: Instructions encoded by the rt field when opcode field = REGIMM. 46 | 31---------26----------20-------16------------------------------0 47 | | = REGIMM | | rt | | 48 | ------6---------------------5------------------------------------ 49 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 50 | 00 | BLTZ | BGEZ | --- | --- | --- | --- | --- | --- | 51 | 01 | --- | --- | --- | --- | --- | --- | --- | --- | 52 | 10 |BLTZAL |BGEZAL | --- | --- | --- | --- | --- | --- | 53 | 11 | --- | --- | --- | --- | --- | --- | --- | --- | 54 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 55 | 56 | 57 | **************************************************************************** 58 | ** COP0 ** 59 | **************************************************************************** 60 | 61 | COP0: Instructions encoded by the fmt field when opcode = COP0. 62 | 31--------26-25------21 ----------------------------------------0 63 | | 010000 | fmt | | 64 | ------6----------5----------------------------------------------- 65 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 66 | 00 | MFC0 | --- | --- | --- | MTC0 | --- | --- | --- | 67 | 01 | --- | --- | --- | --- | --- | --- | --- | --- | 68 | 10 | --- | --- | --- | --- | --- | --- | --- | --- | 69 | 11 | --- | --- | --- | --- | --- | --- | --- | --- | 70 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 71 | 72 | 73 | **************************************************************************** 74 | ** COP2 - Reality Coprocessor (RCP) ** 75 | **************************************************************************** 76 | 77 | COP2: Instructions encoded by the fmt field when opcode = COP2. 78 | 31--------26-25------21 ----------------------------------------0 79 | | = COP2 | fmt | | 80 | ------6----------5----------------------------------------------- 81 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 82 | 00 | MFC2 | --- | CFC2 | --- | MTC2 | --- | CTC2 | --- | 83 | 01 | --- | --- | --- | --- | --- | --- | --- | --- | 84 | 10 | *1 | *1 | *1 | *1 | *1 | *1 | *1 | *1 | 85 | 11 | *1 | *1 | *1 | *1 | *1 | *1 | *1 | *1 | 86 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 87 | *1 = Vector opcode 88 | 89 | 90 | RSP Load: Instr. encoded by rd field when opcode field = LWC2 91 | 31---------26-------------------15-------11---------------------0 92 | | 110010 | | rd | | 93 | ------6-----------------------------5---------------------------- 94 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 95 | 00 | LBV | LSV | LLV | LDV | LQV | LRV | LPV | LUV | 96 | 01 | LHV | LFV | LWV | LTV | --- | --- | --- | --- | 97 | 10 | --- | --- | --- | --- | --- | --- | --- | --- | 98 | 11 | --- | --- | --- | --- | --- | --- | --- | --- | 99 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 100 | 101 | RSP Store: Instr. encoded by rd field when opcode field = SWC2 102 | 31---------26-------------------15-------11---------------------0 103 | | 111010 | | rd | | 104 | ------6-----------------------------5---------------------------- 105 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 106 | 00 | SBV | SSV | SLV | SDV | SQV | SRV | SPV | SUV | 107 | 01 | SHV | SFV | SWV | STV | --- | --- | --- | --- | 108 | 10 | --- | --- | --- | --- | --- | --- | --- | --- | 109 | 11 | --- | --- | --- | --- | --- | --- | --- | --- | 110 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 111 | 112 | Vector opcodes: Instr. encoded by the function field when opcode = COP2. 113 | 31---------26---25------------------------------------5---------0 114 | | = COP2 | 1 | | function| 115 | ------6-------1--------------------------------------------6----- 116 | |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo 117 | 000 | VMULF | VMULU | VRNDP | VMULQ | VMUDL | VMUDM | VMUDN | VMUDH | 118 | 001 | VMACF | VMACU | VRNDN | VMACQ | VMADL | VMADM | VMADN | VMADH | 119 | 010 | VADD | VSUB | VSUT? | VABS | VADDC | VSUBC | VADDB?| VSUBB?| 120 | 011 | VACCB?| VSUCB?| VSAD? | VSAC? | VSUM? | VSAW | --- | --- | 121 | 100 | VLT | VEQ | VNE | VGE | VCL | VCH | VCR | VMRG | 122 | 101 | VAND | VNAND | VOR | VNOR | VXOR | VNXOR | --- | --- | 123 | 110 | VRCP | VRCPL | VRCPH | VMOV | VRSQ | VRSQL | VRSQH | --- | 124 | 110 | --- | --- | --- | --- | --- | --- | --- | --- | 125 | hi |-------|-------|-------|-------|-------|-------|-------|-------| 126 | Comment: Those with a ? in the end of them may not exist 127 | -------------------------------------------------------------------------------- /n64ops/n64ops#g.txt: -------------------------------------------------------------------------------- 1 | Nintendo 64 Toolkit: opcodes v1.1 by anarko 2 | 3 | Part G: ROM header information released on 1999-04-21 4 | ---------------------------------------------------------------------------- 5 | 6 | * Mr Backup Z64 (.BIN or .Z64 files) uses a Low/High byte format 7 | (Big endian), wich is the "correct" format to read from. 8 | 9 | * Doctor V64 (.V64, .N64 or .U64 files) uses a High/Low byte format 10 | (Middle endian), so each word are byte flipped, like this: 11 | "ETTSNI G" 12 | When it should look like this: 13 | "TESTING " 14 | To solve this, rotate each word by 8 bits. 15 | 16 | ---------------------------------------------------------------------------- 17 | The addresses below is only valid for ROM's in Low/High 18 | format, eg: Mr Backup Z64 ROM's. You have to byteswap Doctor 19 | V64 ROM's before you can read data that makes any sense. 20 | ---------------------------------------------------------------------------- 21 | 0000h (1 byte): initial PI_BSB_DOM1_LAT_REG value (0x80) 22 | 0001h (1 byte): initial PI_BSB_DOM1_PGS_REG value (0x37) 23 | 0002h (1 byte): initial PI_BSB_DOM1_PWD_REG value (0x12) 24 | 0003h (1 byte): initial PI_BSB_DOM1_PGS_REG value (0x40) 25 | 0004h - 0007h (1 dword): ClockRate 26 | 0008h - 000Bh (1 dword): Program Counter (PC) 27 | 000Ch - 000Fh (1 dword): Release 28 | 0010h - 0013h (1 dword): CRC1 29 | 0014h - 0017h (1 dword): CRC2 30 | 0018h - 001Fh (2 dwords): Unknown (0x0000000000000000) 31 | 0020h - 0033h (20 bytes): Image name 32 | Padded with 0x00 or spaces (0x20) 33 | 0034h - 0037h (1 dword): Unknown (0x00000000) 34 | 0038h - 003Bh (1 dword): Manufacturer ID 35 | 0x0000004E = Nintendo ('N') 36 | 003Ch - 003Dh (1 word): Cartridge ID 37 | 003Eh - 003Fh (1 word): Country code 38 | 0x4400 = Germany ('D') 39 | 0x4500 = USA ('E') 40 | 0x4A00 = Japan ('J') 41 | 0x5000 = Europe ('P') 42 | 0x5500 = Australia ('U') 43 | 0040h - 0FFFh (1008 dwords): Boot code 44 | 45 | -------------------------------------------------------------------------------- /n64ops/rcp.txt: -------------------------------------------------------------------------------- 1 | Note: This document contains some errors, please refer to n64ops#f.txt, 2 | n64ops#g.txt for information about the RSP opcodes, and n64ops#c.txt 3 | for the opcode matrix. /anarko 4 | 5 | 6 | 7 | 8 | ============================================================================= 9 | RCP Technical Information - v1.0 10 | ============================================================================= 11 | 12 | 13 | Overview 14 | -------- 15 | 16 | This is the file which I am sure many a N64 emu programmer has been waiting 17 | for. I know I wanted it when I started but I had to compile this document 18 | myself. 19 | 20 | Please Note: This information is a compilation from many sources and it is 21 | possible that some of this may or may not be correct. However, I have 22 | endevoured to make sure that it is as accurate as possible. 23 | 24 | This document is also incomplete so I will be adding more information in 25 | future releases. 26 | 27 | So what is included in this document: 28 | 29 | * RSP Overview 30 | * RCP Opcode Encoding 31 | * RCP Vector Instruction Set 32 | 33 | 34 | RSP Overview 35 | ------------ 36 | 37 | The RSP instruction set is essentially a 32-Bit subset of the MIPS R4000 38 | instruction set, with some extensions. Instructions which are not 39 | implemented include: 40 | 41 | * Any 64-bit Instruction 42 | * Mulitplies 43 | * Divides 44 | * Branch Likely 45 | * Most System Control Opcodes 46 | 47 | The RSP Vector Unit (VU) is implemented as a MIPS Coprocessor (COP2), 48 | with the machine language conforming to the MIPS Coprocessor definition. 49 | The RSP assembler uses a mnemonic syntax for each VU instruction. 50 | 51 | The RSP Registers are as follows: 52 | 53 | * 32 x 32 bit Scalar Registers (Normal MIPS set). 54 | * 32 Vector Registers, each with 8 x 16 bit entries. 55 | * No Scalar Multiplies or HI/LO registers. 56 | * 8 Vector ALUs. Each ALU appears to have a 'hidden' 32 bit accumulator 57 | and hidden flags registers. 58 | 59 | The RSP can only address it's 4K IMEM and 4K DMEM, everything else has to 60 | be done via DMA. The RCP DMA control registers are mapped to COP0 61 | registers. 62 | 63 | RSP Memory is as follows: 64 | 65 | * RSP DMEM Start 0x04000000 66 | * RSP DMEM End 0x04000FFF 67 | * RSP IMEM Start 0x04001000 68 | * RSP IMEM End 0x04001FFF 69 | 70 | The MUL/MAC instructions do 16 x 16 -> 32 and combine this with the hidden 71 | accumulator in various ways. The upshot is that it is possible to do 72 | 32 x 32 -> 32 multiplies in the following four instructions: 73 | 74 | * VMUDL 75 | * VMADM 76 | * VMADN 77 | * VMADH 78 | 79 | The COP2 control registers appear to be vector ALU flags, bit per element. 80 | (VCO, VCC, VCE) 81 | 82 | The vector opcodes are all 3 operand, and the second source can have a 83 | modifier allowing elements to be replicated in various ways: 84 | 85 | Instruction Elements of $v3 sent to ALUs 86 | 87 | vadd $v1, $v2, $v3 0 1 2 3 4 5 6 7 88 | vadd $v1, $v2, $v3[0q] 0 1 2 3 0 1 2 3 89 | vadd $v1, $v2, $v3[1q] 4 5 6 7 4 5 6 7 90 | vadd $v1, $v2, $v3[0h] 0 1 0 1 0 1 0 1 91 | vadd $v1, $v2, $v3[1h] 2 3 2 3 2 3 2 3 92 | vadd $v1, $v2, $v3[2h] 4 5 4 5 4 5 4 5 93 | vadd $v1, $v2, $v3[3h] 6 7 6 7 6 7 6 7 94 | vadd $v1, $v2, $v3[0] 0 0 0 0 0 0 0 0 95 | vadd $v1, $v2, $v3[1] 1 1 1 1 1 1 1 1 96 | vadd $v1, $v2, $v3[2] 2 2 2 2 2 2 2 2 97 | vadd $v1, $v2, $v3[3] 3 3 3 3 3 3 3 3 98 | vadd $v1, $v2, $v3[4] 4 4 4 4 4 4 4 4 99 | vadd $v1, $v2, $v3[5] 5 5 5 5 5 5 5 5 100 | vadd $v1, $v2, $v3[6] 6 6 6 6 6 6 6 6 101 | vadd $v1, $v2, $v3[7] 7 7 7 7 7 7 7 7 102 | 103 | Loads and stores can access byte, short, word, double word or quad word. 104 | For sizes less than quad word, the offset in the vector regsiter can be 105 | selected (on boundaries of that size). There are a whole bunch of 'fancy' 106 | loads and store which appear to shuffle the data on the way in out in 107 | useful ways. The offset for vector loads and vector stores is scaled 108 | depending on the element size. 109 | 110 | The 'guess' instructions (VRCP?, VRSQ?) are pipelined - result is derived 111 | from the previous instructions. 112 | 113 | With some of the Vector Multiply Instructions the Accumlator is a hidden 114 | 32 bit accumulator per element. 115 | 116 | * VMUDL: acc = (src1 * src2) >> 16, dest = acc & 0xffff 117 | * VMADL: acc += (src1 * src2) >> 16, dest = acc & 0xffff 118 | * VMUDM: acc = (src1 * src2), dest = acc >> 16 119 | * VMADM: acc += (src1 * src2), dest = acc >> 16 120 | * VMUDN: acc = (src1 * src2), dest = acc & 0xffff 121 | * VMADN: acc += (src1 * src2), dest = acc & 0xffff 122 | * VMUDH: acc = (src1 * src2) >> 16, dest = acc >> 16 123 | * VMADH: acc += (src1 * src2) >> 16, dest = acc >> 16 124 | 125 | 126 | RCP Opcode Encoding 127 | ------------------- 128 | 129 | This section is still in it's preliminary stages. 130 | 131 | 132 | R-Type (Register) Instruction Format 133 | 134 | +-----------+---------+-------+-------+-------+-----------+ 135 | | OP | RS | RT | RD | SA | Funct | 136 | +-----------+---------+-------+-------+-------+-----------+ 137 | | 010010 | 10000 | ????? | ????? | ????? | ?????? | 138 | | | | | | | | 139 | | CP2 Instr | Sub OpC | VReg3 | VReg2 | VReg1 | CP2 Funct | 140 | +-----------+---------+-------+-------+-------+-----------+ 141 | 142 | 143 | 2..0 COP2 Function 144 | 0 1 2 3 4 5 6 7 145 | 5..3 +-------+-------+-------+-------+-------+-------+-------+-------+ 146 | 0 | VMULF | VMULU | VRNDP | VMULQ | VMUDL | VMUDM | VMUDN | VMUDH | 147 | +-------+-------+-------+-------+-------+-------+-------+-------+ 148 | 1 | VMACF | VMACU | VRNDN | VMACQ | VMADL | VMADM | VMADN | VMADH | 149 | +-------+-------+-------+-------+-------+-------+-------+-------+ 150 | 2 | VADD | VSUB | VSUT | VABS | VADDC | VSUBC | VADDB | VSUBB | 151 | +-------+-------+-------+-------+-------+-------+-------+-------+ 152 | 3 | VACCB | VSUCB | VSAD | VSAC | VSUM | VSAW | | | 153 | +-------+-------+-------+-------+-------+-------+-------+-------+ 154 | 4 | VLT | VEQ | VNE | VGE | VCL | VCH | VCR | VMRG | 155 | +-------+-------+-------+-------+-------+-------+-------+-------+ 156 | 5 | VAND | VNAND | VOR | VNOR | VNXOR | | | | 157 | +-------+-------+-------+-------+-------+-------+-------+-------+ 158 | 6 | | | | | | | | | 159 | +-------+-------+-------+-------+-------+-------+-------+-------+ 160 | 7 | VEXTT | VEXTQ | VEXTN | VINST | VINSQ | VINSN | | | 161 | +-------+-------+-------+-------+-------+-------+-------+-------+ 162 | 163 | 164 | 165 | RCP Vector Instruction Set 166 | -------------------------- 167 | 168 | This section is still in it's preliminary stages. I have a lot more 169 | information about each instruction but have not had the time to write it 170 | all up yet. 171 | 172 | 173 | VMULF Vector (Frac) Multiply 174 | VMACF Vector (Frac) Multiply Accumulate 175 | VMULU Vector (Unsigned Frac) Multiply 176 | VMACU Vector (Unsigned Frac) Multiply Accumulate 177 | VRNDP Vector DCT Round (+) 178 | VRNDN Vector DCT Round (-) 179 | VMULQ Vector (Integer) Multiply 180 | VMACQ Vector (Integer) Multiply Accumulate 181 | VMUDH Vector (High) Multiply 182 | VMADH Vector (High) Multiply Accumulate 183 | VMUDM Vector (Mid-M) Multiply 184 | VMADM Vector (Mid-M) Multiply Accumulate 185 | VMUDN Vector (Mid-N) Multiply 186 | VMADN Vector (Mid-N) Multiply Accumulate 187 | VMUDL Vector (Low) Multiply 188 | VMADL Vector (Low) Multiply Accumulate 189 | VADD Vector Add 190 | VSUB Vector Subtract 191 | VSUT Vector SUT (vt - vs) 192 | VABS Vector Absolute Value 193 | VADDC Vector ADDC 194 | VSUBC Vector SUBC 195 | VADDB Vector Add Byte 196 | VSUBB Vector Subtract Byte 197 | VACCB Vector Add Byte/Add Accumulator 198 | VSUCB Vector Subtract Byte/Add Accumulator 199 | VSAD Vector SAD 200 | VSAC Vector SAC 201 | VSUM Vector SUM 202 | VSAW Vector SAW 203 | VLT Vector Less Than 204 | VEQ Vector Equal To 205 | VNE Vector Not Equal To 206 | VGE Vector Greater Than or Equal To 207 | VCL Vector Clip Low 208 | VCH Vector Clip High 209 | VCR Vector, 1's Complement Clip 210 | VMRG Vector Merge 211 | VAND Vector Logical AND 212 | VNAND Vector Logical NAND 213 | VOR Vector Logical OR 214 | VNOR Vector Logical NOR 215 | VXOR Vector Logical Exclusive OR 216 | VNXOR Vector Logical NOT Exclusive OR 217 | VNOOP Vector No-Operation 218 | VMOV Vector Scalar-Element Move 219 | VRCP Single Precision, Lookup Source, Write Result 220 | VRSQ Single Precision, Lookup Source, Write Result 221 | VRCPH Set Source, Write Previous Result 222 | VRSQH Set Source, Write Previous Result 223 | VRCPL Lookup Source and Previous, Write Result 224 | VRSQL Lookup Source and Previous, Write Result 225 | VINST Vector Insert Triple (5/5/5/1) 226 | VEXTT Vector Extract Triple (5/5/5/1) 227 | VINSQ Vector Insert Quad (4/4/4/4) 228 | VEXTQ Vector Extract Quad (4/4/4/4) 229 | VINSN Vector Insert Nibble (4/4/4/4) Sign-Extended 230 | VEXTN Vector Insert Nibble (4/4/4/4) Sign-Extended 231 | 232 | 233 | LBV Load Byte into Vector 234 | LSV Load Short into Vector 235 | LLV Load Word into Vector 236 | LDV Load Doubleword into Vector 237 | LQV Load Quadword into Vector 238 | LRV Load Rest Vector 239 | LPV Load Packed Vector 240 | LUV Load Unpack Vector 241 | LHV Load Half Vector 242 | LFV Load Fourth Vector 243 | LWV Load Wrap Vector 244 | LTV Load Transpose Vector 245 | 246 | 247 | SBV Store Byte from Vector 248 | SSV Store Short from Vector 249 | SLV Store Word from Vector 250 | SDV Store Doubleword from Vector 251 | SQV Store Quadword from Vector 252 | SRV Store Rest Vector 253 | SPV Store Packed Vector 254 | SUV Store Unpack Vector 255 | SHV Store Half Vector 256 | SFV Store Fourth Vector 257 | SWV Store Wrap Vector 258 | STV Store Transpose Vector 259 | 260 | I have not included the standard MIPS opcodes used in the RCP. 261 | 262 | 263 | -------------------------------------------------------------------------------- /n64ops/readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/n64ops/readme.txt -------------------------------------------------------------------------------- /n64ops/sound.txt: -------------------------------------------------------------------------------- 1 | heres how one way to make sound on N64 : 2 | Crazy nation trainer (xtremeG version) 3 | 4 | 5 | [we tested button and its time to make sound!] 6 | lui $t4,8031 ;make pointer to 'yes' sound 7 | addiu $t4,$t4,4F10 ;80314f10 = start 8 | addiu $t5,$zero,4A71 ;4A71=length 9 | addiu $t6,$zero,1388 ;1388= DAC rate 10 | addiu $t7,$zero,0001 ;1=BIT rate 11 | jal here 12 | nop 13 | [draw yes] 14 | ...... 15 | 16 | [we tested button and time to make 'no' sound] 17 | lui $t4,8031 ;make pointer to 'no' sound 18 | addiu $t4,$t4,12C4 ;803112C4 19 | addiu $t5,$zero,3C45 ;3C45=length 20 | addiu $t6,$zero,1388 ;DAC rate 21 | addiu $t7,$zero,0001 ;1=BIT rate 22 | jal here 23 | nop 24 | [draw no] 25 | 26 | ..... 27 | [...initialize vid, audio] 28 | addiu $t4,$zero,0000 ;[blank out sound] 29 | addiu $t5,$zero,0000 ;initialize 30 | addiu $t6,$zero,0001 31 | addiu $t7,$zero,0001 32 | here: lui $t8,A450 33 | sw $t4,0000($t8) ;start RDRAM address 34 | sw $t5,0004($t8) ;length 35 | addiu $t9,$zero,0001 36 | sw $t9,0008($t8) ;1 = enable dma 37 | sw $t6,0010($t8) ;dac rate 38 | sw $t7,0014($t8) ;bit rate 39 | jr $ra 40 | nop -------------------------------------------------------------------------------- /rambus/n64_rdram_datasheet.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/docs/4ec56c9554e30df9c49bfdac5497bc7b4e4455d2/rambus/n64_rdram_datasheet.pdf -------------------------------------------------------------------------------- /tutorial/day1n64.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | N64 ASM - Day 1 4 | 5 | 6 |

Day 1

7 |
  8 | 
  9 | 
 10 | 
 11 | 
12 |

Figuring out the Assembler

13 |


 14 | 	First, there are several assemblers you could use for the N64, the one I've had
 15 | the most luck using is ASMN6432.EXE from the PSY-Q devkit. Unfortunately, I can't tell
 16 | you where to get the devkit (which does contain a C compiler, so if you're not macho enough
 17 | to use assembler, you can go right ahead and use those illegal libs!), because many people
 18 | would object to it. It's simple enough to find with a search on Google, I regularly loose
 19 | the URL and then find it again in about 30 min. with Google. LEARN THE WAYS OF THE GOOGLE!
 20 | 
 21 | 	The other assemblers that I've had some success with are the one by HalleysCometSoftware
 22 | and Anarko's assembler (in that order). You can get HCS's assembler (and good demo code) from the link above.
 23 | Anarko's assembler is on Dextrose. 
 24 | 
 25 | 	I recommend creating a directory like C:\n64asm\ , so that it has no spaces and you can just
 26 | keep everything in there. Each one of these assemblers needs a different style command to assemble,
 27 | they are: (On the DOS/CMD command-line)
 28 | 
 29 | 	For ASMN6432.EXE:
 30 | 		asmn6432 /p SOURCE,OUTPUTFILE.BIN
 31 | 		copy HEADER /B+OUTPUTFILE.BIN OUTPUTFILE.N64
 32 | 
 33 | 	For n64asm.exe (Anarko's):
 34 | 		Look at the demo sources for the header puesdo-codes, and type n64asm by itself
 35 | 		on the command-line for how to assemble.
 36 | 
 37 | 	For n64.exe (HCS's):
 38 | 		n64 SOURCE.ASM -r
 39 | 
 40 | You may have noticed that ASMN6432 needs an extra command that adds the rom header, you can get
 41 | that from HCS's zip file. 
 42 | 		
 43 | 	Second, I must say that what I know about the N64 (everything I know at a certain time
 44 | that can be applied toward a certain working code file will be eventually described in a "Day"),
 45 | which isn't much as I write this, came from reading documents found on Dextrose and the web AND
 46 | from HCS kindly putting up with my endless questions on Dextrose's Forum, this (hopefully to be
 47 | these) document(hopefully (s)) would not have been possible without his help.
 48 | 
 49 | 

Our First ROM

50 | From here on out, I assume you are using ASMN6432, but N64.exe (HCS's assembler) has 51 | almost the same syntax and, now that I think of it, Anarko's assembler is still quite similar, you'll just have 52 | to figure out how to use each one (and maybe tinker the code a little to get it to assemble on 53 | your chosen assembler. 54 | 55 | Here's our first code file: 56 | 57 | ;;---START OF CODE FILE---;; 58 | org $80000400 59 | 60 | li t1,8 61 | lui t0,$bfc0 62 | sw t1,$07fc(t0) 63 | 64 | infin: 65 | nop 66 | j infin 67 | ;;---END OF CODE FILE---;; 68 | 69 | Now to see what each line does: 70 | 71 | org $80000400 72 | 73 | This tells the assembler where the entry point of the code is in N64 memory ($80000400 is standard for ASM progs). 74 | 75 | li t1,8 76 | lui t0,$bfc0 77 | sw t1,$07fc(t0) 78 | 79 | These lines (which I got from HCS), stop the N64 from crashing in 5 secs. after your 80 | program starts (according to HCS, and some other people). I'm not going to explain 81 | them until later (because I don't what about them stops the N64 from crashing). 82 | 83 | infin: 84 | 85 | If you don't know what that is, I suggest you go read either the GBA or NES assembly sections (the 86 | GBA one is better written in my opinion). Here's a link for you. 87 | 88 | nop 89 | 90 | A Classic, it does nothing, that's right, nothing, except that you should put NOPs 91 | after labels, a spot appearantly known as a "Delay Slot", some assemblers get pissed off 92 | if you have anything but a NOP in the Delay Slot. 93 | 94 | j infin 95 | 96 | J is the jump instruction, J jumps to a label, like Goto in BASIC. In this case, J jumps to 97 | infin, creating an infinite loop like while(1); . 98 | 99 | Assemble your file like shown in the beginning, if you get no errors, you've done a good job. 100 | (I recommend (again) that you keep your assembler and code files in C:\n64asm\, and CD to that 101 | directory in DOS, when you want to assemble something) 102 | 103 |

This Day In Review

104 | 105 | Tomorrow, we'll download an emulator and a plugin needed for the type of programming 106 | where using. Hopefully, we'll quickly get to setting up our VI (Video Interface) registers. 107 | 108 | Until Next Time, 109 | -Mike H a.k.a GbaGuy 110 | 111 |
Intro - Day 2
112 | 113 |

114 | 115 | -------------------------------------------------------------------------------- /tutorial/day2n64.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | N64 ASM - Day 2 4 | 5 | 6 |

Day 2

7 |
 8 | 
 9 | 
10 | 
11 | 
12 |

Some Instructions

13 |


14 | 	In the other tutorials, I may have sort of taught the assembly language
15 | and the system workings at the same time. I don't think that would be best this
16 | time around because of the N64 being somewhat more complex. So today, I'll just
17 | describe the registers and the instructions: LI,LA,LW,SW.
18 | 
19 | 

Before We Get Started

20 | You're probably wondering how to run your ROM. Well, Nemu (which you can get from Zophar) 21 | has a pretty good debugger. To run the ROMs that we'll eventually get to making, you need this 22 | Plugin for Nemu to support the bitmap-mode 23 | drawing that we'll be doing (Thanks again to HCS, for pointing me to it). 24 | 25 |

The R4300i

26 | The main processor that will be running all of our code for a while is a standard RISC MIPS R4300i, 27 | similar to the one in the PS1 (identical maybe?). It runs at ~93MHz. This thing has even more registers 28 | than the ARM7 in the GBA!! There are 32 registers, I'm still not positive what they all are for, but they are 29 | (in the order listed in Nemu's debugger): 30 | 31 | R0 - Special in that it is always zero, you can't change it. 32 | AT - Not entirely sure. Seems to be available to us. 33 | V0-V1 - Don't know. 34 | A0-A3 - Are used to pass parameters to subroutines. 35 | T0-T7 - Temporary data registers, what we should use for regular coding. 36 | S0-S7 - Called "Save" or "Saved" registers, preserved across subroutine calls?? 37 | T8-T9 - Don't know, maybe same as other 'T' registers. 38 | K0-K1 - No Clue. 39 | GP - No Clue. 40 | SP - See AT 41 | S8 - No Clue. 42 | RA - Stores the Return Address for subroutine calls. 43 | 44 | If someone can email me and fill me in on the ones that I don't know or anything that's wrong that you 45 | ever see, please correct me. (I suppose I'll look at the MIPS tech docs and fill out the rest of the list) 46 | 47 |

The LI,LA Instructions

48 | First, the LI instruction. The LI instruction takes 2 operands (parameters): 49 | 50 | li t0, 2 ; the register on the left will get the number on the right. 51 | 52 | simple enough. 53 | 54 | Now, the LA instruction. It also takes 2 operands: 55 | 56 | la t4, LABEL ; the register on the left will get the address of the label on the right. 57 | 58 | Easy, but there's another use. You can (have to with HCS's assembler) use it the same as LI also, 59 | so like this: 60 | 61 | la t0,2 ; register/left gets number/right 62 | 63 | Wow, that was way easier and shorter to explain than I thought it was going to be... (Did I miss something?) 64 | 65 |

This Day In Review

66 | 67 | Hopefully tomorrow, we'll take a look at the Video Interface Mem. Registers. 68 | Nintendo seems to like memory mapping their initialization interfaces... 69 | 70 | Happy Learning!, 71 | - GbaGuy 72 | 73 |
Intro - Day 3
74 | 75 |

76 | 77 | -------------------------------------------------------------------------------- /tutorial/day3n64.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | N64 ASM - Day 3 4 | 5 | 6 |

Day 3

7 |
  8 | 
  9 | 
 10 | 
 11 | 
12 |

Video Interface Registers

13 |


 14 | 	The VI (Video Interface) Memory Mapped Registers start at 0xA4400000 in N64 main memory
 15 | and allow you to initialize the bitmapped screen in many different ways (See Anarko's N64OPS on Dextrose.
 16 | Anarko's document lists them starting at 0x04400000, I don't know why. The Video Registers are:
 17 | (As listed by Nemu's debugger):
 18 | 
 19 | 	VI_STATUS_REG (0xA4400000)     - Chooses color-depth, and some gamma/antialias/interlacing options
 20 | 	VI_DRAM_ADDR_REG (0xA4400004)  - The address of the currect framebuffer (set it to the memory you're going to
 21 | 					use for the N64's bitmapped screen.)
 22 | 	VI_H_WIDTH_REG (0xA4400008)    - The Horizontal Resolution of the framebuffer.
 23 | 	VI_V_INTR_REG (0xA440000C)     - Not sure. Check out N64OPS.
 24 | 	VI_V_CURRENT_LINE_REG (0xA4400010)  - I think it gives the current line that is being drawn. (use it to check
 25 | 						for VBlank??)
 26 | 	VI_TIMING_REG (0xA4400014)     - Not sure what it means that N64OPS says..
 27 | 	VI_V_SYNC_REG (0xA4400018)     - "number of half-lines per field", what the **** does that mean?
 28 | 	VI_H_SYNC_REG (0xA440001C)     - Don't know. See N64OPS.
 29 | 	VI_H_SYNC_LEAP_REG (0xA4400020)  - Don't know. See N64OPS.
 30 | 	VI_H_VIDEO_REG (0xA4400024)      - Ditto.
 31 | 	VI_V_VIDEO_REG (0xA4400028)      - Ditto.
 32 | 	VI_V_BURST_REG (0xA440002C)      - Ditto.
 33 | 	VI_X_SCALE_REG (0xA4400030)      - Seems obvious, but description is a little wierd, commonly seen at 0x200.
 34 | 	VI_Y_SCALE_REG (0xA4400034)      - Seems obvious, but description is a little wierd, commonly seen at 0x400.
 35 | 
 36 | I'll fill out this chart as I figure out exactly what each one does. See Anarko's N64OPS for his
 37 | description (which come almost straight from the comments from the official dev headers).
 38 | 
 39 | If anyone has some more info on these, please email me (I'm going to be saying that alot, aren't I? :) )
 40 | 
 41 | 

Before We Get Started

42 | You're probably wondering how to run your ROM. Well, Nemu (which you can get from Zophar) 43 | has a pretty good debugger. To run the ROMs that we'll eventually get to making, you need this 44 | Plugin for Nemu to support the bitmap-mode 45 | drawing that we'll be doing (Thanks again to HCS, for pointing me to it). 46 | 47 |

Initialization of Video

48 | But first, there's 2 instructions we still need to learn: LW and SW. They work like so: 49 | 50 | LW Loads a 32-bit Word from memory like this: 51 | lw t1,0(t3) ; the 32-bit word at the address created by the memory location 52 | ; in t3 + zero in this case, will be put into t1. 53 | Here's another: 54 | lw t0,4(t1) ; the 32bit word at the address created by the memory location in t1 +4 will be put into 55 | ; t0. So if the address 0xA0200004 has 32 in it, 56 | ; and t1 has 0xA0200000 in it plus the 4 will be 0xA0200004 and then t0 will end up with 57 | ; the 32. 58 | 59 | I hope you understood that. 60 | 61 | SW works in precisely the same way except that it will store the register on the left into the memory address 62 | created by the register plus offset on the right. (The 4 and the zero in the examples are the offsets.) 63 | 64 | Here's our video initialization code: 65 | ;;---CODE START---;; 66 | ; I should mention that while I use 0x in this tutorial's text for hexadecimal numbers, 67 | ; ASMN6432.exe uses $. 68 | la t0,$A4400000 ; VI status register (start of VI reg. mem.) 69 | li t1, $103002 ; basically 16bit color and some other things 70 | sw t1,0(t0) 71 | la t1,0xa0200000 ; address of screen bitmap (framebuffer) 72 | sw t1,4(t0) 73 | li t1,320 ; width of screen (horizontal resolution?) 74 | sw t1,8(t0) 75 | li t1,$2 ; Don't know. 76 | sw t1,12(t0) 77 | li t1,$0 ; Ditto. 78 | sw t1,16(t0) 79 | li t1,$3e52239 ; Ditto until next comment 80 | sw t1,20(t0) 81 | li t1,$0000020d 82 | sw t1,24(t0) 83 | li t1,$00000c15 84 | sw t1,28(t0) 85 | li t1,$0c150c15 86 | sw t1,32(t0) 87 | li t1,$006c02ec 88 | sw t1,36(t0) 89 | li t1,$002501ff 90 | sw t1,40(t0) 91 | li t1,$000e0204 92 | sw t1,44(t0) 93 | li t1,$200 ; something about horizontal scaling? 94 | sw t1,48(t0) 95 | li t1,$400 ; something about vertical scaling? 96 | sw t1,52(t0) 97 | ;;---CODE END---;; 98 | 99 | It basically selects a 320x240 16 bit mode, and does some other stuff I don't know yet. 100 | (That code is essentailly the same as code that HCS was again, nice enough to show me, so 101 | now I use 320x240 16 bit mode.) 102 | It probably wouldn't be too hard to change that to 32 bit color, but I just don't feel like 103 | it (I think you'd have to change $103002 to $103003) and 16 bit color is plenty for most things. 104 | The offsets are not permanently added to the register in ()s, so in the code, the offsets just keep 105 | gaining by 4, for each VI register set. 106 | 107 |

This Day In Review

108 | 109 | Tomorrow, we'll learn some math instructions and then the next day, we'll do some loops. 110 | Then, we'll put together a code file that clears the screen (with code that, yep, HCS showed me.) 111 | 112 | Hold on! We're getting there!, 113 | - GBAGuy 114 | 115 |
Intro - Day 4
116 | 117 |

118 | 119 | -------------------------------------------------------------------------------- /tutorial/day4n64.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | N64 ASM - Day 4 4 | 5 | 6 |

Day 4

7 |
 8 | 
 9 | 
10 | 
11 | 
12 |

Math

13 |


14 | 	Today is going to be all about the math instructions ADD and SUB.
15 | 
16 | 

The ADD Instruction

17 | Now, reel in the fish slowly! Oops, ADD means ADDition, not Attension Deficit Disorder! 18 | What was I thinking!. 19 | 20 | Ok, now that the bad joke is out of the way, ADD works like this: 21 | ADD t1,t2,t3 ; t1 = t2 + t3; is just about the simplest way I can describe it. 22 | 23 | I've also seen: 24 | ADD t1, 2 ; which is supposed to be t1 += 2, appearantly. THIS DOESN'T ALWAYS WORK! 25 | ; alot of the time, an assembler either errors or interprets this as t1 += V0 26 | 27 | Which brings me to another point, a register's (in some assemblers) number can be used 28 | instead it it's t1,v0,a3 style name. See Nemu's debugger for as far as I know, is the correct order. 29 | 30 |

The SUB Instruction

31 | INSERT BAD JOKE ABOUT SubWay HERE. 32 | 33 | The SUB Instruction works like so: 34 | SUB t0,t4,t5 ; t0 = t4 - t5; There's a chance I might have t4 and t5 in the wrong order, 35 | ; but I think I have it right. 36 | 37 | The "I've also seen" comment applies to SUB as well. 38 | 39 |

The MUL/DIV Instruction

40 | The MUL and DIV Instructions work like this (as far as I can tell): 41 | 42 | MUL t0,t2,t4 ; t0 = t2 * t4; 43 | 44 | DIV t1,t0,t6 ; t1 = t0 / t6; 45 | 46 | Also note that all these math instructions use signed numbers. 47 | 48 |

Comparison/Branch Instructions

49 | This would have been shorter than I wanted it to be, so I'll have to talk about Comparison/Branch Instructions 50 | also. 51 | 52 | The first instruction we'll learn is BNEZ, BNEZ is a psuedo-instruction that only Anarko's assembler doesn't 53 | support (along with LA). BNEZ is used like so: 54 | 55 | bnez t1, LABEL ; IF t1 not equal zero THEN GOTO LABEL 56 | 57 | For assemblers that don't support it, use: 58 | 59 | bne t1,$0,LABEL ; same as above, note that $0 is the special CPU register that is permanently zero. 60 | 61 | The other use for BNE (no Z) is: 62 | 63 | bne t1,t3,LABEL ; IF t1 not equal t3 THEN GOTO LABEL 64 | 65 | There is also: 66 | 67 | beq t1,t3,LABEL ; IF t1 == t3 THEN GOTO LABEL 68 | 69 | blt t0,t1,LABEL ; IF t0 less than t1 THEN GOTO LABEL 70 | 71 | bgt t0,t1,LABEL ; IF t0 greater then t1 THEN GOTO LABEL 72 | 73 | ble t2,t4,LABEL ; IF t2 less or = to t4 THEN GOTO LABEL 74 | 75 | bge t2,t4,LABEL ; IF t2 greater or = to t4 THEN GOTO LABEL 76 | 77 | Add a U to the end of the instruction (like BGEU) to compare unsigned numbers. 78 | 79 |

This Day In Review

80 | 81 | Tomorrow, we'll either learn another set of instructions, or we'll do 82 | something else (maybe a pic on screen)! 83 | 84 | Until Next Time!, 85 | - Mike H a.k.a GbaGuy 86 | 87 |
Intro - Day 5
88 | 89 |

90 | 91 | -------------------------------------------------------------------------------- /tutorial/day5n64.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | N64 ASM - Day 5 4 | 5 | 6 |

Day 5

7 |
 8 | 
 9 | 
10 | 
11 | 
12 |

Subroutines

13 |


14 | 	Today is going to be short (maybe) and be about subroutines.
15 | The N64 CPU's subroutine call instruction is JAL (Jump And Link) it works
16 | like so:
17 | 
18 | 	JAL LABEL  ; jump to LABEL, putting return address in ra.
19 | 	NOP        ; you should put a NOP after JALs also. Delay Slot?
20 | 
21 | Then at LABEL you have:
22 | 	
23 | LABEL:
24 | 	NOP ; Delay Slot NOP
25 | 	JR ra  ; Jump Register ra (that contains return address)
26 | 
27 | Note that you can't nest subroutine calls, as a subroutine call will erase
28 | the old return value in ra. The GBA is also like that, the NES is not.
29 | 
30 | It would help if there was a built-in stack. (Is there?)
31 | 
32 | 

The LUI Instruction

33 | I'm not sure what the LUI instruction does, but I'm fairly sure 34 | that it loads the second 16bits of a register, like so: 35 | 36 | LI t1,0 ; t1 = $00000000 37 | LUI t1,$a440 ; after instruction, r1 = $a4400000 38 | 39 | Simple enough, if I didn't miss anything. 40 | 41 |

This Day In Review

42 | 43 | Tomorrow, we'll definitely put a pic on the screen! 44 | 45 | I Can't Wait!, 46 | - GbaGuy 47 | 48 |
Intro - Day 6
49 | 50 |

51 | 52 | -------------------------------------------------------------------------------- /tutorial/day6n64.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | N64 ASM - Day 6 4 | 5 | 6 |

Day 6

7 |
  8 | 
  9 | 
 10 | 
 11 | 
12 |

See Screen, See Pic On Screen

13 |


 14 | 	Today we'll put a picture on the screen.
 15 | 
 16 | 

First

17 | Make a 320x240 bitmap in MSPaint, save in C:\n64asm\ as pic.bmp. 18 | Next, goto Dextrose and download the 19 | patch to the GroundZero Devkit, what we want is the BMP2N64 program. Copy 20 | BMP2N64.exe to your n64 assembly folder. Open a DOS Prompt and type: 21 | 22 | cd your assembly folder path 23 | bmp2n64 -in:pic.bmp -out:pic -label:pic -16 24 | 25 | Two files should be created, you can delete the .H file, but keep the .S file. 26 | The .S File may work as is, but I recommend you delete the lines before 27 | the label and replace all ".half"s with "dh" (no quotes). 28 | 29 |

The Code

30 | 31 | The code for this isn't that much different than we've seen before 32 | or that you could have come up with on your own. So here we go (the whole thing): 33 | 34 | ;;---CODE START---;; 35 | org $80000400 ; starting point 36 | 37 | li t1,8 ; crash protection 38 | lui t0,$bfc0 ; I still don't know what this specifically does. 39 | sw t1,$07fc(t0) 40 | 41 | la t0,$A4400000 ; start of VI regs. ; this block initializes Video 42 | li t1, $103002 43 | sw t1,0(t0) 44 | la t1,$a0200000 ; the frame buffer address 45 | sw t1,4(t0) 46 | li t1,320 47 | sw t1,8(t0) 48 | li t1,$2 49 | sw t1,12(t0) 50 | li t1,$0 51 | sw t1,16(t0) 52 | li t1,$3e52239 53 | sw t1,20(t0) 54 | li t1,$0000020d 55 | sw t1,24(t0) 56 | li t1,$00000c15 57 | sw t1,28(t0) 58 | li t1,$0c150c15 59 | sw t1,32(t0) 60 | li t1,$006c02ec 61 | sw t1,36(t0) 62 | li t1,$002501ff 63 | sw t1,40(t0) 64 | li t1,$000e0204 65 | sw t1,44(t0) 66 | li t1,$200 67 | sw t1,48(t0) 68 | li t1,$400 69 | sw t1,52(t0) 70 | 71 | li t0,0xa0200000 72 | li t3,2 73 | la t2,MKImage ; MKImage should be the label in your .S file 74 | li t1,320*240*2-2 75 | drawImage: 76 | lh t4,0(t2) 77 | sh t4,0(t0) ; there's probably a better way, but oh well :) 78 | add t2,t2,t3 79 | add t0,t0,t3 80 | sub t1,t1,t3 ; there's a better place for this that'll be discussed later 81 | bnez t1,drawImage 82 | 83 | infin: 84 | nop 85 | j infin 86 | 87 | include MKImage.S ; MKImage.S should be the filename of your .S File 88 | ;;---CODE STOP---;; 89 | 90 |

This Day In Review

91 | 92 | I hope you take the time to understand code and not just rip it :)! 93 | 94 | Until Next Time!, 95 | - Mike H a.k.a GbaGuy 96 | 97 |
Intro - Day 7
98 | 99 |

100 | 101 | -------------------------------------------------------------------------------- /tutorial/day7n64.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | N64 ASM - Day 7 4 | 5 | 6 |

Day 7

7 |
 8 | 
 9 | 
10 | 
11 | 
12 |

The Delay Slot

13 |


14 | 	This thing is so Evil and Cool at the same time, I can't come up
15 | seem to come up with even a good joke for the intro (I said "Slot!", maybe?).
16 | 
17 | 

The Info

18 | This information is brought to you by HCS: 19 | 20 | The code for this isn't that much different than we've seen before 21 | or that you could have come up with on your own. So here we go (the whole thing): 22 | (It has been slightly edited)(HCS, I hope you don't mind.): 23 | 24 | This is the instruction immediately after a jump or branch instruction. It is executed during the jump (actually, while 25 | the instruction at the target is being fetched). For example, if we have 26 | 27 | code:-------------------------------------------------------------------------------- 28 | jal dest 29 | addi t0,t0,1 30 | -------------------------------------------------------------------------------- 31 | 32 | Both the jump and the addition will occur. There are some instructions which can't be in 33 | delay slots though (I don't have my manual with me right now and I don't remember what they are) 34 | and asmn64 checks for those. One good application for this is to make loops: 35 | 36 | code:-------------------------------------------------------------------------------- 37 | li t0,7 38 | loop: 39 | ; something to be done 8 times 40 | bnez t0, loop 41 | addi t0,-1 42 | -------------------------------------------------------------------------------- 43 | 44 | The increment (decrement in this case) is had for free, during time the processor would be 45 | otherwise wasting. It is important, whenever you code a jump, to put a NOP after it until 46 | you intend to use the delay slot, otherwise some other part of the code might execute 47 | accidentally. I believe that asmn64 has a command line switch to do this for you automatically. 48 | 49 | The exception to the delay slot execution is several branches called "likely". Actually, they still 50 | execute the instruction in the delay slot, but if the branch is not taken the delay instruction 51 | is skipped. This takes some extra time for the processor to ignore the instruction, so they 52 | should only be used when it is "likely" that the branch will be taken. 53 | 54 |

This Day In Review

55 | 56 | It's always good to get the information from someone who knows what they're talking about! 57 | 58 | Important stuff!, 59 | - GbaGuy 60 | 61 |
Intro - Day 8
62 | 63 |

64 | 65 | -------------------------------------------------------------------------------- /tutorial/day8n64.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | N64 ASM - Day 8 4 | 5 | 6 |

Day 8

7 |
  8 | 
  9 | 
 10 | 			
 11 | 
 12 | 
13 |

Getting Code Onto The RSP

14 |


 15 | 	The RSP is M-a-g-i-c-a-l!
 16 | 
 17 | 	Just keep saying that to yourself any time you can't figure why your code isn't working! :)
 18 | 	Just kidding!
 19 | 
 20 | 

The RSP

21 | First, read N64OPS#H.TXT (Anarko's N64OPS doc, which if you don't have by now, pretend I'm hitting 22 | you with a trout!!!) and look at the SP registers section. 23 | 24 | The RSP is like another processor and contains most of the instructions of the main R4300i. The RSP can 25 | only address main memory from 0xA4000000 To 0xA40FFFFF, if you want to access other parts of memory you 26 | have to use the SP Mem. Registers to DMA to other parts of main memory. Conveniently, the SP registers 27 | reside in the part of main memory that the RSP can access. 28 | 29 | There are two sections of the RSP's memory that are for Data and Code respectively, one is DMEM that 30 | stores Data and is at 0xA4000000 to 0xA4000FFF (small :( ). The other is IMEM and stores code for the RSP 31 | to execute and is at 0xA4001000 to 0xA4001FFF. 32 | 33 |

The SP Registers

34 | The RSP Memory registers start at 0xA4040000 and are: 35 | (These aren't in order and are only the ones that we are going to need today.) 36 | 37 | SP_MEM_ADDR_REG (0xA4040000) - Location to DMEM or IMEM to write to, commonly zero. Bit 12 selects 38 | (1) IMEM or (0) DMEM. 39 | So to transfer to/from starting at 0 write 0x1000 for IMEM or 0x0 for DMEM 40 | to this register. 41 | 42 | SP_DRAM_ADDR_REG (0xA4040004) - Location in main memory to DMA to/from. 43 | SP_RD_LEN_REG (0xA4040008) - The length in bytes of data to read from main memory INTO the RSP. 44 | When you write to this register, DMA will start. 45 | 46 | SP_WR_LEN_REG (0xA404000C) - The length in bytes of data to read from RSP TO main memory. 47 | Writing to this register will also start DMA. 48 | 49 | SP_PC_REG (0xA4080000) - The Program Counter for the RSP, set it to 0x0 before starting the RSP. 50 | 51 | SP_STATUS_REG (0xA4040010) - Allows you to set breaks and halts and interrupts and stuff, you need to 52 | clear a bunch of that stuff in this register to start the RSP. 53 | 54 |

Setting Up DMA

55 | Setting up DMA is quite simple, 3 steps: 56 | 57 | 1) Set SP_MEM_ADDR_REG. 58 | 2) Set SP_DRAM_ADDR_REG. 59 | 3) Set SP_RD_LEN_REG (SP_RD_LEN_REG is Main Mem. -> RSP) 60 | 61 | Writing to a length register causes to DMA to go. 62 | 63 |

Making The RSP Go

64 | Making the RSP go is 2 steps: 65 | 66 | 1) Set SP_PC_REG (zero is just fine.) 67 | 2) Set SP_STATUS_REG (you need to clear almost everything that can be 68 | cleared in the first 9 bits (0-8) (See N64OPS#H.txt) 69 | 70 | After you clear the halts and breaks and stuff the RSP will start running it's code. 71 | 72 |

The Code File

73 | Here's the code to get some code onto the RSP: 74 | 75 | ;;---CODE START---;; 76 | org $80000400 77 | 78 | li t1,8 ; that crash protection code 79 | lui t0,$bfc0 80 | sw t1,$07fc(t0) 81 | 82 | la t0,0xA4040000 ; SP_MEM_ADDR_REG 83 | li t1,0x1000 ; 0x1000 is the start of IMEM (remember as far as the RSP knows it's memory starts at zero, 84 | ; but we know it's memory really starts at 0xA4000000) 85 | sw t1,0(t0) ; SP memory address 86 | 87 | la t0,0xA4040004 ; SP_DRAM_ADDR_REG 88 | la t1,RCPCode ; address of our code to put in the RSP's IMEM. 89 | sw t1,0(t0) 90 | 91 | la t0,0xA4040008 ; SP_RD_LEN_REG 92 | li t1,72 ; length in bytes, to find this value, multiply the #lines of code that you're putting in the RSP * 8 93 | sw t1,0(t0) ; the DMA will start after this write is done. 94 | 95 | nop 96 | nop ;time for the emulator, I'll leave making a loop to wait until DMA is done an exercise to you (my kind reader.) 97 | 98 | la t0,0xA4080000 ; SP_PC_REG 99 | la t1,0x0 ; just set it to zero 100 | sw t1,0(t0) 101 | 102 | la t0,0xA4040010 ; SP_STATUS_REG 103 | li t1,%100101101 ; clears a bunch of things like halt and break. (See N64OPS#H.txt) 104 | sw t1,0(t0) ; and makes the code run 105 | 106 | infin: 107 | nop 108 | j infin 109 | nop 110 | 111 | RCPCode: 112 | obj 0x0 ; sets the base of the code so that jumps/branches will be correct. 113 | always: 114 | nop 115 | j always 116 | objend ; not sure if it's endobj on some assemblers... 117 | nop 118 | nop 119 | nop 120 | ;;---CODE END---;; 121 | 122 | I realize that the code doesn't do anything, I just wanted to get code onto the RSP. 123 | To verify that it works, take a look at Nemu's debugger under "Commands" and under the RSP tab, 124 | you should see just an infinite loop (a J instruction to the address above it). 125 | 126 |

This Day In Review

127 | 128 | Hopefully I'll be able to do more with the RSP and therefore teach you more as time goes on. 129 | 130 | Happy coding!, 131 | - GbaGuy 132 | 133 |
Intro - Day 9
134 | 135 |

136 | 137 | -------------------------------------------------------------------------------- /tutorial/day9n64.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | N64 ASM - Day 9 4 | 5 | 6 |

Day 9

7 |
 8 | 
 9 | 
10 | 			
11 | 
12 | 
13 |

Using The Serial Interface

14 |


15 | 	The Serial Interface (a.k.a The SI Registers) is used for many things including reading controller
16 | data and writing to mempaks and using the Rumble. I recommend that you see LaC's hardware doc for the best
17 | info on using the SI.
18 | 
19 | 

The Info

20 | The SI does DMA with a 64 byte command packet between PIH RAM and main memory (PIH RAM is in main 21 | memory, but it's like taboo to use normal writes with it...). The 64b command packet can be visualized like 22 | this (all diagrams adapted/copied from LaC's doc): 23 | 24 | [64byte block] at 0xbfc007c0 (1fc007c0) 25 | { Command : Results placed here when you DMA the data back to main memory 26 | ff 00 00 00 : 00 00 00 00 - 8 bytes 27 | ff 00 00 00 : 00 00 00 00 - 8 bytes 28 | ff 00 00 00 : 00 00 00 00 - 8 bytes 29 | ff 00 00 00 : 00 00 00 00 - 8 bytes 30 | ff 00 00 00 : 00 00 00 00 - 8 bytes 31 | ff 00 00 00 : 00 00 00 00 - 8 bytes 32 | ff 00 00 00 : 00 00 00 00 - 8 bytes 33 | ff 00 00 00 : 00 00 00 01 - 8 bytes 34 | } ^^pif status/control byte 35 | 36 | It will help for our purposes that the last byte, refered to by LaC as the control byte, always be 01. 37 | Although there's room for 4 bytes, most commands only use 3, so put the Reset command ($FF) in the first spot 38 | to align everything so you get the Results conveniently 4 byte aligned. 39 | 40 | This diagram describes the form of the 3 bytes of the command: 41 | 42 | Command Types: 43 | 44 | | Command | Description |t |r | 45 | +---------+--------------------------+-----+ 46 | | 00 | request info (status) |01|03| 47 | | 01 | read button values |01|04| 48 | | 02 | read from mempack slot |03|21| 49 | | 03 | write to mempack slot |23|01| 50 | | 04 | read eeprom |02|08| 51 | | 05 | write eeprom |10|01| 52 | | ff | reset |01|03| 53 | NOTE: values are in hex 54 | t r Command 55 | Every command is in the form of (referring to the diagram): t r Command. So reading a controller is 0xFF010401 (that 56 | first 0xFF is the alignment thing from the first diagram.). The only thing that I understand how to do so far is read 57 | the controllers, the command packet for reading the controllers looks like this: 58 | 59 | [64byte block] 60 | { command data 61 | ff 010401 - ffffffff 62 | ff 010401 - ffffffff 63 | ff 010401 - ffffffff 64 | ff 010401 - ffffffff 65 | fe 000000 - 00000000 66 | 00 000000 - 00000000 67 | 00 000000 - 00000000 68 | 00 000000 - 00000001 69 | } 70 | 71 | The byte 0xFE means that there aren't any more commands, it can be left off if the packet is totally full of commands. 72 | Appearantly, the controller that we are reading changes by 1 with each controller read command, so the first one is 73 | controller 1, then #2,#3,and #4. Also, if you just read 1 controller, the reading resets between sending command packets, 74 | so you can't read each controller 1 at a time with 1 read command in each packet (I don't know why you'd do that, but you 75 | can't anyway...). 76 | 77 | Note that some commands aren't only 3 bytes long, that's because of the real meaning of t and r. t is how many bytes 78 | we are sending in this specific command not including the r byte (but including, appearantly, the Command byte that 79 | comes after r ). r is how many bytes we want returned as Results from the PIH. Also note that having more than 3 80 | bytes in the specific command makes the previous type of diagram out of alignment with where the results are going to 81 | end up. Results will always end up after the specific command, they just might not be perfectly aligned on those 4 82 | bytes... 83 | 84 |

This Day In Review

85 | 86 | Most (more like all) of this information was edited from LaC's hardware document v0.8. 87 | Please note that this was just to explain SI (or atleast how I understand it, might not be correct.) and 88 | doing specific things like reading controllers and making the RumblePak go will be covered in separate "Day"s. 89 | 90 | Read The Docs!, 91 | - GBAGuy 92 | 93 |
Intro - Day 10
94 | 95 |

96 | 97 | -------------------------------------------------------------------------------- /tutorial/n64asm.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | N64 ASM Tutorial 4 | 5 | 6 |

N64 ASM Tutorials

7 |
8 | This tutorial is about coding for the Nintendo 64 using 9 | your chosen assembler (see Day 1). The tutorial assumes basic assembly 10 | knowledge, so you would most likely want to come here after knowing GBA 11 | or NES assembly. 12 | 13 |

The Extreme Basics (all I know :) )

14 | Day 1 - Figuring Out the Assembler 15 | Day 2 - Some Instructions 16 | Day 3 - Video Interface Registers 17 | Day 4 - Math 18 | Day 5 - Subroutines 19 | Day 6 - See Screen, See Pic On Screen 20 | Day 7 - The Delay Slot 21 | Day 8 - Getting Code onto The RSP 22 | Day 9 - Using The Serial Interface 23 | 50 | 51 |
52 | 53 | If anyone would like to donate something, such as an N64 or V64 54 | , please EMail Me. Also, don't 55 | hesitate to send comments or suggestions. 56 | 57 |

If you came directly here, check out all the GBA and NES stuff
on the Home Page!

58 |
59 | 60 | 61 | -------------------------------------------------------------------------------- /z64/z64_arch.txt: -------------------------------------------------------------------------------- 1 | The Z64 contains an ALi chip, which is far more than a 386: it is a 2 | more or less complete PC (memory, dma and timers, isa bus, keyboard 3 | and simple ISA-based IDE) with that chip, a clock generator and a few 4 | of DRAM chip you have a completely running system. 5 | The N64 interface is done (in HW1.x and 2.x) with a QuickLogic PLD, 6 | while in the 3.x hardware is implemented on-dice in the CPU (which ALi 7 | is able to customize up to a certain degree...) The "ROM" memory and 8 | the emulation interface is visible to the Z64 as a set of I/O ports. 9 | 10 | The Z64 has 512k of RAM (upgradable to 1Meg soldering in the 11 | appropriate chip) and 512K of flash memory (this memory is paged). 12 | it works at ~28MHz. The "ROM" is a 5V dual-bank EDO SIMM. A non-edo or 3.3V 13 | (5v tolerant) part WON'T work. 14 | 15 | the layout of the flash is as follows: 16 | 17 | 4k of "boot rom": the rom is structured as a ISA-EXTENSION bios (which 18 | makes the rest of the flash a bootable disk) 19 | 20 | 444k of a virtual drive (the Z64 sees this as 'A:') formatted as a 21 | normal MSDOS FAT12 floppy. 22 | 23 | 64k in which the bios for the x86 is stored two times. 24 | 25 | The Z64 uses Caldera's OpenDOS as operating system, but it works just 26 | fine with any MSDOS-Like OS (for example the EXCELLENT RxDOS, which 27 | became totally free recently). 28 | 29 | The internal bios is limited to CHS addressing for the hard drive, so 30 | you could have an hard disk of no more than 5xx megabytes, but OpenDOS 31 | has an even harder limitation: the rom'able version only supports 32 | 512 bytes (1 sector) clusters, so you can have only 32 megs as 33 | harddrive. This limitation is bypassed by the IOMega GUEST.EXE so it 34 | is possible to use a zip disk -- most probably using the GUEST.EXE of 35 | the 250M zip it should work fine. 36 | 37 | The Z64 user interface is a simple MSDOS program (the on-screen N64 38 | gui is done by sending to the N64 a special "ROM") 39 | 40 | The Flash-Rom in HW2 is a SST 28SF040 41 | On the SST site (http://www.ssti.com/) this chip is well documented. 42 | It's unlikely that software can fry this chip, but it can get in a non-accessible state. 43 | On the above site you can find instructions to exit this state. 44 | 45 | The CDROM is not a problem related to bios or cluster size: in fact 46 | the "cdrom.sys" driver and MSCDEX.EXE do handle all the accesses to 47 | the CD directly (the "cdrom.sys" generally hits the hardware directly 48 | exposing a known interface via a device for MSCDEX.EXE, which hooks 49 | itself to the int vectors and ADDS functionality to the existing BIOS 50 | and DOS). The problem is the Z64.EXE program, which makes certain 51 | assumptions regarding the environment in which he lives: first off the 52 | drive containing the roms must be writeable -- try to protect the zip 53 | with the zip tools on the pc -- second it assumes to detect 54 | insertion/removal of the disk using the ASPI interface (directly 55 | addressing a "ZIP 100" device. If these requirements are not met it 56 | behaves somewhat weirdly (don't understand why it still works with 57 | 250M zip, but it does, oddly enough) 58 | 59 | 60 | --------------------------------------------------------------------------------