1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2005-2006 Forgotten and the VBA development team
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2, or(at your option)
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include "GBAinline.h"
28 s16 sineTable
[256] = {
29 (s16
)0x0000, (s16
)0x0192, (s16
)0x0323, (s16
)0x04B5, (s16
)0x0645, (s16
)0x07D5, (s16
)0x0964, (s16
)0x0AF1,
30 (s16
)0x0C7C, (s16
)0x0E05, (s16
)0x0F8C, (s16
)0x1111, (s16
)0x1294, (s16
)0x1413, (s16
)0x158F, (s16
)0x1708,
31 (s16
)0x187D, (s16
)0x19EF, (s16
)0x1B5D, (s16
)0x1CC6, (s16
)0x1E2B, (s16
)0x1F8B, (s16
)0x20E7, (s16
)0x223D,
32 (s16
)0x238E, (s16
)0x24DA, (s16
)0x261F, (s16
)0x275F, (s16
)0x2899, (s16
)0x29CD, (s16
)0x2AFA, (s16
)0x2C21,
33 (s16
)0x2D41, (s16
)0x2E5A, (s16
)0x2F6B, (s16
)0x3076, (s16
)0x3179, (s16
)0x3274, (s16
)0x3367, (s16
)0x3453,
34 (s16
)0x3536, (s16
)0x3612, (s16
)0x36E5, (s16
)0x37AF, (s16
)0x3871, (s16
)0x392A, (s16
)0x39DA, (s16
)0x3A82,
35 (s16
)0x3B20, (s16
)0x3BB6, (s16
)0x3C42, (s16
)0x3CC5, (s16
)0x3D3E, (s16
)0x3DAE, (s16
)0x3E14, (s16
)0x3E71,
36 (s16
)0x3EC5, (s16
)0x3F0E, (s16
)0x3F4E, (s16
)0x3F84, (s16
)0x3FB1, (s16
)0x3FD3, (s16
)0x3FEC, (s16
)0x3FFB,
37 (s16
)0x4000, (s16
)0x3FFB, (s16
)0x3FEC, (s16
)0x3FD3, (s16
)0x3FB1, (s16
)0x3F84, (s16
)0x3F4E, (s16
)0x3F0E,
38 (s16
)0x3EC5, (s16
)0x3E71, (s16
)0x3E14, (s16
)0x3DAE, (s16
)0x3D3E, (s16
)0x3CC5, (s16
)0x3C42, (s16
)0x3BB6,
39 (s16
)0x3B20, (s16
)0x3A82, (s16
)0x39DA, (s16
)0x392A, (s16
)0x3871, (s16
)0x37AF, (s16
)0x36E5, (s16
)0x3612,
40 (s16
)0x3536, (s16
)0x3453, (s16
)0x3367, (s16
)0x3274, (s16
)0x3179, (s16
)0x3076, (s16
)0x2F6B, (s16
)0x2E5A,
41 (s16
)0x2D41, (s16
)0x2C21, (s16
)0x2AFA, (s16
)0x29CD, (s16
)0x2899, (s16
)0x275F, (s16
)0x261F, (s16
)0x24DA,
42 (s16
)0x238E, (s16
)0x223D, (s16
)0x20E7, (s16
)0x1F8B, (s16
)0x1E2B, (s16
)0x1CC6, (s16
)0x1B5D, (s16
)0x19EF,
43 (s16
)0x187D, (s16
)0x1708, (s16
)0x158F, (s16
)0x1413, (s16
)0x1294, (s16
)0x1111, (s16
)0x0F8C, (s16
)0x0E05,
44 (s16
)0x0C7C, (s16
)0x0AF1, (s16
)0x0964, (s16
)0x07D5, (s16
)0x0645, (s16
)0x04B5, (s16
)0x0323, (s16
)0x0192,
45 (s16
)0x0000, (s16
)0xFE6E, (s16
)0xFCDD, (s16
)0xFB4B, (s16
)0xF9BB, (s16
)0xF82B, (s16
)0xF69C, (s16
)0xF50F,
46 (s16
)0xF384, (s16
)0xF1FB, (s16
)0xF074, (s16
)0xEEEF, (s16
)0xED6C, (s16
)0xEBED, (s16
)0xEA71, (s16
)0xE8F8,
47 (s16
)0xE783, (s16
)0xE611, (s16
)0xE4A3, (s16
)0xE33A, (s16
)0xE1D5, (s16
)0xE075, (s16
)0xDF19, (s16
)0xDDC3,
48 (s16
)0xDC72, (s16
)0xDB26, (s16
)0xD9E1, (s16
)0xD8A1, (s16
)0xD767, (s16
)0xD633, (s16
)0xD506, (s16
)0xD3DF,
49 (s16
)0xD2BF, (s16
)0xD1A6, (s16
)0xD095, (s16
)0xCF8A, (s16
)0xCE87, (s16
)0xCD8C, (s16
)0xCC99, (s16
)0xCBAD,
50 (s16
)0xCACA, (s16
)0xC9EE, (s16
)0xC91B, (s16
)0xC851, (s16
)0xC78F, (s16
)0xC6D6, (s16
)0xC626, (s16
)0xC57E,
51 (s16
)0xC4E0, (s16
)0xC44A, (s16
)0xC3BE, (s16
)0xC33B, (s16
)0xC2C2, (s16
)0xC252, (s16
)0xC1EC, (s16
)0xC18F,
52 (s16
)0xC13B, (s16
)0xC0F2, (s16
)0xC0B2, (s16
)0xC07C, (s16
)0xC04F, (s16
)0xC02D, (s16
)0xC014, (s16
)0xC005,
53 (s16
)0xC000, (s16
)0xC005, (s16
)0xC014, (s16
)0xC02D, (s16
)0xC04F, (s16
)0xC07C, (s16
)0xC0B2, (s16
)0xC0F2,
54 (s16
)0xC13B, (s16
)0xC18F, (s16
)0xC1EC, (s16
)0xC252, (s16
)0xC2C2, (s16
)0xC33B, (s16
)0xC3BE, (s16
)0xC44A,
55 (s16
)0xC4E0, (s16
)0xC57E, (s16
)0xC626, (s16
)0xC6D6, (s16
)0xC78F, (s16
)0xC851, (s16
)0xC91B, (s16
)0xC9EE,
56 (s16
)0xCACA, (s16
)0xCBAD, (s16
)0xCC99, (s16
)0xCD8C, (s16
)0xCE87, (s16
)0xCF8A, (s16
)0xD095, (s16
)0xD1A6,
57 (s16
)0xD2BF, (s16
)0xD3DF, (s16
)0xD506, (s16
)0xD633, (s16
)0xD767, (s16
)0xD8A1, (s16
)0xD9E1, (s16
)0xDB26,
58 (s16
)0xDC72, (s16
)0xDDC3, (s16
)0xDF19, (s16
)0xE075, (s16
)0xE1D5, (s16
)0xE33A, (s16
)0xE4A3, (s16
)0xE611,
59 (s16
)0xE783, (s16
)0xE8F8, (s16
)0xEA71, (s16
)0xEBED, (s16
)0xED6C, (s16
)0xEEEF, (s16
)0xF074, (s16
)0xF1FB,
60 (s16
)0xF384, (s16
)0xF50F, (s16
)0xF69C, (s16
)0xF82B, (s16
)0xF9BB, (s16
)0xFB4B, (s16
)0xFCDD, (s16
)0xFE6E
66 if(systemVerbose
& VERBOSE_SWI
) {
67 log("ArcTan: %08x (VCOUNT=%2d)\n",
73 s32 a
= -(((s32
)(reg
[0].I
*reg
[0].I
)) >> 14);
74 s32 b
= ((0xA9 * a
) >> 14) + 0x390;
75 b
= ((b
* a
) >> 14) + 0x91C;
76 b
= ((b
* a
) >> 14) + 0xFB6;
77 b
= ((b
* a
) >> 14) + 0x16AA;
78 b
= ((b
* a
) >> 14) + 0x2081;
79 b
= ((b
* a
) >> 14) + 0x3651;
80 b
= ((b
* a
) >> 14) + 0xA2F9;
81 a
= ((s32
)reg
[0].I
* b
) >> 16;
85 if(systemVerbose
& VERBOSE_SWI
) {
86 log("ArcTan: return=%08x\n",
95 if(systemVerbose
& VERBOSE_SWI
) {
96 log("ArcTan2: %08x,%08x (VCOUNT=%2d)\n",
107 res
= ((x
>>16) & 0x8000);
110 res
= ((y
>>16) & 0x8000) + 0x4000;
112 if ((abs(x
) > abs(y
)) || ((abs(x
) == abs(y
)) && (!((x
<0) && (y
<0))))) {
118 res
= 0x8000 + reg
[0].I
;
120 res
= (((y
>>16) & 0x8000)<<1) + reg
[0].I
;
125 res
= (0x4000 + ((y
>>16) & 0x8000)) - reg
[0].I
;
132 if(systemVerbose
& VERBOSE_SWI
) {
133 log("ArcTan2: return=%08x\n",
139 void BIOS_BitUnPack()
142 if(systemVerbose
& VERBOSE_SWI
) {
143 log("BitUnPack: %08x,%08x,%08x (VCOUNT=%2d)\n",
151 u32 source
= reg
[0].I
;
153 u32 header
= reg
[2].I
;
155 int len
= CPUReadHalfWord(header
);
157 if(((source
& 0xe000000) == 0) ||
158 ((source
+ len
) & 0xe000000) == 0)
161 int bits
= CPUReadByte(header
+2);
162 int revbits
= 8 - bits
;
164 u32 base
= CPUReadMemory(header
+4);
165 bool addBase
= (base
& 0x80000000) ? true : false;
167 int dataSize
= CPUReadByte(header
+3);
170 int bitwritecount
= 0;
175 int mask
= 0xff >> revbits
;
176 u8 b
= CPUReadByte(source
);
183 u32 temp
= d
>> bitcount
;
187 data
|= temp
<< bitwritecount
;
188 bitwritecount
+= dataSize
;
189 if(bitwritecount
>= 32) {
190 CPUWriteMemory(dest
, data
);
201 void BIOS_GetBiosChecksum()
206 void BIOS_BgAffineSet()
209 if(systemVerbose
& VERBOSE_SWI
) {
210 log("BgAffineSet: %08x,%08x,%08x (VCOUNT=%2d)\n",
222 for(int i
= 0; i
< num
; i
++) {
223 s32 cx
= CPUReadMemory(src
);
225 s32 cy
= CPUReadMemory(src
);
227 s16 dispx
= CPUReadHalfWord(src
);
229 s16 dispy
= CPUReadHalfWord(src
);
231 s16 rx
= CPUReadHalfWord(src
);
233 s16 ry
= CPUReadHalfWord(src
);
235 u16 theta
= CPUReadHalfWord(src
)>>8;
236 src
+=4; // keep structure alignment
237 s32 a
= sineTable
[(theta
+0x40)&255];
238 s32 b
= sineTable
[theta
];
240 s16 dx
= (rx
* a
)>>14;
241 s16 dmx
= (rx
* b
)>>14;
242 s16 dy
= (ry
* b
)>>14;
243 s16 dmy
= (ry
* a
)>>14;
245 CPUWriteHalfWord(dest
, dx
);
247 CPUWriteHalfWord(dest
, -dmx
);
249 CPUWriteHalfWord(dest
, dy
);
251 CPUWriteHalfWord(dest
, dmy
);
254 s32 startx
= cx
- dx
* dispx
+ dmx
* dispy
;
255 s32 starty
= cy
- dy
* dispx
- dmy
* dispy
;
257 CPUWriteMemory(dest
, startx
);
259 CPUWriteMemory(dest
, starty
);
267 if(systemVerbose
& VERBOSE_SWI
) {
268 log("CpuSet: 0x%08x,0x%08x,0x%08x (VCOUNT=%d)\n", reg
[0].I
, reg
[1].I
,
273 u32 source
= reg
[0].I
;
277 if(((source
& 0xe000000) == 0) ||
278 ((source
+ (((cnt
<< 11)>>9) & 0x1fffff)) & 0xe000000) == 0)
281 int count
= cnt
& 0x1FFFFF;
284 if((cnt
>> 26) & 1) {
285 // needed for 32-bit mode!
286 source
&= 0xFFFFFFFC;
289 if((cnt
>> 24) & 1) {
290 u32 value
= (source
>0x0EFFFFFF ? 0x1CAD1CAD : CPUReadMemory(source
));
292 CPUWriteMemory(dest
, value
);
299 CPUWriteMemory(dest
, (source
>0x0EFFFFFF ? 0x1CAD1CAD : CPUReadMemory(source
)));
307 if((cnt
>> 24) & 1) {
308 u16 value
= (source
>0x0EFFFFFF ? 0x1CAD : CPUReadHalfWord(source
));
310 CPUWriteHalfWord(dest
, value
);
317 CPUWriteHalfWord(dest
, (source
>0x0EFFFFFF ? 0x1CAD : CPUReadHalfWord(source
)));
326 void BIOS_CpuFastSet()
329 if(systemVerbose
& VERBOSE_SWI
) {
330 log("CpuFastSet: 0x%08x,0x%08x,0x%08x (VCOUNT=%d)\n", reg
[0].I
, reg
[1].I
,
335 u32 source
= reg
[0].I
;
339 if(((source
& 0xe000000) == 0) ||
340 ((source
+ (((cnt
<< 11)>>9) & 0x1fffff)) & 0xe000000) == 0)
343 // needed for 32-bit mode!
344 source
&= 0xFFFFFFFC;
347 int count
= cnt
& 0x1FFFFF;
350 if((cnt
>> 24) & 1) {
352 // BIOS always transfers 32 bytes at a time
353 u32 value
= (source
>0x0EFFFFFF ? 0xBAFFFFFB : CPUReadMemory(source
));
354 for(int i
= 0; i
< 8; i
++) {
355 CPUWriteMemory(dest
, value
);
363 // BIOS always transfers 32 bytes at a time
364 for(int i
= 0; i
< 8; i
++) {
365 CPUWriteMemory(dest
, (source
>0x0EFFFFFF ? 0xBAFFFFFB :CPUReadMemory(source
)));
374 void BIOS_Diff8bitUnFilterWram()
377 if(systemVerbose
& VERBOSE_SWI
) {
378 log("Diff8bitUnFilterWram: 0x%08x,0x%08x (VCOUNT=%d)\n", reg
[0].I
,
383 u32 source
= reg
[0].I
;
386 u32 header
= CPUReadMemory(source
);
389 if(((source
& 0xe000000) == 0) ||
390 ((source
+ ((header
>> 8) & 0x1fffff) & 0xe000000) == 0))
393 int len
= header
>> 8;
395 u8 data
= CPUReadByte(source
++);
396 CPUWriteByte(dest
++, data
);
400 u8 diff
= CPUReadByte(source
++);
402 CPUWriteByte(dest
++, data
);
407 void BIOS_Diff8bitUnFilterVram()
410 if(systemVerbose
& VERBOSE_SWI
) {
411 log("Diff8bitUnFilterVram: 0x%08x,0x%08x (VCOUNT=%d)\n", reg
[0].I
,
416 u32 source
= reg
[0].I
;
419 u32 header
= CPUReadMemory(source
);
422 if(((source
& 0xe000000) == 0) ||
423 ((source
+ ((header
>> 8) & 0x1fffff)) & 0xe000000) == 0)
426 int len
= header
>> 8;
428 u8 data
= CPUReadByte(source
++);
429 u16 writeData
= data
;
434 u8 diff
= CPUReadByte(source
++);
436 writeData
|= (data
<< shift
);
440 CPUWriteHalfWord(dest
, writeData
);
450 void BIOS_Diff16bitUnFilter()
453 if(systemVerbose
& VERBOSE_SWI
) {
454 log("Diff16bitUnFilter: 0x%08x,0x%08x (VCOUNT=%d)\n", reg
[0].I
,
459 u32 source
= reg
[0].I
;
462 u32 header
= CPUReadMemory(source
);
465 if(((source
& 0xe000000) == 0) ||
466 ((source
+ ((header
>> 8) & 0x1fffff)) & 0xe000000) == 0)
469 int len
= header
>> 8;
471 u16 data
= CPUReadHalfWord(source
);
473 CPUWriteHalfWord(dest
, data
);
478 u16 diff
= CPUReadHalfWord(source
);
481 CPUWriteHalfWord(dest
, data
);
490 if(systemVerbose
& VERBOSE_SWI
) {
491 log("Div: 0x%08x,0x%08x (VCOUNT=%d)\n",
498 int number
= reg
[0].I
;
499 int denom
= reg
[1].I
;
502 reg
[0].I
= number
/ denom
;
503 reg
[1].I
= number
% denom
;
504 s32 temp
= (s32
)reg
[0].I
;
505 reg
[3].I
= temp
< 0 ? (u32
)-temp
: (u32
)temp
;
508 if(systemVerbose
& VERBOSE_SWI
) {
509 log("Div: return=0x%08x,0x%08x,0x%08x\n",
520 if(systemVerbose
& VERBOSE_SWI
) {
521 log("DivARM: 0x%08x, (VCOUNT=%d)\n",
533 void BIOS_HuffUnComp()
536 if(systemVerbose
& VERBOSE_SWI
) {
537 log("HuffUnComp: 0x%08x,0x%08x (VCOUNT=%d)\n",
544 u32 source
= reg
[0].I
;
547 u32 header
= CPUReadMemory(source
);
550 if(((source
& 0xe000000) == 0) ||
551 ((source
+ ((header
>> 8) & 0x1fffff)) & 0xe000000) == 0)
554 u8 treeSize
= CPUReadByte(source
++);
556 u32 treeStart
= source
;
558 source
+= ((treeSize
+1)<<1)-1; // minus because we already skipped one byte
560 int len
= header
>> 8;
562 u32 mask
= 0x80000000;
563 u32 data
= CPUReadMemory(source
);
567 u8 rootNode
= CPUReadByte(treeStart
);
568 u8 currentNode
= rootNode
;
569 bool writeData
= false;
574 if((header
& 0x0F) == 8) {
580 pos
+= (((currentNode
& 0x3F)+1)<<1);
584 if(currentNode
& 0x40)
586 currentNode
= CPUReadByte(treeStart
+pos
+1);
589 if(currentNode
& 0x80)
591 currentNode
= CPUReadByte(treeStart
+pos
);
595 writeValue
|= (currentNode
<< byteShift
);
600 currentNode
= rootNode
;
606 CPUWriteMemory(dest
, writeValue
);
615 data
= CPUReadMemory(source
);
627 pos
+= (((currentNode
& 0x3F)+1)<<1);
631 if(currentNode
& 0x40)
633 currentNode
= CPUReadByte(treeStart
+pos
+1);
636 if(currentNode
& 0x80)
638 currentNode
= CPUReadByte(treeStart
+pos
);
643 value
|= currentNode
;
645 value
|= (currentNode
<<4);
649 writeValue
|= (value
<< byteShift
);
659 CPUWriteMemory(dest
, writeValue
);
666 currentNode
= rootNode
;
672 data
= CPUReadMemory(source
);
679 void BIOS_LZ77UnCompVram()
682 if(systemVerbose
& VERBOSE_SWI
) {
683 log("LZ77UnCompVram: 0x%08x,0x%08x (VCOUNT=%d)\n",
690 u32 source
= reg
[0].I
;
693 u32 header
= CPUReadMemory(source
);
696 if(((source
& 0xe000000) == 0) ||
697 ((source
+ ((header
>> 8) & 0x1fffff)) & 0xe000000) == 0)
704 int len
= header
>> 8;
707 u8 d
= CPUReadByte(source
++);
710 for(int i
= 0; i
< 8; i
++) {
712 u16 data
= CPUReadByte(source
++) << 8;
713 data
|= CPUReadByte(source
++);
714 int length
= (data
>> 12) + 3;
715 int offset
= (data
& 0x0FFF);
716 u32 windowOffset
= dest
+ byteCount
- offset
- 1;
717 for(int i
= 0; i
< length
; i
++) {
718 writeValue
|= (CPUReadByte(windowOffset
++) << byteShift
);
723 CPUWriteHalfWord(dest
, writeValue
);
734 writeValue
|= (CPUReadByte(source
++) << byteShift
);
738 CPUWriteHalfWord(dest
, writeValue
);
751 for(int i
= 0; i
< 8; i
++) {
752 writeValue
|= (CPUReadByte(source
++) << byteShift
);
756 CPUWriteHalfWord(dest
, writeValue
);
770 void BIOS_LZ77UnCompWram()
773 if(systemVerbose
& VERBOSE_SWI
) {
774 log("LZ77UnCompWram: 0x%08x,0x%08x (VCOUNT=%d)\n", reg
[0].I
, reg
[1].I
,
779 u32 source
= reg
[0].I
;
782 u32 header
= CPUReadMemory(source
);
785 if(((source
& 0xe000000) == 0) ||
786 ((source
+ ((header
>> 8) & 0x1fffff)) & 0xe000000) == 0)
789 int len
= header
>> 8;
792 u8 d
= CPUReadByte(source
++);
795 for(int i
= 0; i
< 8; i
++) {
797 u16 data
= CPUReadByte(source
++) << 8;
798 data
|= CPUReadByte(source
++);
799 int length
= (data
>> 12) + 3;
800 int offset
= (data
& 0x0FFF);
801 u32 windowOffset
= dest
- offset
- 1;
802 for(int i
= 0; i
< length
; i
++) {
803 CPUWriteByte(dest
++, CPUReadByte(windowOffset
++));
809 CPUWriteByte(dest
++, CPUReadByte(source
++));
817 for(int i
= 0; i
< 8; i
++) {
818 CPUWriteByte(dest
++, CPUReadByte(source
++));
827 void BIOS_ObjAffineSet()
830 if(systemVerbose
& VERBOSE_SWI
) {
831 log("ObjAffineSet: 0x%08x,0x%08x,0x%08x,0x%08x (VCOUNT=%d)\n",
843 int offset
= reg
[3].I
;
845 for(int i
= 0; i
< num
; i
++) {
846 s16 rx
= CPUReadHalfWord(src
);
848 s16 ry
= CPUReadHalfWord(src
);
850 u16 theta
= CPUReadHalfWord(src
)>>8;
851 src
+=4; // keep structure alignment
853 s32 a
= (s32
)sineTable
[(theta
+0x40)&255];
854 s32 b
= (s32
)sineTable
[theta
];
856 s16 dx
= ((s32
)rx
* a
)>>14;
857 s16 dmx
= ((s32
)rx
* b
)>>14;
858 s16 dy
= ((s32
)ry
* b
)>>14;
859 s16 dmy
= ((s32
)ry
* a
)>>14;
861 CPUWriteHalfWord(dest
, dx
);
863 CPUWriteHalfWord(dest
, -dmx
);
865 CPUWriteHalfWord(dest
, dy
);
867 CPUWriteHalfWord(dest
, dmy
);
872 void BIOS_RegisterRamReset(u32 flags
)
874 // no need to trace here. this is only called directly from GBA.cpp
875 // to emulate bios initialization
877 CPUUpdateRegister(0x0, 0x80);
882 memset(workRAM
, 0, 0x40000);
885 // clear internal RAM
886 memset(internalRAM
, 0, 0x7e00); // don't clear 0x7e00-0x7fff
890 memset(paletteRAM
, 0, 0x400);
894 memset(vram
, 0, 0x18000);
898 memset(oam
, 0, 0x400);
903 for(i
= 0; i
< 0x10; i
++)
904 CPUUpdateRegister(0x200+i
*2, 0);
906 for(i
= 0; i
< 0xF; i
++)
907 CPUUpdateRegister(0x4+i
*2, 0);
909 for(i
= 0; i
< 0x20; i
++)
910 CPUUpdateRegister(0x20+i
*2, 0);
912 for(i
= 0; i
< 0x18; i
++)
913 CPUUpdateRegister(0xb0+i
*2, 0);
915 CPUUpdateRegister(0x130, 0);
916 CPUUpdateRegister(0x20, 0x100);
917 CPUUpdateRegister(0x30, 0x100);
918 CPUUpdateRegister(0x26, 0x100);
919 CPUUpdateRegister(0x36, 0x100);
924 for(i
= 0; i
< 8; i
++)
925 CPUUpdateRegister(0x110+i
*2, 0);
926 CPUUpdateRegister(0x134, 0x8000);
927 for(i
= 0; i
< 7; i
++)
928 CPUUpdateRegister(0x140+i
*2, 0);
933 CPUWriteByte(0x4000084, 0);
934 CPUWriteByte(0x4000084, 0x80);
935 CPUWriteMemory(0x4000080, 0x880e0000);
936 CPUUpdateRegister(0x88, CPUReadHalfWord(0x4000088)&0x3ff);
937 CPUWriteByte(0x4000070, 0x70);
938 for(i
= 0; i
< 8; i
++)
939 CPUUpdateRegister(0x90+i
*2, 0);
940 CPUWriteByte(0x4000070, 0);
941 for(i
= 0; i
< 8; i
++)
942 CPUUpdateRegister(0x90+i
*2, 0);
943 CPUWriteByte(0x4000084, 0);
948 void BIOS_RegisterRamReset()
951 if(systemVerbose
& VERBOSE_SWI
) {
952 log("RegisterRamReset: 0x%08x (VCOUNT=%d)\n",
958 BIOS_RegisterRamReset(reg
[0].I
);
961 void BIOS_RLUnCompVram()
964 if(systemVerbose
& VERBOSE_SWI
) {
965 log("RLUnCompVram: 0x%08x,0x%08x (VCOUNT=%d)\n",
972 u32 source
= reg
[0].I
;
975 u32 header
= CPUReadMemory(source
& 0xFFFFFFFC);
978 if(((source
& 0xe000000) == 0) ||
979 ((source
+ ((header
>> 8) & 0x1fffff)) & 0xe000000) == 0)
982 int len
= header
>> 8;
988 u8 d
= CPUReadByte(source
++);
991 u8 data
= CPUReadByte(source
++);
993 for(int i
= 0;i
< l
; i
++) {
994 writeValue
|= (data
<< byteShift
);
999 CPUWriteHalfWord(dest
, writeValue
);
1011 for(int i
= 0; i
< l
; i
++) {
1012 writeValue
|= (CPUReadByte(source
++) << byteShift
);
1015 if(byteCount
== 2) {
1016 CPUWriteHalfWord(dest
, writeValue
);
1030 void BIOS_RLUnCompWram()
1033 if(systemVerbose
& VERBOSE_SWI
) {
1034 log("RLUnCompWram: 0x%08x,0x%08x (VCOUNT=%d)\n",
1041 u32 source
= reg
[0].I
;
1042 u32 dest
= reg
[1].I
;
1044 u32 header
= CPUReadMemory(source
& 0xFFFFFFFC);
1047 if(((source
& 0xe000000) == 0) ||
1048 ((source
+ ((header
>> 8) & 0x1fffff)) & 0xe000000) == 0)
1051 int len
= header
>> 8;
1054 u8 d
= CPUReadByte(source
++);
1057 u8 data
= CPUReadByte(source
++);
1059 for(int i
= 0;i
< l
; i
++) {
1060 CPUWriteByte(dest
++, data
);
1067 for(int i
= 0; i
< l
; i
++) {
1068 CPUWriteByte(dest
++, CPUReadByte(source
++));
1077 void BIOS_SoftReset()
1080 if(systemVerbose
& VERBOSE_SWI
) {
1081 log("SoftReset: (VCOUNT=%d)\n", VCOUNT
);
1087 armIrqEnable
= false;
1088 C_FLAG
= V_FLAG
= N_FLAG
= Z_FLAG
= false;
1089 reg
[13].I
= 0x03007F00;
1090 reg
[14].I
= 0x00000000;
1091 reg
[16].I
= 0x00000000;
1092 reg
[R13_IRQ
].I
= 0x03007FA0;
1093 reg
[R14_IRQ
].I
= 0x00000000;
1094 reg
[SPSR_IRQ
].I
= 0x00000000;
1095 reg
[R13_SVC
].I
= 0x03007FE0;
1096 reg
[R14_SVC
].I
= 0x00000000;
1097 reg
[SPSR_SVC
].I
= 0x00000000;
1098 u8 b
= internalRAM
[0x7ffa];
1100 memset(&internalRAM
[0x7e00], 0, 0x200);
1103 armNextPC
= 0x02000000;
1104 reg
[15].I
= 0x02000004;
1106 armNextPC
= 0x08000000;
1107 reg
[15].I
= 0x08000004;
1114 if(systemVerbose
& VERBOSE_SWI
) {
1115 log("Sqrt: %08x (VCOUNT=%2d)\n",
1120 reg
[0].I
= (u32
)sqrt((double)reg
[0].I
);
1122 if(systemVerbose
& VERBOSE_SWI
) {
1123 log("Sqrt: return=%08x\n",
1129 void BIOS_MidiKey2Freq()
1132 if(systemVerbose
& VERBOSE_SWI
) {
1133 log("MidiKey2Freq: WaveData=%08x mk=%08x fp=%08x\n",
1139 int freq
= CPUReadMemory(reg
[0].I
+4);
1141 tmp
= ((double)(180 - reg
[1].I
)) - ((double)reg
[2].I
/ 256.f
);
1142 tmp
= pow((double)2.f
, tmp
/ 12.f
);
1143 reg
[0].I
= (int)((double)freq
/ tmp
);
1146 if(systemVerbose
& VERBOSE_SWI
) {
1147 log("MidiKey2Freq: return %08x\n",
1153 void BIOS_SndDriverJmpTableCopy()
1156 if(systemVerbose
& VERBOSE_SWI
) {
1157 log("SndDriverJmpTableCopy: dest=%08x\n",
1161 for(int i
= 0; i
< 0x24; i
++) {
1162 CPUWriteMemory(reg
[0].I
, 0x9c);