Subversion Repositories Shiroi

Rev

Rev 2 | Rev 4 | 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 3 2024-08-28 09:19:04Z 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
 
3 nishi 26
unsigned char basicbuffer[1024 * 30];
27
 
2 nishi 28
void main(void){
1 nishi 29
	int i;
30
 
31
	posx = 0;
32
	posy = 0;
33
 
34
	vdp_addr = -1;
35
	psg_addr = -1;
36
	fpu_addr = -1;
3 nishi 37
	text_kbd_data = -1;
1 nishi 38
 
39
	init_cards();
40
 
2 nishi 41
	if(vdp_addr == -1){
1 nishi 42
		int i;
2 nishi 43
		for(i = 0; i < 3; i++){
1 nishi 44
			_beep(3L * 1024);
45
			unsigned long j;
2 nishi 46
			for(j = 0; j < 3L * 1024; j++);
1 nishi 47
		}
2 nishi 48
		while(1);
1 nishi 49
	}
2 nishi 50
 
1 nishi 51
	outp(vdp_addr, 0x00);
52
	outp(vdp_addr, 0x80);
53
 
54
	outp(vdp_addr, 0xd0);
55
	outp(vdp_addr, 0x81);
56
 
57
	outp(vdp_addr, 0x02);
58
	outp(vdp_addr, 0x82);
59
 
60
	outp(vdp_addr, 0x00);
61
	outp(vdp_addr, 0x84);
62
 
63
	outp(vdp_addr, 0xf4);
64
	outp(vdp_addr, 0x87);
65
 
66
	write_vram(0);
3 nishi 67
	for(i = 0; i < 0x800; i++) outp(vdp_data, *((unsigned char*)(0x6000 - 2048 + i)));
1 nishi 68
 
69
	beep();
70
 
71
	putstr("Shiroi Microcomputer BASIC\r\n");
2 nishi 72
	if(psg_addr == -1){
1 nishi 73
		putstr("Sound Card Mark I not present\r\n");
2 nishi 74
	}else{
1 nishi 75
		putstr("Sound Card Mark I present\r\n");
76
	}
3 nishi 77
	if(fpu_addr == -1){
78
		putstr("Math  Card Mark I not present\r\n");
79
	}else{
80
		putstr("Math  Card Mark I present\r\n");
81
	}
82
	if(text_kbd_data == -1){
83
		putstr("Text  Card Mark I not present\r\n");
84
		putstr("Text  Card Mark I is required to use the BASIC\r\n");
85
		putstr("Halted. Get one.\r\n");
86
		while(1);
87
	}else{
88
		putstr("Text  Card Mark I present\r\n");
89
	}
1 nishi 90
 
91
	write_vram(0x800 + 40 * 12);
92
	for(i = 0; i < 0x100; i++) outp(vdp_data, i);
3 nishi 93
	while(1){
94
		putchar(getch());
95
	}
96
}
1 nishi 97
 
3 nishi 98
char getch(void){
99
	char k = 0;
100
	while((k = inp(text_kbd_data)) == 0);
101
	while(inp(text_kbd_data) != 0);
102
	return k;
1 nishi 103
}
104
 
3 nishi 105
void print_ptr(void* ptr){
106
	unsigned short p = (unsigned short)ptr;
107
	int i;
108
	const char hex[] = "0123456789ABCDEF";
109
	putstr("0x");
110
	for(i = 0; i < 4; i++){
111
		putchar(hex[(p & 0xf000) >> 12]);
112
		p = p << 4;
113
	}
114
}
115
 
2 nishi 116
void init_cards(void){
1 nishi 117
	int i;
118
	int port = 2;
2 nishi 119
	for(i = 0; i < 256 / 3; i++){
1 nishi 120
		int t = inp(port);
2 nishi 121
		if(t != 0){
122
			if(t == 0x01){
1 nishi 123
				vdp_addr = port - 2;
124
				vdp_data = port - 1;
2 nishi 125
			}else if(t == 0x11){
1 nishi 126
				psg_addr = port - 2;
127
				psg_data = port - 1;
2 nishi 128
			}else if(t == 0x21){
1 nishi 129
				fpu_addr = port - 2;
130
				fpu_data = port - 1;
3 nishi 131
			}else if(t == 0x22){
132
				text_kbd_data = port - 2;
1 nishi 133
			}
3 nishi 134
 
1 nishi 135
		}
136
		port += 3;
137
	}
138
}
139
 
2 nishi 140
void beep(void){
141
	_beep(3L * 1024);
142
}
1 nishi 143
 
2 nishi 144
void _beep(unsigned long howlong){
1 nishi 145
	if(psg_addr == -1) return;
146
	unsigned long i;
147
 
148
	outp(psg_addr, 8);
149
	outp(psg_data, 0x0f);
150
 
151
	outp(psg_addr, 0);
152
	outp(psg_data, 0xd6);
153
 
154
	outp(psg_addr, 1);
155
	outp(psg_data, 0x0);
156
 
157
	outp(psg_addr, 7);
158
	outp(psg_data, 0x3e);
159
 
2 nishi 160
	for(i = 0; i < howlong; i++);
1 nishi 161
 
162
	outp(psg_addr, 7);
163
	outp(psg_data, 0x3f);
164
}
165
 
2 nishi 166
void write_vram(unsigned short addr){
1 nishi 167
	addr |= 0x4000;
168
	outp(vdp_addr, addr & 0x00ff);
169
	outp(vdp_addr, ((addr & 0xff00) >> 8));
170
}
171
 
2 nishi 172
void read_vram(unsigned short addr){
1 nishi 173
	outp(vdp_addr, addr & 0x00ff);
174
	outp(vdp_addr, ((addr & 0xff00) >> 8));
175
}
176
 
2 nishi 177
void scroll_y(void){
1 nishi 178
	int i;
2 nishi 179
	for(i = 0; i < 40 * 23; i++){
1 nishi 180
		read_vram(0x800 + i + 40);
181
		unsigned char ch = inp(vdp_data);
182
		write_vram(0x800 + i);
183
		outp(vdp_data, ch);
184
	}
2 nishi 185
	for(i = 0; i < 40; i++){
1 nishi 186
		outp(vdp_data, 0);
187
	}
188
}
189
 
2 nishi 190
void putchar(char c){
191
	if(c == '\r'){
1 nishi 192
		posx = 0;
2 nishi 193
	}else if(c == '\n'){
1 nishi 194
		posy++;
2 nishi 195
	}else{
1 nishi 196
		write_vram(0x800 + posy * 40 + posx);
197
		outp(vdp_data, c);
198
		posx++;
2 nishi 199
		if(posx == 40){
1 nishi 200
			posx = 0;
201
			posy++;
202
		}
203
	}
2 nishi 204
	if(posy == 24){
1 nishi 205
		scroll_y();
206
		posy = 23;
207
		posx = 0;
208
	}
209
}
210
 
2 nishi 211
void putstr(char* str){
1 nishi 212
	int i;
213
	for(i = 0; str[i] != 0; i++) putchar(str[i]);
214
}
215
 
2 nishi 216
unsigned char inp(unsigned char port) __naked {
217
__asm
218
	ld      hl,#2
219
	add     hl,sp
220
	ld      c,(hl)
221
	in      a,(c)
222
	ld      l,a
223
	ld      h,#0
224
	ret
225
__endasm;
226
}
1 nishi 227
 
2 nishi 228
void outp(unsigned char port, unsigned char data) __naked {
229
__asm
230
	push bc
231
	ld      hl,#4
232
	add     hl,sp
233
	ld      c,(hl)
234
	inc     hl
235
	ld      b,(hl)
236
	out     (c),b
237
	pop     bc
238
	ret
239
__endasm;
240
}