Browse Source

v68: fake IPL, fake Human.sys, some cleanups, add emulator port, fix sound

vampirefrog 1 year ago
parent
commit
ba4f4bc68e
9 changed files with 291 additions and 354 deletions
  1. 22
    3
      Makefile
  2. 0
    2
      main.c
  3. 35
    17
      v68.c
  4. 1
    12
      v68.h
  5. 23
    68
      v68human.c
  6. 0
    61
      v68human.h
  7. 1
    4
      v68iocscall.c
  8. 6
    21
      v68ipl.c
  9. 203
    166
      v68periph.c

+ 22
- 3
Makefile View File

@@ -12,8 +12,27 @@ $(patsubst %.c,musashi/%.c,$(MUSASHIGENCFILES)): musashi/m68kmake musashi/m68k_i
12 12
 musashi/m68kmake: musashi/m68kmake.o
13 13
 	gcc $^ -o $@
14 14
 
15
-v68: main.o tools.o v68.o v68ipl.o v68io.o v68periph.o v68human.o v68doscall.o v68iocscall.o v68fecall.o sjis.o sjis_unicode.o utf8.o ym2151.o dmac.o okim6258.o vgm.o $(MUSASHIOBJS) $(MUSASHIGENOBJS)
16
-	gcc $^ $(shell pkg-config --libs ao)  -lm -o $@
15
+v68: main.o tools.o v68.o v68ipl.o v68io.o v68periph.o v68human.o v68doscall.o v68iocscall.o v68fecall.o sjis.o sjis_unicode.o utf8.o ym2151.o dmac.o okim6258.o vgm.o $(MUSASHIOBJS) $(MUSASHIGENOBJS) fake_ipl.inc fake_human.inc
16
+	gcc $(filter %.o,$^) $(shell pkg-config --libs ao)  -lm -o $@
17
+
18
+v68human.o: v68human.c fake_human.inc
19
+
20
+v68ipl.o: v68ipl.c fake_ipl.inc
21
+
22
+HAS060=wine ~/ownCloud/X68000/run68/run68.exe 'H:\\ownCloud\\X68000\\has060.x'
23
+HASFLAGS=-m68000
24
+LK=wine ~/ownCloud/X68000/run68/run68.exe x/xc/BIN/LK.X
25
+fake_ipl.inc: fake_ipl.s xdump
26
+	include=tests $(HAS060) $(HASFLAGS) $(patsubst %.inc,%.s,$@)
27
+	$(LK) /bff0000 $(patsubst %.inc,%.o,$@)
28
+	./xdump $(patsubst %.inc,%.x,$@) > $@
29
+	rm -f $(patsubst %.inc,%.x,$@) $(patsubst %.inc,%.o,$@)
30
+
31
+fake_human.inc: fake_human.s xdump
32
+	include=tests $(HAS060) $(HASFLAGS) $(patsubst %.inc,%.s,$@)
33
+	$(LK) /b006800 $(patsubst %.inc,%.o,$@)
34
+	./xdump $(patsubst %.inc,%.x,$@) > $@
35
+	rm -f $(patsubst %.inc,%.x,$@) $(patsubst %.inc,%.o,$@)
17 36
 
18 37
 xinfo: xinfo.o md5.o cmdline.o
19 38
 	gcc $^ -o $@
@@ -34,7 +53,7 @@ test-mem: test-mem.o v68.o v68human.o v68opm.o v68io.o v68doscall.o v68fecall.o
34 53
 	gcc -g -Wall $(shell pkg-config --cflags ao) -c $< -o $@
35 54
 
36 55
 clean:
37
-	rm -f v68 xinfo sjis2utf8 *.o musashi/*.o $(patsubst %.c,musashi/%.c,$(MUSASHIGENCFILES)) ay.js *.wasm *.map test
56
+	rm -f v68 xinfo xdump sjis2utf8 *.o musashi/*.o $(patsubst %.c,musashi/%.c,$(MUSASHIGENCFILES)) ay.js *.wasm *.map test
38 57
 
39 58
 main.o: main.c v68.h okim6258.h mamedef.h ym2151.h v68io.h cmdline.h \
40 59
  tools.h

+ 0
- 2
main.c View File

@@ -133,8 +133,6 @@ int main(int argc, char **argv, char **envp) {
133 133
 
134 134
 	signal(SIGINT, sighandler);
135 135
 
136
-	v68_queue_next_command();
137
-
138 136
 	/* -- Play some stuff -- */
139 137
 	while(running) {
140 138
 		int16_t bufL[BUF_SIZE], bufR[BUF_SIZE];

+ 35
- 17
v68.c View File

@@ -12,6 +12,8 @@
12 12
 #include "musashi/m68kcpu.h"
13 13
 
14 14
 
15
+static void v68_reset_cb(void);
16
+
15 17
 struct v68 v68;
16 18
 
17 19
 int v68_init(int clock, int ram_size, int sample_rate) {
@@ -30,17 +32,24 @@ int v68_init(int clock, int ram_size, int sample_rate) {
30 32
 
31 33
 	m68k_init();
32 34
 	m68k_set_cpu_type(M68K_CPU_TYPE_68000);
33
-	m68k_pulse_reset();
34 35
 
35 36
 	v68_ipl_init();
37
+	v68_human_init();
36 38
 	v68_periph_init();
39
+
40
+	m68k_pulse_reset();
41
+
37 42
 	v68_io_init();
38
-	v68_human_init();
39 43
 	v68_iocs_init();
40 44
 
41 45
 	return 0;
42 46
 }
43 47
 
48
+void v68_cpu_reset_instr_cb(void) {
49
+	verbose2("RESET peripherals\n");
50
+	v68.reset_pulsed = 1;
51
+}
52
+
44 53
 int v68_shutdown() {
45 54
 	free(v68.ram);
46 55
 
@@ -49,7 +58,7 @@ int v68_shutdown() {
49 58
 
50 59
 extern int m68ki_initial_cycles;
51 60
 int v68_fill_buffer(int16_t *bufL, int16_t *bufR, int samples) {
52
-	verbose1("v68_fill_buffer samples=%d\n", samples);
61
+	printf("v68_fill_buffer samples=%d\n", samples);
53 62
 	v68.prev_sound_cycles = 0;
54 63
 	v68.buf_remaining = samples;
55 64
 	v68.bufL = bufL;
@@ -73,7 +82,7 @@ int v68_fill_buffer(int16_t *bufL, int16_t *bufR, int samples) {
73 82
 		v68.prev_sound_cycles = 0;
74 83
 		int cycles = m68k_execute(next_int, v68.log_dasm);
75 84
 		int executed_cycles = v68.cpu_ended_timeslice ? next_int - m68ki_initial_cycles : cycles;
76
-		verbose2("v68_fill_buffer  executed_cycles=%d next_int=%d remaining_tstates = %d\n", executed_cycles, next_int, remaining_tstates);
85
+		verbose2("v68_fill_buffer  ended_timeslice=%d executed_cycles=%d next_int=%d remaining_tstates = %d\n", v68.cpu_ended_timeslice, executed_cycles, next_int, remaining_tstates);
77 86
 		v68.cpu_ended_timeslice = 0;
78 87
 
79 88
 		verbose2("v68_fill_buffer  advancing executed_cycles=%d - prev_sound_cycles=%d = %d\n", executed_cycles, v68.prev_sound_cycles, executed_cycles - v68.prev_sound_cycles);
@@ -89,7 +98,11 @@ int v68_fill_buffer(int16_t *bufL, int16_t *bufR, int samples) {
89 98
 }
90 99
 
91 100
 unsigned int m68k_read_memory_8(unsigned int addr) {
92
-	// addr &= 0x00ffffff;
101
+	if(addr <= 0x0000ffff && !v68.reset_pulsed) {
102
+		uint8_t r = v68_ipl_read_8(addr + 0xff0000);
103
+		verbose3("READ8 BOOT 0x%08x = 0x%02x\n", addr, r);
104
+		return r;
105
+	}
93 106
 
94 107
 	if(addr >= 0x00fe0000 && addr <= 0x00ffffff) {
95 108
 		uint8_t r = v68_ipl_read_8(addr);
@@ -114,7 +127,11 @@ unsigned int m68k_read_memory_8(unsigned int addr) {
114 127
 }
115 128
 
116 129
 unsigned int  m68k_read_memory_16(unsigned int addr) {
117
-	// addr &= 0x00ffffff;
130
+	if(addr <= 0x0000ffff && !v68.reset_pulsed) {
131
+		uint16_t r = v68_ipl_read_16(addr + 0xff0000);
132
+		verbose3("READ16 BOOT 0x%08x = 0x%04x\n", addr, r);
133
+		return r;
134
+	}
118 135
 
119 136
 	if(addr >= 0x00fe0000 && addr <= 0x00ffffff) {
120 137
 		uint16_t r = v68_ipl_read_16(addr);
@@ -139,7 +156,11 @@ unsigned int  m68k_read_memory_16(unsigned int addr) {
139 156
 }
140 157
 
141 158
 unsigned int  m68k_read_memory_32(unsigned int addr) {
142
-	// addr &= 0x00ffffff;
159
+	if(addr <= 0x0000ffff && !v68.reset_pulsed) {
160
+		uint32_t r = v68_ipl_read_32(addr + 0xff0000);
161
+		verbose3("READ32 BOOT 0x%08x = 0x%08x\n", addr, r);
162
+		return r;
163
+	}
143 164
 
144 165
 	if(addr >= 0x00fe0000 && addr <= 0x00ffffff) {
145 166
 		uint32_t r = v68_ipl_read_32(addr);
@@ -159,18 +180,17 @@ unsigned int  m68k_read_memory_32(unsigned int addr) {
159 180
 	}
160 181
 
161 182
 	uint32_t r = (v68.ram[addr] << 24) | (v68.ram[addr+1] << 16) | (v68.ram[addr+2] << 8) | v68.ram[addr+3];
162
-	verbose3("READ32 @0x%08x = 0x%08x\n", addr, r);
183
+	verbose3("READ32 RAM 0x%08x = 0x%08x\n", addr, r);
163 184
 	return r;
164 185
 }
165 186
 
166 187
 void m68k_write_memory_8(unsigned int addr, unsigned int data) {
167
-	// addr &= 0x00ffffff;
168
-
169
-	verbose3("WRITE8 0x%08x = %02x\n", addr, data);
170 188
 	if(addr >= 0x00e80000 && addr < 0x00eb0000) {
189
+		verbose3("WRITE8 PERIPH 0x%08x = 0x%02x\n", addr, data);
171 190
 		v68_write_periph_8(addr, data);
172 191
 		return;
173 192
 	}
193
+	verbose3("WRITE8 RAM 0x%08x = 0x%02x\n", addr, data);
174 194
 	if(addr > v68.ram_size) {
175 195
 		verbose2("Could not write RAM at 0x%08x = 0x%02x\n", addr, data);
176 196
 		return;
@@ -179,13 +199,12 @@ void m68k_write_memory_8(unsigned int addr, unsigned int data) {
179 199
 }
180 200
 
181 201
 void m68k_write_memory_16(unsigned int addr, unsigned int data) {
182
-	// addr &= 0x00ffffff;
183
-
184
-	verbose3("WRITE16 0x%08x = %04x\n", addr, data);
185 202
 	if(addr >= 0x00e80000 && addr < 0x00eb0000) {
203
+		verbose3("WRITE16 PERIPH 0x%08x = 0x%04x\n", addr, data);
186 204
 		v68_write_periph_16(addr, data);
187 205
 		return;
188 206
 	}
207
+	verbose3("WRITE16 RAM 0x%08x = 0x%04x\n", addr, data);
189 208
 	if(addr > v68.ram_size) {
190 209
 		verbose2("Could not write RAM at 0x%08x = 0x%04x\n", addr, data);
191 210
 		return;
@@ -195,13 +214,12 @@ void m68k_write_memory_16(unsigned int addr, unsigned int data) {
195 214
 }
196 215
 
197 216
 void m68k_write_memory_32(unsigned int addr, unsigned int data) {
198
-	// addr &= 0x00ffffff;
199
-
200
-	verbose3("WRITE32 0x%08x = %08x\n", addr, data);
201 217
 	if(addr >= 0x00e80000 && addr < 0x00eb0000) {
218
+		verbose3("WRITE32 PERIPH 0x%08x = 0x%08x\n", addr, data);
202 219
 		v68_write_periph_32(addr, data);
203 220
 		return;
204 221
 	}
222
+	verbose3("WRITE32 RAM 0x%08x = 0x%08x\n", addr, data);
205 223
 	if(addr > v68.ram_size) {
206 224
 		verbose2("Could not write RAM at 0x%08x = 0x%08x\n", addr, data);
207 225
 		return;

+ 1
- 12
v68.h View File

@@ -18,15 +18,6 @@
18 18
 #define HUMAN_HEAD      0x6800      /* Humanのメモリ管理ブロック位置 */
19 19
 #define FCB_WORK        0x20F00     /* DOSCALL GETFCB用ワーク領域 */
20 20
 #define HUMAN_WORK      0x21000     /* 割り込み処理先等のワーク領域 */
21
-#define TRAP0_WORK      0x20FF0000  /* TRAP割り込み処理先等のワーク領域 */
22
-#define TRAP1_WORK      0x21FF0000  /* TRAP割り込み処理先等のワーク領域 */
23
-#define TRAP2_WORK      0x22FF0000  /* TRAP割り込み処理先等のワーク領域 */
24
-#define TRAP3_WORK      0x23FF0000  /* TRAP割り込み処理先等のワーク領域 */
25
-#define TRAP4_WORK      0x24FF0000  /* TRAP割り込み処理先等のワーク領域 */
26
-#define TRAP5_WORK      0x25FF0000  /* TRAP割り込み処理先等のワーク領域 */
27
-#define TRAP6_WORK      0x26FF0000  /* TRAP割り込み処理先等のワーク領域 */
28
-#define TRAP7_WORK      0x27FF0000  /* TRAP割り込み処理先等のワーク領域 */
29
-#define TRAP8_WORK      0x28FF0000  /* TRAP割り込み処理先等のワーク領域 */
30 21
 #define ENV_TOP         0x21C00
31 22
 #define ENV_SIZE        0x2000
32 23
 #define STACK_TOP       ENV_TOP + ENV_SIZE
@@ -35,7 +26,6 @@
35 26
 #define PSP_SIZE        MB_SIZE + 240
36 27
 #define PROG_TOP        (STACK_TOP + STACK_SIZE + PSP_SIZE)
37 28
 #define NEST_MAX        20
38
-#define FILE_MAX        20
39 29
 
40 30
 #define RAS_INTERVAL    10000   /* ラスタ割り込みの間隔 */
41 31
 
@@ -53,12 +43,11 @@ struct v68 {
53 43
 	/* Memory allocation */
54 44
 	int heap_start, heap_top;
55 45
 
56
-	struct v68_file_info file_info[FILE_MAX];
57
-
58 46
 #define V68_CMD_QUEUE_LEN 8
59 47
 	char cmd_queue[V68_CMD_QUEUE_LEN][1024];
60 48
 	int cmd_queue_pos;
61 49
 	int running;
50
+	int reset_pulsed;
62 51
 
63 52
 	/* MFP */
64 53
 	int int_vec;

+ 23
- 68
v68human.c View File

@@ -7,78 +7,28 @@
7 7
 #include "musashi/m68kcpu.h"
8 8
 
9 9
 void v68_human_init() {
10
+	verbose1("v68_human_init\n");
10 11
 	v68.log_calls = 0;
11 12
 
12
-	/* Init file info */
13
-	memset(v68.file_info, 0, sizeof(v68.file_info));
14
-	v68.file_info[0].fh   = stdin;
15
-	v68.file_info[0].mode = 0;
16
-	v68.file_info[1].fh   = stdout;
17
-	v68.file_info[1].mode = 1;
18
-	v68.file_info[2].fh   = stderr;
19
-	v68.file_info[2].mode = 1;
20
-
21 13
 	v68.cmd_queue_pos = 0;
22 14
 	v68.running = 0;
23 15
 
24
-	/* Init trap vectors */
25
-	FLAG_S = 1;
26
-
27
-	/* Interrupts */
28
-	m68k_write_memory_32(0x28, HUMAN_WORK);        /* A traps */
29
-	m68k_write_memory_32(0x2C, HUMAN_WORK);        /* F traps */
30
-	m68k_write_memory_32(0x80, TRAP0_WORK);        /* trap0 */
31
-	m68k_write_memory_32(0x84, TRAP1_WORK);        /* trap1 */
32
-	m68k_write_memory_32(0x88, TRAP2_WORK);        /* trap2 */
33
-	m68k_write_memory_32(0x8C, TRAP3_WORK);        /* trap3 */
34
-	m68k_write_memory_32(0x90, TRAP4_WORK);        /* trap4 */
35
-	m68k_write_memory_32(0x94, TRAP5_WORK);        /* trap5 */
36
-	m68k_write_memory_32(0x98, TRAP6_WORK);        /* trap6 */
37
-	m68k_write_memory_32(0x9C, TRAP7_WORK);        /* trap7 */
38
-	m68k_write_memory_32(0xA0, TRAP8_WORK);        /* trap8 */
39
-	m68k_write_memory_32(0x118, 0);                /* vdisp */
40
-	m68k_write_memory_32(0x138, 0);                /* crtc */
41
-
42
-
43
-	uint16_t human_work[] = {
44
-		/* HUMAN_WORK + 0x00: Default exception handler */
45
-		0x4e73,                         /* rte                        */
46
-
47
-		/* HUMAN_WORK + 0x02: Default subroutine handler */
48
-		0x4e75,                         /* rts                        */
49
-
50
-		/* HUMAN_WORK + 0x04: Stop loop */
51
-		0x4e72, 0x2000,                 /* stop $2000                 */
52
-		0x60fa,                         /* bra -4                     */
16
+	uint16_t fake_human[] = {
17
+#include "fake_human.inc"
53 18
 	};
54 19
 
55
-	for(int i = 0; i < sizeof(human_work) / sizeof(human_work[0]); i++) {
56
-		m68k_write_memory_16(HUMAN_WORK + i * 2, human_work[i]);
57
-	}
58
-
59
-	/* IOCS call vector setting */
60
-	for(int i = 0; i < 256; i++) {
61
-		m68k_write_memory_32(0x400 + i * 4, HUMAN_WORK + 0x02);
62
-	}
63
-
64
-	/* IOCS work setting */
65
-	m68k_write_memory_16(0x970, 79);       /* Number of columns on screen -1 */
66
-	m68k_write_memory_16(0x972, 24);       /* Number of lines on screen -1 */
67
-
68
-	/* DOS call vector setting */
69
-	for(int i = 0; i < 256; i++) {
70
-		m68k_write_memory_32(0x1800 + i * 4, HUMAN_WORK + 0x02);
20
+	for(int i = 0; i < sizeof(fake_human) / sizeof(fake_human[0]); i++) {
21
+		v68.ram[HUMAN_HEAD + i * 2] = fake_human[i] >> 8;
22
+		v68.ram[HUMAN_HEAD + i * 2 + 1] = fake_human[i] & 0xff;
71 23
 	}
72 24
 
73
-	FLAG_S = 0;
74
-
75 25
 	v68.heap_start = v68.heap_top = STACK_TOP + STACK_SIZE;
76 26
 
77 27
 	/* Init mem chain */
78
-	m68k_write_memory_32(HUMAN_HEAD + 0x00, 0);
79
-	m68k_write_memory_32(HUMAN_HEAD + 0x04, 0);
80
-	m68k_write_memory_32(HUMAN_HEAD + 0x08, HUMAN_WORK);
81
-	m68k_write_memory_32(HUMAN_HEAD + 0x0c, 0);
28
+	m68k_write_memory_32(HUMAN_HEAD - 0x10 + 0x00, 0);
29
+	m68k_write_memory_32(HUMAN_HEAD - 0x10 + 0x04, 0);
30
+	m68k_write_memory_32(HUMAN_HEAD - 0x10 + 0x08, HUMAN_WORK);
31
+	m68k_write_memory_32(HUMAN_HEAD - 0x10 + 0x0c, 0);
82 32
 }
83 33
 
84 34
 int v68_run_command(char *cmd) {
@@ -257,6 +207,12 @@ int v68_run_command(char *cmd) {
257 207
 
258 208
 		/* 0x10: Environment vars pointer */
259 209
 		m68k_write_memory_32(m + 0x00, ENV_TOP);
210
+		/* 0x14: Return PC */
211
+		if(v68.cur_prog_addr) {
212
+			m68k_write_memory_32(m + 0x04, m68k_read_memory_32(v68.cur_prog_addr + 0x04));
213
+		} else {
214
+			m68k_write_memory_32(m + 0x04, m68k_get_reg(0, M68K_REG_PC));
215
+		}
260 216
 		/* 0x20: Command line pointer */
261 217
 		m68k_write_memory_32(m + 0x10, STACK_TOP);
262 218
 		/* 0x30: Start address of BSS */
@@ -318,9 +274,8 @@ void v68_queue_next_command() {
318 274
 		return;
319 275
 	}
320 276
 
321
-	/* Last command, HALT */
322
-	m68k_set_reg(M68K_REG_SR, 0x2000);
323
-	m68k_set_reg(M68K_REG_PC, HUMAN_WORK + 4);
277
+	/* Last command, restore PC*/
278
+	m68k_set_reg(M68K_REG_PC, m68k_read_memory_32(v68.cur_prog_addr + 0x04));
324 279
 }
325 280
 
326 281
 int v68_env_append(char *env) {
@@ -345,7 +300,7 @@ uint32_t v68_mem_alloc(int size, uint32_t parent_addr) {
345 300
 	/* Align to 4 bytes */
346 301
 	size = (size + 3) & 0xfffffc;
347 302
 
348
-	uint32_t first = m68k_read_memory_32(HUMAN_HEAD + 0x0c);
303
+	uint32_t first = m68k_read_memory_32(HUMAN_HEAD - 0x04);
349 304
 
350 305
 	uint32_t prev = first;
351 306
 	if(first) {
@@ -389,7 +344,7 @@ uint32_t v68_mem_alloc(int size, uint32_t parent_addr) {
389 344
 }
390 345
 
391 346
 int v68_mem_shrink(uint32_t addr, uint32_t new_size) {
392
-	uint32_t first = m68k_read_memory_32(HUMAN_HEAD + 0x0c);
347
+	uint32_t first = m68k_read_memory_32(HUMAN_HEAD - 0x04);
393 348
 
394 349
 	addr -= 16;
395 350
 
@@ -429,7 +384,7 @@ int v68_mem_shrink(uint32_t addr, uint32_t new_size) {
429 384
 }
430 385
 
431 386
 int v68_mem_free(uint32_t addr, uint32_t parent_addr) {
432
-	uint32_t first = m68k_read_memory_32(HUMAN_HEAD + 0x0c);
387
+	uint32_t first = m68k_read_memory_32(HUMAN_HEAD - 0x04);
433 388
 
434 389
 	addr -= 16;
435 390
 
@@ -480,7 +435,7 @@ int v68_mem_free(uint32_t addr, uint32_t parent_addr) {
480 435
 
481 436
 uint32_t v68_mem_remaining() {
482 437
 	uint32_t min = v68.heap_start;
483
-	uint32_t first = m68k_read_memory_32(HUMAN_HEAD + 0x0c);
438
+	uint32_t first = m68k_read_memory_32(HUMAN_HEAD - 0x04);
484 439
 	for(uint32_t cur = first; cur; cur = m68k_read_memory_32(cur + 0x0c)) {
485 440
 		uint32_t end = m68k_read_memory_32(cur + 0x08);
486 441
 		if(end > min) min = end;
@@ -491,7 +446,7 @@ uint32_t v68_mem_remaining() {
491 446
 }
492 447
 
493 448
 void v68_mem_dump() {
494
-	for(uint32_t cur = HUMAN_HEAD; cur; cur = m68k_read_memory_32(cur + 0x0c)) {
449
+	for(uint32_t cur = HUMAN_HEAD - 0x10; cur; cur = m68k_read_memory_32(cur + 0x0c)) {
495 450
 		verbose1("block @%06x addr=%06x prev=%06x parent=%06x end=%06x len=%d next=%06x\n",
496 451
 			cur, cur + 16,
497 452
 			m68k_read_memory_32(cur),

+ 0
- 61
v68human.h View File

@@ -3,67 +3,6 @@
3 3
 #include <stdio.h>
4 4
 #include <stdint.h>
5 5
 
6
-struct v68_psp {
7
-	uint32_t env_addr;        /* 0x10 (16)  Environment's address (not secured if -1) */
8
-	uint32_t return_addr;     /* 0x14 (20)  Return address at the end */
9
-	uint32_t ctrl_c_addr;     /* 0x18 (24)  Return address when interrupted by CTRL + C */
10
-	uint32_t error_ret_addr;  /* 0x1c (28)  Return address when interrupt due to error */
11
-	uint32_t cmdline_addr;    /* 0x20 (32)  Command line address */
12
-	uint8_t  file_handle[12]; /* 0x24 (36)  File handle usage of process */
13
-	                          /* (In use = 1 in the order of bits 0 to 7 of $24 to $2f) */
14
-	uint32_t bss_addr;        /* 0x30 (48)  Start address of BSS */
15
-	uint32_t heap_addr;       /* 0x34 (52)  Start address of heap (same as BSS) */
16
-	uint32_t stack_start;     /* 0x38 (56)  Initial stack address (end of heap + 1) */
17
-	uint32_t parent_usp;      /* 0x3c (60)  USP of the parent process */
18
-	uint32_t parent_ssp;      /* 0x40 (64)  parent process SSP */
19
-	uint16_t parent_sr;       /* 0x44 (68)  parent process SR */
20
-	uint16_t abort_sr;        /* 0x46 (70)  SR at abort */
21
-	uint32_t abort_ssp;       /* 0x48 (72)  SSP at abort */
22
-	uint32_t trap_10;         /* 0x4c (76)  trap #10 vector */
23
-	uint32_t trap_11;         /* 0x50 (80)  trap #11 vector */
24
-    uint32_t trap_12;         /* 0x54 (84)  trap #12 vector */
25
-	uint32_t trap_13;         /* 0x58 (88)  trap #13 vector */
26
-	uint32_t trap_14;         /* 0x5c (92)  trap #14 vector */
27
-	uint32_t shell_flag;      /* 0x60 (96)  shell activation flag (0: normal startup - 1: started as shell) */
28
-	uint8_t  module_num;      /* 0x64 (100) Module number */
29
-	uint8_t  unused[3];
30
-	uint32_t child_psp;       /* 0x68 (104) Process management pointer of loaded child process */
31
-	uint32_t unused2[5];
32
-	uint8_t  drive[2];        /* 0x80 (128) Drive name of executable file */
33
-	uint8_t  exec_path[66];   /* 0x82 (130) Path name of executable file */
34
-	uint8_t  exec_name[24];   /* 0xc4 (196) File name of executable file */
35
-	uint32_t unused3[9];
36
-} __attribute__((packed));    /* 240B */
37
-
38
-struct v68_x_header {
39
-	enum {
40
-		Normal,
41
-		MinimumBlock,
42
-		HighAddress
43
-	} load_mode;
44
-
45
-	uint8_t *base_address;
46
-	uint8_t *starting_address;
47
-	uint32_t text_section_size;
48
-	uint32_t data_section_size;
49
-	uint32_t block_section_size; /* Block storage section size, including .comm .stack */
50
-	uint32_t relocation_information_size;
51
-	uint32_t symbol_table_size;
52
-	uint32_t scd_line_number_table_size;
53
-	uint32_t scd_symbol_table_size;
54
-	uint32_t scd_string_table_size;
55
-	uint32_t bound_module_offset;
56
-} __attribute__((packed));
57
-
58
-struct v68_file_info {
59
-	FILE     *fh;
60
-	unsigned date;
61
-	unsigned time;
62
-	short    mode;
63
-	char     nest;
64
-	char     name[89];
65
-};
66
-
67 6
 void v68_human_init(void);
68 7
 
69 8
 /* Initialize allocator. */

+ 1
- 4
v68iocscall.c View File

@@ -465,10 +465,7 @@ static const char *iocs_call_names[256] = {
465 465
 };
466 466
 
467 467
 void v68_iocs_init() {
468
-	/* Set the IOCS call addresses at 0x400 */
469
-	for(int i = 0; i < 256; i++) {
470
-		m68k_write_memory_32(0x400 + i * 4, 0xff0000);
471
-	}
468
+
472 469
 }
473 470
 
474 471
 int v68_iocs_call(uint16_t instr) {

+ 6
- 21
v68ipl.c View File

@@ -15,29 +15,14 @@ static void write_ipl_16(uint32_t addr, const uint16_t *data, int data_len) {
15 15
 }
16 16
 
17 17
 void v68_ipl_init() {
18
-#define DMA3_VEC_END 0x6a
19
-#define DMA3_VEC_ERR 0x6b
20
-#define DMA3_INT_ADDR 0xff1940
21
-	const uint16_t dma3_int[] = {
22
-		/* DMA 3 interrupt handler */
23
-		0x2f08,                         /* move.l a0, -(a7)           */
24
-		0x41f9, 0x00e8, 0x40c0,         /* lea.l ($00e840c0), a0      */
25
-		0x11e8, 0x0001, 0x0c33,         /* move.b ($0001,A0), ($0c33) */
26
-		0x4a38, 0x0c32,                 /* tst.b ($0c32)              */
27
-		0x6b18,                         /* bmi.b ($00FF196C)          */
28
-		0x13fc, 0x0001, 0x00e9, 0xa007, /* move.b #$01, ($00e9a007)   */
29
-		0x13fc, 0x0003, 0x00e9, 0xa007, /* move.b #$03, ($00e9a007)   */
30
-		0x13fc, 0x0001, 0x00e9, 0x2001, /* move.b #$01, ($00e92001)   */
31
-		0x4a10,                         /* tst.b (a0)                 */
32
-		0x50d0,                         /* st (a0)                    */
33
-		0x4238, 0x0c32,                 /* clr.b ($0c32)              */
34
-		0x205f,                         /* movea.l (a7)+, a0          */
35
-		0x4e73,                         /* rte                        */
18
+	const uint16_t fake_ipl[] = {
19
+#include "fake_ipl.inc"
36 20
 	};
37 21
 
38
-	write_ipl_16(DMA3_INT_ADDR, dma3_int, sizeof(dma3_int) / sizeof(dma3_int[0]));
39
-	m68k_write_memory_32(DMA3_VEC_END * 4, DMA3_INT_ADDR);
40
-	m68k_write_memory_32(DMA3_VEC_ERR * 4, DMA3_INT_ADDR);
22
+	write_ipl_16(0xff0000, fake_ipl, sizeof(fake_ipl) / sizeof(fake_ipl[0]));
23
+	/* IOCS work setting */
24
+	m68k_write_memory_16(0x970, 79);       /* Number of columns on screen -1 */
25
+	m68k_write_memory_16(0x972, 24);       /* Number of lines on screen -1 */
41 26
 }
42 27
 
43 28
 uint8_t v68_ipl_read_8(uint32_t addr) {

+ 203
- 166
v68periph.c View File

@@ -1,5 +1,6 @@
1 1
 #include "v68.h"
2 2
 #include "v68periph.h"
3
+#include "v68iocscall.h"
3 4
 #include "musashi/m68kcpu.h"
4 5
 #include "tools.h"
5 6
 
@@ -7,11 +8,29 @@
7 8
 #define OPM_CLOCK 4000000
8 9
 static uint32_t v68_opm_calc_timera(void);
9 10
 static uint32_t v68_opm_calc_timerb(void);
11
+unsigned int v68_read_periph_32(unsigned int addr);
12
+unsigned int v68_read_periph_16(unsigned int addr);
13
+unsigned int v68_read_periph_8(unsigned int addr);
14
+void v68_write_periph_32(unsigned int addr, unsigned int data);
15
+void v68_write_periph_16(unsigned int addr, unsigned int data);
16
+void v68_write_periph_8(unsigned int addr, unsigned int data);
17
+void v68_opm_write_8(uint32_t addr, uint8_t data);
18
+uint8_t v68_opm_read_8(uint32_t addr);
19
+void v68_mfp_write_8(uint32_t addr, uint8_t value);
20
+uint8_t v68_mfp_read_8(uint32_t addr);
21
+void v68_adpcm_write_8(uint32_t addr, uint8_t value);
22
+uint8_t v68_adpcm_read_8(uint32_t addr);
23
+void v68_ppi_write_8(uint32_t addr, uint8_t value);
24
+uint8_t v68_ppi_read_8(uint32_t addr);
25
+void v68_emu_write_16(uint32_t addr, uint8_t data);
10 26
 
11 27
 void v68_periph_init() {
12 28
 	verbose1("v68_periph_init\n");
13 29
 	v68.periph_timers_altered = 0;
14 30
 
31
+	// for mapping $ff0000 at $000000 at startup
32
+	v68.reset_pulsed = 0;
33
+
15 34
 	ym2151_init(&v68.opm, OPM_CLOCK, v68.sample_rate);
16 35
 	ym2151_reset_chip(&v68.opm);
17 36
 	v68.opm_clka = 0;
@@ -172,175 +191,46 @@ void v68_periph_advance(uint32_t cycles) {
172 191
 		}
173 192
 	}
174 193
 
175
-	v68_render_tstates(v68.periph_cycles - v68.prev_sound_cycles);
176
-	v68.prev_sound_cycles = v68.periph_cycles;
194
+	v68_render_tstates(cycles - v68.prev_sound_cycles);
177 195
 
178 196
 	verbose2("v68_periph_advance done periph_cycles=%d\n", v68.periph_cycles);
179 197
 
180 198
 	v68.in_periph_timing = 0;
181 199
 }
182 200
 
183
-/* FM音源 ◆ FM sound source (OPM) */
184
-static uint32_t v68_opm_calc_timera() {
185
-	uint64_t x = 1024 * v68.opm_clka;
186
-	x *= v68.cpu_clock;
187
-	x /= 62500;
188
-	return x;
189
-}
190
-
191
-static uint32_t v68_opm_calc_timerb() {
192
-	uint64_t x = 1024 * (256 - v68.opm_clkb);
193
-	x *= v68.cpu_clock;
194
-	x /= 4000000;
195
-	return x;
196
-}
197
-
198
-void v68_opm_write_8(uint32_t addr, uint8_t data) {
199
-	verbose1("v68_opm_write_8 0x%08x 0x%02x\n", addr, data);
200
-	switch(addr) {
201
-		case 0x01:
202
-			v68.opm_addr_latch = data;
203
-			break;
204
-		case 0x03: {
205
-				verbose2("v68_opm_write_8  DATA opm_addr_latch=0x%02x data=0x%02x\n", v68.opm_addr_latch, data);
206
-				ym2151_write_reg(&v68.opm, v68.opm_addr_latch, data);
207
-#ifndef __EMSCRIPTEN__
208
-				if(v68.logger)
209
-					vgm_logger_write_ym2151(v68.logger, v68.opm_addr_latch, data);
210
-#endif
211
-				int clka = v68.opm_clka, clkb = v68.opm_clkb;
212
-				switch(v68.opm_addr_latch) {
213
-					case 0x10:
214
-						clka &= 0x0003;
215
-						clka |= data << 2;
216
-						if(v68.opm_clka != clka) {
217
-							v68.opm_clka = clka;
218
-							v68.opm_timera_cycles = v68_opm_calc_timera();
219
-							v68.periph_timers_altered = 1;
220
-						}
221
-						break;
222
-					case 0x11:
223
-						clka &= 0x03fc;
224
-						clka |= data & 0x03;
225
-						if(v68.opm_clka != clka) {
226
-							v68.opm_clka = clka;
227
-							v68.opm_timera_cycles = v68_opm_calc_timera();
228
-							v68.periph_timers_altered = 1;
229
-						}
230
-						break;
231
-					case 0x12:
232
-						clkb = data;
233
-						if(v68.opm_clkb != clkb) {
234
-							v68.opm_clkb = clkb;
235
-							v68.opm_timerb_cycles = v68_opm_calc_timerb();
236
-							v68.periph_timers_altered = 1;
237
-						}
238
-						break;
239
-					case 0x14: {
240
-							if((data & 0x3f) != (v68.opm_flags & 0x3f)) {
241
-								v68.periph_timers_altered = 1;
242
-							}
243
-							v68.opm_flags = data & 0x0f;
244
-							/* Check for reset */
245
-							if(data & 0x10) {
246
-								v68.opm_timera_counter = 0;
247
-							}
248
-							if(data & 0x20) {
249
-								v68.opm_timerb_counter = 0;
250
-							}
251
-						}
252
-						break;
253
-					case 0x1b: {
254
-							if((data & 0x80) != (v68.opm_ct & 0x80)) {
255
-								v68.periph_timers_altered = 1;
256
-							}
257
-							v68.opm_ct = data & 0xc0;
258
-						}
259
-						break;
260
-				}
261
-			}
262
-			break;
263
-	}
264
-}
265
-
266
-uint8_t v68_opm_read_8(uint32_t addr) {
267
-	verbose1("v68_opm_read_8 addr=0x%08x\n", addr);
268
-	switch(addr) {
269
-		case 0x03: {
270
-			uint8_t ret = 0;
271
-			if(v68.opm_timera_counter >= v68.opm_timera_cycles) ret |= 0x01;
272
-			if(v68.opm_timerb_counter >= v68.opm_timerb_cycles) ret |= 0x02;
273
-			return ret;
274
-		}
275
-	}
276
-	return 0x00;
277
-}
278
-
279
-/* MFP ◆ Multi-function peripheral */
280
-void v68_mfp_write_8(uint32_t addr, uint8_t value) {
281
-	verbose2("v68_mfp_write_8 0x%08x = 0x%02x\n", addr, value);
282
-}
283
-
284
-uint8_t v68_mfp_read_8(uint32_t addr) {
285
-	verbose2("v68_mfp_read_8 %08x\n", addr);
286
-	return 0x00;
287
-}
288
-
289
-/* ADPCM ◆ OKI M6258 ADPCM */
290
-void v68_adpcm_write_8(uint32_t addr, uint8_t value) {
291
-	verbose1("v68_adpcm_write_8 addr=0x%08x value=0x%02x\n", addr, value);
292
-	switch(addr) {
293
-		case 0x01: /* 0xe92001 ADPCM command */
294
-			okim6258_write(&v68.oki, 0x00, value);
295
-#ifndef __EMSCRIPTEN__
296
-			if(v68.logger)
297
-				vgm_logger_write_okim6258(v68.logger, 0x00, value);
298
-#endif
299
-			if(value & 0x02) {
300
-				v68.periph_timers_altered = 1;
301
-				v68.oki_freq = 15625;
302
-				v68.oki_sample_cycles = v68.cpu_clock * 2 / v68.oki_freq;
303
-			}
304
-			break;
305
-		case 0x03: /* 0xe92003 Data input / output */
306
-			okim6258_write(&v68.oki, 0x01, value);
307
-#ifndef __EMSCRIPTEN__
308
-			if(v68.logger)
309
-				vgm_logger_write_okim6258(v68.logger, 0x01, value);
310
-#endif
311
-			break;
312
-	}
313
-}
314
-
315
-uint8_t v68_adpcm_read_8(uint32_t addr) {
316
-	verbose1("v68_adpcm_read_8 0x%08x\n", addr);
317
-	return 0x00;
318
-}
319
-
320
-/* i8255 ◆ Programmable peripheral interface */
321
-void v68_ppi_write_8(uint32_t addr, uint8_t value) {
322
-	verbose2("v68_ppi_write_8 0x%08x = 0x%02x\n", addr, value);
323
-}
324
-
325
-uint8_t v68_ppi_read_8(uint32_t addr) {
326
-	verbose2("v68_ppi_read_8 0x%08x\n", addr);
327
-	return 0x00;
328
-}
329
-
330 201
 static void v68_periph_before_read(uint32_t addr) {
331 202
 	(void)addr;
332 203
 	verbose1("v68_periph_before_read addr=0x%08x prev_sound_cycles=%d in_periph_timing=%d\n", addr, v68.prev_sound_cycles, v68.in_periph_timing);
333 204
 
334 205
 	if(v68.in_periph_timing) {
206
+		verbose2("v68_periph_before_read periph_cycles=%d prev_sound_cycles=%d periph_cycles-prev_sound_cycles=%d\n", v68.periph_cycles, v68.prev_sound_cycles, v68.periph_cycles - v68.prev_sound_cycles);
335 207
 		v68_render_tstates(v68.periph_cycles - v68.prev_sound_cycles);
336 208
 		v68.prev_sound_cycles = v68.periph_cycles;
337 209
 	} else {
210
+		verbose2("v68_periph_before_read cycles_run=%d prev_sound_cycles=%d cycles_run-prev_sound_cycles=%d\n", m68k_cycles_run(), v68.prev_sound_cycles, m68k_cycles_run() - v68.prev_sound_cycles);
338 211
 		v68.periph_cycles = v68.prev_sound_cycles;
339 212
 		v68_periph_advance(m68k_cycles_run() - v68.prev_sound_cycles);
340 213
 		v68.prev_sound_cycles = m68k_cycles_run();
341 214
 	}
342 215
 }
343 216
 
217
+static void v68_periph_before_write(uint32_t addr) {
218
+	/* Check for OKIM6258 or Y2151 writes */
219
+	// if(addr == 0xe92001 || addr == 0xe92003 || addr == 0xe90003) {
220
+		verbose1("v68_periph_before_write addr=0x%08x in_periph_timing=%d prev_sound_cycles=%d periph_cycles=%d\n", addr, v68.in_periph_timing, v68.prev_sound_cycles, v68.periph_cycles);
221
+		v68_periph_before_read(addr);
222
+	// }
223
+}
224
+
225
+static void v68_periph_after_write(void) {
226
+	if(v68.periph_timers_altered) {
227
+		verbose1("timers altered at %d cycles, %d remaining\n", m68k_cycles_run(), m68k_cycles_remaining());
228
+		v68.periph_timers_altered = 0;
229
+		v68.cpu_ended_timeslice = 1;
230
+		m68k_end_timeslice();
231
+	}
232
+}
233
+
344 234
 unsigned int v68_read_periph_32(unsigned int addr) {
345 235
 	v68_periph_before_read(addr);
346 236
 	if(addr < 0xe82000) { /* CRTコントローラ ◆ CRT controller */
@@ -446,23 +336,6 @@ unsigned int v68_read_periph_8(unsigned int addr) {
446 336
 	return 0xff;
447 337
 }
448 338
 
449
-static void v68_periph_before_write(uint32_t addr) {
450
-	/* Check for OKIM6258 or Y2151 writes */
451
-	// if(addr == 0xe92001 || addr == 0xe92003 || addr == 0xe90003) {
452
-		verbose1("v68_periph_before_write addr=0x%08x in_periph_timing=%d prev_sound_cycles=%d periph_cycles=%d\n", addr, v68.in_periph_timing, v68.prev_sound_cycles, v68.periph_cycles);
453
-		v68_periph_before_read(addr);
454
-	// }
455
-}
456
-
457
-static void v68_periph_after_write(void) {
458
-	if(v68.periph_timers_altered) {
459
-		verbose1("timers altered at %d cycles, %d remaining\n", m68k_cycles_run(), m68k_cycles_remaining());
460
-		v68.periph_timers_altered = 0;
461
-		v68.cpu_ended_timeslice = 1;
462
-		m68k_end_timeslice();
463
-	}
464
-}
465
-
466 339
 void v68_write_periph_32(unsigned int addr, unsigned int data) {
467 340
 	verbose2("write_periph_32 addr=0x%08x data=0x%08x cycles=%d remaining=%d\n", addr, data, m68k_cycles_run(), m68k_cycles_remaining());
468 341
 
@@ -535,6 +408,8 @@ void v68_write_periph_16(unsigned int addr, unsigned int data) {
535 408
 		v68_ppi_write_8((addr & 0xff) + 0, (data >> 8) & 0xff);
536 409
 		v68_ppi_write_8((addr & 0xff) + 1, (data     ) & 0xff);
537 410
 	} else if(addr < 0xe9e000) { /* I/O コントローラ ◆ I/O controller */
411
+	} else if(addr < 0xeb0000) { /* Emulator port */
412
+		v68_emu_write_16(addr & 0xff, data);
538 413
 	}
539 414
 
540 415
 	v68_periph_after_write();
@@ -569,3 +444,165 @@ void v68_write_periph_8(unsigned int addr, unsigned int data) {
569 444
 
570 445
 	v68_periph_after_write();
571 446
 }
447
+
448
+
449
+/* FM音源 ◆ FM sound source (OPM) */
450
+static uint32_t v68_opm_calc_timera() {
451
+	uint64_t x = 1024 * v68.opm_clka;
452
+	x *= v68.cpu_clock;
453
+	x /= 62500;
454
+	return x;
455
+}
456
+
457
+static uint32_t v68_opm_calc_timerb() {
458
+	uint64_t x = 1024 * (256 - v68.opm_clkb);
459
+	x *= v68.cpu_clock;
460
+	x /= 4000000;
461
+	return x;
462
+}
463
+
464
+void v68_opm_write_8(uint32_t addr, uint8_t data) {
465
+	verbose1("v68_opm_write_8 0x%08x 0x%02x\n", addr, data);
466
+	switch(addr) {
467
+		case 0x01:
468
+			v68.opm_addr_latch = data;
469
+			break;
470
+		case 0x03: {
471
+				verbose2("v68_opm_write_8  DATA opm_addr_latch=0x%02x data=0x%02x\n", v68.opm_addr_latch, data);
472
+				ym2151_write_reg(&v68.opm, v68.opm_addr_latch, data);
473
+#ifndef __EMSCRIPTEN__
474
+				if(v68.logger)
475
+					vgm_logger_write_ym2151(v68.logger, v68.opm_addr_latch, data);
476
+#endif
477
+				int clka = v68.opm_clka, clkb = v68.opm_clkb;
478
+				switch(v68.opm_addr_latch) {
479
+					case 0x10:
480
+						clka &= 0x0003;
481
+						clka |= data << 2;
482
+						if(v68.opm_clka != clka) {
483
+							v68.opm_clka = clka;
484
+							v68.opm_timera_cycles = v68_opm_calc_timera();
485
+							v68.periph_timers_altered = 1;
486
+						}
487
+						break;
488
+					case 0x11:
489
+						clka &= 0x03fc;
490
+						clka |= data & 0x03;
491
+						if(v68.opm_clka != clka) {
492
+							v68.opm_clka = clka;
493
+							v68.opm_timera_cycles = v68_opm_calc_timera();
494
+							v68.periph_timers_altered = 1;
495
+						}
496
+						break;
497
+					case 0x12:
498
+						clkb = data;
499
+						if(v68.opm_clkb != clkb) {
500
+							v68.opm_clkb = clkb;
501
+							v68.opm_timerb_cycles = v68_opm_calc_timerb();
502
+							v68.periph_timers_altered = 1;
503
+						}
504
+						break;
505
+					case 0x14: {
506
+							if((data & 0x3f) != (v68.opm_flags & 0x3f)) {
507
+								v68.periph_timers_altered = 1;
508
+							}
509
+							v68.opm_flags = data & 0x0f;
510
+							/* Check for reset */
511
+							if(data & 0x10) {
512
+								v68.opm_timera_counter = 0;
513
+							}
514
+							if(data & 0x20) {
515
+								v68.opm_timerb_counter = 0;
516
+							}
517
+						}
518
+						break;
519
+					case 0x1b: {
520
+							if((data & 0x80) != (v68.opm_ct & 0x80)) {
521
+								v68.periph_timers_altered = 1;
522
+							}
523
+							v68.opm_ct = data & 0xc0;
524
+						}
525
+						break;
526
+				}
527
+			}
528
+			break;
529
+	}
530
+}
531
+
532
+uint8_t v68_opm_read_8(uint32_t addr) {
533
+	verbose1("v68_opm_read_8 addr=0x%08x\n", addr);
534
+	switch(addr) {
535
+		case 0x03: {
536
+			uint8_t ret = 0;
537
+			if(v68.opm_timera_counter >= v68.opm_timera_cycles) ret |= 0x01;
538
+			if(v68.opm_timerb_counter >= v68.opm_timerb_cycles) ret |= 0x02;
539
+			return ret;
540
+		}
541
+	}
542
+	return 0x00;
543
+}
544
+
545
+/* MFP ◆ Multi-function peripheral */
546
+void v68_mfp_write_8(uint32_t addr, uint8_t value) {
547
+	verbose2("v68_mfp_write_8 0x%08x = 0x%02x\n", addr, value);
548
+}
549
+
550
+uint8_t v68_mfp_read_8(uint32_t addr) {
551
+	verbose2("v68_mfp_read_8 %08x\n", addr);
552
+	return 0x00;
553
+}
554
+
555
+/* ADPCM ◆ OKI M6258 ADPCM */
556
+void v68_adpcm_write_8(uint32_t addr, uint8_t value) {
557
+	verbose1("v68_adpcm_write_8 addr=0x%08x value=0x%02x\n", addr, value);
558
+	switch(addr) {
559
+		case 0x01: /* 0xe92001 ADPCM command */
560
+			okim6258_write(&v68.oki, 0x00, value);
561
+#ifndef __EMSCRIPTEN__
562
+			if(v68.logger)
563
+				vgm_logger_write_okim6258(v68.logger, 0x00, value);
564
+#endif
565
+			if(value & 0x02) {
566
+				v68.periph_timers_altered = 1;
567
+				v68.oki_freq = 15625;
568
+				v68.oki_sample_cycles = v68.cpu_clock * 2 / v68.oki_freq;
569
+			}
570
+			break;
571
+		case 0x03: /* 0xe92003 Data input / output */
572
+			okim6258_write(&v68.oki, 0x01, value);
573
+#ifndef __EMSCRIPTEN__
574
+			if(v68.logger)
575
+				vgm_logger_write_okim6258(v68.logger, 0x01, value);
576
+#endif
577
+			break;
578
+	}
579
+}
580
+
581
+uint8_t v68_adpcm_read_8(uint32_t addr) {
582
+	verbose1("v68_adpcm_read_8 0x%08x\n", addr);
583
+	return 0x00;
584
+}
585
+
586
+/* i8255 ◆ Programmable peripheral interface */
587
+void v68_ppi_write_8(uint32_t addr, uint8_t value) {
588
+	verbose2("v68_ppi_write_8 0x%08x = 0x%02x\n", addr, value);
589
+}
590
+
591
+uint8_t v68_ppi_read_8(uint32_t addr) {
592
+	verbose2("v68_ppi_read_8 0x%08x\n", addr);
593
+	return 0x00;
594
+}
595
+
596
+/* Emulator specific ports */
597
+void v68_emu_write_16(uint32_t addr, uint8_t data) {
598
+	if(addr == 0x00) {
599
+		if((data & 0xff00) == 0xff00)
600
+			v68_dos_call(data);
601
+		else if((data & 0xff00) == 0xfe00)
602
+			v68_fe_call(data);
603
+	} else if(addr == 0x04) {
604
+		v68_iocs_call(data);
605
+	} else if(addr == 0x08) {
606
+		v68_queue_next_command();
607
+	}
608
+}

Loading…
Cancel
Save