Search
lxdream.org :: lxdream :: r54:d8b73031289c
lxdream 0.9.1
released Jun 29
Download Now
changeset54:d8b73031289c
parent53:f2981805b929
child55:96323c198da3
authornkeynes
dateSun Jan 01 08:08:40 2006 +0000 (18 years ago)
Add (partial) DMAC implementation
src/Makefile.am
src/Makefile.in
src/sh4/dmac.c
src/sh4/scif.c
src/sh4/sh4core.h
src/sh4/sh4dasm.c
src/sh4/sh4dasm.h
src/sh4/sh4mmio.c
1.1 --- a/src/Makefile.am Thu Dec 29 12:52:29 2005 +0000
1.2 +++ b/src/Makefile.am Sun Jan 01 08:08:40 2006 +0000
1.3 @@ -15,7 +15,7 @@
1.4 pvr2.c pvr2.h \
1.5 gdrom/ide.c gdrom/ide.h \
1.6 video.c dreamcast.c dreamcast.h \
1.7 - sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c \
1.8 + sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \
1.9 sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \
1.10 sh4/sh4mmio.c sh4/sh4mmio.h sh4/scif.c \
1.11 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \
2.1 --- a/src/Makefile.in Thu Dec 29 12:52:29 2005 +0000
2.2 +++ b/src/Makefile.in Sun Jan 01 08:08:40 2006 +0000
2.3 @@ -142,7 +142,7 @@
2.4 pvr2.c pvr2.h \
2.5 gdrom/ide.c gdrom/ide.h \
2.6 video.c dreamcast.c dreamcast.h \
2.7 - sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c \
2.8 + sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \
2.9 sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \
2.10 sh4/sh4mmio.c sh4/sh4mmio.h sh4/scif.c \
2.11 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \
2.12 @@ -171,13 +171,14 @@
2.13 am_dream_OBJECTS = main.$(OBJEXT) mem.$(OBJEXT) watch.$(OBJEXT) \
2.14 asic.$(OBJEXT) pvr2.$(OBJEXT) ide.$(OBJEXT) video.$(OBJEXT) \
2.15 dreamcast.$(OBJEXT) intc.$(OBJEXT) sh4mem.$(OBJEXT) \
2.16 - timer.$(OBJEXT) sh4core.$(OBJEXT) sh4dasm.$(OBJEXT) \
2.17 - sh4mmio.$(OBJEXT) scif.$(OBJEXT) armcore.$(OBJEXT) \
2.18 - armdasm.$(OBJEXT) armmem.$(OBJEXT) aica.$(OBJEXT) \
2.19 - maple.$(OBJEXT) controller.$(OBJEXT) support.$(OBJEXT) \
2.20 - interface.$(OBJEXT) callbacks.$(OBJEXT) gui.$(OBJEXT) \
2.21 - mmr_win.$(OBJEXT) debug_win.$(OBJEXT) dump_win.$(OBJEXT) \
2.22 - loader.$(OBJEXT) bootstrap.$(OBJEXT) util.$(OBJEXT)
2.23 + timer.$(OBJEXT) dmac.$(OBJEXT) sh4core.$(OBJEXT) \
2.24 + sh4dasm.$(OBJEXT) sh4mmio.$(OBJEXT) scif.$(OBJEXT) \
2.25 + armcore.$(OBJEXT) armdasm.$(OBJEXT) armmem.$(OBJEXT) \
2.26 + aica.$(OBJEXT) maple.$(OBJEXT) controller.$(OBJEXT) \
2.27 + support.$(OBJEXT) interface.$(OBJEXT) callbacks.$(OBJEXT) \
2.28 + gui.$(OBJEXT) mmr_win.$(OBJEXT) debug_win.$(OBJEXT) \
2.29 + dump_win.$(OBJEXT) loader.$(OBJEXT) bootstrap.$(OBJEXT) \
2.30 + util.$(OBJEXT)
2.31 dream_OBJECTS = $(am_dream_OBJECTS)
2.32 dream_DEPENDENCIES =
2.33 dream_LDFLAGS =
2.34 @@ -189,18 +190,18 @@
2.35 @AMDEP_TRUE@ ./$(DEPDIR)/armdasm.Po ./$(DEPDIR)/armmem.Po \
2.36 @AMDEP_TRUE@ ./$(DEPDIR)/asic.Po ./$(DEPDIR)/bootstrap.Po \
2.37 @AMDEP_TRUE@ ./$(DEPDIR)/callbacks.Po ./$(DEPDIR)/controller.Po \
2.38 -@AMDEP_TRUE@ ./$(DEPDIR)/debug_win.Po ./$(DEPDIR)/dreamcast.Po \
2.39 -@AMDEP_TRUE@ ./$(DEPDIR)/dump_win.Po ./$(DEPDIR)/gui.Po \
2.40 -@AMDEP_TRUE@ ./$(DEPDIR)/ide.Po ./$(DEPDIR)/intc.Po \
2.41 -@AMDEP_TRUE@ ./$(DEPDIR)/interface.Po ./$(DEPDIR)/loader.Po \
2.42 -@AMDEP_TRUE@ ./$(DEPDIR)/main.Po ./$(DEPDIR)/maple.Po \
2.43 -@AMDEP_TRUE@ ./$(DEPDIR)/mem.Po ./$(DEPDIR)/mmr_win.Po \
2.44 -@AMDEP_TRUE@ ./$(DEPDIR)/pvr2.Po ./$(DEPDIR)/scif.Po \
2.45 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4core.Po ./$(DEPDIR)/sh4dasm.Po \
2.46 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4mem.Po ./$(DEPDIR)/sh4mmio.Po \
2.47 -@AMDEP_TRUE@ ./$(DEPDIR)/support.Po ./$(DEPDIR)/timer.Po \
2.48 -@AMDEP_TRUE@ ./$(DEPDIR)/util.Po ./$(DEPDIR)/video.Po \
2.49 -@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po
2.50 +@AMDEP_TRUE@ ./$(DEPDIR)/debug_win.Po ./$(DEPDIR)/dmac.Po \
2.51 +@AMDEP_TRUE@ ./$(DEPDIR)/dreamcast.Po ./$(DEPDIR)/dump_win.Po \
2.52 +@AMDEP_TRUE@ ./$(DEPDIR)/gui.Po ./$(DEPDIR)/ide.Po \
2.53 +@AMDEP_TRUE@ ./$(DEPDIR)/intc.Po ./$(DEPDIR)/interface.Po \
2.54 +@AMDEP_TRUE@ ./$(DEPDIR)/loader.Po ./$(DEPDIR)/main.Po \
2.55 +@AMDEP_TRUE@ ./$(DEPDIR)/maple.Po ./$(DEPDIR)/mem.Po \
2.56 +@AMDEP_TRUE@ ./$(DEPDIR)/mmr_win.Po ./$(DEPDIR)/pvr2.Po \
2.57 +@AMDEP_TRUE@ ./$(DEPDIR)/scif.Po ./$(DEPDIR)/sh4core.Po \
2.58 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4dasm.Po ./$(DEPDIR)/sh4mem.Po \
2.59 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4mmio.Po ./$(DEPDIR)/support.Po \
2.60 +@AMDEP_TRUE@ ./$(DEPDIR)/timer.Po ./$(DEPDIR)/util.Po \
2.61 +@AMDEP_TRUE@ ./$(DEPDIR)/video.Po ./$(DEPDIR)/watch.Po
2.62 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
2.63 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
2.64 CCLD = $(CC)
2.65 @@ -261,6 +262,7 @@
2.66 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks.Po@am__quote@
2.67 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/controller.Po@am__quote@
2.68 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug_win.Po@am__quote@
2.69 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmac.Po@am__quote@
2.70 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dreamcast.Po@am__quote@
2.71 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_win.Po@am__quote@
2.72 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui.Po@am__quote@
2.73 @@ -394,6 +396,28 @@
2.74 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.75 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o timer.obj `if test -f 'sh4/timer.c'; then $(CYGPATH_W) 'sh4/timer.c'; else $(CYGPATH_W) '$(srcdir)/sh4/timer.c'; fi`
2.76
2.77 +dmac.o: sh4/dmac.c
2.78 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dmac.o -MD -MP -MF "$(DEPDIR)/dmac.Tpo" \
2.79 +@am__fastdepCC_TRUE@ -c -o dmac.o `test -f 'sh4/dmac.c' || echo '$(srcdir)/'`sh4/dmac.c; \
2.80 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dmac.Tpo" "$(DEPDIR)/dmac.Po"; \
2.81 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/dmac.Tpo"; exit 1; \
2.82 +@am__fastdepCC_TRUE@ fi
2.83 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/dmac.c' object='dmac.o' libtool=no @AMDEPBACKSLASH@
2.84 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dmac.Po' tmpdepfile='$(DEPDIR)/dmac.TPo' @AMDEPBACKSLASH@
2.85 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.86 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dmac.o `test -f 'sh4/dmac.c' || echo '$(srcdir)/'`sh4/dmac.c
2.87 +
2.88 +dmac.obj: sh4/dmac.c
2.89 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dmac.obj -MD -MP -MF "$(DEPDIR)/dmac.Tpo" \
2.90 +@am__fastdepCC_TRUE@ -c -o dmac.obj `if test -f 'sh4/dmac.c'; then $(CYGPATH_W) 'sh4/dmac.c'; else $(CYGPATH_W) '$(srcdir)/sh4/dmac.c'; fi`; \
2.91 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dmac.Tpo" "$(DEPDIR)/dmac.Po"; \
2.92 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/dmac.Tpo"; exit 1; \
2.93 +@am__fastdepCC_TRUE@ fi
2.94 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/dmac.c' object='dmac.obj' libtool=no @AMDEPBACKSLASH@
2.95 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dmac.Po' tmpdepfile='$(DEPDIR)/dmac.TPo' @AMDEPBACKSLASH@
2.96 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.97 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dmac.obj `if test -f 'sh4/dmac.c'; then $(CYGPATH_W) 'sh4/dmac.c'; else $(CYGPATH_W) '$(srcdir)/sh4/dmac.c'; fi`
2.98 +
2.99 sh4core.o: sh4/sh4core.c
2.100 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sh4core.o -MD -MP -MF "$(DEPDIR)/sh4core.Tpo" \
2.101 @am__fastdepCC_TRUE@ -c -o sh4core.o `test -f 'sh4/sh4core.c' || echo '$(srcdir)/'`sh4/sh4core.c; \
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/src/sh4/dmac.c Sun Jan 01 08:08:40 2006 +0000
3.3 @@ -0,0 +1,351 @@
3.4 +/**
3.5 + * $Id: dmac.c,v 1.1 2006-01-01 08:08:40 nkeynes Exp $
3.6 + *
3.7 + * SH4 onboard DMA controller (DMAC) peripheral.
3.8 + *
3.9 + * Copyright (c) 2005 Nathan Keynes.
3.10 + *
3.11 + * This program is free software; you can redistribute it and/or modify
3.12 + * it under the terms of the GNU General Public License as published by
3.13 + * the Free Software Foundation; either version 2 of the License, or
3.14 + * (at your option) any later version.
3.15 + *
3.16 + * This program is distributed in the hope that it will be useful,
3.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.19 + * GNU General Public License for more details.
3.20 + */
3.21 +#define MODULE sh4_module
3.22 +
3.23 +#include "dream.h"
3.24 +#include "mem.h"
3.25 +#include "sh4/sh4core.h"
3.26 +#include "sh4/sh4mmio.h"
3.27 +#include "sh4/intc.h"
3.28 +#include "sh4/dmac.h"
3.29 +
3.30 +static int DMAC_xfer_size[8] = {8, 1, 2, 4, 32, 1, 1, 1};
3.31 +
3.32 +/* Control flags */
3.33 +#define CHCR_IE 0x04 /* Interrupt Enable */
3.34 +#define CHCR_TE 0x02 /* Transfer End */
3.35 +#define CHCR_DE 0x01 /* DMAC Enable */
3.36 +
3.37 +#define IS_DMAC_ENABLED() ((MMIO_READ(DMAC,DMAOR)&0x07) == 0x01)
3.38 +
3.39 +#define IS_AUTO_REQUEST(val) ((val & 0x0C00) == 0x0400)
3.40 +#define CHANNEL_RESOURCE(val) ((val >> 8) & 0x0F)
3.41 +
3.42 +#define DMA_SOURCE(chan) MMIO_READ(DMAC, SAR0 + (chan<<4))
3.43 +#define DMA_DEST(chan) MMIO_READ(DMAC, DAR0 + (chan<<4))
3.44 +#define DMA_COUNT(chan) (MMIO_READ(DMAC, DMATCR0 + (chan<<4)) & 0x00FFFFFF)
3.45 +#define DMA_CONTROL(chan) MMIO_READ(DMAC, CHCR0 + (chan<<4))
3.46 +#define IS_CHANNEL_ENABLED(ctrl) ((ctrl & 0x03) == 0x01)
3.47 +#define IS_CHANNEL_IRQ_ENABLED(ctrl) (ctrl & CHCR_IE)
3.48 +#define IS_CHANNEL_IRQ_ACTIVE(ctrl) ((ctrl & (CHCR_IE|CHCR_TE)) == (CHCR_IE|CHCR_TE))
3.49 +
3.50 +#define DMARES_MEMORY_TO_MEMORY 0x00
3.51 +#define DMARES_MEMORY_TO_DEVICE 0x02
3.52 +#define DMARES_DEVICE_TO_MEMORY 0x03
3.53 +#define DMARES_MEMORY_TO_MEMORY_AUTO 0x04
3.54 +#define DMARES_MEMORY_TO_PERIPH_AUTO 0x05
3.55 +#define DMARES_PERIPH_TO_MEMORY_AUTO 0x06
3.56 +#define DMARES_SCI_TRANSMIT_EMPTY 0x08
3.57 +#define DMARES_SCI_RECEIVE_FULL 0x09
3.58 +#define DMARES_SCIF_TRANSMIT_EMPTY 0x0A
3.59 +#define DMARES_SCIF_RECEIVE_FULL 0x0B
3.60 +#define DMARES_MEMORY_TO_MEMORY_TMU 0x0C
3.61 +#define DMARES_MEMORY_TO_PERIPH_TMU 0x0D
3.62 +#define DMARES_PERIPH_TO_MEMORY_TMU 0x0E
3.63 +
3.64 +void DMAC_set_control( uint32_t channel, uint32_t val )
3.65 +{
3.66 + uint32_t oldval = DMA_CONTROL(channel);
3.67 + int resource;
3.68 + MMIO_WRITE( DMAC, CHCR0 + (channel<<4), val );
3.69 +
3.70 + /* If TE or IE are cleared, clear the interrupt request */
3.71 + if( IS_CHANNEL_IRQ_ACTIVE(oldval) &&
3.72 + !IS_CHANNEL_IRQ_ACTIVE(val) )
3.73 + intc_clear_interrupt( INT_DMA_DMTE0+channel );
3.74 +
3.75 + resource = CHANNEL_RESOURCE(val);
3.76 + if( IS_CHANNEL_ENABLED(val) ) {
3.77 + if( resource >= DMARES_MEMORY_TO_MEMORY_AUTO &&
3.78 + resource < DMARES_SCI_TRANSMIT_EMPTY ) {
3.79 + /* Autorun */
3.80 + }
3.81 + }
3.82 +
3.83 + /* Everything else we don't need to care about until we actually try to
3.84 + * run the channel
3.85 + */
3.86 +}
3.87 +
3.88 +int32_t mmio_region_DMAC_read( uint32_t reg )
3.89 +{
3.90 + return MMIO_READ( DMAC, reg );
3.91 +}
3.92 +
3.93 +void mmio_region_DMAC_write( uint32_t reg, uint32_t val )
3.94 +{
3.95 + switch( reg ) {
3.96 + case DMAOR:
3.97 + MMIO_WRITE( DMAC, reg, val );
3.98 + break;
3.99 + case CHCR0: DMAC_set_control( 0, val ); break;
3.100 + case CHCR1: DMAC_set_control( 1, val ); break;
3.101 + case CHCR2: DMAC_set_control( 2, val ); break;
3.102 + case CHCR3: DMAC_set_control( 3, val ); break;
3.103 + default:
3.104 + MMIO_WRITE( DMAC, reg, val );
3.105 + }
3.106 +}
3.107 +
3.108 +/**
3.109 + * Execute up to run_count transfers on the specified channel. Assumes the
3.110 + * trigger for the channel has been received.
3.111 + *
3.112 + * @param channel Channel number (0-3) to run.
3.113 + * @param run_count number of transfers to execute, or 0 to run to the
3.114 + * end of the transfer count.
3.115 + * @return actual number of transfers run
3.116 + */
3.117 +int DMAC_run_channel( uint32_t channel, uint32_t run_count )
3.118 +{
3.119 + char burst[32]; /* Transfer burst */
3.120 + uint32_t control = DMA_CONTROL(channel);
3.121 +
3.122 + if( IS_CHANNEL_ENABLED(control) ) {
3.123 + uint32_t source = DMA_SOURCE(channel);
3.124 + uint32_t dest = DMA_DEST(channel);
3.125 + uint32_t count = DMA_COUNT( channel );
3.126 + if( count == 0 )
3.127 + count = 0x01000000;
3.128 + if( run_count == 0 || run_count > count )
3.129 + run_count = count;
3.130 + uint32_t xfersize = DMAC_xfer_size[ (control >> 4)&0x07 ];
3.131 + int source_step, dest_step;
3.132 + int resource = (control >> 8) & 0x0F;
3.133 + switch( (control >> 14) & 0x03 ) {
3.134 + case 0: dest_step = 0; break;
3.135 + case 1: dest_step = xfersize; break;
3.136 + case 2: dest_step = -xfersize; break;
3.137 + case 3: dest_step = 0; break; /* Illegal */
3.138 + }
3.139 + switch( (control >> 12) & 0x03 ) {
3.140 + case 0: source_step = 0; break;
3.141 + case 1: source_step = xfersize; break;
3.142 + case 2: source_step = -xfersize; break;
3.143 + case 3: source_step = 0; break; /* Illegal */
3.144 + }
3.145 +
3.146 + while( run_count > 0 ) {
3.147 + /* Origin */
3.148 + if( (resource & 0x02) == 0 ) {
3.149 + /* Source is a normal memory address */
3.150 +
3.151 + } else {
3.152 + /* Device */
3.153 + }
3.154 +
3.155 + /* Destination */
3.156 + if( (resource & 0x01) == 0 ) {
3.157 + /* Destination is a normal memory address */
3.158 + } else {
3.159 + }
3.160 + run_count--;
3.161 + count--;
3.162 + }
3.163 + }
3.164 +}
3.165 +
3.166 +/**
3.167 + * Fetch a block of data by DMA from memory to an external device (ie the
3.168 + * ASIC). The DMA channel must be configured for Mem=>dev or it will return
3.169 + * no bytes and whinge mightily. Note this is NOT used for SH4 peripheral
3.170 + * transfers.
3.171 + *
3.172 + * @return the number of bytes actually transferred.
3.173 + */
3.174 +uint32_t DMAC_get_buffer( int channel, char *buf, uint32_t numBytes )
3.175 +{
3.176 + uint32_t control = DMA_CONTROL(channel);
3.177 + uint32_t source, count, run_count, size, i;
3.178 + char tmp[32];
3.179 +
3.180 + if( !IS_CHANNEL_ENABLED(control) || !IS_DMAC_ENABLED() )
3.181 + return 0;
3.182 +
3.183 + if( ((control >> 8) & 0x0F) != DMARES_MEMORY_TO_DEVICE ) {
3.184 + /* Error? */
3.185 +
3.186 + return 0;
3.187 + }
3.188 +
3.189 + source = DMA_SOURCE(channel);
3.190 + count = DMA_COUNT(channel);
3.191 + if( count == 0 ) count = 0x01000000;
3.192 +
3.193 + size = DMAC_xfer_size[ (control >> 4)&0x07 ];
3.194 + run_count = numBytes / size;
3.195 + if( run_count > count || run_count == 0 )
3.196 + run_count = count;
3.197 +
3.198 + /* Do copy - FIXME: doesn't work when crossing regions */
3.199 + char *region = mem_get_region( source );
3.200 + switch( (control >> 12) & 0x03 ) {
3.201 + case 0:
3.202 + memcpy( tmp, region, size );
3.203 + for( i=0; i<run_count; i++ ) {
3.204 + memcpy( buf, tmp, size );
3.205 + buf += size;
3.206 + }
3.207 + break;
3.208 + case 1:
3.209 + i = run_count * size;
3.210 + memcpy( buf, region, i );
3.211 + source += i;
3.212 + break;
3.213 + case 2:
3.214 + for( i=0; i<run_count; i++ ) {
3.215 + memcpy( buf, region, size );
3.216 + buf += size;
3.217 + region -= size;
3.218 + }
3.219 + source -= (run_count * size);
3.220 + break;
3.221 + default:
3.222 + return 0; /* Illegal */
3.223 + }
3.224 +
3.225 + /* Update the channel registers */
3.226 + count -= run_count;
3.227 + MMIO_WRITE( DMAC, SAR0 + (channel<<4), source );
3.228 + MMIO_WRITE( DMAC, DMATCR0 + (channel<<4), count );
3.229 + if( count == 0 ) {
3.230 + control |= CHCR_TE;
3.231 + if( IS_CHANNEL_IRQ_ENABLED(control) )
3.232 + intc_raise_interrupt( INT_DMA_DMTE0 + channel );
3.233 + MMIO_WRITE( DMAC, CHCR0 + (channel<<4), control );
3.234 + }
3.235 +
3.236 + return run_count * size;
3.237 +}
3.238 +
3.239 +uint32_t DMAC_put_buffer( int channel, char *buf, uint32_t numBytes )
3.240 +{
3.241 + uint32_t control = DMA_CONTROL(channel);
3.242 + uint32_t dest, count, run_count, size, i;
3.243 + char tmp[32];
3.244 +
3.245 + if( !IS_CHANNEL_ENABLED(control) || !IS_DMAC_ENABLED() )
3.246 + return 0;
3.247 +
3.248 + if( ((control >> 8) & 0x0F) != DMARES_DEVICE_TO_MEMORY ) {
3.249 + /* Error? */
3.250 + return 0;
3.251 + }
3.252 +
3.253 + dest = DMA_DEST(channel);
3.254 + count = DMA_COUNT(channel);
3.255 + if( count == 0 ) count = 0x01000000;
3.256 +
3.257 + size = DMAC_xfer_size[ (control >> 4)&0x07 ];
3.258 + run_count = numBytes / size;
3.259 + if( run_count > count || run_count == 0 )
3.260 + run_count = count;
3.261 +
3.262 + /* Do copy - FIXME: doesn't work when crossing regions */
3.263 + char *region = mem_get_region( dest );
3.264 + switch( (control >> 12) & 0x03 ) {
3.265 + case 0:
3.266 + for( i=0; i<run_count; i++ ) {
3.267 + /* Doesn't make a whole lot of sense, but hey... */
3.268 + memcpy( region, buf, size );
3.269 + buf += size;
3.270 + }
3.271 + break;
3.272 + case 1:
3.273 + i = run_count * size;
3.274 + memcpy( region, buf, i );
3.275 + dest += i;
3.276 + break;
3.277 + case 2:
3.278 + for( i=0; i<run_count; i++ ) {
3.279 + memcpy( region, buf, size );
3.280 + buf += size;
3.281 + region -= size;
3.282 + }
3.283 + dest -= (run_count * size);
3.284 + break;
3.285 + default:
3.286 + return 0; /* Illegal */
3.287 + }
3.288 +
3.289 + /* Update the channel registers */
3.290 + count -= run_count;
3.291 + MMIO_WRITE( DMAC, DAR0 + (channel<<4), dest );
3.292 + MMIO_WRITE( DMAC, DMATCR0 + (channel<<4), count );
3.293 + if( count == 0 ) {
3.294 + control |= CHCR_TE;
3.295 + if( IS_CHANNEL_IRQ_ENABLED(control) )
3.296 + intc_raise_interrupt( INT_DMA_DMTE0 + channel );
3.297 + MMIO_WRITE( DMAC, CHCR0 + (channel<<4), control );
3.298 + }
3.299 + return run_count * size;
3.300 +}
3.301 +
3.302 +void DMAC_reset( void )
3.303 +{
3.304 +
3.305 +}
3.306 +
3.307 +void DMAC_save_state( FILE *F )
3.308 +{
3.309 +
3.310 +}
3.311 +
3.312 +int DMAC_load_state( FILE *f )
3.313 +{
3.314 + return 0;
3.315 +}
3.316 +
3.317 +void DMAC_trigger( int resource )
3.318 +{
3.319 + int i;
3.320 + if( !IS_DMAC_ENABLED() )
3.321 + return;
3.322 + for( i=0; i<4; i++ ) {
3.323 + uint32_t control = DMA_CONTROL(i);
3.324 + if( IS_CHANNEL_ENABLED(control) ) {
3.325 + uint32_t channel_res = CHANNEL_RESOURCE(control);
3.326 + switch( resource ) {
3.327 + case DMAC_EXTERNAL:
3.328 + if( channel_res == DMARES_MEMORY_TO_MEMORY )
3.329 + DMAC_run_channel(i,1);
3.330 + break;
3.331 + case DMAC_SCI_TDE:
3.332 + if( channel_res == DMARES_SCI_TRANSMIT_EMPTY )
3.333 + DMAC_run_channel(i,1);
3.334 + break;
3.335 + case DMAC_SCI_RDF:
3.336 + if( channel_res == DMARES_SCI_RECEIVE_FULL )
3.337 + DMAC_run_channel(i,1);
3.338 + break;
3.339 + case DMAC_SCIF_TDE:
3.340 + if( channel_res == DMARES_SCIF_TRANSMIT_EMPTY )
3.341 + DMAC_run_channel(i,1);
3.342 + break;
3.343 + case DMAC_SCIF_RDF:
3.344 + if( channel_res == DMARES_SCIF_RECEIVE_FULL )
3.345 + DMAC_run_channel(i,1);
3.346 + break;
3.347 + case DMAC_TMU_ICI:
3.348 + if( channel_res >= DMARES_MEMORY_TO_MEMORY_TMU )
3.349 + DMAC_run_channel(i,1);
3.350 + break;
3.351 + }
3.352 + }
3.353 + }
3.354 +}
4.1 --- a/src/sh4/scif.c Thu Dec 29 12:52:29 2005 +0000
4.2 +++ b/src/sh4/scif.c Sun Jan 01 08:08:40 2006 +0000
4.3 @@ -1,5 +1,5 @@
4.4 /**
4.5 - * $Id: scif.c,v 1.7 2005-12-26 03:54:55 nkeynes Exp $
4.6 + * $Id: scif.c,v 1.8 2006-01-01 08:08:40 nkeynes Exp $
4.7 * SCIF (Serial Communication Interface with FIFO) implementation - part of the
4.8 * SH4 standard on-chip peripheral set. The SCIF is hooked up to the DCs
4.9 * external serial port
4.10 @@ -20,9 +20,10 @@
4.11 #include <glib.h>
4.12 #include "dream.h"
4.13 #include "mem.h"
4.14 -#include "sh4core.h"
4.15 -#include "sh4mmio.h"
4.16 -#include "intc.h"
4.17 +#include "sh4/sh4core.h"
4.18 +#include "sh4/sh4mmio.h"
4.19 +#include "sh4/intc.h"
4.20 +#include "sh4/dmac.h"
4.21 #include "clock.h"
4.22 #include "serial.h"
4.23
4.24 @@ -255,6 +256,7 @@
4.25 tmp |= SCFSR2_RDF;
4.26 if( IS_RECEIVE_IRQ_ENABLED() )
4.27 intc_raise_interrupt( INT_SCIF_RXI );
4.28 + DMAC_trigger( DMAC_SCIF_RDF );
4.29 }
4.30 MMIO_WRITE( SCIF, SCFSR2, tmp );
4.31 return TRUE;
4.32 @@ -313,6 +315,7 @@
4.33 tmp |= SCFSR2_TEND; /* Transmission ended - no data waiting */
4.34 if( IS_TRANSMIT_IRQ_ENABLED() )
4.35 intc_raise_interrupt( INT_SCIF_TXI );
4.36 + DMAC_trigger( DMAC_SCIF_TDE );
4.37 MMIO_WRITE( SCIF, SCFSR2, tmp );
4.38 }
4.39 return (int)(unsigned int)result;
4.40 @@ -368,6 +371,7 @@
4.41 MMIO_WRITE( SCIF, SCFSR2, MMIO_READ( SCIF, SCFSR2 ) | SCFSR2_TEND | SCFSR2_TDFE );
4.42 if( IS_TRANSMIT_IRQ_ENABLED() ) {
4.43 intc_raise_interrupt( INT_SCIF_TXI );
4.44 + DMAC_trigger( DMAC_SCIF_TDE );
4.45 }
4.46 }
4.47
4.48 @@ -609,6 +613,7 @@
4.49 MMIO_WRITE( SCIF, SCFSR2, tmp | SCFSR2_DR );
4.50 if( IS_RECEIVE_IRQ_ENABLED() )
4.51 intc_raise_interrupt( INT_SCIF_RXI );
4.52 + DMAC_trigger( DMAC_SCIF_RDF );
4.53 }
4.54 }
4.55 SCIF_rcvd_last_tick = rcvd;
5.1 --- a/src/sh4/sh4core.h Thu Dec 29 12:52:29 2005 +0000
5.2 +++ b/src/sh4/sh4core.h Sun Jan 01 08:08:40 2006 +0000
5.3 @@ -1,8 +1,8 @@
5.4 /**
5.5 - * $Id: sh4core.h,v 1.9 2005-12-29 12:52:29 nkeynes Exp $
5.6 + * $Id: sh4core.h,v 1.10 2006-01-01 08:08:40 nkeynes Exp $
5.7 *
5.8 - * This file defines the public functions exported by the SH4 core, except
5.9 - * for disassembly functions defined in sh4dasm.h
5.10 + * This file defines the internal functions exported/used by the SH4 core,
5.11 + * except for disassembly functions defined in sh4dasm.h
5.12 *
5.13 * Copyright (c) 2005 Nathan Keynes.
5.14 *
5.15 @@ -53,7 +53,6 @@
5.16 */
5.17 #define SH4_STATE_STANDBY 4
5.18
5.19 -
5.20 struct sh4_registers {
5.21 uint32_t r[16];
5.22 uint32_t r_bank[8]; /* hidden banked registers */
5.23 @@ -105,12 +104,15 @@
5.24 int32_t sh4_read_phys_word( uint32_t addr );
5.25
5.26 /* Peripheral functions */
5.27 -void DMAC_run_slice( uint32_t );
5.28 void TMU_run_slice( uint32_t );
5.29 void TMU_update_clocks( void );
5.30 void TMU_reset( void );
5.31 void TMU_save_state( FILE * );
5.32 int TMU_load_state( FILE * );
5.33 +void DMAC_reset( void );
5.34 +void DMAC_run_slice( uint32_t );
5.35 +void DMAC_save_state( FILE * );
5.36 +int DMAC_load_state( FILE * );
5.37 void SCIF_reset( void );
5.38 void SCIF_run_slice( uint32_t );
5.39 void SCIF_save_state( FILE *f );
6.1 --- a/src/sh4/sh4dasm.c Thu Dec 29 12:52:29 2005 +0000
6.2 +++ b/src/sh4/sh4dasm.c Sun Jan 01 08:08:40 2006 +0000
6.3 @@ -1,5 +1,5 @@
6.4 /**
6.5 - * $Id: sh4dasm.c,v 1.8 2005-12-26 11:47:15 nkeynes Exp $
6.6 + * $Id: sh4dasm.c,v 1.9 2006-01-01 08:08:40 nkeynes Exp $
6.7 *
6.8 * SH4 CPU definition and disassembly functions
6.9 *
6.10 @@ -380,16 +380,19 @@
6.11 }
6.12
6.13
6.14 -void sh4_disasm_region( FILE *f, int from, int to, int load_addr )
6.15 +void sh4_disasm_region( const gchar *filename, int from, int to )
6.16 {
6.17 int pc;
6.18 char buf[80];
6.19 char opcode[16];
6.20 + FILE *f;
6.21
6.22 + f = fopen( filename, "w" );
6.23 for( pc = from; pc < to; pc+=2 ) {
6.24 buf[0] = '\0';
6.25 sh4_disasm_instruction( pc,
6.26 buf, sizeof(buf), opcode );
6.27 - fprintf( f, " %08x: %s %s\n", pc + load_addr, opcode, buf );
6.28 + fprintf( f, " %08x: %s %s\n", pc, opcode, buf );
6.29 }
6.30 + fclose(f);
6.31 }
7.1 --- a/src/sh4/sh4dasm.h Thu Dec 29 12:52:29 2005 +0000
7.2 +++ b/src/sh4/sh4dasm.h Sun Jan 01 08:08:40 2006 +0000
7.3 @@ -1,5 +1,5 @@
7.4 /**
7.5 - * $Id: sh4dasm.h,v 1.5 2005-12-25 05:57:00 nkeynes Exp $
7.6 + * $Id: sh4dasm.h,v 1.6 2006-01-01 08:08:40 nkeynes Exp $
7.7 *
7.8 * SH4 CPU definition and disassembly function declarations
7.9 *
7.10 @@ -28,7 +28,7 @@
7.11 #include <stdio.h>
7.12
7.13 uint32_t sh4_disasm_instruction( uint32_t pc, char *buf, int len, char * );
7.14 -void sh4_disasm_region( FILE *f, int from, int to, int load_addr );
7.15 +void sh4_disasm_region( const gchar *filename, int from, int to );
7.16
7.17 extern const struct cpu_desc_struct sh4_cpu_desc;
7.18
8.1 --- a/src/sh4/sh4mmio.c Thu Dec 29 12:52:29 2005 +0000
8.2 +++ b/src/sh4/sh4mmio.c Sun Jan 01 08:08:40 2006 +0000
8.3 @@ -1,5 +1,5 @@
8.4 /**
8.5 - * $Id: sh4mmio.c,v 1.6 2005-12-26 03:54:55 nkeynes Exp $
8.6 + * $Id: sh4mmio.c,v 1.7 2006-01-01 08:08:40 nkeynes Exp $
8.7 *
8.8 * Miscellaneous and not-really-implemented SH4 peripheral modules. Also
8.9 * responsible for including the IMPL side of the SH4 MMIO pages.
8.10 @@ -156,12 +156,6 @@
8.11 MMIO_REGION_STUBFNS( UBC )
8.12
8.13
8.14 -/********************************* DMAC *************************************/
8.15 -
8.16 -MMIO_REGION_STUBFNS( DMAC )
8.17 -
8.18 -
8.19 -
8.20 /********************************** SCI *************************************/
8.21
8.22 MMIO_REGION_STUBFNS( SCI )
.