diff -ru dosbox-0.71.orig/config.sub dosbox-0.71/config.sub
--- dosbox-0.71.orig/config.sub	2007-07-30 03:28:31.000000000 -0500
+++ dosbox-0.71/config.sub	2005-12-14 22:26:30.875000000 -0600
@@ -1,10 +1,9 @@
 #! /bin/sh
 # Configuration validation subroutine script.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-#   Inc.
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
-timestamp='2006-07-02'
+timestamp='2003-02-22'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -22,15 +21,14 @@
 #
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
 # configuration script generated by Autoconf, you may include it under
 # the same distribution terms that you use for the rest of that program.
 
-
 # Please send patches to <config-patches@gnu.org>.  Submit a context
 # diff and a properly formatted ChangeLog entry.
 #
@@ -72,7 +70,7 @@
 version="\
 GNU config.sub ($timestamp)
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
@@ -85,11 +83,11 @@
 while test $# -gt 0 ; do
   case $1 in
     --time-stamp | --time* | -t )
-       echo "$timestamp" ; exit ;;
+       echo "$timestamp" ; exit 0 ;;
     --version | -v )
-       echo "$version" ; exit ;;
+       echo "$version" ; exit 0 ;;
     --help | --h* | -h )
-       echo "$usage"; exit ;;
+       echo "$usage"; exit 0 ;;
     -- )     # Stop option processing
        shift; break ;;
     - )	# Use stdin as input.
@@ -101,7 +99,7 @@
     *local*)
        # First pass through any local machine types.
        echo $1
-       exit ;;
+       exit 0;;
 
     * )
        break ;;
@@ -120,9 +118,7 @@
 # Here we must recognize all the valid KERNEL-OS combinations.
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
-  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
+  nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
     ;;
@@ -148,7 +144,7 @@
 	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
 	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
 	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-	-apple | -axis | -knuth | -cray)
+	-apple | -axis)
 		os=
 		basic_machine=$1
 		;;
@@ -173,10 +169,6 @@
 	-hiux*)
 		os=-hiuxwe2
 		;;
-	-sco6)
-		os=-sco5v6
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
 	-sco5)
 		os=-sco3.2v5
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -193,10 +185,6 @@
 		# Don't forget version if it is 3.2v4 or newer.
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 		;;
-	-sco5v6*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
 	-sco*)
 		os=-sco3.2v2
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -240,17 +228,14 @@
 	| a29k \
 	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
 	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-	| am33_2.0 \
-	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
-	| bfin \
-	| c4x | clipper \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| clipper \
 	| d10v | d30v | dlx | dsp16xx \
 	| fr30 | frv \
 	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 	| i370 | i860 | i960 | ia64 \
-	| ip2k | iq2000 \
-	| m32c | m32r | m32rle | m68000 | m68k | m88k \
-	| maxq | mb | microblaze | mcore \
+	| ip2k \
+	| m32r | m68000 | m68k | m88k | mcore \
 	| mips | mipsbe | mipseb | mipsel | mipsle \
 	| mips16 \
 	| mips64 | mips64el \
@@ -259,32 +244,28 @@
 	| mips64vr4100 | mips64vr4100el \
 	| mips64vr4300 | mips64vr4300el \
 	| mips64vr5000 | mips64vr5000el \
-	| mips64vr5900 | mips64vr5900el \
 	| mipsisa32 | mipsisa32el \
 	| mipsisa32r2 | mipsisa32r2el \
 	| mipsisa64 | mipsisa64el \
-	| mipsisa64r2 | mipsisa64r2el \
 	| mipsisa64sb1 | mipsisa64sb1el \
 	| mipsisa64sr71k | mipsisa64sr71kel \
 	| mipstx39 | mipstx39el \
+	| mipsallegrex | mipsallegrexel \
 	| mn10200 | mn10300 \
-	| mt \
 	| msp430 \
-	| nios | nios2 \
 	| ns16k | ns32k \
-	| or32 \
+	| openrisc | or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
 	| pyramid \
-	| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
 	| sh64 | sh64le \
-	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-	| spu | strongarm \
-	| tahoe | thumb | tic4x | tic80 | tron \
+	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic80 | tron \
 	| v850 | v850e \
 	| we32k \
-	| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| x86 | xscale | xstormy16 | xtensa \
 	| z8k)
 		basic_machine=$basic_machine-unknown
 		;;
@@ -295,9 +276,6 @@
 		;;
 	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
 		;;
-	ms1)
-		basic_machine=mt-unknown
-		;;
 
 	# We use `pc' rather than `unknown'
 	# because (1) that's what they normally are, and
@@ -317,20 +295,20 @@
 	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
 	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
 	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-	| avr-* | avr32-* \
-	| bfin-* | bs2000-* \
+	| avr-* \
+	| bs2000-* \
 	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
-	| clipper-* | craynv-* | cydra-* \
+	| clipper-* | cydra-* \
 	| d10v-* | d30v-* | dlx-* \
 	| elxsi-* \
 	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
 	| h8300-* | h8500-* \
 	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 	| i*86-* | i860-* | i960-* | ia64-* \
-	| ip2k-* | iq2000-* \
-	| m32c-* | m32r-* | m32rle-* \
+	| ip2k-* \
+	| m32r-* \
 	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| m88110-* | m88k-* | mcore-* \
 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
 	| mips16-* \
 	| mips64-* | mips64el-* \
@@ -339,36 +317,31 @@
 	| mips64vr4100-* | mips64vr4100el-* \
 	| mips64vr4300-* | mips64vr4300el-* \
 	| mips64vr5000-* | mips64vr5000el-* \
-	| mips64vr5900-* | mips64vr5900el-* \
 	| mipsisa32-* | mipsisa32el-* \
 	| mipsisa32r2-* | mipsisa32r2el-* \
 	| mipsisa64-* | mipsisa64el-* \
-	| mipsisa64r2-* | mipsisa64r2el-* \
 	| mipsisa64sb1-* | mipsisa64sb1el-* \
 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
 	| mipstx39-* | mipstx39el-* \
-	| mmix-* \
-	| mt-* \
+	| mipsallegrex-* | mipsallegrexel-* \
 	| msp430-* \
-	| nios-* | nios2-* \
-	| none-* | np1-* | ns16k-* | ns32k-* \
+	| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
 	| pyramid-* \
 	| romp-* | rs6000-* \
-	| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
 	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+	| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
 	| tahoe-* | thumb-* \
 	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
 	| tron-* \
 	| v850-* | v850e-* | vax-* \
 	| we32k-* \
-	| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
-	| xstormy16-* | xtensa-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+	| xtensa-* \
 	| ymp-* \
 	| z8k-*)
 		;;
@@ -388,9 +361,6 @@
 		basic_machine=a29k-amd
 		os=-udi
 		;;
-    	abacus)
-		basic_machine=abacus-unknown
-		;;
 	adobe68k)
 		basic_machine=m68010-adobe
 		os=-scout
@@ -405,12 +375,6 @@
 		basic_machine=a29k-none
 		os=-bsd
 		;;
-	amd64)
-		basic_machine=x86_64-pc
-		;;
-	amd64-*)
-		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
 	amdahl)
 		basic_machine=580-amdahl
 		os=-sysv
@@ -470,27 +434,12 @@
 		basic_machine=j90-cray
 		os=-unicos
 		;;
-	craynv)
-		basic_machine=craynv-cray
-		os=-unicosmp
-		;;
-	cr16c)
-		basic_machine=cr16c-unknown
-		os=-elf
-		;;
 	crds | unos)
 		basic_machine=m68k-crds
 		;;
-	crisv32 | crisv32-* | etraxfs*)
-		basic_machine=crisv32-axis
-		;;
 	cris | cris-* | etrax*)
 		basic_machine=cris-axis
 		;;
-	crx)
-		basic_machine=crx-unknown
-		os=-elf
-		;;
 	da30 | da30-*)
 		basic_machine=m68k-da30
 		;;
@@ -513,10 +462,6 @@
 		basic_machine=m88k-motorola
 		os=-sysv3
 		;;
-	djgpp)
-		basic_machine=i586-pc
-		os=-msdosdjgpp
-		;;
 	dpx20 | dpx20-*)
 		basic_machine=rs6000-bull
 		os=-bosx
@@ -695,6 +640,10 @@
 	mips3*)
 		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
 		;;
+	mmix*)
+		basic_machine=mmix-knuth
+		os=-mmixware
+		;;
 	monitor)
 		basic_machine=m68k-rom68k
 		os=-coff
@@ -707,9 +656,6 @@
 		basic_machine=i386-pc
 		os=-msdos
 		;;
-	ms1-*)
-		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
-		;;
 	mvs)
 		basic_machine=i370-ibm
 		os=-mvs
@@ -778,6 +724,10 @@
 	np1)
 		basic_machine=np1-gould
 		;;
+	nv1)
+		basic_machine=nv1-cray
+		os=-unicosmp
+		;;
 	nsr-tandem)
 		basic_machine=nsr-tandem
 		;;
@@ -785,12 +735,9 @@
 		basic_machine=hppa1.1-oki
 		os=-proelf
 		;;
-	openrisc | openrisc-*)
+	or32 | or32-*)
 		basic_machine=or32-unknown
-		;;
-	os400)
-		basic_machine=powerpc-ibm
-		os=-os400
+		os=-coff
 		;;
 	OSE68000 | ose68000)
 		basic_machine=m68000-ericsson
@@ -817,36 +764,24 @@
 	pc532 | pc532-*)
 		basic_machine=ns32k-pc532
 		;;
-	pc98)
-		basic_machine=i386-pc
-		;;
-	pc98-*)
-		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
 	pentium | p5 | k5 | k6 | nexgen | viac3)
 		basic_machine=i586-pc
 		;;
 	pentiumpro | p6 | 6x86 | athlon | athlon_*)
 		basic_machine=i686-pc
 		;;
-	pentiumii | pentium2 | pentiumiii | pentium3)
+	pentiumii | pentium2)
 		basic_machine=i686-pc
 		;;
-	pentium4)
-		basic_machine=i786-pc
-		;;
 	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
 		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
 	pentiumpro-* | p6-* | 6x86-* | athlon-*)
 		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+	pentiumii-* | pentium2-*)
 		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	pentium4-*)
-		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
 	pn)
 		basic_machine=pn-gould
 		;;
@@ -875,14 +810,14 @@
 	ps2)
 		basic_machine=i386-ibm
 		;;
+	psp)
+		basic_machine=mipsallegrexel-psp
+		os=-elf
+		;;
 	pw32)
 		basic_machine=i586-unknown
 		os=-pw32
 		;;
-	rdos)
-		basic_machine=i386-pc
-		os=-rdos
-		;;
 	rom68k)
 		basic_machine=m68k-rom68k
 		os=-coff
@@ -909,10 +844,6 @@
 	sb1el)
 		basic_machine=mipsisa64sb1el-unknown
 		;;
-	sei)
-		basic_machine=mips-sei
-		os=-seiux
-		;;
 	sequent)
 		basic_machine=i386-sequent
 		;;
@@ -920,9 +851,6 @@
 		basic_machine=sh-hitachi
 		os=-hms
 		;;
-	sh64)
-		basic_machine=sh64-unknown
-		;;
 	sparclite-wrs | simso-wrs)
 		basic_machine=sparclite-wrs
 		os=-vxworks
@@ -997,6 +925,10 @@
 		basic_machine=t90-cray
 		os=-unicos
 		;;
+        tic4x | c4x*)
+		basic_machine=tic4x-unknown
+		os=-coff
+		;;
 	tic54x | c54x*)
 		basic_machine=tic54x-unknown
 		os=-coff
@@ -1022,10 +954,6 @@
 	tower | tower-32)
 		basic_machine=m68k-ncr
 		;;
-	tpf)
-		basic_machine=s390x-ibm
-		os=-tpf
-		;;
 	udi29k)
 		basic_machine=a29k-amd
 		os=-udi
@@ -1069,10 +997,6 @@
 		basic_machine=hppa1.1-winbond
 		os=-proelf
 		;;
-	xbox)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
 	xps | xps100)
 		basic_machine=xps100-honeywell
 		;;
@@ -1103,9 +1027,6 @@
 	romp)
 		basic_machine=romp-ibm
 		;;
-	mmix)
-		basic_machine=mmix-knuth
-		;;
 	rs6000)
 		basic_machine=rs6000-ibm
 		;;
@@ -1122,10 +1043,13 @@
 	we32k)
 		basic_machine=we32k-att
 		;;
-	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
 		basic_machine=sh-unknown
 		;;
-	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv9 | sparcv9b)
 		basic_machine=sparc-sun
 		;;
 	cydra)
@@ -1198,23 +1122,19 @@
 	      | -aos* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-	      | -openbsd* | -solidbsd* \
-	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
 	      | -chorusos* | -chorusrdb* \
 	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
-	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
-	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers*)
+	      | -powermax* | -dnix*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1226,21 +1146,16 @@
 			;;
 		esac
 		;;
-	-nto-qnx*)
-		;;
 	-nto*)
-		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		os=-nto-qnx
 		;;
 	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
-	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
 	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
 		;;
 	-mac*)
 		os=`echo $os | sed -e 's|mac|macos|'`
 		;;
-	-linux-dietlibc)
-		os=-linux-dietlibc
-		;;
 	-linux*)
 		os=`echo $os | sed -e 's|linux|linux-gnu|'`
 		;;
@@ -1253,9 +1168,6 @@
 	-opened*)
 		os=-openedition
 		;;
-        -os400*)
-		os=-os400
-		;;
 	-wince*)
 		os=-wince
 		;;
@@ -1277,9 +1189,6 @@
 	-atheos*)
 		os=-atheos
 		;;
-	-syllable*)
-		os=-syllable
-		;;
 	-386bsd)
 		os=-bsd
 		;;
@@ -1302,9 +1211,6 @@
 	-sinix*)
 		os=-sysv4
 		;;
-        -tpf*)
-		os=-tpf
-		;;
 	-triton*)
 		os=-sysv3
 		;;
@@ -1341,9 +1247,6 @@
 	-kaos*)
 		os=-kaos
 		;;
-	-zvmoe)
-		os=-zvmoe
-		;;
 	-none)
 		;;
 	*)
@@ -1366,9 +1269,6 @@
 # system, and we'll never get to this point.
 
 case $basic_machine in
-        spu-*)
-		os=-elf
-		;;
 	*-acorn)
 		os=-riscix1.2
 		;;
@@ -1378,9 +1278,6 @@
 	arm*-semi)
 		os=-aout
 		;;
-        c4x-* | tic4x-*)
-        	os=-coff
-		;;
 	# This must come before the *-dec entry.
 	pdp10-*)
 		os=-tops20
@@ -1424,15 +1321,9 @@
 	*-be)
 		os=-beos
 		;;
-	*-haiku)
-		os=-haiku
-		;;
 	*-ibm)
 		os=-aix
 		;;
-    	*-knuth)
-		os=-mmixware
-		;;
 	*-wec)
 		os=-proelf
 		;;
@@ -1565,15 +1456,9 @@
 			-mvs* | -opened*)
 				vendor=ibm
 				;;
-			-os400*)
-				vendor=ibm
-				;;
 			-ptx*)
 				vendor=sequent
 				;;
-			-tpf*)
-				vendor=ibm
-				;;
 			-vxsim* | -vxworks* | -windiss*)
 				vendor=wrs
 				;;
@@ -1598,7 +1483,7 @@
 esac
 
 echo $basic_machine$os
-exit
+exit 0
 
 # Local variables:
 # eval: (add-hook 'write-file-hooks 'time-stamp)
diff -ru dosbox-0.71.orig/include/dos_system.h dosbox-0.71/include/dos_system.h
--- dosbox-0.71.orig/include/dos_system.h	2007-06-13 02:25:14.000000000 -0500
+++ dosbox-0.71/include/dos_system.h	2007-08-01 13:06:07.875000000 -0500
@@ -120,7 +120,11 @@
 /* The following variable can be lowered to free up some memory. 
  * The negative side effect: The stored searches will be turned over faster.
  * Should not have impact on systems with few directory entries. */
+#ifdef PSP
+#define MAX_OPENDIRS 128
+#else
 #define MAX_OPENDIRS 2048
+#endif
 //Can be high as it's only storage (16 bit variable)
 
 class DOS_Drive_Cache {
diff -ru dosbox-0.71.orig/include/dosbox.h dosbox-0.71/include/dosbox.h
--- dosbox-0.71.orig/include/dosbox.h	2007-01-08 12:45:37.000000000 -0600
+++ dosbox-0.71/include/dosbox.h	2007-08-19 19:38:25.171875000 -0500
@@ -21,6 +21,17 @@
 
 #include "config.h"
 
+#ifndef PSP
+#define USE_GUS 1
+#define USE_SDL 1
+#else
+//#define PSPME
+#endif
+
+// deal with unaligned memory
+typedef struct { Bit32u val __attribute__((packed)); } unaligned_word;
+typedef struct { Bit16u val __attribute__((packed)); } unaligned_half;
+
 void E_Exit(const char * message,...) GCC_ATTRIBUTE( __format__(__printf__, 1, 2));
 
 void MSG_Add(const char*,const char*); //add messages to the internal langaugefile
diff -ru dosbox-0.71.orig/include/fpu.h dosbox-0.71/include/fpu.h
--- dosbox-0.71.orig/include/fpu.h	2007-06-12 15:22:07.000000000 -0500
+++ dosbox-0.71/include/fpu.h	2007-08-01 13:06:07.875000000 -0500
@@ -40,7 +40,32 @@
 void FPU_ESC7_Normal(Bitu rm);
 void FPU_ESC7_EA(Bitu func,PhysPt ea);
 
+#ifdef PSP
+#define SINGLE_FLOAT
+#endif
 
+#ifdef SINGLE_FLOAT
+typedef union {
+	float d;
+	Bit32s l;
+} FPU_Reg;
+typedef Real32 FVAL;
+typedef union {
+    double d;
+#ifndef WORDS_BIGENDIAN
+    struct {
+        Bit32u lower;
+        Bit32s upper;
+    } l;
+#else
+    struct {
+        Bit32s upper;
+        Bit32u lower;
+    } l;
+#endif
+    Bit64s ll;
+} double_reg;
+#else
 typedef union {
     double d;
 #ifndef WORDS_BIGENDIAN
@@ -56,6 +81,8 @@
 #endif
     Bit64s ll;
 } FPU_Reg;
+typedef Real64 FVAL;
+#endif
 
 typedef struct {
     Bit32u m1;
@@ -82,7 +109,9 @@
 
 typedef struct {
 	FPU_Reg		regs[9];
+#ifdef SINGLE_FLOAT
 	FPU_P_Reg	p_regs[9];
+#endif
 	FPU_Tag		tags[9];
 	Bit16u		cw,cw_mask_all;
 	Bit16u		sw;
@@ -93,6 +122,7 @@
 
 //get pi from a real library
 #define PI		3.14159265358979323846
+#define PI_2		1.57079632679489
 #define L2E		1.4426950408889634
 #define L2T		3.3219280948873623
 #define LN2		0.69314718055994531
diff -ru dosbox-0.71.orig/include/hardware.h dosbox-0.71/include/hardware.h
--- dosbox-0.71.orig/include/hardware.h	2007-01-08 12:45:37.000000000 -0600
+++ dosbox-0.71/include/hardware.h	2007-08-12 19:56:58.984375000 -0500
@@ -31,7 +31,11 @@
 #define CAPTURE_IMAGE	0x08
 #define CAPTURE_VIDEO	0x10
 
+#ifdef CAPTURE
 extern Bitu CaptureState;
+#else
+#define CaptureState 0
+#endif
 
 void OPL_Init(Section* sec,OPL_Mode mode);
 void CMS_Init(Section* sec);
diff -ru dosbox-0.71.orig/include/inout.h dosbox-0.71/include/inout.h
--- dosbox-0.71.orig/include/inout.h	2007-06-12 15:22:07.000000000 -0500
+++ dosbox-0.71/include/inout.h	2007-08-01 13:06:07.875000000 -0500
@@ -21,7 +21,11 @@
 #ifndef DOSBOX_INOUT_H
 #define DOSBOX_INOUT_H
 
+#ifdef PSP
+#define IO_MAX (0x400)
+#else
 #define IO_MAX (64*1024+3)
+#endif
 
 #define IO_MB	0x1
 #define IO_MW	0x2
diff -ru dosbox-0.71.orig/include/keyboard.h dosbox-0.71/include/keyboard.h
--- dosbox-0.71.orig/include/keyboard.h	2007-01-08 12:45:37.000000000 -0600
+++ dosbox-0.71/include/keyboard.h	2007-08-27 21:02:19.484375000 -0500
@@ -44,9 +44,19 @@
 	KBD_kpdivide,KBD_kpmultiply,KBD_kpminus,KBD_kpplus,KBD_kpenter,KBD_kpperiod,
 
 	
-	KBD_LAST
+	KBD_LAST, KBD_button1, KBD_button2
 };
 
+#ifdef PSP
+typedef struct keymap {
+	KBD_KEYS key;
+	Bitu mask;
+	char ascii;
+} keymap;
+
+#define CAN_USE_LOCK
+#endif
+
 void KEYBOARD_ClrBuffer(void);
 void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed);
 
diff -ru dosbox-0.71.orig/include/mem.h dosbox-0.71/include/mem.h
--- dosbox-0.71.orig/include/mem.h	2007-06-14 03:23:46.000000000 -0500
+++ dosbox-0.71/include/mem.h	2007-08-01 13:06:07.875000000 -0500
@@ -88,19 +88,19 @@
 	return *(Bit8u *)off;
 };
 INLINE Bit16u host_readw(HostPt off) {
-	return *(Bit16u *)off;
+	return ((unaligned_half *)off)->val;
 };
 INLINE Bit32u host_readd(HostPt off) {
-	return *(Bit32u *)off;
+	return ((unaligned_word *)off)->val;
 };
 INLINE void host_writeb(HostPt off,Bit8u val) {
 	*(Bit8u *)(off)=val;
 };
 INLINE void host_writew(HostPt off,Bit16u val) {
-	*(Bit16u *)(off)=val;
+	((unaligned_half *)(off))->val=val;
 };
 INLINE void host_writed(HostPt off,Bit32u val) {
-	*(Bit32u *)(off)=val;
+	((unaligned_word *)(off))->val=val;
 };
 
 #endif
diff -ru dosbox-0.71.orig/include/mixer.h dosbox-0.71/include/mixer.h
--- dosbox-0.71.orig/include/mixer.h	2007-01-08 12:45:37.000000000 -0600
+++ dosbox-0.71/include/mixer.h	2007-08-17 15:11:52.093750000 -0500
@@ -23,6 +23,10 @@
 #include "dosbox.h"
 #endif
 
+#ifdef PSP
+#include <pspkerneltypes.h>
+#endif
+
 typedef void (*MIXER_MixHandler)(Bit8u * sampdate,Bit32u len);
 typedef void (*MIXER_Handler)(Bitu len);
 
@@ -38,7 +42,16 @@
 
 #define MIXER_BUFSIZE (16*1024)
 #define MIXER_BUFMASK (MIXER_BUFSIZE-1)
-extern Bit8u MixTemp[MIXER_BUFSIZE];
+
+#ifdef PSP
+#ifdef PSPME
+#define MixTemp ((Bit8u *)0)		// This is not a NULL pointer!
+#else
+#define MixTemp ((Bit8u *)0x10000)
+#endif
+#else
+extern Bit8u *MixTemp;
+#endif
 
 #define MAX_AUDIO ((1<<(16-1))-1)
 #define MIN_AUDIO -(1<<(16-1))
diff -ru dosbox-0.71.orig/include/paging.h dosbox-0.71/include/paging.h
--- dosbox-0.71.orig/include/paging.h	2007-06-12 15:22:07.000000000 -0500
+++ dosbox-0.71/include/paging.h	2007-08-06 14:59:23.250000000 -0500
@@ -32,7 +32,19 @@
 
 #define MEM_PAGE_SIZE	(4096)
 #define XMS_START		(0x110)
+#ifndef PSP
 #define TLB_SIZE		(1024*1024)
+#define TLB_BANKS		0
+#define BANK_SHIFT		32
+#define BANK_MASK		0
+#define PAGING_LINKS 		(128*1024/4)
+#else 
+#define TLB_SIZE		65536	// This must a power of 2 and greater then LINK_START
+#define BANK_SHIFT		28
+#define BANK_MASK		0xffff // always the same as TLB_SIZE-1?
+#define TLB_BANKS		((1024*1024/TLB_SIZE)-1)
+#define PAGING_LINKS 		(10*1024/4)
+#endif
 
 #define PFLAG_READABLE		0x1
 #define PFLAG_WRITEABLE		0x2
@@ -43,9 +55,6 @@
 
 #define LINK_START	((1024+64)/4)			//Start right after the HMA
 
-//Allow 128 mb of memory to be linked
-#define PAGING_LINKS (128*1024/4)
-
 class PageHandler {
 public:
 	virtual ~PageHandler(void) { }
@@ -66,6 +75,13 @@
 	Bitu flags;
 };
 
+typedef struct {
+	HostPt read;
+	HostPt write;
+	PageHandler * handler;
+	Bit32u	phys_page;
+} tlb_entry;
+
 /* Some other functions */
 void PAGING_Enable(bool enabled);
 bool PAGING_Enabled(void);
@@ -80,6 +96,7 @@
 /* This maps the page directly, only use when paging is disabled */
 void PAGING_MapPage(Bitu lin_page,Bitu phys_page);
 bool PAGING_MakePhysPage(Bitu & page);
+void PAGING_InitTLBBank(tlb_entry **bank);
 
 void MEM_SetLFB( Bitu page, Bitu pages, PageHandler *handler);
 void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler);
@@ -120,7 +137,6 @@
 #pragma pack ()
 #endif
 
-
 union X86PageEntry {
 	Bit32u load;
 	X86_PageEntryBlock block;
@@ -133,12 +149,8 @@
 		Bitu page;
 		PhysPt addr;
 	} base;
-	struct {
-		HostPt read[TLB_SIZE];
-		HostPt write[TLB_SIZE];
-		PageHandler * handler[TLB_SIZE];
-		Bit32u	phys_page[TLB_SIZE];
-	} tlb;
+	tlb_entry tlb[TLB_SIZE];
+	tlb_entry *tlb_banks[TLB_BANKS];
 	struct {
 		Bitu used;
 		Bit32u entries[PAGING_LINKS];
@@ -153,16 +165,6 @@
 
 PageHandler * MEM_GetPageHandler(Bitu phys_page);
 
-/* Use this helper function to access linear addresses in readX/writeX functions */
-INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) {
-	return (paging.tlb.phys_page[linePage>>12]<<12);
-}
-
-INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) {
-	return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff);
-}
-
-
 /* Unaligned address handlers */
 Bit16u mem_unalignedreadw(PhysPt address);
 Bit32u mem_unalignedreadd(PhysPt address);
@@ -176,52 +178,82 @@
 
 /* Special inlined memory reading/writing */
 
+INLINE tlb_entry *get_tlb_entry(PhysPt address) {
+	Bitu index=(address>>12);
+	if (TLB_BANKS && (index > TLB_SIZE)) {
+		Bitu bank=(address>>BANK_SHIFT) - 1;
+		if (!paging.tlb_banks[bank])
+			PAGING_InitTLBBank(&paging.tlb_banks[bank]);
+		return &paging.tlb_banks[bank][index & BANK_MASK];
+	}
+	return &paging.tlb[index];
+}
+
+/* Use this helper function to access linear addresses in readX/writeX functions */
+INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) {
+	tlb_entry *entry = get_tlb_entry(linePage);
+	return (entry->phys_page<<12);
+}
+
+INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) {
+	tlb_entry *entry = get_tlb_entry(linAddr);
+	return (entry->phys_page<<12)|(linAddr&0xfff);
+}
+
+/* the complier will hopefully optimize this nicely */
+
 INLINE Bit8u mem_readb_inline(PhysPt address) {
 	Bitu index=(address>>12);
-	if (paging.tlb.read[index]) return host_readb(paging.tlb.read[index]+address);
-	else return (Bit8u)paging.tlb.handler[index]->readb(address);
+	tlb_entry *entry = get_tlb_entry(address);
+	if (entry->read) return host_readb(entry->read+address);
+	else return (Bit8u)entry->handler->readb(address);
 }
 
 INLINE Bit16u mem_readw_inline(PhysPt address) {
 	if (!(address & 1)) {
 		Bitu index=(address>>12);
+		tlb_entry *entry = get_tlb_entry(address);
 
-		if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address);
-		else return (Bit16u) paging.tlb.handler[index]->readw(address);
+		if (entry->read) return host_readw(entry->read+address);
+		else return (Bit16u) entry->handler->readw(address);
 	} else return mem_unalignedreadw(address);
 }
 
 INLINE Bit32u mem_readd_inline(PhysPt address) {
 	if (!(address & 3)) {
 		Bitu index=(address>>12);
+		tlb_entry *entry = get_tlb_entry(address);
 
-		if (paging.tlb.read[index]) return host_readd(paging.tlb.read[index]+address);
-		else return paging.tlb.handler[index]->readd(address);
+		if (entry->read) return host_readd(entry->read+address);
+		else return entry->handler->readd(address);
 	} else return mem_unalignedreadd(address);
 }
 
 INLINE void mem_writeb_inline(PhysPt address,Bit8u val) {
 	Bitu index=(address>>12);
+	tlb_entry *entry = get_tlb_entry(address);
 
-	if (paging.tlb.write[index]) host_writeb(paging.tlb.write[index]+address,val);
-	else paging.tlb.handler[index]->writeb(address,val);
+	if (entry->write) host_writeb(entry->write+address,val);
+	else entry->handler->writeb(address,val);
 }
 
 INLINE void mem_writew_inline(PhysPt address,Bit16u val) {
 	if (!(address & 1)) {
 		Bitu index=(address>>12);
+		tlb_entry *entry = get_tlb_entry(address);
 
-		if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val);
-		else paging.tlb.handler[index]->writew(address,val);
+		if (entry->write) host_writew(entry->write+address,val);
+		else entry->handler->writew(address,val);
 	} else mem_unalignedwritew(address,val);
 }
 
 INLINE void mem_writed_inline(PhysPt address,Bit32u val) {
 	if (!(address & 3)) {
 		Bitu index=(address>>12);
+		tlb_entry *entry = get_tlb_entry(address);
 
-		if (paging.tlb.write[index]) host_writed(paging.tlb.write[index]+address,val);
-		else paging.tlb.handler[index]->writed(address,val);
+		if (entry->write) host_writed(entry->write+address,val);
+		else entry->handler->writed(address,val);
 	} else mem_unalignedwrited(address,val);
 }
 
@@ -229,49 +261,54 @@
 INLINE Bit16u mem_readw_dyncorex86(PhysPt address) {
 	if ((address & 0xfff)<0xfff) {
 		Bitu index=(address>>12);
+		tlb_entry *entry = get_tlb_entry(address);
 
-		if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address);
-		else return (Bit16u)paging.tlb.handler[index]->readw(address);
+		if (entry->read) return host_readw(entry->read+address);
+		else return (Bit16u)entry->handler->readw(address);
 	} else return mem_unalignedreadw(address);
 }
 
 INLINE Bit32u mem_readd_dyncorex86(PhysPt address) {
 	if ((address & 0xfff)<0xffd) {
 		Bitu index=(address>>12);
+		tlb_entry *entry = get_tlb_entry(address);
 
-		if (paging.tlb.read[index]) return host_readd(paging.tlb.read[index]+address);
-		else return paging.tlb.handler[index]->readd(address);
+		if (entry->read) return host_readd(entry->read+address);
+		else return entry->handler->readd(address);
 	} else return mem_unalignedreadd(address);
 }
 
 INLINE void mem_writew_dyncorex86(PhysPt address,Bit16u val) {
 	if ((address & 0xfff)<0xfff) {
 		Bitu index=(address>>12);
+		tlb_entry *entry = get_tlb_entry(address);
 
-		if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val);
-		else paging.tlb.handler[index]->writew(address,val);
+		if (entry->write) host_writew(entry->write+address,val);
+		else entry->handler->writew(address,val);
 	} else mem_unalignedwritew(address,val);
 }
 
 INLINE void mem_writed_dyncorex86(PhysPt address,Bit32u val) {
 	if ((address & 0xfff)<0xffd) {
 		Bitu index=(address>>12);
+		tlb_entry *entry = get_tlb_entry(address);
 
-		if (paging.tlb.write[index]) host_writed(paging.tlb.write[index]+address,val);
-		else paging.tlb.handler[index]->writed(address,val);
+		if (entry->write) host_writed(entry->write+address,val);
+		else entry->handler->writed(address,val);
 	} else mem_unalignedwrited(address,val);
 }
 
 
 INLINE bool mem_readb_checked_x86(PhysPt address, Bit8u * val) {
 	Bitu index=(address>>12);
-	if (paging.tlb.read[index]) {
-		*val=host_readb(paging.tlb.read[index]+address);
+	tlb_entry *entry = get_tlb_entry(address);
+	if (entry->read) {
+		*val=host_readb(entry->read+address);
 		return false;
 	} else {
 		Bitu uval;
 		bool retval;
-		retval=paging.tlb.handler[index]->readb_checked(address, &uval);
+		retval=entry->handler->readb_checked(address, &uval);
 		*val=(Bit8u)uval;
 		return retval;
 	}
@@ -280,13 +317,14 @@
 INLINE bool mem_readw_checked_x86(PhysPt address, Bit16u * val) {
 	if ((address & 0xfff)<0xfff) {
 		Bitu index=(address>>12);
-		if (paging.tlb.read[index]) {
-			*val=host_readw(paging.tlb.read[index]+address);
+		tlb_entry *entry = get_tlb_entry(address);
+		if (entry->read) {
+			*val=host_readw(entry->read+address);
 			return false;
 		} else {
 			Bitu uval;
 			bool retval;
-			retval=paging.tlb.handler[index]->readw_checked(address, &uval);
+			retval=entry->handler->readw_checked(address, &uval);
 			*val=(Bit16u)uval;
 			return retval;
 		}
@@ -297,13 +335,14 @@
 INLINE bool mem_readd_checked_x86(PhysPt address, Bit32u * val) {
 	if ((address & 0xfff)<0xffd) {
 		Bitu index=(address>>12);
-		if (paging.tlb.read[index]) {
-			*val=host_readd(paging.tlb.read[index]+address);
+		tlb_entry *entry = get_tlb_entry(address);
+		if (entry->read) {
+			*val=host_readd(entry->read+address);
 			return false;
 		} else {
 			Bitu uval;
 			bool retval;
-			retval=paging.tlb.handler[index]->readd_checked(address, &uval);
+			retval=entry->handler->readd_checked(address, &uval);
 			*val=(Bit32u)uval;
 			return retval;
 		}
@@ -312,29 +351,32 @@
 
 INLINE bool mem_writeb_checked_x86(PhysPt address,Bit8u val) {
 	Bitu index=(address>>12);
-	if (paging.tlb.write[index]) {
-		host_writeb(paging.tlb.write[index]+address,val);
+	tlb_entry *entry = get_tlb_entry(address);
+	if (entry->write) {
+		host_writeb(entry->write+address,val);
 		return false;
-	} else return paging.tlb.handler[index]->writeb_checked(address,val);
+	} else return entry->handler->writeb_checked(address,val);
 }
 
 INLINE bool mem_writew_checked_x86(PhysPt address,Bit16u val) {
 	if ((address & 0xfff)<0xfff) {
+		tlb_entry *entry = get_tlb_entry(address);
 		Bitu index=(address>>12);
-		if (paging.tlb.write[index]) {
-			host_writew(paging.tlb.write[index]+address,val);
+		if (entry->write) {
+			host_writew(entry->write+address,val);
 			return false;
-		} else return paging.tlb.handler[index]->writew_checked(address,val);
+		} else return entry->handler->writew_checked(address,val);
 	} else return mem_unalignedwritew_checked_x86(address,val);
 }
 
 INLINE bool mem_writed_checked_x86(PhysPt address,Bit32u val) {
 	if ((address & 0xfff)<0xffd) {
 		Bitu index=(address>>12);
-		if (paging.tlb.write[index]) {
-			host_writed(paging.tlb.write[index]+address,val);
+		tlb_entry *entry = get_tlb_entry(address);
+		if (entry->write) {
+			host_writed(entry->write+address,val);
 			return false;
-		} else return paging.tlb.handler[index]->writed_checked(address,val);
+		} else return entry->handler->writed_checked(address,val);
 	} else return mem_unalignedwrited_checked_x86(address,val);
 }
 
diff -ru dosbox-0.71.orig/include/pic.h dosbox-0.71/include/pic.h
--- dosbox-0.71.orig/include/pic.h	2007-06-03 08:55:16.000000000 -0500
+++ dosbox-0.71/include/pic.h	2007-08-07 22:08:44.390625000 -0500
@@ -44,12 +44,12 @@
 	return CPU_CycleMax-CPU_CycleLeft-CPU_Cycles;
 }
 
-INLINE Bits PIC_MakeCycles(double amount) {
+INLINE Bits PIC_MakeCycles(float amount) {
 	return (Bits)(CPU_CycleMax*amount);
 }
 
-INLINE double PIC_FullIndex(void) {
-	return PIC_Ticks+(double)PIC_TickIndex();
+INLINE float PIC_FullIndex(void) {
+	return PIC_Ticks+(float)PIC_TickIndex();
 }
 
 void PIC_ActivateIRQ(Bitu irq);
diff -ru dosbox-0.71.orig/include/regs.h dosbox-0.71/include/regs.h
--- dosbox-0.71.orig/include/regs.h	2007-06-12 15:22:07.000000000 -0500
+++ dosbox-0.71/include/regs.h	2007-08-04 21:56:04.187500000 -0500
@@ -59,8 +59,8 @@
 enum SegNames { es=0,cs,ss,ds,fs,gs};
 
 struct Segments {
-	Bitu val[8];
-	PhysPt phys[8];
+	Bitu val[6];
+	PhysPt phys[6];
 };
 
 union GenReg32 {
diff -ru dosbox-0.71.orig/include/setup.h dosbox-0.71/include/setup.h
--- dosbox-0.71.orig/include/setup.h	2007-06-14 03:23:46.000000000 -0500
+++ dosbox-0.71/include/setup.h	2007-08-09 22:31:52.734375000 -0500
@@ -82,7 +82,7 @@
         void GetValuestring(char* str) const;
 	~Prop_int(){ }
 };
-class Prop_float:public Property {
+/*class Prop_float:public Property {
 public:
 	Prop_float(char const * const _propname, float _value):Property(_propname){
 		value._float=_value;
@@ -91,7 +91,7 @@
 	void GetValuestring(char* str) const;
 	~Prop_float(){ }
 };
-
+*/
 class Prop_bool:public Property {
 public:
 	Prop_bool(char const * const _propname, bool _value):Property(_propname) { 
@@ -166,13 +166,13 @@
 	void Add_string(char const * const _propname, char const * const _value=NULL);
 	void Add_bool(char const * const _propname, bool _value=false);
 	void Add_hex(char const * const _propname, int _value=0);
-	void Add_float(char const * const _propname, float _value=0.0);   
+//	void Add_float(char const * const _propname, float _value=0.0);   
 
 	int Get_int(char const * const _propname) const;
 	const char* Get_string(char const * const _propname) const;
 	bool Get_bool(char const * const _propname) const;
 	int Get_hex(char const * const _propname) const;
-	float Get_float(char const * const _propname) const;
+//	float Get_float(char const * const _propname) const;
 	void HandleInputline(char *gegevens);
 	void PrintData(FILE* outfile) const;
 	virtual char const * GetPropValue(char const * const _property) const;
diff -ru dosbox-0.71.orig/include/timer.h dosbox-0.71/include/timer.h
--- dosbox-0.71.orig/include/timer.h	2007-01-08 12:45:37.000000000 -0600
+++ dosbox-0.71/include/timer.h	2007-08-01 13:06:07.890625000 -0500
@@ -20,12 +20,17 @@
 #define DOSBOX_TIMER_H
 
 /* underlying clock rate in HZ */
-#include <SDL.h>
+#include "dosbox.h"
 
 #define PIT_TICK_RATE 1193182
 
+#ifdef USE_SDL
+#include <SDL.h>
 #define GetTicks() SDL_GetTicks()
-
+#elif defined(PSP)
+extern struct timeval start;
+Bitu GetTicks();
+#endif
 typedef void (*TIMER_TickHandler)(void);
 
 /* Register a function that gets called everytime if 1 or more ticks pass */
diff -ru dosbox-0.71.orig/include/vga.h dosbox-0.71/include/vga.h
--- dosbox-0.71.orig/include/vga.h	2007-02-22 01:48:19.000000000 -0600
+++ dosbox-0.71/include/vga.h	2007-08-07 22:09:18.578125000 -0500
@@ -26,7 +26,11 @@
 //Don't enable keeping changes and mapping lfb probably...
 #define VGA_LFB_MAPPED
 //#define VGA_KEEP_CHANGES
+#ifdef PSP
+#define VGA_MEMORY (1*1024*1024)
+#else
 #define VGA_MEMORY (2*1024*1024)
+#endif
 #define VGA_CHANGE_SHIFT	9
 
 //Offset inside VGA_MEMORY that will be used for certain types of caching
@@ -121,14 +125,14 @@
 	Bitu parts_lines;
 	Bitu parts_left;
 	struct {
-		double framestart;
-		double vrstart, vrend;		// V-retrace
-		double hrstart, hrend;		// H-retrace
-		double hblkstart, hblkend;	// H-blanking
-		double vblkstart, vblkend;	// V-Blanking
-		double vdend, vtotal;
-		double hdend, htotal;
-		double parts;
+		float framestart;
+		float vrstart, vrend;		// V-retrace
+		float hrstart, hrend;		// H-retrace
+		float hblkstart, hblkend;	// H-blanking
+		float vblkstart, vblkend;	// V-Blanking
+		float vdend, vtotal;
+		float hdend, htotal;
+		float parts;
 	} delay;
 	bool double_scan;
 	bool doublewidth,doubleheight;
@@ -330,7 +334,7 @@
 
 typedef struct {
 	Bit8u	linear[VGA_MEMORY];
-} VGA_Memory;
+} VGA_Memory __attribute__((aligned(4)));
 
 typedef struct {
 	//Add a few more just to be safe
@@ -352,6 +356,7 @@
 typedef struct {
 	VGAModes mode;								/* The mode the vga system is in */
 	VGAModes lastmode;
+	Bit8u force_update;
 	Bit8u misc_output;
 	VGA_Draw draw;
 	VGA_Config config;
diff -ru dosbox-0.71.orig/src/cpu/core_dynrec/cache.h dosbox-0.71/src/cpu/core_dynrec/cache.h
--- dosbox-0.71.orig/src/cpu/core_dynrec/cache.h	2007-06-27 10:22:54.000000000 -0500
+++ dosbox-0.71/src/cpu/core_dynrec/cache.h	2007-08-10 17:14:42.656250000 -0500
@@ -72,6 +72,12 @@
 
 static CacheBlockDynRec link_blocks[2];		// default linking (specially marked)
 
+// cache memory pointers, to be malloc'd later
+static Bit8u * cache_code_start_ptr=NULL;
+static Bit8u * cache_code=NULL;
+static Bit8u * cache_code_link_blocks=NULL;
+static CacheBlockDynRec * cache_blocks=NULL;
+
 // the CodePageHandlerDynRec class provides access to the contained
 // cache blocks and intercepts writes to the code for special treatment
 class CodePageHandlerDynRec : public PageHandler {
@@ -109,7 +115,7 @@
 		bool is_current_block=false;	// if the current block is modified, it has to be exited as soon as possible
 
 		Bit32u ip_point=SegPhys(cs)+reg_eip;
-		ip_point=((paging.tlb.phys_page[ip_point>>12]-phys_page)<<12)+(ip_point&0xfff);
+		ip_point=((get_tlb_entry(ip_point)->phys_page-phys_page)<<12)+(ip_point&0xfff);
 		while (index>=0) {
 			Bitu map=0;
 			// see if there is still some code in the range
@@ -211,7 +217,7 @@
 		addr&=4095;
 		if (host_readw(hostmem+addr)==(Bit16u)val) return false;
 		// see if there's code where we are writing to
-		if (!*(Bit16u*)&write_map[addr]) {
+		if (!((unaligned_half *)&write_map[addr])->val) {
 			if (!active_blocks) {
 				// no blocks left in this page, still delay the page releasing a bit
 				active_count--;
@@ -222,7 +228,7 @@
 				invalidation_map=(Bit8u*)malloc(4096);
 				memset(invalidation_map,0,4096);
 			}
-			(*(Bit16u*)&invalidation_map[addr])+=0x101;
+			(((unaligned_half *)&invalidation_map[addr])->val)+=0x101;
 			if (InvalidateRange(addr,addr+1)) {
 				cpu.exception.which=SMC_CURRENT_BLOCK;
 				return true;
@@ -235,7 +241,7 @@
 		addr&=4095;
 		if (host_readd(hostmem+addr)==(Bit32u)val) return false;
 		// see if there's code where we are writing to
-		if (!*(Bit32u*)&write_map[addr]) {
+		if (!((unaligned_word *)&write_map[addr])->val) {
 			if (!active_blocks) {
 				// no blocks left in this page, still delay the page releasing a bit
 				active_count--;
@@ -246,7 +252,7 @@
 				invalidation_map=(Bit8u*)malloc(4096);
 				memset(invalidation_map,0,4096);
 			}
-			(*(Bit32u*)&invalidation_map[addr])+=0x1010101;
+			(((unaligned_word *)&invalidation_map[addr])->val)+=0x1010101;
 			if (InvalidateRange(addr,addr+3)) {
 				cpu.exception.which=SMC_CURRENT_BLOCK;
 				return true;
@@ -490,7 +496,7 @@
 		}
 	}
 	// advance the active block pointer
-	if (!block->cache.next) {
+	if (!block->cache.next || ((cache_code_start_ptr + CACHE_TOTAL - CACHE_MAXSIZE) < block->cache.next->cache.start)) {
 //		LOG_MSG("Cache full restarting");
 		cache.block.active=cache.block.first;
 	} else {
@@ -498,7 +504,6 @@
 	}
 }
 
-
 // place an 8bit value into the cache
 static INLINE void cache_addb(Bit8u val) {
 	*cache.pos++=val;
@@ -526,12 +531,6 @@
 static void dyn_return(BlockReturn retcode,bool ret_exception);
 static void dyn_run_code(void);
 
-// cache memory pointers, to be malloc'd later
-static Bit8u * cache_code_start_ptr=NULL;
-static Bit8u * cache_code=NULL;
-static Bit8u * cache_code_link_blocks=NULL;
-static CacheBlockDynRec * cache_blocks=NULL;
-
 /* Define temporary pagesize so the MPROTECT case and the regular case share as much code as possible */
 #if (C_HAVE_MPROTECT)
 #define PAGESIZE_TEMP PAGESIZE
@@ -539,9 +538,13 @@
 #define PAGESIZE_TEMP 4096
 #endif
 
-static bool cache_initialized = false;
+#ifdef PSP
+#include <pspsuspend.h>
+#endif
 
-static void cache_init(bool enable) {
+bool cache_initialized = false;
+
+void cache_init(bool enable) {
 	Bits i;
 	if (enable) {
 		// see if cache is already initialized
@@ -551,14 +554,14 @@
 			// allocate the cache blocks memory
 			cache_blocks=(CacheBlockDynRec*)malloc(CACHE_BLOCKS*sizeof(CacheBlockDynRec));
 			if(!cache_blocks) E_Exit("Allocating cache_blocks has failed");
-			memset(cache_blocks,0,sizeof(CacheBlockDynRec)*CACHE_BLOCKS);
-			cache.block.free=&cache_blocks[0];
-			// initialize the cache blocks
-			for (i=0;i<CACHE_BLOCKS-1;i++) {
-				cache_blocks[i].link[0].to=(CacheBlockDynRec *)1;
-				cache_blocks[i].link[1].to=(CacheBlockDynRec *)1;
-				cache_blocks[i].cache.next=&cache_blocks[i+1];
-			}
+		}
+		memset(cache_blocks,0,sizeof(CacheBlockDynRec)*CACHE_BLOCKS);
+		cache.block.free=&cache_blocks[0];
+		// initialize the cache blocks
+		for (i=0;i<CACHE_BLOCKS-1;i++) {
+			cache_blocks[i].link[0].to=(CacheBlockDynRec *)1;
+			cache_blocks[i].link[1].to=(CacheBlockDynRec *)1;
+			cache_blocks[i].cache.next=&cache_blocks[i+1];
 		}
 		if (cache_code_start_ptr==NULL) {
 			// allocate the code cache memory
@@ -566,29 +569,33 @@
 			cache_code_start_ptr=(Bit8u*)VirtualAlloc(0,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP,
 				MEM_COMMIT,PAGE_EXECUTE_READWRITE);
 			if (!cache_code_start_ptr)
-				cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
+				cache_code_start_ptr=(Bit8u*)_aligned_malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP, PAGESIZE_TEMP);
+#elif defined(PSP)
+			int size;
+			void *addr;
+			if(!sceKernelVolatileMemLock(0, &addr, &size)) cache_code_start_ptr=(Bit8u*)0x08300000;
 #else
-			cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
+			cache_code_start_ptr=(Bit8u*)memalign(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP, PAGESIZE_TEMP);
 #endif
 			if(!cache_code_start_ptr) E_Exit("Allocating dynamic cache failed");
-
-			// align the cache at a page boundary
-			cache_code=(Bit8u*)(((long)cache_code_start_ptr + PAGESIZE_TEMP-1) & ~(PAGESIZE_TEMP-1)); //MEM LEAK. store old pointer if you want to free it.
-
-			cache_code_link_blocks=cache_code;
-			cache_code=cache_code+PAGESIZE_TEMP;
+		}
+		cache_code = cache_code_start_ptr;
+		cache_code_link_blocks=cache_code;
+		cache_code=cache_code+PAGESIZE_TEMP;
 
 #if (C_HAVE_MPROTECT)
-			if(mprotect(cache_code_link_blocks,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP,PROT_WRITE|PROT_READ|PROT_EXEC))
-				LOG_MSG("Setting excute permission on the code cache has failed");
+		if(mprotect(cache_code_link_blocks,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP,PROT_WRITE|PROT_READ|PROT_EXEC))
+			LOG_MSG("Setting excute permission on the code cache has failed");
 #endif
-			CacheBlockDynRec * block=cache_getblock();
-			cache.block.first=block;
-			cache.block.active=block;
-			block->cache.start=&cache_code[0];
-			block->cache.size=CACHE_TOTAL;
-			block->cache.next=0;						// last block in the list
-		}
+		CacheBlockDynRec * block=cache_getblock();
+		cache.block.first=block;
+		cache.block.active=block;
+		block->cache.start=&cache_code[0];
+		block->cache.size=CACHE_TOTAL;
+		block->cache.next=0;						// last block in the list
+		cache.pos=&cache_code_link_blocks[64];
+		core_dynrec.runcode=(BlockReturn (*)(Bit8u*))cache.pos;
+		dyn_run_code();
 		// setup the default blocks for block linkage returns
 		cache.pos=&cache_code_link_blocks[0];
 		link_blocks[0].cache.start=cache.pos;
@@ -599,10 +606,7 @@
 		// link code that returns with a special return code
 		dyn_return(BR_Link2,false);
 
-		cache.pos=&cache_code_link_blocks[64];
-		core_dynrec.runcode=(BlockReturn (*)(Bit8u*))cache.pos;
 //		link_blocks[1].cache.start=cache.pos;
-		dyn_run_code();
 
 		cache.free_pages=0;
 		cache.last_page=0;
@@ -616,6 +620,16 @@
 	}
 }
 
+void cache_free_memory(void) {
+	CacheBlockDynRec * list = cache.block.first;
+	do if(list->page.handler) list->page.handler->ClearRelease();
+	while(list = list->cache.next);
+#ifndef PSP
+	free(cache_code_start_ptr);
+#endif
+	cache_code_start_ptr = NULL;  // so the memory will be reallocated later
+}
+	
 static void cache_close(void) {
 /*	for (;;) {
 		if (cache.used_pages) {
diff -ru dosbox-0.71.orig/src/cpu/core_dynrec/decoder.h dosbox-0.71/src/cpu/core_dynrec/decoder.h
--- dosbox-0.71.orig/src/cpu/core_dynrec/decoder.h	2007-06-14 12:47:25.000000000 -0500
+++ dosbox-0.71/src/cpu/core_dynrec/decoder.h	2007-08-01 13:06:07.890625000 -0500
@@ -30,6 +30,17 @@
 	instruction is encountered.
 */
 
+#ifdef PSP
+// writeback dcache and invalidate icache
+#define FLUSH_CACHE   { Bit32u inval_start = (Bit32u)decode.block->cache.start & ~63;					\
+			Bit32u inval_end = ((decode.block->cache.size+(Bit32u)decode.block->cache.start) & ~63) + 64;	\
+			for (;inval_start < inval_end; inval_start+=64) { 						\
+				__builtin_allegrex_cache(0x1a, inval_start);						\
+				__builtin_allegrex_cache(0x08, inval_start); } }
+#else
+#define FLUSH_CACHE
+#endif
+
 static CacheBlockDynRec * CreateCacheBlock(CodePageHandlerDynRec * codepage,PhysPt start,Bitu max_opcodes) {
 	// initialize a load of variables
 	decode.code_start=start;
@@ -578,5 +589,6 @@
 	decode.active_block->page.end=(Bit16u)decode.page.index;
 //	LOG_MSG("Created block size %d start %d end %d",decode.block->cache.size,decode.block->page.start,decode.block->page.end);
 
+	FLUSH_CACHE;
 	return decode.block;
 }
diff -ru dosbox-0.71.orig/src/cpu/core_dynrec/decoder_basic.h dosbox-0.71/src/cpu/core_dynrec/decoder_basic.h
--- dosbox-0.71.orig/src/cpu/core_dynrec/decoder_basic.h	2007-07-22 13:48:54.000000000 -0500
+++ dosbox-0.71/src/cpu/core_dynrec/decoder_basic.h	2007-08-20 21:16:23.062500000 -0500
@@ -134,7 +134,7 @@
 
 	Bitu lin_page=lin_addr >> 12;
 
-	PageHandler * handler=paging.tlb.handler[lin_page];
+	PageHandler * handler=get_tlb_entry(lin_addr)->handler;
 	if (handler->flags & PFLAG_HASCODE) {
 		// this is a codepage handler, and the one that we're looking for
 		cph=(CodePageHandlerDynRec *)handler;
@@ -219,7 +219,7 @@
 		val|=decode_fetchb() << 8;
 		return val;
 	}
-	*(Bit16u *)&decode.page.wmap[decode.page.index]+=0x0101;
+	((unaligned_half *)&decode.page.wmap[decode.page.index])->val+=0x0101;
 	decode.code+=2;decode.page.index+=2;
 	return mem_readw(decode.code-2);
 }
@@ -233,7 +233,7 @@
 		return val;
         /* Advance to the next page */
 	}
-	*(Bit32u *)&decode.page.wmap[decode.page.index]+=0x01010101;
+	((unaligned_word *)&decode.page.wmap[decode.page.index])->val+=0x01010101;
 	decode.code+=4;decode.page.index+=4;
 	return mem_readd(decode.code-4);
 }
@@ -269,8 +269,8 @@
 	// update mask entries
 	switch (size) {
 		case 1 : activecb->cache.wmapmask[mapidx]+=0x01; break;
-		case 2 : (*(Bit16u*)&activecb->cache.wmapmask[mapidx])+=0x0101; break;
-		case 4 : (*(Bit32u*)&activecb->cache.wmapmask[mapidx])+=0x01010101; break;
+		case 2 : ((unaligned_half *)&activecb->cache.wmapmask[mapidx])->val+=0x0101; break;
+		case 4 : ((unaligned_word *)&activecb->cache.wmapmask[mapidx])->val+=0x01010101; break;
 	}
 }
 
@@ -281,9 +281,10 @@
 		decode_advancepage();
 	}
 	Bitu index=(decode.code>>12);
+	tlb_entry *entry = get_tlb_entry(decode.code);
 	// see if position is directly accessible
-	if (paging.tlb.read[index]) {
-		val=(Bitu)(paging.tlb.read[index]+decode.code);
+	if (entry->read) {
+		val=(Bitu)(entry->read+decode.code);
 		decode_increase_wmapmask(1);
 		decode.code++;
 		decode.page.index++;
@@ -299,9 +300,10 @@
 static bool decode_fetchw_imm(Bitu & val) {
 	if (decode.page.index<4095) {
 		Bitu index=(decode.code>>12);
+		tlb_entry *entry = get_tlb_entry(decode.code);
 		// see if position is directly accessible
-		if (paging.tlb.read[index]) {
-			val=(Bitu)(paging.tlb.read[index]+decode.code);
+		if (entry->read) {
+			val=(Bitu)(entry->read+decode.code);
 			decode_increase_wmapmask(2);
 			decode.code+=2;
 			decode.page.index+=2;
@@ -318,9 +320,10 @@
 static bool decode_fetchd_imm(Bitu & val) {
 	if (decode.page.index<4093) {
 		Bitu index=(decode.code>>12);
+		tlb_entry *entry = get_tlb_entry(decode.code);
 		// see if position is directly accessible
-		if (paging.tlb.read[index]) {
-			val=(Bitu)(paging.tlb.read[index]+decode.code);
+		if (entry->read) {
+			val=(Bitu)(entry->read+decode.code);
 			decode_increase_wmapmask(4);
 			decode.code+=4;
 			decode.page.index+=4;
@@ -383,67 +386,67 @@
 // R=host register; I=32bit immediate value; A=address value; m=memory
 
 static DRC_PTR_SIZE_IM INLINE gen_call_function_R(void * func,Bitu op) {
-	gen_load_param_reg(op,0);
+	gen_load_param_reg(op,0, true);
 	return gen_call_function_setup(func, 1);
 }
 
 static DRC_PTR_SIZE_IM INLINE gen_call_function_R3(void * func,Bitu op) {
-	gen_load_param_reg(op,2);
+	gen_load_param_reg(op,2,true);	
 	return gen_call_function_setup(func, 3, true);
 }
 
 static DRC_PTR_SIZE_IM INLINE gen_call_function_RI(void * func,Bitu op1,Bitu op2) {
 	gen_load_param_imm(op2,1);
-	gen_load_param_reg(op1,0);
+	gen_load_param_reg(op1,0,true);
 	return gen_call_function_setup(func, 2);
 }
 
 static DRC_PTR_SIZE_IM INLINE gen_call_function_RA(void * func,Bitu op1,DRC_PTR_SIZE_IM op2) {
 	gen_load_param_addr(op2,1);
-	gen_load_param_reg(op1,0);
+	gen_load_param_reg(op1,0,true);
 	return gen_call_function_setup(func, 2);
 }
 
 static DRC_PTR_SIZE_IM INLINE gen_call_function_RR(void * func,Bitu op1,Bitu op2) {
 	gen_load_param_reg(op2,1);
-	gen_load_param_reg(op1,0);
+	gen_load_param_reg(op1,0,true);
 	return gen_call_function_setup(func, 2);
 }
 
 static DRC_PTR_SIZE_IM INLINE gen_call_function_IR(void * func,Bitu op1,Bitu op2) {
 	gen_load_param_reg(op2,1);
-	gen_load_param_imm(op1,0);
+	gen_load_param_imm(op1,0,true);
 	return gen_call_function_setup(func, 2);
 }
 
 static DRC_PTR_SIZE_IM INLINE gen_call_function_I(void * func,Bitu op) {
-	gen_load_param_imm(op,0);
+	gen_load_param_imm(op,0,true);
 	return gen_call_function_setup(func, 1);
 }
 
 static DRC_PTR_SIZE_IM INLINE gen_call_function_II(void * func,Bitu op1,Bitu op2) {
 	gen_load_param_imm(op2,1);
-	gen_load_param_imm(op1,0);
+	gen_load_param_imm(op1,0,true);
 	return gen_call_function_setup(func, 2);
 }
 
 static DRC_PTR_SIZE_IM INLINE gen_call_function_III(void * func,Bitu op1,Bitu op2,Bitu op3) {
 	gen_load_param_imm(op3,2);
 	gen_load_param_imm(op2,1);
-	gen_load_param_imm(op1,0);
+	gen_load_param_imm(op1,0,true);
 	return gen_call_function_setup(func, 3);
 }
 
 static DRC_PTR_SIZE_IM INLINE gen_call_function_IA(void * func,Bitu op1,DRC_PTR_SIZE_IM op2) {
 	gen_load_param_addr(op2,1);
-	gen_load_param_imm(op1,0);
+	gen_load_param_imm(op1,0,true);
 	return gen_call_function_setup(func, 2);
 }
 
 static DRC_PTR_SIZE_IM INLINE gen_call_function_IIR(void * func,Bitu op1,Bitu op2,Bitu op3) {
 	gen_load_param_reg(op3,2);
 	gen_load_param_imm(op2,1);
-	gen_load_param_imm(op1,0);
+	gen_load_param_imm(op1,0,true);
 	return gen_call_function_setup(func, 3);
 }
 
@@ -451,7 +454,7 @@
 	gen_load_param_reg(op4,3);
 	gen_load_param_imm(op3,2);
 	gen_load_param_imm(op2,1);
-	gen_load_param_imm(op1,0);
+	gen_load_param_imm(op1,0,true);
 	return gen_call_function_setup(func, 4);
 }
 
@@ -459,18 +462,18 @@
 	gen_load_param_reg(op4,3);
 	gen_load_param_reg(op3,2);
 	gen_load_param_reg(op2,1);
-	gen_load_param_imm(op1,0);
+	gen_load_param_imm(op1,0,true);
 	return gen_call_function_setup(func, 4);
 }
 
 static DRC_PTR_SIZE_IM INLINE gen_call_function_m(void * func,Bitu op) {
-	gen_load_param_mem(op,2);
+	gen_load_param_mem(op,2,true);
 	return gen_call_function_setup(func, 3, true);
 }
 
 static DRC_PTR_SIZE_IM INLINE gen_call_function_mm(void * func,Bitu op1,Bitu op2) {
 	gen_load_param_mem(op2,3);
-	gen_load_param_mem(op1,2);
+	gen_load_param_mem(op1,2,true);
 	return gen_call_function_setup(func, 4, true);
 }
 
@@ -496,22 +499,18 @@
 	DRC_PTR_SIZE_IM branch_pos;
 	Bit32u eip_change;
 	Bitu cycles;
-} save_info_dynrec[512];
+} save_info_dynrec[128];
 
 Bitu used_save_info_dynrec=0;
 
-
 // return from current block, with returncode
-static void dyn_return(BlockReturn retcode,bool ret_exception=false) {
-	if (!ret_exception) {
-		gen_mov_dword_to_reg_imm(FC_RETOP,retcode);
-	}
-	gen_return_function();
+static INLINE void dyn_return(BlockReturn retcode,bool ret_exception=false) {
+	gen_return_function((Bit16u)retcode,ret_exception);
 }
 
 static void dyn_run_code(void) {
 	gen_run_code();
-	gen_return_function();
+//	gen_return_function();
 }
 
 // fill in code at the end of the block that contains rarely-executed code
@@ -566,13 +565,14 @@
 bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) DRC_FC;
 bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) {
 	Bitu index=(address>>12);
-	if (paging.tlb.read[index]) {
-		*((Bit8u*)(&core_dynrec.readdata))=host_readb(paging.tlb.read[index]+address);
+	tlb_entry *entry = get_tlb_entry(address);
+	if (entry->read) {
+		*((Bit8u*)(&core_dynrec.readdata))=host_readb(entry->read+address);
 		return false;
 	} else {
 		Bitu uval;
 		bool retval;
-		retval=paging.tlb.handler[index]->readb_checked(address, &uval);
+		retval=entry->handler->readb_checked(address, &uval);
 		*((Bit8u*)(&core_dynrec.readdata))=(Bit8u)uval;
 		return retval;
 	}
@@ -581,10 +581,11 @@
 bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) DRC_FC;
 bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) {
 	Bitu index=(address>>12);
-	if (paging.tlb.write[index]) {
-		host_writeb(paging.tlb.write[index]+address,val);
+	tlb_entry *entry = get_tlb_entry(address);
+	if (entry->write) {
+		host_writeb(entry->write+address,val);
 		return false;
-	} else return paging.tlb.handler[index]->writeb_checked(address,val);
+	} else return entry->handler->writeb_checked(address,val);
 }
 
 bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) DRC_FC;
@@ -594,14 +595,15 @@
 #else
 	if ((address & 0xfff)<0xfff) {
 #endif
-			Bitu index=(address>>12);
-		if (paging.tlb.read[index]) {
-			*((Bit16u*)(&core_dynrec.readdata))=host_readw(paging.tlb.read[index]+address);
+		Bitu index=(address>>12);
+		tlb_entry *entry = get_tlb_entry(address);
+		if (entry->read) {
+			*((Bit16u*)(&core_dynrec.readdata))=host_readw(entry->read+address);
 			return false;
 		} else {
 			Bitu uval;
 			bool retval;
-			retval=paging.tlb.handler[index]->readw_checked(address, &uval);
+			retval=entry->handler->readw_checked(address, &uval);
 			*((Bit16u*)(&core_dynrec.readdata))=(Bit16u)uval;
 			return retval;
 		}
@@ -616,13 +618,14 @@
 	if ((address & 0xfff)<0xffd) {
 #endif
 		Bitu index=(address>>12);
-		if (paging.tlb.read[index]) {
-			*((Bit32u*)(&core_dynrec.readdata))=host_readd(paging.tlb.read[index]+address);
+		tlb_entry *entry = get_tlb_entry(address);
+		if (entry->read) {
+			*((Bit32u*)(&core_dynrec.readdata))=host_readd(entry->read+address);
 			return false;
 		} else {
 			Bitu uval;
 			bool retval;
-			retval=paging.tlb.handler[index]->readd_checked(address, &uval);
+			retval=entry->handler->readd_checked(address, &uval);
 			*((Bit32u*)(&core_dynrec.readdata))=(Bit32u)uval;
 			return retval;
 		}
@@ -637,10 +640,11 @@
 	if ((address & 0xfff)<0xfff) {
 #endif
 		Bitu index=(address>>12);
-		if (paging.tlb.write[index]) {
-			host_writew(paging.tlb.write[index]+address,val);
+		tlb_entry *entry = get_tlb_entry(address);
+		if (entry->write) {
+			host_writew(entry->write+address,val);
 			return false;
-		} else return paging.tlb.handler[index]->writew_checked(address,val);
+		} else return entry->handler->writew_checked(address,val);
 	} else return mem_unalignedwritew_checked_x86(address,val);
 }
 
@@ -652,10 +656,11 @@
 	if ((address & 0xfff)<0xffd) {
 #endif
 		Bitu index=(address>>12);
-		if (paging.tlb.write[index]) {
-			host_writed(paging.tlb.write[index]+address,val);
+		tlb_entry *entry = get_tlb_entry(address);
+		if (entry->write) {
+			host_writed(entry->write+address,val);
 			return false;
-		} else return paging.tlb.handler[index]->writed_checked(address,val);
+		} else return entry->handler->writed_checked(address,val);
 	} else return mem_unalignedwrited_checked_x86(address,val);
 }
 
@@ -664,13 +669,13 @@
 
 // read a byte from a given address and store it in reg_dst
 static void dyn_read_byte(HostReg reg_addr,HostReg reg_dst) {
-	gen_mov_regs(FC_OP1,reg_addr);
+	gen_load_param_reg(reg_addr,0,true);
 	gen_call_function_raw((void *)&mem_readb_checked_drc);
 	dyn_check_exception(FC_RETOP);
 	gen_mov_byte_to_reg_low(reg_dst,&core_dynrec.readdata);
 }
 static void dyn_read_byte_canuseword(HostReg reg_addr,HostReg reg_dst) {
-	gen_mov_regs(FC_OP1,reg_addr);
+	gen_load_param_reg(reg_addr,0,true);
 	gen_call_function_raw((void *)&mem_readb_checked_drc);
 	dyn_check_exception(FC_RETOP);
 	gen_mov_byte_to_reg_low_canuseword(reg_dst,&core_dynrec.readdata);
@@ -679,7 +684,7 @@
 // write a byte from reg_val into the memory given by the address
 static void dyn_write_byte(HostReg reg_addr,HostReg reg_val) {
 	gen_mov_regs(FC_OP2,reg_val);
-	gen_mov_regs(FC_OP1,reg_addr);
+	gen_load_param_reg(reg_addr,0,true);
 	gen_call_function_raw((void *)&mem_writeb_checked_drc);
 	dyn_check_exception(FC_RETOP);
 }
@@ -687,7 +692,7 @@
 // read a 32bit (dword=true) or 16bit (dword=false) value
 // from a given address and store it in reg_dst
 static void dyn_read_word(HostReg reg_addr,HostReg reg_dst,bool dword) {
-	gen_mov_regs(FC_OP1,reg_addr);
+	gen_load_param_reg(reg_addr,0,true);
 	if (dword) gen_call_function_raw((void *)&mem_readd_checked_drc);
 	else gen_call_function_raw((void *)&mem_readw_checked_drc);
 	dyn_check_exception(FC_RETOP);
@@ -699,7 +704,7 @@
 static void dyn_write_word(HostReg reg_addr,HostReg reg_val,bool dword) {
 //	if (!dword) gen_extend_word(false,reg_val);
 	gen_mov_regs(FC_OP2,reg_val);
-	gen_mov_regs(FC_OP1,reg_addr);
+	gen_load_param_reg(reg_addr,0,true);
 	if (dword) gen_call_function_raw((void *)&mem_writed_checked_drc);
 	else gen_call_function_raw((void *)&mem_writew_checked_drc);
 	dyn_check_exception(FC_RETOP);
@@ -1027,13 +1032,117 @@
 	gen_mov_word_to_reg(dest_reg,&core_dynrec.protected_regs[reg],true);
 }
 
+static Bitu mf_functions_num=0;
+
+#ifdef PSP //This way the switch in gen_fill_function_ptr is optimized away
+// flags optimization functions
+// they try to find out if a function can be replaced by another
+// one that does not generate any flags at all
+
+static struct {
+	DRC_PTR_SIZE_IM pos;
+	Bit32u fct_ptr;
+	bool insn;
+} mf_functions[64];
+
+static void InitFlagsOptimization(void) {
+	mf_functions_num=0;
+}
+
+// replace all queued functions with their simpler variants
+// because the current instruction destroys all condition flags and
+// the flags are not required before
+static INLINE void InvalidateFlags(void) {
+	for (Bitu ct=0; ct<mf_functions_num; ct++) {
+		if(mf_functions[ct].insn) {
+			*(Bit32u*)(mf_functions[ct].pos)=*(Bit32u*)(mf_functions[ct].pos+4);
+			*(Bit32u*)(mf_functions[ct].pos+4)=mf_functions[ct].fct_ptr;
+		} else *(Bit32u*)(mf_functions[ct].pos)=mf_functions[ct].fct_ptr;
+	}
+	mf_functions_num=0;
+}
+
+// replace all queued functions with their simpler variants
+// because the current instruction destroys all condition flags and
+// the flags are not required before
+static INLINE void InvalidateFlags(void* current_simple_function, Bitu flags_type) {
+	Bit32u fill;
+	for (Bitu ct=0; ct<mf_functions_num; ct++) {
+		if(mf_functions[ct].insn) {
+			*(Bit32u*)(mf_functions[ct].pos)=*(Bit32u*)(mf_functions[ct].pos+4);
+			*(Bit32u*)(mf_functions[ct].pos+4)=mf_functions[ct].fct_ptr;
+		} else *(Bit32u*)(mf_functions[ct].pos)=mf_functions[ct].fct_ptr;
+	}
+	mf_functions[0].pos=(DRC_PTR_SIZE_IM)cache.pos;
+	fill = gen_fill_function_ptr(current_simple_function, flags_type);
+	if(fill == -1) {
+		mf_functions[0].insn = false;
+		mf_functions[0].fct_ptr = 0x0c000000+((((Bit32u)current_simple_function)>>2)&0x3ffffff);	// jal simple_func
+	} else {
+		mf_functions[0].insn = true;
+		mf_functions[0].fct_ptr = fill;
+	}
+	mf_functions_num=1;
+}
+
+static INLINE void InvalidateFlags(void* current_simple_function,DRC_PTR_SIZE_IM cpos, Bitu flags_type) {
+	Bit32u fill;
+	for (Bitu ct=0; ct<mf_functions_num; ct++) {
+		if(mf_functions[ct].insn) {
+			*(Bit32u*)(mf_functions[ct].pos)=*(Bit32u*)(mf_functions[ct].pos+4);
+			*(Bit32u*)(mf_functions[ct].pos+4)=mf_functions[ct].fct_ptr;
+		} else *(Bit32u*)(mf_functions[ct].pos)=mf_functions[ct].fct_ptr;
+	}
+	mf_functions[0].pos=(DRC_PTR_SIZE_IM)cpos;
+	fill = gen_fill_function_ptr(current_simple_function, flags_type);
+	if(fill == -1) {
+		mf_functions[0].insn = false;
+		mf_functions[0].fct_ptr = 0x0c000000+((((Bit32u)current_simple_function)>>2)&0x3ffffff);	// jal simple_func
+	} else {
+		mf_functions[0].insn = true;
+		mf_functions[0].fct_ptr = fill;
+	}
+	mf_functions_num=1;
+}
 
+// enqueue this instruction, if later an instruction is encountered that
+// destroys all condition flags and the flags weren't needed in-between
+// this function can be replaced by a simpler one as well
+static INLINE void InvalidateFlagsPartially(void* current_simple_function, Bitu flags_type) {
+	Bit32u fill;
+	mf_functions[mf_functions_num].pos=(DRC_PTR_SIZE_IM)cache.pos;
+	fill = gen_fill_function_ptr(current_simple_function, flags_type);
+	if(fill == -1) {
+		mf_functions[mf_functions_num].insn = false;
+		mf_functions[mf_functions_num].fct_ptr = 0x0c000000+((((Bit32u)current_simple_function)>>2)&0x3ffffff);	// jal simple_func
+	} else {
+		mf_functions[mf_functions_num].insn = true;
+		mf_functions[mf_functions_num].fct_ptr = fill;
+	}
+	mf_functions_num++;
+}
 
+// enqueue this instruction, if later an instruction is encountered that
+// destroys all condition flags and the flags weren't needed in-between
+// this function can be replaced by a simpler one as well
+static INLINE void InvalidateFlagsPartially(void* current_simple_function,DRC_PTR_SIZE_IM cpos, Bitu flags_type) {
+	Bit32u fill;
+	mf_functions[mf_functions_num].pos=cpos;
+	fill = gen_fill_function_ptr(current_simple_function, flags_type);
+	if(fill == -1) {
+		mf_functions[mf_functions_num].insn = false;
+		mf_functions[mf_functions_num].fct_ptr = 0x0c000000+((((Bit32u)current_simple_function)>>2)&0x3ffffff);	// jal simple_func
+	} else {
+		mf_functions[mf_functions_num].insn = true;
+		mf_functions[mf_functions_num].fct_ptr = fill;
+	}
+	mf_functions_num++;
+}
+#else
 // flags optimization functions
 // they try to find out if a function can be replaced by another
 // one that does not generate any flags at all
 
-static Bitu mf_functions_num=0;
 static struct {
 	Bit8u* pos;
 	void* fct_ptr;
@@ -1094,7 +1203,7 @@
 	mf_functions_num++;
 #endif
 }
-
+#endif
 // the current function needs the condition flags thus reset the queue
 static void AcquireFlags(Bitu flags_mask) {
 #ifdef DRC_FLAGS_INVALIDATION
diff -ru dosbox-0.71.orig/src/cpu/core_dynrec/decoder_opcodes.h dosbox-0.71/src/cpu/core_dynrec/decoder_opcodes.h
--- dosbox-0.71.orig/src/cpu/core_dynrec/decoder_opcodes.h	2007-07-21 03:46:49.000000000 -0500
+++ dosbox-0.71/src/cpu/core_dynrec/decoder_opcodes.h	2007-08-22 12:43:12.093750000 -0500
@@ -34,7 +34,8 @@
 		dyn_fill_ea(FC_ADDR);
 		gen_protect_addr_reg();
 		dyn_read_byte_canuseword(FC_ADDR,FC_OP1);
-		gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1));
+		//gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1));
+		gen_load_param_mem_byte((Bitu)DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1),1,true);
 		dyn_dop_byte_gencall(op);
 
 		if ((op!=DOP_CMP) && (op!=DOP_TEST)) {
@@ -43,7 +44,8 @@
 		}
 	} else {
 		gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1));
-		gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1));
+		//gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1));
+		gen_load_param_mem_byte((Bitu)DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1),1,true);
 		dyn_dop_byte_gencall(op);
 		if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1));
 	}
@@ -97,12 +99,14 @@
 	if (decode.modrm.mod<3) {
 		dyn_fill_ea(FC_ADDR);
 		dyn_read_byte_canuseword(FC_ADDR,FC_OP2);
-		gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1));
+		//gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1));
+		gen_load_param_mem_byte((Bitu)DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1),0,true);
 		dyn_dop_byte_gencall(op);
 		if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1));
 	} else {
 		gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1));
-		gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1));
+		//gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1));
+		gen_load_param_mem_byte((Bitu)DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1),0,true);
 		dyn_dop_byte_gencall(op);
 		if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1));
 	}
@@ -126,7 +130,8 @@
 		dyn_fill_ea(FC_ADDR);
 		dyn_read_word(FC_ADDR,FC_OP1,decode.big_op);
 		gen_protect_addr_reg();
-		gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op);
+		//gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op);
+		gen_load_param_mem((Bitu)DRCD_REG_WORD(decode.modrm.reg,decode.big_op),1,true,decode.big_op);
 		dyn_dop_word_gencall(op,decode.big_op);
 		if ((op!=DOP_CMP) && (op!=DOP_TEST)) {
 			gen_restore_addr_reg();
@@ -134,7 +139,8 @@
 		}
 	} else {
 		gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op);
-		gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op);
+		//gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op);
+		gen_load_param_mem((Bitu)DRCD_REG_WORD(decode.modrm.reg,decode.big_op),1,true,decode.big_op);
 		dyn_dop_word_gencall(op,decode.big_op);
 		if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op);
 	}
@@ -200,7 +206,8 @@
 		dyn_fill_ea(FC_ADDR);
 		gen_protect_addr_reg();
 		dyn_read_word(FC_ADDR,FC_OP2,decode.big_op);
-		gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op);
+		//gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op);
+		gen_load_param_mem((Bitu)DRCD_REG_WORD(decode.modrm.reg,decode.big_op),0,true,decode.big_op);
 		dyn_dop_word_gencall(op,decode.big_op);
 		if ((op!=DOP_CMP) && (op!=DOP_TEST)) {
 			gen_restore_addr_reg();
@@ -208,7 +215,8 @@
 		}
 	} else {
 		gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op);
-		gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op);
+		//gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op);
+		gen_load_param_mem((Bitu)DRCD_REG_WORD(decode.modrm.reg,decode.big_op),0,true,decode.big_op);
 		dyn_dop_word_gencall(op,decode.big_op);
 		if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op);
 	}
@@ -228,7 +236,8 @@
 
 static void dyn_dop_byte_imm(DualOps op,Bit8u reg,Bit8u idx) {
 	gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(reg,idx));
-	gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb());
+	//gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb());
+	gen_load_param_imm(decode_fetchb(),1,true);
 	dyn_dop_byte_gencall(op);
 	if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(reg,idx));
 }
@@ -237,9 +246,11 @@
 	gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(reg,idx));
 	Bitu val;
 	if (decode_fetchb_imm(val)) {
-		gen_mov_byte_to_reg_low_canuseword(FC_OP2,(void*)val);
+		//gen_mov_byte_to_reg_low_canuseword(FC_OP2,(void*)val);
+		gen_load_param_mem_byte(val,1,true);
 	} else {
-		gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,(Bit8u)val);
+		//gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,(Bit8u)val);
+		gen_load_param_imm((Bit8u)val,1,true);
 	}
 	dyn_dop_byte_gencall(op);
 	if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(reg,idx));
@@ -249,17 +260,20 @@
 	Bitu val;
 	if (decode.big_op) {
 		if (decode_fetchd_imm(val)) {
-			gen_mov_word_to_reg(FC_OP2,(void*)val,true);
+			//gen_mov_word_to_reg(FC_OP2,(void*)val,true);
+			gen_load_param_mem(val,1,true,true);
 			return;
 		}
 	} else {
 		if (decode_fetchw_imm(val)) {
-			gen_mov_word_to_reg(FC_OP2,(void*)val,false);
+			//gen_mov_word_to_reg(FC_OP2,(void*)val,false);
+			gen_load_param_mem(val,1,true,false);
 			return;
 		}
 	}
-	if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)val);
-	else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)val);
+	//if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)val);
+	//else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)val);
+	gen_load_param_imm(val,1,true);
 }
 
 static void dyn_dop_word_imm(DualOps op,Bit8u reg) {
@@ -271,8 +285,9 @@
 
 static void dyn_dop_word_imm_old(DualOps op,Bit8u reg,Bitu imm) {
 	gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op);
-	if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm);
-	else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)imm);
+	/*if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm);
+	else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)imm);*/
+	gen_load_param_imm(imm,1,true);
 	dyn_dop_word_gencall(op,decode.big_op);
 	if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op);
 }
@@ -304,7 +319,8 @@
 
 
 static void dyn_sop_word(SingleOps op,Bit8u reg) {
-	gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op);
+	//gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op);
+	gen_load_param_mem((Bitu)DRCD_REG_WORD(reg,decode.big_op),0,true,decode.big_op);
 	dyn_sop_word_gencall(op,decode.big_op);
 	gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op);
 }
@@ -406,7 +422,8 @@
 }
 
 static void dyn_push_reg(Bit8u reg) {
-	gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op);
+	//gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op);
+	gen_load_param_mem((Bitu)DRCD_REG_WORD(reg,decode.big_op),0,true,decode.big_op);
 	if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword);
 	else gen_call_function_raw((void*)&dynrec_push_word);
 }
@@ -418,17 +435,20 @@
 }
 
 static void dyn_push_byte_imm(Bit8s imm) {
-	gen_mov_dword_to_reg_imm(FC_OP1,(Bit32u)imm);
+	//gen_mov_dword_to_reg_imm(FC_OP1,(Bit32u)imm);
+	gen_load_param_imm((Bit32u)imm,0,true);
 	if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword);
 	else gen_call_function_raw((void*)&dynrec_push_word);
 }
 
 static void dyn_push_word_imm(Bitu imm) {
 	if (decode.big_op) {
-		gen_mov_dword_to_reg_imm(FC_OP1,imm);
+		//gen_mov_dword_to_reg_imm(FC_OP1,imm);
+		gen_load_param_imm(imm,0,true);
 		gen_call_function_raw((void*)&dynrec_push_dword);
 	} else {
-		gen_mov_word_to_reg_imm(FC_OP1,(Bit16u)imm);
+		//gen_mov_word_to_reg_imm(FC_OP1,(Bit16u)imm);
+		gen_load_param_imm((Bit16u)imm,0,true);
 		gen_call_function_raw((void*)&dynrec_push_word);
 	}
 }
@@ -559,7 +579,8 @@
 		dyn_fill_ea(FC_ADDR);
 		gen_protect_addr_reg();
 		dyn_read_byte_canuseword(FC_ADDR,FC_OP1);
-		gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb());
+		//gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb());
+		gen_load_param_imm(decode_fetchb(),1,true);
 		dyn_dop_byte_gencall(op);
 
 		if ((op!=DOP_CMP) && (op!=DOP_TEST)) {
@@ -583,8 +604,9 @@
 			dyn_prep_word_imm(FC_OP2);
 		} else {
 			Bits imm=(Bit8s)decode_fetchb(); 
-			if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm);
-			else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)imm);
+			//if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm);
+			//else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)imm);
+			gen_load_param_imm(imm,1,true);
 		}
 
 		dyn_dop_word_gencall(op,decode.big_op);
@@ -615,13 +637,15 @@
 	}
 	switch (type) {
 	case grp2_1:
-		gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,1);
+		//gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,1);
+		gen_load_param_imm(1,1,true);
 		dyn_shift_byte_gencall((ShiftOps)decode.modrm.reg);
 		break;
 	case grp2_imm: {
 		Bit8u imm=decode_fetchb();
 		if (imm) {
-			gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,imm&0x1f);
+			//gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,imm&0x1f);
+			gen_load_param_imm(imm&0x1f,1,true);
 			dyn_shift_byte_gencall((ShiftOps)decode.modrm.reg);
 		} else return;
 		}
@@ -651,7 +675,8 @@
 	}
 	switch (type) {
 	case grp2_1:
-		gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,1);
+		//gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,1);
+		gen_load_param_imm(1,1,true);
 		dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op);
 		break;
 	case grp2_imm: {
@@ -664,7 +689,8 @@
 		}
 		Bit8u imm=(Bit8u)val;
 		if (imm) {
-			gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,imm&0x1f);
+			//gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,imm&0x1f);
+			gen_load_param_imm(imm&0x1f,1,true);
 			dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op);
 		} else return;
 		}
@@ -691,11 +717,13 @@
 		if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg();
 		dyn_read_byte_canuseword(FC_ADDR,FC_OP1);
 	} else {
-		gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1));
+		if ((decode.modrm.reg>=2)) gen_load_param_mem_byte((Bitu)DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1),0,true);
+		else gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1));
 	}
 	switch (decode.modrm.reg) {
 	case 0x0:	// test eb,ib
-		gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb());
+		//gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb());
+		gen_load_param_imm(decode_fetchb(),1,true);
 		dyn_dop_byte_gencall(DOP_TEST);
 		return;
 	case 0x2:	// NOT Eb
@@ -735,12 +763,15 @@
 		if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg();
 		dyn_read_word(FC_ADDR,FC_OP1,decode.big_op);
 	} else {
-		gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op);
+		if ((decode.modrm.reg>=2)) gen_load_param_mem((Bitu)DRCD_REG_WORD(decode.modrm.rm,decode.big_op),0,true,decode.big_op);
+		else gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op);
 	}
 	switch (decode.modrm.reg) {
 	case 0x0:	// test ev,iv
-		if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,decode_fetchd());
-		else gen_mov_word_to_reg_imm(FC_OP2,decode_fetchw());
+		if (decode.big_op) //gen_mov_dword_to_reg_imm(FC_OP2,decode_fetchd());
+			gen_load_param_imm(decode_fetchd(),1,true);
+		else //gen_mov_word_to_reg_imm(FC_OP2,decode_fetchw());
+			gen_load_param_imm(decode_fetchw(),1,true);
 		dyn_dop_word_gencall(DOP_TEST,decode.big_op);
 		return;
 	case 0x2:	// NOT Ev
@@ -791,7 +822,8 @@
 			gen_restore_addr_reg();
 			dyn_write_byte(FC_ADDR,FC_RETOP);
 		} else {
-			gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1));
+			//gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1));
+			gen_load_param_mem_byte((Bitu)DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1),0,true);
 			dyn_sop_byte_gencall(decode.modrm.reg==0 ? SOP_INC : SOP_DEC);
 			gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1));
 		}
@@ -817,7 +849,8 @@
 		if ((decode.modrm.reg<2) || (decode.modrm.reg==3) || (decode.modrm.reg==5))  gen_protect_addr_reg();
 		dyn_read_word(FC_ADDR,FC_OP1,decode.big_op);
 	} else {
-		gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op);
+		if ((decode.modrm.reg<2) || (decode.modrm.reg==6)) gen_load_param_mem((Bitu)DRCD_REG_WORD(decode.modrm.rm,decode.big_op),0,true,decode.big_op);
+		else gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op);
 	}
 	switch (decode.modrm.reg) {
 	case 0x0://INC Ev
diff -ru dosbox-0.71.orig/src/cpu/core_dynrec/dyn_fpu.h dosbox-0.71/src/cpu/core_dynrec/dyn_fpu.h
--- dosbox-0.71.orig/src/cpu/core_dynrec/dyn_fpu.h	2007-07-22 13:48:54.000000000 -0500
+++ dosbox-0.71/src/cpu/core_dynrec/dyn_fpu.h	2007-08-01 13:06:07.890625000 -0500
@@ -47,6 +47,8 @@
 
 #if C_FPU_X86
 #include "../../fpu/fpu_instructions_x86.h"
+#elif defined(PSP)
+#include "../../fpu/fpu_instructions_vfpu.h"
 #else
 #include "../../fpu/fpu_instructions.h"
 #endif
diff -ru dosbox-0.71.orig/src/cpu/core_dynrec/operators.h dosbox-0.71/src/cpu/core_dynrec/operators.h
--- dosbox-0.71.orig/src/cpu/core_dynrec/operators.h	2007-07-22 13:48:54.000000000 -0500
+++ dosbox-0.71/src/cpu/core_dynrec/operators.h	2007-08-21 21:44:56.531250000 -0500
@@ -393,41 +393,41 @@
 static void dyn_dop_byte_gencall(DualOps op) {
 	switch (op) {
 		case DOP_ADD:
-			InvalidateFlags((void*)&dynrec_add_byte_simple,t_ADDb);
+			InvalidateFlags((void*)&dynrec_add_byte_simple,gen_get_cpos(),t_ADDb);
 			gen_call_function_raw((void*)&dynrec_add_byte);
 			break;
 		case DOP_ADC:
 			AcquireFlags(FLAG_CF);
-			InvalidateFlagsPartially((void*)&dynrec_adc_byte_simple,t_ADCb);
+			InvalidateFlagsPartially((void*)&dynrec_adc_byte_simple,gen_get_cpos(),t_ADCb);
 			gen_call_function_raw((void*)&dynrec_adc_byte);
 			break;
 		case DOP_SUB:
-			InvalidateFlags((void*)&dynrec_sub_byte_simple,t_SUBb);
+			InvalidateFlags((void*)&dynrec_sub_byte_simple,gen_get_cpos(),t_SUBb);
 			gen_call_function_raw((void*)&dynrec_sub_byte);
 			break;
 		case DOP_SBB:
 			AcquireFlags(FLAG_CF);
-			InvalidateFlagsPartially((void*)&dynrec_sbb_byte_simple,t_SBBb);
+			InvalidateFlagsPartially((void*)&dynrec_sbb_byte_simple,gen_get_cpos(),t_SBBb);
 			gen_call_function_raw((void*)&dynrec_sbb_byte);
 			break;
 		case DOP_CMP:
-			InvalidateFlags((void*)&dynrec_cmp_byte_simple,t_CMPb);
+			InvalidateFlags((void*)&dynrec_cmp_byte_simple,gen_get_cpos(),t_CMPb);
 			gen_call_function_raw((void*)&dynrec_cmp_byte);
 			break;
 		case DOP_XOR:
-			InvalidateFlags((void*)&dynrec_xor_byte_simple,t_XORb);
+			InvalidateFlags((void*)&dynrec_xor_byte_simple,gen_get_cpos(),t_XORb);
 			gen_call_function_raw((void*)&dynrec_xor_byte);
 			break;
 		case DOP_AND:
-			InvalidateFlags((void*)&dynrec_and_byte_simple,t_ANDb);
+			InvalidateFlags((void*)&dynrec_and_byte_simple,gen_get_cpos(),t_ANDb);
 			gen_call_function_raw((void*)&dynrec_and_byte);
 			break;
 		case DOP_OR:
-			InvalidateFlags((void*)&dynrec_or_byte_simple,t_ORb);
+			InvalidateFlags((void*)&dynrec_or_byte_simple,gen_get_cpos(),t_ORb);
 			gen_call_function_raw((void*)&dynrec_or_byte);
 			break;
 		case DOP_TEST:
-			InvalidateFlags((void*)&dynrec_test_byte_simple,t_TESTb);
+			InvalidateFlags((void*)&dynrec_test_byte_simple,gen_get_cpos(),t_TESTb);
 			gen_call_function_raw((void*)&dynrec_test_byte);
 			break;
 		default: IllegalOptionDynrec("dyn_dop_byte_gencall");
@@ -438,41 +438,41 @@
 	if (dword) {
 		switch (op) {
 			case DOP_ADD:
-				InvalidateFlags((void*)&dynrec_add_dword_simple,t_ADDd);
+				InvalidateFlags((void*)&dynrec_add_dword_simple,gen_get_cpos(),t_ADDd);
 				gen_call_function_raw((void*)&dynrec_add_dword);
 				break;
 			case DOP_ADC:
 				AcquireFlags(FLAG_CF);
-				InvalidateFlagsPartially((void*)&dynrec_adc_dword_simple,t_ADCd);
+				InvalidateFlagsPartially((void*)&dynrec_adc_dword_simple,gen_get_cpos(),t_ADCd);
 				gen_call_function_raw((void*)&dynrec_adc_dword);
 				break;
 			case DOP_SUB:
-				InvalidateFlags((void*)&dynrec_sub_dword_simple,t_SUBd);
+				InvalidateFlags((void*)&dynrec_sub_dword_simple,gen_get_cpos(),t_SUBd);
 				gen_call_function_raw((void*)&dynrec_sub_dword);
 				break;
 			case DOP_SBB:
 				AcquireFlags(FLAG_CF);
-				InvalidateFlagsPartially((void*)&dynrec_sbb_dword_simple,t_SBBd);
+				InvalidateFlagsPartially((void*)&dynrec_sbb_dword_simple,gen_get_cpos(),t_SBBd);
 				gen_call_function_raw((void*)&dynrec_sbb_dword);
 				break;
 			case DOP_CMP:
-				InvalidateFlags((void*)&dynrec_cmp_dword_simple,t_CMPd);
+				InvalidateFlags((void*)&dynrec_cmp_dword_simple,gen_get_cpos(),t_CMPd);
 				gen_call_function_raw((void*)&dynrec_cmp_dword);
 				break;
 			case DOP_XOR:
-				InvalidateFlags((void*)&dynrec_xor_dword_simple,t_XORd);
+				InvalidateFlags((void*)&dynrec_xor_dword_simple,gen_get_cpos(),t_XORd);
 				gen_call_function_raw((void*)&dynrec_xor_dword);
 				break;
 			case DOP_AND:
-				InvalidateFlags((void*)&dynrec_and_dword_simple,t_ANDd);
+				InvalidateFlags((void*)&dynrec_and_dword_simple,gen_get_cpos(),t_ANDd);
 				gen_call_function_raw((void*)&dynrec_and_dword);
 				break;
 			case DOP_OR:
-				InvalidateFlags((void*)&dynrec_or_dword_simple,t_ORd);
+				InvalidateFlags((void*)&dynrec_or_dword_simple,gen_get_cpos(),t_ORd);
 				gen_call_function_raw((void*)&dynrec_or_dword);
 				break;
 			case DOP_TEST:
-				InvalidateFlags((void*)&dynrec_test_dword_simple,t_TESTd);
+				InvalidateFlags((void*)&dynrec_test_dword_simple,gen_get_cpos(),t_TESTd);
 				gen_call_function_raw((void*)&dynrec_test_dword);
 				break;
 			default: IllegalOptionDynrec("dyn_dop_dword_gencall");
@@ -480,41 +480,41 @@
 	} else {
 		switch (op) {
 			case DOP_ADD:
-				InvalidateFlags((void*)&dynrec_add_word_simple,t_ADDw);
+				InvalidateFlags((void*)&dynrec_add_word_simple,gen_get_cpos(),t_ADDw);
 				gen_call_function_raw((void*)&dynrec_add_word);
 				break;
 			case DOP_ADC:
 				AcquireFlags(FLAG_CF);
-				InvalidateFlagsPartially((void*)&dynrec_adc_word_simple,t_ADCw);
+				InvalidateFlagsPartially((void*)&dynrec_adc_word_simple,gen_get_cpos(),t_ADCw);
 				gen_call_function_raw((void*)&dynrec_adc_word);
 				break;
 			case DOP_SUB:
-				InvalidateFlags((void*)&dynrec_sub_word_simple,t_SUBw);
+				InvalidateFlags((void*)&dynrec_sub_word_simple,gen_get_cpos(),t_SUBw);
 				gen_call_function_raw((void*)&dynrec_sub_word);
 				break;
 			case DOP_SBB:
 				AcquireFlags(FLAG_CF);
-				InvalidateFlagsPartially((void*)&dynrec_sbb_word_simple,t_SBBw);
+				InvalidateFlagsPartially((void*)&dynrec_sbb_word_simple,gen_get_cpos(),t_SBBw);
 				gen_call_function_raw((void*)&dynrec_sbb_word);
 				break;
 			case DOP_CMP:
-				InvalidateFlags((void*)&dynrec_cmp_word_simple,t_CMPw);
+				InvalidateFlags((void*)&dynrec_cmp_word_simple,gen_get_cpos(),t_CMPw);
 				gen_call_function_raw((void*)&dynrec_cmp_word);
 				break;
 			case DOP_XOR:
-				InvalidateFlags((void*)&dynrec_xor_word_simple,t_XORw);
+				InvalidateFlags((void*)&dynrec_xor_word_simple,gen_get_cpos(),t_XORw);
 				gen_call_function_raw((void*)&dynrec_xor_word);
 				break;
 			case DOP_AND:
-				InvalidateFlags((void*)&dynrec_and_word_simple,t_ANDw);
+				InvalidateFlags((void*)&dynrec_and_word_simple,gen_get_cpos(),t_ANDw);
 				gen_call_function_raw((void*)&dynrec_and_word);
 				break;
 			case DOP_OR:
-				InvalidateFlags((void*)&dynrec_or_word_simple,t_ORw);
+				InvalidateFlags((void*)&dynrec_or_word_simple,gen_get_cpos(),t_ORw);
 				gen_call_function_raw((void*)&dynrec_or_word);
 				break;
 			case DOP_TEST:
-				InvalidateFlags((void*)&dynrec_test_word_simple,t_TESTw);
+				InvalidateFlags((void*)&dynrec_test_word_simple,gen_get_cpos(),t_TESTw);
 				gen_call_function_raw((void*)&dynrec_test_word);
 				break;
 			default: IllegalOptionDynrec("dyn_dop_word_gencall");
@@ -665,18 +665,18 @@
 static void dyn_sop_byte_gencall(SingleOps op) {
 	switch (op) {
 		case SOP_INC:
-			InvalidateFlagsPartially((void*)&dynrec_inc_byte_simple,t_INCb);
+			InvalidateFlagsPartially((void*)&dynrec_inc_byte_simple,gen_get_cpos(),t_INCb);
 			gen_call_function_raw((void*)&dynrec_inc_byte);
 			break;
 		case SOP_DEC:
-			InvalidateFlagsPartially((void*)&dynrec_dec_byte_simple,t_DECb);
+			InvalidateFlagsPartially((void*)&dynrec_dec_byte_simple,gen_get_cpos(),t_DECb);
 			gen_call_function_raw((void*)&dynrec_dec_byte);
 			break;
 		case SOP_NOT:
 			gen_call_function_raw((void*)&dynrec_not_byte);
 			break;
 		case SOP_NEG:
-			InvalidateFlags((void*)&dynrec_neg_byte_simple,t_NEGb);
+			InvalidateFlags((void*)&dynrec_neg_byte_simple,gen_get_cpos(),t_NEGb);
 			gen_call_function_raw((void*)&dynrec_neg_byte);
 			break;
 		default: IllegalOptionDynrec("dyn_sop_byte_gencall");
@@ -687,18 +687,18 @@
 	if (dword) {
 		switch (op) {
 			case SOP_INC:
-				InvalidateFlagsPartially((void*)&dynrec_inc_dword_simple,t_INCd);
+				InvalidateFlagsPartially((void*)&dynrec_inc_dword_simple,gen_get_cpos(),t_INCd);
 				gen_call_function_raw((void*)&dynrec_inc_dword);
 				break;
 			case SOP_DEC:
-				InvalidateFlagsPartially((void*)&dynrec_dec_dword_simple,t_DECd);
+				InvalidateFlagsPartially((void*)&dynrec_dec_dword_simple,gen_get_cpos(),t_DECd);
 				gen_call_function_raw((void*)&dynrec_dec_dword);
 				break;
 			case SOP_NOT:
 				gen_call_function_raw((void*)&dynrec_not_dword);
 				break;
 			case SOP_NEG:
-				InvalidateFlags((void*)&dynrec_neg_dword_simple,t_NEGd);
+				InvalidateFlags((void*)&dynrec_neg_dword_simple,gen_get_cpos(),t_NEGd);
 				gen_call_function_raw((void*)&dynrec_neg_dword);
 				break;
 			default: IllegalOptionDynrec("dyn_sop_dword_gencall");
@@ -706,18 +706,18 @@
 	} else {
 		switch (op) {
 			case SOP_INC:
-				InvalidateFlagsPartially((void*)&dynrec_inc_word_simple,t_INCw);
+				InvalidateFlagsPartially((void*)&dynrec_inc_word_simple,gen_get_cpos(),t_INCw);
 				gen_call_function_raw((void*)&dynrec_inc_word);
 				break;
 			case SOP_DEC:
-				InvalidateFlagsPartially((void*)&dynrec_dec_word_simple,t_DECw);
+				InvalidateFlagsPartially((void*)&dynrec_dec_word_simple,gen_get_cpos(),t_DECw);
 				gen_call_function_raw((void*)&dynrec_dec_word);
 				break;
 			case SOP_NOT:
 				gen_call_function_raw((void*)&dynrec_not_word);
 				break;
 			case SOP_NEG:
-				InvalidateFlags((void*)&dynrec_neg_word_simple,t_NEGw);
+				InvalidateFlags((void*)&dynrec_neg_word_simple,gen_get_cpos(),t_NEGw);
 				gen_call_function_raw((void*)&dynrec_neg_word);
 				break;
 			default: IllegalOptionDynrec("dyn_sop_word_gencall");
@@ -1113,11 +1113,11 @@
 static void dyn_shift_byte_gencall(ShiftOps op) {
 	switch (op) {
 		case SHIFT_ROL:
-			InvalidateFlagsPartially((void*)&dynrec_rol_byte_simple,t_ROLb);
+			InvalidateFlagsPartially((void*)&dynrec_rol_byte_simple,gen_get_cpos(),t_ROLb);
 			gen_call_function_raw((void*)&dynrec_rol_byte);
 			break;
 		case SHIFT_ROR:
-			InvalidateFlagsPartially((void*)&dynrec_ror_byte_simple,t_RORb);
+			InvalidateFlagsPartially((void*)&dynrec_ror_byte_simple,gen_get_cpos(),t_RORb);
 			gen_call_function_raw((void*)&dynrec_ror_byte);
 			break;
 		case SHIFT_RCL:
@@ -1130,15 +1130,15 @@
 			break;
 		case SHIFT_SHL:
 		case SHIFT_SAL:
-			InvalidateFlagsPartially((void*)&dynrec_shl_byte_simple,t_SHLb);
+			InvalidateFlagsPartially((void*)&dynrec_shl_byte_simple,gen_get_cpos(),t_SHLb);
 			gen_call_function_raw((void*)&dynrec_shl_byte);
 			break;
 		case SHIFT_SHR:
-			InvalidateFlagsPartially((void*)&dynrec_shr_byte_simple,t_SHRb);
+			InvalidateFlagsPartially((void*)&dynrec_shr_byte_simple,gen_get_cpos(),t_SHRb);
 			gen_call_function_raw((void*)&dynrec_shr_byte);
 			break;
 		case SHIFT_SAR:
-			InvalidateFlagsPartially((void*)&dynrec_sar_byte_simple,t_SARb);
+			InvalidateFlagsPartially((void*)&dynrec_sar_byte_simple,gen_get_cpos(),t_SARb);
 			gen_call_function_raw((void*)&dynrec_sar_byte);
 			break;
 		default: IllegalOptionDynrec("dyn_shift_byte_gencall");
@@ -1149,11 +1149,11 @@
 	if (dword) {
 		switch (op) {
 			case SHIFT_ROL:
-				InvalidateFlagsPartially((void*)&dynrec_rol_dword_simple,t_ROLd);
+				InvalidateFlagsPartially((void*)&dynrec_rol_dword_simple,gen_get_cpos(),t_ROLd);
 				gen_call_function_raw((void*)&dynrec_rol_dword);
 				break;
 			case SHIFT_ROR:
-				InvalidateFlagsPartially((void*)&dynrec_ror_dword_simple,t_RORd);
+				InvalidateFlagsPartially((void*)&dynrec_ror_dword_simple,gen_get_cpos(),t_RORd);
 				gen_call_function_raw((void*)&dynrec_ror_dword);
 				break;
 			case SHIFT_RCL:
@@ -1166,15 +1166,15 @@
 				break;
 			case SHIFT_SHL:
 			case SHIFT_SAL:
-				InvalidateFlagsPartially((void*)&dynrec_shl_dword_simple,t_SHLd);
+				InvalidateFlagsPartially((void*)&dynrec_shl_dword_simple,gen_get_cpos(),t_SHLd);
 				gen_call_function_raw((void*)&dynrec_shl_dword);
 				break;
 			case SHIFT_SHR:
-				InvalidateFlagsPartially((void*)&dynrec_shr_dword_simple,t_SHRd);
+				InvalidateFlagsPartially((void*)&dynrec_shr_dword_simple,gen_get_cpos(),t_SHRd);
 				gen_call_function_raw((void*)&dynrec_shr_dword);
 				break;
 			case SHIFT_SAR:
-				InvalidateFlagsPartially((void*)&dynrec_sar_dword_simple,t_SARd);
+				InvalidateFlagsPartially((void*)&dynrec_sar_dword_simple,gen_get_cpos(),t_SARd);
 				gen_call_function_raw((void*)&dynrec_sar_dword);
 				break;
 			default: IllegalOptionDynrec("dyn_shift_dword_gencall");
@@ -1182,11 +1182,11 @@
 	} else {
 		switch (op) {
 			case SHIFT_ROL:
-				InvalidateFlagsPartially((void*)&dynrec_rol_word_simple,t_ROLw);
+				InvalidateFlagsPartially((void*)&dynrec_rol_word_simple,gen_get_cpos(),t_ROLw);
 				gen_call_function_raw((void*)&dynrec_rol_word);
 				break;
 			case SHIFT_ROR:
-				InvalidateFlagsPartially((void*)&dynrec_ror_word_simple,t_RORw);
+				InvalidateFlagsPartially((void*)&dynrec_ror_word_simple,gen_get_cpos(),t_RORw);
 				gen_call_function_raw((void*)&dynrec_ror_word);
 				break;
 			case SHIFT_RCL:
@@ -1199,15 +1199,15 @@
 				break;
 			case SHIFT_SHL:
 			case SHIFT_SAL:
-				InvalidateFlagsPartially((void*)&dynrec_shl_word_simple,t_SHLw);
+				InvalidateFlagsPartially((void*)&dynrec_shl_word_simple,gen_get_cpos(),t_SHLw);
 				gen_call_function_raw((void*)&dynrec_shl_word);
 				break;
 			case SHIFT_SHR:
-				InvalidateFlagsPartially((void*)&dynrec_shr_word_simple,t_SHRw);
+				InvalidateFlagsPartially((void*)&dynrec_shr_word_simple,gen_get_cpos(),t_SHRw);
 				gen_call_function_raw((void*)&dynrec_shr_word);
 				break;
 			case SHIFT_SAR:
-				InvalidateFlagsPartially((void*)&dynrec_sar_word_simple,t_SARw);
+				InvalidateFlagsPartially((void*)&dynrec_sar_word_simple,gen_get_cpos(),t_SARw);
 				gen_call_function_raw((void*)&dynrec_sar_word);
 				break;
 			default: IllegalOptionDynrec("dyn_shift_word_gencall");
diff -ru dosbox-0.71.orig/src/cpu/core_dynrec/risc_mipsel32.h dosbox-0.71/src/cpu/core_dynrec/risc_mipsel32.h
--- dosbox-0.71.orig/src/cpu/core_dynrec/risc_mipsel32.h	2007-07-27 11:53:31.000000000 -0500
+++ dosbox-0.71/src/cpu/core_dynrec/risc_mipsel32.h	2007-08-20 23:15:40.062500000 -0500
@@ -79,31 +79,33 @@
 // save some state to improve code gen
 static bool temp1_valid = false;
 static Bit32u temp1_value;
+static Bit32u epilog_jump;
+static Bit8u *branch_ptr = NULL;
 
 // move a full register from reg_src to reg_dst
-static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) {
-	if(reg_src == reg_dst) return; 
+static bool gen_mov_regs(HostReg reg_dst,HostReg reg_src) {
+	if(reg_src == reg_dst) return false; 
 	cache_addw((reg_dst<<11)+0x21);      // addu reg_dst, $0, reg_src 
 	cache_addw(reg_src); 
+	return true;
 }
 
 // move a 32bit constant value into dest_reg
-static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) {
-	if(imm < 65536) {
-		cache_addw((Bit16u)imm);		// ori dest_reg, $0, imm
-		cache_addw(0x3400+dest_reg);
-	} else if(((Bit32s)imm < 0) && ((Bit32s)imm >= -32768)) {
-		cache_addw((Bit16u)imm);		// addiu dest_reg, $0, imm
-		cache_addw(0x2400+dest_reg);
-	} else if(!(imm & 0xffff)) {
+static Bit32u gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) {
+	Bit32u ret;
+	if(imm < 65536) 
+		ret = ((0x3400+dest_reg)<<16)+(Bit16u)imm;	// ori dest_reg, $0, imm
+	else if(((Bit32s)imm < 0) && ((Bit32s)imm >= -32768)) 
+		ret = ((0x2400+dest_reg)<<16)+(Bit16u)imm;	// addiu dest_reg, $0, imm
+	else if(!(imm & 0xffff)) 
+		ret = ((0x3c00+dest_reg)<<16)+(Bit16u)(imm>>16);	// lui dest_reg, %hi(imm)
+	else {
 		cache_addw((Bit16u)(imm >> 16));	// lui dest_reg, %hi(imm)
 		cache_addw(0x3c00+dest_reg);
-	} else {
-		cache_addw((Bit16u)(imm >> 16));	// lui dest_reg, %hi(imm)
-		cache_addw(0x3c00+dest_reg);
-		cache_addw((Bit16u)imm);		// ori dest_reg, dest_reg, %lo(imm)
-		cache_addw(0x3400+(dest_reg<<5)+dest_reg);
+		ret = ((0x3400+(dest_reg<<5)+dest_reg)<<16)+(Bit16u)imm;	// ori dest_reg, dest_reg, %lo(imm)
 	}
+	cache_addd(ret);
+	return ret;
 }
 
 // this is the only place temp1 should be modified
@@ -127,19 +129,16 @@
 
 // move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg
 // 16bit moves may destroy the upper 16bit of the destination register
-static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) {
-	Bit16s lohalf = gen_addr_temp1((Bit32u)data);
+static Bit32u gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) {
+	Bit16u lohalf = gen_addr_temp1((Bit32u)data);
+	Bit32u ret;
 	// alignment....
 	if (dword) {
 		if ((Bit32u)data & 3) {
 			cache_addw(lohalf+3);		// lwl dest_reg, 3(temp1)
 			cache_addw(0x8800+(temp1<<5)+dest_reg);
-			cache_addw(lohalf);		// lwr dest_reg, 0(temp1)
-			cache_addw(0x9800+(temp1<<5)+dest_reg);
-		} else {
-			cache_addw(lohalf);		// lw dest_reg, 0(temp1)
-			cache_addw(0x8C00+(temp1<<5)+dest_reg);
-		}
+			ret = ((0x9800+(temp1<<5)+dest_reg)<<16)+lohalf;	// lwr dest_reg, 0(temp1)
+		} else  ret = ((0x8C00+(temp1<<5)+dest_reg)<<16)+lohalf;	// lw dest_reg, 0(temp1)
 	} else {
 		if ((Bit32u)data & 1) {
 			cache_addw(lohalf);		// lbu dest_reg, 0(temp1)
@@ -147,19 +146,16 @@
 			cache_addw(lohalf+1);		// lbu temp2, 1(temp1)
 			cache_addw(0x9000+(temp1<<5)+temp2);
 #if (_MIPS_ISA==MIPS32R2) || defined(PSP)
-			cache_addw(0x7a04);		// ins dest_reg, temp2, 8, 8
-			cache_addw(0x7c00+(temp2<<5)+dest_reg);
+			ret = ((0x7c00+(temp2<<5)+dest_reg)<<16)+0x7a04;	// ins dest_reg, temp2, 8, 8
 #else
 			cache_addw((temp2<<11)+0x200);		// sll temp2, temp2, 8
 			cache_addw(temp2);
-			cache_addw((dest_reg<<11)+0x25);	// or dest_reg, temp2, dest_reg
-			cache_addw((temp2<<5)+dest_reg);
+			ret = (((temp2<<5)+dest_reg)<<16)+((dest_reg<<11)+0x25);	// or dest_reg, temp2, dest_reg
 #endif
-		} else {
-			cache_addw(lohalf);		// lhu dest_reg, 0(temp1);
-			cache_addw(0x9400+(temp1<<5)+dest_reg);
-		}
+		} else ret = ((0x9400+(temp1<<5)+dest_reg)<<16)+lohalf;	// lhu dest_reg, 0(temp1);
 	}
+	cache_addd(ret);
+	return ret;
 }
 
 // move a 16bit constant value into dest_reg
@@ -202,10 +198,11 @@
 // the upper 24bit of the destination register can be destroyed
 // this function does not use FC_OP1/FC_OP2 as dest_reg as these
 // registers might not be directly byte-accessible on some architectures
-static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) {
-	Bit16s lohalf = gen_addr_temp1((Bit32u)data);
-	cache_addw(lohalf);			// lbu dest_reg, 0(temp1)
-	cache_addw(0x9000+(temp1<<5)+dest_reg);
+static Bit32u gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) {
+	Bit16u lohalf = gen_addr_temp1((Bit32u)data);
+	Bit32u ret = ((0x9000+(temp1<<5)+dest_reg)<<16)+lohalf;	// lbu dest_reg, 0(temp1)
+	cache_addd(ret);
+	return ret;
 }
 
 // move an 8bit value from memory into dest_reg
@@ -372,41 +369,71 @@
 	if ((cache.pos ^ func) & 0xf0000000) LOG_MSG("jump overflow\n");
 #endif
 	temp1_valid = false;
-	cache_addd(0x0c000000+(((Bit32u)func>>2)&0x3ffffff));		// jal func
-	DELAY;
+	if(branch_ptr) {
+		*(Bit32u *)branch_ptr = 0x0c000000+(((Bit32u)func>>2)&0x3ffffff);
+		branch_ptr = NULL;
+	} else {
+		cache_addd(0x0c000000+(((Bit32u)func>>2)&0x3ffffff));		// jal func
+		DELAY;
+	}
 }
 
 // generate a call to a function with paramcount parameters
 // note: the parameters are loaded in the architecture specific way
 // using the gen_load_param_ functions below
 static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) {
-	Bit32u proc_addr = (Bit32u)cache.pos;
+	Bit32u proc_addr = (Bit32u)(branch_ptr?branch_ptr:cache.pos);
 	gen_call_function_raw(func);
 	return proc_addr;
 }
 
+static Bit32u INLINE gen_get_cpos() {
+	return (Bit32u)(branch_ptr?branch_ptr:cache.pos);
+}
+
 #ifdef __mips_eabi
 // max of 8 parameters in $a0-$a3 and $t0-$t3
 
 // load an immediate value as param'th function parameter
-static void INLINE gen_load_param_imm(Bitu imm,Bitu param) {
-	gen_mov_dword_to_reg_imm(param+4, imm);
+static void INLINE gen_load_param_imm(Bitu imm,Bitu param,bool last_param=false) {
+	Bit32u delay_op = gen_mov_dword_to_reg_imm(param+4, imm);
+	if(last_param) {
+		branch_ptr = cache.pos-4;
+		cache_addd(delay_op);
+	}
 }
 
 // load an address as param'th function parameter
-static void INLINE gen_load_param_addr(Bitu addr,Bitu param) {
-	gen_mov_dword_to_reg_imm(param+4, addr);
+static void INLINE gen_load_param_addr(Bitu addr,Bitu param,bool last_param=false) {
+	gen_load_param_imm(addr, param, last_param);
 }
 
 // load a host-register as param'th function parameter
-static void INLINE gen_load_param_reg(Bitu reg,Bitu param) {
-	gen_mov_regs(param+4, reg);
+static void INLINE gen_load_param_reg(Bitu reg,Bitu param,bool last_param=false) {
+	if(last_param) {
+		branch_ptr=cache.pos;
+		DELAY;		// placeholder
+	}
+	if(!gen_mov_regs(param+4, reg) && last_param) DELAY;
 }
 
 // load a value from memory as param'th function parameter
-static void INLINE gen_load_param_mem(Bitu mem,Bitu param) {
-	gen_mov_word_to_reg(param+4, (void *)mem, 1);
+static void INLINE gen_load_param_mem(Bitu mem,Bitu param,bool last_param=false,bool dword=true) {
+	Bit32u delay_op = gen_mov_word_to_reg(param+4, (void *)mem, dword);
+	if(last_param) {
+		branch_ptr = cache.pos-4;
+		cache_addd(delay_op);
+	}
 }
+
+static void INLINE gen_load_param_mem_byte(Bitu mem,Bitu param,bool last_param=false) {
+	Bit32u delay_op = gen_mov_byte_to_reg_low(param+4, (void *)mem);
+	if(last_param) {
+		branch_ptr = cache.pos-4;
+		cache_addd(delay_op);
+	}
+}
+
 #else
 	other mips abis
 #endif
@@ -537,17 +564,95 @@
 	cache_addd(0xafb00004);			// sw $s0, 4($sp)
 	cache_addd(0x00800008);			// jr $a0
 	cache_addd(0xafbf0000);			// sw $ra, 0($sp)
-}
-
-// return from a function
-static void gen_return_function(void) {
-	temp1_valid = false;
+	epilog_jump = 0x08000000+(((Bit32u)cache.pos>>2)&0x3ffffff);
 	cache_addd(0x8fbf0000);			// lw $ra, 0($sp)
 	cache_addd(0x8fb00004);			// lw $s0, 4($sp)
 	cache_addd(0x03e00008);			// jr $ra
 	cache_addd(0x27bd0010);			// addiu $sp, $sp, 16
 }
 
+static void gen_return_function(Bit16u retcode, bool ret_exception) {
+	temp1_valid = false;
+	cache_addd(epilog_jump);
+	if (!ret_exception) {
+		gen_mov_word_to_reg_imm(FC_RETOP,retcode);
+	} else DELAY;
+}
+
+#ifdef PSP
+// called when a call to a function can be replaced by a
+// call to a simpler function
+static INLINE Bit32u gen_fill_function_ptr(void* fct_ptr,Bitu flags_type) {
+	//Bit64u ret;
+	// try to avoid function calls but rather directly fill in code
+	switch (flags_type) {
+		case t_ADDb:
+		case t_ADDw:
+		case t_ADDd:
+			return 0x00851021;					// addu $v0, $a0, $a1
+		case t_ORb:
+		case t_ORw:
+		case t_ORd:
+			return 0x00851025;					// or $v0, $a0, $a1
+		case t_ANDb:
+		case t_ANDw:
+		case t_ANDd:
+			return 0x00851024;					// and $v0, $a0, $a1
+		case t_SUBb:
+		case t_SUBw:
+		case t_SUBd:
+			return 0x00851023;					// subu $v0, $a0, $a1
+		case t_XORb:
+		case t_XORw:
+		case t_XORd:
+			return 0x00851026;					// xor $v0, $a0, $a1
+		case t_CMPb:
+		case t_CMPw:
+		case t_CMPd:
+		case t_TESTb:
+		case t_TESTw:
+		case t_TESTd:
+			return 0;							// nop
+		case t_INCb:
+		case t_INCw:
+		case t_INCd:
+			return 0x24820001;					// addiu $v0, $a0, 1
+		case t_DECb:
+		case t_DECw:
+		case t_DECd:
+			return 0x2482ffff;					// addiu $v0, $a0, -1
+		case t_SHLb:
+		case t_SHLw:
+		case t_SHLd:
+			return 0x00a41004;					// sllv $v0, $a0, $a1
+		case t_SHRb:
+		case t_SHRw:
+		case t_SHRd:
+			return 0x00a41006;					// srlv $v0, $a0, $a1
+		case t_SARd:
+			return 0x00a41007;					// srav $v0, $a0, $a1
+#if (_MIPS_ISA==MIPS32R2) || defined(PSP)
+		/*case t_SARb:
+			ret = 0x7c042420;					// seb $a0, $a0
+			return (0x00a41007ll<<32)+ret;				// srav $v0, $a0, $a1
+		case t_SARw:
+			ret = 0x7c042620;					// seh $a0, $a0
+			return (0x00a41007ll<<32)+ret;				// srav $v0, $a0, $a1
+		case t_ROLd:
+			ret = 0x00052823;					// subu	$a1, $0, $a1
+			return (0x00a41046ll<<32)+ret;				// rotrv $v0, $a0, $a1*/
+		case t_RORd:
+			return 0x00a41046;					// rotrv $v0, $a0, $a1
+#endif
+		case t_NEGb:
+		case t_NEGw:
+		case t_NEGd:
+			return 0x00041023;					// subu $v0, $0, $a0
+		default:
+			return 	-1;
+	}
+}
+#else
 #ifdef DRC_FLAGS_INVALIDATION
 // called when a call to a function can be replaced by a
 // call to a simpler function
@@ -613,7 +718,7 @@
 			break;
 #if (_MIPS_ISA==MIPS32R2) || defined(PSP)
 		case t_RORd:
-			*(Bit32u*)pos=0x00a41046;					// rotr $v0, $a0, $a1
+			*(Bit32u*)pos=0x00a41046;					// rotrv $v0, $a0, $a1
 			break;
 #endif
 		case t_NEGb:
@@ -626,7 +731,8 @@
 			break;
 	}
 #else
-	*(Bit32u*)pos=0x0c000000+(((Bit32u)fct_ptr)>>2)&0x3ffffff);		// jal simple_func
+	*(Bit32u*)pos=0x0c000000+((((Bit32u)fct_ptr)>>2)&0x3ffffff);		// jal simple_func
 #endif
 }
 #endif
+#endif
diff -ru dosbox-0.71.orig/src/cpu/core_dynrec.cpp dosbox-0.71/src/cpu/core_dynrec.cpp
--- dosbox-0.71.orig/src/cpu/core_dynrec.cpp	2007-07-27 11:53:30.000000000 -0500
+++ dosbox-0.71/src/cpu/core_dynrec.cpp	2007-08-10 19:47:59.750000000 -0500
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <stddef.h>
 #include <stdlib.h>
+#include <malloc.h>
 
 #if defined (WIN32)
 #include <windows.h>
@@ -48,13 +49,18 @@
 #include "debug.h"
 #include "paging.h"
 #include "inout.h"
-#include "lazyflags.h"
 
 #define CACHE_MAXSIZE	(4096)
+#ifdef PSP
+#define CACHE_TOTAL		(1024*1024*5)
+#define CACHE_BLOCKS		(40*1024)
+#define CACHE_ALIGN		(4)
+#else
 #define CACHE_TOTAL		(1024*1024*8)
-#define CACHE_PAGES		(512)
 #define CACHE_BLOCKS	(128*1024)
 #define CACHE_ALIGN		(16)
+#endif
+#define CACHE_PAGES		(512)
 #define DYN_HASH_SHIFT	(4)
 #define DYN_PAGE_HASH	(4096>>DYN_HASH_SHIFT)
 #define DYN_LINKS		(16)
@@ -130,18 +136,19 @@
 	Bit32u protected_regs[8];	// space to save/restore register values
 } core_dynrec;
 
+#include "lazyflags.h"
 
 #include "core_dynrec/cache.h"
 
-#define X86			0x01
+#define X86		0x01
 #define X86_64		0x02
-#define MIPSEL32	0x03
+#define MIPSEL		0x03
 
 #if C_TARGETCPU == X86_64
 #include "core_dynrec/risc_x64.h"
 #elif C_TARGETCPU == X86
 #include "core_dynrec/risc_x86.h"
-#elif C_TARGETCPU == MIPSEL32
+#elif C_TARGETCPU == MIPSEL
 #include "core_dynrec/risc_mipsel32.h"
 #endif
 
@@ -152,7 +159,7 @@
 	// the last instruction was a control flow modifying instruction
 	Bitu temp_ip=SegPhys(cs)+reg_eip;
 	Bitu temp_page=temp_ip >> 12;
-	CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)paging.tlb.handler[temp_page];
+	CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)get_tlb_entry(temp_ip)->handler;
 	if (temp_handler->flags & PFLAG_HASCODE) {
 		// see if the target is an already translated block
 		block=temp_handler->FindCacheBlock(temp_ip & 4095);
diff -ru dosbox-0.71.orig/src/cpu/core_simple.cpp dosbox-0.71/src/cpu/core_simple.cpp
--- dosbox-0.71.orig/src/cpu/core_simple.cpp	2007-01-09 10:18:52.000000000 -0600
+++ dosbox-0.71/src/cpu/core_simple.cpp	2007-08-01 13:06:07.890625000 -0500
@@ -32,6 +32,9 @@
 #endif
 
 #include "paging.h"
+
+#ifdef SIMPLE
+
 #define SegBase(c)	SegPhys(c)
 #define LoadMb(off) mem_readb(off)
 #define LoadMw(off) mem_readw(off)
@@ -204,3 +207,5 @@
 void CPU_Core_Simple_Init(void) {
 
 }
+
+#endif
diff -ru dosbox-0.71.orig/src/cpu/cpu.cpp dosbox-0.71/src/cpu/cpu.cpp
--- dosbox-0.71.orig/src/cpu/cpu.cpp	2007-06-12 15:22:07.000000000 -0500
+++ dosbox-0.71/src/cpu/cpu.cpp	2007-08-10 14:48:38.437500000 -0500
@@ -22,7 +22,7 @@
 #include <sstream>
 #include "dosbox.h"
 #include "cpu.h"
-#include "memory.h"
+//#include "memory.h"
 #include "debug.h"
 #include "mapper.h"
 #include "setup.h"
@@ -43,11 +43,12 @@
 #endif
 #endif
 
-CPU_Regs cpu_regs;
-CPUBlock cpu;
+CPU_Regs cpu_regs __attribute__((aligned(64)));
+LazyFlags lflags;
+Bit32s CPU_Cycles = 0;
 Segments Segs;
+CPUBlock cpu;
 
-Bit32s CPU_Cycles = 0;
 Bit32s CPU_CycleLeft = 0;
 Bit32s CPU_CycleMax = 3000;
 Bit32s CPU_OldCycleMax = 3000;
@@ -60,6 +61,10 @@
 bool CPU_CycleAutoAdjust;
 Bitu CPU_AutoDetermineMode;
 
+#ifdef PSP
+bool autocycles=false;
+#endif
+
 void CPU_Core_Full_Init(void);
 void CPU_Core_Normal_Init(void);
 void CPU_Core_Simple_Init(void);
@@ -2071,8 +2076,12 @@
 
 		/* Init the cpu cores */
 		CPU_Core_Normal_Init();
+#ifdef SIMPLE
 		CPU_Core_Simple_Init();
+#endif
+#ifdef FULL
 		CPU_Core_Full_Init();
+#endif
 #if (C_DYNAMIC_X86)
 		CPU_Core_Dyn_X86_Init();
 #elif (C_DYNREC)
@@ -2092,6 +2101,11 @@
 		std::string str;
 		CommandLine cmd(0,section->Get_string("cycles"));
 		cmd.FindCommand(1,str);
+#ifdef PSP
+		autocycles = false;
+#endif
+		CPU_CycleUp=section->Get_int("cycleup");
+		CPU_CycleDown=section->Get_int("cycledown");
 
 		if (str=="max") {
 			CPU_CycleMax=0;
@@ -2150,6 +2164,11 @@
 						}
 					}
 				}
+#ifdef PSP
+			} else if (str=="sync") {
+				autocycles = true;
+				CPU_CycleMax = CPU_CycleUp;
+#endif				
 			} else {
 				int rmdval=0;
 				std::istringstream stream(str);
@@ -2158,14 +2177,14 @@
 			}
 			CPU_CycleAutoAdjust=false;
 		}
-		CPU_CycleUp=section->Get_int("cycleup");
-		CPU_CycleDown=section->Get_int("cycledown");
 		const char * core=section->Get_string("core");
 		cpudecoder=&CPU_Core_Normal_Run;
 		if (!strcasecmp(core,"normal")) {
 			cpudecoder=&CPU_Core_Normal_Run;
+#ifdef SIMPLE
 		} else if (!strcasecmp(core,"simple")) {
 			cpudecoder=&CPU_Core_Simple_Run;
+#endif
 		} else if (!strcasecmp(core,"full")) {
 			cpudecoder=&CPU_Core_Full_Run;
 		} 
diff -ru dosbox-0.71.orig/src/cpu/flags.cpp dosbox-0.71/src/cpu/flags.cpp
--- dosbox-0.71.orig/src/cpu/flags.cpp	2007-06-28 05:53:05.000000000 -0500
+++ dosbox-0.71/src/cpu/flags.cpp	2007-08-10 14:48:26.734375000 -0500
@@ -26,7 +26,7 @@
 #include "lazyflags.h"
 #include "pic.h"
 
-LazyFlags lflags;
+extern LazyFlags lflags;
 
 /* CF     Carry Flag -- Set on high-order bit carry or borrow; cleared
           otherwise.
diff -ru dosbox-0.71.orig/src/cpu/paging.cpp dosbox-0.71/src/cpu/paging.cpp
--- dosbox-0.71.orig/src/cpu/paging.cpp	2007-01-08 12:45:38.000000000 -0600
+++ dosbox-0.71/src/cpu/paging.cpp	2007-08-06 15:01:43.500000000 -0500
@@ -316,12 +316,22 @@
 	return paging.cr3;
 }
 
-void PAGING_InitTLB(void) {
+static INLINE void InitTLBInt(tlb_entry *bank) {
 	for (Bitu i=0;i<TLB_SIZE;i++) {
-		paging.tlb.read[i]=0;
-		paging.tlb.write[i]=0;
-		paging.tlb.handler[i]=&init_page_handler;
+		bank[i].read=0;
+		bank[i].write=0;
+		bank[i].handler=&init_page_handler;
 	}
+}
+
+void PAGING_InitTLBBank(tlb_entry **bank) {
+	*bank = (tlb_entry *)malloc(sizeof(tlb_entry)*TLB_SIZE);
+	if(!*bank) E_Exit("Out of Memory");
+	InitTLBInt(*bank);
+}
+
+void PAGING_InitTLB(void) {
+	InitTLBInt(paging.tlb);
 	paging.links.used=0;
 }
 
@@ -329,25 +339,28 @@
 	Bit32u * entries=&paging.links.entries[0];
 	for (;paging.links.used>0;paging.links.used--) {
 		Bitu page=*entries++;
-		paging.tlb.read[page]=0;
-		paging.tlb.write[page]=0;
-		paging.tlb.handler[page]=&init_page_handler;
+		tlb_entry *entry = get_tlb_entry(page<<12);
+		entry->read=0;
+		entry->write=0;
+		entry->handler=&init_page_handler;
 	}
 	paging.links.used=0;
 }
 
 void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) {
+	tlb_entry *entry = get_tlb_entry(lin_page<<12);
 	for (;pages>0;pages--) {
-		paging.tlb.read[lin_page]=0;
-		paging.tlb.write[lin_page]=0;
-		paging.tlb.handler[lin_page]=&init_page_handler;
+		entry->read=0;
+		entry->write=0;
+		entry->handler=&init_page_handler;
 	}
 }
 
 void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) {
 	PageHandler * handler=MEM_GetPageHandler(phys_page);
 	Bitu lin_base=lin_page << 12;
-	if (lin_page>=TLB_SIZE || phys_page>=TLB_SIZE) 
+	tlb_entry *entry = get_tlb_entry(lin_base);
+	if (lin_page>=(TLB_SIZE*(TLB_BANKS+1)) || phys_page>=(TLB_SIZE*(TLB_BANKS+1))) 
 		E_Exit("Illegal page");
 
 	if (paging.links.used>=PAGING_LINKS) {
@@ -355,22 +368,22 @@
 		PAGING_ClearTLB();
 	}
 
-	paging.tlb.phys_page[lin_page]=phys_page;
-	if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=handler->GetHostReadPt(phys_page)-lin_base;
-	else paging.tlb.read[lin_page]=0;
-	if (handler->flags & PFLAG_WRITEABLE) paging.tlb.write[lin_page]=handler->GetHostWritePt(phys_page)-lin_base;
-	else paging.tlb.write[lin_page]=0;
+	entry->phys_page=phys_page;
+	if (handler->flags & PFLAG_READABLE) entry->read=handler->GetHostReadPt(phys_page)-lin_base;
+	else entry->read=0;
+	if (handler->flags & PFLAG_WRITEABLE) entry->write=handler->GetHostWritePt(phys_page)-lin_base;
+	else entry->write=0;
 
 	paging.links.entries[paging.links.used++]=lin_page;
-	paging.tlb.handler[lin_page]=handler;
+	entry->handler=handler;
 }
 
 void PAGING_MapPage(Bitu lin_page,Bitu phys_page) {
 	if (lin_page<LINK_START) {
 		paging.firstmb[lin_page]=phys_page;
-		paging.tlb.read[lin_page]=0;
-		paging.tlb.write[lin_page]=0;
-		paging.tlb.handler[lin_page]=&init_page_handler;
+		paging.tlb[lin_page].read=0;
+		paging.tlb[lin_page].write=0;
+		paging.tlb[lin_page].handler=&init_page_handler;
 	} else {
 		PAGING_LinkPage(lin_page,phys_page);
 	}
@@ -394,12 +407,14 @@
 	if (!enabled) {
 //		LOG(LOG_PAGING,LOG_NORMAL)("Disabled");
 	} else {
+#ifdef SIMPLE
 		if (cpudecoder==CPU_Core_Simple_Run) {
 //			LOG_MSG("CPU core simple won't run this game,switching to normal");
 			cpudecoder=CPU_Core_Normal_Run;
 			CPU_CycleLeft+=CPU_Cycles;
 			CPU_Cycles=0;
 		}
+#endif
 //		LOG(LOG_PAGING,LOG_NORMAL)("Enabled");
 		PAGING_SetDirBase(paging.cr3);
 	}
diff -ru dosbox-0.71.orig/src/dos/cdrom.cpp dosbox-0.71/src/dos/cdrom.cpp
--- dosbox-0.71.orig/src/dos/cdrom.cpp	2007-04-15 07:13:16.000000000 -0500
+++ dosbox-0.71/src/dos/cdrom.cpp	2007-08-01 13:06:07.906250000 -0500
@@ -26,10 +26,12 @@
 #include <unistd.h>
 #include <dirent.h>
 #include "dosbox.h"
-#include "SDL.h"
 #include "support.h"
 #include "cdrom.h"
 
+#ifdef USE_SDL
+#include "SDL.h"
+
 CDROM_Interface_SDL::CDROM_Interface_SDL(void) 
 {
 	driveID		= 0;
@@ -155,6 +157,8 @@
 	return success;
 };	
 
+#endif
+
 int CDROM_GetMountType(char* path, int forceCD)
 // 0 - physical CDROM
 // 1 - Iso file
@@ -170,6 +174,7 @@
 	upcase(buffer);
 #endif
 
+#ifdef USE_SDL
 	int num = SDL_CDNumDrives();
 	// If cd drive is forced then check if its in range and return 0
 	if ((forceCD>=0) && (forceCD<num)) {
@@ -182,7 +187,7 @@
 		cdName = SDL_CDName(i);
 		if (strcmp(buffer,cdName)==0) return 0;
 	};
-	
+#endif
 	// Detect ISO
 	struct stat file_stat;
 	if ((stat(path, &file_stat) == 0) && S_ISREG(file_stat.st_mode)) return 1; 
diff -ru dosbox-0.71.orig/src/dos/cdrom.h dosbox-0.71/src/dos/cdrom.h
--- dosbox-0.71.orig/src/dos/cdrom.h	2007-06-14 03:23:46.000000000 -0500
+++ dosbox-0.71/src/dos/cdrom.h	2007-08-01 13:06:07.906250000 -0500
@@ -13,13 +13,25 @@
 #include "dosbox.h"
 #include "mem.h"
 #include "mixer.h"
+#ifdef USE_SDL
 #include "SDL.h"
 #include "SDL_thread.h"
 
 #if defined(C_SDL_SOUND)
 #include "SDL_sound.h"
 #endif
-
+#else
+#define MSF_TO_FRAMES(M, S, F)	((M)*60*CD_FPS+(S)*CD_FPS+(F))
+#define CD_FPS	75
+#define FRAMES_TO_MSF(f, M,S,F)	{					\
+	int value = f;							\
+	*(F) = value%CD_FPS;						\
+	value /= CD_FPS;						\
+	*(S) = value%60;						\
+	value /= 60;							\
+	*(M) = value;							\
+}
+#endif
 #define RAW_SECTOR_SIZE		2352
 #define COOKED_SECTOR_SIZE	2048
 
@@ -59,7 +71,7 @@
 	
 	virtual void	InitNewMedia		(void) {};
 };	
-
+#ifdef USE_SDL
 class CDROM_Interface_SDL : public CDROM_Interface
 {
 public:
@@ -87,7 +99,7 @@
 	int		driveID;
 	Uint32	oldLeadOut;
 };
-
+#endif
 class CDROM_Interface_Fake : public CDROM_Interface
 {
 public:
@@ -180,7 +192,9 @@
 static  struct imagePlayer {
 		CDROM_Interface_Image *cd;
 		MixerChannel   *channel;
+#ifdef USE_SDL
 		SDL_mutex 	*mutex;
+#endif
 		Bit8u   buffer[8192];
 		int     bufLen;
 		int     currFrame;	
diff -ru dosbox-0.71.orig/src/dos/cdrom_image.cpp dosbox-0.71/src/dos/cdrom_image.cpp
--- dosbox-0.71.orig/src/dos/cdrom_image.cpp	2007-06-12 15:22:08.000000000 -0500
+++ dosbox-0.71/src/dos/cdrom_image.cpp	2007-08-07 22:05:41.953125000 -0500
@@ -90,7 +90,7 @@
 		if (!success) return false;
 	}
 	if (lastSeek != (seek - count)) {
-		int success = Sound_Seek(sample, (int)((double)(seek) / 176.4f));
+		int success = Sound_Seek(sample, (int)((float)(seek) / 176.4f));
 		if (!success) return false;
 	}
 	lastSeek = seek;
@@ -114,7 +114,7 @@
 	while (true) {
 		int success = Sound_Seek(sample, (unsigned int)(shift + time));
 		if (!success) {
-			if (time == 1) return lround((double)shift * 176.4f);
+			if (time == 1) return lround((float)shift * 176.4f);
 			shift += time >> 1;
 			time = 1;
 		} else {
@@ -136,11 +136,13 @@
 {
 	images[subUnit] = this;
 	if (refCount == 0) {
+#ifdef USE_SDL
 		player.mutex = SDL_CreateMutex();
 		if (!player.channel) {
 			player.channel = MIXER_AddChannel(&CDAudioCallBack, 44100, "CDAUDIO");
 		}
 		player.channel->Enable(true);
+#endif
 	}
 	refCount++;
 }
@@ -151,8 +153,10 @@
 	if (player.cd == this) player.cd = NULL;
 	ClearTracks();
 	if (refCount == 0) {
+#ifdef USE_SDL
 		SDL_DestroyMutex(player.mutex);
 		player.channel->Enable(false);
+#endif
 	}
 }
 
@@ -207,8 +211,7 @@
 	return true;
 }
 
-bool CDROM_Interface_Image::GetAudioStatus(bool& playing, bool& pause)
-{
+bool CDROM_Interface_Image::GetAudioStatus(bool& playing, bool& pause) {
 	playing = player.isPlaying;
 	pause = player.isPaused;
 	return true;
@@ -224,6 +227,7 @@
 
 bool CDROM_Interface_Image::PlayAudioSector(unsigned long start,unsigned long len)
 {
+#ifdef USE_SDL // TODO: repair
 	SDL_mutexP(player.mutex);
 	player.cd = this;
 	player.currFrame = start;
@@ -231,6 +235,7 @@
 	player.isPlaying = true;
 	player.isPaused = false;
 	SDL_mutexV(player.mutex);
+#endif
 	return true;
 }
 
@@ -300,6 +305,7 @@
 
 void CDROM_Interface_Image::CDAudioCallBack(Bitu len)
 {
+#ifdef USE_SDL
 	len *= 4;       // 16 bit, stereo
 	if (!len) return;
 	if (!player.isPlaying || player.isPaused) {
@@ -327,6 +333,7 @@
 	player.channel->AddSamples_s16(len/4,(Bit16s *)player.buffer);
 	memmove(player.buffer, &player.buffer[len], player.bufLen - len);
 	player.bufLen -= len;
+#endif
 }
 
 bool CDROM_Interface_Image::LoadIsoFile(char* filename)
@@ -384,7 +391,7 @@
 	return (pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1);
 }
 
-#if defined(WIN32)
+#if defined(WIN32) || defined(PSP)
 static string dirname(char * file) {
 	char * sep = strrchr(file, '\\');
 	if (sep == NULL)
diff -ru dosbox-0.71.orig/src/dos/dos_keyboard_layout.cpp dosbox-0.71/src/dos/dos_keyboard_layout.cpp
--- dosbox-0.71.orig/src/dos/dos_keyboard_layout.cpp	2007-06-14 03:23:46.000000000 -0500
+++ dosbox-0.71/src/dos/dos_keyboard_layout.cpp	2007-08-07 14:26:32.671875000 -0500
@@ -27,6 +27,8 @@
 #include "drives.h"
 #include "dos_inc.h"
 
+#ifdef USE_ALT_KEYB
+
 #include "dos_codepages.h"
 #include "dos_keyboard_layout_data.h"
 
@@ -1056,3 +1058,8 @@
 	sec->AddDestroyFunction(&DOS_KeyboardLayout_ShutDown,true);
 //	MAPPER_AddHandler(switch_keyboard_layout,MK_f2,MMOD1|MMOD2,"sw_layout","Switch Layout");
 }
+
+#else
+void DOS_KeyboardLayout_Init(Section* sec)  {}
+bool DOS_LayoutKey(Bitu key, Bit8u flags1, Bit8u flags2, Bit8u flags3) {return false;}
+#endif
diff -ru dosbox-0.71.orig/src/dos/dos_mscdex.cpp dosbox-0.71/src/dos/dos_mscdex.cpp
--- dosbox-0.71.orig/src/dos/dos_mscdex.cpp	2007-07-20 13:22:28.000000000 -0500
+++ dosbox-0.71/src/dos/dos_mscdex.cpp	2007-08-01 13:06:07.906250000 -0500
@@ -282,7 +282,7 @@
 		// Always use IOCTL in Linux or OS/2
 		cdrom[numDrives] = new CDROM_Interface_Ioctl();
 		LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface.");
-#else
+#elif defined(USE_SDL)
 		// Default case windows and other oses
 		cdrom[numDrives] = new CDROM_Interface_SDL();
 		LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: SDL Interface.");
diff -ru dosbox-0.71.orig/src/dos/dos_programs.cpp dosbox-0.71/src/dos/dos_programs.cpp
--- dosbox-0.71.orig/src/dos/dos_programs.cpp	2007-07-02 09:10:27.000000000 -0500
+++ dosbox-0.71/src/dos/dos_programs.cpp	2007-08-07 14:25:18.328125000 -0500
@@ -103,7 +103,7 @@
 				}
 			return;
 		}
-	   
+#ifdef USE_SDL	  
 		// Show list of cdroms
 		if (cmd->FindExist("-cd",false)) {
 			int num = SDL_CDNumDrives();
@@ -113,7 +113,7 @@
 			};
 			return;
 		}
-
+#endif
 		/* Parse the command line */
 		/* if the command line is empty show current mounts */
 		if (!cmd->GetCount()) {
@@ -1185,6 +1185,7 @@
 	*make=new IMGMOUNT;
 }
 
+#ifdef USE_ALT_KEYB
 
 Bitu DOS_SwitchKeyboardLayout(const char* new_layout);
 Bitu DOS_LoadKeyboardLayout(const char * layoutname, Bit32s codepage, const char * codepagefile);
@@ -1248,7 +1249,259 @@
 static void KEYB_ProgramStart(Program * * make) {
 	*make=new KEYB;
 }
+#endif
+
+#ifdef PSP
+#include <pspctrl.h>
+#include <psppower.h>
+#include "keyboard.h"
+
+// INPUTMAP
+
+extern keymap inputmap[];
+extern bool control_map;
+extern bool joy_state;
+typedef struct keyinfo {
+	KBD_KEYS key;
+	char *ascii;
+} keyinfo;
+
+class INPUTMAP : public Program {
+public:
+	void Run(void);
+private:
+	static const char *button[]; 
+	static const keyinfo chartab[];
+};
+
+const keyinfo INPUTMAP::chartab[] = 
+	{{KBD_1,"1"},{KBD_2,"2"},{KBD_3,"3"},{KBD_4,"4"},{KBD_5,"5"},{KBD_6,"6"},{KBD_7,"7"},{KBD_8,"8"},{KBD_9,"9"},{KBD_0,"0"},
+	{KBD_q,"q"},{KBD_w,"w"},{KBD_e,"e"},{KBD_r,"r"},{KBD_t,"t"},{KBD_y,"y"},{KBD_u,"u"},{KBD_i,"i"},{KBD_o,"o"},{KBD_p,"p"},
+	{KBD_a,"a"},{KBD_s,"s"},{KBD_d,"d"},{KBD_f,"f"},{KBD_g,"g"},{KBD_h,"h"},{KBD_j,"j"},{KBD_k,"k"},{KBD_l,"l"},{KBD_z,"z"},
+	{KBD_x,"x"},{KBD_c,"c"},{KBD_v,"v"},{KBD_b,"b"},{KBD_n,"n"},{KBD_m,"m"},
+	{KBD_f1,"f1"},{KBD_f2,"f2"},{KBD_f3,"f3"},{KBD_f4,"f4"},{KBD_f5,"f5"},{KBD_f6,"f6"},{KBD_f7,"f7"},
+	{KBD_f8,"f8"},{KBD_f9,"f9"},{KBD_f10,"f10"},{KBD_f11,"f11"},{KBD_f12,"f12"},
+	{KBD_esc,"esc"},{KBD_tab,"tab"},{KBD_backspace,"bs"},{KBD_enter,"enter"},{KBD_space,"space"},
+	{KBD_leftalt,"lalt"},{KBD_rightalt,"ralt"},{KBD_leftctrl,"lctrl"},{KBD_rightctrl,"rctrl"},{KBD_leftshift,"lshift"},{KBD_rightshift,"rshift"},
+	{KBD_capslock,"caplock"},{KBD_scrolllock,"scrllock"},{KBD_numlock,"numlock"},
+	{KBD_grave,"`"},{KBD_minus,"-"},{KBD_equals,"="},{KBD_backslash,"\\"},{KBD_leftbracket,"["},{KBD_rightbracket,"]"},
+	{KBD_semicolon,";"},{KBD_quote,"'"},{KBD_period,"."},{KBD_comma,","},{KBD_slash,"/"},
+	{KBD_insert,"insert"},{KBD_home,"home"},{KBD_pageup,"pgup"},{KBD_delete,"del"},{KBD_end,"end"},{KBD_pagedown,"pgdn"},
+	{KBD_left,"left"},{KBD_up,"up"},{KBD_down,"down"},{KBD_right,"right"},
+	{KBD_kp1,"n1"},{KBD_kp2,"n2"},{KBD_kp3,"n3"},{KBD_kp4,"n4"},{KBD_kp5,"n5"},{KBD_kp6,"n6"},{KBD_kp7,"n7"},{KBD_kp8,"n8"},{KBD_kp9,"n9"},{KBD_kp0,"n9"},
+	{KBD_kpdivide,"n/"},{KBD_kpmultiply,"n*"},{KBD_kpminus,"n-"},{KBD_kpplus,"n+"},{KBD_kpenter,"nenter"},{KBD_kpperiod,"n."},
+	{KBD_button1,"button1"},{KBD_button2,"button2"},{KBD_LAST, NULL}};
+
+const char *INPUTMAP::button[] = {"select", "start", "up", "right", "down", "left", "triangle", "circle", "cross", "square", "ltrigger", "rtrigger", NULL}; 
+
+
+void INPUTMAP::Run(void) {
+	if(!cmd->GetCount()) {
+		WriteOut(MSG_Get("PROGRAM_INPUTMAP_USAGE"));
+		return;
+	}
+	if(cmd->FindExist("exec", true)) {
+		Bitu commandNr = 1;
+		if (cmd->FindCommand(commandNr++,temp_line)) {
+			// get Filename
+			char filename[128];
+			strncpy(filename,temp_line.c_str(),128);
+			// Setup commandline
+			bool ok;
+			char args[256];
+			args[0] = 0;
+			do {
+				ok = cmd->FindCommand(commandNr++,temp_line);
+				strncat(args,temp_line.c_str(),256);
+				strncat(args," ",256);
+			} while (ok);			
+			// Use shell to start program
+			DOS_Shell shell;
+			control_map = true;
+			shell.Execute(filename,args);
+			control_map = false;
+			return;
+		}
+	} else if(cmd->FindExist("analog", true)) {
+		if(cmd->FindExist("mouse", true)) joy_state=false;
+		else if(cmd->FindExist("joystick", true)) joy_state=true;
+		else WriteOut(MSG_Get("PROGRAM_INPUTMAP_INVALID"));
+		return;
+	} else {
+		std::string key;
+		for(Bitu i=0; button[i]; i++) {
+			if(cmd->FindString(button[i], key)==true) {
+				for(Bitu j=0; chartab[j].ascii; j++) {
+					if(key == chartab[j].ascii) {
+						if(chartab[j].key == KBD_LAST) break;
+						switch(key.size()) {
+						case 1:
+							inputmap[i].ascii = chartab[j].ascii[0];
+							break;
+						case 2:
+							if(chartab[j].ascii[0] == 'n') {
+								inputmap[i].ascii = chartab[j].ascii[1];
+								break;
+							}
+						default:
+							switch(chartab[j].key) {
+							case KBD_enter:
+							case KBD_kpenter:
+								inputmap[i].ascii = '\r';
+								break;
+							case KBD_space:
+								inputmap[i].ascii = ' ';
+								break;
+							case KBD_tab:
+								inputmap[i].ascii = '\t';
+								break;
+							case KBD_backspace:
+								inputmap[i].ascii = '\b';
+								break;
+							case KBD_esc:
+								inputmap[i].ascii = '\033';
+								break;
+							default:
+								inputmap[i].ascii = '\0';
+							}
+						}
+						inputmap[i].key = chartab[j].key;
+						WriteOut(MSG_Get("PROGRAM_INPUTMAP_MAPPED"), chartab[j].ascii, button[i]);
+						return;
+					}
+				}
+				break;
+			}
+		}
+	}
+	WriteOut(MSG_Get("PROGRAM_INPUTMAP_INVALID"));
+}
 
+static void INPUTMAP_ProgramStart(Program * * make) {
+	*make = new INPUTMAP;
+}
+
+class SYSOPT : public Program {
+public:
+	void Run(void);
+};
+
+void SYSOPT::Run(void) {
+	bool set = false;
+	if(cmd->GetCount() == 2) set = true;
+	if(cmd->FindExist("clock")) {
+		if(set == true) {
+			int val;
+			cmd->FindInt("clock", val);
+			if((val > 333) || (val < 200)) goto error;
+			scePowerSetClockFrequency(val, val, val>>1);
+		}
+		WriteOut(MSG_Get("PROGRAM_SYSOPT_CLOCK"),scePowerGetCpuClockFrequency());
+		return;
+	}
+error:
+	WriteOut(MSG_Get("PROGRAM_SYSOPT_USAGE"));
+}
+
+static void SYSOPT_ProgramStart(Program * * make) {
+	*make = new SYSOPT;
+}
+
+#ifdef PSPPROFILE
+#include <pspdebug.h>
+#include <stdarg.h>
+extern profile_regs_ll regs;
+extern bool profile;
+
+class PROF : public Program {
+public:
+	void Run(void);
+private:
+	static void shell_fprintf(Bit16u handle, const char *format,...) {
+		char buf[1024];
+		va_list msg;
+	
+		va_start(msg,format);
+		vsprintf(buf,format,msg);
+		va_end(msg);
+
+		Bit16u size=strlen(buf);
+		DOS_WriteFile(handle,(Bit8u *)buf,&size);
+	}
+};
+
+void PROF::Run(void) {
+	Bitu commandNr = 1;
+	std::string output = "";
+	cmd->FindString("-o", output, true);
+	if (cmd->FindCommand(commandNr++,temp_line)) {
+		// get Filename
+		char filename[128];
+		strncpy(filename,temp_line.c_str(),128);
+		// Setup commandline
+		bool ok;
+		char args[256];
+		args[0] = 0;
+		do {
+			ok = cmd->FindCommand(commandNr++,temp_line);
+			strncat(args,temp_line.c_str(),256);
+			strncat(args," ",256);
+		} while (ok);			
+		// Use shell to start program
+		DOS_Shell shell;
+		profile = true;
+		memset(&regs, '\0', sizeof(profile_regs_ll));
+		pspDebugProfilerClear();
+		pspDebugProfilerEnable();
+		shell.Execute(filename,args);
+		profile = false;
+		pspDebugProfilerDisable();
+		
+		Bit16u handle=STDOUT;
+		if(output != "")
+		{
+			char filename[255];
+			strncpy(filename, output.c_str(), 255);
+			DOS_CreateFile(filename, 0, &handle);
+		}
+		unsigned long long stall = regs.internal + regs.memory + regs.copz + regs.vfpu;
+		shell_fprintf(handle,"\n********** Profile ***********\n");
+        	shell_fprintf(handle,"systemck       : %20llu [cycles]\n", regs.systemck);
+	        shell_fprintf(handle,"cpu ck         : %20llu [cycles]\n", regs.cpuck);
+        	shell_fprintf(handle,"stall          : %20llu [cycles]\n", stall);
+	        shell_fprintf(handle,"+(internal)    : %20llu [cycles]\n", regs.internal);
+        	shell_fprintf(handle,"+--(memory)    : %20llu [cycles]\n", regs.memory);
+	        shell_fprintf(handle,"+----(COPz)    : %20llu [cycles]\n", regs.copz);
+        	shell_fprintf(handle,"+----(VFPU)    : %20llu [cycles]\n", regs.vfpu);
+	        shell_fprintf(handle,"sleep          : %20llu [cycles]\n", regs.sleep);
+        	shell_fprintf(handle,"bus access     : %20llu [cycles]\n", regs.bus_access);
+	        shell_fprintf(handle,"uncached load  : %20llu [times]\n", regs.uncached_load);
+        	shell_fprintf(handle,"uncached store : %20llu [times]\n", regs.uncached_store);
+	        shell_fprintf(handle,"cached load    : %20llu [times]\n", regs.cached_load);
+        	shell_fprintf(handle,"cached store   : %20llu [times]\n", regs.cached_store);
+	        shell_fprintf(handle,"I cache miss   : %20llu [times]\n", regs.i_miss);
+        	shell_fprintf(handle,"D cache miss   : %20llu [times]\n", regs.d_miss);
+	        shell_fprintf(handle,"D cache wb     : %20llu [times]\n", regs.d_writeback);
+        	shell_fprintf(handle,"COP0 inst.     : %20llu [inst.]\n", regs.cop0_inst);
+	        shell_fprintf(handle,"FPU  inst.     : %20llu [inst.]\n", regs.fpu_inst);
+        	shell_fprintf(handle,"VFPU inst.     : %20llu [inst.]\n", regs.vfpu_inst);
+	        shell_fprintf(handle,"local bus      : %20llu [cycles]\n\n", regs.local_bus);
+		shell_fprintf(handle,"exec inst      : %20llu [inst.]\n", regs.cpuck - (stall + regs.sleep));
+		shell_fprintf(handle,"cached mem acc : %20llu [times]\n", regs.cached_load + regs.cached_store);
+		shell_fprintf(handle,"I$ miss rateck : %20llf [%%]\n", ((double)regs.i_miss / (double)(regs.cpuck - (stall + regs.sleep)))*100);
+		shell_fprintf(handle,"D$ miss ratenum: %20llf [%%]\n", ((double)regs.d_miss / (double)(regs.cached_load + regs.cached_store))*100);
+		shell_fprintf(handle,"D$ miss rateck : %20llf [%%]\n", ((double)regs.d_miss / (double)(regs.cpuck - (stall + regs.sleep)))*100);
+		shell_fprintf(handle,"bus util       : %20llf [%%]\n", ((double)regs.bus_access / (double)regs.systemck)*100);
+		shell_fprintf(handle,"cycle per inst : %20llf [cpi]\n", (double)regs.cpuck /  (double)(regs.cpuck - (stall + regs.sleep)));
+		
+	}
+}
+
+static void PROF_ProgramStart(Program * * make) {
+	*make = new PROF;
+}
+#endif
+#endif
 
 void DOS_SetupPrograms(void) {
 	/*Add Messages */
@@ -1426,7 +1679,7 @@
 	MSG_Add("PROGRAM_IMGMOUNT_MOUNT_NUMBER","Drive number %d mounted as %s\n");
 	MSG_Add("PROGRAM_IMGMOUNT_NON_LOCAL_DRIVE", "The image must be on a host or local drive.\n");
 	MSG_Add("PROGRAM_IMGMOUNT_MULTIPLE_NON_CUEISO_FILES", "Using multiple files is only supported for cue/iso images.\n");
-
+#ifdef USE_ALT_KEYB
 	MSG_Add("PROGRAM_KEYB_INFO","Codepage %i has been loaded\n");
 	MSG_Add("PROGRAM_KEYB_SHOWHELP",
 		"\033[32;1mKEYB\033[0m [keyboard layout ID[ codepage number[ codepage file]]]\n\n"
@@ -1440,6 +1693,22 @@
 	MSG_Add("PROGRAM_KEYB_INVALIDFILE","Keyboard file %s invalid\n");
 	MSG_Add("PROGRAM_KEYB_LAYOUTNOTFOUND","No layout in %s for codepage %i\n");
 	MSG_Add("PROGRAM_KEYB_INVCPFILE","None or invalid codepage file for layout %s\n\n");
+	PROGRAMS_MakeFile("KEYB.COM", KEYB_ProgramStart);
+#endif
+#ifdef PSP
+	MSG_Add("PROGRAM_INPUTMAP_MAPPED", "Key %s is mapped to button %s.\n");
+	MSG_Add("PROGRAM_INPUTMAP_INVALID", "Invalid arguments.\n");
+	MSG_Add("PROGRAM_INPUTMAP_USAGE", "usage: inputmap [option]\nexec <cmdline>: run cmdline with input map\nanalog <mode>: mode sets mouse or joystick\n"
+		"<button> <keycode>: map button to keycode\n");
+
+	MSG_Add("PROGRAM_SYSOPT_CLOCK", "CPU Clock is %dMhz\n");
+	MSG_Add("PROGRAM_SYSOPT_USAGE", "usage: sysopt [option]\nclock <rate>: get clock rate or set clock to rate, rate must be between 200 and 333\n");
+	PROGRAMS_MakeFile("INPUTMAP.COM",INPUTMAP_ProgramStart);
+	PROGRAMS_MakeFile("SYSOPT.COM",SYSOPT_ProgramStart);
+#ifdef PSPPROFILE
+	PROGRAMS_MakeFile("PROF.COM",PROF_ProgramStart);
+#endif
+#endif
 
 	/*regular setup*/
 	PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart);
@@ -1449,5 +1718,4 @@
 	PROGRAMS_MakeFile("INTRO.COM",INTRO_ProgramStart);
 	PROGRAMS_MakeFile("BOOT.COM",BOOT_ProgramStart);
 	PROGRAMS_MakeFile("IMGMOUNT.COM", IMGMOUNT_ProgramStart);
-	PROGRAMS_MakeFile("KEYB.COM", KEYB_ProgramStart);
 }
diff -ru dosbox-0.71.orig/src/dosbox.cpp dosbox-0.71/src/dosbox.cpp
--- dosbox-0.71.orig/src/dosbox.cpp	2007-07-02 15:06:59.000000000 -0500
+++ dosbox-0.71/src/dosbox.cpp	2007-08-22 13:04:05.312500000 -0500
@@ -121,11 +121,22 @@
 static Bit32u ticksScheduled;
 bool ticksLocked;
 
+#ifdef PSP
+#define __cache_lock(addr) 	__builtin_allegrex_cache(0x1f, (Bitu)addr);
+#define __cache_unlock(addr) 	__builtin_allegrex_cache(0x14, (Bitu)addr); \
+				__builtin_allegrex_cache(0x16, (Bitu)addr);
+#else
+#define __cache_lock(addr)
+#define __cache_unlock(addr)
+#endif
+
 static Bitu Normal_Loop(void) {
 	Bits ret;
 	while (1) {
 		if (PIC_RunQueue()) {
+			__cache_lock(&cpu_regs);
 			ret=(*cpudecoder)();
+			__cache_unlock(&cpu_regs);
 			if (ret<0) return 1;
 			if (ret>0) {
 				Bitu blah=(*CallBack_Handlers[ret])();
@@ -169,9 +180,9 @@
 					Bit32s new_cmax = CPU_CycleMax;
 					Bit64s cproc = (Bit64s)CPU_CycleMax * (Bit64s)ticksScheduled;
 					if(cproc > 0) {
-						double ratioremoved = (double) CPU_IODelayRemoved / (double) cproc;
+						float ratioremoved = (float) CPU_IODelayRemoved / (float) cproc;
 						if(ratioremoved < 1.0) {
-							ratio = (Bits)((double)ratio * (1 - ratioremoved));
+							ratio = (Bits)((float)ratio * (1 - ratioremoved));
 							if (ratio <= 1024) 
 								new_cmax = (CPU_CycleMax * ratio) / 1024;
 							else 
@@ -196,7 +207,9 @@
 			}
 		} else {
 			ticksAdded = 0;
+#ifdef USE_SDL
 			SDL_Delay(1);
+#endif
 			ticksDone -= GetTicks() - ticksNew;
 			if (ticksDone < 0)
 				ticksDone = 0;
@@ -240,7 +253,6 @@
 	        "# This is the configurationfile for DOSBox %s.\n"
 	        "# Lines starting with a # are commentlines.\n"
 	        "# They are used to (briefly) document the effect of each option.\n");
-
 	MAPPER_AddHandler(DOSBOX_UnlockSpeed, MK_f12, MMOD2,"speedlock","Speedlock");
 	svgaCard = SVGA_S3Trio; 
 	machine=MCH_VGA;
@@ -296,6 +308,7 @@
 	secprop->Add_int("frameskip",0);
 	secprop->Add_bool("aspect",false);
 	secprop->Add_string("scaler","normal2x");
+	secprop->Add_bool("invert",false);
 	MSG_Add("RENDER_CONFIGFILE_HELP",
 		"frameskip -- How many frames dosbox skips before drawing one.\n"
 		"aspect -- Do aspect correction, if your output method doesn't support scaling this can slow things down!.\n"
@@ -389,7 +402,6 @@
 		"           All OPL modes are 'Adlib', except for CMS.\n"
 		"oplrate -- Sample rate of OPL music emulation.\n"
 		);
-
 	secprop=control->AddSection_prop("gus",&GUS_Init,true); //done
 	secprop->Add_bool("gus",true); 	
 	secprop->Add_int("gusrate",22050);
@@ -410,7 +422,6 @@
 		"            the patch files for GUS playback.  Patch sets used\n"
 		"            with Timidity should work fine.\n"
 	);
-
 	secprop=control->AddSection_prop("speaker",&PCSPEAKER_Init,true);//done
 	secprop->Add_bool("pcspeaker",true);
 	secprop->Add_int("pcrate",22050);
diff -ru dosbox-0.71.orig/src/fpu/fpu.cpp dosbox-0.71/src/fpu/fpu.cpp
--- dosbox-0.71.orig/src/fpu/fpu.cpp	2007-01-08 12:45:39.000000000 -0600
+++ dosbox-0.71/src/fpu/fpu.cpp	2007-08-01 13:06:07.921875000 -0500
@@ -44,6 +44,8 @@
 
 #if C_FPU_X86
 #include "fpu_instructions_x86.h"
+#elif defined(PSP)
+#include "fpu_instructions_vfpu.h"
 #else
 #include "fpu_instructions.h"
 #endif
diff -ru dosbox-0.71.orig/src/fpu/fpu_instructions.h dosbox-0.71/src/fpu/fpu_instructions.h
--- dosbox-0.71.orig/src/fpu/fpu_instructions.h	2007-01-08 12:45:39.000000000 -0600
+++ dosbox-0.71/src/fpu/fpu_instructions.h	2007-08-01 13:06:07.921875000 -0500
@@ -42,7 +42,7 @@
 	return;
 }
 
-static void FPU_PUSH(double in){
+static void FPU_PUSH(FVAL in){
 	TOP = (TOP - 1) &7;
 	//actually check if empty
 	fpu.tags[TOP] = TAG_Valid;
@@ -64,6 +64,429 @@
 	return;
 }
 
+static void FPU_FADD(Bitu op1, Bitu op2){
+	fpu.regs[op1].d+=fpu.regs[op2].d;
+	//flags and such :)
+	return;
+}
+
+static void FPU_FDIV(Bitu st, Bitu other){
+	fpu.regs[st].d= fpu.regs[st].d/fpu.regs[other].d;
+	//flags and such :)
+	return;
+}
+
+static void FPU_FDIVR(Bitu st, Bitu other){
+	fpu.regs[st].d= fpu.regs[other].d/fpu.regs[st].d;
+	// flags and such :)
+	return;
+};
+
+static void FPU_FMUL(Bitu st, Bitu other){
+	fpu.regs[st].d*=fpu.regs[other].d;
+	//flags and such :)
+	return;
+}
+
+static void FPU_FSUB(Bitu st, Bitu other){
+	fpu.regs[st].d = fpu.regs[st].d - fpu.regs[other].d;
+	//flags and such :)
+	return;
+}
+
+static void FPU_FSUBR(Bitu st, Bitu other){
+	fpu.regs[st].d= fpu.regs[other].d - fpu.regs[st].d;
+	//flags and such :)
+	return;
+}
+
+static void FPU_FXCH(Bitu st, Bitu other){
+	FPU_Tag tag = fpu.tags[other];
+	FPU_Reg reg = fpu.regs[other];
+	fpu.tags[other] = fpu.tags[st];
+	fpu.regs[other] = fpu.regs[st];
+	fpu.tags[st] = tag;
+	fpu.regs[st] = reg;
+}
+
+static void FPU_FST(Bitu st, Bitu other){
+	fpu.tags[other] = fpu.tags[st];
+	fpu.regs[other] = fpu.regs[st];
+}
+
+
+static void FPU_FCOM(Bitu st, Bitu other){
+	if(((fpu.tags[st] != TAG_Valid) && (fpu.tags[st] != TAG_Zero)) || 
+		((fpu.tags[other] != TAG_Valid) && (fpu.tags[other] != TAG_Zero))){
+		FPU_SET_C3(1);FPU_SET_C2(1);FPU_SET_C0(1);return;
+	}
+	if(fpu.regs[st].d == fpu.regs[other].d){
+		FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0);return;
+	}
+	if(fpu.regs[st].d < fpu.regs[other].d){
+		FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(1);return;
+	}
+	// st > other
+	FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(0);return;
+}
+
+static INLINE void FPU_FUCOM(Bitu st, Bitu other){
+	//does atm the same as fcom 
+	FPU_FCOM(st,other);
+}
+
+static void FPU_FLD_F32(PhysPt addr,Bitu store_to) {
+	union {
+		float f;
+		Bit32u l;
+	}	blah;
+	blah.l = mem_readd(addr);
+	fpu.regs[store_to].d = static_cast<FVAL>(blah.f);
+}
+
+static void FPU_FLD_I16(PhysPt addr,Bitu store_to) {
+	Bit16s blah = mem_readw(addr);
+	fpu.regs[store_to].d = static_cast<FVAL>(blah);
+}
+
+static void FPU_FLD_I32(PhysPt addr,Bitu store_to) {
+	Bit32s blah = mem_readd(addr);
+	fpu.regs[store_to].d = static_cast<FVAL>(blah);
+}
+
+static void FPU_FBLD(PhysPt addr,Bitu store_to) {
+	Bit64u val = 0;
+	Bitu in = 0;
+	Bit64u base = 1;
+	for(Bitu i = 0;i < 9;i++){
+		in = mem_readb(addr + i);
+		val += ( (in&0xf) * base); //in&0xf shouldn't be higher then 9
+		base *= 10;
+		val += ((( in>>4)&0xf) * base);
+		base *= 10;
+	}
+
+	//last number, only now convert to float in order to get
+	//the best signification
+	FVAL temp = static_cast<FVAL>(val);
+	in = mem_readb(addr + 9);
+	temp += ( (in&0xf) * base );
+	if(in&0x80) temp *= -1.0;
+	fpu.regs[store_to].d = temp;
+}
+
+static void FPU_FST_F32(PhysPt addr) {
+	union {
+		float f;
+		Bit32u l;
+	}	blah;
+	//should depend on rounding method
+	blah.f = static_cast<float>(fpu.regs[TOP].d);
+	mem_writed(addr,blah.l);
+}
+
+#ifdef SINGLE_FLOAT
+
+static void FPU_FBST(PhysPt addr) {
+	FPU_Reg val = fpu.regs[TOP];
+	bool sign = false;
+	if(val.d<0.0){ //sign
+		sign=true;
+		val.d=-val.d;
+	}
+	//numbers from back to front
+	Real32 temp=val.d;
+	Bitu p;
+	for(Bitu i=0;i<9;i++){
+		val.d=temp;
+		temp = static_cast<Real32>(static_cast<Bit32s>(floorf(val.d/10.0)));
+		p = static_cast<Bitu>(val.d - 10.0*temp);  
+		val.d=temp;
+		temp = static_cast<Real32>(static_cast<Bit32s>(floorf(val.d/10.0)));
+		p |= (static_cast<Bitu>(val.d - 10.0*temp)<<4);
+
+		mem_writeb(addr+i,p);
+	}
+	val.d=temp;
+	temp = static_cast<Real32>(static_cast<Bit32s>(floorf(val.d/10.0)));
+	p = static_cast<Bitu>(val.d - 10.0*temp);
+	if(sign)
+		p|=0x80;
+	mem_writeb(addr+9,p);
+}
+
+static float FROUND(float in){
+	switch(fpu.round){
+	case ROUND_Nearest:	
+		if (in-floorf(in)>0.5) return (floorf(in)+1);
+		else if (in-floorf(in)<0.5) return (floorf(in));
+		else return (((static_cast<Bit32s>(floorf(in)))&1)!=0)?(floorf(in)+1):(floorf(in));
+		break;
+	case ROUND_Down:
+		return (floorf(in));
+		break;
+	case ROUND_Up:
+		return (ceilf(in));
+		break;
+	case ROUND_Chop:
+		return in; //the cast afterwards will do it right maybe cast here
+		break;
+	default:
+		return in;
+		break;
+	}
+}
+
+#define BIAS80 16383
+#define BIAS32 127
+
+static Real32 FPU_FLD80(PhysPt addr) {
+	struct{
+		Bit16s begin;
+		Bit32s upper;
+	} test;
+//	test.lower=mem_readd(addr);  // no point
+	test.upper=mem_readd(addr+4);
+	test.begin=mem_readw(addr+8);
+
+	Bit32s exp32 = (test.begin & 0x7fff) - BIAS80;
+	Bit32s mant32 = (test.upper >> 8) & 0x7fffff;
+	Bit32s sign = (test.begin &0x8000)?1:0;
+	if(exp32 == 0x4000) exp32 = 0x80;
+	else if(exp32 > BIAS32) {
+		exp32 = 0x80;
+		mant32 = 0;
+		sign = 0;
+	} else if(exp32 < -BIAS32) {
+		exp32 = -BIAS32;
+		mant32 = 0;
+		sign = 0;
+	}
+
+	exp32 = (exp32 + BIAS32) & 0xff;
+	FPU_Reg result;
+	result.l = (sign <<31)|(exp32 << 23)| mant32;
+	return result.d;
+}
+
+static void FPU_ST80(PhysPt addr, Bitu reg) {
+	struct{
+		Bit16s begin;
+		Bit32s upper;
+	} test;
+	Bit32s sign80 = (fpu.regs[reg].l&0x80000000)?1:0;
+	Bit32s exp80 =  (fpu.regs[reg].l&0x7f800000)>>23;
+	if(exp80 == 0xff)  exp80 = 0x7fff;
+	else exp80 += (BIAS80 - BIAS32);
+	Bit32s mant80 = (fpu.regs[reg].l&0x7fffff)<<8;
+	if(fpu.regs[reg].d != 0) mant80 |= 0x80000000;
+	test.begin = (static_cast<Bit16s>(sign80)<<15)| static_cast<Bit16s>(exp80);
+	test.upper = mant80;
+	mem_writed(addr,0);
+	mem_writed(addr+4,test.upper);
+	mem_writew(addr+8,test.begin);
+}
+
+static void FPU_FLD_F64(PhysPt addr,Bitu store_to) {
+	double_reg reg;
+	reg.l.lower = mem_readd(addr);
+	reg.l.upper = mem_readd(addr+4);
+	fpu.regs[store_to].d = static_cast<Real32>(reg.d);
+}
+
+static void FPU_FST_F64(PhysPt addr) {
+	double_reg reg;
+	reg.d = static_cast<Real64>(fpu.regs[TOP].d);
+	mem_writed(addr,reg.l.lower);
+	mem_writed(addr+4,reg.l.upper);
+}
+
+static void FPU_FST_I64(PhysPt addr) {
+	double_reg blah;
+	blah.ll = static_cast<Bit64s>(FROUND(fpu.regs[TOP].d));
+	mem_writed(addr,blah.l.lower);
+	mem_writed(addr+4,blah.l.upper);
+}
+
+static void FPU_FLD_I64(PhysPt addr,Bitu store_to) {
+	double_reg blah;
+	blah.l.lower = mem_readd(addr);
+	blah.l.upper = mem_readd(addr+4);
+	fpu.regs[store_to].d = static_cast<Real32>(blah.ll);
+}
+
+/* Wolf3d breaks if sin(PI/2) equals 1.0 */
+#define SINFIX .0000001f
+
+static void FPU_FSIN(void){
+	fpu.regs[TOP].d = sinf(fpu.regs[TOP].d) - SINFIX;
+	FPU_SET_C2(0);
+	//flags and such :)
+	return;
+}
+
+static void FPU_FSINCOS(void){
+	Real32 temp = fpu.regs[TOP].d;
+	fpu.regs[TOP].d = sinf(temp) - SINFIX;
+	FPU_PUSH(cosf(temp) - SINFIX);
+	FPU_SET_C2(0);
+	//flags and such :)
+	return;
+}
+
+static void FPU_FCOS(void){
+	fpu.regs[TOP].d = cosf(fpu.regs[TOP].d) - SINFIX;
+	FPU_SET_C2(0);
+	//flags and such :)
+	return;
+}
+
+static void FPU_FSQRT(void){
+	fpu.regs[TOP].d = sqrtf(fpu.regs[TOP].d);
+	//flags and such :)
+	return;
+}
+static void FPU_FPATAN(void){
+	fpu.regs[STV(1)].d = atan2f(fpu.regs[STV(1)].d,fpu.regs[TOP].d);
+	FPU_FPOP();
+	//flags and such :)
+	return;
+}
+static void FPU_FPTAN(void){
+	fpu.regs[TOP].d = tanf(fpu.regs[TOP].d);
+	FPU_PUSH(1.0);
+	FPU_SET_C2(0);
+	//flags and such :)
+	return;
+}
+
+static void FPU_FRNDINT(void){
+	Bit32s temp= static_cast<Bit32s>(FROUND(fpu.regs[TOP].d));
+	fpu.regs[TOP].d=static_cast<float>(temp);
+}
+
+static void FPU_FPREM(void){
+	Real32 valtop = fpu.regs[TOP].d;
+	Real32 valdiv = fpu.regs[STV(1)].d;
+	Bit32s ressaved = static_cast<Bit32s>( (valtop/valdiv) );
+// Some backups
+//	Real64 res=valtop - ressaved*valdiv; 
+//      res= fmod(valtop,valdiv);
+	fpu.regs[TOP].d = valtop - ressaved*valdiv;
+	FPU_SET_C0(static_cast<Bitu>(ressaved&4));
+	FPU_SET_C3(static_cast<Bitu>(ressaved&2));
+	FPU_SET_C1(static_cast<Bitu>(ressaved&1));
+	FPU_SET_C2(0);
+}
+
+static void FPU_FPREM1(void){
+	Real32 valtop = fpu.regs[TOP].d;
+	Real32 valdiv = fpu.regs[STV(1)].d;
+	float quot = valtop/valdiv;
+	float quotf = floorf(quot);
+	Bit32s ressaved;
+	if (quot-quotf>0.5) ressaved = static_cast<Bit32s>(quotf+1);
+	else if (quot-quotf<0.5) ressaved = static_cast<Bit32s>(quotf);
+	else ressaved = static_cast<Bit64s>((((static_cast<Bit32s>(quotf))&1)!=0)?(quotf+1):(quotf));
+	fpu.regs[TOP].d = valtop - ressaved*valdiv;
+	FPU_SET_C0(static_cast<Bitu>(ressaved&4));
+	FPU_SET_C3(static_cast<Bitu>(ressaved&2));
+	FPU_SET_C1(static_cast<Bitu>(ressaved&1));
+	FPU_SET_C2(0);
+}
+
+static void FPU_FXAM(void){
+	if(fpu.regs[TOP].l & 0x80000000)	//sign
+	{ 
+		FPU_SET_C1(1);
+	} 
+	else 
+	{
+		FPU_SET_C1(0);
+	}
+	if(fpu.tags[TOP] == TAG_Empty)
+	{
+		FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(1);
+		return;
+	}
+	if(fpu.regs[TOP].d == 0.0f)		//zero or normalized number.
+	{ 
+		FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0);
+	}
+	else
+	{
+		FPU_SET_C3(0);FPU_SET_C2(1);FPU_SET_C0(0);
+	}
+}
+
+
+static void FPU_F2XM1(void){
+	fpu.regs[TOP].d = powf(2.0,fpu.regs[TOP].d) - 1;
+	return;
+}
+
+static void FPU_FYL2X(void){
+	fpu.regs[STV(1)].d*=logf(fpu.regs[TOP].d)/LN2;
+	FPU_FPOP();
+	return;
+}
+
+static void FPU_FYL2XP1(void){
+	fpu.regs[STV(1)].d*=logf(fpu.regs[TOP].d+1.0)/LN2;
+	FPU_FPOP();
+	return;
+}
+
+static void FPU_FSCALE(void){
+	fpu.regs[TOP].d *= powf(2.0,static_cast<Real32>(static_cast<Bit32s>(fpu.regs[STV(1)].d)));
+	return; //2^x where x is chopped.
+}
+
+static void FPU_FXTRACT(void) {
+	// function stores real bias in st and 
+	// pushes the significant number onto the stack
+	// if double ever uses a different base please correct this function
+
+	FPU_Reg test = fpu.regs[TOP];
+	Bit64s exp80 =  test.l&0x7f800000;
+	Bit64s exp80final = (exp80>>23) - BIAS32;
+	Real64 mant = test.d / (powf(2.0,static_cast<Real32>(exp80final)));
+	fpu.regs[TOP].d = static_cast<Real32>(exp80final);
+	FPU_PUSH(mant); 
+}
+static void FPU_FABS(void){
+	fpu.regs[TOP].d = fabsf(fpu.regs[TOP].d);
+}
+#else
+
+static void FPU_FBST(PhysPt addr) {
+	FPU_Reg val = fpu.regs[TOP];
+	bool sign = false;
+	if(val.d<0.0){ //sign
+		sign=true;
+		val.d=-val.d;
+	}
+	//numbers from back to front
+	Real64 temp=val.d;
+	Bitu p;
+	for(Bitu i=0;i<9;i++){
+		val.d=temp;
+		temp = static_cast<Real64>(static_cast<Bit64s>(floor(val.d/10.0)));
+		p = static_cast<Bitu>(val.d - 10.0*temp);  
+		val.d=temp;
+		temp = static_cast<Real64>(static_cast<Bit64s>(floor(val.d/10.0)));
+		p |= (static_cast<Bitu>(val.d - 10.0*temp)<<4);
+
+		mem_writeb(addr+i,p);
+	}
+	val.d=temp;
+	temp = static_cast<Real64>(static_cast<Bit64s>(floor(val.d/10.0)));
+	p = static_cast<Bitu>(val.d - 10.0*temp);
+	if(sign)
+		p|=0x80;
+	mem_writeb(addr+9,p);
+}
+
 static double FROUND(double in){
 	switch(fpu.round){
 	case ROUND_Nearest:	
@@ -130,105 +553,16 @@
 	mem_writew(addr+8,test.begin);
 }
 
-
-static void FPU_FLD_F32(PhysPt addr,Bitu store_to) {
-	union {
-		float f;
-		Bit32u l;
-	}	blah;
-	blah.l = mem_readd(addr);
-	fpu.regs[store_to].d = static_cast<Real64>(blah.f);
-}
-
 static void FPU_FLD_F64(PhysPt addr,Bitu store_to) {
 	fpu.regs[store_to].l.lower = mem_readd(addr);
 	fpu.regs[store_to].l.upper = mem_readd(addr+4);
 }
 
-static void FPU_FLD_F80(PhysPt addr) {
-	fpu.regs[TOP].d = FPU_FLD80(addr);
-}
-
-static void FPU_FLD_I16(PhysPt addr,Bitu store_to) {
-	Bit16s blah = mem_readw(addr);
-	fpu.regs[store_to].d = static_cast<Real64>(blah);
-}
-
-static void FPU_FLD_I32(PhysPt addr,Bitu store_to) {
-	Bit32s blah = mem_readd(addr);
-	fpu.regs[store_to].d = static_cast<Real64>(blah);
-}
-
-static void FPU_FLD_I64(PhysPt addr,Bitu store_to) {
-	FPU_Reg blah;
-	blah.l.lower = mem_readd(addr);
-	blah.l.upper = mem_readd(addr+4);
-	fpu.regs[store_to].d = static_cast<Real64>(blah.ll);
-}
-
-static void FPU_FBLD(PhysPt addr,Bitu store_to) {
-	Bit64u val = 0;
-	Bitu in = 0;
-	Bit64u base = 1;
-	for(Bitu i = 0;i < 9;i++){
-		in = mem_readb(addr + i);
-		val += ( (in&0xf) * base); //in&0xf shouldn't be higher then 9
-		base *= 10;
-		val += ((( in>>4)&0xf) * base);
-		base *= 10;
-	}
-
-	//last number, only now convert to float in order to get
-	//the best signification
-	Real64 temp = static_cast<Real64>(val);
-	in = mem_readb(addr + 9);
-	temp += ( (in&0xf) * base );
-	if(in&0x80) temp *= -1.0;
-	fpu.regs[store_to].d = temp;
-}
-
-
-static INLINE void FPU_FLD_F32_EA(PhysPt addr) {
-	FPU_FLD_F32(addr,8);
-}
-static INLINE void FPU_FLD_F64_EA(PhysPt addr) {
-	FPU_FLD_F64(addr,8);
-}
-static INLINE void FPU_FLD_I32_EA(PhysPt addr) {
-	FPU_FLD_I32(addr,8);
-}
-static INLINE void FPU_FLD_I16_EA(PhysPt addr) {
-	FPU_FLD_I16(addr,8);
-}
-
-
-static void FPU_FST_F32(PhysPt addr) {
-	union {
-		float f;
-		Bit32u l;
-	}	blah;
-	//should depend on rounding method
-	blah.f = static_cast<float>(fpu.regs[TOP].d);
-	mem_writed(addr,blah.l);
-}
-
 static void FPU_FST_F64(PhysPt addr) {
 	mem_writed(addr,fpu.regs[TOP].l.lower);
 	mem_writed(addr+4,fpu.regs[TOP].l.upper);
 }
 
-static void FPU_FST_F80(PhysPt addr) {
-	FPU_ST80(addr,TOP);
-}
-
-static void FPU_FST_I16(PhysPt addr) {
-	mem_writew(addr,static_cast<Bit16s>(FROUND(fpu.regs[TOP].d)));
-}
-
-static void FPU_FST_I32(PhysPt addr) {
-	mem_writed(addr,static_cast<Bit32s>(FROUND(fpu.regs[TOP].d)));
-}
-
 static void FPU_FST_I64(PhysPt addr) {
 	FPU_Reg blah;
 	blah.ll = static_cast<Bit64s>(FROUND(fpu.regs[TOP].d));
@@ -236,38 +570,11 @@
 	mem_writed(addr+4,blah.l.upper);
 }
 
-static void FPU_FBST(PhysPt addr) {
-	FPU_Reg val = fpu.regs[TOP];
-	bool sign = false;
-	if(val.d<0.0){ //sign
-		sign=true;
-		val.d=-val.d;
-	}
-	//numbers from back to front
-	Real64 temp=val.d;
-	Bitu p;
-	for(Bitu i=0;i<9;i++){
-		val.d=temp;
-		temp = static_cast<Real64>(static_cast<Bit64s>(floor(val.d/10.0)));
-		p = static_cast<Bitu>(val.d - 10.0*temp);  
-		val.d=temp;
-		temp = static_cast<Real64>(static_cast<Bit64s>(floor(val.d/10.0)));
-		p |= (static_cast<Bitu>(val.d - 10.0*temp)<<4);
-
-		mem_writeb(addr+i,p);
-	}
-	val.d=temp;
-	temp = static_cast<Real64>(static_cast<Bit64s>(floor(val.d/10.0)));
-	p = static_cast<Bitu>(val.d - 10.0*temp);
-	if(sign)
-		p|=0x80;
-	mem_writeb(addr+9,p);
-}
-
-static void FPU_FADD(Bitu op1, Bitu op2){
-	fpu.regs[op1].d+=fpu.regs[op2].d;
-	//flags and such :)
-	return;
+static void FPU_FLD_I64(PhysPt addr,Bitu store_to) {
+	FPU_Reg blah;
+	blah.ll = static_cast<Bit64s>(FROUND(fpu.regs[TOP].d));
+	mem_writed(addr,blah.l.lower);
+	mem_writed(addr+4,blah.l.upper);
 }
 
 static void FPU_FSIN(void){
@@ -311,70 +618,6 @@
 	//flags and such :)
 	return;
 }
-static void FPU_FDIV(Bitu st, Bitu other){
-	fpu.regs[st].d= fpu.regs[st].d/fpu.regs[other].d;
-	//flags and such :)
-	return;
-}
-
-static void FPU_FDIVR(Bitu st, Bitu other){
-	fpu.regs[st].d= fpu.regs[other].d/fpu.regs[st].d;
-	// flags and such :)
-	return;
-};
-
-static void FPU_FMUL(Bitu st, Bitu other){
-	fpu.regs[st].d*=fpu.regs[other].d;
-	//flags and such :)
-	return;
-}
-
-static void FPU_FSUB(Bitu st, Bitu other){
-	fpu.regs[st].d = fpu.regs[st].d - fpu.regs[other].d;
-	//flags and such :)
-	return;
-}
-
-static void FPU_FSUBR(Bitu st, Bitu other){
-	fpu.regs[st].d= fpu.regs[other].d - fpu.regs[st].d;
-	//flags and such :)
-	return;
-}
-
-static void FPU_FXCH(Bitu st, Bitu other){
-	FPU_Tag tag = fpu.tags[other];
-	FPU_Reg reg = fpu.regs[other];
-	fpu.tags[other] = fpu.tags[st];
-	fpu.regs[other] = fpu.regs[st];
-	fpu.tags[st] = tag;
-	fpu.regs[st] = reg;
-}
-
-static void FPU_FST(Bitu st, Bitu other){
-	fpu.tags[other] = fpu.tags[st];
-	fpu.regs[other] = fpu.regs[st];
-}
-
-
-static void FPU_FCOM(Bitu st, Bitu other){
-	if(((fpu.tags[st] != TAG_Valid) && (fpu.tags[st] != TAG_Zero)) || 
-		((fpu.tags[other] != TAG_Valid) && (fpu.tags[other] != TAG_Zero))){
-		FPU_SET_C3(1);FPU_SET_C2(1);FPU_SET_C0(1);return;
-	}
-	if(fpu.regs[st].d == fpu.regs[other].d){
-		FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0);return;
-	}
-	if(fpu.regs[st].d < fpu.regs[other].d){
-		FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(1);return;
-	}
-	// st > other
-	FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(0);return;
-}
-
-static void FPU_FUCOM(Bitu st, Bitu other){
-	//does atm the same as fcom 
-	FPU_FCOM(st,other);
-}
 
 static void FPU_FRNDINT(void){
 	Bit64s temp= static_cast<Bit64s>(FROUND(fpu.regs[TOP].d));
@@ -458,6 +701,23 @@
 	return; //2^x where x is chopped.
 }
 
+static void FPU_FXTRACT(void) {
+	// function stores real bias in st and 
+	// pushes the significant number onto the stack
+	// if double ever uses a different base please correct this function
+
+	FPU_Reg test = fpu.regs[TOP];
+	Bit64s exp80 =  test.ll&LONGTYPE(0x7ff0000000000000);
+	Bit64s exp80final = (exp80>>52) - BIAS64;
+	Real64 mant = test.d / (pow(2.0,static_cast<Real64>(exp80final)));
+	fpu.regs[TOP].d = static_cast<Real64>(exp80final);
+	FPU_PUSH(mant); 
+}
+static void FPU_FABS(void){
+	fpu.regs[TOP].d = fabs(fpu.regs[TOP].d);
+}
+#endif
+
 static void FPU_FSTENV(PhysPt addr){
 	FPU_SET_TOP(TOP);
 	if(!cpu.code.big) {
@@ -509,27 +769,10 @@
 	}
 }
 
-static void FPU_FXTRACT(void) {
-	// function stores real bias in st and 
-	// pushes the significant number onto the stack
-	// if double ever uses a different base please correct this function
-
-	FPU_Reg test = fpu.regs[TOP];
-	Bit64s exp80 =  test.ll&LONGTYPE(0x7ff0000000000000);
-	Bit64s exp80final = (exp80>>52) - BIAS64;
-	Real64 mant = test.d / (pow(2.0,static_cast<Real64>(exp80final)));
-	fpu.regs[TOP].d = static_cast<Real64>(exp80final);
-	FPU_PUSH(mant); 
-}
-
 static void FPU_FCHS(void){
 	fpu.regs[TOP].d = -1.0*(fpu.regs[TOP].d);
 }
 
-static void FPU_FABS(void){
-	fpu.regs[TOP].d = fabs(fpu.regs[TOP].d);
-}
-
 static void FPU_FTST(void){
 	fpu.regs[8].d = 0.0;
 	FPU_FCOM(TOP,8);
@@ -571,6 +814,26 @@
 	fpu.tags[TOP] = TAG_Zero;
 }
 
+static INLINE void FPU_FLD_F32_EA(PhysPt addr) {
+	FPU_FLD_F32(addr,8);
+}
+static INLINE void FPU_FLD_F64_EA(PhysPt addr) {
+	FPU_FLD_F64(addr,8);
+}
+static INLINE void FPU_FLD_I32_EA(PhysPt addr) {
+	FPU_FLD_I32(addr,8);
+}
+static INLINE void FPU_FLD_I16_EA(PhysPt addr) {
+	FPU_FLD_I16(addr,8);
+}
+
+static void FPU_FLD_F80(PhysPt addr) {
+	fpu.regs[TOP].d = FPU_FLD80(addr);
+}
+
+static void FPU_FST_F80(PhysPt addr) {
+	FPU_ST80(addr,TOP);
+}
 
 static INLINE void FPU_FADD_EA(Bitu op1){
 	FPU_FADD(op1,8);
@@ -594,3 +857,10 @@
 	FPU_FCOM(op1,8);
 }
 
+static void FPU_FST_I16(PhysPt addr) {
+	mem_writew(addr,static_cast<Bit16s>(FROUND(fpu.regs[TOP].d)));
+}
+
+static void FPU_FST_I32(PhysPt addr) {
+	mem_writed(addr,static_cast<Bit32s>(FROUND(fpu.regs[TOP].d)));
+}
diff -ru dosbox-0.71.orig/src/gui/midi.cpp dosbox-0.71/src/gui/midi.cpp
--- dosbox-0.71.orig/src/gui/midi.cpp	2007-06-14 03:23:46.000000000 -0500
+++ dosbox-0.71/src/gui/midi.cpp	2007-08-01 13:06:07.921875000 -0500
@@ -31,6 +31,8 @@
 #define SYSEX_SIZE 1024
 #define RAWBUF	1024
 
+#ifdef USE_MIDI
+
 Bit8u MIDI_evt_len[256] = {
   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x00
   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x10
@@ -73,8 +75,6 @@
 	MidiHandler * next;
 };
 
-MidiHandler Midi_none;
-
 /* Include different midi drivers, lowest ones get checked first for default */
 
 #if defined(MACOSX)
@@ -97,6 +97,8 @@
 
 #endif
 
+MidiHandler Midi_none;
+
 static struct {
 	Bitu status;
 	Bitu cmd_len;
@@ -207,3 +209,14 @@
 	test = new MIDI(sec);
 	sec->AddDestroyFunction(&MIDI_Destroy,true);
 }
+
+#else
+
+void MIDI_Init(Section * src) { }
+
+void MIDI_RawOutByte(Bit8u data) { }
+
+bool MIDI_Available(void) { return false; }
+
+#endif
+
diff -ru dosbox-0.71.orig/src/gui/render.cpp dosbox-0.71/src/gui/render.cpp
--- dosbox-0.71.orig/src/gui/render.cpp	2007-07-05 11:03:49.000000000 -0500
+++ dosbox-0.71/src/gui/render.cpp	2007-08-01 13:06:07.921875000 -0500
@@ -18,6 +18,10 @@
 
 /* $Id: render.cpp,v 1.54 2007/07/05 16:03:49 c2woody Exp $ */
 
+#ifdef PSP
+#include "renderpsp.h"
+#else
+
 #include <sys/types.h>
 #include <dirent.h>
 #include <assert.h>
@@ -632,4 +636,4 @@
 	MAPPER_AddHandler(IncreaseFrameSkip,MK_f8,MMOD1,"incfskip","Inc Fskip");
 	GFX_SetTitle(-1,render.frameskip.max,false);
 }
-
+#endif
diff -ru dosbox-0.71.orig/src/gui/render_scalers.cpp dosbox-0.71/src/gui/render_scalers.cpp
--- dosbox-0.71.orig/src/gui/render_scalers.cpp	2007-07-05 11:03:49.000000000 -0500
+++ dosbox-0.71/src/gui/render_scalers.cpp	2007-08-04 20:04:38.406250000 -0500
@@ -21,6 +21,8 @@
 //Maybe just do the cache checking back into the simple scalers so they can 
 //just handle it all in one go, but this seems to work well enough for now
 
+#ifndef PSP
+
 #include "dosbox.h"
 #include "render.h"
 #include <string.h>
@@ -438,3 +440,4 @@
 };
 
 #endif
+#endif
diff -ru dosbox-0.71.orig/src/gui/render_scalers.h dosbox-0.71/src/gui/render_scalers.h
--- dosbox-0.71.orig/src/gui/render_scalers.h	2007-07-05 11:03:49.000000000 -0500
+++ dosbox-0.71/src/gui/render_scalers.h	2007-08-04 20:04:03.375000000 -0500
@@ -59,7 +59,9 @@
 	scalerLast
 } scalerOperation_t;
 
-typedef void (*ScalerLineHandler_t)(const void *src);
+typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart, Bitu line, Bit8u *address);
+
+typedef void (*ScalerLineHandler_t)(Bitu vidstart, Bitu line, VGA_Line_Handler handler);
 typedef void (*ScalerComplexHandler_t)(void);
 
 extern Bit8u Scaler_Aspect[];
diff -ru dosbox-0.71.orig/src/gui/sdl_mapper.cpp dosbox-0.71/src/gui/sdl_mapper.cpp
--- dosbox-0.71.orig/src/gui/sdl_mapper.cpp	2007-07-17 08:50:27.000000000 -0500
+++ dosbox-0.71/src/gui/sdl_mapper.cpp	2007-08-01 13:06:34.265625000 -0500
@@ -18,6 +18,8 @@
 
 /* $Id: sdl_mapper.cpp,v 1.39 2007/07/17 13:50:27 c2woody Exp $ */
 
+#ifdef USE_SDL
+
 #include <vector>
 #include <list>
 #include <string.h>
@@ -2352,4 +2354,5 @@
 	mapper.filename=section->Get_string("mapperfile");
 	MAPPER_AddHandler(&MAPPER_Run,MK_f1,MMOD1,"mapper","Mapper");
 }
+#endif
 
diff -ru dosbox-0.71.orig/src/gui/sdlmain.cpp dosbox-0.71/src/gui/sdlmain.cpp
--- dosbox-0.71.orig/src/gui/sdlmain.cpp	2007-06-12 15:22:08.000000000 -0500
+++ dosbox-0.71/src/gui/sdlmain.cpp	2007-08-27 20:53:43.390625000 -0500
@@ -32,7 +32,9 @@
 #include <signal.h>
 #endif
 
+#ifdef USE_SDL
 #include "SDL.h"
+#endif
 
 #include "dosbox.h"
 #include "video.h"
@@ -45,8 +47,335 @@
 #include "mapper.h"
 #include "vga.h"
 #include "keyboard.h"
+#include "joystick.h"
 
 //#define DISABLE_JOYSTICK
+#ifdef WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#if (HAVE_DDRAW_H)
+#include <ddraw.h>
+struct private_hwdata {
+	LPDIRECTDRAWSURFACE3 dd_surface;
+	LPDIRECTDRAWSURFACE3 dd_writebuf;
+};
+#endif
+
+#define STDOUT_FILE	TEXT("stdout.txt")
+#define STDERR_FILE	TEXT("stderr.txt")
+#define DEFAULT_CONFIG_FILE "/dosbox.conf"
+#elif defined(MACOSX)
+#define DEFAULT_CONFIG_FILE "/Library/Preferences/DOSBox Preferences"
+#else /*linux freebsd*/
+#define DEFAULT_CONFIG_FILE "/.dosboxrc"
+#endif
+
+#ifdef PSP
+#include <pspsdk.h>
+#include <pspdebug.h>
+#include <pspkernel.h>
+#include <pspdisplay.h>
+#include <pspctrl.h>
+#include "p_sprint.h"
+#include <pspirkeyb.h>
+#include "me_rpc.h"
+
+static int sensitivity;
+bool control_map = false, joy_state = false, irkeyb = false;
+bool autofire = false, startup_state_capslock = false, startup_state_numlock = false;
+static SceUID main_thsema;
+static bool suspended = false, reinit = false;
+char build_version[] = "DOSBox " VERSION "-psp build " __DATE__ " " __TIME__;
+#ifdef PSPPROFILE
+profile_regs_ll regs;
+bool profile = false;
+#include <pspdebug.h>
+#endif
+
+void cache_init(bool);
+void cache_free_memory(void);
+
+#define UNK KBD_NONE
+keymap inputmap[] =
+{{ KBD_esc, PSP_CTRL_SELECT, '\0' },
+{ KBD_enter, PSP_CTRL_START, '\r' },
+{ KBD_up, PSP_CTRL_UP, '\0' },
+{ KBD_right, PSP_CTRL_RIGHT, '\0' },
+{ KBD_down, PSP_CTRL_DOWN, '\0' },
+{ KBD_left, PSP_CTRL_LEFT, '\0' },
+{ KBD_w, PSP_CTRL_TRIANGLE, 'w' },
+{ KBD_d, PSP_CTRL_CIRCLE, 'd' },
+{ KBD_s, PSP_CTRL_CROSS, 's' },
+{ KBD_a, PSP_CTRL_SQUARE, 'a' },
+{ KBD_button1, PSP_CTRL_LTRIGGER, '\0' },
+{ KBD_button2, PSP_CTRL_RTRIGGER, '\0' },
+{ UNK, 0, '\0' }};
+
+static const KBD_KEYS xlate_table[3][43] = { {
+	UNK, KBD_backspace, KBD_space, KBD_b, KBD_y, KBD_g, KBD_leftbracket, KBD_quote, KBD_comma,
+	KBD_f, KBD_o, KBD_u, KBD_x, KBD_v, KBD_grave, KBD_j, KBD_l, KBD_d, KBD_m, KBD_z,
+	KBD_rightbracket, KBD_backslash, KBD_q, KBD_p, KBD_s, KBD_t, KBD_c, KBD_semicolon, KBD_w,
+	KBD_k, KBD_r, KBD_e, KBD_a, KBD_period, KBD_minus, KBD_slash, KBD_h, KBD_n, KBD_i,
+	KBD_enter, KBD_esc, KBD_tab, UNK
+	}, {
+	UNK, KBD_backspace, KBD_space, KBD_f1, KBD_f2, KBD_f8, KBD_leftbracket, KBD_semicolon,
+	KBD_comma, KBD_f3, KBD_f4, KBD_f5, KBD_kpdivide, KBD_f12, KBD_grave, KBD_f9, KBD_f6,
+	KBD_f7, KBD_f10, KBD_f11, KBD_rightbracket, UNK, KBD_kpmultiply, KBD_0, KBD_1, KBD_2,
+	KBD_9, KBD_equals, KBD_minus, KBD_3, KBD_4, KBD_5, KBD_period, UNK, UNK, UNK, KBD_8,
+	KBD_6, KBD_7, KBD_enter, KBD_esc, KBD_tab, UNK
+	}, {
+	UNK, KBD_down, KBD_enter, KBD_left, KBD_home, KBD_insert, UNK, UNK, UNK, KBD_end, KBD_up,
+	KBD_pageup, UNK, UNK, UNK, KBD_delete, KBD_pagedown, KBD_right, KBD_kpplus, KBD_kpmultiply, UNK,
+	UNK, KBD_scrolllock, KBD_kpminus, KBD_esc, UNK, UNK, UNK, KBD_numlock, UNK, KBD_leftctrl,
+	KBD_leftshift, KBD_leftalt, UNK, UNK, UNK, KBD_capslock, UNK, KBD_tab, KBD_enter, KBD_esc,
+	KBD_tab, KBD_backspace } };
+
+static const KBD_KEYS ir_xlate_table[] = { UNK, KBD_esc, KBD_1, KBD_2, KBD_3, KBD_4, KBD_5, KBD_6, KBD_7,
+	KBD_8, KBD_9, KBD_0, KBD_minus, KBD_equals, KBD_backspace, KBD_tab, KBD_q, KBD_w, KBD_e, KBD_r, KBD_t,
+	KBD_y, KBD_u, KBD_i, KBD_o, KBD_p, KBD_leftbracket, KBD_rightbracket, KBD_enter, KBD_leftctrl, KBD_a,
+	KBD_s, KBD_d, KBD_f, KBD_g, KBD_h, KBD_j, KBD_k, KBD_l, KBD_semicolon, KBD_quote, KBD_grave, KBD_leftshift,
+	KBD_backslash, KBD_z, KBD_x, KBD_c, KBD_v, KBD_b, KBD_n, KBD_m, KBD_comma, KBD_period, KBD_slash, KBD_rightshift,
+	KBD_kpmultiply, KBD_leftalt, KBD_space, KBD_capslock, KBD_f1, KBD_f2, KBD_f3, KBD_f4, KBD_f5, KBD_f6, KBD_f7,
+	KBD_f8, KBD_f9, KBD_f10, KBD_numlock, KBD_scrolllock, KBD_kp7, KBD_kp8, KBD_kp9, KBD_kpminus, KBD_kp4,
+	KBD_kp5, KBD_kp6, KBD_kpplus, KBD_kp1, KBD_kp2, KBD_kp3, KBD_kp0, KBD_kpperiod, UNK, UNK, UNK, UNK, UNK, UNK,
+	UNK, UNK, UNK, UNK, UNK, UNK, KBD_kpenter, KBD_rightctrl, KBD_kpdivide, KBD_printscreen, KBD_rightalt, UNK,
+	KBD_home, KBD_up, KBD_pageup, KBD_left, KBD_right, KBD_end, KBD_down, KBD_pagedown, KBD_insert, KBD_delete, UNK,
+	UNK, UNK, UNK, UNK, UNK, UNK, KBD_pause};
+
+void Mouse_AutoLock(bool enable) {}
+void GUI_StartUp(Section * sec) {
+	Section_prop * section=static_cast<Section_prop *>(sec);
+	std::string inifile=section->Get_string("irkeybini");
+	sensitivity=section->Get_int("sensitivity");
+	if(pspIrKeybInit((inifile == "")?NULL:inifile.c_str(),0) < 0)
+		LOG_MSG("GUI:IR keyboard not found");
+	else {
+		LOG_MSG("GUI:IR keyboard found");
+		irkeyb = true;
+		pspIrKeybOutputMode(PSP_IRKBD_OUTPUT_MODE_RAW);
+	}
+}
+
+void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused){ }
+void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char const * const eventname,char const * const buttonname) {
+	// TODO: implement
+}
+
+static void check_mod(unsigned char mod, bool pressed) {
+	if(mod) {
+		KBD_KEYS modkey;
+		switch(mod) {	// TODO:multiple modifiers
+			case P_SP_MOD_CONTROL:
+				modkey = KBD_leftctrl;
+				break;
+			case P_SP_MOD_SHIFT:
+				modkey = KBD_leftshift;
+				break;
+			case P_SP_MOD_ALT:
+				modkey = KBD_leftalt;
+				break;
+		}
+		KEYBOARD_AddKey(modkey, pressed);
+	}
+}
+
+void GFX_Events() {
+	struct p_sp_Key new_state;
+	SceCtrlData pad;
+	int x, y;
+	static struct p_sp_Key prev_state;
+	static Bitu prev_pad = 0, last_sample = 0;
+	static bool state_change = false; 
+	static bool init = false;
+	char buffer[255];
+	int length;
+
+	sceKernelSignalSema(main_thsema, 1);
+	
+	if (!init) {
+		sceCtrlSetSamplingCycle(0);
+		sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
+		p_sp_init();
+		memset(&prev_state, '\0', sizeof(struct p_sp_Key));
+		JOYSTICK_Enable(0, true);
+		JOYSTICK_Button(0, 0, false);
+		JOYSTICK_Button(0, 1, false);
+		JOYSTICK_Move_X(0, 0);
+		JOYSTICK_Move_Y(0, 0);
+		init = true;
+	}
+	
+#ifdef PSPPROFILE
+	if(profile) {
+		PspDebugProfilerRegs small_regs;
+		pspDebugProfilerGetRegs(&small_regs);
+		regs.systemck += small_regs.systemck;
+		regs.cpuck += small_regs.cpuck;
+		regs.internal += small_regs.internal;
+		regs.memory += small_regs.memory;
+		regs.copz += small_regs.copz;
+		regs.vfpu += small_regs.vfpu;
+		regs.sleep += small_regs.sleep;
+		regs.bus_access += small_regs.bus_access;
+		regs.uncached_load += small_regs.uncached_load;
+		regs.uncached_store += small_regs.uncached_store;
+		regs.cached_load += small_regs.cached_load;
+		regs.cached_store += small_regs.cached_store;
+		regs.i_miss += small_regs.i_miss;
+		regs.d_miss += small_regs.d_miss;
+		regs.d_writeback += small_regs.d_writeback;
+		regs.cop0_inst += small_regs.cop0_inst;
+		regs.fpu_inst += small_regs.fpu_inst;
+		regs.vfpu_inst += small_regs.vfpu_inst;
+		regs.local_bus += small_regs.local_bus;
+		pspDebugProfilerClear();
+	}
+#endif
+
+#ifdef PSPME
+	sc_read_queue();
+#endif
+
+	if (PIC_Ticks < (last_sample + 17)) goto exit;  // limit the input rate to 60Hz
+	last_sample = PIC_Ticks;
+
+	if(sceCtrlPeekBufferPositive(&pad, 1) <= 0) goto exit; 
+	pad.Buttons &= 0xFFFF;
+	
+	if(pad.Buttons == (PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_START | PSP_CTRL_DOWN)) {
+		if(state_change)
+			goto exit;
+
+		if(joy_state) {
+			JOYSTICK_Button(0, 0, false);
+			JOYSTICK_Button(0, 1, false);
+			JOYSTICK_Move_X(0, 0);
+			JOYSTICK_Move_Y(0, 0);
+		}
+		else {
+			Mouse_ButtonReleased(0);
+			Mouse_ButtonReleased(1);
+		}
+		joy_state = !joy_state;
+		state_change = true;
+		goto exit;
+	}
+	if(pad.Buttons == (PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_SELECT | PSP_CTRL_DOWN)) {
+		if(state_change)
+			goto exit;
+
+		control_map = !control_map;
+		state_change = true;
+		goto exit;
+	}
+	if(state_change && pad.Buttons)
+		goto exit;
+	state_change = false;
+
+	x = (int)pad.Lx - 127;
+	y = (int)pad.Ly - 127;
+	
+	/* 32x32 dead zone */
+	if(!((x+16)>>5) && !((y+16)>>5)) {
+		x = 0;
+		y = 0;
+	}
+
+	if(joy_state) {
+		JOYSTICK_Move_X(0, (float)x/127.0f);
+		JOYSTICK_Move_Y(0, (float)y/127.0f);
+	} else if(x || y) {
+		Bits absx = (x>0)?(sensitivity):(-1*sensitivity);
+		Bits absy = (y>0)?(sensitivity):(-1*sensitivity);
+		Mouse_CursorMoved((float)(absx*x*x)/100000.0f, (float)(absy*y*y)/100000.0f, 1, 1, 1);
+	}
+
+	if(irkeyb && (pspIrKeybReadinput(buffer, &length) == PSP_IRKBD_RESULT_OK) && (length > 0)) {
+		int count = length / sizeof(SIrKeybRawCodeData);
+		//printf("got %d keypresses\n",count);
+		SIrKeybRawCodeData *key;
+		for(int i = 0; i < count; i++) {
+			key = &((SIrKeybRawCodeData *)buffer)[i];
+			//printf("key %d %s\n",key->raw,(key->pressed?"pressed":"released"));
+			if(key->raw > 119) continue;
+			KEYBOARD_AddKey(ir_xlate_table[key->raw], key->pressed);
+		}
+	}
+	if(control_map) {
+		for(Bitu i=0; inputmap[i].mask; i++) 
+			if(pad.Buttons & inputmap[i].mask) {
+				if(prev_pad & inputmap[i].mask) continue;
+				switch(inputmap[i].key) {
+				case KBD_button1:
+					if(joy_state) JOYSTICK_Button(0, 0, true);
+					else Mouse_ButtonPressed(0);
+					break;
+				case KBD_button2:
+					if(joy_state) JOYSTICK_Button(0, 1, true);
+					else Mouse_ButtonPressed(1);
+					break;
+				default:
+					KEYBOARD_AddKey(inputmap[i].key, 1);
+				}
+			 } else if(prev_pad & inputmap[i].mask) {
+				switch(inputmap[i].key) {
+				case KBD_button1:
+					if(joy_state) JOYSTICK_Button(0, 0, false);
+					else Mouse_ButtonReleased(0);
+					break;
+				case KBD_button2:
+					if(joy_state) JOYSTICK_Button(0, 1, false);
+					else Mouse_ButtonReleased(1);
+					break;
+				default: 
+					KEYBOARD_AddKey(inputmap[i].key, 0);
+				}
+			}
+	} else {
+		if(p_spReadKeyEx(&new_state, pad.Buttons)) {
+			if((prev_state.keygroup != new_state.keygroup) || (prev_state.keyid != new_state.keyid)) {
+				if(prev_state.keyid) {
+					check_mod(prev_state.modifiers,0);
+					KEYBOARD_AddKey(xlate_table[prev_state.keygroup][prev_state.keyid],0);
+				}
+				check_mod(new_state.modifiers,1);
+				KEYBOARD_AddKey(xlate_table[new_state.keygroup][new_state.keyid],1);
+				memcpy(&prev_state, &new_state, sizeof(p_sp_Key));
+			}
+		} else if(prev_state.keyid) {
+			check_mod(prev_state.modifiers,0);
+			KEYBOARD_AddKey(xlate_table[prev_state.keygroup][prev_state.keyid],0);
+			memset(&prev_state, '\0', sizeof(p_sp_Key));
+		}
+		if(pad.Buttons & PSP_CTRL_LTRIGGER) {
+			if(!(prev_pad & PSP_CTRL_LTRIGGER))
+				if(joy_state) JOYSTICK_Button(0, 0, true);
+				else Mouse_ButtonPressed(0);
+		} else if(prev_pad & PSP_CTRL_LTRIGGER) {
+				if(joy_state) JOYSTICK_Button(0, 0, false);
+				else Mouse_ButtonReleased(0);
+		}
+		if(pad.Buttons & PSP_CTRL_RTRIGGER) {
+			if(!(prev_pad & PSP_CTRL_RTRIGGER))
+				if(joy_state) JOYSTICK_Button(0, 1, true);
+				else Mouse_ButtonPressed(1);
+		} else if(prev_pad & PSP_CTRL_RTRIGGER) {
+				if(joy_state) JOYSTICK_Button(0, 1, false);
+				else Mouse_ButtonReleased(1);
+		}
+	}
+	prev_pad = pad.Buttons;
+exit:
+	sceKernelWaitSema(main_thsema, 1, NULL);
+	if(suspended == true) {
+		cache_init(reinit);
+		suspended = false;
+	}
+}
+
+#else
 
 #if C_OPENGL
 #include "SDL_opengl.h"
@@ -58,6 +387,7 @@
 #define APIENTRYP APIENTRY *
 #endif
 
+
 #ifdef __WIN32__
 #define NVIDIA_PixelDataRange 1
 
@@ -93,28 +423,6 @@
 extern char** environ;
 #endif
 
-#ifdef WIN32
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-#include <windows.h>
-#if (HAVE_DDRAW_H)
-#include <ddraw.h>
-struct private_hwdata {
-	LPDIRECTDRAWSURFACE3 dd_surface;
-	LPDIRECTDRAWSURFACE3 dd_writebuf;
-};
-#endif
-
-#define STDOUT_FILE	TEXT("stdout.txt")
-#define STDERR_FILE	TEXT("stderr.txt")
-#define DEFAULT_CONFIG_FILE "/dosbox.conf"
-#elif defined(MACOSX)
-#define DEFAULT_CONFIG_FILE "/Library/Preferences/DOSBox Preferences"
-#else /*linux freebsd*/
-#define DEFAULT_CONFIG_FILE "/.dosboxrc"
-#endif
-
 #if C_SET_PRIORITY
 #include <sys/resource.h>
 #define PRIO_TOTAL (PRIO_MAX-PRIO_MIN)
@@ -1327,6 +1635,130 @@
 }
 #endif
 
+#endif
+
+#ifdef PSP
+#include <pspiofilemgr.h>
+#include <psppower.h>
+#include <pspsuspend.h>
+#include <pspsysmem_kernel.h>
+#include "regs.h"
+
+extern "C" {
+
+static const char x86_regs[][4] = {
+	"eax","ecx","edx","ebx","esp","ebp","esi","edi","es","cs","ss","ds","fs","gs","eip" };
+	
+static void dump_x86_regs() {
+	int i;
+	pspDebugScreenPrintf("\n");
+        for(i = 0; i < 8; i+=4)
+                pspDebugScreenPrintf("%s:%08X %s:%08X %s:%08X %s:%08X\n", x86_regs[i], cpu_regs.regs[i].dword[DW_INDEX],
+                                x86_regs[i+1], cpu_regs.regs[i+1].dword[DW_INDEX],x86_regs[i+2], cpu_regs.regs[i+2].dword[DW_INDEX],
+				x86_regs[i+3], cpu_regs.regs[i+3].dword[DW_INDEX]);
+	
+	pspDebugScreenPrintf("%s:%08X %s:%08X %s:%08X %s:%08X\n", x86_regs[8], Segs.val[0],
+                                x86_regs[9], Segs.val[1],x86_regs[10], Segs.val[2], x86_regs[11], Segs.val[3]);
+	pspDebugScreenPrintf("%s:%08X %s:%08X %s:%08X\n", x86_regs[12], Segs.val[4], 
+                                x86_regs[13], Segs.val[5], x86_regs[14], cpu_regs.ip.dword[DW_INDEX]);
+}
+
+static int in_exception = 0;
+
+static void trap_handler(PspDebugRegBlock *regs) {
+	if(in_exception) __asm__ volatile(".word 0x70000000");
+	in_exception = 1;
+	pspDebugScreenInit();
+	pspDebugScreenPrintf("%s\n", build_version);
+	pspDebugDumpException(regs);
+	dump_x86_regs();
+#ifdef PSPME
+	stop_me();
+#endif
+	sceKernelSleepThread();
+}
+
+#ifdef PSPME
+void me_trap_handler(PspDebugRegBlock *regs) {
+	pspDebugScreenInit();
+	pspDebugScreenPrintf("ME exception\n");
+	pspDebugDumpException(regs);
+	dump_x86_regs();
+	stop_me();
+	sceKernelSleepThread();
+}
+#endif
+void sceMeWrapperEnd(void);
+__attribute__((constructor)) void install_trap_handler() {
+	pspKernelSetKernelPC();
+	pspDebugInstallErrorHandler(trap_handler);
+	sceMeWrapperEnd();
+	sceKernelSetDdrMemoryProtection((void *)0x88300000, 1024*1024, 0xf);
+}
+
+static SceUID cb_thid, main_thid;
+
+static void end_threads() {
+	sceKernelTerminateDeleteThread(cb_thid);
+	sceKernelTerminateDeleteThread(main_thid);
+	sceKernelExitGame();
+}
+
+PSP_MODULE_INFO("DOSBox", 0x1000, 1, 1);
+#if defined(PSPME) || defined(PSPPROFILE)
+PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_VFPU);
+#else
+PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER|PSP_THREAD_ATTR_VFPU);
+#endif
+
+extern bool cache_initialized;
+
+static int psp_exit_callback(int arg1, int arg2, void *common) {
+#ifdef PSPME
+	stop_me();
+#endif
+	pspIrKeybFinish();
+	exit(0);
+	return 0;
+}
+
+static int psp_power_callback(int unknown, int powerInfo, void *nothing) {
+	if((powerInfo & PSP_POWER_CB_POWER_SWITCH) && (suspended == false)) {
+		sceKernelWaitSema(main_thsema, 1, NULL);
+		sceKernelSuspendThread(main_thid);
+		suspended = true;
+		reinit = cache_initialized;
+		cache_initialized = false;
+		cache_free_memory();
+		sceKernelVolatileMemUnlock();
+	} else if((powerInfo & PSP_POWER_CB_RESUME_COMPLETE) && (suspended == true)) {
+		sceKernelSignalSema(main_thsema, 1);		// doing VolatileMemLock in the callback doesn't work
+		sceKernelResumeThread(main_thid);
+	}
+	return 0;
+}
+
+
+static int psp_callback_thread(SceSize args, void *argp) {
+	int cbid;
+	cbid = sceKernelCreateCallback("Power Callback", psp_power_callback, NULL);
+	scePowerRegisterCallback(0, cbid);
+	cbid = sceKernelCreateCallback("Exit Callback", psp_exit_callback, NULL);
+	sceKernelRegisterExitCallback(cbid);
+	sceKernelSleepThreadCB();
+}
+
+static int psp_setup_callbacks(void) {
+	int thid = 0;
+	main_thid = sceKernelGetThreadId();
+	main_thsema = sceKernelCreateSema("Suspend Sema", 0, 0, 1, NULL);
+	thid = sceKernelCreateThread("update_thread", psp_callback_thread, 0x11, 512, PSP_THREAD_ATTR_USER, 0);
+	if(thid >= 0) sceKernelStartThread(thid, 0, 0);
+	return thid;
+}
+}
+#endif
+
 
 /* static variable to show wether there is not a valid stdout.
  * Fixes some bugs when -noconsole is used in a read only directory */
@@ -1342,11 +1774,21 @@
 	if(!no_stdout) printf(buf);       
 };
 
-int main(int argc, char* argv[]) {
+extern "C" int main(int argc, char* argv[]) {
 	try {
 		CommandLine com_line(argc,argv);
 		Config myconf(&com_line);
 		control=&myconf;
+
+#ifdef PSP
+		atexit(end_threads);
+		cb_thid = psp_setup_callbacks();
+		pspSdkDisableFPUExceptions();
+#ifdef PSPME
+		init_me();
+#endif
+#endif
+
 		if (control->cmdline->FindExist("-version") || 
 		    control->cmdline->FindExist("--version") ) {
 			printf(VERSION "\n");
@@ -1392,7 +1834,7 @@
         setbuf(stdout, NULL);
         setbuf(stderr, NULL);
 #endif
-
+#ifdef USE_SDL
 	if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM
 		|SDL_INIT_NOPARACHUTE
 		) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError());
@@ -1433,8 +1875,11 @@
 		}
 #endif
 		sdl.num_joysticks=SDL_NumJoysticks();
+#endif
 		Section_prop * sdl_sec=control->AddSection_prop("sdl",&GUI_StartUp);
+#ifdef USE_SDL
 		sdl_sec->AddInitFunction(&MAPPER_StartUp);
+#endif
 		sdl_sec->Add_bool("fullscreen",false);
 		sdl_sec->Add_bool("fulldouble",false);
 		sdl_sec->Add_string("fullresolution","original");
@@ -1446,6 +1891,7 @@
 		sdl_sec->Add_string("priority","higher,normal");
 		sdl_sec->Add_string("mapperfile","mapper.txt");
 		sdl_sec->Add_bool("usescancodes",true);
+		sdl_sec->Add_string("irkeybini","");
 
 		MSG_Add("SDL_CONFIGFILE_HELP",
 			"fullscreen -- Start dosbox directly in fullscreen.\n"
@@ -1492,6 +1938,7 @@
 #endif
 		/* Init all the sections */
 		control->Init();
+#ifdef USE_SDL
 		/* Some extra SDL Functions */
 		if (control->cmdline->FindExist("-fullscreen") || sdl_sec->Get_bool("fullscreen")) {
 			if(!sdl.desktop.fullscreen) { //only switch if not allready in fullscreen
@@ -1502,13 +1949,14 @@
 		/* Init the keyMapper */
 		MAPPER_Init();
 		if (control->cmdline->FindExist("-startmapper")) MAPPER_Run(true);
-
+#endif
 		/* Start up main machine */
 		control->StartUp();
 		/* Shutdown everything */
 	} catch (char * error) {
 		GFX_ShowMsg("Exit to error: %s",error);
 		fflush(NULL);
+#ifdef USE_SDL
 		if(sdl.wait_on_error) {
 			//TODO Maybe look for some way to show message in linux?
 #if (C_DEBUG)
@@ -1519,7 +1967,15 @@
 			Sleep(5000);
 #endif 
 		}
-
+#elif defined(PSP)
+		pspIrKeybFinish();
+		pspDebugScreenInit();
+		pspDebugScreenPrintf("Exit to error: %s", error);
+#ifdef PSPME
+		stop_me();
+#endif
+		sceKernelSleepThread();
+#endif
 	}
 	catch (int){ 
 		;//nothing pressed killswitch
@@ -1527,6 +1983,8 @@
 	catch(...){
 		throw;//dunno what happened. rethrow for sdl to catch 
 	}
+#ifdef USE_SDL
 	SDL_Quit();//Let's hope sdl will quit as well when it catches an exception
+#endif
 	return 0;
 };
diff -ru dosbox-0.71.orig/src/hardware/adlib.cpp dosbox-0.71/src/hardware/adlib.cpp
--- dosbox-0.71.orig/src/hardware/adlib.cpp	2007-01-08 12:45:40.000000000 -0600
+++ dosbox-0.71/src/hardware/adlib.cpp	2007-08-07 17:58:16.906250000 -0500
@@ -55,317 +55,87 @@
 };
 
 namespace OPL2 {
-	#define HAS_YM3812 1
 	#include "fmopl.c"
-	void TimerOver(Bitu val){
-		YM3812TimerOver(val>>8,val & 0xff);
-	}
-	void TimerHandler(int channel,double interval_Sec) {
-		if (interval_Sec==0.0) return;
-		PIC_AddEvent(TimerOver,1000.0f*interval_Sec,channel);		
-	}
 }
-#undef OSD_CPU_H
-#undef TL_TAB_LEN
-namespace THEOPL3 {
-	#define HAS_YMF262 1
-	#include "ymf262.c"
-	void TimerOver(Bitu val){
-		YMF262TimerOver(val>>8,val & 0xff);
-	}
-	void TimerHandler(int channel,double interval_Sec) {
-		if (interval_Sec==0.0) return;
-		PIC_AddEvent(TimerOver,1000.0f*interval_Sec,channel);		
+#define OPL2_INTERNAL_FREQ    3600000   // The OPL2 operates at 3.6MHz
+
+class OPL: public Module_base {
+private:
+	IO_ReadHandleObject ReadHandler[2];
+	IO_WriteHandleObject WriteHandler[2];
+	MixerObject MixerChan;
+public:
+	OPL2::FM_OPL * YM3812;
+	OPL(Section* configuration);
+	~OPL() {
+		OPL2::OPLDestroy(YM3812);
 	}
-}
+};
 
-#define OPL2_INTERNAL_FREQ    3600000   // The OPL2 operates at 3.6MHz
-#define OPL3_INTERNAL_FREQ    14400000  // The OPL3 operates at 14.4MHz
+static OPL* test;
 
-#define RAW_SIZE 1024
 static struct {
 	bool active;
-	OPL_Mode mode;
 	MixerChannel * chan;
 	Bit32u last_used;
-	Bit16s mixbuf[2][128];
-	struct {
-		FILE * handle;
-		bool capturing;
-		Bit32u start;
-		Bit32u last;
-		Bit8u index;
-		Bit8u buffer[RAW_SIZE+8];
-		Bit8u regs[2][256];
-		Bit32u used;
-		Bit32u done;
-		Bit8u cmd[2];
-		bool opl3;
-		bool dualopl2;
-	} raw;
 } opl;
 
+Bit8u adlib_commandreg;
+
+void TimerOver(Bitu val){
+	OPL2::OPLTimerOver(test->YM3812,val & 0xff);
+}
+void TimerHandler(int channel,float interval_Sec) {
+	if (interval_Sec==0.0) return;
+	PIC_AddEvent(TimerOver,1000.0f*interval_Sec,channel);		
+}
+
 static void OPL_CallBack(Bitu len) {
 	/* Check for size to update and check for 1 ms updates to the opl registers */
-	Bitu i;
-	switch(opl.mode) {
-	case OPL_opl2:
-		OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)MixTemp,len);
-		opl.chan->AddSamples_m16(len,(Bit16s*)MixTemp);
-		break;
-	case OPL_opl3:
-		THEOPL3::YMF262UpdateOne(0,(OPL2::INT16 *)MixTemp,len);
-		opl.chan->AddSamples_s16(len,(Bit16s*)MixTemp);
-		break;
-	case OPL_dualopl2:
-		OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)opl.mixbuf[0],len);
-		OPL2::YM3812UpdateOne(1,(OPL2::INT16 *)opl.mixbuf[1],len);
-		for (i=0;i<len;i++) {
-			((Bit16s*)MixTemp)[i*2+0]=opl.mixbuf[0][i];
-			((Bit16s*)MixTemp)[i*2+1]=opl.mixbuf[1][i];
-		}
-		opl.chan->AddSamples_s16(len,(Bit16s*)MixTemp);
-		break;
-	}
+	OPL2::YM3812UpdateOne(test->YM3812,(OPL2::INT16 *)MixTemp,len);
+	opl.chan->AddSamples_m16(len,(Bit16s*)MixTemp);
 	if ((PIC_Ticks-opl.last_used)>30000) {
 		opl.chan->Enable(false);
 		opl.active=false;
 	}
 }
 
-static Bitu OPL_Read(Bitu port,Bitu iolen) {
-	Bitu addr=port & 3;
-	switch (opl.mode) {
-	case OPL_opl2:
-		return OPL2::YM3812Read(0,addr);
-	case OPL_dualopl2:
-		return OPL2::YM3812Read(addr>>1,addr);
-	case OPL_opl3:
-		return THEOPL3::YMF262Read(0,addr);
-	}
-	return 0xff;
+Bitu OPL_Read(Bitu port,Bitu iolen) {
+	Bitu addr=port & 1;
+	return OPL2::OPLRead(test->YM3812, addr) | 0x06;
 }
 
-static void OPL_RawAdd(Bitu index,Bitu val);
 void OPL_Write(Bitu port,Bitu val,Bitu iolen) {
 	opl.last_used=PIC_Ticks;
 	if (!opl.active) {
 		opl.active=true;
 		opl.chan->Enable(true);
 	}
-	port&=3;
-	if (port&1) {
-		Bitu index=port>>1;
-		opl.raw.regs[index][opl.raw.cmd[index]]=val;
-		if (opl.raw.capturing) OPL_RawAdd(index,val);
-	} else opl.raw.cmd[port>>1]=val;
+	port&=1;
 	if (!port) adlib_commandreg=val;
-	switch (opl.mode) {
-	case OPL_opl2:
-		OPL2::YM3812Write(0,port,val);
-		break;
-	case OPL_opl3:
-		THEOPL3::YMF262Write(0,port,val);
-		break;
-	case OPL_dualopl2:
-		OPL2::YM3812Write(port>>1,port,val);
-		break;
-	}
+	OPL2::OPLWrite(test->YM3812,port,val);
 }
 
-static Bit8u dro_header[]={
-	'D','B','R','A',		/* 0x00, Bit32u ID */
-	'W','O','P','L',		/* 0x04, Bit32u ID */
-	0x0,0x00,				/* 0x08, Bit16u version low */
-	0x1,0x00,				/* 0x09, Bit16u version high */
-	0x0,0x0,0x0,0x0,		/* 0x0c, Bit32u total milliseconds */
-	0x0,0x0,0x0,0x0,		/* 0x10, Bit32u total data */
-	0x0,0x0,0x0,0x0			/* 0x14, Bit32u Type 0=opl2,1=opl3,2=dual-opl2 */
-};
-/* Commands 
-	0x00 Bit8u, millisecond delay+1
-	0x02 none, Use the low index/data pair
-	0x03 none, Use the high index/data pair
-	0x10 Bit16u, millisecond delay+1
-	0xxx Bit8u, send command and data to current index/data pair
-*/ 
-
-static void OPL_RawEmptyBuffer(void) {
-	fwrite(opl.raw.buffer,1,opl.raw.used,opl.raw.handle);
-	opl.raw.done+=opl.raw.used;
-	opl.raw.used=0;
+OPL::OPL(Section* configuration):Module_base(configuration) {
+	Section_prop * section=static_cast<Section_prop *>(configuration);
+	Bitu base = section->Get_hex("sbbase");
+	Bitu rate = section->Get_int("oplrate");
+	if (!(YM3812 = OPL2::OPLCreate(OPL_TYPE_YM3812, OPL2_INTERNAL_FREQ, rate))) {
+		E_Exit("Can't create OPL2 Emulator");	
+	};
+	OPL2::OPLSetTimerHandler(YM3812,TimerHandler,0);
+	WriteHandler[0].Install(0x388,OPL_Write,IO_MB,2);
+	ReadHandler[0].Install(0x388,OPL_Read,IO_MB,2);
+	WriteHandler[1].Install(base,OPL_Write,IO_MB,2);
+	ReadHandler[1].Install(base,OPL_Read,IO_MB,2);
+
+	opl.active=false;
+	opl.last_used=0;
+	opl.chan=MixerChan.Install(OPL_CallBack,rate,"FM");
 }
 
-#define ADDBUF(_VAL_) opl.raw.buffer[opl.raw.used++]=_VAL_;
-static void OPL_RawAdd(Bitu index,Bitu val) {
-	Bit8u cmd=opl.raw.cmd[index];
-	/* check for cmd's we use for special meaning 
-	   These only control timers or are unused
-	*/
-	if (cmd == 2 || cmd == 3 || cmd == 0x10) return;
-	if (cmd == 4 && !index) return;
-	/* Check if we have yet to start */
-	if (!opl.raw.handle) {
-		if (cmd<0xb0 || cmd>0xb8) return;
-		if (!(val&0x20))  return;
-		Bitu i;
-		opl.raw.last=PIC_Ticks;	
-		opl.raw.start=PIC_Ticks;
-		opl.raw.handle=OpenCaptureFile("Raw Opl",".dro");
-		if (!opl.raw.handle) {
-			opl.raw.capturing=false;		
-			return;
-		}
-		memset(opl.raw.buffer,0,sizeof(opl.raw.buffer));
-		fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle);
-		/* Check the registers to add */
-		for (i=0;i<256;i++) {
-			if (!opl.raw.regs[0][i]) continue;
-			if (i>=0xb0 && i<=0xb8) continue;
-			ADDBUF((Bit8u)i);
-			ADDBUF(opl.raw.regs[0][i]);
-		}
-		bool donesecond=false;
-		/* Check if we already have an opl3 enable bit logged */
-		if (opl.raw.regs[1][5] & 1)
-			opl.raw.opl3 = true;
-		for (i=0;i<256;i++) {
-			if (!opl.raw.regs[1][i]) continue;
-			if (i>=0xb0 && i<=0xb8) continue;
-			if (!donesecond) {
-				/* Or already have dual opl2 */
-				opl.raw.dualopl2 = true;
-				donesecond=true;
-				ADDBUF(0x3);
-			}
-			ADDBUF((Bit8u)i);
-			ADDBUF(opl.raw.regs[1][i]);
-		}
-		if (donesecond) ADDBUF(0x2);
-	}
-	/* Check if we enable opl3 or access dual opl2 mode */
-	if (cmd == 5 && index && (val & 1)) {
-		opl.raw.opl3 = true;
-	}
-	if (index && val && cmd>=0xb0 && cmd<=0xb8) {
-		opl.raw.dualopl2 = true;
-	}
-	/* Check how much time has passed, Allow an extra 5 milliseconds? */
-	if (PIC_Ticks>(opl.raw.last+5)) {
-		Bitu passed=PIC_Ticks-opl.raw.last;
-		opl.raw.last=PIC_Ticks;
-		while (passed) {
-			passed-=1;
-			if (passed<256) {
-				ADDBUF(0x00);					//8bit delay
-				ADDBUF((Bit8u)passed);			//8bit delay
-				passed=0;
-			} else if (passed<0x10000) {
-				ADDBUF(0x01);					//16bit delay
-				ADDBUF((Bit8u)(passed & 0xff));	//lo-byte
-				ADDBUF((Bit8u)(passed >> 8));	//hi-byte
-				passed=0;
-			} else {
-				ADDBUF(0x01);					//16bit delay
-				ADDBUF(0xff);					//lo-byte
-				ADDBUF(0xff);					//hi-byte
-				passed-=0xffff;
-			}
-		}
-	}
-	/* Check if we're still sending to the correct index */
-	if (opl.raw.index != index) {
-		opl.raw.index=index;
-		ADDBUF(opl.raw.index ? 0x3 : 0x2);
-	}
-	ADDBUF(cmd);
-	ADDBUF(val);
-	if (opl.raw.used>=RAW_SIZE) OPL_RawEmptyBuffer();
-}
-
-static void OPL_SaveRawEvent(bool pressed) {
-	if (!pressed)
-		return;
-	/* Check for previously opened wave file */
-	if (opl.raw.handle) {
-		OPL_RawEmptyBuffer();
-		/* Fill in the header with useful information */
-		host_writed(&dro_header[0x0c],opl.raw.last-opl.raw.start);
-		host_writed(&dro_header[0x10],opl.raw.done);
-		if (opl.raw.opl3 && opl.raw.dualopl2) host_writed(&dro_header[0x14],0x1);
-		else if (opl.raw.dualopl2) host_writed(&dro_header[0x14],0x2);
-		else host_writed(&dro_header[0x14],0x0);
-		fseek(opl.raw.handle,0,0);
-		fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle);
-		fclose(opl.raw.handle);
-		opl.raw.handle=0;
-	}
-	if (opl.raw.capturing) {
-		opl.raw.capturing=false;
-		LOG_MSG("Stopping Raw OPL capturing.");
-	} else {
-		LOG_MSG("Preparing to capture Raw OPL, will start with first note played.");
-		opl.raw.capturing=true;
-		opl.raw.index=0;
-		opl.raw.used=0;
-		opl.raw.done=0;
-		opl.raw.start=0;
-		opl.raw.last=0;
-	}
-}
-
-class OPL: public Module_base {
-private:
-	IO_ReadHandleObject ReadHandler[3];
-	IO_WriteHandleObject WriteHandler[3];
-	MixerObject MixerChan;
-public:
-	static OPL_Mode oplmode;
-
-	OPL(Section* configuration):Module_base(configuration) {
-		Section_prop * section=static_cast<Section_prop *>(configuration);
-		Bitu base = section->Get_hex("sbbase");
-		Bitu rate = section->Get_int("oplrate");
-		if (OPL2::YM3812Init(2,OPL2_INTERNAL_FREQ,rate)) {
-			E_Exit("Can't create OPL2 Emulator");	
-		};
-		OPL2::YM3812SetTimerHandler(0,OPL2::TimerHandler,0);
-		OPL2::YM3812SetTimerHandler(1,OPL2::TimerHandler,256);
-		if (THEOPL3::YMF262Init(1,OPL3_INTERNAL_FREQ,rate)) {
-			E_Exit("Can't create OPL3 Emulator");	
-		};
-		THEOPL3::YMF262SetTimerHandler(0,THEOPL3::TimerHandler,0);
-		WriteHandler[0].Install(0x388,OPL_Write,IO_MB,4);
-		ReadHandler[0].Install(0x388,OPL_Read,IO_MB,4);
-		if (oplmode>=OPL_dualopl2) {
-			WriteHandler[1].Install(base,OPL_Write,IO_MB,4);
-			ReadHandler[1].Install(base,OPL_Read,IO_MB,4);
-		}
-
-		WriteHandler[2].Install(base+8,OPL_Write,IO_MB,2);
-		ReadHandler[2].Install(base+8,OPL_Read,IO_MB,2);
-
-		opl.active=false;
-		opl.last_used=0;
-		opl.mode=oplmode;
-		memset(&opl.raw,0,sizeof(opl.raw));
-		opl.chan=MixerChan.Install(OPL_CallBack,rate,"FM");
-		MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL");
-	}
-	~OPL() {
-		if (opl.raw.handle) OPL_SaveRawEvent(true);
-		OPL2::YM3812Shutdown();
-		THEOPL3::YMF262Shutdown();
-	}
-};
-
-static OPL* test;
-
 //Initialize static members
-OPL_Mode OPL::oplmode=OPL_none;
-
 void OPL_Init(Section* sec,OPL_Mode oplmode) {
-	OPL::oplmode = oplmode;
 	test = new OPL(sec);
 }
 
diff -ru dosbox-0.71.orig/src/hardware/cmos.cpp dosbox-0.71/src/hardware/cmos.cpp
--- dosbox-0.71.orig/src/hardware/cmos.cpp	2007-01-09 11:24:50.000000000 -0600
+++ dosbox-0.71/src/hardware/cmos.cpp	2007-08-07 22:00:07.046875000 -0500
@@ -38,9 +38,9 @@
 		bool acknowledged;
 	} timer;
 	struct {
-		double timer;
-		double ended;
-		double alarm;
+		float timer;
+		float ended;
+		float alarm;
 	} last;
 	bool update_ended;
 } cmos;
@@ -168,7 +168,7 @@
 		} else {
 			/* Give correct values at certain times */
 			Bit8u val=0;
-			double index=PIC_FullIndex();
+			float index=PIC_FullIndex();
 			if (index>=(cmos.last.timer+cmos.timer.delay)) {
 				cmos.last.timer=index;
 				val|=0x40;
diff -ru dosbox-0.71.orig/src/hardware/fmopl.c dosbox-0.71/src/hardware/fmopl.c
--- dosbox-0.71.orig/src/hardware/fmopl.c	2007-06-12 15:22:08.000000000 -0500
+++ dosbox-0.71/src/hardware/fmopl.c	2007-08-18 14:41:21.796875000 -0500
@@ -1,682 +1,248 @@
-/*
-**
-** File: fmopl.c - software implementation of FM sound generator
-**                                            types OPL and OPL2
-**
-** Copyright (C) 2002,2003 Jarek Burczynski (bujar at mame dot net)
-** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmulator development
-**
-** Version 0.70
-**
-
-Revision History:
-
-14-06-2003 Jarek Burczynski:
- - implemented all of the status register flags in Y8950 emulation
- - renamed Y8950SetDeltaTMemory() parameters from _rom_ to _mem_ since
-   they can be either RAM or ROM
-
-08-10-2002 Jarek Burczynski (thanks to Dox for the YM3526 chip)
- - corrected YM3526Read() to always set bit 2 and bit 1
-   to HIGH state - identical to YM3812Read (verified on real YM3526)
-
-04-28-2002 Jarek Burczynski:
- - binary exact Envelope Generator (verified on real YM3812);
-   compared to YM2151: the EG clock is equal to internal_clock,
-   rates are 2 times slower and volume resolution is one bit less
- - modified interface functions (they no longer return pointer -
-   that's internal to the emulator now):
-    - new wrapper functions for OPLCreate: YM3526Init(), YM3812Init() and Y8950Init()
- - corrected 'off by one' error in feedback calculations (when feedback is off)
- - enabled waveform usage (credit goes to Vlad Romascanu and zazzal22)
- - speeded up noise generator calculations (Nicola Salmoria)
-
-03-24-2002 Jarek Burczynski (thanks to Dox for the YM3812 chip)
- Complete rewrite (all verified on real YM3812):
- - corrected sin_tab and tl_tab data
- - corrected operator output calculations
- - corrected waveform_select_enable register;
-   simply: ignore all writes to waveform_select register when
-   waveform_select_enable == 0 and do not change the waveform previously selected.
- - corrected KSR handling
- - corrected Envelope Generator: attack shape, Sustain mode and
-   Percussive/Non-percussive modes handling
- - Envelope Generator rates are two times slower now
- - LFO amplitude (tremolo) and phase modulation (vibrato)
- - rhythm sounds phase generation
- - white noise generator (big thanks to Olivier Galibert for mentioning Berlekamp-Massey algorithm)
- - corrected key on/off handling (the 'key' signal is ORed from three sources: FM, rhythm and CSM)
- - funky details (like ignoring output of operator 1 in BD rhythm sound when connect == 1)
-
-12-28-2001 Acho A. Tang
- - reflected Delta-T EOS status on Y8950 status port.
- - fixed subscription range of attack/decay tables
-
-
-	To do:
-		add delay before key off in CSM mode (see CSMKeyControll)
-		verify volume of the FM part on the Y8950
-*/
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 1999-2000 Tatsuyuki Satoh
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ * LGPL licensed version of MAMEs fmopl (V0.37a modified) by
+ * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
+ *
+ * Supposedly faster OPL emulator from scummvm
+ */
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
 #include <math.h>
 
-//#include "driver.h"		/* use M.A.M.E. */
 #include "fmopl.h"
 
-#ifndef PI
-#define PI 3.14159265358979323846
-#endif
-
-
-
-/* output final shift */
-#if (OPL_SAMPLE_BITS==16)
-	#define FINAL_SH	(0)
-	#define MAXOUT		(+32767)
-	#define MINOUT		(-32768)
-#else
-	#define FINAL_SH	(8)
-	#define MAXOUT		(+127)
-	#define MINOUT		(-128)
-#endif
+/* -------------------- preliminary define section --------------------- */
+/* attack/decay rate time rate */
+#define OPL_ARRATE     141280  /* RATE 4 =  2826.24ms @ 3.6MHz */
+#define OPL_DRRATE    1956000  /* RATE 4 = 39280.64ms @ 3.6MHz */
+
+#define FREQ_BITS 24			/* frequency turn          */
+
+/* counter bits = 20 , octerve 7 */
+#define FREQ_RATE   (1<<(FREQ_BITS-20))
+#define TL_BITS    (FREQ_BITS+2)
+
+/* final output shift , limit minimum and maximum */
+#define OPL_OUTSB   (TL_BITS+3-16)		/* OPL output final shift 16bit */
+#define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
+#define OPL_MINOUT (-0x8000<<OPL_OUTSB)
 
+/* -------------------- quality selection --------------------- */
 
-#define FREQ_SH			16  /* 16.16 fixed point (frequency calculations) */
-#define EG_SH			16  /* 16.16 fixed point (EG timing)              */
-#define LFO_SH			24  /*  8.24 fixed point (LFO calculations)       */
-#define TIMER_SH		16  /* 16.16 fixed point (timers calculations)    */
-
-#define FREQ_MASK		((1<<FREQ_SH)-1)
+/* sinwave entries */
+/* used static memory = SIN_ENT * 4 (byte) */
+#define SIN_ENT 2048
 
+/* output level entries (envelope,sinwave) */
+/* envelope counter lower bits */
+#define ENV_BITS 8
 /* envelope output entries */
-#define ENV_BITS		10
-#define ENV_LEN			(1<<ENV_BITS)
-#define ENV_STEP		(128.0/ENV_LEN)
+#define EG_ENT   1024
+/* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
+/* used static  memory = EG_ENT*4 (byte)                     */
 
-#define MAX_ATT_INDEX	((1<<(ENV_BITS-1))-1) /*511*/
-#define MIN_ATT_INDEX	(0)
+#define EG_OFF   ((2*EG_ENT)<<ENV_BITS)  /* OFF          */
+#define EG_DED   EG_OFF
+#define EG_DST   (EG_ENT<<ENV_BITS)      /* DECAY  START */
+#define EG_AED   EG_DST
+#define EG_AST   0                       /* ATTACK START */
 
-/* sinwave entries */
-#define SIN_BITS		10
-#define SIN_LEN			(1<<SIN_BITS)
-#define SIN_MASK		(SIN_LEN-1)
 
-#define TL_RES_LEN		(256)	/* 8 bits addressing (real chip) */
+#define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step  */
+
+/* LFO table entries */
+#define VIB_ENT 512
+#define VIB_SHIFT (32-9)
+#define AMS_ENT 512
+#define AMS_SHIFT (32-9)
 
+#define VIB_RATE 256
 
+/* -------------------- local defines , macros --------------------- */
 
 /* register number to channel number , slot offset */
 #define SLOT1 0
 #define SLOT2 1
 
-/* Envelope Generator phases */
-
-#define EG_ATT			4
-#define EG_DEC			3
-#define EG_SUS			2
-#define EG_REL			1
-#define EG_OFF			0
-
-
-/* save output as raw 16-bit sample */
-
-/*#define SAVE_SAMPLE*/
-
-#ifdef SAVE_SAMPLE
-INLINE signed int acc_calc(signed int value)
-{
-	if (value>=0)
-	{
-		if (value < 0x0200)
-			return (value & ~0);
-		if (value < 0x0400)
-			return (value & ~1);
-		if (value < 0x0800)
-			return (value & ~3);
-		if (value < 0x1000)
-			return (value & ~7);
-		if (value < 0x2000)
-			return (value & ~15);
-		if (value < 0x4000)
-			return (value & ~31);
-		return (value & ~63);
-	}
-	/*else value < 0*/
-	if (value > -0x0200)
-		return (~abs(value) & ~0);
-	if (value > -0x0400)
-		return (~abs(value) & ~1);
-	if (value > -0x0800)
-		return (~abs(value) & ~3);
-	if (value > -0x1000)
-		return (~abs(value) & ~7);
-	if (value > -0x2000)
-		return (~abs(value) & ~15);
-	if (value > -0x4000)
-		return (~abs(value) & ~31);
-	return (~abs(value) & ~63);
-}
-
-
-static FILE *sample[1];
-	#if 1	/*save to MONO file */
-		#define SAVE_ALL_CHANNELS \
-		{	signed int pom = acc_calc(lt); \
-			fputc((unsigned short)pom&0xff,sample[0]); \
-			fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
-		}
-	#else	/*save to STEREO file */
-		#define SAVE_ALL_CHANNELS \
-		{	signed int pom = lt; \
-			fputc((unsigned short)pom&0xff,sample[0]); \
-			fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
-			pom = rt; \
-			fputc((unsigned short)pom&0xff,sample[0]); \
-			fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
-		}
-	#endif
-#endif
-
-/* #define LOG_CYM_FILE */
-#ifdef LOG_CYM_FILE
-	FILE * cymfile = NULL;
-#endif
-
-
-
-#define OPL_TYPE_WAVESEL   0x01  /* waveform select		*/
-#define OPL_TYPE_ADPCM     0x02  /* DELTA-T ADPCM unit	*/
-#define OPL_TYPE_KEYBOARD  0x04  /* keyboard interface	*/
-#define OPL_TYPE_IO        0x08  /* I/O port			*/
-
-/* ---------- Generic interface section ---------- */
-#define OPL_TYPE_YM3526 (0)
-#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL)
-#define OPL_TYPE_Y8950  (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO)
-
-
-
-typedef struct{
-	UINT32	ar;			/* attack rate: AR<<2			*/
-	UINT32	dr;			/* decay rate:  DR<<2			*/
-	UINT32	rr;			/* release rate:RR<<2			*/
-	UINT8	KSR;		/* key scale rate				*/
-	UINT8	ksl;		/* keyscale level				*/
-	UINT8	ksr;		/* key scale rate: kcode>>KSR	*/
-	UINT8	mul;		/* multiple: mul_tab[ML]		*/
-
-	/* Phase Generator */
-	UINT32	Cnt;		/* frequency counter			*/
-	UINT32	Incr;		/* frequency counter step		*/
-	UINT8   FB;			/* feedback shift value			*/
-	INT32   *connect1;	/* slot1 output pointer			*/
-	INT32   op1_out[2];	/* slot1 output for feedback	*/
-	UINT8   CON;		/* connection (algorithm) type	*/
-
-	/* Envelope Generator */
-	UINT8	eg_type;	/* percussive/non-percussive mode */
-	UINT8	state;		/* phase type					*/
-	UINT32	TL;			/* total level: TL << 2			*/
-	INT32	TLL;		/* adjusted now TL				*/
-	INT32	volume;		/* envelope counter				*/
-	UINT32	sl;			/* sustain level: sl_tab[SL]	*/
-	UINT8	eg_sh_ar;	/* (attack state)				*/
-	UINT8	eg_sel_ar;	/* (attack state)				*/
-	UINT8	eg_sh_dr;	/* (decay state)				*/
-	UINT8	eg_sel_dr;	/* (decay state)				*/
-	UINT8	eg_sh_rr;	/* (release state)				*/
-	UINT8	eg_sel_rr;	/* (release state)				*/
-	UINT32	key;		/* 0 = KEY OFF, >0 = KEY ON		*/
-
-	/* LFO */
-	UINT32	AMmask;		/* LFO Amplitude Modulation enable mask */
-	UINT8	vib;		/* LFO Phase Modulation enable flag (active high)*/
-
-	/* waveform select */
-	unsigned int wavetable;
-} OPL_SLOT;
-
-typedef struct{
-	OPL_SLOT SLOT[2];
-	/* phase generator state */
-	UINT32  block_fnum;	/* block+fnum					*/
-	UINT32  fc;			/* Freq. Increment base			*/
-	UINT32  ksl_base;	/* KeyScaleLevel Base step		*/
-	UINT8   kcode;		/* key code (for key scaling)	*/
-} OPL_CH;
-
-/* OPL state */
-typedef struct fm_opl_f {
-	/* FM channel slots */
-	OPL_CH	P_CH[9];				/* OPL/OPL2 chips have 9 channels*/
-
-	UINT32	eg_cnt;					/* global envelope generator counter	*/
-	UINT32	eg_timer;				/* global envelope generator counter works at frequency = chipclock/72 */
-	UINT32	eg_timer_add;			/* step of eg_timer						*/
-	UINT32	eg_timer_overflow;		/* envelope generator timer overlfows every 1 sample (on real chip) */
-
-	UINT8	rhythm;					/* Rhythm mode					*/
-
-	UINT32	fn_tab[1024];			/* fnumber->increment counter	*/
-
-	/* LFO */
-	UINT8	lfo_am_depth;
-	UINT8	lfo_pm_depth_range;
-	UINT32	lfo_am_cnt;
-	UINT32	lfo_am_inc;
-	UINT32	lfo_pm_cnt;
-	UINT32	lfo_pm_inc;
-
-	UINT32	noise_rng;				/* 23 bit noise shift register	*/
-	UINT32	noise_p;				/* current noise 'phase'		*/
-	UINT32	noise_f;				/* current noise period			*/
-
-	UINT8	wavesel;				/* waveform select enable flag	*/
-
-	int		T[2];					/* timer counters				*/
-	int		TC[2];
-	UINT8	st[2];					/* timer enable					*/
-
-#if BUILD_Y8950
-	/* Delta-T ADPCM unit (Y8950) */
-
-	YM_DELTAT *deltat;
-
-	/* Keyboard and I/O ports interface */
-	UINT8	portDirection;
-	UINT8	portLatch;
-	OPL_PORTHANDLER_R porthandler_r;
-	OPL_PORTHANDLER_W porthandler_w;
-	int		port_param;
-	OPL_PORTHANDLER_R keyboardhandler_r;
-	OPL_PORTHANDLER_W keyboardhandler_w;
-	int		keyboard_param;
-#endif
-
-	/* external event callback handlers */
-	OPL_TIMERHANDLER  TimerHandler;	/* TIMER handler				*/
-	int TimerParam;					/* TIMER parameter				*/
-	OPL_IRQHANDLER    IRQHandler;	/* IRQ handler					*/
-	int IRQParam;					/* IRQ parameter				*/
-	OPL_UPDATEHANDLER UpdateHandler;/* stream update handler		*/
-	int UpdateParam;				/* stream update parameter		*/
-
-	UINT8 type;						/* chip type					*/
-	UINT8 address;					/* address register				*/
-	UINT8 status;					/* status flag					*/
-	UINT8 statusmask;				/* status mask					*/
-	UINT8 mode;						/* Reg.08 : CSM,notesel,etc.	*/
-
-	int clock;						/* master clock  (Hz)			*/
-	int rate;						/* sampling rate (Hz)			*/
-	double freqbase;				/* frequency base				*/
-	double TimerBase;				/* Timer base time (==sampling time)*/
-} FM_OPL;
+/* envelope phase */
+#define ENV_MOD_RR  0x00
+#define ENV_MOD_DR  0x01
+#define ENV_MOD_AR  0x02
 
-
-
-/* mapping of register number (offset) to slot number used by the emulator */
-static const int slot_array[32]=
-{
+/* -------------------- tables --------------------- */
+static const int slot_array[32] = {
 	 0, 2, 4, 1, 3, 5,-1,-1,
 	 6, 8,10, 7, 9,11,-1,-1,
 	12,14,16,13,15,17,-1,-1,
 	-1,-1,-1,-1,-1,-1,-1,-1
 };
 
-/* key scale level */
-/* table is 3dB/octave , DV converts this into 6dB/octave */
-/* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */
-#define SC(x) ((UINT32)((x)/(0.1875/2.0)))
-static const UINT32 ksl_tab[8*16]=
-{
+#define SC(mydb) ((uint) (mydb / (EG_STEP/2)))
+
+static const uint KSL_TABLE[8 * 16] = {
 	/* OCT 0 */
-	 SC(0.000), SC(0.000), SC(0.000), SC(0.000),
-	 SC(0.000), SC(0.000), SC(0.000), SC(0.000),
-	 SC(0.000), SC(0.000), SC(0.000), SC(0.000),
-	 SC(0.000), SC(0.000), SC(0.000), SC(0.000),
+	SC(0.000), SC(0.000), SC(0.000), SC(0.000),
+	SC(0.000), SC(0.000), SC(0.000), SC(0.000),
+	SC(0.000), SC(0.000), SC(0.000), SC(0.000),
+	SC(0.000), SC(0.000), SC(0.000), SC(0.000),
 	/* OCT 1 */
-	 SC(0.000), SC(0.000), SC(0.000), SC(0.000),
-	 SC(0.000), SC(0.000), SC(0.000), SC(0.000),
-	 SC(0.000), SC(0.750), SC(1.125), SC(1.500),
-	 SC(1.875), SC(2.250), SC(2.625), SC(3.000),
+	SC(0.000), SC(0.000), SC(0.000), SC(0.000),
+	SC(0.000), SC(0.000), SC(0.000), SC(0.000),
+	SC(0.000), SC(0.750), SC(1.125), SC(1.500),
+	SC(1.875), SC(2.250), SC(2.625), SC(3.000),
 	/* OCT 2 */
-	 SC(0.000), SC(0.000), SC(0.000), SC(0.000),
-	 SC(0.000), SC(1.125), SC(1.875), SC(2.625),
-	 SC(3.000), SC(3.750), SC(4.125), SC(4.500),
-	 SC(4.875), SC(5.250), SC(5.625), SC(6.000),
+	SC(0.000), SC(0.000), SC(0.000), SC(0.000),
+	SC(0.000), SC(1.125), SC(1.875), SC(2.625),
+	SC(3.000), SC(3.750), SC(4.125), SC(4.500),
+	SC(4.875), SC(5.250), SC(5.625), SC(6.000),
 	/* OCT 3 */
-	 SC(0.000), SC(0.000), SC(0.000), SC(1.875),
-	 SC(3.000), SC(4.125), SC(4.875), SC(5.625),
-	 SC(6.000), SC(6.750), SC(7.125), SC(7.500),
-	 SC(7.875), SC(8.250), SC(8.625), SC(9.000),
+	SC(0.000), SC(0.000), SC(0.000), SC(1.875),
+	SC(3.000), SC(4.125), SC(4.875), SC(5.625),
+	SC(6.000), SC(6.750), SC(7.125), SC(7.500),
+	SC(7.875), SC(8.250), SC(8.625), SC(9.000),
 	/* OCT 4 */
-	 SC(0.000), SC(0.000), SC(3.000), SC(4.875),
-	 SC(6.000), SC(7.125), SC(7.875), SC(8.625),
-	 SC(9.000), SC(9.750),SC(10.125),SC(10.500),
-	SC(10.875),SC(11.250),SC(11.625),SC(12.000),
+	SC(0.000), SC(0.000), SC(3.000), SC(4.875),
+	SC(6.000), SC(7.125), SC(7.875), SC(8.625),
+	SC(9.000), SC(9.750), SC(10.125), SC(10.500),
+	SC(10.875), SC(11.250), SC(11.625), SC(12.000),
 	/* OCT 5 */
-	 SC(0.000), SC(3.000), SC(6.000), SC(7.875),
-	 SC(9.000),SC(10.125),SC(10.875),SC(11.625),
-	SC(12.000),SC(12.750),SC(13.125),SC(13.500),
-	SC(13.875),SC(14.250),SC(14.625),SC(15.000),
+	SC(0.000), SC(3.000), SC(6.000), SC(7.875),
+	SC(9.000), SC(10.125), SC(10.875), SC(11.625),
+	SC(12.000), SC(12.750), SC(13.125), SC(13.500),
+	SC(13.875), SC(14.250), SC(14.625), SC(15.000),
 	/* OCT 6 */
-	 SC(0.000), SC(6.000), SC(9.000),SC(10.875),
-	SC(12.000),SC(13.125),SC(13.875),SC(14.625),
-	SC(15.000),SC(15.750),SC(16.125),SC(16.500),
-	SC(16.875),SC(17.250),SC(17.625),SC(18.000),
+	SC(0.000), SC(6.000), SC(9.000), SC(10.875),
+	SC(12.000), SC(13.125), SC(13.875), SC(14.625),
+	SC(15.000), SC(15.750), SC(16.125), SC(16.500),
+	SC(16.875), SC(17.250), SC(17.625), SC(18.000),
 	/* OCT 7 */
-	 SC(0.000), SC(9.000),SC(12.000),SC(13.875),
-	SC(15.000),SC(16.125),SC(16.875),SC(17.625),
-	SC(18.000),SC(18.750),SC(19.125),SC(19.500),
-	SC(19.875),SC(20.250),SC(20.625),SC(21.000)
+	SC(0.000), SC(9.000), SC(12.000), SC(13.875),
+	SC(15.000), SC(16.125), SC(16.875), SC(17.625),
+	SC(18.000), SC(18.750), SC(19.125), SC(19.500),
+	SC(19.875), SC(20.250), SC(20.625), SC(21.000)
 };
 #undef SC
 
-/* sustain level table (3dB per step) */
+
+/* sustain lebel table (3db per step) */
 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
-#define SC(db) (UINT32) ( db * (2.0/ENV_STEP) )
-static const UINT32 sl_tab[16]={
+#define SC(db) (int)(db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
+static const int SL_TABLE[16]={
  SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
  SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
 };
 #undef SC
 
 
-#define RATE_STEPS (8)
-static const unsigned char eg_inc[15*RATE_STEPS]={
-
-/*cycle:0 1  2 3  4 5  6 7*/
-
-/* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */
-/* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..12 1 */
-/* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..12 2 */
-/* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..12 3 */
-
-/* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 13 0 (increment by 1) */
-/* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 13 1 */
-/* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 13 2 */
-/* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 13 3 */
-
-/* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 14 0 (increment by 2) */
-/* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 14 1 */
-/*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 14 2 */
-/*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 14 3 */
-
-/*12 */ 4,4, 4,4, 4,4, 4,4, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 4) */
-/*13 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 2, 15 3 for attack */
-/*14 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */
-};
-
-
-#define O(a) (a*RATE_STEPS)
-
-/*note that there is no O(13) in this table - it's directly in the code */
-static const unsigned char eg_rate_select[16+64+16]={	/* Envelope Generator rates (16 + 64 rates + 16 RKS) */
-/* 16 infinite time rates */
-O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14),
-O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14),
-
-/* rates 00-12 */
-O( 0),O( 1),O( 2),O( 3),
-O( 0),O( 1),O( 2),O( 3),
-O( 0),O( 1),O( 2),O( 3),
-O( 0),O( 1),O( 2),O( 3),
-O( 0),O( 1),O( 2),O( 3),
-O( 0),O( 1),O( 2),O( 3),
-O( 0),O( 1),O( 2),O( 3),
-O( 0),O( 1),O( 2),O( 3),
-O( 0),O( 1),O( 2),O( 3),
-O( 0),O( 1),O( 2),O( 3),
-O( 0),O( 1),O( 2),O( 3),
-O( 0),O( 1),O( 2),O( 3),
-O( 0),O( 1),O( 2),O( 3),
-
-/* rate 13 */
-O( 4),O( 5),O( 6),O( 7),
-
-/* rate 14 */
-O( 8),O( 9),O(10),O(11),
-
-/* rate 15 */
-O(12),O(12),O(12),O(12),
-
-/* 16 dummy rates (same as 15 3) */
-O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12),
-O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12),
-
-};
-#undef O
-
-/*rate  0,    1,    2,    3,   4,   5,   6,  7,  8,  9,  10, 11, 12, 13, 14, 15 */
-/*shift 12,   11,   10,   9,   8,   7,   6,  5,  4,  3,  2,  1,  0,  0,  0,  0  */
-/*mask  4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7,  3,  1,  0,  0,  0,  0  */
-
-#define O(a) (a*1)
-static const unsigned char eg_rate_shift[16+64+16]={	/* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */
-/* 16 infinite time rates */
-O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
-O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
-
-/* rates 00-12 */
-O(12),O(12),O(12),O(12),
-O(11),O(11),O(11),O(11),
-O(10),O(10),O(10),O(10),
-O( 9),O( 9),O( 9),O( 9),
-O( 8),O( 8),O( 8),O( 8),
-O( 7),O( 7),O( 7),O( 7),
-O( 6),O( 6),O( 6),O( 6),
-O( 5),O( 5),O( 5),O( 5),
-O( 4),O( 4),O( 4),O( 4),
-O( 3),O( 3),O( 3),O( 3),
-O( 2),O( 2),O( 2),O( 2),
-O( 1),O( 1),O( 1),O( 1),
-O( 0),O( 0),O( 0),O( 0),
-
-/* rate 13 */
-O( 0),O( 0),O( 0),O( 0),
-
-/* rate 14 */
-O( 0),O( 0),O( 0),O( 0),
-
-/* rate 15 */
-O( 0),O( 0),O( 0),O( 0),
-
-/* 16 dummy rates (same as 15 3) */
-O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
-O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
-
-};
-#undef O
-
+#define TL_MAX (EG_ENT * 2) /* limit(tl + ksr + envelope) + sinwave */
+/* TotalLevel : 48 24 12  6  3 1.5 0.75 (dB) */
+/* TL_TABLE[ 0      to TL_MAX          ] : plus  section */
+/* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
+static int *TL_TABLE;
+
+/* pointers to TL_TABLE with sinwave output offset */
+static int **SIN_TABLE;
+
+/* LFO table */
+static int *AMS_TABLE;
+static int *VIB_TABLE;
+
+/* envelope output curve table */
+/* attack + decay + OFF */
+static int ENV_CURVE[2*EG_ENT+1];
 
 /* multiple table */
-#define SC(x) ((UINT32)((x)*2))
-static const UINT8 mul_tab[16]= {
-/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */
-   SC(0.50), SC(1.00), SC(2.00), SC(3.00), SC(4.00), SC(5.00), SC(6.00), SC(7.00),
-   SC(8.00), SC(9.00),SC(10.00),SC(10.00),SC(12.00),SC(12.00),SC(15.00),SC(15.00)
+#define ML(a) (int)(a * 2)
+static const uint MUL_TABLE[16]= {
+/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
+	ML(0.50), ML(1.00), ML(2.00),  ML(3.00), ML(4.00), ML(5.00), ML(6.00), ML(7.00),
+	ML(8.00), ML(9.00), ML(10.00), ML(10.00),ML(12.00),ML(12.00),ML(15.00),ML(15.00)
 };
-#undef SC
-
-/*	TL_TAB_LEN is calculated as:
-*	12 - sinus amplitude bits     (Y axis)
-*	2  - sinus sign bit           (Y axis)
-*	TL_RES_LEN - sinus resolution (X axis)
-*/
-#define TL_TAB_LEN (12*2*TL_RES_LEN)
-static signed int tl_tab[TL_TAB_LEN];
-
-#define ENV_QUIET		(TL_TAB_LEN>>4)
-
-/* sin waveform table in 'decibel' scale */
-/* four waveforms on OPL2 type chips */
-static unsigned int sin_tab[SIN_LEN * 4];
-
-
-/* LFO Amplitude Modulation table (verified on real YM3812)
-   27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples
-
-   Length: 210 elements.
-
-	Each of the elements has to be repeated
-	exactly 64 times (on 64 consecutive samples).
-	The whole table takes: 64 * 210 = 13440 samples.
-
-	When AM = 1 data is used directly
-	When AM = 0 data is divided by 4 before being used (loosing precision is important)
-*/
-
-#define LFO_AM_TAB_ELEMENTS 210
-
-static const UINT8 lfo_am_table[LFO_AM_TAB_ELEMENTS] = {
-0,0,0,0,0,0,0,
-1,1,1,1,
-2,2,2,2,
-3,3,3,3,
-4,4,4,4,
-5,5,5,5,
-6,6,6,6,
-7,7,7,7,
-8,8,8,8,
-9,9,9,9,
-10,10,10,10,
-11,11,11,11,
-12,12,12,12,
-13,13,13,13,
-14,14,14,14,
-15,15,15,15,
-16,16,16,16,
-17,17,17,17,
-18,18,18,18,
-19,19,19,19,
-20,20,20,20,
-21,21,21,21,
-22,22,22,22,
-23,23,23,23,
-24,24,24,24,
-25,25,25,25,
-26,26,26,
-25,25,25,25,
-24,24,24,24,
-23,23,23,23,
-22,22,22,22,
-21,21,21,21,
-20,20,20,20,
-19,19,19,19,
-18,18,18,18,
-17,17,17,17,
-16,16,16,16,
-15,15,15,15,
-14,14,14,14,
-13,13,13,13,
-12,12,12,12,
-11,11,11,11,
-10,10,10,10,
-9,9,9,9,
-8,8,8,8,
-7,7,7,7,
-6,6,6,6,
-5,5,5,5,
-4,4,4,4,
-3,3,3,3,
-2,2,2,2,
-1,1,1,1
-};
-
-/* LFO Phase Modulation table (verified on real YM3812) */
-static const INT8 lfo_pm_table[8*8*2] = {
+#undef ML
 
-/* FNUM2/FNUM = 00 0xxxxxxx (0x0000) */
-0, 0, 0, 0, 0, 0, 0, 0,	/*LFO PM depth = 0*/
-0, 0, 0, 0, 0, 0, 0, 0,	/*LFO PM depth = 1*/
-
-/* FNUM2/FNUM = 00 1xxxxxxx (0x0080) */
-0, 0, 0, 0, 0, 0, 0, 0,	/*LFO PM depth = 0*/
-1, 0, 0, 0,-1, 0, 0, 0,	/*LFO PM depth = 1*/
-
-/* FNUM2/FNUM = 01 0xxxxxxx (0x0100) */
-1, 0, 0, 0,-1, 0, 0, 0,	/*LFO PM depth = 0*/
-2, 1, 0,-1,-2,-1, 0, 1,	/*LFO PM depth = 1*/
-
-/* FNUM2/FNUM = 01 1xxxxxxx (0x0180) */
-1, 0, 0, 0,-1, 0, 0, 0,	/*LFO PM depth = 0*/
-3, 1, 0,-1,-3,-1, 0, 1,	/*LFO PM depth = 1*/
-
-/* FNUM2/FNUM = 10 0xxxxxxx (0x0200) */
-2, 1, 0,-1,-2,-1, 0, 1,	/*LFO PM depth = 0*/
-4, 2, 0,-2,-4,-2, 0, 2,	/*LFO PM depth = 1*/
-
-/* FNUM2/FNUM = 10 1xxxxxxx (0x0280) */
-2, 1, 0,-1,-2,-1, 0, 1,	/*LFO PM depth = 0*/
-5, 2, 0,-2,-5,-2, 0, 2,	/*LFO PM depth = 1*/
-
-/* FNUM2/FNUM = 11 0xxxxxxx (0x0300) */
-3, 1, 0,-1,-3,-1, 0, 1,	/*LFO PM depth = 0*/
-6, 3, 0,-3,-6,-3, 0, 3,	/*LFO PM depth = 1*/
-
-/* FNUM2/FNUM = 11 1xxxxxxx (0x0380) */
-3, 1, 0,-1,-3,-1, 0, 1,	/*LFO PM depth = 0*/
-7, 3, 0,-3,-7,-3, 0, 3	/*LFO PM depth = 1*/
-};
+/* dummy attack / decay rate ( when rate == 0 ) */
+static int RATE_0[16]=
+{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
+/* -------------------- static state --------------------- */
 
 /* lock level of common table */
 static int num_lock = 0;
 
-
-static void *cur_chip = NULL;	/* current chip pointer */
+/* work table */
+static void *cur_chip = NULL;	/* current chip point */
+/* currenct chip state */
+/* static OPLSAMPLE  *bufL,*bufR; */
+static OPL_CH *S_CH;
+static OPL_CH *E_CH;
 static OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2;
 
-static signed int phase_modulation;	/* phase modulation input (SLOT 2) */
-static signed int output[1];
-
-#if BUILD_Y8950
-static INT32 output_deltat[4];		/* for Y8950 DELTA-T, chip is mono, that 4 here is just for safety */
-#endif
-
-static UINT32	LFO_AM;
-static INT32	LFO_PM;
-
-
-
-INLINE int limit( int val, int max, int min ) {
+static int outd[1];
+static int ams;
+static int vib;
+static int *ams_table;
+static int *vib_table;
+static int amsIncr;
+static int vibIncr;
+static int feedback2;		/* connect for SLOT 2 */
+
+/* --------------------- subroutines  --------------------- */
+
+static inline int Limit(int val, int max, int min) {
+#ifdef PSP
+	return __builtin_allegrex_max(__builtin_allegrex_min(val, max), min);
+#else
 	if ( val > max )
 		val = max;
 	else if ( val < min )
 		val = min;
 
 	return val;
+#endif
 }
 
-
 /* status set and IRQ handling */
-INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag)
-{
+static inline void OPL_STATUS_SET(FM_OPL *OPL, int flag) {
 	/* set status flag */
 	OPL->status |= flag;
-	if(!(OPL->status & 0x80))
-	{
-		if(OPL->status & OPL->statusmask)
-		{	/* IRQ on */
+	if(!(OPL->status & 0x80)) {
+		if(OPL->status & OPL->statusmask) {	/* IRQ on */
 			OPL->status |= 0x80;
 			/* callback user interrupt handler (IRQ is OFF to ON) */
-			if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1);
+			if(OPL->IRQHandler)
+				(OPL->IRQHandler)(OPL->IRQParam,1);
 		}
 	}
 }
 
 /* status reset and IRQ handling */
-INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
-{
+static inline void OPL_STATUS_RESET(FM_OPL *OPL, int flag) {
 	/* reset status flag */
-	OPL->status &=~flag;
-	if((OPL->status & 0x80))
-	{
-		if (!(OPL->status & OPL->statusmask) )
-		{
+	OPL->status &= ~flag;
+	if((OPL->status & 0x80)) {
+		if (!(OPL->status & OPL->statusmask)) {
 			OPL->status &= 0x7f;
 			/* callback user interrupt handler (IRQ is ON to OFF) */
 			if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
@@ -685,1833 +251,865 @@
 }
 
 /* IRQ mask set */
-INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag)
-{
+static inline void OPL_STATUSMASK_SET(FM_OPL *OPL, int flag) {
 	OPL->statusmask = flag;
 	/* IRQ handling check */
 	OPL_STATUS_SET(OPL,0);
 	OPL_STATUS_RESET(OPL,0);
 }
 
-
-/* advance LFO to next sample */
-INLINE void advance_lfo(FM_OPL *OPL)
-{
-	UINT8 tmp;
-
-	/* LFO */
-	OPL->lfo_am_cnt += OPL->lfo_am_inc;
-	if (OPL->lfo_am_cnt >= (LFO_AM_TAB_ELEMENTS<<LFO_SH) )	/* lfo_am_table is 210 elements long */
-		OPL->lfo_am_cnt -= (LFO_AM_TAB_ELEMENTS<<LFO_SH);
-
-	tmp = lfo_am_table[ OPL->lfo_am_cnt >> LFO_SH ];
-
-	if (OPL->lfo_am_depth)
-		LFO_AM = tmp;
-	else
-		LFO_AM = tmp>>2;
-
-	OPL->lfo_pm_cnt += OPL->lfo_pm_inc;
-	LFO_PM = ((OPL->lfo_pm_cnt>>LFO_SH) & 7) | OPL->lfo_pm_depth_range;
-}
-
-/* advance to next sample */
-INLINE void advance(FM_OPL *OPL)
-{
-	OPL_CH *CH;
-	OPL_SLOT *op;
-	int i;
-
-	OPL->eg_timer += OPL->eg_timer_add;
-
-	while (OPL->eg_timer >= OPL->eg_timer_overflow)
-	{
-		OPL->eg_timer -= OPL->eg_timer_overflow;
-
-		OPL->eg_cnt++;
-
-		for (i=0; i<9*2; i++)
-		{
-			CH  = &OPL->P_CH[i/2];
-			op  = &CH->SLOT[i&1];
-
-			/* Envelope Generator */
-			switch(op->state)
-			{
-			case EG_ATT:		/* attack phase */
-				if ( !(OPL->eg_cnt & ((1<<op->eg_sh_ar)-1) ) )
-				{
-					op->volume += (~op->volume *
-	                        		           (eg_inc[op->eg_sel_ar + ((OPL->eg_cnt>>op->eg_sh_ar)&7)])
-        			                          ) >>3;
-
-					if (op->volume <= MIN_ATT_INDEX)
-					{
-						op->volume = MIN_ATT_INDEX;
-						op->state = EG_DEC;
-					}
-
-				}
-			break;
-
-			case EG_DEC:	/* decay phase */
-				if ( !(OPL->eg_cnt & ((1<<op->eg_sh_dr)-1) ) )
-				{
-					op->volume += eg_inc[op->eg_sel_dr + ((OPL->eg_cnt>>op->eg_sh_dr)&7)];
-
-					if ( op->volume >= op->sl )
-						op->state = EG_SUS;
-
-				}
-			break;
-
-			case EG_SUS:	/* sustain phase */
-
-				/* this is important behaviour:
-				one can change percusive/non-percussive modes on the fly and
-				the chip will remain in sustain phase - verified on real YM3812 */
-
-				if(op->eg_type)		/* non-percussive mode */
-				{
-									/* do nothing */
-				}
-				else				/* percussive mode */
-				{
-					/* during sustain phase chip adds Release Rate (in percussive mode) */
-					if ( !(OPL->eg_cnt & ((1<<op->eg_sh_rr)-1) ) )
-					{
-						op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)];
-
-						if ( op->volume >= MAX_ATT_INDEX )
-							op->volume = MAX_ATT_INDEX;
-					}
-					/* else do nothing in sustain phase */
-				}
+/* ----- key on  ----- */
+static inline void OPL_KEYON(OPL_SLOT *SLOT) {
+	/* sin wave restart */
+	SLOT->Cnt = 0;
+	/* set attack */
+	SLOT->evm = ENV_MOD_AR;
+	SLOT->evs = SLOT->evsa;
+	SLOT->evc = EG_AST;
+	SLOT->eve = EG_AED;
+}
+
+/* ----- key off ----- */
+static inline void OPL_KEYOFF(OPL_SLOT *SLOT) {
+	if( SLOT->evm > ENV_MOD_RR) {
+		/* set envelope counter from envleope output */
+
+		// WORKAROUND: The Kyra engine does something very strange when
+		// starting a new song. For each channel:
+		//
+		// * The release rate is set to "fastest".
+		// * Any note is keyed off.
+		// * A very low-frequency note is keyed on.
+		//
+		// Usually, what happens next is that the real notes is keyed
+		// on immediately, in which case there's no problem.
+		//
+		// However, if the note is again keyed off (because the channel
+		// begins on a rest rather than a note), the envelope counter
+		// was moved from the very lowest point on the attack curve to
+		// the very highest point on the release curve.
+		//
+		// Again, this might not be a problem, if the release rate is
+		// still set to "fastest". But in many cases, it had already
+		// been increased. And, possibly because of inaccuracies in the
+		// envelope generator, that would cause the note to "fade out"
+		// for quite a long time.
+		//
+		// What we really need is a way to find the correct starting
+		// point for the envelope counter, and that may be what the
+		// commented-out line below is meant to do. For now, simply
+		// handle the pathological case.
+
+		if (SLOT->evm == ENV_MOD_AR && SLOT->evc == EG_AST)
+			SLOT->evc = EG_DED;
+		else if( !(SLOT->evc & EG_DST) )
+			//SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
+			SLOT->evc = EG_DST;
+		SLOT->eve = EG_DED;
+		SLOT->evs = SLOT->evsr;
+		SLOT->evm = ENV_MOD_RR;
+	}
+}
+
+/* ---------- calcrate Envelope Generator & Phase Generator ---------- */
+
+/* return : envelope output */
+static inline uint OPL_CALC_SLOT(OPL_SLOT *SLOT) {
+	/* calcrate envelope generator */
+	if((SLOT->evc += SLOT->evs) >= SLOT->eve) {
+		switch( SLOT->evm ) {
+		case ENV_MOD_AR: /* ATTACK -> DECAY1 */
+			/* next DR */
+			SLOT->evm = ENV_MOD_DR;
+			SLOT->evc = EG_DST;
+			SLOT->eve = SLOT->SL;
+			SLOT->evs = SLOT->evsd;
 			break;
-
-			case EG_REL:	/* release phase */
-				if ( !(OPL->eg_cnt & ((1<<op->eg_sh_rr)-1) ) )
-				{
-					op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)];
-
-					if ( op->volume >= MAX_ATT_INDEX )
-					{
-						op->volume = MAX_ATT_INDEX;
-						op->state = EG_OFF;
-					}
-
-				}
+		case ENV_MOD_DR: /* DECAY -> SL or RR */
+			SLOT->evc = SLOT->SL;
+			SLOT->eve = EG_DED;
+			if(SLOT->eg_typ) {
+				SLOT->evs = 0;
+			} else {
+				SLOT->evm = ENV_MOD_RR;
+				SLOT->evs = SLOT->evsr;
+			}
 			break;
-
-			default:
+		case ENV_MOD_RR: /* RR -> OFF */
+			SLOT->evc = EG_OFF;
+			SLOT->eve = EG_OFF + 1;
+			SLOT->evs = 0;
 			break;
-			}
 		}
 	}
+	/* calcrate envelope */
+	return SLOT->TLL + ENV_CURVE[SLOT->evc>>ENV_BITS] + (SLOT->ams ? ams : 0);
+}
 
-	for (i=0; i<9*2; i++)
-	{
-		CH  = &OPL->P_CH[i/2];
-		op  = &CH->SLOT[i&1];
-
-		/* Phase Generator */
-		if(op->vib)
-		{
-			UINT8 block;
-			unsigned int block_fnum = CH->block_fnum;
-
-			unsigned int fnum_lfo   = (block_fnum&0x0380) >> 7;
+/* set algorythm connection */
+static void set_algorythm(OPL_CH *CH) {
+	int *carrier = &outd[0];
+	CH->connect1 = CH->CON ? carrier : &feedback2;
+	CH->connect2 = carrier;
+}
 
-			signed int lfo_fn_table_index_offset = lfo_pm_table[LFO_PM + 16*fnum_lfo ];
+/* ---------- frequency counter for operater update ---------- */
+static inline void CALC_FCSLOT(OPL_CH *CH, OPL_SLOT *SLOT) {
+	int ksr;
 
-			if (lfo_fn_table_index_offset)	/* LFO phase modulation active */
-			{
-				block_fnum += lfo_fn_table_index_offset;
-				block = (block_fnum&0x1c00) >> 10;
-				op->Cnt += (OPL->fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul;
-			}
-			else	/* LFO phase modulation  = zero */
-			{
-				op->Cnt += op->Incr;
-			}
-		}
-		else	/* LFO phase modulation disabled for this operator */
-		{
-			op->Cnt += op->Incr;
-		}
-	}
+	/* frequency step counter */
+	SLOT->Incr = CH->fc * SLOT->mul;
+	ksr = CH->kcode >> SLOT->KSR;
 
-	/*	The Noise Generator of the YM3812 is 23-bit shift register.
-	*	Period is equal to 2^23-2 samples.
-	*	Register works at sampling frequency of the chip, so output
-	*	can change on every sample.
-	*
-	*	Output of the register and input to the bit 22 is:
-	*	bit0 XOR bit14 XOR bit15 XOR bit22
-	*
-	*	Simply use bit 22 as the noise output.
-	*/
-
-	OPL->noise_p += OPL->noise_f;
-	i = OPL->noise_p >> FREQ_SH;		/* number of events (shifts of the shift register) */
-	OPL->noise_p &= FREQ_MASK;
-	while (i)
-	{
-		/*
-		UINT32 j;
-		j = ( (OPL->noise_rng) ^ (OPL->noise_rng>>14) ^ (OPL->noise_rng>>15) ^ (OPL->noise_rng>>22) ) & 1;
-		OPL->noise_rng = (j<<22) | (OPL->noise_rng>>1);
-		*/
-
-		/*
-			Instead of doing all the logic operations above, we
-			use a trick here (and use bit 0 as the noise output).
-			The difference is only that the noise bit changes one
-			step ahead. This doesn't matter since we don't know
-			what is real state of the noise_rng after the reset.
-		*/
-
-		if (OPL->noise_rng & 1) OPL->noise_rng ^= 0x800302;
-		OPL->noise_rng >>= 1;
-
-		i--;
+	if( SLOT->ksr != ksr ) {
+		SLOT->ksr = ksr;
+		/* attack , decay rate recalcration */
+		SLOT->evsa = SLOT->AR[ksr];
+		SLOT->evsd = SLOT->DR[ksr];
+		SLOT->evsr = SLOT->RR[ksr];
 	}
+	SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
 }
 
-
-INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab)
-{
-	UINT32 p;
-
-	p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm<<16))) >> FREQ_SH ) & SIN_MASK) ];
-
-	if (p >= TL_TAB_LEN)
-		return 0;
-	return tl_tab[p];
+/* set multi,am,vib,EG-TYP,KSR,mul */
+static inline void set_mul(FM_OPL *OPL, int slot, int v) {
+	OPL_CH   *CH   = &OPL->P_CH[slot / 2];
+	OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
+
+	SLOT->mul    = MUL_TABLE[v & 0x0f];
+	SLOT->KSR    = (v & 0x10) ? 0 : 2;
+	SLOT->eg_typ = (v & 0x20) >> 5;
+	SLOT->vib    = (v & 0x40);
+	SLOT->ams    = (v & 0x80);
+	CALC_FCSLOT(CH, SLOT);
 }
 
-INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab)
-{
-	UINT32 p;
+/* set ksl & tl */
+static inline void set_ksl_tl(FM_OPL *OPL, int slot, int v) {
+	OPL_CH   *CH   = &OPL->P_CH[slot / 2];
+	OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
+	int ksl = v >> 6; /* 0 / 1.5 / 3 / 6 db/OCT */
 
-	p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm      )) >> FREQ_SH ) & SIN_MASK) ];
+	SLOT->ksl = ksl ? 3-ksl : 31;
+	SLOT->TL  = (int)((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */
 
-	if (p >= TL_TAB_LEN)
-		return 0;
-	return tl_tab[p];
+	if(!(OPL->mode & 0x80)) {	/* not CSM latch total level */
+		SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl);
+	}
 }
 
+/* set attack rate & decay rate  */
+static inline void set_ar_dr(FM_OPL *OPL, int slot, int v) {
+	OPL_CH   *CH   = &OPL->P_CH[slot / 2];
+	OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
+	int ar = v >> 4;
+	int dr = v & 0x0f;
+
+	SLOT->AR = ar ? &OPL->AR_TABLE[ar << 2] : RATE_0;
+	SLOT->evsa = SLOT->AR[SLOT->ksr];
+	if(SLOT->evm == ENV_MOD_AR)
+		SLOT->evs = SLOT->evsa;
+
+	SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
+	SLOT->evsd = SLOT->DR[SLOT->ksr];
+	if(SLOT->evm == ENV_MOD_DR)
+		SLOT->evs = SLOT->evsd;
+}
 
-#define volume_calc(OP) ((OP)->TLL + ((UINT32)(OP)->volume) + (LFO_AM & (OP)->AMmask))
-
-/* calculate output */
-INLINE void OPL_CALC_CH( OPL_CH *CH )
-{
+/* set sustain level & release rate */
+static inline void set_sl_rr(FM_OPL *OPL, int slot, int v) {
+	OPL_CH   *CH   = &OPL->P_CH[slot / 2];
+	OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
+	int sl = v >> 4;
+	int rr = v & 0x0f;
+
+	SLOT->SL = SL_TABLE[sl];
+	if(SLOT->evm == ENV_MOD_DR)
+		SLOT->eve = SLOT->SL;
+	SLOT->RR = &OPL->DR_TABLE[rr<<2];
+	SLOT->evsr = SLOT->RR[SLOT->ksr];
+	if(SLOT->evm == ENV_MOD_RR)
+		SLOT->evs = SLOT->evsr;
+}
+
+/* operator output calcrator */
+
+#define OP_OUT(slot,env,con)   slot->wavetable[((slot->Cnt + con) / (0x1000000 / SIN_ENT)) & (SIN_ENT-1)][env]
+/* ---------- calcrate one of channel ---------- */
+static inline void OPL_CALC_CH(OPL_CH *CH) {
+	uint env_out;
 	OPL_SLOT *SLOT;
-	unsigned int env;
-	signed int out;
-
-	phase_modulation = 0;
 
+	feedback2 = 0;
 	/* SLOT 1 */
 	SLOT = &CH->SLOT[SLOT1];
-	env  = volume_calc(SLOT);
-	out  = SLOT->op1_out[0] + SLOT->op1_out[1];
-	SLOT->op1_out[0] = SLOT->op1_out[1];
-	*SLOT->connect1 += SLOT->op1_out[0];
-	SLOT->op1_out[1] = 0;
-	if( env < ENV_QUIET )
-	{
-		if (!SLOT->FB)
-			out = 0;
-		SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<<SLOT->FB), SLOT->wavetable );
+	env_out=OPL_CALC_SLOT(SLOT);
+	if(env_out < (EG_ENT - 1)) {
+		/* PG */
+		if(SLOT->vib)
+			SLOT->Cnt += (SLOT->Incr * vib / VIB_RATE);
+		else
+			SLOT->Cnt += SLOT->Incr;
+		/* connectoion */
+		if(CH->FB) {
+			int feedback1 = (CH->op1_out[0] + CH->op1_out[1]) >> CH->FB;
+			CH->op1_out[1] = CH->op1_out[0];
+			*CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
+		} else {
+			*CH->connect1 += OP_OUT(SLOT, env_out, 0);
+		}
+	} else {
+		CH->op1_out[1] = CH->op1_out[0];
+		CH->op1_out[0] = 0;
 	}
-
 	/* SLOT 2 */
-	SLOT++;
-	env = volume_calc(SLOT);
-	if( env < ENV_QUIET )
-		output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable);
+	SLOT = &CH->SLOT[SLOT2];
+	env_out=OPL_CALC_SLOT(SLOT);
+	if(env_out < (EG_ENT - 1)) {
+		/* PG */
+		if(SLOT->vib)
+			SLOT->Cnt += (SLOT->Incr * vib / VIB_RATE);
+		else
+			SLOT->Cnt += SLOT->Incr;
+		/* connectoion */
+		outd[0] += OP_OUT(SLOT, env_out, feedback2);
+	}
 }
 
-/*
-	operators used in the rhythm sounds generation process:
-
-	Envelope Generator:
-
-channel  operator  register number   Bass  High  Snare Tom  Top
-/ slot   number    TL ARDR SLRR Wave Drum  Hat   Drum  Tom  Cymbal
- 6 / 0   12        50  70   90   f0  +
- 6 / 1   15        53  73   93   f3  +
- 7 / 0   13        51  71   91   f1        +
- 7 / 1   16        54  74   94   f4              +
- 8 / 0   14        52  72   92   f2                    +
- 8 / 1   17        55  75   95   f5                          +
-
-	Phase Generator:
-
-channel  operator  register number   Bass  High  Snare Tom  Top
-/ slot   number    MULTIPLE          Drum  Hat   Drum  Tom  Cymbal
- 6 / 0   12        30                +
- 6 / 1   15        33                +
- 7 / 0   13        31                      +     +           +
- 7 / 1   16        34                -----  n o t  u s e d -----
- 8 / 0   14        32                                  +
- 8 / 1   17        35                      +                 +
-
-channel  operator  register number   Bass  High  Snare Tom  Top
-number   number    BLK/FNUM2 FNUM    Drum  Hat   Drum  Tom  Cymbal
-   6     12,15     B6        A6      +
-
-   7     13,16     B7        A7            +     +           +
+/* ---------- calcrate rythm block ---------- */
+#define WHITE_NOISE_db 6.0
+static inline void OPL_CALC_RH(OPL_CH *CH) {
+	uint env_tam, env_sd, env_top, env_hh;
+	int whitenoise = (int)((rand()&1)*(WHITE_NOISE_db/EG_STEP));
 
-   8     14,17     B8        A8            +           +     +
+	int tone8;
 
-*/
-
-/* calculate rhythm */
-
-INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise )
-{
 	OPL_SLOT *SLOT;
-	signed int out;
-	unsigned int env;
-
-
-	/* Bass Drum (verified on real YM3812):
-	  - depends on the channel 6 'connect' register:
-	      when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out)
-	      when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored
-	  - output sample always is multiplied by 2
-	*/
+	int env_out;
 
-	phase_modulation = 0;
+	/* BD : same as FM serial mode and output level is large */
+	feedback2 = 0;
 	/* SLOT 1 */
 	SLOT = &CH[6].SLOT[SLOT1];
-	env = volume_calc(SLOT);
-
-	out = SLOT->op1_out[0] + SLOT->op1_out[1];
-	SLOT->op1_out[0] = SLOT->op1_out[1];
-
-	if (!SLOT->CON)
-		phase_modulation = SLOT->op1_out[0];
-	/* else ignore output of operator 1 */
-
-	SLOT->op1_out[1] = 0;
-	if( env < ENV_QUIET )
-	{
-		if (!SLOT->FB)
-			out = 0;
-		SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<<SLOT->FB), SLOT->wavetable );
+	env_out = OPL_CALC_SLOT(SLOT);
+	if(env_out < EG_ENT-1) {
+		/* PG */
+		if(SLOT->vib)
+			SLOT->Cnt += (SLOT->Incr * vib / VIB_RATE);
+		else
+			SLOT->Cnt += SLOT->Incr;
+		/* connectoion */
+		if(CH[6].FB) {
+			int feedback1 = (CH[6].op1_out[0] + CH[6].op1_out[1]) >> CH[6].FB;
+			CH[6].op1_out[1] = CH[6].op1_out[0];
+			feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
+		}
+		else {
+			feedback2 = OP_OUT(SLOT, env_out, 0);
+		}
+	} else {
+		feedback2 = 0;
+		CH[6].op1_out[1] = CH[6].op1_out[0];
+		CH[6].op1_out[0] = 0;
 	}
-
 	/* SLOT 2 */
-	SLOT++;
-	env = volume_calc(SLOT);
-	if( env < ENV_QUIET )
-		output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable) * 2;
-
-
-	/* Phase generation is based on: */
-	/* HH  (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) */
-	/* SD  (16) channel 7->slot 1 */
-	/* TOM (14) channel 8->slot 1 */
-	/* TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) */
-
-	/* Envelope generation based on: */
-	/* HH  channel 7->slot1 */
-	/* SD  channel 7->slot2 */
-	/* TOM channel 8->slot1 */
-	/* TOP channel 8->slot2 */
-
-
-	/* The following formulas can be well optimized.
-	   I leave them in direct form for now (in case I've missed something).
-	*/
-
-	/* High Hat (verified on real YM3812) */
-	env = volume_calc(SLOT7_1);
-	if( env < ENV_QUIET )
-	{
-
-		/* high hat phase generation:
-			phase = d0 or 234 (based on frequency only)
-			phase = 34 or 2d0 (based on noise)
-		*/
-
-		/* base frequency derived from operator 1 in channel 7 */
-		unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1;
-		unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1;
-		unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1;
-
-		unsigned char res1 = (bit2 ^ bit7) | bit3;
-
-		/* when res1 = 0 phase = 0x000 | 0xd0; */
-		/* when res1 = 1 phase = 0x200 | (0xd0>>2); */
-		UINT32 phase = res1 ? (0x200|(0xd0>>2)) : 0xd0;
-
-		/* enable gate based on frequency of operator 2 in channel 8 */
-		unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1;
-		unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1;
-
-		unsigned char res2 = (bit3e ^ bit5e);
-
-		/* when res2 = 0 pass the phase from calculation above (res1); */
-		/* when res2 = 1 phase = 0x200 | (0xd0>>2); */
-		if (res2)
-			phase = (0x200|(0xd0>>2));
-
-
-		/* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */
-		/* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */
-		if (phase&0x200)
-		{
-			if (noise)
-				phase = 0x200|0xd0;
-		}
+	SLOT = &CH[6].SLOT[SLOT2];
+	env_out = OPL_CALC_SLOT(SLOT);
+	if(env_out < EG_ENT-1) {
+		/* PG */
+		if(SLOT->vib)
+			SLOT->Cnt += (SLOT->Incr * vib / VIB_RATE);
 		else
-		/* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */
-		/* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */
-		{
-			if (noise)
-				phase = 0xd0>>2;
-		}
-
-		output[0] += op_calc(phase<<FREQ_SH, env, 0, SLOT7_1->wavetable) * 2;
-	}
-
-	/* Snare Drum (verified on real YM3812) */
-	env = volume_calc(SLOT7_2);
-	if( env < ENV_QUIET )
-	{
-		/* base frequency derived from operator 1 in channel 7 */
-		unsigned char bit8 = ((SLOT7_1->Cnt>>FREQ_SH)>>8)&1;
-
-		/* when bit8 = 0 phase = 0x100; */
-		/* when bit8 = 1 phase = 0x200; */
-		UINT32 phase = bit8 ? 0x200 : 0x100;
-
-		/* Noise bit XOR'es phase by 0x100 */
-		/* when noisebit = 0 pass the phase from calculation above */
-		/* when noisebit = 1 phase ^= 0x100; */
-		/* in other words: phase ^= (noisebit<<8); */
-		if (noise)
-			phase ^= 0x100;
-
-		output[0] += op_calc(phase<<FREQ_SH, env, 0, SLOT7_2->wavetable) * 2;
-	}
-
-	/* Tom Tom (verified on real YM3812) */
-	env = volume_calc(SLOT8_1);
-	if( env < ENV_QUIET )
-		output[0] += op_calc(SLOT8_1->Cnt, env, 0, SLOT8_1->wavetable) * 2;
-
-	/* Top Cymbal (verified on real YM3812) */
-	env = volume_calc(SLOT8_2);
-	if( env < ENV_QUIET )
-	{
-		/* base frequency derived from operator 1 in channel 7 */
-		unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1;
-		unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1;
-		unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1;
-
-		unsigned char res1 = (bit2 ^ bit7) | bit3;
+			SLOT->Cnt += SLOT->Incr;
+		/* connectoion */
+		outd[0] += OP_OUT(SLOT, env_out, feedback2) * 2;
+	}
+
+	// SD  (17) = mul14[fnum7] + white noise
+	// TAM (15) = mul15[fnum8]
+	// TOP (18) = fnum6(mul18[fnum8]+whitenoise)
+	// HH  (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
+	env_sd = OPL_CALC_SLOT(SLOT7_2) + whitenoise;
+	env_tam =OPL_CALC_SLOT(SLOT8_1);
+	env_top = OPL_CALC_SLOT(SLOT8_2);
+	env_hh = OPL_CALC_SLOT(SLOT7_1) + whitenoise;
+
+	/* PG */
+	if(SLOT7_1->vib)
+		SLOT7_1->Cnt += (2 * SLOT7_1->Incr * vib / VIB_RATE);
+	else
+		SLOT7_1->Cnt += 2 * SLOT7_1->Incr;
+	if(SLOT7_2->vib)
+		SLOT7_2->Cnt += ((CH[7].fc * 8) * vib / VIB_RATE);
+	else
+		SLOT7_2->Cnt += (CH[7].fc * 8);
+	if(SLOT8_1->vib)
+		SLOT8_1->Cnt += (SLOT8_1->Incr * vib / VIB_RATE);
+	else
+		SLOT8_1->Cnt += SLOT8_1->Incr;
+	if(SLOT8_2->vib)
+		SLOT8_2->Cnt += ((CH[8].fc * 48) * vib / VIB_RATE);
+	else
+		SLOT8_2->Cnt += (CH[8].fc * 48);
 
-		/* when res1 = 0 phase = 0x000 | 0x100; */
-		/* when res1 = 1 phase = 0x200 | 0x100; */
-		UINT32 phase = res1 ? 0x300 : 0x100;
+	tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
 
-		/* enable gate based on frequency of operator 2 in channel 8 */
-		unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1;
-		unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1;
+	/* SD */
+	if(env_sd < (EG_ENT - 1))
+		outd[0] += OP_OUT(SLOT7_1, env_sd, 0) * 8;
+	/* TAM */
+	if(env_tam < (EG_ENT - 1))
+		outd[0] += OP_OUT(SLOT8_1, env_tam, 0) * 2;
+	/* TOP-CY */
+	if(env_top < (EG_ENT - 1))
+		outd[0] += OP_OUT(SLOT7_2, env_top, tone8) * 2;
+	/* HH */
+	if(env_hh  < (EG_ENT-1))
+		outd[0] += OP_OUT(SLOT7_2, env_hh, tone8) * 2;
+}
 
-		unsigned char res2 = (bit3e ^ bit5e);
-		/* when res2 = 0 pass the phase from calculation above (res1); */
-		/* when res2 = 1 phase = 0x200 | 0x100; */
-		if (res2)
-			phase = 0x300;
+/* ----------- initialize time tabls ----------- */
+static void init_timetables(FM_OPL *OPL, int ARRATE, int DRRATE) {
+	int i;
+	float rate;
 
-		output[0] += op_calc(phase<<FREQ_SH, env, 0, SLOT8_2->wavetable) * 2;
+	/* make attack rate & decay rate tables */
+	for (i = 0; i < 4; i++)
+		OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
+	for (i = 4; i <= 60; i++) {
+		rate = OPL->freqbase;						/* frequency rate */
+		if(i < 60)
+			rate *= 1.0 + (i & 3) * 0.25;		/* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
+		rate *= 1 << ((i >> 2) - 1);						/* b2-5 : shift bit */
+		rate *= (float)(EG_ENT << ENV_BITS);
+		OPL->AR_TABLE[i] = (int)(rate / ARRATE);
+		OPL->DR_TABLE[i] = (int)(rate / DRRATE);
+	}
+	for (i = 60; i < 76; i++) {
+		OPL->AR_TABLE[i] = EG_AED-1;
+		OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
 	}
-
 }
 
+/* ---------- generic table initialize ---------- */
+static int OPLOpenTable(void) {
+	int s,t;
+	float rate;
+	int i,j;
+	float pom;
 
-/* generic table initialize */
-static int init_tables(void)
-{
-	signed int i,x;
-	signed int n;
-	double o,m;
-
-
-	for (x=0; x<TL_RES_LEN; x++)
-	{
-		m = (1<<16) / pow(2.0, (x+1) * (ENV_STEP/4.0) / 8.0);
-		m = floor(m);
-
-		/* we never reach (1<<16) here due to the (x+1) */
-		/* result fits within 16 bits at maximum */
-
-		n = (int)m;		/* 16 bits here */
-		n >>= 4;		/* 12 bits here */
-		if (n&1)		/* round to nearest */
-			n = (n>>1)+1;
-		else
-			n = n>>1;
-						/* 11 bits here (rounded) */
-		n <<= 1;		/* 12 bits here (as in real chip) */
-		tl_tab[ x*2 + 0 ] = n;
-		tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ];
+	/* allocate dynamic tables */
+	if((TL_TABLE = (int *)malloc(TL_MAX * 2 * sizeof(int))) == NULL)
+		return 0;
 
-		for (i=1; i<12; i++)
-		{
-			tl_tab[ x*2+0 + i*2*TL_RES_LEN ] =  tl_tab[ x*2+0 ]>>i;
-			tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ];
-		}
-	#if 0
-			logerror("tl %04i", x*2);
-			for (i=0; i<12; i++)
-				logerror(", [%02i] %5i", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ] );
-			logerror("\n");
-	#endif
+	if((SIN_TABLE = (int **)malloc(SIN_ENT * 4 * sizeof(int *))) == NULL) {
+		free(TL_TABLE);
+		return 0;
 	}
-	/*logerror("FMOPL.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/
-
-
-	for (i=0; i<SIN_LEN; i++)
-	{
-		/* non-standard sinus */
-		m = sin( ((i*2)+1) * PI / SIN_LEN ); /* checked against the real chip */
-
-		/* we never reach zero here due to ((i*2)+1) */
 
-		if (m>0.0)
-			o = 8*log(1.0/m)/log(2.0);	/* convert to 'decibels' */
-		else
-			o = 8*log(-1.0/m)/log(2.0);	/* convert to 'decibels' */
-
-		o = o / (ENV_STEP/4);
-
-		n = (int)(2.0*o);
-		if (n&1)						/* round to nearest */
-			n = (n>>1)+1;
-		else
-			n = n>>1;
-
-		sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 );
-
-		/*logerror("FMOPL.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, sin_tab[i], tl_tab[sin_tab[i]] );*/
+	if((AMS_TABLE = (int *)malloc(AMS_ENT * 2 * sizeof(int))) == NULL) {
+		free(TL_TABLE);
+		free(SIN_TABLE);
+		return 0;
 	}
-
-	for (i=0; i<SIN_LEN; i++)
-	{
-		/* waveform 1:  __      __     */
-		/*             /  \____/  \____*/
-		/* output only first half of the sinus waveform (positive one) */
-
-		if (i & (1<<(SIN_BITS-1)) )
-			sin_tab[1*SIN_LEN+i] = TL_TAB_LEN;
-		else
-			sin_tab[1*SIN_LEN+i] = sin_tab[i];
-
-		/* waveform 2:  __  __  __  __ */
-		/*             /  \/  \/  \/  \*/
-		/* abs(sin) */
-
-		sin_tab[2*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>1) ];
-
-		/* waveform 3:  _   _   _   _  */
-		/*             / |_/ |_/ |_/ |_*/
-		/* abs(output only first quarter of the sinus waveform) */
-
-		if (i & (1<<(SIN_BITS-2)) )
-			sin_tab[3*SIN_LEN+i] = TL_TAB_LEN;
-		else
-			sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)];
-
-		/*logerror("FMOPL.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] );
-		logerror("FMOPL.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] );
-		logerror("FMOPL.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] );*/
+	if((VIB_TABLE = (int *)malloc(VIB_ENT * 2 * sizeof(int))) == NULL) {
+		free(TL_TABLE);
+		free(SIN_TABLE);
+		free(AMS_TABLE);
+		return 0;
+	}
+	/* make total level table */
+	for (t = 0; t < EG_ENT - 1 ; t++) {
+		rate = ((1 << TL_BITS) - 1) / powf(10.0, EG_STEP * t / 20);	/* dB -> voltage */
+		TL_TABLE[         t] =  (int)rate;
+		TL_TABLE[TL_MAX + t] = -TL_TABLE[t];
+	}
+	/* fill volume off area */
+	for (t = EG_ENT - 1; t < TL_MAX; t++) {
+		TL_TABLE[t] = TL_TABLE[TL_MAX + t] = 0;
+	}
+
+	/* make sinwave table (total level offet) */
+	/* degree 0 = degree 180                   = off */
+	SIN_TABLE[0] = SIN_TABLE[SIN_ENT /2 ] = &TL_TABLE[EG_ENT - 1];
+	for (s = 1;s <= SIN_ENT / 4; s++) {
+		pom = sinf(2 * PI * s / SIN_ENT); /* sin     */
+		pom = 20 * log10f(1 / pom);	   /* decibel */
+		j = int(pom / EG_STEP);         /* TL_TABLE steps */
+
+		/* degree 0   -  90    , degree 180 -  90 : plus section */
+		SIN_TABLE[          s] = SIN_TABLE[SIN_ENT / 2 - s] = &TL_TABLE[j];
+		/* degree 180 - 270    , degree 360 - 270 : minus section */
+		SIN_TABLE[SIN_ENT / 2 + s] = SIN_TABLE[SIN_ENT - s] = &TL_TABLE[TL_MAX + j];
+	}
+	for (s = 0;s < SIN_ENT; s++) {
+		SIN_TABLE[SIN_ENT * 1 + s] = s < (SIN_ENT / 2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
+		SIN_TABLE[SIN_ENT * 2 + s] = SIN_TABLE[s % (SIN_ENT / 2)];
+		SIN_TABLE[SIN_ENT * 3 + s] = (s / (SIN_ENT / 4)) & 1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT * 2 + s];
+	}
+
+	/* envelope counter -> envelope output table */
+	for (i=0; i < EG_ENT; i++) {
+		/* ATTACK curve */
+		pom = powf(((float)(EG_ENT - 1 - i) / EG_ENT), 8) * EG_ENT;
+		/* if( pom >= EG_ENT ) pom = EG_ENT-1; */
+		ENV_CURVE[i] = (int)pom;
+		/* DECAY ,RELEASE curve */
+		ENV_CURVE[(EG_DST >> ENV_BITS) + i]= i;
+	}
+	/* off */
+	ENV_CURVE[EG_OFF >> ENV_BITS]= EG_ENT - 1;
+	/* make LFO ams table */
+	for (i=0; i < AMS_ENT; i++) {
+		pom = (1.0 + sinf(2 * PI * i / AMS_ENT)) / 2; /* sin */
+		AMS_TABLE[i]         = (int)((1.0 / EG_STEP) * pom); /* 1dB   */
+		AMS_TABLE[AMS_ENT + i] = (int)((4.8 / EG_STEP) * pom); /* 4.8dB */
+	}
+	/* make LFO vibrate table */
+	for (i=0; i < VIB_ENT; i++) {
+		/* 100cent = 1seminote = 6% ?? */
+		pom = (float)VIB_RATE * 0.06 * sinf(2 * PI * i / VIB_ENT); /* +-100sect step */
+		VIB_TABLE[i]         = (int)(VIB_RATE + (pom * 0.07)); /* +- 7cent */
+		VIB_TABLE[VIB_ENT + i] = (int)(VIB_RATE + (pom * 0.14)); /* +-14cent */
 	}
-	/*logerror("FMOPL.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/
-
-
-#ifdef SAVE_SAMPLE
-	sample[0]=fopen("sampsum.pcm","wb");
-#endif
-
 	return 1;
 }
 
-static void OPLCloseTable( void )
-{
-#ifdef SAVE_SAMPLE
-	fclose(sample[0]);
-#endif
+static void OPLCloseTable(void) {
+	free(TL_TABLE);
+	free(SIN_TABLE);
+	free(AMS_TABLE);
+	free(VIB_TABLE);
 }
 
-
-
-static void OPL_initalize(FM_OPL *OPL)
-{
-	int i;
+/* CSM Key Controll */
+static inline void CSMKeyControll(OPL_CH *CH) {
+	OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
+	OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
+	/* all key off */
+	OPL_KEYOFF(slot1);
+	OPL_KEYOFF(slot2);
+	/* total level latch */
+	slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
+	slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
+	/* key on */
+	CH->op1_out[0] = CH->op1_out[1] = 0;
+	OPL_KEYON(slot1);
+	OPL_KEYON(slot2);
+}
+
+/* ---------- opl initialize ---------- */
+static void OPL_initalize(FM_OPL *OPL) {
+	int fn;
 
 	/* frequency base */
-	OPL->freqbase  = (OPL->rate) ? ((double)OPL->clock / 72.0) / OPL->rate  : 0;
-#if 0
-	OPL->rate = (double)OPL->clock / 72.0;
-	OPL->freqbase  = 1.0;
-#endif
-
-	/*logerror("freqbase=%f\n", OPL->freqbase);*/
-
+	OPL->freqbase = (OPL->rate) ? ((float)OPL->clock / OPL->rate) / 72 : 0;
 	/* Timer base time */
-	OPL->TimerBase = 1.0 / ((double)OPL->clock / 72.0 );
-
+	OPL->TimerBase = 1.0/((float)OPL->clock / 72.0 );
+	/* make time tables */
+	init_timetables(OPL, OPL_ARRATE, OPL_DRRATE);
 	/* make fnumber -> increment counter table */
-	for( i=0 ; i < 1024 ; i++ )
-	{
-		/* opn phase increment counter = 20bit */
-		OPL->fn_tab[i] = (UINT32)( (double)i * 64 * OPL->freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */
-#if 0
-		logerror("FMOPL.C: fn_tab[%4i] = %08x (dec=%8i)\n",
-				 i, OPL->fn_tab[i]>>6, OPL->fn_tab[i]>>6 );
-#endif
-	}
-
-#if 0
-	for( i=0 ; i < 16 ; i++ )
-	{
-		logerror("FMOPL.C: sl_tab[%i] = %08x\n",
-			i, sl_tab[i] );
-	}
-	for( i=0 ; i < 8 ; i++ )
-	{
-		int j;
-		logerror("FMOPL.C: ksl_tab[oct=%2i] =",i);
-		for (j=0; j<16; j++)
-		{
-			logerror("%08x ", ksl_tab[i*16+j] );
-		}
-		logerror("\n");
-	}
-#endif
-
-
-	/* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */
-	/* One entry from LFO_AM_TABLE lasts for 64 samples */
-	OPL->lfo_am_inc = (UINT32)((1.0 / 64.0 ) * (1<<LFO_SH) * OPL->freqbase);
-
-	/* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */
-	OPL->lfo_pm_inc = (UINT32)((1.0 / 1024.0) * (1<<LFO_SH) * OPL->freqbase);
-
-	/*logerror ("OPL->lfo_am_inc = %8x ; OPL->lfo_pm_inc = %8x\n", OPL->lfo_am_inc, OPL->lfo_pm_inc);*/
-
-	/* Noise generator: a step takes 1 sample */
-	OPL->noise_f = (UINT32)((1.0 / 1.0) * (1<<FREQ_SH) * OPL->freqbase);
-
-	OPL->eg_timer_add  = (UINT32)((1<<EG_SH)  * OPL->freqbase);
-	OPL->eg_timer_overflow = ( 1 ) * (1<<EG_SH);
-	/*logerror("OPLinit eg_timer_add=%8x eg_timer_overflow=%8x\n", OPL->eg_timer_add, OPL->eg_timer_overflow);*/
-
-}
-
-INLINE void FM_KEYON(OPL_SLOT *SLOT, UINT32 key_set)
-{
-	if( !SLOT->key )
-	{
-		/* restart Phase Generator */
-		SLOT->Cnt = 0;
-		/* phase -> Attack */
-		SLOT->state = EG_ATT;
-	}
-	SLOT->key |= key_set;
-}
-
-INLINE void FM_KEYOFF(OPL_SLOT *SLOT, UINT32 key_clr)
-{
-	if( SLOT->key )
-	{
-		SLOT->key &= key_clr;
-
-		if( !SLOT->key )
-		{
-			/* phase -> Release */
-			if (SLOT->state>EG_REL)
-				SLOT->state = EG_REL;
-		}
+	for( fn=0; fn < 1024; fn++) {
+		OPL->FN_TABLE[fn] = (uint)(OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2);
 	}
+	/* LFO freq.table */
+	OPL->amsIncr = (int)(OPL->rate ? (float)AMS_ENT * (1 << AMS_SHIFT) / OPL->rate * 3.7 * ((float)OPL->clock/3600000) : 0);
+	OPL->vibIncr = (int)(OPL->rate ? (float)VIB_ENT * (1 << VIB_SHIFT) / OPL->rate * 6.4 * ((float)OPL->clock/3600000) : 0);
 }
 
-/* update phase increment counter of operator (also update the EG rates if necessary) */
-INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
-{
-	int ksr;
-
-	/* (frequency) phase increment counter */
-	SLOT->Incr = CH->fc * SLOT->mul;
-	ksr = CH->kcode >> SLOT->KSR;
-
-	if( SLOT->ksr != ksr )
-	{
-		SLOT->ksr = ksr;
+/* ---------- write a OPL registers ---------- */
+static void OPLWriteReg(FM_OPL *OPL, int r, int v) {
+	OPL_CH *CH;
+	int slot;
+	uint block_fnum;
 
-		/* calculate envelope generator rates */
-		if ((SLOT->ar + SLOT->ksr) < 16+62)
-		{
-			SLOT->eg_sh_ar  = eg_rate_shift [SLOT->ar + SLOT->ksr ];
-			SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
-		}
-		else
-		{
-			SLOT->eg_sh_ar  = 0;
-			SLOT->eg_sel_ar = 13*RATE_STEPS;
-		}
-		SLOT->eg_sh_dr  = eg_rate_shift [SLOT->dr + SLOT->ksr ];
-		SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ];
-		SLOT->eg_sh_rr  = eg_rate_shift [SLOT->rr + SLOT->ksr ];
-		SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ];
-	}
-}
-
-/* set multi,am,vib,EG-TYP,KSR,mul */
-INLINE void set_mul(FM_OPL *OPL,int slot,int v)
-{
-	OPL_CH   *CH   = &OPL->P_CH[slot/2];
-	OPL_SLOT *SLOT = &CH->SLOT[slot&1];
-
-	SLOT->mul     = mul_tab[v&0x0f];
-	SLOT->KSR     = (v&0x10) ? 0 : 2;
-	SLOT->eg_type = (v&0x20);
-	SLOT->vib     = (v&0x40);
-	SLOT->AMmask  = (v&0x80) ? ~0 : 0;
-	CALC_FCSLOT(CH,SLOT);
-}
-
-/* set ksl & tl */
-INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v)
-{
-	OPL_CH   *CH   = &OPL->P_CH[slot/2];
-	OPL_SLOT *SLOT = &CH->SLOT[slot&1];
-	int ksl = v>>6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */
-
-	SLOT->ksl = ksl ? 3-ksl : 31;
-	SLOT->TL  = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */
-
-	SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
-}
-
-/* set attack rate & decay rate  */
-INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v)
-{
-	OPL_CH   *CH   = &OPL->P_CH[slot/2];
-	OPL_SLOT *SLOT = &CH->SLOT[slot&1];
-
-	SLOT->ar = (v>>4)  ? 16 + ((v>>4)  <<2) : 0;
-
-	if ((SLOT->ar + SLOT->ksr) < 16+62)
-	{
-		SLOT->eg_sh_ar  = eg_rate_shift [SLOT->ar + SLOT->ksr ];
-		SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
-	}
-	else
-	{
-		SLOT->eg_sh_ar  = 0;
-		SLOT->eg_sel_ar = 13*RATE_STEPS;
-	}
-
-	SLOT->dr    = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0;
-	SLOT->eg_sh_dr  = eg_rate_shift [SLOT->dr + SLOT->ksr ];
-	SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ];
-}
-
-/* set sustain level & release rate */
-INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v)
-{
-	OPL_CH   *CH   = &OPL->P_CH[slot/2];
-	OPL_SLOT *SLOT = &CH->SLOT[slot&1];
-
-	SLOT->sl  = sl_tab[ v>>4 ];
-
-	SLOT->rr  = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0;
-	SLOT->eg_sh_rr  = eg_rate_shift [SLOT->rr + SLOT->ksr ];
-	SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ];
-}
-
-
-/* write a value v to register r on OPL chip */
-static void OPLWriteReg(FM_OPL *OPL, int r, int v)
-{
-	OPL_CH *CH;
-	int slot;
-	int block_fnum;
-
-
-	/* adjust bus to 8 bits */
-	r &= 0xff;
-	v &= 0xff;
-
-#ifdef LOG_CYM_FILE
-	if ((cymfile) && (r!=0) )
-	{
-		fputc( (unsigned char)r, cymfile );
-		fputc( (unsigned char)v, cymfile );
-	}
-#endif
-
-
-	switch(r&0xe0)
-	{
-	case 0x00:	/* 00-1f:control */
-		switch(r&0x1f)
-		{
-		case 0x01:	/* waveform select enable */
-			if(OPL->type&OPL_TYPE_WAVESEL)
-			{
-				OPL->wavesel = v&0x20;
-				/* do not change the waveform previously selected */
+	switch(r & 0xe0) {
+	case 0x00: /* 00-1f:controll */
+		switch(r & 0x1f) {
+		case 0x01:
+			/* wave selector enable */
+			if(OPL->type&OPL_TYPE_WAVESEL) {
+				OPL->wavesel = v & 0x20;
+				if(!OPL->wavesel) {
+					/* preset compatible mode */
+					int c;
+					for(c=0; c<OPL->max_ch; c++) {
+						OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
+						OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
+					}
+				}
 			}
-			break;
+			return;
 		case 0x02:	/* Timer 1 */
-			OPL->T[0] = (256-v)*4;
+			OPL->T[0] = (256-v) * 4;
 			break;
 		case 0x03:	/* Timer 2 */
-			OPL->T[1] = (256-v)*16;
-			break;
+			OPL->T[1] = (256-v) * 16;
+			return;
 		case 0x04:	/* IRQ clear / mask and Timer enable */
-			if(v&0x80)
-			{	/* IRQ flag clear */
-				OPL_STATUS_RESET(OPL,0x7f);
-			}
-			else
-			{	/* set IRQ mask ,timer enable*/
-				OPL->st[0] = v&1;
-				OPL->st[1] = (v>>1)&1;
-
+			if(v & 0x80) {	/* IRQ flag clear */
+				OPL_STATUS_RESET(OPL, 0x7f);
+			} else {	/* set IRQ mask ,timer enable*/
+				uint8 st1 = v & 1;
+				uint8 st2 = (v >> 1) & 1;
 				/* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
-				OPL_STATUS_RESET(OPL, v & 0x78 );
-				OPL_STATUSMASK_SET(OPL, (~v) & 0x78 );
-
-				/* timer 1 */
-				if(OPL->st[0])
-				{
-					OPL->TC[0]=OPL->T[0]*20;
-					double interval = (double)OPL->T[0]*OPL->TimerBase;
-					if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval);
-				}
+				OPL_STATUS_RESET(OPL, v & 0x78);
+				OPL_STATUSMASK_SET(OPL,((~v) & 0x78) | 0x01);
 				/* timer 2 */
-				if(OPL->st[1])
-				{
-					OPL->TC[1]=OPL->T[1]*20;
-					double interval =(double)OPL->T[1]*OPL->TimerBase;
-					if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval);
+				if(OPL->st[1] != st2) {
+					float interval = st2 ? (float)OPL->T[1] * OPL->TimerBase : 0.0;
+					OPL->st[1] = st2;
+					if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 1, interval);
+				}
+				/* timer 1 */
+				if(OPL->st[0] != st1) {
+					float interval = st1 ? (float)OPL->T[0] * OPL->TimerBase : 0.0;
+					OPL->st[0] = st1;
+					if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 0, interval);
 				}
 			}
-			break;
-#if BUILD_Y8950
-		case 0x06:		/* Key Board OUT */
-			if(OPL->type&OPL_TYPE_KEYBOARD)
-			{
-				if(OPL->keyboardhandler_w)
-					OPL->keyboardhandler_w(OPL->keyboard_param,v);
-				else
-					logerror("Y8950: write unmapped KEYBOARD port\n");
-			}
-			break;
-		case 0x07:	/* DELTA-T control 1 : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
-			if(OPL->type&OPL_TYPE_ADPCM)
-				YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
-			break;
-#endif
-		case 0x08:	/* MODE,DELTA-T control 2 : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
-			OPL->mode = v;
-#if BUILD_Y8950
-			if(OPL->type&OPL_TYPE_ADPCM)
-				YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v&0x0f); /* mask 4 LSBs in register 08 for DELTA-T unit */
-#endif
-			break;
-
-#if BUILD_Y8950
-		case 0x09:		/* START ADD */
-		case 0x0a:
-		case 0x0b:		/* STOP ADD  */
-		case 0x0c:
-		case 0x0d:		/* PRESCALE   */
-		case 0x0e:
-		case 0x0f:		/* ADPCM data write */
-		case 0x10: 		/* DELTA-N    */
-		case 0x11: 		/* DELTA-N    */
-		case 0x12: 		/* ADPCM volume */
-			if(OPL->type&OPL_TYPE_ADPCM)
-				YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
-			break;
-
-		case 0x15:		/* DAC data high 8 bits (F7,F6...F2) */
-		case 0x16:		/* DAC data low 2 bits (F1, F0 in bits 7,6) */
-		case 0x17:		/* DAC data shift (S2,S1,S0 in bits 2,1,0) */
-			logerror("FMOPL.C: DAC data register written, but not implemented reg=%02x val=%02x\n",r,v);
-			break;
-
-		case 0x18:		/* I/O CTRL (Direction) */
-			if(OPL->type&OPL_TYPE_IO)
-				OPL->portDirection = v&0x0f;
-			break;
-		case 0x19:		/* I/O DATA */
-			if(OPL->type&OPL_TYPE_IO)
-			{
-				OPL->portLatch = v;
-				if(OPL->porthandler_w)
-					OPL->porthandler_w(OPL->port_param,v&OPL->portDirection);
-			}
-			break;
-#endif
-		default:
-			logerror("FMOPL.C: write to unknown register: %02x\n",r);
-			break;
+			return;
 		}
 		break;
-	case 0x20:	/* am ON, vib ON, ksr, eg_type, mul */
+	case 0x20:	/* am,vib,ksr,eg type,mul */
 		slot = slot_array[r&0x1f];
-		if(slot < 0) return;
+		if(slot == -1)
+			return;
 		set_mul(OPL,slot,v);
-		break;
+		return;
 	case 0x40:
 		slot = slot_array[r&0x1f];
-		if(slot < 0) return;
+		if(slot == -1)
+			return;
 		set_ksl_tl(OPL,slot,v);
-		break;
+		return;
 	case 0x60:
 		slot = slot_array[r&0x1f];
-		if(slot < 0) return;
+		if(slot == -1)
+			return;
 		set_ar_dr(OPL,slot,v);
-		break;
+		return;
 	case 0x80:
 		slot = slot_array[r&0x1f];
-		if(slot < 0) return;
+		if(slot == -1)
+			return;
 		set_sl_rr(OPL,slot,v);
-		break;
+		return;
 	case 0xa0:
-		if (r == 0xbd)			/* am depth, vibrato depth, r,bd,sd,tom,tc,hh */
-		{
-			OPL->lfo_am_depth = v & 0x80;
-			OPL->lfo_pm_depth_range = (v&0x40) ? 8 : 0;
-
-			OPL->rhythm  = v&0x3f;
-
-			if(OPL->rhythm&0x20)
+		switch(r) {
+		case 0xbd:
+			/* amsep,vibdep,r,bd,sd,tom,tc,hh */
 			{
+			uint8 rkey = OPL->rythm ^ v;
+			OPL->ams_table = &AMS_TABLE[v & 0x80 ? AMS_ENT : 0];
+			OPL->vib_table = &VIB_TABLE[v & 0x40 ? VIB_ENT : 0];
+			OPL->rythm  = v & 0x3f;
+			if(OPL->rythm & 0x20) {
 				/* BD key on/off */
-				if(v&0x10)
-				{
-					FM_KEYON (&OPL->P_CH[6].SLOT[SLOT1], 2);
-					FM_KEYON (&OPL->P_CH[6].SLOT[SLOT2], 2);
-				}
-				else
-				{
-					FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2);
-					FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2);
+				if(rkey & 0x10) {
+					if(v & 0x10) {
+						OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
+						OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
+						OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
+					} else {
+						OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
+						OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
+					}
 				}
-				/* HH key on/off */
-				if(v&0x01) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT1], 2);
-				else       FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2);
 				/* SD key on/off */
-				if(v&0x08) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT2], 2);
-				else       FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2);
-				/* TOM key on/off */
-				if(v&0x04) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT1], 2);
-				else       FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2);
+				if(rkey & 0x08) {
+					if(v & 0x08)
+						OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
+					else
+						OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
+				}/* TAM key on/off */
+				if(rkey & 0x04) {
+					if(v & 0x04)
+						OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
+					else
+						OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
+				}
 				/* TOP-CY key on/off */
-				if(v&0x02) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT2], 2);
-				else       FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2);
+				if(rkey & 0x02) {
+					if(v & 0x02)
+						OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
+					else
+						OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
+				}
+				/* HH key on/off */
+				if(rkey & 0x01) {
+					if(v & 0x01)
+						OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
+					else
+						OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
+				}
 			}
-			else
-			{
-				/* BD key off */
-				FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2);
-				FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2);
-				/* HH key off */
-				FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2);
-				/* SD key off */
-				FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2);
-				/* TOM key off */
-				FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2);
-				/* TOP-CY off */
-				FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2);
 			}
 			return;
+
+		default:
+			break;
 		}
 		/* keyon,block,fnum */
-		if( (r&0x0f) > 8) return;
-		CH = &OPL->P_CH[r&0x0f];
-		if(!(r&0x10))
-		{	/* a0-a8 */
-			block_fnum  = (CH->block_fnum&0x1f00) | v;
-		}
-		else
-		{	/* b0-b8 */
-			block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
-
-			if(v&0x20)
-			{
-				FM_KEYON (&CH->SLOT[SLOT1], 1);
-				FM_KEYON (&CH->SLOT[SLOT2], 1);
-			}
-			else
-			{
-				FM_KEYOFF(&CH->SLOT[SLOT1],~1);
-				FM_KEYOFF(&CH->SLOT[SLOT2],~1);
+		if((r & 0x0f) > 8)
+			return;
+		CH = &OPL->P_CH[r & 0x0f];
+		if(!(r&0x10)) {	/* a0-a8 */
+			block_fnum  = (CH->block_fnum & 0x1f00) | v;
+		} else {	/* b0-b8 */
+			int keyon = (v >> 5) & 1;
+			block_fnum = ((v & 0x1f) << 8) | (CH->block_fnum & 0xff);
+			if(CH->keyon != keyon) {
+				if((CH->keyon=keyon)) {
+					CH->op1_out[0] = CH->op1_out[1] = 0;
+					OPL_KEYON(&CH->SLOT[SLOT1]);
+					OPL_KEYON(&CH->SLOT[SLOT2]);
+				} else {
+					OPL_KEYOFF(&CH->SLOT[SLOT1]);
+					OPL_KEYOFF(&CH->SLOT[SLOT2]);
+				}
 			}
 		}
 		/* update */
-		if(CH->block_fnum != block_fnum)
-		{
-			UINT8 block  = block_fnum >> 10;
-
+		if(CH->block_fnum != block_fnum) {
+			int blockRv = 7 - (block_fnum >> 10);
+			int fnum = block_fnum & 0x3ff;
 			CH->block_fnum = block_fnum;
-
-			CH->ksl_base = ksl_tab[block_fnum>>6];
-			CH->fc       = OPL->fn_tab[block_fnum&0x03ff] >> (7-block);
-
-			/* BLK 2,1,0 bits -> bits 3,2,1 of kcode */
-			CH->kcode    = (CH->block_fnum&0x1c00)>>9;
-
-			 /* the info below is actually opposite to what is stated in the Manuals (verifed on real YM3812) */
-			/* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum  */
-			/* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */
-			if (OPL->mode&0x40)
-				CH->kcode |= (CH->block_fnum&0x100)>>8;	/* notesel == 1 */
-			else
-				CH->kcode |= (CH->block_fnum&0x200)>>9;	/* notesel == 0 */
-
-			/* refresh Total Level in both SLOTs of this channel */
-			CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl);
-			CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl);
-
-			/* refresh frequency counter in both SLOTs of this channel */
+			CH->ksl_base = KSL_TABLE[block_fnum >> 6];
+			CH->fc = OPL->FN_TABLE[fnum] >> blockRv;
+			CH->kcode = CH->block_fnum >> 9;
+			if((OPL->mode & 0x40) && CH->block_fnum & 0x100)
+				CH->kcode |=1;
 			CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
 			CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
 		}
-		break;
+		return;
 	case 0xc0:
 		/* FB,C */
-		if( (r&0x0f) > 8) return;
+		if((r & 0x0f) > 8)
+			return;
 		CH = &OPL->P_CH[r&0x0f];
-		CH->SLOT[SLOT1].FB  = (v>>1)&7 ? ((v>>1)&7) + 7 : 0;
-		CH->SLOT[SLOT1].CON = v&1;
-		CH->SLOT[SLOT1].connect1 = CH->SLOT[SLOT1].CON ? &output[0] : &phase_modulation;
-		break;
-	case 0xe0: /* waveform select */
-		/* simply ignore write to the waveform select register if selecting not enabled in test register */
-		if(OPL->wavesel)
 		{
-			slot = slot_array[r&0x1f];
-			if(slot < 0) return;
-			CH = &OPL->P_CH[slot/2];
-
-			CH->SLOT[slot&1].wavetable = (v&0x03)*SIN_LEN;
+			int feedback = (v >> 1) & 7;
+			CH->FB = feedback ? (8 + 1) - feedback : 0;
+			CH->CON = v & 1;
+			set_algorythm(CH);
+		}
+		return;
+	case 0xe0: /* wave type */
+		slot = slot_array[r & 0x1f];
+		if(slot == -1)
+			return;
+		CH = &OPL->P_CH[slot / 2];
+		if(OPL->wavesel) {
+			CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v & 0x03) * SIN_ENT];
 		}
-		break;
-	}
-}
-
-#ifdef LOG_CYM_FILE
-static void cymfile_callback (int n)
-{
-	if (cymfile)
-	{
-		fputc( (unsigned char)0, cymfile );
+		return;
 	}
 }
-#endif
 
 /* lock/unlock for common table */
-static int OPL_LockTable(void)
-{
+static int OPL_LockTable(void) {
 	num_lock++;
-	if(num_lock>1) return 0;
-
+	if(num_lock>1)
+		return 0;
 	/* first time */
-
 	cur_chip = NULL;
 	/* allocate total level table (128kb space) */
-	if( !init_tables() )
-	{
+	if(!OPLOpenTable()) {
 		num_lock--;
 		return -1;
 	}
-
-#ifdef LOG_CYM_FILE
-	cymfile = fopen("3812_.cym","wb");
-	if (cymfile)
-		timer_pulse ( TIME_IN_HZ(110), 0, cymfile_callback); /*110 Hz pulse timer*/
-	else
-		logerror("Could not create file 3812_.cym\n");
-#endif
-
 	return 0;
 }
 
-static void OPL_UnLockTable(void)
-{
-	if(num_lock) num_lock--;
-	if(num_lock) return;
-
+static void OPL_UnLockTable(void) {
+	if(num_lock)
+		num_lock--;
+	if(num_lock)
+		return;
 	/* last time */
-
 	cur_chip = NULL;
 	OPLCloseTable();
+}
 
-#ifdef LOG_CYM_FILE
-	fclose (cymfile);
-	cymfile = NULL;
-#endif
+/*******************************************************************************/
+/*		YM3812 local section                                                   */
+/*******************************************************************************/
+
+/* ---------- update one of chip ----------- */
+static void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length) {
+	int i;
+	int data;
+	int16 *buf = buffer;
+	uint amsCnt = OPL->amsCnt;
+	uint vibCnt = OPL->vibCnt;
+	uint8 rythm = OPL->rythm & 0x20;
+	OPL_CH *CH, *R_CH;
+
+
+	if((void *)OPL != cur_chip) {
+		cur_chip = (void *)OPL;
+		/* channel pointers */
+		S_CH = OPL->P_CH;
+		E_CH = &S_CH[9];
+		/* rythm slot */
+		SLOT7_1 = &S_CH[7].SLOT[SLOT1];
+		SLOT7_2 = &S_CH[7].SLOT[SLOT2];
+		SLOT8_1 = &S_CH[8].SLOT[SLOT1];
+		SLOT8_2 = &S_CH[8].SLOT[SLOT2];
+		/* LFO state */
+		amsIncr = OPL->amsIncr;
+		vibIncr = OPL->vibIncr;
+		ams_table = OPL->ams_table;
+		vib_table = OPL->vib_table;
+	}
+	R_CH = rythm ? &S_CH[6] : E_CH;
+	for(i = 0; i < length; i++) {
+		/*            channel A         channel B         channel C      */
+		/* LFO */
+		ams = ams_table[(amsCnt += amsIncr) >> AMS_SHIFT];
+		vib = vib_table[(vibCnt += vibIncr) >> VIB_SHIFT];
+		outd[0] = 0;
+		/* FM part */
+		for(CH=S_CH; CH < R_CH; CH++)
+			OPL_CALC_CH(CH);
+		/* Rythn part */
+		if(rythm)
+			OPL_CALC_RH(S_CH);
+		/* limit check */
+		data = Limit(outd[0], OPL_MAXOUT, OPL_MINOUT);
+		/* store to sound buffer */
+		buf[i] = data >> OPL_OUTSB;
+	}
 
+	OPL->amsCnt = amsCnt;
+	OPL->vibCnt = vibCnt;
 }
 
-static void OPLResetChip(FM_OPL *OPL)
-{
+/* ---------- reset a chip ---------- */
+static void OPLResetChip(FM_OPL *OPL) {
 	int c,s;
 	int i;
 
-	OPL->eg_timer = 0;
-	OPL->eg_cnt   = 0;
-
-	OPL->noise_rng = 1;	/* noise shift register */
-	OPL->mode   = 0;	/* normal mode */
-	OPL_STATUS_RESET(OPL,0x7f);
-
+	/* reset chip */
+	OPL->mode = 0;	/* normal mode */
+	OPL_STATUS_RESET(OPL, 0x7f);
 	/* reset with register write */
-	OPLWriteReg(OPL,0x01,0); /* wavesel disable */
-	OPLWriteReg(OPL,0x02,0); /* Timer1 */
-	OPLWriteReg(OPL,0x03,0); /* Timer2 */
-	OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */
-	for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
-
-	/* reset operator parameters */
-	for( c = 0 ; c < 9 ; c++ )
-	{
+	OPLWriteReg(OPL, 0x01,0); /* wabesel disable */
+	OPLWriteReg(OPL, 0x02,0); /* Timer1 */
+	OPLWriteReg(OPL, 0x03,0); /* Timer2 */
+	OPLWriteReg(OPL, 0x04,0); /* IRQ mask clear */
+	for(i = 0xff; i >= 0x20; i--)
+		OPLWriteReg(OPL,i,0);
+	/* reset OPerator parameter */
+	for(c = 0; c < OPL->max_ch ;c++ ) {
 		OPL_CH *CH = &OPL->P_CH[c];
-		for(s = 0 ; s < 2 ; s++ )
-		{
+		/* OPL->P_CH[c].PAN = OPN_CENTER; */
+		for(s = 0; s < 2; s++ ) {
 			/* wave table */
-			CH->SLOT[s].wavetable = 0;
-			CH->SLOT[s].state     = EG_OFF;
-			CH->SLOT[s].volume    = MAX_ATT_INDEX;
+			CH->SLOT[s].wavetable = &SIN_TABLE[0];
+			/* CH->SLOT[s].evm = ENV_MOD_RR; */
+			CH->SLOT[s].evc = EG_OFF;
+			CH->SLOT[s].eve = EG_OFF + 1;
+			CH->SLOT[s].evs = 0;
 		}
 	}
-#if BUILD_Y8950
-	if(OPL->type&OPL_TYPE_ADPCM)
-	{
-		YM_DELTAT *DELTAT = OPL->deltat;
-
-		DELTAT->freqbase = OPL->freqbase;
-		DELTAT->output_pointer = &output_deltat[0];
-		DELTAT->portshift = 5;
-		DELTAT->output_range = 1<<23;
-		YM_DELTAT_ADPCM_Reset(DELTAT,0);
-	}
-#endif
 }
 
-/* Create one of virtual YM3812/YM3526/Y8950 */
-/* 'clock' is chip clock in Hz  */
-/* 'rate'  is sampling rate  */
-static FM_OPL *OPLCreate(int type, int clock, int rate)
-{
+/* ----------  Create a virtual YM3812 ----------       */
+/* 'rate'  is sampling rate and 'bufsiz' is the size of the  */
+static FM_OPL *OPLCreate(int type, int clock, int rate) {
 	char *ptr;
 	FM_OPL *OPL;
 	int state_size;
+	int max_ch = 9; /* normaly 9 channels */
 
-	if (OPL_LockTable() ==-1) return NULL;
-
-	/* calculate OPL state size */
+	if( OPL_LockTable() == -1)
+		return NULL;
+	/* allocate OPL state space */
 	state_size  = sizeof(FM_OPL);
-
-#if BUILD_Y8950
-	if (type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT);
-#endif
+	state_size += sizeof(OPL_CH) * max_ch;
 
 	/* allocate memory block */
-	ptr = (char *)malloc(state_size);
-
-	if (ptr==NULL)
+	ptr = (char *)calloc(state_size, 1);
+	if(ptr == NULL)
 		return NULL;
 
 	/* clear */
-	memset(ptr,0,state_size);
-
-	OPL  = (FM_OPL *)ptr;
-
-	ptr += sizeof(FM_OPL);
-
-#if BUILD_Y8950
-	if (type&OPL_TYPE_ADPCM)
-	{
-		OPL->deltat = (YM_DELTAT *)ptr;
-	}
-	ptr += sizeof(YM_DELTAT);
-#endif
+	memset(ptr, 0, state_size);
+	OPL       = (FM_OPL *)ptr; ptr += sizeof(FM_OPL);
+	OPL->P_CH = (OPL_CH *)ptr; ptr += sizeof(OPL_CH) * max_ch;
 
+	/* set channel state pointer */
 	OPL->type  = type;
 	OPL->clock = clock;
 	OPL->rate  = rate;
+	OPL->max_ch = max_ch;
 
-	/* init global tables */
+	/* init grobal tables */
 	OPL_initalize(OPL);
 
+	/* reset chip */
+	OPLResetChip(OPL);
 	return OPL;
 }
 
-/* Destroy one of virtual YM3812 */
-static void OPLDestroy(FM_OPL *OPL)
-{
+/* ----------  Destroy one of vietual YM3812 ----------       */
+static void OPLDestroy(FM_OPL *OPL) {
 	OPL_UnLockTable();
 	free(OPL);
 }
 
-/* Optional handlers */
-
-static void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset)
-{
+/* ----------  Option handlers ----------       */
+static void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler,int channelOffset) {
 	OPL->TimerHandler   = TimerHandler;
 	OPL->TimerParam = channelOffset;
 }
-static void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param)
-{
+
+static void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param) {
 	OPL->IRQHandler     = IRQHandler;
 	OPL->IRQParam = param;
 }
-static void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param)
-{
+
+static void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler,int param) {
 	OPL->UpdateHandler = UpdateHandler;
 	OPL->UpdateParam = param;
 }
 
-static int OPLWrite(FM_OPL *OPL,int a,int v)
-{
-	if( !(a&1) )
-	{	/* address port */
+/* ---------- YM3812 I/O interface ---------- */
+static int OPLWrite(FM_OPL *OPL,int a,int v) {
+	if(!(a & 1)) {	/* address port */
 		OPL->address = v & 0xff;
-	}
-	else
-	{	/* data port */
+	} else {	/* data port */
 		if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
-		OPLWriteReg(OPL,OPL->address,v);
+		OPLWriteReg(OPL, OPL->address,v);
 	}
-	return OPL->status>>7;
+	return OPL->status >> 7;
 }
 
-static unsigned char OPLRead(FM_OPL *OPL,int a)
-{
-	if( !(a&1) )
-	{
-		/* status port */
-
-		#if BUILD_Y8950
-
-		if(OPL->type&OPL_TYPE_ADPCM)	/* Y8950 */
-		{
-			return (OPL->status & (OPL->statusmask|0x80)) | (OPL->deltat->PCM_BSY&1);
-		}
-
-		#endif
-		if (OPL->st[0]) {
-			if (OPL->TC[0]) OPL->TC[0]--;
-			else {
-				OPL->TC[0]=OPL->T[0]*20;
-				OPL_STATUS_SET(OPL,0x40);
-			}
-		}
-		if (OPL->st[1]) {
-			if (OPL->TC[1]) OPL->TC[1]--;
-			else {
-				OPL->TC[1]=OPL->T[1]*20;
-				OPL_STATUS_SET(OPL,0x40);
-			}
-		}
-		return OPL->status & (OPL->statusmask|0x80);
-	}
-
-#if BUILD_Y8950
-	/* data port */
-	switch(OPL->address)
-	{
-	case 0x05: /* KeyBoard IN */
-		if(OPL->type&OPL_TYPE_KEYBOARD)
-		{
-			if(OPL->keyboardhandler_r)
-				return OPL->keyboardhandler_r(OPL->keyboard_param);
-			else
-				logerror("Y8950: read unmapped KEYBOARD port\n");
-		}
-		return 0;
-
-	case 0x0f: /* ADPCM-DATA  */
-		if(OPL->type&OPL_TYPE_ADPCM)
-		{
-			UINT8 val;
-
-            val = YM_DELTAT_ADPCM_Read(OPL->deltat);
-			/*logerror("Y8950: read ADPCM value read=%02x\n",val);*/
-			return val;
-		}
-		return 0;
-
-	case 0x19: /* I/O DATA    */
-		if(OPL->type&OPL_TYPE_IO)
-		{
-			if(OPL->porthandler_r)
-				return OPL->porthandler_r(OPL->port_param);
-			else
-				logerror("Y8950:read unmapped I/O port\n");
-		}
-		return 0;
-	case 0x1a: /* PCM-DATA    */
-		if(OPL->type&OPL_TYPE_ADPCM)
-		{
-			logerror("Y8950 A/D convertion is accessed but not implemented !\n");
-			return 0x80; /* 2's complement PCM data - result from A/D convertion */
-		}
-		return 0;
+static unsigned char OPLRead(FM_OPL *OPL,int a) {
+	if(!(a & 1)) {	/* status port */
+		return OPL->status & (OPL->statusmask | 0x80);
 	}
-#endif
-
 	return 0xff;
 }
 
-/* CSM Key Controll */
-INLINE void CSMKeyControll(OPL_CH *CH)
-{
-	FM_KEYON (&CH->SLOT[SLOT1], 4);
-	FM_KEYON (&CH->SLOT[SLOT2], 4);
-
-	/* The key off should happen exactly one sample later - not implemented correctly yet */
-
-	FM_KEYOFF(&CH->SLOT[SLOT1], ~4);
-	FM_KEYOFF(&CH->SLOT[SLOT2], ~4);
-}
-
-
-static int OPLTimerOver(FM_OPL *OPL,int c)
-{
-	if( c )
-	{	/* Timer B */
-		OPL_STATUS_SET(OPL,0x20);
-	}
-	else
-	{	/* Timer A */
-		OPL_STATUS_SET(OPL,0x40);
+static int OPLTimerOver(FM_OPL *OPL, int c) {
+	if(c) {	/* Timer B */
+		OPL_STATUS_SET(OPL, 0x20);
+	} else {	/* Timer A */
+		OPL_STATUS_SET(OPL, 0x40);
 		/* CSM mode key,TL controll */
-		if( OPL->mode & 0x80 )
-		{	/* CSM mode total level latch and auto key on */
+		if(OPL->mode & 0x80) {	/* CSM mode total level latch and auto key on */
 			int ch;
-			if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
-			for(ch=0; ch<9; ch++)
-				CSMKeyControll( &OPL->P_CH[ch] );
+			if(OPL->UpdateHandler)
+				OPL->UpdateHandler(OPL->UpdateParam,0);
+			for(ch = 0; ch < 9; ch++)
+				CSMKeyControll(&OPL->P_CH[ch]);
 		}
 	}
 	/* reload timer */
-//	if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase);
-	return OPL->status>>7;
-}
-
-
-#define MAX_OPL_CHIPS 2
-
-
-#if (BUILD_YM3812)
-
-static FM_OPL *OPL_YM3812[MAX_OPL_CHIPS];	/* array of pointers to the YM3812's */
-static int YM3812NumChips = 0;				/* number of chips */
-
-int YM3812Init(int num, int clock, int rate)
-{
-	int i;
-
-	if (YM3812NumChips)
-		return -1;	/* duplicate init. */
-
-	YM3812NumChips = num;
-
-	for (i = 0;i < YM3812NumChips; i++)
-	{
-		/* emulator create */
-		OPL_YM3812[i] = OPLCreate(OPL_TYPE_YM3812,clock,rate);
-		if(OPL_YM3812[i] == NULL)
-		{
-			/* it's really bad - we run out of memeory */
-			YM3812NumChips = 0;
-			return -1;
-		}
-		/* reset */
-		YM3812ResetChip(i);
-	}
-
-	return 0;
-}
-
-void YM3812Shutdown(void)
-{
-	int i;
-
-	for (i = 0;i < YM3812NumChips; i++)
-	{
-		/* emulator shutdown */
-		OPLDestroy(OPL_YM3812[i]);
-		OPL_YM3812[i] = NULL;
-	}
-	YM3812NumChips = 0;
-}
-void YM3812ResetChip(int which)
-{
-	OPLResetChip(OPL_YM3812[which]);
-}
-
-int YM3812Write(int which, int a, int v)
-{
-	return OPLWrite(OPL_YM3812[which], a, v);
-}
-
-unsigned char YM3812Read(int which, int a)
-{
-	/* YM3812 always returns bit2 and bit1 in HIGH state */
-	return OPLRead(OPL_YM3812[which], a) | 0x06 ;
-}
-int YM3812TimerOver(int which, int c)
-{
-	return OPLTimerOver(OPL_YM3812[which], c);
-}
-
-void YM3812SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset)
-{
-	OPLSetTimerHandler(OPL_YM3812[which], TimerHandler, channelOffset);
-}
-void YM3812SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param)
-{
-	OPLSetIRQHandler(OPL_YM3812[which], IRQHandler, param);
-}
-void YM3812SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param)
-{
-	OPLSetUpdateHandler(OPL_YM3812[which], UpdateHandler, param);
-}
-
-
-/*
-** Generate samples for one of the YM3812's
-**
-** 'which' is the virtual YM3812 number
-** '*buffer' is the output buffer pointer
-** 'length' is the number of samples that should be generated
-*/
-void YM3812UpdateOne(int which, INT16 *buffer, int length)
-{
-	FM_OPL		*OPL = OPL_YM3812[which];
-	UINT8		rhythm = OPL->rhythm&0x20;
-	OPLSAMPLE	*buf = buffer;
-	int i;
-
-	if( (void *)OPL != cur_chip ){
-		cur_chip = (void *)OPL;
-		/* rhythm slots */
-		SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1];
-		SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2];
-		SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1];
-		SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2];
-	}
-	for( i=0; i < length ; i++ )
-	{
-		int lt;
-
-		output[0] = 0;
-
-		advance_lfo(OPL);
-
-		/* FM part */
-		OPL_CALC_CH(&OPL->P_CH[0]);
-		OPL_CALC_CH(&OPL->P_CH[1]);
-		OPL_CALC_CH(&OPL->P_CH[2]);
-		OPL_CALC_CH(&OPL->P_CH[3]);
-		OPL_CALC_CH(&OPL->P_CH[4]);
-		OPL_CALC_CH(&OPL->P_CH[5]);
-
-		if(!rhythm)
-		{
-			OPL_CALC_CH(&OPL->P_CH[6]);
-			OPL_CALC_CH(&OPL->P_CH[7]);
-			OPL_CALC_CH(&OPL->P_CH[8]);
-		}
-		else		/* Rhythm part */
-		{
-			OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 );
-		}
-
-		lt = output[0];
-
-		lt >>= FINAL_SH;
-
-		/* limit check */
-		lt = limit( lt , MAXOUT, MINOUT );
-
-		#ifdef SAVE_SAMPLE
-		if (which==0)
-		{
-			SAVE_ALL_CHANNELS
-		}
-		#endif
-
-		/* store to sound buffer */
-		buf[i] = lt;
-
-		advance(OPL);
-	}
-
-}
-#endif /* BUILD_YM3812 */
-
-
-
-#if (BUILD_YM3526)
-
-static FM_OPL *OPL_YM3526[MAX_OPL_CHIPS];	/* array of pointers to the YM3526's */
-static int YM3526NumChips = 0;				/* number of chips */
-
-int YM3526Init(int num, int clock, int rate)
-{
-	int i;
-
-	if (YM3526NumChips)
-		return -1;	/* duplicate init. */
-
-	YM3526NumChips = num;
-
-	for (i = 0;i < YM3526NumChips; i++)
-	{
-		/* emulator create */
-		OPL_YM3526[i] = OPLCreate(OPL_TYPE_YM3526,clock,rate);
-		if(OPL_YM3526[i] == NULL)
-		{
-			/* it's really bad - we run out of memeory */
-			YM3526NumChips = 0;
-			return -1;
-		}
-		/* reset */
-		YM3526ResetChip(i);
-	}
-
-	return 0;
-}
-
-void YM3526Shutdown(void)
-{
-	int i;
-
-	for (i = 0;i < YM3526NumChips; i++)
-	{
-		/* emulator shutdown */
-		OPLDestroy(OPL_YM3526[i]);
-		OPL_YM3526[i] = NULL;
-	}
-	YM3526NumChips = 0;
-}
-void YM3526ResetChip(int which)
-{
-	OPLResetChip(OPL_YM3526[which]);
-}
-
-int YM3526Write(int which, int a, int v)
-{
-	return OPLWrite(OPL_YM3526[which], a, v);
-}
-
-unsigned char YM3526Read(int which, int a)
-{
-	/* YM3526 always returns bit2 and bit1 in HIGH state */
-	return OPLRead(OPL_YM3526[which], a) | 0x06 ;
-}
-int YM3526TimerOver(int which, int c)
-{
-	return OPLTimerOver(OPL_YM3526[which], c);
-}
-
-void YM3526SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset)
-{
-	OPLSetTimerHandler(OPL_YM3526[which], TimerHandler, channelOffset);
+//	if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + c, (float)OPL->T[c] * OPL->TimerBase);
+	return OPL->status >> 7;
 }
-void YM3526SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param)
-{
-	OPLSetIRQHandler(OPL_YM3526[which], IRQHandler, param);
-}
-void YM3526SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param)
-{
-	OPLSetUpdateHandler(OPL_YM3526[which], UpdateHandler, param);
-}
-
-
-/*
-** Generate samples for one of the YM3526's
-**
-** 'which' is the virtual YM3526 number
-** '*buffer' is the output buffer pointer
-** 'length' is the number of samples that should be generated
-*/
-void YM3526UpdateOne(int which, INT16 *buffer, int length)
-{
-	FM_OPL		*OPL = OPL_YM3526[which];
-	UINT8		rhythm = OPL->rhythm&0x20;
-	OPLSAMPLE	*buf = buffer;
-	int i;
-
-	if( (void *)OPL != cur_chip ){
-		cur_chip = (void *)OPL;
-		/* rhythm slots */
-		SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1];
-		SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2];
-		SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1];
-		SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2];
-	}
-	for( i=0; i < length ; i++ )
-	{
-		int lt;
-
-		output[0] = 0;
-
-		advance_lfo(OPL);
-
-		/* FM part */
-		OPL_CALC_CH(&OPL->P_CH[0]);
-		OPL_CALC_CH(&OPL->P_CH[1]);
-		OPL_CALC_CH(&OPL->P_CH[2]);
-		OPL_CALC_CH(&OPL->P_CH[3]);
-		OPL_CALC_CH(&OPL->P_CH[4]);
-		OPL_CALC_CH(&OPL->P_CH[5]);
-
-		if(!rhythm)
-		{
-			OPL_CALC_CH(&OPL->P_CH[6]);
-			OPL_CALC_CH(&OPL->P_CH[7]);
-			OPL_CALC_CH(&OPL->P_CH[8]);
-		}
-		else		/* Rhythm part */
-		{
-			OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 );
-		}
-
-		lt = output[0];
-
-		lt >>= FINAL_SH;
-
-		/* limit check */
-		lt = limit( lt , MAXOUT, MINOUT );
-
-		#ifdef SAVE_SAMPLE
-		if (which==0)
-		{
-			SAVE_ALL_CHANNELS
-		}
-		#endif
-
-		/* store to sound buffer */
-		buf[i] = lt;
-
-		advance(OPL);
-	}
-
-}
-#endif /* BUILD_YM3526 */
-
-
-
-
-#if BUILD_Y8950
-
-static FM_OPL *OPL_Y8950[MAX_OPL_CHIPS];	/* array of pointers to the Y8950's */
-static int Y8950NumChips = 0;				/* number of chips */
-
-static void Y8950_deltat_status_set(UINT8 which, UINT8 changebits)
-{
-	OPL_STATUS_SET(OPL_Y8950[which], changebits);
-}
-static void Y8950_deltat_status_reset(UINT8 which, UINT8 changebits)
-{
-	OPL_STATUS_RESET(OPL_Y8950[which], changebits);
-}
-
-int Y8950Init(int num, int clock, int rate)
-{
-	int i;
-
-	if (Y8950NumChips)
-		return -1;	/* duplicate init. */
-
-	Y8950NumChips = num;
-
-	for (i = 0;i < Y8950NumChips; i++)
-	{
-		/* emulator create */
-		OPL_Y8950[i] = OPLCreate(OPL_TYPE_Y8950,clock,rate);
-		if(OPL_Y8950[i] == NULL)
-		{
-			/* it's really bad - we run out of memeory */
-			Y8950NumChips = 0;
-			return -1;
-		}
-		OPL_Y8950[i]->deltat->status_set_handler = Y8950_deltat_status_set;
-		OPL_Y8950[i]->deltat->status_reset_handler = Y8950_deltat_status_reset;
-		OPL_Y8950[i]->deltat->status_change_which_chip = i;
-		OPL_Y8950[i]->deltat->status_change_EOS_bit = 0x10;		/* status flag: set bit4 on End Of Sample */
-		OPL_Y8950[i]->deltat->status_change_BRDY_bit = 0x08;	/* status flag: set bit3 on BRDY (End Of: ADPCM analysis/synthesis, memory reading/writing) */
-		/* reset */
-		Y8950ResetChip(i);
-	}
-
-	return 0;
-}
-
-void Y8950Shutdown(void)
-{
-	int i;
-
-	for (i = 0;i < Y8950NumChips; i++)
-	{
-		/* emulator shutdown */
-		OPLDestroy(OPL_Y8950[i]);
-		OPL_Y8950[i] = NULL;
-	}
-	Y8950NumChips = 0;
-}
-void Y8950ResetChip(int which)
-{
-	OPLResetChip(OPL_Y8950[which]);
-}
-
-int Y8950Write(int which, int a, int v)
-{
-	return OPLWrite(OPL_Y8950[which], a, v);
-}
-
-unsigned char Y8950Read(int which, int a)
-{
-	return OPLRead(OPL_Y8950[which], a);
-}
-int Y8950TimerOver(int which, int c)
-{
-	return OPLTimerOver(OPL_Y8950[which], c);
-}
-
-void Y8950SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset)
-{
-	OPLSetTimerHandler(OPL_Y8950[which], TimerHandler, channelOffset);
-}
-void Y8950SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param)
-{
-	OPLSetIRQHandler(OPL_Y8950[which], IRQHandler, param);
-}
-void Y8950SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param)
-{
-	OPLSetUpdateHandler(OPL_Y8950[which], UpdateHandler, param);
-}
-
-void Y8950SetDeltaTMemory(int which, void * deltat_mem_ptr, int deltat_mem_size )
-{
-	FM_OPL		*OPL = OPL_Y8950[which];
-	OPL->deltat->memory = (UINT8 *)(deltat_mem_ptr);
-	OPL->deltat->memory_size = deltat_mem_size;
-}
-
-/*
-** Generate samples for one of the Y8950's
-**
-** 'which' is the virtual Y8950 number
-** '*buffer' is the output buffer pointer
-** 'length' is the number of samples that should be generated
-*/
-void Y8950UpdateOne(int which, INT16 *buffer, int length)
-{
-	int i;
-	FM_OPL		*OPL = OPL_Y8950[which];
-	UINT8		rhythm  = OPL->rhythm&0x20;
-	YM_DELTAT	*DELTAT = OPL->deltat;
-	OPLSAMPLE	*buf    = buffer;
-
-	if( (void *)OPL != cur_chip ){
-		cur_chip = (void *)OPL;
-		/* rhythm slots */
-		SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1];
-		SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2];
-		SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1];
-		SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2];
-
-	}
-	for( i=0; i < length ; i++ )
-	{
-		int lt;
-
-		output[0] = 0;
-		output_deltat[0] = 0;
-
-		advance_lfo(OPL);
-
-		/* deltaT ADPCM */
-		if( DELTAT->portstate&0x80 )
-			YM_DELTAT_ADPCM_CALC(DELTAT);
-
-		/* FM part */
-		OPL_CALC_CH(&OPL->P_CH[0]);
-		OPL_CALC_CH(&OPL->P_CH[1]);
-		OPL_CALC_CH(&OPL->P_CH[2]);
-		OPL_CALC_CH(&OPL->P_CH[3]);
-		OPL_CALC_CH(&OPL->P_CH[4]);
-		OPL_CALC_CH(&OPL->P_CH[5]);
-
-		if(!rhythm)
-		{
-			OPL_CALC_CH(&OPL->P_CH[6]);
-			OPL_CALC_CH(&OPL->P_CH[7]);
-			OPL_CALC_CH(&OPL->P_CH[8]);
-		}
-		else		/* Rhythm part */
-		{
-			OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 );
-		}
-
-		lt = output[0] + (output_deltat[0]>>11);
-
-		lt >>= FINAL_SH;
-
-		/* limit check */
-		lt = limit( lt , MAXOUT, MINOUT );
-
-		#ifdef SAVE_SAMPLE
-		if (which==0)
-		{
-			SAVE_ALL_CHANNELS
-		}
-		#endif
-
-		/* store to sound buffer */
-		buf[i] = lt;
-
-		advance(OPL);
-	}
-
-}
-
-void Y8950SetPortHandler(int which,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param)
-{
-	FM_OPL		*OPL = OPL_Y8950[which];
-	OPL->porthandler_w = PortHandler_w;
-	OPL->porthandler_r = PortHandler_r;
-	OPL->port_param = param;
-}
-
-void Y8950SetKeyboardHandler(int which,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param)
-{
-	FM_OPL		*OPL = OPL_Y8950[which];
-	OPL->keyboardhandler_w = KeyboardHandler_w;
-	OPL->keyboardhandler_r = KeyboardHandler_r;
-	OPL->keyboard_param = param;
-}
-
-#endif
-
diff -ru dosbox-0.71.orig/src/hardware/fmopl.h dosbox-0.71/src/hardware/fmopl.h
--- dosbox-0.71.orig/src/hardware/fmopl.h	2004-03-03 08:47:06.000000000 -0600
+++ dosbox-0.71/src/hardware/fmopl.h	2007-08-07 17:56:20.421875000 -0500
@@ -1,111 +1,163 @@
-#ifndef __FMOPL_H_
-#define __FMOPL_H_
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 1999-2000 Tatsuyuki Satoh
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ * LGPL licensed version of MAMEs fmopl (V0.37a modified) by
+ * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
+ */
+
+
+#ifndef SOUND_FMOPL_H
+#define SOUND_FMOPL_H
 
-/* --- select emulation chips --- */
-#define BUILD_YM3812 (HAS_YM3812)
-#define BUILD_YM3526 (HAS_YM3526)
-#define BUILD_Y8950  (HAS_Y8950)
-
-/* select output bits size of output : 8 or 16 */
-#define OPL_SAMPLE_BITS 16
-
-/* compiler dependence */
-#ifndef OSD_CPU_H
-#define OSD_CPU_H
-typedef unsigned char	UINT8;   /* unsigned  8bit */
-typedef unsigned short	UINT16;  /* unsigned 16bit */
-typedef unsigned int	UINT32;  /* unsigned 32bit */
-typedef signed char		INT8;    /* signed  8bit   */
-typedef signed short	INT16;   /* signed 16bit   */
-typedef signed int		INT32;   /* signed 32bit   */
-#endif
-
-#if (OPL_SAMPLE_BITS==16)
-typedef INT16 OPLSAMPLE;
-#endif
-#if (OPL_SAMPLE_BITS==8)
-typedef INT8 OPLSAMPLE;
+#ifndef PI
+#define PI 3.14159265358979323846
 #endif
 
+typedef Bit8u uint8;
+typedef Bit16s INT16;
 
-typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec);
+typedef void (*OPL_TIMERHANDLER)(int channel,float interval_Sec);
 typedef void (*OPL_IRQHANDLER)(int param,int irq);
 typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us);
-typedef void (*OPL_PORTHANDLER_W)(int param,unsigned char data);
-typedef unsigned char (*OPL_PORTHANDLER_R)(int param);
-
-
-#if BUILD_YM3812
 
-int  YM3812Init(int num, int clock, int rate);
-void YM3812Shutdown(void);
-void YM3812ResetChip(int which);
-int  YM3812Write(int which, int a, int v);
-unsigned char YM3812Read(int which, int a);
-int  YM3812TimerOver(int which, int c);
-void YM3812UpdateOne(int which, INT16 *buffer, int length);
-
-void YM3812SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset);
-void YM3812SetIRQHandler(int which, OPL_IRQHANDLER IRQHandler, int param);
-void YM3812SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int param);
+#define OPL_TYPE_WAVESEL   0x01  /* waveform select    */
 
+/* Saving is necessary for member of the 'R' mark for suspend/resume */
+/* ---------- OPL one of slot  ---------- */
+typedef struct fm_opl_slot {
+	int TL;		/* total level     :TL << 8				*/
+	int TLL;	/* adjusted now TL						*/
+	uint8 KSR;	/* key scale rate  :(shift down bit)	*/
+	int *AR;	/* attack rate     :&AR_TABLE[AR<<2]	*/
+	int *DR;	/* decay rate      :&DR_TABLE[DR<<2]	*/
+	int SL;		/* sustain level   :SL_TABLE[SL]		*/
+	int *RR;	/* release rate    :&DR_TABLE[RR<<2]	*/
+	uint8 ksl;	/* keyscale level  :(shift down bits)	*/
+	uint8 ksr;	/* key scale rate  :kcode>>KSR			*/
+	uint mul;	/* multiple        :ML_TABLE[ML]		*/
+	uint Cnt;	/* frequency count						*/
+	uint Incr;	/* frequency step						*/
+
+	/* envelope generator state */
+	uint8 eg_typ;/* envelope type flag					*/
+	uint8 evm;	/* envelope phase						*/
+	int evc;	/* envelope counter						*/
+	int eve;	/* envelope counter end point			*/
+	int evs;	/* envelope counter step				*/
+	int evsa;	/* envelope step for AR :AR[ksr]		*/
+	int evsd;	/* envelope step for DR :DR[ksr]		*/
+	int evsr;	/* envelope step for RR :RR[ksr]		*/
+
+	/* LFO */
+	uint8 ams;		/* ams flag                            */
+	uint8 vib;		/* vibrate flag                        */
+	/* wave selector */
+	int **wavetable;
+} OPL_SLOT;
+
+/* ---------- OPL one of channel  ---------- */
+typedef struct fm_opl_channel {
+	OPL_SLOT SLOT[2];
+	uint8 CON;			/* connection type					*/
+	uint8 FB;			/* feed back       :(shift down bit)*/
+	int *connect1;		/* slot1 output pointer				*/
+	int *connect2;		/* slot2 output pointer				*/
+	int op1_out[2];		/* slot1 output for selfeedback		*/
+
+	/* phase generator state */
+	uint block_fnum;	/* block+fnum						*/
+	uint8 kcode;		/* key code        : KeyScaleCode	*/
+	uint fc;			/* Freq. Increment base				*/
+	uint ksl_base;		/* KeyScaleLevel Base step			*/
+	uint8 keyon;		/* key on/off flag					*/
+} OPL_CH;
+
+/* OPL state */
+typedef struct fm_opl_f {
+	uint8 type;			/* chip type                         */
+	int clock;			/* master clock  (Hz)                */
+	int rate;			/* sampling rate (Hz)                */
+	float freqbase;	/* frequency base                    */
+	float TimerBase;	/* Timer base time (==sampling time) */
+	uint8 address;		/* address register                  */
+	uint8 status;		/* status flag                       */
+	uint8 statusmask;	/* status mask                       */
+	uint mode;			/* Reg.08 : CSM , notesel,etc.       */
+
+	/* Timer */
+	int T[2];			/* timer counter                     */
+	uint8 st[2];		/* timer enable                      */
+
+	/* FM channel slots */
+	OPL_CH *P_CH;		/* pointer of CH                     */
+	int	max_ch;			/* maximum channel                   */
+
+	/* Rythm sention */
+	uint8 rythm;		/* Rythm mode , key flag */
+
+	/* time tables */
+	int AR_TABLE[76];	/* atttack rate tables				*/
+	int DR_TABLE[76];	/* decay rate tables				*/
+	uint FN_TABLE[1024];/* fnumber -> increment counter		*/
+
+	/* LFO */
+	int *ams_table;
+	int *vib_table;
+	int amsCnt;
+	int amsIncr;
+	int vibCnt;
+	int vibIncr;
+
+	/* wave selector enable flag */
+	uint8 wavesel;
+
+	/* external event callback handler */
+	OPL_TIMERHANDLER  TimerHandler;		/* TIMER handler   */
+	int TimerParam;						/* TIMER parameter */
+	OPL_IRQHANDLER    IRQHandler;		/* IRQ handler    */
+	int IRQParam;						/* IRQ parameter  */
+	OPL_UPDATEHANDLER UpdateHandler;	/* stream update handler   */
+	int UpdateParam;					/* stream update parameter */
+} FM_OPL;
+
+/* ---------- Generic interface section ---------- */
+#define OPL_TYPE_YM3526 (0)
+#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL)
+
+#if 0
+void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM);
+
+FM_OPL *OPLCreate(int type, int clock, int rate);
+void OPLDestroy(FM_OPL *OPL);
+void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler, int channelOffset);
+void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param);
+void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler, int param);
+
+void OPLResetChip(FM_OPL *OPL);
+int OPLWrite(FM_OPL *OPL, int a, int v);
+unsigned char OPLRead(FM_OPL *OPL, int a);
+int OPLTimerOver(FM_OPL *OPL, int c);
+void OPLWriteReg(FM_OPL *OPL, int r, int v);
+void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length, int output_rate);
+FM_OPL *makeAdlibOPL(int rate);
 #endif
-
-
-#if BUILD_YM3526
-
-/*
-** Initialize YM3526 emulator(s).
-**
-** 'num' is the number of virtual YM3526's to allocate
-** 'clock' is the chip clock in Hz
-** 'rate' is sampling rate
-*/
-int  YM3526Init(int num, int clock, int rate);
-/* shutdown the YM3526 emulators*/
-void YM3526Shutdown(void);
-void YM3526ResetChip(int which);
-int  YM3526Write(int which, int a, int v);
-unsigned char YM3526Read(int which, int a);
-int  YM3526TimerOver(int which, int c);
-/*
-** Generate samples for one of the YM3526's
-**
-** 'which' is the virtual YM3526 number
-** '*buffer' is the output buffer pointer
-** 'length' is the number of samples that should be generated
-*/
-void YM3526UpdateOne(int which, INT16 *buffer, int length);
-
-void YM3526SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset);
-void YM3526SetIRQHandler(int which, OPL_IRQHANDLER IRQHandler, int param);
-void YM3526SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int param);
-
 #endif
 
-
-#if BUILD_Y8950
-
-#include "ymdeltat.h"
-
-/* Y8950 port handlers */
-void Y8950SetPortHandler(int which, OPL_PORTHANDLER_W PortHandler_w, OPL_PORTHANDLER_R PortHandler_r, int param);
-void Y8950SetKeyboardHandler(int which, OPL_PORTHANDLER_W KeyboardHandler_w, OPL_PORTHANDLER_R KeyboardHandler_r, int param);
-void Y8950SetDeltaTMemory(int which, void * deltat_mem_ptr, int deltat_mem_size );
-
-int  Y8950Init (int num, int clock, int rate);
-void Y8950Shutdown (void);
-void Y8950ResetChip (int which);
-int  Y8950Write (int which, int a, int v);
-unsigned char Y8950Read (int which, int a);
-int  Y8950TimerOver (int which, int c);
-void Y8950UpdateOne (int which, INT16 *buffer, int length);
-
-void Y8950SetTimerHandler (int which, OPL_TIMERHANDLER TimerHandler, int channelOffset);
-void Y8950SetIRQHandler (int which, OPL_IRQHANDLER IRQHandler, int param);
-void Y8950SetUpdateHandler (int which, OPL_UPDATEHANDLER UpdateHandler, int param);
-
-#endif
-
-
-#endif
diff -ru dosbox-0.71.orig/src/hardware/gameblaster.cpp dosbox-0.71/src/hardware/gameblaster.cpp
--- dosbox-0.71.orig/src/hardware/gameblaster.cpp	2007-01-08 12:45:40.000000000 -0600
+++ dosbox-0.71/src/hardware/gameblaster.cpp	2007-08-07 22:01:07.281250000 -0500
@@ -45,8 +45,8 @@
 	int envelope[2];		/* envelope (0x00..0x0f or 0x10 == off) */
 
 	/* vars to simulate the square wave */
-	double counter;
-	double freq;
+	float counter;
+	float freq;
 	int level;
 };
 
@@ -54,8 +54,8 @@
 struct saa1099_noise
 {
 	/* vars to simulate the noise generator output */
-	double counter;
-	double freq;
+	float counter;
+	float freq;
 	int level;						/* noise polynomal shifter */
 };
 
@@ -129,7 +129,7 @@
 };
 
 /* global parameters */
-static double sample_rate;
+static float sample_rate;
 static SAA1099 saa1099[2];
 static MixerChannel * cms_chan;
 static Bit16s cms_buffer[2][2][CMS_BUFFER_SIZE];
@@ -217,16 +217,16 @@
 		for (ch = 0; ch < 6; ch++)
 		{
             if (saa->channels[ch].freq == 0.0)
-                saa->channels[ch].freq = (double)((2 * 15625) << saa->channels[ch].octave) /
-                    (511.0 - (double)saa->channels[ch].frequency);
+                saa->channels[ch].freq = (float)((2 * 15625) << saa->channels[ch].octave) /
+                    (511.0 - (float)saa->channels[ch].frequency);
 
             /* check the actual position in the square wave */
             saa->channels[ch].counter -= saa->channels[ch].freq;
 			while (saa->channels[ch].counter < 0)
 			{
 				/* calculate new frequency now after the half wave is updated */
-				saa->channels[ch].freq = (double)((2 * 15625) << saa->channels[ch].octave) /
-					(511.0 - (double)saa->channels[ch].frequency);
+				saa->channels[ch].freq = (float)((2 * 15625) << saa->channels[ch].octave) /
+					(511.0 - (float)saa->channels[ch].frequency);
 
 				saa->channels[ch].counter += sample_rate;
 				saa->channels[ch].level ^= 1;
@@ -429,7 +429,7 @@
 	CMS(Section* configuration):Module_base(configuration) {
 		Section_prop * section = static_cast<Section_prop *>(configuration);
 		Bitu sample_rate_temp = section->Get_int("oplrate");
-		sample_rate = static_cast<double>(sample_rate_temp);
+		sample_rate = static_cast<float>(sample_rate_temp);
 		Bitu base = section->Get_hex("sbbase");
 		WriteHandler.Install(base,write_cms,IO_MB,4);
 
diff -ru dosbox-0.71.orig/src/hardware/gus.cpp dosbox-0.71/src/hardware/gus.cpp
--- dosbox-0.71.orig/src/hardware/gus.cpp	2007-06-09 02:56:17.000000000 -0500
+++ dosbox-0.71/src/hardware/gus.cpp	2007-08-01 13:06:34.281250000 -0500
@@ -28,6 +28,9 @@
 #include "shell.h"
 #include "math.h"
 #include "regs.h"
+
+#ifdef USE_GUS
+
 using namespace std;
 
 //Extra bits of precision over normal gus
@@ -47,7 +50,6 @@
 #define GUS_RATE myGUS.rate
 #define LOG_GUS 0
 
-Bit8u adlib_commandreg;
 static MixerChannel * gus_chan;
 static Bit8u irqtable[8] = { 0, 2, 5, 3, 7, 11, 12, 15 };
 static Bit8u dmatable[8] = { 0, 1, 3, 5, 6, 7, 0, 0 };
@@ -891,3 +893,9 @@
 	test = new GUS(sec);
 	sec->AddDestroyFunction(&GUS_ShutDown,true);
 }
+
+#else
+
+void GUS_Init(Section* src) { }
+
+#endif
diff -ru dosbox-0.71.orig/src/hardware/hardware.cpp dosbox-0.71/src/hardware/hardware.cpp
--- dosbox-0.71.orig/src/hardware/hardware.cpp	2007-01-08 12:45:40.000000000 -0600
+++ dosbox-0.71/src/hardware/hardware.cpp	2007-08-12 19:58:52.312500000 -0500
@@ -36,6 +36,7 @@
 #include "../libs/zmbv/zmbv.cpp"
 #endif
 
+#ifdef CAPTURE
 static char * capturedir;
 extern const char* RunningProgram;
 Bitu CaptureState;
@@ -742,3 +743,6 @@
 	test = new HARDWARE(sec);
 	sec->AddDestroyFunction(&HARDWARE_Destroy,true);
 }
+#else
+void HARDWARE_Init(Section * sec) { }
+#endif
diff -ru dosbox-0.71.orig/src/hardware/iohandler.cpp dosbox-0.71/src/hardware/iohandler.cpp
--- dosbox-0.71.orig/src/hardware/iohandler.cpp	2007-06-12 15:22:08.000000000 -0500
+++ dosbox-0.71/src/hardware/iohandler.cpp	2007-08-06 20:43:30.578125000 -0500
@@ -238,6 +238,10 @@
 		cpudecoder=old_cpudecoder;
 	}
 	else {
+		if(port > IO_MAX) {
+			LOG(LOG_IO,LOG_ERROR)("Invalid write to port %04X",port);
+			return;
+		}
 		IO_USEC_write_delay();
 		io_writehandlers[0][port](port,val,1);
 	}
@@ -273,6 +277,10 @@
 		cpudecoder=old_cpudecoder;
 	}
 	else {
+		if(port > (IO_MAX-1)) {
+			LOG(LOG_IO,LOG_ERROR)("Invalid write to port %04X",port);
+			return;
+		}
 		IO_USEC_write_delay();
 		io_writehandlers[1][port](port,val,2);
 	}
@@ -307,7 +315,13 @@
 		memcpy(&lflags,&old_lflags,sizeof(LazyFlags));
 		cpudecoder=old_cpudecoder;
 	}
-	else io_writehandlers[2][port](port,val,4);
+	else {
+		if(port > (IO_MAX-3)) {
+			LOG(LOG_IO,LOG_ERROR)("Invalid write to port %04X",port);
+			return;
+		}
+		io_writehandlers[2][port](port,val,4);
+	}
 };
 
 Bitu IO_ReadB(Bitu port) {
@@ -340,6 +354,10 @@
 		return retval;
 	}
 	else {
+		if(port > IO_MAX) {
+			LOG(LOG_IO,LOG_ERROR)("Invalid read from port %04X",port);
+			return -1;
+		}
 		IO_USEC_read_delay();
 		return io_readhandlers[0][port](port,1);
 	}
@@ -375,6 +393,10 @@
 		return retval;
 	}
 	else {
+		if(port > (IO_MAX-1)) {
+			LOG(LOG_IO,LOG_ERROR)("Invalid read from port %04X",port);
+			return -1;
+		}
 		IO_USEC_read_delay();
 		return io_readhandlers[1][port](port,2);
 	}
@@ -409,7 +431,13 @@
 		cpudecoder=old_cpudecoder;
 		return retval;
 	}
-	else return io_readhandlers[2][port](port,4);
+	else {
+		if(port > (IO_MAX-3)) {
+			LOG(LOG_IO,LOG_ERROR)("Invalid read from port %04X",port);
+			return -1;
+		}
+		return io_readhandlers[2][port](port,4);
+	}
 };
 
 class IO :public Module_base {
diff -ru dosbox-0.71.orig/src/hardware/joystick.cpp dosbox-0.71/src/hardware/joystick.cpp
--- dosbox-0.71.orig/src/hardware/joystick.cpp	2007-02-22 01:44:07.000000000 -0600
+++ dosbox-0.71/src/hardware/joystick.cpp	2007-08-07 22:01:28.140625000 -0500
@@ -36,7 +36,7 @@
 struct JoyStick {
 	bool enabled;
 	float xpos,ypos;
-	double xtick,ytick;
+	float xtick,ytick;
 	Bitu xcount,ycount;
 	bool button[2];
 };
@@ -89,7 +89,7 @@
 
 static Bitu read_p201_timed(Bitu port,Bitu iolen) {
 	Bit8u ret=0xff;
-	double currentTick = PIC_FullIndex();
+	float currentTick = PIC_FullIndex();
 	if( stick[0].enabled ){
 		if( stick[0].xtick < currentTick ) ret &=~1;
 		if( stick[0].ytick < currentTick ) ret &=~2;
@@ -129,18 +129,18 @@
 	// Axes take time = 24.2 microseconds + ( 0.011 microsecons/ohm * resistance )
 	// to reset to 0
 	// Precalculate the time at which each axis hits 0 here
-	double currentTick = PIC_FullIndex();
+	float currentTick = PIC_FullIndex();
 	if (stick[0].enabled) {
 		stick[0].xtick = currentTick + 1000.0*( JOY_S_CONSTANT + S_PER_OHM *
-	                         (double)(((stick[0].xpos+1.0)* OHMS)) );
+	                         (float)(((stick[0].xpos+1.0)* OHMS)) );
 		stick[0].ytick = currentTick + 1000.0*( JOY_S_CONSTANT + S_PER_OHM *
-		                 (double)(((stick[0].ypos+1.0)* OHMS)) );
+		                 (float)(((stick[0].ypos+1.0)* OHMS)) );
 	}
 	if (stick[1].enabled) {
 		stick[1].xtick = currentTick + 1000.0*( JOY_S_CONSTANT + S_PER_OHM *
-		                 (double)((swap34? stick[1].ypos : stick[1].xpos)+1.0) * OHMS);
+		                 (float)((swap34? stick[1].ypos : stick[1].xpos)+1.0) * OHMS);
 		stick[1].ytick = currentTick + 1000.0*( JOY_S_CONSTANT + S_PER_OHM *
-		                 (double)((swap34? stick[1].xpos : stick[1].ypos)+1.0) * OHMS);
+		                 (float)((swap34? stick[1].xpos : stick[1].ypos)+1.0) * OHMS);
 	}
 }
 
diff -ru dosbox-0.71.orig/src/hardware/keyboard.cpp dosbox-0.71/src/hardware/keyboard.cpp
--- dosbox-0.71.orig/src/hardware/keyboard.cpp	2007-06-12 15:22:08.000000000 -0500
+++ dosbox-0.71/src/hardware/keyboard.cpp	2007-08-01 13:06:34.296875000 -0500
@@ -343,8 +343,8 @@
 		/* Not handled yet. But usuable in mapper for special events */
 		return;
 	default:
-		E_Exit("Unsupported key press");
-		break;
+		LOG_MSG("Unsupported key press");
+		return;
 	}
 	/* Add the actual key in the keyboard queue */
 	if (pressed) {
diff -ru dosbox-0.71.orig/src/hardware/memory.cpp dosbox-0.71/src/hardware/memory.cpp
--- dosbox-0.71.orig/src/hardware/memory.cpp	2007-07-19 13:58:39.000000000 -0500
+++ dosbox-0.71/src/hardware/memory.cpp	2007-08-16 20:43:47.125000000 -0500
@@ -28,7 +28,11 @@
 #include <string.h>
 
 #define PAGES_IN_BLOCK	((1024*1024)/MEM_PAGE_SIZE)
+#ifdef PSP
+#define MAX_MEMORY	10
+#else
 #define MAX_MEMORY	64
+#endif
 #define MAX_PAGE_ENTRIES (MAX_MEMORY*1024*1024/4096)
 #define LFB_PAGES	512
 #define MAX_LINKS	((MAX_MEMORY*1024/4)+4096)		//Hopefully enough
@@ -421,12 +425,12 @@
 
 
 /* Memory access functions */
-Bit16u mem_unalignedreadw(PhysPt address) {
+Bit16u __attribute__((noinline)) mem_unalignedreadw(PhysPt address) {
 	return mem_readb_inline(address) |
 		mem_readb_inline(address+1) << 8;
 }
 
-Bit32u mem_unalignedreadd(PhysPt address) {
+Bit32u __attribute__((noinline)) mem_unalignedreadd(PhysPt address) {
 	return mem_readb_inline(address) |
 		(mem_readb_inline(address+1) << 8) |
 		(mem_readb_inline(address+2) << 16) |
@@ -434,12 +438,12 @@
 }
 
 
-void mem_unalignedwritew(PhysPt address,Bit16u val) {
+void __attribute__((noinline)) mem_unalignedwritew(PhysPt address,Bit16u val) {
 	mem_writeb_inline(address,(Bit8u)val);val>>=8;
 	mem_writeb_inline(address+1,(Bit8u)val);
 }
 
-void mem_unalignedwrited(PhysPt address,Bit32u val) {
+void __attribute__((noinline)) mem_unalignedwrited(PhysPt address,Bit32u val) {
 	mem_writeb_inline(address,(Bit8u)val);val>>=8;
 	mem_writeb_inline(address+1,(Bit8u)val);val>>=8;
 	mem_writeb_inline(address+2,(Bit8u)val);val>>=8;
@@ -447,7 +451,7 @@
 }
 
 
-bool mem_unalignedreadw_checked_x86(PhysPt address, Bit16u * val) {
+bool __attribute__((noinline)) mem_unalignedreadw_checked_x86(PhysPt address, Bit16u * val) {
 	Bit8u rval1,rval2;
 	if (mem_readb_checked_x86(address+0, &rval1)) return true;
 	if (mem_readb_checked_x86(address+1, &rval2)) return true;
@@ -455,7 +459,7 @@
 	return false;
 }
 
-bool mem_unalignedreadd_checked_x86(PhysPt address, Bit32u * val) {
+bool __attribute__((noinline)) mem_unalignedreadd_checked_x86(PhysPt address, Bit32u * val) {
 	Bit8u rval1,rval2,rval3,rval4;
 	if (mem_readb_checked_x86(address+0, &rval1)) return true;
 	if (mem_readb_checked_x86(address+1, &rval2)) return true;
@@ -465,13 +469,13 @@
 	return false;
 }
 
-bool mem_unalignedwritew_checked_x86(PhysPt address,Bit16u val) {
+bool __attribute__((noinline)) mem_unalignedwritew_checked_x86(PhysPt address,Bit16u val) {
 	if (mem_writeb_checked_x86(address,(Bit8u)(val & 0xff))) return true;val>>=8;
 	if (mem_writeb_checked_x86(address+1,(Bit8u)(val & 0xff))) return true;
 	return false;
 }
 
-bool mem_unalignedwrited_checked_x86(PhysPt address,Bit32u val) {
+bool __attribute__((noinline)) mem_unalignedwrited_checked_x86(PhysPt address,Bit32u val) {
 	if (mem_writeb_checked_x86(address,(Bit8u)(val & 0xff))) return true;val>>=8;
 	if (mem_writeb_checked_x86(address+1,(Bit8u)(val & 0xff))) return true;val>>=8;
 	if (mem_writeb_checked_x86(address+2,(Bit8u)(val & 0xff))) return true;val>>=8;
diff -ru dosbox-0.71.orig/src/hardware/mixer.cpp dosbox-0.71/src/hardware/mixer.cpp
--- dosbox-0.71.orig/src/hardware/mixer.cpp	2007-06-12 15:22:08.000000000 -0500
+++ dosbox-0.71/src/hardware/mixer.cpp	2007-08-18 14:51:35.234375000 -0500
@@ -27,6 +27,7 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include <math.h>
+#include <malloc.h>
 
 #if defined (WIN32)
 //Midi listing
@@ -36,8 +37,9 @@
 #include <windows.h>
 #include <mmsystem.h>
 #endif
-
+#ifdef USE_SDL
 #include "SDL.h"
+#endif
 #include "mem.h"
 #include "pic.h"
 #include "dosbox.h"
@@ -50,21 +52,35 @@
 #include "hardware.h"
 #include "programs.h"
 
+#ifdef PSP
+#include <pspaudio.h>
+#include <pspthreadman.h>
+#include <pspsdk.h>
+static SceUID fill_thid, audio_sema;
+#define SDL_LockAudio() sceKernelWaitSema(audio_sema, 1, 0)
+#define SDL_UnlockAudio() sceKernelSignalSema(audio_sema, 1)
+#endif
+static int num_chan = 0;
+
 #define MIXER_SSIZE 4
 #define MIXER_SHIFT 14
 #define MIXER_REMAIN ((1<<MIXER_SHIFT)-1)
-#define MIXER_VOLSHIFT 13
+#define MIXER_VOLSHIFT 0//13
 
 static inline Bit16s MIXER_CLIP(Bits SAMP) {
+#ifdef PSP
+	return __builtin_allegrex_max(__builtin_allegrex_min(SAMP, MAX_AUDIO), MIN_AUDIO);
+#else
 	if (SAMP < MAX_AUDIO) {
 		if (SAMP > MIN_AUDIO)
 			return SAMP;
 		else return MIN_AUDIO;
 	} else return MAX_AUDIO;
+#endif
 }
 
 struct MIXER_Channel {
-	double vol_main[2];
+	float vol_main[2];
 	Bits vol_mul[2];
 	Bit8u mode;
 	Bitu freq;
@@ -78,7 +94,11 @@
 };
 
 static struct {
+#ifdef MIXER_VOL
 	Bit32s work[MIXER_BUFSIZE][2];
+#else
+	Bit16s work[MIXER_BUFSIZE][2]; 
+#endif
 	Bitu pos,done;
 	Bitu needed, min_needed, max_needed;
 	Bit32u tick_add,tick_remain;
@@ -89,7 +109,9 @@
 	Bit32u blocksize;
 } mixer;
 
+#ifndef PSP
 Bit8u MixTemp[MIXER_BUFSIZE];
+#endif
 
 MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,char * name) {
 	MixerChannel * chan=new MixerChannel();
@@ -127,8 +149,10 @@
 }
 
 void MixerChannel::UpdateVolume(void) {
+#ifdef MIXER_VOL
 	volmul[0]=(Bits)((1 << MIXER_VOLSHIFT)*volmain[0]*mixer.mastervol[0]);
 	volmul[1]=(Bits)((1 << MIXER_VOLSHIFT)*volmain[1]*mixer.mastervol[1]);
+#endif
 }
 
 void MixerChannel::SetVolume(float _left,float _right) {
@@ -141,11 +165,13 @@
 	if (_yesno==enabled) return;
 	enabled=_yesno;
 	if (enabled) {
+#ifdef PSP
+		if(!num_chan++) 
+			sceKernelWakeupThread(fill_thid);
+#endif
 		freq_index=MIXER_REMAIN;
-		SDL_LockAudio();
 		if (done<mixer.done) done=mixer.done;
-		SDL_UnlockAudio();
-	}
+	} else num_chan--;
 }
 
 void MixerChannel::SetFreq(Bitu _freq) {
@@ -173,7 +199,7 @@
 		freq_index=MIXER_REMAIN;
 	}
 }
-
+#ifdef MIXER_VOL
 template<bool _8bits,bool stereo,bool signeddata>
 INLINE void MixerChannel::AddSamples(Bitu len,void * data) {
 	Bits diff[2];
@@ -244,6 +270,7 @@
 		LOG_MSG("Can't add, buffer full");	
 		return;
 	}
+
 	Bitu outlen=needed-done;Bits diff;
 	freq_index=0;
 	Bitu temp_add=(len << MIXER_SHIFT)/outlen;
@@ -267,6 +294,95 @@
 	}
 };
 
+
+#else
+template<bool _8bits,bool stereo,bool signeddata>
+INLINE void MixerChannel::AddSamples(Bitu len,void * data) {
+	Bits diff[2];
+	Bit8u * data8=(Bit8u*)data;
+	Bit8s * data8s=(Bit8s*)data;
+	Bit16s * data16=(Bit16s*)data;
+	Bit16u * data16u=(Bit16u*)data;
+	Bitu mixpos=mixer.pos+done;
+	freq_index&=MIXER_REMAIN;
+	Bitu pos=0;Bitu new_pos;
+
+	goto thestart;
+	while (1) {
+		new_pos=freq_index >> MIXER_SHIFT;
+		if (pos<new_pos) {
+			pos=new_pos;
+thestart:
+			if (pos>=len) return;
+			if (_8bits) {
+				if (!signeddata) {
+					if (stereo) {
+						diff[0]=(((Bit8s)(data8[pos*2+0] ^ 0x80)) << 8);
+						diff[1]=(((Bit8s)(data8[pos*2+1] ^ 0x80)) << 8);
+					} else {
+						diff[0]=(((Bit8s)(data8[pos] ^ 0x80)) << 8);
+					}
+				} else {
+					if (stereo) {
+						diff[0]=(data8s[pos*2+0] << 8);
+						diff[1]=(data8s[pos*2+1] << 8);
+					} else {
+						diff[0]=(data8s[pos] << 8);
+					}
+				}
+			} else {
+				if (signeddata) {
+					if (stereo) {
+						diff[0]=data16[pos*2+0];
+						diff[1]=data16[pos*2+1];
+					} else {
+						diff[0]=data16[pos];
+					}
+				} else {
+					if (stereo) {
+						diff[0]=(Bits)data16u[pos*2+0]-32768;
+						diff[1]=(Bits)data16u[pos*2+1]-32768;
+					} else {
+						diff[0]=(Bits)data16u[pos]-32768;
+					}
+				}
+			}
+		}
+		freq_index+=freq_add;
+		mixpos&=MIXER_BUFMASK;
+		mixer.work[mixpos][0] = MIXER_CLIP(mixer.work[mixpos][0] + diff[0]);
+		mixer.work[mixpos][1] = MIXER_CLIP(mixer.work[mixpos][1] + diff[(stereo?1:0)]);
+		mixpos++;done++;
+	}
+}
+
+void MixerChannel::AddStretched(Bitu len,Bit16s * data) {
+	if (done>=needed) {
+		LOG_MSG("Can't add, buffer full");	
+		return;
+	}
+
+	Bitu outlen=needed-done;Bits diff;
+	freq_index=0;
+	Bitu temp_add=(len << MIXER_SHIFT)/outlen;
+	Bitu mixpos=mixer.pos+done;done=needed;
+	Bitu pos=0;
+	diff=data[0];
+	while (outlen--) {
+		Bitu new_pos=freq_index >> MIXER_SHIFT;
+		if (pos<new_pos) {
+			pos=new_pos;
+			diff=data[pos];
+		}
+		freq_index+=freq_add;
+		mixpos&=MIXER_BUFMASK;
+		mixer.work[mixpos][0] = MIXER_CLIP(mixer.work[mixpos][0] + diff);
+		mixer.work[mixpos][1] = MIXER_CLIP(mixer.work[mixpos][1] + diff);
+		mixpos++;
+	}
+};
+#endif
+
 void MixerChannel::AddSamples_m8(Bitu len,Bit8u * data) {
 	AddSamples<true,false,false>(len,data);
 }
@@ -334,10 +450,31 @@
 	}
 	//Reset the the tick_add for constant speed
 	if( Mixer_irq_important() )
-		mixer.tick_add = ((mixer.freq) << MIXER_SHIFT)/1000;
+		mixer.tick_add = ((mixer.freq) << MIXER_SHIFT)/1024;
 	mixer.done = needed;
 }
 
+#ifdef PSPME
+#include "me_rpc.h"
+static void free_audio_lock(void) {
+	SDL_UnlockAudio();
+}
+
+static void me_mix(void) {
+	MIXER_MixData(mixer.needed);
+	mixer.tick_remain+=mixer.tick_add;
+	mixer.needed+=(mixer.tick_remain>>MIXER_SHIFT);
+	mixer.tick_remain&=MIXER_REMAIN;
+	dcache_sync();
+	sc_go((void *)&free_audio_lock);
+}
+
+static void MIXER_Mix(void) {
+	SDL_LockAudio();
+	me_go((void *)&me_mix);
+}
+#else
+
 static void MIXER_Mix(void) {
 	SDL_LockAudio();
 	MIXER_MixData(mixer.needed);
@@ -346,6 +483,7 @@
 	mixer.tick_remain&=MIXER_REMAIN;
 	SDL_UnlockAudio();
 }
+#endif
 
 static void MIXER_Mix_NoSound(void) {
 	MIXER_MixData(mixer.needed);
@@ -366,8 +504,8 @@
 	mixer.tick_remain&=MIXER_REMAIN;
 	mixer.done=0;
 }
-
-static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) {
+#ifndef PSP 
+static bool MIXER_CallBack(void * userdata, Bit8u *stream, int len) {
 	Bitu need=(Bitu)len/MIXER_SSIZE;
 	Bit16s * output=(Bit16s *)stream;
 	Bitu reduce;
@@ -375,9 +513,9 @@
 	Bits sample;
 	/* Enough room in the buffer ? */
 	if (mixer.done < need) {
-//		LOG_MSG("Full underrun need %d, have %d, min %d", need, mixer.done, mixer.min_needed);
+		LOG_MSG("Full underrun need %d, have %d, min %d", need, mixer.done, mixer.min_needed);
 		if((need - mixer.done) > (need >>7) ) //Max 1 procent stretch.
-			return;
+			return false;
 		reduce = mixer.done;
 		index_add = (reduce << MIXER_SHIFT) / need;
 		mixer.tick_add = ((mixer.freq+mixer.min_needed) << MIXER_SHIFT)/1000;
@@ -393,13 +531,13 @@
 				left = (mixer.min_needed - left);
 				left = 1 + (2*left) / mixer.min_needed; //left=1,2,3
 			}
-//			LOG_MSG("needed underrun need %d, have %d, min %d, left %d", need, mixer.done, mixer.min_needed, left);
+			LOG_MSG("needed underrun need %d, have %d, min %d, left %d", need, mixer.done, mixer.min_needed, left);
 			reduce = need - left;
 			index_add = (reduce << MIXER_SHIFT) / need;
 		} else {
 			reduce = need;
 			index_add = (1 << MIXER_SHIFT);
-//			LOG_MSG("regular run need %d, have %d, min %d, left %d", need, mixer.done, mixer.min_needed, left);
+			LOG_MSG("regular run need %d, have %d, min %d, left %d", need, mixer.done, mixer.min_needed, left);
 
 			/* Mixer tick value being updated:
 			 * 3 cases:
@@ -418,7 +556,7 @@
 		}
 	} else {
 		/* There is way too much data in the buffer */
-//		LOG_MSG("overflow run need %d, have %d, min %d", need, mixer.done, mixer.min_needed);
+		LOG_MSG("overflow run need %d, have %d, min %d", need, mixer.done, mixer.min_needed);
 		if (mixer.done > MIXER_BUFSIZE)
 			index_add = MIXER_BUFSIZE - 2*mixer.min_needed;
 		else 
@@ -470,11 +608,79 @@
 			pos++;
 		}
 	}
+	return true;
+}
+#else
+#define NUM_BUFFERS 2
+
+static const unsigned short freqs[] = {48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 0};
+
+extern "C" int sceAudio_38553111(unsigned short, unsigned short, char);
+extern "C" int sceAudio_E0727056(int, void *);
+
+static Bit32u * volatile buf_ptr;
+
+static int MIXER_AudioThread(SceSize args, void *argp) {
+	SceUID done_event = ((SceUID *)argp)[0];
+	sceAudio_38553111(mixer.blocksize, mixer.freq, 2);
+
+	while(1) {
+		sceKernelSetEventFlag(done_event, 1);
+		sceKernelSleepThread();
+		sceAudio_E0727056(PSP_AUDIO_VOLUME_MAX, buf_ptr);
+	}
+}
+
+static int MIXER_FillBufferThread(SceSize args, void *argp) {
+	Bit32u *curr_ptr, *buf = (Bit32u *)memalign(64, mixer.blocksize*NUM_BUFFERS*MIXER_SSIZE), *work = (Bit32u *)mixer.work;
+	Bitu curr_buf = 0, sample, need = mixer.blocksize, pos;
+	SceUID play_thid, done_event;
+	curr_ptr = buf;
+
+	done_event = sceKernelCreateEventFlag("audio_event", 0, 0, 0);
+	play_thid = sceKernelCreateThread("audio_thread", &MIXER_AudioThread, 18, 512, PSP_THREAD_ATTR_USER, NULL); 
+	if(play_thid) sceKernelStartThread(play_thid, sizeof(SceUID), &done_event);
+
+	while(1) {
+		if(!num_chan) {
+			if(mixer.done) {
+				SDL_LockAudio();
+				mixer.done = need;
+			}
+			else sceKernelSleepThread();
+		} else {
+			while(mixer.done < need) sceKernelDelayThread(5000);
+			SDL_LockAudio();
+		}
+		for (MixerChannel * chan=mixer.channels;chan;chan=chan->next) chan->done=0;
+		mixer.done=0;		// if we overrun...
+		mixer.needed=0;
+		pos = mixer.pos;
+		mixer.pos = (mixer.pos+need)&MIXER_BUFMASK;
+		for(sample = 0; sample < need; sample+=(64/MIXER_SSIZE)) {
+			__builtin_allegrex_cache(0x1e, (Bit32u)work+sample+64);		//prefetch next work cache line
+			__builtin_allegrex_cache(0x18, (Bit32u)curr_ptr+sample);	//create dirty exclusive 
+			for(int i = 0; i < (64/MIXER_SSIZE); i++) {
+				curr_ptr[sample+i] = work[pos+i];
+				work[pos+i] = 0;
+			}
+			pos = (pos+(64/MIXER_SSIZE)) & MIXER_BUFMASK;
+			__builtin_allegrex_cache(0x1a, (Bit32u)curr_ptr+sample);	//writeback
+		}
+		SDL_UnlockAudio();
+		buf_ptr = curr_ptr;
+		sceKernelWaitEventFlag(done_event, 1, PSP_EVENT_WAITCLEAR, NULL, NULL);
+		sceKernelWakeupThread(play_thid);
+		curr_buf = (curr_buf+1)%NUM_BUFFERS;
+		curr_ptr = &buf[mixer.blocksize*curr_buf];
+	}
 }
+#endif
 
 static void MIXER_Stop(Section* sec) {
 }
 
+#ifdef MIXER_VOL
 class MIXER : public Program {
 public:
 	void MakeVolume(char * scan,float & vol0,float & vol1) {
@@ -486,7 +692,7 @@
 				++scan;w=1;
 			}
 			char * before=scan;
-			float val=(float)strtod(scan,&scan);
+			float val=strtof(scan,&scan);
 			if (before==scan) {
 				++scan;continue;
 			}
@@ -529,7 +735,7 @@
 	void ShowVolume(char * name,float vol0,float vol1) {
 		WriteOut("%-8s %3.0f:%-3.0f  %+3.2f:%-+3.2f \n",name,
 			vol0*100,vol1*100,
-			20*log(vol0)/log(10.0f),20*log(vol1)/log(10.0f)
+			20*log10f(vol0),20*log10f(vol1)
 		);
 	}
 
@@ -550,6 +756,7 @@
 static void MIXER_ProgramStart(Program * * make) {
 	*make=new MIXER;
 }
+#endif
 
 MixerChannel* MixerObject::Install(MIXER_Handler handler,Bitu freq,char * name){
 	if(!installed) {
@@ -582,10 +789,10 @@
 	mixer.channels=0;
 	mixer.pos=0;
 	mixer.done=0;
-	memset(mixer.work,0,sizeof(mixer.work));
 	mixer.mastervol[0]=1.0f;
 	mixer.mastervol[1]=1.0f;
 
+#ifdef USE_SDL
 	/* Start the Mixer using SDL Sound at 22 khz */
 	SDL_AudioSpec spec;
 	SDL_AudioSpec obtained;
@@ -595,7 +802,7 @@
 	spec.channels=2;
 	spec.callback=MIXER_CallBack;
 	spec.userdata=NULL;
-	spec.samples=(Uint16)mixer.blocksize;
+	spec.samples=(Bit16u)mixer.blocksize;
 
 	mixer.tick_remain=0;
 	if (mixer.nosound) {
@@ -614,10 +821,27 @@
 		TIMER_AddTickHandler(MIXER_Mix);
 		SDL_PauseAudio(0);
 	}
+#elif defined(PSP)
+	int i;
+	for (i = 0; freqs[i]; i++)
+		if (mixer.freq >= freqs[i]) break;
+	if(!(mixer.freq = freqs[i])) mixer.nosound = true;
+	mixer.tick_add=(mixer.freq << MIXER_SHIFT)/1000;
+	mixer.blocksize = PSP_AUDIO_SAMPLE_ALIGN(__builtin_allegrex_max(__builtin_allegrex_min(mixer.blocksize, 4096), 128));
+	audio_sema = sceKernelCreateSema("audio_sema", 0, 1, 1, NULL);
+	if (mixer.nosound) TIMER_AddTickHandler(MIXER_Mix_NoSound);
+	else {
+		TIMER_AddTickHandler(MIXER_Mix);
+		fill_thid = sceKernelCreateThread("fill_thread", &MIXER_FillBufferThread, 20, 512, PSP_THREAD_ATTR_USER, NULL); 
+		if(fill_thid) sceKernelStartThread(fill_thid, 0, NULL);
+	}
+#endif
 	mixer.min_needed=section->Get_int("prebuffer");
 	if (mixer.min_needed>100) mixer.min_needed=100;
 	mixer.min_needed=(mixer.freq*mixer.min_needed)/1000;
 	mixer.max_needed=mixer.blocksize * 2 + 2*mixer.min_needed;
 	mixer.needed=mixer.min_needed+1;
+#ifdef MIXER_VOL
 	PROGRAMS_MakeFile("MIXER.COM",MIXER_ProgramStart);
+#endif
 }
diff -ru dosbox-0.71.orig/src/hardware/mpu401.cpp dosbox-0.71/src/hardware/mpu401.cpp
--- dosbox-0.71.orig/src/hardware/mpu401.cpp	2007-02-03 07:11:38.000000000 -0600
+++ dosbox-0.71/src/hardware/mpu401.cpp	2007-08-01 13:06:34.296875000 -0500
@@ -26,6 +26,8 @@
 #include "cpu.h"
 #include "support.h"
 
+#ifdef USE_MIDI
+
 void MIDI_RawOutByte(Bit8u data);
 bool MIDI_Available(void);
 
@@ -635,3 +637,9 @@
 	test = new MPU401(sec);
 	sec->AddDestroyFunction(&MPU401_Destroy,true);
 }
+
+#else
+
+void MPU401_Init(Section* src) { }
+
+#endif
diff -ru dosbox-0.71.orig/src/hardware/pcspeaker.cpp dosbox-0.71/src/hardware/pcspeaker.cpp
--- dosbox-0.71.orig/src/hardware/pcspeaker.cpp	2007-07-15 11:36:27.000000000 -0500
+++ dosbox-0.71/src/hardware/pcspeaker.cpp	2007-08-01 22:32:18.828125000 -0500
@@ -259,7 +259,7 @@
 		float index=sample_base;
 		sample_base+=sample_add;
 		float end=sample_base;
-		double value=0;
+		float value=0;
 		while(index<end) {
 			/* Check if there is an upcoming event */
 			if (spkr.used && spkr.entries[pos].index<=index) {
@@ -279,7 +279,7 @@
 				index+=vol_len;
 			} else {
 				/* Check how long it will take to goto new level */
-				float vol_time=fabs(vol_diff)/SPKR_SPEED;
+				float vol_time=fabsf(vol_diff)/SPKR_SPEED;
 				if (vol_time<=vol_len) {
 					/* Volume reaches endpoint in this block, calc until that point */
 					value+=vol_time*spkr.volcur;
diff -ru dosbox-0.71.orig/src/hardware/sblaster.cpp dosbox-0.71/src/hardware/sblaster.cpp
--- dosbox-0.71.orig/src/hardware/sblaster.cpp	2007-06-14 13:06:59.000000000 -0500
+++ dosbox-0.71/src/hardware/sblaster.cpp	2007-08-07 22:13:45.031250000 -0500
@@ -217,7 +217,7 @@
 }
 
 static INLINE void SB_RaiseIRQ(SB_IRQS type) {
-	LOG(LOG_SB,LOG_NORMAL)("Raising IRQ");
+//	LOG(LOG_SB,LOG_NORMAL)("Raising IRQ");
 	PIC_ActivateIRQ(sb.hw.irq);
 	switch (type) {
 	case SB_IRQ_8:
@@ -447,7 +447,7 @@
 		if (sb.dma.mode==DSP_DMA_16_ALIASED) read=read<<1;
 		break;
 	default:
-		LOG_MSG("Unhandled dma mode %d",sb.dma.mode);
+//		LOG_MSG("Unhandled dma mode %d",sb.dma.mode);
 		sb.mode=MODE_NONE;
 		return;
 	}
@@ -455,13 +455,13 @@
 	if (!sb.dma.left) {
 		PIC_RemoveEvents(END_DMA_Event);
 		if (!sb.dma.autoinit) {
-			LOG(LOG_SB,LOG_NORMAL)("Single cycle transfer ended");
+//			LOG(LOG_SB,LOG_NORMAL)("Single cycle transfer ended");
 			sb.mode=MODE_NONE;
 			sb.dma.mode=DSP_DMA_NONE;
 		} else {
 			sb.dma.left=sb.dma.total;
 			if (!sb.dma.left) {
-				LOG(LOG_SB,LOG_NORMAL)("Auto-init transfer with 0 size");
+//				LOG(LOG_SB,LOG_NORMAL)("Auto-init transfer with 0 size");
 				sb.mode=MODE_NONE;
 			}
 		}
@@ -528,6 +528,7 @@
 static void DSP_ChangeMode(DSP_MODES mode) {
 	if (sb.mode==mode) return;
 	else sb.chan->FillUp();
+	sb.chan->Enable(true);
 	sb.mode=mode;
 }
 
@@ -928,7 +929,7 @@
 }
 
 //The soundblaster manual says 2.0 Db steps but we'll go for a bit less
-#define CALCVOL(_VAL) (float)pow(10.0f,((float)(31-_VAL)*-1.3f)/20)
+#define CALCVOL(_VAL) (float)powf(10.0f,((float)(31-_VAL)*-1.3f)/20)
 static void CTMIXER_UpdateVolumes(void) {
 	if (!sb.mixer.enabled) return;
 	MixerChannel * chan;
@@ -1271,6 +1272,7 @@
 	case MODE_NONE:
 	case MODE_DMA_PAUSE:
 	case MODE_DMA_MASKED:
+		sb.chan->Enable(false);
 		sb.chan->AddSilence();
 		break;
 	case MODE_DAC:
@@ -1348,6 +1350,8 @@
 		sb.mixer.stereo=false;
 		OPL_Mode opl_mode = OPL_none;
 		Find_Type_And_Opl(section,sb.type,opl_mode);
+		
+		opl_mode = OPL_opl2;
 	
 		switch (opl_mode) {
 		case OPL_none:
diff -ru dosbox-0.71.orig/src/hardware/serialport/serialport.cpp dosbox-0.71/src/hardware/serialport/serialport.cpp
--- dosbox-0.71.orig/src/hardware/serialport/serialport.cpp	2007-02-22 01:41:16.000000000 -0600
+++ dosbox-0.71/src/hardware/serialport/serialport.cpp	2007-08-07 22:03:11.000000000 -0500
@@ -1084,7 +1084,7 @@
 };
 bool CSerial::Getchar(Bit8u* data, bool wait_dsr, Bitu timeout) {
 	
-	double starttime=PIC_FullIndex();
+	float starttime=PIC_FullIndex();
 	// wait for it to become empty
 	// wait for DSR on
 	if(wait_dsr) {
@@ -1124,7 +1124,7 @@
 
 bool CSerial::Putchar(Bit8u data, bool wait_dsr, bool wait_cts, Bitu timeout) {
 	
-	double starttime=PIC_FullIndex();
+	float starttime=PIC_FullIndex();
 	//Bit16u starttime=
 	// wait for it to become empty
 	while(!(LSR&0x20)) {
diff -ru dosbox-0.71.orig/src/hardware/tandy_sound.cpp dosbox-0.71/src/hardware/tandy_sound.cpp
--- dosbox-0.71.orig/src/hardware/tandy_sound.cpp	2007-06-29 12:56:07.000000000 -0500
+++ dosbox-0.71/src/hardware/tandy_sound.cpp	2007-08-07 22:03:39.093750000 -0500
@@ -269,7 +269,7 @@
 	/* at the given sample rate. No. of events = sample rate / (clock/16). */
 	/* STEP is a multiplier used to turn the fraction into a fixed point */
 	/* number. */
-	R->UpdateStep = (unsigned int)(((double)STEP * R->SampleRate * 16) / clock);
+	R->UpdateStep = (unsigned int)(((float)STEP * R->SampleRate * 16) / clock);
 }
 
 
@@ -284,7 +284,7 @@
 {
 	struct SN76496 *R = &sn;
 	int i;
-	double out;
+	float out;
 
 
 	gain &= 0xff;
diff -ru dosbox-0.71.orig/src/hardware/timer.cpp dosbox-0.71/src/hardware/timer.cpp
--- dosbox-0.71.orig/src/hardware/timer.cpp	2007-06-12 15:22:08.000000000 -0500
+++ dosbox-0.71/src/hardware/timer.cpp	2007-08-07 22:11:35.125000000 -0500
@@ -27,6 +27,16 @@
 #include "timer.h"
 #include "setup.h"
 
+#ifdef PSP
+#include <sys/time.h>
+struct timeval start;
+Bitu GetTicks() {
+	struct timeval now;
+	gettimeofday(&now, NULL);
+	return (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000;
+}
+#endif
+
 static INLINE void BIN2BCD(Bit16u& val) {
 	Bit16u temp=val%10 + (((val/10)%10)<<4)+ (((val/100)%10)<<8) + (((val/1000)%10)<<12);
 	val=temp;
@@ -40,7 +50,7 @@
 struct PIT_Block {
 	Bitu cntr;
 	float delay;
-	double start;
+	float start;
 
 	Bit16u read_latch;
 	Bit16u write_latch;
@@ -68,14 +78,14 @@
 	PIC_ActivateIRQ(0);
 	if (pit[0].mode != 0) {
 		pit[0].start += pit[0].delay;
-		double error = 	pit[0].start - PIC_FullIndex();
+		float error = 	pit[0].start - PIC_FullIndex();
 		PIC_AddEvent(PIT0_Event,(float)(pit[0].delay + error));
 	}
 }
 
 static bool counter_output(Bitu counter) {
 	PIT_Block * p=&pit[counter];
-	double index=PIC_FullIndex()-p->start;
+	float index=PIC_FullIndex()-p->start;
 	switch (p->mode) {
 	case 0:
 		if (p->new_mode) return false;
@@ -84,11 +94,11 @@
 		break;
 	case 2:
 		if (p->new_mode) return true;
-		index=fmod(index,(double)p->delay);
+		index=fmodf(index,(float)p->delay);
 		return index>0;
 	case 3:
 		if (p->new_mode) return true;
-		index=fmod(index,(double)p->delay);
+		index=fmodf(index,(float)p->delay);
 		return index*2<p->delay;
 	default:
 		LOG(LOG_PIT,LOG_ERROR)("Illegal Mode %d for reading output",p->mode);
@@ -129,7 +139,7 @@
 	//If gate2 is disabled don't update the read_latch
 	if(counter == 2 && !gate2) return;
 
-	double index=PIC_FullIndex()-p->start;
+	float index=PIC_FullIndex()-p->start;
 	switch (p->mode) {
 	case 4:		/* Software Triggered Strobe */
 	case 0:		/* Interrupt on Terminal Count */
@@ -137,10 +147,10 @@
 		if (index>p->delay) {
 			index-=p->delay;
 			if(p->bcd) {
-				index = fmod(index,(1000.0/PIT_TICK_RATE)*10000.0);
+				index = fmodf(index,(1000.0/PIT_TICK_RATE)*10000.0);
 				p->read_latch = (Bit16u)(9999-index*(PIT_TICK_RATE/1000.0));
 			} else {
-				index = fmod(index,(1000.0/PIT_TICK_RATE)*(double)0x10000);
+				index = fmodf(index,(1000.0/PIT_TICK_RATE)*(float)0x10000);
 				p->read_latch = (Bit16u)(0xffff-index*(PIT_TICK_RATE/1000.0));
 			}
 		} else {
@@ -148,11 +158,11 @@
 		}
 		break;
 	case 2:		/* Rate Generator */
-		index=fmod(index,(double)p->delay);
+		index=fmodf(index,(float)p->delay);
 		p->read_latch=(Bit16u)(p->cntr - (index/p->delay)*p->cntr);
 		break;
 	case 3:		/* Square Wave Rate Generator */
-		index=fmod(index,(double)p->delay);
+		index=fmodf(index,(float)p->delay);
 		index*=2;
 		if (index>p->delay) index-=p->delay;
 		p->read_latch=(Bit16u)(p->cntr - (index/p->delay)*p->cntr);
@@ -208,7 +218,7 @@
 			LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.2f Hz mode %d",1000.0/p->delay,p->mode);
 			break;
 		case 0x02:			/* Timer hooked to PC-Speaker */
-//			LOG(LOG_PIT,"PIT 2 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode);
+//			LOG(LOG_PIT,"PIT 2 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(float)p->cntr,p->mode);
 			PCSPEAKER_SetCounter(p->cntr,p->mode);
 			break;
 		default:
diff -ru dosbox-0.71.orig/src/hardware/vga_draw.cpp dosbox-0.71/src/hardware/vga_draw.cpp
--- dosbox-0.71.orig/src/hardware/vga_draw.cpp	2007-06-12 15:22:08.000000000 -0500
+++ dosbox-0.71/src/hardware/vga_draw.cpp	2007-08-07 22:10:36.640625000 -0500
@@ -27,12 +27,10 @@
 
 #define VGA_PARTS 4
 
-typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart, Bitu line);
-
 static VGA_Line_Handler VGA_DrawLine;
-static Bit8u TempLine[SCALER_MAXWIDTH * 4];
+//static Bit8u TempLine[SCALER_MAXWIDTH * 4];
 
-static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart, Bitu line) {
+static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart, Bitu line, Bit8u *TempLine) {
 	const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
 	Bit32u *draw = (Bit32u *)TempLine;
 	for (Bitu x=vga.draw.blocks;x>0;x--, vidstart++) {
@@ -43,7 +41,7 @@
 	return TempLine;
 }
 
-static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart, Bitu line) {
+static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart, Bitu line, Bit8u *TempLine) {
 	const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
 	Bit32u * draw=(Bit32u *)TempLine;
 	for (Bitu x=0;x<vga.draw.blocks;x++) {
@@ -54,7 +52,7 @@
 	return TempLine;
 }
 
-static Bit8u * VGA_Draw_2BPPHiRes_Line(Bitu vidstart, Bitu line) {
+static Bit8u * VGA_Draw_2BPPHiRes_Line(Bitu vidstart, Bitu line, Bit8u *TempLine) {
 	const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
 	Bit32u * draw=(Bit32u *)TempLine;
 	for (Bitu x=0;x<vga.draw.blocks;x++) {
@@ -70,7 +68,7 @@
 
 static Bitu temp[643]={0};
 
-static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart, Bitu line) {
+static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart, Bitu line, Bit8u *TempLine) {
 	const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
 	const Bit8u *reader = base + vidstart;
 	Bit32u * draw=(Bit32u *)TempLine;
@@ -110,7 +108,7 @@
 	return TempLine;
 }
 
-static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart, Bitu line) {
+static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart, Bitu line, Bit8u *TempLine) {
 	const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
 	Bit32u * draw=(Bit32u *)TempLine;
 	for (Bitu x=0;x<vga.draw.blocks;x++) {
@@ -126,7 +124,7 @@
 	return TempLine;
 }
 
-static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart, Bitu line) {
+static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart, Bitu line, Bit8u *TempLine) {
 	const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
 	Bit32u * draw=(Bit32u *)TempLine;
 	for (Bitu x=0;x<vga.draw.blocks;x++) {
@@ -141,7 +139,7 @@
 }
 
 #ifdef VGA_KEEP_CHANGES
-static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) {
+static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line, Bit8u *TempLine) {
 	Bitu checkMask = vga.changes.checkMask;
 	Bit8u *map = vga.changes.map;
 	Bitu start = (vidstart >> VGA_CHANGE_SHIFT);
@@ -165,8 +163,9 @@
 
 #endif
 
-static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu line) {
+static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu line, Bit8u *TempLine) {
 	Bit8u *ret = &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ];
+	memcpy(TempLine, ret, vga.draw.line_length);
 #if !defined(C_UNALIGNED_MEMORY)
 	if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) {
 		memcpy( TempLine, ret, vga.draw.line_length );
@@ -177,7 +176,7 @@
 }
 
 //Test version, might as well keep it
-static Bit8u * VGA_Draw_Chain_Line(Bitu vidstart, Bitu line) {
+static Bit8u * VGA_Draw_Chain_Line(Bitu vidstart, Bitu line, Bit8u *TempLine) {
 	Bitu i = 0;
 	for ( i = 0; i < vga.draw.width;i++ ) {
 		Bitu addr = vidstart + i;
@@ -186,7 +185,7 @@
 	return TempLine;
 }
 
-static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line) {
+static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line, Bit8u *TempLine) {
 	if(vga.s3.hgc.curmode & 0x1) {
 		Bitu lineat = vidstart / vga.draw.width;
 		if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) {
@@ -246,7 +245,7 @@
 	}
 }
 
-static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart,   Bitu line) {
+static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart,   Bitu line, Bit8u *TempLine) {
 	if(vga.s3.hgc.curmode & 0x1) {
 		Bitu lineat = (vidstart >> 1) / vga.draw.width;
 		if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) {
@@ -309,7 +308,7 @@
 	}
 }
 
-static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart,   Bitu line) {
+static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart,   Bitu line, Bit8u *TempLine) {
 	if(vga.s3.hgc.curmode & 0x1) {
 		Bitu lineat = (vidstart >> 2) / vga.draw.width;
 		if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) {
@@ -379,7 +378,7 @@
 }
 
 static Bit32u FontMask[2]={0xffffffff,0x0};
-static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) {
+static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line, Bit8u *TempLine) {
 	Bits font_addr;
 	Bit32u * draw=(Bit32u *)TempLine;
 	const Bit8u *vidmem = &vga.tandy.draw_base[vidstart];
@@ -436,8 +435,8 @@
 
 static void VGA_DrawPart(Bitu lines) {
 	while (lines--) {
-		Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line );
-		RENDER_DrawLine(data);
+//		Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line );
+		RENDER_DrawLine(vga.draw.address, vga.draw.address_line, VGA_DrawLine);
 		vga.draw.address_line++;
 		if (vga.draw.address_line>=vga.draw.address_line_total) {
 			vga.draw.address_line=0;
@@ -508,7 +507,7 @@
 
 
 static void VGA_VerticalTimer(Bitu val) {
-	double error = vga.draw.delay.framestart;
+	float error = vga.draw.delay.framestart;
 	vga.draw.delay.framestart = PIC_FullIndex();
 	error = vga.draw.delay.framestart - error - vga.draw.delay.vtotal;
 //	 if (abs(error) > 0.001 ) 
@@ -762,7 +761,7 @@
 	
 	fps=(float)clock/(vtotal*htotal);
 	// The time a complete video frame takes
-	vga.draw.delay.vtotal = (1000.0 * (double)(vtotal*htotal)) / (double)clock; 
+	vga.draw.delay.vtotal = (1000.0 * (float)(vtotal*htotal)) / (float)clock; 
 	// Horizontal total (that's how long a line takes with whistles and bells)
 	vga.draw.delay.htotal = htotal*1000.0/clock; //in milliseconds
 	// Start and End of horizontal blanking
@@ -796,8 +795,8 @@
 		vga.draw.delay.vend);
     */
 	vga.draw.parts_total=VGA_PARTS;
-	double correct_ratio=(100.0/525.0);
-	double aspect_ratio=((double)htotal/((double)vtotal)/correct_ratio);
+	float correct_ratio=(100.0f/525.0f);
+	float aspect_ratio=((float)htotal/((float)vtotal)/correct_ratio);
 	vga.draw.delay.parts = vga.draw.delay.vdend/vga.draw.parts_total;
 	vga.draw.resizing=false;
 
diff -ru dosbox-0.71.orig/src/hardware/vga_gfx.cpp dosbox-0.71/src/hardware/vga_gfx.cpp
--- dosbox-0.71.orig/src/hardware/vga_gfx.cpp	2007-01-08 12:45:40.000000000 -0600
+++ dosbox-0.71/src/hardware/vga_gfx.cpp	2007-08-01 13:06:34.296875000 -0500
@@ -32,12 +32,16 @@
 }
 
 static void write_p3cf(Bitu port,Bitu val,Bitu iolen) {
-	switch (gfx(index)) {
-	case 0:	/* Set/Reset Register */
+	Bit32u old;
+	switch (gfx(index))
+	case 0:	{ /* Set/Reset Register */
 		gfx(set_reset)=val & 0x0f;
 		vga.config.full_set_reset=FillTable[val & 0x0f];
+		old = vga.config.full_enable_and_set_reset;
 		vga.config.full_enable_and_set_reset=vga.config.full_set_reset &
 			vga.config.full_enable_set_reset;
+		vga.force_update &= 0xfd;
+		vga.force_update |= (old!=vga.config.full_enable_and_set_reset)<<1;
 		/*
 			0	If in Write Mode 0 and bit 0 of 3CEh index 1 is set a write to
 				display memory will set all the bits in plane 0 of the byte to this
@@ -52,9 +56,13 @@
 	case 1: /* Enable Set/Reset Register */
 		gfx(enable_set_reset)=val & 0x0f;
 		vga.config.full_enable_set_reset=FillTable[val & 0x0f];
+		vga.force_update &= 0xfe;
+		vga.force_update |= (vga.config.full_not_enable_set_reset!=~vga.config.full_enable_set_reset);
 		vga.config.full_not_enable_set_reset=~vga.config.full_enable_set_reset;
+		old = vga.config.full_enable_and_set_reset;
 		vga.config.full_enable_and_set_reset=vga.config.full_set_reset &
 			vga.config.full_enable_set_reset;
+		vga.force_update |= (old!=vga.config.full_enable_and_set_reset);
 //		if (gfx(enable_set_reset)) vga.config.mh_mask|=MH_SETRESET else vga.config.mh_mask&=~MH_SETRESET;
 		break;
 	case 2: /* Color Compare Register */
@@ -70,6 +78,8 @@
 		break;
 	case 3: /* Data Rotate */
 		gfx(data_rotate)=val;
+		vga.force_update &= 0xfb;
+		vga.force_update |= (vga.config.data_rotate!=(val & 7))<<2;
 		vga.config.data_rotate=val & 7;
 //		if (val) vga.config.mh_mask|=MH_ROTATEOP else vga.config.mh_mask&=~MH_ROTATEOP;
 		vga.config.raster_op=(val>>3) & 3;
diff -ru dosbox-0.71.orig/src/hardware/vga_memory.cpp dosbox-0.71/src/hardware/vga_memory.cpp
--- dosbox-0.71.orig/src/hardware/vga_memory.cpp	2007-06-12 15:22:08.000000000 -0500
+++ dosbox-0.71/src/hardware/vga_memory.cpp	2007-08-04 20:51:08.484375000 -0500
@@ -57,6 +57,8 @@
 
 
 void VGA_MapMMIO(void);
+
+#ifndef PSP
 //Nice one from DosEmu
 INLINE static Bit32u RasterOp(Bit32u input,Bit32u mask) {
 	switch (vga.config.raster_op) {
@@ -101,6 +103,103 @@
 	}
 	return full;
 }
+#else
+
+#define SetResetFill(val, out)					\
+      { Bit32u temp, tempa;					\
+	__asm__ ( "li   %1, 0xff\n"				\
+		  "andi %2, %3, 1\n"				\
+		  "movz %1, $0, %2\n"				\
+		  "move %0, %1\n"				\
+		  "li   %1, 0xff00\n"				\
+		  "andi %2, %3, 2\n"				\
+		  "movz %1, $0, %2\n"				\
+		  "or   %0, %0, %1\n"				\
+  		  "lui  %1, 0xff\n"				\
+		  "andi %2, %3, 4\n"				\
+		  "movz %1, $0, %2\n"				\
+		  "or   %0, %0, %1\n"				\
+		  "lui  %1, 0xff00\n"				\
+		  "andi %2, %3, 8\n"				\
+		  "movz %1, $0, %2\n"				\
+		  "or   %0, %0, %1\n"				\
+		:"=r"(out),"=r"(temp),"=r"(tempa):"r"(val)); }
+
+INLINE static Bit32u ModeOperation(Bit8u val) {
+	static Bit8u last_val;
+	static Bit32u last_input;
+	Bit32u input = 0, mask = vga.config.full_bit_mask;
+
+	switch(vga.config.write_mode) {
+// Write Mode 1: In this mode, data is transferred directly from the 32 bit latch register to display memory,
+// affected only by the Memory Plane Write Enable field. The host data is not used in this mode. 
+	case 1:
+		return vga.latch.d;
+// Write Mode 2: In this mode, the bits 3-0 of the host data are replicated across all 8 bits of their
+// respective planes. Then the selected Logical Operation is performed on the resulting data and the data
+// in the latch register. Then the Bit Mask field is used to select which bits come from the resulting
+// data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane
+// Write Enable field are written to memory.
+	case 2:
+		SetResetFill(val, input);
+		break;
+// Write Mode 0: In this mode, the host data is first rotated as per the Rotate Count field, then the
+// Enable Set/Reset mechanism selects data from this or the Set/Reset field. Then the selected Logical
+// Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask
+// field is used to select which bits come from the resulting data and which come from the latch register.
+// Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
+	case 0:
+		if((val == last_val) && !vga.force_update) {
+			input = last_input;
+			break;
+		}
+// Write Mode 3: In this mode, the data in the Set/Reset field is used as if the Enable Set/Reset field were
+// set to 1111b. Then the host data is first rotated as per the Rotate Count field, then logical ANDed with
+// the value of the Bit Mask field. The resulting value is used on the data obtained from the Set/Reset field
+// in the same way that the Bit Mask field would ordinarily be used. to select which bits come from the
+// expansion of the Set/Reset field and which come from the latch register. Finally, only the bit planes
+// enabled by the Memory Plane Write Enable field are written to memory.
+	case 3:
+		Bit8u mode = vga.config.write_mode >> 1;
+		Bit32u input0, input3, mask3, expand;
+
+		vga.force_update = 0;
+		val = (val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate));
+		__asm__ ( "move %0, %1\n"
+			  "ins  %0, %1, 8, 8\n"
+			  "ins  %0, %1, 16, 8\n"
+			  "ins  %0, %1, 24, 8\n"
+			:"=r"(expand):"r"(val));
+//		expand = val | (val<<8) | (val<<16) | (val<<24);
+		mask3 = expand & mask;
+		input0 = (expand & vga.config.full_not_enable_set_reset) | vga.config.full_enable_and_set_reset; 
+		input3 = vga.config.full_set_reset;
+		__asm__ ( "movz  %0, %4, %3\n"
+			  "addiu %2, %3, -1\n"
+			  "movz  %0, %5, %2\n"
+			  "movz  %1, %6, %2\n"
+			:"=r"(input),"=r"(mask),"=r"(mode):"2"(mode),"r"(input0),"r"(input3),"r"(mask3),"1"(mask));
+		last_input = input;
+		last_val = val;
+		break;
+	}
+	if((mask == -1) && !vga.config.raster_op) return input;
+
+	Bit32u a = (input & mask) | (vga.latch.d & ~mask);
+	Bit32u b = (input | ~mask) & vga.latch.d;
+	Bit32u c = (input & mask) | vga.latch.d;
+	Bit32u d = (input & mask) ^ vga.latch.d;
+	Bit32u ret, temp;
+	__asm__ ( "move  %0, %6\n"
+		  "sltiu %1, %2, 3\n"
+		  "movn  %0, %5, %1\n"
+		  "sltiu %1, %2, 2\n"
+		  "movn  %0, %4, %1\n"
+		  "movz  %0, %3, %2\n"
+		:"=r"(ret),"=r"(temp):"r"(vga.config.raster_op),"r"(a),"r"(b),"r"(c),"r"(d) );
+	return ret;
+}
+#endif
 
 /* Gonna assume that whoever maps vga memory, maps it on 32/64kb boundary */
 
@@ -122,7 +221,14 @@
 			return (vga.latch.b[vga.config.read_map_select]);
 		case 1:
 			VGA_Latch templatch;
+#ifdef PSP
+			Bit32u dont_care, compare;
+			SetResetFill(vga.config.color_dont_care, dont_care);
+			SetResetFill(vga.config.color_compare & vga.config.color_dont_care, compare);
+			templatch.d=(vga.latch.d & dont_care) ^ compare;
+#else
 			templatch.d=(vga.latch.d &	FillTable[vga.config.color_dont_care]) ^ FillTable[vga.config.color_compare & vga.config.color_dont_care];
+#endif
 			return (Bit8u)~(templatch.b[0] | templatch.b[1] | templatch.b[2] | templatch.b[3]);
 		}
 		return 0;
@@ -251,8 +357,8 @@
 			Expand16Table[3][temp.b[3]];
 		*(Bit32u *)(write_pixels+4)=colors4_7;
 		if (wrapping && GCC_UNLIKELY( start < 512)) {
-			*(Bit32u *)(write_pixels+512*1024)=colors0_3;
-			*(Bit32u *)(write_pixels+512*1024+4)=colors4_7;
+			*(Bit32u *)(write_pixels+384*1024)=colors0_3;
+			*(Bit32u *)(write_pixels+384*1024+4)=colors4_7;
 		}
 	}
 public:	
diff -ru dosbox-0.71.orig/src/hardware/vga_misc.cpp dosbox-0.71/src/hardware/vga_misc.cpp
--- dosbox-0.71.orig/src/hardware/vga_misc.cpp	2007-06-12 15:22:08.000000000 -0500
+++ dosbox-0.71/src/hardware/vga_misc.cpp	2007-08-07 22:12:31.125000000 -0500
@@ -32,7 +32,7 @@
 	vga.internal.attrindex=false;
 	vga.tandy.pcjr_flipflop=false;
 	Bit8u retval=0;
-	double timeInFrame = PIC_FullIndex()-vga.draw.delay.framestart;
+	float timeInFrame = PIC_FullIndex()-vga.draw.delay.framestart;
 
  	vga.internal.attrindex=false;
  	vga.tandy.pcjr_flipflop=false;
@@ -47,7 +47,7 @@
 		if(timeInFrame >= vga.draw.delay.vrstart &&
 			timeInFrame <= vga.draw.delay.vrend)
 			retval |= 0x80;
-		double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal);
+		float timeInLine=fmodf(timeInFrame,vga.draw.delay.htotal);
 		if(timeInLine >= vga.draw.delay.hrstart &&
 			timeInLine <= vga.draw.delay.hrend)
 			retval |= 1;
@@ -65,7 +65,7 @@
 		if(timeInFrame >= vga.draw.delay.vdend)
 			retval |= 1;
 		else {
-			double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal);
+			float timeInLine=fmodf(timeInFrame,vga.draw.delay.htotal);
 			if(timeInLine >= (vga.draw.delay.hblkstart) && 
 					timeInLine <= vga.draw.delay.hblkend){
 				retval |= 1;
diff -ru dosbox-0.71.orig/src/hardware/vga_other.cpp dosbox-0.71/src/hardware/vga_other.cpp
--- dosbox-0.71.orig/src/hardware/vga_other.cpp	2007-02-01 09:24:03.000000000 -0600
+++ dosbox-0.71/src/hardware/vga_other.cpp	2007-08-01 13:06:34.312500000 -0500
@@ -145,7 +145,7 @@
 	return ~0;
 }
 
-static double hue_offset = 0.0;
+static float hue_offset = 0.0;
 static Bit8u cga16_val = 0;
 static void update_cga16_color(void);
 
@@ -166,8 +166,8 @@
 // to match an entry that is generated here.
 
 	int baseR=0, baseG=0, baseB=0;
-	double sinhue,coshue,hue,basehue = 50.0;
-	double I,Q,Y,pixelI,pixelQ,R,G,B;
+	float sinhue,coshue,hue,basehue = 50.0;
+	float I,Q,Y,pixelI,pixelQ,R,G,B;
 	Bitu colorBit1,colorBit2,colorBit3,colorBit4,index;
 
 	if (cga16_val & 0x01) baseB += 0xa8;
@@ -177,8 +177,8 @@
 	if (cga16_val & 0x20) basehue = 35.0;
 
 	hue = (basehue + hue_offset)*0.017453239;
-	sinhue = sin(hue);
-	coshue = cos(hue);
+	sinhue = sinf(hue);
+	coshue = cosf(hue);
 
 	for(Bitu i = 0; i < 16;i++) {
 		for(Bitu j = 0;j < 5;j++) {
@@ -190,11 +190,11 @@
 
 			//calculate lookup table
 			I = 0; Q = 0;
-			I += (double) colorBit1;
-			Q += (double) colorBit2;
-			I -= (double) colorBit3;
-			Q -= (double) colorBit4;
-			Y  = (double) j / 4.0; //calculated avarage is over 4 bits
+			I += (float) colorBit1;
+			Q += (float) colorBit2;
+			I -= (float) colorBit3;
+			Q -= (float) colorBit4;
+			Y  = (float) j / 4.0; //calculated avarage is over 4 bits
 
 			pixelI = I * 1.0 / 3.0; //I* tvSaturnation / 3.0
 			pixelQ = Q * 1.0 / 3.0; //Q* tvSaturnation / 3.0
diff -ru dosbox-0.71.orig/src/hardware/vga_xga.cpp dosbox-0.71/src/hardware/vga_xga.cpp
--- dosbox-0.71.orig/src/hardware/vga_xga.cpp	2007-01-08 14:44:10.000000000 -0600
+++ dosbox-0.71/src/hardware/vga_xga.cpp	2007-08-01 13:06:34.312500000 -0500
@@ -27,6 +27,8 @@
 
 #define XGA_SHOW_COMMAND_TRACE 0
 
+#if (IO_MAX > 0xe2ea)
+
 struct XGAStatus {
 	struct scissorreg {
 		Bit16u x1, y1, x2, y2;
@@ -1169,4 +1171,6 @@
 
 
 }
-
+#else
+void VGA_SetupXGA(void) {}
+#endif
diff -ru dosbox-0.71.orig/src/ints/int10.h dosbox-0.71/src/ints/int10.h
--- dosbox-0.71.orig/src/ints/int10.h	2007-01-08 12:45:41.000000000 -0600
+++ dosbox-0.71/src/ints/int10.h	2007-08-01 13:06:34.312500000 -0500
@@ -18,8 +18,11 @@
 
 #include "vga.h"
 
+#ifdef PSP
+#define S3_LFB_BASE		0xFF00000
+#else
 #define S3_LFB_BASE		0xC0000000
-
+#endif
 #define BIOSMEM_SEG		0x40
 
 #define BIOSMEM_INITIAL_MODE  0x10
diff -ru dosbox-0.71.orig/src/ints/int10_vesa.cpp dosbox-0.71/src/ints/int10_vesa.cpp
--- dosbox-0.71.orig/src/ints/int10_vesa.cpp	2007-06-12 15:22:09.000000000 -0500
+++ dosbox-0.71/src/ints/int10_vesa.cpp	2007-08-01 13:06:34.312500000 -0500
@@ -28,6 +28,7 @@
 #include "inout.h"
 #include "int10.h"
 #include "dos_inc.h"
+#include "vga.h"
 
 static struct {
 	Bitu setwindow;
@@ -115,7 +116,7 @@
 	}
 	mem_writed(buffer+0x0a,0x0);					//Capabilities and flags
 	mem_writed(buffer+0x0e,int10.rom.vesa_modes);	//VESA Mode list
-	mem_writew(buffer+0x12,32);						//32 64kb blocks for 2 mb memory
+	mem_writew(buffer+0x12,VGA_MEMORY/65536);				//32 64kb blocks for 2 mb memory
 	return 0x00;
 }
 
diff -ru dosbox-0.71.orig/src/ints/mouse.cpp dosbox-0.71/src/ints/mouse.cpp
--- dosbox-0.71.orig/src/ints/mouse.cpp	2007-06-12 15:22:09.000000000 -0500
+++ dosbox-0.71/src/ints/mouse.cpp	2007-08-07 22:17:48.187500000 -0500
@@ -414,8 +414,8 @@
 	float dx = xrel * mouse.pixelPerMickey_x;
 	float dy = yrel * mouse.pixelPerMickey_y;
 
-	if((fabs(x) > 1.0) || (mouse.senv_x < 1.0)) dx *= mouse.senv_x;
-	if((fabs(y) > 1.0) || (mouse.senv_y < 1.0)) dy *= mouse.senv_y;
+	if((fabsf(x) > 1.0) || (mouse.senv_x < 1.0)) dx *= mouse.senv_x;
+	if((fabsf(y) > 1.0) || (mouse.senv_y < 1.0)) dy *= mouse.senv_y;
 	if (useps2callback) dy *= 2;	
 
 	mouse.mickey_x += dx;
@@ -796,9 +796,9 @@
 		// ToDo : double mouse speed value
 		break;
 	case 0x1b:	/* Get mouse sensitivity */
-		reg_bx = Bit16s((60.0* sqrt(mouse.senv_x- (1.0/3.0)) ) +1.0);
+		reg_bx = Bit16s((60.0* sqrtf(mouse.senv_x- (1.0/3.0)) ) +1.0);
 
-		reg_cx = Bit16s((60.0* sqrt(mouse.senv_y- (1.0/3.0)) ) +1.0);
+		reg_cx = Bit16s((60.0* sqrtf(mouse.senv_y- (1.0/3.0)) ) +1.0);
 
 		LOG(LOG_MOUSE,LOG_WARN)("Get sensitivity %d %d",reg_bx,reg_cx);
 
diff -ru dosbox-0.71.orig/src/misc/setup.cpp dosbox-0.71/src/misc/setup.cpp
--- dosbox-0.71.orig/src/misc/setup.cpp	2007-06-27 09:51:30.000000000 -0500
+++ dosbox-0.71/src/misc/setup.cpp	2007-08-09 22:34:00.562500000 -0500
@@ -30,11 +30,11 @@
 
 using namespace std;
 
-void Prop_float::SetValue(char* input){
+/*void Prop_float::SetValue(char* input){
 	input=trim(input);
-	value._float= static_cast<float>(atof(input));
+	value._float= strtof(input,NULL);
 }
-
+*/
 void Prop_int::SetValue(char* input){
 	input=trim(input);
 	value._int= atoi(input);
@@ -70,20 +70,20 @@
 void Prop_bool::GetValuestring(char* str) const{
         sprintf(str,"%s",value._bool?"true":"false");
 }
-
+/*
 void Prop_float::GetValuestring(char* str) const {
 	sprintf(str,"%1.2f",value._float);
 }
-
+*/
 void Prop_hex::GetValuestring(char* str) const {
         sprintf(str,"%X",value._hex);
 }
-
+/*
 void Section_prop::Add_float(char const * const _propname, float _value) {
 	Property* test=new Prop_float(_propname,_value);
 	properties.push_back(test);
 }
-
+*/
 
 void Section_prop::Add_int(const char* _propname, int _value) {
 	Property* test=new Prop_int(_propname,_value);
@@ -120,6 +120,7 @@
 	}
 	return false;
 }
+/*
 float Section_prop::Get_float(char const * const _propname) const {
 	for(const_it tel=properties.begin();tel!=properties.end();tel++){
 		if((*tel)->propname==_propname){
@@ -128,7 +129,7 @@
 	}
 	return false;
 }
-
+*/
 const char* Section_prop::Get_string(char const * const _propname) const {
 	for(const_it tel=properties.begin();tel!=properties.end();tel++){
 		if((*tel)->propname==_propname){
diff -ru dosbox-0.71.orig/src/misc/support.cpp dosbox-0.71/src/misc/support.cpp
--- dosbox-0.71.orig/src/misc/support.cpp	2007-06-12 15:22:09.000000000 -0500
+++ dosbox-0.71/src/misc/support.cpp	2007-08-01 13:06:34.312500000 -0500
@@ -30,6 +30,9 @@
 #include "support.h"
 #include "video.h"
 
+#ifdef PSP_ME
+#include "me_rpc_code.h"
+#endif
 /* 
 	Ripped some source from freedos for this one.
 
diff -ru dosbox-0.71.orig/src/shell/shell.cpp dosbox-0.71/src/shell/shell.cpp
--- dosbox-0.71.orig/src/shell/shell.cpp	2007-07-03 12:32:14.000000000 -0500
+++ dosbox-0.71/src/shell/shell.cpp	2007-08-20 23:08:22.687500000 -0500
@@ -278,6 +278,12 @@
 	return;
 }
 
+#ifdef PSP
+extern const char build_version[];
+#define BUILD build_version
+#else
+#define BUILD "DOSBox v"\ VERSION
+#endif
 
 void DOS_Shell::Run(void) {
 	char input_line[CMD_MAXLINE] = {0};
@@ -292,7 +298,7 @@
 	}
 	/* Start a normal shell and check for a first command init */
 	if(machine != MCH_HERC) { //Hide it for hercules as that looks too weird
-		WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),VERSION);
+		WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),BUILD);
 #if C_DEBUG
 		WriteOut(MSG_Get("SHELL_STARTUP_DEBUG"));
 #endif
@@ -468,14 +474,14 @@
 		"\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
 		"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
 		"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n"
-		"\xBA \033[32mWelcome to DOSBox v%-8s\033[37m                                        \xBA\n"
+		"\xBA \033[32mWelcome to %-16s\033[37m              \xBA\n"
 		"\xBA                                                                    \xBA\n"
 //		"\xBA DOSBox runs real and protected mode games.                         \xBA\n"
 		"\xBA For a short introduction for new users type: \033[33mINTRO\033[37m                 \xBA\n"
 		"\xBA For supported shell commands type: \033[33mHELP\033[37m                            \xBA\n"
 		"\xBA                                                                    \xBA\n"
-		"\xBA If you want more speed, try \033[31mctrl-F8\033[37m and \033[31mctrl-F12\033[37m.                  \xBA\n"
-		"\xBA To activate the keymapper \033[31mctrl-F1\033[37m.                                 \xBA\n"
+//		"\xBA If you want more speed, try \033[31mctrl-F8\033[37m and \033[31mctrl-F12\033[37m.                  \xBA\n"
+//		"\xBA To activate the keymapper \033[31mctrl-F1\033[37m.                                 \xBA\n"
 		"\xBA For more information read the \033[36mREADME\033[37m file in the DOSBox directory. \xBA\n"
 		"\xBA                                                                    \xBA\n"
 	);
