@@ -279,13 +279,192 @@ uint32_t Bus::dma_reg(uint32_t offset) {
279
279
}
280
280
281
281
void Bus::set_dma_reg (uint32_t offset, uint32_t value) {
282
- switch (offset) {
283
- case 0x70 :
284
- dma.set_control (value);
282
+ auto major = (offset & 0x70 ) >> 4 ;
283
+ auto minor = offset & 0xf ;
284
+
285
+ Port active_port;
286
+ switch (major) {
287
+ // Per-channel registers
288
+ // 0-6
289
+ case 0 :
290
+ auto port = dma.from_index (major);
291
+ auto channel = dma.channels [port];
292
+
293
+ switch (minor){
294
+ case 0 : channel.set_base (value);
295
+ case 4 : channel.set_block_control (value);
296
+ case 8 : channel.set_control (value);
297
+ default :
298
+ std::cout << " [BUS] ERROR: Unhandled DMA write at " << std::to_string (offset) << " \n " ;
299
+ exit (0 );
300
+ }
301
+
302
+ if (channel.active ()) {
303
+ active_port = port;
304
+ }
305
+ else {
306
+ active_port = Port::NUL;
307
+ }
308
+ break ;
309
+ case 1 :
310
+ auto port = dma.from_index (major);
311
+ auto channel = dma.channels [port];
312
+
313
+ switch (minor) {
314
+ case 0 : channel.set_base (value);
315
+ case 4 : channel.set_block_control (value);
316
+ case 8 : channel.set_control (value);
317
+ default :
318
+ std::cout << " [BUS] ERROR: Unhandled DMA write at " << std::to_string (offset) << " \n " ;
319
+ exit (0 );
320
+ }
321
+
322
+ if (channel.active ()) {
323
+ active_port = port;
324
+ }
325
+ else {
326
+ active_port = Port::NUL;
327
+ }
328
+ break ;
329
+ case 2 :
330
+ auto port = dma.from_index (major);
331
+ auto channel = dma.channels [port];
332
+
333
+ switch (minor) {
334
+ case 0 : channel.set_base (value);
335
+ case 4 : channel.set_block_control (value);
336
+ case 8 : channel.set_control (value);
337
+ default :
338
+ std::cout << " [BUS] ERROR: Unhandled DMA write at " << std::to_string (offset) << " \n " ;
339
+ exit (0 );
340
+ }
341
+
342
+ if (channel.active ()) {
343
+ active_port = port;
344
+ }
345
+ else {
346
+ active_port = Port::NUL;
347
+ }
348
+ break ;
349
+ case 3 :
350
+ auto port = dma.from_index (major);
351
+ auto channel = dma.channels [port];
352
+
353
+ switch (minor) {
354
+ case 0 : channel.set_base (value);
355
+ case 4 : channel.set_block_control (value);
356
+ case 8 : channel.set_control (value);
357
+ default :
358
+ std::cout << " [BUS] ERROR: Unhandled DMA write at " << std::to_string (offset) << " \n " ;
359
+ exit (0 );
360
+ }
361
+
362
+ if (channel.active ()) {
363
+ active_port = port;
364
+ }
365
+ else {
366
+ active_port = Port::NUL;
367
+ }
368
+ break ;
369
+ case 4 :
370
+ auto port = dma.from_index (major);
371
+ auto channel = dma.channels [port];
372
+
373
+ switch (minor) {
374
+ case 0 : channel.set_base (value);
375
+ case 4 : channel.set_block_control (value);
376
+ case 8 : channel.set_control (value);
377
+ default :
378
+ std::cout << " [BUS] ERROR: Unhandled DMA write at " << std::to_string (offset) << " \n " ;
379
+ exit (0 );
380
+ }
381
+
382
+ if (channel.active ()) {
383
+ active_port = port;
384
+ }
385
+ else {
386
+ active_port = Port::NUL;
387
+ }
388
+ break ;
389
+ case 5 :
390
+ auto port = dma.from_index (major);
391
+ auto channel = dma.channels [port];
392
+
393
+ switch (minor) {
394
+ case 0 : channel.set_base (value);
395
+ case 4 : channel.set_block_control (value);
396
+ case 8 : channel.set_control (value);
397
+ default :
398
+ std::cout << " [BUS] ERROR: Unhandled DMA write at " << std::to_string (offset) << " \n " ;
399
+ exit (0 );
400
+ }
401
+
402
+ if (channel.active ()) {
403
+ active_port = port;
404
+ }
405
+ else {
406
+ active_port = Port::NUL;
407
+ }
408
+ break ;
409
+ case 6 :
410
+ auto port = dma.from_index (major);
411
+ auto channel = dma.channels [port];
412
+
413
+ switch (minor) {
414
+ case 0 : channel.set_base (value);
415
+ case 4 : channel.set_block_control (value);
416
+ case 8 : channel.set_control (value);
417
+ default :
418
+ std::cout << " [BUS] ERROR: Unhandled DMA write at " << std::to_string (offset) << " \n " ;
419
+ exit (0 );
420
+ }
421
+
422
+ if (channel.active ()) {
423
+ active_port = port;
424
+ }
425
+ else {
426
+ active_port = Port::NUL;
427
+ }
428
+ break ;
429
+ // Common DMA registers
430
+ case 7 :
431
+ switch (minor) {
432
+ case 0 :
433
+ dma.set_control (value);
434
+
435
+ case 4 :
436
+ dma.set_interrupt (value);
437
+
438
+ default :
439
+ std::cout << " [BUS] ERROR: Unhandled DMA write at " << std::to_string (offset) << " \n " ;
440
+ exit (0 );
441
+ }
442
+ active_port = Port::NUL;
443
+ break ;
444
+ default :
445
+ std::cout << " [BUS] ERROR: Unhandled DMA write at " << std::to_string (offset) << " \n " ;
446
+ exit (0 );
447
+ };
448
+
449
+ if (active_port != Port::NUL) {
450
+ do_dma (active_port); // Call your do_dma function with the active_port.
451
+ }
452
+ }
453
+
454
+ void Bus::do_dma (Port port) {
455
+ // DMA transfer has been started, for now let's
456
+ // process everything in one pass (i.e. no
457
+ // chopping or priority handling)
458
+ switch (dma.channels [port].sync ) {
459
+ case Sync::LinkedList:
460
+ std::cout << " [BUS] ERROR: Linked list mode unsupported\n " ;
461
+ exit (0 );
285
462
break ;
286
463
287
464
default :
288
- std::cout << " [BUS] ERROR: Unhandled DMA write access\n " ;
465
+ std::cout << " [BUS] UNIMPLEMENTED: DO DMA BLOCK\n " ;
466
+ exit (0 );
467
+ // do_dma_block(port);
289
468
break ;
290
469
}
291
470
}
0 commit comments