├── .gitattributes
├── N64
├── BadInstructionTest
│ ├── BadInstructionTest.N64
│ ├── BadInstructionTest.asm
│ ├── N64_Header.asm
│ └── make.cmd
├── Color16
│ ├── Color16.N64
│ ├── Color16.asm
│ ├── Color16_Test.N64
│ ├── Color16_Test.asm
│ ├── N64_Header.asm
│ └── make.cmd
├── Color32
│ ├── Color32_Test.N64
│ ├── Color32_Test.asm
│ ├── N64_Header.asm
│ └── make.cmd
├── Exception
│ ├── Exception.N64
│ ├── Exception.asm
│ ├── ExceptionTest.N64
│ ├── Main.asm
│ ├── N64_Header.asm
│ ├── cfg
│ │ ├── default.cfg
│ │ └── n64.cfg
│ ├── error.log
│ ├── make.cmd
│ └── nvram
│ │ └── n64
│ │ └── Lesson2.nv
├── Exception2
│ ├── Exception.N64
│ ├── Exception.asm
│ ├── Main.asm
│ ├── N64_Header.asm
│ └── make.cmd
├── ExceptionTest
│ ├── ExceptionTest.N64
│ ├── ExceptionTest.asm
│ ├── N64_Header.asm
│ └── make.cmd
├── GDB
│ ├── GDB_Test.N64
│ ├── GDB_Test.asm
│ ├── N64_Header.asm
│ └── make.cmd
├── IPL_FONT
│ ├── IPL_FONT.N64
│ ├── IPL_FONT.asm
│ ├── IPL_FONT.png
│ ├── N64_Header.asm
│ └── make.cmd
├── InterruptTest
│ ├── InterruptTest.N64
│ ├── InterruptTest.asm
│ ├── N64_Header.asm
│ └── make.cmd
├── LIB
│ ├── COLORS16.INC
│ ├── COLORS32.INC
│ ├── N64.INC
│ ├── N64_BOOTCODE.BIN
│ ├── N64_DRIVE.INC
│ ├── N64_DRIVE.S
│ ├── N64_EVER.INC
│ ├── N64_EVER.S
│ ├── N64_EXCEPTION.INC
│ ├── N64_EXCEPTION.S
│ ├── N64_GDB.INC
│ ├── N64_GDB.S
│ ├── N64_GFX.INC
│ ├── N64_INTERRUPT.INC
│ ├── N64_INTERRUPT.S
│ ├── N64_INTERRUPT_HANDLER.S
│ ├── N64_INTERRUPT_TEMPLATE.S
│ ├── N64_IPL_FONT.INC
│ ├── N64_IPL_FONT.S
│ ├── N64_RSP.INC
│ ├── N64_SYS.INC
│ ├── N64_SYS.S
│ ├── N64_SYSCALL_MARS.S
│ └── README.md
├── Lesson1
│ └── bass-win.zip
├── Lesson2
│ ├── Lesson2.N64
│ ├── Lesson2.asm
│ ├── N64_Header.asm
│ └── make.cmd
└── Template
│ ├── N64_Header.asm
│ ├── Template.N64
│ ├── make.cmd
│ └── template.asm
├── README.md
└── gobass.cmd
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
--------------------------------------------------------------------------------
/N64/BadInstructionTest/BadInstructionTest.N64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/BadInstructionTest/BadInstructionTest.N64
--------------------------------------------------------------------------------
/N64/BadInstructionTest/BadInstructionTest.asm:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 | fill 1052672
4 |
5 | origin $00000000
6 | base $80000000
7 | include "../LIB/N64.INC"
8 | include "../LIB/N64_GFX.INC"
9 | include "../LIB/COLORS32.INC"
10 | include "./N64_HEADER.ASM" // Include 64 Byte Header & Vector Table
11 | insert "../LIB/N64_BOOTCODE.BIN" // Include 4032 Byte Boot Code
12 | force_pc($80001000)
13 | Start:
14 | align(8)
15 | variable vi_buffer(t7)
16 | li vi_buffer, $A0100000
17 | N64_INIT()
18 | ScreenNTSC(320, 240, BPP32, $A0100000) // Screen NTSC: 320x240, 32BPP, DRAM Origin $A0100000
19 | nop
20 | nop
21 | variable backColor(s0)
22 | li backColor, BLUE_VIOLET
23 | variable source(t0)
24 | variable destination(t1)
25 | variable length(t2)
26 | variable count(t3)
27 |
28 | la source, GeneralHandler
29 | la destination, 0x80000180
30 | li length, 128
31 | li count, r0
32 | loop_mem_cpy:
33 | lw s2, 0x0(source)
34 | lw s3, 0x4(source)
35 | lw s4, 0x8(source)
36 | lw s5, 0xC(source)
37 | sw s2, 0x0(destination)
38 | sw s3, 0x4(destination)
39 | sw s4, 0x8(destination)
40 | sw s5, 0xC(destination)
41 | bne length,count, loop_mem_cpy
42 | addi count, count, 16
43 |
44 |
45 | nop
46 | nop
47 | dw 0x40806800
48 | nop
49 | nop
50 |
51 | Loop:
52 | // Insert Looping Code Here
53 | li s6, vi_buffer+0x4B000
54 | loop_color:
55 | sw backColor, 0x0(source)
56 | sw backColor, 0x4(source)
57 | sw backColor, 0x8(source)
58 | sw backColor, 0xC(source)
59 | bne source, s6, loop_color
60 | addi source, source, 16
61 | j Loop
62 | nop // Delay Slot
63 |
64 | GeneralHandler:
65 | li backColor, DARK_ORANGE
66 | eret
--------------------------------------------------------------------------------
/N64/BadInstructionTest/N64_Header.asm:
--------------------------------------------------------------------------------
1 | //============
2 | // N64 Header
3 | //============
4 | // PI_BSB_DOM1
5 | db $80 // Initial PI_BSB_DOM1_LAT_REG Value
6 | db $37 // Initial PI_BSB_DOM1_PGS_REG Value
7 | db $12 // Initial PI_BSB_DOM1_PWD_REG Value
8 | db $40 // Initial PI_BSB_DOM1_PGS_REG Value
9 |
10 | // CLOCK RATE
11 | dw $000F // Initial Clock Rate
12 |
13 | // VECTOR
14 | dw Start // Boot Address Offset
15 | dw $1444 // Release Offset
16 |
17 | // COMPLEMENT CHECK & CHECKSUM
18 | db "CRC1" // CRC1: COMPLEMENT CHECK
19 | db "CRC2" // CRC2: CHECKSUM
20 |
21 | dd 0 // UNUSED
22 |
23 | // PROGRAM TITLE (27 Byte ASCII String, Use Spaces For Unused Bytes)
24 | db "Template "
25 | // "123456789012345678901234567"
26 |
27 | // DEVELOPER ID CODE
28 | db $00 // "N" = Nintendo
29 |
30 | // CARTRIDGE ID CODE
31 | db $00
32 |
33 | db 0 // UNUSED
34 |
35 | // COUNTRY CODE
36 | db $00 // "D" = Germany, "E" = USA, "J" = Japan, "P" = Europe, "U" = Australia
37 |
38 | db 0 // UNUSED
--------------------------------------------------------------------------------
/N64/BadInstructionTest/make.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | set rom_name=BadInstructionTest.N64
3 | REM Space seperated list of source files
4 | set source_files=BadInstructionTest.asm
5 |
6 | if exist %rom_name% (
7 | del /q %rom_name%
8 | )
9 | bass -strict -create %1 -o %rom_name% %source_files%
10 | if exist %rom_name% (
11 | @chksum64 %rom_name%
12 | )
--------------------------------------------------------------------------------
/N64/Color16/Color16.N64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/Color16/Color16.N64
--------------------------------------------------------------------------------
/N64/Color16/Color16.asm:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 | fill 1052672
4 |
5 | origin $00000000
6 | base $80000000
7 | include "../LIB/N64.INC"
8 | include "../LIB/COLORS16.INC"
9 | include "../LIB/N64_GFX.INC"
10 |
11 | include "N64_HEADER.ASM"
12 | insert "../LIB/N64_BOOTCODE.BIN"
13 |
14 | Start:
15 | N64_INIT()
16 | ScreenNTSC(320, 240, BPP16, $A0100000)
17 | DPC(RDPBuffer, RDPBufferEnd)
18 | WaitScanline($200)
19 | nop // Marker NOP's
20 | Loop:
21 | j Loop
22 | nop // Delay Slot
23 | macro square16(col, row, color) {
24 | Set_Fill_Color ({color} << 16) | {color} // Set Fill Color: PACKED COLOR 32B R8G8B8A8 Pixel
25 | Fill_Rectangle (({row} * 20) + (({col} + 1) * 20)) << 2, ({row} * 20) << 2, (({row} * 20) + ({col} * 20)) << 2, ({row} * 20) << 2
26 | }
27 |
28 | align(8) // Align 64-Bit
29 | RDPBuffer:
30 | arch n64.rdp
31 |
32 | Set_Scissor 0<<2,0<<2, 0,0, 320<<2,240<<2
33 | Set_Other_Modes CYCLE_TYPE_FILL // | Z_MODE_OPAQUE
34 | Set_Color_Image IMAGE_DATA_FORMAT_RGBA,SIZE_OF_PIXEL_16B,320-1, $00100000
35 |
36 | // Bottom Right X, Bottom Right Y, Top Left X, Top Left Y
37 |
38 | Set_Fill_Color (BLACK << 16) | BLACK // Set Fill Color: PACKED COLOR 32B R8G8B8A8 Pixel
39 | Fill_Rectangle 319<<2,239<<2, 0<<2,0<<2 // Fill Rectangle: XL 319.0,YL 239.0, XH 0.0,YH 0.0
40 | No_Op
41 | No_Op
42 | square16(0, 0, STEEL_BLUE)
43 | Set_Fill_Color (STEEL_BLUE << 16) | STEEL_BLUE
44 | Fill_Rectangle 20<<2,20<<2, 0<<2,0<<2
45 | No_Op
46 | No_Op
47 |
48 | square16(0, 1, PALE_TURQUOISE)
49 | Set_Fill_Color (PALE_TURQUOISE << 16) | PALE_TURQUOISE
50 | Fill_Rectangle 40<<2,20<<2,0<<2,20<<2
51 | No_Op
52 | No_Op
53 |
54 | //Set_Fill_Color (AQUA << 16) | AQUA
55 | //Fill_Rectangle 319<<2,18<<2, 301<<2,0<<2 //Fill_Rectangle 20<<2,20<<2,5<<2,5<<2
56 | //No_Op
57 |
58 | Sync_Full // Ensure Entire Scene Is Fully Drawn
59 | align(8)
60 | RDPBufferEnd:
61 | dw 0x0
62 | dw 0x0
63 | dw 0x0
64 | dw 0x0
65 | Set_Fill_Color (LIGHT_CYAN <<16) | LIGHT_CYAN
66 | Fill_Rectangle 80<<2,20<<2,100<<2,1<<2
67 |
68 |
69 | Set_Fill_Color (AQUAMARINE <<16) | AQUAMARINE
70 | Fill_Rectangle 260<<2,100<<2,241<<2,81<<2
71 | Set_Fill_Color (TURQUOISE <<16) | TURQUOISE
72 | Fill_Rectangle 280<<2,100<<2,261<<2,81<<2
73 | Set_Fill_Color (MEDIUM_TURQUOISE <<16) | MEDIUM_TURQUOISE
74 | Fill_Rectangle 300<<2,100<<2,281<<2,81<<2
75 | //Set_Fill_Color (DARK_TURQUOISE <<16) | DARK_TURQUOISE
76 | //Fill_Rectangle 320<<2,100<<2,301<<2,81<<2
77 | //Set_Fill_Color (CADET_BLUE <<16) | CADET_BLUE
78 | //Fill_Rectangle 340<<2,100<<2,321<<2,81<<2
79 |
80 | Set_Fill_Color (CYAN <<16) | CYAN
81 | Fill_Rectangle 20<<2,120<<2,1<<2,101<<2
82 | Set_Fill_Color (LIGHT_STEEL_BLUE <<16) | LIGHT_STEEL_BLUE
83 | Fill_Rectangle 40<<2,120<<2,21<<2,101<<2
84 | Set_Fill_Color (POWDER_BLUE <<16) | POWDER_BLUE
85 | Fill_Rectangle 60<<2,120<<2,41<<2,101<<2
86 | Set_Fill_Color (LIGHT_BLUE <<16) | LIGHT_BLUE
87 | Fill_Rectangle 80<<2,120<<2,61<<2,101<<2
88 | Set_Fill_Color (SKY_BLUE <<16) | SKY_BLUE
89 | Fill_Rectangle 100<<2,120<<2,81<<2,101<<2
90 | Set_Fill_Color (LIGHT_SKY_BLUE <<16) | LIGHT_SKY_BLUE
91 | Fill_Rectangle 120<<2,120<<2,101<<2,101<<2
92 | Set_Fill_Color (DEEP_SKY_BLUE <<16) | DEEP_SKY_BLUE
93 | Fill_Rectangle 140<<2,120<<2,121<<2,101<<2
94 | Set_Fill_Color (DODGER_BLUE <<16) | DODGER_BLUE
95 | Fill_Rectangle 160<<2,120<<2,141<<2,101<<2
96 | Set_Fill_Color (CORN_FLOWER_BLUE <<16) | CORN_FLOWER_BLUE
97 | Fill_Rectangle 180<<2,120<<2,161<<2,101<<2
98 | Set_Fill_Color (MEDIUM_SLATE_BLUE <<16) | MEDIUM_SLATE_BLUE
99 | Fill_Rectangle 200<<2,120<<2,181<<2,101<<2
100 | Set_Fill_Color (ROYAL_BLUE <<16) | ROYAL_BLUE
101 | Fill_Rectangle 220<<2,120<<2,201<<2,101<<2
102 | Set_Fill_Color (MEDIUM_BLUE <<16) | MEDIUM_BLUE
103 | Fill_Rectangle 240<<2,120<<2,221<<2,101<<2
104 | Set_Fill_Color (BLUE <<16) | BLUE
105 | Fill_Rectangle 260<<2,120<<2,241<<2,101<<2
106 | Set_Fill_Color (DARK_BLUE <<16) | DARK_BLUE
107 | Fill_Rectangle 280<<2,120<<2,261<<2,101<<2
108 | Set_Fill_Color (NAVY <<16) | NAVY
109 | Fill_Rectangle 300<<2,120<<2,281<<2,101<<2
110 | //Set_Fill_Color (MIDNIGHT_BLUE <<16) | MIDNIGHT_BLUE
111 | //Fill_Rectangle 320<<2,120<<2,301<<2,101<<2
112 | //Set_Fill_Color (BLACK <<16) | BLACK
113 | //Fill_Rectangle 340<<2,120<<2,321<<2,101<<2
114 |
115 |
116 |
117 | Set_Fill_Color (INDIAN_RED <<16) | INDIAN_RED
118 | Fill_Rectangle 20<<2,20<<2, 1<<2,1<<2
119 |
120 | Set_Fill_Color (LIGHT_CORAL <<16) | LIGHT_CORAL
121 | Fill_Rectangle 80<<2,40<<2, 21<<2,1<<2
122 |
123 | Set_Fill_Color (SALMON <<16) | SALMON
124 | Fill_Rectangle 60<<2,20<<2, 41<<2,1<<2
125 |
126 | Set_Fill_Color (DARK_SALMON <<16) | DARK_SALMON
127 | Fill_Rectangle 80<<2,20<<2, 61<<2,1<<2
128 | Set_Fill_Color (CRIMSON <<16) | CRIMSON
129 | Fill_Rectangle 100<<2,20<<2, 81<<2,1<<2
130 |
131 | Set_Fill_Color (RED <<16) | RED
132 | Fill_Rectangle 120<<2,20<<2, 101<<2,1<<2
133 | Set_Fill_Color (FIRE_BRICK <<16) | FIRE_BRICK
134 | Fill_Rectangle 140<<2,20<<2, 121<<2,1<<2
135 | Set_Fill_Color (DARK_RED <<16) | DARK_RED
136 | Fill_Rectangle 160<<2,20<<2, 141<<2,1<<2
137 | Set_Fill_Color (BLACK <<16) | BLACK
138 | Fill_Rectangle 180<<2,20<<2, 161<<2,1<<2
139 |
140 | Set_Fill_Color (PINK <<16) | PINK
141 | Fill_Rectangle 200<<2,20<<2, 181<<2,1<<2
142 | Set_Fill_Color (LIGHT_PINK <<16) | LIGHT_PINK
143 | Fill_Rectangle 220<<2,20<<2, 201<<2,1<<2
144 | Set_Fill_Color (HOT_PINK <<16) | HOT_PINK
145 | Fill_Rectangle 240<<2,20<<2, 221<<2,1<<2
146 | Set_Fill_Color (DEEP_PINK <<16) | DEEP_PINK
147 | Fill_Rectangle 260<<2,20<<2, 241<<2,1<<2
148 | Set_Fill_Color (MEDIUM_VIOLET_RED <<16) | MEDIUM_VIOLET_RED
149 | Fill_Rectangle 280<<2,20<<2, 261<<2,1<<2
150 | Set_Fill_Color (PALE_VIOLET_RED <<16) | PALE_VIOLET_RED
151 | Fill_Rectangle 300<<2,20<<2, 281<<2,1<<2
152 | //Set_Fill_Color (BLACK <<16) | BLACK
153 | //Fill_Rectangle 320<<2,20<<2, 301<<2,1<<2
154 |
155 | // Bottom Right X, Bottom Right Y, Top Left X, Top Left Y
156 | Set_Fill_Color (LIGHT_SALMON <<16) | LIGHT_SALMON
157 | Fill_Rectangle 20<<2,40<<2, 1<<2,21<<2
158 | Set_Fill_Color (CORAL <<16) | CORAL
159 | Fill_Rectangle 40<<2,40<<2, 21<<2,21<<2
160 | Set_Fill_Color (TOMATO <<16) | TOMATO
161 | Fill_Rectangle 60<<2,40<<2, 41<<2,21<<2
162 | Set_Fill_Color (ORANGE_RED <<16) | ORANGE_RED
163 | Fill_Rectangle 80<<2,40<<2, 61<<2,21<<2
164 | Set_Fill_Color (DARK_ORANGE <<16) | DARK_ORANGE
165 | Fill_Rectangle 100<<2,40<<2, 81<<2,21<<2
166 | Set_Fill_Color (ORANGE <<16) | ORANGE
167 | Fill_Rectangle 120<<2,40<<2, 101<<2,21<<2
168 | Set_Fill_Color (BLACK <<16) | BLACK
169 | Fill_Rectangle 140<<2,40<<2, 121<<2,21<<2
170 |
171 | Set_Fill_Color (GOLD <<16) | GOLD
172 | Fill_Rectangle 160<<2,40<<2, 141<<2, 21<<2
173 | Set_Fill_Color (YELLOW <<16) | YELLOW
174 | Fill_Rectangle 180<<2,40<<2, 161<<2,21<<2
175 | Set_Fill_Color (LIGHT_YELLOW <<16) | LIGHT_YELLOW
176 | Fill_Rectangle 200<<2,40<<2, 181<<2,21<<2
177 | Set_Fill_Color (LEMON_CHIFFON <<16) | LEMON_CHIFFON
178 | Fill_Rectangle 220<<2,40<<2, 201<<2,21<<2
179 | Set_Fill_Color (LIGHT_GOLDENROD_YELLOW <<16) | LIGHT_GOLDENROD_YELLOW
180 | Fill_Rectangle 240<<2,40<<2, 221<<2,21<<2
181 | Set_Fill_Color (PAPAYA_WHIP <<16) | PAPAYA_WHIP
182 | Fill_Rectangle 260<<2,40<<2, 241<<2,21<<2
183 | Set_Fill_Color (MOCCASIN <<16) | MOCCASIN
184 | Fill_Rectangle 280<<2,40<<2, 261<<2,21<<2
185 | Set_Fill_Color (PEACH_PUFF <<16) | PEACH_PUFF
186 | Fill_Rectangle 300<<2,40<<2, 281<<2,21<<2
187 | //Set_Fill_Color (PALE_GOLDENROD <<16) | PALE_GOLDENROD
188 | //Fill_Rectangle 320<<2,40<<2, 301<<2,21<<2
189 | //Set_Fill_Color (KHAKI <<16) | KHAKI
190 | //Fill_Rectangle 340<<2,40<<2, 321<<2,21<<2
191 |
192 | Set_Fill_Color (DARK_KHAKI <<16) | DARK_KHAKI
193 | Fill_Rectangle 20<<2,60<<2,1<<2,41<<2
194 | Set_Fill_Color (BLACK <<16) | BLACK
195 | Fill_Rectangle 40<<2,60<<2,21<<2,41<<2
196 |
197 | Set_Fill_Color (LAVENDER <<16) | LAVENDER
198 | Fill_Rectangle 60<<2,60<<2,41<<2,41<<2
199 | Set_Fill_Color (THISTLE <<16) | THISTLE
200 | Fill_Rectangle 80<<2,60<<2,61<<2,41<<2
201 | Set_Fill_Color (PLUM <<16) | PLUM
202 | Fill_Rectangle 100<<2,60<<2,81<<2,41<<2
203 | Set_Fill_Color (VIOLET <<16) | VIOLET
204 | Fill_Rectangle 120<<2,60<<2,101<<2,41<<2
205 | Set_Fill_Color (ORCHID <<16) | ORCHID
206 | Fill_Rectangle 140<<2,60<<2,121<<2,41<<2
207 | Set_Fill_Color (FUCHSIA <<16) | FUCHSIA
208 | Fill_Rectangle 160<<2,60<<2,141<<2,41<<2
209 | Set_Fill_Color (MAGENTA <<16) | MAGENTA
210 | Fill_Rectangle 180<<2,60<<2,161<<2,41<<2
211 | Set_Fill_Color (MEDIUM_ORCHID <<16) | MEDIUM_ORCHID
212 | Fill_Rectangle 200<<2,60<<2,181<<2,41<<2
213 | Set_Fill_Color (BLUE_VIOLET <<16) | BLUE_VIOLET
214 | Fill_Rectangle 220<<2,60<<2,201<<2,41<<2
215 | Set_Fill_Color (DARK_ORCHID <<16) | DARK_ORCHID
216 | Fill_Rectangle 240<<2,60<<2,221<<2,41<<2
217 | Set_Fill_Color (DARK_MAGENTA <<16) | DARK_MAGENTA
218 | Fill_Rectangle 260<<2,60<<2,241<<2,41<<2
219 | Set_Fill_Color (PURPLE <<16) | PURPLE
220 | Fill_Rectangle 280<<2,60<<2,261<<2,41<<2
221 | Set_Fill_Color (INDIGO <<16) | INDIGO
222 | Fill_Rectangle 300<<2,60<<2,281<<2,41<<2
223 | //Set_Fill_Color (SLATE_BLUE <<16) | SLATE_BLUE
224 | //Fill_Rectangle 320<<2,60<<2,301<<2,41<<2
225 | //Set_Fill_Color (DARK_SLATE_BLUE <<16) | DARK_SLATE_BLUE
226 | //Fill_Rectangle 340<<2,60<<2,321<<2,41<<2
227 |
228 | Set_Fill_Color (BLACK <<16) | BLACK
229 | Fill_Rectangle 20<<2,80<<2,1<<2,61<<2
230 | Set_Fill_Color (GREEN_YELLOW <<16) | GREEN_YELLOW
231 | Fill_Rectangle 40<<2,80<<2,21<<2,61<<2
232 | Set_Fill_Color (CHARTREUSE <<16) | CHARTREUSE
233 | Fill_Rectangle 60<<2,80<<2,41<<2,61<<2
234 | Set_Fill_Color (LAWN_GREEN <<16) | LAWN_GREEN
235 | Fill_Rectangle 80<<2,80<<2,61<<2,61<<2
236 | Set_Fill_Color (LIME <<16) | LIME
237 | Fill_Rectangle 100<<2,80<<2,81<<2,61<<2
238 | Set_Fill_Color (LIME_GREEN <<16) | LIME_GREEN
239 | Fill_Rectangle 120<<2,80<<2,101<<2,61<<2
240 | Set_Fill_Color (PALE_GREEN <<16) | PALE_GREEN
241 | Fill_Rectangle 140<<2,80<<2,121<<2,61<<2
242 | Set_Fill_Color (LIGHT_GREEN <<16) | LIGHT_GREEN
243 | Fill_Rectangle 160<<2,80<<2,141<<2,61<<2
244 | Set_Fill_Color (MEDIUM_SPRING_GREEN <<16) | MEDIUM_SPRING_GREEN
245 | Fill_Rectangle 180<<2,80<<2,161<<2,61<<2
246 | Set_Fill_Color (SPRING_GREEN <<16) | SPRING_GREEN
247 | Fill_Rectangle 200<<2,80<<2,181<<2,61<<2
248 | Set_Fill_Color (MEDIUM_SEA_GREEN <<16) | MEDIUM_SEA_GREEN
249 | Fill_Rectangle 220<<2,80<<2,201<<2,61<<2
250 | Set_Fill_Color (SEA_GREEN <<16) | SEA_GREEN
251 | Fill_Rectangle 240<<2,80<<2,221<<2,61<<2
252 | Set_Fill_Color (FOREST_GREEN <<16) | FOREST_GREEN
253 | Fill_Rectangle 260<<2,80<<2,241<<2,61<<2
254 | Set_Fill_Color (GREEN <<16) | GREEN
255 | Fill_Rectangle 280<<2,80<<2,261<<2,61<<2
256 | Set_Fill_Color (DARK_GREEN <<16) | DARK_GREEN
257 | Fill_Rectangle 300<<2,80<<2,281<<2,61<<2
258 | //Set_Fill_Color (YELLOW_GREEN <<16) | YELLOW_GREEN
259 | //Fill_Rectangle 320<<2,80<<2,301<<2,61<<2
260 | //Set_Fill_Color (OLIVE_DRAB <<16) | OLIVE_DRAB
261 | //Fill_Rectangle 340<<2,80<<2,321<<2,61<<2
262 |
263 | Set_Fill_Color (OLIVE <<16) | OLIVE
264 | Fill_Rectangle 20<<2,100<<2,1<<2,81<<2
265 | Set_Fill_Color (DARK_OLIVE_GREEN <<16) | DARK_OLIVE_GREEN
266 | Fill_Rectangle 40<<2,100<<2,21<<2,81<<2
267 | Set_Fill_Color (MEDIUM_AQUAMARINE <<16) | MEDIUM_AQUAMARINE
268 | Fill_Rectangle 60<<2,100<<2,41<<2,81<<2
269 | Set_Fill_Color (DARK_SEA_GREEN <<16) | DARK_SEA_GREEN
270 | Fill_Rectangle 80<<2,100<<2,61<<2,81<<2
271 | Set_Fill_Color (LIGHT_SEA_GREEN <<16) | LIGHT_SEA_GREEN
272 | Fill_Rectangle 100<<2,100<<2,81<<2,81<<2
273 | Set_Fill_Color (DARK_CYAN <<16) | DARK_CYAN
274 | Fill_Rectangle 120<<2,100<<2,101<<2,81<<2
275 | Set_Fill_Color (TEAL <<16) | TEAL
276 | Fill_Rectangle 140<<2,100<<2,121<<2,81<<2
277 | Set_Fill_Color (BLACK <<16) | BLACK
278 | Fill_Rectangle 160<<2,100<<2,141<<2,81<<2
279 |
280 |
281 |
282 | Set_Fill_Color (CORNSILK <<16) | CORNSILK
283 | Fill_Rectangle 20<<2,140<<2,1<<2,121<<2
284 | Set_Fill_Color (BLANCHED_ALMOND <<16) | BLANCHED_ALMOND
285 | Fill_Rectangle 40<<2,140<<2,21<<2,121<<2
286 | Set_Fill_Color (BISQUE <<16) | BISQUE
287 | Fill_Rectangle 60<<2,140<<2,41<<2,121<<2
288 | Set_Fill_Color (NAVAJO_WHITE <<16) | NAVAJO_WHITE
289 | Fill_Rectangle 80<<2,140<<2,61<<2,121<<2
290 | Set_Fill_Color (WHEAT <<16) | WHEAT
291 | Fill_Rectangle 100<<2,140<<2,81<<2,121<<2
292 | Set_Fill_Color (BURLY_WOOD <<16) | BURLY_WOOD
293 | Fill_Rectangle 120<<2,140<<2,101<<2,121<<2
294 | Set_Fill_Color (TAN <<16) | TAN
295 | Fill_Rectangle 140<<2,140<<2,121<<2,121<<2
296 | Set_Fill_Color (ROSY_BROWN <<16) | ROSY_BROWN
297 | Fill_Rectangle 160<<2,140<<2,141<<2,121<<2
298 | Set_Fill_Color (SANDY_BROWN <<16) | SANDY_BROWN
299 | Fill_Rectangle 180<<2,140<<2,161<<2,121<<2
300 | Set_Fill_Color (GOLDENROD <<16) | GOLDENROD
301 | Fill_Rectangle 200<<2,140<<2,181<<2,121<<2
302 | Set_Fill_Color (DARK_GOLDENROD <<16) | DARK_GOLDENROD
303 | Fill_Rectangle 220<<2,140<<2,201<<2,121<<2
304 | Set_Fill_Color (PERU <<16) | PERU
305 | Fill_Rectangle 240<<2,140<<2,221<<2,121<<2
306 | Set_Fill_Color (CHOCOLATE <<16) | CHOCOLATE
307 | Fill_Rectangle 260<<2,140<<2,241<<2,121<<2
308 | Set_Fill_Color (SADDLE_BROWN <<16) | SADDLE_BROWN
309 | Fill_Rectangle 280<<2,140<<2,261<<2,121<<2
310 | Set_Fill_Color (SIENNA <<16) | SIENNA
311 | Fill_Rectangle 300<<2,140<<2,281<<2,121<<2
312 | //Set_Fill_Color (BROWN <<16) | BROWN
313 | //Fill_Rectangle 320<<2,140<<2,301<<2,121<<2
314 | //Set_Fill_Color (MAROON <<16) | MAROON
315 | //Fill_Rectangle 340<<2,140<<2,321<<2,121<<2
316 |
317 | Set_Fill_Color (BLACK <<16) | BLACK
318 | Fill_Rectangle 20<<2,160<<2,1<<2,141<<2
319 | Set_Fill_Color (WHITE <<16) | WHITE
320 | Fill_Rectangle 40<<2,160<<2,21<<2,141<<2
321 | Set_Fill_Color (SNOW <<16) | SNOW
322 | Fill_Rectangle 60<<2,160<<2,41<<2,141<<2
323 | Set_Fill_Color (HONEYDEW <<16) | HONEYDEW
324 | Fill_Rectangle 80<<2,160<<2,61<<2,141<<2
325 | Set_Fill_Color (MINT_CREAM <<16) | MINT_CREAM
326 | Fill_Rectangle 100<<2,160<<2,81<<2,141<<2
327 | Set_Fill_Color (AZURE <<16) | AZURE
328 | Fill_Rectangle 120<<2,160<<2,101<<2,141<<2
329 | Set_Fill_Color (ALICE_BLUE <<16) | ALICE_BLUE
330 | Fill_Rectangle 140<<2,160<<2,121<<2,141<<2
331 | Set_Fill_Color (GHOST_WHITE <<16) | GHOST_WHITE
332 | Fill_Rectangle 160<<2,160<<2,141<<2,141<<2
333 | Set_Fill_Color (WHITE_SMOKE <<16) | WHITE_SMOKE
334 | Fill_Rectangle 180<<2,160<<2,161<<2,141<<2
335 | Set_Fill_Color (SEA_SHELL <<16) | SEA_SHELL
336 | Fill_Rectangle 200<<2,160<<2,181<<2,141<<2
337 | Set_Fill_Color (BEIGE <<16) | BEIGE
338 | Fill_Rectangle 220<<2,160<<2,201<<2,141<<2
339 | Set_Fill_Color (OLD_LACE <<16) | OLD_LACE
340 | Fill_Rectangle 240<<2,160<<2,221<<2,141<<2
341 | Set_Fill_Color (FLORAL_WHITE <<16) | FLORAL_WHITE
342 | Fill_Rectangle 260<<2,160<<2,241<<2,141<<2
343 | Set_Fill_Color (IVORY <<16) | IVORY
344 | Fill_Rectangle 280<<2,160<<2,261<<2,141<<2
345 | Set_Fill_Color (ANTIQUE_WHITE <<16) | ANTIQUE_WHITE
346 | Fill_Rectangle 300<<2,160<<2,281<<2,141<<2
347 | //Set_Fill_Color (LINEN <<16) | LINEN
348 | //Fill_Rectangle 320<<2,160<<2,301<<2,141<<2
349 | //Set_Fill_Color (LAVENDER_BLUSH <<16) | LAVENDER_BLUSH
350 | //Fill_Rectangle 340<<2,160<<2,321<<2,141<<2
351 |
352 | Set_Fill_Color (MISTY_ROSE <<16) | MISTY_ROSE
353 | Fill_Rectangle 20<<2,180<<2,1<<2,161<<2
354 | Set_Fill_Color (BLACK <<16) | BLACK
355 | Fill_Rectangle 40<<2,180<<2,21<<2,161<<2
356 | Set_Fill_Color (GAINSBORO <<16) | GAINSBORO
357 | Fill_Rectangle 60<<2,180<<2,41<<2,161<<2
358 | Set_Fill_Color (LIGHT_GREY <<16) | LIGHT_GREY
359 | Fill_Rectangle 80<<2,180<<2,61<<2,161<<2
360 | Set_Fill_Color (SILVER <<16) | SILVER
361 | Fill_Rectangle 100<<2,180<<2,81<<2,161<<2
362 | Set_Fill_Color (DARK_GREY <<16) | DARK_GREY
363 | Fill_Rectangle 120<<2,180<<2,101<<2,161<<2
364 | Set_Fill_Color (GREY <<16) | GREY
365 | Fill_Rectangle 140<<2,180<<2,121<<2,161<<2
366 | Set_Fill_Color (DIM_GREY <<16) | DIM_GREY
367 | Fill_Rectangle 160<<2,180<<2,141<<2,161<<2
368 | Set_Fill_Color (LIGHT_SLATE_GREY <<16) | LIGHT_SLATE_GREY
369 | Fill_Rectangle 180<<2,180<<2,161<<2,161<<2
370 | Set_Fill_Color (SLATE_GREY <<16) | SLATE_GREY
371 | Fill_Rectangle 200<<2,180<<2,181<<2,161<<2
372 | // Set_Fill_Color (BLACK <<16) | BLACK
373 | // Fill_Rectangle 220<<2,180<<2,201<<2,161<<2
374 | // Set_Fill_Color (BLACK <<16) | BLACK
375 | // Fill_Rectangle 240<<2,180<<2,221<<2,161<<2
376 | // Set_Fill_Color (BLACK <<16) | BLACK
377 | // Fill_Rectangle 260<<2,180<<2,241<<2,161<<2
378 | // Set_Fill_Color (BLACK <<16) | BLACK
379 | // Fill_Rectangle 280<<2,180<<2,261<<2,161<<2
380 | // Set_Fill_Color (BLACK <<16) | BLACK
381 | // Fill_Rectangle 300<<2,180<<2,281<<2,161<<2
382 | // Set_Fill_Color (BLACK <<16) | BLACK
383 | // Fill_Rectangle 320<<2,180<<2,301<<2,161<<2
384 | // Set_Fill_Color (BLACK <<16) | BLACK
385 | // Fill_Rectangle 340<<2,180<<2,321<<2,161<<2
386 |
387 | Sync_Full // Ensure Entire Scene Is Fully Drawn
388 |
--------------------------------------------------------------------------------
/N64/Color16/Color16_Test.N64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/Color16/Color16_Test.N64
--------------------------------------------------------------------------------
/N64/Color16/Color16_Test.asm:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 | fill 1052672
4 |
5 | origin $00000000
6 | base $80000000
7 | include "../LIB/N64.INC"
8 | include "../LIB/COLORS16.INC"
9 | include "../LIB/N64_GFX.INC"
10 |
11 | include "N64_HEADER.ASM"
12 | insert "../LIB/N64_BOOTCODE.BIN"
13 |
14 | Start:
15 | N64_INIT()
16 | ScreenNTSC(320, 240, BPP16, $A0100000)
17 | DPC(RDPBuffer, RDPBufferEnd)
18 | WaitScanline($200)
19 | nop // Marker NOP's
20 | Loop:
21 | j Loop
22 | nop // Delay Slot
23 |
24 |
25 | macro square16(col, row, color) {
26 | Set_Fill_Color ({color} << 16) | {color}
27 | // Bottom Right X, Bottom Right Y, Top Left X, Top Left Y
28 | Fill_Rectangle (({row} * 16) + (({col} + 1) * 16)) << 2, ({row} * 16) + 16 << 2, (({row} * 16) + ({col} * 16)) << 2, ({row} * 16) << 2
29 | }
30 |
31 |
32 | align(8) // Align 64-Bit
33 | RDPBuffer:
34 | arch n64.rdp
35 | Set_Scissor 0<<2,0<<2, 0,0, 320<<2,240<<2
36 | Set_Other_Modes CYCLE_TYPE_FILL // | Z_MODE_OPAQUE
37 | Set_Color_Image IMAGE_DATA_FORMAT_RGBA,SIZE_OF_PIXEL_16B,320-1, $00100000
38 |
39 | Set_Fill_Color (BLACK << 16) | BLACK // Set Fill Color: PACKED COLOR 32B R8G8B8A8 Pixel
40 | Fill_Rectangle 319<<2,239<<2, 0<<2,0<<2 // Fill Rectangle: XL 319.0,YL 239.0, XH 0.0,YH 0.0
41 |
42 | square16(0, 0, STEEL_BLUE)
43 | square16(1, 0, PALE_TURQUOISE)
44 | square16(0, 1, MEDIUM_TURQUOISE)
45 | square16(1, 1, CADET_BLUE)
46 | RDPBufferEnd:
--------------------------------------------------------------------------------
/N64/Color16/N64_Header.asm:
--------------------------------------------------------------------------------
1 | //============
2 | // N64 Header
3 | //============
4 | // PI_BSB_DOM1
5 | db $80 // Initial PI_BSB_DOM1_LAT_REG Value
6 | db $37 // Initial PI_BSB_DOM1_PGS_REG Value
7 | db $12 // Initial PI_BSB_DOM1_PWD_REG Value
8 | db $40 // Initial PI_BSB_DOM1_PGS_REG Value
9 |
10 | // CLOCK RATE
11 | dw $000F // Initial Clock Rate
12 |
13 | // VECTOR
14 | dw Start // Boot Address Offset
15 | dw $1444 // Release Offset
16 |
17 | // COMPLEMENT CHECK & CHECKSUM
18 | db "CRC1" // CRC1: COMPLEMENT CHECK
19 | db "CRC2" // CRC2: CHECKSUM
20 |
21 | dd 0 // UNUSED
22 |
23 | // PROGRAM TITLE (27 Byte ASCII String, Use Spaces For Unused Bytes)
24 | db "Color 16 bit "
25 | // "123456789012345678901234567"
26 |
27 | // DEVELOPER ID CODE
28 | db $00 // "N" = Nintendo
29 |
30 | // CARTRIDGE ID CODE
31 | db $00
32 |
33 | db 0 // UNUSED
34 |
35 | // COUNTRY CODE
36 | db $00 // "D" = Germany, "E" = USA, "J" = Japan, "P" = Europe, "U" = Australia
37 |
38 | db 0 // UNUSED
--------------------------------------------------------------------------------
/N64/Color16/make.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | set rom_name=Color16_Test.N64
3 | REM Space seperated list of source files
4 | set source_files=Color16_Test.asm
5 |
6 | if exist %rom_name% (
7 | del /q %rom_name%
8 | )
9 | bass -strict -create %1 -o %rom_name% %source_files%
10 | if exist %rom_name% (
11 | @chksum64 %rom_name%
12 | )
--------------------------------------------------------------------------------
/N64/Color32/Color32_Test.N64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/Color32/Color32_Test.N64
--------------------------------------------------------------------------------
/N64/Color32/Color32_Test.asm:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 | fill 1052672
4 |
5 | origin $00000000
6 | base $80000000
7 | include "../LIB/N64.INC"
8 | include "../LIB/COLORS32.INC"
9 | include "../LIB/N64_GFX.INC"
10 |
11 | include "N64_HEADER.ASM"
12 | insert "../LIB/N64_BOOTCODE.BIN"
13 |
14 | Start:
15 | N64_INIT()
16 | ScreenNTSC(320, 240, BPP32, $A0100000)
17 | nop // Marker NOP's
18 | WaitScanline($200)
19 | DPC(RDPBuffer, RDPBufferEnd)
20 | nop // Marker NOP's
21 | Loop:
22 | j Loop
23 | nop // Delay Slot
24 |
25 | align(8) // Align 64-Bit
26 | RDPBuffer:
27 | arch n64.rdp
28 | Set_Scissor 0<<2,0<<2, 0,0, 320<<2,240<<2
29 | Set_Other_Modes CYCLE_TYPE_FILL
30 | Set_Color_Image IMAGE_DATA_FORMAT_RGBA,SIZE_OF_PIXEL_32B,320-1, $00100000
31 |
32 | Set_Fill_Color $000000FF // Set Fill Color: PACKED COLOR 32B R8G8B8A8 Pixel
33 | Fill_Rectangle 319<<2,239<<2, 0<<2,0<<2 // Fill Rectangle: XL 319.0,YL 239.0, XH 0.0,YH 0.0
34 |
35 | Set_Fill_Color INDIAN_RED
36 | // Bottom Right X, Bottom Right Y, Top Left X, Top Left Y
37 | Fill_Rectangle 20<<2,20<<2, 1<<2,1<<2
38 |
39 | Set_Fill_Color LIGHT_CORAL
40 | Fill_Rectangle 40<<2,20<<2, 21<<2,1<<2
41 | Set_Fill_Color SALMON
42 | Fill_Rectangle 60<<2,20<<2, 41<<2,1<<2
43 | Set_Fill_Color DARK_SALMON
44 | Fill_Rectangle 80<<2,20<<2, 61<<2,1<<2
45 | Set_Fill_Color CRIMSON
46 | Fill_Rectangle 100<<2,20<<2, 81<<2,1<<2
47 | Set_Fill_Color RED
48 | Fill_Rectangle 120<<2,20<<2, 101<<2,1<<2
49 | Set_Fill_Color FIRE_BRICK
50 | Fill_Rectangle 140<<2,20<<2, 121<<2,1<<2
51 | Set_Fill_Color DARK_RED
52 | Fill_Rectangle 160<<2,20<<2, 141<<2,1<<2
53 | Set_Fill_Color BLACK
54 | Fill_Rectangle 180<<2,20<<2, 161<<2,1<<2
55 |
56 | Set_Fill_Color PINK
57 | Fill_Rectangle 200<<2,20<<2, 181<<2,1<<2
58 | Set_Fill_Color LIGHT_PINK
59 | Fill_Rectangle 220<<2,20<<2, 201<<2,1<<2
60 | Set_Fill_Color HOT_PINK
61 | Fill_Rectangle 240<<2,20<<2, 221<<2,1<<2
62 | Set_Fill_Color DEEP_PINK
63 | Fill_Rectangle 260<<2,20<<2, 241<<2,1<<2
64 | Set_Fill_Color MEDIUM_VIOLET_RED
65 | Fill_Rectangle 280<<2,20<<2, 261<<2,1<<2
66 | Set_Fill_Color PALE_VIOLET_RED
67 | Fill_Rectangle 300<<2,20<<2, 281<<2,1<<2
68 | Set_Fill_Color BLACK
69 | Fill_Rectangle 320<<2,20<<2, 301<<2,1<<2
70 |
71 | // Bottom Right X, Bottom Right Y, Top Left X, Top Left Y
72 | Set_Fill_Color LIGHT_SALMON
73 | Fill_Rectangle 20<<2,40<<2, 1<<2,21<<2
74 | Set_Fill_Color CORAL
75 | Fill_Rectangle 40<<2,40<<2, 21<<2,21<<2
76 | Set_Fill_Color TOMATO
77 | Fill_Rectangle 60<<2,40<<2, 41<<2,21<<2
78 | Set_Fill_Color ORANGE_RED
79 | Fill_Rectangle 80<<2,40<<2, 61<<2,21<<2
80 | Set_Fill_Color DARK_ORANGE
81 | Fill_Rectangle 100<<2,40<<2, 81<<2,21<<2
82 | Set_Fill_Color ORANGE
83 | Fill_Rectangle 120<<2,40<<2, 101<<2,21<<2
84 | Set_Fill_Color BLACK
85 | Fill_Rectangle 140<<2,40<<2, 121<<2,21<<2
86 |
87 | Set_Fill_Color GOLD
88 | Fill_Rectangle 160<<2,40<<2, 141<<2, 21<<2
89 | Set_Fill_Color YELLOW
90 | Fill_Rectangle 180<<2,40<<2, 161<<2,21<<2
91 | Set_Fill_Color LIGHT_YELLOW
92 | Fill_Rectangle 200<<2,40<<2, 181<<2,21<<2
93 | Set_Fill_Color LEMON_CHIFFON
94 | Fill_Rectangle 220<<2,40<<2, 201<<2,21<<2
95 | Set_Fill_Color LIGHT_GOLDENROD_YELLOW
96 | Fill_Rectangle 240<<2,40<<2, 221<<2,21<<2
97 | Set_Fill_Color PAPAYA_WHIP
98 | Fill_Rectangle 260<<2,40<<2, 241<<2,21<<2
99 | Set_Fill_Color MOCCASIN
100 | Fill_Rectangle 280<<2,40<<2, 261<<2,21<<2
101 | Set_Fill_Color PEACH_PUFF
102 | Fill_Rectangle 300<<2,40<<2, 281<<2,21<<2
103 | Set_Fill_Color PALE_GOLDENROD
104 | Fill_Rectangle 320<<2,40<<2, 301<<2,21<<2
105 | Set_Fill_Color KHAKI
106 | Fill_Rectangle 340<<2,40<<2, 321<<2,21<<2
107 |
108 | Set_Fill_Color DARK_KHAKI
109 | Fill_Rectangle 20<<2,60<<2,1<<2,41<<2
110 | Set_Fill_Color BLACK
111 | Fill_Rectangle 40<<2,60<<2,21<<2,41<<2
112 |
113 | Set_Fill_Color LAVENDER
114 | Fill_Rectangle 60<<2,60<<2,41<<2,41<<2
115 | Set_Fill_Color THISTLE
116 | Fill_Rectangle 80<<2,60<<2,61<<2,41<<2
117 | Set_Fill_Color PLUM
118 | Fill_Rectangle 100<<2,60<<2,81<<2,41<<2
119 | Set_Fill_Color VIOLET
120 | Fill_Rectangle 120<<2,60<<2,101<<2,41<<2
121 | Set_Fill_Color ORCHID
122 | Fill_Rectangle 140<<2,60<<2,121<<2,41<<2
123 | Set_Fill_Color FUCHSIA
124 | Fill_Rectangle 160<<2,60<<2,141<<2,41<<2
125 | Set_Fill_Color MAGENTA
126 | Fill_Rectangle 180<<2,60<<2,161<<2,41<<2
127 | Set_Fill_Color MEDIUM_ORCHID
128 | Fill_Rectangle 200<<2,60<<2,181<<2,41<<2
129 | Set_Fill_Color BLUE_VIOLET
130 | Fill_Rectangle 220<<2,60<<2,201<<2,41<<2
131 | Set_Fill_Color DARK_ORCHID
132 | Fill_Rectangle 240<<2,60<<2,221<<2,41<<2
133 | Set_Fill_Color DARK_MAGENTA
134 | Fill_Rectangle 260<<2,60<<2,241<<2,41<<2
135 | Set_Fill_Color PURPLE
136 | Fill_Rectangle 280<<2,60<<2,261<<2,41<<2
137 | Set_Fill_Color INDIGO
138 | Fill_Rectangle 300<<2,60<<2,281<<2,41<<2
139 | Set_Fill_Color SLATE_BLUE
140 | Fill_Rectangle 320<<2,60<<2,301<<2,41<<2
141 | Set_Fill_Color DARK_SLATE_BLUE
142 | Fill_Rectangle 340<<2,60<<2,321<<2,41<<2
143 |
144 | Set_Fill_Color BLACK
145 | Fill_Rectangle 20<<2,80<<2,1<<2,61<<2
146 | Set_Fill_Color GREEN_YELLOW
147 | Fill_Rectangle 40<<2,80<<2,21<<2,61<<2
148 | Set_Fill_Color CHARTREUSE
149 | Fill_Rectangle 60<<2,80<<2,41<<2,61<<2
150 | Set_Fill_Color LAWN_GREEN
151 | Fill_Rectangle 80<<2,80<<2,61<<2,61<<2
152 | Set_Fill_Color LIME
153 | Fill_Rectangle 100<<2,80<<2,81<<2,61<<2
154 | Set_Fill_Color LIME_GREEN
155 | Fill_Rectangle 120<<2,80<<2,101<<2,61<<2
156 | Set_Fill_Color PALE_GREEN
157 | Fill_Rectangle 140<<2,80<<2,121<<2,61<<2
158 | Set_Fill_Color LIGHT_GREEN
159 | Fill_Rectangle 160<<2,80<<2,141<<2,61<<2
160 | Set_Fill_Color MEDIUM_SPRING_GREEN
161 | Fill_Rectangle 180<<2,80<<2,161<<2,61<<2
162 | Set_Fill_Color SPRING_GREEN
163 | Fill_Rectangle 200<<2,80<<2,181<<2,61<<2
164 | Set_Fill_Color MEDIUM_SEA_GREEN
165 | Fill_Rectangle 220<<2,80<<2,201<<2,61<<2
166 | Set_Fill_Color SEA_GREEN
167 | Fill_Rectangle 240<<2,80<<2,221<<2,61<<2
168 | Set_Fill_Color FOREST_GREEN
169 | Fill_Rectangle 260<<2,80<<2,241<<2,61<<2
170 | Set_Fill_Color GREEN
171 | Fill_Rectangle 280<<2,80<<2,261<<2,61<<2
172 | Set_Fill_Color DARK_GREEN
173 | Fill_Rectangle 300<<2,80<<2,281<<2,61<<2
174 | Set_Fill_Color YELLOW_GREEN
175 | Fill_Rectangle 320<<2,80<<2,301<<2,61<<2
176 | Set_Fill_Color OLIVE_DRAB
177 | Fill_Rectangle 340<<2,80<<2,321<<2,61<<2
178 |
179 | Set_Fill_Color OLIVE
180 | Fill_Rectangle 20<<2,100<<2,1<<2,81<<2
181 | Set_Fill_Color DARK_OLIVE_GREEN
182 | Fill_Rectangle 40<<2,100<<2,21<<2,81<<2
183 | Set_Fill_Color MEDIUM_AQUAMARINE
184 | Fill_Rectangle 60<<2,100<<2,41<<2,81<<2
185 | Set_Fill_Color DARK_SEA_GREEN
186 | Fill_Rectangle 80<<2,100<<2,61<<2,81<<2
187 | Set_Fill_Color LIGHT_SEA_GREEN
188 | Fill_Rectangle 100<<2,100<<2,81<<2,81<<2
189 | Set_Fill_Color DARK_CYAN
190 | Fill_Rectangle 120<<2,100<<2,101<<2,81<<2
191 | Set_Fill_Color TEAL
192 | Fill_Rectangle 140<<2,100<<2,121<<2,81<<2
193 | Set_Fill_Color BLACK
194 | Fill_Rectangle 160<<2,100<<2,141<<2,81<<2
195 |
196 | Set_Fill_Color AQUA
197 | Fill_Rectangle 180<<2,100<<2,161<<2,81<<2
198 | Set_Fill_Color CYAN
199 | Fill_Rectangle 200<<2,100<<2,181<<2,81<<2
200 | Set_Fill_Color LIGHT_CYAN
201 | Fill_Rectangle 220<<2,100<<2,201<<2,81<<2
202 | Set_Fill_Color PALE_TURQUOISE
203 | Fill_Rectangle 240<<2,100<<2,221<<2,81<<2
204 | Set_Fill_Color AQUAMARINE
205 | Fill_Rectangle 260<<2,100<<2,241<<2,81<<2
206 | Set_Fill_Color TURQUOISE
207 | Fill_Rectangle 280<<2,100<<2,261<<2,81<<2
208 | Set_Fill_Color MEDIUM_TURQUOISE
209 | Fill_Rectangle 300<<2,100<<2,281<<2,81<<2
210 | Set_Fill_Color DARK_TURQUOISE
211 | Fill_Rectangle 320<<2,100<<2,301<<2,81<<2
212 | Set_Fill_Color CADET_BLUE
213 | Fill_Rectangle 340<<2,100<<2,321<<2,81<<2
214 |
215 | Set_Fill_Color STEEL_BLUE
216 | Fill_Rectangle 20<<2,120<<2,1<<2,101<<2
217 | Set_Fill_Color LIGHT_STEEL_BLUE
218 | Fill_Rectangle 40<<2,120<<2,21<<2,101<<2
219 | Set_Fill_Color POWDER_BLUE
220 | Fill_Rectangle 60<<2,120<<2,41<<2,101<<2
221 | Set_Fill_Color LIGHT_BLUE
222 | Fill_Rectangle 80<<2,120<<2,61<<2,101<<2
223 | Set_Fill_Color SKY_BLUE
224 | Fill_Rectangle 100<<2,120<<2,81<<2,101<<2
225 | Set_Fill_Color LIGHT_SKY_BLUE
226 | Fill_Rectangle 120<<2,120<<2,101<<2,101<<2
227 | Set_Fill_Color DEEP_SKY_BLUE
228 | Fill_Rectangle 140<<2,120<<2,121<<2,101<<2
229 | Set_Fill_Color DODGER_BLUE
230 | Fill_Rectangle 160<<2,120<<2,141<<2,101<<2
231 | Set_Fill_Color CORN_FLOWER_BLUE
232 | Fill_Rectangle 180<<2,120<<2,161<<2,101<<2
233 | Set_Fill_Color MEDIUM_SLATE_BLUE
234 | Fill_Rectangle 200<<2,120<<2,181<<2,101<<2
235 | Set_Fill_Color ROYAL_BLUE
236 | Fill_Rectangle 220<<2,120<<2,201<<2,101<<2
237 | Set_Fill_Color MEDIUM_BLUE
238 | Fill_Rectangle 240<<2,120<<2,221<<2,101<<2
239 | Set_Fill_Color BLUE
240 | Fill_Rectangle 260<<2,120<<2,241<<2,101<<2
241 | Set_Fill_Color DARK_BLUE
242 | Fill_Rectangle 280<<2,120<<2,261<<2,101<<2
243 | Set_Fill_Color NAVY
244 | Fill_Rectangle 300<<2,120<<2,281<<2,101<<2
245 | Set_Fill_Color MIDNIGHT_BLUE
246 | Fill_Rectangle 320<<2,120<<2,301<<2,101<<2
247 | Set_Fill_Color BLACK
248 | Fill_Rectangle 340<<2,120<<2,321<<2,101<<2
249 |
250 | Set_Fill_Color CORNSILK
251 | Fill_Rectangle 20<<2,140<<2,1<<2,121<<2
252 | Set_Fill_Color BLANCHED_ALMOND
253 | Fill_Rectangle 40<<2,140<<2,21<<2,121<<2
254 | Set_Fill_Color BISQUE
255 | Fill_Rectangle 60<<2,140<<2,41<<2,121<<2
256 | Set_Fill_Color NAVAJO_WHITE
257 | Fill_Rectangle 80<<2,140<<2,61<<2,121<<2
258 | Set_Fill_Color WHEAT
259 | Fill_Rectangle 100<<2,140<<2,81<<2,121<<2
260 | Set_Fill_Color BURLY_WOOD
261 | Fill_Rectangle 120<<2,140<<2,101<<2,121<<2
262 | Set_Fill_Color TAN
263 | Fill_Rectangle 140<<2,140<<2,121<<2,121<<2
264 | Set_Fill_Color ROSY_BROWN
265 | Fill_Rectangle 160<<2,140<<2,141<<2,121<<2
266 | Set_Fill_Color SANDY_BROWN
267 | Fill_Rectangle 180<<2,140<<2,161<<2,121<<2
268 | Set_Fill_Color GOLDENROD
269 | Fill_Rectangle 200<<2,140<<2,181<<2,121<<2
270 | Set_Fill_Color DARK_GOLDENROD
271 | Fill_Rectangle 220<<2,140<<2,201<<2,121<<2
272 | Set_Fill_Color PERU
273 | Fill_Rectangle 240<<2,140<<2,221<<2,121<<2
274 | Set_Fill_Color CHOCOLATE
275 | Fill_Rectangle 260<<2,140<<2,241<<2,121<<2
276 | Set_Fill_Color SADDLE_BROWN
277 | Fill_Rectangle 280<<2,140<<2,261<<2,121<<2
278 | Set_Fill_Color SIENNA
279 | Fill_Rectangle 300<<2,140<<2,281<<2,121<<2
280 | Set_Fill_Color BROWN
281 | Fill_Rectangle 320<<2,140<<2,301<<2,121<<2
282 | Set_Fill_Color MAROON
283 | Fill_Rectangle 340<<2,140<<2,321<<2,121<<2
284 |
285 | Set_Fill_Color BLACK
286 | Fill_Rectangle 20<<2,160<<2,1<<2,141<<2
287 | Set_Fill_Color WHITE
288 | Fill_Rectangle 40<<2,160<<2,21<<2,141<<2
289 | Set_Fill_Color SNOW
290 | Fill_Rectangle 60<<2,160<<2,41<<2,141<<2
291 | Set_Fill_Color HONEYDEW
292 | Fill_Rectangle 80<<2,160<<2,61<<2,141<<2
293 | Set_Fill_Color MINT_CREAM
294 | Fill_Rectangle 100<<2,160<<2,81<<2,141<<2
295 | Set_Fill_Color AZURE
296 | Fill_Rectangle 120<<2,160<<2,101<<2,141<<2
297 | Set_Fill_Color ALICE_BLUE
298 | Fill_Rectangle 140<<2,160<<2,121<<2,141<<2
299 | Set_Fill_Color GHOST_WHITE
300 | Fill_Rectangle 160<<2,160<<2,141<<2,141<<2
301 | Set_Fill_Color WHITE_SMOKE
302 | Fill_Rectangle 180<<2,160<<2,161<<2,141<<2
303 | Set_Fill_Color SEA_SHELL
304 | Fill_Rectangle 200<<2,160<<2,181<<2,141<<2
305 | Set_Fill_Color BEIGE
306 | Fill_Rectangle 220<<2,160<<2,201<<2,141<<2
307 | Set_Fill_Color OLD_LACE
308 | Fill_Rectangle 240<<2,160<<2,221<<2,141<<2
309 | Set_Fill_Color FLORAL_WHITE
310 | Fill_Rectangle 260<<2,160<<2,241<<2,141<<2
311 | Set_Fill_Color IVORY
312 | Fill_Rectangle 280<<2,160<<2,261<<2,141<<2
313 | Set_Fill_Color ANTIQUE_WHITE
314 | Fill_Rectangle 300<<2,160<<2,281<<2,141<<2
315 | Set_Fill_Color LINEN
316 | Fill_Rectangle 320<<2,160<<2,301<<2,141<<2
317 | Set_Fill_Color LAVENDER_BLUSH
318 | Fill_Rectangle 340<<2,160<<2,321<<2,141<<2
319 |
320 | Set_Fill_Color MISTY_ROSE
321 | Fill_Rectangle 20<<2,180<<2,1<<2,161<<2
322 | Set_Fill_Color BLACK
323 | Fill_Rectangle 40<<2,180<<2,21<<2,161<<2
324 | Set_Fill_Color GAINSBORO
325 | Fill_Rectangle 60<<2,180<<2,41<<2,161<<2
326 | Set_Fill_Color LIGHT_GREY
327 | Fill_Rectangle 80<<2,180<<2,61<<2,161<<2
328 | Set_Fill_Color SILVER
329 | Fill_Rectangle 100<<2,180<<2,81<<2,161<<2
330 | Set_Fill_Color DARK_GREY
331 | Fill_Rectangle 120<<2,180<<2,101<<2,161<<2
332 | Set_Fill_Color GREY
333 | Fill_Rectangle 140<<2,180<<2,121<<2,161<<2
334 | Set_Fill_Color DIM_GREY
335 | Fill_Rectangle 160<<2,180<<2,141<<2,161<<2
336 | Set_Fill_Color LIGHT_SLATE_GREY
337 | Fill_Rectangle 180<<2,180<<2,161<<2,161<<2
338 | Set_Fill_Color SLATE_GREY
339 | Fill_Rectangle 200<<2,180<<2,181<<2,161<<2
340 | Set_Fill_Color BLACK
341 | Fill_Rectangle 220<<2,180<<2,201<<2,161<<2
342 | Set_Fill_Color BLACK
343 | Fill_Rectangle 240<<2,180<<2,221<<2,161<<2
344 | Set_Fill_Color BLACK
345 | Fill_Rectangle 260<<2,180<<2,241<<2,161<<2
346 | Set_Fill_Color BLACK
347 | Fill_Rectangle 280<<2,180<<2,261<<2,161<<2
348 | Set_Fill_Color BLACK
349 | Fill_Rectangle 300<<2,180<<2,281<<2,161<<2
350 | Set_Fill_Color BLACK
351 | Fill_Rectangle 320<<2,180<<2,301<<2,161<<2
352 | Set_Fill_Color BLACK
353 | Fill_Rectangle 340<<2,180<<2,321<<2,161<<2
354 |
355 | Sync_Full // Ensure Entire Scene Is Fully Drawn
356 | RDPBufferEnd:
--------------------------------------------------------------------------------
/N64/Color32/N64_Header.asm:
--------------------------------------------------------------------------------
1 | //============
2 | // N64 Header
3 | //============
4 | // PI_BSB_DOM1
5 | db $80 // Initial PI_BSB_DOM1_LAT_REG Value
6 | db $37 // Initial PI_BSB_DOM1_PGS_REG Value
7 | db $12 // Initial PI_BSB_DOM1_PWD_REG Value
8 | db $40 // Initial PI_BSB_DOM1_PGS_REG Value
9 |
10 | // CLOCK RATE
11 | dw $000F // Initial Clock Rate
12 |
13 | // VECTOR
14 | dw Start // Boot Address Offset
15 | dw $1444 // Release Offset
16 |
17 | // COMPLEMENT CHECK & CHECKSUM
18 | db "CRC1" // CRC1: COMPLEMENT CHECK
19 | db "CRC2" // CRC2: CHECKSUM
20 |
21 | dd 0 // UNUSED
22 |
23 | // PROGRAM TITLE (27 Byte ASCII String, Use Spaces For Unused Bytes)
24 | db "Color 32 bit "
25 | // "123456789012345678901234567"
26 |
27 | // DEVELOPER ID CODE
28 | db $00 // "N" = Nintendo
29 |
30 | // CARTRIDGE ID CODE
31 | db $00
32 |
33 | db 0 // UNUSED
34 |
35 | // COUNTRY CODE
36 | db $00 // "D" = Germany, "E" = USA, "J" = Japan, "P" = Europe, "U" = Australia
37 |
38 | db 0 // UNUSED
--------------------------------------------------------------------------------
/N64/Color32/make.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | set rom_name=Color32_Test.N64
3 | REM Space seperated list of source files
4 | set source_files=Color32_Test.asm
5 |
6 | if exist %rom_name% (
7 | del /q %rom_name%
8 | )
9 | bass -strict -create %1 -o %rom_name% %source_files%
10 | if exist %rom_name% (
11 | @chksum64 %rom_name%
12 | )
--------------------------------------------------------------------------------
/N64/Exception/Exception.N64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/Exception/Exception.N64
--------------------------------------------------------------------------------
/N64/Exception/Exception.asm:
--------------------------------------------------------------------------------
1 | libn64_tlb_exception_handler:
2 | base $80000000
3 | mtc0 ra, $30
4 | lui ra, 0x8000
5 | fixed_gap(libn64_tlb_exception_handler, 0x080)
6 | libn64_xtlb_exception_handler:
7 | fixed_gap(libn64_xtlb_exception_handler, 0x100)
8 | libn64_cache_exception_handler:
9 | fixed_gap(libn64_cache_exception_handler, 0x180)
10 | libn64_general_exception_handler:
11 |
12 | fixed_gap(libn64_tlb_exception_handler, 0x300)
13 | libn64_exception_jump_table:
14 |
15 | libn64_exception_register_store:
16 | // Scaler Registers
17 | dd 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
18 | dd 0, 0, 0, 0, 0, 0, 0, 0
19 | dd 0, 0, 0, 0, 0, 0, 0, 0
20 | dd 0, 0, 0, 0, 0, 0, 0, 0
21 | db "End of Scaler"
22 | // COP0
23 | dd 0, 0, 0, 0, 0, 0, 0, 0
24 | db "End of Ctrl"
25 | // COP1 Floating Point
26 | dd 0, 0, 0, 0, 0, 0, 0, 0
27 | dd 0, 0, 0, 0, 0, 0, 0, 0
28 | dd 0, 0, 0, 0, 0, 0, 0, 0
29 | dd 0, 0, 0, 0, 0, 0, 0, 0
30 | db "End of Data"
--------------------------------------------------------------------------------
/N64/Exception/ExceptionTest.N64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/Exception/ExceptionTest.N64
--------------------------------------------------------------------------------
/N64/Exception/Main.asm:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 | output "Exception.N64", create
4 | fill 1052672
5 |
6 | origin $00000000
7 | base $80000000
8 | include "../LIB/N64.INC"
9 | include "N64_HEADER.ASM"
10 | insert "../LIB/N64_BOOTCODE.BIN"
11 |
12 | Start:
13 | lui t0,$BFC0
14 | addi t1,r0,8
15 | sw t1,$7FC(t0)
16 |
17 | // DMA interrupt handler on top of the vector.
18 | // First, write the DRAM (destination) register.
19 | lui at, 0xA460
20 | lui v0, 0x8000
21 | sw v0, 0(at) // RDRAM Location
22 | la v1, 0x10000000 + (libn64_tlb_exception_handler - 0x80000000)
23 | sw v1, 0x4(at) // Cart Location
24 | addiu v0, r0, 0x300 - 0x1
25 | sw v0, 0xC(at) // Start DMA from CART -> RDRAM
26 | Loop:
27 | j Loop
28 | nop
29 | include "./Exception.asm"
--------------------------------------------------------------------------------
/N64/Exception/N64_Header.asm:
--------------------------------------------------------------------------------
1 | //============
2 | // N64 Header
3 | //============
4 | // PI_BSB_DOM1
5 | db $80 // Initial PI_BSB_DOM1_LAT_REG Value
6 | db $37 // Initial PI_BSB_DOM1_PGS_REG Value
7 | db $12 // Initial PI_BSB_DOM1_PWD_REG Value
8 | db $40 // Initial PI_BSB_DOM1_PGS_REG Value
9 |
10 | // CLOCK RATE
11 | dw $000F // Initial Clock Rate
12 |
13 | // VECTOR
14 | dw Start // Boot Address Offset
15 | dw $1444 // Release Offset
16 |
17 | // COMPLEMENT CHECK & CHECKSUM
18 | db "CRC1" // CRC1: COMPLEMENT CHECK
19 | db "CRC2" // CRC2: CHECKSUM
20 |
21 | dd 0 // UNUSED
22 |
23 | // PROGRAM TITLE (27 Byte ASCII String, Use Spaces For Unused Bytes)
24 | db "Exception Jump Table "
25 | // "123456789012345678901234567"
26 |
27 | // DEVELOPER ID CODE
28 | db $00 // "N" = Nintendo
29 |
30 | // CARTRIDGE ID CODE
31 | db $00
32 |
33 | db 0 // UNUSED
34 |
35 | // COUNTRY CODE
36 | db $00 // "D" = Germany, "E" = USA, "J" = Japan, "P" = Europe, "U" = Australia
37 |
38 | db 0 // UNUSED
--------------------------------------------------------------------------------
/N64/Exception/cfg/default.cfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/N64/Exception/cfg/n64.cfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/N64/Exception/error.log:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/Exception/error.log
--------------------------------------------------------------------------------
/N64/Exception/make.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | set rom_name=Exception.N64
3 | REM Space seperated list of source files
4 | set source_files=Main.asm
5 |
6 | if exist %rom_name% (
7 | del /q %rom_name%
8 | )
9 | bass -strict -o %rom_name% %source_files%
10 | if exist %rom_name% (
11 | @chksum64 %rom_name%
12 | )
--------------------------------------------------------------------------------
/N64/Exception/nvram/n64/Lesson2.nv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/Exception/nvram/n64/Lesson2.nv
--------------------------------------------------------------------------------
/N64/Exception2/Exception.N64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/Exception2/Exception.N64
--------------------------------------------------------------------------------
/N64/Exception2/Exception.asm:
--------------------------------------------------------------------------------
1 | // Notes:
2 | // There can be only one Exception.
3 | // If the Exception is "Interrupt" then there can be multiple Interrupts.
4 | // Should the Exception handler be able to throw exceptions?
5 | libn64_tlb_exception_handler:
6 | variable old_base(base())
7 | base $80000000
8 | // ra when used correctly is 32bits, COP0$30 is 32 bits
9 | // This frees up ra for anything, including Jumps
10 | mtc0 ra, $30
11 | la ra, libn64_tlb_exception_handler
12 | sw k0, k0(ra)
13 | mfc0 k0, Cause // Get Cause
14 | sw k1, k1(ra)
15 | andi k1, k0, 0x0F // mask
16 | beql k1, r0, Interrupt
17 | nop
18 | // Process Exceptions
19 | // TODO Call Individual handler
20 | j int_x_continue
21 | nop
22 | align(128)
23 | libn64_xtlb_exception_handler:
24 | j $80000001
25 | nop
26 | int_x_continue:
27 | // TODO More Code HERE
28 | Interrupt:
29 | mfc0 k1, SR // Get Status
30 | andi k1, k1, $FF00 // mask
31 | and k0, k0, k1
32 | addi k0, k0, 0x60 // 0x60 = 24 * 4
33 | li k1, libn64_exception_jump_table
34 | add k1, k0, k1
35 | lw k0, 0(k1)
36 | // FIX: Don't have the right memory address yet.
37 | // TODO Call Individual handler
38 | j int_cache_continue
39 | nop
40 | align(128)
41 | libn64_cache_exception_handler:
42 | j $80000002
43 | nop
44 | int_cache_continue:
45 | // TODO More Code HERE
46 | j int_general_continue
47 | nop
48 | align(128)
49 | libn64_general_exception_handler:
50 | j $80000003
51 | nop
52 | int_general_continue:
53 | mfc0 k0, EPC
54 | // Restore the 'ra' register
55 | // TODO: Process Branch Delay Bit, 4 instructions
56 | mfc0 ra, PErr
57 | addiu k0, k0, 4
58 | mtc0 k0, EPC
59 | eret
60 | align(128)
61 | libn64_tlb_exception_handler_end:
62 | base old_base
63 | db "JTBL"
64 | libn64_exception_jump_table:
65 | dw 0 // Interrupt type Exception
66 | dw 0 // TLB Modification
67 | dw 0 // TLB Miss (load or fetch)
68 | dw 0 // TLB Miss (store)
69 | dw 0 // Address Error (load or fetch)
70 | dw 0 // Address Error (store)
71 | dw 0 // Bus Error (instruction fetch)
72 | dw 0 // Bus Error (load or store)
73 | dw 0 // Syscall
74 | dw 0 // Breakpoint
75 | dw 0 // Reserved Instruction
76 | dw 0 // Coprocessor Unusable
77 | dw 0 // Arithmetic Overflow
78 | dw 0 // Trap
79 | db "RFU " // Unused - RFU
80 | dw 0 // Floating Point
81 | dw 0 // 16 MI-SP
82 | dw 0 // 17 MI-SI
83 | dw 0 // 18 MI-AI
84 | dw 0 // 19 MI-VI
85 | dw 0 // 20 MI-PI
86 | dw 0 // 21 MI-DP
87 | dw 0 // 22
88 | dw 0 // Watch
89 | dw 0 // 24 INT0 - Software 0
90 | dw 0 // 25 INT1 - Software 1
91 | dw 0 // 26 INT2 (PIN-INT0) - RCP
92 | dw 0 // 27 INT3 (PIN-INT1) - Unused
93 | dw 0 // 28 INT4 (PIN-INT2) - PIF
94 | dw 0 // 29 INT5 (PIN-INT3) - Unused
95 | dw 0 // 30 INT6 (PIN-INT4) - Unused
96 | dw 0 // 31 INT7 - Timer
97 | db "register"
98 | libn64_exception_register_store:
99 | // Scaler Registers
100 | dd 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
101 | dd 0, 0, 0, 0, 0, 0, 0, 0
102 | dd 0, 0, 0, 0, 0, 0, 0, 0
103 | dd 0, 0, 0, 0, 0, 0, 0, 0
104 | db "End of Scaler"
105 | // COP0
106 | dd 0, 0, 0, 0, 0, 0, 0, 0
107 | db "End of Ctrl"
108 | // COP1 Floating Point
109 | dd 0, 0, 0, 0, 0, 0, 0, 0
110 | dd 0, 0, 0, 0, 0, 0, 0, 0
111 | dd 0, 0, 0, 0, 0, 0, 0, 0
112 | dd 0, 0, 0, 0, 0, 0, 0, 0
113 | db "End of Float"
--------------------------------------------------------------------------------
/N64/Exception2/Main.asm:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 | output "Exception.N64", create
4 | fill 1052672
5 |
6 | origin $00000000
7 | base $80000000
8 | include "../LIB/N64.INC"
9 | include "N64_HEADER.ASM"
10 | insert "../LIB/N64_BOOTCODE.BIN"
11 |
12 | // constant exp_interrupt(0) //Not applicable
13 | constant exp_tlb_modification(1)
14 | constant exp_tlb_miss_misc(2)
15 | constant exp_tlb_miss_store(3)
16 | constant exp_addr_misc(4)
17 | constant exp_addr_store(5)
18 | constant exp_bus_fetch(6)
19 | constant exp_bus_misc(7)
20 | constant exp_syscall(8)
21 | constant exp_breakpoint(9)
22 | constant exp_reserved_instruction(10)
23 | constant exp_coprocessor_unusable(11)
24 | constant exp_arithmetic_overflow(12)
25 | constant exp_trap(13)
26 | //constant unused(14)
27 | constant exp_floating_point(15)
28 | constant int_MI_SP_entry(16)
29 | constant int_MI_SI_entry(17)
30 | constant int_MI_AI_entry(18)
31 | constant int_MI_VI_entry(19)
32 | constant int_MI_PI_entry(20)
33 | constant int_MI_DP_entry(21)
34 | // constant unused(22)
35 | constant exp_watch(23)
36 | constant int_software0_entry(24)
37 | constant int_software1_entry(25)
38 | constant int_RCP_entry(26)
39 | //constant int_unused_entry(27)
40 | constant int_PIF_entry(28)
41 | //constant int_unused_entry(29)
42 | //constant int_unused_entry(30)
43 | constant int_timer_entry(31)
44 |
45 | macro setHandler(handler_name, handler_label) {
46 | nop // Marker NOP's
47 | la t0, libn64_exception_jump_table
48 | li t1, {handler_label}
49 | sw t1, {handler_name}<<2(t0)
50 | nop // Marker NOP's
51 | }
52 |
53 | macro setInterrupt(enable_mask) {
54 | nop // Marker NOP's
55 | mfc0 t0, SR
56 | ori t0, t0, {enable_mask}
57 | mtc0 t0, SR
58 | nop // Marker NOP's
59 | }
60 |
61 | macro fireSoftwareInterrupt0() {
62 | mfc0 t0, Cause
63 | ori t0, t0, 0x0100
64 | mtc0 t0, Cause
65 | }
66 |
67 | macro fireSoftwareInterrupt1() {
68 | mfc0 t0, Cause
69 | ori t0, t0, 0x0200
70 | mtc0 t0, Cause
71 | }
72 |
73 | Start:
74 | N64_INIT()
75 |
76 | setInterrupt(0x0)
77 |
78 | DMA(libn64_tlb_exception_handler, libn64_tlb_exception_handler_end, 0x8000000)
79 |
80 | nop // Marker NOP's
81 | nop // Marker NOP's
82 |
83 | lui t1, PI_BASE
84 | dma_incomplete:
85 | lw t2, PI_STATUS(t1)
86 | bne t2, r0, dma_incomplete
87 | nop
88 | nop // Marker NOP's
89 | nop // Marker NOP's
90 |
91 | setHandler(exp_tlb_modification, software0)
92 | // Test Cases
93 | // Software Interrupts
94 | setHandler(int_software0_entry, software0)
95 | setInterrupt(0x0101)
96 | fireSoftwareInterrupt0()
97 |
98 | nop // Marker NOP's
99 | nop // Marker NOP's
100 |
101 | setHandler(int_software1_entry, software1)
102 | setInterrupt(0x0201)
103 | fireSoftwareInterrupt1()
104 |
105 | setInterrupt(0x0)
106 | nop // Marker NOP's
107 | nop // Marker NOP's
108 |
109 | // Timer Interrupts
110 | setHandler(int_timer_entry, timer)
111 | mfc0 t0, Compare
112 | addi t0, t0, 0x1000
113 | mtc0 t0, Compare
114 | setInterrupt(0x0801)
115 |
116 |
117 | nop // Marker NOP's
118 | setInterrupt(0x0)
119 | nop // Marker NOP's
120 |
121 | Loop:
122 | j Loop
123 | nop
124 |
125 | software0:
126 | ori t4, r0, 123
127 | jr ra
128 | nop
129 |
130 | software1:
131 | ori t4, r0, 234
132 | jr ra
133 | nop
134 | timer:
135 | ori t4, r0, 345
136 | jr ra
137 | nop
138 |
139 | include "./Exception.asm"
--------------------------------------------------------------------------------
/N64/Exception2/N64_Header.asm:
--------------------------------------------------------------------------------
1 | //============
2 | // N64 Header
3 | //============
4 | // PI_BSB_DOM1
5 | db $80 // Initial PI_BSB_DOM1_LAT_REG Value
6 | db $37 // Initial PI_BSB_DOM1_PGS_REG Value
7 | db $12 // Initial PI_BSB_DOM1_PWD_REG Value
8 | db $40 // Initial PI_BSB_DOM1_PGS_REG Value
9 |
10 | // CLOCK RATE
11 | dw $000F // Initial Clock Rate
12 |
13 | // VECTOR
14 | dw Start // Boot Address Offset
15 | dw $1444 // Release Offset
16 |
17 | // COMPLEMENT CHECK & CHECKSUM
18 | db "CRC1" // CRC1: COMPLEMENT CHECK
19 | db "CRC2" // CRC2: CHECKSUM
20 |
21 | dd 0 // UNUSED
22 |
23 | // PROGRAM TITLE (27 Byte ASCII String, Use Spaces For Unused Bytes)
24 | db "Exception Jump Table "
25 | // "123456789012345678901234567"
26 |
27 | // DEVELOPER ID CODE
28 | db $00 // "N" = Nintendo
29 |
30 | // CARTRIDGE ID CODE
31 | db $00
32 |
33 | db 0 // UNUSED
34 |
35 | // COUNTRY CODE
36 | db $00 // "D" = Germany, "E" = USA, "J" = Japan, "P" = Europe, "U" = Australia
37 |
38 | db 0 // UNUSED
--------------------------------------------------------------------------------
/N64/Exception2/make.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | set rom_name=Exception.N64
3 | REM Space seperated list of source files
4 | set source_files=Main.asm
5 |
6 | if exist %rom_name% (
7 | del /q %rom_name%
8 | )
9 | bass -strict -o %rom_name% %source_files%
10 | if exist %rom_name% (
11 | @chksum64 %rom_name%
12 | )
--------------------------------------------------------------------------------
/N64/ExceptionTest/ExceptionTest.N64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/ExceptionTest/ExceptionTest.N64
--------------------------------------------------------------------------------
/N64/ExceptionTest/ExceptionTest.asm:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 | fill 1052672
4 |
5 | origin $00000000
6 | base $80000000
7 | include "../LIB/N64.INC"
8 | include "../LIB/N64_GFX.INC"
9 | include "./N64_HEADER.ASM" // Include 64 Byte Header & Vector Table
10 | insert "../LIB/N64_BOOTCODE.BIN" // Include 4032 Byte Boot Code
11 | constant Status_All_Exceptions(0xFF10)
12 | // CU RP FR RE DS IM KX SX UX KSU ERL EXL IE
13 | // 0011 0 1 0 000'000'000 0000'0000 0 0 0 00 0 0 0
14 | // 0000 0 0 0 000'000'000 1111'1111 0 0 0 10 0 0 1
15 |
16 | force_pc($80001000)
17 | Start:
18 | align(8)
19 | N64_INIT()
20 | ScreenNTSC(320, 240, BPP32, $A0100000) // Screen NTSC: 320x240, 32BPP, DRAM Origin $A0100000
21 | // Insert Initialization Code
22 |
23 | mfc0 s0, SR
24 | // Copy Exception Handler code
25 | la t0, $8000'0000
26 | la t1, ExceptionHandlerBlock
27 | la t2, ExceptionHandlerBlockEnd
28 | repeat_load_exception:
29 | lw t3, 0(t1)
30 | lw t4, 4(t1)
31 | lw t5, 8(t1)
32 | lw t6, 12(t1)
33 | sw t3, 0(t0)
34 | sw t4, 4(t0)
35 | sw t5, 8(t0)
36 | sw t6, 12(t0)
37 | addi t1, t1, 16
38 | bne t1, t2, repeat_load_exception
39 | addi t0, t0, 16
40 | nop
41 | nop
42 | // Copy Exception Handler code to Cache area
43 | la t0, $A000'0000
44 | la t1, ExceptionHandlerBlock
45 | la t2, ExceptionHandlerBlockEnd
46 | repeat_load_exception_cache:
47 | lw t3, 0(t1)
48 | lw t4, 4(t1)
49 | lw t5, 8(t1)
50 | lw t6, 12(t1)
51 | sw t3, 0(t0)
52 | sw t4, 4(t0)
53 | sw t5, 8(t0)
54 | sw t6, 12(t0)
55 | addi t1, t1, 16
56 | bne t1, t2, repeat_load_exception_cache
57 | addi t0, t0, 16
58 | nop
59 | nop
60 |
61 | la t8, savedCP0
62 | jal save_cop0
63 | nop
64 | // Throws TLB Exception
65 | lui t2, r0;
66 | sw t3, 0(t2)
67 | nop
68 | nop
69 | nop
70 |
71 |
72 |
73 |
74 | // Throw XTLB Exception
75 | mfc0 t7, SR
76 | li t8, 0x20
77 | not t8, t8
78 | and t7, t7, t8
79 | mtc0 t7, SR
80 | ori t7, t7, 1
81 | mtc0 t7, SR
82 | // Try to access Memory above 4 GB
83 | addi t2, r0, -1;
84 | sw t3, 0(t2) // TODO: Doesn't work yet
85 | nop
86 | nop
87 | nop
88 |
89 | // Throw Cache Exception - Not Applicable on VR4300
90 |
91 | // Break Instruction
92 | break // TODO: Doesn't work yet
93 |
94 | // Syscall Instruction
95 | // syscall // TODO: Doesn't work yet
96 |
97 | // CP0 Disable - Control Processor
98 | mfc0 t7, SR
99 | li t8, 0x10000000
100 | not t8, t8
101 | and t7, t7, t8
102 | ori t7, t7, 0x10
103 | mtc0 t7, SR
104 | ori t7, t7, 1
105 | mtc0 t7, SR
106 | nop
107 | // Try to use CP0
108 | mtc0 t7, SR // TODO: Doesn't work yet
109 | nop
110 | nop
111 | nop
112 |
113 | // Set CP1 Disable - Floating Point Unit
114 | mfc0 t7, SR
115 | li t8, 0x20000000
116 | not t8, t8
117 | and t7, t7, t8
118 | mtc0 t7, SR
119 | ori t7, t7, 1
120 | mtc0 t7, SR
121 | nop
122 | // Try to use Floating Point Unit
123 | la t0, VALUEDOUBLEA
124 | ldc1 f0, 0(t0)
125 | nop
126 | nop
127 | nop
128 |
129 |
130 |
131 | Loop:
132 | // Insert Looping Code Here
133 | j Loop
134 | nop // Delay Slot
135 |
136 | save_cop0:
137 | dmfc0 t0, Index
138 | dmfc0 t1, Random
139 | dmfc0 t2, EntryLo0
140 | dmfc0 t3, EntryLo1
141 | dmfc0 t4, Context
142 | dmfc0 t5, PageMask
143 | dmfc0 t6, Wired
144 | sw t0, 0x00(k0)
145 | sw t1, 0x08(k0)
146 | sw t2, 0x0F(k0)
147 | sw t3, 0x17(k0)
148 | sw t4, 0x1F(k0)
149 | sw t5, 0x27(k0)
150 | sw t6, 0x2F(k0)
151 |
152 | // dmfc0 t3, EntryLo1
153 | // sw t3, 0x37(k0)
154 |
155 | dmfc0 t0, BadVAddr
156 | dmfc0 t1, Count
157 | dmfc0 t2, EntryHi
158 | dmfc0 t3, Compare
159 | dmfc0 t4, Status
160 | dmfc0 t5, Cause
161 | dmfc0 t6, EPC
162 |
163 | sw t0, 0x3F(k0)
164 | sw t1, 0x47(k0)
165 | sw t2, 0x4F(k0)
166 | sw t3, 0x57(k0)
167 | sw t4, 0x5F(k0)
168 | sw t5, 0x67(k0)
169 | sw t6, 0x6F(k0)
170 |
171 | dmfc0 t0, PRevID
172 | dmfc0 t1, Config
173 | dmfc0 t2, LLAddr
174 | dmfc0 t3, WatchLo
175 | dmfc0 t4, WatchHi
176 | dmfc0 t5, XContext
177 |
178 | sw t0, 0x77(k0)
179 | sw t1, 0x7F(k0)
180 | sw t2, 0x87(k0)
181 | sw t3, 0x8F(k0)
182 | sw t4, 0x97(k0)
183 | sw t5, 0x9F(k0)
184 |
185 | dmfc0 t0, PErr
186 | dmfc0 t1, CacheErr
187 | dmfc0 t2, TagLo
188 | dmfc0 t3, TagHi
189 | dmfc0 t4, ErrorEPC
190 |
191 | sw t0, 0xCF(k0)
192 | sw t1, 0xD7(k0)
193 | sw t2, 0xDF(k0)
194 | sw t3, 0xE7(k0)
195 | sw t4, 0xEF(k0)
196 |
197 | align(128)
198 | savedCP0:
199 | fill 256, 0x55
200 | rIndex: // 0
201 | rRandom: // 1
202 | rEntryLo0: // 2
203 | rEntryLo1: // 3
204 | rContext: // 4
205 | rPageMask: // 5
206 | rWired: // 6
207 | // 7
208 | rBadVAddr: // 8
209 | rCount: // 9
210 | rEntryHi: // 10
211 | rCompare: // 11
212 | rStatus: // SR, 12
213 | rCause: // 13
214 | rEPC: // 14
215 | rPRId: // 15
216 | rConfig: // 16
217 | rLLAddr: // 17
218 | rWatchLo: // 18
219 | rWatchHi: // 19
220 | rXContext: // 20
221 | // 21
222 | // 22
223 | // 23
224 | // 24
225 | // 25
226 | rPErr: // 26
227 | rCacheErr: // 27
228 | rTagLo: // 28
229 | rTagHi: // 29
230 | rErrorEPC: // 30
231 | // 31
232 | saved_cp0_end:
233 |
234 | align(128)
235 | screen_char:
236 | // 49 columns 637 of 640 pixels
237 | // 34 rows 476 of 480 pixels
238 | // 1,666 total characters on screen
239 | fill 49, 0x00
240 | fill 49, 0x01
241 | fill 49, 0x02
242 | fill 49, 0x03
243 | fill 49, 0x04
244 | fill 49, 0x05
245 | fill 49, 0x06
246 | fill 49, 0x07
247 | fill 49, 0x08
248 | fill 49, 0x09
249 | fill 49, 0x0A
250 | fill 49, 0x0B
251 | fill 49, 0x0C
252 | fill 49, 0x0D
253 | fill 49, 0x0E
254 | fill 49, 0x0F
255 | fill 49, 0x10
256 | fill 49, 0x11
257 | fill 49, 0x12
258 | fill 49, 0x13
259 | fill 49, 0x14
260 | fill 49, 0x15
261 | fill 49, 0x16
262 | fill 49, 0x17
263 | fill 49, 0x18
264 | fill 49, 0x19
265 | fill 49, 0x1A
266 | fill 49, 0x1B
267 | fill 49, 0x1C
268 | fill 49, 0x1D
269 | fill 49, 0x1E
270 | fill 49, 0x1F
271 | fill 49, 0x20
272 | fill 49, 0x21
273 | fill 49, 0x22
274 | screen_char_end:
275 |
276 | align(128)
277 | exception_cp0:
278 | fill 256, 0x55
279 | exception_cp0_end:
280 |
281 | align(128)
282 | ExceptionHandlerBlock:
283 | // TLB Handler
284 | la k0, exception_cp0
285 | jal save_cop0
286 | nop
287 | mfc0 k0, EPC
288 | mtc0 s0, SR
289 | addi k0, k0, 4
290 | mtc0 k0, EPC
291 | nop
292 | eret
293 | nop
294 | fill 100, 0xAA
295 | align(128)
296 | // XTLB Handler
297 | mfc0 k0, EPC
298 | mtc0 s0, SR
299 | addi k0, k0, 4
300 | mtc0 k0, EPC
301 | nop
302 | eret
303 | nop
304 | fill 100, 0xBB
305 | align(128)
306 | // Cache Handler
307 | mfc0 k0, EPC
308 | mtc0 s0, SR
309 | addi k0, k0, 4
310 | mtc0 k0, EPC
311 | nop
312 | eret
313 | nop
314 | fill 100, 0xCC
315 | align(128)
316 | // General Handler
317 | mfc0 k0, EPC
318 | mtc0 s0, SR
319 | addi k0, k0, 4
320 | mtc0 k0, EPC
321 | nop
322 | eret
323 | nop
324 | fill 100, 0xDD
325 | ExceptionHandlerBlockEnd:
326 | db 0xff
327 | align(8) // Align 64-Bit
328 | VALUEDOUBLEA:
329 | float64 0.0
--------------------------------------------------------------------------------
/N64/ExceptionTest/N64_Header.asm:
--------------------------------------------------------------------------------
1 | //============
2 | // N64 Header
3 | //============
4 | // PI_BSB_DOM1
5 | db $80 // Initial PI_BSB_DOM1_LAT_REG Value
6 | db $37 // Initial PI_BSB_DOM1_PGS_REG Value
7 | db $12 // Initial PI_BSB_DOM1_PWD_REG Value
8 | db $40 // Initial PI_BSB_DOM1_PGS_REG Value
9 |
10 | // CLOCK RATE
11 | dw $000F // Initial Clock Rate
12 |
13 | // VECTOR
14 | dw Start // Boot Address Offset
15 | dw $1444 // Release Offset
16 |
17 | // COMPLEMENT CHECK & CHECKSUM
18 | db "CRC1" // CRC1: COMPLEMENT CHECK
19 | db "CRC2" // CRC2: CHECKSUM
20 |
21 | dd 0 // UNUSED
22 |
23 | // PROGRAM TITLE (27 Byte ASCII String, Use Spaces For Unused Bytes)
24 | db "Exception Test "
25 | // "123456789012345678901234567"
26 |
27 | // DEVELOPER ID CODE
28 | db $00 // "N" = Nintendo
29 |
30 | // CARTRIDGE ID CODE
31 | db $00
32 |
33 | db 0 // UNUSED
34 |
35 | // COUNTRY CODE
36 | db $00 // "D" = Germany, "E" = USA, "J" = Japan, "P" = Europe, "U" = Australia
37 |
38 | db 0 // UNUSED
--------------------------------------------------------------------------------
/N64/ExceptionTest/make.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | set rom_name=ExceptionTest.N64
3 | REM Space seperated list of source files
4 | set source_files=ExceptionTest.asm
5 |
6 | if exist %rom_name% (
7 | del /q %rom_name%
8 | )
9 | bass -strict -create %1 -o %rom_name% %source_files%
10 | if exist %rom_name% (
11 | @chksum64 %rom_name%
12 | )
--------------------------------------------------------------------------------
/N64/GDB/GDB_Test.N64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/GDB/GDB_Test.N64
--------------------------------------------------------------------------------
/N64/GDB/GDB_Test.asm:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 | fill 1052672
4 |
5 | origin $00000000
6 | base $80000000
7 | // Useful for identifying where a value is in the output ROM file
8 | // Commented = Zeros in Gaps + Interrupt Zeros
9 | // Defined(1) = Filled Gaps + Interrupt Names
10 | // Defined(0) = Filled Gaps + Interrupt Names
11 | define DEBUG_SHOW_STATIC_VALUE(comment_out)
12 | include "../LIB/COLORS16.INC"
13 | include "../LIB/N64.INC"
14 | include "../LIB/N64_DRIVE.INC"
15 | include "../LIB/N64_GDB.INC"
16 | include "../LIB/N64_GFX.INC"
17 | include "../LIB/N64_INTERRUPT.INC"
18 | include "N64_HEADER.ASM"
19 | insert "../LIB/N64_BOOTCODE.BIN"
20 |
21 | Start:
22 | N64_INIT()
23 | ScreenNTSC(320, 240, BPP32, $A0100000) // Screen NTSC: 320x240, 32BPP, DRAM $A0100000
24 | nop // Marker NOP's
25 | nop // Marker NOP's
26 | interrupt_init()
27 | nop // Marker NOP's
28 | nop // Marker NOP's
29 | interrupt_tlb(gdb_serial_tlb_handler)
30 | nop // Marker NOP's
31 | nop // Marker NOP's
32 | gdb_communication_test()
33 | // Clear tlb handler so the debug handler will assign
34 | interrupt_tlb(0x00)
35 | nop // Marker NOP's
36 | nop // Marker NOP's
37 | interrupt_set_debug(gdb_interrupt_handler)
38 | nop // Marker NOP's
39 | nop // Marker NOP's
40 | interrupt_vblank($200,interrupt_vblank_handler)
41 | nop // Marker NOP's
42 | nop // Marker NOP's
43 |
44 | // Force GDB Sync
45 | gdb_sync()
46 |
47 | nop // Marker NOP's
48 | nop // Marker NOP's
49 | // Force TLB Interrupt
50 | lui v0,$7000
51 | lw v1,0000 (v0)
52 | nop // Marker NOP's
53 | nop // Marker NOP's
54 | Loop:
55 | j Loop
56 | nop // Delay Slot
57 |
58 | interrupt_default_handler:
59 | jr ra
60 | nop
61 | interrupt_vblank_handler:
62 | jr ra
63 | nop
64 |
65 | include "../LIB/N64_INTERRUPT.S"
66 | include "../LIB/N64_SYS.S"
67 | include "../LIB/N64_GDB.S"
68 | include "../LIB/N64_INTERRUPT_TEMPLATE.S"
--------------------------------------------------------------------------------
/N64/GDB/N64_Header.asm:
--------------------------------------------------------------------------------
1 | //============
2 | // N64 Header
3 | //============
4 | // PI_BSB_DOM1
5 | db $80 // Initial PI_BSB_DOM1_LAT_REG Value
6 | db $37 // Initial PI_BSB_DOM1_PGS_REG Value
7 | db $12 // Initial PI_BSB_DOM1_PWD_REG Value
8 | db $40 // Initial PI_BSB_DOM1_PGS_REG Value
9 |
10 | // CLOCK RATE
11 | dw $000F // Initial Clock Rate
12 |
13 | // VECTOR
14 | dw Start // Boot Address Offset
15 | dw $1444 // Release Offset
16 |
17 | // COMPLEMENT CHECK & CHECKSUM
18 | db "CRC1" // CRC1: COMPLEMENT CHECK
19 | db "CRC2" // CRC2: CHECKSUM
20 |
21 | dd 0 // UNUSED
22 |
23 | // PROGRAM TITLE (27 Byte ASCII String, Use Spaces For Unused Bytes)
24 | db "GDB Test "
25 | // "123456789012345678901234567"
26 |
27 | // DEVELOPER ID CODE
28 | db $00 // "N" = Nintendo
29 |
30 | // CARTRIDGE ID CODE
31 | db $00
32 |
33 | db 0 // UNUSED
34 |
35 | // COUNTRY CODE
36 | db $00 // "D" = Germany, "E" = USA, "J" = Japan, "P" = Europe, "U" = Australia
37 |
38 | db 0 // UNUSED
--------------------------------------------------------------------------------
/N64/GDB/make.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | set rom_name=GDB_Test.N64
3 | REM Space seperated list of source files
4 | set source_files=GDB_Test.asm
5 |
6 | if exist %rom_name% (
7 | del /q %rom_name%
8 | )
9 | bass -strict -create %1 -o %rom_name% %source_files%
10 | if exist %rom_name% (
11 | @chksum64 %rom_name%
12 | )
--------------------------------------------------------------------------------
/N64/IPL_FONT/IPL_FONT.N64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/IPL_FONT/IPL_FONT.N64
--------------------------------------------------------------------------------
/N64/IPL_FONT/IPL_FONT.asm:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 | fill 1052672
4 |
5 | define SHOW_EXCEPTIONS(1)
6 |
7 | origin $00000000
8 | base $80000000
9 | include "../LIB/N64.INC"
10 | include "../LIB/N64_GFX.INC"
11 | include "../LIB/COLORS16.INC"
12 | include "../LIB/N64_IPL_FONT.INC"
13 | include "../LIB/N64_EXCEPTION.INC"
14 | include "./N64_HEADER.ASM" // Include 64 Byte Header & Vector Table
15 | insert "../LIB/N64_BOOTCODE.BIN" // Include 4032 Byte Boot Code
16 | force_pc($80001000)
17 | Start:
18 | align(8)
19 | variable video_buffer($A0100000)
20 | N64_INIT()
21 | ScreenNTSC(640, 480, BPP16, video_buffer) // Screen NTSC: 640x480, 16BPP, DRAM Origin $A0100000
22 | nop
23 | nop
24 | exception_load_handler()
25 | //DMA(libn64_tlb_exception_handler, libn64_tlb_exception_handler_end, $80000000)
26 | nop
27 | nop
28 | variable font_good($8008'A000)
29 | font_init16(WHITE, SEA_GREEN, font_good)
30 |
31 | variable font_fail($8008'F000)
32 | font_init16(WHITE, RED, font_fail)
33 |
34 | variable font_white($8008'0000)
35 | font_init16(WHITE, 0x01, font_white)
36 |
37 | variable font_blue($8008'5000)
38 | font_init16(STEEL_BLUE, 0x01, font_blue)
39 |
40 | nop
41 | nop
42 | font_print_line16(font_white, video_buffer, 10, 10, testtext, 31)
43 | font_print_line16(font_blue, video_buffer, 100, 30, myname, 20)
44 |
45 | font_print_line16(font_good, video_buffer, 50, 50, pass, 4)
46 | font_print_line16(font_fail, video_buffer, 75, 70, fail, 4)
47 | Loop:
48 |
49 | j Loop
50 | nop // Delay Slot
51 |
52 | include "../LIB/N64_IPL_FONT.S"
53 | include "../LIB/N64_EXCEPTION.S"
54 |
55 | map 'A',0,26 // A-Z
56 | map 'a',0,26 // a-z
57 | map '0',26,10 // 0-9
58 | map '!',36,3 // ! " #
59 | //map '\'', 39, 1 // '
60 | map '*', 40, 6 // * + , - . /
61 | map ':', 46, 1 // :
62 | map '=', 47, 1 // =
63 | map '?',48, 2 // ? @
64 | map ' ',51, 1 // space
65 | testtext:
66 | db "the quick brown fox jumped over"
67 | myname:
68 | db "my name is fraser125"
69 | pass:
70 | db "pass"
71 | fail:
72 | db "fail"
73 | map 0, 0, 256
--------------------------------------------------------------------------------
/N64/IPL_FONT/IPL_FONT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/IPL_FONT/IPL_FONT.png
--------------------------------------------------------------------------------
/N64/IPL_FONT/N64_Header.asm:
--------------------------------------------------------------------------------
1 | //============
2 | // N64 Header
3 | //============
4 | // PI_BSB_DOM1
5 | db $80 // Initial PI_BSB_DOM1_LAT_REG Value
6 | db $37 // Initial PI_BSB_DOM1_PGS_REG Value
7 | db $12 // Initial PI_BSB_DOM1_PWD_REG Value
8 | db $40 // Initial PI_BSB_DOM1_PGS_REG Value
9 |
10 | // CLOCK RATE
11 | dw $000F // Initial Clock Rate
12 |
13 | // VECTOR
14 | dw Start // Boot Address Offset
15 | dw $1444 // Release Offset
16 |
17 | // COMPLEMENT CHECK & CHECKSUM
18 | db "CRC1" // CRC1: COMPLEMENT CHECK
19 | db "CRC2" // CRC2: CHECKSUM
20 |
21 | dd 0 // UNUSED
22 |
23 | // PROGRAM TITLE (27 Byte ASCII String, Use Spaces For Unused Bytes)
24 | db "IPL FONT DEMO "
25 | // "123456789012345678901234567"
26 |
27 | // DEVELOPER ID CODE
28 | db $00 // "N" = Nintendo
29 |
30 | // CARTRIDGE ID CODE
31 | db $00
32 |
33 | db 0 // UNUSED
34 |
35 | // COUNTRY CODE
36 | db $00 // "D" = Germany, "E" = USA, "J" = Japan, "P" = Europe, "U" = Australia
37 |
38 | db 0 // UNUSED
--------------------------------------------------------------------------------
/N64/IPL_FONT/make.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | set rom_name=IPL_FONT.N64
3 | REM Space seperated list of source files
4 | set source_files=IPL_FONT.asm
5 |
6 | if exist %rom_name% (
7 | del /q %rom_name%
8 | )
9 | bass -strict -create %1 -o %rom_name% %source_files%
10 | if exist %rom_name% (
11 | @chksum64 %rom_name%
12 | )
--------------------------------------------------------------------------------
/N64/InterruptTest/InterruptTest.N64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/InterruptTest/InterruptTest.N64
--------------------------------------------------------------------------------
/N64/InterruptTest/InterruptTest.asm:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 | fill 1052672
4 |
5 | origin $00000000
6 | base $80000000
7 | include "../LIB/N64.INC"
8 | include "../LIB/N64_GFX.INC"
9 | include "../LIB/N64_INTERRUPT.INC"
10 | include "./N64_HEADER.ASM" // Include 64 Byte Header & Vector Table
11 | insert "../LIB/N64_BOOTCODE.BIN" // Include 4032 Byte Boot Code
12 | force_pc($80001000)
13 | Start:
14 | align(8)
15 | //N64_INIT()
16 | interrupt_init()
17 | interrupt_set_default(ExceptionHandler) // Interrupts Active by Default
18 | ScreenNTSC(320, 240, BPP32, $A0100000) // Screen NTSC: 320x240, 32BPP, DRAM Origin $A0100000
19 | // Insert Initialization Code
20 | nop // Marker NOP's
21 | nop // Marker NOP's
22 |
23 | // TLB Exception - Handled by the Handler, no developer action
24 | la t0, 0x00000000
25 | lw t0, 0(t0)
26 | nop // Marker NOP's
27 | nop // Marker NOP's
28 |
29 | // BREAK Instruction
30 | interrupt_set_break(ExceptionHandler)
31 | break
32 | nop // Marker NOP's
33 | nop // Marker NOP's
34 |
35 | // SYSCALL Instruction
36 | interrupt_set_syscall(syscall_mars)
37 | //lui a0, r0
38 | //ori a0, 10
39 | //syscall
40 |
41 | // Timer Exception - Just before Inifinite loop
42 | interrupt_set_timer(ExceptionHandler)
43 | nop
44 | mfc0 t0, Count
45 | li t1, 0x1FFFFF // 2 Million
46 | add t0, t1, t0
47 | mtc0 t0, Compare
48 | interrupt_timer_enable()
49 | Loop:
50 | // Insert Looping Code Here
51 | j Loop
52 | nop // Delay Slot
53 |
54 | nop // Marker NOP's
55 | nop // Marker NOP's
56 |
57 | ExceptionHandler:
58 | // interrupt_register_* macros allow the use of any register
59 | // Otherwise only k0, k1, ra can be used.
60 | interrupt_register_save()
61 | //
62 | // Your Code Here
63 | //
64 | interrupt_register_restore()
65 |
66 | jr ra
67 | nop
68 |
69 | // Shared Function Libraries
70 | include "../LIB/N64_SYS.S"
71 | include "../LIB/N64_INTERRUPT.S"
72 | include "../LIB/N64_INTERRUPT_HANDLER.S"
73 | include "../LIB/N64_SYSCALL_MARS.S"
--------------------------------------------------------------------------------
/N64/InterruptTest/N64_Header.asm:
--------------------------------------------------------------------------------
1 | //============
2 | // N64 Header
3 | //============
4 | // PI_BSB_DOM1
5 | db $80 // Initial PI_BSB_DOM1_LAT_REG Value
6 | db $37 // Initial PI_BSB_DOM1_PGS_REG Value
7 | db $12 // Initial PI_BSB_DOM1_PWD_REG Value
8 | db $40 // Initial PI_BSB_DOM1_PGS_REG Value
9 |
10 | // CLOCK RATE
11 | dw $000F // Initial Clock Rate
12 |
13 | // VECTOR
14 | dw Start // Boot Address Offset
15 | dw $1444 // Release Offset
16 |
17 | // COMPLEMENT CHECK & CHECKSUM
18 | db "CRC1" // CRC1: COMPLEMENT CHECK
19 | db "CRC2" // CRC2: CHECKSUM
20 |
21 | dd 0 // UNUSED
22 |
23 | // PROGRAM TITLE (27 Byte ASCII String, Use Spaces For Unused Bytes)
24 | db "Interrupt Test "
25 | // "123456789012345678901234567"
26 |
27 | // DEVELOPER ID CODE
28 | db $00 // "N" = Nintendo
29 |
30 | // CARTRIDGE ID CODE
31 | db $00
32 |
33 | db 0 // UNUSED
34 |
35 | // COUNTRY CODE
36 | db $00 // "D" = Germany, "E" = USA, "J" = Japan, "P" = Europe, "U" = Australia
37 |
38 | db 0 // UNUSED
--------------------------------------------------------------------------------
/N64/InterruptTest/make.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | set rom_name=InterruptTest.N64
3 | REM Space seperated list of source files
4 | set source_files=InterruptTest.asm
5 |
6 | if exist %rom_name% (
7 | del /q %rom_name%
8 | )
9 | bass -strict -create %1 -o %rom_name% %source_files%
10 | if ERRORLEVEL 0 ECHO Compile Success!
11 | if exist %rom_name% (
12 | @chksum64 %rom_name%
13 | )
--------------------------------------------------------------------------------
/N64/LIB/COLORS16.INC:
--------------------------------------------------------------------------------
1 | // COLOR names used from
2 | // http://etetoolkit.org/docs/2.3/reference/reference_treeview.html
3 | // Red Colors
4 | constant INDIAN_RED($CAD6 )
5 | constant LIGHT_CORAL($F420)
6 | constant SALMON($FC1C)
7 | constant DARK_SALMON($EC9E)
8 | constant CRIMSON($D88E)
9 | constant RED($F800)
10 | constant FIRE_BRICK($B108)
11 | constant DARK_RED($8800)
12 | // Pink Colors
13 | constant PINK($FE32)
14 | constant LIGHT_PINK($FDB0)
15 | constant HOT_PINK($FB6C)
16 | constant DEEP_PINK($F8A4)
17 | constant MEDIUM_VIOLET_RED($C0A0)
18 | constant PALE_VIOLET_RED($DBA4)
19 | // Orange Colors
20 | constant LIGHT_SALMON($FD1E)
21 | constant CORAL($FBD4)
22 | constant TOMATO($FB10)
23 | constant ORANGE_RED($FA00)
24 | constant DARK_ORANGE($FC40)
25 | constant ORANGE($FD00)
26 | // YELLOW Colors
27 | constant GOLD($FA80)
28 | constant YELLOW($FFC0)
29 | constant LIGHT_YELLOW($FFF8)
30 | constant LEMON_CHIFFON($FFF2)
31 | constant LIGHT_GOLDENROD_YELLOW($FFF4)
32 | constant PAPAYA_WHIP($FF74)
33 | constant MOCCASIN($FF2C)
34 | constant PEACH_PUFF($FEEE)
35 | constant PALE_GOLDENROD($EF6A)
36 | constant KHAKI($F722)
37 | constant DARK_KHAKI($BD9A)
38 | // Purple Colors
39 | constant LAVENDER($E73E)
40 | constant THISTLE($DDF6)
41 | constant PLUM($DD36)
42 | constant VIOLET($EC3A)
43 | constant ORCHID($DBB4)
44 | constant FUCHSIA($F83E)
45 | constant MAGENTA($F83E)
46 | constant MEDIUM_ORCHID($BAB4)
47 | constant BLUE_VIOLET($8978)
48 | constant DARK_VIOLET($9034)
49 | constant DARK_ORCHID($99B2)
50 | constant DARK_MAGENTA($8822)
51 | constant PURPLE($8020)
52 | constant INDIGO($4820)
53 | constant SLATE_BLUE($6AF2)
54 | constant DARK_SLATE_BLUE($49E2)
55 | // Green Colors
56 | constant GREEN_YELLOW($AFCA)
57 | constant CHARTREUSE($7FC0)
58 | constant LAWN_GREEN($7FC0)
59 | constant LIME($07C0)
60 | constant LIME_GREEN($364C)
61 | constant PALE_GREEN($9FE6)
62 | constant LIGHT_GREEN($9764)
63 | constant MEDIUM_SPRING_GREEN($07E6)
64 | constant SPRING_GREEN($07DE)
65 | constant MEDIUM_SEA_GREEN($3D9C)
66 | constant SEA_GREEN($2C54)
67 | constant FOREST_GREEN($2448)
68 | constant GREEN($0400)
69 | constant DARK_GREEN($0300)
70 | constant YELLOW_GREEN($9E4C)
71 | constant OLIVE_DRAB($6C48)
72 | constant OLIVE($8400)
73 | constant DARK_OLIVE_GREEN($534A)
74 | constant MEDIUM_AQUAMARINE($666A)
75 | constant DARK_SEA_GREEN($8DE2)
76 | constant LIGHT_SEA_GREEN($25AA)
77 | constant DARK_CYAN($0462)
78 | constant TEAL($0420)
79 | // Blue/Cyan Colors
80 | constant AQUA($00C6)
81 | constant CYAN($00C6)
82 | constant LIGHT_CYAN($E0C6)
83 | constant PALE_TURQUOISE($C842)
84 | constant AQUAMARINE($7FF4)
85 | constant TURQUOISE($4734)
86 | constant MEDIUM_TURQUOISE($4EB2)
87 | constant DARK_TURQUOISE($0674)
88 | constant CADET_BLUE($5CE8)
89 | constant STEEL_BLUE($442C)
90 | constant LIGHT_STEEL_BLUE($B636)
91 | constant POWDER_BLUE($B738)
92 | constant LIGHT_BLUE($AEF8)
93 | constant SKY_BLUE($867A)
94 | constant LIGHT_SKY_BLUE($867E)
95 | constant DEEP_SKY_BLUE($05FE)
96 | constant DODGER_BLUE($1CBE)
97 | constant CORN_FLOWER_BLUE($64BA)
98 | constant MEDIUM_SLATE_BLUE($7B7A)
99 | constant ROYAL_BLUE($4378)
100 | constant MEDIUM_BLUE($0032)
101 | constant BLUE($0032)
102 | constant DARK_BLUE($0022)
103 | constant NAVY($0020)
104 | constant MIDNIGHT_BLUE($18DC)
105 | // Brown Colors
106 | constant CORNSILK($FFF6)
107 | constant BLANCHED_ALMOND($FF72)
108 | constant BISQUE($FF30)
109 | constant NAVAJO_WHITE($FEEA)
110 | constant WHEAT($F6EC)
111 | constant BURLY_WOOD($DDE0)
112 | constant TAN($D5A2)
113 | constant ROSY_BROWN($BC62)
114 | constant SANDY_BROWN($F518)
115 | constant GOLDENROD($DD08)
116 | constant DARK_GOLDENROD($BC02)
117 | constant PERU($CC0E)
118 | constant CHOCOLATE($D346)
119 | constant SADDLE_BROWN($8A04)
120 | constant SIENNA($A28A)
121 | constant BROWN($A14A)
122 | constant MAROON($8000)
123 |
124 | // White Colors
125 | constant WHITE($FFFE)
126 | constant SNOW($FFFE)
127 | constant HONEYDEW($F7FC)
128 | constant MINT_CREAM($F7FE)
129 | constant AZURE($F7FE)
130 | constant ALICE_BLUE($F7FE)
131 | constant GHOST_WHITE($FFFE)
132 | constant WHITE_SMOKE($F7BC) // Dark Grey???
133 | constant SEA_SHELL($FFBA)
134 | constant BEIGE($F7B6)
135 | constant OLD_LACE($FFB8)
136 | constant FLORAL_WHITE($FFFC)
137 | constant IVORY($FFFC)
138 | constant ANTIQUE_WHITE($FF74)
139 | constant LINEN($FFB8)
140 | constant LAVENDER_BLUSH($FFBC)
141 | constant MISTY_ROSE($FF38)
142 |
143 | // Gray Colors
144 | constant GAINSBORO($DEF6)
145 | constant LIGHT_GREY($D6B4)
146 | constant SILVER($C630)
147 | constant DARK_GREY($AD6A)
148 | constant GREY($8420)
149 | constant DIM_GREY($6B5A)
150 | constant LIGHT_SLATE_GREY($7466)
151 | constant SLATE_GREY($7424)
152 | constant BLACK($0001)
153 |
--------------------------------------------------------------------------------
/N64/LIB/COLORS32.INC:
--------------------------------------------------------------------------------
1 | // COLOR names used from
2 | // http://etetoolkit.org/docs/2.3/reference/reference_treeview.html
3 | // Red Colors
4 | constant INDIAN_RED($CD5C5C00 )
5 | constant LIGHT_CORAL($F0808000)
6 | constant SALMON($FA807200)
7 | constant DARK_SALMON($E9967A00)
8 | constant CRIMSON($DC143C00)
9 | constant RED($FF000000)
10 | constant FIRE_BRICK($B2222200)
11 | constant DARK_RED($8B000000)
12 | // Pink Colors
13 | constant PINK($FFC0CB00)
14 | constant LIGHT_PINK($FFB6C100)
15 | constant HOT_PINK($FF69B400)
16 | constant DEEP_PINK($FF149300)
17 | constant MEDIUM_VIOLET_RED($C7158500)
18 | constant PALE_VIOLET_RED($DB709300)
19 | // Orange Colors
20 | constant LIGHT_SALMON($FFA07A00)
21 | constant CORAL($FF7F5000)
22 | constant TOMATO($FF634700)
23 | constant ORANGE_RED($FF450000)
24 | constant DARK_ORANGE($FF8C0000)
25 | constant ORANGE($FFA50000)
26 | // YELLOW Colors
27 | constant GOLD($FF570000)
28 | constant YELLOW($FFFF0000)
29 | constant LIGHT_YELLOW($FFFFE000)
30 | constant LEMON_CHIFFON($FFFACD00)
31 | constant LIGHT_GOLDENROD_YELLOW($FAFAD200)
32 | constant PAPAYA_WHIP($FFEFD500)
33 | constant MOCCASIN($FFE4B500)
34 | constant PEACH_PUFF($FFDAB900)
35 | constant PALE_GOLDENROD($EEE8AA00)
36 | constant KHAKI($F0E68C00)
37 | constant DARK_KHAKI($BDB76B00)
38 | // Purple Colors
39 | constant LAVENDER($E6E6FA00)
40 | constant THISTLE($D8BFD800)
41 | constant PLUM($DDA0DD00)
42 | constant VIOLET($EE82EE00)
43 | constant ORCHID($DA70D600)
44 | constant FUCHSIA($FF00FF00)
45 | constant MAGENTA($FF00FF00)
46 | constant MEDIUM_ORCHID($BA55D300)
47 | constant BLUE_VIOLET($8A2BE200)
48 | constant DARK_VIOLET($9400D300)
49 | constant DARK_ORCHID($9932CC00)
50 | constant DARK_MAGENTA($8B008B00)
51 | constant PURPLE($80008000)
52 | constant INDIGO($4B008200)
53 | constant SLATE_BLUE($6A5ACD00)
54 | constant DARK_SLATE_BLUE($483D8B00)
55 | // Green Colors
56 | constant GREEN_YELLOW($ADFF2F00)
57 | constant CHARTREUSE($7FFF0000)
58 | constant LAWN_GREEN($7CFC0000)
59 | constant LIME($00FF0000)
60 | constant LIME_GREEN($32CD3200)
61 | constant PALE_GREEN($98FB9800)
62 | constant LIGHT_GREEN($90EE9000)
63 | constant MEDIUM_SPRING_GREEN($00FA9A00)
64 | constant SPRING_GREEN($00FF7F00)
65 | constant MEDIUM_SEA_GREEN($3CB37100)
66 | constant SEA_GREEN($2E8B5700)
67 | constant FOREST_GREEN($228B2200)
68 | constant GREEN($00800000)
69 | constant DARK_GREEN($00640000)
70 | constant YELLOW_GREEN($9ACD3200)
71 | constant OLIVE_DRAB($6B8E2300)
72 | constant OLIVE($80800000)
73 | constant DARK_OLIVE_GREEN($556B2F00)
74 | constant MEDIUM_AQUAMARINE($66CDAA00)
75 | constant DARK_SEA_GREEN($8FBC8F00)
76 | constant LIGHT_SEA_GREEN($20B2AA00)
77 | constant DARK_CYAN($008B8B00)
78 | constant TEAL($00808000)
79 | // Blue/Cyan Colors
80 | constant AQUA($00ffff00)
81 | constant CYAN($00ffff00)
82 | constant LIGHT_CYAN($e0ffff00)
83 | constant PALE_TURQUOISE($afeeee00)
84 | constant AQUAMARINE($7FFFD400)
85 | constant TURQUOISE($40E0D000)
86 | constant MEDIUM_TURQUOISE($48D1CC00)
87 | constant DARK_TURQUOISE($00CED100)
88 | constant CADET_BLUE($5F9EA000)
89 | constant STEEL_BLUE($4682B400)
90 | constant LIGHT_STEEL_BLUE($B0C4DE00)
91 | constant POWDER_BLUE($B0E0E600)
92 | constant LIGHT_BLUE($ADD8E600)
93 | constant SKY_BLUE($87CEEB00)
94 | constant LIGHT_SKY_BLUE($87CEFA00)
95 | constant DEEP_SKY_BLUE($00BFFF00)
96 | constant DODGER_BLUE($1E90FF00)
97 | constant CORN_FLOWER_BLUE($6495ED00)
98 | constant MEDIUM_SLATE_BLUE($7B68EE00)
99 | constant ROYAL_BLUE($4169E100)
100 | constant MEDIUM_BLUE($0000CD00)
101 | constant BLUE($0000CD00)
102 | constant DARK_BLUE($00008B00)
103 | constant NAVY($00008000)
104 | constant MIDNIGHT_BLUE($19197000)
105 | // Brown Colors
106 | constant CORNSILK($FFF8DC00)
107 | constant BLANCHED_ALMOND($FFEBCD00)
108 | constant BISQUE($FFE4C400)
109 | constant NAVAJO_WHITE($FFDEAD00)
110 | constant WHEAT($F5DEB300)
111 | constant BURLY_WOOD($DEB88700)
112 | constant TAN($D2B48C00)
113 | constant ROSY_BROWN($BC8F8F00)
114 | constant SANDY_BROWN($F4A46000)
115 | constant GOLDENROD($DAA52000)
116 | constant DARK_GOLDENROD($B8860B00)
117 | constant PERU($CD853F00)
118 | constant CHOCOLATE($D2691E00)
119 | constant SADDLE_BROWN($8B451300)
120 | constant SIENNA($A0522D00)
121 | constant BROWN($A52A2A00)
122 | constant MAROON($80000000)
123 |
124 | // White Colors
125 | constant WHITE($FFFFFF00)
126 | constant SNOW($FFFAFA00)
127 | constant HONEYDEW($F0FFF000)
128 | constant MINT_CREAM($F5FFFA00)
129 | constant AZURE($F0FFFF00)
130 | constant ALICE_BLUE($F0F8FF00)
131 | constant GHOST_WHITE($F8F8FF00)
132 | constant WHITE_SMOKE($F5F5F500)
133 | constant SEA_SHELL($FFF5EE00)
134 | constant BEIGE($F5F5DC00)
135 | constant OLD_LACE($FDF5E600)
136 | constant FLORAL_WHITE($FFFAF000)
137 | constant IVORY($FFFFF000)
138 | constant ANTIQUE_WHITE($FAEBD700)
139 | constant LINEN($FAF0E600)
140 | constant LAVENDER_BLUSH($FFF0F500)
141 | constant MISTY_ROSE($FFE4E100)
142 |
143 | // Gray Colors
144 | constant GAINSBORO($DCDCDC00)
145 | constant LIGHT_GREY($D3D3D300)
146 | constant SILVER($C0C0C000)
147 | constant DARK_GREY($A9A9A900)
148 | constant GREY($80808000)
149 | constant DIM_GREY($69696900)
150 | constant LIGHT_SLATE_GREY($77889900)
151 | constant SLATE_GREY($70809000)
152 | constant BLACK($00000000)
153 |
--------------------------------------------------------------------------------
/N64/LIB/N64.INC:
--------------------------------------------------------------------------------
1 | //=============
2 | // N64 Include
3 | //=============
4 | // N64 MIPS 4300 CPU Registers
5 | constant r0(0)
6 | constant r1(1)
7 | constant r2(2)
8 | constant r3(3)
9 | constant r4(4)
10 | constant r5(5)
11 | constant r6(6)
12 | constant r7(7)
13 | constant r8(8)
14 | constant r9(9)
15 | constant r10(10)
16 | constant r11(11)
17 | constant r12(12)
18 | constant r13(13)
19 | constant r14(14)
20 | constant r15(15)
21 | constant r16(16)
22 | constant r17(17)
23 | constant r18(18)
24 | constant r19(19)
25 | constant r20(20)
26 | constant r21(21)
27 | constant r22(22)
28 | constant r23(23)
29 | constant r24(24)
30 | constant r25(25)
31 | constant r26(26)
32 | constant r27(27)
33 | constant r28(28)
34 | constant r29(29)
35 | constant r30(30)
36 | constant r31(31)
37 |
38 | constant at(1)
39 | constant v0(2)
40 | constant v1(3)
41 | constant a0(4)
42 | constant a1(5)
43 | constant a2(6)
44 | constant a3(7)
45 | constant t0(8)
46 | constant t1(9)
47 | constant t2(10)
48 | constant t3(11)
49 | constant t4(12)
50 | constant t5(13)
51 | constant t6(14)
52 | constant t7(15)
53 | constant s0(16)
54 | constant s1(17)
55 | constant s2(18)
56 | constant s3(19)
57 | constant s4(20)
58 | constant s5(21)
59 | constant s6(22)
60 | constant s7(23)
61 | constant t8(24)
62 | constant t9(25)
63 | constant k0(26)
64 | constant k1(27)
65 | constant gp(28)
66 | constant sp(29)
67 | constant s8(30)
68 | constant ra(31)
69 |
70 | // N64 MIPS 4300 CP1 Floating Point Unit (FPU) Registers (COP1)
71 | constant f0(0)
72 | constant f1(1)
73 | constant f2(2)
74 | constant f3(3)
75 | constant f4(4)
76 | constant f5(5)
77 | constant f6(6)
78 | constant f7(7)
79 | constant f8(8)
80 | constant f9(9)
81 | constant f10(10)
82 | constant f11(11)
83 | constant f12(12)
84 | constant f13(13)
85 | constant f14(14)
86 | constant f15(15)
87 | constant f16(16)
88 | constant f17(17)
89 | constant f18(18)
90 | constant f19(19)
91 | constant f20(20)
92 | constant f21(21)
93 | constant f22(22)
94 | constant f23(23)
95 | constant f24(24)
96 | constant f25(25)
97 | constant f26(26)
98 | constant f27(27)
99 | constant f28(28)
100 | constant f29(29)
101 | constant f30(30)
102 | constant f31(31)
103 |
104 | // COP0 registers:
105 | constant Index($00)
106 | constant Random($01)
107 | constant EntryLo0($02)
108 | constant EntryLo1($03)
109 | constant Context($04)
110 | constant PageMask($05)
111 | constant Wired($06)
112 | //constant *RESERVED*($07)
113 | constant BadVAddr($08)
114 | constant Count($09)
115 | constant EntryHi($0A)
116 | constant Compare($0B)
117 | constant Status($0C)
118 | constant SR($0C)
119 | constant Cause($0D)
120 | constant EPC($0E)
121 | constant PRevID($0F)
122 | constant Config($10)
123 | constant LLAddr($11)
124 | constant WatchLo($12)
125 | constant WatchHi($13)
126 | constant XContext($14)
127 | //constant *RESERVED*($15)
128 | //constant *RESERVED*($16)
129 | //constant *RESERVED*($17)
130 | //constant *RESERVED*($18)
131 | //constant *RESERVED*($19)
132 | constant PErr($1A)
133 | constant CacheErr($1B)
134 | constant TagLo($1C)
135 | constant TagHi($1D)
136 | constant ErrorEPC($1E)
137 | //constant *RESERVED*($1F)
138 |
139 | // Memory Map
140 | constant RDRAM($A000) // $00000000..$003FFFFF RDRAM Memory 4MB ($00000000..$007FFFFF 8MB With Expansion Pak)
141 |
142 | constant RDRAM_BASE($A3F0) // $03F00000..$03F00027 RDRAM Base Register
143 | constant RDRAM_DEVICE_TYPE($00) // $03F00000..$03F00003 RDRAM: Device Type Register
144 | constant RDRAM_DEVICE_ID($04) // $03F00004..$03F00007 RDRAM: Device ID Register
145 | constant RDRAM_DELAY($08) // $03F00008..$03F0000B RDRAM: Delay Register
146 | constant RDRAM_MODE($0C) // $03F0000C..$03F0000F RDRAM: Mode Register
147 | constant RDRAM_REF_INTERVAL($10) // $03F00010..$03F00013 RDRAM: Ref Interval Register
148 | constant RDRAM_REF_ROW($14) // $03F00014..$03F00017 RDRAM: Ref Row Register
149 | constant RDRAM_RAS_INTERVAL($18) // $03F00018..$03F0001B RDRAM: Ras Interval Register
150 | constant RDRAM_MIN_INTERVAL($1C) // $03F0001C..$03F0001F RDRAM: Minimum Interval Register
151 | constant RDRAM_ADDR_SELECT($20) // $03F00020..$03F00023 RDRAM: Address Select Register
152 | constant RDRAM_DEVICE_MANUF($24) // $03F00024..$03F00027 RDRAM: Device Manufacturer Register
153 |
154 | constant SP_MEM_BASE($A400) // $04000000..$04000FFF SP MEM Base Register
155 | constant SP_DMEM($0000) // $04000000..$04000FFF SP: RSP DMEM (4096 Bytes)
156 | constant SP_IMEM($1000) // $04001000..$04001FFF SP: RSP IMEM (4096 Bytes)
157 |
158 | constant SP_BASE($A404) // $04040000..$0404001F SP Base Register
159 | constant SP_MEM_ADDR($00) // $04040000..$04040003 SP: Master, SP Memory Address Register
160 | constant SP_DRAM_ADDR($04) // $04040004..$04040007 SP: Slave, SP DRAM DMA Address Register
161 | constant SP_RD_LEN($08) // $04040008..$0404000B SP: Read DMA Length Register
162 | constant SP_WR_LEN($0C) // $0404000C..$0404000F SP: Write DMA Length Register
163 | constant SP_STATUS($10) // $04040010..$04040013 SP: Status Register
164 | constant SP_DMA_FULL($14) // $04040014..$04040017 SP: DMA Full Register
165 | constant SP_DMA_BUSY($18) // $04040018..$0404001B SP: DMA Busy Register
166 | constant SP_SEMAPHORE($1C) // $0404001C..$0404001F SP: Semaphore Register
167 |
168 | constant SP_PC_BASE($A408) // $04080000..$04080007 SP PC Base Register
169 | constant SP_PC($00) // $04080000..$04080003 SP: PC Register
170 | constant SP_IBIST_REG($04) // $04080004..$04080007 SP: IMEM BIST Register
171 |
172 | constant DPC_BASE($A410) // $04100000..$0410001F DP Command (DPC) Base Register
173 | constant DPC_START($00) // $04100000..$04100003 DPC: CMD DMA Start Register
174 | constant DPC_END($04) // $04100004..$04100007 DPC: CMD DMA End Register
175 | constant DPC_CURRENT($08) // $04100008..$0410000B DPC: CMD DMA Current Register
176 | constant DPC_STATUS($0C) // $0410000C..$0410000F DPC: CMD Status Register
177 | constant DPC_CLOCK($10) // $04100010..$04100013 DPC: Clock Counter Register
178 | constant DPC_BUFBUSY($14) // $04100014..$04100017 DPC: Buffer Busy Counter Register
179 | constant DPC_PIPEBUSY($18) // $04100018..$0410001B DPC: Pipe Busy Counter Register
180 | constant DPC_TMEM($1C) // $0410001C..$0410001F DPC: TMEM Load Counter Register
181 |
182 | constant DPS_BASE($A420) // $04200000..$0420000F DP Span (DPS) Base Register
183 | constant DPS_TBIST($00) // $04200000..$04200003 DPS: Tmem Bist Register
184 | constant DPS_TEST_MODE($04) // $04200004..$04200007 DPS: Span Test Mode Register
185 | constant DPS_BUFTEST_ADDR($08) // $04200008..$0420000B DPS: Span Buffer Test Address Register
186 | constant DPS_BUFTEST_DATA($0C) // $0420000C..$0420000F DPS: Span Buffer Test Data Register
187 |
188 | constant MI_BASE($A430) // $04300000..$0430000F MIPS Interface (MI) Base Register
189 | constant MI_INIT_MODE($00) // $04300000..$04300003 MI: Init Mode Register
190 | constant MI_VERSION($04) // $04300004..$04300007 MI: Version Register
191 | constant MI_INTR($08) // $04300008..$0430000B MI: Interrupt Register
192 | constant MI_INTR_MASK($0C) // $0430000C..$0430000F MI: Interrupt Mask Register
193 | constant mi_mask_clear_all($0555) // Value to Clear/Reset all Interrupts
194 |
195 | constant VI_BASE($A440) // $04400000..$04400037 Video Interface (VI) Base Register
196 | constant VI_STATUS($00) // $04400000..$04400003 VI: Status/Control Register
197 | constant VI_ORIGIN($04) // $04400004..$04400007 VI: Origin Register
198 | constant VI_WIDTH($08) // $04400008..$0440000B VI: Width Register
199 | constant VI_V_INTR($0C) // $0440000C..$0440000F VI: Vertical Interrupt Register
200 | constant VI_V_CURRENT_LINE($10) // $04400010..$04400013 VI: Current Vertical Line Register
201 | constant VI_TIMING($14) // $04400014..$04400017 VI: Video Timing Register
202 | constant VI_V_SYNC($18) // $04400018..$0440001B VI: Vertical Sync Register
203 | constant VI_H_SYNC($1C) // $0440001C..$0440001F VI: Horizontal Sync Register
204 | constant VI_H_SYNC_LEAP($20) // $04400020..$04400023 VI: Horizontal Sync Leap Register
205 | constant VI_H_VIDEO($24) // $04400024..$04400027 VI: Horizontal Video Register
206 | constant VI_V_VIDEO($28) // $04400028..$0440002B VI: Vertical Video Register
207 | constant VI_V_BURST($2C) // $0440002C..$0440002F VI: Vertical Burst Register
208 | constant VI_X_SCALE($30) // $04400030..$04400033 VI: X-Scale Register
209 | constant VI_Y_SCALE($34) // $04400034..$04400037 VI: Y-Scale Register
210 |
211 | constant AI_BASE($A450) // $04500000..$04500017 Audio Interface (AI) Base Register
212 | constant AI_DRAM_ADDR($00) // $04500000..$04500003 AI: DRAM Address Register
213 | constant AI_LEN($04) // $04500004..$04500007 AI: Length Register
214 | constant AI_CONTROL($08) // $04500008..$0450000B AI: Control Register
215 | constant AI_STATUS($0C) // $0450000C..$0450000F AI: Status Register
216 | constant AI_DACRATE($10) // $04500010..$04500013 AI: DAC Sample Period Register
217 | constant AI_BITRATE($14) // $04500014..$04500017 AI: Bit Rate Register
218 |
219 | constant PI_BASE($A460) // $04600000..$04600033 Peripheral Interface (PI) Base Register
220 | constant PI_DRAM_ADDR($00) // $04600000..$04600003 PI: DRAM Address Register
221 | constant PI_CART_ADDR($04) // $04600004..$04600007 PI: Pbus (Cartridge) Address Register
222 | constant PI_RD_LEN($08) // $04600008..$0460000B PI: Read Length Register
223 | constant PI_WR_LEN($0C) // $0460000C..$0460000F PI: Write length register
224 | constant PI_STATUS($10) // $04600010..$04600013 PI: Status Register
225 | constant PI_BSD_DOM1_LAT($14) // $04600014..$04600017 PI: Domain 1 Latency Register
226 | constant PI_BSD_DOM1_PWD($18) // $04600018..$0460001B PI: Domain 1 Pulse Width Register
227 | constant PI_BSD_DOM1_PGS($1C) // $0460001C..$0460001F PI: Domain 1 Page Size Register
228 | constant PI_BSD_DOM1_RLS($20) // $04600020..$04600023 PI: Domain 1 Release Register
229 | constant PI_BSD_DOM2_LAT($24) // $04600024..$04600027 PI: Domain 2 Latency Register
230 | constant PI_BSD_DOM2_PWD($28) // $04600028..$0460002B PI: Domain 2 Pulse Width Register
231 | constant PI_BSD_DOM2_PGS($2C) // $0460002C..$0460002F PI: Domain 2 Page Size Register
232 | constant PI_BSD_DOM2_RLS($30) // $04600030..$04600033 PI: Domain 2 Release Register
233 |
234 | constant RI_BASE($A470) // $04700000..$0470001F RDRAM Interface (RI) Base Register
235 | constant RI_MODE($00) // $04700000..$04700003 RI: Mode Register
236 | constant RI_CONFIG($04) // $04700004..$04700007 RI: Config Register
237 | constant RI_CURRENT_LOAD($08) // $04700008..$0470000B RI: Current Load Register
238 | constant RI_SELECT($0C) // $0470000C..$0470000F RI: Select Register
239 | constant RI_REFRESH($10) // $04700010..$04700013 RI: Refresh Register
240 | constant RI_LATENCY($14) // $04700014..$04700017 RI: Latency Register
241 | constant RI_RERROR($18) // $04700018..$0470001B RI: Read Error Register
242 | constant RI_WERROR($1C) // $0470001C..$0470001F RI: Write Error Register
243 |
244 | constant SI_BASE($A480) // $04800000..$0480001B Serial Interface (SI) Base Register
245 | constant SI_DRAM_ADDR($00) // $04800000..$04800003 SI: DRAM Address Register
246 | constant SI_PIF_ADDR_RD64B($04) // $04800004..$04800007 SI: Address Read 64B Register
247 | //*RESERVED*($08) // $04800008..$0480000B SI: Reserved Register
248 | //*RESERVED*($0C) // $0480000C..$0480000F SI: Reserved Register
249 | constant SI_PIF_ADDR_WR64B($10) // $04800010..$04800013 SI: Address Write 64B Register
250 | //*RESERVED*($14) // $04800014..$04800017 SI: Reserved Register
251 | constant SI_STATUS($18) // $04800018..$0480001B SI: Status Register
252 |
253 | constant CART_DOM2_ADDR1($A500) // $05000000..$0507FFFF Cartridge Domain 2(Address 1) SRAM
254 | constant CART_DOM1_ADDR1($A600) // $06000000..$07FFFFFF Cartridge Domain 1(Address 1) 64DD
255 | constant CART_DOM2_ADDR2($A800) // $08000000..$0FFFFFFF Cartridge Domain 2(Address 2) SRAM
256 | constant CART_DOM1_ADDR2($B000) // $10000000..$18000803 Cartridge Domain 1(Address 2) ROM
257 |
258 | constant PIF_BASE($BFC0) // $1FC00000..$1FC007BF PIF Base Register
259 | constant PIF_ROM($000) // $1FC00000..$1FC007BF PIF: Boot ROM
260 | constant PIF_RAM($7C0) // $1FC007C0..$1FC007FF PIF: RAM (JoyChannel)
261 | constant PIF_HWORD($7C4) // $1FC007C4..$1FC007C5 PIF: HWORD
262 | constant PIF_XBYTE($7C6) // $1FC007C6 PIF: Analog X Byte
263 | constant PIF_YBYTE($7C7) // $1FC007C7 PIF: Analog Y Byte
264 |
265 | constant CART_DOM1_ADDR3($BFD0) // $1FD00000..$7FFFFFFF Cartridge Domain 1 (Address 3)
266 |
267 | constant EXT_SYS_AD($8000) // $80000000..$FFFFFFFF External SysAD Device
268 |
269 | constant VI_NTSC_CLOCK(48681812) // NTSC: Hz = 48.681812 MHz
270 | constant VI_PAL_CLOCK(49656530) // PAL: Hz = 49.656530 MHz
271 | constant VI_MPAL_CLOCK(48628316) // MPAL: Hz = 48.628316 MHz
272 |
273 | constant NTSC_Interlaced_HighRes_32bitPixel(0b0000'0001'0000'0001'0000'0001'0000'0011)
274 | constant NTSC_Interlaced_HighRes_16bitPixel(0b0000'0001'0000'0001'0000'0001'0000'0011)
275 | constant NTSC_Interlaced_LowRes_32bitPixel(0b0000'0001'0000'0001'0000'0001'0000'0011)
276 | constant NTSC_Interlaced_LowRes_16bitPixel(0b0000'0001'0000'0001'0000'0001'0000'0011)
277 |
278 | constant NTSC_NonInterlaced_HighRes_32bitPixel(0b0000'0001'0000'0001'0000'0001'0000'0011)
279 | constant NTSC_NonInterlaced_HighRes_16bitPixel(0b0000'0001'0000'0001'0000'0001'0000'0011)
280 | constant NTSC_NonInterlaced_LowRes_32bitPixel(0b0000'0001'0000'0001'0000'0001'0000'0011)
281 | constant NTSC_NonInterlaced_LowRes_16bitPixel(0b0000'0001'0000'0001'0000'0001'0000'0011)
282 |
283 | macro force_pc(size) {
284 | if (pc() > {size}) {
285 | error "Program Counter is greater than specified size"
286 | }
287 | while (pc() < {size}) {
288 | db 0
289 | }
290 | }
291 |
292 | macro fixed_gap(base, gap) {
293 | if (pc() > {base} + {gap}) {
294 | error "Gap is greater than specified size."
295 | }
296 | while (pc() < {base} + {gap}) {
297 | if {defined DEBUG_SHOW_STATIC_VALUE} {
298 | db 0xAB
299 | } else {
300 | db 0x0
301 | }
302 | }
303 | }
304 |
305 | // static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "TEST")
306 | macro static_value(conditional, default, alternative) {
307 | if {defined {conditional}} {
308 | {alternative}
309 | } else {
310 | {default}
311 | }
312 | }
313 |
314 | macro align(size) { // Align Byte Amount
315 | while (pc() % {size}) {
316 | db 0
317 | }
318 | }
319 |
320 | macro N64_INIT() { // Initialise N64 (Stop N64 From Crashing 5 Seconds After Boot)
321 | lui a0,PIF_BASE // A0 = PIF Base Register ($BFC00000)
322 | lli t0,8
323 | sw t0,PIF_RAM+$3C(a0)
324 | // Stack is configured by Cartridge BootCode
325 | //addiu sp, r0, $FFF // 4K of Stack Space
326 | }
327 |
328 | macro STACK_PUSH(register) {
329 | addiu sp, sp, -4
330 | sw {register}, 0(sp)
331 | }
332 |
333 | macro STACK_POP(register) {
334 | lw {register}, 0(sp)
335 | addiu sp, sp, 4
336 | }
337 | macro STACK_ARGS_ENTRY() {
338 | }
339 |
340 | macro STACK_ENTRY() {
341 | addiu sp, sp, -56
342 | sw ra, 0(sp)
343 | sw a0, 4(sp)
344 | sw a1, 8(sp)
345 | sw a2, 12(sp)
346 | sw a3, 16(sp)
347 | sw s0, 20(sp)
348 | sw s1, 24(sp)
349 | sw s2, 28(sp)
350 | sw s3, 32(sp)
351 | sw s4, 36(sp)
352 | sw s5, 40(sp)
353 | sw s6, 44(sp)
354 | sw s7, 48(sp)
355 | sw s8, 52(sp)
356 | }
357 |
358 | macro STACK_RETURN() {
359 | sw ra, 0(sp)
360 | sw a0, 4(sp)
361 | sw a1, 8(sp)
362 | sw a2, 12(sp)
363 | sw a3, 16(sp)
364 | sw s0, 20(sp)
365 | sw s1, 24(sp)
366 | sw s2, 28(sp)
367 | sw s3, 32(sp)
368 | sw s4, 36(sp)
369 | sw s5, 40(sp)
370 | sw s6, 44(sp)
371 | sw s7, 48(sp)
372 | sw s8, 52(sp)
373 | addiu sp, sp, 56
374 | }
375 |
376 | macro DMA(start, end, dest) { // DMA Data Copy Cart->DRAM: Start Cart Address, End Cart Address, Destination DRAM Address
377 | lui a0,PI_BASE // A0 = PI Base Register ($A4600000)
378 | -
379 | lw t0,PI_STATUS(a0) // T0 = Word From PI Status Register ($A4600010)
380 | andi t0,3 // AND PI Status With 3
381 | bnez t0,- // IF TRUE DMA Is Busy
382 | nop // Delay Slot
383 |
384 | la t0,{dest}&$7FFFFF // T0 = Aligned DRAM Physical RAM Offset ($00000000..$007FFFFF 8MB)
385 | sw t0,PI_DRAM_ADDR(a0) // Store RAM Offset To PI DRAM Address Register ($A4600000)
386 | la t0,$10000000|({start}&$3FFFFFF) // T0 = Aligned Cart Physical ROM Offset ($10000000..$13FFFFFF 64MB)
387 | sw t0,PI_CART_ADDR(a0) // Store ROM Offset To PI Cart Address Register ($A4600004)
388 | la t0,({end}-{start})-1 // T0 = Length Of DMA Transfer In Bytes - 1
389 | sw t0,PI_WR_LEN(a0) // Store DMA Length To PI Write Length Register ($A460000C)
390 | }
--------------------------------------------------------------------------------
/N64/LIB/N64_BOOTCODE.BIN:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/LIB/N64_BOOTCODE.BIN
--------------------------------------------------------------------------------
/N64/LIB/N64_DRIVE.INC:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/LIB/N64_DRIVE.INC
--------------------------------------------------------------------------------
/N64/LIB/N64_DRIVE.S:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/LIB/N64_DRIVE.S
--------------------------------------------------------------------------------
/N64/LIB/N64_EVER.INC:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/LIB/N64_EVER.INC
--------------------------------------------------------------------------------
/N64/LIB/N64_EVER.S:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/LIB/N64_EVER.S
--------------------------------------------------------------------------------
/N64/LIB/N64_EXCEPTION.INC:
--------------------------------------------------------------------------------
1 | macro exception_load_handler() {
2 | jal exception_handler_init
3 | nop
4 | }
--------------------------------------------------------------------------------
/N64/LIB/N64_EXCEPTION.S:
--------------------------------------------------------------------------------
1 | align(8)
2 | //B0001500
3 | //10110000000000000001010100000000
4 | //00010000000000000001010100000000
5 | // Additional code outside the Exception Handler
6 | //
7 | exception_handler_init:
8 | lui t0, PI_BASE
9 | // DMA sees DRAM starting @ 0x00000000
10 | // VR4300 sees it at 0x80000000
11 | la t1, 0x0 // libn64_tlb_exception_handler - 0x80000000
12 | sw t1, 0(t0)
13 | lui t2, 0xE000
14 | la t1, libn64_tlb_exception_handler - 0x80000000
15 | //xor t1, t1, t2
16 | sw t1, 4(t0)
17 | addiu t1, r0, $300 - 1
18 | sw t1, 0xC(t0)
19 | jr ra
20 | nop
21 | nop
22 | nop
23 | exception_handler_show:
24 | lui k1, VI_BASE
25 | lw k1, VI_ORIGIN(k1)
26 | addiu k0, $FFFF -2
27 | _loopFrameBuffer:
28 | sw r0, 0(k1)
29 | addi k1,k1,4
30 | bne k0,r0,_loopFrameBuffer
31 | addi k0, k0, -1
32 | li k0,0x3FFFFFF
33 | delay:
34 | bnel k0, r0, delay
35 | addi k0, k0, -1
36 | jr ra
37 | nop
38 |
39 |
40 | exception_handler_cart:
41 | variable old_base(base())
42 | db "exct"
43 | align(128)
44 | libn64_tlb_exception_handler:
45 | base $80000000
46 | dmfc0 k1, Context
47 | nop
48 | lw k0, 0(k1)
49 | lw k1, 8(k1)
50 | mtc0 k0, EntryLo0
51 | mtc0 k1, EntryLo1
52 | nop
53 | tlbwr
54 | if {defined SHOW_EXCEPTIONS} {
55 | jal exception_handler_show
56 | nop
57 | }
58 | eret
59 | exception_default_step1:
60 |
61 | mtc0 ra, $30
62 | la ra, N64_SCALER
63 | sw k0, k0(ra)
64 | mfc0 k0, Cause // Get Cause
65 | sw k1, k1(ra)
66 | mfc0 k1, $30
67 | sw at, at(ra)
68 | sw k1, k1(ra)
69 | mfc0 k1, Status
70 | and k0, k0, k1
71 | j exception_default_step2
72 | nop
73 | align(128)
74 | // N64 can but does not run in User/Supervisor mode
75 | // libn64_xtlb_exception_handler:
76 | dmfc0 k1, XContext
77 | nop
78 | lw k0, 0(k1)
79 | lw k1, 8(k1)
80 | mtc0 k0, EntryLo0
81 | mtc0 k1, EntryLo1
82 | nop
83 | tlbwr
84 | if {defined SHOW_EXCEPTIONS} {
85 | jal exception_handler_show
86 | nop
87 | }
88 | eret
89 | exception_default_step2:
90 | // TODO: Code Here
91 | j exception_default_step3
92 | nop
93 | align(128)
94 | // Not Applicable
95 | //libn64_cache_exception_handler:
96 | exception_default_step3:
97 | // TODO: Code Here
98 | j exception_default_step4
99 | nop
100 | align(128)
101 | libn64_default_exception_handler:
102 | j exception_default_step1
103 | nop
104 | exception_default_step4:
105 | // TODO: Code Here
106 |
107 | if {defined SHOW_EXCEPTIONS} {
108 | jal exception_handler_show
109 | nop
110 | }
111 | eret
112 | // Get this less than 0x300 in size
113 | libn64_tlb_exception_handler_end:
114 | base old_base
115 |
116 | align(8)
117 | db "Exeption registers"
118 | libn64_exception_register_store:
119 | // Scaler Registers
120 | N64_SCALER:
121 | dd 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
122 | dd 0, 0, 0, 0, 0, 0, 0, 0
123 | dd 0, 0, 0, 0, 0, 0, 0, 0
124 | dd 0, 0, 0, 0, 0, 0, 0, 0
125 | db "End of Scaler"
126 | N64_COP0:
127 | dd 0, 0, 0, 0, 0, 0, 0, 0
128 | db "End of Ctrl"
129 | N64_COP1: // Floating Point
130 | dd 0, 0, 0, 0, 0, 0, 0, 0
131 | dd 0, 0, 0, 0, 0, 0, 0, 0
132 | dd 0, 0, 0, 0, 0, 0, 0, 0
133 | dd 0, 0, 0, 0, 0, 0, 0, 0
134 | db "End of Float"
--------------------------------------------------------------------------------
/N64/LIB/N64_GDB.INC:
--------------------------------------------------------------------------------
1 | macro gdb_sync() {
2 | break
3 | }
4 | // has to be called after the Interrupt handler has been put in place
5 | // but before there are any handlers assigned.
6 | // This way it will fall through the handlers and return,
7 | // Also possible to determine if hander was executed.
8 | macro gdb_communication_test() {
9 | jal gdb_serial_test
10 | nop
11 | }
--------------------------------------------------------------------------------
/N64/LIB/N64_GDB.S:
--------------------------------------------------------------------------------
1 | // COP0 Config - EP Register
2 | // COP0 Status FR bit to enable 64-bit Floating point Registers?
3 | // Might be 16 x 64 bit or 32 x 32 bit
4 | // COP0 Status DS Self Diagnostic Status Area
5 | // COP0 Status DS is 8 bits
6 | // ITS - Instruction Trace Support
7 | // BEV - TLB & General Exception Vector
8 | // TS - TLB shutd down
9 | // SR - Soft Reset Exception
10 | // CH - Condition bit of the CP0
11 | // CE - Cache Check bit use ECC register (Not used always 0)
12 | // DE - Cache Parity Error (Not used always 1)
13 | // Packet Size: 448 + Overhead = 512?
14 | // General Purpose Registers: 128
15 | // Miscellaneous Registers: 64
16 | // Floating Point Registers: 256
17 | align(4)
18 | gdb_receive_buffer:
19 | fixed_gap(gdb_receive_buffer, 0x200)
20 |
21 | gdb_transmit_buffer:
22 | fixed_gap(gdb_transmit_buffer, 0x200)
23 |
24 | // 0xFFFF'FFFF = Error
25 | // 0x0 = Untested
26 | // 0x1 = Exists
27 | gdb_serial_status:
28 | dw 0x0
29 |
30 | // Code
31 | align(8)
32 | gdb_interrupt_handler:
33 | la t0, gdb_serial_status
34 | lw t0, 0(t0)
35 | nop
36 | blez t0, _gdb_display_HUD
37 | nop
38 | bgtz t0, _gdb_serial_rxtx
39 | nop
40 | _gdb_serial_rxtx:
41 | _gdb_display_HUD:
42 | _gdb_exit:
43 | jr ra
44 | nop
45 | gdb_serial_test:
46 | // Save current TLB handler
47 | la t0, tlb_handler_ptr
48 | lw t1, 0(t0) // Save old pointer to t1
49 | // Insert our own Handler
50 | la t2, gdb_serial_tlb_handler
51 | sw t2, 0(t0)
52 | // Run our Test and Initialization
53 | //
54 |
55 | // Restore the original Handler
56 | la t0, tlb_handler_ptr
57 | sw t1, 0(t0)
58 | jr ra
59 | nop
60 | gdb_serial_tlb_handler:
61 | la k0, gdb_serial_status
62 | addi k1, r0, -1
63 | sw k1, 0(k0)
64 | jr ra
65 | nop
--------------------------------------------------------------------------------
/N64/LIB/N64_INTERRUPT.INC:
--------------------------------------------------------------------------------
1 | macro interrupt_init() {
2 | jal _interrupt_init
3 | nop
4 | }
5 |
6 | macro interrupt_set_tlb(functionPointer) {
7 | la t0, tlb_handler_ptr
8 | la t1, {functionPointer}
9 | sw t1, 0(t0)
10 | }
11 |
12 | macro interrupt_set_xtlb(functionPointer) {
13 | if ({functionPointer} > 0)
14 | error "XTLB only used in 64 bit mode"
15 | }
16 |
17 | //macro interrupt_set_cache(functionPointer) {
18 | // la t0, cache_handler_ptr
19 | // la t1, {functionPointer}
20 | // sw t1, 0(t0)
21 | //}
22 |
23 | macro interrupt_set_default(functionPointer) {
24 | la t0, default_handler_ptr
25 | la t1, {functionPointer}
26 | sw t1, 0(t0)
27 | }
28 |
29 | macro interrupt_set_vblank(line, functionPointer) {
30 | lui t0,VI_BASE
31 | lli t1,{line}
32 | sw t1,VI_V_INTR(t0)
33 |
34 | la t0, vblank_handler_ptr
35 | la t1, {functionPointer}
36 | sw t1, 0(t0)
37 | jal interrupt_vi_enable
38 | nop
39 | }
40 |
41 | macro interrupt_set_syscall(functionPointer) {
42 | la t0, exc8_Sys_handler_ptr
43 | la t1, {functionPointer}
44 | sw t1, 0(t0)
45 | }
46 |
47 | macro interrupt_set_break(functionPointer) {
48 | la t0, exc9_Bp_handler_ptr
49 | la t1, {functionPointer}
50 | sw t1, 0(t0)
51 | }
52 |
53 | macro interrupt_set_watch(functionPointer) {
54 | la t0, exc23_WATCH_handler_ptr
55 | la t1, {functionPointer}
56 | sw t1, 0(t0)
57 | }
58 |
59 | macro interrupt_watch(address, read, write) {
60 | la t0, {address}
61 | li t1, {read}
62 | li t2, {write}
63 | sll t1, t1, 1
64 | and t0, t0, t1
65 | and t0, t0, t2
66 | mtc0 t0, WatchLo
67 | }
68 |
69 | // Sets all "blank" 0x00 handlers to the Debug Handler
70 | macro interrupt_set_debug(functionPointer) {
71 | la a0, {functionPointer}
72 | jal interrupt_set_debug
73 | nop
74 | }
75 |
76 | macro interrupt_set_timer(functionPointer) {
77 | la t0, int7_handler_ptr
78 | la t1, {functionPointer}
79 | sw t1, 0(t0)
80 | }
81 |
82 | macro interrupt_set_audio(functionPointer) {
83 | la t0, _interrupt_AI
84 | la t1, {functionPointer}
85 | sw t1, 0(t0)
86 | }
87 |
88 | macro interrupt_register_scalar_load() {
89 | la k1, interrupt_saved_registers_std
90 | // Save Registers
91 | lw at, at*4(k1)
92 | lw v0, v0*4(k1)
93 | lw v1, v1*4(k1)
94 |
95 | lw a0, a0*4(k1)
96 | lw a1, a1*4(k1)
97 | lw a2, a2*4(k1)
98 | lw a3, a3*4(k1)
99 |
100 | lw s0, s0*4(k1)
101 | lw s1, s1*4(k1)
102 | lw s2, s2*4(k1)
103 | lw s3, s3*4(k1)
104 | lw s4, s4*4(k1)
105 | lw s5, s5*4(k1)
106 | lw s6, s6*4(k1)
107 | lw s7, s7*4(k1)
108 | lw s8, s8*4(k1)
109 |
110 | lw gp, gp*4(k1)
111 | lw sp, sp*4(k1)
112 |
113 | lw t0, t0*4(k1)
114 | lw t1, t1*4(k1)
115 | lw t2, t2*4(k1)
116 | lw t3, t3*4(k1)
117 | lw t4, t4*4(k1)
118 | lw t5, t5*4(k1)
119 | lw t6, t6*4(k1)
120 | lw t7, t7*4(k1)
121 | lw t8, t8*4(k1)
122 | lw t9, t9*4(k1)
123 | }
124 |
125 | macro interrupt_register_scalar_store() {
126 | la k1, interrupt_saved_registers_std
127 | // Save Registers
128 | sw at, at*4(k1)
129 | sw v0, v0*4(k1)
130 | sw v1, v1*4(k1)
131 |
132 | sw a0, a0*4(k1)
133 | sw a1, a1*4(k1)
134 | sw a2, a2*4(k1)
135 | sw a3, a3*4(k1)
136 |
137 | sw s0, s0*4(k1)
138 | sw s1, s1*4(k1)
139 | sw s2, s2*4(k1)
140 | sw s3, s3*4(k1)
141 | sw s4, s4*4(k1)
142 | sw s5, s5*4(k1)
143 | sw s6, s6*4(k1)
144 | sw s7, s7*4(k1)
145 | sw s8, s8*4(k1)
146 |
147 | sw gp, gp*4(k1)
148 | sw sp, sp*4(k1)
149 |
150 | sw t0, t0*4(k1)
151 | sw t1, t1*4(k1)
152 | sw t2, t2*4(k1)
153 | sw t3, t3*4(k1)
154 | sw t4, t4*4(k1)
155 | sw t5, t5*4(k1)
156 | sw t6, t6*4(k1)
157 | sw t7, t7*4(k1)
158 | sw t8, t8*4(k1)
159 | sw t9, t9*4(k1)
160 | }
161 |
162 | macro interrupt_register_float_load() {
163 | la k1, interrupt_saved_registers_float
164 | ldc1 f0, f0*8(k1)
165 | ldc1 f1, f1*8(k1)
166 | ldc1 f2, f2*8(k1)
167 | ldc1 f3, f3*8(k1)
168 | ldc1 f4, f4*8(k1)
169 | ldc1 f5, f5*8(k1)
170 | ldc1 f6, f6*8(k1)
171 | ldc1 f7, f7*8(k1)
172 | ldc1 f8, f8*8(k1)
173 | ldc1 f9, f9*8(k1)
174 | ldc1 f10, f10*8(k1)
175 | ldc1 f11, f11*8(k1)
176 | ldc1 f12, f12*8(k1)
177 | ldc1 f13, f13*8(k1)
178 | ldc1 f14, f14*8(k1)
179 | ldc1 f15, f15*8(k1)
180 | ldc1 f16, f16*8(k1)
181 | ldc1 f17, f17*8(k1)
182 | ldc1 f18, f18*8(k1)
183 | ldc1 f19, f19*8(k1)
184 | ldc1 f20, f20*8(k1)
185 | ldc1 f21, f21*8(k1)
186 | ldc1 f22, f22*8(k1)
187 | ldc1 f23, f23*8(k1)
188 | ldc1 f24, f24*8(k1)
189 | ldc1 f25, f25*8(k1)
190 | ldc1 f26, f26*8(k1)
191 | ldc1 f27, f27*8(k1)
192 | ldc1 f28, f28*8(k1)
193 | ldc1 f29, f29*8(k1)
194 | ldc1 f30, f30*8(k1)
195 | ldc1 f31, f31*8(k1)
196 | }
197 | macro interrupt_register_float_store() {
198 | la k1, interrupt_saved_registers_float
199 | swc1 f0, f0*8(k1)
200 | swc1 f1, f1*8(k1)
201 | swc1 f2, f2*8(k1)
202 | swc1 f3, f3*8(k1)
203 | swc1 f4, f4*8(k1)
204 | swc1 f5, f5*8(k1)
205 | swc1 f6, f6*8(k1)
206 | swc1 f7, f7*8(k1)
207 | swc1 f8, f8*8(k1)
208 | swc1 f9, f9*8(k1)
209 | swc1 f10, f10*8(k1)
210 | swc1 f11, f11*8(k1)
211 | swc1 f12, f12*8(k1)
212 | swc1 f13, f13*8(k1)
213 | swc1 f14, f14*8(k1)
214 | swc1 f15, f15*8(k1)
215 | swc1 f16, f16*8(k1)
216 | swc1 f17, f17*8(k1)
217 | swc1 f18, f18*8(k1)
218 | swc1 f19, f19*8(k1)
219 | swc1 f20, f20*8(k1)
220 | swc1 f21, f21*8(k1)
221 | swc1 f22, f22*8(k1)
222 | swc1 f23, f23*8(k1)
223 | swc1 f24, f24*8(k1)
224 | swc1 f25, f25*8(k1)
225 | swc1 f26, f26*8(k1)
226 | swc1 f27, f27*8(k1)
227 | swc1 f28, f28*8(k1)
228 | swc1 f29, f29*8(k1)
229 | swc1 f30, f30*8(k1)
230 | swc1 f31, f31*8(k1)
231 | }
232 |
233 | macro interrupt_register_COP0_load() {
234 | la k1, interrupt_saved_COP0_misc
235 | lw t0, Index*4(k1)
236 | lw t1, Random*4(k1)
237 | lw t2, EntryLo0*4(k1)
238 | lw t3, EntryLo1*4(k1)
239 | lw t4, Context*4(k1)
240 | lw t5, PageMask*4(k1)
241 | lw t6, Wired*4(k1)
242 | lw t7, BadVAddr*4(k1)
243 | lw t8, Count*4(k1)
244 | lw t9, EntryHi*4(k1)
245 | mtc0 t0, Index
246 | mtc0 t1, Random
247 | mtc0 t2, EntryLo0
248 | mtc0 t3, EntryLo1
249 | mtc0 t4, Context
250 | mtc0 t5, PageMask
251 | mtc0 t6, Wired
252 | mtc0 t7, BadVAddr
253 | mtc0 t8, Count
254 | mtc0 t9, EntryHi
255 |
256 | lw t0, Compare*4(k1)
257 | lw t1, Status*4(k1)
258 | lw t2, SR*4(k1)
259 | lw t3, Cause*4(k1)
260 | lw t4, EPC*4(k1)
261 | lw t5, PRevID*4(k1)
262 | lw t6, Config*4(k1)
263 | lw t7, LLAddr*4(k1)
264 | lw t8, WatchLo*4(k1)
265 | lw t9, WatchHi*4(k1)
266 | mtc0 t0, Compare
267 | mtc0 t1, Status
268 | mtc0 t2, SR
269 | mtc0 t3, Cause
270 | mtc0 t4, EPC
271 | mtc0 t5, PRevID
272 | mtc0 t6, Config
273 | mtc0 t7, LLAddr
274 | mtc0 t8, WatchLo
275 | mtc0 t9, WatchHi
276 |
277 | // PErr is used to store the 'ra' register
278 | lw t0, XContext*4(k1)
279 | //lw t1, PErr*4(k1)
280 | lw t2, CacheErr*4(k1)
281 | lw t3, TagLo*4(k1)
282 | lw t4, TagHi*4(k1)
283 | lw t5, ErrorEPC*4(k1)
284 | mtc0 t0, XContext
285 | //mfc0 t1, PErr
286 | mtc0 t2, CacheErr
287 | mtc0 t3, TagLo
288 | mtc0 t4, TagHi
289 | mtc0 t5, ErrorEPC
290 | }
291 |
292 | macro interrupt_register_COP0_store() {
293 | la k1, interrupt_saved_COP0_misc
294 | mfc0 t0, Index
295 | mfc0 t1, Random
296 | mfc0 t2, EntryLo0
297 | mfc0 t3, EntryLo1
298 | mfc0 t4, Context
299 | mfc0 t5, PageMask
300 | mfc0 t6, Wired
301 | mfc0 t7, BadVAddr
302 | mfc0 t8, Count
303 | mfc0 t9, EntryHi
304 | sw t0, Index*4(k1)
305 | sw t1, Random*4(k1)
306 | sw t2, EntryLo0*4(k1)
307 | sw t3, EntryLo1*4(k1)
308 | sw t4, Context*4(k1)
309 | sw t5, PageMask*4(k1)
310 | sw t6, Wired*4(k1)
311 | sw t7, BadVAddr*4(k1)
312 | sw t8, Count*4(k1)
313 | sw t9, EntryHi*4(k1)
314 |
315 | mfc0 t0, Compare
316 | mfc0 t1, Status
317 | mfc0 t2, SR
318 | mfc0 t3, Cause
319 | mfc0 t4, EPC
320 | mfc0 t5, PRevID
321 | mfc0 t6, Config
322 | mfc0 t7, LLAddr
323 | mfc0 t8, WatchLo
324 | mfc0 t9, WatchHi
325 | sw t0, Compare*4(k1)
326 | sw t1, Status*4(k1)
327 | sw t2, SR*4(k1)
328 | sw t3, Cause*4(k1)
329 | sw t4, EPC*4(k1)
330 | sw t5, PRevID*4(k1)
331 | sw t6, Config*4(k1)
332 | sw t7, LLAddr*4(k1)
333 | sw t8, WatchLo*4(k1)
334 | sw t9, WatchHi*4(k1)
335 |
336 | // PErr is used to store the 'ra' register
337 | mfc0 t0, XContext
338 | //mfc0 t1, PErr
339 | mfc0 t2, CacheErr
340 | mfc0 t3, TagLo
341 | mfc0 t4, TagHi
342 | mfc0 t5, ErrorEPC
343 | sw t0, XContext*4(k1)
344 | //sw t1, PErr*4(k1)
345 | sw t2, CacheErr*4(k1)
346 | sw t3, TagLo*4(k1)
347 | sw t4, TagHi*4(k1)
348 | sw t5, ErrorEPC*4(k1)
349 | }
350 |
351 | macro interrupt_register_misc_store() {
352 | la k1, interrupt_saved_registers_misc
353 | mfhi t0
354 | mflo t1
355 | sw t0, 0(k1)
356 | sw t1, 4(k1)
357 | }
358 |
359 | macro interrupt_register_misc_load() {
360 | la k1, interrupt_saved_registers_misc
361 | lw t0, 0(k1)
362 | lw t1, 4(k1)
363 | mthi t0
364 | mtlo t1
365 | }
366 |
367 | macro interrupt_register_store() {
368 | // 'ra' saved in the Handler code itself.
369 | // sw ra, ra*4(k1)
370 | // sw k0, *4(k1) Already wiped and re-used
371 | // sw k1, *4(k1) Already wiped and re-used
372 |
373 | // Store scaler registers first because they are used
374 | // for the misc and COP0 store macros
375 | interrupt_register_scalar_store()
376 | interrupt_register_misc_store()
377 | interrupt_register_COP0_store()
378 | interrupt_register_float_store()
379 | }
380 |
381 | macro interrupt_register_load() {
382 | // misc & COP0 load's use the t0-t9 registers
383 | interrupt_register_misc_load()
384 | interrupt_register_COP0_load()
385 | // Load t0-t9 after misc & COP0
386 | interrupt_register_scalar_load()
387 | interrupt_register_float_load()
388 | }
389 |
390 | macro interrupt_activate() {
391 | jal interrupt_activate
392 | nop
393 | }
394 |
395 | macro interrupt_deactivate() {
396 | jal interrupt_deactivate
397 | nop
398 | }
399 |
400 | macro interrupt_timer_enable() {
401 | mfc0 t0, Status
402 | nop
403 | ori t0, 0x8000
404 | mtc0 t0, Status
405 | }
406 |
407 | macro interrupt_timer_disable() {
408 | mfc0 t0, Status
409 | ori t0, 1
410 | mtc0 t0, Status
411 | }
412 |
413 | macro interrupt_timer_reset() {
414 | jal interrupt_timer_reset
415 | nop
416 | }
417 |
418 | macro interrupt_sp_enable() {
419 | jal interrupt_sp_enable
420 | nop
421 | jal _interrupt_mi_manage
422 | nop
423 | }
424 |
425 | macro interrupt_sp_reset() {
426 | jal interrupt_sp_reset
427 | nop
428 | }
429 |
430 | macro interrupt_sp_disable() {
431 | jal interrupt_sp_disable
432 | nop
433 | jal _interrupt_mi_manage
434 | nop
435 | }
436 |
437 |
438 | macro interrupt_si_enable() {
439 | jal interrupt_si_enable
440 | nop
441 | jal _interrupt_mi_manage
442 | nop
443 | }
444 |
445 | macro interrupt_si_reset() {
446 | jal interrupt_si_reset
447 | nop
448 | }
449 |
450 | macro interrupt_si_disable() {
451 | jal interrupt_si_disable
452 | nop
453 | jal _interrupt_mi_manage
454 | nop
455 | }
456 |
457 |
458 | macro interrupt_ai_enable() {
459 | jal interrupt_ai_enable
460 | nop
461 | jal _interrupt_mi_manage
462 | nop
463 | }
464 |
465 | macro interrupt_ai_reset() {
466 | jal interrupt_ai_reset
467 | nop
468 | }
469 |
470 | macro interrupt_ai_disable() {
471 | jal interrupt_ai_disable
472 | nop
473 | jal _interrupt_mi_manage
474 | nop
475 | }
476 |
477 |
478 | macro interrupt_vi_enable() {
479 | jal interrupt_vi_enable
480 | nop
481 | jal _interrupt_mi_manage
482 | nop
483 | }
484 |
485 | macro interrupt_vi_reset() {
486 | jal interrupt_vi_reset
487 | nop
488 | }
489 |
490 | macro interrupt_vi_disable() {
491 | jal interrupt_vi_disable
492 | nop
493 | jal _interrupt_mi_manage
494 | nop
495 | }
496 |
497 |
498 | macro interrupt_pi_enable() {
499 | jal interrupt_pi_enable
500 | nop
501 | jal _interrupt_mi_manage
502 | nop
503 | }
504 |
505 | macro interrupt_pi_reset() {
506 | jal interrupt_pi_reset
507 | nop
508 | }
509 |
510 | macro interrupt_pi_disable() {
511 | jal interrupt_pi_disable
512 | nop
513 | jal _interrupt_mi_manage
514 | nop
515 | }
516 |
517 |
518 | macro interrupt_dp_enable() {
519 | jal interrupt_dp_enable
520 | nop
521 | jal _interrupt_mi_manage
522 | nop
523 | }
524 |
525 | macro interrupt_dp_reset() {
526 | jal interrupt_dp_reset
527 | nop
528 | }
529 |
530 | macro interrupt_dp_disable() {
531 | jal interrupt_dp_disable
532 | nop
533 | jal _interrupt_mi_manage
534 | nop
535 | }
536 |
--------------------------------------------------------------------------------
/N64/LIB/N64_INTERRUPT.S:
--------------------------------------------------------------------------------
1 | constant exception_destination($80000000)
2 | align(8)
3 | _interrupt_init:
4 | la t0, _inthandler_overlay
5 | li t1, exception_destination
6 | li t2, _interrupt_handler_length
7 | addi t2, t2, 15
8 | andi t2, t2, $FFF0
9 | _interrupt_init_loop:
10 | lw t4, 0(t0)
11 | lw t5, 4(t0)
12 | lw t6, 8(t0)
13 | lw t7, 12(t0)
14 | sw t4, 0(t1)
15 | sw t5, 4(t1)
16 | sw t6, 8(t1)
17 | sw t7, 12(t1)
18 | addi t2, t2, -16
19 | addi t0, t0, 16
20 | bnel t2, r0, _interrupt_init_loop
21 | addi t1, t1, 16
22 |
23 | // V4300i Interrupt_Init
24 | mfc0 t0, Status
25 | ori t0, 0x401
26 | mtc0 t0, Status
27 | // RCP Interrupt_Init
28 | la a0, (MI_BASE << 16) | MI_INTR_MASK
29 | li a1, mi_mask_clear_all
30 | sw a1, 0(a0)
31 |
32 | jr ra
33 | nop
34 | nop
35 |
36 | align(8)
37 | interrupt_set_debug:
38 | // Set all empty Jump Table Entries to the debug handler.
39 | li t0, 52
40 | la t1,InterruptHandlers
41 | add t3, t1, t0
42 | _interrupt_set_debug_int_loop:
43 | lw t2, 0(t1)
44 | nop
45 | nop
46 | beql t2, r0, _interrupt_set_debug_int_next
47 | add t2, r0, a0
48 | sw t2, 0(t1)
49 | _interrupt_set_debug_int_next:
50 | bnel t1, t3, _interrupt_set_debug_int_loop
51 | add t1, t1, 4
52 |
53 | _interrupt_set_debug_exceptions:
54 | li t0, 64
55 | la t1,ExceptionHandlers
56 | add t3, t1, t0
57 |
58 |
59 | jr ra
60 | nop
61 |
62 | interrupt_activate:
63 | mfc0 t0, Status
64 | ori t0, 1
65 | mtc0 t0, Status
66 | jr ra
67 | nop
68 |
69 | interrupt_deactivate:
70 | mfc0 t0, Status
71 | la t1, ~1
72 | and t0, t1
73 | mtc0 t0, Status
74 | jr ra
75 | nop
76 |
77 | interrupt_timer_reset:
78 | jr ra
79 | nop
80 |
81 | _interrupt_mi_manage:
82 | // Disable all Interrupts otherwise we might "trigger" one/all.
83 | mfc0 t0, Status
84 | addi t1, r0, -2
85 | and t1, t1, t0
86 | mtc0 t1, Status
87 | // Get MI Interrupts
88 | lui t1, MI_BASE
89 | lw t1, MI_INTR_MASK(t1)
90 | // Set the MI master interrupt if any of the other Interrupts are set.
91 | beq t1, r0, _exit
92 | ori t2, t0, 0x8000
93 | // Restore Global Interrupt State
94 | mtc0 t2, Status
95 | _exit:
96 | jr ra
97 | nop
98 |
99 | interrupt_sp_enable:
100 | la a0, (MI_BASE << 16) | MI_INTR_MASK
101 | lw a1, 0(a0)
102 | nop
103 | ori a1, a1, mi_mask_set_sp
104 | sw a1, 0(a0)
105 | jr ra
106 | nop
107 | interrupt_sp_reset:
108 | la a0, (SP_BASE << 16) | SP_STATUS
109 | lw a1, 0(a0)
110 | nop
111 | ori a1, a1, sp_clear_interrupt
112 | sw a1, 0(a0)
113 | jr ra
114 | nop
115 | interrupt_sp_disable:
116 | la a0, (MI_BASE << 16) | MI_INTR_MASK
117 | lw a1, 0(a0)
118 | nop
119 | ori a1, a1, mi_mask_clear_sp
120 | sw a1, 0(a0)
121 | jr ra
122 | nop
123 |
124 | interrupt_si_enable:
125 | la a0, (MI_BASE << 16) | MI_INTR_MASK
126 | lw a1, 0(a0)
127 | nop
128 | ori a1, a1, mi_mask_set_si
129 | sw a1, 0(a0)
130 | jr ra
131 | nop
132 | interrupt_si_reset:
133 | la a0, (SI_BASE << 16) | SI_STATUS
134 | lw a1, 0(a0)
135 | nop
136 | ori a1, a1, si_clear_interrupt
137 | sw a1, 0(a0)
138 | jr ra
139 | nop
140 | interrupt_si_disable:
141 | la a0, (MI_BASE << 16) | MI_INTR_MASK
142 | lw a1, 0(a0)
143 | nop
144 | ori a1, a1, mi_mask_clear_si
145 | sw a1, 0(a0)
146 | jr ra
147 | nop
148 |
149 | interrupt_ai_enable:
150 | la a0, (MI_BASE << 16) | MI_INTR_MASK
151 | lw a1, 0(a0)
152 | nop
153 | ori a1, a1, mi_mask_set_ai
154 | sw a1, 0(a0)
155 | jr ra
156 | nop
157 | interrupt_ai_reset:
158 | la a0, (AI_BASE << 16) | AI_STATUS
159 | lw a1, 0(a0)
160 | nop
161 | ori a1, a1, ai_clear_interrupt
162 | sw a1, 0(a0)
163 | jr ra
164 | nop
165 | interrupt_ai_disable:
166 | la a0, (MI_BASE << 16) | MI_INTR_MASK
167 | lw a1, 0(a0)
168 | nop
169 | ori a1, a1, mi_mask_clear_ai
170 | sw a1, 0(a0)
171 | jr ra
172 | nop
173 |
174 | interrupt_vi_enable:
175 | beq a0, r0, _interrupt_vi_enable2 // Trashes t0 if true
176 | la t0, (VI_BASE << 16) | VI_V_INTR
177 | sw a0, 0(t0)
178 | _interrupt_vi_enable2:
179 | la a0, (MI_BASE << 16) | MI_INTR_MASK
180 | lw a1, 0(a0)
181 | nop
182 | ori a1, a1, mi_mask_set_vi
183 | sw a1, 0(a0)
184 | jr ra
185 | nop
186 | interrupt_vi_reset:
187 | la a0, (VI_BASE << 16) | VI_V_CURRENT_LINE
188 | lw a1, 0(a0)
189 | nop
190 | nop
191 | sw a1, 0(a0) // Write same value back to reset Interrupt
192 | jr ra
193 | nop
194 | interrupt_vi_disable:
195 | la a0, (MI_BASE << 16) | MI_INTR_MASK
196 | lw a1, 0(a0)
197 | nop
198 | ori a1, a1, mi_mask_clear_vi
199 | sw a1, 0(a0)
200 | jr ra
201 | nop
202 |
203 | interrupt_pi_enable:
204 | la a0, (MI_BASE << 16) | MI_INTR_MASK
205 | lw a1, 0(a0)
206 | nop
207 | ori a1, a1, mi_mask_set_pi
208 | sw a1, 0(a0)
209 | jr ra
210 | nop
211 | interrupt_pi_reset:
212 | la a0, (PI_BASE << 16) | PI_STATUS
213 | lw a1, 0(a0)
214 | nop
215 | ori a1, a1, pi_clear_interrupt
216 | sw a1, 0(a0)
217 | jr ra
218 | nop
219 | interrupt_pi_disable:
220 | la a0, (MI_BASE << 16) | MI_INTR_MASK
221 | lw a1, 0(a0)
222 | nop
223 | ori a1, a1, mi_mask_clear_pi
224 | sw a1, 0(a0)
225 | jr ra
226 | nop
227 |
228 | interrupt_dp_enable:
229 | la a0, (MI_BASE << 16) | MI_INTR_MASK
230 | lw a1, 0(a0)
231 | nop
232 | ori a1, a1, mi_mask_set_dp
233 | sw a1, 0(a0)
234 | jr ra
235 | nop
236 | interrupt_dp_reset:
237 | la a0, (MI_BASE << 16) | MI_INIT_MODE
238 | lw a1, 0(a0)
239 | nop
240 | ori a1, a1, dp_clear_interrupt
241 | sw a1, 0(a0)
242 | jr ra
243 | nop
244 | interrupt_dp_disable:
245 | la a0, (MI_BASE << 16) | MI_INTR_MASK
246 | lw a1, 0(a0)
247 | nop
248 | ori a1, a1, mi_mask_clear_dp
249 | sw a1, 0(a0)
250 | jr ra
251 | nop
252 | align(8)
253 | interrupt_saved_registers_std:
254 | // Standard 32 Registers r0 - ra
255 | dw $0, $0, $0, $0, $0, $0, $0, $0
256 | dw $0, $0, $0, $0, $0, $0, $0, $0
257 | dw $0, $0, $0, $0, $0, $0, $0, $0
258 | dw $0, $0, $0, $0, $0, $0, $0, $0
259 | // Additional Hi, Lo,
260 | interrupt_saved_registers_misc:
261 | dw $0, $0, $0, $0
262 | interrupt_saved_COP0_misc:
263 | dw $0, $0, $0, $0, $0, $0, $0, $0
264 | dw $0, $0, $0, $0, $0, $0, $0, $0
265 | dw $0, $0, $0, $0, $0, $0, $0, $0
266 | dw $0, $0, $0, $0, $0, $0, $0, $0
267 | // Floating Point Registers
268 | interrupt_saved_registers_float:
269 | dl $0, $0, $0, $0, $0, $0, $0, $0
270 | dl $0, $0, $0, $0, $0, $0, $0, $0
271 | dl $0, $0, $0, $0, $0, $0, $0, $0
272 | dl $0, $0, $0, $0, $0, $0, $0, $0
--------------------------------------------------------------------------------
/N64/LIB/N64_INTERRUPT_HANDLER.S:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 | include "../LIB/N64.INC"
4 |
5 | // Every Handler can safely assume that k0, k1, ra are usable registers
6 |
7 | define DEBUG_SHOW_STATIC_VALUE(yes)
8 | align(8)
9 | _inthandler_overlay:
10 | variable pc_save(pc())
11 |
12 | base $80000000
13 | _tlb_handler:
14 | // Merge from 32 & 64 bit versions in See MIPS Run
15 | mfc0 k0, Status
16 | ori k1, r0, 0xE2
17 | and k0, k0, k1
18 | beql k0, r0, _tlb_32
19 | dmfc0 k1, XContext
20 | _tlb_32:
21 | dmfc0 k1, Context
22 | // MAME doesnt support Context & XContext
23 | beq k1, r0, _interrupt_return_handler
24 | nop
25 | lw k0, 0(k1)
26 | lw k1, 8(k1)
27 | mtc0 k0, EntryLo0
28 | mtc0 k1, EntryLo1
29 | nop
30 | tlbwr
31 | _tlb_end:
32 | eret
33 |
34 | fixed_gap(_tlb_handler, 0x40)
35 | ExceptionHandlers:
36 | // Interrupt
37 | exc0_Int_handler_ptr:
38 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "EInt")
39 |
40 | // TLB Change Exception
41 | exc1_Mod_handler_ptr:
42 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "EMod")
43 |
44 | // TLB Refill Exception (Load/Fetch)
45 | exc2_TLBL_handler_ptr:
46 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "TLBL")
47 |
48 | // TLB Refill Exception (Store)
49 | exc3_TLBS_handler_ptr:
50 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "TLBS")
51 |
52 | // Address Error (Load/Fetch)
53 | exc4_AdEL_handler_ptr:
54 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "AdEL")
55 |
56 | // Address Error (Store)
57 | exc5_AdES_handler_ptr:
58 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "AdES")
59 |
60 | // Bus Error (Fetch)
61 | exc6_IBE_handler_ptr:
62 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "IBE ")
63 |
64 | // Bus Error (Load/Store)
65 | exc7_DBE_handler_ptr:
66 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "DBE ")
67 |
68 | // System Exception Call
69 | exc8_Sys_handler_ptr:
70 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "Sys ")
71 |
72 | // Breakpoint Exception
73 | exc9_Bp_handler_ptr:
74 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "Bp ")
75 |
76 | // Reserved Instruction Exception
77 | exc10_RI_handler_ptr:
78 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "RI ")
79 |
80 | // Coprocessor Unusable
81 | exc11_CpU_handler_ptr:
82 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "CpU ")
83 |
84 | // Operation Overflow
85 | exc12_Ov_handler_ptr:
86 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "Ov ")
87 |
88 | // Trap Exception
89 | exc13_Tr_handler_ptr:
90 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "Tr ")
91 |
92 | // Reserved
93 | exc14_reserved_handler_ptr:
94 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "Rsrv")
95 |
96 | // Floating Point Exception
97 | exc15_FPE_handler_ptr:
98 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "FPE ")
99 |
100 |
101 | fixed_gap(_tlb_handler, 0x80)
102 | _xtlb_handler:
103 | j _tlb_handler
104 | nop
105 | default_handler_ptr:
106 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "DEF ")
107 | fixed_gap(ExceptionHandlers, 0x5C)
108 | // Watch
109 | exc23_WATCH_handler_ptr:
110 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "WATH")
111 |
112 | fixed_gap(exc23_WATCH_handler_ptr, 0x20)
113 | _interrupt_MI:
114 | _interrupt_SP:
115 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db " SP ")
116 | _interrupt_SI:
117 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db " SI ")
118 | _interrupt_AI:
119 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db " AI ")
120 |
121 | _interrupt_VI:
122 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db " VI ")
123 | _interrupt_PI:
124 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db " PI ")
125 | _interrupt_DP:
126 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db " DP ")
127 |
128 |
129 | fixed_gap(_xtlb_handler, 0x80)
130 | _cache_handler:
131 | j _interrupt_return_handler
132 | nop
133 | db "LEN "
134 | dw _interrupt_END - _tlb_handler
135 |
136 | InterruptHandlers:
137 | // The interrupt index is confusing! Since INT0 == bit 2, etc.
138 | // Cause Register -> Interrupt Pending bits are the following
139 | // 7. Timer
140 | // 6. Pin Interrupt INT4 Tied to VCC in Schematic
141 | // 5. Pin Interrupt INT3 Tied to VCC in Schematic
142 | // 4. Pin Interrupt INT2 Tied to PIF in Schematic Useful
143 | // 3. Pin Interrupt INT1 Tied to VCC in Schematic
144 | // 2. Pin Interrupt INT0 Tied to RCP in Schematic Useful
145 | // 1. Software 1 Interrupt
146 | // 0. Software 0 Interrupt
147 | // Software
148 | int0_handler_ptr:
149 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INS0")
150 |
151 | // Software
152 | int1_handler_ptr:
153 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INS1")
154 |
155 | // Ext: INT0 RCP
156 | int2_handler_ptr:
157 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INT0")
158 |
159 | // Ext: INT1 Pulled High in Schematic
160 | int3_handler_ptr:
161 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INT1")
162 |
163 | // Ext: INT2 PIF
164 | int4_handler_ptr:
165 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INT2")
166 |
167 | // Ext: INT3 Pulled High in Schematic
168 | int5_handler_ptr:
169 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INT3")
170 |
171 | // Ext: INT4 Pulled High in Schematic
172 | int6_handler_ptr:
173 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INT4")
174 |
175 | // Timer Interrupt
176 | int7_handler_ptr:
177 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INTT")
178 | _interrupt_continue:
179 |
180 | ori k1, k0, $0100 // Software0 Interrupt
181 | bnel k1, r0, _interrupt_custom_handler
182 | // Compiler Side effect int0_handler_ptr is only the lsb 16bits
183 | addi k0, ra, int0_handler_ptr
184 |
185 | j _interrupt_return_handler
186 | nop
187 |
188 | _interrupt_custom_handler:
189 | // Only if k0 is not ZERO
190 | beq k0, r0, _interrupt_return_handler
191 | nop
192 | lw k0, 0(k0)
193 | nop
194 | jalr k0
195 | nop
196 | _interrupt_return_handler:
197 | mfc0 k0, EPC
198 | // Restore the 'ra' register
199 | // TODO: Process Branch Delay Bit, 4 instructions
200 | mfc0 ra, PErr
201 | addiu k0, k0, 4
202 | mtc0 k0, EPC
203 | eret
204 |
205 | fixed_gap(_cache_handler, 0x80)
206 | // Interrupts & Exception Handlers
207 | // BREAK Instruction
208 | // SYSCALL Instruction
209 | _default_handler:
210 |
211 | mfc0 k0, Cause // Happened
212 | // Save ra so it can behave as expected and
213 | // we then have 2 normal registers to use (k0,k1)
214 | // PErr register is available but unused on R4300i,
215 | // its for backwards compatibility with R4000/R4200
216 | mtc0 ra, PErr
217 |
218 | // (Ab)using the 'ra' Register!
219 | lui ra, $8000
220 |
221 | // Register Values
222 | // ra = $8000'0000 '
223 | // k0 starts with the 'Cause' register then
224 | // ends up with the function pointer address to
225 | // load from and eventually the user interrupt
226 | // handler that is called.
227 | // k1 is our 'working' register
228 |
229 | // Look for exceptions first, Zero tell us its an interrupt
230 | andi k1, k0, $007C // Exceptions
231 | beql k1, r0, _default_interrupt
232 | mfc0 k1, SR // Watching
233 |
234 | // Load k0 with indexed Exception Handler Address
235 | // Compiler Side effect ExceptionHandlers is only the lsb 16bits
236 | andi k0, ra, ExceptionHandlers
237 | j _interrupt_custom_handler
238 | add k0, k1, k0
239 |
240 | _default_interrupt:
241 | nop // wait for SR register
242 | and k0, k0, k1 // Happened & Watching = Action to take
243 |
244 | ori k1, k0, $4000 // RCP Interrupt
245 | beq k1, r0, _interrupt_VR4300i
246 | // parse MI Interrupts
247 | lui k1, MI_BASE // wasted on branch but dont care.
248 | lw k0, MI_INTR(k1) // Happened
249 | lw k1, MI_INTR_MASK(k1) // Watching
250 | and k0, k0, k1 // Happened & Watching = Action to take
251 | sll k0, k0, 2
252 | // Compiler Side effect _interrupt_MI is only the lsb 16bits
253 | ori k1, ra, _interrupt_MI
254 | j _interrupt_custom_handler
255 | add k0, k0, k1
256 |
257 | _interrupt_VR4300i:
258 | ori k1, k0, $8000 // Timer Interrupt 7
259 | bnel k1, r0, _interrupt_custom_handler
260 | // Compiler Side effect int7_handler_ptr is only the lsb 16bits
261 | addi k0, ra, int7_handler_ptr
262 |
263 | ori k1, k0, $1000 // PIF Interrupt 5
264 | bnel k1, r0, _interrupt_custom_handler
265 | // Compiler Side effect int4_handler_ptr is only the lsb 16bits
266 | addi k0, ra, int4_handler_ptr
267 |
268 | // $0800 // Pulled High in Schematic
269 | ori k1, k0, $0200 // Software1 Interrupt
270 | bnel k1, r0, _interrupt_custom_handler
271 | // Compiler Side effect int1_handler_ptr is only the lsb 16bits
272 | addi k0, ra, int1_handler_ptr
273 |
274 | j _interrupt_continue
275 | nop
276 |
277 | _interrupt_END:
278 |
279 | fixed_gap(_tlb_handler, 0x200)
280 | //base pc_save
281 | //print(pc())
282 | //output_pc(pc())
283 | //putchar(pc_save)
284 | //putchar(pc())
285 | //fixed_gap(_tlb_handler, 0x240)
286 |
287 | db "LENC"
288 | _interrupt_handler_length:
289 | dw _interrupt_END - _tlb_handler
290 | db "LEND"
291 | dw _interrupt_continue - _tlb_handler
292 | db "EInt" // Interrupt
293 | dw exc0_Int_handler_ptr
294 | db "EMod" // TLB Change Exception
295 | dw exc1_Mod_handler_ptr
296 | db "TLBL" // TLB Refill Exception (Load/Fetch)
297 | dw exc2_TLBL_handler_ptr
298 | db "TLBS" // TLB Refill Exception (Store)
299 | dw exc3_TLBS_handler_ptr
300 | db "AdEL" // Address Error (Load/Fetch)
301 | dw exc4_AdEL_handler_ptr
302 | db "AdES" // Address Error (Store)
303 | dw exc5_AdES_handler_ptr
304 | db "IBE " // Bus Error (Fetch)
305 | dw exc6_IBE_handler_ptr
306 | db "DBE " // Bus Error (Load/Store)
307 | dw exc7_DBE_handler_ptr
308 | db "Sys " // System Exception Call
309 | dw exc8_Sys_handler_ptr
310 | db "Bp " // Breakpoint Exception
311 | dw exc9_Bp_handler_ptr
312 | db "RI " // Reserved Instruction Exception
313 | dw exc10_RI_handler_ptr
314 | db "CpU " // Coprocessor Unusable
315 | dw exc11_CpU_handler_ptr
316 | db "Ov " // Operation Overflow
317 | dw exc12_Ov_handler_ptr
318 | db "Tr " // Trap Exception
319 | dw exc13_Tr_handler_ptr
320 | db "Rsrv" // Reserved
321 | dw exc14_reserved_handler_ptr
322 | db "FPE " // Floating Point Exception
323 | dw exc15_FPE_handler_ptr
324 | db "WATH" // Debug Watch
325 | dw exc23_WATCH_handler_ptr
326 | db "DEF "
327 | dw default_handler_ptr
328 | db " SP "
329 | dw _interrupt_SP
330 | db " SI "
331 | dw _interrupt_SI
332 | db " AI "
333 | dw _interrupt_AI
334 | db " VI "
335 | dw _interrupt_VI
336 | db " PI "
337 | dw _interrupt_PI
338 | db " DP "
339 | dw _interrupt_DP
340 | db "INT0" // Software
341 | dw int0_handler_ptr
342 | db "INT1" // Software
343 | dw int1_handler_ptr
344 | db "INT2" // Ext: INT0 RCP
345 | dw int2_handler_ptr
346 | db "INT3" // Ext: INT1 Pulled High in Schematic
347 | dw int3_handler_ptr
348 | db "INT4" // Ext: INT2 PIF
349 | dw int4_handler_ptr
350 | db "INT5" // Ext: INT3 Pulled High in Schematic
351 | dw int5_handler_ptr
352 | db "INT6" // Ext: INT4 Pulled High in Schematic
353 | dw int6_handler_ptr
354 | db "INT7" // Timer Interrupt
355 | dw int7_handler_ptr
356 | db "END "
357 | dw _END_Interrupt_Handler
358 | _END_Interrupt_Handler:
--------------------------------------------------------------------------------
/N64/LIB/N64_INTERRUPT_TEMPLATE.S:
--------------------------------------------------------------------------------
1 | // This template lays over all of the Interrupt Handlers
2 | // TLB: 0x8000'0000
3 | // XTLB: 0x8000'0080
4 | // Cache: 0xA000'0100
5 | // Default: 0x8000'0180
6 | // End: 0x8000'0200
7 | // Unless the programmer defines a handler they all
8 | // jump through to the default:
9 | // Assumption: Trash k0, k1
10 |
11 | // libdragon notes:
12 | // Checks for Exceptions $0000 00FF
13 | // Checks for Reset Interrupt $0000 1000
14 | // Checks for Timer Interrupt $0000 8000
15 | // $0000 0400 RCP Assumed Type remaining MI has details
16 | // Software Interrupts are not checked
17 |
18 | // VR4300 Programming Guide notes:
19 | //
20 |
21 | db "Inter. Block"
22 | align(8)
23 | _interrupt_handler_template:
24 | variable code_pc(pc())
25 | base $80000000
26 | _tlb_handler:
27 | la k0, tlb_handler_ptr
28 | lw k0, 0(k0)
29 | nop
30 | beq k0, r0, _default_handler
31 | nop
32 | // Jump to custom handler
33 | jalr k0
34 | nop
35 | j _return_handler
36 | nop
37 |
38 | fixed_gap(_tlb_handler, 0x40)
39 | ExceptionHandlers:
40 | exc0_Int_handler_ptr: // Interrupt
41 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "EInt")
42 |
43 | exc1_Mod_handler_ptr: // TLB Change Exception
44 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "EMod")
45 |
46 | exc2_TLBL_handler_ptr: // TLB Refill Exception (Load/Fetch)
47 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "TLBL")
48 |
49 | exc3_TLBS_handler_ptr: // TLB Refill Exception (Store)
50 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "TLBS")
51 |
52 | exc4_AdEL_handler_ptr: // Address Error (Load/Fetch)
53 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "AdEL")
54 |
55 | exc5_AdES_handler_ptr: // Address Error (Store)
56 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "AdES")
57 |
58 | exc6_IBE_handler_ptr: // Bus Error (Fetch)
59 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "IBE ")
60 |
61 | exc7_DBE_handler_ptr: // Bus Error (Load/Store)
62 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "DBE ")
63 |
64 | exc8_Sys_handler_ptr: // System Exception Call
65 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "Sys ")
66 |
67 | exc9_Bp_handler_ptr: // Breakpoint Exception
68 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "Bp ")
69 |
70 | exc10_RI_handler_ptr: // Reserved Instruction Exception
71 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "RI ")
72 |
73 | exc11_CpU_handler_ptr: // Coprocessor Unusable
74 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "CpU ")
75 |
76 | exc12_Ov_handler_ptr: // Operation Overflow
77 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "Ov ")
78 |
79 | exc13_Tr_handler_ptr: // Trap Exception
80 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "Tr ")
81 |
82 | exc14_reserved_handler_ptr: // Reserved
83 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "Rv ")
84 |
85 | exc15_FPE_handler_ptr: // Floating Point Exception
86 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "FPE ")
87 |
88 | fixed_gap(_tlb_handler, 0x80)
89 |
90 | _xtlb_handler:
91 | // Only applies to 64-bit code
92 | // Just in case something gets here, send backwards
93 | j _tlb_handler
94 | nop
95 |
96 | fixed_gap(ExceptionHandlers, 0x5C)
97 | exc23_WATCH_handler_ptr: // Watch
98 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "WATH")
99 |
100 | InterruptHandlers:
101 | // Software
102 | int0_handler_ptr:
103 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INT0")
104 |
105 | // Software
106 | int1_handler_ptr:
107 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INT1")
108 |
109 | // Ext: INT0 RCP
110 | int2_handler_ptr:
111 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INT2")
112 |
113 | // Ext: INT1 Pulled High in Schematic
114 | nt3_handler_ptr:
115 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INT3")
116 |
117 | // Ext: INT2 PIF
118 | int4_handler_ptr:
119 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INT4")
120 |
121 | // Ext: INT3 Pulled High in Schematic
122 | int5_handler_ptr:
123 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INT5")
124 |
125 | // Ext: INT4 Pulled High in Schematic
126 | int6_handler_ptr:
127 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INT6")
128 |
129 | // Timer Interrupt
130 | int7_handler_ptr:
131 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "INT7")
132 |
133 | tlb_handler_ptr:
134 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "TLBH")
135 |
136 | cache_handler_ptr:
137 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "CACH")
138 |
139 | default_handler_ptr:
140 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "DEFT")
141 |
142 | vblank_handler_ptr:
143 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "VBLK")
144 |
145 | other_int_handler_ptr:
146 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "IOTR")
147 |
148 | other_exc_handler_ptr:
149 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "EOTR")
150 |
151 | _intterupt_save_ra:
152 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "ra ")
153 |
154 | fixed_gap(_xtlb_handler, 0x80)
155 |
156 | _cache_handler:
157 | la k0, cache_handler_ptr
158 | lw k0, 0(k0)
159 | nop
160 | beq k0, r0, _default_handler
161 | nop
162 | // Jump to custom handler
163 | jalr k0
164 | nop
165 | j _return_handler
166 | nop
167 | fixed_gap(_cache_handler, 0x80)
168 |
169 | // libdragon notes:
170 | // Checks for Exceptions $0000 00FF
171 | // Checks for Reset Interrupt $0000 1000
172 | // Checks for Timer Interrupt $0000 8000
173 | // $0000 0400 RCP Assumed Type remaining MI has details
174 | // Software Interrupts are not checked
175 |
176 | _default_handler:
177 | // Free up another register
178 | lui k1, $8000
179 | sw ra, _intterupt_save_ra(k1)
180 |
181 | mfc0 k0, SR // What we are watching for
182 | // Very careful use of 'ra' register
183 | mfc0 ra, Cause // What happened
184 | and k0, ra, k0 // Happened & Watching = Action to take
185 | andi ra, k0, $00FF
186 |
187 | // Process Interrupts first
188 | // Shift Right 8 then multiply by 4 to get an address
189 | srl k0, k0, 8
190 | beq k0, r0, _exception_check // k0 before or after are fine for this branch
191 | sll k0, k0, 1
192 |
193 | la k1, InterruptHandlers
194 | j _interrupt_custom_execute
195 | add k0, k0, k1
196 |
197 | _exception_check:
198 | blez ra, _interrupt_other_exception
199 | la k0, ExceptionHandlers // Intentionally in Delay Slot, gets overwritten if wrong.
200 | j _interrupt_custom_execute
201 | add k0, k0, ra
202 |
203 | _interrupt_other_exception:
204 | // Other Exception
205 | la k0, default_handler_ptr
206 |
207 | _interrupt_custom_execute: // Test custom handler
208 | lw k0, 0(k0)
209 | nop
210 | beq k0, r0, _return_handler
211 | nop
212 | _interrupt_custom_handler:
213 | // Jump to custom handler
214 | jalr k0
215 | nop
216 |
217 | //This is the return handler
218 | // Clean up and return
219 | _return_handler:
220 | // Restore the 'ra' register
221 | lui k1, $8000
222 | lw ra, _intterupt_save_ra(k1)
223 |
224 | mfc0 k0, EPC
225 | addiu k0, k0, 4
226 | mtc0 k0, EPC
227 | eret
228 | fixed_gap(_default_handler, 0x80)
229 | base code_pc
230 | db "EndBlock"
--------------------------------------------------------------------------------
/N64/LIB/N64_IPL_FONT.INC:
--------------------------------------------------------------------------------
1 | macro font_init16(forecolor, backcolor, dest) {
2 | li a0, {forecolor}
3 | li a1, {backcolor}
4 | li a2, {dest}
5 | jal fontinit16
6 | nop
7 | }
8 |
9 | macro font_init32(forecolor, backcolor, dest) {
10 | li a0, {forecolor}
11 | li a1, {backcolor}
12 | li a2, {dest}
13 | jal fontinit32
14 | nop
15 | }
16 |
17 | macro font_print_line16(fontname, framebuffer, left, top, string_address, length) {
18 | li a0, {fontname}
19 | li a1, {framebuffer}
20 | li a2, {left}
21 | li a3, {top}
22 | li v0, {string_address}
23 | li v1, {length}
24 | jal fontprintline16
25 | nop
26 | }
27 |
28 | macro font_print_line32(fontname, framebuffer, left, top, string_address, length) {
29 | li a0, {fontname}
30 | li a1, {framebuffer}
31 | li a2, {left}
32 | li a3, {top}
33 | li v0, {string_address}
34 | li v1, {length}
35 | jal fontprintline32
36 | nop
37 | }
38 |
39 | macro font_conv_hex2dec(text_hex_address, text_hex_length, text_dec_address, text_dec_length) {
40 | li a0, {text_hex_address}
41 | li a1, {text_hex_length}
42 | li a2, {text_dec_address}
43 | li a3, {text_dec_length}
44 | jal fontconvhex2dec
45 | nop
46 | }
--------------------------------------------------------------------------------
/N64/LIB/N64_IPL_FONT.S:
--------------------------------------------------------------------------------
1 | align(8)
2 | nop
3 | nop
4 | nop
5 | variable zero(r0)
6 | variable forecolor(a0)
7 | variable backcolor(a1) // (0x01 = transparent)
8 | variable destination(a2)
9 |
10 | variable ipl_font(t0)
11 | variable font_cur_word(t1)
12 | variable font_bits(t2)
13 | variable font_bit_count(t3)
14 | variable font_top_bit_mask(t4)
15 | variable ipl_font_end(t5)
16 |
17 | // 50 Characters @ 23 bytes + (18 0x00 bytes) = 1168 bytes
18 | // 1168 / 4 (word size) = 292 Ignore the last 16 bytes = 288 * 4 = 1152
19 | // 32 bits expand to 16 bit color for each bit = 64 bytes
20 | // Each Font will use 18.5 KB of RAM
21 |
22 | fontinit16:
23 | la ipl_font, $B0000B70
24 | addi ipl_font_end, ipl_font, 1168
25 | li font_top_bit_mask, 0x80000000
26 |
27 | font_next_word16:
28 | lw font_cur_word, 0(ipl_font)
29 | addi font_bit_count, zero, 31
30 |
31 | font_next_bits16:
32 | and font_bits, font_cur_word, font_top_bit_mask
33 | sll font_cur_word, font_cur_word, 1
34 | bnel font_bits, zero, font_forecolor16
35 | nop
36 | sh backcolor, 0(destination)
37 | j font_continue16
38 | nop
39 | font_forecolor16:
40 | sh forecolor, 0(destination)
41 | nop
42 | font_continue16:
43 | addi destination, destination, 2
44 | bne font_bit_count, zero, font_next_bits16
45 | addi font_bit_count, font_bit_count, -1
46 |
47 | bne ipl_font, ipl_font_end, font_next_word16
48 | addi ipl_font, ipl_font, 4
49 | jr ra
50 | addiu v0, zero, 18768
51 | nop
52 | nop
53 |
54 | nop
55 | nop
56 | fontinit32:
57 | la ipl_font, $B0000B70
58 | addi ipl_font_end, ipl_font, 1168
59 | li font_top_bit_mask, 0x80000000
60 |
61 | font_next_word32:
62 | lw font_cur_word, 0(ipl_font)
63 | addi font_bit_count, zero, 31
64 |
65 | font_next_bits32:
66 | and font_bits, font_cur_word, font_top_bit_mask
67 | sll font_cur_word, font_cur_word, 1
68 | bnel font_bits, zero, font_forecolor32
69 | nop
70 | sh backcolor, 0(destination)
71 | j font_continue32
72 | nop
73 | font_forecolor32:
74 | sh forecolor, 0(destination)
75 | nop
76 | font_continue32:
77 | addi destination, destination, 4
78 | bne font_bit_count, zero, font_next_bits32
79 | addi font_bit_count, font_bit_count, -1
80 |
81 | bne ipl_font, ipl_font_end, font_next_word32
82 | addi ipl_font, ipl_font, 4
83 | jr ra
84 | addiu v0, zero, 37536
85 | nop
86 | nop
87 |
88 | nop
89 | nop
90 | nop
91 | align(8)
92 | nop
93 | nop
94 | nop
95 | fontprintline16:
96 | // Constant Values
97 | constant font_addr(a0)
98 | constant fb_addr(a1)
99 | constant fb_left(a2)
100 | constant fb_top(a3)
101 | constant fb_base(fb_top)
102 | constant text_address(v0)
103 | constant text_length(v1)
104 | constant font_char_len(t2)
105 | constant line_byte_width(t4)
106 |
107 | // Variable - i.e. change for each line/char, etc
108 | constant text_curr_idx(t5)
109 | constant text_curr_char(t0)
110 |
111 | constant font_curr_addr(t1)
112 | constant fb_curr_addr(t3)
113 |
114 | // Totally Temp, so anything goes
115 | constant tmp_reg0(t7)
116 | constant tmp_reg1(t8)
117 | constant tmp_reg2(t9)
118 |
119 | addi text_curr_idx, zero, zero
120 | // Each character is 23 original bytes, 368 in expanded font
121 | addi font_char_len, zero, 368
122 |
123 | // Get the Video Pixel Width * 2 for 16 bit color
124 | lui tmp_reg0, VI_BASE
125 | lw tmp_reg0, VI_WIDTH(tmp_reg0)
126 | sll line_byte_width, tmp_reg0, 1 // *2
127 |
128 | // Set fb_curr_addr based on values we have
129 | add fb_curr_addr, zero, fb_addr
130 | // last line is only a partial for this calc, so remove it
131 | addi tmp_reg0, fb_top, -1
132 | // Multiply Video pixel width * number of lines from the top
133 | multu line_byte_width, tmp_reg0
134 | mflo fb_top
135 | // Add Line pixels
136 | add fb_curr_addr, fb_curr_addr, fb_top
137 | // Add partial line pixels
138 | sll tmp_reg0, fb_left, 1 // *2 16 bit color
139 | add fb_base, tmp_reg0, fb_curr_addr
140 |
141 | font_next_char:
142 | beql text_length, zero, font_finished
143 | nop
144 | // Add char offset to fb_base
145 | addi tmp_reg0, zero, 26
146 | multu text_curr_idx, tmp_reg0
147 | mflo tmp_reg0
148 | add fb_curr_addr, fb_base, tmp_reg0
149 | // Get selected char
150 | lb text_curr_char, 0(text_address)
151 | // Check for ' ' (space)
152 | addi tmp_reg0, zero, 0x33
153 | beql text_curr_char, tmp_reg0, font_space
154 | nop
155 | // Position font address
156 | multu font_char_len, text_curr_char
157 | mflo font_curr_addr
158 | add font_curr_addr, font_curr_addr, font_addr
159 | addi t6, zero, 13
160 | font_line_loop:
161 | ld tmp_reg0, 0(font_curr_addr)
162 | ld tmp_reg1, 8(font_curr_addr)
163 | ld tmp_reg2, 16(font_curr_addr)
164 |
165 | sd tmp_reg0, 0(fb_curr_addr)
166 | lh tmp_reg0, 24(font_curr_addr)
167 | sd tmp_reg1, 8(fb_curr_addr)
168 | sd tmp_reg2, 16(fb_curr_addr)
169 | sh tmp_reg0, 24(fb_curr_addr)
170 |
171 | add fb_curr_addr, fb_curr_addr, line_byte_width
172 | addi font_curr_addr, font_curr_addr, 26
173 | bne t6, zero, font_line_loop
174 | addi t6, t6, -1
175 | // Loop over 14 lines
176 |
177 | font_space:
178 | // Char Complete, setup for the next
179 | addi text_address, text_address, 1
180 | addi text_curr_idx, text_curr_idx, 1
181 | bnel text_length, zero, font_next_char
182 | addi text_length, text_length, -1
183 | font_finished:
184 | jr ra
185 | nop
186 | nop
187 | nop
188 |
189 |
190 | align(8)
191 | // https://stackoverflow.com/questions/5558492/divide-by-10-using-bit-shifts
192 | divide10:
193 | variable n(a0)
194 | variable q(v0)
195 | variable r(t0)
196 | variable t(t1)
197 | srl q, n, 1
198 | srl r, n, 2
199 | add q, q, r
200 | srl r, q, 4
201 | add q, q, r
202 | srl r, q, 8
203 | add q, q, r
204 | srl r, q, 16
205 | add q, q, r
206 | srl q, q, 3
207 | sll t, q, 2
208 | add t, t, q
209 | sll t, t, 1
210 | sub r, n, t
211 | addi t, zero, 10
212 | slt t, t, r
213 | jr ra
214 | add q, q, t
215 |
216 | nop
217 | nop
218 | nop
219 | nop
220 | nop
221 | nop
222 |
223 | align(8)
224 | fontconvhex2dec:
225 | variable text_hex_address(a0)
226 | variable text_hex_length(a1)
227 | variable text_dec_address(a2)
228 | variable text_dec_length(a3)
229 | // based on length load the value into a register (upto 64-bit values supported)
230 | // only populated the provided decimal length starting from the right LSB
231 | //jal divide10
232 | //addi a0, zero, -1
233 | // v0 = 0x19999999
234 |
235 | jr ra
236 | nop
237 | nop
238 | nop
--------------------------------------------------------------------------------
/N64/LIB/N64_RSP.INC:
--------------------------------------------------------------------------------
1 | //==============================
2 | // N64 Reality Signal Processor
3 | //==============================
4 | // RSP MIPS 4000 CPU Registers R0..R31
5 | // RSP CP2 128-Bit Vector Registers: V0..V31
6 | // RSP CP2 Vector Elements (128-Bit Vector = 16 Elements): E0..E15
7 |
8 | // RSP CP0 Control Registers (MTF0/MTC0):
9 | constant c0(0) // RSP CP0 Control Register 00: I/DMEM Address For DMA (RW) ($04040000)
10 | constant c1(1) // RSP CP0 Control Register 01: DRAM Address For DMA (RW) ($04040004)
11 | constant c2(2) // RSP CP0 Control Register 02: DMA READ Length (DRAM -> I/DMEM) (RW) ($04040008)
12 | constant c3(3) // RSP CP0 Control Register 03: DMA WRITE Length (DRAM <- I/DMEM) (RW) ($0404000C)
13 | constant c4(4) // RSP CP0 Control Register 04: RSP Status (RW) ($04040010)
14 | constant c5(5) // RSP CP0 Control Register 05: DMA Full (R) ($04040014)
15 | constant c6(6) // RSP CP0 Control Register 06: DMA Busy (R) ($04040018)
16 | constant c7(7) // RSP CP0 Control Register 07: CPU-RSP Semaphore (RW) ($0404001C)
17 | constant c8(8) // RSP CP0 Control Register 08: RDP Command Buffer START (RW) ($04100000)
18 | constant c9(9) // RSP CP0 Control Register 09: RDP Command Buffer END (RW) ($04100004)
19 | constant c10(10) // RSP CP0 Control Register 10: RDP Command Buffer CURRENT (R) ($04100008)
20 | constant c11(11) // RSP CP0 Control Register 11: RDP Status (RW) ($0410000C)
21 | constant c12(12) // RSP CP0 Control Register 12: RDP Clock Counter (R) ($04100010)
22 | constant c13(13) // RSP CP0 Control Register 13: RDP Command Buffer BUSY (R) ($04100014)
23 | constant c14(14) // RSP CP0 Control Register 14: RDP Pipe BUSY (R) ($04100018)
24 | constant c15(15) // RSP CP0 Control Register 15: RDP TMEM BUSY (R) ($0410001C)
25 |
26 | // RSP CP2 Control Registers (CFC2/CTC2):
27 | constant vco(0) // RSP CP2 Control Register 0: Vector Carry Out
28 | constant vcc(1) // RSP CP2 Control Register 1: Vector Compare Code
29 | constant vce(2) // RSP CP2 Control Register 2: Vector Compare Extension
30 |
31 | // RSP Status Read Flags:
32 | constant RSP_HLT($0001) // SP_STATUS: Halt (Bit 0)
33 | constant RSP_BRK($0002) // SP_STATUS: Break (Bit 1)
34 | constant RSP_BSY($0004) // SP_STATUS: DMA Busy (Bit 2)
35 | constant RSP_FUL($0008) // SP_STATUS: DMA Full (Bit 3)
36 | constant RSP_IOF($0010) // SP_STATUS: IO Full (Bit 4)
37 | constant RSP_STP($0020) // SP_STATUS: Single Step (Bit 5)
38 | constant RSP_IOB($0040) // SP_STATUS: Interrupt On Break (Bit 6)
39 | constant RSP_SG0($0080) // SP_STATUS: Signal 0 Set (Bit 7)
40 | constant RSP_SG1($0100) // SP_STATUS: Signal 1 Set (Bit 8)
41 | constant RSP_SG2($0200) // SP_STATUS: Signal 2 Set (Bit 9)
42 | constant RSP_SG3($0400) // SP_STATUS: Signal 3 Set (Bit 10)
43 | constant RSP_SG4($0800) // SP_STATUS: Signal 4 Set (Bit 11)
44 | constant RSP_SG5($1000) // SP_STATUS: Signal 5 Set (Bit 12)
45 | constant RSP_SG6($2000) // SP_STATUS: Signal 6 Set (Bit 13)
46 | constant RSP_SG7($4000) // SP_STATUS: Signal 7 Set (Bit 14)
47 |
48 | // RSP Status Write Flags:
49 | constant CLR_HLT($0000001) // SP_STATUS: Clear Halt (Bit 0)
50 | constant SET_HLT($0000002) // SP_STATUS: Set Halt (Bit 1)
51 | constant CLR_BRK($0000004) // SP_STATUS: Clear Broke (Bit 2)
52 | constant CLR_INT($0000008) // SP_STATUS: Clear Interrupt (Bit 3)
53 | constant SET_INT($0000010) // SP_STATUS: Set Interrupt (Bit 4)
54 | constant CLR_STP($0000020) // SP_STATUS: Clear Single Step (Bit 5)
55 | constant SET_STP($0000040) // SP_STATUS: Set Single Step (Bit 6)
56 | constant CLR_IOB($0000080) // SP_STATUS: Clear Interrupt On Break (Bit 7)
57 | constant SET_IOB($0000100) // SP_STATUS: Set Interrupt On Break (Bit 8)
58 | constant CLR_SG0($0000200) // SP_STATUS: Clear Signal 0 (Bit 9)
59 | constant SET_SG0($0000400) // SP_STATUS: Set Signal 0 (Bit 10)
60 | constant CLR_SG1($0000800) // SP_STATUS: Clear Signal 1 (Bit 11)
61 | constant SET_SG1($0001000) // SP_STATUS: Set Signal 1 (Bit 12)
62 | constant CLR_SG2($0002000) // SP_STATUS: Clear Signal 2 (Bit 13)
63 | constant SET_SG2($0004000) // SP_STATUS: Set Signal 2 (Bit 14)
64 | constant CLR_SG3($0008000) // SP_STATUS: Clear Signal 3 (Bit 15)
65 | constant SET_SG3($0010000) // SP_STATUS: Set Signal 3 (Bit 16)
66 | constant CLR_SG4($0020000) // SP_STATUS: Clear Signal 4 (Bit 17)
67 | constant SET_SG4($0040000) // SP_STATUS: Set Signal 4 (Bit 18)
68 | constant CLR_SG5($0080000) // SP_STATUS: Clear Signal 5 (Bit 19)
69 | constant SET_SG5($0100000) // SP_STATUS: Set Signal 5 (Bit 20)
70 | constant CLR_SG6($0200000) // SP_STATUS: Clear Signal 6 (Bit 21)
71 | constant SET_SG6($0400000) // SP_STATUS: Set Signal 6 (Bit 22)
72 | constant CLR_SG7($0800000) // SP_STATUS: Clear Signal 7 (Bit 23)
73 | constant SET_SG7($1000000) // SP_STATUS: Set Signal 7 (Bit 24)
74 |
75 | // RDP Status Read Flags:
76 | constant RDP_XBS($0001) // DPC_STATUS: Use XBUS DMEM DMA Or DRAM DMA (Bit 0)
77 | constant RDP_FRZ($0002) // DPC_STATUS: RDP Frozen (Bit 1)
78 | constant RDP_FLS($0004) // DPC_STATUS: RDP Flushed (Bit 2)
79 | constant RDP_GCL($0008) // DPC_STATUS: GCLK Alive (Bit 3)
80 | constant RDP_TMB($0010) // DPC_STATUS: TMEM Busy (Bit 4)
81 | constant RDP_PLB($0020) // DPC_STATUS: RDP PIPELINE Busy (Bit 5)
82 | constant RDP_CMB($0040) // DPC_STATUS: RDP COMMAND Unit Busy (Bit 6)
83 | constant RDP_CMR($0080) // DPC_STATUS: RDP COMMAND Buffer Ready (Bit 7)
84 | constant RDP_DMA($0100) // DPC_STATUS: RDP DMA Busy (Bit 8)
85 | constant RDP_CME($0200) // DPC_STATUS: RDP COMMAND END Register Valid (Bit 9)
86 | constant RDP_CMS($0400) // DPC_STATUS: RDP COMMAND START Register Valid (Bit 10)
87 |
88 | // RDP Status Write Flags:
89 | constant CLR_XBS($001) // DPC_STATUS: Clear XBUS DMEM DMA (Bit 0)
90 | constant SET_XBS($002) // DPC_STATUS: Set XBUS DMEM DMA (Bit 1)
91 | constant CLR_FRZ($004) // DPC_STATUS: Clear FREEZE (Bit 2)
92 | constant SET_FRZ($008) // DPC_STATUS: Set FREEZE (Bit 3)
93 | constant CLR_FLS($010) // DPC_STATUS: Clear FLUSH (Bit 4)
94 | constant SET_FLS($020) // DPC_STATUS: Set FLUSH (Bit 5)
95 | constant CLR_TMC($040) // DPC_STATUS: Clear TMEM COUNTER (Bit 6)
96 | constant CLR_PLC($080) // DPC_STATUS: Clear PIPELINE COUNTER (Bit 7)
97 | constant CLR_CMC($100) // DPC_STATUS: Clear COMMAND COUNTER (Bit 8)
98 | constant CLR_CLK($200) // DPC_STATUS: Clear CLOCK COUNTER (Bit 9)
99 |
100 | // CPU DMA
101 | macro DMASPRD(start, end, dest) { // DMA Data Read DRAM->RSP MEM: Start Address, End Address, Destination RSP MEM Address
102 | lui a0,SP_BASE // A0 = SP Base Register ($A4040000)
103 | lui t0,SP_MEM_BASE // T0 = SP Memory Base Register ($A4000000)
104 | ori t0,{dest}&$1FFF // T0 = SP Memory Address Offset ($A4000000..$A4001FFF 8KB)
105 | sw t0,SP_MEM_ADDR(a0) // Store Memory Offset To SP Memory Address Register ($A4040000)
106 | la t0,{start}&$7FFFFFF // T0 = Aligned DRAM Physical RAM Offset ($00000000..$007FFFFF 8MB)
107 | sw t0,SP_DRAM_ADDR(a0) // Store RAM Offset To SP DRAM Address Register ($A4040004)
108 | la t0,({end}-{start})-1 // T0 = Length Of DMA Transfer In Bytes - 1
109 | sw t0,SP_RD_LEN(a0) // Store DMA Length To SP Read Length Register ($A4040008)
110 | }
111 |
112 | macro DMASPWR(start, end, source) { // DMA Data Write RSP MEM->DRAM: Start Address, End Address, Source RSP MEM Address
113 | lui a0,SP_BASE ; A0 = SP Base Register ($A4040000)
114 | lui t0,SP_MEM_BASE ; T0 = SP Memory Base Register ($A4000000)
115 | ori t0,{source}&$1FFF ; T0 = SP Memory Address Offset ($A4000000..$A4001FFF 8KB)
116 | sw t0,SP_MEM_ADDR(a0) ; Store Memory Offset To SP Memory Address Register ($A4040000)
117 | la t0,{start}&$7FFFFFF ; T0 = Aligned DRAM Physical RAM Offset ($00000000..$007FFFFF 8MB)
118 | sw t0,SP_DRAM_ADDR(a0) ; Store RAM Offset To SP DRAM Address Register ($A4040004)
119 | la t0,({end}-{start})-1 ; T0 = Length Of DMA Transfer In Bytes - 1
120 | sw t0,SP_WR_LEN(a0) ; Store DMA Length To SP Write Length Register ($A404000C)
121 | }
122 |
123 | // RSP DMA
124 | macro RSPDMASPRD(start, end, dest) { // DMA Data Read DRAM->RSP MEM: Start Address, End Address, Destination RSP MEM Address
125 | li a0,{dest}&$1FFF // A0 = SP Memory Address Offset ($A4000000..$A4001FFF 8KB)
126 | mtc0 a0,c0 // Store Memory Offset To SP Memory Address Register ($A4040000)
127 | la a0,{start}&$7FFFFFF // A0 = Aligned DRAM Physical RAM Offset ($00000000..$007FFFFF 8MB)
128 | mtc0 a0,c1 // Store RAM Offset To SP DRAM Address Register ($A4040004)
129 | la a0,({end}-{start})-1 // A0 = Length Of DMA Transfer In Bytes - 1
130 | mtc0 a0,c2 // Store DMA Length To SP Read Length Register ($A4040008)
131 | }
132 |
133 | macro RSPDMASPWR(start, end, source) { // DMA Data Write RSP MEM->DRAM: Start Address, End Address, Source RSP MEM Address
134 | li a0,{source}&$1FFF // A0 = SP Memory Address Offset ($A4000000..$A4001FFF 8KB)
135 | mtc0 a0,c0 // Store Memory Offset To SP Memory Address Register ($A4040000)
136 | la a0,{start}&$7FFFFFF // A0 = Aligned DRAM Physical RAM Offset ($00000000..$007FFFFF 8MB)
137 | mtc0 a0,c1 // Store RAM Offset To SP DRAM Address Register ($A4040004)
138 | la a0,({end}-{start})-1 // A0 = Length Of DMA Transfer In Bytes - 1
139 | mtc0 a0,c3 // Store DMA Length To SP Write Length Register ($A404000C)
140 | }
141 |
142 | macro RSPDPC(start, end) { // Run DPC Command Buffer: Start Address, End Address
143 | la a0,{start} // A0 = DPC Command Start Address
144 | mtc0 a0,c8 // Store DPC Command Start Address To DP Start Register ($A4100000)
145 | addi a0,{end}-{start} // A0 = DPC Command End Address
146 | mtc0 a0,c9 // Store DPC Command End Address To DP End Register ($A4100004)
147 | }
148 |
149 | // RSP CP2 Vector Operation Instructions (COP2):
150 | // vmulf vd, vs, vt[e] ; Vector Multiply Signed Fractions: VMULF VD,VS,VT[ELEMENT]
151 | // vmulu vd, vs, vt[e] ; Vector Multiply Unsigned Fractions: VMULU VD,VS,VT[ELEMENT]
152 | // vrndp vd, vs, vt[e] ; Vector DCT Round Positive: VRNDP VD,VS,VT[ELEMENT] (Reserved: MPEG DCT Rounding)
153 | // vmulq vd, vs, vt[e] ; Vector Multiply Integer: VMULQ VD,VS,VT[ELEMENT] (Reserved: MPEG Inverse Quantization)
154 | // vmudl vd, vs, vt[e] ; Vector Multiply Low Partial Products: VMUDL VD,VS,VT[ELEMENT]
155 | // vmudm vd, vs, vt[e] ; Vector Multiply Mid Partial Products: VMUDM VD,VS,VT[ELEMENT]
156 | // vmudn vd, vs, vt[e] ; Vector Multiply Mid Partial Products: VMUDN VD,VS,VT[ELEMENT]
157 | // vmudh vd, vs, vt[e] ; Vector Multiply High Partial Products: VMUDH VD,VS,VT[ELEMENT]
158 | // vmacf vd, vs, vt[e] ; Vector Multiply Accumulate Signed Fractions: VMACF VD,VS,VT[ELEMENT]
159 | // vmacu vd, vs, vt[e] ; Vector Multiply Accumulate Unsigned Fractions: VMACU VD,VS,VT[ELEMENT]
160 | // vrndn vd, vs, vt[e] ; Vector DCT Round Negative: VRNDN VD,VS,VT[ELEMENT] (Reserved: MPEG DCT Rounding)
161 | // vmacq vd, vs, vt[e] ; Vector Multiply Accumulate Integer: VMACQ VD,VS,VT[ELEMENT] (Reserved: MPEG Inverse Quantization)
162 | // vmadl vd, vs, vt[e] ; Vector Multiply Accumulate Low Partial Products: VMADL VD,VS,VT[ELEMENT]
163 | // vmadm vd, vs, vt[e] ; Vector Multiply Accumulate Mid Partial Products: VMADM VD,VS,VT[ELEMENT]
164 | // vmadn vd, vs, vt[e] ; Vector Multiply Accumulate Mid Partial Products: VMADN VD,VS,VT[ELEMENT]
165 | // vmadh vd, vs, vt[e] ; Vector Multiply Accumulate High Partial Products: VMADH VD,VS,VT[ELEMENT]
166 | // vadd vd, vs, vt[e] ; Vector Add Short Elements: VADD VD,VS,VT[ELEMENT]
167 | // vsub vd, vs, vt[e] ; Vector Subtract Short Elements: VSUB VD,VS,VT[ELEMENT]
168 | // vsut vd, vs, vt[e] ; Vector Subtract Short Elements (VT-VS): VSUT VD,VS,VT[ELEMENT] (Reserved)
169 | // vabs vd, vs, vt[e] ; Vector Absolute Value Of Short Elements: VABS VD,VS,VT[ELEMENT]
170 | // vaddc vd, vs, vt[e] ; Vector Add Short Elements With Carry: VADDC VD,VS,VT[ELEMENT]
171 | // vsubc vd, vs, vt[e] ; Vector Subtract Short Elements With Carry: VSUBC VD,VS,VT[ELEMENT]
172 | // vaddb vd, vs, vt[e] ; Vector Add Byte Elements: VADDB VD,VS,VT[ELEMENT] (Reserved)
173 | // vsubb vd, vs, vt[e] ; Vector Subtract Byte Elements: VSUBB VD,VS,VT[ELEMENT] (Reserved)
174 | // vaccb vd, vs, vt[e] ; Vector Add Byte Elements With Carry: VACCB VD,VS,VT[ELEMENT] (Reserved)
175 | // vsucb vd, vs, vt[e] ; Vector Subtract Byte Elements With Carry: VSUCB VD,VS,VT[ELEMENT] (Reserved)
176 | // vsad vd, vs, vt[e] ; Vector SAD: VSAD VD,VS,VT[ELEMENT] (Reserved)
177 | // vsac vd, vs, vt[e] ; Vector SAC: VSAC VD,VS,VT[ELEMENT] (Reserved)
178 | // vsum vd, vs, vt[e] ; Vector SUM: VSUM VD,VS,VT[ELEMENT] (Reserved)
179 | // vsar vd, vs, vt[e] ; Vector Accumulator Read: VSAR VD,VS,VT[ELEMENT]
180 | // vacc vd, vs, vt[e] ; Vector Add Elements With Carry: VACC VD,VS,VT[ELEMENT] (Reserved)
181 | // vsuc vd, vs, vt[e] ; Vector Subtract Elements With Carry: VSUC VD,VS,VT[ELEMENT] (Reserved)
182 | // vlt vd, vs, vt[e] ; Vector Select Less Than: VLT VD,VS,VT[ELEMENT]
183 | // veq vd, vs, vt[e] ; Vector Select Equal: VEQ VD,VS,VT[ELEMENT]
184 | // vne vd, vs, vt[e] ; Vector Select Not Equal: VNE VD,VS,VT[ELEMENT]
185 | // vge vd, vs, vt[e] ; Vector Select Greater Than Or Equal: VGE VD,VS,VT[ELEMENT]
186 | // vcl vd, vs, vt[e] ; Vector Select Clip Test Low: VCL VD,VS,VT[ELEMENT]
187 | // vch vd, vs, vt[e] ; Vector Select Clip Test High: VCH VD,VS,VT[ELEMENT]
188 | // vcr vd, vs, vt[e] ; Vector Select Crimp Test Low: VCR VD,VS,VT[ELEMENT]
189 | // vmrg vd, vs, vt[e] ; Vector Select Merge: VMRG VD,VS,VT[ELEMENT]
190 | // vand vd, vs, vt[e] ; Vector Logical AND Short Elements: VAND VD,VS,VT[ELEMENT]
191 | // vnand vd, vs, vt[e] ; Vector Logical NOT AND Short Elements: VNAND VD,VS,VT[ELEMENT]
192 | // vor vd, vs, vt[e] ; Vector Logical OR Short Elements: VOR VD,VS,VT[ELEMENT]
193 | // vnor vd, vs, vt[e] ; Vector Logical NOT OR Short Elements: VNOR VD,VS,VT[ELEMENT]
194 | // vxor vd, vs, vt[e] ; Vector Logical Exclusive OR Short Elements: VXOR VD,VS,VT[ELEMENT]
195 | // vnxor vd, vs, vt[e] ; Vector Logical NOT Exclusive OR Short Elements: VNXOR VD,VS,VT[ELEMENT]
196 | // v056 vd, vs, vt[e] ; Vector Row 5 Column 6: V056 VD,VS,VT[ELEMENT] (Reserved)
197 | // v057 vd, vs, vt[e] ; Vector Row 5 Column 7: V057 VD,VS,VT[ELEMENT] (Reserved)
198 |
199 | // vrcp vd[de], vt[e] ; Vector Element Scalar Reciprocal (Single Precision): VRCP VD[ELEMENT],VT[ELEMENT]
200 | // vrcpl vd[de], vt[e] ; Vector Element Scalar Reciprocal Low: VRCPL VD[ELEMENT],VT[ELEMENT]
201 | // vrcph vd[de], vt[e] ; Vector Element Scalar Reciprocal High: VRCPH VD[ELEMENT],VT[ELEMENT]
202 | // vmov vd[de], vt[e] ; Vector Element Scalar Move: VMOV VD[ELEMENT],VT[ELEMENT]
203 | // vrsq vd[de], vt[e] ; Vector Element Scalar SQRT Reciprocal (Single Precision): VRSQ VD[ELEMENT],VT[ELEMENT]
204 | // vrsql vd[de], vt[e] ; Vector Element Scalar SQRT Reciprocal Low: VRSQL VD[ELEMENT],VT[ELEMENT]
205 | // vrsqh vd[de], vt[e] ; Vector Element Scalar SQRT Reciprocal High: VRSQH VD[ELEMENT],VT[ELEMENT]
206 |
207 | // vnop ; Vector Null Instruction: VNOP
208 |
209 | // vextt vd, vs, vt[e] ; Vector Extract Triple (5/5/5/1): VEXTT VD,VS,VT[ELEMENT] (Reserved)
210 | // vextq vd, vs, vt[e] ; Vector Extract Quad (4/4/4/4): VEXTQ VD,VS,VT[ELEMENT] (Reserved)
211 | // vextn vd, vs, vt[e] ; Vector Extract Nibble (4/4/4/4) (Sign Extended): VEXTN VD,VS,VT[ELEMENT] (Reserved)
212 | // v073 vd, vs, vt[e] ; Vector Row 7 Column 3: V073 VD,VS,VT[ELEMENT] (Reserved)
213 | // vinst vd, vs, vt[e] ; Vector Insert Triple (5/5/5/1): VINST VD,VS,VT[ELEMENT] (Reserved)
214 | // vinsq vd, vs, vt[e] ; Vector Insert Quad (4/4/4/4): VINSQ VD,VS,VT[ELEMENT] (Reserved)
215 | // vinsn vd, vs, vt[e] ; Vector Insert Nibble (4/4/4/4) (Sign Extended): VINSN VD,VS,VT[ELEMENT] (Reserved)
216 |
217 | // vnull ; Vector Null Instruction: VNULL (Reserved)
218 |
219 | // RSP CP2 Vector Load Instructions (LWC2):
220 | // lbv vt[e], offset(base) ; Load Byte To Vector: LBV VT[ELEMENT],$OFFSET(BASE)
221 | // lsv vt[e], offset(base) ; Load Short To Vector: LSV VT[ELEMENT],$OFFSET(BASE)
222 | // llv vt[e], offset(base) ; Load Long To Vector: LLV VT[ELEMENT],$OFFSET(BASE)
223 | // ldv vt[e], offset(base) ; Load Double To Vector: LDV VT[ELEMENT],$OFFSET(BASE)
224 | // lqv vt[e], offset(base) ; Load Quad To Vector: LQV VT[ELEMENT],$OFFSET(BASE)
225 | // lrv vt[e], offset(base) ; Load Rest To Vector: LRV VT[ELEMENT],$OFFSET(BASE)
226 | // lpv vt[e], offset(base) ; Load Packed Signed To Vector: LPV VT[ELEMENT],$OFFSET(BASE)
227 | // luv vt[e], offset(base) ; Load Packed Unsigned To Vector: LUV VT[ELEMENT],$OFFSET(BASE)
228 | // lhv vt[e], offset(base) ; Load Half Bytes To Vector: LHV VT[ELEMENT],$OFFSET(BASE)
229 | // lfv vt[e], offset(base) ; Load Fourth Bytes To Vector: LFV VT[ELEMENT],$OFFSET(BASE)
230 | // lwv vt[e], offset(base) ; Load Transposed Wrapped Bytes To Vector: LWV VT[ELEMENT],$OFFSET(BASE) (Reserved)
231 | // ltv vt[e], offset(base) ; Load Transposed Bytes To Vector: LTV VT[ELEMENT],$OFFSET(BASE)
232 |
233 | // RSP CP2 Vector Store Instructions (SWC2):
234 | // sbv vt[e], offset(base) ; Store Byte From Vector: SBV VT[ELEMENT],$OFFSET(BASE)
235 | // ssv vt[e], offset(base) ; Store Short From Vector: SSV VT[ELEMENT],$OFFSET(BASE)
236 | // slv vt[e], offset(base) ; Store Long From Vector: SLV VT[ELEMENT],$OFFSET(BASE)
237 | // sdv vt[e], offset(base) ; Store Double From Vector: SDV VT[ELEMENT],$OFFSET(BASE)
238 | // sqv vt[e], offset(base) ; Store Quad From Vector: SQV VT[ELEMENT],$OFFSET(BASE)
239 | // srv vt[e], offset(base) ; Store Rest From Vector: SRV VT[ELEMENT],$OFFSET(BASE)
240 | // spv vt[e], offset(base) ; Store Packed Signed From Vector: SPV VT[ELEMENT],$OFFSET(BASE)
241 | // suv vt[e], offset(base) ; Store Packed Unsigned From Vector: SUV VT[ELEMENT],$OFFSET(BASE)
242 | // shv vt[e], offset(base) ; Store Half Bytes From Vector: SHV VT[ELEMENT],$OFFSET(BASE)
243 | // sfv vt[e], offset(base) ; Store Fourth Bytes From Vector: SFV VT[ELEMENT],$OFFSET(BASE)
244 | // swv vt[e], offset(base) ; Store Transposed Wrapped Bytes From Vector: SWV VT[ELEMENT],$OFFSET(BASE)
245 | // stv vt[e], offset(base) ; Store Transposed Bytes From Vector: STV VT[ELEMENT],$OFFSET(BASE)
--------------------------------------------------------------------------------
/N64/LIB/N64_SYS.INC:
--------------------------------------------------------------------------------
1 | macro sys_get_clock() {
2 | jal sys_get_clock
3 | nop
4 | }
5 |
6 | macro sys_random(min, max) {
7 | li a0, {min}
8 | li a1, {max}
9 | jal sys_random
10 | nop
11 | }
12 |
13 | macro sys_zero_fill(start, length) {
14 | li a0, {start}
15 | li a1, {length}
16 | jal sys_zero_fill
17 | nop
18 | }
19 |
20 | macro sys_max_fill(start, length) {
21 | li a0, {start}
22 | li a1, {length}
23 | jal sys_max_fill
24 | nop
25 | }
26 |
27 | macro sys_count_start1() {
28 | jal sys_count_start1
29 | nop
30 | }
31 |
32 | macro sys_count_end1() {
33 | jal sys_count_end1
34 | nop
35 | }
36 |
37 | macro sys_count_diff1() {
38 | jal sys_count_diff1
39 | nop
40 | }
41 |
42 | macro sys_count_start2() {
43 | jal sys_count_start2
44 | nop
45 | }
46 |
47 | macro sys_count_end2() {
48 | jal sys_count_end2
49 | nop
50 | }
51 |
52 | macro sys_count_diff2() {
53 | jal sys_count_diff2
54 | nop
55 | }
56 |
57 | macro sys_count_start3() {
58 | jal sys_count_start3
59 | nop
60 | }
61 |
62 | macro sys_count_end3() {
63 | jal sys_count_end3
64 | nop
65 | }
66 |
67 | macro sys_count_diff3() {
68 | jal sys_count_diff3
69 | nop
70 | }
71 |
72 | macro sys_count_start4() {
73 | jal sys_count_start4
74 | nop
75 | }
76 |
77 | macro sys_count_end4() {
78 | jal sys_count_end4
79 | nop
80 | }
81 |
82 | macro sys_count_diff4() {
83 | jal sys_count_diff4
84 | nop
85 | }
--------------------------------------------------------------------------------
/N64/LIB/N64_SYS.S:
--------------------------------------------------------------------------------
1 | // Some functions work some don't, Sorry
2 | constant mi_mask_clear_sp($0001)
3 | constant mi_mask_set_sp($0002)
4 | constant mi_mask_clear_si($0004)
5 | constant mi_mask_set_si($0008)
6 | constant mi_mask_clear_ai($0010)
7 | constant mi_mask_set_ai($0020)
8 | constant mi_mask_clear_vi($0040)
9 | constant mi_mask_set_vi($0080)
10 | constant mi_mask_clear_pi($0100)
11 | constant mi_mask_set_pi($0200)
12 | constant mi_mask_clear_dp($0400)
13 | constant mi_mask_set_dp($0800)
14 |
15 | constant pi_clear_interrupt($0002)
16 | constant si_clear_interrupt($0000)
17 | constant sp_clear_interrupt($0008)
18 | constant dp_clear_interrupt($0800)
19 | constant ai_clear_interrupt($0000)
20 |
21 | constant color_depth_mask($0100'0000)
22 | constant resolution_mask($0001'0000)
23 | constant interlacing_mask($0000'0100)
24 | constant tv_format_mask($0000'0003)
25 |
26 | align(8)
27 | // Calls Exit in the 'middle'
28 | sys_get_clock:
29 | la t0, $8000'0300
30 | lw t0, 0(t0)
31 | nop
32 | bnel t0, r0, _sys_get_clock_check_ntsc
33 | addiu t0, t0, -1
34 | li v0, VI_PAL_CLOCK
35 | jr ra
36 | nop
37 | _sys_get_clock_check_ntsc:
38 | bnel t0, r0, _sys_get_clock_check_mpal
39 | addiu t0, t0, -1
40 | li v0, VI_NTSC_CLOCK
41 | jr ra
42 | nop
43 | _sys_get_clock_check_mpal:
44 | li v0, VI_MPAL_CLOCK
45 | jr ra
46 | nop
47 |
48 | sys_random:
49 | // a0 = r0 ignored for now
50 | // a1 = maximum
51 | // v0 @ return = random number
52 | // t0 System Video Clock
53 | // t1 Current Video Line
54 | // t2 Current Counter Value
55 | STACK_PUSH(ra)
56 | jal sys_get_clock
57 | nop
58 | sll t0, v0, 5
59 | la t1, (VI_BASE << 16) | VI_V_CURRENT_LINE
60 | lw t1, 0(t1)
61 | mfc0 t2, Count
62 | // Make 1 value of our 3 Entropies
63 | // t0 shifted left is largest
64 | // quickly add all the others
65 | // Div by maximum is where it gets random
66 | addu t0, t0, t1
67 | addu t0, t0, t2
68 | //subu a0, a1, a0 // Removes the minimum?
69 | divu t0, a1
70 | STACK_POP(ra)
71 | mfhi v0
72 | subu v0, v0, a0
73 | jr ra
74 | nop
75 | // These could incorporate DMA to make all memory moves identical
76 | sys_memcopy:
77 | _sys_memcopy_loop:
78 | lw t4, 0(a0)
79 | lw t5, 4(a0)
80 | lw t6, 8(a0)
81 | lw t7, 12(a0)
82 | sw t4, 0(a1)
83 | sw t5, 4(a1)
84 | sw t6, 8(a1)
85 | sw t7, 12(a1)
86 | addi t2, t2, -16
87 | addi t0, t0, 16
88 | bnel t2, r0, _sys_memcopy_loop
89 | addi t1, t1, 16
90 | jr ra
91 | nop
92 | sys_memmove:
93 | jr ra
94 | nop
95 | sys_move_bytes:
96 | jr ra
97 | nop
98 | sys_mem_parm_check:
99 | jr ra
100 | nop
101 | // Call Example
102 | // la a0, $8000'0000
103 | // li a1, 64
104 | // jal sys_zero_fill
105 | // nop
106 | // 4 byte aligned
107 | // max 16bit range
108 | sys_zero_fill:
109 | add t0, r0, r0
110 | andi a1, a1, $FFFC
111 | add t1, a0, a1
112 | sw t0, 0(a0)
113 | _sys_zero_fill_loop:
114 | addi a0, a0, 4
115 | bnel a0, t1, _sys_zero_fill_loop
116 | sw t0, 0(a0)
117 | jr ra
118 | nop
119 | // Call Example
120 | // la a0, $8000'0000
121 | // li a1, 64
122 | // jal sys_max_fill
123 | // nop
124 | // 4 byte aligned
125 | // max 16bit range
126 | sys_max_fill:
127 | addiu t0, r0, -1
128 | andi a1, a1, $FFFC
129 | add t1, a0, a1
130 | sw t0, 0(a0)
131 | _sys_max_fill_loop:
132 | addi a0, a0, 4
133 | bnel a0, t1, _sys_max_fill_loop
134 | sw t0, 0(a0)
135 | jr ra
136 | nop
137 | // Assumed to spin cycles, i.e. nothing else happens
138 | // Example Logo Startup Screens
139 | sys_delay_ms:
140 | // a0 = ms
141 | STACK_PUSH(ra)
142 | jal sys_get_clock
143 | add t0, r0, v0
144 | multu a0, t0
145 | mfc0 t1, Count
146 | mflo t2
147 | add t2, t1, t2
148 | _sys_delay_ms_loop:
149 | mfc0 t1, Count
150 | // Not working yet
151 | STACK_POP(ra)
152 | jr ra
153 | nop
154 |
155 | // sys_count_*
156 | // Takes 187 Clock Cycles
157 | // Timing accuracy is far lower.
158 | // 0x5D = 93 Nothing
159 | // 0x71 = 113 ScreenNTSC Macro
160 | _sys_count_addr_start1:
161 | dw 0x0
162 | _sys_count_addr_end1:
163 | dw 0x0
164 | align(8)
165 | sys_count_start1: // 187 Count
166 | la v1, _sys_count_addr_start1
167 | mfc0 v0, Count // 93 Count
168 | jr ra
169 | sw v0, 0(v1)
170 |
171 | sys_count_end1:
172 | la v1, _sys_count_addr_end1
173 | mfc0 v0, Count
174 | jr ra
175 | sw v0, 0(v1)
176 |
177 | sys_count_diff1:
178 | la v0, _sys_count_addr_start1
179 | lw v0, 0(v0)
180 | la v1, _sys_count_addr_end1
181 | lw v1, 0(v1)
182 | addiu v0, v0, 93 // Remove 'overhead'
183 | jr ra
184 | subu v0, v1, v0
185 |
186 | _sys_count_addr_start2:
187 | dw 0x0
188 | _sys_count_addr_end2:
189 | dw 0x0
190 | align(8)
191 | sys_count_start2:
192 | la v1, _sys_count_addr_start2
193 | mfc0 v0, Count
194 | jr ra
195 | sw v0, 0(v1)
196 |
197 | sys_count_end2:
198 | la v1, _sys_count_addr_end2
199 | mfc0 v0, Count
200 | jr ra
201 | sw v0, 0(v1)
202 | sys_count_diff2:
203 | la v0, _sys_count_addr_start2
204 | lw v0, 0(v0)
205 | la v1, _sys_count_addr_end2
206 | lw v1, 0(v1)
207 | addiu v0, v0, 93 // Remove 'overhead'
208 | jr ra
209 | subu v0, v1, v0
210 |
211 | _sys_count_addr_start3:
212 | dw 0x0
213 | _sys_count_addr_end3:
214 | dw 0x0
215 | align(8)
216 | sys_count_start3:
217 | la v1, _sys_count_addr_start3
218 | mfc0 v0, Count
219 | jr ra
220 | sw v0, 0(v1)
221 |
222 | sys_count_end3:
223 | la v1, _sys_count_addr_end3
224 | mfc0 v0, Count
225 | jr ra
226 | sw v0, 0(v1)
227 | sys_count_diff3:
228 | la v0, _sys_count_addr_start3
229 | lw v0, 0(v0)
230 | la v1, _sys_count_addr_end3
231 | lw v1, 0(v1)
232 | addiu v0, v0, 93 // Remove 'overhead'
233 | jr ra
234 | subu v0, v1, v0
235 |
236 | _sys_count_addr_start4:
237 | dw 0x0
238 | _sys_count_addr_end4:
239 | dw 0x0
240 | align(8)
241 | sys_count_start4:
242 | la v1, _sys_count_addr_start4
243 | mfc0 v0, Count
244 | jr ra
245 | sw v0, 0(v1)
246 |
247 | sys_count_end4:
248 | la v1, _sys_count_addr_end4
249 | mfc0 v0, Count
250 | jr ra
251 | sw v0, 0(v1)
252 | sys_count_diff4:
253 | la v0, _sys_count_addr_start4
254 | lw v0, 0(v0)
255 | la v1, _sys_count_addr_end4
256 | lw v1, 0(v1)
257 | addiu v0, v0, 93 // Remove 'overhead'
258 | jr ra
259 | subu v0, v1, v0
260 |
--------------------------------------------------------------------------------
/N64/LIB/N64_SYSCALL_MARS.S:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 |
4 | //define DEBUG_SHOW_STATIC_VALUE(yes)
5 |
6 | // Based on http://courses.missouristate.edu/kenvollmar/mars/help/syscallhelp.html
7 | align(8)
8 | syscall_mars:
9 | interrupt_register_save()
10 | la t0, SYSCALL_Handlers
11 | sll t1, v0, 2
12 | lw t0, 0(t1)
13 | jr t0
14 |
15 | _syscall_1:
16 | // Printer Integer
17 | // $a0 = integer to print
18 | _syscall_2:
19 | // Printer Float
20 | // $f12 = float to print
21 | _syscall_3:
22 | // Printer Double
23 | // $f12 = double to print
24 | _syscall_4:
25 | // Printer String
26 | // $a0 = address of null-terminated string to print
27 | _syscall_5:
28 | // Read Integer
29 | // $v0 contains integer read
30 | _syscall_6:
31 | // Read Float
32 | // $f0 contains float read
33 | _syscall_7:
34 | // Read Double
35 | // $f0 contains double read
36 | _syscall_8:
37 | // Read String
38 | // $a0 = address of input buffer
39 | // $a1 = maximum number of characters to read
40 | // Service 8 - Follows semantics of UNIX 'fgets'. For specified length n,
41 | // string can be no longer than n-1. If less than that, adds newline to end.
42 | // In either case, then pads with null byte If n = 1, input is ignored and
43 | // null byte placed at buffer address. If n < 1, input is ignored and nothing
44 | // is written to the buffer.
45 | _syscall_9:
46 | // sbrk (allocate heap memory)
47 | // $a0 = number of bytes to allocate
48 | // $v0 contains address of allocated memory
49 | _syscall_10:
50 | // exit (terminate execution)
51 | _syscall_11:
52 | // $a0 = character to print
53 | // Service 11 - Prints ASCII character corresponding to contents of low-order byte.
54 | _syscall_12:
55 | // Read Character
56 | // $v0 contains character read
57 | _syscall_13:
58 | // open file
59 | // $a0 = address of null-terminated string containing filename
60 | // $a1 = flags
61 | // $a2 = mode
62 | // $v0 contains file descriptor (negative if error). See note below table
63 | _syscall_14:
64 | // read from file
65 | // $a0 = file descriptor
66 | // $a1 = address of input buffer
67 | // $a2 = maximum number of characters to read
68 | // $v0 contains number of characters read
69 | // (0 if end-of-file, negative if error).
70 | _syscall_15:
71 | // write to file
72 | // $a0 = file descriptor
73 | // $a1 = address of output buffer
74 | // $a2 = number of characters to write
75 | // $v0 contains number of characters written (negative if error).
76 | _syscall_16:
77 | // close file
78 | // $a0 = file descriptor
79 | _syscall_17:
80 | // exit2 (terminate with value)
81 | // $a0 = termination result
82 | interrupt_register_restore()
83 | jr ra
84 | nop
85 |
86 | //fixed_gap(_tlb_handler, 0x40)
87 | SYSCALL_Handlers:
88 | // Interrupt
89 | syscall_01_handler_ptr:
90 | static_value(DEBUG_SHOW_STATIC_VALUE, dw 0x0, db "PInt")
91 |
--------------------------------------------------------------------------------
/N64/LIB/README.md:
--------------------------------------------------------------------------------
1 | # N64 LIB Conventions
2 | ## File Extensions
3 | * INC - Contain ONLY constants and macros
4 | * S - Code called with Jump or Branch instructions, may use global variables
5 | In some cases there is an INC and an S file, that have to be used together
6 |
7 | To use the files:
8 | The *.INC should always be at the top of the source file, similar to the #include statement in C.
9 |
10 | The *.S files should be included in the code near where it's used or before/after specific sections based on the desired ROM layout.
11 |
12 | Inside each file the following code patterns apply
13 |
14 | * The underscore _ prefixes labels and macros that are for internal use only.
15 |
16 |
--------------------------------------------------------------------------------
/N64/Lesson1/bass-win.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/Lesson1/bass-win.zip
--------------------------------------------------------------------------------
/N64/Lesson2/Lesson2.N64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/Lesson2/Lesson2.N64
--------------------------------------------------------------------------------
/N64/Lesson2/Lesson2.asm:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 | output "Lesson2.N64", create
4 | fill 1052672
5 |
6 | origin $00000000
7 | base $80000000
8 | include "../LIB/N64.INC"
9 | include "N64_HEADER.ASM"
10 | insert "../LIB/N64_BOOTCODE.BIN"
11 |
12 | Start:
13 | lui t0,$BFC0
14 | addi t1,r0,8
15 | sw t1,$7FC(t0)
16 |
17 | Loop:
18 | j Loop
19 | nop // Delay Slot
--------------------------------------------------------------------------------
/N64/Lesson2/N64_Header.asm:
--------------------------------------------------------------------------------
1 | //============
2 | // N64 Header
3 | //============
4 | // PI_BSB_DOM1
5 | db $80 // Initial PI_BSB_DOM1_LAT_REG Value
6 | db $37 // Initial PI_BSB_DOM1_PGS_REG Value
7 | db $12 // Initial PI_BSB_DOM1_PWD_REG Value
8 | db $40 // Initial PI_BSB_DOM1_PGS_REG Value
9 |
10 | // CLOCK RATE
11 | dw $000F // Initial Clock Rate
12 |
13 | // VECTOR
14 | dw Start // Boot Address Offset
15 | dw $1444 // Release Offset
16 |
17 | // COMPLEMENT CHECK & CHECKSUM
18 | db "CRC1" // CRC1: COMPLEMENT CHECK
19 | db "CRC2" // CRC2: CHECKSUM
20 |
21 | dd 0 // UNUSED
22 |
23 | // PROGRAM TITLE (27 Byte ASCII String, Use Spaces For Unused Bytes)
24 | db "Lesson 2 "
25 | // "123456789012345678901234567"
26 |
27 | // DEVELOPER ID CODE
28 | db $00 // "N" = Nintendo
29 |
30 | // CARTRIDGE ID CODE
31 | db $00
32 |
33 | db 0 // UNUSED
34 |
35 | // COUNTRY CODE
36 | db $00 // "D" = Germany, "E" = USA, "J" = Japan, "P" = Europe, "U" = Australia
37 |
38 | db 0 // UNUSED
--------------------------------------------------------------------------------
/N64/Lesson2/make.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | set rom_name=Lesson2.N64
3 | REM Space seperated list of source files
4 | set source_files=Lesson2.asm
5 |
6 | if exist %rom_name% (
7 | del /q %rom_name%
8 | )
9 | bass -strict -o %rom_name% %source_files%
10 | if exist %rom_name% (
11 | @chksum64 %rom_name%
12 | )
--------------------------------------------------------------------------------
/N64/Template/N64_Header.asm:
--------------------------------------------------------------------------------
1 | //============
2 | // N64 Header
3 | //============
4 | // PI_BSB_DOM1
5 | db $80 // Initial PI_BSB_DOM1_LAT_REG Value
6 | db $37 // Initial PI_BSB_DOM1_PGS_REG Value
7 | db $12 // Initial PI_BSB_DOM1_PWD_REG Value
8 | db $40 // Initial PI_BSB_DOM1_PGS_REG Value
9 |
10 | // CLOCK RATE
11 | dw $000F // Initial Clock Rate
12 |
13 | // VECTOR
14 | dw Start // Boot Address Offset
15 | dw $1444 // Release Offset
16 |
17 | // COMPLEMENT CHECK & CHECKSUM
18 | db "CRC1" // CRC1: COMPLEMENT CHECK
19 | db "CRC2" // CRC2: CHECKSUM
20 |
21 | dd 0 // UNUSED
22 |
23 | // PROGRAM TITLE (27 Byte ASCII String, Use Spaces For Unused Bytes)
24 | db "Template "
25 | // "123456789012345678901234567"
26 |
27 | // DEVELOPER ID CODE
28 | db $00 // "N" = Nintendo
29 |
30 | // CARTRIDGE ID CODE
31 | db $00
32 |
33 | db 0 // UNUSED
34 |
35 | // COUNTRY CODE
36 | db $00 // "D" = Germany, "E" = USA, "J" = Japan, "P" = Europe, "U" = Australia
37 |
38 | db 0 // UNUSED
--------------------------------------------------------------------------------
/N64/Template/Template.N64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraser125/N64-ASM-Tutorial/90743405d5befe765c28ee8cb8df80f58dc67dd7/N64/Template/Template.N64
--------------------------------------------------------------------------------
/N64/Template/make.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | set rom_name=Template.N64
3 | REM Space seperated list of source files
4 | set source_files=Template.asm
5 |
6 | if exist %rom_name% (
7 | del /q %rom_name%
8 | )
9 | bass -strict -create %1 -o %rom_name% %source_files%
10 | if exist %rom_name% (
11 | @chksum64 %rom_name%
12 | )
--------------------------------------------------------------------------------
/N64/Template/template.asm:
--------------------------------------------------------------------------------
1 | arch n64.cpu
2 | endian msb
3 | fill 1052672
4 |
5 | origin $00000000
6 | base $80000000
7 | include "../LIB/N64.INC"
8 | include "./N64_HEADER.ASM" // Include 64 Byte Header & Vector Table
9 | insert "../LIB/N64_BOOTCODE.BIN" // Include 4032 Byte Boot Code
10 | force_pc($80001000)
11 | Start:
12 | align(8)
13 | N64_INIT()
14 | ScreenNTSC(320, 240, BPP32, $A0100000) // Screen NTSC: 320x240, 32BPP, DRAM Origin $A0100000
15 | // Insert Initialization Code
16 | Loop:
17 | // Insert Looping Code Here
18 | j Loop
19 | nop // Delay Slot
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # N64-ASM-Tutorial
2 | The support files for N64 Assembly Language Tutorial that is hosted: https://sites.google.com/site/consoleprotocols/home/homebrew/n64-assembly-home
3 |
4 | * Lesson 1: [Environment](https://sites.google.com/site/consoleprotocols/home/homebrew/n64-assembly-home/Lesson01)
5 | * Lesson 2: [Minimum Code](https://sites.google.com/site/consoleprotocols/home/homebrew/n64-assembly-home/Lesson02)
6 |
--------------------------------------------------------------------------------
/gobass.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | path=c:\bass\bin;c:\bass\include;c:\bass\lib;c:\mame;%path%;
--------------------------------------------------------------------------------