forked from hissorii/px68k
-
Notifications
You must be signed in to change notification settings - Fork 0
/
kaiseki.txt
386 lines (290 loc) · 11.2 KB
/
kaiseki.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
**2013/07/24
* MPU実行ルーチンを入れ替える
xkeropi: M68KRUN() (68kem.asm/_68KRUN)
cps2: m68000/c68k.c/INT32 C68k_Exec(c68k_struc *cpu, INT32 cycle)
* cps2側はc68k_struct C68K構造体で、レジスタ等を管理している。xkeropiの各変数をこの構造体にマッピングしていく
typedef struct c68k_t
{
UINT32 D[8];
UINT32 A[8];
UINT32 flag_C;
UINT32 flag_V;
UINT32 flag_Z;
UINT32 flag_N;
UINT32 flag_X;
UINT32 flag_I;
UINT32 flag_S;
UINT32 USP;
UINT32 PC;
UINT32 HaltState;
INT32 IRQLine;
INT32 IRQState;
INT32 ICount;
UINT32 BasePC;
UINT32 Fetch[C68K_FETCH_BANK];
UINT8 (*Read_Byte)(UINT32 address);
UINT16 (*Read_Word)(UINT32 address);
UINT8 (*Read_Byte_PC_Relative)(UINT32 address);
UINT16 (*Read_Word_PC_Relative)(UINT32 address);
void (*Write_Byte)(UINT32 address, UINT8 data);
void (*Write_Word)(UINT32 address, UINT16 data);
INT32 (*Interrupt_CallBack)(INT32 irqline);
void (*Reset_CallBack)(void);
} c68k_struc;
* TODO: まずはxkeropiのレジスタ関連をocps2のc68k_strucにマッピングする
xkeropi側のレジスタは68kem.asm内の_regsが実態。
これをextern m68k_regs regs;としてC言語側に見せている。
* TODO: stack pointerの扱いがよくわからん
->
- A7がスタックポインタ
- スタックポインタはユーザーモードと特権モードで異なる
- ステータスレジスタのSビット(13bit目)が1ならスーパーバイザーモード
cps2側はc68k_struc内にa[7], USPの二つ
xkeropi側はm68k_regs内にa[7], isp, uspの三つ
xkeropiのCコードでispを触るのはここだけ。あとはR_ISPとしてアセンブラコードのMPUコアで操作されるのみ。
x11/winx68k.cpp: regs.a[7] = regs.isp = (IPL[0x30001]<<24)|(IPL[0x30000]<<16)|(IPL[0x30003]<<8)|IPL[0x30002];
xkeropiのCコードでuspを触る個所はない。アセンブラコード内で操作されるのみ。
* cps2のCPU初期化
cps2/cps2.c/cps2_main()
cps2/cps2.c/cps2_init()
cps2/drive.c/cps2_drive_init()
cps2/cps2crpt.c/cps2_init_68k()
m68000.c/m68000_init()
* m68000_init()の解析
- メモリのbyte/word単位のread/write関数のセットC68k_Set_ReadB(&C68K, Memory_ReadB);等
keropiではアセンブリではcpu_readmem24{,_word,_dword}のだが、xkeropiではC言語で書かれたmem_wrap.c/cpu_readmem24{,_word,_dword}()があるではないか。
すばらしい。現状使われていないようだが、これを有効にしよう。
x68k/memory.h:#define Memory_ReadB cpu_readmem24
x68k/memory.h:#define Memory_ReadW cpu_readmem24_word
x68k/memory.h:#define Memory_ReadD cpu_readmem24_dword
#define m68k_read_memory_8(address) Memory_ReadB(address)
* 2013/07/25
R_IRQ DD 0 ; IRQ Request Level
:
R_IRQ_CALLBACK DD 0 ; irq callback (get vector)
struct m68k_regs {
DWORD IRQ_level;
:
void *irq_callback;
}
** 2013/07/29
* 残るアセンブリコードの洗い出し
-> done
- x11/windraw.c [done]
- x68k/bga.asm [deleted]
- x68k/tvram.c [done]
- x68k/bg.c 少々手直し、追加[done]
- x68k/gvram.c [done]
- x68k/crtc.c [done]
* x68k/bg.c/Sprite_DrawLineMcr()でsegvる
-> 修正done
%macro Sprite_DrawLineMcr 2 (%2が引数でint pri)
mov ebp, [TextDotX]
add ebp, 16
mov edx, 127 * 8
spline_%1_lp:
mov al, [Sprite_Regs + spritectrltbl.sprite_ply + edx]
and al, 3
cmp al, %2
; sctp = &sct[edx/sizeof(spritectrltbl)];
; if (sctp->sprite_ply & 3 == pri)
je spline_%1_plyhit
spline_%1_lpcnt:
sub dx, 8
jns spline_%1_lp
jmp spline_%1_ed
spline_%1_plyhit:
movzx edi, word [Sprite_Regs + spritectrltbl.sprite_posx + edx]
add edi, [BG_HAdjust]
and di, 3ffh
; if (sctp->sprite_posx + BG_HAdjust) & 0x3ff)
; ~~~~xxx: sctp not sct
cmp edi, ebp
jnc spline_%1_lpcnt
; if (t >= TextDotX + 16)
; ~~xxx: >= not > (=でもcarry flagはセットされない)
movzx eax, word [Sprite_Regs + spritectrltbl.sprite_posy + edx]
and ax, 3ffh
; y = sctp->sprite_posy & 0x3fff
sub eax, [VLINEBG]
add eax, [BG_VLINE]
neg eax
add eax, 16
; y -= VLINEBG, y+= BG_VLINE, y = -y, y+= 16
jnc spline_%1_lpcnt
shl al, 4
; y *= 16; //xxx忘れるな
movzx esi, word [Sprite_Regs + spritectrltbl.sprite_ctrl + edx]
mov bx, si
; bx = sctp->sprite_ctrl
shl si, 8
si = sctp->scrite_ctrl * 256; //xxx忘れるな
cmp bh, 40h
jc spline_%1_flipx
; if (sctp->sprite_ctrl < 0x4000)
js spline_%1_fxflipy //サインフラグは引き算後マイナスでよい?
; else if (sctp->sprite_ctrl - 0x4000 & 0x8000)
jge spline_%1_fxflipx
; else if (sctp->sprite_ctrl >= 0x4000)
xor al, 0f0h
; else y ^= 0xf0;
spline_%1_flipx:
lea esi, [BGCHR16 + esi + eax]
; esi = BGCHR16[(sctp->sprite_ctrl * 256) & 0xffff + (y * 16)]
cld ; directioin flagをクリア -> インクリメント方向
spline_%1_out:
shl bh, 4
mov ecx, 16
spline_%1_outlp:
lodsb ; al = *esi;
and ax, 0fh
je spline_%1_trans
or al, bh
cmp [BG_PriBuf + edi * 2], dx
jc spline_%1_trans
mov ax, [TextPal + eax * 2]
mov [BG_LineBuf + edi * 2], ax
or byte [Text_TrFlag + edi], 2
mov [BG_PriBuf + edi * 2], dx
spline_%1_trans:
inc edi
loop spline_%1_outlp
jmp spline_%1_lpcnt
spline_%1_fxflipy:
xor al, 0f0h
spline_%1_fxflipx:
lea esi, [BGCHR16 + esi + eax + 15]
std
jmp spline_%1_out
spline_%1_ed:
%endmacro
* BG_DrawLineMcrX()がない
-> done
** 2013/07/30
* gtk/x11関連のソースをなくす
** 2013/08/08
SDL2.0の研究
int SDL_GetNumVideoDisplays(void)
Disp num: 1
int SDL_GetNumDisplayModes(0) // 引数は0 origin?
DispMode num: 1
SDL_GetDisplayMode(0, 0, &dm);
format: 0x15151002 w: 1280 h: 736 refresh_rate: 0 driverdata: 0
0x X X X X XX XX
| | | | | |
| | | | | +-- bytes
| | | | +-- bites
| | | +-- layout
| | +--order
| +-- type
+-- always 1
#define SDL_DEFINE_PIXELFORMAT(type, order, layout, bits, bytes) \
((1 << 28) | ((type) << 24) | ((order) << 20) | ((layout) << 16) | \
((bits) << 8) | ((bytes) << 0))
SDL_PIXELFORMAT_RGB565 =
SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB,
SDL_PACKEDLAYOUT_565, 16, 2),
SDL_GetWindowSurface()のタイミングで初めてSDL_Surfaceが作成される。
これが32ビットdepthでXRGBフォーマットだ。
struct SDL_Windowはsrc/video/SDL_sysvideo.h で定義されている
SDL_Windowの>surface_validをセットするのはSDL_GetWindowSurface()。
ということは、SDL_GetWindowSurface()するしかWindowにSurfaceをつける手段が
ない?わかりずらいわ!!
* 2013/08/09
OpenGL ESの研究
- OpenGL ES 2.0のライブラリをリンクしても、デフォルトでは1.1で開始される。
2.0で開始するには、以下が必要
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 0 );
- OpenGL ESの開始はSDL_GL_CreateContext()呼び出しの延長で行われる
- glClearColor() はクリアする時の色を指定するだけ。clear本体はglClear()
* 2013/08/10
OpenGL ESの研究の2
- SDL_CreateContext()でEGL Contextが作られる
- SDL_GetWindowSurface()の延長でSDL_Surfaceが作られてしまい、こちらにEGL Contextが移ってしまう?
-> Textureが真っ白になってしまう。
-> 元々sdl_surfaceはスクリーンバッファだが実画面に2倍blitするようにしていたので、単なるmalloc()で確保してもよい。
-> ではスクリーンバッファはmalloc()にする
-> をぉ、textureが反映されるようになった!!
* 2013/08/13
- 仮想キー入力について
Androidの画面下の戻るボタンやメニューボタンのある領域をアイコン領域
その上のアプリが使える領域を描画領域と定義する。
OpenGL座標は描画領域内で800x600にしている。
一方、SDL_FINGERDOWNで拾える座標はアイコン領域まで含めた全画面で(0,0)-(1,1)
SDL_FINGERDOWNで拾える描画領域内の最大値は1*(736/800)
<---1280 (Nexus 7)-->
+--------------------+A
| ||
| ||
| |736 (Nexus 7の場合) ここをDrawYとする
| ||
| |V
+--------------------+A
| ← △ □ : ||64 (Nexus 7の場合) こことDrawYでFullYとする
+--------------------+V
OpenGL座標 -> SDL_FINGERDOWN座標変換
x: ox / 800
y: oy / 600 * (DrawY/FullY)
Nexus 7の場合は oy / 600 * (736 / 800)
** 2013/8/17
* keyboard関連の解析
とりあえずKeyBuf[]にkeycodeを突っ込んでいく感じで。
keycodeはキーダウンは0x80が0で、キーアップは0x80が1な感じで。
** 2013/08/22, 23 PSPの遅さについて
MIDI_DelayOut()がものすごく遅くね?
これ削ると早くなる。
mainloopでNoWaitModeを有効にすれば早くなるけど早くなりすぎる
(オートフレームスキップ時)。
FrameRateは7でAuto Frame Skip
1だとフルフレーム描画
2だと2回に一回画面描画 -> 30fps
3だと3回に一回画面描画 -> 20fps
4だと4回に一回画面描画 -> 15fps
--> MIDI_DelayOut()削り、NoWaitModeでフレームスキップ4ぐらいだとよさげ。
** 2013/08/23
* サウンド関連の解析
ddwin.c/DSound_Init()内でSDL_OpenAudio()を呼び出す。この時のsamples
pcmfree = pcmfreemax = rate * buflen / 200 / 2 -> 2756
rateはConfig.SampleRate 22050
buflenはConfig.BufferSize 50
ds_halfbuffer = pcmfreemax * 4 -> 11024
samplesはpsfreemaxより大きい2のべき乗 -> 4096
samplesは1チャンネル分の大きさなのでステレオの場合はバッファ8192になる。
Send0呼び出し時のclock
216?, 432?の繰り返し px68k
210, 420の繰り返し xkeropi
** 2013/08/26
* サウンドバッファの見直し
- 現状だと、作成したデータの後半を取りこぼしたり、空のデータを食わせたり
してしまっている。
-> サウンドバッファをリングバッファに作り直す
pcmbuffer
+------+----------+----------------+
| |//////////| |
+------+----------+----------------+
A A
| |
| pcmbufwp 書き込みポインタ
|
pcmbufrp 読み込みポインタ
* fmgenの修正点
fmgen/fmgen.h
#define FM_SAMPLETYPE int16
fmgen/psg.h
#define PSG_SAMPLETYPE int16
** 2013/08/27
* winx68k-065s
+------------------+------------------+
| | |
+------------------+------------------+
<--ds_halfbuffer--> <--ds_halfbuffer-->
前半のバッファを書き出したらEvent=0
後半のバッファを書き出したらEvent=1
** 2013/09/03
* scan code
SDL_SCANCODE_MENU = 118,
SDL_SCANCODE_AC_BACK = 270,
* key code
SDLK_MENU = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MENU),
SDLK_AC_BACK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BACK),