Subversion Repositories Shiroi

Rev

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