revision 54:d8b73031289c
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 54:d8b73031289c |
parent | 53:f2981805b929 |
child | 55:96323c198da3 |
author | nkeynes |
date | Sun Jan 01 08:08:40 2006 +0000 (18 years ago) |
Add (partial) DMAC implementation
src/Makefile.am | view | annotate | diff | log | ||
src/Makefile.in | view | annotate | diff | log | ||
src/sh4/dmac.c | view | annotate | diff | log | ||
src/sh4/scif.c | view | annotate | diff | log | ||
src/sh4/sh4core.h | view | annotate | diff | log | ||
src/sh4/sh4dasm.c | view | annotate | diff | log | ||
src/sh4/sh4dasm.h | view | annotate | diff | log | ||
src/sh4/sh4mmio.c | view | annotate | diff | log |
1.1 --- a/src/Makefile.am Thu Dec 29 12:52:29 2005 +00001.2 +++ b/src/Makefile.am Sun Jan 01 08:08:40 2006 +00001.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 +00002.2 +++ b/src/Makefile.in Sun Jan 01 08:08:40 2006 +00002.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.Po2.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.Po2.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.77 +dmac.o: sh4/dmac.c2.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@ fi2.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.c2.87 +2.88 +dmac.obj: sh4/dmac.c2.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@ fi2.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.c2.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 +00003.2 +++ b/src/sh4/dmac.c Sun Jan 01 08:08:40 2006 +00003.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 modify3.12 + * it under the terms of the GNU General Public License as published by3.13 + * the Free Software Foundation; either version 2 of the License, or3.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 of3.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the3.19 + * GNU General Public License for more details.3.20 + */3.21 +#define MODULE sh4_module3.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 0x003.51 +#define DMARES_MEMORY_TO_DEVICE 0x023.52 +#define DMARES_DEVICE_TO_MEMORY 0x033.53 +#define DMARES_MEMORY_TO_MEMORY_AUTO 0x043.54 +#define DMARES_MEMORY_TO_PERIPH_AUTO 0x053.55 +#define DMARES_PERIPH_TO_MEMORY_AUTO 0x063.56 +#define DMARES_SCI_TRANSMIT_EMPTY 0x083.57 +#define DMARES_SCI_RECEIVE_FULL 0x093.58 +#define DMARES_SCIF_TRANSMIT_EMPTY 0x0A3.59 +#define DMARES_SCIF_RECEIVE_FULL 0x0B3.60 +#define DMARES_MEMORY_TO_MEMORY_TMU 0x0C3.61 +#define DMARES_MEMORY_TO_PERIPH_TMU 0x0D3.62 +#define DMARES_PERIPH_TO_MEMORY_TMU 0x0E3.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 to3.84 + * run the channel3.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 the3.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 the3.114 + * end of the transfer count.3.115 + * @return actual number of transfers run3.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 the3.168 + * ASIC). The DMA channel must be configured for Mem=>dev or it will return3.169 + * no bytes and whinge mightily. Note this is NOT used for SH4 peripheral3.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 +00004.2 +++ b/src/sh4/scif.c Sun Jan 01 08:08:40 2006 +00004.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 the4.8 * SH4 standard on-chip peripheral set. The SCIF is hooked up to the DCs4.9 * external serial port4.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.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.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 +00005.2 +++ b/src/sh4/sh4core.h Sun Jan 01 08:08:40 2006 +00005.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, except5.9 - * for disassembly functions defined in sh4dasm.h5.10 + * This file defines the internal functions exported/used by the SH4 core,5.11 + * except for disassembly functions defined in sh4dasm.h5.12 *5.13 * Copyright (c) 2005 Nathan Keynes.5.14 *5.15 @@ -53,7 +53,6 @@5.16 */5.17 #define SH4_STATE_STANDBY 45.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.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 +00006.2 +++ b/src/sh4/sh4dasm.c Sun Jan 01 08:08:40 2006 +00006.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 functions6.9 *6.10 @@ -380,16 +380,19 @@6.11 }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.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 +00007.2 +++ b/src/sh4/sh4dasm.h Sun Jan 01 08:08:40 2006 +00007.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 declarations7.9 *7.10 @@ -28,7 +28,7 @@7.11 #include <stdio.h>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.17 extern const struct cpu_desc_struct sh4_cpu_desc;
8.1 --- a/src/sh4/sh4mmio.c Thu Dec 29 12:52:29 2005 +00008.2 +++ b/src/sh4/sh4mmio.c Sun Jan 01 08:08:40 2006 +00008.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. Also8.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.14 -/********************************* DMAC *************************************/8.15 -8.16 -MMIO_REGION_STUBFNS( DMAC )8.17 -8.18 -8.19 -8.20 /********************************** SCI *************************************/8.22 MMIO_REGION_STUBFNS( SCI )
.