ref: 1b4d507ed55ffb8d297129468c2e3aa3c2653dec
dir: /psx/dev/dma.h/
#ifndef DMA_H
#define DMA_H
#include <stdint.h>
#define PSX_DMAR_BEGIN 0x1f801080
#define PSX_DMAR_SIZE 0x80
#define PSX_DMAR_END 0x1f8010ff
#include "../bus.h"
#include "ic.h"
typedef struct {
uint32_t madr;
uint32_t bcr;
uint32_t chcr;
} dma_channel_t;
typedef struct {
uint32_t io_base, io_size;
psx_bus_t* bus;
psx_ic_t* ic;
dma_channel_t mdec_in;
dma_channel_t mdec_out;
dma_channel_t gpu;
dma_channel_t cdrom;
dma_channel_t spu;
dma_channel_t pio;
dma_channel_t otc;
int mdec_in_irq_delay;
int mdec_out_irq_delay;
int cdrom_irq_delay;
int spu_irq_delay;
int gpu_irq_delay;
int otc_irq_delay;
uint32_t dpcr;
uint32_t dicr;
} psx_dma_t;
psx_dma_t* psx_dma_create();
void psx_dma_init(psx_dma_t*, psx_bus_t*, psx_ic_t*);
void psx_dma_do_mdec_in(psx_dma_t*);
void psx_dma_do_mdec_out(psx_dma_t*);
void psx_dma_do_gpu(psx_dma_t*);
void psx_dma_do_cdrom(psx_dma_t*);
void psx_dma_do_spu(psx_dma_t*);
void psx_dma_do_pio(psx_dma_t*);
void psx_dma_do_otc(psx_dma_t*);
void psx_dma_perform(psx_dma_t*, int);
uint32_t psx_dma_read32(psx_dma_t*, uint32_t);
uint16_t psx_dma_read16(psx_dma_t*, uint32_t);
uint8_t psx_dma_read8(psx_dma_t*, uint32_t);
void psx_dma_write32(psx_dma_t*, uint32_t, uint32_t);
void psx_dma_write16(psx_dma_t*, uint32_t, uint16_t);
void psx_dma_write8(psx_dma_t*, uint32_t, uint8_t);
void psx_dma_destroy(psx_dma_t*);
void psx_dma_update(psx_dma_t*, int);
typedef void (*psx_dma_do_fn_t)(psx_dma_t*);
/*
0-2 DMA0, MDECin Priority (0..7; 0=Highest, 7=Lowest)
3 DMA0, MDECin Master Enable (0=Disable, 1=Enable)
4-6 DMA1, MDECout Priority (0..7; 0=Highest, 7=Lowest)
7 DMA1, MDECout Master Enable (0=Disable, 1=Enable)
8-10 DMA2, GPU Priority (0..7; 0=Highest, 7=Lowest)
11 DMA2, GPU Master Enable (0=Disable, 1=Enable)
12-14 DMA3, CDROM Priority (0..7; 0=Highest, 7=Lowest)
15 DMA3, CDROM Master Enable (0=Disable, 1=Enable)
16-18 DMA4, SPU Priority (0..7; 0=Highest, 7=Lowest)
19 DMA4, SPU Master Enable (0=Disable, 1=Enable)
20-22 DMA5, PIO Priority (0..7; 0=Highest, 7=Lowest)
23 DMA5, PIO Master Enable (0=Disable, 1=Enable)
24-26 DMA6, OTC Priority (0..7; 0=Highest, 7=Lowest)
27 DMA6, OTC Master Enable (0=Disable, 1=Enable)
28-30 Unknown, Priority Offset or so? (R/W)
31 Unknown, no effect? (R/W)
*/
#define DPCR_DMA0EN 0x00000008
#define DPCR_DMA1EN 0x00000080
#define DPCR_DMA2EN 0x00000800
#define DPCR_DMA3EN 0x00008000
#define DPCR_DMA4EN 0x00080000
#define DPCR_DMA5EN 0x00800000
#define DPCR_DMA6EN 0x08000000
/*
0 Transfer Direction (0=To Main RAM, 1=From Main RAM)
1 Memory Address Step (0=Forward;+4, 1=Backward;-4)
2-7 Not used (always zero)
8 Chopping Enable (0=Normal, 1=Chopping; run CPU during DMA gaps)
9-10 SyncMode, Transfer Synchronisation/Mode (0-3):
0 Start immediately and transfer all at once (used for CDROM, OTC)
1 Sync blocks to DMA requests (used for MDEC, SPU, and GPU-data)
2 Linked-List mode (used for GPU-command-lists)
3 Reserved (not used)
11-15 Not used (always zero)
16-18 Chopping DMA Window Size (1 SHL N words)
19 Not used (always zero)
20-22 Chopping CPU Window Size (1 SHL N clks)
23 Not used (always zero)
24 Start/Busy (0=Stopped/Completed, 1=Start/Enable/Busy)
25-27 Not used (always zero)
28 Start/Trigger (0=Normal, 1=Manual Start; use for SyncMode=0)
29 Unknown (R/W) Pause? (0=No, 1=Pause?) (For SyncMode=0 only?)
30 Unknown (R/W)
31 Not used (always zero)
*/
#define CHCR_TDIR_MASK 0x00000001
#define CHCR_STEP_MASK 0x00000002
#define CHCR_CPEN_MASK 0x00000100
#define CHCR_SYNC_MASK 0x00000600
#define CHCR_CDWS_MASK 0x00070000
#define CHCR_CCWS_MASK 0x00380000
#define CHCR_BUSY_MASK 0x01000000
#define CHCR_TRIG_MASK 0x10000000
#define SYNC_SHIF 9
#define CDWS_SHIF 16
#define CCWS_SHIF 19
#define CHCR_TDIR(c) (dma->c.chcr & CHCR_TDIR_MASK)
#define CHCR_STEP(c) (dma->c.chcr & CHCR_STEP_MASK)
#define CHCR_CPEN(c) (dma->c.chcr & CHCR_CPEN_MASK)
#define CHCR_SYNC(c) ((dma->c.chcr & CHCR_SYNC_MASK) >> SYNC_SHIF)
#define CHCR_CDWS(c) ((dma->c.chcr & CHCR_CDWS_MASK) >> CDWS_SHIF)
#define CHCR_CCWS(c) ((dma->c.chcr & CHCR_CCWS_MASK) >> CCWS_SHIF)
#define CHCR_BUSY(c) (dma->c.chcr & CHCR_BUSY_MASK)
#define CHCR_TRIG(c) (dma->c.chcr & CHCR_TRIG_MASK)
#define BCR_SIZE(c) (dma->c.bcr & 0xffff)
#define BCR_BCNT(c) ((dma->c.bcr >> 16) & 0xffff)
/*
0-5 Unknown (read/write-able)
6-14 Not used (always zero)
15 Force IRQ (sets bit31) (0=None, 1=Force Bit31=1)
16-22 IRQ Enable setting bit24-30 upon DMA0..DMA6 (0=None, 1=Enable)
23 IRQ Enable setting bit31 when bit24-30=nonzero (0=None, 1=Enable)
24-30 IRQ Flags for DMA0..DMA6 (Write 1 to reset) (0=None, 1=IRQ)
31 IRQ Signal (0-to-1 triggers 1F801070h.bit3) (0=None, 1=IRQ) (R)
*/
#define DICR_FORCE 0x00008000
#define DICR_FLGEN 0x007f0000
#define DICR_IRQEN 0x00800000
#define DICR_FLAGS 0x7f000000
#define DICR_IRQSI 0x80000000
#define DICR_DMA0EN 0x00010000
#define DICR_DMA1EN 0x00020000
#define DICR_DMA2EN 0x00040000
#define DICR_DMA3EN 0x00080000
#define DICR_DMA4EN 0x00100000
#define DICR_DMA5EN 0x00200000
#define DICR_DMA6EN 0x00400000
#define DICR_DMA0FL 0x01000000
#define DICR_DMA1FL 0x02000000
#define DICR_DMA2FL 0x04000000
#define DICR_DMA3FL 0x08000000
#define DICR_DMA4FL 0x10000000
#define DICR_DMA5FL 0x20000000
#define DICR_DMA6FL 0x40000000
#endif