Update of /cvsroot/arcem/arcem/riscos-single
In directory vz-cvs-4.sog:/tmp/cvs-serv17456/build/riscos-single
Modified Files:
Code,ffb ControlPane.c DispKbd.c filecalls.c
Added Files:
filecalls_internal.h prof.s realmain.s sound.c soundbuf.s
Log Message:
Merge arcem-fast to trunk
--- NEW FILE: soundbuf.s ---
@
@ riscos-single/soundbuf.s
@
@ (c) 2011 Jeffrey Lee <[email protected]>
@
@ Basic SharedSound sound driver for ArcEm, based in part on my SharedSound
@ tutorial from http://www.iconbar.com/forums/viewthread.php?threadid=10778
@
@ This code handles filling the SharedSound buffer from the contents of the
@ buffer in ArcEm's RISC OS frontend (riscos-single/sound.c).
@
@ At the moment only basic sample rate conversion is applied - no linear
@ interpolation or anything like that.
@
.set X_Bit, 0x20000
.set XSharedSound_RemoveHandler, 0x04B441 + X_Bit
.text
.global buffer_fill
.global error_handler
routine_params:
.word sound_buffer @ R0
.word sound_buffer_in @ R3
buffer_out_ptr:
.word sound_buffer_out @ R4
.word sound_rate @ R5
.word sound_buff_mask @ R6
frac_step:
.word 0 @ R7, current fractional step
sound_handler_id_ptr:
.word sound_handler_id
buffer_fill:
@ R0 = our parameter (unused)
@ R1 = buffer base
@ R2 = buffer end
@ R3 = flags (ignored)
@ R4 = Sample frequency (ignored)
@ R5 = Sample period (ignored)
@ R6 = Fractional step (ignored)
@ R7 = LR volume (ignored)
@ R8 = Pointer to fill code (ignored)
#if 0
@ First, check if we need to clear the buffer or add to it
TST R3,#1
ORR R3,R3,#1
STMFD R13!,{R0-R10,R14}
BNE nozeros
MOV R9,#0
MOV R10,R1
zeroloop:
STR R9,[R10],#4
CMP R10,R2
BLT zeroloop
nozeros:
@ Get our params
ADR R0,routine_params
LDMIA R0,{R0,R3-R7}
LDR R3,[R3]
LDR R4,[R4]
LDR R5,[R5]
LDR R6,[R6]
@ Loop and fill
SUBS R3,R3,R4 @ Number of samples available
BLE endloop @ No more input data
mainloop:
AND R8,R4,R6 @ Pos to read from
LDR R10,[R1] @ dest data
LDR R9,[R0,R8,LSL #1] @ Get input pair
ADD R10,R10,R9 @ Mix in (no overflow checks!)
STR R10,[R1],#4
ADD R7,R7,R5 @ Increment fraction accumulator
MOV R10,R7,LSR #24 @ Get any whole movements
BIC R7,R7,#0xFF000000 @ Get rid of whole part
ADD R4,R4,R10,LSL #1 @ Increment out pos
@ Check for buffer ends
SUBS R3,R3,R10,LSL #1
BLE endloop
CMP R1,R2
BLT mainloop
endloop:
@ Store back updated values
LDR R3,buffer_out_ptr
STR R7,frac_step
STR R4,[R3]
LDMFD R13!,{R0-R10,PC}
#else
@ New version for the new sound mixer
@ sound_rate just acts as a pause flag, since the data should be at the
correct rate already
TST R3,#1
ORR R3,R3,#1
STMFD R13!,{R0-R8,R14}
MOVEQ R14,#0 @ R14 becomes mix flag
@ Get our params
ADR R0,routine_params
LDMIA R0,{R0,R3-R6}
LDR R3,[R3]
LDR R4,[R4]
LDR R5,[R5]
LDR R6,[R6]
CMP R3,#0
BEQ nodata
SUBS R3,R3,R4 @ Number of samples available
BLE nodata @ No more input data
CMP R14,#0
BEQ copyloop
mixloop:
AND R8,R4,R6 @ Pos to read from
LDR R14,[R1] @ dest data
ADD R4,R4,#4 @ Increment out pos
LDR R7,[R0,R8,LSL #1] @ Get input pair
SUBS R3,R3,#2
ADD R14,R14,R7 @ Mix in (no overflow checks!)
STR R14,[R1],#2
@ Check for buffer ends
BLE mix_done
CMP R1,R2
BLT mixloop
mix_done:
@ Store back updated values
LDR R3,buffer_out_ptr
STR R4,[R3]
LDMFD R13!,{R0-R8,PC}
copyloop:
AND R8,R4,R6 @ Pos to read from
LDR R9,[R0,R8,LSL #1] @ Get input pair
ADD R4,R4,#2 @ Increment out pos
STR R9,[R1],#4
@ Check for buffer ends
SUBS R3,R3,#2
BLE zeroloop
CMP R1,R2
BLT copyloop
@ Store back updated values
LDR R3,buffer_out_ptr
STR R4,[R3]
LDMFD R13!,{R0-R8,PC}
nodata:
CMP R14,#0
LDMNEFD R13!,{R0-R8,PC} @ No source data, and mixing in, therefore no
work to do
@ Else must fill buffer with zeros
MOV R3,#0 @ Note: Alternate entry points should have R3 as zero already
zeroloop:
CMP R1,R2
STRLT R3,[R1],#4
BLT zeroloop
@ Store back updated values
LDR R3,buffer_out_ptr
STR R4,[R3]
LDMFD R13!,{R0-R8,PC}
#endif
error_handler:
STMFD R13!,{R0-R2,R14}
MRS R2,CPSR
@ Check if sound handler installed, remove
LDR R1,sound_handler_id_ptr
LDR R0,[R1]
CMP R0,#0
SWINE XSharedSound_RemoveHandler
MOV R0,#0
STR R0,[R1]
MSR CPSR_f,R2
LDMFD R13!,{R0-R2,PC}
Index: filecalls.c
===================================================================
RCS file: /cvsroot/arcem/arcem/riscos-single/filecalls.c,v
retrieving revision 1.1
retrieving revision 1.3
diff -u -d -r1.1 -r1.3
--- filecalls.c 25 Feb 2006 00:02:31 -0000 1.1
+++ filecalls.c 12 May 2012 17:34:51 -0000 1.3
@@ -0,0 +1,117 @@
+/* filecalls.c posix implimentatation of the abstracted interface to accesing
host
+ OS file and Directory functions.
+ Copyright (c) 2005 Peter Howkins, covered under the GNU GPL see file
COPYING for more
+ details */
+/* ansi includes */
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+/* posix includes */
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+/* application includes */
+#include "filecalls.h"
+
+/**
+ * Directory_Open
+ *
+ * Open a directory so that it's contents can be scanned
+ *
+ * @param sPath Location of directory to scan
+ * @param hDir Pointer to a Directory struct to fill in
+ * @returns true on success false on failure
+ */
+bool Directory_Open(const char *sPath, Directory *hDirectory)
+{
+ assert(sPath);
+ assert(*sPath);
+ assert(hDirectory);
+
+ hDirectory->hDir = opendir(sPath);
+
+ if(NULL == hDirectory->hDir) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+/**
+ * Directory_Close
+ *
+ * Close a previously opened Directory
+ *
+ * @param hDirectory Directory to close
+ */
+void Directory_Close(Directory hDirectory)
+{
+ closedir(hDirectory.hDir);
+}
+
+/**
+ * Directory_GetNextEntry
+ *
+ * Get the next entry in a directory
+ *
+ * @param hDirectory pointer to Directory to get entry from
+ * @returns String of filename or NULL on EndOfDirectory
+ */
+char *Directory_GetNextEntry(Directory *hDirectory)
+{
+ struct dirent *phDirEntry;
+
+ assert(hDirectory);
+
+ phDirEntry = readdir(hDirectory->hDir);
+ if(phDirEntry) {
+ return phDirEntry->d_name;
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ * File_GetInfo
+ *
+ * Fills in lots of useful info about the passed in file
+ *
+ * @param sPath Path to file to check
+ * @param phFileInfo pointer to FileInfo struct to fill in
+ * @returns false on failure true on success
+ */
+bool File_GetInfo(const char *sPath, FileInfo *phFileInfo)
+{
+ struct stat hEntryInfo;
+
+ assert(sPath);
+ assert(phFileInfo);
+
+ if (stat(sPath, &hEntryInfo) != 0) {
+ fprintf(stderr, "Warning: could not stat() entry \'%s\': %s\n",
+ sPath, strerror(errno));
+ return false;
+ }
+
+ /* Initialise components */
+ phFileInfo->bIsRegularFile = false;
+ phFileInfo->bIsDirectory = false;
+
+ if (S_ISREG(hEntryInfo.st_mode)) {
+ phFileInfo->bIsRegularFile = true;
+ }
+
+ if (S_ISDIR(hEntryInfo.st_mode)) {
+ phFileInfo->bIsDirectory = true;
+ }
+
+ /* Fill in Size */
+ phFileInfo->ulFilesize = hEntryInfo.st_size;
+
+ /* Success! */
+ return true;
+}
+
Index: Code,ffb
===================================================================
RCS file: /cvsroot/arcem/arcem/riscos-single/Code,ffb,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -d -r1.1.1.1 -r1.3
Binary files /tmp/cvsa8aEhH and /tmp/cvsinMeHc differ
--- NEW FILE: sound.c ---
/*
riscos-single/sound.c
(c) 2011 Jeffrey Lee <[email protected]>
Basic SharedSound sound driver for ArcEm, based in part on my SharedSound
tutorial from http://www.iconbar.com/forums/viewthread.php?threadid=10778
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/soundcard.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <pthread.h>
#include <time.h>
#include "../armdefs.h"
#include "../arch/sound.h"
#include "../arch/archio.h"
#include "../arch/displaydev.h"
#include "kernel.h"
#include "swis.h"
/* SharedSound SWI numbers */
#define SharedSound_InstallHandler 0x4B440
#define SharedSound_SampleRate 0x4B446
#define SharedSound_RemoveHandler 0x4B441
int sound_handler_id=0; /* ID of our sound handler (0 if uninstalled) */
#define BUFFER_SAMPLES (32768) /* 16K stereo pairs */
SoundData sound_buffer[BUFFER_SAMPLES];
volatile int sound_buffer_in=BUFFER_SAMPLES; /* Number of samples we've placed
in the buffer */
volatile int sound_buffer_out=0; /* Number of samples read out by the IRQ
routine */
int sound_buff_mask=BUFFER_SAMPLES-1; /* For benefit of assembler code */
int sound_rate = 1<<24; /* Fixed output rate! */
static int buffer_threshold; /* Threshold value used to control desired buffer
level; chosen based around the output sample rate & buffer_seconds */
static float buffer_seconds = 0.2f; /* How much audio we want to try and keep
buffered */
extern void buffer_fill(void); /* Assembler function for performing the buffer
fills */
extern void error_handler(void); /* Assembler function attached to ErrorV */
static void shutdown_sharedsound(void);
extern void __write_backtrace(int signo);
static void sigfunc(int sig)
{
shutdown_sharedsound();
#if 0
/* Dump some emulator state */
ARMul_State *state = &statestr;
fprintf(stderr, "r0 = %08x r4 = %08x r8 = %08x r12 = %08x\n"
"r1 = %08x r5 = %08x r9 = %08x sp = %08x\n"
"r2 = %08x r6 = %08x r10 = %08x lr = %08x\n"
"r3 = %08x r7 = %08x r11 = %08x pc = %08x\n"
"\n",
state->Reg[0], state->Reg[4], state->Reg[8], state->Reg[12],
state->Reg[1], state->Reg[5], state->Reg[9], state->Reg[13],
state->Reg[2], state->Reg[6], state->Reg[10], state->Reg[14],
state->Reg[3], state->Reg[7], state->Reg[11], state->Reg[15]);
int i;
for(i=0;i<4;i++)
fprintf(stderr,"Timer%d Count %08x Latch
%08x\n",i,ioc.TimerCount[i],ioc.TimerInputLatch[i]);
FILE *f = fopen("$.dump","wb");
if(f)
{
for(i=0;i<1024*1024;i+=4)
{
ARMword word = ARMul_LoadWordS(state,i);
if(state->abortSig)
break;
fwrite(&word,4,1,f);
}
fclose(f);
}
#endif
/* Now dump a backtrace of ourself */
__write_backtrace(sig);
exit(0);
}
static int init_sharedsound(void)
{
/* Try to register sharedsound handler, return nonzero on failure */
_kernel_swi_regs regs;
_kernel_oserror *err;
/* First load SharedSound if it isn't already loaded
A *command is the easiest way to do this (usually in your programs
!Run file, but this demo doesn't have one) */
system("RMEnsure SharedSound 0.00 IfThere System:Modules.SSound Then
RMLoad System:Modules.SSound");
/* Now check whether it is loaded, so we can print a more friendly
error message than 'SWI xxx not found' */
regs.r[0] = 18;
regs.r[1] = (int) "SharedSound";
if ((err = _kernel_swi(OS_Module,®s,®s)))
{
fprintf(stderr,"Warning: SharedSound module not loaded, and not
in System:Modules!\n");
return 0;
}
/* Now we can register our handler */
regs.r[0] = (int) buffer_fill;
regs.r[1] = 0;
regs.r[2] = 1;
regs.r[3] = (int) "ArcEm";
regs.r[4] = 0;
if ((err = _kernel_swi(SharedSound_InstallHandler,®s,®s)))
{
fprintf(stderr,"Warning: SharedSound_InstallHandler returned
error %d, %s\n",err->errnum,err->errmess);
return 0;
}
sound_handler_id = regs.r[0];
/* Install error handlers so we don't crash on exit */
atexit(shutdown_sharedsound);
#ifdef __TARGET_UNIXLIB__
/* With UnixLib we need to use signal handlers to catch any errors.
UnixLib doesn't make it very easy to get user code to run when
something bad happens :( */
signal(SIGHUP,sigfunc);
signal(SIGINT,sigfunc);
signal(SIGQUIT,sigfunc);
signal(SIGILL,sigfunc);
signal(SIGABRT,sigfunc);
signal(SIGTRAP,sigfunc);
signal(SIGEMT,sigfunc);
signal(SIGFPE,sigfunc);
signal(SIGKILL,sigfunc);
signal(SIGBUS,sigfunc);
signal(SIGSEGV,sigfunc);
signal(SIGSYS,sigfunc);
signal(SIGPIPE,sigfunc);
signal(SIGALRM,sigfunc);
signal(SIGTERM,sigfunc);
signal(SIGSTOP,sigfunc);
signal(SIGTSTP,sigfunc);
signal(SIGTTIN,sigfunc);
signal(SIGTTOU,sigfunc);
signal(SIGOSERROR,sigfunc);
#else
/* With SCL a simple error handler seems to do the trick */
regs.r[0] = 1;
regs.r[1] = (int) error_handler;
regs.r[2] = 0;
_kernel_swi(OS_Claim,®s,®s);
#endif
/* Get our sample rate */
_swix(SharedSound_SampleRate,_INR(0,1)|_OUT(1),sound_handler_id,0,&Sound_HostRate);
/* Calculate the buffer threshold value
This is the low threshold value, so we divide by 512 to get the
desired level, then by two again to get the low level */
buffer_threshold = ((int)(buffer_seconds*((float)Sound_HostRate)))>>10;
/* Low thresholds may cause issues */
if(buffer_threshold<Sound_BatchSize*4)
buffer_threshold = Sound_BatchSize*4;
/* Big thresholds will cause problems too! */
if(buffer_threshold*4 > BUFFER_SAMPLES)
buffer_threshold = BUFFER_SAMPLES>>2;
fprintf(stderr,"Host audio rate %dHz, using buffer threshold
%d\n",Sound_HostRate>>10,buffer_threshold);
return 0;
}
static void shutdown_sharedsound(void)
{
_kernel_swi_regs regs;
/* Deregister sharedsound handler */
if(sound_handler_id)
{
regs.r[0] = sound_handler_id;
_kernel_swi(SharedSound_RemoveHandler,®s,®s);
sound_handler_id = 0;
}
/* Remove error handler */
regs.r[0] = 1;
regs.r[1] = (int) error_handler;
regs.r[2] = 0;
_kernel_swi(OS_Release,®s,®s);
}
int Sound_InitHost(ARMul_State *state)
{
/* We want the right channel first */
eSound_StereoSense = Stereo_RightLeft;
/* Use a decent batch size */
Sound_BatchSize = 256;
/* Default 20833Hz sample rate if no SharedSound? */
Sound_HostRate = (1000000<<10)/48;
#ifndef PROFILE_ENABLED
if (init_sharedsound())
{
fprintf(stderr,"Error: Couldn't register sound handler\n");
return -1;
}
#endif
return 0;
}
SoundData *Sound_GetHostBuffer(int32_t *destavail)
{
/* Work out how much space is available until next wrap point, or we start
overwriting data */
if(!sound_handler_id)
{
*destavail = BUFFER_SAMPLES>>1;
return sound_buffer;
}
int used = sound_buffer_in-sound_buffer_out;
int ofs = sound_buffer_in & sound_buff_mask;
int buffree = BUFFER_SAMPLES-MAX(ofs,used);
*destavail = buffree>>1;
return sound_buffer + ofs;
}
void Sound_HostBuffered(SoundData *buffer,int32_t numSamples)
{
if(!sound_handler_id)
return;
int used = sound_buffer_in-sound_buffer_out;
int buffree = BUFFER_SAMPLES-used;
numSamples <<= 1;
sound_buffer_in += numSamples;
if(buffree == numSamples)
{
fprintf(stderr,"*** sound overflow! ***\n");
if(Sound_FudgeRate < -10)
Sound_FudgeRate = Sound_FudgeRate/2;
else
Sound_FudgeRate+=10;
}
else if(!used)
{
fprintf(stderr,"*** sound underflow! ***\n");
if(Sound_FudgeRate > 10)
Sound_FudgeRate = Sound_FudgeRate/2;
else
Sound_FudgeRate-=10;
}
else if(used < buffer_threshold)
{
Sound_FudgeRate-=3;
}
else if(used < buffer_threshold*3)
{
Sound_FudgeRate+=3;
}
else if(Sound_FudgeRate)
{
/* Bring the fudge value back towards 0 until we go out of the comfort zone
*/
Sound_FudgeRate += (Sound_FudgeRate>0?-1:1);
}
}
--- NEW FILE: realmain.s ---
@
@ riscos-single/realmain.s
@
@ (c) 2011 Jeffrey Lee <[email protected]>
@
@ Part of Arcem released under the GNU GPL, see file COPYING
@ for details.
@
@ Simple wrapper for main() that creates one large stack frame for us to use.
@ This allows us to skip performing stack extension checks in the main code.
@
@ 256K should be far more than enough
#define STACK_SIZE (256*1024)
.text
.global main
main:
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
sub ip, sp, #STACK_SIZE
bl __rt_stkovf_split_big
bl fakemain
ldmea fp, {fp, sp, pc}
--- NEW FILE: filecalls_internal.h ---
/* filecalls_internal.h
Copyright (c) 2005 Peter Howkins, covered under the GNU GPL see file COPYING
for more
details */
#ifndef __FILECALLS_INTERNAL_H
#define __FILECALLS_INTERNAL_H
#include <sys/types.h>
#include <dirent.h>
struct Directory_s {
DIR *hDir;
};
#define ARCEM_PATH_MAX PATH_MAX
#endif /* __FILECALLS_H */
Index: DispKbd.c
===================================================================
RCS file: /cvsroot/arcem/arcem/riscos-single/DispKbd.c,v
retrieving revision 1.9
retrieving revision 1.11
diff -u -d -r1.9 -r1.11
--- DispKbd.c 10 Mar 2006 18:27:56 -0000 1.9
+++ DispKbd.c 12 May 2012 17:34:51 -0000 1.11
@@ -1,20 +1,12 @@
-/* (c) David Alan Gilbert 1995-1999 - see Readme file for copying info */
+/* (c) David Alan Gilbert 1995-1999 - see Readme file for copying info
+ Hacked about with for new display driver interface by Jeffrey Lee, 2011 */
/* Display and keyboard interface for the Arc emulator */
-// #define MOUSEKEY XK_KP_Add
-
-#define KEYREENABLEDELAY 1000
-
-/*#define DEBUG_VIDCREGS*/
-/* NOTE: Can't use ARMul's refresh function because it has a small
[...1739 lines suppressed...]
+ if(hArcemConfig.eDisplayDriver == DisplayDriver_Standard)
+ DisplayDev_UseUpdateFlags = 1;
+ /* Rebuild fastmap for DisplayDev_UseUpdateFlags changes */
+ ARMul_RebuildFastMap();
+ /* Gobble any keyboard input */
+ while(_swi (ArcEmKey_GetKey, _RETURN(0))) {};
+ /* Reset EmuRate */
+ EmuRate_Reset(&statestr);
+#ifdef PROFILE_ENABLED
+ if(enable_profile)
+ {
+ /* Start profiling */
+ Prof_Reset();
+ }
+ Prof_BeginFunc(Keyboard_Poll);
#endif
}
-
-
+#endif
Index: ControlPane.c
===================================================================
RCS file: /cvsroot/arcem/arcem/riscos-single/ControlPane.c,v
retrieving revision 1.3
retrieving revision 1.5
diff -u -d -r1.3 -r1.5
--- ControlPane.c 9 May 2003 10:54:56 -0000 1.3
+++ ControlPane.c 12 May 2012 17:34:51 -0000 1.5
@@ -5,7 +5,6 @@
#include "../armdefs.h"
#include "archio.h"
#include "armarc.h"
-#include "DispKbd.h"
#include "ControlPane.h"
void ControlPane_Init(ARMul_State *state)
--- NEW FILE: prof.s ---
@
@ prof.s
@
@ (c) 2011 Jeffrey Lee <[email protected]>
@
@ Part of Arcem released under the GNU GPL, see file COPYING
@ for details.
@
@ Very nasty CPU profiling code for RISC OS hosts running on Iyonix or
@ Cortex-A8 machines. This code relies upon the following:
@
@ * Function name poking (-mpoke-function-names) being enabled
@ * 'cortex' #define being set correctly for whether IOP321 or Cortex-A8 code
@ should be used
@ * On IOP321, HAL timer 1 must be free. This also means the results will be in
@ 200MHz clock ticks instead of CPU cycles.
@ * On Cortex-A8, the cycle count performance counter must be free
@ * C heap allocations must come from application space, not a dynamic area (a
@ simple malloc is used to estimate how large the program is by looking at the
@ allocation address). This requirement is currently enforced by
@ riscos-single/DispKbd.c
@
.text
prof_buffer_ptr:
.word 0
prof_buffer_size:
.word 0
prof_buffer_offset:
.word 0
prof_fmt_str:
.ascii "%s,%u,%u\012\000"
.align 2
#define OS_EnterOS 0x16
#define OS_LeaveOS 0x7c
#define OS_Hardware 0x7a
//#define cortex
#ifdef cortex
#define read_timer(out) mrc p15, 0, out, c9, c13, 0 @ counts up
#else
#define read_timer(out) mrc p6, 0, out, c3, c1, 0 @ counts down!
#endif
.global Prof_Init
.global Prof_BeginFunc
.global Prof_Begin
.global Prof_EndFunc
.global Prof_End
.global Prof_Dump
.global Prof_Reset
Prof_Init:
mov ip, sp
stmfd sp!, {v5-v6, fp, ip, lr, pc}
sub fp, ip, #4
mov a1, #4
bl malloc
sub v5, a1, #0x8000
str v5, prof_buffer_size
bl free
mov a1, v5
bl malloc
str a1, prof_buffer_ptr
sub a2, a1, #0x8000
str a2, prof_buffer_offset
mov a2, #0
mov a3, v5
bl memset
#ifdef cortex
@ configure cycle count performance counter
swi OS_EnterOS
mov a1, #1
mcr p15, 0, a1, c9, c14, 0 @ enable user access to perf counters
mvn a1, #0
mcr p15, 0, a1, c9, c12, 2 @ disable counters
mcr p15, 0, a1, c9, c14, 2 @ disable interrupts
mov a1, #0x80000000
mcr p15, 0, a1, c9, c12, 1 @ enable cycle count
mov a1, #7
mcr p15, 0, a1, c9, c12, 0 @ enable & reset
swi OS_LeaveOS
#else
@ No user-mode access to performance counters on XScale, so user timer
@ 1 instead
@ Configure it via HAL calls for simplicity
mov v5, #0
mov a1, #1
mov v6, #13
swi OS_Hardware @ get IRQ
mov v6, #2
swi OS_Hardware @ disable IRQ
mov a1, #1
mvn a2, #0
mov v6, #16
swi OS_Hardware @ set period to max, enables timer
#endif
ldmea fp, {v5-v6, fp, sp, pc}
Prof_Reset:
ldr a1, prof_buffer_ptr
mov a2, #0
ldr a3, prof_buffer_size
b memset
Prof_BeginFunc:
@ a1 = name-poked func ptr
ldrb a2, [a1, #-4]!
sub a1, a1, a2
Prof_Begin:
@ a1 = word-aligned const string ptr, must be >= 8 bytes!
ldr a3, prof_buffer_offset
read_timer(a2)
ldr a4, [a1, a3]!
#ifdef cortex
sub a4, a4, a2 @ sub start time, add finish time
#else
add a4, a4, a2 @ add start countdown, sub finish countdown
#endif
str a4, [a1]
mov pc, lr
Prof_EndFunc:
@ a1 = name-poked func ptr
ldrb a2, [a1, #-4]!
sub a1, a1, a2
Prof_End:
@ a1 = word-aligned const string ptr, must be >= 8 bytes!
ldr a3, prof_buffer_offset
read_timer(a2)
add a1, a1, a3
ldmia a1, {a3,a4}
#ifdef cortex
add a3, a3, a2
#else
sub a3, a3, a2
#endif
add a4, a4, #1
stmia a1, {a3,a4}
mov pc, lr
Prof_Dump:
mov ip, sp
stmfd sp!, {a1,v1-v3,fp,ip,lr,pc}
sub fp, ip, #4
sub sp, sp, #4
ldr v1, prof_buffer_ptr
ldr v2, prof_buffer_size
ldr v3, prof_buffer_offset
add v2, v1, v2
add v3, v3, #8
.loop:
ldr a4, [v1], #4
cmp a4, #0
beq .skip
ldr ip, [v1], #4
str ip, [sp]
sub a3, v1, v3
adr a2, prof_fmt_str
ldr a1, [sp, #4]
bl fprintf
.skip:
cmp v1, v2
blo .loop
ldmea fp, {v1-v3,fp,sp,pc}
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
--
arcem-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/arcem-cvs