Subversion Repositories Shiroi

Rev

Rev 7 | Rev 9 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7 Rev 8
Line 1... Line 1...
1
/* $Id: shiroi.c 7 2024-08-28 14:02:52Z nishi $ */
1
/* $Id: shiroi.c 8 2024-08-28 16:29:15Z nishi $ */
-
 
2
 
-
 
3
#include "io.h"
-
 
4
#include "am9511.h"
-
 
5
#include "psg.h"
-
 
6
#include "video.h"
-
 
7
#include "text.h"
-
 
8
#include "char.h"
2
 
9
 
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);
10
void init_cards(void);
12
void print_ptr(void*);
-
 
13
char getch(void);
-
 
14
void clear(void);
-
 
15
void basic(void);
11
void basic(void);
16
int strlen(const char*);
-
 
17
void cursor(void);
-
 
18
void killcursor(void);
-
 
19
char toupper(char c);
-
 
20
long modl(long a, long b);
-
 
21
long divl(long a, long b);
-
 
22
long mull(long a, long b);
-
 
23
 
-
 
24
#define AM_SR       0x80 /* service request on completion */
-
 
25
#define AM_SINGLE   0x60 /* 16 bit integer */
-
 
26
#define AM_DOUBLE   0x20 /* 32 bit integer */
-
 
27
#define AM_FIXED    0x20 /* fixed point */
-
 
28
#define AM_FLOAT    0x00 /* 32 bit float */
-
 
29
 
-
 
30
#define AM_NOP      0x00 /* no operation */
-
 
31
#define AM_SQRT     0x01 /* square root */
-
 
32
#define AM_SIN      0x02 /* sine */
-
 
33
#define AM_COS      0x03 /* cosine */
-
 
34
#define AM_TAN      0x04 /* tangent */
-
 
35
#define AM_ASIN     0x05 /* inverse sine */
-
 
36
#define AM_ACOS     0x06 /* inverse cosine */
-
 
37
#define AM_ATAN     0x07 /* inverse tangent */
-
 
38
#define AM_LOG      0x08 /* common logarithm (base 10) */
-
 
39
#define AM_LN       0x09 /* natural logairth (base e) */
-
 
40
#define AM_EXP      0x0a /* exponential (e^x) */
-
 
41
#define AM_PWR      0x0b /* power nos^tos */
-
 
42
#define AM_ADD      0x0c /* add */
-
 
43
#define AM_SUB      0x0d /* subtract nos-tos */
-
 
44
#define AM_MUL      0x0e /* multiply, lower half */
-
 
45
#define AM_DIV      0x0f /* divide nos/tos */
-
 
46
#define AM_FADD     0x10 /* floating add */
-
 
47
#define AM_FSUB     0x11 /* floating subtract */
-
 
48
#define AM_FMUL     0x12 /* floating multiply */
-
 
49
#define AM_FDIV     0x13 /* floating divide */
-
 
50
#define AM_CHS      0x14 /* change sign */
-
 
51
#define AM_CHSF     0x15 /* floating change sign */ 
-
 
52
#define AM_MUU      0x16 /* multiply, upper half */
-
 
53
#define AM_PTO      0x17 /* push tos to nos (copy) */
-
 
54
#define AM_POP      0x18 /* pop */
-
 
55
#define AM_XCH      0x19 /* exchange tos and nos */
-
 
56
#define AM_PUPI     0x1a /* push pi */
-
 
57
/*                  0x1b */
-
 
58
#define AM_FLTD     0x1c /* 32 bit to float */
-
 
59
#define AM_FLTS     0x1d /* 16 bit to float */
-
 
60
#define AM_FIXD     0x1e /* float to 32 bit */
-
 
61
#define AM_FIXS     0x1f /* float to 16 bit */
-
 
62
 
-
 
63
#define AM_BUSY     0x80 /* chip is busy */
-
 
64
#define AM_SIGN     0x40 /* tos negative */
-
 
65
#define AM_ZERO     0x20 /* tos zero */
-
 
66
#define AM_ERR_MASK 0x1E /* mask for errors */
-
 
67
#define AM_CARRY    0x01 /* carry/borrow from most significant bit */
-
 
68
 
-
 
69
unsigned short posx;
-
 
70
unsigned short posy;
-
 
71
unsigned short curx;
-
 
72
unsigned short cury;
-
 
73
 
-
 
74
short vdp_addr;
-
 
75
short vdp_data;
-
 
76
short vdg_addr;
-
 
77
short vdg_data;
-
 
78
short psg_addr;
-
 
79
short psg_data;
-
 
80
short fpu_stack;
-
 
81
short fpu_command;
-
 
82
short text_kbd_data;
-
 
83
 
12
 
-
 
13
extern short vdp_addr;
-
 
14
extern short vdp_data;
-
 
15
extern short vdg_addr;
84
int scrwidth;
16
extern short vdg_data;
-
 
17
 
-
 
18
extern short psg_addr;
85
int scrheight;
19
extern short psg_data;
-
 
20
 
-
 
21
extern short fpu_stack;
-
 
22
extern short fpu_command;
-
 
23
 
-
 
24
extern short text_kbd_data;
86
 
25
 
-
 
26
extern int scrwidth;
-
 
27
extern int scrheight;
-
 
28
 
87
char caps;
29
extern char caps;
88
 
30
 
89
unsigned char keylist[13 * 4];
31
unsigned char keylist[13 * 4];
90
unsigned char keylist_caps[13 * 4];
32
unsigned char keylist_caps[13 * 4];
91
 
33
 
92
unsigned char basicbuffer[1024 * 30];
-
 
93
 
-
 
94
void main(void){
34
void main(void){
95
	int i;
35
	int i;
96
	caps = 0;
-
 
97
 
36
 
98
/*
37
/*
99
 * / 1 2 3 4 5 6 7 8 9 10 11 12 13
38
 * / 1 2 3 4 5 6 7 8 9 10 11 12 13
100
 * 1 1 2 3 4 5 6 7 8 9 0  -  =  bs
39
 * 1 1 2 3 4 5 6 7 8 9 0  -  =  bs
101
 * 2 q w e r t y u i o p  [  ]  rt
40
 * 2 q w e r t y u i o p  [  ]  rt
Line 144... Line 83...
144
	keys = "ZXCVBNM<>?    ";
83
	keys = "ZXCVBNM<>?    ";
145
	for(i = 0; i < 13; i++){
84
	for(i = 0; i < 13; i++){
146
		keylist_caps[39 + i] = keys[i];
85
		keylist_caps[39 + i] = keys[i];
147
	}
86
	}
148
 
87
 
149
	posx = 0;
-
 
150
	posy = 0;
-
 
151
	curx = 0;
-
 
152
	cury = 0;
-
 
153
 
-
 
154
	vdp_addr = -1;
88
	vdp_addr = -1;
155
	vdg_addr = -1;
89
	vdg_addr = -1;
156
	psg_addr = -1;
90
	psg_addr = -1;
157
	fpu_stack = -1;
91
	fpu_stack = -1;
158
	text_kbd_data = -1;
92
	text_kbd_data = -1;
159
 
93
 
160
	init_cards();
94
	init_cards();
161
 
95
 
-
 
96
#ifdef ONLY_VDP
-
 
97
	if(vdp_addr == -1){
-
 
98
#else
162
	if(vdp_addr == -1 && vdg_addr == -1){
99
	if(vdp_addr == -1 && vdg_addr == -1){
-
 
100
#endif
163
		int i;
101
		int i;
164
		for(i = 0; i < 3; i++){
102
		for(i = 0; i < 3; i++){
165
			_beep(3L * 1024);
103
			_beep(3L * 1024);
166
			unsigned long j;
104
			unsigned long j;
167
			for(j = 0; j < 3L * 1024; j++);
105
			for(j = 0; j < 3L * 1024; j++);
168
		}
106
		}
169
		while(1);
107
		while(1);
170
	}
108
	}
171
 
109
 
172
	if(vdp_addr != -1){	
-
 
173
		scrwidth = 32;
-
 
174
		scrheight = 24;
110
	video_init();
175
 
-
 
176
		outp(vdp_addr, 0x00);
-
 
177
		outp(vdp_addr, 0x80);
-
 
178
	
-
 
179
		outp(vdp_addr, 0xd8);
-
 
180
		outp(vdp_addr, 0x81);
-
 
181
	
-
 
182
		outp(vdp_addr, 0x02);
-
 
183
		outp(vdp_addr, 0x82);
-
 
184
	
-
 
185
		outp(vdp_addr, 0x50);
-
 
186
		outp(vdp_addr, 0x83);
-
 
187
	
-
 
188
		outp(vdp_addr, 0x00);
-
 
189
		outp(vdp_addr, 0x84);
-
 
190
	
-
 
191
		outp(vdp_addr, 0x29);
-
 
192
		outp(vdp_addr, 0x85);
-
 
193
	
-
 
194
		outp(vdp_addr, 0x03);
-
 
195
		outp(vdp_addr, 0x86);
-
 
196
	
-
 
197
		outp(vdp_addr, 0xe4);
-
 
198
		outp(vdp_addr, 0x87);
-
 
199
	}else if(vdg_addr != -1){
-
 
200
		scrwidth = 32;
-
 
201
		scrheight = 16;
-
 
202
	}
-
 
203
 
-
 
204
	if(vdp_addr != -1){
-
 
205
		/*
-
 
206
		 * VDP:
-
 
207
		 * 0x0000-0x0800: font
-
 
208
		 * 0x0800-0x1400: pattern
-
 
209
		 * 0x1400-0x1480: color
-
 
210
		 * 0x1480-0x1500: sprite attr
-
 
211
		 * 0x1800-0x2000: sprite pattern
-
 
212
		 */
-
 
213
	
-
 
214
		write_vram(0);
111
	text_init();
215
		for(i = 0; i < 0x800; i++) outp(vdp_data, *((unsigned char*)(0x6000 - 2048 + i)));
-
 
216
	
-
 
217
		write_vram(0x1400);
-
 
218
		for(i = 0; i < 0x20; i++) outp(vdp_data, 0xf0);
-
 
219
		write_vram(0x1400 + 0x10);
-
 
220
		for(i = 0; i < 0x10; i++) outp(vdp_data, ((i & 0xf) << 4) | 0);
-
 
221
	}
-
 
222
 
112
 
223
	clear();
113
	clear();
224
 
114
 
225
//	beep();
115
//	beep();
226
 
116
 
Line 242... Line 132...
242
	char k;
132
	char k;
243
	int wait = 0;
133
	int wait = 0;
244
 
134
 
245
	const char* title;
135
	const char* title;
246
 
136
 
-
 
137
#ifdef ONLY_VDP
247
	if(vdp_addr != -1){
138
	if(vdp_addr != -1){
-
 
139
#else
-
 
140
	if(vdp_addr != -1 || vdg_addr != -1){
-
 
141
#endif
248
		title = "Shiroi Microcomputer";
142
		title = "Shiroi Microcomputer";
249
		write_vram(0x800 + scrwidth / 2 - strlen(title) / 2 + mull(scrheight / 2 - 1, scrwidth));
143
		setvramaddr(scrwidth / 2 - strlen(title) / 2 + mull((scrheight - 9) / 2 - 1 + 3, scrwidth));
250
		for(i = 0; title[i] != 0; i++) outp(vdp_data, title[i] - 0x20);
144
		for(i = 0; title[i] != 0; i++) vramchar(title[i]);
251
 
-
 
252
		title = "\x82 2024 Nishi";
-
 
253
		write_vram(0x800 + scrwidth / 2 - strlen(title) / 2 + mull(scrheight - 2, scrwidth));
-
 
254
		for(i = 0; title[i] != 0; i++) outp(vdp_data, title[i] - 0x20);
-
 
255
 
145
 
256
		title = "Press any key to begin";
146
		if(vdp_addr != -1){
257
		write_vram(0x800 + scrwidth / 2 - strlen(title) / 2 + mull(scrheight / 2 + 1, scrwidth));
-
 
258
		for(i = 0; title[i] != 0; i++) outp(vdp_data, title[i] - 0x20);
147
			title = "\x82 2024 Nishi";
259
	}else if(vdg_addr != -1){
148
		}else if(vdg_addr != -1){
260
		title = "Shiroi Microcomputer";
149
			title = "(C) 2024 Nishi";
261
		write_vram(scrwidth / 2 - strlen(title) / 2 + mull(scrheight / 2 - 1, scrwidth));
-
 
262
		for(i = 0; title[i] != 0; i++) outp(vdg_data, toupper(title[i]) - 'A' + 1);
-
 
263
 
150
		}
264
		title = "(C) 2024 Nishi";
-
 
265
		write_vram(scrwidth / 2 - strlen(title) / 2 + mull(scrheight - 2, scrwidth));
151
		setvramaddr(scrwidth / 2 - strlen(title) / 2 + mull(scrheight - 2, scrwidth));
266
		for(i = 0; title[i] != 0; i++) outp(vdg_data, toupper(title[i]) - 'A' + 1);
152
		for(i = 0; title[i] != 0; i++) vramchar(title[i]);
267
 
153
 
268
		title = "Press any key to begin";
154
		title = "Press any key to begin";
269
		write_vram(scrwidth / 2 - strlen(title) / 2 + mull(scrheight / 2 + 1, scrwidth));
155
		setvramaddr(scrwidth / 2 - strlen(title) / 2 + mull((scrheight - 9) / 2 + 1 + 3, scrwidth));
270
		for(i = 0; title[i] != 0; i++) outp(vdg_data, toupper(title[i]) - 'A' + 1);
156
		for(i = 0; title[i] != 0; i++) vramchar(title[i]);
271
	}
157
	}
272
 
158
 
273
move_bar:
159
move_bar:
274
	if(vdp_addr != -1){
160
	if(vdp_addr != -1){
-
 
161
	}
-
 
162
#ifndef ONLY_VDP
275
	}else if(vdg_addr != -1){
163
	else if(vdg_addr != -1){
276
		goto skip;
164
		goto skip;
277
	}
165
	}
-
 
166
#endif
278
	incr = move;
167
	incr = move;
279
	for(i = 0; i < 16; i++){
168
	for(i = 0; i < 16; i++){
280
		int j;
169
		int j;
281
		for(j = 0; j < 3; j++){
170
		for(j = 0; j < 3; j++){
282
			int p = incr;
171
			int p = incr;
283
			if(p >= 15) p = p - 15;
172
			if(p >= 15) p = p - 15;
284
			if(wait == 0){
173
			if(wait == 0){
285
				write_vram(0x800 + i * 2 + j * 32);
174
				setvramaddr(i * 2 + j * 32);
286
				outp(vdp_data, (p + 1) * 8 + 0x80);
175
				_vramchar((p + 1) * 8 + 0x80);
287
				outp(vdp_data, (p + 1) * 8 + 0x80);
176
				_vramchar((p + 1) * 8 + 0x80);
288
				write_vram(0x800 + i * 2 + 32 * 20 - j * 32);
177
				setvramaddr(i * 2 + 32 * 20 - j * 32);
289
				outp(vdp_data, (p + 1) * 8 + 0x80);
178
				_vramchar((p + 1) * 8 + 0x80);
290
				outp(vdp_data, (p + 1) * 8 + 0x80);
179
				_vramchar((p + 1) * 8 + 0x80);
291
			}else{
180
			}else{
292
				if(i * 2 - 1 < 0){
181
				if(i * 2 - 1 < 0){
293
					write_vram(0x800 + i * 2 + j * 32);
182
					setvramaddr(i * 2 + j * 32);
294
					outp(vdp_data, (p + 1) * 8 + 0x80);
183
					_vramchar((p + 1) * 8 + 0x80);
295
				}else{
184
				}else{
296
					write_vram(0x800 + i * 2 + j * 32 - 1);
185
					setvramaddr(i * 2 + j * 32 - 1);
297
					outp(vdp_data, (p + 1) * 8 + 0x80);
186
					_vramchar((p + 1) * 8 + 0x80);
298
					outp(vdp_data, (p + 1) * 8 + 0x80);
187
					_vramchar((p + 1) * 8 + 0x80);
299
				}
188
				}
300
				if(i * 2 - 1 < 0){
189
				if(i * 2 - 1 < 0){
301
					write_vram(0x800 + i * 2 + 32 * 20 - j * 32);
190
					setvramaddr(i * 2 + 32 * 20 - j * 32);
302
					outp(vdp_data, (p + 1) * 8 + 0x80);
191
					_vramchar((p + 1) * 8 + 0x80);
303
				}else{
192
				}else{
304
					write_vram(0x800 + i * 2 + 32 * 20 - j * 32 - 1);
193
					setvramaddr(i * 2 + 32 * 20 - j * 32 - 1);
305
					outp(vdp_data, (p + 1) * 8 + 0x80);
194
					_vramchar((p + 1) * 8 + 0x80);
306
					outp(vdp_data, (p + 1) * 8 + 0x80);
195
					_vramchar((p + 1) * 8 + 0x80);
307
				}
196
				}
308
			}
197
			}
309
		}
198
		}
310
		incr++;
199
		incr++;
311
		if(incr == 15) incr = 0;
200
		if(incr == 15) incr = 0;
Line 320... Line 209...
320
 
209
 
321
skip:
210
skip:
322
	if((k = inp(text_kbd_data)) == 0) goto move_bar;
211
	if((k = inp(text_kbd_data)) == 0) goto move_bar;
323
	while(inp(text_kbd_data) != 0);
212
	while(inp(text_kbd_data) != 0);
324
 
213
 
325
	basic();
-
 
326
}
-
 
327
 
-
 
328
void basic(void){
-
 
329
	clear();
-
 
330
 
-
 
331
	if(vdp_addr == -1){
214
	if(vdp_addr == -1){
332
		outp(vdp_addr, 0xf0);
215
		outp(vdp_addr, 0xf0);
333
		outp(vdp_addr, 0x87);
216
		outp(vdp_addr, 0x87);
334
	}
217
	}
335
 
218
 
336
	putstr("Shiroi Microcomputer BASIC\r\n");
-
 
337
	cursor();
219
	basic();
338
	while(1){
-
 
339
		char c = getch();
-
 
340
		killcursor();
-
 
341
		if(c == '\n'){
-
 
342
			putstr("\r\n");
-
 
343
		}else{
-
 
344
			putchar(c);
-
 
345
		}
-
 
346
		cursor();
-
 
347
	}
-
 
348
}
-
 
349
 
-
 
350
int strlen(const char* str){
-
 
351
	int i;
-
 
352
	for(i = 0; str[i] != 0; i++);
-
 
353
	return i;
-
 
354
}
-
 
355
 
-
 
356
void clear(void){
-
 
357
	int i;
-
 
358
	int size = mull(scrwidth, scrheight);
-
 
359
	if(vdp_addr != -1){
-
 
360
		write_vram(0x800);
-
 
361
		for(i = 0; i < size; i++) outp(vdp_data, 0);
-
 
362
	}else if(vdg_addr != -1){
-
 
363
		write_vram(0);
-
 
364
		for(i = 0; i < size; i++){
-
 
365
			outp(vdg_data, 0x20);
-
 
366
		}
-
 
367
	}
-
 
368
}
-
 
369
 
-
 
370
char getch(void){
-
 
371
	char k = 0;
-
 
372
rep:
-
 
373
	while((k = inp(text_kbd_data)) == 0);
-
 
374
	while(inp(text_kbd_data) != 0);
-
 
375
	unsigned char top = (k & 0xf0) >> 4;
-
 
376
	unsigned char bot = (k & 0x0f);
-
 
377
	top--;
-
 
378
	bot--;
-
 
379
	if(keylist[top * 13 + bot] == '!'){
-
 
380
		caps = caps == 0 ? 1 : 0;
-
 
381
		goto rep;
-
 
382
	}
-
 
383
	return caps ? keylist_caps[top * 13 + bot] : keylist[top * 13 + bot];
-
 
384
}
-
 
385
 
-
 
386
void print_ptr(void* ptr){
-
 
387
	unsigned short p = (unsigned short)ptr;
-
 
388
	int i;
-
 
389
	const char hex[] = "0123456789ABCDEF";
-
 
390
	putstr("0x");
-
 
391
	for(i = 0; i < 4; i++){
-
 
392
		putchar(hex[(p & 0xf000) >> 12]);
-
 
393
		p = p << 4;
-
 
394
	}
-
 
395
}
220
}
396
 
221
 
397
void init_cards(void){
222
void init_cards(void){
398
	int i;
223
	int i;
399
	int port = 2;
224
	int port = 2;
400
	for(i = 0; i < 256 / 3; i++){
225
	for(i = 0; i < 256 / 3; i++){
401
		int t = inp(port);
226
		int t = inp(port);
402
		if(t != 0){
227
		if(t != 0){
403
			if(t == 0x01){
-
 
404
				vdp_addr = port - 2;
228
			video_card(t, port);
405
				vdp_data = port - 1;
-
 
406
			}else if(t == 0x02){
-
 
407
				vdg_addr = port - 2;
-
 
408
				vdg_data = port - 1;
-
 
409
			}else if(t == 0x11){
-
 
410
				psg_addr = port - 2;
229
			psg_card(t, port);
411
				psg_data = port - 1;
-
 
412
			}else if(t == 0x21){
-
 
413
				fpu_stack = port - 2;
-
 
414
				fpu_command = port - 1;
230
			fpu_card(t, port);
415
			}else if(t == 0x22){
-
 
416
				text_kbd_data = port - 2;
231
			text_card(t, port);
417
			}
-
 
418
 
232
 
419
		}
233
		}
420
		port += 3;
234
		port += 3;
421
	}
235
	}
422
}
236
}
423
 
-
 
424
void beep(void){
-
 
425
	_beep(3L * 1024);
-
 
426
}
-
 
427
 
-
 
428
void _beep(unsigned long howlong){
-
 
429
	if(psg_addr == -1) return;
-
 
430
	unsigned long i;
-
 
431
 
-
 
432
	outp(psg_addr, 8);
-
 
433
	outp(psg_data, 0x0f);
-
 
434
 
-
 
435
	outp(psg_addr, 0);
-
 
436
	outp(psg_data, 0xd6);
-
 
437
 
-
 
438
	outp(psg_addr, 1);
-
 
439
	outp(psg_data, 0x0);
-
 
440
 
-
 
441
	outp(psg_addr, 7);
-
 
442
	outp(psg_data, 0x3e);
-
 
443
 
-
 
444
	for(i = 0; i < howlong; i++);
-
 
445
 
-
 
446
	outp(psg_addr, 7);
-
 
447
	outp(psg_data, 0x3f);
-
 
448
}
-
 
449
 
-
 
450
void write_vram(unsigned short addr){
-
 
451
	if(vdp_addr != -1){
-
 
452
		addr |= 0x4000;
-
 
453
		outp(vdp_addr, addr & 0x00ff);
-
 
454
		outp(vdp_addr, ((addr & 0xff00) >> 8));
-
 
455
	}else if(vdg_addr != -1){
-
 
456
		outp(vdg_addr, addr & 0x00ff);
-
 
457
		outp(vdg_addr, ((addr & 0xff00) >> 8));
-
 
458
	}
-
 
459
}
-
 
460
 
-
 
461
void read_vram(unsigned short addr){
-
 
462
	if(vdp_addr != -1){
-
 
463
		outp(vdp_addr, addr & 0x00ff);
-
 
464
		outp(vdp_addr, ((addr & 0xff00) >> 8));
-
 
465
	}else{
-
 
466
		outp(vdg_addr, addr & 0x00ff);
-
 
467
		outp(vdg_addr, ((addr & 0xff00) >> 8));
-
 
468
	}
-
 
469
}
-
 
470
 
-
 
471
void scroll_y(void){
-
 
472
	int i;
-
 
473
	int size = mull(scrwidth, scrheight - 1);
-
 
474
	for(i = 0; i < size; i++){
-
 
475
		if(vdp_addr != -1){
-
 
476
			read_vram(0x800 + i + 32);
-
 
477
			unsigned char ch = inp(vdp_data);
-
 
478
			write_vram(0x800 + i);
-
 
479
			outp(vdp_data, ch);
-
 
480
		}else if(vdg_addr != -1){
-
 
481
			read_vram(i + 32);
-
 
482
			unsigned char ch = inp(vdg_data);
-
 
483
			write_vram(i);
-
 
484
			outp(vdg_data, ch);
-
 
485
		}
-
 
486
	}
-
 
487
	for(i = 0; i < scrwidth; i++){
-
 
488
		if(vdp_addr != -1){
-
 
489
			outp(vdp_data, 0);
-
 
490
		}else if(vdg_addr != -1){
-
 
491
			outp(vdg_data, 0x20);
-
 
492
		}
-
 
493
	}
-
 
494
}
-
 
495
 
-
 
496
void cursor(void){
-
 
497
	if(vdp_addr != -1){
-
 
498
		write_vram(0x800 + mull(posy, scrwidth) + posx);
-
 
499
		outp(vdp_data, 248);
-
 
500
	}else if(vdg_addr != -1){
-
 
501
		write_vram(mull(posy, scrwidth) + posx);
-
 
502
		outp(vdg_data, 0);
-
 
503
	}
-
 
504
	curx = posx;
-
 
505
	cury = posy;
-
 
506
	if(curx == scrwidth){
-
 
507
		curx = 0;
-
 
508
		cury++;
-
 
509
	}
-
 
510
}
-
 
511
 
-
 
512
void killcursor(void){
-
 
513
	if(vdp_addr != -1){
-
 
514
		write_vram(0x800 + mull(cury, scrwidth) + curx);
-
 
515
		outp(vdp_data, 0);
-
 
516
	}else if(vdg_addr != -1){
-
 
517
		write_vram(mull(cury, scrwidth) + curx);
-
 
518
		outp(vdg_data, 0x20);
-
 
519
	}
-
 
520
}
-
 
521
 
-
 
522
char toupper(char c){
-
 
523
	if('a' <= c && c <= 'z'){
-
 
524
		return c - 'a' + 'A';
-
 
525
	}
-
 
526
	return c;
-
 
527
}
-
 
528
 
-
 
529
void putchar(char c){
-
 
530
	if(c == '\r'){
-
 
531
		posx = 0;
-
 
532
	}else if(c == '\n'){
-
 
533
		posy++;
-
 
534
	}else{
-
 
535
		if(vdp_addr != -1){
-
 
536
			write_vram(0x800 + mull(posy, scrwidth) + posx);
-
 
537
		}else if(vdg_addr != -1){
-
 
538
			write_vram(mull(posy, scrwidth) + posx);
-
 
539
		}
-
 
540
		if(vdp_addr != -1){
-
 
541
			outp(vdp_data, c - 0x20);
-
 
542
		}else if(vdg_addr != -1){
-
 
543
			outp(vdg_data, toupper(c) - 'A' + 1);
-
 
544
		}
-
 
545
		posx++;
-
 
546
		if(posx == scrwidth){
-
 
547
			posx = 0;
-
 
548
			posy++;
-
 
549
		}
-
 
550
	}
-
 
551
	if(posy == scrheight){
-
 
552
		scroll_y();
-
 
553
		posy = scrheight - 1;
-
 
554
		posx = 0;
-
 
555
	}
-
 
556
}
-
 
557
 
-
 
558
void putstr(char* str){
-
 
559
	int i;
-
 
560
	for(i = 0; str[i] != 0; i++) putchar(str[i]);
-
 
561
}
-
 
562
 
-
 
563
long modl(long a, long b){
-
 
564
	return a - mull(b, divl(a, b));
-
 
565
}
-
 
566
 
-
 
567
long divl(long a, long b){
-
 
568
	int i;
-
 
569
	for(i = 0; i < 4; i++){
-
 
570
		outp(fpu_stack, a & 0xff);
-
 
571
		a = a >> 8;
-
 
572
	}
-
 
573
	for(i = 0; i < 4; i++){
-
 
574
		outp(fpu_stack, b & 0xff);
-
 
575
		b = b >> 8;
-
 
576
	}
-
 
577
	outp(fpu_command, AM_DOUBLE | AM_DIV);
-
 
578
	unsigned long r = 0;
-
 
579
	for(i = 0; i < 4; i++){
-
 
580
		r = r << 8;
-
 
581
		r |= inp(fpu_stack);
-
 
582
	}
-
 
583
	return r;
-
 
584
}
-
 
585
 
-
 
586
long mull(long a, long b){
-
 
587
	int i;
-
 
588
	for(i = 0; i < 4; i++){
-
 
589
		outp(fpu_stack, a & 0xff);
-
 
590
		a = a >> 8;
-
 
591
	}
-
 
592
	for(i = 0; i < 4; i++){
-
 
593
		outp(fpu_stack, b & 0xff);
-
 
594
		b = b >> 8;
-
 
595
	}
-
 
596
	outp(fpu_command, AM_DOUBLE | AM_MUL);
-
 
597
	long r = 0;
-
 
598
	for(i = 0; i < 4; i++){
-
 
599
		r = r << 8;
-
 
600
		r |= inp(fpu_stack);
-
 
601
	}
-
 
602
	return r;
-
 
603
}
-
 
604
 
-
 
605
 
-
 
606
unsigned char inp(unsigned char port) __naked {
-
 
607
__asm
-
 
608
	ld      hl,#2
-
 
609
	add     hl,sp
-
 
610
	ld      c,(hl)
-
 
611
	in      a,(c)
-
 
612
	ld      l,a
-
 
613
	ld      h,#0
-
 
614
	ret
-
 
615
__endasm;
-
 
616
}
-
 
617
 
-
 
618
void outp(unsigned char port, unsigned char data) __naked {
-
 
619
__asm
-
 
620
	push bc
-
 
621
	ld      hl,#4
-
 
622
	add     hl,sp
-
 
623
	ld      c,(hl)
-
 
624
	inc     hl
-
 
625
	ld      b,(hl)
-
 
626
	out     (c),b
-
 
627
	pop     bc
-
 
628
	ret
-
 
629
__endasm;
-
 
630
}
-