Changes of Revision 2

libretro-picodrive.changes Changed
x
 
1
@@ -1,4 +1,204 @@
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
@@ -17,7 +17,7 @@
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
@@ -1,4 +1,4 @@
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
@@ -1,8099 +0,0 @@
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
@@ -1,373 +0,0 @@
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
@@ -1,28 +0,0 @@
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
@@ -1,907 +0,0 @@
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
@@ -1,202 +0,0 @@
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
@@ -1,16 +0,0 @@
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
@@ -4,19 +4,6 @@
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
@@ -34,6 +21,39 @@
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
@@ -47,10 +67,12 @@
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
@@ -91,6 +113,7 @@
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
@@ -124,6 +147,8 @@
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
@@ -135,6 +160,7 @@
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
@@ -169,15 +195,17 @@
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
@@ -201,7 +229,7 @@
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
@@ -213,10 +241,10 @@
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
@@ -236,6 +264,14 @@
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
@@ -252,10 +288,13 @@
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
@@ -15,10 +15,6 @@
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
@@ -41,18 +37,11 @@
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
@@ -67,7 +56,6 @@
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
@@ -81,7 +69,6 @@
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
@@ -90,14 +77,9 @@
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
@@ -119,15 +101,8 @@
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
@@ -141,14 +116,15 @@
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
@@ -162,29 +138,9 @@
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
@@ -193,6 +149,9 @@
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
@@ -205,20 +164,9 @@
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
@@ -227,18 +175,6 @@
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
@@ -249,130 +185,60 @@
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
@@ -0,0 +1,70 @@
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
@@ -22,6 +22,13 @@
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
@@ -31,17 +38,18 @@
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
@@ -54,7 +62,7 @@
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
@@ -78,23 +86,27 @@
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
@@ -147,18 +159,11 @@
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
@@ -206,26 +211,40 @@
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
@@ -251,6 +270,14 @@
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
@@ -308,8 +335,7 @@
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
@@ -352,10 +378,7 @@
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
@@ -395,15 +418,18 @@
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
@@ -0,0 +1,8098 @@
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
@@ -14,6 +14,7 @@
2
 #include "cz80.h"
3
 
4
 #if PICODRIVE_HACKS
5
+#include <pico/pico_int.h>
6
 #include <pico/memory.h>
7
 #endif
8
 
9
@@ -277,7 +278,8 @@
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
@@ -287,6 +289,8 @@
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
@@ -687,13 +687,13 @@
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
@@ -1,16 +1,44 @@
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
@@ -1,34 +1,192 @@
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
@@ -0,0 +1,1416 @@
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
@@ -0,0 +1,1842 @@
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
@@ -0,0 +1,1773 @@
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
@@ -0,0 +1,1659 @@
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
@@ -1,6 +1,7 @@
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
@@ -13,10 +14,11 @@
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
@@ -51,6 +53,9 @@
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
@@ -61,7 +66,8 @@
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
@@ -106,45 +112,70 @@
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
@@ -156,7 +187,8 @@
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
@@ -170,7 +202,8 @@
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
@@ -185,6 +218,72 @@
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
@@ -1,26 +1,30 @@
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,14 +42,18 @@
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
@@ -53,9 +61,16 @@
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
@@ -73,6 +88,7 @@
83
 #define dbg(...)
84
 #endif
85
 
86
+
87
 ///
88
 #define FETCH_OP(pc) \
89
   dr_pc_base[(pc) / 2]
90
@@ -93,13 +109,21 @@
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
@@ -115,319 +139,438 @@
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
@@ -1,27 +1,86 @@
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
@@ -372,7 +372,7 @@
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
@@ -802,7 +802,7 @@
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
@@ -1049,12 +1049,12 @@
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
@@ -465,7 +465,7 @@
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
@@ -121,7 +121,7 @@
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
@@ -139,7 +139,7 @@
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
@@ -214,7 +214,7 @@
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
@@ -232,13 +232,13 @@
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
@@ -84,7 +84,7 @@
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
@@ -1,6 +1,7 @@
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
@@ -8,42 +9,58 @@
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
@@ -60,21 +77,22 @@
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
@@ -88,17 +106,21 @@
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
@@ -108,12 +130,12 @@
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
@@ -18,7 +18,6 @@
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
@@ -27,16 +26,25 @@
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
@@ -47,16 +55,25 @@
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
@@ -12,7 +12,7 @@
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
@@ -30,7 +30,7 @@
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
@@ -38,30 +38,32 @@
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
@@ -70,7 +72,7 @@
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
@@ -79,7 +81,7 @@
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
@@ -194,11 +196,11 @@
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
@@ -207,8 +209,8 @@
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
@@ -254,11 +256,11 @@
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
@@ -267,7 +269,8 @@
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
@@ -323,8 +326,12 @@
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
@@ -366,19 +373,19 @@
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
@@ -412,8 +419,7 @@
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
@@ -423,7 +429,7 @@
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
@@ -431,7 +437,7 @@
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
@@ -446,6 +452,7 @@
201
libretro-picodrive-0~git20200112.tar.xz/pico/32x/draw.c -> libretro-picodrive-0~git20200716.tar.xz/pico/32x/draw.c Changed
174
 
1
@@ -1,6 +1,7 @@
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
@@ -11,6 +12,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
@@ -44,16 +48,21 @@
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
@@ -61,15 +70,21 @@
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
@@ -233,13 +248,11 @@
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
@@ -278,20 +291,21 @@
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
@@ -305,7 +319,7 @@
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
@@ -314,21 +328,32 @@
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
@@ -0,0 +1,444 @@
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
@@ -1,6 +1,7 @@
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
@@ -40,7 +41,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
@@ -56,32 +59,40 @@
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
@@ -97,15 +108,19 @@
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
@@ -113,40 +128,179 @@
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
@@ -0,0 +1,288 @@
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
@@ -7,32 +7,42 @@
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
@@ -40,7 +50,7 @@
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
@@ -48,16 +58,16 @@
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
@@ -69,67 +79,70 @@
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
@@ -166,21 +179,21 @@
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
@@ -25,6 +25,9 @@
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
@@ -87,6 +90,7 @@
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
@@ -125,6 +129,33 @@
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
@@ -134,6 +165,12 @@
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
@@ -160,8 +197,9 @@
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
@@ -171,6 +209,9 @@
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
@@ -178,36 +219,35 @@
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
@@ -225,7 +265,7 @@
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
@@ -235,30 +275,52 @@
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
@@ -49,4 +49,32 @@
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
@@ -1,5 +1,6 @@
2
 
3
 /* svp */
4
+#include "../pico_types.h"
5
 #include "svp/ssp16.h"
6
 
7
 typedef struct {
8
@@ -18,7 +19,7 @@
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
@@ -693,9 +693,9 @@
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
@@ -1438,12 +1438,9 @@
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
@@ -1712,12 +1709,8 @@
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
@@ -1795,6 +1788,8 @@
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
@@ -8,7 +8,7 @@
2
 
3
 #include "../../arm_features.h"
4
 
5
-.syntax unified
6
+@.syntax unified
7
 .text
8
 .align 2
9
 
10
@@ -281,8 +281,8 @@
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
@@ -501,7 +501,7 @@
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
@@ -510,7 +510,7 @@
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
@@ -525,7 +525,7 @@
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
@@ -562,10 +562,10 @@
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
@@ -10,10 +10,6 @@
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
@@ -32,7 +28,7 @@
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
@@ -125,6 +125,7 @@
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
@@ -137,6 +138,7 @@
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
@@ -14,12 +14,14 @@
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
@@ -6,7 +6,8 @@
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
@@ -65,6 +66,7 @@
12
 .extern PicoWrite16_io
13
 .extern m68k_comm_check
14
 
15
+    PIC_LDR_INIT()
16
 
17
 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
18
 
19
@@ -73,16 +75,16 @@
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
@@ -128,7 +130,7 @@
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
@@ -141,26 +143,26 @@
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
@@ -178,9 +180,9 @@
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
@@ -219,10 +221,10 @@
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
@@ -238,7 +240,7 @@
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
@@ -252,19 +254,19 @@
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
@@ -275,9 +277,9 @@
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
@@ -307,9 +309,9 @@
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
@@ -329,7 +331,7 @@
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
@@ -357,7 +359,7 @@
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
@@ -43,6 +43,12 @@
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
@@ -369,42 +375,32 @@
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,6 +2,7 @@
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
@@ -29,6 +30,7 @@
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
@@ -45,6 +47,8 @@
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
@@ -53,7 +57,11 @@
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
@@ -94,7 +102,7 @@
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
@@ -106,9 +114,10 @@
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
@@ -120,23 +129,24 @@
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
@@ -178,17 +188,19 @@
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
@@ -197,8 +209,8 @@
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
@@ -207,11 +219,12 @@
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
@@ -219,6 +232,18 @@
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
@@ -293,6 +318,7 @@
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
@@ -306,7 +332,7 @@
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
@@ -315,7 +341,7 @@
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
@@ -327,14 +353,15 @@
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
@@ -20,7 +20,7 @@
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
@@ -157,6 +157,8 @@
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
@@ -240,6 +242,8 @@
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
@@ -315,6 +319,8 @@
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
@@ -377,6 +383,8 @@
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
@@ -412,12 +420,13 @@
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
@@ -502,6 +511,11 @@
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
@@ -8,7 +8,7 @@
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
@@ -414,7 +414,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
@@ -590,8 +593,11 @@
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
@@ -688,13 +694,18 @@
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
@@ -715,7 +726,6 @@
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
@@ -915,8 +925,11 @@
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
@@ -1,6 +1,7 @@
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
@@ -8,13 +9,13 @@
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
@@ -317,9 +318,10 @@
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
@@ -342,11 +344,15 @@
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
@@ -362,7 +368,8 @@
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
@@ -517,6 +524,9 @@
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
@@ -541,6 +551,12 @@
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
@@ -571,8 +587,8 @@
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
@@ -599,6 +615,7 @@
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
@@ -694,8 +711,8 @@
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
@@ -790,7 +807,6 @@
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
@@ -942,17 +958,23 @@
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
@@ -963,7 +985,7 @@
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
@@ -1007,10 +1029,16 @@
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
@@ -1126,11 +1154,18 @@
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
@@ -87,19 +87,19 @@
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
@@ -163,12 +163,14 @@
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
@@ -389,7 +391,7 @@
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
@@ -399,8 +401,7 @@
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
@@ -420,6 +421,7 @@
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
@@ -543,7 +545,7 @@
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
@@ -730,8 +732,10 @@
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
@@ -879,7 +883,7 @@
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
@@ -895,10 +899,10 @@
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
@@ -940,11 +944,11 @@
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
@@ -1026,13 +1030,9 @@
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
@@ -1060,6 +1060,7 @@
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
@@ -1221,7 +1222,7 @@
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,13 +2,6 @@
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
@@ -32,8 +25,17 @@
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
@@ -8,7 +8,7 @@
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
@@ -1,12 +1,14 @@
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
@@ -23,8 +25,10 @@
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
@@ -59,6 +63,7 @@
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
@@ -72,7 +77,7 @@
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
@@ -95,7 +100,7 @@
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
@@ -140,7 +145,7 @@
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
@@ -182,7 +187,7 @@
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
@@ -212,7 +217,7 @@
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
@@ -220,6 +225,103 @@
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
@@ -1,6 +1,7 @@
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
@@ -8,83 +9,174 @@
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
@@ -67,6 +67,7 @@
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
@@ -78,6 +79,7 @@
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
@@ -182,8 +184,7 @@
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
@@ -222,51 +223,6 @@
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
@@ -313,7 +269,7 @@
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
@@ -326,7 +282,7 @@
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
@@ -70,8 +70,10 @@
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
@@ -197,14 +199,16 @@
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
@@ -22,27 +22,30 @@
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
@@ -52,10 +55,10 @@
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
@@ -68,28 +71,19 @@
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
@@ -150,27 +144,11 @@
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
@@ -189,10 +167,6 @@
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
@@ -204,25 +178,26 @@
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
@@ -238,12 +213,9 @@
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
@@ -278,8 +250,9 @@
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
@@ -289,18 +262,19 @@
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
@@ -9,7 +9,6 @@
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
@@ -32,6 +31,7 @@
10
 extern "C" {
11
 #endif
12
 
13
+#include "pico_types.h"
14
 
15
 // ----------------------- 68000 CPU -----------------------
16
 #ifdef EMU_C68K
17
@@ -129,9 +129,7 @@
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
@@ -185,7 +183,7 @@
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
@@ -207,7 +205,7 @@
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
@@ -229,11 +227,10 @@
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
@@ -241,11 +238,11 @@
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
@@ -290,6 +287,11 @@
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
@@ -300,13 +302,16 @@
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
@@ -328,8 +333,8 @@
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
@@ -356,6 +361,8 @@
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
@@ -421,11 +428,15 @@
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
@@ -597,7 +608,8 @@
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
@@ -605,7 +617,8 @@
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
@@ -618,8 +631,8 @@
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
@@ -648,12 +661,14 @@
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
@@ -723,7 +738,7 @@
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
@@ -17,10 +17,12 @@
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
@@ -0,0 +1,19 @@
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
@@ -46,8 +46,8 @@
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
@@ -152,7 +152,7 @@
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
@@ -320,16 +320,12 @@
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
@@ -6,32 +6,72 @@
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
@@ -41,7 +81,8 @@
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
@@ -77,3 +118,8 @@
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
@@ -8,3 +8,4 @@
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
@@ -166,13 +166,6 @@
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
@@ -180,20 +173,30 @@
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
@@ -203,6 +206,10 @@
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
@@ -221,13 +228,17 @@
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
@@ -235,9 +246,11 @@
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
@@ -262,6 +275,10 @@
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
@@ -281,6 +298,8 @@
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
@@ -288,14 +307,18 @@
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
@@ -315,11 +338,13 @@
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
@@ -338,6 +363,10 @@
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
@@ -358,15 +387,31 @@
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
@@ -173,9 +173,12 @@
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
@@ -186,6 +189,9 @@
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
@@ -19,9 +19,6 @@
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
@@ -95,58 +92,6 @@
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
@@ -156,6 +101,8 @@
71
   // Reset low pass filter
72
   lpf_lp = 0;
73
   lpf_rp = 0;
74
+
75
+  mix_reset();
76
 }
77
 
78
 
79
@@ -164,6 +111,7 @@
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
@@ -171,7 +119,7 @@
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
@@ -188,10 +136,12 @@
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
@@ -219,59 +169,61 @@
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
@@ -5,6 +5,10 @@
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
@@ -124,7 +128,7 @@
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
@@ -148,7 +152,7 @@
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
@@ -172,16 +176,6 @@
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
@@ -287,7 +281,7 @@
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
@@ -328,10 +322,10 @@
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
@@ -517,7 +511,7 @@
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
@@ -552,6 +546,13 @@
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
@@ -560,7 +561,15 @@
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
@@ -571,8 +580,18 @@
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
@@ -589,38 +608,38 @@
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
@@ -656,6 +675,9 @@
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
@@ -715,12 +737,12 @@
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
@@ -53,6 +53,12 @@
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
@@ -89,7 +95,7 @@
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
@@ -147,6 +153,7 @@
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
@@ -154,7 +161,7 @@
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
@@ -176,22 +183,22 @@
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
@@ -0,0 +1,976 @@
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
@@ -254,6 +254,8 @@
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
@@ -437,7 +439,11 @@
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
@@ -563,7 +569,7 @@
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,6 +2,7 @@
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
@@ -11,28 +12,330 @@
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
@@ -141,6 +141,7 @@
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
@@ -9,6 +9,8 @@
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
@@ -40,6 +42,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
@@ -53,7 +59,7 @@
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
@@ -66,7 +72,11 @@
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
@@ -138,7 +148,7 @@
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
@@ -157,8 +167,16 @@
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
@@ -181,7 +199,7 @@
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
@@ -39,7 +39,7 @@
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
@@ -100,7 +100,7 @@
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
@@ -169,7 +169,7 @@
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
@@ -216,7 +216,7 @@
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
@@ -326,6 +326,10 @@
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
@@ -503,7 +507,7 @@
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
@@ -0,0 +1,485 @@
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
@@ -0,0 +1,28 @@
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
@@ -0,0 +1,412 @@
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
@@ -0,0 +1,6 @@
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
@@ -600,6 +600,7 @@
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
@@ -1411,8 +1412,10 @@
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
@@ -1465,10 +1468,16 @@
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
@@ -76,6 +76,7 @@
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
@@ -0,0 +1,43 @@
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
@@ -0,0 +1,57 @@
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
@@ -0,0 +1,93 @@
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
@@ -93,6 +93,10 @@
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
@@ -148,6 +152,9 @@
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
@@ -0,0 +1,134 @@
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
@@ -499,6 +499,7 @@
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
@@ -506,6 +507,8 @@
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
@@ -920,7 +923,8 @@
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
@@ -936,6 +940,7 @@
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
@@ -48,6 +48,7 @@
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
@@ -58,6 +59,8 @@
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
@@ -21,33 +21,6 @@
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
@@ -12,8 +12,8 @@
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
@@ -9,6 +9,7 @@
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
@@ -20,10 +21,15 @@
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
@@ -51,7 +57,7 @@
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
@@ -86,10 +92,31 @@
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
@@ -0,0 +1,27 @@
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
@@ -89,6 +89,8 @@
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
@@ -119,34 +121,40 @@
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
@@ -272,7 +280,7 @@
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
@@ -1,1 +1,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
@@ -98,6 +98,9 @@
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
@@ -155,7 +155,7 @@
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
@@ -166,22 +166,25 @@
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
@@ -54,7 +54,7 @@
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
@@ -66,7 +66,7 @@
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
@@ -100,10 +100,10 @@
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
@@ -282,7 +282,7 @@
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
@@ -339,7 +339,7 @@
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
@@ -425,8 +425,7 @@
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
@@ -457,8 +456,7 @@
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
@@ -1,7 +1,7 @@
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
@@ -11,7 +11,7 @@
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
@@ -7,6 +7,8 @@
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,7 +2,7 @@
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
@@ -19,7 +19,7 @@
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
@@ -153,6 +153,8 @@
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
@@ -165,8 +167,9 @@
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
@@ -185,7 +188,7 @@
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
@@ -193,7 +196,7 @@
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
@@ -207,6 +210,7 @@
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
@@ -215,4 +219,3 @@
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
@@ -1,17 +1,23 @@
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
@@ -36,7 +42,9 @@
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
@@ -44,12 +52,13 @@
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
@@ -64,8 +73,12 @@
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
@@ -82,7 +95,7 @@
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
@@ -114,14 +114,12 @@
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
@@ -314,14 +312,12 @@
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
@@ -13,7 +13,7 @@
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
@@ -22,7 +22,7 @@
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
@@ -4,9 +4,17 @@
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
@@ -55,7 +55,7 @@
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
@@ -291,38 +291,51 @@
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
@@ -334,25 +347,21 @@
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
@@ -364,12 +373,9 @@
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
@@ -385,6 +391,10 @@
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
@@ -502,9 +512,6 @@
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
@@ -537,10 +544,7 @@
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
@@ -723,6 +727,8 @@
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
@@ -1,6 +1,6 @@
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
@@ -22,11 +22,31 @@
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
@@ -31,7 +31,7 @@
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
@@ -52,6 +52,7 @@
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
@@ -96,8 +97,10 @@
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
@@ -176,7 +179,7 @@
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
@@ -277,6 +280,10 @@
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
@@ -1,4 +1,4 @@
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
@@ -33,7 +33,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
@@ -57,8 +57,6 @@
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
@@ -88,7 +88,7 @@
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
@@ -112,10 +112,12 @@
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
@@ -533,10 +535,6 @@
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
@@ -569,6 +567,8 @@
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
@@ -635,7 +635,7 @@
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
@@ -1301,6 +1301,7 @@
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
@@ -1431,6 +1432,29 @@
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
@@ -1524,7 +1548,6 @@
92
       }
93
 
94
       Pico.m.dirtyPal = 0;
95
-      ps2->updatedPalette = true;
96
    }
97
 
98
    if (PicoIn.AHW & PAHW_SMS) {
99
@@ -1536,6 +1559,25 @@
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
@@ -1574,7 +1616,13 @@
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
@@ -200,6 +200,32 @@
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
@@ -61,10 +61,11 @@
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
@@ -29,7 +29,7 @@
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
@@ -39,10 +39,11 @@
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
@@ -52,7 +53,9 @@
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
@@ -71,8 +74,8 @@
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
@@ -109,6 +112,8 @@
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
@@ -174,7 +179,10 @@
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
@@ -1,21 +1,46 @@
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
@@ -28,11 +53,11 @@
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
@@ -76,15 +101,18 @@
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
@@ -107,11 +135,12 @@
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
@@ -7,21 +7,22 @@
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
@@ -31,24 +32,38 @@
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
@@ -57,7 +72,7 @@
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
@@ -13,7 +13,7 @@
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
@@ -201,13 +201,22 @@
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
@@ -223,6 +232,16 @@
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
@@ -639,7 +658,7 @@
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
@@ -59,7 +59,7 @@
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
@@ -1,13 +1,17 @@
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
@@ -0,0 +1,160 @@
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
@@ -0,0 +1,39 @@
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
@@ -0,0 +1,39 @@
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
@@ -0,0 +1,39 @@
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