Subversion Repositories Shiroi

Rev

Rev 3 | Rev 5 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 nishi 1
/* $Id: shiroi.c 4 2024-08-28 10:07:23Z 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);
3 nishi 12
void print_ptr(void*);
13
char getch(void);
1 nishi 14
 
15
unsigned short posx;
16
unsigned short posy;
17
 
18
short vdp_addr;
19
short vdp_data;
20
short psg_addr;
21
short psg_data;
22
short fpu_addr;
23
short fpu_data;
3 nishi 24
short text_kbd_data;
1 nishi 25
 
4 nishi 26
char caps;
27
 
28
unsigned char keylist[13 * 4];
29
unsigned char keylist_caps[13 * 4];
30
 
3 nishi 31
unsigned char basicbuffer[1024 * 30];
32
 
2 nishi 33
void main(void){
1 nishi 34
	int i;
4 nishi 35
	caps = 0;
1 nishi 36
 
4 nishi 37
/*
38
 * / 1 2 3 4 5 6 7 8 9 10 11 12 13
39
 * 1 1 2 3 4 5 6 7 8 9 0  -  =  
40
 * 2 q w e r t y u i o p  [  ]  rt
41
 * 3 a s d f g h j k l ;  '  \  cl
42
 * 4 z x c v b n m , . /  sp
43
 */
44
	const char* keys;
45
 
46
	keys = "1234567890-= ";
47
	for(i = 0; i < 13; i++){
48
		keylist[i] = keys[i];
49
	}
50
	keys = "qwertyuiop[]\n";
51
	for(i = 0; i < 13; i++){
52
		keylist[13 + i] = keys[i];
53
	}
54
	keys = "asdfghjkl;'\\!";
55
	for(i = 0; i < 13; i++){
56
		keylist[26 + i] = keys[i];
57
	}
58
	keys = "zxcvbnm,./    ";
59
	for(i = 0; i < 13; i++){
60
		keylist[39 + i] = keys[i];
61
	}
62
 
63
	keys = "!@#$%^&*()_+ ";
64
	for(i = 0; i < 13; i++){
65
		keylist_caps[i] = keys[i];
66
	}
67
	keys = "QWERTYUIOP{}\n";
68
	for(i = 0; i < 13; i++){
69
		keylist_caps[13 + i] = keys[i];
70
	}
71
	keys = "ASDFGHJKL:\"|!";
72
	for(i = 0; i < 13; i++){
73
		keylist_caps[26 + i] = keys[i];
74
	}
75
	keys = "ZXCVBNM<>?    ";
76
	for(i = 0; i < 13; i++){
77
		keylist_caps[39 + i] = keys[i];
78
	}
79
 
1 nishi 80
	posx = 0;
81
	posy = 0;
82
 
83
	vdp_addr = -1;
84
	psg_addr = -1;
85
	fpu_addr = -1;
3 nishi 86
	text_kbd_data = -1;
1 nishi 87
 
88
	init_cards();
89
 
2 nishi 90
	if(vdp_addr == -1){
1 nishi 91
		int i;
2 nishi 92
		for(i = 0; i < 3; i++){
1 nishi 93
			_beep(3L * 1024);
94
			unsigned long j;
2 nishi 95
			for(j = 0; j < 3L * 1024; j++);
1 nishi 96
		}
2 nishi 97
		while(1);
1 nishi 98
	}
2 nishi 99
 
1 nishi 100
	outp(vdp_addr, 0x00);
101
	outp(vdp_addr, 0x80);
102
 
103
	outp(vdp_addr, 0xd0);
104
	outp(vdp_addr, 0x81);
105
 
106
	outp(vdp_addr, 0x02);
107
	outp(vdp_addr, 0x82);
108
 
109
	outp(vdp_addr, 0x00);
110
	outp(vdp_addr, 0x84);
111
 
112
	outp(vdp_addr, 0xf4);
113
	outp(vdp_addr, 0x87);
114
 
115
	write_vram(0);
3 nishi 116
	for(i = 0; i < 0x800; i++) outp(vdp_data, *((unsigned char*)(0x6000 - 2048 + i)));
1 nishi 117
 
4 nishi 118
//	beep();
1 nishi 119
 
120
	putstr("Shiroi Microcomputer BASIC\r\n");
2 nishi 121
	if(psg_addr == -1){
1 nishi 122
		putstr("Sound Card Mark I not present\r\n");
2 nishi 123
	}else{
4 nishi 124
		putstr("Sound Card Mark I     present\r\n");
1 nishi 125
	}
3 nishi 126
	if(fpu_addr == -1){
127
		putstr("Math  Card Mark I not present\r\n");
128
	}else{
4 nishi 129
		putstr("Math  Card Mark I     present\r\n");
3 nishi 130
	}
131
	if(text_kbd_data == -1){
132
		putstr("Text  Card Mark I not present\r\n");
133
		putstr("Text  Card Mark I is required to use the BASIC\r\n");
134
		putstr("Halted. Get one.\r\n");
135
		while(1);
136
	}else{
4 nishi 137
		putstr("Text  Card Mark I     present\r\n");
3 nishi 138
	}
1 nishi 139
 
3 nishi 140
	while(1){
141
		putchar(getch());
142
	}
143
}
1 nishi 144
 
3 nishi 145
char getch(void){
146
	char k = 0;
4 nishi 147
rep:
3 nishi 148
	while((k = inp(text_kbd_data)) == 0);
149
	while(inp(text_kbd_data) != 0);
4 nishi 150
	unsigned char top = (k & 0xf0) >> 4;
151
	unsigned char bot = (k & 0x0f);
152
	top--;
153
	bot--;
154
	if(keylist[top * 13 + bot] == '!'){
155
		caps = caps == 0 ? 1 : 0;
156
		goto rep;
157
	}
158
	return caps ? keylist_caps[top * 13 + bot] : keylist[top * 13 + bot];
1 nishi 159
}
160
 
3 nishi 161
void print_ptr(void* ptr){
162
	unsigned short p = (unsigned short)ptr;
163
	int i;
164
	const char hex[] = "0123456789ABCDEF";
165
	putstr("0x");
166
	for(i = 0; i < 4; i++){
167
		putchar(hex[(p & 0xf000) >> 12]);
168
		p = p << 4;
169
	}
170
}
171
 
2 nishi 172
void init_cards(void){
1 nishi 173
	int i;
174
	int port = 2;
2 nishi 175
	for(i = 0; i < 256 / 3; i++){
1 nishi 176
		int t = inp(port);
2 nishi 177
		if(t != 0){
178
			if(t == 0x01){
1 nishi 179
				vdp_addr = port - 2;
180
				vdp_data = port - 1;
2 nishi 181
			}else if(t == 0x11){
1 nishi 182
				psg_addr = port - 2;
183
				psg_data = port - 1;
2 nishi 184
			}else if(t == 0x21){
1 nishi 185
				fpu_addr = port - 2;
186
				fpu_data = port - 1;
3 nishi 187
			}else if(t == 0x22){
188
				text_kbd_data = port - 2;
1 nishi 189
			}
3 nishi 190
 
1 nishi 191
		}
192
		port += 3;
193
	}
194
}
195
 
2 nishi 196
void beep(void){
197
	_beep(3L * 1024);
198
}
1 nishi 199
 
2 nishi 200
void _beep(unsigned long howlong){
1 nishi 201
	if(psg_addr == -1) return;
202
	unsigned long i;
203
 
204
	outp(psg_addr, 8);
205
	outp(psg_data, 0x0f);
206
 
207
	outp(psg_addr, 0);
208
	outp(psg_data, 0xd6);
209
 
210
	outp(psg_addr, 1);
211
	outp(psg_data, 0x0);
212
 
213
	outp(psg_addr, 7);
214
	outp(psg_data, 0x3e);
215
 
2 nishi 216
	for(i = 0; i < howlong; i++);
1 nishi 217
 
218
	outp(psg_addr, 7);
219
	outp(psg_data, 0x3f);
220
}
221
 
2 nishi 222
void write_vram(unsigned short addr){
1 nishi 223
	addr |= 0x4000;
224
	outp(vdp_addr, addr & 0x00ff);
225
	outp(vdp_addr, ((addr & 0xff00) >> 8));
226
}
227
 
2 nishi 228
void read_vram(unsigned short addr){
1 nishi 229
	outp(vdp_addr, addr & 0x00ff);
230
	outp(vdp_addr, ((addr & 0xff00) >> 8));
231
}
232
 
2 nishi 233
void scroll_y(void){
1 nishi 234
	int i;
2 nishi 235
	for(i = 0; i < 40 * 23; i++){
1 nishi 236
		read_vram(0x800 + i + 40);
237
		unsigned char ch = inp(vdp_data);
238
		write_vram(0x800 + i);
239
		outp(vdp_data, ch);
240
	}
2 nishi 241
	for(i = 0; i < 40; i++){
1 nishi 242
		outp(vdp_data, 0);
243
	}
244
}
245
 
2 nishi 246
void putchar(char c){
247
	if(c == '\r'){
1 nishi 248
		posx = 0;
2 nishi 249
	}else if(c == '\n'){
1 nishi 250
		posy++;
2 nishi 251
	}else{
1 nishi 252
		write_vram(0x800 + posy * 40 + posx);
253
		outp(vdp_data, c);
254
		posx++;
2 nishi 255
		if(posx == 40){
1 nishi 256
			posx = 0;
257
			posy++;
258
		}
259
	}
2 nishi 260
	if(posy == 24){
1 nishi 261
		scroll_y();
262
		posy = 23;
263
		posx = 0;
264
	}
265
}
266
 
2 nishi 267
void putstr(char* str){
1 nishi 268
	int i;
269
	for(i = 0; str[i] != 0; i++) putchar(str[i]);
270
}
271
 
2 nishi 272
unsigned char inp(unsigned char port) __naked {
273
__asm
274
	ld      hl,#2
275
	add     hl,sp
276
	ld      c,(hl)
277
	in      a,(c)
278
	ld      l,a
279
	ld      h,#0
280
	ret
281
__endasm;
282
}
1 nishi 283
 
2 nishi 284
void outp(unsigned char port, unsigned char data) __naked {
285
__asm
286
	push bc
287
	ld      hl,#4
288
	add     hl,sp
289
	ld      c,(hl)
290
	inc     hl
291
	ld      b,(hl)
292
	out     (c),b
293
	pop     bc
294
	ret
295
__endasm;
296
}