Search
lxdream.org :: lxdream/src/sh4/sh4.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4.c
changeset 617:476a717a54f3
prev597:87cbdf62aa35
next619:0800a0137472
author nkeynes
date Tue Jan 29 10:39:56 2008 +0000 (14 years ago)
permissions -rw-r--r--
last change Start getting SLEEP into order
file annotate diff log raw
1.1 --- a/src/sh4/sh4.c Tue Jan 22 09:45:21 2008 +0000
1.2 +++ b/src/sh4/sh4.c Tue Jan 29 10:39:56 2008 +0000
1.3 @@ -19,6 +19,7 @@
1.4
1.5 #define MODULE sh4_module
1.6 #include <math.h>
1.7 +#include <assert.h>
1.8 #include "dream.h"
1.9 #include "dreamcast.h"
1.10 #include "sh4/sh4core.h"
1.11 @@ -26,6 +27,7 @@
1.12 #include "sh4/intc.h"
1.13 #include "sh4/xltcache.h"
1.14 #include "sh4/sh4stat.h"
1.15 +#include "sh4/sh4trans.h"
1.16 #include "mem.h"
1.17 #include "clock.h"
1.18 #include "syscall.h"
1.19 @@ -332,16 +334,80 @@
1.20 *fr = sinf(angle);
1.21 }
1.22
1.23 +/**
1.24 + * Enter sleep mode (eg by executing a SLEEP instruction).
1.25 + * Sets sh4_state appropriately and ensures any stopping peripheral modules
1.26 + * are up to date.
1.27 + */
1.28 void sh4_sleep(void)
1.29 {
1.30 if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
1.31 sh4r.sh4_state = SH4_STATE_STANDBY;
1.32 + /* Bring all running peripheral modules up to date, and then halt them. */
1.33 + TMU_run_slice( sh4r.slice_cycle );
1.34 + SCIF_run_slice( sh4r.slice_cycle );
1.35 } else {
1.36 - sh4r.sh4_state = SH4_STATE_SLEEP;
1.37 + if( MMIO_READ( CPG, STBCR2 ) & 0x80 ) {
1.38 + sh4r.sh4_state = SH4_STATE_DEEP_SLEEP;
1.39 + /* Halt DMAC but other peripherals still running */
1.40 +
1.41 + } else {
1.42 + sh4r.sh4_state = SH4_STATE_SLEEP;
1.43 + }
1.44 + }
1.45 + if( sh4_xlat_is_running() ) {
1.46 + sh4_translate_exit( XLAT_EXIT_SLEEP );
1.47 }
1.48 }
1.49
1.50 /**
1.51 + * Wakeup following sleep mode (IRQ or reset). Sets state back to running,
1.52 + * and restarts any peripheral devices that were stopped.
1.53 + */
1.54 +void sh4_wakeup(void)
1.55 +{
1.56 + switch( sh4r.sh4_state ) {
1.57 + case SH4_STATE_STANDBY:
1.58 + break;
1.59 + case SH4_STATE_DEEP_SLEEP:
1.60 + break;
1.61 + case SH4_STATE_SLEEP:
1.62 + break;
1.63 + }
1.64 + sh4r.sh4_state = SH4_STATE_RUNNING;
1.65 +}
1.66 +
1.67 +/**
1.68 + * Run a time slice (or portion of a timeslice) while the SH4 is sleeping.
1.69 + * Returns when either the SH4 wakes up (interrupt received) or the end of
1.70 + * the slice is reached. Updates sh4.slice_cycle with the exit time and
1.71 + * returns the same value.
1.72 + */
1.73 +uint32_t sh4_sleep_run_slice( uint32_t nanosecs )
1.74 +{
1.75 + int sleep_state = sh4r.sh4_state;
1.76 + assert( sleep_state != SH4_STATE_RUNNING );
1.77 + while( sh4r.event_pending < nanosecs ) {
1.78 + sh4r.slice_cycle = sh4r.event_pending;
1.79 + if( sh4r.event_types & PENDING_EVENT ) {
1.80 + event_execute();
1.81 + }
1.82 + if( sh4r.event_types & PENDING_IRQ ) {
1.83 + sh4_wakeup();
1.84 + nanosecs = sh4r.event_pending;
1.85 + break;
1.86 + }
1.87 + }
1.88 + sh4r.slice_cycle = nanosecs;
1.89 + if( sleep_state != SH4_STATE_STANDBY ) {
1.90 + TMU_run_slice( nanosecs );
1.91 + SCIF_run_slice( nanosecs );
1.92 + }
1.93 + return sh4r.slice_cycle;
1.94 +}
1.95 +
1.96 +
1.97 +/**
1.98 * Compute the matrix tranform of fv given the matrix xf.
1.99 * Both fv and xf are word-swapped as per the sh4r.fr banks
1.100 */
.