We truncated the diff of some files because they were too big.
If you want to see the full diff for every file, click here.
Changes of Revision 2
libretro-picodrive.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Sun Aug 09 10:56:09 UTC 2020 - i@guoyunhe.me
4
+
5
+- Update to version 0~git20200716:
6
+ * libretro, build fixes ffor android/ios
7
+ * libretro, tentative fix for android build
8
+ * sh2 drc, optimize standard division insns (default off, needs more scrutiny)
9
+ * Buildfix
10
+ * Buildfix
11
+ * Fix more conflicting types for prototypes
12
+ * Prevent collission with PS2 SDK
13
+ * Make sure function prototype signatures match, and put typedefs into separate header file
14
+ * core, keep offsets header from being build if no preprocessed asm files
15
+ * libretro, build fixes
16
+ * libretro, build fixes
17
+ * core, fix type issues by using stdint types
18
+ * libretro, build fixes
19
+ * sh2, fix for interpreter crash if drc is compiled in too
20
+ * sh2 drc, fix for x86_64 backend
21
+ * libretro, more fixes and cleanups for windows and osx
22
+ * libretro, fix for windows and osx
23
+ * libretro, changes to allow for both standalone and libretro build
24
+ * SDL UI, 2x overlay mode, for improved color resolution
25
+ * libretro make fix for non-arm architectures
26
+ * sh2 drc, fix for SH2 T handling in Mips/RiscV
27
+ * SDL UI, preparation for 2x mode, for improved color resolution
28
+ * sh2 drc, optimisation for SH2 16x16 multiplication
29
+ * SDL UI, fix for CD LED display
30
+ * sh2 drc, backend 32/64 bit compatibility fixes for Mips/RiscV
31
+ * vdp fifo, DMA bugfix
32
+ * sh2 drc, add powerpc64le backend
33
+ * sh2 drc, preparations for powerpc support
34
+ * vdp rendering, bugfix for overlapping high prio sprites
35
+ * release 1.96
36
+ * add copyright stuff to substantially changed files
37
+ * sh2 drc: revised ARM A32 backend optimizer
38
+ * 32x: libretro bugfix
39
+ * sh2: optimisations in drc
40
+ * audio: fix for save/load
41
+ * sh2: bugfix in drc
42
+ * audio: SN76496 fixes
43
+ * 32x poll detection fix
44
+ * vdp fifo, bugfix
45
+ * audio: add option to switch off SSG-EG
46
+ * audio: fixes and optimizations for SSG-EG
47
+ * audio: improve cycle accuracy of SN76496+YM2612
48
+ * 32x, small improvement for poll detection
49
+ * sh2, optimizations to innermost run loop
50
+ * add sh2 ubc area to poll detection
51
+ * 32x pwm, tiny optimization
52
+ * sh2 timer optimization
53
+ * menu background fix for pal mode
54
+ * ym2612 ARM optimisations
55
+ * vdp rendering, sprite caching optimization
56
+ * ym2612 ARM, bug fixing and small optimizations
57
+ * vdp DMA optimizations
58
+ * fix for gp2x audio regression
59
+ * vdp fifo speed optimization
60
+ * fix for 68K cycle accounting
61
+ * vdp rendering fixes
62
+ * vdp rendering, fix for CD (sprites from WORD RAM)
63
+ * ARM asm, symbol visibility fix
64
+ * vdp rendering fixes (debug register, vscroll) for overdrive 2
65
+ * vdp fifo speed optimization
66
+ * hvcounter table resolution reduced
67
+ * vdp rendering improvements
68
+ * vdp rendering, tiny improvement
69
+ * 32x, small improvement for poll detector
70
+ * vdp, some small improvements
71
+ * fix config file parsing for long filenames
72
+ * arm asm sprite rendering: add line accidently deleted in ea431e9
73
+ * ARM SVP drc revived
74
+ * vdp sprite rendering fixes
75
+ * more ARM asm sprite rendering bugfixes
76
+ * improved hi prio sprite rendering speed
77
+ * vdp, tentative fix for save/load compatibility
78
+ * fix for VINT while DMA is running
79
+ * fix for EI insn in cz80 (partial revert of 43e1401)
80
+ * bugfix for ARM asm sprite rendering
81
+ * vdp fifo, refined timing
82
+ * vdp sprite rendering fix
83
+ * vdp fifo, another revision
84
+ * vdp sprite handling improvement (SAT cache)
85
+ * vdp fifo, tentative fix for broken save/load
86
+ * vdp rendering fixes
87
+ * 32X poll detection fix
88
+ * fix compatibility with ancient gas
89
+ * vdp fifo: kludge for DMA fill interrupted by CPU
90
+ * sh2 drc: fix for crash in generated code on x86_64
91
+ * revised VDP fifo implementation
92
+ * new hvcounter tables as per spritesmind.net threads
93
+ * regression fix for gp2x 8bit fast mode
94
+ * improved VRAM128K support (overdrive 2)
95
+ * VDP timing improvements
96
+ * added debug reg sprite plane support (fixes some issues in overdrive 2 demo)
97
+ * sprite rendering improvements for masking and limit edge cases
98
+ * audio fixes for overdrive demo
99
+ * emulator timing fixes, VDP DMA fixes, improved DAC audio
100
+ * bug fixes in drc, audio, display
101
+ * audio: added SSG-EG to YM2612, plus some timing changes for SN76496+YM2612
102
+ * add DC filter to sound mixer to remove potential PCM DC offset
103
+ * sh2 drc: updates from mame for ym2612 sound
104
+ * sh2 drc: optimize T bit handling for A64
105
+ * sh2 drc: fix speed regression
106
+ * sh2 drc: cleanup, fix for drc crash, for mips code emitter
107
+ * remove textrels with -fPIC/-fPIE (for android/ios)
108
+ * sh2 drc, tentative MIPS32/64 Release 2 support
109
+ * release 1.95
110
+ * sh2 drc: bug fixing
111
+ * sh2 drc: fixed some RISC-V bugs
112
+ * sh2 drc, small improvements and bug fixes for code emitters
113
+ * sh2 drc, improved memory management
114
+ * sh2 drc: RISC-V (RV64IM) code emitter, some work on MIPS64
115
+ * sh2 drc: RISC-V (RV64IM) code emitter, some work on MIPS64
116
+ * sh2 drc: optimizations for MIPS code emitting
117
+ * sh2 drc: moved host register assignment to code emitters, minor bugfixing
118
+ * 32x, finetuning
119
+ * fix gp2x regression
120
+ * sh2 drc: reorganised block mgmt code, plus some small scale optimisations
121
+ * sh2 drc: bugfix in block management
122
+ * sh2 drc: bugfix in block management
123
+ * sh2 drc bugfix for aarch64/mips
124
+ * 32x, improved auto frame skip, plus new config option for max auto skip
125
+ * 32x, configurable pwm irq optimization to reduce pwm irq load
126
+ * 32x, speed improvement
127
+ * sh2 drc: speed optimization and bugfixing
128
+ * sh2 drc: fix i386 regression
129
+ * sh2 drc: bug fixing and optimization in register cache and branch handling
130
+ * sh2 drc: drc exit, block linking and branch handling revised (overlooked commit)
131
+ * sh2 drc: drc exit, block linking and branch handling revised
132
+ * sh2 drc: improved RTS call stack cache
133
+ * sh2 drc: rework of register cache to implement basic loop optmization
134
+ * various smallish optimizations, cleanups, and bug fixes
135
+ * cleanup and microoptimizations in SH2 hw handling
136
+ * some drawing code C optimisations
137
+ * bug fix in comm poll fifo, and back to -O3
138
+ * pff... README, 2nd try
139
+ * configuration changes and README
140
+ * cleanup config files, copyright stuff
141
+ * fix for mkoffsets without multiarch binutils
142
+ * various small fixes and optimsations
143
+ * sh2 drc: add aarch64 backend for A64
144
+ * sh2 drc: add mipsel backend for MIPS32 Release 1 (for JZ47xx)
145
+ * SH2 drc: register cache overhaul (bugfixing, speed, readability)
146
+ * SH2 drc: bug fixing and small speed improvements
147
+ * 32X: memory access and polling bug fixes
148
+ * sh2 drc, x86 code emitter: use x86-64 registers R8-R15
149
+ * 32x DMA memory copy performance optimisation
150
+ * sh2 drc, change utils abi to pass sh2 PC in arg0 (reduces compiled code size)
151
+ * sh2 drc, keep T bit in host flags as long as possible
152
+ * add xSR/RTS call stack cache to sh2 drc
153
+ * polling detection: communication poll fifo to avoid comm data loss
154
+ * sh2 memory access improvements, revive ARM asm memory functions
155
+ * sh2 drc, register cache optimisations
156
+ * sh2 drc, block management bugfixes and cleanup
157
+ * sh2 drc, add detection for in-memory polling
158
+ * sh2 drc, add loop detector, handle delay/idle loops
159
+ * sh2 drc, code emitter cleanup, add ARM reorder stage to reduce interlock
160
+ * sh2 drc, make B/W read functions signed (reduces generated code size)
161
+ * sh2 drc, improved constant handling and register allocator
162
+ * speed improvement and fixes for 32x ARM asm draw
163
+ * add literal pool to sh2 drc (for armv[456] without MOVT/W)
164
+ * sh2 drc, reuse blocks if already previously compiled (speedup for Virtua *)
165
+ * various small improvements and fixes
166
+ * overhaul of translation cache and sh2 literals handling
167
+ * added branch cache to sh2 drc to improve cross-tcache jump speed
168
+ * sh2 memory interface optimzations
169
+ * overhaul of the register cache (improves generated code by some 10+%)
170
+ * debug stuff, bug fixing
171
+ * move saving SH2 SR into memory access and do so only if needed
172
+ * add 32bit memory access functions for SH2
173
+ * sh2 drc: sh2 addr modes generalization, more const propagation, code gen optimizations
174
+ * DRC: reworked scan_block (fix register usage masks, better block and literals detection)
175
+ * minor changes
176
+ * reworked palette and buffer handling due to some 32X bugs
177
+ * revamped 32X draw arm asm code
178
+ * kludges for wwf raw, nfl
179
+ * substituted tool to obtain target structure offsets (for asm)
180
+ * improved sh2 clock handling, bug fixing + small improvement to drc emitters
181
+ * sh2 drc host disassembler integration for gp2x
182
+ * bugfix for 32x
183
+ * bfd-less arm disassembler for gph
184
+ * config for x86 (32 bit only, for SH2 drc), add/revive profiling
185
+ * arm asm memory access functions for m/s68k
186
+ * config templates for gp2x, caanoo, dingux either with system toolchain (open2x,gph,opendingux) or ubuntu arm(gcc 4.7 is highest possible),mips
187
+ * arm asm syntax fixes for open2x
188
+ * make gp2x mp3 playback functional (need to unpack and compile helix decoder separately in platform/common/helix)
189
+ * fix gp2x compilation (using linaro arm gcc 4.7 on ubuntu)
190
+ * release 1.93
191
+ * libretro: Allow setting GIT_VERSION.
192
+ * Makefile: Build with optimizations if DEBUG=0
193
+ * Remove not longer files in Picodrive for PS2
194
+ * Change GSKit PS2 version
195
+ * Update picodrive
196
+ * Define HAVE_NO_LANGEXTRA
197
+ * Adapt to newlib
198
+ * Add option to change sound quality
199
+ * Copy tile-based fast renderer buffer
200
+ * Add option to change renderer
201
libretro-picodrive.spec
Changed
10
1
2
3
4
Name: libretro-picodrive
5
-Version: 0~git20200112
6
+Version: 0~git20200716
7
Release: 0
8
Summary: PicoDrive libretro core for MegaDrive/Genesis emulation
9
License: NonFree
10
_servicedata
Changed
9
1
2
<servicedata>
3
<service name="tar_scm">
4
<param name="url">https://github.com/libretro/picodrive.git</param>
5
- <param name="changesrevision">495dddc0ad7847ab4a6ffeb54da3795a3f5a0e6d</param></service></servicedata>
6
\ No newline at end of file
7
+ <param name="changesrevision">e6b80af200f19d8d518d427dc20314606e9d8510</param></service></servicedata>
8
\ No newline at end of file
9
libretro-picodrive-0~git20200112.tar.xz/cpu/DrZ80/drz80.s
Deleted
201
1
2
-;@ Reesy's Z80 Emulator Version 0.001
3
-
4
-;@ (c) Copyright 2004 Reesy, All rights reserved
5
-;@ DrZ80 is free for non-commercial use.
6
-
7
-;@ For commercial use, separate licencing terms must be obtained.
8
-
9
- .data
10
- .align 4
11
-
12
- .global DrZ80Run
13
- .global DrZ80Ver
14
-
15
- .equiv INTERRUPT_MODE, 0 ;@0 = Use internal int handler, 1 = Use Mames int handler
16
- .equiv FAST_Z80SP, 0 ;@0 = Use mem functions for stack pointer, 1 = Use direct mem pointer
17
- .equiv UPDATE_CONTEXT, 0
18
- .equiv DRZ80_XMAP, 1
19
- .equiv DRZ80_XMAP_MORE_INLINE, 1
20
-
21
-.if DRZ80_XMAP
22
- .equ Z80_MEM_SHIFT, 13
23
-.endif
24
-
25
-.if INTERRUPT_MODE
26
- .extern Interrupt
27
-.endif
28
-
29
-DrZ80Ver: .long 0x0001
30
-
31
-;@ --------------------------- Defines ----------------------------
32
-;@ Make sure that regs/pointers for z80pc to z80sp match up!
33
-
34
- z80_icount .req r3
35
- opcodes .req r4
36
- cpucontext .req r5
37
- z80pc .req r6
38
- z80a .req r7
39
- z80f .req r8
40
- z80bc .req r9
41
- z80de .req r10
42
- z80hl .req r11
43
- z80sp .req r12
44
- z80xx .req lr
45
-
46
- .equ z80pc_pointer, 0 ;@ 0
47
- .equ z80a_pointer, z80pc_pointer+4 ;@ 4
48
- .equ z80f_pointer, z80a_pointer+4 ;@ 8
49
- .equ z80bc_pointer, z80f_pointer+4 ;@
50
- .equ z80de_pointer, z80bc_pointer+4
51
- .equ z80hl_pointer, z80de_pointer+4
52
- .equ z80sp_pointer, z80hl_pointer+4
53
- .equ z80pc_base, z80sp_pointer+4
54
- .equ z80sp_base, z80pc_base+4
55
- .equ z80ix, z80sp_base+4
56
- .equ z80iy, z80ix+4
57
- .equ z80i, z80iy+4
58
- .equ z80a2, z80i+4
59
- .equ z80f2, z80a2+4
60
- .equ z80bc2, z80f2+4
61
- .equ z80de2, z80bc2+4
62
- .equ z80hl2, z80de2+4
63
- .equ cycles_pointer, z80hl2+4
64
- .equ previouspc, cycles_pointer+4
65
- .equ z80irq, previouspc+4
66
- .equ z80if, z80irq+1
67
- .equ z80im, z80if+1
68
- .equ z80r, z80im+1
69
- .equ z80irqvector, z80r+1
70
- .equ z80irqcallback, z80irqvector+4
71
- .equ z80_write8, z80irqcallback+4
72
- .equ z80_write16, z80_write8+4
73
- .equ z80_in, z80_write16+4
74
- .equ z80_out, z80_in+4
75
- .equ z80_read8, z80_out+4
76
- .equ z80_read16, z80_read8+4
77
- .equ z80_rebaseSP, z80_read16+4
78
- .equ z80_rebasePC, z80_rebaseSP+4
79
-
80
- .equ VFlag, 0
81
- .equ CFlag, 1
82
- .equ ZFlag, 2
83
- .equ SFlag, 3
84
- .equ HFlag, 4
85
- .equ NFlag, 5
86
- .equ Flag3, 6
87
- .equ Flag5, 7
88
-
89
- .equ Z80_CFlag, 0
90
- .equ Z80_NFlag, 1
91
- .equ Z80_VFlag, 2
92
- .equ Z80_Flag3, 3
93
- .equ Z80_HFlag, 4
94
- .equ Z80_Flag5, 5
95
- .equ Z80_ZFlag, 6
96
- .equ Z80_SFlag, 7
97
-
98
- .equ Z80_IF1, 1<<0
99
- .equ Z80_IF2, 1<<1
100
- .equ Z80_HALT, 1<<2
101
- .equ Z80_NMI, 1<<3
102
-
103
-;@---------------------------------------
104
-
105
-.text
106
-
107
-.if DRZ80_XMAP
108
-
109
-z80_xmap_read8: @ addr
110
- ldr r1,[cpucontext,#z80_read8]
111
- mov r2,r0,lsr #Z80_MEM_SHIFT
112
- ldr r1,[r1,r2,lsl #2]
113
- movs r1,r1,lsl #1
114
- ldrccb r0,[r1,r0]
115
- bxcc lr
116
-
117
-z80_xmap_read8_handler: @ addr, func
118
- str z80_icount,[cpucontext,#cycles_pointer]
119
- stmfd sp!,{r12,lr}
120
- mov lr,pc
121
- bx r1
122
- ldr z80_icount,[cpucontext,#cycles_pointer]
123
- ldmfd sp!,{r12,pc}
124
-
125
-z80_xmap_write8: @ data, addr
126
- ldr r2,[cpucontext,#z80_write8]
127
- add r2,r2,r1,lsr #Z80_MEM_SHIFT-2
128
- bic r2,r2,#3
129
- ldr r2,[r2]
130
- movs r2,r2,lsl #1
131
- strccb r0,[r2,r1]
132
- bxcc lr
133
-
134
-z80_xmap_write8_handler: @ data, addr, func
135
- str z80_icount,[cpucontext,#cycles_pointer]
136
- mov r3,r0
137
- mov r0,r1
138
- mov r1,r3
139
- stmfd sp!,{r12,lr}
140
- mov lr,pc
141
- bx r2
142
- ldr z80_icount,[cpucontext,#cycles_pointer]
143
- ldmfd sp!,{r12,pc}
144
-
145
-z80_xmap_read16: @ addr
146
- @ check if we cross bank boundary
147
- add r1,r0,#1
148
- eor r1,r1,r0
149
- tst r1,#1<<Z80_MEM_SHIFT
150
- bne 0f
151
-
152
- ldr r1,[cpucontext,#z80_read8]
153
- mov r2,r0,lsr #Z80_MEM_SHIFT
154
- ldr r1,[r1,r2,lsl #2]
155
- movs r1,r1,lsl #1
156
- bcs 0f
157
- ldrb r0,[r1,r0]!
158
- ldrb r1,[r1,#1]
159
- orr r0,r0,r1,lsl #8
160
- bx lr
161
-
162
-0:
163
- @ z80_xmap_read8 will save r3 and r12 for us
164
- stmfd sp!,{r8,r9,lr}
165
- mov r8,r0
166
- bl z80_xmap_read8
167
- mov r9,r0
168
- add r0,r8,#1
169
- bl z80_xmap_read8
170
- orr r0,r9,r0,lsl #8
171
- ldmfd sp!,{r8,r9,pc}
172
-
173
-z80_xmap_write16: @ data, addr
174
- add r2,r1,#1
175
- eor r2,r2,r1
176
- tst r2,#1<<Z80_MEM_SHIFT
177
- bne 0f
178
-
179
- ldr r2,[cpucontext,#z80_write8]
180
- add r2,r2,r1,lsr #Z80_MEM_SHIFT-2
181
- bic r2,r2,#3
182
- ldr r2,[r2]
183
- movs r2,r2,lsl #1
184
- bcs 0f
185
- strb r0,[r2,r1]!
186
- mov r0,r0,lsr #8
187
- strb r0,[r2,#1]
188
- bx lr
189
-
190
-0:
191
- stmfd sp!,{r8,r9,lr}
192
- mov r8,r0
193
- mov r9,r1
194
- bl z80_xmap_write8
195
- mov r0,r8,lsr #8
196
- add r1,r9,#1
197
- bl z80_xmap_write8
198
- ldmfd sp!,{r8,r9,pc}
199
-
200
-z80_xmap_rebase_pc:
201
libretro-picodrive-0~git20200112.tar.xz/pico/32x/draw_arm.s
Deleted
201
1
2
-@*
3
-@* PicoDrive
4
-@* (C) notaz, 2010
5
-@*
6
-@* This work is licensed under the terms of MAME license.
7
-@* See COPYING file in the top-level directory.
8
-@*
9
-
10
-.extern Pico32x
11
-.extern PicoDraw2FB
12
-.extern HighPal
13
-
14
-.equiv P32XV_PRI, (1<< 7)
15
-
16
-.bss
17
-.align 2
18
-.global Pico32xNativePal
19
-Pico32xNativePal:
20
- .word 0
21
-
22
-.text
23
-.align 2
24
-
25
-
26
-.macro call_scan_prep cond
27
-.if \cond
28
- ldr r4, =PicoScan32xBegin
29
- ldr r5, =PicoScan32xEnd
30
- ldr r6, =DrawLineDest
31
- ldr r4, [r4]
32
- ldr r5, [r5]
33
- stmfd sp!, {r4,r5,r6}
34
-.endif
35
-.endm
36
-
37
-.macro call_scan_fin_ge cond
38
-.if \cond
39
- addge sp, sp, #4*3
40
-.endif
41
-.endm
42
-
43
-.macro call_scan_begin cond
44
-.if \cond
45
- stmfd sp!, {r1-r3}
46
- and r0, r2, #0xff
47
- add r0, r0, r4
48
- mov lr, pc
49
- ldr pc, [sp, #(3+0)*4]
50
- ldr r0, [sp, #(3+2)*4] @ &DrawLineDest
51
- ldmfd sp!, {r1-r3}
52
- ldr r0, [r0]
53
-.endif
54
-.endm
55
-
56
-.macro call_scan_end cond
57
-.if \cond
58
- stmfd sp!, {r0-r3}
59
- and r0, r2, #0xff
60
- add r0, r0, r4
61
- mov lr, pc
62
- ldr pc, [sp, #(4+1)*4]
63
- ldmfd sp!, {r0-r3}
64
-.endif
65
-.endm
66
-
67
-@ direct color
68
-@ unsigned short *dst, unsigned short *dram, int lines_sft_offs, int mdbg
69
-.macro make_do_loop_dc name call_scan do_md
70
-.global \name
71
-\name:
72
- stmfd sp!, {r4-r11,lr}
73
-
74
- ldr r10,=Pico32x
75
- ldr r11,=PicoDraw2FB
76
- ldr r10,[r10, #0x40] @ Pico32x.vdp_regs[0]
77
- ldr r11,[r11]
78
- ldr r9, =HighPal @ palmd
79
- and r4, r2, #0xff
80
- mov r5, #328
81
- lsl r3, #26 @ mdbg << 26
82
- mla r11,r4,r5,r11 @ r11 = pmd = PicoDraw2FB + offs*328: md data
83
- tst r10,#P32XV_PRI
84
- moveq r10,#0
85
- movne r10,#0x8000 @ r10 = inv_bit
86
- call_scan_prep \call_scan
87
-
88
- mov r4, #0 @ line
89
- b 1f @ loop_outer_entry
90
-
91
-0: @ loop_outer:
92
- call_scan_end \call_scan
93
- add r4, r4, #1
94
- sub r11,r11,#1 @ adjust for prev read
95
- cmp r4, r2, lsr #16
96
- call_scan_fin_ge \call_scan
97
- ldmgefd sp!, {r4-r11,pc}
98
-
99
-1: @ loop_outer_entry:
100
- call_scan_begin \call_scan
101
- mov r12,r4, lsl #1
102
- ldrh r12,[r1, r12]
103
- add r11,r11,#8
104
- mov r6, #320
105
- add r5, r1, r12, lsl #1 @ p32x = dram + dram[l]
106
-
107
-2: @ loop_inner:
108
- ldrb r7, [r11], #1 @ MD pixel
109
- subs r6, r6, #1
110
- blt 0b @ loop_outer
111
- ldrh r8, [r5], #2 @ 32x pixel
112
- cmp r3, r7, lsl #26 @ MD has bg pixel?
113
- beq 3f @ draw32x
114
- eor r12,r8, r10
115
- ands r12,r12,#0x8000 @ !((t ^ inv) & 0x8000)
116
-.if \do_md
117
- mov r7, r7, lsl #1
118
- ldreqh r12,[r9, r7]
119
- streqh r12,[r0], #2 @ *dst++ = palmd[*pmd]
120
-.endif
121
- beq 2b @ loop_inner
122
-
123
-3: @ draw32x:
124
- and r12,r8, #0x03e0
125
- mov r8, r8, lsl #11
126
- orr r8, r8, r8, lsr #(10+11)
127
- orr r8, r8, r12,lsl #1
128
- bic r8, r8, #0x0020 @ kill prio bit
129
- strh r8, [r0], #2 @ *dst++ = bgr2rgb(*p32x++)
130
- b 2b @ loop_inner
131
-.endm
132
-
133
-
134
-@ packed pixel
135
-@ note: this may read a few bytes over the end of PicoDraw2FB and dram,
136
-@ so those should have a bit more alloc'ed than really needed.
137
-@ unsigned short *dst, unsigned short *dram, int lines_sft_offs, int mdbg
138
-.macro make_do_loop_pp name call_scan do_md
139
-.global \name
140
-\name:
141
- stmfd sp!, {r4-r11,lr}
142
-
143
- ldr r11,=PicoDraw2FB
144
- ldr r10,=Pico32xNativePal
145
- ldr r11,[r11]
146
- ldr r10,[r10]
147
- ldr r9, =HighPal @ palmd
148
- and r4, r2, #0xff
149
- mov r5, #328
150
- lsl r3, #26 @ mdbg << 26
151
- mla r11,r4,r5,r11 @ r11 = pmd = PicoDraw2FB + offs*328: md data
152
- call_scan_prep \call_scan
153
-
154
- mov r4, #0 @ line
155
- b 1f @ loop_outer_entry
156
-
157
-0: @ loop_outer:
158
- call_scan_end \call_scan
159
- add r4, r4, #1
160
- cmp r4, r2, lsr #16
161
- call_scan_fin_ge \call_scan
162
- ldmgefd sp!, {r4-r11,pc}
163
-
164
-1: @ loop_outer_entry:
165
- call_scan_begin \call_scan
166
- mov r12,r4, lsl #1
167
- ldrh r12,[r1, r12]
168
- add r11,r11,#8
169
- mov r6, #320/2
170
- add r5, r1, r12, lsl #1 @ p32x = dram + dram[l]
171
- and r12,r2, #0x100 @ shift
172
- add r5, r5, r12,lsr #8
173
-
174
-2: @ loop_inner:
175
-@ r4,r6 - counters; r5 - 32x data; r9,r10 - md,32x pal; r11 - md data
176
-@ r7,r8,r12,lr - temp
177
- tst r5, #1
178
- ldreqb r8, [r5], #2
179
- ldrb r7, [r5, #-1]
180
- ldrneb r8, [r5, #2]! @ r7,r8 - pixel 0,1 index
181
- subs r6, r6, #1
182
- blt 0b @ loop_outer
183
- cmp r7, r8
184
- beq 5f @ check_fill @ +8
185
-
186
-3: @ no_fill:
187
- mov r12,r7, lsl #1
188
- mov lr, r8, lsl #1
189
- ldrh r7, [r10,r12]
190
- ldrh r8, [r10,lr]
191
- add r11,r11,#2
192
-
193
- eor r12,r7, #0x20
194
- tst r12,#0x20
195
- ldrneb r12,[r11,#-2] @ MD pixel 0
196
- eor lr, r8, #0x20
197
- cmpne r3, r12, lsl #26 @ MD has bg pixel?
198
-.if \do_md
199
- mov r12,r12,lsl #1
200
- ldrneh r7, [r9, r12] @ t = palmd[pmd[0]]
201
libretro-picodrive-0~git20200112.tar.xz/pico/pico_int_o32.h
Deleted
30
1
2
-/* autogenerated by tools/mkoffsets, do not edit */
3
-#define OFS_Pico_video_reg 0x0000
4
-#define OFS_Pico_m_rotate 0x0040
5
-#define OFS_Pico_m_z80Run 0x0041
6
-#define OFS_Pico_m_dirtyPal 0x0046
7
-#define OFS_Pico_m_hardware 0x0047
8
-#define OFS_Pico_m_z80_reset 0x004f
9
-#define OFS_Pico_m_sram_reg 0x0049
10
-#define OFS_Pico_sv 0x008c
11
-#define OFS_Pico_sv_data 0x008c
12
-#define OFS_Pico_sv_start 0x0090
13
-#define OFS_Pico_sv_end 0x0094
14
-#define OFS_Pico_sv_flags 0x0098
15
-#define OFS_Pico_rom 0x033c
16
-#define OFS_Pico_romsize 0x0340
17
-#define OFS_EST_DrawScanline 0x00
18
-#define OFS_EST_rendstatus 0x04
19
-#define OFS_EST_DrawLineDest 0x08
20
-#define OFS_EST_HighCol 0x0c
21
-#define OFS_EST_HighPreSpr 0x10
22
-#define OFS_EST_Pico 0x14
23
-#define OFS_EST_PicoMem_vram 0x18
24
-#define OFS_EST_PicoMem_cram 0x1c
25
-#define OFS_EST_PicoOpt 0x20
26
-#define OFS_EST_Draw2FB 0x24
27
-#define OFS_EST_HighPal 0x28
28
-#define OFS_PMEM_vram 0x10000
29
-#define OFS_PMEM_vsram 0x22100
30
libretro-picodrive-0~git20200112.tar.xz/pico/sound/ym2612_arm.s
Deleted
201
1
2
-/*
3
- * PicoDrive
4
- * (C) notaz, 2006
5
- *
6
- * This work is licensed under the terms of MAME license.
7
- * See COPYING file in the top-level directory.
8
- */
9
-
10
-@ this is a rewrite of MAME's ym2612 code, in particular this is only the main sample-generatin loop.
11
-@ it does not seem to give much performance increase (if any at all), so don't use it if it causes trouble.
12
-@ - notaz, 2006
13
-
14
-@ vim:filetype=armasm
15
-
16
-.equiv SLOT1, 0
17
-.equiv SLOT2, 2
18
-.equiv SLOT3, 1
19
-.equiv SLOT4, 3
20
-.equiv SLOT_STRUCT_SIZE, 0x30
21
-
22
-.equiv TL_TAB_LEN, 0x1A00
23
-
24
-.equiv EG_ATT, 4
25
-.equiv EG_DEC, 3
26
-.equiv EG_SUS, 2
27
-.equiv EG_REL, 1
28
-.equiv EG_OFF, 0
29
-
30
-.equiv EG_SH, 16 @ 16.16 fixed point (envelope generator timing)
31
-.equiv EG_TIMER_OVERFLOW, (3*(1<<EG_SH)) @ envelope generator timer overflows every 3 samples (on real chip)
32
-.equiv LFO_SH, 25 /* 7.25 fixed point (LFO calculations) */
33
-
34
-.equiv ENV_QUIET, (2*13*256/8)
35
-
36
-.text
37
-.align 2
38
-
39
-@ r5=slot, r1=eg_cnt, trashes: r0,r2,r3
40
-@ writes output to routp, but only if vol_out changes
41
-.macro update_eg_phase_slot slot
42
- ldrb r2, [r5,#0x17] @ state
43
- add r3, r5, #0x1c
44
- tst r2, r2
45
- beq 0f @ EG_OFF
46
-
47
- ldr r2, [r3, r2, lsl #2] @ pack
48
- mov r3, #1
49
- mov r0, r2, lsr #24 @ shift
50
- mov r3, r3, lsl r0
51
- sub r3, r3, #1
52
-
53
- tst r1, r3
54
- bne 0f @ no volume change
55
-
56
- mov r3, r1, lsr r0
57
- and r3, r3, #7
58
- add r3, r3, r3, lsl #1
59
- mov r3, r2, lsr r3
60
- and r3, r3, #7 @ eg_inc_val shift, may be 0
61
- ldrb r2, [r5,#0x17] @ state
62
- ldrh r0, [r5,#0x1a] @ volume, unsigned (0-1023)
63
-
64
- cmp r2, #4 @ EG_ATT
65
- beq 4f
66
- cmp r2, #2
67
- mov r2, #1
68
- mov r2, r2, lsl r3
69
- mov r2, r2, lsr #1 @ eg_inc_val
70
- add r0, r0, r2
71
- blt 1f @ EG_REL
72
- beq 2f @ EG_SUS
73
-
74
-3: @ EG_DEC
75
- ldr r2, [r5,#0x1c] @ sl (can be 16bit?)
76
- mov r3, #EG_SUS
77
- cmp r0, r2 @ if ( volume >= (INT32) SLOT->sl )
78
- strgeb r3, [r5,#0x17] @ state
79
- b 10f
80
-
81
-4: @ EG_ATT
82
- subs r3, r3, #1 @ eg_inc_val_shift - 1
83
- mov r2, #0
84
- mvnpl r2, r0
85
- mov r2, r2, lsl r3
86
- add r0, r0, r2, asr #4
87
- cmp r0, #0 @ if (volume <= MIN_ATT_INDEX)
88
- movle r3, #EG_DEC
89
- strleb r3, [r5,#0x17] @ state
90
- movle r0, #0
91
- b 10f
92
-
93
-2: @ EG_SUS
94
- mov r2, #1024
95
- sub r2, r2, #1 @ r2 = MAX_ATT_INDEX
96
- cmp r0, r2 @ if ( volume >= MAX_ATT_INDEX )
97
- movge r0, r2
98
- b 10f
99
-
100
-1: @ EG_REL
101
- mov r2, #1024
102
- sub r2, r2, #1 @ r2 = MAX_ATT_INDEX
103
- cmp r0, r2 @ if ( volume >= MAX_ATT_INDEX )
104
- movge r0, r2
105
- movge r3, #EG_OFF
106
- strgeb r3, [r5,#0x17] @ state
107
-
108
-10: @ finish
109
- ldrh r3, [r5,#0x18] @ tl
110
- strh r0, [r5,#0x1a] @ volume
111
-.if \slot == SLOT1
112
- mov r6, r6, lsr #16
113
- add r0, r0, r3
114
- orr r6, r0, r6, lsl #16
115
-.elseif \slot == SLOT2
116
- mov r6, r6, lsl #16
117
- add r0, r0, r3
118
- mov r0, r0, lsl #16
119
- orr r6, r0, r6, lsr #16
120
-.elseif \slot == SLOT3
121
- mov r7, r7, lsr #16
122
- add r0, r0, r3
123
- orr r7, r0, r7, lsl #16
124
-.elseif \slot == SLOT4
125
- mov r7, r7, lsl #16
126
- add r0, r0, r3
127
- mov r0, r0, lsl #16
128
- orr r7, r0, r7, lsr #16
129
-.endif
130
-
131
-0: @ EG_OFF
132
-.endm
133
-
134
-
135
-@ r12=lfo_ampm[31:16], r1=lfo_cnt_old, r2=lfo_cnt, r3=scratch
136
-.macro advance_lfo_m
137
- mov r2, r2, lsr #LFO_SH
138
- cmp r2, r1, lsr #LFO_SH
139
- beq 0f
140
- and r3, r2, #0x3f
141
- cmp r2, #0x40
142
- rsbge r3, r3, #0x3f
143
- bic r12,r12, #0xff000000 @ lfo_ampm &= 0xff
144
- orr r12,r12, r3, lsl #1+24
145
-
146
- mov r2, r2, lsr #2
147
- cmp r2, r1, lsr #LFO_SH+2
148
- bicne r12,r12, #0xff0000
149
- orrne r12,r12, r2, lsl #16
150
-
151
-0:
152
-.endm
153
-
154
-
155
-@ result goes to r1, trashes r2
156
-.macro make_eg_out slot
157
- tst r12, #8
158
- tstne r12, #(1<<(\slot+8))
159
-.if \slot == SLOT1
160
- mov r1, r6, lsl #16
161
- mov r1, r1, lsr #16
162
-.elseif \slot == SLOT2
163
- mov r1, r6, lsr #16
164
-.elseif \slot == SLOT3
165
- mov r1, r7, lsl #16
166
- mov r1, r1, lsr #16
167
-.elseif \slot == SLOT4
168
- mov r1, r7, lsr #16
169
-.endif
170
- andne r2, r12, #0xc0
171
- movne r2, r2, lsr #6
172
- addne r2, r2, #24
173
- addne r1, r1, r12, lsr r2
174
- bic r1, r1, #1
175
-.endm
176
-
177
-
178
-@ \r=sin/result, r1=env, r3=ym_tl_tab
179
-.macro lookup_tl r
180
- tst \r, #0x100
181
- eorne \r, \r, #0xff @ if (sin & 0x100) sin = 0xff - (sin&0xff);
182
- tst \r, #0x200
183
- and \r, \r, #0xff
184
- orr \r, \r, r1, lsl #7
185
- mov \r, \r, lsl #1
186
- ldrh \r, [r3, \r] @ 2ci if ne
187
- rsbne \r, \r, #0
188
-.endm
189
-
190
-
191
-@ lr=context, r12=pack (stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16])
192
-@ r0-r2=scratch, r3=sin_tab, r5=scratch, r6-r7=vol_out[4], r10=op1_out
193
-.macro upd_algo0_m
194
-
195
- @ SLOT3
196
- make_eg_out SLOT3
197
- cmp r1, #ENV_QUIET
198
- movcs r0, #0
199
- bcs 0f
200
- ldr r2, [lr, #0x18]
201
libretro-picodrive-0~git20200112.tar.xz/platform/ps2/SMS_Utils.s
Deleted
201
1
2
-/*
3
-# ___ _ _ ___
4
-# | | | | |
5
-# ___| | | ___| PS2DEV Open Source Project.
6
-#----------------------------------------------------------
7
-# MUL64 is pulled from some binary library (I don't remember which one).
8
-# mips_memcpy routine is pulled from 'sde' library from MIPS.
9
-#
10
-*/
11
-.set noat
12
-.set noreorder
13
-.set nomacro
14
-
15
-.globl MUL64
16
-.globl mips_memcpy
17
-.globl mips_memset
18
-
19
-.text
20
-
21
-MUL64:
22
- pmultuw $v0, $a0, $a1
23
- dsra32 $a2, $a0, 0
24
- dsra32 $v1, $a1, 0
25
- mult $v1, $a0, $v1
26
- mult1 $a2, $a2, $a1
27
- addu $v1, $v1, $a2
28
- dsll32 $v1, $v1, 0
29
- jr $ra
30
- daddu $v0, $v0, $v1
31
-
32
-mips_memcpy:
33
- addu $v0, $a0, $zero
34
- beqz $a2, 1f
35
- sltiu $t2, $a2, 12
36
- bnez $t2, 2f
37
- xor $v1, $a1, $a0
38
- andi $v1, $v1, 7
39
- negu $a3, $a0
40
- beqz $v1, 3f
41
- andi $a3, $a3, 7
42
- beqz $a3, 4f
43
- subu $a2, $a2, $a3
44
- ldr $v1, 0($a1)
45
- ldl $v1, 7($a1)
46
- addu $a1, $a1, $a3
47
- sdr $v1, 0($a0)
48
- addu $a0, $a0, $a3
49
-4:
50
- andi $v1, $a2, 31
51
- subu $a3, $a2, $v1
52
- beqz $a3, 5f
53
- addu $a2, $v1, $zero
54
- addu $a3, $a3, $a1
55
-6:
56
- ldr $v1, 0($a1)
57
- ldl $v1, 7($a1)
58
- ldr $t0, 8($a1)
59
- ldl $t0, 15($a1)
60
- ldr $t1, 16($a1)
61
- ldl $t1, 23($a1)
62
- ldr $t2, 24($a1)
63
- ldl $t2, 31($a1)
64
- sd $v1, 0($a0)
65
- sd $t0, 8($a0)
66
- sd $t1, 16($a0)
67
- addiu $a1, $a1, 32
68
- addiu $a0, $a0, 32
69
- bne $a1, $a3, 6b
70
- sd $t2, -8($a0)
71
-5:
72
- andi $v1, $a2, 7
73
- subu $a3, $a2, $v1
74
- beqz $a3, 2f
75
- addu $a2, $v1, $zero
76
- addu $a3, $a3, $a1
77
-7:
78
- ldr $v1, 0($a1)
79
- ldl $v1, 7($a1)
80
- addiu $a1, $a1, 8
81
- addiu $a0, $a0, 8
82
- nop
83
- bne $a1, $a3, 7b
84
- sd $v1, -8($a0)
85
- beq $zero, $zero, 2f
86
- nop
87
-3:
88
- beqz $a3, 8f
89
- subu $a2, $a2, $a3
90
- ldr $v1, 0($a1)
91
- addu $a1, $a1, $a3
92
- sdr $v1, 0($a0)
93
- addu $a0, $a0, $a3
94
-8:
95
- andi $v1, $a2, 31
96
- subu $a3, $a2, $v1
97
- beqz $a3, 9f
98
- addu $a2, $v1, $zero
99
- addu $a3, $a3, $a1
100
-10:
101
- ld $v1, 0($a1)
102
- ld $t0, 8($a1)
103
- ld $t1, 16($a1)
104
- ld $t2, 24($a1)
105
- sd $v1, 0($a0)
106
- sd $t0, 8($a0)
107
- sd $t1, 16($a0)
108
- addiu $a1, $a1, 32
109
- addiu $a0, $a0, 32
110
- bne $a1, $a3, 10b
111
- sd $t2, -8($a0)
112
-9:
113
- andi $v1, $a2, 7
114
- subu $a3, $a2, $v1
115
- beqz $a3, 2f
116
- addu $a2, $v1, $zero
117
- addu $a3, $a3, $a1
118
-11:
119
- ld $v1, 0($a1)
120
- addiu $a1, $a1, 8
121
- addiu $a0, $a0, 8
122
- nop
123
- nop
124
- bne $a1, $a3, 11b
125
- sd $v1, -8($a0)
126
-2:
127
- beqz $a2, 1f
128
- addu $a3, $a2, $a1
129
-12:
130
- lbu $v1, 0($a1)
131
- addiu $a1, $a1, 1
132
- addiu $a0, $a0, 1
133
- nop
134
- nop
135
- bne $a1, $a3, 12b
136
- sb $v1, -1($a0)
137
-1:
138
- jr $ra
139
- nop
140
-
141
-mips_memset:
142
- beqz $a2, 1f
143
- sltiu $at, $a2, 16
144
- bnez $at, 2f
145
- andi $a1, $a1, 0xFF
146
- dsll $at, $a1, 0x8
147
- or $a1, $a1, $at
148
- dsll $at, $a1, 0x10
149
- or $a1, $a1, $at
150
- dsll32 $at, $a1, 0x0
151
- or $a1, $a1, $at
152
- andi $v1, $a0, 0x7
153
- beqz $v1, 3f
154
- li $a3, 8
155
- subu $a3, $a3, $v1
156
- subu $a2, $a2, $a3
157
- sdr $a1, 0($a0)
158
- addu $a0, $a0, $a3
159
-3:
160
- andi $v1, $a2, 0x1f
161
- subu $a3, $a2, $v1
162
- beqz $a3, 4f
163
- move $a2, $v1
164
- addu $a3, $a3, $a0
165
-5:
166
- sd $a1, 0($a0)
167
- sd $a1, 8($a0)
168
- sd $a1, 16($a0)
169
- addiu $a0, $a0, 32
170
- sd $a1, -8($a0)
171
- bne $a0, $a3, 5b
172
-4:
173
- andi $v1, $a2, 0x7
174
- subu $a3, $a2, $v1
175
- beqz $a3, 2f
176
- move $a2, $v1
177
- addu $a3, $a3, $a0
178
-6:
179
- addiu $a0, $a0, 8
180
- beq $a0, $a3, 2f
181
- sd $a1, -8($a0)
182
- addiu $a0, $a0, 8
183
- beq $a0, $a3, 2f
184
- sd $a1, -8($a0)
185
- addiu $a0, $a0, 8
186
- bne $a0, $a3, 6b
187
- sd $a1, -8($a0)
188
-2:
189
- beqz $a2, 1f
190
- addu $a3, $a2, $a0
191
-7:
192
- addiu $a0, $a0, 1
193
- beq $a0, $a3, 1f
194
- sb $a1, -1($a0)
195
- addiu $a0, $a0, 1
196
- beq $a0, $a3, 1f
197
- sb $a1, -1($a0)
198
- addiu $a0, $a0, 1
199
- bne $a0, $a3, 7b
200
- sb $a1, -1($a0)
201
libretro-picodrive-0~git20200112.tar.xz/platform/ps2/stdint.h
Deleted
18
1
2
-#ifndef STDINT_H
3
-#define STDINT_H
4
-
5
-typedef unsigned long uintptr_t;
6
-typedef signed long intptr_t;
7
-
8
-typedef signed char int8_t;
9
-typedef signed short int16_t;
10
-typedef signed int int32_t;
11
-typedef signed long int64_t;
12
-typedef unsigned char uint8_t;
13
-typedef unsigned short uint16_t;
14
-typedef unsigned int uint32_t;
15
-typedef unsigned long uint64_t;
16
-
17
-#endif //STDINT_H
18
libretro-picodrive-0~git20200112.tar.xz/Makefile -> libretro-picodrive-0~git20200716.tar.xz/Makefile
Changed
175
1
2
CYCLONE_CC ?= gcc
3
CYCLONE_CXX ?= g++
4
5
-ifneq ("$(PLATFORM)", "libretro")
6
- CFLAGS += -Wall -g
7
- ifndef DEBUG
8
- CFLAGS += -O3 -DNDEBUG
9
- endif
10
-endif
11
-
12
-# This is actually needed, bevieve me.
13
-# If you really have to disable this, set NO_ALIGN_FUNCTIONS elsewhere.
14
-ifndef NO_ALIGN_FUNCTIONS
15
-CFLAGS += -falign-functions=2
16
-endif
17
-
18
all: config.mak target_
19
20
ifndef NO_CONFIG_MAK
21
22
config.mak:
23
endif
24
25
+# This is actually needed, believe me.
26
+# If you really have to disable this, set NO_ALIGN_FUNCTIONS elsewhere.
27
+ifndef NO_ALIGN_FUNCTIONS
28
+CFLAGS += -falign-functions=2
29
+endif
30
+
31
+# profiling
32
+pprof ?= 0
33
+gperf ?= 0
34
+
35
+ifneq ("$(PLATFORM)", "libretro")
36
+ CFLAGS += -Wall -g
37
+ifneq ($(findstring gcc,$(CC)),)
38
+ CFLAGS += -ffunction-sections -fdata-sections
39
+ LDFLAGS += -Wl,--gc-sections
40
+endif
41
+ ifndef DEBUG
42
+ CFLAGS += -O3 -DNDEBUG
43
+ endif
44
+
45
+ LD = $(CC)
46
+ OBJOUT ?= -o
47
+ LINKOUT ?= -o
48
+endif
49
+
50
+ifeq ("$(PLATFORM)",$(filter "$(PLATFORM)","gp2x" "opendingux" "rpi1"))
51
+# very small caches, avoid optimization options making the binary much bigger
52
+CFLAGS += -finline-limit=42 -fno-unroll-loops -fno-ipa-cp -ffast-math
53
+# this gets you about 20% better execution speed on 32bit arm/mips
54
+CFLAGS += -fno-common -fno-stack-protector -fno-guess-branch-probability -fno-caller-saves -fno-tree-loop-if-convert -fno-regmove
55
+endif
56
+#OBJS += align.o
57
+
58
# default settings
59
ifeq "$(ARCH)" "arm"
60
use_cyclone ?= 1
61
62
asm_misc ?= 1
63
asm_cdmemory ?= 1
64
asm_mix ?= 1
65
-else # if not arm
66
+asm_32xdraw ?= 1
67
+asm_32xmemory ?= 1
68
+else
69
use_fame ?= 1
70
use_cz80 ?= 1
71
-ifneq (,$(findstring 86,$(ARCH)))
72
+ifneq (,$(filter x86% i386% mips% aarch% riscv% powerpc% ppc%, $(ARCH)))
73
use_sh2drc ?= 1
74
endif
75
endif
76
77
USE_FRONTEND = 1
78
endif
79
ifeq "$(PLATFORM)" "generic"
80
+CFLAGS += -DSDL_OVERLAY_2X
81
OBJS += platform/linux/emu.o platform/linux/blit.o # FIXME
82
OBJS += platform/common/plat_sdl.o
83
OBJS += platform/libpicofe/plat_sdl.o platform/libpicofe/in_sdl.o
84
85
OBJS += platform/gp2x/warm.o
86
USE_FRONTEND = 1
87
PLATFORM_MP3 = 1
88
+PLATFORM_ZLIB = 1
89
+HAVE_ARMv6 = 0
90
endif
91
ifeq "$(PLATFORM)" "libretro"
92
OBJS += platform/libretro/libretro.o
93
94
OBJS += platform/libretro/libretro-common/streams/file_stream_transforms.o
95
OBJS += platform/libretro/libretro-common/vfs/vfs_implementation.o
96
endif
97
+PLATFORM_ZLIB = 1
98
endif
99
100
ifeq "$(USE_FRONTEND)" "1"
101
102
103
endif # USE_FRONTEND
104
105
-OBJS += platform/common/mp3.o
106
+OBJS += platform/common/mp3.o platform/common/mp3_sync.o
107
ifeq "$(PLATFORM_MP3)" "1"
108
+platform/common/mp3_helix.o: CFLAGS += -Iplatform/libpicofe
109
+OBJS += platform/common/mp3_helix.o
110
else ifeq "$(HAVE_LIBAVCODEC)" "1"
111
OBJS += platform/common/mp3_libavcodec.o
112
else
113
OBJS += platform/common/mp3_dummy.o
114
endif
115
116
-ifeq "$(PLATFORM)" "libretro"
117
+ifeq "$(PLATFORM_ZLIB)" "1"
118
# zlib
119
OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \
120
zlib/deflate.o zlib/crc32.o zlib/adler32.o zlib/zutil.o zlib/compress.o zlib/uncompr.o
121
122
target_: $(TARGET)
123
124
clean:
125
- $(RM) $(TARGET) $(OBJS)
126
+ $(RM) $(TARGET) $(OBJS) pico/pico_int_offs.h
127
$(RM) -r .opk_data
128
129
$(TARGET): $(OBJS)
130
131
endif
132
133
pprof: platform/linux/pprof.c
134
- $(CC) -O2 -ggdb -DPPROF -DPPROF_TOOL -I../../ -I. $^ -o $@
135
+ $(CC) $(CFLAGS) -O2 -ggdb -DPPROF -DPPROF_TOOL -I../../ -I. $^ -o $@ $(LDFLAGS) $(LDLIBS)
136
137
-tools/textfilter: tools/textfilter.c
138
- make -C tools/ textfilter
139
+pico/pico_int_offs.h: tools/mkoffsets.sh
140
+ make -C tools/ XCC="$(CC)" XCFLAGS="$(CFLAGS)" XPLATFORM="$(platform)"
141
142
%.o: %.c
143
$(CC) -c $(OBJOUT)$@ $< $(CFLAGS)
144
145
pico/cd/pcm.o: CFLAGS += -fno-strict-aliasing
146
pico/cd/LC89510.o: CFLAGS += -fno-strict-aliasing
147
pico/cd/gfx_cd.o: CFLAGS += -fno-strict-aliasing
148
+ifeq (1,$(use_sh2drc))
149
+ifneq (,$(findstring -flto,$(CFLAGS)))
150
+# if using the DRC, memory and sh2soc directly use the DRC register for SH2 SR
151
+# to avoid saving and reloading it. However, this collides with the use of LTO.
152
+pico/32x/memory.o: CFLAGS += -fno-lto
153
+pico/32x/sh2soc.o: CFLAGS += -fno-lto
154
+endif
155
+endif
156
157
# fame needs ~2GB of RAM to compile on gcc 4.8
158
# on x86, this is reduced by ~300MB when debug info is off (but not on ARM)
159
160
pico/carthw_cfg.c: pico/carthw.cfg
161
tools/make_carthw_c $< $@
162
163
+# preprocessed asm files most probably include the offsets file
164
+$(filter %.S,$(SRCS_COMMON)): pico/pico_int_offs.h
165
+
166
# random deps
167
pico/carthw/svp/compiler.o : cpu/drc/emit_arm.c
168
-cpu/sh2/compiler.o : cpu/drc/emit_arm.c
169
-cpu/sh2/compiler.o : cpu/drc/emit_x86.c
170
+cpu/sh2/compiler.o : cpu/drc/emit_arm.c cpu/drc/emit_arm64.c cpu/drc/emit_ppc.c
171
+cpu/sh2/compiler.o : cpu/drc/emit_x86.c cpu/drc/emit_mips.c cpu/drc/emit_riscv.c
172
cpu/sh2/mame/sh2pico.o : cpu/sh2/mame/sh2.c
173
pico/pico.o pico/cd/mcd.o pico/32x/32x.o : pico/pico_cmn.c pico/pico_int.h
174
pico/memory.o pico/cd/memory.o pico/32x/memory.o : pico/pico_int.h pico/memory.h
175
libretro-picodrive-0~git20200112.tar.xz/Makefile.libretro -> libretro-picodrive-0~git20200716.tar.xz/Makefile.libretro
Changed
201
1
2
platform = win
3
else ifneq ($(findstring Darwin,$(shell uname -a)),)
4
platform = osx
5
- arch = intel
6
- ifeq ($(shell uname -p),powerpc)
7
- arch = ppc
8
- endif
9
else ifneq ($(findstring win,$(shell uname -a)),)
10
platform = win
11
endif
12
13
STATIC_LINKING:= 0
14
TARGET_NAME := picodrive
15
LIBM := -lm
16
-GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
17
-ifneq ($(GIT_VERSION)," unknown")
18
+GIT_VERSION ?= $(shell git rev-parse --short HEAD || echo unknown)
19
+ifneq ($(GIT_VERSION),"unknown")
20
CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
21
endif
22
23
-asm_memory = 0
24
-asm_render = 0
25
-asm_ym2612 = 0
26
-asm_misc = 0
27
-asm_cdmemory = 0
28
-asm_mix = 0
29
-
30
fpic :=
31
32
ifeq ($(STATIC_LINKING),1)
33
34
SHARED := -shared
35
DONT_COMPILE_IN_ZLIB = 1
36
CFLAGS += -DFAMEC_NO_GOTOS
37
- use_sh2drc = 1
38
ifneq ($(findstring SunOS,$(shell uname -a)),)
39
CC=gcc
40
endif
41
42
LIBM :=
43
DONT_COMPILE_IN_ZLIB = 1
44
CFLAGS += -DFAMEC_NO_GOTOS
45
- use_sh2drc = 1
46
47
# OS X
48
else ifeq ($(platform), osx)
49
50
SHARED := -dynamiclib
51
fpic := -fPIC
52
APPLE := 1
53
- arch = intel
54
ifeq ($(shell uname -p),powerpc)
55
- arch = ppc
56
- endif
57
- ifeq ($(arch),ppc)
58
+ CFLAGS += -DHAVE_NO_LANGEXTRA
59
CFLAGS += -DBLARGG_BIG_ENDIAN=1 -D__ppc__ -DFAMEC_NO_GOTOS
60
- else
61
- use_sh2drc = 1
62
endif
63
OSXVER = `sw_vers -productVersion | cut -d. -f 2`
64
OSX_LT_MAVERICKS = `(( $(OSXVER) <= 9)) && echo "YES"`
65
66
CXX += -miphoneos-version-min=8.0
67
CC_AS += -miphoneos-version-min=8.0
68
CFLAGS += -miphoneos-version-min=8.0
69
- ARCH := arm
70
71
STATIC_LINKING = 1
72
- use_cyclone = 0
73
- use_fame = 1
74
- use_drz80 = 0
75
- use_cz80 = 1
76
- use_sh2drc = 0
77
- use_svpdrc = 0
78
79
# iOS
80
else ifneq (,$(findstring ios,$(platform)))
81
82
ifeq ($(platform),ios-arm64)
83
CC = clang -arch arm64 -isysroot $(IOSSDK)
84
CXX = clang++ -arch arm64 -isysroot $(IOSSDK)
85
- CFLAGS += -marm -DARM -D__aarch64__=1
86
+ CFLAGS += -marm -DARM -D__aarch64__=1
87
else
88
CC = clang -arch armv7 -isysroot $(IOSSDK)
89
CXX = clang++ -arch armv7 -isysroot $(IOSSDK)
90
- CFLAGS += -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon -marm
91
+ CC_AS = perl ./tools/gas-preprocessor.pl $(CC)
92
+ CFLAGS += -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon -marm
93
ASFLAGS += -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon
94
+ NO_ARM_ASM = 1
95
endif
96
- CC_AS = perl ./tools/gas-preprocessor.pl $(CC)
97
CFLAGS += -DIOS
98
99
ifeq ($(platform),$(filter $(platform),ios9 ios-arm64))
100
101
CC_AS += -miphoneos-version-min=5.0
102
CFLAGS += -miphoneos-version-min=5.0
103
endif
104
- ARCH := arm
105
-
106
- use_cyclone = 0
107
- use_fame = 1
108
- use_drz80 = 0
109
- use_cz80 = 1
110
- ifeq ($(platform),ios-arm64)
111
- use_sh2drc = 0
112
- use_svpdrc = 0
113
- else
114
- use_sh2drc = 1
115
- use_svpdrc = 1
116
- endif
117
118
# tvOS
119
else ifeq ($(platform), tvos-arm64)
120
- ARCH := arm
121
- use_cyclone = 0
122
- use_fame = 1
123
- use_drz80 = 0
124
- use_cz80 = 1
125
- use_sh2drc = 0
126
- use_svpdrc = 0
127
TARGET := $(TARGET_NAME)_libretro_tvos.dylib
128
SHARED := -dynamiclib
129
fpic := -fPIC
130
131
IOSSDK := $(shell xcodebuild -version -sdk appletvos Path)
132
endif
133
CC_AS = perl ./tools/gas-preprocessor.pl $(CC)
134
+ CC = clang -arch arm64 -isysroot $(IOSSDK)
135
+ CXX = clang++ -arch arm64 -isysroot $(IOSSDK)
136
+ CFLAGS += -marm -DARM -D__aarch64__=1
137
CFLAGS += -DIOS
138
139
# PS3
140
141
NO_MMAP = 1
142
DONT_COMPILE_IN_ZLIB = 1
143
144
- asm_memory = 0
145
- asm_render = 0
146
- asm_ym2612 = 0
147
- asm_misc = 0
148
- asm_cdpico = 0
149
- asm_cdmemory = 0
150
- asm_mix = 0
151
- use_cyclone = 0
152
- use_fame = 1
153
- use_drz80 = 0
154
- use_cz80 = 1
155
-
156
# sncps3
157
else ifeq ($(platform), sncps3)
158
+ ARCH = powerpc
159
TARGET := $(TARGET_NAME)_libretro_ps3.a
160
CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
161
AR = $(CELL_SDK)/host-win32/sn/bin/ps3snarl.exe
162
163
NO_MMAP = 1
164
DONT_COMPILE_IN_ZLIB = 1
165
166
- asm_memory = 0
167
- asm_render = 0
168
- asm_ym2612 = 0
169
- asm_misc = 0
170
- asm_cdpico = 0
171
- asm_cdmemory = 0
172
- asm_mix = 0
173
- use_cyclone = 0
174
- use_fame = 1
175
- use_drz80 = 0
176
- use_cz80 = 1
177
-
178
# Lightweight PS3 Homebrew SDK
179
else ifeq ($(platform), psl1ght)
180
TARGET := $(TARGET_NAME)_libretro_$(platform).a
181
182
NO_MMAP = 1
183
DONT_COMPILE_IN_ZLIB = 1
184
185
- asm_memory = 0
186
- asm_render = 0
187
- asm_ym2612 = 0
188
- asm_misc = 0
189
- asm_cdpico = 0
190
- asm_cdmemory = 0
191
- asm_mix = 0
192
- use_cyclone = 0
193
- use_fame = 1
194
- use_drz80 = 0
195
- use_cz80 = 1
196
-
197
# PSP
198
else ifeq ($(platform), psp1)
199
- TARGET := $(TARGET_NAME)_libretro_$(platform).a
200
- CC = psp-gcc$(EXE_EXT)
201
libretro-picodrive-0~git20200716.tar.xz/README.md
Added
72
1
2
+This is my foray into dynamic recompilation using PicoDrive, a
3
+Megadrive / Genesis / Sega CD / Mega CD / 32X / SMS emulator.
4
+
5
+I added support for MIPS (mips32r1), ARM64 (aarch64) and RISC-V (RV64IM) to the
6
+SH2 recompiler, as well as spent much effort to optimize the DRC-generated code.
7
+I also optimized SH2 memory access inside the emulator, and did some work on
8
+M68K/SH2 CPU synchronization to fix some problems and speed up the emulator.
9
+
10
+It got a bit out of hand. I ended up doing fixes and optimizations all over the
11
+place, mainly for 32X and CD, 32X graphics handling, and probably some more,
12
+see the commit history. As a result, 32X emulation speed has improved a lot.
13
+
14
+### compiling
15
+
16
+I mainly worked with standalone PicoDrive versions as created by configure/make.
17
+A list of platforms for which this is possible can be obtained with
18
+
19
+> configure --help
20
+
21
+If you want to build an executable for a unixoid platform not listed in the
22
+platform list, just use
23
+
24
+> configure --platform=generic
25
+
26
+If DRC is available for the platform, it should be enabled automatically.
27
+
28
+For other platforms using a cross-compiling toolchain I used this,
29
+assuming $TC points to the appropriate cross compile toolchain directory:
30
+
31
+platform|toolchain|configure command
32
+--------|---------|-----------------
33
+gp2x,wiz,caanoo|open2x|CROSS_COMPILE=arm-open2x-linux- CFLAGS="-I$TC/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/include" LDFLAGS="--sysroot $TC/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux -L$TC/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/lib" ./configure --platform=gp2x
34
+gp2x,wiz,caanoo|open2x with ubuntu arm gcc 4.7|CROSS_COMPILE=arm-linux-gnueabi- CFLAGS="-I$TC/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/include" LDFLAGS="-B$TC/gcc-4.1.1-glibc-2.3.6/lib/gcc/arm-open2x-linux/4.1.1 -B$TC/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/lib -L$TC/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/lib" ./configure --platform=gp2x
35
+opendingux|opendingux|CROSS_COMPILE=mipsel-linux- CFLAGS="-I$TC/usr/include -I$TC/usr/include/SDL" LDFLAGS="--sysroot $TC -L$TC/lib" ./configure --platform=opendingux
36
+opendingux|opendingux with ubuntu mips gcc 5.4|CROSS_COMPILE=mipsel-linux-gnu- CFLAGS="-I$TC/usr/include -I$TC/usr/include/SDL" LDFLAGS="-B$TC/usr/lib -B$TC/lib -Wl,-rpath-link=$TC/usr/lib -Wl,-rpath-link=$TC/lib" ./configure --platform=opendingux
37
+gcw0|gcw0|CROSS_COMPILE=mipsel-gcw0-linux-uclibc- CFLAGS="-I$TC/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include -I$TC/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include/SDL" LDFLAGS="--sysroot $TC/usr/mipsel-gcw0-linux-uclibc/sysroot" ./configure --platform=gcw0
38
+
39
+For gp2x, wiz, and caanoo you may need to compile libpng first.
40
+
41
+After configure, compile with
42
+
43
+> make opk # for opendingux and gcw0
44
+>
45
+> make # for anything else
46
+
47
+### helix MP3 decoder
48
+
49
+For 32 bit ARM platforms, there is the possibility to compile the helix MP3
50
+decoder into a shared library to be able to use MP3 audio files with CD games.
51
+The helix source files aren't supplied because of licensing issues. However, if
52
+you have obtained the sources, put them into the platform/common/helix
53
+directory, set CROSS to your cross compiler prefix (e.g. arm-linux-gnueabi-)
54
+and LIBGCC to your cross compiler's libgcc.a
55
+(e.g. /usr/lib/gcc-cross/arm-linux-gnueabi/4.7/libgcc.a), and compile with
56
+
57
+> make -C platform/common/helix CROSS=$CROSS LIBGCC=$LIBGCC
58
+
59
+Copy the resulting ${CROSS}helix_mp3.so as libhelix.so to the directory where
60
+the PicoDrive binary is.
61
+
62
+### installing
63
+
64
+You need to install the resulting binary onto your device manually.
65
+For opendingux and gcw0, copy the opk to your SD card.
66
+For gp2x, wiz and caanoo, the easiest way is to unpack
67
+[PicoDrive_191.zip](http://notaz.gp2x.de/releases/PicoDrive/PicoDrive_191.zip)
68
+on your SD card and replace the PicoDrive binary.
69
+
70
+Send bug reports, fixes etc to <derkub@gmail.com>
71
+Kai-Uwe Bloem
72
libretro-picodrive-0~git20200112.tar.xz/configure -> libretro-picodrive-0~git20200716.tar.xz/configure
Changed
201
1
2
$c >> config.log 2>&1
3
}
4
5
+check_option()
6
+{
7
+ echo 'void test(void) { }' >$TMPC
8
+ compile_object $1 || return 1
9
+ return 0
10
+}
11
+
12
check_define()
13
{
14
$CC -E -dD $CFLAGS pico/arm_features.h | grep -q $1 || return 1
15
16
# setting options to "yes" or "no" will make that choice default,
17
# "" means "autodetect".
18
19
-platform_list="generic pandora gp2x opendingux rpi1 rpi2"
20
+platform_list="generic pandora gp2x wiz caanoo opendingux gcw0 rpi1 rpi2"
21
platform="generic"
22
sound_driver_list="oss alsa sdl"
23
sound_drivers=""
24
have_armv5=""
25
have_armv6=""
26
have_armv7=""
27
+have_arm_oabi=""
28
have_arm_neon=""
29
have_libavcodec=""
30
need_sdl="no"
31
-need_xlib="no"
32
+need_zlib="no"
33
# these are for known platforms
34
optimize_cortexa8="no"
35
optimize_cortexa7="no"
36
37
CXX="${CXX-${CROSS_COMPILE}g++}"
38
AS="${AS-${CROSS_COMPILE}as}"
39
STRIP="${STRIP-${CROSS_COMPILE}strip}"
40
-test -n "$SDL_CONFIG" || SDL_CONFIG="`$CC --print-sysroot 2> /dev/null || true`/usr/bin/sdl-config"
41
+test -n "$SDL_CONFIG" || SDL_CONFIG="`$CC $CFLAGS $LDFLAGS --print-sysroot 2> /dev/null || true`/usr/bin/sdl-config"
42
MAIN_LDLIBS="$LDLIBS -lm"
43
config_mak="config.mak"
44
45
46
;;
47
generic)
48
;;
49
- opendingux)
50
+ opendingux | gcw0)
51
sound_drivers="sdl"
52
+ # both are really an opendingux
53
+ platform="opendingux"
54
;;
55
pandora)
56
sound_drivers="oss alsa"
57
optimize_cortexa8="yes"
58
have_arm_neon="yes"
59
;;
60
- gp2x)
61
+ gp2x | wiz | caanoo)
62
sound_drivers="oss"
63
optimize_arm920="yes"
64
+ # compile for OABI if toolchain provides it (faster code on caanoo)
65
+ have_arm_oabi="yes"
66
+ # always use static linking, since caanoo doesn't have OABI libs. Moreover,
67
+ # dynamic linking slows Wiz 1-10%, and libm on F100 isn't compatible
68
+ LDFLAGS="$LDFLAGS -static"
69
+ # unified binary for all of them
70
CFLAGS="$CFLAGS -D__GP2X__"
71
- if [ "$CROSS_COMPILE" = "arm-linux-" ]; then
72
- # still using static, dynamic linking slows Wiz 1-10%
73
- # also libm on F100 is not compatible
74
- MAIN_LDLIBS="$MAIN_LDLIBS -static"
75
- fi
76
+ platform="gp2x"
77
;;
78
*)
79
fail "unsupported platform: $platform"
80
81
# fi
82
#fi
83
84
-# basic compiler test
85
-cat > $TMPC <<EOF
86
-int main(void) { return 0; }
87
-EOF
88
-if ! compile_binary; then
89
- fail "compiler test failed, please check config.log"
90
-fi
91
-
92
if [ -z "$ARCH" ]; then
93
ARCH=`$CC -dumpmachine | awk -F '-' '{print $1}'`
94
fi
95
96
+# CPU/ABI stuff first, else compile test may fail
97
case "$ARCH" in
98
arm*)
99
# ARM stuff
100
101
have_armv5=`check_define HAVE_ARMV5 && echo yes` || true
102
fi
103
104
+ # must disable thumb as recompiler can't handle it
105
+ if check_define __thumb__; then
106
+ CFLAGS="$CFLAGS -marm"
107
+ fi
108
+ # OABI/EABI selection
109
+ if [ "$have_arm_oabi" = "yes" ] && check_option -mabi=apcs-gnu; then
110
+ echo "$CFLAGS" | grep -q -- '-mabi=' || CFLAGS="$CFLAGS -mabi=apcs-gnu"
111
+ echo "$CFLAGS" | grep -q -- '-m\(no-\)*thumb-interwork' || CFLAGS="$CFLAGS -mno-thumb-interwork"
112
+ echo "$ASFLAGS" | grep -q -- '-mabi=' || ASFLAGS="$ASFLAGS -mabi=apcs-gnu"
113
+ fi
114
+
115
# automatically set mfpu and mfloat-abi if they are not set
116
if [ "$have_arm_neon" = "yes" ]; then
117
fpu="neon"
118
+ abi="hard"
119
elif [ "$have_armv6" = "yes" ]; then
120
fpu="vfp"
121
+ abi="softfp"
122
+ elif check_option -mfpu=fpa; then
123
+ fpu="fpa" # compatibility option for arm-linux-gnueabi-gcc on ubuntu
124
+ abi="soft"
125
fi
126
if [ "x$fpu" != "x" ]; then
127
echo "$CFLAGS" | grep -q -- '-mfpu=' || CFLAGS="$CFLAGS -mfpu=$fpu"
128
echo "$ASFLAGS" | grep -q -- '-mfpu=' || ASFLAGS="$ASFLAGS -mfpu=$fpu"
129
- floatabi_set_by_gcc=`$CC -v 2>&1 | grep -q -- --with-float= && echo yes` || true
130
- if [ "$floatabi_set_by_gcc" != "yes" ]; then
131
- echo "$CFLAGS" | grep -q -- '-mfloat-abi=' || CFLAGS="$CFLAGS -mfloat-abi=softfp"
132
- echo "$ASFLAGS" | grep -q -- '-mfloat-abi=' || ASFLAGS="$ASFLAGS -mfloat-abi=softfp"
133
- fi
134
+ echo "$CFLAGS" | grep -q -- '-mfloat-abi=' || CFLAGS="$CFLAGS -mfloat-abi=$abi"
135
+ echo "$ASFLAGS" | grep -q -- '-mfloat-abi=' || ASFLAGS="$ASFLAGS -mfloat-abi=$abi"
136
fi
137
138
- # must disable thumb as recompiler can't handle it
139
- if check_define __thumb__; then
140
- CFLAGS="$CFLAGS -marm"
141
- fi
142
+ # add -ldl for helix support
143
+ case "$MAIN_LDLIBS" in
144
+ *"-ldl"*) ;;
145
+ *) MAIN_LDLIBS="-ldl $MAIN_LDLIBS" ;;
146
+ esac
147
148
# warn about common mistakes
149
if [ "$platform" != "gp2x" -a "$have_armv5" != "yes" ]; then
150
151
;;
152
esac
153
154
+# basic compiler test
155
+cat > $TMPC <<EOF
156
+int main(void) { return 0; }
157
+EOF
158
+if ! compile_binary; then
159
+ fail "compiler test failed, please check config.log"
160
+fi
161
+
162
# header/library presence tests
163
check_zlib()
164
{
165
166
compile_object "$@"
167
}
168
169
-MAIN_LDLIBS="$MAIN_LDLIBS -lz"
170
-check_zlib -lz || fail "please install zlib (libz-dev)"
171
+check_zlib -lz &&MAIN_LDLIBS="$MAIN_LDLIBS -lz" || need_zlib="yes"
172
173
MAIN_LDLIBS="-lpng $MAIN_LDLIBS"
174
check_libpng || fail "please install libpng (libpng-dev)"
175
176
check_sdl `$SDL_CONFIG --libs` || fail "please install libsdl (libsdl1.2-dev)"
177
fi
178
179
-cat > $TMPC <<EOF
180
-void test(void *f, void *d) { fread(d, 1, 1, f); }
181
-EOF
182
-if compile_object -Wno-unused-result; then
183
+if check_option -Wno-unused_result; then
184
CFLAGS="$CFLAGS -Wno-unused-result"
185
fi
186
187
188
if [ "$have_libavcodec" = "yes" ]; then
189
echo "HAVE_LIBAVCODEC = 1" >> $config_mak
190
fi
191
+if [ "$need_zlib" = "yes" ]; then
192
+ echo "PLATFORM_ZLIB = 1" >> $config_mak
193
+fi
194
195
# GP2X toolchains are too old for UAL asm,
196
# so add this here to not litter main Makefile
197
-if [ "$platform" = "g1p2x" ]; then
198
- echo >> $config_mak
199
- echo "%.o: %.S" >> $config_mak
200
- echo " $(CC) $(CFLAGS) -E -c $^ -o /tmp/$(notdir $@).s" >> $config_mak
201
libretro-picodrive-0~git20200716.tar.xz/cpu/DrZ80/drz80.S
Added
201
1
2
+;@ Reesy's Z80 Emulator Version 0.001
3
+
4
+;@ (c) Copyright 2004 Reesy, All rights reserved
5
+;@ DrZ80 is free for non-commercial use.
6
+
7
+;@ For commercial use, separate licencing terms must be obtained.
8
+
9
+#include "../../pico/arm_features.h"
10
+
11
+ .data
12
+ .align 4
13
+
14
+ .global DrZ80Run
15
+ .global DrZ80Ver
16
+
17
+ .equiv INTERRUPT_MODE, 0 ;@0 = Use internal int handler, 1 = Use Mames int handler
18
+ .equiv FAST_Z80SP, 0 ;@0 = Use mem functions for stack pointer, 1 = Use direct mem pointer
19
+ .equiv UPDATE_CONTEXT, 0
20
+ .equiv DRZ80_XMAP, 1
21
+ .equiv DRZ80_XMAP_MORE_INLINE, 1
22
+
23
+.if DRZ80_XMAP
24
+ .equ Z80_MEM_SHIFT, 13
25
+.endif
26
+
27
+.if INTERRUPT_MODE
28
+ .extern Interrupt
29
+.endif
30
+
31
+DrZ80Ver: .long 0x0001
32
+
33
+;@ --------------------------- Defines ----------------------------
34
+;@ Make sure that regs/pointers for z80pc to z80sp match up!
35
+
36
+ z80_icount .req r3
37
+ opcodes .req r4
38
+ cpucontext .req r5
39
+ z80pc .req r6
40
+ z80a .req r7
41
+ z80f .req r8
42
+ z80bc .req r9
43
+ z80de .req r10
44
+ z80hl .req r11
45
+ z80sp .req r12
46
+ z80xx .req lr
47
+
48
+ .equ z80pc_pointer, 0 ;@ 0
49
+ .equ z80a_pointer, z80pc_pointer+4 ;@ 4
50
+ .equ z80f_pointer, z80a_pointer+4 ;@ 8
51
+ .equ z80bc_pointer, z80f_pointer+4 ;@
52
+ .equ z80de_pointer, z80bc_pointer+4
53
+ .equ z80hl_pointer, z80de_pointer+4
54
+ .equ z80sp_pointer, z80hl_pointer+4
55
+ .equ z80pc_base, z80sp_pointer+4
56
+ .equ z80sp_base, z80pc_base+4
57
+ .equ z80ix, z80sp_base+4
58
+ .equ z80iy, z80ix+4
59
+ .equ z80i, z80iy+4
60
+ .equ z80a2, z80i+4
61
+ .equ z80f2, z80a2+4
62
+ .equ z80bc2, z80f2+4
63
+ .equ z80de2, z80bc2+4
64
+ .equ z80hl2, z80de2+4
65
+ .equ cycles_pointer, z80hl2+4
66
+ .equ previouspc, cycles_pointer+4
67
+ .equ z80irq, previouspc+4
68
+ .equ z80if, z80irq+1
69
+ .equ z80im, z80if+1
70
+ .equ z80r, z80im+1
71
+ .equ z80irqvector, z80r+1
72
+ .equ z80irqcallback, z80irqvector+4
73
+ .equ z80_write8, z80irqcallback+4
74
+ .equ z80_write16, z80_write8+4
75
+ .equ z80_in, z80_write16+4
76
+ .equ z80_out, z80_in+4
77
+ .equ z80_read8, z80_out+4
78
+ .equ z80_read16, z80_read8+4
79
+ .equ z80_rebaseSP, z80_read16+4
80
+ .equ z80_rebasePC, z80_rebaseSP+4
81
+
82
+ .equ VFlag, 0
83
+ .equ CFlag, 1
84
+ .equ ZFlag, 2
85
+ .equ SFlag, 3
86
+ .equ HFlag, 4
87
+ .equ NFlag, 5
88
+ .equ Flag3, 6
89
+ .equ Flag5, 7
90
+
91
+ .equ Z80_CFlag, 0
92
+ .equ Z80_NFlag, 1
93
+ .equ Z80_VFlag, 2
94
+ .equ Z80_Flag3, 3
95
+ .equ Z80_HFlag, 4
96
+ .equ Z80_Flag5, 5
97
+ .equ Z80_ZFlag, 6
98
+ .equ Z80_SFlag, 7
99
+
100
+ .equ Z80_IF1, 1<<0
101
+ .equ Z80_IF2, 1<<1
102
+ .equ Z80_HALT, 1<<2
103
+ .equ Z80_NMI, 1<<3
104
+
105
+;@---------------------------------------
106
+
107
+.text
108
+ PIC_LDR_INIT()
109
+
110
+.if DRZ80_XMAP
111
+
112
+z80_xmap_read8: @ addr
113
+ ldr r1,[cpucontext,#z80_read8]
114
+ mov r2,r0,lsr #Z80_MEM_SHIFT
115
+ ldr r1,[r1,r2,lsl #2]
116
+ movs r1,r1,lsl #1
117
+ ldrccb r0,[r1,r0]
118
+ bxcc lr
119
+
120
+z80_xmap_read8_handler: @ addr, func
121
+ str z80_icount,[cpucontext,#cycles_pointer]
122
+ stmfd sp!,{r12,lr}
123
+ mov lr,pc
124
+ bx r1
125
+ ldr z80_icount,[cpucontext,#cycles_pointer]
126
+ ldmfd sp!,{r12,pc}
127
+
128
+z80_xmap_write8: @ data, addr
129
+ ldr r2,[cpucontext,#z80_write8]
130
+ add r2,r2,r1,lsr #Z80_MEM_SHIFT-2
131
+ bic r2,r2,#3
132
+ ldr r2,[r2]
133
+ movs r2,r2,lsl #1
134
+ strccb r0,[r2,r1]
135
+ bxcc lr
136
+
137
+z80_xmap_write8_handler: @ data, addr, func
138
+ str z80_icount,[cpucontext,#cycles_pointer]
139
+ mov r3,r0
140
+ mov r0,r1
141
+ mov r1,r3
142
+ stmfd sp!,{r12,lr}
143
+ mov lr,pc
144
+ bx r2
145
+ ldr z80_icount,[cpucontext,#cycles_pointer]
146
+ ldmfd sp!,{r12,pc}
147
+
148
+z80_xmap_read16: @ addr
149
+ @ check if we cross bank boundary
150
+ add r1,r0,#1
151
+ eor r1,r1,r0
152
+ tst r1,#1<<Z80_MEM_SHIFT
153
+ bne 0f
154
+
155
+ ldr r1,[cpucontext,#z80_read8]
156
+ mov r2,r0,lsr #Z80_MEM_SHIFT
157
+ ldr r1,[r1,r2,lsl #2]
158
+ movs r1,r1,lsl #1
159
+ bcs 0f
160
+ ldrb r0,[r1,r0]!
161
+ ldrb r1,[r1,#1]
162
+ orr r0,r0,r1,lsl #8
163
+ bx lr
164
+
165
+0:
166
+ @ z80_xmap_read8 will save r3 and r12 for us
167
+ stmfd sp!,{r8,r9,lr}
168
+ mov r8,r0
169
+ bl z80_xmap_read8
170
+ mov r9,r0
171
+ add r0,r8,#1
172
+ bl z80_xmap_read8
173
+ orr r0,r9,r0,lsl #8
174
+ ldmfd sp!,{r8,r9,pc}
175
+
176
+z80_xmap_write16: @ data, addr
177
+ add r2,r1,#1
178
+ eor r2,r2,r1
179
+ tst r2,#1<<Z80_MEM_SHIFT
180
+ bne 0f
181
+
182
+ ldr r2,[cpucontext,#z80_write8]
183
+ add r2,r2,r1,lsr #Z80_MEM_SHIFT-2
184
+ bic r2,r2,#3
185
+ ldr r2,[r2]
186
+ movs r2,r2,lsl #1
187
+ bcs 0f
188
+ strb r0,[r2,r1]!
189
+ mov r0,r0,lsr #8
190
+ strb r0,[r2,#1]
191
+ bx lr
192
+
193
+0:
194
+ stmfd sp!,{r8,r9,lr}
195
+ mov r8,r0
196
+ mov r9,r1
197
+ bl z80_xmap_write8
198
+ mov r0,r8,lsr #8
199
+ add r1,r9,#1
200
+ bl z80_xmap_write8
201
libretro-picodrive-0~git20200112.tar.xz/cpu/cz80/cz80.c -> libretro-picodrive-0~git20200716.tar.xz/cpu/cz80/cz80.c
Changed
28
1
2
#include "cz80.h"
3
4
#if PICODRIVE_HACKS
5
+#include <pico/pico_int.h>
6
#include <pico/memory.h>
7
#endif
8
9
10
CPU->ICount -= CPU->ExtraCycles;
11
CPU->ExtraCycles = 0;
12
}
13
- goto Cz80_Exec;
14
+ if (!CPU->HaltState)
15
+ goto Cz80_Exec;
16
}
17
}
18
else CPU->ICount = 0;
19
20
#if CZ80_ENCRYPTED_ROM
21
CPU->OPBase = OPBase;
22
#endif
23
+ if (CPU->HaltState)
24
+ CPU->ICount = 0;
25
cycles -= CPU->ICount;
26
#if !CZ80_EMULATE_R_EXACTLY
27
zR = (zR + (cycles >> 2)) & 0x7f;
28
libretro-picodrive-0~git20200112.tar.xz/cpu/cz80/cz80_op.c -> libretro-picodrive-0~git20200716.tar.xz/cpu/cz80/cz80_op.c
Changed
17
1
2
OP(0x76): // HALT
3
OP_HALT:
4
CPU->HaltState = 1;
5
- CPU->ICount = 0;
6
goto Cz80_Check_Interrupt;
7
8
OP(0xf3): // DI
9
OP_DI:
10
zIFF = 0;
11
- RET(4)
12
+ USE_CYCLES(4)
13
+ goto Cz80_Exec_nocheck;
14
15
OP(0xfb): // EI
16
OP_EI:
17
libretro-picodrive-0~git20200112.tar.xz/cpu/drc/cmn.h -> libretro-picodrive-0~git20200716.tar.xz/cpu/drc/cmn.h
Changed
55
1
2
-#ifndef UTYPES_DEFINED
3
-typedef unsigned char u8;
4
-typedef signed char s8;
5
-typedef unsigned short u16;
6
-typedef signed short s16;
7
-typedef unsigned int u32;
8
-typedef signed int s32;
9
-#endif
10
11
-#define DRC_TCACHE_SIZE (2*1024*1024)
12
+#define DRC_TCACHE_SIZE (4*1024*1024)
13
14
extern u8 *tcache;
15
16
void drc_cmn_init(void);
17
void drc_cmn_cleanup(void);
18
19
+#define BITMASK1(v0) (1 << (v0))
20
+#define BITMASK2(v0,v1) ((1 << (v0)) | (1 << (v1)))
21
+#define BITMASK3(v0,v1,v2) (BITMASK2(v0,v1) | (1 << (v2)))
22
+#define BITMASK4(v0,v1,v2,v3) (BITMASK3(v0,v1,v2) | (1 << (v3)))
23
+#define BITMASK5(v0,v1,v2,v3,v4) (BITMASK4(v0,v1,v2,v3) | (1 << (v4)))
24
+#define BITMASK6(v0,v1,v2,v3,v4,v5) (BITMASK5(v0,v1,v2,v3,v4) | (1 << (v5)))
25
+#define BITRANGE(v0,v1) (BITMASK1(v1+1)-BITMASK1(v0)) // set with v0..v1
26
+
27
+// binary search approach, since we don't have CLZ on ARM920T
28
+#define FOR_ALL_BITS_SET_DO(mask, bit, code) { \
29
+ u32 __mask = mask; \
30
+ for (bit = 0; bit < 32 && mask; bit++, __mask >>= 1) { \
31
+ if (!(__mask & 0xffff)) \
32
+ bit += 16,__mask >>= 16; \
33
+ if (!(__mask & 0xff)) \
34
+ bit += 8, __mask >>= 8; \
35
+ if (!(__mask & 0xf)) \
36
+ bit += 4, __mask >>= 4; \
37
+ if (!(__mask & 0x3)) \
38
+ bit += 2, __mask >>= 2; \
39
+ if (!(__mask & 0x1)) \
40
+ bit += 1, __mask >>= 1; \
41
+ if (__mask & 0x1) { \
42
+ code; \
43
+ } \
44
+ } \
45
+}
46
+
47
+// inspired by https://graphics.stanford.edu/~seander/bithacks.html
48
+static inline int count_bits(unsigned val)
49
+{
50
+ val = val - ((val >> 1) & 0x55555555);
51
+ val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
52
+ return (((val + (val >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
53
+}
54
+
55
libretro-picodrive-0~git20200112.tar.xz/cpu/drc/emit_arm.c -> libretro-picodrive-0~git20200716.tar.xz/cpu/drc/emit_arm.c
Changed
201
1
2
/*
3
* Basic macros to emit ARM instructions and some utils
4
* Copyright (C) 2008,2009,2010 notaz
5
+ * Copyright (C) 2019 kub
6
*
7
* This work is licensed under the terms of MAME license.
8
* See COPYING file in the top-level directory.
9
*/
10
-#define CONTEXT_REG 11
11
-#define RET_REG 0
12
+#define HOST_REGS 16
13
+
14
+// OABI/EABI: params: r0-r3, return: r0-r1, temp: r12,r14, saved: r4-r8,r10,r11
15
+// SP,PC: r13,r15 must not be used. saved: r9 (for platform use, e.g. on ios)
16
+#define RET_REG 0
17
+#define PARAM_REGS { 0, 1, 2, 3 }
18
+#ifndef __MACH__
19
+#define PRESERVED_REGS { 4, 5, 6, 7, 8, 9, 10, 11 }
20
+#else
21
+#define PRESERVED_REGS { 4, 5, 6, 7, 8, 10, 11 } // no r9..
22
+#endif
23
+#define TEMPORARY_REGS { 12, 14 }
24
+
25
+#define CONTEXT_REG 11
26
+#define STATIC_SH2_REGS { SHR_SR,10 , SHR_R(0),8 , SHR_R(1),9 }
27
28
// XXX: tcache_ptr type for SVP and SH2 compilers differs..
29
#define EMIT_PTR(ptr, x) \
30
do { \
31
*(u32 *)ptr = x; \
32
ptr = (void *)((u8 *)ptr + sizeof(u32)); \
33
- COUNT_OP; \
34
} while (0)
35
36
-#define EMIT(x) EMIT_PTR(tcache_ptr, x)
37
+// ARM special registers and peephole optimization flags
38
+#define SP 13 // stack pointer
39
+#define LR 14 // link (return address)
40
+#define PC 15 // program counter
41
+#define SR 16 // CPSR, status register
42
+#define MEM 17 // memory access (src=LDR, dst=STR)
43
+#define CYC1 20 // 1 cycle interlock (LDR, reg-cntrld shift)
44
+#define CYC2 (CYC1+1)// 2+ cycles interlock (LDR[BH], MUL/MLA etc)
45
+#define NO 32 // token for "no register"
46
+
47
+// bitmask builders
48
+#define M1(x) (u32)(1ULL<<(x)) // u32 to have NO evaluate to 0
49
+#define M2(x,y) (M1(x)|M1(y))
50
+#define M3(x,y,z) (M2(x,y)|M1(z))
51
+#define M4(x,y,z,a) (M3(x,y,z)|M1(a))
52
+#define M5(x,y,z,a,b) (M4(x,y,z,a)|M1(b))
53
+#define M6(x,y,z,a,b,c) (M5(x,y,z,a,b)|M1(c))
54
+#define M10(a,b,c,d,e,f,g,h,i,j) (M5(a,b,c,d,e)|M5(f,g,h,i,j))
55
+
56
+// avoid a warning with clang
57
+static inline uintptr_t pabs(intptr_t v) { return labs(v); }
58
+
59
+// sys_cacheflush always flushes whole pages, and it's rather expensive on ARMs
60
+// hold a list of pending cache updates and merge requests to reduce cacheflush
61
+static struct { void *base, *end; } pageflush[4];
62
+static unsigned pagesize = 4096;
63
+
64
+static void emith_update_cache(void)
65
+{
66
+ int i;
67
+
68
+ for (i = 0; i < 4 && pageflush[i].base; i++) {
69
+ cache_flush_d_inval_i(pageflush[i].base, pageflush[i].end + pagesize-1);
70
+ pageflush[i].base = NULL;
71
+ }
72
+}
73
+
74
+static inline void emith_update_add(void *base, void *end)
75
+{
76
+ void *p_base = (void *)((uintptr_t)(base) & ~(pagesize-1));
77
+ void *p_end = (void *)((uintptr_t)(end ) & ~(pagesize-1));
78
+ int i;
79
+
80
+ for (i = 0; i < 4 && pageflush[i].base; i++) {
81
+ if (p_base <= pageflush[i].end+pagesize && p_end >= pageflush[i].end) {
82
+ if (p_base < pageflush[i].base) pageflush[i].base = p_base;
83
+ pageflush[i].end = p_end;
84
+ return;
85
+ }
86
+ if (p_base <= pageflush[i].base && p_end >= pageflush[i].base-pagesize) {
87
+ if (p_end > pageflush[i].end) pageflush[i].end = p_end;
88
+ pageflush[i].base = p_base;
89
+ return;
90
+ }
91
+ }
92
+ if (i == 4) {
93
+ /* list full and not mergeable -> flush list */
94
+ emith_update_cache();
95
+ i = 0;
96
+ }
97
+ pageflush[i].base = p_base, pageflush[i].end = p_end;
98
+}
99
+
100
+// peephole optimizer. ATM only tries to reduce interlock
101
+#define EMIT_CACHE_SIZE 6
102
+struct emit_op {
103
+ u32 op;
104
+ u32 src, dst;
105
+};
106
+
107
+// peephole cache, last commited insn + cache + next insn = size+2
108
+static struct emit_op emit_cache[EMIT_CACHE_SIZE+2];
109
+static int emit_index;
110
+#define emith_insn_ptr() (u8 *)((u32 *)tcache_ptr-emit_index)
111
+
112
+static inline void emith_pool_adjust(int tcache_offs, int move_offs);
113
+
114
+static NOINLINE void EMIT(u32 op, u32 dst, u32 src)
115
+{
116
+ void * emit_ptr = (u32 *)tcache_ptr - emit_index;
117
+ struct emit_op *const ptr = emit_cache;
118
+ const int n = emit_index+1;
119
+ int i, bi, bd = 0;
120
+
121
+ // account for new insn in tcache
122
+ tcache_ptr = (void *)((u32 *)tcache_ptr + 1);
123
+ COUNT_OP;
124
+ // for conditional execution SR is always source
125
+ if (op < 0xe0000000 /*A_COND_AL << 28*/)
126
+ src |= M1(SR);
127
+ // put insn on back of queue // mask away the NO token
128
+ emit_cache[n] = (struct emit_op)
129
+ { .op=op, .src=src & ~M1(NO), .dst=dst & ~M1(NO) };
130
+ // check insns down the queue as long as permitted by dependencies
131
+ for (bd = bi = 0, i = emit_index; i > 1 && !(dst & M1(PC)); i--) {
132
+ int deps = 0;
133
+ // dst deps between i and n must not be swapped, since any deps
134
+ // but [i].src & [n].src lead to changed semantics if swapped.
135
+ if ((ptr[i].dst & ptr[n].src) || (ptr[n].dst & ptr[i].src) ||
136
+ (ptr[i].dst & ptr[n].dst))
137
+ break;
138
+ // don't swap insns reading PC if it's not a word pool load
139
+ // (ptr[i].op&0xf700000) != EOP_C_AM2_IMM(0,0,0,1,0,0,0))
140
+ if ((ptr[i].src & M1(PC)) && (ptr[i].op&0xf700000) != 0x5100000)
141
+ break;
142
+
143
+ // calculate ARM920T interlock cycles (differences only)
144
+#define D2(x,y) ((ptr[x].dst & ptr[y].src)?((ptr[x].src >> CYC2) & 1):0)
145
+#define D1(x,y) ((ptr[x].dst & ptr[y].src)?((ptr[x].src >> CYC1) & 3):0)
146
+ // insn sequence: [..., i-2, i-1, i, i+1, ..., n-2, n-1, n]
147
+ deps -= D2(i-2,i)+D2(i-1,i+1)+D2(n-2,n ) + D1(i-1,i)+D1(n-1,n);
148
+ deps -= !!(ptr[n].src & M2(CYC1,CYC2));// favour moving LDR down
149
+ // insn sequence: [..., i-2, i-1, n, i, i+1, ..., n-2, n-1]
150
+ deps += D2(i-2,n)+D2(i-1,i )+D2(n ,i+1) + D1(i-1,n)+D1(n ,i);
151
+ deps += !!(ptr[i].src & M2(CYC1,CYC2));// penalize moving LDR up
152
+ // remember best match found
153
+ if (bd > deps)
154
+ bd = deps, bi = i;
155
+ }
156
+ // swap if fewer depencies
157
+ if (bd < 0) {
158
+ // make room for new insn at bi
159
+ struct emit_op tmp = ptr[n];
160
+ for (i = n-1; i >= bi; i--) {
161
+ ptr[i+1] = ptr[i];
162
+ if (ptr[i].src & M1(PC))
163
+ emith_pool_adjust(n-i+1, 1);
164
+ }
165
+ // insert new insn at bi
166
+ ptr[bi] = tmp;
167
+ if (ptr[bi].src & M1(PC))
168
+ emith_pool_adjust(1, bi-n);
169
+ }
170
+ if (dst & M1(PC)) {
171
+ // commit everything if a branch insn is emitted
172
+ for (i = 1; i <= emit_index+1; i++)
173
+ EMIT_PTR(emit_ptr, emit_cache[i].op);
174
+ emit_index = 0;
175
+ } else if (emit_index < EMIT_CACHE_SIZE) {
176
+ // queue not yet full
177
+ emit_index++;
178
+ } else {
179
+ // commit oldest insn from cache
180
+ EMIT_PTR(emit_ptr, emit_cache[1].op);
181
+ for (i = 0; i <= emit_index; i++)
182
+ emit_cache[i] = emit_cache[i+1];
183
+ }
184
+}
185
+
186
+static void emith_flush(void)
187
+{
188
+ int i;
189
+ void *emit_ptr = tcache_ptr - emit_index*sizeof(u32);
190
191
-#define A_R4M (1 << 4)
192
-#define A_R5M (1 << 5)
193
-#define A_R6M (1 << 6)
194
-#define A_R7M (1 << 7)
195
-#define A_R8M (1 << 8)
196
-#define A_R9M (1 << 9)
197
-#define A_R10M (1 << 10)
198
-#define A_R11M (1 << 11)
199
-#define A_R12M (1 << 12)
200
-#define A_R14M (1 << 14)
201
libretro-picodrive-0~git20200716.tar.xz/cpu/drc/emit_arm64.c
Added
201
1
2
+/*
3
+ * Basic macros to emit ARM A64 instructions and some utils
4
+ * Copyright (C) 2019 kub
5
+ *
6
+ * This work is licensed under the terms of MAME license.
7
+ * See COPYING file in the top-level directory.
8
+ */
9
+#define HOST_REGS 32
10
+
11
+// AAPCS64: params: r0-r7, return: r0-r1, temp: r8-r17, saved: r19-r29
12
+// reserved: r18 (for platform use)
13
+#define RET_REG 0
14
+#define PARAM_REGS { 0, 1, 2, 3, 4, 5, 6, 7 }
15
+#define PRESERVED_REGS { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 }
16
+#define TEMPORARY_REGS { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }
17
+
18
+#define CONTEXT_REG 29
19
+#define STATIC_SH2_REGS { SHR_SR,28 , SHR_R(0),27 , SHR_R(1),26 }
20
+
21
+// R31 doesn't exist, it aliases either with zero or SP
22
+#define SP 31 // stack pointer
23
+#define Z0 31 // zero register
24
+#define LR 30 // link register
25
+#define FP 29 // frame pointer
26
+#define PR 18 // platform register
27
+
28
+// All operations but ptr ops are using the lower 32 bits of the A64 registers.
29
+// The upper 32 bits are only used in ptr ops and are zeroed by A64 32 bit ops.
30
+
31
+
32
+#define A64_COND_EQ 0x0
33
+#define A64_COND_NE 0x1
34
+#define A64_COND_HS 0x2
35
+#define A64_COND_LO 0x3
36
+#define A64_COND_MI 0x4
37
+#define A64_COND_PL 0x5
38
+#define A64_COND_VS 0x6
39
+#define A64_COND_VC 0x7
40
+#define A64_COND_HI 0x8
41
+#define A64_COND_LS 0x9
42
+#define A64_COND_GE 0xa
43
+#define A64_COND_LT 0xb
44
+#define A64_COND_GT 0xc
45
+#define A64_COND_LE 0xd
46
+#define A64_COND_CS A64_COND_HS
47
+#define A64_COND_CC A64_COND_LO
48
+// "fake" conditions for T bit handling
49
+#define A64_COND_AL 0xe
50
+#define A64_COND_NV 0xf
51
+
52
+// DRC conditions
53
+#define DCOND_EQ A64_COND_EQ
54
+#define DCOND_NE A64_COND_NE
55
+#define DCOND_MI A64_COND_MI
56
+#define DCOND_PL A64_COND_PL
57
+#define DCOND_HI A64_COND_HI
58
+#define DCOND_HS A64_COND_HS
59
+#define DCOND_LO A64_COND_LO
60
+#define DCOND_GE A64_COND_GE
61
+#define DCOND_GT A64_COND_GT
62
+#define DCOND_LT A64_COND_LT
63
+#define DCOND_LS A64_COND_LS
64
+#define DCOND_LE A64_COND_LE
65
+#define DCOND_VS A64_COND_VS
66
+#define DCOND_VC A64_COND_VC
67
+
68
+#define DCOND_CS A64_COND_HS
69
+#define DCOND_CC A64_COND_LO
70
+
71
+
72
+// unified insn
73
+#define A64_INSN(op, b29, b22, b21, b16, b12, b10, b5, b0) \
74
+ (((op)<<25)|((b29)<<29)|((b22)<<22)|((b21)<<21)|((b16)<<16)|((b12)<<12)|((b10)<<10)|((b5)<<5)|((b0)<<0))
75
+
76
+#define _ 0 // marker for "field unused"
77
+
78
+#define A64_NOP \
79
+ A64_INSN(0xa,0x6,0x4,_,0x3,0x2,_,0,0x1f) // 0xd503201f
80
+
81
+// arithmetic/logical
82
+
83
+enum { OP_AND, OP_OR, OP_EOR, OP_ANDS, OP_ADD, OP_ADDS, OP_SUB, OP_SUBS };
84
+enum { ST_LSL, ST_LSR, ST_ASR, ST_ROR };
85
+enum { XT_UXTW=0x4, XT_UXTX=0x6, XT_LSL=0x7, XT_SXTW=0xc, XT_SXTX=0xe };
86
+#define OP_SZ64 (1 << 31) // bit for 64 bit op selection
87
+#define OP_N64 (1 << 22) // N-bit for 64 bit logical immediate ops
88
+
89
+#define A64_OP_REG(op, n, rd, rn, rm, stype, simm) /* arith+logical, ST_ */ \
90
+ A64_INSN(0x5,(op)&3,((op)&4)|stype,n,rm,_,simm,rn,rd)
91
+#define A64_OP_XREG(op, rd, rn, rm, xtopt, simm) /* arith, XT_ */ \
92
+ A64_INSN(0x5,(op)&3,0x4,1,rm,xtopt,simm,rn,rd)
93
+#define A64_OP_IMM12(op, rd, rn, imm, lsl12) /* arith */ \
94
+ A64_INSN(0x8,(op)&3,((op)&4)|lsl12,_,_,_,(imm)&0xfff,rn,rd)
95
+#define A64_OP_IMMBM(op, rd, rn, immr, imms) /* logical */ \
96
+ A64_INSN(0x9,(op)&3,0x0,_,immr,_,(imms)&0x3f,rn,rd)
97
+
98
+// rd = rn OP (rm SHIFT simm)
99
+#define A64_ADD_REG(rd, rn, rm, stype, simm) \
100
+ A64_OP_REG(OP_ADD,0,rd,rn,rm,stype,simm)
101
+#define A64_ADDS_REG(rd, rn, rm, stype, simm) \
102
+ A64_OP_REG(OP_ADDS,0,rd,rn,rm,stype,simm)
103
+#define A64_SUB_REG(rd, rn, rm, stype, simm) \
104
+ A64_OP_REG(OP_SUB,0,rd,rn,rm,stype,simm)
105
+#define A64_SUBS_REG(rd, rn, rm, stype, simm) \
106
+ A64_OP_REG(OP_SUBS,0,rd,rn,rm,stype,simm)
107
+
108
+#define A64_NEG_REG(rd, rm, stype, simm) \
109
+ A64_SUB_REG(rd,Z0,rm,stype,simm)
110
+#define A64_NEGS_REG(rd, rm, stype, simm) \
111
+ A64_SUBS_REG(rd,Z0,rm,stype,simm)
112
+#define A64_NEGC_REG(rd, rm) \
113
+ A64_SBC_REG(rd,Z0,rm)
114
+#define A64_NEGCS_REG(rd, rm) \
115
+ A64_SBCS_REG(rd,Z0,rm)
116
+#define A64_CMP_REG(rn, rm, stype, simm) \
117
+ A64_SUBS_REG(Z0, rn, rm, stype, simm)
118
+#define A64_CMN_REG(rn, rm, stype, simm) \
119
+ A64_ADDS_REG(Z0, rn, rm, stype, simm)
120
+
121
+#define A64_EOR_REG(rd, rn, rm, stype, simm) \
122
+ A64_OP_REG(OP_EOR,0,rd,rn,rm,stype,simm)
123
+#define A64_OR_REG(rd, rn, rm, stype, simm) \
124
+ A64_OP_REG(OP_OR,0,rd,rn,rm,stype,simm)
125
+#define A64_ORN_REG(rd, rn, rm, stype, simm) \
126
+ A64_OP_REG(OP_OR,1,rd,rn,rm,stype,simm)
127
+#define A64_AND_REG(rd, rn, rm, stype, simm) \
128
+ A64_OP_REG(OP_AND,0,rd,rn,rm,stype,simm)
129
+#define A64_ANDS_REG(rd, rn, rm, stype, simm) \
130
+ A64_OP_REG(OP_ANDS,0,rd,rn,rm,stype,simm)
131
+#define A64_BIC_REG(rd, rn, rm, stype, simm) \
132
+ A64_OP_REG(OP_AND,1,rd,rn,rm,stype,simm)
133
+#define A64_BICS_REG(rd, rn, rm, stype, simm) \
134
+ A64_OP_REG(OP_ANDS,1,rd,rn,rm,stype,simm)
135
+
136
+#define A64_TST_REG(rn, rm, stype, simm) \
137
+ A64_ANDS_REG(Z0, rn, rm, stype, simm)
138
+#define A64_MOV_REG(rd, rm, stype, simm) \
139
+ A64_OR_REG(rd, Z0, rm, stype, simm)
140
+#define A64_MVN_REG(rd, rm, stype, simm) \
141
+ A64_ORN_REG(rd, Z0, rm, stype, simm)
142
+
143
+// rd = rn OP (rm EXTEND simm)
144
+#define A64_ADD_XREG(rd, rn, rm, xtopt, simm) \
145
+ A64_OP_XREG(OP_ADD,rd,rn,rm,xtopt,simm)
146
+#define A64_ADDS_XREG(rd, rn, rm, xtopt, simm) \
147
+ A64_OP_XREG(OP_ADDS,rd,rn,rm,xtopt,simm)
148
+#define A64_SUB_XREG(rd, rn, rm, stype, simm) \
149
+ A64_OP_XREG(OP_SUB,rd,rn,rm,xtopt,simm)
150
+#define A64_SUBS_XREG(rd, rn, rm, stype, simm) \
151
+ A64_OP_XREG(OP_SUBS,rd,rn,rm,xtopt,simm)
152
+
153
+// rd = rn OP rm OP carry
154
+#define A64_ADC_REG(rd, rn, rm) \
155
+ A64_INSN(0xd,OP_ADD &3,0x0,_,rm,_,_,rn,rd)
156
+#define A64_ADCS_REG(rd, rn, rm) \
157
+ A64_INSN(0xd,OP_ADDS&3,0x0,_,rm,_,_,rn,rd)
158
+#define A64_SBC_REG(rd, rn, rm) \
159
+ A64_INSN(0xd,OP_SUB &3,0x0,_,rm,_,_,rn,rd)
160
+#define A64_SBCS_REG(rd, rn, rm) \
161
+ A64_INSN(0xd,OP_SUBS&3,0x0,_,rm,_,_,rn,rd)
162
+
163
+// rd = rn SHIFT rm
164
+#define A64_LSL_REG(rd, rn, rm) \
165
+ A64_INSN(0xd,0x0,0x3,_,rm,_,0x8,rn,rd)
166
+#define A64_LSR_REG(rd, rn, rm) \
167
+ A64_INSN(0xd,0x0,0x3,_,rm,_,0xa,rn,rd)
168
+#define A64_ASR_REG(rd, rn, rm) \
169
+ A64_INSN(0xd,0x0,0x3,_,rm,_,0x9,rn,rd)
170
+#define A64_ROR_REG(rd, rn, rm) \
171
+ A64_INSN(0xd,0x0,0x3,_,rm,_,0xb,rn,rd)
172
+
173
+// rd = REVERSE(rn)
174
+#define A64_RBIT_REG(rd, rn) \
175
+ A64_INSN(0xd,0x2,0x3,_,_,_,_,rn,rd)
176
+
177
+// rd = rn OP (imm12 << (0|12))
178
+#define A64_ADD_IMM(rd, rn, imm12, lsl12) \
179
+ A64_OP_IMM12(OP_ADD, rd, rn, imm12, lsl12)
180
+#define A64_ADDS_IMM(rd, rn, imm12, lsl12) \
181
+ A64_OP_IMM12(OP_ADDS, rd, rn, imm12, lsl12)
182
+#define A64_SUB_IMM(rd, rn, imm12, lsl12) \
183
+ A64_OP_IMM12(OP_SUB, rd, rn, imm12, lsl12)
184
+#define A64_SUBS_IMM(rd, rn, imm12, lsl12) \
185
+ A64_OP_IMM12(OP_SUBS, rd, rn, imm12, lsl12)
186
+
187
+#define A64_CMP_IMM(rn, imm12, lsl12) \
188
+ A64_SUBS_IMM(Z0,rn,imm12,lsl12)
189
+#define A64_CMN_IMM(rn, imm12, lsl12) \
190
+ A64_ADDS_IMM(Z0,rn,imm12,lsl12)
191
+
192
+// rd = rn OP immbm; immbm is a repeated special pattern of 2^n bits length
193
+#define A64_EOR_IMM(rd, rn, immr, imms) \
194
+ A64_OP_IMMBM(OP_EOR,rd,rn,immr,imms)
195
+#define A64_OR_IMM(rd, rn, immr, imms) \
196
+ A64_OP_IMMBM(OP_OR,rd,rn,immr,imms)
197
+#define A64_AND_IMM(rd, rn, immr, imms) \
198
+ A64_OP_IMMBM(OP_AND,rd,rn,immr,imms)
199
+#define A64_ANDS_IMM(rd, rn, immr, imms) \
200
+ A64_OP_IMMBM(OP_ANDS,rd,rn,immr,imms)
201
libretro-picodrive-0~git20200716.tar.xz/cpu/drc/emit_mips.c
Added
201
1
2
+/*
3
+ * Basic macros to emit MIPS32/MIPS64 Release 1 or 2 instructions and some utils
4
+ * Copyright (C) 2019 kub
5
+ *
6
+ * This work is licensed under the terms of MAME license.
7
+ * See COPYING file in the top-level directory.
8
+ */
9
+#define HOST_REGS 32
10
+
11
+// MIPS32 ABI: params: r4-r7, return: r2-r3, temp: r1(at),r8-r15,r24-r25,r31(ra)
12
+// saved: r16-r23,r30, reserved: r0(zero), r26-r27(irq), r28(gp), r29(sp)
13
+// r1,r15,r24,r25(at,t7-t9) are used internally by the code emitter
14
+// MIPSN32/MIPS64 ABI: params: r4-r11, no caller-reserved save area on stack
15
+#define RET_REG 2 // v0
16
+#define PARAM_REGS { 4, 5, 6, 7 } // a0-a3
17
+#define PRESERVED_REGS { 16, 17, 18, 19, 20, 21, 22, 23 } // s0-s7
18
+#define TEMPORARY_REGS { 2, 3, 8, 9, 10, 11, 12, 13, 14 } // v0-v1,t0-t6
19
+
20
+#define CONTEXT_REG 23 // s7
21
+#define STATIC_SH2_REGS { SHR_SR,22 , SHR_R(0),21 , SHR_R(1),20 }
22
+
23
+// NB: the ubiquitous JZ74[46]0 uses MIPS32 Release 1, a slight MIPS II superset
24
+#ifndef __mips_isa_rev
25
+#define __mips_isa_rev 1 // surprisingly not always defined
26
+#endif
27
+
28
+// registers usable for user code: r1-r25, others reserved or special
29
+#define Z0 0 // zero register
30
+#define GP 28 // global pointer
31
+#define SP 29 // stack pointer
32
+#define FP 30 // frame pointer
33
+#define LR 31 // link register
34
+// internally used by code emitter:
35
+#define AT 1 // used to hold intermediate results
36
+#define FNZ 15 // emulated processor flags: N (bit 31) ,Z (all bits)
37
+#define FC 24 // emulated processor flags: C (bit 0), others 0
38
+#define FV 25 // emulated processor flags: Nt^Ns (bit 31). others x
39
+
40
+// All operations but ptr ops are using the lower 32 bits of the registers.
41
+// The upper 32 bits always contain the sign extension from the lower 32 bits.
42
+
43
+// unified conditions; virtual, not corresponding to anything real on MIPS
44
+#define DCOND_EQ 0x0
45
+#define DCOND_NE 0x1
46
+#define DCOND_HS 0x2
47
+#define DCOND_LO 0x3
48
+#define DCOND_MI 0x4
49
+#define DCOND_PL 0x5
50
+#define DCOND_VS 0x6
51
+#define DCOND_VC 0x7
52
+#define DCOND_HI 0x8
53
+#define DCOND_LS 0x9
54
+#define DCOND_GE 0xa
55
+#define DCOND_LT 0xb
56
+#define DCOND_GT 0xc
57
+#define DCOND_LE 0xd
58
+
59
+#define DCOND_CS DCOND_LO
60
+#define DCOND_CC DCOND_HS
61
+
62
+// unified insn
63
+#define MIPS_INSN(op, rs, rt, rd, sa, fn) \
64
+ (((op)<<26)|((rs)<<21)|((rt)<<16)|((rd)<<11)|((sa)<<6)|((fn)<<0))
65
+
66
+#define _ 0 // marker for "field unused"
67
+#define __(n) o##n // enum marker for "undefined"
68
+
69
+// opcode field (encoded in op)
70
+enum { OP__FN=000, OP__RT, OP_J, OP_JAL, OP_BEQ, OP_BNE, OP_BLEZ, OP_BGTZ };
71
+enum { OP_ADDI=010, OP_ADDIU, OP_SLTI, OP_SLTIU, OP_ANDI, OP_ORI, OP_XORI, OP_LUI };
72
+enum { OP_DADDI=030, OP_DADDIU, OP_LDL, OP_LDR, OP__FN2=034, OP__FN3=037 };
73
+enum { OP_LB=040, OP_LH, OP_LWL, OP_LW, OP_LBU, OP_LHU, OP_LWR, OP_LWU };
74
+enum { OP_SB=050, OP_SH, OP_SWL, OP_SW, OP_SDL, OP_SDR, OP_SWR };
75
+enum { OP_SD=067, OP_LD=077 };
76
+// function field (encoded in fn if opcode = OP__FN)
77
+enum { FN_SLL=000, __(01), FN_SRL, FN_SRA, FN_SLLV, __(05), FN_SRLV, FN_SRAV };
78
+enum { FN_JR=010, FN_JALR, FN_MOVZ, FN_MOVN, FN_SYNC=017 };
79
+enum { FN_MFHI=020, FN_MTHI, FN_MFLO, FN_MTLO, FN_DSSLV, __(25), FN_DSLRV, FN_DSRAV };
80
+enum { FN_MULT=030, FN_MULTU, FN_DIV, FN_DIVU, FN_DMULT, FN_DMULTU, FN_DDIV, FN_DDIVU };
81
+enum { FN_ADD=040, FN_ADDU, FN_SUB, FN_SUBU, FN_AND, FN_OR, FN_XOR, FN_NOR };
82
+enum { FN_SLT=052, FN_SLTU, FN_DADD, FN_DADDU, FN_DSUB, FN_DSUBU };
83
+enum { FN_DSLL=070, __(71), FN_DSRL, FN_DSRA, FN_DSLL32, __(75), FN_DSRL32, FN_DSRA32 };
84
+// function field (encoded in fn if opcode = OP__FN2)
85
+enum { FN2_MADD=000, FN2_MADDU, FN2_MUL, __(03), FN2_MSUB, FN2_MSUBU };
86
+enum { FN2_CLZ=040, FN2_CLO, FN2_DCLZ=044, FN2_DCLO };
87
+// function field (encoded in fn if opcode = OP__FN3)
88
+enum { FN3_EXT=000, FN3_DEXTM, FN3_DEXTU, FN3_DEXT, FN3_INS, FN3_DINSM, FN3_DINSU, FN3_DINS };
89
+enum { FN3_BSHFL=040, FN3_DBSHFL=044 };
90
+// rt field (encoded in rt if opcode = OP__RT)
91
+enum { RT_BLTZ=000, RT_BGEZ, RT_BLTZAL=020, RT_BGEZAL, RT_SYNCI=037 };
92
+
93
+// bit shuffle function (encoded in sa if function = FN3_BSHFL)
94
+enum { BS_SBH=002, BS_SHD=005, BS_SEB=020, BS_SEH=030 };
95
+// r (rotate) bit function (encoded in rs/sa if function = FN_SRL/FN_SRLV)
96
+enum { RB_SRL=0, RB_ROTR=1 };
97
+
98
+#define MIPS_NOP 000 // null operation: SLL r0, r0, #0
99
+
100
+// arithmetic/logical
101
+
102
+#define MIPS_OP_REG(op, sa, rd, rs, rt) \
103
+ MIPS_INSN(OP__FN, rs, rt, rd, sa, op) // R-type, SPECIAL
104
+#define MIPS_OP2_REG(op, sa, rd, rs, rt) \
105
+ MIPS_INSN(OP__FN2, rs, rt, rd, sa, op) // R-type, SPECIAL2
106
+#define MIPS_OP3_REG(op, sa, rd, rs, rt) \
107
+ MIPS_INSN(OP__FN3, rs, rt, rd, sa, op) // R-type, SPECIAL3
108
+#define MIPS_OP_IMM(op, rt, rs, imm) \
109
+ MIPS_INSN(op, rs, rt, _, _, (u16)(imm)) // I-type
110
+
111
+// rd = rs OP rt
112
+#define MIPS_ADD_REG(rd, rs, rt) \
113
+ MIPS_OP_REG(FN_ADDU,_, rd, rs, rt)
114
+#define MIPS_DADD_REG(rd, rs, rt) \
115
+ MIPS_OP_REG(FN_DADDU,_, rd, rs, rt)
116
+#define MIPS_SUB_REG(rd, rs, rt) \
117
+ MIPS_OP_REG(FN_SUBU,_, rd, rs, rt)
118
+#define MIPS_DSUB_REG(rd, rs, rt) \
119
+ MIPS_OP_REG(FN_DSUBU,_, rd, rs, rt)
120
+
121
+#define MIPS_NEG_REG(rd, rt) \
122
+ MIPS_SUB_REG(rd, Z0, rt)
123
+
124
+#define MIPS_XOR_REG(rd, rs, rt) \
125
+ MIPS_OP_REG(FN_XOR,_, rd, rs, rt)
126
+#define MIPS_OR_REG(rd, rs, rt) \
127
+ MIPS_OP_REG(FN_OR,_, rd, rs, rt)
128
+#define MIPS_AND_REG(rd, rs, rt) \
129
+ MIPS_OP_REG(FN_AND,_, rd, rs, rt)
130
+#define MIPS_NOR_REG(rd, rs, rt) \
131
+ MIPS_OP_REG(FN_NOR,_, rd, rs, rt)
132
+
133
+#define MIPS_MOVE_REG(rd, rs) \
134
+ MIPS_OR_REG(rd, rs, Z0)
135
+#define MIPS_MVN_REG(rd, rs) \
136
+ MIPS_NOR_REG(rd, rs, Z0)
137
+
138
+// rd = rt SHIFT rs
139
+#define MIPS_LSL_REG(rd, rt, rs) \
140
+ MIPS_OP_REG(FN_SLLV,_, rd, rs, rt)
141
+#define MIPS_LSR_REG(rd, rt, rs) \
142
+ MIPS_OP_REG(FN_SRLV,RB_SRL, rd, rs, rt)
143
+#define MIPS_ASR_REG(rd, rt, rs) \
144
+ MIPS_OP_REG(FN_SRAV,_, rd, rs, rt)
145
+#define MIPS_ROR_REG(rd, rt, rs) \
146
+ MIPS_OP_REG(FN_SRLV,RB_ROTR, rd, rs, rt)
147
+
148
+#define MIPS_SEB_REG(rd, rt) \
149
+ MIPS_OP3_REG(FN3_BSHFL, BS_SEB, rd, _, rt)
150
+#define MIPS_SEH_REG(rd, rt) \
151
+ MIPS_OP3_REG(FN3_BSHFL, BS_SEH, rd, _, rt)
152
+
153
+#define MIPS_EXT_IMM(rt, rs, lsb, sz) \
154
+ MIPS_OP3_REG(FN3_EXT, lsb, (sz)-1, rs, rt)
155
+#define MIPS_INS_IMM(rt, rs, lsb, sz) \
156
+ MIPS_OP3_REG(FN3_INS, lsb, (lsb)+(sz)-1, rs, rt)
157
+
158
+// rd = (rs < rt)
159
+#define MIPS_SLT_REG(rd, rs, rt) \
160
+ MIPS_OP_REG(FN_SLT,_, rd, rs, rt)
161
+#define MIPS_SLTU_REG(rd, rs, rt) \
162
+ MIPS_OP_REG(FN_SLTU,_, rd, rs, rt)
163
+
164
+// rt = rs OP imm16
165
+#define MIPS_ADD_IMM(rt, rs, imm16) \
166
+ MIPS_OP_IMM(OP_ADDIU, rt, rs, imm16)
167
+#define MIPS_DADD_IMM(rt, rs, imm16) \
168
+ MIPS_OP_IMM(OP_DADDIU, rt, rs, imm16)
169
+
170
+#define MIPS_XOR_IMM(rt, rs, imm16) \
171
+ MIPS_OP_IMM(OP_XORI, rt, rs, imm16)
172
+#define MIPS_OR_IMM(rt, rs, imm16) \
173
+ MIPS_OP_IMM(OP_ORI, rt, rs, imm16)
174
+#define MIPS_AND_IMM(rt, rs, imm16) \
175
+ MIPS_OP_IMM(OP_ANDI, rt, rs, imm16)
176
+
177
+// rt = (imm16 << (0|16))
178
+#define MIPS_MOV_IMM(rt, imm16) \
179
+ MIPS_OP_IMM(OP_ORI, rt, Z0, imm16)
180
+#define MIPS_MOVT_IMM(rt, imm16) \
181
+ MIPS_OP_IMM(OP_LUI, rt, _, imm16)
182
+
183
+// rd = rt SHIFT imm5
184
+#define MIPS_LSL_IMM(rd, rt, bits) \
185
+ MIPS_INSN(OP__FN, _, rt, rd, bits, FN_SLL)
186
+#define MIPS_LSR_IMM(rd, rt, bits) \
187
+ MIPS_INSN(OP__FN, RB_SRL, rt, rd, bits, FN_SRL)
188
+#define MIPS_ASR_IMM(rd, rt, bits) \
189
+ MIPS_INSN(OP__FN, _, rt, rd, bits, FN_SRA)
190
+#define MIPS_ROR_IMM(rd, rt, bits) \
191
+ MIPS_INSN(OP__FN, RB_ROTR, rt, rd, bits, FN_SRL)
192
+
193
+#define MIPS_DLSL_IMM(rd, rt, bits) \
194
+ MIPS_INSN(OP__FN, _, rt, rd, bits, FN_DSLL)
195
+#define MIPS_DLSL32_IMM(rd, rt, bits) \
196
+ MIPS_INSN(OP__FN, _, rt, rd, bits, FN_DSLL32)
197
+
198
+// rt = (rs < imm16)
199
+#define MIPS_SLT_IMM(rt, rs, imm16) \
200
+ MIPS_OP_IMM(OP_SLTI, rt, rs, imm16)
201
libretro-picodrive-0~git20200716.tar.xz/cpu/drc/emit_ppc.c
Added
201
1
2
+/*
3
+ * Basic macros to emit PowerISA 2.03 64 bit instructions and some utils
4
+ * Copyright (C) 2020 kub
5
+ *
6
+ * This work is licensed under the terms of MAME license.
7
+ * See COPYING file in the top-level directory.
8
+ */
9
+
10
+// NB bit numbers are reversed in PPC (MSB is bit 0). The emith_* functions and
11
+// macros must take this into account.
12
+
13
+// NB PPC was a 64 bit architecture from the onset, so basically all operations
14
+// are operating on 64 bits. 32 bit arch was only added later on, and there are
15
+// very few 32 bit operations (cmp*, shift/rotate, extract/insert, load/store).
16
+// For most operations the upper bits don't spill into the lower word, for the
17
+// others there is an appropriate 32 bit operation available.
18
+
19
+// NB PowerPC isn't a clean RISC design. Several insns use microcode, which is
20
+// AFAIK notably slower than using some 2-3 non-microcode insns. So, using
21
+// such insns should by avoided if possible. Listed in Cell handbook, App. A:
22
+// - shift/rotate having the amount in a register
23
+// - arithmetic/logical having the RC flag set (except cmp*)
24
+// - load/store algebraic (l?a*), multiple (lmw/stmw), string (ls*/sts*)
25
+// - mtcrf (and some more SPR related, not used here)
26
+// moreover, misaligned load/store crossing a cacheline boundary are microcoded.
27
+// Note also that load/store string isn't available in little endian mode.
28
+
29
+// NB flag handling in PPC differs grossly from the ARM/X86 model. There are 8
30
+// fields in the condition register, each having 4 condition bits. However, only
31
+// the EQ bit is similar to the Z flag. The CA and OV bits in the XER register
32
+// are similar to the C and V bits, but shifts don't use CA, and cmp* doesn't
33
+// use CA and OV.
34
+// Moreover, there's no easy possibility to get CA and OV for 32 bit arithmetic
35
+// since all arithmetic/logical insns use 64 bit.
36
+// For now, use the "no flags" code from the RISC-V backend.
37
+
38
+#define HOST_REGS 32
39
+
40
+// PPC64: params: r3-r10, return: r3, temp: r0,r11-r12, saved: r14-r31
41
+// reserved: r0(zero), r1(stack), r2(TOC), r13(TID)
42
+#define RET_REG 3
43
+#define PARAM_REGS { 3, 4, 5, 6, 7, 8, 9, 10 }
44
+#define PRESERVED_REGS { 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }
45
+#define TEMPORARY_REGS { 11, 12 }
46
+
47
+#define CONTEXT_REG 31
48
+#define STATIC_SH2_REGS { SHR_SR,30 , SHR_R(0),29 , SHR_R(1),28 }
49
+
50
+// if RA is 0 in non-update memory insns, ADDI/ADDIS, ISEL, it aliases with zero
51
+#define Z0 0 // zero register
52
+#define SP 1 // stack pointer
53
+// SPR registers
54
+#define XER -1 // exception register
55
+#define LR -8 // link register
56
+#define CTR -9 // counter register
57
+// internally used by code emitter:
58
+#define AT 0 // emitter temporary (can't be fully used anyway)
59
+#define FNZ 14 // emulated processor flags: N (bit 31) ,Z (all bits)
60
+#define FC 15 // emulated processor flags: C (bit 0), others 0
61
+#define FV 16 // emulated processor flags: Nt^Ns (bit 31). others x
62
+
63
+
64
+// unified conditions; virtual, not corresponding to anything real on PPC
65
+#define DCOND_EQ 0x0
66
+#define DCOND_NE 0x1
67
+#define DCOND_HS 0x2
68
+#define DCOND_LO 0x3
69
+#define DCOND_MI 0x4
70
+#define DCOND_PL 0x5
71
+#define DCOND_VS 0x6
72
+#define DCOND_VC 0x7
73
+#define DCOND_HI 0x8
74
+#define DCOND_LS 0x9
75
+#define DCOND_GE 0xa
76
+#define DCOND_LT 0xb
77
+#define DCOND_GT 0xc
78
+#define DCOND_LE 0xd
79
+
80
+#define DCOND_CS DCOND_LO
81
+#define DCOND_CC DCOND_HS
82
+
83
+// unified insn; use right-aligned bit offsets for the bitfields
84
+#define PPC_INSN(op, b10, b15, b20, b31) \
85
+ (((op)<<26)|((b10)<<21)|((b15)<<16)|((b20)<<11)|((b31)<<0))
86
+
87
+#define _ 0 // marker for "field unused"
88
+#define __(n) o##n // enum marker for "undefined"
89
+#define _CB(v,l,s,d) ((((v)>>(s))&((1<<(l))-1))<<(d)) // copy l bits
90
+
91
+// NB everything privileged or unneeded at 1st sight is left out
92
+// opcode field (encoded in OPCD, bits 0-5)
93
+enum { OP__LMA=004, OP_MULLI=007,
94
+ OP_SUBFIC, __(11), OP_CMPLI, OP_CMPI, OP_ADDIC, OP_ADDICF, OP_ADDI, OP_ADDIS,
95
+ OP_BC, __(21), OP_B, OP__CR, OP_RLWIMI, OP_RLWINM, __(26), OP_RLWNM,
96
+ OP_ORI, OP_ORIS, OP_XORI, OP_XORIS, OP_ANDI, OP_ANDIS, OP__RLD, OP__EXT,
97
+ OP_LWZ, OP_LWZU, OP_LBZ, OP_LBZU, OP_STW, OP_STWU, OP_STB, OP_STBU,
98
+ OP_LHZ, OP_LHZU, OP_LHA, OP_LHAU, OP_STH, OP_STHU, OP_LMW, OP_STMW,
99
+ /*OP_LQ=070,*/ OP__LD=072, OP__ST=076 };
100
+// CR subops (encoded in bits 21-31)
101
+enum { OPC_MCRF=0, OPC_BCLR=32, OPC_BCCTR=1056 };
102
+// RLD subops (encoded in XO bits 27-31)
103
+enum { OPR_RLDICL=0, OPR_RLDICR=4, OPR_RLDIC=8, OPR_RLDIMI=12, OPR_RLDCL=16, OPR_RLDCR=18 };
104
+// EXT subops (encoded in XO bits 21-31)
105
+enum {
106
+ // arith/logical
107
+ OPE_CMP=0, OPE_SUBFC=16, OPE_ADDC=20, OPE_AND=56,
108
+ OPE_CMPL=64, OPE_SUBF=80, OPE_ANDC=120, OPE_NEG=208, OPE_NOR=248,
109
+ OPE_SUBFE=272, OPE_ADDE=276, OPE_SUBFZE=400, OPE_ADDZE=404, OPE_SUBFME=464, OPE_ADDME=468,
110
+ OPE_ADD=532, OPE_EQV=568, OPE_XOR=632, OPE_ORC=824, OPE_OR=888, OPE_NAND=952,
111
+ // shift
112
+ OPE_SLW=48, OPE_SLD=54, OPE_SRW=1072, OPE_SRD=1078, OPE_SRAW=1584, OPE_SRAD=1588, OPE_SRAWI=1648, OPE_SRADI=1652,
113
+ // extend, bitcount
114
+ OPE_CNTLZW=52, OPE_CNTLZD=116, OPE_EXTSH=1844, OPE_EXTSB=1908, OPE_EXTSW=1972,
115
+ // mult/div
116
+ OPE_MULHDU=18, OPE_MULHWU=22, OPE_MULHD=146, OPE_MULHW=150, OPE_MULLD=466, OPE_MULLW=470,
117
+ OPE_DIVDU=914, OPE_DIVWU=918, OPE_DIVD=978, OPE_DIVW=982,
118
+ // load/store indexed
119
+ OPE_LDX=42, OPE_LDUX=106, OPE_STDX=298, OPE_STDUX=362,
120
+ OPE_LWZX=46, OPE_LWZUX=110, OPE_LWAX=682, OPE_LWAUX=746, OPE_STWX=302, OPE_STWUX=366,
121
+ OPE_LBZX=174, OPE_LBZUX=238, /* no LBAX/LBAUX... */ OPE_STBX=430, OPE_STBUX=494,
122
+ OPE_LHZX=558, OPE_LHZUX=622, OPE_LHAX=686, OPE_LHAUX=750, OPE_STHX=814, OPE_STHUX=878,
123
+ // SPR, CR related
124
+ OPE_ISEL=15, OPE_MFCR=38, OPE_MTCRF=288, OPE_MFSPR=678, OPE_MTSPR=934, OPE_MCRXR=1024,
125
+};
126
+// LD subops (encoded in XO bits 30-31)
127
+enum { OPL_LD, OPL_LDU, OPL_LWA };
128
+// ST subops (encoded in XO bits 30-31)
129
+enum { OPS_STD, OPS_STDU /*,OPS_STQ*/ };
130
+
131
+// X*,M*-forms insns often have overflow detect in b21 and CR0 update in b31
132
+#define XOE (1<<10) // (31-21)
133
+#define XRC (1<<0) // (31-31)
134
+#define XF (XOE|XRC)
135
+// MB and ME in M*-forms rotate left
136
+#define MM(b,e) (((b)<<6)|((e)<<1))
137
+#define MD(b,s) (_CB(b,5,0,6)|_CB(b,1,5,5)|_CB(s,5,0,11)|_CB(s,1,5,1))
138
+// AA and LK in I,B-forms branches
139
+#define BAA (1<<1)
140
+#define BLK (1<<0)
141
+// BO and BI condition codes in B-form, BO0-BO4:BI2-BI4 since we only need CR0
142
+#define BLT 0x60
143
+#define BGE 0x20
144
+#define BGT 0x61
145
+#define BLE 0x21
146
+#define BEQ 0x62
147
+#define BNE 0x22
148
+#define BXX 0xa0 // unconditional, aka always
149
+
150
+#define PPC_NOP \
151
+ PPC_INSN(OP_ORI, 0, 0, _, 0) // ori r0, r0, 0
152
+
153
+// arithmetic/logical
154
+
155
+#define PPC_OP_REG(op, xop, rt, ra, rb) /* X*,M*-form */ \
156
+ PPC_INSN((unsigned)op, rt, ra, rb, xop)
157
+#define PPC_OP_IMM(op, rt, ra, imm) /* D,B,I-form */ \
158
+ PPC_INSN((unsigned)op, rt, ra, _, imm)
159
+
160
+// rt = ra OP rb
161
+#define PPC_ADD_REG(rt, ra, rb) \
162
+ PPC_OP_REG(OP__EXT,OPE_ADD,rt,ra,rb)
163
+#define PPC_ADDC_REG(rt, ra, rb) \
164
+ PPC_OP_REG(OP__EXT,OPE_ADD|XOE,rt,ra,rb)
165
+#define PPC_SUB_REG(rt, rb, ra) /* NB reversed args (rb-ra) */ \
166
+ PPC_OP_REG(OP__EXT,OPE_SUBF,rt,ra,rb)
167
+#define PPC_SUBC_REG(rt, rb, ra) \
168
+ PPC_OP_REG(OP__EXT,OPE_SUBF|XOE,rt,ra,rb)
169
+#define PPC_NEG_REG(rt, ra) \
170
+ PPC_OP_REG(OP__EXT,OPE_NEG,rt,ra,_)
171
+#define PPC_NEGC_REG(rt, ra) \
172
+ PPC_OP_REG(OP__EXT,OPE_NEG|XOE,rt,ra,_)
173
+
174
+#define PPC_CMP_REG(ra, rb) \
175
+ PPC_OP_REG(OP__EXT,OPE_CMP,1,ra,rb)
176
+#define PPC_CMPL_REG(ra, rb) \
177
+ PPC_OP_REG(OP__EXT,OPE_CMPL,1,ra,rb)
178
+
179
+#define PPC_CMPW_REG(ra, rb) \
180
+ PPC_OP_REG(OP__EXT,OPE_CMP,0,ra,rb)
181
+#define PPC_CMPLW_REG(ra, rb) \
182
+ PPC_OP_REG(OP__EXT,OPE_CMPL,0,ra,rb)
183
+
184
+#define PPC_XOR_REG(ra, rt, rb) \
185
+ PPC_OP_REG(OP__EXT,OPE_XOR,rt,ra,rb)
186
+#define PPC_OR_REG(ra, rt, rb) \
187
+ PPC_OP_REG(OP__EXT,OPE_OR,rt,ra,rb)
188
+#define PPC_ORN_REG(ra, rt, rb) \
189
+ PPC_OP_REG(OP__EXT,OPE_ORC,rt,ra,rb)
190
+#define PPC_NOR_REG(ra, rt, rb) \
191
+ PPC_OP_REG(OP__EXT,OPE_NOR,rt,ra,rb)
192
+#define PPC_AND_REG(ra, rt, rb) \
193
+ PPC_OP_REG(OP__EXT,OPE_AND,rt,ra,rb)
194
+#define PPC_BIC_REG(ra, rt, rb) \
195
+ PPC_OP_REG(OP__EXT,OPE_ANDC,rt,ra,rb)
196
+
197
+#define PPC_MOV_REG(rt, ra) \
198
+ PPC_OR_REG(rt, ra, ra)
199
+#define PPC_MVN_REG(rt, ra) \
200
+ PPC_NOR_REG(rt, ra, ra)
201
libretro-picodrive-0~git20200716.tar.xz/cpu/drc/emit_riscv.c
Added
201
1
2
+/*
3
+ * Basic macros to emit RISC-V RV64IM instructions and some utils
4
+ * Copyright (C) 2019 kub
5
+ *
6
+ * This work is licensed under the terms of MAME license.
7
+ * See COPYING file in the top-level directory.
8
+ */
9
+#define HOST_REGS 32
10
+
11
+// RISC-V ABI: params: x10-x17, return: x10-x11, temp: x1(ra),x5-x7,x28-x31
12
+// saved: x8(fp),x9,x18-x27, reserved: x0(zero), x4(tp), x3(gp), x2(sp)
13
+// x28-x31(t3-t6) are used internally by the code emitter
14
+#define RET_REG 10 // a0
15
+#define PARAM_REGS { 10, 11, 12, 13, 14, 15, 16, 17 } // a0-a7
16
+#define PRESERVED_REGS { 9, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 } // s1-s11
17
+#define TEMPORARY_REGS { 5, 6, 7 } // t0-t2
18
+
19
+#define CONTEXT_REG 9 // s1
20
+#define STATIC_SH2_REGS { SHR_SR,27 , SHR_R(0),26 , SHR_R(1),25 }
21
+
22
+// registers usable for user code: r1-r25, others reserved or special
23
+#define Z0 0 // zero register
24
+#define GP 3 // global pointer
25
+#define SP 2 // stack pointer
26
+#define FP 8 // frame pointer
27
+#define LR 1 // link register
28
+// internally used by code emitter:
29
+#define AT 31 // used to hold intermediate results
30
+#define FNZ 30 // emulated processor flags: N (bit 31) ,Z (all bits)
31
+#define FC 29 // emulated processor flags: C (bit 0), others 0
32
+#define FV 28 // emulated processor flags: Nt^Ns (bit 31). others x
33
+
34
+// All operations but ptr ops are using the lower 32 bits of the registers.
35
+// The upper 32 bits always contain the sign extension from the lower 32 bits.
36
+
37
+// unified conditions; virtual, not corresponding to anything real on RISC-V
38
+#define DCOND_EQ 0x0
39
+#define DCOND_NE 0x1
40
+#define DCOND_HS 0x2
41
+#define DCOND_LO 0x3
42
+#define DCOND_MI 0x4
43
+#define DCOND_PL 0x5
44
+#define DCOND_VS 0x6
45
+#define DCOND_VC 0x7
46
+#define DCOND_HI 0x8
47
+#define DCOND_LS 0x9
48
+#define DCOND_GE 0xa
49
+#define DCOND_LT 0xb
50
+#define DCOND_GT 0xc
51
+#define DCOND_LE 0xd
52
+
53
+#define DCOND_CS DCOND_LO
54
+#define DCOND_CC DCOND_HS
55
+
56
+// unified insn
57
+#define R5_INSN(b25, b20, b15, b12, b7, op) \
58
+ (((b25)<<25)|((b20)<<20)|((b15)<<15)|((b12)<<12)|((b7)<<7)|((op)<<0))
59
+
60
+#define _ 0 //marker for "field unused"
61
+#define _CB(v,l,s,d) ((((v)>>(s))&((1<<(l))-1))<<(d)) // copy l bits
62
+
63
+#define R5_R_INSN(op, f1, f2, rd, rs, rt) \
64
+ R5_INSN(f2, rt, rs, f1, rd, op)
65
+#define R5_I_INSN(op, f1, rd, rs, imm) \
66
+ R5_INSN(_, _CB(imm,12,0,0), rs, f1, rd, op)
67
+#define R5_S_INSN(op, f1, rt, rs, imm) \
68
+ R5_INSN(_CB(imm,7,5,0), rt, rs, f1, _CB(imm,5,0,0), op)
69
+#define R5_U_INSN(op, rd, imm) \
70
+ R5_INSN(_,_,_, _CB(imm,20,12,0), rd, op)
71
+// oy vey... R5 immediate encoding in branches is really unwieldy :-/
72
+#define R5_B_INSN(op, f1, rt, rs, imm) \
73
+ R5_INSN(_CB(imm,1,12,6)|_CB(imm,6,5,0), rt, rs, f1, \
74
+ _CB(imm,4,1,1)|_CB(imm,1,11,0), op)
75
+#define R5_J_INSN(op, rd, imm) \
76
+ R5_INSN(_CB(imm,1,20,6)|_CB(imm,6,5,0), _CB(imm,4,1,1)|_CB(imm,1,11,0),\
77
+ _CB(imm,8,12,0), rd, op)
78
+
79
+// opcode
80
+enum { OP_LUI=0x37, OP_AUIPC=0x17, OP_JAL=0x6f, // 20-bit immediate
81
+ OP_JALR=0x67, OP_BCOND=0x63, OP_LD=0x03, OP_ST=0x23, // 12-bit immediate
82
+ OP_IMM=0x13, OP_REG=0x33, OP_IMM32=0x1b, OP_REG32=0x3b };
83
+// func3
84
+enum { F1_ADD, F1_SL, F1_SLT, F1_SLTU, F1_XOR, F1_SR, F1_OR, F1_AND };// IMM/REG
85
+enum { F1_MUL, F1_MULH, F1_MULHSU, F1_MULHU, F1_DIV, F1_DIVU, F1_REM, F1_REMU };
86
+enum { F1_BEQ, F1_BNE, F1_BLT=4, F1_BGE, F1_BLTU, F1_BGEU }; // BCOND
87
+enum { F1_B, F1_H, F1_W, F1_D, F1_BU, F1_HU, F1_WU }; // LD/ST
88
+// func7
89
+enum { F2_ALT=0x20, F2_MULDIV=0x01 };
90
+
91
+#define R5_NOP R5_I_INSN(OP_IMM, F1_ADD, Z0, Z0, 0) // nop: ADDI r0, r0, #0
92
+
93
+// arithmetic/logical
94
+
95
+// rd = rs OP rt
96
+#define R5_ADD_REG(rd, rs, rt) \
97
+ R5_R_INSN(OP_REG, F1_ADD, _, rd, rs, rt)
98
+#define R5_SUB_REG(rd, rs, rt) \
99
+ R5_R_INSN(OP_REG, F1_ADD, F2_ALT, rd, rs, rt)
100
+
101
+#define R5_NEG_REG(rd, rt) \
102
+ R5_SUB_REG(rd, Z0, rt)
103
+
104
+#define R5_XOR_REG(rd, rs, rt) \
105
+ R5_R_INSN(OP_REG, F1_XOR, _, rd, rs, rt)
106
+#define R5_OR_REG(rd, rs, rt) \
107
+ R5_R_INSN(OP_REG, F1_OR , _, rd, rs, rt)
108
+#define R5_AND_REG(rd, rs, rt) \
109
+ R5_R_INSN(OP_REG, F1_AND, _, rd, rs, rt)
110
+
111
+// rd = rs SHIFT rt
112
+#define R5_LSL_REG(rd, rs, rt) \
113
+ R5_R_INSN(OP_REG, F1_SL , _, rd, rs, rt)
114
+#define R5_LSR_REG(rd, rs, rt) \
115
+ R5_R_INSN(OP_REG, F1_SR , _, rd, rs, rt)
116
+#define R5_ASR_REG(rd, rs, rt) \
117
+ R5_R_INSN(OP_REG, F1_SR , F2_ALT, rd, rs, rt)
118
+
119
+// rd = (rs < rt)
120
+#define R5_SLT_REG(rd, rs, rt) \
121
+ R5_R_INSN(OP_REG, F1_SLT, _, rd, rs, rt)
122
+#define R5_SLTU_REG(rd, rs, rt) \
123
+ R5_R_INSN(OP_REG, F1_SLTU,_, rd, rs, rt)
124
+
125
+// rd = rs OP imm12
126
+#define R5_ADD_IMM(rd, rs, imm12) \
127
+ R5_I_INSN(OP_IMM, F1_ADD , rd, rs, imm12)
128
+
129
+#define R5_XOR_IMM(rd, rs, imm12) \
130
+ R5_I_INSN(OP_IMM, F1_XOR , rd, rs, imm12)
131
+#define R5_OR_IMM(rd, rs, imm12) \
132
+ R5_I_INSN(OP_IMM, F1_OR , rd, rs, imm12)
133
+#define R5_AND_IMM(rd, rs, imm12) \
134
+ R5_I_INSN(OP_IMM, F1_AND , rd, rs, imm12)
135
+
136
+#define R5_MOV_REG(rd, rs) \
137
+ R5_ADD_IMM(rd, rs, 0)
138
+#define R5_MVN_REG(rd, rs) \
139
+ R5_XOR_IMM(rd, rs, -1)
140
+
141
+// rd = (imm12 << (0|12))
142
+#define R5_MOV_IMM(rd, imm12) \
143
+ R5_OR_IMM(rd, Z0, imm12)
144
+#define R5_MOVT_IMM(rd, imm20) \
145
+ R5_U_INSN(OP_LUI, rd, imm20)
146
+#define R5_MOVA_IMM(rd, imm20) \
147
+ R5_U_INSN(OP_AUIPC, rd, imm20)
148
+
149
+// rd = rs SHIFT imm5/imm6
150
+#define R5_LSL_IMM(rd, rs, bits) \
151
+ R5_R_INSN(OP_IMM, F1_SL , _, rd, rs, bits)
152
+#define R5_LSR_IMM(rd, rs, bits) \
153
+ R5_R_INSN(OP_IMM, F1_SR , _, rd, rs, bits)
154
+#define R5_ASR_IMM(rd, rs, bits) \
155
+ R5_R_INSN(OP_IMM, F1_SR , F2_ALT, rd, rs, bits)
156
+
157
+// rd = (rs < imm12)
158
+#define R5_SLT_IMM(rd, rs, imm12) \
159
+ R5_I_INSN(OP_IMM, F1_SLT , rd, rs, imm12)
160
+#define R5_SLTU_IMM(rd, rs, imm12) \
161
+ R5_I_INSN(OP_IMM, F1_SLTU, rd, rs, imm12)
162
+
163
+// multiplication
164
+
165
+#define R5_MULHU(rd, rs, rt) \
166
+ R5_R_INSN(OP_REG, F1_MULHU, F2_MULDIV, rd, rs, rt)
167
+#define R5_MULHS(rd, rs, rt) \
168
+ R5_R_INSN(OP_REG, F1_MULH, F2_MULDIV, rd, rs, rt)
169
+#define R5_MUL(rd, rs, rt) \
170
+ R5_R_INSN(OP_REG, F1_MUL, F2_MULDIV, rd, rs, rt)
171
+
172
+// branching
173
+
174
+#define R5_J(imm20) \
175
+ R5_J_INSN(OP_JAL, Z0, imm20)
176
+#define R5_JAL(rd, imm20) \
177
+ R5_J_INSN(OP_JAL, rd, imm20)
178
+#define R5_JR(rs, offs12) \
179
+ R5_I_INSN(OP_JALR, _, Z0, rs, offs12)
180
+#define R5_JALR(rd, rs, offs12) \
181
+ R5_I_INSN(OP_JALR, _, rd, rs, offs12)
182
+
183
+// conditional branches; no condition code, these compare rs against rt
184
+#define R5_BCOND(cond, rs, rt, offs13) \
185
+ R5_B_INSN(OP_BCOND, cond, rt, rs, offs13)
186
+#define R5_BCONDZ(cond, rs, offs13) \
187
+ R5_B_INSN(OP_BCOND, cond, Z0, rs, offs13)
188
+#define R5_B(offs13) \
189
+ R5_BCOND(F1_BEQ, Z0, Z0, offs13)
190
+
191
+// load/store indexed base
192
+
193
+#define R5_LW(rd, rs, offs12) \
194
+ R5_I_INSN(OP_LD, F1_W, rd, rs, offs12)
195
+#define R5_LH(rd, rs, offs12) \
196
+ R5_I_INSN(OP_LD, F1_H, rd, rs, offs12)
197
+#define R5_LB(rd, rs, offs12) \
198
+ R5_I_INSN(OP_LD, F1_B, rd, rs, offs12)
199
+#define R5_LHU(rd, rs, offs12) \
200
+ R5_I_INSN(OP_LD, F1_HU, rd, rs, offs12)
201
libretro-picodrive-0~git20200112.tar.xz/cpu/drc/emit_x86.c -> libretro-picodrive-0~git20200716.tar.xz/cpu/drc/emit_x86.c
Changed
201
1
2
/*
3
* Basic macros to emit x86 instructions and some utils
4
* Copyright (C) 2008,2009,2010 notaz
5
+ * Copyright (C) 2019 kub
6
*
7
* This work is licensed under the terms of MAME license.
8
* See COPYING file in the top-level directory.
9
10
*/
11
#include <stdarg.h>
12
13
-enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
14
+enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI, // x86-64,i386 common
15
+ xR8, xR9, xR10, xR11, xR12, xR13, xR14, xR15 }; // x86-64 only
16
17
-#define CONTEXT_REG xBP
18
-#define RET_REG xAX
19
+#define CONTEXT_REG xBP
20
+#define RET_REG xAX
21
22
#define ICOND_JO 0x00
23
#define ICOND_JNO 0x01
24
25
#define DCOND_VS ICOND_JO // oVerflow Set
26
#define DCOND_VC ICOND_JNO // oVerflow Clear
27
28
+#define DCOND_CS ICOND_JB // carry set
29
+#define DCOND_CC ICOND_JAE // carry clear
30
+
31
#define EMIT_PTR(ptr, val, type) \
32
*(type *)(ptr) = val
33
34
35
36
#define EMIT_OP(op) do { \
37
COUNT_OP; \
38
- EMIT(op, u8); \
39
+ if ((op) > 0xff) EMIT((op) >> 8, u8); \
40
+ EMIT((u8)(op), u8); \
41
} while (0)
42
43
#define EMIT_MODRM(mod, r, rm) do { \
44
45
EMIT_PTR(ptr + 1, (tcache_ptr - (ptr+2)), u8)
46
47
// _r_r
48
-#define emith_move_r_r(dst, src) \
49
- EMIT_OP_MODRM(0x8b, 3, dst, src)
50
+#define emith_move_r_r(dst, src) do {\
51
+ EMIT_REX_IF(0, dst, src); \
52
+ EMIT_OP_MODRM64(0x8b, 3, dst, src); \
53
+} while (0)
54
55
#define emith_move_r_r_ptr(dst, src) do { \
56
EMIT_REX_IF(1, dst, src); \
57
EMIT_OP_MODRM64(0x8b, 3, dst, src); \
58
} while (0)
59
60
-#define emith_add_r_r(d, s) \
61
- EMIT_OP_MODRM(0x01, 3, s, d)
62
+#define emith_add_r_r(d, s) do { \
63
+ EMIT_REX_IF(0, s, d); \
64
+ EMIT_OP_MODRM64(0x01, 3, s, d); \
65
+} while (0)
66
67
-#define emith_sub_r_r(d, s) \
68
- EMIT_OP_MODRM(0x29, 3, s, d)
69
+#define emith_add_r_r_ptr(d, s) do { \
70
+ EMIT_REX_IF(1, s, d); \
71
+ EMIT_OP_MODRM64(0x01, 3, s, d); \
72
+} while (0)
73
74
-#define emith_adc_r_r(d, s) \
75
- EMIT_OP_MODRM(0x11, 3, s, d)
76
+#define emith_sub_r_r(d, s) do {\
77
+ EMIT_REX_IF(0, s, d); \
78
+ EMIT_OP_MODRM64(0x29, 3, s, d); \
79
+} while (0)
80
81
-#define emith_sbc_r_r(d, s) \
82
- EMIT_OP_MODRM(0x19, 3, s, d) /* SBB */
83
+#define emith_adc_r_r(d, s) do { \
84
+ EMIT_REX_IF(0, s, d); \
85
+ EMIT_OP_MODRM64(0x11, 3, s, d); \
86
+} while (0)
87
88
-#define emith_or_r_r(d, s) \
89
- EMIT_OP_MODRM(0x09, 3, s, d)
90
+#define emith_sbc_r_r(d, s) do { \
91
+ EMIT_REX_IF(0, s, d); \
92
+ EMIT_OP_MODRM64(0x19, 3, s, d); /* SBB */ \
93
+} while (0)
94
95
-#define emith_and_r_r(d, s) \
96
- EMIT_OP_MODRM(0x21, 3, s, d)
97
+#define emith_or_r_r(d, s) do { \
98
+ EMIT_REX_IF(0, s, d); \
99
+ EMIT_OP_MODRM64(0x09, 3, s, d); \
100
+} while (0)
101
102
-#define emith_eor_r_r(d, s) \
103
- EMIT_OP_MODRM(0x31, 3, s, d) /* XOR */
104
+#define emith_and_r_r(d, s) do { \
105
+ EMIT_REX_IF(0, s, d); \
106
+ EMIT_OP_MODRM64(0x21, 3, s, d); \
107
+} while (0)
108
109
-#define emith_tst_r_r(d, s) \
110
- EMIT_OP_MODRM(0x85, 3, s, d) /* TEST */
111
+#define emith_eor_r_r(d, s) do { \
112
+ EMIT_REX_IF(0, s, d); \
113
+ EMIT_OP_MODRM64(0x31, 3, s, d); /* XOR */ \
114
+} while (0)
115
+
116
+#define emith_tst_r_r(d, s) do { \
117
+ EMIT_REX_IF(0, s, d); \
118
+ EMIT_OP_MODRM64(0x85, 3, s, d); /* TEST */ \
119
+} while (0)
120
121
#define emith_tst_r_r_ptr(d, s) do { \
122
EMIT_REX_IF(1, s, d); \
123
EMIT_OP_MODRM64(0x85, 3, s, d); /* TEST */ \
124
} while (0)
125
126
-#define emith_cmp_r_r(d, s) \
127
- EMIT_OP_MODRM(0x39, 3, s, d)
128
+#define emith_cmp_r_r(d, s) do { \
129
+ EMIT_REX_IF(0, s, d); \
130
+ EMIT_OP_MODRM64(0x39, 3, s, d); \
131
+} while (0)
132
133
// fake teq - test equivalence - get_flags(d ^ s)
134
#define emith_teq_r_r(d, s) do { \
135
136
#define emith_mvn_r_r(d, s) do { \
137
if (d != s) \
138
emith_move_r_r(d, s); \
139
- EMIT_OP_MODRM(0xf7, 3, 2, d); /* NOT d */ \
140
+ EMIT_REX_IF(0, 0, d); \
141
+ EMIT_OP_MODRM64(0xf7, 3, 2, d); /* NOT d */ \
142
} while (0)
143
144
#define emith_negc_r_r(d, s) do { \
145
146
#define emith_neg_r_r(d, s) do { \
147
if (d != s) \
148
emith_move_r_r(d, s); \
149
- EMIT_OP_MODRM(0xf7, 3, 3, d); /* NEG d */ \
150
+ EMIT_REX_IF(0, 0, d); \
151
+ EMIT_OP_MODRM64(0xf7, 3, 3, d); /* NEG d */ \
152
} while (0)
153
154
// _r_r_r
155
156
} \
157
} while (0)
158
159
+#define emith_add_r_r_r_ptr(d, s1, s2) do { \
160
+ if (d == s1) { \
161
+ emith_add_r_r_ptr(d, s2); \
162
+ } else if (d == s2) { \
163
+ emith_add_r_r_ptr(d, s1); \
164
+ } else { \
165
+ emith_move_r_r_ptr(d, s1); \
166
+ emith_add_r_r_ptr(d, s2); \
167
+ } \
168
+} while (0)
169
+
170
+#define emith_sub_r_r_r(d, s1, s2) do { \
171
+ if (d == s1) { \
172
+ emith_sub_r_r(d, s2); \
173
+ } else if (d == s2) { \
174
+ emith_sub_r_r(d, s1); \
175
+ } else { \
176
+ emith_move_r_r(d, s1); \
177
+ emith_sub_r_r(d, s2); \
178
+ } \
179
+} while (0)
180
+
181
+#define emith_adc_r_r_r(d, s1, s2) do { \
182
+ if (d == s1) { \
183
+ emith_adc_r_r(d, s2); \
184
+ } else if (d == s2) { \
185
+ emith_adc_r_r(d, s1); \
186
+ } else { \
187
+ emith_move_r_r(d, s1); \
188
+ emith_adc_r_r(d, s2); \
189
+ } \
190
+} while (0)
191
+
192
+#define emith_sbc_r_r_r(d, s1, s2) do { \
193
+ if (d == s1) { \
194
+ emith_sbc_r_r(d, s2); \
195
+ } else if (d == s2) { \
196
+ emith_sbc_r_r(d, s1); \
197
+ } else { \
198
+ emith_move_r_r(d, s1); \
199
+ emith_sbc_r_r(d, s2); \
200
+ } \
201
libretro-picodrive-0~git20200112.tar.xz/cpu/sh2/compiler.c -> libretro-picodrive-0~git20200716.tar.xz/cpu/sh2/compiler.c
Changed
201
1
2
/*
3
* SH2 recompiler
4
* (C) notaz, 2009,2010,2013
5
+ * (C) kub, 2018,2019,2020
6
*
7
* This work is licensed under the terms of MAME license.
8
* See COPYING file in the top-level directory.
9
*
10
* notes:
11
- * - tcache, block descriptor, link buffer overflows result in sh2_translate()
12
- * failure, followed by full tcache invalidation for that region
13
+ * - tcache, block descriptor, block entry buffer overflows result in oldest
14
+ * blocks being deleted until enough space is available
15
+ * - link and list element buffer overflows result in failure and exit
16
* - jumps between blocks are tracked for SMC handling (in block_entry->links),
17
- * except jumps between different tcaches
18
+ * except jumps from global to CPU-local tcaches
19
*
20
* implemented:
21
* - static register allocation
22
* - remaining register caching and tracking in temporaries
23
* - block-local branch linking
24
- * - block linking (except between tcaches)
25
+ * - block linking
26
* - some constant propagation
27
+ * - call stack caching for host block entry address
28
+ * - delay, poll, and idle loop detection and handling
29
+ * - some T/M flag optimizations where the value is known or isn't used
30
*
31
* TODO:
32
* - better constant propagation
33
- * - stack caching?
34
* - bug fixing
35
*/
36
#include <stddef.h>
37
38
// features
39
#define PROPAGATE_CONSTANTS 1
40
#define LINK_BRANCHES 1
41
-
42
-// limits (per block)
43
-#define MAX_BLOCK_SIZE (BLOCK_INSN_LIMIT * 6 * 6)
44
-
45
-// max literal offset from the block end
46
-#define MAX_LITERAL_OFFSET 32*2
47
-#define MAX_LITERALS (BLOCK_INSN_LIMIT / 4)
48
-#define MAX_LOCAL_BRANCHES 32
49
+#define BRANCH_CACHE 1
50
+#define CALL_STACK 1
51
+#define ALIAS_REGISTERS 1
52
+#define REMAP_REGISTER 1
53
+#define LOOP_DETECTION 1
54
+#define LOOP_OPTIMIZER 1
55
+#define T_OPTIMIZER 1
56
+#define DIV_OPTIMIZER 0
57
+
58
+#define MAX_LITERAL_OFFSET 0x200 // max. MOVA, MOV @(PC) offset
59
+#define MAX_LOCAL_TARGETS (BLOCK_INSN_LIMIT / 4)
60
+#define MAX_LOCAL_BRANCHES (BLOCK_INSN_LIMIT / 2)
61
62
// debug stuff
63
// 01 - warnings/errors
64
65
// 04 - asm
66
// 08 - runtime block entry log
67
// 10 - smc self-check
68
+// 20 - runtime block entry counter
69
+// 40 - rcache checking
70
+// 80 - branch cache statistics
71
+// 100 - write trace
72
+// 200 - compare trace
73
+// 400 - block entry backtrace on exit
74
+// 800 - state dump on exit
75
// {
76
#ifndef DRC_DEBUG
77
-#define DRC_DEBUG 0
78
+#define DRC_DEBUG 0//x847
79
#endif
80
81
#if DRC_DEBUG
82
83
#define dbg(...)
84
#endif
85
86
+
87
///
88
#define FETCH_OP(pc) \
89
dr_pc_base[(pc) / 2]
90
91
#define GET_Rn() \
92
((op >> 8) & 0x0f)
93
94
-#define BITMASK1(v0) (1 << (v0))
95
-#define BITMASK2(v0,v1) ((1 << (v0)) | (1 << (v1)))
96
-#define BITMASK3(v0,v1,v2) (BITMASK2(v0,v1) | (1 << (v2)))
97
-#define BITMASK4(v0,v1,v2,v3) (BITMASK3(v0,v1,v2) | (1 << (v3)))
98
-#define BITMASK5(v0,v1,v2,v3,v4) (BITMASK4(v0,v1,v2,v3) | (1 << (v4)))
99
+#define SHR_T 30 // separate T for not-used detection
100
+#define SHR_MEM 31
101
+#define SHR_TMP -1
102
103
-#define SHR_T SHR_SR // might make them separate someday
104
+#define T 0x00000001
105
+#define S 0x00000002
106
+#define I 0x000000f0
107
+#define Q 0x00000100
108
+#define M 0x00000200
109
+#define T_save 0x00000800
110
+
111
+#define I_SHIFT 4
112
+#define Q_SHIFT 8
113
+#define M_SHIFT 9
114
+#define T_SHIFT 11
115
116
static struct op_data {
117
u8 op;
118
119
enum op_types {
120
OP_UNHANDLED = 0,
121
OP_BRANCH,
122
+ OP_BRANCH_N, // conditional known not to be taken
123
OP_BRANCH_CT, // conditional, branch if T set
124
OP_BRANCH_CF, // conditional, branch if T clear
125
OP_BRANCH_R, // indirect
126
OP_BRANCH_RF, // indirect far (PC + Rm)
127
OP_SETCLRT, // T flag set/clear
128
OP_MOVE, // register move
129
+ OP_LOAD_CONST,// load const to register
130
OP_LOAD_POOL, // literal pool load, imm is address
131
- OP_MOVA,
132
- OP_SLEEP,
133
- OP_RTE,
134
+ OP_MOVA, // MOVA instruction
135
+ OP_SLEEP, // SLEEP instruction
136
+ OP_RTE, // RTE instruction
137
+ OP_TRAPA, // TRAPA instruction
138
+ OP_LDC, // LDC instruction
139
+ OP_DIV0, // DIV0[US] instruction
140
+ OP_UNDEFINED,
141
};
142
143
-#ifdef DRC_SH2
144
+struct div {
145
+ u32 state:1; // 0: expect DIV1/ROTCL, 1: expect DIV1
146
+ u32 rn:5, rm:5, ro:5; // rn and rm for DIV1, ro for ROTCL
147
+ u32 div1:8, rotcl:8; // DIV1 count, ROTCL count
148
+};
149
+union _div { u32 imm; struct div div; }; // XXX tut-tut type punning...
150
+#define div(opd) ((union _div *)&((opd)->imm))->div
151
152
-static int literal_disabled_frames;
153
+// XXX consider trap insns: OP_TRAPA, OP_UNDEFINED?
154
+#define OP_ISBRANCH(op) ((BITRANGE(OP_BRANCH, OP_BRANCH_RF)| BITMASK1(OP_RTE)) \
155
+ & BITMASK1(op))
156
+#define OP_ISBRAUC(op) (BITMASK4(OP_BRANCH, OP_BRANCH_R, OP_BRANCH_RF, OP_RTE) \
157
+ & BITMASK1(op))
158
+#define OP_ISBRACND(op) (BITMASK2(OP_BRANCH_CT, OP_BRANCH_CF) \
159
+ & BITMASK1(op))
160
+#define OP_ISBRAIMM(op) (BITMASK3(OP_BRANCH, OP_BRANCH_CT, OP_BRANCH_CF) \
161
+ & BITMASK1(op))
162
+#define OP_ISBRAIND(op) (BITMASK3(OP_BRANCH_R, OP_BRANCH_RF, OP_RTE) \
163
+ & BITMASK1(op))
164
+
165
+#ifdef DRC_SH2
166
167
#if (DRC_DEBUG & 4)
168
static u8 *tcache_dsm_ptrs[3];
169
static char sh2dasm_buff[64];
170
#define do_host_disasm(tcid) \
171
- host_dasm(tcache_dsm_ptrs[tcid], tcache_ptr - tcache_dsm_ptrs[tcid]); \
172
- tcache_dsm_ptrs[tcid] = tcache_ptr
173
+ host_dasm(tcache_dsm_ptrs[tcid], emith_insn_ptr() - tcache_dsm_ptrs[tcid]); \
174
+ tcache_dsm_ptrs[tcid] = emith_insn_ptr()
175
#else
176
#define do_host_disasm(x)
177
#endif
178
179
-#if (DRC_DEBUG & 8) || defined(PDB)
180
+#define SH2_DUMP(sh2, reason) { \
181
+ char ms = (sh2)->is_slave ? 's' : 'm'; \
182
+ printf("%csh2 %s %08x\n", ms, reason, (sh2)->pc); \
183
+ printf("%csh2 r0-7 %08x %08x %08x %08x %08x %08x %08x %08x\n", ms, \
184
+ (sh2)->r[0], (sh2)->r[1], (sh2)->r[2], (sh2)->r[3], \
185
+ (sh2)->r[4], (sh2)->r[5], (sh2)->r[6], (sh2)->r[7]); \
186
+ printf("%csh2 r8-15 %08x %08x %08x %08x %08x %08x %08x %08x\n", ms, \
187
+ (sh2)->r[8], (sh2)->r[9], (sh2)->r[10], (sh2)->r[11], \
188
+ (sh2)->r[12], (sh2)->r[13], (sh2)->r[14], (sh2)->r[15]); \
189
+ printf("%csh2 pc-ml %08x %08x %08x %08x %08x %08x %08x %08x\n", ms, \
190
+ (sh2)->pc, (sh2)->ppc, (sh2)->pr, (sh2)->sr&0xfff, \
191
+ (sh2)->gbr, (sh2)->vbr, (sh2)->mach, (sh2)->macl); \
192
+ printf("%csh2 tmp-p %08x %08x %08x %08x %08x %08x %08x %08x\n", ms, \
193
+ (sh2)->drc_tmp, (sh2)->irq_cycles, \
194
+ (sh2)->pdb_io_csum[0], (sh2)->pdb_io_csum[1], (sh2)->state, \
195
+ (sh2)->poll_addr, (sh2)->poll_cycles, (sh2)->poll_cnt); \
196
+}
197
+
198
+#if (DRC_DEBUG & (8|256|512|1024)) || defined(PDB)
199
+#if (DRC_DEBUG & (256|512|1024))
200
+static SH2 csh2[2][8];
201
libretro-picodrive-0~git20200112.tar.xz/cpu/sh2/compiler.h -> libretro-picodrive-0~git20200716.tar.xz/cpu/sh2/compiler.h
Changed
97
1
2
int sh2_drc_init(SH2 *sh2);
3
void sh2_drc_finish(SH2 *sh2);
4
-void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid);
5
-void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid);
6
+void sh2_drc_wcheck_ram(uint32_t a, unsigned len, SH2 *sh2);
7
+void sh2_drc_wcheck_da(uint32_t a, unsigned len, SH2 *sh2);
8
9
#ifdef DRC_SH2
10
void sh2_drc_mem_setup(SH2 *sh2);
11
void sh2_drc_flush_all(void);
12
-void sh2_drc_frame(void);
13
#else
14
#define sh2_drc_mem_setup(x)
15
#define sh2_drc_flush_all()
16
#define sh2_drc_frame()
17
#endif
18
19
-#define BLOCK_INSN_LIMIT 128
20
+#define BLOCK_INSN_LIMIT 1024
21
22
/* op_flags */
23
#define OF_DELAY_OP (1 << 0)
24
#define OF_BTARGET (1 << 1)
25
-#define OF_T_SET (1 << 2) // T is known to be set
26
-#define OF_T_CLEAR (1 << 3) // ... clear
27
+#define OF_LOOP (3 << 2) // NONE, IDLE, DELAY, POLL loop
28
#define OF_B_IN_DS (1 << 4)
29
+#define OF_DELAY_INSN (1 << 5) // DT, (TODO ADD+CMP?)
30
+#define OF_POLL_INSN (1 << 6) // MOV @(...),Rn (no post increment), TST @(...)
31
+#define OF_BASIC_LOOP (1 << 7) // pinnable loop without any branches in it
32
33
-void scan_block(unsigned int base_pc, int is_slave,
34
- unsigned char *op_flags, unsigned int *end_pc,
35
- unsigned int *end_literals);
36
+#define OF_IDLE_LOOP (1 << 2)
37
+#define OF_DELAY_LOOP (2 << 2)
38
+#define OF_POLL_LOOP (3 << 2)
39
+
40
+unsigned short scan_block(uint32_t base_pc, int is_slave,
41
+ unsigned char *op_flags, uint32_t *end_pc,
42
+ uint32_t *base_literals, uint32_t *end_literals);
43
+
44
+#if defined(DRC_SH2) && defined(__GNUC__) && !defined(__clang__)
45
+// direct access to some host CPU registers used by the DRC if gcc is used.
46
+// XXX MUST match SHR_SR definitions in cpu/drc/emit_*.c; should be moved there
47
+// XXX yuck, there's no portable way to determine register size. Use long long
48
+// if target is 64 bit and data model is ILP32 or LLP64(windows), else long
49
+#if defined(__arm__)
50
+#define DRC_SR_REG "r10"
51
+#define DRC_REG_LL 0 // 32 bit
52
+#elif defined(__aarch64__)
53
+#define DRC_SR_REG "r28"
54
+#define DRC_REG_LL (__ILP32__ || _WIN32)
55
+#elif defined(__mips__)
56
+#define DRC_SR_REG "s6"
57
+#define DRC_REG_LL (_MIPS_SIM == _ABIN32)
58
+#elif defined(__riscv__) || defined(__riscv)
59
+#define DRC_SR_REG "s11"
60
+#define DRC_REG_LL 0 // no ABI for (__ILP32__ && __riscv_xlen != 32)
61
+#elif defined(__powerpc__)
62
+#define DRC_SR_REG "r30"
63
+#define DRC_REG_LL 0 // no ABI for __ILP32__
64
+#elif defined(__i386__)
65
+#define DRC_SR_REG "edi"
66
+#define DRC_REG_LL 0 // 32 bit
67
+#elif defined(__x86_64__)
68
+#define DRC_SR_REG "rbx"
69
+#define DRC_REG_LL (__ILP32__ || _WIN32)
70
+#endif
71
+#endif
72
+
73
+#ifdef DRC_SR_REG
74
+// XXX this is more clear but produces too much overhead for slow platforms
75
+extern void REGPARM(1) (*sh2_drc_save_sr)(SH2 *sh2);
76
+extern void REGPARM(1) (*sh2_drc_restore_sr)(SH2 *sh2);
77
+
78
+// NB: sh2_sr MUST have register size if optimizing with -O3 (-fif-conversion)
79
+#if DRC_REG_LL
80
+#define DRC_DECLARE_SR register long long _sh2_sr asm(DRC_SR_REG)
81
+#else
82
+#define DRC_DECLARE_SR register long _sh2_sr asm(DRC_SR_REG)
83
+#endif
84
+#define DRC_SAVE_SR(sh2) \
85
+ if (likely(sh2->state & SH2_IN_DRC)) \
86
+ sh2->sr = (s32)_sh2_sr
87
+// sh2_drc_save_sr(sh2)
88
+#define DRC_RESTORE_SR(sh2) \
89
+ if (likely(sh2->state & SH2_IN_DRC)) \
90
+ _sh2_sr = (s32)sh2->sr
91
+// sh2_drc_restore_sr(sh2)
92
+#else
93
+#define DRC_DECLARE_SR
94
+#define DRC_SAVE_SR(sh2)
95
+#define DRC_RESTORE_SR(sh2)
96
+#endif
97
libretro-picodrive-0~git20200112.tar.xz/cpu/sh2/mame/sh2.c -> libretro-picodrive-0~git20200716.tar.xz/cpu/sh2/mame/sh2.c
Changed
35
1
2
#if BUSY_LOOP_HACKS
3
if (disp == -2)
4
{
5
- UINT32 next_opcode = RW( sh2, sh2->ppc & AM );
6
+ UINT32 next_opcode = (UINT32)(UINT16)RW( sh2, sh2->ppc & AM );
7
/* BRA $
8
* NOP
9
*/
10
11
sh2->sr &= ~T;
12
#if BUSY_LOOP_HACKS
13
{
14
- UINT32 next_opcode = RW( sh2, sh2->ppc & AM );
15
+ UINT32 next_opcode = (UINT32)(UINT16)RW( sh2, sh2->ppc & AM );
16
/* DT Rn
17
* BF $-2
18
*/
19
20
INT32 tempm, tempn, dest, src, ans;
21
UINT32 templ;
22
23
- tempn = (INT32) RW( sh2, sh2->r[n] );
24
+ tempn = (INT32)(INT16) RW( sh2, sh2->r[n] );
25
sh2->r[n] += 2;
26
- tempm = (INT32) RW( sh2, sh2->r[m] );
27
+ tempm = (INT32)(INT16) RW( sh2, sh2->r[m] );
28
sh2->r[m] += 2;
29
templ = sh2->macl;
30
- tempm = ((INT32) (short) tempn * (INT32) (short) tempm);
31
+ tempm = (tempn * tempm);
32
if ((INT32) sh2->macl >= 0)
33
dest = 0;
34
else
35
libretro-picodrive-0~git20200112.tar.xz/cpu/sh2/mame/sh2dasm.c -> libretro-picodrive-0~git20200716.tar.xz/cpu/sh2/mame/sh2dasm.c
Changed
10
1
2
sprintf(buffer, "MOV.B @($%02X,%s),R0", (opcode & 15), regname[Rm]);
3
break;
4
case 5:
5
- sprintf(buffer, "MOV.W @($%02X,%s),R0", (opcode & 15), regname[Rm]);
6
+ sprintf(buffer, "MOV.W @($%02X,%s),R0", (opcode & 15) * 2, regname[Rm]);
7
break;
8
case 8:
9
sprintf(buffer, "CMP/EQ #$%02X,R0", (opcode & 0xff));
10
libretro-picodrive-0~git20200112.tar.xz/cpu/sh2/mame/sh2pico.c -> libretro-picodrive-0~git20200716.tar.xz/cpu/sh2/mame/sh2pico.c
Changed
44
1
2
if (sh2->delay)
3
{
4
sh2->ppc = sh2->delay;
5
- opcode = RW(sh2, sh2->delay);
6
+ opcode = (UINT32)(UINT16)RW(sh2, sh2->delay);
7
8
// TODO: more branch types
9
if ((opcode >> 13) == 5) { // BRA/BSR
10
11
else
12
{
13
sh2->ppc = sh2->pc;
14
- opcode = RW(sh2, sh2->pc);
15
+ opcode = (UINT32)(UINT16)RW(sh2, sh2->pc);
16
}
17
18
sh2->delay = 0;
19
20
if (sh2->pc < *base_pc || sh2->pc >= *end_pc) {
21
*base_pc = sh2->pc;
22
scan_block(*base_pc, sh2->is_slave,
23
- op_flags, end_pc, NULL);
24
+ op_flags, end_pc, NULL, NULL);
25
}
26
if ((op_flags[(sh2->pc - *base_pc) / 2]
27
& OF_BTARGET) || sh2->pc == *base_pc
28
29
if (sh2->delay)
30
{
31
sh2->ppc = sh2->delay;
32
- opcode = RW(sh2, sh2->delay);
33
+ opcode = (UINT32)(UINT16)RW(sh2, sh2->delay);
34
sh2->pc -= 2;
35
}
36
else
37
{
38
sh2->ppc = sh2->pc;
39
- opcode = RW(sh2, sh2->pc);
40
+ opcode = (UINT32)(UINT16)RW(sh2, sh2->pc);
41
}
42
43
sh2->delay = 0;
44
libretro-picodrive-0~git20200112.tar.xz/cpu/sh2/sh2.c -> libretro-picodrive-0~git20200716.tar.xz/cpu/sh2/sh2.c
Changed
10
1
2
// do this to avoid missing irqs that other SH2 might clear
3
int vector = sh2->irq_callback(sh2, level);
4
sh2_do_irq(sh2, level, vector);
5
- sh2->m68krcycles_done += C_SH2_TO_M68K(*sh2, 13);
6
+ sh2->m68krcycles_done += C_SH2_TO_M68K(sh2, 13);
7
}
8
else
9
sh2->test_irq = 1;
10
libretro-picodrive-0~git20200112.tar.xz/cpu/sh2/sh2.h -> libretro-picodrive-0~git20200716.tar.xz/cpu/sh2/sh2.h
Changed
155
1
2
#ifndef __SH2_H__
3
#define __SH2_H__
4
5
+#include "../../pico/pico_types.h"
6
#include "../../pico/pico_port.h"
7
8
// registers - matches structure order
9
10
SHR_R0 = 0, SHR_SP = 15,
11
SHR_PC, SHR_PPC, SHR_PR, SHR_SR,
12
SHR_GBR, SHR_VBR, SHR_MACH, SHR_MACL,
13
+ SH2_REGS // register set size
14
} sh2_reg_e;
15
+#define SHR_R(n) (SHR_R0+(n))
16
17
typedef struct SH2_
18
{
19
- unsigned int r[16]; // 00
20
- unsigned int pc; // 40
21
- unsigned int ppc;
22
- unsigned int pr;
23
- unsigned int sr;
24
- unsigned int gbr, vbr; // 50
25
- unsigned int mach, macl; // 58
26
+ // registers. this MUST correlate with enum sh2_reg_e.
27
+ uint32_t r[16] ALIGNED(32);
28
+ uint32_t pc; // 40
29
+ uint32_t ppc;
30
+ uint32_t pr;
31
+ uint32_t sr;
32
+ uint32_t gbr, vbr; // 50
33
+ uint32_t mach, macl; // 58
34
35
// common
36
- const void *read8_map; // 60
37
+ const void *read8_map;
38
const void *read16_map;
39
+ const void *read32_map;
40
const void **write8_tab;
41
const void **write16_tab;
42
+ const void **write32_tab;
43
44
// drc stuff
45
- int drc_tmp; // 70
46
+ int drc_tmp;
47
int irq_cycles;
48
void *p_bios; // convenience pointers
49
void *p_da;
50
- void *p_sdram; // 80
51
+ void *p_sdram;
52
void *p_rom;
53
+ void *p_dram;
54
+ void *p_drcblk_da;
55
+ void *p_drcblk_ram;
56
unsigned int pdb_io_csum[2];
57
58
#define SH2_STATE_RUN (1 << 0) // to prevent recursion
59
-#define SH2_STATE_SLEEP (1 << 1)
60
+#define SH2_STATE_SLEEP (1 << 1) // temporarily stopped (DMA, IO, ...)
61
#define SH2_STATE_CPOLL (1 << 2) // polling comm regs
62
#define SH2_STATE_VPOLL (1 << 3) // polling VDP
63
+#define SH2_STATE_RPOLL (1 << 4) // polling address in SDRAM
64
+#define SH2_TIMER_RUN (1 << 7) // SOC WDT timer is running
65
+#define SH2_IN_DRC (1 << 8) // DRC in use
66
unsigned int state;
67
- unsigned int poll_addr;
68
+ uint32_t poll_addr;
69
int poll_cycles;
70
int poll_cnt;
71
72
+ // DRC branch cache. size must be 2^n and <=128
73
+ int rts_cache_idx;
74
+ struct { uint32_t pc; void *code; } rts_cache[16];
75
+ struct { uint32_t pc; void *code; } branch_cache[128];
76
+
77
// interpreter stuff
78
int icount; // cycles left in current timeslice
79
unsigned int ea;
80
81
unsigned int cycles_timeslice;
82
83
struct SH2_ *other_sh2;
84
+ int (*run)(struct SH2_ *, int);
85
86
// we use 68k reference cycles for easier sync
87
unsigned int m68krcycles_done;
88
unsigned int mult_m68k_to_sh2;
89
unsigned int mult_sh2_to_m68k;
90
91
- unsigned char data_array[0x1000]; // cache (can be used as RAM)
92
- unsigned int peri_regs[0x200/4]; // periphereal regs
93
+ uint8_t data_array[0x1000]; // cache (can be used as RAM)
94
+ uint32_t peri_regs[0x200/4]; // peripheral regs
95
} SH2;
96
97
#define CYCLE_MULT_SHIFT 10
98
#define C_M68K_TO_SH2(xsh2, c) \
99
- ((int)((c) * (xsh2).mult_m68k_to_sh2) >> CYCLE_MULT_SHIFT)
100
+ (int)(((uint64_t)(c) * (xsh2)->mult_m68k_to_sh2) >> CYCLE_MULT_SHIFT)
101
#define C_SH2_TO_M68K(xsh2, c) \
102
- ((int)((c + 3) * (xsh2).mult_sh2_to_m68k) >> CYCLE_MULT_SHIFT)
103
+ (int)(((uint64_t)(c+3U) * (xsh2)->mult_sh2_to_m68k) >> CYCLE_MULT_SHIFT)
104
105
int sh2_init(SH2 *sh2, int is_slave, SH2 *other_sh2);
106
void sh2_finish(SH2 *sh2);
107
108
int sh2_execute_drc(SH2 *sh2c, int cycles);
109
int sh2_execute_interpreter(SH2 *sh2c, int cycles);
110
111
-static __inline int sh2_execute(SH2 *sh2, int cycles, int use_drc)
112
+static __inline void sh2_execute_prepare(SH2 *sh2, int use_drc)
113
+{
114
+#ifdef DRC_SH2
115
+ sh2->run = use_drc ? sh2_execute_drc : sh2_execute_interpreter;
116
+#else
117
+ sh2->run = sh2_execute_interpreter;
118
+#endif
119
+}
120
+
121
+static __inline int sh2_execute(SH2 *sh2, int cycles)
122
{
123
int ret;
124
125
sh2->cycles_timeslice = cycles;
126
-#ifdef DRC_SH2
127
- if (use_drc)
128
- ret = sh2_execute_drc(sh2, cycles);
129
- else
130
-#endif
131
- ret = sh2_execute_interpreter(sh2, cycles);
132
+ ret = sh2->run(sh2, cycles);
133
134
return sh2->cycles_timeslice - ret;
135
}
136
137
138
// pico memhandlers
139
// XXX: move somewhere else
140
-unsigned int REGPARM(2) p32x_sh2_read8(unsigned int a, SH2 *sh2);
141
-unsigned int REGPARM(2) p32x_sh2_read16(unsigned int a, SH2 *sh2);
142
-unsigned int REGPARM(2) p32x_sh2_read32(unsigned int a, SH2 *sh2);
143
-void REGPARM(3) p32x_sh2_write8 (unsigned int a, unsigned int d, SH2 *sh2);
144
-void REGPARM(3) p32x_sh2_write16(unsigned int a, unsigned int d, SH2 *sh2);
145
-void REGPARM(3) p32x_sh2_write32(unsigned int a, unsigned int d, SH2 *sh2);
146
+u32 REGPARM(2) p32x_sh2_read8(u32 a, SH2 *sh2);
147
+u32 REGPARM(2) p32x_sh2_read16(u32 a, SH2 *sh2);
148
+u32 REGPARM(2) p32x_sh2_read32(u32 a, SH2 *sh2);
149
+void REGPARM(3) p32x_sh2_write8 (u32 a, u32 d, SH2 *sh2);
150
+void REGPARM(3) p32x_sh2_write16(u32 a, u32 d, SH2 *sh2);
151
+void REGPARM(3) p32x_sh2_write32(u32 a, u32 d, SH2 *sh2);
152
153
// debug
154
#ifdef DRC_CMP
155
libretro-picodrive-0~git20200112.tar.xz/jni/Android.mk -> libretro-picodrive-0~git20200716.tar.xz/jni/Android.mk
Changed
71
1
2
use_drz80 := 0
3
use_cz80 := 1
4
use_sh2drc := 0
5
-use_sh2mame := 1
6
use_svpdrc := 0
7
8
asm_memory := 0
9
10
asm_misc := 0
11
asm_cdmemory := 0
12
asm_mix := 0
13
+asm_32xdraw := 0
14
+asm_32xmemory := 0
15
16
ifeq ($(TARGET_ARCH),arm)
17
- use_cyclone := 1
18
- use_sh2drc := 1
19
- use_svpdrc := 1
20
- asm_render := 1
21
- asm_misc := 1
22
- asm_mix := 1
23
- use_fame := 0
24
- use_sh2mame := 0
25
+# use_cyclone := 1
26
+# use_fame := 0
27
+# use_drz80 := 1
28
+# use_cz80 := 0
29
+ use_sh2drc := 1
30
+# use_svpdrc := 1
31
+
32
+# asm_memory := 1
33
+# asm_render := 1
34
+# asm_ym2612 := 1
35
+# asm_misc := 1
36
+# asm_cdmemory := 1
37
+# asm_mix := 1
38
+# asm_32xdraw := 1
39
+# asm_32xmemory := 1
40
endif
41
42
ifeq ($(TARGET_ARCH_ABI),armeabi)
43
44
45
SOURCES_C := $(LIBRETRO_DIR)/libretro.c \
46
$(COMMON_DIR)/mp3.c \
47
+ $(COMMON_DIR)/mp3_sync.c \
48
$(COMMON_DIR)/mp3_dummy.c \
49
$(UNZIP_DIR)/unzip.c
50
51
COREFLAGS := $(addprefix -D,$(DEFINES)) -fno-strict-aliasing
52
53
-GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
54
-ifneq ($(GIT_VERSION)," unknown")
55
+GIT_VERSION := $(shell git rev-parse --short HEAD || echo unknown)
56
+ifneq ($(GIT_VERSION),"unknown")
57
COREFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
58
endif
59
60
+ifneq ($(filter armeabi%, $(TARGET_ARCH_ABI)),)
61
+$(CORE_DIR)/pico/pico_int_offs.h:
62
+ cp $(CORE_DIR)/tools/offsets/generic-ilp32-offsets.h $@
63
+.PHONY: $(CORE_DIR)/pico/pico_int_offs.h
64
+
65
+$(filter %.S,$(SRCS_COMMON)): $(CORE_DIR)/pico/pico_int_offs.h
66
+endif
67
+
68
include $(CLEAR_VARS)
69
LOCAL_MODULE := retro
70
LOCAL_SRC_FILES := $(SRCS_COMMON) $(SOURCES_C)
71
libretro-picodrive-0~git20200112.tar.xz/pico/32x/32x.c -> libretro-picodrive-0~git20200716.tar.xz/pico/32x/32x.c
Changed
201
1
2
struct Pico32x Pico32x;
3
SH2 sh2s[2];
4
5
-#define SH2_IDLE_STATES (SH2_STATE_CPOLL|SH2_STATE_VPOLL|SH2_STATE_SLEEP)
6
+#define SH2_IDLE_STATES (SH2_STATE_CPOLL|SH2_STATE_VPOLL|SH2_STATE_RPOLL|SH2_STATE_SLEEP)
7
8
static int REGPARM(2) sh2_irq_cb(SH2 *sh2, int level)
9
{
10
11
}
12
13
// MUST specify active_sh2 when called from sh2 memhandlers
14
-void p32x_update_irls(SH2 *active_sh2, int m68k_cycles)
15
+void p32x_update_irls(SH2 *active_sh2, unsigned int m68k_cycles)
16
{
17
int irqs, mlvl = 0, slvl = 0;
18
int mrun, srun;
19
20
if (active_sh2 != NULL)
21
m68k_cycles = sh2_cycles_done_m68k(active_sh2);
22
23
+ // find top bit = highest irq number (0 <= irl <= 14/2) by binary search
24
+
25
// msh2
26
irqs = Pico32x.sh2irqs | Pico32x.sh2irqi[0];
27
- while ((irqs >>= 1))
28
- mlvl++;
29
- mlvl *= 2;
30
+ if (irqs >= 0x10) mlvl += 8, irqs >>= 4;
31
+ if (irqs >= 0x04) mlvl += 4, irqs >>= 2;
32
+ if (irqs >= 0x02) mlvl += 2, irqs >>= 1;
33
34
// ssh2
35
irqs = Pico32x.sh2irqs | Pico32x.sh2irqi[1];
36
- while ((irqs >>= 1))
37
- slvl++;
38
- slvl *= 2;
39
+ if (irqs >= 0x10) slvl += 8, irqs >>= 4;
40
+ if (irqs >= 0x04) slvl += 4, irqs >>= 2;
41
+ if (irqs >= 0x02) slvl += 2, irqs >>= 1;
42
43
- mrun = sh2_irl_irq(&msh2, mlvl, active_sh2 == &msh2);
44
+ mrun = sh2_irl_irq(&msh2, mlvl, msh2.state & SH2_STATE_RUN);
45
if (mrun) {
46
p32x_sh2_poll_event(&msh2, SH2_IDLE_STATES, m68k_cycles);
47
- if (active_sh2 == &msh2)
48
- sh2_end_run(active_sh2, 1);
49
+ if (msh2.state & SH2_STATE_RUN)
50
+ sh2_end_run(&msh2, 1);
51
}
52
53
- srun = sh2_irl_irq(&ssh2, slvl, active_sh2 == &ssh2);
54
+ srun = sh2_irl_irq(&ssh2, slvl, ssh2.state & SH2_STATE_RUN);
55
if (srun) {
56
p32x_sh2_poll_event(&ssh2, SH2_IDLE_STATES, m68k_cycles);
57
- if (active_sh2 == &ssh2)
58
- sh2_end_run(active_sh2, 1);
59
+ if (ssh2.state & SH2_STATE_RUN)
60
+ sh2_end_run(&ssh2, 1);
61
}
62
63
elprintf(EL_32X, "update_irls: m %d/%d, s %d/%d", mlvl, mrun, slvl, srun);
64
65
// the mask register is inconsistent, CMD is supposed to be a mask,
66
// while others are actually irq trigger enables?
67
// TODO: test on hw..
68
-void p32x_trigger_irq(SH2 *sh2, int m68k_cycles, unsigned int mask)
69
+void p32x_trigger_irq(SH2 *sh2, unsigned int m68k_cycles, unsigned int mask)
70
{
71
Pico32x.sh2irqs |= mask & P32XI_VRES;
72
Pico32x.sh2irqi[0] |= mask & (Pico32x.sh2irq_mask[0] << 3);
73
74
p32x_update_irls(sh2, m68k_cycles);
75
}
76
77
-void p32x_update_cmd_irq(SH2 *sh2, int m68k_cycles)
78
+void p32x_update_cmd_irq(SH2 *sh2, unsigned int m68k_cycles)
79
{
80
if ((Pico32x.sh2irq_mask[0] & 2) && (Pico32x.regs[2 / 2] & 1))
81
Pico32x.sh2irqi[0] |= P32XI_CMD;
82
83
84
void PicoUnload32x(void)
85
{
86
+ sh2_finish(&msh2);
87
+ sh2_finish(&ssh2);
88
if (Pico32xMem != NULL)
89
plat_munmap(Pico32xMem, sizeof(*Pico32xMem));
90
Pico32xMem = NULL;
91
- sh2_finish(&msh2);
92
- sh2_finish(&ssh2);
93
94
PicoIn.AHW &= ~PAHW_32X;
95
}
96
97
{
98
if (PicoIn.AHW & PAHW_32X) {
99
p32x_trigger_irq(NULL, SekCyclesDone(), P32XI_VRES);
100
- p32x_sh2_poll_event(&msh2, SH2_IDLE_STATES, 0);
101
- p32x_sh2_poll_event(&ssh2, SH2_IDLE_STATES, 0);
102
+ p32x_sh2_poll_event(&msh2, SH2_IDLE_STATES, SekCyclesDone());
103
+ p32x_sh2_poll_event(&ssh2, SH2_IDLE_STATES, SekCyclesDone());
104
p32x_pwm_ctl_changed();
105
p32x_timers_recalc();
106
}
107
108
}
109
110
p32x_trigger_irq(NULL, SekCyclesDone(), P32XI_VINT);
111
- p32x_sh2_poll_event(&msh2, SH2_STATE_VPOLL, 0);
112
- p32x_sh2_poll_event(&ssh2, SH2_STATE_VPOLL, 0);
113
+ p32x_sh2_poll_event(&msh2, SH2_STATE_VPOLL, SekCyclesDone());
114
+ p32x_sh2_poll_event(&ssh2, SH2_STATE_VPOLL, SekCyclesDone());
115
}
116
117
-void p32x_schedule_hint(SH2 *sh2, int m68k_cycles)
118
+void p32x_schedule_hint(SH2 *sh2, unsigned int m68k_cycles)
119
{
120
// rather rough, 32x hint is useless in practice
121
int after;
122
123
return; // nobody cares
124
// note: when Pico.m.scanline is 224, SH2s might
125
// still be at scanline 93 (or so)
126
- if (!(Pico32x.sh2_regs[0] & 0x80) && Pico.m.scanline > 224)
127
+ if (!(Pico32x.sh2_regs[0] & 0x80) &&
128
+ Pico.m.scanline > (Pico.video.reg[1] & 0x08 ? 240 : 224))
129
return;
130
131
after = (Pico32x.sh2_regs[4 / 2] + 1) * 488;
132
133
134
p32x_event_schedule(now, event, after);
135
136
- left_to_next = (event_time_next - now) * 3;
137
- sh2_end_run(sh2, left_to_next);
138
+ left_to_next = C_M68K_TO_SH2(sh2, (int)(event_time_next - now));
139
+ if (sh2_cycles_left(sh2) > left_to_next) {
140
+ if (left_to_next < 1)
141
+ left_to_next = 1;
142
+ sh2_end_run(sh2, left_to_next);
143
+ }
144
}
145
146
static void p32x_run_events(unsigned int until)
147
148
oldest, event_time_next);
149
}
150
151
-static void run_sh2(SH2 *sh2, int m68k_cycles)
152
+static void run_sh2(SH2 *sh2, unsigned int m68k_cycles)
153
{
154
- int cycles, done;
155
+ unsigned int cycles, done;
156
157
pevt_log_sh2_o(sh2, EVT_RUN_START);
158
sh2->state |= SH2_STATE_RUN;
159
- cycles = C_M68K_TO_SH2(*sh2, m68k_cycles);
160
+ cycles = C_M68K_TO_SH2(sh2, m68k_cycles);
161
elprintf_sh2(sh2, EL_32X, "+run %u %d @%08x",
162
sh2->m68krcycles_done, cycles, sh2->pc);
163
164
- done = sh2_execute(sh2, cycles, PicoIn.opt & POPT_EN_DRC);
165
+ done = sh2_execute(sh2, cycles);
166
167
- sh2->m68krcycles_done += C_SH2_TO_M68K(*sh2, done);
168
+ sh2->m68krcycles_done += C_SH2_TO_M68K(sh2, done);
169
sh2->state &= ~SH2_STATE_RUN;
170
pevt_log_sh2_o(sh2, EVT_RUN_END);
171
elprintf_sh2(sh2, EL_32X, "-run %u %d",
172
173
174
// there might be new event to schedule current sh2 to
175
if (event_time_next) {
176
- left_to_event = event_time_next - m68k_target;
177
- left_to_event *= 3;
178
+ left_to_event = C_M68K_TO_SH2(sh2, (int)(event_time_next - m68k_target));
179
if (sh2_cycles_left(sh2) > left_to_event) {
180
if (left_to_event < 1)
181
left_to_event = 1;
182
183
}
184
185
#define STEP_LS 24
186
-#define STEP_N 440
187
+#define STEP_N 528 // at least one line (488)
188
189
#define sync_sh2s_normal p32x_sync_sh2s
190
//#define sync_sh2s_lockstep p32x_sync_sh2s
191
192
/* most timing is in 68k clock */
193
void sync_sh2s_normal(unsigned int m68k_target)
194
{
195
- unsigned int now, target, timer_cycles;
196
+ unsigned int now, target, next, timer_cycles;
197
int cycles;
198
199
elprintf(EL_32X, "sh2 sync to %u", m68k_target);
200
201
libretro-picodrive-0~git20200112.tar.xz/pico/32x/draw.c -> libretro-picodrive-0~git20200716.tar.xz/pico/32x/draw.c
Changed
174
1
2
/*
3
* PicoDrive
4
* (C) notaz, 2009,2010
5
+ * (C) kub, 2019
6
*
7
* This work is licensed under the terms of MAME license.
8
* See COPYING file in the top-level directory.
9
10
int (*PicoScan32xEnd)(unsigned int num);
11
int Pico32xDrawMode;
12
13
+void *DrawLineDestBase32x;
14
+int DrawLineDestIncrement32x;
15
+
16
static void convert_pal555(int invert_prio)
17
{
18
unsigned int *ps = (void *)Pico32xMem->pal;
19
20
const unsigned int m1 = 0x001f; \
21
const unsigned int m2 = 0x03e0; \
22
const unsigned int m3 = 0x7c00; \
23
- int i; \
24
+ unsigned short t; \
25
+ int i = 320; \
26
\
27
- for (i = 320; i > 0; i--, pd++, p32x++, pmd++) { \
28
- unsigned short t = *p32x; \
29
- if ((*pmd & 0x3f) != mdbg && !((t ^ inv) & 0x8000)) { \
30
- pmd_draw_code; \
31
- continue; \
32
+ while (i > 0) { \
33
+ for (; i > 0 && (*pmd & 0x3f) == mdbg; pd++, pmd++, i--) { \
34
+ t = *p32x++; \
35
+ *pd = ((t&m1) << 11) | ((t&m2) << 1) | ((t&m3) >> 10); \
36
+ } \
37
+ for (; i > 0 && (*pmd & 0x3f) != mdbg; pd++, pmd++, i--) { \
38
+ t = *p32x++; \
39
+ if ((t ^ inv) & 0x8000) \
40
+ *pd = ((t&m1) << 11) | ((t&m2) << 1) | ((t&m3) >> 10); \
41
+ else \
42
+ pmd_draw_code; \
43
} \
44
- \
45
- *pd = ((t & m1) << 11) | ((t & m2) << 1) | ((t & m3) >> 10); \
46
} \
47
}
48
49
50
#define do_line_pp(pd, p32x, pmd, pmd_draw_code) \
51
{ \
52
unsigned short t; \
53
- int i; \
54
- for (i = 320; i > 0; i--, pd++, p32x++, pmd++) { \
55
- t = pal[*(unsigned char *)((uintptr_t)p32x ^ 1)]; \
56
- if ((t & 0x20) || (*pmd & 0x3f) == mdbg) \
57
+ int i = 320; \
58
+ while (i > 0) { \
59
+ for (; i > 0 && (*pmd & 0x3f) == mdbg; pd++, pmd++, i--) { \
60
+ t = pal[*(unsigned char *)((uintptr_t)(p32x++) ^ 1)]; \
61
*pd = t; \
62
- else \
63
- pmd_draw_code; \
64
+ } \
65
+ for (; i > 0 && (*pmd & 0x3f) != mdbg; pd++, pmd++, i--) { \
66
+ t = pal[*(unsigned char *)((uintptr_t)(p32x++) ^ 1)]; \
67
+ if (t & 0x20) \
68
+ *pd = t; \
69
+ else \
70
+ pmd_draw_code; \
71
+ } \
72
} \
73
-}
74
+}
75
76
// run length mode
77
#define do_line_rl(pd, p32x, pmd, pmd_draw_code) \
78
79
int lines_sft_offs;
80
int which_func;
81
82
- Pico.est.DrawLineDest = (char *)DrawLineDestBase + offs * DrawLineDestIncrement;
83
+ Pico.est.DrawLineDest = (char *)DrawLineDestBase32x + offs * DrawLineDestIncrement32x;
84
dram = Pico32xMem->dram[Pico32x.vdp_regs[0x0a/2] & P32XV_FS];
85
86
- if (Pico32xDrawMode == PDM32X_BOTH) {
87
- if (Pico.m.dirtyPal)
88
- PicoDrawUpdateHighPal();
89
- }
90
+ if (Pico32xDrawMode == PDM32X_BOTH)
91
+ PicoDrawUpdateHighPal();
92
93
if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 2)
94
{
95
96
void PicoDraw32xLayerMdOnly(int offs, int lines)
97
{
98
int have_scan = PicoScan32xBegin != NULL && PicoScan32xEnd != NULL;
99
- unsigned short *dst = (void *)((char *)DrawLineDestBase + offs * DrawLineDestIncrement);
100
+ unsigned short *dst = (void *)((char *)DrawLineDestBase32x + offs * DrawLineDestIncrement32x);
101
unsigned char *pmd = Pico.est.Draw2FB + 328 * offs + 8;
102
unsigned short *pal = Pico.est.HighPal;
103
int poffs = 0, plen = 320;
104
int l, p;
105
106
if (!(Pico.video.reg[12] & 1)) {
107
- // 32col mode
108
+ // 32col mode. for some render modes MD pixel data carries an offset
109
+ if (!(PicoIn.opt & (POPT_ALT_RENDERER|POPT_DIS_32C_BORDER)))
110
+ pmd += 32;
111
poffs = 32;
112
plen = 256;
113
}
114
115
- if (Pico.m.dirtyPal)
116
- PicoDrawUpdateHighPal();
117
+ PicoDrawUpdateHighPal();
118
119
dst += poffs;
120
for (l = 0; l < lines; l++) {
121
122
dst[p + 2] = pal[*pmd++];
123
dst[p + 3] = pal[*pmd++];
124
}
125
- dst = (void *)((char *)dst + DrawLineDestIncrement);
126
+ dst = (void *)((char *)dst + DrawLineDestIncrement32x);
127
pmd += 328 - plen;
128
if (have_scan)
129
PicoScan32xEnd(l + offs);
130
131
132
void PicoDrawSetOutFormat32x(pdso_t which, int use_32x_line_mode)
133
{
134
-#ifdef _ASM_32X_DRAW
135
- extern void *Pico32xNativePal;
136
- Pico32xNativePal = Pico32xMem->pal_native;
137
-#endif
138
+ if (which == PDF_RGB555) {
139
+ // need CLUT pixels in PicoDraw2FB for layer transparency
140
+ PicoDrawSetInternalBuf(Pico.est.Draw2FB, 328);
141
+ PicoDrawSetOutBufMD(DrawLineDestBase32x, DrawLineDestIncrement32x);
142
+ } else {
143
+ // use the same layout as alt renderer
144
+ PicoDrawSetInternalBuf(NULL, 0);
145
+ PicoDrawSetOutBufMD(Pico.est.Draw2FB + 8, 328);
146
+ }
147
148
- if (which == PDF_RGB555 && use_32x_line_mode) {
149
+ if (use_32x_line_mode)
150
// we'll draw via FinalizeLine32xRGB555 (rare)
151
- PicoDrawSetInternalBuf(NULL, 0);
152
Pico32xDrawMode = PDM32X_OFF;
153
- return;
154
- }
155
+ else
156
+ // in RGB555 mode the 32x layer is drawn over the MD layer, in the other
157
+ // modes 32x and MD layer are merged together by the 32x renderer
158
+ Pico32xDrawMode = (which == PDF_RGB555) ? PDM32X_32X_ONLY : PDM32X_BOTH;
159
+}
160
161
- // use the same layout as alt renderer
162
- PicoDrawSetInternalBuf(Pico.est.Draw2FB, 328);
163
- Pico32xDrawMode = (which == PDF_RGB555) ? PDM32X_32X_ONLY : PDM32X_BOTH;
164
+void PicoDrawSetOutBuf32X(void *dest, int increment)
165
+{
166
+ DrawLineDestBase32x = dest;
167
+ DrawLineDestIncrement32x = increment;
168
+ // in RGB555 mode this buffer is also used by the MD renderer
169
+ if (Pico32xDrawMode != PDM32X_BOTH)
170
+ PicoDrawSetOutBufMD(DrawLineDestBase32x, DrawLineDestIncrement32x);
171
}
172
173
// vim:shiftwidth=2:ts=2:expandtab
174
libretro-picodrive-0~git20200716.tar.xz/pico/32x/draw_arm.S
Added
201
1
2
+@*
3
+@* PicoDrive
4
+@* (C) notaz, 2010
5
+@* (C) kub, 2019
6
+@*
7
+@* This work is licensed under the terms of MAME license.
8
+@* See COPYING file in the top-level directory.
9
+@*
10
+
11
+#include "pico/arm_features.h"
12
+#include "pico/pico_int_offs.h"
13
+
14
+.extern Pico32x
15
+.extern Pico
16
+
17
+.equiv P32XV_PRI, (1<< 7)
18
+
19
+.text
20
+.align 2
21
+
22
+ PIC_LDR_INIT()
23
+
24
+.macro call_scan_prep cond est @ &Pico.est
25
+.if \cond
26
+ PIC_LDR(r4, r6, PicoScan32xBegin)
27
+ PIC_LDR(r5, r6, PicoScan32xEnd)
28
+ ldr r6, [\est, #OFS_EST_DrawLineDest]
29
+ ldr r4, [r4]
30
+ ldr r5, [r5]
31
+ stmfd sp!, {r4,r5,r6}
32
+.endif
33
+.endm
34
+
35
+.macro call_scan_fin_ge cond
36
+.if \cond
37
+ addge sp, sp, #4*3
38
+.endif
39
+.endm
40
+
41
+.macro call_scan_begin cond
42
+.if \cond
43
+ stmfd sp!, {r1-r3}
44
+ and r0, r2, #0xff
45
+ add r0, r0, r4
46
+ mov lr, pc
47
+ ldr pc, [sp, #(3+0)*4]
48
+ ldr r0, [sp, #(3+2)*4] @ &DrawLineDest
49
+ ldmfd sp!, {r1-r3}
50
+ ldr r0, [r0]
51
+.endif
52
+.endm
53
+
54
+.macro call_scan_end cond
55
+.if \cond
56
+ stmfd sp!, {r0-r3}
57
+ and r0, r2, #0xff
58
+ add r0, r0, r4
59
+ mov lr, pc
60
+ ldr pc, [sp, #(4+1)*4]
61
+ ldmfd sp!, {r0-r3}
62
+.endif
63
+.endm
64
+
65
+@ direct color
66
+@ unsigned short *dst, unsigned short *dram, int lines_sft_offs, int mdbg
67
+.macro make_do_loop_dc name call_scan do_md
68
+.global \name
69
+\name:
70
+ stmfd sp!, {r4-r11,lr}
71
+
72
+ PIC_LDR(lr, r9, Pico)
73
+ PIC_LDR(r10,r9, Pico32x)
74
+ ldr r11, [lr, #OFS_Pico_est+OFS_EST_Draw2FB]
75
+ ldrh r10,[r10, #0x40] @ Pico32x.vdp_regs[0]
76
+ add r9, lr, #OFS_Pico_est+OFS_EST_HighPal @ palmd
77
+
78
+ and r4, r2, #0xff
79
+ mov r5, #328
80
+ mov r3, r3, lsl #26 @ mdbg << 26
81
+ mla r11,r4,r5,r11 @ r11 = pmd = PicoDraw2FB + offs*328: md data
82
+ tst r10,#P32XV_PRI
83
+ movne r10,#0
84
+ moveq r10,#0x8000 @ r10 = inv_bit
85
+ call_scan_prep \call_scan lr
86
+
87
+ mov r4, #0 @ line
88
+ b 1f @ loop_outer_entry
89
+
90
+0: @ loop_outer:
91
+ call_scan_end \call_scan
92
+ add r4, r4, #1
93
+ cmp r4, r2, lsr #16
94
+ call_scan_fin_ge \call_scan
95
+ ldmgefd sp!, {r4-r11,pc}
96
+
97
+1: @ loop_outer_entry:
98
+ call_scan_begin \call_scan
99
+ mov r12,r4, lsl #1
100
+ ldrh r12,[r1, r12]
101
+ add r11,r11,#8
102
+ mov r6, #320
103
+ add r5, r1, r12, lsl #1 @ p32x = dram + dram[l]
104
+
105
+2: @ loop_inner:
106
+ ldrh r8, [r5], #2
107
+ subs lr, r6, #1
108
+ blt 0b @ loop_outer
109
+
110
+3: @ loop_innermost:
111
+ ldrh r7, [r5], #2 @ 32x pixel
112
+ subs lr, lr, #1
113
+ cmpge r7, r8
114
+ beq 3b @ loop_innermost
115
+
116
+ sub r5, r5, #2
117
+ add lr, lr, #1
118
+ sub lr, r6, lr
119
+ sub r6, r6, lr
120
+
121
+ eor r12,r8, r10
122
+ tst r12, #0x8000 @ !((t ^ inv) & 0x8000)
123
+ bne 5f @ draw_md
124
+
125
+ and r7 ,r8, #0x03e0
126
+ mov r8, r8, lsl #11
127
+ orr r8, r8, r8, lsr #(10+11)
128
+ orr r8, r8, r7 ,lsl #1
129
+ bic r8, r8, #0x0020 @ kill prio bit
130
+
131
+ add r11,r11,lr
132
+ tst r0, #2 @ dst unaligned?
133
+ strneh r8, [r0], #2
134
+ subne lr, lr, #1
135
+ cmp lr, #0
136
+ beq 2b @ loop_inner
137
+ mov r8, r8, lsl #16
138
+ orr r12,r8, r8, lsr #16
139
+ mov r8 ,r12
140
+4: @ draw_32x:
141
+ subs lr, lr, #4 @ store 4 pixels
142
+ stmgeia r0!, {r8, r12}
143
+ bgt 4b @ draw_32x
144
+ beq 2b @ loop_inner
145
+ adds lr, lr, #2 @ store 1-3 leftover pixels
146
+ strge r8, [r0], #4
147
+ strneh r8, [r0], #2
148
+ b 2b @ loop_inner
149
+
150
+5: @ draw_md:
151
+ subs lr, lr, #1
152
+ ldrgeb r7, [r11], #1 @ MD pixel
153
+ blt 2b @ loop_inner
154
+ cmp r3, r7, lsl #26 @ MD has bg pixel?
155
+.if \do_md
156
+ mov r7, r7, lsl #1
157
+ ldrneh r7 ,[r9, r7]
158
+ strneh r7 ,[r0], #2 @ *dst++ = palmd[*pmd]
159
+.else
160
+ addne r0, r0, #2
161
+.endif
162
+ bne 5b @ draw_md
163
+
164
+ and r7 ,r8, #0x03e0
165
+ mov r8, r8, lsl #11
166
+ orr r8, r8, r8, lsr #(10+11)
167
+ orr r8, r8, r7 ,lsl #1
168
+ bic r8, r8, #0x0020 @ kill prio bit
169
+ strh r8, [r0], #2 @ *dst++ = bgr2rgb(*p32x++)
170
+
171
+6: @ draw_md_32x:
172
+ subs lr, lr, #1
173
+ ldrgeb r7, [r11], #1 @ MD pixel
174
+ blt 2b @ loop_inner
175
+ cmp r3, r7, lsl #26 @ MD has bg pixel?
176
+.if \do_md
177
+ mov r7, r7, lsl #1
178
+ ldrneh r7 ,[r9, r7] @ *dst++ = palmd[*pmd]
179
+ moveq r7 ,r8 @ *dst++ = bgr2rgb(*p32x++)
180
+ strh r7 ,[r0], #2
181
+.else
182
+ streqh r8, [r0] @ *dst++ = bgr2rgb(*p32x++)
183
+ add r0, r0, #2
184
+.endif
185
+ b 6b @ draw_md_32x
186
+.endm
187
+
188
+
189
+@ packed pixel
190
+@ note: this may read a few bytes over the end of PicoDraw2FB and dram,
191
+@ so those should have a bit more alloc'ed than really needed.
192
+@ unsigned short *dst, unsigned short *dram, int lines_sft_offs, int mdbg
193
+.macro make_do_loop_pp name call_scan do_md
194
+.global \name
195
+\name:
196
+ stmfd sp!, {r4-r11,lr}
197
+
198
+ PIC_LDR(lr, r9, Pico)
199
+ PIC_LDR(r10,r9, Pico32xMem)
200
+ ldr r9,=OFS_PMEM32x_pal_native
201
libretro-picodrive-0~git20200112.tar.xz/pico/32x/memory.c -> libretro-picodrive-0~git20200716.tar.xz/pico/32x/memory.c
Changed
201
1
2
/*
3
* PicoDrive
4
* (C) notaz, 2009,2010,2013
5
+ * (C) kub, 2019
6
*
7
* This work is licensed under the terms of MAME license.
8
* See COPYING file in the top-level directory.
9
10
*/
11
#include "../pico_int.h"
12
#include "../memory.h"
13
+
14
#include "../../cpu/sh2/compiler.h"
15
+DRC_DECLARE_SR;
16
17
static const char str_mars[] = "MARS";
18
19
20
#define REG8IN16(ptr, offs) ((u8 *)ptr)[(offs) ^ 1]
21
22
// poll detection
23
-#define POLL_THRESHOLD 3
24
+#define POLL_THRESHOLD 5
25
26
static struct {
27
- u32 addr, cycles;
28
+ u32 addr1, addr2, cycles;
29
int cnt;
30
} m68k_poll;
31
32
static int m68k_poll_detect(u32 a, u32 cycles, u32 flags)
33
{
34
int ret = 0;
35
+ // support polling on 2 addresses - seen in Wolfenstein
36
+ int match = (a - m68k_poll.addr1 <= 2 || a - m68k_poll.addr2 <= 2);
37
38
- if (a - 2 <= m68k_poll.addr && m68k_poll.addr <= a + 2
39
- && cycles - m68k_poll.cycles <= 64 && !SekNotPolling)
40
+ if (match && cycles - m68k_poll.cycles <= 64 && !SekNotPolling)
41
{
42
- if (m68k_poll.cnt++ > POLL_THRESHOLD) {
43
+ // detect split 32bit access by same cycle count, and ignore those
44
+ if (cycles != m68k_poll.cycles && ++m68k_poll.cnt >= POLL_THRESHOLD) {
45
if (!(Pico32x.emu_flags & flags)) {
46
elprintf(EL_32X, "m68k poll addr %08x, cyc %u",
47
a, cycles - m68k_poll.cycles);
48
- ret = 1;
49
}
50
Pico32x.emu_flags |= flags;
51
+ ret = 1;
52
}
53
}
54
else {
55
+ // reset poll state in case of restart by interrupt
56
+ Pico32x.emu_flags &= ~(P32XF_68KCPOLL|P32XF_68KVPOLL);
57
+ SekSetStop(0);
58
m68k_poll.cnt = 0;
59
- m68k_poll.addr = a;
60
+ if (!match) {
61
+ m68k_poll.addr2 = m68k_poll.addr1;
62
+ m68k_poll.addr1 = a;
63
+ }
64
SekNotPolling = 0;
65
}
66
m68k_poll.cycles = cycles;
67
68
Pico32x.emu_flags &= ~flags;
69
SekSetStop(0);
70
}
71
- m68k_poll.addr = m68k_poll.cnt = 0;
72
+ m68k_poll.addr1 = m68k_poll.addr2 = m68k_poll.cnt = 0;
73
}
74
75
-static void sh2_poll_detect(SH2 *sh2, u32 a, u32 flags, int maxcnt)
76
+void NOINLINE p32x_sh2_poll_detect(u32 a, SH2 *sh2, u32 flags, int maxcnt)
77
{
78
- int cycles_left = sh2_cycles_left(sh2);
79
+ u32 cycles_done = sh2_cycles_done_t(sh2);
80
+ u32 cycles_diff = cycles_done - sh2->poll_cycles;
81
82
- if (a == sh2->poll_addr && sh2->poll_cycles - cycles_left <= 10) {
83
- if (sh2->poll_cnt++ > maxcnt) {
84
+ // reading 2 consecutive 16bit values is probably a 32bit access. detect this
85
+ // by checking address (max 2 bytes away) and cycles (max 2 cycles later).
86
+ // no polling if more than 20 cycles have passed since last detect call.
87
+ if (a - sh2->poll_addr <= 2 && CYCLES_GE(20, cycles_diff)) {
88
+ if (CYCLES_GT(cycles_diff, 2) && ++sh2->poll_cnt >= maxcnt) {
89
if (!(sh2->state & flags))
90
elprintf_sh2(sh2, EL_32X, "state: %02x->%02x",
91
sh2->state, sh2->state | flags);
92
93
sh2->state |= flags;
94
sh2_end_run(sh2, 1);
95
pevt_log_sh2(sh2, EVT_POLL_START);
96
- return;
97
+#ifdef DRC_SH2
98
+ // mark this as an address used for polling if SDRAM
99
+ if ((a & 0xc6000000) == 0x06000000) {
100
+ unsigned char *p = sh2->p_drcblk_ram;
101
+ p[(a & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT] |= 0x80;
102
+ // mark next word too to enable poll fifo for 32bit access
103
+ p[((a+2) & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT] |= 0x80;
104
+ }
105
+#endif
106
}
107
}
108
- else
109
+ else if (!(sh2->state & (SH2_STATE_CPOLL|SH2_STATE_VPOLL|SH2_STATE_RPOLL))) {
110
sh2->poll_cnt = 0;
111
- sh2->poll_addr = a;
112
- sh2->poll_cycles = cycles_left;
113
+ sh2->poll_addr = a;
114
+ }
115
+ sh2->poll_cycles = cycles_done;
116
}
117
118
-void p32x_sh2_poll_event(SH2 *sh2, u32 flags, u32 m68k_cycles)
119
+void NOINLINE p32x_sh2_poll_event(SH2 *sh2, u32 flags, u32 m68k_cycles)
120
{
121
if (sh2->state & flags) {
122
elprintf_sh2(sh2, EL_32X, "state: %02x->%02x", sh2->state,
123
sh2->state & ~flags);
124
125
- if (sh2->m68krcycles_done < m68k_cycles)
126
+ if (sh2->m68krcycles_done < m68k_cycles && !(sh2->state & SH2_STATE_RUN))
127
sh2->m68krcycles_done = m68k_cycles;
128
129
pevt_log_sh2_o(sh2, EVT_POLL_END);
130
+ sh2->state &= ~flags;
131
}
132
133
- sh2->state &= ~flags;
134
- sh2->poll_addr = sh2->poll_cycles = sh2->poll_cnt = 0;
135
+ if (!(sh2->state & (SH2_STATE_CPOLL|SH2_STATE_VPOLL|SH2_STATE_RPOLL)))
136
+ sh2->poll_addr = sh2->poll_cycles = sh2->poll_cnt = 0;
137
}
138
139
-static void sh2s_sync_on_read(SH2 *sh2)
140
+static void sh2s_sync_on_read(SH2 *sh2, unsigned cycles)
141
{
142
- int cycles;
143
if (sh2->poll_cnt != 0)
144
return;
145
146
- cycles = sh2_cycles_done(sh2);
147
- if (cycles > 600)
148
- p32x_sync_other_sh2(sh2, sh2->m68krcycles_done + cycles / 3);
149
+ if (p32x_sh2_ready(sh2->other_sh2, cycles-250))
150
+ p32x_sync_other_sh2(sh2, cycles);
151
+}
152
+
153
+// poll fifo, stores writes to potential addresses used for polling.
154
+// This is used to correctly deliver syncronisation data to the 3 cpus. The
155
+// fifo stores 16 bit values, 8/32 bit accesses must be adapted accordingly.
156
+#define PFIFO_SZ 4
157
+#define PFIFO_CNT 8
158
+struct sh2_poll_fifo {
159
+ u32 cycles;
160
+ u32 a;
161
+ u16 d;
162
+ int cpu;
163
+} sh2_poll_fifo[PFIFO_CNT][PFIFO_SZ];
164
+unsigned sh2_poll_rd[PFIFO_CNT], sh2_poll_wr[PFIFO_CNT]; // ringbuffer pointers
165
+
166
+static NOINLINE u32 sh2_poll_read(u32 a, u32 d, unsigned int cycles, SH2* sh2)
167
+{
168
+ int hix = (a >> 1) % PFIFO_CNT;
169
+ struct sh2_poll_fifo *fifo = sh2_poll_fifo[hix];
170
+ struct sh2_poll_fifo *p;
171
+ int cpu = sh2 ? sh2->is_slave : -1;
172
+ unsigned idx;
173
+
174
+ a &= ~0x20000000; // ignore writethrough bit
175
+ // fetch oldest write to address from fifo, but stop when reaching the present
176
+ idx = sh2_poll_rd[hix];
177
+ while (idx != sh2_poll_wr[hix] && CYCLES_GE(cycles, fifo[idx].cycles)) {
178
+ p = &fifo[idx];
179
+ idx = (idx+1) % PFIFO_SZ;
180
+
181
+ if (cpu != p->cpu) {
182
+ if (CYCLES_GT(cycles, p->cycles+80)) {
183
+ // drop older fifo stores that may cause synchronisation problems.
184
+ p->a = -1;
185
+ } else if (p->a == a) {
186
+ // replace current data with fifo value and discard fifo entry
187
+ d = p->d;
188
+ p->a = -1;
189
+ break;
190
+ }
191
+ }
192
+ }
193
+ return d;
194
+}
195
+
196
+static NOINLINE void sh2_poll_write(u32 a, u32 d, unsigned int cycles, SH2 *sh2)
197
+{
198
+ int hix = (a >> 1) % PFIFO_CNT;
199
+ struct sh2_poll_fifo *fifo = sh2_poll_fifo[hix];
200
+ struct sh2_poll_fifo *q;
201
libretro-picodrive-0~git20200716.tar.xz/pico/32x/memory_arm.S
Added
201
1
2
+/*
3
+ * PicoDrive 32X memory access functions, assembler version
4
+ * (C) KUB, 2018
5
+ *
6
+ * This work is licensed under the terms of MAME license.
7
+ * See COPYING file in the top-level directory.
8
+ */
9
+
10
+#include "../pico_int_offs.h"
11
+
12
+@ 32X bank sizes... TODO this should somehow come from an include file
13
+.equ SH2_ROM_SHIFT, 10 @ 0x003fffff
14
+.equ SH2_RAM_SHIFT, 14 @ 0x0003ffff
15
+.equ SH2_DRAM_SHIFT,15 @ 0x0001ffff
16
+.equ SH2_DA_SHIFT, 20 @ 0x00000fff
17
+
18
+.equ SH2_DRAM_OW, 1<<(32-SH2_DRAM_SHIFT) @ DRAM overwrite mode bit
19
+
20
+.text
21
+.align 5
22
+
23
+#if 0
24
+@ u32 a, SH2 *sh2
25
+.global sh2_read8_rom
26
+.global sh2_read8_sdram
27
+.global sh2_read8_da
28
+.global sh2_read8_dram
29
+.global sh2_read16_rom
30
+.global sh2_read16_sdram
31
+.global sh2_read16_da
32
+.global sh2_read16_dram
33
+.global sh2_read32_rom
34
+.global sh2_read32_sdram
35
+.global sh2_read32_da
36
+.global sh2_read32_dram
37
+#endif
38
+
39
+@ u32 a, u32 d, SH2 *sh2
40
+.global sh2_write8_sdram
41
+.global sh2_write8_da
42
+.global sh2_write8_dram
43
+.global sh2_write16_sdram
44
+.global sh2_write16_da
45
+.global sh2_write16_dram
46
+.global sh2_write32_sdram
47
+.global sh2_write32_da
48
+.global sh2_write32_dram
49
+
50
+#if 0
51
+sh2_read8_rom:
52
+ ldr ip, [r1, #OFS_SH2_p_rom]
53
+ eor r0, r0, #1
54
+ mov r0, r0, lsl #SH2_ROM_SHIFT
55
+ ldrb r0, [ip, r0, lsr #SH2_ROM_SHIFT]
56
+ bx lr
57
+
58
+sh2_read8_sdram:
59
+ ldr ip, [r1, #OFS_SH2_p_sdram]
60
+ eor r0, r0, #1
61
+ mov r0, r0, lsl #SH2_RAM_SHIFT
62
+ ldrb r0, [ip, r0, lsr #SH2_RAM_SHIFT]
63
+ bx lr
64
+
65
+sh2_read8_da:
66
+ ldr ip, [r1, #OFS_SH2_p_da]
67
+ eor r0, r0, #1
68
+ mov r0, r0, lsl #SH2_DA_SHIFT
69
+ ldrb r0, [ip, r0, lsr #SH2_DA_SHIFT]
70
+ bx lr
71
+
72
+sh2_read8_dram:
73
+ ldr ip, [r1, #OFS_SH2_p_dram]
74
+ eor r0, r0, #1
75
+ mov r0, r0, lsl #SH2_DRAM_SHIFT
76
+ ldrb r0, [ip, r0, lsr #SH2_DRAM_SHIFT]
77
+ bx lr
78
+
79
+sh2_read16_rom:
80
+ ldr ip, [r1, #OFS_SH2_p_rom]
81
+ mov r0, r0, lsl #SH2_ROM_SHIFT
82
+ mov r0, r0, lsr #SH2_ROM_SHIFT
83
+ ldrh r0, [ip, r0]
84
+ bx lr
85
+
86
+sh2_read16_sdram:
87
+ ldr ip, [r1, #OFS_SH2_p_sdram]
88
+ mov r0, r0, lsl #SH2_RAM_SHIFT
89
+ mov r0, r0, lsr #SH2_RAM_SHIFT
90
+ ldrh r0, [ip, r0]
91
+ bx lr
92
+
93
+sh2_read16_da:
94
+ ldr ip, [r1, #OFS_SH2_p_da]
95
+ mov r0, r0, lsl #SH2_DA_SHIFT
96
+ mov r0, r0, lsr #SH2_DA_SHIFT
97
+ ldrh r0, [ip, r0]
98
+ bx lr
99
+
100
+sh2_read16_dram:
101
+ ldr ip, [r1, #OFS_SH2_p_dram]
102
+ mov r0, r0, lsl #SH2_DRAM_SHIFT
103
+ mov r0, r0, lsr #SH2_DRAM_SHIFT
104
+ ldrh r0, [ip, r0]
105
+ bx lr
106
+
107
+sh2_read32_rom:
108
+ ldr ip, [r1, #OFS_SH2_p_rom]
109
+ mov r0, r0, lsl #SH2_ROM_SHIFT
110
+ ldr r0, [ip, r0, lsr #SH2_ROM_SHIFT]
111
+ mov r0, r0, ror #16
112
+ bx lr
113
+
114
+sh2_read32_sdram:
115
+ ldr ip, [r1, #OFS_SH2_p_sdram]
116
+ mov r0, r0, lsl #SH2_RAM_SHIFT
117
+ ldr r0, [ip, r0, lsr #SH2_RAM_SHIFT]
118
+ mov r0, r0, ror #16
119
+ bx lr
120
+
121
+sh2_read32_da:
122
+ ldr ip, [r1, #OFS_SH2_p_da]
123
+ mov r0, r0, lsl #SH2_DA_SHIFT
124
+ ldr r0, [ip, r0, lsr #SH2_DA_SHIFT]
125
+ mov r0, r0, ror #16
126
+ bx lr
127
+
128
+sh2_read32_dram:
129
+ ldr ip, [r1, #OFS_SH2_p_dram]
130
+ mov r0, r0, lsl #SH2_DRAM_SHIFT
131
+ ldr r0, [ip, r0, lsr #SH2_DRAM_SHIFT]
132
+ mov r0, r0, ror #16
133
+ bx lr
134
+#endif
135
+
136
+sh2_write8_sdram:
137
+ @ preserve r0-r2 for tail call
138
+ ldr ip, [r2, #OFS_SH2_p_sdram]
139
+ eor r3, r0, #1
140
+ mov r3, r3, lsl #SH2_RAM_SHIFT
141
+ strb r1, [ip, r3, lsr #SH2_RAM_SHIFT]
142
+#ifdef DRC_SH2
143
+ ldr r1, [r2, #OFS_SH2_p_drcblk_ram]
144
+ ldrb r3, [r1, r3, lsr #SH2_RAM_SHIFT+1]
145
+ cmp r3, #0
146
+ bxeq lr
147
+ @ need to load aligned 16 bit data for check
148
+ bic r0, r0, #1
149
+ mov r1, r0, lsl #SH2_RAM_SHIFT
150
+ mov r1, r1, lsr #SH2_RAM_SHIFT
151
+ ldrh r1, [ip, r1]
152
+ b sh2_sdram_checks
153
+#else
154
+ bx lr
155
+#endif
156
+
157
+sh2_write8_da:
158
+ @ preserve r0 and r2 for tail call
159
+ ldr ip, [r2, #OFS_SH2_p_da]
160
+ eor r3, r0, #1
161
+ mov r3, r3, lsl #SH2_DA_SHIFT
162
+ strb r1, [ip, r3, lsr #SH2_DA_SHIFT]
163
+#ifdef DRC_SH2
164
+ ldr ip, [r2, #OFS_SH2_p_drcblk_da]
165
+ ldrb r1, [ip, r3, lsr #SH2_DA_SHIFT+1]
166
+ bic r0, r0, #1
167
+ cmp r1, #0
168
+ bxeq lr
169
+ mov r1, #2
170
+ b sh2_drc_wcheck_da
171
+#else
172
+ bx lr
173
+#endif
174
+
175
+sh2_write8_dram:
176
+ tst r1, #0xff
177
+ ldrne ip, [r2, #OFS_SH2_p_dram]
178
+ eorne r3, r0, #1
179
+ movne r3, r3, lsl #SH2_DRAM_SHIFT
180
+ strneb r1, [ip, r3, lsr #SH2_DRAM_SHIFT]
181
+ bx lr
182
+
183
+sh2_write16_sdram:
184
+ @ preserve r0-r2 for tail call
185
+ ldr ip, [r2, #OFS_SH2_p_sdram]
186
+ mov r3, r0, lsl #SH2_RAM_SHIFT
187
+ mov r3, r3, lsr #SH2_RAM_SHIFT
188
+ strh r1, [ip, r3]
189
+#ifdef DRC_SH2
190
+ ldr ip, [r2, #OFS_SH2_p_drcblk_ram]
191
+ ldrb r3, [ip, r3, lsr #1]
192
+ cmp r3, #0
193
+ bxeq lr
194
+ b sh2_sdram_checks
195
+#else
196
+ bx lr
197
+#endif
198
+
199
+sh2_write16_da:
200
+ @ preserve r0 and r2 for tail call
201
libretro-picodrive-0~git20200112.tar.xz/pico/32x/pwm.c -> libretro-picodrive-0~git20200716.tar.xz/pico/32x/pwm.c
Changed
201
1
2
*/
3
#include "../pico_int.h"
4
5
-static int pwm_cycles;
6
-static int pwm_mult;
7
-static int pwm_ptr;
8
-static int pwm_irq_reload;
9
-static int pwm_doing_fifo;
10
-static int pwm_silent;
11
+static struct {
12
+ int cycles;
13
+ unsigned mult;
14
+ int ptr;
15
+ int irq_reload;
16
+ int doing_fifo;
17
+ int silent;
18
+ int irq_timer;
19
+ int irq_state;
20
+ short current[2];
21
+} pwm;
22
+
23
+enum { PWM_IRQ_LOCKED, PWM_IRQ_STOPPED, PWM_IRQ_LOW, PWM_IRQ_HIGH };
24
25
void p32x_pwm_ctl_changed(void)
26
{
27
int control = Pico32x.regs[0x30 / 2];
28
int cycles = Pico32x.regs[0x32 / 2];
29
+ int pwm_irq_opt = PicoIn.opt & POPT_PWM_IRQ_OPT;
30
31
cycles = (cycles - 1) & 0x0fff;
32
- pwm_cycles = cycles;
33
+ pwm.cycles = cycles;
34
35
// supposedly we should stop FIFO when xMd is 0,
36
// but mars test disagrees
37
- pwm_mult = 0;
38
+ pwm.mult = 0;
39
if ((control & 0x0f) != 0)
40
- pwm_mult = 0x10000 / cycles;
41
+ pwm.mult = 0x10000 / cycles;
42
43
- pwm_irq_reload = (control & 0x0f00) >> 8;
44
- pwm_irq_reload = ((pwm_irq_reload - 1) & 0x0f) + 1;
45
+ pwm.irq_timer = (control & 0x0f00) >> 8;
46
+ pwm.irq_timer = ((pwm.irq_timer - 1) & 0x0f) + 1;
47
+ pwm.irq_reload = pwm.irq_timer;
48
+ pwm.irq_state = pwm_irq_opt ? PWM_IRQ_STOPPED: PWM_IRQ_LOCKED;
49
50
if (Pico32x.pwm_irq_cnt == 0)
51
- Pico32x.pwm_irq_cnt = pwm_irq_reload;
52
+ Pico32x.pwm_irq_cnt = pwm.irq_reload;
53
}
54
55
static void do_pwm_irq(SH2 *sh2, unsigned int m68k_cycles)
56
57
p32x_trigger_irq(sh2, m68k_cycles, P32XI_PWM);
58
59
if (Pico32x.regs[0x30 / 2] & P32XP_RTP) {
60
- p32x_event_schedule(m68k_cycles, P32X_EVENT_PWM, pwm_cycles / 3 + 1);
61
+ p32x_event_schedule(m68k_cycles, P32X_EVENT_PWM, pwm.cycles / 3 + 1);
62
// note: might recurse
63
p32x_dreq1_trigger();
64
}
65
66
67
static int convert_sample(unsigned int v)
68
{
69
+ if (v > pwm.cycles)
70
+ v = pwm.cycles;
71
if (v == 0)
72
return 0;
73
- if (v > pwm_cycles)
74
- v = pwm_cycles;
75
- return ((int)v - pwm_cycles / 2) * pwm_mult;
76
+ return v * pwm.mult - 0x10000/2;
77
}
78
79
#define consume_fifo(sh2, m68k_cycles) { \
80
int cycles_diff = ((m68k_cycles) * 3) - Pico32x.pwm_cycle_p; \
81
- if (cycles_diff >= pwm_cycles) \
82
+ if (cycles_diff >= pwm.cycles) \
83
consume_fifo_do(sh2, m68k_cycles, cycles_diff); \
84
}
85
86
87
unsigned short *fifo_r = mem->pwm_fifo[1];
88
int sum = 0;
89
90
- if (pwm_cycles == 0 || pwm_doing_fifo)
91
+ if (pwm.cycles == 0 || pwm.doing_fifo)
92
return;
93
94
elprintf(EL_PWM, "pwm: %u: consume %d/%d, %d,%d ptr %d",
95
- m68k_cycles, sh2_cycles_diff, sh2_cycles_diff / pwm_cycles,
96
- Pico32x.pwm_p[0], Pico32x.pwm_p[1], pwm_ptr);
97
+ m68k_cycles, sh2_cycles_diff, sh2_cycles_diff / pwm.cycles,
98
+ Pico32x.pwm_p[0], Pico32x.pwm_p[1], pwm.ptr);
99
100
// this is for recursion from dreq1 writes
101
- pwm_doing_fifo = 1;
102
+ pwm.doing_fifo = 1;
103
104
- for (; sh2_cycles_diff >= pwm_cycles; sh2_cycles_diff -= pwm_cycles)
105
+ while (sh2_cycles_diff >= pwm.cycles)
106
{
107
+ sh2_cycles_diff -= pwm.cycles;
108
+
109
if (Pico32x.pwm_p[0] > 0) {
110
- fifo_l[0] = fifo_l[1];
111
- fifo_l[1] = fifo_l[2];
112
- fifo_l[2] = fifo_l[3];
113
+ mem->pwm_index[0] = (mem->pwm_index[0]+1) % 4;
114
Pico32x.pwm_p[0]--;
115
- mem->pwm_current[0] = convert_sample(fifo_l[0]);
116
- sum += mem->pwm_current[0];
117
+ pwm.current[0] = convert_sample(fifo_l[mem->pwm_index[0]]);
118
+ sum |= (u16)pwm.current[0];
119
}
120
if (Pico32x.pwm_p[1] > 0) {
121
- fifo_r[0] = fifo_r[1];
122
- fifo_r[1] = fifo_r[2];
123
- fifo_r[2] = fifo_r[3];
124
+ mem->pwm_index[1] = (mem->pwm_index[1]+1) % 4;
125
Pico32x.pwm_p[1]--;
126
- mem->pwm_current[1] = convert_sample(fifo_r[0]);
127
- sum += mem->pwm_current[1];
128
+ pwm.current[1] = convert_sample(fifo_r[mem->pwm_index[1]]);
129
+ sum |= (u16)pwm.current[1];
130
}
131
132
- mem->pwm[pwm_ptr * 2 ] = mem->pwm_current[0];
133
- mem->pwm[pwm_ptr * 2 + 1] = mem->pwm_current[1];
134
- pwm_ptr = (pwm_ptr + 1) & (PWM_BUFF_LEN - 1);
135
+ mem->pwm[pwm.ptr * 2 ] = pwm.current[0];
136
+ mem->pwm[pwm.ptr * 2 + 1] = pwm.current[1];
137
+ pwm.ptr = (pwm.ptr + 1) & (PWM_BUFF_LEN - 1);
138
139
if (--Pico32x.pwm_irq_cnt == 0) {
140
- Pico32x.pwm_irq_cnt = pwm_irq_reload;
141
+ Pico32x.pwm_irq_cnt = pwm.irq_reload;
142
do_pwm_irq(sh2, m68k_cycles);
143
+ } else if (Pico32x.pwm_p[1] == 0 && pwm.irq_state >= PWM_IRQ_LOW) {
144
+ // buffer underrun. Reduce reload rate if above programmed setting.
145
+ if (pwm.irq_reload > pwm.irq_timer)
146
+ pwm.irq_reload--;
147
+ pwm.irq_state = PWM_IRQ_LOW;
148
}
149
}
150
Pico32x.pwm_cycle_p = m68k_cycles * 3 - sh2_cycles_diff;
151
- pwm_doing_fifo = 0;
152
+ pwm.doing_fifo = 0;
153
if (sum != 0)
154
- pwm_silent = 0;
155
+ pwm.silent = 0;
156
}
157
158
static int p32x_pwm_schedule_(SH2 *sh2, unsigned int m68k_now)
159
{
160
- unsigned int sh2_now = m68k_now * 3;
161
+ unsigned int pwm_now = m68k_now * 3;
162
int cycles_diff_sh2;
163
164
- if (pwm_cycles == 0)
165
+ if (pwm.cycles == 0)
166
return 0;
167
168
- cycles_diff_sh2 = sh2_now - Pico32x.pwm_cycle_p;
169
- if (cycles_diff_sh2 >= pwm_cycles)
170
+ cycles_diff_sh2 = pwm_now - Pico32x.pwm_cycle_p;
171
+ if (cycles_diff_sh2 >= pwm.cycles)
172
consume_fifo_do(sh2, m68k_now, cycles_diff_sh2);
173
174
if (!((Pico32x.sh2irq_mask[0] | Pico32x.sh2irq_mask[1]) & 1))
175
return 0; // masked by everyone
176
177
- cycles_diff_sh2 = sh2_now - Pico32x.pwm_cycle_p;
178
- return (Pico32x.pwm_irq_cnt * pwm_cycles
179
+ cycles_diff_sh2 = pwm_now - Pico32x.pwm_cycle_p;
180
+ return (Pico32x.pwm_irq_cnt * pwm.cycles
181
- cycles_diff_sh2) / 3 + 1;
182
}
183
184
185
consume_fifo(sh2, m68k_cycles);
186
187
a &= 0x0e;
188
- switch (a) {
189
- case 0: // control
190
- case 2: // cycle
191
+ switch (a/2) {
192
+ case 0/2: // control
193
+ case 2/2: // cycle
194
d = Pico32x.regs[(0x30 + a) / 2];
195
break;
196
197
- case 4: // L ch
198
+ case 4/2: // L ch
199
if (Pico32x.pwm_p[0] == 3)
200
d |= P32XP_FULL;
201
libretro-picodrive-0~git20200112.tar.xz/pico/32x/sh2soc.c -> libretro-picodrive-0~git20200716.tar.xz/pico/32x/sh2soc.c
Changed
201
1
2
#include "../pico_int.h"
3
#include "../memory.h"
4
5
+#include "../../cpu/sh2/compiler.h"
6
+DRC_DECLARE_SR;
7
+
8
// DMAC handling
9
struct dma_chan {
10
unsigned int sar, dar; // src, dst addr
11
12
case 0:
13
d = p32x_sh2_read8(chan->sar, sh2);
14
p32x_sh2_write8(chan->dar, d, sh2);
15
+ break;
16
case 1:
17
d = p32x_sh2_read16(chan->sar, sh2);
18
p32x_sh2_write16(chan->dar, d, sh2);
19
20
chan->sar += size;
21
}
22
23
+// optimization for copying around memory with SH2 DMA
24
+static void dmac_memcpy(struct dma_chan *chan, SH2 *sh2)
25
+{
26
+ u32 size = (chan->chcr >> 10) & 3, up = chan->chcr & (1 << 14);
27
+ int count;
28
+
29
+ if (!up || chan->tcr < 4)
30
+ return;
31
+#if MARS_CHECK_HACK
32
+ // XXX Mars Check Program copies 32K longwords (128KB) from a 64KB buffer in
33
+ // ROM or DRAM to SDRAM in 4-longword mode, overwriting an SDRAM comm area in
34
+ // turn, which crashes the test on emulators without CPU cache emulation.
35
+ // This may be a bug in Mars Check. As a kludge limit the transfer to 64KB,
36
+ // which is what the check program test uses for checking the result.
37
+ // A better way would clearly be to have a mechanism to patch the ROM...
38
+ if (size == 3 && chan->tcr == 32768 && chan->dar == 0x06020000) size = 1;
39
+#endif
40
+ if (size == 3) size = 2; // 4-word xfer mode still counts in words
41
+ // XXX check TCR being a multiple of 4 in 4-word xfer mode?
42
+ // XXX check alignment of sar/dar, generating a bus error if unaligned?
43
+ count = p32x_sh2_memcpy(chan->dar, chan->sar, chan->tcr, 1 << size, sh2);
44
+
45
+ chan->sar += count << size;
46
+ chan->dar += count << size;
47
+ chan->tcr -= count;
48
+}
49
+
50
// DMA trigger by SH2 register write
51
static void dmac_trigger(SH2 *sh2, struct dma_chan *chan)
52
{
53
54
55
if (chan->chcr & DMA_AR) {
56
// auto-request transfer
57
+ sh2->state |= SH2_STATE_SLEEP;
58
+ if ((((chan->chcr >> 12) ^ (chan->chcr >> 14)) & 3) == 0 &&
59
+ (((chan->chcr >> 14) ^ (chan->chcr >> 15)) & 1) == 1) {
60
+ // SM == DM and either DM0 or DM1 are set. check for mem to mem copy
61
+ dmac_memcpy(chan, sh2);
62
+ }
63
while ((int)chan->tcr > 0)
64
dmac_transfer_one(sh2, chan);
65
dmac_transfer_complete(sh2, chan);
66
67
}
68
69
// timer state - FIXME
70
-static int timer_cycles[2];
71
-static int timer_tick_cycles[2];
72
+static u32 timer_cycles[2];
73
+static u32 timer_tick_cycles[2];
74
+static u32 timer_tick_factor[2];
75
76
// timers
77
void p32x_timers_recalc(void)
78
79
80
// SH2 timer step
81
for (i = 0; i < 2; i++) {
82
+ sh2s[i].state &= ~SH2_TIMER_RUN;
83
+ if (PREG8(sh2s[i].peri_regs, 0x80) & 0x20) // TME
84
+ sh2s[i].state |= SH2_TIMER_RUN;
85
tmp = PREG8(sh2s[i].peri_regs, 0x80) & 7;
86
// Sclk cycles per timer tick
87
if (tmp)
88
89
else
90
cycles = 2;
91
timer_tick_cycles[i] = cycles;
92
+ timer_tick_factor[i] = (1ULL << 32) / cycles;
93
timer_cycles[i] = 0;
94
elprintf(EL_32XP, "WDT cycles[%d] = %d", i, cycles);
95
}
96
}
97
98
-void p32x_timers_do(unsigned int m68k_slice)
99
+NOINLINE void p32x_timer_do(SH2 *sh2, unsigned int m68k_slice)
100
{
101
unsigned int cycles = m68k_slice * 3;
102
- int cnt, i;
103
-
104
- // WDT timers
105
- for (i = 0; i < 2; i++) {
106
- void *pregs = sh2s[i].peri_regs;
107
- if (PREG8(pregs, 0x80) & 0x20) { // TME
108
- timer_cycles[i] += cycles;
109
- cnt = PREG8(pregs, 0x81);
110
- while (timer_cycles[i] >= timer_tick_cycles[i]) {
111
- timer_cycles[i] -= timer_tick_cycles[i];
112
- cnt++;
113
- }
114
- if (cnt >= 0x100) {
115
- int level = PREG8(pregs, 0xe3) >> 4;
116
- int vector = PREG8(pregs, 0xe4) & 0x7f;
117
- elprintf(EL_32XP, "%csh2 WDT irq (%d, %d)",
118
- i ? 's' : 'm', level, vector);
119
- sh2_internal_irq(&sh2s[i], level, vector);
120
- cnt &= 0xff;
121
- }
122
- PREG8(pregs, 0x81) = cnt;
123
+ void *pregs = sh2->peri_regs;
124
+ int cnt; int i = sh2->is_slave;
125
+
126
+ // WDT timer
127
+ timer_cycles[i] += cycles;
128
+ if (timer_cycles[i] > timer_tick_cycles[i]) {
129
+ // cnt = timer_cycles[i] / timer_tick_cycles[i];
130
+ cnt = (1ULL * timer_cycles[i] * timer_tick_factor[i]) >> 32;
131
+ timer_cycles[i] -= timer_tick_cycles[i] * cnt;
132
+
133
+ cnt += PREG8(pregs, 0x81);
134
+ if (cnt >= 0x100) {
135
+ int level = PREG8(pregs, 0xe3) >> 4;
136
+ int vector = PREG8(pregs, 0xe4) & 0x7f;
137
+ elprintf(EL_32XP, "%csh2 WDT irq (%d, %d)",
138
+ i ? 's' : 'm', level, vector);
139
+ sh2_internal_irq(sh2, level, vector);
140
+ cnt &= 0xff;
141
}
142
+ PREG8(pregs, 0x81) = cnt;
143
}
144
}
145
146
147
// SH2 internal peripheral memhandlers
148
// we keep them in little endian format
149
150
-u32 sh2_peripheral_read8(u32 a, SH2 *sh2)
151
+u32 REGPARM(2) sh2_peripheral_read8(u32 a, SH2 *sh2)
152
{
153
u8 *r = (void *)sh2->peri_regs;
154
u32 d;
155
156
157
elprintf_sh2(sh2, EL_32XP, "peri r8 [%08x] %02x @%06x",
158
a | ~0x1ff, d, sh2_pc(sh2));
159
+ if ((a & 0x1c0) == 0x140) {
160
+ // abused as comm area
161
+ DRC_SAVE_SR(sh2);
162
+ p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3);
163
+ DRC_RESTORE_SR(sh2);
164
+ }
165
return d;
166
}
167
168
-u32 sh2_peripheral_read16(u32 a, SH2 *sh2)
169
+u32 REGPARM(2) sh2_peripheral_read16(u32 a, SH2 *sh2)
170
{
171
u16 *r = (void *)sh2->peri_regs;
172
u32 d;
173
174
- a &= 0x1ff;
175
+ a &= 0x1fe;
176
d = r[(a / 2) ^ 1];
177
178
elprintf_sh2(sh2, EL_32XP, "peri r16 [%08x] %04x @%06x",
179
a | ~0x1ff, d, sh2_pc(sh2));
180
+ if ((a & 0x1c0) == 0x140) {
181
+ // abused as comm area
182
+ DRC_SAVE_SR(sh2);
183
+ p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3);
184
+ DRC_RESTORE_SR(sh2);
185
+ }
186
return d;
187
}
188
189
-u32 sh2_peripheral_read32(u32 a, SH2 *sh2)
190
+u32 REGPARM(2) sh2_peripheral_read32(u32 a, SH2 *sh2)
191
{
192
u32 d;
193
+
194
a &= 0x1fc;
195
d = sh2->peri_regs[a / 4];
196
197
elprintf_sh2(sh2, EL_32XP, "peri r32 [%08x] %08x @%06x",
198
a | ~0x1ff, d, sh2_pc(sh2));
199
+ if (a == 0x18c)
200
+ // kludge for polling COMM while polling for end of DMA
201
libretro-picodrive-0~git20200112.tar.xz/pico/arm_features.h -> libretro-picodrive-0~git20200716.tar.xz/pico/arm_features.h
Changed
34
1
2
3
#endif
4
5
+// indexed branch (XB) via branch table (BT)
6
+#ifdef __PIC__
7
+#define PIC_XB(c,r,s) add##c pc, r, s
8
+#define PIC_BT(a) b a
9
+#else
10
+#define PIC_XB(c,r,s) ldr##c pc, [pc, r, s]
11
+#define PIC_BT(a) .word a
12
+#endif
13
+
14
+// load data address (LDR) either via literal pool or via GOT
15
+#ifdef __PIC__
16
+// can't use pool loads since ldr= only allows a symbol or a constant expr :-(
17
+#define PIC_LDR_INIT() \
18
+ .macro pic_ldr r t a; \
19
+ ldr \r, [pc, $.LD\@-.-8]; \
20
+ ldr \t, [pc, $.LD\@-.-4]; \
21
+ .LP\@:add \r, pc; \
22
+ ldr \r, [\r, \t]; \
23
+ add pc, $4; \
24
+ .LD\@:.word _GLOBAL_OFFSET_TABLE_-.LP\@-8; \
25
+ .word \a(GOT); \
26
+ .endm;
27
+#define PIC_LDR(r,t,a) pic_ldr r, t, a
28
+#else
29
+#define PIC_LDR_INIT()
30
+#define PIC_LDR(r,t,a) ldr r, =a
31
+#endif
32
+
33
#endif /* __ARM_FEATURES_H__ */
34
libretro-picodrive-0~git20200112.tar.xz/pico/carthw/carthw.h -> libretro-picodrive-0~git20200716.tar.xz/pico/carthw/carthw.h
Changed
17
1
2
3
/* svp */
4
+#include "../pico_types.h"
5
#include "svp/ssp16.h"
6
7
typedef struct {
8
9
extern int carthw_ssf2_active;
10
extern unsigned char carthw_ssf2_banks[8];
11
void carthw_ssf2_startup(void);
12
-void carthw_ssf2_write8(unsigned int a, unsigned int d);
13
+void carthw_ssf2_write8(u32 a, u32 d);
14
15
/* misc */
16
void carthw_Xin1_startup(void);
17
libretro-picodrive-0~git20200112.tar.xz/pico/carthw/svp/compiler.c -> libretro-picodrive-0~git20200716.tar.xz/pico/carthw/svp/compiler.c
Changed
53
1
2
/* spacial version of call for calling C needed on ios, since we use r9.. */
3
static void emith_call_c_func(void *target)
4
{
5
- EOP_STMFD_SP(A_R7M|A_R9M);
6
+ EOP_STMFD_SP(M2(7,9));
7
emith_call(target);
8
- EOP_LDMFD_SP(A_R7M|A_R9M);
9
+ EOP_LDMFD_SP(M2(7,9));
10
}
11
#else
12
#define emith_call_c_func emith_call
13
14
}
15
tr_mov16(0, *pc);
16
tr_r0_to_STACK(*pc);
17
- if (tmpv != A_COND_AL) {
18
- u32 *real_ptr = tcache_ptr;
19
- tcache_ptr = jump_op;
20
- EOP_C_B(tr_neg_cond(tmpv),0,real_ptr - jump_op - 2);
21
- tcache_ptr = real_ptr;
22
- }
23
+ if (tmpv != A_COND_AL)
24
+ EOP_C_B_PTR(jump_op, tr_neg_cond(tmpv), 0,
25
+ tcache_ptr - jump_op - 2);
26
tr_mov16_cond(tmpv, 0, imm);
27
if (tmpv != A_COND_AL)
28
tr_mov16_cond(tr_neg_cond(tmpv), 0, *pc);
29
30
ssp_block_table[pc];
31
if (target != NULL)
32
emith_jump(target);
33
- else {
34
- int ops = emith_jump(ssp_drc_next);
35
- end_ptr = tcache_ptr;
36
- // cause the next block to be emitted over jump instruction
37
- tcache_ptr -= ops;
38
- }
39
+ else
40
+ emith_jump(ssp_drc_next);
41
}
42
else {
43
u32 *target1 = (pc < 0x400) ?
44
45
tr_flush_dirty_ST();
46
tr_flush_dirty_pmcrs();
47
block_end = emit_block_epilogue(ccount, end_cond, jump_pc, pc);
48
+ emith_pool_commit(0);
49
+ emith_flush();
50
51
if (tcache_ptr - (u32 *)tcache > DRC_TCACHE_SIZE/4) {
52
elprintf(EL_ANOMALY|EL_STATUS|EL_SVP, "tcache overflow!\n");
53
libretro-picodrive-0~git20200112.tar.xz/pico/carthw/svp/stub_arm.S -> libretro-picodrive-0~git20200716.tar.xz/pico/carthw/svp/stub_arm.S
Changed
61
1
2
3
#include "../../arm_features.h"
4
5
-.syntax unified
6
+@.syntax unified
7
.text
8
.align 2
9
10
11
bgt ssp_hle_902_loop
12
13
tst r12, #1
14
- ldrhne r0, [r2], #2
15
- strhne r0, [r3], #2
16
+ ldrneh r0, [r2], #2
17
+ strneh r0, [r3], #2
18
19
ldr r0, [r7, #SSP_OFFS_IRAM_ROM]
20
add r1, r7, #0x200
21
22
mov r12, #0x4000
23
orr r12,r12,#0x0018
24
subs r12,r3, r12
25
- subsne r12,r12,#0x0400
26
+ subnes r12,r12,#0x0400
27
blne tr_unhandled
28
29
orr r2, r2, r2, lsl #16
30
31
32
hle_07_036_no_ovrwr:
33
tst r1, #2
34
- strhne r2, [r1], #0x3e @ align
35
+ strneh r2, [r1], #0x3e @ align
36
subne r0, r0, #1
37
subs r0, r0, #4
38
blt hle_07_036_l2
39
40
tst r0, #2
41
strne r2, [r1], #0x40
42
tst r0, #1
43
- strhne r2, [r1], #2
44
+ strneh r2, [r1], #2
45
b hle_07_036_end_copy
46
47
hle_07_036_ovrwr:
48
49
50
hle_07_036_ol2:
51
tst r0, #1
52
- ldrhne r3, [r1]
53
+ ldrneh r3, [r1]
54
andne r3, r3, r12
55
orrne r3, r3, r2
56
- strhne r3, [r1], #2
57
+ strneh r3, [r1], #2
58
59
hle_07_036_end_copy:
60
ldr r2, [r7, #SSP_OFFS_DRAM]
61
libretro-picodrive-0~git20200112.tar.xz/pico/cd/gfx_dma.c -> libretro-picodrive-0~git20200716.tar.xz/pico/cd/gfx_dma.c
Changed
21
1
2
3
#include "cell_map.c"
4
5
-#ifndef UTYPES_DEFINED
6
-typedef unsigned short u16;
7
-#endif
8
-
9
// check: Heart of the alien, jaguar xj 220
10
PICO_INTERNAL void DmaSlowCell(unsigned int source, unsigned int a, int len, unsigned char inc)
11
{
12
13
asrc = cell_map(source >> 2) << 2;
14
asrc |= source & 2;
15
// if(a&1) d=(d<<8)|(d>>8); // ??
16
- r[a>>1] = *(u16 *)(base + asrc);
17
+ VideoWriteVRAM(a, *(u16 *)(base + asrc));
18
source += 2;
19
// AutoIncrement
20
a=(u16)(a+inc);
21
libretro-picodrive-0~git20200112.tar.xz/pico/cd/mcd.c -> libretro-picodrive-0~git20200716.tar.xz/pico/cd/mcd.c
Changed
17
1
2
if (SekShouldInterrupt())
3
Pico_mcd->m.s68k_poll_a = 0;
4
5
+ pprof_start(s68k);
6
SekCycleCntS68k += cyc_do;
7
#if defined(EMU_C68K)
8
PicoCpuCS68k.cycles = cyc_do;
9
10
#elif defined(EMU_F68K)
11
SekCycleCntS68k += fm68k_emulate(&PicoCpuFS68k, cyc_do, 0) - cyc_do;
12
#endif
13
+ pprof_end(s68k);
14
}
15
16
static void pcd_set_cycle_mult(void)
17
libretro-picodrive-0~git20200112.tar.xz/pico/cd/memory.c -> libretro-picodrive-0~git20200716.tar.xz/pico/cd/memory.c
Changed
16
1
2
uptr s68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];
3
uptr s68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];
4
5
+#ifndef _ASM_CD_MEMORY_C
6
MAKE_68K_READ8(s68k_read8, s68k_read8_map)
7
MAKE_68K_READ16(s68k_read16, s68k_read16_map)
8
MAKE_68K_READ32(s68k_read32, s68k_read16_map)
9
MAKE_68K_WRITE8(s68k_write8, s68k_write8_map)
10
MAKE_68K_WRITE16(s68k_write16, s68k_write16_map)
11
MAKE_68K_WRITE32(s68k_write32, s68k_write16_map)
12
+#endif
13
14
// -----------------------------------------------------------------
15
16
libretro-picodrive-0~git20200112.tar.xz/pico/cd/memory_arm.S -> libretro-picodrive-0~git20200716.tar.xz/pico/cd/memory_arm.S
Changed
201
1
2
@* See COPYING file in the top-level directory.
3
@*
4
5
-#include "../pico_int_o32.h"
6
+#include "../arm_features.h"
7
+#include "../pico_int_offs.h"
8
9
.equiv PCM_STEP_SHIFT, 11
10
11
12
.extern PicoWrite16_io
13
.extern m68k_comm_check
14
15
+ PIC_LDR_INIT()
16
17
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
18
19
20
@ r0=addr[in,out], r1,r2=tmp
21
.macro cell_map
22
ands r1, r0, #0x01c000
23
- ldrne pc, [pc, r1, lsr #12]
24
- beq 0f @ most common?
25
- .long 0f
26
- .long 0f
27
- .long 0f
28
- .long 0f
29
- .long 1f
30
- .long 1f
31
- .long 2f
32
- .long 3f
33
+ PIC_XB(ne ,r1, lsr #12)
34
+ b 0f @ most common?
35
+ PIC_BT(0f)
36
+ PIC_BT(0f)
37
+ PIC_BT(0f)
38
+ PIC_BT(0f)
39
+ PIC_BT(1f)
40
+ PIC_BT(1f)
41
+ PIC_BT(2f)
42
+ PIC_BT(3f)
43
1: @ x16 cells
44
and r1, r0, #0x7e00 @ col
45
and r2, r0, #0x01fc @ row
46
47
mov r3, #0x0e0000
48
0:
49
cell_map
50
- ldr r1, =Pico
51
+ PIC_LDR(r1, r2, Pico)
52
add r0, r0, r3
53
ldr r1, [r1, #OFS_Pico_rom] @ Pico.mcd (used everywhere)
54
eor r0, r0, #1
55
56
cmp r1, #0x2000 @ a120xx?
57
bne PicoRead8_io
58
59
- ldr r1, =Pico
60
+ PIC_LDR(r1, r2, Pico)
61
and r0, r0, #0x3f
62
ldr r1, [r1, #OFS_Pico_rom] @ Pico.mcd
63
cmp r0, #0x0e
64
- ldrlt pc, [pc, r0, lsl #2]
65
+ PIC_XB(lt ,r0, lsl #2)
66
b m_m68k_read8_hi
67
- .long m_m68k_read8_r00
68
- .long m_m68k_read8_r01
69
- .long m_m68k_read8_r02
70
- .long m_m68k_read8_r03
71
- .long m_m68k_read8_r04
72
- .long m_read_null @ unused bits
73
- .long m_m68k_read8_r06
74
- .long m_m68k_read8_r07
75
- .long m_m68k_read8_r08
76
- .long m_m68k_read8_r09
77
- .long m_read_null @ reserved
78
- .long m_read_null
79
- .long m_m68k_read8_r0c
80
- .long m_m68k_read8_r0d
81
+ PIC_BT(m_m68k_read8_r00)
82
+ PIC_BT(m_m68k_read8_r01)
83
+ PIC_BT(m_m68k_read8_r02)
84
+ PIC_BT(m_m68k_read8_r03)
85
+ PIC_BT(m_m68k_read8_r04)
86
+ PIC_BT(m_read_null) @ unused bits
87
+ PIC_BT(m_m68k_read8_r06)
88
+ PIC_BT(m_m68k_read8_r07)
89
+ PIC_BT(m_m68k_read8_r08)
90
+ PIC_BT(m_m68k_read8_r09)
91
+ PIC_BT(m_read_null) @ reserved
92
+ PIC_BT(m_read_null)
93
+ PIC_BT(m_m68k_read8_r0c)
94
+ PIC_BT(m_m68k_read8_r0d)
95
m_m68k_read8_r00:
96
add r1, r1, #0x110000
97
ldr r0, [r1, #0x30]
98
99
bx lr
100
m_m68k_read8_r03:
101
add r1, r1, #0x110000
102
- push {r1, lr}
103
+ stmfd sp!, {r1, lr}
104
bl m68k_comm_check
105
- pop {r1, lr}
106
+ ldmfd sp!, {r1, lr}
107
ldrb r0, [r1, #3]
108
and r0, r0, #0xc7
109
bx lr
110
111
add r1, r1, #0x110000
112
movge r0, #0
113
bxge lr
114
- add r1, r0
115
- push {r1, lr}
116
+ add r1, r1, r0
117
+ stmfd sp!, {r1, lr}
118
bl m68k_comm_check
119
- pop {r1, lr}
120
+ ldmfd sp!, {r1, lr}
121
ldrb r0, [r1]
122
bx lr
123
124
125
mov r3, #0x0e0000
126
0:
127
cell_map
128
- ldr r1, =Pico
129
+ PIC_LDR(r1, r2, Pico)
130
add r0, r0, r3
131
ldr r1, [r1, #OFS_Pico_rom] @ Pico.mcd
132
bic r0, r0, #1
133
134
bne PicoRead16_io
135
136
m_m68k_read16_m68k_regs:
137
- ldr r1, =Pico
138
+ PIC_LDR(r1, r2, Pico)
139
and r0, r0, #0x3e
140
ldr r1, [r1, #OFS_Pico_rom] @ Pico.mcd
141
cmp r0, #0x0e
142
- ldrlt pc, [pc, r0, lsl #1]
143
+ PIC_XB(lt ,r0, lsl #1)
144
b m_m68k_read16_hi
145
- .long m_m68k_read16_r00
146
- .long m_m68k_read16_r02
147
- .long m_m68k_read16_r04
148
- .long m_m68k_read16_r06
149
- .long m_m68k_read16_r08
150
- .long m_read_null @ reserved
151
- .long m_m68k_read16_r0c
152
+ PIC_BT(m_m68k_read16_r00)
153
+ PIC_BT(m_m68k_read16_r02)
154
+ PIC_BT(m_m68k_read16_r04)
155
+ PIC_BT(m_m68k_read16_r06)
156
+ PIC_BT(m_m68k_read16_r08)
157
+ PIC_BT(m_read_null) @ reserved
158
+ PIC_BT(m_m68k_read16_r0c)
159
m_m68k_read16_r00:
160
add r1, r1, #0x110000
161
ldr r0, [r1, #0x30]
162
163
bx lr
164
m_m68k_read16_r02:
165
add r1, r1, #0x110000
166
- push {r1, lr}
167
+ stmfd sp!, {r1, lr}
168
bl m68k_comm_check
169
- pop {r1, lr}
170
+ ldmfd sp!, {r1, lr}
171
ldrb r2, [r1, #3]
172
ldrb r0, [r1, #2]
173
and r2, r2, #0xc7
174
175
bxge lr
176
177
add r1, r0, r1
178
- push {r1, lr}
179
+ stmfd sp!, {r1, lr}
180
bl m68k_comm_check
181
- pop {r0, lr}
182
+ ldmfd sp!, {r0, lr}
183
ldrh r0, [r0]
184
mov r1, r0, lsr #8
185
and r0, r0, #0xff
186
187
0:
188
mov r3, r1
189
cell_map
190
- ldr r2, =Pico
191
+ PIC_LDR(r2, r1, Pico)
192
add r0, r0, r12
193
ldr r2, [r2, #OFS_Pico_rom] @ Pico.mcd
194
ldr r2, [r2]
195
196
0:
197
mov r3, r1
198
cell_map
199
- ldr r1, =Pico
200
+ PIC_LDR(r1, r2, Pico)
201
libretro-picodrive-0~git20200112.tar.xz/pico/debug.c -> libretro-picodrive-0~git20200716.tar.xz/pico/debug.c
Changed
63
1
2
!!(Pico.sv.flags & SRF_ENABLED), !!(Pico.sv.flags & SRF_EEPROM), Pico.sv.eeprom_type); MVP;
3
sprintf(dstrp, "sram range: %06x-%06x, reg: %02x\n", Pico.sv.start, Pico.sv.end, Pico.m.sram_reg); MVP;
4
sprintf(dstrp, "pend int: v:%i, h:%i, vdp status: %04x\n", bit(pv->pending_ints,5), bit(pv->pending_ints,4), pv->status); MVP;
5
+ sprintf(dstrp, "VDP regs 00-07: %02x %02x %02x %02x %02x %02x %02x %02x\n",reg[0],reg[1],reg[2],reg[3],reg[4],reg[5],reg[6],reg[7]); MVP;
6
+ sprintf(dstrp, "VDP regs 08-0f: %02x %02x %02x %02x %02x %02x %02x %02x\n",reg[8],reg[9],reg[10],reg[11],reg[12],reg[13],reg[14],reg[15]); MVP;
7
+ sprintf(dstrp, "VDP regs 10-17: %02x %02x %02x %02x %02x %02x %02x %02x\n",reg[16],reg[17],reg[18],reg[19],reg[20],reg[21],reg[22],reg[23]); MVP;
8
+ sprintf(dstrp, "VDP regs 18-1f: %02x %02x %02x %02x %02x %02x %02x %02x\n",reg[24],reg[25],reg[26],reg[27],reg[28],reg[29],reg[30],reg[31]); MVP;
9
+ r = (reg[5]<<9)+(reg[6]<<11);
10
+ sprintf(dstrp, "sprite #0: %04x %04x %04x %04x\n",PicoMem.vram[r/2],PicoMem.vram[r/2+1],PicoMem.vram[r/2+2],PicoMem.vram[r/2+3]); MVP;
11
sprintf(dstrp, "pal: %i, hw: %02x, frame#: %i, cycles: %u\n", Pico.m.pal, Pico.m.hardware, Pico.m.frame_count, SekCyclesDone()); MVP;
12
sprintf(dstrp, "M68k: PC: %06x, SR: %04x, irql: %i\n", SekPc, SekSr, SekIrqLevel); MVP;
13
for (r = 0; r < 8; r++) {
14
15
16
void PDebugZ80Frame(void)
17
{
18
- int lines, line_sample;
19
+ int lines;
20
21
if (PicoIn.AHW & PAHW_SMS)
22
return;
23
24
- if (Pico.m.pal) {
25
+ if (Pico.m.pal)
26
lines = 313;
27
- line_sample = 68;
28
- } else {
29
+ else
30
lines = 262;
31
- line_sample = 93;
32
- }
33
34
z80_resetCycles();
35
PsndStartFrame();
36
37
- if (/*Pico.m.z80Run &&*/ !Pico.m.z80_reset && (PicoIn.opt&POPT_EN_Z80))
38
- PicoSyncZ80(Pico.t.m68c_cnt + line_sample * 488);
39
- if (PicoIn.sndOut)
40
- PsndGetSamples(line_sample);
41
-
42
if (/*Pico.m.z80Run &&*/ !Pico.m.z80_reset && (PicoIn.opt&POPT_EN_Z80)) {
43
PicoSyncZ80(Pico.t.m68c_cnt + 224 * 488);
44
z80_int();
45
}
46
- if (PicoIn.sndOut)
47
- PsndGetSamples(224);
48
49
// sync z80
50
if (/*Pico.m.z80Run &&*/ !Pico.m.z80_reset && (PicoIn.opt&POPT_EN_Z80)) {
51
Pico.t.m68c_cnt += Pico.m.pal ? 151809 : 127671; // cycles adjusted for converter
52
PicoSyncZ80(Pico.t.m68c_cnt);
53
}
54
- if (PicoIn.sndOut && ym2612.dacen && Pico.snd.dac_line < lines)
55
- PsndDoDAC(lines - 1);
56
- PsndDoPSG(lines - 1);
57
+
58
+ if (PicoIn.sndOut)
59
+ PsndGetSamples(lines);
60
61
timers_cycle();
62
Pico.t.m68c_aim = Pico.t.m68c_cnt;
63
libretro-picodrive-0~git20200112.tar.xz/pico/draw.c -> libretro-picodrive-0~git20200716.tar.xz/pico/draw.c
Changed
201
1
2
* line renderer
3
* (c) Copyright Dave, 2004
4
* (C) notaz, 2006-2010
5
+ * (C) kub, 2019-2020
6
*
7
* This work is licensed under the terms of MAME license.
8
* See COPYING file in the top-level directory.
9
10
*/
11
12
#include "pico_int.h"
13
+#define FORCE // layer forcing via debug register?
14
15
int (*PicoScanBegin)(unsigned int num) = NULL;
16
int (*PicoScanEnd) (unsigned int num) = NULL;
17
18
static int HighCacheB[41+1];
19
static int HighPreSpr[80*2+1]; // slightly preprocessed sprites
20
21
+unsigned int VdpSATCache[128]; // VDP sprite cache (1st 32 sprite attr bits)
22
+
23
#define LF_PLANE_1 (1 << 0)
24
#define LF_SH (1 << 1) // must be = 2
25
#define LF_FORCE (1 << 2)
26
27
#define SPRL_HAVE_LO 0x40 // *lo*
28
#define SPRL_MAY_HAVE_OP 0x20 // may have operator sprites on the line
29
#define SPRL_LO_ABOVE_HI 0x10 // low priority sprites may be on top of hi
30
-unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES]; // sprite_count, ^flags, tile_count, [spritep]...
31
+#define SPRL_HAVE_X 0x08 // have sprites with x != 0
32
+#define SPRL_TILE_OVFL 0x04 // tile limit exceeded on previous line
33
+#define SPRL_HAVE_MASK0 0x02 // have sprite with x == 0 in 1st slot
34
+#define SPRL_MASKED 0x01 // lo prio masking by sprite with x == 0 active
35
+unsigned char HighLnSpr[240][4+MAX_LINE_SPRITES+1]; // sprite_count, ^flags, tile_count, sprites_total, [spritep]..., last_width
36
37
int rendstatus_old;
38
int rendlines;
39
40
#define blockcpy memcpy
41
#endif
42
43
-#define TileNormMaker_(pix_func) \
44
+#define TileNormMaker_(pix_func,ret) \
45
{ \
46
unsigned int t; \
47
\
48
49
t = (pack&0x0f000000)>>24; pix_func(5); \
50
t = (pack&0x00f00000)>>20; pix_func(6); \
51
t = (pack&0x000f0000)>>16; pix_func(7); \
52
+ return ret; \
53
}
54
55
-#define TileFlipMaker_(pix_func) \
56
+#define TileFlipMaker_(pix_func,ret) \
57
{ \
58
unsigned int t; \
59
\
60
61
t = (pack&0x000000f0)>> 4; pix_func(5); \
62
t = (pack&0x00000f00)>> 8; pix_func(6); \
63
t = (pack&0x0000f000)>>12; pix_func(7); \
64
+ return ret; \
65
}
66
67
#define TileNormMaker(funcname, pix_func) \
68
static void funcname(unsigned char *pd, unsigned int pack, int pal) \
69
-TileNormMaker_(pix_func)
70
+TileNormMaker_(pix_func,)
71
72
#define TileFlipMaker(funcname, pix_func) \
73
static void funcname(unsigned char *pd, unsigned int pack, int pal) \
74
-TileFlipMaker_(pix_func)
75
+TileFlipMaker_(pix_func,)
76
77
#define TileNormMakerAS(funcname, pix_func) \
78
-static void funcname(unsigned char *pd, unsigned char *mb, unsigned int pack, int pal) \
79
-TileNormMaker_(pix_func)
80
+static unsigned funcname(unsigned char *pd, unsigned m, unsigned int pack, int pal) \
81
+TileNormMaker_(pix_func,m)
82
83
#define TileFlipMakerAS(funcname, pix_func) \
84
-static void funcname(unsigned char *pd, unsigned char *mb, unsigned int pack, int pal) \
85
-TileFlipMaker_(pix_func)
86
+static unsigned funcname(unsigned char *pd, unsigned m, unsigned int pack, int pal) \
87
+TileFlipMaker_(pix_func,m)
88
89
#define pix_just_write(x) \
90
if (t) pd[x]=pal|t
91
92
93
#endif
94
95
+// AS: sprite mask bits in m shifted to bits 8-15, see DrawSpritesHiAS
96
+
97
// draw a sprite pixel (AS)
98
#define pix_as(x) \
99
- if (t & mb[x]) mb[x] = 0, pd[x] = pal | t
100
+ if (t && (m & (1<<(x+8)))) m &= ~(1<<(x+8)), pd[x] = pal | t
101
102
TileNormMakerAS(TileNormAS, pix_as)
103
TileFlipMakerAS(TileFlipAS, pix_as)
104
105
// draw a sprite pixel, process operator colors (AS)
106
#define pix_sh_as(x) \
107
- if (t & mb[x]) { \
108
- mb[x] = 0; \
109
+ if (t && (m & (1<<(x+8)))) { \
110
+ m &= ~(1<<(x+8)); \
111
if (t>=0xe) pd[x]=(pd[x]&0x3f)|(t<<6); /* c0 shadow, 80 hilight */ \
112
else pd[x] = pal | t; \
113
}
114
115
TileFlipMakerAS(TileFlipSH_AS, pix_sh_as)
116
117
#define pix_sh_as_onlyop(x) \
118
- if (t & mb[x]) { \
119
- mb[x] = 0; \
120
+ if (t && (m & (1<<(x+8)))) { \
121
+ m &= ~(1<<(x+8)); \
122
pix_sh_onlyop(x); \
123
}
124
125
126
127
// mark pixel as sprite pixel (AS)
128
#define pix_sh_as_onlymark(x) \
129
- if (t) mb[x] = 0
130
+ if (t) m &= ~(1<<(x+8))
131
132
TileNormMakerAS(TileNormAS_onlymark, pix_sh_as_onlymark)
133
TileFlipMakerAS(TileFlipAS_onlymark, pix_sh_as_onlymark)
134
135
+#ifdef FORCE
136
// forced both layer draw (through debug reg)
137
#define pix_and(x) \
138
pd[x] = (pd[x] & 0xc0) | (pd[x] & (pal | t))
139
140
TileNormMaker(TileNorm_and, pix_and)
141
TileFlipMaker(TileFlip_and, pix_and)
142
143
+// forced sprite draw (through debug reg)
144
+#define pix_sh_as_and(x) /* XXX is there S/H with forced draw? */ \
145
+ if (m & (1<<(x+8))) { \
146
+ m &= ~(1<<(x+8)); \
147
+ if (t>=0xe) pd[x]=(pd[x]&0x3f)|(t<<6); /* c0 shadow, 80 hilight */ \
148
+ else pd[x] = (pd[x] & 0xc0) | (pd[x] & (pal | t)); \
149
+ }
150
+
151
+TileNormMakerAS(TileNormSH_AS_and, pix_sh_as_and)
152
+TileFlipMakerAS(TileFlipSH_AS_and, pix_sh_as_and)
153
+#endif
154
+
155
// --------------------------------------------
156
157
#ifndef _ASM_DRAW_C
158
159
int adj = ((ts->hscroll ^ dx) >> 3) & 1;
160
cell -= adj + 1;
161
ts->cells -= adj;
162
+ PicoMem.vsram[0x3e] = PicoMem.vsram[0x3f] = plane_sh >> 16;
163
}
164
cell+=cellskip;
165
tilex+=cellskip;
166
167
//if((cell&1)==0)
168
{
169
int line,vscroll;
170
- vscroll=PicoMem.vsram[(plane_sh&1)+(cell&~1)];
171
+ vscroll=PicoMem.vsram[(plane_sh&1)+(cell&0x3e)];
172
173
// Find the line in the name table
174
line=(vscroll+scan)&ts->line&0xffff; // ts->line is really ymask ..
175
176
}
177
178
code=PicoMem.vram[ts->nametab+nametabadd+(tilex&ts->xmask)];
179
- if (code==blank) continue;
180
+ if ((code<<16|ty)==blank) continue;
181
if (code>>15) { // high priority tile
182
int cval = code | (dx<<16) | (ty<<25);
183
if(code&0x1000) cval^=7<<26;
184
185
oldcode = code;
186
// Get tile address/2:
187
addr=(code&0x7ff)<<4;
188
- if (code&0x1000) addr+=14-ty; else addr+=ty; // Y-flip
189
190
pal=((code>>9)&0x30)|((plane_sh<<5)&0x40);
191
}
192
193
- pack = *(unsigned int *)(PicoMem.vram + addr);
194
+ if (code & 0x1000) ty ^= 0xe; // Y-flip
195
+ pack = *(unsigned int *)(PicoMem.vram + addr+ty);
196
+
197
if (!pack) {
198
- blank = code;
199
+ blank = code<<16|ty;
200
continue;
201
libretro-picodrive-0~git20200112.tar.xz/pico/draw2.c -> libretro-picodrive-0~git20200716.tar.xz/pico/draw2.c
Changed
73
1
2
#define LINE_WIDTH 328
3
#endif
4
5
-static unsigned char PicoDraw2FB_[(8+320) * (8+240+8)];
6
+static unsigned char PicoDraw2FB_[(8+320) * (8+240+8) + 8];
7
8
static int HighCache2A[41*(TILE_ROWS+1)+1+1]; // caches for high layers
9
static int HighCache2B[41*(TILE_ROWS+1)+1+1];
10
11
{
12
nametab=(pvid->reg[3]&0x3e)<<9; // 32-cell mode
13
nametab_step = 1<<5;
14
+ if (!(PicoIn.opt&POPT_DIS_32C_BORDER))
15
+ scrpos += 32;
16
}
17
nametab += nametab_step*start;
18
19
20
else nametab=(pvid->reg[4]&0x07)<<12; // B
21
22
scrpos = est->Draw2FB;
23
+ if (!(pvid->reg[12]&1) && !(PicoIn.opt&POPT_DIS_32C_BORDER))
24
+ scrpos += 32;
25
scrpos+=8*LINE_WIDTH*(planestart-START_ROW);
26
27
// Get vertical scroll value:
28
29
short blank=-1; // The tile we know is blank
30
unsigned char *scrpos = est->Draw2FB, *pd = 0;
31
32
+ if (!(Pico.video.reg[12]&1) && !(PicoIn.opt&POPT_DIS_32C_BORDER))
33
+ scrpos += 32;
34
// *hcache++ = code|(dx<<16)|(trow<<27); // cache it
35
scrpos+=(*hc++)*LINE_WIDTH - START_ROW*LINE_WIDTH*8;
36
37
38
while(sy <= START_ROW*8) { sy+=8; tile+=tdeltay; height--; }
39
40
scrpos = est->Draw2FB;
41
+ if (!(Pico.video.reg[12]&1) && !(PicoIn.opt&POPT_DIS_32C_BORDER))
42
+ scrpos += 32;
43
scrpos+=(sy-START_ROW*8)*LINE_WIDTH;
44
45
for (; height > 0; height--, sy+=8, tile+=tdeltay)
46
47
int i,u,link=0;
48
unsigned int *sprites[80]; // Sprites
49
int y_min=START_ROW*8, y_max=END_ROW*8; // for a simple sprite masking
50
+ int max_sprites = Pico.video.reg[12]&1 ? 80 : 64;
51
52
table=pvid->reg[5]&0x7f;
53
if (pvid->reg[12]&1) table&=0x7e; // Lowest bit 0 in 40-cell mode
54
table<<=8; // Get sprite table address/2
55
56
- for (i=u=0; u < 80; u++)
57
+ for (i = u = 0; u < max_sprites && link < max_sprites; u++)
58
{
59
unsigned int *sprite=NULL;
60
int code, code2, sx, sy, height;
61
62
maxw = 264; maxcolc = 32;
63
}
64
65
+ // 32C border for centering? (for asm)
66
+ est->rendstatus &= ~PDRAW_BORDER_32;
67
+ if ((est->rendstatus&PDRAW_32_COLS) && !(PicoIn.opt&POPT_DIS_32C_BORDER))
68
+ est->rendstatus |= PDRAW_BORDER_32;
69
+
70
// horizontal window?
71
if ((win=pvid->reg[0x12]))
72
{
73
libretro-picodrive-0~git20200112.tar.xz/pico/draw2_arm.S -> libretro-picodrive-0~git20200716.tar.xz/pico/draw2_arm.S
Changed
76
1
2
* this is highly specialized, be careful if changing related C code!
3
*/
4
5
-#include "pico_int_o32.h"
6
+#include "pico_int_offs.h"
7
8
@ define these constants in your include file:
9
@ .equiv START_ROW, 1
10
11
12
ldr r11,[sp, #9*4] @ est
13
sub r4, r9, #(START_ROW<<24)
14
+ ldr r7, [r11, #OFS_EST_rendstatus]
15
ldr r11, [r11, #OFS_EST_Draw2FB]
16
+ tst r7, #0x100 @ H32 border mode?
17
+ addne r11, r11, #32
18
mov r4, r4, asr #24
19
mov r7, #328*8
20
mla r11, r4, r7, r11 @ scrpos+=8*328*(planestart-START_ROW);
21
22
mov r9, #0xff000000 @ r9=prevcode=-1
23
mvn r6, #0 @ r6=prevy=-1
24
25
+ ldr r7, [r1, #OFS_EST_rendstatus]
26
ldr r4, [r1, #OFS_EST_Draw2FB]
27
ldr r2, [r0], #4 @ read y offset
28
+ tst r7, #0x100 @ H32 border mode?
29
+ addne r4, r4, #32
30
mov r7, #328
31
mla r2, r7, r2, r4
32
sub r12, r2, #(328*8*START_ROW) @ r12=scrpos
33
34
35
ldr r4, [r11, #OFS_Pico_video_reg+12]
36
mov r5, #1 @ nametab_step
37
+ ldr r11, [r3, #OFS_EST_Draw2FB]
38
tst r4, #1 @ 40 cell mode?
39
andne r12, r12, #0xf000 @ 0x3c<<10
40
- andeq r12, r12, #0xf800
41
movne r5, r5, lsl #7
42
- moveq r5, r5, lsl #6 @ nametab_step
43
-
44
- and r4, r0, #0xff
45
+ bne 0f
46
+ ldr r7, [r3, #OFS_EST_rendstatus]
47
+ and r12, r12, #0xf800
48
+ mov r5, r5, lsl #6 @ nametab_step
49
+ tst r7, #0x100
50
+ addne r11, r11, #32 @ center screen in H32 mode
51
+
52
+0: and r4, r0, #0xff
53
mla r12, r5, r4, r12 @ nametab += nametab_step*start;
54
55
ldr r10, [r3, #OFS_EST_PicoMem_vram]
56
57
58
mov r9, #0xff000000 @ r9=prevcode=-1
59
60
- ldr r11, [r3, #OFS_EST_Draw2FB]
61
and r4, r0, #0xff
62
add r11, r11, #328*8
63
sub r4, r4, #START_ROW
64
65
and r3, lr, #0x6000
66
mov r3, r3, lsr #9 @ r3=pal=((code>>9)&0x30);
67
68
+ ldr r0, [r1, #OFS_EST_rendstatus]
69
ldr r11, [r1, #OFS_EST_Draw2FB]
70
ldr r10, [r1, #OFS_EST_PicoMem_vram]
71
+ tst r0, #0x100 @ H32 border mode?
72
+ addne r11, r11, #32
73
sub r1, r12, #(START_ROW*8)
74
mov r0, #328
75
mla r11, r1, r0, r11 @ scrpos+=(sy-START_ROW*8)*328;
76
libretro-picodrive-0~git20200112.tar.xz/pico/draw_arm.S -> libretro-picodrive-0~git20200716.tar.xz/pico/draw_arm.S
Changed
201
1
2
/*
3
* assembly optimized versions of most funtions from draw.c
4
* (C) notaz, 2006-2010,2017
5
+ * (C) kub, 2020
6
*
7
* This work is licensed under the terms of MAME license.
8
* See COPYING file in the top-level directory.
9
10
* this is highly specialized, be careful if changing related C code!
11
*/
12
13
-#include "pico_int_o32.h"
14
+#include "pico_int_offs.h"
15
16
.extern DrawStripInterlace
17
18
.equ PDRAW_SPRITES_MOVED, (1<<0)
19
.equ PDRAW_WND_DIFF_PRIO, (1<<1)
20
-.equ PDRAW_ACC_SPRITES, (1<<2)
21
+.equ PDRAW_PARSE_SPRITES, (1<<2)
22
.equ PDRAW_DIRTY_SPRITES, (1<<4)
23
.equ PDRAW_PLANE_HI_PRIO, (1<<6)
24
.equ PDRAW_SHHI_DONE, (1<<7)
25
26
moveq r1, #0x0007
27
movgt r1, #0x00ff @ r1=ymask=(height<<8)|0xff; ...; // Y Mask in pixels
28
29
- add r10, r10, #5
30
- cmp r10, #7
31
- subge r10, r10, #1 @ r10=shift[width] (5,6,6,7)
32
+ cmp r10, #2
33
+ addlt r10, r10, #5
34
+ moveq r10, #5
35
+ movgt r10, #7 @ r10=shift[width] (5,6,5,7)
36
37
ldr r2, [r12, #OFS_EST_DrawScanline]
38
ldr lr, [r12, #OFS_EST_PicoMem_vram]
39
40
41
mov r4, r8, lsr #8 @ pvid->reg[13]
42
mov r4, r4, lsl #10 @ htab=pvid->reg[13]<<9; (halfwords)
43
- tst r7, #2
44
- addne r4, r4, r2, lsl #2 @ htab+=DrawScanline<<1; // Offset by line
45
- tst r7, #1
46
- biceq r4, r4, #0x1f @ htab&=~0xf; // Offset by tile
47
- add r4, r4, r0, lsl #1 @ htab+=plane
48
+
49
+ ands r3, r7, #0x03
50
+ beq 0f
51
+ cmp r3, #2
52
+ mov r3, r2, lsl #2 @ htab+=DrawScanline<<1; // Offset by line
53
+ biceq r3, #0x1f @ htab&=~0xf; // Offset by tile
54
+ andlt r3, #0x1f
55
+ add r4, r4, r3
56
+0: add r4, r4, r0, lsl #1 @ htab+=plane
57
bic r4, r4, #0x00ff0000 @ just in case
58
ldrh r3, [lr, r4] @ r3=hscroll
59
60
61
bne .DrawStrip_interlace
62
63
tst r0, r0
64
- movne r7, r7, lsr #16
65
+ moveq r7, r7, lsl #16
66
+ mov r7, r7, lsr #16
67
68
@ Find the line in the name table
69
add r2, r2, r7
70
71
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
72
73
.DrawStrip_vsscroll:
74
+ tst r8, #1 @ if h40: lflags |= 0x10000
75
+ orrne r0, r0, #0x10000
76
+
77
rsb r8, r3, #0
78
mov r8, r8, lsr #3 @ r8=tilex=(-ts->hscroll)>>3
79
bic r8, r8, #0x3fc00000
80
81
tst r3, #0x08
82
subne r10,r10, #1<<16 @ cells--
83
subne r10,r10, #1<<24 @ cell-- // even more negative
84
+
85
+ add_c24 r1, lr, (OFS_PMEM_vsram-OFS_PMEM_vram)
86
+ tst r0, #0x10000 @ h40?
87
+ ldrne r3, [r1, #0x00] @ r3=vsram[0x00..0x01]
88
+ ldreq r3, [r1, #0x40] @ r3=vsram[0x20..0x21]
89
+ str r3, [r1, #0x7c] @ vsram[0x3e..0x3f]=r3
90
0:
91
tst r9, #1<<31
92
mov r3, #0
93
94
95
@ calc offset and read tileline code to r7, also calc ty
96
add_c24 r7, lr, (OFS_PMEM_vsram-OFS_PMEM_vram)
97
- add r7, r7, r10,asr #23 @ vsram + ((cell&~1)<<1)
98
- bic r7, r7, #3
99
+ and r4, r10, #0x3e000000
100
+ add r7, r7, r4, asr #23 @ vsram + ((cell&0x3e)<<1)
101
tst r10,#0x8000 @ plane1?
102
addne r7, r7, #2
103
ldrh r7, [r7] @ r7=vscroll
104
105
tst r7, #0x8000
106
bne .DrawStrip_vs_hiprio
107
108
+ orr r7, r7, r10, lsl #24 @ code | (ty << 24)
109
cmp r7, r9
110
beq .DrawStrip_vs_samecode @ we know stuff about this tile already
111
112
113
@ interlace mode 2? Sonic 2?
114
.DrawStrip_interlace:
115
tst r0, r0
116
- moveq r7, r7, lsl #21
117
- movne r7, r7, lsl #5
118
+ movne r7, r7, lsr #16
119
+ mov r7, r7, lsl #21
120
121
@ Find the line in the name table
122
add r2, r7, r2, lsl #22 @ r2=(vscroll+(DrawScanline<<1))<<21 (11 bits);
123
124
add r1, r11, r4 @ r1=pdest
125
126
movs r7, r6, lsl #16
127
- bpl .dtfc_loop @ !(code & 0x8000)
128
cmp r5, r7, lsr #16
129
beq .dtfc_samecode @ if (code==prevcode)
130
131
132
.global DrawSpritesSHi
133
134
DrawSpritesSHi:
135
- ldr r3, [r0]
136
+ ldrb r3, [r0]
137
mov r12,#0xff
138
ands r3, r3, #0x7f
139
bxeq lr
140
141
- stmfd sp!, {r1,r4-r11,lr} @ +est
142
- strb r12,[r0,#2] @ set end marker
143
- add r10,r0, #3 @ r10=HighLnSpr end
144
+ stmfd sp!, {r1,r3-r11,lr} @ +est
145
+ strb r12,[r0,#3] @ set end marker
146
+ ldrb r12,[r0,#1]
147
+ add r10,r0, #4 @ r10=HighLnSpr end
148
+ mvn r12,r12
149
+ tst r12,#0x6 @ masking in slot 1 and tile ovfl?
150
+ ldmeqfd sp!, {r1,r3-r11,pc}
151
add r10,r10,r3 @ r10=HighLnSpr end
152
153
+ ldrb r12,[r10,#0] @ width of last sprite
154
ldr r11,[r1, #OFS_EST_HighCol]
155
+ str r12,[sp, #4]
156
mov r12,#0xf
157
ldr lr, [r1, #OFS_EST_PicoMem_vram]
158
159
160
ldr r7, [sp] @ est
161
ldr r1, [r7, #OFS_EST_HighPreSpr]
162
cmp r0, #0xff
163
- ldmeqfd sp!, {r1,r4-r11,pc} @ end of list
164
+ ldmeqfd sp!, {r1,r3-r11,pc} @ end of list
165
and r0, r0, #0x7f
166
add r0, r1, r0, lsl #3
167
168
169
and r7, r7, #7
170
add r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address
171
172
+ ldr r0, [sp, #4]
173
+ add r6, r6, #1 @ inc now
174
+ cmp r0, #0 @ check width of last sprite
175
+ movne r6, r0
176
+ movne r0, #0
177
+ strne r0, [sp, #4]
178
+
179
mov r5, r5, lsl #4 @ delta<<=4; // Delta of address
180
mov r3, r4, lsr #9 @ r3=pal=((code>>9)&0x30);
181
182
- add r6, r6, #1 @ inc now
183
adds r0, r2, #0 @ mov sx to r0 and set ZV flags
184
b .dsprShi_loop_enter
185
186
187
@ time to do some real work
188
stmfd sp!, {r1,r3-r11,lr} @ +sh|prio<<1 +est
189
mov r12,#0xff
190
- strb r12,[r0,#2] @ set end marker
191
- add r10,r0, #3
192
+ strb r12,[r0,#3] @ set end marker
193
+ ldrb r12,[r0,#1]
194
+ add r10,r0 ,#4
195
+ mvn r12,r12
196
+ tst r12,#0x6 @ masking in slot 1 and tile ovfl?
197
+ ldmeqfd sp!, {r1,r3-r11,pc}
198
add r10,r10,r2 @ r10=HighLnSpr end
199
200
+ ldrb r12,[r10,#0] @ width of last sprite
201
libretro-picodrive-0~git20200112.tar.xz/pico/m68kif_cyclone.s -> libretro-picodrive-0~git20200716.tar.xz/pico/m68kif_cyclone.s
Changed
25
1
2
orrcc r0, r1, r0, lsl #16
3
bxcc lr
4
5
- stmfd sp!,{r0,r1,lr}
6
+ stmfd sp!,{r0,r1,r2,lr}
7
mov lr, pc
8
bx r1
9
mov r2, r0, lsl #16
10
- ldmia sp, {r0,r1}
11
+ ldmfd sp!, {r0,r1}
12
str r2, [sp]
13
add r0, r0, #2
14
mov lr, pc
15
bx r1
16
- ldr r1, [sp]
17
+ ldmfd sp!, {r1,lr}
18
mov r0, r0, lsl #16
19
orr r0, r1, r0, lsr #16
20
- ldmfd sp!,{r1,r2,pc}
21
+ bx lr
22
23
24
cyclone_write8: @ u32 a, u8 d
25
libretro-picodrive-0~git20200112.tar.xz/pico/memory.c -> libretro-picodrive-0~git20200716.tar.xz/pico/memory.c
Changed
134
1
2
m68k_write16_map[i] = (addr >> 1) | MAP_FLAG;
3
}
4
5
+#ifndef _ASM_MEMORY_C
6
MAKE_68K_READ8(m68k_read8, m68k_read8_map)
7
MAKE_68K_READ16(m68k_read16, m68k_read16_map)
8
MAKE_68K_READ32(m68k_read32, m68k_read16_map)
9
MAKE_68K_WRITE8(m68k_write8, m68k_write8_map)
10
MAKE_68K_WRITE16(m68k_write16, m68k_write16_map)
11
MAKE_68K_WRITE32(m68k_write32, m68k_write16_map)
12
+#endif
13
14
// -----------------------------------------------------------------
15
16
17
static void psg_write_68k(u32 d)
18
{
19
// look for volume write and update if needed
20
- if ((d & 0x90) == 0x90 && Pico.snd.psg_line < Pico.m.scanline)
21
+ if ((d & 0x90) == 0x90)
22
PsndDoPSG(Pico.m.scanline);
23
24
SN76496Write(d);
25
26
{
27
if ((d & 0x90) == 0x90) {
28
int scanline = get_scanline(1);
29
- if (Pico.snd.psg_line < scanline)
30
- PsndDoPSG(scanline);
31
+ PsndDoPSG(scanline);
32
}
33
34
SN76496Write(d);
35
36
d = EEPROM_read();
37
if (!(a & 1))
38
d >>= 8;
39
+ d &= 0xff;
40
} else
41
d = *(u8 *)(Pico.sv.data - Pico.sv.start + a);
42
elprintf(EL_SRAMIO, "sram r8 [%06x] %02x @ %06x", a, d, SekPc);
43
44
}
45
if ((a & 0x6000) == 0x4000) { // FM Sound
46
if (PicoIn.opt & POPT_EN_FM)
47
- Pico.m.status |= ym2612_write_local(a & 3, d & 0xff, 0) & 1;
48
+ ym2612_write_local(a & 3, d & 0xff, 0);
49
return;
50
}
51
// TODO: probably other VDP access too? Maybe more mirrors?
52
53
54
static void PicoWrite16_vdp(u32 a, u32 d)
55
{
56
- if ((a & 0x00f9) == 0x0010) // PSG Sound
57
+ if ((a & 0x00f9) == 0x0010) { // PSG Sound
58
psg_write_68k(d);
59
+ return;
60
+ }
61
if ((a & 0x00e0) == 0x0000) {
62
PicoVideoWrite(a, d);
63
return;
64
65
static int get_scanline(int is_from_z80)
66
{
67
if (is_from_z80) {
68
- int mclk_z80 = z80_cyclesDone() * 15;
69
+ int mclk_z80 = (z80_cyclesLeft<0 ? Pico.t.z80c_aim : z80_cyclesDone()) * 15;
70
int mclk_line = Pico.t.z80_scanline * 488 * 7;
71
while (mclk_z80 - mclk_line >= 488 * 7)
72
Pico.t.z80_scanline++, mclk_line += 488 * 7;
73
74
int xcycles = z80_cycles << 8;
75
76
/* check for overflows */
77
- if ((mode_old & 4) && xcycles > Pico.t.timer_a_next_oflow)
78
+ if ((mode_old & 4) && xcycles >= Pico.t.timer_a_next_oflow)
79
ym2612.OPN.ST.status |= 1;
80
81
- if ((mode_old & 8) && xcycles > Pico.t.timer_b_next_oflow)
82
+ if ((mode_old & 8) && xcycles >= Pico.t.timer_b_next_oflow)
83
ym2612.OPN.ST.status |= 2;
84
85
/* update timer a */
86
87
a &= 3;
88
if (a == 1 && ym2612.OPN.ST.address == 0x2a) /* DAC data */
89
{
90
- int scanline = get_scanline(is_from_z80);
91
- //elprintf(EL_STATUS, "%03i -> %03i dac w %08x z80 %i", Pico.snd.dac_line, scanline, d, is_from_z80);
92
+ int cycles = is_from_z80 ? z80_cyclesDone() : z80_cycles_from_68k();
93
+ //elprintf(EL_STATUS, "%03i dac w %08x z80 %i", cycles, d, is_from_z80);
94
ym2612.dacout = ((int)d - 0x80) << 6;
95
if (ym2612.dacen)
96
- PsndDoDAC(scanline);
97
+ PsndDoDAC(cycles);
98
return 0;
99
}
100
101
102
return 0;
103
}
104
case 0x2b: { /* DAC Sel (YM2612) */
105
- int scanline = get_scanline(is_from_z80);
106
- if (ym2612.dacen != (d & 0x80)) {
107
- ym2612.dacen = d & 0x80;
108
- Pico.snd.dac_line = scanline;
109
- }
110
+ ym2612.dacen = d & 0x80;
111
#ifdef __GP2X__
112
- if (PicoIn.opt & POPT_EXT_FM) YM2612Write_940(a, d, scanline);
113
+ if (PicoIn.opt & POPT_EXT_FM) YM2612Write_940(a, d, get_scanline(is_from_z80));
114
#endif
115
return 0;
116
}
117
118
if (PicoIn.opt & POPT_EXT_FM)
119
return YM2612Write_940(a, d, get_scanline(is_from_z80));
120
#endif
121
+ PsndDoFM(is_from_z80 ? z80_cyclesDone() : z80_cycles_from_68k());
122
return YM2612Write_(a, d);
123
}
124
125
126
static void z80_md_ym2612_write(unsigned int a, unsigned char data)
127
{
128
if (PicoIn.opt & POPT_EN_FM)
129
- Pico.m.status |= ym2612_write_local(a, data, 1) & 1;
130
+ ym2612_write_local(a, data, 1);
131
}
132
133
static void z80_md_vdp_br_write(unsigned int a, unsigned char data)
134
libretro-picodrive-0~git20200112.tar.xz/pico/memory.h -> libretro-picodrive-0~git20200716.tar.xz/pico/memory.h
Changed
33
1
2
3
#include "pico_port.h"
4
5
-#ifndef UTYPES_DEFINED
6
-typedef unsigned char u8;
7
-typedef unsigned short u16;
8
-typedef unsigned int u32;
9
-#endif
10
-typedef uintptr_t uptr; // unsigned pointer-sized int
11
-
12
#define M68K_MEM_SHIFT 16
13
// minimum size we can map
14
#define M68K_BANK_SIZE (1 << M68K_MEM_SHIFT)
15
16
17
extern u32 m68k_read8(u32 a);
18
extern u32 m68k_read16(u32 a);
19
+extern u32 m68k_read32(u32 a);
20
extern void m68k_write8(u32 a, u8 d);
21
extern void m68k_write16(u32 a, u16 d);
22
+extern void m68k_write32(u32 a, u32 d);
23
+
24
+extern u32 s68k_read8(u32 a);
25
+extern u32 s68k_read16(u32 a);
26
+extern u32 s68k_read32(u32 a);
27
+extern void s68k_write8(u32 a, u8 d);
28
+extern void s68k_write16(u32 a, u16 d);
29
+extern void s68k_write32(u32 a, u32 d);
30
31
// z80
32
#define Z80_MEM_SHIFT 13
33
libretro-picodrive-0~git20200112.tar.xz/pico/memory_amips.S -> libretro-picodrive-0~git20200716.tar.xz/pico/memory_amips.S
Changed
10
1
2
3
# OUT OF DATE
4
5
-#include "pico_int_o32.h"
6
+#include "pico_int_offs.h"
7
8
.set noreorder
9
.set noat
10
libretro-picodrive-0~git20200112.tar.xz/pico/memory_arm.S -> libretro-picodrive-0~git20200716.tar.xz/pico/memory_arm.S
Changed
186
1
2
/*
3
* PicoDrive
4
* (C) notaz, 2006-2009
5
+ * (C) kub, 2019
6
*
7
* This work is licensed under the terms of MAME license.
8
* See COPYING file in the top-level directory.
9
*/
10
11
-#include "pico_int_o32.h"
12
+#include "arm_features.h"
13
+#include "pico_int_offs.h"
14
15
.equ SRR_MAPPED, (1 << 0)
16
.equ SRR_READONLY, (1 << 1)
17
18
.global PicoWrite8_io
19
.global PicoWrite16_io
20
21
+ PIC_LDR_INIT()
22
+
23
PicoRead8_sram: @ u32 a
24
- ldr r3, =Pico
25
+ PIC_LDR(r3, r1, Pico)
26
ldr r1, [r3, #OFS_Pico_sv_end]
27
cmp r0, r1
28
bgt m_read8_nosram
29
30
ldmfd sp!,{r1,lr}
31
tst r1, #1
32
moveq r0, r0, lsr #8
33
+ and r0, r0, #0xff
34
bx lr
35
36
37
38
cmp r2, #0x1000
39
bne PicoRead8_32x
40
41
- ldr r3, =Pico
42
+ PIC_LDR(r3, r1, Pico)
43
mov r1, r0
44
ldr r0, [r3, #OFS_Pico_m_rotate]
45
add r0, r0, #1
46
47
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
48
49
PicoRead16_sram: @ u32 a, u32 d
50
- ldr r3, =Pico
51
+ PIC_LDR(r3, r1, Pico)
52
ldr r1, [r3, #OFS_Pico_sv_end]
53
cmp r0, r1
54
bgt m_read16_nosram
55
56
cmp r2, #0x1000
57
bne PicoRead16_32x
58
59
- ldr r3, =Pico
60
+ PIC_LDR(r3, r2, Pico)
61
and r2, r0, #0xff00
62
ldr r0, [r3, #OFS_Pico_m_rotate]
63
add r0, r0, #1
64
65
eor r2, r2, #0x003000
66
eors r2, r2, #0x0000f1
67
bne PicoWrite8_32x
68
- ldr r3, =Pico
69
+ PIC_LDR(r3, r2, Pico)
70
ldrb r2, [r3, #OFS_Pico_m_sram_reg]
71
and r1, r1, #(SRR_MAPPED|SRR_READONLY)
72
bic r2, r2, #(SRR_MAPPED|SRR_READONLY)
73
74
eor r2, r2, #0x003000
75
eors r2, r2, #0x0000f0
76
bne PicoWrite16_32x
77
- ldr r3, =Pico
78
+ PIC_LDR(r3, r2, Pico)
79
ldrb r2, [r3, #OFS_Pico_m_sram_reg]
80
and r1, r1, #(SRR_MAPPED|SRR_READONLY)
81
bic r2, r2, #(SRR_MAPPED|SRR_READONLY)
82
83
strb r2, [r3, #OFS_Pico_m_sram_reg]
84
bx lr
85
86
+.global m68k_read8
87
+.global m68k_read16
88
+.global m68k_read32
89
+.global m68k_write8
90
+.global m68k_write16
91
+.global m68k_write32
92
+
93
+m68k_read8:
94
+ PIC_LDR(r3, r2, m68k_read8_map)
95
+ bic r0, r0, #0xff000000
96
+ mov r2, r0, lsr #16
97
+ ldr r3, [r3, r2, lsl #2]
98
+ eor r2, r0, #1
99
+ movs r3, r3, lsl #1
100
+ ldrccb r0, [r3, r2]
101
+ bxcc lr
102
+ bx r3
103
+
104
+m68k_read16:
105
+ PIC_LDR(r3, r2, m68k_read16_map)
106
+ bic r0, r0, #0xff000000
107
+ mov r2, r0, lsr #16
108
+ ldr r3, [r3, r2, lsl #2]
109
+ bic r0, r0, #1
110
+ movs r3, r3, lsl #1
111
+ ldrcch r0, [r3, r0]
112
+ bxcc lr
113
+ bx r3
114
+
115
+m68k_read32:
116
+ PIC_LDR(r3, r2, m68k_read16_map)
117
+ bic r0, r0, #0xff000000
118
+ mov r2, r0, lsr #16
119
+ ldr r3, [r3, r2, lsl #2]
120
+ bic r0, r0, #1
121
+ movs r3, r3, lsl #1
122
+ ldrcch r1, [r3, r0]!
123
+ ldrcch r0, [r3, #2]
124
+ orrcc r0, r0, r1, lsl #16
125
+ bxcc lr
126
+
127
+ stmfd sp!, {r0, r3, r4, lr}
128
+ mov lr, pc
129
+ bx r3
130
+ ldmfd sp!, {r1, r3}
131
+ str r0, [sp]
132
+ add r0, r1, #2
133
+ mov lr, pc
134
+ bx r3
135
+ ldmfd sp!, {r1, lr}
136
+ mov r0, r0, lsl #16
137
+ mov r1, r1, lsl #16
138
+ orr r0, r1, r0, lsr #16
139
+ bx lr
140
+
141
+m68k_write8:
142
+ PIC_LDR(r3, r2, m68k_write8_map)
143
+ bic r0, r0, #0xff000000
144
+ mov r2, r0, lsr #16
145
+ ldr r3, [r3, r2, lsl #2]
146
+ eor r2, r0, #1
147
+ movs r3, r3, lsl #1
148
+ strccb r1, [r3, r2]
149
+ bxcc lr
150
+ bx r3
151
+
152
+m68k_write16:
153
+ PIC_LDR(r3, r2, m68k_write16_map)
154
+ bic r0, r0, #0xff000000
155
+ mov r2, r0, lsr #16
156
+ ldr r3, [r3, r2, lsl #2]
157
+ bic r0, r0, #1
158
+ movs r3, r3, lsl #1
159
+ strcch r1, [r3, r0]
160
+ bxcc lr
161
+ bx r3
162
+
163
+m68k_write32:
164
+ PIC_LDR(r3, r2, m68k_write16_map)
165
+ bic r0, r0, #0xff000000
166
+ mov r2, r0, lsr #16
167
+ ldr r3, [r3, r2, lsl #2]
168
+ bic r0, r0, #1
169
+ movs r3, r3, lsl #1
170
+ movcc r2, r1, lsr #16
171
+ strcch r2, [r3, r0]!
172
+ strcch r1, [r3, #2]
173
+ bxcc lr
174
+
175
+ stmfd sp!, {r0, r1, r3, lr}
176
+ mov r1, r1, lsr #16
177
+ mov lr, pc
178
+ bx r3
179
+ ldmfd sp!, {r0, r1, r3, lr}
180
+ add r0, r0, #2
181
+ bx r3
182
+
183
.pool
184
185
@ vim:filetype=armasm
186
libretro-picodrive-0~git20200112.tar.xz/pico/misc.c -> libretro-picodrive-0~git20200716.tar.xz/pico/misc.c
Changed
201
1
2
/*
3
* rarely used EEPROM code
4
* (C) notaz, 2006-2008
5
+ * (C) kub, 2020
6
*
7
* This work is licensed under the terms of MAME license.
8
* See COPYING file in the top-level directory.
9
10
11
#include "pico_int.h"
12
13
-// H-counter table for hvcounter reads in 40col mode
14
-// based on Gens code
15
+// H-counter table for hvcounter reads in 40col mode, starting at HINT
16
const unsigned char hcounts_40[] = {
17
-0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,
18
-0x0e,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x13,0x14,
19
-0x14,0x15,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,
20
-0x1b,0x1b,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1f,0x1f,0x20,0x20,0x20,0x21,0x21,
21
-0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x25,0x25,0x25,0x26,0x26,0x27,0x27,0x28,0x28,
22
-0x28,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2f,
23
-0x2f,0x30,0x30,0x30,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x34,0x34,0x35,0x35,0x35,
24
-0x36,0x36,0x37,0x37,0x38,0x38,0x38,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3c,0x3c,
25
-0x3d,0x3d,0x3d,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x41,0x41,0x42,0x42,0x42,0x43,
26
-0x43,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x47,0x47,0x47,0x48,0x48,0x49,0x49,0x4a,
27
-0x4a,0x4a,0x4b,0x4b,0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,
28
-0x51,0x51,0x52,0x52,0x52,0x53,0x53,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x57,0x57,
29
-0x57,0x58,0x58,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5e,
30
-0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x64,0x64,0x64,
31
-0x65,0x65,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,
32
-0x6c,0x6c,0x6c,0x6d,0x6d,0x6e,0x6e,0x6f,0x6f,0x6f,0x70,0x70,0x71,0x71,0x71,0x72,
33
-0x72,0x73,0x73,0x74,0x74,0x74,0x75,0x75,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x79,
34
-0x79,0x79,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7e,0x7e,0x7f,0x7f,0x7f,
35
-0x80,0x80,0x81,0x81,0x81,0x82,0x82,0x83,0x83,0x84,0x84,0x84,0x85,0x85,0x86,0x86,
36
-0x86,0x87,0x87,0x88,0x88,0x89,0x89,0x89,0x8a,0x8a,0x8b,0x8b,0x8c,0x8c,0x8c,0x8d,
37
-0x8d,0x8e,0x8e,0x8e,0x8f,0x8f,0x90,0x90,0x91,0x91,0x91,0x92,0x92,0x93,0x93,0x94,
38
-0x94,0x94,0x95,0x95,0x96,0x96,0x96,0x97,0x97,0x98,0x98,0x99,0x99,0x99,0x9a,0x9a,
39
-0x9b,0x9b,0x9b,0x9c,0x9c,0x9d,0x9d,0x9e,0x9e,0x9e,0x9f,0x9f,0xa0,0xa0,0xa1,0xa1,
40
-0xa1,0xa2,0xa2,0xa3,0xa3,0xa3,0xa4,0xa4,0xa5,0xa5,0xa6,0xa6,0xa6,0xa7,0xa7,0xa8,
41
-0xa8,0xa9,0xa9,0xa9,0xaa,0xaa,0xab,0xab,0xab,0xac,0xac,0xad,0xad,0xae,0xae,0xae,
42
-0xaf,0xaf,0xb0,0xb0,
43
-0xe4,0xe4,0xe4,0xe5,0xe5,0xe6,0xe6,0xe6,0xe7,0xe7,0xe8,0xe8,0xe9,0xe9,0xe9,0xea,
44
-0xea,0xeb,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,
45
-0xf1,0xf1,0xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,
46
-0xf8,0xf8,0xf9,0xf9,0xf9,0xfa,0xfa,0xfb,0xfb,0xfb,0xfc,0xfc,0xfd,0xfd,0xfe,0xfe,
47
-0xfe,0xff,0xff,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x05,
48
-0x05,0x06,0x06,0x06,
49
-0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,
50
-0x0e,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x10,
51
+0xa5,0xa6,0xa7,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xae,0xaf,0xb0,0xb1,0xb2,
52
+0xb3,0xb4,0xb5,0xb5,0xe4,0xe5,0xe6,0xe7,0xe8,0xe8,0xe9,0xea,0xea,0xeb,0xec,0xed,
53
+0xed,0xee,0xef,0xef,0xf0,0xf1,0xf2,0xf2,0xf3,0xf4,0xf4,0xf5,0xf6,0xf7,0xf7,0xf8,
54
+0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0x00,0x01,0x02,0x03,0x04,0x04,0x05,0x06,
55
+0x07,0x08,0x09,0x0a,0x0b,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x12,0x13,0x14,
56
+0x15,0x16,0x17,0x18,0x19,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x20,0x21,0x22,
57
+0x23,0x24,0x25,0x26,0x27,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2e,0x2f,0x30,
58
+0x31,0x32,0x33,0x34,0x35,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3c,0x3d,0x3e,
59
+0x3f,0x40,0x41,0x42,0x43,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4a,0x4b,0x4c,
60
+0x4d,0x4e,0x4f,0x50,0x51,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x58,0x59,0x5a,
61
+0x5b,0x5c,0x5d,0x5e,0x5f,0x5f,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x66,0x67,0x68,
62
+0x69,0x6a,0x6b,0x6c,0x6d,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x74,0x75,0x76,
63
+0x77,0x78,0x79,0x7a,0x7b,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x81,0x82,0x82,0x83,0x84,
64
+0x85,0x86,0x87,0x88,0x89,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x90,0x91,0x92,
65
+0x93,0x94,0x95,0x96,0x97,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9e,0x9f,0xa0,
66
+0xa1,0xa2,0xa3,0xa4,0xa5,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xac,0xad,0xae,
67
};
68
69
-// H-counter table for hvcounter reads in 32col mode
70
+// H-counter table for hvcounter reads in 32col mode, starting at HINT
71
const unsigned char hcounts_32[] = {
72
-0x05,0x05,0x05,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x09,0x0a,0x0a,
73
-0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x0f,0x10,
74
-0x10,0x10,0x11,0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x13,0x14,0x14,0x14,0x15,0x15,
75
-0x15,0x16,0x16,0x17,0x17,0x17,0x18,0x18,0x18,0x19,0x19,0x19,0x1a,0x1a,0x1a,0x1b,
76
-0x1b,0x1b,0x1c,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1f,0x1f,0x1f,0x20,0x20,0x20,
77
-0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x26,0x26,
78
-0x26,0x27,0x27,0x27,0x28,0x28,0x28,0x29,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,
79
-0x2c,0x2c,0x2c,0x2d,0x2d,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x30,0x31,0x31,
80
-0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x34,0x34,0x34,0x35,0x35,0x36,0x36,0x36,0x37,
81
-0x37,0x37,0x38,0x38,0x38,0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3b,0x3c,0x3c,
82
-0x3d,0x3d,0x3d,0x3e,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40,0x41,0x41,0x41,0x42,
83
-0x42,0x42,0x43,0x43,0x43,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x46,0x47,0x47,0x47,
84
-0x48,0x48,0x48,0x49,0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b,0x4c,0x4c,0x4d,0x4d,
85
-0x4d,0x4e,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,0x50,0x51,0x51,0x51,0x52,0x52,0x52,
86
-0x53,0x53,0x53,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57,0x57,0x58,0x58,
87
-0x58,0x59,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5e,
88
-0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x60,0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63,
89
-0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x68,0x69,
90
-0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,0x6c,0x6c,0x6c,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,
91
-0x6f,0x6f,0x6f,0x70,0x70,0x70,0x71,0x71,0x71,0x72,0x72,0x72,0x73,0x73,0x74,0x74,
92
-0x74,0x75,0x75,0x75,0x76,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79,0x79,0x79,
93
-0x7a,0x7a,0x7b,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,
94
-0x7f,0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x82,0x83,0x83,0x83,0x84,0x84,0x84,0x85,
95
-0x85,0x85,0x86,0x86,0x86,0x87,0x87,0x87,0x88,0x88,0x88,0x89,0x89,0x89,0x8a,0x8a,
96
-0x8b,0x8b,0x8b,0x8c,0x8c,0x8c,0x8d,0x8d,0x8d,0x8e,0x8e,0x8e,0x8f,0x8f,0x8f,0x90,
97
-0x90,0x90,0x91,0x91,
98
-0xe8,0xe8,0xe8,0xe9,0xe9,0xe9,0xea,0xea,0xea,0xeb,0xeb,0xeb,0xec,0xec,0xec,0xed,
99
-0xed,0xed,0xee,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf0,0xf1,0xf1,0xf1,0xf2,0xf2,0xf2,
100
-0xf3,0xf3,0xf3,0xf4,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf8,0xf8,
101
-0xf8,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,
102
-0xfe,0xfe,0xfe,0xff,0xff,0x00,0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,
103
-0x03,0x04,0x04,0x04,
104
-0x05,0x05,0x05,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x09,0x0a,0x0a,
105
-0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,
106
+0x85,0x86,0x86,0x87,0x88,0x88,0x89,0x8a,0x8a,0x8b,0x8c,0x8d,0x8d,0x8e,0x8f,0x8f,
107
+0x90,0x91,0x91,0x92,0x93,0xe9,0xe9,0xea,0xeb,0xeb,0xec,0xed,0xed,0xee,0xef,0xf0,
108
+0xf0,0xf1,0xf2,0xf2,0xf3,0xf4,0xf4,0xf5,0xf6,0xf7,0xf7,0xf8,0xf9,0xf9,0xfa,0xfb,
109
+0xfb,0xfc,0xfd,0xfe,0xfe,0xff,0x00,0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x05,0x06,
110
+0x07,0x07,0x08,0x09,0x09,0x0a,0x0b,0x0c,0x0c,0x0d,0x0e,0x0e,0x0f,0x10,0x10,0x11,
111
+0x12,0x13,0x13,0x14,0x15,0x15,0x16,0x17,0x17,0x18,0x19,0x1a,0x1a,0x1b,0x1c,0x1c,
112
+0x1d,0x1e,0x1e,0x1f,0x20,0x21,0x21,0x22,0x23,0x23,0x24,0x25,0x25,0x26,0x27,0x28,
113
+0x28,0x29,0x2a,0x2a,0x2b,0x2c,0x2c,0x2d,0x2e,0x2f,0x2f,0x30,0x31,0x31,0x32,0x33,
114
+0x33,0x34,0x35,0x36,0x36,0x37,0x38,0x38,0x39,0x3a,0x3a,0x3b,0x3c,0x3d,0x3d,0x3e,
115
+0x3f,0x3f,0x40,0x41,0x41,0x42,0x43,0x44,0x44,0x45,0x46,0x46,0x47,0x48,0x48,0x49,
116
+0x4a,0x4b,0x4b,0x4c,0x4d,0x4d,0x4e,0x4f,0x4f,0x50,0x51,0x52,0x52,0x53,0x54,0x54,
117
+0x55,0x56,0x56,0x57,0x58,0x59,0x59,0x5a,0x5b,0x5b,0x5c,0x5d,0x5d,0x5e,0x5f,0x60,
118
+0x60,0x61,0x62,0x62,0x63,0x64,0x64,0x65,0x66,0x67,0x67,0x68,0x69,0x69,0x6a,0x6b,
119
+0x6b,0x6c,0x6d,0x6e,0x6e,0x6f,0x70,0x70,0x71,0x72,0x72,0x73,0x74,0x75,0x75,0x76,
120
+0x77,0x77,0x78,0x79,0x79,0x7a,0x7b,0x7c,0x7c,0x7d,0x7e,0x7e,0x7f,0x80,0x80,0x81,
121
+0x82,0x83,0x83,0x84,0x85,0x85,0x86,0x87,0x87,0x88,0x89,0x8a,0x8a,0x8b,0x8c,0x8c,
122
};
123
124
+// VDP transfer slots for blanked and active display in 32col and 40col mode.
125
+// 1 slot is 488/171 = 2.8538 68k cycles in h32, and 488/210 = 2.3238 in h40
126
+// In blanked display, all slots but 5(h32) / 6(h40) are usable for transfers,
127
+// in active display only 16(h32) / 18(h40) slots can be used.
128
+
129
+// XXX inactive tables by slot#=cycles*maxslot#/488. should be through hv tables
130
+// VDP transfer slots in inactive (blanked) display 32col mode.
131
+// refresh slots: 250, 26, 58, 90, 122 -> 32, 64, 96, 128, 160
132
+const unsigned char vdpcyc2sl_32_bl[] = { // 68k cycles/2 to slot #
133
+// 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30
134
+ 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10,
135
+ 10, 11, 12, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 19, 20, 21,
136
+ 21, 22, 23, 23, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 31,
137
+ 32, 33, 34, 34, 35, 36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 42,
138
+ 43, 44, 44, 45, 46, 46, 47, 48, 48, 49, 50, 51, 51, 52, 53, 53,
139
+ 54, 55, 55, 56, 57, 57, 58, 59, 59, 60, 61, 61, 62, 63, 63, 64,
140
+ 65, 65, 66, 67, 68, 68, 69, 70, 70, 71, 72, 72, 73, 74, 74, 75,
141
+ 76, 76, 77, 78, 78, 79, 80, 80, 81, 82, 83, 83, 84, 85, 85, 86,
142
+ 87, 87, 88, 89, 89, 90, 91, 91, 92, 93, 93, 94, 95, 95, 96, 97,
143
+ 97, 98, 99,100,100,101,102,102,103,104,104,105,106,106,107,108,
144
+ 108,109,110,110,111,112,112,113,114,114,115,116,117,117,118,119,
145
+ 119,120,121,121,122,123,123,124,125,125,126,127,127,128,129,129,
146
+ 130,131,131,132,133,134,134,135,136,136,137,138,138,139,140,140,
147
+ 141,142,142,143,144,144,145,146,146,147,148,148,149,150,151,151,
148
+ 152,153,153,154,155,155,156,157,157,158,159,159,160,161,161,162,
149
+ 163,163,164,165,166,166,167,168,168,169,170,170,171,172,172,173,
150
+};
151
+// VDP transfer slots in inactive (blanked) display 40col mode.
152
+// refresh slots: 250, 26, 58, 90, 122, 154 -> 40, 72, 104, 136, 168, 200
153
+const unsigned char vdpcyc2sl_40_bl[] = { // 68k cycles/2 to slot #
154
+// 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30
155
+ 0, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 10, 11, 12,
156
+ 13, 14, 15, 15, 16, 17, 18, 19, 20, 20, 21, 22, 23, 24, 25, 25,
157
+ 26, 27, 28, 29, 30, 30, 31, 32, 33, 34, 35, 35, 36, 37, 38, 39,
158
+ 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 51, 52,
159
+ 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 61, 62, 63, 64, 65, 66,
160
+ 66, 67, 68, 69, 70, 71, 71, 72, 73, 74, 75, 76, 76, 77, 78, 79,
161
+ 80, 81, 81, 82, 83, 84, 85, 86, 86, 87, 88, 89, 90, 91, 91, 92,
162
+ 93, 94, 95, 96, 96, 97, 98, 99,100,101,102,102,103,104,105,106,
163
+ 107,107,108,109,110,111,112,112,113,114,115,116,117,117,118,119,
164
+ 120,121,122,122,123,124,125,126,127,127,128,129,130,131,132,132,
165
+ 133,134,135,136,137,137,138,139,140,141,142,142,143,144,145,146,
166
+ 147,147,148,149,150,151,152,153,153,154,155,156,157,158,158,159,
167
+ 160,161,162,163,163,164,165,166,167,168,168,169,170,171,172,173,
168
+ 173,174,175,176,177,178,178,179,180,181,182,183,183,184,185,186,
169
+ 187,188,188,189,190,191,192,193,193,194,195,196,197,198,198,199,
170
+ 200,201,202,203,204,204,205,206,207,208,209,209,210,211,212,213,
171
+};
172
+// VDP transfer slots in active display 32col mode. Transfer slots (Hint=0):
173
+// 11,25,40,48,56,72,80,88,104,112,120,136,144,152,167,168
174
+const unsigned char vdpcyc2sl_32[] = { // 68k cycles/2 to slot #
175
+// 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30
176
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
177
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
178
+ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
179
+ 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
180
+ 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
181
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
182
+ 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
183
+ 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
184
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
185
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10,
186
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11,
187
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
188
+ 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13,
189
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14,
190
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15,
191
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
192
+};
193
+// VDP transfer slots in active display 40col mode. Transfer slots (Hint=0):
194
+// 21,47,55,63,79,87,95,111,119,127,143,151,159,175,183,191,206,207
195
+const unsigned char vdpcyc2sl_40[] = { // 68k cycles/2 to slot #
196
+// 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30
197
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0
198
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 32
199
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64
200
+ 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 96
201
libretro-picodrive-0~git20200112.tar.xz/pico/pico.c -> libretro-picodrive-0~git20200716.tar.xz/pico/pico.c
Changed
97
1
2
3
memset(&Pico.video,0,sizeof(Pico.video));
4
memset(&Pico.m,0,sizeof(Pico.m));
5
+ memset(&Pico.t,0,sizeof(Pico.t));
6
7
Pico.video.pending_ints=0;
8
z80_reset();
9
10
Pico.video.reg[0] = Pico.video.reg[1] = 0x04;
11
Pico.video.reg[0xc] = 0x81;
12
Pico.video.reg[0xf] = 0x02;
13
+ PicoVideoFIFOMode(0, 1);
14
15
if (PicoIn.AHW & PAHW_MCD)
16
PicoPowerMCD();
17
18
PsndReset(); // pal must be known here
19
20
// create an empty "dma" to cause 68k exec start at random frame location
21
- if (Pico.m.dma_xfers == 0 && !(PicoIn.opt & POPT_DIS_VDP_FIFO))
22
- Pico.m.dma_xfers = rand() & 0x1fff;
23
+ PicoVideoFIFOWrite(rand() & 0x1fff, 0, 0, PVS_CPURD);
24
25
SekFinishIdleDet();
26
27
28
rendstatus_old = -1;
29
}
30
31
-// this table is wrong and should be removed
32
-// keeping it for now to compensate wrong timing elswhere, mainly for Outrunners
33
-static const int dma_timings[] = {
34
- 83, 166, 83, 83, // vblank: 32cell: dma2vram dma2[vs|c]ram vram_fill vram_copy
35
- 102, 204, 102, 102, // vblank: 40cell:
36
- 8, 16, 8, 8, // active: 32cell:
37
- 17, 18, 9, 9 // ...
38
-};
39
-
40
-static const int dma_bsycles[] = {
41
- (488<<8)/83, (488<<8)/166, (488<<8)/83, (488<<8)/83,
42
- (488<<8)/102, (488<<8)/204, (488<<8)/102, (488<<8)/102,
43
- (488<<8)/8, (488<<8)/16, (488<<8)/8, (488<<8)/8,
44
- (488<<8)/9, (488<<8)/18, (488<<8)/9, (488<<8)/9
45
-};
46
-
47
-// grossly inaccurate.. FIXME FIXXXMEE
48
-PICO_INTERNAL int CheckDMA(void)
49
-{
50
- int burn = 0, xfers_can, dma_op = Pico.video.reg[0x17]>>6; // see gens for 00 and 01 modes
51
- int xfers = Pico.m.dma_xfers;
52
- int dma_op1;
53
-
54
- if(!(dma_op&2)) dma_op = (Pico.video.type==1) ? 0 : 1; // setting dma_timings offset here according to Gens
55
- dma_op1 = dma_op;
56
- if(Pico.video.reg[12] & 1) dma_op |= 4; // 40 cell mode?
57
- if(!(Pico.video.status&8)&&(Pico.video.reg[1]&0x40)) dma_op|=8; // active display?
58
- xfers_can = dma_timings[dma_op];
59
- if(xfers <= xfers_can)
60
- {
61
- Pico.video.status &= ~SR_DMA;
62
- if (!(dma_op & 2))
63
- burn = xfers * dma_bsycles[dma_op] >> 8; // have to be approximate because can't afford division..
64
- Pico.m.dma_xfers = 0;
65
- } else {
66
- if(!(dma_op&2)) burn = 488;
67
- Pico.m.dma_xfers -= xfers_can;
68
- }
69
-
70
- elprintf(EL_VDPDMA, "~Dma %i op=%i can=%i burn=%i [%u]",
71
- Pico.m.dma_xfers, dma_op1, xfers_can, burn, SekCyclesDone());
72
- //dprintf("~aim: %i, cnt: %i", Pico.t.m68c_aim, Pico.t.m68c_cnt);
73
- return burn;
74
-}
75
-
76
#include "pico_cmn.c"
77
78
/* sync z80 to 68k */
79
80
goto end;
81
}
82
83
- //if(Pico.video.reg[12]&0x2) Pico.video.status ^= 0x10; // change odd bit in interlace mode
84
+ //if(Pico.video.reg[12]&0x2) Pico.video.status ^= SR_ODD; // change odd bit in interlace mode
85
86
PicoFrameStart();
87
PicoFrameHints();
88
89
{
90
if (!(PicoIn.AHW & PAHW_SMS)) {
91
PicoFrameStart();
92
- PicoDrawSync(223, 0);
93
+ PicoDrawSync(Pico.m.pal?239:223, 0);
94
} else {
95
PicoFrameDrawOnlyMS();
96
}
97
libretro-picodrive-0~git20200112.tar.xz/pico/pico.h -> libretro-picodrive-0~git20200716.tar.xz/pico/pico.h
Changed
32
1
2
#define POPT_EN_DRC (1<<17)
3
#define POPT_DIS_SPRITE_LIM (1<<18)
4
#define POPT_DIS_IDLE_DET (1<<19)
5
-#define POPT_EN_32X (1<<20)
6
+#define POPT_EN_32X (1<<20) // x0 0000
7
#define POPT_EN_PWM (1<<21)
8
+#define POPT_PWM_IRQ_OPT (1<<22)
9
+#define POPT_DIS_FM_SSGEG (1<<23)
10
11
#define PAHW_MCD (1<<0)
12
#define PAHW_32X (1<<1)
13
14
#endif
15
void PicoDoHighPal555(int sh, int line, struct PicoEState *est);
16
// internals
17
-#define PDRAW_SPRITES_MOVED (1<<0) // (asm)
18
+#define PDRAW_SPRITES_MOVED (1<<0) // SAT address modified
19
#define PDRAW_WND_DIFF_PRIO (1<<1) // not all window tiles use same priority
20
+#define PDRAW_PARSE_SPRITES (1<<2) // SAT needs parsing
21
#define PDRAW_INTERLACE (1<<3)
22
-#define PDRAW_DIRTY_SPRITES (1<<4) // (asm)
23
+#define PDRAW_DIRTY_SPRITES (1<<4) // SAT modified
24
#define PDRAW_SONIC_MODE (1<<5) // mid-frame palette changes for 8bit renderer
25
#define PDRAW_PLANE_HI_PRIO (1<<6) // have layer with all hi prio tiles (mk3)
26
#define PDRAW_SHHI_DONE (1<<7) // layer sh/hi already processed
27
#define PDRAW_32_COLS (1<<8) // 32 column mode
28
+#define PDRAW_BORDER_32 (1<<9) // center H32 in buffer (32 px border)
29
extern int rendstatus_old;
30
extern int rendlines;
31
32
libretro-picodrive-0~git20200112.tar.xz/pico/pico_cmn.c -> libretro-picodrive-0~git20200716.tar.xz/pico/pico_cmn.c
Changed
201
1
2
#endif
3
4
// sync m68k to Pico.t.m68c_aim
5
-static void SekSyncM68k(void)
6
+static void SekExecM68k(int cyc_do)
7
{
8
- int cyc_do;
9
- pprof_start(m68k);
10
- pevt_log_m68k_o(EVT_RUN_START);
11
-
12
- while ((cyc_do = Pico.t.m68c_aim - Pico.t.m68c_cnt) > 0) {
13
- Pico.t.m68c_cnt += cyc_do;
14
+ Pico.t.m68c_cnt += cyc_do;
15
16
#if defined(EMU_C68K)
17
- PicoCpuCM68k.cycles = cyc_do;
18
- CycloneRun(&PicoCpuCM68k);
19
- Pico.t.m68c_cnt -= PicoCpuCM68k.cycles;
20
+ PicoCpuCM68k.cycles = cyc_do;
21
+ CycloneRun(&PicoCpuCM68k);
22
+ Pico.t.m68c_cnt -= PicoCpuCM68k.cycles;
23
#elif defined(EMU_M68K)
24
- Pico.t.m68c_cnt += m68k_execute(cyc_do) - cyc_do;
25
+ Pico.t.m68c_cnt += m68k_execute(cyc_do) - cyc_do;
26
#elif defined(EMU_F68K)
27
- Pico.t.m68c_cnt += fm68k_emulate(&PicoCpuFM68k, cyc_do, 0) - cyc_do;
28
+ Pico.t.m68c_cnt += fm68k_emulate(&PicoCpuFM68k, cyc_do, 0) - cyc_do;
29
#endif
30
- }
31
-
32
SekCyclesLeft = 0;
33
+}
34
+
35
+static void SekSyncM68k(void)
36
+{
37
+ int cyc_do;
38
+ pprof_start(m68k);
39
+ pevt_log_m68k_o(EVT_RUN_START);
40
+
41
+ while ((cyc_do = Pico.t.m68c_aim - Pico.t.m68c_cnt) > 0)
42
+ SekExecM68k(cyc_do);
43
44
SekTrace(0);
45
pevt_log_m68k_o(EVT_RUN_END);
46
47
static __inline void SekRunM68k(int cyc)
48
{
49
Pico.t.m68c_aim += cyc;
50
+ Pico.t.m68c_cnt += cyc >> 6; // refresh slowdowns
51
cyc = Pico.t.m68c_aim - Pico.t.m68c_cnt;
52
if (cyc <= 0)
53
return;
54
- Pico.t.m68c_cnt += cyc >> 6; // refresh slowdowns
55
SekSyncM68k();
56
}
57
58
59
}
60
}
61
62
-static void do_timing_hacks_as(struct PicoVideo *pv, int vdp_slots)
63
+static void do_timing_hacks_end(struct PicoVideo *pv)
64
{
65
- pv->lwrite_cnt += vdp_slots - Pico.m.dma_xfers * 2; // wrong *2
66
- if (pv->lwrite_cnt > vdp_slots)
67
- pv->lwrite_cnt = vdp_slots;
68
- else if (pv->lwrite_cnt < 0)
69
- pv->lwrite_cnt = 0;
70
- if (Pico.m.dma_xfers)
71
- SekCyclesBurn(CheckDMA());
72
+ PicoVideoFIFOSync(488);
73
}
74
75
-static void do_timing_hacks_vb(void)
76
+static void do_timing_hacks_start(struct PicoVideo *pv)
77
{
78
- if (unlikely(Pico.m.dma_xfers))
79
- SekCyclesBurn(CheckDMA());
80
+ SekCyclesBurn(PicoVideoFIFOHint()); // prolong cpu HOLD if necessary
81
}
82
83
static int PicoFrameHints(void)
84
{
85
struct PicoVideo *pv = &Pico.video;
86
- int line_sample = Pico.m.pal ? 68 : 93;
87
- int vdp_slots = (Pico.video.reg[12] & 1) ? 18 : 16;
88
int lines, y, lines_vis, skip;
89
int vcnt_wrap, vcnt_adj;
90
unsigned int cycles;
91
92
}
93
}
94
95
- // get samples from sound chips
96
- if ((y == 224 || y == line_sample) && PicoIn.sndOut)
97
- {
98
- cycles = SekCyclesDone();
99
-
100
- if (Pico.m.z80Run && !Pico.m.z80_reset && (PicoIn.opt&POPT_EN_Z80))
101
- PicoSyncZ80(cycles);
102
-#ifdef PICO_CD
103
- if (PicoIn.AHW & PAHW_MCD)
104
- pcd_sync_s68k(cycles, 0);
105
-#endif
106
-#ifdef PICO_32X
107
- p32x_sync_sh2s(cycles);
108
-#endif
109
- PsndGetSamples(y);
110
- }
111
-
112
// Run scanline:
113
Pico.t.m68c_line_start = Pico.t.m68c_aim;
114
- do_timing_hacks_as(pv, vdp_slots);
115
+ do_timing_hacks_start(pv);
116
CPUS_RUN(CYCLES_M68K_LINE);
117
+ do_timing_hacks_end(pv);
118
119
if (PicoLineHook) PicoLineHook();
120
pevt_log_m68k_o(EVT_NEXT_LINE);
121
122
#endif
123
}
124
125
- // VDP FIFO
126
- pv->lwrite_cnt = 0;
127
- Pico.video.status |= SR_EMPT;
128
-
129
memcpy(PicoIn.padInt, PicoIn.pad, sizeof(PicoIn.padInt));
130
PAD_DELAY();
131
132
133
}
134
135
pv->status |= SR_VB | PVS_VB2; // go into vblank
136
+ PicoVideoFIFOMode(pv->reg[1]&0x40, pv->reg[12]&1);
137
138
// the following SekRun is there for several reasons:
139
// there must be a delay after vblank bit is set and irq is asserted (Mazin Saga)
140
// also delay between F bit (bit 7) is set in SR and IRQ happens (Ex-Mutants)
141
// also delay between last H-int and V-int (Golden Axe 3)
142
Pico.t.m68c_line_start = Pico.t.m68c_aim;
143
- do_timing_hacks_vb();
144
+ do_timing_hacks_start(pv);
145
CPUS_RUN(CYCLES_M68K_VINT_LAG);
146
147
pv->status |= SR_F;
148
pv->pending_ints |= 0x20;
149
if (pv->reg[1] & 0x20) {
150
- Pico.t.m68c_aim = Pico.t.m68c_cnt + 11; // HACK
151
- SekSyncM68k();
152
+ if (Pico.t.m68c_cnt - Pico.t.m68c_aim < 60) // CPU blocked?
153
+ SekExecM68k(11); // HACK
154
elprintf(EL_INTS, "vint: @ %06x [%u]", SekPc, SekCyclesDone());
155
SekInterrupt(6);
156
}
157
158
- cycles = SekCyclesDone();
159
+ cycles = Pico.t.m68c_aim;
160
if (Pico.m.z80Run && !Pico.m.z80_reset && (PicoIn.opt&POPT_EN_Z80)) {
161
PicoSyncZ80(cycles);
162
elprintf(EL_INTS, "zint");
163
164
p32x_start_blank();
165
#endif
166
167
- // get samples from sound chips
168
- if (y == 224 && PicoIn.sndOut)
169
- PsndGetSamples(y);
170
-
171
// Run scanline:
172
CPUS_RUN(CYCLES_M68K_LINE - CYCLES_M68K_VINT_LAG);
173
+ do_timing_hacks_end(pv);
174
175
if (PicoLineHook) PicoLineHook();
176
pevt_log_m68k_o(EVT_NEXT_LINE);
177
178
179
// Run scanline:
180
Pico.t.m68c_line_start = Pico.t.m68c_aim;
181
- do_timing_hacks_vb();
182
+ do_timing_hacks_start(pv);
183
CPUS_RUN(CYCLES_M68K_LINE);
184
+ do_timing_hacks_end(pv);
185
186
if (PicoLineHook) PicoLineHook();
187
pevt_log_m68k_o(EVT_NEXT_LINE);
188
189
unsigned int l = PicoIn.overclockM68k * lines / 100;
190
while (l-- > 0) {
191
Pico.t.m68c_cnt -= CYCLES_M68K_LINE;
192
- do_timing_hacks_vb();
193
+ do_timing_hacks_start(pv);
194
SekSyncM68k();
195
+ do_timing_hacks_end(pv);
196
}
197
}
198
199
pv->status &= ~(SR_VB | PVS_VB2);
200
pv->status |= ((pv->reg[1] >> 3) ^ SR_VB) & SR_VB; // forced blanking
201
libretro-picodrive-0~git20200112.tar.xz/pico/pico_int.h -> libretro-picodrive-0~git20200716.tar.xz/pico/pico_int.h
Changed
201
1
2
3
#ifndef PICO_INTERNAL_INCLUDED
4
#define PICO_INTERNAL_INCLUDED
5
-
6
#include <stdio.h>
7
#include <string.h>
8
#include "pico_port.h"
9
10
extern "C" {
11
#endif
12
13
+#include "pico_types.h"
14
15
// ----------------------- 68000 CPU -----------------------
16
#ifdef EMU_C68K
17
18
19
// burn cycles while not in SekRun() and while in
20
#define SekCyclesBurn(c) Pico.t.m68c_cnt += c
21
-#define SekCyclesBurnRun(c) { \
22
- SekCyclesLeft -= c; \
23
-}
24
+#define SekCyclesBurnRun(c) SekCyclesLeft -= c
25
26
// note: sometimes may extend timeslice to delay an irq
27
#define SekEndRun(after) { \
28
29
#define z80_int_assert(a) Cz80_Set_IRQ(&CZ80, 0, (a) ? ASSERT_LINE : CLEAR_LINE)
30
#define z80_nmi() Cz80_Set_IRQ(&CZ80, IRQ_LINE_NMI, 0)
31
32
-#define z80_cyclesLeft (CZ80.ICount - CZ80.ExtraCycles)
33
+#define z80_cyclesLeft CZ80.ICount
34
#define z80_subCLeft(c) CZ80.ICount -= c
35
#define z80_pc() Cz80_Get_Reg(&CZ80, CZ80_PC)
36
37
38
#define z80_cyclesDone() \
39
(Pico.t.z80c_aim - z80_cyclesLeft)
40
41
-#define cycles_68k_to_z80(x) ((x) * 3823 >> 13)
42
+#define cycles_68k_to_z80(x) ((x) * 3822 >> 13)
43
44
// ----------------------- SH2 CPU -----------------------
45
46
47
# define sh2_pc(sh2) (sh2)->ppc
48
#else
49
# define sh2_end_run(sh2, after_) do { \
50
- int left_ = (signed int)(sh2)->sr >> 12; \
51
- if (left_ > (after_)) { \
52
- (sh2)->cycles_timeslice -= left_ - (after_); \
53
- (sh2)->sr &= 0xfff; \
54
- (sh2)->sr |= (after_) << 12; \
55
+ int left_ = ((signed int)(sh2)->sr >> 12) - (after_); \
56
+ if (left_ > 0) { \
57
+ (sh2)->cycles_timeslice -= left_; \
58
+ (sh2)->sr -= (left_ << 12); \
59
} \
60
} while (0)
61
# define sh2_cycles_left(sh2) ((signed int)(sh2)->sr >> 12)
62
63
# define sh2_pc(sh2) (sh2)->pc
64
#endif
65
66
-#define sh2_cycles_done(sh2) ((int)(sh2)->cycles_timeslice - sh2_cycles_left(sh2))
67
+#define sh2_cycles_done(sh2) (unsigned)((int)(sh2)->cycles_timeslice - sh2_cycles_left(sh2))
68
#define sh2_cycles_done_t(sh2) \
69
- ((sh2)->m68krcycles_done * 3 + sh2_cycles_done(sh2))
70
+ (unsigned)(C_M68K_TO_SH2(sh2, (sh2)->m68krcycles_done) + sh2_cycles_done(sh2))
71
#define sh2_cycles_done_m68k(sh2) \
72
- ((sh2)->m68krcycles_done + (sh2_cycles_done(sh2) / 3))
73
+ (unsigned)((sh2)->m68krcycles_done + C_SH2_TO_M68K(sh2, sh2_cycles_done(sh2)))
74
75
#define sh2_reg(c, x) (c) ? ssh2.r[x] : msh2.r[x]
76
#define sh2_gbr(c) (c) ? ssh2.gbr : msh2.gbr
77
78
// not part of real SR
79
#define PVS_ACTIVE (1 << 16)
80
#define PVS_VB2 (1 << 17) // ignores forced blanking
81
+#define PVS_CPUWR (1 << 18) // CPU write blocked by FIFO full
82
+#define PVS_CPURD (1 << 19) // CPU read blocked by FIFO not empty
83
+#define PVS_DMAFILL (1 << 20) // DMA fill is waiting for fill data
84
+#define PVS_DMABG (1 << 21) // background DMA operation is running
85
+#define PVS_FIFORUN (1 << 22) // FIFO is processing
86
87
struct PicoVideo
88
{
89
90
unsigned short addr; // Read/Write address
91
unsigned int status; // Status bits (SR) and extra flags
92
unsigned char pending_ints; // pending interrupts: ??VH????
93
- signed char lwrite_cnt; // VDP write count during active display line
94
+ signed char pad1; // was VDP write count
95
unsigned short v_counter; // V-counter
96
unsigned short debug; // raw debug register
97
unsigned char debug_p; // ... parsed: PVD_*
98
unsigned char addr_u; // bit16 of .addr
99
unsigned char hint_cnt;
100
- unsigned char pad[0x0b];
101
+ unsigned char pad2;
102
+ unsigned short hv_latch; // latched hvcounter value
103
+ signed int fifo_cnt; // pending xfers for current FIFO queue entry
104
+ unsigned char pad[0x04];
105
};
106
107
struct PicoMisc
108
109
unsigned char eeprom_cycle; // EEPROM cycle number
110
unsigned char eeprom_slave; // EEPROM slave word for X24C02 and better SRAMs
111
unsigned char eeprom_status;
112
- unsigned char status; // rapid_ym2612, multi_ym_updates
113
- unsigned short dma_xfers; // 18
114
+ unsigned char pad1; // was ym2612 status
115
+ unsigned short dma_xfers; // 18 unused (was VDP DMA transfer count)
116
unsigned char eeprom_wb[2]; // EEPROM latch/write buffer
117
unsigned int frame_count; // 1c for movies and idle det
118
};
119
120
unsigned int *PicoOpt;
121
unsigned char *Draw2FB;
122
unsigned short HighPal[0x100];
123
+ unsigned short SonicPal[0x100];
124
+ int SonicPalCount;
125
};
126
127
struct PicoMem
128
129
short len_use; // adjusted
130
int len_e_add; // for non-int samples/frame
131
int len_e_cnt;
132
- short dac_line;
133
- short psg_line;
134
+ unsigned int clkl_mult; // z80 clocks per line in Q20
135
+ unsigned int smpl_mult; // samples per line in Q16
136
+ short dac_val, dac_val2; // last DAC sample
137
+ unsigned int dac_pos; // last DAC position in Q20
138
+ unsigned int fm_pos; // last FM position in Q20
139
+ unsigned int psg_pos; // last PSG position in Q16
140
};
141
142
-// run tools/mkoffsets pico/pico_int_o32.h if you change these
143
+// run tools/mkoffsets pico/pico_int_offs.h if you change these
144
// careful with savestate compat
145
struct Pico
146
{
147
148
{
149
unsigned char sdram[0x40000];
150
#ifdef DRC_SH2
151
- unsigned short drcblk_ram[1 << (18 - SH2_DRCBLK_RAM_SHIFT)];
152
+ unsigned char drcblk_ram[1 << (18 - SH2_DRCBLK_RAM_SHIFT)];
153
+ unsigned char drclit_ram[1 << (18 - SH2_DRCBLK_RAM_SHIFT)];
154
#endif
155
unsigned short dram[2][0x20000/2]; // AKA fb
156
union {
157
158
unsigned char m68k_rom_bank[0x10000]; // M68K_BANK_SIZE
159
};
160
#ifdef DRC_SH2
161
- unsigned short drcblk_da[2][1 << (12 - SH2_DRCBLK_DA_SHIFT)];
162
+ unsigned char drcblk_da[2][1 << (12 - SH2_DRCBLK_DA_SHIFT)];
163
+ unsigned char drclit_da[2][1 << (12 - SH2_DRCBLK_DA_SHIFT)];
164
#endif
165
union {
166
unsigned char b[0x800];
167
168
unsigned short pal[0x100];
169
unsigned short pal_native[0x100]; // converted to native (for renderer)
170
signed short pwm[2*PWM_BUFF_LEN]; // PWM buffer for current frame
171
- signed short pwm_current[2]; // current converted samples
172
unsigned short pwm_fifo[2][4]; // [0] - current raw, others - fifo entries
173
+ unsigned pwm_index[2]; // ringbuffer index for pwm_fifo
174
};
175
176
// area.c
177
178
void PicoDrawSync(int to, int blank_last_line);
179
void BackFill(int reg7, int sh, struct PicoEState *est);
180
void FinalizeLine555(int sh, int line, struct PicoEState *est);
181
+void PicoDrawSetOutBufMD(void *dest, int increment);
182
extern int (*PicoScanBegin)(unsigned int num);
183
extern int (*PicoScanEnd)(unsigned int num);
184
-#define MAX_LINE_SPRITES 29
185
-extern unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES];
186
+#define MAX_LINE_SPRITES 27 // +1 last sprite width, +4 hdr; total 32
187
+extern unsigned char HighLnSpr[240][4+MAX_LINE_SPRITES+1];
188
extern void *DrawLineDestBase;
189
extern int DrawLineDestIncrement;
190
+extern unsigned int VdpSATCache[128];
191
192
// draw2.c
193
void PicoDraw2Init(void);
194
195
extern struct PicoMem PicoMem;
196
extern void (*PicoResetHook)(void);
197
extern void (*PicoLineHook)(void);
198
-PICO_INTERNAL int CheckDMA(void);
199
+PICO_INTERNAL int CheckDMA(int cycles);
200
PICO_INTERNAL void PicoDetectRegion(void);
201
libretro-picodrive-0~git20200112.tar.xz/pico/pico_port.h -> libretro-picodrive-0~git20200716.tar.xz/pico/pico_port.h
Changed
14
1
2
#define NOINLINE __attribute__((noinline))
3
#define ALIGNED(n) __attribute__((aligned(n)))
4
#define unlikely(x) __builtin_expect((x), 0)
5
+#define likely(x) __builtin_expect(!!(x), 1)
6
#else
7
#define NOINLINE
8
#define ALIGNED(n)
9
#define unlikely(x) (x)
10
+#define likely(x) (x)
11
#endif
12
13
#ifdef _MSC_VER
14
libretro-picodrive-0~git20200716.tar.xz/pico/pico_types.h
Added
21
1
2
+#ifndef PICO_TYPES
3
+#define PICO_TYPES
4
+
5
+#include <stdint.h>
6
+
7
+#ifndef __TAMTYPES_H__
8
+#ifndef UTYPES_DEFINED
9
+typedef uint8_t u8;
10
+typedef int8_t s8;
11
+typedef uint16_t u16;
12
+typedef int16_t s16;
13
+typedef uint32_t u32;
14
+typedef int32_t s32;
15
+#endif
16
+#endif
17
+
18
+typedef uintptr_t uptr; /* unsigned pointer-sized int */
19
+
20
+#endif
21
libretro-picodrive-0~git20200112.tar.xz/pico/sms.c -> libretro-picodrive-0~git20200716.tar.xz/pico/sms.c
Changed
39
1
2
struct PicoVideo *pv = &Pico.video;
3
4
if (pv->type == 3) {
5
+ if (PicoMem.cram[pv->addr & 0x1f] != d) Pico.m.dirtyPal = 1;
6
PicoMem.cram[pv->addr & 0x1f] = d;
7
- Pico.m.dirtyPal = 1;
8
} else {
9
PicoMem.vramb[pv->addr] = d;
10
}
11
12
13
case 0x40:
14
case 0x41:
15
- if ((d & 0x90) == 0x90 && Pico.snd.psg_line < Pico.m.scanline)
16
+ if ((d & 0x90) == 0x90)
17
PsndDoPSG(Pico.m.scanline);
18
SN76496Write(d);
19
break;
20
21
}
22
}
23
24
- // 224 because of how it's done for MD...
25
- if (y == 224 && PicoIn.sndOut)
26
- PsndGetSamplesMS();
27
-
28
cycles_aim += cycles_line;
29
cycles_done += z80_run((cycles_aim - cycles_done) >> 8) << 8;
30
}
31
32
- if (PicoIn.sndOut && Pico.snd.psg_line < lines)
33
- PsndDoPSG(lines - 1);
34
+ if (PicoIn.sndOut)
35
+ PsndGetSamplesMS(lines);
36
}
37
38
void PicoFrameDrawOnlyMS(void)
39
libretro-picodrive-0~git20200112.tar.xz/pico/sound/mix.c -> libretro-picodrive-0~git20200716.tar.xz/pico/sound/mix.c
Changed
109
1
2
* See COPYING file in the top-level directory.
3
*/
4
5
+#include "string.h"
6
+
7
#define MAXOUT (+32767)
8
#define MINOUT (-32768)
9
10
/* limitter */
11
-#define Limit(val, max,min) { \
12
- if ( val > max ) val = max; \
13
- else if ( val < min ) val = min; \
14
-}
15
+#define Limit16(val) \
16
+ if ((short)val != val) val = (val < 0 ? MINOUT : MAXOUT)
17
18
+int mix_32_to_16l_level;
19
20
-void mix_32_to_16l_stereo(short *dest, int *src, int count)
21
+static struct iir2 { // 2-pole IIR
22
+ int x[2]; // sample buffer
23
+ int y[2]; // filter intermediates
24
+ int i;
25
+} lfi2, rfi2;
26
+
27
+// NB ">>" rounds to -infinity, "/" to 0. To compensate the effect possibly use
28
+// "-(-y>>n)" (round to +infinity) instead of "y>>n" in places.
29
+
30
+// NB uses Q12 fixpoint; samples mustn't have more than 20 bits for this.
31
+#define QB 12
32
+
33
+
34
+// exponential moving average filter for DC filtering
35
+// y[n] = (x[n]-y[n-1])*(1/8192) (corner approx. 20Hz, gain 1)
36
+static inline int filter_exp(struct iir2 *fi2, int x)
37
{
38
- int l, r;
39
+ int xf = (x<<QB) - fi2->y[0];
40
+ fi2->y[0] += xf >> 13;
41
+ xf -= xf >> 2; // level reduction to avoid clipping from overshoot
42
+ return xf>>QB;
43
+}
44
45
- for (; count > 0; count--)
46
- {
47
- l = r = *dest;
48
- l += *src++;
49
- r += *src++;
50
- Limit( l, MAXOUT, MINOUT );
51
- Limit( r, MAXOUT, MINOUT );
52
- *dest++ = l;
53
- *dest++ = r;
54
- }
55
+// unfiltered (for testing)
56
+static inline int filter_null(struct iir2 *fi2, int x)
57
+{
58
+ return x;
59
+}
60
+
61
+#define mix_32_to_16l_stereo_core(dest, src, count, lv, fl) { \
62
+ int l, r; \
63
+ \
64
+ for (; count > 0; count--) \
65
+ { \
66
+ l = r = *dest; \
67
+ l += *src++ >> lv; \
68
+ r += *src++ >> lv; \
69
+ l = fl(&lfi2, l); \
70
+ r = fl(&rfi2, r); \
71
+ Limit16(l); \
72
+ Limit16(r); \
73
+ *dest++ = l; \
74
+ *dest++ = r; \
75
+ } \
76
+}
77
+
78
+void mix_32_to_16l_stereo_lvl(short *dest, int *src, int count)
79
+{
80
+ mix_32_to_16l_stereo_core(dest, src, count, mix_32_to_16l_level, filter_exp);
81
}
82
83
+void mix_32_to_16l_stereo(short *dest, int *src, int count)
84
+{
85
+ mix_32_to_16l_stereo_core(dest, src, count, 0, filter_exp);
86
+}
87
88
void mix_32_to_16_mono(short *dest, int *src, int count)
89
{
90
91
{
92
l = *dest;
93
l += *src++;
94
- Limit( l, MAXOUT, MINOUT );
95
+ l = filter_exp(&lfi2, l);
96
+ Limit16(l);
97
*dest++ = l;
98
}
99
}
100
101
}
102
}
103
104
+void mix_reset(void)
105
+{
106
+ memset(&lfi2, 0, sizeof(lfi2));
107
+ memset(&rfi2, 0, sizeof(rfi2));
108
+}
109
libretro-picodrive-0~git20200112.tar.xz/pico/sound/mix.h -> libretro-picodrive-0~git20200716.tar.xz/pico/sound/mix.h
Changed
6
1
2
3
extern int mix_32_to_16l_level;
4
void mix_32_to_16l_stereo_lvl(short *dest, int *src, int count);
5
+void mix_reset(void);
6
libretro-picodrive-0~git20200112.tar.xz/pico/sound/mix_arm.S -> libretro-picodrive-0~git20200716.tar.xz/pico/sound/mix_arm.S
Changed
192
1
2
@ limit and shift up by 16
3
@ reg=int_sample, lr=1, r3=tmp, kills flags
4
.macro Limitsh reg
5
-@ movs r4, r3, asr #16
6
-@ cmnne r4, #1
7
-@ beq c32_16_no_overflow
8
-@ tst r4, r4
9
-@ mov r3, #0x8000
10
-@ subpl r3, r3, #1
11
-
12
add r3, lr, \reg, asr #15
13
bics r3, r3, #1 @ in non-overflow conditions r3 is 0 or 1
14
moveq \reg, \reg, lsl #16
15
16
subpl \reg, \reg, #0x00010000
17
.endm
18
19
+@ filter out DC offset
20
+@ in=int_sample (max 20 bit), y=filter memory, r3=tmp
21
+.macro DCfilt in y
22
+ rsb r3, \y, \in, lsl #12 @ fixpoint 20.12
23
+ add \y, \y, r3, asr #13
24
+ sub r3, r3, r3, asr #2 @ reduce audio lvl some
25
+ asr \in, r3, #12
26
+.endm
27
28
@ mix 32bit audio (with 16bits really used, upper bits indicate overflow) with normal 16 bit audio with left channel only
29
@ warning: this function assumes dest is word aligned
30
.global mix_32_to_16l_stereo @ short *dest, int *src, int count
31
32
mix_32_to_16l_stereo:
33
- stmfd sp!, {r4-r8,lr}
34
-
35
- mov lr, #1
36
+ stmfd sp!, {r4-r8,r10-r11,lr}
37
38
mov r2, r2, lsl #1
39
subs r2, r2, #4
40
bmi m32_16l_st_end
41
42
+ mov lr, #1
43
+ ldr r12, =filter
44
+ ldmia r12, {r10-r11}
45
+
46
m32_16l_st_loop:
47
ldmia r0, {r8,r12}
48
ldmia r1!, {r4-r7}
49
50
add r5, r5, r8, asr #16
51
add r6, r6, r12,asr #16
52
add r7, r7, r12,asr #16
53
+ DCfilt r4, r10
54
+ DCfilt r5, r11
55
+ DCfilt r6, r10
56
+ DCfilt r7, r11
57
Limitsh r4
58
Limitsh r5
59
Limitsh r6
60
61
ldmia r1!,{r4,r5}
62
add r4, r4, r6
63
add r5, r5, r6
64
+ DCfilt r4, r10
65
+ DCfilt r5, r11
66
Limitsh r4
67
Limitsh r5
68
orr r4, r5, r4, lsr #16
69
str r4, [r0], #4
70
71
m32_16l_st_no_unal2:
72
- ldmfd sp!, {r4-r8,lr}
73
+ ldr r12, =filter
74
+ stmia r12, {r10-r11}
75
+ ldmfd sp!, {r4-r8,r10-r11,lr}
76
bx lr
77
78
79
80
.global mix_32_to_16_mono @ short *dest, int *src, int count
81
82
mix_32_to_16_mono:
83
- stmfd sp!, {r4-r8,lr}
84
+ stmfd sp!, {r4-r8,r10-r11,lr}
85
86
mov lr, #1
87
+ ldr r12, =filter
88
+ ldr r10, [r12]
89
90
@ check if dest is word aligned
91
tst r0, #2
92
93
add r7, r7, r12,asr #16
94
mov r12,r12,lsl #16
95
add r6, r6, r12,asr #16
96
+ DCfilt r4, r10
97
+ DCfilt r5, r10
98
+ DCfilt r6, r10
99
+ DCfilt r7, r10
100
Limitsh r4
101
Limitsh r5
102
Limitsh r6
103
104
add r5, r5, r6, asr #16
105
mov r6, r6, lsl #16
106
add r4, r4, r6, asr #16
107
+ DCfilt r4, r10
108
+ DCfilt r5, r10
109
Limitsh r4
110
Limitsh r5
111
orr r4, r5, r4, lsr #16
112
113
114
m32_16_mo_no_unal2:
115
tst r2, #1
116
- ldmeqfd sp!, {r4-r8,pc}
117
+ beq m32_16_mo_no_unal
118
ldrsh r5, [r0]
119
ldr r4, [r1], #4
120
add r4, r4, r5
121
+ DCfilt r4, r10
122
Limit r4
123
strh r4, [r0], #2
124
125
- ldmfd sp!, {r4-r8,lr}
126
+m32_16_mo_no_unal:
127
+ ldr r12, =filter
128
+ str r10, [r12]
129
+ ldmfd sp!, {r4-r8,r10-r11,lr}
130
bx lr
131
132
133
134
.global mix_32_to_16l_stereo_lvl @ short *dest, int *src, int count
135
136
mix_32_to_16l_stereo_lvl:
137
- stmfd sp!, {r4-r9,lr}
138
+ stmfd sp!, {r4-r11,lr}
139
140
ldr r9, =mix_32_to_16l_level
141
mov lr, #1
142
ldr r9, [r9]
143
+ ldr r12, =filter
144
+ ldm r12, {r10-r11}
145
146
mov r2, r2, lsl #1
147
subs r2, r2, #4
148
149
mov r5, r5, asr r9
150
mov r6, r6, asr r9
151
mov r7, r7, asr r9
152
+ DCfilt r4, r10
153
+ DCfilt r5, r11
154
+ DCfilt r6, r10
155
+ DCfilt r7, r11
156
Limitsh r4
157
Limitsh r5
158
Limitsh r6
159
160
add r5, r5, r6
161
mov r4, r4, asr r9
162
mov r5, r5, asr r9
163
+ DCfilt r4, r10
164
+ DCfilt r5, r11
165
Limitsh r4
166
Limitsh r5
167
orr r4, r5, r4, lsr #16
168
str r4, [r0], #4
169
170
m32_16l_st_l_no_unal2:
171
- ldmfd sp!, {r4-r9,lr}
172
+ ldr r12, =filter
173
+ stmia r12, {r10-r11}
174
+ ldmfd sp!, {r4-r11,lr}
175
bx lr
176
177
#endif /* __GP2X__ */
178
179
+.global mix_reset @ void
180
+mix_reset:
181
+ ldr r0, =filter
182
+ mov r1, #0
183
+ str r1, [r0]
184
+ str r1, [r0, #4]
185
+ bx lr
186
+
187
+.data
188
+filter:
189
+ .ds 8
190
+
191
@ vim:filetype=armasm
192
libretro-picodrive-0~git20200112.tar.xz/pico/sound/sn76496.c -> libretro-picodrive-0~git20200716.tar.xz/pico/sound/sn76496.c
Changed
25
1
2
/* If we exit the loop in the middle, Output[i] has to be inverted */
3
/* and vol[i] incremented only if the exit status of the square */
4
/* wave is 1. */
5
+ left = 0;
6
while (R->Count[i] <= 0)
7
{
8
- R->Count[i] += R->Period[i];
9
+ if (R->Count[i] + R->Period[i]*4 < R->Period[i])
10
+ left+= 4, R->Count[i] += R->Period[i]*4;
11
+ else left++, R->Count[i] += R->Period[i];
12
if (R->Count[i] > 0)
13
{
14
R->Output[i] ^= 1;
15
16
vol[i] += R->Period[i];
17
}
18
if (R->Output[i]) vol[i] -= R->Count[i];
19
+ /* Cut of anything above the sample freqency. It will only create */
20
+ /* aliasing and hearable distortions anyway. */
21
+ if (left > 1) vol[i] = STEP/2;
22
}
23
24
left = STEP;
25
libretro-picodrive-0~git20200112.tar.xz/pico/sound/sound.c -> libretro-picodrive-0~git20200716.tar.xz/pico/sound/sound.c
Changed
201
1
2
// master int buffer to mix to
3
static int PsndBuffer[2*(44100+100)/50];
4
5
-// dac, psg
6
-static unsigned short dac_info[312+4]; // pos in sample buffer
7
-
8
// cdda output buffer
9
short cdda_out_buffer[2*1152];
10
11
12
13
void (*low_pass_filter)(int *buf32, int length) = low_pass_filter_stereo;
14
15
-static void dac_recalculate(void)
16
-{
17
- int lines = Pico.m.pal ? 313 : 262;
18
- int mid = Pico.m.pal ? 68 : 93;
19
- int i, dac_cnt, pos, len;
20
-
21
- if (Pico.snd.len <= lines)
22
- {
23
- // shrinking algo
24
- dac_cnt = -Pico.snd.len;
25
- len=1; pos=0;
26
- dac_info[225] = 1;
27
-
28
- for(i=226; i != 225; i++)
29
- {
30
- if (i >= lines) i = 0;
31
- if(dac_cnt < 0) {
32
- pos++;
33
- dac_cnt += lines;
34
- }
35
- dac_cnt -= Pico.snd.len;
36
- dac_info[i] = pos;
37
- }
38
- }
39
- else
40
- {
41
- // stretching
42
- dac_cnt = Pico.snd.len;
43
- pos=0;
44
- for(i = 225; i != 224; i++)
45
- {
46
- if (i >= lines) i = 0;
47
- len=0;
48
- while(dac_cnt >= 0) {
49
- dac_cnt -= lines;
50
- len++;
51
- }
52
- if (i == mid) // midpoint
53
- while(pos+len < Pico.snd.len/2) {
54
- dac_cnt -= lines;
55
- len++;
56
- }
57
- dac_cnt += Pico.snd.len;
58
- pos += len;
59
- dac_info[i] = pos;
60
- }
61
- }
62
- for (i = lines; i < sizeof(dac_info) / sizeof(dac_info[0]); i++)
63
- dac_info[i] = dac_info[0];
64
-}
65
-
66
-
67
PICO_INTERNAL void PsndReset(void)
68
{
69
// PsndRerate calls YM2612Init, which also resets
70
71
// Reset low pass filter
72
lpf_lp = 0;
73
lpf_rp = 0;
74
+
75
+ mix_reset();
76
}
77
78
79
80
{
81
void *state = NULL;
82
int target_fps = Pico.m.pal ? 50 : 60;
83
+ int target_lines = Pico.m.pal ? 313 : 262;
84
85
if (preserve_state) {
86
state = malloc(0x204);
87
88
ym2612_pack_state();
89
memcpy(state, YM2612GetRegs(), 0x204);
90
}
91
- YM2612Init(Pico.m.pal ? OSC_PAL/7 : OSC_NTSC/7, PicoIn.sndRate);
92
+ YM2612Init(Pico.m.pal ? OSC_PAL/7 : OSC_NTSC/7, PicoIn.sndRate, !(PicoIn.opt&POPT_DIS_FM_SSGEG));
93
if (preserve_state) {
94
// feed it back it's own registers, just like after loading state
95
memcpy(YM2612GetRegs(), state, 0x204);
96
97
// calculate Pico.snd.len
98
Pico.snd.len = PicoIn.sndRate / target_fps;
99
Pico.snd.len_e_add = ((PicoIn.sndRate - Pico.snd.len * target_fps) << 16) / target_fps;
100
- Pico.snd.len_e_cnt = 0;
101
+ Pico.snd.len_e_cnt = 0; // Q16
102
103
- // recalculate dac info
104
- dac_recalculate();
105
+ // samples per line (Q16)
106
+ Pico.snd.smpl_mult = 65536LL * PicoIn.sndRate / (target_fps*target_lines);
107
+ // samples per z80 clock (Q20)
108
+ Pico.snd.clkl_mult = 16 * Pico.snd.smpl_mult * 15/7 / 488;
109
110
// clear all buffers
111
memset32(PsndBuffer, 0, sizeof(PsndBuffer)/4);
112
113
Pico.snd.len_e_cnt -= 0x10000;
114
Pico.snd.len_use++;
115
}
116
-
117
- Pico.snd.dac_line = Pico.snd.psg_line = 0;
118
- Pico.m.status &= ~1;
119
- dac_info[224] = Pico.snd.len_use;
120
}
121
122
-PICO_INTERNAL void PsndDoDAC(int line_to)
123
+PICO_INTERNAL void PsndDoDAC(int cyc_to)
124
{
125
- int pos, pos1, len;
126
+ int pos, len;
127
int dout = ym2612.dacout;
128
- int line_from = Pico.snd.dac_line;
129
130
- if (line_to >= 313)
131
- line_to = 312;
132
+ // number of samples to fill in buffer (Q20)
133
+ len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.dac_pos;
134
135
- pos = dac_info[line_from];
136
- pos1 = dac_info[line_to + 1];
137
- len = pos1 - pos;
138
+ // update position and calculate buffer offset and length
139
+ pos = (Pico.snd.dac_pos+0x80000) >> 20;
140
+ Pico.snd.dac_pos += len;
141
+ len = ((Pico.snd.dac_pos+0x80000) >> 20) - pos;
142
+
143
+ // avoid loss of the 1st sample of a new block (Q rounding issues)
144
+ if (pos+len == 0)
145
+ len = 1, Pico.snd.dac_pos += 0x80000;
146
if (len <= 0)
147
return;
148
149
- Pico.snd.dac_line = line_to + 1;
150
-
151
if (!PicoIn.sndOut)
152
return;
153
154
+ // fill buffer, applying a rather weak order 1 bessel IIR on the way
155
+ // y[n] = (x[n] + x[n-1])*(1/2) (3dB cutoff at 11025 Hz, no gain)
156
+ // 1 sample delay for correct IIR filtering over audio frame boundaries
157
if (PicoIn.opt & POPT_EN_STEREO) {
158
short *d = PicoIn.sndOut + pos*2;
159
- for (; len > 0; len--, d+=2) *d += dout;
160
+ // left channel only, mixed ro right channel in mixing phase
161
+ *d++ += Pico.snd.dac_val2; d++;
162
+ while (--len) *d++ += Pico.snd.dac_val, d++;
163
} else {
164
short *d = PicoIn.sndOut + pos;
165
- for (; len > 0; len--, d++) *d += dout;
166
+ *d++ += Pico.snd.dac_val2;
167
+ while (--len) *d++ += Pico.snd.dac_val;
168
}
169
+ Pico.snd.dac_val2 = (Pico.snd.dac_val + dout) >> 1;
170
+ Pico.snd.dac_val = dout;
171
}
172
173
PICO_INTERNAL void PsndDoPSG(int line_to)
174
{
175
- int line_from = Pico.snd.psg_line;
176
- int pos, pos1, len;
177
+ int pos, len;
178
int stereo = 0;
179
180
- if (line_to >= 313)
181
- line_to = 312;
182
-
183
- pos = dac_info[line_from];
184
- pos1 = dac_info[line_to + 1];
185
- len = pos1 - pos;
186
- //elprintf(EL_STATUS, "%3d %3d %3d %3d %3d",
187
- // pos, pos1, len, line_from, line_to);
188
+ // Q16, number of samples since last call
189
+ len = ((line_to+1) * Pico.snd.smpl_mult) - Pico.snd.psg_pos;
190
if (len <= 0)
191
return;
192
193
- Pico.snd.psg_line = line_to + 1;
194
+ // update position and calculate buffer offset and length
195
+ pos = (Pico.snd.psg_pos+0x8000) >> 16;
196
+ Pico.snd.psg_pos += len;
197
+ len = ((Pico.snd.psg_pos+0x8000) >> 16) - pos;
198
199
if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_PSG))
200
return;
201
libretro-picodrive-0~git20200112.tar.xz/pico/sound/ym2612.c -> libretro-picodrive-0~git20200716.tar.xz/pico/sound/ym2612.c
Changed
201
1
2
**
3
** SSG-EG was also removed, because it's rarely used, Sega2.doc even does not
4
** document it ("proprietary") and tells to write 0 to SSG-EG control register.
5
+**
6
+** updated with fixes from mame 0.216 (file version 1.5.1) (kub)
7
+** SSG-EG readded from GenPlus (kub)
8
+** linear sample interpolation for chip to output rate adaption (kub)
9
*/
10
11
/*
12
13
14
#endif
15
16
-void memset32(int *dest, int c, int count);
17
+void memset32(void *dest, int c, int count);
18
19
20
#ifndef __GNUC__
21
22
23
#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */
24
#define EG_SH 16 /* 16.16 fixed point (envelope generator timing) */
25
-#define LFO_SH 25 /* 7.25 fixed point (LFO calculations) */
26
+#define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */
27
#define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */
28
29
#define ENV_BITS 10
30
31
32
#define EG_TIMER_OVERFLOW (3*(1<<EG_SH)) /* envelope generator timer overflows every 3 samples (on real chip) */
33
34
-#define MAXOUT (+32767)
35
-#define MINOUT (-32768)
36
-
37
-/* limitter */
38
-#define Limit(val, max,min) { \
39
- if ( val > max ) val = max; \
40
- else if ( val < min ) val = min; \
41
-}
42
-
43
-
44
/* TL_TAB_LEN is calculated as:
45
* 13 - sinus amplitude bits (Y axis)
46
* 2 - sinus sign bit (Y axis)
47
48
O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
49
50
/* rates 00-11 */
51
-O( 0),O( 1),O( 2),O( 3),
52
+O(18),O(18),O( 2),O( 3),
53
O( 0),O( 1),O( 2),O( 3),
54
O( 0),O( 1),O( 2),O( 3),
55
O( 0),O( 1),O( 2),O( 3),
56
57
#define O(a) (a*1)
58
static const UINT8 eg_rate_shift[32+64+32]={ /* Envelope Generator counter shifts (32 + 64 rates + 32 RKS) */
59
/* 32 infinite time rates */
60
-O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
61
-O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
62
-O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
63
-O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
64
+O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11),
65
+O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11),
66
+O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11),
67
+O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11),
68
69
/* rates 00-11 */
70
O(11),O(11),O(11),O(11),
71
72
but LFO works with one more bit of a precision so we really need 4096 elements */
73
static UINT32 fn_table[4096]; /* fnumber->increment counter */
74
75
-static int g_lfo_ampm = 0;
76
+static int g_lfo_ampm;
77
78
/* register number to channel number , slot offset */
79
#define OPN_CHAN(N) (N&3)
80
81
ym2612.OPN.ST.status &= ~1;
82
}
83
84
+INLINE void recalc_volout(FM_SLOT *SLOT)
85
+{
86
+ INT16 vol_out = SLOT->volume;
87
+ if ((SLOT->ssg&0x0c) == 0x0c)
88
+ vol_out = (0x200 - SLOT->volume) & MAX_ATT_INDEX;
89
+ SLOT->vol_out = vol_out + SLOT->tl;
90
+}
91
92
INLINE void FM_KEYON(int c , int s )
93
{
94
95
{
96
SLOT->key = 1;
97
SLOT->phase = 0; /* restart Phase Generator */
98
- SLOT->state = EG_ATT; /* phase -> Attack */
99
+ SLOT->ssg ^= SLOT->ssgn;
100
+ SLOT->ssgn = 0;
101
+ SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC;
102
+ if (SLOT->ar_ksr < 32+62) {
103
+ if (SLOT->volume > MIN_ATT_INDEX) SLOT->state = EG_ATT;
104
+ } else {
105
+ SLOT->volume = MIN_ATT_INDEX;
106
+ }
107
+// recalc_volout(SLOT);
108
ym2612.slot_mask |= (1<<s) << (c*4);
109
}
110
}
111
112
if( SLOT->key )
113
{
114
SLOT->key = 0;
115
- if (SLOT->state>EG_REL)
116
+ if (SLOT->state>EG_REL) {
117
SLOT->state = EG_REL;/* phase -> Release */
118
+ if (SLOT->ssg&0x08) {
119
+ if (SLOT->ssg&0x04)
120
+ SLOT->volume = (0x200 - SLOT->volume);
121
+ if (SLOT->volume >= 0x200) {
122
+ SLOT->volume = MAX_ATT_INDEX;
123
+ SLOT->state = EG_OFF;
124
+ }
125
+ }
126
+ }
127
+ SLOT->vol_out = SLOT->volume + SLOT->tl;
128
}
129
}
130
131
132
INLINE void set_tl(FM_SLOT *SLOT, int v)
133
{
134
SLOT->tl = (v&0x7f)<<(ENV_BITS-7); /* 7bit TL */
135
+// if (SLOT->state > EG_REL)
136
+// recalc_volout(SLOT);
137
}
138
139
/* set attack rate & key scale */
140
INLINE void set_ar_ksr(FM_CH *CH, FM_SLOT *SLOT, int v)
141
{
142
UINT8 old_KSR = SLOT->KSR;
143
+ int eg_sh_ar, eg_sel_ar;
144
145
SLOT->ar = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;
146
+ SLOT->ar_ksr = SLOT->ar + SLOT->ksr;
147
148
SLOT->KSR = 3-(v>>6);
149
if (SLOT->KSR != old_KSR)
150
{
151
CH->SLOT[SLOT1].Incr=-1;
152
}
153
+
154
+ /* refresh Attack rate */
155
+ if ((SLOT->ar_ksr) < 32+62)
156
+ {
157
+ eg_sh_ar = eg_rate_shift [SLOT->ar_ksr];
158
+ eg_sel_ar = eg_rate_select[SLOT->ar_ksr];
159
+ }
160
else
161
{
162
- int eg_sh_ar, eg_sel_ar;
163
-
164
- /* refresh Attack rate */
165
- if ((SLOT->ar + SLOT->ksr) < 32+62)
166
- {
167
- eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
168
- eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
169
- }
170
- else
171
- {
172
- eg_sh_ar = 0;
173
- eg_sel_ar = 17;
174
- }
175
-
176
- SLOT->eg_pack_ar = eg_inc_pack[eg_sel_ar] | (eg_sh_ar<<24);
177
+ eg_sh_ar = 0;
178
+ eg_sel_ar = 18;
179
}
180
+
181
+ SLOT->eg_pack_ar = eg_inc_pack[eg_sel_ar] | (eg_sh_ar<<24);
182
}
183
184
/* set decay rate */
185
186
187
SLOT->sl = sl_table[ v>>4 ];
188
189
+ if (SLOT->state == EG_DEC && (SLOT->volume >= (INT32)(SLOT->sl)))
190
+ SLOT->state = EG_SUS;
191
+
192
SLOT->rr = 34 + ((v&0x0f)<<2);
193
194
eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr];
195
196
if (prev_pos != pos)
197
{
198
lfo_ampm &= 0xff;
199
- /* triangle */
200
+ /* triangle (inverted) */
201
libretro-picodrive-0~git20200112.tar.xz/pico/sound/ym2612.h -> libretro-picodrive-0~git20200716.tar.xz/pico/sound/ym2612.h
Changed
77
1
2
};
3
UINT32 eg_pack[4];
4
};
5
+
6
+ UINT8 ssg; /* 0x30 SSG-EG waveform */
7
+ UINT8 ssgn;
8
+ UINT16 ar_ksr; /* 0x32 ar+ksr */
9
+ UINT16 vol_out; /* 0x34 current output from EG (without LFO) */
10
+ UINT16 vol_ipol; /* 0x36 interpolator memory */
11
} FM_SLOT;
12
13
14
15
UINT8 address; /* 10 address register | need_save */
16
UINT8 status; /* 11 status flag | need_save */
17
UINT8 mode; /* mode CSM / 3SLOT */
18
- UINT8 pad;
19
+ UINT8 flags; /* operational flags */
20
int TA; /* timer a */
21
int TAC; /* timer a maxval */
22
int TAT; /* timer a ticker | need_save */
23
24
FM_OPN OPN; /* OPN state */
25
26
UINT32 slot_mask; /* active slot mask (performance hack) */
27
+ UINT32 ssg_mask; /* active ssg mask (performance hack) */
28
} YM2612;
29
#endif
30
31
32
extern YM2612 ym2612;
33
#endif
34
35
-void YM2612Init_(int baseclock, int rate);
36
+void YM2612Init_(int baseclock, int rate, int ssg);
37
void YM2612ResetChip_(void);
38
int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty);
39
40
41
#else
42
/* GP2X specific */
43
#include "../../platform/gp2x/940ctl.h"
44
-extern int PicoIn.opt;
45
-#define YM2612Init(baseclock,rate) { \
46
- if (PicoIn.opt&0x200) YM2612Init_940(baseclock, rate); \
47
- else YM2612Init_(baseclock, rate); \
48
-}
49
-#define YM2612ResetChip() { \
50
- if (PicoIn.opt&0x200) YM2612ResetChip_940(); \
51
+#define YM2612Init(baseclock,rate,ssg) do { \
52
+ if (PicoIn.opt&POPT_EXT_FM) YM2612Init_940(baseclock, rate, ssg); \
53
+ else YM2612Init_(baseclock, rate, ssg); \
54
+} while (0)
55
+#define YM2612ResetChip() do { \
56
+ if (PicoIn.opt&POPT_EXT_FM) YM2612ResetChip_940(); \
57
else YM2612ResetChip_(); \
58
-}
59
-#define YM2612UpdateOne(buffer,length,stereo,is_buf_empty) \
60
- (PicoIn.opt&0x200) ? YM2612UpdateOne_940(buffer, length, stereo, is_buf_empty) : \
61
- YM2612UpdateOne_(buffer, length, stereo, is_buf_empty);
62
-#define YM2612PicoStateLoad() { \
63
- if (PicoIn.opt&0x200) YM2612PicoStateLoad_940(); \
64
+} while (0)
65
+#define YM2612UpdateOne(buffer,length,stereo,is_buf_empty) do { \
66
+ (PicoIn.opt&POPT_EXT_FM) ? YM2612UpdateOne_940(buffer, length, stereo, is_buf_empty) : \
67
+ YM2612UpdateOne_(buffer, length, stereo, is_buf_empty); \
68
+} while (0)
69
+#define YM2612PicoStateLoad() do { \
70
+ if (PicoIn.opt&POPT_EXT_FM) YM2612PicoStateLoad_940(); \
71
else YM2612PicoStateLoad_(); \
72
-}
73
+} while (0)
74
#endif /* __GP2X__ */
75
76
77
libretro-picodrive-0~git20200716.tar.xz/pico/sound/ym2612_arm.S
Added
201
1
2
+/*
3
+ * PicoDrive
4
+ * (C) notaz, 2006
5
+ * (C) kub, 2020 added SSG-EG and simple output rate interpolation
6
+ *
7
+ * This work is licensed under the terms of MAME license.
8
+ * See COPYING file in the top-level directory.
9
+ */
10
+
11
+@ this is a rewrite of MAME's ym2612 code, in particular this is only the main sample-generatin loop.
12
+@ it does not seem to give much performance increase (if any at all), so don't use it if it causes trouble.
13
+@ - notaz, 2006
14
+
15
+@ vim:filetype=armasm
16
+
17
+#include "../arm_features.h"
18
+
19
+@ very simple YM2612 output rate to sample rate adaption (~500k cycles @44100)
20
+#define INTERPOL
21
+#define SSG_EG
22
+
23
+.equiv SLOT1, 0
24
+.equiv SLOT2, 2
25
+.equiv SLOT3, 1
26
+.equiv SLOT4, 3
27
+.equiv SLOT_STRUCT_SIZE, 0x38
28
+
29
+.equiv TL_TAB_LEN, 0x1A00
30
+
31
+.equiv EG_ATT, 4
32
+.equiv EG_DEC, 3
33
+.equiv EG_SUS, 2
34
+.equiv EG_REL, 1
35
+.equiv EG_OFF, 0
36
+
37
+.equiv EG_SH, 16 @ 16.16 fixed point (envelope generator timing)
38
+.equiv EG_TIMER_OVERFLOW, (3*(1<<EG_SH)) @ envelope generator timer overflows every 3 samples (on real chip)
39
+.equiv LFO_SH, 24 /* 8.24 fixed point (LFO calculations) */
40
+
41
+.equiv ENV_QUIET, (2*13*256/8)
42
+
43
+.text
44
+.align 2
45
+ PIC_LDR_INIT()
46
+
47
+@ r5=slot, r1=eg_cnt, trashes: r0,r2,r3
48
+@ writes output to routp, but only if vol_out changes
49
+.macro update_eg_phase_slot
50
+#if defined(INTERPOL)
51
+ ldrh r0, [r5,#0x34] @ vol_out
52
+#endif
53
+ ldrb r2, [r5,#0x17] @ state
54
+ add r3, r5, #0x1c
55
+#if defined(INTERPOL)
56
+ strh r0, [r5,#0x36] @ vol_ipol
57
+#endif
58
+ tst r2, r2
59
+ beq 0f @ EG_OFF
60
+
61
+ ldr r2, [r3, r2, lsl #2] @ pack
62
+ mov r3, #1
63
+ mov r0, r2, lsr #24 @ shift
64
+ mov r3, r3, lsl r0
65
+ sub r3, r3, #1
66
+
67
+ tst r1, r3
68
+ bne 0f @ no volume change
69
+
70
+ mov r3, r1, lsr r0
71
+ ldrb r0, [r5,#0x30] @ ssg
72
+ and r3, r3, #7
73
+ add r3, r3, r3, lsl #1
74
+ mov r3, r2, lsr r3
75
+ and r3, r3, #7 @ eg_inc_val shift, may be 0
76
+ ldrb r2, [r5,#0x17] @ state
77
+
78
+#if defined(SSG_EG)
79
+ tst r0, #0x08 @ ssg enabled?
80
+ tstne r12, #0x02
81
+ bne 9f
82
+#endif
83
+
84
+ @ non-SSG-EG mode
85
+ cmp r2, #4 @ EG_ATT
86
+ ldrh r0, [r5,#0x1a] @ volume, unsigned (0-1023)
87
+ beq 4f
88
+
89
+ cmp r2, #2
90
+ mov r2, #1
91
+ mov r2, r2, lsl r3
92
+ mov r2, r2, lsr #1 @ eg_inc_val
93
+ add r0, r0, r2
94
+ blt 1f @ EG_REL
95
+ beq 2f @ EG_SUS
96
+
97
+3: @ EG_DEC
98
+ ldr r2, [r5,#0x1c] @ sl (can be 16bit?)
99
+ mov r3, #EG_SUS
100
+ cmp r0, r2 @ if ( volume >= (INT32) SLOT->sl )
101
+ strgeb r3, [r5,#0x17] @ state
102
+ b 10f
103
+
104
+4: @ EG_ATT
105
+ subs r3, r3, #1 @ eg_inc_val_shift - 1
106
+ mvnpl r2, r0
107
+ movpl r2, r2, lsl r3
108
+ addpl r0, r0, r2, asr #4
109
+ cmp r0, #0 @ if (volume <= MIN_ATT_INDEX)
110
+ bgt 10f
111
+ ldr r2, [r5,#0x1c]
112
+ mov r0, #0
113
+ cmp r2, #0
114
+ movne r3, #EG_DEC
115
+ moveq r3, #EG_SUS
116
+ strb r3, [r5,#0x17] @ state
117
+ b 10f
118
+
119
+2: @ EG_SUS
120
+ mov r2, #1024
121
+ sub r2, r2, #1 @ r2 = MAX_ATT_INDEX
122
+ cmp r0, r2 @ if ( volume >= MAX_ATT_INDEX )
123
+ movge r0, r2
124
+ b 10f
125
+
126
+1: @ EG_REL
127
+ mov r2, #1024
128
+ sub r2, r2, #1 @ r2 = MAX_ATT_INDEX
129
+ cmp r0, r2 @ if ( volume >= MAX_ATT_INDEX )
130
+ movge r0, r2
131
+ movge r3, #EG_OFF
132
+ strgeb r3, [r5,#0x17] @ state
133
+
134
+10: @ finish
135
+ ldrh r3, [r5,#0x18] @ tl
136
+ strh r0, [r5,#0x1a] @ volume
137
+#if defined(SSG_EG)
138
+ b 11f
139
+
140
+9: @ SSG-EG mode
141
+ ldrh r0, [r5,#0x1a] @ volume, unsigned (0-1023)
142
+ cmp r2, #4 @ EG_ATT
143
+ beq 4f
144
+
145
+ cmp r0, #0x200 @ if ( volume < 0x200 )
146
+ movlt r0, #1
147
+ movlt r3, r0, lsl r3
148
+ ldrlth r0, [r5,#0x1a] @ volume, unsigned (0-1023)
149
+ movlt r3, r3, lsr #1 @ eg_inc_val
150
+ addlt r0, r0, r3, lsl #2
151
+
152
+ cmp r2, #2
153
+ blt 1f @ EG_REL
154
+ beq 10f @ EG_SUS - nothing more to do
155
+
156
+3: @ EG_DEC
157
+ ldr r2, [r5,#0x1c] @ sl (can be 16bit?)
158
+ mov r3, #EG_SUS
159
+ cmp r0, r2 @ if ( volume >= (INT32) SLOT->sl )
160
+ strgeb r3, [r5,#0x17] @ state
161
+ b 10f
162
+
163
+4: @ EG_ATT
164
+ subs r3, r3, #1 @ eg_inc_val_shift - 1
165
+ mvnpl r2, r0
166
+ movpl r2, r2, lsl r3
167
+ addpl r0, r0, r2, asr #4
168
+ cmp r0, #0 @ if (volume <= MIN_ATT_INDEX)
169
+ bgt 10f
170
+ ldr r2, [r5,#0x1c]
171
+ mov r0, #0
172
+ cmp r2, #0
173
+ movne r3, #EG_DEC
174
+ moveq r3, #EG_SUS
175
+ strb r3, [r5,#0x17] @ state
176
+ b 10f
177
+
178
+1: @ EG_REL
179
+ mov r2, #0x200
180
+ cmp r0, r2 @ if ( volume >= 0x200 )
181
+ movge r0, #1024
182
+ subge r0, #1
183
+ movge r3, #EG_OFF
184
+ strgeb r3, [r5,#0x17] @ state
185
+
186
+10: @ finish
187
+ ldrb r2, [r5,#0x30] @ ssg
188
+ ldrb r3, [r5,#0x17] @ state
189
+ strh r0, [r5,#0x1a] @ volume
190
+ cmp r2, #0x0c @ if ( ssg&0x04 && state > EG_REL )
191
+ cmpge r3, #EG_REL+1
192
+ ldrh r3, [r5,#0x18] @ tl
193
+ rsbge r0, r0, #0x200 @ volume = (0x200-volume) & MAX_ATT
194
+ lslge r0, r0, #22
195
+ lsrge r0, r0, #22
196
+
197
+11:
198
+#endif
199
+ add r0, r0, r3 @ volume += tl
200
+ strh r0, [r5,#0x34] @ vol_out
201
libretro-picodrive-0~git20200112.tar.xz/pico/state.c -> libretro-picodrive-0~git20200716.tar.xz/pico/state.c
Changed
32
1
2
CHECKED_WRITE_BUFF(CHUNK_ZRAM, PicoMem.zram);
3
CHECKED_WRITE_BUFF(CHUNK_CRAM, PicoMem.cram);
4
CHECKED_WRITE_BUFF(CHUNK_MISC, Pico.m);
5
+
6
+ PicoVideoSave();
7
CHECKED_WRITE_BUFF(CHUNK_VIDEO, Pico.video);
8
9
z80_pack(buff_z80);
10
11
case CHUNK_CRAM: CHECKED_READ_BUFF(PicoMem.cram); break;
12
case CHUNK_VSRAM: CHECKED_READ_BUFF(PicoMem.vsram); break;
13
case CHUNK_MISC: CHECKED_READ_BUFF(Pico.m); break;
14
- case CHUNK_VIDEO: CHECKED_READ_BUFF(Pico.video); break;
15
+ case CHUNK_VIDEO:
16
+ CHECKED_READ_BUFF(Pico.video);
17
+ PicoVideoLoad();
18
+ break;
19
+
20
case CHUNK_IOPORTS: CHECKED_READ_BUFF(PicoMem.ioports); break;
21
case CHUNK_PSG: CHECKED_READ2(28*4, sn76496_regs); break;
22
case CHUNK_FM:
23
24
z80_unpack(buff_z80);
25
26
// due to dep from 68k cycles..
27
- Pico.t.m68c_aim = Pico.t.m68c_cnt;
28
+ Pico.t.m68c_frame_start = Pico.t.m68c_aim = Pico.t.m68c_cnt;
29
if (PicoIn.AHW & PAHW_32X)
30
Pico32xStateLoaded(0);
31
if (PicoIn.AHW & PAHW_MCD)
32
libretro-picodrive-0~git20200112.tar.xz/pico/videoport.c -> libretro-picodrive-0~git20200716.tar.xz/pico/videoport.c
Changed
201
1
2
* PicoDrive
3
* (c) Copyright Dave, 2004
4
* (C) notaz, 2006-2009
5
+ * (C) kub, 2020
6
*
7
* This work is licensed under the terms of MAME license.
8
* See COPYING file in the top-level directory.
9
10
#define NEED_DMA_SOURCE
11
#include "memory.h"
12
13
-extern const unsigned char hcounts_32[];
14
-extern const unsigned char hcounts_40[];
15
+extern const unsigned char hcounts_32[], hcounts_40[];
16
+extern const unsigned char vdpcyc2sl_32_bl[], vdpcyc2sl_40_bl[];
17
+extern const unsigned char vdpcyc2sl_32[], vdpcyc2sl_40[];
18
+extern const unsigned short vdpsl2cyc_32_bl[], vdpsl2cyc_40_bl[];
19
+extern const unsigned short vdpsl2cyc_32[], vdpsl2cyc_40[];
20
21
-#ifndef UTYPES_DEFINED
22
-typedef unsigned char u8;
23
-typedef unsigned short u16;
24
-typedef unsigned int u32;
25
-#define UTYPES_DEFINED
26
-#endif
27
+static int blankline; // display disabled for this line
28
+
29
+unsigned SATaddr, SATmask; // VRAM addr of sprite attribute table
30
31
int (*PicoDmaHook)(unsigned int source, int len, unsigned short **base, unsigned int *mask) = NULL;
32
33
+
34
+/* VDP FIFO implementation
35
+ *
36
+ * fifo_slot: last slot executed in this scanline
37
+ * fifo_cnt: #slots remaining for active FIFO write (#writes<<#bytep)
38
+ * fifo_total: #total FIFO entries pending
39
+ * fifo_data: last values transferred through fifo
40
+ * fifo_queue: fifo transfer queue (#writes, flags)
41
+ *
42
+ * FIFO states: empty total=0
43
+ * inuse total>0 && total<4
44
+ * full total==4
45
+ * wait total>4
46
+ * Conditions:
47
+ * fifo_slot is always behind slot2cyc[cycles]. Advancing it beyond cycles
48
+ * implies blocking the 68k up to that slot.
49
+ *
50
+ * A FIFO write goes to the end of the FIFO queue, but DMA running in background
51
+ * is always the last queue entry (transfers by CPU intervene and come 1st).
52
+ * There can be more pending writes than FIFO slots, but the CPU will be blocked
53
+ * until FIFO level (without background DMA) <= 4.
54
+ * This is only about correct timing, data xfer must be handled by the caller.
55
+ * Blocking the CPU means burning cycles via SekCyclesBurn*(), which is to be
56
+ * executed by the caller.
57
+ *
58
+ * FIFOSync "executes" FIFO write slots up to the given cycle in the current
59
+ * scanline. A queue entry completely executed is removed from the queue.
60
+ * FIFOWrite pushes writes to the transfer queue. If it's a blocking write, 68k
61
+ * is blocked if more than 4 FIFO writes are pending.
62
+ * FIFORead executes a 68k read. 68k is blocked until the next transfer slot.
63
+ */
64
+
65
+// NB code assumes fifo_* arrays have size 2^n
66
+static struct VdpFIFO { // XXX this must go into save file!
67
+ // last transferred FIFO data, ...x = index XXX currently only CPU
68
+ unsigned short fifo_data[4], fifo_dx;
69
+
70
+ // queued FIFO transfers, ...x = index, ...l = queue length
71
+ // each entry has 2 values: [n]>>3 = #writes, [n]&7 = flags (FQ_*)
72
+ unsigned int fifo_queue[8], fifo_qx, fifo_ql;
73
+ unsigned int fifo_total; // total# of pending FIFO entries (w/o BGDMA)
74
+
75
+ unsigned short fifo_slot; // last executed slot in current scanline
76
+ unsigned short fifo_maxslot;// #slots in scanline
77
+
78
+ const unsigned char *fifo_cyc2sl;
79
+ const unsigned short *fifo_sl2cyc;
80
+} VdpFIFO;
81
+
82
+enum { FQ_BYTE = 1, FQ_BGDMA = 2, FQ_FGDMA = 4 }; // queue flags, NB: BYTE = 1!
83
+
84
+// do the FIFO math
85
+static __inline int AdvanceFIFOEntry(struct VdpFIFO *vf, struct PicoVideo *pv, int slots)
86
+{
87
+ int l = slots, b = vf->fifo_queue[vf->fifo_qx] & FQ_BYTE;
88
+ int cnt = pv->fifo_cnt;
89
+
90
+ // advance currently active FIFO entry
91
+ if (l > cnt)
92
+ l = cnt;
93
+ if (!(vf->fifo_queue[vf->fifo_qx] & FQ_BGDMA))
94
+ vf->fifo_total -= ((cnt & b) + l) >> b;
95
+ cnt -= l;
96
+
97
+ // if entry has been processed...
98
+ if (cnt == 0) {
99
+ // remove entry from FIFO
100
+ if (vf->fifo_ql) {
101
+ vf->fifo_queue[vf->fifo_qx] = 0;
102
+ vf->fifo_qx = (vf->fifo_qx+1) & 7, vf->fifo_ql --;
103
+ }
104
+ // start processing for next entry if there is one
105
+ if (vf->fifo_ql) {
106
+ b = vf->fifo_queue[vf->fifo_qx] & FQ_BYTE;
107
+ cnt = (vf->fifo_queue[vf->fifo_qx] >> 3) << b;
108
+ } else { // FIFO empty
109
+ pv->status &= ~PVS_FIFORUN;
110
+ vf->fifo_total = 0;
111
+ }
112
+ }
113
+
114
+ pv->fifo_cnt = cnt;
115
+ return l;
116
+}
117
+
118
+static __inline void SetFIFOState(struct VdpFIFO *vf, struct PicoVideo *pv)
119
+{
120
+ unsigned int st = pv->status, cmd = pv->command;
121
+ // release CPU and terminate DMA if FIFO isn't blocking the 68k anymore
122
+ if (vf->fifo_total <= 4) {
123
+ st &= ~PVS_CPUWR;
124
+ if (!(st & (PVS_DMABG|PVS_DMAFILL))) {
125
+ st &= ~SR_DMA;
126
+ cmd &= ~0x80;
127
+ }
128
+ }
129
+ if (pv->fifo_cnt == 0) {
130
+ st &= ~PVS_CPURD;
131
+ // terminate DMA if applicable
132
+ if (!(st & (PVS_FIFORUN|PVS_DMAFILL))) {
133
+ st &= ~(SR_DMA|PVS_DMABG);
134
+ cmd &= ~0x80;
135
+ }
136
+ }
137
+ pv->status = st;
138
+ pv->command = cmd;
139
+}
140
+
141
+// sync FIFO to cycles
142
+void PicoVideoFIFOSync(int cycles)
143
+{
144
+ struct VdpFIFO *vf = &VdpFIFO;
145
+ struct PicoVideo *pv = &Pico.video;
146
+ int slots, done;
147
+
148
+ // calculate #slots since last executed slot
149
+ slots = vf->fifo_cyc2sl[cycles>>1] - vf->fifo_slot;
150
+
151
+ // advance FIFO queue by #done slots
152
+ done = slots;
153
+ while (done > 0 && pv->fifo_cnt) {
154
+ int l = AdvanceFIFOEntry(vf, pv, done);
155
+ vf->fifo_slot += l;
156
+ done -= l;
157
+ }
158
+
159
+ if (done != slots)
160
+ SetFIFOState(vf, pv);
161
+}
162
+
163
+// drain FIFO, blocking 68k on the way. FIFO must be synced prior to drain.
164
+static int PicoVideoFIFODrain(int level, int cycles, int bgdma)
165
+{
166
+ struct VdpFIFO *vf = &VdpFIFO;
167
+ struct PicoVideo *pv = &Pico.video;
168
+ unsigned ocyc = cycles;
169
+ int burn = 0;
170
+//int osl = fifo_slot;
171
+
172
+ // process FIFO entries until low level is reached
173
+ while (vf->fifo_slot <= vf->fifo_maxslot && cycles < 488 &&
174
+ ((vf->fifo_total > level) | (vf->fifo_queue[vf->fifo_qx] & bgdma))) {
175
+ int b = vf->fifo_queue[vf->fifo_qx] & FQ_BYTE;
176
+ int cnt = bgdma ? pv->fifo_cnt : ((vf->fifo_total-level)<<b) - (pv->fifo_cnt&b);
177
+ int slot = (pv->fifo_cnt<cnt ? pv->fifo_cnt:cnt) + vf->fifo_slot;
178
+
179
+ if (slot > vf->fifo_maxslot) {
180
+ // target slot in later scanline, advance to eol
181
+ slot = vf->fifo_maxslot;
182
+ cycles = 488;
183
+ } else {
184
+ // advance FIFO to target slot and CPU to cycles at that slot
185
+ cycles = vf->fifo_sl2cyc[slot]<<1;
186
+ }
187
+ if (slot > vf->fifo_slot) {
188
+ AdvanceFIFOEntry(vf, pv, slot - vf->fifo_slot);
189
+ vf->fifo_slot = slot;
190
+ }
191
+ }
192
+ if (cycles > ocyc)
193
+ burn = cycles - ocyc;
194
+
195
+ SetFIFOState(vf, pv);
196
+
197
+ return burn;
198
+}
199
+
200
+// read VDP data port
201
libretro-picodrive-0~git20200112.tar.xz/platform/common/arm_utils.s -> libretro-picodrive-0~git20200716.tar.xz/platform/common/arm_utils.s
Changed
9
1
2
movne lr, #64
3
tstne r3, r3
4
addne r0, r0, #32
5
+ addne r1, r1, #32
6
7
vidCpyM2_loop_out:
8
mov r6, #10
9
libretro-picodrive-0~git20200112.tar.xz/platform/common/common.mak -> libretro-picodrive-0~git20200716.tar.xz/platform/common/common.mak
Changed
80
1
2
asm_ym2612 = 0
3
asm_misc = 0
4
asm_cdmemory = 0
5
+asm_32xdraw = 0
6
+asm_32xmemory = 0
7
asm_mix = 0
8
endif
9
10
11
DEFINES += PPROF
12
SRCS_COMMON += $(R)platform/linux/pprof.c
13
endif
14
+ifeq "$(gperf)" "1"
15
+DEFINES += GPERF
16
+LDFLAGS += -lprofiler -lstdc++
17
+endif
18
19
# ARM asm stuff
20
ifeq "$(ARCH)" "arm"
21
22
endif
23
ifeq "$(asm_ym2612)" "1"
24
DEFINES += _ASM_YM2612_C
25
-SRCS_COMMON += $(R)pico/sound/ym2612_arm.s
26
+SRCS_COMMON += $(R)pico/sound/ym2612_arm.S
27
endif
28
ifeq "$(asm_misc)" "1"
29
DEFINES += _ASM_MISC_C
30
31
endif
32
ifeq "$(asm_32xdraw)" "1"
33
DEFINES += _ASM_32X_DRAW
34
-SRCS_COMMON += $(R)pico/32x/draw_arm.s
35
+SRCS_COMMON += $(R)pico/32x/draw_arm.S
36
+endif
37
+ifeq "$(asm_32xmemory)" "1"
38
+DEFINES += _ASM_32X_MEMORY_C
39
+SRCS_COMMON += $(R)pico/32x/memory_arm.S
40
endif
41
ifeq "$(asm_mix)" "1"
42
SRCS_COMMON += $(R)pico/sound/mix_arm.S
43
44
# --- Z80 ---
45
ifeq "$(use_drz80)" "1"
46
DEFINES += _USE_DRZ80
47
-SRCS_COMMON += $(R)cpu/DrZ80/drz80.s
48
+SRCS_COMMON += $(R)cpu/DrZ80/drz80.S
49
endif
50
#
51
ifeq "$(use_cz80)" "1"
52
53
ifdef drc_debug
54
DEFINES += DRC_DEBUG=$(drc_debug)
55
SRCS_COMMON += $(R)cpu/sh2/mame/sh2dasm.c
56
-SRCS_COMMON += $(R)platform/libpicofe/linux/host_dasm.c
57
-LDFLAGS += -lbfd -lopcodes -liberty
58
+DASM = $(R)platform/libpicofe/linux/host_dasm.c
59
+DASMLIBS = -lbfd -lopcodes -liberty
60
+ifeq ("$(ARCH)",$(filter "$(ARCH)","arm" "mipsel"))
61
+ifeq ($(filter_out $(shell $(CC) --print-file-name=libbfd.so),"/"),)
62
+DASM = $(R)platform/common/host_dasm.c
63
+DASMLIBS =
64
+endif
65
+endif
66
+SRCS_COMMON += $(DASM)
67
+LDFLAGS += $(DASMLIBS)
68
endif
69
endif # use_sh2drc
70
SRCS_COMMON += $(R)cpu/sh2/mame/sh2pico.c
71
72
73
$(FR)cpu/cyclone/Cyclone.s: $(FR)cpu/$(CYCLONE_CONFIG)
74
@echo building Cyclone...
75
- @make CC=$(CYCLONE_CC) CXX=$(CYCLONE_CXX) -C $(R)cpu/cyclone/ CONFIG_FILE=../$(CYCLONE_CONFIG)
76
+ @make CC=$(CYCLONE_CC) CXX=$(CYCLONE_CXX) -C $(R)cpu/cyclone/ CONFIG_FILE=../$(CYCLONE_CONFIG) HAVE_ARMv6=$(HAVE_ARMv6)
77
78
$(FR)cpu/cyclone/Cyclone.s: $(FR)cpu/cyclone/*.cpp $(FR)cpu/cyclone/*.h
79
80
libretro-picodrive-0~git20200112.tar.xz/platform/common/config_file.c -> libretro-picodrive-0~git20200716.tar.xz/platform/common/config_file.c
Changed
57
1
2
3
static int seek_sect(FILE *f, const char *section)
4
{
5
- char line[128], *tmp;
6
+ char line[640], *tmp;
7
int len;
8
9
len = strlen(section);
10
11
FILE *fn = NULL;
12
menu_entry *me;
13
int t;
14
- char line[128];
15
+ char line[640];
16
17
fn = fopen(fname, "w");
18
if (fn == NULL)
19
20
21
int config_writelrom(const char *fname)
22
{
23
- char line[128], *tmp, *optr = NULL;
24
+ char line[640], *tmp, *optr = NULL;
25
char *old_data = NULL;
26
int size;
27
FILE *f;
28
29
30
int config_readlrom(const char *fname)
31
{
32
- char line[128], *tmp;
33
+ char line[640], *tmp;
34
int i, len, ret = -1;
35
FILE *f;
36
37
38
currentConfig.gamma = atoi(val);
39
return 1;
40
41
+ case MA_OPT2_MAX_FRAMESKIP:
42
+ currentConfig.max_skip = atoi(val);
43
+ return 1;
44
+
45
/* PSP */
46
case MA_OPT3_SCALE:
47
if (strcasecmp(var, "Scale factor") != 0) return 0;
48
49
50
int config_readsect(const char *fname, const char *section)
51
{
52
- char line[128], *var, *val;
53
+ char line[640], *var, *val;
54
int keys_encountered = 0;
55
FILE *f;
56
int ret;
57
libretro-picodrive-0~git20200716.tar.xz/platform/common/disarm.c
Added
201
1
2
+/*
3
+ * Copyright (c) 2012 Wojtek Kaniewski <wojtekka@toxygen.net>
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to
7
+ * deal in the Software without restriction, including without limitation the
8
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9
+ * sell copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in
13
+ * all copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ * IN THE SOFTWARE.
22
+ */
23
+
24
+#include <stdio.h>
25
+#include <string.h>
26
+
27
+#define IMM_FORMAT "0x%x"
28
+//#define IMM_FORMAT "%d"
29
+#define ADDR_FORMAT "0x%x"
30
+
31
+static inline unsigned int rol(unsigned int value, unsigned int shift)
32
+{
33
+ shift &= 31;
34
+
35
+ return (value >> shift) | (value << (32 - shift));
36
+}
37
+
38
+static inline const char *condition(unsigned int insn)
39
+{
40
+ const char *conditions[16] = { "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "", "nv" };
41
+ return conditions[(insn >> 28) & 0x0f];
42
+}
43
+
44
+static inline const char *register_name(unsigned int reg)
45
+{
46
+ const char *register_names[16] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" };
47
+ return register_names[reg & 0x0f];
48
+}
49
+
50
+static const char *register_list(unsigned int list, char *buf, size_t buf_len)
51
+{
52
+ int i;
53
+
54
+ buf[0] = 0;
55
+
56
+ for (i = 0; i < 16; i++)
57
+ {
58
+ if ((list >> i) & 1)
59
+ {
60
+ snprintf(buf + strlen(buf), buf_len - strlen(buf), "%s%s", (buf[0] == 0) ? "" : ",", register_name(i));
61
+ }
62
+ }
63
+
64
+ return buf;
65
+}
66
+
67
+static const char *shift(unsigned int insn, char *buf, size_t buf_len)
68
+{
69
+ unsigned int imm = (insn >> 7) & 0x1f;
70
+ const char *rn = register_name(insn >> 8);
71
+ unsigned int type = (insn >> 4) & 0x07;
72
+
73
+ switch (type)
74
+ {
75
+ case 0:
76
+ snprintf(buf, buf_len, (imm != 0) ? ",lsl #%d" : "", imm);
77
+ break;
78
+ case 1:
79
+ snprintf(buf, buf_len, ",lsl %s", rn);
80
+ break;
81
+ case 2:
82
+ snprintf(buf, buf_len, ",lsr #%d", imm ? imm : 32);
83
+ break;
84
+ case 3:
85
+ snprintf(buf, buf_len, ",lsr %s", rn);
86
+ break;
87
+ case 4:
88
+ snprintf(buf, buf_len, ",asr #%d", imm ? imm : 32);
89
+ break;
90
+ case 5:
91
+ snprintf(buf, buf_len, ",asr %s", rn);
92
+ break;
93
+ case 6:
94
+ snprintf(buf, buf_len, (imm != 0) ? ",ror #%d" : ",rrx", imm);
95
+ break;
96
+ case 7:
97
+ snprintf(buf, buf_len, ",ror %s", rn);
98
+ break;
99
+ }
100
+
101
+ return buf;
102
+}
103
+
104
+static const char *immediate(unsigned int imm, int negative, int show_if_zero, char *buf, size_t buf_len)
105
+{
106
+ if (imm || show_if_zero)
107
+ {
108
+ snprintf(buf, buf_len, ",#%s" IMM_FORMAT, (negative) ? "-" : "", imm);
109
+ return buf;
110
+ }
111
+
112
+ return "";
113
+}
114
+
115
+static int data_processing(unsigned int pc, unsigned int insn, char *buf, size_t buf_len)
116
+{
117
+ unsigned int oper = (insn >> 21) & 15;
118
+ const char *names[16] = { "and", "eor", "sub", "rsb", "add", "adc", "sbc", "rsc", "tst", "teq", "cmp", "cmn", "orr", "mov", "bic", "mvn" };
119
+ const char *name;
120
+ const char *s;
121
+ unsigned int rd;
122
+ unsigned int rn;
123
+ int is_move = ((oper == 13) || (oper == 15));
124
+ int is_test = ((oper >= 8) && (oper <= 11));
125
+ char tmp_buf[64];
126
+
127
+ name = names[oper];
128
+ s = ((insn >> 20) & 1) ? "s" : "";
129
+ rn = (insn >> 16) & 15;
130
+ rd = (insn >> 12) & 15;
131
+
132
+ /* mov r0,r0,r0 is a nop */
133
+ if (insn == 0xe1a00000)
134
+ {
135
+ snprintf(buf, buf_len, "nop");
136
+ return 1;
137
+ }
138
+
139
+ /* mrs */
140
+ if ((insn & 0x0fbf0fff) == 0x010f0000)
141
+ {
142
+ const char *psr = ((insn >> 22) & 1) ? "spsr" : "cpsr";
143
+ const char *rd = register_name(insn >> 12);
144
+
145
+ snprintf(buf, buf_len, "mrs%s %s,%s", condition(insn), rd, psr);
146
+
147
+ return 1;
148
+ }
149
+
150
+ /* msr flag only*/
151
+ if ((insn & 0x0db0f000) == 0x0120f000)
152
+ {
153
+ const char *psr = ((insn >> 22) & 1) ? "spsr" : "cpsr";
154
+ const char *suffix;
155
+
156
+ switch ((insn >> 16) & 15)
157
+ {
158
+ case 9:
159
+ suffix = "";
160
+ break;
161
+ case 8:
162
+ suffix = "_f";
163
+ break;
164
+ case 1:
165
+ suffix = "_c";
166
+ break;
167
+ default:
168
+ return 0;
169
+ }
170
+
171
+ if ((insn >> 25) & 1)
172
+ {
173
+ unsigned int imm = rol(insn & 0x000000ff, ((insn >> 8) & 15) * 2);
174
+
175
+ snprintf(buf, buf_len, "msr%s %s%s,#" IMM_FORMAT, condition(insn), psr, suffix, imm);
176
+ }
177
+ else
178
+ {
179
+ const char *rm = register_name(insn >> 0);
180
+
181
+ if (((insn >> 4) & 255) != 0)
182
+ {
183
+ return 0;
184
+ }
185
+
186
+ snprintf(buf, buf_len, "msr%s %s%s,%s", condition(insn), psr, suffix, rm);
187
+ }
188
+
189
+ return 1;
190
+ }
191
+
192
+ if (((insn >> 25) & 1) == 0)
193
+ {
194
+ unsigned int rm;
195
+
196
+ rm = (insn & 15);
197
+
198
+ if (is_move)
199
+ {
200
+ snprintf(buf, buf_len, "%s%s%s %s,%s%s", name, condition(insn), s, register_name(rd), register_name(rm), shift(insn, tmp_buf, sizeof(tmp_buf)));
201
libretro-picodrive-0~git20200716.tar.xz/platform/common/disarm.h
Added
30
1
2
+/*
3
+ * Copyright (C) 2012 Wojtek Kaniewski <wojtekka@toxygen.net>
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to
7
+ * deal in the Software without restriction, including without limitation the
8
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9
+ * sell copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in
13
+ * all copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ * IN THE SOFTWARE.
22
+ */
23
+
24
+#ifndef DISARM_H
25
+#define DISARM_H
26
+
27
+int disarm(uintptr_t pc, uint32_t insn, char *buf, size_t buf_len, unsigned long *sym);
28
+
29
+#endif /* DISARM_H */
30
libretro-picodrive-0~git20200716.tar.xz/platform/common/dismips.c
Added
201
1
2
+/*
3
+ * very basic mips disassembler for MIPS32/MIPS64 Release 2, only for picodrive
4
+ * Copyright (C) 2019 kub
5
+ *
6
+ * This work is licensed under the terms of MAME license.
7
+ * See COPYING file in the top-level directory.
8
+ */
9
+
10
+// unimplemented insns: MOV[FT], SYSCALL, BREAK, SYNC, SYNCI, T*, SDBBP, RDHWR,
11
+// CACHE, PREF, LWC*/LDC*, SWC*/SDC*, and all of COP* (fpu, mmu, irq, exc, ...)
12
+// unimplemented variants of insns: EHB, SSNOP (both SLL zero), JALR.HB, JR.HB
13
+// however, it's certainly good enough for anything picodrive DRC throws at it.
14
+
15
+#include <stdio.h>
16
+#include <stdlib.h>
17
+#include <stdint.h>
18
+#include <string.h>
19
+
20
+#include "dismips.h"
21
+
22
+
23
+static char *const register_names[32] = {
24
+ "$zero",
25
+ "$at",
26
+ "$v0",
27
+ "$v1",
28
+ "$a0",
29
+ "$a1",
30
+ "$a2",
31
+ "$a3",
32
+ "$t0",
33
+ "$t1",
34
+ "$t2",
35
+ "$t3",
36
+ "$t4",
37
+ "$t5",
38
+ "$t6",
39
+ "$t7",
40
+ "$s0",
41
+ "$s1",
42
+ "$s2",
43
+ "$s3",
44
+ "$s4",
45
+ "$s5",
46
+ "$s6",
47
+ "$s7",
48
+ "$t8",
49
+ "$t9",
50
+ "$k0",
51
+ "$k1",
52
+ "$gp",
53
+ "$sp",
54
+ "$fp",
55
+ "$ra"
56
+};
57
+
58
+
59
+enum insn_type {
60
+ REG_DTS, REG_TS, // 3, 2, or 1 regs
61
+ REG_DS, REG_DT, REG_D, REG_S,
62
+ S_IMM_DT, // 2 regs with shift amount
63
+ F_IMM_TS, // 2 regs with bitfield spec
64
+ B_IMM_S, B_IMM_TS, // pc-relative branches with 1 or 2 regs
65
+ J_IMM, // region-relative jump
66
+ A_IMM_TS, // arithmetic immediate with 2 regs
67
+ L_IMM_T, L_IMM_TS, // logical immediate with 1 or 2 regs
68
+ M_IMM_TS, // memory indexed with 2 regs
69
+ SR_BIT = 0x80 // shift right with R-bit
70
+};
71
+
72
+struct insn {
73
+ unsigned char op;
74
+ enum insn_type type;
75
+ char *name;
76
+};
77
+
78
+// ATTN: these array MUST be sorted by op (decode relies on it)
79
+
80
+// instructions with opcode SPECIAL (R-type)
81
+#define OP_SPECIAL 0x00
82
+static const struct insn special_insns[] = {
83
+ {0x00, S_IMM_DT, "sll"},
84
+// {0x01, , "movf\0movt"},
85
+ {0x02, S_IMM_DT|SR_BIT, "srl\0rotr"},
86
+ {0x03, S_IMM_DT, "sra"},
87
+ {0x04, REG_DTS, "sllv"},
88
+ {0x06, REG_DTS|SR_BIT, "srlv\0rotrv"},
89
+ {0x07, REG_DTS, "srav"},
90
+ {0x08, REG_S, "jr"},
91
+ {0x09, REG_DS, "jalr"},
92
+ {0x0a, REG_DTS, "movz"},
93
+ {0x0b, REG_DTS, "movn"},
94
+// {0x0c, , "syscall"},
95
+// {0x0d, , "break"},
96
+// {0x0f, , "sync"},
97
+ {0x10, REG_D, "mfhi"},
98
+ {0x11, REG_S, "mthi"},
99
+ {0x12, REG_D, "mflo"},
100
+ {0x13, REG_S, "mtlo"},
101
+ {0x14, REG_DTS, "dsllv"},
102
+ {0x16, REG_DTS|SR_BIT, "dsrlv\0drotrv"},
103
+ {0x17, REG_DTS, "dsrav"},
104
+ {0x18, REG_TS, "mult"},
105
+ {0x19, REG_TS, "multu"},
106
+ {0x1A, REG_TS, "div"},
107
+ {0x1B, REG_TS, "divu"},
108
+ {0x1C, REG_TS, "dmult"},
109
+ {0x1D, REG_TS, "dmultu"},
110
+ {0x1E, REG_TS, "ddiv"},
111
+ {0x1F, REG_TS, "ddivu"},
112
+ {0x20, REG_DTS, "add"},
113
+ {0x21, REG_DTS, "addu"},
114
+ {0x22, REG_DTS, "sub"},
115
+ {0x23, REG_DTS, "subu"},
116
+ {0x24, REG_DTS, "and"},
117
+ {0x25, REG_DTS, "or"},
118
+ {0x26, REG_DTS, "xor"},
119
+ {0x27, REG_DTS, "nor"},
120
+ {0x2A, REG_DTS, "slt"},
121
+ {0x2B, REG_DTS, "sltu"},
122
+ {0x2C, REG_DTS, "dadd"},
123
+ {0x2D, REG_DTS, "daddu"},
124
+ {0x2E, REG_DTS, "dsub"},
125
+ {0x2F, REG_DTS, "dsubu"},
126
+// {0x30, REG_TS, "tge" },
127
+// {0x31, REG_TS, "tgeu" },
128
+// {0x32, REG_TS, "tlt" },
129
+// {0x33, REG_TS, "tltu" },
130
+// {0x34, REG_TS, "teq" },
131
+// {0x36, REG_TS, "tne" },
132
+ {0x38, S_IMM_DT, "dsll"},
133
+ {0x3A, S_IMM_DT|SR_BIT, "dsrl\0drotrv"},
134
+ {0x3B, S_IMM_DT, "dsra"},
135
+ {0x3C, S_IMM_DT, "dsll32"},
136
+ {0x3E, S_IMM_DT|SR_BIT, "dsrl32\0drotr32"},
137
+ {0x3F, S_IMM_DT, "dsra32"},
138
+};
139
+
140
+// instructions with opcode SPECIAL2 (R-type)
141
+#define OP_SPECIAL2 0x1C
142
+static const struct insn special2_insns[] = {
143
+ {0x00, REG_TS, "madd" },
144
+ {0x01, REG_TS, "maddu" },
145
+ {0x02, REG_TS, "mul" },
146
+ {0x04, REG_TS, "msub" },
147
+ {0x05, REG_TS, "msubu" },
148
+ {0x20, REG_DS, "clz" },
149
+ {0x21, REG_DS, "clo" },
150
+ {0x24, REG_DS, "dclz" },
151
+ {0x25, REG_DS, "dclo" },
152
+// {0x37, , "sdbbp" },
153
+};
154
+
155
+// instructions with opcode SPECIAL3 (R-type)
156
+#define OP_SPECIAL3 0x1F
157
+static const struct insn special3_insns[] = {
158
+ {0x00, F_IMM_TS, "ext" },
159
+ {0x01, F_IMM_TS, "dextm" },
160
+ {0x02, F_IMM_TS, "dextu" },
161
+ {0x03, F_IMM_TS, "dext" },
162
+ {0x04, F_IMM_TS, "ins" },
163
+ {0x05, F_IMM_TS, "dinsm" },
164
+ {0x06, F_IMM_TS, "dinsu" },
165
+ {0x07, F_IMM_TS, "dins" },
166
+// {0x3b, , "rdhwr" },
167
+};
168
+
169
+// instruction with opcode SPECIAL3 and function *BSHFL
170
+#define FN_BSHFL 0x20
171
+static const struct insn bshfl_insns[] = {
172
+ {0x02, REG_DT, "wsbh" },
173
+ {0x10, REG_DT, "seb" },
174
+ {0x18, REG_DT, "seh" },
175
+};
176
+#define FN_DBSHFL 0x24
177
+static const struct insn dbshfl_insns[] = {
178
+ {0x02, REG_DT, "dsbh" },
179
+ {0x05, REG_DT, "dshd" },
180
+};
181
+
182
+// instructions with opcode REGIMM (I-type)
183
+#define OP_REGIMM 0x01
184
+static const struct insn regimm_insns[] = {
185
+ {0x00, B_IMM_S, "bltz"},
186
+ {0x01, B_IMM_S, "bgez"},
187
+ {0x02, B_IMM_S, "bltzl"},
188
+ {0x03, B_IMM_S, "bgezl"},
189
+// {0x08, , "tgei"},
190
+// {0x09, , "tgeiu"},
191
+// {0x0a, , "tlti"},
192
+// {0x0b, , "tltiu"},
193
+// {0x0c, , "teqi"},
194
+// {0x0e, , "tnei"},
195
+ {0x10, B_IMM_S, "bltzal"},
196
+ {0x11, B_IMM_S, "bgezal"},
197
+ {0x12, B_IMM_S, "bltzall"},
198
+ {0x13, B_IMM_S, "bgezall"},
199
+ {0x13, B_IMM_S, "bgezall"},
200
+// {0x1f, , "synci" },
201
libretro-picodrive-0~git20200716.tar.xz/platform/common/dismips.h
Added
8
1
2
+#ifndef DISMIPS_H
3
+#define DISMIPS_H
4
+
5
+int dismips(uintptr_t pc, uint32_t insn, char *buf, size_t buf_len, unsigned long *sym);
6
+
7
+#endif /* DISMIPS_H */
8
libretro-picodrive-0~git20200112.tar.xz/platform/common/emu.c -> libretro-picodrive-0~git20200716.tar.xz/platform/common/emu.c
Changed
40
1
2
defaultConfig.turbo_rate = 15;
3
defaultConfig.msh2_khz = PICO_MSH2_HZ / 1000;
4
defaultConfig.ssh2_khz = PICO_SSH2_HZ / 1000;
5
+ defaultConfig.max_skip = 4;
6
7
// platform specific overrides
8
pemu_prep_defconfig();
9
10
{
11
notice_msg_time = 0;
12
plat_status_msg_clear();
13
+#ifndef __GP2X__
14
plat_video_flip();
15
plat_status_msg_clear(); /* Do it again in case of double buffering */
16
+#endif
17
notice_msg = NULL;
18
}
19
else {
20
21
else if (diff < -target_frametime_x3)
22
{
23
/* no time left for this frame - skip */
24
- /* limit auto frameskip to 8 */
25
- if (frames_done / 8 <= frames_shown)
26
+ /* limit auto frameskip to max_skip */
27
+ if (fskip_cnt < currentConfig.max_skip) {
28
+ fskip_cnt++;
29
skip = 1;
30
- }
31
+ }
32
+ else {
33
+ fskip_cnt = 0;
34
+ }
35
+ } else
36
+ fskip_cnt = 0;
37
38
// don't go in debt too much
39
while (diff < -target_frametime_x3 * 3) {
40
libretro-picodrive-0~git20200112.tar.xz/platform/common/emu.h -> libretro-picodrive-0~git20200716.tar.xz/platform/common/emu.h
Changed
9
1
2
int msh2_khz;
3
int ssh2_khz;
4
int overclock_68k;
5
+ int max_skip;
6
} currentConfig_t;
7
8
extern currentConfig_t currentConfig, defaultConfig;
9
libretro-picodrive-0~git20200716.tar.xz/platform/common/helix
Added
2
1
+(directory)
2
libretro-picodrive-0~git20200716.tar.xz/platform/common/helix/Makefile
Added
45
1
2
+CROSS ?= arm-linux-gnueabi-
3
+
4
+CC = $(CROSS)gcc
5
+AS = $(CROSS)as
6
+AR = $(CROSS)ar
7
+TOOLCHAIN = $(notdir $(CROSS))
8
+LIBGCC ?= ${HOME}/opt/open2x/gcc-4.1.1-glibc-2.3.6/lib/gcc/arm-open2x-linux/4.1.1/libgcc.a
9
+
10
+CFLAGS += -Ipub -O2 -Wall -fstrict-aliasing -ffast-math
11
+ifneq ($(findstring arm-,$(TOOLCHAIN)),)
12
+CFLAGS += -mcpu=arm940t -mtune=arm940t -mfloat-abi=soft -mfpu=fpa -mabi=apcs-gnu -mno-thumb-interwork
13
+ASFLAGS = -mcpu=arm940t -mfloat-abi=soft -mfpu=fpa -mabi=apcs-gnu
14
+OBJS += real/arm/asmpoly_gcc.o
15
+else
16
+CFLAGS += -m32
17
+ASFLAGS += -m32
18
+OBJS += real/polyphase.o
19
+endif
20
+
21
+LIB = $(TOOLCHAIN)helix_mp3.a
22
+SHLIB = $(TOOLCHAIN)helix_mp3.so
23
+
24
+all: $(LIB) $(SHLIB)
25
+
26
+
27
+OBJS += mp3dec.o mp3tabs.o
28
+#OBJS += ipp/bitstream.o ipp/buffers.o ipp/dequant.o ipp/huffman.o ipp/imdct.o ipp/subband.o
29
+OBJS += real/bitstream.o real/buffers.o real/dct32.o real/dequant.o real/dqchan.o real/huffman.o
30
+OBJS += real/hufftabs.o real/imdct.o real/scalfact.o real/stproc.o real/subband.o real/trigtabs.o
31
+
32
+OBJS += lib.o
33
+
34
+real/arm/asmpoly_gcc.o: real/arm/asmpoly_gcc.s
35
+ $(CC) -o $@ $(ASFLAGS) -c $<
36
+
37
+$(LIB) : $(OBJS)
38
+ $(AR) r $@ $^
39
+$(SHLIB) : $(OBJS) $(LIBGCC)
40
+ $(CC) -o $@ -nostdlib -shared $(CFLAGS) $^
41
+
42
+clean:
43
+ $(RM) -f $(OBJS)
44
+
45
libretro-picodrive-0~git20200716.tar.xz/platform/common/helix/lib.c
Added
59
1
2
+#include <stdlib.h>
3
+#include <stdint.h>
4
+
5
+// libgcc has this with gcc 4.x
6
+void raise(int sig)
7
+{
8
+}
9
+
10
+// very limited heap functions for helix decoder
11
+
12
+static char heap[65000] __attribute__((aligned(16)));
13
+static long heap_offs;
14
+
15
+void __malloc_init(void)
16
+{
17
+ heap_offs = 0;
18
+}
19
+
20
+void *malloc(size_t size)
21
+{
22
+ void *chunk = heap + heap_offs;
23
+ size = (size+15) & ~15;
24
+ if (heap_offs + size > sizeof(heap))
25
+ return NULL;
26
+ else {
27
+ heap_offs += size;
28
+ return chunk;
29
+ }
30
+}
31
+
32
+void free(void *chunk)
33
+{
34
+ if (chunk == heap)
35
+ heap_offs = 0;
36
+}
37
+
38
+#if 0
39
+void *memcpy (void *dest, const void *src, size_t n)
40
+{
41
+ char *_dest = dest;
42
+ const char *_src = src;
43
+ while (n--) *_dest++ = *_src++;
44
+ return dest;
45
+}
46
+
47
+void *memmove (void *dest, const void *src, size_t n)
48
+{
49
+ char *_dest = dest+n;
50
+ const char *_src = src+n;
51
+ if (dest <= src || dest >= _src)
52
+ return memcpy(dest, src, n);
53
+ while (n--) *--_dest = *--_src;
54
+ return dest;
55
+}
56
+#else
57
+#include "../memcpy.c"
58
+#endif
59
libretro-picodrive-0~git20200716.tar.xz/platform/common/host_dasm.c
Added
95
1
2
+/*
3
+ * DRC host disassembler interface for MIPS/ARM32 for use without binutils
4
+ * (C) kub, 2018,2019
5
+ */
6
+#include <stdio.h>
7
+#include <stdlib.h>
8
+#include <stdint.h>
9
+#include <string.h>
10
+
11
+#ifdef __mips__
12
+#include "dismips.c"
13
+#define disasm dismips
14
+#else
15
+#include "disarm.c"
16
+#define disasm disarm
17
+#endif
18
+
19
+/* symbols */
20
+typedef struct { const char *name; void *value; } asymbol;
21
+
22
+static asymbol **symbols;
23
+static long symcount, symstorage = 8;
24
+
25
+static const char *lookup_name(void *addr)
26
+{
27
+ asymbol **sptr = symbols;
28
+ int i;
29
+
30
+ for (i = 0; i < symcount; i++) {
31
+ asymbol *sym = *sptr++;
32
+
33
+ if (addr == sym->value)
34
+ return sym->name;
35
+ }
36
+
37
+ return NULL;
38
+}
39
+
40
+void host_dasm(void *addr, int len)
41
+{
42
+ void *end = (char *)addr + len;
43
+ const char *name;
44
+ char buf[64];
45
+ unsigned long insn, symaddr;
46
+
47
+ while (addr < end) {
48
+ name = lookup_name(addr);
49
+ if (name != NULL)
50
+ printf("%s:\n", name);
51
+
52
+ insn = *(unsigned long *)addr;
53
+ printf(" %08lx %08lx ", (long)addr, insn);
54
+ if(disasm((unsigned)addr, insn, buf, sizeof(buf), &symaddr))
55
+ {
56
+ if (symaddr)
57
+ name = lookup_name((void *)symaddr);
58
+ if (symaddr && name)
59
+ printf("%s <%s>\n", buf, name);
60
+ else if (symaddr && !name)
61
+ printf("%s <unknown>\n", buf);
62
+ else
63
+ printf("%s\n", buf);
64
+ } else
65
+ printf("unknown (0x%08lx)\n", insn);
66
+ addr = (char *)addr + sizeof(long);
67
+ }
68
+}
69
+
70
+void host_dasm_new_symbol_(void *addr, const char *name)
71
+{
72
+ asymbol *sym, **tmp;
73
+
74
+ if (symbols == NULL)
75
+ symbols = malloc(symstorage);
76
+ if (symstorage <= symcount * sizeof(symbols[0])) {
77
+ tmp = realloc(symbols, symstorage * 2);
78
+ if (tmp == NULL)
79
+ return;
80
+ symstorage *= 2;
81
+ symbols = tmp;
82
+ }
83
+
84
+ symbols[symcount] = calloc(sizeof(*symbols[0]), 1);
85
+ if (symbols[symcount] == NULL)
86
+ return;
87
+
88
+ // a HACK (should use correct section), but ohwell
89
+ sym = symbols[symcount];
90
+ sym->value = addr;
91
+ sym->name = name;
92
+ symcount++;
93
+}
94
+
95
libretro-picodrive-0~git20200112.tar.xz/platform/common/main.c -> libretro-picodrive-0~git20200716.tar.xz/platform/common/main.c
Changed
22
1
2
emu_init();
3
menu_init();
4
5
+#ifdef GPERF
6
+ ProfilerStart("gperf.out");
7
+#endif
8
+
9
engineState = PGS_Menu;
10
11
if (argc > 1)
12
13
}
14
15
endloop:
16
+#ifdef GPERF
17
+ ProfilerStop();
18
+#endif
19
20
emu_finish();
21
plat_finish();
22
libretro-picodrive-0~git20200716.tar.xz/platform/common/memcpy.c
Added
136
1
2
+/*
3
+ * (C) 2018 Kai-Uwe Bloem <derkub@gmail.com>
4
+ *
5
+ * 32bit ARM/MIPS optimized C implementation of memcpy and memove, designed for
6
+ * good performance with gcc.
7
+ * - if src and dest have the same alignment, 4-word copy is used.
8
+ * - if src and dest are unaligned to each other, still loads word data and
9
+ * stores correctly shifted word data (for all but the first and last bytes
10
+ * to avoid under/overstepping the src region).
11
+ *
12
+ * ATTN does dirty aliasing tricks with undefined behaviour by standard.
13
+ * (however, this improved the generated code).
14
+ * ATTN uses struct assignment, which only works if the compiler is inlining
15
+ * this (else it would probably call memcpy :-)).
16
+ */
17
+#include <stdlib.h>
18
+#include <stdint.h>
19
+
20
+#include <endian.h>
21
+#if __BYTE_ORDER == __LITTLE_ENDIAN
22
+#define _L_ >>
23
+#define _U_ <<
24
+#else
25
+#define _L_ <<
26
+#define _U_ >>
27
+#endif
28
+
29
+void *memcpy(void *dest, const void *src, size_t n)
30
+{
31
+ struct _16 { uint32_t a[4]; };
32
+ union { const void *v; uint8_t *c; uint32_t *i; uint64_t *l; struct _16 *s; }
33
+ ss = { src }, ds = { dest };
34
+ const int lm = sizeof(uint32_t)-1;
35
+
36
+ /* align src to word */
37
+ while (((uintptr_t)ss.c & lm) && n > 0)
38
+ *ds.c++ = *ss.c++, n--;
39
+ if (((uintptr_t)ds.c & lm) == 0) {
40
+ /* fast copy if pointers have the same aligment */
41
+ while (n >= sizeof(struct _16)) /* copy 16 byte blocks */
42
+ *ds.s++ = *ss.s++, n -= sizeof(struct _16);
43
+ if (n >= sizeof(uint64_t)) /* copy leftover 8 byte block */
44
+ *ds.l++ = *ss.l++, n -= sizeof(uint64_t);
45
+// if (n >= sizeof(uint32_t)) /* copy leftover 4 byte block */
46
+// *ds.i++ = *ss.i++, n -= sizeof(uint32_t);
47
+ } else if (n >= 2*sizeof(uint32_t)) {
48
+ /* unaligned data big enough to avoid overstepping src */
49
+ uint32_t v1, v2, b, s;
50
+ /* align dest to word */
51
+ while (((uintptr_t)ds.c & lm) && n > 0)
52
+ *ds.c++ = *ss.c++, n--;
53
+ /* copy loop: load aligned words and store shifted words */
54
+ b = (uintptr_t)ss.c & lm, s = b*8; ss.c -= b;
55
+ v1 = *ss.i++, v2 = *ss.i++;
56
+ while (n >= 3*sizeof(uint32_t)) {
57
+ *ds.i++ = (v1 _L_ s) | (v2 _U_ (32-s)); v1 = *ss.i++;
58
+ *ds.i++ = (v2 _L_ s) | (v1 _U_ (32-s)); v2 = *ss.i++;
59
+ n -= 2*sizeof(uint32_t);
60
+ }
61
+ /* data for one more store is already loaded */
62
+ if (n >= sizeof(uint32_t)) {
63
+ *ds.i++ = (v1 _L_ s) | (v2 _U_ (32-s));
64
+ n -= sizeof(uint32_t);
65
+ ss.c += sizeof(uint32_t);
66
+ }
67
+ ss.c += b - 2*sizeof(uint32_t);
68
+ }
69
+ /* copy 0-7 leftover bytes */
70
+ while (n >= 4) {
71
+ *ds.c++ = *ss.c++, n--; *ds.c++ = *ss.c++, n--;
72
+ *ds.c++ = *ss.c++, n--; *ds.c++ = *ss.c++, n--;
73
+ }
74
+ while (n > 0)
75
+ *ds.c++ = *ss.c++, n--;
76
+ return dest;
77
+}
78
+
79
+void *memmove (void *dest, const void *src, size_t n)
80
+{
81
+ struct _16 { uint32_t a[4]; };
82
+ union { const void *v; uint8_t *c; uint32_t *i; uint64_t *l; struct _16 *s; }
83
+ ss = { src+n }, ds = { dest+n };
84
+ size_t pd = dest > src ? dest - src : src - dest;
85
+ const int lm = sizeof(uint32_t)-1;
86
+
87
+ if (dest <= src || dest >= src+n)
88
+ return memcpy(dest, src, n);
89
+
90
+ /* align src to word */
91
+ while (((uintptr_t)ss.c & lm) && n > 0)
92
+ *--ds.c = *--ss.c, n--;
93
+ /* take care not to copy multi-byte data if it overlaps */
94
+ if (((uintptr_t)ds.c & lm) == 0) {
95
+ /* fast copy if pointers have the same aligment */
96
+ while (n >= sizeof(struct _16) && pd >= sizeof(struct _16))
97
+ /* copy 16 bytes blocks if no overlap */
98
+ *--ds.s = *--ss.s, n -= sizeof(struct _16);
99
+ while (n >= sizeof(uint64_t) && pd >= sizeof(uint64_t))
100
+ /* copy leftover 8 byte blocks if no overlap */
101
+ *--ds.l = *--ss.l, n -= sizeof(uint64_t);
102
+ while (n >= sizeof(uint32_t) && pd >= sizeof(uint32_t))
103
+ /* copy leftover 4 byte blocks if no overlap */
104
+ *--ds.i = *--ss.i, n -= sizeof(uint32_t);
105
+ } else if (n >= 2*sizeof(uint32_t) && pd >= 2*sizeof(uint32_t)) {
106
+ /* unaligned data big enough to avoid understepping src */
107
+ uint32_t v1, v2, b, s;
108
+ /* align dest to word */
109
+ while (((uintptr_t)ds.c & lm) && n > 0)
110
+ *--ds.c = *--ss.c, n--;
111
+ /* copy loop: load aligned words and store shifted words */
112
+ b = (uintptr_t)ss.c & lm, s = b*8; ss.c += b;
113
+ v1 = *--ss.i, v2 = *--ss.i;
114
+ while (n >= 3*sizeof(uint32_t)) {
115
+ *--ds.i = (v1 _U_ s) | (v2 _L_ (32-s)); v1 = *--ss.i;
116
+ *--ds.i = (v2 _U_ s) | (v1 _L_ (32-s)); v2 = *--ss.i;
117
+ n -= 2*sizeof(uint32_t);
118
+ }
119
+ /* data for one more store is already loaded */
120
+ if (n >= sizeof(uint32_t)) {
121
+ *--ds.i = (v1 _U_ s) | (v2 _L_ (32-s));
122
+ n -= sizeof(uint32_t);
123
+ ss.c -= sizeof(uint32_t);
124
+ }
125
+ ss.c -= b - 2*sizeof(uint32_t);
126
+ }
127
+ /* copy 0-7 leftover bytes (or upto everything if ptrs are too close) */
128
+ while (n >= 4) {
129
+ *--ds.c = *--ss.c, n--; *--ds.c = *--ss.c, n--;
130
+ *--ds.c = *--ss.c, n--; *--ds.c = *--ss.c, n--;
131
+ }
132
+ while (n > 0)
133
+ *--ds.c = *--ss.c, n--;
134
+ return dest;
135
+}
136
libretro-picodrive-0~git20200112.tar.xz/platform/common/menu_pico.c -> libretro-picodrive-0~git20200716.tar.xz/platform/common/menu_pico.c
Changed
36
1
2
mee_range_h ("Overclock M68k (%)", MA_OPT2_OVERCLOCK_M68K,currentConfig.overclock_68k, 0, 1000, h_ovrclk),
3
mee_onoff ("Emulate Z80", MA_OPT2_ENABLE_Z80, PicoIn.opt, POPT_EN_Z80),
4
mee_onoff ("Emulate YM2612 (FM)", MA_OPT2_ENABLE_YM2612, PicoIn.opt, POPT_EN_FM),
5
+ mee_onoff ("Disable YM2612 SSG-EG", MA_OPT2_DISABLE_YM_SSG,PicoIn.opt, POPT_DIS_FM_SSGEG),
6
mee_onoff ("Emulate SN76496 (PSG)", MA_OPT2_ENABLE_SN76496,PicoIn.opt, POPT_EN_PSG),
7
mee_onoff ("gzip savestates", MA_OPT2_GZIP_STATES, currentConfig.EmuOpt, EOPT_GZIP_SAVES),
8
mee_onoff ("Don't save last used ROM", MA_OPT2_NO_LAST_ROM, currentConfig.EmuOpt, EOPT_NO_AUTOSVCFG),
9
10
mee_onoff ("Disable frame limiter", MA_OPT2_NO_FRAME_LIMIT,currentConfig.EmuOpt, EOPT_NO_FRMLIMIT),
11
mee_onoff ("Enable dynarecs", MA_OPT2_DYNARECS, PicoIn.opt, POPT_EN_DRC),
12
mee_onoff ("Status line in main menu", MA_OPT2_STATUS_LINE, currentConfig.EmuOpt, EOPT_SHOW_RTC),
13
+ mee_range ("Max auto frameskip", MA_OPT2_MAX_FRAMESKIP, currentConfig.max_skip, 1, 10),
14
+ mee_onoff ("PWM IRQ optimization", MA_OPT2_PWM_IRQ_OPT, PicoIn.opt, POPT_PWM_IRQ_OPT),
15
MENU_OPTIONS_ADV
16
mee_end,
17
};
18
19
}
20
21
static const char credits[] =
22
- "PicoDrive v" VERSION " (c) notaz, 2006-2013\n\n\n"
23
+ "PicoDrive v" VERSION "\n"
24
+ "(c) notaz, 2006-2013; irixxxx, 2018-2020\n\n"
25
"Credits:\n"
26
"fDave: initial code\n"
27
#ifdef EMU_C68K
28
29
"MAME devs: SH2, YM2612 and SN76496 cores\n"
30
"Eke, Stef: some Sega CD code\n"
31
"Inder, ketchupgun: graphics\n"
32
+ "Irixxxx: SH2 drc improvements\n"
33
#ifdef __GP2X__
34
"Squidge: mmuhack\n"
35
"Dzz: ARM940 sample\n"
36
libretro-picodrive-0~git20200112.tar.xz/platform/common/menu_pico.h -> libretro-picodrive-0~git20200716.tar.xz/platform/common/menu_pico.h
Changed
18
1
2
MA_OPT2_VSYNC,
3
MA_OPT2_ENABLE_Z80,
4
MA_OPT2_ENABLE_YM2612,
5
+ MA_OPT2_DISABLE_YM_SSG,
6
MA_OPT2_ENABLE_SN76496,
7
MA_OPT2_GZIP_STATES,
8
MA_OPT2_NO_LAST_ROM,
9
10
MA_OPT2_NO_SPRITE_LIM,
11
MA_OPT2_NO_IDLE_LOOPS,
12
MA_OPT2_OVERCLOCK_M68K,
13
+ MA_OPT2_MAX_FRAMESKIP,
14
+ MA_OPT2_PWM_IRQ_OPT,
15
MA_OPT2_DONE,
16
MA_OPT3_SCALE, /* psp (all OPT3) */
17
MA_OPT3_HSCALE32,
18
libretro-picodrive-0~git20200112.tar.xz/platform/common/mp3.c -> libretro-picodrive-0~git20200716.tar.xz/platform/common/mp3.c
Changed
35
1
2
0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320
3
};
4
5
-int mp3_find_sync_word(const unsigned char *buf, int size)
6
-{
7
- const unsigned char *p, *pe;
8
-
9
- /* find byte-aligned syncword - need 12 (MPEG 1,2) or 11 (MPEG 2.5) matching bits */
10
- for (p = buf, pe = buf + size - 3; p <= pe; p++)
11
- {
12
- int pn;
13
- if (p[0] != 0xff)
14
- continue;
15
- pn = p[1];
16
- if ((pn & 0xf8) != 0xf8 || // currently must be MPEG1
17
- (pn & 6) == 0) { // invalid layer
18
- p++; continue;
19
- }
20
- pn = p[2];
21
- if ((pn & 0xf0) < 0x20 || (pn & 0xf0) == 0xf0 || // bitrates
22
- (pn & 0x0c) != 0) { // not 44kHz
23
- continue;
24
- }
25
-
26
- return p - buf;
27
- }
28
-
29
- return -1;
30
-}
31
-
32
static int try_get_bitrate(unsigned char *buf, int buf_size)
33
{
34
int offs1, offs = 0;
35
libretro-picodrive-0~git20200112.tar.xz/platform/common/mp3.h -> libretro-picodrive-0~git20200716.tar.xz/platform/common/mp3.h
Changed
12
1
2
extern unsigned short mpeg1_l3_bitrates[16];
3
4
#ifdef __GP2X__
5
-void mp3_update_local(int *buffer, int length, int stereo);
6
-void mp3_start_play_local(void *f, int pos);
7
+int _mp3dec_start(FILE *f, int fpos_start);
8
+int _mp3dec_decode(FILE *f, int *file_pos, int file_len);
9
#endif
10
11
#endif // __COMMON_MP3_H__
12
libretro-picodrive-0~git20200112.tar.xz/platform/common/mp3_helix.c -> libretro-picodrive-0~git20200716.tar.xz/platform/common/mp3_helix.c
Changed
70
1
2
3
#include <stdio.h>
4
#include <string.h>
5
+#include <dlfcn.h>
6
7
#include <pico/pico_int.h>
8
#include <pico/sound/mix.h>
9
10
static unsigned char mp3_input_buffer[2 * 1024];
11
12
#ifdef __GP2X__
13
-#define mp3_update mp3_update_local
14
-#define mp3_start_play mp3_start_play_local
15
+#define mp3dec_decode _mp3dec_decode
16
+#define mp3dec_start _mp3dec_start
17
#endif
18
19
+static void *libhelix;
20
+HMP3Decoder (*p_MP3InitDecoder)(void);
21
+void (*p_MP3FreeDecoder)(HMP3Decoder);
22
+int (*p_MP3Decode)(HMP3Decoder, unsigned char **, int *, short *, int);
23
+
24
int mp3dec_decode(FILE *f, int *file_pos, int file_len)
25
{
26
unsigned char *readPtr;
27
28
bytesLeft -= offset;
29
30
had_err = err;
31
- err = MP3Decode(mp3dec, &readPtr, &bytesLeft, cdda_out_buffer, 0);
32
+ err = p_MP3Decode(mp3dec, &readPtr, &bytesLeft, cdda_out_buffer, 0);
33
if (err) {
34
if (err == ERR_MP3_MAINDATA_UNDERFLOW && !had_err) {
35
// just need another frame
36
37
38
int mp3dec_start(FILE *f, int fpos_start)
39
{
40
+ if (libhelix == NULL) {
41
+ libhelix = dlopen("./libhelix.so", RTLD_NOW);
42
+ if (libhelix == NULL) {
43
+ lprintf("mp3dec: load libhelix.so: %s\n", dlerror());
44
+ return -1;
45
+ }
46
+
47
+ p_MP3InitDecoder = dlsym(libhelix, "MP3InitDecoder");
48
+ p_MP3FreeDecoder = dlsym(libhelix, "MP3FreeDecoder");
49
+ p_MP3Decode = dlsym(libhelix, "MP3Decode");
50
+
51
+ if (p_MP3InitDecoder == NULL || p_MP3FreeDecoder == NULL
52
+ || p_MP3Decode == NULL)
53
+ {
54
+ lprintf("mp3dec: missing symbol(s) in libhelix.so\n");
55
+ dlclose(libhelix);
56
+ libhelix = NULL;
57
+ return -1;
58
+ }
59
+ }
60
+
61
// must re-init decoder for new track
62
if (mp3dec)
63
- MP3FreeDecoder(mp3dec);
64
- mp3dec = MP3InitDecoder();
65
+ p_MP3FreeDecoder(mp3dec);
66
+ mp3dec = p_MP3InitDecoder();
67
68
return (mp3dec == 0) ? -1 : 0;
69
}
70
libretro-picodrive-0~git20200716.tar.xz/platform/common/mp3_sync.c
Added
29
1
2
+
3
+int mp3_find_sync_word(const unsigned char *buf, int size)
4
+{
5
+ const unsigned char *p, *pe;
6
+
7
+ /* find byte-aligned syncword - need 12 (MPEG 1,2) or 11 (MPEG 2.5) matching bits */
8
+ for (p = buf, pe = buf + size - 3; p <= pe; p++)
9
+ {
10
+ int pn;
11
+ if (p[0] != 0xff)
12
+ continue;
13
+ pn = p[1];
14
+ if ((pn & 0xf8) != 0xf8 || // currently must be MPEG1
15
+ (pn & 6) == 0) { // invalid layer
16
+ p++; continue;
17
+ }
18
+ pn = p[2];
19
+ if ((pn & 0xf0) < 0x20 || (pn & 0xf0) == 0xf0 || // bitrates
20
+ (pn & 0x0c) != 0) { // not 44kHz
21
+ continue;
22
+ }
23
+
24
+ return p - buf;
25
+ }
26
+
27
+ return -1;
28
+}
29
libretro-picodrive-0~git20200112.tar.xz/platform/common/plat_sdl.c -> libretro-picodrive-0~git20200716.tar.xz/platform/common/plat_sdl.c
Changed
83
1
2
/* YUV stuff */
3
static int yuv_ry[32], yuv_gy[32], yuv_by[32];
4
static unsigned char yuv_u[32 * 2], yuv_v[32 * 2];
5
+static unsigned char yuv_y[256];
6
+static struct uyvy { unsigned int y:8; unsigned int vyu:24; } yuv_uyvy[65536];
7
8
void bgr_to_uyvy_init(void)
9
{
10
11
v = 255;
12
yuv_v[i + 32] = v;
13
}
14
+ // valid Y range seems to be 16..235
15
+ for (i = 0; i < 256; i++) {
16
+ yuv_y[i] = 16 + 219 * i / 32;
17
+ }
18
+ // everything combined into one large array for speed
19
+ for (i = 0; i < 65536; i++) {
20
+ int r = (i >> 11) & 0x1f, g = (i >> 6) & 0x1f, b = (i >> 0) & 0x1f;
21
+ int y = (yuv_ry[r] + yuv_gy[g] + yuv_by[b]) >> 16;
22
+ yuv_uyvy[i].y = yuv_y[y];
23
+ yuv_uyvy[i].vyu = (yuv_v[r-y + 32] << 16) | (yuv_y[y] << 8) | yuv_u[b-y + 32];
24
+ }
25
}
26
27
void rgb565_to_uyvy(void *d, const void *s, int pixels)
28
{
29
- unsigned int *dst = d;
30
- const unsigned short *src = s;
31
- const unsigned char *yu = yuv_u + 32;
32
- const unsigned char *yv = yuv_v + 32;
33
- int r0, g0, b0, r1, g1, b1;
34
- int y0, y1, u, v;
35
-
36
- for (; pixels > 0; src += 2, dst++, pixels -= 2)
37
+ uint32_t *dst = d;
38
+ const uint16_t *src = s;
39
+
40
+ if (plat_sdl_overlay->w > 2*plat_sdl_overlay->h)
41
+ for (; pixels > 0; src += 4, dst += 4, pixels -= 4)
42
+ {
43
+ struct uyvy *uyvy0 = yuv_uyvy + src[0], *uyvy1 = yuv_uyvy + src[1];
44
+ struct uyvy *uyvy2 = yuv_uyvy + src[2], *uyvy3 = yuv_uyvy + src[3];
45
+ dst[0] = (uyvy0->y << 24) | uyvy0->vyu;
46
+ dst[1] = (uyvy1->y << 24) | uyvy1->vyu;
47
+ dst[2] = (uyvy2->y << 24) | uyvy2->vyu;
48
+ dst[3] = (uyvy3->y << 24) | uyvy3->vyu;
49
+ } else
50
+ for (; pixels > 0; src += 4, dst += 2, pixels -= 4)
51
{
52
- r0 = (src[0] >> 11) & 0x1f;
53
- g0 = (src[0] >> 6) & 0x1f;
54
- b0 = src[0] & 0x1f;
55
- r1 = (src[1] >> 11) & 0x1f;
56
- g1 = (src[1] >> 6) & 0x1f;
57
- b1 = src[1] & 0x1f;
58
- y0 = (yuv_ry[r0] + yuv_gy[g0] + yuv_by[b0]) >> 16;
59
- y1 = (yuv_ry[r1] + yuv_gy[g1] + yuv_by[b1]) >> 16;
60
- u = yu[b0 - y0];
61
- v = yv[r0 - y0];
62
- // valid Y range seems to be 16..235
63
- y0 = 16 + 219 * y0 / 31;
64
- y1 = 16 + 219 * y1 / 31;
65
-
66
- *dst = (y1 << 24) | (v << 16) | (y0 << 8) | u;
67
+ struct uyvy *uyvy0 = yuv_uyvy + src[0], *uyvy1 = yuv_uyvy + src[1];
68
+ struct uyvy *uyvy2 = yuv_uyvy + src[2], *uyvy3 = yuv_uyvy + src[3];
69
+ dst[0] = (uyvy1->y << 24) | uyvy0->vyu;
70
+ dst[1] = (uyvy3->y << 24) | uyvy2->vyu;
71
}
72
}
73
74
75
if (shadow_size < 320 * 480 * 2)
76
shadow_size = 320 * 480 * 2;
77
78
- shadow_fb = malloc(shadow_size);
79
+ shadow_fb = calloc(1, shadow_size);
80
g_menubg_ptr = calloc(1, shadow_size);
81
if (shadow_fb == NULL || g_menubg_ptr == NULL) {
82
fprintf(stderr, "OOM\n");
83
libretro-picodrive-0~git20200112.tar.xz/platform/common/version.h -> libretro-picodrive-0~git20200716.tar.xz/platform/common/version.h
Changed
4
1
2
-#define VERSION "1.92"
3
+#define VERSION "1.96"
4
libretro-picodrive-0~git20200112.tar.xz/platform/gizmondo/Makefile -> libretro-picodrive-0~git20200716.tar.xz/platform/gizmondo/Makefile
Changed
11
1
2
endif
3
4
5
+../../tools/textfilter: ../../tools/textfilter.c
6
+ make -C ../../tools/ textfilter
7
+
8
readme.txt: ../../tools/textfilter ../base_readme.txt
9
../../tools/textfilter ../base_readme.txt $@ GIZ
10
11
libretro-picodrive-0~git20200112.tar.xz/platform/gizmondo/emu.c -> libretro-picodrive-0~git20200716.tar.xz/platform/gizmondo/emu.c
Changed
46
1
2
}
3
// a hack for VR
4
if (PicoIn.AHW & PAHW_SVP)
5
- memset32((int *)(Pico.est.Draw2FB+328*8+328*223), 0xe0e0e0e0, 328);
6
+ memset((int *)(Pico.est.Draw2FB+328*8+328*223), 0xe0e0e0e0, 328*4);
7
if (!(Pico.video.reg[12]&1)) lines_flags|=0x10000;
8
if (currentConfig.EmuOpt&0x4000)
9
lines_flags|=0x40000; // (Pico.m.frame_count&1)?0x20000:0x40000;
10
11
int lines_flags;
12
// 8bit accurate renderer
13
if (Pico.m.dirtyPal) {
14
- Pico.m.dirtyPal = 0;
15
- vidConvCpyRGB565(localPal, Pico.cram, 0x40);
16
+ if (Pico.m.dirtyPal == 2)
17
+ Pico.m.dirtyPal = 0;
18
+ /* no support
19
+ switch (Pico.est.SonicPalCount) {
20
+ case 3: vidConvCpyRGB565(localPal+0xc0, Pico.est.SonicPal+0xc0, 0x40);
21
+ case 2: vidConvCpyRGB565(localPal+0x80, Pico.est.SonicPal+0x80, 0x40);
22
+ case 1: vidConvCpyRGB565(localPal+0x40, Pico.est.SonicPal+0x40, 0x40);
23
+ default://vidConvCpyRGB565(localPal, Pico.est.SonicPal, 0x40);
24
+ } */
25
+ vidConvCpyRGB565(localPal, Pico.est.SonicPal, 0x40);
26
if (Pico.video.reg[0xC]&8) { // shadow/hilight mode
27
- //vidConvCpyRGB32sh(localPal+0x40, Pico.cram, 0x40);
28
- //vidConvCpyRGB32hi(localPal+0x80, Pico.cram, 0x40); // TODO?
29
- memcpy32((void *)(localPal+0xc0), (void *)(localPal+0x40), 0x40*2/4);
30
+ //vidConvCpyRGB32sh(localPal+0x40, Pico.est.SonicPal, 0x40);
31
+ //vidConvCpyRGB32hi(localPal+0x80, Pico.est.SonicPal, 0x40); // TODO?
32
+ memcpy((void *)(localPal+0xc0), (void *)(localPal+0x40), 0x40*2);
33
localPal[0xc0] = 0x0600;
34
localPal[0xd0] = 0xc000;
35
localPal[0xe0] = 0x0000; // reserved pixels for OSD
36
localPal[0xf0] = 0xffff;
37
}
38
- /* no support
39
- else if (rendstatus & 0x20) { // mid-frame palette changes
40
- vidConvCpyRGB565(localPal+0x40, HighPal, 0x40);
41
- vidConvCpyRGB565(localPal+0x80, HighPal+0x40, 0x40);
42
- } */
43
}
44
lines_flags = (Pico.video.reg[1]&8) ? 240 : 224;
45
if (!(Pico.video.reg[12]&1)) lines_flags|=0x10000;
46
libretro-picodrive-0~git20200112.tar.xz/platform/gizmondo/menu.c -> libretro-picodrive-0~git20200716.tar.xz/platform/gizmondo/menu.c
Changed
19
1
2
void menu_draw_begin(int use_bgbuff)
3
{
4
if (use_bgbuff)
5
- memcpy32((int *)menu_screen, (int *)bg_buffer, 321*240*2/4);
6
+ memcpy((int *)menu_screen, (int *)bg_buffer, 321*240*2);
7
}
8
9
10
11
lprintf("%s: Framework2D_LockBuffer() returned NULL\n", __FUNCTION__);
12
return;
13
}
14
- memcpy32(giz_screen, (int *)menu_screen, 321*240*2/4);
15
+ memcpy(giz_screen, (int *)menu_screen, 321*240*2);
16
fb_unlock();
17
giz_screen = NULL;
18
fb_flip();
19
libretro-picodrive-0~git20200112.tar.xz/platform/gp2x/940ctl.c -> libretro-picodrive-0~git20200716.tar.xz/platform/gp2x/940ctl.c
Changed
53
1
2
UINT16 *writebuff = shared_ctl->writebuffsel ? shared_ctl->writebuff0 : shared_ctl->writebuff1;
3
4
/* detect rapid ym updates */
5
- if (upd && !(writebuff_ptr & 0x80000000) && scanline < 224)
6
+ if (upd && !(writebuff_ptr & 0x80000000))
7
{
8
- int mid = Pico.m.pal ? 68 : 93;
9
- if (scanline > mid) {
10
+ int mid = (Pico.m.pal ? 313 : 262) / 2;
11
+ if (scanline >= mid) {
12
//printf("%05i:%03i: rapid ym\n", Pico.m.frame_count, scanline);
13
writebuff[writebuff_ptr++ & 0xffff] = 0xfffe;
14
writebuff_ptr |= 0x80000000;
15
16
}
17
18
19
-void YM2612Init_940(int baseclock, int rate)
20
+void YM2612Init_940(int baseclock, int rate, int ssg)
21
{
22
static int oldrate;
23
24
25
memset(shared_ctl, 0, sizeof(*shared_ctl));
26
27
/* cause local ym2612 to init REGS */
28
- YM2612Init_(baseclock, rate);
29
+ YM2612Init_(baseclock, rate, ssg);
30
31
internal_reset();
32
33
34
int mp3dec_decode(FILE *f, int *file_pos, int file_len)
35
{
36
if (!(PicoIn.opt & POPT_EXT_FM)) {
37
- //mp3_update_local(buffer, length, stereo);
38
- return 0;
39
+ return _mp3dec_decode(f, file_pos, file_len);
40
}
41
42
// check if playback was started, track not ended
43
44
int mp3dec_start(FILE *f, int fpos_start)
45
{
46
if (!(PicoIn.opt & POPT_EXT_FM)) {
47
- //mp3_start_play_local(f, pos);
48
- return -1;
49
+ return _mp3dec_start(f, fpos_start);
50
}
51
52
if (loaded_mp3 != f)
53
libretro-picodrive-0~git20200112.tar.xz/platform/gp2x/940ctl.h -> libretro-picodrive-0~git20200716.tar.xz/platform/gp2x/940ctl.h
Changed
10
1
2
void sharedmem940_init(void);
3
void sharedmem940_finish(void);
4
5
-void YM2612Init_940(int baseclock, int rate);
6
+void YM2612Init_940(int baseclock, int rate, int ssg);
7
void YM2612ResetChip_940(void);
8
int YM2612UpdateOne_940(int *buffer, int length, int stereo, int is_buf_empty);
9
10
libretro-picodrive-0~git20200112.tar.xz/platform/gp2x/Makefile -> libretro-picodrive-0~git20200716.tar.xz/platform/gp2x/Makefile
Changed
10
1
2
all: rel
3
4
../../tools/textfilter: ../../tools/textfilter.c
5
- make -C ../../tools/
6
+ make -C ../../tools/ textfilter
7
8
readme.txt: ../../tools/textfilter ../base_readme.txt ../../ChangeLog
9
../../tools/textfilter ../base_readme.txt $@ GP2X
10
libretro-picodrive-0~git20200112.tar.xz/platform/gp2x/PicoDrive.gpe -> libretro-picodrive-0~git20200716.tar.xz/platform/gp2x/PicoDrive.gpe
Changed
10
1
2
export POLLUX_RAM_TIMINGS='ram_timings=2,9,4,1,1,1,1'
3
export POLLUX_LCD_TIMINGS_NTSC='lcd_timings=397,1,37,277,341,0,17,337;clkdiv0=9'
4
export POLLUX_LCD_TIMINGS_PAL='lcd_timings=428,1,37,277,341,0,17,337;clkdiv0=10'
5
+else
6
+ export POLLUX_RAM_TIMINGS='ram_timings=3,9,4,1,1,1,1'
7
fi
8
9
./PicoDrive "$@"
10
libretro-picodrive-0~git20200112.tar.xz/platform/gp2x/code940/940.c -> libretro-picodrive-0~git20200716.tar.xz/platform/gp2x/code940/940.c
Changed
70
1
2
// (c) Copyright 2006-2007, Grazvydas "notaz" Ignotas
3
4
#include "940shared.h"
5
-#include "../../common/mp3.h"
6
+#include "../../common/helix/pub/mp3dec.h"
7
8
static _940_data_t *shared_data = (_940_data_t *) 0x00100000;
9
static _940_ctl_t *shared_ctl = (_940_ctl_t *) 0x00200000;
10
11
// is changed by other core just before we update it
12
void set_if_not_changed(int *val, int oldval, int newval);
13
14
-void _memcpy(void *dst, const void *src, int count);
15
+extern void *memcpy(void *dest, const void *src, unsigned long n);
16
17
// asm volatile ("mov r0, #0" ::: "r0");
18
// asm volatile ("mcr p15, 0, r0, c7, c6, 0" ::: "r0"); /* flush dcache */
19
20
int job = 0;
21
ym2612_940 = &shared_data->ym2612;
22
23
+// extern unsigned __bss_start__, __bss_end__;
24
+// memset(&__bss_start__, 0, &__bss_end__ - &__bss_start__);
25
26
for (;;)
27
{
28
29
case JOB940_INITALL:
30
/* ym2612 */
31
shared_ctl->writebuff0[0] = shared_ctl->writebuff1[0] = 0xffff;
32
- YM2612Init_(shared_ctl->baseclock, shared_ctl->rate);
33
+ YM2612Init_(shared_ctl->baseclock, shared_ctl->rate, 0);
34
/* Helix mp3 decoder */
35
+ __malloc_init();
36
shared_data->mp3dec = MP3InitDecoder();
37
break;
38
39
40
41
case JOB940_PICOSTATESAVE2:
42
YM2612PicoStateSave2(0, 0);
43
- _memcpy(shared_ctl->writebuff0, ym2612_940->REGS, 0x200);
44
+ memcpy(shared_ctl->writebuff0, ym2612_940->REGS, 0x200);
45
break;
46
47
case JOB940_PICOSTATELOAD2_PREP:
48
49
break;
50
51
case JOB940_PICOSTATELOAD2:
52
- _memcpy(ym2612_940->REGS, shared_ctl->writebuff0, 0x200);
53
+ memcpy(ym2612_940->REGS, shared_ctl->writebuff0, 0x200);
54
YM2612PicoStateLoad2(0, 0);
55
break;
56
57
58
59
case JOB940_MP3RESET:
60
if (shared_data->mp3dec) MP3FreeDecoder(shared_data->mp3dec);
61
+ __malloc_init();
62
shared_data->mp3dec = MP3InitDecoder();
63
break;
64
}
65
66
dcache_clean();
67
}
68
}
69
-
70
libretro-picodrive-0~git20200112.tar.xz/platform/gp2x/code940/Makefile -> libretro-picodrive-0~git20200716.tar.xz/platform/gp2x/code940/Makefile
Changed
83
1
2
# you may or may not need to change this
3
-#devkit_path = x:/stuff/dev/devkitgp2x/
4
-devkit_path ?= $(HOME)/opt/devkitGP2X/
5
-lgcc_path = $(devkit_path)lib/gcc/arm-linux/4.0.3/
6
-CROSS = arm-linux-
7
+#devkit_path ?= $(HOME)/opt/devkitGP2X/
8
+#lgcc_path = $(devkit_path)lib/gcc/arm-linux/4.0.3/
9
#CROSS = $(devkit_path)bin/arm-linux-
10
+#devkit_path ?= $(HOME)/opt/open2x
11
+#lgcc_path = $(devkit_path)/gcc-4.1.1-glibc-2.3.6/lib/gcc/arm-open2x-linux/4.1.1/
12
+#CROSS ?= $(devkit_path)/gcc-4.1.1-glibc-2.3.6/bin/arm-open2x-linux-
13
+#devkit_path ?= $(HOME)/opt/arm-unknown-linux-gnu
14
+#lgcc_path = $(HOME)/opt/open2x/gcc-4.1.1-glibc-2.3.6/lib/gcc/arm-open2x-linux/4.1.1/
15
+#CROSS ?= $(devkit_path)/bin/arm-unknown-linux-gnu-
16
+lgcc_path = $(HOME)/opt/open2x/gcc-4.1.1-glibc-2.3.6/lib/gcc/arm-open2x-linux/4.1.1/
17
+CROSS ?= arm-linux-gnueabi-
18
19
# settings
20
#up = 1
21
22
-CFLAGS += -O2 -Wall -fomit-frame-pointer -fstrict-aliasing -ffast-math
23
-CFLAGS += -I../.. -I. -D__GP2X__ -DARM
24
-CFLAGS += -mcpu=arm940t -mtune=arm940t
25
-LDFLAGS = -static -s -e code940 -Ttext 0x0 -L$(lgcc_path) -lgcc
26
+CFLAGS += -O2 -Wall -mno-thumb-interwork -fstrict-aliasing -ffast-math
27
+CFLAGS += -I../../common/helix/pub -I../../.. -I. -D__GP2X__ -DARM
28
+CFLAGS += -mcpu=arm940t -mtune=arm940t -mabi=apcs-gnu -mfloat-abi=soft -mfpu=fpa
29
+LDFLAGS = -static -e code940 -Ttext 0x0 -L$(lgcc_path) -lgcc
30
31
GCC = $(CROSS)gcc
32
STRIP = $(CROSS)strip
33
34
# stuff for 940 core
35
36
# init, emu_control, emu
37
-OBJS940 += 940init.o 940.o 940ym2612.o memcpy.o misc_arm.o mp3.o
38
+OBJS940 += 940init.o 940.o 940ym2612.o misc_arm.o mp3_sync.o
39
+# the asm memcpy code crashes job LOAD2 on 940. Possibly a globbered reg?
40
+# OBJS940 += memcpy.o
41
# the asm code seems to be faster when run on 920, but not on 940 for some reason
42
# OBJS940 += ../../Pico/sound/ym2612_asm.o
43
44
45
OBJS940 += uClibc/memset.o uClibc/s_floor.o uClibc/e_pow.o uClibc/e_sqrt.o uClibc/s_fabs.o
46
OBJS940 += uClibc/s_scalbn.o uClibc/s_copysign.o uClibc/k_sin.o uClibc/k_cos.o uClibc/s_sin.o
47
OBJS940 += uClibc/e_rem_pio2.o uClibc/k_rem_pio2.o uClibc/e_log.o uClibc/wrappers.o
48
+LIBHELIX ?= ../../common/helix/$(notdir $(CROSS))helix_mp3.a
49
50
$(BIN) : code940.elf
51
@echo ">>>" $@
52
$(OBJCOPY) -O binary $< $@
53
54
-code940.elf : $(OBJS940) ../../common/helix/$(CROSS)helix-mp3.a
55
+code940.elf : $(OBJS940) $(LIBHELIX)
56
@echo ">>>" $@
57
$(LD) $^ $(LDFLAGS) -o $@ -Map code940.map
58
59
60
@echo ">>>" $@
61
$(GCC) $(CFLAGS) -DEXTERNAL_YM2612 -c $< -o $@
62
63
-../../common/helix/helix_mp3.a:
64
- @make -C ../../common/helix/
65
+mp3_sync.o: ../../common/mp3_sync.c
66
+ @echo ">>>" $@
67
+ $(GCC) $(CFLAGS) -Os -DCODE940 -c $< -o $@
68
+
69
+$(LIBHELIX):
70
+ @$(MAKE) -C ../../common/helix/ CROSS=$(CROSS)
71
72
73
up: $(BIN)
74
75
##
76
OBJSMP3T = mp3test.o ../gp2x.o ../asmutils.o ../usbjoy.o
77
78
-mp3test.gpe : $(OBJSMP3T) ../helix/helix_mp3.a
79
+mp3test.gpe : $(OBJSMP3T) $(LIBHELIX)
80
$(GCC) -static -o $@ $^
81
$(STRIP) $@
82
@cp -v $@ /mnt/gp2x/mnt/sd
83
libretro-picodrive-0~git20200112.tar.xz/platform/gp2x/code940/memcpy.s -> libretro-picodrive-0~git20200716.tar.xz/platform/gp2x/code940/memcpy.s
Changed
35
1
2
blt Lmemcpy_fl32 /* less than 32 bytes (12 from above) */
3
stmdb sp!, {r4, r7, r8, r9, r10} /* borrow r4 */
4
5
-/* blat 64 bytes at a time */
6
+/* blat 32 bytes at a time */
7
/* XXX for really big copies perhaps we should use more registers */
8
Lmemcpy_floop32:
9
ldmia r1!, {r3, r4, r7, r8, r9, r10, r12, lr}
10
stmia r0!, {r3, r4, r7, r8, r9, r10, r12, lr}
11
-ldmia r1!, {r3, r4, r7, r8, r9, r10, r12, lr}
12
-stmia r0!, {r3, r4, r7, r8, r9, r10, r12, lr}
13
-subs r2, r2, #0x40
14
+subs r2, r2, #0x20
15
bge Lmemcpy_floop32
16
17
cmn r2, #0x10
18
19
subs r2, r2, #0x14 /* less than 32 bytes (12 from above) */
20
blt Lmemcpy_bl32
21
22
-/* blat 64 bytes at a time */
23
+/* blat 32 bytes at a time */
24
/* XXX for really big copies perhaps we should use more registers */
25
Lmemcpy_bloop32:
26
ldmdb r1!, {r3, r4, r7, r8, r9, r10, r12, lr}
27
stmdb r0!, {r3, r4, r7, r8, r9, r10, r12, lr}
28
-ldmdb r1!, {r3, r4, r7, r8, r9, r10, r12, lr}
29
-stmdb r0!, {r3, r4, r7, r8, r9, r10, r12, lr}
30
-subs r2, r2, #0x40
31
+subs r2, r2, #0x20
32
bge Lmemcpy_bloop32
33
34
Lmemcpy_bl32:
35
libretro-picodrive-0~git20200112.tar.xz/platform/gp2x/code940/mp3test.c -> libretro-picodrive-0~git20200716.tar.xz/platform/gp2x/code940/mp3test.c
Changed
10
1
2
//#include "emu.h"
3
//#include "menu.h"
4
#include "../asmutils.h"
5
-#include "../helix/pub/mp3dec.h"
6
+#include "../../helix/pub/mp3dec.h"
7
8
/* we will need some gp2x internals here */
9
extern volatile unsigned short *gp2x_memregs; /* from minimal library rlyeh */
10
libretro-picodrive-0~git20200112.tar.xz/platform/gp2x/code940/uClibc/memset.s -> libretro-picodrive-0~git20200716.tar.xz/platform/gp2x/code940/uClibc/memset.s
Changed
10
1
2
.text
3
.global memset
4
.type memset,%function
5
- .align 4
6
+ .align 2
7
8
memset:
9
mov a4, a1
10
libretro-picodrive-0~git20200112.tar.xz/platform/gp2x/code940/uClibc/wrappers.c -> libretro-picodrive-0~git20200716.tar.xz/platform/gp2x/code940/uClibc/wrappers.c
Changed
19
1
2
{
3
return __ieee754_pow(x, y);
4
}
5
+double __pow_finite(double x, double y)
6
+{
7
+ return __ieee754_pow(x, y);
8
+}
9
10
11
double log(double x)
12
{
13
return __ieee754_log(x);
14
}
15
+double __log_finite(double x)
16
+{
17
+ return __ieee754_log(x);
18
+}
19
libretro-picodrive-0~git20200112.tar.xz/platform/gp2x/emu.c -> libretro-picodrive-0~git20200716.tar.xz/platform/gp2x/emu.c
Changed
165
1
2
gp2x_soc_t soc;
3
4
defaultConfig.CPUclock = default_cpu_clock;
5
- defaultConfig.renderer32x = RT_8BIT_FAST;
6
+ defaultConfig.renderer32x = RT_8BIT_ACC;
7
defaultConfig.analog_deadzone = 50;
8
9
soc = soc_detect();
10
11
}
12
13
static int localPal[0x100];
14
+static int localPalSize;
15
+
16
static void (*vidcpyM2)(void *dest, void *src, int m32col, int with_32c_border);
17
static int (*make_local_pal)(int fast_mode);
18
19
static int make_local_pal_md(int fast_mode)
20
{
21
- int pallen = 0xc0;
22
-
23
- bgr444_to_rgb32(localPal, Pico.cram);
24
- if (fast_mode)
25
- return 0x40;
26
+ int pallen = 0x100;
27
28
- if (Pico.video.reg[0xC] & 8) { // shadow/hilight mode
29
- bgr444_to_rgb32_sh(localPal, Pico.cram);
30
- localPal[0xc0] = 0x0000c000;
31
- localPal[0xd0] = 0x00c00000;
32
- localPal[0xe0] = 0x00000000; // reserved pixels for OSD
33
- localPal[0xf0] = 0x00ffffff;
34
- pallen = 0x100;
35
+ if (fast_mode) {
36
+ bgr444_to_rgb32(localPal, PicoMem.cram);
37
+ pallen = 0x40;
38
+ Pico.m.dirtyPal = 0;
39
}
40
else if (Pico.est.rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes
41
- bgr444_to_rgb32(localPal+0x40, Pico.est.HighPal);
42
- bgr444_to_rgb32(localPal+0x80, Pico.est.HighPal+0x40);
43
+ switch (Pico.est.SonicPalCount) {
44
+ case 3: bgr444_to_rgb32(localPal+0xc0, Pico.est.SonicPal+0xc0);
45
+ case 2: bgr444_to_rgb32(localPal+0x80, Pico.est.SonicPal+0x80);
46
+ case 1: bgr444_to_rgb32(localPal+0x40, Pico.est.SonicPal+0x40);
47
+ default:bgr444_to_rgb32(localPal, Pico.est.SonicPal);
48
+ }
49
+ pallen = (Pico.est.SonicPalCount+1)*0x40;
50
}
51
- else
52
- memcpy(localPal + 0x80, localPal, 0x40 * 4); // for spr prio mess
53
+ else if (Pico.video.reg[0xC] & 8) { // shadow/hilight mode
54
+ bgr444_to_rgb32(localPal, Pico.est.SonicPal);
55
+ bgr444_to_rgb32_sh(localPal, Pico.est.SonicPal);
56
+ }
57
+ else {
58
+ bgr444_to_rgb32(localPal, Pico.est.SonicPal);
59
+ memcpy(localPal+0x40, localPal, 0x40*4); // for spr prio mess
60
+ memcpy(localPal+0x80, localPal, 0x80*4); // for spr prio mess
61
+ }
62
+ localPal[0xc0] = 0x0000c000;
63
+ localPal[0xd0] = 0x00c00000;
64
+ localPal[0xe0] = 0x00000000; // reserved pixels for OSD
65
+ localPal[0xf0] = 0x00ffffff;
66
67
+ if (Pico.m.dirtyPal == 2)
68
+ Pico.m.dirtyPal = 0;
69
return pallen;
70
}
71
72
static int make_local_pal_sms(int fast_mode)
73
{
74
- unsigned short *spal = Pico.cram;
75
+ unsigned short *spal = PicoMem.cram;
76
unsigned int *dpal = (void *)localPal;
77
unsigned int i, t;
78
79
80
*dpal++ = t;
81
}
82
83
+ Pico.m.dirtyPal = 0;
84
return 0x40;
85
}
86
87
void pemu_finalize_frame(const char *fps, const char *notice)
88
{
89
int emu_opt = currentConfig.EmuOpt;
90
- int ret;
91
92
if (PicoIn.AHW & PAHW_32X)
93
- ; // nothing to do
94
+ localPalSize = 0; // nothing to do
95
else if (get_renderer() == RT_8BIT_FAST)
96
{
97
// 8bit fast renderer
98
- if (Pico.m.dirtyPal) {
99
- Pico.m.dirtyPal = 0;
100
- ret = make_local_pal(1);
101
- // feed new palette to our device
102
- gp2x_video_setpalette(localPal, ret);
103
- }
104
+ if (Pico.m.dirtyPal)
105
+ localPalSize = make_local_pal(1);
106
// a hack for VR
107
if (PicoIn.AHW & PAHW_SVP)
108
memset32((int *)(Pico.est.Draw2FB+328*8+328*223), 0xe0e0e0e0, 328);
109
110
{
111
// 8bit accurate renderer
112
if (Pico.m.dirtyPal)
113
- {
114
- Pico.m.dirtyPal = 0;
115
- ret = make_local_pal(0);
116
- gp2x_video_setpalette(localPal, ret);
117
- }
118
+ localPalSize = make_local_pal(0);
119
}
120
+ else localPalSize = 0; // no palette in 16bit mode
121
122
if (notice)
123
osd_text(4, osd_y, notice);
124
125
{
126
int stride = g_screen_width;
127
gp2x_video_flip();
128
+ // switching the palette takes immediate effect, whilst flipping only
129
+ // takes effect with the next vsync; unavoidable flicker may occur!
130
+ if (localPalSize)
131
+ gp2x_video_setpalette(localPal, localPalSize);
132
133
if (is_16bit_mode())
134
stride *= 2;
135
136
if (renderer == RT_16BIT && (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX)) {
137
PicoDrawSetOutFormat(PDF_RGB555, 1);
138
}
139
- else {
140
- PicoDrawSetOutFormat(PDF_NONE, 0);
141
- }
142
PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);
143
gp2x_mode = 16;
144
}
145
146
localPal[0xe0] = 0x00000000; // reserved pixels for OSD
147
localPal[0xf0] = 0x00ffffff;
148
gp2x_video_setpalette(localPal, 0x100);
149
- gp2x_memset_all_buffers(0, 0xe0, 320*240);
150
}
151
- else
152
- gp2x_memset_all_buffers(0, 0, 320*240*2);
153
154
if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX)
155
gp2x_mode = -gp2x_mode;
156
157
PicoDrawSetCallbacks(NULL, NULL);
158
Pico.m.dirtyPal = 1;
159
160
+ if (!no_scale)
161
+ no_scale = currentConfig.scaling == EOPT_SCALE_NONE;
162
emu_cmn_forced_frame(no_scale, do_emu);
163
164
g_menubg_src_ptr = g_screen_ptr;
165
libretro-picodrive-0~git20200112.tar.xz/platform/libpicofe/fonts.h -> libretro-picodrive-0~git20200716.tar.xz/platform/libpicofe/fonts.h
Changed
9
1
2
3
extern unsigned char fontdata8x8[64*16];
4
-extern unsigned char fontdata6x8[256-32][8];
5
+extern unsigned char fontdata6x8[256][8];
6
7
void basic_text_out16_nf(void *fb, int w, int x, int y, const char *text);
8
void basic_text_out16(void *fb, int w, int x, int y, const char *texto, ...);
9
libretro-picodrive-0~git20200112.tar.xz/platform/libpicofe/linux/host_dasm.c -> libretro-picodrive-0~git20200716.tar.xz/platform/libpicofe/linux/host_dasm.c
Changed
34
1
2
3
static struct disassemble_info di;
4
5
-#ifdef __arm__
6
+#if defined __arm__
7
#define print_insn_func print_insn_little_arm
8
#define BFD_ARCH bfd_arch_arm
9
#define BFD_MACH bfd_mach_arm_unknown
10
#define DASM_OPTS "reg-names-std"
11
+#elif defined __aarch64__
12
+#define print_insn_func print_insn_aarch64
13
+#define BFD_ARCH bfd_arch_aarch64
14
+#define BFD_MACH bfd_mach_aarch64
15
+#define DASM_OPTS NULL
16
+#elif defined __mips__
17
+#define print_insn_func print_insn_little_mips
18
+#define BFD_ARCH bfd_arch_mips
19
+#define BFD_MACH bfd_mach_mipsisa32
20
+#define DASM_OPTS NULL
21
+#elif defined __riscv
22
+#define print_insn_func print_insn_riscv
23
+#define BFD_ARCH bfd_arch_riscv
24
+#define BFD_MACH bfd_mach_riscv64
25
+#define DASM_OPTS NULL
26
+#elif defined __powerpc__
27
+#define print_insn_func print_insn_little_powerpc
28
+#define BFD_ARCH bfd_arch_powerpc
29
+#define BFD_MACH bfd_mach_ppc64
30
+#define DASM_OPTS NULL
31
#elif defined(__x86_64__) || defined(__i386__)
32
#define print_insn_func print_insn_i386_intel
33
#define BFD_ARCH bfd_arch_i386
34
libretro-picodrive-0~git20200112.tar.xz/platform/libpicofe/plat_sdl.c -> libretro-picodrive-0~git20200716.tar.xz/platform/libpicofe/plat_sdl.c
Changed
51
1
2
static int window_w, window_h;
3
static int fs_w, fs_h;
4
static int old_fullscreen;
5
-static int vout_mode_overlay = -1, vout_mode_gl = -1;
6
+static int vout_mode_overlay = -1, vout_mode_overlay2x = -1, vout_mode_gl = -1;
7
static void *display, *window;
8
static int gl_quirks;
9
10
11
// invalid method might come from config..
12
if (plat_target.vout_method != 0
13
&& plat_target.vout_method != vout_mode_overlay
14
+ && plat_target.vout_method != vout_mode_overlay2x
15
&& plat_target.vout_method != vout_mode_gl)
16
{
17
fprintf(stderr, "invalid vout_method: %d\n", plat_target.vout_method);
18
19
}
20
}
21
22
- if (plat_target.vout_method == vout_mode_overlay) {
23
- plat_sdl_overlay = SDL_CreateYUVOverlay(w, h, SDL_UYVY_OVERLAY, plat_sdl_screen);
24
+ if (plat_target.vout_method == vout_mode_overlay
25
+ || plat_target.vout_method == vout_mode_overlay2x) {
26
+ int W = plat_target.vout_method == vout_mode_overlay2x && w == 320 ? 2*w : w;
27
+ plat_sdl_overlay = SDL_CreateYUVOverlay(W, h, SDL_UYVY_OVERLAY, plat_sdl_screen);
28
if (plat_sdl_overlay != NULL) {
29
if ((long)plat_sdl_overlay->pixels[0] & 3)
30
fprintf(stderr, "warning: overlay pointer is unaligned\n");
31
32
33
int plat_sdl_init(void)
34
{
35
- static const char *vout_list[] = { NULL, NULL, NULL, NULL };
36
+ static const char *vout_list[] = { NULL, NULL, NULL, NULL, NULL };
37
const SDL_VideoInfo *info;
38
SDL_SysWMinfo wminfo;
39
int overlay_works = 0;
40
41
if (overlay_works) {
42
plat_target.vout_method = vout_mode_overlay = i;
43
vout_list[i++] = "Video Overlay";
44
+#ifdef SDL_OVERLAY_2X
45
+ vout_mode_overlay2x = i;
46
+ vout_list[i++] = "Video Overlay 2x";
47
+#endif
48
}
49
if (gl_works) {
50
plat_target.vout_method = vout_mode_gl = i;
51
libretro-picodrive-0~git20200112.tar.xz/platform/libretro/libretro-common/include/libretro_gskit_ps2.h -> libretro-picodrive-0~git20200716.tar.xz/platform/libretro/libretro-common/include/libretro_gskit_ps2.h
Changed
25
1
2
-/* Copyright (C) 2010-2018 The RetroArch team
3
+/* Copyright (C) 2010-2020 The RetroArch team
4
*
5
* ---------------------------------------------------------------------------------------------
6
* The following license statement only applies to this libretro API header (libretro_d3d.h)
7
8
9
#include <gsKit.h>
10
11
-#define RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION 1
12
+#define RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION 2
13
14
struct retro_hw_ps2_insets
15
{
16
17
* in this interface.
18
*/
19
GSTEXTURE *coreTexture;
20
- bool clearTexture;
21
- bool updatedPalette;
22
struct retro_hw_ps2_insets padding;
23
};
24
typedef struct retro_hw_render_interface_gskit_ps2 RETRO_HW_RENDER_INTEFACE_GSKIT_PS2;
25
libretro-picodrive-0~git20200112.tar.xz/platform/libretro/libretro.c -> libretro-picodrive-0~git20200716.tar.xz/platform/libretro/libretro.c
Changed
140
1
2
#define VOUT_32BIT_WIDTH 256
3
#endif
4
#define VOUT_MAX_HEIGHT 240
5
-#define SND_RATE 44100
6
+#define INITIAL_SND_RATE 44100
7
8
static const float VOUT_PAR = 0.0;
9
static const float VOUT_4_3 = (224.0f * (4.0f / 3.0f));
10
11
static struct retro_hw_ps2_insets padding;
12
#endif
13
14
-static short ALIGNED(4) sndBuffer[2*SND_RATE/50];
15
+static short ALIGNED(4) sndBuffer[2*INITIAL_SND_RATE/50];
16
17
static void snd_write(int len);
18
19
+char **g_argv;
20
+
21
#ifdef _WIN32
22
#define SLASH '\\'
23
#else
24
25
memset(vout_buf, 0, vout_width * VOUT_MAX_HEIGHT);
26
memset(retro_palette, 0, gsKit_texture_size_ee(16, 16, GS_PSM_CT16));
27
PicoDrawSetOutBuf(vout_buf, vout_width);
28
-
29
- if (ps2) {
30
- ps2->clearTexture = true;
31
- }
32
#else
33
vout_width = is_32cols ? VOUT_32BIT_WIDTH : VOUT_MAX_WIDTH;
34
memset(vout_buf, 0, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
35
36
37
void emu_32x_startup(void)
38
{
39
+ PicoDrawSetOutFormat(PDF_RGB555, 0);
40
+ PicoDrawSetOutBuf(vout_buf, vout_width * 2);
41
}
42
43
void lprintf(const char *fmt, ...)
44
45
46
memset(info, 0, sizeof(*info));
47
info->timing.fps = Pico.m.pal ? 50 : 60;
48
- info->timing.sample_rate = SND_RATE;
49
+ info->timing.sample_rate = PicoIn.sndRate;
50
info->geometry.base_width = vout_width;
51
info->geometry.base_height = vout_height;
52
info->geometry.max_width = vout_width;
53
54
struct retro_variable var;
55
int OldPicoRegionOverride;
56
float old_user_vout_width;
57
+ double new_sound_rate;
58
59
var.value = NULL;
60
var.key = "picodrive_input1";
61
62
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
63
PicoIn.sndFilterRange = (atoi(var.value) * 65536) / 100;
64
}
65
+
66
+ var.value = NULL;
67
+ var.key = "picodrive_renderer";
68
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
69
+ if (strcmp(var.value, "fast") == 0)
70
+ PicoIn.opt |= POPT_ALT_RENDERER;
71
+ else
72
+ PicoIn.opt &= ~POPT_ALT_RENDERER;
73
+ }
74
+
75
+ var.value = NULL;
76
+ var.key = "picodrive_sound_rate";
77
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
78
+ new_sound_rate = atoi(var.value);
79
+ if (new_sound_rate != PicoIn.sndRate) {
80
+ /* Update the sound rate */
81
+ PicoIn.sndRate = new_sound_rate;
82
+ PsndRerate(1);
83
+ struct retro_system_av_info av_info;
84
+ retro_get_system_av_info(&av_info);
85
+ environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &av_info);
86
+ }
87
+ }
88
}
89
90
void retro_run(void)
91
92
}
93
94
Pico.m.dirtyPal = 0;
95
- ps2->updatedPalette = true;
96
}
97
98
if (PicoIn.AHW & PAHW_SMS) {
99
100
ps2->padding = padding;
101
102
#else
103
+ if (PicoIn.opt & POPT_ALT_RENDERER) {
104
+ /* In retro_init, PicoDrawSetOutBuf is called to make sure the output gets written to vout_buf, but this only
105
+ * applies to the line renderer (pico/draw.c). The faster tile-based renderer (pico/draw2.c) enabled by
106
+ * POPT_ALT_RENDERER writes to Pico.est.Draw2FB, so we need to manually copy that to vout_buf.
107
+ */
108
+ /* This section is mostly copied from pemu_finalize_frame in platform/linux/emu.c */
109
+ unsigned short *pd = (unsigned short *)vout_buf;
110
+ /* Skip the leftmost 8 columns (it seems to be used as some sort of caching or overscan area) */
111
+ unsigned char *ps = Pico.est.Draw2FB + 8;
112
+ unsigned short *pal = Pico.est.HighPal;
113
+ int x;
114
+ if (Pico.m.dirtyPal)
115
+ PicoDrawUpdateHighPal();
116
+ /* Copy up to the max height to include the overscan area, and skip the leftmost 8 columns again */
117
+ for (i = 0; i < VOUT_MAX_HEIGHT; i++, ps += 8)
118
+ for (x = 0; x < vout_width; x++)
119
+ *pd++ = pal[*ps++];
120
+ }
121
+
122
buff = (char*)vout_buf + vout_offset;
123
#endif
124
125
126
#endif
127
PicoIn.opt |= POPT_EN_DRC;
128
#endif
129
- PicoIn.sndRate = SND_RATE;
130
+
131
+ struct retro_variable var = { .key = "picodrive_sound_rate" };
132
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
133
+ PicoIn.sndRate = atoi(var.value);
134
+ else
135
+ PicoIn.sndRate = INITIAL_SND_RATE;
136
+
137
PicoIn.autoRgnOrder = 0x184; // US, EU, JP
138
139
vout_width = VOUT_MAX_WIDTH;
140
libretro-picodrive-0~git20200112.tar.xz/platform/libretro/libretro_core_options.h -> libretro-picodrive-0~git20200716.tar.xz/platform/libretro/libretro_core_options.h
Changed
34
1
2
},
3
"60"
4
},
5
+#if !defined(RENDER_GSKIT_PS2)
6
+ {
7
+ "picodrive_renderer",
8
+ "Renderer",
9
+ "Fast renderer can't render any mid-frame image changes so it is useful only for some games.",
10
+ {
11
+ { "accurate", NULL },
12
+ { "fast", NULL },
13
+ { NULL, NULL },
14
+ },
15
+ "accurate"
16
+ },
17
+#endif
18
+ {
19
+ "picodrive_sound_rate",
20
+ "Sound quality",
21
+ "Sound quality (in Hz). A lower value may increase performance.",
22
+ {
23
+ { "16000", NULL },
24
+ { "22050", NULL },
25
+ { "32000", NULL },
26
+ { "44100", NULL },
27
+ { NULL, NULL },
28
+ },
29
+ "44100"
30
+ },
31
{ NULL, NULL, NULL, {{0}}, NULL },
32
};
33
34
libretro-picodrive-0~git20200112.tar.xz/platform/linux/blit.c -> libretro-picodrive-0~git20200716.tar.xz/platform/linux/blit.c
Changed
14
1
2
for (i = 0; i < 224; i++)
3
{
4
ps += 8;
5
+ ps += 32;
6
pd += 32;
7
for (u = 0; u < 256; u++)
8
*pd++ = *ps++;
9
- ps += 64;
10
+ ps += 32;
11
pd += 32;
12
}
13
} else {
14
libretro-picodrive-0~git20200112.tar.xz/platform/linux/emu.c -> libretro-picodrive-0~git20200716.tar.xz/platform/linux/emu.c
Changed
66
1
2
3
void pemu_validate_config(void)
4
{
5
-#if !defined(__arm__) && !defined(__i386__) && !defined(__x86_64__)
6
+#if !defined(__arm__) && !defined(__aarch64__) && !defined(__mips__) && !defined(__riscv__) && !defined(__riscv) && !defined(__powerpc__) && !defined(__i386__) && !defined(__x86_64__)
7
PicoIn.opt &= ~POPT_EN_DRC;
8
#endif
9
}
10
11
int led_reg, pitch, scr_offs, led_offs;
12
led_reg = Pico_mcd->s68k_regs[0];
13
14
- pitch = 320;
15
+ pitch = g_screen_ppitch;
16
led_offs = 4;
17
scr_offs = pitch * 2 + 4;
18
19
+#if 0
20
if (currentConfig.renderer != RT_16BIT) {
21
#define p(x) px[(x) >> 2]
22
// 8-bit modes
23
24
p(pitch*0) = p(pitch*1) = p(pitch*2) = col_g;
25
p(pitch*0 + led_offs) = p(pitch*1 + led_offs) = p(pitch*2 + led_offs) = col_r;
26
#undef p
27
- } else {
28
+ } else
29
+#endif
30
+ {
31
#define p(x) px[(x)*2 >> 2] = px[((x)*2 >> 2) + 1]
32
// 16-bit modes
33
unsigned int *px = (unsigned int *)((short *)g_screen_ptr + scr_offs);
34
35
unsigned char *ps = Pico.est.Draw2FB + 328*8 + 8;
36
unsigned short *pal = Pico.est.HighPal;
37
int i, x;
38
- if (Pico.m.dirtyPal)
39
- PicoDrawUpdateHighPal();
40
+
41
+ PicoDrawUpdateHighPal();
42
for (i = 0; i < 224; i++, ps += 8)
43
for (x = 0; x < 320; x++)
44
*pd++ = pal[*ps++];
45
46
47
if (PicoIn.AHW & PAHW_32X)
48
PicoDrawSetOutBuf(g_screen_ptr, g_screen_ppitch * 2);
49
+
50
+ Pico.m.dirtyPal = 1;
51
}
52
53
void plat_video_toggle_renderer(int change, int is_menu)
54
55
void emu_video_mode_change(int start_line, int line_count, int is_32cols)
56
{
57
// clear whole screen in all buffers
58
- memset32(g_screen_ptr, 0, g_screen_ppitch * g_screen_height * 2 / 4);
59
+ if (currentConfig.renderer != RT_16BIT && !(PicoIn.AHW & PAHW_32X))
60
+ memset32(Pico.est.Draw2FB, 0, (320+8) * (8+240+8) / 4);
61
+ else
62
+ memset32(g_screen_ptr, 0, g_screen_ppitch * g_screen_height * 2 / 4);
63
}
64
65
void pemu_loop_prep(void)
66
libretro-picodrive-0~git20200112.tar.xz/platform/linux/pprof.c -> libretro-picodrive-0~git20200716.tar.xz/platform/linux/pprof.c
Changed
97
1
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <unistd.h>
5
+#include <fcntl.h>
6
#include <sys/types.h>
7
#include <sys/ipc.h>
8
#include <sys/shm.h>
9
+#include <sys/mman.h>
10
11
#include <pico/pico_int.h>
12
13
+int rc_mem[pp_total_points];
14
+
15
struct pp_counters *pp_counters;
16
+int *refcounts = rc_mem;
17
static int shmemid;
18
19
+static unsigned long devMem;
20
+volatile unsigned long *gp2x_memregl;
21
+volatile unsigned short *gp2x_memregs;
22
+
23
void pprof_init(void)
24
{
25
int this_is_new_shmem = 1;
26
key_t shmemkey;
27
void *shmem;
28
29
+#if 0
30
+ devMem = open("/dev/mem", O_RDWR);
31
+ if (devMem == -1)
32
+ {
33
+ perror("pprof: open failed");
34
+ return;
35
+ }
36
+ gp2x_memregl = (unsigned long *)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, devMem, 0xc0000000);
37
+ if (gp2x_memregl == (unsigned long *)-1)
38
+ {
39
+ perror("pprof: mmap failed");
40
+ return;
41
+ }
42
+ gp2x_memregs = (unsigned short *)gp2x_memregl;
43
+#endif
44
+
45
#ifndef PPROF_TOOL
46
unsigned int tmp = pprof_get_one();
47
printf("pprof: measured diff is %u\n", pprof_get_one() - tmp);
48
49
return;
50
}
51
52
-#ifndef PPROF_TOOL
53
+//#ifndef PPROF_TOOL
54
shmemid = shmget(shmemkey, sizeof(*pp_counters),
55
IPC_CREAT | IPC_EXCL | 0644);
56
if (shmemid == -1)
57
-#endif
58
+//#endif
59
{
60
shmemid = shmget(shmemkey, sizeof(*pp_counters),
61
0644);
62
63
IT(draw),
64
IT(sound),
65
IT(m68k),
66
+ IT(s68k),
67
+ IT(mem68),
68
IT(z80),
69
IT(msh2),
70
IT(ssh2),
71
+ IT(memsh),
72
IT(dummy),
73
};
74
75
int main(int argc, char *argv[])
76
{
77
- unsigned long long old[pp_total_points], new[pp_total_points];
78
+ pp_type old[pp_total_points], new[pp_total_points];
79
int base = 0;
80
int l, i;
81
82
83
memcpy(new, pp_counters->counter, sizeof(new));
84
for (i = 0; i < ARRAY_SIZE(pp_tab); i++)
85
{
86
- unsigned long long idiff = new[i] - old[i];
87
- unsigned long long bdiff = (new[base] - old[base]) | 1;
88
+ pp_type idiff = new[i] - old[i];
89
+ pp_type bdiff = (new[base] - old[base]) | 1;
90
printf("%6.2f ", (double)idiff * 100.0 / bdiff);
91
}
92
printf("\n");
93
+ fflush(stdout);
94
memcpy(old, new, sizeof(old));
95
96
if (argc < 3)
97
libretro-picodrive-0~git20200112.tar.xz/platform/linux/pprof.h -> libretro-picodrive-0~git20200716.tar.xz/platform/linux/pprof.h
Changed
79
1
2
pp_draw,
3
pp_sound,
4
pp_m68k,
5
+ pp_s68k,
6
+ pp_mem68,
7
pp_z80,
8
pp_msh2,
9
pp_ssh2,
10
+ pp_memsh,
11
pp_dummy,
12
pp_total_points
13
};
14
15
-struct pp_counters
16
-{
17
- unsigned long long counter[pp_total_points];
18
-};
19
-
20
extern struct pp_counters *pp_counters;
21
+extern int *refcounts;
22
23
#ifdef __i386__
24
+typedef unsigned long long pp_type;
25
+
26
static __attribute__((always_inline)) inline unsigned int pprof_get_one(void)
27
{
28
unsigned long long ret;
29
30
#define unglitch_timer(x)
31
32
#elif defined(__GP2X__)
33
+typedef unsigned long pp_type;
34
+
35
+#if 0
36
// XXX: MMSP2 only, timer sometimes seems to return lower vals?
37
extern volatile unsigned long *gp2x_memregl;
38
#define pprof_get_one() (unsigned int)gp2x_memregl[0x0a00 >> 2]
39
#define unglitch_timer(di) \
40
if ((signed int)(di) < 0) di = 0
41
+#else
42
+extern unsigned int (*gp2x_get_ticks_us)(void);
43
+#define pprof_get_one() gp2x_get_ticks_us()
44
+#define unglitch_timer(di) \
45
+ if ((signed int)(di) < 0) di = 0
46
+#endif
47
48
#else
49
#error no timer
50
#endif
51
52
+struct pp_counters
53
+{
54
+ pp_type counter[pp_total_points];
55
+};
56
+
57
#define pprof_start(point) { \
58
- unsigned int pp_start_##point = pprof_get_one()
59
+ unsigned int pp_start_##point = pprof_get_one(); refcounts[pp_##point]++
60
61
#define pprof_end(point) \
62
{ \
63
unsigned int di = pprof_get_one() - pp_start_##point; \
64
unglitch_timer(di); \
65
- pp_counters->counter[pp_##point] += di; \
66
+ if (!--refcounts[pp_##point]) pp_counters->counter[pp_##point] += di; \
67
} \
68
}
69
70
71
{ \
72
unsigned int di = pprof_get_one() - pp_start_##point; \
73
unglitch_timer(di); \
74
- pp_counters->counter[pp_##point] -= di; \
75
+ if (--refcounts[pp_##point]) pp_counters->counter[pp_##point] -= di; \
76
} \
77
}
78
79
libretro-picodrive-0~git20200112.tar.xz/platform/pandora/Makefile -> libretro-picodrive-0~git20200716.tar.xz/platform/pandora/Makefile
Changed
10
1
2
all: rel
3
4
../../tools/textfilter: ../../tools/textfilter.c
5
- make -C ../../tools/
6
+ make -C ../../tools/ textfilter
7
8
#readme.txt: ../../tools/textfilter ../base_readme.txt ../../ChangeLog
9
# ../../tools/textfilter ../base_readme.txt $@ PANDORA
10
libretro-picodrive-0~git20200112.tar.xz/platform/psp/emu.c -> libretro-picodrive-0~git20200716.tar.xz/platform/psp/emu.c
Changed
56
1
2
3
//for (i = 0x3f/2; i >= 0; i--)
4
// dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4);
5
- do_pal_convert(localPal, Pico.cram, currentConfig.gamma, currentConfig.gamma2);
6
-
7
- Pico.m.dirtyPal = 0;
8
- need_pal_upload = 1;
9
-
10
- if (allow_sh && (Pico.video.reg[0xC]&8)) // shadow/hilight?
11
+ if ((currentConfig.EmuOpt&0x80) || (PicoOpt&0x10)) {
12
+ do_pal_convert(localPal, Pico.cram, currentConfig.gamma, currentConfig.gamma2);
13
+ Pico.m.dirtyPal = 0;
14
+ }
15
+ else if (Pico.est.rendstatus&0x20)
16
+ {
17
+ switch (Pico.est.SonicPalCount) {
18
+ case 3: do_pal_convert(localPal+0xc0, Pico.est.SonicPal+0xc0, currentConfig.gamma, currentConfig.gamma2);
19
+ case 2: do_pal_convert(localPal+0x80, Pico.est.SonicPal+0x80, currentConfig.gamma, currentConfig.gamma2);
20
+ case 1: do_pal_convert(localPal+0x40, Pico.est.SonicPal+0x40, currentConfig.gamma, currentConfig.gamma2);
21
+ default:do_pal_convert(localPal, Pico.est.SonicPal, currentConfig.gamma, currentConfig.gamma2);
22
+ }
23
+ }
24
+ else if (allow_sh && (Pico.video.reg[0xC]&8)) // shadow/hilight?
25
{
26
+ do_pal_convert(localPal, Pico.est.SonicPal, currentConfig.gamma, currentConfig.gamma2);
27
// shadowed pixels
28
for (i = 0x3f/2; i >= 0; i--)
29
dpal[0x20|i] = dpal[0x60|i] = (dpal[i]>>1)&0x7bcf7bcf;
30
31
localPal[0xe0] = 0;
32
localPal[0xf0] = 0x001f;
33
}
34
+ else if (allow_as)
35
+ {
36
+ do_pal_convert(localPal, Pico.est.SonicPal, currentConfig.gamma, currentConfig.gamma2);
37
+ memcpy((int *)dpal+0x40/2, (void *)localPal, 0x40*2);
38
+ memcpy((int *)dpal+0x80/2, (void *)localPal, 0x80*2);
39
+ }
40
+
41
+ if (Pico.m.dirtyPal == 2)
42
+ Pico.m.dirtyPal = 0;
43
+ need_pal_upload = 1;
44
}
45
46
static void do_slowmode_lines(int line_to)
47
48
49
PicoIn.sndOut += len / 2;
50
/*if (PicoIn.sndOut > sndBuffer_endptr) {
51
- memcpy32((int *)(void *)sndBuffer, (int *)endptr, (PicoIn.sndOut - endptr + 1) / 2);
52
+ memcpy((int *)(void *)sndBuffer, (int *)endptr, (PicoIn.sndOut - endptr + 1) * 2);
53
PicoIn.sndOut = &sndBuffer[PicoIn.sndOut - endptr];
54
lprintf("mov\n");
55
}
56
libretro-picodrive-0~git20200112.tar.xz/platform/psp/menu.c -> libretro-picodrive-0~git20200716.tar.xz/platform/psp/menu.c
Changed
10
1
2
// int i;
3
4
// for (i = 272; i >= 0; i--, dst += 512, src += 480)
5
- // memcpy32((int *)dst, (int *)src, 480*2/4);
6
+ // memcpy((int *)dst, (int *)src, 480*2);
7
8
sceGuSync(0,0); // sync with prev
9
sceGuStart(GU_DIRECT, guCmdList);
10
libretro-picodrive-0~git20200112.tar.xz/tools/Makefile -> libretro-picodrive-0~git20200716.tar.xz/tools/Makefile
Changed
25
1
2
-CFLAGS = -Wall -ggdb
3
+TARGETS = amalgamate textfilter
4
+HOSTCC ?= cc
5
6
-TARGETS = amalgamate textfilter mkoffsets
7
-OBJS = $(addsuffix .o,$(TARGETS))
8
+all:
9
+ if [ -f "offsets/$(XPLATFORM)-offsets.h" ]; then \
10
+ ln -sf "../tools/offsets/$(XPLATFORM)-offsets.h" ../pico/pico_int_offs.h; \
11
+ else \
12
+ CC="$(XCC)" CFLAGS="$(XCFLAGS)" sh ./mkoffsets.sh ../pico; \
13
+ fi
14
15
-all: $(TARGETS)
16
+$(TARGETS): $(addsuffix .c,$(TARGETS))
17
+ $(HOSTCC) -o $@ -O $@.c
18
19
clean:
20
$(RM) $(TARGETS) $(OBJS)
21
22
-mkoffsets: CFLAGS += -m32 -I..
23
-
24
.PHONY: clean all
25
libretro-picodrive-0~git20200716.tar.xz/tools/mkoffsets.sh
Added
162
1
2
+# automatically compute structure offsets for gcc targets in ELF format
3
+# (C) 2018 Kai-Uwe Bloem. This work is placed in the public domain.
4
+#
5
+# usage: mkoffsets <output dir>
6
+
7
+CC=${CC:-gcc}
8
+
9
+# endianess of target (automagically determined below)
10
+ENDIAN=
11
+
12
+# check which object format to dissect
13
+READELF=
14
+OBJDUMP=
15
+check_obj ()
16
+{
17
+ # prepare an object file; as side effect dtermine the endianess
18
+ CROSS=$(echo $CC | sed 's/gcc.*//')
19
+ echo '#include <stdint.h>' >/tmp/getoffs.c
20
+ echo "const int32_t val = 1;" >>/tmp/getoffs.c
21
+ $CC $CFLAGS -I .. -c /tmp/getoffs.c -o /tmp/getoffs.o || exit 1
22
+
23
+ # check for readelf; readelf is the only toolchain tool not using bfd,
24
+ # hence it works with ELF files for every target
25
+ if file /tmp/getoffs.o | grep -q ELF; then
26
+ if command -v readelf >/dev/null; then
27
+ READELF=readelf
28
+ elif command -v ${CROSS}readelf >/dev/null; then
29
+ READELF=${CROSS}readelf
30
+ fi
31
+ fi
32
+ if [ -n "$READELF" ]; then
33
+ # find the the .rodata section (in case -fdata-sections is used)
34
+ rosect=$($READELF -S /tmp/getoffs.o | grep '\.rodata\|\.sdata' |
35
+ sed 's/^[^.]*././;s/ .*//')
36
+ # read .rodata section as hex string (should be only 4 bytes)
37
+ ro=$($READELF -x $rosect /tmp/getoffs.o | grep '0x' | cut -c14-48 |
38
+ tr -d ' \n' | cut -c1-8)
39
+ # if no output could be read readelf isn't working
40
+ if [ -z "$ro" ]; then
41
+ READELF=
42
+ fi
43
+ fi
44
+ # if there is no working readelf try using objdump
45
+ if [ -z "$READELF" ]; then
46
+ # objdump is using bfd; try using the toolchain objdump first
47
+ # since this is likely working with the toolchain objects
48
+ if command -v ${CROSS}objdump >/dev/null; then
49
+ OBJDUMP=${CROSS}objdump
50
+ elif command -v objdump >/dev/null; then
51
+ OBJDUMP=objdump
52
+ fi
53
+ # find the start line of the .rodata section; read the next line
54
+ ro=$($OBJDUMP -s /tmp/getoffs.o | awk '\
55
+ /Contents of section.*(__const|.r[o]?data|.sdata)/ {o=1; next} \
56
+ {if(o) { gsub(/ .*/,""); $1=""; gsub(/ /,""); print; exit}}')
57
+ # no working tool for extracting the ro data; stop here
58
+ if [ -z "$ro" ]; then
59
+ echo "/* mkoffset.sh: no readelf or not ELF, offset table not created */" >$fn
60
+ echo "WARNING: no readelf or not ELF, offset table not created"
61
+ exit
62
+ fi
63
+ fi
64
+ # extract decimal value from ro
65
+ rodata=$(printf "%d" 0x$ro)
66
+ ENDIAN=$(if [ "$rodata" -eq 1 ]; then echo be; else echo le; fi)
67
+}
68
+
69
+# compile with target C compiler and extract value from .rodata section
70
+compile_rodata ()
71
+{
72
+ $CC $CFLAGS -I .. -c /tmp/getoffs.c -o /tmp/getoffs.o || exit 1
73
+ if [ -n "$READELF" ]; then
74
+ # find the .rodata section (in case -fdata-sections is used)
75
+ rosect=$(readelf -S /tmp/getoffs.o | grep '\.rodata\|\.sdata' |
76
+ sed 's/^[^.]*././;s/ .*//')
77
+ # read .rodata section as hex string (should be only 4 bytes)
78
+ ro=$(readelf -x $rosect /tmp/getoffs.o | grep '0x' | cut -c14-48 |
79
+ tr -d ' \n' | cut -c1-8)
80
+ elif [ -n "$OBJDUMP" ]; then
81
+ # find the start line of the .rodata section; read the next line
82
+ ro=$($OBJDUMP -s /tmp/getoffs.o | awk '\
83
+ /Contents of section.*(__const|.r[o]?data|.sdata)/ {o=1; next} \
84
+ {if(o) { gsub(/ .*/,""); $1=""; gsub(/ /,""); print; exit}}')
85
+ fi
86
+ if [ "$ENDIAN" = "le" ]; then
87
+ # swap needed for le target
88
+ hex=""
89
+ for b in $(echo $ro | sed 's/\([0-9a-f]\{2\}\)/\1 /g'); do
90
+ hex=$b$hex;
91
+ done
92
+ else
93
+ hex=$ro
94
+ fi
95
+ # extract decimal value from hex string
96
+ rodata=$(printf "%d" 0x$hex)
97
+}
98
+
99
+# determine member offset and create #define
100
+get_define () # prefix struct member member...
101
+{
102
+ prefix=$1; shift
103
+ struct=$1; shift
104
+ field=$(echo $* | sed 's/ /./g')
105
+ name=$(echo $* | sed 's/ /_/g')
106
+ echo '#include <stdint.h>' > /tmp/getoffs.c
107
+ echo '#include "pico/pico_int.h"' >> /tmp/getoffs.c
108
+ echo "static struct $struct p;" >> /tmp/getoffs.c
109
+ echo "const int32_t val = (char *)&p.$field - (char*)&p;" >>/tmp/getoffs.c
110
+ compile_rodata
111
+ line=$(printf "#define %-20s 0x%04x" $prefix$name $rodata)
112
+}
113
+
114
+fn="${1:-.}/pico_int_offs.h"
115
+if echo $CFLAGS | grep -qe -flto; then CFLAGS="$CFLAGS -fno-lto"; fi
116
+
117
+check_obj
118
+# output header
119
+echo "/* autogenerated by mkoffset.sh, do not edit */" >$fn
120
+echo "/* target endianess: $ENDIAN, compiled with: $CC $CFLAGS */" >>$fn
121
+# output offsets
122
+get_define OFS_Pico_ Pico video reg ; echo "$line" >>$fn
123
+get_define OFS_Pico_ Pico m rotate ; echo "$line" >>$fn
124
+get_define OFS_Pico_ Pico m z80Run ; echo "$line" >>$fn
125
+get_define OFS_Pico_ Pico m dirtyPal ; echo "$line" >>$fn
126
+get_define OFS_Pico_ Pico m hardware ; echo "$line" >>$fn
127
+get_define OFS_Pico_ Pico m z80_reset ; echo "$line" >>$fn
128
+get_define OFS_Pico_ Pico m sram_reg ; echo "$line" >>$fn
129
+get_define OFS_Pico_ Pico sv ; echo "$line" >>$fn
130
+get_define OFS_Pico_ Pico sv data ; echo "$line" >>$fn
131
+get_define OFS_Pico_ Pico sv start ; echo "$line" >>$fn
132
+get_define OFS_Pico_ Pico sv end ; echo "$line" >>$fn
133
+get_define OFS_Pico_ Pico sv flags ; echo "$line" >>$fn
134
+get_define OFS_Pico_ Pico rom ; echo "$line" >>$fn
135
+get_define OFS_Pico_ Pico romsize ; echo "$line" >>$fn
136
+get_define OFS_Pico_ Pico est ; echo "$line" >>$fn
137
+
138
+get_define OFS_EST_ PicoEState DrawScanline ; echo "$line" >>$fn
139
+get_define OFS_EST_ PicoEState rendstatus ; echo "$line" >>$fn
140
+get_define OFS_EST_ PicoEState DrawLineDest ; echo "$line" >>$fn
141
+get_define OFS_EST_ PicoEState HighCol ; echo "$line" >>$fn
142
+get_define OFS_EST_ PicoEState HighPreSpr ; echo "$line" >>$fn
143
+get_define OFS_EST_ PicoEState Pico ; echo "$line" >>$fn
144
+get_define OFS_EST_ PicoEState PicoMem_vram ; echo "$line" >>$fn
145
+get_define OFS_EST_ PicoEState PicoMem_cram ; echo "$line" >>$fn
146
+get_define OFS_EST_ PicoEState PicoOpt ; echo "$line" >>$fn
147
+get_define OFS_EST_ PicoEState Draw2FB ; echo "$line" >>$fn
148
+get_define OFS_EST_ PicoEState HighPal ; echo "$line" >>$fn
149
+
150
+get_define OFS_PMEM_ PicoMem vram ; echo "$line" >>$fn
151
+get_define OFS_PMEM_ PicoMem vsram ; echo "$line" >>$fn
152
+get_define OFS_PMEM32x_ Pico32xMem pal_native ; echo "$line" >>$fn
153
+
154
+get_define OFS_SH2_ SH2_ is_slave ; echo "$line" >>$fn
155
+get_define OFS_SH2_ SH2_ p_bios ; echo "$line" >>$fn
156
+get_define OFS_SH2_ SH2_ p_da ; echo "$line" >>$fn
157
+get_define OFS_SH2_ SH2_ p_sdram ; echo "$line" >>$fn
158
+get_define OFS_SH2_ SH2_ p_rom ; echo "$line" >>$fn
159
+get_define OFS_SH2_ SH2_ p_dram ; echo "$line" >>$fn
160
+get_define OFS_SH2_ SH2_ p_drcblk_da ; echo "$line" >>$fn
161
+get_define OFS_SH2_ SH2_ p_drcblk_ram ; echo "$line" >>$fn
162
libretro-picodrive-0~git20200716.tar.xz/tools/offsets
Added
2
1
+(directory)
2
libretro-picodrive-0~git20200716.tar.xz/tools/offsets/generic-ilp32-offsets.h
Added
41
1
2
+/* autogenerated by mkoffset.sh, do not edit */
3
+/* target endianess: le, compiled with: mipsel-linux-gnu-gcc -mabi=32 */
4
+#define OFS_Pico_video_reg 0x0000
5
+#define OFS_Pico_m_rotate 0x0040
6
+#define OFS_Pico_m_z80Run 0x0041
7
+#define OFS_Pico_m_dirtyPal 0x0046
8
+#define OFS_Pico_m_hardware 0x0047
9
+#define OFS_Pico_m_z80_reset 0x004f
10
+#define OFS_Pico_m_sram_reg 0x0049
11
+#define OFS_Pico_sv 0x008c
12
+#define OFS_Pico_sv_data 0x008c
13
+#define OFS_Pico_sv_start 0x0090
14
+#define OFS_Pico_sv_end 0x0094
15
+#define OFS_Pico_sv_flags 0x0098
16
+#define OFS_Pico_rom 0x0554
17
+#define OFS_Pico_romsize 0x0558
18
+#define OFS_Pico_est 0x00c8
19
+#define OFS_EST_DrawScanline 0x0000
20
+#define OFS_EST_rendstatus 0x0004
21
+#define OFS_EST_DrawLineDest 0x0008
22
+#define OFS_EST_HighCol 0x000c
23
+#define OFS_EST_HighPreSpr 0x0010
24
+#define OFS_EST_Pico 0x0014
25
+#define OFS_EST_PicoMem_vram 0x0018
26
+#define OFS_EST_PicoMem_cram 0x001c
27
+#define OFS_EST_PicoOpt 0x0020
28
+#define OFS_EST_Draw2FB 0x0024
29
+#define OFS_EST_HighPal 0x0028
30
+#define OFS_PMEM_vram 0x10000
31
+#define OFS_PMEM_vsram 0x22100
32
+#define OFS_PMEM32x_pal_native 0x90e00
33
+#define OFS_SH2_is_slave 0x055c
34
+#define OFS_SH2_p_bios 0x0080
35
+#define OFS_SH2_p_da 0x0084
36
+#define OFS_SH2_p_sdram 0x0088
37
+#define OFS_SH2_p_rom 0x008c
38
+#define OFS_SH2_p_dram 0x0090
39
+#define OFS_SH2_p_drcblk_da 0x0094
40
+#define OFS_SH2_p_drcblk_ram 0x0098
41
libretro-picodrive-0~git20200716.tar.xz/tools/offsets/generic-llp64-offsets.h
Added
41
1
2
+/* autogenerated by mkoffset.sh, do not edit */
3
+/* target endianess: le, compiled with: x86_64-w64-mingw32-gcc */
4
+#define OFS_Pico_video_reg 0x0000
5
+#define OFS_Pico_m_rotate 0x0040
6
+#define OFS_Pico_m_z80Run 0x0041
7
+#define OFS_Pico_m_dirtyPal 0x0046
8
+#define OFS_Pico_m_hardware 0x0047
9
+#define OFS_Pico_m_z80_reset 0x004f
10
+#define OFS_Pico_m_sram_reg 0x0049
11
+#define OFS_Pico_sv 0x0090
12
+#define OFS_Pico_sv_data 0x0090
13
+#define OFS_Pico_sv_start 0x0098
14
+#define OFS_Pico_sv_end 0x009c
15
+#define OFS_Pico_sv_flags 0x00a0
16
+#define OFS_Pico_rom 0x0588
17
+#define OFS_Pico_romsize 0x0590
18
+#define OFS_Pico_est 0x00d8
19
+#define OFS_EST_DrawScanline 0x0000
20
+#define OFS_EST_rendstatus 0x0004
21
+#define OFS_EST_DrawLineDest 0x0008
22
+#define OFS_EST_HighCol 0x0010
23
+#define OFS_EST_HighPreSpr 0x0018
24
+#define OFS_EST_Pico 0x0020
25
+#define OFS_EST_PicoMem_vram 0x0028
26
+#define OFS_EST_PicoMem_cram 0x0030
27
+#define OFS_EST_PicoOpt 0x0038
28
+#define OFS_EST_Draw2FB 0x0040
29
+#define OFS_EST_HighPal 0x0048
30
+#define OFS_PMEM_vram 0x10000
31
+#define OFS_PMEM_vsram 0x22100
32
+#define OFS_PMEM32x_pal_native 0x90e00
33
+#define OFS_SH2_is_slave 0x0a18
34
+#define OFS_SH2_p_bios 0x0098
35
+#define OFS_SH2_p_da 0x00a0
36
+#define OFS_SH2_p_sdram 0x00a8
37
+#define OFS_SH2_p_rom 0x00b0
38
+#define OFS_SH2_p_dram 0x00b8
39
+#define OFS_SH2_p_drcblk_da 0x00c0
40
+#define OFS_SH2_p_drcblk_ram 0x00c8
41
libretro-picodrive-0~git20200716.tar.xz/tools/offsets/generic-lp64-offsets.h
Added
41
1
2
+/* autogenerated by mkoffset.sh, do not edit */
3
+/* target endianess: le, compiled with: mipsel-linux-gnu-gcc -mabi=64 */
4
+#define OFS_Pico_video_reg 0x0000
5
+#define OFS_Pico_m_rotate 0x0040
6
+#define OFS_Pico_m_z80Run 0x0041
7
+#define OFS_Pico_m_dirtyPal 0x0046
8
+#define OFS_Pico_m_hardware 0x0047
9
+#define OFS_Pico_m_z80_reset 0x004f
10
+#define OFS_Pico_m_sram_reg 0x0049
11
+#define OFS_Pico_sv 0x0090
12
+#define OFS_Pico_sv_data 0x0090
13
+#define OFS_Pico_sv_start 0x0098
14
+#define OFS_Pico_sv_end 0x009c
15
+#define OFS_Pico_sv_flags 0x00a0
16
+#define OFS_Pico_rom 0x0588
17
+#define OFS_Pico_romsize 0x0590
18
+#define OFS_Pico_est 0x00d8
19
+#define OFS_EST_DrawScanline 0x0000
20
+#define OFS_EST_rendstatus 0x0004
21
+#define OFS_EST_DrawLineDest 0x0008
22
+#define OFS_EST_HighCol 0x0010
23
+#define OFS_EST_HighPreSpr 0x0018
24
+#define OFS_EST_Pico 0x0020
25
+#define OFS_EST_PicoMem_vram 0x0028
26
+#define OFS_EST_PicoMem_cram 0x0030
27
+#define OFS_EST_PicoOpt 0x0038
28
+#define OFS_EST_Draw2FB 0x0040
29
+#define OFS_EST_HighPal 0x0048
30
+#define OFS_PMEM_vram 0x10000
31
+#define OFS_PMEM_vsram 0x22100
32
+#define OFS_PMEM32x_pal_native 0x90e00
33
+#define OFS_SH2_is_slave 0x0a18
34
+#define OFS_SH2_p_bios 0x0098
35
+#define OFS_SH2_p_da 0x00a0
36
+#define OFS_SH2_p_sdram 0x00a8
37
+#define OFS_SH2_p_rom 0x00b0
38
+#define OFS_SH2_p_dram 0x00b8
39
+#define OFS_SH2_p_drcblk_da 0x00c0
40
+#define OFS_SH2_p_drcblk_ram 0x00c8
41