OSDN Git Service

19ba8d9d6fd860a9fc3616a6d97df945d5f4cccd
[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         //drawLine
541                 c = loadColor(r, 0x36);
542                 if (r->ireg[0x32] < 0 || r->ireg[0x32] >= v_xsiz || r->ireg[0x33] < 0 || r->ireg[0x33] >= v_ysiz)
543                         (*(r->errHndl))(r);
544                 if (r->ireg[0x34] < 0 || r->ireg[0x34] >= v_xsiz || r->ireg[0x35] < 0 || r->ireg[0x35] >= v_ysiz)
545                         (*(r->errHndl))(r);
546                 dx = r->ireg[0x34] - r->ireg[0x32];
547                 dy = r->ireg[0x35] - r->ireg[0x33];
548                 x = r->ireg[0x32] << 10;
549                 y = r->ireg[0x33] << 10;
550                 if (dx < 0) dx = -dx;
551                 if (dy < 0) dy = -dy;
552                 if (dx >= dy) {
553                         len = dx + 1; dx = 1024;
554                         if (r->ireg[0x32] > r->ireg[0x34]) dx *= -1;
555                         if (r->ireg[0x33] > r->ireg[0x35]) dy *= -1;
556                         dy = (dy << 10) / len;
557                 }
558                 else {
559                         len = dy + 1; dy = 1024;
560                         if (r->ireg[0x33] > r->ireg[0x35]) dy *= -1;
561                         if (r->ireg[0x32] > r->ireg[0x34]) dx *= -1;
562                         dx = (dx << 10) / len;
563                 }
564                 if ((r->ireg[0x31] & 3) == 0) {
565                         for (i = 0; i < len; i++) {
566                                 vram[(x >> 10) + (y >> 10) * v_xsiz] = c;
567                                 x += dx;
568                                 y += dy;
569                         }
570                         break;
571                 }
572                 for (i = 0; i < len; i++) {
573                         //      if ((r->ireg[0x31] & 3) == 0) vram[(x >> 10) + (y >> 10) * v_xsiz] =  c;
574                         if ((r->ireg[0x31] & 3) == 1) vram[(x >> 10) + (y >> 10) * v_xsiz] |= c;
575                         if ((r->ireg[0x31] & 3) == 2) vram[(x >> 10) + (y >> 10) * v_xsiz] ^= c;
576                         if ((r->ireg[0x31] & 3) == 3) vram[(x >> 10) + (y >> 10) * v_xsiz] &= c;
577                         x += dx;
578                         y += dy;
579                 }
580                 break;
581
582         case 0xff46:    // fillRect(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
583                 c = loadColor(r, 0x36);
584                 if (r->ireg[0x32] == -1) { r->ireg[0x32] = v_xsiz; r->ireg[0x34] &= 0; }
585                 if (r->ireg[0x33] == -1) { r->ireg[0x33] = v_ysiz; r->ireg[0x35] &= 0; }
586                 checkRect(r, 0x32);
587                 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;
588                 if ((r->ireg[0x31] & 0x20) == 0) {
589                         devFunc0004(mod3, x0, y0, x1, y1, c);
590                 }
591                 else {  // drawRect
592                         devFunc0004(mod3, x0, y0, x1, y0, c);
593                         devFunc0004(mod3, x0, y1, x1, y1, c);
594                         devFunc0004(mod3, x0, y0, x0, y1, c);
595                         devFunc0004(mod3, x1, y0, x1, y1, c);
596                 }
597                 break;
598
599         case 0xff47:    // fillOval(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
600                 // これの計算精度はアーキテクチャに依存する.
601                 c = loadColor(r, 0x36);
602                 if (r->ireg[0x32] == -1) { r->ireg[0x32] = v_xsiz; r->ireg[0x34] &= 0; }
603                 if (r->ireg[0x33] == -1) { r->ireg[0x33] = v_ysiz; r->ireg[0x35] &= 0; }
604                 checkRect(r, 0x32);
605                 double dcx = 0.5 * (r->ireg[0x32] - 1), dcy = 0.5 * (r->ireg[0x33] - 1), dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1;
606                 dcxy *= dcxy;
607                 mod3 = r->ireg[0x31] & 3;
608                 x1 = r->ireg[0x32];
609                 y1 = r->ireg[0x33];
610                 if (mod3 == 0 && (r->ireg[0x31] & 0x20) == 0) {
611                         for (y = 0; y < y1; y++) {
612                                 double dty = (y - dcy) * dcx;
613                                 for (x = 0; x < x1; x++) {
614                                         double dtx = (x - dcx) * dcy;
615                                         if (dtx * dtx + dty * dty > dcxy) continue;
616                                         vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] = c;
617                                 }
618                         }
619                 }
620                 else {
621 #define DRAWOVALPARAM   1
622                         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;
623                         dcxy1 *= dcxy1;
624                         for (y = 0; y < y1; y++) {
625                                 double dty = (y - dcy) * dcx;
626                                 double dty1 = (y - dcy) * dcx1;
627                                 for (x = 0; x < x1; x++) {
628                                         double dtx = (x - dcx) * dcy;
629                                         double dtx1 = (x - dcx) * dcy1;
630                                         if (dtx * dtx + dty * dty > dcxy) continue;
631                                         if (DRAWOVALPARAM <= x && x < x1 - DRAWOVALPARAM && DRAWOVALPARAM <= y && y < y1 - DRAWOVALPARAM) {
632                                                 if (dtx1 * dtx1 + dty1 * dty1 < dcxy1) continue;
633                                         }
634                                         if (mod3 == 0) vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] = c;
635                                         if (mod3 == 1) vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] |= c;
636                                         if (mod3 == 2) vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] ^= c;
637                                         if (mod3 == 3) vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] &= c;
638                                 }
639                         }
640                 }
641                 break;
642
643         case 0xff48:    // drawString(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36, s.len:R37, s.p:P31)
644                 checkString(r, 0x37, 0x31);
645                 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);
646                 break;
647
648         case 0xff49:    /* 適当な乱数を返す */
649                 randStatNext();
650                 unsigned u32t;
651                 u32t = randStat.stat[0] + (randStat.stat[2] >> 8);
652                 r->ireg[0x30] = randStat.stat[3] ^ u32t ^ (-((int)(u32t & 1)) & randStat.tmat);
653                 if (r->ireg[0x31] > 0)
654                         r->ireg[0x30] = (r->ireg[0x30] & 0x7fffffff) % (r->ireg[0x31] + 1);
655                 break;
656
657         case 0xff4a:    /* seedの指定 */
658                 randStatInit(r->ireg[0x31]);
659                 break;
660
661         case 0xff4b:    /* 適当なseedを提供 */
662                 r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);
663                 break;
664
665         case 0xff4c:
666                 checkString(r, 0x37, 0x31);
667                 len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x37], r->preg[0x31].p, r->ireg[0x38], (int *)r->preg[0x32].p, r);
668                 devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), len, pucbuf, r);
669                 break;
670
671         case 0xff4d:
672                 // bitblt(mod, xsiz, ysiz, xscale, yscale, x0, y0, lineskip, inv, p_buf, typ0, p_table, typ1); 
673                 // mod: 0x20:use_table, 0x40:inv_is_visible & typ1_is_color
674                 puc = r->preg[0x31].p;
675                 mod3 = r->ireg[0x31] & 3;
676                 dx = r->ireg[0x34];
677                 dy = r->ireg[0x35];
678                 if (dy == 0) dy = dx;
679                 if (r->ireg[0x32] == -1) { r->ireg[0x32] = v_xsiz / dx; r->ireg[0x36] &= 0; }
680                 if (r->ireg[0x33] == -1) { r->ireg[0x33] = v_ysiz / dy; r->ireg[0x37] &= 0; }
681                 for (y = 0; y < r->ireg[0x33]; y++) {
682                         y0 = y * dy + r->ireg[0x37];
683                         for (x = 0; x < r->ireg[0x32]; x++) {
684                                 x0 = x * dx + r->ireg[0x36];
685                                 c = iColor1[*puc++];
686                                 devFunc0004(mod3, x0, y0, x0 + dx, y0 + dy, c);
687                         }
688                         puc += r->ireg[0x38];
689                 }
690                 break;
691
692         default:
693                 printf("devFunc: error: R30=%08X\n", r->ireg[0x30]);
694                 exit(1);
695
696         }
697         return;
698 }
699
700
701