Browse Source

dmac interrupt impl

vampirefrog 1 year ago
parent
commit
9d34b3e3c2
4 changed files with 29 additions and 13 deletions
  1. 1
    1
      Makefile
  2. 7
    3
      dmac.c
  3. 1
    1
      v68.h
  4. 20
    8
      v68periph.c

+ 1
- 1
Makefile View File

@@ -12,7 +12,7 @@ $(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 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)
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 16
 	gcc $^ $(shell pkg-config --libs ao)  -lm -o $@
17 17
 
18 18
 xinfo: xinfo.o md5.o cmdline.o

+ 7
- 3
dmac.c View File

@@ -1,6 +1,7 @@
1 1
 /* DMAC ◆ DMA controller */
2 2
 
3 3
 #include "v68.h"
4
+#include "musashi/m68k.h"
4 5
 #include "dmac.h"
5 6
 
6 7
 static void dmac_transfer_start(int chan);
@@ -100,7 +101,6 @@ void dmac_tick(int chan) {
100 101
 		verbose2("dmac_tick memory->device mar=0x%08x dar=0x%08x data=0x%02x\n", v68.dmac.channels[chan].mar, v68.dmac.channels[chan].dar, data);
101 102
 	}
102 103
 
103
-
104 104
 	// decrease memory transfer counter
105 105
 	if (v68.dmac.channels[chan].mtc > 0)
106 106
 		v68.dmac.channels[chan].mtc--;
@@ -116,8 +116,7 @@ void dmac_tick(int chan) {
116 116
 	else if ((v68.dmac.channels[chan].scr & 0x0c) == 0x08)
117 117
 		v68.dmac.channels[chan].mar-=datasize;
118 118
 
119
-	if (v68.dmac.channels[chan].mtc <= 0)
120
-	{
119
+	if (v68.dmac.channels[chan].mtc <= 0) {
121 120
 		// End of transfer
122 121
 		verbose2("dmac_tick End of transfer\n");
123 122
 		if ((v68.dmac.channels[chan].ocr & 0x0c) != 0 && v68.dmac.channels[chan].btc > 0)
@@ -139,6 +138,9 @@ void dmac_tick(int chan) {
139 138
 		{
140 139
 			// m_cpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
141 140
 		}
141
+
142
+		v68.int_vec = 0x6a;
143
+		m68k_set_irq(3);
142 144
 	}
143 145
 }
144 146
 
@@ -185,6 +187,8 @@ static void dmac_transfer_abort(int chan) {
185 187
 	v68.dmac.channels[chan].cer = 0x11;
186 188
 	v68.dmac.channels[chan].ccr &= ~0xc0;
187 189
 	// m_dma_error((offs_t)3, v68.dmac.channels[chan].ccr & 0x08);
190
+	v68.int_vec = 0x6b;
191
+	m68k_set_irq(3);
188 192
 }
189 193
 
190 194
 static void dmac_transfer_halt(int chan) {

+ 1
- 1
v68.h View File

@@ -61,7 +61,7 @@ struct v68 {
61 61
 	int running;
62 62
 
63 63
 	/* MFP */
64
-	int mfp_vec;
64
+	int int_vec;
65 65
 
66 66
 	/* Sound Timing */
67 67
 	int16_t *bufL, *bufR;

+ 20
- 8
v68periph.c View File

@@ -51,18 +51,30 @@ uint32_t v68_periph_next_int(uint32_t cycles) {
51 51
 		next_int = v68.opm_timerb_cycles - v68.opm_timerb_counter;
52 52
 	}
53 53
 
54
+	if((v68.dmac.channels[3].csr & 0x08) && v68.dmac.channels[3].mtc * v68.oki_sample_cycles < next_int) {
55
+		next_int = v68.dmac.channels[3].mtc * v68.oki_sample_cycles;
56
+	}
57
+
54 58
 	verbose2("v68_periph_next_int returning %d\n", next_int);
55 59
 	return next_int;
56 60
 }
57 61
 
58 62
 uint32_t v68_int_ack_handler(int int_level) {
59
-	verbose1("v68_int_ack_handler %d\n", int_level);
60
-	if(int_level == 6) {
63
+	verbose1("v68_int_ack_handler int_level=%d int_vec=0x%02x\n", int_level, v68.int_vec);
64
+	if(int_level == 6) { /* MFP */
65
+		CPU_INT_LEVEL = 0;
66
+		int vec = v68.int_vec;
67
+		if(vec) {
68
+			verbose2("v68_int_ack_handler  MFP int ack vec=0x%04x vector address at 0x%08x points to 0x%08x)\n", v68.int_vec, v68.int_vec * 4, m68k_read_memory_32(v68.int_vec * 4));
69
+			v68.int_vec = 0;
70
+			return vec;
71
+		}
72
+	} else if(int_level == 3) { /* DMAC */
61 73
 		CPU_INT_LEVEL = 0;
62
-		int vec = v68.mfp_vec;
63
-		if(vec) { // MFP
64
-			verbose2("v68_int_ack_handler  MFP int ack vec=0x%04x vector address at 0x%08x points to 0x%08x)\n", v68.mfp_vec, v68.mfp_vec * 4, m68k_read_memory_32(v68.mfp_vec * 4));
65
-			v68.mfp_vec = 0;
74
+		int vec = v68.int_vec;
75
+		if(vec) {
76
+			verbose2("v68_int_ack_handler DMAC int ack vec=0x%04x vector address at 0x%08x points to 0x%08x)\n", v68.int_vec, v68.int_vec * 4, m68k_read_memory_32(v68.int_vec * 4));
77
+			v68.int_vec = 0;
66 78
 			return vec;
67 79
 		}
68 80
 	}
@@ -132,7 +144,7 @@ void v68_periph_advance(uint32_t cycles) {
132 144
 	if((v68.opm_flags & 0x01) && v68.opm_timera_counter < v68.opm_timera_cycles) {
133 145
 		v68.opm_timera_counter += cycles;
134 146
 		if(v68.opm_timera_counter >= v68.opm_timera_cycles && (v68.opm_flags & 0x04)) {
135
-			v68.mfp_vec = 0x43;
147
+			v68.int_vec = 0x43;
136 148
 			verbose2("v68_periph_advance  generating IRQ 6 Timer A\n");
137 149
 			m68k_set_irq(6);
138 150
 		}
@@ -142,7 +154,7 @@ void v68_periph_advance(uint32_t cycles) {
142 154
 	if((v68.opm_flags & 0x02) && v68.opm_timerb_counter < v68.opm_timerb_cycles) {
143 155
 		v68.opm_timerb_counter += cycles;
144 156
 		if(v68.opm_timerb_counter >= v68.opm_timerb_cycles && (v68.opm_flags & 0x08)) {
145
-			v68.mfp_vec = 0x43;
157
+			v68.int_vec = 0x43;
146 158
 			verbose2("v68_periph_advance generating IRQ 6 Timer B\n");
147 159
 			m68k_set_irq(6);
148 160
 		}

Loading…
Cancel
Save