Subversion Repositories Shiroi

Rev

Rev 2 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 nishi 1
/* $Id: shiroi.c 1 2024-08-28 08:10:28Z nishi $ */
2
 
3
unsigned char inp(unsigned char);
4
void outp(unsigned char, unsigned char);
5
void write_vram(unsigned short);
6
void putchar(char);
7
void putstr(char*);
8
void scroll_y(void);
9
void beep(void);
10
void _beep(unsigned long howlong);
11
void init_cards(void);
12
 
13
unsigned short posx;
14
unsigned short posy;
15
 
16
short vdp_addr;
17
short vdp_data;
18
short psg_addr;
19
short psg_data;
20
short fpu_addr;
21
short fpu_data;
22
 
23
void main(void) {
24
	int i;
25
 
26
	posx = 0;
27
	posy = 0;
28
 
29
	vdp_addr = -1;
30
	psg_addr = -1;
31
	fpu_addr = -1;
32
 
33
	init_cards();
34
 
35
	if(vdp_addr == -1) {
36
		int i;
37
		for(i = 0; i < 3; i++) {
38
			_beep(3L * 1024);
39
			unsigned long j;
40
			for(j = 0; j < 3L * 1024; j++)
41
				;
42
		}
43
		while(1)
44
			;
45
	}
46
 
47
	outp(vdp_addr, 0x00);
48
	outp(vdp_addr, 0x80);
49
 
50
	outp(vdp_addr, 0xd0);
51
	outp(vdp_addr, 0x81);
52
 
53
	outp(vdp_addr, 0x02);
54
	outp(vdp_addr, 0x82);
55
 
56
	outp(vdp_addr, 0x00);
57
	outp(vdp_addr, 0x84);
58
 
59
	outp(vdp_addr, 0xf4);
60
	outp(vdp_addr, 0x87);
61
 
62
	write_vram(0);
63
	for(i = 0; i < 0x800; i++) outp(vdp_data, *((unsigned char*)(0x2000 + i)));
64
 
65
	beep();
66
 
67
	putstr("Shiroi Microcomputer BASIC\r\n");
68
	if(fpu_addr == -1) {
69
		putstr("Math Card Mark I not present\r\n");
70
	} else {
71
		putstr("Math Card Mark I present\r\n");
72
	}
73
	if(psg_addr == -1) {
74
		putstr("Sound Card Mark I not present\r\n");
75
	} else {
76
		putstr("Sound Card Mark I present\r\n");
77
	}
78
 
79
	write_vram(0x800 + 40 * 12);
80
	for(i = 0; i < 0x100; i++) outp(vdp_data, i);
81
 
82
	while(1)
83
		;
84
}
85
 
86
void init_cards(void) {
87
	int i;
88
	int port = 2;
89
	for(i = 0; i < 256 / 3; i++) {
90
		int t = inp(port);
91
		if(t != 0) {
92
			if(t == 0x01) {
93
				vdp_addr = port - 2;
94
				vdp_data = port - 1;
95
			} else if(t == 0x11) {
96
				psg_addr = port - 2;
97
				psg_data = port - 1;
98
			} else if(t == 0x21) {
99
				fpu_addr = port - 2;
100
				fpu_data = port - 1;
101
			}
102
		}
103
		port += 3;
104
	}
105
}
106
 
107
void beep(void) { _beep(3L * 1024); }
108
 
109
void _beep(unsigned long howlong) {
110
	if(psg_addr == -1) return;
111
	unsigned long i;
112
 
113
	outp(psg_addr, 8);
114
	outp(psg_data, 0x0f);
115
 
116
	outp(psg_addr, 0);
117
	outp(psg_data, 0xd6);
118
 
119
	outp(psg_addr, 1);
120
	outp(psg_data, 0x0);
121
 
122
	outp(psg_addr, 7);
123
	outp(psg_data, 0x3e);
124
 
125
	for(i = 0; i < howlong; i++)
126
		;
127
 
128
	outp(psg_addr, 7);
129
	outp(psg_data, 0x3f);
130
}
131
 
132
void write_vram(unsigned short addr) {
133
	addr |= 0x4000;
134
	outp(vdp_addr, addr & 0x00ff);
135
	outp(vdp_addr, ((addr & 0xff00) >> 8));
136
}
137
 
138
void read_vram(unsigned short addr) {
139
	outp(vdp_addr, addr & 0x00ff);
140
	outp(vdp_addr, ((addr & 0xff00) >> 8));
141
}
142
 
143
void scroll_y(void) {
144
	int i;
145
	for(i = 0; i < 40 * 23; i++) {
146
		read_vram(0x800 + i + 40);
147
		unsigned char ch = inp(vdp_data);
148
		write_vram(0x800 + i);
149
		outp(vdp_data, ch);
150
	}
151
	for(i = 0; i < 40; i++) {
152
		outp(vdp_data, 0);
153
	}
154
}
155
 
156
void putchar(char c) {
157
	if(c == '\r') {
158
		posx = 0;
159
	} else if(c == '\n') {
160
		posy++;
161
	} else {
162
		write_vram(0x800 + posy * 40 + posx);
163
		outp(vdp_data, c);
164
		posx++;
165
		if(posx == 40) {
166
			posx = 0;
167
			posy++;
168
		}
169
	}
170
	if(posy == 24) {
171
		scroll_y();
172
		posy = 23;
173
		posx = 0;
174
	}
175
}
176
 
177
void putstr(char* str) {
178
	int i;
179
	for(i = 0; str[i] != 0; i++) putchar(str[i]);
180
}
181
 
182
unsigned char inp(unsigned char port) __naked { __asm ld hl, #2 add hl, sp ld c, (hl)in a, (c)ld l, a ld h, #0 ret __endasm; }
183
 
184
void outp(unsigned char port, unsigned char data) __naked { __asm push bc ld hl, #4 add hl, sp ld c, (hl)inc hl ld b, (hl)out(c), b pop bc ret __endasm; }