OSDN Git Service

Merge branch 'master' of git.sourceforge.jp:/gitroot/heavyosecpu/HeavyOSECPU
[heavyosecpu/HeavyOSECPU.git] / function.c
1 #include "osecpu.h"
2
3 static struct {
4         unsigned stat[4], mat1, mat2, tmat;
5 } randStat;
6
7 static unsigned char fontdata[] = {
8         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9         0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,
10         0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11         0x00, 0x44, 0x44, 0x44, 0xfe, 0x44, 0x44, 0x44, 0x44, 0x44, 0xfe, 0x44, 0x44, 0x44, 0x00, 0x00,
12         0x10, 0x3a, 0x56, 0x92, 0x92, 0x90, 0x50, 0x38, 0x14, 0x12, 0x92, 0x92, 0xd4, 0xb8, 0x10, 0x10,
13         0x62, 0x92, 0x94, 0x94, 0x68, 0x08, 0x10, 0x10, 0x20, 0x2c, 0x52, 0x52, 0x92, 0x8c, 0x00, 0x00,
14         0x00, 0x70, 0x88, 0x88, 0x88, 0x90, 0x60, 0x47, 0xa2, 0x92, 0x8a, 0x84, 0x46, 0x39, 0x00, 0x00,
15         0x04, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
16         0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x00,
17         0x80, 0x40, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x40, 0x80, 0x00,
18         0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x92, 0x54, 0x38, 0x54, 0x92, 0x10, 0x00, 0x00, 0x00, 0x00,
19         0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xfe, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
20         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x08, 0x10,
21         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
22         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
23         0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x80, 0x80,
24         0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24, 0x18, 0x00, 0x00,
25         0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00,
26         0x00, 0x18, 0x24, 0x42, 0x42, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00,
27         0x00, 0x18, 0x24, 0x42, 0x02, 0x02, 0x04, 0x18, 0x04, 0x02, 0x02, 0x42, 0x24, 0x18, 0x00, 0x00,
28         0x00, 0x0c, 0x0c, 0x0c, 0x14, 0x14, 0x14, 0x24, 0x24, 0x44, 0x7e, 0x04, 0x04, 0x1e, 0x00, 0x00,
29         0x00, 0x7c, 0x40, 0x40, 0x40, 0x58, 0x64, 0x02, 0x02, 0x02, 0x02, 0x42, 0x24, 0x18, 0x00, 0x00,
30         0x00, 0x18, 0x24, 0x42, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00,
31         0x00, 0x7e, 0x42, 0x42, 0x04, 0x04, 0x08, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
32         0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x24, 0x18, 0x24, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00,
33         0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x42, 0x24, 0x18, 0x00, 0x00,
34         0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
35         0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x08, 0x10,
36         0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
37         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38         0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00,
39         0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x04, 0x08, 0x10, 0x10, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
40         0x00, 0x38, 0x44, 0x82, 0x9a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x9c, 0x80, 0x46, 0x38, 0x00, 0x00,
41         0x00, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x24, 0x24, 0x7e, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00,
42         0x00, 0xf0, 0x48, 0x44, 0x44, 0x44, 0x48, 0x78, 0x44, 0x42, 0x42, 0x42, 0x44, 0xf8, 0x00, 0x00,
43         0x00, 0x3a, 0x46, 0x42, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x82, 0x42, 0x44, 0x38, 0x00, 0x00,
44         0x00, 0xf8, 0x44, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x44, 0xf8, 0x00, 0x00,
45         0x00, 0xfe, 0x42, 0x42, 0x40, 0x40, 0x44, 0x7c, 0x44, 0x40, 0x40, 0x42, 0x42, 0xfe, 0x00, 0x00,
46         0x00, 0xfe, 0x42, 0x42, 0x40, 0x40, 0x44, 0x7c, 0x44, 0x44, 0x40, 0x40, 0x40, 0xf0, 0x00, 0x00,
47         0x00, 0x3a, 0x46, 0x42, 0x82, 0x80, 0x80, 0x9e, 0x82, 0x82, 0x82, 0x42, 0x46, 0x38, 0x00, 0x00,
48         0x00, 0xe7, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00,
49         0x00, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00,
50         0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x84, 0x48, 0x30, 0x00,
51         0x00, 0xe7, 0x42, 0x44, 0x48, 0x50, 0x50, 0x60, 0x50, 0x50, 0x48, 0x44, 0x42, 0xe7, 0x00, 0x00,
52         0x00, 0xf0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0xfe, 0x00, 0x00,
53         0x00, 0xc3, 0x42, 0x66, 0x66, 0x66, 0x5a, 0x5a, 0x5a, 0x42, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00,
54         0x00, 0xc7, 0x42, 0x62, 0x62, 0x52, 0x52, 0x52, 0x4a, 0x4a, 0x4a, 0x46, 0x46, 0xe2, 0x00, 0x00,
55         0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00, 0x00,
56         0x00, 0xf8, 0x44, 0x42, 0x42, 0x42, 0x44, 0x78, 0x40, 0x40, 0x40, 0x40, 0x40, 0xf0, 0x00, 0x00,
57         0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x92, 0x8a, 0x44, 0x3a, 0x00, 0x00,
58         0x00, 0xfc, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00,
59         0x00, 0x3a, 0x46, 0x82, 0x82, 0x80, 0x40, 0x38, 0x04, 0x02, 0x82, 0x82, 0xc4, 0xb8, 0x00, 0x00,
60         0x00, 0xfe, 0x92, 0x92, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00,
61         0x00, 0xe7, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x3c, 0x00, 0x00,
62         0x00, 0xe7, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x24, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00,
63         0x00, 0xe7, 0x42, 0x42, 0x42, 0x5a, 0x5a, 0x5a, 0x5a, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00,
64         0x00, 0xe7, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x24, 0x24, 0x24, 0x42, 0x42, 0xe7, 0x00, 0x00,
65         0x00, 0xee, 0x44, 0x44, 0x44, 0x28, 0x28, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00,
66         0x00, 0xfe, 0x84, 0x84, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x42, 0x82, 0xfe, 0x00, 0x00,
67         0x00, 0x3e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x00,
68         0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x04, 0x02, 0x02,
69         0x00, 0x7c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x7c, 0x00,
70         0x00, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00,
72         0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73         0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x04, 0x3c, 0x44, 0x84, 0x84, 0x8c, 0x76, 0x00, 0x00,
74         0xc0, 0x40, 0x40, 0x40, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x64, 0x58, 0x00, 0x00,
75         0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x4c, 0x84, 0x84, 0x80, 0x80, 0x82, 0x44, 0x38, 0x00, 0x00,
76         0x0c, 0x04, 0x04, 0x04, 0x04, 0x34, 0x4c, 0x84, 0x84, 0x84, 0x84, 0x84, 0x4c, 0x36, 0x00, 0x00,
77         0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0xfc, 0x80, 0x82, 0x42, 0x3c, 0x00, 0x00,
78         0x0e, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00,
79         0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x4c, 0x84, 0x84, 0x84, 0x84, 0x4c, 0x34, 0x04, 0x04, 0x78,
80         0xc0, 0x40, 0x40, 0x40, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0xe3, 0x00, 0x00,
81         0x00, 0x10, 0x10, 0x00, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
82         0x00, 0x04, 0x04, 0x00, 0x00, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x30,
83         0xc0, 0x40, 0x40, 0x40, 0x40, 0x4e, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0xe6, 0x00, 0x00,
84         0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
85         0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0xdb, 0x00, 0x00,
86         0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0xe3, 0x00, 0x00,
87         0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00, 0x00,
88         0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x64, 0x58, 0x40, 0xe0,
89         0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x4c, 0x84, 0x84, 0x84, 0x84, 0x84, 0x4c, 0x34, 0x04, 0x0e,
90         0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x62, 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0xe0, 0x00, 0x00,
91         0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x86, 0x82, 0xc0, 0x38, 0x06, 0x82, 0xc2, 0xbc, 0x00, 0x00,
92         0x00, 0x00, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, 0x00, 0x00,
93         0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3b, 0x00, 0x00,
94         0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00,
95         0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x42, 0x42, 0x5a, 0x5a, 0x5a, 0x24, 0x24, 0x24, 0x00, 0x00,
96         0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x44, 0x28, 0x28, 0x10, 0x28, 0x28, 0x44, 0xc6, 0x00, 0x00,
97         0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x10, 0x10, 0x60,
98         0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x84, 0x08, 0x10, 0x20, 0x42, 0x82, 0xfe, 0x00, 0x00,
99         0x00, 0x06, 0x08, 0x10, 0x10, 0x10, 0x10, 0x60, 0x10, 0x10, 0x10, 0x10, 0x08, 0x06, 0x00, 0x00,
100         0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
101         0x00, 0x60, 0x10, 0x08, 0x08, 0x08, 0x08, 0x06, 0x08, 0x08, 0x08, 0x08, 0x10, 0x60, 0x00, 0x00,
102         0x00, 0x72, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103         0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x82, 0xfe, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
104 };
105
106
107
108 // tinyMTの32bit版のアルゴリズムを使っています : http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index-jp.html
109 void randStatNext()
110 {
111         unsigned x, y;
112         x = (randStat.stat[0] & 0x7fffffff) ^ randStat.stat[1] ^ randStat.stat[2];
113         y = randStat.stat[3];
114         x ^= x << 1;
115         y ^= (y >> 1) ^ x;
116         randStat.stat[1] = randStat.stat[2] ^ (-((int)(y & 1)) & randStat.mat1);
117         randStat.stat[2] = x ^ (y << 10) ^ (-((int)(y & 1)) & randStat.mat2);
118         randStat.stat[3] = y;
119         return;
120 }
121
122 void randStatInit(unsigned seed)
123 {
124         int i;
125         randStat.stat[0] = seed;
126         randStat.stat[1] = randStat.mat1 = 0x8f7011ee;
127         randStat.stat[2] = randStat.mat2 = 0xfc78ff1f;
128         randStat.stat[3] = randStat.tmat = 0x3793fdff;
129         for (i = 1; i < 8; i++)
130                 randStat.stat[i & 3] ^= i + ((unsigned)1812433253) * (randStat.stat[(i - 1) & 3] ^ (randStat.stat[(i - 1) & 3] >> 30));
131         for (i = 0; i < 8; i++)
132                 randStatNext();
133         return;
134 }
135
136 const char *searchArg(int argc, const char **argv, const char *tag, int i)
137 {
138         int j, l;
139         const char *r = NULL;
140         if (tag != NULL) {
141                 l = (int)strlen(tag);
142                 for (j = 1; j < argc; j++) {
143                         if (strncmp(argv[j], tag, l) == 0) {
144                                 r = argv[j] + l;
145                                 if (i == 0)     break;
146                                 i--;
147                         }
148                 }
149         }
150         else {
151                 for (j = 1; j < argc; j++) {
152                         if (strchr(argv[j], ':') == NULL) {
153                                 r = argv[j];
154                                 if (i == 0)     break;
155                                 i--;
156                         }
157                 }
158         }
159         if (i != 0) r = NULL;
160         return r;
161 }
162
163 void devFunc0001(int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)
164 {
165         while (len > 0) {
166                 putOsaskChar(*puc++, r);
167                 len--;
168         }
169         return;
170 }
171
172 void devFunc0006(int mod, int sx, int sy, int x, int y, int c, int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)
173 {
174         if (sy == 0) sy = sx;
175         int xx = x + sx * 8;
176         int yy = y + sy * 16;
177         if (xx <= 0 || xx > v_xsiz || yy <= 0 || yy > v_ysiz)
178                 (*(r->errHndl))(r);
179         if (x < 0 || x >= v_xsiz || y < 0 || y >= v_ysiz)
180                 (*(r->errHndl))(r);
181         int i, ddx, ddy, j, ch, dx, dy;
182
183         if ((mod & 3) == 0 && sx == 1 && sy == 1) {
184                 // メジャーケースを高速化.
185                 for (i = 0; i < len; i++) {
186                         ch = puc[i];
187                         if (0x10 <= ch && ch <= 0x1f)
188                                 ch = "0123456789ABCDEF"[ch & 0x0f];
189                         for (dy = 0; dy < 16; dy++) {
190                                 j = fontdata[(ch - ' ') * 16 + dy];
191                                 for (dx = 0; dx < 8; dx++) {
192                                         if ((j & (0x80 >> dx)) != 0) vram[(x + dx) + (y + dy) * v_xsiz] = c;
193                                 }
194                         }
195                         x += 8;
196                 }
197                 return;
198         }
199         for (i = 0; i < len; i++) {
200                 ch = puc[i];
201                 if (0x10 <= ch && ch <= 0x1f)
202                         ch = "0123456789ABCDEF"[ch & 0x0f];
203                 for (dy = 0; dy < 16; dy++) {
204                         j = fontdata[(ch - ' ') * 16 + dy];
205                         for (ddy = 0; ddy < sy; ddy++) {
206                                 for (dx = 0; dx < 8; dx++) {
207                                         if ((j & (0x80 >> dx)) != 0) {
208                                                 for (ddx = 0; ddx < sx; ddx++) {
209                                                         if ((mod & 3) == 0) vram[x + y * v_xsiz] = c;
210                                                         if ((mod & 3) == 1) vram[x + y * v_xsiz] |= c;
211                                                         if ((mod & 3) == 2) vram[x + y * v_xsiz] ^= c;
212                                                         if ((mod & 3) == 3) vram[x + y * v_xsiz] &= c;
213                                                         x++;
214                                                 }
215                                         }
216                                         else
217                                                 x += sx;
218                                 }
219                                 x -= sx * 8;
220                                 y++;
221                         }
222                 }
223                 x += sx * 8;
224                 y -= sy * 16;
225         }
226         return;
227 }
228
229 void devFunc0004(int mod, int x0, int y0, int x1, int y1, int c)
230 {
231         int x, y;
232         if (mod == 0) {
233                 for (y = y0; y <= y1; y++) {
234                         for (x = x0; x <= x1; x++) {
235                                 vram[x + y * v_xsiz] = c;
236                         }
237                 }
238         }
239         else {
240                 for (y = y0; y <= y1; y++) {
241                         for (x = x0; x <= x1; x++) {
242                                 if (mod == 1) vram[x + y * v_xsiz] |= c;
243                                 if (mod == 2) vram[x + y * v_xsiz] ^= c;
244                                 if (mod == 3) vram[x + y * v_xsiz] &= c;
245                         }
246                 }
247         }
248         return;
249 }
250
251 int devFunc0016(int buflen, unsigned char *buf, int plen, unsigned char *p, int qlen, int *q, HOSECPU_RuntimeEnvironment *r)
252 {
253         int i = 0, base, j, k;
254         char sign;
255         while (plen > 0) {
256                 if (i >= buflen)
257                         (*(r->errHndl))(r);
258                 if (*p != 0x01) {
259                         buf[i++] = *p++;
260                         plen--;
261                         continue;
262                 }
263                 p++;
264                 plen--;
265                 if (qlen < 4)
266                         (*(r->errHndl))(r);
267                 base = q[0];
268                 sign = 0;
269                 if (base == 0) base = 16;
270 #if (REVISION == 1)
271                 if (base == -3) base = 10;
272 #endif
273                 if (base == -1) base = 10;
274                 if (base < 0 || base > 16)
275                         (*(r->errHndl))(r);
276                 if (q[1] + i > buflen)
277                         (*(r->errHndl))(r);
278                 j = q[3];
279                 if ((q[2] & 4) == 0) {
280                         // jは符号付き整数.
281                         if ((q[2] & 8) != 0 && j > 0) sign = '+';
282                         if (j < 0) { sign = '-'; j *= -1; }
283                 }
284                 else {
285                         // jは符号無し整数.
286                         if ((q[2] & 8) != 0 && j != 0) sign = '+';
287                 }
288                 for (k = q[1] - 1; k >= 0; k--) {
289                         buf[i + k] = (j % base) + 0x10;
290                         j = ((unsigned)j) / base;
291                 }
292                 k = 0;
293                 if ((q[2] & 2) == 0 && j == 0) {
294                         for (k = 0; k < q[1] - 1; k++) {
295                                 if (buf[i + k] != 0x10) break;
296                                 buf[i + k] = ' ';
297                         }
298                 }
299                 if (sign != 0) {
300                         if (k > 0) k--;
301                         buf[i + k] = sign;
302                 }
303                 if ((q[2] & 1) != 0 && buf[i] == ' ') {
304                         for (j = 0; k < q[1]; k++, j++)
305                                 buf[i + j] = buf[i + k];
306                         i += j;
307                 }
308                 else
309                         i += q[1];
310                 qlen -= 4;
311                 q += 4;
312         }
313         return i;
314 }
315
316 void devFunc(HOSECPU_RuntimeEnvironment *r)
317 {
318         FILE *fp;
319         r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - 128); /* サイズを節約するためにEBPを128バイトずらしているのを元に戻す */
320         int i, c;
321         int x, y, len, dx, dy;
322         unsigned char *puc;
323         unsigned char pucbuf[256];
324         if (r->winClosed != 0)
325                 longjmp(*(r->setjmpEnv), 1);
326         if (0xff44 <= r->ireg[0x30] && r->ireg[0x30] <= 0xff48) {
327                 if (vram == NULL) {
328                         v_xsiz = 640;
329                         v_ysiz = 480;
330                         vram = malloc(640 * 480 * 4);
331                         drv_openWin(640, 480, (void *)vram, &r->winClosed);
332                         r->autoSleep = 1;
333                         for (i = 640 * 480 - 1; i >= 0; i--)
334                                 vram[i] = 0;
335                 }
336         }
337
338         switch (r->ireg[0x30]) {
339         case 0xff00:
340                 printf("R31=%d(dec)\n", r->ireg[0x31]);
341                 break;
342
343         case 0xff01:
344                 /* return: R30, P31 */
345                 if (r->buf0 == NULL)
346                         r->buf0 = malloc(1024 * 1024);
347                 if (r->mainArgc <= r->ireg[0x31]) {
348                         fprintf(stderr, "devFunc: error: R30=ff01: argc error: R31=%08X\n", r->ireg[0x31]);
349                         exit(1);
350                 }
351                 fp = fopen(r->mainArgv[r->ireg[0x31]], "rb");
352                 if (fp == NULL) {
353                         fprintf(stderr, "devFunc: error: R30=ff01: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
354                         exit(1);
355                 }
356                 i = (int)fread(r->buf0, 1, 1024 * 1024 - 4, fp);
357                 if (i >= 1024 * 1024 - 4 || i < 0) {
358                         fprintf(stderr, "devFunc: error: R30=ff01: fread error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
359                         exit(1);
360                 }
361                 fclose(fp);
362                 r->preg[0x31].p = r->buf0;
363                 r->preg[0x31].p0 = r->buf0;
364                 r->preg[0x31].p1 = r->buf0 + i;
365                 r->preg[0x31].typ = 3; // T_UINT8
366                 r->ireg[0x30] = i;
367                 break;
368
369         case 0xff02:
370                 /* return: none */
371                 if (r->mainArgc <= r->ireg[0x31]) {
372                         fprintf(stderr, "devFunc: error: R30=ff02: argc error: R31=%08X\n", r->ireg[0x31]);
373                         exit(1);
374                 }
375                 fp = fopen(r->mainArgv[r->ireg[0x31]], "wb");
376                 if (fp == NULL) {
377                         fprintf(stderr, "devFunc: error: R30=ff02: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
378                         exit(1);
379                 }
380                 if (r->ireg[0x32] >= 1024 * 1024 || r->ireg[0x32] < 0){
381                         fprintf(stderr, "devFunc: error: R30=ff02: fwrite error: R02=%08X\n", r->ireg[0x32]);
382                         exit(1);
383                 }
384                 fwrite(r->preg[0x31].p, 1, r->ireg[0x32], fp);
385                 fclose(fp);
386                 break;
387
388         case 0xff03:
389                 /* return: P31 */
390                 if (r->buf1 == NULL)
391                         r->buf1 = malloc(1024 * 1024);
392                 r->preg[0x31].p = r->buf1;
393                 r->preg[0x31].p0 = r->buf1;
394                 r->preg[0x31].p1 = r->buf1 + 1024 * 1024;
395                 break;
396
397         case 0xff04:
398                 printf("P31.(p-p0)=%d(dec)\n", (int)(r->preg[0x31].p - r->preg[0x31].p0));
399                 break;
400
401         case 0xff05:
402                 fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout);
403                 break;
404
405         case 0xff06:
406                 // R31はリターンコード.
407                 // これを反映すべきだが、現状は手抜きでいつも正常終了.
408                 longjmp(*(r->setjmpEnv), 1);
409                 break;
410
411         case 0xff07:
412                 // マシになった文字列表示.OSASK文字列に対応.offにすれば通常の文字列処理もできる.現状はonのみサポート.
413                 checkString(r, 0x31, 0x31);
414                 devFunc0001(r->ireg[0x31], r->preg[0x31].p, r);
415                 break;
416
417         case 0xff08:
418                 // JITC on JITC
419                 // R31: 言語(back-end, front-end, ...
420                 // R32: level
421                 // R33: debugInfo1
422                 checkString(r, 0x34, 0x31);
423                 if (r->ireg[0x33] < 0 || r->ireg[0x33] > 15 || r->debugInfo1 > 15)
424                         (*(r->errHndl))(r);
425                 for (i = 0; i < r->maxLabels; i++)
426                         r->label[i].opt = 0;
427                 puc = r->preg[0x31].p;
428                 i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + 0);
429                 if (i == 0) {
430                         i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + JITC_PHASE1 + 0);
431                         if (i >= 0) {
432                                 r->mapDi1s[r->debugInfo1][r->ireg[0x33]] = di1_serial;
433                                 di1_serial++;
434                                 r->ireg[0x30] = 0;
435                                 r->preg[0x31].p = r->jitbuf;
436                                 r->preg[0x31].typ = 0; // TYP_CODE
437                                 r->preg[0x31].p0 = r->jitbuf;
438                                 r->preg[0x31].p1 = r->jitbuf + 1;
439                                 //int j; for (j = 0; j < i; j++) printf("%02X ", r->jitbuf[j]); putchar('\n');
440                                 r->jitbuf += i;
441                                 static unsigned char ff08_ret[3] = { 0x1e, 0x3f, 0x30 };
442                                 i = jitCompiler(r->jitbuf, r->jitbuf1, ff08_ret, ff08_ret + 3, puc, r->label, r->maxLabels, r->ireg[0x32], -1, JITC_NOSTARTUP + JITC_PHASE1 + 0);
443                                 r->jitbuf += i;
444                                 break;
445                         }
446                 }
447                 r->ireg[0x30] = -1;
448                 break;
449
450         case 0xff09:
451                 // たぶんbit7を使ったテキストはうまく処理できない(これはもはや仕様にしても問題ないかも).
452                 checkString(r, 0x31, 0x31);
453                 len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x31], r->preg[0x31].p, r->ireg[0x32], (int *)r->preg[0x32].p, r);
454                 devFunc0001(len, pucbuf, r);
455                 break;
456
457         case 0xff40:
458                 /* R31とR32でサイズを指定 */
459                 v_xsiz = r->ireg[0x31];
460                 v_ysiz = r->ireg[0x32];
461                 if (v_xsiz <= 0 || v_ysiz <= 0)
462                         (*(r->errHndl))(r);
463                 r->preg[0x31].p = (void *)(vram = malloc(v_xsiz * v_ysiz * 4));
464                 r->preg[0x31].p0 = r->preg[0x31].p;
465                 r->preg[0x31].p1 = r->preg[0x31].p + v_xsiz * v_ysiz * 4;
466                 drv_openWin(r->ireg[0x31], r->ireg[0x32], r->preg[0x31].p, &r->winClosed);
467                 //      drv_flshWin(r->ireg[1], r->ireg[2], 0, 0);
468                 r->autoSleep = 1;
469                 for (i = v_xsiz * v_ysiz - 1; i >= 0; i--)
470                         vram[i] = 0;
471                 break;
472
473         case 0xff41:
474                 /* R31とR32でサイズを指定、R33とR34でx0,y0指定 */
475                 if (r->ireg[0x31] == -1) { r->ireg[0x31] = v_xsiz; r->ireg[0x33] &= 0; }
476                 if (r->ireg[0x32] == -1) { r->ireg[0x32] = v_ysiz; r->ireg[0x34] &= 0; }
477                 checkRect(r, 0x31);
478                 drv_flshWin(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34]);
479                 break;
480
481         case 0xff42:
482                 if (r->ireg[0x32] == -1) {
483                         r->autoSleep = 1;
484                         longjmp(*(r->setjmpEnv), 1);
485                 }
486                 if (r->ireg[0x32] < 0)
487                         (*(r->errHndl))(r);
488                 r->autoSleep = 0;
489                 if ((r->ireg[0x31] & 1) == 0 && vram != NULL)
490                         drv_flshWin(v_xsiz, v_ysiz, 0, 0);
491                 for (;;) {
492                         if (r->winClosed != 0)
493                                 longjmp(*(r->setjmpEnv), 1);
494                         drv_sleep(r->ireg[0x32]);
495                         if ((r->ireg[0x31] & 2) != 0 && keybuf_c <= 0) continue;
496                         break;
497                 }
498                 break;
499
500         case 0xff43:
501                 //  1:peek
502                 //  2:stdin
503                 //      4,8: ソース指定.
504                 //      16: shift, lock系を有効化.
505                 //      32: 左右のshift系を区別する.
506                 if (r->ireg[0x31] == 2) {       // なぜ3にしなかったのか...
507                         r->ireg[0x30] = fgetc(stdin);
508                         if (r->ireg[0x30] == EOF)
509                                 r->ireg[0x30] = -1;
510                         break;
511                 }
512                 r->ireg[0x30] |= -1;
513                 if (keybuf_c > 0) {
514                         r->ireg[0x30] = keybuf[keybuf_r];
515                         if ((r->ireg[0x31] & 16) == 0) r->ireg[0x30] &= 0x3e3effff;
516                         if ((r->ireg[0x31] & 32) == 0) r->ireg[0x30] |= (r->ireg[0x30] >> 8) & 0xff0000;
517                         if ((r->ireg[0x31] & 1) != 0) {
518                                 keybuf_c--;
519                                 keybuf_r = (keybuf_r + 1) & (KEYBUFSIZ - 1);
520                         }
521                 }
522                 r->ireg[0x32] = r->ireg[0x33] = 0;
523                 if (r->ireg[0x30] == 4132) r->ireg[0x32]--;
524                 if (r->ireg[0x30] == 4133) r->ireg[0x33]--;
525                 if (r->ireg[0x30] == 4134) r->ireg[0x32]++;
526                 if (r->ireg[0x30] == 4135) r->ireg[0x33]++;
527                 break;
528
529         case 0xff44:
530                 c = loadColor(r, 0x34);
531                 if (r->ireg[0x32] < 0 || r->ireg[0x32] >= v_xsiz || r->ireg[0x33] < 0 || r->ireg[0x33] >= v_ysiz)
532                         (*(r->errHndl))(r);
533                 if ((r->ireg[0x31] & 3) == 0) vram[r->ireg[0x32] + r->ireg[0x33] * v_xsiz] = c;
534                 if ((r->ireg[0x31] & 3) == 1) vram[r->ireg[0x32] + r->ireg[0x33] * v_xsiz] |= c;
535                 if ((r->ireg[0x31] & 3) == 2) vram[r->ireg[0x32] + r->ireg[0x33] * v_xsiz] ^= c;
536                 if ((r->ireg[0x31] & 3) == 3) vram[r->ireg[0x32] + r->ireg[0x33] * v_xsiz] &= c;
537                 break;
538
539         case 0xff45:
540                 c = loadColor(r, 0x36);
541                 if (r->ireg[0x32] < 0 || r->ireg[0x32] >= v_xsiz || r->ireg[0x33] < 0 || r->ireg[0x33] >= v_ysiz)
542                         (*(r->errHndl))(r);
543                 if (r->ireg[0x34] < 0 || r->ireg[0x34] >= v_xsiz || r->ireg[0x35] < 0 || r->ireg[0x35] >= v_ysiz)
544                         (*(r->errHndl))(r);
545                 dx = r->ireg[0x34] - r->ireg[0x32];
546                 dy = r->ireg[0x35] - r->ireg[0x33];
547                 x = r->ireg[0x32] << 10;
548                 y = r->ireg[0x33] << 10;
549                 if (dx < 0) dx = -dx;
550                 if (dy < 0) dy = -dy;
551                 if (dx >= dy) {
552                         len = dx + 1; dx = 1024;
553                         if (r->ireg[0x32] > r->ireg[0x34]) dx *= -1;
554                         if (r->ireg[0x33] > r->ireg[0x35]) dy *= -1;
555                         dy = (dy << 10) / len;
556                 }
557                 else {
558                         len = dy + 1; dy = 1024;
559                         if (r->ireg[0x33] > r->ireg[0x35]) dy *= -1;
560                         if (r->ireg[0x32] > r->ireg[0x34]) dx *= -1;
561                         dx = (dx << 10) / len;
562                 }
563                 if ((r->ireg[0x31] & 3) == 0) {
564                         for (i = 0; i < len; i++) {
565                                 vram[(x >> 10) + (y >> 10) * v_xsiz] = c;
566                                 x += dx;
567                                 y += dy;
568                         }
569                         break;
570                 }
571                 for (i = 0; i < len; i++) {
572                         //      if ((r->ireg[0x31] & 3) == 0) vram[(x >> 10) + (y >> 10) * v_xsiz] =  c;
573                         if ((r->ireg[0x31] & 3) == 1) vram[(x >> 10) + (y >> 10) * v_xsiz] |= c;
574                         if ((r->ireg[0x31] & 3) == 2) vram[(x >> 10) + (y >> 10) * v_xsiz] ^= c;
575                         if ((r->ireg[0x31] & 3) == 3) vram[(x >> 10) + (y >> 10) * v_xsiz] &= c;
576                         x += dx;
577                         y += dy;
578                 }
579                 break;
580
581         case 0xff46:    // fillRect(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
582                 c = loadColor(r, 0x36);
583                 if (r->ireg[0x32] == -1) { r->ireg[0x32] = v_xsiz; r->ireg[0x34] &= 0; }
584                 if (r->ireg[0x33] == -1) { r->ireg[0x33] = v_ysiz; r->ireg[0x35] &= 0; }
585                 checkRect(r, 0x32);
586                 int mod3 = r->ireg[0x31] & 3, x0 = r->ireg[0x34], y0 = r->ireg[0x35], x1 = r->ireg[0x34] + r->ireg[0x32] - 1, y1 = r->ireg[0x35] + r->ireg[0x33] - 1;
587                 if ((r->ireg[0x31] & 0x20) == 0) {
588                         devFunc0004(mod3, x0, y0, x1, y1, c);
589                 }
590                 else {  // drawRect
591                         devFunc0004(mod3, x0, y0, x1, y0, c);
592                         devFunc0004(mod3, x0, y1, x1, y1, c);
593                         devFunc0004(mod3, x0, y0, x0, y1, c);
594                         devFunc0004(mod3, x1, y0, x1, y1, c);
595                 }
596                 break;
597
598         case 0xff47:    // fillOval(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
599                 // これの計算精度はアーキテクチャに依存する.
600                 c = loadColor(r, 0x36);
601                 if (r->ireg[0x32] == -1) { r->ireg[0x32] = v_xsiz; r->ireg[0x34] &= 0; }
602                 if (r->ireg[0x33] == -1) { r->ireg[0x33] = v_ysiz; r->ireg[0x35] &= 0; }
603                 checkRect(r, 0x32);
604                 double dcx = 0.5 * (r->ireg[0x32] - 1), dcy = 0.5 * (r->ireg[0x33] - 1), dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1;
605                 dcxy *= dcxy;
606                 mod3 = r->ireg[0x31] & 3;
607                 x1 = r->ireg[0x32];
608                 y1 = r->ireg[0x33];
609                 if (mod3 == 0 && (r->ireg[0x31] & 0x20) == 0) {
610                         for (y = 0; y < y1; y++) {
611                                 double dty = (y - dcy) * dcx;
612                                 for (x = 0; x < x1; x++) {
613                                         double dtx = (x - dcx) * dcy;
614                                         if (dtx * dtx + dty * dty > dcxy) continue;
615                                         vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] = c;
616                                 }
617                         }
618                 }
619                 else {
620 #define DRAWOVALPARAM   1
621                         double dcx1 = 0.5 * (r->ireg[0x32] - (1 + DRAWOVALPARAM * 2)), dcy1 = 0.5 * (r->ireg[0x33] - (1 + DRAWOVALPARAM * 2)), dcxy1 = (dcx1 + 0.5) * (dcy1 + 0.5) - 0.1;
622                         dcxy1 *= dcxy1;
623                         for (y = 0; y < y1; y++) {
624                                 double dty = (y - dcy) * dcx;
625                                 double dty1 = (y - dcy) * dcx1;
626                                 for (x = 0; x < x1; x++) {
627                                         double dtx = (x - dcx) * dcy;
628                                         double dtx1 = (x - dcx) * dcy1;
629                                         if (dtx * dtx + dty * dty > dcxy) continue;
630                                         if (DRAWOVALPARAM <= x && x < x1 - DRAWOVALPARAM && DRAWOVALPARAM <= y && y < y1 - DRAWOVALPARAM) {
631                                                 if (dtx1 * dtx1 + dty1 * dty1 < dcxy1) continue;
632                                         }
633                                         if (mod3 == 0) vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] = c;
634                                         if (mod3 == 1) vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] |= c;
635                                         if (mod3 == 2) vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] ^= c;
636                                         if (mod3 == 3) vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] &= c;
637                                 }
638                         }
639                 }
640                 break;
641
642         case 0xff48:    // drawString(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36, s.len:R37, s.p:P31)
643                 checkString(r, 0x37, 0x31);
644                 devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), r->ireg[0x37], r->preg[0x31].p, r);
645                 break;
646
647         case 0xff49:    /* 適当な乱数を返す */
648                 randStatNext();
649                 unsigned u32t;
650                 u32t = randStat.stat[0] + (randStat.stat[2] >> 8);
651                 r->ireg[0x30] = randStat.stat[3] ^ u32t ^ (-((int)(u32t & 1)) & randStat.tmat);
652                 if (r->ireg[0x31] > 0)
653                         r->ireg[0x30] = (r->ireg[0x30] & 0x7fffffff) % (r->ireg[0x31] + 1);
654                 break;
655
656         case 0xff4a:    /* seedの指定 */
657                 randStatInit(r->ireg[0x31]);
658                 break;
659
660         case 0xff4b:    /* 適当なseedを提供 */
661                 r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);
662                 break;
663
664         case 0xff4c:
665                 checkString(r, 0x37, 0x31);
666                 len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x37], r->preg[0x31].p, r->ireg[0x38], (int *)r->preg[0x32].p, r);
667                 devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), len, pucbuf, r);
668                 break;
669
670         case 0xff4d:
671                 // bitblt(mod, xsiz, ysiz, xscale, yscale, x0, y0, lineskip, inv, p_buf, typ0, p_table, typ1); 
672                 // mod: 0x20:use_table, 0x40:inv_is_visible & typ1_is_color
673                 puc = r->preg[0x31].p;
674                 mod3 = r->ireg[0x31] & 3;
675                 dx = r->ireg[0x34];
676                 dy = r->ireg[0x35];
677                 if (dy == 0) dy = dx;
678                 if (r->ireg[0x32] == -1) { r->ireg[0x32] = v_xsiz / dx; r->ireg[0x36] &= 0; }
679                 if (r->ireg[0x33] == -1) { r->ireg[0x33] = v_ysiz / dy; r->ireg[0x37] &= 0; }
680                 for (y = 0; y < r->ireg[0x33]; y++) {
681                         y0 = y * dy + r->ireg[0x37];
682                         for (x = 0; x < r->ireg[0x32]; x++) {
683                                 x0 = x * dx + r->ireg[0x36];
684                                 c = iColor1[*puc++];
685                                 devFunc0004(mod3, x0, y0, x0 + dx, y0 + dy, c);
686                         }
687                         puc += r->ireg[0x38];
688                 }
689                 break;
690
691         default:
692                 printf("devFunc: error: R30=%08X\n", r->ireg[0x30]);
693                 exit(1);
694
695         }
696         return;
697 }
698
699
700