From c676b6075a6fa28a6cee2aff37b9c645d2a3f6f5 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 30 Mar 2017 21:21:31 +0200 Subject: [PATCH 01/11] Updated drawing, custom, events and other parts from WinUAE 3.4.1 --- Makefile | 26 +- VisualGDB/Amiberry.sln | 48 +- .../Amiberry/Amiberry-Debug.vgdbsettings | 2 +- VisualGDB/Amiberry/Amiberry.vcxproj | 2 +- VisualGDB/VisualGDB/Debug/genlinetoscr | Bin 0 -> 87944 bytes VisualGDB/genblitter/Readme.txt | 17 + .../genblitter/genblitter-Debug.vgdbsettings | 154 + .../genblitter-Release.vgdbsettings | 142 + VisualGDB/genblitter/genblitter.vcxproj | 71 + .../genblitter/genblitter.vcxproj.filters | 40 + VisualGDB/genblitter/genblitter.vcxproj.user | 4 + VisualGDB/genlinetoscr/Readme.txt | 7 + .../genlinetoscr-Debug.vgdbsettings | 154 + .../genlinetoscr-Release.vgdbsettings | 142 + VisualGDB/genlinetoscr/genlinetoscr.vcxproj | 70 + .../genlinetoscr/genlinetoscr.vcxproj.filters | 37 + .../genlinetoscr/genlinetoscr.vcxproj.user | 4 + src/akiko.cpp | 74 +- src/audio.cpp | 32 +- src/autoconf.cpp | 599 +- src/blitfunc.cpp | 3592 ++-- src/blitops.cpp | 517 +- src/blittable.cpp | 138 +- src/blitter.cpp | 1907 +- src/blkdev.cpp | 26 +- src/cfgfile.cpp | 3412 ++- src/cia.cpp | 2723 ++- src/custom.cpp | 9355 +++++--- src/disk.cpp | 9 +- src/drawing.cpp | 4082 ++-- src/events.cpp | 130 +- src/expansion.cpp | 6006 +++++- src/filesys.cpp | 348 +- src/genblitter.cpp | 388 +- src/genlinetoscr.cpp | 605 + src/gfxboard.cpp | 8 + src/gfxutil.cpp | 421 +- src/hardfile.cpp | 29 +- src/include/akiko.h | 3 +- src/include/audio.h | 120 +- src/include/autoconf.h | 308 +- src/include/blit.h | 1033 +- src/include/blitter.h | 60 +- src/include/cia.h | 32 +- src/include/custom.h | 128 +- src/include/drawing.h | 139 +- src/include/events.h | 80 +- src/include/filesys.h | 39 +- src/include/genblitter.h | 24 +- src/include/gfxboard.h | 85 +- src/include/inputdevice.h | 9 +- src/include/keybuf.h | 14 +- src/include/memory.h | 644 +- src/include/native2amiga.h | 6 +- src/include/newcpu.h | 42 +- src/include/options.h | 267 +- src/include/picasso96.h | 51 +- src/include/rommgr.h | 313 +- src/include/savestate.h | 4 +- src/include/sysdeps.h | 87 +- src/include/traps.h | 125 +- src/include/xwin.h | 4 +- src/inputdevice.cpp | 159 +- src/jit/compemu.h | 1 + src/jit/compemu_support.cpp | 71 +- src/linetoscr.c | 806 - src/linetoscr.cpp | 17623 ++++++++++++++++ src/machdep/maccess.h | 22 +- src/main.cpp | 260 +- src/memory.cpp | 3632 +++- src/newcpu.cpp | 270 +- src/osdep/amiberry.cpp | 11 +- src/osdep/amiberry_filesys.cpp | 5 +- src/osdep/amiberry_gfx.cpp | 274 +- src/osdep/amiberry_gfx.h | 3 +- src/osdep/amiberry_gui.cpp | 3 +- src/osdep/amiberry_input.cpp | 5 + src/osdep/amiberry_mem.cpp | 6 +- src/osdep/amiberry_rp9.cpp | 6 +- src/osdep/gui/PanelCPU.cpp | 8 +- src/osdep/gui/PanelConfig.cpp | 2 +- src/osdep/gui/PanelRAM.cpp | 24 +- src/osdep/gui/main_window.cpp | 2 +- src/osdep/menu/menu_config.cpp | 8 +- src/osdep/picasso96.cpp | 1158 +- src/osdep/sysconfig.h | 7 + src/osdep/target.h | 20 +- src/osdep/writelog.cpp | 36 +- src/rommgr.cpp | 840 +- src/savestate.cpp | 24 +- src/trace.c | 87 - src/traps.cpp | 2 + src/uaelib.cpp | 393 +- 93 files changed, 50304 insertions(+), 14402 deletions(-) create mode 100644 VisualGDB/VisualGDB/Debug/genlinetoscr create mode 100644 VisualGDB/genblitter/Readme.txt create mode 100644 VisualGDB/genblitter/genblitter-Debug.vgdbsettings create mode 100644 VisualGDB/genblitter/genblitter-Release.vgdbsettings create mode 100644 VisualGDB/genblitter/genblitter.vcxproj create mode 100644 VisualGDB/genblitter/genblitter.vcxproj.filters create mode 100644 VisualGDB/genblitter/genblitter.vcxproj.user create mode 100644 VisualGDB/genlinetoscr/Readme.txt create mode 100644 VisualGDB/genlinetoscr/genlinetoscr-Debug.vgdbsettings create mode 100644 VisualGDB/genlinetoscr/genlinetoscr-Release.vgdbsettings create mode 100644 VisualGDB/genlinetoscr/genlinetoscr.vcxproj create mode 100644 VisualGDB/genlinetoscr/genlinetoscr.vcxproj.filters create mode 100644 VisualGDB/genlinetoscr/genlinetoscr.vcxproj.user create mode 100644 src/genlinetoscr.cpp delete mode 100644 src/linetoscr.c create mode 100644 src/linetoscr.cpp delete mode 100644 src/trace.c diff --git a/Makefile b/Makefile index 3e5ae654..585e0af3 100644 --- a/Makefile +++ b/Makefile @@ -25,12 +25,8 @@ all: guisan $(PROG) guisan: cd src/guisan && make all && cd ../.. -#DEBUG=1 -#TRACER=1 - +DEBUG=1 PANDORA=1 -#GEN_PROFILE=1 -#USE_PROFILE=1 SDL_CFLAGS = `sdl2-config --cflags --libs` @@ -42,33 +38,22 @@ DEFS += -DUSE_SDL MORE_CFLAGS += -Isrc -Isrc/osdep -Isrc/threaddep -Isrc/include -Isrc/guisan/include MORE_CFLAGS += -Wno-unused -Wno-format -DGCCCONSTFUNC="__attribute__((const))" -MORE_CFLAGS += -fexceptions -fpermissive +MORE_CFLAGS += -fexceptions -fpermissive +MORE_CFLAGS += -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free -LDFLAGS += -lpthread -lm -lz -lpng -lrt -lxml2 -lFLAC -lmpg123 -ldl +LDFLAGS += -lpthread -lm -lz -lpng -lrt -lxml2 -lFLAC -lmpg123 -ldl -lprofiler -ltcmalloc LDFLAGS += -lSDL2 -lSDL2_image -lSDL2_ttf -lguisan -L/opt/vc/lib -Lsrc/guisan/lib ifndef DEBUG MORE_CFLAGS += -Ofast -pipe else MORE_CFLAGS += -g -DDEBUG -Wl,--export-dynamic - -ifdef TRACER -TRACE_CFLAGS = -DTRACER -finstrument-functions -Wall -rdynamic -endif - endif ASFLAGS += $(CPU_FLAGS) CXXFLAGS += $(SDL_CFLAGS) $(CPU_FLAGS) $(DEFS) $(MORE_CFLAGS) -ifdef GEN_PROFILE -MORE_CFLAGS += -fprofile-generate=./test -fprofile-arcs -fvpt -endif -ifdef USE_PROFILE -MORE_CFLAGS += -fprofile-use -fbranch-probabilities -fvpt -endif - OBJS = \ src/akiko.o \ src/aros.rom.o \ @@ -216,9 +201,6 @@ OBJS += src/jit/compemu_support.o src/osdep/neon_helper.o: src/osdep/neon_helper.s $(CXX) $(CPU_FLAGS) -Wall -o src/osdep/neon_helper.o -c src/osdep/neon_helper.s -src/trace.o: src/trace.c - $(CC) $(MORE_CFLAGS) -c src/trace.c -o src/trace.o - $(PROG): $(OBJS) $(CXX) $(CXXFLAGS) -o $(PROG) $(OBJS) $(LDFLAGS) ifndef DEBUG diff --git a/VisualGDB/Amiberry.sln b/VisualGDB/Amiberry.sln index 678ec157..c293a35c 100644 --- a/VisualGDB/Amiberry.sln +++ b/VisualGDB/Amiberry.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.9 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Amiberry", "Amiberry\Amiberry.vcxproj", "{D76BB09D-FF2A-4028-A065-421C430CD238}" ProjectSection(ProjectDependencies) = postProject @@ -9,6 +9,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Amiberry", "Amiberry\Amiber EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "guisan", "guisan\guisan.vcxproj", "{A431BAB9-641E-48D7-8ACE-BC1D5100FBA2}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genlinetoscr", "genlinetoscr\genlinetoscr.vcxproj", "{883F2A00-8030-429B-AC7F-E930DDF9568F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genblitter", "genblitter\genblitter.vcxproj", "{619EFB8C-E41A-4058-B085-1B8CD22692DD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|VisualGDB = Debug|VisualGDB @@ -61,6 +65,46 @@ Global {A431BAB9-641E-48D7-8ACE-BC1D5100FBA2}.Release-rpi2|x64.Build.0 = Debug|VisualGDB {A431BAB9-641E-48D7-8ACE-BC1D5100FBA2}.Release-rpi2|x86.ActiveCfg = Debug|VisualGDB {A431BAB9-641E-48D7-8ACE-BC1D5100FBA2}.Release-rpi2|x86.Build.0 = Debug|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Debug|VisualGDB.ActiveCfg = Debug|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Debug|VisualGDB.Build.0 = Debug|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Debug|x64.ActiveCfg = Debug|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Debug|x86.ActiveCfg = Debug|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release|VisualGDB.ActiveCfg = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release|VisualGDB.Build.0 = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release|x64.ActiveCfg = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release|x86.ActiveCfg = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release-rpi1|VisualGDB.ActiveCfg = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release-rpi1|VisualGDB.Build.0 = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release-rpi1|x64.ActiveCfg = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release-rpi1|x64.Build.0 = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release-rpi1|x86.ActiveCfg = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release-rpi1|x86.Build.0 = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release-rpi2|VisualGDB.ActiveCfg = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release-rpi2|VisualGDB.Build.0 = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release-rpi2|x64.ActiveCfg = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release-rpi2|x64.Build.0 = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release-rpi2|x86.ActiveCfg = Release|VisualGDB + {883F2A00-8030-429B-AC7F-E930DDF9568F}.Release-rpi2|x86.Build.0 = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Debug|VisualGDB.ActiveCfg = Debug|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Debug|VisualGDB.Build.0 = Debug|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Debug|x64.ActiveCfg = Debug|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Debug|x86.ActiveCfg = Debug|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release|VisualGDB.ActiveCfg = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release|VisualGDB.Build.0 = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release|x64.ActiveCfg = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release|x86.ActiveCfg = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release-rpi1|VisualGDB.ActiveCfg = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release-rpi1|VisualGDB.Build.0 = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release-rpi1|x64.ActiveCfg = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release-rpi1|x64.Build.0 = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release-rpi1|x86.ActiveCfg = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release-rpi1|x86.Build.0 = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release-rpi2|VisualGDB.ActiveCfg = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release-rpi2|VisualGDB.Build.0 = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release-rpi2|x64.ActiveCfg = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release-rpi2|x64.Build.0 = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release-rpi2|x86.ActiveCfg = Release|VisualGDB + {619EFB8C-E41A-4058-B085-1B8CD22692DD}.Release-rpi2|x86.Build.0 = Release|VisualGDB EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/VisualGDB/Amiberry/Amiberry-Debug.vgdbsettings b/VisualGDB/Amiberry/Amiberry-Debug.vgdbsettings index 4237630e..3d120c03 100644 --- a/VisualGDB/Amiberry/Amiberry-Debug.vgdbsettings +++ b/VisualGDB/Amiberry/Amiberry-Debug.vgdbsettings @@ -101,7 +101,7 @@ main true false - false + true false diff --git a/VisualGDB/Amiberry/Amiberry.vcxproj b/VisualGDB/Amiberry/Amiberry.vcxproj index 405a5f4f..8bfbf804 100644 --- a/VisualGDB/Amiberry/Amiberry.vcxproj +++ b/VisualGDB/Amiberry/Amiberry.vcxproj @@ -55,7 +55,7 @@ -Wl,-gc-sections,-rpath,/usr/local/lib;%(Link.AdditionalLinkerInputs) ../../src/guisan/lib;=/opt/vc/lib;=/usr/local/lib;%(Link.LibrarySearchDirectories) - SDL2;SDL2_image;SDL2_ttf;pthread;m;z;png;rt;xml2;FLAC;mpg123;dl;guisan;%(Link.AdditionalLibraryNames) + SDL2;SDL2_image;SDL2_ttf;pthread;m;z;png;rt;xml2;FLAC;mpg123;dl;guisan;profiler;%(Link.AdditionalLibraryNames) =/usr/local/lib;%(ExtraRPATH) diff --git a/VisualGDB/VisualGDB/Debug/genlinetoscr b/VisualGDB/VisualGDB/Debug/genlinetoscr new file mode 100644 index 0000000000000000000000000000000000000000..6d22c98bf1931019b52ace4506d877f2587de4dd GIT binary patch literal 87944 zcmb?^3tUxI_WyU^dw~lV@Ty!uF5qlk_ZTBY8qBn_HeSv zW-6;gO-)UID|?PpS!On4)62@KrpF}eY0O(Q)$~;1{6A~&ea^igI{kj1AAP)gpS`|o z?X}ll`*F@XXV)>kbOvJ#`kx7@psURmhI{}A<}sKo2+D^GR-_^si9~PtIv4mlm+^nw z0shYd@PEMo=gkMnVBi875G3hlqBHu(_`e|l|3~~(w_h7^wK)&`AMq2F>&MGX*qmoV z0Rzezc)dh7kv@6!&&2;(8TdcaOV^R`<&5!v(*XWYr_EE_Yjt}B{t>?&Kz3t8b#`NI zW@AIsx(%6Ct!q}*XSFqFsvCw++5CFxNBw*k@b2|qpQcWmKJl@q5N zSaiwnr>{9?vXXrWuk&q1x!pe5Q$=M~0AT=9hu$22`>V5^o4*=3VA9Xp3t4jue+bEL z9}uW7{gE#EAJsohzmWQHrR5*d%k&FLzbfE*5P*jP?8`Utb`C@={?dnjf1m5aeXgJB zbNzUqYcw`gx3$;Sj2uZO9gWJ$m1~-tD%;wtTH7ltQ8{aU<@~yp4Q=gpty3GT+S=;c zP+3wjr?R%LRTfvwncCRgR98_|-B>4R{Zbkms@I4r8XKxt*3?wC(NzvAE34|Nsv9cT zHC^7&R9jio(o)&dnnR!(0k5iVZf!?fdu{W&cGS15Yp+3NC6T3)YpNQWu)e;fwV|oK z9!X{MOJ&?ekeEou|=NAX$%LDSo0r{eU z{8-BG?L2{FohK~zdrn5UI=d{cOx1!+)qX%xEeA5ya42fHM^RNx^L1&OZ?BudK8&H% z%@E~L)F_vtnmxB1Gr4a2Coum+f|kub)wI)xvl)^A#CsGq9)wwOEEo%jeyiQ1s1SKJ zSj+BuKHtRsnf{XOikbvPW%d=vCJ*fFx^LK3$6mJY?IO8-`DhH#Kl-y5WquJ`q^R&5 z<+ANt_s4#wX+GxZJOR%k)xLHAsTcB1+^!@ao}C=WfH-T>{!_;^?X)icjHZREa9JC27RnRDCvGdjC)WcG2( z-g{0aXxUvaxET((84kJG|Eb)=ZiXXnh7T_wSJ!QWM^T4JeN9r|Rn(WV%q+_mdlYqm zEVIb6VvnMR$+93>Ha4LB)W>8~vI&6GN&U3{n495CH^Wb)XCi|=ks&^jAvN)Qd)Qry zu(juEHPD8KX#SIZ5_M$GaXV}()dkOOs?}pt?H(uhP2!_|>Dvc~$#04?zp(7xaol=j z&T)7;PY_=Sa5`VgaiQ~s+1}Zet!X~qx1MW`6NdLK)#D<$^Si#)wDFcBvyWr@{!^qE z$sT~rF9PLTJvVV)my}KVSnRvGj5tm6asJ}{r|d^|948+kIlcH{Q{UAzpI$fd+wBVH zx9I$`{)|L+Uj47|HV7T`_66$jbC2euu}bXZd#hG7N_wG0zFYO*>x2dr% zn;K7chf~edG#`pOyQ1J!y_7%J*%j*_FJX-bgm0`mps4Y(JQ(<^o@c-#t-2pr@FF@xIsWa(h0pdJNQEN5Lm%$XZTGMYO$vIjzUpqXqxW`6m^=W z`QCt{PSG^qVJK>mrumYj9yDi}fViijsN*%wmk>~wZhxA?!hpD4P}Cev^X-J9(wMy& zikhiuzU@%dk(%b)21QNNG+%_2O?*}$t_6xZT+@8DP*k@}hiRH`1r&8Cts%ha#Zdg? zbo>5OD~2;{8_uw2xagN7!x=uLK1pIoN@6HaVpx^LaB~vFt|W#7Neriw7>bh_8j~3| zBr|j-Gwe%dIF!tgl;ZEt*#F{-51177#~#i1AaFX|&O$v+GAe(i@=C+9x$ckMK2( z?+vD?FZXD^BTP|Wx`@65FQV@_>Sv~?kN0T4JD8$AdJ#F=MQ9^5%~!w_^`0KhSHTo@ z_eHQ|;|tl=@jtZRm$X;1cXs`X?B<^v|Et~iNxrTBLp~Z4R9|b4=A${Qsz>vYuUGbn zaYFt@a|Mk-FBEl2kLIH_lFDiQr}APb>Vh6IPOMPWaxa+fu}s z*q6d^l6-yyL;MJa@(~Q%MlkFf!Ektle=N}2Olu#_%Ty=%A!yGg_aJm_mh+|6?o^AU z9<*;Q4AA4l5e%+Wzuf-jdm0P6{Mo?iAG-a0Ky|p7!s`f;bwn{mwe*NNp7>}^Bpqp9 zp}8|~J{NhMKIu`^lhWqjcWb_EX-k^tF2u9Xqo{i&+BmneCtU!rM_mU@TwS%dUC zH+vM7<~Zu-54$zrAmDU=y3u}*`jT*OQQI$oqy2+R;tq9dK3cyHcKiFhHkIM-RE8s| z498L#PNp*al*(XFV{oN0WTg4~!RTKI+a3v!;|aiBtiRrp?Is%z0pbps74^k#%|~|8 z_q_Z*060ziyob%AjZrSA`gFJEyW6a&Pj+j*JIso@w_Ec8ohQQWyVd2ic9<3Q|8;A= zZDvLNL$~JJYF5;@HO=?Fv<>z3cp$FPtf=>OYra)xMOC^rU#(eD@9EZjE6j?z`y#r; z2k3Gu;mnG9OSk6BFe~bg09|P9J7-eV?cJL1CzGOH*RA=&&5FA1BC@}hb1}7ZQ@7@O z+N7u(x;5V?CPiJ}P2*Lxlh(dYlcKIATbLBJxm)wSU{ciEHO;rrq^P&ioN7|k2C|WC zH{B214#c&a6t$*X^R<{1wW?e5HJTK)lI&$t)a7I^lcFx`)_jXiin`v+}qGxMSC0C$I;$~_EX=V6ZT_?%c9rqO-3T)UZT>T!$fCO&U6PvWSdhQ@S;JJJ~rq%&Y7 zL&ivku_GC#jbx}D$*^rC!=8~0Uyfvm&0r|XVAz_$uqT6IUk1aW3S<~tOmsFzTm2Px`8>hmB)U2snG z?F&-WdFM3W(?N<_c24u{4N}xOx@_@WAgnV;QHul0%)oQCL5e!{oaS2*q^Oh6X}+yN ziaP0>=Gz>ksD(P#v*Wxr-EtAyA1^{n>XvpA`3X`t{5W*z3?3Yd0(EGiNnli&;^hI!pI`;@+J4ZLqE{7M!pFVJ6v6 zq>F{_b3D6MYd~A**#eE_o|J}d5BbX)vS8nG7&u*Q zQq)yvHD7^AQR~lYzOg1ntv##xGE9nEeOB{L0(!Ocm&)JOt@%8_X}XuYzFYI1WQuw% ztw&5zuaRr*Ro$9zL_k~m_K|p2yW_w1(Z+7g=KxM`W{NtB`kyIk-dW9O@1y%Kl~>32 z060z0LKb(6wR9NCll#XJ0dsRwz*uny%*_cv9Id$n&uTtePX};+RMd#G7xw?ki_osW z2<S5UGVc6+m7kxgcub1?Ui|+SdJ>$Q34qUTnterd~_G&Mjp}uvhdDOn5&MwM( zDDUa)+DZ3d_RcP|tF!B6U6x#HHZXf@H`T*Vai;WP9cRjk|eOhc#BT2#suweyVT zD`tv%?-{Yzy8DcOy~qHb%V&!E+cTQaEXN+L`!uKY)&DEnqccUl`HUWi*l|HD%{z2o zc-0xrr_WUvlKTPe&!MR6g$?-pej)4|-I|Y{*V8kx%YFg=0NumT{r?&9JZ$+HvBz5$ zU^B8K?e7+yq5Y$xR*?V6=d5>o7#{X8?C~%hp*U3zLsSk!eva^^iX4VjISku!7&>zp z_U14g$PqqB{&+a2_uk7z&-Lv#6}gHESLX@1u2E@R$9in43ph>vXwK>EN}^}+o~w`1 z^J{qCQ!~YLf-s6{^oOBm`Gl($>qA_B7?Z@vwJC0Mj-oQD1K~*q=|TGe7k^GNzw0AS zdv0-#SkvhF`d@$6eB@I$=~JQ7r$WwXz9OcmL1)B$f%%NMFJRJFD9%tI*Y9wTP0f?{ z{GU7=prx~`bcLdp zmMd!Tid&8amEUqKctzbYwzad%w6nA8p`SG0jH)LBp~GOT&f?j;-yLtE_9PO#@smm#eL%wWVQ0<@%~dSE0)@;rz0eh7Gk&J&(6v)(P~UL|^@=ZXrU_jQUqqt*In4 zRIjVoH53?XxNP0jvbl?<&#$PQKXZyJRTq^u;XGVR<%XK(#^zShR$`Xzy+X>QKj9ZH zVYkNS=GE(3c*PRV^`pOrdRM9-S2i{K5oy$y93cNl(8xkpZFOTyeRF-=vg($`+I3Zp zE%mw0^<<1d+@*!OS%od>FQA<*l~q!Ip*rW?a=tzMxW4+!_LA=Xc8)8><=K$yNpoFc z=(Vn?tzl(TT`l*v8dsq!Rp?Mz-`rYR+gf#bL(|GEUPP~rw2`|T*5KlD>X*AFPITpv zr+7AunL+;rv^$`Ez51~xP1suB&}biyR3;PkHSsG$aaqfc!Oe ztt;y)bNM( z*44Kyk|{64Xt4APy^+7PA{t9%ZyJob(*N}9`~ZKXKRGQ|(xgN6xJJ5?YnQtUT`TL_ z^*Ot;y|t>Tt);59uBm2YYFkTdO|xNV{jaZ_Unqj>+L!mg>(D>nMeC$>N1sPiTzRy( zCAR^6rw!_N|A3k}(UnVsc{G0&E`UF0RDe9e=4oS<-17$*iFF+jeS8KkX0D zlj`YLQNmnEW==mc|C>#7{)B|GfW&PI!j|7~3Tg8KD7YHO)!rs3J2 z5_(B(ZU-Y-p;@rLBc)yuToa3i`^ZY-+xc zjNGQ$T&{*LBe$tGr!W77m`MSHu|YDD?yYregp7JuYHI4bhNkwG_SVYwv=n{PTTXLj zt}&naZDwqFxsCL4eO)7=dY;A%%|BEJUymlr-GJEcbN<%4_I0gId`aW_wAQVm&04=I z5ua4c(7m;8jj?y-_0~1jW@b*n<*OPR>twYB2E{**>U#U{H~O9bcs;#+KyRJE`+dXj zMIO1I^V3rGY(ar5XLOotvwye4x0f?!%$OnC)VnT&kM^J()QeR}GjvQ(P36tX8SP5% z)sclRosgz0MNCu|@0WnRg)Sp6_dFT04Wiu_!HK%^axYjH?OVtvsPAZD8{SY~TUYOz zJaaOj-_s=FKw^Q|Xt-9{Kv14870ecQtVIWZ7^vHdZ#ET`QcbU8` z6vJpkGp~Z%NAk#fMM1A>sx@p*?Wk^PTva8S!g<8rUnhy%CTb|zyEmRc_&t?l$Gyle8BhLu&Wx;5(>tJ<4e zvq+Y}R;+4hbJf$ZxV);3HfnXPRqb`PuIi0^*QVdJXSt>|H;rg_)zvn%XTg=8jiTM` zs=a%+ZX>-YKi~;}zQ6Lx9DkL855)Xm=Py*(&F^R(^lir0qgqFirga=Ws&!1$v<~~< zw2op;>zMX8t)o=aI_~(J)={o$9p3k~jtZiGpmi+Pw2luy)H=MH*73>5TE_}a>&W;- z>!{VVjy<1h9ji30Tu1rOvNvYpHIi zYI5agjmyf-%<-g&oFvbjyRdgb0Df#%er66)$7bbYGBuTd_W_myAZRp#gRLx-g_#Cf z2D2#UU@_)cHiX5QoaT6z$lj2j=ZFt}#NRHN?v!Z}fCqvY76UjZ(~4k*ebkL13>g5% zhA@uX5W?UEa5RMRPmyA+3v*#F zKAt@B7oI%X#gnJb^5khp1+hPq&68(Kc=E^4g;cn27*GB*ktfeB=gIS%dGf+TJlTJc zCoi4g$;&-FIhe4B*k75*lS7yCBm}&uRJLwz4YgyA0!1m~DAow~)0>ZD#0)lU5 z1v$VaW*}nS5+LG=B>*Cm%)o%UwFutHwlo0~=K`AuLR0}6(AbXPT?`8a^^V?D`vNZz zdt|u9y4HngpB$&doUWHYlX<%j`orgAoxAjwp3W@MV(P_53FmhNAL&i?nJ>j z=wYhoW0tr;TniM!9v@A;d5k?3toP<|cAL?gCm8vG=*=(K^aVh25D;+}*`kvx`K?9v z=2vW~M`%(^5TXhQ@6B%*76@v6Z>s3c@7XdYdh_3nQ!{4R4|I( z9BZ09O#i(ufpU?7Gr zA~-eHk_d#%`{OboBm{^EkyOO~eg+US|MMk)D+EX}2t#h42!vF88U>Jq!Vq985nrT6 z$MMRRl6-ba2(a8>6BI9}tPKG+>y(H?e#S~p-WdYyHptuPYhS@#!^w|_0M8lZw~5>7 z9s-24bjJXHqpIHx0X{V#yaEAf|13p9z7G+bHem}cB`#z#5OM{zibYw0VOD9382+>+ z{t7n`a^=S~8|GPoi8?ug>cmiII1qB0tD?REkdlLPSMnC9qphlvyRE8By|0) zJh}X3o?MaWrNS#G@#Lx{Jh{4wC)ZrVlWlkK!evEP!$lbt0z z`E>(NZoiQycihdByB_Ar?&o-N_eVUr=VzYW8+$29>CEEEeRFy8%{N@ZA08u1hyK{W z3xD3mlQSRiY9K0jBw(?%{D$7_+wP#eo&7Eha8U`|<0Al@gQZpjNF=&# z5UZ&MejNtHP$q&%5zC2=;iHEGwvB%nPP@tpR|2-7?1eCZMUq7K;RS%r&8q3+_~Gx5 z1#BCr5;lCD7qDIN49_=He)G#be`+aU>-c6WVeVT8*shA5LHUoU{OS=&ls`uKYceRG z{DB<^x9wVB0~`x31#G{edf^Da1hD;<@)pPTP{4La)iU}{KiRvG7z z1%&64(kV|=0O4cutAUiyGJ)_Z(KWz`{3yWo%+UqF71h9y$F~5smz>dJSnaU^PuhT( z0=hvQvLX|(y|S=G5MQ$aZyUte<|e@QmtjkQ<2K+F5!R6vV@qoQ+w1Phz*!r>!VSWg zLjl{{VJSdVI512nMDRuq`Oyj3{;_u*Ks_=#94OEc7_yi&IevDyAT9_8YIGv+JJEsm zhlc~40QG(WqtgIeE_*Zq_%;lcp7 zZ8VF_7u35Wfcp(<>i;VOY~vZds%u z*TMkXY__Kw_$dO2h?ETz7-AK`w4I{>+X8lLoe-ED35+@)jI=|W0NXM)Ymo54Ig!9( z1D8c63(wC1Y_;s^OMwlM`hX^quy}a*2*9?6ZCnoA(I5TFEWoy&-D?8&8Fa2HZNm}% z-4%fCM)us5z=sB%Y|DQn{a37ZF7T5amwM_+94*<3f(7naLNZ@dq(Dty^HNdU` zz+E~JBl(>0ID3D*m=rQzNdaunG4eU~(g5I91DeT6uL{yf0|5GhUN|S8LIvv^f_`QI z5M@b{d`$h=hq7>q|TEqk+8M-{L`n9zKwsm*|p4C+RCs#zC@pqKR*g zas~ngI!J7evSP`Rhin)e`4gv-Y zl8u+-wWgQr02(JObr6t6WIhpQ*EQ9`w$Ze0n&h522$*AV3-UHoajxX99|SZS+*#9U zS=(W1i3dM+gk3ubxXIuagBWnO{a|W9KI$u^lJ_;xzGWQ72OXYwq#XMpi`F|9!Lgy6oo978y`7+Jd z%mLWCDBud6j;zn;0Jc%)g3ILH!>%acE<tC~+o=OckrfW0UatjNWfg$!eskDL$=%@quJvs1&zSdD$Z@^j0UXx3y)9#R7*7AeSa=%z-~!vX@I>S1fS$d|;pvIg34L<%P zH3Uc-qT7bc4zMIgCkAaDB+*lb0Q1jBLjcDG-J!4etA_wvdjtJe5a`)KPZh}(_0A!{ z9}G0NnQ*jgSI~w!h#rXW!FzBB@U8*m66ps5*dFA|k`jGGfFBGXNtBrFL8+r8WsQb=U zaX{w<(0*oF%lkolnXKhcalm{1@CEb~uj+Kr1dC+(lHyTLy>W)6r1x{QDR@PlM8`RS z{C>~@ea2a$g6pl4WsVc5HdqYn1-5)duq8yIuW$ml_k-@+f`Z_q`iOkY3A}Ov7HOh+ z!An|X1)n&9ANoP}ZNd8Bw3(7+Ks=BZubar<0{;z>X!O?LtXj!3B_8nh!@`?EKa%C9 z;8pdKWnDaQOFt||eUjz&;JuegmWShkgZ;4h@8pDHj|G3IH~-^!;Ol-^_=J*nFFn~g z5PW*0sK7cDNF1s+-0vHHTc!Oa6|fx&K0ZQlj2{YA^uyurK6_{kVEZJvXQg;tuwke^ zdDBQ1Hz@W+Wq|Gb;6wESb9XP3jCF-rmdIg8$)Aw=uxe0V92Lq z0QT8X;IyG6%@@dOpgUG)2pa&9uFRYOgeK@4xvbCW2}p8?Z?z;RCIG2^^40WcAR{Eg z0lY;UoXH8mOh1_dPPT%OJEq88;)(=dolf@KhU*J~E(zJ{mgrw40QVYbW3iLK#UYB{bFj)eZxq#IMFhEfbv{-+dCV|^rz?}xrs9IW-qX$|$^^SVd1spsd4FOED zCNnAaV;A5vfB}kj(1WyGYwKkaXmJBkZoTONigMso>x1(oFw+f8F@Sv)<>-0Vnlg!A z<_1=ukA?tNTfbf_f!o}`E&~{#XhAk$TWdY0-w;0P2KF1k07W_QYHMD+l=!|I@EO3q zigNT$>s{j|n!;dFiF*4DGz9QI>y~8_n3)I^8o&TWzmKDvYU|5Qz#^Iy79|4p2GBn@ zWl=QScF6kUCh@e4btD2e8bE51#GJJH+9l?9iNHPsV+adG_gKH%Akpt60$*PM?Pr#? z*hBxgS@MMr2cm`t8bM-GLmyiqF`2`GDF()`37Jfyr-pvsCeh1=1M4n;=FEtsSVB(t z27qjt`$-uPV+L~R#S8xb|*Xcp(8jfmPw zl#jb^6cDlY63TZC2mVP~&=mxwjZ^4(eQ=Vbh}9_n@hgFdjr>7Zv`!Kaxe!Sj4ZExr z7!H7XpiMrJ1@13aD*Iht(29El5o$njI?NfTE%auiqC(a`}!PFR`*Sa{4O zatz0hD!3eooY+$h+?oX3M^)2BL@PanBRJwXWD1qCXOe*Dbqt*JSS51iw0eM$?7bx5 z??koKP#b^FDT$&?1d$>R6J3vEt(_PU$J&-maV(Ok$Fb6r{c$X+ zM2}-_;dv3qx`F3K9P8c^!iYH5tFtLD;#mLY7!k+%j`DgO%b8-tv8Y}>jz#(Y<5+Kx z09>aDD&ttBw2WgZ{l>BAW9`rVaV+md@qnj21=y4V#7qf@V?Dn?5N}NZerphA94m7G z@JI@Y;Ej}VtPf%V>XDulz%oLYDdSi# z4HQJ@2w*B%J{KTe%0@s)=T!)djAOZG0o5abHNC_bajf(;z*QrFn|qV> zIM#I?LXihX0FUSpBaZdh96^0irwA2!GmSV_nNxuNIRf~KfJe!AdK_zXke~*o0`^oO z<|ExzjX2h$OGP77Q-Lgk2mvyVbyGUsahZ5xFT zI_R6@G}+jQJIQ2v9P8PIKv9}Lpot_buE()XOa)f-N0)J|C)A;%?{Y&aBJ&wic$J2oyd(r(m8*wa-3?B)kjMN)OlKjZP zicbmngpokG0XJMB5czL`tQ!fe>y6|~fza~@0lIM{pco*-GXjw?aXp_N3A|(=zxB6x zkf0wO37j7XL>UuLpHW|9BXtD@DugQ&T`H$E2Xa=y)z)-`CIM$JTG1stn zGJp?sj1k9r@N$603Hv$&_<_iL9@FDk2gXV60hxd!Q(DD{W7VWe?yO88pU9kBk7HG= z0{%h5=VSs43~oJ+b#5H+E|D8EfmT1ajALzxklZ(A0=N3PWgIJKyySi)6WHtLmT|1S zp;EQiGJ&`KWIc{mB*~{Tfq(hQGLA*>lyTKUvVe#zqhT_R_5LJDPRRl?{A3x&nmJoc zt897}FxyX-ajdiXl3bewT;?asIM#?VNxmivxWORnaja3P0J}E}c#KHo_x>?q#IZWF z0rpB3@K!I75y$%DYJi={0>04cMjVUcA~eXDDI2h6>rL0=Si`;K|Jgt)k&Nn%IF|EL zfE8u~Q+2u#$GUuzjAMDTfoemt9>=<~5O|C#z9JjAPABum8F4Ic1#mxMlx*M;y#|4i zajfm*q?m)*z?;3raL85Wgc>PD%?7^iEk%!G-Crd!p&oikU-x`LzRUbjqpT&>17s0d zc)pBdJu*yk&-4Iu{M<5*bz+|6uJ-_qer_4Z`l?Qj>uWv0PMurMGct~~dAh{>!2>*P zV8lEl<5;6MNz9ub;6no=<{25sTDnMLzVQI(42+yZL>%kAMu~Cc0InRp-}#cF$FVZ> zxoBJtFt-;*_$Oa3^*Gk=CrODbbAZbYw6Ru5pl0qVl)#-i!0ui^iHWovUoSCF=KzNc zjImNkV2tJEJPG_X2RLN_d0X{3*4t))b>{%qT)mybUOcu_U^%@-%5dib83sn!f@4Z7 znG+>udM;3IV8q)y2+C5k`jNL3p`|?1MJ1cZnAvdAb|&R zf!BKhrLY?<%|j&SWG?WXfeEk|7j~azdb0#ZjHx;=!wc(~^&%L00=k(mcfG3b1A z=9i|&u~rSG_kZ(%mA#R|)wsA57J7ilm$a>Uz)l0mr3o8z;Lnyh*%J7NJm8h{fr5qj zWC+O~bhS;ge3A!z)0-v0k}{4}H$kGq@`1Q~z42TVG0He_T+r}z3Czm}ihBe7RuJgf zL2(^&MXkyQ)*5JTGvR15j@4?CVsFd`?lOQ}qG%Qewg>IFLP~rpA9&FKl0+kpRWn&) zKFA0D*$X3pdK_zeGr-Q}1Ex{3#WH^IP*CdvsgQFN;L*u`g=GK8IM!<`CAwr3u<8P6 zKeMdm{h&d**{>P}?Cyszpr>RUtFTE{MRC{HF2EuyFa>X%Ez!qE0q6Qb2lSbYW4RI~ zi(@p9K3aDL<0d4qASnBqk-l9p!>F<8Vq1?z*y7D$#4Mg!mU!{Wao5{=#({LM_s5;g`%8gqW5c{9XF;C8wxIAOJ9DI5b_ z(hrMaFD7E6g`ghS*XC&_Jh&mSQG7X z>$PPp@N24?HWi|8jQWi@)(38YJv0`0(om9SP9u<Mv+~?Det0JGwL@j+H%Ml24BX zzV?%49BX$z@Eh7`g^mLTj59VkGLE&yDOF7!2NddLziqg_MjY#!Oo?7J4yZTK#$sp0 zvFd^(uwxu>ivjeTT#sXonJa-0j|27@K$<~i)iRE?biM?>GY;r7fB{v@I9A3a2|Pm$ z9S7XW$Zqm4M$(}N|jv;goLzyL*M z981$%w5|ZS)&K@5D&tr$7fOlu764Bfz`hohajZEy`i%nMlk?F=9BXQx6#IPv5LBqQ zKR{6#$GWBhppXVjCh1Sy5`dl>I%%Us z51$AWUI5LR5lOKG9>*eE@;DZKFU#XtJU|jfpIWg9@9Bv^-lXCS#IYWrSzN}k9-+L9 zV;!XYA0`5ilNNNP$FVr&m5IPxIz_BTfpM&V=p;RkMH&rL=o^>3N+6OtI_jxf9>@B8 zk`c!uTj+7Dut|E@rgt1Gagsld#qlzZ6;=Z*nFKUU0%GVQV*Df^g5Y`_i%Qv+Nx(Ha zMvr3!uLlUpc25HCBdR?hj`gesAYtrJlYo~Ds*GdNHzAz*!6e{QgGzBM>KTmPN^j}T z3O5%4<2F*hG<>|RH2hoAY`kq&I2j<4UXY2T-9_>XQ2?_)S6T#wZl40!U%Zn($x8_X z>@QK|E|fm5vLB$RW6nRT#Tz3?em0b|UDGcc8A`HICv!ILc*!g1<3Ri4&lzk_`D=Tc z-ary;&rrORv+*x9lJ6YF*}mzQjW&Fejogc~@dx4)b`=0gWj#f7#75)-3d{{I3BP^CIcxYOM$5I_mu-F z%Zq`i2|W9CB@i`f+*}~#jcg#Qh)Q$l>tgqi#Oa~W= zpf`En;7Qc?Y`BZ^MLdSgzw;YB*&hraJVgY<@0bA$E}KsHe@y|tn*zkp6$E7-r&y-~ zgQrSL#B5IfEio?Q!SE4Nfn1#|CKBho(ZJv(%mX|!1z@wL0t*Q;k2bRhDOfKc%a=HS zX9==qDzL$Tyu~3OQwwT7nKgPdYt&D48U>N#0QjV5)F07 z5z{R+HYU*scf4bIkYAAP9q*d%qKk~ht$^dGsjdNF#nXVf(|{PdLMA7DC`dKafF_+3 zv6|>v_rwAY)pT$=Fk~9Vf2ILD2(zA(-(3VazA!bd1X76n`)R-)KRIbW;P}e4&J1j( z%3qxZysp;(LH^EEJrdwwcb=RE{97l}Gaeu-i)#4U^gyW;VVw>{PS^DpWSHyeHj+LN z9Wfoq)yYx>eV5<}GC#0Nwqf>kU=d-c4H4n=Kb7WBA046Q8Ea)V&C`KRh8%%;h-?vI z{@5bxx@|geZyz~-A$13umkpG1{x}^V<8gCKIWLnOhk0(2l=Ja);PXCm)=UE&L(DVj z(L7mBn+^oc(CuzasyPMu;!PeD(qV1nCbVknZbIYD?eky$Y7(S~?3utQ9b>pjNP-kGcP6kzC--)f8)wNj zw9W*!5Qf?ikvAj2P0WR|n%~R>?(@sx80jXv8)RM2%>-WUBS*SP*9s};A2We3`pA)P z^5`@v$5aeN6!+Fgy2+_jfI5Pu6ayJLMz{(2fZt7`UZf4);PH2s^gCJ8imOl7e4`{M zYyXaK@D#D*6O;8`!tX8y?xRZSN}sGb<(XpOfKG{cw(n$pv>5nIC-<7HdqRLqiUIax zF<>eIVqT!hx|w#Qa)x0F&yjznvb{UV||TX?xFKVY+n|aJNqGGYYGvh-YR2&+8at6uwy{ zMI4<4e5R9okHRyXWgC8)1(;{cHbnfXBw!SNl_;x;pAC#43|U5E zBS+zr!=;?s*+6q2IdT-z(?j0u?X!W~`pA)^aN&A@I)d$)4Lqr1{99Q*3h6Eeh4ll3 zn|wLP?lTzTgjxpS%c8wHqwiF1SBb(RTO~$W~Z5TEONGA-nA>!EV05>TQm(@(21I#t# z2#j=-gN&A{evSlPWARX#9q7g7zLlP-r!6W#gZb6T3rox~`I`_?Lxn(U+ zc2Q!nd_I)k+MG*pQ&KoE`1M#|z!*BOq-em{Wwg->&0P#cdury=ebQp!j+pOHlmU)e zp+L+Jd@tr0)dIwveR%=-?i~7P^Bm=^j#}EYbyGgvaV@Q4J(RaQ*3(;+8s($hbLg{X zFuI6!|F{r{Vf-TA-9lR*6Tfh|*U_sF7JiZBe!Cfn3E~&2?irT?F~R&I!)>DrD{HF+ zJnnzd*F|A$V2kX<^nU^89_iyEbFKQX1X`ic^vWVmP(-5?I8ilY|%2H+}+^?VzLQX zFj48JR7yW6wvf-2Tu!P5o6Yk8`WL}}NUV+uoyW&P!C0UqBo}c0$OX}1gb_p&xDtg( z5oY3?L8bghR#Z9 zf-=HZCBGr-)^avF)zEL<2s%^^C0mL91gFzkkmu3IkX~y!olZmSqn8vyyGG}J4x%^t z{klo|M^gc3Bd60*ih?fcrvo{hf8r!MZ!(ai)&R~{Zf=_GBKQyYO4+qEDoT%}0M6ay z*>pms(2vZ5(*2tN=kLfJ>Cj5QQYbBH1DpqlLg!cpQqriow~;hD+A>huAJYKmIqDHQ z?J|I;q}2^LFEJCT$zU?NE`rKXY-z6mA~#k5bK2J+BmP=CEYsmM0rA(9B5>ps0P))? zZ*kC(kMTE9-s*U6IuL&&<-;ALN`UyAC~tSXGaHD%netJNm}x-#4$8+ms)~U4Ur|2Z zL7!X1-$HqpV?r|!|7+ScB{_24K>Tgwsi`P=cPQW-#_dc;cS`GB-T^r8B}>pjo_$EZB+~((esf4N9TMdH4RO=KpMAMYrp_SYyvqBC&byZ9xZPy`Qa6^+c|cBZ zD4iPWuL&h;G~hhQ=<(a928nVgwouh2^!>Z@HAYYP=!{Xp%K;_-AyOP87@a#BprN3j zA^K59=Ar{h{j73E+wTONe`oaQlujz`OD|nPMm1@>V=tG9kG|cIAXsV#|5hb*` zgC>I|d@#~!s=WSLD7l)7uja*cx~eRmyNjm7WAsZMMF*}5g-IanWI1OrHz1MeAXa~S zFn3lv&Fu6`R63tEkok}Ua1LaY5Sh+x4PdrcEe4zgj1nT#6Kg-WY)eH2;C!9YlT|wA zRnSG>9H{PPp1PzlW3O{`n44pnjB5pKhFh* zrqGB8o!|zBjwJb^Ul7(ao=X2s*c{p^g}zGIJlZ~ljwkGRsw?zFB`|a{m%F0@7&?W^ zbqoWBQX~(de;y4CE#`8M6SkDgy_v9cxZEhh&gF7nCF}w&w_-Cebg9s{02sQ03!7mB zhF0-x`BGqL4VSxsuq%bWgk8ghO($#<&z2Fkh09gTfT8rh8$wS~b}I*bF#s5PBNujx zvNsdfWU~KZBT#0cLr}{sbZBg`{1qj1FsjL7Hx&_?&eklmP_&>}{)!ShZ?o7!CnpwL z=;X^X{#(w*0P}cpnI!JA66BvtfceRpw1Z6;MJFganruMAIGSzXXvhK*##7$n=$r^7 z6j9#l*fj!3m_hk)M?oBrFq86j$7RG@O!+8B9r2b>KGtzJ@y?=ryd!@lkT9F_F2|k8 zKtd_ylN|3jfP^`;UZpzzM)|pvPjh^^8AvFne7fTwi-CmslppC>KMhEzpnQhoR5MLc zl+Sd~-Alr9%4a#&E&~!SrF^#I6v?TgyvOko$*G}yj-!?2)KNayagyY$qyik1PPOGeY-{p21~t?ufHs{lH;((z3?;I5%!RJ7KufxDLS7KBb(1-R=P zmvQ`M!v_L%z@@-b$X3TUQr?2lq=A5Y&E15zyVrZoA~YoMmy=#n{szih5xU$AxHrDB z46xnV2)I8tS?R=COQaWANIK9#n*4c|c&Js95eK+K_`ElkNc4kZ%S11*$o?)=Td`i(*#{ljaGnti6{fwZR z`438VW&`d@zQw1LKske)NuQVwxG&@T8#*0StQyAV86`2R0e3ZLrDH?;(ihLD0o>gt zI!lxvL)*6mG{K;B2%UcU02%lw6>?Q5 zhhhsgxbz^=|45Ca!%6*gA-uF~4B&pAR&F}9v@f~DI~j1l$$OnnGv#!YctH|m@%@nt!FlRvAvNW6e`X2I6ihPQyO7BPl-0x5! z#X(f z{qz{Y;+RLLBl3Ns6~&e*bpLOm8*+X}OpgQj9Wj+osFbA->ZKzP`p}g?bQ#?$g#KIs zL^qL+i$f;>(c{f;QZwiW#TI%5Q(8O*i2jO30G$#mNF^^@f#?F>GjwRIENz_)L{H?U zbcU=bEj4WhqQ4~pbfT<;emfC}9?Ttr4w#jtOJ@Pm30%NZy)=SyD7MhSwI!cLlfHZi z(n++!V@R|VFsd1dwlmV7j;Iwq#pl|R*BwCgt0vl%(Xq9CM-6Xs35x-uqd7kvYU}6M z$T@FMK=M8WgbjqRF;;sTBc`N9YhUjliG??g=Tq*lMWRfT@ zn-0wtrL%{v1ES-2>Ea<7K=fQQ9il55Rhm@-L_bM&(~-Kea7Gjm{WKNQ0lWS-U~$oK zAo@oW9k?sRFFs1DlrlPdS2TtOJ4&Xk1ft9NTtVmY`bomrd}q5LY%CD{3K_2S=lMYN zJH$%|_DUg_l1IJBRi}_}KtB~*=u`D#3mse=N!c=9P{s?2EfiTUvrx#sSpL#i<7F25 zfW6p4XY&?Ya(JFTA1}7h9a)+DrSf^ayi8Il08(tBZ;K--TgD5@ctNp+;v!`h3OE(Z zUwW~p%tG%N60-;zJWtQYi!JnyQkndv@_D?xOj7BcmtqTjE>&!yS6_-P_99>g z&9LqoU@3}*526szGD~vtJF5WiSAtCv2R4)uwYk)ZKKk3<-ch@Q) z-WxFl80vj@3XtHf7zqsX&PxDX-U6Bgy<^*GwO{51hI@ZV2a>$r8X(!LnSm7V%wS-I zw|Wzh>YZu@(!BIPrb+icIS?4>y=54X;Z0u;WO_FZ2C}^EF+jHWkCOq9_pvoVj(5;l zAlFMXQ=a#UCLrJY)nZ_jx2GN$?VY{~7~`Fp35@kdHv;3lljt=juOktd;H{_z3cQJ# z^gE^%DD+;R22AwsTM10^-dY44fOo=D;AME}PJJa0p)d$njNp?eV~$ z;a$26_zS!bT7bjw{xlJI4c>xzz+d5wTME1m@3K(f4R{Y_0B^!Os10}v-ioQf+wlHw z1N~okyip^7ci??E40spbgKpqGc+)omN8z1Y4Ezn=&({I(!@D63_yFEyH}E06on^q^ z;k_ae_z2$LUIKg!F9mu(fp_L2;8S?VEdu@l?-Q}WXYkgUfn)G~mkD&iOLvjS;T@I? zoPakg88`{=lomjRH=+*s9Nwju1OJ3~`K7=qct^GZU%)#xlKzL=-scwpK6rmz2Yddt~2idBu$$VEm{7N9o3c_$91BJ6exZxO|91bIcqjfx7{{r(Jj8^)aBEY+}(qHZd_+hQYVgNs)l~BF+Zmsm>IKZ=7>E1g4{+(9R?*({|R?5Z! zepD;XTnq4HTB&gY;JsSuK?mT+wUYi2z;jwD^Me4FwNmCbfS=Gx#V){4YNbPa0iM@N zUrYo1lvaAvMS!2yO7D9kz|Ux9lKLPN9R(i1ou%(rr z)&PD^E4}XyfcI&o7xMrwY9&;}yb$}0OrCmjU4{D{&I{${Hj*EYZKr@TIttb2k>iJ z3FZJktd-8!0Y0LYKDZm;qgv@*?*RC9t@Ni!fZxzcPp$#{rdE3W;{YGiN`LYIz{j=H zP3r)^rIqj|jQ^ySzRdt$(n|l(0{CsM^kX*z{Ek-o@l}9NXrf5x^+)V(V z(Ml^10{mC4blVdE|3@pm@DC{Vtw)EB)peF4p(l2oQs7&%^;@`*6d(_R8G=u?hV7$WUxKX9FZGfYS2| znDvWzsH=1vW-2{+E$S?;U9kaT`CS(773k(=aR`lM7l%-}mK!Qs0OM#Qu{eY@kfX)7Vk9c;7Kgq;k@$FV2$giXp6n zWA>Nm^Yt`s?ErKQm9};FI>4h<#|7;)Ztk(mjYl230@`WhsbZJc3_QfkGsP}f(S!mz z08sfL?r3vZR_t=8(nLqGDIRhG*li|&mXS5#MOWI^bE+m1?^R8io|-6=tO<>Zcuf!X z)Rb2>Rhz~pXm7>gzz<%frEPr*Ym$#+m)%D%i6pVh9WYBcu(x5Q^3pAB>u)hfxzmBz zZAb{Q%PyF|(E*6vh3Vv_T-w$R7i7A-RJ#9{28f-&bn?bGJSeOX=#r)@zCz(_dwkhjg{y(mH*sDJx5fY>+X^>Nx(N#*#a z%t1Z%Os_ zys=K(inRgOiAWA;qDL;!+&iF&F1bKWI-v13HP(r04v_E@yS%nu!RzT{5Y~x`WN_#L zk&z6Jg7vLYfS9YvoAR`+A650cqW%W2-xc+*@d{m0VU^b)gOBpoxuSKzE0nQA<&WN^ z!TU!58Z_NGyhC%?x@j*!Y%C`4>eIIVUbSQ_#(P4vWGu#eLbPOzM7Ef0i3~oL&d}{mo6+lK|#cmVwcaA@47>SZ)*T88kXatF>Z@G zepb}pX;DwhV57koOxe`(kvlYaKLE5Wh@F-##w)e2eFMPFA4H_2^MO+UvAsxn!||7= zV^BdK$g#7yqz=bFjSqeum#c?x;Tw*Bb~*-+;Q@eQyk!h*yfF4%7XY4o^2sMRoqQ7D z(c1v8rhKRS&q;v)G6HaS_ue^xKdu5yYuz8514!uj)BebH0N>gR@J{>U8vs5t3h++H z90T~p6yP0~cetG~fEy75-gx^M!22oy&f&WO9{B-^zuuj_8(?}9<5PD7{4U;`sqNL? zFurdrKK{D#)m!#zd+=56g0Zpt#^U1uaq)8$VCaMvA3ZsC?-+WeAKnM?@v$)s0*su1 z_&EQ0%_!iH{rdn$>E|&1y!K|1AiWRZx_z3+I*cWaiMU~m+clxRY(hH~qPu5@0iiTjS|{Jjot^F8Ofp1ia-|e@cKG`qKgIJE8HWV^ufCWXmXc({9!3 z*)hDYOSWwc>!{pX-G`ZO!S+qx3b5ac$F}p>Tm26)8-IM8_c*<8YD_+Uo%a~u&WkwU zkMJIUpZ_sWFPnAy_9%4re@6`BU?(ypJdh3n;hhA^JY5QY^dzwCWKeJG!rr5@;)s-%3FZJte3)D zCUSd3MJx9Lu5Ay_iEtio)h#G`qCx?RyMeEFd}6HLBpQAeZzFz4b*XCWIaTK{@8R=u z-T*v&C&6>RPAT03@$mz@0p2#$v*S~F)M8dZBmVCYG_#fblKQ;{uRHKbQTGa85_&EaL zil1WuUGZ}mV1xezfIqzs1@bqe-dp>Z@!g)Vyt+Hv`moP0BJgdyzaOS zX1S(~8CcnHOy*wdn4*o9PKSa$4e!`y)vQ@9v&z~Xk+5Z6Wd3?b09xIqXqu{9 z{FSl4+7oMV4M4*x%b$*0HEe9)D8Q+5*J`+jtroh}!^ z#U4O=_L0fhC}`SH42ENfA;oXgo~|#|Gn27#`4}Oi_+8r`BSI8EL64Wjf0@bH%`z8) zL-8+y_H^B=0HL7xU*NO)Wb8Vb5<#B${{(FfVngvd{_}Ix$lA#Jy{w4t#QzSoXO=$U z$QC8O2^1 z!GCsP#BO{xj=?<`+%s||wnw%b;g|Tcns%j*E!ReBBlY@HJ$uZ_VLD_gjW#V7fv={4>^=Fp6u|n)6{!Qwf$@()H z*#+`Nh9*Xy5#7}DX#2Bwsn_CUJu&jb+n!iU9(5uv6aSeQQYTIwB7a0-;#)E8O1-|+ zpP8o0)A%n&@qe%tB1oh4YBR~~ygNm^@nJwkGS85x^53-5t7+)fUaz5($1 zg?>$@M_(ViUk)t7Tk)^Qv@2?!F4gN9Z-_aykKnAzT)FZEJ|CB9QOnSi`dX%buq z-d}1l=EnCtIrKyEr(#cQbL0EpGxFZyxm{y77I*F5KljIfG`?r<4?gw#FQW`0+a+}v zzH*EHa-{}iaJi3eD;KpT_>uaHx$#}k#MOuuckSNg)h+c9zPe*s-|-WMPLzoHE?jfBbl zX-aY4PMJmm*uDMrE$T0sM#9hjaz;g6?BQ&|O(cA5eR|%}rOK*tICn4R;C%=01J-SI9kV(`ttqCL^?YHc z_pY=%m%R68HLGE^+L(ALRIvN`=wUm`>3M70cv&=F zmab2;yxB=iu>v!j9rqHm&5phSZj(7?1sH1@o2+WpE!RmL;eEK6*OT+CkUXQaGppHD zF`dg6C}vePxOUO1@|Q@lOftK`3acwCxqLA~bA05(n;t-FC)hGG9LK7+aM;%89V|a| zu#VDT)hxSrw1TNRag-Gp5(o{FBgv$2jKRFVQe0$3>VkRwY&xa0bPkR;8dYn9x%7C7 zrPx_LUr6V&*u)cz)mvRw+1yMV-!?DOEAviBWAqLV(HWL|D68k$N_rmJU00Duz*wK? zbe%O;HYykNd5c;$mtuufGNTinMd-b0+iX?!DCH)@@OhnsH0Ib5}jhFNh>*IV6#hwJrf`QYK)k%NaFw~CJr9ZFm} zc(_*UwkinO9Cl3l>l{2>!^WyG^>`t9R-b3-`9d!&;w`SAXjsuvF`v#ZNJ0u(brf}k zP6k{jb-ggdaLwe@kWbVDh$JbP6T}{wpdY-7jYv#adk6S|UQmt1_B<*Epn>AdEWa9%!Yx}xoQANjC zf0K^(;9oeIjvLjgZ90yg7ad>Fmy;`txx8LLuAo(Ec4$2G2UpW)St^q(6!_>f4!1Ja zF>vGkUi5H&sW8Q$=GzqmI$^riX*)V}t(J=n2dwIBF zPo>YKQ^0BsqwYXzIXADf#pE)lQ@&I3KcZ_2DVEXC>Y1Y~l}s(_tdM?KS0mbOxyUE= zfR2iOPgUF9a>Kk26w=9&SelYYrxYKBGqYW*;m#Af_tUmd?3dlGxcd6Mm0v0(7&xx& zwyQuftkbqyu4!*?89uI?_9?67-p8{@=cb5W`T9n zWmU7|t|8V9&321b&5DH#F!d*}M!Rw$!Vt;sLVnKj)|8cn{0dG&x7}!9DZaI3`$SG0 z@j3+er1kA%DObr;^y5BgcQ~AWu-wM}Eu>gB!?MVX_HVoXEup6!gIJpgYg{LzTL^Dk zV4EAJ?U)MMKc%*ulP9;aP5skgCvgHtX$NrvqXvr;6ocZ#!TYdjL~wlVTghcId@+o) z93#mPOAxZsOE&9b#c?_<>i@GdES*_7I>mBl&K#vxb!jIq=%}|)%_R$Jj|-Rr(f7EX z?U>6inOt^(&EZzeI&EU{LMBcpgUk+RG*X#dYKax}j82jS%%3cg^06e9k0q{rEJ@{K z>8#~+jmE;#wT z{2}Il=)GSJ*1Xv_x*gf-w;&2G1lJY`P@z3p)y!hzTkVp6zPhY!-Un01_y)z204 z$;CM($Sj~B~ z%XAaR80)c8NF416;=tBTf5!%lVB#opbqZ!!>$LMlr`I^2*fT*zs^>Sj#07POZYa+tZF*0-6qL0j3gy+xXdia zx7&piS^sPlNTn2w5-iPSBh{DN)*xs58iW9o!YOH=f?C~lse@3KAzr!0|6JgI8rW;? zj*0x0Cj~L1yU93QoXxO;UPPuB-^w?jgIL>e>7Bz#H1ktzE}fkR!U)wU1yJ5JVRjq1 zr!&O*tcKd$0_F^j(9{wClx2?FwvD>UnZnTNVH9xJIKpVzTgj($`E>C-?nnCkY9^gs z;M-Gy<@J?}M1Dg0X(@c;BY0CvAa7E?4pD7WjCRAKo?limhXooXa0fnv!a62#gd-`0 z)bWK~F31;~X45fURsLx;MgfKPleLs13n_M{a6U_WM96+EXEq7F1KCDg;&zm6Fmeak z2BQYcHWb5ECCF+Jd&B0F#UzOiovzCb!wlElv|J3cYRB4yO4qi{R^<|NE;Y+SL?i|& zSuEz$bE`$2^ei4ROigctHUxl>w)A5J%<0gv%!+x@a!lWR=(d$T?uwGS5- znxgZ|nOts#W*RMMT@wDoR_cC4od856dq^Z0YnC0?a81$A3wm+oA(kg#it6dMP{CqW z52AJ|N{=UIi2WdKnBYEWg^vQM%-CwQ!dKh~U_#RpEcEh&EVrU(joNPx;ox)L8 zI2wsl@hI+M#o4UcP3*L=iT~CL(Mf2#-qB}{3@T|7%Ze0vdIkBSO@C{d>jHPsR}7}_PB=_ z&7~J2v@AvlNh!>Cir$$|n#GV**7Dwl!kK)xgoVjidb z%62`!#9K+g{FGqiQOf4vd?CeFq-w)$vd7yklc;27n#+#9xw9R5os~c|0=OGEKWk{` z3(iHOgZ&V;bn`91$4Z<%&N3@A(})7jOjGA(1ty-$7g#EnJtMm}Xk)?Z^*o7Q%Z$`K zHE5P?Tsw&D2#$+T&{g1u0(mQ>*g0B}&!tus--Rob)vB7P2N?i8IQmhuU6X4;DDzs` zC}Y}XW<^9~LiKNiO{0iR&LW(Wx%eXK^=`yxV(h`4-0o17^U0QazkqE2U zroputK61M{F@(cPp;G1!*b%9Q8vLbksXv>{tSUGvR7MJ4>T$#7bwpxq`gAwMXy71( z%_{+Aiizd8)pnOJ0)i-47Pttgf=6kXRd6~=C4G&PvseLz9oME(^LjFaJBeEETV~yG ztqqeQ>!oT6n9z!51O_VLSs$$oSejlH%F1O)giCf{BXrU#4Y2V-7<)&NqSi-b|ob0pv{Gqii7@ld+PbPg4cMLiW|EtK*BA7;hv28oAfRu#fqsI z&t=nZIM&cAE?PA0Cnd6w;G8#)hdhlwp`ruLuxI_iFX+QPoJ?m*{hft*%57Td#t<&laXxnvfZ? z+B?C>^u=9kcO9cub(mvz2$#R;VDE5o5gRIb5xL+5$%blsLCpVRWvxsvb#AV3tXJOc z8YXiqPQz!K5m2l!JdQA5@y(zgJG%gGokxm9p$#5Yldh1Qk8ozyP`mDP6 zp@XoY_W{tTy4anNZcCmEFGF<$9CHnE0Gosq#guQkPA+=TdrZXxW?MQiVR|}!?_&aM60ZMdWN8W-L8!f z6-|0php_Hfgc!c*zPin$FvEbg(5pm`Jpt~B4XbIn1C1L&khMgT&EO#yplGmV ztJ?T`;DmtnP8`1x2IIhzo_hl9y$~icoH|Im(0}|3d*nVJU@rmLur<(AGF8n=1J7IC zBaDIGNOO!J*17ZoVyuXp({4#Igb*jBIIJMzTBXr;Ob%NKja=9phco90gh?IvTi+Ie z29+SDK(LTe_MyOTv%_r)NHcLJmoKvXDmOPv&Yw*ea{2QtojsG|`(U$-W)kn91 z6!nMFtulrkJl8B8q!3EY5U0cBsR5Qp-BcqIjxc4o`Z^}ZVe(_-!90}QcCj1DT2UF# zMG&~XdBRwQA5I9D(xv5c_?o#RZsk*@2k;34w$-SFzwNXm;VP!BjIW{)2c57KV2%(# zl|s-#6Sn8I8IdN-K!|Cb?-Y1a15IAQv5iP}x)Bf#QVT_x8-qz!&`?$^ zVA9+yq=&6d1l+^t<4$!(!KWo5pr9n_CWww-rAa3jC#E<`;+e~nK_botp(J(wEtJbvFo4@+m#W4k+WZQrO(*JZmK{7q#32-Z4x8Hv zQ94A@a)mTYWr_ttq4|M$t~8ZY7_cwM)iji1xaq*W15fl=1Oq=b5z*TLr(x8gpju3t z)S#v2CC4?RnEpf+9TcxYy@V&q(X9fVNHq#uUfU5iPnTduP&FhpvL%5qI6svix3uUE6D|6 zxzV#~YzI*KY%{{?n%*N!2dX$$Y4y@;FB^*A_N!$=GjI~@)go?0hY*q579Kz7Xz)7D z+KV)6@f;}$Rj63)TmlZf!iM87y&nX#^y9)`g`Qtp_l^ai_KdWfEmm<@$2Kcw)l}$C zz)(vbHi|)DH2Z=G^tD}YCyqRM`%utXb93-n^K_1tyEXp_iGWp|pOUkn-Ka{2A5Aq0 zt3gJLhA6yK!u!NKRZb>JA(PqfLxQa9Z9IiT1L^h6KoBSb+)A7D6Fn!<5f!mbw8-<$ zjs^6Z*n|bb_FZX_+JXa!G&;kpoCFAl*E0v98NyHAWOMoDWQG=Kj`*eW=U1W_Atcb+ z-#g}rokxbgq$r87#6^D(wI9*A&Wa-fi{}e`0p?nGz%%pTn`(u+dBFOUNSKfL&!?^X z^bG++DA`vj_Hd>OS37<{(l!Y#$EnvAW^$x_PiMhbUzEj#uh@d|MV^756AhosQDhN1 z%Y+tbxoobO%cfKOh%M2Q4=5q%k<=4(K%KG5rr|p&#hI>9PLIC{X#^~%({{w>PJDK> zv%nnK`0l*BwJ9{^gmusx_xc|acu}vakRPTFS@k4w2#BGOVym9%MYt3u&(+nGVm(B> zQ}b}0>?(W*E@{DN8ukU#rtP#tMq+sKx<&jpT8M-X+^feBXqppNIT0h z0;jyB0ec_K#%+8yx%Hy{F0AD8$@z4O74-aBJs-`{_oV-nJ$Z|cLhr<$`_xX)_rzJw4<;_km$gIw7( zJk?_WZTB(cNLse(n6@<8OfT!XRnP7%pub<$QR?kynK*ku^GVRlk}h2UNFyS78dzzF zB9IV)2!1a%gfJ6+9H!9Pk%A&2g!1GFwmzF-Mg1HddFAKklnUz5p(rmgEe}(MZ;8DY z*t7$n1yA4MhQdnnp)5Fdg>0v!KJ3tG%8*)2XXbkV(|}?3A9Qw`otDADneF21RKxAD zQt40O_yt_90P9a;DSjc3E|m~Hr6b;Q{sz#wZ{rvGGTa+^&-iqb`1GM%exCbX;Y@y~ z(TyTcOYYNmkRNv!btWm9O669wMPX(*;N7+zpIHaxSCA_R@q9oi?-&)qp5Z4pxkpj8 z=Ew>HM!b{Zla=0WE}74#(fQ{Iw!mtgw!=ZsZLjCZ@y8v8Y}9PqxCH!sUW7`?o*Z-L zxilRH8v9KuUVKTf%!5%aop1XnUg`SWRbzsjz?{NZt(JQH%m@M{4pN zK1{_4OO!?K3x$XD>>^7iX35EA2!q?n>|mf^MdBsJdC7Hj`YBh1!>7HU!v8}sOQ-fe zw4GXJ(h~wX7U4#PtK{2=R5FO`onO)C@u&}~!*g>F=qcQA@O*drj5^g8Ft@kq9o2|S zt5bF2jQ8hiHch?$+L>X{6zK}QZPb4K$n=)F)G~fbtRpa1qQbsXN^o5u)^@Fw|RVWn{2J! zwFjE;*bV1d{V1JUxFPD)ra}GAJKJKi%&Wo zG_RxRCJ11w3VHM38ObCplT)q%f=Ju5 zF%XvKuf0bJuchk(Xov2f?w5LUFp-QQ!Wp{)#88Il{mP_paSywpwMIfrqs z$*}86{)^DhJ=7k+toYH4karE=ySNjN@Hsh%HQ`Gh(bX!KRMNS#5k??Vt2}o(0bREv zf|3?@!*MDL-U9@3DXwq`X0o{M;xVUfEB`9e0)+ZuF2&~4!qrGP{h&Swt)LkCc8|Vk z@8sW$c<*KhE>=iEi|-!tI*DoDNm`@3DRd8vZEz3xp|5b2k_9Og1knWyFX06Py$^Fk z@Se#Yq@1q~R?Zhv+_M<6t9W$Gacy~YENtEB*A2+I5WUAx&Ew&q0lk3mJ{=MuJS4o= z6i*XA{vKWuz5@8&;_kR`ORd+d=!eiX%u}DwFgiyO+Q-|RoIB#wk~p?`uBe2*e2A} z>^;#DycX`@4oLLhG4Fm8Yz#kmF2_2cDL%7uX{pu+Y%V{@8D{FraNaGv*ND+DT=rPk zs$5{?$nMoMawNI$WM1^f)EH@sIXdMf97Q~YceU8pwje5yRO$Prt*sU(v; z?;$Zg)b<*hqio^=7J4;3_)!^z*tzc@bc|2aYdaDsj)-&R3;Dxa(9e15Z&FgB)4Ys6 zual>_Ngqm(d-SGk7#h`uUdLtH>QMUjKkLW6WyR z=+3;5y+P4N*zAz&@(e=;*}GMRDnm!Eb<;Il8{DY`URcNd>V5aCA3S>etXjwn4`)#5 z1QD&X{FWb@9l^|*#2O=1j#gU{#fw3^FA2jE%@dapAjhZt74b6!aGcw&;yoaJe!#Ah z+X}fK<2CbK_)_}0l|0Mp1<#9;P!M?DWcVt9X4vf-qOg>&kY0FjRTr-B&_13n;z3>D zJX>B^=GOsA-=aRpmtpIbUvbmt!_zZV3|J`$_m_7fT7I8Q0SjCoZWhUGq(>0FSaEDp z^vNYw-fyKe*d8ZAXH@9Etf_&UfM+~`R~4Zij{GZh`IlES#k6w8)(=Ga90K7rXbMci_0rGbAFWy&`lhGO3?N9) zG&+QUJdB5tD{o0C0k6FsZA`5hHea>4Dk-BcBva?Y{96 zW3^4mS#?~Y;|v)pX$coHLtfoUQR*yVt0bJ5()GirqnFnhL#@{6I%Jjc+ShD?CJDyE zGxnr!9NcZ&P1F2$+mWa8W#3Vhc6r^bxZAPts!i@HIHZ}hPR!b?Qday`(TYa6HkLisHLA?Tm8*q*in*_Z`=2^qsvLOHcbtlSQt5H2{Re?flhO-6})k`hsQj`C6Z61SniCXPePk`AlVVez1&wq3p zE=-Vff(aM>b4}E&mIV`bn+{PlK?C zV>GP_Ow`*hOq3l5CMxY_6P?{tX@=|CR=Mk%4ouKRM$E8{R^1B{v?8O*W!v14A-v33 z{uWK)CD7aRpQ5ZmpJ|PcM4V^{U`2&vl)R(DaSA`L!b24PoC*(9__>%YZ-l~+$7T2$ zo?nGWDg1dAzLvsYQsL_;eB+SJKStq$D!hxr?@;006#kf?tT>EQ_>(GpJ%vwA$@2D4 z_$w;Bm%^JzW&8~ke#cSX4{_K>;U`u2MhZWp!Z%U)-70)Dg`b<2`EQ}{ODepd!txV` zTjfvs#NoES@ay`*2l~R_*B8FMFMLN|_+Vf7PC)_uGX!7#&Rc!-01$&m091bi>;{aN z{Rgm@!XFajf$@f~1}qQrzvPSmgfAQu<$c~4kLl(31B_8vjxWGCe0D(j2ULEZ{w1~2 zjKlZyp`{PD=dcE9{4}_U%Kvkfe>a@eK!s)dU|1Hio6_&{g>xFHuuMPei^unw_l3)v z7nbSQeDRwaz$d3;Vs+n7{VVAY;70fn4OCcz8>#$;FaL)%P+?jAmMtBlT@SA=0Py6Eg>&N`KQ_K9d7!Tj?%kTQ)2j#~dUgp0T0}7XX`CswH zV}7|l0_+)B9&!q@ydRDMh39?c-8kySV|j~eJb8H_)>k>c$Z^Q>eli9WKIJPfOLq>t+~_?(8THJ@J}8}s6^yl48# zyQi-_(diUWo3@r}p+yLW&R3TA zQ*og1=8)Ha2X6A>vAmc2%3J9x4>@RA-fzZ%!l$nB$~$+!i^uX_=_~JCUwO!h%ksVu z2MXUG^U8bWb}t^w`$AuNkM@;^9K9?L)4y5mx19dI)R%wFmmkw}E(||+z*jhnNgv5C zc#;Ay?*qQ_aee%#FWkSsWBHPw1GoXc9rwZ-+(7k9{te(JxNfMIAMk&$JvR@5;^#ED z1>QUaik}164=0BJUh(Y*bA91#U;2mp;>{s%Kga!eqc8sLL*D+3@$c;^?-ux}AyE9M z1~*gxNPZb$7rpNh#oz3r_-SAGeVnDI4|2aB8RGqmk8gn8@OxOlNRQ#q^rio6Ul_T| zf9wm741?m|Zh&#v#YG1CVETLd!gIqw`~?=X7xqJL*z51Tv0LD+!$9;=745s=%a84U zqA&d8BEKx}=lkM6-WUFpVIcZG731&!XTu&pdIQQMm6MasC8u7gOxlLiDVw%^X|im! zCMPB)4ZC@`VYRxOhwH7bX_T$C8m6_|ZFjQk*pm&bJTOhgb`ukAxT^|x8Q-Jwt%){N zj7Ec9M2q8E>w8p93#+kR$L-c?6R4ekAeCpCbfL%?R88BgTaIhm%x&_kd>k0?h@r>2 zdZS%78m#KJZHJD7Ax7UYU9&oI;>Zy^HZ&j+L+PE%;LL2f_9YfZUSzn-@v7Nz*HE;^BZ8U4>~^CB9zp)em5UvEcHFzXIg^;)=FT^hNT7v`c)l`= zwie>ZWhQY1qqxUBD(ghMD;(&dF;0d`TUn|+j)7z3Sa^lp2V`a_pyCpPTO!W2z?<2EOJB+k4(MA_nXY$Eqo$1+m#sqPT z-wT=CTrz_m#0z?n6_axr9aEGY2UT>oOXYDjy&iy2FieLy+lmG~D2&`L6TWnazjZW#yL^q2=}_+a#&^Ec#_|xCdtL*Q zo#Zx#>F}E+^n|w$@j8?bUIrk94%>!lkPkZxKqw!UhdADIF@V4I)hpiv`L6GXdJ*4y zJdWHCsCqF!elGyPzsmN-HF!P_B)cLqi1G409tR-w51%0(`1v?*kN-UoEqq#}n*$)6 z@Jn%kBcfhJ1F<|z_oHGwupY#ZZX81H$NR{7f5ev#`J{tGK(eCzU^@K%gfAWPKkpa< znDxPJvb>-5r9+(RV|ViQ$d63-K9LUJ7x9u$-U;xe#|W!*zvN4Ya`~w#fRD+-eEs+9 zJYDB0fyaGi3gF#@!10f)7v)Szr^pv?9`)+-m-iV$*ElU8KJ<J|`22 zvhahVmOtG!GXQUU%u6Wa-qe?_`pW=!aX6hmGTm%nx_5sV;LkXW-ji;=FJ1Mw0cLw- zFaCK@q?7%!^+|v~e5Z&M?}2rf`pT=F(rA5=AK5-c*nQQ&-KRBJmyy1H!ACeZ8+U&%$oSKj{zus?Kz literal 0 HcmV?d00001 diff --git a/VisualGDB/genblitter/Readme.txt b/VisualGDB/genblitter/Readme.txt new file mode 100644 index 00000000..85dd819a --- /dev/null +++ b/VisualGDB/genblitter/Readme.txt @@ -0,0 +1,17 @@ +This tool generates the following files: +- blit.h +- blitfunc.cpp +- blitfunc.h +- blittable.cpp + +To use it, compile it for the target platform, then execute it there as follows: + +genblitter.exe i > blit.h + +genblitter.exe f > blitfunc.cpp + +genblitter.exe h > blitfunc.h + +genblitter.exe t > blittable.cpp + +Copy the resulting files back in the "src" directory of Amiberry \ No newline at end of file diff --git a/VisualGDB/genblitter/genblitter-Debug.vgdbsettings b/VisualGDB/genblitter/genblitter-Debug.vgdbsettings new file mode 100644 index 00000000..be31e6ea --- /dev/null +++ b/VisualGDB/genblitter/genblitter-Debug.vgdbsettings @@ -0,0 +1,154 @@ + + + Debug + + + + MinGWUnixSlash + + + 192.168.1.152 + SSH + pi + + false + false + false + false + false + $(ProjectDir) + + + + Raspberry PI + com.visualgdb.raspberry_pi + C:\SysGCC\raspberry + false + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-gcc.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-g++.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-gdb.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-ar.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-objcopy.exe + C:\SysGCC\raspberry\bin\make.exe + + C:\SysGCC\raspberry\bin + + true + false + + + MinGWUnixSlash + + + genblitter.vcxproj + + + + LANG + en_US.UTF-8 + + + PATH + C:\SysGCC\raspberry\bin;%PATH% + + + + + 1 + + + + + + false + false + false + false + false + false + false + false + false + + false + false + false + false + false + false + true + false + None + false + false + main + true + false + false + false + + + + + + LANG + en_US.UTF-8 + + + PATH + C:\SysGCC\raspberry\bin;%PATH% + + + + + $(TargetPath) + 2000 + + + false + /home/pi/projects//$(TargetFileName) + Local + false + false + Auto + true + false + + + + + + + + + + + + + Default + + + + true + + + + + False + + + + + true + + Enabled + true + true + true + + + + + + VisualGDB\VisualGDBCache + \ No newline at end of file diff --git a/VisualGDB/genblitter/genblitter-Release.vgdbsettings b/VisualGDB/genblitter/genblitter-Release.vgdbsettings new file mode 100644 index 00000000..d05d7a56 --- /dev/null +++ b/VisualGDB/genblitter/genblitter-Release.vgdbsettings @@ -0,0 +1,142 @@ + + + Release + + + + MinGWUnixSlash + + + 192.168.1.152 + SSH + pi + + false + false + false + false + false + $(ProjectDir) + + + + Raspberry PI + com.visualgdb.raspberry_pi + C:\SysGCC\raspberry + false + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-gcc.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-g++.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-gdb.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-ar.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-objcopy.exe + C:\SysGCC\raspberry\bin\make.exe + + C:\SysGCC\raspberry\bin + + true + false + + + MinGWUnixSlash + + + genblitter.vcxproj + + + + LANG + en_US.UTF-8 + + + PATH + C:\SysGCC\raspberry\bin;%PATH% + + + + 1 + + + + + + false + false + false + false + false + false + false + false + false + + false + false + false + false + false + false + true + false + None + false + false + main + true + false + false + false + + + + + + LANG + en_US.UTF-8 + + + PATH + C:\SysGCC\raspberry\bin;%PATH% + + + + + $(TargetPath) + 2000 + + + false + /home/pi/projects//$(TargetFileName) + Local + false + false + Auto + true + false + + + + + + + + + + + + + Default + + + + true + + + + + Unknown + + true + + + VisualGDB\VisualGDBCache + \ No newline at end of file diff --git a/VisualGDB/genblitter/genblitter.vcxproj b/VisualGDB/genblitter/genblitter.vcxproj new file mode 100644 index 00000000..a7368611 --- /dev/null +++ b/VisualGDB/genblitter/genblitter.vcxproj @@ -0,0 +1,71 @@ + + + + + Debug + VisualGDB + + + Release + VisualGDB + + + + 15.0 + {619EFB8C-E41A-4058-B085-1B8CD22692DD} + + + + + + + + + + Debug + C:\SysGCC\raspberry + + + C:\SysGCC\raspberry + + + + GNUPP14 + C:\SysGCC\raspberry\lib\gcc\arm-linux-gnueabihf\4.9\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\include\c++\4.9;C:\SysGCC\raspberry\arm-linux-gnueabihf\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include;../../src/include;../../src;../../src/osdep;%(ClCompile.AdditionalIncludeDirectories) + DEBUG=1;%(ClCompile.PreprocessorDefinitions) + + + ;%(Link.AdditionalLinkerInputs) + ;%(Link.LibrarySearchDirectories) + ;%(Link.AdditionalLibraryNames) + + + + + + GNUPP14 + C:\SysGCC\raspberry\lib\gcc\arm-linux-gnueabihf\4.9\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\include\c++\4.9;C:\SysGCC\raspberry\arm-linux-gnueabihf\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include;../../src/include;../../src;../../src/osdep;%(ClCompile.AdditionalIncludeDirectories) + NDEBUG=1;RELEASE=1;%(ClCompile.PreprocessorDefinitions) + + + ;%(Link.AdditionalLinkerInputs) + ;%(Link.LibrarySearchDirectories) + ;%(Link.AdditionalLibraryNames) + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualGDB/genblitter/genblitter.vcxproj.filters b/VisualGDB/genblitter/genblitter.vcxproj.filters new file mode 100644 index 00000000..fcb90c62 --- /dev/null +++ b/VisualGDB/genblitter/genblitter.vcxproj.filters @@ -0,0 +1,40 @@ + + + + + {afe8a49f-0586-4eea-b2ea-cc1c4567db36} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4718ef87-4582-42a4-8469-11a35b5a4418} + h;hpp;hxx;hm;inl;inc;xsd + + + {e9ba1ae1-6dab-41af-8b75-7c41100a7fc9} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + {c7346196-4f74-4afd-aa85-9da2661c7ab7} + *.vgdbsettings + + + + + VisualGDB settings + + + VisualGDB settings + + + + + Source files + + + Source files + + + + + + \ No newline at end of file diff --git a/VisualGDB/genblitter/genblitter.vcxproj.user b/VisualGDB/genblitter/genblitter.vcxproj.user new file mode 100644 index 00000000..be250787 --- /dev/null +++ b/VisualGDB/genblitter/genblitter.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/VisualGDB/genlinetoscr/Readme.txt b/VisualGDB/genlinetoscr/Readme.txt new file mode 100644 index 00000000..ff2f6f3c --- /dev/null +++ b/VisualGDB/genlinetoscr/Readme.txt @@ -0,0 +1,7 @@ +This tool generates the "linetoscr.cpp" file. + +Compile it for the target system (e.g. Raspberry) then run it there as: + +genlinetoscr > linetoscr.cpp + +Copy the generated file back into the "src" directory. \ No newline at end of file diff --git a/VisualGDB/genlinetoscr/genlinetoscr-Debug.vgdbsettings b/VisualGDB/genlinetoscr/genlinetoscr-Debug.vgdbsettings new file mode 100644 index 00000000..9513a9ac --- /dev/null +++ b/VisualGDB/genlinetoscr/genlinetoscr-Debug.vgdbsettings @@ -0,0 +1,154 @@ + + + Debug + + + + MinGWUnixSlash + + + 192.168.1.152 + SSH + pi + + false + false + false + false + false + $(ProjectDir) + + + + Raspberry PI + com.visualgdb.raspberry_pi + C:\SysGCC\raspberry + false + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-gcc.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-g++.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-gdb.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-ar.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-objcopy.exe + C:\SysGCC\raspberry\bin\make.exe + + C:\SysGCC\raspberry\bin + + true + false + + + MinGWUnixSlash + + + genlinetoscr.vcxproj + + + + LANG + en_US.UTF-8 + + + PATH + C:\SysGCC\raspberry\bin;%PATH% + + + + + 1 + + + + + + false + false + false + false + false + false + false + false + false + + false + false + false + false + false + false + true + false + None + false + false + main + true + false + false + false + + + + + + LANG + en_US.UTF-8 + + + PATH + C:\SysGCC\raspberry\bin;%PATH% + + + + + $(TargetPath) + 2000 + + + false + /home/pi/projects//$(TargetFileName) + Local + false + false + Auto + true + false + + + + + + + + + + + + + Default + + + + true + + + + + False + + + + + true + + Enabled + true + true + true + + + + + + VisualGDB\VisualGDBCache + \ No newline at end of file diff --git a/VisualGDB/genlinetoscr/genlinetoscr-Release.vgdbsettings b/VisualGDB/genlinetoscr/genlinetoscr-Release.vgdbsettings new file mode 100644 index 00000000..4427ede4 --- /dev/null +++ b/VisualGDB/genlinetoscr/genlinetoscr-Release.vgdbsettings @@ -0,0 +1,142 @@ + + + Release + + + + MinGWUnixSlash + + + 192.168.1.152 + SSH + pi + + false + false + false + false + false + $(ProjectDir) + + + + Raspberry PI + com.visualgdb.raspberry_pi + C:\SysGCC\raspberry + false + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-gcc.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-g++.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-gdb.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-ar.exe + C:\SysGCC\raspberry\bin\arm-linux-gnueabihf-objcopy.exe + C:\SysGCC\raspberry\bin\make.exe + + C:\SysGCC\raspberry\bin + + true + false + + + MinGWUnixSlash + + + genlinetoscr.vcxproj + + + + LANG + en_US.UTF-8 + + + PATH + C:\SysGCC\raspberry\bin;%PATH% + + + + 1 + + + + + + false + false + false + false + false + false + false + false + false + + false + false + false + false + false + false + true + false + None + false + false + main + true + false + false + false + + + + + + LANG + en_US.UTF-8 + + + PATH + C:\SysGCC\raspberry\bin;%PATH% + + + + + $(TargetPath) + 2000 + + + false + /home/pi/projects//$(TargetFileName) + Local + false + false + Auto + true + false + + + + + + + + + + + + + Default + + + + true + + + + + Unknown + + true + + + VisualGDB\VisualGDBCache + \ No newline at end of file diff --git a/VisualGDB/genlinetoscr/genlinetoscr.vcxproj b/VisualGDB/genlinetoscr/genlinetoscr.vcxproj new file mode 100644 index 00000000..a7deedd9 --- /dev/null +++ b/VisualGDB/genlinetoscr/genlinetoscr.vcxproj @@ -0,0 +1,70 @@ + + + + + Debug + VisualGDB + + + Release + VisualGDB + + + + 15.0 + {883F2A00-8030-429B-AC7F-E930DDF9568F} + + + + + + + + + + Debug + C:\SysGCC\raspberry + + + C:\SysGCC\raspberry + + + + GNUPP14 + C:\SysGCC\raspberry\lib\gcc\arm-linux-gnueabihf\4.9\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\include\c++\4.9;C:\SysGCC\raspberry\arm-linux-gnueabihf\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include;../../src/include;../../src;../../src/osdep;%(ClCompile.AdditionalIncludeDirectories) + DEBUG=1;%(ClCompile.PreprocessorDefinitions) + + + ;%(Link.AdditionalLinkerInputs) + ;%(Link.LibrarySearchDirectories) + ;%(Link.AdditionalLibraryNames) + + + + + + GNUPP14 + C:\SysGCC\raspberry\lib\gcc\arm-linux-gnueabihf\4.9\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\include\c++\4.9;C:\SysGCC\raspberry\arm-linux-gnueabihf\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include;../../src/include;../../src;../../src/osdep;%(ClCompile.AdditionalIncludeDirectories) + NDEBUG=1;RELEASE=1;%(ClCompile.PreprocessorDefinitions) + + + ;%(Link.AdditionalLinkerInputs) + ;%(Link.LibrarySearchDirectories) + ;%(Link.AdditionalLibraryNames) + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualGDB/genlinetoscr/genlinetoscr.vcxproj.filters b/VisualGDB/genlinetoscr/genlinetoscr.vcxproj.filters new file mode 100644 index 00000000..dc1e79f8 --- /dev/null +++ b/VisualGDB/genlinetoscr/genlinetoscr.vcxproj.filters @@ -0,0 +1,37 @@ + + + + + {19e139ec-d402-45d4-89fc-39f22443a95b} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {0a02e0a2-214b-4e9e-a7c5-0668ebf38e34} + h;hpp;hxx;hm;inl;inc;xsd + + + {30f92ef0-a24c-49e2-9e92-906dcef4d050} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + {20bde34c-9e8e-42ee-83c1-c8c8143c7516} + *.vgdbsettings + + + + + VisualGDB settings + + + VisualGDB settings + + + + + Source files + + + + + + \ No newline at end of file diff --git a/VisualGDB/genlinetoscr/genlinetoscr.vcxproj.user b/VisualGDB/genlinetoscr/genlinetoscr.vcxproj.user new file mode 100644 index 00000000..be250787 --- /dev/null +++ b/VisualGDB/genlinetoscr/genlinetoscr.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/akiko.cpp b/src/akiko.cpp index ec4e013d..7337abc6 100644 --- a/src/akiko.cpp +++ b/src/akiko.cpp @@ -15,7 +15,7 @@ #include "sysdeps.h" #include "options.h" -#include "memory.h" +#include "include/memory.h" #include "newcpu.h" #include "events.h" #include "savestate.h" @@ -398,21 +398,22 @@ static uae_u32 akiko_c2p_read(int offset) */ #define CDINTERRUPT_SUBCODE 0x80000000 -#define CDINTERRUPT_DRIVEXMIT 0x40000000 /* not used by ROM */ -#define CDINTERRUPT_DRIVERECV 0x20000000 /* not used by ROM */ +#define CDINTERRUPT_DRIVEXMIT 0x40000000 /* not used by ROM. PIO mode. */ +#define CDINTERRUPT_DRIVERECV 0x20000000 /* not used by ROM. PIO mode. */ #define CDINTERRUPT_RXDMADONE 0x10000000 #define CDINTERRUPT_TXDMADONE 0x08000000 #define CDINTERRUPT_PBX 0x04000000 #define CDINTERRUPT_OVERFLOW 0x02000000 -#define CDFLAG_SUBCODE 0x80000000 -#define CDFLAG_TXD 0x40000000 -#define CDFLAG_RXD 0x20000000 -#define CDFLAG_CAS 0x10000000 -#define CDFLAG_PBX 0x08000000 -#define CDFLAG_ENABLE 0x04000000 -#define CDFLAG_RAW 0x02000000 -#define CDFLAG_MSB 0x01000000 +#define CDFLAG_SUBCODE 0x80000000 // 31 +#define CDFLAG_TXD 0x40000000 // 30 +#define CDFLAG_RXD 0x20000000 // 29 +#define CDFLAG_CAS 0x10000000 // 28 +#define CDFLAG_PBX 0x08000000 // 27 +#define CDFLAG_ENABLE 0x04000000 // 26 +#define CDFLAG_RAW 0x02000000 // 25 +#define CDFLAG_MSB 0x01000000 // 24 +#define CDFLAG_NTSC 0x00800000 // 23 #define CDS_ERROR 0x80 #define CDS_PLAYING 0x08 @@ -1673,6 +1674,11 @@ static uae_u32 REGPARAM2 akiko_lget(uaecptr addr) return v; } +bool akiko_ntscmode(void) +{ + return (cdrom_flags & CDFLAG_NTSC) != 0; +} + static void akiko_bput2(uaecptr addr, uae_u32 v, int msg) { uae_u32 tmp; @@ -1789,32 +1795,34 @@ static void akiko_bput2(uaecptr addr, uae_u32 v, int msg) static void REGPARAM2 akiko_bput(uaecptr addr, uae_u32 v) { -#ifdef JIT - special_mem |= S_WRITE; -#endif + addr &= 0xffff; + if (addr >= 0x8000) + return; akiko_bput2(addr, v, 1); } static void REGPARAM2 akiko_wput(uaecptr addr, uae_u32 v) { -#ifdef JIT - special_mem |= S_WRITE; -#endif addr &= 0xfff; - if ((addr < 0x30 && AKIKO_DEBUG_IO)) - write_log(_T("akiko_wput %08X: %08X=%04X\n"), M68K_GETPC, addr, v & 0xffff); + if (addr >= 0x8000) + return; + if ((addr < 0x30 && AKIKO_DEBUG_IO)) { + //if (log_cd32 > 1) + // write_log(_T("akiko_wput %08X: %08X=%04X\n"), M68K_GETPC, addr, v & 0xffff); + } akiko_bput2(addr + 1, v & 0xff, 0); akiko_bput2(addr + 0, v >> 8, 0); } static void REGPARAM2 akiko_lput(uaecptr addr, uae_u32 v) { -#ifdef JIT - special_mem |= S_WRITE; -#endif addr &= 0xffff; - if (addr < 0x30 && AKIKO_DEBUG_IO) - write_log(_T("akiko_lput %08X: %08X=%08X\n"), M68K_GETPC, addr, v); + if (addr >= 0x8000) + return; + if (addr < 0x30 && AKIKO_DEBUG_IO) { + //if (log_cd32 > 1) + // write_log(_T("akiko_lput %08X: %08X=%08X\n"), M68K_GETPC, addr, v); + } akiko_bput2(addr + 3, (v >> 0) & 0xff, 0); akiko_bput2(addr + 2, (v >> 8) & 0xff, 0); akiko_bput2(addr + 1, (v >> 16) & 0xff, 0); @@ -1822,19 +1830,11 @@ static void REGPARAM2 akiko_lput(uaecptr addr, uae_u32 v) } addrbank akiko_bank = { - akiko_lget, - akiko_wget, - akiko_bget, - akiko_lput, - akiko_wput, - akiko_bput, - default_xlate, - default_check, - NULL, - _T("Akiko"), - dummy_lgeti, - dummy_wgeti, - ABFLAG_IO + akiko_lget, akiko_wget, akiko_bget, + akiko_lput, akiko_wput, akiko_bput, + default_xlate, default_check, NULL, NULL, _T("Akiko"), + dummy_lgeti, dummy_wgeti, + ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE }; static const uae_u8 patchdata[] = { 0x0c, 0x82, 0x00, 0x00, 0x03, 0xe8, 0x64, 0x00, 0x00, 0x46 }; diff --git a/src/audio.cpp b/src/audio.cpp index d99489b2..8271223f 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -16,7 +16,7 @@ #include "sysdeps.h" #include "options.h" -#include "memory.h" +#include "include/memory.h" #include "custom.h" #include "newcpu.h" #include "autoconf.h" @@ -1340,18 +1340,35 @@ void audio_hsync(void) update_audio(); } -void AUDxDAT(int nr, uae_u16 v) +void AUDxDAT(int nr, uae_u16 v, uaecptr addr) { struct audio_channel_data *cdp = audio_channel + nr; int chan_ena = (dmacon & DMA_MASTER) && (dmacon & (1 << nr)); +#if DEBUG_AUDIO > 0 + if (debugchannel(nr) && (DEBUG_AUDIO > 1 || (!chan_ena || addr == 0xffffffff || (cdp->state != 2 && cdp->state != 3)))) { + write_log(_T("AUD%dDAT: %04X ADDR=%08X LEN=%d/%d %d,%d,%d %06X\n"), nr, + v, addr, cdp->wlen, cdp->len, cdp->state, chan_ena, isirq(nr) ? 1 : 0, M68K_GETPC); + } +#endif cdp->dat = v; cdp->dat_written = true; +#if TEST_AUDIO > 0 + if (debugchannel(nr) && cdp->have_dat) + write_log(_T("%d: audxdat 1=%04x 2=%04x but old dat not yet used\n"), nr, cdp->dat, cdp->dat2); + cdp->have_dat = true; +#endif if (cdp->state == 2 || cdp->state == 3) { if (chan_ena) { if (cdp->wlen == 1) { cdp->wlen = cdp->len; cdp->intreq2 = true; + //if (sampleripper_enabled) + // do_samplerip(cdp); +#if DEBUG_AUDIO > 0 + if (debugchannel(nr) && cdp->wlen > 1) + write_log(_T("AUD%d looped, IRQ=%d, LC=%08X LEN=%d\n"), nr, isirq(nr) ? 1 : 0, cdp->pt, cdp->wlen); +#endif } else { cdp->wlen = (cdp->wlen - 1) & 0xffff; @@ -1367,16 +1384,20 @@ void AUDxDAT(int nr, uae_u16 v) } cdp->dat_written = false; } +void AUDxDAT(int nr, uae_u16 v) +{ + AUDxDAT(nr, v, 0xffffffff); +} -void audio_dmal_do(int nr, bool reset) +uaecptr audio_getpt(int nr, bool reset) { struct audio_channel_data *cdp = audio_channel + nr; - uae_u16 dat = chipmem_wget_indirect(cdp->pt); + uaecptr p = cdp->pt; cdp->pt += 2; if (reset) cdp->pt = cdp->lc; cdp->ptx_tofetch = false; - AUDxDAT(nr, dat); + return p; } void AUDxLCH(int nr, uae_u16 v) @@ -1384,6 +1405,7 @@ void AUDxLCH(int nr, uae_u16 v) struct audio_channel_data *cdp = audio_channel + nr; audio_activate(); update_audio(); + // someone wants to update PT but DSR has not yet been processed. // too fast CPU and some tracker players: enable DMA, CPU delay, update AUDxPT with loop position if (usehacks() && ((cdp->ptx_tofetch && cdp->state == 1) || cdp->ptx_written)) { diff --git a/src/autoconf.cpp b/src/autoconf.cpp index 433f69eb..b5219bb9 100644 --- a/src/autoconf.cpp +++ b/src/autoconf.cpp @@ -1,22 +1,30 @@ - /* - * UAE - The Un*x Amiga Emulator - * - * AutoConfig devices - * - * Copyright 1995, 1996 Bernd Schmidt - * Copyright 1996 Ed Hanway - */ +/* +* UAE - The Un*x Amiga Emulator +* +* AutoConfig devices +* +* Copyright 1995, 1996 Bernd Schmidt +* Copyright 1996 Ed Hanway +*/ #include "sysconfig.h" #include "sysdeps.h" +#define NEW_TRAP_DEBUG 0 + #include "options.h" #include "uae.h" #include "memory.h" #include "custom.h" +#include "events.h" #include "newcpu.h" #include "autoconf.h" #include "traps.h" +#include "debug.h" +#include "threaddep/thread.h" +#include "native2amiga.h" +#include "inputdevice.h" +//#include "uae/ppc.h" /* Commonly used autoconfig strings */ @@ -24,332 +32,489 @@ uaecptr EXPANSION_explibname, EXPANSION_doslibname, EXPANSION_uaeversion; uaecptr EXPANSION_uaedevname, EXPANSION_explibbase = 0; uaecptr EXPANSION_bootcode, EXPANSION_nullfunc; - /* ROM tag area memory access */ -uae_u8 *rtarea = 0; uaecptr rtarea_base = RTAREA_DEFAULT; +uae_sem_t hardware_trap_event[RTAREA_TRAP_DATA_SIZE / RTAREA_TRAP_DATA_SLOT_SIZE]; +uae_sem_t hardware_trap_event2[RTAREA_TRAP_DATA_SIZE / RTAREA_TRAP_DATA_SLOT_SIZE]; -static uae_u32 REGPARAM3 rtarea_lget (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 rtarea_wget (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 rtarea_bget (uaecptr) REGPARAM; -static void REGPARAM3 rtarea_lput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 rtarea_wput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 rtarea_bput (uaecptr, uae_u32) REGPARAM; -static uae_u8 *REGPARAM3 rtarea_xlate (uaecptr) REGPARAM; -static int REGPARAM3 rtarea_check (uaecptr addr, uae_u32 size) REGPARAM; +static uaecptr rt_trampoline_ptr, trap_entry; +static bool rtarea_write_enabled; +extern volatile uae_atomic hwtrap_waiting; +extern volatile int trap_mode; +DECLARE_MEMORY_FUNCTIONS(rtarea); addrbank rtarea_bank = { - rtarea_lget, rtarea_wget, rtarea_bget, - rtarea_lput, rtarea_wput, rtarea_bput, - rtarea_xlate, rtarea_check, NULL, _T("UAE Boot ROM"), - rtarea_lget, rtarea_wget, ABFLAG_ROMIN + rtarea_lget, rtarea_wget, rtarea_bget, + rtarea_lput, rtarea_wput, rtarea_bput, + rtarea_xlate, rtarea_check, NULL, _T("rtarea"), _T("UAE Boot ROM"), + rtarea_lget, rtarea_wget, + ABFLAG_ROMIN | ABFLAG_PPCIOSPACE, S_READ, S_WRITE }; -static uae_u8 *REGPARAM2 rtarea_xlate (uaecptr addr) -{ - addr &= 0xFFFF; - return rtarea + addr; -} +#define MAX_ABSOLUTE_ROM_ADDRESS 1024 -static int REGPARAM2 rtarea_check (uaecptr addr, uae_u32 size) -{ - addr &= 0xFFFF; - return (addr + size) <= 0xFFFF; -} +static int absolute_rom_address; +static uaecptr absolute_rom_addresses[MAX_ABSOLUTE_ROM_ADDRESS]; +static uaecptr rombase_new; -static uae_u32 REGPARAM2 rtarea_lget (uaecptr addr) +static bool istrapwait(void) { -#ifdef JIT - special_mem |= S_READ; -#endif - addr &= 0xFFFF; - return (uae_u32)(rtarea_wget (addr) << 16) + rtarea_wget (addr+2); -} - -static uae_u32 REGPARAM2 rtarea_wget (uaecptr addr) -{ -#ifdef JIT - special_mem |= S_READ; -#endif - addr &= 0xFFFF; - return (rtarea[addr]<<8) + rtarea[addr+1]; -} - -static uae_u32 REGPARAM2 rtarea_bget (uaecptr addr) -{ -#ifdef JIT - special_mem |= S_READ; -#endif - addr &= 0xFFFF; - return rtarea[addr]; + for (int i = 0; i < RTAREA_TRAP_DATA_NUM + RTAREA_TRAP_DATA_SEND_NUM; i++) { + uae_u8 *data = rtarea_bank.baseaddr + RTAREA_TRAP_DATA + i * RTAREA_TRAP_DATA_SLOT_SIZE; + uae_u8 *status = rtarea_bank.baseaddr + RTAREA_TRAP_STATUS + i * RTAREA_TRAP_STATUS_SIZE; + if (get_long_host(data + RTAREA_TRAP_DATA_TASKWAIT) && status[3] && status[2] >= 0x80) { + return true; + } + } + return false; } #define RTAREA_WRITEOFFSET 0xfff0 -static void REGPARAM2 rtarea_bput (uaecptr addr, uae_u32 value) +static bool rtarea_trap_data(uaecptr addr) { -#ifdef JIT - special_mem |= S_WRITE; -#endif - addr &= 0xffff; - if (addr < RTAREA_WRITEOFFSET) - return; - rtarea[addr] = value; + if (currprefs.uaeboard < 2) + return false; + if (addr >= RTAREA_TRAP_DATA && addr < RTAREA_TRAP_DATA + (RTAREA_TRAP_DATA_NUM + RTAREA_TRAP_DATA_SEND_NUM) * RTAREA_TRAP_DATA_SLOT_SIZE) + return true; + return false; +} +static bool rtarea_trap_status(uaecptr addr) +{ + if (currprefs.uaeboard < 2) + return false; + if (addr >= RTAREA_TRAP_STATUS && addr < RTAREA_TRAP_STATUS + (RTAREA_TRAP_DATA_NUM + RTAREA_TRAP_DATA_SEND_NUM) * RTAREA_TRAP_STATUS_SIZE) + return true; + return false; +} +static bool rtarea_trap_status_extra(uaecptr addr) +{ + if (currprefs.uaeboard < 2) + return false; + if (addr >= RTAREA_TRAP_STATUS + 0x100 && addr < RTAREA_TRAP_STATUS + 0x100 + (RTAREA_TRAP_DATA_NUM + RTAREA_TRAP_DATA_SEND_NUM) * RTAREA_TRAP_STATUS_SIZE) + return true; + return false; } -static void REGPARAM2 rtarea_wput (uaecptr addr, uae_u32 value) +static uae_u8 *REGPARAM2 rtarea_xlate(uaecptr addr) { -#ifdef JIT - special_mem |= S_WRITE; -#endif - addr &= 0xffff; - if (addr < RTAREA_WRITEOFFSET) - return; - rtarea_bput (addr, value >> 8); - rtarea_bput (addr + 1, value & 0xff); + addr &= 0xFFFF; + return rtarea_bank.baseaddr + addr; } -static void REGPARAM2 rtarea_lput (uaecptr addr, uae_u32 value) +static int REGPARAM2 rtarea_check(uaecptr addr, uae_u32 size) +{ + addr &= 0xFFFF; + return (addr + size) <= 0xFFFF; +} + +static uae_u32 REGPARAM2 rtarea_lget(uaecptr addr) +{ + addr &= 0xFFFF; + if (addr & 1) + return 0; + if (addr >= 0xfffd) + return 0; + return (rtarea_bank.baseaddr[addr + 0] << 24) | (rtarea_bank.baseaddr[addr + 1] << 16) | + (rtarea_bank.baseaddr[addr + 2] << 8) | (rtarea_bank.baseaddr[addr + 3] << 0); +} +static uae_u32 REGPARAM2 rtarea_wget(uaecptr addr) +{ + addr &= 0xFFFF; + if (addr & 1) + return 0; + + uaecptr addr2 = addr - RTAREA_TRAP_STATUS; + + if (rtarea_trap_status(addr)) { + int trap_offset = addr2 & (RTAREA_TRAP_STATUS_SIZE - 1); + int trap_slot = addr2 / RTAREA_TRAP_STATUS_SIZE; + // lock attempt + if (trap_offset == 2) { + if (rtarea_bank.baseaddr[addr + 1] & 0x80) { + return rtarea_bank.baseaddr[addr + 1]; + } + rtarea_bank.baseaddr[addr + 1] |= 0x80; + rtarea_bank.baseaddr[addr + 0] = 0; + return 0; + } + } + return (rtarea_bank.baseaddr[addr] << 8) + rtarea_bank.baseaddr[addr + 1]; +} +static uae_u32 REGPARAM2 rtarea_bget(uaecptr addr) +{ + addr &= 0xFFFF; + return rtarea_bank.baseaddr[addr]; +} + +static bool rtarea_write(uaecptr addr) +{ + if (rtarea_write_enabled) + return true; + if (addr >= RTAREA_WRITEOFFSET) + return true; + if (addr >= RTAREA_SYSBASE && addr < RTAREA_SYSBASE + 4) + return true; + return rtarea_trap_data(addr) || rtarea_trap_status(addr) || rtarea_trap_status_extra(addr); +} + +static void REGPARAM2 rtarea_bput(uaecptr addr, uae_u32 value) +{ + addr &= 0xffff; + if (!rtarea_write(addr)) + return; + rtarea_bank.baseaddr[addr] = value; +} + +static void REGPARAM2 rtarea_wput(uaecptr addr, uae_u32 value) { -#ifdef JIT - special_mem |= S_WRITE; -#endif addr &= 0xffff; if (addr < RTAREA_WRITEOFFSET) return; - rtarea_wput (addr, value >> 16); - rtarea_wput (addr + 2, value & 0xffff); + rtarea_bput(addr, value >> 8); + rtarea_bput(addr + 1, value & 0xff); +} + +static void REGPARAM2 rtarea_lput(uaecptr addr, uae_u32 value) +{ + addr &= 0xffff; + if (addr < RTAREA_WRITEOFFSET) + return; + rtarea_wput(addr, value >> 16); + rtarea_wput(addr + 2, value & 0xffff); } /* some quick & dirty code to fill in the rt area and save me a lot of - * scratch paper - */ +* scratch paper +*/ static int rt_addr; static int rt_straddr; -uae_u32 addr (int ptr) +uae_u32 addr(int ptr) { - return (uae_u32)ptr + rtarea_base; + return (uae_u32)ptr + rtarea_base; } -void db (uae_u8 data) +void db(uae_u8 data) { - rtarea[rt_addr++] = data; + rtarea_bank.baseaddr[rt_addr++] = data; } -void dw (uae_u16 data) +void dw(uae_u16 data) { - rtarea[rt_addr++] = (uae_u8)(data >> 8); - rtarea[rt_addr++] = (uae_u8)data; + rtarea_bank.baseaddr[rt_addr++] = (uae_u8)(data >> 8); + rtarea_bank.baseaddr[rt_addr++] = (uae_u8)data; } -void dl (uae_u32 data) +void dl(uae_u32 data) { - rtarea[rt_addr++] = data >> 24; - rtarea[rt_addr++] = data >> 16; - rtarea[rt_addr++] = data >> 8; - rtarea[rt_addr++] = data; + rtarea_bank.baseaddr[rt_addr++] = data >> 24; + rtarea_bank.baseaddr[rt_addr++] = data >> 16; + rtarea_bank.baseaddr[rt_addr++] = data >> 8; + rtarea_bank.baseaddr[rt_addr++] = data; } -uae_u8 dbg (uaecptr addr) +uae_u8 dbg(uaecptr addr) { - addr -= rtarea_base; - return rtarea[addr]; + addr -= rtarea_base; + return rtarea_bank.baseaddr[addr]; } /* store strings starting at the end of the rt area and working - * backward. store pointer at current address - */ +* backward. store pointer at current address +*/ -uae_u32 ds_ansi (const uae_char *str) +uae_u32 ds_ansi(const uae_char *str) { - int len; + int len; - if (!str) - return addr (rt_straddr); - len = strlen (str) + 1; - rt_straddr -= len; - strcpy ((uae_char*)rtarea + rt_straddr, str); - return addr (rt_straddr); + if (!str) + return addr(rt_straddr); + len = strlen(str) + 1; + rt_straddr -= len; + strcpy((uae_char*)rtarea_bank.baseaddr + rt_straddr, str); + return addr(rt_straddr); } -uae_u32 ds (const TCHAR *str) +uae_u32 ds(const TCHAR *str) { - char *s = ua (str); - uae_u32 v = ds_ansi (s); - xfree (s); + char *s = ua(str); + uae_u32 v = ds_ansi(s); + xfree(s); return v; } -uae_u32 ds_bstr_ansi (const uae_char *str) +uae_u32 ds_bstr_ansi(const uae_char *str) { int len; - - len = strlen (str) + 2; + + len = strlen(str) + 2; rt_straddr -= len; while (rt_straddr & 3) rt_straddr--; - rtarea[rt_straddr] = len - 2; - strcpy ((uae_char*)rtarea + rt_straddr + 1, str); - return addr (rt_straddr) >> 2; + rtarea_bank.baseaddr[rt_straddr] = len - 2; + strcpy((uae_char*)rtarea_bank.baseaddr + rt_straddr + 1, str); + return addr(rt_straddr) >> 2; } -void calltrap (uae_u32 n) +void save_rom_absolute(uaecptr addr) { - dw (0xA000 + n); + if (rombase_new) + return; + if (absolute_rom_address >= MAX_ABSOLUTE_ROM_ADDRESS) { + write_log(_T("MAX_ABSOLUTE_ROM_ADDRESS is too low!")); + abort(); + } + for (int i = 0; i < absolute_rom_address; i++) { + if (absolute_rom_addresses[i] == addr) { + write_log(_T("Address %08x already added\n"), addr); + return; + } + } + absolute_rom_addresses[absolute_rom_address++] = addr; } -void org (uae_u32 a) +void add_rom_absolute(uaecptr addr) { - if ( ((a & 0xffff0000) != 0x00f00000) && ((a & 0xffff0000) != rtarea_base) ) - write_log (_T("ORG: corrupt address! %08X"), a); - rt_addr = a & 0xffff; + uaecptr h = here(); + dl(addr); + save_rom_absolute(h); } -uae_u32 here (void) +uae_u32 boot_rom_copy(TrapContext *ctx, uaecptr rombase, int mode) { - return addr (rt_addr); + uaecptr reloc = 0; + if (currprefs.uaeboard < 3) + return 0; + if (!mode) { + rtarea_write_enabled = true; + protect_roms(false); + rombase_new = rombase; + int size = 4 + 2 + 4; + for (int i = 0; i < absolute_rom_address; i++) { + uae_u32 a = absolute_rom_addresses[i]; + if (a >= rtarea_base && a < rtarea_base + 0x10000) { + size += 2; + } + else { + size += 4; + } + } + reloc = uaeboard_alloc_ram(size); + uae_u8 *p = uaeboard_map_ram(reloc); + put_long_host(p, rtarea_base); + p += 4; + for (int i = 0; i < absolute_rom_address; i++) { + uae_u32 a = absolute_rom_addresses[i]; + if (a >= rtarea_base && a < rtarea_base + 0x10000) { + put_word_host(p, a & 0xffff); + p += 2; + } + } + put_word_host(p, 0); + p += 2; + for (int i = 0; i < absolute_rom_address; i++) { + uae_u32 a = absolute_rom_addresses[i]; + if (a < rtarea_base || a >= rtarea_base + 0x10000) { + put_long_host(p, a); + p += 4; + } + } + put_long_host(p, 0); + write_log(_T("ROMBASE %08x RAMBASE %08x RELOC %08x (%d)\n"), rtarea_base, rombase, reloc, absolute_rom_address); + } + else { + rtarea_write_enabled = false; + protect_roms(true); + write_log(_T("ROMBASE changed.\n"), absolute_rom_address); + reloc = 1; + } + return reloc; } -void align (int b) +void calltrap(uae_u32 n) { - rt_addr = (rt_addr + b - 1) & ~(b - 1); + if (currprefs.uaeboard > 2) { + dw(0x4eb9); // JSR rt_trampoline_ptr + add_rom_absolute(rt_trampoline_ptr); + uaecptr a = here(); + org(rt_trampoline_ptr); + dw(0x3f3c); // MOVE.W #n,-(SP) + dw(n); + dw(0x4ef9); // JMP rt_trampoline_entry + add_rom_absolute(trap_entry); + org(a); + rt_trampoline_ptr += 3 * 2 + 1 * 4; + } + else { + dw(0xA000 + n); + } } -static uae_u32 REGPARAM2 nullfunc(TrapContext *context) +void org(uae_u32 a) { - write_log (_T("Null function called\n")); - return 0; + if (((a & 0xffff0000) != 0x00f00000) && ((a & 0xffff0000) != rtarea_base)) + write_log(_T("ORG: corrupt address! %08X"), a); + rt_addr = a & 0xffff; } -static uae_u32 REGPARAM2 getchipmemsize (TrapContext *context) +uae_u32 here(void) { - m68k_dreg (regs, 1) = 0; - m68k_areg (regs, 1) = 0; - return chipmem_bank.allocated; + return addr(rt_addr); } -static uae_u32 REGPARAM2 uae_puts (TrapContext *context) +void align(int b) { - puts ((char *)get_real_address (m68k_areg (regs, 0))); - return 0; + rt_addr = (rt_addr + b - 1) & ~(b - 1); } -void rtarea_init_mem (void) +static uae_u32 REGPARAM2 nullfunc(TrapContext *ctx) { - if(rtarea != 0) - mapped_free(rtarea); - - rtarea = mapped_malloc (RTAREA_SIZE, _T("rtarea")); - if (!rtarea) { - write_log (_T("virtual memory exhausted (rtarea)!\n")); - abort (); - } - memset(rtarea, 0, RTAREA_SIZE); - rtarea_bank.baseaddr = rtarea; + write_log(_T("Null function called\n")); + return 0; } -void rtarea_init (void) +static uae_u32 REGPARAM2 getchipmemsize(TrapContext *ctx) { - uae_u32 a; - TCHAR uaever[100]; + m68k_dreg(regs, 1) = z3chipmem_bank.allocated_size; + m68k_dreg(regs, 1) = z3chipmem_bank.start; + return chipmem_bank.allocated_size; +} - rt_straddr = 0xFF00 - 2; - rt_addr = 0; +static uae_u32 REGPARAM2 uae_puts(TrapContext *ctx) +{ + uae_char buf[MAX_DPATH]; + //trap_get_string(ctx, buf, trap_get_areg(ctx, 0), sizeof uae_char); + TCHAR *s = au(buf); + write_log(_T("%s"), s); + xfree(s); + return 0; +} - init_traps (); +void rtarea_init_mem(void) +{ + if (need_uae_boot_rom(&currprefs)) { + rtarea_bank.flags &= ~ABFLAG_ALLOCINDIRECT; + } + else { + // not enabled and something else may use same address space + rtarea_bank.flags |= ABFLAG_ALLOCINDIRECT; + } + rtarea_bank.reserved_size = RTAREA_SIZE; + rtarea_bank.start = rtarea_base; + if (!mapped_malloc(&rtarea_bank)) { + write_log(_T("virtual memory exhausted (rtarea)!\n")); + abort(); + } +} - rtarea_init_mem (); - memset (rtarea, 0, RTAREA_SIZE); +void rtarea_free(void) +{ + mapped_free(&rtarea_bank); +} - _stprintf (uaever, _T("uae-%d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV); +void rtarea_init(void) +{ + uae_u32 a; + TCHAR uaever[100]; - EXPANSION_uaeversion = ds (uaever); - EXPANSION_explibname = ds (_T("expansion.library")); - EXPANSION_doslibname = ds (_T("dos.library")); - EXPANSION_uaedevname = ds (_T("uae.device")); + rt_straddr = 0xFF00 - 2; + rt_addr = 0; - deftrap (NULL); /* Generic emulator trap */ + rt_trampoline_ptr = rtarea_base + RTAREA_TRAMPOLINE; + trap_entry = 0; + absolute_rom_address = 0; + rombase_new = 0; - dw (0); - dw (0); + init_traps(); - a = here(); - /* Dummy trap - removing this breaks the filesys emulation. */ - org (rtarea_base + 0xFF00); - calltrap (deftrap2 (nullfunc, TRAPFLAG_NO_RETVAL, _T(""))); + rtarea_init_mem(); + memset(rtarea_bank.baseaddr, 0, RTAREA_SIZE); - org (rtarea_base + 0xFF80); - calltrap (deftrapres (getchipmemsize, TRAPFLAG_DORET, _T("getchipmemsize"))); + _stprintf(uaever, _T("uae-%d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV); - org (rtarea_base + 0xFF10); - calltrap (deftrapres (uae_puts, TRAPFLAG_NO_RETVAL, _T("uae_puts"))); - dw (RTS); + EXPANSION_uaeversion = ds(uaever); + EXPANSION_explibname = ds(_T("expansion.library")); + EXPANSION_doslibname = ds(_T("dos.library")); + EXPANSION_uaedevname = ds(_T("uae.device")); + + dw(0); + dw(0); - org (a); - #ifdef FILESYS - filesys_install_code (); + filesys_install_code(); #endif - uae_boot_rom_size = here () - rtarea_base; + deftrap(NULL); /* Generic emulator trap */ + + a = here(); + /* Dummy trap - removing this breaks the filesys emulation. */ + org(rtarea_base + 0xFF00); + calltrap(deftrap2(nullfunc, TRAPFLAG_NO_RETVAL, _T(""))); + + org(rtarea_base + 0xFF80); + calltrap(deftrapres(getchipmemsize, TRAPFLAG_DORET, _T("getchipmemsize"))); + dw(RTS); + + org(rtarea_base + 0xFF10); + calltrap(deftrapres(uae_puts, TRAPFLAG_NO_RETVAL, _T("uae_puts"))); + dw(RTS); + + org(a); + + uae_boot_rom_size = here() - rtarea_base; if (uae_boot_rom_size >= RTAREA_TRAPS) { - write_log (_T("RTAREA_TRAPS needs to be increased!")); - abort (); + write_log(_T("RTAREA_TRAPS needs to be increased!")); + abort(); } #ifdef PICASSO96 - uaegfx_install_code (rtarea_base + RTAREA_RTG); + uaegfx_install_code(rtarea_base + RTAREA_RTG); #endif - org (RTAREA_TRAPS | rtarea_base); - init_extended_traps(); + org(RTAREA_TRAPS | rtarea_base); + init_extended_traps(); } volatile int uae_int_requested = 0; -void set_uae_int_flag (void) -{ - rtarea[RTAREA_INT] = uae_int_requested & 1; -} - void rtarea_setup(void) { - uae_int_requested = 0; - uaecptr base = need_uae_boot_rom (); - if (base) { - write_log (_T("RTAREA located at %08X\n"), base); - rtarea_base = base; - } + uaecptr base = need_uae_boot_rom(&currprefs); + if (base) { + write_log(_T("RTAREA located at %08X\n"), base); + rtarea_base = base; + } } -uaecptr makedatatable (uaecptr resid, uaecptr resname, uae_u8 type, uae_s8 priority, uae_u16 ver, uae_u16 rev) +uaecptr makedatatable(uaecptr resid, uaecptr resname, uae_u8 type, uae_s8 priority, uae_u16 ver, uae_u16 rev) { - uaecptr datatable = here (); + uaecptr datatable = here(); - dw (0xE000); /* INITBYTE */ - dw (0x0008); /* LN_TYPE */ - dw (type << 8); - dw (0xE000); /* INITBYTE */ - dw (0x0009); /* LN_PRI */ - dw (priority << 8); - dw (0xC000); /* INITLONG */ - dw (0x000A); /* LN_NAME */ - dl (resname); - dw (0xE000); /* INITBYTE */ - dw (0x000E); /* LIB_FLAGS */ - dw (0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */ - dw (0xD000); /* INITWORD */ - dw (0x0014); /* LIB_VERSION */ - dw (ver); - dw (0xD000); /* INITWORD */ - dw (0x0016); /* LIB_REVISION */ - dw (rev); - dw (0xC000); /* INITLONG */ - dw (0x0018); /* LIB_IDSTRING */ - dl (resid); - dw (0x0000); /* end of table */ - return datatable; + dw(0xE000); /* INITBYTE */ + dw(0x0008); /* LN_TYPE */ + dw(type << 8); + dw(0xE000); /* INITBYTE */ + dw(0x0009); /* LN_PRI */ + dw(priority << 8); + dw(0xC000); /* INITLONG */ + dw(0x000A); /* LN_NAME */ + dl(resname); + dw(0xE000); /* INITBYTE */ + dw(0x000E); /* LIB_FLAGS */ + dw(0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */ + dw(0xD000); /* INITWORD */ + dw(0x0014); /* LIB_VERSION */ + dw(ver); + dw(0xD000); /* INITWORD */ + dw(0x0016); /* LIB_REVISION */ + dw(rev); + dw(0xC000); /* INITLONG */ + dw(0x0018); /* LIB_IDSTRING */ + dl(resid); + dw(0x0000); /* end of table */ + return datatable; } + diff --git a/src/blitfunc.cpp b/src/blitfunc.cpp index b17064db..468ffb61 100644 --- a/src/blitfunc.cpp +++ b/src/blitfunc.cpp @@ -1,2418 +1,1494 @@ #include "sysconfig.h" #include "sysdeps.h" -#include "config.h" -#include "uae.h" #include "options.h" -#include "include/memory.h" -#include "newcpu.h" #include "custom.h" -#include "savestate.h" +#include "include/memory.h" #include "blitter.h" #include "blitfunc.h" -/* - gno: optimized.. - notaz: too :) -*/ - void blitdofast_0 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - unsigned int i,j,hblitsize,bltdmod; - if (!ptd || !b->hblitsize) return; - hblitsize = b->hblitsize; - bltdmod = b->bltdmod; - j = b->vblitsize; - do - { - i = hblitsize; - do - { - chipmem_agnus_wput (ptd, 0); - ptd += 2; - } - while (--i); - ptd += bltdmod; - } - while (--j); +int i,j; +uae_u32 totald = 0; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = (0) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (ptd) ptd += b->bltdmod; +} + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_0 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - unsigned int i,j,hblitsize,bltdmod; - if (!ptd || !b->hblitsize) return; - hblitsize = b->hblitsize; - bltdmod = b->bltdmod; - j = b->vblitsize; - do - { - i = hblitsize; - do - { - chipmem_agnus_wput (ptd, 0); - ptd -= 2; - } - while (--i); - ptd -= bltdmod; - } - while (--j); +uae_u32 totald = 0; +int i,j; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = (0) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (ptd) ptd -= b->bltdmod; +} + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - unsigned int i,j; - uae_u32 totald = 0; - uae_u32 preva = 0; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 hblitsize = b->hblitsize; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - hblitsize; - if (!hblitsize) return; - for (j = b->vblitsize; j--;) - { - for (i = hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((~srca & srcc)); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = ((uae_u32(preva) << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((~srca & srcc)) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 hblitsize = b->hblitsize; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((~srca & srcc)); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = ((uae_u32(bltadat) << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((~srca & srcc)) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_2a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc & ~(srca & srcb))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = ((uae_u32(prevb) << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = ((uae_u32(preva) << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc & ~(srca & srcb))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_2a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc & ~(srca & srcb))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = ((uae_u32(bltadat) << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc & ~(srca & srcb))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_30 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srca & ~srcb)); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = ((uae_u32(prevb) << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = ((uae_u32(preva) << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srca & ~srcb)) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_30 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srca & ~srcb)); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = ((uae_u32(bltadat) << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srca & ~srcb)) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_3a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcb ^ (srca | (srcb ^ srcc)))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = ((uae_u32(prevb) << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = ((uae_u32(preva) << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcb ^ (srca | (srcb ^ srcc)))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_3a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcb ^ (srca | (srcb ^ srcc)))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcb ^ (srca | (srcb ^ srcc)))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_3c (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srca ^ srcb)); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srca ^ srcb)) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_3c (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srca ^ srcb)); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srca ^ srcb)) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_4a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc ^ (srca & (srcb | srcc)))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc ^ (srca & (srcb | srcc)))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_4a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc ^ (srca & (srcb | srcc)))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc ^ (srca & (srcb | srcc)))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_6a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc ^ (srca & srcb))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc ^ (srca & srcb))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_6a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc ^ (srca & srcb))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc ^ (srca & srcb))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_8a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc & (~srca | srcb))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc & (~srca | srcb))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_8a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc & (~srca | srcb))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc & (~srca | srcb))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_8c (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcb & (~srca | srcc))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcb & (~srca | srcc))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_8c (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcb & (~srca | srcc))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcb & (~srca | srcc))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_9a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc ^ (srca & ~srcb))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc ^ (srca & ~srcb))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_9a (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc ^ (srca & ~srcb))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc ^ (srca & ~srcb))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_a8 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc & (srca | srcb))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc & (srca | srcb))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_a8 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc & (srca | srcb))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc & (srca | srcb))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_aa (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 totald = 0; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = (srcc); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = (srcc) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_aa (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = (srcc); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = (srcc) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_b1 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = (~(srca ^ (srcc | (srca ^ srcb)))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = (~(srca ^ (srcc | (srca ^ srcb)))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_b1 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = (~(srca ^ (srcc | (srca ^ srcb)))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = (~(srca ^ (srcc | (srca ^ srcb)))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_ca (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc ^ (srca & (srcb ^ srcc)))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc ^ (srca & (srcb ^ srcc)))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_ca (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc ^ (srca & (srcb ^ srcc)))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc ^ (srca & (srcb ^ srcc)))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_cc (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 dstd=0; - uaecptr dstp = 0; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = (srcb); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (ptb) ptb += b->bltbmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = (srcb) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (ptb) ptb += b->bltbmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_cc (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 dstd=0; - uaecptr dstp = 0; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = (srcb); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (ptb) ptb -= b->bltbmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = (srcb) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (ptb) ptb -= b->bltbmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_d8 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srca ^ (srcc & (srca ^ srcb)))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srca ^ (srcc & (srca ^ srcb)))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_d8 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srca ^ (srcc & (srca ^ srcb)))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srca ^ (srcc & (srca ^ srcb)))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_e2 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc ^ (srcb & (srca ^ srcc)))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc ^ (srcb & (srca ^ srcc)))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_e2 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc ^ (srcb & (srca ^ srcc)))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc ^ (srcb & (srca ^ srcc)))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_ea (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc | (srca & srcb))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc | (srca & srcb))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_ea (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srcc | (srca & srcb))); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srcc | (srca & srcb))) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_f0 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0; - uae_u32 totald = 0; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = (srca); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptd) ptd += b->bltdmod; - } - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = (srca) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptd) ptd += b->bltdmod; +} + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_f0 (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = (srca); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptd) ptd -= b->bltdmod; - } - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = (srca) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptd) ptd -= b->bltdmod; +} + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_fa (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0; - uae_u32 totald = 0; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc += 2; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srca | srcc)); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptc) ptc += b->bltcmod; - if (ptd) ptd += b->bltdmod; - } - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srca | srcc)) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptc) ptc += b->bltcmod; + if (ptd) ptd += b->bltdmod; +} +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_fa (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0; - uae_u32 srcc = b->bltcdat; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptc) - { - srcc = do_get_mem_word ((uae_u16 *)ptc); - ptc -= 2; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srca | srcc)); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptc) ptc -= b->bltcmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltcdat = srcc; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 srcc = b->bltcdat; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srca | srcc)) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptc) ptc -= b->bltcmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltcdat = srcc; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_fc (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 totald = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; +int i,j; +uae_u32 totald = 0; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 dstd=0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb += 2; - srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta += 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srca | srcb)); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd += 2; - } - } - if (pta) pta += b->bltamod; - if (ptb) ptb += b->bltbmod; - if (ptd) ptd += b->bltdmod; - } - b->bltbhold = srcb; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2; + srcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srca | srcb)) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd += 2; } + } + if (pta) pta += b->bltamod; + if (ptb) ptb += b->bltbmod; + if (ptd) ptd += b->bltdmod; +} +b->bltbhold = srcb; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } void blitdofast_desc_fc (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b) { - uae_u32 totald = 0; - int i,j; - uae_u32 preva = 0, prevb = 0; - uae_u32 srcb = b->bltbhold; - uae_u32 dstd=0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - b->hblitsize; - for (j = b->vblitsize; j--;) - { - for (i = b->hblitsize; i--;) - { - uae_u32 bltadat, srca; - if (ptb) - { - uae_u32 bltbdat; - b->bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)ptb); - ptb -= 2; - srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; - prevb = bltbdat; - } - if (pta) - { - b->bltadat = bltadat = do_get_mem_word ((uae_u16 *)pta); - pta -= 2; - } - else - { - bltadat = b->bltadat; - } - bltadat &= blit_masktable_p[i]; - srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; - preva = bltadat; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - dstd = ((srca | srcb)); - totald |= dstd; - if (ptd) - { - dstp = ptd; - ptd -= 2; - } - } - if (pta) pta -= b->bltamod; - if (ptb) ptb -= b->bltbmod; - if (ptd) ptd -= b->bltdmod; - } - b->bltbhold = srcb; - if (dstp) - chipmem_agnus_wput (dstp, dstd); - if ((totald<<16) != 0) b->blitzero = 0; +uae_u32 totald = 0; +int i,j; +uae_u32 preva = 0; +uae_u32 prevb = 0, srcb = b->bltbhold; +uae_u32 dstd = 0; +uaecptr dstp = 0; +for (j = 0; j < b->vblitsize; j++) { + for (i = 0; i < b->hblitsize; i++) { + uae_u32 bltadat, srca; + if (ptb) { + uae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2; + srcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift; + prevb = bltbdat; + } + if (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; } + bltadat &= blit_masktable[i]; + srca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift; + preva = bltadat; + if (dstp) chipmem_wput_indirect (dstp, dstd); + dstd = ((srca | srcb)) & 0xFFFF; + totald |= dstd; + if (ptd) { dstp = ptd; ptd -= 2; } + } + if (pta) pta -= b->bltamod; + if (ptb) ptb -= b->bltbmod; + if (ptd) ptd -= b->bltdmod; +} +b->bltbhold = srcb; + if (dstp) chipmem_wput_indirect (dstp, dstd); +if (totald != 0) b->blitzero = 0; } - diff --git a/src/blitops.cpp b/src/blitops.cpp index 3060a08e..eb2142db 100644 --- a/src/blitops.cpp +++ b/src/blitops.cpp @@ -1,263 +1,262 @@ -/* This file generated automatically - do not edit */ + /* This file generated automatically - do not edit */ #include "genblitter.h" -struct blitop blitops[256] = -{ - /* 00 */ { "0", 0 }, - /* 01 */ { "~(srca | srcb | srcc)", 7 }, - /* 02 */ { "(srcc & ~(srca | srcb))", 7 }, - /* 03 */ { "~(srca | srcb)", 3 }, - /* 04 */ { "(srcb & ~(srca | srcc))", 7 }, - /* 05 */ { "~(srca | srcc)", 5 }, - /* 06 */ { "(~srca & (srcb ^ srcc))", 7 }, - /* 07 */ { "~(srca | (srcb & srcc))", 7 }, - /* 08 */ { "(~srca & srcb & srcc)", 7 }, - /* 09 */ { "~(srca | (srcb ^ srcc))", 7 }, - /* 0a */ { "(~srca & srcc)", 5 }, - /* 0b */ { "~(srca | (srcb & ~srcc))", 7 }, - /* 0c */ { "(~srca & srcb)", 3 }, - /* 0d */ { "~(srca | (~srcb & srcc))", 7 }, - /* 0e */ { "(~srca & (srcb | srcc))", 7 }, - /* 0f */ { "~srca", 1 }, - /* 10 */ { "(srca & ~(srcb | srcc))", 7 }, - /* 11 */ { "~(srcb | srcc)", 6 }, - /* 12 */ { "(~srcb & (srca ^ srcc))", 7 }, - /* 13 */ { "~(srcb | (srca & srcc))", 7 }, - /* 14 */ { "(~srcc & (srca ^ srcb))", 7 }, - /* 15 */ { "~(srcc | (srca & srcb))", 7 }, - /* 16 */ { "(srca ^ ((srca & srcb) | (srcb ^ srcc)))", 7 }, - /* 17 */ { "~(srca ^ ((srca ^ srcb) & (srca ^ srcc)))", 7 }, - /* 18 */ { "((srca ^ srcb) & (srca ^ srcc))", 7 }, - /* 19 */ { "(srcb ^ (~srcc | (srca & srcb)))", 7 }, - /* 1a */ { "(srca ^ (srcc | (srca & srcb)))", 7 }, - /* 1b */ { "(srca ^ (srcc | ~(srca ^ srcb)))", 7 }, - /* 1c */ { "(srca ^ (srcb | (srca & srcc)))", 7 }, - /* 1d */ { "(srca ^ (srcb | ~(srca ^ srcc)))", 7 }, - /* 1e */ { "(srca ^ (srcb | srcc))", 7 }, - /* 1f */ { "~(srca & (srcb | srcc))", 7 }, - /* 20 */ { "(srca & ~srcb & srcc)", 7 }, - /* 21 */ { "~(srcb | (srca ^ srcc))", 7 }, - /* 22 */ { "(~srcb & srcc)", 6 }, - /* 23 */ { "~(srcb | (srca & ~srcc))", 7 }, - /* 24 */ { "((srca ^ srcb) & (srcb ^ srcc))", 7 }, - /* 25 */ { "(srca ^ (~srcc | (srca & srcb)))", 7 }, - /* 26 */ { "(srcb ^ (srcc | (srca & srcb)))", 7 }, - /* 27 */ { "~(srca ^ (srcc & (srca ^ srcb)))", 7 }, - /* 28 */ { "(srcc & (srca ^ srcb))", 7 }, - /* 29 */ { "~(srca ^ srcb ^ (srcc | (srca & srcb)))", 7 }, - /* 2a */ { "(srcc & ~(srca & srcb))", 7 }, - /* 2b */ { "~(srca ^ ((srca ^ srcb) & (srcb ^ srcc)))", 7 }, - /* 2c */ { "(srcb ^ (srca & (srcb | srcc)))", 7 }, - /* 2d */ { "(srca ^ (srcb | ~srcc))", 7 }, - /* 2e */ { "(srca ^ (srcb | (srca ^ srcc)))", 7 }, - /* 2f */ { "~(srca & (srcb | ~srcc))", 7 }, - /* 30 */ { "(srca & ~srcb)", 3 }, - /* 31 */ { "~(srcb | (~srca & srcc))", 7 }, - /* 32 */ { "(~srcb & (srca | srcc))", 7 }, - /* 33 */ { "~srcb", 2 }, - /* 34 */ { "(srcb ^ (srca | (srcb & srcc)))", 7 }, - /* 35 */ { "(srcb ^ (srca | ~(srcb ^ srcc)))", 7 }, - /* 36 */ { "(srcb ^ (srca | srcc))", 7 }, - /* 37 */ { "~(srcb & (srca | srcc))", 7 }, - /* 38 */ { "(srca ^ (srcb & (srca | srcc)))", 7 }, - /* 39 */ { "(srcb ^ (srca | ~srcc))", 7 }, - /* 3a */ { "(srcb ^ (srca | (srcb ^ srcc)))", 7 }, - /* 3b */ { "~(srcb & (srca | ~srcc))", 7 }, - /* 3c */ { "(srca ^ srcb)", 3 }, - /* 3d */ { "(srca ^ (srcb | ~(srca | srcc)))", 7 }, - /* 3e */ { "(srca ^ (srcb | (srca ^ (srca | srcc))))", 7 }, - /* 3f */ { "~(srca & srcb)", 3 }, - /* 40 */ { "(srca & srcb & ~srcc)", 7 }, - /* 41 */ { "~(srcc | (srca ^ srcb))", 7 }, - /* 42 */ { "((srca ^ srcc) & (srcb ^ srcc))", 7 }, - /* 43 */ { "(srca ^ (~srcb | (srca & srcc)))", 7 }, - /* 44 */ { "(srcb & ~srcc)", 6 }, - /* 45 */ { "~(srcc | (srca & ~srcb))", 7 }, - /* 46 */ { "(srcc ^ (srcb | (srca & srcc)))", 7 }, - /* 47 */ { "~(srca ^ (srcb & (srca ^ srcc)))", 7 }, - /* 48 */ { "(srcb & (srca ^ srcc))", 7 }, - /* 49 */ { "~(srca ^ srcc ^ (srcb | (srca & srcc)))", 7 }, - /* 4a */ { "(srcc ^ (srca & (srcb | srcc)))", 7 }, - /* 4b */ { "(srca ^ (~srcb | srcc))", 7 }, - /* 4c */ { "(srcb & ~(srca & srcc))", 7 }, - /* 4d */ { "(srca ^ ((srca ^ srcb) | ~(srca ^ srcc)))", 7 }, - /* 4e */ { "(srca ^ (srcc | (srca ^ srcb)))", 7 }, - /* 4f */ { "~(srca & (~srcb | srcc))", 7 }, - /* 50 */ { "(srca & ~srcc)", 5 }, - /* 51 */ { "~(srcc | (~srca & srcb))", 7 }, - /* 52 */ { "(srcc ^ (srca | (srcb & srcc)))", 7 }, - /* 53 */ { "~(srcb ^ (srca & (srcb ^ srcc)))", 7 }, - /* 54 */ { "(~srcc & (srca | srcb))", 7 }, - /* 55 */ { "~srcc", 4 }, - /* 56 */ { "(srcc ^ (srca | srcb))", 7 }, - /* 57 */ { "~(srcc & (srca | srcb))", 7 }, - /* 58 */ { "(srca ^ (srcc & (srca | srcb)))", 7 }, - /* 59 */ { "(srcc ^ (srca | ~srcb))", 7 }, - /* 5a */ { "(srca ^ srcc)", 5 }, - /* 5b */ { "(srca ^ (srcc | ~(srca | srcb)))", 7 }, - /* 5c */ { "(srcc ^ (srca | (srcb ^ srcc)))", 7 }, - /* 5d */ { "~(srcc & (srca | ~srcb))", 7 }, - /* 5e */ { "(srca ^ (srcc | (srca ^ (srca | srcb))))", 7 }, - /* 5f */ { "~(srca & srcc)", 5 }, - /* 60 */ { "(srca & (srcb ^ srcc))", 7 }, - /* 61 */ { "~(srcb ^ srcc ^ (srca | (srcb & srcc)))", 7 }, - /* 62 */ { "(srcc ^ (srcb & (srca | srcc)))", 7 }, - /* 63 */ { "(srcb ^ (~srca | srcc))", 7 }, - /* 64 */ { "(srcb ^ (srcc & (srca | srcb)))", 7 }, - /* 65 */ { "(srcc ^ (~srca | srcb))", 7 }, - /* 66 */ { "(srcb ^ srcc)", 6 }, - /* 67 */ { "(srcb ^ (srcc | ~(srca | srcb)))", 7 }, - /* 68 */ { "((srca & srcb) ^ (srcc & (srca | srcb)))", 7 }, - /* 69 */ { "~(srca ^ srcb ^ srcc)", 7 }, - /* 6a */ { "(srcc ^ (srca & srcb))", 7 }, - /* 6b */ { "~(srca ^ srcb ^ (srcc & (srca | srcb)))", 7 }, - /* 6c */ { "(srcb ^ (srca & srcc))", 7 }, - /* 6d */ { "~(srca ^ srcc ^ (srcb & (srca | srcc)))", 7 }, - /* 6e */ { "((~srca & srcb) | (srcb ^ srcc))", 7 }, - /* 6f */ { "(~srca | (srcb ^ srcc))", 7 }, - /* 70 */ { "(srca & ~(srcb & srcc))", 7 }, - /* 71 */ { "~(srca ^ ((srca ^ srcb) | (srca ^ srcc)))", 7 }, - /* 72 */ { "(srcb ^ (srcc | (srca ^ srcb)))", 7 }, - /* 73 */ { "~(srcb & (~srca | srcc))", 7 }, - /* 74 */ { "(srcc ^ (srcb | (srca ^ srcc)))", 7 }, - /* 75 */ { "~(srcc & (~srca | srcb))", 7 }, - /* 76 */ { "(srcb ^ (srcc | (srca ^ (srca & srcb))))", 7 }, - /* 77 */ { "~(srcb & srcc)", 6 }, - /* 78 */ { "(srca ^ (srcb & srcc))", 7 }, - /* 79 */ { "~(srcb ^ srcc ^ (srca & (srcb | srcc)))", 7 }, - /* 7a */ { "((srca & ~srcb) | (srca ^ srcc))", 7 }, - /* 7b */ { "(~srcb | (srca ^ srcc))", 7 }, - /* 7c */ { "((srca ^ srcb) | (srca & ~srcc))", 7 }, - /* 7d */ { "(~srcc | (srca ^ srcb))", 7 }, - /* 7e */ { "((srca ^ srcb) | (srca ^ srcc))", 7 }, - /* 7f */ { "~(srca & srcb & srcc)", 7 }, - /* 80 */ { "(srca & srcb & srcc)", 7 }, - /* 81 */ { "~((srca ^ srcb) | (srca ^ srcc))", 7 }, - /* 82 */ { "(srcc & ~(srca ^ srcb))", 7 }, - /* 83 */ { "(srca ^ (~srcb | (srca & ~srcc)))", 7 }, - /* 84 */ { "(srcb & ~(srca ^ srcc))", 7 }, - /* 85 */ { "(srca ^ (~srcc | (srca & ~srcb)))", 7 }, - /* 86 */ { "(srcb ^ srcc ^ (srca & (srcb | srcc)))", 7 }, - /* 87 */ { "~(srca ^ (srcb & srcc))", 7 }, - /* 88 */ { "(srcb & srcc)", 6 }, - /* 89 */ { "(srcb ^ (~srcc & (~srca | srcb)))", 7 }, - /* 8a */ { "(srcc & (~srca | srcb))", 7 }, - /* 8b */ { "(srca ^ (~srcb | (srca ^ srcc)))", 7 }, - /* 8c */ { "(srcb & (~srca | srcc))", 7 }, - /* 8d */ { "(srca ^ (~srcc | (srca ^ srcb)))", 7 }, - /* 8e */ { "(srca ^ ((srca ^ srcb) | (srca ^ srcc)))", 7 }, - /* 8f */ { "(~srca | (srcb & srcc))", 7 }, - /* 90 */ { "(srca & ~(srcb ^ srcc))", 7 }, - /* 91 */ { "(srcb ^ (~srcc | (~srca & srcb)))", 7 }, - /* 92 */ { "(srca ^ srcc ^ (srcb & (srca | srcc)))", 7 }, - /* 93 */ { "~(srcb ^ (srca & srcc))", 7 }, - /* 94 */ { "(srca ^ srcb ^ (srcc & (srca | srcb)))", 7 }, - /* 95 */ { "~(srcc ^ (srca & srcb))", 7 }, - /* 96 */ { "(srca ^ srcb ^ srcc)", 7 }, - /* 97 */ { "(srca ^ srcb ^ (srcc | ~(srca | srcb)))", 7 }, - /* 98 */ { "(srcb ^ (~srcc & (srca | srcb)))", 7 }, - /* 99 */ { "~(srcb ^ srcc)", 6 }, - /* 9a */ { "(srcc ^ (srca & ~srcb))", 7 }, - /* 9b */ { "~(srcb ^ (srcc & (srca | srcb)))", 7 }, - /* 9c */ { "(srcb ^ (srca & ~srcc))", 7 }, - /* 9d */ { "~(srcc ^ (srcb & (srca | srcc)))", 7 }, - /* 9e */ { "(srcb ^ srcc ^ (srca | (srcb & srcc)))", 7 }, - /* 9f */ { "~(srca & (srcb ^ srcc))", 7 }, - /* a0 */ { "(srca & srcc)", 5 }, - /* a1 */ { "(srca ^ (~srcc & (srca | ~srcb)))", 7 }, - /* a2 */ { "(srcc & (srca | ~srcb))", 7 }, - /* a3 */ { "(srcb ^ (~srca | (srcb ^ srcc)))", 7 }, - /* a4 */ { "(srca ^ (~srcc & (srca | srcb)))", 7 }, - /* a5 */ { "~(srca ^ srcc)", 5 }, - /* a6 */ { "(srcc ^ (~srca & srcb))", 7 }, - /* a7 */ { "~(srca ^ (srcc & (srca | srcb)))", 7 }, - /* a8 */ { "(srcc & (srca | srcb))", 7 }, - /* a9 */ { "~(srcc ^ (srca | srcb))", 7 }, - /* aa */ { "srcc", 4 }, - /* ab */ { "(srcc | ~(srca | srcb))", 7 }, - /* ac */ { "(srcb ^ (srca & (srcb ^ srcc)))", 7 }, - /* ad */ { "~(srcc ^ (srca | (srcb & srcc)))", 7 }, - /* ae */ { "(srcc | (~srca & srcb))", 7 }, - /* af */ { "(~srca | srcc)", 5 }, - /* b0 */ { "(srca & (~srcb | srcc))", 7 }, - /* b1 */ { "~(srca ^ (srcc | (srca ^ srcb)))", 7 }, - /* b2 */ { "(srca ^ ((srca ^ srcc) & (srcb ^ srcc)))", 7 }, - /* b3 */ { "(~srcb | (srca & srcc))", 7 }, - /* b4 */ { "(srca ^ (srcb & ~srcc))", 7 }, - /* b5 */ { "~(srcc ^ (srca & (srcb | srcc)))", 7 }, - /* b6 */ { "(srca ^ srcc ^ (srcb | (srca & srcc)))", 7 }, - /* b7 */ { "~(srcb & (srca ^ srcc))", 7 }, - /* b8 */ { "(srca ^ (srcb & (srca ^ srcc)))", 7 }, - /* b9 */ { "~(srcc ^ (srcb | (srca & srcc)))", 7 }, - /* ba */ { "(srcc | (srca & ~srcb))", 7 }, - /* bb */ { "(~srcb | srcc)", 6 }, - /* bc */ { "((srca ^ srcb) | (srca & srcc))", 7 }, - /* bd */ { "((srca ^ srcb) | ~(srca ^ srcc))", 7 }, - /* be */ { "(srcc | (srca ^ srcb))", 7 }, - /* bf */ { "(srcc | ~(srca & srcb))", 7 }, - /* c0 */ { "(srca & srcb)", 3 }, - /* c1 */ { "(srca ^ (~srcb & (srca | ~srcc)))", 7 }, - /* c2 */ { "(srca ^ (~srcb & (srca | srcc)))", 7 }, - /* c3 */ { "~(srca ^ srcb)", 3 }, - /* c4 */ { "(srcb & (srca | ~srcc))", 7 }, - /* c5 */ { "~(srcb ^ (srca | (srcb ^ srcc)))", 7 }, - /* c6 */ { "(srcb ^ (~srca & srcc))", 7 }, - /* c7 */ { "~(srca ^ (srcb & (srca | srcc)))", 7 }, - /* c8 */ { "(srcb & (srca | srcc))", 7 }, - /* c9 */ { "~(srcb ^ (srca | srcc))", 7 }, - /* ca */ { "(srcc ^ (srca & (srcb ^ srcc)))", 7 }, - /* cb */ { "~(srcb ^ (srca | (srcb & srcc)))", 7 }, - /* cc */ { "srcb", 2 }, - /* cd */ { "(srcb | ~(srca | srcc))", 7 }, - /* ce */ { "(srcb | (~srca & srcc))", 7 }, - /* cf */ { "(~srca | srcb)", 3 }, - /* d0 */ { "(srca & (srcb | ~srcc))", 7 }, - /* d1 */ { "~(srca ^ (srcb | (srca ^ srcc)))", 7 }, - /* d2 */ { "(srca ^ (~srcb & srcc))", 7 }, - /* d3 */ { "~(srcb ^ (srca & (srcb | srcc)))", 7 }, - /* d4 */ { "(srca ^ ((srca ^ srcb) & (srcb ^ srcc)))", 7 }, - /* d5 */ { "(~srcc | (srca & srcb))", 7 }, - /* d6 */ { "(srca ^ srcb ^ (srcc | (srca & srcb)))", 7 }, - /* d7 */ { "~(srcc & (srca ^ srcb))", 7 }, - /* d8 */ { "(srca ^ (srcc & (srca ^ srcb)))", 7 }, - /* d9 */ { "~(srcb ^ (srcc | (srca & srcb)))", 7 }, - /* da */ { "((srca & srcb) | (srca ^ srcc))", 7 }, - /* db */ { "~((srca ^ srcb) & (srcb ^ srcc))", 7 }, - /* dc */ { "(srcb | (srca & ~srcc))", 7 }, - /* dd */ { "(srcb | ~srcc)", 6 }, - /* de */ { "(srcb | (srca ^ srcc))", 7 }, - /* df */ { "(srcb | ~(srca & srcc))", 7 }, - /* e0 */ { "(srca & (srcb | srcc))", 7 }, - /* e1 */ { "~(srca ^ (srcb | srcc))", 7 }, - /* e2 */ { "(srcc ^ (srcb & (srca ^ srcc)))", 7 }, - /* e3 */ { "~(srca ^ (srcb | (srca & srcc)))", 7 }, - /* e4 */ { "(srcb ^ (srcc & (srca ^ srcb)))", 7 }, - /* e5 */ { "~(srca ^ (srcc | (srca & srcb)))", 7 }, - /* e6 */ { "((srca & srcb) | (srcb ^ srcc))", 7 }, - /* e7 */ { "~((srca ^ srcb) & (srca ^ srcc))", 7 }, - /* e8 */ { "(srca ^ ((srca ^ srcb) & (srca ^ srcc)))", 7 }, - /* e9 */ { "(srca ^ srcb ^ (~srcc | (srca & srcb)))", 7 }, - /* ea */ { "(srcc | (srca & srcb))", 7 }, - /* eb */ { "(srcc | ~(srca ^ srcb))", 7 }, - /* ec */ { "(srcb | (srca & srcc))", 7 }, - /* ed */ { "(srcb | ~(srca ^ srcc))", 7 }, - /* ee */ { "(srcb | srcc)", 6 }, - /* ef */ { "(~srca | srcb | srcc)", 7 }, - /* f0 */ { "srca", 1 }, - /* f1 */ { "(srca | ~(srcb | srcc))", 7 }, - /* f2 */ { "(srca | (~srcb & srcc))", 7 }, - /* f3 */ { "(srca | ~srcb)", 3 }, - /* f4 */ { "(srca | (srcb & ~srcc))", 7 }, - /* f5 */ { "(srca | ~srcc)", 5 }, - /* f6 */ { "(srca | (srcb ^ srcc))", 7 }, - /* f7 */ { "(srca | ~(srcb & srcc))", 7 }, - /* f8 */ { "(srca | (srcb & srcc))", 7 }, - /* f9 */ { "(srca | ~(srcb ^ srcc))", 7 }, - /* fa */ { "(srca | srcc)", 5 }, - /* fb */ { "(srca | ~srcb | srcc)", 7 }, - /* fc */ { "(srca | srcb)", 3 }, - /* fd */ { "(srca | srcb | ~srcc)", 7 }, - /* fe */ { "(srca | srcb | srcc)", 7 }, - /* ff */ { "0xFFFFFFFF", 0 } +struct blitop blitops[256] = { + /* 00 */ { "0", 0 }, + /* 01 */ { "~(srca | srcb | srcc)", 7 }, + /* 02 */ { "(srcc & ~(srca | srcb))", 7 }, + /* 03 */ { "~(srca | srcb)", 3 }, + /* 04 */ { "(srcb & ~(srca | srcc))", 7 }, + /* 05 */ { "~(srca | srcc)", 5 }, + /* 06 */ { "(~srca & (srcb ^ srcc))", 7 }, + /* 07 */ { "~(srca | (srcb & srcc))", 7 }, + /* 08 */ { "(~srca & srcb & srcc)", 7 }, + /* 09 */ { "~(srca | (srcb ^ srcc))", 7 }, + /* 0a */ { "(~srca & srcc)", 5 }, + /* 0b */ { "~(srca | (srcb & ~srcc))", 7 }, + /* 0c */ { "(~srca & srcb)", 3 }, + /* 0d */ { "~(srca | (~srcb & srcc))", 7 }, + /* 0e */ { "(~srca & (srcb | srcc))", 7 }, + /* 0f */ { "~srca", 1 }, + /* 10 */ { "(srca & ~(srcb | srcc))", 7 }, + /* 11 */ { "~(srcb | srcc)", 6 }, + /* 12 */ { "(~srcb & (srca ^ srcc))", 7 }, + /* 13 */ { "~(srcb | (srca & srcc))", 7 }, + /* 14 */ { "(~srcc & (srca ^ srcb))", 7 }, + /* 15 */ { "~(srcc | (srca & srcb))", 7 }, + /* 16 */ { "(srca ^ ((srca & srcb) | (srcb ^ srcc)))", 7 }, + /* 17 */ { "~(srca ^ ((srca ^ srcb) & (srca ^ srcc)))", 7 }, + /* 18 */ { "((srca ^ srcb) & (srca ^ srcc))", 7 }, + /* 19 */ { "(srcb ^ (~srcc | (srca & srcb)))", 7 }, + /* 1a */ { "(srca ^ (srcc | (srca & srcb)))", 7 }, + /* 1b */ { "(srca ^ (srcc | ~(srca ^ srcb)))", 7 }, + /* 1c */ { "(srca ^ (srcb | (srca & srcc)))", 7 }, + /* 1d */ { "(srca ^ (srcb | ~(srca ^ srcc)))", 7 }, + /* 1e */ { "(srca ^ (srcb | srcc))", 7 }, + /* 1f */ { "~(srca & (srcb | srcc))", 7 }, + /* 20 */ { "(srca & ~srcb & srcc)", 7 }, + /* 21 */ { "~(srcb | (srca ^ srcc))", 7 }, + /* 22 */ { "(~srcb & srcc)", 6 }, + /* 23 */ { "~(srcb | (srca & ~srcc))", 7 }, + /* 24 */ { "((srca ^ srcb) & (srcb ^ srcc))", 7 }, + /* 25 */ { "(srca ^ (~srcc | (srca & srcb)))", 7 }, + /* 26 */ { "(srcb ^ (srcc | (srca & srcb)))", 7 }, + /* 27 */ { "~(srca ^ (srcc & (srca ^ srcb)))", 7 }, + /* 28 */ { "(srcc & (srca ^ srcb))", 7 }, + /* 29 */ { "~(srca ^ srcb ^ (srcc | (srca & srcb)))", 7 }, + /* 2a */ { "(srcc & ~(srca & srcb))", 7 }, + /* 2b */ { "~(srca ^ ((srca ^ srcb) & (srcb ^ srcc)))", 7 }, + /* 2c */ { "(srcb ^ (srca & (srcb | srcc)))", 7 }, + /* 2d */ { "(srca ^ (srcb | ~srcc))", 7 }, + /* 2e */ { "(srca ^ (srcb | (srca ^ srcc)))", 7 }, + /* 2f */ { "~(srca & (srcb | ~srcc))", 7 }, + /* 30 */ { "(srca & ~srcb)", 3 }, + /* 31 */ { "~(srcb | (~srca & srcc))", 7 }, + /* 32 */ { "(~srcb & (srca | srcc))", 7 }, + /* 33 */ { "~srcb", 2 }, + /* 34 */ { "(srcb ^ (srca | (srcb & srcc)))", 7 }, + /* 35 */ { "(srcb ^ (srca | ~(srcb ^ srcc)))", 7 }, + /* 36 */ { "(srcb ^ (srca | srcc))", 7 }, + /* 37 */ { "~(srcb & (srca | srcc))", 7 }, + /* 38 */ { "(srca ^ (srcb & (srca | srcc)))", 7 }, + /* 39 */ { "(srcb ^ (srca | ~srcc))", 7 }, + /* 3a */ { "(srcb ^ (srca | (srcb ^ srcc)))", 7 }, + /* 3b */ { "~(srcb & (srca | ~srcc))", 7 }, + /* 3c */ { "(srca ^ srcb)", 3 }, + /* 3d */ { "(srca ^ (srcb | ~(srca | srcc)))", 7 }, + /* 3e */ { "(srca ^ (srcb | (srca ^ (srca | srcc))))", 7 }, + /* 3f */ { "~(srca & srcb)", 3 }, + /* 40 */ { "(srca & srcb & ~srcc)", 7 }, + /* 41 */ { "~(srcc | (srca ^ srcb))", 7 }, + /* 42 */ { "((srca ^ srcc) & (srcb ^ srcc))", 7 }, + /* 43 */ { "(srca ^ (~srcb | (srca & srcc)))", 7 }, + /* 44 */ { "(srcb & ~srcc)", 6 }, + /* 45 */ { "~(srcc | (srca & ~srcb))", 7 }, + /* 46 */ { "(srcc ^ (srcb | (srca & srcc)))", 7 }, + /* 47 */ { "~(srca ^ (srcb & (srca ^ srcc)))", 7 }, + /* 48 */ { "(srcb & (srca ^ srcc))", 7 }, + /* 49 */ { "~(srca ^ srcc ^ (srcb | (srca & srcc)))", 7 }, + /* 4a */ { "(srcc ^ (srca & (srcb | srcc)))", 7 }, + /* 4b */ { "(srca ^ (~srcb | srcc))", 7 }, + /* 4c */ { "(srcb & ~(srca & srcc))", 7 }, + /* 4d */ { "(srca ^ ((srca ^ srcb) | ~(srca ^ srcc)))", 7 }, + /* 4e */ { "(srca ^ (srcc | (srca ^ srcb)))", 7 }, + /* 4f */ { "~(srca & (~srcb | srcc))", 7 }, + /* 50 */ { "(srca & ~srcc)", 5 }, + /* 51 */ { "~(srcc | (~srca & srcb))", 7 }, + /* 52 */ { "(srcc ^ (srca | (srcb & srcc)))", 7 }, + /* 53 */ { "~(srcb ^ (srca & (srcb ^ srcc)))", 7 }, + /* 54 */ { "(~srcc & (srca | srcb))", 7 }, + /* 55 */ { "~srcc", 4 }, + /* 56 */ { "(srcc ^ (srca | srcb))", 7 }, + /* 57 */ { "~(srcc & (srca | srcb))", 7 }, + /* 58 */ { "(srca ^ (srcc & (srca | srcb)))", 7 }, + /* 59 */ { "(srcc ^ (srca | ~srcb))", 7 }, + /* 5a */ { "(srca ^ srcc)", 5 }, + /* 5b */ { "(srca ^ (srcc | ~(srca | srcb)))", 7 }, + /* 5c */ { "(srcc ^ (srca | (srcb ^ srcc)))", 7 }, + /* 5d */ { "~(srcc & (srca | ~srcb))", 7 }, + /* 5e */ { "(srca ^ (srcc | (srca ^ (srca | srcb))))", 7 }, + /* 5f */ { "~(srca & srcc)", 5 }, + /* 60 */ { "(srca & (srcb ^ srcc))", 7 }, + /* 61 */ { "~(srcb ^ srcc ^ (srca | (srcb & srcc)))", 7 }, + /* 62 */ { "(srcc ^ (srcb & (srca | srcc)))", 7 }, + /* 63 */ { "(srcb ^ (~srca | srcc))", 7 }, + /* 64 */ { "(srcb ^ (srcc & (srca | srcb)))", 7 }, + /* 65 */ { "(srcc ^ (~srca | srcb))", 7 }, + /* 66 */ { "(srcb ^ srcc)", 6 }, + /* 67 */ { "(srcb ^ (srcc | ~(srca | srcb)))", 7 }, + /* 68 */ { "((srca & srcb) ^ (srcc & (srca | srcb)))", 7 }, + /* 69 */ { "~(srca ^ srcb ^ srcc)", 7 }, + /* 6a */ { "(srcc ^ (srca & srcb))", 7 }, + /* 6b */ { "~(srca ^ srcb ^ (srcc & (srca | srcb)))", 7 }, + /* 6c */ { "(srcb ^ (srca & srcc))", 7 }, + /* 6d */ { "~(srca ^ srcc ^ (srcb & (srca | srcc)))", 7 }, + /* 6e */ { "((~srca & srcb) | (srcb ^ srcc))", 7 }, + /* 6f */ { "(~srca | (srcb ^ srcc))", 7 }, + /* 70 */ { "(srca & ~(srcb & srcc))", 7 }, + /* 71 */ { "~(srca ^ ((srca ^ srcb) | (srca ^ srcc)))", 7 }, + /* 72 */ { "(srcb ^ (srcc | (srca ^ srcb)))", 7 }, + /* 73 */ { "~(srcb & (~srca | srcc))", 7 }, + /* 74 */ { "(srcc ^ (srcb | (srca ^ srcc)))", 7 }, + /* 75 */ { "~(srcc & (~srca | srcb))", 7 }, + /* 76 */ { "(srcb ^ (srcc | (srca ^ (srca & srcb))))", 7 }, + /* 77 */ { "~(srcb & srcc)", 6 }, + /* 78 */ { "(srca ^ (srcb & srcc))", 7 }, + /* 79 */ { "~(srcb ^ srcc ^ (srca & (srcb | srcc)))", 7 }, + /* 7a */ { "((srca & ~srcb) | (srca ^ srcc))", 7 }, + /* 7b */ { "(~srcb | (srca ^ srcc))", 7 }, + /* 7c */ { "((srca ^ srcb) | (srca & ~srcc))", 7 }, + /* 7d */ { "(~srcc | (srca ^ srcb))", 7 }, + /* 7e */ { "((srca ^ srcb) | (srca ^ srcc))", 7 }, + /* 7f */ { "~(srca & srcb & srcc)", 7 }, + /* 80 */ { "(srca & srcb & srcc)", 7 }, + /* 81 */ { "~((srca ^ srcb) | (srca ^ srcc))", 7 }, + /* 82 */ { "(srcc & ~(srca ^ srcb))", 7 }, + /* 83 */ { "(srca ^ (~srcb | (srca & ~srcc)))", 7 }, + /* 84 */ { "(srcb & ~(srca ^ srcc))", 7 }, + /* 85 */ { "(srca ^ (~srcc | (srca & ~srcb)))", 7 }, + /* 86 */ { "(srcb ^ srcc ^ (srca & (srcb | srcc)))", 7 }, + /* 87 */ { "~(srca ^ (srcb & srcc))", 7 }, + /* 88 */ { "(srcb & srcc)", 6 }, + /* 89 */ { "(srcb ^ (~srcc & (~srca | srcb)))", 7 }, + /* 8a */ { "(srcc & (~srca | srcb))", 7 }, + /* 8b */ { "(srca ^ (~srcb | (srca ^ srcc)))", 7 }, + /* 8c */ { "(srcb & (~srca | srcc))", 7 }, + /* 8d */ { "(srca ^ (~srcc | (srca ^ srcb)))", 7 }, + /* 8e */ { "(srca ^ ((srca ^ srcb) | (srca ^ srcc)))", 7 }, + /* 8f */ { "(~srca | (srcb & srcc))", 7 }, + /* 90 */ { "(srca & ~(srcb ^ srcc))", 7 }, + /* 91 */ { "(srcb ^ (~srcc | (~srca & srcb)))", 7 }, + /* 92 */ { "(srca ^ srcc ^ (srcb & (srca | srcc)))", 7 }, + /* 93 */ { "~(srcb ^ (srca & srcc))", 7 }, + /* 94 */ { "(srca ^ srcb ^ (srcc & (srca | srcb)))", 7 }, + /* 95 */ { "~(srcc ^ (srca & srcb))", 7 }, + /* 96 */ { "(srca ^ srcb ^ srcc)", 7 }, + /* 97 */ { "(srca ^ srcb ^ (srcc | ~(srca | srcb)))", 7 }, + /* 98 */ { "(srcb ^ (~srcc & (srca | srcb)))", 7 }, + /* 99 */ { "~(srcb ^ srcc)", 6 }, + /* 9a */ { "(srcc ^ (srca & ~srcb))", 7 }, + /* 9b */ { "~(srcb ^ (srcc & (srca | srcb)))", 7 }, + /* 9c */ { "(srcb ^ (srca & ~srcc))", 7 }, + /* 9d */ { "~(srcc ^ (srcb & (srca | srcc)))", 7 }, + /* 9e */ { "(srcb ^ srcc ^ (srca | (srcb & srcc)))", 7 }, + /* 9f */ { "~(srca & (srcb ^ srcc))", 7 }, + /* a0 */ { "(srca & srcc)", 5 }, + /* a1 */ { "(srca ^ (~srcc & (srca | ~srcb)))", 7 }, + /* a2 */ { "(srcc & (srca | ~srcb))", 7 }, + /* a3 */ { "(srcb ^ (~srca | (srcb ^ srcc)))", 7 }, + /* a4 */ { "(srca ^ (~srcc & (srca | srcb)))", 7 }, + /* a5 */ { "~(srca ^ srcc)", 5 }, + /* a6 */ { "(srcc ^ (~srca & srcb))", 7 }, + /* a7 */ { "~(srca ^ (srcc & (srca | srcb)))", 7 }, + /* a8 */ { "(srcc & (srca | srcb))", 7 }, + /* a9 */ { "~(srcc ^ (srca | srcb))", 7 }, + /* aa */ { "srcc", 4 }, + /* ab */ { "(srcc | ~(srca | srcb))", 7 }, + /* ac */ { "(srcb ^ (srca & (srcb ^ srcc)))", 7 }, + /* ad */ { "~(srcc ^ (srca | (srcb & srcc)))", 7 }, + /* ae */ { "(srcc | (~srca & srcb))", 7 }, + /* af */ { "(~srca | srcc)", 5 }, + /* b0 */ { "(srca & (~srcb | srcc))", 7 }, + /* b1 */ { "~(srca ^ (srcc | (srca ^ srcb)))", 7 }, + /* b2 */ { "(srca ^ ((srca ^ srcc) & (srcb ^ srcc)))", 7 }, + /* b3 */ { "(~srcb | (srca & srcc))", 7 }, + /* b4 */ { "(srca ^ (srcb & ~srcc))", 7 }, + /* b5 */ { "~(srcc ^ (srca & (srcb | srcc)))", 7 }, + /* b6 */ { "(srca ^ srcc ^ (srcb | (srca & srcc)))", 7 }, + /* b7 */ { "~(srcb & (srca ^ srcc))", 7 }, + /* b8 */ { "(srca ^ (srcb & (srca ^ srcc)))", 7 }, + /* b9 */ { "~(srcc ^ (srcb | (srca & srcc)))", 7 }, + /* ba */ { "(srcc | (srca & ~srcb))", 7 }, + /* bb */ { "(~srcb | srcc)", 6 }, + /* bc */ { "((srca ^ srcb) | (srca & srcc))", 7 }, + /* bd */ { "((srca ^ srcb) | ~(srca ^ srcc))", 7 }, + /* be */ { "(srcc | (srca ^ srcb))", 7 }, + /* bf */ { "(srcc | ~(srca & srcb))", 7 }, + /* c0 */ { "(srca & srcb)", 3 }, + /* c1 */ { "(srca ^ (~srcb & (srca | ~srcc)))", 7 }, + /* c2 */ { "(srca ^ (~srcb & (srca | srcc)))", 7 }, + /* c3 */ { "~(srca ^ srcb)", 3 }, + /* c4 */ { "(srcb & (srca | ~srcc))", 7 }, + /* c5 */ { "~(srcb ^ (srca | (srcb ^ srcc)))", 7 }, + /* c6 */ { "(srcb ^ (~srca & srcc))", 7 }, + /* c7 */ { "~(srca ^ (srcb & (srca | srcc)))", 7 }, + /* c8 */ { "(srcb & (srca | srcc))", 7 }, + /* c9 */ { "~(srcb ^ (srca | srcc))", 7 }, + /* ca */ { "(srcc ^ (srca & (srcb ^ srcc)))", 7 }, + /* cb */ { "~(srcb ^ (srca | (srcb & srcc)))", 7 }, + /* cc */ { "srcb", 2 }, + /* cd */ { "(srcb | ~(srca | srcc))", 7 }, + /* ce */ { "(srcb | (~srca & srcc))", 7 }, + /* cf */ { "(~srca | srcb)", 3 }, + /* d0 */ { "(srca & (srcb | ~srcc))", 7 }, + /* d1 */ { "~(srca ^ (srcb | (srca ^ srcc)))", 7 }, + /* d2 */ { "(srca ^ (~srcb & srcc))", 7 }, + /* d3 */ { "~(srcb ^ (srca & (srcb | srcc)))", 7 }, + /* d4 */ { "(srca ^ ((srca ^ srcb) & (srcb ^ srcc)))", 7 }, + /* d5 */ { "(~srcc | (srca & srcb))", 7 }, + /* d6 */ { "(srca ^ srcb ^ (srcc | (srca & srcb)))", 7 }, + /* d7 */ { "~(srcc & (srca ^ srcb))", 7 }, + /* d8 */ { "(srca ^ (srcc & (srca ^ srcb)))", 7 }, + /* d9 */ { "~(srcb ^ (srcc | (srca & srcb)))", 7 }, + /* da */ { "((srca & srcb) | (srca ^ srcc))", 7 }, + /* db */ { "~((srca ^ srcb) & (srcb ^ srcc))", 7 }, + /* dc */ { "(srcb | (srca & ~srcc))", 7 }, + /* dd */ { "(srcb | ~srcc)", 6 }, + /* de */ { "(srcb | (srca ^ srcc))", 7 }, + /* df */ { "(srcb | ~(srca & srcc))", 7 }, + /* e0 */ { "(srca & (srcb | srcc))", 7 }, + /* e1 */ { "~(srca ^ (srcb | srcc))", 7 }, + /* e2 */ { "(srcc ^ (srcb & (srca ^ srcc)))", 7 }, + /* e3 */ { "~(srca ^ (srcb | (srca & srcc)))", 7 }, + /* e4 */ { "(srcb ^ (srcc & (srca ^ srcb)))", 7 }, + /* e5 */ { "~(srca ^ (srcc | (srca & srcb)))", 7 }, + /* e6 */ { "((srca & srcb) | (srcb ^ srcc))", 7 }, + /* e7 */ { "~((srca ^ srcb) & (srca ^ srcc))", 7 }, + /* e8 */ { "(srca ^ ((srca ^ srcb) & (srca ^ srcc)))", 7 }, + /* e9 */ { "(srca ^ srcb ^ (~srcc | (srca & srcb)))", 7 }, + /* ea */ { "(srcc | (srca & srcb))", 7 }, + /* eb */ { "(srcc | ~(srca ^ srcb))", 7 }, + /* ec */ { "(srcb | (srca & srcc))", 7 }, + /* ed */ { "(srcb | ~(srca ^ srcc))", 7 }, + /* ee */ { "(srcb | srcc)", 6 }, + /* ef */ { "(~srca | srcb | srcc)", 7 }, + /* f0 */ { "srca", 1 }, + /* f1 */ { "(srca | ~(srcb | srcc))", 7 }, + /* f2 */ { "(srca | (~srcb & srcc))", 7 }, + /* f3 */ { "(srca | ~srcb)", 3 }, + /* f4 */ { "(srca | (srcb & ~srcc))", 7 }, + /* f5 */ { "(srca | ~srcc)", 5 }, + /* f6 */ { "(srca | (srcb ^ srcc))", 7 }, + /* f7 */ { "(srca | ~(srcb & srcc))", 7 }, + /* f8 */ { "(srca | (srcb & srcc))", 7 }, + /* f9 */ { "(srca | ~(srcb ^ srcc))", 7 }, + /* fa */ { "(srca | srcc)", 5 }, + /* fb */ { "(srca | ~srcb | srcc)", 7 }, + /* fc */ { "(srca | srcb)", 3 }, + /* fd */ { "(srca | srcb | ~srcc)", 7 }, + /* fe */ { "(srca | srcb | srcc)", 7 }, + /* ff */ { "0xFFFFFFFF", 0 } }; diff --git a/src/blittable.cpp b/src/blittable.cpp index c81e0b69..32ad76bc 100644 --- a/src/blittable.cpp +++ b/src/blittable.cpp @@ -1,81 +1,77 @@ #include "sysconfig.h" #include "sysdeps.h" #include "options.h" -#include "include/memory.h" -#include "newcpu.h" #include "custom.h" -#include "savestate.h" +#include "include/memory.h" #include "blitter.h" #include "blitfunc.h" -blitter_func * const blitfunc_dofast[256] = -{ - blitdofast_0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_a, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_2a, 0, 0, 0, 0, 0, - blitdofast_30, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_3a, 0, blitdofast_3c, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_4a, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_6a, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_8a, 0, blitdofast_8c, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_9a, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - blitdofast_a8, 0, blitdofast_aa, 0, 0, 0, 0, 0, - 0, blitdofast_b1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_ca, 0, blitdofast_cc, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - blitdofast_d8, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_e2, 0, 0, 0, 0, 0, - 0, 0, blitdofast_ea, 0, 0, 0, 0, 0, - blitdofast_f0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_fa, 0, blitdofast_fc, 0, 0, 0 +blitter_func * const blitfunc_dofast[256] = { +blitdofast_0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_a, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_2a, 0, 0, 0, 0, 0, +blitdofast_30, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_3a, 0, blitdofast_3c, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_4a, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_6a, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_8a, 0, blitdofast_8c, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_9a, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +blitdofast_a8, 0, blitdofast_aa, 0, 0, 0, 0, 0, +0, blitdofast_b1, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_ca, 0, blitdofast_cc, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +blitdofast_d8, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_e2, 0, 0, 0, 0, 0, +0, 0, blitdofast_ea, 0, 0, 0, 0, 0, +blitdofast_f0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_fa, 0, blitdofast_fc, 0, 0, 0 }; -blitter_func * const blitfunc_dofast_desc[256] = -{ - blitdofast_desc_0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_desc_a, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_desc_2a, 0, 0, 0, 0, 0, - blitdofast_desc_30, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_desc_3a, 0, blitdofast_desc_3c, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_desc_4a, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_desc_6a, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_desc_8a, 0, blitdofast_desc_8c, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_desc_9a, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - blitdofast_desc_a8, 0, blitdofast_desc_aa, 0, 0, 0, 0, 0, - 0, blitdofast_desc_b1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_desc_ca, 0, blitdofast_desc_cc, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - blitdofast_desc_d8, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_desc_e2, 0, 0, 0, 0, 0, - 0, 0, blitdofast_desc_ea, 0, 0, 0, 0, 0, - blitdofast_desc_f0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, blitdofast_desc_fa, 0, blitdofast_desc_fc, 0, 0, 0 +blitter_func * const blitfunc_dofast_desc[256] = { +blitdofast_desc_0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_desc_a, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_desc_2a, 0, 0, 0, 0, 0, +blitdofast_desc_30, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_desc_3a, 0, blitdofast_desc_3c, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_desc_4a, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_desc_6a, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_desc_8a, 0, blitdofast_desc_8c, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_desc_9a, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +blitdofast_desc_a8, 0, blitdofast_desc_aa, 0, 0, 0, 0, 0, +0, blitdofast_desc_b1, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_desc_ca, 0, blitdofast_desc_cc, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, +blitdofast_desc_d8, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_desc_e2, 0, 0, 0, 0, 0, +0, 0, blitdofast_desc_ea, 0, 0, 0, 0, 0, +blitdofast_desc_f0, 0, 0, 0, 0, 0, 0, 0, +0, 0, blitdofast_desc_fa, 0, blitdofast_desc_fc, 0, 0, 0 }; diff --git a/src/blitter.cpp b/src/blitter.cpp index 57777c8a..8cdaadfa 100644 --- a/src/blitter.cpp +++ b/src/blitter.cpp @@ -14,7 +14,7 @@ #include "options.h" #include "uae.h" -#include "memory.h" +#include "include/memory.h" #include "newcpu.h" #include "custom.h" #include "events.h" @@ -22,36 +22,78 @@ #include "blitter.h" #include "blit.h" + // 1 = logging + // 2 = no wait detection + // 4 = no D + // 8 = instant + // 16 = activate debugger if weird things + // 32 = logging (no line) + +#if BLITTER_DEBUG +int log_blitter = 1 | 16; +#else +int log_blitter = 0; +#endif + +/* we must not change ce-mode while blitter is running.. */ +static int blitter_cycle_exact, immediate_blits; static int blt_statefile_type; uae_u16 bltcon0, bltcon1; uae_u32 bltapt, bltbpt, bltcpt, bltdpt; +uae_u32 bltptx; +int bltptxpos, bltptxc; +int blitter_nasty; +// blitter is active and D may write to visible bitplane addresses +int blitter_dangerous_bpl; -static int original_ch; +static int original_ch, original_fill, original_line; static int blinea_shift; static uae_u16 blinea, blineb; static int blitline, blitfc, blitfill, blitife, blitsing, blitdesc; static int blitline_started; -static int blitonedot, blitsign; +static int blitonedot, blitsign, blitlinepixel; +static int blit_add; +static int blit_modadda, blit_modaddb, blit_modaddc, blit_modaddd; static int blit_ch; +static int blitter_dontdo; +static int blitter_delayed_debug; +#ifdef BLITTER_SLOWDOWNDEBUG +static int blitter_slowdowndebug; +#endif + struct bltinfo blt_info; static uae_u8 blit_filltable[256][4][2]; uae_u32 blit_masktable[BLITTER_MAX_WORDS]; enum blitter_states bltstate; -static int blit_cyclecounter; -static int blit_slowdown; +static int blit_cyclecounter, blit_waitcyclecounter; +static int blit_maxcyclecounter, blit_slowdown, blit_totalcyclecounter; +static int blit_startcycles, blit_misscyclecounter; + +#ifdef CPUEMU_13 +extern uae_u8 cycle_line[256]; +#endif static long blit_firstline_cycles; static long blit_first_cycle; static int blit_last_cycle, blit_dmacount, blit_dmacount2; -static int blit_nod; +static int blit_linecycles, blit_extracycles, blit_nod; static const int *blit_diag; -static int blit_faulty; -static int ddat1use; +static int blit_frozen, blit_faulty; +static int blit_final; +static int blt_delayed_irq; +static uae_u16 ddat1, ddat2; +static int ddat1use, ddat2use; + +int blit_interrupt; + +static int last_blitter_hpos; + +#define BLITTER_STARTUP_CYCLES 2 /* Blitter Idle Cycle: @@ -158,7 +200,7 @@ static const int blit_cycle_diagram_finalld[] = 2, 0,0, 0,0 }; -static int get_cycle_diagram_type (const int *diag) +static int get_cycle_diagram_type(const int *diag) { for (int i = 0; i < 16; i++) { if (diag == &blit_cycle_diagram[i][0]) @@ -175,7 +217,7 @@ static int get_cycle_diagram_type (const int *diag) return 0xff; } -static const int *set_cycle_diagram_type (uae_u8 diag) +static const int *set_cycle_diagram_type(uae_u8 diag) { if (diag >= 0x00 && diag <= 0x0f) return &blit_cycle_diagram[diag][0]; @@ -187,10 +229,10 @@ static const int *set_cycle_diagram_type (uae_u8 diag) return blit_cycle_diagram_finald; if (diag == 0x82) return blit_cycle_diagram_finalld; - return NULL; + return nullptr; } -void build_blitfilltable (void) +void build_blitfilltable(void) { unsigned int d, fillmask; int i; @@ -218,247 +260,407 @@ void build_blitfilltable (void) } } -static void blitter_dump (void) +STATIC_INLINE void record_dma_blit(uae_u16 reg, uae_u16 dat, uae_u32 addr, int hpos) { - int chipsize = currprefs.chipmem_size; - write_log (_T("PT A=%08X B=%08X C=%08X D=%08X\n"), bltapt, bltbpt, bltcpt, bltdpt); - write_log (_T("CON0=%04X CON1=%04X DAT A=%04X B=%04X C=%04X\n"), - bltcon0, bltcon1, blt_info.bltadat, blt_info.bltbdat, blt_info.bltcdat); - write_log (_T("AFWM=%04X ALWM=%04X MOD A=%04X B=%04X C=%04X D=%04X\n"), - blt_info.bltafwm, blt_info.bltalwm, - blt_info.bltamod & 0xffff, blt_info.bltbmod & 0xffff, blt_info.bltcmod & 0xffff, blt_info.bltdmod & 0xffff); - write_log (_T("PC=%08X DMA=%d\n"), m68k_getpc (), dmaen (DMA_BLITTER)); +#ifdef DEBUGGER + int type; - if (((bltcon0 & 0x800) && bltapt >= chipsize) || ((bltcon0 & 0x400) && bltbpt >= chipsize) || - ((bltcon0 & 0x200) && bltcpt >= chipsize) || ((bltcon0 & 0x100) && bltdpt >= chipsize)) - write_log (_T("PT outside of chipram\n")); + if (blitline) + type = DMARECORD_BLITTER_LINE; + else if (blitfill) + type = DMARECORD_BLITTER_FILL; + else + type = DMARECORD_BLITTER; + if (debug_dma) + record_dma(reg, dat, addr, hpos, vpos, type); + if (memwatch_enabled) { + if (reg == 0) { + uae_u32 mask = MW_MASK_BLITTER_D_N; + if (blitfill) + mask = MW_MASK_BLITTER_D_F; + if (blitline) + mask = MW_MASK_BLITTER_D_L; + debug_wputpeekdma_chipram(addr, dat, mask, reg); + } + else if (reg == 0x70) { + debug_wgetpeekdma_chipram(addr, dat, MW_MASK_BLITTER_C, reg); + } + else if (reg == 0x72) { + debug_wgetpeekdma_chipram(addr, dat, MW_MASK_BLITTER_B, reg); + } + else if (reg == 0x74) { + debug_wgetpeekdma_chipram(addr, dat, MW_MASK_BLITTER_A, reg); + } + } +#endif } -STATIC_INLINE int channel_state (int cycles) +//static void blitter_dump(void) +//{ +// int chipsize = currprefs.chipmem_size; +// write_log(_T("PT A=%08X B=%08X C=%08X D=%08X\n"), bltapt, bltbpt, bltcpt, bltdpt); +// write_log(_T("CON0=%04X CON1=%04X DAT A=%04X B=%04X C=%04X\n"), +// bltcon0, bltcon1, blt_info.bltadat, blt_info.bltbdat, blt_info.bltcdat); +// write_log(_T("AFWM=%04X ALWM=%04X MOD A=%04X B=%04X C=%04X D=%04X\n"), +// blt_info.bltafwm, blt_info.bltalwm, +// blt_info.bltamod & 0xffff, blt_info.bltbmod & 0xffff, blt_info.bltcmod & 0xffff, blt_info.bltdmod & 0xffff); +// write_log(_T("PC=%08X DMA=%d\n"), m68k_getpc(), dmaen(DMA_BLITTER)); +// +// if (((bltcon0 & 0x800) && bltapt >= chipsize) || ((bltcon0 & 0x400) && bltbpt >= chipsize) || +// ((bltcon0 & 0x200) && bltcpt >= chipsize) || ((bltcon0 & 0x100) && bltdpt >= chipsize)) +// write_log(_T("PT outside of chipram\n")); +//} + +STATIC_INLINE const int *get_ch(void) { - if (cycles < blit_diag[0]) - return blit_diag[1 + cycles]; - cycles -= blit_diag[0]; - cycles %= blit_diag[0]; - return blit_diag[1 + blit_diag[0] + cycles]; + if (blit_faulty) + return &blit_diag[0]; + if (blit_final) + return blitline || blit_nod ? blit_cycle_diagram_finalld : blit_cycle_diagram_finald; + return blit_diag; } -static void blitter_done (void) +STATIC_INLINE int channel_state(int cycles) { - ddat1use = 0; - bltstate = BLT_done; - send_interrupt (6); - blitter_done_notify (); - event_remevent(ev_blitter); - unset_special (SPCFLAG_BLTNASTY); + const int *diag; + if (cycles < 0) + return 0; + diag = get_ch(); + if (cycles < diag[0]) + return diag[1 + cycles]; + cycles -= diag[0]; + cycles %= diag[0]; + return diag[1 + diag[0] + cycles]; +} +STATIC_INLINE int channel_pos(int cycles) +{ + const int *diag; + if (cycles < 0) + return 0; + diag = get_ch(); + if (cycles < diag[0]) + return cycles; + cycles -= diag[0]; + cycles %= diag[0]; + return cycles; } -STATIC_INLINE void chipmem_agnus_wput2 (uaecptr addr, uae_u32 w) +int blitter_channel_state(void) { - chipmem_wput_indirect (addr, w); + return channel_state(blit_cyclecounter); +} + +STATIC_INLINE int canblit(int hpos) +{ + if (!dmaen(DMA_BLITTER)) + return -1; + if (is_bitplane_dma(hpos)) + return 0; +#ifdef CPUEMU_13 + if (cycle_line[hpos] & CYCLE_MASK) { + return 0; + } +#endif + return 1; +} + +static void markidlecycle(int hpos) +{ + //if (debug_dma) + // record_dma_event(DMA_EVENT_BLITSTARTFINISH, hpos, vpos); +} + +static void reset_channel_mods(void) +{ + if (bltptxpos < 0) + return; + bltptxpos = -1; + switch (bltptxc) + { + case 1: + bltapt = bltptx; + break; + case 2: + bltbpt = bltptx; + break; + case 3: + bltcpt = bltptx; + break; + case 4: + bltdpt = bltptx; + break; + } +} + +static void check_channel_mods(int hpos, int ch) +{ + if (bltptxpos != hpos) + return; + if (ch == bltptxc) { + bltptxpos = -1; + //write_log(_T("BLITTER: %08X write to %cPT ignored! %08x\n"), bltptx, ch + 'A' - 1, m68k_getpc()); + //activate_debugger(); + } +} + +// blitter interrupt is set (and busy bit cleared) when +// last "main" cycle has been finished, any non-linedraw +// D-channel blit still needs 2 more cycles before final +// D is written (idle cycle, final D write) +// +// line draw interrupt triggers when last D is written +// (or cycle where last D write would have been if +// ONEDOT was active) + +static void blitter_interrupt(int hpos, int done) +{ + if (blit_interrupt) + return; + if (!done && (!blitter_cycle_exact || immediate_blits || currprefs.cpu_model >= 68030 || currprefs.cachesize || currprefs.m68k_speed < 0)) + return; + blit_interrupt = 1; + send_interrupt(6, 4 * CYCLE_UNIT); + //if (debug_dma) + // record_dma_event(DMA_EVENT_BLITIRQ, hpos, vpos); +} + +static void blitter_done(int hpos) +{ + ddat1use = ddat2use = 0; + bltstate = blit_startcycles == 0 || !blitter_cycle_exact || immediate_blits ? BLT_done : BLT_init; + blitter_interrupt(hpos, 1); + blitter_done_notify(hpos); + markidlecycle(hpos); + event2_remevent(ev2_blitter); + unset_special(SPCFLAG_BLTNASTY); + if (log_blitter & 1) + write_log(_T("cycles %d, missed %d, total %d\n"), + blit_totalcyclecounter, blit_misscyclecounter, blit_totalcyclecounter + blit_misscyclecounter); + blitter_dangerous_bpl = 0; +} + +STATIC_INLINE void chipmem_agnus_wput2(uaecptr addr, uae_u32 w) +{ + //last_custom_value1 = w; blitter writes are not stored + if (!(log_blitter & 4)) { + chipmem_wput_indirect(addr, w); + //debug_wputpeekdma_chipram(addr, w, MW_MASK_BLITTER_D_N, 0x000); + } } static void blitter_dofast(void) { - int i,j; - uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; - uae_u8 mt = bltcon0 & 0xFF; + int i, j; + uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; + uae_u8 mt = bltcon0 & 0xFF; - blit_masktable[BLITTER_MAX_WORDS - 1] = blt_info.bltafwm; - blit_masktable[BLITTER_MAX_WORDS - blt_info.hblitsize] &= blt_info.bltalwm; + blit_masktable[0] = blt_info.bltafwm; + blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm; - if (bltcon0 & 0x800) { - bltadatptr = (uaecptr)get_real_address(bltapt); - bltapt += (blt_info.hblitsize * 2 + blt_info.bltamod) * blt_info.vblitsize; - } - if (bltcon0 & 0x400) { - bltbdatptr = (uaecptr)get_real_address(bltbpt); - bltbpt += (blt_info.hblitsize * 2 + blt_info.bltbmod) * blt_info.vblitsize; - } - if (bltcon0 & 0x200) { - bltcdatptr = (uaecptr)get_real_address(bltcpt); - bltcpt += (blt_info.hblitsize * 2 + blt_info.bltcmod) * blt_info.vblitsize; - } - if (bltcon0 & 0x100) { - bltddatptr = bltdpt; - bltdpt += (blt_info.hblitsize * 2 + blt_info.bltdmod) * blt_info.vblitsize; - } + if (bltcon0 & 0x800) { + bltadatptr = bltapt; + bltapt += (blt_info.hblitsize * 2 + blt_info.bltamod) * blt_info.vblitsize; + } + if (bltcon0 & 0x400) { + bltbdatptr = bltbpt; + bltbpt += (blt_info.hblitsize * 2 + blt_info.bltbmod) * blt_info.vblitsize; + } + if (bltcon0 & 0x200) { + bltcdatptr = bltcpt; + bltcpt += (blt_info.hblitsize * 2 + blt_info.bltcmod) * blt_info.vblitsize; + } + if (bltcon0 & 0x100) { + bltddatptr = bltdpt; + bltdpt += (blt_info.hblitsize * 2 + blt_info.bltdmod) * blt_info.vblitsize; + } #if SPEEDUP - if (blitfunc_dofast[mt] && !blitfill) { - (*blitfunc_dofast[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info); - } else + if (blitfunc_dofast[mt] && !blitfill) { + (*blitfunc_dofast[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info); + } + else #endif - { - uae_u32 blitbhold = blt_info.bltbhold; - uae_u32 preva = 0, prevb = 0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - blt_info.hblitsize; + { + uae_u32 blitbhold = blt_info.bltbhold; + uae_u32 preva = 0, prevb = 0; + uaecptr dstp = 0; + int dodst = 0; - for (j = blt_info.vblitsize; j--;) { - blitfc = !!(bltcon1 & 0x4); - for (i = blt_info.hblitsize; i--;) { - uae_u32 bltadat, blitahold; - if (bltadatptr) { - blt_info.bltadat = bltadat = do_get_mem_word ((uae_u16 *)bltadatptr); - bltadatptr += 2; - } else - bltadat = blt_info.bltadat; - bltadat &= blit_masktable_p[i]; - blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift; - preva = bltadat; + for (j = 0; j < blt_info.vblitsize; j++) { + blitfc = !!(bltcon1 & 0x4); + for (i = 0; i < blt_info.hblitsize; i++) { + uae_u32 bltadat, blitahold; + uae_u16 bltbdat; + if (bltadatptr) { + blt_info.bltadat = bltadat = chipmem_wget_indirect(bltadatptr); + bltadatptr += 2; + } + else + bltadat = blt_info.bltadat; + bltadat &= blit_masktable[i]; + blitahold = ((uae_u32(preva) << 16) | bltadat) >> blt_info.blitashift; + preva = bltadat; - if (bltbdatptr) { - uae_u16 bltbdat; - blt_info.bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)bltbdatptr); - bltbdatptr += 2; - blitbhold = (((uae_u32)prevb << 16) | bltbdat) >> blt_info.blitbshift; - prevb = bltbdat; - } - if (bltcdatptr) { - blt_info.bltcdat = do_get_mem_word ((uae_u16 *)bltcdatptr); - bltcdatptr += 2; - } - if (dstp) - chipmem_agnus_wput2 (dstp, blt_info.bltddat); - blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt); - if (blitfill) { - uae_u16 d = blt_info.bltddat; - int ifemode = blitife ? 2 : 0; - int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; - blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] - + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); - blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; - } - if (blt_info.bltddat) - blt_info.blitzero = 0; - if (bltddatptr) { - dstp = bltddatptr; - bltddatptr += 2; - } - } - if (bltadatptr) - bltadatptr += blt_info.bltamod; - if (bltbdatptr) - bltbdatptr += blt_info.bltbmod; - if (bltcdatptr) - bltcdatptr += blt_info.bltcmod; - if (bltddatptr) - bltddatptr += blt_info.bltdmod; - } - if (dstp) - chipmem_agnus_wput2 (dstp, blt_info.bltddat); - blt_info.bltbhold = blitbhold; - } - blit_masktable[BLITTER_MAX_WORDS - 1] = 0xFFFF; - blit_masktable[BLITTER_MAX_WORDS - blt_info.hblitsize] = 0xFFFF; + if (bltbdatptr) { + blt_info.bltbdat = bltbdat = chipmem_wget_indirect(bltbdatptr); + bltbdatptr += 2; + blitbhold = ((uae_u32(prevb) << 16) | bltbdat) >> blt_info.blitbshift; + prevb = bltbdat; + } - bltstate = BLT_done; + if (bltcdatptr) { + blt_info.bltcdat = chipmem_wget_indirect(bltcdatptr); + bltcdatptr += 2; + } + if (dodst) + chipmem_agnus_wput2(dstp, blt_info.bltddat); + blt_info.bltddat = blit_func(blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; + if (blitfill) { + uae_u16 d = blt_info.bltddat; + int ifemode = blitife ? 2 : 0; + int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; + blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] + + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); + blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; + } + if (blt_info.bltddat) + blt_info.blitzero = 0; + if (bltddatptr) { + dodst = 1; + dstp = bltddatptr; + bltddatptr += 2; + } + } + if (bltadatptr) + bltadatptr += blt_info.bltamod; + if (bltbdatptr) + bltbdatptr += blt_info.bltbmod; + if (bltcdatptr) + bltcdatptr += blt_info.bltcmod; + if (bltddatptr) + bltddatptr += blt_info.bltdmod; + } + if (dodst) + chipmem_agnus_wput2(dstp, blt_info.bltddat); + blt_info.bltbhold = blitbhold; + } + blit_masktable[0] = 0xFFFF; + blit_masktable[blt_info.hblitsize - 1] = 0xFFFF; + + bltstate = BLT_done; } static void blitter_dofast_desc(void) { - int i,j; - uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; - uae_u8 mt = bltcon0 & 0xFF; + int i, j; + uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; + uae_u8 mt = bltcon0 & 0xFF; - blit_masktable[BLITTER_MAX_WORDS - 1] = blt_info.bltafwm; - blit_masktable[BLITTER_MAX_WORDS - blt_info.hblitsize] &= blt_info.bltalwm; + blit_masktable[0] = blt_info.bltafwm; + blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm; - if (bltcon0 & 0x800) { - bltadatptr = (uaecptr)get_real_address(bltapt); - bltapt -= (blt_info.hblitsize * 2 + blt_info.bltamod) * blt_info.vblitsize; - } - if (bltcon0 & 0x400) { - bltbdatptr = (uaecptr)get_real_address(bltbpt); - bltbpt -= (blt_info.hblitsize * 2 + blt_info.bltbmod) * blt_info.vblitsize; - } - if (bltcon0 & 0x200) { - bltcdatptr = (uaecptr)get_real_address(bltcpt); - bltcpt -= (blt_info.hblitsize * 2 + blt_info.bltcmod) * blt_info.vblitsize; - } - if (bltcon0 & 0x100) { - bltddatptr = bltdpt; - bltdpt -= (blt_info.hblitsize * 2 + blt_info.bltdmod) * blt_info.vblitsize; - } + if (bltcon0 & 0x800) { + bltadatptr = bltapt; + bltapt -= (blt_info.hblitsize * 2 + blt_info.bltamod) * blt_info.vblitsize; + } + if (bltcon0 & 0x400) { + bltbdatptr = bltbpt; + bltbpt -= (blt_info.hblitsize * 2 + blt_info.bltbmod) * blt_info.vblitsize; + } + if (bltcon0 & 0x200) { + bltcdatptr = bltcpt; + bltcpt -= (blt_info.hblitsize * 2 + blt_info.bltcmod) * blt_info.vblitsize; + } + if (bltcon0 & 0x100) { + bltddatptr = bltdpt; + bltdpt -= (blt_info.hblitsize * 2 + blt_info.bltdmod) * blt_info.vblitsize; + } #if SPEEDUP - if (blitfunc_dofast_desc[mt] && !blitfill) { + if (blitfunc_dofast_desc[mt] && !blitfill) { (*blitfunc_dofast_desc[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info); - } else + } + else #endif - { - uae_u32 blitbhold = blt_info.bltbhold; - uae_u32 preva = 0, prevb = 0; - uaecptr dstp = 0; - uae_u32 *blit_masktable_p = blit_masktable + BLITTER_MAX_WORDS - blt_info.hblitsize; + { + uae_u32 blitbhold = blt_info.bltbhold; + uae_u32 preva = 0, prevb = 0; + uaecptr dstp = 0; + int dodst = 0; - for (j = blt_info.vblitsize; j--;) { + for (j = 0; j < blt_info.vblitsize; j++) { blitfc = !!(bltcon1 & 0x4); - for (i = blt_info.hblitsize; i--;) { + for (i = 0; i < blt_info.hblitsize; i++) { uae_u32 bltadat, blitahold; + uae_u16 bltbdat; if (bltadatptr) { - bltadat = blt_info.bltadat = do_get_mem_word ((uae_u16 *)bltadatptr); + bltadat = blt_info.bltadat = chipmem_wget_indirect(bltadatptr); bltadatptr -= 2; - } else + } + else bltadat = blt_info.bltadat; - bltadat &= blit_masktable_p[i]; - blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift; + bltadat &= blit_masktable[i]; + blitahold = ((uae_u32(bltadat) << 16) | preva) >> blt_info.blitdownashift; preva = bltadat; if (bltbdatptr) { - uae_u16 bltbdat; - blt_info.bltbdat = bltbdat = do_get_mem_word ((uae_u16 *)bltbdatptr); - bltbdatptr -= 2; - blitbhold = (((uae_u32)bltbdat << 16) | prevb) >> blt_info.blitdownbshift; - prevb = bltbdat; - } + blt_info.bltbdat = bltbdat = chipmem_wget_indirect(bltbdatptr); + bltbdatptr -= 2; + blitbhold = ((uae_u32(bltbdat) << 16) | prevb) >> blt_info.blitdownbshift; + prevb = bltbdat; + } - if (bltcdatptr) { - blt_info.bltcdat = blt_info.bltbdat = do_get_mem_word ((uae_u16 *)bltcdatptr); - bltcdatptr -= 2; - } - if (dstp) - chipmem_agnus_wput2 (dstp, blt_info.bltddat); - blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt); - if (blitfill) { - uae_u16 d = blt_info.bltddat; - int ifemode = blitife ? 2 : 0; - int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; - blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] - + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); - blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; - } - if (blt_info.bltddat) - blt_info.blitzero = 0; - if (bltddatptr) { - dstp = bltddatptr; - bltddatptr -= 2; - } - } - if (bltadatptr) - bltadatptr -= blt_info.bltamod; - if (bltbdatptr) - bltbdatptr -= blt_info.bltbmod; - if (bltcdatptr) - bltcdatptr -= blt_info.bltcmod; - if (bltddatptr) - bltddatptr -= blt_info.bltdmod; - } - if (dstp) - chipmem_agnus_wput2 (dstp, blt_info.bltddat); + if (bltcdatptr) { + blt_info.bltcdat = blt_info.bltbdat = chipmem_wget_indirect(bltcdatptr); + bltcdatptr -= 2; + } + if (dodst) + chipmem_agnus_wput2(dstp, blt_info.bltddat); + blt_info.bltddat = blit_func(blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; + if (blitfill) { + uae_u16 d = blt_info.bltddat; + int ifemode = blitife ? 2 : 0; + int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; + blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] + + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); + blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; + } + if (blt_info.bltddat) + blt_info.blitzero = 0; + if (bltddatptr) { + dstp = bltddatptr; + dodst = 1; + bltddatptr -= 2; + } + } + if (bltadatptr) + bltadatptr -= blt_info.bltamod; + if (bltbdatptr) + bltbdatptr -= blt_info.bltbmod; + if (bltcdatptr) + bltcdatptr -= blt_info.bltcmod; + if (bltddatptr) + bltddatptr -= blt_info.bltdmod; + } + if (dodst) + chipmem_agnus_wput2(dstp, blt_info.bltddat); blt_info.bltbhold = blitbhold; } - blit_masktable[BLITTER_MAX_WORDS - 1] = 0xFFFF; - blit_masktable[BLITTER_MAX_WORDS - blt_info.hblitsize] = 0xFFFF; + blit_masktable[0] = 0xFFFF; + blit_masktable[blt_info.hblitsize - 1] = 0xFFFF; - bltstate = BLT_done; + bltstate = BLT_done; } STATIC_INLINE void blitter_read(void) { if (bltcon0 & 0x200) { - blt_info.bltcdat = chipmem_wget_indirect(bltcpt); + if (!dmaen(DMA_BLITTER)) + return; + blt_info.bltcdat = chipmem_wget_indirect(bltcpt); + //debug_wgetpeekdma_chipram(bltcpt, blt_info.bltcdat, MW_MASK_BLITTER_C, 0x070); + last_custom_value1 = blt_info.bltcdat; } + bltstate = BLT_work; } STATIC_INLINE void blitter_write(void) @@ -467,180 +669,655 @@ STATIC_INLINE void blitter_write(void) blt_info.blitzero = 0; /* D-channel state has no effect on linedraw, but C must be enabled or nothing is drawn! */ if (bltcon0 & 0x200) { - chipmem_wput_indirect (bltdpt, blt_info.bltddat); + if (!dmaen(DMA_BLITTER)) + return; + //last_custom_value1 = blt_info.bltddat; blitter writes are not stored + chipmem_wput_indirect(bltdpt, blt_info.bltddat); + //debug_wputpeekdma_chipram(bltdpt, blt_info.bltddat, MW_MASK_BLITTER_D_N, 0x000); } + bltstate = BLT_next; } STATIC_INLINE void blitter_line_incx(void) { - if (++blinea_shift == 16) { - blinea_shift = 0; - bltcpt += 2; - } + if (++blinea_shift == 16) { + blinea_shift = 0; + bltcpt += 2; + } } STATIC_INLINE void blitter_line_decx(void) { - if (blinea_shift-- == 0) { - blinea_shift = 15; - bltcpt -= 2; - } + if (blinea_shift-- == 0) { + blinea_shift = 15; + bltcpt -= 2; + } } STATIC_INLINE void blitter_line_decy(void) { - bltcpt -= blt_info.bltcmod; - blitonedot = 0; + bltcpt -= blt_info.bltcmod; + blitonedot = 0; } STATIC_INLINE void blitter_line_incy(void) { - bltcpt += blt_info.bltcmod; - blitonedot = 0; + bltcpt += blt_info.bltcmod; + blitonedot = 0; } -static int blitter_line(void) +static void blitter_line(void) { uae_u16 blitahold = (blinea & blt_info.bltafwm) >> blinea_shift; + uae_u16 blitchold = blt_info.bltcdat; blt_info.bltbhold = (blineb & 1) ? 0xFFFF : 0; - int blitlinepixel = !blitsing || (blitsing && !blitonedot); - blt_info.bltddat = blit_func (blitahold, blt_info.bltbhold, blt_info.bltcdat, bltcon0 & 0xFF); + blitlinepixel = !blitsing || (blitsing && !blitonedot); + blt_info.bltddat = blit_func(blitahold, blt_info.bltbhold, blitchold, bltcon0 & 0xFF); blitonedot++; +} +static void blitter_line_proc(void) +{ if (bltcon0 & 0x800) { if (blitsign) - bltapt += (uae_s16)blt_info.bltbmod; + bltapt += uae_s16(blt_info.bltbmod); else - bltapt += (uae_s16)blt_info.bltamod; + bltapt += uae_s16(blt_info.bltamod); } if (!blitsign) { if (bltcon1 & 0x10) { if (bltcon1 & 0x8) - blitter_line_decy (); + blitter_line_decy(); else - blitter_line_incy (); - } else { + blitter_line_incy(); + } + else { if (bltcon1 & 0x8) - blitter_line_decx (); + blitter_line_decx(); else - blitter_line_incx (); + blitter_line_incx(); } } if (bltcon1 & 0x10) { if (bltcon1 & 0x4) - blitter_line_decx (); + blitter_line_decx(); else - blitter_line_incx (); - } else { + blitter_line_incx(); + } + else { if (bltcon1 & 0x4) - blitter_line_decy (); + blitter_line_decy(); else - blitter_line_incy (); + blitter_line_incy(); } - blitsign = 0 > (uae_s16)bltapt; - return blitlinepixel; + blitsign = 0 > uae_s16(bltapt); + bltstate = BLT_write; } + + STATIC_INLINE void blitter_nxline(void) { blineb = (blineb << 1) | (blineb >> 15); blt_info.vblitsize--; + bltstate = BLT_read; } +#ifdef CPUEMU_13 + +static int blitter_cyclecounter; +static int blitter_hcounter1, blitter_hcounter2; +static int blitter_vcounter1, blitter_vcounter2; + +static void decide_blitter_line(int hsync, int hpos) +{ + if (blit_final && blt_info.vblitsize) + blit_final = 0; + while (last_blitter_hpos < hpos) { + int c = channel_state(blit_cyclecounter); + + for (;;) { + int v = canblit(last_blitter_hpos); + + if (blit_waitcyclecounter) { + blit_waitcyclecounter = 0; + break; + } + + // final 2 idle cycles? does not need free bus + if (blit_final) { + blit_cyclecounter++; + blit_totalcyclecounter++; + if (blit_cyclecounter >= 2) { + blitter_done(last_blitter_hpos); + return; + } + break; + } + + if (v <= 0) { + blit_misscyclecounter++; + blitter_nasty++; + break; + } + + blit_cyclecounter++; + blit_totalcyclecounter++; + + check_channel_mods(last_blitter_hpos, c); + + if (c == 3) { + + blitter_read(); + alloc_cycle_blitter(last_blitter_hpos, &bltcpt, 3); + record_dma_blit(0x70, blt_info.bltcdat, bltcpt, last_blitter_hpos); + blitter_nasty++; + + } + else if (c == 5) { + + if (ddat1use) { + bltdpt = bltcpt; + } + ddat1use = 1; + blitter_line(); + blitter_line_proc(); + blitter_nxline(); + + } + else if (c == 4) { + + /* onedot mode and no pixel = bus write access is skipped */ + if (blitlinepixel) { + blitter_write(); + alloc_cycle_blitter(last_blitter_hpos, &bltdpt, 4); + record_dma_blit(0x00, blt_info.bltddat, bltdpt, last_blitter_hpos); + blitlinepixel = 0; + blitter_nasty++; + } + if (blt_info.vblitsize == 0) { + bltdpt = bltcpt; + blit_final = 1; + blit_cyclecounter = 0; + blit_waitcyclecounter = 0; + // blit finished bit is set and interrupt triggered + // immediately after last D write + blitter_interrupt(last_blitter_hpos, 0); + break; + } + + } + + break; + } + last_blitter_hpos++; + } + if (hsync) + last_blitter_hpos = 0; + reset_channel_mods(); +} + +#endif + static void actually_do_blit(void) { - if (blitline) { - do { - blitter_read (); + if (blitline) { + do { + blitter_read(); if (ddat1use) bltdpt = bltcpt; ddat1use = 1; - if (blitter_line ()) { - blitter_write (); + blitter_line(); + blitter_line_proc(); + blitter_nxline(); + if (blitlinepixel) { + blitter_write(); + blitlinepixel = 0; } - blitter_nxline (); if (blt_info.vblitsize == 0) bltstate = BLT_done; } while (bltstate != BLT_done); - bltdpt = bltcpt; - } else { + bltdpt = bltcpt; + } + else { if (blitdesc) - blitter_dofast_desc (); + blitter_dofast_desc(); else - blitter_dofast (); + blitter_dofast(); bltstate = BLT_done; } } -static void blitter_doit (void) +static void blitter_doit(void) { - actually_do_blit (); - blitter_done (); + if (blt_info.vblitsize == 0 || (blitline && blt_info.hblitsize != 2)) { + blitter_done(current_hpos()); + return; + } + if (log_blitter) { + if (!blitter_dontdo) + actually_do_blit(); + else + bltstate = BLT_done; + } + else { + actually_do_blit(); + } + blitter_done(current_hpos()); } -void blitter_handler(void) +void blitter_handler(uae_u32 data) { static int blitter_stuck; - if (!dmaen (DMA_BLITTER)) { - event_newevent (ev_blitter, 10); + if (!dmaen(DMA_BLITTER)) { + event2_newevent(ev2_blitter, 10, 0); blitter_stuck++; - if (blitter_stuck < 20000 || !currprefs.immediate_blits) + if (blitter_stuck < 20000 || !immediate_blits) return; /* gotta come back later. */ - /* "free" blitter in immediate mode if it has been "stuck" ~3 frames - * fixes some JIT game incompatibilities - */ + /* "free" blitter in immediate mode if it has been "stuck" ~3 frames + * fixes some JIT game incompatibilities + */ + //debugtest(DEBUGTEST_BLITTER, _T("force-unstuck!\n")); } blitter_stuck = 0; - if (blit_slowdown > 0 && !currprefs.immediate_blits) { - event_newevent (ev_blitter, blit_slowdown); + if (blit_slowdown > 0 && !immediate_blits) { + event2_newevent(ev2_blitter, blit_slowdown, 0); blit_slowdown = -1; return; } - blitter_doit (); + blitter_doit(); } -static void blitter_force_finish (void) +#ifdef CPUEMU_13 + +static uae_u32 preva, prevb; +STATIC_INLINE uae_u16 blitter_doblit(void) { - uae_u16 odmacon; - if (bltstate == BLT_done) - return; - if (bltstate != BLT_done) { - /* blitter is currently running - * force finish (no blitter state support yet) - */ - odmacon = dmacon; - dmacon |= DMA_MASTER | DMA_BLITTER; - write_log (_T("forcing blitter finish\n")); - actually_do_blit (); - blitter_done (); - dmacon = odmacon; - } + uae_u32 blitahold; + uae_u16 bltadat, ddat; + uae_u8 mt = bltcon0 & 0xFF; + + bltadat = blt_info.bltadat; + if (blitter_hcounter1 == 0) + bltadat &= blt_info.bltafwm; + if (blitter_hcounter1 == blt_info.hblitsize - 1) + bltadat &= blt_info.bltalwm; + if (blitdesc) + blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift; + else + blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift; + preva = bltadat; + + ddat = blit_func(blitahold, blt_info.bltbhold, blt_info.bltcdat, mt) & 0xFFFF; + + if ((bltcon1 & 0x18)) { + uae_u16 d = ddat; + int ifemode = blitife ? 2 : 0; + int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; + ddat = (blit_filltable[d & 255][ifemode + blitfc][0] + + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); + blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; + } + + if (ddat) + blt_info.blitzero = 0; + + return ddat; } -static bool invstate (void) + +STATIC_INLINE void blitter_doddma(int hpos) +{ + uae_u16 d; + + if (blit_dmacount2 == 0) { + d = blitter_doblit(); + } + else if (ddat2use) { + d = ddat2; + ddat2use = 0; + } + else if (ddat1use) { + d = ddat1; + ddat1use = 0; + } + else { + static int warn = 10; + if (warn > 0) { + warn--; + write_log(_T("BLITTER: D-channel without nothing to do?\n")); + } + return; + } + record_dma_blit(0x00, d, bltdpt, hpos); + //last_custom_value1 = d; blitter writes are not stored + chipmem_agnus_wput2(bltdpt, d); + alloc_cycle_blitter(hpos, &bltdpt, 4); + bltdpt += blit_add; + blitter_hcounter2++; + if (blitter_hcounter2 == blt_info.hblitsize) { + blitter_hcounter2 = 0; + bltdpt += blit_modaddd; + blitter_vcounter2++; + if (blit_dmacount2 == 0) // d-only + blitter_vcounter1++; + if (blitter_vcounter2 > blitter_vcounter1) + blitter_vcounter1 = blitter_vcounter2; + } + if (blit_ch == 1) + blitter_hcounter1 = blitter_hcounter2; +} + +STATIC_INLINE void blitter_dodma(int ch, int hpos) +{ + uae_u16 dat, reg; + uae_u32 addr; + + switch (ch) + { + case 1: + blt_info.bltadat = dat = chipmem_wget_indirect(bltapt); + last_custom_value1 = blt_info.bltadat; + addr = bltapt; + bltapt += blit_add; + reg = 0x74; + alloc_cycle_blitter(hpos, &bltapt, 1); + break; + case 2: + blt_info.bltbdat = dat = chipmem_wget_indirect(bltbpt); + last_custom_value1 = blt_info.bltbdat; + addr = bltbpt; + bltbpt += blit_add; + if (blitdesc) + blt_info.bltbhold = (((uae_u32)blt_info.bltbdat << 16) | prevb) >> blt_info.blitdownbshift; + else + blt_info.bltbhold = (((uae_u32)prevb << 16) | blt_info.bltbdat) >> blt_info.blitbshift; + prevb = blt_info.bltbdat; + reg = 0x72; + alloc_cycle_blitter(hpos, &bltbpt, 2); + break; + case 3: + blt_info.bltcdat = dat = chipmem_wget_indirect(bltcpt); + last_custom_value1 = blt_info.bltcdat; + addr = bltcpt; + bltcpt += blit_add; + reg = 0x70; + alloc_cycle_blitter(hpos, &bltcpt, 3); + break; + default: + abort(); + } + + blitter_cyclecounter++; + if (blitter_cyclecounter >= blit_dmacount2) { + blitter_cyclecounter = 0; + ddat2 = ddat1; + ddat2use = ddat1use; + ddat1use = 0; + ddat1 = blitter_doblit(); + if (bltcon0 & 0x100) + ddat1use = 1; + blitter_hcounter1++; + if (blitter_hcounter1 == blt_info.hblitsize) { + blitter_hcounter1 = 0; + if (bltcon0 & 0x800) + bltapt += blit_modadda; + if (bltcon0 & 0x400) + bltbpt += blit_modaddb; + if (bltcon0 & 0x200) + bltcpt += blit_modaddc; + blitter_vcounter1++; + blitfc = !!(bltcon1 & 0x4); + } + } + record_dma_blit(reg, dat, addr, hpos); +} + +int blitter_need(int hpos) +{ + int c; + if (bltstate == BLT_done) + return 0; + if (!dmaen(DMA_BLITTER)) + return 0; + c = channel_state(blit_cyclecounter); + return c; +} + +static void do_startcycles(int hpos) +{ + int vhpos = last_blitter_hpos; + while (vhpos < hpos) { + int v = canblit(vhpos); + vhpos++; + if (v > 0) { + blit_startcycles--; + if (blit_startcycles == 0) { + if (blit_faulty) + blit_faulty = -1; + bltstate = BLT_done; + blit_final = 0; + do_blitter(vhpos, 0); + blit_startcycles = 0; + blit_cyclecounter = 0; + blit_waitcyclecounter = 0; + if (blit_faulty) + blit_faulty = 1; + return; + } + } + else { + markidlecycle(hpos); + } + } +} + +void decide_blitter(int hpos) +{ + int hsync = hpos < 0; + + if (hsync && blt_delayed_irq) { + if (blt_delayed_irq > 0) + blt_delayed_irq--; + if (blt_delayed_irq <= 0) { + blt_delayed_irq = 0; + send_interrupt(6, 2 * CYCLE_UNIT); + } + } + + if (immediate_blits) { + if (bltstate == BLT_done) + return; + if (dmaen(DMA_BLITTER)) + blitter_doit(); + return; + } + + if (blit_startcycles > 0) + do_startcycles(hpos); + + if (bltstate == BLT_done) + return; + + if (log_blitter && blitter_delayed_debug) { + blitter_delayed_debug = 0; + blitter_dump(); + } + + if (!blitter_cycle_exact) + return; + + if (hpos < 0) + hpos = maxhpos; + + if (blitline) { + blt_info.got_cycle = 1; + decide_blitter_line(hsync, hpos); + return; + } + + while (last_blitter_hpos < hpos) { + int c; + + c = channel_state(blit_cyclecounter); + + for (;;) { + int v; + + v = canblit(last_blitter_hpos); + + // copper bltsize write needs one cycle (any cycle) delay + if (blit_waitcyclecounter) { + blit_waitcyclecounter = 0; + markidlecycle(last_blitter_hpos); + break; + } + // idle cycles require free bus. + // Final empty cycle does not, unless it is fill mode that requires extra idle cycle + // (CPU can still use this cycle) +#if 1 + if ((blit_cyclecounter < 0 || !blit_final || (blitfill && blit_cycle_diagram_fill[blit_ch][0])) && ((c == 0 && v == 0) || v < 0)) { + blit_misscyclecounter++; + blitter_nasty++; + break; + } +#else + if ((c == 0 && v == 0) || v < 0) { + if (blit_cyclecounter < 0 || !blit_final) { + blit_misscyclecounter++; + break; + } + if (blitfill && blit_cycle_diagram_fill[blit_ch][0]) { + blit_misscyclecounter++; + blitter_nasty++; + break; + } + } +#endif + if (blit_frozen) { + blit_misscyclecounter++; + break; + } + + if (c == 0) { + blt_info.got_cycle = 1; + blit_cyclecounter++; + if (blit_cyclecounter == 0) + blit_final = 0; + blit_totalcyclecounter++; + /* check if blit with zero channels has ended */ + if (blit_ch == 0 && blit_cyclecounter >= blit_maxcyclecounter) { + blitter_done(last_blitter_hpos); + return; + } + markidlecycle(last_blitter_hpos); + break; + } + + blitter_nasty++; + + if (v <= 0) { + blit_misscyclecounter++; + break; + } + + blt_info.got_cycle = 1; + if (c == 4) { + blitter_doddma(last_blitter_hpos); + blit_cyclecounter++; + blit_totalcyclecounter++; + } + else { + if (blitter_vcounter1 < blt_info.vblitsize) { + blitter_dodma(c, last_blitter_hpos); + } + blit_cyclecounter++; + blit_totalcyclecounter++; + } + + if (blitter_vcounter1 >= blt_info.vblitsize && blitter_vcounter2 >= blt_info.vblitsize) { + if (!ddat1use && !ddat2use) { + blitter_done(last_blitter_hpos); + return; + } + } + // check this after end check because last D write won't cause any problems. + check_channel_mods(last_blitter_hpos, c); + break; + } + + if (dmaen(DMA_BLITTER) && !blit_final && (blitter_vcounter1 == blt_info.vblitsize || (blitter_vcounter1 == blt_info.vblitsize - 1 && blitter_hcounter1 == blt_info.hblitsize - 1 && blit_dmacount2 == 0))) { + if (channel_pos(blit_cyclecounter - 1) == blit_diag[0] - 1) { + blitter_interrupt(last_blitter_hpos, 0); + blit_cyclecounter = 0; + blit_final = 1; + } + } + last_blitter_hpos++; + } + reset_channel_mods(); + if (hsync) + last_blitter_hpos = 0; +} +#else +void decide_blitter(int hpos) { } +#endif + +static void blitter_force_finish(void) +{ + uae_u16 odmacon; + if (bltstate == BLT_done) + return; + if (bltstate != BLT_done) { + /* blitter is currently running + * force finish (no blitter state support yet) + */ + odmacon = dmacon; + dmacon |= DMA_MASTER | DMA_BLITTER; + write_log(_T("forcing blitter finish\n")); + if (blitter_cycle_exact && !immediate_blits) { + int rounds = 10000; + while (bltstate != BLT_done && rounds > 0) { +#ifdef CPUEMU_13 + memset(cycle_line, 0, sizeof cycle_line); +#endif + decide_blitter(-1); + rounds--; + } + if (rounds == 0) + write_log(_T("blitter froze!?\n")); + blit_startcycles = 0; + } + else { + actually_do_blit(); + } + blitter_done(current_hpos()); + dmacon = odmacon; + } +} + +static bool invstate(void) { return bltstate != BLT_done && bltstate != BLT_init; } -static void blit_bltset (int con) +static void blit_bltset(int con) { int i; + const int *olddiag = blit_diag; if (con & 2) { blitdesc = bltcon1 & 2; blt_info.blitbshift = bltcon1 >> 12; blt_info.blitdownbshift = 16 - blt_info.blitbshift; if ((bltcon1 & 1) && !blitline_started) { - write_log (_T("BLITTER: linedraw enabled after starting normal blit! %08x\n"), M68K_GETPC); + write_log(_T("BLITTER: linedraw enabled after starting normal blit! %08x\n"), M68K_GETPC); return; } - if (bltstate != BLT_done) { - return; - } } if (con & 1) { @@ -656,25 +1333,88 @@ static void blit_bltset (int con) if (!savestate_state && bltstate != BLT_done && bltstate != BLT_init && blitline && blitline_started) { blitline = 0; bltstate = BLT_done; - write_log (_T("BLITTER: register modification during linedraw! %08x\n"), M68K_GETPC); + blit_interrupt = 1; + write_log(_T("BLITTER: register modification during linedraw! %08x\n"), M68K_GETPC); + //if (log_blitter & 16) + // activate_debugger(); } if (blitline) { + //if (blt_info.hblitsize != 2) { + //debugtest(DEBUGTEST_BLITTER, _T("weird blt_info.hblitsize in linemode: %d vsize=%d\n"), + // blt_info.hblitsize, blt_info.vblitsize); + //if (log_blitter & 16) + // activate_debugger(); + //} blit_diag = blit_cycle_diagram_line; - } else { + } + else { if (con & 2) { blitfc = !!(bltcon1 & 0x4); blitife = !!(bltcon1 & 0x8); if ((bltcon1 & 0x18) == 0x18) { + //debugtest(DEBUGTEST_BLITTER, _T("weird fill mode\n")); blitife = 0; } } + //if (blitfill && !blitdesc) { + //debugtest(DEBUGTEST_BLITTER, _T("fill without desc\n")); + //if (log_blitter & 16) + // activate_debugger(); + //} blit_diag = blitfill && blit_cycle_diagram_fill[blit_ch][0] ? blit_cycle_diagram_fill[blit_ch] : blit_cycle_diagram[blit_ch]; } + //if ((bltcon1 & 0x80) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) { + //debugtest(DEBUGTEST_BLITTER, _T("ECS BLTCON1 DOFF-bit set\n")); + //if (log_blitter & 16) + // activate_debugger(); + //} + + // on the fly switching fillmode from extra cycle to non-extra: blitter freezes + // non-extra cycle to extra cycle: does not freeze but cycle diagram goes weird, + // extra free cycle changes to another D write.. + // (Absolute Inebriation vector cube inside semi-filled vector object requires freezing blitter.) + if (!savestate_state && invstate()) { + static int freezes = 10; + int isen = blit_diag >= &blit_cycle_diagram_fill[0][0] && blit_diag <= &blit_cycle_diagram_fill[15][0]; + int iseo = olddiag >= &blit_cycle_diagram_fill[0][0] && olddiag <= &blit_cycle_diagram_fill[15][0]; + if (iseo != isen) { + if (freezes > 0) { + write_log(_T("BLITTER: on the fly %d (%d) -> %d (%d) switch! PC=%08x\n"), original_ch, iseo, blit_ch, isen, M68K_GETPC); + freezes--; + } + } + if (original_fill == isen) { + blit_frozen = 0; // switched back to original fill mode? unfreeze + } + else if (iseo && !isen) { + blit_frozen = 1; + write_log(_T("BLITTER: frozen! %d (%d) -> %d (%d) %08X\n"), original_ch, iseo, blit_ch, isen, M68K_GETPC); + //if (log_blitter & 16) + // activate_debugger(); + } + else if (!iseo && isen) { + if (!dmaen(DMA_BLITTER)) // subtle shades / nuance bootblock bug + blit_frozen = 1; + if (log_blitter) + write_log(_T("BLITTER: on the fly %d (%d) -> %d (%d) switch\n"), original_ch, iseo, blit_ch, isen); + } + } // on the fly switching from CH=1 to CH=D -> blitter stops writing (Rampage/TEK) // currently just switch to no-channels mode, better than crashing the demo.. - if (!savestate_state && invstate ()) { + if (!savestate_state && invstate()) { + static uae_u8 changetable[32 * 32]; + int o = original_ch + (original_fill ? 16 : 0); + int n = blit_ch + (blitfill ? 16 : 0); + if (o != n) { + if (changetable[o * 32 + n] < 10) { + changetable[o * 32 + n]++; + write_log(_T("BLITTER: channel mode changed while active (%02X->%02X) PC=%08x\n"), o, n, M68K_GETPC); + //if (log_blitter & 16) + // activate_debugger(); + } + } if (blit_ch == 13 && original_ch == 1) { blit_faulty = 1; } @@ -697,162 +1437,331 @@ static void blit_bltset (int con) blit_nod = 0; } if (blit_dmacount2 == 0) { + ddat2use = 0; ddat1use = 0; } } -void reset_blit (int bltcon) +static void blit_modset(void) { - if (bltstate == BLT_done) - return; - blit_bltset (bltcon); + int mult; + + blit_add = blitdesc ? -2 : 2; + mult = blitdesc ? -1 : 1; + blit_modadda = mult * blt_info.bltamod; + blit_modaddb = mult * blt_info.bltbmod; + blit_modaddc = mult * blt_info.bltcmod; + blit_modaddd = mult * blt_info.bltdmod; } -static bool waitingblits (void) +void reset_blit(int bltcon) { - bool waited = false; - while (bltstate != BLT_done && dmaen (DMA_BLITTER)) { - waited = true; - x_do_cycles (8 * CYCLE_UNIT); + if (bltcon & 1) + blinea_shift = bltcon0 >> 12; + if (bltcon & 2) + blitsign = bltcon1 & 0x40; + if (bltstate == BLT_done) + return; + if (bltcon) + blit_bltset(bltcon); + blit_modset(); +} + +static bool waitingblits(void) +{ + //static int warned = 10; + + //bool waited = false; + while (bltstate != BLT_done && dmaen(DMA_BLITTER)) { + //waited = true; + x_do_cycles(8 * CYCLE_UNIT); } + //if (warned && waited) { + // warned--; + // write_log(_T("waiting_blits detected PC=%08x\n"), M68K_GETPC); + //} if (bltstate == BLT_done) return true; return false; } -static void blitter_start_init (void) +static void blitter_start_init(void) { blt_info.blitzero = 1; +#ifdef CPUEMU_13 + preva = 0; + prevb = 0; +#endif + blit_frozen = 0; blitline_started = bltcon1 & 1; - blit_bltset (1 | 2); - ddat1use = 0; + blit_bltset(1 | 2); + blit_modset(); + ddat1use = ddat2use = 0; + blit_interrupt = 0; if (blitline) { - blinea_shift = bltcon0 >> 12; blinea = blt_info.bltadat; blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16 - blt_info.blitbshift)); blitonedot = 0; + blitlinepixel = 0; blitsing = bltcon1 & 0x2; - blitsign = bltcon1 & 0x40; } } -void do_blitter () +static void do_blitter2(int hpos, int copper) { int cycles; int cleanstart; + //if ((log_blitter & 2)) { + // if (bltstate != BLT_done) { + // if (blit_final) { + // write_log(_T("blitter was already active! PC=%08x\n"), M68K_GETPC); + // //activate_debugger(); + // } + // } + //} + cleanstart = 0; if (bltstate == BLT_done) { - blit_faulty = 0; + if (blit_faulty > 0) + blit_faulty = 0; cleanstart = 1; } bltstate = BLT_done; - blit_firstline_cycles = blit_first_cycle = get_cycles (); + blitter_cycle_exact = currprefs.blitter_cycle_exact; + immediate_blits = currprefs.immediate_blits; + blt_info.got_cycle = 0; + last_blitter_hpos = hpos + 1; + blit_firstline_cycles = blit_first_cycle = get_cycles(); + blit_misscyclecounter = 0; blit_last_cycle = 0; + blit_maxcyclecounter = 0; blit_cyclecounter = 0; + blit_totalcyclecounter = 0; - blitter_start_init (); + blitter_start_init(); if (blitline) { cycles = blt_info.vblitsize; - } else { + } + else { cycles = blt_info.vblitsize * blt_info.hblitsize; blit_firstline_cycles = blit_first_cycle + (blit_diag[0] * blt_info.hblitsize) * CYCLE_UNIT + cpu_cycles; } if (cleanstart) { original_ch = blit_ch; + original_fill = blitfill; + original_line = blitline; } - bltstate = BLT_init; + //if ((log_blitter & 1) || ((log_blitter & 32) && !blitline)) { + // blitter_dontdo = 0; + // if (1) { + // int ch = 0; + // if (blit_ch & 1) + // ch++; + // if (blit_ch & 2) + // ch++; + // if (blit_ch & 4) + // ch++; + // if (blit_ch & 8) + // ch++; + // write_log(_T("blitstart: %dx%d ch=%d %d*%d=%d d=%d f=%02x n=%d pc=%08x l=%d dma=%04x %s\n"), + // blt_info.hblitsize, blt_info.vblitsize, ch, blit_diag[0], cycles, blit_diag[0] * cycles, + // blitdesc ? 1 : 0, blitfill, dmaen(DMA_BLITPRI) ? 1 : 0, M68K_GETPC, blitline, + // dmacon, ((dmacon & (DMA_MASTER | DMA_BLITTER)) == (DMA_MASTER | DMA_BLITTER)) ? _T("") : _T(" off!")); + // blitter_dump(); + // } + //} + + bltstate = BLT_init; blit_slowdown = 0; - if (dmaen(DMA_BLITPRI)) - set_special (SPCFLAG_BLTNASTY); - else - unset_special (SPCFLAG_BLTNASTY); + if (dmaen(DMA_BLITPRI)) + set_special(SPCFLAG_BLTNASTY); + else + unset_special(SPCFLAG_BLTNASTY); - if (blt_info.vblitsize == 0 || (blitline && blt_info.hblitsize != 2)) { - if (dmaen (DMA_BLITTER)) - blitter_done (); + if (dmaen(DMA_BLITTER)) + bltstate = BLT_work; + + blit_maxcyclecounter = 0x7fffffff; + blit_waitcyclecounter = 0; + + if (blitter_cycle_exact) { + if (immediate_blits) { + if (dmaen(DMA_BLITTER)) + blitter_doit(); + return; + } + if (log_blitter & 8) { + blitter_handler(0); + } + else { +#ifdef CPUEMU_13 + blitter_hcounter1 = blitter_hcounter2 = 0; + blitter_vcounter1 = blitter_vcounter2 = 0; + if (blit_nod) + blitter_vcounter2 = blt_info.vblitsize; +#endif + blit_cyclecounter = -BLITTER_STARTUP_CYCLES; + blit_waitcyclecounter = copper; + blit_startcycles = 0; + blit_maxcyclecounter = blt_info.hblitsize * blt_info.vblitsize + 2; + } return; } - blit_cyclecounter = cycles * (blit_dmacount2 + (blit_nod ? 0 : 1)); - if (!dmaen (DMA_BLITTER)) - return; - - bltstate = BLT_work; - - if (currprefs.immediate_blits) { - if (dmaen (DMA_BLITTER)) - blitter_doit (); - return; + if (blt_info.vblitsize == 0 || (blitline && blt_info.hblitsize != 2)) { + if (dmaen(DMA_BLITTER)) + blitter_done(hpos); + return; } - event_newevent(ev_blitter, blit_cyclecounter); + if (dmaen(DMA_BLITTER)) { + blt_info.got_cycle = 1; + } - if (dmaen (DMA_BLITTER)) { + if (immediate_blits) { + if (dmaen(DMA_BLITTER)) + blitter_doit(); + return; + } + + blit_cyclecounter = cycles * (blit_dmacount2 + (blit_nod ? 0 : 1)); + event2_newevent(ev2_blitter, blit_cyclecounter, 0); + + if (dmaen(DMA_BLITTER) && (currprefs.cpu_model >= 68020 || !currprefs.cpu_memory_cycle_exact)) { if (currprefs.waiting_blits) { // wait immediately if all cycles in use and blitter nastry if (blit_dmacount == blit_diag[0] && (regs.spcflags & SPCFLAG_BLTNASTY)) { - waitingblits (); + waitingblits(); } } } } -void blitter_check_start (void) +void blitter_check_start(void) { - blitter_start_init (); + if (bltstate != BLT_init) + return; + blitter_start_init(); bltstate = BLT_work; - - if (currprefs.immediate_blits) { - blitter_doit (); - } else { - event_newevent(ev_blitter, blit_cyclecounter); - } + if (immediate_blits) { + blitter_doit(); + } } -void maybe_blit2 (int hack) +void do_blitter(int hpos, int copper) { - if (dmaen (DMA_BLITTER)) { + if (bltstate == BLT_done || !blitter_cycle_exact) { + do_blitter2(hpos, copper); + return; + } + if (!dmaen(DMA_BLITTER) || !blt_info.got_cycle) + return; + // previous blit may have last write cycle left + // and we must let it finish + blit_startcycles = BLITTER_STARTUP_CYCLES; + blit_waitcyclecounter = copper; +} + +void maybe_blit(int hpos, int hack) +{ + static int warned = 10; + + reset_channel_mods(); + + if (bltstate == BLT_done) + return; + + if (savestate_state) + return; + + if (dmaen(DMA_BLITTER) && (currprefs.cpu_model >= 68020 || !currprefs.cpu_memory_cycle_exact)) { bool doit = false; - if (currprefs.waiting_blits) { // automatic + if (currprefs.waiting_blits == 3) { // always + doit = true; + } + else if (currprefs.waiting_blits == 2) { // noidle + if (blit_dmacount == blit_diag[0] && (regs.spcflags & SPCFLAG_BLTNASTY)) + doit = true; + } + else if (currprefs.waiting_blits == 1) { // automatic if (blit_dmacount == blit_diag[0] && (regs.spcflags & SPCFLAG_BLTNASTY)) doit = true; else if (currprefs.m68k_speed < 0) doit = true; } if (doit) { - if (waitingblits ()) + if (waitingblits()) return; } } - if (hack == 1 && get_cycles() < blit_firstline_cycles) - return; + if (warned && dmaen(DMA_BLITTER) && blt_info.got_cycle) { + warned--; + //debugtest(DEBUGTEST_BLITTER, _T("program does not wait for blitter tc=%d\n"), blit_cyclecounter); + if (log_blitter) + warned = 0; + if (log_blitter & 2) { + warned = 10; + write_log(_T("program does not wait for blitter PC=%08x\n"), M68K_GETPC); + } + } - blitter_handler (); + if (blitter_cycle_exact) { + decide_blitter(hpos); + goto end; + } + + if (hack == 1 && int(get_cycles()) - int(blit_firstline_cycles) < 0) + goto end; + + blitter_handler(0); +end:; + if (log_blitter) + blitter_delayed_debug = 1; } -int blitnasty (void) +void check_is_blit_dangerous(uaecptr *bplpt, int planes, int words) +{ + blitter_dangerous_bpl = 0; + if (bltstate == BLT_done || !blitter_cycle_exact) + return; + // too simple but better than nothing + for (int i = 0; i < planes; i++) { + uaecptr bpl = bplpt[i]; + uaecptr dpt = bltdpt & chipmem_bank.mask; + if (dpt >= bpl - 2 * words && dpt < bpl + 2 * words) { + blitter_dangerous_bpl = 1; + return; + } + } +} + +int blitnasty(void) { int cycles, ccnt; if (bltstate == BLT_done) return 0; - if (!dmaen (DMA_BLITTER)) + if (!dmaen(DMA_BLITTER)) return 0; + if (blitter_cycle_exact) { + blitter_force_finish(); + return -1; + } if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[0]) return 0; - cycles = (get_cycles () - blit_first_cycle) / CYCLE_UNIT; + cycles = (get_cycles() - blit_first_cycle) / CYCLE_UNIT; ccnt = 0; while (blit_last_cycle < cycles) { - int c = channel_state (blit_last_cycle++); + int c = channel_state(blit_last_cycle++); if (!c) ccnt++; } @@ -860,172 +1769,266 @@ int blitnasty (void) } /* very approximate emulation of blitter slowdown caused by bitplane DMA */ -void blitter_slowdown (int ddfstrt, int ddfstop, int totalcycles, int freecycles) +void blitter_slowdown(int ddfstrt, int ddfstop, int totalcycles, int freecycles) { - static int oddfstrt, oddfstop, ototal, ofree; - static int slow; + static int oddfstrt, oddfstop, ototal, ofree; + static int slow; - if (!totalcycles || ddfstrt < 0 || ddfstop < 0) - return; - if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) { - int linecycles = ((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles; - int freelinecycles = ((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles; - int dmacycles = (linecycles * blit_dmacount) / blit_diag[0]; - oddfstrt = ddfstrt; - oddfstop = ddfstop; - ototal = totalcycles; - ofree = freecycles; - slow = 0; - if (dmacycles > freelinecycles) - slow = dmacycles - freelinecycles; - } - if (blit_slowdown < 0 || blitline) - return; - blit_slowdown += slow; + if (!totalcycles || ddfstrt < 0 || ddfstop < 0) + return; + if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) { + int linecycles = ((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles; + int freelinecycles = ((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles; + int dmacycles = (linecycles * blit_dmacount) / blit_diag[0]; + oddfstrt = ddfstrt; + oddfstop = ddfstop; + ototal = totalcycles; + ofree = freecycles; + slow = 0; + if (dmacycles > freelinecycles) + slow = dmacycles - freelinecycles; + } + if (blit_slowdown < 0 || blitline) + return; + blit_slowdown += slow; + blit_misscyclecounter += slow; +} + +void blitter_reset(void) +{ + bltptxpos = -1; } #ifdef SAVESTATE -uae_u8 *restore_blitter (uae_u8 *src) +void restore_blitter_finish(void) { - uae_u32 flags = restore_u32(); - - blt_statefile_type = 0; - bltstate = BLT_done; - if (flags & 4) { - bltstate = (flags & 1) ? BLT_done : BLT_init; - } - return src; + //record_dma_reset(); + //record_dma_reset(); + if (blt_statefile_type == 0) { + blit_interrupt = 1; + if (bltstate == BLT_init) { + write_log(_T("blitter was started but DMA was inactive during save\n")); + //do_blitter (0); + } + if (blt_delayed_irq < 0) { + if (intreq & 0x0040) + blt_delayed_irq = 3; + intreq &= ~0x0040; + } + } + else { + last_blitter_hpos = 0; + blit_modset(); + } } -uae_u8 *save_blitter (int *len, uae_u8 *dstptr) +uae_u8 *restore_blitter(uae_u8 *src) { - uae_u8 *dstbak,*dst; - int forced; + uae_u32 flags = restore_u32(); + + blt_statefile_type = 0; + blt_delayed_irq = 0; + bltstate = BLT_done; + if (flags & 4) { + bltstate = (flags & 1) ? BLT_done : BLT_init; + } + if (flags & 2) { + write_log(_T("blitter was force-finished when this statefile was saved\n")); + write_log(_T("contact the author if restored program freezes\n")); + // there is a problem. if system ks vblank is active, we must not activate + // "old" blit's intreq until vblank is handled or ks 1.x thinks it was blitter + // interrupt.. + blt_delayed_irq = -1; + } + return src; +} + +uae_u8 *save_blitter(int *len, uae_u8 *dstptr) +{ + uae_u8 *dstbak, *dst; + int forced; + + forced = 0; + if (bltstate != BLT_done && bltstate != BLT_init) { + write_log(_T("blitter is active, forcing immediate finish\n")); + /* blitter is active just now but we don't have blitter state support yet */ + blitter_force_finish(); + forced = 2; + } + if (dstptr) + dstbak = dst = dstptr; + else + dstbak = dst = xmalloc(uae_u8, 16); + save_u32(((bltstate != BLT_done) ? 0 : 1) | forced | 4); + *len = dst - dstbak; + return dstbak; - forced = 0; - if (bltstate != BLT_done && bltstate != BLT_init) { - write_log (_T("blitter is active, forcing immediate finish\n")); - /* blitter is active just now but we don't have blitter state support yet */ - blitter_force_finish (); - forced = 2; - } - if (dstptr) - dstbak = dst = dstptr; - else - dstbak = dst = xmalloc (uae_u8, 16); - save_u32(((bltstate != BLT_done) ? 0 : 1) | forced | 4); - *len = dst - dstbak; - return dstbak; } // totally non-real-blitter-like state save but better than nothing.. -uae_u8 *restore_blitter_new (uae_u8 *src) +uae_u8 *restore_blitter_new(uae_u8 *src) { uae_u8 state; blt_statefile_type = 1; - state = restore_u8 (); + blitter_cycle_exact = restore_u8(); + state = restore_u8(); - blit_first_cycle = restore_u32 (); - blit_last_cycle = restore_u32 (); - blit_firstline_cycles = restore_u32 (); - blit_cyclecounter = restore_u32 (); - blit_slowdown = restore_u32 (); + blit_first_cycle = restore_u32(); + blit_last_cycle = restore_u32(); + blit_waitcyclecounter = restore_u32(); + blit_startcycles = restore_u32(); + blit_maxcyclecounter = restore_u32(); + blit_firstline_cycles = restore_u32(); + blit_cyclecounter = restore_u32(); + blit_slowdown = restore_u32(); + blit_misscyclecounter = restore_u32(); +#ifdef CPUEMU_13 + blitter_hcounter1 = restore_u16(); + blitter_hcounter2 = restore_u16(); + blitter_vcounter1 = restore_u16(); + blitter_vcounter2 = restore_u16(); +#endif + blit_ch = restore_u8(); + blit_dmacount = restore_u8(); + blit_dmacount2 = restore_u8(); + blit_nod = restore_u8(); + blit_final = restore_u8(); + blitfc = restore_u8(); + blitife = restore_u8(); - blit_ch = restore_u8 (); - blit_dmacount = restore_u8 (); - blit_dmacount2 = restore_u8 (); - blit_nod = restore_u8 (); - blitfc = restore_u8 (); - blitife = restore_u8 (); + blt_info.blitbshift = restore_u8(); + blt_info.blitdownbshift = restore_u8(); + blt_info.blitashift = restore_u8(); + blt_info.blitdownashift = restore_u8(); - blt_info.blitbshift = restore_u8 (); - blt_info.blitdownbshift = restore_u8 (); - blt_info.blitashift = restore_u8 (); - blt_info.blitdownashift = restore_u8 (); + ddat1use = restore_u8(); + ddat2use = restore_u8(); + ddat1 = restore_u16(); + ddat2 = restore_u16(); - ddat1use = restore_u8 (); + blitline = restore_u8(); + blitfill = restore_u8(); + blinea = restore_u16(); + blineb = restore_u16(); + blinea_shift = restore_u8(); + blitonedot = restore_u8(); + blitlinepixel = restore_u8(); + blitsing = restore_u8(); + blitlinepixel = restore_u8(); + blit_interrupt = restore_u8(); + blt_delayed_irq = restore_u8(); + blt_info.blitzero = restore_u8(); + blt_info.got_cycle = restore_u8(); - blitline = restore_u8 (); - blitfill = restore_u8 (); - blinea = restore_u16 (); - blineb = restore_u16 (); - blinea_shift = restore_u8 (); - blitonedot = restore_u8 (); - blitsing = restore_u8 (); - blt_info.blitzero = restore_u8 (); + blit_frozen = restore_u8(); + blit_faulty = restore_u8(); + original_ch = restore_u8(); + original_fill = restore_u8(); + original_line = restore_u8(); - blit_faulty = restore_u8 (); - original_ch = restore_u8 (); + blit_diag = set_cycle_diagram_type(restore_u8()); - blit_diag = set_cycle_diagram_type (restore_u8 ()); + if (restore_u16() != 0x1234) + write_log(_T("error\n")); - if (restore_u16 () != 0x1234) - write_log (_T("error\n")); + blitter_nasty = restore_u8(); bltstate = BLT_done; - if (state > 0) - do_blitter (); + if (!blitter_cycle_exact) { + if (state > 0) + do_blitter(0, 0); + } + else { + if (state == 1) + bltstate = BLT_init; + else if (state == 2) + bltstate = BLT_work; + } return src; } -uae_u8 *save_blitter_new (int *len, uae_u8 *dstptr) +uae_u8 *save_blitter_new(int *len, uae_u8 *dstptr) { - uae_u8 *dstbak,*dst; + uae_u8 *dstbak, *dst; if (dstptr) dstbak = dst = dstptr; else - dstbak = dst = xmalloc (uae_u8, 1000); + dstbak = dst = xmalloc(uae_u8, 1000); uae_u8 state; + save_u8(blitter_cycle_exact ? 1 : 0); if (bltstate == BLT_done) state = 0; else if (bltstate == BLT_init) state = 1; else state = 2; - save_u8 (state); + save_u8(state); if (bltstate != BLT_done) { - write_log (_T("BLITTER active while saving state\n")); - blitter_dump (); + //write_log(_T("BLITTER active while saving state\n")); + //blitter_dump(); } - save_u32 (blit_first_cycle); - save_u32 (blit_last_cycle); - save_u32 (blit_firstline_cycles); - save_u32 (blit_cyclecounter); - save_u32 (blit_slowdown); + save_u32(blit_first_cycle); + save_u32(blit_last_cycle); + save_u32(blit_waitcyclecounter); + save_u32(blit_startcycles); + save_u32(blit_maxcyclecounter); + save_u32(blit_firstline_cycles); + save_u32(blit_cyclecounter); + save_u32(blit_slowdown); + save_u32(blit_misscyclecounter); +#ifdef CPUEMU_13 + save_u16(blitter_hcounter1); + save_u16(blitter_hcounter2); + save_u16(blitter_vcounter1); + save_u16(blitter_vcounter2); +#endif + save_u8(blit_ch); + save_u8(blit_dmacount); + save_u8(blit_dmacount2); + save_u8(blit_nod); + save_u8(blit_final); + save_u8(blitfc); + save_u8(blitife); - save_u8 (blit_ch); - save_u8 (blit_dmacount); - save_u8 (blit_dmacount2); - save_u8 (blit_nod); - save_u8 (blitfc); - save_u8 (blitife); + save_u8(blt_info.blitbshift); + save_u8(blt_info.blitdownbshift); + save_u8(blt_info.blitashift); + save_u8(blt_info.blitdownashift); - save_u8 (blt_info.blitbshift); - save_u8 (blt_info.blitdownbshift); - save_u8 (blt_info.blitashift); - save_u8 (blt_info.blitdownashift); + save_u8(ddat1use); + save_u8(ddat2use); + save_u16(ddat1); + save_u16(ddat2); - save_u8 (ddat1use); + save_u8(blitline); + save_u8(blitfill); + save_u16(blinea); + save_u16(blineb); + save_u8(blinea_shift); + save_u8(blitonedot); + save_u8(blitlinepixel); + save_u8(blitsing); + save_u8(blitlinepixel); + save_u8(blit_interrupt); + save_u8(blt_delayed_irq); + save_u8(blt_info.blitzero); + save_u8(blt_info.got_cycle); - save_u8 (blitline); - save_u8 (blitfill); - save_u16 (blinea); - save_u16 (blineb); - save_u8 (blinea_shift); - save_u8 (blitonedot); - save_u8 (blitsing); - save_u8 (blt_info.blitzero); - - save_u8 (blit_faulty); - save_u8 (original_ch); - save_u8 (get_cycle_diagram_type (blit_diag)); + save_u8(blit_frozen); + save_u8(blit_faulty); + save_u8(original_ch); + save_u8(original_fill); + save_u8(original_line); + save_u8(get_cycle_diagram_type(blit_diag)); - save_u16 (0x1234); + save_u16(0x1234); + + save_u8(blitter_nasty); *len = dst - dstbak; return dstbak; diff --git a/src/blkdev.cpp b/src/blkdev.cpp index 1a12f173..1f30fad0 100644 --- a/src/blkdev.cpp +++ b/src/blkdev.cpp @@ -10,7 +10,7 @@ #include "sysconfig.h" #include "sysdeps.h" #include "options.h" -#include "memory.h" +#include "include/memory.h" #include "blkdev.h" #include "scsidev.h" @@ -133,24 +133,24 @@ int isdatatrack(struct cd_toc_head *th, int block) static int cdscsidevicetype[MAX_TOTAL_SCSI_DEVICES]; -#ifdef _WIN32 - -#include "od-win32/win32.h" - -extern struct device_functions devicefunc_win32_spti; -extern struct device_functions devicefunc_win32_ioctl; - -#endif +//#ifdef _WIN32 +// +//#include "od-win32/win32.h" +// +//extern struct device_functions devicefunc_win32_spti; +//extern struct device_functions devicefunc_win32_ioctl; +// +//#endif extern struct device_functions devicefunc_cdimage; static struct device_functions *devicetable[] = { NULL, &devicefunc_cdimage, -#ifdef _WIN32 - &devicefunc_win32_ioctl, - &devicefunc_win32_spti, -#endif +//#ifdef _WIN32 +// &devicefunc_win32_ioctl, +// &devicefunc_win32_spti, +//#endif NULL }; static int driver_installed[6]; diff --git a/src/cfgfile.cpp b/src/cfgfile.cpp index fa8f2ad5..1d9c41de 100644 --- a/src/cfgfile.cpp +++ b/src/cfgfile.cpp @@ -32,6 +32,9 @@ #include "calc.h" #include "gfxboard.h" +#define cfgfile_warning write_log +#define cfgfile_warning_obsolete write_log + static int config_newfilesystem; static struct strlist *temp_lines; static struct strlist *error_lines; @@ -94,10 +97,8 @@ static const struct cfg_lines opttable[] = { _T("comp_trustlong"), _T("How to access longs in compiler (direct/indirect/indirectKS/afterPic") }, { _T("comp_nf"), _T("Whether to optimize away flag generation where possible") }, { _T("comp_fpu"), _T("Whether to provide JIT FPU emulation") }, - { _T("compforcesettings"), _T("Whether to force the JIT compiler settings") }, { _T("cachesize"), _T("How many MB to use to buffer translated instructions") }, { _T("override_dga_address"),_T("Address from which to map the frame buffer (upper 16 bits) (DANGEROUS!)") }, - { _T("avoid_cmov"), _T("Set to yes on machines that lack the CMOV instruction") }, { _T("avoid_dga"), _T("Set to yes if the use of DGA extension creates problems") }, { _T("avoid_vid"), _T("Set to yes if the use of the Vidmode extension creates problems") }, { _T("parallel_on_demand"), _T("") }, @@ -120,10 +121,10 @@ static const struct cfg_lines opttable[] = { _T("catweasel"), _T("Catweasel board io base address") } }; -static const TCHAR* guimode1[] = {_T("no"), _T("yes"), _T("nowait"), 0}; -static const TCHAR* guimode2[] = {_T("false"), _T("true"), _T("nowait"), 0}; -static const TCHAR* guimode3[] = {_T("0"), _T("1"), _T("nowait"), 0}; -static const TCHAR* csmode[] = {_T("ocs"), _T("ecs_agnus"), _T("ecs_denise"), _T("ecs"), _T("aga"), 0}; +static const TCHAR *guimode1[] = { _T("no"), _T("yes"), _T("nowait"), 0 }; +static const TCHAR *guimode2[] = { _T("false"), _T("true"), _T("nowait"), 0 }; +static const TCHAR *guimode3[] = { _T("0"), _T("1"), _T("nowait"), 0 }; +static const TCHAR *csmode[] = { _T("ocs"), _T("ecs_agnus"), _T("ecs_denise"), _T("ecs"), _T("aga"), 0 }; static const TCHAR *linemode[] = { _T("none"), _T("double"), _T("scanlines"), _T("scanlines2p"), _T("scanlines3p"), @@ -142,7 +143,7 @@ static const TCHAR *interpolmode[] = { _T("none"), _T("anti"), _T("sinc"), _T("r static const TCHAR *collmode[] = { _T("none"), _T("sprites"), _T("playfields"), _T("full"), 0 }; static const TCHAR *compmode[] = { _T("direct"), _T("indirect"), _T("indirectKS"), _T("afterPic"), 0 }; static const TCHAR *flushmode[] = { _T("soft"), _T("hard"), 0 }; -static const TCHAR *kbleds[] = { _T("none"), _T("POWER"), _T("DF0"), _T("DF1"), _T("DF2"), _T("DF3"), _T("HD"), _T("CD"), 0 }; +static const TCHAR *kbleds[] = { _T("none"), _T("POWER"), _T("DF0"), _T("DF1"), _T("DF2"), _T("DF3"), _T("HD"), _T("CD"), _T("DFx"), 0 }; static const TCHAR *onscreenleds[] = { _T("false"), _T("true"), _T("rtg"), _T("both"), 0 }; static const TCHAR *soundfiltermode1[] = { _T("off"), _T("emulated"), _T("on"), 0 }; static const TCHAR *soundfiltermode2[] = { _T("standard"), _T("enhanced"), 0 }; @@ -160,11 +161,13 @@ static const TCHAR *rtctype[] = { _T("none"), _T("MSM6242B"), _T("RP5C01A"), _T( static const TCHAR *ciaatodmode[] = { _T("vblank"), _T("50hz"), _T("60hz"), 0 }; static const TCHAR *ksmirrortype[] = { _T("none"), _T("e0"), _T("a8+e0"), 0 }; static const TCHAR *cscompa[] = { - _T("-"), _T("Generic"), _T("CDTV"), _T("CD32"), _T("A500"), _T("A500+"), _T("A600"), - _T("A1000"), _T("A1200"), _T("A2000"), _T("A3000"), _T("A3000T"), _T("A4000"), _T("A4000T"), 0 + _T("-"), _T("Generic"), _T("CDTV"), _T("CDTV-CR"), _T("CD32"), _T("A500"), _T("A500+"), _T("A600"), + _T("A1000"), _T("A1200"), _T("A2000"), _T("A3000"), _T("A3000T"), _T("A4000"), _T("A4000T"), + _T("Velvet"), + NULL }; static const TCHAR *qsmodes[] = { - _T("A500"), _T("A500+"), _T("A600"), _T("A1000"), _T("A1200"), _T("A3000"), _T("A4000"), _T(""), _T("CD32"), _T("CDTV"), _T("ARCADIA"), NULL }; + _T("A500"), _T("A500+"), _T("A600"), _T("A1000"), _T("A1200"), _T("A3000"), _T("A4000"), _T(""), _T("CD32"), _T("CDTV"), _T("CDTV-CR"), _T("ARCADIA"), NULL }; /* 3-state boolean! */ static const TCHAR *fullmodes[] = { _T("false"), _T("true"), /* "FILE_NOT_FOUND", */ _T("fullwindow"), 0 }; /* bleh for compatibility */ @@ -173,13 +176,15 @@ static const TCHAR *maxhoriz[] = { _T("lores"), _T("hires"), _T("superhires"), 0 static const TCHAR *maxvert[] = { _T("nointerlace"), _T("interlace"), 0 }; static const TCHAR *abspointers[] = { _T("none"), _T("mousehack"), _T("tablet"), 0 }; static const TCHAR *magiccursors[] = { _T("both"), _T("native"), _T("host"), 0 }; -static const TCHAR *autoscale[] = { _T("none"), _T("auto"), _T("standard"), _T("max"), _T("scale"), _T("resize"), _T("center"), _T("manual"), _T("integer"), _T("integer_auto"), 0 }; +static const TCHAR *autoscale[] = { _T("none"), _T("auto"), _T("standard"), _T("max"), _T("scale"), _T("resize"), _T("center"), _T("manual"), +_T("integer"), _T("integer_auto"), _T("separator"), _T("overscan_blanking"), 0 }; static const TCHAR *autoscale_rtg[] = { _T("resize"), _T("scale"), _T("center"), _T("integer"), 0 }; +static const TCHAR *autoscalelimit[] = { _T("1/1"), _T("1/2"), _T("1/4"), _T("1/8"), 0 }; static const TCHAR *joyportmodes[] = { _T(""), _T("mouse"), _T("mousenowheel"), _T("djoy"), _T("gamepad"), _T("ajoy"), _T("cdtvjoy"), _T("cd32joy"), _T("lightpen"), 0 }; -static const TCHAR *joyaf[] = { _T("none"), _T("normal"), _T("toggle"), 0 }; +static const TCHAR *joyaf[] = { _T("none"), _T("normal"), _T("toggle"), _T("always"), 0 }; static const TCHAR *epsonprinter[] = { _T("none"), _T("ascii"), _T("epson_matrix_9pin"), _T("epson_matrix_24pin"), _T("epson_matrix_48pin"), 0 }; static const TCHAR *aspects[] = { _T("none"), _T("vga"), _T("tv"), 0 }; -static const TCHAR *vsyncmodes[] = { _T("false"), _T("true"), _T("autoswitch"), 0 }; +static const TCHAR *vsyncmodes[] = { _T("adaptive"), _T("false"), _T("true"), _T("autoswitch"), 0 }; static const TCHAR *vsyncmodes2[] = { _T("normal"), _T("busywait"), 0 }; static const TCHAR *filterapi[] = { _T("directdraw"), _T("direct3d"), 0 }; static const TCHAR *dongles[] = @@ -191,21 +196,95 @@ static const TCHAR *dongles[] = }; static const TCHAR *cdmodes[] = { _T("disabled"), _T(""), _T("image"), _T("ioctl"), _T("spti"), _T("aspi"), 0 }; static const TCHAR *cdconmodes[] = { _T(""), _T("uae"), _T("ide"), _T("scsi"), _T("cdtv"), _T("cd32"), 0 }; -static const TCHAR *specialmonitors[] = { _T("none"), _T("autodetect"), _T("a2024"), _T("graffiti"), 0 }; -static const TCHAR *rtgtype[] = { - _T("ZorroII"), _T("ZorroIII"), - _T("PicassoII"), - _T("PicassoII+"), - _T("Piccolo_Z2"), _T("Piccolo_Z3"), - _T("PiccoloSD64_Z2"), _T("PiccoloSD64_Z3"), - _T("Spectrum28/24_Z2"), _T("Spectrum28/24_Z3"), - _T("PicassoIV_Z2"), _T("PicassoIV_Z3"), - 0 }; +static const TCHAR *specialmonitors[] = { _T("none"), _T("autodetect"), _T("a2024"), _T("graffiti"), +_T("ham_e"), _T("ham_e_plus"), _T("videodac18"), _T("avideo12"), _T("avideo24"), _T("firecracker24"), _T("dctv"), _T("opalvision"), _T("colorburst"), 0 }; +static const TCHAR *genlockmodes[] = { _T("none"), _T("noise"), _T("testcard"), _T("image"), _T("video"), _T("stream"), _T("ld"), _T("sony_ld"), _T("pioneer_ld"), NULL }; +static const TCHAR *ppc_implementations[] = { + _T("auto"), + _T("dummy"), + _T("pearpc"), + _T("qemu"), + NULL +}; +static const TCHAR *ppc_cpu_idle[] = { + _T("disabled"), + _T("1"), + _T("2"), + _T("3"), + _T("4"), + _T("5"), + _T("6"), + _T("7"), + _T("8"), + _T("9"), + _T("max"), + NULL +}; static const TCHAR *waitblits[] = { _T("disabled"), _T("automatic"), _T("noidleonly"), _T("always"), 0 }; static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), 0 }; static const TCHAR *leds[] = { _T("power"), _T("df0"), _T("df1"), _T("df2"), _T("df3"), _T("hd"), _T("cd"), _T("fps"), _T("cpu"), _T("snd"), _T("md"), 0 }; -static int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9 }; +static const int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9 }; static const TCHAR *lacer[] = { _T("off"), _T("i"), _T("p"), 0 }; +/* another boolean to choice update.. */ +static const TCHAR *cycleexact[] = { _T("false"), _T("memory"), _T("true"), 0 }; + +struct hdcontrollerconfig +{ + const TCHAR *label; + int romtype; +}; + +static const struct hdcontrollerconfig hdcontrollers[] = { + { _T("uae"), 0 }, + + { _T("ide%d"), 0 }, + { _T("ide%d_mainboard"), ROMTYPE_MB_IDE }, + + { _T("scsi%d"), 0 }, + { _T("scsi%d_a3000"), ROMTYPE_SCSI_A3000 }, + { _T("scsi%d_a4000t"), ROMTYPE_SCSI_A4000T }, + { _T("scsi%d_cdtv"), ROMTYPE_CDTVSCSI }, + + { NULL } +}; +static const TCHAR *z3mapping[] = { + _T("auto"), + _T("uae"), + _T("real"), + NULL +}; +static const TCHAR *uaescsidevmodes[] = { + _T("original"), + _T("rename_scsi"), + NULL +}; +static const TCHAR *uaebootrom[] = { + _T("automatic"), + _T("disabled"), + _T("min"), + _T("full"), + NULL +}; +static const TCHAR *uaeboard[] = { + _T("disabled"), + _T("min"), + _T("full"), + _T("full+indirect"), + NULL +}; + +static const TCHAR *serialcrlf[] = { + _T("disabled"), + _T("crlf_cr"), + NULL +}; +static const TCHAR *threebitcolors[] = { + _T("disabled"), + _T("3to4to8bit"), + _T("3to4bit"), + _T("3to8bit"), + NULL +}; static const TCHAR *obsolete[] = { _T("accuracy"), _T("gfx_opengl"), _T("gfx_32bit_blits"), _T("32bit_blits"), @@ -216,17 +295,77 @@ static const TCHAR *obsolete[] = { _T("serial_hardware_dtrdsr"), _T("gfx_filter_upscale"), _T("gfx_correct_aspect"), _T("gfx_autoscale"), _T("parallel_sampler"), _T("parallel_ascii_emulation"), _T("avoid_vid"), _T("avoid_dga"), _T("z3chipmem_size"), _T("state_replay_buffer"), _T("state_replay"), + _T("z3realmapping"), _T("force_0x10000000_z3"), _T("gfx_filter_vert_zoom"),_T("gfx_filter_horiz_zoom"), _T("gfx_filter_vert_zoom_mult"), _T("gfx_filter_horiz_zoom_mult"), _T("gfx_filter_vert_offset"), _T("gfx_filter_horiz_offset"), - _T("rtg_vert_zoom_multf"), _T("rtg_horiz_zoom_multf"), + + // created by some buggy beta + _T("uaehf0%s,%s"), + _T("uaehf1%s,%s"), + _T("uaehf2%s,%s"), + _T("uaehf3%s,%s"), + _T("uaehf4%s,%s"), + _T("uaehf5%s,%s"), + _T("uaehf6%s,%s"), + _T("uaehf7%s,%s"), + + _T("pcibridge_rom_file"), + _T("pcibridge_rom_options"), + + _T("cpuboard_ext_rom_file"), + _T("uaeboard_mode"), + + _T("comp_oldsegv"), + _T("comp_midopt"), + _T("comp_lowopt"), + _T("avoid_cmov"), + _T("compforcesettings"), NULL }; #define UNEXPANDED _T("$(FILE_PATH)") +static TCHAR *cfgfile_option_find_it(const TCHAR *s, const TCHAR *option, bool checkequals) +{ + TCHAR buf[MAX_DPATH]; + if (!s) + return NULL; + _tcscpy(buf, s); + _tcscat(buf, _T(",")); + TCHAR *p = buf; + for (;;) { + TCHAR *tmpp = _tcschr(p, ','); + TCHAR *tmpp2 = NULL; + if (tmpp == NULL) + return NULL; + *tmpp++ = 0; + if (checkequals) { + tmpp2 = _tcschr(p, '='); + if (tmpp2) + *tmpp2++ = 0; + } + if (!strcasecmp(p, option)) { + if (checkequals && tmpp2) + return tmpp2; + return p; + } + p = tmpp; + } +} + +static bool cfgfile_option_find(const TCHAR *s, const TCHAR *option) +{ + return cfgfile_option_find_it(s, option, false) != NULL; +} + +static TCHAR *cfgfile_option_get(const TCHAR *s, const TCHAR *option) +{ + return cfgfile_option_find_it(s, option, true); +} + static void trimwsa(char *s) { /* Delete trailing whitespace. */ @@ -245,59 +384,43 @@ static int match_string(const TCHAR *table[], const TCHAR *str) } // escape config file separators and control characters -static TCHAR* cfgfile_escape(const TCHAR* s, const TCHAR* escstr, bool quote) +static TCHAR *cfgfile_escape(const TCHAR *s, const TCHAR *escstr, bool quote) { bool doquote = false; int cnt = 0; - - for (int i = 0; s[i]; i++) - { + for (int i = 0; s[i]; i++) { TCHAR c = s[i]; if (c == 0) break; - if (c < 32 || c == '\\' || c == '\"' || c == '\'') - { + if (c < 32 || c == '\\' || c == '\"' || c == '\'') { cnt++; } - for (int j = 0; escstr && escstr[j]; j++) - { - if (c == escstr[j]) - { + for (int j = 0; escstr && escstr[j]; j++) { + if (c == escstr[j]) { cnt++; - if (quote) - { + if (quote) { doquote = true; cnt++; } } } } - - TCHAR* s2 = xmalloc(TCHAR, _tcslen(s) + cnt * 4 + 1); - TCHAR* p = s2; - + TCHAR *s2 = xmalloc(TCHAR, _tcslen(s) + cnt * 4 + 1); + TCHAR *p = s2; if (doquote) *p++ = '\"'; - - for (int i = 0; s[i]; i++) - { + for (int i = 0; s[i]; i++) { TCHAR c = s[i]; - if (c == 0) break; - - if (c == '\\' || c == '\"' || c == '\'') - { + if (c == '\\' || c == '\"' || c == '\'') { *p++ = '\\'; *p++ = c; } - else if (c >= 32 && !quote) - { + else if (c >= 32 && !quote) { bool escaped = false; - for (int j = 0; escstr && escstr[j]; j++) - { - if (c == escstr[j]) - { + for (int j = 0; escstr && escstr[j]; j++) { + if (c == escstr[j]) { *p++ = '\\'; *p++ = c; escaped = true; @@ -307,8 +430,7 @@ static TCHAR* cfgfile_escape(const TCHAR* s, const TCHAR* escstr, bool quote) if (!escaped) *p++ = c; } - else if (c < 32) - { + else if (c < 32) { *p++ = '\\'; switch (c) { @@ -328,49 +450,36 @@ static TCHAR* cfgfile_escape(const TCHAR* s, const TCHAR* escstr, bool quote) break; } } - else - { + else { *p++ = c; } } - if (doquote) *p++ = '\"'; - *p = 0; return s2; } - -static TCHAR* cfgfile_unescape(const TCHAR* s, const TCHAR** endpos, TCHAR separator) +static TCHAR *cfgfile_unescape(const TCHAR *s, const TCHAR **endpos, TCHAR separator) { bool quoted = false; - TCHAR* s2 = xmalloc(TCHAR, _tcslen(s) + 1); - TCHAR* p = s2; - - if (s[0] == '\"') - { + TCHAR *s2 = xmalloc(TCHAR, _tcslen(s) + 1); + TCHAR *p = s2; + if (s[0] == '\"') { s++; quoted = true; } - int i; - for (i = 0; s[i]; i++) - { + for (i = 0; s[i]; i++) { TCHAR c = s[i]; - if (quoted && c == '\"') - { + if (quoted && c == '\"') { i++; break; } - - if (c == separator) - { + if (c == separator) { i++; break; } - - if (c == '\\') - { + if (c == '\\') { char v = 0; TCHAR c2; c = s[i + 1]; @@ -397,8 +506,7 @@ static TCHAR* cfgfile_unescape(const TCHAR* s, const TCHAR** endpos, TCHAR separ } i++; } - else - { + else { *p++ = c; } } @@ -407,55 +515,44 @@ static TCHAR* cfgfile_unescape(const TCHAR* s, const TCHAR** endpos, TCHAR separ *endpos = &s[i]; return s2; } - -static TCHAR* cfgfile_unescape(const TCHAR* s, const TCHAR** endpos) +static TCHAR *cfgfile_unescape(const TCHAR *s, const TCHAR **endpos) { return cfgfile_unescape(s, endpos, 0); } -static TCHAR* getnextentry(const TCHAR** valuep, const TCHAR separator) +static TCHAR *getnextentry(const TCHAR **valuep, const TCHAR separator) { - TCHAR* s; - const TCHAR* value = *valuep; - if (value[0] == '\"') - { + TCHAR *s; + const TCHAR *value = *valuep; + if (value[0] == '\"') { s = cfgfile_unescape(value, valuep); value = *valuep; - - if (*value != 0 && *value != separator) - { + if (*value != 0 && *value != separator) { xfree(s); return NULL; } - value++; *valuep = value; } - else - { + else { s = cfgfile_unescape(value, valuep, separator); } return s; } -static TCHAR* cfgfile_subst_path2(const TCHAR* path, const TCHAR* subst, const TCHAR* file) +static TCHAR *cfgfile_subst_path2(const TCHAR *path, const TCHAR *subst, const TCHAR *file) { /* @@@ use strcasecmp for some targets. */ - if (_tcslen(path) > 0 && _tcsncmp(file, path, _tcslen(path)) == 0) - { + if (_tcslen(path) > 0 && _tcsncmp(file, path, _tcslen(path)) == 0) { int l; TCHAR *p2, *p = xmalloc(TCHAR, _tcslen(file) + _tcslen(subst) + 2); _tcscpy(p, subst); l = _tcslen(p); - while (l > 0 && p[l - 1] == '/') p[--l] = '\0'; - l = _tcslen(path); - while (file[l] == '/') l++; - _tcscat(p, _T("/")); _tcscat(p, file + l); p2 = target_expand_environment(p); @@ -751,17 +848,13 @@ static void cfgfile_dwrite_path(struct zfile *f, struct multipath *mp, const TCH static void write_filesys_config(struct uae_prefs *p, struct zfile *f) { - int i; - TCHAR tmp[MAX_DPATH], tmp2[MAX_DPATH], tmp3[MAX_DPATH]; - TCHAR *hdcontrollers[] = { _T("uae"), - _T("ide0"), _T("ide1"), _T("ide2"), _T("ide3"), - _T("scsi0"), _T("scsi1"), _T("scsi2"), _T("scsi3"), _T("scsi4"), _T("scsi5"), _T("scsi6"), - _T("scsram"), _T("scide") }; /* scsram = smart card sram = pcmcia sram card */ + TCHAR tmp[MAX_DPATH], tmp2[MAX_DPATH], tmp3[MAX_DPATH], hdcs[MAX_DPATH]; - for (i = 0; i < p->mountitems; i++) { + for (int i = 0; i < p->mountitems; i++) { struct uaedev_config_data *uci = &p->mountconfig[i]; struct uaedev_config_info *ci = &uci->ci; - TCHAR *str1, *str2, *str1b, *str2b; + TCHAR *str1, *str1b, *str2b; + const TCHAR *str2; int bp = ci->bootpri; str2 = _T(""); @@ -773,7 +866,7 @@ static void write_filesys_config(struct uae_prefs *p, struct zfile *f) if (ptr) { *ptr++ = 0; str2 = ptr; - ptr = _tcschr(str2, ','); + ptr = (TCHAR *)_tcschr(str2, ','); if (ptr) *ptr = 0; } @@ -781,6 +874,41 @@ static void write_filesys_config(struct uae_prefs *p, struct zfile *f) else { str1 = cfgfile_put_multipath(&p->path_hardfile, ci->rootdir); } + int ct = ci->controller_type; + int romtype = 0; + if (ct >= HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST && ct <= HD_CONTROLLER_TYPE_SCSI_LAST) { + _stprintf(hdcs, _T("scsi%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST].name); + romtype = expansionroms[ct - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST].romtype; + } + else if (ct >= HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST && ct <= HD_CONTROLLER_TYPE_IDE_LAST) { + _stprintf(hdcs, _T("ide%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST].name); + romtype = expansionroms[ct - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST].romtype; + } + else if (ct == HD_CONTROLLER_TYPE_SCSI_AUTO) { + _stprintf(hdcs, _T("scsi%d"), ci->controller_unit); + } + else if (ct == HD_CONTROLLER_TYPE_IDE_AUTO) { + _stprintf(hdcs, _T("ide%d"), ci->controller_unit); + } + else if (ct == HD_CONTROLLER_TYPE_PCMCIA) { + if (ci->controller_type_unit == 0) + _tcscpy(hdcs, _T("scsram")); + else + _tcscpy(hdcs, _T("scide")); + } + else if (ct == HD_CONTROLLER_TYPE_UAE) { + _tcscpy(hdcs, _T("uae")); + } + if (romtype) { + for (int j = 0; hdcontrollers[j].label; j++) { + if (hdcontrollers[j].romtype == (romtype & ROMTYPE_MASK)) { + _stprintf(hdcs, hdcontrollers[j].label, ci->controller_unit); + break; + } + } + } + if (ci->controller_type_unit > 0 && ct != HD_CONTROLLER_TYPE_PCMCIA) + _stprintf(hdcs + _tcslen(hdcs), _T("-%d"), ci->controller_type_unit + 1); str1b = cfgfile_escape(str1, _T(":,"), true); str2b = cfgfile_escape(str2, _T(":,"), true); @@ -789,32 +917,86 @@ static void write_filesys_config(struct uae_prefs *p, struct zfile *f) ci->devname ? ci->devname : _T(""), ci->volname, str1, bp); cfgfile_write_str(f, _T("filesystem2"), tmp); _tcscpy(tmp3, tmp); +#if 0 + _stprintf(tmp2, _T("filesystem=%s,%s:%s"), uci->readonly ? _T("ro") : _T("rw"), + uci->volname, str); + zfile_fputs(f, tmp2); +#endif } else if (ci->type == UAEDEV_HDF || ci->type == UAEDEV_CD || ci->type == UAEDEV_TAPE) { _stprintf(tmp, _T("%s,%s:%s,%d,%d,%d,%d,%d,%s,%s"), ci->readonly ? _T("ro") : _T("rw"), ci->devname ? ci->devname : _T(""), str1, ci->sectors, ci->surfaces, ci->reserved, ci->blocksize, - bp, ci->filesys ? ci->filesys : _T(""), hdcontrollers[ci->controller]); + bp, ci->filesys ? ci->filesys : _T(""), hdcs); _stprintf(tmp3, _T("%s,%s:%s%s%s,%d,%d,%d,%d,%d,%s,%s"), ci->readonly ? _T("ro") : _T("rw"), ci->devname ? ci->devname : _T(""), str1b, str2b[0] ? _T(":") : _T(""), str2b, ci->sectors, ci->surfaces, ci->reserved, ci->blocksize, - bp, ci->filesys ? ci->filesys : _T(""), hdcontrollers[ci->controller]); - if (ci->highcyl) { + bp, ci->filesys ? ci->filesys : _T(""), hdcs); + if (ci->highcyl || ci->physical_geometry) { TCHAR *s = tmp + _tcslen(tmp); TCHAR *s2 = s; _stprintf(s2, _T(",%d"), ci->highcyl); - if (ci->pcyls && ci->pheads && ci->psecs) { + if (ci->physical_geometry && ci->pheads && ci->psecs) { TCHAR *s = tmp + _tcslen(tmp); _stprintf(s, _T(",%d/%d/%d"), ci->pcyls, ci->pheads, ci->psecs); } _tcscat(tmp3, s2); } + if (ci->controller_media_type) { + _tcscat(tmp, _T(",CF")); + _tcscat(tmp3, _T(",CF")); + } + const TCHAR *extras = NULL; + if (ct >= HD_CONTROLLER_TYPE_SCSI_FIRST && ct <= HD_CONTROLLER_TYPE_SCSI_LAST) { + if (ci->unit_feature_level == HD_LEVEL_SCSI_1) { + extras = _T("SCSI1"); + } + else if (ci->unit_feature_level == HD_LEVEL_SASI) { + extras = _T("SASI"); + } + else if (ci->unit_feature_level == HD_LEVEL_SASI_ENHANCED) { + extras = _T("SASIE"); + } + else if (ci->unit_feature_level == HD_LEVEL_SASI_CHS) { + extras = _T("SASI_CHS"); + } + } + else if (ct >= HD_CONTROLLER_TYPE_IDE_FIRST && ct <= HD_CONTROLLER_TYPE_IDE_LAST) { + if (ci->unit_feature_level == HD_LEVEL_ATA_1) { + extras = _T("ATA1"); + } + else if (ci->unit_feature_level == HD_LEVEL_ATA_2S) { + extras = _T("ATA2+S"); + } + } + if (extras) { + _tcscat(tmp, _T(",")); + _tcscat(tmp3, _T(",")); + _tcscat(tmp, extras); + _tcscat(tmp3, extras); + } + if (ci->unit_special_flags) { + TCHAR tmpx[32]; + _stprintf(tmpx, _T(",flags=0x%x"), ci->unit_special_flags); + _tcscat(tmp, tmpx); + _tcscat(tmp3, tmpx); + } + if (ci->lock) { + _tcscat(tmp, _T(",lock")); + _tcscat(tmp3, _T(",lock")); + } + if (ci->type == UAEDEV_HDF) cfgfile_write_str(f, _T("hardfile2"), tmp); +#if 0 + _stprintf(tmp2, _T("hardfile=%s,%d,%d,%d,%d,%s"), + uci->readonly ? "ro" : "rw", uci->sectors, + uci->surfaces, uci->reserved, uci->blocksize, str); + zfile_fputs(f, tmp2); +#endif } - _stprintf(tmp2, _T("uaehf%d"), i); if (ci->type == UAEDEV_CD) { cfgfile_write(f, tmp2, _T("cd%d,%s"), ci->device_emu_unit, tmp); @@ -825,9 +1007,20 @@ static void write_filesys_config(struct uae_prefs *p, struct zfile *f) else { cfgfile_write(f, tmp2, _T("%s,%s"), ci->type == UAEDEV_HDF ? _T("hdf") : _T("dir"), tmp3); } + if (ci->type == UAEDEV_DIR) { + bool add_extra = false; + if (ci->inject_icons) { + add_extra = true; + } + if (add_extra) { + _stprintf(tmp2, _T("%s,inject_icons=%s"), ci->devname, ci->inject_icons ? _T("true") : _T("false")); + cfgfile_write(f, _T("filesystem_extra"), tmp2); + } + } xfree(str1b); xfree(str2b); xfree(str1); + } } @@ -886,7 +1079,331 @@ static void write_resolution(struct zfile *f, const TCHAR *ws, const TCHAR *hs, } } -void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) +static int cfgfile_read_rom_settings(const struct expansionboardsettings *ebs, const TCHAR *buf, TCHAR *configtext) +{ + int settings = 0; + int bitcnt = 0; + int sstr = 0; + if (configtext) + configtext[0] = 0; + TCHAR *ct = configtext; + for (int i = 0; ebs[i].name; i++) { + const struct expansionboardsettings *eb = &ebs[i]; + bitcnt += eb->bitshift; + if (eb->type == EXPANSIONBOARD_STRING) { + const TCHAR *p = cfgfile_option_get(buf, eb->configname); + if (p) { + _tcscpy(ct, p); + ct += _tcslen(ct); + } + *ct++ = 0; + } + else if (eb->type == EXPANSIONBOARD_MULTI) { + int itemcnt = -1; + int itemfound = 0; + const TCHAR *p = eb->configname; + while (p[0]) { + if (itemcnt >= 0) { + if (cfgfile_option_find(buf, p)) { + itemfound = itemcnt; + } + } + itemcnt++; + p += _tcslen(p) + 1; + } + int cnt = 1; + int bits = 1; + for (int i = 0; i < 8; i++) { + if ((1 << i) >= itemcnt) { + cnt = 1 << i; + bits = i; + break; + } + } + int multimask = cnt - 1; + if (eb->invert) + itemfound ^= 0x7fffffff; + itemfound &= multimask; + settings |= itemfound << bitcnt; + bitcnt += bits; + } + else { + int mask = 1 << bitcnt; + if (cfgfile_option_find(buf, eb->configname)) { + settings |= mask; + } + if (eb->invert) + settings ^= mask; + bitcnt++; + } + } + return settings; +} + +static void cfgfile_write_rom_settings(const struct expansionboardsettings *ebs, TCHAR *buf, int settings, const TCHAR *settingstring) +{ + int bitcnt = 0; + int sstr = 0; + for (int j = 0; ebs[j].name; j++) { + const struct expansionboardsettings *eb = &ebs[j]; + bitcnt += eb->bitshift; + if (eb->type == EXPANSIONBOARD_STRING) { + if (settingstring) { + const TCHAR *p = settingstring; + for (int i = 0; i < sstr; i++) { + p += _tcslen(p) + 1; + } + if (buf[0]) + _tcscat(buf, _T(",")); + _stprintf(buf, _T("%s=%s"), eb->configname, p); + sstr++; + } + } + else if (eb->type == EXPANSIONBOARD_MULTI) { + int itemcnt = -1; + const TCHAR *p = eb->configname; + while (p[0]) { + itemcnt++; + p += _tcslen(p) + 1; + } + int cnt = 1; + int bits = 1; + for (int i = 0; i < 8; i++) { + if ((1 << i) >= itemcnt) { + cnt = 1 << i; + bits = i; + break; + } + } + int multimask = cnt - 1; + int multivalue = settings; + if (eb->invert) + multivalue ^= 0x7fffffff; + multivalue = (multivalue >> bitcnt) & multimask; + p = eb->configname; + while (multivalue >= 0) { + multivalue--; + p += _tcslen(p) + 1; + } + if (buf[0]) + _tcscat(buf, _T(",")); + _tcscat(buf, p); + bitcnt += bits; + } + else { + int value = settings; + if (eb->invert) + value ^= 0x7fffffff; + if (value & (1 << bitcnt)) { + if (buf[0]) + _tcscat(buf, _T(",")); + _tcscat(buf, eb->configname); + } + bitcnt++; + } + } +} + +static void cfgfile_write_board_rom(struct uae_prefs *prefs, struct zfile *f, struct multipath *mp, struct boardromconfig *br) +{ + TCHAR buf[256]; + TCHAR name[256]; + const struct expansionromtype *ert; + + if (br->device_type == 0) + return; + ert = get_device_expansion_rom(br->device_type); + if (!ert) + return; + for (int i = 0; i < MAX_BOARD_ROMS; i++) { + if (br->device_num == 0) + _tcscpy(name, ert->name); + else + _stprintf(name, _T("%s-%d"), ert->name, br->device_num + 1); + if (i == 0 || _tcslen(br->roms[i].romfile)) { + _stprintf(buf, _T("%s%s_rom_file"), name, i ? _T("_ext") : _T("")); + cfgfile_write_rom(f, mp, br->roms[i].romfile, buf); + if (br->roms[i].romident[0]) { + _stprintf(buf, _T("%s%s_rom"), name, i ? _T("_ext") : _T("")); + cfgfile_dwrite_str(f, buf, br->roms[i].romident); + } + if (br->roms[i].autoboot_disabled || ert->subtypes || ert->settings || ert->id_jumper || br->device_order > 0) { + TCHAR buf2[256], *p; + buf2[0] = 0; + p = buf2; + _stprintf(buf, _T("%s%s_rom_options"), name, i ? _T("_ext") : _T("")); + if (ert->subtypes) { + const struct expansionsubromtype *srt = ert->subtypes; + int k = br->roms[i].subtype; + while (k && srt[1].name) { + srt++; + k--; + } + _stprintf(p, _T("subtype=%s"), srt->configname); + } + if (br->device_order > 0 && prefs->autoconfig_custom_sort) { + if (buf2[0]) + _tcscat(buf2, _T(",")); + _stprintf(buf2, _T("order=%d"), br->device_order); + } + if (br->roms[i].autoboot_disabled) { + if (buf2[0]) + _tcscat(buf2, _T(",")); + _tcscat(buf2, _T("autoboot_disabled=true")); + } + if (ert->id_jumper) { + TCHAR tmp[256]; + _stprintf(tmp, _T("id=%d"), br->roms[i].device_id); + if (buf2[0]) + _tcscat(buf2, _T(",")); + _tcscat(buf2, tmp); + } + if (br->roms[i].device_settings && ert->settings) { + cfgfile_write_rom_settings(ert->settings, buf2, br->roms[i].device_settings, br->roms[i].configtext); + } + if (buf2[0]) + cfgfile_dwrite_str(f, buf, buf2); + } + + if (br->roms[i].board_ram_size) { + _stprintf(buf, _T("%s%s_mem_size"), name, i ? _T("_ext") : _T("")); + cfgfile_write(f, buf, _T("%d"), br->roms[i].board_ram_size / 0x40000); + } + } + } +} + +static bool cfgfile_readramboard(const TCHAR *option, const TCHAR *value, const TCHAR *name, struct ramboard *rbp) +{ + TCHAR tmp1[MAX_DPATH]; + int v; + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + struct ramboard *rb = &rbp[i]; + if (i > 0) + _stprintf(tmp1, _T("%s%d_size"), name, i + 1); + else + _stprintf(tmp1, _T("%s_size"), name); + if (!_tcsicmp(option, tmp1)) { + v = 0; + cfgfile_intval(option, value, tmp1, &v, 0x100000); + rb->size = v; + return true; + } + if (i > 0) + _stprintf(tmp1, _T("%s%d_size_k"), name, i + 1); + else + _stprintf(tmp1, _T("%s_size_k"), name); + if (!_tcsicmp(option, tmp1)) { + v = 0; + cfgfile_intval(option, value, tmp1, &v, 1024); + rb->size = v; + return true; + } + if (i > 0) + _stprintf(tmp1, _T("%s%d_options"), name, i + 1); + else + _stprintf(tmp1, _T("%s_options"), name); + if (!_tcsicmp(option, tmp1)) { + TCHAR *s, *s1, *s2; + s = cfgfile_option_get(value, _T("order")); + if (s) + rb->device_order = _tstol(s); + s = cfgfile_option_get(value, _T("mid")); + if (s) + rb->manufacturer = _tstol(s); + s = cfgfile_option_get(value, _T("pid")); + if (s) + rb->product = _tstol(s); + s = cfgfile_option_get(value, _T("no_reset_unmap")); + if (s) + rb->no_reset_unmap = true; + s = cfgfile_option_get(value, _T("data")); + if (s && _tcslen(s) >= 3 * 16 - 1) { + rb->autoconfig_inuse = true; + for (int i = 0; i < sizeof rb->autoconfig; i++) { + TCHAR *s2 = &s[i * 3]; + if (i + 1 < sizeof rb->autoconfig && s2[2] != '.') + break; + TCHAR *endptr; + s[2] = 0; + rb->autoconfig[i] = (uae_u8)_tcstol(s2, &endptr, 16); + } + } + s1 = cfgfile_option_get(value, _T("start")); + s2 = cfgfile_option_get(value, _T("end")); + if (s1 && s2) { + TCHAR *endptr; + rb->start_address = _tcstol(s1, &endptr, 16); + rb->end_address = _tcstol(s2, &endptr, 16); + if (rb->start_address && rb->end_address > rb->start_address) { + rb->manual_config = true; + rb->autoconfig_inuse = false; + } + } + s1 = cfgfile_option_get(value, _T("write_address")); + if (s1) { + TCHAR *endptr; + rb->write_address = _tcstol(s1, &endptr, 16); + } + + return true; + } + } + return false; +} + +static void cfgfile_writeramboard(struct uae_prefs *prefs, struct zfile *f, const TCHAR *name, int num, struct ramboard *rb) +{ + TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH]; + if (num > 0) + _stprintf(tmp1, _T("%s%d_options"), name, num + 1); + else + _stprintf(tmp1, _T("%s_options"), name); + tmp2[0] = 0; + TCHAR *p = tmp2; + if (rb->device_order > 0 && prefs->autoconfig_custom_sort) { + if (tmp2[0]) + *p++ = ','; + _stprintf(p, _T("order=%d"), rb->device_order); + p += _tcslen(p); + } + if (rb->manufacturer) { + if (tmp2[0]) + *p++ = ','; + _stprintf(p, _T("mid=%u,pid=%u"), rb->manufacturer, rb->product); + p += _tcslen(p); + } + if (rb->no_reset_unmap) { + if (tmp2[0]) + *p++ = ','; + _tcscpy(p, _T("no_reset_unmap=true")); + p += _tcslen(p); + } + if (rb->autoconfig_inuse) { + uae_u8 *ac = rb->autoconfig; + if (tmp2[0]) + *p++ = ','; + _stprintf(p, _T("data=%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x"), + ac[0], ac[1], ac[2], ac[3], ac[4], ac[5], ac[6], ac[7], + ac[8], ac[9], ac[10], ac[11], ac[12], ac[13], ac[14], ac[15]); + p += _tcslen(p); + } + if (rb->manual_config && rb->start_address && rb->end_address) { + if (tmp2[0]) + *p++ = ','; + _stprintf(p, _T("start=%08x,end=%08x"), rb->start_address, rb->end_address); + p += _tcslen(p); + } + if (rb->write_address) { + _stprintf(p, _T(",write_address=%08x"), rb->write_address); + p += _tcslen(p); + } + if (tmp2[0]) { + cfgfile_write(f, tmp1, tmp2); + } +} + +void cfgfile_save_options(struct zfile *f, struct uae_prefs *p, int type) { struct strlist *sl; TCHAR tmp[MAX_DPATH]; @@ -900,6 +1417,7 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) cfgfile_write(f, _T("config_version"), _T("%d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV); cfgfile_write_str(f, _T("config_hardware_path"), p->config_hardware_path); cfgfile_write_str(f, _T("config_host_path"), p->config_host_path); + cfgfile_write_str(f, _T("config_all_path"), p->config_all_path); if (p->config_window_title[0]) cfgfile_write_str(f, _T("config_window_title"), p->config_window_title); @@ -955,23 +1473,21 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) if (p->romextident[0]) cfgfile_write_str(f, _T("kickstart_ext_rom="), p->romextident); - cfgfile_write_rom(f, &p->path_rom, p->a2091romfile, _T("a2091_rom_file")); - cfgfile_write_rom(f, &p->path_rom, p->a4091romfile, _T("a4091_rom_file")); - if (p->a2091romident[0]) - cfgfile_dwrite_str(f, _T("a2091_rom"), p->a2091romident); - if (p->a4091romident[0]) - cfgfile_dwrite_str(f, _T("a4091_rom"), p->a4091romident); + for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) { + cfgfile_write_board_rom(p, f, &p->path_rom, &p->expansionboard[i]); + } cfgfile_write_path(f, &p->path_rom, _T("flash_file"), p->flashfile); cfgfile_write_path(f, &p->path_rom, _T("cart_file"), p->cartfile); cfgfile_write_path(f, &p->path_rom, _T("rtc_file"), p->rtcfile); if (p->cartident[0]) cfgfile_write_str(f, _T("cart"), p->cartident); - if (p->amaxromfile[0]) - cfgfile_write_path(f, &p->path_rom, _T("amax_rom_file"), p->amaxromfile); + cfgfile_dwrite_path(f, &p->path_rom, _T("picassoiv_rom_file"), p->picassoivromfile); cfgfile_write_bool(f, _T("kickshifter"), p->kickshifter); - cfgfile_write_bool(f, _T("ks_write_enabled"), p->rom_readwrite); + cfgfile_dwrite_bool(f, _T("ks_write_enabled"), p->rom_readwrite); + + cfgfile_write(f, _T("floppy_volume"), _T("%d"), p->dfxclickvolume_disk[0]); p->nr_floppies = 4; for (i = 0; i < 4; i++) { @@ -987,6 +1503,12 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) _stprintf(tmp, _T("floppy%dsoundext"), i); cfgfile_dwrite(f, tmp, p->floppyslots[i].dfxclickexternal); } + if (p->floppyslots[i].dfxclick) { + _stprintf(tmp, _T("floppy%dsoundvolume_disk"), i); + cfgfile_write(f, tmp, _T("%d"), p->dfxclickvolume_disk[i]); + _stprintf(tmp, _T("floppy%dsoundvolume_empty"), i); + cfgfile_write(f, tmp, _T("%d"), p->dfxclickvolume_empty[i]); + } if (p->floppyslots[i].dfxtype < 0 && p->nr_floppies > i) p->nr_floppies = i; } @@ -1032,13 +1554,14 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) cfgfile_write(f, _T("nr_floppies"), _T("%d"), p->nr_floppies); cfgfile_dwrite_bool(f, _T("floppy_write_protect"), p->floppy_read_only); cfgfile_write(f, _T("floppy_speed"), _T("%d"), p->floppy_speed); - cfgfile_write(f, _T("floppy_volume"), _T("%d"), p->dfxclickvolume); cfgfile_dwrite(f, _T("floppy_channel_mask"), _T("0x%x"), p->dfxclickchannelmask); + cfgfile_write(f, _T("cd_speed"), _T("%d"), p->cd_speed); cfgfile_write_bool(f, _T("parallel_on_demand"), p->parallel_demand); cfgfile_write_bool(f, _T("serial_on_demand"), p->serial_demand); cfgfile_write_bool(f, _T("serial_hardware_ctsrts"), p->serial_hwctsrts); cfgfile_write_bool(f, _T("serial_direct"), p->serial_direct); cfgfile_dwrite(f, _T("serial_stopbits"), _T("%d"), p->serial_stopbits); + cfgfile_dwrite_str(f, _T("serial_translate"), serialcrlf[p->serial_crlf]); cfgfile_write_str(f, _T("scsi"), scsimode[p->scsi]); cfgfile_write_bool(f, _T("uaeserial"), p->uaeserial); cfgfile_write_bool(f, _T("sana2"), p->sana2); @@ -1052,10 +1575,18 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) cfgfile_write_str(f, _T("sound_interpol"), interpolmode[p->sound_interpol]); cfgfile_write_str(f, _T("sound_filter"), soundfiltermode1[p->sound_filter]); cfgfile_write_str(f, _T("sound_filter_type"), soundfiltermode2[p->sound_filter_type]); - cfgfile_write(f, _T("sound_volume"), _T("%d"), p->sound_volume); + cfgfile_write(f, _T("sound_volume"), _T("%d"), p->sound_volume_master); + cfgfile_write(f, _T("sound_volume_paula"), _T("%d"), p->sound_volume_paula); if (p->sound_volume_cd >= 0) cfgfile_write(f, _T("sound_volume_cd"), _T("%d"), p->sound_volume_cd); + if (p->sound_volume_board >= 0) + cfgfile_write(f, _T("sound_volume_ahi"), _T("%d"), p->sound_volume_board); + if (p->sound_volume_midi >= 0) + cfgfile_write(f, _T("sound_volume_midi"), _T("%d"), p->sound_volume_midi); + if (p->sound_volume_genlock >= 0) + cfgfile_write(f, _T("sound_volume_genlock"), _T("%d"), p->sound_volume_genlock); cfgfile_write_bool(f, _T("sound_auto"), p->sound_auto); + cfgfile_write_bool(f, _T("sound_cdaudio"), p->sound_cdaudio); cfgfile_write_bool(f, _T("sound_stereo_swap_paula"), p->sound_stereo_swap_paula); cfgfile_write_bool(f, _T("sound_stereo_swap_ahi"), p->sound_stereo_swap_ahi); cfgfile_dwrite(f, _T("sampler_frequency"), _T("%d"), p->sampler_freq); @@ -1068,29 +1599,25 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) cfgfile_write_str(f, _T("comp_trustnaddr"), compmode[p->comptrustnaddr]); cfgfile_write_bool(f, _T("comp_nf"), p->compnf); cfgfile_write_bool(f, _T("comp_constjump"), p->comp_constjump); - cfgfile_write_bool(f, _T("comp_oldsegv"), p->comp_oldsegv); - cfgfile_write_str(f, _T("comp_flushmode"), flushmode[p->comp_hardflush]); +#ifdef USE_JIT_FPU cfgfile_write_bool(f, _T("compfpu"), p->compfpu); - cfgfile_write_bool(f, _T("fpu_strict"), p->fpu_strict); - cfgfile_write_bool(f, _T("comp_midopt"), p->comp_midopt); - cfgfile_write_bool(f, _T("comp_lowopt"), p->comp_lowopt); - cfgfile_write_bool(f, _T("avoid_cmov"), p->avoid_cmov); +#endif cfgfile_write(f, _T("cachesize"), _T("%d"), p->cachesize); for (i = 0; i < MAX_JPORTS; i++) { struct jport *jp = &p->jports[i]; int v = jp->id; TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH]; - if (v == JPORT_CUSTOM) { - _tcscpy(tmp2, _T("custom")); - } - else if (v == JPORT_NONE) { + if (v == JPORT_NONE) { _tcscpy(tmp2, _T("none")); } - else if (v < JSEM_JOYS) { + else if (v < JSEM_CUSTOM) { _stprintf(tmp2, _T("kbd%d"), v + 1); } + else if (v < JSEM_JOYS) { + _stprintf(tmp2, _T("custom%d"), v - JSEM_CUSTOM); + } else if (v < JSEM_MICE) { _stprintf(tmp2, _T("joy%d"), v - JSEM_JOYS); } @@ -1108,13 +1635,13 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) _stprintf(tmp1, _T("joyport%dmode"), i); cfgfile_write(f, tmp1, joyportmodes[jp->mode]); } - if (jp->name[0]) { + if (jp->idc.name[0]) { _stprintf(tmp1, _T("joyportfriendlyname%d"), i); - cfgfile_write(f, tmp1, jp->name); + cfgfile_write(f, tmp1, jp->idc.name); } - if (jp->configname[0]) { + if (jp->idc.configname[0]) { _stprintf(tmp1, _T("joyportname%d"), i); - cfgfile_write(f, tmp1, jp->configname); + cfgfile_write(f, tmp1, jp->idc.configname); } if (jp->nokeyboardoverride) { _stprintf(tmp1, _T("joyport%dkeyboardoverride"), i); @@ -1122,6 +1649,15 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) } } } + for (i = 0; i < MAX_JPORTS_CUSTOM; i++) { + struct jport_custom *jp = &p->jports_custom[i]; + if (jp->custom[0]) { + TCHAR tmp1[MAX_DPATH]; + _stprintf(tmp1, _T("joyportcustom%d"), i); + cfgfile_write(f, tmp1, jp->custom); + } + } + if (p->dongle) { if (p->dongle + 1 >= sizeof(dongles) / sizeof(TCHAR*)) cfgfile_write(f, _T("dongle"), _T("%d"), p->dongle); @@ -1131,8 +1667,66 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) cfgfile_write_bool(f, _T("bsdsocket_emu"), p->socket_emu); + //{ + // // backwards compatibility + // const TCHAR *name; + // struct romconfig *rc; + // rc = get_device_romconfig(p, ROMTYPE_A2065, 0); + // if (rc) { + // name = ethernet_getselectionname(rc ? rc->device_settings : 0); + // cfgfile_write_str(f, _T("a2065"), name); + // } + // rc = get_device_romconfig(p, ROMTYPE_NE2KPCMCIA, 0); + // if (rc) { + // name = ethernet_getselectionname(rc ? rc->device_settings : 0); + // cfgfile_write_str(f, _T("ne2000_pcmcia"), name); + // } + // rc = get_device_romconfig(p, ROMTYPE_NE2KPCI, 0); + // if (rc) { + // name = ethernet_getselectionname(rc ? rc->device_settings : 0); + // cfgfile_write_str(f, _T("ne2000_pci"), name); + // } + //} + +#ifdef WITH_SLIRP + tmp[0] = 0; + for (i = 0; i < MAX_SLIRP_REDIRS; i++) { + struct slirp_redir *sr = &p->slirp_redirs[i]; + if (sr->proto && !sr->srcport) { + TCHAR *p = tmp + _tcslen(tmp); + if (p > tmp) + *p++ = ','; + _stprintf(p, _T("%d"), sr->dstport); + } + } + if (tmp[0]) + cfgfile_write_str(f, _T("slirp_ports"), tmp); + for (i = 0; i < MAX_SLIRP_REDIRS; i++) { + struct slirp_redir *sr = &p->slirp_redirs[i]; + if (sr->proto && sr->srcport) { + uae_u32 v = htonl(sr->addr); + if (v) { + _stprintf(tmp, _T("%s:%d:%d:%d.%d.%d.%d"), + sr->proto == 1 ? _T("tcp") : _T("udp"), + sr->dstport, sr->srcport, + (v >> 24) & 0xff, (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff); + } + else { + _stprintf(tmp, _T("%s:%d:%d"), + sr->proto == 1 ? _T("tcp") : _T("udp"), + sr->dstport, sr->srcport); + } + cfgfile_write_str(f, _T("slirp_redir"), tmp); + } + } +#endif /* WITH_SLIRP */ + cfgfile_write_bool(f, _T("synchronize_clock"), p->tod_hack); cfgfile_write(f, _T("maprom"), _T("0x%x"), p->maprom); + cfgfile_dwrite_str(f, _T("boot_rom_uae"), uaebootrom[p->boot_rom]); + cfgfile_dwrite_str(f, _T("uaeboard"), uaeboard[p->uaeboard]); + if (p->autoconfig_custom_sort) + cfgfile_dwrite(f, _T("uaeboard_options"), _T("order=%d"), p->uaeboard_order); cfgfile_dwrite_str(f, _T("parallel_matrix_emulation"), epsonprinter[p->parallel_matrix_emulation]); cfgfile_write_bool(f, _T("parallel_postscript_emulation"), p->parallel_postscript_emulation); cfgfile_write_bool(f, _T("parallel_postscript_detection"), p->parallel_postscript_detection); @@ -1140,7 +1734,7 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) cfgfile_write(f, _T("parallel_autoflush"), _T("%d"), p->parallel_autoflush_time); cfgfile_dwrite(f, _T("uae_hide"), _T("%d"), p->uae_hide); cfgfile_dwrite_bool(f, _T("uae_hide_autoconfig"), p->uae_hide_autoconfig); - cfgfile_dwrite_bool(f, _T("magic_mouse"), p->input_magic_mouse); + cfgfile_dwrite_bool(f, _T("magic_mouse"), (p->input_mouse_untrap & MOUSEUNTRAP_MAGIC) != 0); cfgfile_dwrite_str(f, _T("magic_mousecursor"), magiccursors[p->input_magic_mouse_cursor]); cfgfile_dwrite_str(f, _T("absolute_mouse"), abspointers[p->input_tablet]); cfgfile_dwrite_bool(f, _T("tablet_library"), p->tablet_library); @@ -1172,9 +1766,9 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) cfgfile_write(f, _T("gfx_backbuffers_rtg"), _T("%d"), p->gfx_apmode[1].gfx_backbuffers); if (p->gfx_apmode[APMODE_NATIVE].gfx_interlaced) cfgfile_write_bool(f, _T("gfx_interlace"), p->gfx_apmode[APMODE_NATIVE].gfx_interlaced); - cfgfile_write_str(f, _T("gfx_vsync"), vsyncmodes[p->gfx_apmode[0].gfx_vsync]); + cfgfile_write_str(f, _T("gfx_vsync"), vsyncmodes[p->gfx_apmode[0].gfx_vsync + 1]); cfgfile_write_str(f, _T("gfx_vsyncmode"), vsyncmodes2[p->gfx_apmode[0].gfx_vsyncmode]); - cfgfile_write_str(f, _T("gfx_vsync_picasso"), vsyncmodes[p->gfx_apmode[1].gfx_vsync]); + cfgfile_write_str(f, _T("gfx_vsync_picasso"), vsyncmodes[p->gfx_apmode[1].gfx_vsync + 1]); cfgfile_write_str(f, _T("gfx_vsyncmode_picasso"), vsyncmodes2[p->gfx_apmode[1].gfx_vsyncmode]); cfgfile_write_bool(f, _T("gfx_lores"), p->gfx_resolution == 0); cfgfile_write_str(f, _T("gfx_resolution"), lorestype1[p->gfx_resolution]); @@ -1187,20 +1781,129 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) cfgfile_write_str(f, _T("gfx_center_vertical"), centermode1[p->gfx_ycenter]); cfgfile_write_str(f, _T("gfx_colour_mode"), colormode1[p->color_mode]); cfgfile_write_bool(f, _T("gfx_blacker_than_black"), p->gfx_blackerthanblack); + cfgfile_dwrite_bool(f, _T("gfx_monochrome"), p->gfx_grayscale); + cfgfile_dwrite_str(f, _T("gfx_atari_palette_fix"), threebitcolors[p->gfx_threebitcolors]); cfgfile_dwrite_bool(f, _T("gfx_black_frame_insertion"), p->lightboost_strobo); + cfgfile_dwrite(f, _T("gfx_black_frame_insertion_ratio"), _T("%d"), p->lightboost_strobo_ratio); cfgfile_write_str(f, _T("gfx_api"), filterapi[p->gfx_api]); cfgfile_dwrite(f, _T("gfx_horizontal_tweak"), _T("%d"), p->gfx_extrawidth); +#ifdef GFXFILTER + for (int j = 0; j < 2; j++) { + struct gfx_filterdata *gf = &p->gf[j]; + const TCHAR *ext = j == 0 ? NULL : _T("_rtg"); + for (int i = 0; i gfx_filtershader[i][0]) + cfgfile_write_ext(f, _T("gfx_filter_pre"), ext, _T("D3D:%s"), gf->gfx_filtershader[i]); + if (gf->gfx_filtermask[i][0]) + cfgfile_write_str(f, _T("gfx_filtermask_pre"), ext, gf->gfx_filtermask[i]); + } + for (int i = 0; i < MAX_FILTERSHADERS; i++) { + if (gf->gfx_filtershader[i + MAX_FILTERSHADERS][0]) + cfgfile_write_ext(f, _T("gfx_filter_post"), ext, _T("D3D:%s"), gf->gfx_filtershader[i + MAX_FILTERSHADERS]); + if (gf->gfx_filtermask[i + MAX_FILTERSHADERS][0]) + cfgfile_write_str(f, _T("gfx_filtermask_post"), ext, gf->gfx_filtermask[i + MAX_FILTERSHADERS]); + } + cfgfile_dwrite_str(f, _T("gfx_filter_mask"), ext, gf->gfx_filtermask[2 * MAX_FILTERSHADERS]); + { + bool d3dfound = false; + if (gf->gfx_filtershader[2 * MAX_FILTERSHADERS][0] && p->gfx_api) { + cfgfile_dwrite_ext(f, _T("gfx_filter"), ext, _T("D3D:%s"), gf->gfx_filtershader[2 * MAX_FILTERSHADERS]); + d3dfound = true; + } + if (!d3dfound) { + if (gf->gfx_filter > 0) { + int i = 0; + struct uae_filter *uf; + while (uaefilters[i].name) { + uf = &uaefilters[i]; + if (uf->type == gf->gfx_filter) { + cfgfile_dwrite_str(f, _T("gfx_filter"), ext, uf->cfgname); + } + i++; + } + } + else { + cfgfile_dwrite_ext(f, _T("gfx_filter"), ext, _T("no")); + } + } + } + cfgfile_dwrite_str(f, _T("gfx_filter_mode"), ext, filtermode2[gf->gfx_filter_filtermode]); + cfgfile_dwrite_ext(f, _T("gfx_filter_vert_zoomf"), ext, _T("%f"), gf->gfx_filter_vert_zoom); + cfgfile_dwrite_ext(f, _T("gfx_filter_horiz_zoomf"), ext, _T("%f"), gf->gfx_filter_horiz_zoom); + cfgfile_dwrite_ext(f, _T("gfx_filter_vert_zoom_multf"), ext, _T("%f"), gf->gfx_filter_vert_zoom_mult); + cfgfile_dwrite_ext(f, _T("gfx_filter_horiz_zoom_multf"), ext, _T("%f"), gf->gfx_filter_horiz_zoom_mult); + cfgfile_dwrite_ext(f, _T("gfx_filter_vert_offsetf"), ext, _T("%f"), gf->gfx_filter_vert_offset); + cfgfile_dwrite_ext(f, _T("gfx_filter_horiz_offsetf"), ext, _T("%f"), gf->gfx_filter_horiz_offset); + + cfgfile_dwrite_ext(f, _T("gfx_filter_left_border"), ext, _T("%d"), gf->gfx_filter_left_border); + cfgfile_dwrite_ext(f, _T("gfx_filter_right_border"), ext, _T("%d"), gf->gfx_filter_right_border); + cfgfile_dwrite_ext(f, _T("gfx_filter_top_border"), ext, _T("%d"), gf->gfx_filter_top_border); + cfgfile_dwrite_ext(f, _T("gfx_filter_bottom_border"), ext, _T("%d"), gf->gfx_filter_bottom_border); + + cfgfile_dwrite_ext(f, _T("gfx_filter_scanlines"), ext, _T("%d"), gf->gfx_filter_scanlines); + cfgfile_dwrite_ext(f, _T("gfx_filter_scanlinelevel"), ext, _T("%d"), gf->gfx_filter_scanlinelevel); + cfgfile_dwrite_ext(f, _T("gfx_filter_scanlineratio"), ext, _T("%d"), gf->gfx_filter_scanlineratio); + + cfgfile_dwrite_ext(f, _T("gfx_filter_luminance"), ext, _T("%d"), gf->gfx_filter_luminance); + cfgfile_dwrite_ext(f, _T("gfx_filter_contrast"), ext, _T("%d"), gf->gfx_filter_contrast); + cfgfile_dwrite_ext(f, _T("gfx_filter_saturation"), ext, _T("%d"), gf->gfx_filter_saturation); + cfgfile_dwrite_ext(f, _T("gfx_filter_gamma"), ext, _T("%d"), gf->gfx_filter_gamma); + cfgfile_dwrite_ext(f, _T("gfx_filter_gamma_r"), ext, _T("%d"), gf->gfx_filter_gamma_ch[0]); + cfgfile_dwrite_ext(f, _T("gfx_filter_gamma_g"), ext, _T("%d"), gf->gfx_filter_gamma_ch[1]); + cfgfile_dwrite_ext(f, _T("gfx_filter_gamma_b"), ext, _T("%d"), gf->gfx_filter_gamma_ch[2]); + + cfgfile_dwrite_ext(f, _T("gfx_filter_blur"), ext, _T("%d"), gf->gfx_filter_blur); + cfgfile_dwrite_ext(f, _T("gfx_filter_noise"), ext, _T("%d"), gf->gfx_filter_noise); + cfgfile_dwrite_bool(f, _T("gfx_filter_bilinear"), ext, gf->gfx_filter_bilinear != 0); + + cfgfile_dwrite_ext(f, _T("gfx_filter_keep_autoscale_aspect"), ext, _T("%d"), gf->gfx_filter_keep_autoscale_aspect); + cfgfile_dwrite_str(f, _T("gfx_filter_keep_aspect"), ext, aspects[gf->gfx_filter_keep_aspect]); + cfgfile_dwrite_str(f, _T("gfx_filter_autoscale"), ext, ext == NULL ? autoscale[gf->gfx_filter_autoscale] : autoscale_rtg[gf->gfx_filter_autoscale]); + cfgfile_dwrite_str(f, _T("gfx_filter_autoscale_limit"), ext, autoscalelimit[gf->gfx_filter_integerscalelimit]); + cfgfile_dwrite_ext(f, _T("gfx_filter_aspect_ratio"), ext, _T("%d:%d"), + gf->gfx_filter_aspect >= 0 ? (gf->gfx_filter_aspect / ASPECTMULT) : -1, + gf->gfx_filter_aspect >= 0 ? (gf->gfx_filter_aspect & (ASPECTMULT - 1)) : -1); + if (gf->gfx_filteroverlay[0]) { + cfgfile_dwrite_ext(f, _T("gfx_filter_overlay"), ext, _T("%s%s"), + gf->gfx_filteroverlay, _tcschr(gf->gfx_filteroverlay, ',') ? _T(",") : _T("")); + } + } + cfgfile_dwrite(f, _T("gfx_luminance"), _T("%d"), p->gfx_luminance); + cfgfile_dwrite(f, _T("gfx_contrast"), _T("%d"), p->gfx_contrast); + cfgfile_dwrite(f, _T("gfx_gamma"), _T("%d"), p->gfx_gamma); + cfgfile_dwrite(f, _T("gfx_gamma_r"), _T("%d"), p->gfx_gamma_ch[0]); + cfgfile_dwrite(f, _T("gfx_gamma_g"), _T("%d"), p->gfx_gamma_ch[1]); + cfgfile_dwrite(f, _T("gfx_gamma_b"), _T("%d"), p->gfx_gamma_ch[2]); + + cfgfile_dwrite(f, _T("gfx_center_horizontal_position"), _T("%d"), p->gfx_xcenter_pos); + cfgfile_dwrite(f, _T("gfx_center_vertical_position"), _T("%d"), p->gfx_ycenter_pos); + cfgfile_dwrite(f, _T("gfx_center_horizontal_size"), _T("%d"), p->gfx_xcenter_size); + cfgfile_dwrite(f, _T("gfx_center_vertical_size"), _T("%d"), p->gfx_ycenter_size); + + cfgfile_dwrite(f, _T("rtg_vert_zoom_multf"), _T("%.f"), p->rtg_vert_zoom_mult); + cfgfile_dwrite(f, _T("rtg_horiz_zoom_multf"), _T("%.f"), p->rtg_horiz_zoom_mult); + +#endif + cfgfile_write_bool(f, _T("immediate_blits"), p->immediate_blits); cfgfile_dwrite_str(f, _T("waiting_blits"), waitblits[p->waiting_blits]); cfgfile_write_bool(f, _T("ntsc"), p->ntscmode); cfgfile_write_bool(f, _T("genlock"), p->genlock); + cfgfile_dwrite_bool(f, _T("genlock_alpha"), p->genlock_alpha); + cfgfile_dwrite_bool(f, _T("genlock_aspect"), p->genlock_aspect); + cfgfile_dwrite_str(f, _T("genlockmode"), genlockmodes[p->genlock_image]); + cfgfile_dwrite_str(f, _T("genlock_image"), p->genlock_image_file); + cfgfile_dwrite_str(f, _T("genlock_video"), p->genlock_video_file); + cfgfile_dwrite(f, _T("genlock_mix"), _T("%d"), p->genlock_mix); + cfgfile_dwrite(f, _T("genlock_scale"), _T("%d"), p->genlock_scale); cfgfile_dwrite_str(f, _T("monitoremu"), specialmonitors[p->monitoremu]); cfgfile_dwrite_bool(f, _T("show_leds"), !!(p->leds_on_screen & STATUSLINE_CHIPSET)); cfgfile_dwrite_bool(f, _T("show_leds_rtg"), !!(p->leds_on_screen & STATUSLINE_RTG)); write_leds(f, _T("show_leds_enabled"), p->leds_on_screen_mask[0]); write_leds(f, _T("show_leds_enabled_rtg"), p->leds_on_screen_mask[1]); + cfgfile_dwrite_bool(f, _T("show_refresh_indicator"), p->refresh_indicator); if (p->osd_pos.y || p->osd_pos.x) { cfgfile_dwrite(f, _T("osd_position"), _T("%.1f%s:%.1f%s"), @@ -1223,11 +1926,14 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) cfgfile_write(f, _T("chipset_refreshrate"), _T("%f"), p->chipset_refreshrate); for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) { - if (p->cr[i].rate <= 0) - continue; struct chipset_refresh *cr = &p->cr[i]; + if (!cr->inuse) + continue; cr->index = i; - _stprintf(tmp, _T("%f"), cr->rate); + if (cr->rate == 0) + _tcscpy(tmp, _T("0")); + else + _stprintf(tmp, _T("%f"), cr->rate); TCHAR *s = tmp + _tcslen(tmp); if (cr->label[0] > 0 && i < MAX_CHIPSET_REFRESH) s += _stprintf(s, _T(",t=%s"), cr->label); @@ -1237,14 +1943,26 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) s += _stprintf(s, _T(",v=%d"), cr->vert); if (cr->locked) _tcscat(s, _T(",locked")); - if (cr->ntsc > 0) + if (cr->ntsc == 1) _tcscat(s, _T(",ntsc")); else if (cr->ntsc == 0) _tcscat(s, _T(",pal")); + else if (cr->ntsc == 2) + _tcscat(s, _T(",custom")); if (cr->lace > 0) _tcscat(s, _T(",lace")); else if (cr->lace == 0) _tcscat(s, _T(",nlace")); + if ((cr->resolution & 7) != 7) { + if (cr->resolution & 1) + _tcscat(s, _T(",lores")); + if (cr->resolution & 2) + _tcscat(s, _T(",hires")); + if (cr->resolution & 4) + _tcscat(s, _T(",shres")); + if (cr->resolution_pct > 0 && cr->resolution_pct < 100) + s += _stprintf(s, _T("rpct=%d"), cr->resolution_pct); + } if (cr->framelength > 0) _tcscat(s, _T(",lof")); else if (cr->framelength == 0) @@ -1255,8 +1973,17 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) _tcscat(s, _T(",nvsync")); if (cr->rtg) _tcscat(s, _T(",rtg")); + if (cr->exit) + _tcscat(s, _T(",exit")); + if (cr->defaultdata) + _tcscat(s, _T(",default")); + if (cr->filterprofile[0]) { + TCHAR *se = cfgfile_escape(cr->filterprofile, _T(","), true); + s += _stprintf(s, _T(",filter=%s"), cr->filterprofile); + xfree(se); + } if (cr->commands[0]) { - _tcscat(s, _T(",")); + _tcscat(s, _T(",cmd=")); _tcscat(s, cr->commands); for (int j = 0; j < _tcslen(s); j++) { if (s[j] == '\n') @@ -1264,12 +1991,17 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) } s[_tcslen(s) - 1] = 0; } - if (i == CHIPSET_REFRESH_PAL) - cfgfile_dwrite(f, _T("displaydata_pal"), tmp); - else if (i == CHIPSET_REFRESH_NTSC) - cfgfile_dwrite(f, _T("displaydata_ntsc"), tmp); - else + if (i == CHIPSET_REFRESH_PAL) { + if (cr->locked) + cfgfile_dwrite(f, _T("displaydata_pal"), tmp); + } + else if (i == CHIPSET_REFRESH_NTSC) { + if (cr->locked) + cfgfile_dwrite(f, _T("displaydata_ntsc"), tmp); + } + else { cfgfile_dwrite(f, _T("displaydata"), tmp); + } } cfgfile_write_str(f, _T("collision_level"), collmode[p->collision_level]); @@ -1283,40 +2015,121 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) cfgfile_dwrite_bool(f, _T("cd32cd"), p->cs_cd32cd); cfgfile_dwrite_bool(f, _T("cd32c2p"), p->cs_cd32c2p); cfgfile_dwrite_bool(f, _T("cd32nvram"), p->cs_cd32nvram); + cfgfile_dwrite(f, _T("cd32nvram_size"), _T("%d"), p->cs_cd32nvram_size / 1024); cfgfile_dwrite_bool(f, _T("cdtvcd"), p->cs_cdtvcd); + cfgfile_dwrite_bool(f, _T("cdtv-cr"), p->cs_cdtvcr); cfgfile_dwrite_bool(f, _T("cdtvram"), p->cs_cdtvram); cfgfile_dwrite(f, _T("cdtvramcard"), _T("%d"), p->cs_cdtvcard); - cfgfile_dwrite_str(f, _T("ide"), p->cs_ide == IDE_A600A1200 ? _T("a600/a1200") : (p->cs_ide == IDE_A4000 ? _T("a4000") : _T("none"))); cfgfile_dwrite_bool(f, _T("a1000ram"), p->cs_a1000ram); cfgfile_dwrite(f, _T("fatgary"), _T("%d"), p->cs_fatgaryrev); cfgfile_dwrite(f, _T("ramsey"), _T("%d"), p->cs_ramseyrev); cfgfile_dwrite_bool(f, _T("pcmcia"), p->cs_pcmcia); - cfgfile_dwrite_bool(f, _T("scsi_cdtv"), p->cs_cdtvscsi); - cfgfile_dwrite_bool(f, _T("scsi_a2091"), p->a2091); - cfgfile_dwrite_bool(f, _T("scsi_a4091"), p->a4091); - cfgfile_dwrite_bool(f, _T("scsi_a3000"), p->cs_mbdmac == 1); - cfgfile_dwrite_bool(f, _T("scsi_a4000t"), p->cs_mbdmac == 2); cfgfile_dwrite_bool(f, _T("bogomem_fast"), p->cs_slowmemisfast); cfgfile_dwrite_bool(f, _T("resetwarning"), p->cs_resetwarning); cfgfile_dwrite_bool(f, _T("denise_noehb"), p->cs_denisenoehb); cfgfile_dwrite_bool(f, _T("agnus_bltbusybug"), p->cs_agnusbltbusybug); cfgfile_dwrite_bool(f, _T("ics_agnus"), p->cs_dipagnus); cfgfile_dwrite_bool(f, _T("cia_todbug"), p->cs_ciatodbug); + cfgfile_dwrite_bool(f, _T("z3_autoconfig"), p->cs_z3autoconfig); + cfgfile_dwrite_bool(f, _T("1mchipjumper"), p->cs_1mchipjumper); + cfgfile_dwrite_bool(f, _T("color_burst"), p->cs_color_burst); cfgfile_dwrite(f, _T("chipset_hacks"), _T("0x%x"), p->cs_hacks); - cfgfile_dwrite_bool(f, _T("fastmem_autoconfig"), p->fastmem_autoconfig); - cfgfile_write(f, _T("fastmem_size"), _T("%d"), p->fastmem_size / 0x100000); - cfgfile_dwrite(f, _T("fastmem2_size"), _T("%d"), p->fastmem2_size / 0x100000); + if (is_board_enabled(p, ROMTYPE_CD32CART, 0)) { + cfgfile_dwrite_bool(f, _T("cd32fmv"), true); + } + if (is_board_enabled(p, ROMTYPE_MB_IDE, 0) && p->cs_ide == 1) { + cfgfile_dwrite_str(f, _T("ide"), _T("a600/a1200")); + } + if (is_board_enabled(p, ROMTYPE_MB_IDE, 0) && p->cs_ide == 2) { + cfgfile_dwrite_str(f, _T("ide"), _T("a4000")); + } + if (is_board_enabled(p, ROMTYPE_CDTVSCSI, 0)) { + cfgfile_dwrite_bool(f, _T("scsi_cdtv"), true); + } + if (is_board_enabled(p, ROMTYPE_SCSI_A3000, 0)) { + cfgfile_dwrite_bool(f, _T("scsi_a3000"), true); + } + if (is_board_enabled(p, ROMTYPE_SCSI_A4000T, 0)) { + cfgfile_dwrite_bool(f, _T("scsi_a4000t"), true); + } + + cfgfile_dwrite_str(f, _T("z3mapping"), z3mapping[p->z3_mapping_mode]); + cfgfile_dwrite_bool(f, _T("board_custom_order"), p->autoconfig_custom_sort); + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + if (p->fastmem[i].size < 0x100000 && p->fastmem[i].size) { + if (i > 0) + _stprintf(tmp, _T("fastmem%d_size_k"), i + 1); + else + _tcscpy(tmp, _T("fastmem_size_k")); + cfgfile_write(f, tmp, _T("%d"), p->fastmem[i].size / 1024); + } + else if (p->fastmem[i].size || i == 0) { + if (i > 0) + _stprintf(tmp, _T("fastmem%d_size"), i + 1); + else + _tcscpy(tmp, _T("fastmem_size")); + cfgfile_write(f, tmp, _T("%d"), p->fastmem[i].size / 0x100000); + } + cfgfile_writeramboard(p, f, _T("fastmem"), i, &p->fastmem[i]); + } + cfgfile_write(f, _T("mem25bit_size"), _T("%d"), p->mem25bit_size / 0x100000); cfgfile_write(f, _T("a3000mem_size"), _T("%d"), p->mbresmem_low_size / 0x100000); cfgfile_write(f, _T("mbresmem_size"), _T("%d"), p->mbresmem_high_size / 0x100000); - cfgfile_write(f, _T("z3mem_size"), _T("%d"), p->z3fastmem_size / 0x100000); - cfgfile_dwrite(f, _T("z3mem2_size"), _T("%d"), p->z3fastmem2_size / 0x100000); - cfgfile_write(f, _T("z3mem_start"), _T("0x%x"), p->z3fastmem_start); + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + if (i == 0 || p->z3fastmem[i].size) { + if (i > 0) + _stprintf(tmp, _T("z3mem%d_size"), i + 1); + else + _tcscpy(tmp, _T("z3mem_size")); + cfgfile_write(f, tmp, _T("%d"), p->z3fastmem[i].size / 0x100000); + } + cfgfile_writeramboard(p, f, _T("z3mem"), i, &p->z3fastmem[i]); + } + cfgfile_write(f, _T("z3mem_start"), _T("0x%x"), p->z3autoconfig_start); cfgfile_write(f, _T("bogomem_size"), _T("%d"), p->bogomem_size / 0x40000); - cfgfile_write(f, _T("gfxcard_size"), _T("%d"), p->rtgmem_size / 0x100000); - cfgfile_write_str(f, _T("gfxcard_type"), rtgtype[p->rtgmem_type]); + if (p->cpuboard_type) { + const struct cpuboardtype *cbt = &cpuboards[p->cpuboard_type]; + const struct cpuboardsubtype *cbst = &cbt->subtypes[p->cpuboard_subtype]; + const struct expansionboardsettings *cbs = cbst->settings; + cfgfile_dwrite_str(f, _T("cpuboard_type"), cbst->configname); + if (cbs && p->cpuboard_settings) { + tmp[0] = 0; + cfgfile_write_rom_settings(cbs, tmp, p->cpuboard_settings, NULL); + cfgfile_dwrite_str(f, _T("cpuboard_settings"), tmp); + } + } + else { + cfgfile_dwrite_str(f, _T("cpuboard_type"), _T("none")); + } + cfgfile_dwrite(f, _T("cpuboardmem1_size"), _T("%d"), p->cpuboardmem1_size / 0x100000); + cfgfile_dwrite(f, _T("cpuboardmem2_size"), _T("%d"), p->cpuboardmem2_size / 0x100000); cfgfile_write_bool(f, _T("gfxcard_hardware_vblank"), p->rtg_hardwareinterrupt); cfgfile_write_bool(f, _T("gfxcard_hardware_sprite"), p->rtg_hardwaresprite); + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + TCHAR tmp2[100]; + struct rtgboardconfig *rbc = &p->rtgboards[i]; + if (rbc->rtgmem_size) { + if (i > 0) + _stprintf(tmp, _T("gfxcard%d_size"), i + 1); + else + _tcscpy(tmp, _T("gfxcard_size")); + cfgfile_write(f, tmp, _T("%d"), rbc->rtgmem_size / 0x100000); + if (i > 0) + _stprintf(tmp, _T("gfxcard%d_type"), i + 1); + else + _tcscpy(tmp, _T("gfxcard_type")); + cfgfile_dwrite_str(f, tmp, gfxboard_get_configname(rbc->rtgmem_type)); + if (rbc->device_order > 0 && p->autoconfig_custom_sort) { + _stprintf(tmp2, _T("order=%d"), rbc->device_order); + if (i > 0) + _stprintf(tmp, _T("gfxcard%d_options"), i + 1); + else + _tcscpy(tmp, _T("gfxcard_options")); + cfgfile_dwrite_str(f, tmp, tmp2); + } + } + } cfgfile_write(f, _T("chipmem_size"), _T("%d"), p->chipmem_size == 0x20000 ? -1 : (p->chipmem_size == 0x40000 ? 0 : p->chipmem_size / 0x80000)); cfgfile_dwrite(f, _T("megachipmem_size"), _T("%d"), p->z3chipmem_size / 0x100000); // do not save aros rom special space @@ -1334,6 +2147,7 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) cfgfile_write_str(f, _T("cpu_speed"), p->m68k_speed < 0 ? _T("max") : _T("real")); } cfgfile_write(f, _T("cpu_throttle"), _T("%.1f"), p->m68k_speed_throttle); + cfgfile_dwrite(f, _T("cpu_x86_throttle"), _T("%.1f"), p->x86_speed_throttle); /* do not reorder start */ write_compatibility_cpu(f, p); @@ -1342,9 +2156,17 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) cfgfile_write(f, _T("fpu_model"), _T("%d"), p->fpu_model); if (p->mmu_model) cfgfile_write(f, _T("mmu_model"), _T("%d"), p->mmu_model); + if (p->ppc_mode) { + cfgfile_write_str(f, _T("ppc_model"), p->ppc_model[0] ? p->ppc_model : (p->ppc_mode == 1 ? _T("automatic") : _T("manual"))); + cfgfile_write_str(f, _T("ppc_cpu_idle"), ppc_cpu_idle[p->ppc_cpu_idle]); + } cfgfile_write_bool(f, _T("cpu_compatible"), p->cpu_compatible); cfgfile_write_bool(f, _T("cpu_24bit_addressing"), p->address_space_24); /* do not reorder end */ + cfgfile_dwrite_bool(f, _T("cpu_reset_pause"), p->reset_delay); + cfgfile_dwrite_bool(f, _T("cpu_threaded"), p->cpu_thread); + if (p->ppc_mode) + cfgfile_write_str(f, _T("ppc_implementation"), ppc_implementations[p->ppc_implementation]); if (p->cpu_cycle_exact) { if (p->cpu_frequency) @@ -1356,24 +2178,54 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) } cfgfile_write_bool(f, _T("cpu_cycle_exact"), p->cpu_cycle_exact); + // must be after cpu_cycle_exact + cfgfile_write_bool(f, _T("cpu_memory_cycle_exact"), p->cpu_memory_cycle_exact); cfgfile_write_bool(f, _T("blitter_cycle_exact"), p->blitter_cycle_exact); - cfgfile_write_bool(f, _T("cycle_exact"), p->cpu_cycle_exact && p->blitter_cycle_exact ? 1 : 0); + // must be after cpu_cycle_exact, cpu_memory_cycle_exact and blitter_cycle_exact + if (p->cpu_cycle_exact && p->blitter_cycle_exact) + cfgfile_write_str(f, _T("cycle_exact"), cycleexact[2]); + else if (p->cpu_memory_cycle_exact && p->blitter_cycle_exact) + cfgfile_write_str(f, _T("cycle_exact"), cycleexact[1]); + else + cfgfile_write_str(f, _T("cycle_exact"), cycleexact[0]); + cfgfile_dwrite_bool(f, _T("fpu_no_unimplemented"), p->fpu_no_unimplemented); cfgfile_dwrite_bool(f, _T("cpu_no_unimplemented"), p->int_no_unimplemented); + cfgfile_write_bool(f, _T("fpu_strict"), p->fpu_strict); + cfgfile_dwrite_bool(f, _T("fpu_softfloat"), p->fpu_softfloat); cfgfile_write_bool(f, _T("rtg_nocustom"), p->picasso96_nocustom); cfgfile_write(f, _T("rtg_modes"), _T("0x%x"), p->picasso96_modeflags); cfgfile_write_bool(f, _T("log_illegal_mem"), p->illegal_mem); + +#if 0 if (p->catweasel >= 100) cfgfile_dwrite(f, _T("catweasel"), _T("0x%x"), p->catweasel); else cfgfile_dwrite(f, _T("catweasel"), _T("%d"), p->catweasel); + cfgfile_write_bool(f, _T("toccata"), p->obs_sound_toccata); + if (p->obs_sound_toccata_mixer) + cfgfile_write_bool(f, _T("toccata_mixer"), p->obs_sound_toccata_mixer); + cfgfile_write_bool(f, _T("es1370_pci"), p->obs_sound_es1370); + cfgfile_write_bool(f, _T("fm801_pci"), p->obs_sound_fm801); +#endif + + cfgfile_dwrite_bool(f, _T("keyboard_connected"), p->keyboard_connected); + //cfgfile_write_str(f, _T("kbd_lang"), (p->keyboard_lang == KBD_LANG_DE ? _T("de") + // : p->keyboard_lang == KBD_LANG_DK ? _T("dk") + // : p->keyboard_lang == KBD_LANG_ES ? _T("es") + // : p->keyboard_lang == KBD_LANG_US ? _T("us") + // : p->keyboard_lang == KBD_LANG_SE ? _T("se") + // : p->keyboard_lang == KBD_LANG_FR ? _T("fr") + // : p->keyboard_lang == KBD_LANG_IT ? _T("it") + // : _T("FOO"))); cfgfile_dwrite(f, _T("state_replay_rate"), _T("%d"), p->statecapturerate); cfgfile_dwrite(f, _T("state_replay_buffers"), _T("%d"), p->statecapturebuffersize); cfgfile_dwrite_bool(f, _T("state_replay_autoplay"), p->inprec_autoplay); cfgfile_dwrite_bool(f, _T("warp"), p->turbo_emulation); + cfgfile_dwrite(f, _T("warp_limit"), _T("%d"), p->turbo_emulation_limit); #ifdef FILESYS write_filesys_config(p, f); @@ -1382,32 +2234,42 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type) cfgfile_dwrite(f, _T("filesys_max_size"), _T("%d"), p->filesys_limit); cfgfile_dwrite(f, _T("filesys_max_name_length"), _T("%d"), p->filesys_max_name); cfgfile_dwrite(f, _T("filesys_max_file_size"), _T("%d"), p->filesys_max_file_size); + cfgfile_dwrite_bool(f, _T("filesys_inject_icons"), p->filesys_inject_icons); + cfgfile_dwrite_str(f, _T("filesys_inject_icons_drawer"), p->filesys_inject_icons_drawer); + cfgfile_dwrite_str(f, _T("filesys_inject_icons_project"), p->filesys_inject_icons_project); + cfgfile_dwrite_str(f, _T("filesys_inject_icons_tool"), p->filesys_inject_icons_tool); + cfgfile_dwrite_str(f, _T("scsidev_mode"), uaescsidevmodes[p->uaescsidevmode]); #endif + cfgfile_dwrite_bool(f, _T("harddrive_write_protect"), p->harddrive_read_only); + write_inputdevice_config(p, f); } -int cfgfile_yesno(const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, bool numbercheck) +static int cfgfile_yesno(const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, bool numbercheck) { if (name != NULL && _tcscmp(option, name) != 0) return 0; if (strcasecmp(value, _T("yes")) == 0 || strcasecmp(value, _T("y")) == 0 - || strcasecmp(value, _T("true")) == 0 || strcasecmp(value, _T("t")) == 0) + || strcasecmp(value, _T("true")) == 0 || strcasecmp(value, _T("t")) == 0 + || (numbercheck && strcasecmp(value, _T("1")) == 0)) *location = 1; else if (strcasecmp(value, _T("no")) == 0 || strcasecmp(value, _T("n")) == 0 || strcasecmp(value, _T("false")) == 0 || strcasecmp(value, _T("f")) == 0 || (numbercheck && strcasecmp(value, _T("0")) == 0)) *location = 0; else { - write_log(_T("Option `%s' requires a value of either `yes' or `no' (was '%s').\n"), option, value); + cfgfile_warning(_T("Option '%s' requires a value of either 'true' or 'false' (was '%s').\n"), option, value); return -1; } return 1; } -int cfgfile_yesno(const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location) + +static int cfgfile_yesno(const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location) { return cfgfile_yesno(option, value, name, location, true); } -int cfgfile_yesno(const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location, bool numbercheck) + +static int cfgfile_yesno(const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location, bool numbercheck) { int val; int ret = cfgfile_yesno(option, value, name, &val, numbercheck); @@ -1419,14 +2281,14 @@ int cfgfile_yesno(const TCHAR *option, const TCHAR *value, const TCHAR *name, bo *location = val != 0; return 1; } + int cfgfile_yesno(const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location) { return cfgfile_yesno(option, value, name, location, true); } -int cfgfile_doubleval(const TCHAR *option, const TCHAR *value, const TCHAR *name, double *location) +static int cfgfile_doubleval(const TCHAR *option, const TCHAR *value, const TCHAR *name, double *location) { - int base = 10; TCHAR *endptr; if (name != NULL && _tcscmp(option, name) != 0) return 0; @@ -1434,9 +2296,8 @@ int cfgfile_doubleval(const TCHAR *option, const TCHAR *value, const TCHAR *name return 1; } -int cfgfile_floatval(const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, float *location) +static int cfgfile_floatval(const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, float *location) { - int base = 10; TCHAR *endptr; if (name == NULL) return 0; @@ -1454,12 +2315,13 @@ int cfgfile_floatval(const TCHAR *option, const TCHAR *value, const TCHAR *name, *location = (float)_tcstod(value, &endptr); return 1; } -int cfgfile_floatval(const TCHAR *option, const TCHAR *value, const TCHAR *name, float *location) + +static int cfgfile_floatval(const TCHAR *option, const TCHAR *value, const TCHAR *name, float *location) { return cfgfile_floatval(option, value, name, NULL, location); } -int cfgfile_intval(const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, unsigned int *location, int scale) +static int cfgfile_intval(const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, unsigned int *location, int scale) { int base = 10; TCHAR *endptr; @@ -1491,13 +2353,13 @@ int cfgfile_intval(const TCHAR *option, const TCHAR *value, const TCHAR *name, c *location = 1; return 1; } - write_log(_T("Option '%s' requires a numeric argument but got '%s'\n"), nameext ? tmp : option, value); + cfgfile_warning(_T("Option '%s' requires a numeric argument but got '%s'\n"), nameext ? tmp : option, value); return -1; } return 1; } -int cfgfile_intval(const TCHAR *option, const TCHAR *value, const TCHAR *name, unsigned int *location, int scale) +static int cfgfile_intval(const TCHAR *option, const TCHAR *value, const TCHAR *name, unsigned int *location, int scale) { return cfgfile_intval(option, value, name, NULL, location, scale); } @@ -1510,7 +2372,7 @@ int cfgfile_intval(const TCHAR *option, const TCHAR *value, const TCHAR *name, i *location = (int)v; return r; } -int cfgfile_intval(const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, int *location, int scale) +static int cfgfile_intval(const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, int *location, int scale) { unsigned int v = 0; int r = cfgfile_intval(option, value, name, nameext, &v, scale); @@ -1520,7 +2382,7 @@ int cfgfile_intval(const TCHAR *option, const TCHAR *value, const TCHAR *name, c return r; } -int cfgfile_strval(const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, int *location, const TCHAR *table[], int more) +static int cfgfile_strval(const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, int *location, const TCHAR *table[], int more) { int val; TCHAR tmp[MAX_DPATH]; @@ -1547,7 +2409,7 @@ int cfgfile_strval(const TCHAR *option, const TCHAR *value, const TCHAR *name, c val = 0; } else { - write_log(_T("Unknown value ('%s') for option '%s'.\n"), value, nameext ? tmp : option); + cfgfile_warning(_T("Unknown value ('%s') for option '%s'.\n"), value, nameext ? tmp : option); return -1; } } @@ -1559,7 +2421,7 @@ int cfgfile_strval(const TCHAR *option, const TCHAR *value, const TCHAR *name, i return cfgfile_strval(option, value, name, NULL, location, table, more); } -int cfgfile_strboolval(const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location, const TCHAR *table[], int more) +static int cfgfile_strboolval(const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location, const TCHAR *table[], int more) { int locationint; if (!cfgfile_strval(option, value, name, &locationint, table, more)) @@ -1577,7 +2439,7 @@ int cfgfile_string(const TCHAR *option, const TCHAR *value, const TCHAR *name, T return 1; } -int cfgfile_string(const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, TCHAR *location, int maxsz) +static int cfgfile_string(const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, TCHAR *location, int maxsz) { if (nameext) { TCHAR tmp[MAX_DPATH]; @@ -1595,7 +2457,7 @@ int cfgfile_string(const TCHAR *option, const TCHAR *value, const TCHAR *name, c return 1; } -int cfgfile_path(const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz, struct multipath *mp) +static int cfgfile_path(const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz, struct multipath *mp) { if (!cfgfile_string(option, value, name, location, maxsz)) return 0; @@ -1622,12 +2484,12 @@ int cfgfile_path(const TCHAR *option, const TCHAR *value, const TCHAR *name, TCH return 1; } -int cfgfile_path(const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz) +static int cfgfile_path(const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz) { return cfgfile_path(option, value, name, location, maxsz, NULL); } -int cfgfile_multipath(const TCHAR *option, const TCHAR *value, const TCHAR *name, struct multipath *mp) +static int cfgfile_multipath(const TCHAR *option, const TCHAR *value, const TCHAR *name, struct multipath *mp) { TCHAR tmploc[MAX_DPATH]; if (!cfgfile_string(option, value, name, tmploc, 256)) @@ -1645,7 +2507,7 @@ int cfgfile_multipath(const TCHAR *option, const TCHAR *value, const TCHAR *name return 1; } -int cfgfile_rom(const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz) +static int cfgfile_rom(const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz) { TCHAR id[MAX_DPATH]; if (!cfgfile_string(option, value, name, id, sizeof id / sizeof(TCHAR))) @@ -1701,20 +2563,33 @@ static int getintval(TCHAR **p, int *result, int delim) return 1; } -static int getintval2(TCHAR **p, int *result, int delim) +static int getintval2(TCHAR **p, int *result, int delim, bool last) { TCHAR *value = *p; int base = 10; TCHAR *endptr; - TCHAR *p2 = _tcschr(*p, delim); + TCHAR *p2; + p2 = _tcschr(*p, delim); if (p2 == 0) { - p2 = _tcschr(*p, 0); - if (p2 == 0) { - *p = 0; + if (last) { + if (delim != '.') + p2 = _tcschr(*p, ','); + if (p2 == 0) { + p2 = *p; + while (*p2) + p2++; + if (p2 == *p) + return 0; + } + } + else { return 0; } } + if (!_istdigit(**p) && **p != '-' && **p != '+') + return 0; + if (*p2 != 0) *p2++ = '\0'; @@ -1731,6 +2606,68 @@ static int getintval2(TCHAR **p, int *result, int delim) return 1; } +static int cfgfile_option_select(TCHAR *s, const TCHAR *option, const TCHAR *select) +{ + TCHAR buf[MAX_DPATH]; + if (!s) + return -1; + _tcscpy(buf, s); + _tcscat(buf, _T(",")); + TCHAR *p = buf; + for (;;) { + TCHAR *tmpp = _tcschr(p, ','); + if (tmpp == NULL) + return -1; + *tmpp++ = 0; + TCHAR *tmpp2 = _tcschr(p, '='); + if (!tmpp2) + return -1; + *tmpp2++ = 0; + if (!strcasecmp(p, option)) { + int idx = 0; + while (select[0]) { + if (!strcasecmp(select, tmpp2)) + return idx; + idx++; + select += _tcslen(select) + 1; + } + } + p = tmpp; + } +} + +static int cfgfile_option_bool(TCHAR *s, const TCHAR *option) +{ + TCHAR buf[MAX_DPATH]; + if (!s) + return -1; + _tcscpy(buf, s); + _tcscat(buf, _T(",")); + TCHAR *p = buf; + for (;;) { + TCHAR *tmpp = _tcschr(p, ','); + if (tmpp == NULL) + return -1; + *tmpp++ = 0; + TCHAR *tmpp2 = _tcschr(p, '='); + if (tmpp2) + *tmpp2++ = 0; + if (!strcasecmp(p, option)) { + if (!tmpp2) + return 0; + TCHAR *tmpp3 = _tcschr(tmpp2, ','); + if (tmpp3) + *tmpp3 = 0; + if (tmpp2 && !strcasecmp(tmpp2, _T("true"))) + return 1; + if (tmpp2 && !strcasecmp(tmpp2, _T("false"))) + return 0; + return 1; + } + p = tmpp; + } +} + static void set_chipset_mask(struct uae_prefs *p, int val) { p->chipset_mask = (val == 0 ? 0 @@ -1776,6 +2713,10 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) for (i = 0; i < MAX_SPARE_DRIVES; i++) { _stprintf(tmpbuf, _T("diskimage%d"), i); if (cfgfile_path(option, value, tmpbuf, p->dfxlist[i], sizeof p->dfxlist[i] / sizeof(TCHAR), &p->path_floppy)) { +#if 0 + if (i < 4 && !p->df[i][0]) + _tcscpy(p->df[i], p->dfxlist[i]); +#endif return 1; } } @@ -1802,7 +2743,6 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) TCHAR *next2 = _tcschr(next, ':'); if (next2) *next2++ = 0; - int tmpval = 0; if (!_tcsicmp(next, _T("delay"))) { p->cdslots[i].delayed = true; next = next2; @@ -1843,7 +2783,6 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) p->cdslots[i].inuse = true; p->cdslots[i].type = type; } - // disable all following units i++; while (i < MAX_TOTAL_SCSI_DEVICES) { @@ -1889,12 +2828,17 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_intval(option, value, _T("state_replay_buffers"), &p->statecapturebuffersize, 1) || cfgfile_yesno(option, value, _T("state_replay_autoplay"), &p->inprec_autoplay) || cfgfile_intval(option, value, _T("sound_frequency"), &p->sound_freq, 1) - || cfgfile_intval(option, value, _T("sound_volume"), &p->sound_volume, 1) + || cfgfile_intval(option, value, _T("sound_volume"), &p->sound_volume_master, 1) + || cfgfile_intval(option, value, _T("sound_volume_paula"), &p->sound_volume_paula, 1) || cfgfile_intval(option, value, _T("sound_volume_cd"), &p->sound_volume_cd, 1) + || cfgfile_intval(option, value, _T("sound_volume_ahi"), &p->sound_volume_board, 1) + || cfgfile_intval(option, value, _T("sound_volume_midi"), &p->sound_volume_midi, 1) + || cfgfile_intval(option, value, _T("sound_volume_genlock"), &p->sound_volume_genlock, 1) || cfgfile_intval(option, value, _T("sound_stereo_separation"), &p->sound_stereo_separation, 1) || cfgfile_intval(option, value, _T("sound_stereo_mixing_delay"), &p->sound_mixed_stereo_delay, 1) || cfgfile_intval(option, value, _T("sampler_frequency"), &p->sampler_freq, 1) || cfgfile_intval(option, value, _T("sampler_buffer"), &p->sampler_buffer, 1) + || cfgfile_intval(option, value, _T("warp_limit"), &p->turbo_emulation_limit, 1) || cfgfile_intval(option, value, _T("gfx_framerate"), &p->gfx_framerate, 1) || cfgfile_intval(option, value, _T("gfx_top_windowed"), &p->gfx_size_win.x, 1) @@ -1906,6 +2850,7 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_intval(option, value, _T("gfx_backbuffers_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_backbuffers, 1) || cfgfile_yesno(option, value, _T("gfx_interlace"), &p->gfx_apmode[APMODE_NATIVE].gfx_interlaced) || cfgfile_yesno(option, value, _T("gfx_interlace_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_interlaced) + || cfgfile_intval(option, value, _T("gfx_black_frame_insertion_ratio"), &p->lightboost_strobo_ratio, 1) || cfgfile_intval(option, value, _T("gfx_center_horizontal_position"), &p->gfx_xcenter_pos, 1) || cfgfile_intval(option, value, _T("gfx_center_vertical_position"), &p->gfx_ycenter_pos, 1) @@ -1915,10 +2860,17 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_intval(option, value, _T("filesys_max_size"), &p->filesys_limit, 1) || cfgfile_intval(option, value, _T("filesys_max_name_length"), &p->filesys_max_name, 1) || cfgfile_intval(option, value, _T("filesys_max_file_size"), &p->filesys_max_file_size, 1) + || cfgfile_yesno(option, value, _T("filesys_inject_icons"), &p->filesys_inject_icons) + || cfgfile_string(option, value, _T("filesys_inject_icons_drawer"), p->filesys_inject_icons_drawer, sizeof p->filesys_inject_icons_drawer / sizeof(TCHAR)) + || cfgfile_string(option, value, _T("filesys_inject_icons_project"), p->filesys_inject_icons_project, sizeof p->filesys_inject_icons_project / sizeof(TCHAR)) + || cfgfile_string(option, value, _T("filesys_inject_icons_tool"), p->filesys_inject_icons_tool, sizeof p->filesys_inject_icons_tool / sizeof(TCHAR)) || cfgfile_intval(option, value, _T("gfx_luminance"), &p->gfx_luminance, 1) || cfgfile_intval(option, value, _T("gfx_contrast"), &p->gfx_contrast, 1) || cfgfile_intval(option, value, _T("gfx_gamma"), &p->gfx_gamma, 1) + || cfgfile_intval(option, value, _T("gfx_gamma_r"), &p->gfx_gamma_ch[0], 1) + || cfgfile_intval(option, value, _T("gfx_gamma_g"), &p->gfx_gamma_ch[1], 1) + || cfgfile_intval(option, value, _T("gfx_gamma_b"), &p->gfx_gamma_ch[2], 1) || cfgfile_floatval(option, value, _T("rtg_vert_zoom_multf"), &p->rtg_vert_zoom_mult) || cfgfile_floatval(option, value, _T("rtg_horiz_zoom_multf"), &p->rtg_horiz_zoom_mult) || cfgfile_intval(option, value, _T("gfx_horizontal_tweak"), &p->gfx_extrawidth, 1) @@ -1927,8 +2879,15 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_intval(option, value, _T("floppy1sound"), &p->floppyslots[1].dfxclick, 1) || cfgfile_intval(option, value, _T("floppy2sound"), &p->floppyslots[2].dfxclick, 1) || cfgfile_intval(option, value, _T("floppy3sound"), &p->floppyslots[3].dfxclick, 1) - || cfgfile_intval(option, value, _T("floppy_channel_mask"), &p->dfxclickchannelmask, 1) - || cfgfile_intval(option, value, _T("floppy_volume"), &p->dfxclickvolume, 1)) + || cfgfile_intval(option, value, _T("floppy0soundvolume_disk"), &p->dfxclickvolume_disk[0], 1) + || cfgfile_intval(option, value, _T("floppy1soundvolume_disk"), &p->dfxclickvolume_disk[1], 1) + || cfgfile_intval(option, value, _T("floppy2soundvolume_disk"), &p->dfxclickvolume_disk[2], 1) + || cfgfile_intval(option, value, _T("floppy3soundvolume_disk"), &p->dfxclickvolume_disk[3], 1) + || cfgfile_intval(option, value, _T("floppy0soundvolume_empty"), &p->dfxclickvolume_empty[0], 1) + || cfgfile_intval(option, value, _T("floppy1soundvolume_empty"), &p->dfxclickvolume_empty[1], 1) + || cfgfile_intval(option, value, _T("floppy2soundvolume_empty"), &p->dfxclickvolume_empty[2], 1) + || cfgfile_intval(option, value, _T("floppy3soundvolume_empty"), &p->dfxclickvolume_empty[3], 1) + || cfgfile_intval(option, value, _T("floppy_channel_mask"), &p->dfxclickchannelmask, 1)) return 1; if (cfgfile_path(option, value, _T("floppy0soundext"), p->floppyslots[0].dfxclickexternal, sizeof p->floppyslots[0].dfxclickexternal / sizeof(TCHAR)) @@ -1947,16 +2906,17 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_yesno(option, value, _T("floppy3wp"), &p->floppyslots[3].forcedwriteprotect) || cfgfile_yesno(option, value, _T("sampler_stereo"), &p->sampler_stereo) || cfgfile_yesno(option, value, _T("sound_auto"), &p->sound_auto) + || cfgfile_yesno(option, value, _T("sound_cdaudio"), &p->sound_cdaudio) || cfgfile_yesno(option, value, _T("sound_stereo_swap_paula"), &p->sound_stereo_swap_paula) || cfgfile_yesno(option, value, _T("sound_stereo_swap_ahi"), &p->sound_stereo_swap_ahi) - || cfgfile_yesno(option, value, _T("avoid_cmov"), &p->avoid_cmov) || cfgfile_yesno(option, value, _T("log_illegal_mem"), &p->illegal_mem) || cfgfile_yesno(option, value, _T("filesys_no_fsdb"), &p->filesys_no_uaefsdb) + || cfgfile_yesno(option, value, _T("gfx_monochrome"), &p->gfx_grayscale) || cfgfile_yesno(option, value, _T("gfx_blacker_than_black"), &p->gfx_blackerthanblack) || cfgfile_yesno(option, value, _T("gfx_black_frame_insertion"), &p->lightboost_strobo) || cfgfile_yesno(option, value, _T("gfx_flickerfixer"), &p->gfx_scandoubler) || cfgfile_yesno(option, value, _T("gfx_autoresolution_vga"), &p->gfx_autoresolution_vga) - || cfgfile_yesno(option, value, _T("magic_mouse"), &p->input_magic_mouse) + || cfgfile_yesno(option, value, _T("show_refresh_indicator"), &p->refresh_indicator) || cfgfile_yesno(option, value, _T("warp"), &p->turbo_emulation) || cfgfile_yesno(option, value, _T("headless"), &p->headless) || cfgfile_yesno(option, value, _T("clipboard_sharing"), &p->clipboard_sharing) @@ -1989,10 +2949,63 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_strval(option, value, _T("gfx_max_horizontal"), &p->gfx_max_horizontal, maxhoriz, 0) || cfgfile_strval(option, value, _T("gfx_max_vertical"), &p->gfx_max_vertical, maxvert, 0) || cfgfile_strval(option, value, _T("gfx_api"), &p->gfx_api, filterapi, 0) + || cfgfile_strval(option, value, _T("gfx_atari_palette_fix"), &p->gfx_threebitcolors, threebitcolors, 0) || cfgfile_strval(option, value, _T("magic_mousecursor"), &p->input_magic_mouse_cursor, magiccursors, 0) || cfgfile_strval(option, value, _T("absolute_mouse"), &p->input_tablet, abspointers, 0)) return 1; + if (cfgfile_yesno(option, value, _T("magic_mouse"), &vb)) { + p->input_mouse_untrap |= MOUSEUNTRAP_MAGIC; + return 1; + } + + +#ifdef GFXFILTER + for (int j = 0; j < 2; j++) { + struct gfx_filterdata *gf = &p->gf[j]; + const TCHAR *ext = j == 0 ? NULL : _T("_rtg"); + if (cfgfile_strval(option, value, _T("gfx_filter_autoscale"), ext, &gf->gfx_filter_autoscale, j == 0 ? autoscale : autoscale_rtg, 0) + || cfgfile_strval(option, value, _T("gfx_filter_keep_aspect"), ext, &gf->gfx_filter_keep_aspect, aspects, 0) + || cfgfile_strval(option, value, _T("gfx_filter_autoscale_limit"), ext, &gf->gfx_filter_integerscalelimit, autoscalelimit, 0)) + return 1; + + if (cfgfile_floatval(option, value, _T("gfx_filter_vert_zoomf"), ext, &gf->gfx_filter_vert_zoom) + || cfgfile_floatval(option, value, _T("gfx_filter_horiz_zoomf"), ext, &gf->gfx_filter_horiz_zoom) + || cfgfile_floatval(option, value, _T("gfx_filter_vert_zoom_multf"), ext, &gf->gfx_filter_vert_zoom_mult) + || cfgfile_floatval(option, value, _T("gfx_filter_horiz_zoom_multf"), ext, &gf->gfx_filter_horiz_zoom_mult) + || cfgfile_floatval(option, value, _T("gfx_filter_vert_offsetf"), ext, &gf->gfx_filter_vert_offset) + || cfgfile_floatval(option, value, _T("gfx_filter_horiz_offsetf"), ext, &gf->gfx_filter_horiz_offset) + || cfgfile_intval(option, value, _T("gfx_filter_left_border"), ext, &gf->gfx_filter_left_border, 1) + || cfgfile_intval(option, value, _T("gfx_filter_right_border"), ext, &gf->gfx_filter_right_border, 1) + || cfgfile_intval(option, value, _T("gfx_filter_top_border"), ext, &gf->gfx_filter_top_border, 1) + || cfgfile_intval(option, value, _T("gfx_filter_bottom_border"), ext, &gf->gfx_filter_bottom_border, 1) + || cfgfile_intval(option, value, _T("gfx_filter_scanlines"), ext, &gf->gfx_filter_scanlines, 1) + || cfgfile_intval(option, value, _T("gfx_filter_scanlinelevel"), ext, &gf->gfx_filter_scanlinelevel, 1) + || cfgfile_intval(option, value, _T("gfx_filter_scanlineratio"), ext, &gf->gfx_filter_scanlineratio, 1) + || cfgfile_intval(option, value, _T("gfx_filter_luminance"), ext, &gf->gfx_filter_luminance, 1) + || cfgfile_intval(option, value, _T("gfx_filter_contrast"), ext, &gf->gfx_filter_contrast, 1) + || cfgfile_intval(option, value, _T("gfx_filter_saturation"), ext, &gf->gfx_filter_saturation, 1) + || cfgfile_intval(option, value, _T("gfx_filter_gamma"), ext, &gf->gfx_filter_gamma, 1) + || cfgfile_intval(option, value, _T("gfx_filter_gamma_r"), ext, &gf->gfx_filter_gamma_ch[0], 1) + || cfgfile_intval(option, value, _T("gfx_filter_gamma_g"), ext, &gf->gfx_filter_gamma_ch[1], 1) + || cfgfile_intval(option, value, _T("gfx_filter_gamma_b"), ext, &gf->gfx_filter_gamma_ch[2], 1) + || cfgfile_intval(option, value, _T("gfx_filter_blur"), ext, &gf->gfx_filter_blur, 1) + || cfgfile_intval(option, value, _T("gfx_filter_noise"), ext, &gf->gfx_filter_noise, 1) + || cfgfile_intval(option, value, _T("gfx_filter_bilinear"), ext, &gf->gfx_filter_bilinear, 1) + || cfgfile_intval(option, value, _T("gfx_filter_keep_autoscale_aspect"), ext, &gf->gfx_filter_keep_autoscale_aspect, 1) + || cfgfile_string(option, value, _T("gfx_filter_mask"), ext, gf->gfx_filtermask[2 * MAX_FILTERSHADERS], sizeof gf->gfx_filtermask[2 * MAX_FILTERSHADERS] / sizeof(TCHAR))) + return 1; + } +#endif + + if (cfgfile_intval(option, value, _T("floppy_volume"), &v, 1)) { + for (int i = 0; i < 4; i++) { + p->dfxclickvolume_disk[i] = v; + p->dfxclickvolume_empty[i] = v; + } + return 1; + } + if (_tcscmp(option, _T("gfx_width_windowed")) == 0) { if (!_tcscmp(value, _T("native"))) { p->gfx_size_win.width = 0; @@ -2090,13 +3103,17 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) return 1; } if (_tcscmp(option, _T("gfx_vsync")) == 0) { - if (cfgfile_strval(option, value, _T("gfx_vsync"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsync, vsyncmodes, 0) >= 0) + if (cfgfile_strval(option, value, _T("gfx_vsync"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsync, vsyncmodes, 0) >= 0) { + p->gfx_apmode[APMODE_NATIVE].gfx_vsync--; return 1; + } return cfgfile_yesno(option, value, _T("gfx_vsync"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsync); } if (_tcscmp(option, _T("gfx_vsync_picasso")) == 0) { - if (cfgfile_strval(option, value, _T("gfx_vsync_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsync, vsyncmodes, 0) >= 0) + if (cfgfile_strval(option, value, _T("gfx_vsync_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsync, vsyncmodes, 0) >= 0) { + p->gfx_apmode[APMODE_RTG].gfx_vsync--; return 1; + } return cfgfile_yesno(option, value, _T("gfx_vsync_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsync); } if (cfgfile_strval(option, value, _T("gfx_vsyncmode"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsyncmode, vsyncmodes2, 0)) @@ -2167,6 +3184,149 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) return 1; } +#ifdef GFXFILTER + for (int j = 0; j < 2; j++) { + struct gfx_filterdata *gf = &p->gf[j]; + if ((j == 0 && _tcscmp(option, _T("gfx_filter_overlay")) == 0) || (j == 1 && _tcscmp(option, _T("gfx_filter_overlay_rtg")) == 0)) { + TCHAR *s = _tcschr(value, ','); + gf->gfx_filteroverlay_overscan = 0; + gf->gfx_filteroverlay_pos.x = 0; + gf->gfx_filteroverlay_pos.y = 0; + gf->gfx_filteroverlay_pos.width = 0; + gf->gfx_filteroverlay_pos.height = 0; + if (s) + *s = 0; + while (s) { + *s++ = 0; + gf->gfx_filteroverlay_overscan = _tstol(s); + s = _tcschr(s, ':'); + if (!s) + break; + break; + } + _tcsncpy(gf->gfx_filteroverlay, value, sizeof gf->gfx_filteroverlay / sizeof(TCHAR) - 1); + gf->gfx_filteroverlay[sizeof gf->gfx_filteroverlay / sizeof(TCHAR) - 1] = 0; + return 1; + } + + if ((j == 0 && (_tcscmp(option, _T("gfx_filtermask_pre")) == 0 || _tcscmp(option, _T("gfx_filtermask_post")) == 0)) || + (j == 1 && (_tcscmp(option, _T("gfx_filtermask_pre_rtg")) == 0 || _tcscmp(option, _T("gfx_filtermask_post_rtg")) == 0))) { + if (_tcscmp(option, _T("gfx_filtermask_pre")) == 0 || _tcscmp(option, _T("gfx_filtermask_pre_rtg")) == 0) { + for (int i = 0; i < MAX_FILTERSHADERS; i++) { + if (gf->gfx_filtermask[i][0] == 0) { + _tcscpy(gf->gfx_filtermask[i], value); + break; + } + } + } + else { + for (int i = 0; i < MAX_FILTERSHADERS; i++) { + if (gf->gfx_filtermask[i + MAX_FILTERSHADERS][0] == 0) { + _tcscpy(gf->gfx_filtermask[i + MAX_FILTERSHADERS], value); + break; + } + } + } + return 1; + } + + if ((j == 0 && (_tcscmp(option, _T("gfx_filter_pre")) == 0 || _tcscmp(option, _T("gfx_filter_post")) == 0)) || + (j == 1 && (_tcscmp(option, _T("gfx_filter_pre_rtg")) == 0 || _tcscmp(option, _T("gfx_filter_post_rtg")) == 0))) { + TCHAR *s = _tcschr(value, ':'); + if (s) { + *s++ = 0; + if (!_tcscmp(value, _T("D3D"))) { + p->gfx_api = 1; + if (_tcscmp(option, _T("gfx_filter_pre")) == 0 || _tcscmp(option, _T("gfx_filter_pre_rtg")) == 0) { + for (int i = 0; i < MAX_FILTERSHADERS; i++) { + if (gf->gfx_filtershader[i][0] == 0) { + _tcscpy(gf->gfx_filtershader[i], s); + break; + } + } + } + else { + for (int i = 0; i < MAX_FILTERSHADERS; i++) { + if (gf->gfx_filtershader[i + MAX_FILTERSHADERS][0] == 0) { + _tcscpy(gf->gfx_filtershader[i + MAX_FILTERSHADERS], s); + break; + } + } + } + } + } + return 1; + } + + if ((j == 0 && _tcscmp(option, _T("gfx_filter")) == 0) || (j == 1 && _tcscmp(option, _T("gfx_filter_rtg")) == 0)) { + TCHAR *s = _tcschr(value, ':'); + gf->gfx_filter = 0; + if (s) { + *s++ = 0; + if (!_tcscmp(value, _T("D3D"))) { + p->gfx_api = 1; + _tcscpy(gf->gfx_filtershader[2 * MAX_FILTERSHADERS], s); + for (int i = 0; i < 2 * MAX_FILTERSHADERS; i++) { + if (!_tcsicmp(gf->gfx_filtershader[i], s)) { + gf->gfx_filtershader[i][0] = 0; + gf->gfx_filtermask[i][0] = 0; + } + } + } + } + if (!_tcscmp(value, _T("none"))) { + gf->gfx_filtershader[2 * MAX_FILTERSHADERS][0] = 0; + for (int i = 0; i < 2 * MAX_FILTERSHADERS; i++) { + gf->gfx_filtershader[i][0] = 0; + gf->gfx_filtermask[i][0] = 0; + } + } + else if (!_tcscmp(value, _T("direct3d"))) { + p->gfx_api = 1; // forwards compatibiity + } + else { + int i = 0; + while (uaefilters[i].name) { + if (!_tcscmp(uaefilters[i].cfgname, value)) { + gf->gfx_filter = uaefilters[i].type; + break; + } + i++; + } + } + return 1; + } + if (j == 0 && _tcscmp(option, _T("gfx_filter_mode")) == 0) { + cfgfile_strval(option, value, _T("gfx_filter_mode"), &gf->gfx_filter_filtermode, filtermode2, 0); + return 1; + } + if (j == 1 && _tcscmp(option, _T("gfx_filter_mode_rtg")) == 0) { + cfgfile_strval(option, value, _T("gfx_filter_mode_rtg"), &gf->gfx_filter_filtermode, filtermode2, 0); + return 1; + } + + if ((j == 0 && cfgfile_string(option, value, _T("gfx_filter_aspect_ratio"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) || + (j == 1 && cfgfile_string(option, value, _T("gfx_filter_aspect_ratio_rtg"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR)))) { + int v1, v2; + TCHAR *s; + + gf->gfx_filter_aspect = -1; + v1 = _tstol(tmpbuf); + s = _tcschr(tmpbuf, ':'); + if (s) { + v2 = _tstol(s + 1); + if (v1 < 0 || v2 < 0) + gf->gfx_filter_aspect = -1; + else if (v1 == 0 || v2 == 0) + gf->gfx_filter_aspect = 0; + else + gf->gfx_filter_aspect = v1 * ASPECTMULT + v2; + } + return 1; + } + } +#endif + if (_tcscmp(option, _T("gfx_width")) == 0 || _tcscmp(option, _T("gfx_height")) == 0) { cfgfile_intval(option, value, _T("gfx_width"), &p->gfx_size_win.width, 1); cfgfile_intval(option, value, _T("gfx_height"), &p->gfx_size_win.height, 1); @@ -2194,30 +3354,43 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) return 1; } - if (_tcscmp(option, _T("joyportfriendlyname0")) == 0 || _tcscmp(option, _T("joyportfriendlyname1")) == 0) { - inputdevice_joyport_config(p, value, _tcscmp(option, _T("joyportfriendlyname0")) == 0 ? 0 : 1, -1, 2, true); + if (cfgfile_string(option, value, _T("joyportcustom0"), p->jports_custom[0].custom, sizeof p->jports_custom[0].custom / sizeof(TCHAR))) return 1; - } - if (_tcscmp(option, _T("joyportfriendlyname2")) == 0 || _tcscmp(option, _T("joyportfriendlyname3")) == 0) { - inputdevice_joyport_config(p, value, _tcscmp(option, _T("joyportfriendlyname2")) == 0 ? 2 : 3, -1, 2, true); + if (cfgfile_string(option, value, _T("joyportcustom1"), p->jports_custom[1].custom, sizeof p->jports_custom[1].custom / sizeof(TCHAR))) return 1; - } - if (_tcscmp(option, _T("joyportname0")) == 0 || _tcscmp(option, _T("joyportname1")) == 0) { - inputdevice_joyport_config(p, value, _tcscmp(option, _T("joyportname0")) == 0 ? 0 : 1, -1, 1, true); + if (cfgfile_string(option, value, _T("joyportcustom2"), p->jports_custom[2].custom, sizeof p->jports_custom[2].custom / sizeof(TCHAR))) return 1; - } - if (_tcscmp(option, _T("joyportname2")) == 0 || _tcscmp(option, _T("joyportname3")) == 0) { - inputdevice_joyport_config(p, value, _tcscmp(option, _T("joyportname2")) == 0 ? 2 : 3, -1, 1, true); + if (cfgfile_string(option, value, _T("joyportcustom3"), p->jports_custom[3].custom, sizeof p->jports_custom[3].custom / sizeof(TCHAR))) return 1; - } - if (_tcscmp(option, _T("joyport0")) == 0 || _tcscmp(option, _T("joyport1")) == 0) { - inputdevice_joyport_config(p, value, _tcscmp(option, _T("joyport0")) == 0 ? 0 : 1, -1, 0, true); + if (cfgfile_string(option, value, _T("joyportcustom4"), p->jports_custom[4].custom, sizeof p->jports_custom[4].custom / sizeof(TCHAR))) return 1; - } - if (_tcscmp(option, _T("joyport2")) == 0 || _tcscmp(option, _T("joyport3")) == 0) { - inputdevice_joyport_config(p, value, _tcscmp(option, _T("joyport2")) == 0 ? 2 : 3, -1, 0, true); + if (cfgfile_string(option, value, _T("joyportcustom5"), p->jports_custom[5].custom, sizeof p->jports_custom[5].custom / sizeof(TCHAR))) return 1; - } + + //if (_tcscmp(option, _T("joyportfriendlyname0")) == 0 || _tcscmp(option, _T("joyportfriendlyname1")) == 0) { + // inputdevice_joyport_config_store(p, value, _tcscmp(option, _T("joyportfriendlyname0")) == 0 ? 0 : 1, -1, 2); + // return 1; + //} + //if (_tcscmp(option, _T("joyportfriendlyname2")) == 0 || _tcscmp(option, _T("joyportfriendlyname3")) == 0) { + // inputdevice_joyport_config_store(p, value, _tcscmp(option, _T("joyportfriendlyname2")) == 0 ? 2 : 3, -1, 2); + // return 1; + //} + //if (_tcscmp(option, _T("joyportname0")) == 0 || _tcscmp(option, _T("joyportname1")) == 0) { + // inputdevice_joyport_config_store(p, value, _tcscmp(option, _T("joyportname0")) == 0 ? 0 : 1, -1, 1); + // return 1; + //} + //if (_tcscmp(option, _T("joyportname2")) == 0 || _tcscmp(option, _T("joyportname3")) == 0) { + // inputdevice_joyport_config_store(p, value, _tcscmp(option, _T("joyportname2")) == 0 ? 2 : 3, -1, 1); + // return 1; + //} + //if (_tcscmp(option, _T("joyport0")) == 0 || _tcscmp(option, _T("joyport1")) == 0) { + // inputdevice_joyport_config_store(p, value, _tcscmp(option, _T("joyport0")) == 0 ? 0 : 1, -1, 0); + // return 1; + //} + //if (_tcscmp(option, _T("joyport2")) == 0 || _tcscmp(option, _T("joyport3")) == 0) { + // inputdevice_joyport_config_store(p, value, _tcscmp(option, _T("joyport2")) == 0 ? 2 : 3, -1, 0); + // return 1; + //} if (cfgfile_strval(option, value, _T("joyport0mode"), &p->jports[0].mode, joyportmodes, 0)) return 1; if (cfgfile_strval(option, value, _T("joyport1mode"), &p->jports[1].mode, joyportmodes, 0)) @@ -2234,6 +3407,7 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) return 1; if (cfgfile_strval(option, value, _T("joyport3autofire"), &p->jports[3].autofire, joyaf, 0)) return 1; + if (cfgfile_yesno(option, value, _T("joyport0keyboardoverride"), &vb)) { p->jports[0].nokeyboardoverride = !vb; return 1; @@ -2310,6 +3484,22 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) return 1; } + + //if (_tcscmp(option, _T("kbd_lang")) == 0) { + // KbdLang l; + // if ((l = KBD_LANG_DE, strcasecmp(value, _T("de")) == 0) + // || (l = KBD_LANG_DK, strcasecmp(value, _T("dk")) == 0) + // || (l = KBD_LANG_SE, strcasecmp(value, _T("se")) == 0) + // || (l = KBD_LANG_US, strcasecmp(value, _T("us")) == 0) + // || (l = KBD_LANG_FR, strcasecmp(value, _T("fr")) == 0) + // || (l = KBD_LANG_IT, strcasecmp(value, _T("it")) == 0) + // || (l = KBD_LANG_ES, strcasecmp(value, _T("es")) == 0)) + // p->keyboard_lang = l; + // else + // cfgfile_warning(_T("Unknown keyboard language\n")); + // return 1; + //} + if (cfgfile_string(option, value, _T("config_version"), tmpbuf, sizeof(tmpbuf) / sizeof(TCHAR))) { TCHAR *tmpp2; tmpp = _tcschr(value, '.'); @@ -2364,11 +3554,12 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) _tcsncpy(tmpbuf, value, sizeof tmpbuf / sizeof(TCHAR) - 1); tmpbuf[sizeof tmpbuf / sizeof(TCHAR) - 1] = '\0'; - int vert = -1, horiz = -1, lace = -1, ntsc = -1, framelength = -1, vsync = -1; - bool locked = false; - bool rtg = false; + int vert = -1, horiz = -1, lace = -1, ntsc = -1, framelength = -1, vsync = -1, hres = 0; + bool locked = false, rtg = false, exit = false; + bool cmdmode = false, defaultdata = false; double rate = -1; - TCHAR cmd[MAX_DPATH], label[16] = { 0 }; + int rpct = 0; + TCHAR cmd[MAX_DPATH], filter[64] = { 0 }, label[16] = { 0 }; TCHAR *tmpp = tmpbuf; TCHAR *end = tmpbuf + _tcslen(tmpbuf); cmd[0] = 0; @@ -2384,76 +3575,181 @@ static int cfgfile_parse_host(struct uae_prefs *p, TCHAR *option, TCHAR *value) equals++; *next = 0; - if (rate < 0) - rate = _tstof(tmpp); - else if (!_tcsnicmp(tmpp, _T("v="), 2)) - vert = _tstol(equals); - else if (!_tcsnicmp(tmpp, _T("h="), 2)) - horiz = _tstol(equals); - else if (!_tcsnicmp(tmpp, _T("t="), 2)) - _tcsncpy(label, equals, sizeof label / sizeof(TCHAR) - 1); - else if (equals) { + if (cmdmode) { if (_tcslen(cmd) + _tcslen(tmpp) + 2 < sizeof(cmd) / sizeof(TCHAR)) { _tcscat(cmd, tmpp); _tcscat(cmd, _T("\n")); } } - if (!_tcsnicmp(tmpp, _T("locked"), 4)) - locked = true; - if (!_tcsnicmp(tmpp, _T("nlace"), 5)) - lace = 0; - if (!_tcsnicmp(tmpp, _T("lace"), 4)) - lace = 1; - if (!_tcsnicmp(tmpp, _T("nvsync"), 5)) - vsync = 0; - if (!_tcsnicmp(tmpp, _T("vsync"), 4)) - vsync = 1; - if (!_tcsnicmp(tmpp, _T("ntsc"), 4)) - ntsc = 1; - if (!_tcsnicmp(tmpp, _T("pal"), 3)) - ntsc = 0; - if (!_tcsnicmp(tmpp, _T("lof"), 3)) - framelength = 1; - if (!_tcsnicmp(tmpp, _T("shf"), 3)) - framelength = 0; - if (!_tcsnicmp(tmpp, _T("rtg"), 3)) - rtg = true; + else { + if (!_tcsnicmp(tmpp, _T("cmd="), 4)) { + cmdmode = true; + tmpp += 4; + } + if (rate < 0) + rate = _tstof(tmpp); + else if (!_tcsnicmp(tmpp, _T("v="), 2)) + vert = _tstol(equals); + else if (!_tcsnicmp(tmpp, _T("h="), 2)) + horiz = _tstol(equals); + else if (!_tcsnicmp(tmpp, _T("t="), 2)) + _tcsncpy(label, equals, sizeof label / sizeof(TCHAR) - 1); + else if (!_tcsnicmp(tmpp, _T("filter="), 7)) + _tcsncpy(filter, equals, sizeof filter / sizeof(TCHAR) - 1); + else if (!_tcsnicmp(tmpp, _T("rpct="), 5)) + rpct = _tstol(equals); + else if (equals) { + if (_tcslen(cmd) + _tcslen(tmpp) + 2 < sizeof(cmd) / sizeof(TCHAR)) { + _tcscat(cmd, tmpp); + _tcscat(cmd, _T("\n")); + } + } + if (!_tcsnicmp(tmpp, _T("locked"), 4)) + locked = true; + if (!_tcsnicmp(tmpp, _T("nlace"), 5)) + lace = 0; + if (!_tcsnicmp(tmpp, _T("lace"), 4)) + lace = 1; + if (!_tcsnicmp(tmpp, _T("lores"), 5)) + hres |= 1 << RES_LORES; + if (!_tcsnicmp(tmpp, _T("hires"), 5)) + hres |= 1 << RES_HIRES; + if (!_tcsnicmp(tmpp, _T("shres"), 5)) + hres |= 1 << RES_SUPERHIRES; + if (!_tcsnicmp(tmpp, _T("nvsync"), 5)) + vsync = 0; + if (!_tcsnicmp(tmpp, _T("vsync"), 4)) + vsync = 1; + if (!_tcsnicmp(tmpp, _T("ntsc"), 4)) + ntsc = 1; + if (!_tcsnicmp(tmpp, _T("pal"), 3)) + ntsc = 0; + if (!_tcsnicmp(tmpp, _T("custom"), 6)) + ntsc = 2; + if (!_tcsnicmp(tmpp, _T("lof"), 3)) + framelength = 1; + if (!_tcsnicmp(tmpp, _T("shf"), 3)) + framelength = 0; + if (!_tcsnicmp(tmpp, _T("rtg"), 3)) + rtg = true; + if (!_tcsnicmp(tmpp, _T("exit"), 4)) + exit = true; + if (!_tcsnicmp(tmpp, _T("default"), 7)) + defaultdata = true; + } tmpp = next; if (tmpp >= end) break; tmpp++; } - if (rate > 0) { - for (int i = 0; i < MAX_CHIPSET_REFRESH; i++) { - if (_tcscmp(option, _T("displaydata_pal")) == 0) { - i = CHIPSET_REFRESH_PAL; - p->cr[i].rate = -1; - _tcscpy(label, _T("PAL")); - } - else if (_tcscmp(option, _T("displaydata_ntsc")) == 0) { - i = CHIPSET_REFRESH_NTSC; - p->cr[i].rate = -1; - _tcscpy(label, _T("NTSC")); - } - if (p->cr[i].rate <= 0) { - p->cr[i].horiz = horiz; - p->cr[i].vert = vert; - p->cr[i].lace = lace; - p->cr[i].ntsc = ntsc; - p->cr[i].vsync = vsync; - p->cr[i].locked = locked; - p->cr[i].rtg = rtg; - p->cr[i].framelength = framelength; - p->cr[i].rate = rate; - _tcscpy(p->cr[i].commands, cmd); - _tcscpy(p->cr[i].label, label); - break; - } + for (int i = 0; i < MAX_CHIPSET_REFRESH; i++) { + struct chipset_refresh *cr = &p->cr[i]; + if (_tcscmp(option, _T("displaydata_pal")) == 0) { + i = CHIPSET_REFRESH_PAL; + cr = &p->cr[i]; + cr->inuse = false; + _tcscpy(label, _T("PAL")); + } + else if (_tcscmp(option, _T("displaydata_ntsc")) == 0) { + i = CHIPSET_REFRESH_NTSC; + cr = &p->cr[i]; + cr->inuse = false; + _tcscpy(label, _T("NTSC")); + } + if (!cr->inuse) { + cr->inuse = true; + cr->horiz = horiz; + cr->vert = vert; + cr->lace = lace; + cr->resolution = hres ? hres : 1 + 2 + 4; + cr->resolution_pct = rpct; + cr->ntsc = ntsc; + cr->vsync = vsync; + cr->locked = locked; + cr->rtg = rtg; + cr->exit = exit; + cr->framelength = framelength; + cr->rate = rate; + cr->defaultdata = defaultdata; + _tcscpy(cr->commands, cmd); + _tcscpy(cr->label, label); + TCHAR *se = cfgfile_unescape(filter, NULL); + _tcscpy(cr->filterprofile, se); + xfree(se); + break; } } return 1; } +#ifdef WITH_SLIRP + if (cfgfile_string(option, value, _T("slirp_ports"), tmpbuf, sizeof(tmpbuf) / sizeof(TCHAR))) { + TCHAR *tmpp2 = tmpbuf; + _tcscat(tmpbuf, _T(",")); + for (;;) { + tmpp = _tcschr(tmpp2, ','); + if (!tmpp) + break; + *tmpp++ = 0; + for (i = 0; i < MAX_SLIRP_REDIRS; i++) { + struct slirp_redir *sr = &p->slirp_redirs[i]; + if (sr->proto == 0) { + sr->dstport = _tstol(tmpp2); + sr->proto = 1; + break; + } + } + tmpp2 = tmpp; + } + return 1; + } + if (cfgfile_string(option, value, _T("slirp_redir"), tmpbuf, sizeof(tmpbuf) / sizeof(TCHAR))) { + TCHAR *tmpp2 = tmpbuf; + _tcscat(tmpbuf, _T(":")); + for (i = 0; i < MAX_SLIRP_REDIRS; i++) { + struct slirp_redir *sr = &p->slirp_redirs[i]; + if (sr->proto == 0) { + char *s; + tmpp = _tcschr(tmpp2, ':'); + if (!tmpp) + break; + *tmpp++ = 0; + if (!_tcsicmp(tmpp2, _T("tcp"))) + sr->proto = 1; + else if (!_tcsicmp(tmpp2, _T("udp"))) + sr->proto = 2; + else + break; + tmpp2 = tmpp; + tmpp = _tcschr(tmpp2, ':'); + if (!tmpp) { + sr->proto = 0; + break; + } + *tmpp++ = 0; + sr->dstport = _tstol(tmpp2); + tmpp2 = tmpp; + tmpp = _tcschr(tmpp2, ':'); + if (!tmpp) { + sr->proto = 0; + break; + } + *tmpp++ = 0; + sr->srcport = _tstol(tmpp2); + tmpp2 = tmpp; + tmpp = _tcschr(tmpp2, ':'); + if (!tmpp) + break; + *tmpp++ = 0; + s = ua(tmpp2); + sr->addr = inet_addr(s); + xfree(s); + } + } + return 1; + } +#endif + return 0; } @@ -2527,7 +3823,7 @@ end: xfree(romtxt); } -static struct uaedev_config_data* getuci(struct uae_prefs* p) +static struct uaedev_config_data *getuci(struct uae_prefs *p) { if (p->mountitems < MOUNT_CONFIG_SIZE) return &p->mountconfig[p->mountitems++]; @@ -2545,27 +3841,42 @@ struct uaedev_config_data *add_filesys_config(struct uae_prefs *p, int index, st return NULL; } } - if (ci->type == UAEDEV_CD) { - if (ci->controller > HD_CONTROLLER_SCSI6 || ci->controller < HD_CONTROLLER_IDE0) - return NULL; - } - if (ci->type == UAEDEV_TAPE) { - if (ci->controller != HD_CONTROLLER_UAE && (ci->controller > HD_CONTROLLER_SCSI6 || ci->controller < HD_CONTROLLER_IDE0)) - return NULL; + for (;;) { + if (ci->type == UAEDEV_CD) { + if (ci->controller_type >= HD_CONTROLLER_TYPE_IDE_FIRST && ci->controller_type <= HD_CONTROLLER_TYPE_IDE_LAST) + break; + if (ci->controller_type >= HD_CONTROLLER_TYPE_SCSI_FIRST && ci->controller_type <= HD_CONTROLLER_TYPE_SCSI_LAST) + break; + } + else if (ci->type == UAEDEV_TAPE) { + if (ci->controller_type == HD_CONTROLLER_TYPE_UAE) + break; + if (ci->controller_type >= HD_CONTROLLER_TYPE_SCSI_FIRST && ci->controller_type <= HD_CONTROLLER_TYPE_SCSI_LAST) + break; + } + else { + break; + } + return NULL; } + if (index < 0) { - if (ci->controller != HD_CONTROLLER_UAE) { - int ctrl = ci->controller; + if (ci->controller_type != HD_CONTROLLER_TYPE_UAE) { + int ctrl = ci->controller_type; + int ctrlunit = ci->controller_type_unit; + int cunit = ci->controller_unit; for (;;) { for (i = 0; i < p->mountitems; i++) { - if (p->mountconfig[i].ci.controller == ctrl) { - ctrl++; - if (ctrl == HD_CONTROLLER_IDE3 + 1 || ctrl == HD_CONTROLLER_SCSI6 + 1) + if (p->mountconfig[i].ci.controller_type == ctrl && p->mountconfig[i].ci.controller_type_unit == ctrlunit && p->mountconfig[i].ci.controller_unit == cunit) { + cunit++; + if (ctrl >= HD_CONTROLLER_TYPE_IDE_FIRST && ctrl <= HD_CONTROLLER_TYPE_IDE_LAST && cunit == 4) + return NULL; + if (ctrl >= HD_CONTROLLER_TYPE_SCSI_FIRST && ctrl <= HD_CONTROLLER_TYPE_SCSI_LAST && cunit >= 7) return NULL; } } if (i == p->mountitems) { - ci->controller = ctrl; + ci->controller_unit = cunit; break; } } @@ -2587,8 +3898,8 @@ struct uaedev_config_data *add_filesys_config(struct uae_prefs *p, int index, st return NULL; memcpy(&uci->ci, ci, sizeof(struct uaedev_config_info)); - validatedevicename(uci->ci.devname); - validatevolumename(uci->ci.volname); + validatedevicename(uci->ci.devname, NULL); + validatevolumename(uci->ci.volname, NULL); if (!uci->ci.devname[0] && ci->type != UAEDEV_CD && ci->type != UAEDEV_TAPE) { TCHAR base[32]; TCHAR base2[32]; @@ -2607,10 +3918,10 @@ struct uaedev_config_data *add_filesys_config(struct uae_prefs *p, int index, st } } _tcscpy(uci->ci.devname, base2); - validatedevicename(uci->ci.devname); + validatedevicename(uci->ci.devname, NULL); } if (ci->type == UAEDEV_DIR) { - TCHAR *s = filesys_createvolname(uci->ci.volname, uci->ci.rootdir, _T("Harddrive")); + TCHAR *s = filesys_createvolname(uci->ci.volname, uci->ci.rootdir, NULL, _T("Harddrive")); _tcscpy(uci->ci.volname, s); xfree(s); } @@ -2621,9 +3932,9 @@ static void parse_addmem(struct uae_prefs *p, TCHAR *buf, int num) { int size = 0, addr = 0; - if (!getintval2(&buf, &addr, ',')) + if (!getintval2(&buf, &addr, ',', false)) return; - if (!getintval2(&buf, &size, 0)) + if (!getintval2(&buf, &size, 0, true)) return; if (addr & 0xffff) return; @@ -2633,24 +3944,89 @@ static void parse_addmem(struct uae_prefs *p, TCHAR *buf, int num) p->custom_memory_sizes[num] = size; } -static int get_filesys_controller(const TCHAR *hdc) +static void get_filesys_controller(const TCHAR *hdc, int *type, int *typenum, int *num) { - int hdcv = HD_CONTROLLER_UAE; + int hdcv = HD_CONTROLLER_TYPE_UAE; + int hdunit = 0; + int idx = 0; if (_tcslen(hdc) >= 4 && !_tcsncmp(hdc, _T("ide"), 3)) { - hdcv = hdc[3] - '0' + HD_CONTROLLER_IDE0; - if (hdcv < HD_CONTROLLER_IDE0 || hdcv > HD_CONTROLLER_IDE3) - hdcv = 0; + hdcv = HD_CONTROLLER_TYPE_IDE_AUTO; + hdunit = hdc[3] - '0'; + if (hdunit < 0 || hdunit >= 6) + hdunit = 0; } - if (_tcslen(hdc) >= 5 && !_tcsncmp(hdc, _T("scsi"), 4)) { - hdcv = hdc[4] - '0' + HD_CONTROLLER_SCSI0; - if (hdcv < HD_CONTROLLER_SCSI0 || hdcv > HD_CONTROLLER_SCSI6) - hdcv = 0; + else if (_tcslen(hdc) >= 5 && !_tcsncmp(hdc, _T("scsi"), 4)) { + hdcv = HD_CONTROLLER_TYPE_SCSI_AUTO; + hdunit = hdc[4] - '0'; + if (hdunit < 0 || hdunit >= 8 + 2) + hdunit = 0; } - if (_tcslen(hdc) >= 6 && !_tcsncmp(hdc, _T("scsram"), 6)) - hdcv = HD_CONTROLLER_PCMCIA_SRAM; - if (_tcslen(hdc) >= 5 && !_tcsncmp(hdc, _T("scide"), 6)) - hdcv = HD_CONTROLLER_PCMCIA_IDE; - return hdcv; + if (hdcv > HD_CONTROLLER_TYPE_UAE) { + bool found = false; + const TCHAR *ext = _tcsrchr(hdc, '_'); + if (ext) { + ext++; + int len = _tcslen(ext); + if (len > 2 && ext[len - 2] == '-' && ext[len - 1] >= '2' && ext[len - 1] <= '9') { + idx = ext[len - 1] - '1'; + len -= 2; + } + for (int i = 0; hdcontrollers[i].label; i++) { + const TCHAR *ext2 = _tcsrchr(hdcontrollers[i].label, '_'); + if (ext2) { + ext2++; + if (_tcslen(ext2) == len && !_tcsnicmp(ext, ext2, len) && hdc[0] == hdcontrollers[i].label[0]) { + if (hdcontrollers[i].romtype) { + for (int j = 0; expansionroms[j].name; j++) { + if ((expansionroms[j].romtype & ROMTYPE_MASK) == hdcontrollers[i].romtype) { + hdcv = hdcv == HD_CONTROLLER_TYPE_IDE_AUTO ? j + HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST : j + HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST; + break; + } + } + } + if (hdcv == HD_CONTROLLER_TYPE_IDE_AUTO) { + hdcv = i; + } + else if (hdcv == HD_CONTROLLER_TYPE_SCSI_AUTO) { + hdcv = i + HD_CONTROLLER_EXPANSION_MAX; + } + found = true; + break; + } + } + } + if (!found) { + for (int i = 0; expansionroms[i].name; i++) { + const struct expansionromtype *ert = &expansionroms[i]; + if (_tcslen(ert->name) == len && !_tcsnicmp(ext, ert->name, len)) { + if (hdcv == HD_CONTROLLER_TYPE_IDE_AUTO) { + hdcv = HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST + i; + } + else { + hdcv = HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST + i; + } + break; + } + } + + } + } + } + else if (_tcslen(hdc) >= 6 && !_tcsncmp(hdc, _T("scsram"), 6)) { + hdcv = HD_CONTROLLER_TYPE_PCMCIA; + hdunit = 0; + idx = 0; + } + else if (_tcslen(hdc) >= 5 && !_tcsncmp(hdc, _T("scide"), 6)) { + hdcv = HD_CONTROLLER_TYPE_PCMCIA; + hdunit = 0; + idx = 1; + } + if (idx >= MAX_DUPLICATE_EXPANSION_BOARDS) + idx = MAX_DUPLICATE_EXPANSION_BOARDS - 1; + *type = hdcv; + *typenum = idx; + *num = hdunit; } static bool parse_geo(const TCHAR *tname, struct uaedev_config_info *uci, struct hardfiledata *hfd, bool empty) @@ -2745,7 +4121,7 @@ static bool parse_geo(const TCHAR *tname, struct uaedev_config_info *uci, struct if (!_tcsicmp(key, _T("unit"))) uci->unit = v; if (!_tcsicmp(key, _T("controller"))) - uci->controller = get_filesys_controller(val); + get_filesys_controller(val, &uci->controller_type, &uci->controller_type_unit, &uci->controller_unit); if (!_tcsicmp(key, _T("flags"))) uci->flags = v; if (!_tcsicmp(key, _T("priority"))) @@ -2763,10 +4139,31 @@ static bool parse_geo(const TCHAR *tname, struct uaedev_config_info *uci, struct _tcscpy(uci->filesys, val); if (!_tcsicmp(key, _T("device"))) _tcscpy(uci->devname, val); + if (!_tcsicmp(key, _T("badblocks"))) { + TCHAR *p = val; + while (p && *p && uci->badblock_num < MAX_UAEDEV_BADBLOCKS) { + struct uaedev_badblock *bb = &uci->badblocks[uci->badblock_num]; + if (!_istdigit(*p)) + break; + bb->first = _tstol(p); + bb->last = bb->first; + TCHAR *p1 = _tcschr(p, ','); + TCHAR *p2 = NULL; + if (p1) { + p2 = p1 + 1; + *p1 = 0; + } + p1 = _tcschr(p, '-'); + if (p1) { + bb->last = _tstol(p1 + 1); + } + uci->badblock_num++; + p = p2; + } + } xfree(val); xfree(key); } - zfile_fclose(f); return false; } @@ -2782,7 +4179,7 @@ bool get_hd_geometry(struct uaedev_config_info *uci) memset(&hfd, 0, sizeof hfd); hfd.ci.readonly = true; hfd.ci.blocksize = 512; - if (hdf_open(&hfd, uci->rootdir)) { + if (hdf_open(&hfd, uci->rootdir) > 0) { parse_geo(tname, uci, &hfd, false); hdf_close(&hfd); } @@ -2901,7 +4298,7 @@ static int cfgfile_parse_newfilesys(struct uae_prefs *p, int nr, int type, TCHAR || !getintval(&tmpp, &uci.reserved, ',') || !getintval(&tmpp, &uci.blocksize, ',')) goto invalid_fs; - if (getintval2(&tmpp, &uci.bootpri, ',')) { + if (getintval2(&tmpp, &uci.bootpri, ',', false)) { tmpp2 = tmpp; tmpp = _tcschr(tmpp, ','); if (tmpp != 0) { @@ -2910,14 +4307,53 @@ static int cfgfile_parse_newfilesys(struct uae_prefs *p, int nr, int type, TCHAR TCHAR *tmpp2 = _tcschr(tmpp, ','); if (tmpp2) *tmpp2++ = 0; - uci.controller = get_filesys_controller(tmpp); + get_filesys_controller(tmpp, &uci.controller_type, &uci.controller_type_unit, &uci.controller_unit); if (tmpp2) { - if (getintval2(&tmpp2, &uci.highcyl, ',')) { + if (getintval2(&tmpp2, &uci.highcyl, ',', false)) { getintval(&tmpp2, &uci.pcyls, '/'); getintval(&tmpp2, &uci.pheads, '/'); - getintval2(&tmpp2, &uci.psecs, '/'); + getintval2(&tmpp2, &uci.psecs, '/', true); + if (uci.pheads && uci.psecs) { + uci.physical_geometry = true; + } + else { + uci.pheads = uci.psecs = uci.pcyls = 0; + uci.physical_geometry = false; + } } } + uci.controller_media_type = 0; + uci.unit_feature_level = 1; + + if (cfgfile_option_find(tmpp2, _T("CF"))) + uci.controller_media_type = 1; + else if (cfgfile_option_find(tmpp2, _T("HD"))) + uci.controller_media_type = 0; + + TCHAR *pflags; + if ((pflags = cfgfile_option_get(tmpp2, _T("flags")))) { + getintval(&pflags, &uci.unit_special_flags, 0); + } + + if (cfgfile_option_find(tmpp2, _T("lock"))) + uci.lock = true; + + if (cfgfile_option_find(tmpp2, _T("SCSI2"))) + uci.unit_feature_level = HD_LEVEL_SCSI_2; + else if (cfgfile_option_find(tmpp2, _T("SCSI1"))) + uci.unit_feature_level = HD_LEVEL_SCSI_1; + else if (cfgfile_option_find(tmpp2, _T("SASIE"))) + uci.unit_feature_level = HD_LEVEL_SASI_ENHANCED; + else if (cfgfile_option_find(tmpp2, _T("SASI"))) + uci.unit_feature_level = HD_LEVEL_SASI; + else if (cfgfile_option_find(tmpp2, _T("SASI_CHS"))) + uci.unit_feature_level = HD_LEVEL_SASI_CHS; + else if (cfgfile_option_find(tmpp2, _T("ATA2+S"))) + uci.unit_feature_level = HD_LEVEL_ATA_2S; + else if (cfgfile_option_find(tmpp2, _T("ATA2+"))) + uci.unit_feature_level = HD_LEVEL_ATA_2; + else if (cfgfile_option_find(tmpp2, _T("ATA1"))) + uci.unit_feature_level = HD_LEVEL_ATA_1; } } if (type == 2) { @@ -2954,7 +4390,7 @@ empty_fs: return 1; invalid_fs: - write_log(_T("Invalid filesystem/hardfile/cd specification.\n")); + cfgfile_warning(_T("Invalid filesystem/hardfile/cd specification.\n")); return 1; } @@ -3027,7 +4463,7 @@ static int cfgfile_parse_filesys(struct uae_prefs *p, const TCHAR *option, TCHAR _tcscpy(uci->filesys, value); } else if (!_tcscmp(s, _T("controller"))) { - uci->controller = get_filesys_controller(value); + get_filesys_controller(value, &uci->controller_type, &uci->controller_type_unit, &uci->controller_unit); } } } @@ -3088,7 +4524,7 @@ static int cfgfile_parse_filesys(struct uae_prefs *p, const TCHAR *option, TCHAR xfree(str); return 1; invalid_fs: - write_log(_T("Invalid filesystem/hardfile specification.\n")); + cfgfile_warning(_T("Invalid filesystem/hardfile specification.\n")); return 1; } @@ -3097,28 +4533,233 @@ static int cfgfile_parse_filesys(struct uae_prefs *p, const TCHAR *option, TCHAR return cfgfile_parse_newfilesys(p, -1, 0, value, -1, false); if (_tcscmp(option, _T("hardfile2")) == 0) return cfgfile_parse_newfilesys(p, -1, 1, value, -1, false); + if (_tcscmp(option, _T("filesystem_extra")) == 0) { + int idx = 0; + TCHAR *s = value; + _tcscat(s, _T(",")); + struct uaedev_config_info *ci = NULL; + for (;;) { + TCHAR *tmpp = _tcschr(s, ','); + if (tmpp == NULL) + return 1; + *tmpp++ = 0; + if (idx == 0) { + for (i = 0; i < p->mountitems; i++) { + if (p->mountconfig[i].ci.devname && !_tcscmp(p->mountconfig[i].ci.devname, s)) { + ci = &p->mountconfig[i].ci; + break; + } + } + if (!ci || ci->type != UAEDEV_DIR) + return 1; + } + else { + bool b = true; + TCHAR *tmpp2 = _tcschr(s, '='); + if (tmpp2) { + *tmpp2++ = 0; + if (!strcasecmp(tmpp2, _T("false"))) + b = false; + } + if (!strcasecmp(s, _T("inject_icons"))) { + ci->inject_icons = b; + } + } + idx++; + s = tmpp; + } + } return 0; } +static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, const TCHAR *value, struct multipath *mp) +{ + TCHAR buf[256], buf2[MAX_DPATH], buf3[MAX_DPATH]; + bool dummy; + int val; + const struct expansionromtype *ert; + + for (int i = 0; expansionroms[i].name; i++) { + struct boardromconfig *brc; + int idx; + ert = &expansionroms[i]; + + for (int j = 0; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) { + TCHAR name[256]; + + if (j == 0) + _tcscpy(name, ert->name); + else + _stprintf(name, _T("%s-%d"), ert->name, j + 1); + + _stprintf(buf, _T("scsi_%s"), name); + if (cfgfile_yesno(option, value, buf, &dummy)) { + return true; + } + + _stprintf(buf, _T("%s_rom_file"), name); + if (cfgfile_path(option, value, buf, buf2, MAX_DPATH / sizeof(TCHAR), mp)) { + if (buf2[0]) { + if (ert->deviceflags & EXPANSIONTYPE_NET) { + // make sure network settings are available before parsing net "rom" entries + //ethernet_updateselection(); + } + brc = get_device_rom_new(p, ert->romtype, j, &idx); + _tcscpy(brc->roms[idx].romfile, buf2); + } + return true; + } + + _stprintf(buf, _T("%s_rom_file_id"), name); + buf2[0] = 0; + if (cfgfile_rom(option, value, buf, buf2, MAX_DPATH / sizeof(TCHAR))) { + if (buf2[0]) { + brc = get_device_rom_new(p, ert->romtype, j, &idx); + _tcscpy(brc->roms[idx].romfile, buf2); + } + return true; + } + + _stprintf(buf, _T("%s_rom"), name); + if (cfgfile_string(option, value, buf, buf2, sizeof buf2 / sizeof(TCHAR))) { + if (buf2[0]) { + decode_rom_ident(buf3, sizeof(buf3) / sizeof(TCHAR), buf2, ert->romtype); + if (buf3[0]) { + brc = get_device_rom_new(p, ert->romtype, j, &idx); + _tcscpy(brc->roms[idx].romident, buf3); + } + } + return true; + } + + _stprintf(buf, _T("%s_rom_options"), name); + if (cfgfile_string(option, value, buf, buf2, sizeof buf2 / sizeof(TCHAR))) { + brc = get_device_rom(p, ert->romtype, j, &idx); + if (brc) { + TCHAR *p; + if (cfgfile_option_bool(buf2, _T("autoboot_disabled")) == 1) { + brc->roms[idx].autoboot_disabled = true; + } + p = cfgfile_option_get(buf2, _T("order")); + if (p) { + brc->device_order = _tstol(p); + } + if (ert->settings) { + brc->roms[idx].device_settings = cfgfile_read_rom_settings(ert->settings, buf2, brc->roms[idx].configtext); + } + if (ert->id_jumper) { + p = cfgfile_option_get(buf2, _T("id")); + if (p) { + brc->roms[idx].device_id = _tstol(p); + } + } + if (ert->subtypes) { + const struct expansionsubromtype *srt = ert->subtypes; + TCHAR tmp[MAX_DPATH]; + p = tmp; + *p = 0; + while (srt->name) { + _tcscpy(p, srt->configname); + p += _tcslen(p) + 1; + p[0] = 0; + srt++; + } + int v = cfgfile_option_select(buf2, _T("subtype"), tmp); + if (v >= 0) + brc->roms[idx].subtype = v; + } + } + return true; + } + } + + _stprintf(buf, _T("%s_mem_size"), ert->name); + if (cfgfile_intval(option, value, buf, &val, 0x40000)) { + if (val) { + brc = get_device_rom_new(p, ert->romtype, 0, &idx); + brc->roms[idx].board_ram_size = val; + } + return true; + } + } + return false; +} + +static void addbcromtype(struct uae_prefs *p, int romtype, bool add, const TCHAR *romfile, int devnum) +{ + if (!add) { + clear_device_rom(p, romtype, devnum, true); + } + else { + struct boardromconfig *brc = get_device_rom_new(p, romtype, devnum, NULL); + if (brc && !brc->roms[0].romfile[0]) { + _tcscpy(brc->roms[0].romfile, romfile ? romfile : _T(":ENABLED")); + } + } +} + +static void addbcromtypenet(struct uae_prefs *p, int romtype, const TCHAR *netname, int devnum) +{ + int is = is_device_rom(p, romtype, devnum); + if (netname == NULL || netname[0] == 0) { + if (is < 0) + clear_device_rom(p, romtype, devnum, true); + } + else { + if (is < 0) { + struct boardromconfig *brc = get_device_rom_new(p, romtype, devnum, NULL); + if (brc) { + if (!brc->roms[0].romfile[0]) { + _tcscpy(brc->roms[0].romfile, _T(":ENABLED")); + } + //ethernet_updateselection(); + //if (!brc->roms[0].device_settings) + // brc->roms[0].device_settings = ethernet_getselection(netname); + } + } + } +} + static int cfgfile_parse_hardware(struct uae_prefs *p, const TCHAR *option, TCHAR *value) { int tmpval, dummyint, i; - bool tmpbool, dummybool; - TCHAR *section = 0; + bool dummybool; TCHAR tmpbuf[CONFIG_BLEN]; - if (cfgfile_yesno(option, value, _T("cpu_cycle_exact"), &p->cpu_cycle_exact) - || cfgfile_yesno(option, value, _T("blitter_cycle_exact"), &p->blitter_cycle_exact)) { - if (p->cpu_model >= 68020 && p->cachesize > 0) - p->cpu_cycle_exact = p->blitter_cycle_exact = 0; + if (cfgfile_yesno(option, value, _T("cpu_cycle_exact"), &p->cpu_cycle_exact)) { /* we don't want cycle-exact in 68020/40+JIT modes */ + if (p->cpu_model >= 68020 && p->cachesize > 0) + p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = false; + p->cpu_memory_cycle_exact = p->cpu_cycle_exact; return 1; } - if (cfgfile_yesno(option, value, _T("cycle_exact"), &tmpbool)) { - p->cpu_cycle_exact = p->blitter_cycle_exact = tmpbool; + if (cfgfile_yesno(option, value, _T("blitter_cycle_exact"), &p->blitter_cycle_exact)) { if (p->cpu_model >= 68020 && p->cachesize > 0) - p->cpu_cycle_exact = p->blitter_cycle_exact = false; + p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = false; + return 1; + } + if (cfgfile_yesno(option, value, _T("cpu_memory_cycle_exact"), &p->cpu_memory_cycle_exact)) { + if (!p->cpu_memory_cycle_exact) + p->blitter_cycle_exact = p->cpu_cycle_exact = false; + return 1; + } + if (cfgfile_strval(option, value, _T("cycle_exact"), &tmpval, cycleexact, 0)) { + if (tmpval > 0) { + p->blitter_cycle_exact = true; + p->cpu_cycle_exact = tmpval > 1; + p->cpu_memory_cycle_exact = true; + } + else { + p->blitter_cycle_exact = false; + p->cpu_cycle_exact = false; + p->cpu_memory_cycle_exact = false; + } + if (p->cpu_model >= 68020 && p->cachesize > 0) + p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = false; + // if old version and CE and fastest possible: set to approximate + if (p->cpu_cycle_exact && p->config_version < ((2 << 16) | (8 << 8) | (2 << 0)) && p->m68k_speed < 0) + p->m68k_speed = 0; return 1; } @@ -3128,18 +4769,15 @@ static int cfgfile_parse_hardware(struct uae_prefs *p, const TCHAR *option, TCHA } - if (cfgfile_yesno(option, value, _T("scsi_a3000"), &dummybool)) { - if (dummybool) - p->cs_mbdmac = 1; - return 1; - } - if (cfgfile_yesno(option, value, _T("scsi_a4000t"), &dummybool)) { - if (dummybool) - p->cs_mbdmac = 2; + if (cfgfile_string(option, value, _T("a2065"), p->a2065name, sizeof p->a2065name / sizeof(TCHAR))) { + if (p->a2065name[0]) + addbcromtype(p, ROMTYPE_A2065, true, NULL, 0); return 1; } - if (cfgfile_string(option, value, _T("a2065"), p->a2065name, sizeof p->a2065name / sizeof(TCHAR))) + if (cfgfile_string(option, value, _T("ne2000_pci"), p->ne2000pciname, sizeof p->ne2000pciname / sizeof(TCHAR))) + return 1; + if (cfgfile_string(option, value, _T("ne2000_pcmcia"), p->ne2000pcmcianame, sizeof p->ne2000pcmcianame / sizeof(TCHAR))) return 1; if (cfgfile_yesno(option, value, _T("immediate_blits"), &p->immediate_blits) @@ -3149,12 +4787,10 @@ static int cfgfile_parse_hardware(struct uae_prefs *p, const TCHAR *option, TCHA || cfgfile_yesno(option, value, _T("cd32c2p"), &p->cs_cd32c2p) || cfgfile_yesno(option, value, _T("cd32nvram"), &p->cs_cd32nvram) || cfgfile_yesno(option, value, _T("cdtvcd"), &p->cs_cdtvcd) + || cfgfile_yesno(option, value, _T("cdtv-cr"), &p->cs_cdtvcr) || cfgfile_yesno(option, value, _T("cdtvram"), &p->cs_cdtvram) || cfgfile_yesno(option, value, _T("a1000ram"), &p->cs_a1000ram) - || cfgfile_yesno(option, value, _T("pcmcia"), &p->cs_pcmcia) || cfgfile_yesno(option, value, _T("scsi_cdtv"), &p->cs_cdtvscsi) - || cfgfile_yesno(option, value, _T("scsi_a4091"), &p->a4091) - || cfgfile_yesno(option, value, _T("scsi_a2091"), &p->a2091) || cfgfile_yesno(option, value, _T("cia_overlay"), &p->cs_ciaoverlay) || cfgfile_yesno(option, value, _T("bogomem_fast"), &p->cs_slowmemisfast) || cfgfile_yesno(option, value, _T("ksmirror_e0"), &p->cs_ksmirror_e0) @@ -3163,40 +4799,49 @@ static int cfgfile_parse_hardware(struct uae_prefs *p, const TCHAR *option, TCHA || cfgfile_yesno(option, value, _T("cia_todbug"), &p->cs_ciatodbug) || cfgfile_yesno(option, value, _T("denise_noehb"), &p->cs_denisenoehb) || cfgfile_yesno(option, value, _T("ics_agnus"), &p->cs_dipagnus) + || cfgfile_yesno(option, value, _T("z3_autoconfig"), &p->cs_z3autoconfig) + || cfgfile_yesno(option, value, _T("color_burst"), &p->cs_color_burst) + || cfgfile_yesno(option, value, _T("1mchipjumper"), &p->cs_1mchipjumper) || cfgfile_yesno(option, value, _T("agnus_bltbusybug"), &p->cs_agnusbltbusybug) - || cfgfile_yesno(option, value, _T("fastmem_autoconfig"), &p->fastmem_autoconfig) || cfgfile_yesno(option, value, _T("gfxcard_hardware_vblank"), &p->rtg_hardwareinterrupt) || cfgfile_yesno(option, value, _T("gfxcard_hardware_sprite"), &p->rtg_hardwaresprite) || cfgfile_yesno(option, value, _T("synchronize_clock"), &p->tod_hack) + || cfgfile_yesno(option, value, _T("keyboard_connected"), &p->keyboard_connected) || cfgfile_yesno(option, value, _T("kickshifter"), &p->kickshifter) || cfgfile_yesno(option, value, _T("ks_write_enabled"), &p->rom_readwrite) || cfgfile_yesno(option, value, _T("ntsc"), &p->ntscmode) || cfgfile_yesno(option, value, _T("sana2"), &p->sana2) || cfgfile_yesno(option, value, _T("genlock"), &p->genlock) + || cfgfile_yesno(option, value, _T("genlock_alpha"), &p->genlock_alpha) + || cfgfile_yesno(option, value, _T("genlock_aspect"), &p->genlock_aspect) || cfgfile_yesno(option, value, _T("cpu_compatible"), &p->cpu_compatible) + || cfgfile_yesno(option, value, _T("cpu_threaded"), &p->cpu_thread) || cfgfile_yesno(option, value, _T("cpu_24bit_addressing"), &p->address_space_24) + || cfgfile_yesno(option, value, _T("cpu_reset_pause"), &p->reset_delay) || cfgfile_yesno(option, value, _T("parallel_on_demand"), &p->parallel_demand) || cfgfile_yesno(option, value, _T("parallel_postscript_emulation"), &p->parallel_postscript_emulation) || cfgfile_yesno(option, value, _T("parallel_postscript_detection"), &p->parallel_postscript_detection) || cfgfile_yesno(option, value, _T("serial_on_demand"), &p->serial_demand) || cfgfile_yesno(option, value, _T("serial_hardware_ctsrts"), &p->serial_hwctsrts) || cfgfile_yesno(option, value, _T("serial_direct"), &p->serial_direct) + || cfgfile_yesno(option, value, _T("fpu_strict"), &p->fpu_strict) + || cfgfile_yesno(option, value, _T("fpu_softfloat"), &p->fpu_softfloat) || cfgfile_yesno(option, value, _T("comp_nf"), &p->compnf) || cfgfile_yesno(option, value, _T("comp_constjump"), &p->comp_constjump) - || cfgfile_yesno(option, value, _T("comp_oldsegv"), &p->comp_oldsegv) - || cfgfile_yesno(option, value, _T("compforcesettings"), &dummybool) +#ifdef USE_JIT_FPU || cfgfile_yesno(option, value, _T("compfpu"), &p->compfpu) - || cfgfile_yesno(option, value, _T("fpu_strict"), &p->fpu_strict) - || cfgfile_yesno(option, value, _T("comp_midopt"), &p->comp_midopt) - || cfgfile_yesno(option, value, _T("comp_lowopt"), &p->comp_lowopt) +#endif || cfgfile_yesno(option, value, _T("rtg_nocustom"), &p->picasso96_nocustom) || cfgfile_yesno(option, value, _T("floppy_write_protect"), &p->floppy_read_only) + || cfgfile_yesno(option, value, _T("harddrive_write_protect"), &p->harddrive_read_only) || cfgfile_yesno(option, value, _T("uae_hide_autoconfig"), &p->uae_hide_autoconfig) + || cfgfile_yesno(option, value, _T("board_custom_order"), &p->autoconfig_custom_sort) || cfgfile_yesno(option, value, _T("uaeserial"), &p->uaeserial)) return 1; if (cfgfile_intval(option, value, _T("cachesize"), &p->cachesize, 1) + || cfgfile_intval(option, value, _T("cd32nvram_size"), &p->cs_cd32nvram_size, 1024) || cfgfile_intval(option, value, _T("chipset_hacks"), &p->cs_hacks, 1) || cfgfile_intval(option, value, _T("serial_stopbits"), &p->serial_stopbits, 1) || cfgfile_intval(option, value, _T("cpu060_revision"), &p->cpu060_revision, 1) @@ -3205,19 +4850,17 @@ static int cfgfile_parse_hardware(struct uae_prefs *p, const TCHAR *option, TCHA || cfgfile_intval(option, value, _T("fatgary"), &p->cs_fatgaryrev, 1) || cfgfile_intval(option, value, _T("ramsey"), &p->cs_ramseyrev, 1) || cfgfile_doubleval(option, value, _T("chipset_refreshrate"), &p->chipset_refreshrate) - || cfgfile_intval(option, value, _T("fastmem_size"), &p->fastmem_size, 0x100000) - || cfgfile_intval(option, value, _T("fastmem2_size"), &p->fastmem2_size, 0x100000) + || cfgfile_intval(option, value, _T("cpuboardmem1_size"), &p->cpuboardmem1_size, 0x100000) + || cfgfile_intval(option, value, _T("cpuboardmem2_size"), &p->cpuboardmem2_size, 0x100000) + || cfgfile_intval(option, value, _T("mem25bit_size"), &p->mem25bit_size, 0x100000) || cfgfile_intval(option, value, _T("a3000mem_size"), &p->mbresmem_low_size, 0x100000) || cfgfile_intval(option, value, _T("mbresmem_size"), &p->mbresmem_high_size, 0x100000) - || cfgfile_intval(option, value, _T("z3mem_size"), &p->z3fastmem_size, 0x100000) - || cfgfile_intval(option, value, _T("z3mem2_size"), &p->z3fastmem2_size, 0x100000) || cfgfile_intval(option, value, _T("megachipmem_size"), &p->z3chipmem_size, 0x100000) - || cfgfile_intval(option, value, _T("z3mem_start"), &p->z3fastmem_start, 1) + || cfgfile_intval(option, value, _T("z3mem_start"), &p->z3autoconfig_start, 1) || cfgfile_intval(option, value, _T("bogomem_size"), &p->bogomem_size, 0x40000) - || cfgfile_intval(option, value, _T("gfxcard_size"), &p->rtgmem_size, 0x100000) - || cfgfile_strval(option, value, _T("gfxcard_type"), &p->rtgmem_type, rtgtype, 0) || cfgfile_intval(option, value, _T("rtg_modes"), &p->picasso96_modeflags, 1) || cfgfile_intval(option, value, _T("floppy_speed"), &p->floppy_speed, 1) + || cfgfile_intval(option, value, _T("cd_speed"), &p->cd_speed, 1) || cfgfile_intval(option, value, _T("floppy_write_length"), &p->floppy_write_length, 1) || cfgfile_intval(option, value, _T("floppy_random_bits_min"), &p->floppy_random_bits_min, 1) || cfgfile_intval(option, value, _T("floppy_random_bits_max"), &p->floppy_random_bits_max, 1) @@ -3231,13 +4874,13 @@ static int cfgfile_parse_hardware(struct uae_prefs *p, const TCHAR *option, TCHA || cfgfile_intval(option, value, _T("uae_hide"), &p->uae_hide, 1) || cfgfile_intval(option, value, _T("cpu_frequency"), &p->cpu_frequency, 1) || cfgfile_intval(option, value, _T("kickstart_ext_rom_file2addr"), &p->romextfile2addr, 1) - || cfgfile_intval(option, value, _T("catweasel"), &p->catweasel, 1)) + || cfgfile_intval(option, value, _T("genlock_scale"), &p->genlock_scale, 1) + || cfgfile_intval(option, value, _T("genlock_mix"), &p->genlock_mix, 1)) return 1; if (cfgfile_strval(option, value, _T("comp_trustbyte"), &p->comptrustbyte, compmode, 0) || cfgfile_strval(option, value, _T("rtc"), &p->cs_rtc, rtctype, 0) || cfgfile_strval(option, value, _T("ciaatod"), &p->cs_ciaatod, ciaatodmode, 0) - || cfgfile_strval(option, value, _T("ide"), &p->cs_ide, idemode, 0) || cfgfile_strval(option, value, _T("scsi"), &p->scsi, scsimode, 0) || cfgfile_strval(option, value, _T("comp_trustword"), &p->comptrustword, compmode, 0) || cfgfile_strval(option, value, _T("comp_trustlong"), &p->comptrustlong, compmode, 0) @@ -3245,34 +4888,184 @@ static int cfgfile_parse_hardware(struct uae_prefs *p, const TCHAR *option, TCHA || cfgfile_strval(option, value, _T("collision_level"), &p->collision_level, collmode, 0) || cfgfile_strval(option, value, _T("parallel_matrix_emulation"), &p->parallel_matrix_emulation, epsonprinter, 0) || cfgfile_strval(option, value, _T("monitoremu"), &p->monitoremu, specialmonitors, 0) + || cfgfile_strval(option, value, _T("genlockmode"), &p->genlock_image, genlockmodes, 0) || cfgfile_strval(option, value, _T("waiting_blits"), &p->waiting_blits, waitblits, 0) || cfgfile_strval(option, value, _T("floppy_auto_extended_adf"), &p->floppy_auto_ext2, autoext2, 0) + || cfgfile_strval(option, value, _T("z3mapping"), &p->z3_mapping_mode, z3mapping, 0) + || cfgfile_strval(option, value, _T("scsidev_mode"), &p->uaescsidevmode, uaescsidevmodes, 0) + || cfgfile_strval(option, value, _T("boot_rom_uae"), &p->boot_rom, uaebootrom, 0) + || cfgfile_strval(option, value, _T("uaeboard"), &p->uaeboard, uaeboard, 0) + || cfgfile_strval(option, value, _T("serial_translate"), &p->serial_crlf, serialcrlf, 0) || cfgfile_strboolval(option, value, _T("comp_flushmode"), &p->comp_hardflush, flushmode, 0)) return 1; if (cfgfile_path(option, value, _T("kickstart_rom_file"), p->romfile, sizeof p->romfile / sizeof(TCHAR), &p->path_rom) || cfgfile_path(option, value, _T("kickstart_ext_rom_file"), p->romextfile, sizeof p->romextfile / sizeof(TCHAR), &p->path_rom) || cfgfile_path(option, value, _T("kickstart_ext_rom_file2"), p->romextfile2, sizeof p->romextfile2 / sizeof(TCHAR), &p->path_rom) - || cfgfile_path(option, value, _T("a2091_rom_file"), p->a2091romfile, sizeof p->a2091romfile / sizeof(TCHAR), &p->path_rom) - || cfgfile_path(option, value, _T("a4091_rom_file"), p->a4091romfile, sizeof p->a4091romfile / sizeof(TCHAR), &p->path_rom) || cfgfile_rom(option, value, _T("kickstart_rom_file_id"), p->romfile, sizeof p->romfile / sizeof(TCHAR)) || cfgfile_rom(option, value, _T("kickstart_ext_rom_file_id"), p->romextfile, sizeof p->romextfile / sizeof(TCHAR)) - || cfgfile_rom(option, value, _T("a2091_rom_file_id"), p->a2091romfile, sizeof p->a2091romfile / sizeof(TCHAR)) - || cfgfile_rom(option, value, _T("a4091_rom_file_id"), p->a4091romfile, sizeof p->a4091romfile / sizeof(TCHAR)) - || cfgfile_path(option, value, _T("amax_rom_file"), p->amaxromfile, sizeof p->amaxromfile / sizeof(TCHAR)) || cfgfile_path(option, value, _T("flash_file"), p->flashfile, sizeof p->flashfile / sizeof(TCHAR), &p->path_rom) || cfgfile_path(option, value, _T("cart_file"), p->cartfile, sizeof p->cartfile / sizeof(TCHAR), &p->path_rom) || cfgfile_path(option, value, _T("rtc_file"), p->rtcfile, sizeof p->rtcfile / sizeof(TCHAR), &p->path_rom) + || cfgfile_path(option, value, _T("picassoiv_rom_file"), p->picassoivromfile, sizeof p->picassoivromfile / sizeof(TCHAR), &p->path_rom) + || cfgfile_string(option, value, _T("genlock_image"), p->genlock_image_file, sizeof p->genlock_image_file / sizeof(TCHAR)) + || cfgfile_string(option, value, _T("genlock_video"), p->genlock_video_file, sizeof p->genlock_video_file / sizeof(TCHAR)) || cfgfile_string(option, value, _T("pci_devices"), p->pci_devices, sizeof p->pci_devices / sizeof(TCHAR)) || cfgfile_string(option, value, _T("ghostscript_parameters"), p->ghostscript_parameters, sizeof p->ghostscript_parameters / sizeof(TCHAR))) return 1; + if (cfgfile_string(option, value, _T("uaeboard_options"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) { + TCHAR *s = cfgfile_option_get(value, _T("order")); + if (s) + p->uaeboard_order = _tstol(s); + return 1; + } + + if (cfgfile_readramboard(option, value, _T("fastmem"), &p->fastmem[0])) { + return 1; + } + if (cfgfile_readramboard(option, value, _T("z3mem"), &p->z3fastmem[0])) { + return 1; + } + + if (cfgfile_yesno(option, value, _T("pcmcia"), &p->cs_pcmcia)) { + if (p->cs_pcmcia) + addbcromtype(p, ROMTYPE_MB_PCMCIA, true, NULL, 0); + return 1; + } + if (cfgfile_strval(option, value, _T("ide"), &p->cs_ide, idemode, 0)) { + if (p->cs_ide) + addbcromtype(p, ROMTYPE_MB_IDE, true, NULL, 0); + return 1; + } + if (cfgfile_yesno(option, value, _T("scsi_a3000"), &dummybool)) { + if (dummybool) { + addbcromtype(p, ROMTYPE_SCSI_A3000, true, NULL, 0); + p->cs_mbdmac = 1; + } + return 1; + } + if (cfgfile_yesno(option, value, _T("scsi_a4000t"), &dummybool)) { + if (dummybool) { + addbcromtype(p, ROMTYPE_SCSI_A4000T, true, NULL, 0); + p->cs_mbdmac = 2; + } + return 1; + } + if (cfgfile_yesno(option, value, _T("cd32fmv"), &p->cs_cd32fmv)) { + if (p->cs_cd32fmv) { + addbcromtype(p, ROMTYPE_CD32CART, true, p->cartfile, 0); + } + return 1; + } + if (cfgfile_intval(option, value, _T("catweasel"), &p->catweasel, 1)) { + if (p->catweasel) { + addbcromtype(p, ROMTYPE_CATWEASEL, true, NULL, 0); + } + return 1; + } + if (cfgfile_yesno(option, value, _T("toccata"), &dummybool)) + { + if (dummybool) { + addbcromtype(p, ROMTYPE_TOCCATA, true, NULL, 0); + } + return 1; + } + if (cfgfile_yesno(option, value, _T("es1370_pci"), &dummybool)) + { + if (dummybool) { + addbcromtype(p, ROMTYPE_ES1370, true, NULL, 0); + } + return 1; + } + if (cfgfile_yesno(option, value, _T("fm801_pci"), &dummybool)) + { + if (dummybool) { + addbcromtype(p, ROMTYPE_FM801, true, NULL, 0); + } + return 1; + } + if (cfgfile_yesno(option, value, _T("toccata_mixer"), &dummybool)) + { + if (dummybool) { + addbcromtype(p, ROMTYPE_TOCCATA, true, NULL, 0); + } + return 1; + } + + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + struct rtgboardconfig *rbc = &p->rtgboards[i]; + TCHAR tmp[100]; + if (i > 0) + _stprintf(tmp, _T("gfxcard%d_size"), i + 1); + else + _tcscpy(tmp, _T("gfxcard_size")); + if (cfgfile_intval(option, value, tmp, &rbc->rtgmem_size, 0x100000)) + return 1; + if (i > 0) + _stprintf(tmp, _T("gfxcard%d_options"), i + 1); + else + _tcscpy(tmp, _T("gfxcard_options")); + if (!_tcsicmp(option, tmp)) { + TCHAR *s = cfgfile_option_get(value, _T("order")); + if (s) { + rbc->device_order = _tstol(s); + } + return 1; + } + if (i > 0) + _stprintf(tmp, _T("gfxcard%d_type"), i + 1); + else + _tcscpy(tmp, _T("gfxcard_type")); + if (cfgfile_string(option, value, tmp, tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) { + rbc->rtgmem_type = 0; + rbc->rtg_index = i; + int j = 0; + for (;;) { + const TCHAR *t = gfxboard_get_configname(j); + if (!t) { + break; + } + if (!_tcsicmp(t, tmpbuf)) { + rbc->rtgmem_type = j; + break; + } + j++; + } + return 1; + } + } + + if (cfgfile_string(option, value, _T("cpuboard_type"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) { + p->cpuboard_type = 0; + p->cpuboard_subtype = 0; + for (i = 0; cpuboards[i].name && !p->cpuboard_type; i++) { + const struct cpuboardtype *cbt = &cpuboards[i]; + if (cbt->subtypes) { + for (int j = 0; cbt->subtypes[j].name; j++) { + if (!_tcsicmp(cbt->subtypes[j].configname, tmpbuf)) { + p->cpuboard_type = i; + p->cpuboard_subtype = j; + } + } + } + } + return 1; + } + if (cfgfile_string(option, value, _T("cpuboard_settings"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) { + p->cpuboard_settings = 0; + const struct cpuboardsubtype *cbst = &cpuboards[p->cpuboard_type].subtypes[p->cpuboard_subtype]; + if (cbst->settings) { + p->cpuboard_settings = cfgfile_read_rom_settings(cbst->settings, tmpbuf, NULL); + } + return 1; + } + if (cfgfile_strval(option, value, _T("chipset_compatible"), &p->cs_compatible, cscompa, 0)) { built_in_chipset_prefs(p); return 1; } - if (cfgfile_strval(option, value, _T("cart_internal"), &p->cart_internal, cartsmode, 0)) { if (p->cart_internal) { struct romdata *rd = getromdatabyid(63); @@ -3289,19 +5082,15 @@ static int cfgfile_parse_hardware(struct uae_prefs *p, const TCHAR *option, TCHA decode_rom_ident(p->romextfile, sizeof p->romextfile / sizeof(TCHAR), p->romextident, ROMTYPE_ALL_EXT); return 1; } - if (cfgfile_string(option, value, _T("a2091_rom"), p->a2091romident, sizeof p->a2091romident / sizeof(TCHAR))) { - decode_rom_ident(p->a2091romident, sizeof p->a2091romident / sizeof(TCHAR), p->a2091romident, ROMTYPE_A2091BOOT); - return 1; - } - if (cfgfile_string(option, value, _T("a4091_rom"), p->a4091romident, sizeof p->a4091romident / sizeof(TCHAR))) { - decode_rom_ident(p->a4091romident, sizeof p->a4091romident / sizeof(TCHAR), p->a4091romident, ROMTYPE_A4091BOOT); - return 1; - } + if (cfgfile_string(option, value, _T("cart"), p->cartident, sizeof p->cartident / sizeof(TCHAR))) { decode_rom_ident(p->cartfile, sizeof p->cartfile / sizeof(TCHAR), p->cartident, ROMTYPE_ALL_CART); return 1; } + if (cfgfile_read_board_rom(p, option, value, &p->path_rom)) + return 1; + for (i = 0; i < 4; i++) { _stprintf(tmpbuf, _T("floppy%d"), i); if (cfgfile_path(option, value, tmpbuf, p->floppyslots[i].df, sizeof p->floppyslots[i].df / sizeof(TCHAR), &p->path_floppy)) @@ -3348,20 +5137,47 @@ static int cfgfile_parse_hardware(struct uae_prefs *p, const TCHAR *option, TCHA return 1; } + if (cfgfile_strval(option, value, _T("ppc_implementation"), &p->ppc_implementation, ppc_implementations, 0)) + return 1; + if (cfgfile_string(option, value, _T("ppc_model"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) { + p->ppc_mode = 0; + p->ppc_model[0] = 0; + if (!_tcsicmp(tmpbuf, _T("automatic"))) { + p->ppc_mode = 1; + } + else if (!_tcsicmp(tmpbuf, _T("manual"))) { + p->ppc_mode = 2; + } + else { + if (tmpbuf[0] && _tcslen(tmpbuf) < sizeof(p->ppc_model) / sizeof(TCHAR)) { + _tcscpy(p->ppc_model, tmpbuf); + p->ppc_mode = 2; + } + } + return 1; + } + if (cfgfile_strval(option, value, _T("ppc_cpu_idle"), &p->ppc_cpu_idle, ppc_cpu_idle, 0)) + return 1; + /* old-style CPU configuration */ if (cfgfile_string(option, value, _T("cpu_type"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) { + // 68000/010 32-bit addressing was not available until 2.8.2 + bool force24bit = p->config_version <= ((2 << 16) | (8 << 8) | (1 << 0)); p->fpu_model = 0; p->address_space_24 = 0; p->cpu_model = 680000; if (!_tcscmp(tmpbuf, _T("68000"))) { p->cpu_model = 68000; + if (force24bit) + p->address_space_24 = 1; } else if (!_tcscmp(tmpbuf, _T("68010"))) { p->cpu_model = 68010; + if (force24bit) + p->address_space_24 = 1; } else if (!_tcscmp(tmpbuf, _T("68ec020"))) { p->cpu_model = 68020; - p->address_space_24 = 1; } else if (!_tcscmp(tmpbuf, _T("68020"))) { p->cpu_model = 68020; @@ -3403,6 +5219,9 @@ static int cfgfile_parse_hardware(struct uae_prefs *p, const TCHAR *option, TCHA if (cfgfile_doubleval(option, value, _T("cpu_throttle"), &p->m68k_speed_throttle)) { return 1; } + if (cfgfile_doubleval(option, value, _T("cpu_x86_throttle"), &p->x86_speed_throttle)) { + return 1; + } if (cfgfile_intval(option, value, _T("finegrain_cpu_speed"), &p->m68k_speed, 1)) { if (OFFICIAL_CYCLE_UNIT > CYCLE_UNIT) { int factor = OFFICIAL_CYCLE_UNIT / CYCLE_UNIT; @@ -3442,8 +5261,181 @@ static int cfgfile_parse_hardware(struct uae_prefs *p, const TCHAR *option, TCHA return 0; } +static void romtype_restricted(struct uae_prefs *p, const int *list) +{ + for (int i = 0; list[i]; i++) { + int romtype = list[i]; + if (is_board_enabled(p, romtype, 0)) { + i++; + while (list[i]) { + romtype = list[i]; + if (is_board_enabled(p, romtype, 0)) { + write_log(_T("ROMTYPE %08x removed\n"), romtype); + addbcromtype(p, romtype, false, NULL, 0); + } + i++; + return; + } + } + } +} + +void cfgfile_compatibility_rtg(struct uae_prefs *p) +{ + int uaegfx = -1; + // only one uaegfx + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + struct rtgboardconfig *rbc = &p->rtgboards[i]; + if (rbc->rtgmem_size && rbc->rtgmem_type < GFXBOARD_HARDWARE) { + if (uaegfx >= 0) { + rbc->rtgmem_size = 0; + rbc->rtgmem_type = 0; + } + else { + uaegfx = i; + } + } + } + // uaegfx must be first + if (uaegfx > 0) { + struct rtgboardconfig *rbc = &p->rtgboards[uaegfx]; + struct rtgboardconfig *rbc2 = &p->rtgboards[0]; + int size = rbc->rtgmem_size; + int type = rbc->rtgmem_type; + rbc->rtgmem_size = rbc2->rtgmem_size; + rbc->rtgmem_type = rbc2->rtgmem_type; + rbc2->rtgmem_size = size; + rbc2->rtgmem_type = type; + } + // allow only one a2410 and vga + int a2410 = -1; + int vga = -1; + //for (int i = 0; i < MAX_RTG_BOARDS; i++) { + // struct rtgboardconfig *rbc = &p->rtgboards[i]; + // if (rbc->rtgmem_type == GFXBOARD_A2410) { + // if (a2410 >= 0) { + // rbc->rtgmem_size = 0; + // rbc->rtgmem_type = 0; + // } + // else { + // a2410 = i; + // } + // } + // if (rbc->rtgmem_type == GFXBOARD_VGA) { + // if (vga >= 0) { + // rbc->rtgmem_size = 0; + // rbc->rtgmem_type = 0; + // } + // else { + // vga = i; + // } + // } + //} + // empty slots last + bool reorder = true; + while (reorder) { + reorder = false; + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + struct rtgboardconfig *rbc = &p->rtgboards[i]; + if (i > 0 && rbc->rtgmem_size && p->rtgboards[i - 1].rtgmem_size == 0) { + struct rtgboardconfig *rbc2 = &p->rtgboards[i - 1]; + rbc2->rtgmem_size = rbc->rtgmem_size; + rbc2->rtgmem_type = rbc->rtgmem_type; + rbc2->device_order = rbc->device_order; + rbc->rtgmem_size = 0; + rbc->rtgmem_type = 0; + rbc->device_order = 0; + reorder = true; + break; + } + } + } + int rtgs[MAX_RTG_BOARDS] = { 0 }; + //for (int i = 0; i < MAX_RTG_BOARDS; i++) { + // if (p->rtgboards[i].rtgmem_size && !rtgs[i]) { + // uae_u32 romtype = gfxboard_get_romtype(&p->rtgboards[i]); + // if (romtype) { + // int devnum = 0; + // for (int j = i; j < MAX_RTG_BOARDS; j++) { + // rtgs[j] = 1; + // if (gfxboard_get_romtype(&p->rtgboards[j]) == romtype) { + // TCHAR *romname = NULL; + // if (romtype == ROMTYPE_PICASSOIV) { + // romname = p->picassoivromfile; + // } + // else if (romtype == ROMTYPE_x86_VGA) { + // romname = _T(""); + // } + // addbcromtype(p, romtype, true, romname, devnum); + // devnum++; + // } + // } + // while (devnum < MAX_DUPLICATE_EXPANSION_BOARDS) { + // addbcromtype(p, romtype, false, NULL, devnum); + // devnum++; + // } + // } + // } + //} + //for (int i = 0; i < MAX_RTG_BOARDS; i++) { + // if (!rtgs[i]) { + // uae_u32 romtype = gfxboard_get_romtype(&p->rtgboards[i]); + // if (romtype) { + // for (int devnum = 0; devnum < MAX_DUPLICATE_EXPANSION_BOARDS; devnum++) { + // addbcromtype(p, romtype, false, NULL, devnum); + // } + // } + // } + //} +} + +void cfgfile_compatibility_romtype(struct uae_prefs *p) +{ + addbcromtype(p, ROMTYPE_MB_PCMCIA, p->cs_pcmcia, NULL, 0); + + addbcromtype(p, ROMTYPE_MB_IDE, p->cs_ide != 0, NULL, 0); + + if (p->cs_mbdmac == 1) { + addbcromtype(p, ROMTYPE_SCSI_A4000T, false, NULL, 0); + addbcromtype(p, ROMTYPE_SCSI_A3000, true, NULL, 0); + } + else if (p->cs_mbdmac == 2) { + addbcromtype(p, ROMTYPE_SCSI_A3000, false, NULL, 0); + addbcromtype(p, ROMTYPE_SCSI_A4000T, true, NULL, 0); + } + else { + addbcromtype(p, ROMTYPE_SCSI_A3000, false, NULL, 0); + addbcromtype(p, ROMTYPE_SCSI_A4000T, false, NULL, 0); + } + + addbcromtype(p, ROMTYPE_CDTVDMAC, p->cs_cdtvcd && !p->cs_cdtvcr, NULL, 0); + addbcromtype(p, ROMTYPE_CDTVSCSI, p->cs_cdtvscsi, NULL, 0); + + addbcromtype(p, ROMTYPE_CDTVCR, p->cs_cdtvcr, NULL, 0); + + addbcromtype(p, ROMTYPE_CD32CART, p->cs_cd32fmv, p->cartfile, 0); + + if (p->config_version < ((3 << 16) | (4 << 8) | (0 << 0))) { + // 3.3.0 or older + addbcromtypenet(p, ROMTYPE_A2065, p->a2065name, 0); + addbcromtypenet(p, ROMTYPE_NE2KPCMCIA, p->ne2000pcmcianame, 0); + addbcromtypenet(p, ROMTYPE_NE2KPCI, p->ne2000pciname, 0); + } + + static const int restricted_net[] = { + ROMTYPE_A2065, ROMTYPE_NE2KPCMCIA, ROMTYPE_NE2KPCI, ROMTYPE_NE2KISA, + ROMTYPE_ARIADNE2, ROMTYPE_XSURF, ROMTYPE_XSURF100Z2, ROMTYPE_XSURF100Z3, + ROMTYPE_HYDRA, ROMTYPE_LANROVER, + 0 }; + static const int restricted_x86[] = { ROMTYPE_A1060, ROMTYPE_A2088, ROMTYPE_A2088T, ROMTYPE_A2286, ROMTYPE_A2386, 0 }; + static const int restricted_pci[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, 0 }; + romtype_restricted(p, restricted_net); + romtype_restricted(p, restricted_x86); + romtype_restricted(p, restricted_pci); +} + static bool createconfigstore(struct uae_prefs*); -static int getconfigstoreline(const TCHAR* option, TCHAR* value); +static int getconfigstoreline(const TCHAR *option, TCHAR *value); static void calcformula(struct uae_prefs *prefs, TCHAR *in) { @@ -3504,7 +5496,7 @@ static void calcformula(struct uae_prefs *prefs, TCHAR *in) } } -int cfgfile_parse_option(struct uae_prefs *p, TCHAR *option, TCHAR *value, int type) +int cfgfile_parse_option(struct uae_prefs *p, const TCHAR *option, TCHAR *value, int type) { calcformula(p, value); @@ -3516,6 +5508,8 @@ int cfgfile_parse_option(struct uae_prefs *p, TCHAR *option, TCHAR *value, int t return 1; if (!_tcscmp(option, _T("config_host"))) return 1; + if (cfgfile_path(option, value, _T("config_all_path"), p->config_all_path, sizeof p->config_all_path / sizeof(TCHAR))) + return 1; if (cfgfile_path(option, value, _T("config_hardware_path"), p->config_hardware_path, sizeof p->config_hardware_path / sizeof(TCHAR))) return 1; if (cfgfile_path(option, value, _T("config_host_path"), p->config_host_path, sizeof p->config_host_path / sizeof(TCHAR))) @@ -3525,8 +5519,13 @@ int cfgfile_parse_option(struct uae_prefs *p, TCHAR *option, TCHAR *value, int t return 1; } if (type == 0 || (type & CONFIG_TYPE_HOST)) { - if (cfgfile_parse_host(p, option, value)) + // cfgfile_parse_host may modify the option (convert to lowercase). + TCHAR* writable_option = my_strdup(option); + if (cfgfile_parse_host(p, writable_option, value)) { + free(writable_option); return 1; + } + free(writable_option); } if (type > 0 && (type & (CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST)) != (CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST)) return 1; @@ -3554,7 +5553,7 @@ static int cfgfile_separate_linea(const TCHAR *filename, char *line, TCHAR *line line2 = strchr(line, '='); if (!line2) { TCHAR *s = au(line1); - write_log(_T("CFGFILE: '%s', linea was incomplete with only %s\n"), filename, s); + cfgfile_warning(_T("CFGFILE: '%s', linea was incomplete with only %s\n"), filename, s); xfree(s); return 0; } @@ -3597,7 +5596,7 @@ static int cfgfile_separate_line(TCHAR *line, TCHAR *line1b, TCHAR *line2b) return 0; line2 = _tcschr(line, '='); if (!line2) { - write_log(_T("CFGFILE: line was incomplete with only %s\n"), line1); + cfgfile_warning(_T("CFGFILE: line was incomplete with only %s\n"), line1); return 0; } *line2++ = '\0'; @@ -3635,7 +5634,7 @@ static int isobsolete(TCHAR *s) int i = 0; while (obsolete[i]) { if (!strcasecmp(s, obsolete[i])) { - write_log(_T("obsolete config entry '%s'\n"), s); + cfgfile_warning_obsolete(_T("obsolete config entry '%s'\n"), s); return 1; } i++; @@ -3643,11 +5642,11 @@ static int isobsolete(TCHAR *s) if (_tcslen(s) > 2 && !_tcsncmp(s, _T("w."), 2)) return 1; if (_tcslen(s) >= 10 && !_tcsncmp(s, _T("gfx_opengl"), 10)) { - write_log(_T("obsolete config entry '%s\n"), s); + cfgfile_warning_obsolete(_T("obsolete config entry '%s\n"), s); return 1; } if (_tcslen(s) >= 6 && !_tcsncmp(s, _T("gfx_3d"), 6)) { - write_log(_T("obsolete config entry '%s\n"), s); + cfgfile_warning_obsolete(_T("obsolete config entry '%s\n"), s); return 1; } return 0; @@ -3674,7 +5673,7 @@ static void cfgfile_parse_separated_line(struct uae_prefs *p, TCHAR *line1b, TCH p->all_lines = u; if (!ret) { u->unknown = 1; - write_log(_T("unknown config entry: '%s=%s'\n"), u->option, u->value); + cfgfile_warning(_T("unknown config entry: '%s=%s'\n"), u->option, u->value); } } } @@ -3709,6 +5708,8 @@ void cfgfile_parse_line(struct uae_prefs *p, TCHAR *line, int type) static void subst(TCHAR *p, TCHAR *f, int n) { + if (_tcslen(p) == 0 || _tcslen(f) == 0) + return; TCHAR *str = cfgfile_subst_path(UNEXPANDED, p, f); _tcsncpy(f, str, n - 1); f[n - 1] = '\0'; @@ -3718,7 +5719,6 @@ static void subst(TCHAR *p, TCHAR *f, int n) static int getconfigstoreline(const TCHAR *option, TCHAR *value) { TCHAR tmp[CONFIG_BLEN * 2], tmp2[CONFIG_BLEN * 2]; - int idx = 0; if (!configstore) return 0; @@ -3802,7 +5802,6 @@ static int cfgfile_load_2(struct uae_prefs *p, const TCHAR *filename, bool real, if (real) { p->config_version = 0; config_newfilesystem = 0; - store_inputdevice_config(p); //reset_inputdevice_config (p); } @@ -3844,6 +5843,7 @@ static int cfgfile_load_2(struct uae_prefs *p, const TCHAR *filename, bool real, cfgfile_string(line1b, line2b, _T("config_description"), p->description, sizeof p->description / sizeof(TCHAR)); cfgfile_path(line1b, line2b, _T("config_hardware_path"), p->config_hardware_path, sizeof p->config_hardware_path / sizeof(TCHAR)); cfgfile_path(line1b, line2b, _T("config_host_path"), p->config_host_path, sizeof p->config_host_path / sizeof(TCHAR)); + cfgfile_path(line1b, line2b, _T("config_all_path"), p->config_all_path, sizeof p->config_all_path / sizeof(TCHAR)); cfgfile_string(line1b, line2b, _T("config_window_title"), p->config_window_title, sizeof p->config_window_title / sizeof(TCHAR)); } } @@ -3866,8 +5866,12 @@ static int cfgfile_load_2(struct uae_prefs *p, const TCHAR *filename, bool real, subst(p->path_rom.path[0], p->romfile, sizeof p->romfile / sizeof(TCHAR)); subst(p->path_rom.path[0], p->romextfile, sizeof p->romextfile / sizeof(TCHAR)); subst(p->path_rom.path[0], p->romextfile2, sizeof p->romextfile2 / sizeof(TCHAR)); - subst(p->path_rom.path[0], p->a2091romfile, sizeof p->a2091romfile / sizeof(TCHAR)); - subst(p->path_rom.path[0], p->a4091romfile, sizeof p->a4091romfile / sizeof(TCHAR)); + + for (i = 0; i < MAX_EXPANSION_BOARDS; i++) { + for (int j = 0; j < MAX_BOARD_ROMS; j++) { + subst(p->path_rom.path[0], p->expansionboard[i].roms[j].romfile, MAX_DPATH / sizeof(TCHAR)); + } + } return 1; } @@ -3885,28 +5889,34 @@ int cfgfile_load(struct uae_prefs *p, const TCHAR *filename, int *type, int igno write_log(_T("load config '%s':%d\n"), filename, type ? *type : -1); v = cfgfile_load_2(p, filename, 1, type); if (!v) { - write_log(_T("load failed\n")); + cfgfile_warning(_T("cfgfile_load_2 failed\n")); goto end; } //if (userconfig) // target_addtorecent(filename, 0); if (!ignorelink) { + if (p->config_all_path[0]) { + fetch_configurationpath(tmp, sizeof(tmp) / sizeof(TCHAR)); + _tcsncat(tmp, p->config_all_path, sizeof(tmp) / sizeof(TCHAR) - _tcslen(tmp) - 1); + type2 = CONFIG_TYPE_HOST | CONFIG_TYPE_HARDWARE; + cfgfile_load(p, tmp, &type2, 1, 0); + } if (p->config_hardware_path[0]) { fetch_configurationpath(tmp, sizeof(tmp) / sizeof(TCHAR)); - _tcsncat(tmp, p->config_hardware_path, sizeof(tmp) / sizeof(TCHAR)); + _tcsncat(tmp, p->config_hardware_path, sizeof(tmp) / sizeof(TCHAR) - _tcslen(tmp) - 1); type2 = CONFIG_TYPE_HARDWARE; cfgfile_load(p, tmp, &type2, 1, 0); } if (p->config_host_path[0]) { fetch_configurationpath(tmp, sizeof(tmp) / sizeof(TCHAR)); - _tcsncat(tmp, p->config_host_path, sizeof(tmp) / sizeof(TCHAR)); + _tcsncat(tmp, p->config_host_path, sizeof(tmp) / sizeof(TCHAR) - _tcslen(tmp) - 1); type2 = CONFIG_TYPE_HOST; cfgfile_load(p, tmp, &type2, 1, 0); } } end: recursive--; - fixup_prefs(p); + fixup_prefs(p, userconfig != 0); return v; } @@ -4262,15 +6272,15 @@ int parse_cmdline_option(struct uae_prefs *p, TCHAR c, const TCHAR *arg) break; case 'Z': - p->z3fastmem_size = _tstoi(arg) * 0x100000; + p->z3fastmem[0].size = _tstoi(arg) * 0x100000; break; case 'U': - p->rtgmem_size = _tstoi(arg) * 0x100000; + p->rtgboards[0].rtgmem_size = _tstoi(arg) * 0x100000; break; case 'F': - p->fastmem_size = _tstoi(arg) * 0x100000; + p->fastmem[0].size = _tstoi(arg) * 0x100000; break; case 'b': @@ -4281,6 +6291,23 @@ int parse_cmdline_option(struct uae_prefs *p, TCHAR c, const TCHAR *arg) p->chipmem_size = _tstoi(arg) * 0x80000; break; + //case 'l': + // if (0 == strcasecmp(arg, _T("de"))) + // p->keyboard_lang = KBD_LANG_DE; + // else if (0 == strcasecmp(arg, _T("dk"))) + // p->keyboard_lang = KBD_LANG_DK; + // else if (0 == strcasecmp(arg, _T("us"))) + // p->keyboard_lang = KBD_LANG_US; + // else if (0 == strcasecmp(arg, _T("se"))) + // p->keyboard_lang = KBD_LANG_SE; + // else if (0 == strcasecmp(arg, _T("fr"))) + // p->keyboard_lang = KBD_LANG_FR; + // else if (0 == strcasecmp(arg, _T("it"))) + // p->keyboard_lang = KBD_LANG_IT; + // else if (0 == strcasecmp(arg, _T("es"))) + // p->keyboard_lang = KBD_LANG_ES; + // break; + case 'O': parse_gfx_specs(p, arg); break; case 'd': if (_tcschr(arg, 'S') != NULL || _tcschr(arg, 's')) { @@ -4470,7 +6497,7 @@ end: return err; } -uae_u32 cfgfile_modify(uae_u32 index, TCHAR *parms, uae_u32 size, TCHAR *out, uae_u32 outsize) +uae_u32 cfgfile_modify(uae_u32 index, const TCHAR *parms, uae_u32 size, TCHAR *out, uae_u32 outsize) { TCHAR *p; TCHAR *argc[UAELIB_MAX_PARSE]; @@ -4552,7 +6579,7 @@ end: return err; } -uae_u32 cfgfile_uaelib_modify(uae_u32 index, uae_u32 parms, uae_u32 size, uae_u32 out, uae_u32 outsize) +uae_u32 cfgfile_uaelib_modify(TrapContext *ctx, uae_u32 index, uae_u32 parms, uae_u32 size, uae_u32 out, uae_u32 outsize) { uae_char *p, *parms_p = NULL, *parms_out = NULL; int i, ret; @@ -4589,13 +6616,15 @@ uae_u32 cfgfile_uaelib_modify(uae_u32 index, uae_u32 parms, uae_u32 size, uae_u3 xfree(parms_in); if (out) { parms_out = ua(out_p); - p = parms_out; - for (i = 0; i < outsize - 1; i++) { - uae_u8 b = *p++; - put_byte(out + i, b); - put_byte(out + i + 1, 0); - if (!b) + int len = 0; + uae_u8 *haddr = (uae_u8*)parms_out; + for (;;) { + uae_u8 v = *haddr++; + put_byte(out, v); + out++; + if (!v) break; + len++; } } xfree(parms_out); @@ -4605,7 +6634,7 @@ end: return ret; } -const TCHAR *cfgfile_read_config_value(const TCHAR *option) +static const TCHAR *cfgfile_read_config_value(const TCHAR *option) { struct strlist *sl; for (sl = currprefs.all_lines; sl; sl = sl->next) { @@ -4615,30 +6644,46 @@ const TCHAR *cfgfile_read_config_value(const TCHAR *option) return NULL; } -uae_u32 cfgfile_uaelib(int mode, uae_u32 name, uae_u32 dst, uae_u32 maxlen) +uae_u32 cfgfile_uaelib(TrapContext *ctx, int mode, uae_u32 name, uae_u32 dst, uae_u32 maxlen) { - TCHAR tmp[CONFIG_BLEN]; - int i; + TCHAR *str; + uae_char tmpa[CONFIG_BLEN]; if (mode) return 0; - for (i = 0; i < sizeof(tmp) / sizeof(TCHAR); i++) { - tmp[i] = get_byte(name + i); - if (tmp[i] == 0) + int len = 0; + uae_u8 *haddr = (uae_u8*)tmpa; + for (;;) { + uae_u8 v = *haddr++; + put_byte(name, v); + name++; + if (!v) break; + len++; } - tmp[sizeof(tmp) / sizeof(TCHAR) - 1] = 0; - if (tmp[0] == 0) + + str = au(tmpa); + if (str[0] == 0) { + xfree(str); return 0; - const TCHAR *value = cfgfile_read_config_value(tmp); + } + const TCHAR *value = cfgfile_read_config_value(str); + xfree(str); if (value) { char *s = ua(value); - for (i = 0; i < maxlen; i++) { - put_byte(dst + i, s[i]); - if (s[i] == 0) + + len = 0; + haddr = (uae_u8*)s; + for (;;) { + uae_u8 v = *haddr++; + put_byte(dst, v); + dst++; + if (!v) break; + len++; } + xfree(s); return dst; } @@ -4674,10 +6719,10 @@ uae_u8 *save_configuration(int *len, bool fullconfig) continue; //write_log (_T("'%s'\n"), tmpout); out = uutf8(tmpout); - strcpy(reinterpret_cast(p), out); + strcpy((char*)p, out); xfree(out); - strcat(reinterpret_cast(p), "\n"); - p += strlen(reinterpret_cast(p)); + strcat((char*)p, "\n"); + p += strlen((char*)p); if (p - dstbak >= tmpsize - sizeof(tmpout)) break; } @@ -4688,6 +6733,7 @@ uae_u8 *save_configuration(int *len, bool fullconfig) return dstbak; } +#ifdef UAE_MINI static void default_prefs_mini(struct uae_prefs *p, int type) { _tcscpy(p->description, _T("UAE default A500 configuration")); @@ -4700,17 +6746,20 @@ static void default_prefs_mini(struct uae_prefs *p, int type) p->chipmem_size = 0x00080000; p->bogomem_size = 0x00080000; } +#endif #include "sounddep/sound.h" -void default_prefs(struct uae_prefs *p, int type) +void default_prefs(struct uae_prefs *p, bool reset, int type) { int i; int roms[] = { 6, 7, 8, 9, 10, 14, 5, 4, 3, 2, 1, -1 }; TCHAR zero = 0; struct zfile *f; + //reset_inputdevice_config(p, reset); //TODO reset_inputdevice_config(p); + memset(p, 0, sizeof(*p)); _tcscpy(p->description, _T("UAE default configuration")); p->config_hardware_path[0] = 0; @@ -4737,7 +6786,7 @@ void default_prefs(struct uae_prefs *p, int type) p->ghostscript_parameters[0] = 0; p->uae_hide = 0; p->uae_hide_autoconfig = false; - p->jit_direct_compatible_memory = true; + p->z3_mapping_mode = Z3MAPPING_AUTO; p->mountitems = 0; for (i = 0; i < MOUNT_CONFIG_SIZE; i++) { @@ -4745,14 +6794,16 @@ void default_prefs(struct uae_prefs *p, int type) p->mountconfig[i].unitnum = -1; } - memset(&p->jports[0], 0, sizeof(struct jport)); - memset(&p->jports[1], 0, sizeof(struct jport)); - memset(&p->jports[2], 0, sizeof(struct jport)); - memset(&p->jports[3], 0, sizeof(struct jport)); - p->jports[0].id = JSEM_MICE; - p->jports[1].id = JSEM_KBDLAYOUT; + p->jports[0].id = -1; + p->jports[1].id = -1; p->jports[2].id = -1; p->jports[3].id = -1; + //if (reset) { + // inputdevice_joyport_config_store(p, _T("mouse"), 0, -1, 0); + // inputdevice_joyport_config_store(p, _T("kbd1"), 1, -1, 0); + //} + + p->keyboard_connected = true; p->produce_sound = 3; p->sound_stereo = SND_STEREO; @@ -4763,7 +6814,8 @@ void default_prefs(struct uae_prefs *p, int type) p->sound_interpol = 1; p->sound_filter = FILTER_SOUND_EMUL; p->sound_filter_type = 0; - p->sound_auto = 1; + p->sound_auto = true; + p->sound_cdaudio = false; p->sampler_stereo = false; p->sampler_buffer = 0; p->sampler_freq = 0; @@ -4775,22 +6827,12 @@ void default_prefs(struct uae_prefs *p, int type) p->compnf = 1; p->comp_hardflush = 0; p->comp_constjump = 1; - p->comp_oldsegv = 0; +#ifdef USE_JIT_FPU p->compfpu = 1; - p->fpu_strict = 0; +#else + p->compfpu = 0; +#endif p->cachesize = DEFAULT_JIT_CACHE_SIZE; - p->avoid_cmov = 0; - p->comp_midopt = 0; - p->comp_lowopt = 0; - - for (i = 0; i < 10; i++) - p->optcount[i] = -1; - p->optcount[0] = 4; /* How often a block has to be executed before it is translated */ - p->optcount[1] = 0; /* How often to use the naive translation */ - p->optcount[2] = 0; - p->optcount[3] = 0; - p->optcount[4] = 0; - p->optcount[5] = 0; p->gfx_framerate = 1; p->gfx_autoframerate = 50; @@ -4805,7 +6847,13 @@ void default_prefs(struct uae_prefs *p, int type) p->gfx_size_win_xtra[i].height = 0; } p->gfx_resolution = RES_HIRES; +#ifndef AMIBERRY p->gfx_vresolution = VRES_DOUBLE; + p->gfx_iscanlines = 1; +#else + p->gfx_vresolution = VRES_NONDOUBLE; + p->gfx_iscanlines = 0; +#endif p->gfx_apmode[0].gfx_fullscreen = GFX_WINDOW; p->gfx_apmode[1].gfx_fullscreen = GFX_WINDOW; p->gfx_xcenter = 0; p->gfx_ycenter = 0; @@ -4823,7 +6871,7 @@ void default_prefs(struct uae_prefs *p, int type) p->gfx_apmode[0].gfx_backbuffers = 2; p->gfx_apmode[1].gfx_backbuffers = 1; - p->immediate_blits = 0; + p->immediate_blits = false; p->waiting_blits = 0; p->collision_level = 2; p->leds_on_screen = 0; @@ -4831,22 +6879,24 @@ void default_prefs(struct uae_prefs *p, int type) p->keyboard_leds_in_use = 0; p->keyboard_leds[0] = p->keyboard_leds[1] = p->keyboard_leds[2] = 0; p->scsi = 0; - p->uaeserial = 0; + p->uaeserial = false; p->cpu_idle = 0; p->turbo_emulation = 0; + p->turbo_emulation_limit = 0; p->headless = 0; p->catweasel = 0; p->tod_hack = 0; p->maprom = 0; + p->boot_rom = 0; p->filesys_no_uaefsdb = 0; p->filesys_custom_uaefsdb = 1; p->picasso96_nocustom = 1; p->cart_internal = 1; - p->sana2 = 0; + p->sana2 = false; p->clipboard_sharing = false; p->native_code = false; - p->cs_compatible = 1; + p->cs_compatible = CP_GENERIC; p->cs_rtc = 2; p->cs_df0idhw = 1; p->cs_a1000ram = 0; @@ -4855,9 +6905,8 @@ void default_prefs(struct uae_prefs *p, int type) p->cs_agnusrev = -1; p->cs_deniserev = -1; p->cs_mbdmac = 0; - p->a2091 = 0; - p->a4091 = 0; - p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = false; + p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = p->cs_cd32fmv = false; + p->cs_cd32nvram_size = 1024; p->cs_cdtvcd = p->cs_cdtvram = false; p->cs_cdtvcard = 0; p->cs_pcmcia = 0; @@ -4869,6 +6918,7 @@ void default_prefs(struct uae_prefs *p, int type) p->cs_slowmemisfast = 0; p->cs_resetwarning = 1; p->cs_ciatodbug = false; + p->cs_color_burst = false; for (int i = APMODE_NATIVE; i <= APMODE_RTG; i++) { struct gfx_filterdata *f = &p->gf[i]; @@ -4915,6 +6965,8 @@ void default_prefs(struct uae_prefs *p, int type) p->prtname[0] = 0; p->sername[0] = 0; + p->cpu_thread = false; + p->fpu_model = 0; p->cpu_model = 68000; p->m68k_speed_throttle = 0; @@ -4925,34 +6977,39 @@ void default_prefs(struct uae_prefs *p, int type) p->fpu_revision = 0; p->fpu_no_unimplemented = false; p->int_no_unimplemented = false; + p->fpu_strict = false; + p->fpu_softfloat = false; p->m68k_speed = 0; - p->cpu_compatible = 1; - p->address_space_24 = 1; - p->cpu_cycle_exact = 0; - p->blitter_cycle_exact = 0; +#ifndef AMIBERRY + p->cpu_compatible = true; +#else + p->cpu_compatible = false; +#endif + p->address_space_24 = true; + p->cpu_cycle_exact = false; + p->cpu_memory_cycle_exact = false; + p->blitter_cycle_exact = false; p->chipset_mask = CSMASK_ECS_AGNUS; - p->genlock = 0; + p->genlock = false; + p->genlock_image = 0; + p->genlock_mix = 0; p->ntscmode = 0; p->filesys_limit = 0; p->filesys_max_name = 107; p->filesys_max_file_size = 0x7fffffff; - p->fastmem_size = 0x00000000; - p->fastmem2_size = 0x00000000; - p->mbresmem_low_size = 0x00000000; - p->mbresmem_high_size = 0x00000000; - p->z3fastmem_size = 0x00000000; - p->z3fastmem2_size = 0x00000000; - p->z3fastmem_start = 0x10000000; + p->z3autoconfig_start = 0x10000000; p->chipmem_size = 0x00080000; p->bogomem_size = 0x00080000; - p->rtgmem_size = 0x00000000; - p->rtgmem_type = GFXBOARD_UAE_Z3; + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + p->rtgboards[i].rtg_index = i; + } + p->rtgboards[0].rtgmem_size = 0x00000000; + p->rtgboards[0].rtgmem_type = GFXBOARD_UAE_Z3; p->custom_memory_addrs[0] = 0; p->custom_memory_sizes[0] = 0; p->custom_memory_addrs[1] = 0; p->custom_memory_sizes[1] = 0; - p->fastmem_autoconfig = true; p->nr_floppies = 2; p->floppy_read_only = false; @@ -4964,8 +7021,16 @@ void default_prefs(struct uae_prefs *p, int type) p->floppy_write_length = 0; p->floppy_random_bits_min = 1; p->floppy_random_bits_max = 3; - p->dfxclickvolume = 33; + p->dfxclickvolume_disk[0] = 33; + p->dfxclickvolume_disk[1] = 33; + p->dfxclickvolume_disk[2] = 33; + p->dfxclickvolume_disk[3] = 33; + p->dfxclickvolume_empty[0] = 33; + p->dfxclickvolume_empty[1] = 33; + p->dfxclickvolume_empty[2] = 33; + p->dfxclickvolume_empty[3] = 33; p->dfxclickchannelmask = 0xffff; + p->cd_speed = 100; p->statecapturebuffersize = 100; p->statecapturerate = 5 * 50; @@ -4977,7 +7042,7 @@ void default_prefs(struct uae_prefs *p, int type) p->input_tablet = TABLET_OFF; p->tablet_library = false; - p->input_magic_mouse = 0; + p->input_mouse_untrap = MOUSEUNTRAP_NONE; p->input_magic_mouse_cursor = 0; inputdevice_default_prefs(p); @@ -5001,6 +7066,7 @@ void default_prefs(struct uae_prefs *p, int type) cr->rate = 50.0; cr->ntsc = 0; cr->locked = false; + cr->inuse = true; _tcscpy(cr->label, _T("PAL")); cr = &p->cr[CHIPSET_REFRESH_NTSC]; cr->index = CHIPSET_REFRESH_NTSC; @@ -5012,8 +7078,14 @@ void default_prefs(struct uae_prefs *p, int type) cr->rate = 60.0; cr->ntsc = 1; cr->locked = false; + cr->inuse = true; _tcscpy(cr->label, _T("NTSC")); + p->lightboost_strobo = false; + p->lightboost_strobo_ratio = 50; + + savestate_state = 0; + target_default_options(p, type); zfile_fclose(default_file); @@ -5064,8 +7136,9 @@ static void buildin_default_prefs(struct uae_prefs *p) p->m68k_speed = 0; p->cpu_compatible = 1; p->address_space_24 = 1; - p->cpu_cycle_exact = 0; - p->blitter_cycle_exact = 0; + p->cpu_cycle_exact = false; + p->cpu_memory_cycle_exact = false; + p->blitter_cycle_exact = false; p->chipset_mask = CSMASK_ECS_AGNUS; p->immediate_blits = 0; p->waiting_blits = 0; @@ -5076,25 +7149,32 @@ static void buildin_default_prefs(struct uae_prefs *p) p->uaeserial = 0; p->cpu_idle = 0; p->turbo_emulation = 0; + p->turbo_emulation_limit = 0; p->catweasel = 0; p->tod_hack = 0; p->maprom = 0; p->cachesize = 0; p->socket_emu = 0; - p->sound_volume = 0; - p->sound_volume_cd = 0; p->clipboard_sharing = false; + p->ppc_mode = 0; + p->ppc_model[0] = 0; + p->cpuboard_type = 0; + p->cpuboard_subtype = 0; p->chipmem_size = 0x00080000; p->bogomem_size = 0x00080000; - p->fastmem_size = 0x00000000; - p->mbresmem_low_size = 0x00000000; - p->mbresmem_high_size = 0x00000000; - p->z3fastmem_size = 0x00000000; - p->z3fastmem2_size = 0x00000000; - p->z3chipmem_size = 0x00000000; - p->rtgmem_size = 0x00000000; - p->rtgmem_type = GFXBOARD_UAE_Z3; + p->z3chipmem_size = 0; + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + memset(p->fastmem, 0, sizeof(struct ramboard)); + memset(p->z3fastmem, 0, sizeof(struct ramboard)); + } + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + p->rtgboards[i].rtgmem_size = 0x00000000; + p->rtgboards[i].rtgmem_type = GFXBOARD_UAE_Z3; + } + for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) { + memset(&p->expansionboard[i], 0, sizeof(struct boardromconfig)); + } p->cs_rtc = 0; p->cs_a1000ram = false; @@ -5103,9 +7183,7 @@ static void buildin_default_prefs(struct uae_prefs *p) p->cs_agnusrev = -1; p->cs_deniserev = -1; p->cs_mbdmac = 0; - p->a2091 = false; - p->a4091 = false; - p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = false; + p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = p->cs_cd32fmv = false; p->cs_cdtvcd = p->cs_cdtvram = p->cs_cdtvcard = false; p->cs_ide = 0; p->cs_pcmcia = 0; @@ -5116,21 +7194,22 @@ static void buildin_default_prefs(struct uae_prefs *p) p->cs_df0idhw = 1; p->cs_resetwarning = 0; p->cs_ciatodbug = false; + p->cs_1mchipjumper = false; - _tcscpy(p->romfile, _T("")); _tcscpy(p->romextfile, _T("")); - _tcscpy(p->a2091romfile, _T("")); - _tcscpy(p->a4091romfile, _T("")); - _tcscpy(p->flashfile, _T("")); - _tcscpy(p->cartfile, _T("")); - _tcscpy(p->rtcfile, _T("")); - _tcscpy(p->amaxromfile, _T("")); + _tcscpy(p->romextfile2, _T("")); + + p->ne2000pciname[0] = 0; + p->ne2000pcmcianame[0] = 0; + p->a2065name[0] = 0; + p->prtname[0] = 0; p->sername[0] = 0; p->mountitems = 0; target_default_options(p, 1); + cfgfile_compatibility_romtype(p); } static void set_68020_compa(struct uae_prefs *p, int compa, int cd32) @@ -5140,26 +7219,43 @@ static void set_68020_compa(struct uae_prefs *p, int compa, int cd32) case 0: p->blitter_cycle_exact = 1; p->m68k_speed = 0; - if (p->cpu_model == 68020 && p->cachesize == 0) { + if ((p->cpu_model == 68020 || p->cpu_model == 68030) && p->cachesize == 0) { p->cpu_cycle_exact = 1; - p->cpu_clock_multiplier = 4 << 8; + p->cpu_memory_cycle_exact = true; + if (p->cpu_model == 68020) + p->cpu_clock_multiplier = 4 << 8; + else + p->cpu_clock_multiplier = 5 << 8; } break; case 1: + p->blitter_cycle_exact = true; + p->m68k_speed = 0; + if ((p->cpu_model == 68020 || p->cpu_model == 68030) && p->cachesize == 0) { + p->cpu_memory_cycle_exact = true; + if (p->cpu_model == 68020) + p->cpu_clock_multiplier = 4 << 8; + else + p->cpu_clock_multiplier = 5 << 8; + } + break; + case 2: p->cpu_compatible = true; p->m68k_speed = 0; break; - case 2: + case 3: p->cpu_compatible = 0; p->m68k_speed = -1; p->address_space_24 = 0; break; - case 3: + case 4: p->cpu_compatible = 0; p->address_space_24 = 0; - p->cachesize = 8192; + p->cachesize = MAX_JIT_CACHE; break; } + if (p->cpu_model >= 68030) + p->address_space_24 = 0; } /* 0: cycle-exact @@ -5174,7 +7270,7 @@ static void set_68000_compa(struct uae_prefs *p, int compa) switch (compa) { case 0: - p->cpu_cycle_exact = p->blitter_cycle_exact = 1; + p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = true; break; case 1: break; @@ -5207,7 +7303,7 @@ static int bip_a3000(struct uae_prefs *p, int config, int compa, int romcheck) if (compa == 0) p->mmu_model = 68030; else - p->cachesize = 8192; + p->cachesize = MAX_JIT_CACHE; p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; p->cpu_compatible = p->address_space_24 = 0; p->m68k_speed = -1; @@ -5238,16 +7334,28 @@ static int bip_a4000(struct uae_prefs *p, int config, int compa, int romcheck) p->mbresmem_low_size = 8 * 1024 * 1024; p->cpu_model = 68030; p->fpu_model = 68882; - if (config > 0) { + switch (config) + { + case 1: p->cpu_model = 68040; p->fpu_model = 68040; + break; + case 2: + p->cpu_model = 68060; + p->fpu_model = 68060; + p->ppc_mode = 1; + //cpuboard_setboard(p, BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC); + p->cpuboardmem1_size = 128 * 1024 * 1024; + int roms_ppc[] = { 98, -1 }; + configure_rom(p, roms_ppc, romcheck); + break; } p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; p->cpu_compatible = p->address_space_24 = 0; p->m68k_speed = -1; p->immediate_blits = 0; p->produce_sound = 2; - p->cachesize = 8192; + p->cachesize = MAX_JIT_CACHE; p->floppyslots[0].dfxtype = DRV_35_HD; p->floppyslots[1].dfxtype = DRV_35_HD; p->floppy_speed = 0; @@ -5282,7 +7390,7 @@ static int bip_a4000t(struct uae_prefs *p, int config, int compa, int romcheck) p->m68k_speed = -1; p->immediate_blits = 0; p->produce_sound = 2; - p->cachesize = 8192; + p->cachesize = MAX_JIT_CACHE; p->floppyslots[0].dfxtype = DRV_35_HD; p->floppyslots[1].dfxtype = DRV_35_HD; p->floppy_speed = 0; @@ -5293,6 +7401,23 @@ static int bip_a4000t(struct uae_prefs *p, int config, int compa, int romcheck) return configure_rom(p, roms, romcheck); } +static void bip_velvet(struct uae_prefs *p, int config, int compa, int romcheck) +{ + p->chipset_mask = 0; + p->bogomem_size = 0; + p->sound_filter = FILTER_SOUND_ON; + set_68000_compa(p, compa); + p->floppyslots[1].dfxtype = DRV_NONE; + p->cs_compatible = CP_VELVET; + p->cs_slowmemisfast = 1; + p->cs_dipagnus = 1; + p->cs_agnusbltbusybug = 1; + built_in_chipset_prefs(p); + p->cs_denisenoehb = 1; + p->cs_cia6526 = 1; + p->chipmem_size = 0x40000; +} + static int bip_a1000(struct uae_prefs *p, int config, int compa, int romcheck) { int roms[2]; @@ -5313,13 +7438,54 @@ static int bip_a1000(struct uae_prefs *p, int config, int compa, int romcheck) p->cs_denisenoehb = 1; if (config > 1) p->chipmem_size = 0x40000; + if (config > 2) { + roms[0] = 125; + roms[1] = -1; + bip_velvet(p, config, compa, romcheck); + } return configure_rom(p, roms, romcheck); } +static int bip_cdtvcr(struct uae_prefs *p, int config, int compa, int romcheck) +{ + int roms[4]; + + p->bogomem_size = 0; + p->chipmem_size = 0x100000; + p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; + p->cs_cdtvcd = p->cs_cdtvram = true; + p->cs_cdtvcr = true; + p->cs_rtc = 1; + p->nr_floppies = 0; + p->floppyslots[0].dfxtype = DRV_NONE; + if (config > 0) + p->floppyslots[0].dfxtype = DRV_35_DD; + p->floppyslots[1].dfxtype = DRV_NONE; + set_68000_compa(p, compa); + p->cs_compatible = CP_CDTVCR; + built_in_chipset_prefs(p); + fetch_datapath(p->flashfile, sizeof(p->flashfile) / sizeof(TCHAR)); + _tcscat(p->flashfile, _T("cdtv-cr.nvr")); + roms[0] = 9; + roms[1] = 10; + roms[2] = -1; + if (!configure_rom(p, roms, romcheck)) + return 0; + roms[0] = 108; + roms[1] = 107; + roms[2] = -1; + if (!configure_rom(p, roms, romcheck)) + return 0; + return 1; +} + static int bip_cdtv(struct uae_prefs *p, int config, int compa, int romcheck) { int roms[4]; + if (config >= 2) + return bip_cdtvcr(p, config - 2, compa, romcheck); + p->bogomem_size = 0; p->chipmem_size = 0x100000; p->chipset_mask = CSMASK_ECS_AGNUS; @@ -5353,10 +7519,10 @@ static int bip_cdtv(struct uae_prefs *p, int config, int compa, int romcheck) static int bip_cd32(struct uae_prefs *p, int config, int compa, int romcheck) { - int roms[2]; + int roms[3]; buildin_default_prefs_68020(p); - p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = 1; + p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = true; p->nr_floppies = 0; p->floppyslots[0].dfxtype = DRV_NONE; p->floppyslots[1].dfxtype = DRV_NONE; @@ -5377,7 +7543,10 @@ static int bip_cd32(struct uae_prefs *p, int config, int compa, int romcheck) return 0; } if (config > 0) { - roms[0] = 23; + p->cs_cd32fmv = true; + roms[0] = 74; + roms[1] = 23; + roms[2] = -1; if (!configure_rom(p, roms, romcheck)) return 0; } @@ -5387,20 +7556,65 @@ static int bip_cd32(struct uae_prefs *p, int config, int compa, int romcheck) static int bip_a1200(struct uae_prefs *p, int config, int compa, int romcheck) { int roms[4]; + int roms_bliz[2]; buildin_default_prefs_68020(p); roms[0] = 11; roms[1] = 15; roms[2] = 31; roms[3] = -1; + roms_bliz[0] = -1; + roms_bliz[1] = -1; p->cs_rtc = 0; - if (config == 1) { - p->fastmem_size = 0x400000; - p->cs_rtc = 2; - } - set_68020_compa(p, compa, 0); p->cs_compatible = CP_A1200; built_in_chipset_prefs(p); + switch (config) + { + case 1: + p->fastmem[0].size = 0x400000; + p->cs_rtc = 1; + break; + case 2: + //cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230IV); + p->cpuboardmem1_size = 32 * 1024 * 1024; + p->cpu_model = 68030; + p->cs_rtc = 1; + roms_bliz[0] = 89; + configure_rom(p, roms_bliz, romcheck); + break; + case 3: + //cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260); + p->cpuboardmem1_size = 32 * 1024 * 1024; + p->cpu_model = 68040; + p->fpu_model = 68040; + p->cs_rtc = 1; + roms_bliz[0] = 90; + configure_rom(p, roms_bliz, romcheck); + break; + case 4: + //cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260); + p->cpuboardmem1_size = 32 * 1024 * 1024; + p->cpu_model = 68060; + p->fpu_model = 68060; + p->cs_rtc = 1; + roms_bliz[0] = 90; + configure_rom(p, roms_bliz, romcheck); + break; + case 5: + //cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC); + p->cpuboardmem1_size = 256 * 1024 * 1024; + p->cpu_model = 68060; + p->fpu_model = 68060; + p->ppc_mode = 1; + p->cs_rtc = 1; + roms[0] = 15; + roms[1] = 11; + roms[2] = -1; + roms_bliz[0] = 100; + configure_rom(p, roms_bliz, romcheck); + break; + } + set_68020_compa(p, compa, 0); return configure_rom(p, roms, romcheck); } @@ -5412,6 +7626,9 @@ static int bip_a600(struct uae_prefs *p, int config, int compa, int romcheck) roms[1] = 9; roms[2] = 8; roms[3] = -1; + set_68000_compa(p, compa); + p->cs_compatible = CP_A600; + built_in_chipset_prefs(p); p->bogomem_size = 0; p->chipmem_size = 0x100000; if (config > 0) @@ -5419,11 +7636,8 @@ static int bip_a600(struct uae_prefs *p, int config, int compa, int romcheck) if (config == 1) p->chipmem_size = 0x200000; if (config == 2) - p->fastmem_size = 0x400000; + p->fastmem[0].size = 0x400000; p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; - set_68000_compa(p, compa); - p->cs_compatible = CP_A600; - built_in_chipset_prefs(p); return configure_rom(p, roms, romcheck); } @@ -5433,6 +7647,9 @@ static int bip_a500p(struct uae_prefs *p, int config, int compa, int romcheck) roms[0] = 7; roms[1] = -1; + set_68000_compa(p, compa); + p->cs_compatible = CP_A500P; + built_in_chipset_prefs(p); p->bogomem_size = 0; p->chipmem_size = 0x100000; if (config > 0) @@ -5440,11 +7657,8 @@ static int bip_a500p(struct uae_prefs *p, int config, int compa, int romcheck) if (config == 1) p->chipmem_size = 0x200000; if (config == 2) - p->fastmem_size = 0x400000; + p->fastmem[0].size = 0x400000; p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; - set_68000_compa(p, compa); - p->cs_compatible = CP_A500P; - built_in_chipset_prefs(p); return configure_rom(p, roms, romcheck); } @@ -5502,20 +7716,19 @@ static int bip_a500(struct uae_prefs *p, int config, int compa, int romcheck) static int bip_super(struct uae_prefs *p, int config, int compa, int romcheck) { - int roms[8]; + int roms[7]; - roms[0] = 46; - roms[1] = 16; - roms[2] = 31; - roms[3] = 15; - roms[4] = 14; - roms[5] = 12; - roms[6] = 11; - roms[7] = -1; + roms[0] = 16; + roms[1] = 31; + roms[2] = 15; + roms[3] = 14; + roms[4] = 12; + roms[5] = 11; + roms[6] = -1; p->bogomem_size = 0; p->chipmem_size = 0x400000; - p->z3fastmem_size = 8 * 1024 * 1024; - p->rtgmem_size = 16 * 1024 * 1024; + p->z3fastmem[0].size = 8 * 1024 * 1024; + p->rtgboards[0].rtgmem_size = 16 * 1024 * 1024; p->cpu_model = 68040; p->fpu_model = 68040; p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; @@ -5523,7 +7736,7 @@ static int bip_super(struct uae_prefs *p, int config, int compa, int romcheck) p->m68k_speed = -1; p->immediate_blits = 1; p->produce_sound = 2; - p->cachesize = 8192; + p->cachesize = MAX_JIT_CACHE; p->floppyslots[0].dfxtype = DRV_35_HD; p->floppyslots[1].dfxtype = DRV_35_HD; p->floppy_speed = 0; @@ -5624,12 +7837,15 @@ int built_in_prefs(struct uae_prefs *p, int model, int config, int compa, int ro v = bip_super(p, config, compa, romcheck); break; } - if ((p->cpu_model >= 68020 || !p->cpu_cycle_exact) && !p->immediate_blits) + if ((p->cpu_model >= 68020 || !p->cpu_cycle_exact || !p->cpu_memory_cycle_exact) && !p->immediate_blits) p->waiting_blits = 1; if (p->sound_filter_type == FILTER_SOUND_TYPE_A500 && (p->chipset_mask & CSMASK_AGA)) p->sound_filter_type = FILTER_SOUND_TYPE_A1200; else if (p->sound_filter_type == FILTER_SOUND_TYPE_A1200 && !(p->chipset_mask & CSMASK_AGA)) p->sound_filter_type = FILTER_SOUND_TYPE_A500; + if (p->cpu_model >= 68040) + p->cs_bytecustomwritebug = true; + cfgfile_compatibility_romtype(p); return v; } @@ -5640,7 +7856,7 @@ int built_in_chipset_prefs(struct uae_prefs *p) p->cs_a1000ram = 0; p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = 0; - p->cs_cdtvcd = p->cs_cdtvram = p->cs_cdtvscsi = 0; + p->cs_cdtvcd = p->cs_cdtvram = p->cs_cdtvscsi = p->cs_cdtvcr = 0; p->cs_fatgaryrev = -1; p->cs_ide = 0; p->cs_ramseyrev = -1; @@ -5661,15 +7877,34 @@ int built_in_chipset_prefs(struct uae_prefs *p) p->cs_resetwarning = 1; p->cs_slowmemisfast = 0; p->cs_ciatodbug = false; + p->cs_z3autoconfig = false; + p->cs_bytecustomwritebug = false; + p->cs_1mchipjumper = false; switch (p->cs_compatible) { case CP_GENERIC: // generic - p->cs_rtc = 2; - p->cs_fatgaryrev = 0; - p->cs_ide = -1; - p->cs_mbdmac = -1; - p->cs_ramseyrev = 0x0f; + if (p->cpu_model >= 68020) { + // big box-like + p->cs_rtc = 2; + p->cs_fatgaryrev = 0; + p->cs_ide = -1; + p->cs_mbdmac = 0; + p->cs_ramseyrev = 0x0f; + } + else if (p->cpu_compatible) { + // very A500-like + p->cs_df0idhw = 0; + p->cs_resetwarning = 0; + if (p->bogomem_size || p->chipmem_size > 0x80000 || p->fastmem[0].size) + p->cs_rtc = 1; + p->cs_ciatodbug = true; + } + else { + // sort of A500-like + p->cs_ide = -1; + p->cs_rtc = 1; + } break; case CP_CDTV: // CDTV p->cs_rtc = 1; @@ -5677,8 +7912,21 @@ int built_in_chipset_prefs(struct uae_prefs *p) p->cs_df0idhw = 1; p->cs_ksmirror_e0 = 0; break; + case CP_CDTVCR: // CDTV-CR + p->cs_rtc = 1; + p->cs_cdtvcd = p->cs_cdtvram = 1; + p->cs_cdtvcr = true; + p->cs_df0idhw = 1; + p->cs_ksmirror_e0 = 0; + p->cs_ide = IDE_A600A1200; + p->cs_pcmcia = 1; + p->cs_ksmirror_a8 = 1; + p->cs_ciaoverlay = 0; + p->cs_resetwarning = 0; + p->cs_ciatodbug = true; + break; case CP_CD32: // CD32 - p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = 1; + p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = true; p->cs_ksmirror_e0 = 0; p->cs_ksmirror_a8 = 1; p->cs_ciaoverlay = 0; @@ -5687,7 +7935,7 @@ int built_in_chipset_prefs(struct uae_prefs *p) case CP_A500: // A500 p->cs_df0idhw = 0; p->cs_resetwarning = 0; - if (p->bogomem_size || p->chipmem_size > 0x80000 || p->fastmem_size) + if (p->bogomem_size || p->chipmem_size > 0x80000 || p->fastmem[0].size) p->cs_rtc = 1; p->cs_ciatodbug = true; break; @@ -5697,7 +7945,6 @@ int built_in_chipset_prefs(struct uae_prefs *p) p->cs_ciatodbug = true; break; case CP_A600: // A600 - p->cs_rtc = 1; p->cs_ide = IDE_A600A1200; p->cs_pcmcia = 1; p->cs_ksmirror_a8 = 1; @@ -5713,12 +7960,19 @@ int built_in_chipset_prefs(struct uae_prefs *p) p->cs_dipagnus = 1; p->cs_ciatodbug = true; break; + case CP_VELVET: // A1000 Prototype + p->cs_ciaatod = p->ntscmode ? 2 : 1; + p->cs_ksmirror_e0 = 0; + p->cs_agnusbltbusybug = 1; + p->cs_dipagnus = 1; + p->cs_denisenoehb = 1; + break; case CP_A1200: // A1200 p->cs_ide = IDE_A600A1200; p->cs_pcmcia = 1; p->cs_ksmirror_a8 = 1; p->cs_ciaoverlay = 0; - if (p->fastmem_size || p->z3fastmem_size) + if (p->fastmem[0].size || p->z3fastmem[0].size || p->cpuboard_type) p->cs_rtc = 1; break; case CP_A2000: // A2000 @@ -5733,6 +7987,7 @@ int built_in_chipset_prefs(struct uae_prefs *p) p->cs_mbdmac = 1; p->cs_ksmirror_e0 = 0; p->cs_ciaatod = p->ntscmode ? 2 : 1; + p->cs_z3autoconfig = true; break; case CP_A3000T: // A3000T p->cs_rtc = 2; @@ -5741,6 +7996,7 @@ int built_in_chipset_prefs(struct uae_prefs *p) p->cs_mbdmac = 1; p->cs_ksmirror_e0 = 0; p->cs_ciaatod = p->ntscmode ? 2 : 1; + p->cs_z3autoconfig = true; break; case CP_A4000: // A4000 p->cs_rtc = 2; @@ -5751,6 +8007,7 @@ int built_in_chipset_prefs(struct uae_prefs *p) p->cs_ksmirror_a8 = 0; p->cs_ksmirror_e0 = 0; p->cs_ciaoverlay = 0; + p->cs_z3autoconfig = true; break; case CP_A4000T: // A4000T p->cs_rtc = 2; @@ -5761,8 +8018,72 @@ int built_in_chipset_prefs(struct uae_prefs *p) p->cs_ksmirror_a8 = 0; p->cs_ksmirror_e0 = 0; p->cs_ciaoverlay = 0; + p->cs_z3autoconfig = true; break; } + if (p->cpu_model >= 68040) + p->cs_bytecustomwritebug = true; + return 1; +} + +int built_in_cpuboard_prefs(struct uae_prefs *p) +{ + int roms[2], roms2[2]; + + roms[0] = -1; + roms[1] = -1; + roms2[0] = -1; + roms2[1] = -1; + + //switch (cpuboards[p->cpuboard_type].id) + //{ + //case BOARD_MACROSYSTEM: + // switch (p->cpuboard_subtype) + // { + // case BOARD_MACROSYSTEM_SUB_WARPENGINE_A4000: + // roms[0] = 93; + // break; + // } + // break; + //case BOARD_BLIZZARD: + // switch (p->cpuboard_subtype) + // { + // case BOARD_BLIZZARD_SUB_1230IV: + // roms[0] = 89; + // break; + // case BOARD_BLIZZARD_SUB_1260: + // roms[0] = 90; + // break; + // case BOARD_BLIZZARD_SUB_2060: + // roms[0] = 92; + // break; + // case BOARD_BLIZZARD_SUB_PPC: + // roms[0] = p->cpu_model == 68040 ? 99 : 100; + // break; + // } + // break; + //case BOARD_CYBERSTORM: + // switch (p->cpuboard_subtype) + // { + // case BOARD_CYBERSTORM_SUB_MK1: + // roms[0] = p->cpu_model == 68040 ? 95 : 101; + // break; + // case BOARD_CYBERSTORM_SUB_MK2: + // roms[0] = 96; + // break; + // case BOARD_CYBERSTORM_SUB_MK3: + // roms[0] = 97; + // break; + // case BOARD_CYBERSTORM_SUB_PPC: + // roms[0] = 98; + // break; + // } + // break; + //} + if (!configure_rom(p, roms, 0)) + return 0; + if (!configure_rom(p, roms2, 0)) + return 0; return 1; } @@ -5790,20 +8111,17 @@ bool is_error_log(void) { return error_lines != NULL; } - -TCHAR* get_error_log(void) +TCHAR *get_error_log(void) { - strlist* sl; + strlist *sl; int len = 0; - for (sl = error_lines; sl; sl = sl->next) - { + for (sl = error_lines; sl; sl = sl->next) { len += _tcslen(sl->option) + 1; } if (!len) return NULL; - TCHAR* s = xcalloc(TCHAR, len + 1); - for (sl = error_lines; sl; sl = sl->next) - { + TCHAR *s = xcalloc(TCHAR, len + 1); + for (sl = error_lines; sl; sl = sl->next) { _tcscat(s, sl->option); _tcscat(s, _T("\n")); } diff --git a/src/cia.cpp b/src/cia.cpp index bff73a06..bc30ffda 100644 --- a/src/cia.cpp +++ b/src/cia.cpp @@ -12,7 +12,7 @@ #include #include "options.h" -#include "memory.h" +#include "include/memory.h" #include "custom.h" #include "newcpu.h" #include "cia.h" @@ -30,12 +30,29 @@ #include "autoconf.h" #include "drawing.h" +#define CIAA_DEBUG_R 0 +#define CIAA_DEBUG_W 0 +#define CIAA_DEBUG_IRQ 0 + +#define CIAB_DEBUG_R 0 +#define CIAB_DEBUG_W 0 +#define CIAB_DEBUG_IRQ 0 + +#define DONGLE_DEBUG 0 +#define KB_DEBUG 0 +#define CLOCK_DEBUG 0 + #define TOD_HACK -/* e-clock is 10 CPU cycles, 4 cycles high, 6 low - * data transfer happens during 4 high cycles - */ + /* Akiko internal CIA differences: + - BFE101 and BFD100: reads 3F if data direction is in. + + */ + + /* e-clock is 10 CPU cycles, 4 cycles high, 6 low + * data transfer happens during 4 high cycles + */ #define ECLOCK_DATA_CYCLE 4 #define ECLOCK_WAIT_CYCLE 6 @@ -56,8 +73,10 @@ static unsigned long ciaatod, ciabtod, ciaatol, ciabtol, ciaaalarm, ciabalarm; static int ciaatlatch, ciabtlatch; static bool oldovl, oldcd32mute; static bool led; +static int led_old_brightness; +static unsigned long led_cycles_on, led_cycles_off, led_cycle; -static unsigned int ciabpra; +unsigned int ciabpra; static unsigned long ciaala, ciaalb, ciabla, ciablb; static int ciaatodon, ciabtodon; @@ -67,328 +86,428 @@ static int div10; static int kbstate, kblostsynccnt; static uae_u8 kbcode; -STATIC_INLINE void setclr (unsigned int *p, unsigned int val) +static uae_u8 serbits; +static int warned = 10; +static int rtc_delayed_write; + +static void setclr(unsigned int *p, unsigned int val) { - if (val & 0x80) { - *p |= val & 0x7F; - } else { - *p &= ~val; - } + if (val & 0x80) { + *p |= val & 0x7F; + } + else { + *p &= ~val; + } } -STATIC_INLINE void ICR (uae_u32 data) +/* delay interrupt after current CIA register access if +* interrupt would have triggered mid access +*/ +static int cia_interrupt_disabled; +static int cia_interrupt_delay; + +static void ICR(uae_u32 data) { - INTREQ_0 (0x8000 | data); + INTREQ_0(0x8000 | data); } -STATIC_INLINE void ICRA(uae_u32 data) +static void ICRA(uae_u32 data) { ciaaicr |= 0x40; +#if 1 + if (currprefs.cpu_memory_cycle_exact && !(ciaaicr & 0x20) && (cia_interrupt_disabled & 1)) { + cia_interrupt_delay |= 1; +#if CIAB_DEBUG_IRQ + write_log(_T("ciab interrupt disabled ICR=%02X PC=%x\n"), ciabicr, M68K_GETPC); +#endif + return; + } +#endif ciaaicr |= 0x20; - ICR (0x0008); + ICR(0x0008); } -STATIC_INLINE void ICRB(uae_u32 data) +static void ICRB(uae_u32 data) { ciabicr |= 0x40; +#if 1 + if (currprefs.cpu_memory_cycle_exact && !(ciabicr & 0x20) && (cia_interrupt_disabled & 2)) { + cia_interrupt_delay |= 2; +#if CIAB_DEBUG_IRQ + write_log(_T("ciab interrupt disabled ICR=%02X PC=%x\n"), ciabicr, M68K_GETPC); +#endif + return; + } +#endif ciabicr |= 0x20; - ICR (0x2000); + if (currprefs.cs_compatible == CP_VELVET) { + // Both CIAs in Velvet are connected to level 2. + ICR(0x0008); + } + else { + ICR(0x2000); + } } -STATIC_INLINE void RethinkICRA (void) +static void RethinkICRA(void) { - if (ciaaicr & ciaaimask) { + if (ciaaicr & ciaaimask) { +#if CIAA_DEBUG_IRQ + write_log(_T("CIAA IRQ %02X\n"), ciaaicr); +#endif if (!(ciaaicr & 0x80)) { ciaaicr |= 0x80; - ICRA (0x0008); - } - } + if (currprefs.cpu_memory_cycle_exact) { + event2_newevent_xx(-1, DIV10 + 2 * CYCLE_UNIT + CYCLE_UNIT / 2, 0, ICRA); + } + else { + ICRA(0x0008); + } + } + } } -STATIC_INLINE void RethinkICRB (void) +static void RethinkICRB(void) { - if (ciabicr & ciabimask) { + if (ciabicr & ciabimask) { +#if CIAB_DEBUG_IRQ + write_log(_T("CIAB IRQ %02X\n"), ciabicr); +#endif if (!(ciabicr & 0x80)) { ciabicr |= 0x80; - ICRB (0); - } - } + if (currprefs.cpu_memory_cycle_exact) { + event2_newevent_xx(-1, DIV10 + 2 * CYCLE_UNIT + CYCLE_UNIT / 2, 0, ICRB); + } + else { + ICRB(0); + } + } + } } -void rethink_cias (void) +void rethink_cias(void) { if (ciaaicr & 0x40) - ICRA (0); + ICRA(0); if (ciabicr & 0x40) - ICRB (0); + ICRB(0); } /* Figure out how many CIA timer cycles have passed for each timer since the last call of CIA_calctimers. */ -static void compute_passed_time (void) +static void compute_passed_time(void) { - unsigned long int ccount = (get_cycles () - eventtab[ev_cia].oldcycles + div10); - unsigned long int ciaclocks = ccount / DIV10; + unsigned long int ccount = (get_cycles() - eventtab[ev_cia].oldcycles + div10); + unsigned long int ciaclocks = ccount / DIV10; - ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0; + ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0; - /* CIA A timers */ - if ((ciaacra & 0x21) == 0x01) { + /* CIA A timers */ + if ((ciaacra & 0x21) == 0x01) { unsigned long int cc = ciaclocks; if (cc > ciaastarta) cc -= ciaastarta; else cc = 0; + assert((ciaata + 1) >= cc); ciaata_passed = cc; - } - if ((ciaacrb & 0x61) == 0x01) { + } + if ((ciaacrb & 0x61) == 0x01) { unsigned long int cc = ciaclocks; if (cc > ciaastartb) cc -= ciaastartb; else cc = 0; + assert((ciaatb + 1) >= cc); ciaatb_passed = cc; - } + } - /* CIA B timers */ - if ((ciabcra & 0x21) == 0x01) { + /* CIA B timers */ + if ((ciabcra & 0x21) == 0x01) { unsigned long int cc = ciaclocks; if (cc > ciabstarta) cc -= ciabstarta; else cc = 0; + assert((ciabta + 1) >= cc); ciabta_passed = cc; - } - if ((ciabcrb & 0x61) == 0x01) { + } + if ((ciabcrb & 0x61) == 0x01) { unsigned long int cc = ciaclocks; if (cc > ciabstartb) cc -= ciabstartb; else cc = 0; + assert((ciabtb + 1) >= cc); ciabtb_passed = cc; - } + } } /* Called to advance all CIA timers to the current time. This expects that one of the timer values will be modified, and CIA_calctimers will be called in the same cycle. */ -static int CIA_update_check (void) +static int CIA_update_check(void) { - unsigned long int ccount = (get_cycles () - eventtab[ev_cia].oldcycles + div10); - unsigned long int ciaclocks = ccount / DIV10; + unsigned long int ccount = (get_cycles() - eventtab[ev_cia].oldcycles + div10); + unsigned long int ciaclocks = ccount / DIV10; - int aovfla = 0, aovflb = 0, asp = 0, bovfla = 0, bovflb = 0, bsp = 0; + int aovfla = 0, aovflb = 0, asp = 0, bovfla = 0, bovflb = 0, bsp = 0; int icr = 0; - div10 = ccount % DIV10; + div10 = ccount % DIV10; - /* CIA A timers */ - if ((ciaacra & 0x21) == 0x01) { + /* CIA A timers */ + if ((ciaacra & 0x21) == 0x01) { bool check = true; unsigned long int cc = ciaclocks; if (ciaastarta > 0) { if (cc > ciaastarta) { cc -= ciaastarta; ciaastarta = 0; - } else { + } + else { ciaastarta -= cc; check = false; } } if (check) { + assert((ciaata + 1) >= cc); if ((ciaata + 1) == cc) { - if ((ciaacra & 0x48) == 0x40 && ciaasdr_cnt > 0 && --ciaasdr_cnt == 0) - asp = 1; - aovfla = 1; - if ((ciaacrb & 0x61) == 0x41 || (ciaacrb & 0x61) == 0x61) { - if (ciaatb-- == 0) - aovflb = 1; - } - } + if ((ciaacra & 0x48) == 0x40 && ciaasdr_cnt > 0 && --ciaasdr_cnt == 0) + asp = 1; + aovfla = 1; + if ((ciaacrb & 0x61) == 0x41 || (ciaacrb & 0x61) == 0x61) { + if (ciaatb-- == 0) + aovflb = 1; + } + } ciaata -= cc; } - } - if ((ciaacrb & 0x61) == 0x01) { + } + if ((ciaacrb & 0x61) == 0x01) { bool check = true; unsigned long int cc = ciaclocks; if (ciaastartb > 0) { if (cc > ciaastartb) { cc -= ciaastartb; ciaastartb = 0; - } else { + } + else { ciaastartb -= cc; check = false; } } if (check) { + assert((ciaatb + 1) >= cc); if ((ciaatb + 1) == cc) - aovflb = 1; + aovflb = 1; ciaatb -= cc; } - } + } - /* CIA B timers */ - if ((ciabcra & 0x21) == 0x01) { + /* CIA B timers */ + if ((ciabcra & 0x21) == 0x01) { bool check = true; unsigned long int cc = ciaclocks; if (ciabstarta > 0) { if (cc > ciabstarta) { cc -= ciabstarta; ciabstarta = 0; - } else { + } + else { ciabstarta -= cc; check = false; } } if (check) { + assert((ciabta + 1) >= cc); if ((ciabta + 1) == cc) { - if ((ciabcra & 0x48) == 0x40 && ciabsdr_cnt > 0 && --ciabsdr_cnt == 0) - bsp = 1; - bovfla = 1; - if ((ciabcrb & 0x61) == 0x41 || (ciabcrb & 0x61) == 0x61) { - if (ciabtb-- == 0) - bovflb = 1; - } - } + if ((ciabcra & 0x48) == 0x40 && ciabsdr_cnt > 0 && --ciabsdr_cnt == 0) + bsp = 1; + bovfla = 1; + if ((ciabcrb & 0x61) == 0x41 || (ciabcrb & 0x61) == 0x61) { + if (ciabtb-- == 0) + bovflb = 1; + } + } ciabta -= cc; } - } - if ((ciabcrb & 0x61) == 0x01) { + } + if ((ciabcrb & 0x61) == 0x01) { bool check = true; unsigned long int cc = ciaclocks; if (ciabstartb > 0) { if (cc > ciabstartb) { cc -= ciabstartb; ciabstartb = 0; - } else { + } + else { ciabstartb -= cc; check = false; } } if (check) { + assert((ciabtb + 1) >= cc); if ((ciabtb + 1) == cc) - bovflb = 1; + bovflb = 1; ciabtb -= cc; } - } + } - if (aovfla) { + if (aovfla) { ciaaicr |= 1; icr = 1; - ciaata = ciaala; - if (ciaacra & 0x8) { - ciaacra &= ~1; - } - } - if (aovflb) { + ciaata = ciaala; + if (ciaacra & 0x8) { + ciaacra &= ~1; + } + } + if (aovflb) { ciaaicr |= 2; icr = 1; - ciaatb = ciaalb; - if (ciaacrb & 0x8) { - ciaacrb &= ~1; - } - } - if (asp) { + ciaatb = ciaalb; + if (ciaacrb & 0x8) { + ciaacrb &= ~1; + } + } + if (asp) { ciaaicr |= 8; icr = 1; - } - if (bovfla) { + } + if (bovfla) { ciabicr |= 1; icr |= 2; - ciabta = ciabla; - if (ciabcra & 0x8) { - ciabcra &= ~1; - } - } - if (bovflb) { + ciabta = ciabla; + if (ciabcra & 0x8) { + ciabcra &= ~1; + } + } + if (bovflb) { ciabicr |= 2; icr |= 2; - ciabtb = ciablb; - if (ciabcrb & 0x8) { - ciabcrb &= ~1; - } - } - if (bsp) { + ciabtb = ciablb; + if (ciabcrb & 0x8) { + ciabcrb &= ~1; + } + } + if (bsp) { ciabicr |= 8; icr |= 2; - } + } return icr; } -static void CIA_update (void) +static void CIA_update(void) { - int icr = CIA_update_check (); + int icr = CIA_update_check(); if (icr & 1) - RethinkICRA (); + RethinkICRA(); if (icr & 2) - RethinkICRB (); + RethinkICRB(); } /* Call this only after CIA_update has been called in the same cycle. */ -static void CIA_calctimers (void) +static void CIA_calctimers(void) { - long int ciaatimea = -1, ciaatimeb = -1, ciabtimea = -1, ciabtimeb = -1; + long int ciaatimea = -1, ciaatimeb = -1, ciabtimea = -1, ciabtimeb = -1; int div10diff = DIV10 - div10; - eventtab[ev_cia].oldcycles = get_cycles (); - if ((ciaacra & 0x21) == 0x01) { + eventtab[ev_cia].oldcycles = get_cycles(); + + if ((ciaacra & 0x21) == 0x01) { ciaatimea = div10diff + DIV10 * (ciaata + ciaastarta); - } - if ((ciaacrb & 0x61) == 0x01) { + } +#if 0 + if ((ciaacrb & 0x61) == 0x41) { + /* Timer B will not get any pulses if Timer A is off. */ + if (ciaatimea >= 0) { + /* If Timer A is in one-shot mode, and Timer B needs more than + * one pulse, it will not underflow. */ + if (ciaatb == 0 || (ciaacra & 0x8) == 0) { + /* Otherwise, we can determine the time of the underflow. */ + /* This may overflow, however. So just ignore this timer and + use the fact that we'll call CIA_handler for the A timer. */ + /* ciaatimeb = ciaatimea + ciaala * DIV10 * ciaatb; */ + } + } + } +#endif + if ((ciaacrb & 0x61) == 0x01) { ciaatimeb = div10diff + DIV10 * (ciaatb + ciaastartb); - } + } - if ((ciabcra & 0x21) == 0x01) { + if ((ciabcra & 0x21) == 0x01) { ciabtimea = div10diff + DIV10 * (ciabta + ciabstarta); - } - if ((ciabcrb & 0x61) == 0x01) { + } +#if 0 + if ((ciabcrb & 0x61) == 0x41) { + /* Timer B will not get any pulses if Timer A is off. */ + if (ciabtimea >= 0) { + /* If Timer A is in one-shot mode, and Timer B needs more than + * one pulse, it will not underflow. */ + if (ciabtb == 0 || (ciabcra & 0x8) == 0) { + /* Otherwise, we can determine the time of the underflow. */ + /* ciabtimeb = ciabtimea + ciabla * DIV10 * ciabtb; */ + } + } + } +#endif + if ((ciabcrb & 0x61) == 0x01) { ciabtimeb = div10diff + DIV10 * (ciabtb + ciabstartb); - } - eventtab[ev_cia].active = (ciaatimea != -1 || ciaatimeb != -1 - || ciabtimea != -1 || ciabtimeb != -1); - if (eventtab[ev_cia].active) { - unsigned long int ciatime = ~0L; - if (ciaatimea != -1) - ciatime = ciaatimea; - if (ciaatimeb != -1 && ciaatimeb < ciatime) - ciatime = ciaatimeb; - if (ciabtimea != -1 && ciabtimea < ciatime) - ciatime = ciabtimea; - if (ciabtimeb != -1 && ciabtimeb < ciatime) - ciatime = ciabtimeb; - eventtab[ev_cia].evtime = ciatime + get_cycles (); - } - events_schedule(); + } + + eventtab[ev_cia].active = (ciaatimea != -1 || ciaatimeb != -1 + || ciabtimea != -1 || ciabtimeb != -1); + if (eventtab[ev_cia].active) { + unsigned long int ciatime = ~0L; + if (ciaatimea != -1) + ciatime = ciaatimea; + if (ciaatimeb != -1 && ciaatimeb < ciatime) + ciatime = ciaatimeb; + if (ciabtimea != -1 && ciabtimea < ciatime) + ciatime = ciabtimea; + if (ciabtimeb != -1 && ciabtimeb < ciatime) + ciatime = ciabtimeb; + eventtab[ev_cia].evtime = ciatime + get_cycles(); + } + events_schedule(); } -void CIA_handler (void) +void CIA_handler(void) { - CIA_update (); - CIA_calctimers (); + CIA_update(); + CIA_calctimers(); } -void cia_diskindex (void) +void cia_diskindex(void) { - ciabicr |= 0x10; - RethinkICRB(); + ciabicr |= 0x10; + RethinkICRB(); +} +void cia_parallelack(void) +{ + ciaaicr |= 0x10; + RethinkICRA(); } -static bool checkalarm (unsigned long tod, unsigned long alarm, bool inc) +static bool checkalarm(unsigned long tod, unsigned long alarm, bool inc, int ab) { - if (tod == alarm) - return true; - if (aga_mode) // A1200 has no TOD bug + if (tod == alarm) + return true; + // if (!ab) + // return false; + if (!currprefs.cs_ciatodbug) return false; - if (!inc) - return false; - /* emulate buggy TODMED counter. - * it counts: .. 29 2A 2B 2C 2D 2E 2F 20 30 31 32 .. - * (2F->20->30 only takes couple of cycles but it will trigger alarm.. - */ - if (tod & 0x000fff) - return false; - if (((tod - 1) & 0xfff000) == alarm) - return true; - return false; + if (!inc) + return false; + /* emulate buggy TODMED counter. + * it counts: .. 29 2A 2B 2C 2D 2E 2F 20 30 31 32 .. + * (2F->20->30 only takes couple of cycles but it will trigger alarm.. + */ + if (tod & 0x000fff) + return false; + if (((tod - 1) & 0xfff000) == alarm) + return true; + return false; } -STATIC_INLINE void ciab_checkalarm (bool inc) +STATIC_INLINE bool ciab_checkalarm(bool inc, bool irq) { // hack: do not trigger alarm interrupt if KS code and both // tod and alarm == 0. This incorrectly triggers on non-cycle exact @@ -396,161 +515,511 @@ STATIC_INLINE void ciab_checkalarm (bool inc) // at least 1 or larger due to bus cycle delays when reading // old value. #if 1 - if ((munge24 (m68k_getpc ()) & 0xFFF80000) != 0xF80000) { + if ((munge24(m68k_getpc()) & 0xFFF80000) != 0xF80000) { if (ciabtod == 0 && ciabalarm == 0) - return; + return false; } #endif - if (checkalarm (ciabtod, ciabalarm, inc)) { - ciabicr |= 4; - RethinkICRB (); - } + if (checkalarm(ciabtod, ciabalarm, inc, 1)) { +#if CIAB_DEBUG_IRQ + write_log(_T("CIAB tod %08x %08x\n"), ciabtod, ciabalarm); +#endif + if (irq) { + ciabicr |= 4; + RethinkICRB(); + } + return true; + } + return false; } -STATIC_INLINE void ciaa_checkalarm (bool inc) +STATIC_INLINE void ciaa_checkalarm(bool inc) { - if (checkalarm (ciaatod, ciaaalarm, inc)) { - ciaaicr |= 4; - RethinkICRA (); - } + if (checkalarm(ciaatod, ciaaalarm, inc, 0)) { +#if CIAA_DEBUG_IRQ + write_log(_T("CIAA tod %08x %08x\n"), ciaatod, ciaaalarm); +#endif + ciaaicr |= 4; + RethinkICRA(); + } } + #ifdef TOD_HACK -static int tod_hack, tod_hack_delay; -static void tod_hack_reset (void) +static uae_u64 tod_hack_tv, tod_hack_tod, tod_hack_tod_last; +static int tod_hack_enabled; +static int tod_hack_delay; +static int tod_diff_cnt; +#define TOD_HACK_DELAY 50 +#define TOD_HACK_TIME 312 * 50 * 10 +static void tod_hack_reset(void) { - struct timeval tv; - uae_u32 rate = vblank_hz; - gettimeofday (&tv, NULL); - tod_hack = (uae_u32)(((uae_u64)tv.tv_sec) * rate + tv.tv_usec / (1000000 / rate)); - tod_hack -= ciaatod; - tod_hack_delay = 10 * 50; + struct timeval tv; + gettimeofday(&tv, NULL); + tod_hack_tv = (uae_u64)tv.tv_sec * 1000000 + tv.tv_usec; + tod_hack_tod = ciaatod; + tod_hack_tod_last = tod_hack_tod; + tod_diff_cnt = 0; } #endif -static void setcode (uae_u8 keycode) +static int heartbeat_cnt; +void cia_heartbeat(void) { - kbcode = ~((keycode << 1) | (keycode >> 7)); + heartbeat_cnt = 10; } -static void keyreq (void) +static void do_tod_hack(int dotod) { + struct timeval tv; + static int oldrate; + uae_u64 t; + int rate; + int docount = 0; + + if (tod_hack_enabled == 0) + return; + if (!heartbeat_cnt) { + if (tod_hack_enabled > 0) + tod_hack_enabled = -1; + return; + } + if (tod_hack_enabled < 0) { + tod_hack_enabled = TOD_HACK_TIME; + return; + } + if (tod_hack_enabled > 1) { + tod_hack_enabled--; + if (tod_hack_enabled == 1) { + //write_log (_T("TOD HACK enabled\n")); + tod_hack_reset(); + } + return; + } + + if (currprefs.cs_ciaatod == 0) { + rate = (int)(vblank_hz + 0.5); + if (rate >= 59 && rate <= 61) + rate = 60; + if (rate >= 49 && rate <= 51) + rate = 50; + } + else if (currprefs.cs_ciaatod == 1) { + rate = 50; + } + else { + rate = 60; + } + if (rate <= 0) + return; + if (rate != oldrate || (ciaatod & 0xfff) != (tod_hack_tod_last & 0xfff)) { + write_log(_T("TOD HACK reset %d,%d %ld,%lld\n"), rate, oldrate, ciaatod, tod_hack_tod_last); + tod_hack_reset(); + oldrate = rate; + docount = 1; + } + + if (!dotod && currprefs.cs_ciaatod == 0) + return; + + if (tod_hack_delay > 0) { + tod_hack_delay--; + if (tod_hack_delay > 0) + return; + tod_hack_delay = TOD_HACK_DELAY; + } + + gettimeofday(&tv, NULL); + t = (uae_u64)tv.tv_sec * 1000000 + tv.tv_usec; + if (t - tod_hack_tv >= 1000000 / rate) { + tod_hack_tv += 1000000 / rate; + tod_diff_cnt += 1000000 - (1000000 / rate) * rate; + tod_hack_tv += tod_diff_cnt / rate; + tod_diff_cnt %= rate; + docount = 1; + } + if (docount) { + ciaatod++; + ciaatod &= 0x00ffffff; + tod_hack_tod_last = ciaatod; + ciaa_checkalarm(false); + } +} + +static int resetwarning_phase, resetwarning_timer; + +static void setcode(uae_u8 keycode) +{ + kbcode = ~((keycode << 1) | (keycode >> 7)); +} + +static void sendrw(void) +{ + setcode(AK_RESETWARNING); ciaasdr = kbcode; kblostsynccnt = 8 * maxvpos * 8; // 8 frames * 8 bits. ciaaicr |= 8; - RethinkICRA (); + RethinkICRA(); + write_log(_T("KB: sent reset warning code (phase=%d)\n"), resetwarning_phase); } -void CIA_hsync_posthandler (void) +int resetwarning_do(int canreset) { - if (ciabtodon) { - ciabtod++; - ciabtod &= 0xFFFFFF; - ciab_checkalarm (1); - } - - if ((keys_available() || kbstate < 3) && !kblostsynccnt && (hsync_counter & 15) == 0) { - switch (kbstate) - { - case 0: - kbcode = 0; /* powerup resync */ - kbstate++; - break; - case 1: - setcode (AK_INIT_POWERUP); - kbstate++; - break; - case 2: - setcode (AK_TERM_POWERUP); - kbstate++; - break; - case 3: - kbcode = ~get_next_key (); - break; - } - keyreq (); + if (!currprefs.keyboard_connected) + return 0; + if (resetwarning_phase || regs.halted > 0) { + /* just force reset if second reset happens during resetwarning */ + if (canreset) { + resetwarning_phase = 0; + resetwarning_timer = 0; + } + return 0; } + resetwarning_phase = 1; + resetwarning_timer = maxvpos_nom * 5; + write_log(_T("KB: reset warning triggered\n")); + sendrw(); + return 1; } - -void CIA_vsync_prehandler (void) +static void resetwarning_check(void) { - CIA_handler (); - if (kblostsynccnt > 0) { - kblostsynccnt -= maxvpos; - if (kblostsynccnt <= 0) { + if (resetwarning_timer > 0) { + resetwarning_timer--; + if (resetwarning_timer <= 0) { + write_log(_T("KB: reset warning forced reset. Phase=%d\n"), resetwarning_phase); + resetwarning_phase = -1; kblostsynccnt = 0; - keyreq (); + //send_internalevent(INTERNALEVENT_KBRESET); + uae_reset(0, 1); + } + } + if (resetwarning_phase == 1) { + if (!kblostsynccnt) { /* first AK_RESETWARNING handshake received */ + write_log(_T("KB: reset warning second phase..\n")); + resetwarning_phase = 2; + resetwarning_timer = maxvpos_nom * 5; + sendrw(); + } + } + else if (resetwarning_phase == 2) { + if (ciaacra & 0x40) { /* second AK_RESETWARNING handshake active */ + resetwarning_phase = 3; + write_log(_T("KB: reset warning SP = output\n")); + /* System won't reset until handshake signal becomes inactive or 10s has passed */ + resetwarning_timer = 10 * maxvpos_nom * vblank_hz; + } + } + else if (resetwarning_phase == 3) { + if (!(ciaacra & 0x40)) { /* second AK_RESETWARNING handshake disabled */ + write_log(_T("KB: reset warning end by software. reset.\n")); + resetwarning_phase = -1; + kblostsynccnt = 0; + //send_internalevent(INTERNALEVENT_KBRESET); + uae_reset(0, 1); } } } -void CIA_vsync_posthandler (void) +void CIA_hsync_prehandler(void) +{ +} + +static void keyreq(void) +{ +#if KB_DEBUG + write_log(_T("code=%02x (%02x)\n"), kbcode, (uae_u8)(~((kbcode >> 1) | (kbcode << 7)))); +#endif + ciaasdr = kbcode; + kblostsynccnt = 8 * maxvpos * 8; // 8 frames * 8 bits. + ciaaicr |= 8; + RethinkICRA(); +} + +/* All this complexity to lazy evaluate TOD increase. +* Only increase it cycle-exactly if it is visible to running program: +* causes interrupt or program is reading or writing TOD registers +*/ + +static int ciab_tod_hoffset; +static int ciab_tod_event_state; +// TOD increase has extra 14-16 E-clock delay +// Possibly TICK input pin has built-in debounce circuit +#define TOD_INC_DELAY (14 * (ECLOCK_DATA_CYCLE + ECLOCK_WAIT_CYCLE) / 2) + +static void CIAB_tod_inc(bool irq) +{ + ciab_tod_event_state = 3; // done + if (!ciabtodon) + return; + ciabtod++; + ciabtod &= 0xFFFFFF; + ciab_checkalarm(true, irq); +} + +static void CIAB_tod_inc_event(uae_u32 v) +{ + if (ciab_tod_event_state != 2) + return; + CIAB_tod_inc(true); +} + +// Someone reads or writes TOD registers, sync TOD increase +static void CIAB_tod_check(void) +{ + if (ciab_tod_event_state != 1 || !ciabtodon) + return; + int hpos = current_hpos(); + hpos -= ciab_tod_hoffset; + if (hpos >= 0 || currprefs.m68k_speed < 0) { + // Program should see the changed TOD + CIAB_tod_inc(true); + return; + } + // Not yet, add event to guarantee exact TOD inc position + ciab_tod_event_state = 2; // event active + event2_newevent_xx(-1, -hpos, 0, CIAB_tod_inc_event); +} + +void CIAB_tod_handler(int hoffset) +{ + if (!ciabtodon) + return; + ciab_tod_hoffset = hoffset + TOD_INC_DELAY; + ciab_tod_event_state = 1; // TOD inc needed + if (checkalarm((ciabtod + 1) & 0xffffff, ciabalarm, true, 1)) { + // causes interrupt on this line, add event + ciab_tod_event_state = 2; // event active + event2_newevent_xx(-1, ciab_tod_hoffset, 0, CIAB_tod_inc_event); + } +} + +void keyboard_connected(bool connect) +{ + if (connect) { + write_log(_T("Keyboard connected\n")); + } + else { + write_log(_T("Keyboard disconnected\n")); + } + kbstate = 0; + kblostsynccnt = 0; + resetwarning_phase = 0; +} + +static void check_keyboard(void) +{ + if (currprefs.keyboard_connected) { + if ((keys_available() || kbstate < 3) && !kblostsynccnt) { + switch (kbstate) + { + case 0: + kbcode = 0; /* powerup resync */ + kbstate++; + break; + case 1: + setcode(AK_INIT_POWERUP); + kbstate++; + break; + case 2: + setcode(AK_TERM_POWERUP); + kbstate++; + break; + case 3: + kbcode = ~get_next_key(); + break; + } + keyreq(); + } + } + else { + while (keys_available()) { + get_next_key(); + } + } +} + +void CIA_hsync_posthandler(bool ciahsync, bool dotod) +{ + if (ciahsync) { + // cia hysnc + // Previous line was supposed to increase TOD but + // no one cared. Do it now. + if (ciab_tod_event_state == 1) + CIAB_tod_inc(false); + ciab_tod_event_state = 0; + + if (currprefs.tod_hack && ciaatodon) + do_tod_hack(dotod); + } + else if (currprefs.keyboard_connected) { + // custom hsync + if (resetwarning_phase) { + resetwarning_check(); + while (keys_available()) + get_next_key(); + } + else { + if ((hsync_counter & 15) == 0) + check_keyboard(); + } + } + else { + while (keys_available()) { + get_next_key(); + } + } +} + +static void calc_led(int old_led) +{ + unsigned long c = get_cycles(); + unsigned long t = (c - led_cycle) / CYCLE_UNIT; + if (old_led) + led_cycles_on += t; + else + led_cycles_off += t; + led_cycle = c; +} + +static void led_vsync(void) +{ + int v; + + calc_led(led); + if (led_cycles_on && !led_cycles_off) + v = 255; + else if (led_cycles_off && !led_cycles_on) + v = 0; + else if (led_cycles_off) + v = led_cycles_on * 255 / (led_cycles_on + led_cycles_off); + else + v = 255; + if (v < 0) + v = 0; + if (v > 255) + v = 255; + gui_data.powerled_brightness = v; + led_cycles_on = 0; + led_cycles_off = 0; + if (led_old_brightness != gui_data.powerled_brightness) { + gui_data.powerled = gui_data.powerled_brightness > 127; + //gui_led(LED_POWER, gui_data.powerled, gui_data.powerled_brightness); + gui_led(LED_POWER, gui_data.powerled); + led_filter_audio(); + } + led_old_brightness = gui_data.powerled_brightness; + led_cycle = get_cycles(); +} + +static void write_battclock(void); +void CIA_vsync_prehandler(void) +{ + if (heartbeat_cnt > 0) + heartbeat_cnt--; + if (rtc_delayed_write < 0) { + rtc_delayed_write = 50; + } + else if (rtc_delayed_write > 0) { + rtc_delayed_write--; + if (rtc_delayed_write == 0) + write_battclock(); + } + led_vsync(); + CIA_handler(); + if (kblostsynccnt > 0) { + kblostsynccnt -= maxvpos; + if (kblostsynccnt <= 0) { + kblostsynccnt = 0; + keyreq(); +#if KB_DEBUG + write_log(_T("lostsync\n")); +#endif + } + } +} + +static void CIAA_tod_handler(uae_u32 v) +{ + ciaatod++; + ciaatod &= 0xFFFFFF; + ciaa_checkalarm(true); +} + +void CIAA_tod_inc(int cycles) { #ifdef TOD_HACK - if (currprefs.tod_hack && ciaatodon) { - struct timeval tv; - uae_u32 t, nt, rate = vblank_hz; - if (tod_hack_delay > 0) { - tod_hack_delay--; - if (tod_hack_delay == 0) { - tod_hack_reset (); - tod_hack_delay = 0; - write_log (_T("TOD_HACK re-initialized CIATOD=%06X\n"), ciaatod); - } - } - if (tod_hack_delay == 0) { - gettimeofday (&tv, NULL); - t = (uae_u32)(((uae_u64)tv.tv_sec) * rate + tv.tv_usec / (1000000 / rate)); - nt = t - tod_hack; - if ((nt < ciaatod && ciaatod - nt < 10) || nt == ciaatod) - return; /* try not to count backwards */ - ciaatod = nt; - ciaatod &= 0xffffff; - ciaa_checkalarm (0); - return; - } - } + if (currprefs.tod_hack && tod_hack_enabled == 1) + return; #endif - if (ciaatodon) { - ciaatod++; - ciaatod &= 0xFFFFFF; - ciaa_checkalarm (1); - } + if (!ciaatodon) + return; + event2_newevent_xx(-1, cycles + TOD_INC_DELAY, 0, CIAA_tod_handler); } -STATIC_INLINE void check_led (void) +static void check_led(void) { - uae_u8 v = ciaapra; - bool led2; + uae_u8 v = ciaapra; + bool led2; - v |= ~ciaadra; /* output is high when pin's direction is input */ - led2 = (v & 2) ? 0 : 1; - if (led2 != led) { - led = led2; - gui_data.powerled = led2; - led_filter_audio(); - } + v |= ~ciaadra; /* output is high when pin's direction is input */ + led2 = (v & 2) ? 0 : 1; + if (led2 != led) { + calc_led(led); + led = led2; + led_old_brightness = -1; + } } -static void bfe001_change (void) +static void bfe001_change(void) { - uae_u8 v = ciaapra; - check_led (); - if (!(aga_mode) && (v & 1) != oldovl) { - oldovl = v & 1; - if (!oldovl) { - map_overlay (1); - } else { - map_overlay (0); - } - } + uae_u8 v = ciaapra; + check_led(); + if (currprefs.cs_ciaoverlay && (v & 1) != oldovl) { + oldovl = v & 1; + if (!oldovl) { + map_overlay(1); + } + else { + //activate_debugger (); + map_overlay(0); + } + } if (currprefs.cs_cd32cd && (v & 1) != oldcd32mute) { oldcd32mute = v & 1; - akiko_mute (oldcd32mute ? 0 : 1); + akiko_mute(oldcd32mute ? 0 : 1); } } +static uae_u32 getciatod(uae_u32 tod) +{ + if (!currprefs.cs_cia6526) + return tod; + uae_u32 bcdtod = 0; + for (int i = 0; i < 4; i++) { + int val = tod % 10; + bcdtod *= 16; + bcdtod += val; + tod /= 10; + } + return bcdtod; +} +static void setciatod(unsigned long *tod, uae_u32 v) +{ + if (!currprefs.cs_cia6526) { + *tod = v; + return; + } + uae_u32 bintod = 0; + for (int i = 0; i < 4; i++) { + int val = v / 16; + bintod *= 10; + bintod += val; + v /= 16; + } + *tod = bintod; +} + static uae_u8 ReadCIAA (unsigned int addr) { unsigned int tmp; @@ -708,246 +1177,385 @@ static uae_u8 ReadCIAB (unsigned int addr) return 0; } -static void WriteCIAA (uae_u16 addr,uae_u8 val) +static void WriteCIAA(uae_u16 addr, uae_u8 val) { int reg = addr & 15; - if ((aga_mode) && oldovl) { - map_overlay (1); - oldovl = 0; - } - switch (reg) { - case 0: - ciaapra = (ciaapra & ~0xc3) | (val & 0xc3); - bfe001_change (); - handle_cd32_joystick_cia (ciaapra, ciaadra); - break; - case 1: - ciaaprb = val; - break; - case 2: - ciaadra = val; - bfe001_change (); - break; - case 3: - ciaadrb = val; - break; - case 4: - CIA_update (); - ciaala = (ciaala & 0xff00) | val; - CIA_calctimers (); - break; - case 5: - CIA_update (); - ciaala = (ciaala & 0xff) | (val << 8); - if ((ciaacra & 1) == 0) - ciaata = ciaala; - if (ciaacra & 8) { - ciaata = ciaala; - ciaacra |= 1; - ciaastarta = CIASTARTCYCLESHI; - } - CIA_calctimers (); - break; - case 6: - CIA_update (); - ciaalb = (ciaalb & 0xff00) | val; - CIA_calctimers (); - break; - case 7: - CIA_update (); - ciaalb = (ciaalb & 0xff) | (val << 8); - if ((ciaacrb & 1) == 0) - ciaatb = ciaalb; - if (ciaacrb & 8) { - ciaatb = ciaalb; - ciaacrb |= 1; - ciaastartb = CIASTARTCYCLESHI; - } - CIA_calctimers (); - break; - case 8: - if (ciaacrb & 0x80) { - ciaaalarm = (ciaaalarm & ~0xff) | val; - } else { - ciaatod = (ciaatod & ~0xff) | val; - ciaatodon = 1; - ciaa_checkalarm (false); -#ifdef TOD_HACK - if (currprefs.tod_hack) - tod_hack_reset (); +#if CIAA_DEBUG_W > 0 + write_log(_T("W_CIAA: bfe%x01 %02X %08X\n"), reg, val, M68K_GETPC); #endif - } - break; - case 9: - if (ciaacrb & 0x80) { - ciaaalarm = (ciaaalarm & ~0xff00) | (val << 8); - } else { - ciaatod = (ciaatod & ~0xff00) | (val << 8); - } - break; - case 10: - if (ciaacrb & 0x80) { - ciaaalarm = (ciaaalarm & ~0xff0000) | (val << 16); - } else { - ciaatod = (ciaatod & ~0xff0000) | (val << 16); - ciaatodon = 0; - } - break; - case 12: - CIA_update (); - ciaasdr = val; - if ((ciaacra & 0x41) == 0x41 && ciaasdr_cnt == 0) - ciaasdr_cnt = 8 * 2; - CIA_calctimers (); - break; - case 13: - setclr(&ciaaimask,val); - RethinkICRA (); - break; - case 14: - CIA_update (); - val &= 0x7f; /* bit 7 is unused */ - if ((val & 1) && !(ciaacra & 1)) - ciaastarta = CIASTARTCYCLESCRA; - if ((val & 0x40) == 0 && (ciaacra & 0x40) != 0) { - /* todo: check if low to high or high to low only */ - kblostsynccnt = 0; - } - ciaacra = val; - if (ciaacra & 0x10) { - ciaacra &= ~0x10; - ciaata = ciaala; - } - CIA_calctimers (); - break; - case 15: - CIA_update (); - if ((val & 1) && !(ciaacrb & 1)) - ciaastartb = CIASTARTCYCLESCRA; - ciaacrb = val; - if (ciaacrb & 0x10) { - ciaacrb &= ~0x10; - ciaatb = ciaalb; - } - CIA_calctimers (); - break; - } +#ifdef ACTION_REPLAY + ar_ciaa[reg] = val; +#endif + if (!currprefs.cs_ciaoverlay && oldovl) { + map_overlay(1); + oldovl = 0; + } + switch (reg) { + case 0: +#if DONGLE_DEBUG > 0 + if (notinrom()) + write_log(_T("BFE001 W %02X %s\n"), val, debuginfo(0)); +#endif + ciaapra = (ciaapra & ~0xc3) | (val & 0xc3); + bfe001_change(); + handle_cd32_joystick_cia(ciaapra, ciaadra); + //dongle_cia_write(0, reg, val); +#ifdef AMAX + if (is_device_rom(&currprefs, ROMTYPE_AMAX, 0) > 0) + amax_bfe001_write(val, ciaadra); +#endif + break; + case 1: +#if DONGLE_DEBUG > 0 + if (notinrom()) + write_log(_T("BFE101 W %02X %s\n"), val, debuginfo(0)); +#endif + ciaaprb = val; + //dongle_cia_write(0, reg, val); +#ifdef PARALLEL_PORT + if (isprinter() > 0) { + doprinter(val); + cia_parallelack(); + } + else if (isprinter() < 0) { + parallel_direct_write_data(val, ciaadrb); + cia_parallelack(); +#ifdef ARCADIA + } + else if (arcadia_bios) { + arcadia_parport(1, ciaaprb, ciaadrb); +#endif + } + else if (parallel_port_scsi) { + parallel_port_scsi_write(0, ciaaprb, ciaadrb); + } +#endif + break; + case 2: +#if DONGLE_DEBUG > 0 + if (notinrom()) + write_log(_T("BFE201 W %02X %s\n"), val, debuginfo(0)); +#endif + ciaadra = val; + //dongle_cia_write(0, reg, val); + bfe001_change(); + break; + case 3: + ciaadrb = val; + //dongle_cia_write(0, reg, val); +#if DONGLE_DEBUG > 0 + if (notinrom()) + write_log(_T("BFE301 W %02X %s\n"), val, debuginfo(0)); +#endif +#ifdef ARCADIA + if (arcadia_bios) + arcadia_parport(1, ciaaprb, ciaadrb); +#endif + break; + case 4: + CIA_update(); + ciaala = (ciaala & 0xff00) | val; + CIA_calctimers(); + break; + case 5: + CIA_update(); + ciaala = (ciaala & 0xff) | (val << 8); + if ((ciaacra & 1) == 0) + ciaata = ciaala; + if (ciaacra & 8) { + ciaata = ciaala; + ciaacra |= 1; + ciaastarta = CIASTARTCYCLESHI; + } + CIA_calctimers(); + break; + case 6: + CIA_update(); + ciaalb = (ciaalb & 0xff00) | val; + CIA_calctimers(); + break; + case 7: + CIA_update(); + ciaalb = (ciaalb & 0xff) | (val << 8); + if ((ciaacrb & 1) == 0) + ciaatb = ciaalb; + if (ciaacrb & 8) { + ciaatb = ciaalb; + ciaacrb |= 1; + ciaastartb = CIASTARTCYCLESHI; + } + CIA_calctimers(); + break; + case 8: + if (ciaacrb & 0x80) { + setciatod(&ciaaalarm, (getciatod(ciaaalarm) & ~0xff) | val); + } + else { + setciatod(&ciaatod, (getciatod(ciaatod) & ~0xff) | val); + ciaatodon = 1; + ciaa_checkalarm(false); + } + break; + case 9: + if (ciaacrb & 0x80) { + setciatod(&ciaaalarm, (getciatod(ciaaalarm) & ~0xff00) | (val << 8)); + } + else { + setciatod(&ciaatod, (getciatod(ciaatod) & ~0xff00) | (val << 8)); + } + break; + case 10: + if (ciaacrb & 0x80) { + setciatod(&ciaaalarm, (getciatod(ciaaalarm) & ~0xff0000) | (val << 16)); + } + else { + setciatod(&ciaatod, (getciatod(ciaatod) & ~0xff0000) | (val << 16)); + if (!currprefs.cs_cia6526) + ciaatodon = 0; + } + break; + case 11: + if (currprefs.cs_cia6526) { + if (ciaacrb & 0x80) { + setciatod(&ciaaalarm, (getciatod(ciaaalarm) & ~0xff000000) | (val << 24)); + } + else { + setciatod(&ciaatod, (getciatod(ciaatod) & ~0xff000000) | (val << 24)); + ciaatodon = 0; + } + } + break; + case 12: + CIA_update(); + ciaasdr = val; + if ((ciaacra & 0x41) == 0x41 && ciaasdr_cnt == 0) + ciaasdr_cnt = 8 * 2; +#if KB_DEBUG + write_log(_T("CIAA serial port write: %02x cnt=%d PC=%08x\n"), ciaasdr, ciaasdr_cnt, M68K_GETPC); +#endif + CIA_calctimers(); + break; + case 13: + setclr(&ciaaimask, val); + RethinkICRA(); + break; + case 14: + CIA_update(); + val &= 0x7f; /* bit 7 is unused */ + if ((val & 1) && !(ciaacra & 1)) + ciaastarta = CIASTARTCYCLESCRA; + //if (currprefs.cpuboard_type != 0 && (val & 0x40) != (ciaacra & 0x40)) { + // /* bleh, Phase5 CPU timed early boot key check fix.. */ + // if (m68k_getpc() >= 0xf00000 && m68k_getpc() < 0xf80000) + // check_keyboard(); + //} + if ((val & 0x40) == 0 && (ciaacra & 0x40) != 0) { + /* todo: check if low to high or high to low only */ + kblostsynccnt = 0; +#if KB_DEBUG + write_log(_T("KB_ACK %02x->%02x %08x\n"), ciaacra, val, M68K_GETPC); +#endif + } + ciaacra = val; + if (ciaacra & 0x10) { + ciaacra &= ~0x10; + ciaata = ciaala; + } + CIA_calctimers(); + break; + case 15: + CIA_update(); + if ((val & 1) && !(ciaacrb & 1)) + ciaastartb = CIASTARTCYCLESCRA; + ciaacrb = val; + if (ciaacrb & 0x10) { + ciaacrb &= ~0x10; + ciaatb = ciaalb; + } + CIA_calctimers(); + break; + } } -static void WriteCIAB (uae_u16 addr,uae_u8 val) +static void WriteCIAB(uae_u16 addr, uae_u8 val) { int reg = addr & 15; - switch (reg) { - case 0: - ciabpra = val; - break; - case 1: - ciabprb = val; - DISK_select(val); - break; - case 2: - ciabdra = val; - break; - case 3: - ciabdrb = val; - break; - case 4: - CIA_update (); - ciabla = (ciabla & 0xff00) | val; - CIA_calctimers (); - break; - case 5: - CIA_update (); - ciabla = (ciabla & 0xff) | (val << 8); - if ((ciabcra & 1) == 0) - ciabta = ciabla; - if (ciabcra & 8) { - ciabta = ciabla; - ciabcra |= 1; +#if CIAB_DEBUG_W > 0 + if (((addr >= 8 && addr <= 10) || addr == 15) || CIAB_DEBUG_W > 1) + write_log(_T("W_CIAB: bfd%x00 %02X %08X\n"), reg, val, M68K_GETPC); +#endif +#ifdef ACTION_REPLAY + ar_ciab[reg] = val; +#endif + switch (reg) { + case 0: +#if DONGLE_DEBUG > 0 + if (notinrom()) + write_log(_T("BFD000 W %02X %s\n"), val, debuginfo(0)); +#endif + //dongle_cia_write(1, reg, val); + ciabpra = val; +#ifdef SERIAL_PORT + if (currprefs.use_serial) + serial_writestatus(ciabpra, ciabdra); +#endif +#ifdef PARALLEL_PORT + if (isprinter() < 0) { + parallel_direct_write_status(val, ciabdra); + } + else if (parallel_port_scsi) { + parallel_port_scsi_write(1, ciabpra, ciabdra); + } +#endif + break; + case 1: +#ifdef ACTION_REPLAY + action_replay_cia_access(true); +#endif +#if DONGLE_DEBUG > 0 + if (notinrom()) + write_log(_T("BFD100 W %02X %s\n"), val, debuginfo(0)); +#endif + //dongle_cia_write(1, reg, val); + ciabprb = val; + DISK_select(val); + break; + case 2: +#if DONGLE_DEBUG > 0 + if (notinrom()) + write_log(_T("BFD200 W %02X %s\n"), val, debuginfo(0)); +#endif + //dongle_cia_write(1, reg, val); + ciabdra = val; +#ifdef SERIAL_PORT + if (currprefs.use_serial) + serial_writestatus(ciabpra, ciabdra); +#endif + break; + case 3: +#if DONGLE_DEBUG > 0 + if (notinrom()) + write_log(_T("BFD300 W %02X %s\n"), val, debuginfo(0)); +#endif + //dongle_cia_write(1, reg, val); + ciabdrb = val; + break; + case 4: + CIA_update(); + ciabla = (ciabla & 0xff00) | val; + CIA_calctimers(); + break; + case 5: + CIA_update(); + ciabla = (ciabla & 0xff) | (val << 8); + if ((ciabcra & 1) == 0) + ciabta = ciabla; + if (ciabcra & 8) { + ciabta = ciabla; + ciabcra |= 1; ciabstarta = CIASTARTCYCLESHI; - } - CIA_calctimers (); - break; - case 6: - CIA_update (); - ciablb = (ciablb & 0xff00) | val; - CIA_calctimers (); - break; - case 7: - CIA_update (); - ciablb = (ciablb & 0xff) | (val << 8); - if ((ciabcrb & 1) == 0) - ciabtb = ciablb; - if (ciabcrb & 8) { - ciabtb = ciablb; - ciabcrb |= 1; + } + CIA_calctimers(); + break; + case 6: + CIA_update(); + ciablb = (ciablb & 0xff00) | val; + CIA_calctimers(); + break; + case 7: + CIA_update(); + ciablb = (ciablb & 0xff) | (val << 8); + if ((ciabcrb & 1) == 0) + ciabtb = ciablb; + if (ciabcrb & 8) { + ciabtb = ciablb; + ciabcrb |= 1; ciabstartb = CIASTARTCYCLESHI; - } - CIA_calctimers (); - break; - case 8: - if (ciabcrb & 0x80) { - ciabalarm = (ciabalarm & ~0xff) | val; - } else { - ciabtod = (ciabtod & ~0xff) | val; - ciabtodon = 1; - ciab_checkalarm (false); - } - break; - case 9: - if (ciabcrb & 0x80) { - ciabalarm = (ciabalarm & ~0xff00) | (val << 8); - } else { - ciabtod = (ciabtod & ~0xff00) | (val << 8); - } - break; - case 10: - if (ciabcrb & 0x80) { - ciabalarm = (ciabalarm & ~0xff0000) | (val << 16); - } else { - ciabtod = (ciabtod & ~0xff0000) | (val << 16); - ciabtodon = 0; - } - break; - case 12: - CIA_update (); - ciabsdr = val; - if ((ciabcra & 0x40) == 0) - ciabsdr_cnt = 0; - if ((ciabcra & 0x41) == 0x41 && ciabsdr_cnt == 0) - ciabsdr_cnt = 8 * 2; - CIA_calctimers (); - break; - case 13: - setclr(&ciabimask,val); - RethinkICRB (); - break; - case 14: - CIA_update (); - val &= 0x7f; /* bit 7 is unused */ - if ((val & 1) && !(ciabcra & 1)) - ciabstarta = CIASTARTCYCLESCRA; - ciabcra = val; - if (ciabcra & 0x10) { - ciabcra &= ~0x10; - ciabta = ciabla; - } - CIA_calctimers (); - break; - case 15: - CIA_update (); - if ((val & 1) && !(ciabcrb & 1)) - ciabstartb = CIASTARTCYCLESCRA; - ciabcrb = val; - if (ciabcrb & 0x10) { - ciabcrb &= ~0x10; - ciabtb = ciablb; - } - CIA_calctimers (); - break; - } + } + CIA_calctimers(); + break; + case 8: + CIAB_tod_check(); + if (ciabcrb & 0x80) { + setciatod(&ciabalarm, (getciatod(ciabalarm) & ~0xff) | val); + } + else { + setciatod(&ciabtod, (getciatod(ciabtod) & ~0xff) | val); + ciabtodon = 1; + ciab_checkalarm(false, true); + } + break; + case 9: + CIAB_tod_check(); + if (ciabcrb & 0x80) { + setciatod(&ciabalarm, (getciatod(ciabalarm) & ~0xff00) | (val << 8)); + } + else { + setciatod(&ciabtod, (getciatod(ciabtod) & ~0xff00) | (val << 8)); + } + break; + case 10: + CIAB_tod_check(); + if (ciabcrb & 0x80) { + setciatod(&ciabalarm, (getciatod(ciabalarm) & ~0xff0000) | (val << 16)); + } + else { + setciatod(&ciabtod, (getciatod(ciabtod) & ~0xff0000) | (val << 16)); + if (!currprefs.cs_cia6526) + ciabtodon = 0; + } + break; + case 11: + if (currprefs.cs_cia6526) { + CIAB_tod_check(); + if (ciabcrb & 0x80) { + setciatod(&ciabalarm, (getciatod(ciabalarm) & ~0xff000000) | (val << 24)); + } + else { + setciatod(&ciabtod, (getciatod(ciabtod) & ~0xff000000) | (val << 24)); + ciabtodon = 0; + } + } + break; + case 12: + CIA_update(); + ciabsdr = val; + if ((ciabcra & 0x40) == 0) + ciabsdr_cnt = 0; + if ((ciabcra & 0x41) == 0x41 && ciabsdr_cnt == 0) + ciabsdr_cnt = 8 * 2; + CIA_calctimers(); + break; + case 13: + setclr(&ciabimask, val); + RethinkICRB(); + break; + case 14: + CIA_update(); + val &= 0x7f; /* bit 7 is unused */ + if ((val & 1) && !(ciabcra & 1)) + ciabstarta = CIASTARTCYCLESCRA; + ciabcra = val; + if (ciabcra & 0x10) { + ciabcra &= ~0x10; + ciabta = ciabla; + } + CIA_calctimers(); + break; + case 15: + CIA_update(); + if ((val & 1) && !(ciabcrb & 1)) + ciabstartb = CIASTARTCYCLESCRA; + ciabcrb = val; + if (ciabcrb & 0x10) { + ciabcrb &= ~0x10; + ciabtb = ciablb; + } + CIA_calctimers(); + break; + } } void cia_set_overlay (bool overlay) @@ -955,80 +1563,89 @@ void cia_set_overlay (bool overlay) oldovl = overlay; } -/* CIA memory access */ - -static uae_u32 REGPARAM3 cia_lget (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 cia_wget (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 cia_bget (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 cia_bget_compatible (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 cia_lgeti (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 cia_wgeti (uaecptr) REGPARAM; -static void REGPARAM3 cia_lput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 cia_wput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 cia_bput (uaecptr, uae_u32) REGPARAM; - -addrbank cia_bank = { - cia_lget, cia_wget, cia_bget, - cia_lput, cia_wput, cia_bput, - default_xlate, default_check, NULL, _T("CIA"), - cia_lgeti, cia_wgeti, ABFLAG_IO, 0x3f01, 0xbfc000 -}; - -void CIA_reset (void) +void CIA_reset(void) { - if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) - cia_bank.bget = cia_bget_compatible; - else - cia_bank.bget = cia_bget; - #ifdef TOD_HACK - tod_hack = 0; - if (currprefs.tod_hack) - tod_hack_reset (); + tod_hack_tv = 0; + tod_hack_tod = 0; + tod_hack_enabled = 0; + if (currprefs.tod_hack) + tod_hack_enabled = TOD_HACK_TIME; #endif - kblostsynccnt = 0; - oldcd32mute = 1; - if (!savestate_state) { + kblostsynccnt = 0; + serbits = 0; + oldcd32mute = 1; + resetwarning_phase = resetwarning_timer = 0; + heartbeat_cnt = 0; + ciab_tod_event_state = 0; + + if (!savestate_state) { oldovl = true; - kbstate = 0; - ciaatlatch = ciabtlatch = 0; - ciaapra = 0; ciaadra = 0; - ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0; - ciaaicr = ciabicr = ciaaimask = ciabimask = 0; - ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; /* outmode = toggle; */ - ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF; - ciaaalarm = ciabalarm = 0; - ciabpra = 0x8C; ciabdra = 0; - div10 = 0; - ciaasdr_cnt = 0; ciaasdr = 0; - ciabsdr_cnt = 0; ciabsdr = 0; - ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0; - ciaatol = ciabtol = ciaaprb = ciaadrb = ciabprb = ciabdrb = 0; - CIA_calctimers (); - DISK_select_set (ciabprb); - } - map_overlay (0); - check_led (); - if (savestate_state) { - if (!(aga_mode)) { + kbstate = 0; + ciaatlatch = ciabtlatch = 0; + ciaapra = 0; ciaadra = 0; + ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0; + ciaaicr = ciabicr = ciaaimask = ciabimask = 0; + ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; /* outmode = toggle; */ + ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF; + ciaaalarm = ciabalarm = 0; + ciabpra = 0x8C; ciabdra = 0; + div10 = 0; + ciaasdr_cnt = 0; ciaasdr = 0; + ciabsdr_cnt = 0; ciabsdr = 0; + ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0; + CIA_calctimers(); + DISK_select_set(ciabprb); + } + map_overlay(0); + check_led(); +#ifdef SERIAL_PORT + if (currprefs.use_serial && !savestate_state) + serial_dtr_off(); /* Drop DTR at reset */ +#endif + if (savestate_state) { + if (currprefs.cs_ciaoverlay) { oldovl = true; } - bfe001_change (); - if (aga_mode) { - map_overlay (oldovl ? 0 : 1); + bfe001_change(); + if (!currprefs.cs_ciaoverlay) { + map_overlay(oldovl ? 0 : 1); } - } + } #ifdef CD32 - if (!isrestore ()) { - akiko_reset (); - if (!akiko_init ()) + if (!isrestore()) { + akiko_reset(); + if (!akiko_init()) currprefs.cs_cd32cd = changed_prefs.cs_cd32cd = 0; } #endif } -static void cia_wait_pre (void) +void dumpcia(void) +{ + write_log(_T("A: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)\n"), + ciaacra, ciaacrb, ciaaicr, ciaaimask, ciaata, ciaala, ciaatb, ciaalb); + write_log(_T("TOD %06x (%06x) ALARM %06x %c%c CYC=%08X\n"), + ciaatod, ciaatol, ciaaalarm, ciaatlatch ? 'L' : ' ', ciaatodon ? ' ' : 'S', get_cycles()); + write_log(_T("B: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)\n"), + ciabcra, ciabcrb, ciabicr, ciabimask, ciabta, ciabla, ciabtb, ciablb); + write_log(_T("TOD %06x (%06x) ALARM %06x %c%c CLK=%d\n"), + ciabtod, ciabtol, ciabalarm, ciabtlatch ? 'L' : ' ', ciabtodon ? ' ' : 'S', div10 / CYCLE_UNIT); +} + +/* CIA memory access */ + +DECLARE_MEMORY_FUNCTIONS(cia); +addrbank cia_bank = { + cia_lget, cia_wget, cia_bget, + cia_lput, cia_wput, cia_bput, + default_xlate, default_check, NULL, NULL, _T("CIA"), + cia_lgeti, cia_wgeti, + ABFLAG_IO | ABFLAG_CIA, S_READ, S_WRITE, NULL, 0x3f01, 0xbfc000 +}; + +static void cia_wait_pre(int cianummask) { if (currprefs.cachesize) return; @@ -1037,19 +1654,21 @@ static void cia_wait_pre (void) int cycles; if (div >= DIV10 * ECLOCK_DATA_CYCLE / 10) { - cycles = DIV10 - div; + cycles = DIV10 - div; cycles += DIV10 * ECLOCK_DATA_CYCLE / 10; - } else if (div) { - cycles = DIV10 + DIV10 * ECLOCK_DATA_CYCLE / 10 - div; - } else { + } + else if (div) { + cycles = DIV10 + DIV10 * ECLOCK_DATA_CYCLE / 10 - div; + } + else { cycles = DIV10 * ECLOCK_DATA_CYCLE / 10 - div; } - if (cycles) { - do_cycles (cycles); + if (cycles) { + do_cycles(cycles); } } -static void cia_wait_post (uae_u32 value) +static void cia_wait_post(int cianummask, uae_u32 value) { if (currprefs.cachesize) { do_cycles (8 * CYCLE_UNIT / 2); @@ -1059,485 +1678,741 @@ static void cia_wait_post (uae_u32 value) } } -static uae_u32 REGPARAM2 cia_bget_compatible (uaecptr addr) +// Gayle or Fat Gary does not enable CIA /CS lines if both CIAs are selected +// Old Gary based Amigas enable both CIAs in this situation + +STATIC_INLINE bool issinglecia(void) +{ + return currprefs.cs_ide || currprefs.cs_pcmcia || currprefs.cs_mbdmac || currprefs.cs_cd32cd; +} +STATIC_INLINE bool isgayle(void) +{ + return currprefs.cs_ide || currprefs.cs_pcmcia; +} + +// Gayle CIA select +STATIC_INLINE bool iscia(uaecptr addr) +{ + uaecptr mask = addr & 0xf000; + return mask == 0xe000 || mask == 0xd000; +} + +static bool isgaylenocia(uaecptr addr) +{ + if (!isgayle()) + return true; + // gayle CIA region is only 4096 bytes at 0xbfd000 and 0xbfe000 + return iscia(addr); +} + +static bool isgarynocia(uaecptr addr) +{ + return !iscia(addr) && currprefs.cs_fatgaryrev >= 0; +} + +static int cia_chipselect(uaecptr addr) +{ + int cs = (addr >> 12) & 3; + if (currprefs.cs_cd32cd) { + // Unexpected Akiko CIA select: + // 0,1 = CIA-A + if (cs == 0) + cs = 1; + // 2,3 = CIA-B + if (cs == 3) + cs = 2; + } + return cs; +} + +static uae_u32 REGPARAM2 cia_bget(uaecptr addr) { int r = (addr & 0xf00) >> 8; - uae_u8 v; + uae_u8 v = 0; -#ifdef JIT - special_mem |= S_READ; -#endif + if (isgarynocia(addr)) + return dummy_get(addr, 1, false, 0); - cia_wait_pre (); - switch ((addr >> 12) & 3) { - case 0: - v = (addr & 1) ? ReadCIAA (r) : ReadCIAB (r); - break; - case 1: - v = (addr & 1) ? regs.irc : ReadCIAB (r); - break; - case 2: - v = (addr & 1) ? ReadCIAA (r) : regs.irc >> 8; - break; + if (!isgaylenocia(addr)) + return dummy_get(addr, 1, false, 0); + + switch (cia_chipselect(addr)) + { + case 0: + if (!issinglecia()) { + cia_wait_pre(1 | 2); + v = (addr & 1) ? ReadCIAA(r) : ReadCIAB(r); + cia_wait_post(1 | 2, v); + } + break; + case 1: + cia_wait_pre(2); + if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) { + v = (addr & 1) ? regs.irc : ReadCIAB(r); + } + else { + v = (addr & 1) ? dummy_get(addr, 1, false, 0) : ReadCIAB(r); + } + cia_wait_post(2, v); + break; + case 2: + cia_wait_pre(1); + if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) + v = (addr & 1) ? ReadCIAA(r) : regs.irc >> 8; + else + v = (addr & 1) ? ReadCIAA(r) : dummy_get(addr, 1, false, 0); + cia_wait_post(1, v); + break; case 3: - v = (addr & 1) ? regs.irc : regs.irc >> 8; - break; - } - cia_wait_post (v); + if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) { + cia_wait_pre(0); + v = (addr & 1) ? regs.irc : regs.irc >> 8; + cia_wait_post(0, v); + } + if (warned > 0 || currprefs.illegal_mem) { + write_log(_T("cia_bget: unknown CIA address %08X=%02X PC=%08X\n"), addr, v & 0xff, M68K_GETPC); + warned--; + } + break; + } - return v; + return v; } -static uae_u32 REGPARAM2 cia_bget (uaecptr addr) +static uae_u32 REGPARAM2 cia_wget(uaecptr addr) { int r = (addr & 0xf00) >> 8; - uae_u8 v; + uae_u16 v = 0; -#ifdef JIT - special_mem |= S_READ; -#endif + if (isgarynocia(addr)) + return dummy_get(addr, 2, false, 0); - switch ((addr >> 12) & 3) { - case 0: - cia_wait_pre (); - v = (addr & 1) ? ReadCIAA (r) : ReadCIAB (r); - cia_wait_post (v); - break; - case 1: - cia_wait_pre (); - v = (addr & 1) ? 0xff : ReadCIAB (r); - cia_wait_post (v); - break; - case 2: - cia_wait_pre (); - v = (addr & 1) ? ReadCIAA (r) : 0xff; - cia_wait_post (v); - break; + if (!isgaylenocia(addr)) + return dummy_get(addr, 2, false, 0); + + switch (cia_chipselect(addr)) + { + case 0: + if (!issinglecia()) + { + cia_wait_pre(1 | 2); + v = (ReadCIAB(r) << 8) | ReadCIAA(r); + cia_wait_post(1 | 2, v); + } + break; + case 1: + cia_wait_pre(2); + v = (ReadCIAB(r) << 8) | dummy_get(addr, 1, false, 0); + cia_wait_post(2, v); + break; + case 2: + cia_wait_pre(1); + v = (dummy_get(addr, 1, false, 0) << 8) | ReadCIAA(r); + cia_wait_post(1, v); + break; case 3: - v = 0xff; - break; - } - - return v; + if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) { + cia_wait_pre(0); + v = regs.irc; + cia_wait_post(0, v); + } + if (warned > 0 || currprefs.illegal_mem) { + write_log(_T("cia_wget: unknown CIA address %08X=%04X PC=%08X\n"), addr, v & 0xffff, M68K_GETPC); + warned--; + } + break; + } + return v; } -static uae_u32 REGPARAM2 cia_wget (uaecptr addr) +static uae_u32 REGPARAM2 cia_lget(uaecptr addr) +{ + uae_u32 v; + v = cia_wget(addr) << 16; + v |= cia_wget(addr + 2); + return v; +} + +static uae_u32 REGPARAM2 cia_wgeti(uaecptr addr) +{ + if (currprefs.cpu_model >= 68020) + return dummy_wgeti(addr); + return cia_wget(addr); +} +static uae_u32 REGPARAM2 cia_lgeti(uae_u32 addr) +{ + if (currprefs.cpu_model >= 68020) + return dummy_lgeti(addr); + return cia_lget(addr); +} + +static void REGPARAM2 cia_bput(uaecptr addr, uae_u32 value) { int r = (addr & 0xf00) >> 8; - uae_u16 v; -#ifdef JIT - special_mem |= S_READ; -#endif + if (isgarynocia(addr)) { + dummy_put(addr, 1, false); + return; + } - cia_wait_pre (); - switch ((addr >> 12) & 3) - { - case 0: - v = (ReadCIAB (r) << 8) | ReadCIAA (r); - break; - case 1: - v = (ReadCIAB (r) << 8) | 0xff; - break; - case 2: - v = (0xff << 8) | ReadCIAA (r); - break; - case 3: - if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) - v = regs.irc; - else - v = 0xffff; - break; - } - cia_wait_post (v); - return v; + if (!isgaylenocia(addr)) + return; + + int cs = cia_chipselect(addr); + + if (!issinglecia() || (cs & 3) != 0) { + cia_wait_pre(((cs & 2) == 0 ? 1 : 0) | ((cs & 1) == 0 ? 2 : 0)); + if ((cs & 2) == 0) + WriteCIAB(r, value); + if ((cs & 1) == 0) + WriteCIAA(r, value); + cia_wait_post(((cs & 2) == 0 ? 1 : 0) | ((cs & 1) == 0 ? 2 : 0), value); + if (((cs & 3) == 3) && (warned > 0 || currprefs.illegal_mem)) { + write_log(_T("cia_bput: unknown CIA address %08X=%02X PC=%08X\n"), addr, value & 0xff, M68K_GETPC); + warned--; + } + } } -static uae_u32 REGPARAM2 cia_lget (uaecptr addr) +static void REGPARAM2 cia_wput(uaecptr addr, uae_u32 value) { - uae_u32 v; - v = cia_wget (addr) << 16; - v |= cia_wget (addr + 2); - return v; + int r = (addr & 0xf00) >> 8; + + if (isgarynocia(addr)) { + dummy_put(addr, 2, false); + return; + } + + if (!isgaylenocia(addr)) + return; + + int cs = cia_chipselect(addr); + + if (!issinglecia() || (cs & 3) != 0) { + cia_wait_pre(((cs & 2) == 0 ? 1 : 0) | ((cs & 1) == 0 ? 2 : 0)); + if ((cs & 2) == 0) + WriteCIAB(r, value >> 8); + if ((cs & 1) == 0) + WriteCIAA(r, value & 0xff); + cia_wait_post(((cs & 2) == 0 ? 1 : 0) | ((cs & 1) == 0 ? 2 : 0), value); + if (((cs & 3) == 3) && (warned > 0 || currprefs.illegal_mem)) { + write_log(_T("cia_wput: unknown CIA address %08X=%04X %08X\n"), addr, value & 0xffff, M68K_GETPC); + warned--; + } + } } -static uae_u32 REGPARAM2 cia_wgeti (uaecptr addr) +static void REGPARAM2 cia_lput(uaecptr addr, uae_u32 value) { - if (currprefs.cpu_model >= 68020) - return dummy_wgeti(addr); - return cia_wget(addr); -} -static uae_u32 REGPARAM2 cia_lgeti (uaecptr addr) -{ - if (currprefs.cpu_model >= 68020) - return dummy_lgeti(addr); - return cia_lget(addr); -} - -static void REGPARAM2 cia_bput (uaecptr addr, uae_u32 value) -{ - value &= 0xFF; - int r = (addr & 0xf00) >> 8; - -#ifdef JIT - special_mem |= S_WRITE; -#endif - - cia_wait_pre (); - if ((addr & 0x2000) == 0) - WriteCIAB (r, value); - if ((addr & 0x1000) == 0) - WriteCIAA (r, value); - cia_wait_post (value); -} - -static void REGPARAM2 cia_wput (uaecptr addr, uae_u32 value) -{ - value &= 0xFFFF; - int r = (addr & 0xf00) >> 8; - -#ifdef JIT - special_mem |= S_WRITE; -#endif - - cia_wait_pre (); - if ((addr & 0x2000) == 0) - WriteCIAB (r, value >> 8); - if ((addr & 0x1000) == 0) - WriteCIAA (r, value & 0xff); - cia_wait_post (value); -} - -static void REGPARAM2 cia_lput (uaecptr addr, uae_u32 value) -{ - cia_wput (addr, value >> 16); - cia_wput (addr + 2, value & 0xffff); + cia_wput(addr, value >> 16); + cia_wput(addr + 2, value & 0xffff); } /* battclock memory access */ -static uae_u32 REGPARAM3 clock_lget (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 clock_wget (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 clock_bget (uaecptr) REGPARAM; -static void REGPARAM3 clock_lput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 clock_wput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 clock_bput (uaecptr, uae_u32) REGPARAM; +static uae_u32 REGPARAM3 clock_lget(uaecptr) REGPARAM; +static uae_u32 REGPARAM3 clock_wget(uaecptr) REGPARAM; +static uae_u32 REGPARAM3 clock_bget(uaecptr) REGPARAM; +static void REGPARAM3 clock_lput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 clock_wput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 clock_bput(uaecptr, uae_u32) REGPARAM; addrbank clock_bank = { - clock_lget, clock_wget, clock_bget, - clock_lput, clock_wput, clock_bput, - default_xlate, default_check, NULL, _T("Battery backed up clock (none)"), - dummy_lgeti, dummy_wgeti, ABFLAG_IO, 0x3f, 0xd80000 + clock_lget, clock_wget, clock_bget, + clock_lput, clock_wput, clock_bput, + default_xlate, default_check, NULL, NULL, _T("Battery backed up clock (none)"), + dummy_lgeti, dummy_wgeti, + ABFLAG_IO, S_READ, S_WRITE, NULL, 0x3f, 0xd80000 }; static unsigned int clock_control_d; static unsigned int clock_control_e; static unsigned int clock_control_f; -static uae_u8 getclockreg (int addr, struct tm *ct) +#define RF5C01A_RAM_SIZE 16 +static uae_u8 rtc_memory[RF5C01A_RAM_SIZE], rtc_alarm[RF5C01A_RAM_SIZE]; + +static uae_u8 getclockreg(int addr, struct tm *ct) { uae_u8 v = 0; - switch (addr) { - case 0x0: v = ct->tm_sec % 10; break; - case 0x1: v = ct->tm_sec / 10; break; - case 0x2: v = ct->tm_min % 10; break; - case 0x3: v = ct->tm_min / 10; break; - case 0x4: v = ct->tm_hour % 10; break; - case 0x5: + if (currprefs.cs_rtc == 1 || currprefs.cs_rtc == 3) { /* MSM6242B */ + switch (addr) { + case 0x0: v = ct->tm_sec % 10; break; + case 0x1: v = ct->tm_sec / 10; break; + case 0x2: v = ct->tm_min % 10; break; + case 0x3: v = ct->tm_min / 10; break; + case 0x4: v = ct->tm_hour % 10; break; + case 0x5: if (clock_control_f & 4) { v = ct->tm_hour / 10; // 24h - } else { + } + else { v = (ct->tm_hour % 12) / 10; // 12h v |= ct->tm_hour >= 12 ? 4 : 0; // AM/PM bit } - break; - case 0x6: v = ct->tm_mday % 10; break; - case 0x7: v = ct->tm_mday / 10; break; - case 0x8: v = (ct->tm_mon + 1) % 10; break; - case 0x9: v = (ct->tm_mon + 1) / 10; break; - case 0xA: v = ct->tm_year % 10; break; - case 0xB: v = (ct->tm_year / 10) & 0x0f; break; - case 0xC: v = ct->tm_wday; break; - case 0xD: v = clock_control_d; break; - case 0xE: v = clock_control_e; break; - case 0xF: v = clock_control_f; break; - } + break; + case 0x6: v = ct->tm_mday % 10; break; + case 0x7: v = ct->tm_mday / 10; break; + case 0x8: v = (ct->tm_mon + 1) % 10; break; + case 0x9: v = (ct->tm_mon + 1) / 10; break; + case 0xA: v = ct->tm_year % 10; break; + case 0xB: v = (ct->tm_year / 10) & 0x0f; break; + case 0xC: v = ct->tm_wday; break; + case 0xD: v = clock_control_d; break; + case 0xE: v = clock_control_e; break; + case 0xF: v = clock_control_f; break; + } + } + else if (currprefs.cs_rtc == 2) { /* RF5C01A */ + int bank = clock_control_d & 3; + /* memory access */ + if (bank >= 2 && addr < 0x0d) + return (rtc_memory[addr] >> ((bank == 2) ? 0 : 4)) & 0x0f; + /* alarm */ + if (bank == 1 && addr < 0x0d) { + v = rtc_alarm[addr]; +#if CLOCK_DEBUG + write_log(_T("CLOCK ALARM R %X: %X\n"), addr, v); +#endif + return v; + } + switch (addr) { + case 0x0: v = ct->tm_sec % 10; break; + case 0x1: v = ct->tm_sec / 10; break; + case 0x2: v = ct->tm_min % 10; break; + case 0x3: v = ct->tm_min / 10; break; + case 0x4: v = ct->tm_hour % 10; break; + case 0x5: + if (rtc_alarm[10] & 1) + v = ct->tm_hour / 10; // 24h + else + v = ((ct->tm_hour % 12) / 10) | (ct->tm_hour >= 12 ? 2 : 0); // 12h + break; + case 0x6: v = ct->tm_wday; break; + case 0x7: v = ct->tm_mday % 10; break; + case 0x8: v = ct->tm_mday / 10; break; + case 0x9: v = (ct->tm_mon + 1) % 10; break; + case 0xA: v = (ct->tm_mon + 1) / 10; break; + case 0xB: v = (ct->tm_year % 100) % 10; break; + case 0xC: v = (ct->tm_year % 100) / 10; break; + case 0xD: v = clock_control_d; break; + /* E and F = write-only, reads as zero */ + case 0xE: v = 0; break; + case 0xF: v = 0; break; + } + } +#if CLOCK_DEBUG + write_log(_T("CLOCK R: %X = %X, PC=%08x\n"), addr, v, M68K_GETPC); +#endif return v; } +static void write_battclock(void) +{ + if (!currprefs.rtcfile[0] || currprefs.cs_rtc == 0) + return; + struct zfile *f = zfile_fopen(currprefs.rtcfile, _T("wb")); + if (f) { + struct tm *ct; + time_t t = time(0); + t += currprefs.cs_rtc_adjust; + ct = localtime(&t); + uae_u8 od = clock_control_d; + if (currprefs.cs_rtc == 2) + clock_control_d &= ~3; + for (int i = 0; i < 13; i++) { + uae_u8 v = getclockreg(i, ct); + zfile_fwrite(&v, 1, 1, f); + } + clock_control_d = od; + zfile_fwrite(&clock_control_d, 1, 1, f); + zfile_fwrite(&clock_control_e, 1, 1, f); + zfile_fwrite(&clock_control_f, 1, 1, f); + if (currprefs.cs_rtc == 2) { + zfile_fwrite(rtc_alarm, RF5C01A_RAM_SIZE, 1, f); + zfile_fwrite(rtc_memory, RF5C01A_RAM_SIZE, 1, f); + } + zfile_fclose(f); + } +} + void rtc_hardreset(void) { - clock_bank.name = _T("Battery backed up clock (MSM6242B)"); - clock_control_d = 0x1; - clock_control_e = 0; - clock_control_f = 0x4; /* 24/12 */ + rtc_delayed_write = 0; + if (currprefs.cs_rtc == 1 || currprefs.cs_rtc == 3) { /* MSM6242B */ + clock_bank.name = currprefs.cs_rtc == 1 ? _T("Battery backed up clock (MSM6242B)") : _T("Battery backed up clock A2000 (MSM6242B)"); + clock_control_d = 0x1; + clock_control_e = 0; + clock_control_f = 0x4; /* 24/12 */ + } + else if (currprefs.cs_rtc == 2) { /* RF5C01A */ + clock_bank.name = _T("Battery backed up clock (RF5C01A)"); + clock_control_d = 0x8; /* Timer EN */ + clock_control_e = 0; + clock_control_f = 0; + memset(rtc_memory, 0, RF5C01A_RAM_SIZE); + memset(rtc_alarm, 0, RF5C01A_RAM_SIZE); + rtc_alarm[10] = 1; /* 24H mode */ + } + if (currprefs.rtcfile[0]) { + struct zfile *f = zfile_fopen(currprefs.rtcfile, _T("rb")); + if (f) { + uae_u8 empty[13]; + zfile_fread(empty, 13, 1, f); + zfile_fread(&clock_control_d, 1, 1, f); + zfile_fread(&clock_control_e, 1, 1, f); + zfile_fread(&clock_control_f, 1, 1, f); + zfile_fread(rtc_alarm, RF5C01A_RAM_SIZE, 1, f); + zfile_fread(rtc_memory, RF5C01A_RAM_SIZE, 1, f); + zfile_fclose(f); + } + } } -static uae_u32 REGPARAM2 clock_lget (uaecptr addr) +static uae_u32 REGPARAM2 clock_lget(uaecptr addr) { - return (clock_wget (addr) << 16) | clock_wget (addr + 2); + if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0) + return dummy_get(addr, 4, false, 0); + + return (clock_wget(addr) << 16) | clock_wget(addr + 2); } -static uae_u32 REGPARAM2 clock_wget (uaecptr addr) +static uae_u32 REGPARAM2 clock_wget(uaecptr addr) { - return (clock_bget (addr) << 8) | clock_bget (addr + 1); + if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0) + return dummy_get(addr, 2, false, 0); + + return (clock_bget(addr) << 8) | clock_bget(addr + 1); } -static uae_u32 REGPARAM2 clock_bget (uaecptr addr) +static uae_u32 REGPARAM2 clock_bget(uaecptr addr) { - time_t t; - struct tm *ct; + struct tm *ct; uae_u8 v = 0; -#ifdef JIT - special_mem |= S_READ; + if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0) + return dummy_get(addr, 1, false, 0); + +#ifdef CDTV + if (currprefs.cs_cdtvram && (addr & 0xffff) >= 0x8000) + return cdtv_battram_read(addr); #endif - addr &= 0x3f; - if ((addr & 3) == 2 || (addr & 3) == 0) { - if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) - v = regs.irc >> 8; - return v; - } - t = time(0); - ct = localtime (&t); - addr >>= 2; - return getclockreg (addr, ct); + + addr &= 0x3f; + if ((addr & 3) == 2 || (addr & 3) == 0 || currprefs.cs_rtc == 0) { + return dummy_get(addr, 1, false, v); + } + time_t t = time(0); + t += currprefs.cs_rtc_adjust; + ct = localtime(&t); + addr >>= 2; + return getclockreg(addr, ct); } -static void REGPARAM2 clock_lput (uaecptr addr, uae_u32 value) +static void REGPARAM2 clock_lput(uaecptr addr, uae_u32 value) { - clock_wput (addr, value >> 16); - clock_wput (addr + 2, value); + if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0) { + dummy_put(addr, 4, value); + return; + } + + clock_wput(addr, value >> 16); + clock_wput(addr + 2, value); } -static void REGPARAM2 clock_wput (uaecptr addr, uae_u32 value) +static void REGPARAM2 clock_wput(uaecptr addr, uae_u32 value) { - clock_bput (addr, value >> 8); - clock_bput (addr + 1, value); + if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0) { + dummy_put(addr, 2, value); + return; + } + + clock_bput(addr, value >> 8); + clock_bput(addr + 1, value); } -static void REGPARAM2 clock_bput (uaecptr addr, uae_u32 value) +static void REGPARAM2 clock_bput(uaecptr addr, uae_u32 value) { -#ifdef JIT - special_mem |= S_WRITE; + // write_log(_T("W: %x (%x): %x, PC=%08x\n"), addr, (addr & 0xff) >> 2, value & 0xff, M68K_GETPC); + + if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0) { + dummy_put(addr, 1, value); + return; + } + +#ifdef CDTV + if (currprefs.cs_cdtvram && (addr & 0xffff) >= 0x8000) { + cdtv_battram_write(addr, value); + return; + } #endif - addr &= 0x3f; - if ((addr & 1) != 1) - return; - addr >>= 2; - value &= 0x0f; - switch (addr) - { - case 0xD: clock_control_d = value & (1|8); break; - case 0xE: clock_control_e = value; break; - case 0xF: clock_control_f = value; break; - } + + addr &= 0x3f; + if ((addr & 1) != 1 || currprefs.cs_rtc == 0) + return; + addr >>= 2; + value &= 0x0f; + if (currprefs.cs_rtc == 1 || currprefs.cs_rtc == 3) { /* MSM6242B */ +#if CLOCK_DEBUG + write_log(_T("CLOCK W %X: %X\n"), addr, value); +#endif + switch (addr) + { + case 0xD: clock_control_d = value & (1 | 8); break; + case 0xE: clock_control_e = value; break; + case 0xF: clock_control_f = value; break; + } + } + else if (currprefs.cs_rtc == 2) { /* RF5C01A */ + int bank = clock_control_d & 3; + /* memory access */ + if (bank >= 2 && addr < 0x0d) { + uae_u8 ov = rtc_memory[addr]; + rtc_memory[addr] &= ((bank == 2) ? 0xf0 : 0x0f); + rtc_memory[addr] |= value << ((bank == 2) ? 0 : 4); + if (rtc_memory[addr] != ov) + rtc_delayed_write = -1; + return; + } + /* alarm */ + if (bank == 1 && addr < 0x0d) { +#if CLOCK_DEBUG + write_log(_T("CLOCK ALARM W %X: %X\n"), addr, value); +#endif + uae_u8 ov = rtc_alarm[addr]; + rtc_alarm[addr] = value; + rtc_alarm[0] = rtc_alarm[1] = rtc_alarm[9] = rtc_alarm[12] = 0; + rtc_alarm[3] &= ~0x8; + rtc_alarm[5] &= ~0xc; + rtc_alarm[6] &= ~0x8; + rtc_alarm[8] &= ~0xc; + rtc_alarm[10] &= ~0xe; + rtc_alarm[11] &= ~0xc; + if (rtc_alarm[addr] != ov) + rtc_delayed_write = -1; + return; + } +#if CLOCK_DEBUG + write_log(_T("CLOCK W %X: %X\n"), addr, value); +#endif + switch (addr) + { + case 0xD: clock_control_d = value; break; + case 0xE: clock_control_e = value; break; + case 0xF: clock_control_f = value; break; + } + } + rtc_delayed_write = -1; } #ifdef SAVESTATE /* CIA-A and CIA-B save/restore code */ -static void save_cia_prepare (void) +static void save_cia_prepare(void) { - CIA_update_check (); - CIA_calctimers (); - compute_passed_time (); + CIA_update_check(); + CIA_calctimers(); + compute_passed_time(); } -void restore_cia_start (void) +void restore_cia_start(void) { /* Fixes very old statefiles without keyboard state */ kbstate = 3; + setcapslockstate(0); kblostsynccnt = 0; } -void restore_cia_finish (void) +void restore_cia_finish(void) { - eventtab[ev_cia].oldcycles = get_cycles (); - CIA_update (); - CIA_calctimers (); - compute_passed_time (); + eventtab[ev_cia].oldcycles = get_cycles(); + CIA_update(); + CIA_calctimers(); + compute_passed_time(); eventtab[ev_cia].oldcycles -= div10; - DISK_select_set (ciabprb); + //dumpcia (); + DISK_select_set(ciabprb); } -uae_u8 *restore_cia (int num, uae_u8 *src) +uae_u8 *restore_cia(int num, uae_u8 *src) { - uae_u8 b; - uae_u16 w; - uae_u32 l; + uae_u8 b; + uae_u16 w; + uae_u32 l; - /* CIA registers */ - b = restore_u8 (); /* 0 PRA */ - if (num) ciabpra = b; else ciaapra = b; - b = restore_u8 (); /* 1 PRB */ - if (num) ciabprb = b; else ciaaprb = b; - b = restore_u8 (); /* 2 DDRA */ - if (num) ciabdra = b; else ciaadra = b; - b = restore_u8 (); /* 3 DDRB */ - if (num) ciabdrb = b; else ciaadrb = b; - w = restore_u16 (); /* 4 TA */ - if (num) ciabta = w; else ciaata = w; - w = restore_u16 (); /* 6 TB */ - if (num) ciabtb = w; else ciaatb = w; - l = restore_u8 (); /* 8/9/A TOD */ - l |= restore_u8 () << 8; - l |= restore_u8 () << 16; - if (num) ciabtod = l; else ciaatod = l; - restore_u8 (); /* B unused */ - b = restore_u8 (); /* C SDR */ - if (num) ciabsdr = b; else ciaasdr = b; - b = restore_u8 (); /* D ICR INFORMATION (not mask!) */ - if (num) ciabicr = b; else ciaaicr = b; - b = restore_u8 (); /* E CRA */ - if (num) ciabcra = b; else ciaacra = b; - b = restore_u8 (); /* F CRB */ - if (num) ciabcrb = b; else ciaacrb = b; + /* CIA registers */ + b = restore_u8(); /* 0 PRA */ + if (num) ciabpra = b; else ciaapra = b; + b = restore_u8(); /* 1 PRB */ + if (num) ciabprb = b; else ciaaprb = b; + b = restore_u8(); /* 2 DDRA */ + if (num) ciabdra = b; else ciaadra = b; + b = restore_u8(); /* 3 DDRB */ + if (num) ciabdrb = b; else ciaadrb = b; + w = restore_u16(); /* 4 TA */ + if (num) ciabta = w; else ciaata = w; + w = restore_u16(); /* 6 TB */ + if (num) ciabtb = w; else ciaatb = w; + l = restore_u8(); /* 8/9/A TOD */ + l |= restore_u8() << 8; + l |= restore_u8() << 16; + if (num) ciabtod = l; else ciaatod = l; + restore_u8(); /* B unused */ + b = restore_u8(); /* C SDR */ + if (num) ciabsdr = b; else ciaasdr = b; + b = restore_u8(); /* D ICR INFORMATION (not mask!) */ + if (num) ciabicr = b; else ciaaicr = b; + b = restore_u8(); /* E CRA */ + if (num) ciabcra = b; else ciaacra = b; + b = restore_u8(); /* F CRB */ + if (num) ciabcrb = b; else ciaacrb = b; - /* CIA internal data */ + /* CIA internal data */ - b = restore_u8 (); /* ICR MASK */ - if (num) ciabimask = b; else ciaaimask = b; - w = restore_u8 (); /* timer A latch */ - w |= restore_u8 () << 8; - if (num) ciabla = w; else ciaala = w; - w = restore_u8 (); /* timer B latch */ - w |= restore_u8 () << 8; - if (num) ciablb = w; else ciaalb = w; - w = restore_u8 (); /* TOD latched value */ - w |= restore_u8 () << 8; - w |= restore_u8 () << 16; - if (num) ciabtol = w; else ciaatol = w; - l = restore_u8 (); /* alarm */ - l |= restore_u8 () << 8; - l |= restore_u8 () << 16; - if (num) ciabalarm = l; else ciaaalarm = l; - b = restore_u8 (); - if (num) ciabtlatch = b & 1; else ciaatlatch = b & 1; /* is TOD latched? */ - if (num) ciabtodon = b & 2; else ciaatodon = b & 2; /* is TOD stopped? */ - b = restore_u8 (); - if (num) - div10 = CYCLE_UNIT * b; - b = restore_u8 (); - if (num) ciabsdr_cnt = b; else ciaasdr_cnt = b; - return src; + b = restore_u8(); /* ICR MASK */ + if (num) ciabimask = b; else ciaaimask = b; + w = restore_u8(); /* timer A latch */ + w |= restore_u8() << 8; + if (num) ciabla = w; else ciaala = w; + w = restore_u8(); /* timer B latch */ + w |= restore_u8() << 8; + if (num) ciablb = w; else ciaalb = w; + w = restore_u8(); /* TOD latched value */ + w |= restore_u8() << 8; + w |= restore_u8() << 16; + if (num) ciabtol = w; else ciaatol = w; + l = restore_u8(); /* alarm */ + l |= restore_u8() << 8; + l |= restore_u8() << 16; + if (num) ciabalarm = l; else ciaaalarm = l; + b = restore_u8(); + if (num) ciabtlatch = b & 1; else ciaatlatch = b & 1; /* is TOD latched? */ + if (num) ciabtodon = b & 2; else ciaatodon = b & 2; /* is TOD stopped? */ + b = restore_u8(); + if (num) + div10 = CYCLE_UNIT * b; + b = restore_u8(); + if (num) ciabsdr_cnt = b; else ciaasdr_cnt = b; + return src; } -uae_u8 *save_cia (int num, int *len, uae_u8 *dstptr) +uae_u8 *save_cia(int num, int *len, uae_u8 *dstptr) { - uae_u8 *dstbak,*dst, b; - uae_u16 t; + uae_u8 *dstbak, *dst, b; + uae_u16 t; - if (dstptr) - dstbak = dst = dstptr; - else - dstbak = dst = xmalloc (uae_u8, 100); + if (dstptr) + dstbak = dst = dstptr; + else + dstbak = dst = xmalloc(uae_u8, 1000); - save_cia_prepare (); + save_cia_prepare(); - /* CIA registers */ + /* CIA registers */ - b = num ? ciabpra : ciaapra; /* 0 PRA */ - save_u8 (b); - b = num ? ciabprb : ciaaprb; /* 1 PRB */ - save_u8 (b); - b = num ? ciabdra : ciaadra; /* 2 DDRA */ - save_u8 (b); - b = num ? ciabdrb : ciaadrb; /* 3 DDRB */ - save_u8 (b); - t = (num ? ciabta - ciabta_passed : ciaata - ciaata_passed);/* 4 TA */ - save_u16 (t); - t = (num ? ciabtb - ciabtb_passed : ciaatb - ciaatb_passed);/* 6 TB */ - save_u16 (t); - b = (num ? ciabtod : ciaatod); /* 8 TODL */ - save_u8 (b); - b = (num ? ciabtod >> 8 : ciaatod >> 8); /* 9 TODM */ - save_u8 (b); - b = (num ? ciabtod >> 16 : ciaatod >> 16); /* A TODH */ - save_u8 (b); - save_u8 (0); /* B unused */ - b = num ? ciabsdr : ciaasdr; /* C SDR */ - save_u8 (b); - b = num ? ciabicr : ciaaicr; /* D ICR INFORMATION (not mask!) */ - save_u8 (b); - b = num ? ciabcra : ciaacra; /* E CRA */ - save_u8 (b); - b = num ? ciabcrb : ciaacrb; /* F CRB */ - save_u8 (b); + b = num ? ciabpra : ciaapra; /* 0 PRA */ + save_u8(b); + b = num ? ciabprb : ciaaprb; /* 1 PRB */ + save_u8(b); + b = num ? ciabdra : ciaadra; /* 2 DDRA */ + save_u8(b); + b = num ? ciabdrb : ciaadrb; /* 3 DDRB */ + save_u8(b); + t = (num ? ciabta - ciabta_passed : ciaata - ciaata_passed);/* 4 TA */ + save_u16(t); + t = (num ? ciabtb - ciabtb_passed : ciaatb - ciaatb_passed);/* 6 TB */ + save_u16(t); + b = (num ? ciabtod : ciaatod); /* 8 TODL */ + save_u8(b); + b = (num ? ciabtod >> 8 : ciaatod >> 8); /* 9 TODM */ + save_u8(b); + b = (num ? ciabtod >> 16 : ciaatod >> 16); /* A TODH */ + save_u8(b); + save_u8(0); /* B unused */ + b = num ? ciabsdr : ciaasdr; /* C SDR */ + save_u8(b); + b = num ? ciabicr : ciaaicr; /* D ICR INFORMATION (not mask!) */ + save_u8(b); + b = num ? ciabcra : ciaacra; /* E CRA */ + save_u8(b); + b = num ? ciabcrb : ciaacrb; /* F CRB */ + save_u8(b); - /* CIA internal data */ + /* CIA internal data */ - save_u8 (num ? ciabimask : ciaaimask); /* ICR */ - b = (num ? ciabla : ciaala); /* timer A latch LO */ - save_u8 (b); - b = (num ? ciabla >> 8 : ciaala >> 8); /* timer A latch HI */ - save_u8 (b); - b = (num ? ciablb : ciaalb); /* timer B latch LO */ - save_u8 (b); - b = (num ? ciablb >> 8 : ciaalb >> 8); /* timer B latch HI */ - save_u8 (b); - b = (num ? ciabtol : ciaatol); /* latched TOD LO */ - save_u8 (b); - b = (num ? ciabtol >> 8 : ciaatol >> 8); /* latched TOD MED */ - save_u8 (b); - b = (num ? ciabtol >> 16 : ciaatol >> 16); /* latched TOD HI */ - save_u8 (b); - b = (num ? ciabalarm : ciaaalarm); /* alarm LO */ - save_u8 (b); - b = (num ? ciabalarm >> 8 : ciaaalarm >>8 ); /* alarm MED */ - save_u8 (b); - b = (num ? ciabalarm >> 16 : ciaaalarm >> 16); /* alarm HI */ - save_u8 (b); - b = 0; - if (num) - b |= ciabtlatch ? 1 : 0; - else - b |= ciaatlatch ? 1 : 0; /* is TOD latched? */ - if (num) - b |= ciabtodon ? 2 : 0; - else - b |= ciaatodon ? 2 : 0; /* TOD stopped? */ - save_u8 (b); - save_u8 (num ? div10 / CYCLE_UNIT : 0); - save_u8 (num ? ciabsdr_cnt : ciaasdr_cnt); - *len = dst - dstbak; - return dstbak; + save_u8(num ? ciabimask : ciaaimask); /* ICR */ + b = (num ? ciabla : ciaala); /* timer A latch LO */ + save_u8(b); + b = (num ? ciabla >> 8 : ciaala >> 8); /* timer A latch HI */ + save_u8(b); + b = (num ? ciablb : ciaalb); /* timer B latch LO */ + save_u8(b); + b = (num ? ciablb >> 8 : ciaalb >> 8); /* timer B latch HI */ + save_u8(b); + b = (num ? ciabtol : ciaatol); /* latched TOD LO */ + save_u8(b); + b = (num ? ciabtol >> 8 : ciaatol >> 8); /* latched TOD MED */ + save_u8(b); + b = (num ? ciabtol >> 16 : ciaatol >> 16); /* latched TOD HI */ + save_u8(b); + b = (num ? ciabalarm : ciaaalarm); /* alarm LO */ + save_u8(b); + b = (num ? ciabalarm >> 8 : ciaaalarm >> 8);/* alarm MED */ + save_u8(b); + b = (num ? ciabalarm >> 16 : ciaaalarm >> 16); /* alarm HI */ + save_u8(b); + b = 0; + if (num) + b |= ciabtlatch ? 1 : 0; + else + b |= ciaatlatch ? 1 : 0; /* is TOD latched? */ + if (num) + b |= ciabtodon ? 2 : 0; + else + b |= ciaatodon ? 2 : 0; /* TOD stopped? */ + save_u8(b); + save_u8(num ? div10 / CYCLE_UNIT : 0); + save_u8(num ? ciabsdr_cnt : ciaasdr_cnt); + *len = dst - dstbak; + return dstbak; } -uae_u8 *save_keyboard (int *len, uae_u8 *dstptr) +uae_u8 *save_keyboard(int *len, uae_u8 *dstptr) { uae_u8 *dst, *dstbak; if (dstptr) dstbak = dst = dstptr; else - dstbak = dst = xmalloc (uae_u8, 4 + 4 + 1 + 1 + 1 + 1 + 1 + 2); - save_u32 (1); - save_u8 (kbstate); - save_u8 (0); - save_u8 (0); - save_u8 (0); - save_u8 (kbcode); - save_u16 (kblostsynccnt); + dstbak = dst = xmalloc(uae_u8, 4 + 4 + 1 + 1 + 1 + 1 + 1 + 2); + save_u32(getcapslockstate() ? 1 : 0); + save_u32(1); + save_u8(kbstate); + save_u8(0); + save_u8(0); + save_u8(0); + save_u8(kbcode); + save_u16(kblostsynccnt); *len = dst - dstbak; return dstbak; } -uae_u8 *restore_keyboard (uae_u8 *src) +uae_u8 *restore_keyboard(uae_u8 *src) { - uae_u32 v = restore_u32 (); - kbstate = restore_u8 (); - restore_u8 (); - restore_u8 (); - restore_u8 (); - kbcode = restore_u8 (); - kblostsynccnt = restore_u16 (); + setcapslockstate(restore_u32() & 1); + uae_u32 v = restore_u32(); + kbstate = restore_u8(); + restore_u8(); + restore_u8(); + restore_u8(); + kbcode = restore_u8(); + kblostsynccnt = restore_u16(); if (!(v & 1)) { kbstate = 3; kblostsynccnt = 0; } - return src; + return src; } #endif /* SAVESTATE */ diff --git a/src/custom.cpp b/src/custom.cpp index 9837fcfa..c19bf2d7 100644 --- a/src/custom.cpp +++ b/src/custom.cpp @@ -37,64 +37,119 @@ #include "akiko.h" #include "gfxboard.h" #include "blkdev.h" +#include "clipboard.h" +#include "amiberry_gfx.h" +#include "rommgr.h" +#define CUSTOM_DEBUG 0 +#define SPRITE_DEBUG 0 +#define SPRITE_DEBUG_MINY 0 +#define SPRITE_DEBUG_MAXY 0x300 #define SPR0_HPOS 0x15 #define MAX_SPRITES 8 +#define SPRITE_COLLISIONS +#define SPEEDUP 1 +#define AUTOSCALE_SPRITES 1 -STATIC_INLINE bool nocustom() +#define SPRBORDER 0 + +STATIC_INLINE bool nocustom(void) { - if (picasso_on) + if (picasso_on && currprefs.picasso96_nocustom) return true; return false; } -extern int screen_is_picasso; +static void uae_abort(const TCHAR *format, ...) +{ + static int nomore; + va_list parms; + TCHAR buffer[1000]; -long last_synctime = 0; -static int frh_count = 0; -#define LAST_SPEEDUP_LINE 30 -#define SPEEDUP_CYCLES_JIT 2800 -#define SPEEDUP_CYCLES_NONJIT 600 -#define SPEEDUP_TIMELIMIT_JIT -1500 -#define SPEEDUP_TIMELIMIT_NONJIT -2000 -int pissoff_value = SPEEDUP_CYCLES_JIT * CYCLE_UNIT; -int speedup_timelimit = SPEEDUP_TIMELIMIT_JIT; + va_start(parms, format); + _vsntprintf(buffer, sizeof(buffer) - 1, format, parms); + va_end(parms); + if (nomore) { + write_log(_T("%s\n"), buffer); + return; + } + gui_message(buffer); + nomore = 1; +} + +static unsigned int n_consecutive_skipped = 0; +static unsigned int total_skipped = 0; + +extern int cpu_last_stop_vpos, cpu_stopped_lines; +static int cpu_sleepmode, cpu_sleepmode_cnt; + +STATIC_INLINE void sync_copper(int hpos); /* Events */ +unsigned long int vsync_cycles; +static int extra_cycle; + static int rpt_did_reset; struct ev eventtab[ev_max]; struct ev2 eventtab2[ev2_max]; +int hpos_offset; int vpos; static int vpos_count, vpos_count_diff; -static int lof_store; // real bit in custom registers +int lof_store; // real bit in custom registers static int lof_current; // what display device thinks +static bool lof_lastline, lof_prev_lastline; +static int lol; static int next_lineno, prev_lineno; -static int lof_changed = 0, lof_changing = 0; +static enum nln_how nextline_how; +static int lof_changed = 0, lof_changing = 0, interlace_changed = 0; static int lof_changed_previous_field; static int vposw_change; static bool lof_lace; +static bool bplcon0_interlace_seen; +static int scandoubled_line; +static bool vsync_rendered, frame_rendered, frame_shown; +static int vsynctimeperline; +static int frameskiptime; +static bool genlockhtoggle; +static bool genlockvtoggle; +static bool graphicsbuffer_retry; +static int scanlinecount; +static int cia_hsync; #define LOF_TOGGLES_NEEDED 3 +static int lof_togglecnt_lace, lof_togglecnt_nlace; + +/* Stupid genlock-detection prevention hack. +* We should stop calling vsync_handler() and +* hstop_handler() completely but it is not +* worth the trouble.. +*/ +static int vpos_previous, hpos_previous; +static int vpos_lpen, hpos_lpen, lightpen_triggered; +int lightpen_x = -1, lightpen_y = -1, lightpen_cx, lightpen_cy, lightpen_active, lightpen_enabled; + static uae_u32 sprtaba[256], sprtabb[256]; static uae_u32 sprite_ab_merge[256]; - /* Tables for collision detection. */ static uae_u32 sprclx[16], clxmask[16]; +/* T genlock bit in ECS Denise and AGA color registers */ +static uae_u8 color_regs_genlock[256]; + /* * Hardware registers of all sorts. */ static int REGPARAM3 custom_wput_1(int, uaecptr, uae_u32, int) REGPARAM; -static uae_u16 intena; -uae_u16 intreq; +static uae_u16 cregs[256]; + +uae_u16 intena, intreq; uae_u16 dmacon; uae_u16 adkcon; /* used by audio code */ -static uae_u32 last_custom_value1; - +uae_u32 last_custom_value1; static uae_u32 cop1lc, cop2lc, copcon; @@ -103,25 +158,35 @@ int maxhpos_short = MAXHPOS_PAL; int maxvpos = MAXVPOS_PAL; int maxvpos_nom = MAXVPOS_PAL; // nominal value (same as maxvpos but "faked" maxvpos in fake 60hz modes) int maxvpos_display = MAXVPOS_PAL; // value used for display size +int hsyncendpos, hsyncstartpos; static int maxvpos_total = 511; int minfirstline = VBLANK_ENDLINE_PAL; +int firstblankedline; static int equ_vblank_endline = EQU_ENDLINE_PAL; static bool equ_vblank_toggle = true; double vblank_hz = VBLANK_HZ_PAL, fake_vblank_hz, vblank_hz_stored, vblank_hz_nom; +double hblank_hz; +static float vblank_hz_lof, vblank_hz_shf, vblank_hz_lace; static int vblank_hz_mult, vblank_hz_state; +static struct chipset_refresh *stored_chipset_refresh; +int doublescan; +bool programmedmode; int syncbase; -static int fmode; -static uae_u16 beamcon0; -static uae_u16 new_beamcon0; -static uae_u16 vtotal = MAXVPOS_PAL, htotal = MAXHPOS_PAL; +static int fmode_saved, fmode; +uae_u16 beamcon0, new_beamcon0; +static bool varsync_changed; +uae_u16 vtotal = MAXVPOS_PAL, htotal = MAXHPOS_PAL; +static int maxvpos_stored, maxhpos_stored; static uae_u16 hsstop, hbstrt, hbstop, vsstop, vbstrt, vbstop, hsstrt, vsstrt, hcenter; +static int ciavsyncmode; static int diw_hstrt, diw_hstop; static int diw_hcounter; +static uae_u16 refptr; +static uae_u32 refptr_val; #define HSYNCTIME (maxhpos * CYCLE_UNIT) -struct sprite -{ +struct sprite { uaecptr pt; int xpos; int vstart; @@ -130,52 +195,89 @@ struct sprite int armed; int dmastate; int dmacycle; + int ptxhpos; + int ptxhpos2, ptxvpos2; + bool ignoreverticaluntilnextline; }; static struct sprite spr[MAX_SPRITES]; static int plfstrt_sprite; +static bool sprite_ignoreverticaluntilnextline; + +uaecptr sprite_0; +int sprite_0_width, sprite_0_height, sprite_0_doubled; +uae_u32 sprite_0_colors[4]; +static uae_u8 magic_sprite_mask = 0xff; static int sprite_vblank_endline = VBLANK_SPRITE_PAL; static uae_u16 sprctl[MAX_SPRITES], sprpos[MAX_SPRITES]; +#ifdef AGA static uae_u16 sprdata[MAX_SPRITES][4], sprdatb[MAX_SPRITES][4]; - +#else +static uae_u16 sprdata[MAX_SPRITES][1], sprdatb[MAX_SPRITES][1]; +#endif +static int sprite_last_drawn_at[MAX_SPRITES]; static int last_sprite_point, nr_armed; static int sprite_width, sprres; +static int sprite_sprctlmask; int sprite_buffer_res; -static uae_u16 bplxdat[8]; -static bool bpl1dat_written, bpl1dat_early, bpl1dat_written_at_least_once; +#ifdef CPUEMU_13 +uae_u8 cycle_line[256 + 1]; +#endif + +static bool bpl1dat_written, bpl1dat_written_at_least_once; static bool bpldmawasactive; -static uae_s16 bpl1mod, bpl2mod; -static uaecptr bplpt[8]; +static uae_s16 bpl1mod, bpl2mod, dbpl1mod, dbpl2mod; +static int dbpl1mod_on, dbpl2mod_on; +static uaecptr prevbpl[2][MAXVPOS][8]; +static uaecptr bplpt[8], bplptx[8]; + +static int bitplane_line_crossing; static struct color_entry current_colors; -static unsigned int bplcon0; +unsigned int bplcon0; static unsigned int bplcon1, bplcon2, bplcon3, bplcon4; static unsigned int bplcon0d, bplcon0dd, bplcon0_res, bplcon0_planes, bplcon0_planes_limit; static unsigned int diwstrt, diwstop, diwhigh; static int diwhigh_written; -static unsigned int ddfstrt, ddfstop, ddfstrt_old_hpos; -static int line_cyclebased; -static int bplcon1_hpos; +static unsigned int ddfstrt, ddfstop; +static int line_cyclebased, badmode, diw_change; +static int bplcon1_fetch; +static int hpos_is_zero_bplcon1_hack = -1; + +#define SET_LINE_CYCLEBASED line_cyclebased = 2; /* The display and data fetch windows */ enum diw_states { - DIW_waiting_start, - DIW_waiting_stop + DIW_waiting_start, DIW_waiting_stop }; static int plffirstline, plflastline; -static int plfstrt_start, plfstrt, plfstop; +int plffirstline_total, plflastline_total; +static int autoscale_bordercolors; +static int plfstrt, plfstop; static int sprite_minx, sprite_maxx; +static int first_bpl_vpos; +static int last_ddf_pix_hpos; static int last_decide_line_hpos; static int last_fetch_hpos, last_sprite_hpos; static int diwfirstword, diwlastword; -static int plfleft_real; static int last_hdiw; static enum diw_states diwstate, hdiwstate, ddfstate; +static int bpl_hstart; + +int first_planes_vpos, last_planes_vpos; +static int first_bplcon0, first_bplcon0_old; +static int first_planes_vpos_old, last_planes_vpos_old; +int diwfirstword_total, diwlastword_total; +int ddffirstword_total, ddflastword_total; +static int diwfirstword_total_old, diwlastword_total_old; +static int ddffirstword_total_old, ddflastword_total_old; +bool vertical_changed, horizontal_changed; +int firstword_bplcon1; static int last_copper_hpos; static int copper_access; @@ -183,8 +285,7 @@ static int copper_access; /* Sprite collisions */ static unsigned int clxdat, clxcon, clxcon2, clxcon_bpl_enable, clxcon_bpl_match; -enum copper_states -{ +enum copper_states { COP_stop, COP_waitforever, COP_read1, @@ -203,53 +304,32 @@ enum copper_states COP_start_delay }; -struct copper -{ +struct copper { /* The current instruction words. */ unsigned int i1, i2; + unsigned int saved_i1, saved_i2; enum copper_states state, state_prev; /* Instruction pointer. */ - uaecptr ip; - int hpos; + uaecptr ip, saved_ip; + int hpos, vpos; unsigned int ignore_next; int vcmp, hcmp; - /* When we schedule a copper event, knowing a few things about the future - of the copper list can reduce the number of sync_with_cpu calls - dramatically. */ - unsigned int first_sync; - unsigned int regtypes_modified; - int strobe; /* COPJMP1 / COPJMP2 accessed */ int moveaddr, movedata, movedelay; }; -#define REGTYPE_NONE 0 -#define REGTYPE_COLOR 1 -#define REGTYPE_SPRITE 2 -#define REGTYPE_PLANE 4 -#define REGTYPE_BLITTER 8 -#define REGTYPE_JOYPORT 16 -#define REGTYPE_DISK 32 -#define REGTYPE_POS 64 -#define REGTYPE_AUDIO 128 - -#define REGTYPE_ALL 255 -/* Always set in regtypes_modified, to enable a forced update when things like - DMACON, BPLCON0, COPJMPx get written. */ -#define REGTYPE_FORCE 256 - -static unsigned int regtypes[512]; - static struct copper cop_state; static int copper_enabled_thisline; +static int cop_min_waittime; /* - * Statistics - */ - +* Statistics +*/ unsigned long int frametime = 0, lastframetime = 0, timeframes = 0; -unsigned long hsync_counter = 0; +unsigned long hsync_counter = 0, vsync_counter = 0; +unsigned long int idletime; +int bogusframe; /* Recording of custom chip register changes. */ static int current_change_set; @@ -274,25 +354,58 @@ static int next_color_change; static int next_color_entry, remembered_color_entry; static int color_src_match, color_dest_match, color_compare_result; +static uae_u32 thisline_changed; + +#ifdef SMART_UPDATE +#define MARK_LINE_CHANGED do { thisline_changed = 1; } while (0) +#else +#define MARK_LINE_CHANGED do { ; } while (0) +#endif + static struct decision thisline_decision; static int fetch_cycle, fetch_modulo_cycle; -static int bitplane_dma_turned_on; +static bool aga_plf_passed_stop2; +static int plf_start_hpos, plf_end_hpos; +static int ddfstop_written_hpos; +static int bitplane_off_delay; +static bool ocs_agnus_ddf_enable_toggle; +static int bpl_dma_off_when_active; +static int bitplane_maybe_start_hpos; +static bool ddfstop_matched; +static int bitplane_overrun, bitplane_overrun_hpos; +static int bitplane_overrun_fetch_cycle, bitplane_overrun_cycle_diagram_shift; enum plfstate { plf_idle, - plf_start, + // enable passed + plf_passed_enable, + // ddfstrt match + plf_passed_start, + // active (ddfstrt + 4 match) plf_active, - plf_wait_stop, + // inactive, waiting + plf_wait, + // ddfstop passed plf_passed_stop, + // ddfstop+4 passed + plf_passed_stop_act, + // last block finished plf_passed_stop2, - plf_end, - plf_finished + plf_end } plf_state; -enum fetchstate +enum plfrenderstate { + plfr_idle, + plfr_active, + plfr_end, + plfr_finished +} plfr_state; + +enum fetchstate { fetch_not_started, + fetch_started_first, fetch_started, fetch_was_plane0 } fetch_state; @@ -301,43 +414,44 @@ enum fetchstate * helper functions */ -#define nodraw() (framecnt != 0) - -void set_speedup_values() +STATIC_INLINE int ecsshres(void) { - if (currprefs.m68k_speed < 0) - { - if (currprefs.cachesize) - { - pissoff_value = SPEEDUP_CYCLES_JIT * CYCLE_UNIT; - speedup_timelimit = SPEEDUP_TIMELIMIT_JIT; - } - else - { - pissoff_value = SPEEDUP_CYCLES_NONJIT * CYCLE_UNIT; - speedup_timelimit = SPEEDUP_TIMELIMIT_NONJIT; - } - } - else - { - pissoff_value = 0; - speedup_timelimit = 0; + return bplcon0_res == RES_SUPERHIRES && (currprefs.chipset_mask & CSMASK_ECS_DENISE) && !(currprefs.chipset_mask & CSMASK_AGA); +} + +STATIC_INLINE int nodraw(void) +{ + //return !currprefs.cpu_memory_cycle_exact && framecnt != 0; + return framecnt != 0; +} + +static int doflickerfix(void) +{ + return currprefs.gfx_vresolution && doublescan < 0 && vpos < MAXVPOS; +} + +uae_u32 get_copper_address(int copno) +{ + switch (copno) { + case 1: return cop1lc; + case 2: return cop2lc; + case -1: return cop_state.ip; + default: return 0; } } - -void reset_frame_rate_hack() +void reset_frame_rate_hack(void) { - is_syncline = 0; if (currprefs.m68k_speed >= 0) return; rpt_did_reset = 1; + is_syncline = 0; vsyncmintime = read_processor_time() + vsynctimebase; - write_log (_T("Resetting frame rate hack\n")); + write_log(_T("Resetting frame rate hack\n")); } -STATIC_INLINE void setclr(uae_u16* p, uae_u16 val) +STATIC_INLINE void setclr(uae_u16 *p, uae_u16 val) { if (val & 0x8000) *p |= val & 0x7FFF; @@ -345,71 +459,129 @@ STATIC_INLINE void setclr(uae_u16* p, uae_u16 val) *p &= ~val; } -static void update_mirrors() +STATIC_INLINE void alloc_cycle(int hpos, int type) +{ +#ifdef CPUEMU_13 + cycle_line[hpos] = type; +#endif +} +STATIC_INLINE void alloc_cycle_maybe(int hpos, int type) +{ +#ifdef CPUEMU_13 + if ((cycle_line[hpos] & CYCLE_MASK) == 0) + alloc_cycle(hpos, type); +#endif +} + +void alloc_cycle_ext(int hpos, int type) +{ + alloc_cycle(hpos, type); +} + +void alloc_cycle_blitter(int hpos, uaecptr *ptr, int chnum) +{ +#ifdef CPUEMU_13 + if (cycle_line[hpos] & CYCLE_COPPER_SPECIAL) { + static int warned = 100; + uaecptr srcptr = cop_state.strobe == 1 ? cop1lc : cop2lc; + if (warned > 0) { + write_log(_T("buggy copper cycle conflict with blitter ch %c %08x <- %08x PC=%08x\n"), 'A' + (chnum - 1), *ptr, srcptr, m68k_getpc()); + warned--; + //activate_debugger (); + } + if ((currprefs.cs_hacks & 1) && currprefs.cpu_model == 68000) + *ptr = srcptr; + } +#endif + alloc_cycle(hpos, CYCLE_BLITTER); +} + +static void set_chipset_mode(void) +{ + if (currprefs.chipset_mask & CSMASK_AGA) { + fmode = fmode_saved; + } + else { + fmode = 0; + } + sprite_width = GET_SPRITEWIDTH(fmode); +} + +static void update_mirrors(void) { aga_mode = (currprefs.chipset_mask & CSMASK_AGA) != 0; + direct_rgb = aga_mode; + if (currprefs.chipset_mask & CSMASK_AGA) + sprite_sprctlmask = 0x01 | 0x08 | 0x10; + else if (currprefs.chipset_mask & CSMASK_ECS_DENISE) + sprite_sprctlmask = 0x01 | 0x10; + else + sprite_sprctlmask = 0x01; + set_chipset_mode(); } -STATIC_INLINE uae_u8* pfield_xlateptr(uaecptr plpt, int bytecount) +STATIC_INLINE uae_u8 *pfield_xlateptr(uaecptr plpt, int bytecount) { - plpt &= chipmem_bank.mask; - if ((plpt + bytecount) > chipmem_bank.allocated) - return nullptr; - return chipmem_bank.baseaddr + plpt; + if (!chipmem_check_indirect(plpt, bytecount)) { + static int count = 0; + if (!count) + count++, write_log(_T("Warning: Bad playfield pointer %08x\n"), plpt); + return NULL; + } + return chipmem_xlate_indirect(plpt); } -STATIC_INLINE void docols(struct color_entry* colentry) +static void docols(struct color_entry *colentry) { int i; - if (aga_mode) - { - for (i = 0; i < 256; i++) - { - int v = colentry->color_regs_aga[i]; +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) { + for (i = 0; i < 256; i++) { + int v = color_reg_get(colentry, i); if (v < 0 || v > 16777215) continue; - colentry->acolors[i] = CONVERT_RGB(v); + colentry->acolors[i] = getxcolor(v); } } - else - { - for (i = 0; i < 32; i++) - { - int v = colentry->color_regs_ecs[i]; + else { +#endif + for (i = 0; i < 32; i++) { + int v = color_reg_get(colentry, i); if (v < 0 || v > 4095) continue; - colentry->acolors[i] = xcolors[v]; + colentry->acolors[i] = getxcolor(v); } +#ifdef AGA } +#endif } extern struct color_entry colors_for_drawing; -void notice_new_xcolors() +void notice_new_xcolors(void) { int i; update_mirrors(); docols(¤t_colors); docols(&colors_for_drawing); - for (i = 0; i < (MAXVPOS + 1) * 2; i++) - { - docols(curr_color_tables + i); + for (i = 0; i < (MAXVPOS + 1) * 2; i++) { + docols(color_tables[0] + i); + docols(color_tables[1] + i); } } static void do_sprites(int currhp); -static void remember_ctable() +static void remember_ctable(void) { /* This can happen when program crashes very badly */ if (next_color_entry >= COLOR_TABLE_SIZE) return; - if (remembered_color_entry < 0) - { + if (remembered_color_entry < 0) { /* The colors changed since we last recorded a color map. Record a - * new one. */ + * new one. */ color_reg_cpy(curr_color_tables + next_color_entry, ¤t_colors); remembered_color_entry = next_color_entry++; } @@ -432,26 +604,32 @@ static void remember_ctable() color_src_match = oldctable; color_dest_match = remembered_color_entry; } -// thisline_changed |= changed; + thisline_changed |= changed; } else { /* We know the result of the comparison */ -// if (color_compare_result) -// thisline_changed = 1; + if (color_compare_result) + thisline_changed = 1; } } -STATIC_INLINE int get_equ_vblank_endline() +static void remember_ctable_for_border(void) +{ + remember_ctable(); +} + +STATIC_INLINE int get_equ_vblank_endline(void) { return equ_vblank_endline + (equ_vblank_toggle ? (lof_current ? 1 : 0) : 0); } -#define HARD_DDF_LIMITS_DISABLED ((beamcon0 & 0x80) || (bplcon0 & 0x40)) +#define DDF_OFFSET 4 +#define HARD_DDF_LIMITS_DISABLED ((beamcon0 & 0x80) || (beamcon0 & 0x4000) || (bplcon0 & 0x40)) /* The HRM says 0xD8, but that can't work... */ -#define HARD_DDF_STOP (HARD_DDF_LIMITS_DISABLED ? 0xff : 0xd6) -#define HARD_DDF_START_REAL 0x18 +#define HARD_DDF_STOP (HARD_DDF_LIMITS_DISABLED ? maxhpos : 0xd4) +#define HARD_DDF_START_REAL 0x14 /* Programmed rates or superhires (!) disable normal DMA limits */ -#define HARD_DDF_START (HARD_DDF_LIMITS_DISABLED ? 0x04 : 0x18) +#define HARD_DDF_START (HARD_DDF_LIMITS_DISABLED ? 0x04 : 0x14) /* Called to determine the state of the horizontal display window state * machine at the current position. It might have changed since we last @@ -459,9 +637,9 @@ STATIC_INLINE int get_equ_vblank_endline() static void decide_diw(int hpos) { /* Last hpos = hpos + 0.5, eg. normal PAL end hpos is 227.5 * 2 = 455 - OCS Denise: 9 bit hdiw counter does not reset during lines 0 to 9 - (PAL) or lines 0 to 10 (NTSC). A1000 PAL: 1 to 9, NTSC: 1 to 10. - ECS Denise and AGA: no above "features" + OCS Denise: 9 bit hdiw counter does not reset during lines 0 to 9 + (PAL) or lines 0 to 10 (NTSC). A1000 PAL: 1 to 9, NTSC: 1 to 10. + ECS Denise and AGA: no above "features" */ int hdiw = hpos >= maxhpos ? maxhpos * 2 + 1 : hpos * 2 + 2; @@ -469,20 +647,17 @@ static void decide_diw(int hpos) hdiw = diw_hcounter; /* always mask, bad programs may have set maxhpos = 256 */ hdiw &= 511; - for (;;) - { + for (;;) { int lhdiw = hdiw; if (last_hdiw > lhdiw) lhdiw = 512; - if (lhdiw >= diw_hstrt && last_hdiw < diw_hstrt && hdiwstate == DIW_waiting_start) - { + if (lhdiw >= diw_hstrt && last_hdiw < diw_hstrt && hdiwstate == DIW_waiting_start) { if (thisline_decision.diwfirstword < 0) thisline_decision.diwfirstword = diwfirstword < 0 ? PIXEL_XPOS(0) : diwfirstword; hdiwstate = DIW_waiting_stop; } - if (((hpos >= maxhpos && HARD_DDF_LIMITS_DISABLED) || (lhdiw >= diw_hstop && last_hdiw < diw_hstop)) && hdiwstate == DIW_waiting_stop) - { + if (((hpos >= maxhpos && HARD_DDF_LIMITS_DISABLED) || (lhdiw >= diw_hstop && last_hdiw < diw_hstop)) && hdiwstate == DIW_waiting_stop) { if (thisline_decision.diwlastword < 0) thisline_decision.diwlastword = diwlastword < 0 ? 0 : diwlastword; hdiwstate = DIW_waiting_start; @@ -494,22 +669,43 @@ static void decide_diw(int hpos) last_hdiw = hdiw; } -static int fetchmode; -static int delaymask; +static int fetchmode, fetchmode_size, fetchmode_mask, fetchmode_bytes; static int real_bitplane_number[3][3][9]; /* Disable bitplane DMA if planes > available DMA slots. This is needed - e.g. by the Sanity WOC demo (at the "Party Effect"). */ -STATIC_INLINE int GET_PLANES_LIMIT() +e.g. by the Sanity WOC demo (at the "Party Effect"). */ +STATIC_INLINE int GET_PLANES_LIMIT(uae_u16 bc0) { - return real_bitplane_number[fetchmode][bplcon0_res][bplcon0_planes]; + int res = GET_RES_AGNUS(bc0); + int planes = GET_PLANES(bc0); + return real_bitplane_number[fetchmode][res][planes]; } -STATIC_INLINE void add_modulo(int nr) +static void reset_moddelays(void) +{ + if (dbpl1mod_on > 0) { + bpl1mod = dbpl1mod; + dbpl1mod_on = 0; + } + if (dbpl2mod_on > 0) { + bpl2mod = dbpl2mod; + dbpl2mod_on = 0; + } +} + +static void add_modulo(int hpos, int nr) { int mod; - if (fmode & 0x4000) - { + + if (dbpl1mod_on != hpos && dbpl1mod_on) { + bpl1mod = dbpl1mod; + dbpl1mod_on = 0; + } + if (dbpl2mod_on != hpos && dbpl2mod_on) { + bpl2mod = dbpl2mod; + dbpl2mod_on = 0; + } + if (fmode & 0x4000) { if (((diwstrt >> 8) ^ vpos) & 1) mod = bpl2mod; else @@ -520,96 +716,113 @@ STATIC_INLINE void add_modulo(int nr) else mod = bpl1mod; bplpt[nr] += mod; + bplptx[nr] += mod; + reset_moddelays(); } -STATIC_INLINE void add_modulos() +static void add_modulos(void) { int m1, m2; - if (fmode & 0x4000) - { + reset_moddelays(); + if (fmode & 0x4000) { if (((diwstrt >> 8) ^ vpos) & 1) m1 = m2 = bpl2mod; else m1 = m2 = bpl1mod; } - else - { + else { m1 = bpl1mod; m2 = bpl2mod; } - switch (bplcon0_planes_limit) - { - case 8: bplpt[7] += m2; - case 7: bplpt[6] += m1; - case 6: bplpt[5] += m2; - case 5: bplpt[4] += m1; - case 4: bplpt[3] += m2; - case 3: bplpt[2] += m1; - case 2: bplpt[1] += m2; - case 1: bplpt[0] += m1; + switch (bplcon0_planes_limit) { +#ifdef AGA + case 8: bplpt[7] += m2; bplptx[7] += m2; + case 7: bplpt[6] += m1; bplptx[6] += m1; +#endif + case 6: bplpt[5] += m2; bplptx[5] += m2; + case 5: bplpt[4] += m1; bplptx[4] += m1; + case 4: bplpt[3] += m2; bplptx[3] += m2; + case 3: bplpt[2] += m1; bplptx[2] += m1; + case 2: bplpt[1] += m2; bplptx[1] += m2; + case 1: bplpt[0] += m1; bplptx[0] += m1; } } +static void finish_playfield_line(void) +{ + /* The latter condition might be able to happen in interlaced frames. */ + if (vpos >= minfirstline && (thisframe_first_drawn_line < 0 || vpos < thisframe_first_drawn_line)) + thisframe_first_drawn_line = vpos; + thisframe_last_drawn_line = vpos; + +#ifdef SMART_UPDATE + if (line_decisions[next_lineno].plflinelen != thisline_decision.plflinelen + || line_decisions[next_lineno].plfleft != thisline_decision.plfleft + || line_decisions[next_lineno].bplcon0 != thisline_decision.bplcon0 + || line_decisions[next_lineno].bplcon2 != thisline_decision.bplcon2 +#ifdef ECS_DENISE + || line_decisions[next_lineno].bplcon3 != thisline_decision.bplcon3 +#endif +#ifdef AGA + || line_decisions[next_lineno].bplcon4 != thisline_decision.bplcon4 +#endif + ) +#endif /* SMART_UPDATE */ + thisline_changed = 1; +} /* The fetch unit mainly controls ddf stop. It's the number of cycles that - are contained in an indivisible block during which ddf is active. E.g. - if DDF starts at 0x30, and fetchunit is 8, then possible DDF stops are - 0x30 + n * 8. */ +are contained in an indivisible block during which ddf is active. E.g. +if DDF starts at 0x30, and fetchunit is 8, then possible DDF stops are +0x30 + n * 8. */ static int fetchunit, fetchunit_mask; /* The delay before fetching the same bitplane again. Can be larger than - the number of bitplanes; in that case there are additional empty cycles - with no data fetch (this happens for high fetchmodes and low - resolutions). */ -static int fetchstart, fetchstart_mask; +the number of bitplanes; in that case there are additional empty cycles +with no data fetch (this happens for high fetchmodes and low +resolutions). */ +static int fetchstart, fetchstart_shift, fetchstart_mask; /* fm_maxplane holds the maximum number of planes possible with the current - fetch mode. This selects the cycle diagram: - 8 planes: 73516240 - 4 planes: 3120 - 2 planes: 10. */ -static int fm_maxplane; +fetch mode. This selects the cycle diagram: +8 planes: 73516240 +4 planes: 3120 +2 planes: 10. */ +static int fm_maxplane, fm_maxplane_shift; /* The corresponding values, by fetchmode and display resolution. */ -static const int fetchunits[] = {8,8,8,0, 16,8,8,0, 32,16,8,0}; -static const int fetchstarts[] = {3,2,1,0, 4,3,2,0, 5,4,3,0}; -static const int fm_maxplanes[] = {3,2,1,0, 3,3,2,0, 3,3,3,0}; +static const int fetchunits[] = { 8,8,8,0, 16,8,8,0, 32,16,8,0 }; +static const int fetchstarts[] = { 3,2,1,0, 4,3,2,0, 5,4,3,0 }; +static const int fm_maxplanes[] = { 3,2,1,0, 3,3,2,0, 3,3,3,0 }; static int cycle_diagram_table[3][3][9][32]; static int cycle_diagram_free_cycles[3][3][9]; static int cycle_diagram_total_cycles[3][3][9]; -static int* curr_diagram; -static const int cycle_sequences[3 * 8] = {2,1,2,1,2,1,2,1, 4,2,3,1,4,2,3,1, 8,4,6,2,7,3,5,1}; +static int *curr_diagram; +static const int cycle_sequences[3 * 8] = { 2,1,2,1,2,1,2,1, 4,2,3,1,4,2,3,1, 8,4,6,2,7,3,5,1 }; -static void create_cycle_diagram_table() +static void create_cycle_diagram_table(void) { int fm, res, cycle, planes, rplanes, v; int fetch_start, max_planes, freecycles; - const int* cycle_sequence; + const int *cycle_sequence; - for (fm = 0; fm <= 2; fm++) - { - for (res = 0; res <= 2; res++) - { + for (fm = 0; fm <= 2; fm++) { + for (res = 0; res <= 2; res++) { max_planes = fm_maxplanes[fm * 4 + res]; fetch_start = 1 << fetchstarts[fm * 4 + res]; cycle_sequence = &cycle_sequences[(max_planes - 1) * 8]; max_planes = 1 << max_planes; - for (planes = 0; planes <= 8; planes++) - { + for (planes = 0; planes <= 8; planes++) { freecycles = 0; for (cycle = 0; cycle < 32; cycle++) cycle_diagram_table[fm][res][planes][cycle] = -1; - if (planes <= max_planes) - { - for (cycle = 0; cycle < fetch_start; cycle++) - { - if (cycle < max_planes && planes >= cycle_sequence[cycle & 7]) - { + if (planes <= max_planes) { + for (cycle = 0; cycle < fetch_start; cycle++) { + if (cycle < max_planes && planes >= cycle_sequence[cycle & 7]) { v = cycle_sequence[cycle & 7]; } - else - { + else { v = 0; freecycles++; } @@ -621,7 +834,7 @@ static void create_cycle_diagram_table() rplanes = planes; if (rplanes > max_planes) rplanes = 0; - if (rplanes == 7 && fm == 0 && res == 0 && !(aga_mode)) + if (rplanes == 7 && fm == 0 && res == 0 && !(currprefs.chipset_mask & CSMASK_AGA)) rplanes = 4; real_bitplane_number[fm][res][planes] = rplanes; } @@ -629,43 +842,63 @@ static void create_cycle_diagram_table() } } - /* Used by the copper. */ static int estimated_last_fetch_cycle; static int cycle_diagram_shift; static void estimate_last_fetch_cycle(int hpos) { - if (plf_state < plf_passed_stop) - { - int stop = plfstop < hpos || plfstop > HARD_DDF_STOP ? HARD_DDF_STOP : plfstop; - /* We know that fetching is up-to-date up until hpos, so we can use fetch_cycle. */ - int fetch_cycle_at_stop = fetch_cycle + (stop - hpos); - int starting_last_block_at = (fetch_cycle_at_stop + fetchunit - 1) & ~fetchunit_mask; + int fetchunit = fetchunits[fetchmode * 4 + bplcon0_res]; + // Last fetch is always max 8 even if fetchunit is larger. + int lastfetchunit = fetchunit >= 8 ? 8 : fetchunit; - estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + fetchunit; + if (plf_state < plf_passed_stop) { + int stop; + + if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { + // ECS: stop wins if start == stop + stop = plfstop + DDF_OFFSET < hpos || plfstop > HARD_DDF_STOP ? HARD_DDF_STOP : plfstop; + } + else { + // OCS: start wins if start == stop + stop = plfstop + DDF_OFFSET <= hpos || plfstop > HARD_DDF_STOP ? HARD_DDF_STOP : plfstop; + } + /* We know that fetching is up-to-date up until hpos, so we can use fetch_cycle. */ + int fetch_cycle_at_stop = fetch_cycle + (stop - hpos + DDF_OFFSET); + int starting_last_block_at = (fetch_cycle_at_stop + fetchunit - 1) & ~(fetchunit - 1); + + estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + lastfetchunit; } - else - { - int starting_last_block_at = (fetch_cycle + fetchunit - 1) & ~fetchunit_mask; + else { + int starting_last_block_at = (fetch_cycle + fetchunit - 1) & ~(fetchunit - 1); if (plf_state == plf_passed_stop2) starting_last_block_at -= fetchunit; - estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + fetchunit; + estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + lastfetchunit; } } static uae_u32 outword[MAX_PLANES]; static int out_nbits, out_offs; -static uae_u32 todisplay[MAX_PLANES][4]; -static uae_u32 fetched[MAX_PLANES]; -static uae_u32 fetched_aga0[MAX_PLANES]; -static uae_u32 fetched_aga1[MAX_PLANES]; +static uae_u16 todisplay[MAX_PLANES], todisplay2[MAX_PLANES]; +static uae_u16 fetched[MAX_PLANES]; +static bool todisplay_fetched[2]; +#ifdef AGA +static uae_u64 todisplay_aga[MAX_PLANES], todisplay2_aga[MAX_PLANES]; +static uae_u64 fetched_aga[MAX_PLANES]; +#endif /* Expansions from bplcon0/bplcon1. */ static int toscr_res, toscr_res2p; -static int toscr_nr_planes, toscr_nr_planes2; -static int toscr_delay[2]; +static int toscr_nr_planes, toscr_nr_planes2, toscr_nr_planes_agnus, toscr_nr_planes_shifter; +static int fetchwidth; +static int toscr_delay[2], toscr_delay_adjusted[2], toscr_delay_sh[2]; +static bool shdelay_disabled; +static int delay_cycles, delay_lastcycle[2], hack_delay_shift; +static bool bplcon1_written; + +#define PLANE_RESET_HPOS 8 +static int planesactiveatresetpoint; /* The number of bits left from the last fetched words. This is an optimization - conceptually, we have to make sure the result is @@ -675,14 +908,6 @@ static int toscr_delay[2]; we can do more work at once. */ static int toscr_nbits; -/* undocumented bitplane delay hardware feature */ -static int delayoffset; - -STATIC_INLINE void compute_delay_offset() -{ - delayoffset = (16 << fetchmode) - (((plfstrt - HARD_DDF_START_REAL) & fetchstart_mask) << 1); -} - static void record_color_change2(int hpos, int regno, unsigned long value) { int pos = hpos * 2; @@ -695,85 +920,107 @@ static void record_color_change2(int hpos, int regno, unsigned long value) curr_color_changes[next_color_change].regno = -1; } -// OCS/ECS, lores, 7 planes = 4 "real" planes + BPL5DAT and BPL6DAT as static 5th and 6th plane -STATIC_INLINE int isocs7planes() +static bool isehb(uae_u16 bplcon0, uae_u16 bplcon2) { - return !(aga_mode) && bplcon0_res == 0 && bplcon0_planes == 7; + bool bplehb; + if (currprefs.chipset_mask & CSMASK_AGA) + bplehb = (bplcon0 & 0x7010) == 0x6000; + else if (currprefs.chipset_mask & CSMASK_ECS_DENISE) + bplehb = ((bplcon0 & 0xFC00) == 0x6000 || (bplcon0 & 0xFC00) == 0x7000); + else + bplehb = ((bplcon0 & 0xFC00) == 0x6000 || (bplcon0 & 0xFC00) == 0x7000) && !currprefs.cs_denisenoehb; + return bplehb; } -STATIC_INLINE int is_bitplane_dma(int hpos) +// OCS/ECS, lores, 7 planes = 4 "real" planes + BPL5DAT and BPL6DAT as static 5th and 6th plane +STATIC_INLINE int isocs7planes(void) { - if (fetch_state == fetch_not_started || hpos < plfstrt || plf_state == plf_wait_stop) + return !(currprefs.chipset_mask & CSMASK_AGA) && bplcon0_res == 0 && bplcon0_planes == 7; +} + +int is_bitplane_dma(int hpos) +{ + if (hpos < bpl_hstart || fetch_state == fetch_not_started || plf_state == plf_wait) { + if (bitplane_overrun && hpos < bitplane_overrun_hpos) { + return curr_diagram[(hpos - bitplane_overrun_cycle_diagram_shift) & fetchstart_mask]; + } return 0; + } if ((plf_state >= plf_end && hpos >= thisline_decision.plfright) || hpos >= estimated_last_fetch_cycle) return 0; return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask]; } -STATIC_INLINE void update_denise(int hpos) +STATIC_INLINE int is_bitplane_dma_inline(int hpos) { - toscr_res = GET_RES_DENISE(bplcon0d); - toscr_res2p = 2 << toscr_res; - if (bplcon0dd != bplcon0d) - { - record_color_change2(hpos, 0x100 + 0x1000, bplcon0d); - bplcon0dd = bplcon0d; - } - toscr_nr_planes = GET_PLANES(bplcon0d); - if (isocs7planes()) - { - if (toscr_nr_planes2 < 6) - toscr_nr_planes2 = 6; - } - else - { - toscr_nr_planes2 = toscr_nr_planes; + if (hpos < bpl_hstart || fetch_state == fetch_not_started || plf_state == plf_wait) { + if (bitplane_overrun && hpos < bitplane_overrun_hpos) { + return curr_diagram[(hpos - bitplane_overrun_cycle_diagram_shift) & fetchstart_mask]; + } + return 0; } + if ((plf_state >= plf_end && hpos >= thisline_decision.plfright) + || hpos >= estimated_last_fetch_cycle) + return 0; + return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask]; } -static int islinetoggle() +static int islinetoggle(void) { int linetoggle = 0; - if (!(beamcon0 & 0x0800) && !(beamcon0 & 0x0020) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - { + if (!(beamcon0 & 0x0800) && !(beamcon0 & 0x0020) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) { linetoggle = 1; // NTSC and !LOLDIS -> LOL toggles every line } - else if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS) && currprefs.ntscmode) - { + else if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS) && currprefs.ntscmode) { linetoggle = 1; // hardwired NTSC Agnus } return linetoggle; } /* Expand bplcon0/bplcon1 into the toscr_xxx variables. */ -STATIC_INLINE void compute_toscr_delay_1(int bplcon1) +static void compute_toscr_delay(int bplcon1) { int delay1 = (bplcon1 & 0x0f) | ((bplcon1 & 0x0c00) >> 6); int delay2 = ((bplcon1 >> 4) & 0x0f) | (((bplcon1 >> 4) & 0x0c00) >> 6); - int shdelay1 = (bplcon1 >> 12) & 3; - int shdelay2 = (bplcon1 >> 8) & 3; + int shdelay1 = (bplcon1 >> 8) & 3; + int shdelay2 = (bplcon1 >> 12) & 3; + int delaymask = fetchmode_mask >> toscr_res; + toscr_delay[0] = (delay1 & delaymask) << toscr_res; + toscr_delay[0] |= shdelay1 >> (RES_MAX - toscr_res); + toscr_delay[1] = (delay2 & delaymask) << toscr_res; + toscr_delay[1] |= shdelay2 >> (RES_MAX - toscr_res); + +#if SPEEDUP + /* SPEEDUP code still needs this hack */ + int delayoffset = fetchmode_size - (((bpl_hstart - (HARD_DDF_START_REAL + DDF_OFFSET)) & fetchstart_mask) << 1); delay1 += delayoffset; delay2 += delayoffset; - toscr_delay[0] = (delay1 & (delaymask >> toscr_res)) << toscr_res; - toscr_delay[0] |= shdelay1 >> (RES_MAX - toscr_res); - toscr_delay[1] = (delay2 & (delaymask >> toscr_res)) << toscr_res; - toscr_delay[1] |= shdelay2 >> (RES_MAX - toscr_res); + toscr_delay_adjusted[0] = (delay1 & delaymask) << toscr_res; + toscr_delay_adjusted[0] |= shdelay1 >> (RES_MAX - toscr_res); + toscr_delay_adjusted[1] = (delay2 & delaymask) << toscr_res; + toscr_delay_adjusted[1] |= shdelay2 >> (RES_MAX - toscr_res); +#endif } -STATIC_INLINE void compute_toscr_delay(int hpos, int bplcon1) +static void set_delay_lastcycle(void) { - update_denise(hpos); - compute_toscr_delay_1(bplcon1); + if (HARD_DDF_LIMITS_DISABLED) { + delay_lastcycle[0] = (256 * 2) << bplcon0_res; + delay_lastcycle[1] = (256 * 2) << bplcon0_res; + } + else { + delay_lastcycle[0] = ((maxhpos + 1) * 2 + 0) << bplcon0_res; + delay_lastcycle[1] = delay_lastcycle[0]; + if (islinetoggle()) + delay_lastcycle[1]++; + } } static int bpldmasetuphpos, bpldmasetuphpos_diff; static int bpldmasetupphase; - -#ifdef WITH_INGAME_WARNING -static bool shres_warned = false; -#endif +static void update_toscr_planes(int fm); /* set currently active Agnus bitplane DMA sequence */ static void setup_fmodes(int hpos) @@ -782,53 +1029,55 @@ static void setup_fmodes(int hpos) { case 0: fetchmode = 0; - delaymask = 15; // (16 << fetchmode) - 1; break; case 1: case 2: fetchmode = 1; - delaymask = 31; // (16 << fetchmode) - 1; break; case 3: fetchmode = 2; - delaymask = 63; // (16 << fetchmode) - 1; break; } + badmode = GET_RES_AGNUS(bplcon0) != GET_RES_DENISE(bplcon0); bplcon0_res = GET_RES_AGNUS(bplcon0); - if (bplcon0_res == RES_SUPERHIRES) - { -#ifdef WITH_INGAME_WARNING - if (!shres_warned) - { - InGameMessage("Superhires resolution requested.\nNot supported in UAE4ARM."); - shres_warned = true; - } -#endif - bplcon0_res = RES_LORES; - } bplcon0_planes = GET_PLANES(bplcon0); - bplcon0_planes_limit = GET_PLANES_LIMIT(); + bplcon0_planes_limit = GET_PLANES_LIMIT(bplcon0); fetchunit = fetchunits[fetchmode * 4 + bplcon0_res]; fetchunit_mask = fetchunit - 1; - int fetchstart_shift = fetchstarts[fetchmode * 4 + bplcon0_res]; + fetchstart_shift = fetchstarts[fetchmode * 4 + bplcon0_res]; fetchstart = 1 << fetchstart_shift; fetchstart_mask = fetchstart - 1; - int fm_maxplane_shift = fm_maxplanes[fetchmode * 4 + bplcon0_res]; + fm_maxplane_shift = fm_maxplanes[fetchmode * 4 + bplcon0_res]; fm_maxplane = 1 << fm_maxplane_shift; fetch_modulo_cycle = fetchunit - fetchstart; + fetchmode_size = 16 << fetchmode; + fetchmode_bytes = 2 << fetchmode; + fetchmode_mask = fetchmode_size - 1; + set_delay_lastcycle(); + compute_toscr_delay(bplcon1); - if (thisline_decision.plfleft < 0) - { + if (thisline_decision.plfleft < 0) { thisline_decision.bplres = bplcon0_res; thisline_decision.bplcon0 = bplcon0; thisline_decision.nr_planes = bplcon0_planes; } - +#ifdef CPUEMU_13 + if (is_bitplane_dma(hpos - 1)) + cycle_line[hpos - 1] = 1; +#endif curr_diagram = cycle_diagram_table[fetchmode][bplcon0_res][bplcon0_planes_limit]; estimate_last_fetch_cycle(hpos); +#ifdef DEBUGGER + if (bpldmasetuphpos >= 0 && debug_dma) + record_dma_event(DMA_EVENT_BPLFETCHUPDATE, hpos, vpos); +#endif bpldmasetuphpos = -1; bpldmasetupphase = 0; - line_cyclebased = vpos; + toscr_nr_planes_agnus = bplcon0_planes; + if (isocs7planes()) { + toscr_nr_planes_agnus = 6; + } + SET_LINE_CYCLEBASED; } static void BPLCON0_Denise(int hpos, uae_u16 v, bool); @@ -840,7 +1089,7 @@ static void BPLCON0_Denise(int hpos, uae_u16 v, bool); #define BPLCON_AGNUS_DELAY (3 + (copper_access ? 1 : 0) + (bplcon0_planes == 8 ? 1 : 0)) #define BPLCON_DENISE_DELAY (copper_access ? 1 : 0) -STATIC_INLINE void maybe_setup_fmodes(int hpos) +static void maybe_setup_fmodes(int hpos) { switch (bpldmasetupphase) { @@ -863,216 +1112,399 @@ STATIC_INLINE void maybe_check(int hpos) static void bpldmainitdelay(int hpos) { - line_cyclebased = vpos; - if (hpos + BPLCON_AGNUS_DELAY < 0x14) - { + SET_LINE_CYCLEBASED; + if (!bitplane_overrun && hpos + BPLCON_AGNUS_DELAY < 0x14) { BPLCON0_Denise(hpos, bplcon0, false); setup_fmodes(hpos); return; } - if (bpldmasetuphpos < 0) - { + if (bpldmasetuphpos < 0) { bpldmasetuphpos = hpos + BPLCON_DENISE_DELAY; bpldmasetuphpos_diff = BPLCON_AGNUS_DELAY - BPLCON_DENISE_DELAY; bpldmasetupphase = 0; - if (BPLCON_DENISE_DELAY == 0) - { + if (BPLCON_DENISE_DELAY == 0) { maybe_setup_fmodes(hpos); } } } -STATIC_INLINE void update_toscr_planes() +STATIC_INLINE void clear_fetchbuffer(uae_u32 *ptr, int nwords) { - if (toscr_nr_planes2 > thisline_decision.nr_planes) - { - if (thisline_decision.nr_planes > 0) - { - int j; - for (j = thisline_decision.nr_planes; j < toscr_nr_planes2; j++) - memset(reinterpret_cast(line_data[next_lineno] + 2 * MAX_WORDS_PER_LINE * j), 0, out_offs * 4); + int i; + + if (!thisline_changed) { + for (i = 0; i < nwords; i++) { + if (ptr[i]) { + thisline_changed = 1; + break; + } } - thisline_decision.nr_planes = toscr_nr_planes2; + } + memset(ptr, 0, nwords * 4); +} + +static void update_toscr_planes(int fm) +{ + // This must be called just before new bitplane block starts, + // not when depth value changes. Depth can change early and can leave + // 16+ pixel horizontal line of old data visible. + if (toscr_nr_planes_agnus > thisline_decision.nr_planes) { + if (out_offs) { + int j; + for (j = thisline_decision.nr_planes; j < toscr_nr_planes_agnus; j++) { + clear_fetchbuffer(reinterpret_cast(line_data[next_lineno] + 2 * MAX_WORDS_PER_LINE * j), out_offs); + if (thisline_decision.plfleft >= 0) { + todisplay[j] = 0; +#ifdef AGA + if (fm) + todisplay_aga[j] = 0; +#endif + } + } + } + thisline_decision.nr_planes = toscr_nr_planes_agnus; } } STATIC_INLINE void maybe_first_bpl1dat(int hpos) { - if (thisline_decision.plfleft >= 0) - { - // early bpl1dat crap fix (Sequential engine animation) - if (plfleft_real < 0) - { - int i; - for (i = 0; i < MAX_PLANES; i++) - { - todisplay[i][0] = 0; - todisplay[i][1] = 0; - todisplay[i][2] = 0; - todisplay[i][3] = 0; - } - plfleft_real = hpos; - bpl1dat_early = true; - } - } - else - { - plfleft_real = thisline_decision.plfleft = hpos; - compute_delay_offset(); - } + if (thisline_decision.plfleft < 0) + thisline_decision.plfleft = hpos; } -STATIC_INLINE void fetch(int nr, int fm) +static int fetch_warn(int nr, int hpos) { - if (nr < bplcon0_planes_limit) - { - uaecptr p = bplpt[nr]; + static int warned1 = 30, warned2 = 30; + int add = fetchmode_bytes; + if (hpos == maxhpos - 1 || hpos == 1 || hpos == 3 || hpos == 5) { + if (warned1 >= 0) { + write_log(_T("WARNING: BPL fetch conflicts with strobe refresh slot %d!\n"), hpos); + warned1--; + } + add = refptr_val; + } + else { + if (warned2 >= 0) { + warned2--; + write_log(_T("WARNING: BPL fetch at hpos 0x%02X!\n"), hpos); + } + add = refptr_val; + } + bitplane_line_crossing = hpos; + return add; + } + +static void fetch(int nr, int fm, bool modulo, int hpos) +{ + if (nr < bplcon0_planes_limit) { + uaecptr p; + int add = fetchmode_bytes; + + // refresh conflict? + if ((hpos > maxhpos - HPOS_SHIFT || hpos == 1 || hpos == 3 || hpos == 5) && !(beamcon0 & 0x80)) { + add = fetch_warn(nr, hpos); + } + + p = bplpt[nr]; + bplpt[nr] += add; + bplptx[nr] += add; + if (nr == 0) bpl1dat_written = true; + +#ifdef DEBUGGER + if (debug_dma) + record_dma(0x110 + nr * 2, chipmem_wget_indirect(p), p, hpos, vpos, DMARECORD_BITPLANE); + if (memwatch_enabled) + debug_wgetpeekdma_chipram(p, chipmem_wget_indirect(p), MW_MASK_BPL_0 << nr, 0x110 + nr * 2); +#endif switch (fm) { case 0: - fetched[nr] = bplxdat[nr] = last_custom_value1 = chipmem_wget_indirect(p); - bplpt[nr] += 2; + fetched[nr] = chipmem_wget_indirect(p); + last_custom_value1 = fetched[nr]; break; +#ifdef AGA case 1: - fetched_aga0[nr] = chipmem_lget_indirect(p); - last_custom_value1 = uae_u16(fetched_aga0[nr]); - bplpt[nr] += 4; + fetched_aga[nr] = chipmem_lget_indirect(p); + last_custom_value1 = fetched_aga[nr]; + fetched[nr] = uae_u16(fetched_aga[nr]); break; case 2: - fetched_aga1[nr] = chipmem_lget_indirect(p); - fetched_aga0[nr] = chipmem_lget_indirect(p + 4); - last_custom_value1 = uae_u16(fetched_aga0[nr]); - bplpt[nr] += 8; + fetched_aga[nr] = static_cast(chipmem_lget_indirect(p)) << 32; + fetched_aga[nr] |= chipmem_lget_indirect(p + 4); + last_custom_value1 = uae_u32(fetched_aga[nr]); + fetched[nr] = uae_u16(fetched_aga[nr]); break; +#endif } - if (plf_state == plf_passed_stop2 && fetch_cycle >= (fetch_cycle & ~fetchunit_mask) + fetch_modulo_cycle) - { - add_modulo(nr); - } - } - else - { - // use whatever left in BPLxDAT if no DMA - // normally useless but "7-planes" feature won't work without this - fetched[nr] = bplxdat[nr]; + if (modulo) + add_modulo(hpos, nr); } } -STATIC_INLINE void toscr_3_ecs(int nbits) +STATIC_INLINE void toscr_3_ecs(int oddeven, int step, int nbits) +{ + int i; + int shift = 16 - nbits; + + // if number of planes decrease (or go to zero), we still need to + // shift all possible remaining pixels out of Denise's shift register + for (i = oddeven; i < thisline_decision.nr_planes; i += step) { + outword[i] <<= nbits; + } + + for (i = oddeven; i < toscr_nr_planes2; i += step) { + outword[i] |= todisplay2[i] >> shift; + todisplay2[i] <<= nbits; + } +} + +#ifdef AGA + +STATIC_INLINE void toscr_3_aga(int oddeven, int step, int nbits, int fm) { - int delay1 = toscr_delay[0]; - int delay2 = toscr_delay[1]; int i; uae_u32 mask = 0xFFFF >> (16 - nbits); + int shift = fetchmode_size - nbits; - for (i = 0; i < toscr_nr_planes2; i += 2) - { + for (i = oddeven; i < thisline_decision.nr_planes; i += step) { outword[i] <<= nbits; - outword[i] |= (todisplay[i][0] >> (16 - nbits + delay1)) & mask; - todisplay[i][0] <<= nbits; } - for (i = 1; i < toscr_nr_planes2; i += 2) - { - outword[i] <<= nbits; - outword[i] |= (todisplay[i][0] >> (16 - nbits + delay2)) & mask; - todisplay[i][0] <<= nbits; + + for (i = oddeven; i < toscr_nr_planes2; i += step) { + outword[i] |= (todisplay2_aga[i] >> shift) & mask; + todisplay2_aga[i] <<= nbits; } } -STATIC_INLINE void shift32plus(uae_u32* p, int n) -{ - uae_u32 t = p[1]; - t <<= n; - t |= p[0] >> (32 - n); - p[1] = t; -} +#endif -STATIC_INLINE void aga_shift(uae_u32* p, int n, int fm) +static void toscr_2_0(int nbits) { toscr_3_ecs(0, 1, nbits); } +static void toscr_2_0_oe(int oddeven, int step, int nbits) { toscr_3_ecs(oddeven, step, nbits); } +#ifdef AGA +static void toscr_2_1(int nbits) { toscr_3_aga(0, 1, nbits, 1); } +static void toscr_2_1_oe(int oddeven, int step, int nbits) { toscr_3_aga(oddeven, step, nbits, 1); } +static void toscr_2_2(int nbits) { toscr_3_aga(0, 1, nbits, 2); } +static void toscr_2_2_oe(int oddeven, int step, int nbits) { toscr_3_aga(oddeven, step, nbits, 2); } +#endif + +STATIC_INLINE void do_tosrc(int oddeven, int step, int nbits, int fm) { - if (fm == 2) - { - shift32plus(p + 2, n); - shift32plus(p + 1, n); + switch (fm) { + case 0: + if (step == 2) + toscr_2_0_oe(oddeven, step, nbits); + else + toscr_2_0(nbits); + break; +#ifdef AGA + case 1: + if (step == 2) + toscr_2_1_oe(oddeven, step, nbits); + else + toscr_2_1(nbits); + break; + case 2: + if (step == 2) + toscr_2_2_oe(oddeven, step, nbits); + else + toscr_2_2(nbits); + break; +#endif } - shift32plus(p + 0, n); - p[0] <<= n; } - -STATIC_INLINE void toscr_3_aga(int nbits, int fm) +STATIC_INLINE void do_delays_3_ecs(int nbits) { - int delay1 = toscr_delay[0]; - int delay2 = toscr_delay[1]; - int i; - uae_u32 mask = 0xFFFF >> (16 - nbits); + int delaypos = delay_cycles & fetchmode_mask; + for (int oddeven = 0; oddeven < 2; oddeven++) { + int delay = toscr_delay[oddeven]; + if (delaypos > delay) + delay += fetchmode_size; + int diff = delay - delaypos; + int nbits2 = nbits; + if (nbits2 > diff) { + do_tosrc(oddeven, 2, diff, 0); + nbits2 -= diff; + if (todisplay_fetched[oddeven]) { + for (int i = oddeven; i < toscr_nr_planes_shifter; i += 2) + todisplay2[i] = todisplay[i]; + todisplay_fetched[oddeven] = false; + } + } + if (nbits2) + do_tosrc(oddeven, 2, nbits2, 0); + } +} - { - int offs = (16 << fm) - nbits + delay1; - int off1 = offs >> 5; - if (off1 == 3) - off1 = 2; - offs -= off1 * 32; - for (i = 0; i < toscr_nr_planes2; i += 2) - { - uae_u32 t0 = todisplay[i][off1]; - uae_u32 t1 = todisplay[i][off1 + 1]; - uae_u64 t = (static_cast(t1) << 32) | t0; - outword[i] <<= nbits; - outword[i] |= (t >> offs) & mask; - aga_shift(todisplay[i], nbits, fm); +STATIC_INLINE void do_delays_fast_3_ecs(int nbits) +{ + int delaypos = delay_cycles & fetchmode_mask; + int delay = toscr_delay[0]; + if (delaypos > delay) + delay += fetchmode_size; + int diff = delay - delaypos; + int nbits2 = nbits; + if (nbits2 > diff) { + do_tosrc(0, 1, diff, 0); + nbits2 -= diff; + if (todisplay_fetched[0]) { + for (int i = 0; i < toscr_nr_planes_shifter; i++) + todisplay2[i] = todisplay[i]; + todisplay_fetched[0] = false; + todisplay_fetched[1] = false; } } - { - int offs = (16 << fm) - nbits + delay2; - int off1 = offs >> 5; - if (off1 == 3) - off1 = 2; - offs -= off1 * 32; - for (i = 1; i < toscr_nr_planes2; i += 2) - { - uae_u32 t0 = todisplay[i][off1]; - uae_u32 t1 = todisplay[i][off1 + 1]; - uae_u64 t = (static_cast(t1) << 32) | t0; - outword[i] <<= nbits; - outword[i] |= (t >> offs) & mask; - aga_shift(todisplay[i], nbits, fm); + if (nbits2) + do_tosrc(0, 1, nbits2, 0); +} + +STATIC_INLINE void do_delays_3_aga(int nbits, int fm) +{ + int delaypos = delay_cycles & fetchmode_mask; + for (int oddeven = 0; oddeven < 2; oddeven++) { + int delay = toscr_delay[oddeven]; + if (delaypos > delay) + delay += fetchmode_size; + int diff = delay - delaypos; + int nbits2 = nbits; + if (nbits2 > diff) { + do_tosrc(oddeven, 2, diff, fm); + nbits2 -= diff; + if (todisplay_fetched[oddeven]) { + for (int i = oddeven; i < toscr_nr_planes_shifter; i += 2) + todisplay2_aga[i] = todisplay_aga[i]; + todisplay_fetched[oddeven] = false; + } } + if (nbits2) + do_tosrc(oddeven, 2, nbits2, fm); } } -static void toscr_2_0(int nbits) { toscr_3_ecs(nbits); } -static void toscr_2_1(int nbits) { toscr_3_aga(nbits, 1); } -static void toscr_2_2(int nbits) { toscr_3_aga(nbits, 2); } +STATIC_INLINE void do_delays_fast_3_aga(int nbits, int fm) +{ + int delaypos = delay_cycles & fetchmode_mask; + int delay = toscr_delay[0]; + if (delaypos > delay) + delay += fetchmode_size; + int diff = delay - delaypos; + int nbits2 = nbits; + if (nbits2 > diff) { + do_tosrc(0, 1, diff, fm); + nbits2 -= diff; + if (todisplay_fetched[0]) { + for (int i = 0; i < toscr_nr_planes_shifter; i++) + todisplay2_aga[i] = todisplay_aga[i]; + todisplay_fetched[0] = false; + todisplay_fetched[1] = false; + } + } + if (nbits2) + do_tosrc(0, 1, nbits2, fm); +} + +static void do_delays_2_0(int nbits) { do_delays_3_ecs(nbits); } +#ifdef AGA +static void do_delays_2_1(int nbits) { do_delays_3_aga(nbits, 1); } +static void do_delays_2_2(int nbits) { do_delays_3_aga(nbits, 2); } +#endif +static void do_delays_fast_2_0(int nbits) { do_delays_fast_3_ecs(nbits); } +#ifdef AGA +static void do_delays_fast_2_1(int nbits) { do_delays_fast_3_aga(nbits, 1); } +static void do_delays_fast_2_2(int nbits) { do_delays_fast_3_aga(nbits, 2); } +#endif + + +// slower version, odd and even delays are different or crosses maxhpos +STATIC_INLINE void do_delays(int nbits, int fm) +{ + switch (fm) { + case 0: + do_delays_2_0(nbits); + break; +#ifdef AGA + case 1: + do_delays_2_1(nbits); + break; + case 2: + do_delays_2_2(nbits); + break; +#endif + } +} + +// common optimized case: odd delay == even delay +STATIC_INLINE void do_delays_fast(int nbits, int fm) +{ + switch (fm) { + case 0: + do_delays_fast_2_0(nbits); + break; +#ifdef AGA + case 1: + do_delays_fast_2_1(nbits); + break; + case 2: + do_delays_fast_2_2(nbits); + break; +#endif + } +} + +static void toscr_right_edge(int nbits, int fm) +{ + // Emulate hpos counter (delay_cycles) reseting at the end of scanline. + // (Result is ugly shift in graphics in far right overscan) + int diff = delay_lastcycle[lol] - delay_cycles; + int nbits2 = nbits; + if (nbits2 >= diff) { + do_delays(diff, fm); + nbits2 -= diff; + delay_cycles = 0; + if (hpos_is_zero_bplcon1_hack >= 0) { + compute_toscr_delay(hpos_is_zero_bplcon1_hack); + hpos_is_zero_bplcon1_hack = -1; + } + toscr_delay[0] -= 2; + toscr_delay[0] &= fetchmode_mask; + toscr_delay[1] -= 2; + toscr_delay[1] &= fetchmode_mask; + } + if (nbits2) { + do_delays(nbits2, fm); + delay_cycles += nbits2; + } +} STATIC_INLINE void toscr_1(int nbits, int fm) { - switch (fm) - { - case 0: - toscr_2_0(nbits); - break; - case 1: - toscr_2_1(nbits); - break; - case 2: - toscr_2_2(nbits); - break; + if (delay_cycles + nbits >= delay_lastcycle[lol]) { + toscr_right_edge(nbits, fm); + } + else if (toscr_delay[0] == toscr_delay[1]) { + // Most common case. + do_delays_fast(nbits, fm); + delay_cycles += nbits; + } + else { + do_delays(nbits, fm); + delay_cycles += nbits; } out_nbits += nbits; - if (out_nbits == 32) - { + if (out_nbits == 32) { int i; - uae_u32* dataptr32 = reinterpret_cast(line_data[next_lineno]); - dataptr32 += out_offs; - - for (i = 0; i < thisline_decision.nr_planes; i++) - { - *dataptr32 = outword[i]; + uae_u8 *dataptr = line_data[next_lineno] + out_offs * 4; + for (i = 0; i < thisline_decision.nr_planes; i++) { + uae_u32 *dataptr32 = reinterpret_cast(dataptr); + if (*dataptr32 != outword[i]) { + thisline_changed = 1; + *dataptr32 = outword[i]; + } outword[i] = 0; - dataptr32 += MAX_WORDS_PER_LINE >> 1; + dataptr += MAX_WORDS_PER_LINE * 2; } out_offs++; out_nbits = 0; @@ -1085,14 +1517,12 @@ static void toscr_fm2(int); STATIC_INLINE void toscr(int nbits, int fm) { - switch (fm) - { - case 0: toscr_fm0(nbits); - break; - case 1: toscr_fm1(nbits); - break; - case 2: toscr_fm2(nbits); - break; + switch (fm) { + case 0: toscr_fm0(nbits); break; +#ifdef AGA + case 1: toscr_fm1(nbits); break; + case 2: toscr_fm2(nbits); break; +#endif } } @@ -1100,15 +1530,13 @@ STATIC_INLINE void toscr_0(int nbits, int fm) { int t; - if (nbits > 16) - { + if (nbits > 16) { toscr(16, fm); nbits -= 16; } t = 32 - out_nbits; - if (t < nbits) - { + if (t < nbits) { toscr_1(t, fm); nbits -= t; } @@ -1119,36 +1547,29 @@ static void toscr_fm0(int nbits) { toscr_0(nbits, 0); } static void toscr_fm1(int nbits) { toscr_0(nbits, 1); } static void toscr_fm2(int nbits) { toscr_0(nbits, 2); } -STATIC_INLINE int flush_plane_data(int fm) +static int flush_plane_data(int fm) { int i = 0; - if (out_nbits <= 16) - { + if (out_nbits <= 16) { i += 16; toscr_1(16, fm); } - if (out_nbits != 0) - { + if (out_nbits != 0) { i += 32 - out_nbits; toscr_1(32 - out_nbits, fm); } + i += 32; toscr_1(16, fm); toscr_1(16, fm); - if (fm == 2) - { - /* flush AGA full 64-bit shift register */ + if (fm == 2) { + /* flush AGA full 64-bit shift register + possible data in todisplay */ i += 32; toscr_1(16, fm); toscr_1(16, fm); - } - - if (bpl1dat_early) - { - // clear possible crap in right border if - // bpl1dat was written "out of sync" + i += 32; toscr_1(16, fm); toscr_1(16, fm); } @@ -1163,488 +1584,732 @@ STATIC_INLINE void flush_display(int fm) toscr_nbits = 0; } -STATIC_INLINE void fetch_start() +static void record_color_change(int hpos, int regno, unsigned long value); + +static void hack_shres_delay(int hpos) +{ + if (!(currprefs.chipset_mask & CSMASK_AGA) && !toscr_delay_sh[0] && !toscr_delay_sh[1]) + return; + int o0 = toscr_delay_sh[0]; + int o1 = toscr_delay_sh[1]; + int shdelay1 = (bplcon1 >> 8) & 3; + int shdelay2 = (bplcon1 >> 12) & 3; + if (shdelay1 != shdelay2) { + shdelay_disabled = true; + } + if (shdelay_disabled) { + toscr_delay_sh[0] = 0; + toscr_delay_sh[1] = 0; + } + else { + toscr_delay_sh[0] = (shdelay1 & 3) >> toscr_res; + toscr_delay_sh[1] = (shdelay2 & 3) >> toscr_res; + } + if (hpos >= 0 && (toscr_delay_sh[0] != o0 || toscr_delay_sh[1] != o1)) { + record_color_change(hpos, 0, COLOR_CHANGE_SHRES_DELAY | toscr_delay_sh[0]); + current_colors.extra &= ~(1 << CE_SHRES_DELAY); + current_colors.extra &= ~(1 << (CE_SHRES_DELAY + 1)); + current_colors.extra |= toscr_delay_sh[0] << CE_SHRES_DELAY; + remembered_color_entry = -1; + thisline_changed = true; + } +} + +static void update_denise_shifter_planes(int hpos) +{ + int np = GET_PLANES(bplcon0d); + // if DMA has ended but there is still data waiting in todisplay, + // it must be flushed out before number of planes change + if (np < toscr_nr_planes_shifter && hpos > thisline_decision.plfright && thisline_decision.plfright && (todisplay_fetched[0] || todisplay_fetched[1])) { + int diff = (hpos - thisline_decision.plfright) << (1 + toscr_res); + while (diff >= 16) { + toscr_1(16, fetchmode); + diff -= 16; + } + if (diff) + toscr_1(diff, fetchmode); + thisline_decision.plfright += hpos - thisline_decision.plfright; + } + // FIXME: Samplers / Back In 90 vs Disposable Hero title screen in fast modes + if (currprefs.cpu_model < 68020) { + toscr_nr_planes_shifter = np; + if (isocs7planes()) { + if (toscr_nr_planes_shifter < 6) + toscr_nr_planes_shifter = 6; + } + } +} + +static void update_denise(int hpos) +{ + int res = GET_RES_DENISE(bplcon0d); + if (res != toscr_res) + flush_display(fetchmode); + toscr_res = GET_RES_DENISE(bplcon0d); + toscr_res2p = 2 << toscr_res; + delay_cycles = (hpos * 2) << toscr_res; + if (bplcon0dd != bplcon0d) { + record_color_change2(hpos, 0x100 + 0x1000, bplcon0d); + bplcon0dd = bplcon0d; + } + toscr_nr_planes = GET_PLANES(bplcon0d); + if (isocs7planes()) { + if (toscr_nr_planes2 < 6) + toscr_nr_planes2 = 6; + } + else { + toscr_nr_planes2 = toscr_nr_planes; + } + toscr_nr_planes_shifter = toscr_nr_planes2; + hack_shres_delay(hpos); +} + +STATIC_INLINE void fetch_start(int hpos) { fetch_state = fetch_started; } /* Called when all planes have been fetched, i.e. when a new block - of data is available to be displayed. The data in fetched[] is - moved into todisplay[]. */ -STATIC_INLINE void beginning_of_plane_block_x(int hpos, int fm) +of data is available to be displayed. The data in fetched[] is +moved into todisplay[]. */ +static void beginning_of_plane_block(int hpos, int fm) { int i; - int oleft = thisline_decision.plfleft; - static uae_u16 bplcon1t, bplcon1t2; - - flush_display(fm); if (fm == 0) - for (i = 0; i < MAX_PLANES; i++) - { - todisplay[i][0] |= fetched[i]; + for (i = 0; i < MAX_PLANES; i++) { + todisplay[i] = fetched[i]; } +#ifdef AGA else - for (i = 0; i < MAX_PLANES; i++) - { - if (fm == 2) - todisplay[i][1] = fetched_aga1[i]; - todisplay[i][0] = fetched_aga0[i]; + for (i = 0; i < MAX_PLANES; i++) { + todisplay_aga[i] = fetched_aga[i]; } - - update_denise(hpos); +#endif + todisplay_fetched[0] = todisplay_fetched[1] = true; maybe_first_bpl1dat(hpos); - - bplcon1t2 = bplcon1t; - bplcon1t = bplcon1; - // writing to BPLCON1 1 cycle after BPL1DAT access will - // not (except first BPL1DAT write) affect the display - // until next display block - if (bplcon1_hpos != hpos || oleft < 0) - bplcon1t2 = bplcon1t; - compute_toscr_delay(hpos, bplcon1t2); + update_denise(hpos); + if (toscr_nr_planes_agnus > thisline_decision.nr_planes) + update_toscr_planes(fm); } -static void beginning_of_plane_block_0(int hpos) { beginning_of_plane_block_x(hpos, 0); }; -static void beginning_of_plane_block_1(int hpos) { beginning_of_plane_block_x(hpos, 1); }; -static void beginning_of_plane_block_2(int hpos) { beginning_of_plane_block_x(hpos, 2); }; -STATIC_INLINE void beginning_of_plane_block(int hpos, int fm) -{ - if (fm == 0) - beginning_of_plane_block_0(hpos); - else if (fm == 1) - beginning_of_plane_block_1(hpos); - else - beginning_of_plane_block_2(hpos); -} +#ifdef SPEEDUP /* The usual inlining tricks - don't touch unless you know what you are doing. */ -STATIC_INLINE void long_fetch_ecs(int plane, int nwords, int weird_number_of_bits, int dma) +STATIC_INLINE void long_fetch_16(int plane, int nwords, int weird_number_of_bits, int dma) { - uae_u16* real_pt = reinterpret_cast(pfield_xlateptr(bplpt[plane], nwords * 2)); - int delay = toscr_delay[(plane & 1)]; + uae_u16 *real_pt = reinterpret_cast(pfield_xlateptr(bplpt[plane], nwords * 2)); + int delay = toscr_delay_adjusted[plane & 1]; int tmp_nbits = out_nbits; - uae_u32 shiftbuffer = todisplay[plane][0]; + uae_u32 shiftbuffer; uae_u32 outval = outword[plane]; uae_u32 fetchval = fetched[plane]; - uae_u32* dataptr_start = reinterpret_cast(line_data[next_lineno] + (2 * plane * MAX_WORDS_PER_LINE)); - uae_u32* dataptr = dataptr_start + out_offs; + uae_u32 *dataptr = reinterpret_cast(line_data[next_lineno] + 2 * plane * MAX_WORDS_PER_LINE + 4 * out_offs); - if (dma) - { + if (dma) { bplpt[plane] += nwords * 2; + bplptx[plane] += nwords * 2; } if (real_pt == nullptr) - /* @@@ Don't do this, fall back on chipmem_wget instead. */ + /* @@@ Don't do this, fall back on chipmem_wget instead. */ return; - while (nwords > 0) - { + shiftbuffer = todisplay2[plane] << delay; + + while (nwords > 0) { int bits_left = 32 - tmp_nbits; uae_u32 t; + shiftbuffer |= fetchval; + t = (shiftbuffer >> delay) & 0xffff; - if (weird_number_of_bits && bits_left < 16) - { + if (weird_number_of_bits && bits_left < 16) { outval <<= bits_left; outval |= t >> (16 - bits_left); + thisline_changed |= *dataptr ^ outval; *dataptr++ = outval; + outval = t; tmp_nbits = 16 - bits_left; } - else - { + else { outval = (outval << 16) | t; tmp_nbits += 16; - if (tmp_nbits == 32) - { + if (tmp_nbits == 32) { + thisline_changed |= *dataptr ^ outval; *dataptr++ = outval; tmp_nbits = 0; } } shiftbuffer <<= 16; nwords--; - if (dma) - { - __asm__( - "ldrh %[val], [%[pt]], #2 \n\t" - "rev16 %[val], %[val] \n\t" - : [val] "=r"(fetchval), [pt] "+r"(real_pt)); + if (dma) { + fetchval = do_get_mem_word(real_pt); + real_pt++; } } fetched[plane] = fetchval; - todisplay[plane][0] = shiftbuffer; + todisplay2[plane] = shiftbuffer >> delay; outword[plane] = outval; } - -STATIC_INLINE void long_fetch_aga(int plane, int nwords, int weird_number_of_bits, int fm, int dma) +#ifdef AGA +STATIC_INLINE void long_fetch_32(int plane, int nwords, int weird_number_of_bits, int dma) { - uae_u32* real_pt = reinterpret_cast(pfield_xlateptr(bplpt[plane], nwords * 2)); - int delay = toscr_delay[plane & 1]; + uae_u32 *real_pt = reinterpret_cast(pfield_xlateptr(bplpt[plane], nwords * 2)); + int delay = toscr_delay_adjusted[plane & 1]; int tmp_nbits = out_nbits; + uae_u64 shiftbuffer; uae_u32 outval = outword[plane]; - uae_u32 fetchval0 = fetched_aga0[plane]; - uae_u32 fetchval1 = fetched_aga1[plane]; - uae_u32* dataptr_start = reinterpret_cast(line_data[next_lineno] + 2 * plane * MAX_WORDS_PER_LINE); - uae_u32* dataptr = dataptr_start + out_offs; + uae_u32 fetchval = fetched_aga[plane]; + uae_u32 *dataptr = reinterpret_cast(line_data[next_lineno] + 2 * plane * MAX_WORDS_PER_LINE + 4 * out_offs); - int offs = (16 << fm) - 16 + delay; - int off1 = offs >> 5; - if (off1 == 3) - off1 = 2; - offs -= off1 << 5; - - if (dma) - { + if (dma) { bplpt[plane] += nwords * 2; + bplptx[plane] += nwords * 2; } - if (real_pt == nullptr) - /* @@@ Don't do this, fall back on chipmem_wget instead. */ + if (real_pt == 0) + /* @@@ Don't do this, fall back on chipmem_wget instead. */ return; - /* Instead of shifting a 64 bit value more than 16 bits, we */ - /* move the pointer for x bytes and shift a 32 bit value less */ - /* than 16 bits. See (1) */ - int buffer_add = (offs >> 4); - offs &= 15; + shiftbuffer = todisplay2_aga[plane] << delay; - while (nwords > 0) - { - int i; - uae_u32* shiftbuffer = todisplay[plane]; + while (nwords > 0) { - shiftbuffer[0] = fetchval0; - if (fm == 2) - shiftbuffer[1] = fetchval1; + shiftbuffer |= fetchval; - /* (1) */ - if (buffer_add) - shiftbuffer = reinterpret_cast(reinterpret_cast(shiftbuffer) + buffer_add); - - for (i = 0; i < (1 << fm); i++) - { + for (int i = 0; i < 2; i++) { + uae_u32 t; int bits_left = 32 - tmp_nbits; - uae_u32 t0 = shiftbuffer[off1]; + t = (shiftbuffer >> (16 + delay)) & 0xffff; - t0 = uae_u32((t0 >> offs) & 0xFFFF); - - - if (weird_number_of_bits && bits_left < 16) - { + if (weird_number_of_bits && bits_left < 16) { outval <<= bits_left; - outval |= t0 >> (16 - bits_left); + outval |= t >> (16 - bits_left); + + thisline_changed |= *dataptr ^ outval; *dataptr++ = outval; - outval = t0; + + outval = t; tmp_nbits = 16 - bits_left; - /* Instead of shifting 128 bit of data for 16 bit, */ - /* we move the pointer two bytes. See also (2) and (3) */ - /*aga_shift (shiftbuffer, 16, fm); */ - shiftbuffer = reinterpret_cast(reinterpret_cast(shiftbuffer) - 1); } - else - { - outval = (outval << 16) | t0; - /* (2) */ - /*aga_shift (shiftbuffer, 16, fm); */ - shiftbuffer = reinterpret_cast(reinterpret_cast(shiftbuffer) - 1); + else { + outval = (outval << 16) | t; tmp_nbits += 16; - if (tmp_nbits == 32) - { + if (tmp_nbits == 32) { + thisline_changed |= *dataptr ^ outval; *dataptr++ = outval; tmp_nbits = 0; } } + shiftbuffer <<= 16; + } + nwords -= 2; + if (dma) { + fetchval = do_get_mem_long(real_pt); + real_pt++; } - /* (3) */ - /* We have to move the data, but now, we can simply */ - /* copy long values and have to do it only once. */ - if (fm == 1) - todisplay[plane][1] = todisplay[plane][0]; - else - { - todisplay[plane][3] = todisplay[plane][1]; - todisplay[plane][2] = todisplay[plane][0]; - } - - nwords -= 1 << fm; - - if (dma) - { - if (fm == 1) - fetchval0 = do_get_mem_long(real_pt); - else - { - fetchval1 = do_get_mem_long(real_pt); - fetchval0 = do_get_mem_long(real_pt + 1); - } - real_pt += fm; - } } - fetched_aga0[plane] = fetchval0; - fetched_aga1[plane] = fetchval1; + fetched_aga[plane] = fetchval; + todisplay2_aga[plane] = (shiftbuffer >> delay) & 0xffffffff; outword[plane] = outval; } -static void long_fetch_ecs_0(int hpos, int nwords, int dma) { long_fetch_ecs(hpos, nwords, 0, dma); } -static void long_fetch_ecs_1(int hpos, int nwords, int dma) { long_fetch_ecs(hpos, nwords, 1, dma); } -static void long_fetch_aga_1_0(int hpos, int nwords, int dma) { long_fetch_aga(hpos, nwords, 0, 1, dma); } -static void long_fetch_aga_1_1(int hpos, int nwords, int dma) { long_fetch_aga(hpos, nwords, 1, 1, dma); } -static void long_fetch_aga_2_0(int hpos, int nwords, int dma) { long_fetch_aga(hpos, nwords, 0, 2, dma); } -static void long_fetch_aga_2_1(int hpos, int nwords, int dma) { long_fetch_aga(hpos, nwords, 1, 2, dma); } +STATIC_INLINE void shift32plus(uae_u64 *p, int n) +{ + uae_u64 t = p[1]; + t <<= n; + t |= p[0] >> (64 - n); + p[1] = t; +} -static void do_long_fetch(int nwords, int dma, int fm) +STATIC_INLINE void aga_shift(uae_u64 *p, int n) +{ + if (n == 0) return; + shift32plus(p, n); + p[0] <<= n; +} + +STATIC_INLINE void shift32plusn(uae_u64 *p, int n) +{ + uae_u64 t = p[0]; + t >>= n; + t |= p[1] << (64 - n); + p[0] = t; +} + +STATIC_INLINE void aga_shift_n(uae_u64 *p, int n) +{ + if (n == 0) return; + shift32plusn(p, n); + p[1] >>= n; +} + +STATIC_INLINE void long_fetch_64(int plane, int nwords, int weird_number_of_bits, int dma) +{ + uae_u32 *real_pt = reinterpret_cast(pfield_xlateptr(bplpt[plane], nwords * 2)); + int delay = toscr_delay_adjusted[plane & 1]; + int tmp_nbits = out_nbits; +#ifdef HAVE_UAE_U128 + uae_u128 shiftbuffer; +#else + uae_u64 shiftbuffer[2]; +#endif + uae_u32 outval = outword[plane]; + uae_u64 fetchval = fetched_aga[plane]; + uae_u32 *dataptr = reinterpret_cast(line_data[next_lineno] + 2 * plane * MAX_WORDS_PER_LINE + 4 * out_offs); + int shift = (64 - 16) + delay; + + if (dma) { + bplpt[plane] += nwords * 2; + bplptx[plane] += nwords * 2; + } + + if (real_pt == 0) + /* @@@ Don't do this, fall back on chipmem_wget instead. */ + return; + +#ifdef HAVE_UAE_U128 + shiftbuffer = todisplay2_aga[plane] << delay; +#else + shiftbuffer[1] = 0; + shiftbuffer[0] = todisplay2_aga[plane]; + aga_shift(shiftbuffer, delay); +#endif + + while (nwords > 0) { + int i; + +#ifdef HAVE_UAE_U128 + shiftbuffer |= fetchval; +#else + shiftbuffer[0] |= fetchval; +#endif + + for (i = 0; i < 4; i++) { + uae_u32 t; + int bits_left = 32 - tmp_nbits; + +#ifdef HAVE_UAE_U128 + t = (shiftbuffer >> shift) & 0xffff; +#else + if (64 - shift > 0) { + t = shiftbuffer[1] << (64 - shift); + t |= shiftbuffer[0] >> shift; + } + else { + t = shiftbuffer[1] >> (shift - 64); + } + t &= 0xffff; +#endif + + if (weird_number_of_bits && bits_left < 16) { + outval <<= bits_left; + outval |= t >> (16 - bits_left); + + thisline_changed |= *dataptr ^ outval; + *dataptr++ = outval; + + outval = t; + tmp_nbits = 16 - bits_left; + } + else { + outval = (outval << 16) | t; + tmp_nbits += 16; + if (tmp_nbits == 32) { + thisline_changed |= *dataptr ^ outval; + *dataptr++ = outval; + tmp_nbits = 0; + } + } +#ifdef HAVE_UAE_U128 + shiftbuffer <<= 16; +#else + aga_shift(shiftbuffer, 16); +#endif + } + + nwords -= 4; + + if (dma) { + fetchval = static_cast(do_get_mem_long(real_pt)) << 32; + fetchval |= do_get_mem_long(real_pt + 1); + real_pt += 2; + } +} + fetched_aga[plane] = fetchval; +#ifdef HAVE_UAE_U128 + todisplay2_aga[plane] = shiftbuffer >> delay; +#else + aga_shift_n(shiftbuffer, delay); + todisplay2_aga[plane] = shiftbuffer[0]; +#endif + outword[plane] = outval; +} +#endif + +static void long_fetch_16_0(int hpos, int nwords, int dma) { long_fetch_16(hpos, nwords, 0, dma); } +static void long_fetch_16_1(int hpos, int nwords, int dma) { long_fetch_16(hpos, nwords, 1, dma); } +#ifdef AGA +static void long_fetch_32_0(int hpos, int nwords, int dma) { long_fetch_32(hpos, nwords, 0, dma); } +static void long_fetch_32_1(int hpos, int nwords, int dma) { long_fetch_32(hpos, nwords, 1, dma); } +static void long_fetch_64_0(int hpos, int nwords, int dma) { long_fetch_64(hpos, nwords, 0, dma); } +static void long_fetch_64_1(int hpos, int nwords, int dma) { long_fetch_64(hpos, nwords, 1, dma); } +#endif + +static void do_long_fetch(int hpos, int nwords, int dma, int fm) { int i; flush_display(fm); - switch (fm) - { + beginning_of_plane_block(hpos, fm); + + switch (fm) { case 0: - if (out_nbits & 15) - { + if (out_nbits & 15) { for (i = 0; i < toscr_nr_planes; i++) - long_fetch_ecs_1(i, nwords, dma); + long_fetch_16_1(i, nwords, dma); } - else - { + else { for (i = 0; i < toscr_nr_planes; i++) - long_fetch_ecs_0(i, nwords, dma); + long_fetch_16_0(i, nwords, dma); } break; +#ifdef AGA case 1: - if (out_nbits & 15) - { + if (out_nbits & 15) { for (i = 0; i < toscr_nr_planes; i++) - long_fetch_aga_1_1(i, nwords, dma); + long_fetch_32_1(i, nwords, dma); } - else - { + else { for (i = 0; i < toscr_nr_planes; i++) - long_fetch_aga_1_0(i, nwords, dma); + long_fetch_32_0(i, nwords, dma); } break; case 2: - if (out_nbits & 15) - { + if (out_nbits & 15) { for (i = 0; i < toscr_nr_planes; i++) - long_fetch_aga_2_1(i, nwords, dma); + long_fetch_64_1(i, nwords, dma); } - else - { + else { for (i = 0; i < toscr_nr_planes; i++) - long_fetch_aga_2_0(i, nwords, dma); + long_fetch_64_0(i, nwords, dma); } break; +#endif } out_nbits += nwords * 16; out_offs += out_nbits >> 5; out_nbits &= 31; + delay_cycles += nwords * 16; if (dma && toscr_nr_planes > 0) fetch_state = fetch_was_plane0; } -STATIC_INLINE void finish_last_fetch(int pos, int fm) +#endif + +static void finish_last_fetch(int pos, int fm, bool reallylast) { if (thisline_decision.plfleft < 0) return; - if (plf_state >= plf_end) + if (plfr_state >= plfr_end) return; - plf_state = plf_end; - pos += flush_plane_data(fm); + plfr_state = plfr_end; + + flush_display(fm); + // This may not be the last fetch, store current endpos for future use. + // There is at least one demo that has two DDFSTRT-DDFSTOP horizontal sections + // Subtle Shades / Nuance. thisline_decision.plfright = pos; - thisline_decision.plflinelen = out_offs; - if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) - { - bpl1dat_early = true; - ddfstate = DIW_waiting_start; - fetch_state = fetch_not_started; + + if (!reallylast) { + if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { + ddfstate = DIW_waiting_start; + fetch_state = fetch_not_started; + } } } +static void reset_bpl_vars(void) +{ + out_nbits = 0; + out_offs = 0; + toscr_nbits = 0; + thisline_decision.bplres = bplcon0_res; +} + /* check special case where last fetch wraps to next line - * this makes totally corrupted and flickering display on - * real hardware due to refresh cycle conflicts - */ +* this makes totally corrupted and flickering display on +* real hardware due to refresh cycle conflicts +* Exception: AGA + 64 bit fetch: glitch free overrun is possible. +*/ static void maybe_finish_last_fetch(int pos, int fm) { - bool done = false; - - if (plf_state != plf_passed_stop2 || fetch_state != fetch_started || !dmaen(DMA_BITPLANE)) - { - finish_last_fetch(pos, fm); - return; + if (plf_state > plf_passed_stop2 || plf_state < plf_passed_stop || (fetch_state != fetch_started && fetch_state != fetch_started_first) || !dmaen(DMA_BITPLANE)) { + finish_last_fetch(pos, fm, true); } - do - { - int cycle_start = fetch_cycle & fetchstart_mask; - switch (fm_maxplane) - { + else { + bitplane_overrun_fetch_cycle = fetch_cycle - 1; + int cycle_start = bitplane_overrun_fetch_cycle & fetchstart_mask; + int left = fetchunit - cycle_start; + if (plf_state == plf_passed_stop_act) { + // not passed stop: remaining cycles + full block. + bitplane_overrun = 2; + bitplane_overrun_hpos = left + fm_maxplane; + } + else { + // already passsed stop but some cycles remaining. + bitplane_overrun = -1; + // only idle cycles left? + left -= fetchunit - fm_maxplane; + if (left <= 0) + bitplane_overrun = 0; + bitplane_overrun_hpos = left; + } + bitplane_overrun_cycle_diagram_shift = fetchunit - (bitplane_overrun_fetch_cycle & fetchstart_mask); + finish_last_fetch(pos, fm, true); + } +} + +static void do_overrun_fetch(int until, int fm) +{ + static int warned = 20; + bool hit = false; + + if (until <= 0) + return; + for (int pos = last_fetch_hpos; pos < until; pos++) { + bool bpl0 = false; + int cycle_start = bitplane_overrun_fetch_cycle & fetchstart_mask; + + if (pos < 0) + continue; + + if ((bitplane_overrun_fetch_cycle & fetchunit_mask) == 0 && bitplane_overrun < 0) { + bitplane_overrun = 0; + return; + } + + bool modulo = bitplane_overrun < 2; + switch (fm_maxplane) { case 8: - switch (cycle_start) - { - case 0: fetch(7, fm); - break; - case 1: fetch(3, fm); - break; - case 2: fetch(5, fm); - break; - case 3: fetch(1, fm); - break; - case 4: fetch(6, fm); - break; - case 5: fetch(2, fm); - break; - case 6: fetch(4, fm); - break; - case 7: fetch(0, fm); - break; + switch (cycle_start) { + case 0: fetch(7, fm, modulo, pos); hit = true; break; + case 1: fetch(3, fm, modulo, pos); hit = true; break; + case 2: fetch(5, fm, modulo, pos); hit = true; break; + case 3: fetch(1, fm, modulo, pos); hit = true; break; + case 4: fetch(6, fm, modulo, pos); hit = true; break; + case 5: fetch(2, fm, modulo, pos); hit = true; break; + case 6: fetch(4, fm, modulo, pos); hit = true; break; + case 7: fetch(0, fm, modulo, pos); hit = true; bpl0 = true; break; default: - goto end; + break; } break; case 4: - switch (cycle_start) - { - case 0: fetch(3, fm); - break; - case 1: fetch(1, fm); - break; - case 2: fetch(2, fm); - break; - case 3: fetch(0, fm); - break; + switch (cycle_start) { + case 0: fetch(3, fm, modulo, pos); hit = true; break; + case 1: fetch(1, fm, modulo, pos); hit = true; break; + case 2: fetch(2, fm, modulo, pos); hit = true; break; + case 3: fetch(0, fm, modulo, pos); hit = true; bpl0 = true; break; default: - goto end; + break; } break; case 2: - switch (cycle_start) - { - case 0: fetch(1, fm); - break; - case 1: fetch(0, fm); - break; + switch (cycle_start) { + case 0: fetch(1, fm, modulo, pos); hit = true; break; + case 1: fetch(0, fm, modulo, pos); hit = true; bpl0 = true; break; default: - goto end; + break; } break; } - fetch_cycle++; - toscr_nbits += toscr_res2p; - if (toscr_nbits > 16) - toscr_nbits = 0; - if (toscr_nbits == 16) - flush_display(fm); - done = true; + if ((bitplane_overrun_fetch_cycle & fetchunit_mask) == 0) { + bitplane_overrun--; + if (hit && warned > 0) { + warned--; + write_log(_T("WARNING: bitplane DMA crossing scanlines!\n")); + } + if (bitplane_overrun <= 0) + break; + } + + bitplane_overrun_fetch_cycle++; } - while ((fetch_cycle & fetchunit_mask) != 0); - -end: - finish_last_fetch(pos, fm); } - /* make sure fetch that goes beyond maxhpos is finished */ -STATIC_INLINE void finish_final_fetch() +static void finish_final_fetch(void) { - if (plf_state < plf_end) - { - finish_last_fetch(maxhpos, fetchmode); - if (plf_state != plf_end) - return; - } - plf_state = plf_finished; + if (thisline_decision.plfleft < 0) + return; + + if (plfr_state < plfr_end) + finish_last_fetch(maxhpos, fetchmode, true); + plfr_state = plfr_finished; + + // workaround for too long fetches that don't pass plf_passed_stop2 before end of scanline + if (aga_plf_passed_stop2 && plf_state >= plf_passed_stop) + plf_state = plf_end; + + // This is really the end of scanline, we can finally flush all remaining data. + thisline_decision.plfright += flush_plane_data(fetchmode); + thisline_decision.plflinelen = out_offs; + + finish_playfield_line(); } -STATIC_INLINE int one_fetch_cycle_0(int pos, int ddfstop_to_test, int dma, int fm) +STATIC_INLINE int one_fetch_cycle_0(int pos, int dma, int fm) { - if (plf_state < plf_passed_stop && pos == ddfstop_to_test) - plf_state = plf_passed_stop; + bool bplactive = true; + bool diw = diwstate == DIW_waiting_stop; + if (plf_state == plf_wait && dma && diw) { + // same timings as when switching off, see below + bpl_dma_off_when_active = 0; + bplactive = false; + if (bitplane_off_delay >= 0) + bitplane_off_delay = !dma ? -4 : -5; + if (bitplane_off_delay < 0) { + bitplane_off_delay++; + if (bitplane_off_delay == 0) { + if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { + plf_state = plf_passed_stop; + } + else { + plf_state = plf_active; + } + } + } + } + else if (!dma || !diw) { + bplactive = false; + // dma off: turn off bitplane output after 4 cycles + // (yes, switching DMA off won't disable it immediately) + // diw off: turn off bitplane output after 5 cycles + // (Starflight / Phenomena jumping scroller in ECS) + // This is not correctly emulated, there probably is + // 4+ stage shift register that causes these delays. + if (plf_state == plf_active || plf_state == plf_passed_stop || plf_state == plf_passed_stop_act) { + bpl_dma_off_when_active = 1; + if (bitplane_off_delay <= 0) + bitplane_off_delay = !dma ? 4 : 5; + } + if (bitplane_off_delay > 0) { + bplactive = true; + bitplane_off_delay--; + if (bitplane_off_delay == 0) { + bplactive = false; + plf_state = plf_wait; + } + } + } - if ((fetch_cycle & fetchunit_mask) == 0) - { - if (plf_state == plf_passed_stop2) - { - finish_last_fetch(pos, fm); + if ((dma && diw) || (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) { + if (plf_state != plf_wait) { + if (pos == plfstop && ddfstop_written_hpos != pos) { + if (plf_state < plf_passed_stop) { + plf_state = plf_passed_stop; + } + plf_end_hpos = pos + DDF_OFFSET; + } + else if (pos == plf_end_hpos) { + ddfstop_matched = true; + if (plf_state < plf_passed_stop_act) { + plf_state = plf_passed_stop_act; + } + } + } + } + + if ((fetch_cycle & fetchunit_mask) == 0) { + if (plf_state == plf_passed_stop2) { + finish_last_fetch(pos, fm, false); return 1; } - if (plf_state == plf_passed_stop) - { + if (plf_state == plf_passed_stop_act) { plf_state = plf_passed_stop2; } - else if (plf_state == plf_passed_stop2) - { - plf_state = plf_end; + } + + // must be after above test, otherwise same fetch + // block may pass both stop_act and stop2 tests. + if (pos == HARD_DDF_STOP) { + if (plf_state < plf_wait) { + plf_state = plf_passed_stop_act; } } maybe_check(pos); - if (dma && plf_state != plf_wait_stop) - { + if (bplactive) { /* fetchstart_mask can be larger than fm_maxplane if FMODE > 0. This means - that the remaining cycles are idle; we'll fall through the whole switch - without doing anything. */ + that the remaining cycles are idle; we'll fall through the whole switch + without doing anything. */ int cycle_start = fetch_cycle & fetchstart_mask; - switch (fm_maxplane) - { + bool modulo = plf_state == plf_passed_stop2 && fetch_cycle >= (fetch_cycle & ~fetchunit_mask) + fetch_modulo_cycle; + + + switch (fm_maxplane) { case 8: - switch (cycle_start) - { - case 0: fetch(7, fm); - break; - case 1: fetch(3, fm); - break; - case 2: fetch(5, fm); - break; - case 3: fetch(1, fm); - break; - case 4: fetch(6, fm); - break; - case 5: fetch(2, fm); - break; - case 6: fetch(4, fm); - break; - case 7: fetch(0, fm); + switch (cycle_start) { + case 0: fetch(7, fm, modulo, pos); break; + case 1: fetch(3, fm, modulo, pos); break; + case 2: fetch(5, fm, modulo, pos); break; + case 3: fetch(1, fm, modulo, pos); break; + case 4: fetch(6, fm, modulo, pos); break; + case 5: fetch(2, fm, modulo, pos); break; + case 6: fetch(4, fm, modulo, pos); break; + case 7: fetch(0, fm, modulo, pos); break; +#ifdef AGA + default: + // if AGA: consider plf_passed_stop2 already + // active when last plane has been written, + // even if there is still idle cycles left + if (plf_state == plf_passed_stop_act) + aga_plf_passed_stop2 = true; break; +#endif } break; case 4: - switch (cycle_start) - { - case 0: fetch(3, fm); - break; - case 1: fetch(1, fm); - break; - case 2: fetch(2, fm); - break; - case 3: fetch(0, fm); + switch (cycle_start) { + case 0: fetch(3, fm, modulo, pos); break; + case 1: fetch(1, fm, modulo, pos); break; + case 2: fetch(2, fm, modulo, pos); break; + case 3: fetch(0, fm, modulo, pos); break; +#ifdef AGA + default: + if (plf_state == plf_passed_stop_act) + aga_plf_passed_stop2 = true; break; +#endif } break; case 2: - switch (cycle_start) - { - case 0: fetch(1, fm); - break; - case 1: fetch(0, fm); + switch (cycle_start) { + case 0: fetch(1, fm, modulo, pos); break; + case 1: fetch(0, fm, modulo, pos); break; +#ifdef AGA + default: + if (plf_state == plf_passed_stop_act) + aga_plf_passed_stop2 = true; break; +#endif } break; } } - if (bpl1dat_written) - { + if (bpl1dat_written) { // do this here because if program plays with BPLCON0 during scanline // it is possible that one DMA BPL1DAT write is completely missed // and we must not draw anything at all in next dma block if this happens @@ -1656,9 +2321,14 @@ STATIC_INLINE int one_fetch_cycle_0(int pos, int ddfstop_to_test, int dma, int f fetch_cycle++; toscr_nbits += toscr_res2p; - if (toscr_nbits > 16) - { - write_log (_T("toscr_nbits > 16 (%d)"), toscr_nbits); + if (bplcon1_written) { + flush_display(fm); + compute_toscr_delay(bplcon1); + bplcon1_written = false; + } + + if (toscr_nbits > 16) { + uae_abort(_T("toscr_nbits > 16 (%d)"), toscr_nbits); toscr_nbits = 0; } if (toscr_nbits == 16) @@ -1667,59 +2337,47 @@ STATIC_INLINE int one_fetch_cycle_0(int pos, int ddfstop_to_test, int dma, int f return 0; } -static int one_fetch_cycle_fm0(int pos, int ddfstop_to_test, int dma) { return one_fetch_cycle_0(pos, ddfstop_to_test, dma, 0); } -static int one_fetch_cycle_fm1(int pos, int ddfstop_to_test, int dma) { return one_fetch_cycle_0(pos, ddfstop_to_test, dma, 1); } -static int one_fetch_cycle_fm2(int pos, int ddfstop_to_test, int dma) { return one_fetch_cycle_0(pos, ddfstop_to_test, dma, 2); } +static int one_fetch_cycle_fm0(int pos, int dma) { return one_fetch_cycle_0(pos, dma, 0); } +static int one_fetch_cycle_fm1(int pos, int dma) { return one_fetch_cycle_0(pos, dma, 1); } +static int one_fetch_cycle_fm2(int pos, int dma) { return one_fetch_cycle_0(pos, dma, 2); } -STATIC_INLINE int one_fetch_cycle(int pos, int ddfstop_to_test, int dma, int fm) +STATIC_INLINE int one_fetch_cycle(int pos, int dma, int fm) { - switch (fm) - { - case 0: return one_fetch_cycle_fm0(pos, ddfstop_to_test, dma); - case 1: return one_fetch_cycle_fm1(pos, ddfstop_to_test, dma); - case 2: return one_fetch_cycle_fm2(pos, ddfstop_to_test, dma); - default: write_log (_T("fm corrupt")); - return 0; + switch (fm) { + case 0: return one_fetch_cycle_fm0(pos, dma); +#ifdef AGA + case 1: return one_fetch_cycle_fm1(pos, dma); + case 2: return one_fetch_cycle_fm2(pos, dma); +#endif + default: uae_abort(_T("fm corrupt")); return 0; } } -static void update_bpldats(int hpos) -{ - for (int i = 0; i < MAX_PLANES; i++) - { - fetched_aga0[i] = bplxdat[i]; - fetched_aga1[i] = 0; - fetched[i] = bplxdat[i]; - } - beginning_of_plane_block(hpos, fetchmode); -} - static void update_fetch_x(int until, int fm) { int pos; - if (nodraw ()) + if (nodraw()) return; pos = last_fetch_hpos; - update_toscr_planes(); + update_toscr_planes(fm); // not optimized, update_fetch_x() is extremely rarely used. - for (; pos < until; pos++) - { + for (; pos < until; pos++) { + toscr_nbits += toscr_res2p; - if (toscr_nbits > 16) - { - write_log (_T("xtoscr_nbits > 16 (%d)"), toscr_nbits); + if (toscr_nbits > 16) { + uae_abort(_T("xtoscr_nbits > 16 (%d)"), toscr_nbits); toscr_nbits = 0; } if (toscr_nbits == 16) flush_display(fm); + } - if (until >= maxhpos) - { + if (until >= maxhpos) { maybe_finish_last_fetch(pos, fm); return; } @@ -1727,68 +2385,52 @@ static void update_fetch_x(int until, int fm) flush_display(fm); } -STATIC_INLINE void update_fetch(int until, int fm) +static void update_fetch(int until, int fm) { int pos; int dma = dmaen(DMA_BITPLANE); - int ddfstop_to_test; if (nodraw() || plf_state >= plf_end) return; - /* We need an explicit test against HARD_DDF_STOP here to guard against - programs that move the DDFSTOP before our current position before we - reach it. */ - ddfstop_to_test = HARD_DDF_STOP; - if (ddfstop >= last_fetch_hpos && plfstop < HARD_DDF_STOP) - ddfstop_to_test = plfstop; - - update_toscr_planes(); - pos = last_fetch_hpos; cycle_diagram_shift = last_fetch_hpos - fetch_cycle; /* First, a loop that prepares us for the speedup code. We want to enter - the SPEEDUP case with fetch_state == fetch_was_plane0, and then unroll - whole blocks, so that we end on the same fetch_state again. */ - for (; ; pos++) - { - if (pos == until) - { - if (until >= maxhpos) - { + the SPEEDUP case with fetch_state == fetch_was_plane0 or it is the very + first fetch cycle (which equals to same state as fetch_was_plane0) + and then unroll whole blocks, so that we end on the same fetch_state again. */ + for (; ; pos++) { + if (pos == until) { + if (until >= maxhpos) { maybe_finish_last_fetch(pos, fm); return; } - flush_display(fm); return; } if (fetch_state == fetch_was_plane0) break; - fetch_start(); - if (one_fetch_cycle(pos, ddfstop_to_test, dma, fm)) + fetch_start(pos); + if (one_fetch_cycle(pos, dma, fm)) return; - } - - // vdiw getting cleared mid-scan = fetches also stop - if (diwstate == DIW_waiting_start && plf_state < plf_wait_stop) - { - // ecs = continue at passed_stop - // ocs = line is done - if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) - plf_state = plf_wait_stop; - else - plf_state = plf_passed_stop2; - } + } +#if SPEEDUP /* Unrolled version of the for loop below. */ - if (plf_state < plf_wait_stop && line_cyclebased != vpos && line_cyclebased + 1 != vpos - && dma + if (plf_state == plf_active && !line_cyclebased && dma && (fetch_cycle & fetchstart_mask) == (fm_maxplane & fetchstart_mask) - && toscr_nr_planes == thisline_decision.nr_planes) + && !badmode +#ifdef DEBUGGER + && !debug_dma +#endif + && toscr_nr_planes == toscr_nr_planes_agnus) { + int ddfstop_to_test_ddf = HARD_DDF_STOP; + if (plfstop >= last_fetch_hpos - DDF_OFFSET && plfstop < ddfstop_to_test_ddf) + ddfstop_to_test_ddf = plfstop; + int ddfstop_to_test = ddfstop_to_test_ddf + DDF_OFFSET; int offs = (pos - fetch_cycle) & fetchunit_mask; int ddf2 = ((ddfstop_to_test - offs + fetchunit - 1) & ~fetchunit_mask) + offs; int ddf3 = ddf2 + fetchunit; @@ -1796,48 +2438,58 @@ STATIC_INLINE void update_fetch(int until, int fm) int count; count = stop - pos; - - if (count >= fetchstart) - { + if (count >= fetchstart) { count &= ~fetchstart_mask; + int stoppos = pos + count; - if (thisline_decision.plfleft < 0) - { - compute_delay_offset(); - compute_toscr_delay_1(bplcon1); + if (thisline_decision.plfleft < 0) { + compute_toscr_delay(bplcon1); } - do_long_fetch(count >> (3 - toscr_res), dma, fm); + + do_long_fetch(pos, count >> (3 - toscr_res), dma, fm); /* This must come _after_ do_long_fetch so as not to confuse flush_display - into thinking the first fetch has produced any output worth emitting to - the screen. But the calculation of delay_offset must happen _before_. */ + into thinking the first fetch has produced any output worth emitting to + the screen. But the calculation of delay_offset must happen _before_. */ maybe_first_bpl1dat(pos); - if (pos <= ddfstop_to_test && pos + count > ddfstop_to_test) + if (pos <= plfstop && stoppos > plfstop) { plf_state = plf_passed_stop; - if (pos <= ddfstop_to_test && pos + count > ddf2) + plf_end_hpos = plfstop + DDF_OFFSET; + } + if (pos <= plfstop + DDF_OFFSET && stoppos > plfstop + DDF_OFFSET) { + plf_state = plf_passed_stop_act; + plf_end_hpos = 256 + DDF_OFFSET; + ddfstop_matched = true; + } + if (pos <= HARD_DDF_STOP && stoppos > HARD_DDF_STOP) { + if (plf_state < plf_wait) + plf_state = plf_passed_stop_act; + } + if (pos <= ddfstop_to_test && stoppos > ddf2) { plf_state = plf_passed_stop2; - if (pos <= ddf2 && pos + count >= ddf2 + fm_maxplane) + } + if (pos <= ddf2 && stoppos >= ddf2 + fm_maxplane) { add_modulos(); + } pos += count; fetch_cycle += count; } } +#endif + for (; pos < until; pos++) { - for (; pos < until; pos++) - { - if (fetch_state == fetch_was_plane0) - { + if (fetch_state == fetch_was_plane0) { + flush_display(fm); beginning_of_plane_block(pos, fm); - estimate_last_fetch_cycle(pos); } - fetch_start(); - if (one_fetch_cycle(pos, ddfstop_to_test, dma, fm)) + fetch_start(pos); + + if (one_fetch_cycle(pos, dma, fm)) return; } - if (until >= maxhpos) - { + if (until >= maxhpos) { maybe_finish_last_fetch(pos, fm); return; } @@ -1848,29 +2500,33 @@ static void update_fetch_0(int hpos) { update_fetch(hpos, 0); } static void update_fetch_1(int hpos) { update_fetch(hpos, 1); } static void update_fetch_2(int hpos) { update_fetch(hpos, 2); } -STATIC_INLINE void decide_fetch(int hpos) +static void decide_fetch(int hpos) { - if (hpos > last_fetch_hpos) - { - if (fetch_state != fetch_not_started) - { - switch (fetchmode) - { - case 0: update_fetch_0(hpos); - break; - case 1: update_fetch_1(hpos); - break; - case 2: update_fetch_2(hpos); - break; - default: write_log (_T("fetchmode corrupt")); + if (hpos > last_fetch_hpos) { + if (bitplane_overrun) { + if (fetch_state != fetch_not_started) { + bitplane_overrun = 0; + } + else { + do_overrun_fetch(hpos, fetchmode); } } - else if (bpl1dat_written_at_least_once) - { + if (fetch_state != fetch_not_started) { + switch (fetchmode) { + case 0: update_fetch_0(hpos); break; +#ifdef AGA + case 1: update_fetch_1(hpos); break; + case 2: update_fetch_2(hpos); break; +#endif + default: uae_abort(_T("fetchmode corrupt")); + } + } + else if (bpl1dat_written_at_least_once) { // "PIO" mode display update_fetch_x(hpos, fetchmode); bpl1dat_written = false; } + maybe_check(hpos); last_fetch_hpos = hpos; } @@ -1878,131 +2534,277 @@ STATIC_INLINE void decide_fetch(int hpos) STATIC_INLINE void decide_fetch_safe(int hpos) { - decide_fetch(hpos); + if (!blitter_dangerous_bpl) { + decide_fetch(hpos); + decide_blitter(hpos); + } + else { + while (hpos > last_fetch_hpos) { + decide_fetch(last_fetch_hpos + 1); + decide_blitter(last_fetch_hpos + 1); + } + } } -static void reset_bpl_vars() +static void start_bpl_dma(int hstart) { - out_nbits = 0; - out_offs = 0; - toscr_nbits = 0; - thisline_decision.bplres = bplcon0_res; -} + if (first_bpl_vpos < 0) + first_bpl_vpos = vpos; -STATIC_INLINE void start_bpl_dma(int hstart) -{ - fetch_start(); + if (doflickerfix() && interlace_seen > 0 && !scandoubled_line) { + int i; + for (i = 0; i < 8; i++) { + prevbpl[lof_current][vpos][i] = bplptx[i]; + if (!lof_current && (bplcon0 & 4)) + bplpt[i] = prevbpl[1 - lof_current][vpos][i]; + if (!(bplcon0 & 4) || interlace_seen < 0) + prevbpl[1 - lof_current][vpos][i] = prevbpl[lof_current][vpos][i] = 0; + } + } + + fetch_state = fetch_started; + plfr_state = plfr_active; ddfstate = DIW_waiting_stop; + bpl_hstart = hstart; - if (!bpldmawasactive) - { - plfstrt_sprite = plfstrt; + if (!bpldmawasactive) { + + if (last_fetch_hpos < 0) + last_fetch_hpos = 0; + plfstrt_sprite = hstart; + // OCS Agnus needs at least 1 empty cycle between + // sprite fetch and bitplane cycle sequence start. + if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + plfstrt_sprite--; fetch_cycle = 0; - - compute_toscr_delay(last_fetch_hpos, bplcon1); - - /* If someone already wrote BPL1DAT, clear the area between that point and - the real fetch start. */ - if (bpl1dat_written_at_least_once && hstart > last_fetch_hpos) - { + update_denise(last_fetch_hpos); + if (bpl1dat_written_at_least_once && hstart > last_fetch_hpos) { update_fetch_x(hstart, fetchmode); bpl1dat_written_at_least_once = false; } - else - { + else { reset_bpl_vars(); } cycle_diagram_shift = hstart; bpldmawasactive = true; + } - else - { - // this is a hack, something weird happens without this - // (Subtle Shades) - thisline_decision.plfright++; - thisline_decision.plflinelen = ++out_offs; + else { + + flush_display(fetchmode); + // Calculate difference between last end to new start + int diff = (hstart - thisline_decision.plfright) << (1 + toscr_res); + // Render all missing pixels, use toscr because previous data may + // still be in buffers. + while (diff >= 16) { + toscr_1(16, fetchmode); + diff -= 16; + } + if (diff) + toscr_1(diff, fetchmode); + + cycle_diagram_shift = hstart; + update_denise(last_fetch_hpos); + update_fetch_x(hstart, fetchmode); } last_fetch_hpos = hstart; + estimate_last_fetch_cycle(hstart); + } -/* this may turn on datafetch if program turns dma on during the ddf */ -STATIC_INLINE void maybe_start_bpl_dma(int hpos) +STATIC_INLINE bool cant_this_last_line(void) { - /* OCS: BPL DMA never restarts if DMA is turned on during DDF - * ECS/AGA: BPL DMA restarts but only if DMA was turned off - outside of DDF or during current line, otherwise display - processing jumps immediately to "DDFSTOP passed"-condition */ - if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - { - bitplane_dma_turned_on = hpos; - return; - } - if (fetch_state != fetch_not_started) - return; - if (diwstate != DIW_waiting_stop) - return; - if (hpos <= plfstrt) - return; - if (hpos > plfstop - fetchunit) - return; - if (ddfstate != DIW_waiting_start) - plf_state = plf_passed_stop; - start_bpl_dma(hpos); + // Last line.. + // ..works normally if A1000 Agnus + if (currprefs.cs_dipagnus) + return false; + // ..inhibits bitplane and sprite DMA if later Agnus revision. + return vpos + 1 >= maxvpos + lof_store; } -/* This function is responsible for turning on datafetch if necessary. */ +/* This function is responsible for turning on datafetch if necessary. */ STATIC_INLINE void decide_line(int hpos) { + bool ecs = (currprefs.chipset_mask & CSMASK_ECS_AGNUS) != 0; + /* Take care of the vertical DIW. */ - if (vpos == plffirstline) - { - diwstate = DIW_waiting_stop; - line_cyclebased = vpos; + if (vpos == plffirstline) { + // A1000 Agnus won't start bitplane DMA if vertical diw is zero. + if (vpos > 0 || (vpos == 0 && !currprefs.cs_dipagnus)) { + diwstate = DIW_waiting_stop; + SET_LINE_CYCLEBASED; + } } - if (vpos == plflastline) - { + // last line of field can never have bitplane dma active if not A1000 Agnus. + if (vpos == plflastline || cant_this_last_line() || (vpos == 0 && currprefs.cs_dipagnus)) { diwstate = DIW_waiting_start; - line_cyclebased = vpos; + SET_LINE_CYCLEBASED; } if (hpos <= last_decide_line_hpos) return; - if (fetch_state == fetch_not_started) - { - int start = (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? plfstrt - 4 : HARD_DDF_START_REAL - 2; - if (last_decide_line_hpos < start && hpos >= start) - { - if (plf_state == plf_idle || plf_state == plf_end) - plf_state = plf_start; - } - if ((diwstate == DIW_waiting_stop || (currprefs.chipset_mask & CSMASK_ECS_AGNUS))) - { - int ok = 0; - if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) - { - if (plf_state == plf_start) - plf_state = plf_active; - if (plf_state == plf_active) - ok = 1; - /* hack warning.. Writing to DDFSTRT when DMA should start must be ignored - * (correct fix would be emulate this delay for every custom register, but why bother..) */ - if (hpos - 2 == ddfstrt_old_hpos) - ok = 0; + bool dma = dmaen(DMA_BITPLANE) != 0; + bool diw = diwstate == DIW_waiting_stop; + + if (ecs) { + if (1) { + if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) { + ddfstop_matched = false; } - if (ok && diwstate == DIW_waiting_stop) - { - if (dmaen(DMA_BITPLANE) && bitplane_dma_turned_on + 4 < hpos) - { - start_bpl_dma(plfstrt); - estimate_last_fetch_cycle(plfstrt); + } + } + else { + if (1) { + if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) { + ddfstop_matched = false; + // plfstrt==0 works strangely (Nakudemo / Vision-X) + if (plfstrt > -DDF_OFFSET) + ocs_agnus_ddf_enable_toggle = false; + } + } + } + + if (fetch_state == fetch_not_started) { + bool strtpassed = false; + plfstate nextstate = plf_end; + int hstart; + + hstart = last_decide_line_hpos; + if (hstart < bitplane_maybe_start_hpos) + hstart = bitplane_maybe_start_hpos; + if (hstart < HARD_DDF_START_REAL + DDF_OFFSET) + hstart = HARD_DDF_START_REAL + DDF_OFFSET; + // DMA enabled mid-line: DDF_OFFSET delay first + if (bitplane_maybe_start_hpos + DDF_OFFSET > hstart) + hstart = bitplane_maybe_start_hpos + DDF_OFFSET; + if (hstart & 1) + hstart++; + + if (ecs) { + // ECS DDFSTRT/STOP matching does not require DMA or DIW. + if (1) { + if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) { + // active == already started because ddfstop was not detected in last line + if (plf_state != plf_active) { + plf_state = plf_passed_start; + strtpassed = true; + plf_start_hpos = plfstrt + DDF_OFFSET; + } + } + } + if (1) { + if ((strtpassed && hpos >= plf_start_hpos) || (last_decide_line_hpos < plf_start_hpos && hpos >= plf_start_hpos)) { + if (plf_state == plf_passed_start) { + plf_state = plf_active; + hstart = plf_start_hpos; + } + } + } + } + else { + if (1) { + int start = HARD_DDF_START_REAL; + if (last_decide_line_hpos < start && hpos >= start) { + if (!ocs_agnus_ddf_enable_toggle) + plf_state = plf_passed_enable; + ocs_agnus_ddf_enable_toggle = true; + } + } + // OCS DDFSTRT/STOP matching requires DMA and DIW enabled. + if (dma && diw) { + if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) { + if (plf_state == plf_passed_enable) { + plf_state = plf_passed_start; + strtpassed = true; + plf_start_hpos = plfstrt + DDF_OFFSET; + } + ocs_agnus_ddf_enable_toggle = false; + } + } + if (dma && diw) { + if ((strtpassed && hpos >= plf_start_hpos) || (last_decide_line_hpos < plf_start_hpos && hpos >= plf_start_hpos)) { + if (plf_state == plf_passed_start) { + plf_state = plf_active; + hstart = plf_start_hpos; + } + } + } + } + + if (diw && dma) { + bool test = false; + if (ecs) { + test = (plf_state == plf_active && (hpos >= HARD_DDF_START_REAL + DDF_OFFSET || HARD_DDF_LIMITS_DISABLED)); + if (bpl_dma_off_when_active) { + if (plfstop < hstart) { + test = false; + } + } + } + else { + test = (plf_state == plf_active); + // if DMA enabled mid-scanline but ddfstrt not matched (dma was off): start when ddfstop is matched + // (Crash Landing crack intro / Scoopex) + if (!test && last_decide_line_hpos < plfstop && hstart > plfstop) { + if (hstart == ((bitplane_maybe_start_hpos + DDF_OFFSET + 1) & ~1)) { + hstart = plfstop + DDF_OFFSET; + test = true; + nextstate = plf_passed_stop; + } + } + } + if (test) { + start_bpl_dma(hstart); + // if ECS: pre-set plf_end_hpos if we have already passed virtual ddfstop + if (ecs) { + if (last_decide_line_hpos < hstart && hstart >= plfstop && hstart - plfstop <= DDF_OFFSET) { + plf_end_hpos = plfstop + DDF_OFFSET; + nextstate = plf_passed_stop; + } + if (last_decide_line_hpos < HARD_DDF_STOP && hstart > HARD_DDF_STOP) { + plf_end_hpos = HARD_DDF_STOP + DDF_OFFSET; + nextstate = plf_passed_stop; + } + if (bpl_dma_off_when_active) { + nextstate = plf_passed_stop_act; + bpl_dma_off_when_active = 0; + } + } + if (nextstate != plf_end) { + plf_state = nextstate; + estimate_last_fetch_cycle(hstart); } last_decide_line_hpos = hpos; do_sprites(hpos); return; } + + } + + if (ecs) { + if (1) { + // ddfstrt == ddfstop: ddfstrt wins. + if (plfstrt != plfstop && last_decide_line_hpos < plfstop && hpos >= plfstop && plfstop <= maxhpos - DDF_OFFSET) { + ddfstop_matched = true; + if (plf_state != plf_wait && plf_state < plf_passed_stop) { + plf_state = plf_passed_stop; + plf_end_hpos = plfstop + DDF_OFFSET; + } + } + if (last_decide_line_hpos < HARD_DDF_STOP && hpos >= HARD_DDF_STOP) { + plf_state = plf_passed_stop_act; + } + } + } + else { + if (dma && diw) { + if (last_decide_line_hpos < plfstop && hpos >= plfstop && plfstop <= maxhpos - DDF_OFFSET && plf_state != plf_wait) { + ddfstop_matched = true; + } + } } } @@ -2013,10 +2815,10 @@ STATIC_INLINE void decide_line(int hpos) } /* Called when a color is about to be changed (write to a color register), - * but the new color has not been entered into the table yet. */ +* but the new color has not been entered into the table yet. */ static void record_color_change(int hpos, int regno, unsigned long value) { - if (regno < 0x1000 && nodraw ()) + if (regno < 0x1000 && nodraw()) return; /* Early positions don't appear on-screen. */ if (vpos < minfirstline) @@ -2028,64 +2830,88 @@ static void record_color_change(int hpos, int regno, unsigned long value) if (thisline_decision.ctable < 0) remember_ctable(); - if ((regno < 0x1000 || regno == 0x1000 + 0x10c) && hpos < HBLANK_OFFSET && !(beamcon0 & 0x80) && prev_lineno >= 0) - { - struct draw_info* pdip = curr_drawinfo + prev_lineno; + if ((regno < 0x1000 || regno == 0x1000 + 0x10c) && hpos < HBLANK_OFFSET && !(beamcon0 & 0x80) && prev_lineno >= 0) { + struct draw_info *pdip = curr_drawinfo + prev_lineno; int idx = pdip->last_color_change; int extrahpos = regno == 0x1000 + 0x10c ? 1 : 0; + bool lastsync = false; /* Move color changes in horizontal cycles 0 to HBLANK_OFFSET to end of previous line. - * Cycles 0 to HBLANK_OFFSET are visible in right border on real Amigas. (because of late hsync) - */ + * Cycles 0 to HBLANK_OFFSET are visible in right border on real Amigas. (because of late hsync) + */ + if (curr_color_changes[idx - 1].regno == 0xffff) { + idx--; + lastsync = true; + } pdip->last_color_change++; pdip->nr_color_changes++; curr_color_changes[idx].linepos = (hpos + maxhpos) * 2 + extrahpos; curr_color_changes[idx].regno = regno; curr_color_changes[idx].value = value; - curr_color_changes[idx + 1].regno = -1; + if (lastsync) { + curr_color_changes[idx + 1].linepos = hsyncstartpos * 2; + curr_color_changes[idx + 1].regno = 0xffff; + curr_color_changes[idx + 2].regno = -1; + } + else { + curr_color_changes[idx + 1].regno = -1; + } } record_color_change2(hpos, regno, value); } static bool isbrdblank(int hpos, uae_u16 bplcon0, uae_u16 bplcon3) { - bool brdblank; + bool brdblank, brdntrans; +#ifdef ECS_DENISE brdblank = (currprefs.chipset_mask & CSMASK_ECS_DENISE) && (bplcon0 & 1) && (bplcon3 & 0x20); - if (hpos >= 0 && current_colors.extra != brdblank) - { - record_color_change(hpos, 0, COLOR_CHANGE_BRDBLANK | (brdblank ? 1 : 0) | (current_colors.extra ? 2 : 0)); - current_colors.extra = brdblank; + brdntrans = (currprefs.chipset_mask & CSMASK_ECS_DENISE) && (bplcon0 & 1) && (bplcon3 & 0x10); +#else + brdblank = false; + brdntrans = false; +#endif + if (hpos >= 0 && (ce_is_borderblank(current_colors.extra) != brdblank || ce_is_borderntrans(current_colors.extra) != brdntrans)) { + record_color_change(hpos, 0, COLOR_CHANGE_BRDBLANK | (brdblank ? 1 : 0) | (ce_is_bordersprite(current_colors.extra) ? 2 : 0) | (brdntrans ? 4 : 0)); + current_colors.extra &= ~(1 << CE_BORDERBLANK); + current_colors.extra &= ~(1 << CE_BORDERNTRANS); + current_colors.extra |= brdblank ? (1 << CE_BORDERBLANK) : 0; + current_colors.extra |= brdntrans ? (1 << CE_BORDERNTRANS) : 0; remembered_color_entry = -1; } return brdblank; } - static bool issprbrd(int hpos, uae_u16 bplcon0, uae_u16 bplcon3) { bool brdsprt; - brdsprt = (aga_mode) && (bplcon0 & 1) && (bplcon3 & 0x02); - if (hpos >= 0 && current_colors.extra != brdsprt) - { - record_color_change(hpos, 0, COLOR_CHANGE_BRDBLANK | (current_colors.extra ? 1 : 0) | (brdsprt ? 2 : 0)); - current_colors.extra = brdsprt; +#ifdef AGA + brdsprt = (currprefs.chipset_mask & CSMASK_AGA) && (bplcon0 & 1) && (bplcon3 & 0x02); +#else + brdsprt = false; +#endif + if (hpos >= 0 && ce_is_bordersprite(current_colors.extra) != brdsprt) { + record_color_change(hpos, 0, COLOR_CHANGE_BRDBLANK | (ce_is_borderblank(current_colors.extra) ? 1 : 0) | (ce_is_borderntrans(current_colors.extra) ? 4 : 0) | (brdsprt ? 2 : 0)); + current_colors.extra &= ~(1 << CE_BORDERSPRITE); + current_colors.extra |= brdsprt ? (1 << CE_BORDERSPRITE) : 0; remembered_color_entry = -1; - if (brdsprt && !current_colors.extra) + if (brdsprt && !ce_is_borderblank(current_colors.extra)) thisline_decision.bordersprite_seen = true; } - return brdsprt && !current_colors.extra; + return brdsprt && !ce_is_borderblank(current_colors.extra); } static void record_register_change(int hpos, int regno, uae_u16 value) { - if (regno == 0x100) - { // BPLCON0 + if (regno == 0x100) { // BPLCON0 if (value & 0x800) - thisline_decision.ham_seen = true; + thisline_decision.ham_seen = 1; + thisline_decision.ehb_seen = isehb(value, bplcon2); isbrdblank(hpos, value, bplcon3); issprbrd(hpos, value, bplcon3); } - else if (regno == 0x106) - { // BPLCON3 + else if (regno == 0x104) { // BPLCON2 + thisline_decision.ehb_seen = isehb(bplcon0, value); + } + else if (regno == 0x106) { // BPLCON3 isbrdblank(hpos, bplcon0, value); issprbrd(hpos, bplcon0, value); } @@ -2103,12 +2929,15 @@ static int expand_sprres(uae_u16 con0, uae_u16 con3) default: res = RES_LORES; break; +#ifdef ECS_DENISE case 0: /* ECS defaults (LORES,HIRES=LORES sprite,SHRES=HIRES sprite) */ if ((currprefs.chipset_mask & CSMASK_ECS_DENISE) && GET_RES_DENISE(con0) == RES_SUPERHIRES) res = RES_HIRES; else res = RES_LORES; break; +#endif +#ifdef AGA case 1: res = RES_LORES; break; @@ -2118,6 +2947,7 @@ static int expand_sprres(uae_u16 con0, uae_u16 con3) case 3: res = RES_SUPERHIRES; break; +#endif } return res; } @@ -2133,14 +2963,26 @@ static int expand_sprres(uae_u16 con0, uae_u16 con3) /* handle very rarely needed playfield collision (CLXDAT bit 0) */ /* only known game needing this is Rotor */ -static void do_playfield_collisions() +static void do_playfield_collisions(void) { int bplres = bplcon0_res; hwres_t ddf_left = thisline_decision.plfleft * 2 << bplres; hwres_t hw_diwlast = coord_window_to_diw_x(thisline_decision.diwlastword); hwres_t hw_diwfirst = coord_window_to_diw_x(thisline_decision.diwfirstword); int i, collided, minpos, maxpos; - int planes = (aga_mode) ? 8 : 6; +#ifdef AGA + int planes = (currprefs.chipset_mask & CSMASK_AGA) ? 8 : 6; +#else + int planes = 6; +#endif + + //if (clxcon_bpl_enable == 0) { + // clxdat |= 1; + // return; + //} + //// collision bit already set? + //if (clxdat & 1) + // return; collided = 0; minpos = thisline_decision.plfleft * 2; @@ -2149,32 +2991,26 @@ static void do_playfield_collisions() maxpos = thisline_decision.plfright * 2; if (maxpos > hw_diwlast) maxpos = hw_diwlast; - for (i = minpos; i < maxpos && !collided; i += 32) - { + for (i = minpos; i < maxpos && !collided; i += 32) { int offs = ((i << bplres) - ddf_left) >> 3; int j; uae_u32 total = 0xffffffff; - for (j = 0; j < planes; j++) - { + for (j = 0; j < planes; j++) { int ena = (clxcon_bpl_enable >> j) & 1; int match = (clxcon_bpl_match >> j) & 1; uae_u32 t = 0xffffffff; - if (ena) - { - if (j < thisline_decision.nr_planes) - { - t = *reinterpret_cast(line_data[next_lineno] + offs + 2 * j * MAX_WORDS_PER_LINE); + if (ena) { + if (j < thisline_decision.nr_planes) { + t = *(uae_u32 *)(line_data[next_lineno] + offs + 2 * j * MAX_WORDS_PER_LINE); t ^= (match & 1) - 1; } - else - { + else { t = (match & 1) - 1; } } total &= t; } - if (total) - { + if (total) { collided = 1; } } @@ -2191,8 +3027,8 @@ static void do_playfield_collisions() } /* Sprite-to-sprite collisions are taken care of in record_sprite. This one does - playfield/sprite collisions. */ -static void do_sprite_collisions() +playfield/sprite collisions. */ +static void do_sprite_collisions(void) { int nr_sprites = curr_drawinfo[next_lineno].nr_sprites; int first = curr_drawinfo[next_lineno].first_sprite_entry; @@ -2203,9 +3039,14 @@ static void do_sprite_collisions() hwres_t hw_diwlast = coord_window_to_diw_x(thisline_decision.diwlastword); hwres_t hw_diwfirst = coord_window_to_diw_x(thisline_decision.diwfirstword); - for (i = 0; i < nr_sprites; i++) - { - struct sprite_entry* e = curr_sprite_entries + first + i; + //if (clxcon_bpl_enable == 0 && !nr_sprites) + // return; + //// all sprite to bitplane collision bits already set? + //if ((clxdat & 0x1fe) == 0x1fe) + // return; + + for (i = 0; i < nr_sprites; i++) { + struct sprite_entry *e = curr_sprite_entries + first + i; sprbuf_res_t j; sprbuf_res_t minpos = e->pos; sprbuf_res_t maxpos = e->max; @@ -2221,8 +3062,7 @@ static void do_sprite_collisions() if (minp1 < thisline_decision.plfleft * 2) minpos = thisline_decision.plfleft * 2 << sprite_buffer_res; - for (j = minpos; j < maxpos; j++) - { + for (j = minpos; j < maxpos; j++) { int sprpix = spixels[e->first_pixel + j - e->pos] & collision_mask; int k, offs, match = 1; @@ -2233,31 +3073,33 @@ static void do_sprite_collisions() sprpix = sprite_ab_merge[sprpix & 255] | (sprite_ab_merge[sprpix >> 8] << 2); sprpix <<= 1; - /* Loop over number of playfields. */ - for (k = 1; k >= 0; k--) - { - int l; - int planes = (aga_mode) ? 8 : 6; + // both odd and even collision bits already set? + if ((clxdat & (sprpix << 0)) && (clxdat & (sprpix << 4))) + continue; + /* Loop over number of playfields. */ + for (k = 1; k >= 0; k--) { + int l; +#ifdef AGA + int planes = (currprefs.chipset_mask & CSMASK_AGA) ? 8 : 6; +#else + int planes = 6; +#endif if (bplcon0 & 0x400) match = 1; - for (l = k; match && l < planes; l += 2) - { + for (l = k; match && l < planes; l += 2) { int t = 0; - if (l < thisline_decision.nr_planes) - { - uae_u32* ldata = reinterpret_cast(line_data[next_lineno] + 2 * l * MAX_WORDS_PER_LINE); + if (l < thisline_decision.nr_planes) { + uae_u32 *ldata = reinterpret_cast(line_data[next_lineno] + 2 * l * MAX_WORDS_PER_LINE); uae_u32 word = ldata[offs >> 5]; t = (word >> (31 - (offs & 31))) & 1; } - if (clxcon_bpl_enable & (1 << l)) - { + if (clxcon_bpl_enable & (1 << l)) { if (t != ((clxcon_bpl_match >> l) & 1)) match = 0; } } - if (match) - { + if (match) { clxdat |= sprpix << (k * 4); } } @@ -2265,35 +3107,32 @@ static void do_sprite_collisions() } } -STATIC_INLINE void record_sprite_1(int sprxp, uae_u16* buf, uae_u32 datab, int num, int dbl, - unsigned int mask, int do_collisions, uae_u32 collision_mask) +static void record_sprite_1(int sprxp, uae_u16 *buf, uae_u32 datab, int num, int dbl, + unsigned int mask, int do_collisions, uae_u32 collision_mask) { int j = 0; - while (datab) - { + while (datab) { unsigned int col = 0; - unsigned int coltmp = 0; + unsigned coltmp = 0; if ((sprxp >= sprite_minx && sprxp < sprite_maxx) || (bplcon3 & 2)) col = (datab & 3) << (2 * num); - if ((j & mask) == 0) - { + + if ((j & mask) == 0) { unsigned int tmp = (*buf) | col; *buf++ = tmp; if (do_collisions) coltmp |= tmp; sprxp++; } - if (dbl > 0) - { + if (dbl > 0) { unsigned int tmp = (*buf) | col; *buf++ = tmp; if (do_collisions) coltmp |= tmp; sprxp++; } - if (dbl > 1) - { + if (dbl > 1) { unsigned int tmp; tmp = (*buf) | col; *buf++ = tmp; @@ -2308,11 +3147,9 @@ STATIC_INLINE void record_sprite_1(int sprxp, uae_u16* buf, uae_u32 datab, int n } j++; datab >>= 2; - if (do_collisions) - { + if (do_collisions) { coltmp &= collision_mask; - if (coltmp) - { + if (coltmp) { unsigned int shrunk_tmp = sprite_ab_merge[coltmp & 255] | (sprite_ab_merge[coltmp >> 8] << 2); clxdat |= sprclx[shrunk_tmp]; } @@ -2329,9 +3166,9 @@ STATIC_INLINE void record_sprite_1(int sprxp, uae_u16* buf, uae_u32 datab, int n The data is recorded either in lores pixels (if OCS/ECS), or in hires or superhires pixels (if AGA). */ -static void record_sprite(int line, int num, int sprxp, uae_u16* data, uae_u16* datb, unsigned int ctl) +static void record_sprite(int line, int num, int sprxp, uae_u16 *data, uae_u16 *datb, unsigned int ctl) { - struct sprite_entry* e = curr_sprite_entries + next_sprite_entry; + struct sprite_entry *e = curr_sprite_entries + next_sprite_entry; int i; int word_offs; uae_u32 collision_mask; @@ -2341,8 +3178,7 @@ static void record_sprite(int line, int num, int sprxp, uae_u16* data, uae_u16* half = 0; dbl = sprite_buffer_res - sprres; - if (dbl < 0) - { + if (dbl < 0) { half = -dbl; dbl = 0; mask = 1 << half; @@ -2351,22 +3187,17 @@ static void record_sprite(int line, int num, int sprxp, uae_u16* data, uae_u16* attachment = sprctl[num | 1] & 0x80; /* Try to coalesce entries if they aren't too far apart */ - if (! next_sprite_forced && e[-1].max + sprite_width >= sprxp) - { + if (!next_sprite_forced && e[-1].max + sprite_width >= sprxp) { e--; } - else - { + else { next_sprite_entry++; e->pos = sprxp; - e->has_attached = false; + e->has_attached = 0; } if (sprxp < e->pos) - { - write_log (_T("sprxp < e->pos")); - return; - } + uae_abort(_T("sprxp < e->pos")); e->max = sprxp + width; e[1].first_pixel = e->first_pixel + ((e->max - e->pos + 3) & ~3); @@ -2375,15 +3206,13 @@ static void record_sprite(int line, int num, int sprxp, uae_u16* data, uae_u16* collision_mask = clxmask[clxcon >> 12]; word_offs = e->first_pixel + sprxp - e->pos; - for (i = 0; i < sprite_width; i += 16) - { + for (i = 0; i < sprite_width; i += 16) { unsigned int da = *data; unsigned int db = *datb; uae_u32 datab = ((sprtaba[da & 0xFF] << 16) | sprtaba[da >> 8] | (sprtabb[db & 0xFF] << 16) | sprtabb[db >> 8]); - int off = (i << dbl) >> half; - uae_u16* buf = spixels + word_offs + off; + uae_u16 *buf = spixels + word_offs + off; if (currprefs.collision_level > 0 && collision_mask) record_sprite_1(sprxp + off, buf, datab, num, dbl, mask, 1, collision_mask); else @@ -2393,13 +3222,11 @@ static void record_sprite(int line, int num, int sprxp, uae_u16* data, uae_u16* } /* We have 8 bits per pixel in spixstate, two for every sprite pair. The - low order bit records whether the attach bit was set for this pair. */ - if (attachment) - { - uae_u8 state = 0x03 << (num & ~1); - uae_u8* stb1 = spixstate.bytes + word_offs; - for (i = 0; i < width; i += 8) - { + low order bit records whether the attach bit was set for this pair. */ + if (attachment && !ecsshres()) { + uae_u32 state = 0x01010101 << (num & ~1); + uae_u8 *stb1 = spixstate.bytes + word_offs; + for (i = 0; i < width; i += 8) { stb1[0] |= state; stb1[1] |= state; stb1[2] |= state; @@ -2410,25 +3237,23 @@ static void record_sprite(int line, int num, int sprxp, uae_u16* data, uae_u16* stb1[7] |= state; stb1 += 8; } - e->has_attached = true; + e->has_attached = 1; } } -static void add_sprite(int* countp, int num, int sprxp, int posns[], int nrs[]) +static void add_sprite(int *countp, int num, int sprxp, int posns[], int nrs[]) { int count = *countp; int j, bestp; /* Sort the sprites in order of ascending X position before recording them. */ - for (bestp = 0; bestp < count; bestp++) - { + for (bestp = 0; bestp < count; bestp++) { if (posns[bestp] > sprxp) break; if (posns[bestp] == sprxp && nrs[bestp] < num) break; } - for (j = count; j > bestp; j--) - { + for (j = count; j > bestp; j--) { posns[j] = posns[j - 1]; nrs[j] = nrs[j - 1]; } @@ -2440,15 +3265,18 @@ static void add_sprite(int* countp, int num, int sprxp, int posns[], int nrs[]) static int tospritexdiw(int diw) { - return coord_window_to_hw_x(diw - (DIW_DDF_OFFSET << lores_shift)) << sprite_buffer_res; + return coord_window_to_hw_x(diw - (DIW_DDF_OFFSET << lores_shift)) << sprite_buffer_res; } - static int tospritexddf(int ddf) { return (ddf * 2 - DIW_DDF_OFFSET) << sprite_buffer_res; } +static int fromspritexdiw(int ddf) +{ + return coord_hw_to_window_x(ddf >> sprite_buffer_res) + (DIW_DDF_OFFSET << lores_shift); +} -static void calcsprite() +static void calcsprite(void) { sprite_maxx = 0x7fff; sprite_minx = 0; @@ -2456,94 +3284,202 @@ static void calcsprite() sprite_maxx = tospritexdiw(thisline_decision.diwlastword); if (thisline_decision.diwfirstword >= 0) sprite_minx = tospritexdiw(thisline_decision.diwfirstword); - if (thisline_decision.plfleft >= 0) - { + if (thisline_decision.plfleft >= 0) { int min, max; min = tospritexddf(thisline_decision.plfleft); max = tospritexddf(thisline_decision.plfright); - if (min > sprite_minx && min < max) - { /* min < max = full line ddf */ - if (currprefs.chipset_mask & CSMASK_ECS_DENISE) - { + if (min > sprite_minx && min < max) { /* min < max = full line ddf */ + if (currprefs.chipset_mask & CSMASK_ECS_DENISE) { sprite_minx = min; } - else - { + else { if (thisline_decision.plfleft >= 0x28 || bpldmawasactive) sprite_minx = min; } } /* sprites are visible from first BPL1DAT write to end of line - * ECS Denise/AGA: no limits - * OCS Denise: BPL1DAT write only enables sprite if hpos >= 0x28 or so. - * (undocumented feature) - */ + * ECS Denise/AGA: no limits + * OCS Denise: BPL1DAT write only enables sprite if hpos >= 0x28 or so. + * (undocumented feature) + */ } } -static void decide_sprites(int hpos) +static void decide_sprites(int spnr, int hpos, bool usepointx, bool quick) { int nrs[MAX_SPRITES * 2], posns[MAX_SPRITES * 2]; int count, i; - int point = hpos * 2 + 0; + int point; int width = sprite_width; int sscanmask = 0x100 << sprite_buffer_res; + int gotdata = 0; + int startnr = 0, endnr = MAX_SPRITES - 1; if (thisline_decision.plfleft < 0 && !(bplcon3 & 2)) return; - if (nodraw () || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point) + // let sprite shift register empty completely + // if sprite is at the very edge of right border + point = hpos * 2; + if (hpos >= maxhpos) + point += ((9 - 2) * 2) * sprite_buffer_res; + + if (nodraw() || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point) return; - decide_diw(hpos); - decide_line(hpos); - calcsprite(); + if (spnr >= 0) { + startnr = spnr; + endnr = spnr; + } + if (!quick) { + decide_diw(hpos); + decide_line(hpos); + calcsprite(); + } count = 0; - for (i = 0; i < MAX_SPRITES; i++) - { - int sprxp = (fmode & 0x8000) ? (spr[i].xpos & ~sscanmask) : spr[i].xpos; + for (i = startnr; i <= endnr; i++) { + int xpos = spr[i].xpos; + int sprxp = (fmode & 0x8000) ? (xpos & ~sscanmask) : xpos; int hw_xp = sprxp >> sprite_buffer_res; + int pointx = usepointx && (sprctl[i] & sprite_sprctlmask) ? 0 : 1; - if (spr[i].xpos < 0) + if (xpos < 0) continue; - if (! spr[i].armed) + if (!((false & magic_sprite_mask) & (1 << i))) continue; - if (hw_xp > last_sprite_point && hw_xp <= point) - { + if (!spr[i].armed) + continue; + + if (hw_xp > last_sprite_point && hw_xp <= point + pointx) { add_sprite(&count, i, sprxp, posns, nrs); } /* SSCAN2-bit is fun.. */ - if ((fmode & 0x8000) && !(sprxp & sscanmask)) - { + if ((fmode & 0x8000) && !(sprxp & sscanmask)) { sprxp |= sscanmask; hw_xp = sprxp >> sprite_buffer_res; - if (hw_xp > last_sprite_point && hw_xp <= point) - { + if (hw_xp > last_sprite_point && hw_xp <= point + pointx) { add_sprite(&count, MAX_SPRITES + i, sprxp, posns, nrs); } } + else if (!(fmode & 0x80) && xpos >= (2 << sprite_buffer_res) && xpos <= (9 << sprite_buffer_res)) { + // right border wrap around. SPRxCTL horizontal bits do not matter. + sprxp += (maxhpos * 2) << sprite_buffer_res; + hw_xp = sprxp >> sprite_buffer_res; + if (hw_xp > last_sprite_point && hw_xp <= point + pointx) { + add_sprite(&count, MAX_SPRITES + i, sprxp, posns, nrs); + } + // (not really mutually exclusive of SSCAN2-bit but not worth the trouble) + } } - for (i = 0; i < count; i++) - { + for (i = 0; i < count; i++) { int nr = nrs[i] & (MAX_SPRITES - 1); record_sprite(next_lineno, nr, posns[i], sprdata[nr], sprdatb[nr], sprctl[nr]); + /* get left and right sprite edge if brdsprt enabled */ +#if AUTOSCALE_SPRITES + if (dmaen(DMA_SPRITE) && (bplcon0 & 1) && (bplcon3 & 0x02) && !(bplcon3 & 0x20) && nr > 0) { + int j, jj; + for (j = 0, jj = 0; j < sprite_width; j += 16, jj++) { + int nx = fromspritexdiw(posns[i] + j); + if (sprdata[nr][jj] || sprdatb[nr][jj]) { + if (diwfirstword_total > nx && nx >= (48 << currprefs.gfx_resolution)) + diwfirstword_total = nx; + if (diwlastword_total < nx + 16 && nx <= (448 << currprefs.gfx_resolution)) + diwlastword_total = nx + 16; + } + } + gotdata = 1; + } +#endif } last_sprite_point = point; + +#if AUTOSCALE_SPRITES + /* get upper and lower sprite position if brdsprt enabled */ + if (gotdata) { + if (vpos < first_planes_vpos) + first_planes_vpos = vpos; + if (vpos < plffirstline_total) + plffirstline_total = vpos; + if (vpos > last_planes_vpos) + last_planes_vpos = vpos; + if (vpos > plflastline_total) + plflastline_total = vpos; + } +#endif +} +static void decide_sprites(int spnr, int hpos) +{ + decide_sprites(spnr, hpos, false, false); +} +static void maybe_decide_sprites(int spnr, int hpos) +{ + if (!spr[spnr].armed) + return; + if (!sprdata[spnr] && !sprdatb[spnr]) + return; + decide_sprites(spnr, hpos, true, true); +} + +static int sprites_differ(struct draw_info *dip, struct draw_info *dip_old) +{ + struct sprite_entry *this_first = curr_sprite_entries + dip->first_sprite_entry; + struct sprite_entry *this_last = curr_sprite_entries + dip->last_sprite_entry; + struct sprite_entry *prev_first = prev_sprite_entries + dip_old->first_sprite_entry; + int npixels; + int i; + + if (dip->nr_sprites != dip_old->nr_sprites) + return 1; + + if (dip->nr_sprites == 0) + return 0; + + for (i = 0; i < dip->nr_sprites; i++) { + if (this_first[i].pos != prev_first[i].pos + || this_first[i].max != prev_first[i].max + || this_first[i].has_attached != prev_first[i].has_attached) + return 1; + } + + npixels = this_last->first_pixel + (this_last->max - this_last->pos) - this_first->first_pixel; + if (memcmp(spixels + this_first->first_pixel, spixels + prev_first->first_pixel, + npixels * sizeof(uae_u16)) != 0) + return 1; + if (memcmp(spixstate.bytes + this_first->first_pixel, spixstate.bytes + prev_first->first_pixel, npixels) != 0) + return 1; + return 0; +} + +static int color_changes_differ(struct draw_info *dip, struct draw_info *dip_old) +{ + if (dip->nr_color_changes != dip_old->nr_color_changes) + return 1; + + if (dip->nr_color_changes == 0) + return 0; + if (memcmp(curr_color_changes + dip->first_color_change, + prev_color_changes + dip_old->first_color_change, + dip->nr_color_changes * sizeof *curr_color_changes) != 0) + return 1; + return 0; } /* End of a horizontal scan line. Finish off all decisions that were not - * made yet. */ -STATIC_INLINE void finish_decisions() +* made yet. */ +static void finish_decisions(void) { - struct draw_info* dip; + struct draw_info *dip; + struct draw_info *dip_old; + struct decision *dp; + int changed; int hpos = maxhpos; - if (nodraw ()) + if (nodraw()) return; decide_diw(hpos); @@ -2551,32 +3487,50 @@ STATIC_INLINE void finish_decisions() decide_fetch_safe(hpos); finish_final_fetch(); - if (thisline_decision.plfleft >= 0 && thisline_decision.plflinelen < 0) - { + record_color_change2(hsyncstartpos, 0xffff, 0); + if (thisline_decision.plfleft >= 0 && thisline_decision.plflinelen < 0) { + if (fetch_state != fetch_not_started) { + write_log(_T("fetch_state=%d plfleft=%d,len=%d,vpos=%d,hpos=%d\n"), + fetch_state, thisline_decision.plfleft, thisline_decision.plflinelen, + vpos, hpos); + uae_abort(_T("fetch_state != fetch_not_started")); + } thisline_decision.plfright = thisline_decision.plfleft; thisline_decision.plflinelen = 0; thisline_decision.bplres = RES_LORES; } /* Large DIWSTOP values can cause the stop position never to be - * reached, so the state machine always stays in the same state and - * there's a more-or-less full-screen DIW. */ - if (hdiwstate == DIW_waiting_stop) - { + * reached, so the state machine always stays in the same state and + * there's a more-or-less full-screen DIW. */ + if (hdiwstate == DIW_waiting_stop) { thisline_decision.diwlastword = max_diwlastword; if (thisline_decision.diwfirstword < 0) thisline_decision.diwfirstword = min_diwlastword; } - decide_sprites(hpos + 1); + + if (thisline_decision.diwfirstword != line_decisions[next_lineno].diwfirstword) + MARK_LINE_CHANGED; + if (thisline_decision.diwlastword != line_decisions[next_lineno].diwlastword) + MARK_LINE_CHANGED; dip = curr_drawinfo + next_lineno; + dip_old = prev_drawinfo + next_lineno; + dp = line_decisions + next_lineno; + changed = thisline_changed | custom_frame_redraw_necessary; + if (thisline_decision.plfleft >= 0 && thisline_decision.nr_planes > 0) + record_diw_line(thisline_decision.plfleft, diwfirstword, diwlastword); + + decide_sprites(-1, hpos + 1); dip->last_sprite_entry = next_sprite_entry; dip->last_color_change = next_color_change; - if (thisline_decision.ctable < 0) - { - remember_ctable(); + if (thisline_decision.ctable < 0) { + if (thisline_decision.plfleft < 0) + remember_ctable_for_border(); + else + remember_ctable(); } dip->nr_color_changes = next_color_change - dip->first_color_change; @@ -2584,23 +3538,50 @@ STATIC_INLINE void finish_decisions() line_decisions[next_lineno] = thisline_decision; + if (thisline_decision.plfleft != line_decisions[next_lineno].plfleft) + changed = 1; + if (!changed && color_changes_differ(dip, dip_old)) + changed = 1; + if (!changed && /* bitplane visible in this line OR border sprites enabled */ + (thisline_decision.plfleft >= 0 || ((thisline_decision.bplcon0 & 1) && (thisline_decision.bplcon3 & 0x02) && !(thisline_decision.bplcon3 & 0x20))) + && sprites_differ(dip, dip_old)) + { + changed = 1; + } + + if (changed) { + thisline_changed = 1; + *dp = thisline_decision; + } + else { + /* The only one that may differ: */ + dp->ctable = thisline_decision.ctable; + } + /* leave free space for possible extra color changes at the end of line */ next_color_change += (HBLANK_OFFSET + 1) / 2; diw_hcounter += maxhpos * 2; if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE) && vpos == get_equ_vblank_endline() - 1) diw_hcounter++; - if ((currprefs.chipset_mask & CSMASK_ECS_DENISE) || vpos > get_equ_vblank_endline()) - { + if ((currprefs.chipset_mask & CSMASK_ECS_DENISE) || vpos > get_equ_vblank_endline() || (currprefs.cs_dipagnus && vpos == 0)) { diw_hcounter = maxhpos * 2; last_hdiw = 2 - 1; } + + if (next_color_change >= MAX_REG_CHANGE - 30) { + //write_log(_T("color_change buffer overflow!\n")); + next_color_change = 0; + dip->nr_color_changes = 0; + dip->first_color_change = 0; + dip->last_color_change = 0; + } } /* Set the state of all decisions to "undecided" for a new scanline. */ -static void reset_decisions() +static void reset_decisions(void) { - if (nodraw ()) + if (nodraw()) return; toscr_nr_planes = toscr_nr_planes2 = 0; @@ -2608,83 +3589,138 @@ static void reset_decisions() thisline_decision.nr_planes = 0; bpl1dat_written = false; bpl1dat_written_at_least_once = false; - bpl1dat_early = false; - plfleft_real = -1; thisline_decision.plfleft = -1; thisline_decision.plflinelen = -1; - thisline_decision.ham_seen = !! (bplcon0 & 0x800); - thisline_decision.ham_at_start = !! (bplcon0 & 0x800); + thisline_decision.ham_seen = !!(bplcon0 & 0x800); + thisline_decision.ehb_seen = !!isehb(bplcon0, bplcon2); + thisline_decision.ham_at_start = !!(bplcon0 & 0x800); thisline_decision.bordersprite_seen = issprbrd(-1, bplcon0, bplcon3); /* decided_res shouldn't be touched before it's initialized by decide_line(). */ thisline_decision.diwfirstword = -1; thisline_decision.diwlastword = -1; - if (hdiwstate == DIW_waiting_stop) - { + if (hdiwstate == DIW_waiting_stop) { thisline_decision.diwfirstword = min_diwlastword; + if (thisline_decision.diwfirstword != line_decisions[next_lineno].diwfirstword) + MARK_LINE_CHANGED; } thisline_decision.ctable = -1; + thisline_changed = 0; curr_drawinfo[next_lineno].first_color_change = next_color_change; curr_drawinfo[next_lineno].first_sprite_entry = next_sprite_entry; next_sprite_forced = 1; last_sprite_point = 0; fetch_state = fetch_not_started; - bplcon1_hpos = -1; - if (bpldmasetuphpos >= 0) - { + if (bpldmasetuphpos >= 0) { // this can happen in "too fast" modes BPLCON0_Denise(0, bplcon0, true); setup_fmodes(0); } bpldmasetuphpos = -1; bpldmasetupphase = 0; - ddfstrt_old_hpos = -1; bpldmawasactive = false; - bitplane_dma_turned_on = 0; + reset_moddelays(); + delay_cycles = 0; + compute_toscr_delay(bplcon1); - if (plf_state > plf_active) - plf_state = plf_idle; - if (plf_state == plf_active && !(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + if (plf_state >= plf_passed_stop2 || plf_state == plf_wait) plf_state = plf_idle; - memset(todisplay, 0, sizeof todisplay); - memset(fetched, 0, sizeof fetched); - if (aga_mode) - { - memset(fetched_aga0, 0, sizeof fetched_aga0); - memset(fetched_aga1, 0, sizeof fetched_aga1); + // Only ECS Agnus can keep DDF open between lines + if ((currprefs.chipset_mask & CSMASK_ECS_AGNUS)) { + if (!ddfstop_matched) { + plf_state = plf_active; + } } - memset(outword, 0, sizeof outword); - last_decide_line_hpos = -1; + bpl_hstart = 256; + plfr_state = plfr_idle; + plf_start_hpos = 256 + DDF_OFFSET; + plf_end_hpos = 256 + DDF_OFFSET; + ddfstop_written_hpos = -1; + bitplane_maybe_start_hpos = -1; + bitplane_off_delay = -1; + hack_delay_shift = 0; + + if (line_cyclebased) { + line_cyclebased--; + if (!line_cyclebased) { + bpl_dma_off_when_active = 0; + } + } + + memset(outword, 0, sizeof outword); + // fetched[] must not be cleared (Sony VX-90 / Royal Amiga Force) + todisplay_fetched[0] = todisplay_fetched[1] = false; + memset(todisplay, 0, sizeof todisplay); + memset(todisplay2, 0, sizeof todisplay2); +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) { + memset(todisplay_aga, 0, sizeof todisplay_aga); + memset(todisplay2_aga, 0, sizeof todisplay2_aga); + } + aga_plf_passed_stop2 = false; +#endif + + if (bitplane_line_crossing) { + // BPL1DAT would have been written after end of last scanline. + // Set BPL1DAT "written at least once" state for new scanline. + bitplane_line_crossing -= maxhpos - HPOS_SHIFT; + if (bitplane_line_crossing > 0) { + bpl1dat_written = true; + bpl1dat_written_at_least_once = true; + reset_bpl_vars(); + beginning_of_plane_block(bitplane_line_crossing, fetchmode); + } + bitplane_line_crossing = 0; + } + else { + reset_bpl_vars(); + } + + last_decide_line_hpos = -(DDF_OFFSET + 1); + last_ddf_pix_hpos = -1; last_sprite_hpos = -1; last_fetch_hpos = -1; + if (sprite_ignoreverticaluntilnextline) { + sprite_ignoreverticaluntilnextline = false; + for (int i = 0; i < MAX_SPRITES; i++) + spr[i].ignoreverticaluntilnextline = false; + } + /* These are for comparison. */ thisline_decision.bplcon0 = bplcon0; thisline_decision.bplcon2 = bplcon2; +#ifdef ECS_DENISE thisline_decision.bplcon3 = bplcon3; +#endif +#ifdef AGA thisline_decision.bplcon4 = bplcon4; +#endif + scanlinecount++; } int vsynctimebase_orig; -void compute_vsynctime() +void compute_vsynctime(void) { + double svpos = maxvpos_nom; + double shpos = maxhpos_short; + double syncadjust = 1.0; + fake_vblank_hz = 0; vblank_hz_mult = 0; vblank_hz_state = 1; - if (fabs(currprefs.chipset_refreshrate) > 0.1) - { + if (fabs(currprefs.chipset_refreshrate) > 0.1) { + syncadjust = currprefs.chipset_refreshrate / vblank_hz_nom; vblank_hz = currprefs.chipset_refreshrate; - if (isvsync_chipset()) - { + if (isvsync_chipset()) { int mult = 0; - if (getvsyncrate(vblank_hz, &mult) != vblank_hz) - { + if (getvsyncrate(vblank_hz, &mult) != vblank_hz) { vblank_hz = getvsyncrate(vblank_hz, &vblank_hz_mult); if (vblank_hz_mult > 0) vblank_hz_state = 0; @@ -2693,176 +3729,336 @@ void compute_vsynctime() } if (!fake_vblank_hz) fake_vblank_hz = vblank_hz; - // if (currprefs.turbo_emulation) - // vsynctimebase = vsynctimebase_orig = 1; - // else - vsynctimebase = vsynctimebase_orig = int(syncbase / fake_vblank_hz); -#if 0 - if (!picasso_on) { - updatedisplayarea(); + + if (currprefs.turbo_emulation) { + if (currprefs.turbo_emulation_limit > 0) { + vsynctimebase = int(syncbase / currprefs.turbo_emulation_limit); + } + else { + vsynctimebase = 1; + } } -#endif - if (currprefs.produce_sound > 1) - { - double svpos = maxvpos_nom; - double shpos = maxhpos_short; - if (islinetoggle()) - { - shpos += 0.5; - } - // if (interlace_seen) { - if ((bplcon0 & 4)) - { - svpos += 0.5; - } - else if (lof_current) - { - svpos += 1.0; - } + else { + vsynctimebase = int(syncbase / fake_vblank_hz); + } + vsynctimebase_orig = vsynctimebase; + + if (islinetoggle()) { + shpos += 0.5; + } + if (interlace_seen) { + svpos += 0.5; + } + else if (lof_current) { + svpos += 1.0; + } + if (currprefs.produce_sound > 1) { double clk = svpos * shpos * fake_vblank_hz; //write_log (_T("SNDRATE %.1f*%.1f*%.6f=%.6f\n"), svpos, shpos, fake_vblank_hz, clk); update_sound(clk); + //devices_update_sound(clk, syncadjust); //TODO } + //devices_update_sync(svpos, syncadjust); //TODO } -int current_maxvpos() +void getsyncregisters(uae_u16 *phsstrt, uae_u16 *phsstop, uae_u16 *pvsstrt, uae_u16 *pvsstop) +{ + *phsstrt = hsstrt; + *phsstop = hsstop; + *pvsstrt = vsstrt; + *pvsstop = vsstop; +} + +//static void dumpsync(void) +//{ +// static int cnt = 100; +// if (cnt < 0) +// return; +// cnt--; +// write_log(_T("BEAMCON0=%04X VTOTAL=%04X HTOTAL=%04X\n"), new_beamcon0, vtotal, htotal); +// write_log(_T(" HSSTOP=%04X HBSTRT=%04X HBSTOP=%04X\n"), hsstop, hbstrt, hbstop); +// write_log(_T(" VSSTOP=%04X VBSTRT=%04X VBSTOP=%04X\n"), vsstop, vbstrt, vbstop); +// write_log(_T(" HSSTRT=%04X VSSTRT=%04X HCENTER=%04X\n"), hsstrt, vsstrt, hcenter); +// write_log(_T(" HSYNCSTART=%04X HSYNCEND=%04X\n"), hsyncstartpos, hsyncendpos); +//} + +int current_maxvpos(void) { return maxvpos + (lof_store ? 1 : 0); } -static void compute_framesync() +struct chipset_refresh *get_chipset_refresh(void) { - int v; + int islace = interlace_seen ? 1 : 0; + int isntsc = (beamcon0 & 0x20) ? 0 : 1; + int custom = (beamcon0 & 0x80) ? 1 : 0; - if (!picasso_on && !picasso_requested_on) - { - if (fabs(vblank_hz - 50) < 1 || fabs(vblank_hz - 60) < 1) - { - vsync_switchmode(vblank_hz); + if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + isntsc = currprefs.ntscmode ? 1 : 0; + + int def = -1; + for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) { + struct chipset_refresh *cr = &currprefs.cr[i]; + if (cr->defaultdata) + def = i; + if (cr->inuse) { + if ((cr->horiz < 0 || cr->horiz == maxhpos) && + (cr->vert < 0 || cr->vert == maxvpos_display) && + (cr->ntsc < 0 || (cr->ntsc == 1 && isntsc && !custom) || (cr->ntsc == 0 && !isntsc && !custom) || (cr->ntsc == 2 && custom)) && + (cr->lace < 0 || (cr->lace > 0 && islace) || (cr->lace == 0 && !islace)) && + (cr->resolution == 0 || cr->resolution == 7 || (cr->resolution & (1 << detected_screen_resolution))) && + (cr->framelength < 0 || (cr->framelength > 0 && lof_store) || (cr->framelength == 0 && !lof_store) || (cr->framelength >= 0 && islace)) && + ((cr->rtg && picasso_on) || (!cr->rtg && !picasso_on)) && + (cr->vsync < 0 || (cr->vsync > 0 && isvsync_chipset()) || (cr->vsync == 0 && !isvsync_chipset()))) + return cr; } - v = (vblank_hz >= 55) ? 60 : 50; } - else - { - v = (currprefs.ntscmode ? 60 : 50); + if (def >= 0) + return &currprefs.cr[def]; + return nullptr; +} + +static bool changed_chipset_refresh(void) +{ + return stored_chipset_refresh != get_chipset_refresh(); +} + +void compute_framesync(void) +{ + int islace = interlace_seen ? 1 : 0; + int isntsc = (beamcon0 & 0x20) ? 0 : 1; + bool found = false; + + if (islace) { + vblank_hz = vblank_hz_lace; + } + else if (lof_current) { + vblank_hz = vblank_hz_lof; + } + else { + vblank_hz = vblank_hz_shf; } - changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = v; + //vblank_hz = target_adjust_vblank_hz(vblank_hz); + + struct chipset_refresh *cr = get_chipset_refresh(); + while (cr) { + double v = -1; + if (!picasso_on && !picasso_requested_on) { + if (isvsync_chipset()) { + if (cr->index == CHIPSET_REFRESH_PAL || cr->index == CHIPSET_REFRESH_NTSC) { + if ((fabs(vblank_hz - 50) < 1 || fabs(vblank_hz - 60) < 1 || fabs(vblank_hz - 100) < 1 || fabs(vblank_hz - 120) < 1) && currprefs.gfx_apmode[0].gfx_vsync == 2 && currprefs.gfx_apmode[0].gfx_fullscreen > 0) { + vsync_switchmode(int(vblank_hz)); + } + } + + else if (isvsync_chipset() > 0) { + if (currprefs.gfx_apmode[0].gfx_refreshrate) + v = abs(currprefs.gfx_apmode[0].gfx_refreshrate); + } + } + else { + if (cr->locked == false) { + changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = vblank_hz; + cfgfile_parse_lines(&changed_prefs, cr->commands, -1); + if (cr->commands[0]) + write_log(_T("CMD1: '%s'\n"), cr->commands); + break; + } + else { + v = cr->rate; + } + } + if (v < 0) + v = cr->rate; + if (v > 0) { + changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = v; + cfgfile_parse_lines(&changed_prefs, cr->commands, -1); + if (cr->commands[0]) + write_log(_T("CMD2: '%s'\n"), cr->commands); + } + } + else { + if (cr->locked == false) + v = vblank_hz; + else + v = cr->rate; + changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = v; + cfgfile_parse_lines(&changed_prefs, cr->commands, -1); + if (cr->commands[0]) + write_log(_T("CMD3: '%s'\n"), cr->commands); + } + found = true; + break; + } + if (!found) { + changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = vblank_hz; + } + stored_chipset_refresh = cr; + interlace_changed = 0; + lof_togglecnt_lace = 0; + lof_togglecnt_nlace = 0; lof_changing = 0; + if (beamcon0 & 0x80) { + int res = GET_RES_AGNUS(bplcon0); + int vres = islace ? 1 : 0; + int res2, vres2; + + res2 = currprefs.gfx_resolution; + if (doublescan > 0) + res2++; + if (res2 > RES_MAX) + res2 = RES_MAX; + + vres2 = currprefs.gfx_vresolution; + if (doublescan > 0 && !islace) + vres2--; + + if (vres2 < 0) + vres2 = 0; + if (vres2 > VRES_QUAD) + vres2 = VRES_QUAD; + + int start = hsyncstartpos; //hbstrt; + int stop = hsyncendpos; //hbstop; + + gfxvidinfo.outwidth = ((maxhpos - (maxhpos - start + DISPLAY_LEFT_SHIFT / 2) + 1) * 2) << res2; + gfxvidinfo.outheight = ((firstblankedline < maxvpos ? firstblankedline : maxvpos) - minfirstline + 1) << vres2; + + } + else { + gfxvidinfo.outwidth = AMIGA_WIDTH_MAX << currprefs.gfx_resolution; + gfxvidinfo.outheight = (maxvpos_display - minfirstline + 1) << currprefs.gfx_vresolution; + } + memset(line_decisions, 0, sizeof line_decisions); + memset(line_drawinfo, 0, sizeof line_drawinfo); + for (int i = 0; i < sizeof(line_decisions) / sizeof *line_decisions; i++) { + line_decisions[i].plfleft = -2; + } compute_vsynctime(); - if (target_graphics_buffer_update()) - { + hblank_hz = double(currprefs.ntscmode ? CHIPSET_CLOCK_NTSC : CHIPSET_CLOCK_PAL) / (maxhpos + (islinetoggle() ? 0.5 : 0)); + + set_config_changed(); + + if (target_graphics_buffer_update()) { reset_drawing(); } } /* set PAL/NTSC or custom timing variables */ -static void init_hz(bool fullinit) +static void init_hz(bool checkvposw) { - int isntsc; - int omaxvpos = maxvpos; + int isntsc, islace; + int odbl = doublescan, omaxvpos = maxvpos; + double ovblank = vblank_hz; int hzc = 0; - if (fullinit) + if (!checkvposw) vpos_count = 0; vpos_count_diff = vpos_count; + doublescan = 0; + programmedmode = false; if ((beamcon0 & 0xA0) != (new_beamcon0 & 0xA0)) hzc = 1; - if (beamcon0 != new_beamcon0) - { + if (beamcon0 != new_beamcon0) { + //write_log(_T("BEAMCON0 %04x -> %04x PC=%08x\n"), beamcon0, new_beamcon0, M68K_GETPC); vpos_count_diff = vpos_count = 0; } beamcon0 = new_beamcon0; isntsc = (beamcon0 & 0x20) ? 0 : 1; + islace = (interlace_seen) ? 1 : 0; if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) isntsc = currprefs.ntscmode ? 1 : 0; - if (!isntsc) - { + int clk = currprefs.ntscmode ? CHIPSET_CLOCK_NTSC : CHIPSET_CLOCK_PAL; + if (!isntsc) { maxvpos = MAXVPOS_PAL; maxhpos = MAXHPOS_PAL; minfirstline = VBLANK_ENDLINE_PAL; - vblank_hz = VBLANK_HZ_PAL; + vblank_hz_nom = vblank_hz = VBLANK_HZ_PAL; sprite_vblank_endline = VBLANK_SPRITE_PAL; equ_vblank_endline = EQU_ENDLINE_PAL; equ_vblank_toggle = true; + vblank_hz_shf = double(clk) / ((maxvpos + 0) * maxhpos); + vblank_hz_lof = double(clk) / ((maxvpos + 1) * maxhpos); + vblank_hz_lace = double(clk) / ((maxvpos + 0.5) * maxhpos); } - else - { + else { maxvpos = MAXVPOS_NTSC; maxhpos = MAXHPOS_NTSC; minfirstline = VBLANK_ENDLINE_NTSC; - vblank_hz = VBLANK_HZ_NTSC; + vblank_hz_nom = vblank_hz = VBLANK_HZ_NTSC; sprite_vblank_endline = VBLANK_SPRITE_NTSC; equ_vblank_endline = EQU_ENDLINE_NTSC; equ_vblank_toggle = false; + vblank_hz_shf = double(clk) / ((maxvpos + 0) * (maxhpos + 0.5)); + vblank_hz_lof = double(clk) / ((maxvpos + 1) * (maxhpos + 0.5)); + vblank_hz_lace = double(clk) / ((maxvpos + 0.5) * (maxhpos + 0.5)); } maxvpos_nom = maxvpos; maxvpos_display = maxvpos; - if (vpos_count > 0) - { + if (vpos_count > 0) { // we come here if vpos_count != maxvpos and beamcon0 didn't change // (someone poked VPOSW) if (vpos_count < 10) vpos_count = 10; vblank_hz = (isntsc ? 15734.0 : 15625.0) / vpos_count; - // vblank_hz_nom = vblank_hz_shf = vblank_hz_lof = vblank_hz_lace = vblank_hz; + vblank_hz_nom = vblank_hz_shf = vblank_hz_lof = vblank_hz_lace = vblank_hz; maxvpos_nom = vpos_count - (lof_current ? 1 : 0); - if ((maxvpos_nom >= 256 && maxvpos_nom <= 313) || (beamcon0 & 0x80)) - { + if ((maxvpos_nom >= 256 && maxvpos_nom <= 313) || (beamcon0 & 0x80)) { maxvpos_display = maxvpos_nom; } - else if (maxvpos_nom < 256) - { + else if (maxvpos_nom < 256) { maxvpos_display = 255; } - else - { + else { maxvpos_display = 313; } reset_drawing(); } - else if (vpos_count == 0) - { + else if (vpos_count == 0) { // mode reset vpos_count = maxvpos; vpos_count_diff = maxvpos; } + firstblankedline = maxvpos + 1; - if (beamcon0 & 0x80) - { + if (beamcon0 & 0x80) { // programmable scanrates (ECS Agnus) if (vtotal >= MAXVPOS) vtotal = MAXVPOS - 1; maxvpos = vtotal + 1; + firstblankedline = maxvpos + 1; if (htotal >= MAXHPOS) htotal = MAXHPOS - 1; maxhpos = htotal + 1; - vblank_hz = 227.0 * 312.0 * 50.0 / (maxvpos * maxhpos); + vblank_hz_nom = vblank_hz = 227.0 * 312.0 * 50.0 / (maxvpos * maxhpos); + vblank_hz_shf = vblank_hz; + vblank_hz_lof = 227.0 * 313.0 * 50.0 / (maxvpos * maxhpos);; + vblank_hz_lace = 227.0 * 312.5 * 50.0 / (maxvpos * maxhpos);; - if ((beamcon0 & 0x1000) && (beamcon0 & 0x0200)) - { // VARVBEN + VARVSYEN + if ((beamcon0 & 0x1000) && (beamcon0 & 0x0200)) { // VARVBEN + VARVSYEN minfirstline = vsstop > vbstop ? vsstop : vbstop; if (minfirstline > maxvpos / 2) minfirstline = vsstop > vbstop ? vbstop : vsstop; + firstblankedline = vbstrt; } - else if (beamcon0 & 0x0200) - { + else if (beamcon0 & 0x0200) { minfirstline = vsstop; if (minfirstline > maxvpos / 2) minfirstline = 0; } - else if (beamcon0 & 0x1000) - { + else if (beamcon0 & 0x1000) { minfirstline = vbstop; if (minfirstline > maxvpos / 2) minfirstline = 0; + firstblankedline = vbstrt; } if (minfirstline < 2) @@ -2870,10 +4066,19 @@ static void init_hz(bool fullinit) if (minfirstline >= maxvpos) minfirstline = maxvpos - 1; + if (firstblankedline < minfirstline) + firstblankedline = maxvpos + 1; + sprite_vblank_endline = minfirstline - 2; maxvpos_nom = maxvpos; maxvpos_display = maxvpos; equ_vblank_endline = -1; + doublescan = htotal <= 164 && vtotal >= 350 ? 1 : 0; + // if superhires and wide enough: not doublescan + if (doublescan && htotal >= 140 && (bplcon0 & 0x0040)) + doublescan = 0; + programmedmode = true; + varsync_changed = true; vpos_count = maxvpos_nom; vpos_count_diff = maxvpos_nom; hzc = 1; @@ -2882,7 +4087,9 @@ static void init_hz(bool fullinit) maxvpos_nom = MAXVPOS; if (maxvpos_display >= MAXVPOS) maxvpos_display = MAXVPOS; - if (maxvpos != omaxvpos) + if (currprefs.gfx_scandoubler && doublescan == 0) + doublescan = -1; + if (doublescan != odbl || maxvpos != omaxvpos) hzc = 1; /* limit to sane values */ if (vblank_hz < 10) @@ -2890,39 +4097,98 @@ static void init_hz(bool fullinit) if (vblank_hz > 300) vblank_hz = 300; maxhpos_short = maxhpos; + set_delay_lastcycle(); + if ((beamcon0 & 0x80) && (beamcon0 & 0x0100)) { + + hsyncstartpos = hsstrt; + hsyncendpos = hsstop; + + if ((bplcon0 & 1) && (bplcon3 & 1)) { + + if (hbstrt > maxhpos / 2) { + if (hsyncstartpos < hbstrt) + hsyncstartpos = hbstrt; + } + else { + if (hsyncstartpos > hbstrt) + hsyncstartpos = hbstrt; + } + + if (hbstop > maxhpos / 2) { + if (hsyncendpos > hbstop) + hsyncendpos = hbstop; + } + else { + if (hsyncendpos < hbstop) + hsyncendpos = hbstop; + } + } + + if (hsyncstartpos < hsyncendpos) + hsyncstartpos = maxhpos + hsyncstartpos; + + hsyncendpos--; + + if (hsyncendpos < 2) + hsyncendpos = 2; + + if (hsyncstartpos - hsyncendpos < maxhpos / 2) + hsyncstartpos = maxhpos; + + } + else { + + hsyncstartpos = maxhpos_short + 13; + hsyncendpos = 24; + + } + hpos_offset = 0; eventtab[ev_hsync].oldcycles = get_cycles(); eventtab[ev_hsync].evtime = get_cycles() + HSYNCTIME; events_schedule(); - if (hzc) - { + if (hzc) { + interlace_seen = islace; reset_drawing(); } + maxvpos_total = (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? (MAXVPOS_LINES_ECS - 1) : (MAXVPOS_LINES_OCS - 1); if (maxvpos_total > MAXVPOS) maxvpos_total = MAXVPOS; +#ifdef PICASSO96 + if (!p96refresh_active) { + maxvpos_stored = maxvpos; + maxhpos_stored = maxhpos; + vblank_hz_stored = vblank_hz; + } +#endif compute_framesync(); + //devices_syncchange(); #ifdef PICASSO96 init_hz_p96(); #endif + if (vblank_hz != ovblank) + updatedisplayarea(); inputdevice_tablet_strobe(); - if (fullinit) - vpos_count_diff = maxvpos_nom; + if (varsync_changed) { + varsync_changed = false; + //dumpsync(); + } } -void init_hz() -{ - init_hz(false); -} - -void init_hz_full() +static void init_hz_vposw(void) { init_hz(true); } -static void calcdiw() +void init_hz_normal(void) +{ + init_hz(false); +} + +static void calcdiw(void) { int hstrt = diwstrt & 0xFF; int hstop = diwstop & 0xFF; @@ -2930,24 +4196,20 @@ static void calcdiw() int vstop = diwstop >> 8; // vertical in ECS Agnus - if (diwhigh_written && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) - { + if (diwhigh_written && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) { vstrt |= (diwhigh & 7) << 8; vstop |= ((diwhigh >> 8) & 7) << 8; } - else - { + else { if ((vstop & 0x80) == 0) vstop |= 0x100; } // horizontal in ECS Denise - if (diwhigh_written && (currprefs.chipset_mask & CSMASK_ECS_DENISE)) - { + if (diwhigh_written && (currprefs.chipset_mask & CSMASK_ECS_DENISE)) { hstrt |= ((diwhigh >> 5) & 1) << 8; hstop |= ((diwhigh >> 13) & 1) << 8; } - else - { + else { hstop += 0x100; } @@ -2956,152 +4218,206 @@ static void calcdiw() diwfirstword = coord_diw_to_window_x(hstrt); diwlastword = coord_diw_to_window_x(hstop); - if (diwfirstword >= diwlastword) - { + + if (diwfirstword >= diwlastword) { diwfirstword = min_diwlastword; diwlastword = max_diwlastword; } if (diwfirstword < min_diwlastword) diwfirstword = min_diwlastword; + if (vstrt == vpos && vstop != vpos && diwstate == DIW_waiting_start) { + // This may start BPL DMA immediately. + SET_LINE_CYCLEBASED; + bitplane_maybe_start_hpos = current_hpos(); + } + plffirstline = vstrt; plflastline = vstop; - plfstrt = ddfstrt; - plfstop = ddfstop; + plfstrt = ddfstrt - DDF_OFFSET; + plfstop = ddfstop - DDF_OFFSET; - /* probably not the correct place.. should use plf_state instead */ - if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) - { - /* ECS/AGA and ddfstop > maxhpos == always-on display */ - if (plfstop > maxhpos) - plfstrt = 0; - if (plfstrt < HARD_DDF_START) - plfstrt = HARD_DDF_START; - } - else - { - /* OCS and ddfstrt >= ddfstop == ddfstop = max */ - if (plfstrt >= plfstop && plfstrt >= HARD_DDF_START) - plfstop = 0xff; - } + diw_change = 2; } /* display mode changed (lores, doubling etc..), recalculate everything */ -void init_custom() +void init_custom(void) { update_mirrors(); create_cycle_diagram_table(); reset_drawing(); - init_hz(); + init_hz_normal(); calcdiw(); } static int timehack_alive = 0; -static uae_u32 REGPARAM2 timehack_helper(TrapContext* context) +static uae_u32 REGPARAM2 timehack_helper(TrapContext *context) { #ifdef HAVE_GETTIMEOFDAY struct timeval tv; - if (m68k_dreg (regs, 0) == 0) + if (m68k_dreg(regs, 0) == 0) return timehack_alive; timehack_alive = 10; gettimeofday(&tv, nullptr); - put_long(m68k_areg (regs, 0), tv.tv_sec - (365 * 8 + 2) * 24 * 60 * 60); - put_long(m68k_areg (regs, 0) + 4, tv.tv_usec); + put_long(m68k_areg(regs, 0), tv.tv_sec - (((365 * 8 + 2) * 24) * 60 * 60)); + put_long(m68k_areg(regs, 0) + 4, tv.tv_usec); return 0; #else - return 2; + return 2; #endif } /* - * register functions - */ -STATIC_INLINE uae_u16 DENISEID(int* missing) +* register functions +*/ +static uae_u16 DENISEID(int *missing) { *missing = 0; - if (aga_mode) - { + if (currprefs.cs_deniserev >= 0) + return currprefs.cs_deniserev; +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) { + if (currprefs.cs_ide == IDE_A4000) + return 0xFCF8; return 0x00F8; } +#endif if (currprefs.chipset_mask & CSMASK_ECS_DENISE) return 0xFFFC; - if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) + if (currprefs.cpu_model == 68000 && (currprefs.cpu_compatible || currprefs.cpu_memory_cycle_exact)) *missing = 1; return 0xFFFF; } STATIC_INLINE uae_u16 DMACONR(int hpos) { + decide_line(hpos); + decide_fetch_safe(hpos); dmacon &= ~(0x4000 | 0x2000); - dmacon |= (bltstate == BLT_done ? 0 : 0x4000) + dmacon |= ((blit_interrupt || (!blit_interrupt && currprefs.cs_agnusbltbusybug && !blt_info.got_cycle)) ? 0 : 0x4000) | (blt_info.blitzero ? 0x2000 : 0); return dmacon; } - -STATIC_INLINE uae_u16 INTENAR() +STATIC_INLINE uae_u16 INTENAR(void) { return intena; } - -STATIC_INLINE uae_u16 ADKCONR() +uae_u16 INTREQR(void) +{ + return intreq; +} +STATIC_INLINE uae_u16 ADKCONR(void) { return adkcon; } -STATIC_INLINE int GETVPOS() +STATIC_INLINE int islightpentriggered(void) { - return vpos; + if (beamcon0 & 0x2000) // LPENDIS + return 0; + return lightpen_triggered > 0; +} +STATIC_INLINE int issyncstopped(void) +{ + return (bplcon0 & 2) && !currprefs.genlock; } -STATIC_INLINE int GETHPOS() +STATIC_INLINE int GETVPOS(void) { - return current_hpos(); + return islightpentriggered() ? vpos_lpen : (issyncstopped() ? vpos_previous : vpos); +} +STATIC_INLINE int GETHPOS(void) +{ + return islightpentriggered() ? hpos_lpen : (issyncstopped() ? hpos_previous : current_hpos()); } -#define CPU_ACCURATE (currprefs.cpu_model < 68020) +// fake changing hpos when rom genlock test runs and genlock is connected +static bool hsyncdelay(void) +{ + if (!currprefs.genlock) + return false; + //if (currprefs.cpu_memory_cycle_exact || currprefs.m68k_speed >= 0) + if (currprefs.m68k_speed >= 0) + return false; + if (bplcon0 == (0x0100 | 0x0002)) { + return true; + } + return false; +} + +#define CPU_ACCURATE (currprefs.cpu_model < 68020 || (currprefs.cpu_model == 68020 && currprefs.cpu_memory_cycle_exact)) // DFF006 = 0.W must be valid result but better do this only in 68000 modes (whdload black screen!) // HPOS is shifted by 3 cycles and VPOS increases when shifted HPOS==1 #define HPOS_OFFSET (CPU_ACCURATE ? HPOS_SHIFT : 0) #define VPOS_INC_DELAY (HPOS_OFFSET ? 1 : 0) -STATIC_INLINE uae_u16 VPOSR() +static uae_u16 VPOSR(void) { unsigned int csbit = 0; uae_u16 vp = GETVPOS(); uae_u16 hp = GETHPOS(); + int lof = lof_store; - if (hp + HPOS_OFFSET >= maxhpos + VPOS_INC_DELAY) - { + if (vp + 1 == maxvpos + lof_store && (hp == maxhpos - 1 || hp == maxhpos - 2)) { + // lof toggles 2 cycles before maxhpos, so do fake toggle here. + if ((bplcon0 & 4) && CPU_ACCURATE) + lof = lof ? 0 : 1; + } + if (hp + HPOS_OFFSET >= maxhpos + VPOS_INC_DELAY) { vp++; if (vp >= maxvpos + lof_store) vp = 0; } vp = (vp >> 8) & 7; - csbit |= (aga_mode) ? 0x2300 : 0; - csbit |= (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? 0x2000 : 0; - if (currprefs.ntscmode) - csbit |= 0x1000; + if (currprefs.cs_agnusrev >= 0) { + csbit |= currprefs.cs_agnusrev << 8; + } + else { +#ifdef AGA + csbit |= (currprefs.chipset_mask & CSMASK_AGA) ? 0x2300 : 0; +#endif + csbit |= (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? 0x2000 : 0; + if (currprefs.ntscmode) + csbit |= 0x1000; + } if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) vp &= 1; - vp |= (lof_store ? 0x8000 : 0) | csbit; + vp |= (lof ? 0x8000 : 0) | csbit; + if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) + vp |= lol ? 0x80 : 0; + hsyncdelay(); + return vp; } +static void vposback(int oldvpos) +{ + if (cop_state.state == COP_wait && oldvpos == cop_state.vcmp) { + copper_enabled_thisline = 0; + unset_special(SPCFLAG_COPPER); + } +} + static void VPOSW(uae_u16 v) { int oldvpos = vpos; - if (lof_store != ((v & 0x8000) ? 1 : 0)) - { + + if (lof_store != ((v & 0x8000) ? 1 : 0)) { lof_store = (v & 0x8000) ? 1 : 0; lof_changing = lof_store ? 1 : -1; } + if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { + lol = (v & 0x0080) ? 1 : 0; + if (!islinetoggle()) + lol = 0; + } if (lof_changing) return; vpos &= 0x00ff; @@ -3120,54 +4436,107 @@ static void VHPOSW(uae_u16 v) int oldvpos = vpos; bool changed = false; + if (currprefs.cpu_memory_cycle_exact && currprefs.cpu_model == 68000) { + /* Special hack for Smooth Copper in CoolFridge / Upfront demo */ + int chp = current_hpos_safe(); + int hp = v & 0xff; + if (chp >= 0x21 && chp <= 0x29 && hp == 0x2d) { + hack_delay_shift = 4; + record_color_change(chp, 0, COLOR_CHANGE_HSYNC_HACK | 6); + thisline_changed = true; + } + } + v >>= 8; vpos &= 0xff00; vpos |= v; if (vpos != oldvpos && !changed) vposw_change++; - if (vpos < oldvpos) - { + if (vpos < oldvpos) { vpos = oldvpos; } - else if (vpos < minfirstline && oldvpos < minfirstline) - { + else if (vpos < minfirstline && oldvpos < minfirstline) { vpos = oldvpos; } } -STATIC_INLINE uae_u16 VHPOSR() +static uae_u16 VHPOSR(void) { + static uae_u16 oldhp; uae_u16 vp = GETVPOS(); uae_u16 hp = GETHPOS(); + hp += HPOS_OFFSET; - if (hp >= maxhpos) - { + if (hp >= maxhpos) { hp -= maxhpos; // vpos increases when hp==1, not when hp==0 - if (hp >= VPOS_INC_DELAY) - { + if (hp >= VPOS_INC_DELAY) { vp++; if (vp >= maxvpos + lof_store) vp = 0; } } - if (HPOS_OFFSET) - { + if (HPOS_OFFSET) { hp += 1; if (hp >= maxhpos) hp -= maxhpos; } vp <<= 8; + + if (hsyncdelay()) { + // fake continuously changing hpos in fastest possible modes + hp = oldhp % maxhpos; + oldhp++; + } + vp |= hp; return vp; } +static void REFPTR(uae_u16 v) +{ + /* + ECS Agnus: + + b15 8000: R 040 + b14 4000: R 020 + b13 2000: R 010 + b12 1000: R 008 + b11 0800: R 004 + b10 0400: R 002 + b09 0200: R 001 + b08 0100: C 080 + b07 0080: C 040 + b06 0040: C 020 + b05 0020: C 010 + b04 0010: C 008 + b03 0008: C 004 + b02 0004: C 002 C 100 + b01 0002: C 001 R 100 + b00 0001: R 080 + + */ + + refptr = v; + refptr_val = (v & 0xfe00) | ((v & 0x01fe) >> 1); + if (v & 1) { + refptr_val |= 0x80 << 9; + } + if (v & 2) { + refptr_val |= 1; + refptr_val |= 0x100 << 9; + } + if (v & 4) { + refptr_val |= 2; + refptr_val |= 0x100; + } +} + static int test_copper_dangerous(unsigned int address) { int addr = address & 0x01fe; - if (addr < ((copcon & 2) ? ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? 0 : 0x40) : 0x80)) - { + if (addr < ((copcon & 2) ? ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? 0 : 0x40) : 0x80)) { cop_state.state = COP_stop; copper_enabled_thisline = 0; unset_special(SPCFLAG_COPPER); @@ -3182,32 +4551,29 @@ static void immediate_copper(int num) int oldpos = 0; cop_state.state = COP_stop; + cop_state.vpos = vpos; cop_state.hpos = current_hpos() & ~1; cop_state.ip = num == 1 ? cop1lc : cop2lc; - while (pos < (maxvpos << 5)) - { + while (pos < (maxvpos << 5)) { if (oldpos > pos) pos = oldpos; if (!dmaen(DMA_COPPER)) break; - if (cop_state.ip >= currprefs.chipmem_size) + if (cop_state.ip >= currprefs.chipmem_size && cop_state.ip < currprefs.z3chipmem_start && cop_state.ip >= currprefs.z3chipmem_start + currprefs.z3chipmem_size) break; pos++; oldpos = pos; cop_state.i1 = chipmem_wget_indirect(cop_state.ip); cop_state.i2 = chipmem_wget_indirect(cop_state.ip + 2); cop_state.ip += 4; - if (!(cop_state.i1 & 1)) - { // move + if (!(cop_state.i1 & 1)) { // move cop_state.i1 &= 0x1fe; - if (cop_state.i1 == 0x88) - { + if (cop_state.i1 == 0x88) { cop_state.ip = cop1lc; continue; } - if (cop_state.i1 == 0x8a) - { + if (cop_state.i1 == 0x8a) { cop_state.ip = cop2lc; continue; } @@ -3215,8 +4581,7 @@ static void immediate_copper(int num) break; custom_wput_1(0, cop_state.i1, cop_state.i2, 0); } - else - { // wait or skip + else { // wait or skip if ((cop_state.i1 >> 8) > ((pos >> 5) & 0xff)) pos = (((pos >> 5) & 0x100) | ((cop_state.i1 >> 8)) << 5) | ((cop_state.i1 & 0xff) >> 3); if (cop_state.i1 >= 0xffdf && cop_state.i2 == 0xfffe) @@ -3229,19 +4594,16 @@ static void immediate_copper(int num) STATIC_INLINE void COP1LCH(uae_u16 v) { - cop1lc = (cop1lc & 0xffff) | (uae_u32(v) << 16); + cop1lc = (cop1lc & 0xffff) | ((uae_u32)v << 16); } - STATIC_INLINE void COP1LCL(uae_u16 v) { cop1lc = (cop1lc & ~0xffff) | (v & 0xfffe); } - STATIC_INLINE void COP2LCH(uae_u16 v) { - cop2lc = (cop2lc & 0xffff) | (uae_u32(v) << 16); + cop2lc = (cop2lc & 0xffff) | ((uae_u32)v << 16); } - STATIC_INLINE void COP2LCL(uae_u16 v) { cop2lc = (cop2lc & ~0xffff) | (v & 0xfffe); @@ -3253,43 +4615,34 @@ static void compute_spcflag_copper(int hpos); // normal COPJMP write: takes 2 more cycles static void COPJMP(int num, int vblank) { - int was_active = eventtab[ev_copper].active; int oldstrobe = cop_state.strobe; bool wasstopped = cop_state.state == COP_stop && !vblank; unset_special(SPCFLAG_COPPER); cop_state.ignore_next = 0; + if (!oldstrobe) cop_state.state_prev = cop_state.state; - if ((cop_state.state == COP_wait || cop_state.state == COP_waitforever) && !vblank) - { + if ((cop_state.state == COP_wait || cop_state.state == COP_waitforever) && !vblank && dmaen(DMA_COPPER)) { cop_state.state = COP_strobe_delay1x; } - else - { + else { cop_state.state = vblank ? COP_start_delay : (copper_access ? COP_strobe_delay1 : COP_strobe_extra); } + cop_state.vpos = vpos; cop_state.hpos = current_hpos() & ~1; copper_enabled_thisline = 0; cop_state.strobe = num; - eventtab[ev_copper].active = false; - - if (nocustom()) - { + if (nocustom()) { immediate_copper(num); return; } - if (was_active) - events_schedule(); - - if (dmaen(DMA_COPPER)) - { + if (dmaen(DMA_COPPER)) { compute_spcflag_copper(current_hpos()); } - else if (wasstopped || (oldstrobe > 0 && oldstrobe != num && cop_state.state_prev == COP_wait)) - { + else if (wasstopped || (oldstrobe > 0 && oldstrobe != num && cop_state.state_prev == COP_wait)) { /* dma disabled, copper idle and accessed both COPxJMPs -> copper stops! */ cop_state.state = COP_stop; } @@ -3300,6 +4653,31 @@ STATIC_INLINE void COPCON(uae_u16 a) copcon = a; } +static void check_copper_stop(void) +{ + if (copper_enabled_thisline < 0 && !((dmacon & DMA_COPPER) && (dmacon & DMA_MASTER))) { + copper_enabled_thisline = 0; + unset_special(SPCFLAG_COPPER); + } +} + +static void copper_stop(void) +{ + if (copper_enabled_thisline) { + // let MOVE to finish + switch (cop_state.state) + { + case COP_read2: + copper_enabled_thisline = -1; + break; + } + } + if (copper_enabled_thisline >= 0) { + copper_enabled_thisline = 0; + unset_special(SPCFLAG_COPPER); + } +} + static void DMACON(int hpos, uae_u16 v) { int oldcop, newcop; @@ -3314,28 +4692,23 @@ static void DMACON(int hpos, uae_u16 v) dmacon &= 0x07FF; changed = dmacon ^ oldcon; + oldcop = (oldcon & DMA_COPPER) && (oldcon & DMA_MASTER); newcop = (dmacon & DMA_COPPER) && (dmacon & DMA_MASTER); - if (oldcop != newcop) - { - eventtab[ev_copper].active = false; - - if (newcop && !oldcop) - { + if (oldcop != newcop) { + if (newcop && !oldcop) { compute_spcflag_copper(hpos); } - else if (!newcop) - { - copper_enabled_thisline = 0; - unset_special(SPCFLAG_COPPER); + else if (!newcop) { + copper_stop(); } } + if ((dmacon & DMA_BLITPRI) > (oldcon & DMA_BLITPRI) && bltstate != BLT_done) set_special(SPCFLAG_BLTNASTY); - if (dmaen(DMA_BLITTER) && bltstate == BLT_init) - { + if (dmaen(DMA_BLITTER) && bltstate == BLT_init) { blitter_check_start(); } @@ -3345,42 +4718,131 @@ static void DMACON(int hpos, uae_u16 v) if (changed & (DMA_MASTER | 0x0f)) audio_state_machine(); - if (changed & (DMA_MASTER | DMA_BITPLANE)) - { - line_cyclebased = vpos; - if (dmaen(DMA_BITPLANE)) - maybe_start_bpl_dma(hpos); + if (changed & (DMA_MASTER | DMA_BITPLANE)) { + SET_LINE_CYCLEBASED; + bitplane_maybe_start_hpos = hpos; } - - events_schedule(); } -int intlev() +static int irq_nmi; + +void NMI_delayed(void) { - uae_u16 imask = intreq & intena; - if (!(imask && (intena & 0x4000))) + irq_nmi = 1; +} + +static uae_u16 intreq_internal, intena_internal; + +int intlev(void) +{ + uae_u16 imask = intreq_internal & intena_internal; + if (irq_nmi) { + irq_nmi = 0; + return 7; + } + if (!(imask && (intena_internal & 0x4000))) return -1; - if (imask & (0x4000 | 0x2000)) // 13 14 + if (imask & (0x4000 | 0x2000)) // 13 14 return 6; - if (imask & (0x1000 | 0x0800)) // 11 12 + if (imask & (0x1000 | 0x0800)) // 11 12 return 5; - if (imask & (0x0400 | 0x0200 | 0x0100 | 0x0080)) // 7 8 9 10 + if (imask & (0x0400 | 0x0200 | 0x0100 | 0x0080)) // 7 8 9 10 return 4; - if (imask & (0x0040 | 0x0020 | 0x0010)) // 4 5 6 + if (imask & (0x0040 | 0x0020 | 0x0010)) // 4 5 6 return 3; - if (imask & 0x0008) // 3 + if (imask & 0x0008) // 3 return 2; - if (imask & (0x0001 | 0x0002 | 0x0004)) // 0 1 2 + if (imask & (0x0001 | 0x0002 | 0x0004)) // 0 1 2 return 1; return -1; } -STATIC_INLINE void rethink_intreq() +#define INT_PROCESSING_DELAY (3 * CYCLE_UNIT) +STATIC_INLINE int use_eventmode(uae_u16 v) { + if (currprefs.cpu_memory_cycle_exact && currprefs.cpu_model <= 68020) + return 1; + return 0; +} + + +void rethink_uae_int(void) +{ + bool irq2 = false; + bool irq6 = false; + + if (uae_int_requested) { + if (uae_int_requested & 0xff00) + irq6 = true; + if (uae_int_requested & 0x00ff) + irq2 = true; + } + + { + extern void bsdsock_fake_int_handler(void); + extern int volatile bsd_int_requested; + if (bsd_int_requested) + bsdsock_fake_int_handler(); + } + + uae_u16 mask = (irq6 ? 0x2000 : 0) | (irq2 ? 0x0008 : 0); + if (mask) + INTREQ_0(0x8000 | mask); +} + +static void rethink_intreq(void) +{ + //serial_check_irq(); //TODO rethink_cias(); +#ifdef A2065 + rethink_a2065(); +#endif +#ifdef A2091 + rethink_a2091(); +#endif +#ifdef CDTV + rethink_cdtv(); +#endif #ifdef CD32 rethink_akiko(); #endif + //rethink_gayle(); //TODO +} + +static void send_interrupt_do(uae_u32 v) +{ + INTREQ_0(0x8000 | (1 << v)); +} + +void send_interrupt(int num, int delay) +{ + if (use_eventmode(0x8000) && delay > 0) { + // always queue interrupt if it is active because + // next instruction in bad code can switch it off.. + // Absolute Inebriation / Virtual Dreams "big glenz" part + if (!(intreq & (1 << num)) || (intena & (1 << num))) + event2_newevent_xx(-1, delay, num, send_interrupt_do); + } + else { + send_interrupt_do(num); + } +} + +static int int_recursive; // yes, bad idea. + +static void send_intena_do(uae_u32 v) +{ + setclr(&intena_internal, v); + doint(); +} + +static void send_intreq_do(uae_u32 v) +{ + setclr(&intreq_internal, v); + int_recursive++; + rethink_intreq(); + int_recursive--; + doint(); } static void INTENA(uae_u16 v) @@ -3388,16 +4850,43 @@ static void INTENA(uae_u16 v) uae_u16 old = intena; setclr(&intena, v); - if (!(v & 0x8000) && old == intena) + if (!(v & 0x8000) && old == intena && intena == intena_internal) return; - if (v & 0x8000) - doint(); + //write_log (_T("%04x %04x %04x %04x\n"), intena, intena_internal, intreq, intreq_internal); + + if (use_eventmode(v)) { + if (old == intena && intena == intena_internal) + return; + event2_newevent_xx(-1, INT_PROCESSING_DELAY, v, send_intena_do); + } + else { + intena_internal = intena; + if (v & 0x8000) + doint(); + } +} + +static void INTREQ_nodelay(uae_u16 v) +{ + setclr(&intreq, v); + setclr(&intreq_internal, v); + doint(); } void INTREQ_f(uae_u16 v) { - setclr(&intreq, v); + if (use_eventmode(v)) { + setclr(&intreq, v); + send_intreq_do(v); + } + else { + uae_u16 old = intreq; + setclr(&intreq, v); + setclr(&intreq_internal, v); + //if ((old & 0x0800) && !(intreq & 0x0800)) + // serial_rbf_clear(); + } } bool INTREQ_0(uae_u16 v) @@ -3405,11 +4894,34 @@ bool INTREQ_0(uae_u16 v) uae_u16 old = intreq; setclr(&intreq, v); - if (old == intreq) + //if ((old & 0x0800) && !(intreq & 0x0800)) + // serial_rbf_clear(); + + if (int_recursive) { + // don't add new event if this call came from send_intreq_do/rethink + // and intreq didn't change. + // it wouldn't make any difference except to slow down everything + if (old == intreq) + return false; + } + + if (use_eventmode(v)) { + // don't bother to waste time for interrupt queuing if nothing changes + // but only if we are sure there is no other queued changes + if (old == intreq && intreq_internal == intreq) + return false; + event2_newevent_xx(-1, INT_PROCESSING_DELAY, v, send_intreq_do); return false; - if (v & 0x8000) - doint(); - return true; + } + else { + uae_u16 old2 = intreq_internal; + intreq_internal = intreq; + if (old == intreq && old2 == intreq_internal) + return false; + if (v & 0x8000) + doint(); + return true; + } } void INTREQ(uae_u16 data) @@ -3426,101 +4938,168 @@ static void ADKCON(int hpos, uae_u16 v) DISK_update_adkcon(hpos, v); setclr(&adkcon, v); audio_update_adkmasks(); + //if ((v >> 11) & 1) + // serial_uartbreak((adkcon >> 11) & 1); } static void BEAMCON0(uae_u16 v) { - if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) - { - if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE)) - v &= 0x20; - new_beamcon0 = v; + if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { + if (v != new_beamcon0) { + new_beamcon0 = v; + //if (v & ~0x20) { + //write_log(_T("warning: %04X written to BEAMCON0 PC=%08X\n"), v, M68K_GETPC); + //dumpsync(); + //} + } + calcdiw(); } } -static void varsync() +static void varsync(void) { if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) return; #ifdef PICASSO96 - if (picasso_on) - { + if (picasso_on && p96refresh_active) { + vtotal = p96refresh_active; return; } #endif if (!(beamcon0 & 0x80)) return; - vpos_count = 0; + varsync_changed = true; } +#ifdef PICASSO96 +void set_picasso_hack_rate(int hz) +{ + if (!picasso_on) + return; + vpos_count = 0; + p96refresh_active = int(maxvpos_stored * vblank_hz_stored / hz); + if (!currprefs.cs_ciaatod) + changed_prefs.cs_ciaatod = currprefs.cs_ciaatod = currprefs.ntscmode ? 2 : 1; + if (p96refresh_active > 0) { + new_beamcon0 |= 0x80; + } +} +#endif + + +/* "Dangerous" blitter D-channel: Writing to memory which is also currently +* read by bitplane DMA +*/ +static void dcheck_is_blit_dangerous(void) +{ + check_is_blit_dangerous(bplpt, bplcon0_planes, 50 << bplcon0_res); +} static void BPLxPTH(int hpos, uae_u16 v, int num) { decide_line(hpos); decide_fetch_safe(hpos); - bplpt[num] = (bplpt[num] & 0x0000ffff) | (uae_u32(v) << 16); -} + if (copper_access && is_bitplane_dma(hpos + 1) == num + 1) { + SET_LINE_CYCLEBASED; + return; + } + bplpt[num] = (bplpt[num] & 0x0000ffff) | ((uae_u32)v << 16); + bplptx[num] = (bplptx[num] & 0x0000ffff) | ((uae_u32)v << 16); + dcheck_is_blit_dangerous(); + //write_log (_T("%d:%d:BPL%dPTH %08X COP=%08x\n"), hpos, vpos, num, bplpt[num], cop_state.ip); +} static void BPLxPTL(int hpos, uae_u16 v, int num) { decide_line(hpos); decide_fetch_safe(hpos); - /* chipset feature: BPLxPTL write and next cycle doing DMA fetch using same pointer register -> - * this write goes nowhere (same happens with all DMA channels, not just BPL) - * (intro MoreNewStuffy by PlasmaForce) - */ + + /* chipset feature: + * BPLxPTL write and next cycle doing DMA fetch using same pointer register -> + * next DMA cycle uses old value. + * (Multiscroll / Cult) + * + * If following cycle is not BPL DMA: written value is lost + * + * last fetch block does not have this side-effect, probably due to modulo adds. + * Also it seems only plane 0 fetches have this feature (because of above reason!) + * (MoreNewStuffy / PlasmaForce) + */ /* only detect copper accesses to prevent too fast CPU mode glitches */ - if (copper_access && num == 0 && is_bitplane_dma(hpos + 1) == num + 1) - { + if (copper_access && is_bitplane_dma(hpos + 1) == num + 1) { + SET_LINE_CYCLEBASED; return; } bplpt[num] = (bplpt[num] & 0xffff0000) | (v & 0x0000fffe); + bplptx[num] = (bplptx[num] & 0xffff0000) | (v & 0x0000fffe); + dcheck_is_blit_dangerous(); + //write_log (_T("%d:%d:BPL%dPTL %08X COP=%08x\n"), hpos, vpos, num, bplpt[num], cop_state.ip); } static void BPLCON0_Denise(int hpos, uae_u16 v, bool immediate) { - if (! (currprefs.chipset_mask & CSMASK_ECS_DENISE)) + if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE)) v &= ~0x00F1; - else if (! (aga_mode)) + else if (!(currprefs.chipset_mask & CSMASK_AGA)) v &= ~0x00B0; v &= ~(0x0200 | 0x0100 | 0x0080 | 0x0020); +#if SPRBORDER + v |= 1; +#endif if (bplcon0d == v && !immediate) return; bplcon0dd = -1; - - if (immediate) - { + // fake unused 0x0080 bit as an EHB bit (see below) + if (isehb(bplcon0d, bplcon2)) + v |= 0x80; + if (immediate) { record_register_change(hpos, 0x100, v); } - else - { + else { record_register_change(hpos, 0x100, (bplcon0d & ~(0x800 | 0x400 | 0x80)) | (v & (0x0800 | 0x400 | 0x80 | 0x01))); } - bplcon0d = v; + bplcon0d = v & ~0x80; - if (currprefs.chipset_mask & CSMASK_ECS_DENISE) - { - decide_sprites(hpos); +#ifdef ECS_DENISE + if (currprefs.chipset_mask & CSMASK_ECS_DENISE) { + decide_sprites(-1, hpos); sprres = expand_sprres(v, bplcon3); } +#endif if (thisline_decision.plfleft < 0) update_denise(hpos); + else + update_denise_shifter_planes(hpos); } static void BPLCON0(int hpos, uae_u16 v) { - if (! (currprefs.chipset_mask & CSMASK_ECS_DENISE)) + if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE)) v &= ~0x00F1; - else if (! (aga_mode)) + else if (!(currprefs.chipset_mask & CSMASK_AGA)) v &= ~0x00B0; - v &= ~(0x0080 | 0x0020); + v &= ~0x0080; +#if SPRBORDER + v |= 1; +#endif if (bplcon0 == v) return; - line_cyclebased = vpos; + SET_LINE_CYCLEBASED; + decide_diw(hpos); + decide_line(hpos); + decide_fetch_safe(hpos); + + if (!issyncstopped()) { + vpos_previous = vpos; + hpos_previous = hpos; + } + + if (bplcon0 & 4) + bplcon0_interlace_seen = true; bplcon0 = v; @@ -3530,51 +5109,56 @@ static void BPLCON0(int hpos, uae_u16 v) BPLCON0_Denise(hpos, v, true); } -STATIC_INLINE void BPLCON1(int hpos, uae_u16 v) +static void BPLCON1(int hpos, uae_u16 v) { - if (!(aga_mode)) + if (!(currprefs.chipset_mask & CSMASK_AGA)) v &= 0xff; if (bplcon1 == v) return; - line_cyclebased = vpos; + SET_LINE_CYCLEBASED; decide_line(hpos); decide_fetch_safe(hpos); - bplcon1_hpos = hpos; + bplcon1_written = true; bplcon1 = v; + hack_shres_delay(hpos); } -STATIC_INLINE void BPLCON2(int hpos, uae_u16 v) +static void BPLCON2(int hpos, uae_u16 v) { - if (!(aga_mode)) + if (!(currprefs.chipset_mask & CSMASK_AGA)) v &= 0x7f; - if (bplcon2 == v) + if ((bplcon2 & 0x3fff) == (v & 0x3fff)) return; decide_line(hpos); bplcon2 = v; - record_register_change(hpos, 0x104, v); + record_register_change(hpos, 0x104, bplcon2); } -STATIC_INLINE void BPLCON3(int hpos, uae_u16 v) +#ifdef ECS_DENISE +static void BPLCON3(int hpos, uae_u16 v) { - if (! (currprefs.chipset_mask & CSMASK_ECS_DENISE)) + if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE)) return; - if (!(aga_mode)) - { + if (!(currprefs.chipset_mask & CSMASK_AGA)) { v &= 0x003f; v |= 0x0c00; } +#if SPRBORDER + v |= 2; +#endif if (bplcon3 == v) return; decide_line(hpos); - decide_sprites(hpos); + decide_sprites(-1, hpos); bplcon3 = v; sprres = expand_sprres(bplcon0, bplcon3); record_register_change(hpos, 0x106, v); } - -STATIC_INLINE void BPLCON4(int hpos, uae_u16 v) +#endif +#ifdef AGA +static void BPLCON4(int hpos, uae_u16 v) { - if (! (aga_mode)) + if (!(currprefs.chipset_mask & CSMASK_AGA)) return; if (bplcon4 == v) return; @@ -3582,56 +5166,70 @@ STATIC_INLINE void BPLCON4(int hpos, uae_u16 v) bplcon4 = v; record_register_change(hpos, 0x10c, v); } +#endif static void BPL1MOD(int hpos, uae_u16 v) { v &= ~1; - if (uae_s16(bpl1mod) == uae_s16(v)) - return; - decide_line(hpos); - decide_fetch_safe(hpos); - bpl1mod = v; + if (uae_s16(bpl1mod) != uae_s16(v)) { + decide_line(hpos); + decide_fetch_safe(hpos); + } + // write to BPLxMOD one cycle before + // BPL fetch that also adds modulo: + // Old BPLxMOD value is added. + if (1 && (is_bitplane_dma(hpos + 1) & 1)) { + dbpl1mod = v; + dbpl1mod_on = hpos + 1; + } + else { + bpl1mod = v; + dbpl1mod_on = 0; + } } static void BPL2MOD(int hpos, uae_u16 v) { v &= ~1; - if (uae_s16(bpl2mod) == uae_s16(v)) - return; - decide_line(hpos); - decide_fetch_safe(hpos); - bpl2mod = v; -} - -/* Needed in special OCS/ECS "7-plane" mode, - * also handles CPU generated bitplane data - */ -static void BPLxDAT(int hpos, int num, uae_u16 v) -{ - // only BPL0DAT access can do anything visible - if (num == 0 && hpos >= 8) - { + if (uae_s16(bpl2mod) != uae_s16(v)) { decide_line(hpos); decide_fetch_safe(hpos); } - bplxdat[num] = v; - if (num == 0 && hpos >= 8) - { + if (1 && (is_bitplane_dma(hpos + 1) & 2)) { + dbpl2mod = v; + dbpl2mod_on = hpos + 1; + } + else { + bpl2mod = v; + dbpl2mod_on = 0; + } +} + +/* Needed in special OCS/ECS "7-plane" mode, +* also handles CPU generated bitplane data +*/ +static void BPLxDAT(int hpos, int num, uae_u16 v) +{ + // only BPL1DAT access can do anything visible + if (num == 0 && hpos >= 8) { + decide_line(hpos); + decide_fetch_safe(hpos); + } + flush_display(fetchmode); + fetched[num] = v; + fetched_aga[num] = v; + if (num == 0 && hpos >= 8) { bpl1dat_written = true; bpl1dat_written_at_least_once = true; if (thisline_decision.plfleft < 0) - { - thisline_decision.plfleft = (hpos + 3) & ~3; reset_bpl_vars(); - compute_delay_offset(); - } - update_bpldats(hpos); + beginning_of_plane_block(hpos, fetchmode); } } static void DIWSTRT(int hpos, uae_u16 v) { - if (diwstrt == v && ! diwhigh_written) + if (diwstrt == v && !diwhigh_written) return; decide_diw(hpos); decide_line(hpos); @@ -3642,7 +5240,7 @@ static void DIWSTRT(int hpos, uae_u16 v) static void DIWSTOP(int hpos, uae_u16 v) { - if (diwstop == v && ! diwhigh_written) + if (diwstop == v && !diwhigh_written) return; decide_diw(hpos); decide_line(hpos); @@ -3655,7 +5253,7 @@ static void DIWHIGH(int hpos, uae_u16 v) { if (!(currprefs.chipset_mask & (CSMASK_ECS_DENISE | CSMASK_ECS_AGNUS))) return; - if (!(aga_mode)) + if (!(currprefs.chipset_mask & CSMASK_AGA)) v &= ~(0x0008 | 0x0010 | 0x1000 | 0x0800); v &= ~(0x8000 | 0x4000 | 0x0080 | 0x0040); if (diwhigh_written && diwhigh == v) @@ -3671,13 +5269,24 @@ static void DDFSTRT(int hpos, uae_u16 v) v &= 0xfe; if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) v &= 0xfc; - if (ddfstrt == v && hpos + 2 != ddfstrt) - return; - line_cyclebased = vpos; decide_line(hpos); - ddfstrt_old_hpos = hpos; + SET_LINE_CYCLEBASED; + // Move state back to passed_enable if this DDFSTRT write was done exactly when + // it would match and start bitplane DMA. + if (hpos == ddfstrt - DDF_OFFSET && plf_state == plf_passed_start && plf_start_hpos == hpos + DDF_OFFSET) { + plf_state = plf_passed_enable; + plf_start_hpos = maxhpos; + } ddfstrt = v; calcdiw(); + if (fetch_state != fetch_not_started) + estimate_last_fetch_cycle(hpos); + if (ddfstop > 0xD4 && (ddfstrt & 4) == 4) { + static int last_warned; + last_warned = (last_warned + 1) & 4095; + if (last_warned == 0) + write_log(_T("WARNING! Very strange DDF values (%x %x).\n"), ddfstrt, ddfstop); + } } static void DDFSTOP(int hpos, uae_u16 v) @@ -3685,49 +5294,74 @@ static void DDFSTOP(int hpos, uae_u16 v) v &= 0xfe; if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) v &= 0xfc; - if (ddfstop == v && hpos + 2 != ddfstop) - return; - line_cyclebased = vpos; decide_line(hpos); decide_fetch_safe(hpos); + SET_LINE_CYCLEBASED; + // DDFSTOP write when old DDFSTOP value match: old value matches normally. + // Works differently than DDFSTRT which is interesting. + if (hpos == v - DDF_OFFSET) { + if (plf_state == plf_passed_stop && plf_end_hpos == hpos + DDF_OFFSET) { + plf_state = plf_active; + plf_end_hpos = 256 + DDF_OFFSET; + // don't let one_fetch_cycle_0() to do this again + ddfstop_written_hpos = hpos; + } + } + else if (hpos == ddfstop - DDF_OFFSET) { + // if old ddfstop would have matched, emulate it here + if (plf_state == plf_active) { + plf_state = plf_passed_stop; + plf_end_hpos = hpos + DDF_OFFSET; + } + } ddfstop = v; calcdiw(); if (fetch_state != fetch_not_started) estimate_last_fetch_cycle(hpos); + if (ddfstop > 0xD4 && (ddfstrt & 4) == 4) { + static int last_warned; + if (last_warned == 0) + write_log(_T("WARNING! Very strange DDF values (%x).\n"), ddfstop); + last_warned = (last_warned + 1) & 4095; + } } static void FMODE(int hpos, uae_u16 v) { - if (!(aga_mode)) + if (!(currprefs.chipset_mask & CSMASK_AGA)) { + //if (currprefs.monitoremu) + // specialmonitor_store_fmode(vpos, hpos, v); v = 0; + } v &= 0xC00F; if (fmode == v) return; - line_cyclebased = vpos; - fmode = v; - sprite_width = GET_SPRITEWIDTH (fmode); + SET_LINE_CYCLEBASED; + fmode_saved = v; + set_chipset_mode(); bpldmainitdelay(hpos); } static void FNULL(uae_u16 v) { + } -static void BLTADAT(uae_u16 v) +static void BLTADAT(int hpos, uae_u16 v) { - maybe_blit(0); + maybe_blit(hpos, 0); blt_info.bltadat = v; } /* - * "Loading data shifts it immediately" says the HRM. Well, that may - * be true for BLTBDAT, but not for BLTADAT - it appears the A data must be - * loaded for every word so that AFWM and ALWM can be applied. - */ -static void BLTBDAT(uae_u16 v) +* "Loading data shifts it immediately" says the HRM. Well, that may +* be true for BLTBDAT, but not for BLTADAT - it appears the A data must be +* loaded for every word so that AFWM and ALWM can be applied. +*/ +static void BLTBDAT(int hpos, uae_u16 v) { - maybe_blit(0); + maybe_blit(hpos, 0); if (bltcon1 & 2) blt_info.bltbhold = v << (bltcon1 >> 12); @@ -3735,125 +5369,128 @@ static void BLTBDAT(uae_u16 v) blt_info.bltbhold = v >> (bltcon1 >> 12); blt_info.bltbdat = v; } +static void BLTCDAT(int hpos, uae_u16 v) { maybe_blit(hpos, 0); blt_info.bltcdat = v; reset_blit(0); } -STATIC_INLINE void BLTCDAT(uae_u16 v) -{ - maybe_blit(0); - blt_info.bltcdat = v; -} - -STATIC_INLINE void BLTAMOD(uae_u16 v) -{ - maybe_blit(1); - blt_info.bltamod = uae_s16(v & 0xFFFE); -} - -STATIC_INLINE void BLTBMOD(uae_u16 v) -{ - maybe_blit(1); - blt_info.bltbmod = uae_s16(v & 0xFFFE); -} - -STATIC_INLINE void BLTCMOD(uae_u16 v) -{ - maybe_blit(1); - blt_info.bltcmod = uae_s16(v & 0xFFFE); -} - -STATIC_INLINE void BLTDMOD(uae_u16 v) -{ - maybe_blit(1); - blt_info.bltdmod = uae_s16(v & 0xFFFE); -} - -STATIC_INLINE void BLTCON0(uae_u16 v) -{ - maybe_blit(2); - bltcon0 = v; - reset_blit(1); -} +static void BLTAMOD(int hpos, uae_u16 v) { maybe_blit(hpos, 1); blt_info.bltamod = uae_s16(v & 0xFFFE); reset_blit(0); } +static void BLTBMOD(int hpos, uae_u16 v) { maybe_blit(hpos, 1); blt_info.bltbmod = uae_s16(v & 0xFFFE); reset_blit(0); } +static void BLTCMOD(int hpos, uae_u16 v) { maybe_blit(hpos, 1); blt_info.bltcmod = uae_s16(v & 0xFFFE); reset_blit(0); } +static void BLTDMOD(int hpos, uae_u16 v) { maybe_blit(hpos, 1); blt_info.bltdmod = uae_s16(v & 0xFFFE); reset_blit(0); } +static void BLTCON0(int hpos, uae_u16 v) { maybe_blit(hpos, 2); bltcon0 = v; reset_blit(1); } /* The next category is "Most useless hardware register". - * And the winner is... */ -static void BLTCON0L(uae_u16 v) +* And the winner is... */ +static void BLTCON0L(int hpos, uae_u16 v) { - if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) return; // ei voittoa. - maybe_blit(2); - bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF); + maybe_blit(hpos, 2); bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF); reset_blit(1); } +static void BLTCON1(int hpos, uae_u16 v) { maybe_blit(hpos, 2); bltcon1 = v; reset_blit(2); } -STATIC_INLINE void BLTCON1(uae_u16 v) +static void BLTAFWM(int hpos, uae_u16 v) { maybe_blit(hpos, 2); blt_info.bltafwm = v; reset_blit(0); } +static void BLTALWM(int hpos, uae_u16 v) { maybe_blit(hpos, 2); blt_info.bltalwm = v; reset_blit(0); } + +static void BLTAPTH(int hpos, uae_u16 v) { - maybe_blit(2); - bltcon1 = v; - reset_blit(2); + maybe_blit(hpos, 0); + if (bltstate != BLT_done && currprefs.blitter_cycle_exact && currprefs.cpu_memory_cycle_exact) { + bltptx = (bltapt & 0xffff) | ((uae_u32)v << 16); + bltptxpos = hpos; + bltptxc = 1; + } + else { + bltapt = (bltapt & 0xffff) | ((uae_u32)v << 16); + } +} +static void BLTAPTL(int hpos, uae_u16 v) +{ + maybe_blit(hpos, 0); + if (bltstate != BLT_done && currprefs.blitter_cycle_exact && currprefs.cpu_memory_cycle_exact) { + bltptx = (bltapt & ~0xffff) | (v & 0xFFFE); + bltptxpos = hpos; + bltptxc = 1; + } + else { + bltapt = (bltapt & ~0xffff) | (v & 0xFFFE); + } +} +static void BLTBPTH(int hpos, uae_u16 v) +{ + maybe_blit(hpos, 0); + if (bltstate != BLT_done && currprefs.blitter_cycle_exact && currprefs.cpu_memory_cycle_exact) { + bltptx = (bltbpt & 0xffff) | ((uae_u32)v << 16); + bltptxpos = hpos; + bltptxc = 2; + } + else { + bltbpt = (bltbpt & 0xffff) | ((uae_u32)v << 16); + } +} +static void BLTBPTL(int hpos, uae_u16 v) +{ + maybe_blit(hpos, 0); + if (bltstate != BLT_done && currprefs.blitter_cycle_exact && currprefs.cpu_memory_cycle_exact) { + bltptx = (bltbpt & ~0xffff) | (v & 0xFFFE); + bltptxpos = hpos; + bltptxc = 2; + } + else { + bltbpt = (bltbpt & ~0xffff) | (v & 0xFFFE); + } +} +static void BLTCPTH(int hpos, uae_u16 v) +{ + maybe_blit(hpos, 0); + if (bltstate != BLT_done && currprefs.blitter_cycle_exact && currprefs.cpu_memory_cycle_exact) { + bltptx = (bltcpt & 0xffff) | ((uae_u32)v << 16); + bltptxpos = hpos; + bltptxc = 3; + } + else { + bltcpt = (bltcpt & 0xffff) | ((uae_u32)v << 16); + } +} +static void BLTCPTL(int hpos, uae_u16 v) +{ + maybe_blit(hpos, 0); + if (bltstate != BLT_done && currprefs.blitter_cycle_exact && currprefs.cpu_memory_cycle_exact) { + bltptx = (bltcpt & ~0xffff) | (v & 0xFFFE); + bltptxpos = hpos; + bltptxc = 3; + } + else { + bltcpt = (bltcpt & ~0xffff) | (v & 0xFFFE); + } +} +static void BLTDPTH(int hpos, uae_u16 v) +{ + maybe_blit(hpos, 0); + if (bltstate != BLT_done && currprefs.blitter_cycle_exact && currprefs.cpu_memory_cycle_exact) { + bltptx = (bltdpt & 0xffff) | ((uae_u32)v << 16); + bltptxpos = hpos; + bltptxc = 4; + } + else { + bltdpt = (bltdpt & 0xffff) | ((uae_u32)v << 16); + } +} +static void BLTDPTL(int hpos, uae_u16 v) +{ + maybe_blit(hpos, 0); + if (bltstate != BLT_done && currprefs.blitter_cycle_exact && currprefs.cpu_memory_cycle_exact) { + bltptx = (bltdpt & ~0xffff) | (v & 0xFFFE); + bltptxpos = hpos; + bltptxc = 4; + } + else { + bltdpt = (bltdpt & ~0xffff) | (v & 0xFFFE); + } } -STATIC_INLINE void BLTAFWM(uae_u16 v) +static void BLTSIZE(int hpos, uae_u16 v) { - maybe_blit(2); - blt_info.bltafwm = v; -} - -STATIC_INLINE void BLTALWM(uae_u16 v) -{ - maybe_blit(2); - blt_info.bltalwm = v; -} - -STATIC_INLINE void BLTAPTH(uae_u16 v) -{ - maybe_blit(0); - bltapt = (bltapt & 0xffff) | (uae_u32(v) << 16); -} - -STATIC_INLINE void BLTAPTL(uae_u16 v) -{ - maybe_blit(0); - bltapt = (bltapt & ~0xffff) | (v & 0xFFFE); -} - -STATIC_INLINE void BLTBPTH(uae_u16 v) -{ - maybe_blit(0); - bltbpt = (bltbpt & 0xffff) | (uae_u32(v) << 16); -} - -STATIC_INLINE void BLTBPTL(uae_u16 v) -{ - maybe_blit(0); - bltbpt = (bltbpt & ~0xffff) | (v & 0xFFFE); -} - -STATIC_INLINE void BLTCPTH(uae_u16 v) -{ - maybe_blit(0); - bltcpt = (bltcpt & 0xffff) | (uae_u32(v) << 16); -} - -STATIC_INLINE void BLTCPTL(uae_u16 v) -{ - maybe_blit(0); - bltcpt = (bltcpt & ~0xffff) | (v & 0xFFFE); -} - -STATIC_INLINE void BLTDPTH(uae_u16 v) -{ - maybe_blit(0); - bltdpt = (bltdpt & 0xffff) | (uae_u32(v) << 16); -} - -STATIC_INLINE void BLTDPTL(uae_u16 v) -{ - maybe_blit(0); - bltdpt = (bltdpt & ~0xffff) | (v & 0xFFFE); -} - -static void BLTSIZE(uae_u16 v) -{ - maybe_blit(0); + maybe_blit(hpos, 0); blt_info.vblitsize = v >> 6; blt_info.hblitsize = v & 0x3F; @@ -3861,34 +5498,34 @@ static void BLTSIZE(uae_u16 v) blt_info.vblitsize = 1024; if (!blt_info.hblitsize) blt_info.hblitsize = 64; - do_blitter(); + do_blitter(hpos, copper_access); + dcheck_is_blit_dangerous(); } -static void BLTSIZV(uae_u16 v) +static void BLTSIZV(int hpos, uae_u16 v) { - if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) return; - maybe_blit(0); + maybe_blit(hpos, 0); blt_info.vblitsize = v & 0x7FFF; } -static void BLTSIZH(uae_u16 v) +static void BLTSIZH(int hpos, uae_u16 v) { - if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) return; - maybe_blit(0); + maybe_blit(hpos, 0); blt_info.hblitsize = v & 0x7FF; if (!blt_info.vblitsize) blt_info.vblitsize = 0x8000; if (!blt_info.hblitsize) blt_info.hblitsize = 0x0800; - do_blitter(); + do_blitter(hpos, copper_access); } STATIC_INLINE void spr_arm(int num, int state) { - switch (state) - { + switch (state) { case 0: nr_armed -= spr[num].armed; spr[num].armed = 0; @@ -3900,9 +5537,9 @@ STATIC_INLINE void spr_arm(int num, int state) } } -STATIC_INLINE void sprstartstop(struct sprite* s) +STATIC_INLINE void sprstartstop(struct sprite *s) { - if (vpos < sprite_vblank_endline) + if (vpos < sprite_vblank_endline || cant_this_last_line() || s->ignoreverticaluntilnextline) return; if (vpos == s->vstart) s->dmastate = 1; @@ -3910,109 +5547,147 @@ STATIC_INLINE void sprstartstop(struct sprite* s) s->dmastate = 0; } -STATIC_INLINE void SPRxCTLPOS(int num) +static void SPRxCTLPOS(int num) { int sprxp; - struct sprite* s = &spr[num]; + struct sprite *s = &spr[num]; sprstartstop(s); sprxp = (sprpos[num] & 0xFF) * 2 + (sprctl[num] & 1); sprxp <<= sprite_buffer_res; /* Quite a bit salad in this register... */ - if (aga_mode) - { - if (sprite_buffer_res) - sprxp |= ((sprctl[num] >> 4) & 1); + if (false) { + } +#ifdef AGA + else if (currprefs.chipset_mask & CSMASK_AGA) { + sprxp |= ((sprctl[num] >> 3) & 3) >> (RES_MAX - sprite_buffer_res); s->dblscan = sprpos[num] & 0x80; } - else if (sprite_buffer_res && currprefs.chipset_mask & CSMASK_ECS_DENISE) - { - sprxp |= ((sprctl[num] >> 4) & 1); +#endif +#ifdef ECS_DENISE + else if (currprefs.chipset_mask & CSMASK_ECS_DENISE) { + sprxp |= ((sprctl[num] >> 3) & 2) >> (RES_MAX - sprite_buffer_res); } +#endif s->xpos = sprxp; s->vstart = sprpos[num] >> 8; s->vstart |= (sprctl[num] & 0x04) ? 0x0100 : 0; s->vstop = sprctl[num] >> 8; s->vstop |= (sprctl[num] & 0x02) ? 0x100 : 0; - if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) - { + if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { s->vstart |= (sprctl[num] & 0x40) ? 0x0200 : 0; s->vstop |= (sprctl[num] & 0x20) ? 0x0200 : 0; } sprstartstop(s); } -STATIC_INLINE void SPRxCTL_1(uae_u16 v, int num) +static void SPRxCTL_1(uae_u16 v, int num, int hpos) { - struct sprite* s = &spr[num]; + if (hpos >= maxhpos - 2 && sprctl[num] != v && vpos < maxvpos - 1) { + struct sprite *s = &spr[num]; + vpos++; + sprstartstop(s); + vpos--; + s->ignoreverticaluntilnextline = true; + sprite_ignoreverticaluntilnextline = true; + } sprctl[num] = v; spr_arm(num, 0); SPRxCTLPOS(num); } - -STATIC_INLINE void SPRxPOS_1(uae_u16 v, int num) +static void SPRxPOS_1(uae_u16 v, int num, int hpos) { - struct sprite* s = &spr[num]; + if (hpos >= maxhpos - 2 && sprpos[num] != v && vpos < maxvpos - 1) { + struct sprite *s = &spr[num]; + vpos++; + sprstartstop(s); + vpos--; + s->ignoreverticaluntilnextline = true; + sprite_ignoreverticaluntilnextline = true; + } sprpos[num] = v; SPRxCTLPOS(num); -} - -STATIC_INLINE void SPRxDATA_1(uae_u16 v, int num) + } +static void SPRxDATA_1(uae_u16 v, int num, int hpos) { sprdata[num][0] = v; +#ifdef AGA sprdata[num][1] = v; sprdata[num][2] = v; sprdata[num][3] = v; +#endif spr_arm(num, 1); } - -STATIC_INLINE void SPRxDATB_1(uae_u16 v, int num) +static void SPRxDATB_1(uae_u16 v, int num, int hpos) { sprdatb[num][0] = v; +#ifdef AGA sprdatb[num][1] = v; sprdatb[num][2] = v; sprdatb[num][3] = v; +#endif } -STATIC_INLINE void SPRxDATA(int hpos, uae_u16 v, int num) +/* +SPRxDATA and SPRxDATB is moved to shift register when SPRxPOS matches. + +When copper writes to SPRxDATx exactly when SPRxPOS matches: +- If sprite low x bit (SPRCTL bit 0) is not set, shift register copy +is done first (previously loaded SPRxDATx value is shown) and then +new SPRxDATx gets stored for future use. +- If sprite low x bit is set, new SPRxDATx is stored, then SPRxPOS +matches and value written to SPRxDATx is visible. + +- Writing to SPRxPOS when SPRxPOS matches: shift register +copy is always done first, then new SPRxPOS value is stored +for future use. (SPRxCTL not tested) +*/ + +static void SPRxDATA(int hpos, uae_u16 v, int num) { - decide_sprites(hpos); - SPRxDATA_1(v, num); + decide_sprites(-1, hpos, true, false); + SPRxDATA_1(v, num, hpos); +} +static void SPRxDATB(int hpos, uae_u16 v, int num) +{ + decide_sprites(-1, hpos, true, false); + SPRxDATB_1(v, num, hpos); } -STATIC_INLINE void SPRxDATB(int hpos, uae_u16 v, int num) +static void SPRxCTL(int hpos, uae_u16 v, int num) { - decide_sprites(hpos); - SPRxDATB_1(v, num); + decide_sprites(-1, hpos); + SPRxCTL_1(v, num, hpos); } - -STATIC_INLINE void SPRxCTL(int hpos, uae_u16 v, int num) +static void SPRxPOS(int hpos, uae_u16 v, int num) { - decide_sprites(hpos); - SPRxCTL_1(v, num); -} + struct sprite *s = &spr[num]; + int oldvpos; -STATIC_INLINE void SPRxPOS(int hpos, uae_u16 v, int num) -{ - decide_sprites(hpos); - SPRxPOS_1(v, num); + decide_sprites(-1, hpos); + oldvpos = s->vstart; + SPRxPOS_1(v, num, hpos); + // Superfrog flashing intro bees fix. + // if SPRxPOS is written one cycle before sprite's first DMA slot and sprite's vstart matches after + // SPRxPOS write, current line's DMA slot's stay idle. DMA decision seems to be done 4 cycles earlier. + if (hpos >= SPR0_HPOS + num * 4 - 4 && hpos <= SPR0_HPOS + num * 4 - 1 && oldvpos != vpos) { + s->ptxvpos2 = vpos; + s->ptxhpos2 = hpos + 4; + } } static void SPRxPTH(int hpos, uae_u16 v, int num) { - decide_sprites(hpos); - if (hpos - 1 != MAXHPOS) - { + decide_sprites(-1, hpos); + if (hpos - 1 != spr[num].ptxhpos) { spr[num].pt &= 0xffff; - spr[num].pt |= uae_u32(v) << 16; + spr[num].pt |= (uae_u32)v << 16; } } - static void SPRxPTL(int hpos, uae_u16 v, int num) { - decide_sprites(hpos); - if (hpos - 1 != MAXHPOS) - { + decide_sprites(-1, hpos); + if (hpos - 1 != spr[num].ptxhpos) { spr[num].pt &= ~0xffff; spr[num].pt |= v & ~1; } @@ -4027,48 +5702,93 @@ static void CLXCON(uae_u16 v) static void CLXCON2(uae_u16 v) { - if (!(aga_mode)) + if (!(currprefs.chipset_mask & CSMASK_AGA)) return; clxcon2 = v; clxcon_bpl_enable |= v & (0x40 | 0x80); clxcon_bpl_match |= (v & (0x01 | 0x02)) << 6; } -static uae_u16 CLXDAT() +static uae_u16 CLXDAT(void) { uae_u16 v = clxdat | 0x8000; clxdat = 0; return v; } +#ifdef AGA + +//void dump_aga_custom(void) +//{ +// int c1, c2, c3, c4; +// uae_u32 rgb1, rgb2, rgb3, rgb4; +// +// for (c1 = 0; c1 < 64; c1++) { +// c2 = c1 + 64; +// c3 = c2 + 64; +// c4 = c3 + 64; +// rgb1 = current_colors.color_regs_aga[c1]; +// rgb2 = current_colors.color_regs_aga[c2]; +// rgb3 = current_colors.color_regs_aga[c3]; +// rgb4 = current_colors.color_regs_aga[c4]; +// write_log(_T("%3d %08X %3d %08X %3d %08X %3d %08X\n"), +// c1, rgb1, c2, rgb2, c3, rgb3, c4, rgb4); +// } +//} + static uae_u16 COLOR_READ(int num) { int cr, cg, cb, colreg; uae_u16 cval; - if (!(aga_mode) || !(bplcon2 & 0x0100)) + if (!(currprefs.chipset_mask & CSMASK_AGA) || !(bplcon2 & 0x0100)) return 0xffff; colreg = ((bplcon3 >> 13) & 7) * 32 + num; - cr = current_colors.color_regs_aga[colreg] >> 16; + cr = (current_colors.color_regs_aga[colreg] >> 16) & 0xFF; cg = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF; cb = current_colors.color_regs_aga[colreg] & 0xFF; - if (bplcon3 & 0x200) - { + if (bplcon3 & 0x200) { cval = ((cr & 15) << 8) | ((cg & 15) << 4) | ((cb & 15) << 0); } - else - { + else { cval = ((cr >> 4) << 8) | ((cg >> 4) << 4) | ((cb >> 4) << 0); + if (color_regs_genlock[num]) + cval |= 0x8000; } return cval; } +#endif + +static void checkautoscalecol0(void) +{ + if (!copper_access) + return; + if (vpos < 20) + return; + if (isbrdblank(-1, bplcon0, bplcon3)) + return; + // autoscale if copper changes COLOR00 on top or bottom of screen + if (vpos >= minfirstline) { + int vpos2 = autoscale_bordercolors ? minfirstline : vpos; + if (first_planes_vpos == 0) + first_planes_vpos = vpos2 - 2; + if (plffirstline_total == current_maxvpos()) + plffirstline_total = vpos2 - 2; + if (vpos2 > last_planes_vpos || vpos2 > plflastline_total) + plflastline_total = last_planes_vpos = vpos2 + 3; + autoscale_bordercolors = 0; + } + else { + autoscale_bordercolors++; + } +} static void COLOR_WRITE(int hpos, uae_u16 v, int num) { - v &= 0xFFF; - if (aga_mode) - { + bool colzero = false; +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) { int r, g, b; int cr, cg, cb; int colreg; @@ -4082,46 +5802,59 @@ static void COLOR_WRITE(int hpos, uae_u16 v, int num) r = (v & 0xF00) >> 8; g = (v & 0xF0) >> 4; b = (v & 0xF) >> 0; - cr = current_colors.color_regs_aga[colreg] >> 16; + cr = (current_colors.color_regs_aga[colreg] >> 16) & 0xFF; cg = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF; cb = current_colors.color_regs_aga[colreg] & 0xFF; - if (bplcon3 & 0x200) - { - cr &= 0xF0; - cr |= r; - cg &= 0xF0; - cg |= g; - cb &= 0xF0; - cb |= b; + if (bplcon3 & 0x200) { + cr &= 0xF0; cr |= r; + cg &= 0xF0; cg |= g; + cb &= 0xF0; cb |= b; } - else - { + else { cr = r + (r << 4); cg = g + (g << 4); cb = b + (b << 4); + color_regs_genlock[colreg] = v >> 15; } - cval = (cr << 16) | (cg << 8) | cb; + cval = (cr << 16) | (cg << 8) | cb | (color_regs_genlock[colreg] ? 0x80000000 : 0); + if (cval && colreg == 0) + colzero = true; + if (cval == current_colors.color_regs_aga[colreg]) return; + if (colreg == 0) + checkautoscalecol0(); + /* Call this with the old table still intact. */ record_color_change(hpos, colreg, cval); remembered_color_entry = -1; current_colors.color_regs_aga[colreg] = cval; - current_colors.acolors[colreg] = CONVERT_RGB(cval); + current_colors.acolors[colreg] = getxcolor(cval); + } - else - { + else { +#endif + v &= 0x8fff; + if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE)) + v &= 0xfff; + color_regs_genlock[num] = v >> 15; + if (num && v == 0) + colzero = true; if (current_colors.color_regs_ecs[num] == v) return; + if (num == 0) + checkautoscalecol0(); /* Call this with the old table still intact. */ record_color_change(hpos, num, v); remembered_color_entry = -1; current_colors.color_regs_ecs[num] = v; - current_colors.acolors[num] = xcolors[v]; + current_colors.acolors[num] = getxcolor(v); +#ifdef AGA } +#endif } /* The copper code. The biggest nightmare in the whole emulator. @@ -4163,192 +5896,61 @@ static void COLOR_WRITE(int hpos, uae_u16 v, int num) /* Determine which cycles are available for the copper in a display * with a agiven number of planes. */ -STATIC_INLINE int copper_cant_read(int hpos) +STATIC_INLINE int copper_cant_read2(int hpos, int alloc) { if (hpos + 1 >= maxhpos) // first refresh slot return 1; - if ((hpos == maxhpos - 3) && (maxhpos & 1)) - { + if ((hpos == maxhpos - 3) && (maxhpos & 1) && alloc >= 0) { + if (alloc) { + alloc_cycle(hpos, CYCLE_COPPER); + } return -1; } - return is_bitplane_dma(hpos); + return is_bitplane_dma_inline(hpos); } - -/* The future, Conan? - We try to look ahead in the copper list to avoid doing continuous calls - to updat_copper (which is what happens when SPCFLAG_COPPER is set). If - we find that the same effect can be achieved by setting a delayed event - and then doing multiple copper insns in one batch, we can get a massive - speedup. - - We don't try to be precise here. All copper reads take exactly 2 cycles, - the effect of bitplane contention is ignored. Trying to get it exactly - right would be much more complex and as such carry a huge risk of getting - it subtly wrong; and it would also be more expensive - we want this code - to be fast. */ - -static void predict_copper() +static int copper_cant_read(int hpos, int alloc) { - uaecptr ip = cop_state.ip; - unsigned int c_hpos = cop_state.hpos; - enum copper_states state = cop_state.state; - unsigned int w1, w2, cycle_count; - unsigned int modified = REGTYPE_FORCE; - - switch (state) - { - case COP_read1: - break; - - case COP_read2: - w1 = cop_state.i1; - w2 = chipmem_wget_indirect(ip); - if (w1 & 1) - { - if (w2 & 1) - return; // SKIP - state = COP_wait; // WAIT - c_hpos += 4; - } - else - { // MOVE - modified |= regtypes[w1 & 0x1FE]; - state = COP_read1; - c_hpos += 2; - } - ip += 2; - break; - - case COP_strobe_delay2: - case COP_strobe_delay2x: - case COP_start_delay: - c_hpos += 2; - state = COP_read1; - break; - - case COP_strobe_extra: - c_hpos += 6; - state = COP_read1; - break; - - case COP_strobe_delay1: - case COP_strobe_delay1x: - c_hpos += 4; - state = COP_read1; - break; - - case COP_stop: - case COP_waitforever: - case COP_bltwait: - case COP_skip_in2: - case COP_skip1: - return; - - case COP_wait_in2: - c_hpos += 2; - case COP_wait1: - w1 = cop_state.i1; - w2 = cop_state.i2; - state = COP_wait; - break; - - case COP_wait: - w1 = cop_state.i1; - w2 = cop_state.i2; - break; - - default: - return; - } - /* Only needed for COP_wait, but let's shut up the compiler. */ - cop_state.first_sync = c_hpos; - - while (c_hpos + 1 < maxhpos) - { - if (state == COP_read1) - { - w1 = chipmem_wget_indirect(ip); - if (w1 & 1) - { - w2 = chipmem_wget_indirect(ip + 2); - if (w2 & 1) - break; // SKIP - state = COP_wait; // WAIT - c_hpos += 6; - } - else - { // MOVE - modified |= regtypes[w1 & 0x1FE]; - c_hpos += 4; - } - ip += 4; - } - else - { // state is COP_wait - if ((w2 & 0xFE) != 0xFE) - break; - else - { - unsigned int vcmp = (w1 & (w2 | 0x8000)) >> 8; - unsigned int hcmp = (w1 & 0xFE); - - unsigned int vp = vpos & (((w2 >> 8) & 0x7F) | 0x80); - if (vp < vcmp) - { - /* Whee. We can wait until the end of the line! */ - c_hpos = maxhpos; - } - else if (vp > vcmp || hcmp <= c_hpos) - { - state = COP_read1; - /* minimum wakeup time */ - c_hpos += 2; - } - else - { - state = COP_read1; - c_hpos = hcmp + 2; - } - /* If this is the current instruction, remember that we don't - need to sync CPU and copper anytime soon. */ - if (cop_state.ip == ip) - { - cop_state.first_sync = c_hpos; - } - } - } - } - - cycle_count = c_hpos - cop_state.hpos; - if (cycle_count >= 8) - { - cop_state.regtypes_modified = modified; - unset_special(SPCFLAG_COPPER); - eventtab[ev_copper].active = true; - eventtab[ev_copper].evtime = get_cycles() + cycle_count * CYCLE_UNIT; - events_schedule(); - } + int cant = copper_cant_read2(hpos, alloc); +#ifdef DEBUGGER + if (cant && debug_dma) + record_dma_event(DMA_EVENT_COPPERWANTED, hpos, vpos); +#endif + return cant; } -STATIC_INLINE int custom_wput_copper(int hpos, uaecptr addr, uae_u32 value, int noget) +static int custom_wput_copper(int hpos, uaecptr addr, uae_u32 value, int noget) { int v; + hpos += hack_delay_shift; + //value = debug_wputpeekdma_chipset(0xdff000 + addr, value, MW_MASK_COPPER, 0x08c); copper_access = 1; v = custom_wput_1(hpos, addr, value, noget); copper_access = 0; return v; } +//static void dump_copper(const TCHAR *error, int until_hpos) +//{ +// write_log(_T("\n")); +// write_log(_T("%s: vpos=%d until_hpos=%d vp=%d\n"), +// error, vpos, until_hpos, vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80)); +// write_log(_T("cvcmp=%d chcmp=%d chpos=%d cvpos=%d ci1=%04X ci2=%04X\n"), +// cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos, cop_state.saved_i1, cop_state.saved_i2); +// write_log(_T("cstate=%d ip=%x SPCFLAGS=%x iscline=%d\n"), +// cop_state.state, cop_state.ip, regs.spcflags, copper_enabled_thisline); +// write_log(_T("\n")); +//} + // "emulate" chip internal delays, not the right place but fast and 99.9% programs // use only copper to write BPLCON1 etc.. (exception is HulkaMania/TSP..) // this table should be filled with zeros and done somewhere else.. -static int customdelay[] = { +static int customdelay[]= { 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 32 0x00 - 0x3e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x40 - 0x5e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x60 - 0x7e */ - 0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0, /* 0x80 - 0x9e */ + 0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0, /* 0x80 - 0x9e */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 32 0xa0 - 0xde */ /* BPLxPTH/BPLxPTL */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */ @@ -4366,20 +5968,25 @@ static int customdelay[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; +/* +CPU write COPJMP wakeup sequence when copper is waiting: +- Idle cycle (can be used by other DMA channel) +- Read word from current copper pointer (next word after wait instruction) to 1FE +This cycle can conflict with blitter DMA. +Normal copper cycles resume +- Write word from new copper pointer to 8C +*/ + static void update_copper(int until_hpos) { - int vp = vpos & (((cop_state.i2 >> 8) & 0x7F) | 0x80); + int vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); int c_hpos = cop_state.hpos; if (nocustom()) - { - eventtab[ev_copper].active = false; return; - } - if (cop_state.state == COP_wait && vp < cop_state.vcmp) - { - eventtab[ev_copper].active = false; + if (cop_state.state == COP_wait && vp < cop_state.vcmp) { + //dump_copper(_T("error2"), until_hpos); copper_enabled_thisline = 0; cop_state.state = COP_stop; unset_special(SPCFLAG_COPPER); @@ -4392,8 +5999,7 @@ static void update_copper(int until_hpos) if (until_hpos > (maxhpos & ~1)) until_hpos = maxhpos & ~1; - for (;;) - { + for (;;) { int old_hpos = c_hpos; int hp; @@ -4402,14 +6008,14 @@ static void update_copper(int until_hpos) /* So we know about the fetch state. */ decide_line(c_hpos); - decide_fetch_safe(c_hpos); + // bitplane only, don't want blitter to steal our cycles. + decide_fetch(c_hpos); - if (cop_state.movedelay) - { // cop_state.movedelay is 0 or 1 - cop_state.movedelay = 0; - custom_wput_copper(c_hpos, cop_state.moveaddr, cop_state.movedata, 0); - if (! copper_enabled_thisline) - goto out; + if (cop_state.movedelay > 0) { + cop_state.movedelay--; + if (cop_state.movedelay == 0) { + custom_wput_copper(c_hpos, cop_state.moveaddr, cop_state.movedata, 0); + } } if ((c_hpos == maxhpos - 3) && (maxhpos & 1)) @@ -4420,12 +6026,12 @@ static void update_copper(int until_hpos) switch (cop_state.state) { case COP_wait_in2: - if (copper_cant_read(old_hpos)) + if (copper_cant_read(old_hpos, 0)) continue; cop_state.state = COP_wait1; break; case COP_skip_in2: - if (copper_cant_read(old_hpos)) + if (copper_cant_read(old_hpos, 0)) continue; cop_state.state = COP_skip1; break; @@ -4437,10 +6043,12 @@ static void update_copper(int until_hpos) case COP_strobe_delay1: // First cycle after COPJMP is just like normal first read cycle // Cycle is used and needs to be free. - if (copper_cant_read(old_hpos)) + if (copper_cant_read(old_hpos, 1)) continue; - if (old_hpos == maxhpos - 2) - { +#ifdef CPUEMU_13 + alloc_cycle(old_hpos, CYCLE_COPPER); +#endif + if (old_hpos == maxhpos - 2) { // if COP_strobe_delay2 would cross scanlines (positioned immediately // after first strobe/refresh slot) it will disappear! cop_state.state = COP_read1; @@ -4450,8 +6058,7 @@ static void update_copper(int until_hpos) cop_state.ip = cop2lc; cop_state.strobe = 0; } - else - { + else { cop_state.state = COP_strobe_delay2; cop_state.ip += 2; } @@ -4460,6 +6067,17 @@ static void update_copper(int until_hpos) // Second cycle after COPJMP. This is the strange one. // This cycle does not need to be free // But it still gets allocated by copper if it is free = CPU and blitter can't use it. +#ifdef CPUEMU_13 + if (!copper_cant_read(old_hpos, 0)) { + alloc_cycle(old_hpos, CYCLE_COPPER); +#ifdef DEBUGGER + if (debug_dma) + record_dma(0x1fe, chipmem_wget_indirect(cop_state.ip), cop_state.ip, old_hpos, vpos, DMARECORD_COPPER); + if (memwatch_enabled) + debug_wgetpeekdma_chipram(cop_state.ip, chipmem_wget_indirect(cop_state.ip), MW_MASK_COPPER, 0x1fe); +#endif + } +#endif cop_state.state = COP_read1; // Next cycle finally reads from new pointer if (cop_state.strobe == 1) @@ -4470,16 +6088,18 @@ static void update_copper(int until_hpos) break; case COP_strobe_delay1x: - // First cycle after COPJMP and Copper was waiting. This is the buggy one. - // Cycle can be free and copper won't allocate it. - // If Blitter uses this cycle = Copper's address gets copied blitter DMA pointer.. + // First cycle after COPJMP and Copper was waiting. cop_state.state = COP_strobe_delay2x; break; case COP_strobe_delay2x: - // Second cycle fetches following word and tosses it away. Must be free cycle - // but is not allocated, blitter or cpu can still use it. - if (copper_cant_read(old_hpos)) + // Second cycle fetches following word and tosses it away. + // Cycle can be free and copper won't allocate it. + // If Blitter uses this cycle = Copper's PC gets copied to blitter DMA pointer.. + if (copper_cant_read(old_hpos, 1)) continue; +#ifdef CPUEMU_13 + cycle_line[old_hpos] |= CYCLE_COPPER_SPECIAL; +#endif cop_state.state = COP_read1; // Next cycle finally reads from new pointer if (cop_state.strobe == 1) @@ -4491,93 +6111,100 @@ static void update_copper(int until_hpos) case COP_start_delay: // cycle after vblank strobe fetches word from old pointer first - if (copper_cant_read(old_hpos)) + if (copper_cant_read(old_hpos, 1)) continue; cop_state.state = COP_read1; - cop_state.i1 = chipmem_wget_indirect(cop_state.ip); + cop_state.i1 = last_custom_value1 = chipmem_wget_indirect(cop_state.ip); +#ifdef CPUEMU_13 + alloc_cycle(old_hpos, CYCLE_COPPER); +#endif cop_state.ip = cop1lc; break; case COP_read1: - if (copper_cant_read(old_hpos)) + if (copper_cant_read(old_hpos, 1)) continue; - cop_state.i1 = chipmem_wget_indirect(cop_state.ip); + cop_state.i1 = last_custom_value1 = chipmem_wget_indirect(cop_state.ip); +#ifdef CPUEMU_13 + alloc_cycle(old_hpos, CYCLE_COPPER); +#endif cop_state.ip += 2; cop_state.state = COP_read2; break; case COP_read2: - if (copper_cant_read(old_hpos)) + if (copper_cant_read(old_hpos, 1)) continue; - cop_state.i2 = chipmem_wget_indirect(cop_state.ip); + cop_state.i2 = last_custom_value1 = chipmem_wget_indirect(cop_state.ip); +#ifdef CPUEMU_13 + alloc_cycle(old_hpos, CYCLE_COPPER); +#endif cop_state.ip += 2; + cop_state.saved_i1 = cop_state.i1; + cop_state.saved_i2 = cop_state.i2; + cop_state.saved_ip = cop_state.ip; - if (cop_state.i1 & 1) - { // WAIT or SKIP + if (cop_state.i1 & 1) { // WAIT or SKIP cop_state.ignore_next = 0; if (cop_state.i2 & 1) cop_state.state = COP_skip_in2; else cop_state.state = COP_wait_in2; + } - else - { // MOVE + else { // MOVE + unsigned int reg = cop_state.i1 & 0x1FE; uae_u16 data = cop_state.i2; cop_state.state = COP_read1; - test_copper_dangerous(reg); - if (! copper_enabled_thisline) - goto out; // was "dangerous" register -> copper stopped - if (cop_state.ignore_next) - { - reg = 0x1fe; - cop_state.ignore_next = 0; - } - if (reg == 0x88) - { + test_copper_dangerous(reg); + if (!copper_enabled_thisline) + goto out; // was "dangerous" register -> copper stopped + + if (cop_state.ignore_next) + reg = 0x1fe; + + if (reg == 0x88) { cop_state.strobe = 1; cop_state.state = COP_strobe_delay1; } - else if (reg == 0x8a) - { + else if (reg == 0x8a) { cop_state.strobe = 2; cop_state.state = COP_strobe_delay1; } - else - { + else { + // FIX: all copper writes happen 1 cycle later than CPU writes - if (customdelay[reg / 2]) - { + if (customdelay[reg / 2]) { cop_state.moveaddr = reg; cop_state.movedata = data; - cop_state.movedelay = 1; + cop_state.movedelay = customdelay[cop_state.moveaddr / 2]; } - else - { + else { custom_wput_copper(old_hpos, reg, data, 0); } } + cop_state.ignore_next = 0; } + check_copper_stop(); break; case COP_wait1: cop_state.state = COP_wait; - cop_state.vcmp = (cop_state.i1 & (cop_state.i2 | 0x8000)) >> 8; - cop_state.hcmp = (cop_state.i1 & cop_state.i2 & 0xFE); + cop_state.vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; + cop_state.hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xFE); - vp = vpos & (((cop_state.i2 >> 8) & 0x7F) | 0x80); + vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); - if (cop_state.i1 == 0xFFFF && cop_state.i2 == 0xFFFE) - { + if (cop_state.saved_i1 == 0xFFFF && cop_state.saved_i2 == 0xFFFE) { cop_state.state = COP_waitforever; copper_enabled_thisline = 0; unset_special(SPCFLAG_COPPER); goto out; } - if (vp < cop_state.vcmp) - { + if (vp < cop_state.vcmp) { copper_enabled_thisline = 0; unset_special(SPCFLAG_COPPER); goto out; @@ -4585,59 +6212,58 @@ static void update_copper(int until_hpos) /* fall through */ case COP_wait: - { - int ch_comp = c_hpos; - if (ch_comp & 1) - ch_comp = 0; - if (copper_cant_read(old_hpos)) - continue; + { + int ch_comp = c_hpos; + if (ch_comp & 1) + ch_comp = 0; - hp = ch_comp & (cop_state.i2 & 0xFE); - if (vp == cop_state.vcmp && hp < cop_state.hcmp) - { - /* Position not reached yet. */ - break; + /* First handle possible blitter wait + * Must be before following free cycle check + */ + if ((cop_state.saved_i2 & 0x8000) == 0) { + decide_blitter(old_hpos); + if (bltstate != BLT_done) { + /* We need to wait for the blitter. */ + cop_state.state = COP_bltwait; + copper_enabled_thisline = 0; + unset_special(SPCFLAG_COPPER); + goto out; } - - /* Now we know that the comparisons were successful. We might still - have to wait for the blitter though. */ - if ((cop_state.i2 & 0x8000) == 0) - { - if (bltstate != BLT_done) - { - /* We need to wait for the blitter. */ - cop_state.state = COP_bltwait; - copper_enabled_thisline = 0; - unset_special(SPCFLAG_COPPER); - goto out; - } - } - - cop_state.state = COP_read1; } - break; + + if (copper_cant_read(old_hpos, 0)) + continue; + + hp = ch_comp & (cop_state.saved_i2 & 0xFE); + if (vp == cop_state.vcmp && hp < cop_state.hcmp) + break; + + cop_state.state = COP_read1; + } + break; case COP_skip1: - { - unsigned int vcmp, hcmp, vp1, hp1; - - if (c_hpos >= (maxhpos & ~1) || (c_hpos & 1)) - break; - if (copper_cant_read(old_hpos)) - continue; - - vcmp = (cop_state.i1 & (cop_state.i2 | 0x8000)) >> 8; - hcmp = (cop_state.i1 & cop_state.i2 & 0xFE); - vp1 = vpos & (((cop_state.i2 >> 8) & 0x7F) | 0x80); - hp1 = c_hpos & (cop_state.i2 & 0xFE); - - if ((vp1 > vcmp || (vp1 == vcmp && hp1 >= hcmp)) && ((cop_state.i2 & 0x8000) != 0 || bltstate == BLT_done)) - cop_state.ignore_next = 1; - - cop_state.state = COP_read1; + { + unsigned int vcmp, hcmp, vp1, hp1; + if (c_hpos >= (maxhpos & ~1) || (c_hpos & 1)) break; - } + + if (copper_cant_read(old_hpos, 0)) + continue; + + vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; + hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xFE); + vp1 = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); + hp1 = c_hpos & (cop_state.saved_i2 & 0xFE); + + if ((vp1 > vcmp || (vp1 == vcmp && hp1 >= hcmp)) && ((cop_state.saved_i2 & 0x8000) != 0 || bltstate == BLT_done)) + cop_state.ignore_next = 1; + + cop_state.state = COP_read1; + + break; + } default: break; } @@ -4646,7 +6272,6 @@ static void update_copper(int until_hpos) out: cop_state.hpos = c_hpos; last_copper_hpos = until_hpos; - } static void compute_spcflag_copper(int hpos) @@ -4658,20 +6283,18 @@ static void compute_spcflag_copper(int hpos) if (!dmaen(DMA_COPPER) || cop_state.state == COP_stop || cop_state.state == COP_waitforever || cop_state.state == COP_bltwait || nocustom()) return; - if (cop_state.state == COP_wait) - { - int vp = vpos & (((cop_state.i2 >> 8) & 0x7F) | 0x80); + if (cop_state.state == COP_wait) { + int vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); if (vp < cop_state.vcmp) return; } // do not use past cycles if starting for the first time in this line // (write to DMACON for example) hpos+1 for long lines - if (!wasenabled && cop_state.hpos < hpos && hpos < maxhpos) - { + if (!wasenabled && cop_state.hpos < hpos && hpos < maxhpos) { hpos = (hpos + 2) & ~1; - if (hpos > (maxhpos & ~1)) - hpos = maxhpos & ~1; + if (hpos >(maxhpos_short & ~1)) + hpos = maxhpos_short & ~1; cop_state.hpos = hpos; } @@ -4682,208 +6305,254 @@ static void compute_spcflag_copper(int hpos) cop_state.state = COP_strobe_delay1; copper_enabled_thisline = 1; - set_special(SPCFLAG_COPPER); } -static void copper_handler() +void blitter_done_notify(int hpos) { - /* This will take effect immediately, within the same cycle. */ - set_special(SPCFLAG_COPPER); - - if (! copper_enabled_thisline) - return; - - eventtab[ev_copper].active = false; -} - -/* -Copper writes to BLTSIZE: 3 blitter idle cycles, blitter normal cycle starts -(CPU write to BLTSIZE only have 2 idle cycles at start) - -BFD=0 wait: 1 cycle (or 2 if hpos is not aligned) delay before wait ends -*/ -void blitter_done_notify() -{ - int vp = vpos; - if (cop_state.state != COP_bltwait) return; - int hpos = current_hpos() + 3; + int vp_wait = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); + int vp = vpos; + + hpos++; hpos &= ~1; - if (hpos >= maxhpos) - { + if (hpos >= maxhpos) { hpos -= maxhpos; vp++; } cop_state.hpos = hpos; - cop_state.state = COP_read1; + cop_state.vpos = vp; + cop_state.state = COP_wait; + /* No need to check blitter state again */ + cop_state.saved_i2 |= 0x8000; - if (dmaen(DMA_COPPER) && vp == vpos) - { + if (dmaen(DMA_COPPER) && vp_wait >= cop_state.vcmp) { copper_enabled_thisline = 1; set_special(SPCFLAG_COPPER); } + else { + unset_special(SPCFLAG_COPPER); + } } -void do_copper() +void do_copper(void) { int hpos = current_hpos(); update_copper(hpos); } /* ADDR is the address that is going to be read/written; this access is - the reason why we want to update the copper. This function is also - used from hsync_handler to finish up the line; for this case, we check - hpos against maxhpos. */ -STATIC_INLINE void sync_copper_with_cpu(int hpos, int do_schedule, unsigned int addr) +the reason why we want to update the copper. This function is also +used from hsync_handler to finish up the line; for this case, we check +hpos against maxhpos. */ +STATIC_INLINE void sync_copper_with_cpu(int hpos, int do_schedule) { - if (eventtab[ev_copper].active) - { - if (hpos != maxhpos) - { - /* There might be reasons why we don't actually need to bother - updating the copper. */ - if (hpos < cop_state.first_sync) - return; - - if ((cop_state.regtypes_modified & regtypes[addr & 0x1FE]) == 0) - return; - } - - eventtab[ev_copper].active = false; - if (do_schedule) - events_schedule(); - set_special(SPCFLAG_COPPER); - } - /* Need to let the copper advance to the current position. */ if (copper_enabled_thisline) update_copper(hpos); } -STATIC_INLINE uae_u16 sprite_fetch(struct sprite* s) +static void cursorsprite(void) { - last_custom_value1 = chipmem_wget_indirect(s->pt); - s->pt += 2; - return last_custom_value1; + if (!dmaen(DMA_SPRITE) || first_planes_vpos == 0) + return; + sprite_0 = spr[0].pt; + sprite_0_height = spr[0].vstop - spr[0].vstart; + sprite_0_colors[0] = 0; + sprite_0_doubled = 0; + if (sprres == 0) + sprite_0_doubled = 1; + if (currprefs.chipset_mask & CSMASK_AGA) { + int sbasecol = ((bplcon4 >> 4) & 15) << 4; + sprite_0_colors[1] = current_colors.color_regs_aga[sbasecol + 1]; + sprite_0_colors[2] = current_colors.color_regs_aga[sbasecol + 2]; + sprite_0_colors[3] = current_colors.color_regs_aga[sbasecol + 3]; + } + else { + sprite_0_colors[1] = xcolors[current_colors.color_regs_ecs[17]]; + sprite_0_colors[2] = xcolors[current_colors.color_regs_ecs[18]]; + sprite_0_colors[3] = xcolors[current_colors.color_regs_ecs[19]]; + } + sprite_0_width = sprite_width; + //if (currprefs.input_tablet && (currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC)) { + // if (currprefs.input_magic_mouse_cursor == MAGICMOUSE_HOST_ONLY && mousehack_alive()) + // magic_sprite_mask &= ~1; + // else + // magic_sprite_mask |= 1; + //} } -STATIC_INLINE uae_u16 sprite_fetch2(struct sprite* s) +static uae_u16 sprite_fetch(struct sprite *s, int dma, int hpos, int cycle, int mode) +{ + uae_u16 data = last_custom_value1; + if (dma) { + if (cycle && currprefs.cpu_memory_cycle_exact) + s->ptxhpos = hpos; + data = last_custom_value1 = chipmem_wget_indirect(s->pt); + alloc_cycle(hpos, CYCLE_SPRITE); + } + s->pt += 2; + return data; +} +static uae_u16 sprite_fetch2(struct sprite *s, int hpos, int cycle, int mode) { uae_u16 data = chipmem_wget_indirect(s->pt); s->pt += 2; return data; } -STATIC_INLINE void do_sprites_1(int num, int cycle, int hpos) +static void do_sprites_1(int num, int cycle, int hpos) { - struct sprite* s = &spr[num]; - int dma, posctl = 0; + struct sprite *s = &spr[num]; + int posctl = 0; uae_u16 data; // fetch both sprite pairs even if DMA was switched off between sprites int isdma = dmaen(DMA_SPRITE) || ((num & 1) && spr[num & ~1].dmacycle); - if (isdma && vpos == sprite_vblank_endline) - spr_arm(num, 0); + if (cant_this_last_line()) + return; - if (isdma && s->dblscan && (fmode & 0x8000) && (vpos & 1) != (s->vstart & 1) && s->dmastate) - { + // see SPRxCTRL below + // if (isdma && vpos == sprite_vblank_endline) + // spr_arm (num, 0); + +#ifdef AGA + if (isdma && s->dblscan && (fmode & 0x8000) && (vpos & 1) != (s->vstart & 1) && s->dmastate) { spr_arm(num, 1); return; } - if (vpos == s->vstart) - { +#endif +#if SPRITE_DEBUG >= 3 * 256 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) + write_log(_T("%d:%d:slot%d:%d\n"), vpos, hpos, num, cycle); +#endif + if (vpos == s->vstart) { +#if SPRITE_DEBUG > 0 + if (!s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) + write_log(_T("%d:%d:SPR%d START\n"), vpos, hpos, num); +#endif s->dmastate = 1; + if (s->ptxvpos2 == vpos && hpos < s->ptxhpos2) + return; + if (num == 0 && cycle == 0) + cursorsprite(); } - if (vpos == s->vstop || vpos == sprite_vblank_endline) - { + if (vpos == s->vstop || vpos == sprite_vblank_endline) { +#if SPRITE_DEBUG > 0 + if (s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) + write_log(_T("%d:%d:SPR%d STOP\n"), vpos, hpos, num); +#endif s->dmastate = 0; } if (!isdma) return; - dma = hpos < plfstrt_sprite || diwstate != DIW_waiting_stop; - if (vpos == s->vstop || vpos == sprite_vblank_endline) - { + int dma = hpos < plfstrt_sprite || diwstate != DIW_waiting_stop; + int sprxp = s->xpos >> (sprite_buffer_res + 1); + bool start_before_dma = hpos >= sprxp && sprxp >= 16; + if (vpos == s->vstop || vpos == sprite_vblank_endline) { s->dmastate = 0; posctl = 1; - if (dma) - { - data = sprite_fetch(s); + if (dma) { + data = sprite_fetch(s, dma, hpos, cycle, 0); switch (sprite_width) { case 64: - s->pt += 4; + sprite_fetch2(s, hpos, cycle, 0); + sprite_fetch2(s, hpos, cycle, 0); case 32: - s->pt += 2; + sprite_fetch2(s, hpos, cycle, 0); break; } - if (cycle == 0) - { - SPRxPOS_1(data, num); + if (cycle == 0) { + if (start_before_dma && s->armed) { + maybe_decide_sprites(num, hpos); + } + SPRxPOS_1(data, num, hpos); s->dmacycle = 1; } - else - { - SPRxCTL_1(data, num); + else { + // This is needed to disarm previous field's sprite. + // It can be seen on OCS Agnus + ECS Denise combination where + // this cycle is disabled due to weird DDFTSTR=$18 copper list + // which causes corrupted sprite to "wrap around" the display. + SPRxCTL_1(data, num, hpos); s->dmastate = 0; sprstartstop(s); } } - if (vpos == sprite_vblank_endline) - { + if (vpos == sprite_vblank_endline) { // s->vstart == sprite_vblank_endline won't enable the sprite. s->dmastate = 0; } +#if SPRITE_DEBUG >= 256 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { + write_log(_T("%d:%d:dma:P=%06X "), vpos, hpos, s->pt); + } +#endif } - - if (s->dmastate && !posctl && dma) - { - data = sprite_fetch(s); - if (cycle == 0) - { - SPRxDATA_1(data, num); + if (s->dmastate && !posctl && dma) { + data = sprite_fetch(s, dma, hpos, cycle, 1); +#if SPRITE_DEBUG >= 256 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { + write_log(_T("%d:%d:dma:P=%06X "), vpos, hpos, s->pt); + } +#endif + if (cycle == 0) { + // if xpos is earlier than this cycle, decide it first. + if (start_before_dma) { + maybe_decide_sprites(num, hpos); + } + SPRxDATA_1(data, num, hpos); s->dmacycle = 1; } - else - { - SPRxDATB_1(data, num); - spr_arm(num, 1); + else { + // This is needed if xpos is between DATA and DATB fetches + // Test does not need to be accurate, only purpose is to + // not lose performance when sprites have "normal" positioning. + if (start_before_dma) { + maybe_decide_sprites(num, hpos); + } + SPRxDATB_1(data, num, hpos); } +#ifdef AGA switch (sprite_width) { case 64: - { - uae_u16 data32 = sprite_fetch2(s); - uae_u16 data641 = sprite_fetch2(s); - uae_u16 data642 = sprite_fetch2(s); - if (cycle == 0) - { + { + uae_u16 data32 = sprite_fetch2(s, hpos, cycle, 1); + uae_u16 data641 = sprite_fetch2(s, hpos, cycle, 1); + uae_u16 data642 = sprite_fetch2(s, hpos, cycle, 1); + if (dma) { + if (cycle == 0) { sprdata[num][3] = data642; sprdata[num][2] = data641; sprdata[num][1] = data32; } - else - { + else { sprdatb[num][3] = data642; sprdatb[num][2] = data641; sprdatb[num][1] = data32; } } - break; + } + break; case 32: - { - uae_u16 data32 = sprite_fetch2(s); + { + uae_u16 data32 = sprite_fetch2(s, hpos, cycle, 1); + if (dma) { if (cycle == 0) sprdata[num][1] = data32; else sprdatb[num][1] = data32; } - break; } + break; + } +#endif } } @@ -4892,30 +6561,12 @@ static void do_sprites(int hpos) int maxspr, minspr; int i; - if (vpos == 0) - { - // It is also possible armed status is cleared - // I am not sure so lets start with clearing - // data only - if (dmaen(DMA_SPRITE)) - { - for (i = 0; i < MAX_SPRITES; i++) - { - sprdata[i][0] = 0; - sprdatb[i][0] = 0; - sprdata[i][1] = 0; - sprdatb[i][1] = 0; - sprdata[i][2] = 0; - sprdatb[i][2] = 0; - sprdata[i][3] = 0; - sprdatb[i][3] = 0; - } - } - return; - } if (vpos < sprite_vblank_endline) return; + if (doflickerfix() && interlace_seen && (next_lineno & 1)) + return; + maxspr = hpos; minspr = last_sprite_hpos + 1; @@ -4930,8 +6581,7 @@ static void do_sprites(int hpos) if (minspr == maxspr) return; - for (i = minspr; i <= maxspr; i++) - { + for (i = minspr; i <= maxspr; i++) { int cycle = -1; int num = (i - SPR0_HPOS) / 4; switch ((i - SPR0_HPOS) & 3) @@ -4944,8 +6594,8 @@ static void do_sprites(int hpos) cycle = 1; break; } - if (cycle >= 0) - { + if (cycle >= 0) { + spr[num].ptxhpos = MAXHPOS; do_sprites_1(num, cycle, i); } } @@ -4953,22 +6603,65 @@ static void do_sprites(int hpos) last_sprite_hpos = hpos; } -static void init_sprites() +static void init_sprites(void) { memset(sprpos, 0, sizeof sprpos); memset(sprctl, 0, sizeof sprctl); } -static void init_hardware_frame() +static void init_hardware_frame(void) { + int i; + + first_bpl_vpos = -1; next_lineno = 0; prev_lineno = -1; + nextline_how = nln_normal; diwstate = DIW_waiting_start; ddfstate = DIW_waiting_start; + + if (first_bplcon0 != first_bplcon0_old) { + vertical_changed = horizontal_changed = true; + } + first_bplcon0_old = first_bplcon0; + + if (first_planes_vpos != first_planes_vpos_old || + last_planes_vpos != last_planes_vpos_old) { + vertical_changed = true; + } + first_planes_vpos_old = first_planes_vpos; + last_planes_vpos_old = last_planes_vpos; + + if (diwfirstword_total != diwfirstword_total_old || + diwlastword_total != diwlastword_total_old || + ddffirstword_total != ddffirstword_total_old || + ddflastword_total != ddflastword_total_old) { + horizontal_changed = true; + } + diwfirstword_total_old = diwfirstword_total; + diwlastword_total_old = diwlastword_total; + ddffirstword_total_old = ddffirstword_total; + ddflastword_total_old = ddflastword_total; + + first_planes_vpos = 0; + last_planes_vpos = 0; + diwfirstword_total = max_diwlastword; + diwlastword_total = 0; + ddffirstword_total = max_diwlastword; + ddflastword_total = 0; + plflastline_total = 0; + plffirstline_total = current_maxvpos(); + first_bplcon0 = 0; + autoscale_bordercolors = 0; + + for (i = 0; i < MAX_SPRITES; i++) { + spr[i].ptxhpos = MAXHPOS; + spr[i].ptxvpos2 = -1; + } plf_state = plf_end; } -void init_hardware_for_drawing_frame() +void init_hardware_for_drawing_frame(void) { /* Avoid this code in the first frame after a customreset. */ if (prev_sprite_entries) { @@ -5002,99 +6695,639 @@ void init_hardware_for_drawing_frame() next_sprite_forced = 1; } -STATIC_INLINE void rtg_vsync() +static int rpt_vsync(int adjust) +{ + frame_time_t curr_time = read_processor_time(); + int v = curr_time - vsyncwaittime + adjust; + if (v > syncbase || v < -syncbase) { + vsyncmintime = vsyncmaxtime = vsyncwaittime = curr_time; + v = 0; + } + return v; +} + +static void rtg_vsync(void) { #ifdef PICASSO96 + frame_time_t start, end; + start = read_processor_time(); picasso_handle_vsync(); + end = read_processor_time(); + frameskiptime += end - start; #endif } -void fpscounter_reset() +static void rtg_vsynccheck(void) { - timeframes = 0; - frametime = 0; - lastframetime = read_processor_time(); + //if (vblank_found_rtg) { + // vblank_found_rtg = false; + rtg_vsync(); + //} } -static void fpscounter() +static void maybe_process_pull_audio(void) +{ + //audio_finish_pull(); +} + +// moving average algorithm +#define MAVG_MAX_SIZE 128 +struct mavg_data +{ + int values[MAVG_MAX_SIZE]; + int size; + int offset; + int mavg; +}; + +static void mavg_clear(struct mavg_data *md) +{ + md->size = 0; + md->offset = 0; + md->mavg = 0; +} + +static int mavg(struct mavg_data *md, int newval, int size) +{ + if (md->size < size) { + md->values[md->size++] = newval; + md->mavg += newval; + } + else { + md->mavg -= md->values[md->offset]; + md->values[md->offset] = newval; + md->mavg += newval; + md->offset++; + if (md->offset >= size) + md->offset -= size; + } + return md->mavg / md->size; +} + +#define MAVG_VSYNC_SIZE 128 + +extern int log_vsync, debug_vsync_min_delay, debug_vsync_forced_delay; +static bool framewait(void) +{ + //return true always //TODO check if this is needed + return true; + + frame_time_t curr_time; + frame_time_t start; + int vs = isvsync_chipset(); + int status = 0; + + is_syncline = 0; + + static struct mavg_data ma_frameskipt; + int frameskipt_avg = mavg(&ma_frameskipt, frameskiptime, MAVG_VSYNC_SIZE); + + frameskiptime = 0; + + if (vs > 0) { + + static struct mavg_data ma_legacy; + static frame_time_t vsync_time; + int t; + + curr_time = read_processor_time(); + vsyncwaittime = vsyncmaxtime = curr_time + vsynctimebase; + if (!frame_rendered && !picasso_on) { + updatedisplayarea(); + frame_rendered = true; + } + + start = read_processor_time(); + t = 0; + if (int(start) - int(vsync_time) >= 0 && int(start) - int(vsync_time) < vsynctimebase) + t += int(start) - int(vsync_time); + + if (!frame_shown) { + updatedisplayarea(); + if (currprefs.gfx_apmode[0].gfx_strobo) + updatedisplayarea(); + } + + maybe_process_pull_audio(); + + int legacy_avg = mavg(&ma_legacy, t, MAVG_VSYNC_SIZE); + if (t > legacy_avg) + legacy_avg = t; + t = legacy_avg; + + /*if (debug_vsync_min_delay && t < debug_vsync_min_delay * vsynctimebase / 100) + t = debug_vsync_min_delay * vsynctimebase / 100; + if (debug_vsync_forced_delay > 0) + t = debug_vsync_forced_delay * vsynctimebase / 100;*/ + + vsync_time = read_processor_time(); + if (t > vsynctimebase * 2 / 3) + t = vsynctimebase * 2 / 3; + + if (currprefs.m68k_speed < 0) { + vsynctimeperline = (vsynctimebase - t) / (maxvpos_display + 1); + } + else { + vsynctimeperline = (vsynctimebase - t) / 3; + } + + if (vsynctimeperline < 1) + vsynctimeperline = 1; + + frame_shown = true; + return 1; + + } + else if (vs < 0) { + + int freetime; + extern int extraframewait, extraframewait2; + + if (!vblank_hz_state) + return status != 0; + + if (vs == -2 || vs == -3) { + + // fastest possible + int max, adjust, flipdelay, val; + frame_time_t now; + static struct mavg_data ma_skip, ma_adjust; + + val = 0; + + if (!frame_rendered && !picasso_on) { + frame_time_t start, end; + start = read_processor_time(); + updatedisplayarea(); + frame_rendered = true; + end = read_processor_time(); + val += end - start; + } + + curr_time = 0;//vsync_busywait_end(&flipdelay); // vsync time + status = 0; //vsync_busywait_do(NULL, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); + //vsync_busywait_start(); + + now = read_processor_time(); // current time + adjust = (int)now - (int)curr_time; + //write_log (_T("%d "), adjust); + if (adjust < 0 || adjust >= vsynctimebase) + adjust = 0; + if (adjust > vsynctimebase * 2 / 3) + adjust = vsynctimebase * 2 / 3; + + int adjust_avg = mavg(&ma_adjust, adjust, MAVG_VSYNC_SIZE); + + val += adjust_avg; + + int flipdelay_avg = mavg(&ma_skip, flipdelay, MAVG_VSYNC_SIZE); + if (flipdelay > flipdelay_avg) + flipdelay_avg = flipdelay; + if (currprefs.gfx_apmode[0].gfx_vflip == 0) { + val += flipdelay_avg; + //write_log (_T("%d "), skipcnt); + } + val += frameskipt_avg; + + //if (currprefs.gfx_apmode[0].gfx_vflip == 0) { + // if (debug_vsync_min_delay && val < debug_vsync_min_delay * vsynctimebase / 100) + // val = debug_vsync_min_delay * vsynctimebase / 100; + // if (debug_vsync_forced_delay > 0) + // val = debug_vsync_forced_delay * vsynctimebase / 100; + //} + + //write_log (_T("%d "), adjust); + + if (val > vsynctimebase * 2 / 3) + val = vsynctimebase * 2 / 3; + + max = (int)((vsynctimebase - val) * (1000.0 + currprefs.m68k_speed_throttle) / 1000.0); + if (max < 1) + max = 1; + + vsyncmintime = now; + vsyncwaittime = curr_time + (vsynctimebase - 0); + + vsynctimeperline = max / (maxvpos_display + 1); + if (status <= 0 || vsynctimeperline < 1) + vsynctimeperline = 1; + vsyncmaxtime = now + max; + + //if (0 || (log_vsync & 2)) { + // write_log(_T("%05d:%05d:%05d=%05d:%05d/%05d %03d%%\n"), adjust_avg, frameskipt_avg, flipdelay_avg, + // val, vsynctimeperline, vsynctimebase, val * 100 / vsynctimebase); + //} + + frame_shown = true; + + } + else { + + int max, adjust, flipdelay, flipdelay_avg; + static struct mavg_data ma_skip; + frame_time_t now; + + flipdelay = 0; + curr_time = 0;//vsync_busywait_end(&flipdelay); + if (!frame_rendered && !picasso_on) + { + updatedisplayarea(); + frame_rendered = true; + } + + + status = 0;//vsync_busywait_do(&freetime, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); + //vsync_busywait_start(); + + now = read_processor_time(); + + maybe_process_pull_audio(); + //if (extraframewait && !currprefs.turbo_emulation) { + // cpu_sleep_millis(-extraframewait); + // maybe_process_pull_audio(); + //} + //else if (extraframewait2 && !currprefs.turbo_emulation) { + // uae_time_t add = ((uae_s64)extraframewait2) * syncbase / (1000 * 1000); + // frame_time_t efw = read_processor_time() + add; + // for (;;) { + // frame_time_t nfw = read_processor_time(); + // if (audio_is_pull_event()) + // break; + // if ((int)efw - (int)nfw <= 0) + // break; + // } + // maybe_process_pull_audio(); + //} + + adjust = (int)now - (int)curr_time; + int adjustx = adjust; + if (adjust < 0) + adjust = 0; + if (adjust > vsynctimebase) + adjust = 0; + if (adjust > vsynctimebase / 2) + adjust = vsynctimebase / 2; + + vsyncmintime = now; + vsyncwaittime = curr_time + vsynctimebase; + + if (currprefs.gfx_apmode[0].gfx_vflip == 0) { + flipdelay_avg = mavg(&ma_skip, flipdelay, MAVG_VSYNC_SIZE); + if (flipdelay > flipdelay_avg) + flipdelay_avg = flipdelay; + } + else { + flipdelay_avg = 0; + } + + max = vsynctimebase - adjust - flipdelay_avg; + + //if (currprefs.gfx_apmode[0].gfx_vflip == 0) { + // int val = vsynctimebase - max; + // if (debug_vsync_min_delay && val < debug_vsync_min_delay * vsynctimebase / 100) + // val = debug_vsync_min_delay * vsynctimebase / 100; + // if (debug_vsync_forced_delay > 0) + // val = debug_vsync_forced_delay * vsynctimebase / 100; + // max = vsynctimebase - val; + //} + + vsynctimeperline = max / 3; + if (status <= 0 || vsynctimeperline < 1) + vsynctimeperline = 1; + vsyncmaxtime = now + max; + + //if (0 || (log_vsync & 2)) { + // write_log(_T("%06d:%06d:%06d:%06d %06d/%06d %03d%%\n"), frameskipt_avg, flipdelay_avg, adjust, adjustx, + // vsynctimeperline, vsynctimebase, (vsynctimebase - max) * 100 / vsynctimebase); + //} + + frame_shown = true; + + } + return status != 0; + } + + status = 1; + + int clockadjust = 0; + int vstb = vsynctimebase; + + //if (currprefs.m68k_speed < 0 && !cpu_sleepmode && !currprefs.cpu_memory_cycle_exact) { + if (currprefs.m68k_speed < 0) { + + if (!frame_rendered && !picasso_on) { + updatedisplayarea(); + frame_rendered = true; + } + + if (currprefs.m68k_speed_throttle) { + // this delay can safely overshoot frame time by 1-2 ms, following code will compensate for it. + for (;;) { + curr_time = read_processor_time(); + if ((int)vsyncwaittime - (int)curr_time <= 0 || (int)vsyncwaittime - (int)curr_time > 2 * vsynctimebase) + break; + rtg_vsynccheck(); + //if (cpu_sleep_millis(1) < 0) { + // curr_time = read_processor_time(); + // break; + //} + } + } + else { + curr_time = read_processor_time(); + } + + int max; + int adjust = 0; + if ((int)curr_time - (int)vsyncwaittime > 0 && (int)curr_time - (int)vsyncwaittime < vstb / 2) + adjust += curr_time - vsyncwaittime; + adjust += clockadjust; + max = (int)(vstb * (1000.0 + currprefs.m68k_speed_throttle) / 1000.0 - adjust); + vsyncwaittime = curr_time + vstb - adjust; + vsyncmintime = curr_time; + + if (max < 0) { + max = 0; + vsynctimeperline = 1; + } + else { + vsynctimeperline = max / (maxvpos_display + 1); + } + vsyncmaxtime = curr_time + max; + } + else { + + int t = 0; + + if (!frame_rendered && !picasso_on) { + start = read_processor_time(); + updatedisplayarea(); + frame_rendered = true; + t = read_processor_time() - start; + } + while (!currprefs.turbo_emulation) { + double v = rpt_vsync(clockadjust) / (syncbase / 1000.0); + if (v >= -2) + break; + rtg_vsynccheck(); + maybe_process_pull_audio(); + //if (cpu_sleep_millis(1) < 0) + // break; + } + while (rpt_vsync(clockadjust) < 0) { + rtg_vsynccheck(); + //if (audio_is_pull_event()) + // break; + } + idletime += read_processor_time() - start; + curr_time = read_processor_time(); + vsyncmintime = curr_time; + vsyncmaxtime = vsyncwaittime = curr_time + vstb; + if (frame_rendered) { + updatedisplayarea(); + t += read_processor_time() - curr_time; + } + t += frameskipt_avg; + vsynctimeperline = (vstb - t) / 3; + if (vsynctimeperline < 0) + vsynctimeperline = 0; + else if (vsynctimeperline > vstb / 3) + vsynctimeperline = vstb / 3; + + frame_shown = true; + + } + return status != 0; +} + +static void reset_cpu_idle(void) +{ + cpu_sleepmode_cnt = 0; + if (cpu_sleepmode) { + cpu_sleepmode = 0; + } +} + +#define FPSCOUNTER_MAVG_SIZE 10 +static struct mavg_data fps_mavg, idle_mavg; + +void fpscounter_reset(void) +{ + mavg_clear(&fps_mavg); + mavg_clear(&idle_mavg); + bogusframe = 2; + lastframetime = read_processor_time(); + idletime = 0; +} + +static void fpscounter(bool frameok) { frame_time_t now, last; - const int mcnt = 20; now = read_processor_time(); last = now - lastframetime; lastframetime = now; + if (bogusframe || int(last) < 0) + return; + + mavg(&fps_mavg, last / 10, FPSCOUNTER_MAVG_SIZE); + mavg(&idle_mavg, idletime / 10, FPSCOUNTER_MAVG_SIZE); + idletime = 0; + frametime += last; timeframes++; - if ((timeframes % mcnt) == 0) - { - int fps = frametime == 0 ? 0 : (syncbase * mcnt) / (frametime / 10); - if (currprefs.gfx_framerate > 0) - fps = fps / (currprefs.gfx_framerate + 1); - if (fps > 9999) - fps = 9999; - gui_data.fps = (fps + 5) / 10; - frametime = 0; + if ((timeframes & 7) == 0) { + double idle = 1000 - (idle_mavg.mavg == 0 ? 0.0 : double(idle_mavg.mavg) * 1000.0 / vsynctimebase); + int fps = fps_mavg.mavg == 0 ? 0 : syncbase * 10 / fps_mavg.mavg; + if (fps > 99999) + fps = 99999; + if (idle < 0) + idle = 0; + if (idle > 100 * 10) + idle = 100 * 10; + if (fake_vblank_hz * 10 > fps) { + double mult = double(fake_vblank_hz) * 10.0 / fps; + idle *= mult; + } + if (currprefs.turbo_emulation && idle < 100 * 10) + idle = 100 * 10; + gui_data.fps = fps; + gui_data.idle = int(idle); + gui_data.fps_color = frameok ? 0 : 1; + if ((timeframes & 15) == 0) { + gui_fps(fps, int(idle), frameok ? 0 : 1); + } } } // vsync functions that are not hardware timing related -static void vsync_handler_pre() +static void vsync_handler_pre(void) { - // handle_events (); + if (currprefs.m68k_speed < 0) { + if (regs.stopped) { + cpu_stopped_lines += maxvpos - cpu_last_stop_vpos; + } + int mv = 12 - currprefs.cpu_idle / 15; + if (mv >= 1 && mv <= 11) { + mv = 11 - mv; + if (cpu_stopped_lines >= maxvpos * (mv * 10) / 100) { + cpu_sleepmode_cnt++; + if (cpu_sleepmode_cnt >= 50) { + cpu_sleepmode_cnt = 50; + if (!cpu_sleepmode) { + cpu_sleepmode = 1; + //write_log(_T("sleep\n")); + } + } + } + else { + reset_cpu_idle(); + } + } + else { + reset_cpu_idle(); + } + } + if (regs.halted < 0) + reset_cpu_idle(); + cpu_last_stop_vpos = 0; + cpu_stopped_lines = 0; + if (bogusframe > 0) + bogusframe--; + + config_check_vsync(); + if (timehack_alive > 0) + timehack_alive--; + + //audio_vsync(); //TODO + blkdev_vsync(); + CIA_vsync_prehandler(); + inputdevice_vsync(); + filesys_vsync(); + //sampler_vsync(); //TODO + //clipboard_vsync(); //TODO #ifdef PICASSO96 - if (currprefs.rtgmem_size) + if (isvsync_rtg() >= 0) rtg_vsync(); #endif - blkdev_vsync(); - CIA_vsync_prehandler(); + if (!vsync_rendered) { + frame_time_t start, end; + start = read_processor_time(); + vsync_handle_redraw(lof_store, lof_changed, bplcon0, bplcon3); + vsync_rendered = true; + end = read_processor_time(); + frameskiptime += end - start; + } - if (quit_program > 0) - { + bool frameok = framewait(); + + //if (!picasso_on) { + // if (!frame_rendered && vblank_hz_state) { + // updatedisplayarea(); + // frame_rendered = true; + // } + // if (frame_rendered && !frame_shown) { + // updatedisplayarea(); + // frame_shown = true; + // } + //} + + fpscounter(frameok); + + bool waspaused = false; + //while (handle_events()) { + // if (!waspaused) { + // render_screen(true); + // show_screen(0); + // waspaused = true; + // } + // // we are paused, do all config checks but don't do any emulation + // if (vsync_handle_check()) { + // redraw_frame(); + // render_screen(true); + // show_screen(0); + // } + // config_check_vsync(); + //} + + if (quit_program > 0) { /* prevent possible infinite loop at wait_cycles().. */ framecnt = 0; reset_decisions(); return; } - if (timehack_alive > 0) - timehack_alive--; + vsync_rendered = false; + frame_shown = false; + frame_rendered = false; - inputdevice_vsync(); - filesys_vsync(); - - vsync_handle_redraw(); - - fpscounter(); + if (vblank_hz_mult > 0) + vblank_hz_state ^= 1; + else + vblank_hz_state = 1; vsync_handle_check(); } // emulated hardware vsync -static void vsync_handler_post() +static void vsync_handler_post(void) { + static frame_time_t prevtime; + prevtime = read_processor_time(); + DISK_vsync(); - if (bplcon0 & 4) - { +#ifdef WITH_LUA + uae_lua_run_handler("on_uae_vsync"); +#endif + + if (bplcon0 & 4) { lof_store = lof_store ? 0 : 1; } + if ((bplcon0 & 2) && currprefs.genlock) { + genlockvtoggle = lof_store ? 1 : 0; + } + if (lof_prev_lastline != lof_lastline) { + if (lof_togglecnt_lace < LOF_TOGGLES_NEEDED) + lof_togglecnt_lace++; + if (lof_togglecnt_lace >= LOF_TOGGLES_NEEDED) + lof_togglecnt_nlace = 0; + } + else { + // only 1-2 vblanks with bplcon0 lace bit set? + // lets check if lof has changed + if (!(bplcon0 & 4) && lof_togglecnt_lace > 0 && lof_togglecnt_lace < LOF_TOGGLES_NEEDED && !interlace_seen) { + lof_changed = 1; + } + lof_togglecnt_nlace = LOF_TOGGLES_NEEDED; + lof_togglecnt_lace = 0; + } + lof_prev_lastline = lof_lastline; lof_current = lof_store; - if (lof_changing) - { + if (lof_togglecnt_lace >= LOF_TOGGLES_NEEDED) { + interlace_changed = notice_interlace_seen(true); + if (interlace_changed) { + notice_screen_contents_lost(); + } + } + else if (lof_togglecnt_nlace >= LOF_TOGGLES_NEEDED) { + interlace_changed = notice_interlace_seen(false); + if (interlace_changed) { + notice_screen_contents_lost(); + } + } + if (lof_changing) { // still same? Trigger change now. - if ((!lof_store && lof_changing < 0) || (lof_store && lof_changing > 0)) - { + if ((!lof_store && lof_changing < 0) || (lof_store && lof_changing > 0)) { lof_changed_previous_field++; lof_changed = 1; // lof toggling? decide as interlace. - if (lof_changed_previous_field >= LOF_TOGGLES_NEEDED) - { + if (lof_changed_previous_field >= LOF_TOGGLES_NEEDED) { lof_changed_previous_field = LOF_TOGGLES_NEEDED; if (lof_lace == false) lof_lace = true; @@ -5106,191 +7339,265 @@ static void vsync_handler_post() } lof_changing = 0; } - else - { + else { lof_changed_previous_field = 0; lof_lace = false; } -#ifdef JIT - if (currprefs.cachesize) - { - vsyncmintime = last_synctime; - frh_count = 0; - } - else -#endif - { - vsyncmintime = last_synctime + vsynctimebase * (maxvpos_display - LAST_SPEEDUP_LINE) / maxvpos_display; - } - #ifdef PICASSO96 - if (picasso_on) - { - int p96refresh_active = int(maxvpos) * vblank_hz / (m68k_dreg(regs, 1) * 2); - if (p96refresh_active) - { - vpos_count = p96refresh_active; - vtotal = vpos_count; - } + if (p96refresh_active) { + vpos_count = p96refresh_active; + vtotal = vpos_count; } #endif +#ifdef GFXBOARD + if (!picasso_on) + gfxboard_vsync_handler(); +#endif - if ((beamcon0 & (0x20 | 0x80)) != (new_beamcon0 & (0x20 | 0x80))) - { - init_hz(); + if (varsync_changed || (beamcon0 & (0x10 | 0x20 | 0x80 | 0x100 | 0x200)) != (new_beamcon0 & (0x10 | 0x20 | 0x80 | 0x100 | 0x200))) { + init_hz_normal(); } - else if (vpos_count > 0 && abs(vpos_count - vpos_count_diff) > 1 && vposw_change < 4) - { - init_hz(); + else if (vpos_count > 0 && abs(vpos_count - vpos_count_diff) > 1 && vposw_change < 4) { + init_hz_vposw(); } - else if (lof_changed) - { + else if (interlace_changed || changed_chipset_refresh() || lof_changed) { compute_framesync(); } lof_changed = 0; vposw_change = 0; + bplcon0_interlace_seen = false; - eventtab[ev_copper].active = false; COPJMP(1, 1); init_hardware_frame(); + + vsync_cycles = get_cycles(); } -#ifdef JIT - -#define N_LINES 8 - -STATIC_INLINE int trigger_frh(int v) +static void copper_check(int n) { - return (v & (N_LINES - 1)) == 0; -} - -STATIC_INLINE long int diff32(frame_time_t x, frame_time_t y) -{ - return static_cast(x - y); -} - -static void frh_handler() -{ - if (currprefs.m68k_speed < 0) - { - frame_time_t curr_time = read_processor_time(); - vsyncmintime += vsynctimebase * N_LINES / maxvpos_display; - if (rpt_did_reset) - { - vsyncmintime = curr_time + vsynctimebase; - rpt_did_reset = 0; - } - /* Allow this to be one frame's worth of cycles out */ - while (diff32(curr_time, vsyncmintime + vsynctimebase) > 0) - { - vsyncmintime += vsynctimebase * N_LINES / maxvpos_display; - } + if (cop_state.state == COP_wait) { + int vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); + //if (vp < cop_state.vcmp) { + //if (copper_enabled_thisline) + // write_log(_T("COPPER BUG %d: vp=%d vpos=%d vcmp=%d thisline=%d\n"), n, vp, vpos, cop_state.vcmp, copper_enabled_thisline); + //} } } + +/* + +0 0 - +1 1 -- +2 2 - +3 3 -- +4 4 - +5 5 -- + +0 x - +1 0 -- +2 1 - +3 2 -- +4 3 - +5 4 -- + +*/ + +static void hsync_scandoubler(void) +{ + int i, idx1; + struct draw_info *dip1; + uaecptr bpltmp[8], bpltmpx[8]; + + if (lof_store && vpos >= maxvpos_nom - 1) + return; + + next_lineno++; + scandoubled_line = 1; +#ifdef DEBUGGER + debug_dma = 0; #endif + for (i = 0; i < 8; i++) { + int diff; + bpltmp[i] = bplpt[i]; + bpltmpx[i] = bplptx[i]; + if (prevbpl[lof_store][vpos][i] && prevbpl[1 - lof_store][vpos][i]) { + diff = prevbpl[lof_store][vpos][i] - prevbpl[1 - lof_store][vpos][i]; + if (lof_store) { + if (bplcon0 & 4) + bplpt[i] = prevbpl[lof_store][vpos][i] - diff; + } + else { + if (bplcon0 & 4) + bplpt[i] = prevbpl[lof_store][vpos][i]; + else + bplpt[i] = bplpt[i] - diff; + + } + } + } + + reset_decisions(); + plf_state = plf_idle; + plfr_state = plfr_idle; + + // copy color changes + dip1 = curr_drawinfo + next_lineno - 1; + for (idx1 = dip1->first_color_change; idx1 < dip1->last_color_change; idx1++) { + struct color_change *cs2 = &curr_color_changes[idx1]; + int regno = cs2->regno; + int hpos = cs2->linepos; + if (regno < 0x1000 && hpos < HBLANK_OFFSET && !(beamcon0 & 0x80) && prev_lineno >= 0) { + struct draw_info *pdip = curr_drawinfo + next_lineno - 1; + int idx = pdip->last_color_change; + pdip->last_color_change++; + pdip->nr_color_changes++; + curr_color_changes[idx].linepos = hpos + maxhpos + 1; + curr_color_changes[idx].regno = regno; + curr_color_changes[idx].value = cs2->value; + curr_color_changes[idx + 1].regno = -1; + } + else { + struct color_change *cs1 = &curr_color_changes[next_color_change]; + memcpy(cs1, cs2, sizeof(struct color_change)); + next_color_change++; + } + } + curr_color_changes[next_color_change].regno = -1; + + finish_decisions(); + hsync_record_line_state(next_lineno, nln_normal, thisline_changed); + hardware_line_completed(next_lineno); + scandoubled_line = 0; + + for (i = 0; i < 8; i++) { + bplpt[i] = bpltmp[i]; + bplptx[i] = bpltmpx[i]; + } +} + +static void events_dmal(int); static uae_u16 dmal, dmal_hpos; -static void dmal_func2() +static void dmal_emu(uae_u32 v) { - event_remevent(ev_dmal); - // Disk and Audio DMA bits are ignored by Agnus, Agnus only checks DMAL and master bit if (!(dmacon & DMA_MASTER)) return; + int hpos = current_hpos(); + if (v >= 6) { + v -= 6; + int nr = v / 2; + uaecptr pt = audio_getpt(nr, (v & 1) != 0); + uae_u16 dat = chipmem_wget_indirect(pt); - while (dmal) - { - if (dmal & 3) - { - if (dmal_hpos >= 6) - { - int nr = (dmal_hpos - 6) >> 1; - audio_dmal_do(nr, (dmal & 2) ? true : false); + last_custom_value1 = dat; + AUDxDAT(nr, dat, pt); + } + else { + uae_u16 dat; + int w = v & 1; + uaecptr pt = disk_getpt(); + // disk_fifostatus() needed in >100% disk speed modes + if (w) { + // write to disk + if (disk_fifostatus() <= 0) { + dat = chipmem_wget_indirect(pt); + last_custom_value1 = dat; + DSKDAT(dat); } - else - { - uae_u16 dat; - int w = (dmal & 2) ? 1 : 0; - uaecptr pt = disk_getpt(); - // disk_fifostatus() needed in >100% disk speed modes - if (w) - { - // write to disk - if (disk_fifostatus() <= 0) - { - dat = chipmem_wget_indirect(pt); - DSKDAT(dat); - } - } - else - { - // read from disk - if (disk_fifostatus() >= 0) - { - dat = DSKDATR(); - chipmem_wput_indirect(pt, dat); - } - } + } + else { + // read from disk + if (disk_fifostatus() >= 0) { + dat = DSKDATR(); + chipmem_wput_indirect(pt, dat); } } + } +} + +static void dmal_func(uae_u32 v) +{ + dmal_emu(v); + events_dmal(0); +} + +static void dmal_func2(uae_u32 v) +{ + while (dmal) { + if (dmal & 3) + dmal_emu(dmal_hpos + ((dmal & 2) ? 1 : 0)); dmal_hpos += 2; dmal >>= 2; } } -STATIC_INLINE void events_dmal() +static void events_dmal(int hp) { - if (currprefs.cachesize) - { - dmal_func2(); - } - else - { - event_newevent(ev_dmal, 7); - } -} - -static void events_dmal_hsync() -{ - uae_u16 dmal_disk = disk_dmal(); - - dmal = audio_dmal(); - if (!dmal && !dmal_disk) + if (!dmal) return; - - if (dmal_disk) - { - dmal_hpos = 0; - dmal <<= 6; - dmal |= dmal_disk; + if (currprefs.cpu_memory_cycle_exact) { + while (dmal) { + if (dmal & 3) + break; + hp += 2; + dmal >>= 2; + dmal_hpos += 2; + } + event2_newevent2(hp, dmal_hpos + ((dmal & 2) ? 1 : 0), dmal_func); + dmal &= ~3; + } + else if (currprefs.cachesize) { + dmal_func2(0); + } + else { + event2_newevent2(hp, 13, dmal_func2); } - else - dmal_hpos = 6; - events_dmal(); } -static bool is_custom_vsync() +static void events_dmal_hsync(void) +{ + if (dmal) + write_log(_T("DMAL error!? %04x\n"), dmal); + dmal = audio_dmal(); + dmal <<= 6; + dmal |= disk_dmal(); + if (!dmal) + return; + dmal_hpos = 0; + if (currprefs.cpu_memory_cycle_exact) { + for (int i = 0; i < 6 + 8; i += 2) { + if (dmal & (3 << i)) { + alloc_cycle_ext(i + 7, CYCLE_MISC); + } + } + } + events_dmal(7); +} + +static bool is_custom_vsync(void) { int vp = vpos + 1; int vpc = vpos_count + 1; /* Agnus vpos counter keeps counting until it wraps around if VPOSW writes put it past maxvpos */ if (vp >= maxvpos_total) vp = 0; - if (vp == maxvpos + lof_store || vp == maxvpos + lof_store + 1 || vpc >= MAXVPOS) - { + if (vp == maxvpos + lof_store || vp == maxvpos + lof_store + 1 || vpc >= MAXVPOS) { // vpos_count >= MAXVPOS just to not crash if VPOSW writes prevent vsync completely return true; } return false; } -static void set_hpos() +static void set_hpos(void) { + maxhpos = maxhpos_short + lol; + hpos_offset = 0; eventtab[ev_hsync].evtime = get_cycles() + HSYNCTIME; eventtab[ev_hsync].oldcycles = get_cycles(); } @@ -5300,29 +7607,60 @@ static void hsync_handler_pre(bool onvsync) { int hpos = current_hpos(); - if (!nocustom()) - { - /* Using 0x8A makes sure that we don't accidentally trip over the - modified_regtypes check. */ - sync_copper_with_cpu(maxhpos, 0, 0x8A); - finish_decisions(); - if (thisline_decision.plfleft >= 0) - { - if (currprefs.collision_level > 1) - DO_SPRITE_COLLISIONS - if (currprefs.collision_level > 2) - DO_PLAYFIELD_COLLISIONS + if (!nocustom()) { + sync_copper_with_cpu(maxhpos, 0); + + // Seven Seas scrolling quick fix hack + // checks if copper is going to modify BPLCON1 in next cycle. + if (copper_enabled_thisline && cop_state.state == COP_read2 && (cop_state.i1 & 0x1fe) == 0x102) { + // it did, pre-load value for Denise shifter emulation + hpos_is_zero_bplcon1_hack = chipmem_wget_indirect(cop_state.ip); + // following finish_decision() is going to finish this line + // it is too late when copper actually does the move } - hsync_record_line_state(next_lineno); + + finish_decisions(); + if (thisline_decision.plfleft >= 0) { + if (currprefs.collision_level > 1) + DO_SPRITE_COLLISIONS + if (currprefs.collision_level > 2) + DO_PLAYFIELD_COLLISIONS + } + hsync_record_line_state(next_lineno, nextline_how, thisline_changed); + /* reset light pen latch */ + if (vpos == sprite_vblank_endline) { + lightpen_triggered = 0; + sprite_0 = 0; + } + if (lightpen_enabled && lightpen_cx > 0 && (bplcon0 & 8) && !lightpen_triggered && lightpen_cy == vpos) { + vpos_lpen = vpos; + hpos_lpen = lightpen_cx; + lightpen_triggered = 1; + } + hardware_line_completed(next_lineno); + if (doflickerfix() && interlace_seen > 0) + hsync_scandoubler(); + notice_resolution_seen(GET_RES_AGNUS(bplcon0), interlace_seen != 0); } +#ifdef A2065 + a2065_hsync_handler(); +#endif #ifdef CD32 AKIKO_hsync_handler(); #endif +#ifdef CDTV + CDTV_hsync_handler(); +#endif + decide_blitter(-1); #ifdef PICASSO96 picasso_handle_hsync(); #endif + { + //void ahi_hsync(void); + //ahi_hsync(); + } DISK_hsync(); if (currprefs.produce_sound) @@ -5330,179 +7668,399 @@ static void hsync_handler_pre(bool onvsync) hsync_counter++; + refptr += 0x0200 * 4; + refptr_val += 0x0200 * 4; + + if (islinetoggle()) + lol ^= 1; + else + lol = 0; + vpos++; vpos_count++; if (vpos >= maxvpos_total) vpos = 0; - if (onvsync) - { + if (onvsync) { vpos = 0; + vsync_counter++; } set_hpos(); } +STATIC_INLINE bool is_last_line(void) +{ + return vpos + 1 == maxvpos + lof_store; +} + // this prepares for new line static void hsync_handler_post(bool onvsync) { last_copper_hpos = 0; +#ifdef CPUEMU_13 + if (currprefs.cpu_memory_cycle_exact || currprefs.blitter_cycle_exact) { + memset(cycle_line, 0, sizeof cycle_line); + } +#endif - CIA_hsync_posthandler(); - if (onvsync) - { - CIA_vsync_posthandler(); + // genlock active: + // vertical: interlaced = toggles every other field, non-interlaced = both fields (normal) + // horizontal: PAL = every line, NTSC = every other line + genlockhtoggle = !genlockhtoggle; + bool ciahsyncs = !(bplcon0 & 2) || ((bplcon0 & 2) && currprefs.genlock && (!currprefs.ntscmode || genlockhtoggle)); + bool ciavsyncs = !(bplcon0 & 2) || ((bplcon0 & 2) && currprefs.genlock && genlockvtoggle); + + CIA_hsync_posthandler(false, false); + if (currprefs.cs_cd32cd) { + CIA_hsync_posthandler(true, true); + CIAB_tod_handler(18); + } + else if (ciahsyncs) { + CIA_hsync_posthandler(true, ciahsyncs); + if (beamcon0 & (0x80 | 0x100)) { + if (hsstop < (maxhpos & ~1) && hsstrt < maxhpos) + CIAB_tod_handler(hsstop); + } + else { + CIAB_tod_handler(18); + } + } + + if (currprefs.cs_cd32cd) { + + if (cia_hsync < maxhpos) { + CIAA_tod_inc(cia_hsync); + cia_hsync += (akiko_ntscmode() ? 262 : 313) * maxhpos; + } + else { + cia_hsync -= maxhpos; + } + + } + else if (currprefs.cs_ciaatod > 0) { + if (cia_hsync < maxhpos) { + int newcount; + CIAA_tod_inc(cia_hsync); + newcount = (vblank_hz * (2 * maxvpos + (interlace_seen ? 1 : 0)) * (2 * maxhpos + (islinetoggle() ? 1 : 0))) / ((currprefs.cs_ciaatod == 2 ? 60 : 50) * 4); + cia_hsync += newcount; + } + else { + cia_hsync -= maxhpos; + } + } + else if (currprefs.cs_ciaatod == 0 && ciavsyncs) { + // CIA-A TOD counter increases when vsync pulse ends + if (beamcon0 & (0x80 | 0x200)) { + if (vpos == vsstop && vsstrt <= maxvpos) + CIAA_tod_inc(lof_store ? hsstop : hsstop + hcenter); + } + else { + if (vpos == (currprefs.ntscmode ? VSYNC_ENDLINE_NTSC : VSYNC_ENDLINE_PAL)) { + CIAA_tod_inc(lof_store ? 132 : 18); + } + } } inputdevice_hsync(); - last_custom_value1 = 0xffff; // refresh slots should set this to 0xffff - - if (!nocustom()) - { - if (bltstate != BLT_done && dmaen(DMA_BITPLANE) && diwstate == DIW_waiting_stop) - { + if (!nocustom()) { + if (!currprefs.blitter_cycle_exact && bltstate != BLT_done && dmaen(DMA_BITPLANE) && diwstate == DIW_waiting_stop) { blitter_slowdown(thisline_decision.plfleft, thisline_decision.plfright - (16 << fetchmode), - cycle_diagram_total_cycles[fetchmode][bplcon0_res][bplcon0_planes_limit], - cycle_diagram_free_cycles[fetchmode][bplcon0_res][bplcon0_planes_limit]); + cycle_diagram_total_cycles[fetchmode][GET_RES_AGNUS(bplcon0)][GET_PLANES_LIMIT(bplcon0)], + cycle_diagram_free_cycles[fetchmode][GET_RES_AGNUS(bplcon0)][GET_PLANES_LIMIT(bplcon0)]); } } - if (onvsync) - { + if (onvsync) { + // vpos_count >= MAXVPOS just to not crash if VPOSW writes prevent vsync completely + if ((bplcon0 & 8) && !lightpen_triggered) { + vpos_lpen = vpos - 1; + hpos_lpen = maxhpos; + lightpen_triggered = 1; + } vpos = 0; vsync_handler_post(); vpos_count = 0; } + // A1000 DIP Agnus (8361): vblank interrupt is triggered on line 1! + if (currprefs.cs_dipagnus) { + if (vpos == 1) + send_interrupt(5, 1 * CYCLE_UNIT); + } + else { + if (vpos == 0) + send_interrupt(5, 1 * CYCLE_UNIT); + } + // lastline - 1? + if (vpos + 1 == maxvpos + lof_store || vpos + 1 == maxvpos + lof_store + 1) { + lof_lastline = lof_store != 0; + } - if (vpos == 0) - send_interrupt(5); +#ifdef CPUEMU_13 + if (currprefs.cpu_memory_cycle_exact || currprefs.blitter_cycle_exact) { + int hp = maxhpos - 1, i; + for (i = 0; i < 4; i++) { + alloc_cycle(hp, i == 0 ? CYCLE_STROBE : CYCLE_REFRESH); /* strobe */ +#ifdef DEBUGGER + if (debug_dma) { + uae_u16 strobe = 0x3c; + if (vpos < equ_vblank_endline) + strobe = 0x38; + else if (vpos < minfirstline) + strobe = 0x3a; + else if (vpos + 1 == maxvpos + lof_store) + strobe = 0x38; + else if ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) && lol) + strobe = 0x3e; + record_dma(i == 0 ? strobe : 0x1fe, 0xffff, 0xffffffff, hp, vpos, DMARECORD_REFRESH); + } +#endif + hp += 2; + if (hp >= maxhpos) + hp -= maxhpos; + } + } +#endif events_dmal_hsync(); - if (currprefs.m68k_speed < 0) - { -#ifdef JIT - if (currprefs.cachesize) - { - frh_count++; - if (trigger_frh(frh_count) && vpos < maxvpos_display - LAST_SPEEDUP_LINE) - { - frh_handler(); + if (currprefs.m68k_speed < 0) { + static int sleeps_remaining; + if (is_last_line()) { + sleeps_remaining = (165 - currprefs.cpu_idle) / 6; + if (sleeps_remaining < 0) + sleeps_remaining = 0; + /* really last line, just run the cpu emulation until whole vsync time has been used */ + if (regs.stopped && currprefs.cpu_idle) { + // CPU in STOP state: sleep if enough time left. + frame_time_t rpt = read_processor_time(); + //while (!vsync_isdone() && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase) { + // maybe_process_pull_audio(); + // if (!execute_other_cpu(rpt + vsynctimebase / 10)) { + // if (cpu_sleep_millis(1) < 0) + // break; + // } + // rpt = read_processor_time(); + //} + } + else if (currprefs.m68k_speed_throttle) { + vsyncmintime = read_processor_time(); /* end of CPU emulation time */ + is_syncline = 0; + maybe_process_pull_audio(); + } + else { + vsyncmintime = vsyncmaxtime; /* emulate if still time left */ + is_syncline_end = read_processor_time() + vsynctimebase; /* far enough in future, we never wait that long */ + is_syncline = 2; + maybe_process_pull_audio(); } - is_syncline = trigger_frh(frh_count + 1) && vpos < maxvpos_display - LAST_SPEEDUP_LINE + 1 && !rpt_did_reset; } - else + else { + static int linecounter; + /* end of scanline, run cpu emulation as long as we still have time */ + vsyncmintime += vsynctimeperline; + linecounter++; + is_syncline = 0; + //if (!vsync_isdone() && !currprefs.turbo_emulation) { + // if ((int)vsyncmaxtime - (int)vsyncmintime > 0) { + // if ((int)vsyncwaittime - (int)vsyncmintime > 0) { + // frame_time_t rpt = read_processor_time(); + // /* Extra time left? Do some extra CPU emulation */ + // if ((int)vsyncmintime - (int)rpt > 0) { + // if (regs.stopped && currprefs.cpu_idle && sleeps_remaining > 0) { + // // STOP STATE: sleep. + // cpu_sleep_millis(1); + // sleeps_remaining--; + // maybe_process_pull_audio(); + // } + // else { + // is_syncline = 1; + // /* limit extra time */ + // is_syncline_end = rpt + vsynctimeperline; + // linecounter = 0; + // } + // } + // } + // if (!isvsync()) { + // // extra cpu emulation time if previous 10 lines without extra time. + // if (!is_syncline && linecounter >= 10 && (!regs.stopped || !currprefs.cpu_idle)) { + // is_syncline = -1; + // is_syncline_end = read_processor_time() + vsynctimeperline; + // linecounter = 0; + // } + // } + // } + //} + //maybe_process_pull_audio(); + } + } + else if (!currprefs.cpu_thread) { + static int nextwaitvpos; + if (vpos == 0) + nextwaitvpos = maxvpos_display * 1 / 4; + //if (audio_is_pull() > 0 && !currprefs.turbo_emulation) { + // maybe_process_pull_audio(); + // frame_time_t rpt = read_processor_time(); + // while (audio_pull_buffer() > 1 && (!isvsync() || (!vsync_isdone() && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase))) { + // cpu_sleep_millis(1); + // maybe_process_pull_audio(); + // rpt = read_processor_time(); + // } + //} + if (vpos + 1 < maxvpos + lof_store + && vpos >= nextwaitvpos && vpos < maxvpos - (maxvpos / 3) + //&& (audio_is_pull() <= 0 || (audio_is_pull() > 0 + // && audio_pull_buffer())) + ) { -#endif - is_syncline = vpos + 1 == maxvpos_display + lof_store - LAST_SPEEDUP_LINE; -#ifdef JIT + nextwaitvpos += maxvpos_display * 1 / 3; + vsyncmintime += vsynctimeperline; + //if (!vsync_isdone() && !currprefs.turbo_emulation) { + // frame_time_t rpt = read_processor_time(); + // // sleep if more than 2ms "free" time + // while (!vsync_isdone() && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase) { + // maybe_process_pull_audio(); + // if (!execute_other_cpu(rpt + vsynctimebase / 10)) { + // if (cpu_sleep_millis(1) < 0) + // break; + // } + // rpt = read_processor_time(); + // //write_log (_T("*")); + // } + //} } -#endif } - if (!nocustom()) - { + if (!nocustom()) { int lineno = vpos; if (lineno >= MAXVPOS) lineno %= MAXVPOS; + nextline_how = nln_normal; + if (doflickerfix() && interlace_seen > 0) { + lineno *= 2; + } + else if (!interlace_seen && doublescan <= 0 && currprefs.gfx_vresolution && currprefs.gfx_pscanlines > 1) { + lineno *= 2; + if (timeframes & 1) { + lineno++; + nextline_how = currprefs.gfx_pscanlines == 3 ? nln_lower_black_always : nln_lower_black; + } + else { + nextline_how = currprefs.gfx_pscanlines == 3 ? nln_upper_black_always : nln_upper_black; + } + } + else if ((doublescan <= 0 || interlace_seen > 0) && currprefs.gfx_vresolution && currprefs.gfx_iscanlines) { + lineno *= 2; + if (interlace_seen) { + if (!lof_current) { + lineno++; + nextline_how = currprefs.gfx_iscanlines == 2 ? nln_lower_black_always : nln_lower_black; + } + else { + nextline_how = currprefs.gfx_iscanlines == 2 ? nln_upper_black_always : nln_upper_black; + } + } + else { + nextline_how = currprefs.gfx_vresolution > VRES_NONDOUBLE && currprefs.gfx_pscanlines == 1 ? nln_nblack : nln_doubled; + } + } + else if (currprefs.gfx_vresolution && (doublescan <= 0 || interlace_seen > 0)) { + lineno *= 2; + if (interlace_seen) { + if (!lof_current) { + lineno++; + nextline_how = nln_lower; + } + else { + nextline_how = nln_upper; + } + } + else { + nextline_how = currprefs.gfx_vresolution > VRES_NONDOUBLE && currprefs.gfx_pscanlines == 1 ? nln_nblack : nln_doubled; + } + } prev_lineno = next_lineno; next_lineno = lineno; reset_decisions(); } - if (uae_int_requested) - { - INTREQ(0x8000 | 0x0008); - } - - { - extern void bsdsock_fake_int_handler(); - extern int volatile bsd_int_requested; - if (bsd_int_requested) - bsdsock_fake_int_handler(); - } + rethink_uae_int(); /* Default to no bitplane DMA overriding sprite DMA */ plfstrt_sprite = 0xff; /* See if there's a chance of a copper wait ending this line. */ cop_state.hpos = 0; compute_spcflag_copper(maxhpos); -} -static void init_regtypes() -{ - int i; - for (i = 0; i < 512; i += 2) - { - regtypes[i] = REGTYPE_ALL; - if ((i >= 0x20 && i < 0x28) || i == 0x08 || i == 0x7E) - regtypes[i] = REGTYPE_DISK; - else if (i >= 0x68 && i < 0x70) - regtypes[i] = REGTYPE_NONE; - else if (i >= 0x40 && i < 0x78) - regtypes[i] = REGTYPE_BLITTER; - else if (i >= 0xA0 && i < 0xE0 && (i & 0xF) < 0xE) - regtypes[i] = REGTYPE_AUDIO; - else if (i >= 0xA0 && i < 0xE0) - regtypes[i] = REGTYPE_NONE; - else if (i >= 0xE0 && i < 0x100) - regtypes[i] = REGTYPE_PLANE; - else if (i >= 0x120 && i < 0x180) - regtypes[i] = REGTYPE_SPRITE; - else if (i >= 0x180 && i < 0x1C0) - regtypes[i] = REGTYPE_COLOR; - else - switch (i) - { - case 0x02: - /* DMACONR - setting this to REGTYPE_BLITTER will cause it to - conflict with DMACON (since that is REGTYPE_ALL), and the - blitter registers (for the BBUSY bit), but nothing else, - which is (I think) what we want. */ - regtypes[i] = REGTYPE_BLITTER; - break; - case 0x04: case 0x06: case 0x2A: case 0x2C: - regtypes[i] = REGTYPE_POS; - break; - case 0x0A: case 0x0C: - case 0x0E: - regtypes[i] = REGTYPE_SPRITE; - break; - case 0x10: - regtypes[i] = REGTYPE_AUDIO; - break; - case 0x12: case 0x14: case 0x16: - case 0x36: - regtypes[i] = REGTYPE_JOYPORT; - break; - case 0x1A: - regtypes[i] = REGTYPE_DISK; - break; - case 0x102: - case 0x104: - case 0x106: - case 0x108: - case 0x10A: - regtypes[i] = REGTYPE_PLANE; - break; - case 0x88: case 0x8A: - case 0x8E: case 0x90: case 0x92: case 0x94: - case 0x96: - case 0x100: - regtypes[i] |= REGTYPE_FORCE; - break; - } + if (GET_PLANES(bplcon0) > 0 && dmaen(DMA_BITPLANE)) { + if (first_bplcon0 == 0) + first_bplcon0 = bplcon0; + if (vpos > last_planes_vpos) + last_planes_vpos = vpos; + if (vpos >= minfirstline && first_planes_vpos == 0) { + first_planes_vpos = vpos > minfirstline ? vpos - 1 : vpos; + } + else if (vpos >= current_maxvpos() - 1) { + last_planes_vpos = current_maxvpos(); + } } + if (diw_change == 0) { + if (vpos >= first_planes_vpos && vpos <= last_planes_vpos) { + if (diwlastword > diwlastword_total) { + diwlastword_total = diwlastword; + if (diwlastword_total > coord_diw_to_window_x(hsyncstartpos * 2)) + diwlastword_total = coord_diw_to_window_x(hsyncstartpos * 2); + } + if (diwfirstword < diwfirstword_total) { + diwfirstword_total = diwfirstword; + if (diwfirstword_total < coord_diw_to_window_x(hsyncendpos * 2)) + diwfirstword_total = coord_diw_to_window_x(hsyncendpos * 2); + firstword_bplcon1 = bplcon1; + } + } + if (diwstate == DIW_waiting_stop) { + int f = 8 << fetchmode; + if (plfstrt + f < ddffirstword_total + f) + ddffirstword_total = plfstrt + f; + if (plfstop + 2 * f > ddflastword_total + 2 * f) + ddflastword_total = plfstop + 2 * f; + } + if ((plffirstline < plffirstline_total || (plffirstline_total == minfirstline && vpos > minfirstline)) && plffirstline < vpos / 2) { + firstword_bplcon1 = bplcon1; + if (plffirstline < minfirstline) + plffirstline_total = minfirstline; + else + plffirstline_total = plffirstline; + } + if (plflastline > plflastline_total && plflastline > plffirstline_total && plflastline > maxvpos / 2) + plflastline_total = plflastline; + } + if (diw_change > 0) + diw_change--; + + /* fastest possible + last line and no vflip wait: render the frame as early as possible */ + if (is_last_line() && isvsync_chipset() <= -2 && !vsync_rendered && currprefs.gfx_apmode[0].gfx_vflip == 0) { + frame_time_t start, end; + start = read_processor_time(); + vsync_rendered = true; + vsync_handle_redraw(lof_store, lof_changed, bplcon0, bplcon3); + //if (vblank_hz_state) { + // updatedisplayarea(); + // frame_rendered = true; + //} + end = read_processor_time(); + frameskiptime += end - start; + } + + rtg_vsynccheck(); } -static void hsync_handler() +static void hsync_handler(void) { bool vs = is_custom_vsync(); hsync_handler_pre(vs); - if (vs) - { + if (vs) { vsync_handler_pre(); - if (savestate_check()) - { + if (savestate_check()) { uae_reset(0, 0); return; } @@ -5510,42 +8068,32 @@ static void hsync_handler() hsync_handler_post(vs); } -void init_eventtab() +void init_eventtab(void) { int i; nextevent = 0; - for (i = 0; i < ev_max; i++) - { + for (i = 0; i < ev_max; i++) { eventtab[i].active = false; eventtab[i].oldcycles = get_cycles(); } - for (i = 0; i < ev2_max; i++) - { - eventtab2[i].active = false; + for (i = 0; i < ev2_max; i++) { + eventtab2[i].active = 0; } eventtab[ev_cia].handler = CIA_handler; eventtab[ev_hsync].handler = hsync_handler; eventtab[ev_hsync].evtime = get_cycles() + HSYNCTIME; eventtab[ev_hsync].active = true; - eventtab[ev_copper].handler = copper_handler; - eventtab[ev_copper].active = false; eventtab[ev_misc].handler = MISC_handler; eventtab[ev_audio].handler = audio_evhandler; - eventtab[ev_blitter].handler = blitter_handler; - eventtab[ev_dmal].handler = dmal_func2; - + eventtab2[ev2_blitter].handler = blitter_handler; eventtab2[ev2_disk].handler = DISK_handler; - eventtab2[ev2_disk_motor0].handler = DISK_motordelay_func; - eventtab2[ev2_disk_motor1].handler = DISK_motordelay_func; - eventtab2[ev2_disk_motor2].handler = DISK_motordelay_func; - eventtab2[ev2_disk_motor3].handler = DISK_motordelay_func; events_schedule(); } -void custom_prepare() +void custom_prepare(void) { set_hpos(); hsync_handler_post(true); @@ -5554,49 +8102,55 @@ void custom_prepare() void custom_reset(bool hardreset, bool keyboardreset) { int i; - int zero = 0; target_reset(); reset_all_systems(); - write_log (_T("Reset at %08X. Chipset mask = %08X\n"), M68K_GETPC, currprefs.chipset_mask); + //write_log(_T("Reset at %08X. Chipset mask = %08X\n"), M68K_GETPC, currprefs.chipset_mask); + //memory_map_dump(); + //lightpen_active = -1; + //lightpen_triggered = 0; + //lightpen_cx = lightpen_cy = -1; nr_armed = 0; - if (! savestate_state) - { + if (!savestate_state) { + cia_hsync = 0; + extra_cycle = 0; hsync_counter = 0; + vsync_counter = 0; currprefs.chipset_mask = changed_prefs.chipset_mask; update_mirrors(); + blitter_reset(); - if (hardreset) - { - if (!aga_mode) - { - uae_u16 c = ((currprefs.chipset_mask & CSMASK_ECS_DENISE) && !(currprefs.chipset_mask & CSMASK_AGA)) ? 0xfff : 0x000; - for (i = 0; i < 32; i++) - { + if (hardreset) { + if (!aga_mode) { + uae_u16 c = (((currprefs.chipset_mask & CSMASK_ECS_DENISE) && !(currprefs.chipset_mask & CSMASK_AGA)) || currprefs.cs_denisenoehb) ? 0xfff : 0x000; + for (i = 0; i < 32; i++) { current_colors.color_regs_ecs[i] = c; current_colors.acolors[i] = getxcolor(c); } +#ifdef AGA } - else - { + else { uae_u32 c = 0; - for (i = 0; i < 256; i++) - { + for (i = 0; i < 256; i++) { current_colors.color_regs_aga[i] = c; current_colors.acolors[i] = getxcolor(c); } +#endif } + lof_store = lof_current = 0; + lof_lace = false; } + clxdat = 0; /* Clear the armed flags of all sprites. */ memset(spr, 0, sizeof spr); dmacon = 0; - intreq = 0; - intena = 0; + intreq_internal = 0; + intena = intena_internal = 0; copcon = 0; DSKLEN(0, 0); @@ -5604,42 +8158,40 @@ void custom_reset(bool hardreset, bool keyboardreset) bplcon0 = 0; bplcon4 = 0x0011; /* Get AGA chipset into ECS compatibility mode */ bplcon3 = 0x0C00; + diwhigh = 0; diwhigh_written = 0; hdiwstate = DIW_waiting_start; // this does not reset at vblank - // Some more values to reset... - bltcon0 = bltcon1 = bltapt = bltbpt = bltcpt = bltdpt = 0; - memset(&blt_info, 0, sizeof blt_info); - last_custom_value1 = 0; - last_synctime = 0; - frh_count = 0; - intreq = 0; - cop1lc = cop2lc = 0; - bpl1mod = bpl2mod = 0; - bplcon1 = bplcon2 = 0; - diwstrt = diwstop = ddfstrt = ddfstop = ddfstrt_old_hpos = 0; - vsstop = 0; - copper_enabled_thisline = 0; - estimated_last_fetch_cycle = 0; - + refptr = 0xffff; FMODE(0, 0); CLXCON(0); CLXCON2(0); setup_fmodes(0); - sprite_width = GET_SPRITEWIDTH (fmode); + sprite_width = GET_SPRITEWIDTH(fmode); beamcon0 = new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20; bltstate = BLT_done; - lof_store = lof_current = 0; - lof_lace = false; + blit_interrupt = 1; init_sprites(); } + //gayle_reset(hardreset); //TODO #ifdef AUTOCONFIG expamem_reset(); #endif + //a1000_reset(); //TODO DISK_reset(); CIA_reset(); + //gayle_reset(0); //TODO +#ifdef A2091 + a2091_reset(); +#endif +#ifdef GFXBOARD + gfxboard_reset(); +#endif +#ifdef NCR + ncr_reset(); +#endif #ifdef JIT compemu_reset(); #endif @@ -5651,14 +8203,16 @@ void custom_reset(bool hardreset, bool keyboardreset) inputdevice_reset(); timehack_alive = 0; - curr_sprite_entries = 0; - prev_sprite_entries = 0; + curr_sprite_entries = nullptr; + prev_sprite_entries = nullptr; sprite_entries[0][0].first_pixel = 0; sprite_entries[1][0].first_pixel = MAX_SPR_PIXELS; sprite_entries[0][1].first_pixel = 0; sprite_entries[1][1].first_pixel = MAX_SPR_PIXELS; memset(spixels, 0, 2 * MAX_SPR_PIXELS * sizeof *spixels); memset(&spixstate, 0, sizeof spixstate); + toscr_delay_sh[0] = 0; + toscr_delay_sh[1] = 0; cop_state.state = COP_stop; cop_state.movedelay = 0; @@ -5667,16 +8221,19 @@ void custom_reset(bool hardreset, bool keyboardreset) diwstate = DIW_waiting_start; dmal = 0; - new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20; - time_per_frame = 1000 * 1000 / (currprefs.ntscmode ? 60 : 50); - init_hz_full(); + init_hz_normal(); + // init_hz sets vpos_count + vpos_count = 0; + vpos_lpen = -1; lof_changing = 0; + lof_togglecnt_nlace = lof_togglecnt_lace = 0; + //nlace_cnt = NLACE_CNT_NEEDED; audio_reset(); - if (!isrestore()) - { + if (!isrestore()) { /* must be called after audio_reset */ adkcon = 0; + //serial_uartbreak(0); audio_update_adkmasks(); } @@ -5685,43 +8242,33 @@ void custom_reset(bool hardreset, bool keyboardreset) reset_decisions(); - init_regtypes(); + bogusframe = 1; - if (isrestore()) - { + if (isrestore()) { uae_u16 v; uae_u32 vv; audio_update_adkmasks(); INTENA(0); INTREQ(0); - - if (diwhigh) - diwhigh_written = 1; - else - diwhigh_written = 0; COPJMP(1, 1); v = bplcon0; BPLCON0(0, 0); BPLCON0(0, v); FMODE(0, fmode); - - if (!(currprefs.chipset_mask & CSMASK_AGA)) - { - for (i = 0; i < 32; i++) - { + if (!(currprefs.chipset_mask & CSMASK_AGA)) { + for (i = 0; i < 32; i++) { vv = current_colors.color_regs_ecs[i]; - current_colors.color_regs_ecs[i] = static_cast(-1); + current_colors.color_regs_ecs[i] = -1; record_color_change(0, i, vv); remembered_color_entry = -1; current_colors.color_regs_ecs[i] = vv; current_colors.acolors[i] = xcolors[vv]; } +#ifdef AGA } - else - { - for (i = 0; i < 256; i++) - { + else { + for (i = 0; i < 256; i++) { vv = current_colors.color_regs_aga[i]; current_colors.color_regs_aga[i] = -1; record_color_change(0, i, vv); @@ -5729,24 +8276,44 @@ void custom_reset(bool hardreset, bool keyboardreset) current_colors.color_regs_aga[i] = vv; current_colors.acolors[i] = CONVERT_RGB(vv); } +#endif } CLXCON(clxcon); CLXCON2(clxcon2); calcdiw(); - for (i = 0; i < 8; i++) - { + //v = serper; + //serper = 0; + //SERPER(v); + for (i = 0; i < 8; i++) { SPRxCTLPOS(i); nr_armed += spr[i].armed != 0; } - if (! currprefs.produce_sound) - { + if (!currprefs.produce_sound) { eventtab[ev_audio].active = false; events_schedule(); } + + //write_log(_T("CPU=%d Chipset=%s %s\n"), + // currprefs.cpu_model, + // (currprefs.chipset_mask & CSMASK_AGA) ? _T("AGA") : + // (currprefs.chipset_mask & (CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE)) == (CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE) ? _T("Full ECS") : + // (currprefs.chipset_mask & CSMASK_ECS_DENISE) ? _T("ECS Denise") : + // (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? _T("ECS") : + // _T("OCS"), currprefs.ntscmode ? _T("NTSC") : _T("PAL")); + //write_log(_T("State restored\n")); } sprres = expand_sprres(bplcon0, bplcon3); - sprite_width = GET_SPRITEWIDTH (fmode); + sprite_width = GET_SPRITEWIDTH(fmode); setup_fmodes(0); + shdelay_disabled = false; + +#ifdef ACTION_REPLAY + /* Doing this here ensures we can use the 'reset' command from within AR */ + action_replay_reset(hardreset, keyboardreset); +#endif +#if defined(ENFORCER) + enforcer_disable(); +#endif if (hardreset) rtc_hardreset(); @@ -5756,12 +8323,29 @@ void custom_reset(bool hardreset, bool keyboardreset) #endif } +//void dumpcustom(void) +//{ +// write_log(_T("DMACON: %04x INTENA: %04x (%04x) INTREQ: %04x (%04x) VPOS: %x HPOS: %x\n"), DMACONR(current_hpos()), +// intena, intena_internal, intreq, intreq_internal, vpos, current_hpos()); +// write_log(_T("COP1LC: %08lx, COP2LC: %08lx COPPTR: %08lx\n"), (unsigned long)cop1lc, (unsigned long)cop2lc, cop_state.ip); +// write_log(_T("DIWSTRT: %04x DIWSTOP: %04x DDFSTRT: %04x DDFSTOP: %04x\n"), +// (unsigned int)diwstrt, (unsigned int)diwstop, (unsigned int)ddfstrt, (unsigned int)ddfstop); +// write_log(_T("BPLCON 0: %04x 1: %04x 2: %04x 3: %04x 4: %04x LOF=%d/%d HDIW=%d VDIW=%d\n"), +// bplcon0, bplcon1, bplcon2, bplcon3, bplcon4, +// lof_current, lof_store, +// hdiwstate == DIW_waiting_start ? 0 : 1, diwstate == DIW_waiting_start ? 0 : 1); +// if (timeframes) { +// write_log(_T("Average frame time: %.2f ms [frames: %d time: %d]\n"), +// double(frametime) / timeframes, timeframes, frametime); +// if (total_skipped) +// write_log(_T("Skipped frames: %d\n"), total_skipped); +// } +//} -static void gen_custom_tables() +static void gen_custom_tables(void) { int i; - for (i = 0; i < 256; i++) - { + for (i = 0; i < 256; i++) { sprtaba[i] = ((((i >> 7) & 1) << 0) | (((i >> 6) & 1) << 2) | (((i >> 5) & 1) << 4) @@ -5774,8 +8358,7 @@ static void gen_custom_tables() sprite_ab_merge[i] = (((i & 15) ? 1 : 0) | ((i & 240) ? 2 : 0)); } - for (i = 0; i < 16; i++) - { + for (i = 0; i < 16; i++) { clxmask[i] = (((i & 1) ? 0xF : 0x3) | ((i & 2) ? 0xF0 : 0x30) | ((i & 4) ? 0xF00 : 0x300) @@ -5790,38 +8373,25 @@ static void gen_custom_tables() } /* mousehack is now in "filesys boot rom" */ -static uae_u32 REGPARAM2 mousehack_helper_old(struct TrapContext* ctx) +static uae_u32 REGPARAM2 mousehack_helper_old(struct TrapContext *ctx) { return 0; } -static int allocate_sprite_tables() +int custom_init(void) { - if (curr_sprite_entries != nullptr) - curr_sprite_entries = xmalloc (struct sprite_entry, MAX_SPR_PIXELS / 16); - if (curr_color_changes == nullptr) - curr_color_changes = xmalloc (struct color_change, MAX_REG_CHANGE); - - return 1; -} - -int custom_init() -{ - if (!allocate_sprite_tables()) - return 0; #ifdef AUTOCONFIG - if (uae_boot_rom) - { + if (uae_boot_rom_type) { uaecptr pos; pos = here(); org(rtarea_base + 0xFF70); - calltrap(deftrap (mousehack_helper_old)); + calltrap(deftrap(mousehack_helper_old)); dw(RTS); org(rtarea_base + 0xFFA0); - calltrap(deftrap (timehack_helper)); + calltrap(deftrap(timehack_helper)); dw(RTS); org(pos); @@ -5831,7 +8401,6 @@ int custom_init() gen_custom_tables(); build_blitfilltable(); - next_sprite_entry = 0; drawing_init(); create_cycle_diagram_table(); @@ -5853,8 +8422,9 @@ static void REGPARAM3 custom_bput(uaecptr, uae_u32) REGPARAM; addrbank custom_bank = { custom_lget, custom_wget, custom_bget, custom_lput, custom_wput, custom_bput, - default_xlate, default_check, nullptr, _T("Custom chipset"), - custom_lgeti, custom_wgeti, ABFLAG_IO, 0x1ff, 0xdff000 + default_xlate, default_check, nullptr, nullptr, _T("Custom chipset"), + custom_lgeti, custom_wgeti, + ABFLAG_IO, S_READ, S_WRITE, nullptr, 0x1ff, 0xdff000 }; static uae_u32 REGPARAM2 custom_wgeti(uaecptr addr) @@ -5863,7 +8433,6 @@ static uae_u32 REGPARAM2 custom_wgeti(uaecptr addr) return dummy_wgeti(addr); return custom_wget(addr); } - static uae_u32 REGPARAM2 custom_lgeti(uaecptr addr) { if (currprefs.cpu_model >= 68020) @@ -5871,111 +8440,130 @@ static uae_u32 REGPARAM2 custom_lgeti(uaecptr addr) return custom_lget(addr); } -STATIC_INLINE uae_u32 REGPARAM2 custom_wget_1(uaecptr addr, int noput) +static uae_u32 REGPARAM2 custom_wget_1(int hpos, uaecptr addr, int noput, bool isbyte) { uae_u16 v; int missing; -#ifdef JIT - special_mem |= S_READ; -#endif - switch (addr & 0x1fe) - { - case 0x000: v = 0xffff; - break; /* BPLDDAT */ - case 0x002: v = DMACONR(current_hpos()); - break; - case 0x004: v = VPOSR(); - break; - case 0x006: v = VHPOSR(); - break; + addr &= 0xfff; - case 0x008: v = 0xffff; - break; + switch (addr & 0x1fe) { + case 0x002: v = DMACONR(hpos); break; + case 0x004: v = VPOSR(); break; + case 0x006: v = VHPOSR(); break; - case 0x00A: v = JOY0DAT(); - break; - case 0x00C: v = JOY1DAT(); - break; - case 0x00E: v = CLXDAT(); - break; - case 0x010: v = ADKCONR(); - break; + case 0x00A: v = JOY0DAT(); break; + case 0x00C: v = JOY1DAT(); break; + case 0x00E: v = CLXDAT(); break; + case 0x010: v = ADKCONR(); break; - case 0x012: v = POT0DAT(); - break; - case 0x014: v = POT1DAT(); - break; - case 0x016: v = POTGOR(); - break; - case 0x018: v = 0x3000 /* no data */; - break; - case 0x01A: v = DSKBYTR(current_hpos()); - break; - case 0x01C: v = INTENAR(); - break; - case 0x01E: v = INTREQR(); - break; + case 0x012: v = POT0DAT(); break; + case 0x014: v = POT1DAT(); break; + case 0x016: v = POTGOR(); break; + //case 0x018: v = SERDATR(); break; + case 0x01A: v = DSKBYTR(hpos); break; + case 0x01C: v = INTENAR(); break; + case 0x01E: v = INTREQR(); break; case 0x07C: v = DENISEID(&missing); if (missing) goto writeonly; break; +#ifdef AGA case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A: case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196: case 0x198: case 0x19A: case 0x19C: case 0x19E: case 0x1A0: case 0x1A2: case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE: case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA: case 0x1BC: case 0x1BE: - if (!(aga_mode)) + if (!(currprefs.chipset_mask & CSMASK_AGA)) goto writeonly; v = COLOR_READ((addr & 0x3E) / 2); break; +#endif default: writeonly: /* OCS/ECS: - * reading write-only register causes write with last value in chip - * bus (custom registers, chipram, slowram) - * and finally returns either all ones or something weird if DMA happens - * in next (or previous) cycle.. FIXME. - * - * OCS-only special case: DFF000 (BLTDDAT) will always return whatever was left in bus - * - * AGA: - * Can also return last CPU accessed value - * Remembers old last_custom_value1 - */ + * reading write-only register causes write with last value in chip + * bus (custom registers, chipram, slowram) + * and finally returns either all ones or something weird if DMA happens + * in next (or previous) cycle.. FIXME. + * + * OCS-only special case: DFF000 (BLTDDAT) will always return whatever was left in bus + * + * AGA: + * Can also return last CPU accessed value + * Remembers old last_custom_value1 + */ v = last_custom_value1; - line_cyclebased = vpos; - if (!noput) - { + SET_LINE_CYCLEBASED; + if (!noput) { + int r, c, bmdma; uae_u16 l; - int hpos = current_hpos(); - if (aga_mode) - { + + if (currprefs.chipset_mask & CSMASK_AGA) { l = 0; } - else - { - l = currprefs.cpu_compatible && currprefs.cpu_model == 68000 ? regs.irc : 0xffff; + else { + // last chip bus value (read or write) is written to register + if (currprefs.cpu_compatible && currprefs.cpu_model == 68000) { + if (isbyte) + l = (regs.chipset_latch_rw << 8) | (regs.chipset_latch_rw & 0xff); + else + l = regs.chipset_latch_rw; + } + else { + l = regs.chipset_latch_rw; + } } decide_line(hpos); decide_fetch_safe(hpos); - custom_wput_1(hpos, addr, l, 1); + //debug_wputpeek(0xdff000 + addr, l); + r = custom_wput_1(hpos, addr, l, 1); + + // CPU gets back (OCS/ECS only): + // - if last cycle was DMA cycle: DMA cycle data + // - if last cycle was not DMA cycle: FFFF or some ANDed old data. + // +#ifdef CPUEMU_13 + c = cycle_line[hpos] & CYCLE_MASK; + bmdma = is_bitplane_dma(hpos); + if (currprefs.chipset_mask & CSMASK_AGA) { + if (bmdma || (c > CYCLE_REFRESH && c < CYCLE_CPU)) { + v = last_custom_value1; + } + else if (c == CYCLE_CPU) { + v = regs.db; + } + else { + v = last_custom_value1 >> ((addr & 2) ? 0 : 16); + } + } + else { + if (bmdma || (c > CYCLE_REFRESH && c < CYCLE_CPU)) { + v = last_custom_value1; + } + else { + // refresh checked because refresh cycles do not always + // set last_custom_value1 for performance reasons. + v = 0xffff; + } + } +#endif + return v; } - return v; } return v; } -STATIC_INLINE uae_u32 custom_wget2(uaecptr addr) +static uae_u32 custom_wget2(uaecptr addr, bool byte) { uae_u32 v; int hpos = current_hpos(); - sync_copper_with_cpu(hpos, 1, addr); - v = custom_wget_1(addr, 0); + sync_copper_with_cpu(hpos, 1); + v = custom_wget_1(hpos, addr, 0, byte); return v; } @@ -5983,33 +8571,32 @@ static uae_u32 REGPARAM2 custom_wget(uaecptr addr) { uae_u32 v; - if (addr & 1) - { + if ((addr & 0xffff) < 0x8000 && currprefs.cs_fatgaryrev >= 0) + return dummy_get(addr, 2, false, 0); + if (addr & 1) { /* think about move.w $dff005,d0.. (68020+ only) */ addr &= ~1; - v = custom_wget2(addr) << 8; - v |= custom_wget2(addr + 2) >> 8; - return v & 0xFFFF; + v = custom_wget2(addr, false) << 8; + v |= custom_wget2(addr + 2, false) >> 8; + return v; } - return custom_wget2(addr); + return custom_wget2(addr, false); } static uae_u32 REGPARAM2 custom_bget(uaecptr addr) { uae_u32 v; -#ifdef JIT - special_mem |= S_READ; -#endif - v = custom_wget2(addr & ~1); + if ((addr & 0xffff) < 0x8000 && currprefs.cs_fatgaryrev >= 0) + return dummy_get(addr, 1, false, 0); + v = custom_wget2(addr & ~1, true); v >>= (addr & 1 ? 0 : 8); - return v & 0xFF; + return v; } static uae_u32 REGPARAM2 custom_lget(uaecptr addr) { -#ifdef JIT - special_mem |= S_READ; -#endif + if ((addr & 0xffff) < 0x8000 && currprefs.cs_fatgaryrev >= 0) + return dummy_get(addr, 4, false, 0); return (uae_u32(custom_wget(addr)) << 16) | custom_wget(addr + 2); } @@ -6017,241 +8604,135 @@ static int REGPARAM2 custom_wput_1(int hpos, uaecptr addr, uae_u32 value, int no { addr &= 0x1FE; value &= 0xffff; - switch (addr) - { - case 0x00E: CLXDAT(); - break; - case 0x020: DSKPTH(value); - break; - case 0x022: DSKPTL(value); - break; - case 0x024: DSKLEN(value, hpos); - break; - case 0x026: /* DSKDAT (value). Writing to DMA write registers won't do anything */; - break; + switch (addr) { + case 0x00E: CLXDAT(); break; - case 0x02A: VPOSW(value); - break; - case 0x02C: VHPOSW(value); - break; - case 0x02E: COPCON(value); - break; - case 0x030: break; - case 0x032: break; - case 0x034: POTGO(value); - break; - case 0x036: JOYTEST(value); - break; + case 0x020: DSKPTH(value); break; + case 0x022: DSKPTL(value); break; + case 0x024: DSKLEN(value, hpos); break; + case 0x026: /* DSKDAT (value). Writing to DMA write registers won't do anything */; break; + case 0x028: REFPTR(value); break; + case 0x02A: VPOSW(value); break; + case 0x02C: VHPOSW(value); break; + case 0x02E: COPCON(value); break; + //case 0x030: SERDAT(value); break; + //case 0x032: SERPER(value); break; + case 0x034: POTGO(value); break; - case 0x040: BLTCON0(value); - break; - case 0x042: BLTCON1(value); - break; + case 0x040: BLTCON0(hpos, value); break; + case 0x042: BLTCON1(hpos, value); break; - case 0x044: BLTAFWM(value); - break; - case 0x046: BLTALWM(value); - break; + case 0x044: BLTAFWM(hpos, value); break; + case 0x046: BLTALWM(hpos, value); break; - case 0x048: BLTCPTH(value); - break; - case 0x04A: BLTCPTL(value); - break; - case 0x04C: BLTBPTH(value); - break; - case 0x04E: BLTBPTL(value); - break; - case 0x050: BLTAPTH(value); - break; - case 0x052: BLTAPTL(value); - break; - case 0x054: BLTDPTH(value); - break; - case 0x056: BLTDPTL(value); - break; + case 0x050: BLTAPTH(hpos, value); break; + case 0x052: BLTAPTL(hpos, value); break; + case 0x04C: BLTBPTH(hpos, value); break; + case 0x04E: BLTBPTL(hpos, value); break; + case 0x048: BLTCPTH(hpos, value); break; + case 0x04A: BLTCPTL(hpos, value); break; + case 0x054: BLTDPTH(hpos, value); break; + case 0x056: BLTDPTL(hpos, value); break; - case 0x058: BLTSIZE(value); - break; - case 0x05A: BLTCON0L(value); - break; - case 0x05C: BLTSIZV(value); - break; - case 0x05E: BLTSIZH(value); - break; + case 0x058: BLTSIZE(hpos, value); break; - case 0x064: BLTAMOD(value); - break; - case 0x062: BLTBMOD(value); - break; - case 0x060: BLTCMOD(value); - break; - case 0x066: BLTDMOD(value); - break; + case 0x064: BLTAMOD(hpos, value); break; + case 0x062: BLTBMOD(hpos, value); break; + case 0x060: BLTCMOD(hpos, value); break; + case 0x066: BLTDMOD(hpos, value); break; - case 0x070: BLTCDAT(value); - break; - case 0x072: BLTBDAT(value); - break; - case 0x074: BLTADAT(value); - break; + case 0x070: BLTCDAT(hpos, value); break; + case 0x072: BLTBDAT(hpos, value); break; + case 0x074: BLTADAT(hpos, value); break; - case 0x07E: DSKSYNC(hpos, value); - break; + case 0x07E: DSKSYNC(hpos, value); break; - case 0x080: COP1LCH(value); - break; - case 0x082: COP1LCL(value); - break; - case 0x084: COP2LCH(value); - break; - case 0x086: COP2LCL(value); - break; + case 0x080: COP1LCH(value); break; + case 0x082: COP1LCL(value); break; + case 0x084: COP2LCH(value); break; + case 0x086: COP2LCL(value); break; - case 0x088: COPJMP(1, 0); - break; - case 0x08A: COPJMP(2, 0); - break; + case 0x088: COPJMP(1, 0); break; + case 0x08A: COPJMP(2, 0); break; - case 0x08E: DIWSTRT(hpos, value); - break; - case 0x090: DIWSTOP(hpos, value); - break; - case 0x092: DDFSTRT(hpos, value); - break; - case 0x094: DDFSTOP(hpos, value); - break; + case 0x08E: DIWSTRT(hpos, value); break; + case 0x090: DIWSTOP(hpos, value); break; + case 0x092: DDFSTRT(hpos, value); break; + case 0x094: DDFSTOP(hpos, value); break; - case 0x096: DMACON(hpos, value); - break; - case 0x098: CLXCON(value); - break; - case 0x09A: INTENA(value); - break; - case 0x09C: INTREQ(value); - break; - case 0x09E: ADKCON(hpos, value); - break; + case 0x096: DMACON(hpos, value); break; + case 0x098: CLXCON(value); break; + case 0x09A: INTENA(value); break; + case 0x09C: INTREQ(value); break; + case 0x09E: ADKCON(hpos, value); break; - case 0x0A0: AUDxLCH(0, value); - break; - case 0x0A2: AUDxLCL(0, value); - break; - case 0x0A4: AUDxLEN(0, value); - break; - case 0x0A6: AUDxPER(0, value); - break; - case 0x0A8: AUDxVOL(0, value); - break; - case 0x0AA: AUDxDAT(0, value); - break; + case 0x0A0: AUDxLCH(0, value); break; + case 0x0A2: AUDxLCL(0, value); break; + case 0x0A4: AUDxLEN(0, value); break; + case 0x0A6: AUDxPER(0, value); break; + case 0x0A8: AUDxVOL(0, value); break; + case 0x0AA: AUDxDAT(0, value); break; - case 0x0B0: AUDxLCH(1, value); - break; - case 0x0B2: AUDxLCL(1, value); - break; - case 0x0B4: AUDxLEN(1, value); - break; - case 0x0B6: AUDxPER(1, value); - break; - case 0x0B8: AUDxVOL(1, value); - break; - case 0x0BA: AUDxDAT(1, value); - break; + case 0x0B0: AUDxLCH(1, value); break; + case 0x0B2: AUDxLCL(1, value); break; + case 0x0B4: AUDxLEN(1, value); break; + case 0x0B6: AUDxPER(1, value); break; + case 0x0B8: AUDxVOL(1, value); break; + case 0x0BA: AUDxDAT(1, value); break; - case 0x0C0: AUDxLCH(2, value); - break; - case 0x0C2: AUDxLCL(2, value); - break; - case 0x0C4: AUDxLEN(2, value); - break; - case 0x0C6: AUDxPER(2, value); - break; - case 0x0C8: AUDxVOL(2, value); - break; - case 0x0CA: AUDxDAT(2, value); - break; + case 0x0C0: AUDxLCH(2, value); break; + case 0x0C2: AUDxLCL(2, value); break; + case 0x0C4: AUDxLEN(2, value); break; + case 0x0C6: AUDxPER(2, value); break; + case 0x0C8: AUDxVOL(2, value); break; + case 0x0CA: AUDxDAT(2, value); break; - case 0x0D0: AUDxLCH(3, value); - break; - case 0x0D2: AUDxLCL(3, value); - break; - case 0x0D4: AUDxLEN(3, value); - break; - case 0x0D6: AUDxPER(3, value); - break; - case 0x0D8: AUDxVOL(3, value); - break; - case 0x0DA: AUDxDAT(3, value); - break; + case 0x0D0: AUDxLCH(3, value); break; + case 0x0D2: AUDxLCL(3, value); break; + case 0x0D4: AUDxLEN(3, value); break; + case 0x0D6: AUDxPER(3, value); break; + case 0x0D8: AUDxVOL(3, value); break; + case 0x0DA: AUDxDAT(3, value); break; - case 0x0E0: BPLxPTH(hpos, value, 0); - break; - case 0x0E2: BPLxPTL(hpos, value, 0); - break; - case 0x0E4: BPLxPTH(hpos, value, 1); - break; - case 0x0E6: BPLxPTL(hpos, value, 1); - break; - case 0x0E8: BPLxPTH(hpos, value, 2); - break; - case 0x0EA: BPLxPTL(hpos, value, 2); - break; - case 0x0EC: BPLxPTH(hpos, value, 3); - break; - case 0x0EE: BPLxPTL(hpos, value, 3); - break; - case 0x0F0: BPLxPTH(hpos, value, 4); - break; - case 0x0F2: BPLxPTL(hpos, value, 4); - break; - case 0x0F4: BPLxPTH(hpos, value, 5); - break; - case 0x0F6: BPLxPTL(hpos, value, 5); - break; - case 0x0F8: BPLxPTH(hpos, value, 6); - break; - case 0x0FA: BPLxPTL(hpos, value, 6); - break; - case 0x0FC: BPLxPTH(hpos, value, 7); - break; - case 0x0FE: BPLxPTL(hpos, value, 7); - break; + case 0x0E0: BPLxPTH(hpos, value, 0); break; + case 0x0E2: BPLxPTL(hpos, value, 0); break; + case 0x0E4: BPLxPTH(hpos, value, 1); break; + case 0x0E6: BPLxPTL(hpos, value, 1); break; + case 0x0E8: BPLxPTH(hpos, value, 2); break; + case 0x0EA: BPLxPTL(hpos, value, 2); break; + case 0x0EC: BPLxPTH(hpos, value, 3); break; + case 0x0EE: BPLxPTL(hpos, value, 3); break; + case 0x0F0: BPLxPTH(hpos, value, 4); break; + case 0x0F2: BPLxPTL(hpos, value, 4); break; + case 0x0F4: BPLxPTH(hpos, value, 5); break; + case 0x0F6: BPLxPTL(hpos, value, 5); break; + case 0x0F8: BPLxPTH(hpos, value, 6); break; + case 0x0FA: BPLxPTL(hpos, value, 6); break; + case 0x0FC: BPLxPTH(hpos, value, 7); break; + case 0x0FE: BPLxPTL(hpos, value, 7); break; - case 0x100: BPLCON0(hpos, value); - break; - case 0x102: BPLCON1(hpos, value); - break; - case 0x104: BPLCON2(hpos, value); - break; - case 0x106: BPLCON3(hpos, value); - break; + case 0x100: BPLCON0(hpos, value); break; + case 0x102: BPLCON1(hpos, value); break; + case 0x104: BPLCON2(hpos, value); break; +#ifdef ECS_DENISE + case 0x106: BPLCON3(hpos, value); break; +#endif - case 0x108: BPL1MOD(hpos, value); - break; - case 0x10A: BPL2MOD(hpos, value); - break; - case 0x10C: BPLCON4(hpos, value); - break; - case 0x10E: CLXCON2(value); - break; + case 0x108: BPL1MOD(hpos, value); break; + case 0x10A: BPL2MOD(hpos, value); break; +#ifdef AGA + case 0x10E: CLXCON2(value); break; +#endif - case 0x110: BPLxDAT(hpos, 0, value); - break; - case 0x112: BPLxDAT(hpos, 1, value); - break; - case 0x114: BPLxDAT(hpos, 2, value); - break; - case 0x116: BPLxDAT(hpos, 3, value); - break; - case 0x118: BPLxDAT(hpos, 4, value); - break; - case 0x11A: BPLxDAT(hpos, 5, value); - break; - case 0x11C: BPLxDAT(hpos, 6, value); - break; - case 0x11E: BPLxDAT(hpos, 7, value); - break; + case 0x110: BPLxDAT(hpos, 0, value); break; + case 0x112: BPLxDAT(hpos, 1, value); break; + case 0x114: BPLxDAT(hpos, 2, value); break; + case 0x116: BPLxDAT(hpos, 3, value); break; + case 0x118: BPLxDAT(hpos, 4, value); break; + case 0x11A: BPLxDAT(hpos, 5, value); break; + case 0x11C: BPLxDAT(hpos, 6, value); break; + case 0x11E: BPLxDAT(hpos, 7, value); break; case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A: case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196: @@ -6286,87 +8767,37 @@ static int REGPARAM2 custom_wput_1(int hpos, uaecptr addr, uae_u32 value, int no SPRxDATB(hpos, value, (addr - 0x146) / 8); break; - case 0x1C0: if (htotal != value) - { - htotal = value & (MAXHPOS_ROWS - 1); - varsync(); - } - break; - case 0x1C2: if (hsstop != value) - { - hsstop = value & (MAXHPOS_ROWS - 1); - varsync(); - } - break; - case 0x1C4: if (hbstrt != value) - { - hbstrt = value & (MAXHPOS_ROWS - 1); - varsync(); - } - break; - case 0x1C6: if (hbstop != value) - { - hbstop = value & (MAXHPOS_ROWS - 1); - varsync(); - } - break; - case 0x1C8: if (vtotal != value) - { - vtotal = value & (MAXVPOS_LINES_ECS - 1); - varsync(); - } - break; - case 0x1CA: if (vsstop != value) - { - vsstop = value & (MAXVPOS_LINES_ECS - 1); - varsync(); - } - break; - case 0x1CC: if (vbstrt < value || vbstrt > (value & (MAXVPOS_LINES_ECS - 1)) + 1) - { - vbstrt = value & (MAXVPOS_LINES_ECS - 1); - varsync(); - } - break; - case 0x1CE: if (vbstop < value || vbstop > (value & (MAXVPOS_LINES_ECS - 1)) + 1) - { - vbstop = value & (MAXVPOS_LINES_ECS - 1); - varsync(); - } - break; - case 0x1DC: BEAMCON0(value); - break; - case 0x1DE: if (hsstrt != value) - { - hsstrt = value & (MAXHPOS_ROWS - 1); - varsync(); - } - break; - case 0x1E0: if (vsstrt != value) - { - vsstrt = value & (MAXVPOS_LINES_ECS - 1); - varsync(); - } - break; - case 0x1E2: if (hcenter != value) - { - hcenter = value & (MAXHPOS_ROWS - 1); - varsync(); - } - break; - case 0x1E4: DIWHIGH(hpos, value); - break; + case 0x36: JOYTEST(value); break; + case 0x5A: BLTCON0L(hpos, value); break; + case 0x5C: BLTSIZV(hpos, value); break; + case 0x5E: BLTSIZH(hpos, value); break; + case 0x1E4: DIWHIGH(hpos, value); break; +#ifdef AGA + case 0x10C: BPLCON4(hpos, value); break; +#endif - case 0x1FC: FMODE(hpos, value); - break; - case 0x1FE: FNULL(value); - break; + case 0x1DC: BEAMCON0(value); break; + case 0x1C0: if (htotal != value) { htotal = value & (MAXHPOS_ROWS - 1); varsync(); } break; + case 0x1C2: if (hsstop != value) { hsstop = value & (MAXHPOS_ROWS - 1); varsync(); } break; + case 0x1C4: if (hbstrt != value) { hbstrt = value & (MAXHPOS_ROWS - 1); varsync(); } break; + case 0x1C6: if (hbstop != value) { hbstop = value & (MAXHPOS_ROWS - 1); varsync(); } break; + case 0x1C8: if (vtotal != value) { vtotal = value & (MAXVPOS_LINES_ECS - 1); varsync(); } break; + case 0x1CA: if (vsstop != value) { vsstop = value & (MAXVPOS_LINES_ECS - 1); varsync(); } break; + case 0x1CC: if (vbstrt < value || vbstrt >(value & (MAXVPOS_LINES_ECS - 1)) + 1) { vbstrt = value & (MAXVPOS_LINES_ECS - 1); varsync(); } break; + case 0x1CE: if (vbstop < value || vbstop >(value & (MAXVPOS_LINES_ECS - 1)) + 1) { vbstop = value & (MAXVPOS_LINES_ECS - 1); varsync(); } break; + case 0x1DE: if (hsstrt != value) { hsstrt = value & (MAXHPOS_ROWS - 1); varsync(); } break; + case 0x1E0: if (vsstrt != value) { vsstrt = value & (MAXVPOS_LINES_ECS - 1); varsync(); } break; + case 0x1E2: if (hcenter != value) { hcenter = value & (MAXHPOS_ROWS - 1); varsync(); } break; + +#ifdef AGA + case 0x1FC: FMODE(hpos, value); break; +#endif + case 0x1FE: FNULL(value); break; /* writing to read-only register causes read access */ default: - if (!noget) - { - custom_wget_1(addr, 1); + if (!noget) { + custom_wget_1(hpos, addr, 1, false); } return 1; } @@ -6376,17 +8807,19 @@ static int REGPARAM2 custom_wput_1(int hpos, uaecptr addr, uae_u32 value, int no static void REGPARAM2 custom_wput(uaecptr addr, uae_u32 value) { int hpos = current_hpos(); -#ifdef JIT - special_mem |= S_WRITE; -#endif - sync_copper_with_cpu(hpos, 1, addr); - if (addr & 1) - { + + if ((addr & 0xffff) < 0x8000 && currprefs.cs_fatgaryrev >= 0) { + dummy_put(addr, 2, value); + return; + } + + sync_copper_with_cpu(hpos, 1); + if (addr & 1) { addr &= ~1; custom_wput_1(hpos, addr, (value >> 8) | (value & 0xff00), 0); custom_wput_1(hpos, addr + 2, (value << 8) | (value & 0x00ff), 0); return; - } +} custom_wput_1(hpos, addr, value, 0); } @@ -6394,47 +8827,51 @@ static void REGPARAM2 custom_bput(uaecptr addr, uae_u32 value) { uae_u16 rval; - if (aga_mode) - { - if (addr & 1) - { + if ((addr & 0xffff) < 0x8000 && currprefs.cs_fatgaryrev >= 0) { + dummy_put(addr, 1, value); + return; + } + if (currprefs.chipset_mask & CSMASK_AGA) { + if (addr & 1) { rval = value & 0xff; } - else - { + else { rval = (value << 8) | (value & 0xFF); } } - else - { + else { rval = (value << 8) | (value & 0xff); } -#ifdef JIT - special_mem |= S_WRITE; -#endif - custom_wput(addr & ~1, rval); + if (currprefs.cs_bytecustomwritebug) { + if (addr & 1) + custom_wput(addr & ~1, rval); + else + custom_wput(addr, value << 8); + } + else { + custom_wput(addr & ~1, rval); + } } static void REGPARAM2 custom_lput(uaecptr addr, uae_u32 value) { -#ifdef JIT - special_mem |= S_WRITE; -#endif + if ((addr & 0xffff) < 0x8000 && currprefs.cs_fatgaryrev >= 0) { + dummy_put(addr, 4, value); + return; + } custom_wput(addr & 0xfffe, value >> 16); - custom_wput((addr + 2) & 0xfffe, uae_u16(value)); + custom_wput((addr + 2) & 0xfffe, (uae_u16)value); } #ifdef SAVESTATE -void custom_prepare_savestate() +void custom_prepare_savestate(void) { int i; - for (i = 0; i < ev2_max; i++) - { - if (eventtab2[i].active) - { + for (i = 0; i < ev2_max; i++) { + if (eventtab2[i].active) { eventtab2[i].active = false; eventtab2[i].handler(eventtab2[i].data); } @@ -6447,9 +8884,9 @@ void custom_prepare_savestate() #define RW restore_u16 () #define RL restore_u32 () -uae_u8* restore_custom(uae_u8* src) +uae_u8 *restore_custom(uae_u8 *src) { - uae_u16 dsklen, dskbytr, ru16; + uae_u16 dsklen, dskbytr; int dskpt; int i; @@ -6457,152 +8894,157 @@ uae_u8* restore_custom(uae_u8* src) changed_prefs.chipset_mask = currprefs.chipset_mask = RL & CSMASK_MASK; update_mirrors(); - blt_info.bltddat = RW; /* 000 BLTDDAT */ - ru16 = RW; /* 002 DMACONR -> see also 096 */ - if ((ru16 & 0x4000) == 0) - bltstate = BLT_done; - blt_info.blitzero = (ru16 & 0x2000 ? 1 : 0); - RW; /* 004 VPOSR */ - RW; /* 006 VHPOSR */ - RW; /* 008 DSKDATR (dummy register) */ - JOYSET(0, RW); /* 00A JOY0DAT */ - JOYSET(1, RW); /* 00C JOY1DAT */ - clxdat = RW; /* 00E CLXDAT */ - RW; /* 010 ADKCONR -> see 09E */ - RW; /* 012 POT0DAT */ - RW; /* 014 POT1DAT */ - RW; /* 016 POTINP -> see 034 */ - RW; /* 018 SERDATR* */ - dskbytr = RW; /* 01A DSKBYTR */ - RW; /* 01C INTENAR -> see 09A */ - RW; /* 01E INTREQR -> see 09C */ - dskpt = RL; /* 020-022 DSKPT */ - dsklen = RW; /* 024 DSKLEN */ - RW; /* 026 DSKDAT */ - RW; /* 028 REFPTR */ - i = RW; - lof_store = lof_current = (i & 0x8000) ? 1 : 0; /* 02A VPOSW */ - RW; /* 02C VHPOSW */ - COPCON(RW); /* 02E COPCON */ - RW; /* 030 SERDAT */ - RW; /* 032 SERPER* */ - potgo_value = 0; - POTGO(RW); /* 034 POTGO */ - RW; /* 036 JOYTEST* */ - RW; /* 038 STREQU */ - RW; /* 03A STRVHBL */ - RW; /* 03C STRHOR */ - RW; /* 03E STRLONG */ - BLTCON0(RW); /* 040 BLTCON0 */ - BLTCON1(RW); /* 042 BLTCON1 */ - BLTAFWM(RW); /* 044 BLTAFWM */ - BLTALWM(RW); /* 046 BLTALWM */ - bltcpt = RL; /* 048-04B BLTCPT */ - bltbpt = RL; /* 04C-04F BLTBPT */ - bltapt = RL; /* 050-053 BLTAPT */ - bltdpt = RL; /* 054-057 BLTDPT */ - RW; /* 058 BLTSIZE */ - RW; /* 05A BLTCON0L -> see 040 */ - blt_info.vblitsize = RW; /* 05C BLTSIZV */ - blt_info.hblitsize = RW; /* 05E BLTSIZH */ - blt_info.bltcmod = RW; /* 060 BLTCMOD */ - blt_info.bltbmod = RW; /* 062 BLTBMOD */ - blt_info.bltamod = RW; /* 064 BLTAMOD */ - blt_info.bltdmod = RW; /* 066 BLTDMOD */ - RW; /* 068 ? */ - RW; /* 06A ? */ - RW; /* 06C ? */ - RW; /* 06E ? */ - blt_info.bltcdat = RW; /* 070 BLTCDAT */ - BLTBDAT(RW); /* 072 BLTBDAT */ - blt_info.bltadat = RW; /* 074 BLTADAT */ - RW; /* 076 ? */ - RW; /* 078 ? */ - RW; /* 07A ? */ - RW; /* 07C LISAID */ - ru16 = RW; - DSKSYNC(-1, ru16); /* 07E DSKSYNC */ - cop1lc = RL; /* 080/082 COP1LC */ - cop2lc = RL; /* 084/086 COP2LC */ - RW; /* 088 COPJMP1 */ - RW; /* 08A COPJMP2 */ - RW; /* 08C COPINS */ - diwstrt = RW; /* 08E DIWSTRT */ - diwstop = RW; /* 090 DIWSTOP */ - ddfstrt = RW; /* 092 DDFSTRT */ - ddfstop = RW; /* 094 DDFSTOP */ + RW; /* 000 BLTDDAT */ + RW; /* 002 DMACONR */ + RW; /* 004 VPOSR */ + RW; /* 006 VHPOSR */ + RW; /* 008 DSKDATR (dummy register) */ + JOYSET(0, RW); /* 00A JOY0DAT */ + JOYSET(1, RW); /* 00C JOY1DAT */ + clxdat = RW; /* 00E CLXDAT */ + RW; /* 010 ADKCONR */ + RW; /* 012 POT0DAT* */ + RW; /* 014 POT1DAT* */ + RW; /* 016 POTINP* */ + RW; /* 018 SERDATR* */ + dskbytr = RW; /* 01A DSKBYTR */ + RW; /* 01C INTENAR */ + RW; /* 01E INTREQR */ + dskpt = RL; /* 020-022 DSKPT */ + dsklen = RW; /* 024 DSKLEN */ + RW; /* 026 DSKDAT */ + refptr = RW; /* 028 REFPTR */ + i = RW; lof_store = lof_current = (i & 0x8000) ? 1 : 0; lol = (i & 0x0080) ? 1 : 0; /* 02A VPOSW */ + RW; /* 02C VHPOSW */ + COPCON(RW); /* 02E COPCON */ + RW; /* 030 SERDAT* */ + //serper = RW; /* 032 SERPER* */ + potgo_value = 0; POTGO(RW); /* 034 POTGO */ + RW; /* 036 JOYTEST* */ + RW; /* 038 STREQU */ + RW; /* 03A STRVHBL */ + RW; /* 03C STRHOR */ + RW; /* 03E STRLONG */ + BLTCON0(0, RW); /* 040 BLTCON0 */ + BLTCON1(0, RW); /* 042 BLTCON1 */ + BLTAFWM(0, RW); /* 044 BLTAFWM */ + BLTALWM(0, RW); /* 046 BLTALWM */ + BLTCPTH(0, RW); BLTCPTL(0, RW); /* 048-04B BLTCPT */ + BLTBPTH(0, RW); BLTBPTL(0, RW); /* 04C-04F BLTBPT */ + BLTAPTH(0, RW); BLTAPTL(0, RW); /* 050-053 BLTAPT */ + BLTDPTH(0, RW); BLTDPTL(0, RW); /* 054-057 BLTDPT */ + RW; /* 058 BLTSIZE */ + RW; /* 05A BLTCON0L */ + blt_info.vblitsize = RW;/* 05C BLTSIZV */ + blt_info.hblitsize = RW;/* 05E BLTSIZH */ + BLTCMOD(0, RW); /* 060 BLTCMOD */ + BLTBMOD(0, RW); /* 062 BLTBMOD */ + BLTAMOD(0, RW); /* 064 BLTAMOD */ + BLTDMOD(0, RW); /* 066 BLTDMOD */ + RW; /* 068 ? */ + RW; /* 06A ? */ + RW; /* 06C ? */ + RW; /* 06E ? */ + BLTCDAT(0, RW); /* 070 BLTCDAT */ + BLTBDAT(0, RW); /* 072 BLTBDAT */ + BLTADAT(0, RW); /* 074 BLTADAT */ + RW; /* 076 ? */ + RW; /* 078 ? */ + RW; /* 07A ? */ + RW; /* 07C LISAID */ + DSKSYNC(-1, RW); /* 07E DSKSYNC */ + cop1lc = RL; /* 080/082 COP1LC */ + cop2lc = RL; /* 084/086 COP2LC */ + RW; /* 088 ? */ + RW; /* 08A ? */ + RW; /* 08C ? */ + diwstrt = RW; /* 08E DIWSTRT */ + diwstop = RW; /* 090 DIWSTOP */ + ddfstrt = RW; /* 092 DDFSTRT */ + ddfstop = RW; /* 094 DDFSTOP */ dmacon = RW & ~(0x2000 | 0x4000); /* 096 DMACON */ - CLXCON(RW); /* 098 CLXCON */ - intena = RW; /* 09A INTENA */ - intreq = RW; /* 09C INTREQ */ - adkcon = RW; /* 09E ADKCON */ - /* 0A0 - 0DE Audio regs */ + CLXCON(RW); /* 098 CLXCON */ + intena = intena_internal = RW; /* 09A INTENA */ + intreq = RW; /* 09C INTREQ */ + intreq_internal = intreq; + adkcon = RW; /* 09E ADKCON */ for (i = 0; i < 8; i++) - bplpt[i] = RL; - bplcon0 = RW; /* 100 BPLCON0 */ - bplcon1 = RW; /* 102 BPLCON1 */ - bplcon2 = RW; /* 104 BPLCON2 */ - bplcon3 = RW; /* 106 BPLCON3 */ - bpl1mod = RW; /* 108 BPL1MOD */ - bpl2mod = RW; /* 10A BPL2MOD */ - bplcon4 = RW; /* 10C BPLCON4 */ - CLXCON2(RW); /* 10E CLXCON2* */ + bplptx[i] = bplpt[i] = RL; + bplcon0 = RW; /* 100 BPLCON0 */ + bplcon1 = RW; /* 102 BPLCON1 */ + bplcon2 = RW; /* 104 BPLCON2 */ + bplcon3 = RW; /* 106 BPLCON3 */ + bpl1mod = RW; /* 108 BPL1MOD */ + bpl2mod = RW; /* 10A BPL2MOD */ + bplcon4 = RW; /* 10C BPLCON4 */ + clxcon2 = RW; /* 10E CLXCON2* */ for (i = 0; i < 8; i++) - bplxdat[i] = RW; /* BPLXDAT */ - /* 120 - 17E Sprite regs */ - for (i = 0; i < 32; i++) - current_colors.color_regs_ecs[i] = RW; /* 180-1BE COLORxx */ - htotal = RW; /* 1C0 HTOTAL */ - hsstop = RW; /* 1C2 HSTOP ? */ - hbstrt = RW; /* 1C4 HBSTRT ? */ - hbstop = RW; /* 1C6 HBSTOP ? */ - vtotal = RW; /* 1C8 VTOTAL */ - vsstop = RW; /* 1CA VSSTOP */ - vbstrt = RW; /* 1CC VBSTRT */ - vbstop = RW; /* 1CE VBSTOP */ - RW; /* 1D0 ? */ - RW; /* 1D2 ? */ - RW; /* 1D4 ? */ - RW; /* 1D6 ? */ - RW; /* 1D8 ? */ - RW; /* 1DA ? */ - new_beamcon0 = RW; /* 1DC BEAMCON0 */ - hsstrt = RW; /* 1DE HSSTRT */ - vsstrt = RW; /* 1E0 VSSTT */ - hcenter = RW; /* 1E2 HCENTER */ - diwhigh = RW; /* 1E4 DIWHIGH */ + fetched[i] = RW; /* BPLXDAT */ + for (i = 0; i < 32; i++) { + uae_u16 v = RW; + color_regs_genlock[i] = (v & 0x8000) != 0; + current_colors.color_regs_ecs[i] = v & 0xfff; /* 180 COLORxx */ + } + htotal = RW; /* 1C0 HTOTAL */ + hsstop = RW; /* 1C2 HSTOP ? */ + hbstrt = RW; /* 1C4 HBSTRT ? */ + hbstop = RW; /* 1C6 HBSTOP ? */ + vtotal = RW; /* 1C8 VTOTAL */ + vsstop = RW; /* 1CA VSSTOP */ + vbstrt = RW; /* 1CC VBSTRT */ + vbstop = RW; /* 1CE VBSTOP */ + RW; /* 1D0 ? */ + RW; /* 1D2 ? */ + RW; /* 1D4 ? */ + RW; /* 1D6 ? */ + RW; /* 1D8 ? */ + RW; /* 1DA ? */ + new_beamcon0 = RW; /* 1DC BEAMCON0 */ + hsstrt = RW; /* 1DE HSSTRT */ + vsstrt = RW; /* 1E0 VSSTT */ + hcenter = RW; /* 1E2 HCENTER */ + diwhigh = RW; /* 1E4 DIWHIGH */ diwhigh_written = (diwhigh & 0x8000) ? 1 : 0; hdiwstate = (diwhigh & 0x4000) ? DIW_waiting_stop : DIW_waiting_start; diwhigh &= 0x3fff; - RW; /* 1E6 ? */ - RW; /* 1E8 ? */ - RW; /* 1EA ? */ - RW; /* 1EC ? */ - RW; /* 1EE ? */ - RW; /* 1F0 ? */ - RW; /* 1F2 ? */ - RW; /* 1F4 ? */ - RW; /* 1F6 ? */ - RW; /* 1F8 ? */ - i = RW; /* 1FA ? */ + RW; /* 1E6 ? */ + RW; /* 1E8 ? */ + RW; /* 1EA ? */ + RW; /* 1EC ? */ + RW; /* 1EE ? */ + RW; /* 1F0 ? */ + RW; /* 1F2 ? */ + RW; /* 1F4 ? */ + RW; /* 1F6 ? */ + RW; /* 1F8 ? */ + i = RW; /* 1FA ? */ if (i & 0x8000) currprefs.ntscmode = changed_prefs.ntscmode = i & 1; - fmode = RW; /* 1FC FMODE */ - last_custom_value1 = RW; /* 1FE ? */ + fmode = fmode_saved = RW; /* 1FC FMODE */ + last_custom_value1 = RW;/* 1FE ? */ + + current_colors.extra = 0; + if (isbrdblank(-1, bplcon0, bplcon3)) + current_colors.extra |= 1 << CE_BORDERBLANK; + if (issprbrd(-1, bplcon0, bplcon3)) + current_colors.extra |= 1 << CE_BORDERSPRITE; + if ((currprefs.chipset_mask & CSMASK_ECS_DENISE) && (bplcon0 & 1) && (bplcon3 & 0x10)) + current_colors.extra |= 1 << CE_BORDERNTRANS; - current_colors.extra = isbrdblank(-1, bplcon0, bplcon3); DISK_restore_custom(dskpt, dsklen, dskbytr); - FMODE(0, fmode); - return src; } +#endif /* SAVESTATE */ + +#if defined SAVESTATE || defined DEBUGGER + #define SB save_u8 #define SW save_u16 #define SL save_u32 -uae_u8* save_custom(int* len, uae_u8* dstptr, int full) +uae_u8 *save_custom(int *len, uae_u8 *dstptr, int full) { uae_u8 *dstbak, *dst; int i, dummy; @@ -6614,164 +9056,185 @@ uae_u8* save_custom(int* len, uae_u8* dstptr, int full) if (dstptr) dstbak = dst = dstptr; else - dstbak = dst = xmalloc (uae_u8, 8 + 256 * 2); + dstbak = dst = xmalloc(uae_u8, 8 + 256 * 2); - SL (currprefs.chipset_mask); - SW (blt_info.bltddat); /* 000 BLTDDAT */ - SW (dmacon); /* 002 DMACONR */ - SW (VPOSR()); /* 004 VPOSR */ - SW (VHPOSR()); /* 006 VHPOSR */ - SW (0); /* 008 DSKDATR */ - SW (JOYGET (0)); /* 00A JOY0DAT */ - SW (JOYGET (1)); /* 00C JOY1DAT */ - SW (clxdat | 0x8000); /* 00E CLXDAT */ - SW (ADKCONR()); /* 010 ADKCONR */ - SW (POT0DAT()); /* 012 POT0DAT */ - SW (POT1DAT()); /* 014 POT1DAT */ - SW (0); /* 016 POTINP * */ - SW (0); /* 018 SERDATR * */ - SW (dskbytr); /* 01A DSKBYTR */ - SW (INTENAR()); /* 01C INTENAR */ - SW (INTREQR()); /* 01E INTREQR */ - SL (dskpt); /* 020-023 DSKPT */ - SW (dsklen); /* 024 DSKLEN */ - SW (0); /* 026 DSKDAT */ - SW (0); /* 028 REFPTR */ - SW ((lof_store ? 0x8001 : 0)); /* 02A VPOSW */ - SW (0); /* 02C VHPOSW */ - SW (copcon); /* 02E COPCON */ - SW (0); /* 030 SERDAT * */ - SW (0); /* 032 SERPER * */ - SW (potgo_value); /* 034 POTGO */ - SW (0); /* 036 JOYTEST * */ - SW (0); /* 038 STREQU */ - SW (0); /* 03A STRVBL */ - SW (0); /* 03C STRHOR */ - SW (0); /* 03E STRLONG */ - SW (bltcon0); /* 040 BLTCON0 */ - SW (bltcon1); /* 042 BLTCON1 */ - SW (blt_info.bltafwm); /* 044 BLTAFWM */ - SW (blt_info.bltalwm); /* 046 BLTALWM */ - SL (bltcpt); /* 048-04B BLTCPT */ - SL (bltbpt); /* 04C-04F BLTBPT */ - SL (bltapt); /* 050-053 BLTAPT */ - SL (bltdpt); /* 054-057 BLTDPT */ - SW (0); /* 058 BLTSIZE */ - SW (0); /* 05A BLTCON0L (use BLTCON0 instead) */ - SW (blt_info.vblitsize); /* 05C BLTSIZV */ - SW (blt_info.hblitsize); /* 05E BLTSIZH */ - SW (blt_info.bltcmod); /* 060 BLTCMOD */ - SW (blt_info.bltbmod); /* 062 BLTBMOD */ - SW (blt_info.bltamod); /* 064 BLTAMOD */ - SW (blt_info.bltdmod); /* 066 BLTDMOD */ - SW (0); /* 068 ? */ - SW (0); /* 06A ? */ - SW (0); /* 06C ? */ - SW (0); /* 06E ? */ - SW (blt_info.bltcdat); /* 070 BLTCDAT */ - SW (blt_info.bltbdat); /* 072 BLTBDAT */ - SW (blt_info.bltadat); /* 074 BLTADAT */ - SW (0); /* 076 ? */ - SW (0); /* 078 ? */ - SW (0); /* 07A ? */ - SW (DENISEID (&dummy)); /* 07C DENISEID/LISAID */ - SW (dsksync); /* 07E DSKSYNC */ - SL (cop1lc); /* 080-083 COP1LC */ - SL (cop2lc); /* 084-087 COP2LC */ - SW (0); /* 088 COPJMP1 */ - SW (0); /* 08A COPJMP2 */ - SW (0); /* 08C COPINS */ - SW (diwstrt); /* 08E DIWSTRT */ - SW (diwstop); /* 090 DIWSTOP */ - SW (ddfstrt); /* 092 DDFSTRT */ - SW (ddfstop); /* 094 DDFSTOP */ - SW (dmacon); /* 096 DMACON */ - SW (clxcon); /* 098 CLXCON */ - SW (intena); /* 09A INTENA */ - SW (intreq); /* 09C INTREQ */ - SW (adkcon); /* 09E ADKCON */ - /* 0A0 - 0DE Audio regs */ + SL(currprefs.chipset_mask); + SW(0); /* 000 BLTDDAT */ + SW(dmacon); /* 002 DMACONR */ + SW(VPOSR()); /* 004 VPOSR */ + SW(VHPOSR()); /* 006 VHPOSR */ + SW(0); /* 008 DSKDATR */ + SW(JOYGET(0)); /* 00A JOY0DAT */ + SW(JOYGET(1)); /* 00C JOY1DAT */ + SW(clxdat | 0x8000); /* 00E CLXDAT */ + SW(ADKCONR()); /* 010 ADKCONR */ + SW(POT0DAT()); /* 012 POT0DAT */ + SW(POT1DAT()); /* 014 POT1DAT */ + SW(0); /* 016 POTINP * */ + SW(0); /* 018 SERDATR * */ + SW(dskbytr); /* 01A DSKBYTR */ + SW(INTENAR()); /* 01C INTENAR */ + SW(INTREQR()); /* 01E INTREQR */ + SL(dskpt); /* 020-023 DSKPT */ + SW(dsklen); /* 024 DSKLEN */ + SW(0); /* 026 DSKDAT */ + SW(refptr); /* 028 REFPTR */ + SW((lof_store ? 0x8001 : 0) | (lol ? 0x0080 : 0));/* 02A VPOSW */ + SW(0); /* 02C VHPOSW */ + SW(copcon); /* 02E COPCON */ + //SW(serdat); /* 030 SERDAT * */ + //SW(serper); /* 032 SERPER * */ + SW(potgo_value); /* 034 POTGO */ + SW(0); /* 036 JOYTEST * */ + SW(0); /* 038 STREQU */ + SW(0); /* 03A STRVBL */ + SW(0); /* 03C STRHOR */ + SW(0); /* 03E STRLONG */ + SW(bltcon0); /* 040 BLTCON0 */ + SW(bltcon1); /* 042 BLTCON1 */ + SW(blt_info.bltafwm); /* 044 BLTAFWM */ + SW(blt_info.bltalwm); /* 046 BLTALWM */ + SL(bltcpt); /* 048-04B BLTCPT */ + SL(bltbpt); /* 04C-04F BLTCPT */ + SL(bltapt); /* 050-053 BLTCPT */ + SL(bltdpt); /* 054-057 BLTCPT */ + SW(0); /* 058 BLTSIZE */ + SW(0); /* 05A BLTCON0L (use BLTCON0 instead) */ + SW(blt_info.vblitsize);/* 05C BLTSIZV */ + SW(blt_info.hblitsize);/* 05E BLTSIZH */ + SW(blt_info.bltcmod); /* 060 BLTCMOD */ + SW(blt_info.bltbmod); /* 062 BLTBMOD */ + SW(blt_info.bltamod); /* 064 BLTAMOD */ + SW(blt_info.bltdmod); /* 066 BLTDMOD */ + SW(0); /* 068 ? */ + SW(0); /* 06A ? */ + SW(0); /* 06C ? */ + SW(0); /* 06E ? */ + SW(blt_info.bltcdat); /* 070 BLTCDAT */ + SW(blt_info.bltbdat); /* 072 BLTBDAT */ + SW(blt_info.bltadat); /* 074 BLTADAT */ + SW(0); /* 076 ? */ + SW(0); /* 078 ? */ + SW(0); /* 07A ? */ + SW(DENISEID(&dummy)); /* 07C DENISEID/LISAID */ + SW(dsksync); /* 07E DSKSYNC */ + SL(cop1lc); /* 080-083 COP1LC */ + SL(cop2lc); /* 084-087 COP2LC */ + SW(0); /* 088 ? */ + SW(0); /* 08A ? */ + SW(0); /* 08C ? */ + SW(diwstrt); /* 08E DIWSTRT */ + SW(diwstop); /* 090 DIWSTOP */ + SW(ddfstrt); /* 092 DDFSTRT */ + SW(ddfstop); /* 094 DDFSTOP */ + SW(dmacon); /* 096 DMACON */ + SW(clxcon); /* 098 CLXCON */ + SW(intena); /* 09A INTENA */ + SW(intreq); /* 09C INTREQ */ + SW(adkcon); /* 09E ADKCON */ for (i = 0; full && i < 32; i++) - SW (0); + SW(0); for (i = 0; i < 8; i++) - SL (bplpt[i]); /* 0E0-0FE BPLxPT */ - SW (bplcon0); /* 100 BPLCON0 */ - SW (bplcon1); /* 102 BPLCON1 */ - SW (bplcon2); /* 104 BPLCON2 */ - SW (bplcon3); /* 106 BPLCON3 */ - SW (bpl1mod); /* 108 BPL1MOD */ - SW (bpl2mod); /* 10A BPL2MOD */ - SW (bplcon4); /* 10C BPLCON4 */ - SW (clxcon2); /* 10E CLXCON2 */ + SL(bplpt[i]); /* 0E0-0FE BPLxPT */ + SW(bplcon0); /* 100 BPLCON0 */ + SW(bplcon1); /* 102 BPLCON1 */ + SW(bplcon2); /* 104 BPLCON2 */ + SW(bplcon3); /* 106 BPLCON3 */ + SW(bpl1mod); /* 108 BPL1MOD */ + SW(bpl2mod); /* 10A BPL2MOD */ + SW(bplcon4); /* 10C BPLCON4 */ + SW(clxcon2); /* 10E CLXCON2 */ for (i = 0; i < 8; i++) - SW (bplxdat[i]); /* 110 BPLxDAT */ - /* 120 - 17E Sprite regs */ - if (full) - { - for (i = 0; i < 8; i++) - { - SL (spr[i].pt); /* 120-13E SPRxPT */ + SW(fetched[i]); /* 110 BPLxDAT */ + if (full) { + for (i = 0; i < 8; i++) { + SL(spr[i].pt); /* 120-13E SPRxPT */ } - for (i = 0; i < 8; i++) - { - SW (sprpos[i]); /* 1x0 SPRxPOS */ - SW (sprctl[i]); /* 1x2 SPRxPOS */ - SW (sprdata[i][0]); /* 1x4 SPRxDATA */ - SW (sprdatb[i][0]); /* 1x6 SPRxDATB */ + for (i = 0; i < 8; i++) { + SW(sprpos[i]); /* 1x0 SPRxPOS */ + SW(sprctl[i]); /* 1x2 SPRxPOS */ + SW(sprdata[i][0]); /* 1x4 SPRxDATA */ + SW(sprdatb[i][0]); /* 1x6 SPRxDATB */ } } - for (i = 0; i < 32; i++) - SW (current_colors.color_regs_ecs[i]); /* 180-1BE COLORxx */ - SW (htotal); /* 1C0 HTOTAL */ - SW (hsstop); /* 1C2 HSTOP */ - SW (hbstrt); /* 1C4 HBSTRT */ - SW (hbstop); /* 1C6 HBSTOP */ - SW (vtotal); /* 1C8 VTOTAL */ - SW (vsstop); /* 1CA VSSTOP */ - SW (vbstrt); /* 1CC VBSTRT */ - SW (vbstop); /* 1CE VBSTOP */ - SW (0); /* 1D0 */ - SW (0); /* 1D2 */ - SW (0); /* 1D4 */ - SW (0); /* 1D6 */ - SW (0); /* 1D8 */ - SW (0); /* 1DA */ - SW (beamcon0); /* 1DC BEAMCON0 */ - SW (hsstrt); /* 1DE HSSTRT */ - SW (vsstrt); /* 1E0 VSSTRT */ - SW (hcenter); /* 1E2 HCENTER */ - SW (diwhigh | (diwhigh_written ? 0x8000 : 0) | (hdiwstate == DIW_waiting_stop ? 0x4000 : 0)); /* 1E4 DIWHIGH */ - SW (0); /* 1E6 */ - SW (0); /* 1E8 */ - SW (0); /* 1EA */ - SW (0); /* 1EC */ - SW (0); /* 1EE */ - SW (0); /* 1F0 */ - SW (0); /* 1F2 */ - SW (0); /* 1F4 */ - SW (0); /* 1F6 */ - SW (0); /* 1F8 */ - SW (0x8000 | (currprefs.ntscmode ? 1 : 0)); /* 1FA (re-used for NTSC) */ - SW (fmode); /* 1FC FMODE */ - SW (last_custom_value1); /* 1FE */ + for (i = 0; i < 32; i++) { + if (currprefs.chipset_mask & CSMASK_AGA) { + uae_u32 v = current_colors.color_regs_aga[i]; + uae_u16 v2; + v &= 0x00f0f0f0; + v2 = (v >> 4) & 15; + v2 |= ((v >> 12) & 15) << 4; + v2 |= ((v >> 20) & 15) << 8; + SW(v2); + } + else { + uae_u16 v = current_colors.color_regs_ecs[i]; + if (color_regs_genlock[i]) + v |= 0x8000; + SW(v); /* 180-1BE COLORxx */ + } + } + SW(htotal); /* 1C0 HTOTAL */ + SW(hsstop); /* 1C2 HSTOP*/ + SW(hbstrt); /* 1C4 HBSTRT */ + SW(hbstop); /* 1C6 HBSTOP */ + SW(vtotal); /* 1C8 VTOTAL */ + SW(vsstop); /* 1CA VSSTOP */ + SW(vbstrt); /* 1CC VBSTRT */ + SW(vbstop); /* 1CE VBSTOP */ + SW(0); /* 1D0 */ + SW(0); /* 1D2 */ + SW(0); /* 1D4 */ + SW(0); /* 1D6 */ + SW(0); /* 1D8 */ + SW(0); /* 1DA */ + SW(beamcon0); /* 1DC BEAMCON0 */ + SW(hsstrt); /* 1DE HSSTRT */ + SW(vsstrt); /* 1E0 VSSTRT */ + SW(hcenter); /* 1E2 HCENTER */ + SW(diwhigh | (diwhigh_written ? 0x8000 : 0) | (hdiwstate == DIW_waiting_stop ? 0x4000 : 0)); /* 1E4 DIWHIGH */ + SW(0); /* 1E6 */ + SW(0); /* 1E8 */ + SW(0); /* 1EA */ + SW(0); /* 1EC */ + SW(0); /* 1EE */ + SW(0); /* 1F0 */ + SW(0); /* 1F2 */ + SW(0); /* 1F4 */ + SW(0); /* 1F6 */ + SW(0); /* 1F8 */ + SW(0x8000 | (currprefs.ntscmode ? 1 : 0)); /* 1FA (re-used for NTSC) */ + SW(fmode); /* 1FC FMODE */ + SW(last_custom_value1); /* 1FE */ *len = dst - dstbak; return dstbak; } -uae_u8* restore_custom_agacolors(uae_u8* src) +#endif /* SAVESTATE || DEBUGGER */ + +#ifdef SAVESTATE + +uae_u8 *restore_custom_agacolors(uae_u8 *src) { int i; - for (i = 0; i < 256; i++) - { + for (i = 0; i < 256; i++) { +#ifdef AGA uae_u32 v = RL; + color_regs_genlock[i] = 0; + if (v & 0x80000000) + color_regs_genlock[i] = 1; + v &= 0x80ffffff; current_colors.color_regs_aga[i] = v; +#else + RL; +#endif } return src; } -uae_u8* save_custom_agacolors(int* len, uae_u8* dstptr) +uae_u8 *save_custom_agacolors(int *len, uae_u8 *dstptr) { uae_u8 *dstbak, *dst; int i; @@ -6779,21 +9242,25 @@ uae_u8* save_custom_agacolors(int* len, uae_u8* dstptr) if (dstptr) dstbak = dst = dstptr; else - dstbak = dst = xmalloc (uae_u8, 256 * 4); + dstbak = dst = xmalloc(uae_u8, 256 * 4); for (i = 0; i < 256; i++) - SL (current_colors.color_regs_aga[i]); +#ifdef AGA + SL(current_colors.color_regs_aga[i] | (color_regs_genlock[i] ? 0x80000000 : 0)); +#else + SL(0); +#endif *len = dst - dstbak; return dstbak; } -uae_u8* restore_custom_sprite(int num, uae_u8* src) +uae_u8 *restore_custom_sprite(int num, uae_u8 *src) { - memset(&spr[num], 0, sizeof (struct sprite)); - spr[num].pt = RL; /* 120-13E SPRxPT */ - sprpos[num] = RW; /* 1x0 SPRxPOS */ - sprctl[num] = RW; /* 1x2 SPRxPOS */ - sprdata[num][0] = RW; /* 1x4 SPRxDATA */ - sprdatb[num][0] = RW; /* 1x6 SPRxDATB */ + memset(&spr[num], 0, sizeof(struct sprite)); + spr[num].pt = RL; /* 120-13E SPRxPT */ + sprpos[num] = RW; /* 1x0 SPRxPOS */ + sprctl[num] = RW; /* 1x2 SPRxPOS */ + sprdata[num][0] = RW; /* 1x4 SPRxDATA */ + sprdatb[num][0] = RW; /* 1x6 SPRxDATB */ sprdata[num][1] = RW; sprdatb[num][1] = RW; sprdata[num][2] = RW; @@ -6804,87 +9271,619 @@ uae_u8* restore_custom_sprite(int num, uae_u8* src) return src; } -uae_u8* save_custom_sprite(int num, int* len, uae_u8* dstptr) +uae_u8 *save_custom_sprite(int num, int *len, uae_u8 *dstptr) { uae_u8 *dstbak, *dst; if (dstptr) dstbak = dst = dstptr; else - dstbak = dst = xmalloc (uae_u8, 30); - SL (spr[num].pt); /* 120-13E SPRxPT */ - SW (sprpos[num]); /* 1x0 SPRxPOS */ - SW (sprctl[num]); /* 1x2 SPRxPOS */ - SW (sprdata[num][0]); /* 1x4 SPRxDATA */ - SW (sprdatb[num][0]); /* 1x6 SPRxDATB */ - SW (sprdata[num][1]); - SW (sprdatb[num][1]); - SW (sprdata[num][2]); - SW (sprdatb[num][2]); - SW (sprdata[num][3]); - SW (sprdatb[num][3]); - SB (spr[num].armed ? 1 : 0); + dstbak = dst = xmalloc(uae_u8, 30); + SL(spr[num].pt); /* 120-13E SPRxPT */ + SW(sprpos[num]); /* 1x0 SPRxPOS */ + SW(sprctl[num]); /* 1x2 SPRxPOS */ + SW(sprdata[num][0]); /* 1x4 SPRxDATA */ + SW(sprdatb[num][0]); /* 1x6 SPRxDATB */ + SW(sprdata[num][1]); + SW(sprdatb[num][1]); + SW(sprdata[num][2]); + SW(sprdatb[num][2]); + SW(sprdata[num][3]); + SW(sprdatb[num][3]); + SB(spr[num].armed ? 1 : 0); *len = dst - dstbak; return dstbak; } -uae_u8* restore_custom_extra(uae_u8* src) +uae_u8 *restore_custom_extra(uae_u8 *src) { - uae_u32 v = restore_u32 (); + uae_u32 v = restore_u32(); if (!(v & 1)) v = 0; + currprefs.cs_compatible = changed_prefs.cs_compatible = v >> 24; cia_set_overlay((v & 2) != 0); + currprefs.genlock = changed_prefs.genlock = RBB; + currprefs.cs_rtc = changed_prefs.cs_rtc = RB; + currprefs.cs_rtc_adjust = changed_prefs.cs_rtc_adjust = RL; + + currprefs.cs_a1000ram = changed_prefs.cs_a1000ram = RBB; + currprefs.cs_slowmemisfast = changed_prefs.cs_slowmemisfast = RBB; + + RBB; + RBB; + currprefs.cs_cdtvscsi = changed_prefs.cs_cdtvscsi = RBB; + + currprefs.cs_pcmcia = changed_prefs.cs_pcmcia = RBB; + currprefs.cs_ciaatod = changed_prefs.cs_ciaatod = RB; + currprefs.cs_ciaoverlay = changed_prefs.cs_ciaoverlay = RBB; + + currprefs.cs_agnusbltbusybug = changed_prefs.cs_agnusbltbusybug = RBB; + currprefs.cs_denisenoehb = changed_prefs.cs_denisenoehb = RBB; + + currprefs.cs_agnusrev = changed_prefs.cs_agnusrev = SRB; + currprefs.cs_deniserev = changed_prefs.cs_deniserev = SRB; + currprefs.cs_fatgaryrev = changed_prefs.cs_fatgaryrev = SRB; + currprefs.cs_ramseyrev = changed_prefs.cs_ramseyrev = SRB; + currprefs.cs_cd32c2p = changed_prefs.cs_cd32c2p = RBB; currprefs.cs_cd32cd = changed_prefs.cs_cd32cd = RBB; currprefs.cs_cd32nvram = changed_prefs.cs_cd32nvram = RBB; + currprefs.cs_cdtvcd = changed_prefs.cs_cdtvcd = RBB; + currprefs.cs_cdtvram = changed_prefs.cs_cdtvram = RBB; + currprefs.cs_cdtvcard = changed_prefs.cs_cdtvcard = RB; + + currprefs.cs_df0idhw = changed_prefs.cs_df0idhw = RBB; + currprefs.cs_dipagnus = changed_prefs.cs_dipagnus = RBB; + currprefs.cs_ide = changed_prefs.cs_ide = RB; + currprefs.cs_mbdmac = changed_prefs.cs_mbdmac = RB; + currprefs.cs_ksmirror_a8 = changed_prefs.cs_ksmirror_a8 = RBB; + currprefs.cs_ksmirror_e0 = changed_prefs.cs_ksmirror_e0 = RBB; + currprefs.cs_resetwarning = changed_prefs.cs_resetwarning = RBB; + currprefs.cs_z3autoconfig = changed_prefs.cs_z3autoconfig = RBB; + currprefs.cs_1mchipjumper = changed_prefs.cs_1mchipjumper = RBB; return src; } -uae_u8* save_custom_extra(int* len, uae_u8* dstptr) +uae_u8 *save_custom_extra(int *len, uae_u8 *dstptr) { uae_u8 *dstbak, *dst; if (dstptr) dstbak = dst = dstptr; else - dstbak = dst = xmalloc (uae_u8, 1000); + dstbak = dst = xmalloc(uae_u8, 1000); - SL ((&get_mem_bank (0) != &chipmem_bank ? 2 : 0) | 1); + SL((currprefs.cs_compatible << 24) | 1); + SB(currprefs.genlock ? 1 : 0); + SB(currprefs.cs_rtc); + SL(currprefs.cs_rtc_adjust); - SB (currprefs.cs_cd32c2p); - SB (currprefs.cs_cd32cd); - SB (currprefs.cs_cd32nvram); + SB(currprefs.cs_a1000ram ? 1 : 0); + SB(currprefs.cs_slowmemisfast ? 1 : 0); + + SB(is_board_enabled(&currprefs, ROMTYPE_A2091, 0) ? 1 : 0); + SB(is_board_enabled(&currprefs, ROMTYPE_A4091, 0) ? 1 : 0); + SB(currprefs.cs_cdtvscsi ? 1 : 0); + + SB(currprefs.cs_pcmcia ? 1 : 0); + SB(currprefs.cs_ciaatod); + SB(currprefs.cs_ciaoverlay ? 1 : 0); + + SB(currprefs.cs_agnusbltbusybug ? 1 : 0); + SB(currprefs.cs_denisenoehb ? 1 : 0); + + SB(currprefs.cs_agnusrev); + SB(currprefs.cs_deniserev); + SB(currprefs.cs_fatgaryrev); + SB(currprefs.cs_ramseyrev); + + SB(currprefs.cs_cd32c2p); + SB(currprefs.cs_cd32cd); + SB(currprefs.cs_cd32nvram); + SB(currprefs.cs_cdtvcd ? 1 : 0); + SB(currprefs.cs_cdtvram ? 1 : 0); + SB(currprefs.cs_cdtvcard); + + SB(currprefs.cs_df0idhw ? 1 : 0); + SB(currprefs.cs_dipagnus ? 1 : 0); + SB(currprefs.cs_ide); + SB(currprefs.cs_mbdmac); + SB(currprefs.cs_ksmirror_a8 ? 1 : 0); + SB(currprefs.cs_ksmirror_e0 ? 1 : 0); + SB(currprefs.cs_resetwarning ? 1 : 0); + SB(currprefs.cs_z3autoconfig ? 1 : 0); + SB(currprefs.cs_1mchipjumper ? 1 : 0); *len = dst - dstbak; return dstbak; } +uae_u8 *restore_custom_event_delay(uae_u8 *src) +{ + if (restore_u32() != 1) + return src; + int cnt = restore_u8(); + for (int i = 0; i < cnt; i++) { + uae_u8 type = restore_u8(); + evt e = restore_u64(); + uae_u32 data = restore_u32(); + if (type == 1) + event2_newevent_xx(-1, e, data, send_interrupt_do); + } + return src; +} +uae_u8 *save_custom_event_delay(int *len, uae_u8 *dstptr) +{ + uae_u8 *dstbak, *dst; + int cnt = 0; + + for (int i = ev2_misc; i < ev2_max; i++) { + struct ev2 *e = &eventtab2[i]; + if (e->active && e->handler == send_interrupt_do) { + cnt++; + } + } + if (cnt == 0) + return NULL; + + if (dstptr) + dstbak = dst = dstptr; + else + dstbak = dst = xmalloc(uae_u8, 1000); + + save_u32(1); + save_u8(cnt); + for (int i = ev2_misc; i < ev2_max; i++) { + struct ev2 *e = &eventtab2[i]; + if (e->active && e->handler == send_interrupt_do) { + save_u8(1); + save_u64(e->evtime - get_cycles()); + save_u32(e->data); + + } + } + + *len = dst - dstbak; + return dstbak; +} + + +uae_u8 *save_cycles(int *len, uae_u8 *dstptr) +{ + uae_u8 *dstbak, *dst; + if (dstptr) + dstbak = dst = dstptr; + else + dstbak = dst = xmalloc(uae_u8, 1000); + save_u32(1); + save_u32(CYCLE_UNIT); + save_u64(get_cycles()); + save_u32(extra_cycle); + write_log(_T("SAVECYCLES %08lX\n"), get_cycles()); + *len = dst - dstbak; + return dstbak; +} + +uae_u8 *restore_cycles(uae_u8 *src) +{ + if (restore_u32() != 1) + return src; + restore_u32(); + start_cycles = restore_u64(); + extra_cycle = restore_u32(); + if (extra_cycle < 0 || extra_cycle >= 2 * CYCLE_UNIT) + extra_cycle = 0; + write_log(_T("RESTORECYCLES %08lX\n"), start_cycles); + return src; +} + #endif /* SAVESTATE */ -void check_prefs_changed_custom() +void check_prefs_changed_custom(void) { + if (!config_changed) + return; currprefs.gfx_framerate = changed_prefs.gfx_framerate; + if (currprefs.turbo_emulation_limit != changed_prefs.turbo_emulation_limit) { + currprefs.turbo_emulation_limit = changed_prefs.turbo_emulation_limit; + if (changed_prefs.turbo_emulation) { + warpmode(changed_prefs.turbo_emulation); + } + } + if (currprefs.turbo_emulation != changed_prefs.turbo_emulation) + warpmode(changed_prefs.turbo_emulation); if (inputdevice_config_change_test()) inputdevice_copyconfig(&changed_prefs, &currprefs); currprefs.immediate_blits = changed_prefs.immediate_blits; currprefs.waiting_blits = changed_prefs.waiting_blits; currprefs.collision_level = changed_prefs.collision_level; + if (!currprefs.keyboard_connected && changed_prefs.keyboard_connected) { + // send powerup sync + keyboard_connected(true); + } + else if (currprefs.keyboard_connected && !changed_prefs.keyboard_connected) { + keyboard_connected(false); + } + currprefs.keyboard_connected = changed_prefs.keyboard_connected; + + currprefs.cs_ciaatod = changed_prefs.cs_ciaatod; + currprefs.cs_rtc = changed_prefs.cs_rtc; currprefs.cs_cd32cd = changed_prefs.cs_cd32cd; currprefs.cs_cd32c2p = changed_prefs.cs_cd32c2p; currprefs.cs_cd32nvram = changed_prefs.cs_cd32nvram; + currprefs.cs_cdtvcd = changed_prefs.cs_cdtvcd; + currprefs.cs_ide = changed_prefs.cs_ide; + currprefs.cs_pcmcia = changed_prefs.cs_pcmcia; + currprefs.cs_fatgaryrev = changed_prefs.cs_fatgaryrev; + currprefs.cs_ramseyrev = changed_prefs.cs_ramseyrev; + currprefs.cs_agnusrev = changed_prefs.cs_agnusrev; + currprefs.cs_deniserev = changed_prefs.cs_deniserev; + currprefs.cs_mbdmac = changed_prefs.cs_mbdmac; + currprefs.cs_df0idhw = changed_prefs.cs_df0idhw; + currprefs.cs_slowmemisfast = changed_prefs.cs_slowmemisfast; + currprefs.cs_dipagnus = changed_prefs.cs_dipagnus; + currprefs.cs_denisenoehb = changed_prefs.cs_denisenoehb; + currprefs.cs_z3autoconfig = changed_prefs.cs_z3autoconfig; if (currprefs.chipset_mask != changed_prefs.chipset_mask || - currprefs.ntscmode != changed_prefs.ntscmode) - { + currprefs.picasso96_nocustom != changed_prefs.picasso96_nocustom || + currprefs.ntscmode != changed_prefs.ntscmode) { + currprefs.picasso96_nocustom = changed_prefs.picasso96_nocustom; currprefs.chipset_mask = changed_prefs.chipset_mask; - if (currprefs.ntscmode != changed_prefs.ntscmode) - { + if (currprefs.ntscmode != changed_prefs.ntscmode) { currprefs.ntscmode = changed_prefs.ntscmode; new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20; } init_custom(); } +#ifdef GFXFILTER + struct gfx_filterdata *fd = &currprefs.gf[0]; + struct gfx_filterdata *fdcp = &changed_prefs.gf[0]; + + fd->gfx_filter_horiz_zoom = fdcp->gfx_filter_horiz_zoom; + fd->gfx_filter_vert_zoom = fdcp->gfx_filter_vert_zoom; + fd->gfx_filter_horiz_offset = fdcp->gfx_filter_horiz_offset; + fd->gfx_filter_vert_offset = fdcp->gfx_filter_vert_offset; + fd->gfx_filter_scanlines = fdcp->gfx_filter_scanlines; + + fd->gfx_filter_left_border = fdcp->gfx_filter_left_border; + fd->gfx_filter_right_border = fdcp->gfx_filter_right_border; + fd->gfx_filter_top_border = fdcp->gfx_filter_top_border; + fd->gfx_filter_bottom_border = fdcp->gfx_filter_bottom_border; +#endif +} + +#ifdef CPUEMU_13 + +STATIC_INLINE void sync_copper(int hpos) +{ + if (copper_enabled_thisline) + update_copper(hpos); +} + +STATIC_INLINE void decide_fetch_ce(int hpos) +{ + if ((line_cyclebased || blitter_dangerous_bpl) && vpos < current_maxvpos()) + decide_fetch(hpos); +} + +#define BLIT_NASTY 4 + +// blitter not in nasty mode = CPU gets one cycle if it has been waiting +// at least 4 cycles (all DMA cycles count, not just blitter cycles, even +// blitter idle cycles do count!) + +extern int cpu_tracer; +static int dma_cycle(void) +{ + int hpos, hpos_old; + + blitter_nasty = 1; + if (cpu_tracer < 0) + return current_hpos_safe(); + if (!currprefs.cpu_memory_cycle_exact) + return current_hpos_safe(); + while (currprefs.cpu_memory_cycle_exact) { + int bpldma; + int blitpri = dmacon & DMA_BLITPRI; + hpos_old = current_hpos_safe(); + hpos = hpos_old + 1; + decide_line(hpos); + sync_copper(hpos); + decide_fetch_ce(hpos); + bpldma = is_bitplane_dma(hpos_old); + if (bltstate != BLT_done) { + if (!blitpri && blitter_nasty >= BLIT_NASTY && (cycle_line[hpos_old] & CYCLE_MASK) == 0 && !bpldma) { + alloc_cycle(hpos_old, CYCLE_CPUNASTY); + break; + } + decide_blitter(hpos); + // copper may have been waiting for the blitter + sync_copper(hpos); + } + if ((cycle_line[hpos_old] & CYCLE_MASK) == 0 && !bpldma) { + alloc_cycle(hpos_old, CYCLE_CPU); + break; + } + do_cycles(1 * CYCLE_UNIT); + /* bus was allocated to dma channel, wait for next cycle.. */ + } + return hpos_old; +} + +STATIC_INLINE void checknasty(int hpos, int vpos) +{ + if (blitter_nasty >= BLIT_NASTY && !(dmacon & DMA_BLITPRI)) + record_dma_event(DMA_EVENT_BLITNASTY, hpos, vpos); +} + +static void sync_ce020(void) +{ + unsigned long c; + int extra; + + c = get_cycles(); + extra = c & (CYCLE_UNIT - 1); + if (extra) { + extra = CYCLE_UNIT - extra; + do_cycles(extra); + } +} + +#define SETIFCHIP \ + if (addr < 0xd80000) \ + last_custom_value1 = v; + +uae_u32 wait_cpu_cycle_read(uaecptr addr, int mode) +{ + uae_u32 v = 0; + int hpos; + + hpos = dma_cycle(); + x_do_cycles_pre(CYCLE_UNIT); + +#ifdef DEBUGGER + struct dma_rec *dr = NULL; + if (debug_dma) { + int reg = 0x1000; + if (mode < 0) + reg |= 4; + else if (mode > 0) + reg |= 2; + else + reg |= 1; + dr = record_dma(reg, v, addr, hpos, vpos, mode == -2 || mode == 2 ? DMARECORD_CPU_I : DMARECORD_CPU_D); + checknasty(hpos, vpos); + } +#endif + switch (mode) + { + case -1: + v = get_long(addr); + break; + case -2: + v = get_longi(addr); + break; + case 1: + v = get_word(addr); + break; + case 2: + v = get_wordi(addr); + break; + case 0: + v = get_byte(addr); + break; + } + +#ifdef DEBUGGER + if (debug_dma) + dr->dat = v; +#endif + + x_do_cycles_post(CYCLE_UNIT, v); + + regs.chipset_latch_rw = regs.chipset_latch_read = v; + SETIFCHIP + return v; +} + +uae_u32 wait_cpu_cycle_read_ce020(uaecptr addr, int mode) +{ + uae_u32 v = 0; + int hpos; + + sync_ce020(); + hpos = dma_cycle(); + x_do_cycles_pre(CYCLE_UNIT); + +#ifdef DEBUGGER + struct dma_rec *dr = NULL; + if (debug_dma) { + int reg = 0x1000; + if (mode < 0) + reg |= 4; + else if (mode > 0) + reg |= 2; + else + reg |= 1; + dr = record_dma(reg, v, addr, hpos, vpos, mode == -2 || mode == 2 ? DMARECORD_CPU_I : DMARECORD_CPU_D); + checknasty(hpos, vpos); + } +#endif + switch (mode) { + case -1: + v = get_long(addr); + break; + case -2: + v = get_longi(addr); + break; + case 1: + v = get_word(addr); + break; + case 2: + v = get_wordi(addr); + break; + case 0: + v = get_byte(addr); + break; + } + +#ifdef DEBUGGER + if (debug_dma) + dr->dat = v; +#endif + + x_do_cycles_post(CYCLE_UNIT, v); + + regs.chipset_latch_rw = regs.chipset_latch_read = v; + SETIFCHIP + return v; +} + +void wait_cpu_cycle_write(uaecptr addr, int mode, uae_u32 v) +{ + int hpos; + + hpos = dma_cycle(); + x_do_cycles_pre(CYCLE_UNIT); + +#ifdef DEBUGGER + if (debug_dma) { + int reg = 0x1100; + if (mode < 0) + reg |= 4; + else if (mode > 0) + reg |= 2; + else + reg |= 1; + record_dma(reg, v, addr, hpos, vpos, DMARECORD_CPU_D); + checknasty(hpos, vpos); + } +#endif + + if (mode < 0) + put_long(addr, v); + else if (mode > 0) + put_word(addr, v); + else if (mode == 0) + put_byte(addr, v); + + x_do_cycles_post(CYCLE_UNIT, v); + + regs.chipset_latch_rw = regs.chipset_latch_write = v; + SETIFCHIP +} + +void wait_cpu_cycle_write_ce020(uaecptr addr, int mode, uae_u32 v) +{ + int hpos; + + sync_ce020(); + hpos = dma_cycle(); + x_do_cycles_pre(CYCLE_UNIT); + +#ifdef DEBUGGER + if (debug_dma) { + int reg = 0x1100; + if (mode < 0) + reg |= 4; + else if (mode > 0) + reg |= 2; + else + reg |= 1; + record_dma(reg, v, addr, hpos, vpos, DMARECORD_CPU_D); + checknasty(hpos, vpos); + } +#endif + + if (mode < 0) + put_long(addr, v); + else if (mode > 0) + put_word(addr, v); + else if (mode == 0) + put_byte(addr, v); + + x_do_cycles_post(CYCLE_UNIT, v); + + regs.chipset_latch_rw = regs.chipset_latch_write = v; + SETIFCHIP +} + +void do_cycles_ce(unsigned long cycles) +{ + cycles += extra_cycle; + while (cycles >= CYCLE_UNIT) { + int hpos = current_hpos() + 1; + decide_line(hpos); + sync_copper(hpos); + decide_fetch_ce(hpos); + if (bltstate != BLT_done) + decide_blitter(hpos); + do_cycles(1 * CYCLE_UNIT); + cycles -= CYCLE_UNIT; + } + extra_cycle = cycles; +} + +void do_cycles_ce020(unsigned long cycles) +{ + unsigned long c; + int extra; + + if (!cycles) + return; + c = get_cycles(); + extra = c & (CYCLE_UNIT - 1); + if (extra) { + extra = CYCLE_UNIT - extra; + if (extra >= cycles) { + do_cycles(cycles); + return; + } + do_cycles(extra); + cycles -= extra; + } + c = cycles; + while (c) { + int hpos = current_hpos() + 1; + decide_line(hpos); + sync_copper(hpos); + decide_fetch_ce(hpos); + if (bltstate != BLT_done) + decide_blitter(hpos); + if (c < CYCLE_UNIT) + break; + do_cycles(1 * CYCLE_UNIT); + c -= CYCLE_UNIT; + } + if (c > 0) + do_cycles(c); +} + + +int is_cycle_ce(void) +{ + int hpos = current_hpos(); + return cycle_line[hpos] & CYCLE_MASK; +} + +#endif + +bool isvga(void) +{ + if (!(beamcon0 & 0x80)) + return false; + if (hblank_hz >= 20000) + return true; + return false; +} + +bool ispal(void) +{ + if (beamcon0 & 0x80) + return currprefs.ntscmode == 0; + return maxvpos_display >= MAXVPOS_NTSC + (MAXVPOS_PAL - MAXVPOS_NTSC) / 2; } diff --git a/src/disk.cpp b/src/disk.cpp index 9695dc19..28806651 100644 --- a/src/disk.cpp +++ b/src/disk.cpp @@ -1477,6 +1477,11 @@ void DISK_motordelay_func(uae_u32 v) floppy[v].motordelay = 0; } +static void motordelay_func(uae_u32 v) +{ + floppy[v].motordelay = 0; +} + static void drive_motor(drive* drv, bool off) { if (drv->motoroff && !off) @@ -1498,9 +1503,7 @@ static void drive_motor(drive* drv, bool off) if (currprefs.cpu_model <= 68010 && currprefs.m68k_speed == 0) { drv->motordelay = 1; - event2_newevent(ev2_disk_motor0 + (drv - floppy), 30, drv - floppy); - //TODO: enable when event2_newevent2 is implemented, replace the above - //event2_newevent2(30, drv - floppy, motordelay_func); + event2_newevent2(30, drv - floppy, motordelay_func); } } drv->motoroff = off; diff --git a/src/drawing.cpp b/src/drawing.cpp index 5c1013d8..099c5729 100644 --- a/src/drawing.cpp +++ b/src/drawing.cpp @@ -29,8 +29,10 @@ #include "sysconfig.h" #include "sysdeps.h" + #include #include + #include "options.h" #include "threaddep/thread.h" #include "uae.h" @@ -44,22 +46,41 @@ #include "drawing.h" #include "savestate.h" #include "statusline.h" -#include -#include - -#define VERTICAL_OFFSET 18; +#include "amiberry_gfx.h" extern int sprite_buffer_res; -int lores_factor; +static int lores_factor; +int lores_shift; -static void lores_reset() +static void pfield_set_linetoscr(void); + +int debug_bpl_mask = 0xff, debug_bpl_mask_one; + +static void lores_set(int lores) +{ + int old = lores; + lores_shift = lores; + if (lores_shift != old) + pfield_set_linetoscr(); +} + +static void lores_reset(void) { lores_factor = currprefs.gfx_resolution ? 2 : 1; - + lores_set(currprefs.gfx_resolution); + if (doublescan > 0) { + if (lores_shift < 2) + lores_shift++; + lores_factor = 2; + lores_set(lores_shift); + } sprite_buffer_res = currprefs.gfx_resolution; + if (doublescan > 0 && sprite_buffer_res < RES_SUPERHIRES) + sprite_buffer_res++; } bool aga_mode; /* mirror of chipset_mask & CSMASK_AGA */ +bool direct_rgb; /* The shift factor to apply when converting between Amiga coordinates and window coordinates. Zero if the resolution is the same, positive if window coordinates @@ -67,6 +88,18 @@ bool aga_mode; /* mirror of chipset_mask & CSMASK_AGA */ coordinates have a lower resolution (i.e. we're shrinking the image). */ static int res_shift; +static int linedbl, linedbld; + +int interlace_seen; +int detected_screen_resolution; + +#define AUTO_LORES_FRAMES 10 +static int can_use_lores = 0, frame_res, frame_res_lace; +static int resolution_count[RES_MAX + 1], lines_count; +static bool center_reset; +static bool init_genlock_data; +bool need_genlock_data; + /* Lookup tables for dual playfields. The dblpf_*1 versions are for the case that playfield 1 has the priority, dbplpf_*2 are used if playfield 2 has priority. If we need an array for non-dual playfield mode, it has no number. */ @@ -74,60 +107,94 @@ static int res_shift; to contain two 16 bit words, with the appropriate mask if pf1 is in the foreground being at bit offset 0, the one used if pf2 is in front being at offset 16. */ -static int dblpf_ms1[256], dblpf_ms2[256]; + +static int dblpf_ms1[256], dblpf_ms2[256], dblpf_ms[256]; static int dblpf_ind1[256], dblpf_ind2[256]; static int dblpf_2nd1[256], dblpf_2nd2[256]; -static const int dblpfofs[] = {0, 2, 4, 8, 16, 32, 64, 128}; +static const int dblpfofs[] = { 0, 2, 4, 8, 16, 32, 64, 128 }; + +static int sprite_offs[256]; -static int sprite_col_nat[65536]; -static int sprite_col_at[65536]; -static int sprite_bit[65536]; static uae_u32 clxtab[256]; /* Video buffer description structure. Filled in by the graphics system * dependent code. */ + struct vidbuf_description gfxvidinfo; /* OCS/ECS color lookup table. */ xcolnr xcolors[4096]; -static uae_u8 spritepixels[MAX_PIXELS_PER_LINE * 5]; /* used when sprite resolution > lores */ +struct spritepixelsbuf +{ + uae_u8 attach; + uae_u8 stdata; + uae_u16 data; +}; + +static struct spritepixelsbuf spritepixels_buffer[MAX_PIXELS_PER_LINE]; +static struct spritepixelsbuf *spritepixels; static int sprite_first_x, sprite_last_x; +#ifdef AGA /* AGA mode color lookup tables */ unsigned int xredcolors[256], xgreencolors[256], xbluecolors[256]; static int dblpf_ind1_aga[256], dblpf_ind2_aga[256]; +#else +static uae_u8 spriteagadpfpixels[1]; +static int dblpf_ind1_aga[1], dblpf_ind2_aga[1]; +#endif +int xredcolor_s, xredcolor_b, xredcolor_m; +int xgreencolor_s, xgreencolor_b, xgreencolor_m; +int xbluecolor_s, xbluecolor_b, xbluecolor_m; struct color_entry colors_for_drawing; +static struct color_entry direct_colors_for_drawing; + +static xcolnr *p_acolors; +static xcolnr *p_xcolors; /* The size of these arrays is pretty arbitrary; it was chosen to be "more - than enough". The coordinates used for indexing into these arrays are - almost, but not quite, Amiga coordinates (there's a constant offset). */ -static union pixdata_u -{ +than enough". The coordinates used for indexing into these arrays are +almost, but not quite, Amiga coordinates (there's a constant offset). */ +static union { + /* Let's try to align this thing. */ + double uupzuq; + long int cruxmedo; uae_u8 apixels[MAX_PIXELS_PER_LINE * 2]; uae_u16 apixels_w[MAX_PIXELS_PER_LINE * 2 / sizeof(uae_u16)]; uae_u32 apixels_l[MAX_PIXELS_PER_LINE * 2 / sizeof(uae_u32)]; } pixdata; +static uae_u8 *refresh_indicator_buffer; +static uae_u8 *refresh_indicator_changed, *refresh_indicator_changed_prev; +static int refresh_indicator_height; + uae_u16 spixels[2 * MAX_SPR_PIXELS]; /* Eight bits for every pixel. */ union sps_union spixstate; -static uae_u16 ham_linebuf[MAX_PIXELS_PER_LINE * 2]; +static uae_u32 ham_linebuf[MAX_PIXELS_PER_LINE * 2]; +static uae_u8 *real_bplpt[8]; -static uae_u8* xlinebuffer; +static uae_u8 all_ones[MAX_PIXELS_PER_LINE]; +static uae_u8 all_zeros[MAX_PIXELS_PER_LINE]; + +uae_u8 *xlinebuffer, *xlinebuffer_genlock; static int *amiga2aspect_line_map, *native2amiga_line_map; -static uae_u8** row_map; +static uae_u8 **row_map; +static uae_u8 *row_map_genlock_buffer; static uae_u8 row_tmp[MAX_PIXELS_PER_LINE * 32 / 8]; static int max_drawn_amiga_line; +uae_u8 **row_map_genlock; +uae_u8 *row_map_color_burst_buffer; /* line_draw_funcs: pfield_do_linetoscr, pfield_do_fill_line, decode_ham */ -typedef void (*line_draw_func)(int, int); +typedef void(*line_draw_func)(int, int, bool); #define LINE_UNDECIDED 1 #define LINE_DECIDED 2 @@ -139,80 +206,85 @@ typedef void (*line_draw_func)(int, int); #define LINE_DONE_AS_PREVIOUS 8 #define LINE_REMEMBERED_AS_PREVIOUS 9 -static int linestate_first_undecided = 0; +#define LINESTATE_SIZE ((MAXVPOS + 2) * 2 + 1) + +static uae_u8 linestate[LINESTATE_SIZE]; uae_u8 line_data[(MAXVPOS + 2) * 2][MAX_PLANES * MAX_WORDS_PER_LINE * 2]; +/* Centering variables. */ +static int min_diwstart, max_diwstop; /* The visible window: VISIBLE_LEFT_BORDER contains the left border of the visible - area, VISIBLE_RIGHT_BORDER the right border. These are in window coordinates. */ -static int visible_left_border, visible_right_border; -static int linetoscr_x_adjust_bytes; +area, VISIBLE_RIGHT_BORDER the right border. These are in window coordinates. */ +int visible_left_border, visible_right_border; +/* Pixels outside of visible_start and visible_stop are always black */ +static int visible_left_start, visible_right_stop; +static int visible_top_start, visible_bottom_stop; +/* same for hblank */ +static int hblank_left_start, hblank_right_stop; + +static int linetoscr_x_adjust_pixbytes, linetoscr_x_adjust_pixels; static int thisframe_y_adjust; static int thisframe_y_adjust_real, max_ypos_thisframe, min_ypos_for_screen; +int thisframe_first_drawn_line, thisframe_last_drawn_line; + +/* A frame counter that forces a redraw after at least one skipped frame in +interlace mode. */ +static int last_redraw_point; + +#define MAX_STOP 30000 +static int first_drawn_line, last_drawn_line; +static int first_block_line, last_block_line; + +#define NO_BLOCK -3 /* These are generated by the drawing code from the line_decisions array for - each line that needs to be drawn. These are basically extracted out of - bit fields in the hardware registers. */ -static int bplehb, bplham, bpldualpf, bpldualpfpri, bpldualpf2of, bplplanecnt; +each line that needs to be drawn. These are basically extracted out of +bit fields in the hardware registers. */ +static int bplehb, bplham, bpldualpf, bpldualpfpri, bpldualpf2of, bplplanecnt, ecsshres; +static int bplbypass, bplcolorburst, bplcolorburst_field; +static bool issprites; static int bplres; -static int plf1pri, plf2pri, bplxor; +static int plf1pri, plf2pri, bplxor, bpland, bpldelay_sh; static uae_u32 plf_sprite_mask; -static uae_u32 plf_sprite_mask_n16; -static int sbasecol[2] = {16, 16}; +static int sbasecol[2] = { 16, 16 }; +static int hposblank; +static bool specialmonitoron; +static bool ecs_genlock_features_active; +static uae_u8 ecs_genlock_features_mask; +static bool ecs_genlock_features_colorkey; +static int hsync_shift_hack; -bool picasso_requested_on; -bool picasso_on; +bool picasso_requested_on, picasso_requested_forced_on, picasso_on; int inhibit_frame; -int framecnt = 0; +int framecnt; +int custom_frame_redraw_necessary; +static int frame_redraw_necessary; +static int picasso_redraw_necessary; /* Calculate idle time (time to wait for vsync) */ -int idletime_frames = 0; -unsigned long idletime_time = 0; int idletime_percent = 0; -#define IDLETIME_FRAMES 20 -long time_per_frame = 20000; // Default for PAL (50 Hz): 20000 microsecs -// Temporary define -#define OFFSET_FREE_CPU_CYCLES 1500 -#define STEP_CYCLES 250 +#define xlinecheck(start, end) -void adjust_idletime(long ms_waited) +static void clearbuffer(struct vidbuffer *dst) { - if (ms_waited == -1) - { - // Frame miss... - idletime_percent = 0; - ms_waited = 0; - } - - idletime_frames++; - idletime_time += ms_waited; - if (idletime_frames >= IDLETIME_FRAMES) - { - unsigned long ms_for_frames = time_per_frame * idletime_frames * (1 + currprefs.gfx_framerate); - idletime_percent = idletime_time * 100 / ms_for_frames; - if (idletime_percent < 0) - idletime_percent = 0; - else if (idletime_percent > 100) - idletime_percent = 100; - idletime_time = 0; - idletime_frames = 0; - } - - if (currprefs.m68k_speed < 0) - { - if (ms_waited < (500 + OFFSET_FREE_CPU_CYCLES) && speedup_timelimit > -10000) - speedup_timelimit -= STEP_CYCLES; - else if (ms_waited > (1400 + OFFSET_FREE_CPU_CYCLES) && speedup_timelimit < -1000) - speedup_timelimit += STEP_CYCLES; + if (!dst->bufmem_allocated) + return; + uae_u8 *p = dst->bufmem_allocated; + for (int y = 0; y < dst->height_allocated; y++) { + memset(p, 0, dst->width_allocated * dst->pixbytes); + p += dst->rowbytes; } } -void reset_decision_table() +static void reset_decision_table(void) { - linestate_first_undecided = 0; + for (int i = 0; i < sizeof linestate / sizeof *linestate; i++) { + linestate[i] = LINE_UNDECIDED; + } } STATIC_INLINE void count_frame() @@ -233,20 +305,14 @@ STATIC_INLINE int xshift(int x, int shift) int coord_native_to_amiga_x(int x) { - if (gfxvidinfo.outwidth > 600) - { - x += (visible_left_border << 1); - return x + 2 * DISPLAY_LEFT_SHIFT - 2 * DIW_DDF_OFFSET; - } - x += visible_left_border; - x <<= (1 - lores_shift); + x = xshift(x, 1 - lores_shift); return x + 2 * DISPLAY_LEFT_SHIFT - 2 * DIW_DDF_OFFSET; } int coord_native_to_amiga_y(int y) { - return native2amiga_line_map[y]; + return native2amiga_line_map[y] + thisframe_y_adjust - minfirstline; } STATIC_INLINE int res_shift_from_window(int x) @@ -263,9 +329,382 @@ STATIC_INLINE int res_shift_from_amiga(int x) return x << -res_shift; } +void notice_screen_contents_lost(void) +{ + picasso_redraw_necessary = 1; + frame_redraw_necessary = 2; +} + +bool isnativevidbuf(void) +{ + // we always use the SDL surface as the drawbuffer + return true; +} + +extern int plffirstline_total, plflastline_total; +extern int first_planes_vpos, last_planes_vpos; +extern int diwfirstword_total, diwlastword_total; +extern int ddffirstword_total, ddflastword_total; +extern bool vertical_changed, horizontal_changed; +extern int firstword_bplcon1; +extern int lof_store; + +#define MIN_DISPLAY_W 256 +#define MIN_DISPLAY_H 192 +#define MAX_DISPLAY_W 362 +#define MAX_DISPLAY_H 283 + +static int gclow, gcloh, gclox, gcloy, gclorealh; +static int stored_left_start, stored_top_start, stored_width, stored_height; + +void get_custom_topedge(int *xp, int *yp, bool max) +{ + if (isnativevidbuf() && !max) { + int x, y; + x = visible_left_border + (DISPLAY_LEFT_SHIFT << currprefs.gfx_resolution); + y = minfirstline << currprefs.gfx_vresolution; + + *xp = x; + *yp = y; + } + else { + *xp = 0; + *yp = 0; + } +} + +static void reset_custom_limits(void) +{ + gclow = gcloh = gclox = gcloy = 0; + gclorealh = -1; + center_reset = true; +} + +static void set_blanking_limits(void) +{ + hblank_left_start = visible_left_start; + hblank_right_stop = visible_right_stop; + + //if (programmedmode) { + // if (hblank_left_start < coord_hw_to_window_x(hsyncendpos * 2)) + // hblank_left_start = coord_hw_to_window_x(hsyncendpos * 2); + // if (hblank_right_stop > coord_hw_to_window_x(hsyncstartpos * 2)) + // hblank_right_stop = coord_hw_to_window_x(hsyncstartpos * 2); + //} +} + +void get_custom_raw_limits(int *pw, int *ph, int *pdx, int *pdy) +{ + if (stored_width > 0) { + *pw = stored_width; + *ph = stored_height; + *pdx = stored_left_start; + *pdy = stored_top_start; + } + else { + int x = visible_left_border; + if (x < visible_left_start) + x = visible_left_start; + *pdx = x; + int x2 = visible_right_border; + if (x2 > visible_right_stop) + x2 = visible_right_stop; + *pw = x2 - x; + int y = min_ypos_for_screen; + if (y < visible_top_start) + y = visible_top_start; + *pdy = y; + int y2 = max_ypos_thisframe; + if (y2 > visible_bottom_stop) + y2 = visible_bottom_stop; + *ph = y2 - y; + } +} + +void set_custom_limits(int w, int h, int dx, int dy) +{ + int vls = visible_left_start; + int vrs = visible_right_stop; + int vts = visible_top_start; + int vbs = visible_bottom_stop; + + if (w <= 0 || dx < 0) { + visible_left_start = 0; + visible_right_stop = MAX_STOP; + } + else { + visible_left_start = visible_left_border + dx; + visible_right_stop = visible_left_start + w; + } + if (h <= 0 || dy < 0) { + visible_top_start = 0; + visible_bottom_stop = MAX_STOP; + } + else { + visible_top_start = min_ypos_for_screen + dy; + visible_bottom_stop = visible_top_start + h; + } + if (vls != visible_left_start || vrs != visible_right_stop || + vts != visible_top_start || vbs != visible_bottom_stop) + notice_screen_contents_lost(); + + set_blanking_limits(); +} + +void store_custom_limits(int w, int h, int x, int y) +{ + stored_left_start = x; + stored_top_start = y; + stored_width = w; + stored_height = h; +} + +int get_custom_limits(int *pw, int *ph, int *pdx, int *pdy, int *prealh) +{ + int w, h, dx, dy, y1, y2, dbl1, dbl2; + int ret = 0; + + if (!pw || !ph || !pdx || !pdy) { + reset_custom_limits(); + return 0; + } + + if (!isnativevidbuf()) { + *pw = gfxvidinfo.outwidth; + *ph = gfxvidinfo.outheight; + *pdx = 0; + *pdy = 0; + *prealh = -1; + return 1; + } + + *pw = gclow; + *ph = gcloh; + *pdx = gclox; + *pdy = gcloy; + *prealh = gclorealh; + + if (gclow > 0 && gcloh > 0) + ret = -1; + + if (interlace_seen) { + static int interlace_count; + // interlace = only use long frames + if (lof_store && (interlace_count & 1) == 0) + interlace_count++; + if (!lof_store && (interlace_count & 1) != 0) + interlace_count++; + if (interlace_count < 3) + return ret; + if (!lof_store) + return ret; + interlace_count = 0; + /* program may have set last visible line as last possible line (CD32 boot screen) */ + if (last_planes_vpos < maxvpos) + last_planes_vpos++; + if (plflastline_total < maxvpos) + plflastline_total++; + } + + if (plflastline_total < 4) + plflastline_total = last_planes_vpos; + + ddffirstword_total = coord_hw_to_window_x(ddffirstword_total * 2 + DIW_DDF_OFFSET); + ddflastword_total = coord_hw_to_window_x(ddflastword_total * 2 + DIW_DDF_OFFSET); + + if (doublescan <= 0 && !programmedmode) { + int min = coord_diw_to_window_x(92); + int max = coord_diw_to_window_x(460); + if (diwfirstword_total < min) + diwfirstword_total = min; + if (diwlastword_total > max) + diwlastword_total = max; + if (ddffirstword_total < min) + ddffirstword_total = min; + if (ddflastword_total > max) + ddflastword_total = max; + } + + w = diwlastword_total - diwfirstword_total; + dx = diwfirstword_total - visible_left_border; + + y2 = plflastline_total; + if (y2 > last_planes_vpos) + y2 = last_planes_vpos; + y1 = plffirstline_total; + if (first_planes_vpos > y1) + y1 = first_planes_vpos; + if (minfirstline > y1) + y1 = minfirstline; + + dbl2 = dbl1 = currprefs.gfx_vresolution; + if (doublescan > 0 && interlace_seen <= 0) { + dbl1--; + dbl2--; + } + + h = y2 - y1; + dy = y1 - minfirstline; + + if (first_planes_vpos == 0) { + // no planes enabled during frame + if (ret < 0) + return 1; + h = currprefs.ntscmode ? 200 : 240; + w = 320 << currprefs.gfx_resolution; + dy = 36 / 2; + dx = 58; + } + + if (dx < 0) + dx = 0; + + *prealh = -1; + if (!programmedmode && first_planes_vpos) { + int th = (maxvpos - minfirstline) * 95 / 100; + if (th > h) { + th = xshift(th, dbl1); + *prealh = th; + } + } + + dy = xshift(dy, dbl2); + h = xshift(h, dbl1); + + if (w == 0 || h == 0) + return 0; + + if (doublescan <= 0 && !programmedmode) { + if ((w >> currprefs.gfx_resolution) < MIN_DISPLAY_W) { + dx += (w - (MIN_DISPLAY_W << currprefs.gfx_resolution)) / 2; + w = MIN_DISPLAY_W << currprefs.gfx_resolution; + } + if ((h >> dbl1) < MIN_DISPLAY_H) { + dy += (h - (MIN_DISPLAY_H << dbl1)) / 2; + h = MIN_DISPLAY_H << dbl1; + } + if ((w >> currprefs.gfx_resolution) > MAX_DISPLAY_W) { + dx += (w - (MAX_DISPLAY_W << currprefs.gfx_resolution)) / 2; + w = MAX_DISPLAY_W << currprefs.gfx_resolution; + } + if ((h >> dbl1) > MAX_DISPLAY_H) { + dy += (h - (MAX_DISPLAY_H << dbl1)) / 2; + h = MAX_DISPLAY_H << dbl1; + } + } + + if (gclow == w && gcloh == h && gclox == dx && gcloy == dy) + return ret; + + if (w <= 0 || h <= 0 || dx < 0 || dy < 0) + return ret; + if (doublescan <= 0 && !programmedmode) { + if (dx > gfxvidinfo.outwidth / 3) + return ret; + if (dy > gfxvidinfo.outheight / 3) + return ret; + } + + gclow = w; + gcloh = h; + gclox = dx; + gcloy = dy; + gclorealh = *prealh; + *pw = w; + *ph = h; + *pdx = dx; + *pdy = dy; +#if 1 + write_log(_T("Display Size: %dx%d Offset: %dx%d\n"), w, h, dx, dy); + write_log(_T("First: %d Last: %d MinV: %d MaxV: %d Min: %d\n"), + plffirstline_total, plflastline_total, + first_planes_vpos, last_planes_vpos, minfirstline); +#endif + center_reset = true; + return 1; +} + +void get_custom_mouse_limits(int *pw, int *ph, int *pdx, int *pdy, int dbl) +{ + int delay1, delay2; + int w, h, dx, dy, dbl1, dbl2, y1, y2; + + w = diwlastword_total - diwfirstword_total; + dx = diwfirstword_total - visible_left_border; + + y2 = plflastline_total; + if (y2 > last_planes_vpos) + y2 = last_planes_vpos; + y1 = plffirstline_total; + if (first_planes_vpos > y1) + y1 = first_planes_vpos; + if (minfirstline > y1) + y1 = minfirstline; + + h = y2 - y1; + dy = y1 - minfirstline; + + if (*pw > 0) + w = *pw; + + w = xshift(w, res_shift); + + if (*ph > 0) + h = *ph; + + delay1 = (firstword_bplcon1 & 0x0f) | ((firstword_bplcon1 & 0x0c00) >> 6); + delay2 = ((firstword_bplcon1 >> 4) & 0x0f) | (((firstword_bplcon1 >> 4) & 0x0c00) >> 6); + // if (delay1 == delay2) + // dx += delay1; + + dx = xshift(dx, res_shift); + + dbl2 = dbl1 = currprefs.gfx_vresolution; + if ((doublescan > 0 || interlace_seen > 0) && !dbl) { + dbl1--; + dbl2--; + } + if (interlace_seen > 0) + dbl2++; + if (interlace_seen <= 0 && dbl) + dbl2--; + h = xshift(h, dbl1); + dy = xshift(dy, dbl2); + + if (w < 1) + w = 1; + if (h < 1) + h = 1; + if (dx < 0) + dx = 0; + if (dy < 0) + dy = 0; + *pw = w; *ph = h; + *pdx = dx; *pdy = dy; +} + static struct decision* dp_for_drawing; static struct draw_info* dip_for_drawing; +/* Record DIW of the current line for use by centering code. */ +void record_diw_line(int plfstrt, int first, int last) +{ + if (last > max_diwstop) + max_diwstop = last; + if (first < min_diwstart) { + min_diwstart = first; + } +} + +STATIC_INLINE int get_shdelay_add(void) +{ + if (bplres == RES_SUPERHIRES) + return 0; + int add = bpldelay_sh; + add >>= RES_MAX - currprefs.gfx_resolution; + return add; +} + /* * Screen update macros/functions */ @@ -275,123 +714,75 @@ static struct draw_info* dip_for_drawing; All of these are forced into the visible window (VISIBLE_LEFT_BORDER .. VISIBLE_RIGHT_BORDER). PLAYFIELD_START and PLAYFIELD_END are in window coordinates. */ static int playfield_start, playfield_end; +static int real_playfield_start, real_playfield_end; +static int sprite_playfield_start; +static bool may_require_hard_way; +static int linetoscr_diw_start, linetoscr_diw_end; +static int native_ddf_left, native_ddf_right; + static int pixels_offset; -static int src_pixel, ham_src_pixel; +static int src_pixel; /* How many pixels in window coordinates which are to the left of the left border. */ static int unpainted; -#include "linetoscr.c" - -static void pfield_do_linetoscr_0_640(int start, int stop) -{ - int local_res_shift = 1 - bplres; // stretch LORES, nothing for HIRES, shrink for SUPERHIRES - start = start << 1; - stop = stop << 1; - - if (local_res_shift == 0) - src_pixel = linetoscr_16(src_pixel, start, stop); - else if (local_res_shift == 1) - src_pixel = linetoscr_16_stretch1(src_pixel, start, stop); - else //if (local_res_shift == -1) - src_pixel = linetoscr_16_shrink1(src_pixel, start, stop); -} - -static void pfield_do_linetoscr_0_640_AGA(int start, int stop) -{ - int local_res_shift = 1 - bplres; // stretch LORES, nothing for HIRES, shrink for SUPERHIRES - start = start << 1; - stop = stop << 1; - - if (local_res_shift == 0) - src_pixel = linetoscr_16_aga(src_pixel, start, stop); - else if (local_res_shift == 1) - src_pixel = linetoscr_16_stretch1_aga(src_pixel, start, stop); - else //if (local_res_shift == -1) - src_pixel = linetoscr_16_shrink1_aga(src_pixel, start, stop); -} - -static void pfield_do_linetoscr_0(int start, int stop) -{ - if (res_shift == 0) - src_pixel = linetoscr_16(src_pixel, start, stop); - //else if (res_shift == 1) //can't happen, target is lores - // src_pixel = linetoscr_16_stretch1 (src_pixel, start, stop); - else //if (res_shift == -1) - src_pixel = linetoscr_16_shrink1(src_pixel, start, stop); -} - -static void pfield_do_linetoscr_0_AGA(int start, int stop) -{ - if (res_shift == 0) - src_pixel = linetoscr_16_aga(src_pixel, start, stop); - //else if (res_shift == 1) //can't happen, target is lores - // src_pixel = linetoscr_16_stretch1_aga (src_pixel, start, stop); - else //if (res_shift == -1) - src_pixel = linetoscr_16_shrink1_aga(src_pixel, start, stop); -} - STATIC_INLINE xcolnr getbgc(bool blank) { - return (blank || colors_for_drawing.extra) ? 0 : colors_for_drawing.acolors[0]; + return (blank || hposblank || ce_is_borderblank(colors_for_drawing.extra)) ? 0 : colors_for_drawing.acolors[0]; } -static void pfield_do_fill_line_0_640(int start, int stop) +static void set_res_shift(int shift) { - uae_u16* b = &(reinterpret_cast(xlinebuffer)[start << 1]); - xcolnr col = getbgc(false); - int i; - int max = (stop - start) << 1; - for (i = 0; i < max; i++ , b++) - *b = col; + int old = res_shift; + res_shift = shift; + if (res_shift != old) + pfield_set_linetoscr(); } -static void pfield_do_fill_line_0(int start, int stop) -{ - uae_u16* b = &(reinterpret_cast(xlinebuffer)[start]); - xcolnr col = getbgc(false); - int i; - int max = (stop - start); - for (i = 0; i < max; i++ , b++) - *b = col; -} - -static line_draw_func pfield_do_linetoscr = line_draw_func(pfield_do_linetoscr_0); -static line_draw_func pfield_do_fill_line = line_draw_func(pfield_do_fill_line_0); - /* Initialize the variables necessary for drawing a line. - * This involves setting up start/stop positions and display window - * borders. */ -static void pfield_init_linetoscr() +* This involves setting up start/stop positions and display window +* borders. */ +static void pfield_init_linetoscr(bool border) { /* First, get data fetch start/stop in DIW coordinates. */ int ddf_left = dp_for_drawing->plfleft * 2 + DIW_DDF_OFFSET; int ddf_right = dp_for_drawing->plfright * 2 + DIW_DDF_OFFSET; int leftborderhidden; + int native_ddf_left2; + + hsync_shift_hack = 0; + + if (border) + ddf_left = DISPLAY_LEFT_SHIFT; /* Compute datafetch start/stop in pixels; native display coordinates. */ - int native_ddf_left = coord_hw_to_window_x(ddf_left); - int native_ddf_right = coord_hw_to_window_x(ddf_right); + native_ddf_left = coord_hw_to_window_x(ddf_left); + native_ddf_right = coord_hw_to_window_x(ddf_right); - int linetoscr_diw_start = dp_for_drawing->diwfirstword; - int linetoscr_diw_end = dp_for_drawing->diwlastword; + // Blerkenwiegel/Scoopex workaround + native_ddf_left2 = native_ddf_left; + if (native_ddf_left < 0) + native_ddf_left = 0; - if (dip_for_drawing->nr_sprites == 0) - { - if (linetoscr_diw_start < native_ddf_left) - linetoscr_diw_start = native_ddf_left; - if (linetoscr_diw_end > native_ddf_right) - linetoscr_diw_end = native_ddf_right; - } + if (native_ddf_right < native_ddf_left) + native_ddf_right = native_ddf_left; + + linetoscr_diw_start = dp_for_drawing->diwfirstword; + linetoscr_diw_end = dp_for_drawing->diwlastword; /* Perverse cases happen. */ if (linetoscr_diw_end < linetoscr_diw_start) linetoscr_diw_end = linetoscr_diw_start; - res_shift = lores_shift - bplres; + set_res_shift(lores_shift - bplres); playfield_start = linetoscr_diw_start; playfield_end = linetoscr_diw_end; + if (playfield_start < native_ddf_left) + playfield_start = native_ddf_left; + if (playfield_end > native_ddf_right) + playfield_end = native_ddf_right; + if (playfield_start < visible_left_border) playfield_start = visible_left_border; if (playfield_start > visible_right_border) @@ -401,16 +792,45 @@ static void pfield_init_linetoscr() if (playfield_end > visible_right_border) playfield_end = visible_right_border; - if (dp_for_drawing->bordersprite_seen && !colors_for_drawing.extra && dip_for_drawing->nr_sprites) - { + real_playfield_start = playfield_start; + sprite_playfield_start = playfield_start; + real_playfield_end = playfield_end; + + // Sprite hpos don't include DIW_DDF_OFFSET and can appear 1 lores pixel + // before first bitplane pixel appears. + // This means "bordersprite" condition is possible under OCS/ECS too. Argh! + if (dip_for_drawing->nr_sprites) { + if (!ce_is_borderblank(colors_for_drawing.extra)) { + /* bordersprite off or not supported: sprites are visible until diw_end */ + if (playfield_end < linetoscr_diw_end && hblank_right_stop > playfield_end) { + playfield_end = linetoscr_diw_end; + } + int left = coord_hw_to_window_x(dp_for_drawing->plfleft * 2); + if (left < visible_left_border) + left = visible_left_border; + if (left < playfield_start && left >= linetoscr_diw_start) { + playfield_start = left; + } + } + else { + sprite_playfield_start = 0; + if (playfield_end < linetoscr_diw_end && hblank_right_stop > playfield_end) { + playfield_end = linetoscr_diw_end; + } + } + } + +#ifdef AGA + may_require_hard_way = false; + if (dp_for_drawing->bordersprite_seen && !ce_is_borderblank(colors_for_drawing.extra) && dip_for_drawing->nr_sprites) { int min = visible_right_border, max = visible_left_border, i; - for (i = 0; i < dip_for_drawing->nr_sprites; i++) - { + for (i = 0; i < dip_for_drawing->nr_sprites; i++) { int x; x = curr_sprite_entries[dip_for_drawing->first_sprite_entry + i].pos; if (x < min) min = x; - x = curr_sprite_entries[dip_for_drawing->first_sprite_entry + i].max; + // include max extra pixels, sprite may be 2x or 4x size: 4x - 1. + x = curr_sprite_entries[dip_for_drawing->first_sprite_entry + i].max + (4 - 1); if (x > max) max = x; } @@ -425,44 +845,66 @@ static void pfield_init_linetoscr() playfield_end = max; if (playfield_end > visible_right_border) playfield_end = visible_right_border; + sprite_playfield_start = 0; + may_require_hard_way = true; } +#endif unpainted = visible_left_border < playfield_start ? 0 : visible_left_border - playfield_start; - ham_src_pixel = MAX_PIXELS_PER_LINE + res_shift_from_window(playfield_start - native_ddf_left); unpainted = res_shift_from_window(unpainted); - if (sprite_first_x < sprite_last_x) - { - uae_u8* p = spritepixels + sprite_first_x; - int len = sprite_last_x - sprite_first_x + 1; - int i; - /* clear previous sprite data storage line */ - memset(p, 0, len); - - sprite_last_x = 0; - sprite_first_x = MAX_PIXELS_PER_LINE - 1; + int first_x = sprite_first_x; + int last_x = sprite_last_x; + if (first_x < last_x) { + if (dp_for_drawing->bordersprite_seen && !ce_is_borderblank(colors_for_drawing.extra)) { + if (first_x > visible_left_border) + first_x = visible_left_border; + if (last_x < visible_right_border) + last_x = visible_right_border; + } + if (first_x < 0) + first_x = 0; + if (last_x > MAX_PIXELS_PER_LINE - 2) + last_x = MAX_PIXELS_PER_LINE - 2; + if (first_x < last_x) + memset(spritepixels + first_x, 0, sizeof(struct spritepixelsbuf) * (last_x - first_x + 1)); } + sprite_last_x = 0; + sprite_first_x = MAX_PIXELS_PER_LINE - 1; + /* Now, compute some offsets. */ ddf_left -= DISPLAY_LEFT_SHIFT; + pixels_offset = MAX_PIXELS_PER_LINE - (ddf_left << bplres); ddf_left <<= bplres; - pixels_offset = MAX_PIXELS_PER_LINE - ddf_left; - leftborderhidden = playfield_start - native_ddf_left; + leftborderhidden = playfield_start - native_ddf_left2; + if (hblank_left_start > playfield_start) + leftborderhidden += hblank_left_start - playfield_start; src_pixel = MAX_PIXELS_PER_LINE + res_shift_from_window(leftborderhidden); if (dip_for_drawing->nr_sprites == 0) return; + if (aga_mode) { + int add = get_shdelay_add(); + if (add) { + if (sprite_playfield_start > 0) { + sprite_playfield_start -= add; + } + else { + ;// this is most likely wrong: playfield_start -= add; + } + } + } + /* We need to clear parts of apixels. */ - if (linetoscr_diw_start < native_ddf_left) - { + if (linetoscr_diw_start < native_ddf_left) { int size = res_shift_from_window(native_ddf_left - linetoscr_diw_start); linetoscr_diw_start = native_ddf_left; memset(pixdata.apixels + MAX_PIXELS_PER_LINE - size, 0, size); } - if (linetoscr_diw_end > native_ddf_right) - { + if (linetoscr_diw_end > native_ddf_right) { int pos = res_shift_from_window(native_ddf_right - native_ddf_left); int size = res_shift_from_window(linetoscr_diw_end - native_ddf_right); linetoscr_diw_start = native_ddf_left; @@ -470,22 +912,114 @@ static void pfield_init_linetoscr() } } -STATIC_INLINE void fill_line() +// erase sprite graphics in pixdata if they were outside of ddf +static void pfield_erase_hborder_sprites(void) { - int nints; - int* start; + if (sprite_first_x < native_ddf_left) { + int size = res_shift_from_window(native_ddf_left - sprite_first_x); + memset(pixdata.apixels + MAX_PIXELS_PER_LINE - size, 0, size); + } + if (sprite_last_x > native_ddf_right) { + int pos = res_shift_from_window(native_ddf_right - native_ddf_left); + int size = res_shift_from_window(sprite_last_x - native_ddf_right); + memset(pixdata.apixels + MAX_PIXELS_PER_LINE + pos, 0, size); + } +} + +// erase whole viewable area if sprite in upper or lower border +static void pfield_erase_vborder_sprites(void) +{ + if (visible_right_border <= visible_left_border) + return; + int pos = 0; + int size = 0; + if (visible_left_border < native_ddf_left) { + size = res_shift_from_window(native_ddf_left - visible_left_border); + pos = -size; + } + if (visible_right_border > native_ddf_left) + size += res_shift_from_window(visible_right_border - native_ddf_left); + memset(pixdata.apixels + MAX_PIXELS_PER_LINE - pos, 0, size); +} + +STATIC_INLINE uae_u16 merge_2pixel16(uae_u16 p1, uae_u16 p2) +{ + uae_u16 v = ((((p1 >> xredcolor_s) & xredcolor_m) + ((p2 >> xredcolor_s) & xredcolor_m)) / 2) << xredcolor_s; + v |= ((((p1 >> xbluecolor_s) & xbluecolor_m) + ((p2 >> xbluecolor_s) & xbluecolor_m)) / 2) << xbluecolor_s; + v |= ((((p1 >> xgreencolor_s) & xgreencolor_m) + ((p2 >> xgreencolor_s) & xgreencolor_m)) / 2) << xgreencolor_s; + return v; +} +STATIC_INLINE uae_u32 merge_2pixel32(uae_u32 p1, uae_u32 p2) +{ + uae_u32 v = ((((p1 >> 16) & 0xff) + ((p2 >> 16) & 0xff)) / 2) << 16; + v |= ((((p1 >> 8) & 0xff) + ((p2 >> 8) & 0xff)) / 2) << 8; + v |= ((((p1 >> 0) & 0xff) + ((p2 >> 0) & 0xff)) / 2) << 0; + return v; +} + +STATIC_INLINE void fill_line_16(uae_u8 *buf, int start, int stop, bool blank) +{ + uae_u16 *b = (uae_u16 *)buf; + unsigned int i; + unsigned int rem = 0; + xcolnr col = getbgc(blank); + if (((uintptr_t)&b[start]) & 1) + b[start++] = (uae_u16)col; + if (start >= stop) + return; + if (((uintptr_t)&b[stop]) & 1) { + rem++; + stop--; + } + for (i = start; i < stop; i += 2) { + uae_u32 *b2 = (uae_u32 *)&b[i]; + *b2 = col; + } + if (rem) + b[stop] = (uae_u16)col; +} + +STATIC_INLINE void fill_line_32(uae_u8 *buf, int start, int stop, bool blank) +{ + uae_u32 *b = (uae_u32 *)buf; + unsigned int i; + xcolnr col = getbgc(blank); + for (i = start; i < stop; i++) + b[i] = col; +} + +static void pfield_do_fill_line(int start, int stop, bool blank) +{ + if (stop <= start) + return; + switch (gfxvidinfo.pixbytes) { + case 2: fill_line_16(xlinebuffer, start, stop, blank); break; + case 4: fill_line_32(xlinebuffer, start, stop, blank); break; + } + if (need_genlock_data) { + memset(xlinebuffer_genlock + start, 0, stop - start); + } +} + +static void fill_line2(int startpos, int len) +{ + int shift; + int nints, nrem; + int *start; xcolnr val; - nints = gfxvidinfo.outwidth >> 1; - if (gfxvidinfo.outwidth > 600) - start = reinterpret_cast(static_cast(xlinebuffer) + (visible_left_border << 2)); - else - start = reinterpret_cast(static_cast(xlinebuffer) + (visible_left_border << 1)); + shift = 0; + if (gfxvidinfo.pixbytes == 2) + shift = 1; + if (gfxvidinfo.pixbytes == 4) + shift = 2; + nints = len >> (2 - shift); + nrem = nints & 7; + nints &= ~7; + start = (int *)(((uae_u8*)xlinebuffer) + (startpos << shift)); val = getbgc(false); - val |= val << 16; - for (; nints > 0; nints -= 8 , start += 8) - { + for (; nints > 0; nints -= 8, start += 8) { *start = val; *(start + 1) = val; *(start + 2) = val; @@ -495,9 +1029,855 @@ STATIC_INLINE void fill_line() *(start + 6) = val; *(start + 7) = val; } + + switch (nrem) { + case 7: + *start++ = val; + case 6: + *start++ = val; + case 5: + *start++ = val; + case 4: + *start++ = val; + case 3: + *start++ = val; + case 2: + *start++ = val; + case 1: + *start = val; + } } -static void dummy_worker(int start, int stop) +static void fill_line_border(int lineno) +{ + int lastpos = visible_left_border; + int endpos = visible_left_border + gfxvidinfo.outwidth; + + if (lineno < visible_top_start || lineno >= visible_bottom_stop) { + int b = hposblank; + hposblank = 3; + fill_line2(lastpos, gfxvidinfo.outwidth); + if (need_genlock_data) { + memset(xlinebuffer_genlock + lastpos, 0, gfxvidinfo.outwidth); + } + hposblank = b; + return; + } + + // full hblank + if (hposblank) { + hposblank = 3; + fill_line2(lastpos, gfxvidinfo.outwidth); + if (need_genlock_data) { + memset(xlinebuffer_genlock + lastpos, 0, gfxvidinfo.outwidth); + } + return; + } + // hblank not visible + if (hblank_left_start <= lastpos && hblank_right_stop >= endpos) { + fill_line2(lastpos, gfxvidinfo.outwidth); + if (need_genlock_data) { + memset(xlinebuffer_genlock + lastpos, 0, gfxvidinfo.outwidth); + } + return; + } + + // left, right or both hblanks visible + if (lastpos < hblank_left_start) { + int t = hblank_left_start < endpos ? hblank_left_start : endpos; + pfield_do_fill_line(lastpos, t, true); + lastpos = t; + } + if (lastpos < hblank_right_stop) { + int t = hblank_right_stop < endpos ? hblank_right_stop : endpos; + pfield_do_fill_line(lastpos, t, false); + lastpos = t; + } + if (lastpos < endpos) { + pfield_do_fill_line(lastpos, endpos, true); + } +} + +static int sprite_shdelay; +#define SPRITE_DEBUG 0 +static uae_u8 render_sprites(int pos, int dualpf, uae_u8 apixel, int aga) +{ + struct spritepixelsbuf *spb = &spritepixels[pos]; + unsigned int v = spb->data; + int *shift_lookup = dualpf ? (bpldualpfpri ? dblpf_ms2 : dblpf_ms1) : dblpf_ms; + int maskshift, plfmask; + + // shdelay hack, above &spritepixels[pos] is correct. + pos += sprite_shdelay; + /* The value in the shift lookup table is _half_ the shift count we + need. This is because we can't shift 32 bits at once (undefined + behaviour in C). */ + maskshift = shift_lookup[apixel]; + plfmask = (plf_sprite_mask >> maskshift) >> maskshift; + v &= ~plfmask; + /* Extra 1 sprite pixel at DDFSTRT is only possible if at least 1 plane is active */ + if ((bplplanecnt > 0 || pos >= sprite_playfield_start) && (v != 0 || SPRITE_DEBUG)) { + unsigned int vlo, vhi, col; + unsigned int v1 = v & 255; + /* OFFS determines the sprite pair with the highest priority that has + any bits set. E.g. if we have 0xFF00 in the buffer, we have sprite + pairs 01 and 23 cleared, and pairs 45 and 67 set, so OFFS will + have a value of 4. + 2 * OFFS is the bit number in V of the sprite pair, and it also + happens to be the color offset for that pair. + */ + int offs; + if (v1 == 0) + offs = 4 + sprite_offs[v >> 8]; + else + offs = sprite_offs[v1]; + + /* Shift highest priority sprite pair down to bit zero. */ + v >>= offs * 2; + v &= 15; +#if SPRITE_DEBUG > 0 + v ^= 8; +#endif + if (spb->attach && (spb->stdata & (3 << offs))) { + col = v; + if (aga) + col += sbasecol[1]; + else + col += 16; + } + else { + /* This sequence computes the correct color value. We have to select + either the lower-numbered or the higher-numbered sprite in the pair. + We have to select the high one if the low one has all bits zero. + If the lower-numbered sprite has any bits nonzero, (VLO - 1) is in + the range of 0..2, and with the mask and shift, VHI will be zero. + If the lower-numbered sprite is zero, (VLO - 1) is a mask of + 0xFFFFFFFF, and we select the bits of the higher numbered sprite + in VHI. + This is _probably_ more efficient than doing it with branches. */ + vlo = v & 3; + vhi = (v & (vlo - 1)) >> 2; + col = (vlo | vhi); + if (aga) { + if (vhi > 0) + col += sbasecol[1]; + else + col += sbasecol[0]; + } + else { + col += 16; + } + col += offs * 2; + } + + return col; + } + + return 0; +} + +static bool get_genlock_very_rare_and_complex_case(uae_u8 v) +{ + // border color without BRDNTRAN bit set = transparent + if (v == 0 && !ce_is_borderntrans(colors_for_drawing.extra)) + return false; + if (ecs_genlock_features_colorkey) { + // color key match? + if (currprefs.chipset_mask & CSMASK_AGA) { + if (colors_for_drawing.color_regs_aga[v] & 0x80000000) + return false; + } + else { + if (colors_for_drawing.color_regs_ecs[v] & 0x8000) + return false; + } + } + // plane mask match? + if (v & ecs_genlock_features_mask) + return false; + return true; +} +// false = transparent +STATIC_INLINE bool get_genlock_transparency(uae_u8 v) +{ + if (!ecs_genlock_features_active) { + if (v == 0) + return false; + return true; + } + else { + return get_genlock_very_rare_and_complex_case(v); + } +} + +#include "linetoscr.cpp" + +#define LTPARMS src_pixel, start, stop + +/* ECS SuperHires special cases */ + +#define PUTBPIX(x) buf[dpix] = (x); + +STATIC_INLINE uae_u32 shsprite(int dpix, uae_u32 spix_val, uae_u32 v, int spr) +{ + uae_u8 sprcol; + uae_u16 scol; + if (!spr) + return v; + sprcol = render_sprites(dpix, 0, spix_val, 0); + if (!sprcol) + return v; + /* good enough for now.. */ + scol = colors_for_drawing.color_regs_ecs[sprcol] & 0xccc; + scol |= scol >> 2; + return xcolors[scol]; +} + +static int NOINLINE linetoscr_16_sh_func(int spix, int dpix, int stoppos, int spr) +{ + uae_u16 *buf = (uae_u16 *)xlinebuffer; + + while (dpix < stoppos) { + uae_u16 spix_val1, spix_val2; + uae_u16 v; + int off; + spix_val1 = pixdata.apixels[spix++]; + spix_val2 = pixdata.apixels[spix++]; + off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); + v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; + v |= v >> 2; + PUTBPIX(shsprite(dpix, spix_val1, xcolors[v], spr)); + dpix++; + v = (colors_for_drawing.color_regs_ecs[off] & 0x333) << 2; + v |= v >> 2; + PUTBPIX(shsprite(dpix, spix_val2, xcolors[v], spr)); + dpix++; + } + return spix; +} +static int linetoscr_16_sh_spr(int spix, int dpix, int stoppos) +{ + return linetoscr_16_sh_func(spix, dpix, stoppos, true); +} +static int linetoscr_16_sh(int spix, int dpix, int stoppos) +{ + return linetoscr_16_sh_func(spix, dpix, stoppos, false); +} +static int NOINLINE linetoscr_32_sh_func(int spix, int dpix, int stoppos, int spr) +{ + uae_u32 *buf = (uae_u32 *)xlinebuffer; + + while (dpix < stoppos) { + uae_u32 spix_val1, spix_val2; + uae_u16 v; + int off; + spix_val1 = pixdata.apixels[spix++]; + spix_val2 = pixdata.apixels[spix++]; + off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); + v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; + v |= v >> 2; + PUTBPIX(shsprite(dpix, spix_val1, xcolors[v], spr)); + dpix++; + v = (colors_for_drawing.color_regs_ecs[off] & 0x333) << 2; + v |= v >> 2; + PUTBPIX(shsprite(dpix, spix_val2, xcolors[v], spr)); + dpix++; + } + return spix; +} +static int linetoscr_32_sh_spr(int spix, int dpix, int stoppos) +{ + return linetoscr_32_sh_func(spix, dpix, stoppos, true); +} +static int linetoscr_32_sh(int spix, int dpix, int stoppos) +{ + return linetoscr_32_sh_func(spix, dpix, stoppos, false); +} +static int NOINLINE linetoscr_32_shrink1_sh_func(int spix, int dpix, int stoppos, int spr) +{ + uae_u32 *buf = (uae_u32 *)xlinebuffer; + + while (dpix < stoppos) { + uae_u32 spix_val1, spix_val2; + uae_u16 v; + int off; + spix_val1 = pixdata.apixels[spix++]; + spix_val2 = pixdata.apixels[spix++]; + off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); + v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; + v |= v >> 2; + PUTBPIX(shsprite(dpix, spix_val1, xcolors[v], spr)); + dpix++; + } + return spix; +} +static int linetoscr_32_shrink1_sh_spr(int spix, int dpix, int stoppos) +{ + return linetoscr_32_shrink1_sh_func(spix, dpix, stoppos, true); +} +static int linetoscr_32_shrink1_sh(int spix, int dpix, int stoppos) +{ + return linetoscr_32_shrink1_sh_func(spix, dpix, stoppos, false); +} +static int NOINLINE linetoscr_32_shrink1f_sh_func(int spix, int dpix, int stoppos, int spr) +{ + uae_u32 *buf = (uae_u32 *)xlinebuffer; + + while (dpix < stoppos) { + uae_u32 spix_val1, spix_val2, dpix_val1, dpix_val2; + uae_u16 v; + int off; + spix_val1 = pixdata.apixels[spix++]; + spix_val2 = pixdata.apixels[spix++]; + off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); + v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; + v |= v >> 2; + dpix_val1 = xcolors[v]; + v = (colors_for_drawing.color_regs_ecs[off] & 0x333) << 2; + v |= v >> 2; + dpix_val2 = xcolors[v]; + PUTBPIX(shsprite(dpix, spix_val1, merge_2pixel32(dpix_val1, dpix_val2), spr)); + dpix++; + } + return spix; +} +static int linetoscr_32_shrink1f_sh_spr(int spix, int dpix, int stoppos) +{ + return linetoscr_32_shrink1f_sh_func(spix, dpix, stoppos, true); +} +static int linetoscr_32_shrink1f_sh(int spix, int dpix, int stoppos) +{ + return linetoscr_32_shrink1f_sh_func(spix, dpix, stoppos, false); +} +static int NOINLINE linetoscr_16_shrink1_sh_func(int spix, int dpix, int stoppos, int spr) +{ + uae_u16 *buf = (uae_u16 *)xlinebuffer; + + while (dpix < stoppos) { + uae_u16 spix_val1, spix_val2; + uae_u16 v; + int off; + spix_val1 = pixdata.apixels[spix++]; + spix_val2 = pixdata.apixels[spix++]; + off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); + v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; + v |= v >> 2; + PUTBPIX(shsprite(dpix, spix_val1, xcolors[v], spr)); + dpix++; + } + return spix; +} +static int linetoscr_16_shrink1_sh_spr(int spix, int dpix, int stoppos) +{ + return linetoscr_16_shrink1_sh_func(spix, dpix, stoppos, true); +} +static int linetoscr_16_shrink1_sh(int spix, int dpix, int stoppos) +{ + return linetoscr_16_shrink1_sh_func(spix, dpix, stoppos, false); +} +static int NOINLINE linetoscr_16_shrink1f_sh_func(int spix, int dpix, int stoppos, int spr) +{ + uae_u16 *buf = (uae_u16 *)xlinebuffer; + + while (dpix < stoppos) { + uae_u16 spix_val1, spix_val2, dpix_val1, dpix_val2; + uae_u16 v; + int off; + spix_val1 = pixdata.apixels[spix++]; + spix_val2 = pixdata.apixels[spix++]; + off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); + v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; + v |= v >> 2; + dpix_val1 = xcolors[v]; + v = (colors_for_drawing.color_regs_ecs[off] & 0x333) << 2; + v |= v >> 2; + dpix_val2 = xcolors[v]; + PUTBPIX(shsprite(dpix, spix_val1, merge_2pixel16(dpix_val1, dpix_val2), spr)); + dpix++; + } + return spix; +} +static int linetoscr_16_shrink1f_sh_spr(int spix, int dpix, int stoppos) +{ + return linetoscr_16_shrink1f_sh_func(spix, dpix, stoppos, true); +} +static int linetoscr_16_shrink1f_sh(int spix, int dpix, int stoppos) +{ + return linetoscr_16_shrink1f_sh_func(spix, dpix, stoppos, false); +} +static int NOINLINE linetoscr_32_shrink2_sh_func(int spix, int dpix, int stoppos, int spr) +{ + uae_u32 *buf = (uae_u32 *)xlinebuffer; + + while (dpix < stoppos) { + uae_u32 spix_val1, spix_val2; + uae_u16 v; + int off; + spix_val1 = pixdata.apixels[spix++]; + spix_val2 = pixdata.apixels[spix++]; + off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); + v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; + v |= v >> 2; + PUTBPIX(shsprite(dpix, spix_val1, xcolors[v], spr)); + spix += 2; + dpix++; + } + return spix; +} +static int linetoscr_32_shrink2_sh_spr(int spix, int dpix, int stoppos) +{ + return linetoscr_32_shrink2_sh_func(spix, dpix, stoppos, true); +} +static int linetoscr_32_shrink2_sh(int spix, int dpix, int stoppos) +{ + return linetoscr_32_shrink2_sh_func(spix, dpix, stoppos, false); +} +static int NOINLINE linetoscr_32_shrink2f_sh_func(int spix, int dpix, int stoppos, int spr) +{ + uae_u32 *buf = (uae_u32 *)xlinebuffer; + + while (dpix < stoppos) { + uae_u32 spix_val1, spix_val2, dpix_val1, dpix_val2, dpix_val3, dpix_val4; + uae_u16 v; + int off; + spix_val1 = pixdata.apixels[spix++]; + spix_val2 = pixdata.apixels[spix++]; + off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); + v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; + v |= v >> 2; + dpix_val1 = xcolors[v]; + v = (colors_for_drawing.color_regs_ecs[off] & 0x333) << 2; + v |= v >> 2; + dpix_val2 = xcolors[v]; + dpix_val3 = merge_2pixel32(dpix_val1, dpix_val2); + spix_val1 = pixdata.apixels[spix++]; + spix_val2 = pixdata.apixels[spix++]; + off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); + v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; + v |= v >> 2; + dpix_val1 = xcolors[v]; + v = (colors_for_drawing.color_regs_ecs[off] & 0x333) << 2; + v |= v >> 2; + dpix_val2 = xcolors[v]; + dpix_val4 = merge_2pixel32(dpix_val1, dpix_val2); + PUTBPIX(shsprite(dpix, spix_val1, merge_2pixel32(dpix_val3, dpix_val4), spr)); + dpix++; + } + return spix; +} +static int linetoscr_32_shrink2f_sh_spr(int spix, int dpix, int stoppos) +{ + return linetoscr_32_shrink2f_sh_func(spix, dpix, stoppos, true); +} +static int linetoscr_32_shrink2f_sh(int spix, int dpix, int stoppos) +{ + return linetoscr_32_shrink2f_sh_func(spix, dpix, stoppos, false); +} +static int NOINLINE linetoscr_16_shrink2_sh_func(int spix, int dpix, int stoppos, int spr) +{ + uae_u16 *buf = (uae_u16 *)xlinebuffer; + + while (dpix < stoppos) { + uae_u16 spix_val1, spix_val2; + uae_u16 v; + int off; + spix_val1 = pixdata.apixels[spix++]; + spix_val2 = pixdata.apixels[spix++]; + off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); + v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; + v |= v >> 2; + PUTBPIX(shsprite(dpix, spix_val1, xcolors[v], spr)); + spix += 2; + dpix++; + } + return spix; +} +static int linetoscr_16_shrink2_sh_spr(int spix, int dpix, int stoppos) +{ + return linetoscr_16_shrink2_sh_func(spix, dpix, stoppos, true); +} +static int linetoscr_16_shrink2_sh(int spix, int dpix, int stoppos) +{ + return linetoscr_16_shrink2_sh_func(spix, dpix, stoppos, false); +} +static int NOINLINE linetoscr_16_shrink2f_sh_func(int spix, int dpix, int stoppos, int spr) +{ + uae_u16 *buf = (uae_u16 *)xlinebuffer; + + while (dpix < stoppos) { + uae_u16 spix_val1, spix_val2, dpix_val1, dpix_val2, dpix_val3, dpix_val4; + uae_u16 v; + int off; + spix_val1 = pixdata.apixels[spix++]; + spix_val2 = pixdata.apixels[spix++]; + off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); + v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; + v |= v >> 2; + dpix_val1 = xcolors[v]; + v = (colors_for_drawing.color_regs_ecs[off] & 0x333) << 2; + v |= v >> 2; + dpix_val2 = xcolors[v]; + dpix_val3 = merge_2pixel32(dpix_val1, dpix_val2); + spix_val1 = pixdata.apixels[spix++]; + spix_val2 = pixdata.apixels[spix++]; + off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); + v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; + v |= v >> 2; + dpix_val1 = xcolors[v]; + v = (colors_for_drawing.color_regs_ecs[off] & 0x333) << 2; + v |= v >> 2; + dpix_val2 = xcolors[v]; + dpix_val4 = merge_2pixel32(dpix_val1, dpix_val2); + PUTBPIX(shsprite(dpix, spix_val1, merge_2pixel16(dpix_val3, dpix_val4), spr)); + dpix++; + } + return spix; +} +static int linetoscr_16_shrink2f_sh_spr(int spix, int dpix, int stoppos) +{ + return linetoscr_16_shrink2f_sh_func(spix, dpix, stoppos, true); +} +static int linetoscr_16_shrink2f_sh(int spix, int dpix, int stoppos) +{ + return linetoscr_16_shrink2f_sh_func(spix, dpix, stoppos, false); +} + +typedef int(*call_linetoscr)(int spix, int dpix, int dpix_end); + +static call_linetoscr pfield_do_linetoscr_normal; +static call_linetoscr pfield_do_linetoscr_sprite; +static call_linetoscr pfield_do_linetoscr_spriteonly; + +static void pfield_do_linetoscr(int start, int stop, bool blank) +{ + src_pixel = pfield_do_linetoscr_normal(src_pixel, start, stop); +} +static void pfield_do_linetoscr_spr(int start, int stop, bool blank) +{ + src_pixel = pfield_do_linetoscr_sprite(src_pixel, start, stop); +} +static int pfield_do_nothing(int a, int b, int c) +{ + return a; +} + +/* AGA subpixel delay hack */ +static call_linetoscr pfield_do_linetoscr_shdelay_normal; +static call_linetoscr pfield_do_linetoscr_shdelay_sprite; + +static int pfield_do_linetoscr_normal_shdelay(int spix, int dpix, int dpix_end) +{ + int add = get_shdelay_add(); + int add2 = add * gfxvidinfo.pixbytes; + if (add) { + // Clear skipped pixel(s). + pfield_do_linetoscr_shdelay_sprite(spix, dpix, dpix + add); + } + xlinebuffer += add2; + int out = pfield_do_linetoscr_shdelay_normal(spix, dpix, dpix_end); + xlinebuffer -= add2; + return out; +} +static int pfield_do_linetoscr_sprite_shdelay(int spix, int dpix, int dpix_end) +{ + int out = spix; + if (dpix < real_playfield_start && dpix_end > real_playfield_start) { + // Crosses real_playfield_start. + // Render only from dpix to real_playfield_start. + int len = real_playfield_start - dpix; + out = pfield_do_linetoscr_spriteonly(out, dpix, dpix + len); + dpix = real_playfield_start; + } + else if (dpix_end <= real_playfield_start) { + // Does not cross real_playfield_start, nothing special needed. + out = pfield_do_linetoscr_spriteonly(out, dpix, dpix_end); + return out; + } + // Render bitplane with subpixel scroll, from real_playfield_start to end. + int add = get_shdelay_add(); + int add2 = add * gfxvidinfo.pixbytes; + if (add) { + pfield_do_linetoscr_shdelay_sprite(out, dpix, dpix + add); + } + sprite_shdelay = add; + spritepixels += add; + xlinebuffer += add2; + out = pfield_do_linetoscr_shdelay_sprite(out, dpix, dpix_end); + xlinebuffer -= add2; + spritepixels -= add; + sprite_shdelay = 0; + return out; +} + +static void pfield_set_linetoscr(void) +{ + xlinecheck(start, stop); + p_acolors = colors_for_drawing.acolors; + p_xcolors = xcolors; + bpland = 0xff; + if (bplbypass) { + p_acolors = direct_colors_for_drawing.acolors; + } + spritepixels = spritepixels_buffer; + pfield_do_linetoscr_spriteonly = pfield_do_nothing; +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) { + if (res_shift == 0) { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_aga; + pfield_do_linetoscr_sprite = linetoscr_16_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_16_aga_spronly; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_aga; + pfield_do_linetoscr_sprite = linetoscr_32_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_32_aga_spronly; + break; + } + } + else if (res_shift == 2) { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_stretch2_aga; + pfield_do_linetoscr_sprite = linetoscr_16_stretch2_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_16_stretch2_aga_spronly; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_stretch2_aga; + pfield_do_linetoscr_sprite = linetoscr_32_stretch2_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_32_stretch2_aga_spronly; + break; + } + } + else if (res_shift == 1) { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_stretch1_aga; + pfield_do_linetoscr_sprite = linetoscr_16_stretch1_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_16_stretch1_aga_spronly; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_stretch1_aga; + pfield_do_linetoscr_sprite = linetoscr_32_stretch1_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_32_stretch1_aga_spronly; + break; + } + } + else if (res_shift == -1) { + if (currprefs.gfx_lores_mode) { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_shrink1f_aga; + pfield_do_linetoscr_sprite = linetoscr_16_shrink1f_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_16_shrink1f_aga_spronly; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_shrink1f_aga; + pfield_do_linetoscr_sprite = linetoscr_32_shrink1f_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_32_shrink1f_aga_spronly; + break; + } + } + else { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_shrink1_aga; + pfield_do_linetoscr_sprite = linetoscr_16_shrink1_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_16_shrink1_aga_spronly; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_shrink1_aga; + pfield_do_linetoscr_sprite = linetoscr_32_shrink1_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_32_shrink1_aga_spronly; + break; + } + } + } + else if (res_shift == -2) { + if (currprefs.gfx_lores_mode) { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_shrink2f_aga; + pfield_do_linetoscr_sprite = linetoscr_16_shrink2f_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_16_shrink2f_aga_spronly; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_shrink2f_aga; + pfield_do_linetoscr_sprite = linetoscr_32_shrink2f_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_32_shrink2f_aga_spronly; + break; + } + } + else { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_shrink2_aga; + pfield_do_linetoscr_sprite = linetoscr_16_shrink2_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_16_shrink2_aga_spronly; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_shrink2_aga; + pfield_do_linetoscr_sprite = linetoscr_32_shrink2_aga_spr; + pfield_do_linetoscr_spriteonly = linetoscr_32_shrink2_aga_spronly; + break; + } + } + } + if (get_shdelay_add()) { + pfield_do_linetoscr_shdelay_normal = pfield_do_linetoscr_normal; + pfield_do_linetoscr_shdelay_sprite = pfield_do_linetoscr_sprite; + pfield_do_linetoscr_normal = pfield_do_linetoscr_normal_shdelay; + pfield_do_linetoscr_sprite = pfield_do_linetoscr_sprite_shdelay; + } + } +#endif +#ifdef ECS_DENISE + if (!(currprefs.chipset_mask & CSMASK_AGA) && ecsshres) { + // TODO: genlock support + if (res_shift == 0) { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_sh; + pfield_do_linetoscr_sprite = linetoscr_16_sh_spr; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_sh; + pfield_do_linetoscr_sprite = linetoscr_32_sh_spr; + break; + } + } + else if (res_shift == -1) { + if (currprefs.gfx_lores_mode) { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_shrink1f_sh; + pfield_do_linetoscr_sprite = linetoscr_16_shrink1f_sh_spr; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_shrink1f_sh; + pfield_do_linetoscr_sprite = linetoscr_32_shrink1f_sh_spr; + break; + } + } + else { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_shrink1_sh; + pfield_do_linetoscr_sprite = linetoscr_16_shrink1_sh_spr; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_shrink1_sh; + pfield_do_linetoscr_sprite = linetoscr_32_shrink1_sh_spr; + break; + } + } + } + else if (res_shift == -2) { + if (currprefs.gfx_lores_mode) { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_shrink2f_sh; + pfield_do_linetoscr_sprite = linetoscr_16_shrink2f_sh_spr; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_shrink2f_sh; + pfield_do_linetoscr_sprite = linetoscr_32_shrink2f_sh_spr; + break; + } + } + else { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_shrink2_sh; + pfield_do_linetoscr_sprite = linetoscr_16_shrink2_sh_spr; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_shrink2_sh; + pfield_do_linetoscr_sprite = linetoscr_32_shrink2_sh_spr; + break; + } + } + } + } +#endif + if (!(currprefs.chipset_mask & CSMASK_AGA) && !ecsshres) { + if (res_shift == 0) { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16; + pfield_do_linetoscr_sprite = linetoscr_16_spr; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32; + pfield_do_linetoscr_sprite = linetoscr_32_spr; + break; + } + } + else if (res_shift == 2) { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_stretch2; + pfield_do_linetoscr_sprite = linetoscr_16_stretch2_spr; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_stretch2; + pfield_do_linetoscr_sprite = linetoscr_32_stretch2_spr; + break; + } + } + else if (res_shift == 1) { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_stretch1; + pfield_do_linetoscr_sprite = linetoscr_16_stretch1_spr; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_stretch1; + pfield_do_linetoscr_sprite = linetoscr_32_stretch1_spr; + break; + } + } + else if (res_shift == -1) { + if (currprefs.gfx_lores_mode) { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_shrink1f; + pfield_do_linetoscr_sprite = linetoscr_16_shrink1f_spr; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_shrink1f; + pfield_do_linetoscr_sprite = linetoscr_32_shrink1f_spr; + break; + } + } + else { + switch (gfxvidinfo.pixbytes) { + case 2: + pfield_do_linetoscr_normal = linetoscr_16_shrink1; + pfield_do_linetoscr_sprite = linetoscr_16_shrink1_spr; + break; + case 4: + pfield_do_linetoscr_normal = linetoscr_32_shrink1; + pfield_do_linetoscr_sprite = linetoscr_32_shrink1_spr; + break; + } + } + } + } +} + +// left or right AGA border sprite +static void pfield_do_linetoscr_bordersprite_aga(int start, int stop, bool blank) +{ + if (blank) { + pfield_do_fill_line(start, stop, blank); + return; + } + pfield_do_linetoscr_spriteonly(src_pixel, start, stop); +} + +static void dummy_worker(int start, int stop, bool blank) { } @@ -564,43 +1944,45 @@ STATIC_INLINE int DECODE_HAM6_3(int col, int pv) #endif static int ham_decode_pixel; -static uae_u16 ham_lastcolor; +static unsigned int ham_lastcolor; /* Decode HAM in the invisible portion of the display (left of VISIBLE_LEFT_BORDER), * but don't draw anything in. This is done to prepare HAM_LASTCOLOR for later, * when decode_ham runs. * */ -static void init_ham_decoding() +static void init_ham_decoding(void) { int unpainted_amiga = unpainted; - ham_decode_pixel = ham_src_pixel; - ham_lastcolor = colors_for_drawing.acolors[0]; + ham_decode_pixel = src_pixel; + ham_lastcolor = color_reg_get(&colors_for_drawing, 0); - if (!bplham) - { - if (unpainted_amiga > 0) - { + if (!bplham) { + if (unpainted_amiga > 0) { int pv = pixdata.apixels[ham_decode_pixel + unpainted_amiga - 1]; - if (aga_mode) - ham_lastcolor = colors_for_drawing.acolors[pv ^ bplxor]; +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) + ham_lastcolor = colors_for_drawing.color_regs_aga[pv ^ bplxor] & 0xffffff; else - ham_lastcolor = colors_for_drawing.acolors[pv]; +#endif + ham_lastcolor = colors_for_drawing.color_regs_ecs[pv] & 0xfff; } } - else if (aga_mode) + else if (currprefs.chipset_mask & CSMASK_AGA) { if (bplplanecnt >= 7) { /* AGA mode HAM8 */ while (unpainted_amiga-- > 0) { - int pv = pixdata.apixels[ham_decode_pixel++] ^ bplxor; + int pw = pixdata.apixels[ham_decode_pixel++]; + int pv = pw ^ bplxor; + int pc = pv >> 2; switch (pv & 0x3) { - case 0x0: ham_lastcolor = colors_for_drawing.acolors[pv >> 2]; + case 0x0: ham_lastcolor = colors_for_drawing.color_regs_aga[pc] & 0xffffff; break; break; -#ifdef ARMV6T2 +#ifdef NO_ARMV6T2 case 0x1: ham_lastcolor = DECODE_HAM8_1(ham_lastcolor, pv); break; case 0x2: ham_lastcolor = DECODE_HAM8_2(ham_lastcolor, pv); @@ -608,9 +1990,9 @@ static void init_ham_decoding() case 0x3: ham_lastcolor = DECODE_HAM8_3(ham_lastcolor, pv); break; #else - case 0x1: ham_lastcolor &= 0xFFFF03; ham_lastcolor |= (pv & 0xFC); break; - case 0x2: ham_lastcolor &= 0x03FFFF; ham_lastcolor |= (pv & 0xFC) << 16; break; - case 0x3: ham_lastcolor &= 0xFF03FF; ham_lastcolor |= (pv & 0xFC) << 8; break; + case 0x1: ham_lastcolor &= 0xFFFF03; ham_lastcolor |= (pw & 0xFC); break; + case 0x2: ham_lastcolor &= 0x03FFFF; ham_lastcolor |= (pw & 0xFC) << 16; break; + case 0x3: ham_lastcolor &= 0xFF03FF; ham_lastcolor |= (pw & 0xFC) << 8; break; #endif } } @@ -619,12 +2001,14 @@ static void init_ham_decoding() { /* AGA mode HAM6 */ while (unpainted_amiga-- > 0) { - int pv = pixdata.apixels[ham_decode_pixel++] ^ bplxor; + int pw = pixdata.apixels[ham_decode_pixel++]; + int pv = pw ^ bplxor; + uae_u32 pc = ((pw & 0xf) << 0) | ((pw & 0xf) << 4); switch (pv & 0x30) { - case 0x00: ham_lastcolor = colors_for_drawing.acolors[pv]; + case 0x00: ham_lastcolor = colors_for_drawing.color_regs_aga[pv & 0x0f] & 0xffffff; break; break; -#ifdef ARMV6T2 +#ifdef NO_ARMV6T2 case 0x10: ham_lastcolor = DECODE_HAM6_1(ham_lastcolor, pv); break; case 0x20: ham_lastcolor = DECODE_HAM6_2(ham_lastcolor, pv); @@ -632,9 +2016,9 @@ static void init_ham_decoding() case 0x30: ham_lastcolor = DECODE_HAM6_3(ham_lastcolor, pv); break; #else - case 0x10: ham_lastcolor &= 0xFFFF00; ham_lastcolor |= (pv & 0xF) << 4; break; - case 0x20: ham_lastcolor &= 0x00FFFF; ham_lastcolor |= (pv & 0xF) << 20; break; - case 0x30: ham_lastcolor &= 0xFF00FF; ham_lastcolor |= (pv & 0xF) << 12; break; + case 0x10: ham_lastcolor &= 0xFFFF00; ham_lastcolor |= pc << 0; break; + case 0x20: ham_lastcolor &= 0x00FFFF; ham_lastcolor |= pc << 16; break; + case 0x30: ham_lastcolor &= 0xFF00FF; ham_lastcolor |= pc << 8; break; #endif } } @@ -648,9 +2032,9 @@ static void init_ham_decoding() int pv = pixdata.apixels[ham_decode_pixel++]; switch (pv & 0x30) { - case 0x00: ham_lastcolor = colors_for_drawing.acolors[pv]; + case 0x00: ham_lastcolor = colors_for_drawing.color_regs_ecs[pv] & 0xfff; break; break; -#ifdef ARMV6T2 +#ifdef NO_ARMV6T2 case 0x10: ham_lastcolor = DECODE_HAM6_1(ham_lastcolor, pv); break; case 0x20: ham_lastcolor = DECODE_HAM6_2(ham_lastcolor, pv); @@ -667,35 +2051,40 @@ static void init_ham_decoding() } } -static void decode_ham(int pix, int stoppos) +static void decode_ham(int pix, int stoppos, bool blank) { int todraw_amiga = res_shift_from_window(stoppos - pix); + int hdp = ham_decode_pixel; if (!bplham) { while (todraw_amiga-- > 0) { int pv = pixdata.apixels[ham_decode_pixel]; - if (aga_mode) - ham_lastcolor = colors_for_drawing.acolors[pv ^ bplxor]; +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) + ham_lastcolor = colors_for_drawing.color_regs_aga[pv ^ bplxor] & 0xffffff; else - ham_lastcolor = colors_for_drawing.acolors[pv]; +#endif + ham_lastcolor = colors_for_drawing.color_regs_ecs[pv] & 0xfff; ham_linebuf[ham_decode_pixel++] = ham_lastcolor; } } - else if (aga_mode) + else if (currprefs.chipset_mask & CSMASK_AGA) { if (bplplanecnt >= 7) { /* AGA mode HAM8 */ while (todraw_amiga-- > 0) { - int pv = pixdata.apixels[ham_decode_pixel] ^ bplxor; + int pw = pixdata.apixels[ham_decode_pixel]; + int pv = pw ^ bplxor; + int pc = pv >> 2; switch (pv & 0x3) { - case 0x0: ham_lastcolor = colors_for_drawing.acolors[pv >> 2]; + case 0x0: ham_lastcolor = colors_for_drawing.color_regs_aga[pc] & 0xffffff; break; break; -#ifdef ARMV6T2 +#ifdef NO_ARMV6T2 case 0x1: ham_lastcolor = DECODE_HAM8_1(ham_lastcolor, pv); break; case 0x2: ham_lastcolor = DECODE_HAM8_2(ham_lastcolor, pv); @@ -703,9 +2092,9 @@ static void decode_ham(int pix, int stoppos) case 0x3: ham_lastcolor = DECODE_HAM8_3(ham_lastcolor, pv); break; #else - case 0x1: ham_lastcolor &= 0xFFFF03; ham_lastcolor |= (pv & 0xFC); break; - case 0x2: ham_lastcolor &= 0x03FFFF; ham_lastcolor |= (pv & 0xFC) << 16; break; - case 0x3: ham_lastcolor &= 0xFF03FF; ham_lastcolor |= (pv & 0xFC) << 8; break; + case 0x1: ham_lastcolor &= 0xFFFF03; ham_lastcolor |= (pw & 0xFC); break; + case 0x2: ham_lastcolor &= 0x03FFFF; ham_lastcolor |= (pw & 0xFC) << 16; break; + case 0x3: ham_lastcolor &= 0xFF03FF; ham_lastcolor |= (pw & 0xFC) << 8; break; #endif } ham_linebuf[ham_decode_pixel++] = ham_lastcolor; @@ -715,12 +2104,14 @@ static void decode_ham(int pix, int stoppos) { /* AGA mode HAM6 */ while (todraw_amiga-- > 0) { - int pv = pixdata.apixels[ham_decode_pixel] ^ bplxor; + int pw = pixdata.apixels[ham_decode_pixel]; + int pv = pw ^ bplxor; + uae_u32 pc = ((pw & 0xf) << 0) | ((pw & 0xf) << 4); switch (pv & 0x30) { - case 0x00: ham_lastcolor = colors_for_drawing.acolors[pv]; + case 0x00: ham_lastcolor = colors_for_drawing.color_regs_aga[pv & 0x0f] & 0xffffff; break; break; -#ifdef ARMV6T2 +#ifdef NO_ARMV6T2 case 0x10: ham_lastcolor = DECODE_HAM6_1(ham_lastcolor, pv); break; case 0x20: ham_lastcolor = DECODE_HAM6_2(ham_lastcolor, pv); @@ -728,9 +2119,9 @@ static void decode_ham(int pix, int stoppos) case 0x30: ham_lastcolor = DECODE_HAM6_3(ham_lastcolor, pv); break; #else - case 0x10: ham_lastcolor &= 0xFFFF00; ham_lastcolor |= (pv & 0xF) << 4; break; - case 0x20: ham_lastcolor &= 0x00FFFF; ham_lastcolor |= (pv & 0xF) << 20; break; - case 0x30: ham_lastcolor &= 0xFF00FF; ham_lastcolor |= (pv & 0xF) << 12; break; + case 0x10: ham_lastcolor &= 0xFFFF00; ham_lastcolor |= pc << 0; break; + case 0x20: ham_lastcolor &= 0x00FFFF; ham_lastcolor |= pc << 16; break; + case 0x30: ham_lastcolor &= 0xFF00FF; ham_lastcolor |= pc << 8; break; #endif } ham_linebuf[ham_decode_pixel++] = ham_lastcolor; @@ -745,9 +2136,9 @@ static void decode_ham(int pix, int stoppos) int pv = pixdata.apixels[ham_decode_pixel]; switch (pv & 0x30) { - case 0x00: ham_lastcolor = colors_for_drawing.acolors[pv]; + case 0x00: ham_lastcolor = colors_for_drawing.color_regs_ecs[pv] & 0xfff; break; break; -#ifdef ARMV6T2 +#ifdef NO_ARMV6T2 case 0x10: ham_lastcolor = DECODE_HAM6_1(ham_lastcolor, pv); break; case 0x20: ham_lastcolor = DECODE_HAM6_2(ham_lastcolor, pv); @@ -765,798 +2156,184 @@ static void decode_ham(int pix, int stoppos) } } -static void gen_pfield_tables() +static void erase_ham_right_border(int pix, int stoppos, bool blank) +{ + if (stoppos < playfield_end) + return; + // erase right border in HAM modes or old HAM data may be visible + // if DDFSTOP < DIWSTOP (Uridium II title screen) + int todraw_amiga = res_shift_from_window(stoppos - pix); + while (todraw_amiga-- > 0) + ham_linebuf[ham_decode_pixel++] = 0; +} + +static void gen_pfield_tables(void) { int i; - for (i = 0; i < 256; i++) - { + for (i = 0; i < 256; i++) { int plane1 = ((i >> 0) & 1) | ((i >> 1) & 2) | ((i >> 2) & 4) | ((i >> 3) & 8); int plane2 = ((i >> 1) & 1) | ((i >> 2) & 2) | ((i >> 3) & 4) | ((i >> 4) & 8); - dblpf_2nd1[i] = plane1 == 0 ? (plane2 == 0 ? 0 : 2) : 1; - dblpf_2nd2[i] = plane2 == 0 ? (plane1 == 0 ? 0 : 1) : 2; + dblpf_2nd1[i] = plane1 == 0 && plane2 != 0; + dblpf_2nd2[i] = plane2 != 0; +#ifdef AGA dblpf_ind1_aga[i] = plane1 == 0 ? plane2 : plane1; dblpf_ind2_aga[i] = plane2 == 0 ? plane1 : plane2; +#endif dblpf_ms1[i] = plane1 == 0 ? (plane2 == 0 ? 16 : 8) : 0; dblpf_ms2[i] = plane2 == 0 ? (plane1 == 0 ? 16 : 0) : 8; + dblpf_ms[i] = i == 0 ? 16 : 8; + if (plane2 > 0) plane2 += 8; dblpf_ind1[i] = i >= 128 ? i & 0x7F : (plane1 == 0 ? plane2 : plane1); dblpf_ind2[i] = i >= 128 ? i & 0x7F : (plane2 == 0 ? plane1 : plane2); + // Hack for OCS/ECS-only dualplayfield chipset bug. + // If PF2P2 is invalid (>5), playfield color becomes transparent but + // playfield still hides playfield under it! (if plfpri is set) + if (i & 64) { + dblpf_ind2[i] = 0; + dblpf_ind1[i] = 0; + } + + sprite_offs[i] = (i & 15) ? 0 : 2; + clxtab[i] = ((((i & 3) && (i & 12)) << 9) | (((i & 3) && (i & 48)) << 10) | (((i & 3) && (i & 192)) << 11) | (((i & 12) && (i & 48)) << 12) | (((i & 12) && (i & 192)) << 13) | (((i & 48) && (i & 192)) << 14)); + } - for (i = 0; i < 65536; ++i) - { - sprite_col_nat[i] = - (i & 0x0003) ? ((i >> 0) & 3) + 0 : - (i & 0x000C) ? ((i >> 2) & 3) + 0 : - (i & 0x0030) ? ((i >> 4) & 3) + 4 : - (i & 0x00C0) ? ((i >> 6) & 3) + 4 : - (i & 0x0300) ? ((i >> 8) & 3) + 8 : - (i & 0x0C00) ? ((i >> 10) & 3) + 8 : - (i & 0x3000) ? ((i >> 12) & 3) + 12 : - (i & 0xC000) ? ((i >> 14) & 3) + 12 : 0; - sprite_col_at[i] = - (i & 0x000F) ? ((i >> 0) & 0x000F) : - (i & 0x00F0) ? ((i >> 4) & 0x000F) : - (i & 0x0F00) ? ((i >> 8) & 0x000F) : - (i & 0xF000) ? ((i >> 12) & 0x000F) : 0; - sprite_bit[i] = - (i & 0x0003) ? 0x01 : - (i & 0x000C) ? 0x02 : - (i & 0x0030) ? 0x04 : - (i & 0x00C0) ? 0x08 : - (i & 0x0300) ? 0x10 : - (i & 0x0C00) ? 0x20 : - (i & 0x3000) ? 0x40 : - (i & 0xC000) ? 0x80 : 0; - } + memset(all_ones, 0xff, MAX_PIXELS_PER_LINE); + } -static void draw_sprites_normal_sp_lo_nat(struct sprite_entry* e) -{ - uae_u16* buf = spixels + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT)); - window_pos += pixels_offset; - unsigned max = e->max; - for (pos = e->pos; pos < max; pos++) - { - unsigned int v = buf[pos]; - - if (pixdata.apixels[window_pos]) - v &= plf_sprite_mask_n16; - if (v != 0) - { - unsigned int col; - col = sprite_col_nat[v] + 16; - pixdata.apixels[window_pos] = col; - } - window_pos++; - } -} - -static void draw_sprites_normal_ham_lo_nat(struct sprite_entry* e) -{ - uae_u16* buf = spixels + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT)); - window_pos += pixels_offset; - unsigned max = e->max; - for (pos = e->pos; pos < max; pos++) - { - unsigned int v = buf[pos]; - - if (pixdata.apixels[window_pos]) - v &= plf_sprite_mask_n16; - if (v != 0) - { - unsigned int col; - col = sprite_col_nat[v] + 16; - ham_linebuf[window_pos] = colors_for_drawing.acolors[col]; - } - window_pos++; - } -} - - -static void draw_sprites_normal_dp_lo_nat(struct sprite_entry* e) -{ - int* shift_lookup = (bpldualpfpri ? dblpf_ms2 : dblpf_ms1); - uae_u16* buf = spixels + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT)); - window_pos += pixels_offset; - unsigned max = e->max; - for (pos = e->pos; pos < max; pos++) - { - int maskshift, plfmask; - unsigned int v = buf[pos]; - - maskshift = shift_lookup[pixdata.apixels[window_pos]]; - plfmask = (plf_sprite_mask >> maskshift) >> maskshift; - v &= ~plfmask; - if (v != 0) - { - unsigned int col; - col = sprite_col_nat[v] + 16 + 128; - pixdata.apixels[window_pos] = col; - } - window_pos++; - } -} - -static void draw_sprites_normal_sp_lo_at(struct sprite_entry* e) -{ - uae_u16* buf = spixels + e->first_pixel; - uae_u8* stbuf = spixstate.bytes + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - stbuf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT)); - window_pos += pixels_offset; - unsigned max = e->max; - for (pos = e->pos; pos < max; pos++) - { - unsigned int v = buf[pos]; - - if (pixdata.apixels[window_pos]) - v &= plf_sprite_mask_n16; - if (v != 0) - { - unsigned int col; - int offs; - offs = sprite_bit[v]; - if (stbuf[pos] & offs) - { - col = sprite_col_at[v] + 16; - } - else - { - col = sprite_col_nat[v] + 16; - } - pixdata.apixels[window_pos] = col; - } - window_pos++; - } -} - -static void draw_sprites_normal_ham_lo_at(struct sprite_entry* e) -{ - uae_u16* buf = spixels + e->first_pixel; - uae_u8* stbuf = spixstate.bytes + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - stbuf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT)); - window_pos += pixels_offset; - unsigned max = e->max; - for (pos = e->pos; pos < max; pos++) - { - unsigned int v = buf[pos]; - - if (pixdata.apixels[window_pos]) - v &= plf_sprite_mask_n16; - if (v != 0) - { - unsigned int col; - int offs; - offs = sprite_bit[v]; - if (stbuf[pos] & offs) - { - col = sprite_col_at[v] + 16; - } - else - { - col = sprite_col_nat[v] + 16; - } - ham_linebuf[window_pos] = colors_for_drawing.acolors[col]; - } - window_pos++; - } -} - -static void draw_sprites_normal_dp_lo_at(struct sprite_entry* e) -{ - int* shift_lookup = (bpldualpfpri ? dblpf_ms2 : dblpf_ms1); - uae_u16* buf = spixels + e->first_pixel; - uae_u8* stbuf = spixstate.bytes + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - stbuf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT)); - window_pos += pixels_offset; - unsigned max = e->max; - for (pos = e->pos; pos < max; pos++) - { - int maskshift, plfmask; - unsigned int v = buf[pos]; - - maskshift = shift_lookup[pixdata.apixels[window_pos]]; - plfmask = (plf_sprite_mask >> maskshift) >> maskshift; - v &= ~plfmask; - if (v != 0) - { - unsigned int col; - int offs; - offs = sprite_bit[v]; - if (stbuf[pos] & offs) - { - col = sprite_col_at[v] + 16 + 128; - } - else - { - col = sprite_col_nat[v] + 16 + 128; - } - pixdata.apixels[window_pos] = col; - } - window_pos++; - } -} - -static void draw_sprites_normal_sp_hi_nat(struct sprite_entry* e) -{ - uae_u16* buf = spixels + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT)); - window_pos <<= 1; - window_pos += pixels_offset; - unsigned max = e->max; - for (pos = e->pos; pos < max; pos++) - { - unsigned int v = buf[pos]; - - if (pixdata.apixels[window_pos]) - v &= plf_sprite_mask_n16; - if (v != 0) - { - unsigned int col; - col = sprite_col_nat[v] + 16; - pixdata.apixels_w[window_pos >> 1] = col | (col << 8); - } - window_pos += 2; - } -} - -static void draw_sprites_normal_ham_hi_nat(struct sprite_entry* e) -{ - uae_u16* buf = spixels + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT)); - window_pos <<= 1; - window_pos += pixels_offset; - unsigned max = e->max; - for (pos = e->pos; pos < max; pos++) - { - unsigned int v = buf[pos]; - - if (pixdata.apixels[window_pos]) - v &= plf_sprite_mask_n16; - if (v != 0) - { - unsigned int col; - col = sprite_col_nat[v] + 16; - col = col | (col << 8); - ham_linebuf[window_pos >> 1] = colors_for_drawing.acolors[col]; - } - window_pos += 2; - } -} - - -static void draw_sprites_normal_dp_hi_nat(struct sprite_entry* e) -{ - int* shift_lookup = (bpldualpfpri ? dblpf_ms2 : dblpf_ms1); - uae_u16* buf = spixels + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT)); - window_pos <<= 1; - window_pos += pixels_offset; - unsigned max = e->max; - for (pos = e->pos; pos < max; pos++) - { - int maskshift, plfmask; - unsigned int v = buf[pos]; - - maskshift = shift_lookup[pixdata.apixels[window_pos]]; - plfmask = (plf_sprite_mask >> maskshift) >> maskshift; - v &= ~plfmask; - if (v != 0) - { - unsigned int col; - col = sprite_col_nat[v] + 16 + 128; - pixdata.apixels_w[window_pos >> 1] = col | (col << 8); - } - window_pos += 2; - } -} - -static void draw_sprites_normal_sp_hi_at(struct sprite_entry* e) -{ - uae_u16* buf = spixels + e->first_pixel; - uae_u8* stbuf = spixstate.bytes + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - stbuf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT)); - window_pos <<= 1; - window_pos += pixels_offset; - unsigned max = e->max; - for (pos = e->pos; pos < max; pos++) - { - unsigned int v = buf[pos]; - - if (pixdata.apixels[window_pos]) - v &= plf_sprite_mask_n16; - if (v != 0) - { - unsigned int col; - int offs; - offs = sprite_bit[v]; - if (stbuf[pos] & offs) - { - col = sprite_col_at[v] + 16; - } - else - { - col = sprite_col_nat[v] + 16; - } - pixdata.apixels_w[window_pos >> 1] = col | (col << 8); - } - window_pos += 2; - } -} - -static void draw_sprites_normal_ham_hi_at(struct sprite_entry* e) -{ - uae_u16* buf = spixels + e->first_pixel; - uae_u8* stbuf = spixstate.bytes + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - stbuf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT)); - window_pos <<= 1; - window_pos += pixels_offset; - unsigned max = e->max; - for (pos = e->pos; pos < max; pos++) - { - unsigned int v = buf[pos]; - - if (pixdata.apixels[window_pos]) - v &= plf_sprite_mask_n16; - if (v != 0) - { - unsigned int col; - int offs; - offs = sprite_bit[v]; - if (stbuf[pos] & offs) - { - col = sprite_col_at[v] + 16; - } - else - { - col = sprite_col_nat[v] + 16; - } - col = col | (col << 8); - ham_linebuf[window_pos >> 1] = colors_for_drawing.acolors[col]; - } - window_pos += 2; - } -} - -static void draw_sprites_normal_dp_hi_at(struct sprite_entry* e) -{ - int* shift_lookup = (bpldualpfpri ? dblpf_ms2 : dblpf_ms1); - uae_u16* buf = spixels + e->first_pixel; - uae_u8* stbuf = spixstate.bytes + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - stbuf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT)); - window_pos <<= 1; - window_pos += pixels_offset; - - unsigned max = e->max; - for (pos = e->pos; pos < max; pos++) - { - int maskshift, plfmask; - unsigned int v = buf[pos]; - - maskshift = shift_lookup[pixdata.apixels[window_pos]]; - plfmask = (plf_sprite_mask >> maskshift) >> maskshift; - v &= ~plfmask; - if (v != 0) - { - unsigned int col; - int offs; - offs = sprite_bit[v]; - if (stbuf[pos] & offs) - { - col = sprite_col_at[v] + 16 + 128; - } - else - { - col = sprite_col_nat[v] + 16 + 128; - } - pixdata.apixels_w[window_pos >> 1] = col | (col << 8); - } - window_pos += 2; - } -} - -typedef void (*draw_sprites_func)(struct sprite_entry* e); -static draw_sprites_func draw_sprites_dp_hi[2] = { - draw_sprites_normal_dp_hi_nat, - draw_sprites_normal_dp_hi_at -}; -static draw_sprites_func draw_sprites_sp_hi[2] = { - draw_sprites_normal_sp_hi_nat, - draw_sprites_normal_sp_hi_at -}; -static draw_sprites_func draw_sprites_ham_hi[2] = { - draw_sprites_normal_ham_hi_nat, - draw_sprites_normal_ham_hi_at -}; -static draw_sprites_func draw_sprites_dp_lo[2] = { - draw_sprites_normal_dp_lo_nat, - draw_sprites_normal_dp_lo_at -}; -static draw_sprites_func draw_sprites_sp_lo[2] = { - draw_sprites_normal_sp_lo_nat, - draw_sprites_normal_sp_lo_at -}; -static draw_sprites_func draw_sprites_ham_lo[2] = { - draw_sprites_normal_ham_lo_nat, - draw_sprites_normal_ham_lo_at -}; - -static draw_sprites_func* draw_sprites_punt = draw_sprites_sp_lo; - /* When looking at this function and the ones that inline it, bear in mind - what an optimizing compiler will do with this code. All callers of this - function only pass in constant arguments (except for E). This means - that many of the if statements will go away completely after inlining. */ - -/* NOTE: This function is called for AGA modes *only* */ -STATIC_INLINE void draw_sprites_aga_ham(struct sprite_entry* e, const int doubling, const int skip, const int has_attach) +what an optimizing compiler will do with this code. All callers of this +function only pass in constant arguments (except for E). This means +that many of the if statements will go away completely after inlining. */ +STATIC_INLINE void draw_sprites_1(struct sprite_entry *e, int dualpf, int has_attach) { - uae_u16* buf = spixels + e->first_pixel; - uae_u8* stbuf = spixstate.bytes + e->first_pixel; - int pos, window_pos; + uae_u16 *buf = spixels + e->first_pixel; + uae_u8 *stbuf = spixstate.bytes + e->first_pixel; + int spr_pos, pos; + int epos = e->pos; + int emax = e->max; - buf -= e->pos; - stbuf -= e->pos; + buf -= epos; + stbuf -= epos; - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT) << sprite_buffer_res); - if (skip) - window_pos >>= 1; - else if (doubling) - window_pos <<= 1; - window_pos += pixels_offset; + spr_pos = epos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT) << sprite_buffer_res); - for (pos = e->pos; pos < e->max; pos += 1 << skip) - { - unsigned int v = buf[pos]; + if (spr_pos < sprite_first_x) + sprite_first_x = spr_pos; - if (v) - { - if (pixdata.apixels[window_pos]) - v &= plf_sprite_mask_n16; - if (v != 0) - { - unsigned int col; - int offs; - offs = sprite_bit[v]; - if (has_attach && (stbuf[pos] & offs)) - { - col = sprite_col_at[v] + sbasecol[1]; - } - else - { - if (offs & 0x55) - col = sprite_col_nat[v] + sbasecol[0]; - else - col = sprite_col_nat[v] + sbasecol[1]; - } - - col = colors_for_drawing.acolors[col ^ bplxor]; - ham_linebuf[window_pos] = col; - if (doubling) - ham_linebuf[window_pos + 1] = col; - } + for (pos = epos; pos < emax; pos++, spr_pos++) { + if (spr_pos >= 0 && spr_pos < MAX_PIXELS_PER_LINE) { + spritepixels[spr_pos].data = buf[pos]; + spritepixels[spr_pos].stdata = stbuf[pos]; + spritepixels[spr_pos].attach = has_attach; } - window_pos += 1 << doubling; - } -} - -STATIC_INLINE void draw_sprites_aga_dp(struct sprite_entry* e, const int doubling, const int skip, const int has_attach) -{ - int* shift_lookup = (bpldualpfpri ? dblpf_ms2 : dblpf_ms1); - uae_u16* buf = spixels + e->first_pixel; - uae_u8* stbuf = spixstate.bytes + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - stbuf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT) << sprite_buffer_res); - if (skip) - window_pos >>= 1; - else if (doubling) - window_pos <<= 1; - window_pos += pixels_offset; - - if (window_pos < sprite_first_x) - sprite_first_x = window_pos; - - for (pos = e->pos; pos < e->max; pos += 1 << skip) - { - int maskshift, plfmask; - unsigned int v = buf[pos]; - - if (v) - { - /* The value in the shift lookup table is _half_ the shift count we - need. This is because we can't shift 32 bits at once (undefined - behaviour in C). */ - maskshift = shift_lookup[pixdata.apixels[window_pos]]; - plfmask = (plf_sprite_mask >> maskshift) >> maskshift; - v &= ~plfmask; - if (v != 0) - { - unsigned int col; - int offs; - offs = sprite_bit[v]; - if (has_attach && (stbuf[pos] & offs)) - { - col = sprite_col_at[v] + sbasecol[1]; - } - else - { - if (offs & 0x55) - col = sprite_col_nat[v] + sbasecol[0]; - else - col = sprite_col_nat[v] + sbasecol[1]; - } - - spritepixels[window_pos] = col; - if (doubling) - spritepixels[window_pos + 1] = col; - } - } - - window_pos += 1 << doubling; } - if (window_pos > sprite_last_x) - sprite_last_x = window_pos; + if (spr_pos > sprite_last_x) + sprite_last_x = spr_pos; } -STATIC_INLINE void draw_sprites_aga_sp(struct sprite_entry* e, const int doubling, const int skip, const int has_attach) +/* See comments above. Do not touch if you don't know what's going on. +* (We do _not_ want the following to be inlined themselves). */ +/* lores bitplane, lores sprites */ +static void NOINLINE draw_sprites_normal_sp_nat(struct sprite_entry *e) { draw_sprites_1(e, 0, 0); } +static void NOINLINE draw_sprites_normal_dp_nat(struct sprite_entry *e) { draw_sprites_1(e, 1, 0); } +static void NOINLINE draw_sprites_normal_sp_at(struct sprite_entry *e) { draw_sprites_1(e, 0, 1); } +static void NOINLINE draw_sprites_normal_dp_at(struct sprite_entry *e) { draw_sprites_1(e, 1, 1); } + +#ifdef AGA +/* not very optimized */ +STATIC_INLINE void draw_sprites_aga(struct sprite_entry *e, int aga) { - uae_u16* buf = spixels + e->first_pixel; - uae_u8* stbuf = spixstate.bytes + e->first_pixel; - int pos, window_pos; - - buf -= e->pos; - stbuf -= e->pos; - - window_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT) << sprite_buffer_res); - if (skip) - window_pos >>= 1; - else if (doubling) - window_pos <<= 1; - window_pos += pixels_offset; - - for (pos = e->pos; pos < e->max; pos += 1 << skip) - { - unsigned int v = buf[pos]; - - if (v) - { - if (pixdata.apixels[window_pos]) - v &= plf_sprite_mask_n16; - if (v != 0) - { - unsigned int col; - int offs; - offs = sprite_bit[v]; - if (has_attach && (stbuf[pos] & offs)) - { - col = sprite_col_at[v] + sbasecol[1]; - } - else - { - if (offs & 0x55) - col = sprite_col_nat[v] + sbasecol[0]; - else - col = sprite_col_nat[v] + sbasecol[1]; - } - - col ^= bplxor; - if (doubling) - pixdata.apixels_w[window_pos >> 1] = col | (col << 8); - else - pixdata.apixels[window_pos] = col; - } - } - window_pos += 1 << doubling; - } + draw_sprites_1(e, bpldualpf, e->has_attached); } +#endif -// ENTRY, doubling, skip, has_attach -static void draw_sprites_aga_sp_lo_nat(struct sprite_entry* e) { draw_sprites_aga_sp(e, 0, 1, 0); } -static void draw_sprites_aga_dp_lo_nat(struct sprite_entry* e) { draw_sprites_aga_dp(e, 0, 1, 0); } -static void draw_sprites_aga_ham_lo_nat(struct sprite_entry* e) { draw_sprites_aga_ham(e, 0, 1, 0); } - -static void draw_sprites_aga_sp_lo_at(struct sprite_entry* e) { draw_sprites_aga_sp(e, 0, 1, 1); } -static void draw_sprites_aga_dp_lo_at(struct sprite_entry* e) { draw_sprites_aga_dp(e, 0, 1, 1); } -static void draw_sprites_aga_ham_lo_at(struct sprite_entry* e) { draw_sprites_aga_ham(e, 0, 1, 1); } - -static void draw_sprites_aga_sp_hi_nat(struct sprite_entry* e) { draw_sprites_aga_sp(e, 0, 0, 0); } -static void draw_sprites_aga_dp_hi_nat(struct sprite_entry* e) { draw_sprites_aga_dp(e, 0, 0, 0); } -static void draw_sprites_aga_ham_hi_nat(struct sprite_entry* e) { draw_sprites_aga_ham(e, 0, 0, 0); } - -static void draw_sprites_aga_sp_hi_at(struct sprite_entry* e) { draw_sprites_aga_sp(e, 0, 0, 1); } -static void draw_sprites_aga_dp_hi_at(struct sprite_entry* e) { draw_sprites_aga_dp(e, 0, 0, 1); } -static void draw_sprites_aga_ham_hi_at(struct sprite_entry* e) { draw_sprites_aga_ham(e, 0, 0, 1); } - -static void draw_sprites_aga_sp_shi_nat(struct sprite_entry* e) { draw_sprites_aga_sp(e, 1, 0, 0); } -static void draw_sprites_aga_dp_shi_nat(struct sprite_entry* e) { draw_sprites_aga_dp(e, 1, 0, 0); } -static void draw_sprites_aga_ham_shi_nat(struct sprite_entry* e) { draw_sprites_aga_ham(e, 1, 0, 0); } - -static void draw_sprites_aga_sp_shi_at(struct sprite_entry* e) { draw_sprites_aga_sp(e, 1, 0, 1); } -static void draw_sprites_aga_dp_shi_at(struct sprite_entry* e) { draw_sprites_aga_dp(e, 1, 0, 1); } -static void draw_sprites_aga_ham_shi_at(struct sprite_entry* e) { draw_sprites_aga_ham(e, 1, 0, 1); } - -static draw_sprites_func draw_sprites_aga_sp_lo[2] = { - draw_sprites_aga_sp_lo_nat, - draw_sprites_aga_sp_lo_at -}; -static draw_sprites_func draw_sprites_aga_sp_hi[2] = { - draw_sprites_aga_sp_hi_nat, - draw_sprites_aga_sp_hi_at -}; -static draw_sprites_func draw_sprites_aga_sp_shi[2] = { - draw_sprites_aga_sp_shi_nat, - draw_sprites_aga_sp_shi_at -}; - -static draw_sprites_func draw_sprites_aga_dp_lo[2] = { - draw_sprites_aga_dp_lo_nat, - draw_sprites_aga_dp_lo_at -}; -static draw_sprites_func draw_sprites_aga_dp_hi[2] = { - draw_sprites_aga_dp_hi_nat, - draw_sprites_aga_dp_hi_at -}; -static draw_sprites_func draw_sprites_aga_dp_shi[2] = { - draw_sprites_aga_dp_shi_nat, - draw_sprites_aga_dp_shi_at -}; - -static draw_sprites_func draw_sprites_aga_ham_lo[2] = { - draw_sprites_aga_ham_lo_nat, - draw_sprites_aga_ham_lo_at -}; -static draw_sprites_func draw_sprites_aga_ham_hi[2] = { - draw_sprites_aga_ham_hi_nat, - draw_sprites_aga_ham_hi_at -}; -static draw_sprites_func draw_sprites_aga_ham_shi[2] = { - draw_sprites_aga_ham_shi_nat, - draw_sprites_aga_ham_shi_at -}; - -STATIC_INLINE void decide_draw_sprites() +STATIC_INLINE void draw_sprites_ecs(struct sprite_entry *e) { - if (aga_mode) - { - int diff = sprite_buffer_res - bplres; - if (diff > 0) - { // doubling = 0, skip = 1 - if (bpldualpf) - { // ham = 0, dualpf = 1 - draw_sprites_punt = draw_sprites_aga_dp_lo; - } - else if (dp_for_drawing->ham_seen) - { // ham = 1, dualpf = 0 - draw_sprites_punt = draw_sprites_aga_ham_lo; - } - else - { // ham = 0, dualpf = 0 - draw_sprites_punt = draw_sprites_aga_sp_lo; - } - } - else if (diff == 0) - { // doubling = 0, skip = 0 - if (bpldualpf) - { // ham = 0, dualpf = 1 - draw_sprites_punt = draw_sprites_aga_dp_hi; - } - else if (dp_for_drawing->ham_seen) - { // ham = 1, dualpf = 0 - draw_sprites_punt = draw_sprites_aga_ham_hi; - } - else - { // ham = 0, dualpf = 0 - draw_sprites_punt = draw_sprites_aga_sp_hi; - } - } + if (e->has_attached) { + if (bpldualpf) + draw_sprites_normal_dp_at(e); else - { // doubling = 1, skip = 0 - if (bpldualpf) - { // ham = 0, dualpf = 1 - draw_sprites_punt = draw_sprites_aga_dp_shi; - } - else if (dp_for_drawing->ham_seen) - { // ham = 1, dualpf = 0 - draw_sprites_punt = draw_sprites_aga_ham_shi; - } - else - { // ham = 0, dualpf = 0 - draw_sprites_punt = draw_sprites_aga_sp_shi; - } - } + draw_sprites_normal_sp_at(e); } - else - { - if (bplres == RES_LORES) - if (bpldualpf) - draw_sprites_punt = draw_sprites_dp_lo; - else if (dp_for_drawing->ham_seen) - draw_sprites_punt = draw_sprites_ham_lo; - else - draw_sprites_punt = draw_sprites_sp_lo; - else if (bpldualpf) - draw_sprites_punt = draw_sprites_dp_hi; - else if (dp_for_drawing->ham_seen) - draw_sprites_punt = draw_sprites_ham_hi; + else { + if (bpldualpf) + draw_sprites_normal_dp_nat(e); else - draw_sprites_punt = draw_sprites_sp_hi; + draw_sprites_normal_sp_nat(e); } } +#ifdef AGA +/* clear possible bitplane data outside DIW area */ +static void clear_bitplane_border_aga(void) +{ + int len, shift = res_shift; + uae_u8 v = 0; + + if (shift < 0) { + shift = -shift; + len = (real_playfield_start - playfield_start) << shift; + memset(pixdata.apixels + pixels_offset + (playfield_start << shift), v, len); + len = (playfield_end - real_playfield_end) << shift; + memset(pixdata.apixels + pixels_offset + (real_playfield_end << shift), v, len); + } + else { + len = (real_playfield_start - playfield_start) >> shift; + memset(pixdata.apixels + pixels_offset + (playfield_start >> shift), v, len); + len = (playfield_end - real_playfield_end) >> shift; + memset(pixdata.apixels + pixels_offset + (real_playfield_end >> shift), v, len); + } +} +#endif + +static void weird_bitplane_fix(int start, int end) +{ + int sh = lores_shift; + uae_u8 *p = pixdata.apixels + pixels_offset; + + start >>= sh; + end >>= sh; + if (bplplanecnt == 5 && !bpldualpf) { + /* emulate OCS/ECS only undocumented "SWIV" hardware feature */ + for (int i = start; i < end; i++) { + if (p[i] & 16) + p[i] = 16; + } + } + else if (bpldualpf && bpldualpfpri) { + /* in dualplayfield mode this feature is even more strange.. */ + for (int i = start; i < end; i++) { + if (p[i] & (2 | 8 | 32)) + p[i] |= 0x40; + } + } + else if (bpldualpf && !bpldualpfpri) { + for (int i = start; i < end; i++) { + p[i] &= ~(2 | 8 | 32); + } + } +} + +/* We use the compiler's inlining ability to ensure that PLANES is in effect a compile time +constant. That will cause some unnecessary code to be optimized away. +Don't touch this if you don't know what you are doing. */ + #define MERGE(a,b,mask,shift) do {\ uae_u32 tmp = mask & (a ^ (b >> shift)); \ a ^= tmp; \ @@ -1567,7 +2344,8 @@ STATIC_INLINE void decide_draw_sprites() #define DATA_POINTER(n) (line_data[lineno] + (n) * MAX_WORDS_PER_LINE * 2) -#ifdef USE_ARMNEON +//TODO Test if this is actually faster +#ifdef NO_USE_ARMNEON #ifdef __cplusplus extern "C" @@ -1734,11 +2512,6 @@ static pfield_doline_func pfield_doline_n[9] = { #else -static uae_u8 *real_bplpt[8]; - -/* We use the compiler's inlining ability to ensure that PLANES is in effect a compile time - constant. That will cause some unnecessary code to be optimized away. - Don't touch this if you don't know what you are doing. */ STATIC_INLINE void pfield_doline_1(uae_u32 *pixels, int wordcount, int planes) { while (wordcount-- > 0) { @@ -1746,8 +2519,10 @@ STATIC_INLINE void pfield_doline_1(uae_u32 *pixels, int wordcount, int planes) b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0, b6 = 0, b7 = 0; switch (planes) { +#ifdef AGA case 8: b0 = GETLONG(real_bplpt[7]); real_bplpt[7] += 4; case 7: b1 = GETLONG(real_bplpt[6]); real_bplpt[6] += 4; +#endif case 6: b2 = GETLONG(real_bplpt[5]); real_bplpt[5] += 4; case 5: b3 = GETLONG(real_bplpt[4]); real_bplpt[4] += 4; case 4: b4 = GETLONG(real_bplpt[3]); real_bplpt[3] += 4; @@ -1793,34 +2568,42 @@ STATIC_INLINE void pfield_doline_1(uae_u32 *pixels, int wordcount, int planes) } /* See above for comments on inlining. These functions should _not_ - be inlined themselves. */ +be inlined themselves. */ static void NOINLINE pfield_doline_n1(uae_u32 *data, int count) { pfield_doline_1(data, count, 1); } static void NOINLINE pfield_doline_n2(uae_u32 *data, int count) { pfield_doline_1(data, count, 2); } static void NOINLINE pfield_doline_n3(uae_u32 *data, int count) { pfield_doline_1(data, count, 3); } static void NOINLINE pfield_doline_n4(uae_u32 *data, int count) { pfield_doline_1(data, count, 4); } static void NOINLINE pfield_doline_n5(uae_u32 *data, int count) { pfield_doline_1(data, count, 5); } static void NOINLINE pfield_doline_n6(uae_u32 *data, int count) { pfield_doline_1(data, count, 6); } +#ifdef AGA static void NOINLINE pfield_doline_n7(uae_u32 *data, int count) { pfield_doline_1(data, count, 7); } static void NOINLINE pfield_doline_n8(uae_u32 *data, int count) { pfield_doline_1(data, count, 8); } +#endif #endif /* USE_ARMNEON */ static void pfield_doline(int lineno) { int wordcount = dp_for_drawing->plflinelen; - uae_u32* data = pixdata.apixels_l + MAX_PIXELS_PER_LINE / 4; + uae_u32 *data = pixdata.apixels_l + MAX_PIXELS_PER_LINE / 4; -#ifdef USE_ARMNEON + //TODO Test if this is actually faster +#ifdef NO_USE_ARMNEON pfield_doline_n[bplplanecnt](data, wordcount, lineno); #else +#ifdef SMART_UPDATE +//#define DATA_POINTER(n) ((debug_bpl_mask & (1 << n)) ? (line_data[lineno] + (n) * MAX_WORDS_PER_LINE * 2) : (debug_bpl_mask_one ? all_ones : all_zeros)) real_bplpt[0] = DATA_POINTER(0); real_bplpt[1] = DATA_POINTER(1); real_bplpt[2] = DATA_POINTER(2); real_bplpt[3] = DATA_POINTER(3); real_bplpt[4] = DATA_POINTER(4); real_bplpt[5] = DATA_POINTER(5); +#ifdef AGA real_bplpt[6] = DATA_POINTER(6); real_bplpt[7] = DATA_POINTER(7); +#endif +#endif switch (bplplanecnt) { default: break; @@ -1831,16 +2614,38 @@ static void pfield_doline(int lineno) case 4: pfield_doline_n4(data, wordcount); break; case 5: pfield_doline_n5(data, wordcount); break; case 6: pfield_doline_n6(data, wordcount); break; +#ifdef AGA case 7: pfield_doline_n7(data, wordcount); break; case 8: pfield_doline_n8(data, wordcount); break; - } +#endif +} #endif /* USE_ARMNEON */ + + if (refresh_indicator_buffer && refresh_indicator_height > lineno) { + uae_u8 *opline = refresh_indicator_buffer + lineno * MAX_PIXELS_PER_LINE * 2; + wordcount *= 32; + if (!memcmp(opline, data, wordcount)) { + if (refresh_indicator_changed[lineno] != 0xff) { + refresh_indicator_changed[lineno]++; + if (refresh_indicator_changed[lineno] > refresh_indicator_changed_prev[lineno]) { + refresh_indicator_changed_prev[lineno] = refresh_indicator_changed[lineno]; + } + } + } + else { + memcpy(opline, data, wordcount); + if (refresh_indicator_changed[lineno] != refresh_indicator_changed_prev[lineno]) + refresh_indicator_changed_prev[lineno] = 0; + refresh_indicator_changed[lineno] = 0; + } + } } -void init_row_map() +void init_row_map(void) { - static uae_u8* oldbufmem; + static uae_u8 *oldbufmem; static int oldheight, oldpitch; + static bool oldgenlock; int i, j; if (gfxvidinfo.outheight > max_uae_height) @@ -1848,23 +2653,44 @@ void init_row_map() write_log(_T("Resolution too high, aborting\n")); abort(); } - if (!row_map) + if (!row_map) { row_map = xmalloc(uae_u8*, max_uae_height + 1); + row_map_genlock = xmalloc(uae_u8*, max_uae_height + 1); + } if (oldbufmem && oldbufmem == gfxvidinfo.bufmem && oldheight == gfxvidinfo.outheight && - oldpitch == gfxvidinfo.rowbytes) + oldpitch == gfxvidinfo.rowbytes && + oldgenlock == init_genlock_data) return; - + xfree(row_map_genlock_buffer); + row_map_genlock_buffer = NULL; + if (init_genlock_data) { + row_map_genlock_buffer = xcalloc(uae_u8, gfxvidinfo.outwidth * (gfxvidinfo.outheight + 2)); + } + xfree(row_map_color_burst_buffer); + row_map_color_burst_buffer = NULL; + //if (currprefs.cs_color_burst) { + // row_map_color_burst_buffer = xcalloc(uae_u8, gfxvidinfo.outheight + 2); + //} j = oldheight == 0 ? max_uae_height : oldheight; - for (i = gfxvidinfo.outheight; i < max_uae_height + 1 && i < j + 1; i++) + for (i = gfxvidinfo.outheight; i < max_uae_height + 1 && i < j + 1; i++) { row_map[i] = row_tmp; - for (i = 0 , j = 0; i < gfxvidinfo.outheight; i++ , j += gfxvidinfo.rowbytes) + row_map_genlock[i] = row_tmp; + } + for (i = 0, j = 0; i < gfxvidinfo.outheight; i++, j += gfxvidinfo.rowbytes) { row_map[i] = gfxvidinfo.bufmem + j; - + if (init_genlock_data) { + row_map_genlock[i] = row_map_genlock_buffer + gfxvidinfo.outwidth * (i + 1); + } + else { + row_map_genlock[i] = NULL; + } + } oldbufmem = gfxvidinfo.bufmem; oldheight = gfxvidinfo.outheight; oldpitch = gfxvidinfo.rowbytes; + oldgenlock = init_genlock_data; } static void init_aspect_maps() @@ -1877,6 +2703,12 @@ static void init_aspect_maps() /* Do nothing if the gfx driver hasn't initialized the screen yet */ return; + linedbld = linedbl = currprefs.gfx_vresolution; + if (doublescan > 0 && interlace_seen <= 0) { + linedbl = 0; + linedbld = 1; + } + if (native2amiga_line_map) xfree(native2amiga_line_map); if (amiga2aspect_line_map) @@ -1886,8 +2718,8 @@ static void init_aspect_maps() amiga2aspect_line_map = xmalloc(int, (MAXVPOS + 1) * 2 + 1); native2amiga_line_map = xmalloc(int, h); - maxl = MAXVPOS + 1; - min_ypos_for_screen = minfirstline; + maxl = (MAXVPOS + 1) << linedbld; + min_ypos_for_screen = minfirstline << linedbl; max_drawn_amiga_line = -1; for (i = 0; i < maxl; i++) { int v = i - min_ypos_for_screen; @@ -1897,88 +2729,167 @@ static void init_aspect_maps() v = -1; amiga2aspect_line_map[i] = v; } - if (max_drawn_amiga_line < 0) max_drawn_amiga_line = maxl - min_ypos_for_screen; - if (max_drawn_amiga_line > gfxvidinfo.outheight) - max_drawn_amiga_line = gfxvidinfo.outheight; for (i = 0; i < h; i++) native2amiga_line_map[i] = -1; - for (i = maxl - 1; i >= min_ypos_for_screen; i--) - { + for (i = maxl - 1; i >= min_ypos_for_screen; i--) { int j; if (amiga2aspect_line_map[i] == -1) continue; for (j = amiga2aspect_line_map[i]; j < h && native2amiga_line_map[j] == -1; j++) - native2amiga_line_map[j] = i; + native2amiga_line_map[j] = i >> linedbl; } + + visible_left_start = 0; + visible_right_stop = MAX_STOP; + visible_top_start = 0; + visible_bottom_stop = MAX_STOP; + set_blanking_limits(); } /* - * One drawing frame has been finished. Tell the graphics code about it. - */ +* A raster line has been built in the graphics buffer. Tell the graphics code +* to do anything necessary to display it. +*/ +static void do_flush_line_1(int lineno) +{ + if (lineno < first_drawn_line) + first_drawn_line = lineno; + if (lineno > last_drawn_line) + last_drawn_line = lineno; + + //if (gfxvidinfo.maxblocklines == 0) + // flush_line(vb, lineno); + //else { + // if ((last_block_line + 2) < lineno) { + // if (first_block_line != NO_BLOCK) + // flush_block(vb, first_block_line, last_block_line); + // first_block_line = lineno; + // } + // last_block_line = lineno; + // if (last_block_line - first_block_line >= gfxvidinfo.maxblocklines) { + // flush_block(vb, first_block_line, last_block_line); + // first_block_line = last_block_line = NO_BLOCK; + // } + //} +} + +STATIC_INLINE void do_flush_line(int lineno) +{ + do_flush_line_1(lineno); +} + +/* +* One drawing frame has been finished. Tell the graphics code about it. +* Note that the actual flush_screen() call is a no-op for all reasonable +* systems. +*/ STATIC_INLINE void do_flush_screen() { - unlockscr(); flush_screen(); /* vsync mode */ } /* We only save hardware registers during the hardware frame. Now, when * drawing the frame, we expand the data into a slightly more useful * form. */ -static void pfield_expand_dp_bplcon() +static void pfield_expand_dp_bplcon(void) { + bool pfield_mode_changed = false; + bplres = dp_for_drawing->bplres; bplplanecnt = dp_for_drawing->nr_planes; bplham = dp_for_drawing->ham_seen; - if (aga_mode) - { - bplehb = (dp_for_drawing->bplcon0 & 0x7010) == 0x6000; - bpldualpf2of = dp_for_drawing->bplcon3 >> 10 & 7; - sbasecol[0] = (dp_for_drawing->bplcon4 >> 4 & 15) << 4; - sbasecol[1] = (dp_for_drawing->bplcon4 >> 0 & 15) << 4; - bplxor = dp_for_drawing->bplcon4 >> 8; - } - else - bplehb = (dp_for_drawing->bplcon0 & 0xFC00) == 0x6000 || (dp_for_drawing->bplcon0 & 0xFC00) == 0x7000; - if (currprefs.chipset_mask & CSMASK_ECS_DENISE && dp_for_drawing->bplcon2 & 0x0200) + bplehb = dp_for_drawing->ehb_seen; + if ((currprefs.chipset_mask & CSMASK_ECS_DENISE) && (dp_for_drawing->bplcon2 & 0x0200)) bplehb = 0; + issprites = dip_for_drawing->nr_sprites > 0; + bplcolorburst = (dp_for_drawing->bplcon0 & 0x200) != 0; + if (!bplcolorburst) + bplcolorburst_field = 0; +#ifdef ECS_DENISE + int oecsshres = ecsshres; + ecsshres = bplres == RES_SUPERHIRES && (currprefs.chipset_mask & CSMASK_ECS_DENISE) && !(currprefs.chipset_mask & CSMASK_AGA); + pfield_mode_changed = oecsshres != ecsshres; +#endif plf1pri = dp_for_drawing->bplcon2 & 7; plf2pri = (dp_for_drawing->bplcon2 >> 3) & 7; plf_sprite_mask = 0xFFFF0000 << (4 * plf2pri); plf_sprite_mask |= (0x0000FFFF << (4 * plf1pri)) & 0xFFFF; - plf_sprite_mask_n16 = ~(plf_sprite_mask >> 16); bpldualpf = (dp_for_drawing->bplcon0 & 0x400) == 0x400; bpldualpfpri = (dp_for_drawing->bplcon2 & 0x40) == 0x40; + +#ifdef AGA + // BYPASS: HAM and EHB select bits are ignored + if (bplbypass != (dp_for_drawing->bplcon0 & 0x20) != 0) { + bpland = 0xff; + bplbypass = (dp_for_drawing->bplcon0 & 0x20) != 0; + pfield_mode_changed = true; + } + if (bplbypass) { + if (bplham && bplplanecnt == 6) + bpland = 0x0f; + if (bplham && bplplanecnt == 8) + bpland = 0xfc; + bplham = 0; + if (bplehb) + bpland = 31; + bplehb = 0; + } + bpldualpf2of = (dp_for_drawing->bplcon3 >> 10) & 7; + sbasecol[0] = ((dp_for_drawing->bplcon4 >> 4) & 15) << 4; + sbasecol[1] = ((dp_for_drawing->bplcon4 >> 0) & 15) << 4; + bplxor = dp_for_drawing->bplcon4 >> 8; + int sh = (colors_for_drawing.extra >> CE_SHRES_DELAY) & 3; + if (sh != bpldelay_sh) { + bpldelay_sh = sh; + pfield_mode_changed = true; + } +#endif + ecs_genlock_features_active = (currprefs.chipset_mask & CSMASK_ECS_DENISE) && ((dp_for_drawing->bplcon2 & 0x0c00) || ce_is_borderntrans(colors_for_drawing.extra)) ? 1 : 0; + if (ecs_genlock_features_active) { + ecs_genlock_features_colorkey = false; + ecs_genlock_features_mask = 0; + if (dp_for_drawing->bplcon3 & 0x0800) { + ecs_genlock_features_mask = 1 << ((dp_for_drawing->bplcon2 >> 12) & 7); + } + if (dp_for_drawing->bplcon3 & 0x0400) { + ecs_genlock_features_colorkey = true; + } + } + if (pfield_mode_changed) + pfield_set_linetoscr(); } static bool isham(uae_u16 bplcon0) { int p = GET_PLANES(bplcon0); if (!(bplcon0 & 0x800)) - return false; - if (aga_mode) - { + return 0; + if (currprefs.chipset_mask & CSMASK_AGA) { // AGA only has 6 or 8 plane HAM if (p == 6 || p == 8) - return true; + return 1; } - else - { + else { // OCS/ECS also supports 5 plane HAM if (GET_RES_DENISE(bplcon0) > 0) - return false; + return 0; if (p >= 5) - return true; + return 1; } - return false; + return 0; } static void pfield_expand_dp_bplconx(int regno, int v) { + if (regno == 0xffff) { + hposblank = 1; + return; + } regno -= 0x1000; switch (regno) { @@ -1991,62 +2902,76 @@ static void pfield_expand_dp_bplconx(int regno, int v) case 0x104: // BPLCON2 dp_for_drawing->bplcon2 = v; break; +#ifdef ECS_DENISE case 0x106: // BPLCON3 dp_for_drawing->bplcon3 = v; break; +#endif +#ifdef AGA case 0x10c: // BPLCON4 dp_for_drawing->bplcon4 = v; break; +#endif } pfield_expand_dp_bplcon(); - // res_shift = lores_shift - bplres; + set_res_shift(lores_shift - bplres); } static int drawing_color_matches; - -static enum -{ - color_match_acolors, - color_match_full -} color_match_type; +static enum { color_match_acolors, color_match_full } color_match_type; /* Set up colors_for_drawing to the state at the beginning of the currently drawn - line. Try to avoid copying color tables around whenever possible. */ +line. Try to avoid copying color tables around whenever possible. */ static void adjust_drawing_colors(int ctable, int need_full) { - if (drawing_color_matches != ctable || need_full < 0) - { - if (need_full) - { + if (drawing_color_matches != ctable || need_full < 0) { + if (need_full) { color_reg_cpy(&colors_for_drawing, curr_color_tables + ctable); color_match_type = color_match_full; } - else - { - memcpy(colors_for_drawing.acolors, - curr_color_tables[ctable].acolors, - sizeof colors_for_drawing.acolors); + else { + memcpy(colors_for_drawing.acolors, curr_color_tables[ctable].acolors, + sizeof colors_for_drawing.acolors); colors_for_drawing.extra = curr_color_tables[ctable].extra; color_match_type = color_match_acolors; } drawing_color_matches = ctable; } - else if (need_full && color_match_type != color_match_full) - { + else if (need_full && color_match_type != color_match_full) { color_reg_cpy(&colors_for_drawing, &curr_color_tables[ctable]); color_match_type = color_match_full; } } -STATIC_INLINE void do_color_changes(line_draw_func worker_border, line_draw_func worker_pfield) +static void playfield_hard_way(line_draw_func worker_pfield, int first, int last) +{ + if (first < real_playfield_start) { + int next = last < real_playfield_start ? last : real_playfield_start; + int diff = next - first; + pfield_do_linetoscr_bordersprite_aga(first, next, false); + if (res_shift >= 0) + diff >>= res_shift; + else + diff <<= res_shift; + src_pixel += diff; + first = next; + } + (*worker_pfield)(first, last < real_playfield_end ? last : real_playfield_end, false); + if (last > real_playfield_end) + pfield_do_linetoscr_bordersprite_aga(real_playfield_end, last, false); +} + +static void do_color_changes(line_draw_func worker_border, line_draw_func worker_pfield, int vp) { int i; int lastpos = visible_left_border; - int endpos = visible_right_border; + int endpos = visible_left_border + gfxvidinfo.outwidth; - for (i = dip_for_drawing->first_color_change; i <= dip_for_drawing->last_color_change; i++) - { + for (i = dip_for_drawing->first_color_change; i <= dip_for_drawing->last_color_change; i++) { + int regno = curr_color_changes[i].regno; + unsigned int value = curr_color_changes[i].value; int nextpos, nextpos_in_range; + if (i == dip_for_drawing->last_color_change) nextpos = endpos; else @@ -2056,219 +2981,758 @@ STATIC_INLINE void do_color_changes(line_draw_func worker_border, line_draw_func if (nextpos > endpos) nextpos_in_range = endpos; + // left hblank (left edge to hblank end) + if (nextpos_in_range > lastpos && lastpos < hblank_left_start) { + int t = nextpos_in_range <= hblank_left_start ? nextpos_in_range : hblank_left_start; + (*worker_border) (lastpos, t, true); + lastpos = t; + } + // left border (hblank end to playfield start) - if (nextpos_in_range > lastpos && lastpos < playfield_start) - { + if (nextpos_in_range > lastpos && lastpos < playfield_start) { int t = nextpos_in_range <= playfield_start ? nextpos_in_range : playfield_start; - (*worker_border)(lastpos, t); + (*worker_border) (lastpos, t, false); lastpos = t; } // playfield - if (nextpos_in_range > lastpos && lastpos >= playfield_start && lastpos < playfield_end) - { + if (nextpos_in_range > lastpos && lastpos >= playfield_start && lastpos < playfield_end) { int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end; - (*worker_pfield)(lastpos, t); + if (plf2pri > 5 && !(currprefs.chipset_mask & CSMASK_AGA)) + weird_bitplane_fix(lastpos, t); + if (bplxor && may_require_hard_way && worker_pfield != pfield_do_linetoscr_bordersprite_aga) + playfield_hard_way(worker_pfield, lastpos, t); + else + (*worker_pfield) (lastpos, t, false); lastpos = t; } // right border (playfield end to hblank start) - if (nextpos_in_range > lastpos && lastpos >= playfield_end) - { - (*worker_border)(lastpos, nextpos_in_range); + if (nextpos_in_range > lastpos && lastpos >= playfield_end) { + int t = nextpos_in_range <= hblank_right_stop ? nextpos_in_range : hblank_right_stop; + (*worker_border) (lastpos, t, false); + lastpos = t; + } + + // right hblank (hblank start to right edge, hblank start may be earlier than playfield end) + if (nextpos_in_range > hblank_right_stop) { + (*worker_border) (hblank_right_stop, nextpos_in_range, true); lastpos = nextpos_in_range; } - if (i != dip_for_drawing->last_color_change) - { - int regno = curr_color_changes[i].regno; - unsigned int value = curr_color_changes[i].value; - if (regno >= 0x1000) - { - pfield_expand_dp_bplconx(regno, value); + if (regno >= 0x1000) { + pfield_expand_dp_bplconx(regno, value); + } + else if (regno >= 0 && !(value & COLOR_CHANGE_MASK)) { + color_reg_set(&colors_for_drawing, regno, value); + colors_for_drawing.acolors[regno] = getxcolor(value); + } + else if (regno == 0 && (value & COLOR_CHANGE_MASK)) { + if (value & COLOR_CHANGE_BRDBLANK) { + colors_for_drawing.extra &= ~(1 << CE_BORDERBLANK); + colors_for_drawing.extra &= ~(1 << CE_BORDERNTRANS); + colors_for_drawing.extra &= ~(1 << CE_BORDERSPRITE); + colors_for_drawing.extra |= (value & 1) != 0 ? (1 << CE_BORDERBLANK) : 0; + colors_for_drawing.extra |= (value & 3) == 2 ? (1 << CE_BORDERSPRITE) : 0; + colors_for_drawing.extra |= (value & 5) == 4 ? (1 << CE_BORDERNTRANS) : 0; } - else if (regno >= 0) - { - if (regno == 0 && (value & COLOR_CHANGE_BRDBLANK)) - { - colors_for_drawing.extra = (value & 1) != 0; - colors_for_drawing.extra = (value & 3) == 2; - } - else - { - color_reg_set(&colors_for_drawing, regno, value); - colors_for_drawing.acolors[regno] = getxcolor(value); - } + else if (value & COLOR_CHANGE_SHRES_DELAY) { + colors_for_drawing.extra &= ~(1 << CE_SHRES_DELAY); + colors_for_drawing.extra &= ~(1 << (CE_SHRES_DELAY + 1)); + colors_for_drawing.extra |= (value & 3) << CE_SHRES_DELAY; + pfield_expand_dp_bplcon(); + } + else if (value & COLOR_CHANGE_HSYNC_HACK) { + hsync_shift_hack = (uae_s8)value; } } if (lastpos >= endpos) break; } + + if (vp < visible_top_start || vp >= visible_bottom_stop) { + // outside of visible area + // Just overwrite with black. Above code needs to run because of custom registers, + // not worth the trouble for separate code path just for max 10 lines or so + (*worker_border) (visible_left_border, visible_left_border + gfxvidinfo.outwidth, true); + } + + if (hsync_shift_hack > 0) { + // hpos shift hack + int shift = (hsync_shift_hack << lores_shift) * gfxvidinfo.pixbytes; + if (shift) { + int firstpos = visible_left_border * gfxvidinfo.pixbytes; + int lastpos = (visible_left_border + gfxvidinfo.outwidth) * gfxvidinfo.pixbytes; + memmove(xlinebuffer + firstpos, xlinebuffer + firstpos + shift, lastpos - firstpos - shift); + memset(xlinebuffer + lastpos - shift, 0, shift); + } + } } -static void pfield_draw_line(int lineno, int gfx_ypos) +STATIC_INLINE bool is_color_changes(struct draw_info *di) { + int regno = curr_color_changes[di->first_color_change].regno; + int changes = di->nr_color_changes; + return changes > 1 || (changes == 1 && regno != 0xffff && regno != -1); +} + +enum double_how { + dh_buf, + dh_line, + dh_emerg +}; + +static void pfield_draw_line(int lineno, int gfx_ypos, int follow_ypos) +{ + static int warned = 0; int border = 0; + int do_double = 0; + bool have_color_changes; + enum double_how dh; + int ls = linestate[lineno]; + dp_for_drawing = line_decisions + lineno; dip_for_drawing = curr_drawinfo + lineno; - if (dp_for_drawing->plfleft < 0) - border = 1; + if (dp_for_drawing->plfleft >= 0) { + lines_count++; + resolution_count[dp_for_drawing->bplres]++; + } - xlinebuffer = row_map[gfx_ypos]; - xlinebuffer -= linetoscr_x_adjust_bytes; - - if (border == 0) + switch (ls) { + case LINE_REMEMBERED_AS_PREVIOUS: + // if (!warned) // happens when program messes up with VPOSW + // write_log (_T("Shouldn't get here... this is a bug.\n")), warned++; + return; + + case LINE_BLACK: + linestate[lineno] = LINE_REMEMBERED_AS_BLACK; + border = -1; + break; + + case LINE_REMEMBERED_AS_BLACK: + return; + + case LINE_AS_PREVIOUS: + dp_for_drawing--; + dip_for_drawing--; + linestate[lineno] = LINE_DONE_AS_PREVIOUS; + if (dp_for_drawing->plfleft < 0) + border = 1; + break; + + case LINE_DONE_AS_PREVIOUS: + /* fall through */ + case LINE_DONE: + return; + + case LINE_DECIDED_DOUBLE: + if (follow_ypos >= 0) { + do_double = 1; + linestate[lineno + 1] = LINE_DONE_AS_PREVIOUS; + } + + /* fall through */ + default: + if (dp_for_drawing->plfleft < 0) + border = 1; + linestate[lineno] = LINE_DONE; + break; + } + + have_color_changes = is_color_changes(dip_for_drawing); + + dh = dh_line; + xlinebuffer = row_map[gfx_ypos], dh = dh_buf; + xlinebuffer -= linetoscr_x_adjust_pixbytes; + xlinebuffer_genlock = row_map_genlock[gfx_ypos] - linetoscr_x_adjust_pixels; + + if (row_map_color_burst_buffer) + row_map_color_burst_buffer[gfx_ypos] = bplcolorburst; + + if (border == 0) { + pfield_expand_dp_bplcon(); - pfield_init_linetoscr(); + pfield_init_linetoscr(false); pfield_doline(lineno); - adjust_drawing_colors(dp_for_drawing->ctable, dp_for_drawing->ham_seen || bplehb); + adjust_drawing_colors(dp_for_drawing->ctable, dp_for_drawing->ham_seen || bplehb || ecsshres); /* The problem is that we must call decode_ham() BEFORE we do the sprites. */ - if (dp_for_drawing->ham_seen) - { + if (dp_for_drawing->ham_seen) { + int ohposblank = hposblank; + uae_u8 b0 = dp_for_drawing->bplcon0; + uae_u8 b2 = dp_for_drawing->bplcon2; + uae_u8 b3 = dp_for_drawing->bplcon3; + uae_u8 b4 = dp_for_drawing->bplcon4; init_ham_decoding(); - if (dip_for_drawing->nr_color_changes == 0) - { - /* The easy case: need to do HAM decoding only once for the - * full line. */ - decode_ham(visible_left_border, visible_right_border); - } - else /* Argh. */ - { - do_color_changes(dummy_worker, decode_ham); - // reset colors to state before above do_color_changes() - adjust_drawing_colors(dp_for_drawing->ctable, (dp_for_drawing->ham_seen || bplehb) ? -1 : 0); + do_color_changes(dummy_worker, decode_ham, lineno); + if (have_color_changes) { + // do_color_changes() did color changes and register changes, restore them. + adjust_drawing_colors(dp_for_drawing->ctable, -1); + dp_for_drawing->bplcon0 = b0; + dp_for_drawing->bplcon2 = b2; + dp_for_drawing->bplcon3 = b3; + dp_for_drawing->bplcon4 = b4; pfield_expand_dp_bplcon(); } + hposblank = ohposblank; + ham_decode_pixel = src_pixel; bplham = dp_for_drawing->ham_at_start; } - if (dip_for_drawing->nr_sprites) - { + if (dip_for_drawing->nr_sprites) { int i; - decide_draw_sprites(); - for (i = 0; i < dip_for_drawing->nr_sprites; i++) - { - struct sprite_entry* e = curr_sprite_entries + dip_for_drawing->first_sprite_entry + i; - draw_sprites_punt[e->has_attached](e); +#ifdef AGA + if (ce_is_bordersprite(colors_for_drawing.extra) && dp_for_drawing->bordersprite_seen && !ce_is_borderblank(colors_for_drawing.extra)) + clear_bitplane_border_aga(); +#endif + + for (i = 0; i < dip_for_drawing->nr_sprites; i++) { +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) + draw_sprites_aga(curr_sprite_entries + dip_for_drawing->first_sprite_entry + i, 1); + else +#endif + draw_sprites_ecs(curr_sprite_entries + dip_for_drawing->first_sprite_entry + i); } } - do_color_changes(pfield_do_fill_line, pfield_do_linetoscr); +#ifdef AGA + if (dip_for_drawing->nr_sprites && ce_is_bordersprite(colors_for_drawing.extra) && !ce_is_borderblank(colors_for_drawing.extra) && dp_for_drawing->bordersprite_seen) + do_color_changes(pfield_do_linetoscr_bordersprite_aga, pfield_do_linetoscr_spr, lineno); + else +#endif + do_color_changes(pfield_do_fill_line, dip_for_drawing->nr_sprites ? pfield_do_linetoscr_spr : pfield_do_linetoscr, lineno); + + if (dh == dh_emerg) + memcpy(row_map[gfx_ypos], xlinebuffer + linetoscr_x_adjust_pixbytes, gfxvidinfo.pixbytes * gfxvidinfo.outwidth); + + do_flush_line(gfx_ypos); + if (do_double) { + if (dh == dh_emerg) + memcpy(row_map[follow_ypos], xlinebuffer + linetoscr_x_adjust_pixbytes, gfxvidinfo.pixbytes * gfxvidinfo.outwidth); + else if (dh == dh_buf) + memcpy(row_map[follow_ypos], row_map[gfx_ypos], gfxvidinfo.pixbytes * gfxvidinfo.outwidth); + if (need_genlock_data) + memcpy(row_map_genlock[follow_ypos], row_map_genlock[gfx_ypos], gfxvidinfo.outwidth); + do_flush_line(follow_ypos); + } + + if (dip_for_drawing->nr_sprites) + pfield_erase_hborder_sprites(); } - else - { // border > 0: top or bottom border + else if (border > 0) { // border > 0: top or bottom border + bool dosprites = false; adjust_drawing_colors(dp_for_drawing->ctable, 0); - /* this makes things complex.. */ - if (dp_for_drawing->bordersprite_seen && !colors_for_drawing.extra && dip_for_drawing->nr_sprites) - { +#ifdef AGA /* this makes things complex.. */ + if (dp_for_drawing->bordersprite_seen && !ce_is_borderblank(colors_for_drawing.extra) && dip_for_drawing->nr_sprites) { dosprites = true; pfield_expand_dp_bplcon(); - pfield_init_linetoscr(); + pfield_init_linetoscr(true); + pfield_erase_vborder_sprites(); } +#endif - if (!dosprites && dip_for_drawing->nr_color_changes == 0) - { - fill_line(); + if (!dosprites && !have_color_changes) { + if (dp_for_drawing->plfleft < -1) { + // blanked border line + int tmp = hposblank; + hposblank = 1; + fill_line_border(lineno); + hposblank = tmp; + } + else { + // normal border line + fill_line_border(lineno); + } + + do_flush_line(gfx_ypos); + if (do_double) { + if (dh == dh_buf) { + xlinebuffer = row_map[follow_ypos] - linetoscr_x_adjust_pixbytes; + xlinebuffer_genlock = row_map_genlock[follow_ypos] - linetoscr_x_adjust_pixels; + fill_line_border(lineno); + } + /* If dh == dh_line, do_flush_line will re-use the rendered line + * from linemem. */ + do_flush_line(follow_ypos); + } return; } - if (dosprites) - { - int i; - uae_u16 oxor = bplxor; - memset(pixdata.apixels, 0, sizeof pixdata); - decide_draw_sprites(); - for (i = 0; i < dip_for_drawing->nr_sprites; i++) - { - struct sprite_entry* e = curr_sprite_entries + dip_for_drawing->first_sprite_entry + i; - draw_sprites_punt[e->has_attached](e); - } - if (dp_for_drawing->ham_seen) - { - int todraw_amiga = res_shift_from_window(visible_right_border - visible_left_border); - init_ham_decoding(); - memset(ham_linebuf + ham_decode_pixel, 0, todraw_amiga * sizeof(uae_u32)); - } - bplxor = 0; - do_color_changes(pfield_do_fill_line, pfield_do_linetoscr); - bplxor = oxor; +#ifdef AGA + if (dosprites) { + + for (int i = 0; i < dip_for_drawing->nr_sprites; i++) + draw_sprites_aga(curr_sprite_entries + dip_for_drawing->first_sprite_entry + i, 1); + do_color_changes(pfield_do_linetoscr_bordersprite_aga, pfield_do_linetoscr_bordersprite_aga, lineno); +#else + if (0) { +#endif + } - else - { + else { + playfield_start = visible_right_border; playfield_end = visible_right_border; - do_color_changes(pfield_do_fill_line, pfield_do_fill_line); + do_color_changes(pfield_do_fill_line, pfield_do_fill_line, lineno); + } + + if (dh == dh_emerg) + memcpy(row_map[gfx_ypos], xlinebuffer + linetoscr_x_adjust_pixbytes, gfxvidinfo.pixbytes * gfxvidinfo.outwidth); + do_flush_line(gfx_ypos); + if (do_double) { + if (dh == dh_emerg) + memcpy(row_map[follow_ypos], xlinebuffer + linetoscr_x_adjust_pixbytes, gfxvidinfo.pixbytes * gfxvidinfo.outwidth); + else if (dh == dh_buf) + memcpy(row_map[follow_ypos], row_map[gfx_ypos], gfxvidinfo.pixbytes * gfxvidinfo.outwidth); + if (need_genlock_data) + memcpy(row_map_genlock[follow_ypos], row_map_genlock[gfx_ypos], gfxvidinfo.outwidth); + do_flush_line(follow_ypos); + } + + } else { + + // top or bottom blanking region + int tmp = hposblank; + hposblank = 1; + fill_line_border(lineno); + hposblank = tmp; + do_flush_line(gfx_ypos); + } } static void center_image() { - int deltaToBorder; - deltaToBorder = (gfxvidinfo.outwidth >> currprefs.gfx_resolution) - 320; + int prev_x_adjust = visible_left_border; + int prev_y_adjust = thisframe_y_adjust; - visible_left_border = 73 - (deltaToBorder >> 1); - visible_right_border = 393 + (deltaToBorder >> 1); + int w = gfxvidinfo.outwidth; + if (max_diwstop > 0) { - if (gfxvidinfo.outwidth > 600) - linetoscr_x_adjust_bytes = (visible_left_border * gfxvidinfo.pixbytes) << 1; + if (max_diwstop - min_diwstart < w )//&& currprefs.gfx_xcenter == 2) + /* Try to center. */ + visible_left_border = (max_diwstop - min_diwstart - w) / 2 + min_diwstart; + else + visible_left_border = max_diwstop - w - (max_diwstop - min_diwstart - w) / 2; + visible_left_border &= ~((xshift(1, lores_shift)) - 1); + + if (!center_reset && !vertical_changed) { + /* Would the old value be good enough? If so, leave it as it is if we want to be clever. */ + if (visible_left_border < prev_x_adjust && prev_x_adjust < min_diwstart && min_diwstart - visible_left_border <= 32) + visible_left_border = prev_x_adjust; + } + } else - linetoscr_x_adjust_bytes = visible_left_border * gfxvidinfo.pixbytes; + { + visible_left_border = 0; + } + + if (visible_left_border > max_diwlastword - 32) + visible_left_border = max_diwlastword - 32; + if (visible_left_border < 0) + visible_left_border = 0; + visible_left_border &= ~((xshift(1, lores_shift)) - 1); + + linetoscr_x_adjust_pixels = visible_left_border; + linetoscr_x_adjust_pixbytes = linetoscr_x_adjust_pixels * gfxvidinfo.pixbytes; + + visible_right_border = visible_left_border + w; + if (visible_right_border > max_diwlastword) + visible_right_border = max_diwlastword; + + int max_drawn_amiga_line_tmp = max_drawn_amiga_line; + if (max_drawn_amiga_line_tmp > gfxvidinfo.outheight) + max_drawn_amiga_line_tmp = gfxvidinfo.outheight; + max_drawn_amiga_line_tmp >>= linedbl; thisframe_y_adjust = minfirstline; + if (thisframe_first_drawn_line >= 0) { + if (thisframe_last_drawn_line - thisframe_first_drawn_line < max_drawn_amiga_line_tmp )//&& currprefs.gfx_ycenter == 2) + thisframe_y_adjust = (thisframe_last_drawn_line - thisframe_first_drawn_line - max_drawn_amiga_line_tmp) / 2 + thisframe_first_drawn_line; + else + thisframe_y_adjust = thisframe_first_drawn_line; + /* Would the old value be good enough? If so, leave it as it is if we want to be clever. */ + if (!center_reset && !horizontal_changed) { + if (thisframe_y_adjust != prev_y_adjust) { + if (prev_y_adjust <= thisframe_first_drawn_line && prev_y_adjust + max_drawn_amiga_line_tmp > thisframe_last_drawn_line) + thisframe_y_adjust = prev_y_adjust; + } + } + } /* Make sure the value makes sense */ - if (thisframe_y_adjust + max_drawn_amiga_line > maxvpos + maxvpos / 2) - thisframe_y_adjust = maxvpos + maxvpos / 2 - max_drawn_amiga_line; + if (thisframe_y_adjust + max_drawn_amiga_line_tmp > maxvpos + maxvpos / 2) + thisframe_y_adjust = maxvpos + maxvpos / 2 - max_drawn_amiga_line_tmp; if (thisframe_y_adjust < 0) thisframe_y_adjust = 0; - thisframe_y_adjust_real = thisframe_y_adjust + VERTICAL_OFFSET; - max_ypos_thisframe = (maxvpos_display - minfirstline + 1); + thisframe_y_adjust_real = thisframe_y_adjust << linedbl; + max_ypos_thisframe = (maxvpos_display - minfirstline + 1) << linedbl; + + if (prev_x_adjust != visible_left_border || prev_y_adjust != thisframe_y_adjust) { + int redraw = interlace_seen > 0 && linedbl ? 2 : 1; + if (redraw > frame_redraw_necessary) + frame_redraw_necessary = redraw; + } + + max_diwstop = 0; + min_diwstart = MAX_STOP; + + center_reset = false; + horizontal_changed = false; + vertical_changed = false; } -static void init_drawing_frame() +static int frame_res_cnt; +static int autoswitch_old_resolution; +static void init_drawing_frame(void) { + int i, maxline; + static int frame_res_old; + + int largest_res = 0; + int largest_count = 0; + int largest_count_res = 0; + for (int i = 0; i <= RES_MAX; i++) { + if (resolution_count[i]) + largest_res = i; + if (resolution_count[i] >= largest_count) { + largest_count = resolution_count[i]; + largest_count_res = i; + } + } + if (currprefs.gfx_resolution == changed_prefs.gfx_resolution && lines_count > 0) { + detected_screen_resolution = largest_res; + } + +#if 0 + if (currprefs.gfx_resolution == changed_prefs.gfx_resolution && lines_count > 0) { + + if (currprefs.gfx_autoresolution_vga && programmedmode && gfxvidinfo.gfx_resolution_reserved >= RES_HIRES && gfxvidinfo.gfx_vresolution_reserved >= VRES_DOUBLE) { + if (largest_res == RES_SUPERHIRES && (gfxvidinfo.gfx_resolution_reserved < RES_SUPERHIRES || gfxvidinfo.gfx_vresolution_reserved < 1)) { + // enable full doubling/superhires support if programmed mode. It may be "half-width" only and may fit in normal display window. + gfxvidinfo.gfx_resolution_reserved = RES_SUPERHIRES; + gfxvidinfo.gfx_vresolution_reserved = VRES_DOUBLE; + graphics_reset(false); + } + int newres = largest_res; + if (htotal < 190) + newres = largest_res + 1; + if (newres < RES_HIRES) + newres = RES_HIRES; + if (newres > RES_MAX) + newres = RES_MAX; + if (changed_prefs.gfx_resolution != newres) { + autoswitch_old_resolution = RES_HIRES; + write_log(_T("Programmed mode autores = %d -> %d (%d)\n"), changed_prefs.gfx_resolution, newres, largest_res); + changed_prefs.gfx_resolution = newres; + set_config_changed(); + return; + } + } + else if (autoswitch_old_resolution == RES_HIRES) { + autoswitch_old_resolution = 0; + if (changed_prefs.gfx_resolution != RES_HIRES) { + changed_prefs.gfx_resolution = RES_HIRES; + set_config_changed(); + return; + } + } + + if (currprefs.gfx_autoresolution) { + int frame_res_detected; + int frame_res_lace_detected = frame_res_lace; + + if (currprefs.gfx_autoresolution == 1 || currprefs.gfx_autoresolution >= 100) + frame_res_detected = largest_res; + else if (largest_count * 100 / lines_count >= currprefs.gfx_autoresolution) + frame_res_detected = largest_count_res; + else + frame_res_detected = largest_count_res - 1; + if (frame_res_detected < 0) + frame_res_detected = 0; + + if (frame_res_detected >= 0 && frame_res_lace_detected >= 0) { + if (frame_res_cnt > 0 && frame_res_old == frame_res_detected * 2 + frame_res_lace_detected) { + frame_res_cnt--; + if (frame_res_cnt == 0) { + int m = frame_res_detected * 2 + frame_res_lace_detected; + struct wh *dst = currprefs.gfx_apmode[0].gfx_fullscreen ? &changed_prefs.gfx_size_fs : &changed_prefs.gfx_size_win; + while (m < 3 * 2) { + struct wh *src = currprefs.gfx_apmode[0].gfx_fullscreen ? &currprefs.gfx_size_fs_xtra[m] : &currprefs.gfx_size_win_xtra[m]; + if ((src->width > 0 && src->height > 0) || (currprefs.gfx_api || currprefs.gf[0].gfx_filter > 0)) { + int nr = m >> 1; + int nl = (m & 1) == 0 ? 0 : 1; + int nr_o = nr; + int nl_o = nl; + + if (currprefs.gfx_autoresolution >= 100 && nl == 0 && nr > 0) { + nl = 1; + } + + if (currprefs.gfx_autoresolution_minh < 0) { + if (nr < nl) + nr = nl; + } + else if (nr < currprefs.gfx_autoresolution_minh) { + nr = currprefs.gfx_autoresolution_minh; + } + if (currprefs.gfx_autoresolution_minv < 0) { + if (nl < nr) + nl = nr; + } + else if (nl < currprefs.gfx_autoresolution_minv) { + nl = currprefs.gfx_autoresolution_minv; + } + + if (nr > gfxvidinfo.gfx_resolution_reserved) + nr = gfxvidinfo.gfx_resolution_reserved; + if (nl > gfxvidinfo.gfx_vresolution_reserved) + nl = gfxvidinfo.gfx_vresolution_reserved; + + if (changed_prefs.gfx_resolution != nr || changed_prefs.gfx_vresolution != nl) { + changed_prefs.gfx_resolution = nr; + changed_prefs.gfx_vresolution = nl; + + write_log(_T("RES -> %d (%d) LINE -> %d (%d) (%d - %d, %d - %d)\n"), nr, nr_o, nl, nl_o, + currprefs.gfx_autoresolution_minh, currprefs.gfx_autoresolution_minv, + gfxvidinfo.gfx_resolution_reserved, gfxvidinfo.gfx_vresolution_reserved); + set_config_changed(); + } + if (src->width > 0 && src->height > 0) { + if (memcmp(dst, src, sizeof *dst)) { + *dst = *src; + set_config_changed(); + } + } + break; + } + m++; + } + frame_res_cnt = currprefs.gfx_autoresolution_delay; + } + } + else { + frame_res_old = frame_res_detected * 2 + frame_res_lace_detected; + frame_res_cnt = currprefs.gfx_autoresolution_delay; + if (frame_res_cnt <= 0) + frame_res_cnt = 1; + } + } + } + } +#endif + for (int i = 0; i <= RES_MAX; i++) + resolution_count[i] = 0; + lines_count = 0; + frame_res = -1; + frame_res_lace = 0; + + if (can_use_lores > AUTO_LORES_FRAMES && 0) { + lores_factor = 1; + lores_set(0); + } + else { + can_use_lores++; + lores_reset(); + } + init_hardware_for_drawing_frame(); - linestate_first_undecided = 0; + if (thisframe_first_drawn_line < 0) + thisframe_first_drawn_line = minfirstline; + if (thisframe_first_drawn_line > thisframe_last_drawn_line) + thisframe_last_drawn_line = thisframe_first_drawn_line; + + maxline = ((maxvpos_display + 1) << linedbl) + 2; +#ifdef SMART_UPDATE + for (i = 0; i < maxline; i++) { + int ls = linestate[i]; + switch (ls) { + case LINE_DONE_AS_PREVIOUS: + linestate[i] = LINE_REMEMBERED_AS_PREVIOUS; + break; + case LINE_REMEMBERED_AS_BLACK: + break; + default: + linestate[i] = LINE_UNDECIDED; + break; + } +} +#else + memset(linestate, LINE_UNDECIDED, maxline); +#endif + last_drawn_line = 0; + first_drawn_line = 32767; + + first_block_line = last_block_line = NO_BLOCK; + if (frame_redraw_necessary) { + reset_decision_table(); + custom_frame_redraw_necessary = 1; + frame_redraw_necessary--; + } + else { + custom_frame_redraw_necessary = 0; + } center_image(); + thisframe_first_drawn_line = -1; + thisframe_last_drawn_line = -1; + drawing_color_matches = -1; } +static int lightpen_y1, lightpen_y2; +static int statusbar_y1, statusbar_y2; + +void putpixel(uae_u8 *buf, uae_u8 *genlockbuf, int bpp, int x, xcolnr c8, int opaq) +{ + if (x <= 0) + return; + + if (genlockbuf) + genlockbuf[x] = 0xff; + + switch (bpp) { + case 1: + buf[x] = (uae_u8)c8; + break; + case 2: + { + uae_u16 *p = (uae_u16*)buf + x; + *p = (uae_u16)c8; + break; + } + case 3: + /* no 24 bit yet */ + break; + case 4: + { + int i; + if (1 || opaq || currprefs.gf[0].gfx_filter == 0) { + uae_u32 *p = (uae_u32*)buf + x; + *p = c8; + } + else { + for (i = 0; i < 4; i++) { + int v1 = buf[i + bpp * x]; + int v2 = (c8 >> (i * 8)) & 255; + v1 = (v1 * 2 + v2 * 3) / 5; + if (v1 > 255) + v1 = 255; + buf[i + bpp * x] = v1; + } + } + break; + } + } +} + +static uae_u8 *status_line_ptr(int line) +{ + int y; + + y = line - (gfxvidinfo.outheight - TD_TOTAL_HEIGHT); + xlinebuffer = row_map[line]; + xlinebuffer_genlock = row_map_genlock[line]; + return xlinebuffer; +} + static void draw_status_line(int line, int statusy) { - uae_u8* buf; + uae_u8 *buf = status_line_ptr(line); + if (!buf) + return; + //if (statusy < 0) + // statusline_render(buf, gfxvidinfo.pixbytes, gfxvidinfo.rowbytes, gfxvidinfo.outwidth, TD_TOTAL_HEIGHT, xredcolors, xgreencolors, xbluecolors, NULL); + //else + draw_status_line_single(buf, statusy, gfxvidinfo.outwidth); +} - xlinebuffer = row_map[line]; - buf = xlinebuffer; - draw_status_line_single(buf, statusy, gfxvidinfo.outwidth); +static void refresh_indicator_init(void) +{ + xfree(refresh_indicator_buffer); + refresh_indicator_buffer = NULL; + xfree(refresh_indicator_changed); + refresh_indicator_changed = NULL; + xfree(refresh_indicator_changed_prev); + refresh_indicator_changed_prev = NULL; + + //if (!currprefs.refresh_indicator) + return; + + refresh_indicator_height = 600; + refresh_indicator_buffer = xcalloc(uae_u8, MAX_PIXELS_PER_LINE * 2 * refresh_indicator_height); + refresh_indicator_changed = xcalloc(uae_u8, refresh_indicator_height); + refresh_indicator_changed_prev = xcalloc(uae_u8, refresh_indicator_height); +} + +static const int refresh_indicator_colors[] = { 0x777, 0x0f0, 0x00f, 0xff0, 0xf0f }; + +static void refresh_indicator_update() +{ + for (int i = 0; i < max_ypos_thisframe; i++) { + int i1 = i + min_ypos_for_screen; + int line = i + thisframe_y_adjust_real; + int whereline = amiga2aspect_line_map[i1]; + int wherenext = amiga2aspect_line_map[i1 + 1]; + + if (whereline >= gfxvidinfo.outheight) + break; + if (whereline < 0) + continue; + if (line >= refresh_indicator_height) + break; + + xlinebuffer = row_map[whereline]; + uae_u8 pixel = refresh_indicator_changed_prev[line]; + if (wherenext >= 0) { + pixel = refresh_indicator_changed_prev[line & ~1]; + } + + int color1 = 0; + int color2 = 0; + if (pixel <= 4) { + color1 = color2 = refresh_indicator_colors[pixel]; + } + else if (pixel <= 8) { + color2 = refresh_indicator_colors[pixel - 5]; + } + for (int x = 0; x < 8; x++) { + putpixel(xlinebuffer, NULL, gfxvidinfo.pixbytes, x, xcolors[color1], 1); + } + for (int x = 8; x < 16; x++) { + putpixel(xlinebuffer, NULL, gfxvidinfo.pixbytes, x, xcolors[color2], 1); + } + } } static void draw_frame2() { int i; - for (i = 0; i < max_ypos_thisframe; i++) - { + for (i = 0; i < max_ypos_thisframe; i++) { int i1 = i + min_ypos_for_screen; int line = i + thisframe_y_adjust_real; - int where2 = amiga2aspect_line_map[i1]; + int whereline = amiga2aspect_line_map[i1]; + int wherenext = amiga2aspect_line_map[i1 + 1]; - if (where2 >= gfxvidinfo.outheight) + if (whereline >= gfxvidinfo.outheight) break; - if (where2 < 0) + if (whereline < 0) continue; - pfield_draw_line(line, where2); + + hposblank = 0; + pfield_draw_line(line, whereline, wherenext); } } @@ -2276,25 +3740,6 @@ static void finish_drawing_frame() { int i; - lockscr(); - - if (gfxvidinfo.outwidth > 600) - { - if (aga_mode) - pfield_do_linetoscr = line_draw_func(pfield_do_linetoscr_0_640_AGA); - else - pfield_do_linetoscr = line_draw_func(pfield_do_linetoscr_0_640); - pfield_do_fill_line = line_draw_func(pfield_do_fill_line_0_640); - } - else - { - if (aga_mode) - pfield_do_linetoscr = line_draw_func(pfield_do_linetoscr_0_AGA); - else - pfield_do_linetoscr = line_draw_func(pfield_do_linetoscr_0); - pfield_do_fill_line = line_draw_func(pfield_do_fill_line_0); - } - draw_frame2(); if (currprefs.leds_on_screen) @@ -2303,16 +3748,50 @@ static void finish_drawing_frame() { int line = gfxvidinfo.outheight - TD_TOTAL_HEIGHT + i; draw_status_line(line, i); + do_flush_line(line); } } + + if (refresh_indicator_buffer) + refresh_indicator_update(); + do_flush_screen(); } -static void check_picasso() +void hardware_line_completed(int lineno) +{ +#ifndef SMART_UPDATE + { + int i, where; + /* l is the line that has been finished for drawing. */ + i = lineno - thisframe_y_adjust_real; + if (i >= 0 && i < max_ypos_thisframe) { + where = amiga2aspect_line_map[i + min_ypos_for_screen]; + if (where < gfxvidinfo.drawbuffer.outheight && where >= 0) + pfield_draw_line(lineno, where, amiga2aspect_line_map[i + min_ypos_for_screen + 1]); + } + } +#endif +} + +void check_prefs_picasso(void) { #ifdef PICASSO96 - if (picasso_requested_on == picasso_on) + if (picasso_on && picasso_redraw_necessary) + picasso_refresh(); + picasso_redraw_necessary = 0; + + if (picasso_requested_on == picasso_on && !picasso_requested_forced_on) return; + + if (picasso_requested_on) { + picasso_requested_forced_on = false; + picasso_on = false; + picasso_requested_on = false; + return; + } + + picasso_requested_forced_on = false; picasso_on = picasso_requested_on; if (!picasso_on) @@ -2323,33 +3802,54 @@ static void check_picasso() gfx_set_picasso_state(picasso_on); picasso_enablescreen(picasso_requested_on); + notice_screen_contents_lost(); notice_new_xcolors(); count_frame(); + compute_framesync(); #endif } -void vsync_handle_check() +void redraw_frame(void) +{ + last_drawn_line = 0; + first_drawn_line = 32767; + finish_drawing_frame(); + flush_screen(); +} + +bool vsync_handle_check(void) { int changed = check_prefs_changed_gfx(); - if (changed) - { + if (changed > 0) { reset_drawing(); + init_row_map(); + init_aspect_maps(); + notice_screen_contents_lost(); + notice_new_xcolors(); + } + else if (changed < 0) { + reset_drawing(); + init_row_map(); + init_aspect_maps(); + notice_screen_contents_lost(); notice_new_xcolors(); } check_prefs_changed_cd(); check_prefs_changed_audio(); check_prefs_changed_custom(); check_prefs_changed_cpu(); - check_picasso(); + check_prefs_picasso(); + return changed != 0; } - -void vsync_handle_redraw() +void vsync_handle_redraw(int long_field, int lof_changed, uae_u16 bplcon0p, uae_u16 bplcon3p) { + last_redraw_point++; + if (lof_changed || interlace_seen <= 0 || (currprefs.gfx_iscanlines && interlace_seen > 0) || last_redraw_point >= 2 || long_field) { + last_redraw_point = 0; + if (framecnt == 0) - { finish_drawing_frame(); - } if (quit_program < 0) { @@ -2363,65 +3863,211 @@ void vsync_handle_redraw() if (framecnt == 0) init_drawing_frame(); + else if (currprefs.cpu_memory_cycle_exact) + init_hardware_for_drawing_frame(); + } + else { + if (isvsync_chipset()) + flush_screen(); /* vsync mode */ + } + + gui_flicker_led(-1, 0, 0); } -void hsync_record_line_state(int lineno) +void hsync_record_line_state(int lineno, enum nln_how how, int changed) { + uae_u8 *state; + if (framecnt != 0) return; - linestate_first_undecided = lineno + 1; + state = linestate + lineno; + changed |= frame_redraw_necessary != 0 || refresh_indicator_buffer != NULL || + ((lineno >= lightpen_y1 && lineno < lightpen_y2) || + (lineno >= statusbar_y1 && lineno < statusbar_y2)); + + switch (how) { + case nln_normal: + *state = changed ? LINE_DECIDED : LINE_DONE; + break; + case nln_doubled: + *state = changed ? LINE_DECIDED_DOUBLE : LINE_DONE; + changed |= state[1] != LINE_REMEMBERED_AS_PREVIOUS; + state[1] = changed ? LINE_AS_PREVIOUS : LINE_DONE_AS_PREVIOUS; + break; + case nln_nblack: + *state = changed ? LINE_DECIDED : LINE_DONE; + if (state[1] != LINE_REMEMBERED_AS_BLACK) { + state[1] = LINE_BLACK; + } + break; + case nln_lower: + if (lineno > 0 && state[-1] == LINE_UNDECIDED) { + state[-1] = LINE_DECIDED; //LINE_BLACK; + } + *state = changed ? LINE_DECIDED : LINE_DONE; + break; + case nln_upper: + *state = changed ? LINE_DECIDED : LINE_DONE; + if (state[1] == LINE_UNDECIDED + || state[1] == LINE_REMEMBERED_AS_PREVIOUS + || state[1] == LINE_AS_PREVIOUS) + state[1] = LINE_DECIDED; //LINE_BLACK; + break; + case nln_lower_black_always: + state[1] = LINE_BLACK; + *state = LINE_DECIDED; + // if (lineno == (maxvpos + lof_store) * 2 - 1) + // *state = LINE_BLACK; + break; + case nln_lower_black: + changed |= state[0] != LINE_DONE; + state[1] = LINE_DONE; + *state = changed ? LINE_DECIDED : LINE_DONE; + // if (lineno == (maxvpos + lof_store) * 2 - 1) + // *state = LINE_BLACK; + break; + //case nln_upper_black_always: + // *state = LINE_DECIDED; + // if (lineno > 0) { + // state[-1] = LINE_BLACK; + // } + // if (!interlace_seen && lineno == (maxvpos + lof_store) * 2 - 2) { + // state[1] = LINE_BLACK; + // } + // break; + //case nln_upper_black: + // changed |= state[0] != LINE_DONE; + // *state = changed ? LINE_DECIDED : LINE_DONE; + // if (lineno > 0) { + // state[-1] = LINE_DONE; + // } + // if (!interlace_seen && lineno == (maxvpos + lof_store) * 2 - 2) { + // state[1] = LINE_DONE; + // } + // break; + } +} + +void notice_resolution_seen(int res, bool lace) +{ + if (res > frame_res) + frame_res = res; + if (res > 0) + can_use_lores = 0; + if (!frame_res_lace && lace) + frame_res_lace = lace; +} + +bool notice_interlace_seen(bool lace) +{ + bool changed = false; + // non-lace to lace switch (non-lace active at least one frame)? + if (lace) { + if (interlace_seen == 0) { + changed = true; + //write_log (_T("->lace PC=%x\n"), m68k_getpc ()); + } + interlace_seen = currprefs.gfx_vresolution ? 1 : -1; + } + else { + if (interlace_seen) { + changed = true; + //write_log (_T("->non-lace PC=%x\n"), m68k_getpc ()); + } + interlace_seen = 0; + } + return changed; } void reset_drawing() { + max_diwstop = 0; + lores_reset(); - linestate_first_undecided = 0; + reset_decision_table(); init_aspect_maps(); init_row_map(); + last_redraw_point = 0; + memset(spixels, 0, sizeof spixels); memset(&spixstate, 0, sizeof spixstate); init_drawing_frame(); + pfield_set_linetoscr(); + + notice_screen_contents_lost(); + frame_res_cnt = currprefs.gfx_autoresolution_delay; + lightpen_y1 = lightpen_y2 = -1; + + reset_custom_limits(); + + center_reset = true; + bplcolorburst_field = 1; + hsync_shift_hack = 0; } -void drawing_init() +static void gen_direct_drawing_table(void) { +#ifdef AGA + // BYPASS color table + for (int i = 0; i < 256; i++) { + uae_u32 v = (i << 16) | (i << 8) | i; + direct_colors_for_drawing.acolors[i] = CONVERT_RGB(v); + } +#endif +} + +void drawing_init(void) +{ + refresh_indicator_init(); + gen_pfield_tables(); + gen_direct_drawing_table(); + #ifdef PICASSO96 - if (!isrestore()) - { + if (!isrestore()) { picasso_on = false; picasso_requested_on = false; gfx_set_picasso_state(0); } #endif xlinebuffer = gfxvidinfo.bufmem; + xlinebuffer_genlock = nullptr; + inhibit_frame = 0; reset_drawing(); } -int isvsync_chipset() +int isvsync_chipset(void) { - if (picasso_on) + if (picasso_on || currprefs.gfx_apmode[0].gfx_vsync <= 0) return 0; - return 1; + if (currprefs.gfx_apmode[0].gfx_vsyncmode == 0) + return 1; + if (currprefs.m68k_speed >= 0) + return -1; + return currprefs.cachesize ? -3 : -2; } -int isvsync_rtg() +int isvsync_rtg(void) { - if (!picasso_on) + if (!picasso_on || currprefs.gfx_apmode[1].gfx_vsync <= 0) return 0; - return 1; + if (currprefs.gfx_apmode[1].gfx_vsyncmode == 0) + return 1; + if (currprefs.m68k_speed >= 0) + return -1; + return currprefs.cachesize ? -3 : -2; } -int isvsync() +int isvsync(void) { if (picasso_on) return isvsync_rtg(); diff --git a/src/events.cpp b/src/events.cpp index 97487941..7c68e217 100644 --- a/src/events.cpp +++ b/src/events.cpp @@ -16,8 +16,19 @@ #include "newcpu.h" #include "events.h" -frame_time_t vsyncmintime; +static const int pissoff_nojit_value = 256 * CYCLE_UNIT; + +unsigned long int event_cycles, nextevent, currcycle; +int is_syncline, is_syncline_end; +long cycles_to_next_event; +long max_cycles_to_next_event; +long cycles_to_hsync_event; +unsigned long start_cycles; +bool event_wait; + +frame_time_t vsyncmintime, vsyncmaxtime, vsyncwaittime; int vsynctimebase; +int event2_count; void events_schedule (void) { @@ -38,41 +49,41 @@ void events_schedule (void) void do_cycles_cpu_fastest (unsigned long cycles_to_add) { - if ((regs.pissoff -= cycles_to_add) > 0) + if ((pissoff -= cycles_to_add) > 0) return; - cycles_to_add = -regs.pissoff; - regs.pissoff = 0; + cycles_to_add = -pissoff; + pissoff = 0; - if (is_syncline && eventtab[ev_hsync].evtime - currcycle <= cycles_to_add) - { - int rpt = read_processor_time (); - int v = rpt - vsyncmintime; - if (v > syncbase || v < -syncbase) - vsyncmintime = rpt; - if (v < speedup_timelimit) - { - regs.pissoff = pissoff_value; - return; - } - is_syncline = 0; - } + if (is_syncline && eventtab[ev_hsync].evtime - currcycle <= cycles_to_add) + { + int rpt = read_processor_time(); + int v = rpt - vsyncmintime; + if (v > syncbase || v < -syncbase) + vsyncmintime = rpt; + if (v < speedup_timelimit) + { + pissoff = pissoff_value; + return; + } + is_syncline = 0; + } - while ((nextevent - currcycle) <= cycles_to_add) - { - int i; - cycles_to_add -= (nextevent - currcycle); - currcycle = nextevent; + while ((nextevent - currcycle) <= cycles_to_add) + { + int i; + cycles_to_add -= (nextevent - currcycle); + currcycle = nextevent; - for (i = 0; i < ev_max; i++) - { - if (eventtab[i].active && eventtab[i].evtime == currcycle) - { - (*eventtab[i].handler)(); - } - } - events_schedule(); - } + for (i = 0; i < ev_max; i++) + { + if (eventtab[i].active && eventtab[i].evtime == currcycle) + { + (*eventtab[i].handler)(); + } + } + events_schedule(); + } currcycle += cycles_to_add; } @@ -145,3 +156,60 @@ void MISC_handler(void) } recursive--; } + +void event2_newevent_xx(int no, evt t, uae_u32 data, evfunc2 func) +{ + evt et; + static int next = ev2_misc; + + et = t + get_cycles(); + if (no < 0) { + no = next; + for (;;) { + if (!eventtab2[no].active) { + event2_count++; + break; + } + if (eventtab2[no].evtime == et && eventtab2[no].handler == func && eventtab2[no].data == data) + break; + no++; + if (no == ev2_max) + no = ev2_misc; + if (no == next) { + write_log(_T("out of event2's!\n")); + return; + } + } + next = no; + } + eventtab2[no].active = true; + eventtab2[no].evtime = et; + eventtab2[no].handler = func; + eventtab2[no].data = data; + MISC_handler(); +} + +void event2_newevent_x_replace(evt t, uae_u32 data, evfunc2 func) +{ + for (int i = 0; i < ev2_max; i++) { + if (eventtab2[i].active && eventtab2[i].handler == func) { + eventtab2[i].active = false; + } + } + if (int(t) <= 0) { + func(data); + return; + } + event2_newevent_xx(-1, t * CYCLE_UNIT, data, func); +} + + +int current_hpos(void) +{ + int hp = current_hpos_safe(); + if (hp < 0 || hp > 256) { + gui_message(_T("hpos = %d!?\n"), hp); + hp = 0; + } + return hp; +} \ No newline at end of file diff --git a/src/expansion.cpp b/src/expansion.cpp index 7342633e..9b691635 100644 --- a/src/expansion.cpp +++ b/src/expansion.cpp @@ -1,42 +1,84 @@ - /* - * UAE - The Un*x Amiga Emulator - * - * AutoConfig (tm) Expansions (ZorroII/III) - * - * Copyright 1996,1997 Stefan Reinauer - * Copyright 1997 Brian King - * - added gfxcard code - * - */ +/* +* UAE - The Un*x Amiga Emulator +* +* AutoConfig (tm) Expansions (ZorroII/III) +* +* Copyright 1996,1997 Stefan Reinauer +* Copyright 1997 Brian King +* - added gfxcard code +* +*/ #include "sysconfig.h" #include "sysdeps.h" #include "options.h" #include "uae.h" -#include "memory.h" +//#include "traps.h" +#include "include/memory.h" #include "rommgr.h" -#include "autoconf.h" #include "custom.h" #include "newcpu.h" #include "savestate.h" #include "zfile.h" +//#include "catweasel.h" +//#include "cdtv.h" +//#include "cdtvcr.h" +#include "threaddep/thread.h" +//#include "a2091.h" +//#include "a2065.h" #include "gfxboard.h" +//#include "cd32_fmv.h" +//#include "ncr_scsi.h" +//#include "ncr9x_scsi.h" +#include "scsi.h" +#include "debug.h" +//#include "gayle.h" +//#include "idecontrollers.h" +//#include "cpuboard.h" +//#include "sndboard.h" +//#include "uae/ppc.h" +#include "autoconf.h" +//#include "specialmonitors.h" +#include "inputdevice.h" +//#include "pci.h" +//#include "x86.h" +#include "filesys.h" +//#include "ethernet.h" +//#include "sana2.h" -#define MAX_EXPANSION_BOARDS 8 + +#define CARD_FLAG_CAN_Z3 1 +#define CARD_FLAG_CHILD 8 + +// More information in first revision HRM Appendix_G +#define BOARD_PROTOAUTOCONFIG 1 + +#define BOARD_AUTOCONFIG_Z2 2 +#define BOARD_AUTOCONFIG_Z3 3 +#define BOARD_NONAUTOCONFIG_BEFORE 4 +#define BOARD_NONAUTOCONFIG_AFTER_Z2 5 +#define BOARD_NONAUTOCONFIG_AFTER_Z3 6 +#define BOARD_IGNORE 7 + +#define KS12_BOOT_HACK 1 + +#define EXP_DEBUG 0 + +#define MAX_EXPANSION_BOARD_SPACE 16 /* ********************************************************** */ /* 00 / 02 */ /* er_Type */ -#define Z2_MEM_8MB 0x00 /* Size of Memory Block */ -#define Z2_MEM_4MB 0x07 -#define Z2_MEM_2MB 0x06 -#define Z2_MEM_1MB 0x05 +#define Z2_MEM_8MB 0x00 /* Size of Memory Block */ +#define Z2_MEM_4MB 0x07 +#define Z2_MEM_2MB 0x06 +#define Z2_MEM_1MB 0x05 #define Z2_MEM_512KB 0x04 #define Z2_MEM_256KB 0x03 #define Z2_MEM_128KB 0x02 -#define Z2_MEM_64KB 0x01 +#define Z2_MEM_64KB 0x01 /* extended definitions */ #define Z3_MEM_16MB 0x00 #define Z3_MEM_32MB 0x01 @@ -50,7 +92,9 @@ #define rom_card 0x10 /* ROM vector is valid */ #define add_memory 0x20 /* Link RAM into free memory list */ -#define zorroII 0xc0 /* Type of Expansion Card */ +/* Type of Expansion Card */ +#define protoautoconfig 0x40 +#define zorroII 0xc0 #define zorroIII 0x80 /* ********************************************************** */ @@ -64,10 +108,10 @@ #define hackers_id 2011 /* Special ID for test cards */ /* Card Type */ -#define commodore_a2091 3 /* A2091 / A590 Card from C= */ +#define commodore_a2091 3 /* A2091 / A590 Card from C= */ #define commodore_a2091_ram 10 /* A2091 / A590 Ram on HD-Card */ #define commodore_a2232 70 /* A2232 Multiport Expansion */ -#define ass_nexus_scsi 1 /* Nexus SCSI Controller */ +#define ass_nexus_scsi 1 /* Nexus SCSI Controller */ #define gvp_series_2_scsi 11 #define gvp_iv_24_gfx 32 @@ -124,74 +168,141 @@ uaecptr ROM_filesys_resname, ROM_filesys_resid; uaecptr ROM_filesys_diagentry; uaecptr ROM_hardfile_resname, ROM_hardfile_resid; uaecptr ROM_hardfile_init; -bool uae_boot_rom; +int uae_boot_rom_type; int uae_boot_rom_size; /* size = code size only */ static bool chipdone; +static int do_mount; + +#define FILESYS_DIAGPOINT 0x01e0 +#define FILESYS_BOOTPOINT 0x01e6 +#define FILESYS_DIAGAREA 0x2000 /* ********************************************************** */ -static void (*card_init[MAX_EXPANSION_BOARDS]) (void); -static void (*card_map[MAX_EXPANSION_BOARDS]) (void); -static const char *card_name[MAX_EXPANSION_BOARDS]; +struct card_data +{ + bool(*initrc)(struct autoconfig_info*); + bool(*initnum)(struct autoconfig_info*); + addrbank *(*map)(struct autoconfig_info*); + struct romconfig *rc; + const TCHAR *name; + int flags; + int zorro; + uaecptr base; + uae_u32 size; + // parsing updated fields + const struct expansionromtype *ert; + const struct cpuboardsubtype *cst; + struct autoconfig_info aci; +}; -static int ecard, cardno; +static struct card_data cards_set[MAX_EXPANSION_BOARD_SPACE]; +static struct card_data *cards[MAX_EXPANSION_BOARD_SPACE]; + +static int ecard, cardno, z3num; +static addrbank *expamem_bank_current; static uae_u16 uae_id; +static bool isnonautoconfig(int v) +{ + return v == BOARD_NONAUTOCONFIG_AFTER_Z2 || + v == BOARD_NONAUTOCONFIG_AFTER_Z3 || + v == BOARD_NONAUTOCONFIG_BEFORE; +} + +static bool ks12orolder(void) +{ + /* check if Kickstart version is below 1.3 */ + return kickstart_version && kickstart_version < 34; +} +static bool ks11orolder(void) +{ + return kickstart_version && kickstart_version < 33; +} + + /* ********************************************************** */ /* Please note: ZorroIII implementation seems to work different - * than described in the HRM. This claims that ZorroIII config - * address is 0xff000000 while the ZorroII config space starts - * at 0x00e80000. In reality, both, Z2 and Z3 cards are - * configured in the ZorroII config space. Kickstart 3.1 doesn't - * even do a single read or write access to the ZorroIII space. - * The original Amiga include files tell the same as the HRM. - * ZorroIII: If you set ext_size in er_Flags and give a Z2-size - * in er_Type you can very likely add some ZorroII address space - * to a ZorroIII card on a real Amiga. This is not implemented - * yet. - * -- Stefan - * - * Surprising that 0xFF000000 isn't used. Maybe it depends on the - * ROM. Anyway, the HRM says that Z3 cards may appear in Z2 config - * space, so what we are doing here is correct. - * -- Bernd - */ +* than described in the HRM. This claims that ZorroIII config +* address is 0xff000000 while the ZorroII config space starts +* at 0x00e80000. In reality, both, Z2 and Z3 cards are +* configured in the ZorroII config space. Kickstart 3.1 doesn't +* even do a single read or write access to the ZorroIII space. +* The original Amiga include files tell the same as the HRM. +* ZorroIII: If you set ext_size in er_Flags and give a Z2-size +* in er_Type you can very likely add some ZorroII address space +* to a ZorroIII card on a real Amiga. This is not implemented +* yet. +* -- Stefan +* +* Surprising that 0xFF000000 isn't used. Maybe it depends on the +* ROM. Anyway, the HRM says that Z3 cards may appear in Z2 config +* space, so what we are doing here is correct. +* -- Bernd +*/ /* Autoconfig address space at 0xE80000 */ static uae_u8 expamem[65536]; +static uae_u8 expamem_write_space[65536]; +#define AUTOMATIC_AUTOCONFIG_MAX_ADDRESS 0x80 +static int expamem_autoconfig_mode; +static addrbank*(*expamem_map)(struct autoconfig_info*); static uae_u8 expamem_lo; static uae_u16 expamem_hi; +uaecptr expamem_z3_pointer_real, expamem_z3_pointer_uae; +uaecptr expamem_z3_highram_real, expamem_z3_highram_uae; +uaecptr expamem_highmem_pointer; +uae_u32 expamem_board_size; +uaecptr expamem_board_pointer; +static uae_u8 slots_e8[8] = { 0 }; +static uae_u8 slots_20[(8 * 1024 * 1024) / 65536] = { 0 }; + +static int z3hack_override; + +void set_expamem_z3_hack_mode(int mode) +{ + z3hack_override = mode; +} + +bool expamem_z3hack(struct uae_prefs *p) +{ + if (z3hack_override == Z3MAPPING_UAE) + return true; + if (z3hack_override == Z3MAPPING_REAL) + return false; + return p->z3_mapping_mode == Z3MAPPING_UAE; //|| cpuboard_memorytype(p) == BOARD_MEMORY_BLIZZARD_12xx; +} /* Ugly hack for >2M chip RAM in single pool - * We can't add it any later or early boot menu - * stops working because it sets kicktag at the end - * of chip ram... - */ -static void addextrachip (uae_u32 sysbase) +* We can't add it any later or early boot menu +* stops working because it sets kicktag at the end +* of chip ram... +*/ +static void addextrachip(uae_u32 sysbase) { if (currprefs.chipmem_size <= 0x00200000) return; if (sysbase & 0x80000001) return; - if (!valid_address (sysbase, 1000)) + if (!valid_address(sysbase, 1000)) return; - uae_u32 ml = get_long (sysbase + 322); - if (!valid_address (ml, 32)) + uae_u32 ml = get_long(sysbase + 322); + if (!valid_address(ml, 32)) return; uae_u32 next; - while ((next = get_long (ml))) { - if (!valid_address (ml, 32)) + while ((next = get_long(ml))) { + if (!valid_address(ml, 32)) return; - uae_u32 upper = get_long (ml + 24); - uae_u32 lower = get_long (ml + 20); + uae_u32 upper = get_long(ml + 24); + uae_u32 lower = get_long(ml + 20); if (lower & ~0xffff) { ml = next; continue; } - uae_u16 attr = get_word (ml + 14); + uae_u16 attr = get_word(ml + 14); if ((attr & 0x8002) != 2) { ml = next; continue; @@ -199,962 +310,5375 @@ static void addextrachip (uae_u32 sysbase) if (upper >= currprefs.chipmem_size) return; uae_u32 added = currprefs.chipmem_size - upper; - uae_u32 first = get_long (ml + 16); - put_long (ml + 24, currprefs.chipmem_size); // mh_Upper - put_long (ml + 28, get_long (ml + 28) + added); // mh_Free + uae_u32 first = get_long(ml + 16); + put_long(ml + 24, currprefs.chipmem_size); // mh_Upper + put_long(ml + 28, get_long(ml + 28) + added); // mh_Free uae_u32 next; while (first) { next = first; - first = get_long (next); + first = get_long(next); } - uae_u32 bytes = get_long (next + 4); + uae_u32 bytes = get_long(next + 4); if (next + bytes == 0x00200000) { - put_long (next + 4, currprefs.chipmem_size - next); - } else { - put_long (0x00200000 + 0, 0); - put_long (0x00200000 + 4, added); - put_long (next, 0x00200000); + put_long(next + 4, currprefs.chipmem_size - next); + } + else { + put_long(0x00200000 + 0, 0); + put_long(0x00200000 + 4, added); + put_long(next, 0x00200000); } return; } } +addrbank expamem_null, expamem_none; -static uae_u32 REGPARAM3 expamem_lget (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 expamem_wget (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 expamem_bget (uaecptr) REGPARAM; -static void REGPARAM3 expamem_lput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 expamem_wput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 expamem_bput (uaecptr, uae_u32) REGPARAM; - +DECLARE_MEMORY_FUNCTIONS(expamem_write); +addrbank expamem_write_bank = { + expamem_write_lget, expamem_write_wget, expamem_write_bget, + expamem_write_lput, expamem_write_wput, expamem_write_bput, + default_xlate, default_check, NULL, NULL, _T("Autoconfig Z2 WRITE"), + dummy_lgeti, dummy_wgeti, + ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE +}; +DECLARE_MEMORY_FUNCTIONS(expamem); addrbank expamem_bank = { - expamem_lget, expamem_wget, expamem_bget, - expamem_lput, expamem_wput, expamem_bput, - default_xlate, default_check, NULL, _T("Autoconfig"), - dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE + expamem_lget, expamem_wget, expamem_bget, + expamem_lput, expamem_wput, expamem_bput, + default_xlate, default_check, NULL, NULL, _T("Autoconfig Z2"), + dummy_lgeti, dummy_wgeti, + ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE +}; +DECLARE_MEMORY_FUNCTIONS(expamemz3); +static addrbank expamemz3_bank = { + expamemz3_lget, expamemz3_wget, expamemz3_bget, + expamemz3_lput, expamemz3_wput, expamemz3_bput, + default_xlate, default_check, NULL, NULL, _T("Autoconfig Z3"), + dummy_lgeti, dummy_wgeti, + ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE }; -static void expamem_map_clear (void) +static addrbank *expamem_map_clear(void) { - write_log (_T("expamem_map_clear() got called. Shouldn't happen.\n")); + write_log(_T("expamem_map_clear() got called. Shouldn't happen.\n")); + return NULL; } -static void expamem_init_clear (void) +static void expamem_init_clear(void) { - memset (expamem, 0xff, sizeof expamem); + memset(expamem, 0xff, sizeof expamem); + expamem_map = NULL; } /* autoconfig area is "non-existing" after last device */ -static void expamem_init_clear_zero (void) +static void expamem_init_clear_zero(void) { - map_banks (&dummy_bank, 0xe8, 1, 0); -} - -static void expamem_init_clear2 (void) -{ - expamem_bank.name = _T("Autoconfig"); - expamem_init_clear_zero(); - ecard = cardno; -} - -static void expamem_init_last (void) -{ - expamem_init_clear2(); - write_log (_T("Memory map after autoconfig:\n")); -} - -void expamem_next(void) -{ - expamem_init_clear(); - map_banks (&expamem_bank, 0xE8, 1, 0); - ++ecard; - if (ecard < cardno) { - expamem_bank.name = card_name[ecard] ? card_name[ecard] : (TCHAR*) _T("None"); - (*card_init[ecard]) (); - } else { - expamem_init_clear2 (); - } -} - -static uae_u32 REGPARAM2 expamem_lget (uaecptr addr) -{ - write_log (_T("warning: READ.L from address $%lx PC=%x\n"), addr, M68K_GETPC); - return (expamem_wget (addr) << 16) | expamem_wget (addr + 2); -} - -static uae_u32 REGPARAM2 expamem_wget (uaecptr addr) -{ - uae_u32 v = (expamem_bget (addr) << 8) | expamem_bget (addr + 1); - write_log (_T("warning: READ.W from address $%lx=%04x PC=%x\n"), addr, v & 0xffff, M68K_GETPC); - return v; -} - -static uae_u32 REGPARAM2 expamem_bget (uaecptr addr) -{ - uae_u8 b; -#ifdef JIT - special_mem |= S_READ; -#endif - if (!chipdone) { - chipdone = true; - addextrachip (get_long (4)); + if (currprefs.cpu_model < 68020) { + map_banks(&dummy_bank, 0xe8, 1, 0); + if (!currprefs.address_space_24) + map_banks(&dummy_bank, AUTOCONFIG_Z3 >> 16, 1, 0); } - addr &= 0xFFFF; - b = expamem[addr]; - return b; + else { + map_banks(&expamem_bank, 0xe8, 1, 0); + if (!currprefs.address_space_24) + map_banks(&expamemz3_bank, AUTOCONFIG_Z3 >> 16, 1, 0); + } + expamem_bank_current = NULL; } -static void REGPARAM2 expamem_write (uaecptr addr, uae_u32 value) +static void expamem_init_clear2(void) { -#ifdef JIT - special_mem |= S_WRITE; -#endif - addr &= 0xffff; - if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) { + expamem_bank.name = _T("Autoconfig Z2"); + expamemz3_bank.name = _T("Autoconfig Z3"); + expamem_init_clear_zero(); + ecard = cardno; +} + +static addrbank *expamem_init_last(void) +{ + expamem_init_clear2(); + write_log(_T("Memory map after autoconfig:\n")); + //memory_map_dump(); + return NULL; +} + +static uae_u8 REGPARAM2 expamem_read(int addr) +{ + uae_u8 b = (expamem[addr] & 0xf0) | (expamem[addr + 2] >> 4); + if (addr == 0 || addr == 2 || addr == 0x40 || addr == 0x42) + return b; + b = ~b; + return b; +} + +static void REGPARAM2 expamem_write(uaecptr addr, uae_u32 value) +{ + addr &= 0xffff; + if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) { expamem[addr] = (value & 0xf0); expamem[addr + 2] = (value & 0x0f) << 4; - } else { + } + else { expamem[addr] = ~(value & 0xf0); expamem[addr + 2] = ~((value & 0x0f) << 4); - } + } } -static int REGPARAM2 expamem_type (void) +static int REGPARAM2 expamem_type(void) { - return ((expamem[0] | expamem[2] >> 4) & 0xc0); + return expamem_read(0) & 0xc0; } -static void REGPARAM2 expamem_lput (uaecptr addr, uae_u32 value) +void expansion_cpu_fallback(void) { -#ifdef JIT - special_mem |= S_WRITE; -#endif - write_log (_T("warning: WRITE.L to address $%lx : value $%lx\n"), addr, value); + if (ecard < cardno) { + card_data *cd = cards[ecard]; + if (cd->cst && (cd->cst->deviceflags & EXPANSIONTYPE_FALLBACK_DISABLE)) { + expamem_next(NULL, NULL); + } + } } -static void REGPARAM2 expamem_wput (uaecptr addr, uae_u32 value) +static void call_card_init(int index) { -#ifdef JIT - special_mem |= S_WRITE; -#endif - value &= 0xffff; - if (ecard >= cardno) - return; - if (expamem_type() != zorroIII) - write_log (_T("warning: WRITE.W to address $%lx : value $%x\n"), addr, value); - else { - switch (addr & 0xff) { - case 0x44: - if (expamem_type() == zorroIII) { - uae_u32 p1, p2 = 0; - // +Bernd Roesch & Toni Wilen - p1 = get_word (regs.regs[11] + 0x20); - if (expamem[0] & add_memory) { - // Z3 RAM expansion - p2 = 0; - if (currprefs.z3fastmem_size) - p2 = z3fastmem_bank.start >> 16; - } else { - // Z3 P96 RAM -#ifdef PICASSO96 - if (gfxmem_bank.start & 0xff000000) - p2 = gfxmem_bank.start >> 16; -#endif - } - put_word (regs.regs[11] + 0x20, p2); - put_word (regs.regs[11] + 0x28, p2); - // -Bernd Roesch - expamem_hi = p2; - (*card_map[ecard]) (); - if (p1 != p2) - write_log (_T(" Card %d remapped %04x0000 -> %04x0000\n"), ecard + 1, p1, p2); - write_log (_T(" Card %d (Zorro%s) done.\n"), ecard + 1, expamem_type() == 0xc0 ? _T("II") : _T("III")); - expamem_next (); - } - break; - case 0x4c: - write_log (_T(" Card %d (Zorro%s) had no success.\n"), ecard + 1, expamem_type () == 0xc0 ? _T("II") : _T("III")); - expamem_hi = expamem_lo = 0; - (*card_map[ecard]) (); - break; - } - } + addrbank *ab, *abe; + card_data *cd = cards[ecard]; + struct autoconfig_info *aci = &cd->aci; + bool ok = false; + + if (currprefs.address_space_24 && cd->cst && (cd->cst->deviceflags & EXPANSIONTYPE_FALLBACK_DISABLE)) { + write_log(_T("Card %d: skipping autoconfig (fallback mode)\n"), ecard); + expamem_next(NULL, NULL); + return; + } + + expamem_bank.name = cd->name ? cd->name : _T("None"); + aci->prefs = &currprefs; + aci->doinit = true; + aci->devnum = (cd->flags >> 16) & 255; + aci->ert = cd->ert; + aci->cst = cd->cst; + aci->rc = cd->rc; + aci->zorro = cd->zorro; + memset(aci->autoconfig_raw, 0xff, sizeof aci->autoconfig_raw); + if (cd->initnum) { + ok = cd->initnum(aci); + } + else { + ok = cd->initrc(aci); + } + if (ok) { + ab = NULL; + if (!cd->map) + ab = aci->Addrbank; + } + else { + write_log(_T("Card %d: skipping autoconfig (init failed)\n"), ecard); + expamem_next(NULL, NULL); + return; + } + if (ab == &expamem_none) { + write_log(_T("Card %d: skipping autoconfig (none)\n"), ecard); + expamem_init_clear(); + expamem_init_clear_zero(); + map_banks(&expamem_bank, 0xE8, 1, 0); + if (!currprefs.address_space_24) + map_banks(&dummy_bank, AUTOCONFIG_Z3 >> 16, 1, 0); + expamem_bank_current = NULL; + return; + } + if (ab == &expamem_null || cd->zorro < 1 || cd->zorro > 3 || aci->zorro < 0) { + write_log(_T("Card %d: skipping autoconfig (not autoconfig)\n"), ecard); + expamem_next(NULL, NULL); + return; + } + + expamem_board_pointer = cd->base; + expamem_board_size = cd->size; + + abe = ab; + if (!abe) + abe = &expamem_bank; + expamem_autoconfig_mode = 0; + if (abe != &expamem_bank) { + if (aci->autoconfig_automatic) { + if (aci->autoconfigp) { + memset(expamem, 0xff, AUTOMATIC_AUTOCONFIG_MAX_ADDRESS); + for (int i = 0; i < 16; i++) { + expamem_write(i * 4, aci->autoconfig_bytes[i]); + } + expamem_autoconfig_mode = 1; + } + else if (aci->autoconfig_bytes) { + memset(expamem, 0xff, AUTOMATIC_AUTOCONFIG_MAX_ADDRESS); + for (int i = 0; i < 16; i++) { + expamem_write(i * 4, aci->autoconfig_bytes[i]); + } + expamem_autoconfig_mode = 1; + } + else if (aci->autoconfig_raw) { + memcpy(expamem, aci->autoconfig_raw, sizeof aci->autoconfig_raw); + } + } + else { + for (int i = 0; i < 16 * 4; i++) { + expamem[i] = abe->sub_banks ? abe->sub_banks[0].bank->bget(i) : abe->bget(i); + } + } + } + + if (aci->write_bank_address && aci->write_bank_address != 0xffffffff) { + map_banks(&expamem_write_bank, aci->write_bank_address >> 16, aci->size >> 16, 0); + } + + if (ab) { + // non-NULL: not using expamem_bank + expamem_bank_current = ab; + if ((cd->flags & CARD_FLAG_CAN_Z3) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) { + map_banks(&expamemz3_bank, AUTOCONFIG_Z3 >> 16, 1, 0); + map_banks(&dummy_bank, 0xE8, 1, 0); + } + else { + map_banks(&expamem_bank, 0xE8, 1, 0); + if (!currprefs.address_space_24) + map_banks(&dummy_bank, AUTOCONFIG_Z3 >> 16, 1, 0); + } + } + else { + if ((cd->flags & CARD_FLAG_CAN_Z3) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) { + map_banks(&expamemz3_bank, AUTOCONFIG_Z3 >> 16, 1, 0); + map_banks(&dummy_bank, 0xE8, 1, 0); + expamem_bank_current = &expamem_bank; + } + else { + map_banks(&expamem_bank, 0xE8, 1, 0); + if (!currprefs.address_space_24) + map_banks(&dummy_bank, AUTOCONFIG_Z3 >> 16, 1, 0); + expamem_bank_current = NULL; + } + } } -static void REGPARAM2 expamem_bput (uaecptr addr, uae_u32 value) +static void boardmessage(addrbank *mapped, bool success) { -#ifdef JIT - special_mem |= S_WRITE; + uae_u8 type = expamem_read(0); + int size = expamem_board_size; + TCHAR sizemod = 'K'; + + size /= 1024; + if (size > 8 * 1024) { + sizemod = 'M'; + size /= 1024; + } + write_log(_T("Card %d: Z%d 0x%08x %4d%c %s %s%s\n"), + ecard + 1, (type & 0xc0) == zorroII ? 2 : ((type & 0xc0) == zorroIII ? 3 : 1), + expamem_board_pointer, size, sizemod, + type & rom_card ? _T("ROM") : (type & add_memory ? _T("RAM") : _T("IO ")), + mapped->name, + success ? _T("") : _T(" [SHUT UP]")); +#if 0 + for (int i = 0; i < 16; i++) { + write_log(_T("%s%02X"), i > 0 ? _T(".") : _T(""), expamem_read(i * 4)); + } + write_log(_T("\n")); #endif - if (ecard >= cardno) - return; - value &= 0xff; - switch (addr & 0xff) { - case 0x30: - case 0x32: - expamem_hi = 0; - expamem_lo = 0; - expamem_write (0x48, 0x00); +} + +void expamem_shutup(addrbank *mapped) +{ + if (mapped) { + mapped->start = 0xffffffff; + boardmessage(mapped, false); + } +} + +void expamem_next(addrbank *mapped, addrbank *next) +{ + if (mapped) + boardmessage(mapped, mapped->start != 0xffffffff); + + expamem_init_clear(); + expamem_init_clear_zero(); + for (;;) { + ++ecard; + if (ecard >= cardno) break; + struct card_data *ec = cards[ecard]; + if (ec->zorro == 3 && ec->base == 0xffffffff) { + write_log(_T("Autoconfig chain enumeration aborted, 32-bit address space overflow.\n")); + ecard = cardno; + break; + } + if (ec->initrc && isnonautoconfig(ec->zorro)) { + struct autoconfig_info aci = { 0 }; + aci.doinit = true; + aci.prefs = &currprefs; + aci.rc = cards[ecard]->rc; + ec->initrc(&aci); + } + else { + call_card_init(ecard); + break; + } + } + if (ecard >= cardno) { + expamem_init_clear2(); + expamem_init_last(); + } +} +// only for custom autoconfig device development purposes, not in use in any normal config +static uae_u32 REGPARAM2 expamem_write_lget(uaecptr addr) +{ + addr &= 0xffff; + return (expamem_write_space[addr + 0] << 24) | (expamem_write_space[addr + 1] << 16) | (expamem_write_space[addr + 2] << 8) | (expamem_write_space[addr + 3] << 0); +} +static uae_u32 REGPARAM2 expamem_write_wget(uaecptr addr) +{ + addr &= 0xffff; + return (expamem_write_space[addr + 0] << 8) | (expamem_write_space[addr + 1] << 0); +} +static uae_u32 REGPARAM2 expamem_write_bget(uaecptr addr) +{ + addr &= 0xffff; + return expamem_write_space[addr]; +} +static void REGPARAM2 expamem_write_lput(uaecptr addr, uae_u32 value) +{ + addr &= 0xffff; + expamem_write_space[addr + 0] = value >> 24; + expamem_write_space[addr + 1] = value >> 16; + expamem_write_space[addr + 2] = value >> 8; + expamem_write_space[addr + 3] = value >> 0; +} +static void REGPARAM2 expamem_write_wput(uaecptr addr, uae_u32 value) +{ + addr &= 0xffff; + expamem_write_space[addr + 0] = value >> 8; + expamem_write_space[addr + 1] = value; +} +static void REGPARAM2 expamem_write_bput(uaecptr addr, uae_u32 value) +{ + addr &= 0xffff; + expamem_write_space[addr] = value; +} + +static uae_u32 REGPARAM2 expamem_lget(uaecptr addr) +{ + if (expamem_bank_current && expamem_bank_current != &expamem_bank) { + if (expamem_autoconfig_mode && (addr & 0xffff) < AUTOMATIC_AUTOCONFIG_MAX_ADDRESS) { + return (expamem_wget(addr) << 16) | expamem_wget(addr + 2); + } + return expamem_bank_current->sub_banks ? expamem_bank_current->sub_banks[0].bank->lget(addr) : expamem_bank_current->lget(addr); + } + write_log(_T("warning: Z2 READ.L from address $%08x PC=%x\n"), addr, M68K_GETPC); + return (expamem_wget(addr) << 16) | expamem_wget(addr + 2); +} + +static uae_u32 REGPARAM2 expamem_wget(uaecptr addr) +{ + if (expamem_bank_current && expamem_bank_current != &expamem_bank) { + if (expamem_autoconfig_mode && (addr & 0xffff) < AUTOMATIC_AUTOCONFIG_MAX_ADDRESS) { + return (expamem_bget(addr) << 8) | expamem_bget(addr + 1); + } + return expamem_bank_current->sub_banks ? expamem_bank_current->sub_banks[0].bank->wget(addr) : expamem_bank_current->wget(addr); + } + if (expamem_type() != zorroIII) { + if (expamem_bank_current && expamem_bank_current != &expamem_bank) + return expamem_bank_current->bget(addr) << 8; + } + uae_u32 v = (expamem_bget(addr) << 8) | expamem_bget(addr + 1); + if (cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8) { + uae_u32 val = v; + cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8(addr, &val, 2, false); + v = val; + } + write_log(_T("warning: READ.W from address $%08x=%04x PC=%x\n"), addr, v & 0xffff, M68K_GETPC); + return v; +} + +static uae_u32 REGPARAM2 expamem_bget(uaecptr addr) +{ + uae_u8 b; + if (!chipdone) { + chipdone = true; + addextrachip(get_long(4)); + } + if (expamem_bank_current && expamem_bank_current != &expamem_bank) { + if (expamem_autoconfig_mode && (addr & 0xffff) < AUTOMATIC_AUTOCONFIG_MAX_ADDRESS) { + return expamem[addr & 0xffff]; + } + return expamem_bank_current->sub_banks ? expamem_bank_current->sub_banks[0].bank->bget(addr) : expamem_bank_current->bget(addr); + } + addr &= 0xFFFF; + b = expamem[addr]; + if (cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8) { + uae_u32 val = b; + cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8(addr, &val, 1, false); + b = val; + } +#if EXP_DEBUG + write_log(_T("expamem_bget %x %x\n"), addr, b); +#endif + return b; +} + +static void REGPARAM2 expamem_lput(uaecptr addr, uae_u32 value) +{ + if (expamem_bank_current && expamem_bank_current != &expamem_bank) { + if (expamem_autoconfig_mode && (addr & 0xffff) < AUTOMATIC_AUTOCONFIG_MAX_ADDRESS) { + return; + } + expamem_bank_current->sub_banks ? expamem_bank_current->sub_banks[0].bank->lput(addr, value) : expamem_bank_current->lput(addr, value); + return; + } + write_log(_T("warning: Z2 WRITE.L to address $%08x : value $%08x\n"), addr, value); +} + +static void REGPARAM2 expamem_wput(uaecptr addr, uae_u32 value) +{ +#if EXP_DEBUG + write_log(_T("expamem_wput %x %x\n"), addr, value); +#endif + value &= 0xffff; + if (cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8) { + if (cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8(addr, &value, 2, true)) + return; + } + if (ecard >= cardno) + return; + card_data *cd = cards[ecard]; + if (!expamem_map) + expamem_map = cd->map; + if (expamem_type() != zorroIII) { + write_log(_T("warning: WRITE.W to address $%08x : value $%x PC=%08x\n"), addr, value, M68K_GETPC); + } + switch (addr & 0xff) { + case 0x48: + // A2630 boot rom writes WORDs to Z2 boards! + if (expamem_type() == zorroII) { + expamem_lo = 0; + expamem_hi = (value >> 8) & 0xff; + expamem_board_pointer = (expamem_hi | (expamem_lo >> 4)) << 16; + if (expamem_map) { + expamem_next(expamem_map(&cd->aci), NULL); + return; + } + if (expamem_bank_current && expamem_bank_current != &expamem_bank) { + expamem_bank_current->sub_banks ? expamem_bank_current->sub_banks[0].bank->bput(addr, value >> 8) : expamem_bank_current->bput(addr, value >> 8); + return; + } + } + break; + case 0x44: + if (expamem_type() == zorroIII) { + uaecptr addr; + expamem_hi = value & 0xff00; + addr = (expamem_hi | (expamem_lo >> 4)) << 16; + if (!expamem_z3hack(&currprefs)) { + expamem_board_pointer = addr; + } + else { + if (addr != expamem_board_pointer) { + put_word(regs.regs[11] + 0x20, expamem_board_pointer >> 16); + put_word(regs.regs[11] + 0x28, expamem_board_pointer >> 16); + } + } + } + if (expamem_map) { + expamem_next(expamem_map(&cd->aci), NULL); + return; + } + if (expamem_autoconfig_mode) { + map_banks_z3(cd->aci.Addrbank, expamem_board_pointer >> 16, expamem_board_size >> 16); + cd->aci.postinit = true; + cd->initrc(&cd->aci); + expamem_next(cd->aci.Addrbank, NULL); + return; + } + break; + case 0x4c: + if (expamem_map) { + expamem_next(NULL, NULL); + return; + } + break; + } + if (expamem_bank_current && expamem_bank_current != &expamem_bank) { + expamem_bank_current->sub_banks ? expamem_bank_current->sub_banks[0].bank->wput(addr, value) : expamem_bank_current->wput(addr, value); + } +} + +static void REGPARAM2 expamem_bput(uaecptr addr, uae_u32 value) +{ +#if EXP_DEBUG + write_log(_T("expamem_bput %x %x\n"), addr, value); +#endif + value &= 0xff; + if (cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8) { + if (cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8(addr, &value, 1, true)) + return; + } + if (ecard >= cardno) + return; + card_data *cd = cards[ecard]; + if (!expamem_map) + expamem_map = cd->map; + if (expamem_type() == protoautoconfig) { + switch (addr & 0xff) { + case 0x22: + expamem_hi = value & 0x7f; + expamem_board_pointer = AUTOCONFIG_Z2 | (expamem_hi * 4096); + if (expamem_map) { + expamem_next(expamem_map(&cd->aci), NULL); + return; + } + break; + } + } + else { + switch (addr & 0xff) { case 0x48: - if (expamem_type () == zorroII) { - expamem_hi = value; - (*card_map[ecard]) (); - write_log (_T(" Card %d (Zorro%s) done.\n"), ecard + 1, expamem_type() == 0xc0 ? _T("II") : _T("III")); - expamem_next (); - } else if (expamem_type() == zorroIII) - expamem_lo = value; + if (expamem_type() == zorroII) { + expamem_hi = value & 0xff; + expamem_board_pointer = (expamem_hi | (expamem_lo >> 4)) << 16; + if (expamem_map) { + expamem_next(expamem_map(&cd->aci), NULL); + return; + } + if (expamem_autoconfig_mode) { + map_banks_z2(cd->aci.Addrbank, expamem_board_pointer >> 16, expamem_board_size >> 16); + cd->aci.postinit = true; + cd->initrc(&cd->aci); + expamem_next(cd->aci.Addrbank, NULL); + return; + } + } + else { + expamem_lo = value & 0xff; + } break; case 0x4a: - if (expamem_type () == zorroII) - expamem_lo = value; + if (expamem_type() == zorroII) { + expamem_lo = value & 0xff; + } + if (expamem_autoconfig_mode) + return; break; case 0x4c: - expamem_hi = expamem_lo = 0; - (*card_map[ecard]) (); - write_log (_T(" Card %d (Zorro%s) had no success.\n"), ecard + 1, expamem_type() == 0xc0 ? _T("II") : _T("III")); - expamem_next (); + if (expamem_map) { + expamem_hi = expamem_lo = 0xff; + expamem_board_pointer = 0xffffffff; + addrbank *ab = expamem_map(&cd->aci); + if (ab) + ab->start = 0xffffffff; + expamem_next(ab, NULL); + return; + } break; + } + } + if (expamem_bank_current && expamem_bank_current != &expamem_bank) { + expamem_bank_current->sub_banks ? expamem_bank_current->sub_banks[0].bank->bput(addr, value) : expamem_bank_current->bput(addr, value); } } +static uae_u32 REGPARAM2 expamemz3_bget(uaecptr addr) +{ + int reg = addr & 0xff; + if (!expamem_bank_current) + return 0; + if (addr & 0x100) + reg += 2; + return expamem_bank_current->bget(reg + 0); +} + +static uae_u32 REGPARAM2 expamemz3_wget(uaecptr addr) +{ + uae_u32 v = (expamemz3_bget(addr) << 8) | expamemz3_bget(addr + 1); + write_log(_T("warning: Z3 READ.W from address $%08x=%04x PC=%x\n"), addr, v & 0xffff, M68K_GETPC); + return v; +} + +static uae_u32 REGPARAM2 expamemz3_lget(uaecptr addr) +{ + write_log(_T("warning: Z3 READ.L from address $%08x PC=%x\n"), addr, M68K_GETPC); + return (expamemz3_wget(addr) << 16) | expamemz3_wget(addr + 2); +} + +static void REGPARAM2 expamemz3_bput(uaecptr addr, uae_u32 value) +{ + int reg = addr & 0xff; + if (!expamem_bank_current) + return; + if (addr & 0x100) + reg += 2; + if (reg == 0x48) { + if (expamem_type() == zorroII) { + expamem_hi = value & 0xff; + expamem_board_pointer = (expamem_hi | (expamem_lo >> 4)) << 16; + } + else { + expamem_lo = value & 0xff; + } + } + else if (reg == 0x4a) { + if (expamem_type() == zorroII) + expamem_lo = value & 0xff; + } + expamem_bank_current->bput(reg, value); +} + +static void REGPARAM2 expamemz3_wput(uaecptr addr, uae_u32 value) +{ + int reg = addr & 0xff; + if (!expamem_bank_current) + return; + if (addr & 0x100) + reg += 2; + if (reg == 0x44) { + if (expamem_type() == zorroIII) { + uaecptr addr; + expamem_hi = value & 0xff00; + addr = (expamem_hi | (expamem_lo >> 4)) << 16;; + if (!expamem_z3hack(&currprefs)) { + expamem_board_pointer = addr; + } + else { + if (addr != expamem_board_pointer) { + put_word(regs.regs[11] + 0x20, expamem_board_pointer >> 16); + put_word(regs.regs[11] + 0x28, expamem_board_pointer >> 16); + } + } + } + } + expamem_bank_current->wput(reg, value); +} +static void REGPARAM2 expamemz3_lput(uaecptr addr, uae_u32 value) +{ + write_log(_T("warning: Z3 WRITE.L to address $%08x : value $%08x\n"), addr, value); +} + +#ifdef CD32 + +static bool expamem_init_cd32fmv(struct autoconfig_info *aci) +{ + expamem_init_clear(); + load_rom_rc(aci->rc, ROMTYPE_CD32CART, 262144, 0, expamem, 128, 0); + memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw); + //expamem_map = cd32_fmv_init; + return true; +} + +#endif + /* ********************************************************** */ /* - * Fast Memory - */ +* Fast Memory +*/ -MEMORY_FUNCTIONS(fastmem); -addrbank fastmem_bank = { - fastmem_lget, fastmem_wget, fastmem_bget, - fastmem_lput, fastmem_wput, fastmem_bput, - fastmem_xlate, fastmem_check, NULL, _T("Fast memory"), - fastmem_lget, fastmem_wget, ABFLAG_RAM +MEMORY_ARRAY_FUNCTIONS(fastmem, 0); +MEMORY_ARRAY_FUNCTIONS(fastmem, 1); +MEMORY_ARRAY_FUNCTIONS(fastmem, 2); +MEMORY_ARRAY_FUNCTIONS(fastmem, 3); + +addrbank fastmem_bank[MAX_RAM_BOARDS] = +{ + { + fastmem0_lget, fastmem0_wget, fastmem0_bget, + fastmem0_lput, fastmem0_wput, fastmem0_bput, + fastmem0_xlate, fastmem0_check, NULL, _T("*"), _T("Fast memory"), + fastmem0_lget, fastmem0_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 + }, + { + fastmem1_lget, fastmem1_wget, fastmem1_bget, + fastmem1_lput, fastmem1_wput, fastmem1_bput, + fastmem1_xlate, fastmem1_check, NULL, _T("*"), _T("Fast memory 2"), + fastmem1_lget, fastmem1_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 + }, + { + fastmem2_lget, fastmem2_wget, fastmem2_bget, + fastmem2_lput, fastmem2_wput, fastmem2_bput, + fastmem2_xlate, fastmem2_check, NULL, _T("*"), _T("Fast memory 3"), + fastmem2_lget, fastmem2_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 + }, + { + fastmem3_lget, fastmem3_wget, fastmem3_bget, + fastmem3_lput, fastmem3_wput, fastmem3_bput, + fastmem3_xlate, fastmem3_check, NULL, _T("*"), _T("Fast memory 4"), + fastmem3_lget, fastmem3_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 + } }; +#ifdef CATWEASEL + +/* +* Catweasel ZorroII +*/ + +DECLARE_MEMORY_FUNCTIONS(catweasel); + +static uae_u32 catweasel_mask; +static uae_u32 catweasel_start; + +static uae_u32 REGPARAM2 catweasel_lget(uaecptr addr) +{ + write_log(_T("catweasel_lget @%08X!\n"), addr); + return 0; +} + +static uae_u32 REGPARAM2 catweasel_wget(uaecptr addr) +{ + write_log(_T("catweasel_wget @%08X!\n"), addr); + return 0; +} + +static uae_u32 REGPARAM2 catweasel_bget(uaecptr addr) +{ + addr -= catweasel_start & catweasel_mask; + addr &= catweasel_mask; + return catweasel_do_bget(addr); +} + +static void REGPARAM2 catweasel_lput(uaecptr addr, uae_u32 l) +{ + write_log(_T("catweasel_lput @%08X=%08X!\n"), addr, l); +} + +static void REGPARAM2 catweasel_wput(uaecptr addr, uae_u32 w) +{ + write_log(_T("catweasel_wput @%08X=%04X!\n"), addr, w); +} + +static void REGPARAM2 catweasel_bput(uaecptr addr, uae_u32 b) +{ + addr -= catweasel_start & catweasel_mask; + addr &= catweasel_mask; + catweasel_do_bput(addr, b); +} + +static int REGPARAM2 catweasel_check(uaecptr addr, uae_u32 size) +{ + return 0; +} + +static uae_u8 *REGPARAM2 catweasel_xlate(uaecptr addr) +{ + write_log(_T("catweasel_xlate @%08X size %08X\n"), addr); + return 0; +} + +static Addrbank catweasel_bank = { + catweasel_lget, catweasel_wget, catweasel_bget, + catweasel_lput, catweasel_wput, catweasel_bput, + catweasel_xlate, catweasel_check, NULL, NULL, _T("Catweasel"), + dummy_lgeti, dummy_wgeti, + ABFLAG_IO, S_READ, S_WRITE +}; + +static Addrbank *expamem_map_catweasel(int devnum) +{ + catweasel_start = expamem_board_pointer; + map_banks_z2(&catweasel_bank, catweasel_start >> 16, 1); + return &catweasel_bank; +} + +static bool expamem_init_catweasel(struct autoconfig_info *aci) +{ + uae_u8 productid = cwc.type >= CATWEASEL_TYPE_MK3 ? 66 : 200; + uae_u16 vendorid = cwc.type >= CATWEASEL_TYPE_MK3 ? 4626 : 5001; + + catweasel_mask = (cwc.type >= CATWEASEL_TYPE_MK3) ? 0xffff : 0x1ffff; + + expamem_init_clear(); + + expamem_write(0x00, (cwc.type >= CATWEASEL_TYPE_MK3 ? Z2_MEM_64KB : Z2_MEM_128KB) | zorroII); + + expamem_write(0x04, productid); + + expamem_write(0x08, 0); + + expamem_write(0x10, vendorid >> 8); + expamem_write(0x14, vendorid & 0xff); + + expamem_write(0x18, 0x00); /* ser.no. Byte 0 */ + expamem_write(0x1c, 0x00); /* ser.no. Byte 1 */ + expamem_write(0x20, 0x00); /* ser.no. Byte 2 */ + expamem_write(0x24, 0x00); /* ser.no. Byte 3 */ + + expamem_write(0x28, 0x00); /* Rom-Offset hi */ + expamem_write(0x2c, 0x00); /* ROM-Offset lo */ + + expamem_write(0x40, 0x00); /* Ctrl/Statusreg.*/ + + memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw); + + return true; +} + +#endif + #ifdef FILESYS /* - * Filesystem device ROM - * This is very simple, the Amiga shouldn't be doing things with it. - */ +* Filesystem device ROM/RAM space +*/ -static uae_u32 REGPARAM3 filesys_lget (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 filesys_wget (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 filesys_bget (uaecptr) REGPARAM; -static void REGPARAM3 filesys_lput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 filesys_wput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 filesys_bput (uaecptr, uae_u32) REGPARAM; - -static uae_u32 filesys_start; /* Determined by the OS */ -uae_u8 *filesysory; - -static uae_u32 REGPARAM2 filesys_lget (uaecptr addr) -{ - uae_u8 *m; -#ifdef JIT - special_mem |= S_READ; -#endif - addr -= filesys_start; - addr &= 65535; - m = filesysory + addr; - return do_get_mem_long ((uae_u32 *)m); -} - -static uae_u32 REGPARAM2 filesys_wget (uaecptr addr) -{ - uae_u8 *m; -#ifdef JIT - special_mem |= S_READ; -#endif - addr -= filesys_start; - addr &= 65535; - m = filesysory + addr; - return do_get_mem_word ((uae_u16 *)m); -} - -static uae_u32 REGPARAM2 filesys_bget (uaecptr addr) -{ -#ifdef JIT - special_mem |= S_READ; -#endif - addr -= filesys_start; - addr &= 65535; - return filesysory[addr]; -} - -static void REGPARAM2 filesys_lput (uaecptr addr, uae_u32 l) -{ -#ifdef JIT - special_mem |= S_WRITE; -#endif - write_log (_T("filesys_lput called PC=%p\n"), M68K_GETPC); -} - -static void REGPARAM2 filesys_wput (uaecptr addr, uae_u32 w) -{ -#ifdef JIT - special_mem |= S_WRITE; -#endif - write_log (_T("filesys_wput called PC=%p\n"), M68K_GETPC); -} - -static void REGPARAM2 filesys_bput (uaecptr addr, uae_u32 b) -{ -#ifdef JIT - special_mem |= S_WRITE; -#endif -} - -static addrbank filesys_bank = { - filesys_lget, filesys_wget, filesys_bget, - filesys_lput, filesys_wput, filesys_bput, - default_xlate, default_check, NULL, _T("Filesystem Autoconfig Area"), - dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE +DECLARE_MEMORY_FUNCTIONS(filesys); +addrbank filesys_bank = { + filesys_lget, filesys_wget, filesys_bget, + filesys_lput, filesys_wput, filesys_bput, + filesys_xlate, filesys_check, NULL, _T("*"), _T("Filesystem autoconfig"), + filesys_lget, filesys_wget, + ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE }; +static bool filesys_write(uaecptr addr) +{ + return addr >= 0x4000; +} + +static uae_u32 REGPARAM2 filesys_lget(uaecptr addr) +{ + uae_u8 *m; + addr -= filesys_bank.start & 65535; + addr &= 65535; + m = filesys_bank.baseaddr + addr; +#if EXP_DEBUG + write_log(_T("filesys_lget %x %x\n"), addr, do_get_mem_long((uae_u32 *)m)); +#endif + return do_get_mem_long((uae_u32 *)m); +} + +static uae_u32 REGPARAM2 filesys_wget(uaecptr addr) +{ + uae_u8 *m; + addr -= filesys_bank.start & 65535; + addr &= 65535; + m = filesys_bank.baseaddr + addr; +#if EXP_DEBUG + write_log(_T("filesys_wget %x %x\n"), addr, do_get_mem_word((uae_u16 *)m)); +#endif + return do_get_mem_word((uae_u16 *)m); +} + +static uae_u32 REGPARAM2 filesys_bget(uaecptr addr) +{ + addr -= filesys_bank.start & 65535; + addr &= 65535; +#if EXP_DEBUG + write_log(_T("filesys_bget %x %x\n"), addr, filesys_bank.baseaddr[addr]); +#endif + return filesys_bank.baseaddr[addr]; +} + + +static void REGPARAM2 filesys_bput(uaecptr addr, uae_u32 b) +{ + addr -= filesys_bank.start & 65535; + addr &= 65535; + if (!filesys_write(addr)) + return; + filesys_bank.baseaddr[addr] = b; +} + +static void REGPARAM2 filesys_lput(uaecptr addr, uae_u32 l) +{ + addr -= filesys_bank.start & 65535; + addr &= 65535; + if (!filesys_write(addr)) + return; + filesys_bank.baseaddr[addr + 0] = l >> 24; + filesys_bank.baseaddr[addr + 1] = l >> 16; + filesys_bank.baseaddr[addr + 2] = l >> 8; + filesys_bank.baseaddr[addr + 3] = l >> 0; +} + +static void REGPARAM2 filesys_wput(uaecptr addr, uae_u32 w) +{ + addr -= filesys_bank.start & 65535; + addr &= 65535; + if (!filesys_write(addr)) + return; + filesys_bank.baseaddr[addr + 0] = w >> 8; + filesys_bank.baseaddr[addr + 1] = w & 0xff; +} + +static int REGPARAM2 filesys_check(uaecptr addr, uae_u32 size) +{ + addr -= filesys_bank.start & 65535; + addr &= 65535; + return (addr + size) <= filesys_bank.allocated_size; +} +static uae_u8 *REGPARAM2 filesys_xlate(uaecptr addr) +{ + addr -= filesys_bank.start & 65535; + addr &= 65535; + return filesys_bank.baseaddr + addr; +} + #endif /* FILESYS */ -/* - * Z3fastmem Memory - */ - -MEMORY_FUNCTIONS(z3fastmem); - -addrbank z3fastmem_bank = { - z3fastmem_lget, z3fastmem_wget, z3fastmem_bget, - z3fastmem_lput, z3fastmem_wput, z3fastmem_bput, - z3fastmem_xlate, z3fastmem_check, NULL, _T("ZorroIII Fast RAM"), - z3fastmem_lget, z3fastmem_wget, ABFLAG_RAM +DECLARE_MEMORY_FUNCTIONS(uaeboard); +addrbank uaeboard_bank = { + uaeboard_lget, uaeboard_wget, uaeboard_bget, + uaeboard_lput, uaeboard_wput, uaeboard_bput, + uaeboard_xlate, uaeboard_check, NULL, _T("*"), _T("UAE Board"), + dummy_lgeti, dummy_wgeti, + ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE }; -/* Z3-based UAEGFX-card */ +uae_u32 uaeboard_base; /* Determined by the OS */ +static uae_u32 uaeboard_ram_start; +#define UAEBOARD_WRITEOFFSET 0x4000 + +uae_u8 *uaeboard_map_ram(uaecptr p) +{ + if (currprefs.uaeboard > 1) { + p -= uaeboard_base; + return uaeboard_bank.baseaddr + p; + } + else { + p -= filesys_bank.start; + return filesys_bank.baseaddr + p; + } +} + +uaecptr uaeboard_alloc_ram(uae_u32 size) +{ + uaecptr p; + size += 7; + size &= ~7; + if (currprefs.uaeboard > 1) { + p = uaeboard_ram_start + uaeboard_base; + memset(uaeboard_bank.baseaddr + uaeboard_ram_start, 0, size); + } + else { + p = uaeboard_ram_start + filesys_bank.start; + memset(filesys_bank.baseaddr + uaeboard_ram_start, 0, size); + } + uaeboard_ram_start += size; + return p; +} + +static bool uaeboard_write(uaecptr addr) +{ + if (addr >= UAEBOARD_WRITEOFFSET) + return true; + return false; +} + +static uae_u32 REGPARAM2 uaeboard_wget(uaecptr addr) +{ + uae_u8 *m; + addr -= uaeboard_base & 65535; + addr &= 65535; + m = uaeboard_bank.baseaddr + addr; + uae_u16 v = do_get_mem_word((uae_u16 *)m); + return v; +} + +static uae_u32 REGPARAM2 uaeboard_lget(uaecptr addr) +{ + addr -= uaeboard_base & 65535; + addr &= 65535; + uae_u32 v = uaeboard_wget(addr) << 16; + v |= uaeboard_wget(addr + 2); + return v; +} + +static uae_u32 REGPARAM2 uaeboard_bget(uaecptr addr) +{ + addr -= uaeboard_base & 65535; + addr &= 65535; + return uaeboard_bank.baseaddr[addr]; +} + +static void REGPARAM2 uaeboard_wput(uaecptr addr, uae_u32 w) +{ + addr -= uaeboard_base & 65535; + addr &= 65535; + if (!uaeboard_write(addr)) + return; + uae_u8 *m = uaeboard_bank.baseaddr + addr; + put_word_host(m, w); +} + +static void REGPARAM2 uaeboard_lput(uaecptr addr, uae_u32 l) +{ + addr -= uaeboard_base & 65535; + addr &= 65535; + if (!uaeboard_write(addr)) + return; + uaeboard_wput(addr, l >> 16); + uaeboard_wput(addr + 2, l); +} + +static void REGPARAM2 uaeboard_bput(uaecptr addr, uae_u32 b) +{ + addr -= uaeboard_base & 65535; + addr &= 65535; + if (!uaeboard_write(addr)) + return; + uaeboard_bank.baseaddr[addr] = b; +} + +static int REGPARAM2 uaeboard_check(uaecptr addr, uae_u32 size) +{ + addr -= uaeboard_base & 65535; + addr &= 65535; + return (addr + size) <= uaeboard_bank.allocated_size; +} +static uae_u8 *REGPARAM2 uaeboard_xlate(uaecptr addr) +{ + addr -= uaeboard_base & 65535; + addr &= 65535; + return filesys_bank.baseaddr + addr; +} + +static addrbank *expamem_map_uaeboard(struct autoconfig_info *aci) +{ + uaeboard_base = expamem_board_pointer; + uaeboard_ram_start = UAEBOARD_WRITEOFFSET; + uaeboard_bank.start = uaeboard_base; + map_banks_z2(&uaeboard_bank, uaeboard_base >> 16, 1); + if (currprefs.uaeboard > 1) { + rtarea_bank.start = uaeboard_base + 65536; + map_banks_z2(&rtarea_bank, (uaeboard_base + 65536) >> 16, 1); + } + return &uaeboard_bank; +} + +static bool get_params_filesys(struct uae_prefs *prefs, struct expansion_params *p) +{ + p->device_order = prefs->uaeboard_order; + return true; +} +static bool set_params_filesys(struct uae_prefs *prefs, struct expansion_params *p) +{ + prefs->uaeboard_order = p->device_order; + return true; +} + +static bool expamem_init_uaeboard(struct autoconfig_info *aci) +{ + bool ks12 = ks12orolder(); + struct uae_prefs *p = aci->prefs; + bool hide = p->uae_hide_autoconfig; + bool rom = p->uaeboard > 1; + + aci->label = _T("UAE Boot ROM"); + aci->Addrbank = &uaeboard_bank; + aci->get_params = get_params_filesys; + aci->set_params = set_params_filesys; + + expamem_init_clear(); + expamem_write(0x00, (p->uaeboard > 1 ? Z2_MEM_128KB : Z2_MEM_64KB) | zorroII | (ks12 || !rom ? 0 : rom_card)); + + expamem_write(0x08, no_shutup); + + expamem_write(0x04, 1); + expamem_write(0x10, 6502 >> 8); + expamem_write(0x14, 6502 & 0xff); + + expamem_write(0x18, 0x00); /* ser.no. Byte 0 */ + expamem_write(0x1c, 0x00); /* ser.no. Byte 1 */ + expamem_write(0x20, p->uaeboard); /* ser.no. Byte 2 */ + expamem_write(0x24, 0x02); /* ser.no. Byte 3 */ + + uae_u8 *ptr = uaeboard_bank.baseaddr; + + if (rom) { + + int diagoffset = 0x80; + int diagpoint = 24; + int bootpoint = diagpoint + 16; + /* struct DiagArea - the size has to be large enough to store several device ROMTags */ + const uae_u8 diagarea[] = { + 0x90, 0x00, /* da_Config, da_Flags */ + 0x03, 0x00, /* da_Size */ + (uae_u8)(diagpoint >> 8), (uae_u8)diagpoint, + (uae_u8)(bootpoint >> 8), (uae_u8)bootpoint, + 0, (uae_u8)(hide ? 0 : 14), // Name offset + 0, 0, 0, 0, + (uae_u8)(hide ? 0 : 'U'), (uae_u8)(hide ? 0 : 'A'), (uae_u8)(hide ? 0 : 'E'), 0 + }; + expamem_write(0x28, diagoffset >> 8); /* ROM-Offset hi */ + expamem_write(0x2c, diagoffset & 0xff); /* ROM-Offset lo */ + /* Build a DiagArea */ + memcpy(expamem + diagoffset, diagarea, sizeof diagarea); + diagpoint += diagoffset; + bootpoint += diagoffset; + + if (aci->doinit) { + if (p->uaeboard > 2) { + /* Call hwtrap_install */ + put_word_host(expamem + diagpoint + 0, 0x4EB9); /* JSR */ + put_long_host(expamem + diagpoint + 2, filesys_get_entry(9)); + diagpoint += 6; + } + /* Call DiagEntry */ + put_word_host(expamem + diagpoint + 0, 0x4EF9); /* JMP */ + put_long_host(expamem + diagpoint + 2, ROM_filesys_diagentry); + + /* What comes next is a plain bootblock */ + put_word_host(expamem + bootpoint + 0, 0x4EF9); /* JMP */ + put_long_host(expamem + bootpoint + 2, EXPANSION_bootcode); + + put_long_host(rtarea_bank.baseaddr + RTAREA_FSBOARD, uaeboard_bank.start + 0x2000); + } + + } + else { + + expamem_write(0x28, 0x00); /* ROM-Offset hi */ + expamem_write(0x2c, 0x00); /* ROM-Offset lo */ + + } + + memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw); + + if (!aci->doinit) + return true; + + memcpy(ptr, expamem, 0x100); + + return true; +} + +/* +* Z3fastmem Memory +*/ + +MEMORY_ARRAY_FUNCTIONS(z3fastmem, 0); +MEMORY_ARRAY_FUNCTIONS(z3fastmem, 1); +MEMORY_ARRAY_FUNCTIONS(z3fastmem, 2); +MEMORY_ARRAY_FUNCTIONS(z3fastmem, 3); + +addrbank z3fastmem_bank[MAX_RAM_BOARDS] = +{ + { + z3fastmem0_lget, z3fastmem0_wget, z3fastmem0_bget, + z3fastmem0_lput, z3fastmem0_wput, z3fastmem0_bput, + z3fastmem0_xlate, z3fastmem0_check, NULL, _T("*"), _T("Zorro III Fast RAM"), + z3fastmem0_lget, z3fastmem0_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 + }, + { + z3fastmem1_lget, z3fastmem1_wget, z3fastmem1_bget, + z3fastmem1_lput, z3fastmem1_wput, z3fastmem1_bput, + z3fastmem1_xlate, z3fastmem1_check, NULL, _T("*"), _T("Zorro III Fast RAM #2"), + z3fastmem1_lget, z3fastmem1_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 + }, + { + z3fastmem2_lget, z3fastmem2_wget, z3fastmem2_bget, + z3fastmem2_lput, z3fastmem2_wput, z3fastmem2_bput, + z3fastmem2_xlate, z3fastmem2_check, NULL, _T("*"), _T("Zorro III Fast RAM #3"), + z3fastmem2_lget, z3fastmem2_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 + }, + { + z3fastmem3_lget, z3fastmem3_wget, z3fastmem3_bget, + z3fastmem3_lput, z3fastmem3_wput, z3fastmem3_bput, + z3fastmem3_xlate, z3fastmem3_check, NULL, _T("*"), _T("Zorro III Fast RAM #4"), + z3fastmem3_lget, z3fastmem3_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 + } +}; + +MEMORY_FUNCTIONS(z3chipmem); + +addrbank z3chipmem_bank = { + z3chipmem_lget, z3chipmem_wget, z3chipmem_bget, + z3chipmem_lput, z3chipmem_wput, z3chipmem_bput, + z3chipmem_xlate, z3chipmem_check, NULL, _T("*"), _T("MegaChipRAM"), + z3chipmem_lget, z3chipmem_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 +}; /* ********************************************************** */ /* - * Expansion Card (ZORRO II) for 1/2/4/8 MB of Fast Memory - */ +* Expansion Card (ZORRO II) for 64/128/256/512KB 1/2/4/8MB of Fast Memory +*/ -static void expamem_map_fastcard (void) +static addrbank *expamem_map_fastcard(struct autoconfig_info *aci) { - fastmem_bank.start = ((expamem_hi | (expamem_lo >> 4)) << 16); - if (fastmem_bank.start) { - map_banks (&fastmem_bank, fastmem_bank.start >> 16, fastmem_bank.allocated >> 16, 0); - write_log (_T("Fastcard: mapped @$%lx: %dMB fast memory\n"), fastmem_bank.start, fastmem_bank.allocated >> 20); - } + uae_u32 start = ((expamem_hi | (expamem_lo >> 4)) << 16); + addrbank *ab = &fastmem_bank[aci->devnum]; + if (start == 0x00ff0000) + return ab; + uae_u32 size = ab->allocated_size; + ab->start = start; + if (ab->start && size) { + map_banks_z2(ab, ab->start >> 16, size >> 16); + } + return ab; } -static void expamem_init_fastcard (void) +static bool fastmem_autoconfig(struct uae_prefs *p, struct autoconfig_info *aci, int zorro, uae_u8 type, uae_u32 serial, int allocated) { - uae_u16 mid = uae_id; - uae_u8 pid = 81; - uae_u8 type = add_memory | zorroII; + uae_u16 mid = 0; + uae_u8 pid; + uae_u8 flags = 0; + DEVICE_MEMORY_CALLBACK dmc = NULL; + struct romconfig *dmc_rc = NULL; + uae_u8 ac[16] = { 0 }; + int boardnum = aci->devnum; - expamem_init_clear(); - if (fastmem_bank.allocated == 0x100000) + if (aci->cst) { + mid = aci->cst->memory_mid; + pid = aci->cst->memory_pid; + serial = aci->cst->memory_serial; + } + else if (aci->ert) { + const struct expansionromtype *ert = aci->ert; + struct romconfig *rc = get_device_romconfig(p, ert->romtype, 0); + if (ert->subtypes) { + const struct expansionsubromtype *srt = &ert->subtypes[rc->subtype]; + if (srt->memory_mid) { + mid = srt->memory_mid; + pid = srt->memory_pid; + serial = srt->memory_serial; + if (!srt->memory_after) + type |= chainedconfig; + } + } + else { + if (ert->memory_mid) { + mid = ert->memory_mid; + pid = ert->memory_pid; + serial = ert->memory_serial; + if (!ert->memory_after) + type |= chainedconfig; + } + } + dmc = ert->memory_callback; + dmc_rc = rc; + } + + uae_u8 *forceac = NULL; + struct ramboard *rb = NULL; + + if (!mid) { + if (zorro <= 2) { + rb = &p->fastmem[boardnum]; + if (rb->autoconfig[0]) { + forceac = rb->autoconfig; + } + else if (rb->manufacturer) { + mid = rb->manufacturer; + pid = rb->product; + serial = 0; + } + else { + pid = p->maprom && !p->cpuboard_type ? 1 : 81; + } + } + else { + int subsize = (allocated == 0x100000 ? Z3_SS_MEM_1MB + : allocated == 0x200000 ? Z3_SS_MEM_2MB + : allocated == 0x400000 ? Z3_SS_MEM_4MB + : allocated == 0x800000 ? Z3_SS_MEM_8MB + : Z3_SS_MEM_SAME); + struct ramboard *rb = &p->z3fastmem[boardnum]; + if (rb->autoconfig[0]) { + forceac = rb->autoconfig; + } + else if (rb->manufacturer) { + mid = rb->manufacturer; + pid = rb->product; + serial = 0; + } + else { + pid = p->maprom && !p->cpuboard_type ? 3 : 83; + } + flags |= care_addr | force_z3 | (allocated > 0x800000 ? ext_size : subsize); + } + } + if (!mid) { + mid = uae_id; + serial = 1; + } + + if (forceac) { + for (int i = 0; i < 16; i++) { + ac[i] = forceac[i]; + ac[0] &= ~7; + ac[0] |= type & 7; + if (flags) + ac[0x08 / 4] = flags; + } + } + else { + ac[0x00 / 4] = type; + ac[0x04 / 4] = pid; + ac[0x08 / 4] = flags; + ac[0x10 / 4] = mid >> 8; + ac[0x14 / 4] = (uae_u8)mid; + ac[0x18 / 4] = serial >> 24; + ac[0x1c / 4] = serial >> 16; + ac[0x20 / 4] = serial >> 8; + ac[0x24 / 4] = serial >> 0; + } + + if (dmc && dmc_rc) + dmc(dmc_rc, ac, allocated); + + expamem_write(0x00, ac[0x00 / 4]); + expamem_write(0x04, ac[0x04 / 4]); + expamem_write(0x08, ac[0x08 / 4]); + expamem_write(0x10, ac[0x10 / 4]); + expamem_write(0x14, ac[0x14 / 4]); + + expamem_write(0x18, ac[0x18 / 4]); /* ser.no. Byte 0 */ + expamem_write(0x1c, ac[0x1c / 4]); /* ser.no. Byte 1 */ + expamem_write(0x20, ac[0x20 / 4]); /* ser.no. Byte 2 */ + expamem_write(0x24, ac[0x24 / 4]); /* ser.no. Byte 3 */ + + expamem_write(0x28, 0x00); /* ROM-Offset hi */ + expamem_write(0x2c, 0x00); /* ROM-Offset lo */ + + expamem_write(0x40, 0x00); /* Ctrl/Statusreg.*/ + + if (rb && rb->manual_config) { + aci->start = rb->start_address; + aci->size = rb->end_address - rb->start_address + 1; + memcpy(&aci->autoconfig_bytes, ac, sizeof ac); + return false; + } + + return true; +} + +static const uae_u8 a2630_autoconfig[] = { 0xe7, 0x51, 0x40, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +static bool megachipram_init(struct autoconfig_info *aci) +{ + aci->zorro = 0; + aci->start = 0x10000000; + aci->size = aci->prefs->z3chipmem_size; + aci->label = _T("32-bit Chip RAM"); + return true; +} + +static bool expamem_init_fastcard_2(struct autoconfig_info *aci, int zorro) +{ + struct uae_prefs *p = aci->prefs; + addrbank *bank = &fastmem_bank[aci->devnum]; + uae_u8 type = add_memory | zorroII; + int size = p->fastmem[aci->devnum].size; + + aci->label = zorro == 1 ? _T("Z1 Fast RAM") : _T("Z2 Fast RAM"); + aci->zorro = zorro; + + expamem_init_clear(); + if (size == 65536) + type |= Z2_MEM_64KB; + else if (size == 131072) + type |= Z2_MEM_128KB; + else if (size == 262144) + type |= Z2_MEM_256KB; + else if (size == 524288) + type |= Z2_MEM_512KB; + else if (size == 0x100000) type |= Z2_MEM_1MB; - else if (fastmem_bank.allocated == 0x200000) + else if (size == 0x200000) type |= Z2_MEM_2MB; - else if (fastmem_bank.allocated == 0x400000) + else if (size == 0x400000) type |= Z2_MEM_4MB; - else if (fastmem_bank.allocated == 0x800000) + else if (size == 0x800000) type |= Z2_MEM_8MB; - expamem_write (0x00, type); + aci->Addrbank = bank; + aci->write_bank_address = p->fastmem[aci->devnum].write_address; - expamem_write (0x08, care_addr); +#ifndef AMIBERRY + if (aci->devnum == 0) { + if (ISCPUBOARDP(p, BOARD_COMMODORE, BOARD_COMMODORE_SUB_A26x0)) { + expamem_write(1 * 4, p->cpu_model <= 68020 ? 0x50 : 0x51); + for (int i = 2; i < 16; i++) + expamem_write(i * 4, a2630_autoconfig[i]); + type &= 7; + type |= a2630_autoconfig[0] & ~7; + expamem_write(0, type); + memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw); + return true; + } + } +#endif - expamem_write (0x04, pid); + if (!fastmem_autoconfig(p, aci, BOARD_AUTOCONFIG_Z2, type, 1, size)) { + aci->zorro = -1; + } - expamem_write (0x10, mid >> 8); - expamem_write (0x14, mid & 0xff); + if (expamem_write_space[0] != 0x00 && expamem_write_space[0] != 0xff && aci->write_bank_address) { + memcpy(expamem, expamem_write_space, 65536); + memcpy(bank->baseaddr, expamem_write_space, 65536); + } - expamem_write (0x18, 0x00); /* ser.no. Byte 0 */ - expamem_write (0x1c, 0x00); /* ser.no. Byte 1 */ - expamem_write (0x20, 0x00); /* ser.no. Byte 2 */ - expamem_write (0x24, 0x01); /* ser.no. Byte 3 */ + memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw); - expamem_write (0x28, 0x00); /* Rom-Offset hi */ - expamem_write (0x2c, 0x00); /* ROM-Offset lo */ + if (p->fastmem[aci->devnum].no_reset_unmap && bank->allocated_size) { + map_banks_z2(bank, bank->start >> 16, size >> 16); + } - expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/ + return true; +} + +static bool expamem_init_fastcard(struct autoconfig_info *aci) +{ + return expamem_init_fastcard_2(aci, 2); +} +static bool expamem_init_fastcard_z1(struct autoconfig_info *aci) +{ + return expamem_init_fastcard_2(aci, 1); +} + +bool expansion_is_next_board_fastram(void) +{ + return ecard + 1 < MAX_EXPANSION_BOARD_SPACE && cards[ecard + 1] && cards[ecard + 1]->map == expamem_map_fastcard; } /* ********************************************************** */ #ifdef FILESYS -/* - * Filesystem device - */ - -static void expamem_map_filesys (void) +static bool expamem_rtarea_init(struct autoconfig_info *aci) { - uaecptr a; - - filesys_start = ((expamem_hi | (expamem_lo >> 4)) << 16); - map_banks (&filesys_bank, filesys_start >> 16, 1, 0); - write_log (_T("Filesystem: mapped memory @$%lx.\n"), filesys_start); - /* 68k code needs to know this. */ - a = here (); - org (rtarea_base + RTAREA_FSBOARD); - dl (filesys_start + 0x2000); - org (a); + aci->start = rtarea_base; + aci->size = 65536; + aci->Addrbank = &rtarea_bank; + aci->label = _T("UAE Boot ROM"); + return true; } -#define FILESYS_DIAGPOINT 0x01e0 -#define FILESYS_BOOTPOINT 0x01e6 -#define FILESYS_DIAGAREA 0x2000 +/* +* Filesystem device +*/ -static void expamem_init_filesys (void) +static void expamem_map_filesys_update(void) { - /* struct DiagArea - the size has to be large enough to store several device ROMTags */ - uae_u8 diagarea[] = { 0x90, 0x00, /* da_Config, da_Flags */ - 0x02, 0x00, /* da_Size */ + /* 68k code needs to know this. */ + uaecptr a = here(); + org(rtarea_base + RTAREA_FSBOARD); + dl(filesys_bank.start + 0x2000); + org(a); +} + +static addrbank *expamem_map_filesys(struct autoconfig_info *aci) +{ + // Warn if PPC doing autoconfig and UAE expansion enabled + static bool warned; + if (!warned && regs.halted < 0) { + warned = true; + // can't show dialogs from PPC thread, deadlock danger. + regs.halted = -2; + } + mapped_free(&filesys_bank); + filesys_bank.start = expamem_board_pointer; + filesys_bank.mask = filesys_bank.reserved_size - 1; + if (expamem_board_pointer == 0xffffffff) + return &filesys_bank; + mapped_malloc(&filesys_bank); + memcpy(filesys_bank.baseaddr, expamem, 0x3000); + uaeboard_ram_start = UAEBOARD_WRITEOFFSET; + map_banks_z2(&filesys_bank, filesys_bank.start >> 16, 1); + expamem_map_filesys_update(); + return &filesys_bank; +} + +#if KS12_BOOT_HACK +static void add_ks12_boot_hack(void) +{ + uaecptr name = ds(_T("UAE boot")); + align(2); + uaecptr code = here(); + // allocate fake diagarea + dl(0x48e73f3e); // movem.l d2-d7/a2-a6,-(sp) + dw(0x203c); // move.l #x,d0 + dl(0x0300); + dw(0x7201); // moveq #1,d1 + dl(0x4eaeff3a); // jsr -0xc6(a6) + dw(0x2440); // move.l d0,a2 ;diag area + dw(0x9bcd); // sub.l a5,a5 ;expansionbase + dw(0x97cb); // sub.l a3,a3 ;configdev + dw(0x4eb9); // jsr + dl(ROM_filesys_diagentry); + dl(0x4cdf7cfc); // movem.l (sp)+,d2-d7/a2-a6 + dw(0x4e75); + // struct Resident + uaecptr addr = here(); + dw(0x4afc); + dl(addr); + dl(addr + 26); + db(1); // RTF_COLDSTART + db((uae_u8)kickstart_version); // version + db(0); // NT_UNKNOWN + db(1); // priority + dl(name); + dl(name); + dl(code); +} +#endif + +static bool expamem_init_filesys(struct autoconfig_info *aci) +{ + bool ks12 = ks12orolder(); + bool hide = currprefs.uae_hide_autoconfig; + + if (aci) { + aci->label = ks12 ? _T("Pre-KS 1.3 UAE FS ROM") : _T("UAE FS ROM"); + aci->get_params = get_params_filesys; + aci->set_params = set_params_filesys; + aci->Addrbank = &filesys_bank; + } + +#if 0 + FILE *f = fopen("d:\\amiga\\amiga\\source\\acap\\autoconf", "rb"); + fread(expamem, 1, 256, f); + fclose(f); + memcpy(filesys_bank.baseaddr, expamem, 0x3000); + return NULL; +#endif + + /* struct DiagArea - the size has to be large enough to store several device ROMTags */ + const uae_u8 diagarea[] = { + 0x90, 0x00, /* da_Config, da_Flags */ + 0x02, 0x00, /* da_Size */ FILESYS_DIAGPOINT >> 8, FILESYS_DIAGPOINT & 0xff, - FILESYS_BOOTPOINT >> 8, FILESYS_BOOTPOINT & 0xff - }; + FILESYS_BOOTPOINT >> 8, FILESYS_BOOTPOINT & 0xff, + 0, (uae_u8)(hide ? 0 : 14), // Name offset + 0, 0, 0, 0, + (uae_u8)(hide ? 0 : 'U'), (uae_u8)(hide ? 0 : 'A'), (uae_u8)(hide ? 0 : 'E'), 0 + }; - expamem_init_clear(); - expamem_write (0x00, Z2_MEM_64KB | rom_card | zorroII); + expamem_init_clear(); + expamem_write(0x00, Z2_MEM_64KB | zorroII | (ks12 || !do_mount ? 0 : rom_card)); - expamem_write (0x08, no_shutup); + expamem_write(0x08, no_shutup); - expamem_write (0x04, 82); - expamem_write (0x10, uae_id >> 8); - expamem_write (0x14, uae_id & 0xff); + expamem_write(0x04, currprefs.maprom && !currprefs.cpuboard_type ? 2 : 82); + expamem_write(0x10, uae_id >> 8); + expamem_write(0x14, uae_id & 0xff); - expamem_write (0x18, 0x00); /* ser.no. Byte 0 */ - expamem_write (0x1c, 0x00); /* ser.no. Byte 1 */ - expamem_write (0x20, 0x00); /* ser.no. Byte 2 */ - expamem_write (0x24, 0x01); /* ser.no. Byte 3 */ + expamem_write(0x18, 0x00); /* ser.no. Byte 0 */ + expamem_write(0x1c, 0x00); /* ser.no. Byte 1 */ + expamem_write(0x20, 0x00); /* ser.no. Byte 2 */ + expamem_write(0x24, 0x01); /* ser.no. Byte 3 */ - /* er_InitDiagVec */ - expamem_write (0x28, 0x20); /* Rom-Offset hi */ - expamem_write (0x2c, 0x00); /* ROM-Offset lo */ + /* er_InitDiagVec */ + expamem_write(0x28, 0x20); /* ROM-Offset hi */ + expamem_write(0x2c, 0x00); /* ROM-Offset lo */ - expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/ + expamem_write(0x40, 0x00); /* Ctrl/Statusreg.*/ - /* Build a DiagArea */ - memcpy (expamem + FILESYS_DIAGAREA, diagarea, sizeof diagarea); + if (aci && !aci->doinit) { + memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw); + return true; + } - /* Call DiagEntry */ - do_put_mem_word ((uae_u16 *)(expamem + FILESYS_DIAGAREA + FILESYS_DIAGPOINT), 0x4EF9); /* JMP */ - do_put_mem_long ((uae_u32 *)(expamem + FILESYS_DIAGAREA + FILESYS_DIAGPOINT + 2), ROM_filesys_diagentry); + /* Build a DiagArea */ + memcpy(expamem + FILESYS_DIAGAREA, diagarea, sizeof diagarea); - /* What comes next is a plain bootblock */ - do_put_mem_word ((uae_u16 *)(expamem + FILESYS_DIAGAREA + FILESYS_BOOTPOINT), 0x4EF9); /* JMP */ - do_put_mem_long ((uae_u32 *)(expamem + FILESYS_DIAGAREA + FILESYS_BOOTPOINT + 2), EXPANSION_bootcode); - - memcpy (filesysory, expamem, 0x3000); + /* Call DiagEntry */ + put_word_host(expamem + FILESYS_DIAGAREA + FILESYS_DIAGPOINT, 0x4EF9); /* JMP */ + put_long_host(expamem + FILESYS_DIAGAREA + FILESYS_DIAGPOINT + 2, ROM_filesys_diagentry); + + /* What comes next is a plain bootblock */ + put_word_host(expamem + FILESYS_DIAGAREA + FILESYS_BOOTPOINT, 0x4EF9); /* JMP */ + put_long_host(expamem + FILESYS_DIAGAREA + FILESYS_BOOTPOINT + 2, EXPANSION_bootcode); + + if (ks12) + add_ks12_boot_hack(); + + return true; } #endif /* - * Zorro III expansion memory - */ +* Zorro III expansion memory +*/ -static void expamem_map_z3fastmem_2 (addrbank *bank, uaecptr *startp, uae_u32 size, uae_u32 allocated, int chip) +static addrbank *expamem_map_z3fastmem(struct autoconfig_info *aci) { - int z3fs = ((expamem_hi | (expamem_lo >> 4)) << 16); - int start = *startp; + int devnum = aci->devnum; + addrbank *ab = &z3fastmem_bank[devnum]; + uaecptr z3fs = expamem_board_pointer; + uae_u32 size = currprefs.z3fastmem[devnum].size; - if (z3fs && start != z3fs) { - write_log(_T("WARNING: Z3MEM mapping changed from $%08x to $%08x\n"), start, z3fs); - map_banks(&dummy_bank, start >> 16, size >> 16, allocated); - *startp = z3fs; - map_banks (bank, start >> 16, size >> 16, allocated); - } - write_log (_T("Z3MEM (32bit): mapped @$%08x: %d MB Zorro III %s memory \n"), - start, allocated / 0x100000, chip ? _T("chip") : _T("fast")); + if (ab->allocated_size) + map_banks_z3(ab, z3fs >> 16, size >> 16); + return ab; } -static void expamem_map_z3fastmem (void) +static bool expamem_init_z3fastmem(struct autoconfig_info *aci) { - expamem_map_z3fastmem_2 (&z3fastmem_bank, &z3fastmem_bank.start, currprefs.z3fastmem_size, z3fastmem_bank.allocated, 0); -} + addrbank *bank = &z3fastmem_bank[aci->devnum]; -static void expamem_init_z3fastmem_2 (addrbank *bank, uae_u32 start, uae_u32 size, uae_u32 allocated) -{ - int code = (allocated == 0x100000 ? Z2_MEM_1MB - : allocated == 0x200000 ? Z2_MEM_2MB - : allocated == 0x400000 ? Z2_MEM_4MB - : allocated == 0x800000 ? Z2_MEM_8MB - : allocated == 0x1000000 ? Z3_MEM_16MB - : allocated == 0x2000000 ? Z3_MEM_32MB - : allocated == 0x4000000 ? Z3_MEM_64MB - : allocated == 0x8000000 ? Z3_MEM_128MB - : allocated == 0x10000000 ? Z3_MEM_256MB - : allocated == 0x20000000 ? Z3_MEM_512MB + uae_u32 size = aci->prefs->z3fastmem[aci->devnum].size; + + aci->label = _T("Z3 Fast RAM"); + + int code = (size == 0x100000 ? Z2_MEM_1MB + : size == 0x200000 ? Z2_MEM_2MB + : size == 0x400000 ? Z2_MEM_4MB + : size == 0x800000 ? Z2_MEM_8MB + : size == 0x1000000 ? Z3_MEM_16MB + : size == 0x2000000 ? Z3_MEM_32MB + : size == 0x4000000 ? Z3_MEM_64MB + : size == 0x8000000 ? Z3_MEM_128MB + : size == 0x10000000 ? Z3_MEM_256MB + : size == 0x20000000 ? Z3_MEM_512MB : Z3_MEM_1GB); - int subsize = (allocated == 0x100000 ? Z3_SS_MEM_1MB - : allocated == 0x200000 ? Z3_SS_MEM_2MB - : allocated == 0x400000 ? Z3_SS_MEM_4MB - : allocated == 0x800000 ? Z3_SS_MEM_8MB - : Z3_SS_MEM_SAME); - if (allocated < 0x1000000) + if (size < 0x1000000) code = Z3_MEM_16MB; /* Z3 physical board size is always at least 16M */ - expamem_init_clear(); - expamem_write (0x00, add_memory | zorroIII | code); + expamem_init_clear(); + fastmem_autoconfig(aci->prefs, aci, BOARD_AUTOCONFIG_Z3, add_memory | zorroIII | code, 1, size); - expamem_write (0x08, care_addr | force_z3 | (allocated > 0x800000 ? ext_size : subsize)); + memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw); + aci->Addrbank = bank; - expamem_write (0x04, 83); + if (!aci->doinit) + return true; - expamem_write (0x10, uae_id >> 8); - expamem_write (0x14, uae_id & 0xff); - - expamem_write (0x18, 0x00); /* ser.no. Byte 0 */ - expamem_write (0x1c, 0x00); /* ser.no. Byte 1 */ - expamem_write (0x20, 0x00); /* ser.no. Byte 2 */ - expamem_write (0x24, 0x01); /* ser.no. Byte 3 */ - - expamem_write (0x28, 0x00); /* Rom-Offset hi */ - expamem_write (0x2c, 0x00); /* ROM-Offset lo */ - - expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/ - - map_banks (bank, start >> 16, size >> 16, allocated); -} -static void expamem_init_z3fastmem (void) -{ - expamem_init_z3fastmem_2 (&z3fastmem_bank, z3fastmem_bank.start, currprefs.z3fastmem_size, z3fastmem_bank.allocated); + uae_u32 start = bank->start; + bool alwaysmapz3 = aci->prefs->z3_mapping_mode != Z3MAPPING_REAL || aci->prefs->z3fastmem[aci->devnum].no_reset_unmap; + if ((alwaysmapz3 || expamem_z3hack(aci->prefs)) && bank->allocated_size) { + map_banks_z3(bank, start >> 16, size >> 16); + } + return true; } #ifdef PICASSO96 /* - * Fake Graphics Card (ZORRO III) - BDK - */ +* Fake Graphics Card (ZORRO III) - BDK +*/ -static void expamem_map_gfxcard (void) +static addrbank *expamem_map_gfxcard_z3(struct autoconfig_info *aci) { - gfxmem_bank.start = (expamem_hi | (expamem_lo >> 4)) << 16; - if (gfxmem_bank.start) { - map_banks (&gfxmem_bank, gfxmem_bank.start >> 16, gfxmem_bank.allocated >> 16, gfxmem_bank.allocated); - write_log (_T("%sUAEGFX-card: mapped @$%lx, %d MB RTG RAM\n"), currprefs.rtgmem_type ? _T("Z3") : _T("Z2"), gfxmem_bank.baseaddr, gfxmem_bank.allocated / 0x100000); - } + int devnum = aci->devnum; + gfxmem_banks[devnum]->start = expamem_board_pointer; + map_banks_z3(gfxmem_banks[devnum], gfxmem_banks[devnum]->start >> 16, gfxmem_banks[devnum]->allocated_size >> 16); + return gfxmem_banks[devnum]; } -static void expamem_init_gfxcard (bool z3) +static addrbank *expamem_map_gfxcard_z2(struct autoconfig_info *aci) { - int code = (gfxmem_bank.allocated == 0x100000 ? Z2_MEM_1MB - : gfxmem_bank.allocated == 0x200000 ? Z2_MEM_2MB - : gfxmem_bank.allocated == 0x400000 ? Z2_MEM_4MB - : gfxmem_bank.allocated == 0x800000 ? Z2_MEM_8MB - : gfxmem_bank.allocated == 0x1000000 ? Z3_MEM_16MB - : gfxmem_bank.allocated == 0x2000000 ? Z3_MEM_32MB - : gfxmem_bank.allocated == 0x4000000 ? Z3_MEM_64MB - : gfxmem_bank.allocated == 0x8000000 ? Z3_MEM_128MB - : gfxmem_bank.allocated == 0x10000000 ? Z3_MEM_256MB - : gfxmem_bank.allocated == 0x20000000 ? Z3_MEM_512MB - : Z3_MEM_1GB); - int subsize = (gfxmem_bank.allocated == 0x100000 ? Z3_SS_MEM_1MB - : gfxmem_bank.allocated == 0x200000 ? Z3_SS_MEM_2MB - : gfxmem_bank.allocated == 0x400000 ? Z3_SS_MEM_4MB - : gfxmem_bank.allocated == 0x800000 ? Z3_SS_MEM_8MB - : Z3_SS_MEM_SAME); + int devnum = aci->devnum; + gfxmem_banks[devnum]->start = expamem_board_pointer; + map_banks_z2(gfxmem_banks[devnum], gfxmem_banks[devnum]->start >> 16, gfxmem_banks[devnum]->allocated_size >> 16); + return gfxmem_banks[devnum]; +} - if (gfxmem_bank.allocated < 0x1000000 && z3) +static bool expamem_init_gfxcard(struct autoconfig_info *aci, bool z3) +{ + int devnum = aci->devnum; + struct uae_prefs *p = aci->prefs; + int size = p->rtgboards[devnum].rtgmem_size; + int code = (size == 0x100000 ? Z2_MEM_1MB + : size == 0x200000 ? Z2_MEM_2MB + : size == 0x400000 ? Z2_MEM_4MB + : size == 0x800000 ? Z2_MEM_8MB + : size == 0x1000000 ? Z3_MEM_16MB + : size == 0x2000000 ? Z3_MEM_32MB + : size == 0x4000000 ? Z3_MEM_64MB + : size == 0x8000000 ? Z3_MEM_128MB + : size == 0x10000000 ? Z3_MEM_256MB + : size == 0x20000000 ? Z3_MEM_512MB + : Z3_MEM_1GB); + int subsize = (size == 0x100000 ? Z3_SS_MEM_1MB + : size == 0x200000 ? Z3_SS_MEM_2MB + : size == 0x400000 ? Z3_SS_MEM_4MB + : size == 0x800000 ? Z3_SS_MEM_8MB + : Z3_SS_MEM_SAME); + + aci->label = _T("UAE RTG"); + aci->direct_vram = true; + + if (size < 0x1000000 && z3) code = Z3_MEM_16MB; /* Z3 physical board size is always at least 16M */ - expamem_init_clear(); - expamem_write (0x00, (z3 ? zorroIII : zorroII) | code); + expamem_init_clear(); + expamem_write(0x00, (z3 ? zorroIII : zorroII) | code); - expamem_write (0x08, care_addr | (z3 ? (force_z3 | (gfxmem_bank.allocated > 0x800000 ? ext_size: subsize)) : 0)); + expamem_write(0x08, care_addr | (z3 ? (force_z3 | (size > 0x800000 ? ext_size : subsize)) : 0)); + expamem_write(0x04, 96); - expamem_write (0x04, 96); + expamem_write(0x10, uae_id >> 8); + expamem_write(0x14, uae_id & 0xff); - expamem_write (0x10, uae_id >> 8); - expamem_write (0x14, uae_id & 0xff); + expamem_write(0x18, 0x00); /* ser.no. Byte 0 */ + expamem_write(0x1c, 0x00); /* ser.no. Byte 1 */ + expamem_write(0x20, 0x00); /* ser.no. Byte 2 */ + expamem_write(0x24, 0x01); /* ser.no. Byte 3 */ - expamem_write (0x18, 0x00); /* ser.no. Byte 0 */ - expamem_write (0x1c, 0x00); /* ser.no. Byte 1 */ - expamem_write (0x20, 0x00); /* ser.no. Byte 2 */ - expamem_write (0x24, 0x01); /* ser.no. Byte 3 */ + expamem_write(0x28, 0x00); /* ROM-Offset hi */ + expamem_write(0x2c, 0x00); /* ROM-Offset lo */ - expamem_write (0x28, 0x00); /* ROM-Offset hi */ - expamem_write (0x2c, 0x00); /* ROM-Offset lo */ + expamem_write(0x40, 0x00); /* Ctrl/Statusreg.*/ - expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/ + memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw); + aci->Addrbank = gfxmem_banks[devnum]; + return true; } -static void expamem_init_gfxcard_z3 (void) +static bool expamem_init_gfxcard_z3(struct autoconfig_info *aci) { - expamem_init_gfxcard (true); + return expamem_init_gfxcard(aci, true); } -static void expamem_init_gfxcard_z2 (void) +static bool expamem_init_gfxcard_z2(struct autoconfig_info *aci) { - expamem_init_gfxcard (false); + return expamem_init_gfxcard(aci, false); } #endif + #ifdef SAVESTATE -static size_t fast_filepos, z3_filepos, p96_filepos; +static size_t fast_filepos[MAX_RAM_BOARDS], z3_filepos[MAX_RAM_BOARDS]; +static size_t z3_fileposchip, p96_filepos; #endif -void free_fastmemory (void) +void free_fastmemory(int boardnum) { - if (fastmem_bank.baseaddr) - mapped_free (fastmem_bank.baseaddr); - fastmem_bank.baseaddr = 0; + mapped_free(&fastmem_bank[boardnum]); } -static bool mapped_malloc_dynamic (uae_u32 *currpsize, uae_u32 *changedpsize, addrbank *bank, int max, const TCHAR *name) +static bool mapped_malloc_dynamic(uae_u32 *currpsize, uae_u32 *changedpsize, addrbank *bank, int max, const TCHAR *label) { int alloc = *currpsize; - bank->allocated = 0; + bank->allocated_size = 0; + bank->reserved_size = alloc; bank->baseaddr = NULL; bank->mask = 0; if (!alloc) return false; - while (alloc >= max * 1024 * 1024) { - uae_u8 *mem = mapped_malloc (alloc, name); - if (mem) { - bank->baseaddr = mem; - *currpsize = alloc; - *changedpsize = alloc; - bank->mask = alloc - 1; - bank->allocated = alloc; - return true; - } - write_log (_T("Out of memory for %s, %d bytes.\n"), name, alloc); - alloc /= 2; + bank->mask = alloc - 1; + bank->label = label ? label : _T("*"); + if (mapped_malloc(bank)) { + *currpsize = alloc; + *changedpsize = alloc; + return true; } + write_log(_T("Out of memory for %s, %d bytes.\n"), label ? label : _T("?"), alloc); return false; } -static void allocate_expamem (void) +uaecptr expansion_startaddress(struct uae_prefs *p, uaecptr addr, uae_u32 size) { - currprefs.fastmem_size = changed_prefs.fastmem_size; - currprefs.z3fastmem_size = changed_prefs.z3fastmem_size; - currprefs.rtgmem_size = changed_prefs.rtgmem_size; - currprefs.rtgmem_type = changed_prefs.rtgmem_type; + if (!size) + return addr; + if (addr < 0x10000000) { + return (addr + size - 1) & ~(size - 1); + } + else { + if (size < 16 * 1024 * 1024) + size = 16 * 1024 * 1024; + if (!expamem_z3hack(p)) + return (addr + size - 1) & ~(size - 1); + } + return addr; +} - z3fastmem_bank.start = currprefs.z3fastmem_start; +static void allocate_expamem(void) +{ + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + memcpy(&currprefs.rtgboards[i], &changed_prefs.rtgboards[i], sizeof(struct rtgboardconfig)); + } + currprefs.z3chipmem_size = changed_prefs.z3chipmem_size; - if (fastmem_bank.allocated != currprefs.fastmem_size) { - free_fastmemory (); - fastmem_bank.allocated = currprefs.fastmem_size; - fastmem_bank.mask = fastmem_bank.allocated - 1; + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + currprefs.fastmem[i].size = changed_prefs.fastmem[i].size; + currprefs.z3fastmem[i].size = changed_prefs.z3fastmem[i].size; + } - if (fastmem_bank.allocated) { - fastmem_bank.baseaddr = mapped_malloc (fastmem_bank.allocated, _T("fast")); - if (fastmem_bank.baseaddr == 0) { - write_log (_T("Out of memory for fastmem card.\n")); - fastmem_bank.allocated = 0; - } - } - memory_hardreset(1); - } - if (z3fastmem_bank.allocated != currprefs.z3fastmem_size) { - if (z3fastmem_bank.baseaddr) - mapped_free (z3fastmem_bank.baseaddr); - mapped_malloc_dynamic (&currprefs.z3fastmem_size, &changed_prefs.z3fastmem_size, &z3fastmem_bank, 1, _T("z3")); - memory_hardreset(1); - } + z3chipmem_bank.start = Z3BASE_UAE; + + if (currprefs.mbresmem_high_size >= 128 * 1024 * 1024) + z3chipmem_bank.start += (currprefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024; + + if (currprefs.z3chipmem_size && z3fastmem_bank[0].start - z3chipmem_bank.start < currprefs.z3chipmem_size) + currprefs.z3chipmem_size = changed_prefs.z3chipmem_size = 0; + + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + if (fastmem_bank[i].reserved_size != currprefs.fastmem[i].size) { + free_fastmemory(i); + + if (fastmem_bank[i].start == 0xffffffff) { + fastmem_bank[i].reserved_size = 0; + } + else { + fastmem_bank[i].reserved_size = currprefs.fastmem[i].size; + fastmem_bank[i].mask = fastmem_bank[i].reserved_size - 1; + if (currprefs.fastmem[i].manual_config) { + fastmem_bank[i].start = currprefs.fastmem[i].start_address; + } + if (fastmem_bank[i].reserved_size && fastmem_bank[i].start != 0xffffffff) { + mapped_malloc(&fastmem_bank[i]); + if (fastmem_bank[i].baseaddr == 0) { + write_log(_T("Out of memory for fastmem card.\n")); + } + } + } + memory_hardreset(1); + } + } + + if (z3fastmem_bank[0].reserved_size != currprefs.z3fastmem[0].size) { + mapped_free(&z3fastmem_bank[0]); + mapped_malloc_dynamic(&currprefs.z3fastmem[0].size, &changed_prefs.z3fastmem[0].size, &z3fastmem_bank[0], 1, _T("*")); + memory_hardreset(1); + } + for (int i = 1; i < MAX_RAM_BOARDS; i++) { + if (currprefs.z3fastmem[i].size && z3fastmem_bank[i].start == 0xffffffff) { + z3fastmem_bank[i].start = expansion_startaddress(&currprefs, z3fastmem_bank[i - 1].start, currprefs.z3fastmem[i - 1].size); + } + if (z3fastmem_bank[i].reserved_size != currprefs.z3fastmem[i].size) { + mapped_free(&z3fastmem_bank[i]); + + z3fastmem_bank[i].reserved_size = currprefs.z3fastmem[i].size; + z3fastmem_bank[i].mask = z3fastmem_bank[i].reserved_size - 1; + + if (z3fastmem_bank[i].reserved_size) { + mapped_malloc(&z3fastmem_bank[i]); + if (z3fastmem_bank[i].baseaddr == 0) { + write_log(_T("Out of memory for 32 bit fast memory #%d.\n"), i); + } + } + memory_hardreset(1); + } + } + if (z3chipmem_bank.reserved_size != currprefs.z3chipmem_size) { + mapped_free(&z3chipmem_bank); + mapped_malloc_dynamic(&currprefs.z3chipmem_size, &changed_prefs.z3chipmem_size, &z3chipmem_bank, 16, _T("*")); + memory_hardreset(1); + } #ifdef PICASSO96 - if (gfxmem_bank.allocated != currprefs.rtgmem_size) { - if (gfxmem_bank.baseaddr) - mapped_free (gfxmem_bank.baseaddr); - mapped_malloc_dynamic (&currprefs.rtgmem_size, &changed_prefs.rtgmem_size, &gfxmem_bank, 1, currprefs.rtgmem_type ? _T("z3_gfx") : _T("z2_gfx")); - memory_hardreset(1); - } + struct rtgboardconfig *rbc = &currprefs.rtgboards[0]; + if (gfxmem_banks[0]->reserved_size != rbc->rtgmem_size) { + mapped_free(gfxmem_banks[0]); + if (rbc->rtgmem_type < GFXBOARD_HARDWARE) + mapped_malloc_dynamic(&rbc->rtgmem_size, &changed_prefs.rtgboards[0].rtgmem_size, gfxmem_banks[0], 1, NULL); + memory_hardreset(1); + } #endif #ifdef SAVESTATE - if (savestate_state == STATE_RESTORE) { - if (fastmem_bank.allocated > 0) { - restore_ram (fast_filepos, fastmem_bank.baseaddr); - map_banks (&fastmem_bank, fastmem_bank.start >> 16, currprefs.fastmem_size >> 16, - fastmem_bank.allocated); - } - if (z3fastmem_bank.allocated > 0) { - restore_ram (z3_filepos, z3fastmem_bank.baseaddr); - map_banks (&z3fastmem_bank, z3fastmem_bank.start >> 16, currprefs.z3fastmem_size >> 16, - z3fastmem_bank.allocated); - } + if (savestate_state == STATE_RESTORE) { + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + if (fastmem_bank[i].allocated_size > 0) { + restore_ram(fast_filepos[i], fastmem_bank[i].baseaddr); + if (!fastmem_bank[i].start) { + // old statefile compatibility support + fastmem_bank[i].start = 0x00200000; + } + map_banks(&fastmem_bank[i], fastmem_bank[i].start >> 16, currprefs.fastmem[i].size >> 16, + fastmem_bank[i].allocated_size); + } + if (z3fastmem_bank[i].allocated_size > 0) { + restore_ram(z3_filepos[i], z3fastmem_bank[i].baseaddr); + map_banks(&z3fastmem_bank[i], z3fastmem_bank[i].start >> 16, currprefs.z3fastmem[i].size >> 16, + z3fastmem_bank[i].allocated_size); + } + } + if (z3chipmem_bank.allocated_size > 0) { + restore_ram(z3_fileposchip, z3chipmem_bank.baseaddr); + map_banks(&z3chipmem_bank, z3chipmem_bank.start >> 16, currprefs.z3chipmem_size >> 16, + z3chipmem_bank.allocated_size); + } #ifdef PICASSO96 - if (gfxmem_bank.allocated > 0 && gfxmem_bank.start > 0) { - restore_ram (p96_filepos, gfxmem_bank.baseaddr); - map_banks (&gfxmem_bank, gfxmem_bank.start >> 16, currprefs.rtgmem_size >> 16, - gfxmem_bank.allocated); - } + if (gfxmem_banks[0]->allocated_size > 0 && gfxmem_banks[0]->start > 0) { + restore_ram(p96_filepos, gfxmem_banks[0]->baseaddr); + map_banks(gfxmem_banks[0], gfxmem_banks[0]->start >> 16, currprefs.rtgboards[0].rtgmem_size >> 16, + gfxmem_banks[0]->allocated_size); + } #endif - } + } #endif /* SAVESTATE */ } -static uaecptr check_boot_rom (void) +static uaecptr check_boot_rom(struct uae_prefs *p, int *boot_rom_type) { - uaecptr b = RTAREA_DEFAULT; - addrbank *ab; + uaecptr b = RTAREA_DEFAULT; + addrbank *ab; - ab = &get_mem_bank (RTAREA_DEFAULT); - if (ab) { - if (valid_address (RTAREA_DEFAULT, 65536)) - b = RTAREA_BACKUP; - } - if (nr_directory_units (NULL)) - return b; - if (nr_directory_units (&currprefs)) - return b; - if (currprefs.socket_emu) + if (p->uaeboard > 1) { + *boot_rom_type = 2; + return uaeboard_bank.start ? uaeboard_bank.start + 0x10000 : 0x00eb0000; + } + *boot_rom_type = 0; + if (p->boot_rom == 1) + return 0; + *boot_rom_type = 1; + if (p->cs_cdtvcd || is_device_rom(p, ROMTYPE_CDTVSCSI, 0) >= 0 || p->uae_hide > 1) + b = RTAREA_BACKUP; + if (p->cs_mbdmac == 1 || p->cpuboard_type) + b = RTAREA_BACKUP; +#ifndef AMIBERRY + // CSPPC enables MMU at boot and remaps 0xea0000->0xeffff. + if (ISCPUBOARDP(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC)) + b = RTAREA_BACKUP_2; +#endif + ab = &get_mem_bank(RTAREA_DEFAULT); + if (ab) { + if (valid_address(RTAREA_DEFAULT, 65536)) + b = RTAREA_BACKUP; + } + if (nr_directory_units(NULL)) return b; - if (currprefs.input_tablet > 0) - return b; - if (currprefs.rtgmem_size) - return b; - if (currprefs.chipmem_size > 2 * 1024 * 1024) - return b; - return 0; + if (nr_directory_units(p)) + return b; + if (p->socket_emu) + return b; + if (p->uaeserial) + return b; + if (p->scsi == 1) + return b; + if (p->sana2) + return b; + if (p->input_tablet > 0) + return b; + if (p->rtgboards[0].rtgmem_size && p->rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE) + return b; +#ifndef AMIBERRY + if (p->win32_automount_removable) + return b; +#endif + if (p->chipmem_size > 2 * 1024 * 1024) + return b; + if (p->z3chipmem_size) + return b; + if (p->boot_rom >= 3) + return b; + if (p->boot_rom == 2 && b == 0xf00000) { + *boot_rom_type = -1; + return b; + } + *boot_rom_type = 0; + return 0; } -uaecptr need_uae_boot_rom (void) +uaecptr need_uae_boot_rom(struct uae_prefs *p) { - uaecptr v; + uaecptr v; - uae_boot_rom = 0; - v = check_boot_rom (); - if (v) - uae_boot_rom = 1; - if (!rtarea_base) { - uae_boot_rom = 0; - v = 0; - } - return v; + uae_boot_rom_type = 0; + v = check_boot_rom(p, &uae_boot_rom_type); + if (!rtarea_base) { + uae_boot_rom_type = 0; + v = 0; + } + return v; } -void expamem_reset (void) +static void add_cpu_expansions(struct uae_prefs *p, int zorro, int *fastmem_nump) { - int do_mount = 1; + int fastmem_num = MAX_RAM_BOARDS; + if (fastmem_nump) + fastmem_num = *fastmem_nump; - ecard = 0; - cardno = 0; - chipdone = false; + const struct cpuboardsubtype *cst = &cpuboards[p->cpuboard_type].subtypes[p->cpuboard_subtype]; + if (cst->init && cst->initzorro == zorro) { + int idx; + struct boardromconfig *brc = get_device_rom(p, ROMTYPE_CPUBOARD, 0, &idx); + if (brc) { + struct romconfig *rc = &brc->roms[idx]; + cards_set[cardno].flags = cst->initflag; + cards_set[cardno].name = cst->name; + cards_set[cardno].initrc = cst->init; + cards_set[cardno].rc = rc; + cards_set[cardno].zorro = zorro; + cards_set[cardno].cst = cst; + cards_set[cardno++].map = NULL; + if (cst->init2) { + cards_set[cardno].flags = cst->initflag | CARD_FLAG_CHILD; + cards_set[cardno].name = cst->name; + cards_set[cardno].initrc = cst->init2; + cards_set[cardno].zorro = zorro; + cards_set[cardno].cst = cst; + cards_set[cardno++].map = NULL; + } + if (fastmem_num < MAX_RAM_BOARDS && zorro == 2 && cst->memory_mid && p->fastmem[fastmem_num].size) { + cards_set[cardno].flags = (fastmem_num << 16) | CARD_FLAG_CHILD; + cards_set[cardno].name = _T("Z2Fast"); + cards_set[cardno].initnum = expamem_init_fastcard; + cards_set[cardno].zorro = zorro; + cards_set[cardno].cst = cst; + cards_set[cardno++].map = expamem_map_fastcard; + fastmem_num++; + } + } + } + if (fastmem_nump) + *fastmem_nump = fastmem_num; +} - uae_id = hackers_id; +static void add_expansions(struct uae_prefs *p, int zorro, int *fastmem_nump, int mode) +{ + int fastmem_num = MAX_RAM_BOARDS; + if (fastmem_nump) + fastmem_num = *fastmem_nump; + for (int i = 0; expansionroms[i].name; i++) { + const struct expansionromtype *ert = &expansionroms[i]; + if (ert->zorro == zorro) { + for (int j = 0; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) { + struct romconfig *rc = get_device_romconfig(p, ert->romtype, j); + if (rc) { + int mid = ert->memory_mid; + bool memory_after = ert->memory_after; + bool added = false; + if (ert->subtypes) { + const struct expansionsubromtype *srt = &ert->subtypes[rc->subtype]; + mid = srt->memory_mid; + memory_after = srt->memory_after; + } - allocate_expamem (); - expamem_bank.name = _T("Autoconfig [reset]"); + if (mode == 1 && ert->memory_mid) + continue; + if (mode == 2 && !ert->memory_mid) + continue; + if (fastmem_num < MAX_RAM_BOARDS && zorro == 2 && mid && !memory_after && p->fastmem[fastmem_num].size) { + cards_set[cardno].flags = (fastmem_num << 16); + cards_set[cardno].name = _T("Z2Fast"); + cards_set[cardno].initnum = expamem_init_fastcard; + cards_set[cardno].zorro = zorro; + cards_set[cardno].ert = ert; + cards_set[cardno++].map = expamem_map_fastcard; + fastmem_num++; + added = true; + } + if (fastmem_num < MAX_RAM_BOARDS && zorro == 3 && mid && !memory_after && p->z3fastmem[fastmem_num].size) { + cards_set[cardno].flags = CARD_FLAG_CAN_Z3 | (fastmem_num << 16); + cards_set[cardno].name = _T("Z3Fast"); + cards_set[cardno].initnum = expamem_init_z3fastmem; + cards_set[cardno].zorro = zorro; + cards_set[cardno].ert = ert; + cards_set[cardno++].map = expamem_map_z3fastmem; + fastmem_num++; + added = true; + } + cards_set[cardno].flags = added ? CARD_FLAG_CHILD : 0; + cards_set[cardno].name = ert->name; + cards_set[cardno].initrc = ert->init; + cards_set[cardno].rc = rc; + cards_set[cardno].zorro = zorro; + cards_set[cardno].ert = ert; + cards_set[cardno++].map = NULL; + if (ert->init2) { + cards_set[cardno].flags = CARD_FLAG_CHILD; + cards_set[cardno].name = ert->name; + cards_set[cardno].initrc = ert->init2; + cards_set[cardno].rc = rc; + cards_set[cardno].zorro = zorro; + cards_set[cardno++].map = NULL; + } + if (fastmem_num < MAX_RAM_BOARDS && zorro == 1 && mid && p->fastmem[fastmem_num].size) { + cards_set[cardno].flags = (fastmem_num << 16) | CARD_FLAG_CHILD; + cards_set[cardno].name = _T("Z1Fast"); + cards_set[cardno].initnum = expamem_init_fastcard_z1; + cards_set[cardno].zorro = zorro; + cards_set[cardno].ert = ert; + cards_set[cardno++].map = NULL; + fastmem_num++; + } + if (fastmem_num < MAX_RAM_BOARDS && zorro == 2 && mid && memory_after && p->fastmem[fastmem_num].size) { + cards_set[cardno].flags = (fastmem_num << 16) | CARD_FLAG_CHILD; + cards_set[cardno].name = _T("Z2Fast"); + cards_set[cardno].initnum = expamem_init_fastcard; + cards_set[cardno].zorro = zorro; + cards_set[cardno].ert = ert; + cards_set[cardno++].map = expamem_map_fastcard; + fastmem_num++; + } + if (fastmem_num < MAX_RAM_BOARDS && zorro == 3 && mid && memory_after && p->z3fastmem[fastmem_num].size) { + cards_set[cardno].flags = CARD_FLAG_CAN_Z3 | (fastmem_num << 16) | CARD_FLAG_CHILD; + cards_set[cardno].name = _T("Z3Fast"); + cards_set[cardno].initnum = expamem_init_z3fastmem; + cards_set[cardno].zorro = zorro; + cards_set[cardno].ert = ert; + cards_set[cardno++].map = expamem_map_z3fastmem; + fastmem_num++; + } + } + } + } + } + if (fastmem_nump) + *fastmem_nump = fastmem_num; +} - /* check if Kickstart version is below 1.3 */ - if (kickstart_version && do_mount - && (/* Kickstart 1.0 & 1.1! */ - kickstart_version == 0xFFFF - /* Kickstart < 1.3 */ - || kickstart_version < 34)) - { - /* warn user */ - write_log (_T("Kickstart version is below 1.3! Disabling automount devices.\n")); - do_mount = 0; - } - if (need_uae_boot_rom() == 0) - do_mount = 0; - if (fastmem_bank.baseaddr != NULL && currprefs.chipmem_size <= 2 * 1024 * 1024) { - fastmem_bank.name = _T("Fast memory"); - card_name[cardno] = _T("Z2Fast"); - card_init[cardno] = expamem_init_fastcard; - card_map[cardno++] = expamem_map_fastcard; - } +uae_u32 expansion_board_size(addrbank *ab) +{ + uae_u32 size = 0; + uae_u8 code = (ab->bget(0) & 0xf0) | ((ab->bget(2) & 0xf0) >> 4); + if ((code & 0xc0) == zorroII) { + // Z2 + code &= 7; + if (code == 0) + size = 8 * 1024 * 1024; + else + size = 32768 << code; + } + return size; +} + +static uae_u8 autoconfig_read(const uae_u8 *autoconfig, int offset) +{ + uae_u8 b = (autoconfig[offset] & 0xf0) | (autoconfig[offset + 2] >> 4); + if (offset == 0 || offset == 2 || offset == 0x40 || offset == 0x42) + return b; + b = ~b; + return b; +} + +static void expansion_parse_autoconfig(struct card_data *cd, const uae_u8 *autoconfig) +{ + uae_u8 code = autoconfig[0]; + uae_u32 expamem_z3_size; + + if ((code & 0xc0) == zorroII) { + int slotsize; + // Z2 + cd->zorro = 2; + code &= 7; + if (code == 0) + expamem_board_size = 8 * 1024 * 1024; + else + expamem_board_size = 32768 << code; + slotsize = expamem_board_size / 65536; + + expamem_board_pointer = 0xffffffff; + + for (int slottype = 0; slottype < 2; slottype++) + { + uae_u8 *slots = slots_e8; + int numslots = sizeof slots_e8; + uaecptr slotaddr = AUTOCONFIG_Z2; + if (slotsize >= 8 || slottype > 0) { + slots = slots_20; + numslots = sizeof slots_20; + slotaddr = AUTOCONFIG_Z2_MEM; + } + for (int i = 0; i < numslots; i++) { + if (((slotsize - 1) & i) == 0) { + bool free = true; + for (int j = 0; j < slotsize && j + i < numslots; j++) { + if (slots[i + j] != 0) { + free = false; + break; + } + } + if (free) { + for (int j = 0; j < slotsize; j++) { + slots[i + j] = 1; + } + expamem_board_pointer = slotaddr + i * 65536; + break; + } + } + } + if (expamem_board_pointer != 0xffffffff || slotsize >= 8) + break; + } + + } + else if ((code & 0xc0) == zorroIII) { + // Z3 + + cd->zorro = 3; + code &= 7; + if (autoconfig[2] & ext_size) + expamem_z3_size = (16 * 1024 * 1024) << code; + else + expamem_z3_size = 16 * 1024 * 1024; + + uaecptr newp = (expamem_z3_pointer_real + expamem_z3_size - 1) & ~(expamem_z3_size - 1); + if (newp < expamem_z3_pointer_real) + newp = 0xffffffff; + expamem_z3_pointer_real = newp; + + expamem_board_pointer = expamem_z3hack(cd->aci.prefs) ? expamem_z3_pointer_uae : expamem_z3_pointer_real; + expamem_board_size = expamem_z3_size; + + } + else if ((code & 0xc0) == 0x40) { + cd->zorro = 1; + // 0x40 = "Box without init/diagnostic code" + // proto autoconfig "box" size. + //expamem_z2_size = (1 << ((code >> 3) & 7)) * 4096; + // much easier this way, all old-style boards were made for + // A1000 and didn't have passthrough connector. + expamem_board_size = 65536; + expamem_board_pointer = 0xe90000; + } + +} + +static void reset_ac_data(struct uae_prefs *p) +{ + expamem_z3_pointer_real = Z3BASE_REAL; + expamem_z3_pointer_uae = Z3BASE_UAE; + expamem_z3_highram_real = 0; + expamem_z3_highram_uae = 0; + + expamem_highmem_pointer = 0; + if (p->mbresmem_low_size) + expamem_highmem_pointer = 0x08000000; + if (p->mbresmem_high_size) + expamem_highmem_pointer = 0x08000000 + p->mbresmem_high_size; + + if (p->mbresmem_high_size >= 128 * 1024 * 1024) + expamem_z3_pointer_uae += (p->mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024; + expamem_z3_pointer_uae += p->z3chipmem_size; + expamem_board_pointer = 0; + expamem_board_size = 0; + memset(slots_20, 0, sizeof slots_20); + memset(slots_e8, 0, sizeof slots_e8); + slots_e8[0] = 1; +} + +static void reset_ac(struct uae_prefs *p) +{ + do_mount = 1; + + if (need_uae_boot_rom(p) == 0) + do_mount = 0; + if (uae_boot_rom_type <= 0) + do_mount = 0; + + /* check if Kickstart version is below 1.3 */ + if (ks12orolder() && do_mount && p->uaeboard < 2) { + /* warn user */ +#if KS12_BOOT_HACK + do_mount = -1; +#else + write_log(_T("Kickstart version is below 1.3! Disabling automount devices.\n")); + do_mount = 0; +#endif + } + + if (p->uae_hide) + uae_id = commodore; + else + uae_id = hackers_id; + + for (int i = 0; i < MAX_EXPANSION_BOARD_SPACE; i++) { + memset(&cards_set[i], 0, sizeof(struct card_data)); + } + + ecard = 0; + cardno = 0; + + reset_ac_data(p); +} + +void expansion_generate_autoconfig_info(struct uae_prefs *p) +{ + expansion_scan_autoconfig(p, true); +} + +bool alloc_expansion_bank(addrbank *bank, struct autoconfig_info *aci) +{ + bank->start = aci->start; + bank->reserved_size = aci->size; + aci->Addrbank = bank; + return mapped_malloc(bank); +} + +void free_expansion_bank(addrbank *bank) +{ + mapped_free(bank); + bank->start = NULL; + bank->reserved_size = 0; +} + +struct autoconfig_info *expansion_get_autoconfig_data(struct uae_prefs *p, int index) +{ + if (index >= cardno) + return NULL; + struct card_data *cd = cards[index]; + return &cd->aci; +} + +struct autoconfig_info *expansion_get_autoconfig_by_address(struct uae_prefs *p, uaecptr addr) +{ + for (int i = 0; i < cardno; i++) { + struct card_data *cd = cards[i]; + if (addr >= cd->base && addr < cd->base + cd->size) + return &cd->aci; + } + return NULL; +} + +struct autoconfig_info *expansion_get_autoconfig_info(struct uae_prefs *p, int romtype, int devnum) +{ + for (int i = 0; i < cardno; i++) { + struct card_data *cd = cards[i]; + if (cd->rc) { + if (cd->rc->back->device_type == romtype && cd->rc->back->device_num == devnum) { + return &cd->aci; + } + } + else if (cd->cst) { + if ((romtype & ROMTYPE_CPUBOARD) && (cd->cst->romtype & ROMTYPE_CPUBOARD)) + return &cd->aci; + } + else { + // z2 and z3 ram boards are "fake" + if ((romtype == ROMTYPE_RAMZ2 && !_tcsicmp(cd->name, _T("Z2Fast"))) + || (romtype == ROMTYPE_RAMZ3 && !_tcsicmp(cd->name, _T("Z3Fast"))) + || (romtype == ROMTYPE_MEGACHIP && !_tcsicmp(cd->name, _T("MegaChipRAM")))) + { + if (((cd->flags >> 16) & 255) == devnum) + return &cd->aci; + } + } + } + return NULL; +} + +static void expansion_init_cards(struct uae_prefs *p) +{ + reset_ac_data(p); + + for (int i = 0; i < cardno; i++) { + bool ok; + struct card_data *cd = &cards_set[i]; + struct autoconfig_info *aci = &cd->aci; + memset(aci->autoconfig_raw, 0xff, sizeof aci->autoconfig_raw); + cd->base = 0; + cd->size = 0; + aci->devnum = (cd->flags >> 16) & 255; + aci->prefs = p; + aci->ert = cd->ert; + aci->cst = cd->cst; + aci->start = 0xffffffff; + aci->zorro = cd->zorro; + if (cd->initnum) { + ok = cd->initnum(aci); + } + else { + aci->rc = cd->rc; + ok = cd->initrc(aci); + } + if (cd->flags & CARD_FLAG_CHILD) + aci->parent_of_previous = true; + + if ((aci->zorro == 1 || aci->zorro == 2 || aci->zorro == 3) && aci->Addrbank != &expamem_null && aci->Addrbank != &expamem_none && (aci->autoconfig_raw[0] != 0xff || aci->autoconfigp)) { + uae_u8 ac2[16]; + const uae_u8 *a = aci->autoconfigp; + if (!a) { + for (int i = 0; i < 16; i++) { + ac2[i] = autoconfig_read(aci->autoconfig_raw, i * 4); + } + a = ac2; + } + expansion_parse_autoconfig(cd, a); + cd->size = expamem_board_size; + } + } +} + +static void set_order(struct uae_prefs *p, struct card_data *cd, int order) +{ + if (!cd) + return; + if (cd->aci.set_params) { + struct expansion_params parms = { 0 }; + parms.device_order = order; + if (cd->aci.set_params(p, &parms)) + return; + } + if (cd->zorro <= 0 || cd->zorro >= 4) + return; + if (cd->rc) { + cd->rc->back->device_order = order; + return; + } + int devnum = (cd->flags >> 16) & 255; + if (!_tcsicmp(cd->name, _T("Z2Fast"))) { + p->fastmem[devnum].device_order = order; + return; + } + if (!_tcsicmp(cd->name, _T("Z3Fast"))) { + p->z3fastmem[devnum].device_order = order; + return; + } + if (!_tcsicmp(cd->name, _T("Z3RTG")) || !_tcsicmp(cd->name, _T("Z2RTG"))) { + p->rtgboards[devnum].device_order = order; + return; + } + +} + +static int get_order(struct uae_prefs *p, struct card_data *cd) +{ + if (!cd) + return EXPANSION_ORDER_MAX - 1; + if (cd->cst) + return -4; // Accelerator must be always first + if (cd->aci.hardwired) + return -3; + if (cd->aci.get_params) { + struct expansion_params parms; + if (cd->aci.get_params(p, &parms)) + return parms.device_order; + } + if (cd->zorro <= 0) + return -1; + if (cd->zorro >= 4) + return -2; + if (cd->rc) + return cd->rc->back->device_order; + int devnum = (cd->flags >> 16) & 255; + if (!_tcsicmp(cd->name, _T("Z2Fast"))) + return p->fastmem[devnum].device_order; + if (!_tcsicmp(cd->name, _T("Z3Fast"))) + return p->z3fastmem[devnum].device_order; + if (!_tcsicmp(cd->name, _T("Z3RTG")) || !_tcsicmp(cd->name, _T("Z2RTG"))) + return p->rtgboards[devnum].device_order; + if (!_tcsicmp(cd->name, _T("MegaChipRAM"))) + return -1; + return EXPANSION_ORDER_MAX - 1; +} + +bool expansion_can_move(struct uae_prefs *p, int index) +{ + if (index < 0 || index >= cardno) + return false; + struct card_data *cd = cards[index]; + if (cd->aci.parent_of_previous) + return false; + int order1 = get_order(p, cd); + if (order1 < 0 || order1 >= EXPANSION_ORDER_MAX - 1) + return false; + return true; +} + +static void expansion_parse_cards(struct uae_prefs *p, bool log) +{ + if (log) + write_log(_T("Autoconfig board list:\n")); + reset_ac_data(p); + for (int i = 0; i < cardno; i++) { + bool ok; + struct card_data *cd = cards[i]; + struct autoconfig_info *aci = &cd->aci; + memset(aci->autoconfig_raw, 0xff, sizeof aci->autoconfig_raw); + memset(aci->autoconfig_bytes, 0xff, sizeof aci->autoconfig_bytes); + cd->base = 0; + cd->size = 0; + aci->devnum = (cd->flags >> 16) & 255; + aci->prefs = p; + aci->ert = cd->ert; + aci->cst = cd->cst; + aci->zorro = cd->zorro; + aci->start = 0xffffffff; + if (cd->initnum) { + ok = cd->initnum(aci); + } + else { + aci->rc = cd->rc; + ok = cd->initrc(aci); + } + if (aci->last_high_ram > expamem_highmem_pointer) { + expamem_highmem_pointer = aci->last_high_ram; + if (log) + write_log(_T("Non-Autoconfig highmem increased to %08x\n"), expamem_highmem_pointer); + } + if (log) + write_log(_T("Card %02d: "), i + 1); + if (ok) { + TCHAR label[MAX_DPATH]; + label[0] = 0; + if (aci->cst && !label[0]) { +#if 0 + const TCHAR *man = NULL; + for (int i = 0; cpuboards[i].name && man == NULL; i++) { + const struct cpuboardtype *cbt = &cpuboards[i]; + if (cbt->subtypes) { + for (int j = 0; cbt->subtypes[j].name && man == NULL; j++) { + if (&cbt->subtypes[j] == aci->cst) + man = cpuboards[i].name; + } + } + } + _stprintf(label, _T("%s (%s)"), aci->cst->name, man); +#endif + _tcscpy(label, aci->cst->name); + } + if (cd->rc && !label[0]) { + const struct expansionromtype *ert = get_device_expansion_rom(cd->rc->back->device_type); + if (ert) { + _tcscpy(label, ert->friendlyname); + } + } + if (!label[0]) { + if (aci->label) { + _tcscpy(label, aci->label); + } + else if (aci->Addrbank && aci->Addrbank->label) { + _tcscpy(label, aci->Addrbank->label); + } + else { + _tcscpy(label, _T("")); + } + } + if (aci->devnum > 0) { + TCHAR *s = label + _tcslen(label); + _stprintf(s, _T(" [%d]"), aci->devnum + 1); + } + + if ((aci->zorro == 1 || aci->zorro == 2 || aci->zorro == 3) && aci->Addrbank != &expamem_none && (aci->autoconfig_raw[0] != 0xff || aci->autoconfigp)) { + uae_u8 ac2[16]; + const uae_u8 *a = aci->autoconfigp; + if (!a) { + for (int i = 0; i < 16; i++) { + ac2[i] = autoconfig_read(aci->autoconfig_raw, i * 4); + } + a = ac2; + } + if (log) { + write_log(_T("'%s'\n"), label); + write_log(_T(" %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x\n"), + a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], + a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); + write_log(_T(" MID %u (%04x) PID %u (%02x) SER %08x\n"), + (a[4] << 8) | a[5], (a[4] << 8) | a[5], + a[1], a[1], + (a[6] << 24) | (a[7] << 16) | (a[8] << 8) | a[9]); + } + expansion_parse_autoconfig(cd, a); + uae_u32 size = expamem_board_size; + TCHAR sizemod = 'K'; + uae_u8 type = a[0]; + size /= 1024; + if (size > 8 * 1024) { + sizemod = 'M'; + size /= 1024; + } + bool z3 = (type & 0xc0) == zorroIII; + if (log) { + write_log(_T(" Z%d 0x%08x 0x%08x %4d%c %s %d\n"), + (type & 0xc0) == zorroII ? 2 : (z3 ? 3 : 1), + z3 && !currprefs.z3autoconfig_start ? expamem_z3_pointer_real : expamem_board_pointer, + z3 && !currprefs.z3autoconfig_start ? expamem_z3_pointer_uae : expamem_board_pointer, + size, sizemod, + type & rom_card ? _T("ROM") : (type & add_memory ? _T("RAM") : _T("IO ")), get_order(p, cd)); + } + cd->base = expamem_board_pointer; + cd->size = expamem_board_size; + if ((type & 0xc0) == zorroIII) { + aci->start = expamem_z3hack(p) ? expamem_z3_pointer_uae : expamem_z3_pointer_real; + } + else { + aci->start = expamem_board_pointer; + } + aci->size = cd->size; + memcpy(aci->autoconfig_bytes, a, sizeof aci->autoconfig_bytes); + if (aci->Addrbank) { + aci->Addrbank->start = expamem_board_pointer; + if (aci->Addrbank->reserved_size == 0 && !(type & add_memory) && expamem_board_size < 524288) { + aci->Addrbank->reserved_size = expamem_board_size; + } + } + aci->zorro = cd->zorro; + if (cd->zorro == 3) { + if (expamem_z3_pointer_real + expamem_board_size < expamem_z3_pointer_real) { + expamem_z3_pointer_real = 0xffffffff; + expamem_z3_highram_real = 0xffffffff; + } + else { + expamem_z3_pointer_real += expamem_board_size; + } + if (expamem_z3_pointer_uae + expamem_board_size < expamem_z3_pointer_uae) { + expamem_z3_pointer_uae = 0xffffffff; + expamem_z3_highram_uae = 0xffffffff; + } + else { + expamem_z3_pointer_uae += expamem_board_size; + } + if (expamem_board_pointer + expamem_board_size < expamem_board_pointer) { + expamem_board_pointer = 0xffffffff; + } + else { + expamem_board_pointer += expamem_board_size; + } + if ((type & add_memory) || aci->direct_vram) { + if (expamem_z3_pointer_uae != 0xffffffff && expamem_z3_pointer_uae > expamem_z3_highram_uae) + expamem_z3_highram_uae = expamem_z3_pointer_uae; + if (expamem_z3_pointer_real != 0xffffffff && expamem_z3_pointer_real > expamem_z3_highram_real) + expamem_z3_highram_real = expamem_z3_pointer_real; + } + + } + } + else { + cd->base = aci->start; + cd->size = aci->size; + if (log) + write_log(_T("'%s' no autoconfig %08x - %08x.\n"), aci->label ? aci->label : _T(""), cd->base, cd->base + cd->size - 1); + } + _tcscpy(aci->name, label); + if (cd->flags & CARD_FLAG_CHILD) + aci->parent_of_previous = true; + } + else { + if (log) + write_log(_T("init failed.\n"), i); + } + } + if (log) + write_log(_T("END\n")); +} + +int expansion_autoconfig_move(struct uae_prefs *p, int index, int dir, bool test) +{ + if (index < 0 || index >= cardno) + return -1; + if (!dir) + return -1; + struct card_data *cd1 = cards[index]; + int order1 = get_order(p, cd1); + if (order1 < 0 || order1 >= EXPANSION_ORDER_MAX - 1) + return -1; + struct card_data *cd2; + int order2; + for (;;) { + if (index + dir < 0 || index + dir >= cardno) + return -1; + cd2 = cards[index + dir]; + if (cd1->aci.parent_of_previous && !cd2->aci.parent_of_previous) + return -1; + order2 = get_order(p, cd2); + if (order2 >= 0 && order2 < EXPANSION_ORDER_MAX - 1) { + if (!cd1->aci.parent_of_previous && !cd2->aci.parent_of_previous) + break; + } + dir += dir < 0 ? -1 : 1; + } + if (test) { + return 0; + } + set_order(p, cd1, order2); + set_order(p, cd2, order1); + if (p != &currprefs) + expansion_scan_autoconfig(p, false); + for (int i = 0; i < cardno; i++) { + if (cards[i] == cd1) + return i; + } + return -1; +} + +static void expansion_recalc_order(struct uae_prefs *p) +{ + int ordermin = 1; + for (;;) { + int order = EXPANSION_ORDER_MAX; + int idx = -1; + for (int i = 0; i < cardno; i++) { + struct card_data *cdc = cards[i]; + int o = get_order(p, cdc); + if (o >= ordermin && order > o) { + order = o; + idx = i; + } + } + if (idx < 0) + break; + set_order(p, cards[idx], ordermin); + ordermin++; + } +} + +void expansion_set_autoconfig_sort(struct uae_prefs *p) +{ + for (int i = 0; i < cardno; i++) { + set_order(p, cards[i], i + 1); + } + expansion_recalc_order(p); +} + +static bool ischild(struct card_data *cd) +{ + if (cd->aci.parent_name) + return true; + if (cd->aci.parent_address_space) + return true; + if (cd->aci.parent_of_previous) + return true; + if (cd->aci.parent_romtype) + return true; + return false; +} + +static void check_card_child(int index, bool *inuse, int *new_cardnop) +{ + struct card_data *cd = &cards_set[index]; + int new_cardno = *new_cardnop; + // address space "conflict" parent? + for (int i = 0; i < cardno; i++) { + struct card_data *cdc = &cards_set[i]; + if (inuse[i]) + continue; + if (!cdc->aci.parent_address_space) + continue; + if (cd->aci.start && cd->aci.size && cdc->aci.start >= cd->aci.start && cdc->aci.start < cd->aci.start + cd->aci.size) { + cards[new_cardno++] = cdc; + cdc->aci.parent_of_previous = true; + inuse[i] = true; + } + } + // romtype parent? + for (int i = 0; i < cardno; i++) { + struct card_data *cdc = &cards_set[i]; + if (inuse[i]) + continue; + const int *parent = cdc->aci.parent_romtype; + if (!parent) + continue; + for (int j = 0; parent[j]; j++) { + if (cd->rc && parent[j] == (cd->rc->back->device_type & ROMTYPE_MASK)) { + cards[new_cardno++] = cdc; + cdc->aci.parent_of_previous = true; + inuse[i] = true; + } + } + } + // named parent + for (int i = 0; i < cardno; i++) { + struct card_data *cdc = &cards_set[i]; + if (inuse[i]) + continue; + if (cdc->aci.parent_name && cd->name && !_tcsicmp(cdc->aci.parent_name, cd->name)) { + cards[new_cardno++] = cdc; + cdc->aci.parent_of_previous = true; + inuse[i] = true; + } + } + *new_cardnop = new_cardno; +} + +static bool add_card_sort(int index, bool *inuse, int *new_cardnop) +{ + struct card_data *cd = &cards_set[index]; + if (ischild(cd)) + return false; + int new_cardno = *new_cardnop; + cards[new_cardno++] = cd; + inuse[index] = true; + int index2 = index + 1; + // any children? + while (index2 < cardno) { + struct card_data *cdc = &cards_set[index2]; + struct autoconfig_info *aci = &cdc->aci; + if (inuse[index2]) + break; + if (!ischild(cdc)) + break; + if (aci->parent_of_previous) { + cards[new_cardno++] = cdc; + inuse[index2] = true; + check_card_child(index2, inuse, &new_cardno); + } + index2++; + } + check_card_child(index, inuse, &new_cardno); + *new_cardnop = new_cardno; + return true; +} + +static void expansion_autoconfig_sort(struct uae_prefs *p) +{ + const int zs[] = { BOARD_NONAUTOCONFIG_BEFORE, 0, BOARD_PROTOAUTOCONFIG, BOARD_AUTOCONFIG_Z2, BOARD_NONAUTOCONFIG_AFTER_Z2, BOARD_AUTOCONFIG_Z3, BOARD_NONAUTOCONFIG_AFTER_Z3, -1 }; + bool inuse[MAX_EXPANSION_BOARD_SPACE]; + struct card_data *tcards[MAX_EXPANSION_BOARD_SPACE]; + int new_cardno = 0; + + // default sort first, sets correct parent/child order + for (int i = 0; i < cardno; i++) { + inuse[i] = false; + cards[i] = NULL; + } + cards[cardno] = NULL; + for (int type = 0; zs[type] >= 0; type++) { + bool changed = true; + int z = zs[type]; + bool inuse2[MAX_EXPANSION_BOARD_SPACE]; + memset(inuse2, 0, sizeof inuse2); + while (changed) { + changed = false; + // unmovables first + int testorder = 0; + int idx = -1; + for (int i = 0; i < cardno; i++) { + if (inuse[i]) + continue; + if (inuse2[i]) + continue; + struct card_data *cd = &cards_set[i]; + if (ischild(cd)) + continue; + if (cd->zorro != z) + continue; + int order = get_order(p, cd); + if (cd->aci.hardwired) + order = -1; + if (order >= 0) + continue; + if (testorder > order) { + testorder = order; + idx = i; + } + } + if (idx >= 0) { + inuse2[idx] = true; + add_card_sort(idx, inuse, &new_cardno); + changed = true; + } + } + changed = true; + memset(inuse2, 0, sizeof inuse2); + while (changed) { + changed = false; + for (int i = 0; i < cardno; i++) { + if (inuse[i]) + continue; + if (inuse2[i]) + continue; + struct card_data *cd = &cards_set[i]; + if (ischild(cd)) + continue; + if (cd->zorro != z) + continue; + if (get_order(p, cd) < EXPANSION_ORDER_MAX - 1) + continue; + inuse2[i] = true; + add_card_sort(i, inuse, &new_cardno); + changed = true; + } + } + changed = true; + memset(inuse2, 0, sizeof inuse2); + while (changed) { + // the rest + changed = false; + for (int i = 0; i < cardno; i++) { + if (inuse[i]) + continue; + if (inuse2[i]) + continue; + struct card_data *cd = &cards_set[i]; + if (ischild(cd)) + continue; + if (cd->zorro != z) + continue; + inuse2[i] = true; + add_card_sort(i, inuse, &new_cardno); + changed = true; + } + } + } + for (int i = 0; i < cardno; i++) { + if (inuse[i]) + continue; + cards[new_cardno++] = &cards_set[i]; + } + for (int i = 0; i < cardno; i++) { + struct autoconfig_info *aci = &cards[i]->aci; + tcards[i] = cards[i]; + tcards[i]->aci.can_sort = !aci->hardwired && !aci->parent_of_previous && get_order(p, cards[i]) < EXPANSION_ORDER_MAX - 1 && get_order(p, cards[i]) >= 0; + } + + if (!p->autoconfig_custom_sort) { + + new_cardno = 0; + + // accelerator and hardwired first + for (int idx = 0; idx < cardno; idx++) { + struct card_data *cd = tcards[idx]; + if (!cd) + continue; + if (cd->cst || cd->aci.hardwired) { + cards[new_cardno++] = cd; + tcards[idx] = NULL; + for (int j = idx + 1; j < cardno; j++) { + struct card_data *cdc = tcards[j]; + if (!cdc || !ischild(cdc)) + break; + cards[new_cardno++] = cdc; + tcards[j] = NULL; + } + } + } + // re-sort by board size + for (int idx = 0; idx < cardno; idx++) { + struct card_data *cd = tcards[idx]; + if (!cd) + continue; + int z = cd->zorro; + if ((z != 2 && z != 3 && !ischild(cd)) || cd->cst) { + cards[new_cardno++] = cd; + tcards[idx] = NULL; + for (int j = idx + 1; j < cardno; j++) { + struct card_data *cdc = tcards[j]; + if (!cdc || !ischild(cdc)) + break; + cards[new_cardno++] = cdc; + tcards[j] = NULL; + } + } + } + for (int z = 2; z <= 3; z++) { + for (;;) { + int idx2 = -1; + uae_u32 size = 0; + for (int j = 0; j < cardno; j++) { + struct card_data *cdc = tcards[j]; + if (cdc && cdc->size > size && cdc->zorro == z && !ischild(cdc)) { + size = cdc->size; + idx2 = j; + } + } + if (idx2 < 0) + break; + cards[new_cardno++] = tcards[idx2]; + tcards[idx2] = NULL; + for (int j = idx2 + 1; j < cardno; j++) { + struct card_data *cdc = tcards[j]; + if (!cdc || !ischild(cdc)) + break; + cards[new_cardno++] = cdc; + tcards[j] = NULL; + } + } + } + + } + else { + + // re-sort by configuration data + new_cardno = 0; + for (;;) { + int order = EXPANSION_ORDER_MAX; + int idx = -1; + for (int i = 0; i < cardno; i++) { + struct card_data *cd = tcards[i]; + if (cd && get_order(p, cd) < order && !cd->aci.parent_of_previous) { + order = get_order(p, cd); + idx = i; + } + } + if (idx >= 0) { + struct card_data *cd = tcards[idx]; + struct autoconfig_info *aci = &cd->aci; + cards[new_cardno++] = cd; + tcards[idx] = NULL; + // sort children, if any + int child = 0; + for (int j = idx + 1; j < cardno; j++) { + struct card_data *cdc = tcards[j]; + if (!cdc || !cdc->aci.parent_of_previous) + break; + child++; + } + for (;;) { + order = EXPANSION_ORDER_MAX; + int cidx = -1; + for (int j = 0; j < child; j++) { + struct card_data *cdc = tcards[j + idx + 1]; + if (cdc && get_order(p, cdc) < order) { + order = get_order(p, cdc); + cidx = j; + } + } + if (cidx < 0) + break; + cards[new_cardno++] = tcards[idx + 1 + cidx]; + tcards[idx + 1 + cidx] = NULL; + } + for (int j = 0; j < child; j++) { + if (tcards[idx + 1 + j]) { + cards[new_cardno++] = tcards[idx + 1 + j]; + } + } + } + if (idx < 0) + break; + } + } + + for (int i = 0; i < cardno; i++) { + if (tcards[i]) { + cards[new_cardno++] = tcards[i]; + } + } + +} + +static void expansion_add_autoconfig(struct uae_prefs *p) +{ + int fastmem_num; + + reset_ac(p); + + if (p->cpuboard_type) { + // This may require first 128k slot. + cards_set[cardno].flags = 1; + cards_set[cardno].name = _T("CPUBoard"); +#ifndef AMIBERRY + cards_set[cardno].initrc = cpuboard_autoconfig_init; +#endif + cards_set[cardno].zorro = BOARD_NONAUTOCONFIG_BEFORE; + cards_set[cardno].cst = &cpuboards[p->cpuboard_type].subtypes[p->cpuboard_subtype];; + cards_set[cardno++].map = NULL; + } + + if (p->z3chipmem_size) { + cards_set[cardno].flags = 0; + cards_set[cardno].name = _T("MegaChipRAM"); + cards_set[cardno].initrc = megachipram_init; + cards_set[cardno].zorro = BOARD_NONAUTOCONFIG_BEFORE; + cards_set[cardno++].map = NULL; + } + + // add possible non-autoconfig boards + add_cpu_expansions(p, BOARD_NONAUTOCONFIG_BEFORE, NULL); + add_expansions(p, BOARD_NONAUTOCONFIG_BEFORE, NULL, 0); + + fastmem_num = 0; + add_expansions(p, BOARD_PROTOAUTOCONFIG, &fastmem_num, 0); + add_cpu_expansions(p, BOARD_AUTOCONFIG_Z2, &fastmem_num); + // immediately after Z2Fast so that it can be emulated as A590/A2091 with fast ram. + add_expansions(p, BOARD_AUTOCONFIG_Z2, &fastmem_num, 0); + + add_cpu_expansions(p, BOARD_NONAUTOCONFIG_AFTER_Z2, NULL); + add_expansions(p, BOARD_NONAUTOCONFIG_AFTER_Z2, NULL, 0); + + while (fastmem_num < MAX_RAM_BOARDS) { + if (p->fastmem[fastmem_num].size) { + cards_set[cardno].flags = fastmem_num << 16; + cards_set[cardno].name = _T("Z2Fast"); + cards_set[cardno].zorro = 2; + cards_set[cardno].initnum = expamem_init_fastcard; + cards_set[cardno++].map = expamem_map_fastcard; + } + fastmem_num++; + } #ifdef FILESYS - if (do_mount) { - card_name[cardno] = _T("UAEFS"); - card_init[cardno] = expamem_init_filesys; - card_map[cardno++] = expamem_map_filesys; - } + if (do_mount && p->uaeboard >= 0 && p->uaeboard < 2) { + cards_set[cardno].flags = 0; + cards_set[cardno].name = _T("UAEFS"); + cards_set[cardno].zorro = 2; + cards_set[cardno].initnum = expamem_init_filesys; + cards_set[cardno++].map = expamem_map_filesys; + } + if (p->uaeboard > 0) { + cards_set[cardno].flags = 0; + cards_set[cardno].name = _T("UAEBOARD"); + cards_set[cardno].zorro = 2; + cards_set[cardno].initnum = expamem_init_uaeboard; + cards_set[cardno++].map = expamem_map_uaeboard; + } + if (do_mount && p->uaeboard < 2) { + cards_set[cardno].flags = 0; + cards_set[cardno].name = _T("UAEBOOTROM"); + cards_set[cardno].zorro = BOARD_NONAUTOCONFIG_BEFORE; + cards_set[cardno].initnum = expamem_rtarea_init; + cards_set[cardno++].map = NULL; + + } #endif #ifdef PICASSO96 - if (currprefs.rtgmem_type == GFXBOARD_UAE_Z2 && gfxmem_bank.baseaddr != NULL) { - card_name[cardno] = _T("Z2RTG"); - card_init[cardno] = expamem_init_gfxcard_z2; - card_map[cardno++] = expamem_map_gfxcard; + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + struct rtgboardconfig *rbc = &p->rtgboards[i]; + if (rbc->rtgmem_size && rbc->rtgmem_type == GFXBOARD_UAE_Z2) { + cards_set[cardno].flags = 4 | (i << 16); + cards_set[cardno].zorro = 2; + cards_set[cardno].name = _T("Z2RTG"); + cards_set[cardno].initnum = expamem_init_gfxcard_z2; + cards_set[cardno++].map = expamem_map_gfxcard_z2; + } + } +#endif +#ifdef GFXBOARD + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + struct rtgboardconfig *rbc = &p->rtgboards[i]; + if (rbc->rtgmem_size && rbc->rtgmem_type >= GFXBOARD_HARDWARE && gfxboard_get_configtype(rbc) <= 2) { + cards_set[cardno].flags = 4 | (i << 16); + if (gfxboard_get_func(rbc)) { + cards_set[cardno].name = _T("Z2RTG"); + cards_set[cardno].zorro = 2; + cards_set[cardno].flags = (i << 16); + cards_set[cardno++].initnum = gfxboard_init_board; + } + else { + cards_set[cardno].name = _T("Z2RTG"); + cards_set[cardno].zorro = 2; + cards_set[cardno++].initnum = gfxboard_init_memory; + if (gfxboard_num_boards(rbc) == 3) { + cards_set[cardno].flags = (i << 16) | CARD_FLAG_CHILD; + cards_set[cardno].name = _T("Gfxboard VRAM Zorro II Extra"); + cards_set[cardno].zorro = 2; + cards_set[cardno++].initnum = gfxboard_init_memory_p4_z2; + } + if (gfxboard_is_registers(rbc)) { + cards_set[cardno].flags = (i << 16) | CARD_FLAG_CHILD; + cards_set[cardno].name = _T("Gfxboard Registers"); + cards_set[cardno].zorro = 2; + cards_set[cardno++].initnum = gfxboard_init_registers; + } + } + } + } +#endif +#ifndef AMIBERRY + if (p->monitoremu == MONITOREMU_FIRECRACKER24) { + cards_set[cardno].flags = 0; + cards_set[cardno].name = _T("FireCracker24"); + cards_set[cardno].zorro = 2; + cards_set[cardno++].initnum = specialmonitor_autoconfig_init; } #endif /* Z3 boards last */ - if (z3fastmem_bank.baseaddr != NULL) { - card_name[cardno] = _T("Z3Fast"); - card_init[cardno] = expamem_init_z3fastmem; - card_map[cardno++] = expamem_map_z3fastmem; - map_banks (&z3fastmem_bank, z3fastmem_bank.start >> 16, currprefs.z3fastmem_size >> 16, z3fastmem_bank.allocated); + fastmem_num = 0; + + add_cpu_expansions(p, BOARD_AUTOCONFIG_Z3, &fastmem_num); + + // add combo Z3 boards (something + Z3 RAM) + add_expansions(p, BOARD_AUTOCONFIG_Z3, &fastmem_num, 2); + + // add remaining RAM boards + for (int i = fastmem_num; i < MAX_RAM_BOARDS; i++) { + if (p->z3fastmem[i].size) { + z3num = 0; + cards_set[cardno].flags = (2 | CARD_FLAG_CAN_Z3) | (i << 16); + cards_set[cardno].name = _T("Z3Fast"); + cards_set[cardno].zorro = 3; + cards_set[cardno].initnum = expamem_init_z3fastmem; + cards_set[cardno++].map = expamem_map_z3fastmem; + } } #ifdef PICASSO96 - if (currprefs.rtgmem_type == GFXBOARD_UAE_Z3 && gfxmem_bank.baseaddr != NULL) { - card_name[cardno] = _T("Z3RTG"); - card_init[cardno] = expamem_init_gfxcard_z3; - card_map[cardno++] = expamem_map_gfxcard; + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + if (p->rtgboards[i].rtgmem_size && p->rtgboards[i].rtgmem_type == GFXBOARD_UAE_Z3) { + cards_set[cardno].flags = 4 | CARD_FLAG_CAN_Z3 | (i << 16); + cards_set[cardno].name = _T("Z3RTG"); + cards_set[cardno].zorro = 3; + cards_set[cardno].initnum = expamem_init_gfxcard_z3; + cards_set[cardno++].map = expamem_map_gfxcard_z3; + } + } +#endif +#ifdef GFXBOARD + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + struct rtgboardconfig *rbc = &p->rtgboards[i]; + if (rbc->rtgmem_size && rbc->rtgmem_type >= GFXBOARD_HARDWARE && gfxboard_get_configtype(rbc) == 3) { + cards_set[cardno].flags = 4 | CARD_FLAG_CAN_Z3 | (i << 16); + cards_set[cardno].name = _T("Z3RTG"); + cards_set[cardno].zorro = 3; + cards_set[cardno++].initnum = gfxboard_init_memory; + if (gfxboard_is_registers(rbc)) { + cards_set[cardno].flags = 1 | (i << 16) | CARD_FLAG_CHILD; + cards_set[cardno].zorro = 3; + cards_set[cardno].name = _T("Gfxboard Registers"); + cards_set[cardno++].initnum = gfxboard_init_registers; + } + } } #endif - if (cardno > 0 && cardno < MAX_EXPANSION_BOARDS) { - card_name[cardno] = _T("Empty"); - card_init[cardno] = expamem_init_last; - card_map[cardno++] = expamem_map_clear; - } + // add non-memory Z3 boards + add_expansions(p, BOARD_AUTOCONFIG_Z3, NULL, 1); + + add_cpu_expansions(p, BOARD_NONAUTOCONFIG_AFTER_Z3, NULL); + add_expansions(p, BOARD_NONAUTOCONFIG_AFTER_Z3, NULL, 0); - if (cardno == 0 || savestate_state) - expamem_init_clear_zero (); - else - (*card_init[0]) (); } -void expansion_init (void) +void expansion_scan_autoconfig(struct uae_prefs *p, bool log) +{ + cfgfile_compatibility_romtype(p); + expansion_add_autoconfig(p); + expansion_init_cards(p); + expansion_autoconfig_sort(p); + expansion_parse_cards(p, log); +} + +void expamem_reset(void) +{ + reset_ac(&currprefs); + + chipdone = false; + + allocate_expamem(); + expamem_bank.name = _T("Autoconfig [reset]"); + + expansion_add_autoconfig(&currprefs); + expansion_init_cards(&currprefs); + expansion_autoconfig_sort(&currprefs); + expansion_parse_cards(&currprefs, true); + + if (cardno == 0 || savestate_state) + expamem_init_clear_zero(); + else + call_card_init(0); +} + +void expansion_init(void) { if (savestate_state != STATE_RESTORE) { - fastmem_bank.allocated = 0; - fastmem_bank.mask = fastmem_bank.start = 0; - fastmem_bank.baseaddr = NULL; + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + fastmem_bank[i].reserved_size = 0; + fastmem_bank[i].mask = 0; + fastmem_bank[i].baseaddr = NULL; + } #ifdef PICASSO96 - gfxmem_bank.allocated = 0; - gfxmem_bank.mask = gfxmem_bank.start = 0; - gfxmem_bank.baseaddr = NULL; + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + gfxmem_banks[i]->reserved_size = 0; + gfxmem_banks[i]->mask = 0; + gfxmem_banks[i]->baseaddr = NULL; + } #endif - z3fastmem_bank.allocated = 0; - z3fastmem_bank.mask = z3fastmem_bank.start = 0; - z3fastmem_bank.baseaddr = NULL; - } - -#ifdef FILESYS - filesys_start = 0; - filesysory = 0; +#ifdef CATWEASEL + catweasel_mask = catweasel_start = 0; #endif - expamem_lo = 0; - expamem_hi = 0; - - allocate_expamem (); + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + z3fastmem_bank[i].reserved_size = 0; + z3fastmem_bank[i].mask = 0; + z3fastmem_bank[i].baseaddr = NULL; + } + + z3chipmem_bank.reserved_size = 0; + z3chipmem_bank.mask = z3chipmem_bank.start = 0; + z3chipmem_bank.baseaddr = NULL; + } + + allocate_expamem(); + + if (currprefs.uaeboard) { + uaeboard_bank.reserved_size = 0x10000; + mapped_malloc(&uaeboard_bank); + } + +} + +void expansion_cleanup(void) +{ + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + mapped_free(&fastmem_bank[i]); + mapped_free(&z3fastmem_bank[i]); + } + mapped_free(&z3chipmem_bank); + +#ifdef PICASSO96 + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + if (currprefs.rtgboards[i].rtgmem_type < GFXBOARD_HARDWARE) { + mapped_free(gfxmem_banks[i]); + } + } +#endif #ifdef FILESYS - filesysory = (uae_u8 *) malloc (0x10000); //mapped_malloc (0x10000, _T("filesys")); - if (!filesysory) { - write_log (_T("virtual memory exhausted (filesysory)!\n")); - abort(); - } - filesys_bank.baseaddr = filesysory; + mapped_free(&filesys_bank); +#endif + if (currprefs.uaeboard) { + mapped_free(&uaeboard_bank); + } + +#ifdef CATWEASEL + catweasel_free(); #endif } -void expansion_cleanup (void) +void expansion_map(void) { - mapped_free (fastmem_bank.baseaddr); - fastmem_bank.baseaddr = NULL; - mapped_free (z3fastmem_bank.baseaddr); - z3fastmem_bank.baseaddr = NULL; - -#ifdef PICASSO96 - mapped_free (gfxmem_bank.baseaddr); - gfxmem_bank.baseaddr = NULL; -#endif - -#ifdef FILESYS - if (filesysory) - free (filesysory); // mapped_free (filesysory); - filesysory = NULL; -#endif + map_banks(&expamem_bank, 0xE8, 1, 0); + // map non-autoconfig ram boards + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + struct ramboard *rb = &currprefs.fastmem[i]; + if (rb->manual_config) { + map_banks(&fastmem_bank[i], rb->start_address >> 16, (rb->end_address - rb->start_address + 1) >> 16, 0); + } + else if (rb->no_reset_unmap && rb->start_address) { + map_banks(&fastmem_bank[i], rb->start_address >> 16, rb->size >> 16, 0); + } + rb = &currprefs.z3fastmem[i]; + if (rb->manual_config) { + map_banks(&z3fastmem_bank[i], rb->start_address >> 16, (rb->end_address - rb->start_address + 1) >> 16, 0); + } + else if (rb->no_reset_unmap && rb->start_address) { + map_banks(&z3fastmem_bank[i], rb->start_address >> 16, rb->size >> 16, 0); + } + } + if (currprefs.z3chipmem_size) { + map_banks_z3(&z3chipmem_bank, z3chipmem_bank.start >> 16, currprefs.z3chipmem_size >> 16); + } + if (do_mount < 0 && ks11orolder()) { + filesys_bank.start = 0xe90000; + mapped_free(&filesys_bank); + mapped_malloc(&filesys_bank); + map_banks_z2(&filesys_bank, filesys_bank.start >> 16, 1); + expamem_init_filesys(0); + expamem_map_filesys_update(); + } } -static void clear_bank (addrbank *ab) +static void clear_bank(addrbank *ab) { - if (!ab->baseaddr || !ab->allocated) + if (!ab->baseaddr || !ab->allocated_size) return; - memset (ab->baseaddr, 0, ab->allocated > 0x800000 ? 0x800000 : ab->allocated); + memset(ab->baseaddr, 0, ab->allocated_size > 0x800000 ? 0x800000 : ab->allocated_size); } void expansion_clear(void) { - clear_bank (&fastmem_bank); - clear_bank (&z3fastmem_bank); -#ifdef PICASSO96 - clear_bank (&gfxmem_bank); -#endif + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + clear_bank(&fastmem_bank[i]); + clear_bank(&z3fastmem_bank[i]); + } + clear_bank(&z3chipmem_bank); + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + clear_bank(gfxmem_banks[i]); + } } #ifdef SAVESTATE /* State save/restore code. */ -uae_u8 *save_fram (int *len) +uae_u8 *save_fram(int *len, int num) { - *len = fastmem_bank.allocated; - return fastmem_bank.baseaddr; + *len = fastmem_bank[num].allocated_size; + return fastmem_bank[num].baseaddr; } -uae_u8 *save_zram (int *len, int num) +uae_u8 *save_zram(int *len, int num) { - *len = z3fastmem_bank.allocated; - return z3fastmem_bank.baseaddr; + if (num < 0) { + *len = z3chipmem_bank.allocated_size; + return z3chipmem_bank.baseaddr; + } + *len = z3fastmem_bank[num].allocated_size; + return z3fastmem_bank[num].baseaddr; } -#ifdef PICASSO96 -uae_u8 *save_pram (int *len) +uae_u8 *save_pram(int *len) { - *len = gfxmem_bank.allocated; - return gfxmem_bank.baseaddr; -} -#endif - -void restore_fram (int len, size_t filepos) -{ - fast_filepos = filepos; - changed_prefs.fastmem_size = len; + *len = gfxmem_banks[0]->allocated_size; + return gfxmem_banks[0]->baseaddr; } -void restore_zram (int len, size_t filepos, int num) +void restore_fram(int len, size_t filepos, int num) { - z3_filepos = filepos; - changed_prefs.z3fastmem_size = len; + fast_filepos[num] = filepos; + changed_prefs.fastmem[num].size = len; } -void restore_pram (int len, size_t filepos) +void restore_zram(int len, size_t filepos, int num) { - p96_filepos = filepos; - changed_prefs.rtgmem_size = len; + if (num == -1) { + z3_fileposchip = filepos; + changed_prefs.z3chipmem_size = len; + } + else { + z3_filepos[num] = filepos; + changed_prefs.z3fastmem[num].size = len; + } } -uae_u8 *save_expansion (int *len, uae_u8 *dstptr) +void restore_pram(int len, size_t filepos) { - uae_u8 *dstbak, *dst; - if (dstptr) - dst = dstbak = dstptr; - else - dstbak = dst = (uae_u8 *)malloc (20); - save_u32 (fastmem_bank.start); - save_u32 (z3fastmem_bank.start); -#ifdef PICASSO96 - save_u32 (gfxmem_bank.start); -#endif - save_u32 (rtarea_base); - *len = dst - dstbak; - return dstbak; + p96_filepos = filepos; + changed_prefs.rtgboards[0].rtgmem_size = len; } -uae_u8 *restore_expansion (uae_u8 *src) +uae_u8 *save_expansion(int *len, uae_u8 *dstptr) { - fastmem_bank.start = restore_u32 (); - z3fastmem_bank.start = restore_u32 (); -#ifdef PICASSO96 - gfxmem_bank.start = restore_u32 (); -#endif - rtarea_base = restore_u32 (); - if (rtarea_base != 0 && rtarea_base != RTAREA_DEFAULT && rtarea_base != RTAREA_BACKUP) - rtarea_base = 0; - return src; + uae_u8 *dst, *dstbak; + if (dstptr) + dst = dstbak = dstptr; + else + dstbak = dst = xmalloc(uae_u8, 6 * 4); + save_u32(fastmem_bank[0].start); + save_u32(z3fastmem_bank[0].start); + save_u32(gfxmem_banks[0]->start); + save_u32(rtarea_base); + save_u32(fastmem_bank[1].start); + *len = 4 + 4 + 4 + 4 + 4; + return dstbak; +} + +uae_u8 *restore_expansion(uae_u8 *src) +{ + fastmem_bank[0].start = restore_u32(); + z3fastmem_bank[0].start = restore_u32(); + gfxmem_banks[0]->start = restore_u32(); + rtarea_base = restore_u32(); + fastmem_bank[1].start = restore_u32(); + if (rtarea_base != 0 && rtarea_base != RTAREA_DEFAULT && rtarea_base != RTAREA_BACKUP && rtarea_base != RTAREA_BACKUP_2) + rtarea_base = 0; + return src; +} + +uae_u8 *save_expansion_info(int *len, uae_u8 *dstptr) +{ + uae_u8 *dst, *dstbak; + if (dstptr) + dst = dstbak = dstptr; + else + dstbak = dst = xmalloc(uae_u8, 100 + MAX_EXPANSION_BOARD_SPACE * 100); + save_u32(1); + save_u32(0); + save_u32(cardno); + for (int i = 0; i < cardno; i++) { + struct card_data *ec = cards[i]; + if (ec->rc) { + save_u32(ec->rc->back->device_type); + save_u32(ec->rc->back->device_num); + save_string(ec->rc->romfile); + save_string(ec->rc->romident); + } + else { + save_u32(0xffffffff); + } + save_u32(ec->base); + save_u32(ec->size); + save_u32(ec->flags); + save_string(ec->name); + } + save_u32(0); + *len = dst - dstbak; + return dstbak; +} + +uae_u8 *restore_expansion_info(uae_u8 *src) +{ + if (restore_u32() != 1) + return src; + restore_u32(); + int num = restore_u32(); + for (int i = 0; i < num; i++) { + int romtype = restore_u32(); + if (romtype != 0xffffffff) { + restore_u32(); + restore_string(); + restore_string(); + } + restore_u32(); + restore_u32(); + restore_u32(); + restore_string(); + } + restore_u32(); + return src; } #endif /* SAVESTATE */ + +#if 0 +static const struct expansionsubromtype a2090_sub[] = { + { + _T("A2090a"), _T("a2090a"), + 0, 0, 0, + { 0 }, + }, + { + _T("A2090a + 1M RAM"), _T("a2090a_2"), + 0, 0, 0, + { 0 }, + }, + { + NULL + } +}; +#endif +static const struct expansionsubromtype a2091_sub[] = { + { + _T("DMAC-01"), _T("dmac01"), 0, + commodore, commodore_a2091_ram, 0, true, + { 0 } + }, + { + _T("DMAC-02"), _T("dmac02"), 0, + commodore, commodore_a2091_ram, 0, true, + { 0 } + }, + { + NULL + } +}; +static const struct expansionsubromtype gvp1_sub[] = { + { + _T("Impact A2000-1/X"), _T("a2000-1"), 0, + 1761, 8, 0, false, + { 0 } + }, + { + _T("Impact A2000-HC"), _T("a2000-hc"), 0, + 1761, 8, 0, false, + { 0 } + }, + { + _T("Impact A2000-HC+2"), _T("a2000-hc+"), 0, + 1761, 8, 0, false, + { 0 } + }, + { + NULL + } +}; +static const struct expansionsubromtype masoboshi_sub[] = { + { + _T("MC-302"), _T("mc-302"), 0, + 2157, 3, 0, false, + { 0 } + }, + { + _T("MC-702"), _T("mc-702"), 0, + 2157, 3, 0, false, + { 0 } + }, + { + NULL + } +}; +static const struct expansionsubromtype rochard_sub[] = { + { + _T("IDE"), _T("ide"), 0, + 2144, 2, 0, false, + { 0 } + }, + { + _T("IDE+SCSI"), _T("scsi"), 0, + 2144, 2, 0, false, + { 0 } + }, + { + NULL + } +}; +static const struct expansionsubromtype supra_sub[] = { + { + _T("A500 ByteSync/XP"), _T("bytesync"), ROMTYPE_NONE | ROMTYPE_SUPRA, + 1056, 9, 0, false, + { 0xd1, 13, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }, + }, + { + _T("A2000 Word Sync"), _T("wordsync"), ROMTYPE_NONE | ROMTYPE_SUPRA, + 1056, 9, 0, false, + { 0xd1, 12, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }, + }, + { + _T("A500 Autoboot"), _T("500"), ROMTYPE_NONE | ROMTYPE_SUPRA, + 1056, 5, 0, false, + { 0xd1, 8, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }, + }, + { + _T("Non Autoboot (4x4)"), _T("4x4"), ROMTYPE_NOT | ROMTYPE_SUPRA, + 1056, 2, 0, false, + { 0xc1, 1, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + }, + { + _T("A2000 DMA"), _T("dma"), ROMTYPE_NONE | ROMTYPE_SUPRADMA, + 1056, 2, 0, false, + { 0xd1, 3, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00 }, + }, + { + NULL + } +}; + +static const struct expansionsubromtype mediator_sub[] = { + { + _T("1200"), _T("1200"), ROMTYPE_NOT | ROMTYPE_MEDIATOR + }, + { + _T("1200SX"), _T("1200sx"), ROMTYPE_NOT | ROMTYPE_MEDIATOR + }, + { + _T("1200TX"), _T("1200tx"), ROMTYPE_NOT | ROMTYPE_MEDIATOR + }, + { + _T("4000MK2"), _T("4000mkii"), ROMTYPE_NOT | ROMTYPE_MEDIATOR + }, + { + NULL + } +}; +static const struct expansionboardsettings mediator_settings[] = { + { + _T("Full PCI DMA"), + _T("fulldma") + }, + { + _T("Win Size"), + _T("winsize") + }, + { + _T("Swap Config"), + _T("swapconfig") + }, + { + NULL + } +}; +static const struct expansionboardsettings bridge_settings[] = { + { + _T("Full PCI DMA"), + _T("fulldma") + }, + { + NULL + } +}; + +static const struct expansionboardsettings x86at286_bridge_settings[] = { + { + // 14 + _T("Default video\0") _T("Monochrome\0") _T("Color\0"), + _T("video\0") _T("mono\0") _T("color\0"), + true, false, 14 + }, + { + // 15 + _T("Keyboard lock"), + _T("keylock"), + false + }, + { // 16 - 18 + _T("Memory\0") _T("1M\0") _T("2M\0") _T("4M\0") _T("8M\0") _T("16M\0"), + _T("memory\0") _T("1M\0") _T("2M\0") _T("4M\0") _T("8M\0") _T("16M\0"), + true, false, 0 + }, + { // 19 - 20 + _T("CPU core\0") _T("DOSBox simple\0") _T("DOSBox normal\0") _T("DOSBox full\0") _T("DOSBox auto\0"), + _T("cpu\0") _T("dbsimple\0") _T("dbnormal\0") _T("dbfull\0") _T("dbauto\0"), + true, false, 0 + }, + { // 22 + _T("FPU"), + _T("fpu"), + false, false, 1 + }, + { // 23 - 25 + _T("CPU Arch\0") _T("auto\0") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"), + _T("cpuarch\0") _T("auto\0") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"), + true, false, 0 + }, + { + NULL + } +}; + +static const struct expansionboardsettings x86at386_bridge_settings[] = { + { + // 15 + _T("Keyboard lock"), + _T("keylock"), + false, false, 15 + }, + { // 16 - 18 + _T("Memory\0") _T("1M\0") _T("2M\0") _T("4M\0") _T("8M\0") _T("16M\0") _T("32M\0") _T("64M\0"), + _T("memory\0") _T("1M\0") _T("2M\0") _T("4M\0") _T("8M\0") _T("16M\0") _T("32M\0") _T("64M\0"), + true, false, 0 + }, + { // 19 - 20 + _T("CPU core\0") _T("DOSBox simple\0") _T("DOSBox normal\0") _T("DOSBox full\0") _T("DOSBox auto\0"), + _T("cpu\0") _T("dbsimple\0") _T("dbnormal\0") _T("dbfull\0") _T("dbauto\0"), + true, false, 0 + }, + { // 22 + _T("FPU"), + _T("fpu"), + false, false, 1 + }, + { // 23 - 25 + _T("CPU Arch\0") _T("auto\0") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"), + _T("cpuarch\0") _T("auto\0") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"), + true, false, 0 + }, + { + NULL + } +}; + +static const struct expansionboardsettings x86_bridge_settings[] = { + { + // 2-3 + _T("Memory (SW1:3-4)\0") _T("128K\0") _T("256K\0") _T("512K\0") _T("640K\0"), + _T("memory\0") _T("128k\0") _T("256k\0") _T("512k\0") _T("640k\0"), + true, false, 2 + }, + { + // 4-5 + _T("Default video (J1)\0") _T("Monochrome\0") _T("Color 40x25\0") _T("Color 80x25\0") _T("None\0"), + _T("video\0") _T("mono\0") _T("color40\0") _T("color80\0") _T("none\0"), + true, false, 0 + }, + { // 19 - 21 + _T("CPU core\0") _T("Fake86\0") _T("DOSBox simple\0") _T("DOSBox normal\0") _T("DOSBox full\0") _T("DOSBox auto\0"), + _T("cpu\0") _T("fake86\0") _T("dbsimple\0") _T("dbnormal\0") _T("dbfull\0") _T("dbauto\0"), + true, false, 19 - 6 + }, + { // 22 + _T("FPU (DOSBox CPU only)"), + _T("fpu") + }, + { // 23 - 25 + _T("CPU Arch (DOSBox CPU only)\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"), + _T("cpuarch\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"), + true, false, 0 + }, + { + NULL + } +}; + +static const struct expansionboardsettings x86_bridge_sidecar_settings[] = { + { + // 0 + _T("System Diagnostics (SW1:1)"), + _T("diagnostics"), + }, + { + // 1 + _T("8037 installed (SW1:2)"), + _T("fpu"), + }, + { + // 2-3 + _T("Memory (SW1:3-4)\0") _T("128K\0") _T("256K\0") _T("512K\0") _T("640K\0"), + _T("memory\0") _T("128k\0") _T("256k\0") _T("512k\0") _T("640k\0"), + true + }, + { + // 4-5 + _T("Default video (SW1:5-6)\0") _T("Monochrome\0") _T("Color 40x25\0") _T("Color 80x25\0") _T("None\0"), + _T("video\0") _T("mono\0") _T("color40\0") _T("color80\0") _T("none\0"), + true + }, + { + // 6-7 + _T("Floppy drives (SW1:7-8)\0") _T("1\0") _T("2\0") _T("3\0") _T("4\0"), + _T("floppy\0") _T("floppy1\0") _T("floppy2\0") _T("floppy3\0") _T("floppy4\0"), + true + }, + { + // 8 + _T("Disable mono video emulation (SW2:1)"), + _T("mono_card") + }, + { + // 9 + _T("Disable color video emulation (SW2:2)"), + _T("color_card") + }, + { + // 10-11 + _T("Address sector (SW2:3-4)\0") _T("A0000-AFFFF (1)\0") _T("A0000-AFFFF (2)\0") _T("D0000-DFFFF\0") _T("E0000-EFFFF\0"), + _T("memory\0") _T("sector_a0000_1\0") _T("sector_a0000_2\0") _T("sector_d0000\0") _T("sector_e0000\0"), + true + }, + { + // 12 + _T("Disable parallel port emulation (J11)"), + _T("parport_card") + }, + { // 19 - 21 + _T("CPU core\0") _T("Fake86\0") _T("DOSBox simple\0") _T("DOSBox normal\0") _T("DOSBox full\0") _T("DOSBox auto\0"), + _T("cpu\0") _T("fake86\0") _T("dbsimple\0") _T("dbnormal\0") _T("dbfull\0") _T("dbauto\0"), + true, false, 19 - 13 + }, + { // 22 + _T("FPU (DOSBox CPU only)"), + _T("fpu") + }, + { // 23 - 25 + _T("CPU Arch (DOSBox CPU only)\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"), + _T("cpuarch\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"), + true, false, 0 + }, + { + NULL + } +}; + +static const struct expansionboardsettings toccata_soundcard_settings[] = { + { + _T("Paula/CD audio mixer"), + _T("mixer") + }, + { + NULL + } +}; + +static const struct expansionboardsettings x86_athdxt_settings[] = { + { + _T("ROM Address\0") _T("0xCC000\0") _T("0xDC000\0") _T("0xEC000\0"), + _T("baseaddress\0") _T("0xcc000\0") _T("0xdc000\0") _T("0xec000\0"), + true + }, + { + NULL + } +}; + + +static const struct expansionboardsettings harlequin_settings[] = { + { + _T("Model\0") _T("Harlequin (PAL)\0") _T("Harlequin (NTSC)\0") _T("Harlequin Plus (PAL)\0") _T("Harlequin Plus (NTSC)\0"), + _T("model\0") _T("pal\0") _T("ntsc\0") _T("pluspal\0") _T("plusntsc\0"), + true + }, + { + _T("VRAM\0") _T("1.5M\0") _T("2M\0") _T("3M\0") _T("4M\0"), + _T("vram\0") _T("1.5m\0") _T("2m\0") _T("3m\0") _T("4m\0"), + true + }, + { + _T("Genlock"), + _T("genlock") + }, + { + NULL + } +}; + +static struct expansionboardsettings ne2k_isa_settings[] = { + { + _T("IO\0") _T("240\0") _T("260\0") _T("280\0") _T("2A0\0") _T("300\0") _T("320\0") _T("340\0") _T("360\0"), + _T("io\0") _T("240\0") _T("260\0") _T("280\0") _T("2A0\0") _T("300\0") _T("320\0") _T("340\0") _T("360\0"), + true, false, 0 + }, + { + _T("IRQ\0") _T("3\0") _T("4\0") _T("5\0") _T("7\0") _T("9\0") _T("10\0") _T("11\0") _T("12\0") _T("15\0"), + _T("irq\0") _T("3\0") _T("4\0") _T("5\0") _T("7\0") _T("9\0") _T("10\0") _T("11\0") _T("12\0") _T("15\0"), + true, false, 0 + }, + { + NULL, NULL, + true, false, 4 + }, + { + NULL + } +}; + +static struct expansionboardsettings lanrover_settings[] = { + { + _T("Interrupt level\0") _T("2\0") _T("6\0"), + _T("irq\0") _T("2\0") _T("6\0"), + true, false, 0 + }, + { + _T("MAC\0"), + _T("mac\0"), + 2, false, 0 + }, + { + NULL, NULL, + true, false, 15 + }, + { + NULL + } +}; +static struct expansionboardsettings ethernet_settings[] = { + { + _T("MAC\0"), + _T("mac\0"), + 2, false, 0 + }, + { + NULL, NULL, + true, false, 16 + }, + { + NULL + } +}; + +static struct expansionboardsettings *netsettings[] = { + ethernet_settings, + lanrover_settings, + ne2k_isa_settings, + NULL +}; + +struct netdriverdata **target_ethernet_enumerate(void); + +uae_u32 ethernet_getselection(const TCHAR *name) +{ +#ifndef AMIBERRY + struct netdriverdata **ndd = target_ethernet_enumerate(); + if (!ndd) + return 0; + for (int i = 0; ndd && i < MAX_TOTAL_NET_DEVICES; i++) { + if (ndd[i] && !_tcsicmp(ndd[i]->name, name)) + return i << 16; + } +#endif + return 0; +} + +const TCHAR *ethernet_getselectionname(uae_u32 settings) +{ +#ifndef AMIBERRY + struct netdriverdata **ndd = target_ethernet_enumerate(); + if (!ndd) + return 0; + settings = (settings >> 16) & 255; + for (int i = 0; ndd && i < MAX_TOTAL_NET_DEVICES; i++) { + if (i == settings) + return ndd[i]->name; + } +#endif + return _T("slirp"); +} + +void ethernet_updateselection(void) +{ +#ifndef AMIBERRY + static int updated; + if (updated) + return; + updated = 1; + struct netdriverdata **ndd = target_ethernet_enumerate(); + if (!ndd) + return; + static TCHAR tmp1[MAX_DPATH]; + static TCHAR tmp2[MAX_DPATH]; + _tcscpy(tmp1, _T("Network mode")); + _tcscpy(tmp2, _T("netmode")); + TCHAR *p1 = tmp1 + _tcslen(tmp1) + 1; + TCHAR *p2 = tmp2 + _tcslen(tmp2) + 1; + for (int i = 0; ndd && i < MAX_TOTAL_NET_DEVICES; i++) { + if (ndd[i]) { + TCHAR mac[20]; + mac[0] = 0; + if (ndd[i]->type == UAENET_SLIRP || ndd[i]->type == UAENET_SLIRP_INBOUND) { + _stprintf(mac, _T(" xx:xx:xx:%02X:%02X:%02X"), + ndd[i]->mac[3], ndd[i]->mac[4], ndd[i]->mac[5]); + } + _stprintf(p1, _T("%s%s"), ndd[i]->desc, mac[0] ? mac : _T("")); + p1 += _tcslen(p1) + 1; + _tcscpy(p2, ndd[i]->name); + p2 += _tcslen(p2) + 1; + } + } + *p1 = 0; + *p2 = 0; + for (int i = 0; netsettings[i]; i++) { + struct expansionboardsettings *ebs = netsettings[i]; + int j; + for (j = 0; ebs[j].name; j++); + ebs[j].name = tmp1; + ebs[j].configname = tmp2; + } +#endif +} + +static void fastlane_memory_callback(struct romconfig *rc, uae_u8 *ac, int size) +{ + struct zfile *z = read_device_from_romconfig(rc, NULL); + if (z) { + // load autoconfig data from rom file + uae_u8 act[16] = { 0 }; + zfile_fseek(z, 0x80, SEEK_SET); + zfile_fread(act, 1, 16, z); + zfile_fclose(z); + for (int i = 1; i < 16; i++) { + ac[i] = ~act[i]; + act[i] = ~act[i]; + } + // don't overwrite uae configured memory size + ac[0] = (ac[0] & 7) | (act[0] & 0xf8); + ac[2] = (ac[2] & 0x0f) | (act[2] & 0xf0); + } +} +static void hda506_memory_callback(struct romconfig *rc, uae_u8 *ac, int size) +{ + if (currprefs.cs_a1000ram) + ac[1] = 1; + else + ac[1] = 2; +} +static void nexus_memory_callback(struct romconfig *rc, uae_u8 *ac, int size) +{ + if (rc->device_settings & 1) + ac[0] &= ~(1 << 5); + if (size <= 2 * 1024 * 1024) + ac[1] = 2; + else if (size <= 4 * 1024 * 1024) + ac[1] = 4; + else + ac[1] = 8; +} +static const struct expansionboardsettings golemfast_settings[] = { + { + _T("IDE"), + _T("ide") + }, + { + NULL + } +}; +static const struct expansionboardsettings nexus_settings[] = { + { + _T("MEM TEST"), + _T("memtest") + }, + { + NULL + } +}; +static const struct expansionboardsettings buddha_settings[] = { + { + _T("Model\0") _T("Buddha\0") _T("Catweasel Z2\0"), + _T("model\0") _T("buddha\0") _T("cwz2\0"), + true, false, 0 + }, + { + NULL + } +}; + +static const struct expansionboardsettings adscsi2000_settings[] = { + { + _T("Cache (B)"), + _T("B") + }, + { + NULL + } +}; +static const struct expansionboardsettings warpengine_settings[] = { + { + _T("Jumper H"), + _T("jumper_h") + }, + { + _T("Jumper J"), + _T("jumper_j") + }, + { + _T("Jumper K"), + _T("jumper_k") + }, + { + NULL + } +}; +static const struct expansionboardsettings a4091_settings[] = { + { + _T("Fast Bus"), + _T("fastbus"), + }, + { + _T("Delayed autoboot"), + _T("delayedautoboot") + }, + { + _T("Syncronous mode"), + _T("syncmode") + }, + { + _T("Termination"), + _T("term") + }, + { + _T("LUN"), + _T("lun") + }, + { + NULL + } +}; +static const struct expansionboardsettings dataflyersplus_settings[] = { + { + _T("Configuration\0") _T("SCSI+IDE\0") _T("SCSI\0") _T("IDE\0"), + _T("config\0") _T("scsiide") _T("scsi\0") _T("ide\0"), + true + }, + { + NULL + } +}; + +const struct expansionromtype expansionroms[] = { +#if 0 + { + _T("cpuboard"), _T("Accelerator"), _T("Accelerator"), + NULL, NULL, add_cpuboard_unit, ROMTYPE_CPUBOARD, 0, 0, 0, true, + NULL, 0, + false, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE + }, + + /* PCI Bridgeboards */ + + { + _T("grex"), _T("G-REX"), _T("DCE"), + grex_init, NULL, NULL, ROMTYPE_GREX | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_PCI_BRIDGE + }, + { + _T("mediator"), _T("Mediator"), _T("Elbox"), + mediator_init, mediator_init2, NULL, ROMTYPE_MEDIATOR | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, false, + mediator_sub, 0, + false, EXPANSIONTYPE_PCI_BRIDGE, + 0, 0, 0, false, NULL, + false, 0, mediator_settings + }, + { + _T("prometheus"), _T("Prometheus"), _T("Matay"), + prometheus_init, NULL, NULL, ROMTYPE_PROMETHEUS | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z3, false, + NULL, 0, + false, EXPANSIONTYPE_PCI_BRIDGE, + 0, 0, 0, false, NULL, + false, 0, bridge_settings + }, + + /* SCSI/IDE expansion */ + + { + _T("apollo"), _T("Apollo 500/2000"), _T("3-State"), + apollo_init_hd, NULL, apollo_add_scsi_unit, ROMTYPE_APOLLOHD, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + false, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE, + 8738, 0, 0 + }, + { + _T("add500"), _T("ADD-500"), _T("Archos"), + add500_init, NULL, add500_add_scsi_unit, ROMTYPE_ADD500, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + false, EXPANSIONTYPE_SCSI, + 8498, 27, 0, true, NULL + }, + { + _T("blizzardscsikitiii"), _T("SCSI Kit III"), _T("Phase 5"), + NULL, NULL, cpuboard_ncr9x_add_scsi_unit, ROMTYPE_BLIZKIT3, 0, 0, 0, true, + NULL, 0, + false, EXPANSIONTYPE_SCSI + }, + { + _T("blizzardscsikitiv"), _T("SCSI Kit IV"), _T("Phase 5"), + NULL, NULL, cpuboard_ncr9x_add_scsi_unit, ROMTYPE_BLIZKIT4, 0, 0, 0, true, + NULL, 0, + false, EXPANSIONTYPE_SCSI + }, + { + _T("oktagon2008"), _T("Oktagon 2008"), _T("BSC/Alfa Data"), + ncr_oktagon_autoconfig_init, NULL, oktagon_add_scsi_unit, ROMTYPE_OKTAGON, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI + }, + { + _T("alfapower"), _T("AlfaPower/AT-Bus 2008"), _T("BSC/Alfa Data"), + alf_init, NULL, alf_add_ide_unit, ROMTYPE_ALFA, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + false, EXPANSIONTYPE_IDE, + 2092, 8, 0 + }, + { + _T("alfapowerplus"), _T("AlfaPower Plus"), _T("BSC/Alfa Data"), + alf_init, NULL, alf_add_ide_unit, ROMTYPE_ALFAPLUS, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + false, EXPANSIONTYPE_IDE, + 2092, 8, 0 + }, + { + _T("cltda1000scsi"), _T("A1000/A2000 SCSI"), _T("C-Ltd"), + cltda1000scsi_init, NULL, cltda1000scsi_add_scsi_unit, ROMTYPE_CLTDSCSI | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + false, EXPANSIONTYPE_SCSI, + 0, 0, 0, false, NULL, + false, 0, NULL, + { 0xc1, 0x0c, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + }, + { + _T("a2090a"), _T("A2090a"), _T("Commodore"), + a2090_init, NULL, a2090_add_scsi_unit, ROMTYPE_A2090 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_CUSTOM_SECONDARY + }, + { + _T("a2091"), _T("A590/A2091"), _T("Commodore"), + a2091_init, NULL, a2091_add_scsi_unit, ROMTYPE_A2091 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, + a2091_sub, 1, + true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_CUSTOM_SECONDARY, + commodore, commodore_a2091, 0, true, NULL + }, + { + _T("a4091"), _T("A4091"), _T("Commodore"), + ncr710_a4091_autoconfig_init, NULL, a4091_add_scsi_unit, ROMTYPE_A4091, 0, 0, BOARD_AUTOCONFIG_Z3, false, + NULL, 0, + false, EXPANSIONTYPE_SCSI, + 0, 0, 0, false, NULL, + true, 0, a4091_settings + }, + { + _T("dataflyerscsiplus"), _T("DataFlyer SCSI+"), _T("Expansion Systems"), + dataflyer_init, NULL, dataflyer_add_scsi_unit, ROMTYPE_DATAFLYERP | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_SCSI + }, + { + _T("dataflyerplus"), _T("DataFlyer Plus"), _T("Expansion Systems"), + dataflyerplus_init, NULL, dataflyerplus_add_idescsi_unit, ROMTYPE_DATAFLYER, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE, + 0, 0, 0, false, NULL, + false, 0, dataflyersplus_settings + }, + { + _T("gvp1"), _T("GVP Series I"), _T("Great Valley Products"), + gvp_init_s1, NULL, gvp_s1_add_scsi_unit, ROMTYPE_GVPS1 | ROMTYPE_NONE, ROMTYPE_GVPS12, 0, BOARD_AUTOCONFIG_Z2, false, + gvp1_sub, 1, + true, EXPANSIONTYPE_SCSI + }, + { + _T("gvp"), _T("GVP Series II"), _T("Great Valley Products"), + gvp_init_s2, NULL, gvp_s2_add_scsi_unit, ROMTYPE_GVPS2 | ROMTYPE_NONE, ROMTYPE_GVPS12, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI, + 2017, 10, 0 + }, + { + _T("vector"), _T("Vector Falcon 8000"), _T("HK-Computer"), + vector_init, NULL, vector_add_scsi_unit, ROMTYPE_VECTOR, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + false, EXPANSIONTYPE_SCSI + }, + { + _T("adide"), _T("AdIDE"), _T("ICD"), + adide_init, NULL, adide_add_ide_unit, ROMTYPE_ADIDE | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_IDE + }, + { + _T("adscsi2000"), _T("AdSCSI Advantage 2000"), _T("ICD"), + adscsi_init, NULL, adscsi_add_scsi_unit, ROMTYPE_ADSCSI, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + false, EXPANSIONTYPE_SCSI, + 0, 0, 0, false, NULL, + true, 0, adscsi2000_settings + }, + { + _T("buddha"), _T("Buddha"), _T("Individual Computers"), + buddha_init, NULL, buddha_add_ide_unit, ROMTYPE_BUDDHA, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + false, EXPANSIONTYPE_IDE, + 0, 0, 0, false, NULL, + false, 4, buddha_settings, + { 0xd1, 0x00, 0x00, 0x00, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00 }, + }, + { + _T("trumpcardpro"), _T("Grand Slam"), _T("IVS"), + trumpcardpro_init, NULL, trumpcardpro_add_scsi_unit, ROMTYPE_IVSTPRO, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI, + 2112, 4, 0, false, NULL, + true, 0, NULL, + { 0xd1, 0x34, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }, + }, + { + _T("kommos"), _T("Kommos A500/A2000 SCSI"), _T("Jürgen Kommos"), + kommos_init, NULL, kommos_add_scsi_unit, ROMTYPE_KOMMOS, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_SCSI + }, + { + _T("golem"), _T("Golem SCSI II"), _T("Kupke"), + golem_init, NULL, golem_add_scsi_unit, ROMTYPE_GOLEM, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI, + 2079, 3, 0 + }, + { + _T("golemfast"), _T("Golem Fast SCSI/IDE"), _T("Kupke"), + golemfast_init, NULL, golemfast_add_idescsi_unit, ROMTYPE_GOLEMFAST, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE, + 0, 0, 0, false, NULL, + true, 0, golemfast_settings + }, + { + _T("multievolution"), _T("Multi Evolution 500/2000"), _T("MacroSystem"), + ncr_multievolution_init, NULL, multievolution_add_scsi_unit, ROMTYPE_MEVOLUTION, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_SCSI, + 18260, 8, 0, true + }, + { + _T("scram8490"), _T("SCRAM (DP8490V)"), _T("MegaMicro"), + scram5380_init, NULL, scram5380_add_scsi_unit, ROMTYPE_SCRAM5380, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI, + 4096, 4, 0, false, NULL, + false, 0, NULL, + { 0xd1, 3, 0x40, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00 } + }, + { + _T("scram5394"), _T("SCRAM (NCR53C94)"), _T("MegaMicro"), + ncr_scram5394_init, NULL, scram5394_add_scsi_unit, ROMTYPE_SCRAM5394, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI, + 4096, 4, 0, false, NULL, + false, 0, NULL, + { 0xd1, 7, 0x40, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00 } + }, + { + _T("paradox"), _T("Paradox SCSI"), _T("Mainhattan Data"), + paradox_init, NULL, paradox_add_scsi_unit, ROMTYPE_PARADOX | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_PARALLEL_ADAPTER + }, + { + _T("ateam"), _T("A-Team"), _T("Mainhattan Data"), + ateam_init, NULL, ateam_add_ide_unit, ROMTYPE_ATEAM, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_IDE + }, + { + _T("mtecat"), _T("AT 500"), _T("M-Tec"), + mtec_init, NULL, mtec_add_ide_unit, ROMTYPE_MTEC, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_IDE + }, + { + _T("masoboshi"), _T("MasterCard"), _T("Masoboshi"), + masoboshi_init, NULL, masoboshi_add_idescsi_unit, ROMTYPE_MASOBOSHI | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, + masoboshi_sub, 0, + true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE + }, + { + _T("hardframe"), _T("HardFrame"), _T("Microbotics"), + hardframe_init, NULL, hardframe_add_scsi_unit, ROMTYPE_HARDFRAME, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI, + 0, 0, 0, false, NULL, + true + }, + { + _T("stardrive"), _T("StarDrive"), _T("Microbotics"), + stardrive_init, NULL, stardrive_add_scsi_unit, ROMTYPE_STARDRIVE | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_SCSI, + 1010, 0, 0, false, NULL, + false, 0, NULL, + { 0xc1, 2, 0x00, 0x00, 0x03, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + + }, + { + _T("filecard2000"), _T("Filecard 2000/OSSI 500"), _T("Otronic"), + ossi_init, NULL, ossi_add_scsi_unit, ROMTYPE_OSSI, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + true, EXPANSIONTYPE_SCSI, + 0, 0, 0, false, NULL, + false, 0, NULL, + { 0xc1, 1, 0x00, 0x00, 0x07, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + _T("fastlane"), _T("Fastlane"), _T("Phase 5"), + ncr_fastlane_autoconfig_init, NULL, fastlane_add_scsi_unit, ROMTYPE_FASTLANE, 0, 0, BOARD_AUTOCONFIG_Z3, false, + NULL, 0, + false, EXPANSIONTYPE_SCSI, + 8512, 10, 0, false, fastlane_memory_callback + }, + { + _T("phoenixboard"), _T("Phoenix Board SCSI"), _T("Phoenix Microtechnologies"), + phoenixboard_init, NULL, phoenixboard_add_scsi_unit, ROMTYPE_PHOENIXB, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + true, EXPANSIONTYPE_SCSI, + }, + { + _T("ptnexus"), _T("Nexus"), _T("Preferred Technologies"), + ptnexus_init, NULL, ptnexus_add_scsi_unit, ROMTYPE_PTNEXUS | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + false, EXPANSIONTYPE_SCSI, + 2102, 4, 0, false, nexus_memory_callback, + false, 0, nexus_settings, + { 0xd1, 0x01, 0x00, 0x00, 0x08, 0x36, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }, + }, + { + _T("protar"), _T("A500 HD"), _T("Protar"), + protar_init, NULL, protar_add_ide_unit, ROMTYPE_PROTAR, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI, + 4149, 51, 0 + }, + { + _T("rochard"), _T("RocHard RH800C"), _T("Roctec"), + rochard_init, NULL, rochard_add_idescsi_unit, ROMTYPE_ROCHARD | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, + rochard_sub, 0, + true, EXPANSIONTYPE_IDE | EXPANSIONTYPE_SCSI, + 2144, 2, 0, false, NULL, + false, 2, NULL + }, + { + _T("supradrive"), _T("SupraDrive"), _T("Supra Corporation"), + supra_init, NULL, supra_add_scsi_unit, ROMTYPE_SUPRA | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, + supra_sub, 0, + true, EXPANSIONTYPE_SCSI + }, +#if 0 /* driver is MIA, 3rd party ScottDevice driver is not enough for full implementation. */ + { + _T("microforge"), _T("Hard Disk"), _T("Micro Forge"), + microforge_init, NULL, microforge_add_scsi_unit, ROMTYPE_MICROFORGE | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_SASI | EXPANSIONTYPE_SCSI + }, +#endif + + { + _T("omtiadapter"), _T("OMTI-Adapter"), _T("C't"), + omtiadapter_init, NULL, omtiadapter_scsi_unit, ROMTYPE_OMTIADAPTER | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI + }, + { + _T("alf1"), _T("A.L.F."), _T("Elaborate Bytes"), + alf1_init, NULL, alf1_add_scsi_unit, ROMTYPE_ALF1 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI + }, + { + _T("promigos"), _T("Promigos"), _T("Flesch und Hörnemann"), + promigos_init, NULL, promigos_add_scsi_unit, ROMTYPE_PROMIGOS | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI + }, + { + _T("tecmar"), _T("T-Card/T-Disk"), _T("Tecmar"), + tecmar_init, NULL, tecmar_add_scsi_unit, ROMTYPE_TECMAR | ROMTYPE_NOT, 0, 0, BOARD_PROTOAUTOCONFIG, true, + NULL, 0, + false, EXPANSIONTYPE_SASI | EXPANSIONTYPE_SCSI, + 1001, 1, 0 + }, + { + _T("system2000"), _T("System 2000"), _T("Vortex"), + system2000_init, NULL, system2000_add_scsi_unit, ROMTYPE_SYSTEM2000 | ROMTYPE_NONE, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI + }, + { + _T("xebec"), _T("9720H"), _T("Xebec"), + xebec_init, NULL, xebec_add_scsi_unit, ROMTYPE_XEBEC | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_SASI | EXPANSIONTYPE_SCSI + }, +#if 0 + { + _T("kronos"), _T("Kronos"), _T("C-Ltd"), + kronos_init, kronos_add_scsi_unit, ROMTYPE_KRONOS, 0, 0, 2, false, + NULL, 0, + false, EXPANSIONTYPE_SCSI, + 0, 0, 0, + { 0xd1, 4, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }, + }, +#endif + { + _T("hda506"), _T("HDA-506"), _T("Spirit Technology"), + hda506_init, NULL, hda506_add_scsi_unit, ROMTYPE_HDA506 | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI, + 0, 0, 0, false, NULL, + false, 0, NULL, + { 0xc1, 0x04, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + _T("amax"), _T("AMAX ROM dongle"), _T("ReadySoft"), + NULL, NULL, NULL, ROMTYPE_AMAX | ROMTYPE_NONE, 0, 0, 0, false + }, + +#if 0 + { + _T("x86_xt_hd"), _T("x86 XT"), _T("x86"), + x86_xt_hd_init, NULL, x86_add_xt_hd_unit, ROMTYPE_X86_HD | ROMTYPE_NONE, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI + }, +#endif + { + _T("x86athdprimary"), _T("AT IDE Primary"), _T("x86"), + x86_at_hd_init_1, NULL, x86_add_at_hd_unit_1, ROMTYPE_X86_AT_HD1 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_IDE + }, + { + _T("x86athdsecondary"), _T("AT IDE Secondary"), _T("x86"), + x86_at_hd_init_2, NULL, x86_add_at_hd_unit_2, ROMTYPE_X86_AT_HD2 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_IDE + }, + { + _T("x86athdxt"), _T("XTIDE Universal BIOS HD"), _T("x86"), + x86_at_hd_init_xt, NULL, x86_add_at_hd_unit_xt, ROMTYPE_X86_XT_IDE | ROMTYPE_NONE, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_IDE, + 0, 0, 0, false, NULL, + false, 0, x86_athdxt_settings + }, + + /* PC Bridgeboards */ + + { + _T("a1060"), _T("A1060 Sidecar"), _T("Commodore"), + a1060_init, NULL, NULL, ROMTYPE_A1060 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_X86_BRIDGE, + 0, 0, 0, false, NULL, + false, 0, x86_bridge_sidecar_settings + }, + { + _T("a2088"), _T("A2088"), _T("Commodore"), + a2088xt_init, NULL, NULL, ROMTYPE_A2088 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_X86_BRIDGE, + 0, 0, 0, false, NULL, + false, 0, x86_bridge_settings + }, + { + _T("a2088t"), _T("A2088T"), _T("Commodore"), + a2088t_init, NULL, NULL, ROMTYPE_A2088T | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_X86_BRIDGE, + 0, 0, 0, false, NULL, + false, 0, x86_bridge_settings + }, + { + _T("a2286"), _T("A2286"), _T("Commodore"), + a2286_init, NULL, NULL, ROMTYPE_A2286 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_X86_BRIDGE, + 0, 0, 0, false, NULL, + false, 0, x86at286_bridge_settings + }, + { + _T("a2386"), _T("A2386SX"), _T("Commodore"), + a2386_init, NULL, NULL, ROMTYPE_A2386 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_X86_BRIDGE, + 0, 0, 0, false, NULL, + false, 0, x86at386_bridge_settings + }, + + // only here for rom selection and settings + { + _T("picassoiv"), _T("Picasso IV"), _T("Village Tronic"), + NULL, NULL, NULL, ROMTYPE_PICASSOIV | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, true, + NULL, 0, + false, EXPANSIONTYPE_RTG + }, + { + _T("x86vga"), _T("x86 VGA"), _T("x86"), + NULL, NULL, NULL, ROMTYPE_x86_VGA | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, true, + NULL, 0, + false, EXPANSIONTYPE_RTG + }, + { + _T("harlequin"), _T("Harlequin"), _T("ACS"), + NULL, NULL, NULL, ROMTYPE_HARLEQUIN | ROMTYPE_NOT, 0, 0, BOARD_IGNORE, false, + NULL, 0, + false, EXPANSIONTYPE_RTG, + 0, 0, 0, false, NULL, + false, 0, harlequin_settings + }, + + /* Sound Cards */ + + { + _T("toccata"), _T("Toccata"), _T("MacroSystem"), + sndboard_init, NULL, NULL, ROMTYPE_TOCCATA | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_SOUND, + 0, 0, 0, false, NULL, + false, 0, toccata_soundcard_settings, + { 0xc1, 12, 0, 0, 18260 >> 8, 18260 & 255 } + }, + { + _T("es1370"), _T("ES1370 PCI"), _T("Ensoniq"), + pci_expansion_init, NULL, NULL, ROMTYPE_ES1370 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_SOUND + }, + { + _T("fm801"), _T("FM801 PCI"), _T("Fortemedia"), + pci_expansion_init, NULL, NULL, ROMTYPE_FM801 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_SOUND + }, + { + _T("uaesnd_z2"), _T("UAESND Z2"), NULL, + uaesndboard_init_z2, NULL, NULL, ROMTYPE_UAESNDZ2 | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_SOUND, + 0, 0, 0, false, NULL, + false, 0, NULL, + { 0xc1, 2, 0x00, 0x00, 6502 >> 8, 6502 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + _T("uaesnd_z3"), _T("UAESND Z3"), NULL, + uaesndboard_init_z3, NULL, NULL, ROMTYPE_UAESNDZ3 | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z3, true, + NULL, 0, + false, EXPANSIONTYPE_SOUND, + 0, 0, 0, false, NULL, + false, 0, NULL, + { 0x80, 2, 0x10, 0x00, 6502 >> 8, 6502 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, +#if 0 + { + _T("pmx"), _T("pmx"), NULL, + pmx_init, NULL, NULL, ROMTYPE_PMX | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_SOUND, + 0, 0, 0, false, NULL, + false, 0, NULL, + { 0xc1, 0x30, 0x00, 0x00, 0x0e, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, +#endif + + /* Network */ + { + _T("a2065"), _T("A2065"), _T("Commodore"), + a2065_init, NULL, NULL, ROMTYPE_A2065 | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_NET, + 0, 0, 0, false, NULL, + false, 0, ethernet_settings, + { 0xc1, 0x70, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + _T("ariadne"), _T("Ariadne"), _T("Village Tronic"), + ariadne_init, NULL, NULL, ROMTYPE_ARIADNE | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_NET, + 0, 0, 0, false, NULL, + false, 0, ethernet_settings, + { 0xc1, 0xc9, 0x00, 0x00, 2167 >> 8, 2167 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + _T("ariadne2"), _T("Ariadne II"), _T("Village Tronic"), + ariadne2_init, NULL, NULL, ROMTYPE_ARIADNE2 | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_NET, + 0, 0, 0, false, NULL, + false, 0, ethernet_settings, + { 0xc1, 0xca, 0x00, 0x00, 2167 >> 8, 2167 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + _T("hydra"), _T("AmigaNet"), _T("Hydra Systems"), + hydra_init, NULL, NULL, ROMTYPE_HYDRA | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_NET, + 0, 0, 0, false, NULL, + false, 0, ethernet_settings, + { 0xc1, 0x01, 0x00, 0x00, 2121 >> 8, 2121 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + _T("eb920"), _T("LAN Rover/EB920"), _T("ASDG"), + lanrover_init, NULL, NULL, ROMTYPE_LANROVER | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_NET, + 0, 0, 0, false, NULL, + false, 0, lanrover_settings, + { 0xc1, 0xfe, 0x00, 0x00, 1023 >> 8, 1023 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + _T("xsurf"), _T("X-Surf"), _T("Individual Computers"), + xsurf_init, NULL, NULL, ROMTYPE_XSURF | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_NET, + 0, 0, 0, false, NULL, + false, 0, ethernet_settings, + { 0xc1, 0x17, 0x00, 0x00, 4626 >> 8, 4626 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + _T("xsurf100z2"), _T("X-Surf-100 Z2"), _T("Individual Computers"), + xsurf100_init, NULL, NULL, ROMTYPE_XSURF100Z2 | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_NET, + 0, 0, 0, false, NULL, + false, 0, ethernet_settings, + { 0xc1, 0x64, 0x10, 0x00, 4626 >> 8, 4626 & 255, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00 } + }, + { + _T("xsurf100z3"), _T("X-Surf-100 Z3"), _T("Individual Computers"), + xsurf100_init, NULL, NULL, ROMTYPE_XSURF100Z3 | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z3, true, + NULL, 0, + false, EXPANSIONTYPE_NET, + 0, 0, 0, false, NULL, + false, 0, ethernet_settings, + { 0x82, 0x64, 0x32, 0x00, 4626 >> 8, 4626 & 255, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00 } + }, + { + _T("ne2000_pcmcia"), _T("RTL8019 PCMCIA (NE2000 compatible)"), NULL, + gayle_init_ne2000_pcmcia, NULL, NULL, ROMTYPE_NE2KPCMCIA | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_NET, + 0, 0, 0, false, NULL, + false, 0, ethernet_settings, + }, + { + _T("ne2000_pci"), _T("RTL8029 PCI (NE2000 compatible)"), NULL, + pci_expansion_init, NULL, NULL, ROMTYPE_NE2KPCI | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_NET, + 0, 0, 0, false, NULL, + false, 0, ethernet_settings, + }, + { + _T("ne2000_isa"), _T("RTL8019 ISA (NE2000 compatible)"), NULL, + isa_expansion_init, NULL, NULL, ROMTYPE_NE2KISA | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_NET, + 0, 0, 0, false, NULL, + false, 0, ne2k_isa_settings + }, + + /* Catweasel */ + { + _T("catweasel"), _T("Catweasel"), _T("Individual Computers"), + expamem_init_catweasel, NULL, NULL, ROMTYPE_CATWEASEL | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_FLOPPY + }, + + /* built-in controllers */ + { + _T("cd32fmv"), _T("CD32 FMV"), _T("Commodore"), + expamem_init_cd32fmv, NULL, NULL, ROMTYPE_CD32CART, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_INTERNAL + }, + { + _T("cdtvdmac"), _T("CDTV DMAC"), _T("Commodore"), + cdtv_init, NULL, NULL, ROMTYPE_CDTVDMAC | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_INTERNAL + }, + { + _T("cdtvscsi"), _T("CDTV SCSI"), _T("Commodore"), + cdtvscsi_init, NULL, cdtv_add_scsi_unit, ROMTYPE_CDTVSCSI | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_INTERNAL | EXPANSIONTYPE_SCSI + }, + { + _T("cdtvcr"), _T("CDTV-CR"), _T("Commodore"), + cdtvcr_init, NULL, NULL, ROMTYPE_CDTVCR | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_INTERNAL + }, + { + _T("scsi_a3000"), _T("A3000 SCSI"), _T("Commodore"), + a3000scsi_init, NULL, a3000_add_scsi_unit, ROMTYPE_SCSI_A3000 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true, + NULL, 0, + false, EXPANSIONTYPE_INTERNAL | EXPANSIONTYPE_SCSI + }, + { + _T("scsi_a4000t"), _T("A4000T SCSI"), _T("Commodore"), + a4000t_scsi_init, NULL, a4000t_add_scsi_unit, ROMTYPE_SCSI_A4000T | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_INTERNAL | EXPANSIONTYPE_SCSI + }, + { + _T("ide_mb"), _T("A600/A1200/A4000 IDE"), _T("Commodore"), + gayle_ide_init, NULL, gayle_add_ide_unit, ROMTYPE_MB_IDE | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_INTERNAL | EXPANSIONTYPE_IDE + }, + { + _T("pcmcia_mb"), _T("A600/A1200 PCMCIA"), _T("Commodore"), + gayle_pcmcia_init, NULL, gayle_add_pcmcia_unit, ROMTYPE_MB_PCMCIA | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, + NULL, 0, + false, EXPANSIONTYPE_INTERNAL + }, +#endif + + { + NULL + } +}; + +static const struct expansionboardsettings blizzardboard_settings[] = { + { + _T("MapROM"), + _T("maprom") + }, + { + NULL + } +}; + +static const struct expansionboardsettings blizzardboard_settings_mk2[] = { + { + _T("MapROM"), + _T("maprom") + }, + { + _T("SCSI Kit II"), + _T("scsikitii") + }, + { + NULL + } +}; + +static const struct cpuboardsubtype gvpboard_sub[] = { +#if 0 + + { + _T("A3001 Series I"), + _T("A3001SI"), + ROMTYPE_CB_A3001S1, 0, + gvp_add_ide_unit, EXPANSIONTYPE_IDE | EXPANSIONTYPE_24BIT, + BOARD_MEMORY_Z2, + 8 * 1024 * 1024, + 0, + gvp_ide_rom_autoconfig_init, NULL, BOARD_AUTOCONFIG_Z2, 0 + }, + { + _T("A3001 Series II"), + _T("A3001SII"), + 0, 0, + gvp_add_ide_unit, EXPANSIONTYPE_IDE | EXPANSIONTYPE_24BIT, + BOARD_MEMORY_Z2, + 8 * 1024 * 1024, + 0, + gvp_ide_rom_autoconfig_init, gvp_ide_controller_autoconfig_init, BOARD_AUTOCONFIG_Z2, 0 + }, + { + _T("A530"), + _T("GVPA530"), + ROMTYPE_GVPS2, 0, + gvp_s2_add_accelerator_scsi_unit, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_24BIT, + BOARD_MEMORY_Z2, + 8 * 1024 * 1024, + 0, + gvp_init_accelerator, NULL, BOARD_AUTOCONFIG_Z2, 1, + NULL, NULL, + 2017, 9, 0, false + }, + { + _T("G-Force 030"), + _T("GVPGFORCE030"), + ROMTYPE_GVPS2, ROMTYPE_GVPS12, + gvp_s2_add_accelerator_scsi_unit, EXPANSIONTYPE_SCSI, + BOARD_MEMORY_25BITMEM, + 128 * 1024 * 1024, + 0, + gvp_init_accelerator, NULL, BOARD_AUTOCONFIG_Z2, 1 + }, + { + _T("Tek Magic 2040/2060"), + _T("TekMagic"), + ROMTYPE_CB_TEKMAGIC, 0, + tekmagic_add_scsi_unit, EXPANSIONTYPE_SCSI, + BOARD_MEMORY_HIGHMEM, + 128 * 1024 * 1024 + }, +#endif + { + NULL + } +}; +static const struct cpuboardsubtype blizzardboard_sub[] = { +#if 0 + { + _T("Blizzard 1230 II"), + _T("Blizzard1230II"), + ROMTYPE_CB_B1230MK2, 0, + cpuboard_ncr9x_add_scsi_unit, EXPANSIONTYPE_SCSI, + BOARD_MEMORY_BLIZZARD_12xx, + 64 * 1024 * 1024, + 0, + NULL, NULL, 0, 0, + blizzardboard_settings_mk2 + }, + { + _T("Blizzard 1230 III"), + _T("Blizzard1230III"), + ROMTYPE_CB_B1230MK3, 0, + NULL, 0, + BOARD_MEMORY_BLIZZARD_12xx, + 32 * 1024 * 1024, + 0, + NULL, NULL, 0, 0, + blizzardboard_settings + }, + { + _T("Blizzard 1230 IV"), + _T("Blizzard1230IV"), + ROMTYPE_CB_BLIZ1230, 0, + NULL, EXPANSIONTYPE_FALLBACK_DISABLE | EXPANSIONTYPE_HAS_FALLBACK, + BOARD_MEMORY_BLIZZARD_12xx, + 256 * 1024 * 1024, + 0, + NULL, NULL, 0, 0, + blizzardboard_settings + }, + { + _T("Blizzard 1260"), + _T("Blizzard1260"), + ROMTYPE_CB_BLIZ1260, 0, + NULL, EXPANSIONTYPE_FALLBACK_DISABLE | EXPANSIONTYPE_HAS_FALLBACK, + BOARD_MEMORY_BLIZZARD_12xx, + 256 * 1024 * 1024, + 0, + NULL, NULL, 0, 0, + blizzardboard_settings + }, + { + _T("Blizzard 2060"), + _T("Blizzard2060"), + ROMTYPE_CB_BLIZ2060, 0, + cpuboard_ncr9x_add_scsi_unit, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_FALLBACK_DISABLE | EXPANSIONTYPE_HAS_FALLBACK, + BOARD_MEMORY_HIGHMEM, + 128 * 1024 * 1024, + 0, + NULL, NULL, 0, 0, + blizzardboard_settings + }, + { + _T("Blizzard PPC"), + _T("BlizzardPPC"), + ROMTYPE_CB_BLIZPPC, 0, + blizzardppc_add_scsi_unit, EXPANSIONTYPE_SCSI, + BOARD_MEMORY_BLIZZARD_PPC, + 256 * 1024 * 1024 + }, +#endif + { + NULL + } +}; +static const struct cpuboardsubtype cyberstormboard_sub[] = { +#if 0 + { + _T("CyberStorm MK I"), + _T("CyberStormMK1"), + ROMTYPE_CB_CSMK1, 0, + cpuboard_ncr9x_add_scsi_unit, EXPANSIONTYPE_SCSI, + BOARD_MEMORY_HIGHMEM, + 128 * 1024 * 1024 + }, + { + _T("CyberStorm MK II"), + _T("CyberStormMK2"), + ROMTYPE_CB_CSMK2, 0, + cpuboard_ncr9x_add_scsi_unit, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_FALLBACK_DISABLE | EXPANSIONTYPE_HAS_FALLBACK, + BOARD_MEMORY_HIGHMEM, + 128 * 1024 * 1024 + }, + { + _T("CyberStorm MK III"), + _T("CyberStormMK3"), + ROMTYPE_CB_CSMK3, 0, + cyberstorm_add_scsi_unit, EXPANSIONTYPE_SCSI, + BOARD_MEMORY_HIGHMEM, + 128 * 1024 * 1024 + }, + { + _T("CyberStorm PPC"), + _T("CyberStormPPC"), + ROMTYPE_CB_CSPPC, 0, + cyberstorm_add_scsi_unit, EXPANSIONTYPE_SCSI, + BOARD_MEMORY_HIGHMEM, + 128 * 1024 * 1024 + }, +#endif + { + NULL + } +}; +static const struct cpuboardsubtype warpengine_sub[] = { +#if 0 + { + _T("Warp Engine A4000"), + _T("WarpEngineA4000"), + ROMTYPE_CB_WENGINE, 0, + warpengine_add_scsi_unit, EXPANSIONTYPE_SCSI, + BOARD_MEMORY_HIGHMEM, + 128 * 1024 * 1024, + 0x01000000, + ncr710_warpengine_autoconfig_init, NULL, BOARD_AUTOCONFIG_Z3, 1, + warpengine_settings + }, +#endif + { + NULL + } +}; +static const struct expansionboardsettings mtec_settings[] = { + { + _T("SCSI disabled"), + _T("scsioff") + }, + { + NULL + } +}; +static const struct cpuboardsubtype mtec_sub[] = { +#if 0 + { + _T("E-Matrix 530"), + _T("e-matrix530"), + ROMTYPE_CB_EMATRIX, 0, + ematrix_add_scsi_unit, EXPANSIONTYPE_SCSI, + BOARD_MEMORY_CUSTOM_32, + 128 * 1024 * 1024, + 0, + ncr_ematrix_autoconfig_init, NULL, BOARD_AUTOCONFIG_Z2, 1, + mtec_settings + }, +#endif + { + NULL + } +}; + +static const struct expansionboardsettings ivsvector_settings[] = { + { + // 0/1 + _T("Memory (JP12)\0") _T("4M\0") _T("8M\0") _T("16M\0") _T("32M\0"), + _T("memory\0") _T("4m\0") _T("8m\0") _T("16m\0") _T("32m\0"), + true, false, 0 + }, + { + // 3 + _T("Disable FastROM (JP17)"), + _T("disfastrom"), + false, false, 1 + }, + { + // 4 + _T("Autoboot (JP20)"), + _T("autoboot"), + false, false, 0 + }, + { + // 5 + _T("Dis68kRAM (JP14)"), + _T("dis68kram"), + false, false, 1 + }, + { + // 6 + _T("Burst (JP13)"), + _T("burst"), + false, false, 1 + }, + { + NULL + } +}; + + +static const struct expansionboardsettings a26x0board_settings[] = { + { + _T("OSMODE (J304)"), + _T("j304") + }, + { + NULL + } +}; +static const struct cpuboardsubtype commodore_sub[] = { +#if 0 + { + _T("A2620/A2630"), + _T("A2630"), + ROMTYPE_CB_A26x0, 0, + NULL, 0, + BOARD_MEMORY_25BITMEM, + 128 * 1024 * 1024, + 0, + NULL, NULL, 0, 0, + a26x0board_settings, + cpuboard_io_special + }, +#endif + { + NULL + } +}; +static const struct cpuboardsubtype dbk_sub[] = { +#if 0 + { + _T("1230/1240"), + _T("DKB12x0"), + ROMTYPE_CB_DKB12x0, 0, + cpuboard_dkb_add_scsi_unit, EXPANSIONTYPE_SCSI, + 0, + 128 * 1024 * 1024, + 0, + ncr_dkb_autoconfig_init, NULL, BOARD_AUTOCONFIG_Z2, 0 + }, + { + _T("Wildfire"), + _T("wildfire"), + ROMTYPE_CB_DBK_WF, 0, + wildfire_add_scsi_unit, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_HAS_FALLBACK, + BOARD_MEMORY_HIGHMEM, + 128 * 1024 * 1024, + 0, + dkb_wildfire_pci_init, NULL, BOARD_NONAUTOCONFIG_BEFORE, 0 + }, +#endif + { + NULL + } +}; +static const struct cpuboardsubtype fusionforty_sub[] = { +#if 0 + { + _T("Fusion Forty"), + _T("FusionForty"), + ROMTYPE_CB_FUSION, 0, + NULL, 0, + BOARD_MEMORY_HIGHMEM, + 128 * 1024 * 1024 + }, +#endif + { + NULL + } +}; +static const struct cpuboardsubtype ivs_sub[] = { +#if 0 + { + _T("Vector"), + _T("Vector"), + ROMTYPE_CB_VECTOR, 0, + ivsvector_add_scsi_unit, EXPANSIONTYPE_SCSI, + BOARD_MEMORY_HIGHMEM, + 32 * 1024 * 1024, + 0, + ivsvector_init, NULL, BOARD_AUTOCONFIG_Z2, 1, + ivsvector_settings, NULL, + 2112, 240, 0, false + }, +#endif + { + NULL + } +}; + +static const struct expansionboardsettings apollo_settings[] = { + { + _T("SCSI module installed"), + _T("scsi") + }, + { + NULL + } +}; + +static const struct cpuboardsubtype apollo_sub[] = { +#if 0 + { + _T("Apollo 1240/1260"), + _T("Apollo"), + ROMTYPE_CB_APOLLO, 0, + apollo_add_scsi_unit, EXPANSIONTYPE_SCSI, + BOARD_MEMORY_HIGHMEM, + 128 * 1024 * 1024, + 0, + apollo_init_cpu, NULL, 2, 0, + apollo_settings + }, +#endif + { + NULL + } +}; +static const struct cpuboardsubtype kupkeboard_sub[] = { +#if 0 + { + _T("Golem 030"), + _T("golem030"), + ROMTYPE_CB_GOLEM030, 0, + NULL, 0, + BOARD_MEMORY_25BITMEM, + 16 * 1024 * 1024 + }, +#endif + { + NULL + } +}; +static const struct cpuboardsubtype icboard_sub[] = { + { + _T("ACA 500"), + _T("aca500"), + ROMTYPE_CB_ACA500, 0, + NULL, EXPANSIONTYPE_24BIT + }, + { + NULL + } +}; +static const struct cpuboardsubtype dceboard_sub[] = { +#if 0 + { + _T("SX32 Pro"), + _T("sx32pro"), + ROMTYPE_CB_SX32PRO, 0, + NULL, 0, + BOARD_MEMORY_CUSTOM_32, + 64 * 1024 * 1024 + }, +#endif + { + NULL + } +}; + +static const struct cpuboardsubtype dummy_sub[] = { + { NULL } +}; + +const struct cpuboardtype cpuboards[] = { + { + -1, + _T("-"), + dummy_sub, 0 + }, +#if 0 + { + BOARD_ACT, + _T("ACT"), + apollo_sub, 0 + }, + { + BOARD_COMMODORE, + _T("Commodore"), + commodore_sub, 0 + }, + { + BOARD_DCE, + _T("DCE"), + dceboard_sub, 0 + }, + { + BOARD_DKB, + _T("DKB"), + dbk_sub, 0 + }, + { + BOARD_GVP, + _T("Great Valley Products"), + gvpboard_sub, 0 + }, + { + BOARD_KUPKE, + _T("Kupke"), + kupkeboard_sub, 0 + }, + { + BOARD_MACROSYSTEM, + _T("MacroSystem"), + warpengine_sub, 0 + }, + { + BOARD_MTEC, + _T("M-Tec"), + mtec_sub, 0 + }, + { + BOARD_BLIZZARD, + _T("Phase 5 - Blizzard"), + blizzardboard_sub, 0 + }, + { + BOARD_CYBERSTORM, + _T("Phase 5 - CyberStorm"), + cyberstormboard_sub, 0 + }, + { + BOARD_RCS, + _T("RCS Management"), + fusionforty_sub, 0 + }, + { + BOARD_IVS, + _T("Interactive Video Systems"), + ivs_sub, 0 + }, +#endif +#if 0 + { + BOARD_IC, + _T("Individual Computers"), + icboard_sub, 0 + }, +#endif + { + NULL + } +}; + +const struct memoryboardtype memoryboards[] +{ + // z2 + { + _T("UAE"), _T("0xf00000 RAM"), + 2, 0xf00000, 0xffff, 0xff + }, + { + _T("DKB"), _T("Insider I/II"), + 2, 0x800000, 0xffff, 0xff + }, + { + _T("GVP"), _T("Impact A2000-RAM8"), + 2, 0, 2077, 9 + }, + { + _T("Kupke"), _T("Golem RAM-Card"), + 2, 0, 2073, 3 + }, + { + _T("Supra"), _T("SupraRAM 500RX"), + 2, 0, 1056, 10 + }, + { + _T("Supra"), _T("SupraRAM 2000"), + 2, 0, 1056, 9 + }, + // z3 + { + _T("E3B"), _T("ZorRAM"), + 3, 0, 3643, 32 + }, + + + { + NULL + } +}; diff --git a/src/filesys.cpp b/src/filesys.cpp index 3aedfda3..dca8481c 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -113,6 +113,7 @@ static void aino_test_init (a_inode *aino) uaecptr filesys_initcode; +static uaecptr bootrom_start; static uae_u32 fsdevname, fshandlername, filesys_configdev; static int filesys_in_interrupt; static uae_u32 mountertask; @@ -129,34 +130,37 @@ static int automountunit = -1; typedef struct { int unit_type; int open; // >0 start as filesystem, <0 = allocated but do not start - TCHAR *devname; /* device name, e.g. UAE0: */ - uaecptr devname_amiga; - uaecptr startup; + TCHAR *devname; /* device name, e.g. UAE0: */ + uaecptr devname_amiga; + uaecptr startup; uaecptr devicenode; - TCHAR *volname; /* volume name, e.g. CDROM, WORK, etc. */ - int volflags; /* volume flags, readonly, stream uaefsdb support */ - TCHAR *rootdir; /* root native directory/hdf. empty drive if invalid path */ - struct zvolume *zarchive; - TCHAR *rootdirdiff; /* "diff" file/directory */ - bool readonly; /* disallow write access? */ - bool locked; /* action write protect */ + uaecptr parmpacket; + TCHAR *volname; /* volume name, e.g. CDROM, WORK, etc. */ + int volflags; /* volume flags, readonly, stream uaefsdb support */ + TCHAR *rootdir; /* root native directory/hdf. empty drive if invalid path */ + struct zvolume *zarchive; + TCHAR *rootdirdiff; /* "diff" file/directory */ + bool readonly; /* disallow write access? */ + bool locked; /* action write protect */ bool unknown_media; /* ID_UNREADABLE_DISK */ - int bootpri; /* boot priority. -128 = no autoboot, -129 = no mount */ - int devno; - int controller; - bool wasisempty; /* if true, this unit was created empty */ - bool canremove; /* if true, this unit can be safely ejected and remounted */ - bool configureddrive; /* if true, this is drive that was manually configured */ - - struct hardfiledata hf; + int bootpri; /* boot priority. -128 = no autoboot, -129 = no mount */ + int devno; + int controller_type; + int controller_unit; + bool wasisempty; /* if true, this unit was created empty */ + bool canremove; /* if true, this unit can be safely ejected and remounted */ + bool configureddrive; /* if true, this is drive that was manually configured */ + bool inject_icons; /* inject icons if directory filesystem */ - /* Threading stuff */ - smp_comm_pipe *volatile unit_pipe, *volatile back_pipe; - uae_thread_id tid; - struct _unit *self; - /* Reset handling */ - uae_sem_t reset_sync_sem; - volatile int reset_state; + struct hardfiledata hf; + + /* Threading stuff */ + smp_comm_pipe *volatile unit_pipe, *volatile back_pipe; + uae_thread_id tid; + struct _unit *self; + /* Reset handling */ + uae_sem_t reset_sync_sem; + volatile int reset_state; /* RDB stuff */ uaecptr rdb_devname_amiga[DEVNAMES_PER_HDF]; @@ -169,6 +173,12 @@ typedef struct { /* filesystem seglist */ uaecptr filesysseg; uae_u32 rdb_dostype; + + /* CDFS */ + bool cd_open; + int cddevno; + void *cdfs_superblock; + } UnitInfo; struct uaedev_mount_info { @@ -187,21 +197,22 @@ int nr_units (void) return cnt; } -int nr_directory_units (struct uae_prefs *p) +int nr_directory_units(struct uae_prefs *p) { - int i, cnt = 0; - if (p) { - for (i = 0; i < p->mountitems; i++) { - if (p->mountconfig[i].ci.controller == 0) - cnt++; - } - } else { - for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) { - if (mountinfo.ui[i].open > 0 && mountinfo.ui[i].controller == 0) - cnt++; - } - } - return cnt; + int i, cnt = 0; + if (p) { + for (i = 0; i < p->mountitems; i++) { + if (p->mountconfig[i].ci.controller_type == HD_CONTROLLER_TYPE_UAE) + cnt++; + } + } + else { + for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) { + if (mountinfo.ui[i].open > 0 && mountinfo.ui[i].controller_type == HD_CONTROLLER_TYPE_UAE) + cnt++; + } + } + return cnt; } static int is_virtual (int unit_no) @@ -327,14 +338,15 @@ int get_filesys_unitconfig (struct uae_prefs *p, int index, struct mountedinfo * _stprintf (mi->rootdir, _T("CD %d"), ui->hf.ci.cd_emu_unit); #endif } - } else { - if (!ui->controller) { - mi->ismounted = 1; - if (uci->ci.type == UAEDEV_HDF) - mi->ismedia = ui->hf.drive_empty ? false : true; - else - mi->ismedia = true; - } + } + else if (uci->ci.type != UAEDEV_TAPE) { + if (ui->controller_type == HD_CONTROLLER_TYPE_UAE) { // what is this? || (ui->controller && p->cs_ide)) { + mi->ismounted = 1; + if (uci->ci.type == UAEDEV_HDF) + mi->ismedia = ui->hf.drive_empty ? false : true; + else + mi->ismedia = true; + } } if (mi->size < 0) @@ -389,23 +401,31 @@ static void fixcharset (TCHAR *s) au_fs_copy (s, strlen (tmp) + 1, tmp); } -TCHAR *validatevolumename (TCHAR *s) +TCHAR *validatevolumename(TCHAR *s, const TCHAR *def) { - stripsemicolon (s); - fixcharset (s); - striplength (s, 30); + stripsemicolon(s); + fixcharset(s); + striplength(s, 30); + if (_tcslen(s) == 0 && def) { + xfree(s); + s = my_strdup(def); + } return s; } -TCHAR *validatedevicename (TCHAR *s) +TCHAR *validatedevicename(TCHAR *s, const TCHAR *def) { - stripsemicolon (s); - stripspace (s); - fixcharset (s); - striplength (s, 30); + stripsemicolon(s); + stripspace(s); + fixcharset(s); + striplength(s, 30); + if (_tcslen(s) == 0 && def) { + xfree(s); + s = my_strdup(def); + } return s; } -TCHAR *filesys_createvolname (const TCHAR *volname, const TCHAR *rootdir, const TCHAR *def) +TCHAR *filesys_createvolname(const TCHAR *volname, const TCHAR *rootdir, struct zvolume *zv, const TCHAR *def) { TCHAR *nvol = NULL; int i, archivehd; @@ -452,7 +472,7 @@ TCHAR *filesys_createvolname (const TCHAR *volname, const TCHAR *rootdir, const else nvol = my_strdup (_T("")); } - validatevolumename (nvol); + validatevolumename (nvol, def); xfree (p); return nvol; } @@ -524,15 +544,15 @@ static int set_filesys_unit_1 (int nr, struct uaedev_config_info *ci) } } - if (ci->controller) { - ui = &mountinfo.ui[nr]; - memset (ui, 0, sizeof (UnitInfo)); - memcpy (&ui->hf.ci, &c, sizeof (struct uaedev_config_info)); - ui->readonly = c.readonly; - ui->unit_type = -1; - ui->open = -1; - return nr; - } + if (ci->controller_type != HD_CONTROLLER_TYPE_UAE || ci->type == UAEDEV_TAPE) { + ui = &mountinfo.ui[nr]; + memset(ui, 0, sizeof(UnitInfo)); + memcpy(&ui->hf.ci, &c, sizeof(struct uaedev_config_info)); + ui->readonly = c.readonly; + ui->unit_type = -1; + ui->open = -1; + return nr; + } for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) { if (nr == i || !mountinfo.ui[i].open || mountinfo.ui[i].rootdir == NULL) @@ -553,7 +573,7 @@ static int set_filesys_unit_1 (int nr, struct uaedev_config_info *ci) if (set_filesys_volume (c.rootdir, &flags, &c.readonly, &emptydrive, &ui->zarchive) < 0) return -1; } - ui->volname = filesys_createvolname (c.volname, c.rootdir, _T("harddrive")); + ui->volname = filesys_createvolname(c.volname, c.rootdir, ui->zarchive, _T("harddrive")); ui->volflags = flags; } else { ui->unit_type = UNIT_FILESYSTEM; @@ -650,23 +670,23 @@ static int add_filesys_unit (struct uaedev_config_info *ci) return ret; } -int kill_filesys_unitconfig (struct uae_prefs *p, int nr) +int kill_filesys_unitconfig(struct uae_prefs *p, int nr) { struct uaedev_config_data *uci; - if (nr < 0) - return 0; - uci = getuci (p->mountconfig, nr); - hardfile_do_disk_change (uci, 0); - if (uci->configoffset >= 0 && uci->ci.controller == 0) - filesys_media_change (uci->ci.rootdir, 0, uci); - while (nr < MOUNT_CONFIG_SIZE) { - memmove (&p->mountconfig[nr], &p->mountconfig[nr + 1], sizeof (struct uaedev_config_data)); - nr++; - } - p->mountitems--; - memset (&p->mountconfig[MOUNT_CONFIG_SIZE - 1], 0, sizeof (struct uaedev_config_data)); - return 1; + if (nr < 0) + return 0; + uci = getuci(p->mountconfig, nr); + hardfile_do_disk_change(uci, 0); + if (uci->configoffset >= 0 && uci->ci.controller_type == HD_CONTROLLER_TYPE_UAE) + filesys_media_change(uci->ci.rootdir, 0, uci); + while (nr < MOUNT_CONFIG_SIZE) { + memmove(&p->mountconfig[nr], &p->mountconfig[nr + 1], sizeof(struct uaedev_config_data)); + nr++; + } + p->mountitems--; + memset(&p->mountconfig[MOUNT_CONFIG_SIZE - 1], 0, sizeof(struct uaedev_config_data)); + return 1; } int move_filesys_unitconfig (struct uae_prefs *p, int nr, int to) @@ -708,14 +728,14 @@ static void initialize_mountinfo(void) UnitInfo *uip = &mountinfo.ui[0]; for (nr = 0; nr < currprefs.mountitems; nr++) { - struct uaedev_config_data *uci = &currprefs.mountconfig[nr]; - if (uci->ci.controller == HD_CONTROLLER_UAE && (uci->ci.type == UAEDEV_DIR || uci->ci.type == UAEDEV_HDF)) { - struct uaedev_config_info ci; - memcpy (&ci, &uci->ci, sizeof (struct uaedev_config_info)); - ci.flags = MYVOLUMEINFO_REUSABLE; - int idx = set_filesys_unit_1 (-1, &ci); - allocuci (&currprefs, nr, idx); - } + struct uaedev_config_data *uci = &currprefs.mountconfig[nr]; + if (uci->ci.controller_type == HD_CONTROLLER_TYPE_UAE && (uci->ci.type == UAEDEV_DIR || uci->ci.type == UAEDEV_HDF)) { + struct uaedev_config_info ci; + memcpy(&ci, &uci->ci, sizeof(struct uaedev_config_info)); + ci.flags = MYVOLUMEINFO_REUSABLE; + int idx = set_filesys_unit_1(-1, &ci); + allocuci(&currprefs, nr, idx); + } } } @@ -1494,7 +1514,7 @@ static uae_u32 filesys_media_change_reply (TrapContext *ctx, int mode) if (emptydrive) return 0; xfree (u->ui.volname); - ui->volname = u->ui.volname = filesys_createvolname (u->mount_volume, u->mount_rootdir, _T("removable")); + ui->volname = u->ui.volname = filesys_createvolname(u->mount_volume, u->mount_rootdir, u->zarchive, _T("removable")); #ifdef RETROPLATFORM rp_harddrive_image_change (nr, u->mount_readonly, u->mount_rootdir); #endif @@ -1580,8 +1600,9 @@ int filesys_media_change (const TCHAR *rootdir, int inserted, struct uaedev_conf if (uci) { volptr = my_strdup (uci->ci.volname); } else { - volname[0] = 0; - target_get_volume_name (&mountinfo, rootdir, volname, MAX_DPATH, 1, 0); + struct uaedev_config_info ci2 = { 0 }; + _tcscpy(ci2.rootdir, rootdir); + target_get_volume_name(&mountinfo, &ci2, 1, 0, -1); volptr = volname; if (!volname[0]) volptr = NULL; @@ -1591,7 +1612,7 @@ int filesys_media_change (const TCHAR *rootdir, int inserted, struct uaedev_conf } } if (!volptr) { - volptr = filesys_createvolname (NULL, rootdir, _T("removable")); + volptr = filesys_createvolname(NULL, rootdir, NULL, _T("removable")); _tcscpy (volname, volptr); xfree (volptr); volptr = volname; @@ -5890,12 +5911,15 @@ error2: static void init_filesys_diagentry (void) { - do_put_mem_long ((uae_u32 *)(filesysory + 0x2100), EXPANSION_explibname); - do_put_mem_long ((uae_u32 *)(filesysory + 0x2104), filesys_configdev); - do_put_mem_long ((uae_u32 *)(filesysory + 0x2108), EXPANSION_doslibname); - do_put_mem_word ((uae_u16 *)(filesysory + 0x210e), nr_units()); - do_put_mem_word ((uae_u16 *)(filesysory + 0x210c), 0); - native2amiga_startup(); + put_long_host(baseaddr + 0x2100, EXPANSION_explibname); + put_long_host(baseaddr + 0x2104, filesys_configdev); + put_long_host(baseaddr + 0x2108, EXPANSION_doslibname); + put_word_host(baseaddr + 0x210c, 0); + put_word_host(baseaddr + 0x210e, nr_units()); + put_word_host(baseaddr + 0x2110, 0); + put_word_host(baseaddr + 0x2112, 1 | (currprefs.uae_hide_autoconfig || currprefs.uaeboard > 1 ? 16 : 0)); + + native2amiga_startup(); } void filesys_start_threads (void) @@ -6940,8 +6964,9 @@ void filesys_vsync (void) { Unit *u; - if (!uae_boot_rom) - return; + if (uae_boot_rom_type <= 0) + return; + if (heartbeat == get_long (rtarea_base + RTAREA_HEARTBEAT)) { if (heartbeat_count > 0) heartbeat_count--; @@ -7049,75 +7074,80 @@ void filesys_install (void) org (loop); } +uaecptr filesys_get_entry(int index) +{ + return bootrom_start + dlg(bootrom_start + bootrom_header + index * 4 - 4) + bootrom_header - 4; +} + void filesys_install_code (void) { - uae_u32 a, b, items; + uae_u32 b, items; - bootrom_header = 3 * 4; - align(4); - a = here (); - #include "filesys_bootrom.cpp" + bootrom_header = 3 * 4; + align(4); + bootrom_start = here(); +#include "filesys_bootrom.cpp" - items = dlg (a + 8) & 0xffff; - /* The last offset comes from the code itself, look for it near the top. */ - EXPANSION_bootcode = a + bootrom_header + items * 4 - 4; - b = a + bootrom_header + 3 * 4 - 4; - filesys_initcode = a + dlg (b) + bootrom_header - 4; + items = dlg(bootrom_start + 8) & 0xffff; + /* The last offset comes from the code itself, look for it near the top. */ + EXPANSION_bootcode = bootrom_start + bootrom_header + items * 4 - 4; + b = bootrom_start + bootrom_header + 3 * 4 - 4; + filesys_initcode = bootrom_start + dlg(b) + bootrom_header - 4; } -static uae_u8 *restore_filesys_hardfile (UnitInfo *ui, uae_u8 *src) +static uae_u8 *restore_filesys_hardfile(UnitInfo *ui, uae_u8 *src) { - struct hardfiledata *hfd = &ui->hf; - TCHAR *s; + struct hardfiledata *hfd = &ui->hf; + TCHAR *s; - hfd->virtsize = restore_u64(); - hfd->offset = restore_u64(); - hfd->ci.highcyl = restore_u32 (); - hfd->ci.sectors = restore_u32 (); - hfd->ci.surfaces = restore_u32 (); - hfd->ci.reserved = restore_u32 (); - hfd->ci.blocksize = restore_u32 (); - hfd->ci.readonly = restore_u32 () != 0; - hfd->flags = restore_u32(); - hfd->rdbcylinders = restore_u32 (); - hfd->rdbsectors = restore_u32 (); - hfd->rdbheads = restore_u32 (); - s = restore_string(); - _tcscpy (hfd->vendor_id, s); - xfree(s); - s = restore_string(); - _tcscpy (hfd->product_id, s); - xfree(s); - s = restore_string(); - _tcscpy (hfd->product_rev, s); - xfree(s); - s = restore_string(); - _tcscpy (hfd->device_name, s); - xfree(s); - return src; + hfd->virtsize = restore_u64(); + hfd->offset = restore_u64(); + hfd->ci.highcyl = restore_u32(); + hfd->ci.sectors = restore_u32(); + hfd->ci.surfaces = restore_u32(); + hfd->ci.reserved = restore_u32(); + hfd->ci.blocksize = restore_u32(); + hfd->ci.readonly = restore_u32() != 0; + hfd->flags = restore_u32(); + hfd->rdbcylinders = restore_u32(); + hfd->rdbsectors = restore_u32(); + hfd->rdbheads = restore_u32(); + s = restore_string(); + _tcscpy(hfd->vendor_id, s); + xfree(s); + s = restore_string(); + _tcscpy(hfd->product_id, s); + xfree(s); + s = restore_string(); + _tcscpy(hfd->product_rev, s); + xfree(s); + s = restore_string(); + _tcscpy(hfd->ci.devname, s); + xfree(s); + return src; } -static uae_u8 *save_filesys_hardfile (UnitInfo *ui, uae_u8 *dst) +static uae_u8 *save_filesys_hardfile(UnitInfo *ui, uae_u8 *dst) { - struct hardfiledata *hfd = &ui->hf; + struct hardfiledata *hfd = &ui->hf; - save_u64 (hfd->virtsize); - save_u64 (hfd->offset); - save_u32 (hfd->ci.highcyl); - save_u32 (hfd->ci.sectors); - save_u32 (hfd->ci.surfaces); - save_u32 (hfd->ci.reserved); - save_u32 (hfd->ci.blocksize); - save_u32 (hfd->ci.readonly); - save_u32 (hfd->flags); - save_u32 (hfd->rdbcylinders); - save_u32 (hfd->rdbsectors); - save_u32 (hfd->rdbheads); - save_string (hfd->vendor_id); - save_string (hfd->product_id); - save_string (hfd->product_rev); - save_string (hfd->device_name); - return dst; + save_u64(hfd->virtsize); + save_u64(hfd->offset); + save_u32(hfd->ci.highcyl); + save_u32(hfd->ci.sectors); + save_u32(hfd->ci.surfaces); + save_u32(hfd->ci.reserved); + save_u32(hfd->ci.blocksize); + save_u32(hfd->ci.readonly); + save_u32(hfd->flags); + save_u32(hfd->rdbcylinders); + save_u32(hfd->rdbsectors); + save_u32(hfd->rdbheads); + save_string(hfd->vendor_id); + save_string(hfd->product_id); + save_string(hfd->product_rev); + save_string(hfd->ci.devname); + return dst; } static a_inode *restore_filesys_get_base (Unit *u, TCHAR *npath) diff --git a/src/genblitter.cpp b/src/genblitter.cpp index 7db91813..5ba6dc63 100644 --- a/src/genblitter.cpp +++ b/src/genblitter.cpp @@ -1,11 +1,11 @@ -/* - * UAE - The Un*x Amiga Emulator - * - * Optimized blitter minterm function generator - * - * Copyright 1995,1996 Bernd Schmidt - * Copyright 1996 Alessandro Bissacco - */ + /* + * UAE - The Un*x Amiga Emulator + * + * Optimized blitter minterm function generator + * + * Copyright 1995,1996 Bernd Schmidt + * Copyright 1996 Alessandro Bissacco + */ #include "sysconfig.h" #include @@ -15,8 +15,7 @@ /* Here is the minterm table used in blitter function generation */ -static unsigned char blttbl[]= -{ +static unsigned char blttbl[]= { 0x00, 0x0a, 0x2a, 0x30, 0x3a, 0x3c, 0x4a, 0x6a, 0x8a, 0x8c, 0x9a, 0xa8, 0xaa, 0xb1, 0xca, 0xcc, 0xd8, 0xe2, 0xea, 0xf0, 0xfa, 0xfc }; @@ -24,11 +23,10 @@ static unsigned char blttbl[]= static void generate_include(void) { int minterm; - printf("STATIC_INLINE uae_u32 blit_func(const uae_u32 srca, const uae_u32 srcb, const uae_u32 srcc, const uae_u8 mt)\n{\nswitch(mt){\n"); - for (minterm = 0; minterm < 256; minterm++) - { - printf("case 0x%x:\n", minterm); - printf("\treturn %s;\n", blitops[minterm].s); + printf("STATIC_INLINE uae_u32 blit_func(uae_u32 srca, uae_u32 srcb, uae_u32 srcc, uae_u8 mt)\n{\nswitch(mt){\n"); + for (minterm = 0; minterm < 256; minterm++) { + printf("case 0x%x:\n", minterm); + printf("\treturn %s;\n", blitops[minterm].s); } printf("}\n"); printf("return 0;\n"); /* No, sir, it doesn't! */ @@ -46,163 +44,162 @@ static void generate_func(void) printf("#include \"blitter.h\"\n"); printf("#include \"blitfunc.h\"\n\n"); - for (i = 0; i < sizeof(blttbl); i++) - { - int active = blitops[blttbl[i]].used; - int a_is_on = active & 1, b_is_on = active & 2, c_is_on = active & 4; - printf("void blitdofast_%x (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b)\n",blttbl[i]); - printf("{\n"); - printf("int i,j;\n"); - printf("uae_u32 totald = 0;\n"); + for (i = 0; i < sizeof(blttbl); i++) { + int active = blitops[blttbl[i]].used; + int a_is_on = active & 1, b_is_on = active & 2, c_is_on = active & 4; + printf("void blitdofast_%x (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b)\n",blttbl[i]); + printf("{\n"); + printf("int i,j;\n"); + printf("uae_u32 totald = 0;\n"); #if 0 - printf("if (currprefs.blits_32bit_enabled && b->hblitsize > 1"); - if (a_is_on) printf(" && !b->blitashift && b->bltafwm==0xffff && b->bltalwm==0xffff"); - if (b_is_on) printf(" && !b->blitbshift"); - printf(") {\n"); - if (a_is_on) printf("uae_u32 srca=((uae_u32)b->bltadat << 16) | b->bltadat;\n"); - if (b_is_on) printf("uae_u32 srcb=((uae_u32)b->bltbdat << 16) | b->bltbdat;\n"); - if (c_is_on) printf("uae_u32 srcc=((uae_u32)b->bltcdat << 16) | b->bltcdat;\n"); - printf("uae_u32 dest;\n"); - printf("int count=b->hblitsize/2, oddword=b->hblitsize&1;\n"); - printf("for (j=0;jvblitsize;j++) {\n"); - printf("\tfor(i=0;ibltamod;\n"); - if (b_is_on) printf("\tif (ptb) ptb += b->bltbmod;\n"); - if (c_is_on) printf("\tif (ptc) ptc += b->bltcmod;\n"); - printf("\tif (ptd) ptd += b->bltdmod;\n"); - printf("}\n"); - if (a_is_on) printf("if (pta) b->bltadat = (*(pta-b->bltamod-2) << 8) | *(pta - b->bltamod - 1);\n"); /* Maybe not necessary, but I don't want problems */ - if (b_is_on) printf("if (ptb) b->bltbdat = (*(ptb-b->bltbmod-2) << 8) | *(ptb - b->bltbmod - 1);\n"); - if (c_is_on) printf("if (ptc) b->bltcdat = (*(ptc-b->bltcmod-2) << 8) | *(ptc - b->bltcmod - 1);\n"); - printf("if (ptd) b->bltddat = (*(ptd-b->bltdmod-2) << 8) | *(ptd - b->bltdmod - 1);\n"); + printf("if (currprefs.blits_32bit_enabled && b->hblitsize > 1"); + if (a_is_on) printf(" && !b->blitashift && b->bltafwm==0xffff && b->bltalwm==0xffff"); + if (b_is_on) printf(" && !b->blitbshift"); + printf(") {\n"); + if (a_is_on) printf("uae_u32 srca=((uae_u32)b->bltadat << 16) | b->bltadat;\n"); + if (b_is_on) printf("uae_u32 srcb=((uae_u32)b->bltbdat << 16) | b->bltbdat;\n"); + if (c_is_on) printf("uae_u32 srcc=((uae_u32)b->bltcdat << 16) | b->bltcdat;\n"); + printf("uae_u32 dest;\n"); + printf("int count=b->hblitsize/2, oddword=b->hblitsize&1;\n"); + printf("for (j=0;jvblitsize;j++) {\n"); + printf("\tfor(i=0;ibltamod;\n"); + if (b_is_on) printf("\tif (ptb) ptb += b->bltbmod;\n"); + if (c_is_on) printf("\tif (ptc) ptc += b->bltcmod;\n"); + printf("\tif (ptd) ptd += b->bltdmod;\n"); + printf("}\n"); + if (a_is_on) printf("if (pta) b->bltadat = (*(pta-b->bltamod-2) << 8) | *(pta - b->bltamod - 1);\n"); /* Maybe not necessary, but I don't want problems */ + if (b_is_on) printf("if (ptb) b->bltbdat = (*(ptb-b->bltbmod-2) << 8) | *(ptb - b->bltbmod - 1);\n"); + if (c_is_on) printf("if (ptc) b->bltcdat = (*(ptc-b->bltcmod-2) << 8) | *(ptc - b->bltcmod - 1);\n"); + printf("if (ptd) b->bltddat = (*(ptd-b->bltdmod-2) << 8) | *(ptd - b->bltdmod - 1);\n"); - printf("} else {\n"); + printf("} else {\n"); #endif - if (a_is_on) printf("uae_u32 preva = 0;\n"); - if (b_is_on) printf("uae_u32 prevb = 0, srcb = b->bltbhold;\n"); - if (c_is_on) printf("uae_u32 srcc = b->bltcdat;\n"); - printf("uae_u32 dstd=0;\n"); - printf("uaecptr dstp = 0;\n"); - printf("for (j = 0; j < b->vblitsize; j++) {\n"); - printf("\tfor (i = 0; i < b->hblitsize; i++) {\n\t\tuae_u32 bltadat, srca;\n\n"); - if (c_is_on) printf("\t\tif (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; }\n"); - if (b_is_on) printf("\t\tif (ptb) {\n\t\t\tuae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2;\n"); - if (b_is_on) printf("\t\t\tsrcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift;\n"); - if (b_is_on) printf("\t\t\tprevb = bltbdat;\n\t\t}\n"); - if (a_is_on) printf("\t\tif (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; }\n"); - if (a_is_on) printf("\t\tbltadat &= blit_masktable[i];\n"); - if (a_is_on) printf("\t\tsrca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift;\n"); - if (a_is_on) printf("\t\tpreva = bltadat;\n"); - printf("\t\tif (dstp) chipmem_wput_indirect (dstp, dstd);\n"); - printf("\t\tdstd = (%s) & 0xFFFF;\n", blitops[blttbl[i]].s); - printf("\t\ttotald |= dstd;\n"); - printf("\t\tif (ptd) { dstp = ptd; ptd += 2; }\n"); - printf("\t}\n"); - if (a_is_on) printf("\tif (pta) pta += b->bltamod;\n"); - if (b_is_on) printf("\tif (ptb) ptb += b->bltbmod;\n"); - if (c_is_on) printf("\tif (ptc) ptc += b->bltcmod;\n"); - printf("\tif (ptd) ptd += b->bltdmod;\n"); - printf("}\n"); - if (b_is_on) printf("b->bltbhold = srcb;\n"); - if (c_is_on) printf("b->bltcdat = srcc;\n"); - printf("\t\tif (dstp) chipmem_wput_indirect (dstp, dstd);\n"); + if (a_is_on) printf("uae_u32 preva = 0;\n"); + if (b_is_on) printf("uae_u32 prevb = 0, srcb = b->bltbhold;\n"); + if (c_is_on) printf("uae_u32 srcc = b->bltcdat;\n"); + printf("uae_u32 dstd=0;\n"); + printf("uaecptr dstp = 0;\n"); + printf("for (j = 0; j < b->vblitsize; j++) {\n"); + printf("\tfor (i = 0; i < b->hblitsize; i++) {\n\t\tuae_u32 bltadat, srca;\n\n"); + if (c_is_on) printf("\t\tif (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; }\n"); + if (b_is_on) printf("\t\tif (ptb) {\n\t\t\tuae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2;\n"); + if (b_is_on) printf("\t\t\tsrcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift;\n"); + if (b_is_on) printf("\t\t\tprevb = bltbdat;\n\t\t}\n"); + if (a_is_on) printf("\t\tif (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; }\n"); + if (a_is_on) printf("\t\tbltadat &= blit_masktable[i];\n"); + if (a_is_on) printf("\t\tsrca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift;\n"); + if (a_is_on) printf("\t\tpreva = bltadat;\n"); + printf("\t\tif (dstp) chipmem_wput_indirect (dstp, dstd);\n"); + printf("\t\tdstd = (%s) & 0xFFFF;\n", blitops[blttbl[i]].s); + printf("\t\ttotald |= dstd;\n"); + printf("\t\tif (ptd) { dstp = ptd; ptd += 2; }\n"); + printf("\t}\n"); + if (a_is_on) printf("\tif (pta) pta += b->bltamod;\n"); + if (b_is_on) printf("\tif (ptb) ptb += b->bltbmod;\n"); + if (c_is_on) printf("\tif (ptc) ptc += b->bltcmod;\n"); + printf("\tif (ptd) ptd += b->bltdmod;\n"); + printf("}\n"); + if (b_is_on) printf("b->bltbhold = srcb;\n"); + if (c_is_on) printf("b->bltcdat = srcc;\n"); + printf("\t\tif (dstp) chipmem_wput_indirect (dstp, dstd);\n"); #if 0 - printf("}\n"); + printf("}\n"); #endif - printf("if (totald != 0) b->blitzero = 0;\n"); - printf("}\n"); + printf("if (totald != 0) b->blitzero = 0;\n"); + printf("}\n"); - printf("void blitdofast_desc_%x (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b)\n",blttbl[i]); - printf("{\n"); - printf("uae_u32 totald = 0;\n"); - printf("int i,j;\n"); + printf("void blitdofast_desc_%x (uaecptr pta, uaecptr ptb, uaecptr ptc, uaecptr ptd, struct bltinfo *b)\n",blttbl[i]); + printf("{\n"); + printf("uae_u32 totald = 0;\n"); + printf("int i,j;\n"); #if 0 - printf("if (currprefs.blits_32bit_enabled && b->hblitsize > 1"); - if (a_is_on) printf(" && !b->blitashift && b->bltafwm==0xffff && b->bltalwm==0xffff"); - if (b_is_on) printf(" && !b->blitbshift"); - printf(") {\n"); - if (a_is_on) printf("uae_u32 srca = ((uae_u32)b->bltadat << 16) | b->bltadat;\n"); - if (b_is_on) printf("uae_u32 srcb = ((uae_u32)b->bltbdat << 16) | b->bltbdat;\n"); - if (c_is_on) printf("uae_u32 srcc = ((uae_u32)b->bltcdat << 16) | b->bltcdat;\n"); - printf("uae_u32 dest;\n"); - printf("int count=b->hblitsize/2, oddword=b->hblitsize&1;\n"); - printf("for (j=0;jvblitsize;j++) {\n"); - printf("\tfor(i=0;ibltamod;\n"); - if (b_is_on) printf("\tif (ptb) ptb -= b->bltbmod;\n"); - if (c_is_on) printf("\tif (ptc) ptc -= b->bltcmod;\n"); - printf("\tif (ptd) ptd-=b->bltdmod;\n"); - printf("}\n"); - if (a_is_on) printf("if (pta) b->bltadat = (*(pta + b->bltamod + 2) << 8) | *(pta + b->bltamod + 1);\n"); /* Maybe not necessary, but I don't want problems */ - if (b_is_on) printf("if (ptb) b->bltbdat = (*(ptb + b->bltbmod + 2) << 8) | *(ptb + b->bltbmod + 1);\n"); - if (c_is_on) printf("if (ptc) b->bltcdat = (*(ptc + b->bltcmod + 2) << 8) | *(ptc + b->bltcmod + 1);\n"); - printf("if (ptd) b->bltddat = (*(ptd + b->bltdmod + 2) << 8) | *(ptd + b->bltdmod + 1);\n"); + printf("if (currprefs.blits_32bit_enabled && b->hblitsize > 1"); + if (a_is_on) printf(" && !b->blitashift && b->bltafwm==0xffff && b->bltalwm==0xffff"); + if (b_is_on) printf(" && !b->blitbshift"); + printf(") {\n"); + if (a_is_on) printf("uae_u32 srca = ((uae_u32)b->bltadat << 16) | b->bltadat;\n"); + if (b_is_on) printf("uae_u32 srcb = ((uae_u32)b->bltbdat << 16) | b->bltbdat;\n"); + if (c_is_on) printf("uae_u32 srcc = ((uae_u32)b->bltcdat << 16) | b->bltcdat;\n"); + printf("uae_u32 dest;\n"); + printf("int count=b->hblitsize/2, oddword=b->hblitsize&1;\n"); + printf("for (j=0;jvblitsize;j++) {\n"); + printf("\tfor(i=0;ibltamod;\n"); + if (b_is_on) printf("\tif (ptb) ptb -= b->bltbmod;\n"); + if (c_is_on) printf("\tif (ptc) ptc -= b->bltcmod;\n"); + printf("\tif (ptd) ptd-=b->bltdmod;\n"); + printf("}\n"); + if (a_is_on) printf("if (pta) b->bltadat = (*(pta + b->bltamod + 2) << 8) | *(pta + b->bltamod + 1);\n"); /* Maybe not necessary, but I don't want problems */ + if (b_is_on) printf("if (ptb) b->bltbdat = (*(ptb + b->bltbmod + 2) << 8) | *(ptb + b->bltbmod + 1);\n"); + if (c_is_on) printf("if (ptc) b->bltcdat = (*(ptc + b->bltcmod + 2) << 8) | *(ptc + b->bltcmod + 1);\n"); + printf("if (ptd) b->bltddat = (*(ptd + b->bltdmod + 2) << 8) | *(ptd + b->bltdmod + 1);\n"); - printf("} else {\n"); + printf("} else {\n"); #endif - if (a_is_on) printf("uae_u32 preva = 0;\n"); - if (b_is_on) printf("uae_u32 prevb = 0, srcb = b->bltbhold;\n"); - if (c_is_on) printf("uae_u32 srcc = b->bltcdat;\n"); - printf("uae_u32 dstd=0;\n"); - printf("uaecptr dstp = 0;\n"); - printf("for (j = 0; j < b->vblitsize; j++) {\n"); - printf("\tfor (i = 0; i < b->hblitsize; i++) {\n\t\tuae_u32 bltadat, srca;\n"); - if (c_is_on) printf("\t\tif (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; }\n"); - if (b_is_on) printf("\t\tif (ptb) {\n\t\t\tuae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2;\n"); - if (b_is_on) printf("\t\t\tsrcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift;\n"); - if (b_is_on) printf("\t\t\tprevb = bltbdat;\n\t\t}\n"); - if (a_is_on) printf("\t\tif (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; }\n"); - if (a_is_on) printf("\t\tbltadat &= blit_masktable[i];\n"); - if (a_is_on) printf("\t\tsrca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift;\n"); - if (a_is_on) printf("\t\tpreva = bltadat;\n"); - printf("\t\tif (dstp) chipmem_wput_indirect (dstp, dstd);\n"); - printf("\t\tdstd = (%s) & 0xFFFF;\n", blitops[blttbl[i]].s); - printf("\t\ttotald |= dstd;\n"); - printf("\t\tif (ptd) { dstp = ptd; ptd -= 2; }\n"); - printf("\t}\n"); - if (a_is_on) printf("\tif (pta) pta -= b->bltamod;\n"); - if (b_is_on) printf("\tif (ptb) ptb -= b->bltbmod;\n"); - if (c_is_on) printf("\tif (ptc) ptc -= b->bltcmod;\n"); - printf("\tif (ptd) ptd -= b->bltdmod;\n"); - printf("}\n"); - if (b_is_on) printf("b->bltbhold = srcb;\n"); - if (c_is_on) printf("b->bltcdat = srcc;\n"); - printf("\t\tif (dstp) chipmem_wput_indirect (dstp, dstd);\n"); + if (a_is_on) printf("uae_u32 preva = 0;\n"); + if (b_is_on) printf("uae_u32 prevb = 0, srcb = b->bltbhold;\n"); + if (c_is_on) printf("uae_u32 srcc = b->bltcdat;\n"); + printf("uae_u32 dstd = 0;\n"); + printf("uaecptr dstp = 0;\n"); + printf("for (j = 0; j < b->vblitsize; j++) {\n"); + printf("\tfor (i = 0; i < b->hblitsize; i++) {\n\t\tuae_u32 bltadat, srca;\n"); + if (c_is_on) printf("\t\tif (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; }\n"); + if (b_is_on) printf("\t\tif (ptb) {\n\t\t\tuae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2;\n"); + if (b_is_on) printf("\t\t\tsrcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift;\n"); + if (b_is_on) printf("\t\t\tprevb = bltbdat;\n\t\t}\n"); + if (a_is_on) printf("\t\tif (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; }\n"); + if (a_is_on) printf("\t\tbltadat &= blit_masktable[i];\n"); + if (a_is_on) printf("\t\tsrca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift;\n"); + if (a_is_on) printf("\t\tpreva = bltadat;\n"); + printf("\t\tif (dstp) chipmem_wput_indirect (dstp, dstd);\n"); + printf("\t\tdstd = (%s) & 0xFFFF;\n", blitops[blttbl[i]].s); + printf("\t\ttotald |= dstd;\n"); + printf("\t\tif (ptd) { dstp = ptd; ptd -= 2; }\n"); + printf("\t}\n"); + if (a_is_on) printf("\tif (pta) pta -= b->bltamod;\n"); + if (b_is_on) printf("\tif (ptb) ptb -= b->bltbmod;\n"); + if (c_is_on) printf("\tif (ptc) ptc -= b->bltcmod;\n"); + printf("\tif (ptd) ptd -= b->bltdmod;\n"); + printf("}\n"); + if (b_is_on) printf("b->bltbhold = srcb;\n"); + if (c_is_on) printf("b->bltcdat = srcc;\n"); + printf("\t\tif (dstp) chipmem_wput_indirect (dstp, dstd);\n"); #if 0 - printf("}\n"); + printf("}\n"); #endif - printf("if (totald != 0) b->blitzero = 0;\n"); - printf("}\n"); + printf("if (totald != 0) b->blitzero = 0;\n"); + printf("}\n"); } } @@ -218,31 +215,27 @@ static void generate_table(void) printf("#include \"blitter.h\"\n"); printf("#include \"blitfunc.h\"\n\n"); printf("blitter_func * const blitfunc_dofast[256] = {\n"); - for (i = 0; i < 256; i++) - { - if (index < sizeof(blttbl) && i == blttbl[index]) - { - printf("blitdofast_%x",i); - index++; - } - else printf("0"); - if (i < 255) printf(", "); - if ((i & 7) == 7) printf("\n"); + for (i = 0; i < 256; i++) { + if (index < sizeof(blttbl) && i == blttbl[index]) { + printf("blitdofast_%x",i); + index++; + } + else printf("0"); + if (i < 255) printf(", "); + if ((i & 7) == 7) printf("\n"); } printf("};\n\n"); index = 0; printf("blitter_func * const blitfunc_dofast_desc[256] = {\n"); - for (i = 0; i < 256; i++) - { - if (index < sizeof(blttbl) && i == blttbl[index]) - { - printf("blitdofast_desc_%x",i); - index++; - } - else printf("0"); - if (i < 255) printf(", "); - if ((i & 7) == 7) printf("\n"); + for (i = 0; i < 256; i++) { + if (index < sizeof(blttbl) && i == blttbl[index]) { + printf("blitdofast_desc_%x",i); + index++; + } + else printf("0"); + if (i < 255) printf(", "); + if ((i & 7) == 7) printf("\n"); } printf("};\n"); } @@ -250,10 +243,9 @@ static void generate_table(void) static void generate_header(void) { unsigned int i; - for (i = 0; i < sizeof(blttbl); i++) - { - printf("extern blitter_func blitdofast_%x;\n",blttbl[i]); - printf("extern blitter_func blitdofast_desc_%x;\n",blttbl[i]); + for (i = 0; i < sizeof(blttbl); i++) { + printf("extern blitter_func blitdofast_%x;\n",blttbl[i]); + printf("extern blitter_func blitdofast_desc_%x;\n",blttbl[i]); } } @@ -262,22 +254,16 @@ int main(int argc, char **argv) char mode = 'i'; if (argc == 2) mode = *argv[1]; - switch (mode) - { - case 'i': - generate_include(); - break; - case 'f': - generate_func(); - break; - case 't': - generate_table(); - break; - case 'h': - generate_header(); - break; - default: - abort(); + switch (mode) { + case 'i': generate_include(); + break; + case 'f': generate_func(); + break; + case 't': generate_table(); + break; + case 'h': generate_header(); + break; + default: abort(); } return 0; } diff --git a/src/genlinetoscr.cpp b/src/genlinetoscr.cpp new file mode 100644 index 00000000..5ad25657 --- /dev/null +++ b/src/genlinetoscr.cpp @@ -0,0 +1,605 @@ +/* +* E-UAE - The portable Amiga Emulator +* +* Generate pixel output code. +* +* (c) 2006 Richard Drummond +*/ + +#include "sysconfig.h" +#include "sysdeps.h" + +#include +#include +#include + +/* Output for big-endian target if true, little-endian is false. */ +int do_bigendian; + +typedef int DEPTH_T; + +#define DEPTH_8BPP 0 +#define DEPTH_16BPP 1 +#define DEPTH_32BPP 2 +#define DEPTH_MAX DEPTH_32BPP + +static const char *get_depth_str (DEPTH_T bpp) +{ + if (bpp == DEPTH_8BPP) + return "8"; + else if (bpp == DEPTH_16BPP) + return "16"; + else + return "32"; +} + +static const char *get_depth_type_str (DEPTH_T bpp) +{ + if (bpp == DEPTH_8BPP) + return "uae_u8"; + else if (bpp == DEPTH_16BPP) + return "uae_u16"; + else + return "uae_u32"; +} + +typedef int HMODE_T; + +#define HMODE_NORMAL 0 +#define HMODE_DOUBLE 1 +#define HMODE_DOUBLE2X 2 +#define HMODE_HALVE1 3 +#define HMODE_HALVE1F 4 +#define HMODE_HALVE2 5 +#define HMODE_HALVE2F 6 +#define HMODE_MAX HMODE_HALVE2F + +static const char *get_hmode_str (HMODE_T hmode) +{ + if (hmode == HMODE_DOUBLE) + return "_stretch1"; + else if (hmode == HMODE_DOUBLE2X) + return "_stretch2"; + else if (hmode == HMODE_HALVE1) + return "_shrink1"; + else if (hmode == HMODE_HALVE1F) + return "_shrink1f"; + else if (hmode == HMODE_HALVE2) + return "_shrink2"; + else if (hmode == HMODE_HALVE2F) + return "_shrink2f"; + else + return ""; +} + + +typedef enum +{ + CMODE_NORMAL, + CMODE_DUALPF, + CMODE_EXTRAHB, + CMODE_HAM +} CMODE_T; +#define CMODE_MAX CMODE_HAM + + +static FILE *outfile; +static unsigned int outfile_indent = 0; + +static void set_outfile (FILE *f) +{ + outfile = f; +} + +static int set_indent (int indent) +{ + int old_indent = outfile_indent; + outfile_indent = indent; + return old_indent; +} + +static void outindent(void) +{ + unsigned int i; + for (i = 0; i < outfile_indent; i++) + fputc(' ', outfile); +} + +static void outf(const char *s, ...) +{ + va_list ap; + va_start(ap, s); + vfprintf(outfile, s, ap); +} + +static void outln (const char *s) +{ + outindent(); + fprintf (outfile, "%s\n", s); +} + +static void outlnf (const char *s, ...) +{ + va_list ap; + outindent(); + va_start (ap, s); + vfprintf (outfile, s, ap); + fputc ('\n', outfile); +} + +static void out_linetoscr_decl (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, int genlock) +{ + outlnf ("static int NOINLINE linetoscr_%s%s%s%s%s(int spix, int dpix, int dpix_end)", + get_depth_str (bpp), + get_hmode_str (hmode), aga ? "_aga" : "", spr > 0 ? "_spr" : (spr < 0 ? "_spronly" : ""), genlock ? "_genlock" : ""); +} + +static void out_linetoscr_do_srcpix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE_T cmode, int spr) +{ + if (spr < 0) { + outln ( " sprpix_val = 0;"); + } else { + if (aga && cmode != CMODE_DUALPF) { + if (spr) + outln ( " sprpix_val = pixdata.apixels[spix];"); + if (cmode != CMODE_HAM) + outln ( " spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val;"); + } else if (cmode != CMODE_HAM) { + outln ( " spix_val = pixdata.apixels[spix];"); + if (spr) + outln ( " sprpix_val = spix_val;"); + } + } +} + +static void out_linetoscr_do_dstpix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE_T cmode, int spr) +{ + if (spr < 0) + return; + if (aga && cmode == CMODE_HAM) { + outln ( " spix_val = ham_linebuf[spix];"); + outln ( " dpix_val = CONVERT_RGB (spix_val);"); + } else if (cmode == CMODE_HAM) { + outln ( " spix_val = ham_linebuf[spix];"); + outln ( " dpix_val = p_xcolors[spix_val];"); + if (spr) + outln ( " sprpix_val = pixdata.apixels[spix];"); + } else if (aga && cmode == CMODE_DUALPF) { + outln ( " {"); + outln ( " uae_u8 val = lookup[spix_val];"); + outln ( " if (lookup_no[spix_val])"); + outln ( " val += dblpfofs[bpldualpf2of];"); + outln ( " val ^= xor_val;"); + outln ( " dpix_val = p_acolors[val];"); + outln ( " }"); + } else if (cmode == CMODE_DUALPF) { + outln ( " dpix_val = p_acolors[lookup[spix_val]];"); + } else if (aga && cmode == CMODE_EXTRAHB) { + outln ( " if (pixdata.apixels[spix] & 0x20) {"); + outln ( " unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F;"); + outln ( " dpix_val = CONVERT_RGB (c);"); + outln ( " } else"); + outln ( " dpix_val = p_acolors[spix_val];"); + } else if (cmode == CMODE_EXTRAHB) { + outln ( " if (spix_val <= 31)"); + outln ( " dpix_val = p_acolors[spix_val];"); + outln ( " else"); + outln ( " dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777];"); + } else + outln ( " dpix_val = p_acolors[spix_val];"); +} + +static void out_linetoscr_do_incspix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE_T cmode, int spr) +{ + if (spr < 0) { + outln(" spix++;"); + return; + } + if (hmode == HMODE_HALVE1F) { + outln ( " {"); + outln ( " uae_u32 tmp_val;"); + outln ( " spix++;"); + outln ( " tmp_val = dpix_val;"); + out_linetoscr_do_srcpix (bpp, hmode, aga, cmode, spr); + out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr); + outlnf ( " dpix_val = merge_2pixel%d (dpix_val, tmp_val);", bpp == 0 ? 8 : bpp == 1 ? 16 : 32); + outln ( " spix++;"); + outln ( " }"); + } else if (hmode == HMODE_HALVE2F) { + outln ( " {"); + outln ( " uae_u32 tmp_val, tmp_val2, tmp_val3;"); + outln ( " spix++;"); + outln ( " tmp_val = dpix_val;"); + out_linetoscr_do_srcpix (bpp, hmode, aga, cmode, spr); + out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr); + outln ( " spix++;"); + outln ( " tmp_val2 = dpix_val;"); + out_linetoscr_do_srcpix (bpp, hmode, aga, cmode, spr); + out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr); + outln ( " spix++;"); + outln ( " tmp_val3 = dpix_val;"); + out_linetoscr_do_srcpix (bpp, hmode, aga, cmode, spr); + out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr); + outlnf ( " tmp_val = merge_2pixel%d (tmp_val, tmp_val2);", bpp == 0 ? 8 : bpp == 1 ? 16 : 32); + outlnf ( " tmp_val2 = merge_2pixel%d (tmp_val3, dpix_val);", bpp == 0 ? 8 : bpp == 1 ? 16 : 32); + outlnf ( " dpix_val = merge_2pixel%d (tmp_val, tmp_val2);", bpp == 0 ? 8 : bpp == 1 ? 16 : 32); + outln ( " spix++;"); + outln ( " }"); + } else if (hmode == HMODE_HALVE1) { + outln ( " spix += 2;"); + } else if (hmode == HMODE_HALVE2) { + outln ( " spix += 4;"); + } else { + outln ( " spix++;"); + } +} + +static void put_dpixsprgenlock(int offset, int genlock) +{ + if (!genlock) + return; + if (offset) + outlnf(" genlock_buf[dpix + %d] = get_genlock_transparency(sprcol);", offset); + else + outlnf(" genlock_buf[dpix] = get_genlock_transparency(sprcol);"); +} + +static void put_dpixgenlock(int offset, CMODE_T cmode, int aga, int genlock, const char *var2) +{ + if (!genlock) + return; + outindent(); + if (offset) + outf(" genlock_buf[dpix + %d] = get_genlock_transparency(", offset); + else + outf(" genlock_buf[dpix] = get_genlock_transparency("); + + if (genlock) { + if (cmode == CMODE_EXTRAHB) { + outf("%s", var2 ? var2 : "spix_val & 31"); + } + else if (cmode == CMODE_DUALPF) { + outf("%s", var2 ? var2 : "lookup[spix_val]"); + } + else if (cmode == CMODE_HAM) { + if (aga) { + outf("%s", var2 ? var2 : "(spix_val >> 2) & 63"); + } + else { + outf("%s", var2 ? var2 : "spix_val & 15"); + } + } + else { + outf("%s", var2 ? var2 : "spix_val"); + } + } + outf(");\n"); +} + +static void put_dpix (const char *var) +{ + outlnf(" buf[dpix++] = %s;", var); +} + +static void out_sprite (DEPTH_T bpp, HMODE_T hmode, CMODE_T cmode, int aga, int cnt, int spr, int genlock) +{ + if (aga) { + if (cnt == 1) { + outlnf ( " if (spritepixels[dpix].data) {"); + outlnf ( " sprcol = render_sprites (dpix + 0, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); + outlnf(" if (sprcol) {"); + outlnf ( " out_val = p_acolors[sprcol];"); + put_dpixsprgenlock(0, genlock); + outlnf(" }"); + outlnf(" }"); + put_dpix("out_val"); + } else if (cnt == 2) { + outlnf ( " {"); + outlnf ( " uae_u32 out_val1 = out_val;"); + outlnf ( " uae_u32 out_val2 = out_val;"); + outlnf(" if (spritepixels[dpix + 0].data) {"); + outlnf ( " sprcol = render_sprites (dpix + 0, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); + outlnf ( " if (sprcol) {"); + outlnf ( " out_val1 = p_acolors[sprcol];"); + put_dpixsprgenlock(0, genlock); + outlnf(" }"); + outlnf(" }"); + outlnf ( " if (spritepixels[dpix + 1].data) {"); + outlnf ( " sprcol = render_sprites (dpix + 1, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); + outlnf ( " if (sprcol) {"); + outlnf ( " out_val2 = p_acolors[sprcol];"); + put_dpixsprgenlock(1, genlock); + outlnf(" }"); + outlnf(" }"); + put_dpix("out_val1"); + put_dpix("out_val2"); + outlnf ( " }"); + } else if (cnt == 4) { + outlnf ( " {"); + outlnf ( " uae_u32 out_val1 = out_val;"); + outlnf ( " uae_u32 out_val2 = out_val;"); + outlnf ( " uae_u32 out_val3 = out_val;"); + outlnf ( " uae_u32 out_val4 = out_val;"); + outlnf(" if (spritepixels[dpix + 0].data) {"); + outlnf ( " sprcol = render_sprites (dpix + 0, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); + outlnf ( " if (sprcol) {"); + outlnf ( " out_val1 = p_acolors[sprcol];"); + put_dpixsprgenlock(0, genlock); + outlnf(" }"); + outlnf(" }"); + outlnf ( " if (spritepixels[dpix + 1].data) {"); + outlnf ( " sprcol = render_sprites (dpix + 1, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); + outlnf ( " if (sprcol) {"); + outlnf ( " out_val2 = p_acolors[sprcol];"); + put_dpixsprgenlock(1, genlock); + outlnf(" }"); + outlnf(" }"); + outlnf ( " if (spritepixels[dpix + 2].data) {"); + outlnf ( " sprcol = render_sprites (dpix + 2, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); + outlnf ( " if (sprcol) {"); + outlnf ( " out_val3 = p_acolors[sprcol];"); + put_dpixsprgenlock(2, genlock); + outlnf(" }"); + outlnf(" }"); + outlnf ( " if (spritepixels[dpix + 3].data) {"); + outlnf ( " sprcol = render_sprites (dpix + 3, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); + outlnf ( " if (sprcol) {"); + outlnf ( " out_val4 = p_acolors[sprcol];"); + put_dpixsprgenlock(3, genlock); + outlnf(" }"); + outlnf(" }"); + put_dpix("out_val1"); + put_dpix("out_val2"); + put_dpix("out_val3"); + put_dpix("out_val4"); + outlnf ( " }"); + } + } else { + outlnf ( " if (spritepixels[dpix].data) {"); + outlnf ( " sprcol = render_sprites (dpix, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); + put_dpixsprgenlock(0, genlock); + outlnf(" if (sprcol) {"); + outlnf ( " uae_u32 spcol = p_acolors[sprcol];"); + outlnf ( " out_val = spcol;"); + outlnf ( " }"); + outlnf ( " }"); + while (cnt-- > 0) + put_dpix("out_val"); + } +} + + +static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CMODE_T cmode, int genlock) +{ + int old_indent = set_indent (8); + + if (aga && cmode == CMODE_DUALPF) { + outln ( "int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga;"); + outln ( "int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1;"); + } else if (cmode == CMODE_DUALPF) + outln ( "int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1;"); + + if (bpp == DEPTH_16BPP && hmode != HMODE_DOUBLE && hmode != HMODE_DOUBLE2X && spr == 0) { + outln ( "int rem;"); + outln ( "if (((uintptr_t)&buf[dpix]) & 2) {"); + outln ( " uae_u32 spix_val;"); + outln ( " uae_u32 dpix_val;"); + + out_linetoscr_do_srcpix (bpp, hmode, aga, cmode, spr); + out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr); + out_linetoscr_do_incspix (bpp, hmode, aga, cmode, spr); + + put_dpix("dpix_val"); + outln ( "}"); + outln ( "if (dpix >= dpix_end)"); + outln ( " return spix;"); + outln ( "rem = (((uintptr_t)&buf[dpix_end]) & 2);"); + outln ( "if (rem)"); + outln ( " dpix_end--;"); + } + + outln ( "while (dpix < dpix_end) {"); + if (spr) + outln ( " uae_u32 sprpix_val;"); + if (spr >= 0) { + outln ( " uae_u32 spix_val;"); + outln ( " uae_u32 dpix_val;"); + } + outln ( " uae_u32 out_val;"); + outln ( ""); + + out_linetoscr_do_srcpix (bpp, hmode, aga, cmode, spr); + out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr); + out_linetoscr_do_incspix (bpp, hmode, aga, cmode, spr); + + if (spr >= 0) + outln ( " out_val = dpix_val;"); + else + outln ( " out_val = p_acolors[0];"); + + if (hmode == HMODE_DOUBLE) { + put_dpixgenlock(0, cmode, aga, genlock, NULL); + put_dpixgenlock(1, cmode, aga, genlock, NULL); + } else if (hmode == HMODE_DOUBLE2X) { + put_dpixgenlock(0, cmode, aga, genlock, NULL); + put_dpixgenlock(1, cmode, aga, genlock, NULL); + put_dpixgenlock(2, cmode, aga, genlock, NULL); + put_dpixgenlock(3, cmode, aga, genlock, NULL); + } else { + put_dpixgenlock(0, cmode, aga, genlock, NULL); + } + + if (hmode != HMODE_DOUBLE && hmode != HMODE_DOUBLE2X && bpp == DEPTH_16BPP && spr == 0) { + out_linetoscr_do_srcpix (bpp, hmode, aga, cmode, spr); + out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr); + out_linetoscr_do_incspix (bpp, hmode, aga, cmode, spr); + + if (do_bigendian) + outln ( " out_val = (out_val << 16) | (dpix_val & 0xFFFF);"); + else + outln ( " out_val = (out_val & 0xFFFF) | (dpix_val << 16);"); + } + + if (hmode == HMODE_DOUBLE) { + if (bpp == DEPTH_8BPP) { + outln ( " *((uae_u16 *)&buf[dpix]) = (uae_u16) out_val;"); + outln ( " dpix += 2;"); + } else if (bpp == DEPTH_16BPP) { + if (spr) { + out_sprite(bpp, hmode, cmode, aga, 2, spr, genlock); + } else { + outln ( " *((uae_u32 *)&buf[dpix]) = out_val;"); + outln ( " dpix += 2;"); + } + } else { + if (spr) { + out_sprite(bpp, hmode, cmode, aga, 2, spr, genlock); + } else { + put_dpix("out_val"); + put_dpix("out_val"); + } + } + } else if (hmode == HMODE_DOUBLE2X) { + if (bpp == DEPTH_8BPP) { + outln ( " *((uae_u32 *)&buf[dpix]) = (uae_u32) out_val;"); + outln ( " dpix += 4;"); + } else if (bpp == DEPTH_16BPP) { + if (spr) { + out_sprite(bpp, hmode, cmode, aga, 4, spr, genlock); + } else { + outln ( " *((uae_u32 *)&buf[dpix]) = out_val;"); + outln ( " dpix += 2;"); + outln ( " *((uae_u32 *)&buf[dpix]) = out_val;"); + outln ( " dpix += 2;"); + } + } else { + if (spr) { + out_sprite(bpp, hmode, cmode, aga, 4, spr, genlock); + } else { + put_dpix("out_val"); + put_dpix("out_val"); + put_dpix("out_val"); + put_dpix("out_val"); + } + } + } else { + if (bpp == DEPTH_16BPP) { + if (spr) { + out_sprite(bpp, hmode, cmode, aga, 1, spr, genlock); + } else { + outln ( " *((uae_u32 *)&buf[dpix]) = out_val;"); + outln ( " dpix += 2;"); + } + } else { + if (spr) { + out_sprite(bpp, hmode, cmode, aga, 1, spr, genlock); + } else { + put_dpix("out_val"); + } + } + } + + outln ( "}"); + + + if (bpp == DEPTH_16BPP && hmode != HMODE_DOUBLE && hmode != HMODE_DOUBLE2X && spr == 0) { + outln ( "if (rem) {"); + outln ( " uae_u32 spix_val;"); + outln ( " uae_u32 dpix_val;"); + + out_linetoscr_do_srcpix (bpp, hmode, aga, cmode, spr); + out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr); + out_linetoscr_do_incspix (bpp, hmode, aga, cmode, spr); + + put_dpix("dpix_val"); + outln ( "}"); + } + + set_indent (old_indent); + + return; +} + +static void out_linetoscr (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, int genlock) +{ + if (aga) + outln ("#ifdef AGA"); + + out_linetoscr_decl (bpp, hmode, aga, spr, genlock); + outln ( "{"); + + outlnf ( " %s *buf = (%s *) xlinebuffer;", get_depth_type_str (bpp), get_depth_type_str (bpp)); + if (genlock) + outlnf(" uae_u8 *genlock_buf = xlinebuffer_genlock;"); + if (spr) + outln ( " uae_u8 sprcol;"); + if (aga && spr >= 0) { + outln(" uae_u8 xor_val = bplxor;"); + outln(" uae_u8 and_val = bpland;"); + } + outln ( ""); + + if (spr >= 0) { + outln ( " if (bplham) {"); + out_linetoscr_mode(bpp, hmode, aga, spr, CMODE_HAM, genlock); + outln ( " } else if (bpldualpf) {"); + out_linetoscr_mode(bpp, hmode, aga, spr, CMODE_DUALPF, genlock); + outln ( " } else if (bplehb) {"); + out_linetoscr_mode(bpp, hmode, aga, spr, CMODE_EXTRAHB, genlock); + outln ( " } else {"); + out_linetoscr_mode(bpp, hmode, aga, spr, CMODE_NORMAL, genlock); + } else { + outln ( " if (1) {"); + out_linetoscr_mode(bpp, hmode, aga, spr, CMODE_NORMAL, genlock); + } + + outln ( " }\n"); + outln ( " return spix;"); + outln ( "}"); + + if (aga) + outln ( "#endif"); + outln ( ""); +} + +int main (int argc, char *argv[]) +{ + DEPTH_T bpp; + int aga, spr; + HMODE_T hmode; + + do_bigendian = 0; + + for (int i = 1; i < argc; i++) { + if (argv[i][0] != '-') + continue; + if (argv[i][1] == 'b' && argv[i][2] == '\0') + do_bigendian = 1; + } + + set_outfile (stdout); + + outln ("/*"); + outln (" * UAE - The portable Amiga emulator."); + outln (" *"); + outln (" * This file was generated by genlinetoscr. Don't edit."); + outln (" */"); + outln (""); + + for (bpp = DEPTH_16BPP; bpp <= DEPTH_MAX; bpp++) { + for (aga = 0; aga <= 1 ; aga++) { + if (aga && bpp == DEPTH_8BPP) + continue; + for (spr = -1; spr <= 1; spr++) { + if (!aga && spr < 0) + continue; + for (hmode = HMODE_NORMAL; hmode <= HMODE_MAX; hmode++) { + out_linetoscr(bpp, hmode, aga, spr, 0); + if (spr >= 0) + out_linetoscr(bpp, hmode, aga, spr, 1); + } + } + } + } + return 0; +} diff --git a/src/gfxboard.cpp b/src/gfxboard.cpp index 3af49b7f..0ef8fda8 100644 --- a/src/gfxboard.cpp +++ b/src/gfxboard.cpp @@ -31,3 +31,11 @@ bool gfxboard_is_z3 (int type) return false; } +const TCHAR *gfxboard_get_configname(int type) +{ + if (type == GFXBOARD_UAE_Z2) + return _T("ZorroII"); + if (type == GFXBOARD_UAE_Z3) + return _T("ZorroIII"); + //return boards[type - GFXBOARD_HARDWARE].configname; +} \ No newline at end of file diff --git a/src/gfxutil.cpp b/src/gfxutil.cpp index 2aa547bd..d743d022 100644 --- a/src/gfxutil.cpp +++ b/src/gfxutil.cpp @@ -15,7 +15,7 @@ double getvsyncrate(double hz, int *mult) { -// struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; + struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; if (hz < 0) return 0; @@ -24,9 +24,9 @@ double getvsyncrate(double hz, int *mult) return hz / 2; } if (hz < 35 && hz > 0) { -// if (ap->gfx_interlaced) -// *mult = 0; -// else + if (ap->gfx_interlaced) + *mult = 0; + else *mult = 1; return hz * 2; } @@ -42,16 +42,39 @@ unsigned int doMask (int p, int bits, int shift) { /* p is a value from 0 to 15 (Amiga color value) * scale to 0..255, shift to align msb with mask, and apply mask */ + uae_u32 val; - uae_u32 val = p * 0x11111111UL; - if (!bits) - return 0; - val >>= (32 - bits); - val <<= shift; + //uae_u32 val = p * 0x11111111UL; + val = p << 24; + if (!bits) + return 0; + val >>= (32 - bits); + val <<= shift; - return val; + return val; } +int bits_in_mask(unsigned long mask) +{ + int n = 0; + while (mask) { + n += mask & 1; + mask >>= 1; + } + return n; +} + +int mask_shift(unsigned long mask) +{ + int n = 0; + if (!mask) + return 0; + while (!(mask & 1)) { + n++; + mask >>= 1; + } + return n; +} unsigned int doMask256 (int p, int bits, int shift) { @@ -69,14 +92,135 @@ unsigned int doMask256 (int p, int bits, int shift) static unsigned int doColor(int i, int bits, int shift) { - int shift2; - if(bits >= 8) - shift2 = 0; - else - shift2 = 8 - bits; - return (i >> shift2) << shift; + int shift2; + + if (bits >= 8) + shift2 = 0; + else + shift2 = 8 - bits; + return (i >> shift2) << shift; } +static unsigned int doAlpha(int alpha, int bits, int shift) +{ + return (alpha & ((1 << bits) - 1)) << shift; +} + +static float video_gamma(float value, float gamma, float bri, float con) +{ + double factor; + float ret; + + value += bri; + value *= con; + + if (value <= 0.0f) + return 0.0f; + + factor = pow(255.0f, 1.0f - gamma); + ret = float(factor * pow(value, gamma)); + + if (ret < 0.0f) + ret = 0.0f; + + return ret; +} + +static uae_u32 Gamma[256 * 3][3]; +static int lf, hf; + +//static void video_calc_gammatable(void) +//{ +// float bri, con, gam, gams[3]; +// +// bri = ((float)(currprefs.gfx_luminance)) * (128.0f / 1000.0f); +// con = ((float)(currprefs.gfx_contrast + 1000)) / 1000.0f; +// gam = ((float)(1000 - currprefs.gfx_gamma)) / 1000.0f - 1.0; +// gams[0] = gam + ((float)(1000 - currprefs.gfx_gamma_ch[0])) / 1000.0f; +// gams[1] = gam + ((float)(1000 - currprefs.gfx_gamma_ch[1])) / 1000.0f; +// gams[2] = gam + ((float)(1000 - currprefs.gfx_gamma_ch[2])) / 1000.0f; +// +// lf = 64 * currprefs.gf[picasso_on].gfx_filter_blur / 1000; +// hf = 256 - lf * 2; +// +// for (int i = 0; i < (256 * 3); i++) { +// for (int j = 0; j < 3; j++) { +// float val = i - 256; +// float v; +// +// if (currprefs.gfx_threebitcolors == 2) { +// val *= 2; +// } +// else if (currprefs.gfx_threebitcolors == 3) { +// val = (val * 252.0) / 119.0; +// } +// else if (currprefs.gfx_threebitcolors == 1) { +// val = (val * 252.0) / 238.0; +// } +// +// if (currprefs.gfx_luminance == 0 && currprefs.gfx_contrast == 0 && currprefs.gfx_gamma == 0 && +// currprefs.gfx_gamma_ch[0] == 0 && currprefs.gfx_gamma_ch[1] == 0 && currprefs.gfx_gamma_ch[2] == 0) { +// v = val; +// } +// else { +// v = video_gamma(val, gams[j], bri, con); +// } +// +// if (v < 0.0) +// v = 0.0; +// if (v > 255.0) +// v = 255.0; +// +// gamma[i][j] = (uae_u32)(v + 0.5); +// } +// } +//} + +static uae_u32 limit256(double v) +{ + v = v * double(currprefs.gf[picasso_on].gfx_filter_contrast + 1000) / 1000.0 + currprefs.gf[picasso_on].gfx_filter_luminance / 10.0; + if (v < 0) + v = 0; + if (v > 255) + v = 255; + return uae_u32(v) & 0xff; +} +static uae_u32 limit256rb(double v) +{ + v *= double(currprefs.gf[picasso_on].gfx_filter_saturation + 1000) / 1000.0; + if (v < -128) + v = -128; + if (v > 127) + v = 127; + return uae_u32(v) & 0xff; +} +static double get_y(int r, int g, int b) +{ + return 0.2989f * r + 0.5866f * g + 0.1145f * b; +} +static uae_u32 get_yh(int r, int g, int b) +{ + return limit256(get_y(r, g, b) * hf / 256); +} +static uae_u32 get_yl(int r, int g, int b) +{ + return limit256(get_y(r, g, b) * lf / 256); +} +static uae_u32 get_cb(int r, int g, int b) +{ + return limit256rb(-0.168736f * r - 0.331264f * g + 0.5f * b); +} +static uae_u32 get_cr(int r, int g, int b) +{ + return limit256rb(0.5f * r - 0.418688f * g - 0.081312f * b); +} + +extern uae_s32 tyhrgb[65536]; +extern uae_s32 tylrgb[65536]; +extern uae_s32 tcbrgb[65536]; +extern uae_s32 tcrrgb[65536]; +extern uae_u32 redc[3 * 256], grec[3 * 256], bluc[3 * 256]; + static uae_u32 lowbits (int v, int shift, int lsize) { v >>= shift; @@ -84,15 +228,248 @@ static uae_u32 lowbits (int v, int shift, int lsize) return v; } -void alloc_colors64k (int rw, int gw, int bw, int rs, int gs, int bs, int byte_swap) +void alloc_colors_picasso(int rw, int gw, int bw, int rs, int gs, int bs, int rgbfmt) { +#ifdef PICASSO96 + int byte_swap = 0; int i; - for (i = 0; i < 4096; i++) { - int r = i >> 8; - int g = (i >> 4) & 0xf; - int b = i & 0xf; - xcolors[i] = doMask(r, rw, rs) | doMask(g, gw, gs) | doMask(b, bw, bs); + int red_bits = 0, green_bits, blue_bits; + int red_shift, green_shift, blue_shift; + int bpp = rw + gw + bw; + + switch (rgbfmt) + { + case RGBFB_R5G6B5PC: + red_bits = 5; + green_bits = 6; + blue_bits = 5; + red_shift = 11; + green_shift = 5; + blue_shift = 0; + break; + case RGBFB_R5G5B5PC: + red_bits = green_bits = blue_bits = 5; + red_shift = 10; + green_shift = 5; + blue_shift = 0; + break; + case RGBFB_R5G6B5: + red_bits = 5; + green_bits = 6; + blue_bits = 5; + red_shift = 11; + green_shift = 5; + blue_shift = 0; + byte_swap = 1; + break; + case RGBFB_R5G5B5: + red_bits = green_bits = blue_bits = 5; + red_shift = 10; + green_shift = 5; + blue_shift = 0; + byte_swap = 1; + break; + case RGBFB_B5G6R5PC: + red_bits = 5; + green_bits = 6; + blue_bits = 5; + red_shift = 0; + green_shift = 5; + blue_shift = 11; + break; + case RGBFB_B5G5R5PC: + red_bits = green_bits = blue_bits = 5; + red_shift = 0; + green_shift = 5; + blue_shift = 10; + break; + default: + red_bits = rw; + green_bits = gw; + blue_bits = bw; + red_shift = rs; + green_shift = gs; + blue_shift = bs; + break; } + +#ifdef WORDS_BIGENDIAN + byte_swap = !byte_swap; +#endif + + memset(p96_rgbx16, 0, sizeof p96_rgbx16); + + if (red_bits) { + int lrbits = 8 - red_bits; + int lgbits = 8 - green_bits; + int lbbits = 8 - blue_bits; + int lrmask = (1 << red_bits) - 1; + int lgmask = (1 << green_bits) - 1; + int lbmask = (1 << blue_bits) - 1; + for (i = 65535; i >= 0; i--) { + uae_u32 r, g, b, c; + uae_u32 j = byte_swap ? bswap_16(i) : i; + r = (((j >> red_shift) & lrmask) << lrbits) | lowbits(j, red_shift, lrbits); + g = (((j >> green_shift) & lgmask) << lgbits) | lowbits(j, green_shift, lgbits); + b = (((j >> blue_shift) & lbmask) << lbbits) | lowbits(j, blue_shift, lbbits); + c = doMask(r, rw, rs) | doMask(g, gw, gs) | doMask(b, bw, bs); + if (bpp <= 16) + c *= 0x00010001; + p96_rgbx16[i] = c; + } + } +#endif +} + +void alloc_colors_rgb(int rw, int gw, int bw, int rs, int gs, int bs, int aw, int as, int alpha, int byte_swap, + uae_u32 *rc, uae_u32 *gc, uae_u32 *bc) +{ + int bpp = rw + gw + bw + aw; + int i; + for (i = 0; i < 256; i++) { + int j; + + if (currprefs.gfx_blackerthanblack) { + j = i * 15 / 16 + 15; + } + else { + j = i; + } + j += 256; + + rc[i] = doColor(Gamma[j][0], rw, rs) | doAlpha(alpha, aw, as); + gc[i] = doColor(Gamma[j][1], gw, gs) | doAlpha(alpha, aw, as); + bc[i] = doColor(Gamma[j][2], bw, bs) | doAlpha(alpha, aw, as); + if (byte_swap) { + if (bpp <= 16) { + rc[i] = bswap_16(rc[i]); + gc[i] = bswap_16(gc[i]); + bc[i] = bswap_16(bc[i]); + } + else { + rc[i] = bswap_32(rc[i]); + gc[i] = bswap_32(gc[i]); + bc[i] = bswap_32(bc[i]); + } + } + if (bpp <= 16) { + /* Fill upper 16 bits of each colour value with + * a copy of the colour. */ + rc[i] = rc[i] * 0x00010001; + gc[i] = gc[i] * 0x00010001; + bc[i] = bc[i] * 0x00010001; + } + } +} + +void alloc_colors64k (int rw, int gw, int bw, int rs, int gs, int bs, int aw, int as, int alpha, int byte_swap) +{ + int bpp = rw + gw + bw + aw; + int i, j; + + //video_calc_gammatable(); + j = 256; + for (i = 0; i < 4096; i++) { + int r = ((i >> 8) << 4) | (i >> 8); + int g = (((i >> 4) & 0xf) << 4) | ((i >> 4) & 0x0f); + int b = ((i & 0xf) << 4) | (i & 0x0f); + r = Gamma[r + j][0]; + g = Gamma[g + j][1]; + b = Gamma[b + j][2]; + xcolors[i] = doMask(r, rw, rs) | doMask(g, gw, gs) | doMask(b, bw, bs) | doAlpha(alpha, aw, as); + if (byte_swap) { + if (bpp <= 16) { + xcolors[i] = bswap_16(xcolors[i]); + } + else { + xcolors[i] = bswap_32(xcolors[i]); + } + } + if (bpp <= 16) { + /* Fill upper 16 bits of each colour value + * with a copy of the colour. */ + xcolors[i] |= xcolors[i] * 0x00010001; + } + } +#if defined(AGA) || defined(GFXFILTER) + alloc_colors_rgb(rw, gw, bw, rs, gs, bs, aw, as, alpha, byte_swap, xredcolors, xgreencolors, xbluecolors); + /* copy original color table */ + //for (i = 0; i < 256; i++) { + // redc[0 * 256 + i] = xredcolors[0]; + // grec[0 * 256 + i] = xgreencolors[0]; + // bluc[0 * 256 + i] = xbluecolors[0]; + // redc[1 * 256 + i] = xredcolors[i]; + // grec[1 * 256 + i] = xgreencolors[i]; + // bluc[1 * 256 + i] = xbluecolors[i]; + // redc[2 * 256 + i] = xredcolors[255]; + // grec[2 * 256 + i] = xgreencolors[255]; + // bluc[2 * 256 + i] = xbluecolors[255]; + //} +#ifdef GFXFILTER + if (usedfilter && usedfilter->yuv) { + /* create internal 5:6:5 color tables */ + for (i = 0; i < 256; i++) { + j = i + 256; + xredcolors[i] = doColor(gamma[j][0], 5, 11); + xgreencolors[i] = doColor(gamma[j][1], 6, 5); + xbluecolors[i] = doColor(gamma[j][2], 5, 0); + if (bpp <= 16) { + /* Fill upper 16 bits of each colour value with + * a copy of the colour. */ + xredcolors[i] = xredcolors[i] * 0x00010001; + xgreencolors[i] = xgreencolors[i] * 0x00010001; + xbluecolors[i] = xbluecolors[i] * 0x00010001; + } + } + for (i = 0; i < 4096; i++) { + int r = ((i >> 8) << 4) | (i >> 8); + int g = (((i >> 4) & 0xf) << 4) | ((i >> 4) & 0x0f); + int b = ((i & 0xf) << 4) | (i & 0x0f); + r = gamma[r + 256][0]; + g = gamma[g + 256][1]; + b = gamma[b + 256][2]; + xcolors[i] = doMask(r, 5, 11) | doMask(g, 6, 5) | doMask(b, 5, 0); + if (byte_swap) { + if (bpp <= 16) + xcolors[i] = bswap_16(xcolors[i]); + else + xcolors[i] = bswap_32(xcolors[i]); + } + if (bpp <= 16) { + /* Fill upper 16 bits of each colour value + * with a copy of the colour. */ + xcolors[i] |= xcolors[i] * 0x00010001; + } + } + + /* create RGB 5:6:5 -> YUV tables */ + for (i = 0; i < 65536; i++) { + uae_u32 r, g, b; + r = (((i >> 11) & 31) << 3) | lowbits(i, 11, 3); + r = gamma[r + 256][0]; + g = (((i >> 5) & 63) << 2) | lowbits(i, 5, 2); + g = gamma[g + 256][1]; + b = (((i >> 0) & 31) << 3) | lowbits(i, 0, 3); + b = gamma[b + 256][2]; + tyhrgb[i] = get_yh(r, g, b) * 256 * 256; + tylrgb[i] = get_yl(r, g, b) * 256 * 256; + tcbrgb[i] = ((uae_s8)get_cb(r, g, b)) * 256; + tcrrgb[i] = ((uae_s8)get_cr(r, g, b)) * 256; + } + } +#endif + +#endif + xredcolor_b = rw; + xgreencolor_b = gw; + xbluecolor_b = bw; + xredcolor_s = rs; + xgreencolor_s = gs; + xbluecolor_s = bs; + xredcolor_m = ((1 << rw) - 1) << xredcolor_s; + xgreencolor_m = ((1 << gw) - 1) << xgreencolor_s; + xbluecolor_m = ((1 << bw) - 1) << xbluecolor_s; + /* create AGA color tables */ for(i=0; i<256; i++) { xredcolors[i] = doColor(i, rw, rs); diff --git a/src/hardfile.cpp b/src/hardfile.cpp index 4febfa5a..414354b4 100644 --- a/src/hardfile.cpp +++ b/src/hardfile.cpp @@ -350,8 +350,8 @@ static void create_virtual_rdb(struct hardfiledata *hfd) pl(part, 6, -1); pl(part, 7, -1); pl(part, 8, 0); // devflags - part[9 * 4] = _tcslen(hfd->device_name); - ua_copy((char*)part + 9 * 4 + 1, -1, hfd->device_name); + part[9 * 4] = _tcslen(hfd->ci.devname); + ua_copy((char*)part + 9 * 4 + 1, 30, hfd->ci.devname); denv = part + 128; pl(denv, 0, 80); @@ -573,12 +573,12 @@ void hdf_close(struct hardfiledata *hfd) hfd->vhd_sectormap = NULL; } -int hdf_dup(struct hardfiledata *dhfd, const struct hardfiledata *shfd) -{ - return hdf_dup_target(dhfd, shfd); -} +//int hdf_dup(struct hardfiledata *dhfd, const struct hardfiledata *shfd) +//{ +// return hdf_dup_target(dhfd, shfd); +//} -extern int get_guid_target(uae_u8 *out); +//extern int get_guid_target(uae_u8 *out); static uae_u64 vhd_read(struct hardfiledata *hfd, void *v, uae_u64 offset, uae_u64 len) { @@ -795,7 +795,7 @@ int vhd_create(const TCHAR *name, uae_u64 size, uae_u32 dostype) b[0x3b] = tracksec; // disk type b[0x3c + 3] = HFD_VHD_DYNAMIC; - get_guid_target(b + 0x44); + //get_guid_target(b + 0x44); crc = vhd_checksum(b, -1); b[0x40] = crc >> 24; b[0x41] = crc >> 16; @@ -1604,12 +1604,13 @@ void hardfile_do_disk_change(struct uaedev_config_data *uci, bool insert) int fsid = uci->configoffset; struct hardfiledata *hfd; - if (uci->ci.controller == HD_CONTROLLER_PCMCIA_SRAM) { - //gayle_modify_pcmcia_sram_unit(uci->ci.rootdir, uci->ci.readonly, insert); //TODO - return; - } - else if (uci->ci.controller == HD_CONTROLLER_PCMCIA_IDE) { - //gayle_modify_pcmcia_ide_unit(uci->ci.rootdir, uci->ci.readonly, insert); //TODO + if (uci->ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA) { + if (uci->ci.controller_type_unit == 0) { + //gayle_modify_pcmcia_sram_unit(&uci->ci, insert); + } + else { + //gayle_modify_pcmcia_ide_unit(&uci->ci, insert); + } return; } hfd = get_hardfile_data(fsid); diff --git a/src/include/akiko.h b/src/include/akiko.h index dd4ff11a..b9d3a48b 100644 --- a/src/include/akiko.h +++ b/src/include/akiko.h @@ -1,4 +1,4 @@ - +#pragma once #define AKIKO_BASE 0xb80000 #define AKIKO_BASE_END 0xb80100 /* ?? */ @@ -9,5 +9,6 @@ extern void akiko_free (void); extern void AKIKO_hsync_handler (void); extern void akiko_mute (int); +extern bool akiko_ntscmode(void); extern void rethink_akiko (void); diff --git a/src/include/audio.h b/src/include/audio.h index a8f33d18..f3cc323c 100644 --- a/src/include/audio.h +++ b/src/include/audio.h @@ -6,45 +6,103 @@ * Copyright 1995, 1996, 1997 Bernd Schmidt */ +#pragma once #define PERIOD_MAX ULONG_MAX +#define MAX_EV ~0u -extern void aud0_handler (void); -extern void aud1_handler (void); -extern void aud2_handler (void); -extern void aud3_handler (void); +void AUDxDAT(int nr, uae_u16 value); +void AUDxDAT(int nr, uae_u16 value, uaecptr addr); +void AUDxVOL(int nr, uae_u16 value); +void AUDxPER(int nr, uae_u16 value); +void AUDxLCH(int nr, uae_u16 value); +void AUDxLCL(int nr, uae_u16 value); +void AUDxLEN(int nr, uae_u16 value); -extern void AUDxDAT (int nr, uae_u16 value); -extern void AUDxVOL (int nr, uae_u16 value); -extern void AUDxPER (int nr, uae_u16 value); -extern void AUDxLCH (int nr, uae_u16 value); -extern void AUDxLCL (int nr, uae_u16 value); -extern void AUDxLEN (int nr, uae_u16 value); +uae_u16 audio_dmal(void); +void audio_state_machine(void); +uaecptr audio_getpt(int nr, bool reset); +int init_audio(void); +void audio_reset(void); +void update_audio(void); +void audio_evhandler(void); +void audio_hsync(void); +void audio_update_adkmasks(void); +void update_sound(double clk); +void update_cda_sound(double clk); +void led_filter_audio(void); +void set_audio(void); +int audio_activate(void); +void audio_deactivate(void); +void audio_vsync(void); +void audio_sampleripper(int); +void write_wavheader(struct zfile *wavfile, uae_u32 size, uae_u32 freq); -extern uae_u16 audio_dmal (void); -extern void audio_state_machine (void); -extern void audio_dmal_do (int nr, bool reset); +int audio_is_pull(void); +int audio_pull_buffer(void); +bool audio_finish_pull(void); +bool audio_is_pull_event(void); +bool audio_is_event_frame_possible(int); -extern int init_audio (void); -extern void audio_reset (void); -extern void update_audio (void); -extern void audio_evhandler (void); -extern void audio_hsync (void); -extern void audio_update_adkmasks (void); -extern void update_sound (double clk); -extern void led_filter_audio (void); -extern void set_audio(void); -extern int audio_activate(void); -extern void audio_deactivate(void); +extern int sampleripper_enabled; -enum -{ - SND_MONO, SND_STEREO, SND_4CH_CLONEDSTEREO, SND_4CH, SND_6CH_CLONEDSTEREO, SND_6CH, SND_NONE +typedef void(*CDA_CALLBACK)(int); +typedef bool(*SOUND_STREAM_CALLBACK)(int); + +extern int audio_enable_stream(bool, int, int, SOUND_STREAM_CALLBACK); +extern void audio_state_stream_state(int, int*, int, unsigned int); + +extern void audio_cda_new_buffer(uae_s16 *buffer, int length, int userdata, CDA_CALLBACK next_cd_audio_buffer_callback); +extern void audio_cda_volume(int left, int right); + +extern int sound_cd_volume[2]; +extern int sound_paula_volume[2]; + +#define AUDIO_CHANNEL_MAX_STREAM_CH 8 +#define AUDIO_CHANNEL_STREAMS 9 + +#define AUDIO_CHANNELS_PAULA 4 + +enum { + SND_MONO, + SND_STEREO, + SND_4CH_CLONEDSTEREO, + SND_4CH, + SND_6CH_CLONEDSTEREO, + SND_6CH, + SND_NONE }; -STATIC_INLINE int get_audio_ismono (int stereomode) + +static inline int get_audio_stereomode(int channels) { - if (stereomode == 0) - return 1; - return 0; + switch (channels) + { + case 1: + return SND_MONO; + case 2: + return SND_STEREO; + case 4: + return SND_4CH; + case 6: + return SND_6CH; + } + return SND_STEREO; +} + +STATIC_INLINE int get_audio_nativechannels(int stereomode) +{ + int ch[] = { 1, 2, 4, 4, 6, 6, 0 }; + return ch[stereomode]; +} + +STATIC_INLINE int get_audio_amigachannels(int stereomode) +{ + int ch[] = { 1, 2, 2, 4, 2, 4, 0 }; + return ch[stereomode]; +} + +STATIC_INLINE int get_audio_ismono(int stereomode) +{ + return stereomode == 0; } #define SOUND_MAX_DELAY_BUFFER 1024 diff --git a/src/include/autoconf.h b/src/include/autoconf.h index 115d551c..de0b85e5 100644 --- a/src/include/autoconf.h +++ b/src/include/autoconf.h @@ -1,36 +1,87 @@ - /* - * UAE - The Un*x Amiga Emulator - * - * Autoconfig device support - * - * (c) 1996 Ed Hanway - */ +/* +* UAE - The Un*x Amiga Emulator +* +* Autoconfig device support +* +* (c) 1996 Ed Hanway +*/ + +#ifndef UAE_AUTOCONF_H +#define UAE_AUTOCONF_H + +//#include "uae/types.h" +#include "sysconfig.h" +#include "traps.h" +#include "include/memory.h" + +#define AFTERDOS_INIT_PRI ((-121) & 0xff) +#define AFTERDOS_PRI ((-122) & 0xff) #define RTAREA_DEFAULT 0xf00000 #define RTAREA_BACKUP 0xef0000 +#define RTAREA_BACKUP_2 0xdb0000 #define RTAREA_SIZE 0x10000 -#define RTAREA_TRAPS 0x2000 -#define RTAREA_RTG 0x3000 + +#define RTAREA_TRAPS 0x3000 +#define RTAREA_RTG 0x3800 +#define RTAREA_TRAMPOLINE 0x3a00 +#define RTAREA_DATAREGION 0xF000 + #define RTAREA_FSBOARD 0xFFEC -#define RTAREA_INT 0xFFEB +#define RTAREA_HEARTBEAT 0xFFF0 +#define RTAREA_TRAPTASK 0xFFF4 +#define RTAREA_EXTERTASK 0xFFF8 +#define RTAREA_INTREQ 0xFFFC -extern uae_u32 addr (int); -extern void db (uae_u8); -extern void dw (uae_u16); -extern void dl (uae_u32); -extern uae_u32 ds_ansi (const uae_char*); -extern uae_u32 ds (const TCHAR*); -extern uae_u32 ds_bstr_ansi (const uae_char*); -extern uae_u8 dbg (uaecptr); -extern void calltrap (uae_u32); -extern void org (uae_u32); -extern uae_u32 here (void); -extern uaecptr makedatatable (uaecptr resid, uaecptr resname, uae_u8 type, uae_s8 priority, uae_u16 ver, uae_u16 rev); +#define RTAREA_TRAP_DATA 0x4000 +#define RTAREA_TRAP_DATA_SIZE 0x8000 +#define RTAREA_TRAP_DATA_SLOT_SIZE 0x2000 // 8192 +#define RTAREA_TRAP_DATA_SECOND 80 +#define RTAREA_TRAP_DATA_TASKWAIT (RTAREA_TRAP_DATA_SECOND - 4) +#define RTAREA_TRAP_DATA_EXTRA 144 +#define RTAREA_TRAP_DATA_EXTRA_SIZE (RTAREA_TRAP_DATA_SLOT_SIZE - RTAREA_TRAP_DATA_EXTRA) -extern void align (int); +#define RTAREA_TRAP_STATUS 0xF000 +#define RTAREA_TRAP_STATUS_SIZE 8 +#define RTAREA_TRAP_STATUS_SECOND 4 + +#define RTAREA_VARIABLES 0x3F00 +#define RTAREA_VARIABLES_SIZE 0x100 +#define RTAREA_SYSBASE 0x3FFC +#define RTAREA_GFXBASE 0x3FF8 +#define RTAREA_INTBASE 0x3FF4 +#define RTAREA_INTXY 0x3FF0 + +#define RTAREA_TRAP_DATA_NUM (RTAREA_TRAP_DATA_SIZE / RTAREA_TRAP_DATA_SLOT_SIZE) +#define RTAREA_TRAP_DATA_SEND_NUM 1 + +#define RTAREA_TRAP_SEND_STATUS (RTAREA_TRAP_STATUS + RTAREA_TRAP_STATUS_SIZE * RTAREA_TRAP_DATA_NUM) +#define RTAREA_TRAP_SEND_DATA (RTAREA_TRAP_DATA + RTAREA_TRAP_DATA_SLOT_SIZE * RTAREA_TRAP_DATA_NUM) + +#define UAEBOARD_DATAREGION_START 0x4000 +#define UAEBOARD_DATAREGION_SIZE 0xc000 + +extern uae_u32 addr(int); +extern void db(uae_u8); +extern void dw(uae_u16); +extern void dl(uae_u32); +extern uae_u32 ds_ansi(const uae_char*); +extern uae_u32 ds(const TCHAR*); +extern uae_u32 ds_bstr_ansi(const uae_char*); +extern uae_u8 dbg(uaecptr); +extern void calltrap(uae_u32); +extern void org(uae_u32); +extern uae_u32 here(void); +extern uaecptr makedatatable(uaecptr resid, uaecptr resname, uae_u8 type, uae_s8 priority, uae_u16 ver, uae_u16 rev); +extern uae_u32 boot_rom_copy(TrapContext*, uaecptr, int); +extern void add_rom_absolute(uaecptr addr); +extern void save_rom_absolute(uaecptr addr); + +extern void align(int); extern volatile int uae_int_requested; -extern void set_uae_int_flag (void); +extern void rtarea_reset(void); +extern bool rethink_traps(void); #define RTS 0x4e75 #define RTE 0x4e73 @@ -43,56 +94,187 @@ extern uaecptr ROM_filesys_resname, ROM_filesys_resid; extern uaecptr ROM_filesys_diagentry; extern uaecptr ROM_hardfile_resname, ROM_hardfile_resid; extern uaecptr ROM_hardfile_init; -extern uaecptr filesys_initcode; +extern uaecptr filesys_initcode, filesys_initcode_ptr; -extern int is_hardfile (int unit_no); -extern int nr_units (void); -extern int nr_directory_units (struct uae_prefs*); -extern uaecptr need_uae_boot_rom (void); +extern int is_hardfile(int unit_no); +extern int nr_units(void); +extern int nr_directory_units(struct uae_prefs*); +extern uaecptr need_uae_boot_rom(struct uae_prefs*); struct mountedinfo { - uae_s64 size; - bool ismounted; - bool ismedia; - int nrcyls; + uae_s64 size; + bool ismounted; + bool ismedia; + int error; + int nrcyls; TCHAR rootdir[MAX_DPATH]; }; -extern int add_filesys_unitconfig (struct uae_prefs *p, int index, TCHAR *error); -extern int get_filesys_unitconfig (struct uae_prefs *p, int index, struct mountedinfo*); -extern int kill_filesys_unitconfig (struct uae_prefs *p, int nr); -extern int move_filesys_unitconfig (struct uae_prefs *p, int nr, int to); -extern TCHAR *validatedevicename (TCHAR *s); -extern TCHAR *validatevolumename (TCHAR *s); +extern int get_filesys_unitconfig(struct uae_prefs *p, int index, struct mountedinfo*); +extern int kill_filesys_unitconfig(struct uae_prefs *p, int nr); +extern int move_filesys_unitconfig(struct uae_prefs *p, int nr, int to); +extern TCHAR *validatedevicename(TCHAR *s, const TCHAR *def); +extern TCHAR *validatevolumename(TCHAR *s, const TCHAR *def); -int filesys_insert (int nr, const TCHAR *volume, const TCHAR *rootdir, bool readonly, int flags); -int filesys_eject (int nr); -int filesys_media_change (const TCHAR *rootdir, int inserted, struct uaedev_config_data *uci); +int filesys_insert(int nr, const TCHAR *volume, const TCHAR *rootdir, bool readonly, int flags); +int filesys_eject(int nr); +int filesys_media_change(const TCHAR *rootdir, int inserted, struct uaedev_config_data *uci); -extern TCHAR *filesys_createvolname (const TCHAR *volname, const TCHAR *rootdir, const TCHAR *def); -extern int target_get_volume_name (struct uaedev_mount_info *mtinf, const TCHAR *volumepath, TCHAR *volumename, int size, bool inserted, bool fullcheck); +extern TCHAR *filesys_createvolname(const TCHAR *volname, const TCHAR *rootdir, struct zvolume *zv, const TCHAR *def); +extern int target_get_volume_name(struct uaedev_mount_info *mtinf, struct uaedev_config_info *ci, bool inserted, bool fullcheck, int cnt); -extern int sprintf_filesys_unit (TCHAR *buffer, int num); +extern int sprintf_filesys_unit(TCHAR *buffer, int num); -extern void filesys_reset (void); -extern void filesys_cleanup (void); -extern void filesys_prepare_reset (void); -extern void filesys_start_threads (void); -extern void filesys_flush_cache (void); -extern void filesys_free_handles (void); -extern void filesys_vsync (void); +extern void filesys_reset(void); +extern void filesys_cleanup(void); +extern void filesys_prepare_reset(void); +extern void filesys_start_threads(void); +extern void filesys_flush_cache(void); +extern void filesys_free_handles(void); +extern void filesys_vsync(void); -extern void filesys_install (void); -extern void filesys_install_code (void); -extern void filesys_store_devinfo (uae_u8 *); -extern void hardfile_install (void); -extern void hardfile_reset (void); -extern void emulib_install (void); -extern void expansion_init (void); -extern void expansion_cleanup (void); -extern void expansion_clear (void); +extern void filesys_install(void); +extern void filesys_install_code(void); +extern uaecptr filesys_get_entry(int); +extern void filesys_store_devinfo(uae_u8 *); +extern void hardfile_install(void); +extern void hardfile_reset(void); +extern void emulib_install(void); +extern uae_u32 uaeboard_demux(uae_u32*); +extern void expansion_init(void); +extern void expansion_cleanup(void); +extern void expansion_clear(void); +extern uaecptr expansion_startaddress(struct uae_prefs*, uaecptr addr, uae_u32 size); +extern bool expansion_is_next_board_fastram(void); +extern uaecptr uaeboard_alloc_ram(uae_u32); +extern uae_u8 *uaeboard_map_ram(uaecptr); +extern void expansion_scan_autoconfig(struct uae_prefs*, bool); +extern void expansion_generate_autoconfig_info(struct uae_prefs *p); +extern struct autoconfig_info *expansion_get_autoconfig_info(struct uae_prefs*, int romtype, int devnum); +extern struct autoconfig_info *expansion_get_autoconfig_data(struct uae_prefs *p, int index); +extern struct autoconfig_info *expansion_get_autoconfig_by_address(struct uae_prefs *p, uaecptr addr); +extern void expansion_set_autoconfig_sort(struct uae_prefs *p); +extern int expansion_autoconfig_move(struct uae_prefs *p, int index, int direction, bool test); +extern bool expansion_can_move(struct uae_prefs *p, int index); +extern bool alloc_expansion_bank(addrbank *bank, struct autoconfig_info *aci); +extern void free_expansion_bank(addrbank *bank); +extern void expansion_map(void); +extern uae_u32 expansion_board_size(addrbank *ab); -extern void uaegfx_install_code (uaecptr); +extern void uaegfx_install_code(uaecptr); -extern uae_u32 emulib_target_getcpurate (uae_u32, uae_u32*); +extern uae_u32 emulib_target_getcpurate(uae_u32, uae_u32*); + +typedef bool(*DEVICE_INIT)(struct autoconfig_info*); +typedef void(*DEVICE_ADD)(int, struct uaedev_config_info*, struct romconfig*); +typedef bool(*E8ACCESS)(int, uae_u32*, int, bool); +typedef void(*DEVICE_MEMORY_CALLBACK)(struct romconfig*, uae_u8*, int); +#define EXPANSIONTYPE_SCSI 1 +#define EXPANSIONTYPE_IDE 2 +#define EXPANSIONTYPE_24BIT 4 +#define EXPANSIONTYPE_SASI 16 +#define EXPANSIONTYPE_CUSTOM 32 +#define EXPANSIONTYPE_PCI_BRIDGE 64 +#define EXPANSIONTYPE_PARALLEL_ADAPTER 128 +#define EXPANSIONTYPE_X86_BRIDGE 0x100 +#define EXPANSIONTYPE_CUSTOM_SECONDARY 0x200 +#define EXPANSIONTYPE_RTG 0x400 +#define EXPANSIONTYPE_SOUND 0x800 +#define EXPANSIONTYPE_FLOPPY 0x1000 +#define EXPANSIONTYPE_NET 0x2000 +#define EXPANSIONTYPE_INTERNAL 0x4000 +#define EXPANSIONTYPE_FALLBACK_DISABLE 0x8000 +#define EXPANSIONTYPE_HAS_FALLBACK 0x10000 + +#define EXPANSIONBOARD_CHECKBOX 0 +#define EXPANSIONBOARD_MULTI 1 +#define EXPANSIONBOARD_STRING 2 + +struct expansionboardsettings +{ + const TCHAR *name; + const TCHAR *configname; + int type; + bool invert; + int bitshift; +}; +struct expansionsubromtype +{ + const TCHAR *name; + const TCHAR *configname; + uae_u32 romtype; + int memory_mid, memory_pid; + uae_u32 memory_serial; + bool memory_after; + uae_u8 autoconfig[16]; +}; +struct expansionromtype +{ + const TCHAR *name; + const TCHAR *friendlyname; + const TCHAR *friendlymanufacturer; + DEVICE_INIT init, init2; + DEVICE_ADD add; + uae_u32 romtype; + uae_u32 romtype_extra; + uae_u32 parentromtype; + int zorro; + bool singleonly; + const struct expansionsubromtype *subtypes; + int defaultsubtype; + bool autoboot_jumper; + int deviceflags; + int memory_mid, memory_pid; + uae_u32 memory_serial; + bool memory_after; + DEVICE_MEMORY_CALLBACK memory_callback; + bool id_jumper; + int extrahdports; + const struct expansionboardsettings *settings; + uae_u8 autoconfig[16]; +}; +extern const struct expansionromtype expansionroms[]; +struct cpuboardsubtype +{ + const TCHAR *name; + const TCHAR *configname; + int romtype, romtype_extra; + DEVICE_ADD add; + int deviceflags; + int memorytype; + int maxmemory; + int z3extra; + DEVICE_INIT init, init2; + int initzorro; + int initflag; + const struct expansionboardsettings *settings; + E8ACCESS e8; + // if includes Z2 or Z3 RAM + int memory_mid, memory_pid; + uae_u32 memory_serial; + bool memory_after; + uae_u8 autoconfig[16]; +}; +struct cpuboardtype +{ + int id; + const TCHAR *name; + const struct cpuboardsubtype *subtypes; + int defaultsubtype; +}; +extern const struct cpuboardtype cpuboards[]; +struct memoryboardtype +{ + const TCHAR *man; + const TCHAR *name; + uae_u8 z; + uae_u32 address; + uae_u16 manufacturer; + uae_u8 product; + uae_u8 autoconfig[16]; +}; +extern const struct memoryboardtype memoryboards[]; + + +#endif /* UAE_AUTOCONF_H */ diff --git a/src/include/blit.h b/src/include/blit.h index 8bb73df0..eb620735 100644 --- a/src/include/blit.h +++ b/src/include/blit.h @@ -1,519 +1,518 @@ -STATIC_INLINE uae_u32 blit_func(const uae_u32 srca, const uae_u32 srcb, const uae_u32 srcc, const uae_u8 mt) +STATIC_INLINE uae_u32 blit_func(uae_u32 srca, uae_u32 srcb, uae_u32 srcc, uae_u8 mt) { - switch(mt) - { - case 0x0: - return 0; - case 0x1: - return ~(srca | srcb | srcc); - case 0x2: - return (srcc & ~(srca | srcb)); - case 0x3: - return ~(srca | srcb); - case 0x4: - return (srcb & ~(srca | srcc)); - case 0x5: - return ~(srca | srcc); - case 0x6: - return (~srca & (srcb ^ srcc)); - case 0x7: - return ~(srca | (srcb & srcc)); - case 0x8: - return (~srca & srcb & srcc); - case 0x9: - return ~(srca | (srcb ^ srcc)); - case 0xa: - return (~srca & srcc); - case 0xb: - return ~(srca | (srcb & ~srcc)); - case 0xc: - return (~srca & srcb); - case 0xd: - return ~(srca | (~srcb & srcc)); - case 0xe: - return (~srca & (srcb | srcc)); - case 0xf: - return ~srca; - case 0x10: - return (srca & ~(srcb | srcc)); - case 0x11: - return ~(srcb | srcc); - case 0x12: - return (~srcb & (srca ^ srcc)); - case 0x13: - return ~(srcb | (srca & srcc)); - case 0x14: - return (~srcc & (srca ^ srcb)); - case 0x15: - return ~(srcc | (srca & srcb)); - case 0x16: - return (srca ^ ((srca & srcb) | (srcb ^ srcc))); - case 0x17: - return ~(srca ^ ((srca ^ srcb) & (srca ^ srcc))); - case 0x18: - return ((srca ^ srcb) & (srca ^ srcc)); - case 0x19: - return (srcb ^ (~srcc | (srca & srcb))); - case 0x1a: - return (srca ^ (srcc | (srca & srcb))); - case 0x1b: - return (srca ^ (srcc | ~(srca ^ srcb))); - case 0x1c: - return (srca ^ (srcb | (srca & srcc))); - case 0x1d: - return (srca ^ (srcb | ~(srca ^ srcc))); - case 0x1e: - return (srca ^ (srcb | srcc)); - case 0x1f: - return ~(srca & (srcb | srcc)); - case 0x20: - return (srca & ~srcb & srcc); - case 0x21: - return ~(srcb | (srca ^ srcc)); - case 0x22: - return (~srcb & srcc); - case 0x23: - return ~(srcb | (srca & ~srcc)); - case 0x24: - return ((srca ^ srcb) & (srcb ^ srcc)); - case 0x25: - return (srca ^ (~srcc | (srca & srcb))); - case 0x26: - return (srcb ^ (srcc | (srca & srcb))); - case 0x27: - return ~(srca ^ (srcc & (srca ^ srcb))); - case 0x28: - return (srcc & (srca ^ srcb)); - case 0x29: - return ~(srca ^ srcb ^ (srcc | (srca & srcb))); - case 0x2a: - return (srcc & ~(srca & srcb)); - case 0x2b: - return ~(srca ^ ((srca ^ srcb) & (srcb ^ srcc))); - case 0x2c: - return (srcb ^ (srca & (srcb | srcc))); - case 0x2d: - return (srca ^ (srcb | ~srcc)); - case 0x2e: - return (srca ^ (srcb | (srca ^ srcc))); - case 0x2f: - return ~(srca & (srcb | ~srcc)); - case 0x30: - return (srca & ~srcb); - case 0x31: - return ~(srcb | (~srca & srcc)); - case 0x32: - return (~srcb & (srca | srcc)); - case 0x33: - return ~srcb; - case 0x34: - return (srcb ^ (srca | (srcb & srcc))); - case 0x35: - return (srcb ^ (srca | ~(srcb ^ srcc))); - case 0x36: - return (srcb ^ (srca | srcc)); - case 0x37: - return ~(srcb & (srca | srcc)); - case 0x38: - return (srca ^ (srcb & (srca | srcc))); - case 0x39: - return (srcb ^ (srca | ~srcc)); - case 0x3a: - return (srcb ^ (srca | (srcb ^ srcc))); - case 0x3b: - return ~(srcb & (srca | ~srcc)); - case 0x3c: - return (srca ^ srcb); - case 0x3d: - return (srca ^ (srcb | ~(srca | srcc))); - case 0x3e: - return (srca ^ (srcb | (srca ^ (srca | srcc)))); - case 0x3f: - return ~(srca & srcb); - case 0x40: - return (srca & srcb & ~srcc); - case 0x41: - return ~(srcc | (srca ^ srcb)); - case 0x42: - return ((srca ^ srcc) & (srcb ^ srcc)); - case 0x43: - return (srca ^ (~srcb | (srca & srcc))); - case 0x44: - return (srcb & ~srcc); - case 0x45: - return ~(srcc | (srca & ~srcb)); - case 0x46: - return (srcc ^ (srcb | (srca & srcc))); - case 0x47: - return ~(srca ^ (srcb & (srca ^ srcc))); - case 0x48: - return (srcb & (srca ^ srcc)); - case 0x49: - return ~(srca ^ srcc ^ (srcb | (srca & srcc))); - case 0x4a: - return (srcc ^ (srca & (srcb | srcc))); - case 0x4b: - return (srca ^ (~srcb | srcc)); - case 0x4c: - return (srcb & ~(srca & srcc)); - case 0x4d: - return (srca ^ ((srca ^ srcb) | ~(srca ^ srcc))); - case 0x4e: - return (srca ^ (srcc | (srca ^ srcb))); - case 0x4f: - return ~(srca & (~srcb | srcc)); - case 0x50: - return (srca & ~srcc); - case 0x51: - return ~(srcc | (~srca & srcb)); - case 0x52: - return (srcc ^ (srca | (srcb & srcc))); - case 0x53: - return ~(srcb ^ (srca & (srcb ^ srcc))); - case 0x54: - return (~srcc & (srca | srcb)); - case 0x55: - return ~srcc; - case 0x56: - return (srcc ^ (srca | srcb)); - case 0x57: - return ~(srcc & (srca | srcb)); - case 0x58: - return (srca ^ (srcc & (srca | srcb))); - case 0x59: - return (srcc ^ (srca | ~srcb)); - case 0x5a: - return (srca ^ srcc); - case 0x5b: - return (srca ^ (srcc | ~(srca | srcb))); - case 0x5c: - return (srcc ^ (srca | (srcb ^ srcc))); - case 0x5d: - return ~(srcc & (srca | ~srcb)); - case 0x5e: - return (srca ^ (srcc | (srca ^ (srca | srcb)))); - case 0x5f: - return ~(srca & srcc); - case 0x60: - return (srca & (srcb ^ srcc)); - case 0x61: - return ~(srcb ^ srcc ^ (srca | (srcb & srcc))); - case 0x62: - return (srcc ^ (srcb & (srca | srcc))); - case 0x63: - return (srcb ^ (~srca | srcc)); - case 0x64: - return (srcb ^ (srcc & (srca | srcb))); - case 0x65: - return (srcc ^ (~srca | srcb)); - case 0x66: - return (srcb ^ srcc); - case 0x67: - return (srcb ^ (srcc | ~(srca | srcb))); - case 0x68: - return ((srca & srcb) ^ (srcc & (srca | srcb))); - case 0x69: - return ~(srca ^ srcb ^ srcc); - case 0x6a: - return (srcc ^ (srca & srcb)); - case 0x6b: - return ~(srca ^ srcb ^ (srcc & (srca | srcb))); - case 0x6c: - return (srcb ^ (srca & srcc)); - case 0x6d: - return ~(srca ^ srcc ^ (srcb & (srca | srcc))); - case 0x6e: - return ((~srca & srcb) | (srcb ^ srcc)); - case 0x6f: - return (~srca | (srcb ^ srcc)); - case 0x70: - return (srca & ~(srcb & srcc)); - case 0x71: - return ~(srca ^ ((srca ^ srcb) | (srca ^ srcc))); - case 0x72: - return (srcb ^ (srcc | (srca ^ srcb))); - case 0x73: - return ~(srcb & (~srca | srcc)); - case 0x74: - return (srcc ^ (srcb | (srca ^ srcc))); - case 0x75: - return ~(srcc & (~srca | srcb)); - case 0x76: - return (srcb ^ (srcc | (srca ^ (srca & srcb)))); - case 0x77: - return ~(srcb & srcc); - case 0x78: - return (srca ^ (srcb & srcc)); - case 0x79: - return ~(srcb ^ srcc ^ (srca & (srcb | srcc))); - case 0x7a: - return ((srca & ~srcb) | (srca ^ srcc)); - case 0x7b: - return (~srcb | (srca ^ srcc)); - case 0x7c: - return ((srca ^ srcb) | (srca & ~srcc)); - case 0x7d: - return (~srcc | (srca ^ srcb)); - case 0x7e: - return ((srca ^ srcb) | (srca ^ srcc)); - case 0x7f: - return ~(srca & srcb & srcc); - case 0x80: - return (srca & srcb & srcc); - case 0x81: - return ~((srca ^ srcb) | (srca ^ srcc)); - case 0x82: - return (srcc & ~(srca ^ srcb)); - case 0x83: - return (srca ^ (~srcb | (srca & ~srcc))); - case 0x84: - return (srcb & ~(srca ^ srcc)); - case 0x85: - return (srca ^ (~srcc | (srca & ~srcb))); - case 0x86: - return (srcb ^ srcc ^ (srca & (srcb | srcc))); - case 0x87: - return ~(srca ^ (srcb & srcc)); - case 0x88: - return (srcb & srcc); - case 0x89: - return (srcb ^ (~srcc & (~srca | srcb))); - case 0x8a: - return (srcc & (~srca | srcb)); - case 0x8b: - return (srca ^ (~srcb | (srca ^ srcc))); - case 0x8c: - return (srcb & (~srca | srcc)); - case 0x8d: - return (srca ^ (~srcc | (srca ^ srcb))); - case 0x8e: - return (srca ^ ((srca ^ srcb) | (srca ^ srcc))); - case 0x8f: - return (~srca | (srcb & srcc)); - case 0x90: - return (srca & ~(srcb ^ srcc)); - case 0x91: - return (srcb ^ (~srcc | (~srca & srcb))); - case 0x92: - return (srca ^ srcc ^ (srcb & (srca | srcc))); - case 0x93: - return ~(srcb ^ (srca & srcc)); - case 0x94: - return (srca ^ srcb ^ (srcc & (srca | srcb))); - case 0x95: - return ~(srcc ^ (srca & srcb)); - case 0x96: - return (srca ^ srcb ^ srcc); - case 0x97: - return (srca ^ srcb ^ (srcc | ~(srca | srcb))); - case 0x98: - return (srcb ^ (~srcc & (srca | srcb))); - case 0x99: - return ~(srcb ^ srcc); - case 0x9a: - return (srcc ^ (srca & ~srcb)); - case 0x9b: - return ~(srcb ^ (srcc & (srca | srcb))); - case 0x9c: - return (srcb ^ (srca & ~srcc)); - case 0x9d: - return ~(srcc ^ (srcb & (srca | srcc))); - case 0x9e: - return (srcb ^ srcc ^ (srca | (srcb & srcc))); - case 0x9f: - return ~(srca & (srcb ^ srcc)); - case 0xa0: - return (srca & srcc); - case 0xa1: - return (srca ^ (~srcc & (srca | ~srcb))); - case 0xa2: - return (srcc & (srca | ~srcb)); - case 0xa3: - return (srcb ^ (~srca | (srcb ^ srcc))); - case 0xa4: - return (srca ^ (~srcc & (srca | srcb))); - case 0xa5: - return ~(srca ^ srcc); - case 0xa6: - return (srcc ^ (~srca & srcb)); - case 0xa7: - return ~(srca ^ (srcc & (srca | srcb))); - case 0xa8: - return (srcc & (srca | srcb)); - case 0xa9: - return ~(srcc ^ (srca | srcb)); - case 0xaa: - return srcc; - case 0xab: - return (srcc | ~(srca | srcb)); - case 0xac: - return (srcb ^ (srca & (srcb ^ srcc))); - case 0xad: - return ~(srcc ^ (srca | (srcb & srcc))); - case 0xae: - return (srcc | (~srca & srcb)); - case 0xaf: - return (~srca | srcc); - case 0xb0: - return (srca & (~srcb | srcc)); - case 0xb1: - return ~(srca ^ (srcc | (srca ^ srcb))); - case 0xb2: - return (srca ^ ((srca ^ srcc) & (srcb ^ srcc))); - case 0xb3: - return (~srcb | (srca & srcc)); - case 0xb4: - return (srca ^ (srcb & ~srcc)); - case 0xb5: - return ~(srcc ^ (srca & (srcb | srcc))); - case 0xb6: - return (srca ^ srcc ^ (srcb | (srca & srcc))); - case 0xb7: - return ~(srcb & (srca ^ srcc)); - case 0xb8: - return (srca ^ (srcb & (srca ^ srcc))); - case 0xb9: - return ~(srcc ^ (srcb | (srca & srcc))); - case 0xba: - return (srcc | (srca & ~srcb)); - case 0xbb: - return (~srcb | srcc); - case 0xbc: - return ((srca ^ srcb) | (srca & srcc)); - case 0xbd: - return ((srca ^ srcb) | ~(srca ^ srcc)); - case 0xbe: - return (srcc | (srca ^ srcb)); - case 0xbf: - return (srcc | ~(srca & srcb)); - case 0xc0: - return (srca & srcb); - case 0xc1: - return (srca ^ (~srcb & (srca | ~srcc))); - case 0xc2: - return (srca ^ (~srcb & (srca | srcc))); - case 0xc3: - return ~(srca ^ srcb); - case 0xc4: - return (srcb & (srca | ~srcc)); - case 0xc5: - return ~(srcb ^ (srca | (srcb ^ srcc))); - case 0xc6: - return (srcb ^ (~srca & srcc)); - case 0xc7: - return ~(srca ^ (srcb & (srca | srcc))); - case 0xc8: - return (srcb & (srca | srcc)); - case 0xc9: - return ~(srcb ^ (srca | srcc)); - case 0xca: - return (srcc ^ (srca & (srcb ^ srcc))); - case 0xcb: - return ~(srcb ^ (srca | (srcb & srcc))); - case 0xcc: - return srcb; - case 0xcd: - return (srcb | ~(srca | srcc)); - case 0xce: - return (srcb | (~srca & srcc)); - case 0xcf: - return (~srca | srcb); - case 0xd0: - return (srca & (srcb | ~srcc)); - case 0xd1: - return ~(srca ^ (srcb | (srca ^ srcc))); - case 0xd2: - return (srca ^ (~srcb & srcc)); - case 0xd3: - return ~(srcb ^ (srca & (srcb | srcc))); - case 0xd4: - return (srca ^ ((srca ^ srcb) & (srcb ^ srcc))); - case 0xd5: - return (~srcc | (srca & srcb)); - case 0xd6: - return (srca ^ srcb ^ (srcc | (srca & srcb))); - case 0xd7: - return ~(srcc & (srca ^ srcb)); - case 0xd8: - return (srca ^ (srcc & (srca ^ srcb))); - case 0xd9: - return ~(srcb ^ (srcc | (srca & srcb))); - case 0xda: - return ((srca & srcb) | (srca ^ srcc)); - case 0xdb: - return ~((srca ^ srcb) & (srcb ^ srcc)); - case 0xdc: - return (srcb | (srca & ~srcc)); - case 0xdd: - return (srcb | ~srcc); - case 0xde: - return (srcb | (srca ^ srcc)); - case 0xdf: - return (srcb | ~(srca & srcc)); - case 0xe0: - return (srca & (srcb | srcc)); - case 0xe1: - return ~(srca ^ (srcb | srcc)); - case 0xe2: - return (srcc ^ (srcb & (srca ^ srcc))); - case 0xe3: - return ~(srca ^ (srcb | (srca & srcc))); - case 0xe4: - return (srcb ^ (srcc & (srca ^ srcb))); - case 0xe5: - return ~(srca ^ (srcc | (srca & srcb))); - case 0xe6: - return ((srca & srcb) | (srcb ^ srcc)); - case 0xe7: - return ~((srca ^ srcb) & (srca ^ srcc)); - case 0xe8: - return (srca ^ ((srca ^ srcb) & (srca ^ srcc))); - case 0xe9: - return (srca ^ srcb ^ (~srcc | (srca & srcb))); - case 0xea: - return (srcc | (srca & srcb)); - case 0xeb: - return (srcc | ~(srca ^ srcb)); - case 0xec: - return (srcb | (srca & srcc)); - case 0xed: - return (srcb | ~(srca ^ srcc)); - case 0xee: - return (srcb | srcc); - case 0xef: - return (~srca | srcb | srcc); - case 0xf0: - return srca; - case 0xf1: - return (srca | ~(srcb | srcc)); - case 0xf2: - return (srca | (~srcb & srcc)); - case 0xf3: - return (srca | ~srcb); - case 0xf4: - return (srca | (srcb & ~srcc)); - case 0xf5: - return (srca | ~srcc); - case 0xf6: - return (srca | (srcb ^ srcc)); - case 0xf7: - return (srca | ~(srcb & srcc)); - case 0xf8: - return (srca | (srcb & srcc)); - case 0xf9: - return (srca | ~(srcb ^ srcc)); - case 0xfa: - return (srca | srcc); - case 0xfb: - return (srca | ~srcb | srcc); - case 0xfc: - return (srca | srcb); - case 0xfd: - return (srca | srcb | ~srcc); - case 0xfe: - return (srca | srcb | srcc); - case 0xff: - return 0xFFFFFFFF; - } - return 0; +switch(mt){ +case 0x0: + return 0; +case 0x1: + return ~(srca | srcb | srcc); +case 0x2: + return (srcc & ~(srca | srcb)); +case 0x3: + return ~(srca | srcb); +case 0x4: + return (srcb & ~(srca | srcc)); +case 0x5: + return ~(srca | srcc); +case 0x6: + return (~srca & (srcb ^ srcc)); +case 0x7: + return ~(srca | (srcb & srcc)); +case 0x8: + return (~srca & srcb & srcc); +case 0x9: + return ~(srca | (srcb ^ srcc)); +case 0xa: + return (~srca & srcc); +case 0xb: + return ~(srca | (srcb & ~srcc)); +case 0xc: + return (~srca & srcb); +case 0xd: + return ~(srca | (~srcb & srcc)); +case 0xe: + return (~srca & (srcb | srcc)); +case 0xf: + return ~srca; +case 0x10: + return (srca & ~(srcb | srcc)); +case 0x11: + return ~(srcb | srcc); +case 0x12: + return (~srcb & (srca ^ srcc)); +case 0x13: + return ~(srcb | (srca & srcc)); +case 0x14: + return (~srcc & (srca ^ srcb)); +case 0x15: + return ~(srcc | (srca & srcb)); +case 0x16: + return (srca ^ ((srca & srcb) | (srcb ^ srcc))); +case 0x17: + return ~(srca ^ ((srca ^ srcb) & (srca ^ srcc))); +case 0x18: + return ((srca ^ srcb) & (srca ^ srcc)); +case 0x19: + return (srcb ^ (~srcc | (srca & srcb))); +case 0x1a: + return (srca ^ (srcc | (srca & srcb))); +case 0x1b: + return (srca ^ (srcc | ~(srca ^ srcb))); +case 0x1c: + return (srca ^ (srcb | (srca & srcc))); +case 0x1d: + return (srca ^ (srcb | ~(srca ^ srcc))); +case 0x1e: + return (srca ^ (srcb | srcc)); +case 0x1f: + return ~(srca & (srcb | srcc)); +case 0x20: + return (srca & ~srcb & srcc); +case 0x21: + return ~(srcb | (srca ^ srcc)); +case 0x22: + return (~srcb & srcc); +case 0x23: + return ~(srcb | (srca & ~srcc)); +case 0x24: + return ((srca ^ srcb) & (srcb ^ srcc)); +case 0x25: + return (srca ^ (~srcc | (srca & srcb))); +case 0x26: + return (srcb ^ (srcc | (srca & srcb))); +case 0x27: + return ~(srca ^ (srcc & (srca ^ srcb))); +case 0x28: + return (srcc & (srca ^ srcb)); +case 0x29: + return ~(srca ^ srcb ^ (srcc | (srca & srcb))); +case 0x2a: + return (srcc & ~(srca & srcb)); +case 0x2b: + return ~(srca ^ ((srca ^ srcb) & (srcb ^ srcc))); +case 0x2c: + return (srcb ^ (srca & (srcb | srcc))); +case 0x2d: + return (srca ^ (srcb | ~srcc)); +case 0x2e: + return (srca ^ (srcb | (srca ^ srcc))); +case 0x2f: + return ~(srca & (srcb | ~srcc)); +case 0x30: + return (srca & ~srcb); +case 0x31: + return ~(srcb | (~srca & srcc)); +case 0x32: + return (~srcb & (srca | srcc)); +case 0x33: + return ~srcb; +case 0x34: + return (srcb ^ (srca | (srcb & srcc))); +case 0x35: + return (srcb ^ (srca | ~(srcb ^ srcc))); +case 0x36: + return (srcb ^ (srca | srcc)); +case 0x37: + return ~(srcb & (srca | srcc)); +case 0x38: + return (srca ^ (srcb & (srca | srcc))); +case 0x39: + return (srcb ^ (srca | ~srcc)); +case 0x3a: + return (srcb ^ (srca | (srcb ^ srcc))); +case 0x3b: + return ~(srcb & (srca | ~srcc)); +case 0x3c: + return (srca ^ srcb); +case 0x3d: + return (srca ^ (srcb | ~(srca | srcc))); +case 0x3e: + return (srca ^ (srcb | (srca ^ (srca | srcc)))); +case 0x3f: + return ~(srca & srcb); +case 0x40: + return (srca & srcb & ~srcc); +case 0x41: + return ~(srcc | (srca ^ srcb)); +case 0x42: + return ((srca ^ srcc) & (srcb ^ srcc)); +case 0x43: + return (srca ^ (~srcb | (srca & srcc))); +case 0x44: + return (srcb & ~srcc); +case 0x45: + return ~(srcc | (srca & ~srcb)); +case 0x46: + return (srcc ^ (srcb | (srca & srcc))); +case 0x47: + return ~(srca ^ (srcb & (srca ^ srcc))); +case 0x48: + return (srcb & (srca ^ srcc)); +case 0x49: + return ~(srca ^ srcc ^ (srcb | (srca & srcc))); +case 0x4a: + return (srcc ^ (srca & (srcb | srcc))); +case 0x4b: + return (srca ^ (~srcb | srcc)); +case 0x4c: + return (srcb & ~(srca & srcc)); +case 0x4d: + return (srca ^ ((srca ^ srcb) | ~(srca ^ srcc))); +case 0x4e: + return (srca ^ (srcc | (srca ^ srcb))); +case 0x4f: + return ~(srca & (~srcb | srcc)); +case 0x50: + return (srca & ~srcc); +case 0x51: + return ~(srcc | (~srca & srcb)); +case 0x52: + return (srcc ^ (srca | (srcb & srcc))); +case 0x53: + return ~(srcb ^ (srca & (srcb ^ srcc))); +case 0x54: + return (~srcc & (srca | srcb)); +case 0x55: + return ~srcc; +case 0x56: + return (srcc ^ (srca | srcb)); +case 0x57: + return ~(srcc & (srca | srcb)); +case 0x58: + return (srca ^ (srcc & (srca | srcb))); +case 0x59: + return (srcc ^ (srca | ~srcb)); +case 0x5a: + return (srca ^ srcc); +case 0x5b: + return (srca ^ (srcc | ~(srca | srcb))); +case 0x5c: + return (srcc ^ (srca | (srcb ^ srcc))); +case 0x5d: + return ~(srcc & (srca | ~srcb)); +case 0x5e: + return (srca ^ (srcc | (srca ^ (srca | srcb)))); +case 0x5f: + return ~(srca & srcc); +case 0x60: + return (srca & (srcb ^ srcc)); +case 0x61: + return ~(srcb ^ srcc ^ (srca | (srcb & srcc))); +case 0x62: + return (srcc ^ (srcb & (srca | srcc))); +case 0x63: + return (srcb ^ (~srca | srcc)); +case 0x64: + return (srcb ^ (srcc & (srca | srcb))); +case 0x65: + return (srcc ^ (~srca | srcb)); +case 0x66: + return (srcb ^ srcc); +case 0x67: + return (srcb ^ (srcc | ~(srca | srcb))); +case 0x68: + return ((srca & srcb) ^ (srcc & (srca | srcb))); +case 0x69: + return ~(srca ^ srcb ^ srcc); +case 0x6a: + return (srcc ^ (srca & srcb)); +case 0x6b: + return ~(srca ^ srcb ^ (srcc & (srca | srcb))); +case 0x6c: + return (srcb ^ (srca & srcc)); +case 0x6d: + return ~(srca ^ srcc ^ (srcb & (srca | srcc))); +case 0x6e: + return ((~srca & srcb) | (srcb ^ srcc)); +case 0x6f: + return (~srca | (srcb ^ srcc)); +case 0x70: + return (srca & ~(srcb & srcc)); +case 0x71: + return ~(srca ^ ((srca ^ srcb) | (srca ^ srcc))); +case 0x72: + return (srcb ^ (srcc | (srca ^ srcb))); +case 0x73: + return ~(srcb & (~srca | srcc)); +case 0x74: + return (srcc ^ (srcb | (srca ^ srcc))); +case 0x75: + return ~(srcc & (~srca | srcb)); +case 0x76: + return (srcb ^ (srcc | (srca ^ (srca & srcb)))); +case 0x77: + return ~(srcb & srcc); +case 0x78: + return (srca ^ (srcb & srcc)); +case 0x79: + return ~(srcb ^ srcc ^ (srca & (srcb | srcc))); +case 0x7a: + return ((srca & ~srcb) | (srca ^ srcc)); +case 0x7b: + return (~srcb | (srca ^ srcc)); +case 0x7c: + return ((srca ^ srcb) | (srca & ~srcc)); +case 0x7d: + return (~srcc | (srca ^ srcb)); +case 0x7e: + return ((srca ^ srcb) | (srca ^ srcc)); +case 0x7f: + return ~(srca & srcb & srcc); +case 0x80: + return (srca & srcb & srcc); +case 0x81: + return ~((srca ^ srcb) | (srca ^ srcc)); +case 0x82: + return (srcc & ~(srca ^ srcb)); +case 0x83: + return (srca ^ (~srcb | (srca & ~srcc))); +case 0x84: + return (srcb & ~(srca ^ srcc)); +case 0x85: + return (srca ^ (~srcc | (srca & ~srcb))); +case 0x86: + return (srcb ^ srcc ^ (srca & (srcb | srcc))); +case 0x87: + return ~(srca ^ (srcb & srcc)); +case 0x88: + return (srcb & srcc); +case 0x89: + return (srcb ^ (~srcc & (~srca | srcb))); +case 0x8a: + return (srcc & (~srca | srcb)); +case 0x8b: + return (srca ^ (~srcb | (srca ^ srcc))); +case 0x8c: + return (srcb & (~srca | srcc)); +case 0x8d: + return (srca ^ (~srcc | (srca ^ srcb))); +case 0x8e: + return (srca ^ ((srca ^ srcb) | (srca ^ srcc))); +case 0x8f: + return (~srca | (srcb & srcc)); +case 0x90: + return (srca & ~(srcb ^ srcc)); +case 0x91: + return (srcb ^ (~srcc | (~srca & srcb))); +case 0x92: + return (srca ^ srcc ^ (srcb & (srca | srcc))); +case 0x93: + return ~(srcb ^ (srca & srcc)); +case 0x94: + return (srca ^ srcb ^ (srcc & (srca | srcb))); +case 0x95: + return ~(srcc ^ (srca & srcb)); +case 0x96: + return (srca ^ srcb ^ srcc); +case 0x97: + return (srca ^ srcb ^ (srcc | ~(srca | srcb))); +case 0x98: + return (srcb ^ (~srcc & (srca | srcb))); +case 0x99: + return ~(srcb ^ srcc); +case 0x9a: + return (srcc ^ (srca & ~srcb)); +case 0x9b: + return ~(srcb ^ (srcc & (srca | srcb))); +case 0x9c: + return (srcb ^ (srca & ~srcc)); +case 0x9d: + return ~(srcc ^ (srcb & (srca | srcc))); +case 0x9e: + return (srcb ^ srcc ^ (srca | (srcb & srcc))); +case 0x9f: + return ~(srca & (srcb ^ srcc)); +case 0xa0: + return (srca & srcc); +case 0xa1: + return (srca ^ (~srcc & (srca | ~srcb))); +case 0xa2: + return (srcc & (srca | ~srcb)); +case 0xa3: + return (srcb ^ (~srca | (srcb ^ srcc))); +case 0xa4: + return (srca ^ (~srcc & (srca | srcb))); +case 0xa5: + return ~(srca ^ srcc); +case 0xa6: + return (srcc ^ (~srca & srcb)); +case 0xa7: + return ~(srca ^ (srcc & (srca | srcb))); +case 0xa8: + return (srcc & (srca | srcb)); +case 0xa9: + return ~(srcc ^ (srca | srcb)); +case 0xaa: + return srcc; +case 0xab: + return (srcc | ~(srca | srcb)); +case 0xac: + return (srcb ^ (srca & (srcb ^ srcc))); +case 0xad: + return ~(srcc ^ (srca | (srcb & srcc))); +case 0xae: + return (srcc | (~srca & srcb)); +case 0xaf: + return (~srca | srcc); +case 0xb0: + return (srca & (~srcb | srcc)); +case 0xb1: + return ~(srca ^ (srcc | (srca ^ srcb))); +case 0xb2: + return (srca ^ ((srca ^ srcc) & (srcb ^ srcc))); +case 0xb3: + return (~srcb | (srca & srcc)); +case 0xb4: + return (srca ^ (srcb & ~srcc)); +case 0xb5: + return ~(srcc ^ (srca & (srcb | srcc))); +case 0xb6: + return (srca ^ srcc ^ (srcb | (srca & srcc))); +case 0xb7: + return ~(srcb & (srca ^ srcc)); +case 0xb8: + return (srca ^ (srcb & (srca ^ srcc))); +case 0xb9: + return ~(srcc ^ (srcb | (srca & srcc))); +case 0xba: + return (srcc | (srca & ~srcb)); +case 0xbb: + return (~srcb | srcc); +case 0xbc: + return ((srca ^ srcb) | (srca & srcc)); +case 0xbd: + return ((srca ^ srcb) | ~(srca ^ srcc)); +case 0xbe: + return (srcc | (srca ^ srcb)); +case 0xbf: + return (srcc | ~(srca & srcb)); +case 0xc0: + return (srca & srcb); +case 0xc1: + return (srca ^ (~srcb & (srca | ~srcc))); +case 0xc2: + return (srca ^ (~srcb & (srca | srcc))); +case 0xc3: + return ~(srca ^ srcb); +case 0xc4: + return (srcb & (srca | ~srcc)); +case 0xc5: + return ~(srcb ^ (srca | (srcb ^ srcc))); +case 0xc6: + return (srcb ^ (~srca & srcc)); +case 0xc7: + return ~(srca ^ (srcb & (srca | srcc))); +case 0xc8: + return (srcb & (srca | srcc)); +case 0xc9: + return ~(srcb ^ (srca | srcc)); +case 0xca: + return (srcc ^ (srca & (srcb ^ srcc))); +case 0xcb: + return ~(srcb ^ (srca | (srcb & srcc))); +case 0xcc: + return srcb; +case 0xcd: + return (srcb | ~(srca | srcc)); +case 0xce: + return (srcb | (~srca & srcc)); +case 0xcf: + return (~srca | srcb); +case 0xd0: + return (srca & (srcb | ~srcc)); +case 0xd1: + return ~(srca ^ (srcb | (srca ^ srcc))); +case 0xd2: + return (srca ^ (~srcb & srcc)); +case 0xd3: + return ~(srcb ^ (srca & (srcb | srcc))); +case 0xd4: + return (srca ^ ((srca ^ srcb) & (srcb ^ srcc))); +case 0xd5: + return (~srcc | (srca & srcb)); +case 0xd6: + return (srca ^ srcb ^ (srcc | (srca & srcb))); +case 0xd7: + return ~(srcc & (srca ^ srcb)); +case 0xd8: + return (srca ^ (srcc & (srca ^ srcb))); +case 0xd9: + return ~(srcb ^ (srcc | (srca & srcb))); +case 0xda: + return ((srca & srcb) | (srca ^ srcc)); +case 0xdb: + return ~((srca ^ srcb) & (srcb ^ srcc)); +case 0xdc: + return (srcb | (srca & ~srcc)); +case 0xdd: + return (srcb | ~srcc); +case 0xde: + return (srcb | (srca ^ srcc)); +case 0xdf: + return (srcb | ~(srca & srcc)); +case 0xe0: + return (srca & (srcb | srcc)); +case 0xe1: + return ~(srca ^ (srcb | srcc)); +case 0xe2: + return (srcc ^ (srcb & (srca ^ srcc))); +case 0xe3: + return ~(srca ^ (srcb | (srca & srcc))); +case 0xe4: + return (srcb ^ (srcc & (srca ^ srcb))); +case 0xe5: + return ~(srca ^ (srcc | (srca & srcb))); +case 0xe6: + return ((srca & srcb) | (srcb ^ srcc)); +case 0xe7: + return ~((srca ^ srcb) & (srca ^ srcc)); +case 0xe8: + return (srca ^ ((srca ^ srcb) & (srca ^ srcc))); +case 0xe9: + return (srca ^ srcb ^ (~srcc | (srca & srcb))); +case 0xea: + return (srcc | (srca & srcb)); +case 0xeb: + return (srcc | ~(srca ^ srcb)); +case 0xec: + return (srcb | (srca & srcc)); +case 0xed: + return (srcb | ~(srca ^ srcc)); +case 0xee: + return (srcb | srcc); +case 0xef: + return (~srca | srcb | srcc); +case 0xf0: + return srca; +case 0xf1: + return (srca | ~(srcb | srcc)); +case 0xf2: + return (srca | (~srcb & srcc)); +case 0xf3: + return (srca | ~srcb); +case 0xf4: + return (srca | (srcb & ~srcc)); +case 0xf5: + return (srca | ~srcc); +case 0xf6: + return (srca | (srcb ^ srcc)); +case 0xf7: + return (srca | ~(srcb & srcc)); +case 0xf8: + return (srca | (srcb & srcc)); +case 0xf9: + return (srca | ~(srcb ^ srcc)); +case 0xfa: + return (srca | srcc); +case 0xfb: + return (srca | ~srcb | srcc); +case 0xfc: + return (srca | srcb); +case 0xfd: + return (srca | srcb | ~srcc); +case 0xfe: + return (srca | srcb | srcc); +case 0xff: + return 0xFFFFFFFF; +} +return 0; } diff --git a/src/include/blitter.h b/src/include/blitter.h index b05de3e4..7bc2ed15 100644 --- a/src/include/blitter.h +++ b/src/include/blitter.h @@ -6,44 +6,48 @@ * (c) 1995 Bernd Schmidt */ +#pragma once struct bltinfo { - int blitzero; - int blitashift,blitbshift,blitdownashift,blitdownbshift; - uae_u16 bltadat, bltbdat, bltcdat,bltddat; - uae_u16 bltahold,bltbhold,bltafwm,bltalwm; - int vblitsize,hblitsize; - int bltamod,bltbmod,bltcmod,bltdmod; + int blitzero; + int blitashift, blitbshift, blitdownashift, blitdownbshift; + uae_u16 bltadat, bltbdat, bltcdat, bltddat; + uae_u16 bltahold, bltbhold, bltafwm, bltalwm; + int vblitsize, hblitsize; + int bltamod, bltbmod, bltcmod, bltdmod; + int got_cycle; }; extern enum blitter_states { - BLT_done, BLT_init, BLT_read, BLT_work, BLT_write, BLT_next + BLT_done, BLT_init, BLT_read, BLT_work, BLT_write, BLT_next } bltstate; extern struct bltinfo blt_info; +extern int blitter_nasty, blit_interrupt, blitter_dangerous_bpl; + +extern void check_is_blit_dangerous(uaecptr *bplpt, int planes, int words); + extern uae_u16 bltsize; -extern uae_u16 bltcon0,bltcon1; -extern uae_u32 bltapt,bltbpt,bltcpt,bltdpt; +extern uae_u16 bltcon0, bltcon1; +extern uae_u32 bltapt, bltbpt, bltcpt, bltdpt; +extern uae_u32 bltptx; +extern int bltptxpos, bltptxc; +extern int blit_singlechannel; -extern void maybe_blit2 (int); -STATIC_INLINE void maybe_blit (int hack) -{ - if (bltstate == BLT_done) - return; - - if (savestate_state) - return; - - maybe_blit2(hack); -} -extern void reset_blit (int); -extern int blitnasty (void); -extern void blitter_handler (void); -extern void build_blitfilltable (void); -extern void do_blitter (void); -extern void blitter_done_notify (void); -extern void blitter_slowdown (int, int, int, int); -extern void blitter_check_start (void); +extern void maybe_blit(int, int); +extern void reset_blit(int); +extern int blitnasty(void); +extern int blitnnasty(int); +extern void blitter_handler(uae_u32); +extern void build_blitfilltable(void); +extern void do_blitter(int, int); +extern void decide_blitter(int hpos); +extern int blitter_need(int hpos); +extern void blitter_done_notify(int hpos); +extern void blitter_slowdown(int, int, int, int); +extern int blitter_channel_state(void); +extern void blitter_check_start(void); +extern void blitter_reset(void); typedef void blitter_func(uaecptr, uaecptr, uaecptr, uaecptr, struct bltinfo *); diff --git a/src/include/cia.h b/src/include/cia.h index 83bbf0bb..4d838469 100644 --- a/src/include/cia.h +++ b/src/include/cia.h @@ -6,16 +6,30 @@ * (c) 1995 Bernd Schmidt */ -extern void CIA_reset (void); -extern void CIA_vsync_prehandler (void); -extern void CIA_hsync_posthandler (void); -extern void CIA_vsync_posthandler (void); -extern void CIA_handler (void); +#pragma once +extern void CIA_reset(void); +extern void CIA_vsync_prehandler(void); +extern void CIA_hsync_prehandler(void); +extern void CIA_hsync_posthandler(bool, bool); +extern void CIA_handler(void); +extern void CIAA_tod_inc(int); +extern void CIAB_tod_handler(int); -extern void diskindex_handler (void); -extern void cia_diskindex (void); +extern void diskindex_handler(void); +extern void cia_parallelack(void); +extern void cia_diskindex(void); -extern void rethink_cias (void); -extern void cia_set_overlay (bool); +extern void dumpcia(void); +extern void rethink_cias(void); +extern int resetwarning_do(int); +extern void cia_set_overlay(bool); +void cia_heartbeat(void); + +extern int parallel_direct_write_data(uae_u8, uae_u8); +extern int parallel_direct_read_data(uae_u8*); +extern int parallel_direct_write_status(uae_u8, uae_u8); +extern int parallel_direct_read_status(uae_u8*); extern void rtc_hardreset(void); + +extern void keyboard_connected(bool); diff --git a/src/include/custom.h b/src/include/custom.h index 130a644f..3048717d 100644 --- a/src/include/custom.h +++ b/src/include/custom.h @@ -1,10 +1,10 @@ /* - * UAE - The Un*x Amiga Emulator - * - * custom chip support - * - * (c) 1995 Bernd Schmidt - */ +* UAE - The Un*x Amiga Emulator +* +* custom chip support +* +* (c) 1995 Bernd Schmidt +*/ #ifndef UAE_CUSTOM_H #define UAE_CUSTOM_H @@ -12,7 +12,7 @@ #include "machdep/rpt.h" /* These are the masks that are ORed together in the chipset_mask option. - * If CSMASK_AGA is set, the ECS bits are guaranteed to be set as well. */ +* If CSMASK_AGA is set, the ECS bits are guaranteed to be set as well. */ #define CSMASK_ECS_AGNUS 1 #define CSMASK_ECS_DENISE 2 #define CSMASK_AGA 4 @@ -26,28 +26,39 @@ #define MAXVPOS_LINES_OCS 512 #define HPOS_SHIFT 3 -extern void set_speedup_values(); -extern int custom_init(); -extern void custom_prepare(); +uae_u32 get_copper_address(int copno); + +extern int custom_init(void); +extern void custom_prepare(void); extern void custom_reset(bool hardreset, bool keyboardreset); -extern int intlev(); +extern int intlev(void); +extern void dumpcustom(void); -extern void do_copper(); +extern void do_disk(void); +extern void do_copper(void); -extern void notice_new_xcolors(); -extern void init_row_map(); -extern void init_hz_full(); -extern void init_custom(); +extern void notice_new_xcolors(void); +extern void notice_screen_contents_lost(void); +extern void init_row_map(void); +extern void init_hz_normal(void); +extern void init_custom(void); -extern bool picasso_requested_on; -extern bool picasso_on; +extern bool picasso_requested_on, picasso_requested_forced_on, picasso_on; +extern void set_picasso_hack_rate(int hz); -extern unsigned long int hsync_counter; +/* Set to 1 to leave out the current frame in average frame time calculation. +* Useful if the debugger was active. */ +extern int bogusframe; +extern unsigned long int hsync_counter, vsync_counter; extern uae_u16 dmacon; -extern uae_u16 intreq; +extern uae_u16 intena, intreq, intreqr; -extern int vpos; +extern int vpos, lof_store; + +extern int find_copper_record(uaecptr, int *, int *); + +extern int n_frames; STATIC_INLINE int dmaen(unsigned int dmamask) { @@ -58,6 +69,7 @@ STATIC_INLINE int dmaen(unsigned int dmamask) #define SPCFLAG_COPPER 4 #define SPCFLAG_INT 8 #define SPCFLAG_BRK 16 +#define SPCFLAG_UAEINT 32 #define SPCFLAG_TRACE 64 #define SPCFLAG_DOTRACE 128 #define SPCFLAG_DOINT 256 /* arg, JIT fails without this.. */ @@ -69,21 +81,19 @@ STATIC_INLINE int dmaen(unsigned int dmamask) #ifdef JIT #define SPCFLAG_END_COMPILE 16384 #endif +#define SPCFLAG_CHECK 32768 extern uae_u16 adkcon; +extern unsigned int joy0dir, joy1dir; +extern int joy0button, joy1button; + extern void INTREQ(uae_u16); extern bool INTREQ_0(uae_u16); extern void INTREQ_f(uae_u16); -STATIC_INLINE void send_interrupt(int num) -{ - INTREQ_0(0x8000 | (1 << num)); -} - -STATIC_INLINE uae_u16 INTREQR() -{ - return intreq; -} +extern void send_interrupt(int num, int delay); +extern void rethink_uae_int(void); +extern uae_u16 INTREQR(void); /* maximums for statically allocated tables */ #ifdef UAE_MINI @@ -120,6 +130,7 @@ extern int maxvpos, maxvpos_nom, maxvpos_display; extern int hsyncstartpos, hsyncendpos; extern int minfirstline, vblank_endline, numscrlines; extern double vblank_hz, fake_vblank_hz; +extern double hblank_hz; extern int vblank_skip, doublescan; extern bool programmedmode; @@ -135,17 +146,43 @@ extern bool programmedmode; #define DMA_MASTER 0x0200 #define DMA_BLITPRI 0x0400 +#define CYCLE_REFRESH 1 +#define CYCLE_STROBE 2 +#define CYCLE_MISC 3 +#define CYCLE_SPRITE 4 +#define CYCLE_COPPER 5 +#define CYCLE_BLITTER 6 +#define CYCLE_CPU 7 +#define CYCLE_CPUNASTY 8 +#define CYCLE_COPPER_SPECIAL 0x10 + +#define CYCLE_MASK 0x0f + +extern unsigned long frametime, timeframes; +extern uae_u16 htotal, vtotal, beamcon0; + /* 100 words give you 1600 horizontal pixels. Should be more than enough for - * superhires. Don't forget to update the definition in genp2c.c as well. - * needs to be larger for superhires support */ +* superhires. Don't forget to update the definition in genp2c.c as well. +* needs to be larger for superhires support */ #ifdef CUSTOM_SIMPLE #define MAX_WORDS_PER_LINE 50 #else #define MAX_WORDS_PER_LINE 100 #endif +extern uae_u32 hirestab_h[256][2]; +extern uae_u32 lorestab_h[256][4]; + +extern uae_u32 hirestab_l[256][1]; +extern uae_u32 lorestab_l[256][2]; + +#ifdef AGA /* AGA mode color lookup tables */ extern unsigned int xredcolors[256], xgreencolors[256], xbluecolors[256]; +#endif +extern int xredcolor_s, xredcolor_b, xredcolor_m; +extern int xgreencolor_s, xgreencolor_b, xgreencolor_m; +extern int xbluecolor_s, xbluecolor_b, xbluecolor_m; #define RES_LORES 0 #define RES_HIRES 1 @@ -156,6 +193,9 @@ extern unsigned int xredcolors[256], xgreencolors[256], xbluecolors[256]; #define VRES_QUAD 2 #define VRES_MAX 1 +/* calculate shift depending on resolution (replaced "decided_hires ? 4 : 8") */ +#define RES_SHIFT(res) ((res) == RES_LORES ? 8 : (res) == RES_HIRES ? 4 : 2) + /* get resolution from bplcon0 */ STATIC_INLINE int GET_RES_DENISE(uae_u16 con0) { @@ -163,14 +203,12 @@ STATIC_INLINE int GET_RES_DENISE(uae_u16 con0) con0 &= ~0x40; // SUPERHIRES return ((con0) & 0x40) ? RES_SUPERHIRES : ((con0) & 0x8000) ? RES_HIRES : RES_LORES; } - STATIC_INLINE int GET_RES_AGNUS(uae_u16 con0) { if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) con0 &= ~0x40; // SUPERHIRES return ((con0) & 0x40) ? RES_SUPERHIRES : ((con0) & 0x8000) ? RES_HIRES : RES_LORES; } - /* get sprite width from FMODE */ #define GET_SPRITEWIDTH(FMODE) ((((FMODE) >> 2) & 3) == 3 ? 64 : (((FMODE) >> 2) & 3) == 0 ? 16 : 32) /* Compute the number of bitplanes from a value written to BPLCON0 */ @@ -183,8 +221,24 @@ STATIC_INLINE int GET_PLANES(uae_u16 bplcon0) return (bplcon0 >> 12) & 7; // normal planes bits } -extern void fpscounter_reset(); +extern void fpscounter_reset(void); +extern unsigned long idletime; +extern int lightpen_x, lightpen_y, lightpen_cx, lightpen_cy, lightpen_active, lightpen_enabled; -extern int current_maxvpos(); +struct customhack { + uae_u16 v; + int vpos, hpos; +}; +void customhack_put(struct customhack *ch, uae_u16 v, int hpos); +uae_u16 customhack_get(struct customhack *ch, int hpos); +extern void alloc_cycle_ext(int, int); +extern void alloc_cycle_blitter(int hpos, uaecptr *ptr, int); +extern bool ispal(void); +extern bool isvga(void); +extern int current_maxvpos(void); +extern struct chipset_refresh *get_chipset_refresh(void); +extern void compute_framesync(void); +extern void getsyncregisters(uae_u16 *phsstrt, uae_u16 *phsstop, uae_u16 *pvsstrt, uae_u16 *pvsstop); +int is_bitplane_dma(int hpos); -#endif /* CUSTOM_H */ +#endif /* UAE_CUSTOM_H */ diff --git a/src/include/drawing.h b/src/include/drawing.h index b4e1ccc2..52311933 100644 --- a/src/include/drawing.h +++ b/src/include/drawing.h @@ -18,40 +18,57 @@ #define MAX_PLANES 6 #endif +#ifdef AMIBERRY +#define AMIGA_WIDTH_MAX (640 / 2) +#define AMIGA_HEIGHT_MAX (512 / 2) +#else #define AMIGA_WIDTH_MAX (752 / 2) #define AMIGA_HEIGHT_MAX (576 / 2) +#endif -/* According to the HRM, pixel data spends a couple of cycles somewhere in the chips - before it appears on-screen. */ + //#define NEWHSYNC + +#ifdef NEWHSYNC +#define DIW_DDF_OFFSET 9 + /* this many cycles starting from hpos=0 are visible on right border */ +#define HBLANK_OFFSET 13 +#define DISPLAY_LEFT_SHIFT 0x40 +#else + /* According to the HRM, pixel data spends a couple of cycles somewhere in the chips + before it appears on-screen. (TW: display emulation now does this automatically) */ #define DIW_DDF_OFFSET 1 -/* this many cycles starting from hpos=0 are visible on right border */ + /* this many cycles starting from hpos=0 are visible on right border */ #define HBLANK_OFFSET 9 -/* We ignore that many lores pixels at the start of the display. These are + /* We ignore that many lores pixels at the start of the display. These are * invisible anyway due to hardware DDF limits. */ #define DISPLAY_LEFT_SHIFT 0x38 +#endif -#define PIXEL_XPOS(HPOS) (((HPOS)*2 - DISPLAY_LEFT_SHIFT + DIW_DDF_OFFSET - 1) ) +#define PIXEL_XPOS(HPOS) (((HPOS)*2 - DISPLAY_LEFT_SHIFT + DIW_DDF_OFFSET - 1) << lores_shift) #define min_diwlastword (0) -#define max_diwlastword (PIXEL_XPOS(0x1d4>> 1)) +#define max_diwlastword (PIXEL_XPOS(0x1d4 >> 1)) -#define lores_shift 0 -extern bool aga_mode; +extern int lores_shift, interlace_seen; +extern bool aga_mode, direct_rgb; +extern int visible_left_border, visible_right_border; +extern int detected_screen_resolution; STATIC_INLINE int coord_hw_to_window_x(int x) { x -= DISPLAY_LEFT_SHIFT; - return x; + return x << lores_shift; } STATIC_INLINE int coord_window_to_hw_x(int x) { + x >>= lores_shift; return x + DISPLAY_LEFT_SHIFT; } STATIC_INLINE int coord_diw_to_window_x(int x) { - return (x - DISPLAY_LEFT_SHIFT + DIW_DDF_OFFSET - 1); + return (x - DISPLAY_LEFT_SHIFT + DIW_DDF_OFFSET - 1) << lores_shift; } STATIC_INLINE int coord_window_to_diw_x(int x) @@ -61,15 +78,32 @@ STATIC_INLINE int coord_window_to_diw_x(int x) } extern int framecnt; - +extern int custom_frame_redraw_necessary; /* color values in two formats: 12 (OCS/ECS) or 24 (AGA) bit Amiga RGB (color_regs), * and the native color value; both for each Amiga hardware color register. * * !!! See color_reg_xxx functions below before touching !!! */ -struct color_entry +#define CE_BORDERBLANK 0 +#define CE_BORDERNTRANS 1 +#define CE_BORDERSPRITE 2 +#define CE_SHRES_DELAY 4 + +STATIC_INLINE bool ce_is_borderblank(uae_u8 data) { + return (data & (1 << CE_BORDERBLANK)) != 0; +} +STATIC_INLINE bool ce_is_bordersprite(uae_u8 data) +{ + return (data & (1 << CE_BORDERSPRITE)) != 0; +} +STATIC_INLINE bool ce_is_borderntrans(uae_u8 data) +{ + return (data & (1 << CE_BORDERNTRANS)) != 0; +} + +struct color_entry { uae_u16 color_regs_ecs[32]; #ifndef AGA xcolnr acolors[32]; @@ -89,14 +123,16 @@ struct color_entry STATIC_INLINE xcolnr getxcolor(int c) { - if (aga_mode) +#ifdef AGA + if (direct_rgb) return CONVERT_RGB(c); else +#endif return xcolors[c]; } /* functions for reading, writing, copying and comparing struct color_entry */ -STATIC_INLINE int color_reg_get(struct color_entry* ce, int c) +STATIC_INLINE int color_reg_get(struct color_entry *ce, int c) { #ifdef AGA if (aga_mode) @@ -105,8 +141,7 @@ STATIC_INLINE int color_reg_get(struct color_entry* ce, int c) #endif return ce->color_regs_ecs[c]; } - -STATIC_INLINE void color_reg_set(struct color_entry* ce, int c, int v) +STATIC_INLINE void color_reg_set(struct color_entry *ce, int c, int v) { #ifdef AGA if (aga_mode) @@ -115,8 +150,7 @@ STATIC_INLINE void color_reg_set(struct color_entry* ce, int c, int v) #endif ce->color_regs_ecs[c] = v; } - -STATIC_INLINE int color_reg_cmp(struct color_entry* ce1, struct color_entry* ce2) +STATIC_INLINE int color_reg_cmp(struct color_entry *ce1, struct color_entry *ce2) { int v; #ifdef AGA @@ -129,18 +163,17 @@ STATIC_INLINE int color_reg_cmp(struct color_entry* ce1, struct color_entry* ce2 return 0; return 1; } - /* ugly copy hack, is there better solution? */ -STATIC_INLINE void color_reg_cpy(struct color_entry* dst, struct color_entry* src) +STATIC_INLINE void color_reg_cpy(struct color_entry *dst, struct color_entry *src) { dst->extra = src->extra; #ifdef AGA if (aga_mode) - /* copy acolors and color_regs_aga */ + /* copy acolors and color_regs_aga */ memcpy(dst->acolors, src->acolors, sizeof(struct color_entry) - sizeof(uae_u16) * 32); else #endif - /* copy first 32 acolors and color_regs_ecs */ + /* copy first 32 acolors and color_regs_ecs */ memcpy(dst->color_regs_ecs, src->color_regs_ecs, sizeof(struct color_entry)); } @@ -154,9 +187,10 @@ STATIC_INLINE void color_reg_cpy(struct color_entry* dst, struct color_entry* sr */ #define COLOR_CHANGE_BRDBLANK 0x80000000 - -struct color_change -{ +#define COLOR_CHANGE_SHRES_DELAY 0x40000000 +#define COLOR_CHANGE_HSYNC_HACK 0x20000000 +#define COLOR_CHANGE_MASK 0xf0000000 +struct color_change { int linepos; int regno; unsigned int value; @@ -169,9 +203,8 @@ struct color_change #define MAX_PIXELS_PER_LINE 1760 #endif -/* No divisors for MAX_PIXELS_PER_LINE; we support AGA and may one day - want to use SHRES sprites. */ -#define MAX_SPR_PIXELS (((MAXVPOS + 1)*2 + 1) * MAX_PIXELS_PER_LINE) +/* No divisors for MAX_PIXELS_PER_LINE; we support AGA and SHRES sprites */ +#define MAX_SPR_PIXELS (((MAXVPOS + 1) * 2 + 1) * MAX_PIXELS_PER_LINE) struct sprite_entry { @@ -181,12 +214,10 @@ struct sprite_entry bool has_attached; }; -union sps_union -{ +union sps_union { uae_u8 bytes[2 * MAX_SPR_PIXELS]; uae_u32 words[2 * MAX_SPR_PIXELS / 4]; }; - extern union sps_union spixstate; extern uae_u16 spixels[MAX_SPR_PIXELS * 2]; @@ -201,8 +232,7 @@ extern struct draw_info *curr_drawinfo, *prev_drawinfo; /* struct decision contains things we save across drawing frames for * comparison (smart update stuff). */ -struct decision -{ +struct decision { /* Records the leftmost access of BPL1DAT. */ int plfleft, plfright, plflinelen; /* Display window: native coordinates, depend on lores state. */ @@ -223,8 +253,7 @@ struct decision /* Anything related to changes in hw registers during the DDF for one * line. */ -struct draw_info -{ +struct draw_info { int first_sprite_entry, last_sprite_entry; int first_color_change, last_color_change; int nr_color_changes, nr_sprites; @@ -238,18 +267,50 @@ extern uae_u8 line_data[(MAXVPOS + 2) * 2][MAX_PLANES * MAX_WORDS_PER_LINE * 2]; extern int coord_native_to_amiga_y(int); extern int coord_native_to_amiga_x(int); -extern void hsync_record_line_state(int lineno); -extern void vsync_handle_redraw(); -extern void vsync_handle_check(); +extern void record_diw_line(int plfstrt, int first, int last); +extern void hardware_line_completed(int lineno); + +/* Determine how to draw a scan line. */ +enum nln_how { + /* All lines on a non-doubled display. */ + nln_normal, + /* Non-interlace, doubled display. */ + nln_doubled, + /* Interlace, doubled display, upper line. */ + nln_upper, + /* Interlace, doubled display, lower line. */ + nln_lower, + /* This line normal, next one black. */ + nln_nblack, + nln_upper_black, + nln_lower_black, + nln_upper_black_always, + nln_lower_black_always +}; + +extern void hsync_record_line_state(int lineno, enum nln_how, int changed); +extern void vsync_handle_redraw(int long_field, int lof_changed, uae_u16, uae_u16); +extern bool vsync_handle_check(); extern void init_hardware_for_drawing_frame(); extern void reset_drawing(); extern void drawing_init(); +extern bool notice_interlace_seen(bool); +extern void notice_resolution_seen(int, bool); +extern void frame_drawn(void); +extern void redraw_frame(void); +extern bool draw_frame(); +extern int get_custom_limits(int *pw, int *ph, int *pdx, int *pdy, int *prealh); +extern void store_custom_limits(int w, int h, int dx, int dy); +extern void set_custom_limits(int w, int h, int dx, int dy); +extern void get_custom_topedge(int *x, int *y, bool max); +extern void get_custom_raw_limits(int *pw, int *ph, int *pdx, int *pdy); extern long time_per_frame; -extern void adjust_idletime(long ns_waited); /* Finally, stuff that shouldn't really be shared. */ +extern int thisframe_first_drawn_line, thisframe_last_drawn_line; + #define IHF_SCROLLLOCK 0 #define IHF_QUIT_PROGRAM 1 #define IHF_PICASSO 2 diff --git a/src/include/events.h b/src/include/events.h index 448a7453..8e5f105b 100644 --- a/src/include/events.h +++ b/src/include/events.h @@ -16,15 +16,21 @@ #include "machdep/rpt.h" -extern frame_time_t vsyncmintime; +extern frame_time_t vsyncmintime, vsyncmaxtime, vsyncwaittime; extern int vsynctimebase, syncbase; extern void reset_frame_rate_hack (); +extern unsigned long int vsync_cycles; +extern unsigned long start_cycles; +extern int event2_count; +extern bool event_wait; extern int speedup_timelimit; extern void compute_vsynctime (); extern void init_eventtab (); extern void events_schedule (); +extern unsigned long currcycle, nextevent; +extern int is_syncline, is_syncline_end; extern long last_synctime; typedef void (*evfunc)(); typedef void (*evfunc2)(uae_u32); @@ -52,18 +58,19 @@ struct ev2 }; enum { - ev_copper, - ev_cia, ev_audio, ev_blitter, ev_dmal, ev_misc, ev_hsync, - ev_max + ev_cia, ev_audio, ev_misc, ev_hsync, + ev_max }; enum { - ev2_disk, ev2_disk_motor0, ev2_disk_motor1, ev2_disk_motor2, ev2_disk_motor3, - ev2_max + ev2_blitter, ev2_disk, ev2_misc, + ev2_max = 12 }; extern int pissoff_value; -#define countdown (regs.pissoff) +extern uae_s32 pissoff; + +#define countdown (pissoff) //TODO: check and implement this //#define do_cycles do_cycles_slow @@ -79,18 +86,18 @@ STATIC_INLINE void cycles_do_special () { #ifdef JIT if (currprefs.cachesize) { - if (regs.pissoff >= 0) - regs.pissoff = -1; + if (pissoff >= 0) + pissoff = -1; } else #endif { - regs.pissoff = 0; + pissoff = 0; } } STATIC_INLINE void do_extra_cycles(unsigned long cycles_to_add) { - regs.pissoff -= cycles_to_add; + pissoff -= cycles_to_add; } STATIC_INLINE unsigned long int get_cycles () @@ -98,56 +105,51 @@ STATIC_INLINE unsigned long int get_cycles () return currcycle; } -STATIC_INLINE void set_cycles (unsigned long int x) +STATIC_INLINE void set_cycles(unsigned long int x) { - currcycle = x; + currcycle = x; eventtab[ev_hsync].oldcycles = x; } -STATIC_INLINE int current_hpos_safe () +STATIC_INLINE int current_hpos_safe(void) { - int hp = (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT; + int hp = (get_cycles() - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT; return hp; } -STATIC_INLINE int current_hpos () -{ - int hp = (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT; - return hp; -} +extern int current_hpos(void); -STATIC_INLINE bool cycles_in_range (unsigned long endcycles) +STATIC_INLINE bool cycles_in_range(unsigned long endcycles) { - signed long c = get_cycles (); + signed long c = get_cycles(); return static_cast(endcycles) - c > 0; } extern void MISC_handler(); +extern void event2_newevent_xx(int no, evt t, uae_u32 data, evfunc2 func); +extern void event2_newevent_x_replace(evt t, uae_u32 data, evfunc2 func); -STATIC_INLINE void event2_newevent (int no, evt t, uae_u32 data) +STATIC_INLINE void event2_newevent_x(int no, evt t, uae_u32 data, evfunc2 func) { - eventtab2[no].active = true; - eventtab2[no].evtime = (t * CYCLE_UNIT) + get_cycles(); - eventtab2[no].data = data; - MISC_handler(); + if (int(t) <= 0) { + func(data); + return; + } + event2_newevent_xx(no, t * CYCLE_UNIT, data, func); } -STATIC_INLINE void event2_remevent (int no) +STATIC_INLINE void event2_newevent(int no, evt t, uae_u32 data) { - eventtab2[no].active = false; + event2_newevent_x(no, t, data, eventtab2[no].handler); +} +STATIC_INLINE void event2_newevent2(evt t, uae_u32 data, evfunc2 func) +{ + event2_newevent_x(-1, t, data, func); } -STATIC_INLINE void event_newevent (int no, evt t) +STATIC_INLINE void event2_remevent(int no) { - evt ct = get_cycles(); - eventtab[no].active = true; - eventtab[no].evtime = ct + t * CYCLE_UNIT; - events_schedule(); -} - -STATIC_INLINE void event_remevent (int no) -{ - eventtab[no].active = false; + eventtab2[no].active = 0; } #endif diff --git a/src/include/filesys.h b/src/include/filesys.h index 5a52cef3..b7a5d825 100644 --- a/src/include/filesys.h +++ b/src/include/filesys.h @@ -24,8 +24,7 @@ struct hdf_cache time_t lastaccess; }; -struct hardfiledata -{ +struct hardfiledata { uae_u64 virtsize; // virtual size uae_u64 physsize; // physical size (dynamic disk) uae_u64 offset; @@ -40,7 +39,6 @@ struct hardfiledata TCHAR vendor_id[8 + 1]; TCHAR product_id[16 + 1]; TCHAR product_rev[4 + 1]; - TCHAR device_name[256]; /* geometry from possible RDSK block */ int rdbcylinders; int rdbsectors; @@ -64,7 +62,7 @@ struct hardfiledata void *chd_handle; int drive_empty; - TCHAR* emptyname; + TCHAR *emptyname; struct hdf_cache bcache[MAX_HDF_CACHE_BLOCKS]; uae_u8 scsi_sense[MAX_SCSI_SENSE]; @@ -72,13 +70,13 @@ struct hardfiledata struct uaedev_config_info delayedci; int reinsertdelay; bool isreinsert; + bool unit_stopped; }; #define HFD_FLAGS_REALDRIVE 1 #define HFD_FLAGS_REALDRIVEPARTITION 2 -struct hd_hardfiledata -{ +struct hd_hardfiledata { struct hardfiledata hfd; uae_u64 size; int cyls; @@ -90,20 +88,21 @@ struct hd_hardfiledata int ansi_version; }; -#define HD_CONTROLLER_UAE 0 -#define HD_CONTROLLER_IDE0 1 -#define HD_CONTROLLER_IDE1 2 -#define HD_CONTROLLER_IDE2 3 -#define HD_CONTROLLER_IDE3 4 -#define HD_CONTROLLER_SCSI0 5 -#define HD_CONTROLLER_SCSI1 6 -#define HD_CONTROLLER_SCSI2 7 -#define HD_CONTROLLER_SCSI3 8 -#define HD_CONTROLLER_SCSI4 9 -#define HD_CONTROLLER_SCSI5 10 -#define HD_CONTROLLER_SCSI6 11 -#define HD_CONTROLLER_PCMCIA_SRAM 12 -#define HD_CONTROLLER_PCMCIA_IDE 13 +#define HD_CONTROLLER_EXPANSION_MAX 120 +#define HD_CONTROLLER_NEXT_UNIT 300 + +#define HD_CONTROLLER_TYPE_UAE 0 +#define HD_CONTROLLER_TYPE_IDE_AUTO (HD_CONTROLLER_TYPE_UAE + 1) +#define HD_CONTROLLER_TYPE_IDE_FIRST (HD_CONTROLLER_TYPE_IDE_AUTO) +#define HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST (HD_CONTROLLER_TYPE_IDE_FIRST + 1) +#define HD_CONTROLLER_TYPE_IDE_LAST (HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST + HD_CONTROLLER_EXPANSION_MAX - 1) + +#define HD_CONTROLLER_TYPE_SCSI_AUTO (HD_CONTROLLER_TYPE_IDE_LAST + 1) +#define HD_CONTROLLER_TYPE_SCSI_FIRST (HD_CONTROLLER_TYPE_SCSI_AUTO) +#define HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST (HD_CONTROLLER_TYPE_SCSI_FIRST + 1) +#define HD_CONTROLLER_TYPE_SCSI_LAST (HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST + HD_CONTROLLER_EXPANSION_MAX - 1) + +#define HD_CONTROLLER_TYPE_PCMCIA (HD_CONTROLLER_TYPE_SCSI_LAST + 1) #define FILESYS_VIRTUAL 0 #define FILESYS_HARDFILE 1 diff --git a/src/include/genblitter.h b/src/include/genblitter.h index 032dbfc0..cb8116da 100644 --- a/src/include/genblitter.h +++ b/src/include/genblitter.h @@ -1,16 +1,20 @@ -/* - * UAE - The Un*x Amiga Emulator - * - * Optimized blitter minterm function generator - * - * Copyright 1995,1996 Bernd Schmidt - * Copyright 1996 Alessandro Bissacco - */ + /* + * UAE - The Un*x Amiga Emulator + * + * Optimized blitter minterm function generator + * + * Copyright 1995,1996 Bernd Schmidt + * Copyright 1996 Alessandro Bissacco + */ -struct blitop -{ +#ifndef UAE_GENBLITTER_H +#define UAE_GENBLITTER_H + +struct blitop { const char *s; int used; }; extern struct blitop blitops[256]; + +#endif /* UAE_GENBLITTER_H */ diff --git a/src/include/gfxboard.h b/src/include/gfxboard.h index 7b97d541..f9e850b2 100644 --- a/src/include/gfxboard.h +++ b/src/include/gfxboard.h @@ -1,6 +1,89 @@ -extern bool gfxboard_is_z3 (int); +#pragma once +#include "picasso96.h" + +extern bool gfxboard_init_memory(struct autoconfig_info*); +extern bool gfxboard_init_memory_p4_z2(struct autoconfig_info*); +extern bool gfxboard_init_registers(struct autoconfig_info*); +extern void gfxboard_free(void); +extern void gfxboard_reset(void); +extern bool gfxboard_vsync_handler(bool); +extern void gfxboard_hsync_handler(void); +extern int gfxboard_get_configtype(struct rtgboardconfig*); +extern bool gfxboard_is_registers(struct rtgboardconfig*); +extern int gfxboard_get_vram_min(struct rtgboardconfig*); +extern int gfxboard_get_vram_max(struct rtgboardconfig*); +extern bool gfxboard_need_byteswap(struct rtgboardconfig*); +extern int gfxboard_get_autoconfig_size(struct rtgboardconfig*); +extern double gfxboard_get_vsync(void); +extern void gfxboard_refresh(void); +extern int gfxboard_toggle(int mode, int msg); +extern int gfxboard_num_boards(struct rtgboardconfig*); +extern uae_u32 gfxboard_get_romtype(struct rtgboardconfig*); +extern const TCHAR *gfxboard_get_name(int); +extern const TCHAR *gfxboard_get_manufacturername(int); +extern const TCHAR *gfxboard_get_configname(int); +extern struct gfxboard_func *gfxboard_get_func(struct rtgboardconfig *rbc); + +extern bool gfxboard_allocate_slot(int, int); +extern void gfxboard_free_slot(int); +extern bool gfxboard_rtg_enable_initial(int); +extern void gfxboard_rtg_disable(int); +extern bool gfxboard_init_board(struct autoconfig_info*); + +extern struct gfxboard_func a2410_func; +extern struct gfxboard_func harlequin_func; + +extern void vga_io_put(int board, int portnum, uae_u8 v); +extern uae_u8 vga_io_get(int board, int portnum); +extern void vga_ram_put(int board, int offset, uae_u8 v); +extern uae_u8 vga_ram_get(int board, int offset); + +void gfxboard_get_a8_vram(int index); +void gfxboard_free_vram(int index); + +int gfxboard_get_devnum(struct uae_prefs *p, int index); #define GFXBOARD_UAE_Z2 0 #define GFXBOARD_UAE_Z3 1 #define GFXBOARD_HARDWARE 2 + +#define GFXBOARD_PICASSO2 2 +#define GFXBOARD_PICASSO2PLUS 3 +#define GFXBOARD_PICCOLO_Z2 4 +#define GFXBOARD_PICCOLO_Z3 5 +#define GFXBOARD_SD64_Z2 6 +#define GFXBOARD_SD64_Z3 7 +#define GFXBOARD_SPECTRUM_Z2 8 +#define GFXBOARD_SPECTRUM_Z3 9 +#define GFXBOARD_PICASSO4_Z2 10 +#define GFXBOARD_PICASSO4_Z3 11 +#define GFXBOARD_A2410 12 +#define GFXBOARD_VGA 13 + +struct gfxboard_mode +{ + int width; + int height; + RGBFTYPE mode; + bool redraw_required; +}; + +typedef bool(*GFXBOARD_INIT)(struct autoconfig_info*); +typedef void(*GFXBOARD_FREE)(void*); +typedef void(*GFXBOARD_RESET)(void*); +typedef void(*GFXBOARD_HSYNC)(void*); +typedef bool(*GFXBOARD_VSYNC)(void*, struct gfxboard_mode*); +typedef bool(*GFXBOARD_TOGGLE)(void*, int); +typedef void(*GFXBOARD_CONFIGURED)(void*, uae_u32); + +struct gfxboard_func +{ + GFXBOARD_INIT init; + GFXBOARD_FREE free; + GFXBOARD_RESET reset; + GFXBOARD_HSYNC hsync; + GFXBOARD_VSYNC vsync; + GFXBOARD_TOGGLE toggle; + GFXBOARD_CONFIGURED configured; +}; \ No newline at end of file diff --git a/src/include/inputdevice.h b/src/include/inputdevice.h index 351fa2ca..b3f03e0b 100644 --- a/src/include/inputdevice.h +++ b/src/include/inputdevice.h @@ -310,18 +310,17 @@ extern void setsystime (void); #define JSEM_MODE_LIGHTPEN 8 #define JSEM_KBDLAYOUT 0 +#define JSEM_CUSTOM 10 #define JSEM_JOYS 100 #define JSEM_MICE 200 #define JSEM_END 300 -#define JSEM_XARCADE1LAYOUT (JSEM_KBDLAYOUT + 3) -#define JSEM_XARCADE2LAYOUT (JSEM_KBDLAYOUT + 4) #define JSEM_DECODEVAL(port,p) ((p)->jports[port].id) #define JSEM_ISNUMPAD(port,p) (jsem_iskbdjoy(port,p) == JSEM_KBDLAYOUT) #define JSEM_ISCURSOR(port,p) (jsem_iskbdjoy(port,p) == JSEM_KBDLAYOUT + 1) #define JSEM_ISSOMEWHEREELSE(port,p) (jsem_iskbdjoy(port,p) == JSEM_KBDLAYOUT + 2) -#define JSEM_ISXARCADE1(port,p) (jsem_iskbdjoy(port,p) == JSEM_XARCADE1LAYOUT) -#define JSEM_ISXARCADE2(port,p) (jsem_iskbdjoy(port,p) == JSEM_XARCADE2LAYOUT) -#define JSEM_LASTKBD 5 +#define JSEM_ISCUSTOM(port,p) ((p)->jports[port].id >= JSEM_CUSTOM && (p)->jports[port].id < JSEM_CUSTOM + MAX_JPORTS_CUSTOM) +#define JSEM_GETCUSTOMIDX(port,p) ((p)->jports[port].id - JSEM_CUSTOM) +#define JSEM_LASTKBD 3 #define JSEM_ISANYKBD(port,p) (jsem_iskbdjoy(port,p) >= JSEM_KBDLAYOUT && jsem_iskbdjoy(port,p) < JSEM_KBDLAYOUT + JSEM_LASTKBD) extern int jsem_isjoy (int port, const struct uae_prefs *p); diff --git a/src/include/keybuf.h b/src/include/keybuf.h index 803cc613..28041c8e 100644 --- a/src/include/keybuf.h +++ b/src/include/keybuf.h @@ -7,8 +7,12 @@ * (c) 1996 Bernd Schmidt */ -extern int get_next_key (void); -extern int keys_available (void); -extern int record_key (int); -extern void keybuf_init (void); -extern int getcapslockstate (void); +#pragma once +extern int get_next_key(void); +extern int keys_available(void); +extern int record_key(int); +extern int record_key_direct(int); +extern void keybuf_init(void); +extern int getcapslockstate(void); +extern void setcapslockstate(int); +extern void keybuf_inject(const uae_char*); diff --git a/src/include/memory.h b/src/include/memory.h index 21c17a4b..1f37c79e 100644 --- a/src/include/memory.h +++ b/src/include/memory.h @@ -9,7 +9,11 @@ #ifndef MEMORY_H #define MEMORY_H -extern void memory_reset (void); +#include "options.h" + +extern void memory_reset(void); +extern void memory_restore(void); +extern void a1000_reset(void); #ifdef JIT extern int special_mem; @@ -25,65 +29,153 @@ extern void cache_free (uae_u8*, int); extern uae_u8* natmem_offset; #endif +bool init_shm(void); +void free_shm(void); +bool preinit_shm(void); +extern bool canbang; +extern bool jit_direct_compatible_memory; + +#define Z3BASE_UAE 0x10000000 +#define Z3BASE_REAL 0x40000000 + +#define AUTOCONFIG_Z2 0x00e80000 +#define AUTOCONFIG_Z2_MEM 0x00200000 +#define AUTOCONFIG_Z3 0xff000000 + #ifdef ADDRESS_SPACE_24BIT #define MEMORY_BANKS 256 #else #define MEMORY_BANKS 65536 +#define MEMORY_RANGE_MASK (~0) #endif -typedef uae_u32 (REGPARAM3 *mem_get_func)(uaecptr) REGPARAM; +typedef uae_u32(REGPARAM3 *mem_get_func)(uaecptr) REGPARAM; typedef void (REGPARAM3 *mem_put_func)(uaecptr, uae_u32) REGPARAM; typedef uae_u8 *(REGPARAM3 *xlate_func)(uaecptr) REGPARAM; typedef int (REGPARAM3 *check_func)(uaecptr, uae_u32) REGPARAM; extern uae_u32 max_z3fastmem; +extern uae_u32 wait_cpu_cycle_read(uaecptr addr, int mode); +extern void wait_cpu_cycle_write(uaecptr addr, int mode, uae_u32 v); +extern uae_u32 wait_cpu_cycle_read_ce020(uaecptr addr, int mode); +extern void wait_cpu_cycle_write_ce020(uaecptr addr, int mode, uae_u32 v); + #undef DIRECT_MEMFUNCS_SUCCESSFUL #include "machdep/maccess.h" #define chipmem_start_addr 0x00000000 #define bogomem_start_addr 0x00C00000 +#define cardmem_start_addr 0x00E00000 #define kickmem_start_addr 0x00F80000 #define ROM_SIZE_512 524288 #define ROM_SIZE_256 262144 +#define ROM_SIZE_128 131072 +extern bool ersatzkickfile; extern bool cloanto_rom, kickstart_rom; extern uae_u16 kickstart_version; -extern bool uae_boot_rom; +extern int uae_boot_rom_type; extern int uae_boot_rom_size; extern uaecptr rtarea_base; +extern uaecptr uaeboard_base; -enum { ABFLAG_UNK = 0, ABFLAG_RAM = 1, ABFLAG_ROM = 2, ABFLAG_ROMIN = 4, ABFLAG_IO = 8, ABFLAG_NONE = 16, ABFLAG_SAFE = 32 }; +extern uae_u8* baseaddr[]; + +enum +{ + ABFLAG_UNK = 0, ABFLAG_RAM = 1, ABFLAG_ROM = 2, ABFLAG_ROMIN = 4, ABFLAG_IO = 8, + ABFLAG_NONE = 16, ABFLAG_SAFE = 32, ABFLAG_INDIRECT = 64, ABFLAG_NOALLOC = 128, + ABFLAG_RTG = 256, ABFLAG_THREADSAFE = 512, ABFLAG_DIRECTMAP = 1024, ABFLAG_ALLOCINDIRECT = 2048, + ABFLAG_CHIPRAM = 4096, ABFLAG_CIA = 8192, ABFLAG_PPCIOSPACE = 16384, +}; typedef struct { - /* These ones should be self-explanatory... */ - mem_get_func lget, wget, bget; - mem_put_func lput, wput, bput; - /* Use xlateaddr to translate an Amiga address to a uae_u8 * that can - * be used to address memory without calling the wget/wput functions. - * This doesn't work for all memory banks, so this function may call - * abort(). */ - xlate_func xlateaddr; - /* To prevent calls to abort(), use check before calling xlateaddr. - * It checks not only that the memory bank can do xlateaddr, but also - * that the pointer points to an area of at least the specified size. - * This is used for example to translate bitplane pointers in custom.c */ - check_func check; - /* For those banks that refer to real memory, we can save the whole trouble - of going through function calls, and instead simply grab the memory - ourselves. This holds the memory address where the start of memory is - for this particular bank. */ - uae_u8 *baseaddr; - const TCHAR *name; - /* for instruction opcode/operand fetches */ - mem_get_func lgeti, wgeti; - int flags; + /* These ones should be self-explanatory... */ + mem_get_func lget, wget, bget; + mem_put_func lput, wput, bput; + /* Use xlateaddr to translate an Amiga address to a uae_u8 * that can + * be used to address memory without calling the wget/wput functions. + * This doesn't work for all memory banks, so this function may call + * abort(). */ + xlate_func xlateaddr; + /* To prevent calls to abort(), use check before calling xlateaddr. + * It checks not only that the memory bank can do xlateaddr, but also + * that the pointer points to an area of at least the specified size. + * This is used for example to translate bitplane pointers in custom.c */ + check_func check; + /* For those banks that refer to real memory, we can save the whole trouble + of going through function calls, and instead simply grab the memory + ourselves. This holds the memory address where the start of memory is + for this particular bank. */ + uae_u8 *baseaddr; + const TCHAR *label; + const TCHAR *name; + /* for instruction opcode/operand fetches */ + mem_get_func lgeti, wgeti; + int flags; + int jit_read_flag, jit_write_flag; + struct addrbank_sub *sub_banks; uae_u32 mask; uae_u32 startmask; uae_u32 start; - uae_u32 allocated; + // if RAM: size of allocated RAM. Zero if failed. + uae_u32 allocated_size; + // size of bank (if IO or before RAM allocation) + uae_u32 reserved_size; } addrbank; +#define MEMORY_MIN_SUBBANK 1024 +struct addrbank_sub +{ + addrbank *bank; + uae_u32 offset; + uae_u32 suboffset; + uae_u32 mask; + uae_u32 maskval; +}; + +struct autoconfig_info +{ + struct uae_prefs *prefs; + bool doinit; + bool postinit; + int devnum; + uae_u8 autoconfig_raw[128]; + uae_u8 autoconfig_bytes[16]; + TCHAR name[128]; + const uae_u8 *autoconfigp; + bool autoconfig_automatic; + uae_u32 start; + uae_u32 size; + int zorro; + const TCHAR *label; + addrbank *Addrbank; + uaecptr write_bank_address; + struct romconfig *rc; + uae_u32 last_high_ram; + const struct cpuboardsubtype *cst; + const struct expansionromtype *ert; + struct autoconfig_info *parent; + const int *parent_romtype; + bool parent_of_previous; + bool parent_address_space; + bool direct_vram; + const TCHAR *parent_name; + bool can_sort; + bool hardwired; + bool(*get_params)(struct uae_prefs*, struct expansion_params*); + bool(*set_params)(struct uae_prefs*, struct expansion_params*); + void *userdata; +}; + +#define CE_MEMBANK_FAST32 0 +#define CE_MEMBANK_CHIP16 1 +#define CE_MEMBANK_CHIP32 2 +#define CE_MEMBANK_CIA 3 +#define CE_MEMBANK_FAST16 4 +extern uae_u8 ce_banktype[65536], ce_cachable[65536]; + #define MEMORY_LGET(name) \ static uae_u32 REGPARAM3 name ## _lget (uaecptr) REGPARAM; \ static uae_u32 REGPARAM2 name ## _lget (uaecptr addr) \ @@ -146,7 +238,7 @@ static int REGPARAM2 name ## _check (uaecptr addr, uae_u32 size) \ { \ addr -= name ## _bank.start & name ## _bank.mask; \ addr &= name ## _bank.mask; \ - return (addr + size) <= name ## _bank.allocated; \ + return (addr + size) <= name ## _bank.allocated_size; \ } #define MEMORY_XLATE(name) \ static uae_u8 *REGPARAM3 name ## _xlate (uaecptr addr) REGPARAM; \ @@ -157,6 +249,30 @@ static uae_u8 *REGPARAM2 name ## _xlate (uaecptr addr) \ return name ## _bank.baseaddr + addr; \ } +#define DECLARE_MEMORY_FUNCTIONS(name) \ +static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _lget) (uaecptr) REGPARAM; \ +static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _lgeti) (uaecptr) REGPARAM; \ +static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _wget) (uaecptr) REGPARAM; \ +static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _wgeti) (uaecptr) REGPARAM; \ +static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _bget) (uaecptr) REGPARAM; \ +static void REGPARAM3 NOWARN_UNUSED(name ## _lput) (uaecptr, uae_u32) REGPARAM; \ +static void REGPARAM3 NOWARN_UNUSED(name ## _wput) (uaecptr, uae_u32) REGPARAM; \ +static void REGPARAM3 NOWARN_UNUSED(name ## _bput) (uaecptr, uae_u32) REGPARAM; \ +static int REGPARAM3 NOWARN_UNUSED(name ## _check) (uaecptr addr, uae_u32 size) REGPARAM; \ +static uae_u8 *REGPARAM3 NOWARN_UNUSED(name ## _xlate) (uaecptr addr) REGPARAM; + +#define DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(name, suffix) \ +static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _lget_ ## suffix) (uaecptr) REGPARAM; \ +static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _lgeti_ ## suffix) (uaecptr) REGPARAM; \ +static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _wget_ ## suffix) (uaecptr) REGPARAM; \ +static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _wgeti_ ## suffix) (uaecptr) REGPARAM; \ +static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _bget_ ## suffix) (uaecptr) REGPARAM; \ +static void REGPARAM3 NOWARN_UNUSED(name ## _lput_ ## suffix) (uaecptr, uae_u32) REGPARAM; \ +static void REGPARAM3 NOWARN_UNUSED(name ## _wput_ ## suffix) (uaecptr, uae_u32) REGPARAM; \ +static void REGPARAM3 NOWARN_UNUSED(name ## _bput_ ## suffix) (uaecptr, uae_u32) REGPARAM; \ +static int REGPARAM3 NOWARN_UNUSED(name ## _check_ ## suffix) (uaecptr addr, uae_u32 size) REGPARAM; \ +static uae_u8 *REGPARAM3 NOWARN_UNUSED(name ## _xlate_ ## suffix) (uaecptr addr) REGPARAM; + #define MEMORY_FUNCTIONS(name) \ MEMORY_LGET(name); \ MEMORY_WGET(name); \ @@ -167,53 +283,206 @@ MEMORY_BPUT(name); \ MEMORY_CHECK(name); \ MEMORY_XLATE(name); -extern uae_u8 *filesysory; -extern uae_u8 *rtarea; + +#define MEMORY_ARRAY_LGET(name, index) \ +static uae_u32 REGPARAM3 name ## index ## _lget (uaecptr) REGPARAM; \ +static uae_u32 REGPARAM2 name ## index ## _lget (uaecptr addr) \ +{ \ + uae_u8 *m; \ + addr -= name ## _bank[index].start & name ## _bank[index].mask; \ + addr &= name ## _bank[index].mask; \ + m = name ## _bank[index].baseaddr + addr; \ + return do_get_mem_long ((uae_u32 *)m); \ +} +#define MEMORY_ARRAY_WGET(name, index) \ +static uae_u32 REGPARAM3 name ## index ## _wget (uaecptr) REGPARAM; \ +static uae_u32 REGPARAM2 name ## index ## _wget (uaecptr addr) \ +{ \ + uae_u8 *m; \ + addr -= name ## _bank[index].start & name ## _bank[index].mask; \ + addr &= name ## _bank[index].mask; \ + m = name ## _bank[index].baseaddr + addr; \ + return do_get_mem_word ((uae_u16 *)m); \ +} +#define MEMORY_ARRAY_BGET(name, index) \ +static uae_u32 REGPARAM3 name ## index ## _bget (uaecptr) REGPARAM; \ +static uae_u32 REGPARAM2 name ## index ## _bget (uaecptr addr) \ +{ \ + addr -= name ## _bank[index].start & name ## _bank[index].mask; \ + addr &= name ## _bank[index].mask; \ + return name ## _bank[index].baseaddr[addr]; \ +} +#define MEMORY_ARRAY_LPUT(name, index) \ +static void REGPARAM3 name ## index ## _lput (uaecptr, uae_u32) REGPARAM; \ +static void REGPARAM2 name ## index ## _lput (uaecptr addr, uae_u32 l) \ +{ \ + uae_u8 *m; \ + addr -= name ## _bank[index].start & name ## _bank[index].mask; \ + addr &= name ## _bank[index].mask; \ + m = name ## _bank[index].baseaddr + addr; \ + do_put_mem_long ((uae_u32 *)m, l); \ +} +#define MEMORY_ARRAY_WPUT(name, index) \ +static void REGPARAM3 name ## index ## _wput (uaecptr, uae_u32) REGPARAM; \ +static void REGPARAM2 name ## index ## _wput (uaecptr addr, uae_u32 w) \ +{ \ + uae_u8 *m; \ + addr -= name ## _bank[index].start & name ## _bank[index].mask; \ + addr &= name ## _bank[index].mask; \ + m = name ## _bank[index].baseaddr + addr; \ + do_put_mem_word ((uae_u16 *)m, w); \ +} +#define MEMORY_ARRAY_BPUT(name, index) \ +static void REGPARAM3 name ## index ## _bput (uaecptr, uae_u32) REGPARAM; \ +static void REGPARAM2 name ## index ## _bput (uaecptr addr, uae_u32 b) \ +{ \ + addr -= name ## _bank[index].start & name ## _bank[index].mask; \ + addr &= name ## _bank[index].mask; \ + name ## _bank[index].baseaddr[addr] = b; \ +} +#define MEMORY_ARRAY_CHECK(name, index) \ +static int REGPARAM3 name ## index ## _check (uaecptr addr, uae_u32 size) REGPARAM; \ +static int REGPARAM2 name ## index ## _check (uaecptr addr, uae_u32 size) \ +{ \ + addr -= name ## _bank[index].start & name ## _bank[index].mask; \ + addr &= name ## _bank[index].mask; \ + return (addr + size) <= name ## _bank[index].allocated_size; \ +} +#define MEMORY_ARRAY_XLATE(name, index) \ +static uae_u8 *REGPARAM3 name ## index ## _xlate (uaecptr addr) REGPARAM; \ +static uae_u8 *REGPARAM2 name ## index ## _xlate (uaecptr addr) \ +{ \ + addr -= name ## _bank[index].start & name ## _bank[index].mask; \ + addr &= name ## _bank[index].mask; \ + return name ## _bank[index].baseaddr + addr; \ +} + +#define MEMORY_ARRAY_FUNCTIONS(name, index) \ +MEMORY_ARRAY_LGET(name, index); \ +MEMORY_ARRAY_WGET(name, index); \ +MEMORY_ARRAY_BGET(name, index); \ +MEMORY_ARRAY_LPUT(name, index); \ +MEMORY_ARRAY_WPUT(name, index); \ +MEMORY_ARRAY_BPUT(name, index); \ +MEMORY_ARRAY_CHECK(name, index); \ +MEMORY_ARRAY_XLATE(name, index); extern addrbank chipmem_bank; +extern addrbank chipmem_agnus_bank; +extern addrbank chipmem_bank_ce2; extern addrbank kickmem_bank; extern addrbank custom_bank; extern addrbank clock_bank; extern addrbank cia_bank; extern addrbank rtarea_bank; +extern addrbank filesys_bank; +extern addrbank uaeboard_bank; extern addrbank expamem_bank; -extern addrbank fastmem_bank; -extern addrbank gfxmem_bank; +extern addrbank expamem_null, expamem_none; +extern addrbank fastmem_bank[MAX_RAM_BOARDS]; +extern addrbank fastmem_nojit_bank[MAX_RAM_BOARDS]; +extern addrbank *gfxmem_banks[MAX_RTG_BOARDS]; +extern addrbank gayle_bank; +extern addrbank gayle2_bank; +extern addrbank mbres_bank; extern addrbank akiko_bank; +extern addrbank cardmem_bank; extern addrbank bogomem_bank; -extern addrbank z3fastmem_bank; +extern addrbank z3fastmem_bank[MAX_RAM_BOARDS]; +extern addrbank z3chipmem_bank; +extern addrbank mem25bit_bank; +extern addrbank a3000lmem_bank; +extern addrbank a3000hmem_bank; extern addrbank extendedkickmem_bank; extern addrbank extendedkickmem2_bank; +extern addrbank custmem1_bank; +extern addrbank custmem2_bank; -extern void rtarea_init (void); -extern void rtarea_init_mem (void); -extern void rtarea_setup (void); -extern void expamem_init (void); -extern void expamem_reset (void); -extern void expamem_next (void); +extern void rtarea_init(void); +extern void rtarea_free(void); +extern void rtarea_init_mem(void); +extern void rtarea_setup(void); +extern void expamem_reset(void); +extern void expamem_next(addrbank *mapped, addrbank *next); +extern void expamem_shutup(addrbank *mapped); +extern bool expamem_z3hack(struct uae_prefs*); +extern void expansion_cpu_fallback(void); +extern void set_expamem_z3_hack_mode(int); +extern uaecptr expamem_board_pointer, expamem_highmem_pointer; +extern uaecptr expamem_z3_pointer_real, expamem_z3_pointer_uae; +extern uae_u32 expamem_z3_highram_real, expamem_z3_highram_uae; +extern uae_u32 expamem_board_size; + +extern uae_u32 last_custom_value1; /* Default memory access functions */ +extern void dummy_put(uaecptr addr, int size, uae_u32 val); +extern uae_u32 dummy_get(uaecptr addr, int size, bool inst, uae_u32 defvalue); +extern uae_u32 dummy_get_safe(uaecptr addr, int size, bool inst, uae_u32 defvalue); + extern int REGPARAM3 default_check(uaecptr addr, uae_u32 size) REGPARAM; extern uae_u8 *REGPARAM3 default_xlate(uaecptr addr) REGPARAM; /* 680x0 opcode fetches */ -extern uae_u32 REGPARAM3 dummy_lgeti (uaecptr addr) REGPARAM; -extern uae_u32 REGPARAM3 dummy_wgeti (uaecptr addr) REGPARAM; +extern uae_u32 REGPARAM3 dummy_lgeti(uaecptr addr) REGPARAM; +extern uae_u32 REGPARAM3 dummy_wgeti(uaecptr addr) REGPARAM; + +/* sub bank support */ +extern uae_u32 REGPARAM3 sub_bank_lget(uaecptr) REGPARAM; +extern uae_u32 REGPARAM3 sub_bank_wget(uaecptr) REGPARAM; +extern uae_u32 REGPARAM3 sub_bank_bget(uaecptr) REGPARAM; +extern void REGPARAM3 sub_bank_lput(uaecptr, uae_u32) REGPARAM; +extern void REGPARAM3 sub_bank_wput(uaecptr, uae_u32) REGPARAM; +extern void REGPARAM3 sub_bank_bput(uaecptr, uae_u32) REGPARAM; +extern uae_u32 REGPARAM3 sub_bank_lgeti(uaecptr) REGPARAM; +extern uae_u32 REGPARAM3 sub_bank_wgeti(uaecptr) REGPARAM; +extern int REGPARAM3 sub_bank_check(uaecptr addr, uae_u32 size) REGPARAM; +extern uae_u8 *REGPARAM3 sub_bank_xlate(uaecptr addr) REGPARAM; +extern addrbank *get_sub_bank(uaecptr *addr); #define bankindex(addr) (((uaecptr)(addr)) >> 16) extern addrbank *mem_banks[MEMORY_BANKS]; -#define get_mem_bank(addr) (*mem_banks[bankindex(addr)]) +#ifdef JIT +extern uae_u8 *baseaddr[MEMORY_BANKS]; +#endif -extern void memory_init (void); -extern void memory_cleanup (void); -extern void map_banks (addrbank *bank, int first, int count, int realsize); -extern void map_banks_quick (addrbank *bank, int first, int count, int realsize); -extern void map_overlay (int chip); -extern void memory_hardreset (int); -extern void memory_clear (void); -extern void free_fastmemory (void); +#define get_mem_bank(addr) (*mem_banks[bankindex(addr)]) +extern addrbank *get_mem_bank_real(uaecptr); + +#ifdef JIT +#define put_mem_bank(addr, b, realstart) do { \ + (mem_banks[bankindex(addr)] = (b)); \ + if ((b)->baseaddr) \ + baseaddr[bankindex(addr)] = (b)->baseaddr - (realstart); \ + else \ + baseaddr[bankindex(addr)] = (uae_u8*)(((uae_u8*)b)+1); \ +} while (0) +#else +#define put_mem_bank(addr, b, realstart) \ + (mem_banks[bankindex(addr)] = (b)); +#endif + +extern void memory_init(void); +extern void memory_cleanup(void); +extern void restore_banks(void); +extern void map_banks(addrbank *bank, int first, int count, int realsize); +extern void map_banks_z2(addrbank *bank, int first, int count); +extern uae_u32 map_banks_z2_autosize(addrbank *bank, int first); +extern void map_banks_z3(addrbank *bank, int first, int count); +extern bool validate_banks_z2(addrbank *bank, int start, int size); +extern bool validate_banks_z3(addrbank *bank, int start, int size); +extern void map_banks_quick(addrbank *bank, int first, int count, int realsize); +extern void map_banks_nojitdirect(addrbank *bank, int first, int count, int realsize); +extern void map_banks_cond(addrbank *bank, int first, int count, int realsize); +extern void map_overlay(int chip); +extern void memory_hardreset(int); +extern void memory_clear(void); +extern void free_fastmemory(int); +extern void set_roms_modified(void); +extern void reload_roms(void); +extern bool read_kickstart_version(struct uae_prefs *p); #define longget(addr) (call_mem_get_func(get_mem_bank(addr).lget, addr)) #define wordget(addr) (call_mem_get_func(get_mem_bank(addr).wget, addr)) @@ -226,53 +495,90 @@ extern void free_fastmemory (void); STATIC_INLINE uae_u32 get_long(uaecptr addr) { - return longget(addr); + return longget(addr); } - STATIC_INLINE uae_u32 get_word(uaecptr addr) { - return wordget(addr); + return wordget(addr); } - STATIC_INLINE uae_u32 get_byte(uaecptr addr) { - return byteget(addr); + return byteget(addr); } - STATIC_INLINE uae_u32 get_longi(uaecptr addr) { return longgeti(addr); } - STATIC_INLINE uae_u32 get_wordi(uaecptr addr) { - return wordgeti(addr); + return wordgeti(addr); +} + +STATIC_INLINE uae_u32 get_long_jit(uaecptr addr) +{ + addrbank *bank = &get_mem_bank(addr); +#ifdef JIT + special_mem |= bank->jit_read_flag; +#endif + return bank->lget(addr); +} +STATIC_INLINE uae_u32 get_word_jit(uaecptr addr) +{ + addrbank *bank = &get_mem_bank(addr); +#ifdef JIT + special_mem |= bank->jit_read_flag; +#endif + return bank->wget(addr); +} +STATIC_INLINE uae_u32 get_byte_jit(uaecptr addr) +{ + addrbank *bank = &get_mem_bank(addr); +#ifdef JIT + special_mem |= bank->jit_read_flag; +#endif + return bank->bget(addr); +} +STATIC_INLINE uae_u32 get_longi_jit(uaecptr addr) +{ + addrbank *bank = &get_mem_bank(addr); +#ifdef JIT + special_mem |= bank->jit_read_flag; +#endif + return bank->lgeti(addr); +} +STATIC_INLINE uae_u32 get_wordi_jit(uaecptr addr) +{ + addrbank *bank = &get_mem_bank(addr); +#ifdef JIT + special_mem |= bank->jit_read_flag; +#endif + return bank->wgeti(addr); } /* - * Read a host pointer from addr - */ +* Read a host pointer from addr +*/ #if SIZEOF_VOID_P == 4 -# define get_pointer(addr) ((void *)get_long(addr)) +# define get_pointer(addr) ((void *)get_long (addr)) #else # if SIZEOF_VOID_P == 8 -STATIC_INLINE void *get_pointer (uaecptr addr) +STATIC_INLINE void *get_pointer(uaecptr addr) { - const unsigned int n = SIZEOF_VOID_P / 4; - union { - void *ptr; - uae_u32 longs[SIZEOF_VOID_P / 4]; - } p; - unsigned int i; + const unsigned int n = SIZEOF_VOID_P / 4; + union { + void *ptr; + uae_u32 longs[SIZEOF_VOID_P / 4]; + } p; + unsigned int i; - for (i = 0; i < n; i++) { + for (i = 0; i < n; i++) { #ifdef WORDS_BIGENDIAN - p.longs[i] = get_long (addr + i * 4); + p.longs[i] = get_long(addr + i * 4); #else - p.longs[n - 1 - i] = get_long (addr + i * 4); + p.longs[n - 1 - i] = get_long(addr + i * 4); #endif - } - return p.ptr; + } + return p.ptr; } # else # error "Unknown or unsupported pointer size." @@ -281,85 +587,195 @@ STATIC_INLINE void *get_pointer (uaecptr addr) STATIC_INLINE void put_long(uaecptr addr, uae_u32 l) { - longput(addr, l); + longput(addr, l); } STATIC_INLINE void put_word(uaecptr addr, uae_u32 w) { - wordput(addr, w); + wordput(addr, w); } STATIC_INLINE void put_byte(uaecptr addr, uae_u32 b) { - byteput(addr, b); + byteput(addr, b); +} + +STATIC_INLINE void put_long_jit(uaecptr addr, uae_u32 l) +{ + addrbank *bank = &get_mem_bank(addr); +#ifdef JIT + special_mem |= bank->jit_write_flag; +#endif + bank->lput(addr, l); +} +STATIC_INLINE void put_word_jit(uaecptr addr, uae_u32 l) +{ + addrbank *bank = &get_mem_bank(addr); +#ifdef JIT + special_mem |= bank->jit_write_flag; +#endif + bank->wput(addr, l); +} +STATIC_INLINE void put_byte_jit(uaecptr addr, uae_u32 l) +{ + addrbank *bank = &get_mem_bank(addr); +#ifdef JIT + special_mem |= bank->jit_write_flag; +#endif + bank->bput(addr, l); } /* - * Store host pointer v at addr - */ +* Store host pointer v at addr +*/ #if SIZEOF_VOID_P == 4 -# define put_pointer(addr, p) (put_long((addr), (uae_u32)(p))) +# define put_pointer(addr, p) (put_long ((addr), (uae_u32)(p))) #else # if SIZEOF_VOID_P == 8 -STATIC_INLINE void put_pointer (uaecptr addr, void *v) +STATIC_INLINE void put_pointer(uaecptr addr, void *v) { - const unsigned int n = SIZEOF_VOID_P / 4; - union { - void *ptr; - uae_u32 longs[SIZEOF_VOID_P / 4]; - } p; - unsigned int i; + const unsigned int n = SIZEOF_VOID_P / 4; + union { + void *ptr; + uae_u32 longs[SIZEOF_VOID_P / 4]; + } p; + unsigned int i; - p.ptr = v; + p.ptr = v; - for (i = 0; i < n; i++) { + for (i = 0; i < n; i++) { #ifdef WORDS_BIGENDIAN - put_long (addr + i * 4, p.longs[i]); + put_long(addr + i * 4, p.longs[i]); #else - put_long (addr + i * 4, p.longs[n - 1 - i]); + put_long(addr + i * 4, p.longs[n - 1 - i]); #endif - } + } } # endif #endif STATIC_INLINE uae_u8 *get_real_address(uaecptr addr) { - return get_mem_bank(addr).xlateaddr(addr); + return get_mem_bank(addr).xlateaddr(addr); } STATIC_INLINE int valid_address(uaecptr addr, uae_u32 size) { - return get_mem_bank(addr).check(addr, size); + return get_mem_bank(addr).check(addr, size); } -extern int addr_valid (const TCHAR*,uaecptr,uae_u32); +STATIC_INLINE void put_quad_host(void *addr, uae_u64 v) +{ + do_put_mem_long((uae_u32*)addr, v >> 32); + do_put_mem_long(((uae_u32*)addr) + 1, (uae_u32)v); +} +STATIC_INLINE void put_long_host(void *addr, uae_u32 v) +{ + do_put_mem_long((uae_u32*)addr, v); +} +STATIC_INLINE void put_word_host(void *addr, uae_u16 v) +{ + do_put_mem_word((uae_u16*)addr, v); +} +STATIC_INLINE void put_byte_host(void *addr, uae_u8 v) +{ + *((uae_u8*)addr) = v; +} +STATIC_INLINE uae_u64 get_quad_host(void *addr) +{ + uae_u64 v = ((uae_u64)do_get_mem_long((uae_u32*)addr)) << 32; + v |= do_get_mem_long(((uae_u32*)addr) + 1); + return v; +} +STATIC_INLINE uae_u32 get_long_host(void *addr) +{ + return do_get_mem_long((uae_u32*)addr); +} +STATIC_INLINE uae_u16 get_word_host(void *addr) +{ + return do_get_mem_word((uae_u16*)addr); +} +STATIC_INLINE uae_u32 get_byte_host(void *addr) +{ + return *((uae_u8*)addr); +} + +extern int addr_valid(const TCHAR*, uaecptr, uae_u32); /* For faster access in custom chip emulation. */ -extern void REGPARAM3 chipmem_agnus_wput (uaecptr addr, uae_u32 w); +extern void REGPARAM3 chipmem_lput(uaecptr, uae_u32) REGPARAM; +extern void REGPARAM3 chipmem_wput(uaecptr, uae_u32) REGPARAM; +extern void REGPARAM3 chipmem_bput(uaecptr, uae_u32) REGPARAM; + +extern uae_u32 REGPARAM3 chipmem_agnus_wget(uaecptr) REGPARAM; +extern void REGPARAM3 chipmem_agnus_wput(uaecptr, uae_u32) REGPARAM; -extern uae_u32 chipmem_full_mask; extern addrbank dummy_bank; -STATIC_INLINE uae_u32 chipmem_lget_indirect(uae_u32 PT) { - return do_get_mem_long((uae_u32 *)&chipmem_bank.baseaddr[PT & chipmem_full_mask]); -} -STATIC_INLINE uae_u32 chipmem_wget_indirect (uae_u32 PT) { - return do_get_mem_word((uae_u16 *)&chipmem_bank.baseaddr[PT & chipmem_full_mask]); -} +/* 68020+ Chip RAM DMA contention emulation */ +extern void REGPARAM3 chipmem_bput_c2(uaecptr, uae_u32) REGPARAM; -#define chipmem_wput_indirect chipmem_agnus_wput +extern uae_u32(REGPARAM3 *chipmem_lget_indirect)(uaecptr) REGPARAM; +extern uae_u32(REGPARAM3 *chipmem_wget_indirect)(uaecptr) REGPARAM; +extern uae_u32(REGPARAM3 *chipmem_bget_indirect)(uaecptr) REGPARAM; +extern void (REGPARAM3 *chipmem_lput_indirect)(uaecptr, uae_u32) REGPARAM; +extern void (REGPARAM3 *chipmem_wput_indirect)(uaecptr, uae_u32) REGPARAM; +extern void (REGPARAM3 *chipmem_bput_indirect)(uaecptr, uae_u32) REGPARAM; +extern int (REGPARAM3 *chipmem_check_indirect)(uaecptr, uae_u32) REGPARAM; +extern uae_u8 *(REGPARAM3 *chipmem_xlate_indirect)(uaecptr) REGPARAM; -extern uae_u8 *mapped_malloc (size_t, const TCHAR*); -extern void mapped_free (uae_u8 *); -extern void clearexec (void); +#ifdef NATMEM_OFFSET -extern uaecptr strcpyha_safe (uaecptr dst, const uae_char *src); -extern uae_char *strcpyah_safe (uae_char *dst, uaecptr src, int maxsize); -extern void memcpyha_safe (uaecptr dst, const uae_u8 *src, int size); -extern void memcpyha (uaecptr dst, const uae_u8 *src, int size); -extern void memcpyah_safe (uae_u8 *dst, uaecptr src, int size); -extern void memcpyah (uae_u8 *dst, uaecptr src, int size); +typedef struct shmpiece_reg { + uae_u8 *native_address; + int id; + uae_u32 size; + const TCHAR *name; + struct shmpiece_reg *next; + struct shmpiece_reg *prev; +} shmpiece; -extern uae_s32 getz2size (struct uae_prefs *p); -extern uae_u32 getz2endaddr (void); +extern shmpiece *shm_start; + +extern uae_u8* natmem_offset; +extern uae_u8 *natmem_reserved; +extern uae_u32 natmem_reserved_size; + +#endif + +extern bool mapped_malloc(addrbank*); +extern void mapped_free(addrbank*); +extern void a3000_fakekick(int); + +extern uaecptr strcpyha_safe(uaecptr dst, const uae_char *src); +extern uae_char *strcpyah_safe(uae_char *dst, uaecptr src, int maxsize); +extern void memcpyha_safe(uaecptr dst, const uae_u8 *src, int size); +extern void memcpyha(uaecptr dst, const uae_u8 *src, int size); +extern void memcpyah_safe(uae_u8 *dst, uaecptr src, int size); +extern void memcpyah(uae_u8 *dst, uaecptr src, int size); + +#define UAE_MEMORY_REGIONS_MAX 64 +#define UAE_MEMORY_REGION_NAME_LENGTH 64 + +#define UAE_MEMORY_REGION_RAM (1 << 0) +#define UAE_MEMORY_REGION_ALIAS (1 << 1) +#define UAE_MEMORY_REGION_MIRROR (1 << 2) + +/* Get a list of memory regions in the Amiga address space */ + +typedef struct UaeMemoryRegion { + uaecptr start; + uae_u32 size; + TCHAR name[UAE_MEMORY_REGION_NAME_LENGTH]; + TCHAR rom_name[UAE_MEMORY_REGION_NAME_LENGTH]; + uaecptr alias; + int flags; + uae_u8 *memory; +} UaeMemoryRegion; + +typedef struct UaeMemoryMap { + UaeMemoryRegion regions[UAE_MEMORY_REGIONS_MAX]; + int num_regions; +} UaeMemoryMap; + +void uae_memory_map(UaeMemoryMap *map); #endif /* MEMORY_H */ diff --git a/src/include/native2amiga.h b/src/include/native2amiga.h index fcddc41e..7a2493d4 100644 --- a/src/include/native2amiga.h +++ b/src/include/native2amiga.h @@ -10,8 +10,9 @@ * and some of it needs thread support. */ +#pragma once +#include "sysconfig.h" #include "native2amiga_api.h" - #include "traps.h" /* @@ -49,6 +50,5 @@ extern smp_comm_pipe native2amiga_pending; STATIC_INLINE void do_uae_int_requested (void) { - uae_int_requested |= 1; - set_uae_int_flag (); + uae_int_requested |= 1; } diff --git a/src/include/newcpu.h b/src/include/newcpu.h index bbfaa1fe..fd933f84 100644 --- a/src/include/newcpu.h +++ b/src/include/newcpu.h @@ -35,7 +35,8 @@ #include "readcpu.h" #include "machdep/m68k.h" -#include "memory.h" +#include "include/memory.h" +#include "events.h" extern const int areg_byteinc[]; extern const int imm8_table[]; @@ -54,17 +55,25 @@ typedef uae_u32 REGPARAM3 cpuop_func (uae_u32) REGPARAM; typedef void REGPARAM3 cpuop_func_ce (uae_u32) REGPARAM; struct cputbl { - cpuop_func *handler; - uae_u16 opcode; + cpuop_func *handler; + uae_u16 opcode; }; #ifdef JIT +#define MAX_JIT_CACHE 16384 typedef uae_u32 REGPARAM3 compop_func (uae_u32) REGPARAM; +#define COMP_OPCODE_ISJUMP 0x0001 +#define COMP_OPCODE_LONG_OPCODE 0x0002 +#define COMP_OPCODE_CMOV 0x0004 +#define COMP_OPCODE_ISADDX 0x0008 +#define COMP_OPCODE_ISCJUMP 0x0010 +#define COMP_OPCODE_USES_FPU 0x0020 + struct comptbl { - compop_func *handler; + compop_func *handler; uae_u32 specific; - uae_u32 opcode; + uae_u32 opcode; }; #endif @@ -104,8 +113,12 @@ struct regstruct uae_u8 *pc_oldp; uae_u32 instruction_pc; - uae_u16 irc, ir; - uae_u32 spcflags; + uae_u16 irc, ir, db; + volatile uae_atomic spcflags; + uae_u32 last_prefetch; + uae_u32 chipset_latch_rw; + uae_u32 chipset_latch_read; + uae_u32 chipset_latch_write; uaecptr usp, isp, msp; uae_u16 sr; @@ -115,8 +128,10 @@ struct regstruct flagtype m; flagtype x; flagtype stopped; - int halted; + int halted; + int exception; int intmask; + int ipl, ipl_pin; uae_u32 vbr,sfc,dfc; @@ -143,11 +158,8 @@ struct regstruct uae_u8 panic; uae_u32 panic_pc, panic_addr; - signed long pissoff; }; -extern unsigned long nextevent, is_syncline, currcycle; - extern struct regstruct regs; #include "events.h" @@ -160,10 +172,14 @@ STATIC_INLINE uae_u32 munge24(uae_u32 x) extern int cpu_cycles; extern bool m68k_pc_indirect; -STATIC_INLINE void set_special (uae_u32 x) +STATIC_INLINE void set_special_exter(uae_u32 x) { regs.spcflags |= x; - cycles_do_special(); +} +STATIC_INLINE void set_special(uae_u32 x) +{ + regs.spcflags |= x; + cycles_do_special(); } STATIC_INLINE void unset_special (uae_u32 x) diff --git a/src/include/options.h b/src/include/options.h index e9289152..1af20c1d 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -10,9 +10,10 @@ #ifndef OPTIONS_H #define OPTIONS_H -#define UAEMAJOR 2 -#define UAEMINOR 8 +#define UAEMAJOR 3 +#define UAEMINOR 4 #define UAESUBREV 1 +#include "traps.h" extern long int version; @@ -59,22 +60,29 @@ struct uae_input_device uae_s8 enabled; }; +#define MAX_JPORTS_CUSTOM 6 #define MAX_JPORTS 4 #define NORMAL_JPORTS 2 #define MAX_JPORTNAME 128 - -struct jport -{ +struct jport_custom { + TCHAR custom[MAX_DPATH]; +}; +struct inputdevconfig { + TCHAR name[MAX_JPORTNAME]; + TCHAR configname[MAX_JPORTNAME]; + TCHAR shortid[16]; +}; +struct jport { int id; int mode; // 0=def,1=mouse,2=joy,3=anajoy,4=lightpen int autofire; - TCHAR name[MAX_JPORTNAME]; - TCHAR configname[MAX_JPORTNAME]; + struct inputdevconfig idc; bool nokeyboardoverride; }; +#define JPORT_UNPLUGGED -2 #define JPORT_NONE -1 -#define JPORT_CUSTOM -2 + #define JPORT_AF_NORMAL 1 #define JPORT_AF_TOGGLE 2 #define JPORT_AF_ALWAYS 3 @@ -86,10 +94,18 @@ struct jport #define MAX_SPARE_DRIVES 20 #define MAX_CUSTOM_MEMORY_ADDRS 2 +#define CONFIG_TYPE_ALL -1 +#define CONFIG_TYPE_DEFAULT 0 #define CONFIG_TYPE_HARDWARE 1 #define CONFIG_TYPE_HOST 2 +#define CONFIG_TYPE_NORESET 4 #define CONFIG_BLEN 2560 +#define MOUSEUNTRAP_NONE 0 +#define MOUSEUNTRAP_MIDDLEBUTTON 1 +#define MOUSEUNTRAP_MAGIC 2 +#define MOUSEUNTRAP_BOTH 3 + #define TABLET_OFF 0 #define TABLET_MOUSEHACK 1 #define TABLET_REAL 2 @@ -110,9 +126,9 @@ struct cdslot TCHAR name[MAX_DPATH]; bool inuse; bool delayed; + bool temporary; int type; }; - struct floppyslot { TCHAR df[MAX_DPATH]; @@ -136,18 +152,33 @@ struct wh { #define UAEDEV_CD 2 #define UAEDEV_TAPE 3 +#define HD_LEVEL_SCSI_1 0 +#define HD_LEVEL_SCSI_2 1 +#define HD_LEVEL_SASI 2 +#define HD_LEVEL_SASI_ENHANCED 2 +#define HD_LEVEL_SASI_CHS 3 + +#define HD_LEVEL_ATA_1 0 +#define HD_LEVEL_ATA_2 1 +#define HD_LEVEL_ATA_2S 2 + #define BOOTPRI_NOAUTOBOOT -128 #define BOOTPRI_NOAUTOMOUNT -129 #define ISAUTOBOOT(ci) ((ci)->bootpri > BOOTPRI_NOAUTOBOOT) #define ISAUTOMOUNT(ci) ((ci)->bootpri > BOOTPRI_NOAUTOMOUNT) - -struct uaedev_config_info +#define MAX_UAEDEV_BADBLOCKS 8 +struct uaedev_badblock { + uae_u32 first; + uae_u32 last; +}; +struct uaedev_config_info { int type; TCHAR devname[MAX_DPATH]; TCHAR volname[MAX_DPATH]; TCHAR rootdir[MAX_DPATH]; bool readonly; + bool lock; int bootpri; TCHAR filesys[MAX_DPATH]; int lowcyl; @@ -157,8 +188,13 @@ struct uaedev_config_info int sectors; int reserved; int blocksize; - int controller; - // zero if default + int controller_type; + int controller_type_unit; + int controller_unit; + int controller_media_type; // 1 = CF IDE, 0 = normal + int unit_feature_level; + int unit_special_flags; + bool physical_geometry; // if false: use defaults int pcyls, pheads, psecs; int flags; int buffers; @@ -173,6 +209,9 @@ struct uaedev_config_info int sectorsperblock; int forceload; int device_emu_unit; + bool inject_icons; + int badblock_num; + struct uaedev_badblock badblocks[MAX_UAEDEV_BADBLOCKS]; }; struct uaedev_config_data @@ -183,8 +222,8 @@ struct uaedev_config_data }; enum { - CP_GENERIC = 1, CP_CDTV, CP_CD32, CP_A500, CP_A500P, CP_A600, CP_A1000, - CP_A1200, CP_A2000, CP_A3000, CP_A3000T, CP_A4000, CP_A4000T + CP_GENERIC = 1, CP_CDTV, CP_CDTVCR, CP_CD32, CP_A500, CP_A500P, CP_A600, CP_A1000, + CP_A1200, CP_A2000, CP_A3000, CP_A3000T, CP_A4000, CP_A4000T, CP_VELVET }; #define IDE_A600A1200 1 @@ -204,11 +243,22 @@ enum { #define AUTOSCALE_MANUAL 7 // use gfx_xcenter_pos and gfx_ycenter_pos #define AUTOSCALE_INTEGER 8 #define AUTOSCALE_INTEGER_AUTOSCALE 9 +#define AUTOSCALE_SEPARATOR 10 +#define AUTOSCALE_OVERSCAN_BLANK 11 #define MONITOREMU_NONE 0 #define MONITOREMU_AUTO 1 #define MONITOREMU_A2024 2 #define MONITOREMU_GRAFFITI 3 +#define MONITOREMU_HAM_E 4 +#define MONITOREMU_HAM_E_PLUS 5 +#define MONITOREMU_VIDEODAC18 6 +#define MONITOREMU_AVIDEO12 7 +#define MONITOREMU_AVIDEO24 8 +#define MONITOREMU_FIRECRACKER24 9 +#define MONITOREMU_DCTV 10 +#define MONITOREMU_OPALVISION 11 +#define MONITOREMU_COLORBURST 12 #define MAX_FILTERSHADERS 4 @@ -219,18 +269,24 @@ enum { struct chipset_refresh { + bool inuse; int index; bool locked; bool rtg; + bool exit; + bool defaultdata; int horiz; int vert; int lace; + int resolution; + int resolution_pct; int ntsc; int vsync; int framelength; double rate; TCHAR label[16]; TCHAR commands[256]; + TCHAR filterprofile[64]; }; #define APMODE_NATIVE 0 @@ -279,6 +335,62 @@ struct gfx_filterdata int gfx_filter_keep_autoscale_aspect; }; +#define MAX_DUPLICATE_EXPANSION_BOARDS 4 +#define MAX_EXPANSION_BOARDS 20 +struct boardromconfig; +struct romconfig +{ + TCHAR romfile[MAX_DPATH]; + TCHAR romident[256]; + uae_u32 board_ram_size; + bool autoboot_disabled; + int device_id; + int device_settings; + int subtype; + void *unitdata; + TCHAR configtext[256]; + struct boardromconfig *back; +}; +#define MAX_BOARD_ROMS 2 +struct boardromconfig +{ + int device_type; + int device_num; + int device_order; + struct romconfig roms[MAX_BOARD_ROMS]; +}; +#define MAX_RTG_BOARDS 4 +struct rtgboardconfig +{ + int rtg_index; + int rtgmem_type; + uae_u32 rtgmem_size; + int device_order; +}; +#define MAX_RAM_BOARDS 4 +struct ramboard +{ + uae_u32 size; + uae_u16 manufacturer; + uae_u8 product; + uae_u8 autoconfig[16]; + bool autoconfig_inuse; + bool manual_config; + bool no_reset_unmap; + int device_order; + uae_u32 start_address; + uae_u32 end_address; + uae_u32 write_address; +}; +struct expansion_params +{ + int device_order; +}; + +#define Z3MAPPING_AUTO 0 +#define Z3MAPPING_UAE 1 +#define Z3MAPPING_REAL 2 + struct uae_prefs { struct strlist* all_lines; @@ -288,6 +400,7 @@ struct uae_prefs int config_version; TCHAR config_hardware_path[MAX_DPATH]; TCHAR config_host_path[MAX_DPATH]; + TCHAR config_all_path[MAX_DPATH]; TCHAR config_window_title[256]; bool illegal_mem; @@ -296,6 +409,7 @@ struct uae_prefs bool serial_hwctsrts; bool serial_direct; int serial_stopbits; + int serial_crlf; bool parallel_demand; int parallel_matrix_emulation; bool parallel_postscript_emulation; @@ -317,11 +431,16 @@ struct uae_prefs int sound_interpol; int sound_filter; int sound_filter_type; - int sound_volume; + int sound_volume_master; + int sound_volume_paula; int sound_volume_cd; + int sound_volume_board; + int sound_volume_midi; + int sound_volume_genlock; bool sound_stereo_swap_paula; bool sound_stereo_swap_ahi; bool sound_auto; + bool sound_cdaudio; int sampler_freq; int sampler_buffer; @@ -333,18 +452,12 @@ struct uae_prefs int comptrustnaddr; bool compnf; bool compfpu; - bool comp_midopt; - bool comp_lowopt; - bool fpu_strict; - bool comp_hardflush; bool comp_constjump; - bool comp_oldsegv; - int cachesize; - int optcount[10]; + bool fpu_strict; - bool avoid_cmov; + bool fpu_softfloat; int gfx_framerate, gfx_autoframerate; struct wh gfx_size_win; @@ -366,12 +479,15 @@ struct uae_prefs int gfx_xcenter_pos, gfx_ycenter_pos; int gfx_xcenter_size, gfx_ycenter_size; int gfx_max_horizontal, gfx_max_vertical; - int gfx_saturation, gfx_luminance, gfx_contrast, gfx_gamma; + int gfx_saturation, gfx_luminance, gfx_contrast, gfx_gamma, gfx_gamma_ch[3]; bool gfx_blackerthanblack; + int gfx_threebitcolors; int gfx_api; int color_mode; int gfx_extrawidth; bool lightboost_strobo; + int lightboost_strobo_ratio; + bool gfx_grayscale; struct gfx_filterdata gf[2]; @@ -381,8 +497,16 @@ struct uae_prefs bool immediate_blits; int waiting_blits; unsigned int chipset_mask; + bool keyboard_connected; bool ntscmode; bool genlock; + int genlock_image; + int genlock_mix; + int genlock_scale; + int genlock_aspect; + bool genlock_alpha; + TCHAR genlock_image_file[MAX_DPATH]; + TCHAR genlock_video_file[MAX_DPATH]; int monitoremu; double chipset_refreshrate; struct chipset_refresh cr[MAX_CHIPSET_REFRESH + 2]; @@ -398,23 +522,34 @@ struct uae_prefs bool uaeserial; int catweasel; int cpu_idle; + int ppc_cpu_idle; bool cpu_cycle_exact; int cpu_clock_multiplier; int cpu_frequency; bool blitter_cycle_exact; + bool cpu_memory_cycle_exact; int floppy_speed; int floppy_write_length; int floppy_random_bits_min; int floppy_random_bits_max; int floppy_auto_ext2; + int cd_speed; bool tod_hack; uae_u32 maprom; + int boot_rom; bool rom_readwrite; int turbo_emulation; + int turbo_emulation_limit; bool headless; int filesys_limit; int filesys_max_name; int filesys_max_file_size; + bool filesys_inject_icons; + TCHAR filesys_inject_icons_tool[MAX_DPATH]; + TCHAR filesys_inject_icons_project[MAX_DPATH]; + TCHAR filesys_inject_icons_drawer[MAX_DPATH]; + int uaescsidevmode; + bool reset_delay; int cs_compatible; int cs_ciaatod; @@ -427,6 +562,8 @@ struct uae_prefs bool cs_cd32cd; bool cs_cd32c2p; bool cs_cd32nvram; + bool cs_cd32fmv; + int cs_cd32nvram_size; bool cs_cdtvcd; bool cs_cdtvram; int cs_cdtvcard; @@ -439,6 +576,7 @@ struct uae_prefs int cs_deniserev; int cs_mbdmac; bool cs_cdtvscsi; + bool cs_cdtvcr; bool cs_df0idhw; bool cs_slowmemisfast; bool cs_resetwarning; @@ -446,20 +584,21 @@ struct uae_prefs bool cs_dipagnus; bool cs_agnusbltbusybug; bool cs_ciatodbug; + bool cs_z3autoconfig; + bool cs_1mchipjumper; + bool cs_cia6526; + bool cs_bytecustomwritebug; + bool cs_color_burst; int cs_hacks; + struct boardromconfig expansionboard[MAX_EXPANSION_BOARDS]; + TCHAR romfile[MAX_DPATH]; TCHAR romident[256]; TCHAR romextfile[MAX_DPATH]; uae_u32 romextfile2addr; TCHAR romextfile2[MAX_DPATH]; TCHAR romextident[256]; - TCHAR a2091romfile[MAX_DPATH]; - TCHAR a2091romident[256]; - bool a2091; - TCHAR a4091romfile[MAX_DPATH]; - TCHAR a4091romident[256]; - bool a4091; TCHAR flashfile[MAX_DPATH]; TCHAR rtcfile[MAX_DPATH]; TCHAR cartfile[MAX_DPATH]; @@ -468,13 +607,16 @@ struct uae_prefs TCHAR pci_devices[256]; TCHAR prtname[256]; TCHAR sername[256]; - TCHAR amaxromfile[MAX_DPATH]; TCHAR a2065name[MAX_DPATH]; + TCHAR ne2000pciname[MAX_DPATH]; + TCHAR ne2000pcmcianame[MAX_DPATH]; + TCHAR picassoivromfile[MAX_DPATH]; struct cdslot cdslots[MAX_TOTAL_SCSI_DEVICES]; TCHAR quitstatefile[MAX_DPATH]; TCHAR statefile[MAX_DPATH]; TCHAR inprecfile[MAX_DPATH]; bool inprec_autoplay; + bool refresh_indicator; struct multipath path_floppy; struct multipath path_hardfile; @@ -483,35 +625,48 @@ struct uae_prefs int m68k_speed; double m68k_speed_throttle; + double x86_speed_throttle; int cpu_model; int mmu_model; int cpu060_revision; int fpu_model; int fpu_revision; + int ppc_mode; + TCHAR ppc_model[32]; bool cpu_compatible; + bool cpu_thread; bool int_no_unimplemented; bool fpu_no_unimplemented; bool address_space_24; bool picasso96_nocustom; int picasso96_modeflags; + int cpu_model_fallback; - uae_u32 z3fastmem_size, z3fastmem2_size; - uae_u32 z3fastmem_start; + uae_u32 z3autoconfig_start; + struct ramboard z3fastmem[MAX_RAM_BOARDS]; + struct ramboard fastmem[MAX_RAM_BOARDS]; uae_u32 z3chipmem_size; uae_u32 z3chipmem_start; - uae_u32 fastmem_size, fastmem2_size; - bool fastmem_autoconfig; uae_u32 chipmem_size; uae_u32 bogomem_size; uae_u32 mbresmem_low_size; uae_u32 mbresmem_high_size; - uae_u32 rtgmem_size; + uae_u32 mem25bit_size; + int cpuboard_type; + int cpuboard_subtype; + int cpuboard_settings; + uae_u32 cpuboardmem1_size; + uae_u32 cpuboardmem2_size; + int ppc_implementation; bool rtg_hardwareinterrupt; bool rtg_hardwaresprite; - int rtgmem_type; bool rtg_more_compatible; + struct rtgboardconfig rtgboards[MAX_RTG_BOARDS]; uae_u32 custom_memory_addrs[MAX_CUSTOM_MEMORY_ADDRS]; uae_u32 custom_memory_sizes[MAX_CUSTOM_MEMORY_ADDRS]; + uae_u32 custom_memory_mask[MAX_CUSTOM_MEMORY_ADDRS]; + int uaeboard; + int uaeboard_order; bool kickshifter; bool filesys_no_uaefsdb; @@ -521,7 +676,12 @@ struct uae_prefs bool clipboard_sharing; bool native_code; bool uae_hide_autoconfig; - bool jit_direct_compatible_memory; + int z3_mapping_mode; + bool autoconfig_custom_sort; + bool obs_sound_toccata; + bool obs_sound_toccata_mixer; + bool obs_sound_es1370; + bool obs_sound_fm801; int mountitems; struct uaedev_config_data mountconfig[MOUNT_CONFIG_SIZE]; @@ -529,8 +689,10 @@ struct uae_prefs int nr_floppies; struct floppyslot floppyslots[4]; bool floppy_read_only; + bool harddrive_read_only; TCHAR dfxlist[MAX_SPARE_DRIVES][MAX_DPATH]; - int dfxclickvolume; + int dfxclickvolume_disk[4]; + int dfxclickvolume_empty[4]; int dfxclickchannelmask; TCHAR luafiles[MAX_LUA_STATES][MAX_DPATH]; @@ -551,10 +713,17 @@ struct uae_prefs #endif int statecapturerate, statecapturebuffersize; + int aviout_width, aviout_height, aviout_xoffset, aviout_yoffset; + int screenshot_width, screenshot_height, screenshot_xoffset, screenshot_yoffset; + int screenshot_min_width, screenshot_min_height; + int screenshot_max_width, screenshot_max_height; + int screenshot_output_width, screenshot_output_height; + int screenshot_xmult, screenshot_ymult; /* input */ struct jport jports[MAX_JPORTS]; + struct jport_custom jports_custom[MAX_JPORTS_CUSTOM]; int input_selected_setting; int input_joymouse_multiplier; int input_joymouse_deadzone; @@ -566,9 +735,10 @@ struct uae_prefs int input_mouse_speed; int input_tablet; bool tablet_library; - bool input_magic_mouse; + int input_mouse_untrap; int input_magic_mouse_cursor; int input_keyboard_type; + int input_autoswitch; struct uae_input_device joystick_settings[MAX_INPUT_SETTINGS][MAX_INPUT_DEVICES]; struct uae_input_device mouse_settings[MAX_INPUT_SETTINGS][MAX_INPUT_DEVICES]; struct uae_input_device keyboard_settings[MAX_INPUT_SETTINGS][MAX_INPUT_DEVICES]; @@ -576,6 +746,7 @@ struct uae_prefs TCHAR input_config_name[GAMEPORT_INPUT_SETTINGS][256]; int dongle; int input_contact_bounce; + int input_device_match_mask; }; extern int config_changed; @@ -610,7 +781,7 @@ extern void error_log(const TCHAR*, ...); extern TCHAR *get_error_log(void); extern bool is_error_log(void); -extern void default_prefs(struct uae_prefs *, int); +extern void default_prefs(struct uae_prefs *, bool, int); extern void discard_prefs(struct uae_prefs *, int); int parse_cmdline_option(struct uae_prefs *, TCHAR, const TCHAR*); @@ -635,21 +806,23 @@ extern int cfgfile_load(struct uae_prefs *p, const TCHAR *filename, int *type, i extern int cfgfile_save(struct uae_prefs *p, const TCHAR *filename, int); extern void cfgfile_parse_line(struct uae_prefs *p, TCHAR *, int); extern void cfgfile_parse_lines(struct uae_prefs *p, const TCHAR *, int); -extern int cfgfile_parse_option(struct uae_prefs *p, TCHAR *option, TCHAR *value, int); +extern int cfgfile_parse_option(struct uae_prefs *p, const TCHAR *option, TCHAR *value, int); extern int cfgfile_get_description(const TCHAR *filename, TCHAR *description, TCHAR *hostlink, TCHAR *hardwarelink, int *type); extern void cfgfile_show_usage(void); extern int cfgfile_searchconfig(const TCHAR *in, int index, TCHAR *out, int outsize); -extern uae_u32 cfgfile_uaelib(int mode, uae_u32 name, uae_u32 dst, uae_u32 maxlen); -extern uae_u32 cfgfile_uaelib_modify(uae_u32 mode, uae_u32 parms, uae_u32 size, uae_u32 out, uae_u32 outsize); -extern uae_u32 cfgfile_modify(uae_u32 index, TCHAR *parms, uae_u32 size, TCHAR *out, uae_u32 outsize); +extern uae_u32 cfgfile_uaelib(TrapContext *ctx, int mode, uae_u32 name, uae_u32 dst, uae_u32 maxlen); +extern uae_u32 cfgfile_uaelib_modify(TrapContext *ctx, uae_u32 mode, uae_u32 parms, uae_u32 size, uae_u32 out, uae_u32 outsize); +extern uae_u32 cfgfile_modify(uae_u32 index, const TCHAR *parms, uae_u32 size, TCHAR *out, uae_u32 outsize); extern void cfgfile_addcfgparam(TCHAR *); extern int built_in_prefs(struct uae_prefs *p, int model, int config, int compa, int romcheck); extern int built_in_chipset_prefs(struct uae_prefs *p); extern int cmdlineparser(const TCHAR *s, TCHAR *outp[], int max); extern int cfgfile_configuration_change(int); extern void fixup_prefs_dimensions(struct uae_prefs *prefs); -extern void fixup_prefs(struct uae_prefs *prefs); +extern void fixup_prefs(struct uae_prefs *prefs, bool userconfig); extern void fixup_cpu(struct uae_prefs *prefs); +extern void cfgfile_compatibility_romtype(struct uae_prefs *p); +extern void cfgfile_compatibility_rtg(struct uae_prefs *p); extern void check_prefs_changed_custom(void); extern void check_prefs_changed_cpu(void); diff --git a/src/include/picasso96.h b/src/include/picasso96.h index 697600c1..d4e74d15 100644 --- a/src/include/picasso96.h +++ b/src/include/picasso96.h @@ -553,29 +553,31 @@ struct Line { /************************************************************************/ struct picasso96_state_struct { - uae_u32 RGBFormat; /* true-colour, CLUT, hi-colour, etc. */ - struct MyCLUTEntry CLUT[256]; /* Duh! */ - uaecptr Address; /* Active screen address (Amiga-side) */ - uaecptr Extent; /* End address of screen (Amiga-side) */ - uae_u16 Width; /* Active display width (From SetGC) */ - uae_u16 VirtualWidth;/* Total screen width (From SetPanning) */ - uae_u16 BytesPerRow; /* Total screen width in bytes (From SetGC) */ - uae_u16 Height; /* Active display height (From SetGC) */ - uae_u16 VirtualHeight; /* Total screen height */ - uae_u8 GC_Depth; /* From SetGC() */ - uae_u8 GC_Flags; /* From SetGC() */ - long XOffset; /* From SetPanning() */ - long YOffset; /* From SetPanning() */ - uae_u8 SwitchState; /* From SetSwitch() - 0 is Amiga, 1 is Picasso */ - uae_u8 BytesPerPixel; - uae_u8 CardFound; - //here follow winuae additional entrys - uae_u8 *HostAddress; /* Active screen address (PC-side) */ - // host address is need because Windows - // support NO direct access all the time to gfx Card - // everytime windows can remove your surface from card so the mainrender place - // must be in memory - long XYOffset; + RGBFTYPE RGBFormat; /* true-colour, CLUT, hi-colour, etc.*/ + struct MyCLUTEntry CLUT[256]; /* Duh! */ + uaecptr Address; /* Active screen address (Amiga-side)*/ + uaecptr Extent; /* End address of screen (Amiga-side)*/ + uae_u16 Width; /* Active display width (From SetGC)*/ + uae_u16 VirtualWidth;/* Total screen width (From SetPanning)*/ + uae_u16 BytesPerRow; /* Total screen width in bytes (FromSetGC) */ + uae_u16 Height; /* Active display height (From SetGC)*/ + uae_u16 VirtualHeight; /* Total screen height */ + uae_u8 GC_Depth; /* From SetGC() */ + uae_u8 GC_Flags; /* From SetGC() */ + long XOffset; /* From SetPanning() */ + long YOffset; /* From SetPanning() */ + uae_u8 SwitchState; /* From SetSwitch() - 0 is Amiga, 1 isPicasso */ + uae_u8 BytesPerPixel; + uae_u8 CardFound; + //here follow winuae additional entrys + uae_u8 BigAssBitmap; /* Set to 1 when our Amiga screen is bigger than the displayable area */ + unsigned int Version; + uae_u8 *HostAddress; /* Active screen address (PC-side) */ + // host address is need because Windows + // support NO direct access all the time to gfx Card + // everytime windows can remove your surface from card so the mainrender place + // must be in memory + long XYOffset; }; extern void InitPicasso96 (void); @@ -594,6 +596,7 @@ extern void picasso_handle_vsync (void); extern void picasso_trigger_vblank (void); extern void picasso_reset (void); extern int picasso_palette (void); +extern bool picasso_flushpixels(int index); /* This structure describes the UAE-side framebuffer for the Picasso * screen. */ @@ -609,11 +612,13 @@ struct picasso_vidbuf_description { extern struct picasso_vidbuf_description picasso_vidinfo; extern void gfx_set_picasso_modeinfo (uae_u32 w, uae_u32 h, uae_u32 d, RGBFTYPE rgbfmt); +extern void gfx_set_picasso_colors(RGBFTYPE rgbfmt); extern void gfx_set_picasso_baseaddr (uaecptr); extern void gfx_set_picasso_state (int on); extern uae_u8 *gfx_lock_picasso (void); extern void gfx_unlock_picasso (void); +extern int p96refresh_active; extern int p96hsync_counter; #define LIB_SIZE 34 diff --git a/src/include/rommgr.h b/src/include/rommgr.h index b8bf6f2e..cf3dfa4c 100644 --- a/src/include/rommgr.h +++ b/src/include/rommgr.h @@ -1,94 +1,255 @@ -extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size); +#pragma once +extern int decode_cloanto_rom_do(uae_u8 *mem, int size, int real_size); -#define ROMTYPE_KICK 0x000001 -#define ROMTYPE_KICKCD32 0x000002 -#define ROMTYPE_EXTCD32 0x000004 -#define ROMTYPE_EXTCDTV 0x000008 -#define ROMTYPE_A2091BOOT 0x000010 -#define ROMTYPE_A4091BOOT 0x000020 -#define ROMTYPE_AR 0x000040 -#define ROMTYPE_SUPERIV 0x000080 -#define ROMTYPE_KEY 0x000100 -#define ROMTYPE_ARCADIABIOS 0x000200 -#define ROMTYPE_ARCADIAGAME 0x000400 -#define ROMTYPE_HRTMON 0x000800 -#define ROMTYPE_NORDIC 0x001000 -#define ROMTYPE_XPOWER 0x002000 -#define ROMTYPE_CD32CART 0x004000 -#define ROMTYPE_SPECIALKICK 0x008000 -#define ROMTYPE_MASK 0x01ffff -#define ROMTYPE_EVEN 0x020000 -#define ROMTYPE_ODD 0x040000 -#define ROMTYPE_8BIT 0x080000 -#define ROMTYPE_BYTESWAP 0x100000 -#define ROMTYPE_CD32 0x200000 -#define ROMTYPE_SCRAMBLED 0x400000 -#define ROMTYPE_NONE 0x800000 +#define ROMTYPE_SUB_MASK 0x000000ff +#define ROMTYPE_GROUP_MASK 0x003fff00 +#define ROMTYPE_MASK 0x003fffff + +#define ROMTYPE_KICK 0x00000100 +#define ROMTYPE_KICKCD32 0x00000200 +#define ROMTYPE_EXTCD32 0x00000400 +#define ROMTYPE_EXTCDTV 0x00000800 +#define ROMTYPE_KEY 0x00001000 +#define ROMTYPE_ARCADIABIOS 0x00002000 +#define ROMTYPE_ARCADIAGAME 0x00004000 +#define ROMTYPE_CD32CART 0x00008000 +#define ROMTYPE_SPECIALKICK 0x00010000 +#define ROMTYPE_ALG 0x00020000 + +#define ROMTYPE_CPUBOARD 0x00040000 +#define ROMTYPE_CB_A3001S1 0x00040001 +#define ROMTYPE_CB_APOLLO 0x00040002 +#define ROMTYPE_CB_FUSION 0x00040003 +#define ROMTYPE_CB_DKB12x0 0x00040004 +#define ROMTYPE_CB_WENGINE 0x00040005 +#define ROMTYPE_CB_TEKMAGIC 0x00040006 +#define ROMTYPE_CB_BLIZ1230 0x00040007 +#define ROMTYPE_CB_BLIZ1260 0x00040008 +#define ROMTYPE_CB_BLIZ2060 0x00040009 +#define ROMTYPE_CB_A26x0 0x0004000a +#define ROMTYPE_CB_CSMK1 0x0004000b +#define ROMTYPE_CB_CSMK2 0x0004000c +#define ROMTYPE_CB_CSMK3 0x0004000d +#define ROMTYPE_CB_CSPPC 0x0004000e +#define ROMTYPE_CB_BLIZPPC 0x0004000f +#define ROMTYPE_CB_GOLEM030 0x00040010 +#define ROMTYPE_CB_ACA500 0x00040011 +#define ROMTYPE_CB_DBK_WF 0x00040012 +#define ROMTYPE_CB_EMATRIX 0x00040013 +#define ROMTYPE_CB_SX32PRO 0x00040014 +#define ROMTYPE_CB_B1230MK2 0x00040015 +#define ROMTYPE_CB_B1230MK3 0x00040016 +#define ROMTYPE_CB_VECTOR 0x00040017 + +#define ROMTYPE_FREEZER 0x00080000 +#define ROMTYPE_AR 0x00080001 +#define ROMTYPE_AR2 0x00080002 +#define ROMTYPE_HRTMON 0x00080003 +#define ROMTYPE_NORDIC 0x00080004 +#define ROMTYPE_XPOWER 0x00080005 +#define ROMTYPE_SUPERIV 0x00080006 + +#define ROMTYPE_SCSI 0x00100000 +#define ROMTYPE_A2091 0x00100001 +#define ROMTYPE_A4091 0x00100002 +#define ROMTYPE_BLIZKIT4 0x00100003 +#define ROMTYPE_FASTLANE 0x00100004 +#define ROMTYPE_OKTAGON 0x00100005 +#define ROMTYPE_GVPS1 0x00100006 +#define ROMTYPE_GVPS12 0x00100007 +#define ROMTYPE_GVPS2 0x00100008 +#define ROMTYPE_AMAX 0x00100009 +#define ROMTYPE_ALFA 0x0010000a +#define ROMTYPE_ALFAPLUS 0x0010000b +#define ROMTYPE_APOLLO 0x0010000c +#define ROMTYPE_MASOBOSHI 0x0010000d +#define ROMTYPE_SUPRA 0x0010000e +#define ROMTYPE_A2090 0x0010000f +#define ROMTYPE_GOLEM 0x00100010 +#define ROMTYPE_STARDRIVE 0x00100011 +#define ROMTYPE_KOMMOS 0x00100012 +#define ROMTYPE_VECTOR 0x00100013 +#define ROMTYPE_ADIDE 0x00100014 +#define ROMTYPE_MTEC 0x00100015 +#define ROMTYPE_PROTAR 0x00100016 +#define ROMTYPE_ADD500 0x00100017 +#define ROMTYPE_KRONOS 0x00100018 +#define ROMTYPE_ADSCSI 0x00100019 +#define ROMTYPE_ROCHARD 0x0010001a +#define ROMTYPE_CLTDSCSI 0x0010001b +#define ROMTYPE_PTNEXUS 0x0010001c +#define ROMTYPE_DATAFLYERP 0x0010001d +#define ROMTYPE_SUPRADMA 0x0010001e +#define ROMTYPE_GREX 0x0010001f +#define ROMTYPE_PROMETHEUS 0x00100020 +#define ROMTYPE_MEDIATOR 0x00100021 +#define ROMTYPE_TECMAR 0x00100022 +#define ROMTYPE_XEBEC 0x00100023 +#define ROMTYPE_MICROFORGE 0x00100024 +#define ROMTYPE_PARADOX 0x00100025 +#define ROMTYPE_HDA506 0x00100026 +#define ROMTYPE_ALF1 0x00100027 +#define ROMTYPE_PROMIGOS 0x00100028 +#define ROMTYPE_SYSTEM2000 0x00100029 +#define ROMTYPE_A1060 0x0010002a +#define ROMTYPE_A2088 0x0010002b +#define ROMTYPE_A2088T 0x0010002c +#define ROMTYPE_A2286 0x0010002d +#define ROMTYPE_A2386 0x0010002e +#define ROMTYPE_OMTIADAPTER 0x0010002f +#define ROMTYPE_X86_HD 0x00100030 +#define ROMTYPE_X86_AT_HD1 0x00100031 +#define ROMTYPE_X86_AT_HD2 0x00100032 +#define ROMTYPE_X86_XT_IDE 0x00100033 +#define ROMTYPE_PICASSOIV 0x00100034 +#define ROMTYPE_x86_VGA 0x00100035 +#define ROMTYPE_APOLLOHD 0x00100036 +#define ROMTYPE_MEVOLUTION 0x00100037 +#define ROMTYPE_GOLEMFAST 0x00100038 +#define ROMTYPE_PHOENIXB 0x00100039 +#define ROMTYPE_IVSTPRO 0x0010003A +#define ROMTYPE_TOCCATA 0x0010003B +#define ROMTYPE_ES1370 0x0010003C +#define ROMTYPE_FM801 0x0010003D +#define ROMTYPE_UAESNDZ2 0x0010003E +#define ROMTYPE_UAESNDZ3 0x0010003F +#define ROMTYPE_RAMZ2 0x00100040 +#define ROMTYPE_RAMZ3 0x00100041 +#define ROMTYPE_CATWEASEL 0x00100042 +#define ROMTYPE_CDTVSCSI 0x00100043 +#define ROMTYPE_MB_IDE 0x00100044 +#define ROMTYPE_SCSI_A3000 0x00100045 +#define ROMTYPE_SCSI_A4000T 0x00100046 +#define ROMTYPE_MB_PCMCIA 0x00100047 +#define ROMTYPE_MEGACHIP 0x00100048 +#define ROMTYPE_A2065 0x00100049 +#define ROMTYPE_NE2KPCI 0x0010004a +#define ROMTYPE_NE2KPCMCIA 0x0010004b +#define ROMTYPE_CDTVDMAC 0x0010004c +#define ROMTYPE_CDTVCR 0x0010004d +#define ROMTYPE_IVSVECTOR 0x0010004e +#define ROMTYPE_BUDDHA 0x0010004f +#define ROMTYPE_NE2KISA 0x00100050 +#define ROMTYPE_BLIZKIT3 0x00100051 +#define ROMTYPE_SCRAM5380 0x00100052 +#define ROMTYPE_SCRAM5394 0x00100053 +#define ROMTYPE_OSSI 0x00100054 +#define ROMTYPE_HARLEQUIN 0x00100055 +#define ROMTYPE_DATAFLYER 0x00100056 +#define ROMTYPE_ARIADNE2 0x00100057 +#define ROMTYPE_XSURF 0x00100058 +#define ROMTYPE_XSURF100Z2 0x00100059 +#define ROMTYPE_XSURF100Z3 0x0010005a +#define ROMTYPE_HYDRA 0x0010005b +#define ROMTYPE_LANROVER 0x0010005c +#define ROMTYPE_ARIADNE 0x0010005d +#define ROMTYPE_HARDFRAME 0x0010005e +#define ROMTYPE_ATEAM 0x0010005f +#define ROMTYPE_PMX 0x00100060 + +#define ROMTYPE_NOT 0x00800000 +#define ROMTYPE_QUAD 0x01000000 +#define ROMTYPE_EVEN 0x02000000 +#define ROMTYPE_ODD 0x04000000 +#define ROMTYPE_8BIT 0x08000000 +#define ROMTYPE_BYTESWAP 0x10000000 +#define ROMTYPE_CD32 0x20000000 +#define ROMTYPE_SCRAMBLED 0x40000000 +#define ROMTYPE_NONE 0x80000000 #define ROMTYPE_ALL_KICK (ROMTYPE_KICK | ROMTYPE_KICKCD32 | ROMTYPE_CD32) #define ROMTYPE_ALL_EXT (ROMTYPE_EXTCD32 | ROMTYPE_EXTCDTV) #define ROMTYPE_ALL_CART (ROMTYPE_AR | ROMTYPE_HRTMON | ROMTYPE_NORDIC | ROMTYPE_XPOWER | ROMTYPE_CD32CART) struct romheader { - const char *name; - int id; + const TCHAR *name; + int id; }; struct romdata { - const char *name; - int ver, rev; - int subver, subrev; - const char *model; - uae_u32 size; - int id; - int cpu; - int cloanto; - int type; - int group; - int title; - const char *partnumber; - uae_u32 crc32; - uae_u32 sha1[5]; - const char *configname; + const TCHAR *name; + int ver, rev; + int subver, subrev; + const TCHAR *model; + uae_u32 size; + int id; + int cpu; + int cloanto; + uae_u32 type; + int group; + int title; + const TCHAR *partnumber; + uae_u32 crc32; + uae_u32 sha1[5]; + const TCHAR *configname; + const TCHAR *defaultfilename; }; struct romlist { - TCHAR *path; - struct romdata *rd; + TCHAR *path; + struct romdata *rd; }; -extern struct romdata *getromdatabypath (const TCHAR *path); -extern struct romdata *getromdatabycrc (uae_u32 crc32); -extern struct romdata *getromdatabycrc (uae_u32 crc32, bool); -extern struct romdata *getromdatabydata (uae_u8 *rom, int size); -extern struct romdata *getromdatabyid (int id); -extern struct romdata *getromdatabyidgroup (int id, int group, int subitem); -extern struct romdata *getromdatabyzfile (struct zfile *f); -extern struct romlist **getarcadiaroms (void); -extern struct romdata *getarcadiarombyname (const TCHAR *name); -extern struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, const TCHAR *model, int romflags, bool all); -extern void getromname (const struct romdata*, TCHAR*); -extern struct romdata *getromdatabyname (const TCHAR*); -extern struct romlist *getromlistbyids(const int *ids); +extern struct romdata *getromdatabypath(const TCHAR *path); +extern struct romdata *getromdatabycrc(uae_u32 crc32); +extern struct romdata *getromdatabycrc(uae_u32 crc32, bool); +extern struct romdata *getromdatabydata(uae_u8 *rom, int size); +extern struct romdata *getromdatabyid(int id); +extern struct romdata *getromdatabyidgroup(int id, int group, int subitem); +extern struct romdata *getromdatabyzfile(struct zfile *f); +extern struct romdata *getfrombydefaultname(const TCHAR *name, int size); +extern struct romlist **getarcadiaroms(void); +extern struct romdata *getarcadiarombyname(const TCHAR *name); +extern struct romlist **getromlistbyident(int ver, int rev, int subver, int subrev, const TCHAR *model, int romflags, bool all); +extern void getromname(const struct romdata*, TCHAR*); +extern struct romdata *getromdatabyname(const TCHAR*); +extern struct romlist *getromlistbyids(const int *ids, const TCHAR *romname); +extern struct romdata *getromdatabyids(const int *ids); +extern struct romlist *getromlistbyromtype(uae_u32 romtype); extern void romwarning(const int *ids); extern struct romlist *getromlistbyromdata(const struct romdata *rd); -extern void romlist_add (const TCHAR *path, struct romdata *rd); -extern TCHAR *romlist_get (const struct romdata *rd); -extern void romlist_clear (void); -extern struct zfile *read_rom (struct romdata *rd); -extern struct zfile *read_rom_name (const TCHAR *filename); +extern void romlist_add(const TCHAR *path, struct romdata *rd); +extern TCHAR *romlist_get(const struct romdata *rd); +extern void romlist_clear(void); +extern struct zfile *read_rom(struct romdata *rd); +extern struct zfile *read_rom_name(const TCHAR *filename); +extern struct zfile *read_device_from_romconfig(struct romconfig *rc, uae_u32 romtype); -extern int load_keyring (struct uae_prefs *p, const TCHAR *path); -extern uae_u8 *target_load_keyfile (struct uae_prefs *p, const TCHAR *path, int *size, TCHAR *name); -extern void free_keyring (void); -extern int get_keyring (void); -extern void kickstart_fix_checksum (uae_u8 *mem, int size); -extern int kickstart_checksum (uae_u8 *mem, int size); -extern int decode_rom (uae_u8 *mem, int size, int mode, int real_size); -extern struct zfile *rom_fopen (const TCHAR *name, const TCHAR *mode, int mask); -extern struct zfile *read_rom_name_guess (const TCHAR *filename); -extern void addkeydir (const TCHAR *path); -extern void addkeyfile (const TCHAR *path); -extern int romlist_count (void); -extern struct romlist *romlist_getit (void); -extern int configure_rom (struct uae_prefs *p, const int *rom, int msg); +extern int load_keyring(struct uae_prefs *p, const TCHAR *path); +extern uae_u8 *target_load_keyfile(struct uae_prefs *p, const TCHAR *path, int *size, TCHAR *name); +extern void free_keyring(void); +extern int get_keyring(void); +extern void kickstart_fix_checksum(uae_u8 *mem, int size); +extern void descramble_nordicpro(uae_u8*, int, int); +extern int kickstart_checksum(uae_u8 *mem, int size); +extern int decode_rom(uae_u8 *mem, int size, int mode, int real_size); +extern struct zfile *rom_fopen(const TCHAR *name, const TCHAR *mode, int mask); +extern struct zfile *read_rom_name_guess(const TCHAR *filename); +extern void addkeydir(const TCHAR *path); +extern void addkeyfile(const TCHAR *path); +extern int romlist_count(void); +extern struct romlist *romlist_getit(void); +extern int configure_rom(struct uae_prefs *p, const int *rom, int msg); + +int is_device_rom(struct uae_prefs *p, int romtype, int devnum); +struct zfile *read_device_rom(struct uae_prefs *p, int romtype, int devnum, int *roms); +struct romconfig *get_device_romconfig(struct uae_prefs *p, int romtype, int devnum); +struct boardromconfig *get_device_rom(struct uae_prefs *p, int romtype, int devnum, int *index); +void set_device_rom(struct uae_prefs *p, const TCHAR *path, int romtype, int devnum); +const struct expansionromtype *get_device_expansion_rom(int romtype); +const struct expansionromtype *get_unit_expansion_rom(int hdunit); +struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int devnum, int *index); +void clear_device_rom(struct uae_prefs *p, int romtype, int devnum, bool deleteDevice); +struct boardromconfig *get_boardromconfig(struct uae_prefs *p, int romtype, int *index); +bool is_board_enabled(struct uae_prefs *p, int romtype, int devnum); +void board_prefs_changed(int romtype, int devnum); + +#define LOADROM_FILL 1 +#define LOADROM_EVENONLY 2 +#define LOADROM_EVENONLY_ODDONE ((255 << 16) | LOADROM_EVENONLY) +#define LOADROM_ONEFILL 4 +#define LOADROM_ZEROFILL 8 +#define LOADROM_ODDFILL(x) ((x << 16) | LOADROM_EVENONLY) +bool load_rom_rc(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags); + +#define EXPANSION_ORDER_MAX 10000 diff --git a/src/include/savestate.h b/src/include/savestate.h index 09770010..8f24fc75 100644 --- a/src/include/savestate.h +++ b/src/include/savestate.h @@ -125,7 +125,7 @@ extern uae_u8 *save_input (int *len, uae_u8 *dstptr); extern void restore_cram (int, size_t); extern void restore_bram (int, size_t); -extern void restore_fram (int, size_t); +extern void restore_fram(int, size_t, int); extern void restore_zram (int, size_t, int); extern void restore_bootrom (int, size_t); extern void restore_pram (int, size_t); @@ -133,7 +133,7 @@ extern void restore_ram (size_t, uae_u8*); extern uae_u8 *save_cram(int *); extern uae_u8 *save_bram(int *); -extern uae_u8 *save_fram(int *); +extern uae_u8 *save_fram(int *, int); extern uae_u8 *save_zram(int *, int); extern uae_u8 *save_bootrom(int *); extern uae_u8 *save_pram(int *); diff --git a/src/include/sysdeps.h b/src/include/sysdeps.h index c02854f7..54aced6a 100644 --- a/src/include/sysdeps.h +++ b/src/include/sysdeps.h @@ -22,16 +22,43 @@ using namespace std; #include #include -#ifdef _GCCRES_ -#undef _GCCRES_ +#ifndef UAE +#define UAE #endif -#ifdef UAE4ALL_NO_USE_RESTRICT -#define _GCCRES_ +#if defined(__x86_64__) || defined(_M_AMD64) +#define CPU_x86_64 1 +#define CPU_64_BIT 1 +#elif defined(__i386__) || defined(_M_IX86) +#define CPU_i386 1 +#elif defined(__arm__) || defined(_M_ARM) +#define CPU_arm 1 +#elif defined(__powerpc__) || defined(_M_PPC) +#define CPU_powerpc 1 #else -#define _GCCRES_ __restrict__ +#error unrecognized CPU type #endif +//#ifdef _WIN32 +/* Parameters are passed in ECX, EDX for both x86 and x86-64 (RCX, RDX). +* For x86-64, __fastcall is the default, so it isn't really required. */ +//#define JITCALL __fastcall +//#elif defined(CPU_x86_64) +///* Parameters are passed in RDI, RSI by default (System V AMD64 ABI). */ +//#define JITCALL +//#elif defined(HAVE_FUNC_ATTRIBUTE_REGPARM) +///* Parameters are passed in EAX, EDX on x86 with regparm(2). */ +//#define JITCALL __attribute__((regparm(2))) +///* This was originally regparm(3), but as far as I can see only two register +//* params are supported by the JIT code. It probably just worked anyway +//* if all functions used max two arguments. */ +//#elif !defined(JIT) +//#define JITCALL +//#endif +#define REGPARAM +#define REGPARAM2 +#define REGPARAM3 + #ifndef __STDC__ #error "Your compiler is not ANSI. Get a real one." #endif @@ -117,15 +144,6 @@ struct utimbuf }; #endif -#if defined(__GNUC__) && defined(AMIGA) -/* gcc on the amiga need that __attribute((regparm)) must */ -/* be defined in function prototypes as well as in */ -/* function definitions ! */ -#define REGPARAM2 REGPARAM -#else /* not(GCC & AMIGA) */ -#define REGPARAM2 -#endif - /* sam: some definitions so that SAS/C can compile UAE */ #if defined(__SASC) && defined(AMIGA) #define REGPARAM2 @@ -215,6 +233,12 @@ typedef uae_u32 uaecptr; #define UVAL64(a) (a ## ul) #endif +void atomic_and(volatile uae_atomic *p, uae_u32 v); +void atomic_or(volatile uae_atomic *p, uae_u32 v); +uae_atomic atomic_inc(volatile uae_atomic *p); +uae_atomic atomic_dec(volatile uae_atomic *p); +uae_u32 atomic_bit_test_and_reset(volatile uae_atomic *p, uae_u32 v); + #ifdef HAVE_STRDUP #define my_strdup strdup #else @@ -226,6 +250,8 @@ extern void my_trim(TCHAR*); extern TCHAR *my_strdup_trim(const TCHAR*); extern TCHAR *au(const char*); extern char *ua(const TCHAR*); +extern TCHAR *aucp(const char *s, unsigned int cp); +extern char *uacp(const TCHAR *s, unsigned int cp); extern TCHAR *au_fs(const char*); extern char *ua_fs(const TCHAR*, int); extern char *ua_copy(char *dst, int maxlen, const TCHAR *src); @@ -234,7 +260,9 @@ extern char *ua_fs_copy(char *dst, int maxlen, const TCHAR *src, int defchar); extern TCHAR *au_fs_copy(TCHAR *dst, int maxlen, const char *src); extern char *uutf8(const TCHAR *s); extern TCHAR *utf8u(const char *s); +extern void unicode_init(void); extern void to_lower(TCHAR *s, int len); +extern void to_upper(TCHAR *s, int len); /* We can only rely on GNU C getting enums right. Mickeysoft VSC++ is known * to have problems, and it's likely that other compilers choke too. */ @@ -267,8 +295,8 @@ extern void to_lower(TCHAR *s, int len); #undef DONT_HAVE_STDIO #undef DONT_HAVE_MALLOC -#if defined AMIBERRY - +#ifdef AMIBERRY +#include #include #define FILEFLAG_DIR 0x1 @@ -279,17 +307,6 @@ extern void to_lower(TCHAR *s, int len); #define FILEFLAG_SCRIPT 0x20 #define FILEFLAG_PURE 0x40 -#define REGPARAM2 -#define REGPARAM3 -#define REGPARAM - -#define abort() \ - do { \ - printf ("Internal error; file %s, line %d\n", __FILE__, __LINE__); \ - SDL_Quit(); \ - (abort) (); \ -} while (0) - #endif #ifdef DONT_HAVE_POSIX @@ -371,6 +388,8 @@ extern void mallocemu_free(void *ptr); #define ASM_SYM_FOR_FUNC(a) #endif +#include "target.h" + #ifdef UAE_CONSOLE #undef write_log #define write_log write_log_standard @@ -392,11 +411,7 @@ extern void gui_message(const TCHAR *, ...); #ifndef STATIC_INLINE #if __GNUC__ - 1 > 1 && __GNUC_MINOR__ - 1 >= 0 -#ifdef RASPBERRY -#define STATIC_INLINE static __inline__ -#else #define STATIC_INLINE static __inline__ __attribute__ ((always_inline)) -#endif #define NOINLINE __attribute__ ((noinline)) #define NORETURN __attribute__ ((noreturn)) #elif _MSC_VER @@ -410,8 +425,6 @@ extern void gui_message(const TCHAR *, ...); #endif #endif -#include "target.h" - /* Every Amiga hardware clock cycle takes this many "virtual" cycles. This used to be hardcoded as 1, but using higher values allows us to time some stuff more precisely. @@ -498,4 +511,10 @@ extern void xfree(const void*); #endif -#define DBLEQU(f, i) (abs ((f) - (i)) < 0.000001) \ No newline at end of file +#define DBLEQU(f, i) (abs ((f) - (i)) < 0.000001) + +#ifdef HAVE_VAR_ATTRIBUTE_UNUSED +#define NOWARN_UNUSED(x) __attribute__((unused)) x +#else +#define NOWARN_UNUSED(x) x +#endif \ No newline at end of file diff --git a/src/include/traps.h b/src/include/traps.h index 06e6f027..70cd93d1 100644 --- a/src/include/traps.h +++ b/src/include/traps.h @@ -13,10 +13,42 @@ #ifndef TRAPS_H #define TRAPS_H +#include "sysconfig.h" + +#define TRAPCMD_MULTI 0 +#define TRAPCMD_PUT_LONG 1 +#define TRAPCMD_PUT_WORD 2 +#define TRAPCMD_PUT_BYTE 3 +#define TRAPCMD_GET_LONG 4 +#define TRAPCMD_GET_WORD 5 +#define TRAPCMD_GET_BYTE 6 +#define TRAPCMD_PUT_BYTES 7 +#define TRAPCMD_PUT_WORDS 8 +#define TRAPCMD_PUT_LONGS 9 +#define TRAPCMD_GET_BYTES 10 +#define TRAPCMD_GET_WORDS 11 +#define TRAPCMD_GET_LONGS 12 +#define TRAPCMD_PUT_STRING 13 +#define TRAPCMD_GET_STRING 14 +#define TRAPCMD_SET_LONGS 15 +#define TRAPCMD_SET_WORDS 16 +#define TRAPCMD_SET_BYTES 17 +#define TRAPCMD_CALL_LIB 18 +#define TRAPCMD_CALL_FUNC 19 +#define TRAPCMD_NOP 20 +#define TRAPCMD_GET_BSTR 21 + +struct trapmd { + uae_u16 cmd; + uae_u32 params[4]; + uae_u8 trapmd_index, parm_num; + uae_u8 *haddr; +}; + /* * Data passed to a trap handler */ -struct TrapContext; +typedef struct TrapContext TrapContext; #define TRAPFLAG_NO_REGSAVE 1 @@ -26,33 +58,90 @@ struct TrapContext; #define TRAPFLAG_UAERES 16 /* - * A function which handles a 68k trap - */ -typedef uae_u32 (REGPARAM3 *TrapHandler) (TrapContext *) REGPARAM; +* A function which handles a 68k trap +*/ +typedef uae_u32(REGPARAM3 *TrapHandler) (TrapContext *) REGPARAM; /* - * Interface with 68k interpreter - */ -extern void REGPARAM3 m68k_handle_trap (unsigned int trap_num) REGPARAM; +* Interface with 68k interpreter +*/ +extern void REGPARAM3 m68k_handle_trap(unsigned int trap_num) REGPARAM; -unsigned int define_trap (TrapHandler handler_func, int flags, const TCHAR *name); -uaecptr find_trap (const TCHAR *name); +unsigned int define_trap(TrapHandler handler_func, int flags, const TCHAR *name); +uaecptr find_trap(const TCHAR *name); /* - * Call a 68k Library function from an extended trap - */ -extern uae_u32 CallLib (TrapContext *context, uaecptr library_base, uae_s16 func_offset); -extern uae_u32 CallFunc (TrapContext *context, uaecptr func); +* Call a 68k Library function from an extended trap +*/ +extern uae_u32 CallLib(TrapContext *context, uaecptr library_base, uae_s16 func_offset); +extern uae_u32 CallFunc(TrapContext *context, uaecptr func); /* - * Initialization - */ -void init_traps (void); -void init_extended_traps (void); +* Initialization +*/ +void init_traps(void); +void free_traps(void); +void init_extended_traps(void); -#define deftrap(f) define_trap((f), 0, _T("")) +#define deftrap(f) define_trap((f), 0, _T(#f)) #define deftrap2(f, mode, str) define_trap((f), (mode), (str)) #define deftrapres(f, mode, str) define_trap((f), (mode | TRAPFLAG_UAERES), (str)) +/* New trap system */ + +void call_hardware_trap(uae_u8*, uaecptr, int); +void trap_set_background(TrapContext *ctx); +void trap_background_set_complete(TrapContext *ctx); +bool trap_valid_address(TrapContext *ctx, uaecptr addr, uae_u32 size); +bool trap_is_indirect(void); +void trap_dos_active(void); +void trap_reset(void); +typedef uae_u32(*TRAP_CALLBACK)(TrapContext*, void*); +void trap_callback(TRAP_CALLBACK, void*); + +void trap_memcpyha_safe(TrapContext *ctx, uaecptr dst, const uae_u8 *src, int size); +void trap_memcpyah_safe(TrapContext *ctx, uae_u8 *dst, uaecptr src, int size); + +TrapContext *alloc_host_main_trap_context(void); +TrapContext *alloc_host_thread_trap_context(void); +void free_host_trap_context(TrapContext*); + +uae_u32 trap_get_dreg(TrapContext *ctx, int reg); +uae_u32 trap_get_areg(TrapContext *ctx, int reg); +void trap_set_dreg(TrapContext *ctx, int reg, uae_u32 v); +void trap_set_areg(TrapContext *ctx, int reg, uae_u32 v); + +void trap_put_quad(TrapContext *ctx, uaecptr addr, uae_u64 v); +void trap_put_long(TrapContext *ctx, uaecptr addr, uae_u32 v); +void trap_put_word(TrapContext *ctx, uaecptr addr, uae_u16 v); +void trap_put_byte(TrapContext *ctx, uaecptr addr, uae_u8 v); + +uae_u64 trap_get_quad(TrapContext *ctx, uaecptr addr); +uae_u32 trap_get_long(TrapContext *ctx, uaecptr addr); +uae_u16 trap_get_word(TrapContext *ctx, uaecptr addr); +uae_u8 trap_get_byte(TrapContext *ctx, uaecptr addr); + +void trap_put_bytes(TrapContext *ctx, const void *haddrp, uaecptr addr, int cnt); +void trap_get_bytes(TrapContext *ctx, void *haddrp, uaecptr addr, int cnt); +void trap_put_longs(TrapContext *ctx, uae_u32 *haddr, uaecptr addr, int cnt); +void trap_get_longs(TrapContext *ctx, uae_u32 *haddr, uaecptr addr, int cnt); +void trap_put_words(TrapContext *ctx, uae_u16 *haddr, uaecptr addr, int cnt); +void trap_get_words(TrapContext *ctx, uae_u16 *haddr, uaecptr addr, int cnt); + +int trap_put_string(TrapContext *ctx, const void *haddrp, uaecptr addr, int maxlen); +int trap_get_string(TrapContext *ctx, void *haddrp, uaecptr addr, int maxlen); +uae_char *trap_get_alloc_string(TrapContext *ctx, uaecptr addr, int maxlen); + +void trap_set_longs(TrapContext *ctx, uaecptr addr, uae_u32 v, int cnt); +void trap_set_words(TrapContext *ctx, uaecptr addr, uae_u16 v, int cnt); +void trap_set_bytes(TrapContext *ctx, uaecptr addr, uae_u8 v, int cnt); + +void trap_multi(TrapContext *ctx, struct trapmd *data, int items); + +void trap_call_add_dreg(TrapContext *ctx, int reg, uae_u32 v); +void trap_call_add_areg(TrapContext *ctx, int reg, uae_u32 v); +uae_u32 trap_call_lib(TrapContext *ctx, uaecptr base, uae_s16 offset); +uae_u32 trap_call_func(TrapContext *ctx, uaecptr func); + #endif diff --git a/src/include/xwin.h b/src/include/xwin.h index ce07333b..718f6107 100644 --- a/src/include/xwin.h +++ b/src/include/xwin.h @@ -38,7 +38,9 @@ extern int bits_in_mask (unsigned long mask); extern int mask_shift (unsigned long mask); extern unsigned int doMask (int p, int bits, int shift); extern unsigned int doMask256 (int p, int bits, int shift); -extern void alloc_colors64k (int, int, int, int, int, int, int); +extern void alloc_colors64k(int, int, int, int, int, int, int, int, int, int); +extern void alloc_colors_rgb(int rw, int gw, int bw, int rs, int gs, int bs, int aw, int as, int alpha, int byte_swap, + uae_u32 *rc, uae_u32 *gc, uae_u32 *bc); extern void alloc_colors_picasso (int rw, int gw, int bw, int rs, int gs, int bs, int rgbfmt); extern double getvsyncrate(double hz, int *mult); diff --git a/src/inputdevice.cpp b/src/inputdevice.cpp index 466259c9..4d9f0117 100644 --- a/src/inputdevice.cpp +++ b/src/inputdevice.cpp @@ -254,13 +254,12 @@ static void freejport(struct uae_prefs* dst, int num) dst->jports[num].nokeyboardoverride = override; } -static void copyjport(const struct uae_prefs* src, struct uae_prefs* dst, int num) +static void copyjport(const struct uae_prefs *src, struct uae_prefs *dst, int num) { if (!src) return; freejport(dst, num); - _tcscpy (dst->jports[num].configname, src->jports[num].configname); - _tcscpy (dst->jports[num].name, src->jports[num].name); + memcpy(&dst->jports[num].idc, &src->jports[num].idc, sizeof(struct inputdevconfig)); dst->jports[num].id = src->jports[num].id; dst->jports[num].mode = src->jports[num].mode; dst->jports[num].autofire = src->jports[num].autofire; @@ -809,12 +808,10 @@ static void set_kbr_default(struct uae_prefs* p, int index, int devnum, struct u } } -static void inputdevice_default_kb(struct uae_prefs* p, int num) +static void inputdevice_default_kb(struct uae_prefs *p, int num) { - if (num == GAMEPORT_INPUT_SETTINGS) - { - if (p->jports[0].id != JPORT_CUSTOM || p->jports[1].id != JPORT_CUSTOM) - reset_inputdevice_slot(p, num); + if (num == GAMEPORT_INPUT_SETTINGS) { + reset_inputdevice_slot(p, num); } set_kbr_default(p, num, -1, keyboard_default); } @@ -1264,15 +1261,15 @@ static uaecptr get_gfxbase(void) int inputdevice_is_tablet(void) { int v; - if (!uae_boot_rom) + if (uae_boot_rom_type <= 0) return 0; if (currprefs.input_tablet == TABLET_OFF) return 0; if (currprefs.input_tablet == TABLET_MOUSEHACK) return -1; - /*v = is_tablet(); + v = is_tablet(); if (!v) - return 0;*/ + return 0; if (kickstart_version < 37) return v ? -1 : 0; return v ? 1 : 0; @@ -1299,7 +1296,7 @@ static bool mousehack_enable(void) { int mode; - if (!uae_boot_rom || currprefs.input_tablet == TABLET_OFF) + if (uae_boot_rom_type <= 0 || currprefs.input_tablet == TABLET_OFF) return false; if (mousehack_address && mousehack_enabled) return true; @@ -1408,7 +1405,7 @@ void get_custom_mouse_limits(int *w, int *h, int *dx, int *dy, int dbl); void inputdevice_tablet_strobe() { mousehack_enable(); - if (!uae_boot_rom) + if (uae_boot_rom_type <= 0) return; if (!tablet_data) return; @@ -1533,7 +1530,7 @@ static void mousehack_helper(uae_u32 buttonmask) int x, y; //float fdy, fdx, fmx, fmy; - if (currprefs.input_magic_mouse == 0 && currprefs.input_tablet < TABLET_MOUSEHACK) + if (!(currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC) && currprefs.input_tablet < TABLET_MOUSEHACK) return; x = lastmx; y = lastmy; @@ -1567,7 +1564,7 @@ static void mousehack_helper(uae_u32 buttonmask) x = coord_native_to_amiga_x(x); y = coord_native_to_amiga_y(y) << 1; } - inputdevice_mh_abs(x, y, buttonmask); + //inputdevice_mh_abs(x, y, buttonmask); } static int mouseedge_x, mouseedge_y, mouseedge_time; @@ -3466,7 +3463,7 @@ static int switchdevice(struct uae_input_device* id, int num, bool buttonmode) /* "GamePorts" switch if in GamePorts mode or Input mode and GamePorts port was not NONE */ if (currprefs.input_selected_setting == GAMEPORT_INPUT_SETTINGS || currprefs.jports[newport].id != JPORT_NONE) { - if ((num == 0 || num == 1) && currprefs.jports[newport].id != JPORT_CUSTOM) + if ((num == 0 || num == 1) && !JSEM_ISCUSTOM(newport, &currprefs)) { bool issupermouse = false; int om = jsem_ismouse(num, &currprefs); @@ -4835,24 +4832,19 @@ static void remove_custom_config(struct uae_prefs* prefs, bool nocustom, int ind } // prepare port for custom mapping, remove all current Amiga side device mappings -void inputdevice_compa_prepare_custom(struct uae_prefs* prefs, int index, int newmode, bool removeold) +void inputdevice_compa_prepare_custom(struct uae_prefs *prefs, int index, int newmode, bool removeold) { int mode = prefs->jports[index].mode; - freejport(prefs, index); - resetjport(prefs, index); - if (newmode >= 0) - { + if (newmode >= 0) { mode = newmode; } - else if (mode == 0) - { + else if (mode == 0) { mode = index == 0 ? JSEM_MODE_WHEELMOUSE : (prefs->cs_cd32cd ? JSEM_MODE_JOYSTICK_CD32 : JSEM_MODE_JOYSTICK); } prefs->jports[index].mode = mode; - prefs->jports[index].id = JPORT_CUSTOM; - if (removeold) - { + if (removeold) { + prefs->jports_custom[JSEM_GETCUSTOMIDX(index, prefs)].custom[0] = 0; remove_compa_config(prefs, index); remove_custom_config(prefs, false, index); } @@ -5007,12 +4999,9 @@ static void compatibility_copy(struct uae_prefs* prefs, bool gameports) joymodes[i] = prefs->jports[i].mode; joyinputs[i] = NULL; // remove all mappings from this port, except if custom - if (prefs->jports[i].id != JPORT_CUSTOM) - { - if (gameports) - remove_compa_config(prefs, i); - } - remove_custom_config(prefs, prefs->jports[i].id == JPORT_CUSTOM, i); + if (gameports) + remove_compa_config(prefs, i); + remove_custom_config(prefs, false, i); setjoyinputs(prefs, i); } @@ -5153,8 +5142,8 @@ static void compatibility_copy(struct uae_prefs* prefs, bool gameports) break; #endif } - _tcsncpy (prefs->jports[i].name, idev[IDTYPE_MOUSE].get_friendlyname (joy), MAX_JPORTNAME - 1); - _tcsncpy (prefs->jports[i].configname, idev[IDTYPE_MOUSE].get_uniquename (joy), MAX_JPORTNAME - 1); + _tcsncpy(prefs->jports[i].idc.name, idev[IDTYPE_MOUSE].get_friendlyname (joy), MAX_JPORTNAME - 1); + _tcsncpy(prefs->jports[i].idc.configname, idev[IDTYPE_MOUSE].get_uniquename (joy), MAX_JPORTNAME - 1); } } } @@ -5210,8 +5199,8 @@ static void compatibility_copy(struct uae_prefs* prefs, bool gameports) break; #endif } - _tcsncpy (prefs->jports[i].name, idev[IDTYPE_JOYSTICK].get_friendlyname (joy), MAX_JPORTNAME - 1); - _tcsncpy (prefs->jports[i].configname, idev[IDTYPE_JOYSTICK].get_uniquename (joy), MAX_JPORTNAME - 1); + _tcsncpy(prefs->jports[i].idc.name, idev[IDTYPE_JOYSTICK].get_friendlyname (joy), MAX_JPORTNAME - 1); + _tcsncpy(prefs->jports[i].idc.configname, idev[IDTYPE_JOYSTICK].get_uniquename (joy), MAX_JPORTNAME - 1); used[joy] = 1; } } @@ -5284,14 +5273,6 @@ static void compatibility_copy(struct uae_prefs* prefs, bool gameports) else kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_SE]; } - else if (JSEM_ISXARCADE1 (i, prefs)) - { - kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_XA1]; - } - else if (JSEM_ISXARCADE2 (i, prefs)) - { - kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_XA2]; - } if (kb) { switch (mode) @@ -5719,10 +5700,11 @@ void inputdevice_devicechange(struct uae_prefs *prefs) for (i = 0; i < MAX_JPORTS; i++) { freejport(prefs, i); - if (jportid[i] == JPORT_CUSTOM) { - inputdevice_joyport_config(prefs, _T("custom"), i, jportsmode[i], 0, true); - } - else if (jports[i]) { + //if (jportid[i] == JPORT_CUSTOM) { + // inputdevice_joyport_config(prefs, _T("custom"), i, jportsmode[i], 0, true); + //} + //else + if (jports[i]) { inputdevice_joyport_config(prefs, jports[i], i, jportsmode[i], 2, true); } else if (jportskb[i] >= 0) { @@ -6741,18 +6723,18 @@ static void swapjoydevice(struct uae_input_device *uid, int **swaps) void inputdevice_swap_compa_ports(struct uae_prefs* prefs, int portswap) { struct jport tmp; - if ((prefs->jports[portswap].id == JPORT_CUSTOM || prefs->jports[portswap + 1].id == JPORT_CUSTOM)) - { - int* swaps[2]; +#if 0 + if ((prefs->jports[portswap].id == JPORT_CUSTOM || prefs->jports[portswap + 1].id == JPORT_CUSTOM)) { + const int *swaps[2]; swaps[0] = rem_ports[portswap]; swaps[1] = rem_ports[portswap + 1]; - for (int l = 0; l < MAX_INPUT_DEVICES; l++) - { + for (int l = 0; l < MAX_INPUT_DEVICES; l++) { swapjoydevice(&prefs->joystick_settings[GAMEPORT_INPUT_SETTINGS][l], swaps); swapjoydevice(&prefs->mouse_settings[GAMEPORT_INPUT_SETTINGS][l], swaps); swapjoydevice(&prefs->keyboard_settings[GAMEPORT_INPUT_SETTINGS][l], swaps); } } +#endif memcpy(&tmp, &prefs->jports[portswap], sizeof (struct jport)); memcpy(&prefs->jports[portswap], &prefs->jports[portswap + 1], sizeof (struct jport)); memcpy(&prefs->jports[portswap + 1], &tmp, sizeof (struct jport)); @@ -7243,43 +7225,70 @@ int jsem_iskbdjoy(int port, const struct uae_prefs* p) static struct jport stored_ports[MAX_JPORTS]; -static void fixjport(struct jport* port, int add) +static bool fixjport(struct jport *port, int add, bool always) { + bool wasinvalid = false; int vv = port->id; - if (vv == JPORT_CUSTOM || vv == JPORT_NONE) - return; - if (vv >= JSEM_JOYS && vv < JSEM_MICE) - { + if (vv == JPORT_NONE) + return wasinvalid; + if (vv >= JSEM_JOYS && vv < JSEM_MICE) { vv -= JSEM_JOYS; vv += add; if (vv >= inputdevice_get_device_total(IDTYPE_JOYSTICK)) vv = 0; vv += JSEM_JOYS; } - else if (vv >= JSEM_MICE && vv < JSEM_END) - { + else if (vv >= JSEM_MICE && vv < JSEM_END) { vv -= JSEM_MICE; vv += add; if (vv >= inputdevice_get_device_total(IDTYPE_MOUSE)) vv = 0; vv += JSEM_MICE; } - else if (vv >= JSEM_KBDLAYOUT && vv < JSEM_LASTKBD) - { + else if (vv >= JSEM_KBDLAYOUT && vv < JSEM_LASTKBD) { vv -= JSEM_KBDLAYOUT; vv += add; if (vv >= JSEM_LASTKBD) vv = 0; vv += JSEM_KBDLAYOUT; } + else if (vv >= JSEM_CUSTOM && vv < JSEM_CUSTOM + MAX_JPORTS_CUSTOM) { + vv -= JSEM_CUSTOM; + vv += add; + if (vv >= MAX_JPORTS_CUSTOM) + vv = 0; + vv += JSEM_CUSTOM; + } + if (port->id != vv || always) { + port->idc.shortid[0] = 0; + port->idc.configname[0] = 0; + port->idc.name[0] = 0; + if (vv >= JSEM_JOYS && vv < JSEM_MICE) { + _tcscpy(port->idc.name, inputdevice_get_device_name(IDTYPE_JOYSTICK, vv - JSEM_JOYS)); + _tcscpy(port->idc.configname, inputdevice_get_device_unique_name(IDTYPE_JOYSTICK, vv - JSEM_JOYS)); + } + else if (vv >= JSEM_MICE && vv < JSEM_END) { + _tcscpy(port->idc.name, inputdevice_get_device_name(IDTYPE_MOUSE, vv - JSEM_MICE)); + _tcscpy(port->idc.configname, inputdevice_get_device_unique_name(IDTYPE_MOUSE, vv - JSEM_MICE)); + } + else if (vv >= JSEM_KBDLAYOUT && vv < JSEM_CUSTOM) { + _stprintf(port->idc.shortid, _T("kbd%d"), vv - JSEM_KBDLAYOUT + 1); + } + wasinvalid = true; +#if 0 + write_log(_T("fixjport %d %d %d (%s)\n"), port->id, vv, add, port->name); +#endif + } port->id = vv; + return wasinvalid; } void inputdevice_validate_jports(struct uae_prefs* p, int changedport) { int i, j; - for (i = 0; i < MAX_JPORTS; i++) - fixjport(&p->jports[i], 0); + for (i = 0; i < MAX_JPORTS; i++) { + fixjport(&p->jports[i], 0, changedport == i); + } for (i = 0; i < MAX_JPORTS; i++) { if (p->jports[i].id < 0) @@ -7312,7 +7321,7 @@ void inputdevice_validate_jports(struct uae_prefs* p, int changedport) { k = i; } - fixjport(&p->jports[k], 1); + fixjport(&p->jports[k], 1, false); cnt++; if (cnt > 10) p->jports[k].id = JSEM_KBDLAYOUT; @@ -7361,6 +7370,22 @@ void restore_inputdevice_config(struct uae_prefs* p, int portnum) memcpy(&p->jports[portnum], &stored_ports[portnum], sizeof (struct jport)); } +void inputdevice_joyport_config_store(struct uae_prefs *p, const TCHAR *value, int portnum, int mode, int type) +{ + struct jport *jp = &p->jports[portnum]; + if (type == 2) { + _tcscpy(jp->idc.name, value); + } + else if (type == 1) { + _tcscpy(jp->idc.configname, value); + } + else { + _tcscpy(jp->idc.shortid, value); + } + if (mode >= 0) + jp->mode = mode; +} + int inputdevice_joyport_config(struct uae_prefs* p, const TCHAR* value, int portnum, int mode, int type, bool validate) { switch (type) @@ -7444,7 +7469,7 @@ int inputdevice_joyport_config(struct uae_prefs* p, const TCHAR* value, int port else if (_tcscmp (value, _T("custom")) == 0) { got = 2; - start = JPORT_CUSTOM; + start = JSEM_CUSTOM; } if (got) { @@ -7491,7 +7516,7 @@ int inputdevice_joyport_config(struct uae_prefs* p, const TCHAR* value, int port int inputdevice_getjoyportdevice(int port, int val) { int idx; - if (val == JPORT_CUSTOM) + if (val == JSEM_CUSTOM) { idx = inputdevice_get_device_total(IDTYPE_JOYSTICK) + JSEM_LASTKBD; if (port < 2) diff --git a/src/jit/compemu.h b/src/jit/compemu.h index a3c16d53..5ea9ca9e 100644 --- a/src/jit/compemu.h +++ b/src/jit/compemu.h @@ -144,6 +144,7 @@ extern int get_cache_state(void); extern uae_u32 get_jitted_size(void); #ifdef JIT extern void (*flush_icache)(uaecptr ptr, int n); +extern void flush_icache_hard(uaecptr ptr, int n); #endif extern void alloc_cache(void); extern void compile_block(cpu_history* pc_hist, int blocklen, int totcyles); diff --git a/src/jit/compemu_support.cpp b/src/jit/compemu_support.cpp index e9fcb0c3..fb28525e 100644 --- a/src/jit/compemu_support.cpp +++ b/src/jit/compemu_support.cpp @@ -117,6 +117,16 @@ const int tune_nop_fillers = 1; // Tune no-op fillers for architecture static int setzflg_uses_bsf = 0; // setzflg virtual instruction can use native BSF instruction correctly? static int align_loops = 0; // Align the start of loops static int align_jumps = 0; // Align the start of jumps +static int optcount[10] = { +#ifdef UAE + 4, // How often a block has to be executed before it is translated +#else + 10, // How often a block has to be executed before it is translated +#endif + 0, // How often to use naive translation + 0, 0, 0, 0, + -1, -1, -1, -1 +}; op_properties prop[65536]; @@ -211,7 +221,7 @@ extern const struct cputbl op_smalltbl_4_nf[]; extern const struct cputbl op_smalltbl_5_nf[]; #endif -static void flush_icache_hard(uaecptr ptr, int n); +//static void flush_icache_hard(uaecptr ptr, int n); static void flush_icache_lazy(uaecptr ptr, int n); static void flush_icache_none(uaecptr ptr, int n); void (*flush_icache)(uaecptr ptr, int n) = flush_icache_none; @@ -232,9 +242,9 @@ static void prepare_for_call_2(void); static void align_target(uae_u32 a); #endif -STATIC_INLINE void flush_cpu_icache(void *from, void *to); -STATIC_INLINE void write_jmp_target(uae_u32 *jmpaddr, cpuop_func* a); -STATIC_INLINE void emit_jmp_target(uae_u32 a); +static void inline flush_cpu_icache(void *from, void *to); +static void inline write_jmp_target(uae_u32 *jmpaddr, cpuop_func* a); +static void inline emit_jmp_target(uae_u32 a); uae_u32 m68k_pc_offset; @@ -401,24 +411,23 @@ STATIC_INLINE void set_dhtu(blockinfo* bi, cpuop_func* dh) } } -STATIC_INLINE void invalidate_block(blockinfo* bi) +static inline void invalidate_block(blockinfo* bi) { - int i; - - bi->optlevel = 0; - bi->count = currprefs.optcount[0]-1; - bi->handler = NULL; - bi->handler_to_use = (cpuop_func *)popall_execute_normal; - bi->direct_handler = NULL; - set_dhtu(bi, bi->direct_pen); - bi->needed_flags = 0xff; + int i; + bi->optlevel = 0; + bi->count = optcount[0] - 1; + bi->handler = NULL; + bi->handler_to_use = (cpuop_func*)popall_execute_normal; + bi->direct_handler = NULL; + set_dhtu(bi, bi->direct_pen); + bi->needed_flags = 0xff; bi->status = BI_INVALID; - for (i=0; i<2; i++) { - bi->dep[i].jmp_off = NULL; - bi->dep[i].target = NULL; - } - remove_deps(bi); + for (i = 0; i<2; i++) { + bi->dep[i].jmp_off = NULL; + bi->dep[i].target = NULL; + } + remove_deps(bi); } STATIC_INLINE void create_jmpdep(blockinfo* bi, int i, uae_u32* jmpaddr, uae_u32 target) @@ -688,7 +697,7 @@ STATIC_INLINE void emit_byte(uae_u8 x) STATIC_INLINE void emit_long(uae_u32 x) { - *((uae_u32*)target) = x; + *reinterpret_cast(target) = x; target += 4; } @@ -2632,11 +2641,11 @@ STATIC_INLINE void create_popalls(void) pushall_call_handler = get_target(); raw_push_regs_to_preserve(); raw_dec_sp(stack_space); - compemu_raw_init_r_regstruct((uintptr)®s); + compemu_raw_init_r_regstruct(uintptr(®s)); r = REG_PC_TMP; - compemu_raw_mov_l_rm(r,(uintptr)®s.pc_p); + compemu_raw_mov_l_rm(r,uintptr(®s.pc_p)); compemu_raw_and_TAGMASK(r); - compemu_raw_jmp_m_indexed((uintptr)cache_tags, r, SIZEOF_VOID_P); + compemu_raw_jmp_m_indexed(uintptr(cache_tags), r, SIZEOF_VOID_P); /* now the exit points */ #ifndef ALIGN_NOT_NEEDED @@ -2645,7 +2654,7 @@ STATIC_INLINE void create_popalls(void) popall_do_nothing = get_target(); raw_inc_sp(stack_space); raw_pop_preserved_regs(); - compemu_raw_jmp((uintptr)do_nothing); + compemu_raw_jmp(uintptr(do_nothing)); #ifndef ALIGN_NOT_NEEDED align_target(align_jumps); @@ -2653,7 +2662,7 @@ STATIC_INLINE void create_popalls(void) popall_execute_normal = get_target(); raw_inc_sp(stack_space); raw_pop_preserved_regs(); - compemu_raw_jmp((uintptr)execute_normal); + compemu_raw_jmp(uintptr(execute_normal)); #ifndef ALIGN_NOT_NEEDED align_target(align_jumps); @@ -2661,7 +2670,7 @@ STATIC_INLINE void create_popalls(void) popall_cache_miss = get_target(); raw_inc_sp(stack_space); raw_pop_preserved_regs(); - compemu_raw_jmp((uintptr)cache_miss); + compemu_raw_jmp(uintptr(cache_miss)); #ifndef ALIGN_NOT_NEEDED align_target(align_jumps); @@ -2885,7 +2894,7 @@ static void flush_icache_none(uaecptr ptr, int n) /* Nothing to do. */ } -static void flush_icache_hard(uaecptr ptr, int n) +void flush_icache_hard(uaecptr ptr, int n) { blockinfo* bi, *dbi; @@ -3064,10 +3073,10 @@ void compile_block(cpu_history* pc_hist, int blocklen, int totcycles) } } if (bi->count == -1) { - optlev++; - while (!currprefs.optcount[optlev]) - optlev++; - bi->count = currprefs.optcount[optlev] - 1; + optlev++; + while (!optcount[optlev]) + optlev++; + bi->count = optcount[optlev] - 1; } current_block_pc_p = (uintptr)pc_hist[0].location; diff --git a/src/linetoscr.c b/src/linetoscr.c deleted file mode 100644 index 2f6fc272..00000000 --- a/src/linetoscr.c +++ /dev/null @@ -1,806 +0,0 @@ -/* Note: - * xcolors[] contains 16-bit color information in both words - * colors_for_drawing.acolors (non AGA) contains 16-bit color information in both words - * colors_for_drawing.acolors (AGA) contains 16-bit color information in one word - */ - -STATIC_INLINE uae_u32 merge_words(uae_u32 val, uae_u32 val2) -{ - __asm__ ( - "pkhbt %[o], %[o], %[d], lsl #16 \n\t" - : [o] "+r" (val) : [d] "r" (val2) ); - return val; -} - -STATIC_INLINE uae_u32 double_word(uae_u32 val) -{ - __asm__ ( - "pkhbt %[o], %[o], %[o], lsl #16 \n\t" - : [o] "+r" (val) ); - return val; -} - -static int NOINLINE linetoscr_16 (int spix, int dpix, int dpix_end) -{ - uae_u16 *buf = (uae_u16 *) xlinebuffer; - - if (bplham) { - int rem; - if (((long)&buf[dpix]) & 2) { - buf[dpix++] = ham_linebuf[spix++]; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 out_val; - - out_val = *((uae_u32 *)&ham_linebuf[spix]); - spix += 2; - *((uae_u32 *)&buf[dpix]) = out_val; - dpix += 2; - } - if (rem) { - buf[dpix++] = ham_linebuf[spix++]; - } - } else if (bpldualpf) { - int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; - int rem; - if (((long)&buf[dpix]) & 2) { - uae_u32 spix_val; - spix_val = pixdata.apixels[spix++]; - buf[dpix++] = colors_for_drawing.acolors[lookup[spix_val]]; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 dpix_val; - uae_u32 out_val; - - spix_val = pixdata.apixels[spix++]; - out_val = colors_for_drawing.acolors[lookup[spix_val]]; - spix_val = pixdata.apixels[spix++]; - dpix_val = colors_for_drawing.acolors[lookup[spix_val]]; - *((uae_u32 *)&buf[dpix]) = merge_words(out_val, dpix_val); - dpix += 2; - } - if (rem) { - uae_u32 spix_val; - spix_val = pixdata.apixels[spix++]; - buf[dpix++] = colors_for_drawing.acolors[lookup[spix_val]]; - } - } else if (bplehb) { - int rem; - if (((long)&buf[dpix]) & 2) { - uae_u32 spix_val; - uae_u32 dpix_val; - spix_val = pixdata.apixels[spix++]; - if (spix_val <= 31) - dpix_val = colors_for_drawing.acolors[spix_val]; - else - dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; - buf[dpix++] = dpix_val; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 dpix_val; - uae_u32 out_val; - - spix_val = pixdata.apixels[spix++]; - if (spix_val <= 31) - out_val = colors_for_drawing.acolors[spix_val]; - else - out_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; - spix_val = pixdata.apixels[spix++]; - if (spix_val <= 31) - dpix_val = colors_for_drawing.acolors[spix_val]; - else - dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; - *((uae_u32 *)&buf[dpix]) = merge_words(out_val, dpix_val); - dpix += 2; - } - if (rem) { - uae_u32 spix_val; - uae_u32 dpix_val; - spix_val = pixdata.apixels[spix++]; - if (spix_val <= 31) - dpix_val = colors_for_drawing.acolors[spix_val]; - else - dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; - buf[dpix++] = dpix_val; - } - } else { - int rem; - if (((long)&buf[dpix]) & 2) { - uae_u32 spix_val; - spix_val = pixdata.apixels[spix++]; - buf[dpix++] = colors_for_drawing.acolors[spix_val]; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 dpix_val; - uae_u32 out_val; - - spix_val = pixdata.apixels[spix++]; - out_val = colors_for_drawing.acolors[spix_val]; - spix_val = pixdata.apixels[spix++]; - dpix_val = colors_for_drawing.acolors[spix_val]; - *((uae_u32 *)&buf[dpix]) = merge_words(out_val, dpix_val); - dpix += 2; - } - if (rem) { - uae_u32 spix_val; - spix_val = pixdata.apixels[spix++]; - buf[dpix++] = colors_for_drawing.acolors[spix_val]; - } - } - - return spix; -} - -static int NOINLINE linetoscr_16_stretch1 (int spix, int dpix, int dpix_end) -{ - uae_u16 *buf = (uae_u16 *) xlinebuffer; - - if (bplham) { - while (dpix < dpix_end) { - uae_u32 out_val = ham_linebuf[spix++]; - *((uae_u32 *)&buf[dpix]) = double_word(out_val); - dpix += 2; - } - } else if (bpldualpf) { - int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; - while (dpix < dpix_end) { - uae_u32 spix_val; - - spix_val = pixdata.apixels[spix++]; - *((uae_u32 *)&buf[dpix]) = colors_for_drawing.acolors[lookup[spix_val]]; - dpix += 2; - } - } else if (bplehb) { - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 out_val; - - spix_val = pixdata.apixels[spix++]; - if (spix_val <= 31) - out_val = colors_for_drawing.acolors[spix_val]; - else - out_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x0777]; - *((uae_u32 *)&buf[dpix]) = double_word(out_val); - dpix += 2; - } - } else { - while (dpix < dpix_end) { - uae_u32 spix_val; - - spix_val = pixdata.apixels[spix++]; - *((uae_u32 *)&buf[dpix]) = colors_for_drawing.acolors[spix_val]; - dpix += 2; - } - } - - return spix; -} - -static int NOINLINE linetoscr_16_shrink1 (int spix, int dpix, int dpix_end) -{ - uae_u16 *buf = (uae_u16 *) xlinebuffer; - - if (bplham) { - int rem; - if (((long)&buf[dpix]) & 2) { - uae_u32 dpix_val; - dpix_val = ham_linebuf[spix]; - spix += 2; - buf[dpix++] = dpix_val; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 dpix_val; - uae_u32 out_val; - - out_val = ham_linebuf[spix]; - spix += 2; - dpix_val = ham_linebuf[spix]; - spix += 2; - out_val = merge_words(out_val, dpix_val); - - *((uae_u32 *)&buf[dpix]) = out_val; - dpix += 2; - } - if (rem) { - uae_u32 dpix_val; - dpix_val = ham_linebuf[spix]; - spix += 2; - buf[dpix++] = dpix_val; - } - } else if (bpldualpf) { - int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; - int rem; - if (((long)&buf[dpix]) & 2) { - uae_u32 spix_val; - uae_u32 dpix_val; - spix_val = pixdata.apixels[spix]; - dpix_val = colors_for_drawing.acolors[lookup[spix_val]]; - spix += 2; - buf[dpix++] = dpix_val; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 dpix_val; - uae_u32 out_val; - - spix_val = pixdata.apixels[spix]; - out_val = colors_for_drawing.acolors[lookup[spix_val]]; - spix += 2; - spix_val = pixdata.apixels[spix]; - dpix_val = colors_for_drawing.acolors[lookup[spix_val]]; - spix += 2; - *((uae_u32 *)&buf[dpix]) = merge_words(out_val, dpix_val); - dpix += 2; - } - if (rem) { - uae_u32 spix_val; - uae_u32 dpix_val; - spix_val = pixdata.apixels[spix]; - dpix_val = colors_for_drawing.acolors[lookup[spix_val]]; - spix += 2; - buf[dpix++] = dpix_val; - } - } else if (bplehb) { - int rem; - if (((long)&buf[dpix]) & 2) { - uae_u32 spix_val; - uae_u32 dpix_val; - spix_val = pixdata.apixels[spix]; - if (spix_val <= 31) - dpix_val = colors_for_drawing.acolors[spix_val]; - else - dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; - spix += 2; - buf[dpix++] = dpix_val; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 dpix_val; - uae_u32 out_val; - - spix_val = pixdata.apixels[spix]; - if (spix_val <= 31) - out_val = colors_for_drawing.acolors[spix_val]; - else - out_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; - spix += 2; - spix_val = pixdata.apixels[spix]; - if (spix_val <= 31) - dpix_val = colors_for_drawing.acolors[spix_val]; - else - dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; - spix += 2; - *((uae_u32 *)&buf[dpix]) = merge_words(out_val, dpix_val); - dpix += 2; - } - if (rem) { - uae_u32 spix_val; - uae_u32 dpix_val; - spix_val = pixdata.apixels[spix]; - if (spix_val <= 31) - dpix_val = colors_for_drawing.acolors[spix_val]; - else - dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; - spix += 2; - buf[dpix++] = dpix_val; - } - } else { - int rem; - if (((long)&buf[dpix]) & 2) { - uae_u32 spix_val; - spix_val = pixdata.apixels[spix]; - spix += 2; - buf[dpix++] = colors_for_drawing.acolors[spix_val]; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 dpix_val; - uae_u32 out_val; - - spix_val = pixdata.apixels[spix]; - out_val = colors_for_drawing.acolors[spix_val]; - spix += 2; - spix_val = pixdata.apixels[spix]; - dpix_val = colors_for_drawing.acolors[spix_val]; - spix += 2; - *((uae_u32 *)&buf[dpix]) = merge_words(out_val, dpix_val); - dpix += 2; - } - if (rem) { - uae_u32 spix_val; - spix_val = pixdata.apixels[spix]; - spix += 2; - buf[dpix++] = colors_for_drawing.acolors[spix_val]; - } - } - - return spix; -} - -#ifdef AGA - -static int NOINLINE linetoscr_16_aga (int spix, int dpix, int dpix_end) -{ - uae_u16 *buf = (uae_u16 *) xlinebuffer; - uae_u8 xor_val = bplxor; - - if (bplham) { - int rem; - if (((long)&buf[dpix]) & 2) { - buf[dpix++] = ham_linebuf[spix]; - spix++; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 out_val; - - out_val = *((uae_u32 *)&ham_linebuf[spix]); - spix += 2; - *((uae_u32 *)&buf[dpix]) = out_val; - dpix += 2; - } - if (rem) { - buf[dpix++] = ham_linebuf[spix]; - spix++; - } - } else if (bpldualpf) { - int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; - int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; - int rem; - if (((long)&buf[dpix]) & 2) { - uae_u32 spix_val; - uae_u32 dpix_val; - if (spritepixels[spix]) { - dpix_val = colors_for_drawing.acolors[spritepixels[spix]]; - } else { - spix_val = pixdata.apixels[spix]; - uae_u8 val = lookup[spix_val]; - if (lookup_no[spix_val] == 2) - val += dblpfofs[bpldualpf2of]; - val ^= xor_val; - dpix_val = colors_for_drawing.acolors[val]; - } - spix++; - buf[dpix++] = dpix_val; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 dpix_val; - uae_u32 out_val; - - if (spritepixels[spix]) { - out_val = colors_for_drawing.acolors[spritepixels[spix]]; - } else { - spix_val = pixdata.apixels[spix]; - uae_u8 val = lookup[spix_val]; - if (lookup_no[spix_val] == 2) - val += dblpfofs[bpldualpf2of]; - val ^= xor_val; - out_val = colors_for_drawing.acolors[val]; - } - spix++; - if (spritepixels[spix]) { - dpix_val = colors_for_drawing.acolors[spritepixels[spix]]; - } else { - spix_val = pixdata.apixels[spix]; - uae_u8 val = lookup[spix_val]; - if (lookup_no[spix_val] == 2) - val += dblpfofs[bpldualpf2of]; - val ^= xor_val; - dpix_val = colors_for_drawing.acolors[val]; - } - spix++; - *((uae_u32 *)&buf[dpix]) = merge_words(out_val, dpix_val); - dpix += 2; - } - if (rem) { - uae_u32 spix_val; - uae_u32 dpix_val; - if (spritepixels[spix]) { - dpix_val = colors_for_drawing.acolors[spritepixels[spix]]; - } else { - spix_val = pixdata.apixels[spix]; - uae_u8 val = lookup[spix_val]; - if (lookup_no[spix_val] == 2) - val += dblpfofs[bpldualpf2of]; - val ^= xor_val; - dpix_val = colors_for_drawing.acolors[val]; - } - spix++; - buf[dpix++] = dpix_val; - } - } else if (bplehb) { - int rem; - if (((long)&buf[dpix]) & 2) { - uae_u32 spix_val; - uae_u32 dpix_val; - spix_val = pixdata.apixels[spix++] ^ xor_val; - if (spix_val >= 32 && spix_val < 64) { - unsigned int c = (colors_for_drawing.color_regs_aga[spix_val - 32] >> 1) & 0x7F7F7F; - dpix_val = CONVERT_RGB (c); - } else - dpix_val = colors_for_drawing.acolors[spix_val]; - buf[dpix++] = dpix_val; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 dpix_val; - uae_u32 out_val; - - spix_val = pixdata.apixels[spix++] ^ xor_val; - if (spix_val >= 32 && spix_val < 64) { - unsigned int c = (colors_for_drawing.color_regs_aga[spix_val - 32] >> 1) & 0x7F7F7F; - out_val = CONVERT_RGB (c); - } else - out_val = colors_for_drawing.acolors[spix_val]; - spix_val = pixdata.apixels[spix++] ^ xor_val; - if (spix_val >= 32 && spix_val < 64) { - unsigned int c = (colors_for_drawing.color_regs_aga[spix_val - 32] >> 1) & 0x7F7F7F; - dpix_val = CONVERT_RGB (c); - } else - dpix_val = colors_for_drawing.acolors[spix_val]; - *((uae_u32 *)&buf[dpix]) = merge_words(out_val, dpix_val); - dpix += 2; - } - if (rem) { - uae_u32 spix_val; - uae_u32 dpix_val; - spix_val = pixdata.apixels[spix++] ^ xor_val; - if (spix_val >= 32 && spix_val < 64) { - unsigned int c = (colors_for_drawing.color_regs_aga[spix_val - 32] >> 1) & 0x7F7F7F; - dpix_val = CONVERT_RGB (c); - } else - dpix_val = colors_for_drawing.acolors[spix_val]; - buf[dpix++] = dpix_val; - } - } else { - int rem; - if (((long)&buf[dpix]) & 2) { - uae_u32 spix_val; - spix_val = pixdata.apixels[spix++] ^ xor_val; - buf[dpix++] = colors_for_drawing.acolors[spix_val]; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 dpix_val; - uae_u32 out_val; - - spix_val = pixdata.apixels[spix++] ^ xor_val; - out_val = colors_for_drawing.acolors[spix_val]; - spix_val = pixdata.apixels[spix++] ^ xor_val; - dpix_val = colors_for_drawing.acolors[spix_val]; - *((uae_u32 *)&buf[dpix]) = merge_words(out_val, dpix_val); - dpix += 2; - } - if (rem) { - uae_u32 spix_val; - spix_val = pixdata.apixels[spix++] ^ xor_val; - buf[dpix++] = colors_for_drawing.acolors[spix_val]; - } - } - - return spix; -} -#endif - -#ifdef AGA -static int NOINLINE linetoscr_16_stretch1_aga (int spix, int dpix, int dpix_end) -{ - uae_u16 *buf = (uae_u16 *) xlinebuffer; - uae_u8 xor_val = bplxor; - - if (bplham) { - while (dpix < dpix_end) { - uae_u32 out_val; - out_val = ham_linebuf[spix++]; - *((uae_u32 *)&buf[dpix]) = double_word(out_val); - dpix += 2; - } - } else if (bpldualpf) { - int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; - int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 out_val; - - if (spritepixels[spix]) { - out_val = colors_for_drawing.acolors[spritepixels[spix]]; - } else { - spix_val = pixdata.apixels[spix]; - uae_u8 val = lookup[spix_val]; - if (lookup_no[spix_val] == 2) - val += dblpfofs[bpldualpf2of]; - val ^= xor_val; - out_val = colors_for_drawing.acolors[val]; - } - spix++; - *((uae_u32 *)&buf[dpix]) = double_word(out_val); - dpix += 2; - } - } else if (bplehb) { - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 out_val; - - spix_val = pixdata.apixels[spix++] ^ xor_val; - if (spix_val >= 32 && spix_val < 64) { - unsigned int c = (colors_for_drawing.color_regs_aga[spix_val - 32] >> 1) & 0x7F7F7F; - out_val = CONVERT_RGB (c); - } else - out_val = colors_for_drawing.acolors[spix_val]; - *((uae_u32 *)&buf[dpix]) = double_word(out_val); - dpix += 2; - } - } else { - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 out_val; - - spix_val = pixdata.apixels[spix++] ^ xor_val; - out_val = colors_for_drawing.acolors[spix_val]; - *((uae_u32 *)&buf[dpix]) = double_word(out_val); - dpix += 2; - } - } - - return spix; -} -#endif - -#ifdef AGA -static int NOINLINE linetoscr_16_shrink1_aga (int spix, int dpix, int dpix_end) -{ - uae_u16 *buf = (uae_u16 *) xlinebuffer; - uae_u8 xor_val = bplxor; - - if (bplham) { - int rem; - if (((long)&buf[dpix]) & 2) { - buf[dpix++] = ham_linebuf[spix]; - spix += 2; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 dpix_val; - uae_u32 out_val; - - out_val = ham_linebuf[spix]; - spix += 2; - dpix_val = ham_linebuf[spix]; - spix += 2; - out_val = merge_words(out_val, dpix_val); - *((uae_u32 *)&buf[dpix]) = out_val; - dpix += 2; - } - if (rem) { - buf[dpix++] = ham_linebuf[spix]; - spix += 2; - } - } else if (bpldualpf) { - int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; - int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; - int rem; - if (((long)&buf[dpix]) & 2) { - uae_u32 spix_val; - uae_u32 dpix_val; - if (spritepixels[spix]) { - dpix_val = colors_for_drawing.acolors[spritepixels[spix]]; - } else { - spix_val = pixdata.apixels[spix]; - uae_u8 val = lookup[spix_val]; - if (lookup_no[spix_val] == 2) - val += dblpfofs[bpldualpf2of]; - val ^= xor_val; - dpix_val = colors_for_drawing.acolors[val]; - } - spix += 2; - buf[dpix++] = dpix_val; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 dpix_val; - uae_u32 out_val; - - if (spritepixels[spix]) { - out_val = colors_for_drawing.acolors[spritepixels[spix]]; - } else { - spix_val = pixdata.apixels[spix]; - uae_u8 val = lookup[spix_val]; - if (lookup_no[spix_val] == 2) - val += dblpfofs[bpldualpf2of]; - val ^= xor_val; - out_val = colors_for_drawing.acolors[val]; - } - spix += 2; - if (spritepixels[spix]) { - dpix_val = colors_for_drawing.acolors[spritepixels[spix]]; - } else { - spix_val = pixdata.apixels[spix]; - uae_u8 val = lookup[spix_val]; - if (lookup_no[spix_val] == 2) - val += dblpfofs[bpldualpf2of]; - val ^= xor_val; - dpix_val = colors_for_drawing.acolors[val]; - } - spix += 2; - *((uae_u32 *)&buf[dpix]) = merge_words(out_val, dpix_val); - dpix += 2; - } - if (rem) { - uae_u32 spix_val; - uae_u32 dpix_val; - if (spritepixels[spix]) { - dpix_val = colors_for_drawing.acolors[spritepixels[spix]]; - } else { - spix_val = pixdata.apixels[spix]; - uae_u8 val = lookup[spix_val]; - if (lookup_no[spix_val] == 2) - val += dblpfofs[bpldualpf2of]; - val ^= xor_val; - dpix_val = colors_for_drawing.acolors[val]; - } - spix += 2; - buf[dpix++] = dpix_val; - } - } else if (bplehb) { - int rem; - if (((long)&buf[dpix]) & 2) { - uae_u32 spix_val; - uae_u32 dpix_val; - spix_val = pixdata.apixels[spix] ^ xor_val; - if (spix_val >= 32 && spix_val < 64) { - unsigned int c = (colors_for_drawing.color_regs_aga[spix_val - 32] >> 1) & 0x7F7F7F; - dpix_val = CONVERT_RGB (c); - } else - dpix_val = colors_for_drawing.acolors[spix_val]; - spix += 2; - buf[dpix++] = dpix_val; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 dpix_val; - uae_u32 out_val; - - spix_val = pixdata.apixels[spix] ^ xor_val; - if (spix_val >= 32 && spix_val < 64) { - unsigned int c = (colors_for_drawing.color_regs_aga[spix_val - 32] >> 1) & 0x7F7F7F; - out_val = CONVERT_RGB (c); - } else - out_val = colors_for_drawing.acolors[spix_val]; - spix += 2; - spix_val = pixdata.apixels[spix] ^ xor_val; - if (spix_val >= 32 && spix_val < 64) { - unsigned int c = (colors_for_drawing.color_regs_aga[spix_val - 32] >> 1) & 0x7F7F7F; - dpix_val = CONVERT_RGB (c); - } else - dpix_val = colors_for_drawing.acolors[spix_val]; - spix += 2; - *((uae_u32 *)&buf[dpix]) = merge_words(out_val, dpix_val); - dpix += 2; - } - if (rem) { - uae_u32 spix_val; - uae_u32 dpix_val; - spix_val = pixdata.apixels[spix] ^ xor_val; - if (spix_val >= 32 && spix_val < 64) { - unsigned int c = (colors_for_drawing.color_regs_aga[spix_val - 32] >> 1) & 0x7F7F7F; - dpix_val = CONVERT_RGB (c); - } else - dpix_val = colors_for_drawing.acolors[spix_val]; - spix += 2; - buf[dpix++] = dpix_val; - } - } else { - int rem; - if (((long)&buf[dpix]) & 2) { - uae_u32 spix_val; - spix_val = pixdata.apixels[spix] ^ xor_val; - spix += 2; - buf[dpix++] = colors_for_drawing.acolors[spix_val]; - } - if (dpix >= dpix_end) - return spix; - rem = (((long)&buf[dpix_end]) & 2); - if (rem) - dpix_end--; - while (dpix < dpix_end) { - uae_u32 spix_val; - uae_u32 dpix_val; - uae_u32 out_val; - - spix_val = pixdata.apixels[spix] ^ xor_val; - out_val = colors_for_drawing.acolors[spix_val]; - spix += 2; - spix_val = pixdata.apixels[spix] ^ xor_val; - dpix_val = colors_for_drawing.acolors[spix_val]; - spix += 2; - *((uae_u32 *)&buf[dpix]) = merge_words(out_val, dpix_val); - dpix += 2; - } - if (rem) { - uae_u32 spix_val; - spix_val = pixdata.apixels[spix] ^ xor_val; - spix += 2; - buf[dpix++] = colors_for_drawing.acolors[spix_val]; - } - } - - return spix; -} -#endif diff --git a/src/linetoscr.cpp b/src/linetoscr.cpp new file mode 100644 index 00000000..5ce9cac1 --- /dev/null +++ b/src/linetoscr.cpp @@ -0,0 +1,17623 @@ +/* + * UAE - The portable Amiga emulator. + * + * This file was generated by genlinetoscr. Don't edit. + */ +STATIC_INLINE uae_u32 merge_words(uae_u32 val, uae_u32 val2) +{ + __asm__( + "pkhbt %[o], %[o], %[d], lsl #16 \n\t" + : [o] "+r" (val) : [d] "r" (val2)); + return val; +} + +STATIC_INLINE uae_u32 double_word(uae_u32 val) +{ + __asm__( + "pkhbt %[o], %[o], %[o], lsl #16 \n\t" + : [o] "+r" (val)); + return val; +} + +static int NOINLINE linetoscr_16(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_stretch1(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_stretch1_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 15); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_stretch2(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_stretch2_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val & 15); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 2] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 3] = get_genlock_transparency(lookup[spix_val]); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val & 31); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink1(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 2; + out_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink1_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink1f(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink1f_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink2(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 4; + out_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink2_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink2f(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink2f_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_stretch1_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_stretch1_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_stretch2_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_stretch2_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 2] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 3] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink1_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink1_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink1f_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink1f_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink2_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink2_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink2f_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_16_shrink2f_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +#ifdef AGA +static int NOINLINE linetoscr_16_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_stretch1_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_stretch2_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink1_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink1f_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink2_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink2f_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_aga(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + buf[dpix++] = dpix_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_stretch1_aga(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_stretch1_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 1] = get_genlock_transparency((spix_val >> 2) & 63); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_stretch2_aga(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_stretch2_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 1] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 2] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 3] = get_genlock_transparency((spix_val >> 2) & 63); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 2] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 3] = get_genlock_transparency(lookup[spix_val]); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val & 31); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink1_aga(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + out_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink1_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + buf[dpix++] = dpix_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink1f_aga(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink1f_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + buf[dpix++] = dpix_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink2_aga(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + out_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink2_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + buf[dpix++] = dpix_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink2f_aga(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink2f_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } else if (bplehb) { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } else { + int rem; + if (((uintptr_t)&buf[dpix]) & 2) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + if (dpix >= dpix_end) + return spix; + rem = (((uintptr_t)&buf[dpix_end]) & 2); + if (rem) + dpix_end--; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = (out_val & 0xFFFF) | (dpix_val << 16); + *((uae_u32 *)&buf[dpix]) = out_val; + dpix += 2; + } + if (rem) { + uae_u32 spix_val; + uae_u32 dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + buf[dpix++] = dpix_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_stretch1_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 1, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_stretch1_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 1] = get_genlock_transparency((spix_val >> 2) & 63); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 1, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_stretch2_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 1, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 1, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 1, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_stretch2_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 1] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 2] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 3] = get_genlock_transparency((spix_val >> 2) & 63); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + genlock_buf[dpix + 2] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + genlock_buf[dpix + 3] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 2] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 3] = get_genlock_transparency(lookup[spix_val]); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 1, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 1, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + genlock_buf[dpix + 2] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 1, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + genlock_buf[dpix + 3] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val & 31); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + genlock_buf[dpix + 2] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + genlock_buf[dpix + 3] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + genlock_buf[dpix + 2] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + genlock_buf[dpix + 3] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink1_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink1_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink1f_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink1f_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel16 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink2_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink2_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink2f_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_16_shrink2f_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u16 *buf = (uae_u16 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel16 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel16 (tmp_val3, dpix_val); + dpix_val = merge_2pixel16 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +static int NOINLINE linetoscr_32(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_stretch1(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_stretch1_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 15); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_stretch2(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_stretch2_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val & 15); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 2] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 3] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink1(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 2; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink1_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink1f(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink1f_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink2(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 4; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink2_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink2f(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink2f_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_stretch1_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_stretch1_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_stretch2_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_stretch2_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val & 15); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 2] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 3] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink1_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink1_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink1f_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink1f_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink2_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink2_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink2f_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +static int NOINLINE linetoscr_32_shrink2f_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = p_xcolors[spix_val]; + sprpix_val = pixdata.apixels[spix]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 15); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[lookup[spix_val]]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 1, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + if (spix_val <= 31) + dpix_val = p_acolors[spix_val]; + else + dpix_val = p_xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix, 0, sprpix_val, 0); + genlock_buf[dpix] = get_genlock_transparency(sprcol); + if (sprcol) { + uae_u32 spcol = p_acolors[sprcol]; + out_val = spcol; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} + +#ifdef AGA +static int NOINLINE linetoscr_32_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_stretch1_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_stretch2_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink1_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink1f_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink2_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink2f_aga_spronly(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + + if (1) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 out_val; + + sprpix_val = 0; + spix++; + out_val = p_acolors[0]; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_aga(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_stretch1_aga(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_stretch1_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 1] = get_genlock_transparency((spix_val >> 2) & 63); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_stretch2_aga(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_stretch2_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 1] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 2] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 3] = get_genlock_transparency((spix_val >> 2) & 63); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 2] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 3] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink1_aga(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink1_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink1f_aga(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink1f_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink2_aga(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink2_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink2f_aga(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink2f_aga_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_stretch1_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 1, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_stretch1_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 1] = get_genlock_transparency((spix_val >> 2) & 63); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 1, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + } + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_stretch2_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 1, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 1, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 1, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_stretch2_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 1] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 2] = get_genlock_transparency((spix_val >> 2) & 63); + genlock_buf[dpix + 3] = get_genlock_transparency((spix_val >> 2) & 63); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + genlock_buf[dpix + 2] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + genlock_buf[dpix + 3] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 1] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 2] = get_genlock_transparency(lookup[spix_val]); + genlock_buf[dpix + 3] = get_genlock_transparency(lookup[spix_val]); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 1, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 1, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + genlock_buf[dpix + 2] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 1, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + genlock_buf[dpix + 3] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val & 31); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val & 31); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + genlock_buf[dpix + 2] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + genlock_buf[dpix + 3] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 1] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 2] = get_genlock_transparency(spix_val); + genlock_buf[dpix + 3] = get_genlock_transparency(spix_val); + { + uae_u32 out_val1 = out_val; + uae_u32 out_val2 = out_val; + uae_u32 out_val3 = out_val; + uae_u32 out_val4 = out_val; + if (spritepixels[dpix + 0].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val1 = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 1].data) { + sprcol = render_sprites (dpix + 1, 0, sprpix_val, 1); + if (sprcol) { + out_val2 = p_acolors[sprcol]; + genlock_buf[dpix + 1] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 2].data) { + sprcol = render_sprites (dpix + 2, 0, sprpix_val, 1); + if (sprcol) { + out_val3 = p_acolors[sprcol]; + genlock_buf[dpix + 2] = get_genlock_transparency(sprcol); + } + } + if (spritepixels[dpix + 3].data) { + sprcol = render_sprites (dpix + 3, 0, sprpix_val, 1); + if (sprcol) { + out_val4 = p_acolors[sprcol]; + genlock_buf[dpix + 3] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val1; + buf[dpix++] = out_val2; + buf[dpix++] = out_val3; + buf[dpix++] = out_val4; + } + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink1_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink1_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 2; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink1f_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink1f_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + dpix_val = merge_2pixel32 (dpix_val, tmp_val); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink2_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink2_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix += 4; + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink2f_aga_spr(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + +#ifdef AGA +static int NOINLINE linetoscr_32_shrink2f_aga_spr_genlock(int spix, int dpix, int dpix_end) +{ + uae_u32 *buf = (uae_u32 *) xlinebuffer; + uae_u8 *genlock_buf = xlinebuffer_genlock; + uae_u8 sprcol; + uae_u8 xor_val = bplxor; + uae_u8 and_val = bpland; + + if (bplham) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val2 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + spix++; + tmp_val3 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = ham_linebuf[spix]; + dpix_val = CONVERT_RGB (spix_val); + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency((spix_val >> 2) & 63); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bpldualpf) { + int *lookup = bpldualpfpri ? dblpf_ind2_aga : dblpf_ind1_aga; + int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val2 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + spix++; + tmp_val3 = dpix_val; + spix_val = pixdata.apixels[spix]; + sprpix_val = spix_val; + { + uae_u8 val = lookup[spix_val]; + if (lookup_no[spix_val]) + val += dblpfofs[bpldualpf2of]; + val ^= xor_val; + dpix_val = p_acolors[val]; + } + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(lookup[spix_val]); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 1, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else if (bplehb) { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + if (pixdata.apixels[spix] & 0x20) { + unsigned int c = (colors_for_drawing.color_regs_aga[spix_val & 0x1f] >> 1) & 0x7F7F7F; + dpix_val = CONVERT_RGB (c); + } else + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val & 31); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } else { + while (dpix < dpix_end) { + uae_u32 sprpix_val; + uae_u32 spix_val; + uae_u32 dpix_val; + uae_u32 out_val; + + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + { + uae_u32 tmp_val, tmp_val2, tmp_val3; + spix++; + tmp_val = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val2 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + spix++; + tmp_val3 = dpix_val; + sprpix_val = pixdata.apixels[spix]; + spix_val = (pixdata.apixels[spix] ^ xor_val) & and_val; + dpix_val = p_acolors[spix_val]; + tmp_val = merge_2pixel32 (tmp_val, tmp_val2); + tmp_val2 = merge_2pixel32 (tmp_val3, dpix_val); + dpix_val = merge_2pixel32 (tmp_val, tmp_val2); + spix++; + } + out_val = dpix_val; + genlock_buf[dpix] = get_genlock_transparency(spix_val); + if (spritepixels[dpix].data) { + sprcol = render_sprites (dpix + 0, 0, sprpix_val, 1); + if (sprcol) { + out_val = p_acolors[sprcol]; + genlock_buf[dpix] = get_genlock_transparency(sprcol); + } + } + buf[dpix++] = out_val; + } + } + + return spix; +} +#endif + diff --git a/src/machdep/maccess.h b/src/machdep/maccess.h index 4f796021..d86f1210 100644 --- a/src/machdep/maccess.h +++ b/src/machdep/maccess.h @@ -44,15 +44,13 @@ STATIC_INLINE uae_u16 do_get_mem_word(uae_u16 *a) #else STATIC_INLINE uae_u16 do_get_mem_word(uae_u16 *a) { - uae_u8 *b = (uae_u8 *)a; - return (*b << 8) | (*(b+1)); + uae_u8 *b = (uae_u8 *)a; + + return (*b << 8) | (*(b + 1)); } #endif -STATIC_INLINE uae_u8 do_get_mem_byte(uae_u8 *a) -{ - return *a; -} +#define do_get_mem_byte(a) ((uae_u32)*(uae_u8 *)(a)) #ifdef ARMV6_ASSEMBLY STATIC_INLINE void do_put_mem_long(uae_u32 *a, uae_u32 v) @@ -65,12 +63,12 @@ STATIC_INLINE void do_put_mem_long(uae_u32 *a, uae_u32 v) #else STATIC_INLINE void do_put_mem_long(uae_u32 *a, uae_u32 v) { - uae_u8 *b = (uae_u8 *)a; + uae_u8 *b = (uae_u8 *)a; - *b = v >> 24; - *(b+1) = v >> 16; - *(b+2) = v >> 8; - *(b+3) = v; + *b = v >> 24; + *(b + 1) = v >> 16; + *(b + 2) = v >> 8; + *(b + 3) = v; } #endif @@ -88,7 +86,7 @@ STATIC_INLINE void do_put_mem_word(uae_u16 *a, uae_u16 v) uae_u8 *b = (uae_u8 *)a; *b = v >> 8; - *(b + 1) = v; + *(b + 1) = (uae_u8)v; } #endif diff --git a/src/main.cpp b/src/main.cpp index 0890134d..29bf059f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,6 +54,10 @@ SDL_DisplayMode sdlMode; #include #include "keyboard.h" +#ifdef DEBUG +#include "gperftools/profiler.h" +#endif + long int version = 256 * 65536L*UAEMAJOR + 65536L*UAEMINOR + UAESUBREV; struct uae_prefs currprefs, changed_prefs; @@ -282,12 +286,30 @@ void fixup_cpu(struct uae_prefs *p) } -void fixup_prefs(struct uae_prefs *p) +void fixup_prefs(struct uae_prefs *p, bool userconfig) { int err = 0; built_in_chipset_prefs(p); fixup_cpu(p); + cfgfile_compatibility_rtg(p); + cfgfile_compatibility_romtype(p); + + read_kickstart_version(p); + + //if (p->cpuboard_type && p->cpuboardmem1_size > cpuboard_maxmemory(p)) { + // error_log(_T("Unsupported accelerator board memory size %d (0x%x).\n"), p->cpuboardmem1_size, p->cpuboardmem1_size); + // p->cpuboardmem1_size = cpuboard_maxmemory(p); + //} + //if (cpuboard_memorytype(p) == BOARD_MEMORY_HIGHMEM) { + // p->mbresmem_high_size = p->cpuboardmem1_size; + //} + //else if (cpuboard_memorytype(p) == BOARD_MEMORY_Z2) { + // p->fastmem[0].size = p->cpuboardmem1_size; + //} + //else if (cpuboard_memorytype(p) == BOARD_MEMORY_25BITMEM) { + // p->mem25bit_size = p->cpuboardmem1_size; + //} if (((p->chipmem_size & (p->chipmem_size - 1)) != 0 && p->chipmem_size != 0x180000) || p->chipmem_size < 0x20000 @@ -297,69 +319,63 @@ void fixup_prefs(struct uae_prefs *p) p->chipmem_size = 0x200000; err = 1; } - if ((p->fastmem_size & (p->fastmem_size - 1)) != 0 - || (p->fastmem_size != 0 && (p->fastmem_size < 0x100000 || p->fastmem_size > 0x800000))) - { - error_log(_T("Unsupported fastmem size %d (0x%x)."), p->fastmem_size, p->fastmem_size); - p->fastmem_size = 0; - err = 1; - } - if (p->rtgmem_size > max_z3fastmem && p->rtgmem_type == GFXBOARD_UAE_Z3) { - error_log(_T("Graphics card memory size %d (0x%x) larger than maximum reserved %d (0x%x)."), p->rtgmem_size, p->rtgmem_size, max_z3fastmem, max_z3fastmem); - p->rtgmem_size = max_z3fastmem; - err = 1; - } - if ((p->rtgmem_size & (p->rtgmem_size - 1)) != 0 || (p->rtgmem_size != 0 && (p->rtgmem_size < 0x100000))) { - error_log(_T("Unsupported graphics card memory size %d (0x%x)."), p->rtgmem_size, p->rtgmem_size); - if (p->rtgmem_size > max_z3fastmem) - p->rtgmem_size = max_z3fastmem; - else - p->rtgmem_size = 0; - err = 1; + + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + if ((p->fastmem[i].size & (p->fastmem[i].size - 1)) != 0 + || (p->fastmem[i].size != 0 && (p->fastmem[i].size < 0x10000 || p->fastmem[i].size > 0x800000))) + { + error_log(_T("Unsupported fastmem size %d (0x%x)."), p->fastmem[i].size, p->fastmem[i].size); + p->fastmem[i].size = 0; + err = 1; + } } - if (p->z3fastmem_size > max_z3fastmem) { - error_log(_T("Zorro III fastmem size %d (0x%x) larger than max reserved %d (0x%x)."), p->z3fastmem_size, p->z3fastmem_size, max_z3fastmem, max_z3fastmem); - p->z3fastmem_size = max_z3fastmem; - err = 1; - } - if ((p->z3fastmem_size & (p->z3fastmem_size - 1)) != 0 || (p->z3fastmem_size != 0 && p->z3fastmem_size < 0x100000)) - { - error_log(_T("Unsupported Zorro III fastmem size %d (0x%x)."), p->z3fastmem_size, p->z3fastmem_size); - p->z3fastmem_size = 0; - err = 1; + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + struct rtgboardconfig *rbc = &p->rtgboards[i]; + if (rbc->rtgmem_size > max_z3fastmem && rbc->rtgmem_type == GFXBOARD_UAE_Z3) { + error_log(_T("Graphics card memory size %d (0x%x) larger than maximum reserved %d (0x%x)."), rbc->rtgmem_size, rbc->rtgmem_size, max_z3fastmem, max_z3fastmem); + rbc->rtgmem_size = max_z3fastmem; + err = 1; + } + + if ((rbc->rtgmem_size & (rbc->rtgmem_size - 1)) != 0 || (rbc->rtgmem_size != 0 && (rbc->rtgmem_size < 0x100000))) { + error_log(_T("Unsupported graphics card memory size %d (0x%x)."), rbc->rtgmem_size, rbc->rtgmem_size); + if (rbc->rtgmem_size > max_z3fastmem) + rbc->rtgmem_size = max_z3fastmem; + else + rbc->rtgmem_size = 0; + err = 1; + } } - if (p->z3fastmem2_size > max_z3fastmem) { - error_log(_T("Zorro III fastmem2 size %d (0x%x) larger than max reserved %d (0x%x)."), p->z3fastmem2_size, p->z3fastmem2_size, max_z3fastmem, max_z3fastmem); - p->z3fastmem2_size = max_z3fastmem; - err = 1; - } - if ((p->z3fastmem2_size & (p->z3fastmem2_size - 1)) != 0 || (p->z3fastmem2_size != 0 && p->z3fastmem2_size < 0x100000)) - { - error_log(_T("Unsupported Zorro III fastmem2 size %x (%x)."), p->z3fastmem2_size, p->z3fastmem2_size); - p->z3fastmem2_size = 0; - err = 1; + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + if ((p->z3fastmem[i].size & (p->z3fastmem[i].size - 1)) != 0 || (p->z3fastmem[i].size != 0 && p->z3fastmem[i].size < 0x100000)) + { + error_log(_T("Unsupported Zorro III fastmem size %d (0x%x)."), p->z3fastmem[i].size, p->z3fastmem[i].size); + p->z3fastmem[i].size = 0; + err = 1; + } } - p->z3fastmem_start &= ~0xffff; - if (p->z3fastmem_start < 0x1000000) - p->z3fastmem_start = 0x1000000; + p->z3autoconfig_start &= ~0xffff; + if (p->z3autoconfig_start < 0x1000000) + p->z3autoconfig_start = 0x1000000; if (p->z3chipmem_size > max_z3fastmem) { error_log(_T("Zorro III fake chipmem size %d (0x%x) larger than max reserved %d (0x%x)."), p->z3chipmem_size, p->z3chipmem_size, max_z3fastmem, max_z3fastmem); p->z3chipmem_size = max_z3fastmem; err = 1; -} - if ((p->z3chipmem_size & (p->z3chipmem_size - 1)) != 0 || (p->z3chipmem_size != 0 && p->z3chipmem_size < 0x100000)) + } + if (((p->z3chipmem_size & (p->z3chipmem_size - 1)) != 0 && p->z3chipmem_size != 0x18000000 && p->z3chipmem_size != 0x30000000) || (p->z3chipmem_size != 0 && p->z3chipmem_size < 0x100000)) { - error_log(_T("Unsupported Zorro III fake chipmem size %d (0x%x)."), p->z3chipmem_size, p->z3chipmem_size); + error_log(_T("Unsupported 32-bit chipmem size %d (0x%x)."), p->z3chipmem_size, p->z3chipmem_size); p->z3chipmem_size = 0; err = 1; } - if (p->address_space_24 && (p->z3fastmem_size != 0 || p->z3fastmem2_size != 0 || p->z3chipmem_size != 0)) { - p->z3fastmem_size = p->z3fastmem2_size = p->z3chipmem_size = 0; + if (p->address_space_24 && (p->z3fastmem[0].size != 0 || p->z3fastmem[1].size != 0 || p->z3fastmem[2].size != 0 || p->z3fastmem[3].size != 0 || p->z3chipmem_size != 0)) { + p->z3fastmem[0].size = p->z3fastmem[1].size = p->z3fastmem[2].size = p->z3fastmem[3].size = 0; + p->z3chipmem_size = 0; error_log(_T("Can't use a Z3 graphics card or 32-bit memory when using a 24 bit address space.")); } @@ -373,37 +389,67 @@ void fixup_prefs(struct uae_prefs *p) p->bogomem_size = 0x180000; error_log(_T("Possible Gayle bogomem conflict fixed.")); } - if (p->chipmem_size > 0x200000 && p->fastmem_size != 0) { + if (p->chipmem_size > 0x200000 && (p->fastmem[0].size > 262144 || p->fastmem[1].size > 262144)) { error_log(_T("You can't use fastmem and more than 2MB chip at the same time.")); - p->fastmem_size = 0; + p->chipmem_size = 0x200000; err = 1; } + if (p->mem25bit_size > 128 * 1024 * 1024 || (p->mem25bit_size & 0xfffff)) { + p->mem25bit_size = 0; + error_log(_T("Unsupported 25bit RAM size")); + } if (p->mbresmem_low_size > 0x04000000 || (p->mbresmem_low_size & 0xfffff)) { p->mbresmem_low_size = 0; - error_log(_T("Unsupported A3000 MB RAM size")); + error_log(_T("Unsupported Mainboard RAM size")); } if (p->mbresmem_high_size > 0x08000000 || (p->mbresmem_high_size & 0xfffff)) { p->mbresmem_high_size = 0; - error_log(_T("Unsupported Motherboard RAM size.")); + error_log(_T("Unsupported CPU Board RAM size.")); } - if (p->rtgmem_type >= GFXBOARD_HARDWARE) { - /*if (p->rtgmem_size < gfxboard_get_vram_min(p->rtgmem_type)) - p->rtgmem_size = gfxboard_get_vram_min(p->rtgmem_type);*/ - if (p->address_space_24 && gfxboard_is_z3(p->rtgmem_type)) { - p->rtgmem_type = GFXBOARD_UAE_Z2; - p->rtgmem_size = 0; - error_log(_T("Z3 RTG and 24-bit address space are not compatible.")); - } + //for (int i = 0; i < MAX_RTG_BOARDS; i++) { + // struct rtgboardconfig *rbc = &p->rtgboards[i]; + // if (p->chipmem_size > 0x200000 && rbc->rtgmem_size && gfxboard_get_configtype(rbc) == 2) { + // error_log(_T("You can't use Zorro II RTG and more than 2MB chip at the same time.")); + // p->chipmem_size = 0x200000; + // err = 1; + // } + // if (rbc->rtgmem_type >= GFXBOARD_HARDWARE) { + // if (gfxboard_get_vram_min(rbc) > 0 && rbc->rtgmem_size < gfxboard_get_vram_min(rbc)) { + // error_log(_T("Graphics card memory size %d (0x%x) smaller than minimum hardware supported %d (0x%x)."), + // rbc->rtgmem_size, rbc->rtgmem_size, gfxboard_get_vram_min(rbc), gfxboard_get_vram_min(rbc)); + // rbc->rtgmem_size = gfxboard_get_vram_min(rbc); + // } + // if (p->address_space_24 && gfxboard_get_configtype(rbc) == 3) { + // rbc->rtgmem_type = GFXBOARD_UAE_Z2; + // rbc->rtgmem_size = 0; + // error_log(_T("Z3 RTG and 24-bit address space are not compatible.")); + // } + // if (gfxboard_get_vram_max(rbc) > 0 && rbc->rtgmem_size > gfxboard_get_vram_max(rbc)) { + // error_log(_T("Graphics card memory size %d (0x%x) larger than maximum hardware supported %d (0x%x)."), + // rbc->rtgmem_size, rbc->rtgmem_size, gfxboard_get_vram_max(rbc), gfxboard_get_vram_max(rbc)); + // rbc->rtgmem_size = gfxboard_get_vram_max(rbc); + // } + // } + // if (p->address_space_24 && rbc->rtgmem_size && rbc->rtgmem_type == GFXBOARD_UAE_Z3) { + // error_log(_T("Z3 RTG and 24bit address space are not compatible.")); + // rbc->rtgmem_type = GFXBOARD_UAE_Z2; + // rbc->rtgmem_size = 0; + // } + //} + + if (p->cs_z3autoconfig && p->address_space_24) { + p->cs_z3autoconfig = false; + error_log(_T("Z3 autoconfig and 24bit address space are not compatible.")); } - if (p->address_space_24 && p->rtgmem_size && p->rtgmem_type == GFXBOARD_UAE_Z3) { - error_log(_T("Z3 RTG and 24bit address space are not compatible.")); - p->rtgmem_type = GFXBOARD_UAE_Z2; - } - if (p->rtgmem_type == GFXBOARD_UAE_Z2 && (p->chipmem_size > 2 * 1024 * 1024 || getz2size(p) > 8 * 1024 * 1024 || getz2size(p) < 0)) { - p->rtgmem_size = 0; - error_log(_T("Too large Z2 RTG memory size.")); + +#if 0 + if (p->m68k_speed < -1 || p->m68k_speed > 20) { + write_log(_T("Bad value for -w parameter: must be -1, 0, or within 1..20.\n")); + p->m68k_speed = 4; + err = 1; } +#endif if (p->produce_sound < 0 || p->produce_sound > 3) { error_log(_T("Bad value for -S parameter: enable value must be within 0..3.")); @@ -435,17 +481,21 @@ void fixup_prefs(struct uae_prefs *p) p->cachesize = 0; err = 1; } - if ((p->z3fastmem_size || p->z3fastmem2_size || p->z3chipmem_size) && (p->address_space_24 || p->cpu_model < 68020)) { - error_log(_T("Z3 fast memory can't be used with a 68000/68010 emulation. Turning off Z3 fast memory.")); - p->z3fastmem_size = 0; - p->z3fastmem2_size = 0; + if ((p->z3fastmem[0].size || p->z3fastmem[1].size || p->z3fastmem[2].size || p->z3fastmem[3].size || p->z3chipmem_size) && p->address_space_24) { + error_log(_T("Z3 fast memory can't be used if address space is 24-bit.")); + p->z3fastmem[0].size = 0; + p->z3fastmem[1].size = 0; + p->z3fastmem[2].size = 0; + p->z3fastmem[3].size = 0; p->z3chipmem_size = 0; err = 1; } - if (p->rtgmem_size > 0 && p->rtgmem_type == GFXBOARD_UAE_Z3 && (p->cpu_model < 68020 || p->address_space_24)) { - error_log(_T("UAEGFX RTG can't be used with a 68000/68010 or 68EC020 emulation. Turning off RTG.")); - p->rtgmem_size = 0; - err = 1; + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + if ((p->rtgboards[i].rtgmem_size > 0 && p->rtgboards[i].rtgmem_type == GFXBOARD_UAE_Z3) && p->address_space_24) { + error_log(_T("UAEGFX Z3 RTG can't be used if address space is 24-bit.")); + p->rtgboards[i].rtgmem_size = 0; + err = 1; + } } #if !defined (BSDSOCKET) @@ -455,6 +505,10 @@ void fixup_prefs(struct uae_prefs *p) err = 1; } #endif + if (p->socket_emu && p->uaeboard >= 3) { + write_log(_T("bsdsocket.library is not compatible with indirect UAE Boot ROM.\n")); + p->socket_emu = 0; + } if (p->nr_floppies < 0 || p->nr_floppies > 4) { error_log(_T("Invalid number of floppies. Using 2.")); @@ -479,8 +533,8 @@ void fixup_prefs(struct uae_prefs *p) err = 1; } if (p->parallel_postscript_emulation) - p->parallel_postscript_detection = true; - if (p->cs_compatible == 1) { + p->parallel_postscript_detection = 1; + if (p->cs_compatible == CP_GENERIC) { p->cs_fatgaryrev = p->cs_ramseyrev = p->cs_mbdmac = -1; p->cs_ide = 0; if (p->cpu_model >= 68020) { @@ -488,8 +542,8 @@ void fixup_prefs(struct uae_prefs *p) p->cs_ide = -1; p->cs_ramseyrev = 0x0f; p->cs_mbdmac = 0; - } } +} else if (p->cs_compatible == 0) { if (p->cs_ide == IDE_A4000) { if (p->cs_fatgaryrev < 0) @@ -498,6 +552,9 @@ void fixup_prefs(struct uae_prefs *p) p->cs_ramseyrev = 0x0f; } } + if (p->chipmem_size >= 0x100000) + p->cs_1mchipjumper = true; + /* Can't fit genlock and A2024 or Graffiti at the same time, * also Graffiti uses genlock audio bit as an enable signal */ @@ -505,6 +562,9 @@ void fixup_prefs(struct uae_prefs *p) error_log(_T("Genlock and A2024 or Graffiti can't be active simultaneously.")); p->genlock = false; } + if (p->cs_hacks) { + error_log(_T("chipset_hacks is nonzero (0x%04x)."), p->cs_hacks); + } fixup_prefs_dimensions(p); @@ -524,7 +584,7 @@ void fixup_prefs(struct uae_prefs *p) p->address_space_24 = 0; #endif #if !defined (CPUEMU_13) - p->cpu_cycle_exact = p->blitter_cycle_exact = false; + p->cpu_cycle_exact = p->blitter_cycle_exact = 0; #endif #ifndef AGA p->chipset_mask &= ~CSMASK_AGA; @@ -539,15 +599,18 @@ void fixup_prefs(struct uae_prefs *p) #endif #if !defined (SCSIEMU) p->scsi = 0; +//#ifdef _WIN32 +// p->win32_aspi = 0; +//#endif #endif #if !defined (SANA2) - p->sana2 = false; + p->sana2 = 0; #endif #if !defined (UAESERIAL) - p->uaeserial = false; + p->uaeserial = 0; #endif #if defined (CPUEMU_13) - if (p->cpu_cycle_exact) { + if (p->cpu_memory_cycle_exact) { if (p->gfx_framerate > 1) { error_log(_T("Cycle-exact requires disabled frameskip.")); p->gfx_framerate = 1; @@ -556,22 +619,33 @@ void fixup_prefs(struct uae_prefs *p) error_log(_T("Cycle-exact and JIT can't be active simultaneously.")); p->cachesize = 0; } +#if 0 if (p->m68k_speed) { error_log(_T("Adjustable CPU speed is not available in cycle-exact mode.")); p->m68k_speed = 0; } +#endif } #endif - if (p->maprom && !p->address_space_24) + if (p->gfx_framerate < 1) + p->gfx_framerate = 1; + if (p->maprom && !p->address_space_24) { p->maprom = 0x0f000000; - if (((p->maprom & 0xff000000) && p->address_space_24) || p->mbresmem_high_size == 0x08000000) { + } + if (((p->maprom & 0xff000000) && p->address_space_24) || (p->maprom && p->mbresmem_high_size >= 0x08000000)) { p->maprom = 0x00e00000; } + if (p->maprom && p->cpuboard_type) { + error_log(_T("UAE Maprom and accelerator board emulation are not compatible.")); + p->maprom = 0; + } + if (p->tod_hack && p->cs_ciaatod == 0) p->cs_ciaatod = p->ntscmode ? 2 : 1; built_in_chipset_prefs(p); blkdev_fix_prefs(p); + //inputdevice_fix_prefs(p, userconfig); target_fixup_options(p); } @@ -787,7 +861,7 @@ static void parse_cmdline_and_init_file(int argc, TCHAR **argv) if (!target_cfgfile_load(&currprefs, optionsfile, 0, default_config)) { write_log(_T("failed to load config '%s'\n"), optionsfile); } - fixup_prefs(&currprefs); + fixup_prefs(&currprefs, false); parse_cmdline(argc, argv); } @@ -1012,8 +1086,8 @@ static int real_main2 (int argc, TCHAR **argv) set_config_changed(); if (restart_config[0]) { - default_prefs(&currprefs, 0); - fixup_prefs(&currprefs); + default_prefs(&currprefs, true, 0); + fixup_prefs(&currprefs, true); } if (!graphics_setup()) { @@ -1063,7 +1137,11 @@ static int real_main2 (int argc, TCHAR **argv) gui_data.md = -1; #ifdef NATMEM_OFFSET - init_shm(); + if (!init_shm()) { + if (currprefs.start_gui) + uae_restart(-1, NULL); + return 0; +} #endif #ifdef WITH_LUA uae_lua_init(); @@ -1072,7 +1150,7 @@ static int real_main2 (int argc, TCHAR **argv) picasso_reset(); #endif - fixup_prefs(&currprefs); + fixup_prefs(&currprefs, true); #ifdef RETROPLATFORM rp_fixup_options(&currprefs); #endif @@ -1090,12 +1168,14 @@ static int real_main2 (int argc, TCHAR **argv) #ifdef AUTOCONFIG native2amiga_install(); #endif - custom_init(); /* Must come after memory_init */ #ifdef SERIAL_PORT serial_init(); #endif DISK_init(); +#ifdef WITH_PPC + uae_ppc_reset(true); +#endif reset_frame_rate_hack(); init_m68k(); /* must come after reset_frame_rate_hack (); */ diff --git a/src/memory.cpp b/src/memory.cpp index 2cb897e6..82c7f0ec 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -11,7 +11,7 @@ #include "options.h" #include "uae.h" -#include "memory.h" +#include "include/memory.h" #include "rommgr.h" #include "ersatz.h" #include "zfile.h" @@ -23,72 +23,164 @@ #include "gui.h" #include "akiko.h" #include "gfxboard.h" +#include "jit/compemu.h" +bool canbang; +static bool rom_write_enabled; #ifdef JIT /* Set by each memory handler that does not simply access real memory. */ int special_mem; #endif static int mem_hardreset; +static bool roms_modified; -static size_t bootrom_filepos, chip_filepos, bogo_filepos, rom_filepos; +#define FLASHEMU 0 + +static bool isdirectjit(void) +{ + return currprefs.cachesize && !currprefs.comptrustbyte; +} + +static bool canjit(void) +{ + if (currprefs.cpu_model < 68020 || currprefs.address_space_24) + return false; + return true; +} +static bool needmman(void) +{ + //if (!jit_direct_compatible_memory) + // return false; +//#ifdef _WIN32 +// return true; +//#endif + if (canjit()) + return true; + return false; +} + +static void nocanbang(void) +{ + if (canbang) { + write_log(_T("Switching JIT direct off!\n")); + } + canbang = 0; +} + +uae_u8 ce_banktype[65536]; +uae_u8 ce_cachable[65536]; + +static size_t bootrom_filepos, chip_filepos, bogo_filepos, a3000lmem_filepos, a3000hmem_filepos, mem25bit_filepos; /* Set if we notice during initialization that settings changed, and we must clear all memory to prevent bogus contents from confusing the Kickstart. */ static bool need_hardreset; +static int bogomem_aliasing; /* The address space setting used during the last reset. */ static bool last_address_space_24; addrbank *mem_banks[MEMORY_BANKS]; +/* This has two functions. It either holds a host address that, when added +to the 68k address, gives the host address corresponding to that 68k +address (in which case the value in this array is even), OR it holds the +same value as mem_banks, for those banks that have baseaddr==0. In that +case, bit 0 is set (the memory access routines will take care of it). */ + +uae_u8 *baseaddr[MEMORY_BANKS]; + +#ifdef NO_INLINE_MEMORY_ACCESS +__inline__ uae_u32 longget(uaecptr addr) +{ + return call_mem_get_func(get_mem_bank(addr).lget, addr); +} +__inline__ uae_u32 wordget(uaecptr addr) +{ + return call_mem_get_func(get_mem_bank(addr).wget, addr); +} +__inline__ uae_u32 byteget(uaecptr addr) +{ + return call_mem_get_func(get_mem_bank(addr).bget, addr); +} +__inline__ void longput(uaecptr addr, uae_u32 l) +{ + call_mem_put_func(get_mem_bank(addr).lput, addr, l); +} +__inline__ void wordput(uaecptr addr, uae_u32 w) +{ + call_mem_put_func(get_mem_bank(addr).wput, addr, w); +} +__inline__ void byteput(uaecptr addr, uae_u32 b) +{ + call_mem_put_func(get_mem_bank(addr).bput, addr, b); +} +#endif int addr_valid(const TCHAR *txt, uaecptr addr, uae_u32 len) { - addrbank *ab = &get_mem_bank(addr); - if (ab == 0 || !(ab->flags & (ABFLAG_RAM | ABFLAG_ROM)) || addr < 0x100 || len < 0 || len > 16777215 || !valid_address(addr, len)) { - write_log (_T("corrupt %s pointer %x (%d) detected!\n"), txt, addr, len); - return 0; - } - return 1; + addrbank *ab = &get_mem_bank(addr); + if (ab == 0 || !(ab->flags & (ABFLAG_RAM | ABFLAG_ROM)) || addr < 0x100 || len > 16777215 || !valid_address(addr, len)) { + write_log(_T("corrupt %s pointer %x (%d) detected!\n"), txt, addr, len); + return 0; + } + return 1; } +static int illegal_count; /* A dummy bank that only contains zeros */ -static uae_u32 REGPARAM3 dummy_lget (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 dummy_wget (uaecptr) REGPARAM; -static uae_u32 REGPARAM3 dummy_bget (uaecptr) REGPARAM; -static void REGPARAM3 dummy_lput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 dummy_wput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 dummy_bput (uaecptr, uae_u32) REGPARAM; -static int REGPARAM3 dummy_check (uaecptr addr, uae_u32 size) REGPARAM; +static uae_u32 REGPARAM3 dummy_lget(uaecptr) REGPARAM; +static uae_u32 REGPARAM3 dummy_wget(uaecptr) REGPARAM; +static uae_u32 REGPARAM3 dummy_bget(uaecptr) REGPARAM; +static void REGPARAM3 dummy_lput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 dummy_wput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 dummy_bput(uaecptr, uae_u32) REGPARAM; +static int REGPARAM3 dummy_check(uaecptr addr, uae_u32 size) REGPARAM; +#define MAX_ILG 1000 #define NONEXISTINGDATA 0 //#define NONEXISTINGDATA 0xffffffff -STATIC_INLINE uae_u32 dummy_get (uaecptr addr, int size, bool inst) +void dummy_put(uaecptr addr, int size, uae_u32 val) { - uae_u32 v = NONEXISTINGDATA; +} + +uae_u32 dummy_get(uaecptr addr, int size, bool inst, uae_u32 defvalue) +{ + uae_u32 v = defvalue; + uae_u32 mask = size == 4 ? 0xffffffff : (1 << (size * 8)) - 1; if (currprefs.cpu_model >= 68040) - return v; + return v & mask; if (!currprefs.cpu_compatible) - return v; + return v & mask; if (currprefs.address_space_24) addr &= 0x00ffffff; if (addr >= 0x10000000) - return v; + return v & mask; + // CD32 returns zeros from all unmapped addresses + if (currprefs.cs_cd32cd) + return 0; if ((currprefs.cpu_model <= 68010) || (currprefs.cpu_model == 68020 && (currprefs.chipset_mask & CSMASK_AGA) && currprefs.address_space_24)) { - if (size == 4) { - v = (regs.irc << 16) | regs.irc; - } else if (size == 2) { - v = regs.irc & 0xffff; - } else { - v = regs.irc; - v = (addr & 1) ? (v & 0xff) : ((v >> 8) & 0xff); + if (size == 4) { + v = regs.db & 0xffff; + if (addr & 1) + v = (v << 8) | (v >> 8); + v = (v << 16) | v; } - } - return v; + else if (size == 2) { + v = regs.db & 0xffff; + if (addr & 1) + v = (v << 8) | (v >> 8); + } + else { + v = regs.db; + v = (addr & 1) ? (v & 0xff) : ((v >> 8) & 0xff); + } + } + return v & mask; } static uae_u32 REGPARAM2 dummy_lget (uaecptr addr) @@ -96,14 +188,14 @@ static uae_u32 REGPARAM2 dummy_lget (uaecptr addr) #ifdef JIT special_mem |= S_READ; #endif - return dummy_get (addr, 4, false); + return dummy_get(addr, 4, false, NONEXISTINGDATA); } uae_u32 REGPARAM2 dummy_lgeti (uaecptr addr) { #ifdef JIT special_mem |= S_READ; #endif - return dummy_get (addr, 4, true); + return dummy_get(addr, 4, true, NONEXISTINGDATA); } static uae_u32 REGPARAM2 dummy_wget (uaecptr addr) @@ -111,14 +203,14 @@ static uae_u32 REGPARAM2 dummy_wget (uaecptr addr) #ifdef JIT special_mem |= S_READ; #endif - return dummy_get (addr, 2, false); + return dummy_get(addr, 2, false, NONEXISTINGDATA); } uae_u32 REGPARAM2 dummy_wgeti (uaecptr addr) { #ifdef JIT special_mem |= S_READ; #endif - return dummy_get (addr, 2, true); + return dummy_get(addr, 2, true, NONEXISTINGDATA); } static uae_u32 REGPARAM2 dummy_bget (uaecptr addr) @@ -126,7 +218,7 @@ static uae_u32 REGPARAM2 dummy_bget (uaecptr addr) #ifdef JIT special_mem |= S_READ; #endif - return dummy_get (addr, 1, false); + return dummy_get(addr, 1, false, NONEXISTINGDATA); } static void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l) @@ -158,96 +250,439 @@ static int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size) return 0; } +static void REGPARAM2 none_put(uaecptr addr, uae_u32 v) +{ +} +static uae_u32 REGPARAM2 ones_get(uaecptr addr) +{ + return 0xffffffff; +} + +addrbank *get_sub_bank(uaecptr *paddr) +{ + int i; + uaecptr addr = *paddr; + addrbank *ab = &get_mem_bank(addr); + struct addrbank_sub *sb = ab->sub_banks; + if (!sb) + return &dummy_bank; + for (i = 0; sb[i].bank; i++) { + int offset = addr & 65535; + if (offset < sb[i + 1].offset) { + uae_u32 mask = sb[i].mask; + uae_u32 maskval = sb[i].maskval; + if ((offset & mask) == maskval) { + *paddr = addr - sb[i].suboffset; + return sb[i].bank; + } + } + } + *paddr = addr - sb[i - 1].suboffset; + return sb[i - 1].bank; +} +uae_u32 REGPARAM3 sub_bank_lget(uaecptr addr) REGPARAM +{ + addrbank *ab = get_sub_bank(&addr); + return ab->lget(addr); +} +uae_u32 REGPARAM3 sub_bank_wget(uaecptr addr) REGPARAM +{ + addrbank *ab = get_sub_bank(&addr); + return ab->wget(addr); +} +uae_u32 REGPARAM3 sub_bank_bget(uaecptr addr) REGPARAM +{ + addrbank *ab = get_sub_bank(&addr); + return ab->bget(addr); +} +void REGPARAM3 sub_bank_lput(uaecptr addr, uae_u32 v) REGPARAM +{ + addrbank *ab = get_sub_bank(&addr); + ab->lput(addr, v); +} +void REGPARAM3 sub_bank_wput(uaecptr addr, uae_u32 v) REGPARAM +{ + addrbank *ab = get_sub_bank(&addr); + ab->wput(addr, v); +} +void REGPARAM3 sub_bank_bput(uaecptr addr, uae_u32 v) REGPARAM +{ + addrbank *ab = get_sub_bank(&addr); + ab->bput(addr, v); +} +uae_u32 REGPARAM3 sub_bank_lgeti(uaecptr addr) REGPARAM +{ + addrbank *ab = get_sub_bank(&addr); + return ab->lgeti(addr); +} +uae_u32 REGPARAM3 sub_bank_wgeti(uaecptr addr) REGPARAM +{ + addrbank *ab = get_sub_bank(&addr); + return ab->wgeti(addr); +} +int REGPARAM3 sub_bank_check(uaecptr addr, uae_u32 size) REGPARAM +{ + addrbank *ab = get_sub_bank(&addr); + return ab->check(addr, size); +} +uae_u8 *REGPARAM3 sub_bank_xlate(uaecptr addr) REGPARAM +{ + addrbank *ab = get_sub_bank(&addr); + return ab->xlateaddr(addr); +} + /* Chip memory */ -uae_u32 chipmem_full_mask; +static uae_u32 chipmem_full_mask; +static uae_u32 chipmem_full_size; -static int REGPARAM3 chipmem_check (uaecptr addr, uae_u32 size) REGPARAM; -static uae_u8 *REGPARAM3 chipmem_xlate (uaecptr addr) REGPARAM; +static int REGPARAM3 chipmem_check(uaecptr addr, uae_u32 size) REGPARAM; +static uae_u8 *REGPARAM3 chipmem_xlate(uaecptr addr) REGPARAM; -uae_u32 REGPARAM2 chipmem_lget (uaecptr addr) +#ifdef AGA + +/* AGA ce-chipram access */ + +static void ce2_timeout(void) { - uae_u32 *m; - - addr &= chipmem_bank.mask; - m = (uae_u32 *)(chipmem_bank.baseaddr + addr); - return do_get_mem_long (m); +#ifdef CPUEMU_13 + wait_cpu_cycle_read(0, -1); +#endif } -static uae_u32 REGPARAM2 chipmem_wget (uaecptr addr) +static uae_u32 REGPARAM2 chipmem_lget_ce2(uaecptr addr) { - uae_u16 *m, v; + uae_u32 *m; - addr &= chipmem_bank.mask; - m = (uae_u16 *)(chipmem_bank.baseaddr + addr); - v = do_get_mem_word (m); - return v; + addr &= chipmem_bank.mask; + m = (uae_u32 *)(chipmem_bank.baseaddr + addr); + ce2_timeout(); + return do_get_mem_long(m); } -static uae_u32 REGPARAM2 chipmem_bget (uaecptr addr) +static uae_u32 REGPARAM2 chipmem_wget_ce2(uaecptr addr) +{ + uae_u16 *m, v; + + addr &= chipmem_bank.mask; + m = (uae_u16 *)(chipmem_bank.baseaddr + addr); + ce2_timeout(); + v = do_get_mem_word(m); + return v; +} + +static uae_u32 REGPARAM2 chipmem_bget_ce2(uaecptr addr) +{ + addr &= chipmem_bank.mask; + ce2_timeout(); + return chipmem_bank.baseaddr[addr]; +} + +static void REGPARAM2 chipmem_lput_ce2(uaecptr addr, uae_u32 l) +{ + uae_u32 *m; + + addr &= chipmem_bank.mask; + m = (uae_u32 *)(chipmem_bank.baseaddr + addr); + ce2_timeout(); + do_put_mem_long(m, l); +} + +static void REGPARAM2 chipmem_wput_ce2(uaecptr addr, uae_u32 w) +{ + uae_u16 *m; + + addr &= chipmem_bank.mask; + m = (uae_u16 *)(chipmem_bank.baseaddr + addr); + ce2_timeout(); + do_put_mem_word(m, w); +} + +static void REGPARAM2 chipmem_bput_ce2(uaecptr addr, uae_u32 b) +{ + addr &= chipmem_bank.mask; + ce2_timeout(); + chipmem_bank.baseaddr[addr] = b; +} + +#endif + +static uae_u32 REGPARAM2 chipmem_lget(uaecptr addr) +{ + uae_u32 *m; + + addr &= chipmem_bank.mask; + m = (uae_u32 *)(chipmem_bank.baseaddr + addr); + return do_get_mem_long(m); +} + +static uae_u32 REGPARAM2 chipmem_wget(uaecptr addr) +{ + uae_u16 *m, v; + + addr &= chipmem_bank.mask; + m = (uae_u16 *)(chipmem_bank.baseaddr + addr); + v = do_get_mem_word(m); + return v; +} + +static uae_u32 REGPARAM2 chipmem_bget(uaecptr addr) { uae_u8 v; - addr &= chipmem_bank.mask; + addr &= chipmem_bank.mask; v = chipmem_bank.baseaddr[addr]; return v; } -void REGPARAM2 chipmem_lput (uaecptr addr, uae_u32 l) +void REGPARAM2 chipmem_lput(uaecptr addr, uae_u32 l) { - uae_u32 *m; - addr &= chipmem_bank.mask; - m = (uae_u32 *)(chipmem_bank.baseaddr + addr); - do_put_mem_long(m, l); + uae_u32 *m; + + addr &= chipmem_bank.mask; + m = (uae_u32 *)(chipmem_bank.baseaddr + addr); + do_put_mem_long(m, l); } -void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w) +void REGPARAM2 chipmem_wput(uaecptr addr, uae_u32 w) { - uae_u16 *m; - addr &= chipmem_bank.mask; - m = (uae_u16 *)(chipmem_bank.baseaddr + addr); - do_put_mem_word (m, w); + uae_u16 *m; + + addr &= chipmem_bank.mask; + m = (uae_u16 *)(chipmem_bank.baseaddr + addr); + do_put_mem_word(m, w); } -void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b) +void REGPARAM2 chipmem_bput(uaecptr addr, uae_u32 b) { - addr &= chipmem_bank.mask; + addr &= chipmem_bank.mask; chipmem_bank.baseaddr[addr] = b; } -void REGPARAM2 chipmem_agnus_wput (uaecptr addr, uae_u32 w) +/* cpu chipmem access inside agnus addressable ram but no ram available */ +static uae_u32 chipmem_dummy(void) { - uae_u16 *m; - - addr &= chipmem_full_mask; - if (addr >= chipmem_bank.allocated) - return; - m = (uae_u16 *)(chipmem_bank.baseaddr + addr); - do_put_mem_word (m, w); + /* not really right but something random that has more ones than zeros.. */ + return 0xffff & ~((1 << (uaerand() & 31)) | (1 << (uaerand() & 31))); } -static int REGPARAM2 chipmem_check (uaecptr addr, uae_u32 size) +static void REGPARAM2 chipmem_dummy_bput(uaecptr addr, uae_u32 b) +{ +} +static void REGPARAM2 chipmem_dummy_wput(uaecptr addr, uae_u32 b) +{ +} +static void REGPARAM2 chipmem_dummy_lput(uaecptr addr, uae_u32 b) { - addr &= chipmem_bank.mask; - return (addr + size) <= chipmem_bank.allocated; } -static uae_u8 *REGPARAM2 chipmem_xlate (uaecptr addr) +static uae_u32 REGPARAM2 chipmem_dummy_bget(uaecptr addr) +{ + return chipmem_dummy(); +} +static uae_u32 REGPARAM2 chipmem_dummy_wget(uaecptr addr) +{ + return chipmem_dummy(); +} +static uae_u32 REGPARAM2 chipmem_dummy_lget(uaecptr addr) +{ + return (chipmem_dummy() << 16) | chipmem_dummy(); +} + +static uae_u32 REGPARAM2 chipmem_agnus_lget(uaecptr addr) +{ + uae_u32 *m; + + addr &= chipmem_full_mask; + if (addr >= chipmem_full_size - 3) + return 0; + m = (uae_u32 *)(chipmem_bank.baseaddr + addr); + return do_get_mem_long(m); +} + +uae_u32 REGPARAM2 chipmem_agnus_wget(uaecptr addr) +{ + uae_u16 *m; + + addr &= chipmem_full_mask; + if (addr >= chipmem_full_size - 1) + return 0; + m = (uae_u16 *)(chipmem_bank.baseaddr + addr); + return do_get_mem_word(m); +} + +static uae_u32 REGPARAM2 chipmem_agnus_bget(uaecptr addr) +{ + addr &= chipmem_full_mask; + if (addr >= chipmem_full_size) + return 0; + return chipmem_bank.baseaddr[addr]; +} + +static void REGPARAM2 chipmem_agnus_lput(uaecptr addr, uae_u32 l) +{ + uae_u32 *m; + + addr &= chipmem_full_mask; + if (addr >= chipmem_full_size - 3) + return; + m = (uae_u32 *)(chipmem_bank.baseaddr + addr); + do_put_mem_long(m, l); +} + +void REGPARAM2 chipmem_agnus_wput(uaecptr addr, uae_u32 w) +{ + uae_u16 *m; + + addr &= chipmem_full_mask; + if (addr >= chipmem_full_size - 1) + return; + m = (uae_u16 *)(chipmem_bank.baseaddr + addr); + do_put_mem_word(m, w); +} + +static void REGPARAM2 chipmem_agnus_bput(uaecptr addr, uae_u32 b) +{ + addr &= chipmem_full_mask; + if (addr >= chipmem_full_size) + return; + chipmem_bank.baseaddr[addr] = b; +} + +static int REGPARAM2 chipmem_check(uaecptr addr, uae_u32 size) { addr &= chipmem_bank.mask; - return chipmem_bank.baseaddr + addr; + return (addr + size) <= chipmem_full_size; +} + +static uae_u8 *REGPARAM2 chipmem_xlate(uaecptr addr) +{ + addr &= chipmem_bank.mask; + return chipmem_bank.baseaddr + addr; +} + +STATIC_INLINE void REGPARAM2 chipmem_lput_bigmem(uaecptr addr, uae_u32 v) +{ + put_long(addr, v); +} +STATIC_INLINE void REGPARAM2 chipmem_wput_bigmem(uaecptr addr, uae_u32 v) +{ + put_word(addr, v); +} +STATIC_INLINE void REGPARAM2 chipmem_bput_bigmem(uaecptr addr, uae_u32 v) +{ + put_byte(addr, v); +} +STATIC_INLINE uae_u32 REGPARAM2 chipmem_lget_bigmem(uaecptr addr) +{ + return get_long(addr); +} +STATIC_INLINE uae_u32 REGPARAM2 chipmem_wget_bigmem(uaecptr addr) +{ + return get_word(addr); +} +STATIC_INLINE uae_u32 REGPARAM2 chipmem_bget_bigmem(uaecptr addr) +{ + return get_byte(addr); +} +STATIC_INLINE int REGPARAM2 chipmem_check_bigmem(uaecptr addr, uae_u32 size) +{ + return valid_address(addr, size); +} +STATIC_INLINE uae_u8* REGPARAM2 chipmem_xlate_bigmem(uaecptr addr) +{ + return get_real_address(addr); +} + +uae_u32(REGPARAM2 *chipmem_lget_indirect)(uaecptr); +uae_u32(REGPARAM2 *chipmem_wget_indirect)(uaecptr); +uae_u32(REGPARAM2 *chipmem_bget_indirect)(uaecptr); +void (REGPARAM2 *chipmem_lput_indirect)(uaecptr, uae_u32); +void (REGPARAM2 *chipmem_wput_indirect)(uaecptr, uae_u32); +void (REGPARAM2 *chipmem_bput_indirect)(uaecptr, uae_u32); +int (REGPARAM2 *chipmem_check_indirect)(uaecptr, uae_u32); +uae_u8 *(REGPARAM2 *chipmem_xlate_indirect)(uaecptr); + +static void chipmem_setindirect(void) +{ + if (currprefs.z3chipmem_size) { + chipmem_lget_indirect = chipmem_lget_bigmem; + chipmem_wget_indirect = chipmem_wget_bigmem; + chipmem_bget_indirect = chipmem_bget_bigmem; + chipmem_lput_indirect = chipmem_lput_bigmem; + chipmem_wput_indirect = chipmem_wput_bigmem; + chipmem_bput_indirect = chipmem_bput_bigmem; + chipmem_check_indirect = chipmem_check_bigmem; + chipmem_xlate_indirect = chipmem_xlate_bigmem; + } + else { + chipmem_lget_indirect = chipmem_lget; + chipmem_wget_indirect = chipmem_agnus_wget; + chipmem_bget_indirect = chipmem_agnus_bget; + chipmem_lput_indirect = chipmem_lput; + chipmem_wput_indirect = chipmem_agnus_wput; + chipmem_bput_indirect = chipmem_agnus_bput; + chipmem_check_indirect = chipmem_check; + chipmem_xlate_indirect = chipmem_xlate; + } } /* Slow memory */ MEMORY_FUNCTIONS(bogomem); +/* CDTV expension memory card memory */ + +MEMORY_FUNCTIONS(cardmem); + +/* A3000 motherboard fast memory */ + +MEMORY_FUNCTIONS(a3000lmem); +MEMORY_FUNCTIONS(a3000hmem); + +/* 25bit memory (0x01000000) */ + +MEMORY_FUNCTIONS(mem25bit); + /* Kick memory */ uae_u16 kickstart_version; -static void REGPARAM3 kickmem_lput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 kickmem_wput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 kickmem_bput (uaecptr, uae_u32) REGPARAM; +/* +* A1000 kickstart RAM handling +* +* RESET instruction unhides boot ROM and disables write protection +* write access to boot ROM hides boot ROM and enables write protection +* +*/ +static int a1000_kickstart_mode; +static uae_u8 *a1000_bootrom; +static void a1000_handle_kickstart(int mode) +{ + if (!a1000_bootrom) + return; + protect_roms(false); + if (mode == 0) { + a1000_kickstart_mode = 0; + memcpy(kickmem_bank.baseaddr, kickmem_bank.baseaddr + ROM_SIZE_256, ROM_SIZE_256); + kickstart_version = (kickmem_bank.baseaddr[ROM_SIZE_256 + 12] << 8) | kickmem_bank.baseaddr[ROM_SIZE_256 + 13]; + } + else { + a1000_kickstart_mode = 1; + memcpy(kickmem_bank.baseaddr, a1000_bootrom, ROM_SIZE_256); + kickstart_version = 0; + } + if (kickstart_version == 0xffff) + kickstart_version = 0; +} + +void a1000_reset(void) +{ + a1000_handle_kickstart(1); +} + +static void REGPARAM3 kickmem_lput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 kickmem_wput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 kickmem_bput(uaecptr, uae_u32) REGPARAM; MEMORY_BGET(kickmem); MEMORY_WGET(kickmem); @@ -255,25 +690,98 @@ MEMORY_LGET(kickmem); MEMORY_CHECK(kickmem); MEMORY_XLATE(kickmem); -static void REGPARAM2 kickmem_lput (uaecptr addr, uae_u32 b) +static void REGPARAM2 kickmem_lput(uaecptr addr, uae_u32 b) { -#ifdef JIT - special_mem |= S_WRITE; + uae_u32 *m; + if (currprefs.rom_readwrite && rom_write_enabled) { + addr &= kickmem_bank.mask; + m = (uae_u32 *)(kickmem_bank.baseaddr + addr); + do_put_mem_long(m, b); +#if 0 + if (addr == ROM_SIZE_512 - 4) { + rom_write_enabled = false; + write_log(_T("ROM write disabled\n")); + } #endif + } + else if (a1000_kickstart_mode) { + if (addr >= 0xfc0000) { + addr &= kickmem_bank.mask; + m = (uae_u32 *)(kickmem_bank.baseaddr + addr); + do_put_mem_long(m, b); + return; + } + else + a1000_handle_kickstart(0); + } + else if (currprefs.illegal_mem) { + write_log(_T("Illegal kickmem lput at %08x\n"), addr); + } } -static void REGPARAM2 kickmem_wput (uaecptr addr, uae_u32 b) +static void REGPARAM2 kickmem_wput(uaecptr addr, uae_u32 b) { -#ifdef JIT - special_mem |= S_WRITE; -#endif + uae_u16 *m; + if (currprefs.rom_readwrite && rom_write_enabled) { + addr &= kickmem_bank.mask; + m = (uae_u16 *)(kickmem_bank.baseaddr + addr); + do_put_mem_word(m, b); + } + else if (a1000_kickstart_mode) { + if (addr >= 0xfc0000) { + addr &= kickmem_bank.mask; + m = (uae_u16 *)(kickmem_bank.baseaddr + addr); + do_put_mem_word(m, b); + return; + } + else + a1000_handle_kickstart(0); + } + else if (currprefs.illegal_mem) { + write_log(_T("Illegal kickmem wput at %08x\n"), addr); + } } -static void REGPARAM2 kickmem_bput (uaecptr addr, uae_u32 b) +static void REGPARAM2 kickmem_bput(uaecptr addr, uae_u32 b) { -#ifdef JIT - special_mem |= S_WRITE; -#endif + if (currprefs.rom_readwrite && rom_write_enabled) { + addr &= kickmem_bank.mask; + kickmem_bank.baseaddr[addr] = b; + } + else if (a1000_kickstart_mode) { + if (addr >= 0xfc0000) { + addr &= kickmem_bank.mask; + kickmem_bank.baseaddr[addr] = b; + return; + } + else + a1000_handle_kickstart(0); + } + else if (currprefs.illegal_mem) { + write_log(_T("Illegal kickmem bput at %08x\n"), addr); + } +} + +static void REGPARAM2 kickmem2_lput(uaecptr addr, uae_u32 l) +{ + uae_u32 *m; + addr &= kickmem_bank.mask; + m = (uae_u32 *)(kickmem_bank.baseaddr + addr); + do_put_mem_long(m, l); +} + +static void REGPARAM2 kickmem2_wput(uaecptr addr, uae_u32 w) +{ + uae_u16 *m; + addr &= kickmem_bank.mask; + m = (uae_u16 *)(kickmem_bank.baseaddr + addr); + do_put_mem_word(m, w); +} + +static void REGPARAM2 kickmem2_bput(uaecptr addr, uae_u32 b) +{ + addr &= kickmem_bank.mask; + kickmem_bank.baseaddr[addr] = b; } /* CD32/CDTV extended kick memory */ @@ -284,10 +792,11 @@ static int extendedkickmem_type; #define EXTENDED_ROM_CDTV 2 #define EXTENDED_ROM_KS 3 #define EXTENDED_ROM_ARCADIA 4 +#define EXTENDED_ROM_ALG 5 -static void REGPARAM3 extendedkickmem_lput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 extendedkickmem_wput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 extendedkickmem_bput (uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 extendedkickmem_lput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 extendedkickmem_wput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 extendedkickmem_bput(uaecptr, uae_u32) REGPARAM; MEMORY_BGET(extendedkickmem); MEMORY_WGET(extendedkickmem); @@ -295,29 +804,26 @@ MEMORY_LGET(extendedkickmem); MEMORY_CHECK(extendedkickmem); MEMORY_XLATE(extendedkickmem); -static void REGPARAM2 extendedkickmem_lput (uaecptr addr, uae_u32 b) +static void REGPARAM2 extendedkickmem_lput(uaecptr addr, uae_u32 b) { -#ifdef JIT - special_mem |= S_WRITE; -#endif + if (currprefs.illegal_mem) + write_log(_T("Illegal extendedkickmem lput at %08x\n"), addr); } -static void REGPARAM2 extendedkickmem_wput (uaecptr addr, uae_u32 b) +static void REGPARAM2 extendedkickmem_wput(uaecptr addr, uae_u32 b) { -#ifdef JIT - special_mem |= S_WRITE; -#endif + if (currprefs.illegal_mem) + write_log(_T("Illegal extendedkickmem wput at %08x\n"), addr); } -static void REGPARAM2 extendedkickmem_bput (uaecptr addr, uae_u32 b) +static void REGPARAM2 extendedkickmem_bput(uaecptr addr, uae_u32 b) { -#ifdef JIT - special_mem |= S_WRITE; -#endif + if (currprefs.illegal_mem) + write_log(_T("Illegal extendedkickmem lput at %08x\n"), addr); } -static void REGPARAM3 extendedkickmem2_lput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 extendedkickmem2_wput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM3 extendedkickmem2_bput (uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 extendedkickmem2_lput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 extendedkickmem2_wput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 extendedkickmem2_bput(uaecptr, uae_u32) REGPARAM; MEMORY_BGET(extendedkickmem2); MEMORY_WGET(extendedkickmem2); @@ -325,805 +831,2109 @@ MEMORY_LGET(extendedkickmem2); MEMORY_CHECK(extendedkickmem2); MEMORY_XLATE(extendedkickmem2); -static void REGPARAM2 extendedkickmem2_lput (uaecptr addr, uae_u32 b) +static void REGPARAM2 extendedkickmem2_lput(uaecptr addr, uae_u32 b) { -#ifdef JIT - special_mem |= S_WRITE; -#endif + if (currprefs.illegal_mem) + write_log(_T("Illegal extendedkickmem2 lput at %08x\n"), addr); } -static void REGPARAM2 extendedkickmem2_wput (uaecptr addr, uae_u32 b) +static void REGPARAM2 extendedkickmem2_wput(uaecptr addr, uae_u32 b) { -#ifdef JIT - special_mem |= S_WRITE; -#endif + if (currprefs.illegal_mem) + write_log(_T("Illegal extendedkickmem2 wput at %08x\n"), addr); } -static void REGPARAM2 extendedkickmem2_bput (uaecptr addr, uae_u32 b) +static void REGPARAM2 extendedkickmem2_bput(uaecptr addr, uae_u32 b) { -#ifdef JIT - special_mem |= S_WRITE; -#endif + if (currprefs.illegal_mem) + write_log(_T("Illegal extendedkickmem2 lput at %08x\n"), addr); } /* Default memory access functions */ -int REGPARAM2 default_check (uaecptr a, uae_u32 b) +int REGPARAM2 default_check(uaecptr a, uae_u32 b) { - return 0; + return 0; } static int be_cnt; -uae_u8 *REGPARAM2 default_xlate (uaecptr a) +uae_u8 *REGPARAM2 default_xlate(uaecptr addr) { - if (quit_program == 0) { - /* do this only in 68010+ mode, there are some tricky A500 programs.. */ - if(currprefs.cpu_model > 68000 || !currprefs.cpu_compatible) { + static int recursive; + + if (recursive) { + cpu_halt(3); + return kickmem_xlate(2); + } + recursive++; + int size = currprefs.cpu_model >= 68020 ? 4 : 2; + + if (quit_program == 0) { + /* do this only in 68010+ mode, there are some tricky A500 programs.. */ + if (currprefs.cpu_model > 68000 || !currprefs.cpu_compatible) { if (be_cnt < 3) { - write_log (_T("Your Amiga program just did something terribly stupid %08X PC=%08X\n"), a, M68K_GETPC); - } + int i, j; + uaecptr a2 = addr - 32; + uaecptr a3 = m68k_getpc() - 32; + write_log(_T("Your Amiga program just did something terribly stupid %08X PC=%08X\n"), addr, M68K_GETPC); + } be_cnt++; if (regs.s || be_cnt > 1000) { - cpu_halt (3); + cpu_halt(3); be_cnt = 0; - } else { - regs.panic = 4; - regs.panic_pc = m68k_getpc (); - regs.panic_addr = a; - set_special (SPCFLAG_BRK); } - } - } - return kickmem_xlate (2); /* So we don't crash. */ + else { + regs.panic = 4; + regs.panic_pc = m68k_getpc(); + regs.panic_addr = addr; + set_special(SPCFLAG_BRK); + } + } + } + recursive--; + return kickmem_xlate(2); /* So we don't crash. */ } /* Address banks */ addrbank dummy_bank = { - dummy_lget, dummy_wget, dummy_bget, - dummy_lput, dummy_wput, dummy_bput, - default_xlate, dummy_check, NULL, NULL, - dummy_lgeti, dummy_wgeti, ABFLAG_NONE + dummy_lget, dummy_wget, dummy_bget, + dummy_lput, dummy_wput, dummy_bput, + default_xlate, dummy_check, NULL, NULL, NULL, + dummy_lgeti, dummy_wgeti, + ABFLAG_NONE, S_READ, S_WRITE +}; + +addrbank ones_bank = { + ones_get, ones_get, ones_get, + none_put, none_put, none_put, + default_xlate, dummy_check, NULL, NULL, _T("Ones"), + dummy_lgeti, dummy_wgeti, + ABFLAG_NONE, S_READ, S_WRITE }; addrbank chipmem_bank = { - chipmem_lget, chipmem_wget, chipmem_bget, - chipmem_lput, chipmem_wput, chipmem_bput, - chipmem_xlate, chipmem_check, NULL, _T("Chip memory"), - chipmem_lget, chipmem_wget, ABFLAG_RAM + chipmem_lget, chipmem_wget, chipmem_bget, + chipmem_lput, chipmem_wput, chipmem_bput, + chipmem_xlate, chipmem_check, NULL, _T("chip"), _T("Chip memory"), + chipmem_lget, chipmem_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_CHIPRAM, 0, 0 }; +addrbank chipmem_dummy_bank = { + chipmem_dummy_lget, chipmem_dummy_wget, chipmem_dummy_bget, + chipmem_dummy_lput, chipmem_dummy_wput, chipmem_dummy_bput, + default_xlate, dummy_check, NULL, NULL, _T("Dummy Chip memory"), + dummy_lgeti, dummy_wgeti, + ABFLAG_IO | ABFLAG_CHIPRAM, S_READ, S_WRITE +}; + +#ifdef AGA +addrbank chipmem_bank_ce2 = { + chipmem_lget_ce2, chipmem_wget_ce2, chipmem_bget_ce2, + chipmem_lput_ce2, chipmem_wput_ce2, chipmem_bput_ce2, + chipmem_xlate, chipmem_check, NULL, NULL, _T("Chip memory (68020 'ce')"), + chipmem_lget_ce2, chipmem_wget_ce2, + ABFLAG_RAM | ABFLAG_CHIPRAM, S_READ, S_WRITE +}; +#endif + addrbank bogomem_bank = { - bogomem_lget, bogomem_wget, bogomem_bget, - bogomem_lput, bogomem_wput, bogomem_bput, - bogomem_xlate, bogomem_check, NULL, _T("Slow memory"), - bogomem_lget, bogomem_wget, ABFLAG_RAM + bogomem_lget, bogomem_wget, bogomem_bget, + bogomem_lput, bogomem_wput, bogomem_bput, + bogomem_xlate, bogomem_check, NULL, _T("bogo"), _T("Slow memory"), + bogomem_lget, bogomem_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 +}; + +addrbank cardmem_bank = { + cardmem_lget, cardmem_wget, cardmem_bget, + cardmem_lput, cardmem_wput, cardmem_bput, + cardmem_xlate, cardmem_check, NULL, _T("rom_e0"), _T("CDTV memory card"), + cardmem_lget, cardmem_wget, + ABFLAG_RAM, 0, 0 +}; + +addrbank mem25bit_bank = { + mem25bit_lget, mem25bit_wget, mem25bit_bget, + mem25bit_lput, mem25bit_wput, mem25bit_bput, + mem25bit_xlate, mem25bit_check, NULL, _T("25bitmem"), _T("25bit memory"), + mem25bit_lget, mem25bit_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 +}; + +addrbank a3000lmem_bank = { + a3000lmem_lget, a3000lmem_wget, a3000lmem_bget, + a3000lmem_lput, a3000lmem_wput, a3000lmem_bput, + a3000lmem_xlate, a3000lmem_check, NULL, _T("ramsey_low"), _T("RAMSEY memory (low)"), + a3000lmem_lget, a3000lmem_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 +}; + +addrbank a3000hmem_bank = { + a3000hmem_lget, a3000hmem_wget, a3000hmem_bget, + a3000hmem_lput, a3000hmem_wput, a3000hmem_bput, + a3000hmem_xlate, a3000hmem_check, NULL, _T("ramsey_high"), _T("RAMSEY memory (high)"), + a3000hmem_lget, a3000hmem_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 }; addrbank kickmem_bank = { - kickmem_lget, kickmem_wget, kickmem_bget, - kickmem_lput, kickmem_wput, kickmem_bput, - kickmem_xlate, kickmem_check, NULL, _T("Kickstart ROM"), - kickmem_lget, kickmem_wget, ABFLAG_ROM + kickmem_lget, kickmem_wget, kickmem_bget, + kickmem_lput, kickmem_wput, kickmem_bput, + kickmem_xlate, kickmem_check, NULL, _T("kick"), _T("Kickstart ROM"), + kickmem_lget, kickmem_wget, + ABFLAG_ROM | ABFLAG_THREADSAFE, 0, S_WRITE +}; + +addrbank kickram_bank = { + kickmem_lget, kickmem_wget, kickmem_bget, + kickmem2_lput, kickmem2_wput, kickmem2_bput, + kickmem_xlate, kickmem_check, NULL, NULL, _T("Kickstart Shadow RAM"), + kickmem_lget, kickmem_wget, + ABFLAG_UNK | ABFLAG_SAFE, 0, S_WRITE }; addrbank extendedkickmem_bank = { - extendedkickmem_lget, extendedkickmem_wget, extendedkickmem_bget, - extendedkickmem_lput, extendedkickmem_wput, extendedkickmem_bput, - extendedkickmem_xlate, extendedkickmem_check, NULL, _T("Extended Kickstart ROM"), - extendedkickmem_lget, extendedkickmem_wget, ABFLAG_ROM + extendedkickmem_lget, extendedkickmem_wget, extendedkickmem_bget, + extendedkickmem_lput, extendedkickmem_wput, extendedkickmem_bput, + extendedkickmem_xlate, extendedkickmem_check, NULL, NULL, _T("Extended Kickstart ROM"), + extendedkickmem_lget, extendedkickmem_wget, + ABFLAG_ROM | ABFLAG_THREADSAFE, 0, S_WRITE }; addrbank extendedkickmem2_bank = { - extendedkickmem2_lget, extendedkickmem2_wget, extendedkickmem2_bget, - extendedkickmem2_lput, extendedkickmem2_wput, extendedkickmem2_bput, - extendedkickmem2_xlate, extendedkickmem2_check, NULL, _T("Extended 2nd Kickstart ROM"), - extendedkickmem2_lget, extendedkickmem2_wget, ABFLAG_ROM + extendedkickmem2_lget, extendedkickmem2_wget, extendedkickmem2_bget, + extendedkickmem2_lput, extendedkickmem2_wput, extendedkickmem2_bput, + extendedkickmem2_xlate, extendedkickmem2_check, NULL, _T("rom_a8"), _T("Extended 2nd Kickstart ROM"), + extendedkickmem2_lget, extendedkickmem2_wget, + ABFLAG_ROM | ABFLAG_THREADSAFE, 0, S_WRITE }; +MEMORY_FUNCTIONS(custmem1); +MEMORY_FUNCTIONS(custmem2); -static const char *kickstring = "exec.library"; -static int read_kickstart (struct zfile *f, uae_u8 *mem, int size, int dochecksum, int noalias) +addrbank custmem1_bank = { + custmem1_lget, custmem1_wget, custmem1_bget, + custmem1_lput, custmem1_wput, custmem1_bput, + custmem1_xlate, custmem1_check, NULL, _T("custmem1"), _T("Non-autoconfig RAM #1"), + custmem1_lget, custmem1_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 +}; +addrbank custmem2_bank = { + custmem2_lget, custmem2_wget, custmem2_bget, + custmem2_lput, custmem2_wput, custmem2_bput, + custmem2_xlate, custmem2_check, NULL, _T("custmem2"), _T("Non-autoconfig RAM #2"), + custmem2_lget, custmem2_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 +}; + +#define fkickmem_size ROM_SIZE_512 +static int a3000_f0; +void a3000_fakekick(int map) { - uae_char buffer[20]; - int i, j, oldpos; - int cr = 0, kickdisk = 0; + static uae_u8 *kickstore; - if (size < 0) { - zfile_fseek (f, 0, SEEK_END); - size = zfile_ftell (f) & ~0x3ff; - zfile_fseek (f, 0, SEEK_SET); - } - oldpos = zfile_ftell (f); - i = zfile_fread (buffer, 1, 11, f); - if (!memcmp(buffer, "KICK", 4)) { - zfile_fseek (f, 512, SEEK_SET); - kickdisk = 1; -#if 0 - } else if (size >= ROM_SIZE_512 && !memcmp (buffer, "AMIG", 4)) { - /* ReKick */ - zfile_fseek (f, oldpos + 0x6c, SEEK_SET); - cr = 2; -#endif - } else if (memcmp ((uae_char*)buffer, "AMIROMTYPE1", 11) != 0) { - zfile_fseek (f, oldpos, SEEK_SET); - } else { - cloanto_rom = 1; - cr = 1; - } - - memset (mem, 0, size); - for (i = 0; i < 8; i++) - mem[size - 16 + i * 2 + 1] = 0x18 + i; - mem[size - 20] = size >> 24; - mem[size - 19] = size >> 16; - mem[size - 18] = size >> 8; - mem[size - 17] = size >> 0; - - i = zfile_fread (mem, 1, size, f); - - if (kickdisk && i > ROM_SIZE_256) - i = ROM_SIZE_256; -#if 0 - if (i >= ROM_SIZE_256 && (i != ROM_SIZE_256 && i != ROM_SIZE_512 && i != ROM_SIZE_512 * 2 && i != ROM_SIZE_512 * 4)) { - notify_user (NUMSG_KSROMREADERROR); - return 0; - } -#endif - if (i < size - 20) - kickstart_fix_checksum (mem, size); - - j = 1; - while (j < i) - j <<= 1; - i = j; - - if (!noalias && i == size / 2) - memcpy (mem + size / 2, mem, size / 2); - - if (cr) { - if(!decode_rom (mem, size, cr, i)) - return 0; - } - - for (j = 0; j < 256 && i >= ROM_SIZE_256; j++) { - if (!memcmp (mem + j, kickstring, strlen (kickstring) + 1)) - break; - } - - if (j == 256 || i < ROM_SIZE_256) - dochecksum = 0; - if (dochecksum) - kickstart_checksum (mem, size); - return i; + protect_roms(false); + if (map) { + uae_u8 *fkickmemory = a3000lmem_bank.baseaddr + a3000lmem_bank.reserved_size - fkickmem_size; + if (fkickmemory[2] == 0x4e && fkickmemory[3] == 0xf9 && fkickmemory[4] == 0x00) { + if (!kickstore) + kickstore = xmalloc(uae_u8, fkickmem_size); + memcpy(kickstore, kickmem_bank.baseaddr, fkickmem_size); + if (fkickmemory[5] == 0xfc) { + memcpy(kickmem_bank.baseaddr, fkickmemory, fkickmem_size / 2); + memcpy(kickmem_bank.baseaddr + fkickmem_size / 2, fkickmemory, fkickmem_size / 2); + extendedkickmem_bank.reserved_size = 65536; + extendedkickmem_bank.label = _T("rom_f0"); + extendedkickmem_bank.mask = extendedkickmem_bank.reserved_size - 1; + mapped_malloc(&extendedkickmem_bank); + memcpy(extendedkickmem_bank.baseaddr, fkickmemory + fkickmem_size / 2, 65536); + map_banks(&extendedkickmem_bank, 0xf0, 1, 1); + a3000_f0 = 1; + } + else { + memcpy(kickmem_bank.baseaddr, fkickmemory, fkickmem_size); + } + } + } + else { + if (a3000_f0) { + map_banks(&dummy_bank, 0xf0, 1, 1); + mapped_free(&extendedkickmem_bank); + a3000_f0 = 0; + } + if (kickstore) + memcpy(kickmem_bank.baseaddr, kickstore, fkickmem_size); + xfree(kickstore); + kickstore = NULL; + } + protect_roms(true); } -static bool load_extendedkickstart (const TCHAR *romextfile, int type) +static bool is_alg_rom(const TCHAR *name) { - struct zfile *f; - int size, off; + struct romdata *rd = getromdatabypath(name); + if (!rd) + return false; + return (rd->type & ROMTYPE_ALG) != 0; +} + +static void descramble_alg(uae_u8 *data, int size) +{ + uae_u8 *tbuf = xmalloc(uae_u8, size); + memcpy(tbuf, data, size); + for (int mode = 0; mode < 3; mode++) { + if ((data[8] == 0x4a && data[9] == 0xfc)) + break; + for (int s = 0; s < size; s++) { + int d = s; + if (mode == 0) { + if (s & 0x2000) + d ^= 0x1000; + if (s & 0x8000) + d ^= 0x4000; + } + else if (mode == 1) { + if (s & 0x2000) + d ^= 0x1000; + } + else { + if ((~s) & 0x2000) + d ^= 0x1000; + if (s & 0x8000) + d ^= 0x4000; + d ^= 0x20000; + } + data[d] = tbuf[s]; + } + } + xfree(tbuf); +} + +static const char *kickstring = "exec.library"; + +static int read_kickstart(struct zfile *f, uae_u8 *mem, int size, int dochecksum, int noalias) +{ + uae_char buffer[20]; + int i, j, oldpos; + int cr = 0, kickdisk = 0; + + if (size < 0) { + zfile_fseek(f, 0, SEEK_END); + size = zfile_ftell(f) & ~0x3ff; + zfile_fseek(f, 0, SEEK_SET); + } + oldpos = zfile_ftell(f); + i = zfile_fread(buffer, 1, 11, f); + if (!memcmp(buffer, "KICK", 4)) { + zfile_fseek(f, 512, SEEK_SET); + kickdisk = 1; + } + else if (memcmp(static_cast(buffer), "AMIROMTYPE1", 11) != 0) { + zfile_fseek(f, oldpos, SEEK_SET); + } + else { + cloanto_rom = 1; + cr = 1; + } + + memset(mem, 0, size); + if (size >= 131072) { + for (i = 0; i < 8; i++) { + mem[size - 16 + i * 2 + 1] = 0x18 + i; + } + mem[size - 20] = size >> 24; + mem[size - 19] = size >> 16; + mem[size - 18] = size >> 8; + mem[size - 17] = size >> 0; + } + + i = zfile_fread(mem, 1, size, f); + + if (kickdisk && i > ROM_SIZE_256) + i = ROM_SIZE_256; + + if (i < size - 20) + kickstart_fix_checksum(mem, size); + j = 1; + while (j < i) + j <<= 1; + i = j; + + if (!noalias && i == size / 2) + memcpy(mem + size / 2, mem, size / 2); + + if (cr) { + if (!decode_rom(mem, size, cr, i)) + return 0; + } + + if (size <= 256) + return size; + + if (currprefs.cs_a1000ram && i < ROM_SIZE_256) { + int off = 0; + if (!a1000_bootrom) + a1000_bootrom = xcalloc(uae_u8, ROM_SIZE_256); + while (off + i < ROM_SIZE_256) { + memcpy(a1000_bootrom + off, kickmem_bank.baseaddr, i); + off += i; + } + memset(kickmem_bank.baseaddr, 0, kickmem_bank.allocated_size); + a1000_handle_kickstart(1); + dochecksum = 0; + i = ROM_SIZE_512; + } + + for (j = 0; j < 256 && i >= ROM_SIZE_256; j++) { + if (!memcmp(mem + j, kickstring, strlen(kickstring) + 1)) + break; + } + + if (j == 256 || i < ROM_SIZE_256) + dochecksum = 0; + if (dochecksum) + kickstart_checksum(mem, size); + return i; +} + +static bool load_extendedkickstart(const TCHAR *romextfile, int type) +{ + struct zfile *f; + int size, off; bool ret = false; - if (_tcslen (romextfile) == 0) - return false; - f = read_rom_name (romextfile); - if (!f) { - notify_user (NUMSG_NOEXTROM); - return false; - } - zfile_fseek (f, 0, SEEK_END); - size = zfile_ftell (f); - extendedkickmem_bank.allocated = ROM_SIZE_512; - off = 0; + if (_tcslen(romextfile) == 0) + return false; + //if (is_arcadia_rom(romextfile) == ARCADIA_BIOS) { + // extendedkickmem_type = EXTENDED_ROM_ARCADIA; + // return false; + //} + if (is_alg_rom(romextfile)) { + type = EXTENDED_ROM_ALG; + + } + f = read_rom_name(romextfile); + if (!f) { + notify_user(NUMSG_NOEXTROM); + return false; + } + zfile_fseek(f, 0, SEEK_END); + size = zfile_ftell(f); + extendedkickmem_bank.reserved_size = ROM_SIZE_512; + off = 0; if (type == 0) { if (currprefs.cs_cd32cd) { extendedkickmem_type = EXTENDED_ROM_CD32; - } else if (size > 300000) { - extendedkickmem_type = EXTENDED_ROM_CD32; - } else if (need_uae_boot_rom () != 0xf00000) { - extendedkickmem_type = EXTENDED_ROM_CDTV; - } - } else { + } + else if (currprefs.cs_cdtvcd || currprefs.cs_cdtvram) { + extendedkickmem_type = EXTENDED_ROM_CDTV; + } + else if (size > 300000) { + extendedkickmem_type = EXTENDED_ROM_CD32; + } + else if (need_uae_boot_rom(&currprefs) != 0xf00000) { + extendedkickmem_type = EXTENDED_ROM_CDTV; + } + } + else { extendedkickmem_type = type; } if (extendedkickmem_type) { - zfile_fseek (f, off, SEEK_SET); - switch (extendedkickmem_type) { - case EXTENDED_ROM_CDTV: - extendedkickmem_bank.baseaddr = mapped_malloc (extendedkickmem_bank.allocated, _T("rom_f0")); - extendedkickmem_bank.start = 0xf00000; - break; - case EXTENDED_ROM_CD32: - extendedkickmem_bank.baseaddr = mapped_malloc (extendedkickmem_bank.allocated, _T("rom_e0")); - extendedkickmem_bank.start = 0xe00000; - break; - } + zfile_fseek(f, off, SEEK_SET); + switch (extendedkickmem_type) { + case EXTENDED_ROM_CDTV: + extendedkickmem_bank.label = _T("rom_f0"); + mapped_malloc(&extendedkickmem_bank); + extendedkickmem_bank.start = 0xf00000; + break; + case EXTENDED_ROM_CD32: + extendedkickmem_bank.label = _T("rom_e0"); + mapped_malloc(&extendedkickmem_bank); + extendedkickmem_bank.start = 0xe00000; + break; + case EXTENDED_ROM_ALG: + extendedkickmem_bank.label = _T("rom_f0"); + mapped_malloc(&extendedkickmem_bank); + extendedkickmem_bank.start = 0xf00000; + break; + } if (extendedkickmem_bank.baseaddr) { - read_kickstart (f, extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated, 0, 1); - extendedkickmem_bank.mask = extendedkickmem_bank.allocated - 1; + read_kickstart(f, extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated_size, 0, 1); + if (extendedkickmem_type == EXTENDED_ROM_ALG) + descramble_alg(extendedkickmem_bank.baseaddr, 262144); + extendedkickmem_bank.mask = extendedkickmem_bank.allocated_size - 1; ret = true; } } - zfile_fclose (f); - return ret; + zfile_fclose(f); + return ret; +} + +static int patch_shapeshifter(uae_u8 *kickmemory) +{ + /* Patch Kickstart ROM for ShapeShifter - from Christian Bauer. + * Changes 'lea $400,a0' and 'lea $1000,a0' to 'lea $3000,a0' for + * ShapeShifter compatability. + */ + int i, patched = 0; + uae_u8 kickshift1[] = { 0x41, 0xf8, 0x04, 0x00 }; + uae_u8 kickshift2[] = { 0x41, 0xf8, 0x10, 0x00 }; + uae_u8 kickshift3[] = { 0x43, 0xf8, 0x04, 0x00 }; + + for (i = 0x200; i < 0x300; i++) { + if (!memcmp(kickmemory + i, kickshift1, sizeof(kickshift1)) || + !memcmp(kickmemory + i, kickshift2, sizeof(kickshift2)) || + !memcmp(kickmemory + i, kickshift3, sizeof(kickshift3))) { + kickmemory[i + 2] = 0x30; + write_log(_T("Kickstart KickShifted @%04X\n"), i); + patched++; + } + } + return patched; } /* disable incompatible drivers */ -static int patch_residents (uae_u8 *kickmemory, int size) +static int patch_residents(uae_u8 *kickmemory, int size) { - int i, j, patched = 0; - const char *residents[] = { "NCR scsi.device", "scsi.device", "carddisk.device", "card.resource", 0 }; - // "scsi.device", "carddisk.device", "card.resource" }; - uaecptr base = size == ROM_SIZE_512 ? 0xf80000 : 0xfc0000; + int i, j, patched = 0; + const uae_char *residents[] = { "NCR scsi.device", NULL }; + // "scsi.device", "carddisk.device", "card.resource" }; + uaecptr base = size == ROM_SIZE_512 ? 0xf80000 : 0xfc0000; - for (i = 0; i < size - 100; i++) { - if (kickmemory[i] == 0x4a && kickmemory[i + 1] == 0xfc) { - uaecptr addr; - addr = (kickmemory[i + 2] << 24) | (kickmemory[i + 3] << 16) | (kickmemory[i + 4] << 8) | (kickmemory[i + 5] << 0); - if (addr != i + base) - continue; - addr = (kickmemory[i + 14] << 24) | (kickmemory[i + 15] << 16) | (kickmemory[i + 16] << 8) | (kickmemory[i + 17] << 0); - if (addr >= base && addr < base + size) { - j = 0; - while (residents[j]) { - if (!memcmp (residents[j], kickmemory + addr - base, strlen (residents[j]) + 1)) { - TCHAR *s = au (residents[j]); - write_log (_T("KSPatcher: '%s' at %08X disabled\n"), s, i + base); - xfree (s); - kickmemory[i] = 0x4b; /* destroy RTC_MATCHWORD */ - patched++; - break; - } - j++; - } - } - } - } - return patched; + if (is_device_rom(&currprefs, ROMTYPE_SCSI_A4000T, 0) < 0) { + for (i = 0; i < size - 100; i++) { + if (kickmemory[i] == 0x4a && kickmemory[i + 1] == 0xfc) { + uaecptr addr; + addr = (kickmemory[i + 2] << 24) | (kickmemory[i + 3] << 16) | (kickmemory[i + 4] << 8) | (kickmemory[i + 5] << 0); + if (addr != i + base) + continue; + addr = (kickmemory[i + 14] << 24) | (kickmemory[i + 15] << 16) | (kickmemory[i + 16] << 8) | (kickmemory[i + 17] << 0); + if (addr >= base && addr < base + size) { + j = 0; + while (residents[j]) { + if (!memcmp(residents[j], kickmemory + addr - base, strlen(residents[j]) + 1)) { + TCHAR *s = au(residents[j]); + write_log(_T("KSPatcher: '%s' at %08X disabled\n"), s, i + base); + xfree(s); + kickmemory[i] = 0x4b; /* destroy RTC_MATCHWORD */ + patched++; + break; + } + j++; + } + } + } + } + } + return patched; } static void patch_kick(void) { - int patched = 0; - patched += patch_residents (kickmem_bank.baseaddr, kickmem_bank.allocated); - if (extendedkickmem_bank.baseaddr) { - patched += patch_residents (extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated); - if (patched) - kickstart_fix_checksum (extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated); - } - if (patched) - kickstart_fix_checksum (kickmem_bank.baseaddr, kickmem_bank.allocated); + int patched = 0; + if (kickmem_bank.allocated_size >= ROM_SIZE_512 && currprefs.kickshifter) + patched += patch_shapeshifter(kickmem_bank.baseaddr); + patched += patch_residents(kickmem_bank.baseaddr, kickmem_bank.allocated_size); + if (extendedkickmem_bank.baseaddr) { + patched += patch_residents(extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated_size); + if (patched) + kickstart_fix_checksum(extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated_size); + } + if (patched) + kickstart_fix_checksum(kickmem_bank.baseaddr, kickmem_bank.allocated_size); } extern unsigned char arosrom[]; extern unsigned int arosrom_len; -static bool load_kickstart_replacement (void) +static bool load_kickstart_replacement(void) { struct zfile *f; - - f = zfile_fopen_data (_T("aros.gz"), arosrom_len, arosrom); + f = zfile_fopen_data(_T("aros.gz"), arosrom_len, arosrom); if (!f) return false; - f = zfile_gunzip (f); + f = zfile_gunzip(f); if (!f) return false; - extendedkickmem_bank.allocated = ROM_SIZE_512; + extendedkickmem_bank.reserved_size = ROM_SIZE_512; extendedkickmem_bank.mask = ROM_SIZE_512 - 1; + extendedkickmem_bank.label = _T("rom_e0"); extendedkickmem_type = EXTENDED_ROM_KS; - extendedkickmem_bank.baseaddr = mapped_malloc (extendedkickmem_bank.allocated, _T("rom_e0")); - read_kickstart (f, extendedkickmem_bank.baseaddr, ROM_SIZE_512, 0, 1); + mapped_malloc(&extendedkickmem_bank); + read_kickstart(f, extendedkickmem_bank.baseaddr, ROM_SIZE_512, 0, 1); - kickmem_bank.allocated = ROM_SIZE_512; + + kickmem_bank.reserved_size = ROM_SIZE_512; kickmem_bank.mask = ROM_SIZE_512 - 1; - read_kickstart (f, kickmem_bank.baseaddr, ROM_SIZE_512, 1, 0); - zfile_fclose (f); + read_kickstart(f, kickmem_bank.baseaddr, ROM_SIZE_512, 1, 0); + + zfile_fclose(f); + + //seriallog = -1; + + // if 68000-68020 config without any other fast ram with m68k aros: enable special extra RAM. + if (currprefs.cpu_model <= 68020 && + currprefs.cachesize == 0 && + currprefs.fastmem[0].size == 0 && + currprefs.z3fastmem[0].size == 0 && + currprefs.mbresmem_high_size == 0 && + currprefs.mbresmem_low_size == 0 && + currprefs.cpuboardmem1_size == 0) { + + changed_prefs.custom_memory_addrs[0] = currprefs.custom_memory_addrs[0] = 0xa80000; + changed_prefs.custom_memory_sizes[0] = currprefs.custom_memory_sizes[0] = 512 * 1024; + changed_prefs.custom_memory_mask[0] = currprefs.custom_memory_mask[0] = 0; + changed_prefs.custom_memory_addrs[1] = currprefs.custom_memory_addrs[1] = 0xb00000; + changed_prefs.custom_memory_sizes[1] = currprefs.custom_memory_sizes[1] = 512 * 1024; + changed_prefs.custom_memory_mask[1] = currprefs.custom_memory_mask[1] = 0; + + } + return true; } -static int load_kickstart (void) +static struct zfile *get_kickstart_filehandle(struct uae_prefs *p) { - struct zfile *f; - TCHAR tmprom[MAX_DPATH], tmprom2[MAX_DPATH]; - int patched = 0; + struct zfile *f; + TCHAR tmprom[MAX_DPATH], tmprom2[MAX_DPATH]; - cloanto_rom = 0; - if (!_tcscmp (currprefs.romfile, _T(":AROS"))) - return load_kickstart_replacement (); - f = read_rom_name (currprefs.romfile); - _tcscpy (tmprom, currprefs.romfile); - if (f == NULL) { - _stprintf (tmprom2, _T("%s%s"), start_path_data, currprefs.romfile); - f = rom_fopen (tmprom2, _T("rb"), ZFD_NORMAL); - if (f == NULL) { - _stprintf (currprefs.romfile, _T("%sroms/kick.rom"), start_path_data); - f = rom_fopen (currprefs.romfile, _T("rb"), ZFD_NORMAL); - if (f == NULL) { - _stprintf (currprefs.romfile, _T("%skick.rom"), start_path_data); - f = rom_fopen( currprefs.romfile, _T("rb"), ZFD_NORMAL); - if (f == NULL) - f = read_rom_name_guess (tmprom); - } - } else { - _tcscpy (currprefs.romfile, tmprom2); - } - } - addkeydir (currprefs.romfile); + f = read_rom_name(p->romfile); + _tcscpy(tmprom, p->romfile); + if (f == NULL) { + _stprintf(tmprom2, _T("%s%s"), start_path_data, p->romfile); + f = rom_fopen(tmprom2, _T("rb"), ZFD_NORMAL); + if (f == NULL) { + _stprintf(p->romfile, _T("%sroms/kick.rom"), start_path_data); + f = rom_fopen(p->romfile, _T("rb"), ZFD_NORMAL); + if (f == NULL) { + _stprintf(p->romfile, _T("%skick.rom"), start_path_data); + f = rom_fopen(p->romfile, _T("rb"), ZFD_NORMAL); + if (f == NULL) { + _stprintf(p->romfile, _T("%s../shared/rom/kick.rom"), start_path_data); + f = rom_fopen(p->romfile, _T("rb"), ZFD_NORMAL); + if (f == NULL) { + _stprintf(p->romfile, _T("%s../System/rom/kick.rom"), start_path_data); + f = rom_fopen(p->romfile, _T("rb"), ZFD_NORMAL); + if (f == NULL) + f = read_rom_name_guess(tmprom); + } + } + } + } + else { + _tcscpy(p->romfile, tmprom2); + } + } + return f; +} + +static int load_kickstart(void) +{ + TCHAR tmprom[MAX_DPATH]; + cloanto_rom = 0; + if (!_tcscmp(currprefs.romfile, _T(":AROS"))) { + return load_kickstart_replacement(); + } + _tcscpy(tmprom, currprefs.romfile); + struct zfile *f = get_kickstart_filehandle(&currprefs); + addkeydir(currprefs.romfile); if (f == NULL) /* still no luck */ - goto err; + goto err; - if (f != NULL) { - int filesize, size, maxsize; - int kspos = ROM_SIZE_512; - int extpos = 0; + if (f != NULL) { + int filesize, size, maxsize; + int kspos = ROM_SIZE_512; + int extpos = 0; - maxsize = ROM_SIZE_512; - zfile_fseek (f, 0, SEEK_END); - filesize = zfile_ftell (f); - zfile_fseek (f, 0, SEEK_SET); - if (filesize == 1760 * 512) { - filesize = ROM_SIZE_256; - maxsize = ROM_SIZE_256; - } - if (filesize == ROM_SIZE_512 + 8) { - /* GVP 0xf0 kickstart */ - zfile_fseek (f, 8, SEEK_SET); - } - if (filesize >= ROM_SIZE_512 * 2) { - struct romdata *rd = getromdatabyzfile(f); - zfile_fseek (f, kspos, SEEK_SET); - } - if (filesize >= ROM_SIZE_512 * 4) { - kspos = ROM_SIZE_512 * 3; - extpos = 0; - zfile_fseek (f, kspos, SEEK_SET); - } - size = read_kickstart (f, kickmem_bank.baseaddr, maxsize, 1, 0); - if (size == 0) - goto err; - kickmem_bank.mask = size - 1; - kickmem_bank.allocated = size; - if (filesize >= ROM_SIZE_512 * 2 && !extendedkickmem_type) { - extendedkickmem_bank.allocated = ROM_SIZE_512; - extendedkickmem_type = EXTENDED_ROM_KS; - extendedkickmem_bank.baseaddr = mapped_malloc (extendedkickmem_bank.allocated, _T("rom_e0")); - extendedkickmem_bank.start = 0xe00000; - zfile_fseek (f, extpos, SEEK_SET); - read_kickstart (f, extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated, 0, 1); - extendedkickmem_bank.mask = extendedkickmem_bank.allocated - 1; - } - if (filesize > ROM_SIZE_512 * 2) { - extendedkickmem2_bank.allocated = ROM_SIZE_512 * 2; - extendedkickmem2_bank.baseaddr = mapped_malloc (extendedkickmem2_bank.allocated, _T("rom_a8")); - zfile_fseek (f, extpos + ROM_SIZE_512, SEEK_SET); - read_kickstart (f, extendedkickmem2_bank.baseaddr, ROM_SIZE_512, 0, 1); - zfile_fseek (f, extpos + ROM_SIZE_512 * 2, SEEK_SET); - read_kickstart (f, extendedkickmem2_bank.baseaddr + ROM_SIZE_512, ROM_SIZE_512, 0, 1); - extendedkickmem2_bank.mask = extendedkickmem2_bank.allocated - 1; + maxsize = ROM_SIZE_512; + zfile_fseek(f, 0, SEEK_END); + filesize = zfile_ftell(f); + zfile_fseek(f, 0, SEEK_SET); + if (filesize == 1760 * 512) { + filesize = ROM_SIZE_256; + maxsize = ROM_SIZE_256; + } + if (filesize == ROM_SIZE_512 + 8) { + /* GVP 0xf0 kickstart */ + zfile_fseek(f, 8, SEEK_SET); + } + if (filesize >= ROM_SIZE_512 * 2) { + struct romdata *rd = getromdatabyzfile(f); + zfile_fseek(f, kspos, SEEK_SET); + } + if (filesize >= ROM_SIZE_512 * 4) { + kspos = ROM_SIZE_512 * 3; + extpos = 0; + zfile_fseek(f, kspos, SEEK_SET); + } + size = read_kickstart(f, kickmem_bank.baseaddr, maxsize, 1, 0); + if (size == 0) + goto err; + kickmem_bank.mask = size - 1; + kickmem_bank.reserved_size = size; + if (filesize >= ROM_SIZE_512 * 2 && !extendedkickmem_type) { + extendedkickmem_bank.reserved_size = ROM_SIZE_512; + if (currprefs.cs_cdtvcd || currprefs.cs_cdtvram) { + extendedkickmem_type = EXTENDED_ROM_CDTV; + extendedkickmem_bank.reserved_size *= 2; + extendedkickmem_bank.label = _T("rom_f0"); + extendedkickmem_bank.start = 0xf00000; + } + else { + extendedkickmem_type = EXTENDED_ROM_KS; + extendedkickmem_bank.label = _T("rom_e0"); + extendedkickmem_bank.start = 0xe00000; + } + mapped_malloc(&extendedkickmem_bank); + zfile_fseek(f, extpos, SEEK_SET); + read_kickstart(f, extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated_size, 0, 1); + extendedkickmem_bank.mask = extendedkickmem_bank.allocated_size - 1; + } + if (filesize > ROM_SIZE_512 * 2) { + extendedkickmem2_bank.reserved_size = ROM_SIZE_512 * 2; + mapped_malloc(&extendedkickmem2_bank); + zfile_fseek(f, extpos + ROM_SIZE_512, SEEK_SET); + read_kickstart(f, extendedkickmem2_bank.baseaddr, ROM_SIZE_512, 0, 1); + zfile_fseek(f, extpos + ROM_SIZE_512 * 2, SEEK_SET); + read_kickstart(f, extendedkickmem2_bank.baseaddr + ROM_SIZE_512, ROM_SIZE_512, 0, 1); + extendedkickmem2_bank.mask = extendedkickmem2_bank.allocated_size - 1; extendedkickmem2_bank.start = 0xa80000; - } - } + } + } - kickstart_version = (kickmem_bank.baseaddr[12] << 8) | kickmem_bank.baseaddr[13]; - if (kickstart_version == 0xffff) - kickstart_version = 0; - zfile_fclose (f); - return 1; +#if defined(AMIGA) + chk_sum: +#endif -err: - _tcscpy (currprefs.romfile, tmprom); - zfile_fclose (f); - return 0; + kickstart_version = (kickmem_bank.baseaddr[12] << 8) | kickmem_bank.baseaddr[13]; + if (kickstart_version == 0xffff) { + // 1.0-1.1 and older + kickstart_version = (kickmem_bank.baseaddr[16] << 8) | kickmem_bank.baseaddr[17]; + if (kickstart_version > 33) + kickstart_version = 0; + } + zfile_fclose(f); + return 1; + err: + _tcscpy(currprefs.romfile, tmprom); + zfile_fclose(f); + return 0; } +#ifndef NATMEM_OFFSET -static void init_mem_banks (void) +bool mapped_malloc(addrbank *ab) { - int i; - for (i = 0; i < MEMORY_BANKS; i++) { - mem_banks[i] = &dummy_bank; - } + ab->startmask = ab->start; + ab->baseaddr = xcalloc(uae_u8, ab->reserved_size + 4); + ab->allocated_size = ab->baseaddr != NULL ? ab->reserved_size : 0; + return ab->baseaddr != NULL; } -static bool singlebit (uae_u32 v) +void mapped_free(addrbank *ab) +{ + xfree(ab->baseaddr); + ab->allocated_size = 0; + ab->baseaddr = NULL; +} + +#else + +#include + +shmpiece *shm_start; + +static void dumplist(void) +{ + shmpiece *x = shm_start; + write_log(_T("Start Dump:\n")); + while (x) { + write_log(_T("this=%p,Native %p,id %d,prev=%p,next=%p,size=0x%08x\n"), + x, x->native_address, x->id, x->prev, x->next, x->size); + x = x->next; + } + write_log(_T("End Dump:\n")); +} + +static shmpiece *find_shmpiece(uae_u8 *base, bool safe) +{ + shmpiece *x = shm_start; + + while (x && x->native_address != base) + x = x->next; + if (!x) { + if (safe || bogomem_aliasing) + return 0; + write_log(_T("NATMEM: Failure to find mapping at %08lx, %p\n"), base - NATMEM_OFFSET, base); + nocanbang(); + return 0; + } + return x; +} + +static void delete_shmmaps(uae_u32 start, uae_u32 size) +{ + if (!needmman()) + return; + + while (size) { + uae_u8 *base = mem_banks[bankindex(start)]->baseaddr; + if (base) { + shmpiece *x; + //base = ((uae_u8*)NATMEM_OFFSET)+start; + + x = find_shmpiece(base, true); + if (!x) + return; + + if (x->size > size) { + if (isdirectjit()) + write_log(_T("NATMEM WARNING: size mismatch mapping at %08x (size %08x, delsize %08x)\n"), start, x->size, size); + size = x->size; + } + + uae_shmdt(x->native_address); + size -= x->size; + start += x->size; + if (x->next) + x->next->prev = x->prev; /* remove this one from the list */ + if (x->prev) + x->prev->next = x->next; + else + shm_start = x->next; + xfree(x); + } + else { + size -= 0x10000; + start += 0x10000; + } + } +} + +static void add_shmmaps(uae_u32 start, Addrbank *what) +{ + shmpiece *x = shm_start; + shmpiece *y; + uae_u8 *base = what->baseaddr; + + if (!needmman()) + return; + + if (!base) + return; + + if (what->jit_read_flag && what->jit_write_flag) + return; + + x = find_shmpiece(base, false); + if (!x) + return; + + y = xmalloc(shmpiece, 1); + *y = *x; + base = ((uae_u8 *)NATMEM_OFFSET) + start; + y->native_address = (uae_u8*)uae_shmat(what, y->id, base, 0); + if (y->native_address == (void *)-1) { + write_log(_T("NATMEM: Failure to map existing at %08x (%p)\n"), start, base); + dumplist(); + nocanbang(); + return; + } + y->next = shm_start; + y->prev = NULL; + if (y->next) + y->next->prev = y; + shm_start = y; +} + +#define MAPPED_MALLOC_DEBUG 0 + +bool mapped_malloc(Addrbank *ab) +{ + int id; + void *answer; + shmpiece *x; + bool rtgmem = (ab->flags & ABFLAG_RTG) != 0; + static int recurse; + + if (ab->allocated_size) { + write_log(_T("mapped_malloc with memory bank '%s' already allocated!?\n"), ab->name); + } + ab->allocated_size = 0; + + if (ab->label && ab->label[0] == '*') { + if (ab->start == 0 || ab->start == 0xffffffff) { + write_log(_T("mapped_malloc(*) without start address!\n")); + return false; + } + } + + struct uae_mman_data md = { 0 }; + uaecptr start = ab->start; + if (uae_mman_info(ab, &md)) { + start = md.start; + } + ab->startmask = start; + if (!md.directsupport || (ab->flags & ABFLAG_ALLOCINDIRECT)) { + if (!(ab->flags & ABFLAG_ALLOCINDIRECT)) { + if (canbang) { + write_log(_T("JIT direct switched off: %s\n"), ab->name); + } + nocanbang(); + } + ab->flags &= ~ABFLAG_DIRECTMAP; + if (ab->flags & ABFLAG_NOALLOC) { + ab->allocated_size = ab->reserved_size; +#if MAPPED_MALLOC_DEBUG + write_log(_T("mapped_malloc noalloc %s\n"), ab->name); +#endif + return true; + } + ab->baseaddr = xcalloc(uae_u8, ab->reserved_size + 4); + if (ab->baseaddr) { + // fill end of ram with ILLEGAL to catch direct PC falling out of RAM. + put_long_host(ab->baseaddr + ab->reserved_size, 0x4afc4afc); + ab->allocated_size = ab->reserved_size; + } +#if MAPPED_MALLOC_DEBUG + write_log(_T("mapped_malloc nodirect %s %p\n"), ab->name, ab->baseaddr); +#endif + return ab->baseaddr != NULL; + } + + id = uae_shmget(UAE_IPC_PRIVATE, ab, 0x1ff); + if (id == -1) { + nocanbang(); + if (recurse) + return NULL; + recurse++; + mapped_malloc(ab); + recurse--; + return ab->baseaddr != NULL; + } + if (!(ab->flags & ABFLAG_NOALLOC)) { + answer = uae_shmat(ab, id, 0, 0); + uae_shmctl(id, UAE_IPC_RMID, NULL); + } + else { + write_log(_T("MMAN: mapped_malloc using existing baseaddr %p\n"), ab->baseaddr); + answer = ab->baseaddr; + } + if (answer != (void *)-1) { + x = xmalloc(shmpiece, 1); + x->native_address = (uae_u8*)answer; + x->id = id; + x->size = ab->reserved_size; + x->name = ab->label; + x->next = shm_start; + x->prev = NULL; + if (x->next) + x->next->prev = x; + shm_start = x; + ab->baseaddr = x->native_address; + if (ab->baseaddr) { + if (md.hasbarrier) { + // fill end of ram with ILLEGAL to catch direct PC falling out of RAM. + put_long_host(ab->baseaddr + ab->reserved_size, 0x4afc4afc); + } + ab->allocated_size = ab->reserved_size; + } + ab->flags |= ABFLAG_DIRECTMAP; +#if MAPPED_MALLOC_DEBUG + write_log(_T("mapped_malloc direct %s %p\n"), ab->name, ab->baseaddr); +#endif + return ab->baseaddr != NULL; + } + if (recurse) + return NULL; + nocanbang(); + recurse++; + mapped_malloc(ab); + recurse--; +#if MAPPED_MALLOC_DEBUG + write_log(_T("mapped_malloc indirect %s %p\n"), ab->name, ab->baseaddr); +#endif + return ab->baseaddr != NULL; +} + +#endif + +static void init_mem_banks(void) +{ + // unsigned so i << 16 won't overflow to negative when i >= 32768 + for (unsigned int i = 0; i < MEMORY_BANKS; i++) + put_mem_bank(i << 16, &dummy_bank, 0); +#ifdef NATMEM_OFFSET + delete_shmmaps(0, 0xFFFF0000); +#endif +} + +static bool singlebit(uae_u32 v) { while (v && !(v & 1)) v >>= 1; return (v & ~1) == 0; } -static void allocate_memory (void) +static void allocate_memory(void) { - if (chipmem_bank.allocated != currprefs.chipmem_size) { - int memsize; - mapped_free (chipmem_bank.baseaddr); - chipmem_bank.baseaddr = 0; - if (currprefs.chipmem_size > 2 * 1024 * 1024) - free_fastmemory (); - - memsize = chipmem_bank.allocated = currprefs.chipmem_size; - chipmem_full_mask = chipmem_bank.mask = chipmem_bank.allocated - 1; + bogomem_aliasing = 0; + + bool bogoreset = (bogomem_bank.flags & ABFLAG_NOALLOC) != 0 && + (chipmem_bank.reserved_size != currprefs.chipmem_size || bogomem_bank.reserved_size != currprefs.bogomem_size); + + if (bogoreset) { + mapped_free(&chipmem_bank); + mapped_free(&bogomem_bank); + } + + /* emulate 0.5M+0.5M with 1M Agnus chip ram aliasing */ + if (currprefs.chipmem_size == 0x80000 && currprefs.bogomem_size >= 0x80000 && + (currprefs.chipset_mask & CSMASK_ECS_AGNUS) && !(currprefs.chipset_mask & CSMASK_AGA) && currprefs.cpu_model < 68020) { + if ((chipmem_bank.reserved_size != currprefs.chipmem_size || bogomem_bank.reserved_size != currprefs.bogomem_size)) { + int memsize1, memsize2; + mapped_free(&chipmem_bank); + mapped_free(&bogomem_bank); + bogomem_bank.reserved_size = 0; + memsize1 = chipmem_bank.reserved_size = currprefs.chipmem_size; + memsize2 = bogomem_bank.reserved_size = currprefs.bogomem_size; + chipmem_bank.mask = chipmem_bank.reserved_size - 1; + chipmem_bank.start = chipmem_start_addr; + chipmem_full_mask = bogomem_bank.reserved_size * 2 - 1; + chipmem_full_size = 0x80000 * 2; + chipmem_bank.reserved_size = memsize1 + memsize2; + mapped_malloc(&chipmem_bank); + chipmem_bank.reserved_size = currprefs.chipmem_size; + chipmem_bank.allocated_size = currprefs.chipmem_size; + bogomem_bank.baseaddr = chipmem_bank.baseaddr + memsize1; + bogomem_bank.mask = bogomem_bank.reserved_size - 1; + bogomem_bank.start = bogomem_start_addr; + bogomem_bank.flags |= ABFLAG_NOALLOC; + bogomem_bank.allocated_size = bogomem_bank.reserved_size; + if (chipmem_bank.baseaddr == 0) { + write_log(_T("Fatal error: out of memory for chipmem.\n")); + chipmem_bank.reserved_size = 0; + } + else { + need_hardreset = true; + } + } + bogomem_aliasing = 1; + } + else if (currprefs.chipmem_size == 0x80000 && currprefs.bogomem_size >= 0x80000 && + !(currprefs.chipset_mask & CSMASK_ECS_AGNUS) && currprefs.cs_1mchipjumper && currprefs.cpu_model < 68020) { + if ((chipmem_bank.reserved_size != currprefs.chipmem_size || bogomem_bank.reserved_size != currprefs.bogomem_size)) { + int memsize1, memsize2; + mapped_free(&chipmem_bank); + mapped_free(&bogomem_bank); + bogomem_bank.reserved_size = 0; + memsize1 = chipmem_bank.reserved_size = currprefs.chipmem_size; + memsize2 = bogomem_bank.reserved_size = currprefs.bogomem_size; + chipmem_bank.mask = chipmem_bank.reserved_size - 1; + chipmem_bank.start = chipmem_start_addr; + chipmem_full_mask = chipmem_bank.reserved_size - 1; + chipmem_full_size = chipmem_bank.reserved_size; + chipmem_bank.reserved_size = memsize1 + memsize2; + mapped_malloc(&chipmem_bank); + chipmem_bank.reserved_size = currprefs.chipmem_size; + chipmem_bank.allocated_size = currprefs.chipmem_size; + bogomem_bank.baseaddr = chipmem_bank.baseaddr + memsize1; + bogomem_bank.mask = bogomem_bank.reserved_size - 1; + bogomem_bank.start = chipmem_bank.start + currprefs.chipmem_size; + bogomem_bank.flags |= ABFLAG_NOALLOC; + if (chipmem_bank.baseaddr == 0) { + write_log(_T("Fatal error: out of memory for chipmem.\n")); + chipmem_bank.reserved_size = 0; + } + else { + need_hardreset = true; + } + } + bogomem_aliasing = 2; + } + + if (chipmem_bank.reserved_size != currprefs.chipmem_size || bogoreset) { + int memsize; + mapped_free(&chipmem_bank); + chipmem_bank.flags &= ~ABFLAG_NOALLOC; + + memsize = chipmem_bank.reserved_size = chipmem_full_size = currprefs.chipmem_size; + chipmem_full_mask = chipmem_bank.mask = chipmem_bank.reserved_size - 1; chipmem_bank.start = chipmem_start_addr; if (!currprefs.cachesize && memsize < 0x100000) memsize = 0x100000; - if (memsize > 0x100000 && memsize < 0x200000) - memsize = 0x200000; - chipmem_bank.baseaddr = mapped_malloc (memsize, _T("chip")); + if (memsize > 0x100000 && memsize < 0x200000) + memsize = 0x200000; + chipmem_bank.reserved_size = memsize; + mapped_malloc(&chipmem_bank); + chipmem_bank.reserved_size = currprefs.chipmem_size; + chipmem_bank.allocated_size = currprefs.chipmem_size; if (chipmem_bank.baseaddr == 0) { - write_log (_T("Fatal error: out of memory for chipmem.\n")); - chipmem_bank.allocated = 0; - } else { + write_log(_T("Fatal error: out of memory for chipmem.\n")); + chipmem_bank.reserved_size = 0; + } + else { need_hardreset = true; - if (memsize > chipmem_bank.allocated) - memset (chipmem_bank.baseaddr + chipmem_bank.allocated, 0xff, memsize - chipmem_bank.allocated); - } - currprefs.chipset_mask = changed_prefs.chipset_mask; - chipmem_full_mask = chipmem_bank.allocated - 1; - if ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) && !currprefs.cachesize) { - if (chipmem_bank.allocated < 0x100000) - chipmem_full_mask = 0x100000 - 1; - if (chipmem_bank.allocated > 0x100000 && chipmem_bank.allocated < 0x200000) - chipmem_full_mask = chipmem_bank.mask = 0x200000 - 1; + if (memsize > chipmem_bank.allocated_size) + memset(chipmem_bank.baseaddr + chipmem_bank.allocated_size, 0xff, memsize - chipmem_bank.allocated_size); } - } - - if (bogomem_bank.allocated != currprefs.bogomem_size) { - mapped_free (bogomem_bank.baseaddr); - bogomem_bank.baseaddr = NULL; - - if(currprefs.bogomem_size > 0x1c0000) - currprefs.bogomem_size = 0x1c0000; - if (currprefs.bogomem_size > 0x180000 && ((changed_prefs.chipset_mask & CSMASK_AGA) || (currprefs.cpu_model >= 68020))) - currprefs.bogomem_size = 0x180000; - - bogomem_bank.allocated = currprefs.bogomem_size; - if (bogomem_bank.allocated >= 0x180000) - bogomem_bank.allocated = 0x200000; - bogomem_bank.mask = bogomem_bank.allocated - 1; - bogomem_bank.start = bogomem_start_addr; - - if (bogomem_bank.allocated) { - bogomem_bank.baseaddr = mapped_malloc (bogomem_bank.allocated, _T("bogo")); - if (bogomem_bank.baseaddr == 0) { - write_log (_T("Out of memory for bogomem.\n")); - bogomem_bank.allocated = 0; - } + currprefs.chipset_mask = changed_prefs.chipset_mask; + chipmem_full_mask = chipmem_bank.allocated_size - 1; + if (!currprefs.cachesize) { + if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { + if (chipmem_bank.allocated_size < 0x100000) + chipmem_full_mask = 0x100000 - 1; + if (chipmem_bank.allocated_size > 0x100000 && chipmem_bank.allocated_size < 0x200000) + chipmem_full_mask = chipmem_bank.mask = 0x200000 - 1; + } + else if (currprefs.cs_1mchipjumper) { + chipmem_full_mask = 0x80000 - 1; + } } - need_hardreset = true; } - if (savestate_state == STATE_RESTORE) { - if (bootrom_filepos) { - protect_roms (false); - restore_ram (bootrom_filepos, rtarea); - protect_roms (true); - } - restore_ram (chip_filepos, chipmem_bank.baseaddr); - if (bogomem_bank.allocated > 0) - restore_ram (bogo_filepos, bogomem_bank.baseaddr); - } - bootrom_filepos = 0; - chip_filepos = 0; - bogo_filepos = 0; -} + if (bogomem_bank.reserved_size != currprefs.bogomem_size || bogoreset) { + if (!(bogomem_bank.reserved_size == 0x200000 && currprefs.bogomem_size == 0x180000)) { + mapped_free(&bogomem_bank); + bogomem_bank.flags &= ~ABFLAG_NOALLOC; + bogomem_bank.reserved_size = 0; -void map_overlay (int chip) -{ - int size; - addrbank *cb; - int currPC = m68k_getpc(); + bogomem_bank.reserved_size = currprefs.bogomem_size; + if (bogomem_bank.reserved_size >= 0x180000) + bogomem_bank.reserved_size = 0x200000; + bogomem_bank.mask = bogomem_bank.reserved_size - 1; + bogomem_bank.start = bogomem_start_addr; - size = chipmem_bank.allocated >= 0x180000 ? (chipmem_bank.allocated >> 16) : 32; - cb = &chipmem_bank; - if (chip) { - map_banks (&dummy_bank, 0, 32, 0); - map_banks (cb, 0, size, chipmem_bank.allocated); - } else { - addrbank *rb = NULL; - if (size < 32) - size = 32; - cb = &get_mem_bank (0xf00000); - if (!rb && cb && (cb->flags & ABFLAG_ROM) && get_word (0xf00000) == 0x1114) - rb = cb; - cb = &get_mem_bank (0xe00000); - if (!rb && cb && (cb->flags & ABFLAG_ROM) && get_word (0xe00000) == 0x1114) - rb = cb; - if (!rb) - rb = &kickmem_bank; - map_banks (rb, 0, size, 0x80000); - } - if (!isrestore () && valid_address (regs.pc, 4)) - m68k_setpc_normal (currPC); -} - -uae_s32 getz2size (struct uae_prefs *p) -{ - uae_u32 start; - start = p->fastmem_size; - if (p->rtgmem_size && !gfxboard_is_z3 (p->rtgmem_type)) { - while (start & (p->rtgmem_size - 1) && start < 8 * 1024 * 1024) - start += 1024 * 1024; - if (start + p->rtgmem_size > 8 * 1024 * 1024) - return -1; + if (bogomem_bank.reserved_size) { + if (!mapped_malloc(&bogomem_bank)) { + write_log(_T("Out of memory for bogomem.\n")); + bogomem_bank.reserved_size = 0; + } + } + need_hardreset = true; + } } - start += p->rtgmem_size; - return start; -} + if (mem25bit_bank.reserved_size != currprefs.mem25bit_size) { + mapped_free(&mem25bit_bank); -uae_u32 getz2endaddr (void) -{ - uae_u32 start; - start = currprefs.fastmem_size; - if (currprefs.rtgmem_size && !gfxboard_is_z3 (currprefs.rtgmem_type)) { - if (!start) - start = 0x00200000; - while (start & (currprefs.rtgmem_size - 1) && start < 4 * 1024 * 1024) - start += 1024 * 1024; + mem25bit_bank.reserved_size = currprefs.mem25bit_size; + mem25bit_bank.mask = mem25bit_bank.reserved_size - 1; + mem25bit_bank.start = 0x01000000; + if (mem25bit_bank.reserved_size) { + if (!mapped_malloc(&mem25bit_bank)) { + write_log(_T("Out of memory for 25 bit memory.\n")); + mem25bit_bank.reserved_size = 0; + } + } + need_hardreset = true; } - return start + 2 * 1024 * 1024; + if (a3000lmem_bank.reserved_size != currprefs.mbresmem_low_size) { + mapped_free(&a3000lmem_bank); + + a3000lmem_bank.reserved_size = currprefs.mbresmem_low_size; + a3000lmem_bank.mask = a3000lmem_bank.reserved_size - 1; + a3000lmem_bank.start = 0x08000000 - a3000lmem_bank.reserved_size; + if (a3000lmem_bank.reserved_size) { + if (!mapped_malloc(&a3000lmem_bank)) { + write_log(_T("Out of memory for a3000lowmem.\n")); + a3000lmem_bank.reserved_size = 0; + } + } + need_hardreset = true; + } + if (a3000hmem_bank.reserved_size != currprefs.mbresmem_high_size) { + mapped_free(&a3000hmem_bank); + + a3000hmem_bank.reserved_size = currprefs.mbresmem_high_size; + a3000hmem_bank.mask = a3000hmem_bank.reserved_size - 1; + a3000hmem_bank.start = 0x08000000; + if (a3000hmem_bank.reserved_size) { + if (!mapped_malloc(&a3000hmem_bank)) { + write_log(_T("Out of memory for a3000highmem.\n")); + a3000hmem_bank.reserved_size = 0; + } + } + need_hardreset = true; + } +#ifdef CDTV + if (cardmem_bank.reserved_size != currprefs.cs_cdtvcard * 1024) { + mapped_free(&cardmem_bank); + cardmem_bank.baseaddr = NULL; + + cardmem_bank.reserved_size = currprefs.cs_cdtvcard * 1024; + cardmem_bank.mask = cardmem_bank.reserved_size - 1; + cardmem_bank.start = 0xe00000; + if (cardmem_bank.reserved_size) { + if (!mapped_malloc(&cardmem_bank)) { + write_log(_T("Out of memory for cardmem.\n")); + cardmem_bank.reserved_size = 0; + } + } + cdtv_loadcardmem(cardmem_bank.baseaddr, cardmem_bank.reserved_size); + } +#endif + if (custmem1_bank.reserved_size != currprefs.custom_memory_sizes[0]) { + mapped_free(&custmem1_bank); + custmem1_bank.reserved_size = currprefs.custom_memory_sizes[0]; + // custmem1 and 2 can have non-power of 2 size so only set correct mask if size is power of 2. + custmem1_bank.mask = singlebit(custmem1_bank.reserved_size) ? custmem1_bank.reserved_size - 1 : -1; + custmem1_bank.start = currprefs.custom_memory_addrs[0]; + if (custmem1_bank.reserved_size) { + if (!mapped_malloc(&custmem1_bank)) + custmem1_bank.reserved_size = 0; + } + } + if (custmem2_bank.reserved_size != currprefs.custom_memory_sizes[1]) { + mapped_free(&custmem2_bank); + custmem2_bank.reserved_size = currprefs.custom_memory_sizes[1]; + custmem2_bank.mask = singlebit(custmem2_bank.reserved_size) ? custmem2_bank.reserved_size - 1 : -1; + custmem2_bank.start = currprefs.custom_memory_addrs[1]; + if (custmem2_bank.reserved_size) { + if (!mapped_malloc(&custmem2_bank)) + custmem2_bank.reserved_size = 0; + } + } + + if (savestate_state == STATE_RESTORE) { + if (bootrom_filepos) { + protect_roms(false); + restore_ram(bootrom_filepos, rtarea_bank.baseaddr); + protect_roms(true); + } + restore_ram(chip_filepos, chipmem_bank.baseaddr); + if (bogomem_bank.allocated_size > 0) + restore_ram(bogo_filepos, bogomem_bank.baseaddr); + if (mem25bit_bank.allocated_size > 0) + restore_ram(mem25bit_filepos, mem25bit_bank.baseaddr); + if (a3000lmem_bank.allocated_size > 0) + restore_ram(a3000lmem_filepos, a3000lmem_bank.baseaddr); + if (a3000hmem_bank.allocated_size > 0) + restore_ram(a3000hmem_filepos, a3000hmem_bank.baseaddr); + } +#ifdef AGA + chipmem_bank_ce2.baseaddr = chipmem_bank.baseaddr; +#endif + bootrom_filepos = 0; + chip_filepos = 0; + bogo_filepos = 0; + a3000lmem_filepos = 0; + a3000hmem_filepos = 0; + //cpuboard_init(); } -void memory_clear (void) +static void fill_ce_banks(void) +{ + int i; + + if (currprefs.cpu_model <= 68010) { + memset(ce_banktype, CE_MEMBANK_FAST16, sizeof ce_banktype); + } + else { + memset(ce_banktype, CE_MEMBANK_FAST32, sizeof ce_banktype); + } + // data cachable regions (2 = burst supported) + memset(ce_cachable, 0, sizeof ce_cachable); + memset(ce_cachable + (0x00c00000 >> 16), 1, currprefs.bogomem_size >> 16); + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + if (fastmem_bank[i].start != 0xffffffff) + memset(ce_cachable + (fastmem_bank[i].start >> 16), 1 | 2, currprefs.fastmem[i].size >> 16); + if (z3fastmem_bank[i].start != 0xffffffff) + memset(ce_cachable + (z3fastmem_bank[i].start >> 16), 1 | 2, currprefs.z3fastmem[i].size >> 16); + } + memset(ce_cachable + (a3000hmem_bank.start >> 16), 1 | 2, currprefs.mbresmem_high_size >> 16); + memset(ce_cachable + (a3000lmem_bank.start >> 16), 1 | 2, currprefs.mbresmem_low_size >> 16); + memset(ce_cachable + (mem25bit_bank.start >> 16), 1 | 2, currprefs.mem25bit_size >> 16); + + addrbank *ab = &get_mem_bank(0); + if (ab && (ab->flags & ABFLAG_CHIPRAM)) { + for (i = 0; i < (0x200000 >> 16); i++) { + ce_banktype[i] = (currprefs.cs_mbdmac || (currprefs.chipset_mask & CSMASK_AGA)) ? CE_MEMBANK_CHIP32 : CE_MEMBANK_CHIP16; + } + } + if (!currprefs.cs_slowmemisfast) { + for (i = (0xc00000 >> 16); i < (0xe00000 >> 16); i++) + ce_banktype[i] = ce_banktype[0]; + for (i = (bogomem_bank.start >> 16); i < ((bogomem_bank.start + bogomem_bank.allocated_size) >> 16); i++) + ce_banktype[i] = ce_banktype[0]; + } + for (i = (0xd00000 >> 16); i < (0xe00000 >> 16); i++) + ce_banktype[i] = CE_MEMBANK_CHIP16; + for (i = (0xa00000 >> 16); i < (0xc00000 >> 16); i++) { + addrbank *b; + ce_banktype[i] = CE_MEMBANK_CIA; + b = &get_mem_bank(i << 16); + if (b && !(b->flags & ABFLAG_CIA)) { + ce_banktype[i] = CE_MEMBANK_FAST32; + ce_cachable[i] = 1; + } + } + // CD32 ROM is 16-bit + if (currprefs.cs_cd32cd) { + for (i = (0xe00000 >> 16); i < (0xe80000 >> 16); i++) + ce_banktype[i] = CE_MEMBANK_FAST16; + for (i = (0xf80000 >> 16); i <= (0xff0000 >> 16); i++) + ce_banktype[i] = CE_MEMBANK_FAST16; + } + + // A4000T NCR is 32-bit + if (is_device_rom(&currprefs, ROMTYPE_SCSI_A4000T, 0) >= 0) { + ce_banktype[0xdd0000 >> 16] = CE_MEMBANK_FAST32; + } + + if (currprefs.address_space_24) { + for (i = 1; i < 256; i++) + memcpy(&ce_banktype[i * 256], &ce_banktype[0], 256); + } +} + +void map_overlay(int chip) +{ + int size; + addrbank *cb; + + size = chipmem_bank.allocated_size >= 0x180000 ? (chipmem_bank.allocated_size >> 16) : 32; + if (bogomem_aliasing) + size = 8; + cb = &chipmem_bank; +#ifdef AGA +#if 0 + if (currprefs.cpu_cycle_exact && currprefs.cpu_model >= 68020) + cb = &chipmem_bank_ce2; +#endif +#endif + if (chip) { + map_banks(&dummy_bank, 0, size, 0); + if (!isdirectjit()) { + if ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) && bogomem_bank.allocated_size == 0) { + map_banks(cb, 0, size, chipmem_bank.allocated_size); + int start = chipmem_bank.allocated_size >> 16; + if (chipmem_bank.allocated_size < 0x100000) { + if (currprefs.cs_1mchipjumper) { + int dummy = (0x100000 - chipmem_bank.allocated_size) >> 16; + map_banks(&chipmem_dummy_bank, start, dummy, 0); + map_banks(&chipmem_dummy_bank, start + 16, dummy, 0); + } + } + else if (chipmem_bank.allocated_size < 0x200000 && chipmem_bank.allocated_size > 0x100000) { + int dummy = (0x200000 - chipmem_bank.allocated_size) >> 16; + map_banks(&chipmem_dummy_bank, start, dummy, 0); + } + } + else { + int mapsize = 32; + if ((chipmem_bank.allocated_size >> 16) > mapsize) + mapsize = chipmem_bank.allocated_size >> 16; + map_banks(cb, 0, mapsize, chipmem_bank.allocated_size); + } + } + else { + map_banks(cb, 0, chipmem_bank.allocated_size >> 16, 0); + } + } + else { + addrbank *rb = NULL; + if (size < 32 && bogomem_aliasing == 0) + size = 32; + cb = &get_mem_bank(0xf00000); + if (!rb && cb && (cb->flags & ABFLAG_ROM) && get_word(0xf00000) == 0x1114) + rb = cb; + cb = &get_mem_bank(0xe00000); + if (!rb && cb && (cb->flags & ABFLAG_ROM) && get_word(0xe00000) == 0x1114) + rb = cb; + if (!rb) + rb = &kickmem_bank; + map_banks(rb, 0, size, 0x80000); + } + fill_ce_banks(); + //cpuboard_overlay_override(); + if (!isrestore() && valid_address(regs.pc, 4)) + m68k_setpc_normal(m68k_getpc()); +} + +static void map_banks_set(addrbank *bank, int start, int size, int realsize) +{ + bank->startmask = start << 16; + map_banks(bank, start, size, realsize); +} + +void memory_clear(void) { mem_hardreset = 0; if (savestate_state == STATE_RESTORE) return; if (chipmem_bank.baseaddr) - memset (chipmem_bank.baseaddr, 0, chipmem_bank.allocated); + memset(chipmem_bank.baseaddr, 0, chipmem_bank.allocated_size); if (bogomem_bank.baseaddr) - memset (bogomem_bank.baseaddr, 0, bogomem_bank.allocated); - expansion_clear (); + memset(bogomem_bank.baseaddr, 0, bogomem_bank.allocated_size); + if (mem25bit_bank.baseaddr) + memset(mem25bit_bank.baseaddr, 0, mem25bit_bank.allocated_size); + if (a3000lmem_bank.baseaddr) + memset(a3000lmem_bank.baseaddr, 0, a3000lmem_bank.allocated_size); + if (a3000hmem_bank.baseaddr) + memset(a3000hmem_bank.baseaddr, 0, a3000hmem_bank.allocated_size); + expansion_clear(); + //cpuboard_clear(); } -void memory_reset (void) +static void restore_roms(void) { - int bnk, bnk_end; + roms_modified = false; + protect_roms(false); + write_log(_T("ROM loader.. (%s)\n"), currprefs.romfile); + kickstart_rom = 1; + a1000_handle_kickstart(0); + xfree(a1000_bootrom); + a1000_bootrom = 0; + a1000_kickstart_mode = 0; + + memcpy(currprefs.romfile, changed_prefs.romfile, sizeof currprefs.romfile); + memcpy(currprefs.romextfile, changed_prefs.romextfile, sizeof currprefs.romextfile); + need_hardreset = true; + mapped_free(&extendedkickmem_bank); + mapped_free(&extendedkickmem2_bank); + extendedkickmem_bank.reserved_size = 0; + extendedkickmem2_bank.reserved_size = 0; + extendedkickmem_type = 0; + load_extendedkickstart(currprefs.romextfile, 0); + load_extendedkickstart(currprefs.romextfile2, EXTENDED_ROM_CDTV); + kickmem_bank.mask = ROM_SIZE_512 - 1; + if (!load_kickstart()) { + if (_tcslen(currprefs.romfile) > 0) { + error_log(_T("Failed to open '%s'\n"), currprefs.romfile); + notify_user(NUMSG_NOROM); + } + load_kickstart_replacement(); + } + else { + struct romdata *rd = getromdatabydata(kickmem_bank.baseaddr, kickmem_bank.reserved_size); + if (rd) { + write_log(_T("Known ROM '%s' loaded\n"), rd->name); +#if 1 + if ((rd->cpu & 8) && changed_prefs.cpu_model < 68030) { + notify_user(NUMSG_KS68030PLUS); + uae_restart(-1, NULL); + } + else if ((rd->cpu & 3) == 3 && changed_prefs.cpu_model != 68030) { + notify_user(NUMSG_KS68030); + uae_restart(-1, NULL); + } + else if ((rd->cpu & 3) == 1 && changed_prefs.cpu_model < 68020) { + notify_user(NUMSG_KS68EC020); + uae_restart(-1, NULL); + } + else if ((rd->cpu & 3) == 2 && (changed_prefs.cpu_model < 68020 || changed_prefs.address_space_24)) { + notify_user(NUMSG_KS68020); + uae_restart(-1, NULL); + } +#endif + if (rd->cloanto) + cloanto_rom = 1; + kickstart_rom = 0; + if ((rd->type & (ROMTYPE_SPECIALKICK | ROMTYPE_KICK)) == ROMTYPE_KICK) + kickstart_rom = 1; + if ((rd->cpu & 4) && currprefs.cs_compatible) { + /* A4000 ROM = need ramsey, gary and ide */ + if (currprefs.cs_ramseyrev < 0) + changed_prefs.cs_ramseyrev = currprefs.cs_ramseyrev = 0x0f; + changed_prefs.cs_fatgaryrev = currprefs.cs_fatgaryrev = 0; + if (currprefs.cs_ide != IDE_A4000) + changed_prefs.cs_ide = currprefs.cs_ide = -1; + } + } + else { + write_log(_T("Unknown ROM '%s' loaded\n"), currprefs.romfile); + } + } + patch_kick(); + write_log(_T("ROM loader end\n")); + protect_roms(true); +} + +bool read_kickstart_version(struct uae_prefs *p) +{ + kickstart_version = 0; + cloanto_rom = 0; + struct zfile *z = get_kickstart_filehandle(p); + if (!z) + return false; + uae_u8 mem[32] = { 0 }; + read_kickstart(z, mem, sizeof mem, 0, 0); + zfile_fclose(z); + kickstart_version = (mem[12] << 8) | mem[13]; + if (kickstart_version == 0xffff) { + // 1.0-1.1 and older + kickstart_version = (mem[16] << 8) | mem[17]; + if (kickstart_version > 33) + kickstart_version = 0; + } + write_log(_T("KS ver = %04x\n"), kickstart_version); + return true; +} + +void reload_roms(void) +{ + if (roms_modified) + restore_roms(); +} + +void memory_restore(void) +{ + last_address_space_24 = currprefs.address_space_24; + //cpuboard_map(); + map_banks_set(&kickmem_bank, 0xF8, 8, 0); +} + +void memory_reset(void) +{ + int bnk, bnk_end; bool gayleorfatgary; + //alg_flag = 0; need_hardreset = false; + rom_write_enabled = true; /* Use changed_prefs, as m68k_reset is called later. */ if (last_address_space_24 != changed_prefs.address_space_24) need_hardreset = true; last_address_space_24 = changed_prefs.address_space_24; if (mem_hardreset > 2) - memory_init (); + memory_init(); be_cnt = 0; - currprefs.chipmem_size = changed_prefs.chipmem_size; - currprefs.bogomem_size = changed_prefs.bogomem_size; + currprefs.chipmem_size = changed_prefs.chipmem_size; + currprefs.bogomem_size = changed_prefs.bogomem_size; + currprefs.mbresmem_low_size = changed_prefs.mbresmem_low_size; + currprefs.mbresmem_high_size = changed_prefs.mbresmem_high_size; + currprefs.cs_ksmirror_e0 = changed_prefs.cs_ksmirror_e0; + currprefs.cs_ksmirror_a8 = changed_prefs.cs_ksmirror_a8; + currprefs.cs_ciaoverlay = changed_prefs.cs_ciaoverlay; + currprefs.cs_cdtvram = changed_prefs.cs_cdtvram; + currprefs.cs_cdtvcard = changed_prefs.cs_cdtvcard; + currprefs.cs_a1000ram = changed_prefs.cs_a1000ram; + currprefs.cs_ide = changed_prefs.cs_ide; + currprefs.cs_fatgaryrev = changed_prefs.cs_fatgaryrev; + currprefs.cs_ramseyrev = changed_prefs.cs_ramseyrev; + //cpuboard_reset(); - gayleorfatgary = (currprefs.chipset_mask & CSMASK_AGA); + gayleorfatgary = ((currprefs.chipset_mask & CSMASK_AGA) || currprefs.cs_pcmcia || currprefs.cs_ide > 0 || currprefs.cs_mbdmac) && !currprefs.cs_cd32cd; - init_mem_banks (); - allocate_memory (); + init_mem_banks(); + allocate_memory(); + chipmem_setindirect(); - if (mem_hardreset > 1 - || _tcscmp (currprefs.romfile, changed_prefs.romfile) != 0 - || _tcscmp (currprefs.romextfile, changed_prefs.romextfile) != 0) - { - protect_roms (false); - write_log (_T("ROM loader.. (%s)\n"), currprefs.romfile); - kickstart_rom = 1; + if (mem_hardreset > 1 || ((roms_modified || a1000_bootrom)) //&& is_hardreset()) + || _tcscmp(currprefs.romfile, changed_prefs.romfile) != 0 + || _tcscmp(currprefs.romextfile, changed_prefs.romextfile) != 0) + { + restore_roms(); + } - memcpy (currprefs.romfile, changed_prefs.romfile, sizeof currprefs.romfile); - memcpy (currprefs.romextfile, changed_prefs.romextfile, sizeof currprefs.romextfile); - need_hardreset = true; - mapped_free (extendedkickmem_bank.baseaddr); - extendedkickmem_bank.baseaddr = NULL; - extendedkickmem_bank.allocated = 0; - extendedkickmem2_bank.baseaddr = NULL; - extendedkickmem2_bank.allocated = 0; - extendedkickmem_type = 0; - load_extendedkickstart (currprefs.romextfile, 0); - kickmem_bank.mask = ROM_SIZE_512 - 1; - if (!load_kickstart ()) { - if (_tcslen (currprefs.romfile) > 0) { - error_log (_T("Failed to open '%s'\n"), currprefs.romfile); - notify_user (NUMSG_NOROM); - } - load_kickstart_replacement (); - } else { - struct romdata *rd = getromdatabydata (kickmem_bank.baseaddr, kickmem_bank.allocated); - if (rd) { - write_log (_T("Known ROM '%s' loaded\n"), rd->name); - if ((rd->cpu & 8) && changed_prefs.cpu_model < 68030) { - notify_user (NUMSG_KS68030PLUS); - uae_restart (-1, NULL); - } else if ((rd->cpu & 3) == 3 && changed_prefs.cpu_model != 68030) { - notify_user (NUMSG_KS68030); - uae_restart (-1, NULL); - } else if ((rd->cpu & 3) == 1 && changed_prefs.cpu_model < 68020) { - notify_user (NUMSG_KS68EC020); - uae_restart (-1, NULL); - } else if ((rd->cpu & 3) == 2 && (changed_prefs.cpu_model < 68020 || changed_prefs.address_space_24)) { - notify_user (NUMSG_KS68020); - uae_restart (-1, NULL); - } - if (rd->cloanto) - cloanto_rom = 1; - kickstart_rom = 0; - if ((rd->type & (ROMTYPE_SPECIALKICK | ROMTYPE_KICK)) == ROMTYPE_KICK) - kickstart_rom = 1; - } else { - write_log (_T("Unknown ROM '%s' loaded\n"), currprefs.romfile); - } - } - patch_kick (); - write_log (_T("ROM loader end\n")); - protect_roms (true); - } + if ((cloanto_rom || extendedkickmem_bank.allocated_size) && currprefs.maprom && currprefs.maprom < 0x01000000) { + currprefs.maprom = changed_prefs.maprom = 0x00a80000; + if (extendedkickmem2_bank.allocated_size) // can't do if 2M ROM + currprefs.maprom = changed_prefs.maprom = 0; + } - map_banks (&custom_bank, 0xC0, 0xE0 - 0xC0, 0); - map_banks (&cia_bank, 0xA0, 32, 0); + map_banks(&custom_bank, 0xC0, 0xE0 - 0xC0, 0); + map_banks(&cia_bank, 0xA0, 32, 0); + if (!currprefs.cs_a1000ram && currprefs.cs_rtc != 3) + /* D80000 - DDFFFF not mapped (A1000 or A2000 = custom chips) */ + map_banks(&dummy_bank, 0xD8, 6, 0); - /* D80000 - DDFFFF not mapped (A1000 or A2000 = custom chips) */ - map_banks (&dummy_bank, 0xD8, 6, 0); + /* map "nothing" to 0x200000 - 0x9FFFFF (0xBEFFFF if Gayle or Fat Gary) */ + bnk = chipmem_bank.allocated_size >> 16; + if (bnk < 0x20 + (currprefs.fastmem[0].size >> 16)) + bnk = 0x20 + (currprefs.fastmem[0].size >> 16); + bnk_end = currprefs.cs_cd32cd ? 0xBE : (gayleorfatgary ? 0xBF : 0xA0); + map_banks(&dummy_bank, bnk, bnk_end - bnk, 0); + if (gayleorfatgary) { + // a3000 or a4000 = custom chips from 0xc0 to 0xd0 + if (currprefs.cs_ide == IDE_A4000 || currprefs.cs_mbdmac) + map_banks(&dummy_bank, 0xd0, 8, 0); + else + map_banks(&dummy_bank, 0xc0, 0xd8 - 0xc0, 0); + } + else if (currprefs.cs_cd32cd) { + // CD32: 0xc0 to 0xd0 + map_banks(&dummy_bank, 0xd0, 8, 0); + // strange 64k custom mirror + map_banks(&custom_bank, 0xb9, 1, 0); + } - /* map "nothing" to 0x200000 - 0x9FFFFF (0xBEFFFF if Gayle or Fat Gary) */ - bnk = chipmem_bank.allocated >> 16; - if (bnk < 0x20 + (currprefs.fastmem_size >> 16)) - bnk = 0x20 + (currprefs.fastmem_size >> 16); - bnk_end = gayleorfatgary ? 0xBF : 0xA0; - map_banks (&dummy_bank, bnk, bnk_end - bnk, 0); - if (gayleorfatgary) { - // a3000 or a4000 = custom chips from 0xc0 to 0xd0 - map_banks (&dummy_bank, 0xc0, 0xd8 - 0xc0, 0); - } - - if (bogomem_bank.baseaddr) { - int t = currprefs.bogomem_size >> 16; - if (t > 0x1C) - t = 0x1C; - if (t > 0x18 && ((currprefs.chipset_mask & CSMASK_AGA) || (currprefs.cpu_model >= 68020 && !currprefs.address_space_24))) - t = 0x18; - map_banks (&bogomem_bank, 0xC0, t, 0); - } - map_banks (&clock_bank, 0xDC, 1, 0); + if (bogomem_bank.baseaddr) { + int t = currprefs.bogomem_size >> 16; + if (t > 0x1C) + t = 0x1C; + if (t > 0x18 && ((currprefs.chipset_mask & CSMASK_AGA) || (currprefs.cpu_model >= 68020 && !currprefs.address_space_24))) + t = 0x18; + if (bogomem_aliasing == 2) + map_banks(&bogomem_bank, 0x08, t, 0); + else + map_banks(&bogomem_bank, 0xC0, t, 0); + } + //if (currprefs.cs_ide || currprefs.cs_pcmcia) { + // if (currprefs.cs_ide == IDE_A600A1200 || currprefs.cs_pcmcia) { + // map_banks(&gayle_bank, 0xD8, 6, 0); + // map_banks(&gayle2_bank, 0xDD, 2, 0); + // } + // //gayle_map_pcmcia(); + // if (currprefs.cs_ide == IDE_A4000 || is_device_rom(&currprefs, ROMTYPE_SCSI_A4000T, 0)) + // map_banks(&gayle_bank, 0xDD, 1, 0); + // if (currprefs.cs_ide < 0 && !currprefs.cs_pcmcia) + // map_banks(&gayle_bank, 0xD8, 6, 0); + // if (currprefs.cs_ide < 0) + // map_banks(&gayle_bank, 0xDD, 1, 0); + //} + if (currprefs.cs_rtc == 3) // A2000 clock + map_banks(&clock_bank, 0xD8, 4, 0); + if (currprefs.cs_rtc == 1 || currprefs.cs_rtc == 2 || currprefs.cs_cdtvram) + map_banks(&clock_bank, 0xDC, 1, 0); + else if (currprefs.cs_ksmirror_a8 || currprefs.cs_ide > 0 || currprefs.cs_pcmcia) + map_banks(&clock_bank, 0xDC, 1, 0); /* none clock */ + //if (currprefs.cs_fatgaryrev >= 0 || currprefs.cs_ramseyrev >= 0) + // map_banks(&mbres_bank, 0xDE, 1, 0); #ifdef CD32 - if (currprefs.cs_cd32c2p || currprefs.cs_cd32cd || currprefs.cs_cd32nvram) { - map_banks (&akiko_bank, AKIKO_BASE >> 16, 1, 0); + //if (currprefs.cs_cd32c2p || currprefs.cs_cd32cd || currprefs.cs_cd32nvram) { + // map_banks(&akiko_bank, AKIKO_BASE >> 16, 1, 0); + // map_banks(&gayle2_bank, 0xDD, 2, 0); + //} +#endif + if (mem25bit_bank.baseaddr) + map_banks(&mem25bit_bank, mem25bit_bank.start >> 16, mem25bit_bank.allocated_size >> 16, 0); + if (a3000lmem_bank.baseaddr) + map_banks(&a3000lmem_bank, a3000lmem_bank.start >> 16, a3000lmem_bank.allocated_size >> 16, 0); + if (a3000hmem_bank.baseaddr) + map_banks(&a3000hmem_bank, a3000hmem_bank.start >> 16, a3000hmem_bank.allocated_size >> 16, 0); +#ifdef CDTV + if (cardmem_bank.baseaddr) + map_banks(&cardmem_bank, cardmem_bank.start >> 16, cardmem_bank.allocated_size >> 16, 0); +#endif + //cpuboard_map(); + map_banks_set(&kickmem_bank, 0xF8, 8, 0); + if (currprefs.maprom) { + //if (!cpuboard_maprom()) + map_banks_set(&kickram_bank, currprefs.maprom >> 16, extendedkickmem2_bank.allocated_size ? 32 : (extendedkickmem_bank.allocated_size ? 16 : 8), 0); + } + /* map beta Kickstarts at 0x200000/0xC00000/0xF00000 */ + if (kickmem_bank.baseaddr[0] == 0x11 && kickmem_bank.baseaddr[2] == 0x4e && kickmem_bank.baseaddr[3] == 0xf9 && kickmem_bank.baseaddr[4] == 0x00) { + uae_u32 addr = kickmem_bank.baseaddr[5]; + if (addr == 0x20 && currprefs.chipmem_size <= 0x200000 && currprefs.fastmem[0].size == 0) + map_banks_set(&kickmem_bank, addr, 8, 0); + if (addr == 0xC0 && currprefs.bogomem_size == 0) + map_banks_set(&kickmem_bank, addr, 8, 0); + if (addr == 0xF0) + map_banks_set(&kickmem_bank, addr, 8, 0); + } + + if (a1000_bootrom) + a1000_handle_kickstart(1); + +#ifdef AUTOCONFIG + expansion_map(); +#endif + + if (a3000_f0) + map_banks_set(&extendedkickmem_bank, 0xf0, 1, 0); + + /* Map the chipmem into all of the lower 8MB */ + map_overlay(1); + + switch (extendedkickmem_type) { + case EXTENDED_ROM_KS: + map_banks_set(&extendedkickmem_bank, 0xE0, 8, 0); + break; +#ifdef CDTV + case EXTENDED_ROM_CDTV: + map_banks_set(&extendedkickmem_bank, 0xF0, extendedkickmem_bank.allocated_size == 2 * ROM_SIZE_512 ? 16 : 8, 0); + break; +#endif +#ifdef CD32 + case EXTENDED_ROM_CD32: + map_banks_set(&extendedkickmem_bank, 0xE0, 8, 0); + break; +#endif + case EXTENDED_ROM_ALG: + map_banks_set(&extendedkickmem_bank, 0xF0, 4, 0); + //alg_map_banks(); + break; + } + +#ifdef AUTOCONFIG + if (need_uae_boot_rom(&currprefs) && currprefs.uaeboard < 2) + map_banks_set(&rtarea_bank, rtarea_base >> 16, 1, 0); +#endif + + if ((cloanto_rom || currprefs.cs_ksmirror_e0) && (currprefs.maprom != 0xe00000) && !extendedkickmem_type) { + map_banks(&kickmem_bank, 0xE0, 8, 0); + } + if (currprefs.cs_ksmirror_a8) { + if (extendedkickmem2_bank.allocated_size) { + map_banks_set(&extendedkickmem2_bank, 0xa8, 16, 0); + } + else { + struct romdata *rd = getromdatabypath(currprefs.cartfile); + if (!rd || rd->id != 63) { + if (extendedkickmem_type == EXTENDED_ROM_CD32 || extendedkickmem_type == EXTENDED_ROM_KS) + map_banks(&extendedkickmem_bank, 0xb0, 8, 0); + else + map_banks(&kickmem_bank, 0xb0, 8, 0); + map_banks(&kickmem_bank, 0xa8, 8, 0); + } + } + } + +#ifdef ARCADIA + if (is_arcadia_rom(currprefs.romextfile) == ARCADIA_BIOS) { + if (_tcscmp(currprefs.romextfile, changed_prefs.romextfile) != 0) + memcpy(currprefs.romextfile, changed_prefs.romextfile, sizeof currprefs.romextfile); + if (_tcscmp(currprefs.cartfile, changed_prefs.cartfile) != 0) + memcpy(currprefs.cartfile, changed_prefs.cartfile, sizeof currprefs.cartfile); + arcadia_unmap(); + is_arcadia_rom(currprefs.romextfile); + is_arcadia_rom(currprefs.cartfile); + arcadia_map_banks(); } #endif - map_banks (&kickmem_bank, 0xF8, 8, 0); - /* map beta Kickstarts at 0x200000/0xC00000/0xF00000 */ - if (kickmem_bank.baseaddr[0] == 0x11 && kickmem_bank.baseaddr[2] == 0x4e && kickmem_bank.baseaddr[3] == 0xf9 && kickmem_bank.baseaddr[4] == 0x00) { - uae_u32 addr = kickmem_bank.baseaddr[5]; - if (addr == 0x20 && chipmem_bank.allocated <= 0x200000 && fastmem_bank.allocated == 0) - map_banks (&kickmem_bank, addr, 8, 0); - if (addr == 0xC0 && bogomem_bank.allocated == 0) - map_banks (&kickmem_bank, addr, 8, 0); - if (addr == 0xF0) - map_banks (&kickmem_bank, addr, 8, 0); - } - -#ifdef AUTOCONFIG - map_banks (&expamem_bank, 0xE8, 1, 0); +#ifdef ACTION_REPLAY +#ifdef ARCADIA + if (!arcadia_bios) { +#endif + action_replay_memory_reset(); +#ifdef ARCADIA + } +#endif #endif - /* Map the chipmem into all of the lower 8MB */ - map_overlay (1); - - switch (extendedkickmem_type) { - case EXTENDED_ROM_KS: - map_banks (&extendedkickmem_bank, 0xE0, 8, 0); - break; -#ifdef CD32 - case EXTENDED_ROM_CD32: - map_banks (&extendedkickmem_bank, 0xE0, 8, 0); - break; -#endif - } -#ifdef AUTOCONFIG - if (need_uae_boot_rom ()) - map_banks (&rtarea_bank, rtarea_base >> 16, 1, 0); -#endif - - if ((cloanto_rom) && !extendedkickmem_type) - map_banks (&kickmem_bank, 0xE0, 8, 0); - - if (currprefs.chipset_mask & CSMASK_AGA) { - if (extendedkickmem_type == EXTENDED_ROM_CD32 || extendedkickmem_type == EXTENDED_ROM_KS) - map_banks (&extendedkickmem_bank, 0xb0, 8, 0); - else - map_banks (&kickmem_bank, 0xb0, 8, 0); - map_banks (&kickmem_bank, 0xa8, 8, 0); + for (int i = 0; i < 2; i++) { + if (currprefs.custom_memory_sizes[i]) { + map_banks(i == 0 ? &custmem1_bank : &custmem2_bank, + currprefs.custom_memory_addrs[i] >> 16, + currprefs.custom_memory_sizes[i] >> 16, 0); + if (currprefs.custom_memory_mask[i]) { + for (int j = currprefs.custom_memory_addrs[i]; j & currprefs.custom_memory_mask[i]; j += currprefs.custom_memory_sizes[i]) { + map_banks(i == 0 ? &custmem1_bank : &custmem2_bank, j >> 16, currprefs.custom_memory_sizes[i] >> 16, 0); + } + } + } } if (mem_hardreset) { - memory_clear (); + memory_clear(); } - write_log (_T("memory init end\n")); + write_log(_T("memory init end\n")); } -void memory_init (void) +void memory_init(void) { - init_mem_banks (); - virtualdevice_init (); + init_mem_banks(); + virtualdevice_init(); - chipmem_bank.allocated = 0; - bogomem_bank.allocated = 0; - kickmem_bank.baseaddr = NULL; - extendedkickmem_bank.baseaddr = NULL; - extendedkickmem_bank.allocated = 0; - extendedkickmem2_bank.baseaddr = NULL; - extendedkickmem2_bank.allocated = 0; - extendedkickmem_type = 0; - chipmem_bank.baseaddr = 0; - bogomem_bank.baseaddr = NULL; + chipmem_bank.reserved_size = 0; + bogomem_bank.reserved_size = 0; + kickmem_bank.baseaddr = NULL; + extendedkickmem_bank.baseaddr = NULL; + extendedkickmem_bank.reserved_size = 0; + extendedkickmem2_bank.baseaddr = NULL; + extendedkickmem2_bank.reserved_size = 0; + extendedkickmem_type = 0; + chipmem_bank.baseaddr = 0; + mem25bit_bank.reserved_size = mem25bit_bank.reserved_size = 0; + a3000lmem_bank.reserved_size = a3000hmem_bank.reserved_size = 0; + a3000lmem_bank.baseaddr = a3000hmem_bank.baseaddr = NULL; + bogomem_bank.baseaddr = NULL; + cardmem_bank.baseaddr = NULL; + custmem1_bank.reserved_size = custmem2_bank.reserved_size = 0; + custmem1_bank.baseaddr = NULL; + custmem2_bank.baseaddr = NULL; - kickmem_bank.baseaddr = mapped_malloc (ROM_SIZE_512, _T("kick")); - memset (kickmem_bank.baseaddr, 0, ROM_SIZE_512); - _tcscpy (currprefs.romfile, _T("")); - currprefs.romextfile[0] = 0; + kickmem_bank.reserved_size = ROM_SIZE_512; + mapped_malloc(&kickmem_bank); + memset(kickmem_bank.baseaddr, 0, ROM_SIZE_512); + _tcscpy(currprefs.romfile, _T("")); + currprefs.romextfile[0] = 0; + //cpuboard_reset(); + +#ifdef ACTION_REPLAY + action_replay_unload(0); + action_replay_load(); + action_replay_init(1); +#ifdef ACTION_REPLAY_HRTMON + hrtmon_load(); +#endif +#endif } -void memory_cleanup (void) +void memory_cleanup(void) { - mapped_free (bogomem_bank.baseaddr); - mapped_free (kickmem_bank.baseaddr); - mapped_free (chipmem_bank.baseaddr); - mapped_free (extendedkickmem_bank.baseaddr); - mapped_free (extendedkickmem2_bank.baseaddr); - - bogomem_bank.baseaddr = NULL; - kickmem_bank.baseaddr = NULL; - chipmem_bank.baseaddr = NULL; - extendedkickmem_bank.baseaddr = NULL; - extendedkickmem2_bank.baseaddr = NULL; - - init_mem_banks (); + mapped_free(&mem25bit_bank); + mapped_free(&a3000lmem_bank); + mapped_free(&a3000hmem_bank); + mapped_free(&bogomem_bank); + mapped_free(&kickmem_bank); + xfree(a1000_bootrom); + mapped_free(&chipmem_bank); +#ifdef CDTV + if (cardmem_bank.baseaddr) { + cdtv_savecardmem(cardmem_bank.baseaddr, cardmem_bank.allocated_size); + mapped_free(&cardmem_bank); + } +#endif + mapped_free(&custmem1_bank); + mapped_free(&custmem2_bank); + + bogomem_bank.baseaddr = NULL; + kickmem_bank.baseaddr = NULL; + mem25bit_bank.baseaddr = NULL; + a3000lmem_bank.baseaddr = a3000hmem_bank.baseaddr = NULL; + a1000_bootrom = NULL; + a1000_kickstart_mode = 0; + chipmem_bank.baseaddr = NULL; + cardmem_bank.baseaddr = NULL; + custmem1_bank.baseaddr = NULL; + custmem2_bank.baseaddr = NULL; + + //cpuboard_cleanup(); +#ifdef ACTION_REPLAY + action_replay_cleanup(); +#endif +#ifdef ARCADIA + arcadia_unmap(); +#endif } -void memory_hardreset (int mode) +void set_roms_modified(void) +{ + roms_modified = true; +} + +void memory_hardreset(int mode) { if (mode + 1 > mem_hardreset) mem_hardreset = mode + 1; } -static void map_banks2 (addrbank *bank, int start, int size, int realsize, int quick) +// do not map if it conflicts with custom banks +void map_banks_cond(addrbank *bank, int start, int size, int realsize) { - int bnr; - unsigned long int hioffs = 0, endhioffs = 0x100; - addrbank *orgbank = bank; - uae_u32 realstart = start; + for (int i = 0; i < MAX_CUSTOM_MEMORY_ADDRS; i++) { + int cstart = currprefs.custom_memory_addrs[i] >> 16; + if (!cstart) + continue; + int csize = currprefs.custom_memory_sizes[i] >> 16; + if (!csize) + continue; + if (start <= cstart && start + size >= cstart) + return; + if (cstart <= start && (cstart + size >= start || start + size > cstart)) + return; + } + map_banks(bank, start, size, realsize); +} - flush_icache (0, 3); /* Sure don't want to keep any old mappings around! */ +#ifdef WITH_THREADED_CPU - if (!realsize) - realsize = size << 16; +struct addrbank_thread { + Addrbank *orig; + Addrbank ab; +}; - if ((size << 16) < realsize) { - write_log (_T("Broken mapping, size=%x, realsize=%x\nStart is %x\n"), - size, realsize, start); - } +#define MAX_THREAD_BANKS 200 +static addrbank_thread *thread_banks[MAX_THREAD_BANKS]; +static Addrbank *thread_mem_banks[MEMORY_BANKS]; +static int thread_banks_used; + +static void REGPARAM2 threadcpu_lput(uaecptr addr, uae_u32 l) +{ + cpu_semaphore_get(); + thread_mem_banks[bankindex(addr)]->lput(addr, l); + cpu_semaphore_release(); +} + +static void REGPARAM2 threadcpu_wput(uaecptr addr, uae_u32 w) +{ + cpu_semaphore_get(); + thread_mem_banks[bankindex(addr)]->wput(addr, w); + cpu_semaphore_release(); +} + +static void REGPARAM2 threadcpu_bput(uaecptr addr, uae_u32 b) +{ + cpu_semaphore_get(); + thread_mem_banks[bankindex(addr)]->bput(addr, b); + cpu_semaphore_release(); +} +static uae_u32 REGPARAM2 threadcpu_lget(uaecptr addr) +{ + cpu_semaphore_get(); + uae_u32 v = thread_mem_banks[bankindex(addr)]->lget(addr); + cpu_semaphore_release(); + return v; +} +static uae_u32 REGPARAM2 threadcpu_wget(uaecptr addr) +{ + cpu_semaphore_get(); + uae_u32 v = thread_mem_banks[bankindex(addr)]->wget(addr); + cpu_semaphore_release(); + return v; +} +uae_u32 REGPARAM2 threadcpu_bget(uaecptr addr) +{ + cpu_semaphore_get(); + uae_u32 v = thread_mem_banks[bankindex(addr)]->bget(addr); + cpu_semaphore_release(); + return v; +} + +static Addrbank *get_bank_cpu_thread(Addrbank *bank) +{ + if (bank->flags & ABFLAG_THREADSAFE) + return bank; + if (bank == &dummy_bank) + return bank; + + for (int i = 0; i < thread_banks_used; i++) { + if (thread_banks[i]->orig == bank) { + return &thread_banks[i]->ab; + } + } + struct addrbank_thread *at = thread_banks[thread_banks_used]; + if (!at) + at = xcalloc(addrbank_thread, 1); + thread_banks[thread_banks_used++] = at; + at->orig = bank; + memcpy(&at->ab, bank, sizeof Addrbank); + Addrbank *tb = &at->ab; + tb->lget = threadcpu_lget; + tb->wget = threadcpu_wget; + tb->bget = threadcpu_bget; + tb->lput = threadcpu_lput; + tb->wput = threadcpu_wput; + tb->bput = threadcpu_bput; + // wgeti/lgeti should always point to real RAM + return tb; +} +#endif + +static void map_banks2(addrbank *bank, int start, int size, int realsize, int quick) +{ + int bnr, old; + unsigned long int hioffs = 0, endhioffs = 0x100; + uae_u32 realstart = start; + addrbank *orig_bank = NULL; + +#ifdef WITH_THREADED_CPU + if (currprefs.cpu_thread) { + Addrbank *b = bank; + bank = get_bank_cpu_thread(bank); + if (b != bank) + orig_bank = b; + } +#endif + + //if (quick <= 0) + // old = debug_bankchange(-1); + flush_icache_hard(0, 3); /* Sure don't want to keep any old mappings around! */ +#ifdef NATMEM_OFFSET + if (!quick) + delete_shmmaps(start << 16, size << 16); +#endif + + if (!realsize) + realsize = size << 16; + + if ((size << 16) < realsize) { + write_log(_T("Broken mapping, size=%x, realsize=%x\nStart is %x\n"), + size, realsize, start); + } #ifndef ADDRESS_SPACE_24BIT - if (start >= 0x100) { - for (bnr = start; bnr < start + size; bnr++) { - mem_banks[bnr] = bank; - } - return; - } + if (start >= 0x100) { + int real_left = 0; + for (bnr = start; bnr < start + size; bnr++) { + if (!real_left) { + realstart = bnr; + real_left = realsize >> 16; +#ifdef NATMEM_OFFSET + if (!quick) + add_shmmaps(realstart << 16, bank); #endif - if (last_address_space_24) - endhioffs = 0x10000; + } + put_mem_bank(bnr << 16, bank, realstart << 16); +#ifdef WITH_THREADED_CPU + if (currprefs.cpu_thread) { + if (orig_bank) + put_mem_bank(bnr << 16, orig_bank, realstart << 16); + thread_mem_banks[bnr] = orig_bank; + } +#endif + real_left--; + } + //if (quick <= 0) + // debug_bankchange(old); + return; + } +#endif + if (last_address_space_24) + endhioffs = 0x10000; #ifdef ADDRESS_SPACE_24BIT - endhioffs = 0x100; + endhioffs = 0x100; #endif - for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) { - for (bnr = start; bnr < start + size; bnr++) { - mem_banks[bnr + hioffs] = bank; - } - } + for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) { + int real_left = 0; + for (bnr = start; bnr < start + size; bnr++) { + if (!real_left) { + realstart = bnr + hioffs; + real_left = realsize >> 16; +#ifdef NATMEM_OFFSET + if (!quick) + add_shmmaps(realstart << 16, bank); +#endif + } + put_mem_bank((bnr + hioffs) << 16, bank, realstart << 16); +#ifdef WITH_THREADED_CPU + if (currprefs.cpu_thread) { + if (orig_bank) + put_mem_bank((bnr + hioffs) << 16, bank, realstart << 16); + thread_mem_banks[bnr + hioffs] = orig_bank; + } +#endif + real_left--; + } + } + //if (quick <= 0) + // debug_bankchange(old); + fill_ce_banks(); } -void map_banks (addrbank *bank, int start, int size, int realsize) +static addrbank *highram_temp_bank[65536 - 0x100]; + +void restore_banks(void) { - map_banks2 (bank, start, size, realsize, 0); + for (int bnr = 0x100; bnr < 65536; bnr++) { + if (highram_temp_bank[bnr - 0x100]) { + map_banks(highram_temp_bank[bnr - 0x100], bnr, 1, 0); + } + else { + map_banks(&dummy_bank, bnr, 1, 0); + } + } } -void map_banks_quick (addrbank *bank, int start, int size, int realsize) + +void map_banks(addrbank *bank, int start, int size, int realsize) { - map_banks2 (bank, start, size, realsize, 1); + if (start == 0xffffffff) + return; + if (start >= 0x100) { + int real_left = 0; + for (int bnr = start; bnr < start + size; bnr++) { + highram_temp_bank[bnr - 0x100] = bank; + } + if (currprefs.address_space_24) + return; + } + map_banks2(bank, start, size, realsize, 0); +#ifdef WITH_PPC + ppc_generate_map_banks(bank, start, size); +#endif +} + +bool validate_banks_z3(addrbank *bank, int start, int size) +{ + if (start < 0x1000 || size <= 0) { + error_log(_T("Z3 invalid map_banks(%s) start=%08x size=%08x\n"), bank->name, start << 16, size << 16); + cpu_halt(7); + return false; + } + if (size > 0x4000 || start + size > 0xf000) { + error_log(_T("Z3 invalid map_banks(%s) start=%08x size=%08x\n"), bank->name, start << 16, size << 16); + return false; + } + for (int i = start; i < start + size; i++) { + addrbank *ab = &get_mem_bank(start << 16); + if (ab != &dummy_bank && ab != bank) { + error_log(_T("Z3 map_banks(%s) attempting to override existing memory bank '%s' at %08x!\n"), bank->name, ab->name, i << 16); + return false; + } + } + return true; +} + +void map_banks_z3(addrbank *bank, int start, int size) +{ + if (!validate_banks_z3(bank, start, size)) + return; + map_banks(bank, start, size, 0); +} + +bool validate_banks_z2(addrbank *bank, int start, int size) +{ + if (start < 0x20 || (start >= 0xa0 && start < 0xe9) || start >= 0xf0) { + error_log(_T("Z2 map_banks(%s) with invalid start address %08X\n"), bank->name, start << 16); + cpu_halt(7); + return false; + } + if (start >= 0xe9) { + if (start + size > 0xf0) { + error_log(_T("Z2 map_banks(%s) with invalid region %08x - %08X\n"), bank->name, start << 16, (start + size) << 16); + cpu_halt(7); + return false; + } + } + else { + if (start + size > 0xa0) { + error_log(_T("Z2 map_banks(%s) with invalid region %08x - %08X\n"), bank->name, start << 16, (start + size) << 16); + cpu_halt(7); + return false; + } + } + if (size <= 0 || size > 0x80) { + error_log(_T("Z2 map_banks(%s) with invalid size %08x\n"), bank->name, size); + cpu_halt(7); + return false; + } + for (int i = start; i < start + size; i++) { + addrbank *ab = &get_mem_bank(start << 16); + if (ab != &dummy_bank) { + error_log(_T("Z2 map_banks(%s) attempting to override existing memory bank '%s' at %08x!\n"), bank->name, ab->name, i << 16); + return false; + } + } + return true; +} + + +void map_banks_z2(addrbank *bank, int start, int size) +{ + if (!validate_banks_z2(bank, start, size)) + return; + map_banks(bank, start, size, 0); +} + +uae_u32 map_banks_z2_autosize(addrbank *bank, int start) +{ + uae_u32 size = expansion_board_size(bank); + if (!size) { + error_log(_T("Z2 map_banks(%s) %08x, invalid size!\n"), bank->name, start << 16); + return 0; + } + map_banks_z2(bank, start, size >> 16); + return size; +} + +void map_banks_quick(addrbank *bank, int start, int size, int realsize) +{ + map_banks2(bank, start, size, realsize, 1); +#ifdef WITH_PPC + ppc_generate_map_banks(bank, start, size); +#endif +} +void map_banks_nojitdirect(addrbank *bank, int start, int size, int realsize) +{ + map_banks2(bank, start, size, realsize, -1); +#ifdef WITH_PPC + ppc_generate_map_banks(bank, start, size); +#endif } #ifdef SAVESTATE @@ -1132,228 +2942,258 @@ void map_banks_quick (addrbank *bank, int start, int size, int realsize) uae_u8 *save_bootrom(int *len) { - if (!uae_boot_rom) - return 0; - *len = uae_boot_rom_size; - return rtarea; + if (!uae_boot_rom_type) + return 0; + *len = uae_boot_rom_size; + return rtarea_bank.baseaddr; } -uae_u8 *save_cram (int *len) +uae_u8 *save_cram(int *len) { - *len = chipmem_bank.allocated; - return chipmem_bank.baseaddr; + *len = chipmem_bank.allocated_size; + return chipmem_bank.baseaddr; } -uae_u8 *save_bram (int *len) +uae_u8 *save_bram(int *len) { - *len = bogomem_bank.allocated; - return bogomem_bank.baseaddr; + *len = bogomem_bank.allocated_size; + return bogomem_bank.baseaddr; } -void restore_bootrom (int len, size_t filepos) +static uae_u8 *save_mem25bitram(int *len) { - bootrom_filepos = filepos; + *len = mem25bit_bank.allocated_size; + return mem25bit_bank.baseaddr; } -void restore_cram (int len, size_t filepos) +uae_u8 *save_a3000lram(int *len) { - chip_filepos = filepos; - changed_prefs.chipmem_size = len; + *len = a3000lmem_bank.allocated_size; + return a3000lmem_bank.baseaddr; } -void restore_bram (int len, size_t filepos) +uae_u8 *save_a3000hram(int *len) { - bogo_filepos = filepos; - changed_prefs.bogomem_size = len; + *len = a3000hmem_bank.allocated_size; + return a3000hmem_bank.baseaddr; } -uae_u8 *restore_rom (uae_u8 *src) +void restore_bootrom(int len, size_t filepos) { - uae_u32 crc32, mem_start, mem_size, mem_type, version; - TCHAR *s, *romn; - int i, crcdet; - struct romlist *rl = romlist_getit (); + bootrom_filepos = filepos; +} - mem_start = restore_u32 (); - mem_size = restore_u32 (); - mem_type = restore_u32 (); - version = restore_u32 (); - crc32 = restore_u32 (); - romn = restore_string (); - crcdet = 0; - for (i = 0; i < romlist_count (); i++) { - if (rl[i].rd->crc32 == crc32 && crc32) { - if (zfile_exists (rl[i].path)) { - switch (mem_type) - { - case 0: - _tcsncpy (changed_prefs.romfile, rl[i].path, 255); - break; - case 1: - _tcsncpy (changed_prefs.romextfile, rl[i].path, 255); - break; - } - write_log (_T("ROM '%s' = '%s'\n"), romn, rl[i].path); - crcdet = 1; - } else { - write_log (_T("ROM '%s' = '%s' invalid rom scanner path!"), romn, rl[i].path); - } - break; - } - } - s = restore_string (); - if (!crcdet) { - if(zfile_exists (s)) { - switch (mem_type) - { - case 0: - _tcsncpy (changed_prefs.romfile, s, 255); - break; - case 1: - _tcsncpy (changed_prefs.romextfile, s, 255); - break; - } - write_log (_T("ROM detected (path) as '%s'\n"), s); - crcdet = 1; - } - } - xfree (s); - if (!crcdet) - write_log (_T("WARNING: ROM '%s' %d.%d (CRC32=%08x %08x-%08x) not found!\n"), +void restore_cram(int len, size_t filepos) +{ + chip_filepos = filepos; + changed_prefs.chipmem_size = len; +} + +void restore_bram(int len, size_t filepos) +{ + bogo_filepos = filepos; + changed_prefs.bogomem_size = len; +} + +void restore_a3000lram(int len, size_t filepos) +{ + a3000lmem_filepos = filepos; + changed_prefs.mbresmem_low_size = len; +} + +void restore_a3000hram(int len, size_t filepos) +{ + a3000hmem_filepos = filepos; + changed_prefs.mbresmem_high_size = len; +} + +uae_u8 *restore_rom(uae_u8 *src) +{ + uae_u32 crc32, mem_start, mem_size, mem_type, version; + TCHAR *s, *romn; + int i, crcdet; + struct romlist *rl = romlist_getit(); + + mem_start = restore_u32(); + mem_size = restore_u32(); + mem_type = restore_u32(); + version = restore_u32(); + crc32 = restore_u32(); + romn = restore_string(); + crcdet = 0; + for (i = 0; i < romlist_count(); i++) { + if (rl[i].rd->crc32 == crc32 && crc32) { + if (zfile_exists(rl[i].path)) { + switch (mem_type) + { + case 0: + _tcsncpy(changed_prefs.romfile, rl[i].path, 255); + break; + case 1: + _tcsncpy(changed_prefs.romextfile, rl[i].path, 255); + break; + } + write_log(_T("ROM '%s' = '%s'\n"), romn, rl[i].path); + crcdet = 1; + } + else { + write_log(_T("ROM '%s' = '%s' invalid rom scanner path!"), romn, rl[i].path); + } + break; + } + } + s = restore_string(); + if (!crcdet) { + if (zfile_exists(s)) { + switch (mem_type) + { + case 0: + _tcsncpy(changed_prefs.romfile, s, 255); + break; + case 1: + _tcsncpy(changed_prefs.romextfile, s, 255); + break; + } + write_log(_T("ROM detected (path) as '%s'\n"), s); + crcdet = 1; + } + } + xfree(s); + if (!crcdet) + write_log(_T("WARNING: ROM '%s' %d.%d (CRC32=%08x %08x-%08x) not found!\n"), romn, version >> 16, version & 0xffff, crc32, mem_start, mem_start + mem_size - 1); - xfree (romn); - - return src; + xfree(romn); + return src; } -uae_u8 *save_rom (int first, int *len, uae_u8 *dstptr) +uae_u8 *save_rom(int first, int *len, uae_u8 *dstptr) { - static int count; - uae_u8 *dst, *dstbak; - uae_u8 *mem_real_start; - uae_u32 version; - TCHAR *path; - int mem_start, mem_size, mem_type, saverom; - int i; - TCHAR tmpname[1000]; + static int count; + uae_u8 *dst, *dstbak; + uae_u8 *mem_real_start; + uae_u32 version; + TCHAR *path; + int mem_start, mem_size, mem_type, saverom; + int i; + TCHAR tmpname[1000]; - version = 0; - saverom = 0; - if (first) - count = 0; - for (;;) { - mem_type = count; - mem_size = 0; - switch (count) { - case 0: /* Kickstart ROM */ - mem_start = 0xf80000; - mem_real_start = kickmem_bank.baseaddr; - mem_size = kickmem_bank.allocated; - path = currprefs.romfile; - /* 256KB or 512KB ROM? */ - for (i = 0; i < mem_size / 2 - 4; i++) { - if (longget (i + mem_start) != longget (i + mem_start + mem_size / 2)) - break; - } - if (i == mem_size / 2 - 4) { - mem_size /= 2; - mem_start += ROM_SIZE_256; - } - version = longget (mem_start + 12); /* version+revision */ - _stprintf (tmpname, _T("Kickstart %d.%d"), wordget (mem_start + 12), wordget (mem_start + 14)); - break; - case 1: /* Extended ROM */ - if (!extendedkickmem_type) - break; - mem_start = extendedkickmem_bank.start; - mem_real_start = extendedkickmem_bank.baseaddr; - mem_size = extendedkickmem_bank.allocated; - path = currprefs.romextfile; - version = longget (mem_start + 12); /* version+revision */ + version = 0; + saverom = 0; + if (first) + count = 0; + for (;;) { + mem_type = count; + mem_size = 0; + switch (count) { + case 0: /* Kickstart ROM */ + mem_start = 0xf80000; + mem_real_start = kickmem_bank.baseaddr; + mem_size = kickmem_bank.allocated_size; + path = currprefs.romfile; + /* 256KB or 512KB ROM? */ + for (i = 0; i < mem_size / 2 - 4; i++) { + if (longget(i + mem_start) != longget(i + mem_start + mem_size / 2)) + break; + } + if (i == mem_size / 2 - 4) { + mem_size /= 2; + mem_start += ROM_SIZE_256; + } + version = longget(mem_start + 12); /* version+revision */ + _stprintf(tmpname, _T("Kickstart %d.%d"), wordget(mem_start + 12), wordget(mem_start + 14)); + break; + case 1: /* Extended ROM */ + if (!extendedkickmem_type) + break; + mem_start = extendedkickmem_bank.start; + mem_real_start = extendedkickmem_bank.baseaddr; + mem_size = extendedkickmem_bank.allocated_size; + path = currprefs.romextfile; + version = longget(mem_start + 12); /* version+revision */ if (version == 0xffffffff) - version = longget (mem_start + 16); - _stprintf (tmpname, _T("Extended")); - break; - default: - return 0; - } - count++; - if (mem_size) - break; - } - if (dstptr) - dstbak = dst = dstptr; - else - dstbak = dst = xmalloc (uae_u8, 4 + 4 + 4 + 4 + 4 + 256 + 256 + mem_size); - save_u32 (mem_start); - save_u32 (mem_size); - save_u32 (mem_type); - save_u32 (version); - save_u32 (get_crc32 (mem_real_start, mem_size)); - save_string (tmpname); - save_string (path); - if (saverom) { - for (i = 0; i < mem_size; i++) - *dst++ = byteget (mem_start + i); - } - *len = dst - dstbak; - return dstbak; + version = longget(mem_start + 16); + _stprintf(tmpname, _T("Extended")); + break; + default: + return 0; + } + count++; + if (mem_size) + break; + } + if (dstptr) + dstbak = dst = dstptr; + else + dstbak = dst = xmalloc(uae_u8, 4 + 4 + 4 + 4 + 4 + 256 + 256 + mem_size); + save_u32(mem_start); + save_u32(mem_size); + save_u32(mem_type); + save_u32(version); + save_u32(get_crc32(mem_real_start, mem_size)); + save_string(tmpname); + save_string(path); + if (saverom) { + for (i = 0; i < mem_size; i++) + *dst++ = byteget(mem_start + i); + } + *len = dst - dstbak; + return dstbak; } #endif /* SAVESTATE */ /* memory helpers */ -void memcpyha_safe (uaecptr dst, const uae_u8 *src, int size) +void memcpyha_safe(uaecptr dst, const uae_u8 *src, int size) { - if (!addr_valid (_T("memcpyha"), dst, size)) - return; - while (size--) - put_byte (dst++, *src++); + if (!addr_valid(_T("memcpyha"), dst, size)) + return; + while (size--) + put_byte(dst++, *src++); } -void memcpyha (uaecptr dst, const uae_u8 *src, int size) +void memcpyha(uaecptr dst, const uae_u8 *src, int size) { - while (size--) - put_byte (dst++, *src++); + while (size--) + put_byte(dst++, *src++); } -void memcpyah_safe (uae_u8 *dst, uaecptr src, int size) +void memcpyah_safe(uae_u8 *dst, uaecptr src, int size) { - if (!addr_valid (_T("memcpyah"), src, size)) - return; - while (size--) - *dst++ = get_byte(src++); + if (!addr_valid(_T("memcpyah"), src, size)) + return; + while (size--) + *dst++ = get_byte(src++); } -void memcpyah (uae_u8 *dst, uaecptr src, int size) +void memcpyah(uae_u8 *dst, uaecptr src, int size) { - while (size--) - *dst++ = get_byte(src++); + while (size--) + *dst++ = get_byte(src++); } -uae_char *strcpyah_safe (uae_char *dst, uaecptr src, int maxsize) +uae_char *strcpyah_safe(uae_char *dst, uaecptr src, int maxsize) { uae_char *res = dst; - uae_u8 b; + uae_u8 b; dst[0] = 0; - do { - if (!addr_valid (_T("_tcscpyah"), src, 1)) - return res; - b = get_byte(src++); - *dst++ = b; + do { + if (!addr_valid(_T("_tcscpyah"), src, 1)) + return res; + b = get_byte(src++); + *dst++ = b; *dst = 0; - maxsize--; + maxsize--; if (maxsize <= 1) - break; - } while (b); - return res; + break; + } while (b); + return res; } -uaecptr strcpyha_safe (uaecptr dst, const uae_char *src) +uaecptr strcpyha_safe(uaecptr dst, const uae_char *src) { - uaecptr res = dst; - uae_u8 b; - do { - if (!addr_valid (_T("_tcscpyha"), dst, 1)) - return res; - b = *src++; - put_byte (dst++, b); - } while (b); - return res; + uaecptr res = dst; + uae_u8 b; + do { + if (!addr_valid(_T("_tcscpyha"), dst, 1)) + return res; + b = *src++; + put_byte(dst++, b); + } while (b); + return res; } diff --git a/src/newcpu.cpp b/src/newcpu.cpp index 10a565a8..129df783 100644 --- a/src/newcpu.cpp +++ b/src/newcpu.cpp @@ -50,6 +50,7 @@ #include "cia.h" #include "inputdevice.h" #include "audio.h" +#include #ifdef JIT #include "jit/compemu.h" #include @@ -58,6 +59,8 @@ static void build_comp(void) {} bool check_prefs_changed_comp (void) { return false; } #endif +/* For faster JIT cycles handling */ +uae_s32 pissoff = 0; /* Opcode of faulting instruction */ static uae_u16 last_op_for_exception_3; @@ -85,11 +88,15 @@ cpuop_func *cpufunctbl[65536]; extern uae_u32 get_fpsr(void); #define COUNT_INSTRS 0 +#define MC68060_PCR 0x04300000 +#define MC68EC060_PCR 0x04310000 static uae_u64 fake_srp_030, fake_crp_030; static uae_u32 fake_tt0_030, fake_tt1_030, fake_tc_030; static uae_u16 fake_mmusr_030; +int cpu_last_stop_vpos, cpu_stopped_lines; + #if COUNT_INSTRS static unsigned long int instrcount[65536]; static uae_u16 opcodenums[65536]; @@ -348,28 +355,17 @@ STATIC_INLINE unsigned long adjust_cycles(unsigned long cycles) return res; } - -void check_prefs_changed_adr24 (void) -{ - if(currprefs.address_space_24 != changed_prefs.address_space_24) - { - currprefs.address_space_24 = changed_prefs.address_space_24; - - if (currprefs.address_space_24) { - regs.address_space_mask = 0x00ffffff; - fixup_prefs(&changed_prefs); - } else { - regs.address_space_mask = 0xffffffff; - } - } -} - static void prefs_changed_cpu (void) { - fixup_cpu (&changed_prefs); - currprefs.cpu_model = changed_prefs.cpu_model; - currprefs.fpu_model = changed_prefs.fpu_model; - currprefs.cpu_compatible = changed_prefs.cpu_compatible; + fixup_cpu(&changed_prefs); + currprefs.cpu_model = changed_prefs.cpu_model; + currprefs.fpu_model = changed_prefs.fpu_model; + currprefs.mmu_model = changed_prefs.mmu_model; + currprefs.cpu_compatible = changed_prefs.cpu_compatible; + currprefs.cpu_cycle_exact = changed_prefs.cpu_cycle_exact; + currprefs.int_no_unimplemented = changed_prefs.int_no_unimplemented; + currprefs.fpu_no_unimplemented = changed_prefs.fpu_no_unimplemented; + currprefs.blitter_cycle_exact = changed_prefs.blitter_cycle_exact; } static int check_prefs_changed_cpu2(void) @@ -377,28 +373,65 @@ static int check_prefs_changed_cpu2(void) int changed = 0; #ifdef JIT - changed = check_prefs_changed_comp () ? 1 : 0; + changed = check_prefs_changed_comp() ? 1 : 0; #endif - if (changed - || currprefs.cpu_model != changed_prefs.cpu_model - || currprefs.fpu_model != changed_prefs.fpu_model - || currprefs.cpu_compatible != changed_prefs.cpu_compatible) { - cpu_prefs_changed_flag |= 1; - - } - if (changed - || currprefs.m68k_speed != changed_prefs.m68k_speed) { - cpu_prefs_changed_flag |= 2; - } + if (changed + || currprefs.cpu_model != changed_prefs.cpu_model + || currprefs.fpu_model != changed_prefs.fpu_model + || currprefs.mmu_model != changed_prefs.mmu_model + || currprefs.int_no_unimplemented != changed_prefs.int_no_unimplemented + || currprefs.fpu_no_unimplemented != changed_prefs.fpu_no_unimplemented + || currprefs.cpu_compatible != changed_prefs.cpu_compatible + || currprefs.cpu_cycle_exact != changed_prefs.cpu_cycle_exact) { + cpu_prefs_changed_flag |= 1; + } + if (changed + || currprefs.m68k_speed != changed_prefs.m68k_speed + || currprefs.m68k_speed_throttle != changed_prefs.m68k_speed_throttle + || currprefs.cpu_clock_multiplier != changed_prefs.cpu_clock_multiplier + || currprefs.cpu_frequency != changed_prefs.cpu_frequency) { + cpu_prefs_changed_flag |= 2; + } return cpu_prefs_changed_flag; } void check_prefs_changed_cpu(void) { + if (!config_changed) + return; + + if (currprefs.cpu_idle != changed_prefs.cpu_idle) { + currprefs.cpu_idle = changed_prefs.cpu_idle; + } if (check_prefs_changed_cpu2()) { - set_special (SPCFLAG_MODE_CHANGE); - reset_frame_rate_hack (); - set_speedup_values(); + set_special(SPCFLAG_MODE_CHANGE); + reset_frame_rate_hack(); + } +} + +#define LAST_SPEEDUP_LINE 30 +#define SPEEDUP_CYCLES_JIT 2800 +#define SPEEDUP_CYCLES_NONJIT 600 +#define SPEEDUP_TIMELIMIT_JIT -1500 +#define SPEEDUP_TIMELIMIT_NONJIT -2000 +//int pissoff_value = SPEEDUP_CYCLES_JIT * CYCLE_UNIT; +int speedup_timelimit = SPEEDUP_TIMELIMIT_JIT; + +void set_speedup_values(void) +{ + if (currprefs.m68k_speed < 0) { + if (currprefs.cachesize) { + pissoff_value = SPEEDUP_CYCLES_JIT * CYCLE_UNIT; + speedup_timelimit = SPEEDUP_TIMELIMIT_JIT; + } + else { + pissoff_value = SPEEDUP_CYCLES_NONJIT * CYCLE_UNIT; + speedup_timelimit = SPEEDUP_TIMELIMIT_NONJIT; + } + } + else { + pissoff_value = 0; + speedup_timelimit = 0; } } @@ -433,8 +466,6 @@ void init_m68k (void) #endif } -unsigned long nextevent, is_syncline, currcycle; - struct regstruct regs; int get_cpu_model(void) @@ -447,9 +478,9 @@ STATIC_INLINE int in_rom (uaecptr pc) return (munge24 (pc) & 0xFFF80000) == 0xF80000; } -STATIC_INLINE int in_rtarea (uaecptr pc) +STATIC_INLINE int in_rtarea(uaecptr pc) { - return (munge24 (pc) & 0xFFFF0000) == rtarea_base && uae_boot_rom; + return (munge24(pc) & 0xFFFF0000) == rtarea_base && uae_boot_rom_type; } void REGPARAM2 MakeSR (void) @@ -767,7 +798,7 @@ static void m68k_reset (bool hardreset) { uae_u32 v; - regs.pissoff = 0; + pissoff = 0; cpu_cycles = 0; regs.spcflags = 0; @@ -1065,7 +1096,7 @@ static void do_trace (void) && cctrue (regs.ccrflags, (opcode >> 8) & 0xf)) || ((opcode & 0xf0f0) == 0x5050 /* DBcc */ && !cctrue (regs.ccrflags, (opcode >> 8) & 0xf) - && (uae_s16)m68k_dreg (regs, opcode & 7) != 0)) + && uae_s16(m68k_dreg (regs, opcode & 7)) != 0)) { unset_special (SPCFLAG_TRACE); set_special (SPCFLAG_DOTRACE); @@ -1268,7 +1299,7 @@ typedef void compiled_handler(void); static void m68k_run_jit (void) { for (;;) { - ((compiled_handler*)(pushall_call_handler))(); + ((compiled_handler*)pushall_call_handler)(); /* Whenever we return from that, we should check spcflags */ if (uae_int_requested) { INTREQ_f (0x8008); @@ -1343,82 +1374,90 @@ static void exception2_handle (uaecptr addr, uaecptr fault) Exception (2); } -void m68k_go (int may_quit) +void m68k_go(int may_quit) { - int hardboot = 1; + int hardboot = 1; int startup = 1; - if (in_m68k_go || !may_quit) { - write_log (_T("Bug! m68k_go is not reentrant.\n")); - abort (); - } + if (in_m68k_go || !may_quit) { + write_log(_T("Bug! m68k_go is not reentrant.\n")); + abort(); + } - reset_frame_rate_hack (); - update_68k_cycles (); + reset_frame_rate_hack(); + update_68k_cycles(); + start_cycles = 0; cpu_prefs_changed_flag = 0; - in_m68k_go++; - for (;;) { - void (*run_func)(void); + in_m68k_go++; +#ifdef DEBUG + ProfilerStart("amiberry-sdl2.prof"); +#endif + for (;;) { + void(*run_func)(void); - if (quit_program > 0) { - int hardreset = (quit_program == UAE_RESET_HARD ? 1 : 0) | hardboot; + if (quit_program > 0) { + int hardreset = (quit_program == UAE_RESET_HARD ? 1 : 0) | hardboot; bool kbreset = quit_program == UAE_RESET_KEYBOARD; if (quit_program == UAE_QUIT) - break; - if(quit_program == UAE_RESET_HARD) - reinit_amiga(); + break; + if (quit_program == UAE_RESET_HARD) + reinit_amiga(); int restored = 0; hsync_counter = 0; - quit_program = 0; - hardboot = 0; + vsync_counter = 0; + quit_program = 0; + hardboot = 0; + #ifdef SAVESTATE if (savestate_state == STATE_DORESTORE) savestate_state = STATE_RESTORE; - if (savestate_state == STATE_RESTORE) - restore_state (savestate_fname); + if (savestate_state == STATE_RESTORE) + restore_state(savestate_fname); #endif - set_cycles (0); - check_prefs_changed_adr24(); - custom_reset (hardreset != 0, kbreset); - m68k_reset (hardreset != 0); - if (hardreset) { - memory_clear (); - write_log (_T("hardreset, memory cleared\n")); - } + //prefs_changed_cpu(); + //build_cpufunctbl(); + //set_x_funcs(); //TODO + set_cycles(start_cycles); + custom_reset(hardreset != 0, kbreset); + m68k_reset(hardreset != 0); + if (hardreset) { + memory_clear(); + write_log(_T("hardreset, memory cleared\n")); + } #ifdef SAVESTATE - /* We may have been restoring state, but we're done now. */ - if (isrestore ()) { - savestate_restore_finish (); + /* We may have been restoring state, but we're done now. */ + if (isrestore()) { + savestate_restore_finish(); startup = 1; restored = 1; - } + } #endif - if (currprefs.produce_sound == 0) - eventtab[ev_audio].active = 0; - m68k_setpc_normal (regs.pc); - check_prefs_changed_audio (); + if (currprefs.produce_sound == 0) + eventtab[ev_audio].active = 0; + m68k_setpc_normal(regs.pc); + check_prefs_changed_audio(); if (!restored || hsync_counter == 0) - savestate_check (); - } + savestate_check(); + } - if (regs.panic) { - regs.panic = 0; - /* program jumped to non-existing memory and cpu was >= 68020 */ - get_real_address (regs.isp); /* stack in no one's land? -> halt */ - if (regs.isp & 1) + if (regs.panic) { + regs.panic = 0; + /* program jumped to non-existing memory and cpu was >= 68020 */ + get_real_address(regs.isp); /* stack in no one's land? -> halt */ + if (regs.isp & 1) regs.panic = 5; - if (!regs.panic) - exception2_handle (regs.panic_pc, regs.panic_addr); - if (regs.panic) { + if (!regs.panic) + exception2_handle(regs.panic_pc, regs.panic_addr); + if (regs.panic) { int id = regs.panic; - /* system is very badly confused */ - regs.panic = 0; - cpu_halt (id); - } - } + /* system is very badly confused */ + regs.panic = 0; + cpu_halt(id); + } + } if (regs.spcflags & SPCFLAG_MODE_CHANGE) { if (cpu_prefs_changed_flag & 1) { @@ -1427,7 +1466,7 @@ void m68k_go (int may_quit) build_cpufunctbl(); m68k_setpc_normal(pc); fill_prefetch(); - } + } if (cpu_prefs_changed_flag & 2) { fixup_cpu(&changed_prefs); currprefs.m68k_speed = changed_prefs.m68k_speed; @@ -1436,27 +1475,30 @@ void m68k_go (int may_quit) cpu_prefs_changed_flag = 0; } - if (startup) { - custom_prepare (); - protect_roms (true); + if (startup) { + custom_prepare(); + protect_roms(true); } - startup = 0; + startup = 0; if (regs.halted) { - cpu_halt (regs.halted); + cpu_halt(regs.halted); continue; } - run_func = - currprefs.cpu_compatible && currprefs.cpu_model <= 68010 ? m68k_run_1 : + run_func = + currprefs.cpu_compatible && currprefs.cpu_model <= 68010 ? m68k_run_1 : #ifdef JIT - currprefs.cpu_model >= 68020 && currprefs.cachesize ? m68k_run_jit : + currprefs.cpu_model >= 68020 && currprefs.cachesize ? m68k_run_jit : #endif - m68k_run_2; + m68k_run_2; unset_special(SPCFLAG_MODE_CHANGE); unset_special(SPCFLAG_BRK); - run_func (); - } - protect_roms (false); - in_m68k_go--; + run_func(); + } +#ifdef DEBUG + ProfilerStop(); +#endif + protect_roms(false); + in_m68k_go--; } #ifdef SAVESTATE @@ -1520,6 +1562,9 @@ uae_u8 *restore_cpu (uae_u8 *src) regs.srp = restore_u32(); } if (flags & 0x80000000) { + regs.chipset_latch_rw = restore_u32(); + regs.chipset_latch_read = restore_u32(); + regs.chipset_latch_write = restore_u32(); int khz = restore_u32(); restore_u32(); if (khz > 0 && khz < 800000) @@ -1650,6 +1695,9 @@ uae_u8 *save_cpu (int *len, uae_u8 *dstptr) if (currprefs.cpu_model >= 68020) khz *= 2; } + save_u32(regs.chipset_latch_rw); + save_u32(regs.chipset_latch_read); + save_u32(regs.chipset_latch_write); save_u32 (khz); // clock rate in KHz: -1 = fastest possible save_u32 (0); // spare *len = dst - dstbak; @@ -1756,8 +1804,10 @@ void m68k_setstopped (void) regs.stopped = 1; /* A traced STOP instruction drops through immediately without actually stopping. */ - if ((regs.spcflags & SPCFLAG_DOTRACE) == 0) - set_special (SPCFLAG_STOP); + if ((regs.spcflags & SPCFLAG_DOTRACE) == 0) { + set_special(SPCFLAG_STOP); + cpu_last_stop_vpos = vpos; + } else m68k_resumestopped (); } @@ -1769,6 +1819,8 @@ void m68k_resumestopped (void) regs.stopped = 0; fill_prefetch (); unset_special (SPCFLAG_STOP); + cpu_stopped_lines += vpos - cpu_last_stop_vpos; + cpu_last_stop_vpos = vpos; } void fill_prefetch (void) diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index cb687734..3cfe7c8c 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -43,6 +43,8 @@ #include #include "scsidev.h" +int pissoff_value = 15000 * CYCLE_UNIT; + extern void signal_segv(int signum, siginfo_t* info, void* ptr); extern void gui_force_rtarea_hdchange(); @@ -228,9 +230,9 @@ void target_quit() void target_fixup_options(struct uae_prefs* p) { - p->rtgmem_type = 1; - if (p->z3fastmem_start != z3_start_adr) - p->z3fastmem_start = z3_start_adr; + p->rtgboards[0].rtgmem_type = 1; + if (p->z3fastmem[0].start_address != z3_start_adr) + p->z3fastmem[0].start_address = z3_start_adr; p->picasso96_modeflags = RGBFF_CLUT | RGBFF_R5G6B5 | RGBFF_R8G8B8A8; if (p->gfx_size.width == 0) @@ -383,7 +385,7 @@ int target_cfgfile_load(struct uae_prefs* p, const char* filename, int type, int gui_force_rtarea_hdchange(); discard_prefs(p, type); - default_prefs(p, 0); + default_prefs(p, true, 0); const char* ptr = strstr(filename, ".rp9"); if (ptr > nullptr) @@ -792,6 +794,7 @@ int handle_msgpump() //ch = true; } break; + case SDLK_CAPSLOCK: // capslock if (currprefs.keyboard_leds[KBLED_CAPSLOCKB] > 0) { diff --git a/src/osdep/amiberry_filesys.cpp b/src/osdep/amiberry_filesys.cpp index 30c1c731..bd1eb292 100644 --- a/src/osdep/amiberry_filesys.cpp +++ b/src/osdep/amiberry_filesys.cpp @@ -3,6 +3,7 @@ #include #include "sysconfig.h" #include "sysdeps.h" +#include "options.h" #include "config.h" #include "zfile.h" @@ -204,8 +205,8 @@ FILE *my_opentext (const TCHAR *name) } /* Returns 1 if an actual volume-name was found, 2 if no volume-name (so uses some defaults) */ -int target_get_volume_name(struct uaedev_mount_info *mtinf, const char *volumepath, char *volumename, int size, bool inserted, bool fullcheck) +int target_get_volume_name(struct uaedev_mount_info *mtinf, struct uaedev_config_info *ci, bool inserted, bool fullcheck, int cnt) { - sprintf(volumename, "DH_%c", volumepath[0]); + _stprintf(ci->volname, _T("DH_%c"), ci->rootdir[0]); return 2; } diff --git a/src/osdep/amiberry_gfx.cpp b/src/osdep/amiberry_gfx.cpp index d26de569..288d461f 100644 --- a/src/osdep/amiberry_gfx.cpp +++ b/src/osdep/amiberry_gfx.cpp @@ -20,6 +20,8 @@ /* SDL variable for output of emulation */ SDL_Surface* screen = nullptr; +static int oldtex_w, oldtex_h, oldtex_rtg; + /* Possible screen modes (x and y resolutions) */ #define MAX_SCREEN_MODES 14 static int x_size_table[MAX_SCREEN_MODES] = {640, 640, 720, 800, 800, 960, 1024, 1280, 1280, 1280, 1360, 1366, 1680, 1920}; @@ -53,10 +55,10 @@ int graphics_setup(void) void InitAmigaVidMode(struct uae_prefs* p) { /* Initialize structure for Amiga video modes */ - gfxvidinfo.pixbytes = 2; + gfxvidinfo.pixbytes = screen->format->BytesPerPixel; gfxvidinfo.bufmem = static_cast(screen->pixels); - gfxvidinfo.outwidth = screen->w ? screen->w : 640; //p->gfx_size.width; - gfxvidinfo.outheight = screen->h ? screen->h : 256; //p->gfx_size.height; + gfxvidinfo.outwidth = screen->w ? screen->w : AMIGA_WIDTH_MAX << currprefs.gfx_resolution; + gfxvidinfo.outheight = screen->h ? screen->h : AMIGA_HEIGHT_MAX << currprefs.gfx_vresolution; gfxvidinfo.rowbytes = screen->pitch; } @@ -73,6 +75,33 @@ void graphics_subshutdown() } } +void Create_SDL_Surface(int width, int height, int depth) +{ + screen = SDL_CreateRGBSurface(0, width, height, depth, 0, 0, 0, 0); + check_error_sdl(screen == nullptr, "Unable to create a surface"); +} + +void Create_SDL_Texture(int width, int height, int depth) +{ + if (depth == 16) { + // Initialize SDL Texture for the renderer + texture = SDL_CreateTexture(renderer, + SDL_PIXELFORMAT_RGB565, // 16-bit + SDL_TEXTUREACCESS_STREAMING, + width, + height); + } + else if (depth == 32) + { + texture = SDL_CreateTexture(renderer, + SDL_PIXELFORMAT_BGRA32, // 32-bit + SDL_TEXTUREACCESS_STREAMING, + width, + height); + } + check_error_sdl(texture == nullptr, "Unable to create texture"); +} + // Check if the requested Amiga resolution can be displayed with the current Screen mode as a direct multiple // Based on this we make the decision to use Linear (smooth) or Nearest Neighbor (pixelated) scaling bool isModeAspectRatioExact(SDL_DisplayMode* mode, int width, int height) @@ -97,51 +126,43 @@ static void open_screen(struct uae_prefs* p) { int width; int height; - + int depth = 32; #ifdef PICASSO96 if (screen_is_picasso) { width = picasso_vidinfo.width; height = picasso_vidinfo.height; - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); // make the scaled rendering look smoother. } else #endif { p->gfx_resolution = p->gfx_size.width ? (p->gfx_size.width > 600 ? 1 : 0) : 1; - width = p->gfx_size.width ? p->gfx_size.width : 640; - height = p->gfx_size.height ? p->gfx_size.height : 256; - - if (p->scaling_method == -1) - { - if (isModeAspectRatioExact(&sdlMode, width, height)) - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest"); - else - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); - } - else if (p->scaling_method == 0) - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest"); - else if (p->scaling_method == 1) - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); + width = p->gfx_size.width ? p->gfx_size.width : AMIGA_WIDTH_MAX << currprefs.gfx_resolution; + height = p->gfx_size.height ? p->gfx_size.height : AMIGA_HEIGHT_MAX << currprefs.gfx_vresolution; } + if (p->scaling_method == -1) + { + if (isModeAspectRatioExact(&sdlMode, width, height)) + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest"); + else + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); + } + else if (p->scaling_method == 0) + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest"); + else if (p->scaling_method == 1) + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); + graphics_subshutdown(); - - screen = SDL_CreateRGBSurface(0, width, height, 16, 0, 0, 0, 0); - check_error_sdl(screen == nullptr, "Unable to create a surface"); + + Create_SDL_Surface(width, height, depth); if (screen_is_picasso) SDL_RenderSetLogicalSize(renderer, width, height); else SDL_RenderSetLogicalSize(renderer, width, height*2); - // Initialize SDL Texture for the renderer - texture = SDL_CreateTexture(renderer, - SDL_PIXELFORMAT_RGB565, - SDL_TEXTUREACCESS_STREAMING, - width, - height); - check_error_sdl(texture == nullptr, "Unable to create texture"); + Create_SDL_Texture(width, height, depth); updatedisplayarea(); @@ -184,7 +205,7 @@ int check_prefs_changed_gfx() if (currprefs.chipset_refreshrate != changed_prefs.chipset_refreshrate) { currprefs.chipset_refreshrate = changed_prefs.chipset_refreshrate; - init_hz_full(); + init_hz_normal(); changed = 1; } @@ -196,14 +217,14 @@ int check_prefs_changed_gfx() int lockscr() { - SDL_LockSurface(screen); + //SDL_LockSurface(screen); return 1; } void unlockscr() { - SDL_UnlockSurface(screen); + //SDL_UnlockSurface(screen); } @@ -211,23 +232,38 @@ void wait_for_vsync() { } +void DX_Fill(int dstx, int dsty, int width, int height, uae_u32 color) +{ + SDL_Rect dstrect; + if (width < 0) + width = picasso_vidinfo.width; + if (height < 0) + height = picasso_vidinfo.height; + + dstrect.x = dstx; + dstrect.y = dsty; + dstrect.w = width; + dstrect.h = height; + + SDL_FillRect(screen, &dstrect, color); +} void flush_screen() { - if (savestate_state == STATE_DOSAVE) - { - if (delay_savestate_frame > 0) - --delay_savestate_frame; - else - { - CreateScreenshot(); - save_thumb(screenshot_filename); - savestate_state = 0; - } - } + //if (savestate_state == STATE_DOSAVE) + //{ + // if (delay_savestate_frame > 0) + // --delay_savestate_frame; + // else + // { + // CreateScreenshot(); + // save_thumb(screenshot_filename); + // savestate_state = 0; + // } + //} updatedisplayarea(); - init_row_map(); + //init_row_map(); } static void graphics_subinit() @@ -243,47 +279,30 @@ static void graphics_subinit() } } -STATIC_INLINE int bitsInMask(unsigned long mask) -{ - /* count bits in mask */ - int n = 0; - while (mask) - { - n += mask & 1; - mask >>= 1; - } - return n; -} +/* Color management */ -STATIC_INLINE int maskShift(unsigned long mask) -{ - /* determine how far mask is shifted */ - int n = 0; - while (!(mask & 1)) - { - n++; - mask >>= 1; - } - return n; -} +static xcolnr xcol8[4096]; + +static int red_bits, green_bits, blue_bits, alpha_bits; +static int red_shift, green_shift, blue_shift, alpha_shift; +static int alpha; static int init_colors() { - int i; - int red_bits, green_bits, blue_bits; - int red_shift, green_shift, blue_shift; + alpha = 0; /* Truecolor: */ - red_bits = bitsInMask(screen->format->Rmask); - green_bits = bitsInMask(screen->format->Gmask); - blue_bits = bitsInMask(screen->format->Bmask); - red_shift = maskShift(screen->format->Rmask); - green_shift = maskShift(screen->format->Gmask); - blue_shift = maskShift(screen->format->Bmask); - alloc_colors64k(red_bits, green_bits, blue_bits, red_shift, green_shift, blue_shift, 0); + red_bits = bits_in_mask(screen->format->Rmask); + green_bits = bits_in_mask(screen->format->Gmask); + blue_bits = bits_in_mask(screen->format->Bmask); + red_shift = mask_shift(screen->format->Rmask); + green_shift = mask_shift(screen->format->Gmask); + blue_shift = mask_shift(screen->format->Bmask); + alpha_bits = 0; + alpha_shift = 0; + + alloc_colors64k(red_bits, green_bits, blue_bits, red_shift, green_shift, blue_shift, alpha_bits, alpha_shift, alpha, 0); notice_new_xcolors(); - for (i = 0; i < 4096; i++) - xcolors[i] = xcolors[i] * 0x00010001; return 1; } @@ -310,7 +329,7 @@ static int get_display_depth() // const SDL_VideoInfo *vid_info; // int depth = 0; - int depth = 16; + int depth = 32; // if ((vid_info = SDL_GetVideoInfo())) // { @@ -475,60 +494,41 @@ static int save_thumb(char* path) bool vsync_switchmode(int hz) { - // int changed_height = changed_prefs.gfx_size.height; - // - // if (hz >= 55) - // hz = 60; - // else - // hz = 50; - // - // if(hz == 50 && currVSyncRate == 60) - // { - // // Switch from NTSC -> PAL - // switch(changed_height) { - // case 200: changed_height = 240; break; - // case 216: changed_height = 262; break; - // case 240: changed_height = 270; break; - // case 256: changed_height = 270; break; - // case 262: changed_height = 270; break; - // case 270: changed_height = 270; break; - // } - // } - // else if(hz == 60 && currVSyncRate == 50) - // { - // // Switch from PAL -> NTSC - // switch(changed_height) { - // case 200: changed_height = 200; break; - // case 216: changed_height = 200; break; - // case 240: changed_height = 200; break; - // case 256: changed_height = 216; break; - // case 262: changed_height = 216; break; - // case 270: changed_height = 240; break; - // } - // } - // - // if(changed_height == currprefs.gfx_size.height && hz == currprefs.chipset_refreshrate) - // return true; - // - // changed_prefs.gfx_size.height = changed_height; - return true; } bool target_graphics_buffer_update() { - bool rate_changed = false; - - if (currprefs.gfx_size.height != changed_prefs.gfx_size.height) + int w, h; + if (screen_is_picasso) { - update_display(&changed_prefs); - rate_changed = true; + w = picasso96_state.Width > picasso_vidinfo.width ? picasso96_state.Width : picasso_vidinfo.width; + h = picasso96_state.Height > picasso_vidinfo.height ? picasso96_state.Height : picasso_vidinfo.height; + } + else + { + w = gfxvidinfo.outwidth; + h = gfxvidinfo.outheight; } - if (rate_changed) + if (oldtex_w == w && oldtex_h == h && oldtex_rtg == screen_is_picasso) + return false; + + if (!w || !h) { + oldtex_w = w; + oldtex_h = h; + oldtex_rtg = screen_is_picasso; + return false; + } + + oldtex_w = w; + oldtex_h = h; + oldtex_rtg = screen_is_picasso; + + if (currprefs.gfx_size.height != h || + currprefs.gfx_size.width != w) { - fpscounter_reset(); - time_per_frame = 1000 * 1000 / (currprefs.chipset_refreshrate); + update_display(&changed_prefs); } return true; @@ -546,8 +546,12 @@ int picasso_palette() int r = picasso96_state.CLUT[i].Red; int g = picasso96_state.CLUT[i].Green; int b = picasso96_state.CLUT[i].Blue; - int value = (r << 16 | g << 8 | b); - uae_u32 v = CONVERT_RGB(value); + //int value = (r << 16 | g << 8 | b); + //uae_u32 v = CONVERT_RGB(value); + uae_u32 v = (doMask256(r, red_bits, red_shift) + | doMask256(g, green_bits, green_shift) + | doMask256(b, blue_bits, blue_shift)) + | doMask256(0xff, alpha_bits, alpha_shift); if (v != picasso_vidinfo.clut[i]) { picasso_vidinfo.clut[i] = v; @@ -641,9 +645,7 @@ void picasso_InitResolutions() int rgbFormat = (bitdepth == 8 ? RGBFB_CLUT : (bitdepth == 16 ? RGBFB_R5G6B5 : RGBFB_R8G8B8A8)); int pixelFormat = 1 << rgbFormat; pixelFormat |= RGBFF_CHUNKY; - // - // if (SDL_VideoModeOK (x_size_table[i], y_size_table[i], 16, SDL_SWSURFACE)) - // { + DisplayModes[count].res.width = x_size_table[i]; DisplayModes[count].res.height = y_size_table[i]; DisplayModes[count].depth = bit_unit >> 3; @@ -655,7 +657,6 @@ void picasso_InitResolutions() DisplayModes[count].res.width, DisplayModes[count].res.height, DisplayModes[count].depth * 8); count++; - // } } } DisplayModes[count].depth = -1; @@ -688,18 +689,23 @@ void gfx_set_picasso_modeinfo(uae_u32 w, uae_u32 h, uae_u32 depth, RGBFTYPE rgbf picasso_vidinfo.selected_rgbformat = rgbfmt; picasso_vidinfo.width = w; picasso_vidinfo.height = h; - picasso_vidinfo.depth = 2; // Native depth + picasso_vidinfo.depth = 4; // Native depth picasso_vidinfo.extra_mem = 1; - - picasso_vidinfo.pixbytes = 2; // Native bytes + picasso_vidinfo.pixbytes = 4; // Native bytes + gfx_set_picasso_colors(rgbfmt); if (screen_is_picasso) { open_screen(&currprefs); picasso_vidinfo.rowbytes = screen->pitch; - picasso_vidinfo.rgbformat = RGBFB_R5G6B5; + picasso_vidinfo.rgbformat = RGBFB_R8G8B8A8; } } +void gfx_set_picasso_colors(RGBFTYPE rgbfmt) +{ + alloc_colors_picasso(red_bits, green_bits, blue_bits, red_shift, green_shift, blue_shift, rgbfmt); +} + uae_u8* gfx_lock_picasso() { SDL_LockSurface(screen); diff --git a/src/osdep/amiberry_gfx.h b/src/osdep/amiberry_gfx.h index 089e7aa1..281aa10e 100644 --- a/src/osdep/amiberry_gfx.h +++ b/src/osdep/amiberry_gfx.h @@ -10,4 +10,5 @@ extern SDL_Texture* gui_texture; extern SDL_DisplayMode sdlMode; extern void check_error_sdl(bool check, const char* message); -extern void updatedisplayarea(); \ No newline at end of file +extern void updatedisplayarea(); +void DX_Fill(int dstx, int dsty, int width, int height, uae_u32 color); \ No newline at end of file diff --git a/src/osdep/amiberry_gui.cpp b/src/osdep/amiberry_gui.cpp index cc07e999..d5b77f70 100644 --- a/src/osdep/amiberry_gui.cpp +++ b/src/osdep/amiberry_gui.cpp @@ -431,7 +431,7 @@ static void gui_to_prefs() /* filesys hack */ currprefs.mountitems = changed_prefs.mountitems; memcpy(&currprefs.mountconfig, &changed_prefs.mountconfig, MOUNT_CONFIG_SIZE * sizeof(struct uaedev_config_info)); - fixup_prefs(&changed_prefs); + fixup_prefs(&changed_prefs, true); } @@ -621,7 +621,6 @@ void gui_led(int led, int on) else kbd_led_status &= ~LED_SCR; } } - ioctl(0, KDSETLED, kbd_led_status); } diff --git a/src/osdep/amiberry_input.cpp b/src/osdep/amiberry_input.cpp index e188fa9a..8b2ef143 100644 --- a/src/osdep/amiberry_input.cpp +++ b/src/osdep/amiberry_input.cpp @@ -657,3 +657,8 @@ void SimulateMouseOrJoy(int code, int keypressed) break; } } + +int is_tablet() +{ + return 0; +} \ No newline at end of file diff --git a/src/osdep/amiberry_mem.cpp b/src/osdep/amiberry_mem.cpp index 2a6ca082..bdfe15b7 100644 --- a/src/osdep/amiberry_mem.cpp +++ b/src/osdep/amiberry_mem.cpp @@ -12,7 +12,7 @@ #include #include "SDL.h" - +extern addrbank gfxmem_bank; uae_u8* natmem_offset = nullptr; uae_u32 natmem_size; static uae_u64 totalAmigaMemSize; @@ -139,8 +139,8 @@ void alloc_AmigaMem() static uae_u32 getz2rtgaddr() { uae_u32 start; - start = currprefs.fastmem_size; - while (start & (currprefs.rtgmem_size - 1) && start < 4 * 1024 * 1024) + start = currprefs.fastmem[0].size; + while (start & (currprefs.rtgboards[0].rtgmem_size - 1) && start < 4 * 1024 * 1024) start += 1024 * 1024; return start + 2 * 1024 * 1024; } diff --git a/src/osdep/amiberry_rp9.cpp b/src/osdep/amiberry_rp9.cpp index e1f3c43b..13edf4ba 100644 --- a/src/osdep/amiberry_rp9.cpp +++ b/src/osdep/amiberry_rp9.cpp @@ -86,7 +86,7 @@ static bool get_value(xmlNode *node, const char *key, char *value, int max_size) static void set_default_system(struct uae_prefs *p, const char *system, int rom) { - default_prefs(p, 0); + default_prefs(p, true, 0); del_tmpFiles(); if (strcmp(system, "a-500") == 0) @@ -145,9 +145,9 @@ static void parse_ram(struct uae_prefs *p, xmlNode *node) { int size = atoi(reinterpret_cast(content)); if(strcmp(reinterpret_cast(attr), "fast") == 0) - p->fastmem_size = size; + p->fastmem[0].size = size; else if(strcmp(reinterpret_cast(attr), "z3") == 0) - p->z3fastmem_size = size; + p->z3fastmem[0].size = size; else if(strcmp(reinterpret_cast(attr), "chip") == 0) p->chipmem_size = size; xmlFree(attr); diff --git a/src/osdep/gui/PanelCPU.cpp b/src/osdep/gui/PanelCPU.cpp index dbb6c6f4..cb5b644e 100644 --- a/src/osdep/gui/PanelCPU.cpp +++ b/src/osdep/gui/PanelCPU.cpp @@ -43,16 +43,16 @@ public: changed_prefs.cpu_model = 68000; changed_prefs.fpu_model = 0; changed_prefs.address_space_24 = true; - changed_prefs.z3fastmem_size = 0; - changed_prefs.rtgmem_size = 0; + changed_prefs.z3fastmem[0].size = 0; + changed_prefs.rtgboards[0].rtgmem_size = 0; } else if (actionEvent.getSource() == optCPU68010) { changed_prefs.cpu_model = 68010; changed_prefs.fpu_model = 0; changed_prefs.address_space_24 = true; - changed_prefs.z3fastmem_size = 0; - changed_prefs.rtgmem_size = 0; + changed_prefs.z3fastmem[0].size = 0; + changed_prefs.rtgboards[0].rtgmem_size = 0; } else if (actionEvent.getSource() == optCPU68020) { diff --git a/src/osdep/gui/PanelConfig.cpp b/src/osdep/gui/PanelConfig.cpp index 9727703d..27c7c715 100644 --- a/src/osdep/gui/PanelConfig.cpp +++ b/src/osdep/gui/PanelConfig.cpp @@ -48,7 +48,7 @@ void load_buildin_config(int id) if (changed_prefs.cdslots[0].inuse) gui_force_rtarea_hdchange(); discard_prefs(&changed_prefs, 0); - default_prefs(&changed_prefs, 0); + default_prefs(&changed_prefs, true, 0); switch (id) { case BUILDINID_A500: diff --git a/src/osdep/gui/PanelRAM.cpp b/src/osdep/gui/PanelRAM.cpp index b19f6f2a..73041ba1 100644 --- a/src/osdep/gui/PanelRAM.cpp +++ b/src/osdep/gui/PanelRAM.cpp @@ -48,8 +48,8 @@ public: if (actionEvent.getSource() == sldChipmem) { changed_prefs.chipmem_size = ChipMem_values[int(sldChipmem->getValue())]; - if ((changed_prefs.chipmem_size > 0x200000) && (changed_prefs.fastmem_size > 0)) - changed_prefs.fastmem_size = 0; + if ((changed_prefs.chipmem_size > 0x200000) && (changed_prefs.fastmem[0].size > 0)) + changed_prefs.fastmem[0].size = 0; } if (actionEvent.getSource() == sldSlowmem) @@ -59,22 +59,22 @@ public: if (actionEvent.getSource() == sldFastmem) { - changed_prefs.fastmem_size = FastMem_values[int(sldFastmem->getValue())]; - if (changed_prefs.fastmem_size > 0 && changed_prefs.chipmem_size > 0x200000) + changed_prefs.fastmem[0].size = FastMem_values[int(sldFastmem->getValue())]; + if (changed_prefs.fastmem[0].size > 0 && changed_prefs.chipmem_size > 0x200000) changed_prefs.chipmem_size = 0x200000; } if (actionEvent.getSource() == sldZ3mem) { - changed_prefs.z3fastmem_size = FastMem_values[int(sldZ3mem->getValue())]; - if (changed_prefs.z3fastmem_size > max_z3fastmem) - changed_prefs.z3fastmem_size = max_z3fastmem; + changed_prefs.z3fastmem[0].size = FastMem_values[int(sldZ3mem->getValue())]; + if (changed_prefs.z3fastmem[0].size > max_z3fastmem) + changed_prefs.z3fastmem[0].size = max_z3fastmem; } if (actionEvent.getSource() == sldGfxmem) { - changed_prefs.rtgmem_size = FastMem_values[int(sldGfxmem->getValue())]; - changed_prefs.rtgmem_type = 1; + changed_prefs.rtgboards[0].rtgmem_size = FastMem_values[int(sldGfxmem->getValue())]; + changed_prefs.rtgboards[0].rtgmem_type = 1; } RefreshPanelRAM(); @@ -225,7 +225,7 @@ void RefreshPanelRAM() for (i = 0; i < 5; ++i) { - if (changed_prefs.fastmem_size == FastMem_values[i]) + if (changed_prefs.fastmem[0].size == FastMem_values[i]) { sldFastmem->setValue(i); lblFastsize->setCaption(FastMem_list[i]); @@ -235,7 +235,7 @@ void RefreshPanelRAM() for (i = 0; i < 9; ++i) { - if (changed_prefs.z3fastmem_size == FastMem_values[i]) + if (changed_prefs.z3fastmem[0].size == FastMem_values[i]) { sldZ3mem->setValue(i); lblZ3size->setCaption(FastMem_list[i]); @@ -246,7 +246,7 @@ void RefreshPanelRAM() for (i = 0; i < 6; ++i) { - if (changed_prefs.rtgmem_size == FastMem_values[i]) + if (changed_prefs.rtgboards[0].rtgmem_size == FastMem_values[i]) { sldGfxmem->setValue(i); lblGfxsize->setCaption(FastMem_list[i]); diff --git a/src/osdep/gui/main_window.cpp b/src/osdep/gui/main_window.cpp index 3ce938bb..cafb2492 100644 --- a/src/osdep/gui/main_window.cpp +++ b/src/osdep/gui/main_window.cpp @@ -118,7 +118,7 @@ static int gui_create_rtarea_flag(struct uae_prefs* p) if (p->input_tablet > 0) flag |= 8; - if (p->rtgmem_size) + if (p->rtgboards[0].rtgmem_size) flag |= 16; if (p->chipmem_size > 2 * 1024 * 1024) diff --git a/src/osdep/menu/menu_config.cpp b/src/osdep/menu/menu_config.cpp index d5dd9728..137107f2 100644 --- a/src/osdep/menu/menu_config.cpp +++ b/src/osdep/menu/menu_config.cpp @@ -416,7 +416,7 @@ int loadconfig_old(struct uae_prefs* p, const char* orgpath) return 0; } // Set everthing to default and clear HD settings - default_prefs(p, 0); + default_prefs(p, true, 0); SetDefaultMenuSettings(p); char filebuffer[256]; @@ -618,10 +618,10 @@ int loadconfig_old(struct uae_prefs* p, const char* orgpath) p->bogomem_size = (p->bogomem_size <= 2) ? 0x080000 << p->bogomem_size : (p->bogomem_size == 3) ? 0x180000 : 0x1c0000; - fscanf(f, "fastmemory=%d\n", &p->fastmem_size); - if (p->fastmem_size > 0 && p->fastmem_size < 10) + fscanf(f, "fastmemory=%d\n", &p->fastmem[0].size); + if (p->fastmem[0].size > 0 && p->fastmem[0].size < 10) // Was saved in old format - p->fastmem_size = 0x080000 << p->fastmem_size; + p->fastmem[0].size = 0x080000 << p->fastmem[0].size; fclose(f); diff --git a/src/osdep/picasso96.cpp b/src/osdep/picasso96.cpp index 921de653..73812995 100644 --- a/src/osdep/picasso96.cpp +++ b/src/osdep/picasso96.cpp @@ -44,79 +44,119 @@ #if defined(PICASSO96) -#include "config.h" +#define MULTIDISPLAY 0 +#define WINCURSOR 1 +#define NEWTRAP 1 + +#define USE_HARDWARESPRITE 1 +#define P96TRACING_ENABLED 0 +#define P96TRACING_SETUP_ENABLED 0 +#define P96SPRTRACING_ENABLED 0 + #include "options.h" #include "threaddep/thread.h" #include "include/memory.h" #include "custom.h" +#include "events.h" #include "newcpu.h" #include "xwin.h" #include "savestate.h" #include "autoconf.h" #include "traps.h" #include "native2amiga.h" +#include "drawing.h" +#include "inputdevice.h" +#include "amiberry_gfx.h" #include "picasso96.h" #include "SDL.h" #define NOBLITTER 0 #define NOBLITTER_BLIT 0 +#define NOBLITTER_ALL 0 +static int hwsprite = 0; static int picasso96_BT = BT_uaegfx; static int picasso96_GCT = GCT_Unknown; static int picasso96_PCT = PCT_Unknown; +int p96refresh_active; bool have_done_picasso = true; /* For the JIT compiler */ static int p96syncrate; -int p96hsync_counter; +int p96hsync_counter, full_refresh; + +#define PICASSO_STATE_SETDISPLAY 1 +#define PICASSO_STATE_SETPANNING 2 +#define PICASSO_STATE_SETGC 4 +#define PICASSO_STATE_SETDAC 8 +#define PICASSO_STATE_SETSWITCH 16 #ifdef PICASSO96 #ifdef DEBUG // Change this to _DEBUG for debugging #define P96TRACING_ENABLED 1 #define P96TRACING_LEVEL 1 #endif -static void flushpixels(); #if P96TRACING_ENABLED #define P96TRACE(x) do { write_log x; } while(0) #else #define P96TRACE(x) #endif - -static void REGPARAM2 gfxmem_lputx(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 gfxmem_wputx(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 gfxmem_bputx(uaecptr, uae_u32) REGPARAM; +#if P96TRACING_SETUP_ENABLED +#define P96TRACE_SETUP(x) do { write_log x; } while(0) +#else +#define P96TRACE_SETUP(x) +#endif +#if P96SPRTRACING_ENABLED +#define P96TRACE_SPR(x) do { write_log x; } while(0) +#else +#define P96TRACE_SPR(x) +#endif +#define P96TRACE2(x) do { write_log x; } while(0) static uae_u8 all_ones_bitmap, all_zeros_bitmap; /* yuk */ struct picasso96_state_struct picasso96_state; +static struct picasso96_state_struct picasso96_state_uaegfx; struct picasso_vidbuf_description picasso_vidinfo; -static struct PicassoResolution* newmodes = nullptr; +static struct PicassoResolution *newmodes; static int picasso_convert, host_mode; /* These are the maximum resolutions... They are filled in by GetSupportedResolutions() have to fill this in, otherwise problems occur on the Amiga side P96 s/w which expects data here. */ -static struct ScreenResolution planar = {320, 240}; -static struct ScreenResolution chunky = {640, 480}; -static struct ScreenResolution hicolour = {640, 480}; -static struct ScreenResolution truecolour = {640, 480}; -static struct ScreenResolution alphacolour = {640, 480}; +static struct ScreenResolution planar = { 320, 240 }; +static struct ScreenResolution chunky = { 640, 480 }; +static struct ScreenResolution hicolour = { 640, 480 }; +static struct ScreenResolution truecolour = { 640, 480 }; +static struct ScreenResolution alphacolour = { 640, 480 }; +uae_u32 p96_rgbx16[65536]; +uae_u32 p96rc[256], p96gc[256], p96bc[256]; + +static int cursorwidth, cursorheight, cursorok; +static uae_u8 *cursordata; +static uae_u32 cursorrgb[4], cursorrgbn[4]; +static int cursordeactivate, setupcursor_needed; +static bool cursorvisible; +//static HCURSOR wincursor; +static int wincursor_shown; static uaecptr boardinfo, ABI_interrupt; static int interrupt_enabled; -int p96vblank; +double p96vblank; +static int rtg_clear_flag; +static bool picasso_active; +static bool picasso_changed; static int uaegfx_old, uaegfx_active; static uae_u32 reserved_gfxmem; static uaecptr uaegfx_resname, - uaegfx_resid, - uaegfx_init, - uaegfx_base, - uaegfx_rom; +uaegfx_resid, +uaegfx_init, +uaegfx_base, +uaegfx_rom; -typedef enum -{ +typedef enum { BLIT_FALSE, BLIT_NOR, BLIT_ONLYDST, @@ -136,50 +176,54 @@ typedef enum BLIT_SWAP = 30 } BLIT_OPCODE; -#define UAE_RTG_LIBRARY_VERSION 40 -#define UAE_RTG_LIBRARY_REVISION 3994 - -static void checkrtglibrary() -{ - uae_u32 v; - static int checked = FALSE; - - if (checked) - return; - v = get_long(4); // execbase - v += 378; // liblist - while ((v = get_long(v))) - { - uae_u32 v2 = get_long(v + 10); // name - uae_u8* p; - addrbank* b = &get_mem_bank(v2); - if (!b || !b->check(v2, 12)) - continue; - p = b->xlateaddr(v2); - if (!memcmp(p, "rtg.library\0", 12)) - { - uae_u16 ver = get_word(v + 20); - uae_u16 rev = get_word(v + 22); - if (ver * 10000 + rev < UAE_RTG_LIBRARY_VERSION * 10000 + UAE_RTG_LIBRARY_REVISION) - { - TCHAR msg[2000]; - sprintf(msg, _T("installed rtg.library: %d.%d, required: %d.%d\n"), ver, rev, UAE_RTG_LIBRARY_VERSION, UAE_RTG_LIBRARY_REVISION); - gui_message(msg); - } - else - { - write_log(_T("P96: rtg.library %d.%d detected\n"), ver, rev); - } - checked = TRUE; - } - } -} - +static void init_picasso_screen(void); static uae_u32 p2ctab[256][2]; static int set_gc_called = 0, init_picasso_screen_called = 0; //fastscreen static uaecptr oldscr = 0; +extern addrbank gfxmem_bank; +extern addrbank *gfxmem_banks[MAX_RTG_BOARDS]; +extern int rtg_index; + +#define UAE_RTG_LIBRARY_VERSION 40 +#define UAE_RTG_LIBRARY_REVISION 3994 + +//static void checkrtglibrary() +//{ +// uae_u32 v; +// static int checked = FALSE; +// +// if (checked) +// return; +// v = get_long(4); // execbase +// v += 378; // liblist +// while ((v = get_long(v))) +// { +// uae_u32 v2 = get_long(v + 10); // name +// uae_u8* p; +// addrbank* b = &get_mem_bank(v2); +// if (!b || !b->check(v2, 12)) +// continue; +// p = b->xlateaddr(v2); +// if (!memcmp(p, "rtg.library\0", 12)) +// { +// uae_u16 ver = get_word(v + 20); +// uae_u16 rev = get_word(v + 22); +// if (ver * 10000 + rev < UAE_RTG_LIBRARY_VERSION * 10000 + UAE_RTG_LIBRARY_REVISION) +// { +// TCHAR msg[2000]; +// sprintf(msg, _T("installed rtg.library: %d.%d, required: %d.%d\n"), ver, rev, UAE_RTG_LIBRARY_VERSION, UAE_RTG_LIBRARY_REVISION); +// gui_message(msg); +// } +// else +// { +// write_log(_T("P96: rtg.library %d.%d detected\n"), ver, rev); +// } +// checked = TRUE; +// } +// } +//} STATIC_INLINE void endianswap(uae_u32* vp, int bpp) { @@ -340,6 +384,8 @@ static void ShowSupportedResolutions(void) #endif +static void **gwwbuf[MAX_RTG_BOARDS]; +static int gwwbufsize[MAX_RTG_BOARDS], gwwpagesize[MAX_RTG_BOARDS], gwwpagemask[MAX_RTG_BOARDS]; extern uae_u8* natmem_offset; static uae_u8 GetBytesPerPixel(uae_u32 RGBfmt) @@ -450,7 +496,7 @@ static int CopyBitMapStructureA2U(uaecptr amigamemptr, struct BitMap* bm) if (valid_address(plane, bm->BytesPerRow * bm->Rows)) bm->Planes[i] = get_real_address(plane); else - return 0; + bm->Planes[i] = &all_zeros_bitmap; break; } } @@ -558,31 +604,7 @@ void picasso_trigger_vblank() put_byte(uaegfx_base + CARD_IRQFLAG, 1); } -void picasso_handle_vsync() -{ - if (currprefs.rtgmem_size == 0) - return; - if (!picasso_on) - { - picasso_trigger_vblank(); - return; - } - - pframecnt++; - - if (doskip() && p96skipmode == 0) - { - ; - } - else - { - flushpixels(); - flush_screen(); - } - - picasso_trigger_vblank(); -} static int set_panning_called = 0; @@ -719,11 +741,28 @@ static int getconvert(int rgbformat, int pixbytes) static void setconvert() { + static int ohost_mode, orgbformat; + picasso_convert = getconvert(picasso96_state.RGBFormat, picasso_vidinfo.pixbytes); host_mode = GetSurfacePixelFormat(); + if (picasso_vidinfo.pixbytes == 4) + alloc_colors_rgb(8, 8, 8, 16, 8, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc); + else + alloc_colors_rgb(5, 6, 5, 11, 5, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc); + gfx_set_picasso_colors(picasso96_state.RGBFormat); picasso_palette(); - write_log (_T("RTG conversion: Depth=%d HostRGBF=%d P96RGBF=%d Mode=%d\n"), - picasso_vidinfo.pixbytes, host_mode, picasso96_state.RGBFormat, picasso_convert); + if (host_mode != ohost_mode || picasso96_state.RGBFormat != orgbformat) { + write_log(_T("RTG conversion: Depth=%d HostRGBF=%d P96RGBF=%d Mode=%d\n"), + picasso_vidinfo.pixbytes, host_mode, picasso96_state.RGBFormat, picasso_convert); + ohost_mode = host_mode; + orgbformat = picasso96_state.RGBFormat; + } + full_refresh = 1; +} + +bool picasso_is_active(void) +{ + return picasso_active; } /* Clear our screen, since we've got a new Picasso screen-mode, and refresh with the proper contents @@ -738,6 +777,7 @@ void picasso_refresh() if (!picasso_on) return; + full_refresh = 1; setconvert(); /* Make sure that the first time we show a Picasso video mode, we don't blit any crap. @@ -745,12 +785,27 @@ void picasso_refresh() */ if (picasso96_state.Address) { + unsigned int width, height; /* blit the stuff from our static frame-buffer to the gfx-card */ ri.Memory = gfxmem_bank.baseaddr + (picasso96_state.Address - gfxmem_bank.start); ri.BytesPerRow = picasso96_state.BytesPerRow; - ri.RGBFormat = RGBFTYPE(picasso96_state.RGBFormat); + ri.RGBFormat = picasso96_state.RGBFormat; - flushpixels(); + if (set_panning_called) { + width = (picasso96_state.VirtualWidth < picasso96_state.Width) ? + picasso96_state.VirtualWidth : picasso96_state.Width; + height = (picasso96_state.VirtualHeight < picasso96_state.Height) ? + picasso96_state.VirtualHeight : picasso96_state.Height; + // Let's put a black-border around the case where we've got a sub-screen... + if (!picasso96_state.BigAssBitmap) { + if (picasso96_state.XOffset || picasso96_state.YOffset) + DX_Fill(0, 0, picasso96_state.Width, picasso96_state.Height, 0); + } + } + else { + width = picasso96_state.Width; + height = picasso96_state.Height; + } } else { @@ -758,6 +813,39 @@ void picasso_refresh() } } +static void selectuaegfx(void) +{ + memcpy(&picasso96_state, &picasso96_state_uaegfx, sizeof picasso96_state); +} + +static int p96hsync; + +void picasso_handle_vsync() +{ + if (currprefs.rtgboards[0].rtgmem_size == 0) + return; + + if (!picasso_on) + { + picasso_trigger_vblank(); + return; + } + + pframecnt++; + + if (doskip() && p96skipmode == 0) + { + ; + } + else + { + picasso_flushpixels(0); + flush_screen(); + } + + picasso_trigger_vblank(); +} + #define BLT_SIZE 4 #define BLT_MULT 1 #define BLT_NAME BLIT_FALSE_32 @@ -983,10 +1071,10 @@ void picasso_refresh() /* * Functions to perform an action on the frame-buffer */ -static int do_blitrect_frame_buffer(struct RenderInfo* ri, struct - RenderInfo* dstri, unsigned long srcx, unsigned long srcy, - unsigned long dstx, unsigned long dsty, unsigned long width, unsigned - long height, uae_u8 mask, BLIT_OPCODE opcode) +static int do_blitrect_frame_buffer(struct RenderInfo *ri, struct + RenderInfo *dstri, unsigned long srcx, unsigned long srcy, + unsigned long dstx, unsigned long dsty, unsigned long width, unsigned + long height, uae_u8 mask, BLIT_OPCODE opcode) { uae_u8 *src, *dst; uae_u8 Bpp = GetBytesPerPixel(ri->RGBFormat); @@ -994,187 +1082,126 @@ static int do_blitrect_frame_buffer(struct RenderInfo* ri, struct src = ri->Memory + srcx * Bpp + srcy * ri->BytesPerRow; dst = dstri->Memory + dstx * Bpp + dsty * dstri->BytesPerRow; - - if (mask != 0xFF && Bpp > 1) - { - write_log (_T("WARNING - BlitRect() has mask 0x%x with Bpp %d.\n"), mask, Bpp); + if (mask != 0xFF && Bpp > 1) { + write_log(_T("WARNING - BlitRect() has mask 0x%x with Bpp %d.\n"), mask, Bpp); } - P96TRACE ((_T("(%dx%d)=(%dx%d)=(%dx%d)=%d\n"), srcx, srcy, dstx, dsty, width, height, opcode)); - if (mask == 0xFF || Bpp > 1) - { - if (opcode == BLIT_SRC) - { + P96TRACE((_T("(%dx%d)=(%dx%d)=(%dx%d)=%d\n"), srcx, srcy, dstx, dsty, width, height, opcode)); + if (mask == 0xFF || Bpp > 1) { + + if (opcode == BLIT_SRC) { /* handle normal case efficiently */ - if (ri->Memory == dstri->Memory && dsty == srcy) - { + if (ri->Memory == dstri->Memory && dsty == srcy) { unsigned long i; - for (i = 0; i < height; i++ , src += ri->BytesPerRow , dst += dstri->BytesPerRow) + for (i = 0; i < height; i++, src += ri->BytesPerRow, dst += dstri->BytesPerRow) memmove(dst, src, total_width); } - else if (dsty < srcy) - { + else if (dsty < srcy) { unsigned long i; - for (i = 0; i < height; i++ , src += ri->BytesPerRow , dst += dstri->BytesPerRow) + for (i = 0; i < height; i++, src += ri->BytesPerRow, dst += dstri->BytesPerRow) memcpy(dst, src, total_width); } - else - { + else { unsigned long i; src += (height - 1) * ri->BytesPerRow; dst += (height - 1) * dstri->BytesPerRow; - for (i = 0; i < height; i++ , src -= ri->BytesPerRow , dst -= dstri->BytesPerRow) + for (i = 0; i < height; i++, src -= ri->BytesPerRow, dst -= dstri->BytesPerRow) memcpy(dst, src, total_width); } return 1; - } - if (Bpp == 4) - { - /* 32-bit optimized */ - switch (opcode) - { - case BLIT_FALSE: BLIT_FALSE_32(PARMS); - break; - case BLIT_NOR: BLIT_NOR_32(PARMS); - break; - case BLIT_ONLYDST: BLIT_ONLYDST_32(PARMS); - break; - case BLIT_NOTSRC: BLIT_NOTSRC_32(PARMS); - break; - case BLIT_ONLYSRC: BLIT_ONLYSRC_32(PARMS); - break; - case BLIT_NOTDST: BLIT_NOTDST_32(PARMS); - break; - case BLIT_EOR: BLIT_EOR_32(PARMS); - break; - case BLIT_NAND: BLIT_NAND_32(PARMS); - break; - case BLIT_AND: BLIT_AND_32(PARMS); - break; - case BLIT_NEOR: BLIT_NEOR_32(PARMS); - break; - case BLIT_NOTONLYSRC: BLIT_NOTONLYSRC_32(PARMS); - break; - case BLIT_NOTONLYDST: BLIT_NOTONLYDST_32(PARMS); - break; - case BLIT_OR: BLIT_OR_32(PARMS); - break; - case BLIT_TRUE: BLIT_TRUE_32(PARMS); - break; - case BLIT_SWAP: BLIT_SWAP_32(PARMS); - break; - } } - else if (Bpp == 3) - { - /* 24-bit (not very) optimized */ - switch (opcode) - { - case BLIT_FALSE: BLIT_FALSE_24(PARMS); - break; - case BLIT_NOR: BLIT_NOR_24(PARMS); - break; - case BLIT_ONLYDST: BLIT_ONLYDST_24(PARMS); - break; - case BLIT_NOTSRC: BLIT_NOTSRC_24(PARMS); - break; - case BLIT_ONLYSRC: BLIT_ONLYSRC_24(PARMS); - break; - case BLIT_NOTDST: BLIT_NOTDST_24(PARMS); - break; - case BLIT_EOR: BLIT_EOR_24(PARMS); - break; - case BLIT_NAND: BLIT_NAND_24(PARMS); - break; - case BLIT_AND: BLIT_AND_24(PARMS); - break; - case BLIT_NEOR: BLIT_NEOR_24(PARMS); - break; - case BLIT_NOTONLYSRC: BLIT_NOTONLYSRC_24(PARMS); - break; - case BLIT_NOTONLYDST: BLIT_NOTONLYDST_24(PARMS); - break; - case BLIT_OR: BLIT_OR_24(PARMS); - break; - case BLIT_TRUE: BLIT_TRUE_24(PARMS); - break; - case BLIT_SWAP: BLIT_SWAP_24(PARMS); - break; + else { + + if (Bpp == 4) { + + /* 32-bit optimized */ + switch (opcode) + { + case BLIT_FALSE: BLIT_FALSE_32(PARMS); break; + case BLIT_NOR: BLIT_NOR_32(PARMS); break; + case BLIT_ONLYDST: BLIT_ONLYDST_32(PARMS); break; + case BLIT_NOTSRC: BLIT_NOTSRC_32(PARMS); break; + case BLIT_ONLYSRC: BLIT_ONLYSRC_32(PARMS); break; + case BLIT_NOTDST: BLIT_NOTDST_32(PARMS); break; + case BLIT_EOR: BLIT_EOR_32(PARMS); break; + case BLIT_NAND: BLIT_NAND_32(PARMS); break; + case BLIT_AND: BLIT_AND_32(PARMS); break; + case BLIT_NEOR: BLIT_NEOR_32(PARMS); break; + case BLIT_NOTONLYSRC: BLIT_NOTONLYSRC_32(PARMS); break; + case BLIT_NOTONLYDST: BLIT_NOTONLYDST_32(PARMS); break; + case BLIT_OR: BLIT_OR_32(PARMS); break; + case BLIT_TRUE: BLIT_TRUE_32(PARMS); break; + case BLIT_SWAP: BLIT_SWAP_32(PARMS); break; + } } - } - else if (Bpp == 2) - { - /* 16-bit optimized */ - switch (opcode) - { - case BLIT_FALSE: BLIT_FALSE_16(PARMS); - break; - case BLIT_NOR: BLIT_NOR_16(PARMS); - break; - case BLIT_ONLYDST: BLIT_ONLYDST_16(PARMS); - break; - case BLIT_NOTSRC: BLIT_NOTSRC_16(PARMS); - break; - case BLIT_ONLYSRC: BLIT_ONLYSRC_16(PARMS); - break; - case BLIT_NOTDST: BLIT_NOTDST_16(PARMS); - break; - case BLIT_EOR: BLIT_EOR_16(PARMS); - break; - case BLIT_NAND: BLIT_NAND_16(PARMS); - break; - case BLIT_AND: BLIT_AND_16(PARMS); - break; - case BLIT_NEOR: BLIT_NEOR_16(PARMS); - break; - case BLIT_NOTONLYSRC: BLIT_NOTONLYSRC_16(PARMS); - break; - case BLIT_NOTONLYDST: BLIT_NOTONLYDST_16(PARMS); - break; - case BLIT_OR: BLIT_OR_16(PARMS); - break; - case BLIT_TRUE: BLIT_TRUE_16(PARMS); - break; - case BLIT_SWAP: BLIT_SWAP_16(PARMS); - break; + else if (Bpp == 3) { + + /* 24-bit (not very) optimized */ + switch (opcode) + { + case BLIT_FALSE: BLIT_FALSE_24(PARMS); break; + case BLIT_NOR: BLIT_NOR_24(PARMS); break; + case BLIT_ONLYDST: BLIT_ONLYDST_24(PARMS); break; + case BLIT_NOTSRC: BLIT_NOTSRC_24(PARMS); break; + case BLIT_ONLYSRC: BLIT_ONLYSRC_24(PARMS); break; + case BLIT_NOTDST: BLIT_NOTDST_24(PARMS); break; + case BLIT_EOR: BLIT_EOR_24(PARMS); break; + case BLIT_NAND: BLIT_NAND_24(PARMS); break; + case BLIT_AND: BLIT_AND_24(PARMS); break; + case BLIT_NEOR: BLIT_NEOR_24(PARMS); break; + case BLIT_NOTONLYSRC: BLIT_NOTONLYSRC_24(PARMS); break; + case BLIT_NOTONLYDST: BLIT_NOTONLYDST_24(PARMS); break; + case BLIT_OR: BLIT_OR_24(PARMS); break; + case BLIT_TRUE: BLIT_TRUE_24(PARMS); break; + case BLIT_SWAP: BLIT_SWAP_24(PARMS); break; + } + } - } - else if (Bpp == 1) - { - /* 8-bit optimized */ - switch (opcode) - { - case BLIT_FALSE: BLIT_FALSE_8(PARMS); - break; - case BLIT_NOR: BLIT_NOR_8(PARMS); - break; - case BLIT_ONLYDST: BLIT_ONLYDST_8(PARMS); - break; - case BLIT_NOTSRC: BLIT_NOTSRC_8(PARMS); - break; - case BLIT_ONLYSRC: BLIT_ONLYSRC_8(PARMS); - break; - case BLIT_NOTDST: BLIT_NOTDST_8(PARMS); - break; - case BLIT_EOR: BLIT_EOR_8(PARMS); - break; - case BLIT_NAND: BLIT_NAND_8(PARMS); - break; - case BLIT_AND: BLIT_AND_8(PARMS); - break; - case BLIT_NEOR: BLIT_NEOR_8(PARMS); - break; - case BLIT_NOTONLYSRC: BLIT_NOTONLYSRC_8(PARMS); - break; - case BLIT_NOTONLYDST: BLIT_NOTONLYDST_8(PARMS); - break; - case BLIT_OR: BLIT_OR_8(PARMS); - break; - case BLIT_TRUE: BLIT_TRUE_8(PARMS); - break; - case BLIT_SWAP: BLIT_SWAP_8(PARMS); - break; + else if (Bpp == 2) { + + /* 16-bit optimized */ + switch (opcode) + { + case BLIT_FALSE: BLIT_FALSE_16(PARMS); break; + case BLIT_NOR: BLIT_NOR_16(PARMS); break; + case BLIT_ONLYDST: BLIT_ONLYDST_16(PARMS); break; + case BLIT_NOTSRC: BLIT_NOTSRC_16(PARMS); break; + case BLIT_ONLYSRC: BLIT_ONLYSRC_16(PARMS); break; + case BLIT_NOTDST: BLIT_NOTDST_16(PARMS); break; + case BLIT_EOR: BLIT_EOR_16(PARMS); break; + case BLIT_NAND: BLIT_NAND_16(PARMS); break; + case BLIT_AND: BLIT_AND_16(PARMS); break; + case BLIT_NEOR: BLIT_NEOR_16(PARMS); break; + case BLIT_NOTONLYSRC: BLIT_NOTONLYSRC_16(PARMS); break; + case BLIT_NOTONLYDST: BLIT_NOTONLYDST_16(PARMS); break; + case BLIT_OR: BLIT_OR_16(PARMS); break; + case BLIT_TRUE: BLIT_TRUE_16(PARMS); break; + case BLIT_SWAP: BLIT_SWAP_16(PARMS); break; + } + + } + else if (Bpp == 1) { + + /* 8-bit optimized */ + switch (opcode) + { + case BLIT_FALSE: BLIT_FALSE_8(PARMS); break; + case BLIT_NOR: BLIT_NOR_8(PARMS); break; + case BLIT_ONLYDST: BLIT_ONLYDST_8(PARMS); break; + case BLIT_NOTSRC: BLIT_NOTSRC_8(PARMS); break; + case BLIT_ONLYSRC: BLIT_ONLYSRC_8(PARMS); break; + case BLIT_NOTDST: BLIT_NOTDST_8(PARMS); break; + case BLIT_EOR: BLIT_EOR_8(PARMS); break; + case BLIT_NAND: BLIT_NAND_8(PARMS); break; + case BLIT_AND: BLIT_AND_8(PARMS); break; + case BLIT_NEOR: BLIT_NEOR_8(PARMS); break; + case BLIT_NOTONLYSRC: BLIT_NOTONLYSRC_8(PARMS); break; + case BLIT_NOTONLYDST: BLIT_NOTONLYDST_8(PARMS); break; + case BLIT_OR: BLIT_OR_8(PARMS); break; + case BLIT_TRUE: BLIT_TRUE_8(PARMS); break; + case BLIT_SWAP: BLIT_SWAP_8(PARMS); break; + } } } return 1; @@ -1296,11 +1323,11 @@ static uae_u32 REGPARAM2 picasso_FindCard(TrapContext* ctx) } boardinfo = AmigaBoardInfo; - if (gfxmem_bank.allocated && !picasso96_state.CardFound) + if (gfxmem_bank.allocated_size && !picasso96_state.CardFound) { /* Fill in MemoryBase, MemorySize */ put_long(AmigaBoardInfo + PSSO_BoardInfo_MemoryBase, gfxmem_bank.start); - put_long(AmigaBoardInfo + PSSO_BoardInfo_MemorySize, gfxmem_bank.allocated - reserved_gfxmem); + put_long(AmigaBoardInfo + PSSO_BoardInfo_MemorySize, gfxmem_bank.allocated_size - reserved_gfxmem); picasso96_state.CardFound = 1; /* mark our "card" as being found */ return -1; } @@ -1336,16 +1363,16 @@ static void FillBoardInfo(uaecptr amigamemptr, struct LibResolution* res, int wi put_byte(amigamemptr + PSSO_ModeInfo_Depth, depth); put_byte(amigamemptr + PSSO_ModeInfo_Flags, 0); put_word(amigamemptr + PSSO_ModeInfo_HorTotal, width); - put_word(amigamemptr + PSSO_ModeInfo_HorBlankSize, 0); + put_word(amigamemptr + PSSO_ModeInfo_HorBlankSize, 1); put_word(amigamemptr + PSSO_ModeInfo_HorSyncStart, 0); - put_word(amigamemptr + PSSO_ModeInfo_HorSyncSize, 0); + put_word(amigamemptr + PSSO_ModeInfo_HorSyncSize, 1); put_byte(amigamemptr + PSSO_ModeInfo_HorSyncSkew, 0); put_byte(amigamemptr + PSSO_ModeInfo_HorEnableSkew, 0); put_word(amigamemptr + PSSO_ModeInfo_VerTotal, height); - put_word(amigamemptr + PSSO_ModeInfo_VerBlankSize, 0); + put_word(amigamemptr + PSSO_ModeInfo_VerBlankSize, 1); put_word(amigamemptr + PSSO_ModeInfo_VerSyncStart, 0); - put_word(amigamemptr + PSSO_ModeInfo_VerSyncSize, 0); + put_word(amigamemptr + PSSO_ModeInfo_VerSyncSize, 1); put_byte(amigamemptr + PSSO_ModeInfo_first_union, 98); put_byte(amigamemptr + PSSO_ModeInfo_second_union, 14); @@ -1428,17 +1455,28 @@ static struct modeids mi[] = -1,-1,0 }; -static int AssignModeID(int w, int h, int* unkcnt) +static int AssignModeID(int w, int h, int *unkcnt) { int i; - for (i = 0; mi[i].width > 0; i++) - { +#ifdef NEWMODES2 + return 0x40000000 | (w << 14) | h; +#endif + for (i = 0; mi[i].width > 0; i++) { if (w == mi[i].width && h == mi[i].height) return 0x50001000 | (mi[i].id * 0x10000); } (*unkcnt)++; - write_log (_T("P96: Non-unique mode %dx%d\n"), w, h); + write_log(_T("P96: Non-unique mode %dx%d"), w, h); + if (256 - (*unkcnt) == mi[i - 1].id + 1) { + (*unkcnt) = 256 - 127; + write_log(_T(" (Skipped reserved)")); + } + else if (256 - (*unkcnt) == 11) { + (*unkcnt) = 511; + write_log(_T(" (Using extra)")); + } + write_log(_T("\n")); return 0x51001000 - (*unkcnt) * 0x10000; } @@ -1474,7 +1512,7 @@ static void init_alloc(TrapContext* ctx, int size) else if (uaegfx_active) { reserved_gfxmem = size; - picasso96_amem = gfxmem_bank.start + gfxmem_bank.allocated - size; + picasso96_amem = gfxmem_bank.start + gfxmem_bank.allocated_size - size; } picasso96_amemend = picasso96_amem + size; write_log(_T("P96 RESINFO: %08X-%08X (%d,%d)\n"), picasso96_amem, picasso96_amemend, size / PSSO_ModeInfo_sizeof, size); @@ -1498,7 +1536,7 @@ static int p96depth(int depth) return ok; } -static int missmodes[] = {640, 400, 640, 480, 800, 480, -1}; +static int missmodes[] = { 320, 200, 320, 240, 320, 256, 640, 400, 640, 480, 640, 512, 800, 600, 1024, 768, 1280, 1024, -1 }; static uaecptr uaegfx_card_install(TrapContext* ctx, uae_u32 size); @@ -1510,7 +1548,7 @@ static void picasso96_alloc2(TrapContext* ctx) xfree (newmodes); newmodes = nullptr; picasso96_amem = picasso96_amemend = 0; - if (gfxmem_bank.allocated == 0) + if (gfxmem_bank.allocated_size == 0) return; misscnt = 0; newmodes = xmalloc (struct PicassoResolution, MAX_PICASSO_MODES); @@ -1669,7 +1707,7 @@ static void inituaegfx(uaecptr ABI) flags = get_long(ABI + PSSO_BoardInfo_Flags); flags &= 0xffff0000; if (flags & BIF_NOBLITTER) - write_log (_T("P96: Blitter disabled in devs:monitors/uaegfx!\n")); + write_log(_T("P96: Blitter disabled in devs:monitors/uaegfx!\n")); flags |= BIF_BLITTER | BIF_NOMEMORYMODEMIX; flags &= ~BIF_HARDWARESPRITE; @@ -1728,7 +1766,7 @@ static void addmode(uaecptr AmigaBoardInfo, uaecptr* amem, struct LibResolution* { if (!p96depth(depth)) continue; - if (gfxmem_bank.allocated >= w * h * (depth + 7) / 8) + if (gfxmem_bank.allocated_size >= w * h * (depth + 7) / 8) { FillBoardInfo(*amem, res, w, h, depth); *amem += PSSO_ModeInfo_sizeof; @@ -1785,7 +1823,7 @@ static uae_u32 REGPARAM2 picasso_InitCard(TrapContext* ctx) } if (amem > picasso96_amemend) - write_log (_T("P96: display resolution list corruption %08x<>%08x (%d)\n"), amem, picasso96_amemend, i); + write_log(_T("P96: display resolution list corruption %08x<>%08x (%d)\n"), amem, picasso96_amemend, i); return -1; } @@ -1829,8 +1867,8 @@ void picasso_enablescreen(int on) if (!init_picasso_screen_called) init_picasso_screen(); + setconvert(); picasso_refresh(); - checkrtglibrary(); } static void resetpalette() @@ -1998,6 +2036,10 @@ static void picasso_SetPanningInit() { picasso96_state.XYOffset = picasso96_state.Address + picasso96_state.XOffset * picasso96_state.BytesPerPixel + picasso96_state.YOffset * picasso96_state.BytesPerRow; + if (picasso96_state_uaegfx.VirtualWidth > picasso96_state_uaegfx.Width || picasso96_state_uaegfx.VirtualHeight > picasso96_state_uaegfx.Height) + picasso96_state_uaegfx.BigAssBitmap = 1; + else + picasso96_state_uaegfx.BigAssBitmap = 0; } static uae_u32 REGPARAM2 picasso_SetPanning(TrapContext* ctx) @@ -2007,7 +2049,7 @@ static uae_u32 REGPARAM2 picasso_SetPanning(TrapContext* ctx) uaecptr bi = m68k_areg (regs, 0); uaecptr bmeptr = get_long(bi + PSSO_BoardInfo_BitMapExtra); /* Get our BoardInfo ptr's BitMapExtra ptr */ uae_u16 bme_width, bme_height; - uae_u32 rgbf; + RGBFTYPE rgbf; if (oldscr == 0) { @@ -2029,7 +2071,7 @@ static uae_u32 REGPARAM2 picasso_SetPanning(TrapContext* ctx) put_word(bi + PSSO_BoardInfo_YOffset, picasso96_state.YOffset); picasso96_state.VirtualWidth = bme_width; picasso96_state.VirtualHeight = bme_height; - picasso96_state.RGBFormat = m68k_dreg (regs, 7); + picasso96_state.RGBFormat = (RGBFTYPE)m68k_dreg (regs, 7); picasso96_state.BytesPerPixel = GetBytesPerPixel(picasso96_state.RGBFormat); picasso96_state.BytesPerRow = picasso96_state.VirtualWidth * picasso96_state.BytesPerPixel; picasso_SetPanningInit(); @@ -2282,7 +2324,7 @@ STATIC_INLINE int BlitRectHelper() return do_blitrect_frame_buffer(ri, dstri, srcx, srcy, dstx, dsty, width, height, mask, opcode); } -STATIC_INLINE int BlitRect(uaecptr ri, uaecptr dstri, +static int BlitRect(uaecptr ri, uaecptr dstri, unsigned long srcx, unsigned long srcy, unsigned long dstx, unsigned long dsty, unsigned long width, unsigned long height, uae_u8 mask, BLIT_OPCODE opcode) { @@ -2473,6 +2515,9 @@ static uae_u32 REGPARAM2 picasso_BlitPattern(TrapContext* ctx) result = 1; } + if (pattern.Size >= 16) + result = 0; + if (result) { uae_u32 fgpen, bgpen; @@ -2802,6 +2847,10 @@ static uae_u32 REGPARAM2 picasso_SetDisplay(TrapContext* ctx) void init_hz_p96() { p96vblank = vblank_hz; + if (p96vblank <= 0) + p96vblank = 60; + if (p96vblank >= 300) + p96vblank = 300; p96syncrate = maxvpos_nom * vblank_hz / p96vblank; } @@ -2935,10 +2984,10 @@ static uae_u32 REGPARAM2 picasso_BlitPlanar2Chunky(TrapContext* ctx) } /* NOTE: Watch for those planeptrs of 0x00000000 and 0xFFFFFFFF for all zero / all one bitmaps !!!! */ -static void PlanarToDirect(struct RenderInfo* ri, struct BitMap* bm, - unsigned long srcx, unsigned long srcy, - unsigned long dstx, unsigned long dsty, - unsigned long width, unsigned long height, uae_u8 mask, struct ColorIndexMapping* cim) +static void PlanarToDirect(struct RenderInfo *ri, struct BitMap *bm, + unsigned long srcx, unsigned long srcy, + unsigned long dstx, unsigned long dsty, + unsigned long width, unsigned long height, uae_u8 mask, uaecptr acim) { int j; int bpp = GetBytesPerPixel(ri->RGBFormat); @@ -2947,6 +2996,8 @@ static void PlanarToDirect(struct RenderInfo* ri, struct BitMap* bm, int Depth = bm->Depth; unsigned long rows; long eol_offset; + int maxc = -1; + uae_u32 cim[256]; if (!bpp) return; @@ -2982,42 +3033,71 @@ static void PlanarToDirect(struct RenderInfo* ri, struct BitMap* bm, v |= ((*PLANAR[k] >> bitoffs) & 1) << k; } } + + // most operations use only low palette values + // do not fetch and convert whole palette unless needed + if (v > maxc) { + int vc = v; + if (vc < 3) + vc = 3; + else if (vc < 7) + vc = 7; + else if (vc < 15) + vc = 15; + else if (vc < 31) + vc = 32; + else if (vc < 63) + vc = 63; + else + vc = 255; + //get_longs(&cim[maxc + 1], acim + 4 + (maxc + 1) * 4, vc - maxc); + int cnt = vc - maxc; + if (cnt > 0) { + uaecptr addr = acim + 4 + (maxc + 1) * 4; + uae_u32 *p = (uae_u32*)&cim[maxc + 1]; + for (int i = 0; i < vc - maxc; i++) + { + *p++ = get_long(addr); + addr += 4; + } + } + for (int i = maxc + 1; i <= vc; i++) { + endianswap(&cim[i], bpp); + } + maxc = vc; + } + switch (bpp) { case 2: - reinterpret_cast(image2)[0] = uae_u16(cim->Colors[v]); + ((uae_u16 *)image2)[0] = (uae_u16)(cim[v]); image2 += 2; break; case 3: - image2[0] = cim->Colors[v] >> 0; - image2[1] = cim->Colors[v] >> 8; - image2[2] = cim->Colors[v] >> 16; + image2[0] = cim[v] >> 0; + image2[1] = cim[v] >> 8; + image2[2] = cim[v] >> 16; image2 += 3; break; case 4: - reinterpret_cast(image2)[0] = cim->Colors[v]; + ((uae_u32 *)image2)[0] = cim[v]; image2 += 4; break; } bitoffs--; bitoffs &= 7; - if (bitoffs == 7) - { + if (bitoffs == 7) { int k; - for (k = 0; k < Depth; k++) - { - if (PLANAR[k] != &all_zeros_bitmap && PLANAR[k] != &all_ones_bitmap) - { + for (k = 0; k < Depth; k++) { + if (PLANAR[k] != &all_zeros_bitmap && PLANAR[k] != &all_ones_bitmap) { PLANAR[k]++; } } } } - for (i = 0; i < Depth; i++) - { - if (PLANAR[i] != &all_zeros_bitmap && PLANAR[i] != &all_ones_bitmap) - { + for (i = 0; i < Depth; i++) { + if (PLANAR[i] != &all_zeros_bitmap && PLANAR[i] != &all_ones_bitmap) { PLANAR[i] += eol_offset; } } @@ -3067,7 +3147,6 @@ static uae_u32 REGPARAM2 picasso_BlitPlanar2Direct(TrapContext* ctx) uae_u8 Mask = m68k_dreg (regs, 7); struct RenderInfo local_ri; struct BitMap local_bm; - struct ColorIndexMapping local_cim; uae_u32 result = 0; if (NOBLITTER) @@ -3080,10 +3159,9 @@ static uae_u32 REGPARAM2 picasso_BlitPlanar2Direct(TrapContext* ctx) if (CopyRenderInfoStructureA2U(ri, &local_ri) && CopyBitMapStructureA2U(bm, &local_bm)) { Mask = 0xFF; - CopyColorIndexMappingA2U(cim, &local_cim, GetBytesPerPixel(local_ri.RGBFormat)); P96TRACE((_T("BlitPlanar2Direct(%d, %d, %d, %d, %d, %d) Minterm 0x%x, Mask 0x%x, Depth %d\n"), srcx, srcy, dstx, dsty, width, height, minterm, Mask, local_bm.Depth)); - PlanarToDirect(&local_ri, &local_bm, srcx, srcy, dstx, dsty, width, height, Mask, &local_cim); + PlanarToDirect(&local_ri, &local_bm, srcx, srcy, dstx, dsty, width, height, Mask, cim); result = 1; } return result; @@ -3107,54 +3185,477 @@ static void statusline(uae_u8* dst) } } -// TODO: Change this to use SDL2 native conversions -static void copyall(uae_u8* src, uae_u8* dst) +static void copyrow(uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcbytesperrow, int srcpixbytes, int dy, int dstbytesperrow, int dstpixbytes, bool direct, int convert_mode) { - if (picasso96_state.RGBFormat == RGBFB_R5G6B5) - copy_screen_16bit_swap(dst, src, picasso96_state.Width * picasso96_state.Height * 2); - else if (picasso96_state.RGBFormat == RGBFB_CLUT) - { - int pixels = picasso96_state.Width * picasso96_state.Height; - copy_screen_8bit(dst, src, pixels, picasso_vidinfo.clut); + uae_u8 *src2 = src + y * srcbytesperrow; + uae_u8 *dst2 = dst + dy * dstbytesperrow; + int endx = x + width, endx4; + int dstpix = dstpixbytes; + int srcpix = srcpixbytes; + + if (direct) { + memcpy(dst2 + x * dstpix, src2 + x * srcpix, width * dstpix); + return; + } + // native match? + if (currprefs.gfx_api) { + switch (convert_mode) + { +#ifdef WORDS_BIGENDIAN + case RGBFB_A8R8G8B8_32: + case RGBFB_R5G6B5_16: +#else + case RGBFB_B8G8R8A8_32: + case RGBFB_R5G6B5PC_16: +#endif + memcpy(dst2 + x * dstpix, src2 + x * srcpix, width * dstpix); + return; + } + } + else { + switch (convert_mode) + { +#ifdef WORDS_BIGENDIAN + case RGBFB_A8R8G8B8_32: + case RGBFB_R5G6B5_16: +#else + case RGBFB_B8G8R8A8_32: + case RGBFB_R5G6B5PC_16: +#endif + memcpy(dst2 + x * dstpix, src2 + x * srcpix, width * dstpix); + return; + } + } + + endx4 = endx & ~3; + + switch (convert_mode) + { + /* 24bit->32bit */ + case RGBFB_R8G8B8_32: + while (x < endx) { + ((uae_u32*)dst2)[x] = (src2[x * 3 + 0] << 16) | (src2[x * 3 + 1] << 8) | (src2[x * 3 + 2] << 0); + x++; + } + break; + case RGBFB_B8G8R8_32: + while (x < endx) { + ((uae_u32*)dst2)[x] = ((uae_u32*)(src2 + x * 3))[0] & 0x00ffffff; + x++; + } + break; + + /* 32bit->32bit */ + case RGBFB_R8G8B8A8_32: + while (x < endx) { + ((uae_u32*)dst2)[x] = (src2[x * 4 + 0] << 16) | (src2[x * 4 + 1] << 8) | (src2[x * 4 + 2] << 0); + x++; + } + break; + case RGBFB_A8R8G8B8_32: + while (x < endx) { + ((uae_u32*)dst2)[x] = (src2[x * 4 + 1] << 16) | (src2[x * 4 + 2] << 8) | (src2[x * 4 + 3] << 0); + x++; + } + break; + case RGBFB_A8B8G8R8_32: + while (x < endx) { + ((uae_u32*)dst2)[x] = ((uae_u32*)src2)[x] >> 8; + x++; + } + break; + + /* 15/16bit->32bit */ + case RGBFB_R5G6B5PC_32: + case RGBFB_R5G5B5PC_32: + case RGBFB_R5G6B5_32: + case RGBFB_R5G5B5_32: + case RGBFB_B5G6R5PC_32: + case RGBFB_B5G5R5PC_32: + { + while ((x & 3) && x < endx) { + ((uae_u32*)dst2)[x] = p96_rgbx16[((uae_u16*)src2)[x]]; + x++; + } + while (x < endx4) { + ((uae_u32*)dst2)[x] = p96_rgbx16[((uae_u16*)src2)[x]]; + x++; + ((uae_u32*)dst2)[x] = p96_rgbx16[((uae_u16*)src2)[x]]; + x++; + ((uae_u32*)dst2)[x] = p96_rgbx16[((uae_u16*)src2)[x]]; + x++; + ((uae_u32*)dst2)[x] = p96_rgbx16[((uae_u16*)src2)[x]]; + x++; + } + while (x < endx) { + ((uae_u32*)dst2)[x] = p96_rgbx16[((uae_u16*)src2)[x]]; + x++; + } + } + break; + + /* 16/15bit->16bit */ + case RGBFB_R5G5B5PC_16: + case RGBFB_R5G6B5_16: + case RGBFB_R5G5B5_16: + case RGBFB_B5G5R5PC_16: + case RGBFB_B5G6R5PC_16: + case RGBFB_R5G6B5PC_16: + { + while ((x & 3) && x < endx) { + ((uae_u16*)dst2)[x] = (uae_u16)p96_rgbx16[((uae_u16*)src2)[x]]; + x++; + } + while (x < endx4) { + ((uae_u16*)dst2)[x] = (uae_u16)p96_rgbx16[((uae_u16*)src2)[x]]; + x++; + ((uae_u16*)dst2)[x] = (uae_u16)p96_rgbx16[((uae_u16*)src2)[x]]; + x++; + ((uae_u16*)dst2)[x] = (uae_u16)p96_rgbx16[((uae_u16*)src2)[x]]; + x++; + ((uae_u16*)dst2)[x] = (uae_u16)p96_rgbx16[((uae_u16*)src2)[x]]; + x++; + } + while (x < endx) { + ((uae_u16*)dst2)[x] = (uae_u16)p96_rgbx16[((uae_u16*)src2)[x]]; + x++; + } + } + break; + + /* 24bit->16bit */ + case RGBFB_R8G8B8_16: + while (x < endx) { + uae_u8 r, g, b; + r = src2[x * 3 + 0]; + g = src2[x * 3 + 1]; + b = src2[x * 3 + 2]; + ((uae_u16*)dst2)[x] = p96_rgbx16[(((r >> 3) & 0x1f) << 11) | (((g >> 2) & 0x3f) << 5) | (((b >> 3) & 0x1f) << 0)]; + x++; + } + break; + case RGBFB_B8G8R8_16: + while (x < endx) { + uae_u32 v; + v = ((uae_u32*)(&src2[x * 3]))[0] >> 8; + ((uae_u16*)dst2)[x] = p96_rgbx16[(((v >> (8 + 3)) & 0x1f) << 11) | (((v >> (0 + 2)) & 0x3f) << 5) | (((v >> (16 + 3)) & 0x1f) << 0)]; + x++; + } + break; + + /* 32bit->16bit */ + case RGBFB_R8G8B8A8_16: + while (x < endx) { + uae_u32 v; + v = ((uae_u32*)src2)[x]; + ((uae_u16*)dst2)[x] = p96_rgbx16[(((v >> (0 + 3)) & 0x1f) << 11) | (((v >> (8 + 2)) & 0x3f) << 5) | (((v >> (16 + 3)) & 0x1f) << 0)]; + x++; + } + break; + case RGBFB_A8R8G8B8_16: + while (x < endx) { + uae_u32 v; + v = ((uae_u32*)src2)[x]; + ((uae_u16*)dst2)[x] = p96_rgbx16[(((v >> (8 + 3)) & 0x1f) << 11) | (((v >> (16 + 2)) & 0x3f) << 5) | (((v >> (24 + 3)) & 0x1f) << 0)]; + x++; + } + break; + case RGBFB_A8B8G8R8_16: + while (x < endx) { + uae_u32 v; + v = ((uae_u32*)src2)[x]; + ((uae_u16*)dst2)[x] = p96_rgbx16[(((v >> (24 + 3)) & 0x1f) << 11) | (((v >> (16 + 2)) & 0x3f) << 5) | (((v >> (8 + 3)) & 0x1f) << 0)]; + x++; + } + break; + case RGBFB_B8G8R8A8_16: + while (x < endx) { + uae_u32 v; + v = ((uae_u32*)src2)[x]; + ((uae_u16*)dst2)[x] = p96_rgbx16[(((v >> (16 + 3)) & 0x1f) << 11) | (((v >> (8 + 2)) & 0x3f) << 5) | (((v >> (0 + 3)) & 0x1f) << 0)]; + x++; + } + break; + + /* 8bit->32bit */ + case RGBFB_CLUT_RGBFB_32: + { + while ((x & 3) && x < endx) { + ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + x++; + } + while (x < endx4) { + ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + x++; + ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + x++; + ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + x++; + ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + x++; + } + while (x < endx) { + ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + x++; + } + } + break; + + /* 8bit->16bit */ + case RGBFB_CLUT_RGBFB_16: + { + while ((x & 3) && x < endx) { + ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + x++; + } + while (x < endx4) { + ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + x++; + ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + x++; + ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + x++; + ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + x++; + } + while (x < endx) { + ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + x++; + } + } + break; } - else - copy_screen_32bit_to_16bit(dst, src, picasso96_state.Width * picasso96_state.Height * 4); } -static void flushpixels() +void fb_copyrow(uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcpixbytes, int dy) { + copyrow(src, dst, x, y, width, 0, srcpixbytes, dy, picasso_vidinfo.rowbytes, picasso_vidinfo.pixbytes, picasso96_state.RGBFormat == host_mode, picasso_convert); +} + +static void copyallinvert(uae_u8 *src, uae_u8 *dst, int pwidth, int pheight, int srcbytesperrow, int srcpixbytes, int dstbytesperrow, int dstpixbytes, bool direct, int mode_convert) +{ + int x, y, w; + + w = pwidth * dstpixbytes; + if (direct) { + for (y = 0; y < pheight; y++) { + for (x = 0; x < w; x++) + dst[x] = src[x] ^ 0xff; + dst += dstbytesperrow; + src += srcbytesperrow; + } + } + else { + uae_u8 *src2 = src; + for (y = 0; y < pheight; y++) { + for (x = 0; x < w; x++) + src2[x] ^= 0xff; + copyrow(src, dst, 0, y, pwidth, srcbytesperrow, srcpixbytes, y, dstbytesperrow, dstpixbytes, direct, mode_convert); + for (x = 0; x < w; x++) + src2[x] ^= 0xff; + src2 += srcbytesperrow; + } + } +} + +// TODO: Change this to use SDL2 native conversions +static void copyall(uae_u8 *src, uae_u8 *dst, int pwidth, int pheight, int srcbytesperrow, int srcpixbytes, int dstbytesperrow, int dstpixbytes, bool direct, int mode_convert) +{ + //if (picasso96_state.RGBFormat == RGBFB_R5G6B5) + // copy_screen_16bit_swap(dst, src, picasso96_state.Width * picasso96_state.Height * 2); + //else if (picasso96_state.RGBFormat == RGBFB_CLUT) + //{ + // int pixels = picasso96_state.Width * picasso96_state.Height; + // copy_screen_8bit(dst, src, pixels, picasso_vidinfo.clut); + //} + //else + // copy_screen_32bit_to_16bit(dst, src, picasso96_state.Width * picasso96_state.Height * 4); + + int y; + + int w = pwidth * picasso_vidinfo.pixbytes; + for (y = 0; y < pheight; y++) { + memcpy(dst, src, w); + dst += dstbytesperrow; + src += srcbytesperrow; + } +} + +bool picasso_flushpixels(int index) +{ + uae_u8 *src_start; + uae_u8 *src_end; + int lock = 0; + uae_u8* dst = nullptr; + unsigned long gwwcnt; + int pwidth = picasso96_state.Width > picasso96_state.VirtualWidth ? picasso96_state.VirtualWidth : picasso96_state.Width; + int pheight = picasso96_state.Height > picasso96_state.VirtualHeight ? picasso96_state.VirtualHeight : picasso96_state.Height; + int maxy = -1; + int miny = pheight - 1; + int flushlines = 0, matchcount = 0; uae_u8* src = gfxmem_bank.start + natmem_offset; int off = picasso96_state.XYOffset - gfxmem_bank.start; - uae_u8* src_start = src + off; - uae_u8* src_end = src + off + picasso96_state.BytesPerRow * picasso96_state.Height; - uae_u8* dst = nullptr; + + src_start = src + off; + src_end = src + off + picasso96_state.BytesPerRow * picasso96_state.Height; + if (!picasso_vidinfo.extra_mem || src_start >= src_end) - return; + return false; - if (doskip() && p96skipmode == 1) - return; + if (full_refresh || rtg_clear_flag) + full_refresh = -1; - dst = gfx_lock_picasso(); - if (dst == nullptr) - return; + for (;;) { + bool dofull; - copyall(src + off, dst); + gwwcnt = 0; + + if (doskip() && p96skipmode == 1) { + break; + } + + if (full_refresh < 0) { + gwwcnt = (src_end - src_start) / gwwpagesize[index] + 1; + full_refresh = 1; + for (int i = 0; i < gwwcnt; i++) + gwwbuf[index][i] = src_start + i * gwwpagesize[index]; + } + else { + unsigned long ps; + gwwcnt = gwwbufsize[index]; + //if (mman_GetWriteWatch(src_start, src_end - src_start, gwwbuf[index], &gwwcnt, &ps)) + // break; + } + + matchcount += gwwcnt; + + if (gwwcnt == 0) + break; + + dofull = gwwcnt >= ((src_end - src_start) / gwwpagesize[index]) * 80 / 100; + + dst = gfx_lock_picasso(); + if (rtg_clear_flag) + rtg_clear_flag--; + if (dst == NULL) + break; + lock = 1; + + if (doskip() && p96skipmode == 2) { + break; + } + + if (dofull) { + copyall(src + off, dst, pwidth, pheight, + picasso96_state.BytesPerRow, picasso96_state.BytesPerPixel, + picasso_vidinfo.rowbytes, picasso_vidinfo.pixbytes, + picasso96_state.RGBFormat == host_mode, picasso_convert); + + miny = 0; + maxy = pheight; + flushlines = -1; + break; + } + + for (int i = 0; i < gwwcnt; i++) { + uae_u8 *p = (uae_u8*)gwwbuf[index][i]; + + if (p >= src_start && p < src_end) { + int y, x, realoffset; + + if (p >= src + off) { + realoffset = p - (src + off); + } + else { + realoffset = 0; + } + + y = realoffset / picasso96_state.BytesPerRow; + if (y < pheight) { + int w = gwwpagesize[index] / picasso96_state.BytesPerPixel; + x = (realoffset % picasso96_state.BytesPerRow) / picasso96_state.BytesPerPixel; + if (x < pwidth) { + copyrow(src + off, dst, x, y, pwidth - x, + picasso96_state.BytesPerRow, picasso96_state.BytesPerPixel, + y, picasso_vidinfo.rowbytes, picasso_vidinfo.pixbytes, + picasso96_state.RGBFormat == host_mode, picasso_convert); + flushlines++; + } + w = (gwwpagesize[index] - (picasso96_state.BytesPerRow - x * picasso96_state.BytesPerPixel)) / picasso96_state.BytesPerPixel; + if (y < miny) + miny = y; + y++; + while (y < pheight && w > 0) { + int maxw = w > pwidth ? pwidth : w; + copyrow(src + off, dst, 0, y, maxw, + picasso96_state.BytesPerRow, picasso96_state.BytesPerPixel, + y, picasso_vidinfo.rowbytes, picasso_vidinfo.pixbytes, + picasso96_state.RGBFormat == host_mode, picasso_convert); + w -= maxw; + y++; + flushlines++; + } + if (y > maxy) + maxy = y; + } + + } + + } + break; + } + + //copyall(src + off, dst); if (currprefs.leds_on_screen) statusline(dst); - gfx_unlock_picasso(); + if (lock) + gfx_unlock_picasso(); + if (dst && gwwcnt) { + full_refresh = 0; + } + return lock != 0; } +extern addrbank gfxmem_bank; MEMORY_FUNCTIONS(gfxmem); - addrbank gfxmem_bank = { gfxmem_lget, gfxmem_wget, gfxmem_bget, gfxmem_lput, gfxmem_wput, gfxmem_bput, - gfxmem_xlate, gfxmem_check, nullptr, _T("RTG RAM"), - dummy_lgeti, dummy_wgeti, ABFLAG_RAM + gfxmem_xlate, gfxmem_check, NULL, NULL, _T("RTG RAM"), + dummy_lgeti, dummy_wgeti, + ABFLAG_RAM | ABFLAG_RTG, 0, 0 }; +extern addrbank gfxmem2_bank; +MEMORY_FUNCTIONS(gfxmem2); +addrbank gfxmem2_bank = { + gfxmem2_lget, gfxmem2_wget, gfxmem2_bget, + gfxmem2_lput, gfxmem2_wput, gfxmem2_bput, + gfxmem2_xlate, gfxmem2_check, NULL, NULL, _T("RTG RAM #2"), + dummy_lgeti, dummy_wgeti, + ABFLAG_RAM | ABFLAG_RTG, 0, 0 +}; +extern addrbank gfxmem3_bank; +MEMORY_FUNCTIONS(gfxmem3); +addrbank gfxmem3_bank = { + gfxmem3_lget, gfxmem3_wget, gfxmem3_bget, + gfxmem3_lput, gfxmem3_wput, gfxmem3_bput, + gfxmem3_xlate, gfxmem3_check, NULL, NULL, _T("RTG RAM #3"), + dummy_lgeti, dummy_wgeti, + ABFLAG_RAM | ABFLAG_RTG, 0, 0 +}; +extern addrbank gfxmem4_bank; +MEMORY_FUNCTIONS(gfxmem4); +addrbank gfxmem4_bank = { + gfxmem4_lget, gfxmem4_wget, gfxmem4_bget, + gfxmem4_lput, gfxmem4_wput, gfxmem4_bput, + gfxmem4_xlate, gfxmem4_check, NULL, NULL, _T("RTG RAM #4"), + dummy_lgeti, dummy_wgeti, + ABFLAG_RAM | ABFLAG_RTG, 0, 0 +}; +addrbank *gfxmem_banks[MAX_RTG_BOARDS]; /* Call this function first, near the beginning of code flow * Place in InitGraphics() which seems reasonable... @@ -3163,6 +3664,11 @@ void InitPicasso96() { int i; + gfxmem_banks[0] = &gfxmem_bank; + gfxmem_banks[1] = &gfxmem2_bank; + gfxmem_banks[2] = &gfxmem3_bank; + gfxmem_banks[3] = &gfxmem4_bank; + //fastscreen oldscr = 0; //fastscreen @@ -3607,7 +4113,7 @@ uae_u32 picasso_demux(uae_u32 arg, TrapContext* ctx) case 31: return picasso_InvertRect(ctx); case 32: return picasso_BlitPlanar2Direct(ctx); //case 34: return picasso_WaitVerticalSync (ctx); - case 35: return gfxmem_bank.allocated ? 1 : 0; + case 35: return gfxmem_bank.allocated_size ? 1 : 0; case 36: return picasso_SetSprite(ctx); case 37: return picasso_SetSpritePosition(ctx); case 38: return picasso_SetSpriteImage(ctx); @@ -3649,9 +4155,9 @@ uae_u8* restore_p96(uae_u8* src) set_gc_called = !!(flags & 2); set_panning_called = !!(flags & 4); interrupt_enabled = !!(flags & 32); - changed_prefs.rtgmem_size = restore_u32(); + changed_prefs.rtgboards[0].rtgmem_size = restore_u32(); picasso96_state.Address = restore_u32(); - picasso96_state.RGBFormat = restore_u32(); + picasso96_state.RGBFormat = (RGBFTYPE)restore_u32(); picasso96_state.Width = restore_u16(); picasso96_state.Height = restore_u16(); picasso96_state.VirtualWidth = restore_u16(); @@ -3685,7 +4191,7 @@ uae_u8* save_p96(int* len, uae_u8* dstptr) uae_u8 *dstbak, *dst; int i; - if (currprefs.rtgmem_size == 0) + if (currprefs.rtgboards[0].rtgmem_size == 0) return nullptr; if (dstptr) dstbak = dst = dstptr; @@ -3694,7 +4200,7 @@ uae_u8* save_p96(int* len, uae_u8* dstptr) save_u32 (2); save_u32 ((picasso_on ? 1 : 0) | (set_gc_called ? 2 : 0) | (set_panning_called ? 4 : 0) | (interrupt_enabled ? 32 : 0) | 64); - save_u32 (currprefs.rtgmem_size); + save_u32 (currprefs.rtgboards[0].rtgmem_size); save_u32 (picasso96_state.Address); save_u32 (picasso96_state.RGBFormat); save_u16 (picasso96_state.Width); diff --git a/src/osdep/sysconfig.h b/src/osdep/sysconfig.h index 09c4a5ca..0ff32a43 100644 --- a/src/osdep/sysconfig.h +++ b/src/osdep/sysconfig.h @@ -1,4 +1,9 @@ +#pragma once +#pragma warning (disable : 4761) +#pragma warning (disable : 4996) +#pragma warning (disable : 4018) + #define SUPPORT_THREADS #define MAX_DPATH 256 @@ -61,6 +66,8 @@ #undef ENFORCER #endif +typedef long uae_atomic; + /* src/sysconfig.h. Generated automatically by configure. */ /* src/sysconfig.h.in. Generated automatically from configure.in by autoheader. */ diff --git a/src/osdep/target.h b/src/osdep/target.h index e2534464..b38e500b 100644 --- a/src/osdep/target.h +++ b/src/osdep/target.h @@ -7,9 +7,10 @@ */ #pragma once -#include "SDL.h" -#define TARGET_NAME "Amiberry" +#define TARGET_NAME _T("Amiberry") +#define TARGET_PROVIDES_DEFAULT_PREFS +#define TARGET_NO_DITHER #define NO_MAIN_IN_MAIN_C @@ -56,17 +57,8 @@ int count_HDs(struct uae_prefs *p); extern void gui_force_rtarea_hdchange(); extern bool hardfile_testrdb(const TCHAR *filename); -#ifdef __cplusplus -extern "C" { -#endif - void trace_begin(void); - void trace_end(void); -#ifdef __cplusplus -} -#endif - -STATIC_INLINE size_t uae_tcslcpy(TCHAR *dst, const TCHAR *src, size_t size) +static size_t uae_tcslcpy(TCHAR *dst, const TCHAR *src, size_t size) { if (size == 0) { return 0; @@ -81,7 +73,7 @@ STATIC_INLINE size_t uae_tcslcpy(TCHAR *dst, const TCHAR *src, size_t size) return src_len; } -STATIC_INLINE size_t uae_strlcpy(char *dst, const char *src, size_t size) +static size_t uae_strlcpy(char *dst, const char *src, size_t size) { if (size == 0) { return 0; @@ -96,7 +88,7 @@ STATIC_INLINE size_t uae_strlcpy(char *dst, const char *src, size_t size) return src_len; } -STATIC_INLINE int max(int x, int y) +static int max(int x, int y) { return x > y ? x : y; } \ No newline at end of file diff --git a/src/osdep/writelog.cpp b/src/osdep/writelog.cpp index 22c06266..e513e5f3 100644 --- a/src/osdep/writelog.cpp +++ b/src/osdep/writelog.cpp @@ -15,13 +15,13 @@ FILE *debugfile = NULL; void console_out (const TCHAR *format,...) { - va_list parms; - TCHAR buffer[WRITE_LOG_BUF_SIZE]; + //va_list parms; + //TCHAR buffer[WRITE_LOG_BUF_SIZE]; - va_start (parms, format); - vsnprintf (buffer, WRITE_LOG_BUF_SIZE-1, format, parms); - va_end (parms); - printf(buffer); + //va_start (parms, format); + //vsnprintf (buffer, WRITE_LOG_BUF_SIZE-1, format, parms); + //va_end (parms); + //printf(buffer); } void writeconsole(const TCHAR *buffer) @@ -31,19 +31,19 @@ void writeconsole(const TCHAR *buffer) void write_log (const char *format,...) { - int count; - int numwritten; - TCHAR buffer[WRITE_LOG_BUF_SIZE]; + //int count; + //int numwritten; + //TCHAR buffer[WRITE_LOG_BUF_SIZE]; - va_list parms; - va_start (parms, format); - count = vsnprintf( buffer, WRITE_LOG_BUF_SIZE-1, format, parms ); - if( debugfile ) - { - fprintf( debugfile, buffer ); - fflush (debugfile); - } - va_end (parms); + //va_list parms; + //va_start (parms, format); + //count = vsnprintf( buffer, WRITE_LOG_BUF_SIZE-1, format, parms ); + //if( debugfile ) + //{ + // fprintf( debugfile, buffer ); + // fflush (debugfile); + //} + //va_end (parms); } void jit_abort (const TCHAR *format,...) diff --git a/src/rommgr.cpp b/src/rommgr.cpp index 8a68c505..71007333 100644 --- a/src/rommgr.cpp +++ b/src/rommgr.cpp @@ -17,6 +17,7 @@ #include "crc32.h" #include "autoconf.h" +#include "filesys.h" static struct romlist *rl; static int romlist_cnt; @@ -110,6 +111,8 @@ static struct romdata roms[] = { 0xffffffff, 0, 0, 0, 0, 0, _T("AROS") }, { _T(" ROM Disabled"), 0, 0, 0, 0, _T("NOROM\0"), 0, 87, 0, 0, ROMTYPE_NONE, 0, 0, NULL, 0xffffffff, 0, 0, 0, 0, 0, _T("NOROM") }, + { _T(" Enabled"), 0, 0, 0, 0, _T("ENABLED\0"), 0, 142, 0, 0, ROMTYPE_NOT, 0, 0, NULL, + 0xffffffff, 0, 0, 0, 0, 0, _T("ENABLED") }, { _T("Cloanto Amiga Forever ROM key"), 0, 0, 0, 0, 0, 2069, 0, 0, 1, ROMTYPE_KEY, 0, 0, NULL, 0x869ae1b1, 0x801bbab3,0x2e3d3738,0x6dd1636d,0x4f1d6fa7,0xe21d5874 }, @@ -118,6 +121,13 @@ static struct romdata roms[] = { { _T("Cloanto Amiga Forever 2010 ROM key"), 0, 0, 0, 0, 0, 1544, 73, 0, 1, ROMTYPE_KEY, 0, 0, NULL, 0x8c4dd05c, 0x05034f62,0x0b5bb7b2,0x86954ea9,0x164fdb90,0xfb2897a4 }, + { _T("KS ROM Velvet 23.93"), 23, 93, 23, 93, _T("VELVET\0"), 131072, 125, 0, 0, ROMTYPE_KICK, 0, 0, NULL, + 0xadcb44c9, 0x7c36b2ba,0x298da3da,0xce60d0ba,0x8511d470,0x76a40d5c, NULL, NULL }, + ALTROMPN(125, 1, 1, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x1d988ab8, 0xee3988a2, 0xb2693334, 0x0239d1d9, 0xf50d4fb3, 0xe0daf3bc) + ALTROMPN(125, 1, 2, 32768, ROMTYPE_QUAD | ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xe466b28f, 0x3e197d69, 0xcffa3e1a, 0x0c291d57, 0xb53f7d1f, 0xcb858cf7) + ALTROMPN(125, 1, 3, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x715988a9, 0x08c36600, 0x3948c4c5, 0x4216ef8c, 0x17ebe16c, 0xc91d3b7a) + ALTROMPN(125, 1, 4, 32768, ROMTYPE_QUAD | ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xc4dc7e6a, 0x66b231d0, 0x8425c858, 0xdfcd36d2, 0xd38a0df8, 0x518e06a4) + { _T("KS ROM v1.0 (A1000)(NTSC)"), 1, 0, 1, 0, _T("A1000\0"), 262144, 1, 0, 0, ROMTYPE_KICK, 0, 0, NULL, 0x299790ff, 0x00C15406,0xBEB4B8AB,0x1A16AA66,0xC05860E1,0xA7C1AD79 }, { _T("KS ROM v1.1 (A1000)(NTSC)"), 1, 1, 31, 34, _T("A1000\0"), 262144, 2, 0, 0, ROMTYPE_KICK, 0, 0, NULL, @@ -159,8 +169,8 @@ static struct romdata roms[] = { ALTROMPN(12, 1, 2, 262144, ROMTYPE_ODD , _T("391514-02"), 0x17266a55,0x42fbed34,0x53d1f11c,0xcbde89a9,0x826f2d11,0x75cca5cc) { _T("KS ROM v3.1 (A4000)"), 3, 1, 40, 70, _T("A4000\0"), 524288, 13, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL, 0x2b4566f1, 0x81c631dd,0x096bbb31,0xd2af9029,0x9c76b774,0xdb74076c }, - ALTROM(13, 1, 1, 262144, ROMTYPE_EVEN, 0xf9cbecc9,0x138d8cb4,0x3b8312fe,0x16d69070,0xde607469,0xb3d4078e) - ALTROM(13, 1, 2, 262144, ROMTYPE_ODD , 0xf8248355,0xc2379547,0x9fae3910,0xc185512c,0xa268b82f,0x1ae4fe05) + ALTROM(13, 1, 1, 262144, ROMTYPE_EVEN, 0xf9cbecc9,0x138d8cb4,0x3b8312fe,0x16d69070,0xde607469,0xb3d4078e) + ALTROM(13, 1, 2, 262144, ROMTYPE_ODD , 0xf8248355,0xc2379547,0x9fae3910,0xc185512c,0xa268b82f,0x1ae4fe05) { _T("KS ROM v3.1 (A500,A600,A2000)"), 3, 1, 40, 63, _T("A500\0A600\0A2000\0"), 524288, 14, 0, 0, ROMTYPE_KICK, 0, 0, NULL, 0xfc24ae0d, 0x3B7F1493,0xB27E2128,0x30F989F2,0x6CA76C02,0x049F09CA }, { _T("KS ROM v3.1 (A1200)"), 3, 1, 40, 68, _T("A1200\0"), 524288, 15, 1, 0, ROMTYPE_KICK, 0, 0, NULL, @@ -169,19 +179,19 @@ static struct romdata roms[] = { ALTROMPN(15, 1, 2, 262144, ROMTYPE_ODD , _T("391774-01"), 0x16c07bf8,0x90e331be,0x1970b0e5,0x3f53a9b0,0x390b51b5,0x9b3869c2) { _T("KS ROM v3.1 (A3000)"), 3, 1, 40, 68, _T("A3000\0"), 524288, 61, 2, 0, ROMTYPE_KICK, 0, 0, NULL, 0xefb239cc, 0xF8E210D7,0x2B4C4853,0xE0C9B85D,0x223BA20E,0x3D1B36EE }, - ALTROM(61, 1, 1, 262144, ROMTYPE_EVEN, 0x286b9a0d,0x6763a225,0x8ec493f7,0x408cf663,0x110dae9a,0x17803ad1) - ALTROM(61, 1, 2, 262144, ROMTYPE_ODD , 0x0b8cde6a,0x5f02e97b,0x48ebbba8,0x7d516a56,0xb0400c6f,0xc3434d8d) + ALTROM(61, 1, 1, 262144, ROMTYPE_EVEN, 0x286b9a0d,0x6763a225,0x8ec493f7,0x408cf663,0x110dae9a,0x17803ad1) + ALTROM(61, 1, 2, 262144, ROMTYPE_ODD , 0x0b8cde6a,0x5f02e97b,0x48ebbba8,0x7d516a56,0xb0400c6f,0xc3434d8d) { _T("KS ROM v3.1 (A4000)(Cloanto)"), 3, 1, 40, 68, _T("A4000\0"), 524288, 31, 2 | 4, 1, ROMTYPE_KICK, 0, 0, NULL, 0x43b6dd22, 0xC3C48116,0x0866E60D,0x085E436A,0x24DB3617,0xFF60B5F9 }, { _T("KS ROM v3.1 (A4000)"), 3, 1, 40, 68, _T("A4000\0"), 524288, 16, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL, 0xd6bae334, 0x5FE04842,0xD04A4897,0x20F0F4BB,0x0E469481,0x99406F49 }, - ALTROM(16, 1, 1, 262144, ROMTYPE_EVEN, 0xb2af34f8,0x24e52b5e,0xfc020495,0x17387ab7,0xb1a1475f,0xc540350e) - ALTROM(16, 1, 2, 262144, ROMTYPE_ODD , 0xe65636a3,0x313c7cbd,0xa5779e56,0xf19a41d3,0x4e760f51,0x7626d882) + ALTROM(16, 1, 1, 262144, ROMTYPE_EVEN, 0xb2af34f8,0x24e52b5e,0xfc020495,0x17387ab7,0xb1a1475f,0xc540350e) + ALTROM(16, 1, 2, 262144, ROMTYPE_ODD , 0xe65636a3,0x313c7cbd,0xa5779e56,0xf19a41d3,0x4e760f51,0x7626d882) { _T("KS ROM v3.1 (A4000T)"), 3, 1, 40, 70, _T("A4000T\0"), 524288, 17, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL, 0x75932c3a, 0xB0EC8B84,0xD6768321,0xE01209F1,0x1E6248F2,0xF5281A21 }, ALTROMPN(17, 1, 1, 262144, ROMTYPE_EVEN, _T("391657-01"), 0x0ca94f70,0xb3806eda,0xcb3362fc,0x16a154ce,0x1eeec5bf,0x5bc24789) ALTROMPN(17, 1, 2, 262144, ROMTYPE_ODD , _T("391658-01"), 0xdfe03120,0xcd7a706c,0x431b04d8,0x7814d3a2,0xd8b39710,0x0cf44c0c) - { _T("KS ROM v3.X (A4000)(Cloanto)"), 3, 10, 45, 57, _T("A4000\0"), 524288, 46, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL, + { _T("KS ROM v3.X (A4000)(Cloanto)"), 3, 10, 45, 57, _T("A4000\0"), 524288, 46, 2 | 4, 1, ROMTYPE_KICK, 0, 0, NULL, 0x3ac99edc, 0x3cbfc9e1,0xfe396360,0x157bd161,0xde74fc90,0x1abee7ec }, { _T("CD32 KS ROM v3.1"), 3, 1, 40, 60, _T("CD32\0"), 524288, 18, 1, 0, ROMTYPE_KICKCD32, 0, 0, NULL, @@ -189,16 +199,16 @@ static struct romdata roms[] = { { _T("CD32 extended ROM"), 3, 1, 40, 60, _T("CD32\0"), 524288, 19, 1, 0, ROMTYPE_EXTCD32, 0, 0, NULL, 0x87746be2, 0x5BEF3D62,0x8CE59CC0,0x2A66E6E4,0xAE0DA48F,0x60E78F7F }, - /* plain CD32 rom */ + /* plain CD32 rom */ { _T("CD32 ROM (KS + extended)"), 3, 1, 40, 60, _T("CD32\0"), 2 * 524288, 64, 1, 0, ROMTYPE_KICKCD32 | ROMTYPE_EXTCD32 | ROMTYPE_CD32, 0, 0, NULL, 0xf5d4f3c8, 0x9fa14825,0xc40a2475,0xa2eba5cf,0x325bd483,0xc447e7c1 }, - /* real CD32 rom dump 391640-03 */ + /* real CD32 rom dump 391640-03 */ ALTROMPN(64, 1, 1, 2 * 524288, ROMTYPE_CD32, _T("391640-03"), 0xa4fbc94a, 0x816ce6c5,0x07787585,0x0c7d4345,0x2230a9ba,0x3a2902db ) - - { _T("CD32 MPEG Cartridge ROM"), 3, 1, 40, 30, _T("CD32FMV\0"), 262144, 23, 1, 0, ROMTYPE_CD32CART, 0, 0, NULL, + + { _T("CD32 Full Motion Video Cartridge ROM"), 3, 1, 40, 30, _T("CD32FMV\0"), 262144, 23, 1, 0, ROMTYPE_CD32CART, 0, 0, NULL, 0xc35c37bf, 0x03ca81c7,0xa7b259cf,0x64bc9582,0x863eca0f,0x6529f435 }, - { _T("CD32 MPEG Cartridge ROM"), 3, 1, 40, 22, _T("CD32FMV\0"), 262144, 74, 1, 0, ROMTYPE_CD32CART, 0, 0, _T("391777-01"), - 0xc2002d08, 0xa1ca2d71,0x7efb6c60,0xb9bfabeb,0x0280ae97,0xe82b0cb9 }, + { _T("CD32 Full Motion Video Cartridge ROM"), 3, 1, 40, 22, _T("CD32FMV\0"), 262144, 74, 1, 0, ROMTYPE_CD32CART, 0, 0, _T("391777-01"), + 0xf11158eb, 0x94e469a7,0x6030dcb2,0x99ebc752,0x0aaeef9d,0xb54284cf }, { _T("CDTV extended ROM v1.00"), 1, 0, 1, 0, _T("CDTV\0"), 262144, 20, 0, 0, ROMTYPE_EXTCDTV, 0, 0, NULL, 0x42baa124, 0x7BA40FFA,0x17E500ED,0x9FED041F,0x3424BD81,0xD9C907BE }, @@ -206,16 +216,20 @@ static struct romdata roms[] = { ALTROMPN(20, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, _T("252607-01"), 0xaccbbc2e,0x41b06d16,0x79c6e693,0x3c3378b7,0x626025f7,0x641ebc5c) { _T("CDTV extended ROM v2.07"), 2, 7, 2, 7, _T("CDTV\0"), 262144, 22, 0, 0, ROMTYPE_EXTCDTV, 0, 0, NULL, 0xceae68d2, 0x5BC114BB,0xA29F60A6,0x14A31174,0x5B3E2464,0xBFA06846 }, - ALTROM(22, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x36d73cb8,0x9574e546,0x4b390697,0xf28f9a43,0x4e604e5e,0xf5e5490a) - ALTROM(22, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, 0x6e84dce7,0x01a0679e,0x895a1a0f,0x559c7253,0xf539606b,0xd447b54f) + ALTROM(22, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x36d73cb8,0x9574e546,0x4b390697,0xf28f9a43,0x4e604e5e,0xf5e5490a) + ALTROM(22, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, 0x6e84dce7,0x01a0679e,0x895a1a0f,0x559c7253,0xf539606b,0xd447b54f) { _T("CDTV/A570 extended ROM v2.30"), 2, 30, 2, 30, _T("CDTV\0"), 262144, 21, 0, 0, ROMTYPE_EXTCDTV, 0, 0, _T("391298-01"), 0x30b54232, 0xED7E461D,0x1FFF3CDA,0x321631AE,0x42B80E3C,0xD4FA5EBB }, - ALTROM(21, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x48e4d74f,0x54946054,0x2269e410,0x36018402,0xe1f6b855,0xfd89092b) - ALTROM(21, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, 0x8a54f362,0x03df800f,0x032046fd,0x892f6e7e,0xec08b76d,0x33981e8c) + ALTROM(21, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x48e4d74f,0x54946054,0x2269e410,0x36018402,0xe1f6b855,0xfd89092b) + ALTROM(21, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, 0x8a54f362,0x03df800f,0x032046fd,0x892f6e7e,0xec08b76d,0x33981e8c) + { _T("CDTV-CR extended ROM v3.32"), 3, 32, 3, 32, _T("CDTVCR\0"), 262144, 107, 0, 0, ROMTYPE_EXTCDTV, 0, 0, NULL, + 0x581a85cf, 0xd6b8d3f2,0x854eba9b,0x2d514579,0x9529e8b3,0x3b85e0b4 }, + { _T("CDTV-CR extended ROM v3.44"), 3, 44, 3, 44, _T("CDTVCR\0"), 262144, 108, 0, 0, ROMTYPE_EXTCDTV, 0, 0, NULL, + 0x0b7bd64f, 0x3b160c5a,0xbe79f10a,0xe6924332,0x8004bb9e,0x3162b648 }, { _T("A1000 bootstrap ROM"), 0, 0, 0, 0, _T("A1000\0"), 65536, 24, 0, 0, ROMTYPE_KICK, 0, 0, NULL, 0x0b1ad2d0, 0xBA93B8B8,0x5CA0D83A,0x68225CC3,0x3B95050D,0x72D2FDD7 }, - ALTROM(24, 1, 1, 8192, 0, 0x62f11c04, 0xC87F9FAD,0xA4EE4E69,0xF3CCA0C3,0x6193BE82,0x2B9F5FE6) + ALTROM(24, 1, 1, 8192, 0, 0x62f11c04, 0xC87F9FAD,0xA4EE4E69,0xF3CCA0C3,0x6193BE82,0x2B9F5FE6) ALTROMPN(24, 2, 1, 4096, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("252179-01"), 0x42553bc4,0x8855a97f,0x7a44e3f6,0x2d1c88d9,0x38fee1f4,0xc606af5b) ALTROMPN(24, 2, 2, 4096, ROMTYPE_ODD | ROMTYPE_8BIT, _T("252180-01"), 0x8e5b9a37,0xd10f1564,0xb99f5ffe,0x108fa042,0x362e877f,0x569de2c3) @@ -224,23 +238,23 @@ static struct romdata roms[] = { { _T("Freezer: Action Replay Mk I v1.00"), 1, 0, 1, 0, _T("AR\0"), 65536, 52, 0, 0, ROMTYPE_AR, 0, 1, NULL, 0x2d921771, 0x1EAD9DDA,0x2DAD2914,0x6441F5EF,0x72183750,0x22E01248 }, - ALTROM(52, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x82d6eb87, 0x7c9bac11,0x28666017,0xeee6f019,0x63fb3890,0x7fbea355) - ALTROM(52, 1, 2, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, 0x40ae490c, 0x81d8e432,0x01b73fd9,0x2e204ebd,0x68af8602,0xb62ce397) + ALTROM(52, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x82d6eb87, 0x7c9bac11,0x28666017,0xeee6f019,0x63fb3890,0x7fbea355) + ALTROM(52, 1, 2, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, 0x40ae490c, 0x81d8e432,0x01b73fd9,0x2e204ebd,0x68af8602,0xb62ce397) { _T("Freezer: Action Replay Mk I v1.50"), 1, 50, 1, 50, _T("AR\0"), 65536, 25, 0, 0, ROMTYPE_AR, 0, 1, NULL, - 0xd4ce0675, 0x843B433B,0x2C56640E,0x045D5FDC,0x854DC6B1,0xA4964E7C }, - ALTROM(25, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x7fbd6de2, 0xb5f71a5c,0x09d65ecc,0xa8a3bc93,0x93558461,0xca190228) - ALTROM(25, 1, 2, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, 0x43018069, 0xad8ff242,0xb2cbf125,0x1fc53a73,0x581cf57a,0xb69cee00) - { _T("Freezer: Action Replay Mk II v2.05"), 2, 5, 2, 5, _T("AR\0"), 131072, 26, 0, 0, ROMTYPE_AR, 0, 1, NULL, + 0xf82c4258, 0x843B433B,0x2C56640E,0x045D5FDC,0x854DC6B1,0xA4964E7C }, + ALTROM(25, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x7fbd6de2, 0xb5f71a5c,0x09d65ecc,0xa8a3bc93,0x93558461,0xca190228) + ALTROM(25, 1, 2, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, 0x43018069, 0xad8ff242,0xb2cbf125,0x1fc53a73,0x581cf57a,0xb69cee00) + { _T("Freezer: Action Replay Mk II v2.05"), 2, 5, 2, 5, _T("AR\0"), 131072, 26, 0, 0, ROMTYPE_AR2, 0, 1, NULL, 0x1287301f, 0xF6601DE8,0x888F0050,0x72BF562B,0x9F533BBC,0xAF1B0074 }, - { _T("Freezer: Action Replay Mk II v2.12"), 2, 12, 2, 12, _T("AR\0"), 131072, 27, 0, 0, ROMTYPE_AR, 0, 1, NULL, + { _T("Freezer: Action Replay Mk II v2.12"), 2, 12, 2, 12, _T("AR\0"), 131072, 27, 0, 0, ROMTYPE_AR2, 0, 1, NULL, 0x804d0361, 0x3194A07A,0x0A82D8B5,0xF2B6AEFA,0x3CA581D6,0x8BA8762B }, - { _T("Freezer: Action Replay Mk II v2.14"), 2, 14, 2, 14, _T("AR\0"), 131072, 28, 0, 0, ROMTYPE_AR, 0, 1, NULL, + { _T("Freezer: Action Replay Mk II v2.14"), 2, 14, 2, 14, _T("AR\0"), 131072, 28, 0, 0, ROMTYPE_AR2, 0, 1, NULL, 0x49650e4f, 0x255D6DF6,0x3A4EAB0A,0x838EB1A1,0x6A267B09,0x59DFF634 }, - { _T("Freezer: Action Replay Mk III v3.09"), 3, 9, 3, 9, _T("AR\0"), 262144, 29, 0, 0, ROMTYPE_AR, 0, 1, NULL, + { _T("Freezer: Action Replay Mk III v3.09"), 3, 9, 3, 9, _T("AR\0"), 262144, 29, 0, 0, ROMTYPE_AR2, 0, 1, NULL, 0x0ed9b5aa, 0x0FF3170A,0xBBF0CA64,0xC9DD93D6,0xEC0C7A01,0xB5436824 }, - ALTROM(29, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x2b84519f, 0x7841873b,0xf009d834,0x1dfa2794,0xb3751bac,0xf86adcc8) - ALTROM(29, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, 0x1d35bd56, 0x6464be16,0x26b51949,0x9e76e4e3,0x409e8016,0x515d48b6) - { _T("Freezer: Action Replay Mk III v3.17"), 3, 17, 3, 17, _T("AR\0"), 262144, 30, 0, 0, ROMTYPE_AR, 0, 1, NULL, + ALTROM(29, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x2b84519f, 0x7841873b,0xf009d834,0x1dfa2794,0xb3751bac,0xf86adcc8) + ALTROM(29, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, 0x1d35bd56, 0x6464be16,0x26b51949,0x9e76e4e3,0x409e8016,0x515d48b6) + { _T("Freezer: Action Replay Mk III v3.17"), 3, 17, 3, 17, _T("AR\0"), 262144, 30, 0, 0, ROMTYPE_AR2, 0, 1, NULL, 0xc8a16406, 0x5D4987C2,0xE3FFEA8B,0x1B02E314,0x30EF190F,0x2DB76542 }, { _T("Freezer: Action Replay 1200"), 0, 0, 0, 0, _T("AR\0"), 262144, 47, 0, 0, ROMTYPE_AR, 0, 1, NULL, 0x8d760101, 0x0F6AB834,0x2810094A,0xC0642F62,0xBA42F78B,0xC0B07E6A }, @@ -251,45 +265,269 @@ static struct romdata roms[] = { 0xe668a0be, 0x633A6E65,0xA93580B8,0xDDB0BE9C,0x9A64D4A1,0x7D4B4801 }, { _T("Freezer: X-Power Professional 500 v1.2"), 1, 2, 1, 2, _T("XPOWER\0"), 131072, 65, 0, 0, ROMTYPE_XPOWER, 0, 1, NULL, 0x9e70c231, 0xa2977a1c,0x41a8ca7d,0x4af4a168,0x726da542,0x179d5963 }, - ALTROM(65, 1, 1, 65536, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xf98742e4,0xe8e683ba,0xd8b38d1f,0x79f3ad83,0xa9e67c6f,0xa91dc96c) - ALTROM(65, 1, 2, 65536, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xdfb9984b,0x8d6bdd49,0x469ec8e2,0x0143fbb3,0x72e92500,0x99f07910) + ALTROM(65, 1, 1, 65536, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xf98742e4,0xe8e683ba,0xd8b38d1f,0x79f3ad83,0xa9e67c6f,0xa91dc96c) + ALTROM(65, 1, 2, 65536, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xdfb9984b,0x8d6bdd49,0x469ec8e2,0x0143fbb3,0x72e92500,0x99f07910) { _T("Freezer: X-Power Professional 500 v1.3"), 1, 3, 1, 3, _T("XPOWER\0"), 131072, 68, 0, 0, ROMTYPE_XPOWER, 0, 1, NULL, 0x31e057f0, 0x84650266,0x465d1859,0x7fd71dee,0x00775930,0xb7e450ee }, - ALTROM(68, 1, 1, 65536, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x0b2ce0c7,0x45ad5456,0x89192404,0x956f47ce,0xf66a5274,0x57ace33b) - ALTROM(68, 1, 2, 65536, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x34580c35,0x8ad42566,0x7364f238,0x978f4381,0x08f8d5ec,0x470e72ea) + ALTROM(68, 1, 1, 65536, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x0b2ce0c7,0x45ad5456,0x89192404,0x956f47ce,0xf66a5274,0x57ace33b) + ALTROM(68, 1, 2, 65536, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x34580c35,0x8ad42566,0x7364f238,0x978f4381,0x08f8d5ec,0x470e72ea) { _T("Freezer: Nordic Power v1.5"), 1, 5, 1, 5, _T("NPOWER\0"), 65536, 69, 0, 0, ROMTYPE_NORDIC, 0, 1, NULL, 0x83b4b21c, 0xc56ced25,0x506a5aab,0x3fa13813,0x4fc9e5ae,0x0f9d3709 }, - ALTROM(69, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xdd207174,0xae67652d,0x64f5db20,0x0f4b2110,0xee59567f,0xfbd90a1b) - ALTROM(69, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x8f93d85d,0x73c62d21,0x40c0c092,0x6315b702,0xdd5d0f05,0x3dad7fab) + ALTROM(69, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xdd207174,0xae67652d,0x64f5db20,0x0f4b2110,0xee59567f,0xfbd90a1b) + ALTROM(69, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x8f93d85d,0x73c62d21,0x40c0c092,0x6315b702,0xdd5d0f05,0x3dad7fab) { _T("Freezer: Nordic Power v2.0"), 2, 0, 2, 0, _T("NPOWER\0"), 65536, 67, 0, 0, ROMTYPE_NORDIC, 0, 1, NULL, 0xa4db2906, 0x0aec68f7,0x25470c89,0x6b699ff4,0x6623dec5,0xc777466e }, - ALTROM(67, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xb21be46c,0x50dc607c,0xce976bbd,0x3841eaf0,0x591ddc7e,0xa1939ad2) - ALTROM(67, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x96057aed,0xdd9209e2,0x1d5edfc1,0xcdb52abe,0x93de0f35,0xc43da696) + ALTROM(67, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xb21be46c,0x50dc607c,0xce976bbd,0x3841eaf0,0x591ddc7e,0xa1939ad2) + ALTROM(67, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x96057aed,0xdd9209e2,0x1d5edfc1,0xcdb52abe,0x93de0f35,0xc43da696) { _T("Freezer: Nordic Power v3.0"), 3, 0, 3, 0, _T("NPOWER\0"), 65536, 70, 0, 0, ROMTYPE_NORDIC, 0, 1, NULL, 0x72850aef, 0x59c91d1f,0xa8f118f9,0x0bdba05a,0x9ae788d7,0x7a6cc7c9 }, - ALTROM(70, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xf3330e1f,0x3a597db2,0xb7d11b6c,0xb8e13496,0xc215f223,0x88c4ca3c) + ALTROM(70, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xf3330e1f,0x3a597db2,0xb7d11b6c,0xb8e13496,0xc215f223,0x88c4ca3c) ALTROM(70, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xee58e0f9,0x4148f4cb,0xb42cec33,0x8ca144de,0xd4f54118,0xe0f185dd) - { _T("Freezer: HRTMon v2.33 (built-in)"), 0, 0, 0, 0, _T("HRTMON\0"), 0, 63, 0, 0, ROMTYPE_HRTMON, 0, 1, NULL, + { _T("Freezer: Nordic Power v3.2"), 3, 2, 3, 2, _T("NPOWER\0"), 65536, 115, 0, 0, ROMTYPE_NORDIC, 0, 1, NULL, + 0x46158b6e, 0xd8c3f5af,0x5f109c61,0x5f6acb38,0x68fe6c06,0x580041b5 }, + ALTROM(115, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x4bfc71de,0x51914de0,0xdc0f055a,0x29ca188d,0xa7f61914,0xfdecbd07) + ALTROM(115, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x923ec443,0x9f1e5334,0xaa620745,0xf4d0c50e,0x8736543b,0x6d4366c5) + { _T("Freezer: Pro Access v2.17"), 2, 17, 2, 17, _T("PROACCESS\0"), 65536, 116, 0, 0, ROMTYPE_AR, 0, 1, NULL, + 0xc4c265cd, 0x6a5c0d99,0x69a624dc,0x1b437aec,0x5dbcd4c7,0x2ce9064a }, + ALTROM(116, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x1909f7e9, 0x5abe9b9d,0xaae328c8,0x134e2b62,0x7b33b698,0xe342afc2) + ALTROM(116, 1, 2, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, 0xa3927c72, 0x7adc9352,0x2d112ae9,0x23b9a70d,0x951b1e7a,0xba800ea6) + + { _T("Freezer: HRTMon v2.36 (built-in)"), 0, 0, 0, 0, _T("HRTMON\0"), 0, 63, 0, 0, ROMTYPE_HRTMON, 0, 1, NULL, 0xffffffff, 0, 0, 0, 0, 0, _T("HRTMon") }, - { _T("A590/A2091 ROM 6.0"), 6, 0, 6, 0, _T("A590\0A2091\0"), 16384, 53, 0, 0, ROMTYPE_A2091BOOT, 0, 0, NULL, + { _T("A2090a"), 0, 0, 0, 0, _T("A2090A\0"), 16384, 122, 0, 0, ROMTYPE_A2090, 0, 0, NULL, + 0x73fe45a7, 0x77ce9091,0x4be5a3bf,0x6f26b343,0x062b5bd8,0xc63c3754 }, + ALTROMPN(122, 1, 1, 8192, ROMTYPE_ODD | ROMTYPE_8BIT, _T("315097-01"), 0x150b116c,0x8011d873,0x3be53db0,0x79dfe319,0x7ffb8634,0x1baa6dbd) + ALTROMPN(122, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("315098-01"), 0xbe422e3b,0x64ad1646,0x030db10f,0x54f13f64,0x7d449e4d,0x17f9ab5c) + { _T("A590/A2091 6.0"), 6, 0, 6, 0, _T("A590\0A2091\0"), 16384, 53, 0, 0, ROMTYPE_A2091, 0, 0, NULL, 0x8396cf4e, 0x5E03BC61,0x8C862ABE,0x7BF79723,0xB4EEF4D2,0x1859A0F2 }, ALTROMPN(53, 1, 1, 8192, ROMTYPE_ODD | ROMTYPE_8BIT, _T("390389-03"), 0xb0b8cf24,0xfcf40175,0x05f4d441,0x814b45d5,0x59c19eab,0x43816b30) ALTROMPN(53, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390388-03"), 0x2e77bbff,0x8a098845,0x068f32cf,0xa4d34a27,0x8cd290f6,0x1d35a52c) - { _T("A590/A2091 ROM 6.6"), 6, 6, 6, 6, _T("A590\0A2091\0"), 16384, 54, 0, 0, ROMTYPE_A2091BOOT, 0, 0, NULL, + { _T("A590/A2091 6.6"), 6, 6, 6, 6, _T("A590\0A2091\0"), 16384, 54, 0, 0, ROMTYPE_A2091, 0, 0, NULL, 0x33e00a7a, 0x739BB828,0xE874F064,0x9360F59D,0x26B5ED3F,0xBC99BB66 }, ALTROMPN(54, 1, 1, 8192, ROMTYPE_ODD | ROMTYPE_8BIT, _T("390722-02"), 0xe536bbb2,0xfd7f8a6d,0xa18c1b02,0xd07eb990,0xc2467a24,0x183ede12) ALTROMPN(54, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390721-02"), 0xc0871d25,0xe155f18a,0xbb90cf82,0x0589c15e,0x70559d3b,0x6b391af8) - { _T("A590/A2091 ROM 7.0"), 7, 0, 7, 0, _T("A590\0A2091\0"), 16384, 55, 0, 0, ROMTYPE_A2091BOOT, 0, 0, NULL, + { _T("A590/A2091 7.0"), 7, 0, 7, 0, _T("A590\0A2091\0"), 16384, 55, 0, 0, ROMTYPE_A2091, 0, 0, NULL, 0x714a97a2, 0xE50F01BA,0xF2899892,0x85547863,0x72A82C33,0x3C91276E }, ALTROMPN(55, 1, 1, 8192, ROMTYPE_ODD | ROMTYPE_8BIT, _T("390722-03"), 0xa9ccffed,0x149f5bd5,0x2e2d2990,0x4e3de483,0xb9ad7724,0x48e9278e) ALTROMPN(55, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390721-03"), 0x2942747a,0xdbd7648e,0x79c75333,0x7ff3e4f4,0x91de224b,0xf05e6bb6) - { _T("A590/A2091 Guru ROM 6.14"), 6, 14, 6, 14, _T("A590\0A2091\0"), 32768, 56, 0, 0, ROMTYPE_A2091BOOT, 0, 0, NULL, + { _T("A590/A2091 Guru ROM 6.14"), 6, 14, 6, 14, _T("A590\0A2091\0"), 32768, 56, 0, 0, ROMTYPE_A2091, 0, 0, NULL, 0x04e52f93, 0x6DA21B6F,0x5E8F8837,0xD64507CD,0x8A4D5CDC,0xAC4F426B }, - { _T("A4091 ROM 40.9"), 40, 9, 40, 9, _T("A4091\0"), 32768, 57, 0, 0, ROMTYPE_A4091BOOT, 0, 0, NULL, + { _T("A4091 40.9"), 40, 9, 40, 9, _T("A4091\0"), 32768, 57, 0, 0, ROMTYPE_A4091, 0, 0, NULL, 0x00000000, 0, 0, 0, 0, 0 }, - { _T("A4091 ROM 40.13"), 40, 13, 40, 13, _T("A4091\0"), 32768, 58, 0, 0, ROMTYPE_A4091BOOT, 0, 0, _T("391592-02"), + { _T("A4091 40.13"), 40, 13, 40, 13, _T("A4091\0"), 32768, 58, 0, 0, ROMTYPE_A4091, 0, 0, _T("391592-02"), 0x54cb9e85, 0x3CE66919,0xF6FD6797,0x4923A12D,0x91B730F1,0xFFB4A7BA }, + { _T("SupraDrive AMAB6"), 3, 8, 3, 8, _T("SUPRA\0"), 16384, 121, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB6"), + 0xf40bd349, 0x82168556,0x07525067,0xe9263431,0x1fb9c347,0xe737f247 }, + { _T("SupraDrive AMAB5"), 3, 0, 3, 0, _T("SUPRA\0"), 16384, 134, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB5"), + 0x75e1b343, 0xf15de74b,0x4e2a9c99,0xa6dc4f6c,0x33f64c76,0x8c043d1c }, + { _T("SupraDrive AMAB4"), 0, 0, 0, 0, _T("SUPRA\0"), 8192, 135, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB4"), + 0xde7f3f1c, 0xc0acbfc8,0x6641a6c1,0x024870cc,0x519f8c4c,0xbdfe8c64 }, + { _T("SupraDrive AMAB3"), 0, 0, 0, 0, _T("SUPRA\0"), 8192, 136, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB3"), + 0x3ead39aa, 0x02fe79ee,0xef423098,0xec6add8c,0xb92f849f,0xc64bcd41 }, + + { _T("Blizzard 1230-II"), 0, 0, 0, 0, _T("B1230MKII\0"), 32768, 163, 0, 0, ROMTYPE_CB_B1230MK2, 0, 0, NULL, + 0xf307cd34, 0xd2f0bfe5, 0x6e84e9f2, 0x2dc11583, 0x30702fd7, 0xd59584ee }, + { _T("Blizzard 1230-III"), 0, 0, 0, 0, _T("B1230MKIII\0"), 32768, 162, 0, 0, ROMTYPE_CB_B1230MK3, 0, 0, NULL, + 0x8412a22c, 0x3a4c55f3, 0xdaf62084, 0xd947e418, 0x137db019, 0xf13efc7d }, + { _T("Blizzard 1230-IV"), 0, 0, 0, 0, _T("B1230MKIV\0"), 32768, 89, 0, 0, ROMTYPE_CB_BLIZ1230, 0, 0, NULL, + 0x3078dbdc, 0x4d3e7fd0, 0xa1a4c3ae, 0xe17c5de3, 0xcbe1af03, 0x447aff92 }, + { _T("Blizzard 1240/1260"), 0, 0, 0, 0, _T("B1240\0B1260\0"), 32768, 90, 0, 0, ROMTYPE_CB_BLIZ1260, 0, 0, NULL, + 0xf88ae0f1, 0xf69aca4b,0xb13e3389,0x04676f0c,0x8616f8db,0x074c313d }, + + { _T("Blizzard 2060 v8.2"), 8, 2, 8, 2, _T("B2060\0"), 65536, 168, 0, 0, ROMTYPE_CB_BLIZ2060, 0, 0, NULL, + 0x2f42af81, 0x003577b8, 0x4e1f2e59, 0x3add6c9f, 0xfd65a7b4, 0x2abaa933 }, + ALTROMPN(168, 1, 1, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xb5892212, 0x7282a8ca, 0xf7ab194d, 0x16e1d05a, 0x582f0ebf, 0x1046b3d0) + ALTROMPN(168, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x821a01c0, 0x6fd29f69, 0x28c5980e, 0x313b3b15, 0xb5d683ac, 0x209dd1bf) + { _T("Blizzard 2060 v8.5"), 8, 5, 8, 5, _T("B2060\0"), 65536, 92, 0, 0, ROMTYPE_CB_BLIZ2060, 0, 0, NULL, + 0xce270bc0, 0xe043c1aa, 0x3bb06e06, 0xd4dabff3, 0x0a8c6317, 0xabfef2bb }, + ALTROMPN(92, 1, 1, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xa6023f20, 0xdfb048d6, 0xbdc03587, 0x241e8121, 0x26aba603, 0xd69b0238) + ALTROMPN(92, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x9635a9cd, 0x47578b27, 0xc4ba6e54, 0x891930dd, 0xcb4b6a45, 0x5d6b31b2) + + { _T("Blizzard SCSI Kit III"), 1, 139, 1, 139, _T("BSCSIIII\0"), 65536, 167, 0, 0, ROMTYPE_BLIZKIT3, 0, 0, NULL, + 0xfd2c772f, 0x1411c248, 0x72f7cb8d, 0xecbe4744, 0xf0b8d12a, 0x1aaaad44, NULL, _T("blizzard_scsi_kit_iv.rom") }, + { _T("Blizzard SCSI Kit IV"), 8, 5, 8, 5, _T("BSCSIIV\0"), 32768, 94, 0, 0, ROMTYPE_BLIZKIT4, 0, 0, NULL, + 0xf53a0fca, 0xefe17ca5,0x88c44a7f,0x0f8c62be,0x20f23278,0xcfe06727, NULL, _T("blizzard_scsi_kit_iv.rom") }, + { _T("Fastlane"), 8, 5, 8, 5, _T("FASTLANE\0"), 20788, 102, 0, 0, ROMTYPE_FASTLANE, 0, 0, NULL, + 0xe4f485a5, 0x20bf7de5,0x05e45d0a,0xc411cfd2,0x806d0fd8,0xe46276de, NULL, _T("fastlanez3.rom") }, + { _T("Oktagon 2008"), 6, 12, 6, 12, _T("OKTAGON\0"), 32768, 103, 0, 0, ROMTYPE_OKTAGON, 0, 0, NULL, + 0xbb0d2f6a, 0x56c441fa,0x37d19339,0x3081b2e8,0xceae823b,0xc7e97e49, NULL, _T("oktagon2008.rom") }, + { _T("Warp Engine A4000"), 0, 0, 0, 0, _T("WARPENGINE\0WARPENGINEA4000\0"), 32768, 93, 0, 0, ROMTYPE_CB_WENGINE, 0, 0, NULL, + 0x4deb574a, 0x6e6c95ff,0xe8448391,0xd36c5b68,0xc9065cb0,0x702a7d27 }, + { _T("TekMagic 2040/2060"), 1, 0, 1, 0, _T("TEKMAGIC\0TEKMAGIC2040\0TEKMAGIC2060\0"), 65536, 104, 0, 0, ROMTYPE_CB_TEKMAGIC, 0, 0, NULL, + 0x9e9781d5, 0xf65b60d1,0x4300c50f,0x2ed17cf4,0x4dcfdef9,0x16697bc9, NULL, _T("tekmagic2060.rom") }, + ALTROMPN(104, 1, 1, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x888da4cf, 0x6ae85f3a, 0x65331ba4, 0xaaba67ae, 0x34763d70, 0x2bde0495) + ALTROMPN(104, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xaf1f47db, 0x28d5bed0, 0xbc517d46, 0x500e8159, 0x723e0b64, 0x4733c26a) + + { _T("A2620/A2630 -07"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 105, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-07/390283-07"), + 0x169d80e9, 0x41f518cb,0x41c1dc1f,0xcc636383,0x20676af5,0x4969010c, NULL, NULL }, + ALTROMPN(105, 1, 1, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, _T("390282-07"), 0xf2904058, 0x33695119, 0x5fdf5d56, 0x095a696b, 0x0ba2641d, 0x334845df) + ALTROMPN(105, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-07"), 0xf697d458, 0x09fe260b, 0x03784e87, 0x3351dbec, 0x5146a455, 0x814383d1) + { _T("A2620/A2630 -06"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 106, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-06/390283-06"), + 0xeb31fd9e, 0x2d6a5c68,0x1040f98d,0x7e63ad08,0x90da9e83,0x2b5c704d, NULL, NULL }, + ALTROMPN(106, 1, 1, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, _T("390282-06"), 0xd6ae582c, 0x47b3dea3, 0x31db76e6, 0x1380a3d6, 0x9f191657, 0xdd1cd4b3) + ALTROMPN(106, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-06"), 0xcd379634, 0x65e251e2, 0xf6961c8e, 0x33a86c3d, 0x01248f70, 0xa159823b) + { _T("A2620/A2630 -04"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 165, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-04/390283-04"), + 0xd4666ae9, 0x93cbd775, 0x42843f6d, 0x8234c271, 0xab860304, 0x06a1ae0a, NULL, NULL }, + ALTROMPN(165, 1, 1, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, _T("390282-04"), 0x28d5af1e, 0xc6a51a63, 0xca2a0833, 0xf32c4a59, 0x7d9d5b95, 0xcfa79a9e) + ALTROMPN(165, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-04"), 0x325aaf5f, 0xe76b384b, 0x5740cc0e, 0x782ae887, 0xe921352b, 0x115b2489) + { _T("A2620/A2630 -01"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 164, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-01/390283-01"), + 0x6ee2ecdd, 0x4c82e3ba, 0x2d2dd1d3, 0x82f01098, 0xc26681b8, 0xff62f36d, NULL, NULL }, + ALTROMPN(164, 1, 1, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, _T("390282-01"), 0xdf76493b, 0x331ede0a, 0x8ca995cc, 0x1917f592, 0x18718e5b, 0x3c7fac39) + ALTROMPN(164, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-01"), 0xd74187de, 0x681e4985, 0x4da64bf1, 0x6f2f99f7, 0x4b195f54, 0x0b8bd614) + + { _T("DKB 12x0"), 1, 23, 1, 23, _T("DKB\0"), 32768, 112, 0, 0, ROMTYPE_CB_DKB12x0, 0, 0, NULL, + 0xf3b2b0b3, 0x1d539593,0xb1d7514e,0xeb214ab3,0x433a97fc,0x8a010366, NULL, NULL }, + { _T("Fusion Forty"), 0, 0, 0, 0, _T("FUSIONFORTY\0"), 131072, 113, 0, 0, ROMTYPE_CB_FUSION, 0, 0, NULL, + 0x48fcb5fd, 0x15674dac,0x90b6d8db,0xdda3a175,0x997184c2,0xa423d733, NULL, NULL }, + ALTROMPN(113, 1, 1, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, _T("U28"), 0x434a21a8, 0x472c1623, 0x02babd00, 0x7c1a77ff, 0x40dd12ab, 0x39c97f82) + ALTROMPN(113, 1, 2, 32768, ROMTYPE_QUAD | ROMTYPE_ODD | ROMTYPE_8BIT, _T("U27"), 0x38373cf6, 0xfe8aa931, 0xada6b6f3, 0x6b48ca3c, 0x9b86677d, 0xbee4da59) + ALTROMPN(113, 1, 3, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, _T("U25"), 0xc9e990d3, 0xb251ef73, 0x1374e796, 0xa87cbc7e, 0x9263320a, 0x28a71d2b) + ALTROMPN(113, 1, 4, 32768, ROMTYPE_QUAD | ROMTYPE_ODD | ROMTYPE_8BIT, _T("U26"), 0x2e117fe0, 0xbb2de2da, 0x6db4e92c, 0x636fefe6, 0x13a32699, 0xcea31011) + { _T("Apollo 1240/1260"), 5, 60, 5, 60, _T("APOLLO12XX\0"), 131072, 119, 0, 0, ROMTYPE_CB_APOLLO, 0, 0, NULL, + 0xcd009ad9, 0x1c3b4851,0xc5a221e3,0xa7ca24fc,0xc1df4a5b,0x9f2343ad }, + { _T("GVP A3001 Series I"), 3, 3, 3, 3, _T("A3001SI\0"), 8192, 114, 0, 0, ROMTYPE_CB_A3001S1, 0, 0, NULL, + 0xaaff7c65, 0x424cf3da,0xcc9da794,0x0ba74446,0x69dd1691,0x44ae87ee, NULL, NULL }, + { _T("Kupke Golem 030"), 0, 0, 0, 0, _T("GOLEM030\0"), 8192, 126, 0, 0, ROMTYPE_CB_GOLEM030, 0, 0, NULL, + 0x05d473f4, 0x574ec567, 0xcc67e06f, 0x91dcecb9, 0x8c204399, 0x5fe2a09f, NULL, NULL }, + { _T("DKB WildFire"), 1, 1, 1, 1, _T("WILDFIRE\0"), 18352, 143, 0, 0, ROMTYPE_CB_DBK_WF, 0, 0, NULL, + 0xb2dae8c4, 0xcdfe2d96, 0xe44d4f8d, 0x3833a5e8, 0xb6c832fd, 0xc7b341a9, NULL, NULL }, + { _T("M-Tec E-Matrix 530"), 0, 0, 0, 0, _T("EMATRIX530\0"), 65536, 144, 0, 0, ROMTYPE_CB_EMATRIX, 0, 0, NULL, + 0x3942d827, 0x5aaf118f, 0x61fc3083, 0x1435b87c, 0x8bdab6a4, 0x59b4ee22, NULL, NULL }, + { _T("SX32 Pro"), 0, 0, 0, 0, _T("SX32PRO\0"), 65536, 160, 0, 0, ROMTYPE_CB_SX32PRO, 0, 0, NULL, + 0xbfd68a88, 0x84a50880, 0x76917549, 0xadf33b16, 0x8a869adb, 0x9e5a6fac, NULL, NULL }, + { _T("IVS Vector 4.14"), 4, 14, 4, 14, _T("VECTOR030\0"), 65536, 166, 0, 0, ROMTYPE_CB_VECTOR, 0, 0, NULL, + 0x3befa0c0, 0x4414673c, 0xa52f78a0, 0xae656824, 0xfd08b54f, 0xa1de237c, NULL, NULL }, + ALTROMPN(166, 1, 1, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xb64e3bbf, 0xd6f4fc81, 0x38325a78, 0x74ff1c15, 0x7c93f1a2, 0x444904ae) + ALTROMPN(166, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x541b5988, 0x3546517b, 0x57cecd2f, 0x9fbfcd0c, 0xf26fdbbf, 0xfb009e3e) + + { _T("Preferred Technologies Nexus"), 1, 0, 1, 0, _T("PTNEXUS\0"), 8192, 139, 0, 0, ROMTYPE_PTNEXUS, 0, 0, NULL, + 0xf495879a, 0xa3bd0202, 0xe14aa5b6, 0x49d3ce88, 0x22975950, 0x6500dbc2, NULL, NULL }, + { _T("ICD AdSCSI 2000"), 1, 6, 1, 6, _T("ADSCSI\0"), 32768, 133, 0, 0, ROMTYPE_ADSCSI, 0, 0, NULL, + 0x7dba3e1f, 0x1e05f284, 0xd59a1e5d, 0x4e4de44e, 0x6f075175, 0x625cd6c0, NULL, NULL }, + { _T("Archos ADD-500"), 1, 21, 1, 21, _T("ADD\0"), 16384, 132, 0, 0, ROMTYPE_ADD500, 0, 0, NULL, + 0x3f4e4a74, 0x9ed96fc0,0xd6381dc3,0x3192b0af,0xdfae4b74,0x576c3a69, NULL, NULL }, + { _T("Protar A500HD"), 1, 193, 1, 193, _T("PROTAR\0"), 32768, 131, 0, 0, ROMTYPE_PROTAR, 0, 0, NULL, + 0x10c1b22c, 0x2b800cde,0x79fd559e,0xebd5e432,0xd711af3d,0x0b8ea7e9, NULL, NULL }, + { _T("M-Tec AT500"), 1, 33, 1, 33, _T("MTECAT\0"), 32768, 130, 0, 0, ROMTYPE_MTEC, 0, 0, NULL, + 0x38b6b6b0, 0x8bb1093a,0xd592e7df,0x99c48f83,0xb9f842b2,0xb1a6e618, NULL, NULL }, + { _T("AdIDE 40/44 v33"), 33, 0, 33, 0, _T("ADIDE\0"), 16384, 141, 0, 0, ROMTYPE_ADIDE, 0, 0, NULL, + 0x330254ce, 0xc91dd3b5,0x3f1986bd,0x94fba150,0xe753c2da,0x4dee78e7, NULL, NULL }, + { _T("AdIDE 40/44 v34"), 34, 0, 34, 0, _T("ADIDE\0"), 16384, 129, 0, 0, ROMTYPE_ADIDE, 0, 0, NULL, + 0xedf84cbe, 0xabdbc01d,0xaa0b3aae,0xe4401ad7,0xe65525a9,0x6bfa2b27, NULL, NULL }, + { _T("Vector Falcon 8000 v7.1"), 7, 1, 7, 1, _T("VECTOR\0"), 32768, 128, 0, 0, ROMTYPE_VECTOR, 0, 0, NULL, + 0xa8120c55, 0x248935ab, 0xf4d74036, 0xefdafdbb, 0x7817e232, 0xfc13e0fa, NULL, NULL }, + ALTROMPN(128, 1, 1, 16384, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x798b1152, 0x603ba087,0xecee69ac,0x7ccf6e88,0x3e374fc8,0x808bcbb4) + ALTROMPN(128, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xd8b2f469, 0xbc600f99,0xa0ff7384,0xdabc7a04,0xb7bb0e71,0xad615db5) + { _T("Vector Falcon 8000 v7.6"), 7, 6, 7, 6, _T("VECTOR\0"), 32768, 172, 0, 0, ROMTYPE_VECTOR, 0, 0, NULL, + 0x2177a145, 0x8a7e617f,0xed566bb8,0xb33f6409, 0x05d9b946, 0xcee6d4bf, NULL, NULL }, + ALTROMPN(172, 1, 1, 16384, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x6228a3e4,0x72fa4175,0x21731e91,0x6c6c8519,0x91110287,0x9f4c0cb9) + ALTROMPN(172, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xf0a0ab0d,0xd239405a,0x5c4983ce,0xeaff0fd2,0x36d42d82,0x5a0cafd1) + { _T("Kommos A500/A2000 v1.8"), 1, 8, 1, 8, _T("KOMMOS\0"), 32768, 127, 0, 0, ROMTYPE_KOMMOS, 0, 0, NULL, + 0xc1a5c848, 0x291310f1, 0x25455f2d, 0x8e114bcd, 0xe104ca4c, 0x9db51747, NULL, NULL }, + ALTROMPN(127, 1, 1, 16384, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x1b86d2ed, 0x969995a1, 0x2ebf8c15, 0xab87e8d0, 0xddc837a1, 0xb90fbfa8) + ALTROMPN(127, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x65b4c3a0, 0x60e904d4, 0xe45bb6ba, 0x3e253ffa, 0xda4ee2e5, 0xc8548da1) + { _T("Kommos A500/A2000 v1.7"), 1, 7, 1, 7, _T("KOMMOS\0"), 32768, 140, 0, 0, ROMTYPE_KOMMOS, 0, 0, NULL, + 0x025d7835, 0x8205ad6e, 0x08dbf5a6, 0x9ba17956, 0xb5237ffe, 0x768de5a4, NULL, NULL }, + ALTROMPN(140, 1, 1, 16384, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x3d982391, 0xbe26e141, 0x1e16cab4, 0xeab8af33, 0x1476ef8e, 0x21fcb2af) + ALTROMPN(140, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x68adc0ad, 0xb5eef088, 0xed8a9439, 0xb0302907, 0xcb3cb207, 0x62f28da7) + { _T("Kupke Golem v3.9"), 3, 9, 3, 9, _T("GOLEM\0"), 16384, 124, 0, 0, ROMTYPE_GOLEM, 0, 0, NULL, + 0x49157dd0, 0x03b615c9,0x2befa474,0xa37303ca,0xdc3e830d,0x3c0d9a9f, NULL, NULL }, + ALTROMPN(124, 1, 1, 8192, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x88cf2ec5, 0x59680f8d, 0xae520893, 0xff9ada35, 0xac9a1146, 0x4f87453c) + ALTROMPN(124, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x713298ad, 0x2ad7d6f3, 0xd696fd2c, 0x51a256ee, 0xea185c47, 0x52906e04) + { _T("GVP Series I v1.0"), 1, 0, 1, 16, _T("GVPI\0"), 16384, 123, 0, 0, ROMTYPE_GVPS1, 0, 0, NULL, + 0x1a4c20aa, 0xb9a3377e,0x2d9b5163,0x28693c63,0x19ffb65b,0x40ae3618, NULL, NULL }, + ALTROMPN(123, 1, 1, 8192, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x27f15785, 0x1a71a78d, 0xdd4e9559, 0x0f133bba, 0x4a71122f, 0x44caef78) + ALTROMPN(123, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xa723193e, 0x05b4a072, 0x785c7824, 0x54e003c3, 0x6d88bd9b, 0xf5f561b9) + { _T("GVP Series I/II v3.15"), 3, 15, 3, 15, _T("GVPII\0GVPI\0"), 16384, 111, 0, 0, ROMTYPE_GVPS12, 0, 0, NULL, + 0xf99c6f11, 0x77098a9e,0x35acaef2,0x11a546f0,0xc564cdac,0xf52836c4, NULL, NULL }, + { _T("GVP Series II v4.15"), 4, 15, 4, 15, _T("GVPII\0"), 16384, 109, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL, + 0xf89f44d6, 0xbf10c12c,0xc72dd040,0x549ea17c,0x24947633,0xe3773297, NULL, NULL }, + { _T("GVP Series II Guru ROM"), 6, 14, 6, 14, _T("GVPII\0"), 32768, 110, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL, + 0x756103b1, 0x7f1335ea,0xf5b7ce73,0xc5231173,0x261da5aa,0xe7249645, NULL, NULL }, + { _T("AlfaPower v6.10"), 6, 10, 6, 10, _T("ALFAPOWER\0"), 32768, 117, 0, 0, ROMTYPE_ALFA, 0, 0, NULL, + 0x1cfb0a0b, 0xc7275eda,0x547d6664,0x5c4eb7a0,0x3b5cef37,0xa498365a, NULL, NULL }, + { _T("AlfaPower v8.3"), 8, 3, 8, 3, _T("ALFAPOWERPLUS\0"), 32768, 118, 0, 0, ROMTYPE_ALFAPLUS, 0, 0, NULL, + 0xe8201bad, 0xdefea015,0x596fce32,0x11e84397,0x23046a31,0x5a7726dc, NULL, NULL }, + { _T("Masoboshi MC-702"), 2, 201, 2, 201, _T("MASOBOSHI\0"), 32768, 120, 0, 0, ROMTYPE_MASOBOSHI, 0, 0, NULL, + 0xcd99b98a, 0x3897e46a,0x66d5833f,0x849b8e81,0x30acb3cb,0x319a2fa0, NULL, NULL }, + { _T("Roctec RocHard RH800C v1"), 1, 0, 1, 0, _T("ROCHARD\0"), 16384, 138, 0, 0, ROMTYPE_ROCHARD, 0, 0, NULL, + 0x0e980aec, 0xbcafa14d,0xe80576cb,0xe3e0c638,0x1ca90379,0xe078a8bd, NULL, NULL }, + ALTROMPN(138, 1, 1, 8192, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xde3a855b, 0xda2fe069, 0xd78c9ccc, 0xc221711f, 0x1e598298, 0x2bdabffd) + ALTROMPN(138, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xb0ed3006, 0x0a88d84e, 0x2094f9e5, 0x18d37f90, 0x34764f22, 0x9696c3d9) + { _T("Roctec RocHard RH800C v2"), 2, 0, 2, 0, _T("ROCHARD\0"), 16384, 146, 0, 0, ROMTYPE_ROCHARD, 0, 0, NULL, + 0x5c27be3f, 0xacdb8bc7,0x64493f65,0x9da4c1e8,0x3005ceeb,0xced73dbc, NULL, NULL }, + ALTROMPN(146, 1, 1, 8192, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xc5b8f068, 0x6ada1205, 0x44d284d0, 0x326d68cb, 0x7a2d9fb4, 0x77f35852) + ALTROMPN(146, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xc88843cb, 0x3d7eb1b6, 0x8139b81b, 0x0665684c, 0x536ab3d0, 0x52a5dd9d) + { _T("Apollo 500/2000"), 0, 0, 0, 0, _T("APOLLOHD\0"), 16384, 145, 0, 0, ROMTYPE_APOLLOHD, 0, 0, NULL, + 0x931bad25, 0x24b4ee4c,0x129c7a93,0xf83ad570,0x66afd80c,0x4179f39c, NULL, NULL }, + { _T("Multi Evolution 500/2000"), 3, 0, 3, 0, _T("MULTIEVOLUTION\0"), 65536, 156, 0, 0, ROMTYPE_MEVOLUTION, 0, 0, NULL, + 0xd13a2c89, 0xf9e38c4b,0xf5c6499d,0x486946ba,0x7b7636b8,0x0845265b, NULL, NULL }, + ALTROMPN(156, 1, 1, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x339b3549, 0x74de857b, 0x42f9a8e0, 0xc1f3c29e, 0x06982622, 0x853d08fe) + ALTROMPN(156, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x3aca5d1f, 0x786f2197, 0xc614be91, 0xae7e87da, 0xb42c3290, 0xd7997763) + { _T("Kupke Golem v4.2"), 4, 2, 4, 2, _T("GOLEMFAST\0"), 16384, 157, 0, 0, ROMTYPE_GOLEMFAST, 0, 0, NULL, + 0x5e94ee56, 0xf83dae55, 0x49f9b735, 0x52d5c6e0, 0x41da4c6c, 0x995a7f47, NULL, NULL }, + ALTROMPN(157, 1, 1, 8192, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xec13fda0, 0x6af1447c, 0x4363c46d, 0x05697458, 0x01daa30c, 0x03c01c9f) + ALTROMPN(157, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x39b0075e, 0xf6644ea0, 0x6c3ed349, 0xfb0fb6b4, 0xa9f07655, 0x0b104179) + { _T("Phoenix Board SCSI v.J"), 3, 1, 3, 1, _T("PBSCSI\0"), 32768, 159, 0, 0, ROMTYPE_PHOENIXB, 0, 0, NULL, + 0x1f672e4b, 0xb20d50b8, 0x31ec9823, 0xfa732fc6, 0x522ecc6a, 0xae36ec33, NULL, NULL }, + { _T("IVS GramdSlam/Trumpcard Pro v4.9"), 4, 9, 4, 9, _T("IVSPRO\0"), 16384, 161, 0, 0, ROMTYPE_IVSTPRO, 0, 0, NULL, + 0x4a15f224, 0x29500b47, 0x289e84ac, 0x575e3c7d, 0x82199b45, 0x605d8fc9, NULL, NULL }, + { _T("Expansion Systems Dataflyer+ v1.5"), 1, 5, 1, 5, _T("DATAFLYERPLUS\0"), 32768, 170, 0, 0, ROMTYPE_DATAFLYER, 0, 0, NULL, + 0x00888f19, 0x54b73354, 0xb3592691, 0x59a80909, 0x0bdb67df, 0x8ac22aa9, NULL, NULL }, + { _T("Expansion Systems Dataflyer+ v1.7"), 1, 7, 1, 7, _T("DATAFLYERPLUS\0"), 32768, 171, 0, 0, ROMTYPE_DATAFLYER, 0, 0, NULL, + 0xb0814aca, 0xb817672c, 0x1beb86c6, 0x840aa4bd, 0xf4640835, 0x1ed103f4, NULL, NULL }, + { _T("Expansion Systems Dataflyer+ v2.1"), 2, 1, 2, 1, _T("DATAFLYERPLUS\0"), 32768, 169, 0, 0, ROMTYPE_DATAFLYER, 0, 0, NULL, + 0xc49daa65, 0x20275716, 0xdc7eb00e, 0x5dc53680, 0xb5c8a90a, 0x7c00e390, NULL, NULL }, + { _T("Microbotics HardFrame v1.5"), 1, 5, 1, 5, _T("HARDFRAME\0"), 32768, 173, 0, 0, ROMTYPE_HARDFRAME, 0, 0, NULL, + 0x8d144212, 0xc5a4f497, 0x5216c1b1, 0xe08760d0, 0x0bd579ef, 0xea226354, NULL, NULL }, + { _T("Mainhattan Data A-Team v1.8"), 1, 8, 1, 8, _T("ATEAM\0"), 65536, 174, 0, 0, ROMTYPE_ATEAM, 0, 0, NULL, + 0x4fe08a5d, 0x007e5c61, 0x4048f598, 0x6d14011d, 0x23a41435, 0x5e0a2259, NULL, NULL }, + + { _T("CyberStorm MK I 68040"), 0, 0, 0, 0, _T("CSMKI\0"), 32768, 95, 0, 0, ROMTYPE_CB_CSMK1, 0, 0, NULL, + 0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk1_040.rom") }, + { _T("CyberStorm MK I 68060"), 0, 0, 0, 0, _T("CSMKI\0"), 65536, 101, 0, 0, ROMTYPE_CB_CSMK1, 0, 0, NULL, + 0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk1_060.rom") }, + { _T("CyberStorm MK II"), 0, 0, 0, 0, _T("CSMKII\0"), 131072, 96, 0, 0, ROMTYPE_CB_CSMK2, 0, 0, NULL, + 0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk2.rom") }, + { _T("CyberStorm MK III"), 0, 0, 0, 0, _T("CSMKIII\0"), 131072, 97, 0, 0, ROMTYPE_CB_CSMK3, 0, 0, NULL, + 0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk3.rom") }, + { _T("CyberStorm PPC"), 0, 0, 0, 0, _T("CSPPC\0"), 131072, 98, 0, 0, ROMTYPE_CB_CSPPC, 0, 0, NULL, + 0, 0, 0, 0, 0, 0, NULL, _T("cyberstormppc.rom") }, + { _T("Blizzard PPC 68040"), 0, 0, 0, 0, _T("BPPC\0"), 524288, 99, 0, 0, ROMTYPE_CB_BLIZPPC, 0, 0, NULL, + 0, 0, 0, 0, 0, 0, NULL, _T("blizzardppc_040.rom") }, + { _T("Blizzard PPC 68060"), 0, 0, 0, 0, _T("BPPC\0"), 524288, 100, 0, 0, ROMTYPE_CB_BLIZPPC, 0, 0, NULL, + 0, 0, 0, 0, 0, 0, NULL, _T("blizzardppc_060.rom") }, + { _T("ACA 500"), 0, 0, 0, 0, _T("ACA500\0"), 524288, 137, 0, 0, ROMTYPE_CB_ACA500, 0, 0, NULL, + 0, 0, 0, 0, 0, 0, NULL, _T("menu500.aca") }, + + { _T("Picasso IV"), 7, 4, 7, 4, _T("PIV\0"), 131072, 91, 0, 0, ROMTYPE_PICASSOIV, 0, 0, NULL, + 0xa8133e7e, 0xcafafb91,0x6f16b9f3,0xec9b49aa,0x4b40eb4e,0xeceb5b5b }, + + { _T("A1060 BIOS 2.06"), 2, 6, 2, 6, _T("A1060\0"), 16384, 147, 0, 0, ROMTYPE_A1060, 0, 0, _T("380619-03"), + 0x185f2bbd, 0xeba74ad1,0x000a5351,0xa5d99179,0xbf75f831,0xac2d2402, NULL, NULL }, + { _T("A2088 BIOS 3.4"), 3, 4, 3, 4, _T("A2088\0"), 16384, 148, 0, 0, ROMTYPE_A2088, 0, 0, _T("380788-04"), + 0x05552160, 0xd1defdee, 0x1c0eae41, 0x07d81e26, 0x74915cd2, 0x9d352f2e, NULL, NULL }, + { _T("A2088 BIOS 3.5"), 3, 5, 3, 5, _T("A2088\0"), 16384, 158, 0, 0, ROMTYPE_A2088, 0, 0, _T("380788-04"), + 0xf8e1ad83, 0x45a2b7db,0x6e86fe80,0x5cfef63c,0x65c331a7,0x16a6e9e8, NULL, NULL }, + { _T("A2088 BIOS 3.6.1"), 3, 61, 3, 61, _T("A2088\0"), 16384, 149, 0, 0, ROMTYPE_A2088, 0, 0, _T("380788-06"), + 0x5fd93e56, 0xc1b707a8,0xa62907d7,0x5299f10a,0xa60efd1f,0x44514b26, NULL, NULL }, + { _T("A2088T BIOS 4.10"), 4, 10, 4, 11, _T("A2088T\0"), 32768, 150, 0, 0, ROMTYPE_A2088T, 0, 0, _T("390657-02"), + 0x20c5d1a9, 0x08e3fbb7,0x28dfc514,0x24083313,0x373ea7a5,0xa2c3e965, NULL, NULL }, + { _T("A2088T BIOS 4.11"), 4, 11, 4, 11, _T("A2088T\0"), 32768, 151, 0, 0, ROMTYPE_A2088T, 0, 0, _T("390547-02"), + 0x074bc9b0, 0x2a3f56bc,0xe395f203,0x46eb68c4,0xade7153e,0x3e69f892, NULL, NULL }, + { _T("A2088T BIOS 4.12"), 4, 12, 4, 12, _T("A2088T\0"), 32768, 152, 0, 0, ROMTYPE_A2088T, 0, 0, _T("390547-03"), + 0x92447176, 0x582fa254,0x73aa2679,0xefcd41a5,0xbdadf1a2,0x6a87a75f, NULL, NULL }, + { _T("A2286 BIOS 3.6"), 3, 6, 3, 6, _T("A2286\0"), 32768, 153, 0, 0, ROMTYPE_A2286, 0, 0, NULL, + 0x63d75f70, 0x9f5d6c78,0x656d2fe7,0x36608644,0x771b6d30,0x31083264, NULL, NULL }, + ALTROMPN(153, 1, 1, 16384, ROMTYPE_ODD | ROMTYPE_8BIT, _T("380682-03"), 0xb3f76402, 0xef9ba5f2, 0x2714ad6d, 0xfa5e0aef, 0x2d09ce83, 0x578ee26d) + ALTROMPN(153, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("380683-03"), 0xab053693, 0x75229d80, 0x443fad78, 0xa298d04b, 0x37c8e6c3, 0x2c1b6df0) + { _T("A2286 BIOS 4.2"), 4, 2, 4, 2, _T("A2286\0"), 32768, 154, 0, 0, ROMTYPE_A2286, 0, 0, NULL, + 0xd572e205, 0x74fdf0f8,0x325fbc41,0x2b98c72d,0xf5095804,0x831c46b5, NULL, NULL }, + ALTROMPN(154, 1, 1, 16384, ROMTYPE_ODD | ROMTYPE_8BIT, _T("380682-04"), 0xc23dcd55, 0x38dc24b7, 0x14427b15, 0xd5214cc9, 0xb9be0de7, 0x20bd6a34) + ALTROMPN(154, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("380683-04"), 0xdad80c0b, 0x12fe2916, 0x64f8c412, 0x3877a24e, 0x05837091, 0x44d8acd0) + { _T("A2386SX BIOS 1.0"), 1, 0, 1, 0, _T("A2386SX\0"), 65536, 155, 0, 0, ROMTYPE_A2386, 0, 0, NULL, + 0x37003e0c, 0x2e127e9c,0x8581d30c,0x2e46404b,0x21608e3c,0xe935fa27, NULL, NULL }, { _T("Arcadia OnePlay 2.11"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 49, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0 }, { _T("Arcadia TenPlay 2.11"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 50, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0 }, @@ -322,7 +560,129 @@ static struct romdata roms[] = { { _T("Arcadia Leader Board Golf v2.5"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 86, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 }, { _T("Arcadia Aaargh"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 88, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 }, - { NULL } + // maddog_01.dat, maddog_02.dat + { _T("American Laser Games Mad Dog McCree v1C"), 0, 0, 0, 0, _T("ALG\0"), 131072, 175, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x48fd863c, 0x9bf6f337,0x585122a5,0x97c19d71,0x224e3b68,0x347a98de }, + ALTROMPN(175, 1, 1, 65536, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xf64014ec, 0xd343a2cb, 0x5d899215, 0x3b8c916f, 0x39b11d3d, 0xb736543d) + ALTROMPN(175, 1, 2, 65536, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x04572557, 0x3dfe2ce9, 0x4ced8701, 0xa3e73ed5, 0x869b6fbe, 0x1c8b3286) + // md_2.02_u1.bin, md_2.02_u2.bin + { _T("American Laser Games Mad Dog McCree v2.02"), 0, 0, 0, 0, _T("ALG\0"), 262144, 176, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x65181234, 0x321fe70a,0xb0986712,0xe4c6cc17,0x0fe48f1d,0x491ba069 }, + ALTROMPN(176, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xf46e1242, 0x2960bc18,0x00b22eea,0x50036ae4,0x3fd3cb2a,0xb7dcf8a4) + ALTROMPN(176, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xa49890d1, 0x148f78fb,0x426f5b91,0x2e8c3836,0xa149bfcb,0x966da477) + // md_2.03_1.bin, md_2.03_2.bin + { _T("American Laser Games Mad Dog McCree v2.03"), 0, 0, 0, 0, _T("ALG\0"), 262144, 177, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0xbf0878ad, 0x7ff88de7,0x3fd5245e,0x346cca21,0xd0765de1,0x8ba28877 }, + ALTROMPN(177, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xa50d3c04, 0x4cf100fd,0xb5b2f223,0x6539fd0e,0xc33b3db1,0x9c64a6b8) + ALTROMPN(177, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x6f5b8f2d, 0xbbf32bb2,0x7a998d53,0x744411d7,0x5efdbdb7,0x30855809) + // md2_01.bin, md2_02.bin + { _T("American Laser Games Mad Dog II: The Lost Gold v2.02"), 0, 0, 0, 0, _T("ALG\0"), 262144, 178, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x992f9a53, 0xf039a74c,0xc63e1465,0xb3036d4c,0x030df1ef,0x5ba03ff4 }, + ALTROMPN(178, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xaddffa51, 0x665e9d93,0xddfa6b2e,0xa5d006b4,0x1bf7eac3,0x294244cc) + ALTROMPN(178, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x4092227f, 0x6e5393aa,0x5e64b598,0x87260f48,0x3c509600,0x84de7bd1) + // md2_1.10_u1.bin, md2_1.10_u2.bin + { _T("American Laser Games Mad Dog II: The Lost Gold v1.10"), 0, 0, 0, 0, _T("ALG\0"), 262144, 179, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0xc3230ece, 0x4dd60b21,0xf7ab65cd,0x77304753,0x6a4ff2eb,0x75b0778c }, + ALTROMPN(179, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x0e113b2c, 0x739d777f,0x3cb92fbc,0x730c6c1b,0x664d8741,0x21d191b1) + ALTROMPN(179, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x61808612, 0x1a0a301e,0x79585a81,0xe6cf4673,0x7068970f,0xb8a205fa) + // md2_01_v.2.04.bin, md2_02_v.2.04.bin + { _T("American Laser Games Mad Dog II: The Lost Gold v2.04"), 0, 0, 0, 0, _T("ALG\0"), 262144, 180, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x1b9ddae6, 0xd52cc668,0xe4876294,0x5c4d9033,0x71d8a0b1,0x323b4464 }, + ALTROMPN(180, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x361bd99c, 0x5de6ef38,0xe334e19f,0x509227de,0x7880306a,0xc984ec23) + ALTROMPN(180, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x0e1227f4, 0xbfd9081b,0xb7d2bcbb,0x77357839,0xf292ce61,0x36e9b228) + // md2_1.0_1.bin, md2_1.0_2.bin + { _T("American Laser Games Mad Dog II: The Lost Gold v1.00"), 0, 0, 0, 0, _T("ALG\0"), 262144, 181, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x348b1a05, 0xece8f1ec,0x4d97f98d,0xb1279ed5,0x28cb0fca,0x51c167bb }, + ALTROMPN(181, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x0ce8db97, 0xdd4c09db,0x59bb8c6c,0xaba935b1, 0xb28babe2, 0x8ba8516b) + ALTROMPN(181, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x97272a1d, 0x10901464,0x7c491f01,0x9ffb2109, 0x1c7d0b89, 0xe1755b75) + // sp_14_u1.bin, sp_14_u2.bin + { _T("American Laser Games Space Pirates v1.4"), 0, 0, 0, 0, _T("ALG\0"), 262144, 182, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x69e09b90, 0xda3cba84,0x1c37222f,0xc45b4704,0x997072ad,0x1e9a1f8e }, + ALTROMPN(182, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x4102988c, 0x969d4668,0xbe50990c,0x7debf9ed,0x4e8b8c6e,0x422acdf5) + ALTROMPN(182, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x30390ab0, 0x80fa14d8,0x81902258,0x398225bd,0xfd71ed5e,0x9e2d6c91) + // sp_01.dat, sp_02.dat + { _T("American Laser Games Space Pirates v2.2"), 0, 0, 0, 0, _T("ALG\0"), 262144, 183, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x09c2cfcb, 0x93ad6a25,0x77fa7870,0x971890f2,0x6af11382, 0xa433f80b }, + ALTROMPN(183, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x10d162a2, 0x26833d5b,0xe1057be8,0x639c00a7,0xbe18be33,0x404ea751) + ALTROMPN(183, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xc0975188, 0xfd7643dc,0x972e7861,0x249ab7e7,0x61999759,0x84888ae4) + // johnny_01.bin, johnny_02.bin + { _T("American Laser Games Who Shot Johnny Rock? v1.6"), 0, 0, 0, 0, _T("ALG\0"), 131072, 184, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0xaeda7df4, 0xa612c4b9,0x2bd81ab9,0x564e58da,0x9a6a4d81,0x93c59acf }, + ALTROMPN(184, 1, 1, 65536, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x046569b3, 0xefe5a8b2,0xbe1c5556,0x95f2a91c,0x88951d35,0x45f1b915) + ALTROMPN(184, 1, 2, 65536, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xedde1745, 0x573b79f8,0x808fedaa,0xbf3b7623,0x50a91579,0x2d26c1bc) + // wsjr151.bin,wsjr152.bin + { _T("American Laser Games Who Shot Johnny Rock? v1.5"), 0, 0, 0, 0, _T("ALG\0"), 131072, 185, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x50eb4827, 0x72568673,0x4163aa16,0xd0ad3177,0xbd720187,0x125a63ec }, + ALTROMPN(185, 1, 1, 65536, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x8ab626dd, 0xe45561f7,0x7fc279b7,0x1dc1dd2e,0x15a0870c,0xb5c1cd89) + ALTROMPN(185, 1, 2, 65536, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x9beeb1d7, 0x3fe0265e,0x5d36103d,0x3d9557d7,0x5e5e3728,0xe0b30da7) + // gg_1.dat,gg_2.dat + { _T("American Laser Games Gallagher's Gallery v2.2"), 0, 0, 0, 0, _T("ALG\0"), 262144, 186, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0xcbe791de, 0x17aa6f16,0x7e138409,0xe1ef039e,0x928fee5a,0xf43e91cb }, + ALTROMPN(186, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x855c9d82, 0x96711aaa,0x02f309ca,0xcd3e8d8e,0xfbe95cfc,0x811aba96) + ALTROMPN(186, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x3793b211, 0xdccb1d9c,0x5e2d6a4d,0x249426ae,0x6348e9fc,0x9b72e665) + // gg_21_rom1.bin,gg_21_rom2.bin + { _T("American Laser Games Gallagher's Gallery v2.1"), 0, 0, 0, 0, _T("ALG\0"), 262144, 187, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x9bfe35bb, 0x76c8cad8,0xd0f4758f,0x1adc0fc9,0x7cb6ad30,0x44b54d47 }, + ALTROMPN(187, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x70f887e5, 0xcd6cedc8,0x5bbe6767,0x4dfd140f,0xed901877,0x8f8cd8db) + ALTROMPN(187, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x4109f39e, 0x42d06de4,0x2c56f21e,0x4899b4c4,0x252baabb,0x51f24fda) + // fd_131_u1.bin,fd_131_u2.bin + { _T("American Laser Games Fast Draw Showdown v1.31"), 0, 0, 0, 0, _T("ALG\0"), 262144, 188, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x6977addf, 0xdc845431,0xbb1a39bd,0x615afe5f,0x7cb7c8d0,0x3433ef8c }, + ALTROMPN(188, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xe1ed7982, 0xf7562c6e,0x0ce6bf1a,0x9885cc59,0x3e08c250,0x9f82bbe1) + ALTROMPN(188, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xb7c79ab3, 0x6eca1bc9,0x590c22a0,0x04fb8590,0x1e5c7d41,0xf5b14ee2) + // fast_01.bin,fast_02.bin + { _T("American Laser Games Fast Draw Showdown v1.30"), 0, 0, 0, 0, _T("ALG\0"), 262144, 189, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x47772e36, 0x5af67b5e,0xa56b2337,0xfdd427fb,0xd82d478f,0xb1994dbc }, + ALTROMPN(189, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x0d76a2da, 0xd396371a,0xe1b9b0b6,0xe6bc6f1f,0x85c4b97b,0xfc5dc34d) + ALTROMPN(189, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x4c4eb71e, 0x3bd487c5,0x46b6c807,0x70a5fc88,0x0dcb1039,0x5ca431a2) + // lbh_101_u1.bin,lbh_101_u2.bin + { _T("American Laser Games The Last Bounty Hunter v1.01"), 0, 0, 0, 0, _T("ALG\0"), 262144, 190, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0xd2a5a539, 0xb97c799b,0x53355b55,0x4dfbf335,0x6f20fd2b,0xa5998806 }, + ALTROMPN(190, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xb21c5c42, 0x9ac856cd,0xf2c9538c,0xc4ae55f0,0x79f33737,0x6d3361c0) + ALTROMPN(190, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xf13b25d2, 0xe2f663c2,0x3b03592f,0x482ef5e1,0xdf87b651,0x937a500d) + // bounty_01.bin,bounty_02.bin + { _T("American Laser Games The Last Bounty Hunter v0.06"), 0, 0, 0, 0, _T("ALG\0"), 262144, 191, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0xce600734, 0xe52aea03,0x080dcd08,0x8d4b61ed,0xe46de9c7,0xfc4dd74e }, + ALTROMPN(191, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x2727ef1d, 0xf5342139,0x0b65c21a,0x7666ff9d,0x0f53ebf2,0xa463d836) + ALTROMPN(191, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x977566b2, 0x937e079e,0x992ecb59,0x30b17c10,0x24c326e1,0x0962642b) + // cp_151_u1.bin,cp_151_u2.bin + { _T("American Laser Games Crime Patrol v1.51"), 0, 0, 0, 0, _T("ALG\0"), 262144, 192, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0xcada2bed, 0xc5da9d82,0x7864feff,0x75d87dd1,0x9ec06529,0x7d2b318b }, + ALTROMPN(192, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xaefd6e09, 0x351e665e,0x2e636804,0x7a5cc80d,0x0f9d876b,0xca068b6a) + ALTROMPN(192, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xf2270cee, 0x1e735373,0x723c3cff,0xb6dd04d5,0xc30c08e7,0x57deae61) + // cp01.dat,cp02.dat + { _T("American Laser Games Crime Patrol v1.4"), 0, 0, 0, 0, _T("ALG\0"), 262144, 193, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x51ba3153, 0x55086ba0,0xef41c6d6,0x41041b73,0x047cad38,0xaf2a21f3 }, + ALTROMPN(193, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xa39a8b50, 0x55ca317e,0xf13c3a42,0xf12d68c4,0x80e6cc2d,0x4459f6a4) + ALTROMPN(193, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xe41fd2e8, 0x1cd9875f,0xb4133ba4,0xe3616271,0x975dc736,0xb343f156) + // cp_1.20_u1.bin,cp_1.20_u2.bin + { _T("American Laser Games Crime Patrol v1.2"), 0, 0, 0, 0, _T("ALG\0"), 262144, 194, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x63e9f444, 0x6f2624a5,0x6a672f97,0xc751ae51,0xb4b834a5,0x097a855a }, + ALTROMPN(194, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x475e847a, 0x82fd1608,0x35758cd5,0x1ea22f90,0xb08921a4,0x0409f94d) + ALTROMPN(194, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x814f5777, 0x341a1d7b,0x64112af3,0xe8243bdb,0xfec72e7f,0xa85aa903) + // cp2_1.3_1.bin, cp2_1.3_2.bin + { _T("American Laser Games Crime Patrol 2: Drug Wars v1.3"), 0, 0, 0, 0, _T("ALG\0"), 262144, 195, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x57d1f606, 0xffbee51c,0x9c52a9c6,0x6440cbf8,0x34144321,0x75036282 }, + ALTROMPN(195, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xdbdaa79a, 0x99804490,0x9d5c93e3,0xbd1baafe,0xfab818fd,0xb7b3f55e) + ALTROMPN(195, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xe653395d, 0x8f6c86d9,0x8a52b7d8,0x5ae285fd,0x841167cd,0x07979318) + // cp2_1.dat, cp2_2.dat + { _T("American Laser Games Crime Patrol 2: Drug Wars v1.1"), 0, 0, 0, 0, _T("ALG\0"), 262144, 196, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x49c751db, 0x789679f9,0xa3fe3aa0,0xf9b8bb35,0x1f3ea632,0xe429408d }, + ALTROMPN(196, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xf4e5251e, 0xe0c91343,0xa98193d4,0x87c40e7a,0x85f542b2,0xa7a88f03) + ALTROMPN(196, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x47879042, 0x8bb6c541,0xe4e8e450,0x8da8d4b9,0x3600176a,0x2e7a1f41) + // platoonv4u1.bin,platoonv4u2.bin + { _T("Nova Platoon V.3.1 US"), 0, 0, 0, 0, _T("ALG\0"), 262144, 197, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0xad975c96, 0x9565207f,0x6684baa8,0xe5c85c34,0x740a3f60,0x75d3a7b5 }, + ALTROMPN(197, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x09a133cf, 0x9b3ff630,0x35be8576,0xc88fb284,0xa25c2da5,0xdb0d5160) + ALTROMPN(197, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x8b33263e, 0xa1df3823,0x6321af90,0xb522e2a7,0x83984fdf,0x02e4c597) + // zb_u2.bin,zb_u3.bin + { _T("Web Picmatic Zorton Brothers (Los Justicieros)"), 0, 0, 0, 0, _T("ALG\0"), 131072, 198, 0, 0, ROMTYPE_ALG, 0, 0, NULL, + 0x9cda09ae, 0x3353ae63,0x64b3d0b1,0x006db48e,0xa2bdc7b5,0x4946bbb9 }, + ALTROMPN(198, 1, 1, 65536, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xf59cfc4a, 0x9fadf7f1,0xe23d6b4e,0x828bf2b3,0xde919d08,0x7c690a3f) + ALTROMPN(198, 1, 2, 65536, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x938b25cb, 0xd0114bbc,0x588dcfce,0x6a469013,0xd0e35afb,0x93e38af5) + + { NULL } + }; void romlist_clear (void) @@ -968,16 +1328,32 @@ void getromname (const struct romdata *rd, TCHAR *name) _stprintf (name + _tcslen (name), _T(" [%s]"), rd->partnumber); } -struct romlist *getromlistbyromdata (const struct romdata *rd) +struct romlist *getromlistbyromdata(const struct romdata *rd) { - int ids[2]; - - ids[0] = rd->id; - ids[1] = 0; - return getromlistbyids(ids); + int ids[2]; + + ids[0] = rd->id; + ids[1] = -1; + return getromlistbyids(ids, NULL); } -struct romlist *getromlistbyids (const int *ids) +struct romlist *getromlistbyromtype(uae_u32 romtype) +{ + int i = 0; + while (roms[i].name) { + if (roms[i].type == romtype) { + struct romdata *rd = &roms[i]; + for (int j = 0; j < romlist_cnt; j++) { + if (rl[j].rd->id == rd->id) + return &rl[j]; + } + } + i++; + } + return NULL; +} + +struct romlist *getromlistbyids(const int *ids, const TCHAR *romname) { struct romdata *rd; int i, j; @@ -996,29 +1372,31 @@ struct romlist *getromlistbyids (const int *ids) return NULL; } -void romwarning (const int *ids) +void romwarning(const int *ids) { int i, exp; TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH]; TCHAR tmp3[MAX_DPATH]; + if (ids[0] == -1) + return; exp = 0; tmp2[0] = 0; i = 0; while (ids[i] >= 0) { - struct romdata *rd = getromdatabyid (ids[i]); + struct romdata *rd = getromdatabyid(ids[i]); if (!(rd->type & ROMTYPE_NONE)) { - getromname (rd, tmp1); - _tcscat (tmp2, _T("- ")); - _tcscat (tmp2, tmp1); - _tcscat (tmp2, _T("\n")); - if (rd->type & (ROMTYPE_A2091BOOT | ROMTYPE_A4091BOOT)) - exp++; + getromname(rd, tmp1); + _tcscat(tmp2, _T("- ")); + _tcscat(tmp2, tmp1); + _tcscat(tmp2, _T("\n")); + if (rd->type & (ROMTYPE_SCSI | ROMTYPE_CPUBOARD | ROMTYPE_CD32CART)) + exp++; } i++; - } - translate_message (exp ? NUMSG_EXPROMNEED : NUMSG_ROMNEED, tmp3); - gui_message (tmp3, tmp2); + } + translate_message(exp ? NUMSG_EXPROMNEED : NUMSG_ROMNEED, tmp3); + gui_message(tmp3, tmp2); } static void byteswap (uae_u8 *buf, int size) @@ -1356,8 +1734,334 @@ int configure_rom (struct uae_prefs *p, const int *rom, int msg) return 0; } if (rd->type & (ROMTYPE_KICK | ROMTYPE_KICKCD32)) - _tcscpy (p->romfile, path); - if (rd->type & (ROMTYPE_EXTCD32 | ROMTYPE_EXTCDTV | ROMTYPE_ARCADIABIOS)) - _tcscpy (p->romextfile, path); + _tcscpy(p->romfile, path); + if (rd->type & (ROMTYPE_EXTCD32 | ROMTYPE_EXTCDTV | ROMTYPE_ARCADIABIOS | ROMTYPE_ALG)) + _tcscpy(p->romextfile, path); + if (rd->type & ROMTYPE_CD32CART) { + _tcscpy(p->cartfile, path); + struct boardromconfig *brc = get_device_rom_new(p, ROMTYPE_CD32CART, 0, NULL); + if (brc) + _tcscpy(brc->roms[0].romfile, p->cartfile); + } + if ((rd->type & ROMTYPE_ARCADIAGAME) || + rd->type == ROMTYPE_HRTMON || rd->type == ROMTYPE_XPOWER || rd->type == ROMTYPE_NORDIC || rd->type == ROMTYPE_AR || rd->type == ROMTYPE_SUPERIV) + _tcscpy(p->cartfile, path); + if (rd->type & ROMTYPE_CPUBOARD) + set_device_rom(p, path, ROMTYPE_CPUBOARD, 0); return 1; } + +void set_device_rom(struct uae_prefs *p, const TCHAR *path, int romtype, int devnum) +{ + int idx; + const struct expansionromtype *ert = get_device_expansion_rom(romtype); + if (path == NULL) { + struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx); + if (brc) { + brc->roms[idx].romfile[0] = 0; + brc->roms[idx].romident[0] = 0; + } + } + else { + struct boardromconfig *brc = get_device_rom_new(p, romtype, devnum, &idx); + _tcscpy(brc->roms[idx].romfile, path); + } +} + +const struct expansionromtype *get_unit_expansion_rom(int hdunit) +{ + if (hdunit >= HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST && hdunit <= HD_CONTROLLER_TYPE_SCSI_LAST) + return &expansionroms[hdunit - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST]; + if (hdunit >= HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST && hdunit <= HD_CONTROLLER_TYPE_IDE_LAST) + return &expansionroms[hdunit - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST]; + return NULL; +} + +const struct expansionromtype *get_device_expansion_rom(int romtype) +{ + for (int i = 0; expansionroms[i].name; i++) { + const struct expansionromtype *ert = &expansionroms[i]; + if ((ert->romtype & ROMTYPE_MASK) == (romtype & ROMTYPE_MASK)) + return ert; + } + return NULL; +} + +static void device_rom_defaults(struct uae_prefs *p, struct boardromconfig *brc, int romtype, int devnum) +{ + memset(brc, 0, sizeof(boardromconfig)); + brc->device_type = romtype; + brc->device_num = devnum; + for (int i = 0; i < MAX_BOARD_ROMS; i++) { + brc->roms[i].device_id = 7; + brc->roms[i].back = brc; + } + int order = 0; + for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) { + if (p->expansionboard[i].device_order > order) + order = p->expansionboard[i].device_order; + } + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + if (p->fastmem[i].device_order > order) + order = p->fastmem[i].device_order; + if (p->z3fastmem[i].device_order > order) + order = p->z3fastmem[i].device_order; + } + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + if (p->rtgboards[i].device_order > order) + order = p->rtgboards[i].device_order; + } + brc->device_order = order + 1; +} + +struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int devnum, int *index) +{ + int idx2; + static struct boardromconfig fake; + const struct expansionromtype *ert = get_device_expansion_rom(romtype); + if (!ert) { + if (index) + *index = 0; + return &fake; + } + if (index) + *index = ert->parentromtype ? 1 : 0; + struct boardromconfig *brc = get_device_rom(p, ert->parentromtype ? ert->parentromtype : romtype, devnum, &idx2); + if (!brc) { + for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) { + brc = &p->expansionboard[i]; + if (brc->device_type == 0) + continue; + int ok = 0; + for (int j = 0; j < MAX_BOARD_ROMS; j++) { + if (!brc->roms[j].romfile[0] && !brc->roms[j].romident[0] && !brc->roms[j].board_ram_size) + ok++; + } + if (ok == MAX_BOARD_ROMS) + memset(brc, 0, sizeof(boardromconfig)); + } + for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) { + brc = &p->expansionboard[i]; + if (brc->device_type == 0) { + device_rom_defaults(p, brc, romtype, devnum); + return brc; + } + } + return &fake; + } + return brc; +} + +void clear_device_rom(struct uae_prefs *p, int romtype, int devnum, bool deleteDevice) +{ + int index; + struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &index); + if (!brc) + return; + if (deleteDevice) { + memset(brc, 0, sizeof(struct boardromconfig)); + } + else { + memset(&brc->roms[index], 0, sizeof(struct romconfig)); + } +} + +struct boardromconfig *get_device_rom(struct uae_prefs *p, int romtype, int devnum, int *index) +{ + const struct expansionromtype *ert = get_device_expansion_rom(romtype); + if (!ert) { + *index = 0; + return NULL; + } + int parentrom = ert->parentromtype ? ert->parentromtype : romtype; + if (index) + *index = ert->parentromtype ? 1 : 0; + for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) { + struct boardromconfig *brc = &p->expansionboard[i]; + if (!brc->device_type) + continue; + if ((brc->device_type & ROMTYPE_MASK) == (parentrom & ROMTYPE_MASK) && brc->device_num == devnum) + return brc; + } + return NULL; +} + +struct romconfig *get_device_romconfig(struct uae_prefs *p, int romtype, int devnum) +{ + int idx; + struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx); + if (brc) + return &brc->roms[idx]; + return NULL; +} + +void board_prefs_changed(int romtype, int devnum) +{ + int idx1, idx2; + struct boardromconfig *brc1 = get_device_rom(&currprefs, romtype, devnum, &idx1); + struct boardromconfig *brc2 = get_device_rom(&changed_prefs, romtype, devnum, &idx2); + if (brc1 && brc2) { + memcpy(brc1, brc2, sizeof(struct boardromconfig)); + } + else if (brc1 && !brc2) { + clear_device_rom(&currprefs, romtype, devnum, true); + } + else if (!brc1 && brc2) { + brc1 = get_device_rom_new(&currprefs, romtype, devnum, &idx1); + if (brc1) + memcpy(brc1, brc2, sizeof(struct boardromconfig)); + } +} + +bool is_board_enabled(struct uae_prefs *p, int romtype, int devnum) +{ + int idx; + if (romtype == ROMTYPE_CPUBOARD && p->cpuboard_type) { + return devnum == 0; + } + struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx); + if (!brc) + return false; + return brc->roms[idx].romfile[0] != 0; +} + +static bool isspecialrom(const TCHAR *name) +{ + if (!_tcsicmp(name, _T(":NOROM"))) + return true; + if (!_tcsicmp(name, _T(":ENABLED"))) + return true; + return false; +} + +struct zfile *read_device_from_romconfig(struct romconfig *rc, uae_u32 romtype) +{ + struct zfile *z = NULL; + if (isspecialrom(rc->romfile)) + return z; + z = read_rom_name(rc->romfile); + if (z) + return z; + if (romtype) { + struct romlist *rl = getromlistbyromtype(romtype); + if (rl) { + struct romdata *rd = rl->rd; + z = read_rom(rd); + } + } + return z; +} + +struct zfile *read_device_rom(struct uae_prefs *p, int romtype, int devnum, int *roms) +{ + int idx; + struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx); + if (brc) { + const TCHAR *romname = brc->roms[idx].romfile; + if (isspecialrom(romname)) + return NULL; + struct zfile *z = read_rom_name(romname); + if (!z && roms) { + struct romlist *rl = getromlistbyids(roms, romname); + if (rl) { + struct romdata *rd = rl->rd; + z = read_rom(rd); + } + } + return z; + } + return NULL; +} + +int is_device_rom(struct uae_prefs *p, int romtype, int devnum) +{ + int idx; + struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx); + if (brc) { + const TCHAR *romname = brc->roms[idx].romfile; + if (_tcslen(romname) == 0) + return -1; + if (isspecialrom(romname)) + return 0; + return 1; + } + return -1; +} + +struct boardromconfig *get_boardromconfig(struct uae_prefs *p, int romtype, int *index) +{ + for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) { + struct boardromconfig *brc = &p->expansionboard[i]; + if (!brc->device_type) + continue; + if ((brc->device_type & ROMTYPE_MASK) == (romtype & ROMTYPE_MASK)) { + for (int j = 0; j < MAX_BOARD_ROMS; j++) { + if (brc->roms[j].romfile[0]) { + if (index) + *index = j; + return brc; + } + } + } + } + return NULL; +} + +bool load_rom_rc(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags) +{ + if (flags & LOADROM_ONEFILL) + memset(rom, 0xff, maxromsize); + if (flags & LOADROM_ZEROFILL) + memset(rom, 0x00, maxromsize); + struct zfile *f = read_device_from_romconfig(rc, romtype); + if (!f) + return false; + zfile_fseek(f, fileoffset, SEEK_SET); + int cnt = 0; + int pos = 0; + int bytes = 0; + bool eof = false; + while (cnt < maxromsize && cnt < maxfilesize && pos < maxromsize) { + uae_u8 b = 0xff; + if (!eof) { + if (!zfile_fread(&b, 1, 1, f)) + eof = true; + else + bytes++; + } + if (eof) { + int bitcnt = 0; + for (int i = 1; i < maxromsize; i <<= 1) { + if (cnt & i) + bitcnt++; + } + if (bitcnt == 1) + break; + } + + rom[pos] = b; + if (flags & LOADROM_EVENONLY) { + rom[pos + 1] = (flags >> 16) & 0xff; + pos += 2; + } + else { + pos += 1; + } + cnt++; + } + if (f) + write_log(_T("ROM '%s' loaded, %d bytes.\n"), zfile_getname(f), bytes); + zfile_fclose(f); + int posend = pos; + if (!(flags & LOADROM_FILL)) + return true; + int oldpos = 0; + while (pos < maxromsize) { + rom[pos] = rom[oldpos]; + oldpos++; + pos++; + if (oldpos >= posend) + oldpos = 0; + } + return true; +} \ No newline at end of file diff --git a/src/savestate.cpp b/src/savestate.cpp index 3fa5ba16..7c906cc4 100644 --- a/src/savestate.cpp +++ b/src/savestate.cpp @@ -461,7 +461,7 @@ void restore_state(const TCHAR* filename) TCHAR name[5]; size_t len, totallen; size_t filepos, filesize; - int z3num; + int z3num, z2num; chunk = 0; f = zfile_fopen(filename, _T("rb"), ZFD_NORMAL); @@ -485,9 +485,9 @@ void restore_state(const TCHAR* filename) restore_cia_start(); changed_prefs.bogomem_size = 0; changed_prefs.chipmem_size = 0; - changed_prefs.fastmem_size = 0; - changed_prefs.z3fastmem_size = 0; - z3num = 0; + changed_prefs.fastmem[0].size = 0; + changed_prefs.z3fastmem[0].size = 0; + z2num = z3num = 0; for (;;) { name[0] = 0; @@ -510,7 +510,7 @@ void restore_state(const TCHAR* filename) } else if (!_tcscmp (name, _T("FRAM"))) { - restore_fram(totallen, filepos); + restore_fram(totallen, filepos, z2num++); continue; } else if (!_tcscmp (name, _T("ZRAM"))) @@ -663,7 +663,7 @@ void savestate_restore_finish() #endif restore_cia_finish(); savestate_state = 0; - init_hz_full(); + init_hz_normal(); audio_activate(); } @@ -695,9 +695,15 @@ static void save_rams(struct zfile* f, int comp) dst = save_bram(&len); save_chunk(f, dst, len, _T("BRAM"), comp); #ifdef AUTOCONFIG - dst = save_fram(&len); - save_chunk(f, dst, len, _T("FRAM"), comp); - dst = save_zram(&len, 0); + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + dst = save_fram(&len, i); + save_chunk(f, dst, len, _T("FRAM"), comp); + } + for (int i = 0; i < MAX_RAM_BOARDS; i++) { + dst = save_zram(&len, i); + save_chunk(f, dst, len, _T("ZRAM"), comp); + } + dst = save_zram(&len, -1); save_chunk(f, dst, len, _T("ZRAM"), comp); dst = save_bootrom(&len); save_chunk(f, dst, len, _T("BORO"), comp); diff --git a/src/trace.c b/src/trace.c deleted file mode 100644 index b826f061..00000000 --- a/src/trace.c +++ /dev/null @@ -1,87 +0,0 @@ -#define _GNU_SOURCE - -#include -#include -#include -#include - - -#define MAX_TRACE 2000 - -static void* trc_func[MAX_TRACE]; -static void* trc_caller[MAX_TRACE]; -static int trc_enter[MAX_TRACE]; -static int trc_number[MAX_TRACE]; -static int trc_next_write = 0; -static int trc_counter = 0; - -static int do_trace = 0; - -static FILE *fd; - - -void trace_begin (void) -{ - if(do_trace) - return; - memset(trc_enter, 0, sizeof(int) * MAX_TRACE); - do_trace = 1; -} - -void trace_end (void) -{ - if(do_trace) - { - do_trace = 0; - - fd = fopen("trace.txt", "w"); - for(int i=0; i 0) - { - Dl_info dlinfo; - memset(&dlinfo, 0, sizeof(dlinfo)); - int func_found = dladdr(trc_func[trc_next_write], &dlinfo); - if(func_found && dlinfo.dli_sname != NULL) - { - fprintf(fd, "%8d - %s 0x%08X from 0x%08X (%s)\n", trc_number[trc_next_write], (trc_enter[trc_next_write] == 1 ? "enter" : "leave"), - trc_func[trc_next_write], trc_caller[trc_next_write], dlinfo.dli_sname); - } - } - ++trc_next_write; - if(trc_next_write >= MAX_TRACE) - trc_next_write = 0; - } - fclose(fd); - } -} - -void __cyg_profile_func_enter (void *func, void *caller) -{ - if(do_trace) - { - trc_enter[trc_next_write] = 1; - trc_func[trc_next_write] = func; - trc_caller[trc_next_write] = caller; - trc_number[trc_next_write] = trc_counter; - ++trc_counter; - ++trc_next_write; - if(trc_next_write >= MAX_TRACE) - trc_next_write = 0; - } -} - -void __cyg_profile_func_exit (void *func, void *caller) -{ - if(do_trace) - { - trc_enter[trc_next_write] = 2; - trc_func[trc_next_write] = func; - trc_caller[trc_next_write] = caller; - trc_number[trc_next_write] = trc_counter; - ++trc_counter; - ++trc_next_write; - if(trc_next_write >= MAX_TRACE) - trc_next_write = 0; - } -} diff --git a/src/traps.cpp b/src/traps.cpp index b40ae553..dede43e6 100644 --- a/src/traps.cpp +++ b/src/traps.cpp @@ -74,6 +74,7 @@ struct Trap static struct Trap traps[MAX_TRAPS]; static unsigned int trap_count = 1; +volatile uae_atomic hwtrap_waiting; static const int trace_traps = 0; @@ -523,3 +524,4 @@ void init_extended_traps() trap_mutex = nullptr; uae_sem_init(&trap_mutex, 0, 1); } + diff --git a/src/uaelib.cpp b/src/uaelib.cpp index 1f3bb20b..08eecff4 100755 --- a/src/uaelib.cpp +++ b/src/uaelib.cpp @@ -28,45 +28,45 @@ #include "picasso96.h" #include "filesys.h" -/* + /* * Returns UAE Version */ -static uae_u32 emulib_GetVersion (void) +static uae_u32 emulib_GetVersion(void) { - return version; + return version; } /* - * Resets your amiga - */ -static uae_u32 emulib_HardReset (void) +* Resets your amiga +*/ +static uae_u32 emulib_HardReset(void) { uae_reset(1, 1); - return 0; + return 0; } -static uae_u32 emulib_Reset (void) +static uae_u32 emulib_Reset(void) { uae_reset(0, 0); - return 0; + return 0; } /* - * Enables SOUND - */ -static uae_u32 emulib_EnableSound (uae_u32 val) +* Enables SOUND +*/ +static uae_u32 emulib_EnableSound(uae_u32 val) { - if (!sound_available || currprefs.produce_sound == 2) - return 0; + if (!sound_available || currprefs.produce_sound == 2) + return 0; - currprefs.produce_sound = val; - return 1; + currprefs.produce_sound = val; + return 1; } /* - * Enables FAKE JOYSTICK - */ -static uae_u32 emulib_EnableJoystick (uae_u32 val) +* Enables FAKE JOYSTICK +*/ +static uae_u32 emulib_EnableJoystick(uae_u32 val) { currprefs.jports[0].id = val & 255; currprefs.jports[1].id = (val >> 8) & 255; @@ -74,18 +74,18 @@ static uae_u32 emulib_EnableJoystick (uae_u32 val) } /* - * Sets the framerate - */ -static uae_u32 emulib_SetFrameRate (uae_u32 val) +* Sets the framerate +*/ +static uae_u32 emulib_SetFrameRate(uae_u32 val) { - if (val == 0) - return 0; - else if (val > 20) - return 0; - else { - currprefs.gfx_framerate = val; - return 1; - } + if (val == 0) + return 0; + else if (val > 20) + return 0; + else { + currprefs.gfx_framerate = val; + return 1; + } } /* @@ -103,78 +103,78 @@ static uae_u32 emulib_ChangeLanguage (uae_u32 which) * Changes chip memory size * (reboots) */ -static uae_u32 REGPARAM2 emulib_ChgCMemSize (uae_u32 memsize) +static uae_u32 REGPARAM2 emulib_ChgCMemSize(TrapContext *ctx, uae_u32 memsize) { - if (memsize != 0x80000 && memsize != 0x100000 && - memsize != 0x200000) { - memsize = 0x200000; - write_log (_T("Unsupported chipmem size!\n")); - } - m68k_dreg (regs, 0) = 0; + if (memsize != 0x80000 && memsize != 0x100000 && + memsize != 0x200000) { + memsize = 0x200000; + write_log(_T("Unsupported chipmem size!\n")); + } + m68k_dreg(regs, 0) = 0; - changed_prefs.chipmem_size = memsize; + changed_prefs.chipmem_size = memsize; uae_reset(1, 1); - return 1; + return 1; } /* * Changes slow memory size * (reboots) */ -static uae_u32 REGPARAM2 emulib_ChgSMemSize (uae_u32 memsize) +static uae_u32 REGPARAM2 emulib_ChgSMemSize(TrapContext *ctx, uae_u32 memsize) { - if (memsize != 0x80000 && memsize != 0x100000 && - memsize != 0x180000 && memsize != 0x1C0000) { - memsize = 0; - write_log (_T("Unsupported bogomem size!\n")); - } + if (memsize != 0x80000 && memsize != 0x100000 && + memsize != 0x180000 && memsize != 0x1C0000) { + memsize = 0; + write_log(_T("Unsupported bogomem size!\n")); + } - m68k_dreg (regs, 0) = 0; - changed_prefs.bogomem_size = memsize; - uae_reset (1, 1); - return 1; + m68k_dreg(regs, 0) = 0; + changed_prefs.bogomem_size = memsize; + uae_reset(1, 1); + return 1; } /* * Changes fast memory size * (reboots) */ -static uae_u32 REGPARAM2 emulib_ChgFMemSize (uae_u32 memsize) +static uae_u32 REGPARAM2 emulib_ChgFMemSize(TrapContext *ctx, uae_u32 memsize) { - if (memsize != 0x100000 && memsize != 0x200000 && - memsize != 0x400000 && memsize != 0x800000) { - memsize = 0; - write_log (_T("Unsupported fastmem size!\n")); - } - m68k_dreg (regs, 0) = 0; - changed_prefs.fastmem_size = memsize; - uae_reset (1, 1); - return 0; + if (memsize != 0x100000 && memsize != 0x200000 && + memsize != 0x400000 && memsize != 0x800000) { + memsize = 0; + write_log(_T("Unsupported fastmem size!\n")); + } + m68k_dreg(regs, 0) = 0; + changed_prefs.fastmem[0].size = memsize; + uae_reset(1, 1); + return 0; } /* * Inserts a disk */ -static uae_u32 emulib_InsertDisk (uaecptr name, uae_u32 drive) +static uae_u32 emulib_InsertDisk(TrapContext *ctx, uaecptr name, uae_u32 drive) { - int i = 0; - char real_name[256]; + int i = 0; + char real_name[256]; TCHAR *s; - if (drive > 3) - return 0; + if (drive > 3) + return 0; - while ((real_name[i] = get_byte (name + i)) != 0 && i++ != 254) - ; + while ((real_name[i] = get_byte(name + i)) != 0 && i++ != 254) + ; - if (i == 255) - return 0; /* ENAMETOOLONG */ + if (i == 255) + return 0; /* ENAMETOOLONG */ - s = au (real_name); - _tcscpy (changed_prefs.floppyslots[drive].df, s); - xfree (s); + s = au(real_name); + _tcscpy(changed_prefs.floppyslots[drive].df, s); + xfree(s); - return 1; + return 1; } /* @@ -190,42 +190,42 @@ static uae_u32 emulib_ExitEmu (void) /* * Gets UAE Configuration */ -static uae_u32 emulib_GetUaeConfig (uaecptr place) +static uae_u32 emulib_GetUaeConfig(TrapContext *ctx, uaecptr place) { - int i, j; + int j; - put_long (place, version); - put_long (place + 4, chipmem_bank.allocated); - put_long (place + 8, bogomem_bank.allocated); - put_long (place + 12, fastmem_bank.allocated); - put_long (place + 16, currprefs.gfx_framerate); - put_long (place + 20, currprefs.produce_sound); - put_long (place + 24, currprefs.jports[0].id | (currprefs.jports[1].id << 8)); - put_long (place + 28, 0); - if (disk_empty (0)) - put_byte (place + 32, 0); - else - put_byte (place + 32, 1); - if (disk_empty (1)) - put_byte (place + 33, 0); - else - put_byte (place + 33, 1); - if (disk_empty(2)) - put_byte (place + 34, 0); - else - put_byte (place + 34, 1); - if (disk_empty(3)) - put_byte (place + 35, 0); - else - put_byte (place + 35, 1); + put_long(place, version); + put_long(place + 4, chipmem_bank.allocated_size); + put_long(place + 8, bogomem_bank.allocated_size); + put_long(place + 12, fastmem_bank[0].allocated_size); + put_long(place + 16, currprefs.gfx_framerate); + put_long(place + 20, currprefs.produce_sound); + put_long(place + 24, currprefs.jports[0].id | (currprefs.jports[1].id << 8)); + //put_long(ctx, place + 28, currprefs.keyboard_lang); + if (disk_empty(0)) + put_byte(place + 32, 0); + else + put_byte(place + 32, 1); + if (disk_empty(1)) + put_byte(place + 33, 0); + else + put_byte(place + 33, 1); + if (disk_empty(2)) + put_byte(place + 34, 0); + else + put_byte(place + 34, 1); + if (disk_empty(3)) + put_byte(place + 35, 0); + else + put_byte(place + 35, 1); - for (j = 0; j < 4; j++) { - char *s = ua (currprefs.floppyslots[j].df); + for (int i = 0; i < 4; i++) { + char *s = ua(currprefs.floppyslots[i].df); for (i = 0; i < 256; i++) - put_byte (place + 36 + i + j * 256, s[i]); - xfree (s); - } - return 1; + put_byte(place + 36 + i + j * 256, s[i]); + xfree(s); + } + return 1; } /* @@ -241,16 +241,16 @@ static uae_u32 emulib_SetUaeConfig (uaecptr place) /* * Gets the name of the disk in the given drive */ -static uae_u32 emulib_GetDisk (uae_u32 drive, uaecptr name) +static uae_u32 emulib_GetDisk(TrapContext *ctx, uae_u32 drive, uaecptr name) { - int i; - if (drive > 3) - return 0; + int i; + if (drive > 3) + return 0; - for (i = 0;i < 256; i++) { - put_byte (name + i, currprefs.floppyslots[drive].df[i]); - } - return 1; + for (i = 0; i < 256; i++) { + put_byte(name + i, currprefs.floppyslots[drive].df[i]); + } + return 1; } /* @@ -311,32 +311,104 @@ static uae_u32 emulib_Minimize (void) return 0; // OSDEP_minimize_uae(); } -static int native_dos_op (uae_u32 mode, uae_u32 p1, uae_u32 p2, uae_u32 p3) +static int native_dos_op(TrapContext *ctx, uae_u32 mode, uae_u32 p1, uae_u32 p2, uae_u32 p3) { - TCHAR tmp[MAX_DPATH]; + TCHAR tmp[MAX_DPATH]; char *s; - int v, i; + int v, i; - if (mode) - return -1; - /* receive native path from lock - * p1 = dos.library:Lock, p2 = buffer, p3 = max buffer size - */ - v = get_native_path (p1, tmp); - if (v) - return v; - s = ua (tmp); - for (i = 0; i <= strlen (s) && i < p3 - 1; i++) { - put_byte (p2 + i, s[i]); - put_byte (p2 + i + 1, 0); - } - xfree (s); - return 0; + if (mode) + return -1; + /* receive native path from lock + * p1 = dos.library:Lock, p2 = buffer, p3 = max buffer size + */ + v = get_native_path(p1, tmp); + if (v) + return v; + s = ua(tmp); + for (i = 0; i <= strlen(s) && i < p3 - 1; i++) { + put_byte(p2 + i, s[i]); + put_byte(p2 + i + 1, 0); + } + xfree(s); + return 0; } extern uae_u32 picasso_demux (uae_u32 arg, TrapContext *context); -static uae_u32 REGPARAM2 uaelib_demux2 (TrapContext *context) +static uae_u32 uaelib_demux_common(TrapContext *ctx, uae_u32 ARG0, uae_u32 ARG1, uae_u32 ARG2, uae_u32 ARG3, uae_u32 ARG4, uae_u32 ARG5) +{ + switch (ARG0) { + case 0: return emulib_GetVersion(); + case 1: return emulib_GetUaeConfig(ctx, ARG1); + case 2: return emulib_SetUaeConfig(ARG1); + case 3: return emulib_HardReset(); + case 4: return emulib_Reset(); + case 5: return emulib_InsertDisk(ctx, ARG1, ARG2); + case 6: return emulib_EnableSound(ARG1); + case 7: return emulib_EnableJoystick(ARG1); + case 8: return emulib_SetFrameRate(ARG1); + case 9: return emulib_ChgCMemSize(ctx, ARG1); + case 10: return emulib_ChgSMemSize(ctx, ARG1); + case 11: return emulib_ChgFMemSize(ctx, ARG1); + case 12: return emulib_ChangeLanguage(ARG1); + /* The next call brings bad luck */ + case 13: return emulib_ExitEmu(); + case 14: return emulib_GetDisk(ctx, ARG1, ARG2); + case 15: return emulib_Debug(); + + case 68: return emulib_Minimize(); + case 69: return emulib_ExecuteNativeCode(); + + case 70: return 0; /* RESERVED. Something uses this.. */ + + case 80: + if (!currprefs.maprom) + return 0xffffffff; + /* Disable possible ROM protection */ + //unprotect_maprom(); + return currprefs.maprom; + case 81: return cfgfile_uaelib(ctx, ARG1, ARG2, ARG3, ARG4); + case 82: return cfgfile_uaelib_modify(ctx, ARG1, ARG2, ARG3, ARG4, ARG5); + case 83: currprefs.mmkeyboard = ARG1 ? 1 : 0; return currprefs.mmkeyboard; +#ifdef DEBUGGER + case 84: return mmu_init(ARG1, ARG2, ARG3); +#endif + case 85: return native_dos_op(ctx, ARG1, ARG2, ARG3, ARG4); + case 86: + if (valid_address(ARG1, 1)) { + TCHAR *s = au((char*)get_real_address(ARG1)); + write_log(_T("DBG: %s\n"), s); + xfree(s); + return 1; + } + return 0; + case 87: + { + uae_u32 d0, d1; + d0 = emulib_target_getcpurate(ARG1, &d1); + m68k_dreg(regs, 1) = d1; + return d0; + } + + } + return 0; +} + +uae_u32 uaeboard_demux(uae_u32 *board) +{ + uae_u32 arg0, arg1, arg2, arg3, arg4, arg5; + + arg0 = do_get_mem_word((uae_u16*)&board[0]); + arg1 = do_get_mem_long(&board[2]); + arg2 = do_get_mem_long(&board[3]); + arg3 = do_get_mem_long(&board[4]); + arg4 = do_get_mem_long(&board[5]); + arg5 = do_get_mem_long(&board[6]); + return uaelib_demux_common(NULL, arg0, arg1, arg2, arg3, arg4, arg5); +} + +static uae_u32 REGPARAM2 uaelib_demux2(TrapContext *ctx) { #define ARG0 (get_long (m68k_areg (regs, 7) + 4)) #define ARG1 (get_long (m68k_areg (regs, 7) + 8)) @@ -347,60 +419,9 @@ static uae_u32 REGPARAM2 uaelib_demux2 (TrapContext *context) #ifdef PICASSO96 if (ARG0 >= 16 && ARG0 <= 39) - return picasso_demux (ARG0, context); + return picasso_demux(ARG0, ctx); #endif - - switch (ARG0) - { - case 0: return emulib_GetVersion (); - case 1: return emulib_GetUaeConfig (ARG1); - case 2: return emulib_SetUaeConfig (ARG1); - case 3: return emulib_HardReset (); - case 4: return emulib_Reset (); - case 5: return emulib_InsertDisk (ARG1, ARG2); - case 6: return emulib_EnableSound (ARG1); - case 7: return emulib_EnableJoystick (ARG1); - case 8: return emulib_SetFrameRate (ARG1); - case 9: return emulib_ChgCMemSize (ARG1); - case 10: return emulib_ChgSMemSize (ARG1); - case 11: return emulib_ChgFMemSize (ARG1); - case 12: return emulib_ChangeLanguage (ARG1); - /* The next call brings bad luck */ - case 13: return emulib_ExitEmu (); - case 14: return emulib_GetDisk (ARG1, ARG2); - case 15: return emulib_Debug (); - - case 68: return emulib_Minimize (); - case 69: return emulib_ExecuteNativeCode (); - - case 70: return 0; /* RESERVED. Something uses this.. */ - - case 80: - return 0xffffffff; - case 81: return cfgfile_uaelib (ARG1, ARG2, ARG3, ARG4); - case 82: return cfgfile_uaelib_modify (ARG1, ARG2, ARG3, ARG4, ARG5); - case 83: return 0; -#ifdef DEBUGGER - case 84: return mmu_init (ARG1, ARG2, ARG3); -#endif - case 85: return native_dos_op (ARG1, ARG2, ARG3, ARG4); - case 86: - if (valid_address(ARG1, 1)) { - TCHAR *s = au ((char*)get_real_address (ARG1)); - write_log (_T("DBG: %s\n"), s); - xfree (s); - return 1; - } - return 0; - case 87: - { - uae_u32 d0, d1; - d0 = emulib_target_getcpurate (ARG1, &d1); - m68k_dreg (regs, 1) = d1; - return d0; - } - } - return 0; + return uaelib_demux_common(ctx, ARG0, ARG1, ARG2, ARG3, ARG4, ARG5); } static uae_u32 REGPARAM2 uaelib_demux (TrapContext *context) @@ -417,8 +438,8 @@ static uae_u32 REGPARAM2 uaelib_demux (TrapContext *context) void emulib_install (void) { uaecptr a; - if (!uae_boot_rom) - return; + if (!uae_boot_rom_type) + return; a = here (); org (rtarea_base + 0xFF60); #if 0 From 4549cf6d0cd9c16af26c590858ddfb2231e46203 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 30 Mar 2017 21:45:03 +0200 Subject: [PATCH 02/11] Updated README for development branch --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 903b0fcc..2740994c 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ Amiga emulator for the Raspberry Pi ================================= -Warning: this branch is still Work In Progress - it requires a few extra steps to build and some things may not be finished yet! :) -If you're looking for the latest "stable" version, please use the master branch for now. -Once this branch is complete, it will be merged back to the master and replace it. +WARNING: Experimental, unstable, development branch. +Stuff here will most probably break at some places. Don't bother reporting bugs! # History (newest first) +- Updated drawing, custom, events and a few other parts from WinUAE 3.4.1 - Added GPerfTools for profiling and optimized malloc functions (note: this adds 2 extra dependencies, check below) - Added an option for choosing Scaling Method (for non-Picasso modes): Auto, Nearest Neighbor (pixelated) or Linear (smooth). Auto will automatically choose between the other two modes on the fly, depending on the Amiga resolution requested and if the native monitor resolution can display it as an exact multiple or not. This vastly improves the sharpness of the resulting image. - Improved image centering (for non-Picasso modes) From 419cd5592d9107a65ea6376bf750ecd97326dffd Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 30 Mar 2017 23:00:20 +0200 Subject: [PATCH 03/11] Reworked VSLinux solution, added Guisan project Moved 7z/Archive/7z files to 7z/ folder for simplicity --- .vs/ProjectSettings.json | 3 + .vs/VSWorkspaceState.json | 7 + Makefile | 12 +- VSLinux/Amiberry.sln | 39 +- VSLinux/Amiberry.vcxproj | 503 +++++-- VSLinux/Amiberry.vcxproj.filters | 1165 ++++++++++++----- VSLinux/Amiberry.vcxproj.user | 2 +- VSLinux/guisan/guisan.vcxproj | 199 +++ VSLinux/guisan/guisan.vcxproj.filters | 383 ++++++ VSLinux/guisan/guisan.vcxproj.user | 4 + .../-451911409.CopySourcesUpToDateFile.tlog | 115 ++ .../-451911409.Local_Remote_PathMapping.tlog | 126 ++ .../-451911409.RemoteProjectDirFile.tlog | 1 + VisualGDB/Amiberry/Amiberry.vcxproj | 24 +- VisualGDB/Amiberry/Amiberry.vcxproj.filters | 174 ++- src/archivers/7z/{Archive/7z => }/7zAlloc.cpp | 0 src/archivers/7z/{Archive/7z => }/7zAlloc.h | 0 .../7z/{Archive/7z => }/7zDecode.cpp | 0 src/archivers/7z/{Archive/7z => }/7zDecode.h | 0 .../7z/{Archive/7z => }/7zExtract.cpp | 0 src/archivers/7z/{Archive/7z => }/7zExtract.h | 0 .../7z/{Archive/7z => }/7zHeader.cpp | 0 src/archivers/7z/{Archive/7z => }/7zHeader.h | 0 src/archivers/7z/{Archive/7z => }/7zIn.cpp | 0 src/archivers/7z/{Archive/7z => }/7zIn.h | 0 src/archivers/7z/{Archive/7z => }/7zItem.cpp | 0 src/archivers/7z/{Archive/7z => }/7zItem.h | 0 src/guisan/Makefile | 2 +- 28 files changed, 2240 insertions(+), 519 deletions(-) create mode 100644 .vs/ProjectSettings.json create mode 100644 .vs/VSWorkspaceState.json create mode 100644 VSLinux/guisan/guisan.vcxproj create mode 100644 VSLinux/guisan/guisan.vcxproj.filters create mode 100644 VSLinux/guisan/guisan.vcxproj.user create mode 100644 VSLinux/guisan/obj/ARM/Debug/-451911409.CopySourcesUpToDateFile.tlog create mode 100644 VSLinux/guisan/obj/ARM/Debug/-451911409.Local_Remote_PathMapping.tlog create mode 100644 VSLinux/guisan/obj/ARM/Debug/-451911409.RemoteProjectDirFile.tlog rename src/archivers/7z/{Archive/7z => }/7zAlloc.cpp (100%) rename src/archivers/7z/{Archive/7z => }/7zAlloc.h (100%) rename src/archivers/7z/{Archive/7z => }/7zDecode.cpp (100%) rename src/archivers/7z/{Archive/7z => }/7zDecode.h (100%) rename src/archivers/7z/{Archive/7z => }/7zExtract.cpp (100%) rename src/archivers/7z/{Archive/7z => }/7zExtract.h (100%) rename src/archivers/7z/{Archive/7z => }/7zHeader.cpp (100%) rename src/archivers/7z/{Archive/7z => }/7zHeader.h (100%) rename src/archivers/7z/{Archive/7z => }/7zIn.cpp (100%) rename src/archivers/7z/{Archive/7z => }/7zIn.h (100%) rename src/archivers/7z/{Archive/7z => }/7zItem.cpp (100%) rename src/archivers/7z/{Archive/7z => }/7zItem.h (100%) diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json new file mode 100644 index 00000000..f8b48885 --- /dev/null +++ b/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": null +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 00000000..39bc0a78 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,7 @@ +{ + "ExpandedNodes": [ + "" + ], + "SelectedNode": "\\Makefile", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/Makefile b/Makefile index 585e0af3..4d39ffb7 100644 --- a/Makefile +++ b/Makefile @@ -97,12 +97,12 @@ OBJS = \ src/uaeresource.o \ src/zfile.o \ src/zfile_archive.o \ - src/archivers/7z/Archive/7z/7zAlloc.o \ - src/archivers/7z/Archive/7z/7zDecode.o \ - src/archivers/7z/Archive/7z/7zExtract.o \ - src/archivers/7z/Archive/7z/7zHeader.o \ - src/archivers/7z/Archive/7z/7zIn.o \ - src/archivers/7z/Archive/7z/7zItem.o \ + src/archivers/7z/7zAlloc.o \ + src/archivers/7z/7zDecode.o \ + src/archivers/7z/7zExtract.o \ + src/archivers/7z/7zHeader.o \ + src/archivers/7z/7zIn.o \ + src/archivers/7z/7zItem.o \ src/archivers/7z/7zBuf.o \ src/archivers/7z/7zCrc.o \ src/archivers/7z/7zStream.o \ diff --git a/VSLinux/Amiberry.sln b/VSLinux/Amiberry.sln index ce389562..e3678a84 100644 --- a/VSLinux/Amiberry.sln +++ b/VSLinux/Amiberry.sln @@ -1,20 +1,45 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.10 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Amiberry", "Amiberry.vcxproj", "{FDB65B17-494A-4248-9F05-B527D4EA15DF}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Amiberry", "Amiberry.vcxproj", "{7B9A67B2-3F13-4E7B-A875-AAB6CAAE63D7}" + ProjectSection(ProjectDependencies) = postProject + {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD} = {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "guisan", "guisan\guisan.vcxproj", "{06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {FDB65B17-494A-4248-9F05-B527D4EA15DF}.Debug|ARM.ActiveCfg = Debug|ARM - {FDB65B17-494A-4248-9F05-B527D4EA15DF}.Debug|ARM.Build.0 = Debug|ARM - {FDB65B17-494A-4248-9F05-B527D4EA15DF}.Release|ARM.ActiveCfg = Release|ARM - {FDB65B17-494A-4248-9F05-B527D4EA15DF}.Release|ARM.Build.0 = Release|ARM + {7B9A67B2-3F13-4E7B-A875-AAB6CAAE63D7}.Debug|ARM.ActiveCfg = Debug|ARM + {7B9A67B2-3F13-4E7B-A875-AAB6CAAE63D7}.Debug|ARM.Build.0 = Debug|ARM + {7B9A67B2-3F13-4E7B-A875-AAB6CAAE63D7}.Debug|x64.ActiveCfg = Debug|ARM + {7B9A67B2-3F13-4E7B-A875-AAB6CAAE63D7}.Debug|x86.ActiveCfg = Debug|ARM + {7B9A67B2-3F13-4E7B-A875-AAB6CAAE63D7}.Release|ARM.ActiveCfg = Release|ARM + {7B9A67B2-3F13-4E7B-A875-AAB6CAAE63D7}.Release|ARM.Build.0 = Release|ARM + {7B9A67B2-3F13-4E7B-A875-AAB6CAAE63D7}.Release|x64.ActiveCfg = Release|ARM + {7B9A67B2-3F13-4E7B-A875-AAB6CAAE63D7}.Release|x86.ActiveCfg = Release|ARM + {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD}.Debug|ARM.ActiveCfg = Debug|ARM + {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD}.Debug|ARM.Build.0 = Debug|ARM + {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD}.Debug|x64.ActiveCfg = Debug|x64 + {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD}.Debug|x64.Build.0 = Debug|x64 + {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD}.Debug|x86.ActiveCfg = Debug|x86 + {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD}.Debug|x86.Build.0 = Debug|x86 + {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD}.Release|ARM.ActiveCfg = Release|ARM + {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD}.Release|ARM.Build.0 = Release|ARM + {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD}.Release|x64.ActiveCfg = Release|x64 + {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD}.Release|x64.Build.0 = Release|x64 + {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD}.Release|x86.ActiveCfg = Release|x86 + {06B356E1-FE8B-4E50-BF9F-A9D6E419ECBD}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/VSLinux/Amiberry.vcxproj b/VSLinux/Amiberry.vcxproj index 6d291813..d7348f90 100644 --- a/VSLinux/Amiberry.vcxproj +++ b/VSLinux/Amiberry.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -9,51 +9,41 @@ Release ARM - - Debug - x86 - - - Release - x86 - - - Debug - x64 - - - Release - x64 - - {fdb65b17-494a-4248-9f05-b527d4ea15df} + {7b9a67b2-3f13-4e7b-a875-aab6caae63d7} Linux Amiberry - 14.0 + 15.0 Linux 1.0 Generic - {2238F9CD-F817-4ECC-BD14-2524D2669B35} + {FC1A4D80-50E9-41DA-9192-61C0DBAA00D2} true + Makefile false + Makefile true + Makefile false + Makefile true + Makefile false + Makefile @@ -61,16 +51,102 @@ - + + true + + + true + + + true + + + true + + + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + + + true + + + + + true + + + true + + + true + + + + true + + + + + false + + + + + + + - - - - - - @@ -100,57 +176,163 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + + - - + + + false + + + false + - - - - - + + false + + + false + + + false + + + false + + + false + + + + + + + + @@ -174,7 +356,6 @@ - @@ -183,39 +364,163 @@ - - + + - - - - - - - - - - - - + + false + + + false + + + false + + + false + + + false + + - - - - - - - + + false + + + false + + + false + + + false + + + false + + + false + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VSLinux/Amiberry.vcxproj.filters b/VSLinux/Amiberry.vcxproj.filters index 9720ee10..52f036d1 100644 --- a/VSLinux/Amiberry.vcxproj.filters +++ b/VSLinux/Amiberry.vcxproj.filters @@ -1,389 +1,954 @@  - - {49228265-161c-4a81-bb34-c4b3c5dce9c1} + + {253280e9-c935-41d3-8e4e-39ebc63802f0} - - {20f71c16-162f-4d26-aae7-b3f1bc9d1c9d} + + {53c88284-1055-4c1c-a230-f658b82872e8} - - {7c08ca58-13a9-43ec-9b0e-232a5ebd5f87} + + {beb24d9f-04b4-4ff7-a648-2810307c1d90} - - {526ae108-f94b-4747-9119-f77731c5880c} + + {90bb891e-7895-46e0-9a58-4fc315cfee05} - - {50ad2909-799e-4fb0-978f-579fe69ffe66} + + {ccc27a70-d842-434a-806a-2c82270a3626} - - {f7746b1b-45f2-4042-91f9-38620ffd2c0f} + + {18906c9e-7036-435e-b58b-e4e5c06bd8ae} - - {66f33547-0e09-45ff-ad9c-fc5dec3c613a} + + {2199a572-d5d5-4cd2-b104-f4ba6d84b67c} - - {11f31a8d-4d98-4392-98d8-78f3d43c78e3} + + {2c69437c-7427-4286-911b-2ffed55d3419} - - {56baa296-792f-4f0a-b0de-995c05f6ab1c} + + {bc0781c0-e25a-40e5-8352-91325353b9c6} - - {2aba86dc-7b9a-49aa-b8c4-23be34727118} + + {5aa6adea-6b4a-421f-85b7-3d991e692797} - - {54f7095b-0cae-44e1-8934-46d9687c8aa7} + + {c9e8ab77-3764-441d-b860-ac4bafac403f} - - {45071947-9292-477a-a961-aa5389141134} + + {9e28e271-aba8-4259-9080-15cbb0f84c06} - - {47c15abb-07dc-4489-9434-a2bc09f958fa} + + {9262078c-316d-4975-a594-63d1b48e0fe1} - - {c6d41834-f403-43fe-91c4-f661765ccacd} + + {8d279526-2cc8-4ce5-a4ca-9e528419e925} - - {17cf9b08-84bf-46dd-b5de-a789af5c2224} + + {f3850bab-03d2-4fd0-9a0d-25388878f5f4} + + + {2bcd8c2b-b029-428e-b2b6-8347eadb5199} + + + {f0713680-4f05-45d8-b1d4-ea24d1305970} + + + {b25f6ac8-afcb-45b8-a0fc-f0bc1c88fba1} + + + {32996091-d9d9-437f-8338-e15198404b91} + + + {767f436f-8275-4c9f-abf9-a880ba80c1f2} + + + {ef3ace82-28e8-45cc-9b49-b6b712e33cd4} - - jit + + conf + + + kickstarts + + + savestates + + + screenshots + + + + + data + + + data + + + data + + + data + + + data + + + data + + + data + + + data + + + data + + + data + + + data + + + data + + + data + + + data + + + data + + + data + + + + + data + + + + + + src + + + src + + + src + + + src\osdep + + + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src - - jit + + src - - jit + + src - - jit + + src - - machdep + + src - - sounddep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep + + src - - osdep\menu + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui + + src - - osdep\gui - - - osdep\gui - - - osdep\gui - - - osdep\gui - - - osdep\gui - - - osdep\gui - - - osdep\gui - - - osdep\gui - - - archivers\zip - - - archivers\wrp - - - archivers\lzx - - - archivers\lha - - - archivers\lha - - - archivers\lha - - - archivers\lha - - - archivers\lha - - - archivers\lha - - - archivers\lha - - - archivers\lha - - - archivers\lha - - - archivers\lha - - - archivers\lha - - - archivers\dms - - - archivers\dms - - - archivers\dms - - - archivers\dms - - - archivers\dms - - - archivers\dms - - - archivers\dms - - - archivers\dms - - - archivers\dms - - - archivers\dms - - - archivers\dms + + src\archivers\7z - archivers\7z + src\archivers\7z - archivers\7z + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z - archivers\7z + src\archivers\7z - archivers\7z + src\archivers\7z - archivers\7z + src\archivers\7z - archivers\7z + src\archivers\7z - archivers\7z + src\archivers\7z - - archivers\7z\Archive\7z + + src\archivers\dms - - archivers\7z\Archive\7z + + src\archivers\dms - - archivers\7z\Archive\7z + + src\archivers\dms - - archivers\7z\Archive\7z + + src\archivers\dms - - archivers\7z\Archive\7z + + src\archivers\dms - - archivers\7z\Archive\7z + + src\archivers\dms - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - osdep + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\lha + + + src\archivers\lha + + + src\archivers\lha + + + src\archivers\lha + + + src\archivers\lha + + + src\archivers\lha + + + src\archivers\lha + + + src\archivers\lha + + + src\archivers\lha + + + src\archivers\lha + + + src\archivers\lha + + + src\archivers\lzx + + + src\archivers\wrp + + + src\archivers\zip + + + src\jit + + + src\jit + + + src\jit + + + src\jit + + + src\jit + + + src\jit + + + src\jit + + + src\jit + + + src\machdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\menu + + + src\sounddep + + + src\sounddep - - osdep - - - - + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\7z + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\dms + + + src\archivers\lha + + + src\archivers\lha + + + src\archivers\wrp + + + src\archivers\zip + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\include + + + src\jit + + + src\jit + + + src\jit + + + src\jit + + + src\jit + + + src\machdep + + + src\machdep + + + src\machdep + + + src\machdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\osdep\gui + + + src\sounddep + + + src\threaddep + \ No newline at end of file diff --git a/VSLinux/Amiberry.vcxproj.user b/VSLinux/Amiberry.vcxproj.user index abe8dd89..be250787 100644 --- a/VSLinux/Amiberry.vcxproj.user +++ b/VSLinux/Amiberry.vcxproj.user @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/VSLinux/guisan/guisan.vcxproj b/VSLinux/guisan/guisan.vcxproj new file mode 100644 index 00000000..0d604281 --- /dev/null +++ b/VSLinux/guisan/guisan.vcxproj @@ -0,0 +1,199 @@ + + + + + Debug + ARM + + + Release + ARM + + + Debug + x86 + + + Release + x86 + + + Debug + x64 + + + Release + x64 + + + + {06b356e1-fe8b-4e50-bf9f-a9d6e419ecbd} + Linux + guisan + 15.0 + Linux + 1.0 + Generic + {FC1A4D80-50E9-41DA-9192-61C0DBAA00D2} + + + + true + Makefile + + + false + Makefile + + + true + Makefile + + + false + Makefile + + + true + Makefile + + + false + Makefile + + + + + + + + cd ~/projects/guisan/; make all + cd ~/projects/guisan/; make clean + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VSLinux/guisan/guisan.vcxproj.filters b/VSLinux/guisan/guisan.vcxproj.filters new file mode 100644 index 00000000..5c660da6 --- /dev/null +++ b/VSLinux/guisan/guisan.vcxproj.filters @@ -0,0 +1,383 @@ + + + + + {eeccf75c-d704-4a8b-9282-f083ba4283a7} + + + {7f295f07-15f7-4000-81ea-c83f4ca91ca7} + + + {0ae8cfa1-0e8f-4a72-9ea2-f8c1fc9b8970} + + + {27c19eef-8ca1-41c3-a0b5-ef0f16bde5a7} + + + {5fa33cfa-ffca-4f07-b5ca-3fca6db3dc91} + + + {5227ba91-51a7-4209-9121-03505fdb08fc} + + + {6248903a-d143-48ca-b3e9-48692f78ec08} + + + {aee8cc37-3791-4194-98db-09124b276380} + + + {4542cfd7-c089-47ed-825c-f4c219c7f45b} + + + {52b5b3c9-6832-454a-b245-039fb824f16f} + + + + + lib + + + + + include + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan + + + include\guisan\opengl + + + include\guisan\opengl + + + include\guisan\opengl + + + include\guisan\sdl + + + include\guisan\sdl + + + include\guisan\sdl + + + include\guisan\sdl + + + include\guisan\sdl + + + include\guisan\sdl + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + include\guisan\widgets + + + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src\opengl + + + src\opengl + + + src\opengl + + + src\sdl + + + src\sdl + + + src\sdl + + + src\sdl + + + src\sdl + + + src\sdl + + + src\widgets + + + src\widgets + + + src\widgets + + + src\widgets + + + src\widgets + + + src\widgets + + + src\widgets + + + src\widgets + + + src\widgets + + + src\widgets + + + src\widgets + + + src\widgets + + + src\widgets + + + src\widgets + + + src\widgets + + + src\widgets + + + \ No newline at end of file diff --git a/VSLinux/guisan/guisan.vcxproj.user b/VSLinux/guisan/guisan.vcxproj.user new file mode 100644 index 00000000..be250787 --- /dev/null +++ b/VSLinux/guisan/guisan.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/VSLinux/guisan/obj/ARM/Debug/-451911409.CopySourcesUpToDateFile.tlog b/VSLinux/guisan/obj/ARM/Debug/-451911409.CopySourcesUpToDateFile.tlog new file mode 100644 index 00000000..5af2ec89 --- /dev/null +++ b/VSLinux/guisan/obj/ARM/Debug/-451911409.CopySourcesUpToDateFile.tlog @@ -0,0 +1,115 @@ +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\actionevent.cpp|636253888575313789|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\basiccontainer.cpp|636253888575318791|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\cliprectangle.cpp|636253888575323805|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\color.cpp|636253888575328544|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\defaultfont.cpp|636253888575328544|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\event.cpp|636253888575328544|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\exception.cpp|636253888575337940|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\focushandler.cpp|636253888575342974|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\font.cpp|636253888575342974|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\genericinput.cpp|636253888575347982|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\graphics.cpp|636253888575463197|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\gui.cpp|636253888575467247|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\guisan.cpp|636253888575472254|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\image.cpp|636253888575477265|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\imagefont.cpp|636253888575477265|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\inputevent.cpp|636253888575482276|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\key.cpp|636253888575487281|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\keyevent.cpp|636253888575491193|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\keyinput.cpp|636253888575491193|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\mouseevent.cpp|636253888575491193|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\mouseinput.cpp|636253888575501212|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl\opengl.cpp|636253888575501212|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl\openglgraphics.cpp|636253888575501212|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl\openglimage.cpp|636253888575511213|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\rectangle.cpp|636253888575511213|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdl.cpp|636253888575521214|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlgraphics.cpp|636253888575521214|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlimage.cpp|636253888575531216|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlimageloader.cpp|636253888575531216|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlinput.cpp|636253888575531216|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdltruetypefont.cpp|636253888575541243|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\selectionevent.cpp|636253888575541243|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widget.cpp|636253888575541243|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\button.cpp|636253888575551221|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\checkbox.cpp|636253888575551221|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\container.cpp|636253888575551221|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\dropdown.cpp|636253888575561226|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\icon.cpp|636253888575561226|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\imagebutton.cpp|636253888575561226|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\label.cpp|636253888575571224|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\listbox.cpp|636253888575581228|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\radiobutton.cpp|636253888575581228|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\scrollarea.cpp|636253888575581228|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\slider.cpp|636253888575591230|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\tab.cpp|636253888575591230|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\tabbedarea.cpp|636253888575591230|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\textbox.cpp|636253888575601231|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\textfield.cpp|636253888575606490|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\window.cpp|636253888575606490|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan.hpp|636253888574873009|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\actionevent.hpp|636253888574883010|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\actionlistener.hpp|636253888575008037|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\basiccontainer.hpp|636253888575018017|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\cliprectangle.hpp|636253888575018017|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\color.hpp|636253888575018017|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\deathlistener.hpp|636253888575028025|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\defaultfont.hpp|636253888575028025|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\event.hpp|636253888575038017|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\exception.hpp|636253888575038017|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\focushandler.hpp|636253888575038017|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\focuslistener.hpp|636253888575048024|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\font.hpp|636253888575048024|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\genericinput.hpp|636253888575048024|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\glut.hpp|636253888575048024|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\graphics.hpp|636253888575058020|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\gui.hpp|636253888575058020|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\image.hpp|636253888575058020|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\imagefont.hpp|636253888575068030|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\imageloader.hpp|636253888575068030|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\input.hpp|636253888575068030|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\inputevent.hpp|636253888575068030|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\key.hpp|636253888575078025|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\keyevent.hpp|636253888575078025|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\keyinput.hpp|636253888575078025|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\keylistener.hpp|636253888575088027|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\listmodel.hpp|636253888575088027|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\mouseevent.hpp|636253888575088027|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\mouseinput.hpp|636253888575088027|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\mouselistener.hpp|636253888575098034|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl.hpp|636253888575098034|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl\openglgraphics.hpp|636253888575098034|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl\openglimage.hpp|636253888575108038|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl\openglsdlimageloader.hpp|636253888575108038|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\platform.hpp|636253888575108038|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\rectangle.hpp|636253888575198065|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl.hpp|636253888575198065|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlgraphics.hpp|636253888575207964|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlimage.hpp|636253888575207964|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlimageloader.hpp|636253888575217980|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlinput.hpp|636253888575217980|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlpixel.hpp|636253888575217980|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdltruetypefont.hpp|636253888575227981|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\selectionevent.hpp|636253888575227981|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\selectionlistener.hpp|636253888575237965|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widget.hpp|636253888575237965|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgetlistener.hpp|636253888575237965|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\button.hpp|636253888575247975|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\checkbox.hpp|636253888575247975|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\container.hpp|636253888575257973|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\dropdown.hpp|636253888575257973|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\icon.hpp|636253888575257973|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\imagebutton.hpp|636253888575267989|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\label.hpp|636253888575267989|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\listbox.hpp|636253888575277979|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\radiobutton.hpp|636253888575277979|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\scrollarea.hpp|636253888575277979|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\slider.hpp|636253888575287980|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\tab.hpp|636253888575287980|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\tabbedarea.hpp|636253888575297978|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\textbox.hpp|636253888575297978|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\textfield.hpp|636253888575303755|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\window.hpp|636253888575308787|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\x.hpp|636253888575308787|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\lib\.keep|636253888575308787|~/projects/guisan| +D:\midwa\Projects\GitHub\amiberry\src\guisan\Makefile|636265107573980514|~/projects/guisan| diff --git a/VSLinux/guisan/obj/ARM/Debug/-451911409.Local_Remote_PathMapping.tlog b/VSLinux/guisan/obj/ARM/Debug/-451911409.Local_Remote_PathMapping.tlog new file mode 100644 index 00000000..031a4c56 --- /dev/null +++ b/VSLinux/guisan/obj/ARM/Debug/-451911409.Local_Remote_PathMapping.tlog @@ -0,0 +1,126 @@ +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\actionevent.cpp|/home/pi/projects/guisan/src/actionevent.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src|/home/pi/projects/guisan/src +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\basiccontainer.cpp|/home/pi/projects/guisan/src/basiccontainer.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\cliprectangle.cpp|/home/pi/projects/guisan/src/cliprectangle.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\color.cpp|/home/pi/projects/guisan/src/color.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\defaultfont.cpp|/home/pi/projects/guisan/src/defaultfont.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\event.cpp|/home/pi/projects/guisan/src/event.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\exception.cpp|/home/pi/projects/guisan/src/exception.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\focushandler.cpp|/home/pi/projects/guisan/src/focushandler.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\font.cpp|/home/pi/projects/guisan/src/font.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\genericinput.cpp|/home/pi/projects/guisan/src/genericinput.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\graphics.cpp|/home/pi/projects/guisan/src/graphics.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\gui.cpp|/home/pi/projects/guisan/src/gui.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\guisan.cpp|/home/pi/projects/guisan/src/guisan.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\image.cpp|/home/pi/projects/guisan/src/image.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\imagefont.cpp|/home/pi/projects/guisan/src/imagefont.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\inputevent.cpp|/home/pi/projects/guisan/src/inputevent.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\key.cpp|/home/pi/projects/guisan/src/key.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\keyevent.cpp|/home/pi/projects/guisan/src/keyevent.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\keyinput.cpp|/home/pi/projects/guisan/src/keyinput.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\mouseevent.cpp|/home/pi/projects/guisan/src/mouseevent.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\mouseinput.cpp|/home/pi/projects/guisan/src/mouseinput.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl\opengl.cpp|/home/pi/projects/guisan/src/opengl/opengl.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl|/home/pi/projects/guisan/src/opengl +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl\openglgraphics.cpp|/home/pi/projects/guisan/src/opengl/openglgraphics.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl\openglimage.cpp|/home/pi/projects/guisan/src/opengl/openglimage.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\rectangle.cpp|/home/pi/projects/guisan/src/rectangle.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdl.cpp|/home/pi/projects/guisan/src/sdl/sdl.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl|/home/pi/projects/guisan/src/sdl +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlgraphics.cpp|/home/pi/projects/guisan/src/sdl/sdlgraphics.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlimage.cpp|/home/pi/projects/guisan/src/sdl/sdlimage.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlimageloader.cpp|/home/pi/projects/guisan/src/sdl/sdlimageloader.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlinput.cpp|/home/pi/projects/guisan/src/sdl/sdlinput.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdltruetypefont.cpp|/home/pi/projects/guisan/src/sdl/sdltruetypefont.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\selectionevent.cpp|/home/pi/projects/guisan/src/selectionevent.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widget.cpp|/home/pi/projects/guisan/src/widget.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\button.cpp|/home/pi/projects/guisan/src/widgets/button.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets|/home/pi/projects/guisan/src/widgets +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\checkbox.cpp|/home/pi/projects/guisan/src/widgets/checkbox.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\container.cpp|/home/pi/projects/guisan/src/widgets/container.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\dropdown.cpp|/home/pi/projects/guisan/src/widgets/dropdown.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\icon.cpp|/home/pi/projects/guisan/src/widgets/icon.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\imagebutton.cpp|/home/pi/projects/guisan/src/widgets/imagebutton.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\label.cpp|/home/pi/projects/guisan/src/widgets/label.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\listbox.cpp|/home/pi/projects/guisan/src/widgets/listbox.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\radiobutton.cpp|/home/pi/projects/guisan/src/widgets/radiobutton.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\scrollarea.cpp|/home/pi/projects/guisan/src/widgets/scrollarea.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\slider.cpp|/home/pi/projects/guisan/src/widgets/slider.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\tab.cpp|/home/pi/projects/guisan/src/widgets/tab.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\tabbedarea.cpp|/home/pi/projects/guisan/src/widgets/tabbedarea.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\textbox.cpp|/home/pi/projects/guisan/src/widgets/textbox.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\textfield.cpp|/home/pi/projects/guisan/src/widgets/textfield.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\window.cpp|/home/pi/projects/guisan/src/widgets/window.cpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan.hpp|/home/pi/projects/guisan/include/guisan.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include|/home/pi/projects/guisan/include +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\actionevent.hpp|/home/pi/projects/guisan/include/guisan/actionevent.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan|/home/pi/projects/guisan/include/guisan +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\actionlistener.hpp|/home/pi/projects/guisan/include/guisan/actionlistener.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\basiccontainer.hpp|/home/pi/projects/guisan/include/guisan/basiccontainer.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\cliprectangle.hpp|/home/pi/projects/guisan/include/guisan/cliprectangle.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\color.hpp|/home/pi/projects/guisan/include/guisan/color.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\deathlistener.hpp|/home/pi/projects/guisan/include/guisan/deathlistener.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\defaultfont.hpp|/home/pi/projects/guisan/include/guisan/defaultfont.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\event.hpp|/home/pi/projects/guisan/include/guisan/event.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\exception.hpp|/home/pi/projects/guisan/include/guisan/exception.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\focushandler.hpp|/home/pi/projects/guisan/include/guisan/focushandler.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\focuslistener.hpp|/home/pi/projects/guisan/include/guisan/focuslistener.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\font.hpp|/home/pi/projects/guisan/include/guisan/font.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\genericinput.hpp|/home/pi/projects/guisan/include/guisan/genericinput.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\glut.hpp|/home/pi/projects/guisan/include/guisan/glut.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\graphics.hpp|/home/pi/projects/guisan/include/guisan/graphics.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\gui.hpp|/home/pi/projects/guisan/include/guisan/gui.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\image.hpp|/home/pi/projects/guisan/include/guisan/image.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\imagefont.hpp|/home/pi/projects/guisan/include/guisan/imagefont.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\imageloader.hpp|/home/pi/projects/guisan/include/guisan/imageloader.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\input.hpp|/home/pi/projects/guisan/include/guisan/input.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\inputevent.hpp|/home/pi/projects/guisan/include/guisan/inputevent.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\key.hpp|/home/pi/projects/guisan/include/guisan/key.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\keyevent.hpp|/home/pi/projects/guisan/include/guisan/keyevent.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\keyinput.hpp|/home/pi/projects/guisan/include/guisan/keyinput.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\keylistener.hpp|/home/pi/projects/guisan/include/guisan/keylistener.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\listmodel.hpp|/home/pi/projects/guisan/include/guisan/listmodel.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\mouseevent.hpp|/home/pi/projects/guisan/include/guisan/mouseevent.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\mouseinput.hpp|/home/pi/projects/guisan/include/guisan/mouseinput.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\mouselistener.hpp|/home/pi/projects/guisan/include/guisan/mouselistener.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl.hpp|/home/pi/projects/guisan/include/guisan/opengl.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl\openglgraphics.hpp|/home/pi/projects/guisan/include/guisan/opengl/openglgraphics.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl|/home/pi/projects/guisan/include/guisan/opengl +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl\openglimage.hpp|/home/pi/projects/guisan/include/guisan/opengl/openglimage.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl\openglsdlimageloader.hpp|/home/pi/projects/guisan/include/guisan/opengl/openglsdlimageloader.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\platform.hpp|/home/pi/projects/guisan/include/guisan/platform.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\rectangle.hpp|/home/pi/projects/guisan/include/guisan/rectangle.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl.hpp|/home/pi/projects/guisan/include/guisan/sdl.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlgraphics.hpp|/home/pi/projects/guisan/include/guisan/sdl/sdlgraphics.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl|/home/pi/projects/guisan/include/guisan/sdl +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlimage.hpp|/home/pi/projects/guisan/include/guisan/sdl/sdlimage.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlimageloader.hpp|/home/pi/projects/guisan/include/guisan/sdl/sdlimageloader.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlinput.hpp|/home/pi/projects/guisan/include/guisan/sdl/sdlinput.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlpixel.hpp|/home/pi/projects/guisan/include/guisan/sdl/sdlpixel.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdltruetypefont.hpp|/home/pi/projects/guisan/include/guisan/sdl/sdltruetypefont.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\selectionevent.hpp|/home/pi/projects/guisan/include/guisan/selectionevent.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\selectionlistener.hpp|/home/pi/projects/guisan/include/guisan/selectionlistener.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widget.hpp|/home/pi/projects/guisan/include/guisan/widget.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgetlistener.hpp|/home/pi/projects/guisan/include/guisan/widgetlistener.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\button.hpp|/home/pi/projects/guisan/include/guisan/widgets/button.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets|/home/pi/projects/guisan/include/guisan/widgets +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\checkbox.hpp|/home/pi/projects/guisan/include/guisan/widgets/checkbox.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\container.hpp|/home/pi/projects/guisan/include/guisan/widgets/container.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\dropdown.hpp|/home/pi/projects/guisan/include/guisan/widgets/dropdown.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\icon.hpp|/home/pi/projects/guisan/include/guisan/widgets/icon.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\imagebutton.hpp|/home/pi/projects/guisan/include/guisan/widgets/imagebutton.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\label.hpp|/home/pi/projects/guisan/include/guisan/widgets/label.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\listbox.hpp|/home/pi/projects/guisan/include/guisan/widgets/listbox.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\radiobutton.hpp|/home/pi/projects/guisan/include/guisan/widgets/radiobutton.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\scrollarea.hpp|/home/pi/projects/guisan/include/guisan/widgets/scrollarea.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\slider.hpp|/home/pi/projects/guisan/include/guisan/widgets/slider.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\tab.hpp|/home/pi/projects/guisan/include/guisan/widgets/tab.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\tabbedarea.hpp|/home/pi/projects/guisan/include/guisan/widgets/tabbedarea.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\textbox.hpp|/home/pi/projects/guisan/include/guisan/widgets/textbox.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\textfield.hpp|/home/pi/projects/guisan/include/guisan/widgets/textfield.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\window.hpp|/home/pi/projects/guisan/include/guisan/widgets/window.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\x.hpp|/home/pi/projects/guisan/include/guisan/x.hpp +D:\midwa\Projects\GitHub\amiberry\src\guisan\lib\.keep|/home/pi/projects/guisan/lib/.keep +D:\midwa\Projects\GitHub\amiberry\src\guisan\lib|/home/pi/projects/guisan/lib +D:\midwa\Projects\GitHub\amiberry\src\guisan\Makefile|/home/pi/projects/guisan/Makefile +D:\midwa\Projects\GitHub\amiberry\src\guisan|/home/pi/projects/guisan diff --git a/VSLinux/guisan/obj/ARM/Debug/-451911409.RemoteProjectDirFile.tlog b/VSLinux/guisan/obj/ARM/Debug/-451911409.RemoteProjectDirFile.tlog new file mode 100644 index 00000000..f912559e --- /dev/null +++ b/VSLinux/guisan/obj/ARM/Debug/-451911409.RemoteProjectDirFile.tlog @@ -0,0 +1 @@ +~/projects/guisan|/home/pi/projects/guisan \ No newline at end of file diff --git a/VisualGDB/Amiberry/Amiberry.vcxproj b/VisualGDB/Amiberry/Amiberry.vcxproj index 8bfbf804..5a2a70c1 100644 --- a/VisualGDB/Amiberry/Amiberry.vcxproj +++ b/VisualGDB/Amiberry/Amiberry.vcxproj @@ -119,15 +119,15 @@ + + + + + + - - - - - - @@ -316,15 +316,15 @@ + + + + + + - - - - - - diff --git a/VisualGDB/Amiberry/Amiberry.vcxproj.filters b/VisualGDB/Amiberry/Amiberry.vcxproj.filters index 866625cd..34e973e1 100644 --- a/VisualGDB/Amiberry/Amiberry.vcxproj.filters +++ b/VisualGDB/Amiberry/Amiberry.vcxproj.filters @@ -41,18 +41,6 @@ {4e7f85db-d3e3-4b65-b969-a7b829bc3281} - - {b1a09498-1e4a-40d4-a986-9e09ad865690} - - - {dcfa291d-f91e-4f23-a259-791df4811cc0} - - - {7944e92f-3c23-4f86-842a-aa199a00dd35} - - - {ad85bf25-c171-40d2-ae9d-997bd5237bab} - {a44fad77-d044-486d-8a84-3f2f17c6bb49} @@ -303,45 +291,6 @@ Source files\jit - - Source files\archivers\7z - - - Source files\archivers\7z - - - Source files\archivers\7z - - - Source files\archivers\7z - - - Source files\archivers\7z - - - Source files\archivers\7z - - - Source files\archivers\7z - - - Source files\archivers\7z\Archive\7z - - - Source files\archivers\7z\Archive\7z - - - Source files\archivers\7z\Archive\7z - - - Source files\archivers\7z\Archive\7z - - - Source files\archivers\7z\Archive\7z - - - Source files\archivers\7z\Archive\7z - Source files\archivers\dms @@ -561,6 +510,45 @@ Source files\osdep + + Source files\archivers\7z + + + Source files\archivers\7z + + + Source files\archivers\7z + + + Source files\archivers\7z + + + Source files\archivers\7z + + + Source files\archivers\7z + + + Source files\archivers\7z + + + Source files\archivers\7z + + + Source files\archivers\7z + + + Source files\archivers\7z + + + Source files\archivers\7z + + + Source files\archivers\7z + + + Source files\archivers\7z + @@ -810,48 +798,6 @@ Header files\jit - - Header files\archivers\7z - - - Header files\archivers\7z - - - Header files\archivers\7z - - - Header files\archivers\7z - - - Header files\archivers\7z - - - Header files\archivers\7z - - - Header files\archivers\7z - - - Header files\archivers\7z - - - Header files\archivers\7z\Archive\7z - - - Header files\archivers\7z\Archive\7z - - - Header files\archivers\7z\Archive\7z - - - Header files\archivers\7z\Archive\7z - - - Header files\archivers\7z\Archive\7z - - - Header files\archivers\7z\Archive\7z - Header files\archivers\dms @@ -1149,5 +1095,47 @@ Header files\osdep + + Header files\archivers\7z + + + Header files\archivers\7z + + + Header files\archivers\7z + + + Header files\archivers\7z + + + Header files\archivers\7z + + + Header files\archivers\7z + + + Header files\archivers\7z + + + Header files\archivers\7z + + + Header files\archivers\7z + + + Header files\archivers\7z + + + Header files\archivers\7z + + + Header files\archivers\7z + + + Header files\archivers\7z + + + Header files\archivers\7z + \ No newline at end of file diff --git a/src/archivers/7z/Archive/7z/7zAlloc.cpp b/src/archivers/7z/7zAlloc.cpp similarity index 100% rename from src/archivers/7z/Archive/7z/7zAlloc.cpp rename to src/archivers/7z/7zAlloc.cpp diff --git a/src/archivers/7z/Archive/7z/7zAlloc.h b/src/archivers/7z/7zAlloc.h similarity index 100% rename from src/archivers/7z/Archive/7z/7zAlloc.h rename to src/archivers/7z/7zAlloc.h diff --git a/src/archivers/7z/Archive/7z/7zDecode.cpp b/src/archivers/7z/7zDecode.cpp similarity index 100% rename from src/archivers/7z/Archive/7z/7zDecode.cpp rename to src/archivers/7z/7zDecode.cpp diff --git a/src/archivers/7z/Archive/7z/7zDecode.h b/src/archivers/7z/7zDecode.h similarity index 100% rename from src/archivers/7z/Archive/7z/7zDecode.h rename to src/archivers/7z/7zDecode.h diff --git a/src/archivers/7z/Archive/7z/7zExtract.cpp b/src/archivers/7z/7zExtract.cpp similarity index 100% rename from src/archivers/7z/Archive/7z/7zExtract.cpp rename to src/archivers/7z/7zExtract.cpp diff --git a/src/archivers/7z/Archive/7z/7zExtract.h b/src/archivers/7z/7zExtract.h similarity index 100% rename from src/archivers/7z/Archive/7z/7zExtract.h rename to src/archivers/7z/7zExtract.h diff --git a/src/archivers/7z/Archive/7z/7zHeader.cpp b/src/archivers/7z/7zHeader.cpp similarity index 100% rename from src/archivers/7z/Archive/7z/7zHeader.cpp rename to src/archivers/7z/7zHeader.cpp diff --git a/src/archivers/7z/Archive/7z/7zHeader.h b/src/archivers/7z/7zHeader.h similarity index 100% rename from src/archivers/7z/Archive/7z/7zHeader.h rename to src/archivers/7z/7zHeader.h diff --git a/src/archivers/7z/Archive/7z/7zIn.cpp b/src/archivers/7z/7zIn.cpp similarity index 100% rename from src/archivers/7z/Archive/7z/7zIn.cpp rename to src/archivers/7z/7zIn.cpp diff --git a/src/archivers/7z/Archive/7z/7zIn.h b/src/archivers/7z/7zIn.h similarity index 100% rename from src/archivers/7z/Archive/7z/7zIn.h rename to src/archivers/7z/7zIn.h diff --git a/src/archivers/7z/Archive/7z/7zItem.cpp b/src/archivers/7z/7zItem.cpp similarity index 100% rename from src/archivers/7z/Archive/7z/7zItem.cpp rename to src/archivers/7z/7zItem.cpp diff --git a/src/archivers/7z/Archive/7z/7zItem.h b/src/archivers/7z/7zItem.h similarity index 100% rename from src/archivers/7z/Archive/7z/7zItem.h rename to src/archivers/7z/7zItem.h diff --git a/src/guisan/Makefile b/src/guisan/Makefile index ca953757..605c70d9 100644 --- a/src/guisan/Makefile +++ b/src/guisan/Makefile @@ -6,7 +6,7 @@ DIRS =$(shell find ./src -maxdepth 3 -type d) SOURCE = $(foreach dir,$(DIRS),$(wildcard $(dir)/*.cpp)) OBJS = $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE))) -INCLUDE =-I./include `sdl2-config --cflags` +INCLUDE =-I./include `sdl2-config --cflags --libs` CFLAGS = -g -w -O3 $(INCLUDE) CXXFLAGS= $(CFLAGS) From c03c70365ddce32aa8ccabb7aa95c0f58996baba Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 30 Mar 2017 23:31:56 +0200 Subject: [PATCH 04/11] Update README.md --- VSLinux/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/VSLinux/README.md b/VSLinux/README.md index c6b95284..515e30ed 100644 --- a/VSLinux/README.md +++ b/VSLinux/README.md @@ -1,5 +1,12 @@ Visual Studio solution using VC++ for Linux. =========================================== +With this solution you can use Visual Studio to edit the sources, remote debug and remote build the project running on a Pi. +For now, no cross compilation is supported in this project but if that is added from Microsoft in the future this solution will be updated accordingly. + +The project is configured to be deployed on a standard Raspbian distro, under the folder ~/projects/ (it will create a subfolder named Amiberry there). The sources are copied to the destination Pi (make sure you edit the connection details so they are correct!), then built using the Remote Build commands available in the project Properties. + +If you want to use Intellisense, you will need to copy the include files from the Pi locally and point the project to them. + You will need Visual Studio 2015 or later and VC++ for Linux installed. Look here for more information on VC++ for Linux: https://blogs.msdn.microsoft.com/vcblog/2016/03/30/visual-c-for-linux-development/ From 19ca0490262c5fff9de82de96be91ca3d565dbfd Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 30 Mar 2017 23:37:18 +0200 Subject: [PATCH 05/11] Updated VSLinux solution --- .gitignore | 3 +- VSLinux/Amiberry.vcxproj | 5 + VSLinux/guisan/guisan.vcxproj | 6 +- VSLinux/guisan/guisan.vcxproj.filters | 1 + .../-451911409.CopySourcesUpToDateFile.tlog | 115 ---------------- .../-451911409.Local_Remote_PathMapping.tlog | 126 ------------------ .../-451911409.RemoteProjectDirFile.tlog | 1 - src/archivers/7z/7zDecode.cpp | 6 +- src/archivers/7z/7zExtract.cpp | 2 +- src/archivers/7z/7zHeader.h | 2 +- src/archivers/7z/7zIn.cpp | 4 +- src/archivers/7z/7zItem.h | 2 +- src/guisan/Makefile | 2 +- src/zfile_archive.cpp | 6 +- 14 files changed, 24 insertions(+), 257 deletions(-) delete mode 100644 VSLinux/guisan/obj/ARM/Debug/-451911409.CopySourcesUpToDateFile.tlog delete mode 100644 VSLinux/guisan/obj/ARM/Debug/-451911409.Local_Remote_PathMapping.tlog delete mode 100644 VSLinux/guisan/obj/ARM/Debug/-451911409.RemoteProjectDirFile.tlog diff --git a/.gitignore b/.gitignore index b7255f28..2f3e1644 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,5 @@ VisualGDB/VisualGDB/Release/build68k VisualGDB/VisualGDB/Release/genblitter VisualGDB/VisualGDB/Release/genlinetoscr VisualGDB/VisualGDB/Release/gencpu -VisualGDB/VisualGDB/Release/gencomp \ No newline at end of file +VisualGDB/VisualGDB/Release/gencomp +*.tlog diff --git a/VSLinux/Amiberry.vcxproj b/VSLinux/Amiberry.vcxproj index d7348f90..19dfe62d 100644 --- a/VSLinux/Amiberry.vcxproj +++ b/VSLinux/Amiberry.vcxproj @@ -50,6 +50,11 @@ + + cd ~/projects/Amiberry; make + cd ~/projects/Amiberry; make clean; make + cd ~/projects/Amiberry; make clean + true diff --git a/VSLinux/guisan/guisan.vcxproj b/VSLinux/guisan/guisan.vcxproj index 0d604281..18b31264 100644 --- a/VSLinux/guisan/guisan.vcxproj +++ b/VSLinux/guisan/guisan.vcxproj @@ -40,6 +40,7 @@ true Makefile + ~/projects/Amiberry/src false @@ -67,8 +68,9 @@ - cd ~/projects/guisan/; make all - cd ~/projects/guisan/; make clean + cd ~/projects/Amiberry/src/guisan/; make all + cd ~/projects/Amiberry/src/guisan/; make clean + cd ~/projects/Amiberry/src/guisan/; make clean; make all diff --git a/VSLinux/guisan/guisan.vcxproj.filters b/VSLinux/guisan/guisan.vcxproj.filters index 5c660da6..ba924d6c 100644 --- a/VSLinux/guisan/guisan.vcxproj.filters +++ b/VSLinux/guisan/guisan.vcxproj.filters @@ -36,6 +36,7 @@ lib + diff --git a/VSLinux/guisan/obj/ARM/Debug/-451911409.CopySourcesUpToDateFile.tlog b/VSLinux/guisan/obj/ARM/Debug/-451911409.CopySourcesUpToDateFile.tlog deleted file mode 100644 index 5af2ec89..00000000 --- a/VSLinux/guisan/obj/ARM/Debug/-451911409.CopySourcesUpToDateFile.tlog +++ /dev/null @@ -1,115 +0,0 @@ -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\actionevent.cpp|636253888575313789|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\basiccontainer.cpp|636253888575318791|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\cliprectangle.cpp|636253888575323805|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\color.cpp|636253888575328544|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\defaultfont.cpp|636253888575328544|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\event.cpp|636253888575328544|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\exception.cpp|636253888575337940|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\focushandler.cpp|636253888575342974|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\font.cpp|636253888575342974|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\genericinput.cpp|636253888575347982|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\graphics.cpp|636253888575463197|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\gui.cpp|636253888575467247|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\guisan.cpp|636253888575472254|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\image.cpp|636253888575477265|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\imagefont.cpp|636253888575477265|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\inputevent.cpp|636253888575482276|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\key.cpp|636253888575487281|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\keyevent.cpp|636253888575491193|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\keyinput.cpp|636253888575491193|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\mouseevent.cpp|636253888575491193|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\mouseinput.cpp|636253888575501212|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl\opengl.cpp|636253888575501212|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl\openglgraphics.cpp|636253888575501212|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl\openglimage.cpp|636253888575511213|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\rectangle.cpp|636253888575511213|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdl.cpp|636253888575521214|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlgraphics.cpp|636253888575521214|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlimage.cpp|636253888575531216|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlimageloader.cpp|636253888575531216|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlinput.cpp|636253888575531216|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdltruetypefont.cpp|636253888575541243|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\selectionevent.cpp|636253888575541243|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widget.cpp|636253888575541243|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\button.cpp|636253888575551221|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\checkbox.cpp|636253888575551221|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\container.cpp|636253888575551221|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\dropdown.cpp|636253888575561226|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\icon.cpp|636253888575561226|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\imagebutton.cpp|636253888575561226|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\label.cpp|636253888575571224|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\listbox.cpp|636253888575581228|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\radiobutton.cpp|636253888575581228|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\scrollarea.cpp|636253888575581228|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\slider.cpp|636253888575591230|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\tab.cpp|636253888575591230|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\tabbedarea.cpp|636253888575591230|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\textbox.cpp|636253888575601231|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\textfield.cpp|636253888575606490|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\window.cpp|636253888575606490|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan.hpp|636253888574873009|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\actionevent.hpp|636253888574883010|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\actionlistener.hpp|636253888575008037|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\basiccontainer.hpp|636253888575018017|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\cliprectangle.hpp|636253888575018017|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\color.hpp|636253888575018017|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\deathlistener.hpp|636253888575028025|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\defaultfont.hpp|636253888575028025|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\event.hpp|636253888575038017|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\exception.hpp|636253888575038017|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\focushandler.hpp|636253888575038017|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\focuslistener.hpp|636253888575048024|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\font.hpp|636253888575048024|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\genericinput.hpp|636253888575048024|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\glut.hpp|636253888575048024|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\graphics.hpp|636253888575058020|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\gui.hpp|636253888575058020|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\image.hpp|636253888575058020|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\imagefont.hpp|636253888575068030|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\imageloader.hpp|636253888575068030|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\input.hpp|636253888575068030|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\inputevent.hpp|636253888575068030|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\key.hpp|636253888575078025|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\keyevent.hpp|636253888575078025|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\keyinput.hpp|636253888575078025|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\keylistener.hpp|636253888575088027|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\listmodel.hpp|636253888575088027|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\mouseevent.hpp|636253888575088027|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\mouseinput.hpp|636253888575088027|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\mouselistener.hpp|636253888575098034|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl.hpp|636253888575098034|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl\openglgraphics.hpp|636253888575098034|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl\openglimage.hpp|636253888575108038|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl\openglsdlimageloader.hpp|636253888575108038|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\platform.hpp|636253888575108038|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\rectangle.hpp|636253888575198065|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl.hpp|636253888575198065|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlgraphics.hpp|636253888575207964|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlimage.hpp|636253888575207964|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlimageloader.hpp|636253888575217980|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlinput.hpp|636253888575217980|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlpixel.hpp|636253888575217980|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdltruetypefont.hpp|636253888575227981|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\selectionevent.hpp|636253888575227981|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\selectionlistener.hpp|636253888575237965|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widget.hpp|636253888575237965|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgetlistener.hpp|636253888575237965|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\button.hpp|636253888575247975|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\checkbox.hpp|636253888575247975|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\container.hpp|636253888575257973|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\dropdown.hpp|636253888575257973|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\icon.hpp|636253888575257973|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\imagebutton.hpp|636253888575267989|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\label.hpp|636253888575267989|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\listbox.hpp|636253888575277979|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\radiobutton.hpp|636253888575277979|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\scrollarea.hpp|636253888575277979|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\slider.hpp|636253888575287980|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\tab.hpp|636253888575287980|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\tabbedarea.hpp|636253888575297978|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\textbox.hpp|636253888575297978|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\textfield.hpp|636253888575303755|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\window.hpp|636253888575308787|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\x.hpp|636253888575308787|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\lib\.keep|636253888575308787|~/projects/guisan| -D:\midwa\Projects\GitHub\amiberry\src\guisan\Makefile|636265107573980514|~/projects/guisan| diff --git a/VSLinux/guisan/obj/ARM/Debug/-451911409.Local_Remote_PathMapping.tlog b/VSLinux/guisan/obj/ARM/Debug/-451911409.Local_Remote_PathMapping.tlog deleted file mode 100644 index 031a4c56..00000000 --- a/VSLinux/guisan/obj/ARM/Debug/-451911409.Local_Remote_PathMapping.tlog +++ /dev/null @@ -1,126 +0,0 @@ -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\actionevent.cpp|/home/pi/projects/guisan/src/actionevent.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src|/home/pi/projects/guisan/src -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\basiccontainer.cpp|/home/pi/projects/guisan/src/basiccontainer.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\cliprectangle.cpp|/home/pi/projects/guisan/src/cliprectangle.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\color.cpp|/home/pi/projects/guisan/src/color.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\defaultfont.cpp|/home/pi/projects/guisan/src/defaultfont.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\event.cpp|/home/pi/projects/guisan/src/event.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\exception.cpp|/home/pi/projects/guisan/src/exception.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\focushandler.cpp|/home/pi/projects/guisan/src/focushandler.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\font.cpp|/home/pi/projects/guisan/src/font.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\genericinput.cpp|/home/pi/projects/guisan/src/genericinput.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\graphics.cpp|/home/pi/projects/guisan/src/graphics.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\gui.cpp|/home/pi/projects/guisan/src/gui.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\guisan.cpp|/home/pi/projects/guisan/src/guisan.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\image.cpp|/home/pi/projects/guisan/src/image.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\imagefont.cpp|/home/pi/projects/guisan/src/imagefont.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\inputevent.cpp|/home/pi/projects/guisan/src/inputevent.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\key.cpp|/home/pi/projects/guisan/src/key.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\keyevent.cpp|/home/pi/projects/guisan/src/keyevent.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\keyinput.cpp|/home/pi/projects/guisan/src/keyinput.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\mouseevent.cpp|/home/pi/projects/guisan/src/mouseevent.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\mouseinput.cpp|/home/pi/projects/guisan/src/mouseinput.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl\opengl.cpp|/home/pi/projects/guisan/src/opengl/opengl.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl|/home/pi/projects/guisan/src/opengl -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl\openglgraphics.cpp|/home/pi/projects/guisan/src/opengl/openglgraphics.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\opengl\openglimage.cpp|/home/pi/projects/guisan/src/opengl/openglimage.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\rectangle.cpp|/home/pi/projects/guisan/src/rectangle.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdl.cpp|/home/pi/projects/guisan/src/sdl/sdl.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl|/home/pi/projects/guisan/src/sdl -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlgraphics.cpp|/home/pi/projects/guisan/src/sdl/sdlgraphics.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlimage.cpp|/home/pi/projects/guisan/src/sdl/sdlimage.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlimageloader.cpp|/home/pi/projects/guisan/src/sdl/sdlimageloader.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdlinput.cpp|/home/pi/projects/guisan/src/sdl/sdlinput.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\sdl\sdltruetypefont.cpp|/home/pi/projects/guisan/src/sdl/sdltruetypefont.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\selectionevent.cpp|/home/pi/projects/guisan/src/selectionevent.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widget.cpp|/home/pi/projects/guisan/src/widget.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\button.cpp|/home/pi/projects/guisan/src/widgets/button.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets|/home/pi/projects/guisan/src/widgets -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\checkbox.cpp|/home/pi/projects/guisan/src/widgets/checkbox.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\container.cpp|/home/pi/projects/guisan/src/widgets/container.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\dropdown.cpp|/home/pi/projects/guisan/src/widgets/dropdown.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\icon.cpp|/home/pi/projects/guisan/src/widgets/icon.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\imagebutton.cpp|/home/pi/projects/guisan/src/widgets/imagebutton.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\label.cpp|/home/pi/projects/guisan/src/widgets/label.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\listbox.cpp|/home/pi/projects/guisan/src/widgets/listbox.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\radiobutton.cpp|/home/pi/projects/guisan/src/widgets/radiobutton.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\scrollarea.cpp|/home/pi/projects/guisan/src/widgets/scrollarea.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\slider.cpp|/home/pi/projects/guisan/src/widgets/slider.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\tab.cpp|/home/pi/projects/guisan/src/widgets/tab.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\tabbedarea.cpp|/home/pi/projects/guisan/src/widgets/tabbedarea.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\textbox.cpp|/home/pi/projects/guisan/src/widgets/textbox.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\textfield.cpp|/home/pi/projects/guisan/src/widgets/textfield.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\src\widgets\window.cpp|/home/pi/projects/guisan/src/widgets/window.cpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan.hpp|/home/pi/projects/guisan/include/guisan.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include|/home/pi/projects/guisan/include -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\actionevent.hpp|/home/pi/projects/guisan/include/guisan/actionevent.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan|/home/pi/projects/guisan/include/guisan -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\actionlistener.hpp|/home/pi/projects/guisan/include/guisan/actionlistener.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\basiccontainer.hpp|/home/pi/projects/guisan/include/guisan/basiccontainer.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\cliprectangle.hpp|/home/pi/projects/guisan/include/guisan/cliprectangle.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\color.hpp|/home/pi/projects/guisan/include/guisan/color.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\deathlistener.hpp|/home/pi/projects/guisan/include/guisan/deathlistener.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\defaultfont.hpp|/home/pi/projects/guisan/include/guisan/defaultfont.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\event.hpp|/home/pi/projects/guisan/include/guisan/event.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\exception.hpp|/home/pi/projects/guisan/include/guisan/exception.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\focushandler.hpp|/home/pi/projects/guisan/include/guisan/focushandler.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\focuslistener.hpp|/home/pi/projects/guisan/include/guisan/focuslistener.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\font.hpp|/home/pi/projects/guisan/include/guisan/font.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\genericinput.hpp|/home/pi/projects/guisan/include/guisan/genericinput.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\glut.hpp|/home/pi/projects/guisan/include/guisan/glut.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\graphics.hpp|/home/pi/projects/guisan/include/guisan/graphics.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\gui.hpp|/home/pi/projects/guisan/include/guisan/gui.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\image.hpp|/home/pi/projects/guisan/include/guisan/image.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\imagefont.hpp|/home/pi/projects/guisan/include/guisan/imagefont.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\imageloader.hpp|/home/pi/projects/guisan/include/guisan/imageloader.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\input.hpp|/home/pi/projects/guisan/include/guisan/input.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\inputevent.hpp|/home/pi/projects/guisan/include/guisan/inputevent.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\key.hpp|/home/pi/projects/guisan/include/guisan/key.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\keyevent.hpp|/home/pi/projects/guisan/include/guisan/keyevent.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\keyinput.hpp|/home/pi/projects/guisan/include/guisan/keyinput.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\keylistener.hpp|/home/pi/projects/guisan/include/guisan/keylistener.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\listmodel.hpp|/home/pi/projects/guisan/include/guisan/listmodel.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\mouseevent.hpp|/home/pi/projects/guisan/include/guisan/mouseevent.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\mouseinput.hpp|/home/pi/projects/guisan/include/guisan/mouseinput.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\mouselistener.hpp|/home/pi/projects/guisan/include/guisan/mouselistener.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl.hpp|/home/pi/projects/guisan/include/guisan/opengl.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl\openglgraphics.hpp|/home/pi/projects/guisan/include/guisan/opengl/openglgraphics.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl|/home/pi/projects/guisan/include/guisan/opengl -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl\openglimage.hpp|/home/pi/projects/guisan/include/guisan/opengl/openglimage.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\opengl\openglsdlimageloader.hpp|/home/pi/projects/guisan/include/guisan/opengl/openglsdlimageloader.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\platform.hpp|/home/pi/projects/guisan/include/guisan/platform.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\rectangle.hpp|/home/pi/projects/guisan/include/guisan/rectangle.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl.hpp|/home/pi/projects/guisan/include/guisan/sdl.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlgraphics.hpp|/home/pi/projects/guisan/include/guisan/sdl/sdlgraphics.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl|/home/pi/projects/guisan/include/guisan/sdl -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlimage.hpp|/home/pi/projects/guisan/include/guisan/sdl/sdlimage.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlimageloader.hpp|/home/pi/projects/guisan/include/guisan/sdl/sdlimageloader.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlinput.hpp|/home/pi/projects/guisan/include/guisan/sdl/sdlinput.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdlpixel.hpp|/home/pi/projects/guisan/include/guisan/sdl/sdlpixel.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\sdl\sdltruetypefont.hpp|/home/pi/projects/guisan/include/guisan/sdl/sdltruetypefont.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\selectionevent.hpp|/home/pi/projects/guisan/include/guisan/selectionevent.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\selectionlistener.hpp|/home/pi/projects/guisan/include/guisan/selectionlistener.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widget.hpp|/home/pi/projects/guisan/include/guisan/widget.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgetlistener.hpp|/home/pi/projects/guisan/include/guisan/widgetlistener.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\button.hpp|/home/pi/projects/guisan/include/guisan/widgets/button.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets|/home/pi/projects/guisan/include/guisan/widgets -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\checkbox.hpp|/home/pi/projects/guisan/include/guisan/widgets/checkbox.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\container.hpp|/home/pi/projects/guisan/include/guisan/widgets/container.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\dropdown.hpp|/home/pi/projects/guisan/include/guisan/widgets/dropdown.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\icon.hpp|/home/pi/projects/guisan/include/guisan/widgets/icon.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\imagebutton.hpp|/home/pi/projects/guisan/include/guisan/widgets/imagebutton.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\label.hpp|/home/pi/projects/guisan/include/guisan/widgets/label.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\listbox.hpp|/home/pi/projects/guisan/include/guisan/widgets/listbox.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\radiobutton.hpp|/home/pi/projects/guisan/include/guisan/widgets/radiobutton.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\scrollarea.hpp|/home/pi/projects/guisan/include/guisan/widgets/scrollarea.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\slider.hpp|/home/pi/projects/guisan/include/guisan/widgets/slider.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\tab.hpp|/home/pi/projects/guisan/include/guisan/widgets/tab.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\tabbedarea.hpp|/home/pi/projects/guisan/include/guisan/widgets/tabbedarea.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\textbox.hpp|/home/pi/projects/guisan/include/guisan/widgets/textbox.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\textfield.hpp|/home/pi/projects/guisan/include/guisan/widgets/textfield.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\widgets\window.hpp|/home/pi/projects/guisan/include/guisan/widgets/window.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\include\guisan\x.hpp|/home/pi/projects/guisan/include/guisan/x.hpp -D:\midwa\Projects\GitHub\amiberry\src\guisan\lib\.keep|/home/pi/projects/guisan/lib/.keep -D:\midwa\Projects\GitHub\amiberry\src\guisan\lib|/home/pi/projects/guisan/lib -D:\midwa\Projects\GitHub\amiberry\src\guisan\Makefile|/home/pi/projects/guisan/Makefile -D:\midwa\Projects\GitHub\amiberry\src\guisan|/home/pi/projects/guisan diff --git a/VSLinux/guisan/obj/ARM/Debug/-451911409.RemoteProjectDirFile.tlog b/VSLinux/guisan/obj/ARM/Debug/-451911409.RemoteProjectDirFile.tlog deleted file mode 100644 index f912559e..00000000 --- a/VSLinux/guisan/obj/ARM/Debug/-451911409.RemoteProjectDirFile.tlog +++ /dev/null @@ -1 +0,0 @@ -~/projects/guisan|/home/pi/projects/guisan \ No newline at end of file diff --git a/src/archivers/7z/7zDecode.cpp b/src/archivers/7z/7zDecode.cpp index 9ef7e8be..91f3cfd8 100644 --- a/src/archivers/7z/7zDecode.cpp +++ b/src/archivers/7z/7zDecode.cpp @@ -3,9 +3,9 @@ #include -#include "../../Bcj2.h" -#include "../../Bra.h" -#include "../../LzmaDec.h" +#include "Bcj2.h" +#include "Bra.h" +#include "LzmaDec.h" #include "7zDecode.h" #define k_Copy 0 diff --git a/src/archivers/7z/7zExtract.cpp b/src/archivers/7z/7zExtract.cpp index eda4a0cc..89cb1216 100644 --- a/src/archivers/7z/7zExtract.cpp +++ b/src/archivers/7z/7zExtract.cpp @@ -1,7 +1,7 @@ /* 7zExtract.c -- Extracting from 7z archive 2008-11-23 : Igor Pavlov : Public domain */ -#include "../../7zCrc.h" +#include "7zCrc.h" #include "7zDecode.h" #include "7zExtract.h" diff --git a/src/archivers/7z/7zHeader.h b/src/archivers/7z/7zHeader.h index fbef0ad8..c44819fe 100644 --- a/src/archivers/7z/7zHeader.h +++ b/src/archivers/7z/7zHeader.h @@ -4,7 +4,7 @@ #ifndef __7Z_HEADER_H #define __7Z_HEADER_H -#include "../../Types.h" +#include "Types.h" #define k7zSignatureSize 6 extern Byte k7zSignature[k7zSignatureSize]; diff --git a/src/archivers/7z/7zIn.cpp b/src/archivers/7z/7zIn.cpp index 6400fd61..d3e1c783 100644 --- a/src/archivers/7z/7zIn.cpp +++ b/src/archivers/7z/7zIn.cpp @@ -1,8 +1,8 @@ /* 7zIn.c -- 7z Input functions 2008-12-31 : Igor Pavlov : Public domain */ -#include "../../7zCrc.h" -#include "../../CpuArch.h" +#include "7zCrc.h" +#include "CpuArch.h" #include "7zDecode.h" #include "7zIn.h" diff --git a/src/archivers/7z/7zItem.h b/src/archivers/7z/7zItem.h index b8e820ba..2e630676 100644 --- a/src/archivers/7z/7zItem.h +++ b/src/archivers/7z/7zItem.h @@ -4,7 +4,7 @@ #ifndef __7Z_ITEM_H #define __7Z_ITEM_H -#include "../../7zBuf.h" +#include "7zBuf.h" typedef struct { diff --git a/src/guisan/Makefile b/src/guisan/Makefile index 605c70d9..847d4424 100644 --- a/src/guisan/Makefile +++ b/src/guisan/Makefile @@ -7,7 +7,7 @@ SOURCE = $(foreach dir,$(DIRS),$(wildcard $(dir)/*.cpp)) OBJS = $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE))) INCLUDE =-I./include `sdl2-config --cflags --libs` -CFLAGS = -g -w -O3 $(INCLUDE) +CFLAGS =-g -w -O3 $(INCLUDE) CXXFLAGS= $(CFLAGS) diff --git a/src/zfile_archive.cpp b/src/zfile_archive.cpp index c84462e3..d511a1ed 100644 --- a/src/zfile_archive.cpp +++ b/src/zfile_archive.cpp @@ -492,9 +492,9 @@ static struct zfile *archive_unpack_zip (struct zfile *zf) #include "archivers/7z/Types.h" #include "archivers/7z/7zCrc.h" -#include "archivers/7z/Archive/7z/7zIn.h" -#include "archivers/7z/Archive/7z/7zExtract.h" -#include "archivers/7z/Archive/7z/7zAlloc.h" +#include "archivers/7z/7zIn.h" +#include "archivers/7z/7zExtract.h" +#include "archivers/7z/7zAlloc.h" static ISzAlloc allocImp; static ISzAlloc allocTempImp; From ffabafaaacc0f84d1b0859e73458f579fa1912bb Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 31 Mar 2017 12:21:35 +0200 Subject: [PATCH 06/11] VSLinux: Dev branch now builds in a separate folder, "Amiberry-dev" to avoid mixing files with other branches --- VSLinux/Amiberry.vcxproj | 15 ++++++++++++--- VSLinux/guisan/guisan.vcxproj | 14 ++++++++++---- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/VSLinux/Amiberry.vcxproj b/VSLinux/Amiberry.vcxproj index 19dfe62d..27ddd3c1 100644 --- a/VSLinux/Amiberry.vcxproj +++ b/VSLinux/Amiberry.vcxproj @@ -51,9 +51,18 @@ - cd ~/projects/Amiberry; make - cd ~/projects/Amiberry; make clean; make - cd ~/projects/Amiberry; make clean + cd ~/projects/Amiberry-dev; make + cd ~/projects/Amiberry-dev; make clean; make + cd ~/projects/Amiberry-dev; make clean + D:\midwa\Projects\GitHub\amiberry\src\guisan\include;D:\midwa\Projects\GitHub\amiberry\src\include;D:\midwa\Projects\GitHub\amiberry\src\threaddep;D:\midwa\Projects\GitHub\amiberry\src\osdep;D:\midwa\Projects\GitHub\amiberry\src;$(NMakeIncludeSearchPath) + $(RemoteRootDir)/$(ProjectName)-dev + + + cd ~/projects/Amiberry-dev; make + cd ~/projects/Amiberry-dev; make clean; make + cd ~/projects/Amiberry-dev; make clean + D:\midwa\Projects\GitHub\amiberry\src\guisan\include;D:\midwa\Projects\GitHub\amiberry\src\include;D:\midwa\Projects\GitHub\amiberry\src\threaddep;D:\midwa\Projects\GitHub\amiberry\src\osdep;D:\midwa\Projects\GitHub\amiberry\src;$(NMakeIncludeSearchPath) + $(RemoteRootDir)/$(ProjectName)-dev diff --git a/VSLinux/guisan/guisan.vcxproj b/VSLinux/guisan/guisan.vcxproj index 18b31264..4d9ec4ed 100644 --- a/VSLinux/guisan/guisan.vcxproj +++ b/VSLinux/guisan/guisan.vcxproj @@ -40,11 +40,12 @@ true Makefile - ~/projects/Amiberry/src + ~/projects/Amiberry-dev/src false Makefile + ~/projects/Amiberry-dev/src true @@ -68,9 +69,14 @@ - cd ~/projects/Amiberry/src/guisan/; make all - cd ~/projects/Amiberry/src/guisan/; make clean - cd ~/projects/Amiberry/src/guisan/; make clean; make all + cd ~/projects/Amiberry-dev/src/guisan/; make all + cd ~/projects/Amiberry-dev/src/guisan/; make clean + cd ~/projects/Amiberry-dev/src/guisan/; make clean; make all + + + cd ~/projects/Amiberry-dev/src/guisan/; make all + cd ~/projects/Amiberry-dev/src/guisan/; make clean; make all + cd ~/projects/Amiberry-dev/src/guisan/; make clean From 9511db2bfda24d23d0df0c3f0a54d3bc55d74a5e Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 31 Mar 2017 13:41:49 +0200 Subject: [PATCH 07/11] Renamed executable for Dev branch --- .gitignore | 1 + Makefile | 2 +- VSLinux/Amiberry.vcxproj | 11 ++++++++++- VSLinux/Amiberry.vcxproj.user | 13 ++++++++++++- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 2f3e1644..3a15de49 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ VisualGDB/VisualGDB/Release/genlinetoscr VisualGDB/VisualGDB/Release/gencpu VisualGDB/VisualGDB/Release/gencomp *.tlog +VSLinux/obj/ARM/Debug/amiberry-sdl2-dev diff --git a/Makefile b/Makefile index 4d39ffb7..819cb282 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ else ifeq ($(PLATFORM),rpi1) CPU_FLAGS += -std=gnu++14 -march=armv6zk -mfpu=vfp -mfloat-abi=hard endif -NAME = amiberry-sdl2 +NAME = amiberry-sdl2-dev RM = rm -f CC = gcc CXX = g++ diff --git a/VSLinux/Amiberry.vcxproj b/VSLinux/Amiberry.vcxproj index 27ddd3c1..114f2317 100644 --- a/VSLinux/Amiberry.vcxproj +++ b/VSLinux/Amiberry.vcxproj @@ -536,7 +536,16 @@ - + + + cp ~/projects/Amiberry-dev/amiberry-sdl2-dev ~/projects/amiberry + + + + + cp ~/projects/Amiberry-dev/amiberry-sdl2-dev ~/projects/amiberry + + \ No newline at end of file diff --git a/VSLinux/Amiberry.vcxproj.user b/VSLinux/Amiberry.vcxproj.user index be250787..14f5d4cc 100644 --- a/VSLinux/Amiberry.vcxproj.user +++ b/VSLinux/Amiberry.vcxproj.user @@ -1,4 +1,15 @@  - + + ~/projects/amiberry + LinuxDebugger + ~/projects/amiberry/amiberry-sdl2-dev + DISPLAY=:0.0 + + + ~/projects/amiberry + LinuxDebugger + ~/projects/amiberry/amiberry-sdl2-dev + DISPLAY=:0.0 + \ No newline at end of file From d1f5c51f453f78b2e3e85fda0b4ed21828cbd7ac Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 31 Mar 2017 14:42:08 +0200 Subject: [PATCH 08/11] Removed Profiler include from Main (not used here) --- src/main.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 29bf059f..b6120f5a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,10 +54,6 @@ SDL_DisplayMode sdlMode; #include #include "keyboard.h" -#ifdef DEBUG -#include "gperftools/profiler.h" -#endif - long int version = 256 * 65536L*UAEMAJOR + 65536L*UAEMINOR + UAESUBREV; struct uae_prefs currprefs, changed_prefs; From 2c8c1d2b498cef1abaf2a850e60148b5f38110a3 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 31 Mar 2017 15:23:30 +0200 Subject: [PATCH 09/11] Update README.md --- README.md | 46 ++++++++-------------------------------------- 1 file changed, 8 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 2740994c..4c0aed8e 100644 --- a/README.md +++ b/README.md @@ -30,49 +30,19 @@ Stuff here will most probably break at some places. Don't bother reporting bugs! - Optimizations for Pi 3 added - New target platform: Pi 3 -# Compiling from source -To get full screen SDL2 support from the console on the Raspberry Pi, you will have to compile SDL2 from source. That is because the OpenGL driver is on higher priority than the OpenGL ES2 one on the Pi, and the OpenGL driver requires X11. If you don't mind that and you want to run the emulator under X11 only, then you can skip this step and install SDL2 from the package manager instead. Otherwise, you can just copy paste the following commands in your terminal. +# Compiling SDL2 +Luckily, the RetroPie project has a handy script that takes care of downloading, compiling and installing SDL2 for us. This currently only handles SDL2, so we still need SDL2_ttf and SDL2_image (see below). -First you will need to get all the necessary tools and requirements for SDL2: +Run these to clone the RetroPie-Setup repo, then run the relevant script: - sudo apt-get update && sudo apt-get upgrade - sudo apt-get install build-essential libfreeimage-dev libopenal-dev libpango1.0-dev libsndfile-dev libudev-dev libasound2-dev libtiff5-dev libwebp-dev automake libegl1-mesa-dev libgl1-mesa-dev libgles2-mesa-dev + git clone https://github.com/RetroPie/RetroPie-Setup + cd RetroPie-Setup + sudo ./retropie_packages.sh sdl2 -Then download the SDL2 source tarball (currently on v2.0.5): +Next, we need SDL2_image and SDL2_ttf: - cd ~ - wget https://www.libsdl.org/release/SDL2-2.0.5.tar.gz - tar zxvf SDL2-2.0.5.tar.gz - cd SDL2-2.0.5 && mkdir build && cd build + sudo apt-get install libsdl2-image-dev libsdl2-ttf-dev -Next, configure SDL2 to disable OpenGL, in order to be able to open screens directly from the console using OpenGL ES2 instead: - - ../configure --disable-pulseaudio --disable-esd --disable-video-opengl - -Compile and install SDL2: - - make -j 4 && sudo make install - -Next, we need SDL2_image (currently v2.0.1): - - cd ~ - wget https://www.libsdl.org/projects/SDL_image/release/SDL2_image-2.0.1.tar.gz - tar zxvf SDL2_image-2.0.1.tar.gz - cd SDL2_image-2.0.1 && mkdir build && cd build - ../configure - make -j 4 - sudo make install - -Next, SDL2_ttf (currently v2.0.14): - - cd ~ - wget https://libsdl.org/projects/SDL_ttf/release/SDL2_ttf-2.0.14.tar.gz - tar zxvf SDL2_ttf-2.0.14.tar.gz - cd SDL2_ttf-2.0.14 && mkdir build && cd build - ../configure - make -j 4 - sudo make install - With SDL2 installed, you can proceed to install Amiberry as follows: Install the following packages: From cdf1b26254b9cc45c786f9bd231e7145cc3b5759 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 31 Mar 2017 18:09:51 +0200 Subject: [PATCH 10/11] Cleanup: Removed unneeded defines --- .gitignore | 1 + Makefile | 7 +- VSLinux/Amiberry.vcxproj | 1 - VSLinux/Amiberry.vcxproj.filters | 3 - VisualGDB/Amiberry/Amiberry.vcxproj | 24 +-- src/fsdb_unix.cpp | 2 +- src/osdep/amiberry_gui.cpp | 2 +- src/osdep/gui/PanelMisc.cpp | 11 +- src/osdep/gui/SelectFile.cpp | 2 +- src/osdep/menu/menu_config.cpp | 4 +- src/osdep/picasso96.cpp | 17 +- src/osdep/sysconfig.h | 2 +- src/sounddep/sound.cpp | 317 ---------------------------- src/sounddep/sound_sdl_new.cpp | 2 +- 14 files changed, 29 insertions(+), 366 deletions(-) delete mode 100644 src/sounddep/sound.cpp diff --git a/.gitignore b/.gitignore index 3a15de49..7ca9e302 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ VisualGDB/VisualGDB/Release/gencpu VisualGDB/VisualGDB/Release/gencomp *.tlog VSLinux/obj/ARM/Debug/amiberry-sdl2-dev +VisualGDB/VisualGDB/Debug/Amiberry-sdl2-dev diff --git a/Makefile b/Makefile index 819cb282..367972e3 100644 --- a/Makefile +++ b/Makefile @@ -26,13 +26,12 @@ guisan: cd src/guisan && make all && cd ../.. DEBUG=1 -PANDORA=1 SDL_CFLAGS = `sdl2-config --cflags --libs` -DEFS += `xml2-config --cflags` -DEFS += -DCPU_arm -DARMV6_ASSEMBLY -DAMIBERRY -DPICASSO96 -DEFS += -DWITH_INGAME_WARNING -DRASPBERRY -DCAPSLOCK_DEBIAN_WORKAROUND +DEFS += `xml2-config --cflags` +DEFS += -DARMV6_ASSEMBLY -DAMIBERRY +DEFS += -DCAPSLOCK_DEBIAN_WORKAROUND DEFS += -DROM_PATH_PREFIX=\"./\" -DDATA_PREFIX=\"./data/\" -DSAVE_PREFIX=\"./saves/\" DEFS += -DUSE_SDL diff --git a/VSLinux/Amiberry.vcxproj b/VSLinux/Amiberry.vcxproj index 114f2317..c305cc2e 100644 --- a/VSLinux/Amiberry.vcxproj +++ b/VSLinux/Amiberry.vcxproj @@ -400,7 +400,6 @@ false - false diff --git a/VSLinux/Amiberry.vcxproj.filters b/VSLinux/Amiberry.vcxproj.filters index 52f036d1..e8a68f59 100644 --- a/VSLinux/Amiberry.vcxproj.filters +++ b/VSLinux/Amiberry.vcxproj.filters @@ -603,9 +603,6 @@ src\osdep\menu - - src\sounddep - src\sounddep diff --git a/VisualGDB/Amiberry/Amiberry.vcxproj b/VisualGDB/Amiberry/Amiberry.vcxproj index 5a2a70c1..5ad7934a 100644 --- a/VisualGDB/Amiberry/Amiberry.vcxproj +++ b/VisualGDB/Amiberry/Amiberry.vcxproj @@ -31,31 +31,31 @@ Debug C:\SysGCC\raspberry - $(ProjectName)-sdl2 + $(ProjectName)-sdl2-dev C:\SysGCC\raspberry - $(ProjectName)-sdl2 + $(ProjectName)-sdl2-dev C:\SysGCC\raspberry - $(ProjectName)-sdl2-rpi2 + $(ProjectName)-sdl2-dev-rpi2 C:\SysGCC\raspberry - $(ProjectName)-sdl2-rpi1 + $(ProjectName)-sdl2-dev-rpi1 GNUPP14 C:\SysGCC\raspberry\lib\gcc\arm-linux-gnueabihf\4.9\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\include\c++\4.9;C:\SysGCC\raspberry\arm-linux-gnueabihf\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include\interface\vmcs_host\linux;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include\interface\vcos\pthreads;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\local\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\local\include\SDL2;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include\libxml2;../../src;../../src/include;../../src/osdep;../../src/threaddep;../../src/guisan/include;=/opt/vc/include;=/opt/vc/include/interface/vmcs_host/linux;=/opt/vc/include/interface/vcos/pthreads;=/usr/local/include;=/usr/local/include/SDL2;=/usr/include/libxml2;%(ClCompile.AdditionalIncludeDirectories) - DEBUG=1;_REENTRANT;RASPBERRY;CAPSLOCK_DEBIAN_WORKAROUND;ARMV6T2;PICASSO96;USE_ARMNEON;CPU_arm;ARMV6_ASSEMBLY;AMIBERRY;WITH_INGAME_WARNING;USE_SDL;ROM_PATH_PREFIX=\"./\";DATA_PREFIX=\"./data/\";SAVE_PREFIX=\"./saves/\";GCCCONSTFUNC="__attribute__((const))";%(ClCompile.PreprocessorDefinitions) + DEBUG=1;_REENTRANT;CAPSLOCK_DEBIAN_WORKAROUND;ARMV6T2;USE_ARMNEON;ARMV6_ASSEMBLY;AMIBERRY;USE_SDL;ROM_PATH_PREFIX=\"./\";DATA_PREFIX=\"./data/\";SAVE_PREFIX=\"./saves/\";GCCCONSTFUNC="__attribute__((const))";%(ClCompile.PreprocessorDefinitions) -march=armv8-a -mfpu=neon-fp-armv8 -mfloat-abi=hard -pipe %(AdditionalOptions) -Wl,-gc-sections,-rpath,/usr/local/lib;%(Link.AdditionalLinkerInputs) ../../src/guisan/lib;=/opt/vc/lib;=/usr/local/lib;%(Link.LibrarySearchDirectories) - SDL2;SDL2_image;SDL2_ttf;pthread;m;z;png;rt;xml2;FLAC;mpg123;dl;guisan;profiler;%(Link.AdditionalLibraryNames) + SDL2;SDL2_image;SDL2_ttf;pthread;m;z;png;rt;xml2;FLAC;mpg123;dl;guisan;profiler;tcmalloc;%(Link.AdditionalLibraryNames) =/usr/local/lib;%(ExtraRPATH) @@ -64,7 +64,7 @@ GNUPP14 C:\SysGCC\raspberry\lib\gcc\arm-linux-gnueabihf\4.9\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\include\c++\4.9;C:\SysGCC\raspberry\arm-linux-gnueabihf\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include\interface\vmcs_host\linux;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include\interface\vcos\pthreads;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\local\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\local\include\SDL2;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include\libxml2;../../src;../../src/include;../../src/osdep;../../src/threaddep;../../src/guisan/include;=/opt/vc/include;=/opt/vc/include/interface/vmcs_host/linux;=/opt/vc/include/interface/vcos/pthreads;=/usr/local/include;=/usr/local/include/SDL2;=/usr/include/libxml2;%(ClCompile.AdditionalIncludeDirectories) - NDEBUG=1;RELEASE=1;_REENTRANT;RASPBERRY;CAPSLOCK_DEBIAN_WORKAROUND;ARMV6T2;PICASSO96;USE_ARMNEON;CPU_arm;ARMV6_ASSEMBLY;AMIBERRY;WITH_INGAME_WARNING;USE_SDL;ROM_PATH_PREFIX=\"./\";DATA_PREFIX=\"./data/\";SAVE_PREFIX=\"./saves/\";GCCCONSTFUNC="__attribute__((const))";%(ClCompile.PreprocessorDefinitions) + NDEBUG=1;RELEASE=1;_REENTRANT;CAPSLOCK_DEBIAN_WORKAROUND;ARMV6T2;USE_ARMNEON;ARMV6_ASSEMBLY;AMIBERRY;USE_SDL;ROM_PATH_PREFIX=\"./\";DATA_PREFIX=\"./data/\";SAVE_PREFIX=\"./saves/\";GCCCONSTFUNC="__attribute__((const))";%(ClCompile.PreprocessorDefinitions) -march=armv8-a -mfpu=neon-fp-armv8 -mfloat-abi=hard -pipe -fweb %(AdditionalOptions) true true @@ -72,7 +72,7 @@ -Wl,-gc-sections,-rpath,/usr/local/lib;%(Link.AdditionalLinkerInputs) ../../src/guisan/lib;=/opt/vc/lib;=/usr/local/lib;%(Link.LibrarySearchDirectories) - SDL2;SDL2_image;SDL2_ttf;pthread;m;z;png;rt;xml2;FLAC;mpg123;dl;guisan;%(Link.AdditionalLibraryNames) + SDL2;SDL2_image;SDL2_ttf;pthread;m;z;png;rt;xml2;FLAC;mpg123;dl;guisan;profiler;tcmalloc;%(Link.AdditionalLibraryNames) =/usr/local/lib;%(ExtraRPATH) @@ -81,7 +81,7 @@ GNUPP14 C:\SysGCC\raspberry\lib\gcc\arm-linux-gnueabihf\4.9\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\include\c++\4.9;C:\SysGCC\raspberry\arm-linux-gnueabihf\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include\interface\vmcs_host\linux;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include\interface\vcos\pthreads;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\local\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\local\include\SDL2;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include\libxml2;../../src;../../src/include;../../src/osdep;../../src/threaddep;../../src/guisan/include;=/opt/vc/include;=/opt/vc/include/interface/vmcs_host/linux;=/opt/vc/include/interface/vcos/pthreads;=/usr/local/include;=/usr/local/include/SDL2;=/usr/include/libxml2;%(ClCompile.AdditionalIncludeDirectories) - NDEBUG=1;RELEASE=1;_REENTRANT;RASPBERRY;CAPSLOCK_DEBIAN_WORKAROUND;ARMV6T2;PICASSO96;USE_ARMNEON;CPU_arm;ARMV6_ASSEMBLY;AMIBERRY;WITH_INGAME_WARNING;USE_SDL;ROM_PATH_PREFIX=\"./\";DATA_PREFIX=\"./data/\";SAVE_PREFIX=\"./saves/\";GCCCONSTFUNC="__attribute__((const))";%(ClCompile.PreprocessorDefinitions) + NDEBUG=1;RELEASE=1;_REENTRANT;CAPSLOCK_DEBIAN_WORKAROUND;ARMV6T2;USE_ARMNEON;ARMV6_ASSEMBLY;AMIBERRY;USE_SDL;ROM_PATH_PREFIX=\"./\";DATA_PREFIX=\"./data/\";SAVE_PREFIX=\"./saves/\";GCCCONSTFUNC="__attribute__((const))";%(ClCompile.PreprocessorDefinitions) -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard -pipe -fweb %(AdditionalOptions) true true @@ -89,7 +89,7 @@ -Wl,-gc-sections,-rpath,/usr/local/lib;%(Link.AdditionalLinkerInputs) ../../src/guisan/lib;=/opt/vc/lib;=/usr/local/lib;%(Link.LibrarySearchDirectories) - SDL2;pthread;m;z;SDL2_image;png;rt;xml2;FLAC;mpg123;dl;SDL2_ttf;guisan;%(Link.AdditionalLibraryNames) + SDL2;SDL2_image;SDL2_ttf;pthread;m;z;png;rt;xml2;FLAC;mpg123;dl;guisan;profiler;tcmalloc;%(Link.AdditionalLibraryNames) =/usr/local/lib;%(ExtraRPATH) @@ -99,7 +99,7 @@ GNUPP14 C:\SysGCC\raspberry\lib\gcc\arm-linux-gnueabihf\4.9\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\include\c++\4.9;C:\SysGCC\raspberry\arm-linux-gnueabihf\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include\interface\vmcs_host\linux;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include\interface\vcos\pthreads;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\local\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\local\include\SDL2;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include\libxml2;../../src;../../src/include;../../src/osdep;../../src/threaddep;../../src/guisan/include;=/opt/vc/include;=/opt/vc/include/interface/vmcs_host/linux;=/opt/vc/include/interface/vcos/pthreads;=/usr/local/include;=/usr/local/include/SDL2;=/usr/include/libxml2;%(ClCompile.AdditionalIncludeDirectories) - NDEBUG=1;RELEASE=1;_REENTRANT;RASPBERRY;CAPSLOCK_DEBIAN_WORKAROUND;PICASSO96;CPU_arm;ARMV6_ASSEMBLY;AMIBERRY;WITH_INGAME_WARNING;USE_SDL;ROM_PATH_PREFIX=\"./\";DATA_PREFIX=\"./data/\";SAVE_PREFIX=\"./saves/\";GCCCONSTFUNC="__attribute__((const))";%(ClCompile.PreprocessorDefinitions) + NDEBUG=1;RELEASE=1;_REENTRANT;CAPSLOCK_DEBIAN_WORKAROUND;ARMV6_ASSEMBLY;AMIBERRY;USE_SDL;ROM_PATH_PREFIX=\"./\";DATA_PREFIX=\"./data/\";SAVE_PREFIX=\"./saves/\";GCCCONSTFUNC="__attribute__((const))";%(ClCompile.PreprocessorDefinitions) -march=armv6zk -mfpu=vfp -mfloat-abi=hard -pipe -fweb %(AdditionalOptions) true true @@ -107,7 +107,7 @@ -Wl,-gc-sections,-rpath,/usr/local/lib;%(Link.AdditionalLinkerInputs) ../../src/guisan/lib;=/opt/vc/lib;=/usr/local/lib;%(Link.LibrarySearchDirectories) - SDL2;pthread;m;z;SDL2_image;png;rt;xml2;FLAC;mpg123;dl;SDL2_ttf;guisan;%(Link.AdditionalLibraryNames) + SDL2;SDL2_image;SDL2_ttf;pthread;m;z;png;rt;xml2;FLAC;mpg123;dl;guisan;profiler;tcmalloc;%(Link.AdditionalLibraryNames) =/usr/local/lib;%(ExtraRPATH) diff --git a/src/fsdb_unix.cpp b/src/fsdb_unix.cpp index ee95a1f3..baaa11a1 100644 --- a/src/fsdb_unix.cpp +++ b/src/fsdb_unix.cpp @@ -83,7 +83,7 @@ int fsdb_fill_file_attrs (a_inode *base, a_inode *aino) | (S_IWUSR & statbuf.st_mode ? 0 : A_FIBF_WRITE) | (S_IRUSR & statbuf.st_mode ? 0 : A_FIBF_READ)); -#if defined(WIN32) || defined(ANDROIDSDL) || defined(RASPBERRY) +#if defined(WIN32) || defined(ANDROIDSDL) || defined(AMIBERRY) // Always give execute & read permission // Temporary do this for raspberry... aino->amigaos_mode &= ~A_FIBF_EXECUTE; diff --git a/src/osdep/amiberry_gui.cpp b/src/osdep/amiberry_gui.cpp index d5b77f70..03f10d17 100644 --- a/src/osdep/amiberry_gui.cpp +++ b/src/osdep/amiberry_gui.cpp @@ -22,7 +22,7 @@ #include "blkdev.h" #include -#ifdef RASPBERRY +#ifdef AMIBERRY #include #include #endif diff --git a/src/osdep/gui/PanelMisc.cpp b/src/osdep/gui/PanelMisc.cpp index 0fbab8cd..72c2f7da 100644 --- a/src/osdep/gui/PanelMisc.cpp +++ b/src/osdep/gui/PanelMisc.cpp @@ -27,7 +27,6 @@ static gcn::UaeDropDown* KeyForQuit; static gcn::Label* lblButtonForQuit; static gcn::UaeDropDown* ButtonForQuit; -#ifdef RASPBERRY class StringListModel : public gcn::ListModel { vector values; @@ -59,7 +58,6 @@ static gcn::UaeDropDown* cboKBDLed_scr; const char* listValues[] = {"none", "POWER", "DF0", "DF1", "DF2", "DF3", "DF*", "HD", "CD"}; StringListModel KBDLedList(listValues, 9); -#endif static const int ControlKey_SDLKeyValues[] = {0, SDL_SCANCODE_F11, SDL_SCANCODE_F12}; @@ -119,13 +117,11 @@ public: else if (actionEvent.getSource() == ButtonForQuit) changed_prefs.button_for_quit = ControlButton_SDLButtonValues[ButtonForQuit->getSelected()]; -#ifdef RASPBERRY else if (actionEvent.getSource() == cboKBDLed_num) changed_prefs.kbd_led_num = cboKBDLed_num->getSelected(); else if (actionEvent.getSource() == cboKBDLed_scr) changed_prefs.kbd_led_scr = cboKBDLed_scr->getSelected(); -#endif } }; @@ -249,12 +245,11 @@ void ExitPanelMisc() delete chkShowGUI; delete chkBSDSocket; -#ifdef RASPBERRY delete lblScrLock; delete lblNumLock; delete cboKBDLed_num; delete cboKBDLed_scr; -#endif + delete miscActionListener; delete lblKeyForMenu; delete KeyForMenu; @@ -272,12 +267,10 @@ void RefreshPanelMisc() chkStatusLine->setSelected(changed_prefs.leds_on_screen); chkShowGUI->setSelected(changed_prefs.start_gui); - chkBSDSocket->setSelected(changed_prefs.socket_emu); -#ifdef RASPBERRY cboKBDLed_num->setSelected(changed_prefs.kbd_led_num); cboKBDLed_scr->setSelected(changed_prefs.kbd_led_scr); -#endif + KeyForMenu->setSelected(GetControlKeyIndex(changed_prefs.key_for_menu)); KeyForQuit->setSelected(GetControlKeyIndex(changed_prefs.key_for_quit)); ButtonForMenu->setSelected(GetControlButtonIndex(changed_prefs.button_for_menu)); diff --git a/src/osdep/gui/SelectFile.cpp b/src/osdep/gui/SelectFile.cpp index cd19a8e8..42b721a2 100644 --- a/src/osdep/gui/SelectFile.cpp +++ b/src/osdep/gui/SelectFile.cpp @@ -18,7 +18,7 @@ #define DIALOG_WIDTH 520 #define DIALOG_HEIGHT 400 -#if defined(RASPBERRY) || defined(ANDROID) +#if defined(AMIBERRY) || defined(ANDROID) #define FILE_SELECT_KEEP_POSITION #endif diff --git a/src/osdep/menu/menu_config.cpp b/src/osdep/menu/menu_config.cpp index 137107f2..8e5e8211 100644 --- a/src/osdep/menu/menu_config.cpp +++ b/src/osdep/menu/menu_config.cpp @@ -423,7 +423,7 @@ int loadconfig_old(struct uae_prefs* p, const char* orgpath) int dummy; fscanf(f, "kickstart=%d\n", &kickstart); -#if defined(RASPBERRY) || defined(ANDROIDSDL) +#if defined(AMIBERRY) || defined(ANDROIDSDL) fscanf(f, "scaling=%d\n", &dummy); #else fscanf(f, "scaling=%d\n", &mainMenu_enableHWscaling); @@ -431,7 +431,7 @@ int loadconfig_old(struct uae_prefs* p, const char* orgpath) fscanf(f, "showstatus=%d\n", &p->leds_on_screen); fscanf(f, "mousemultiplier=%d\n", &p->input_joymouse_multiplier); p->input_joymouse_multiplier *= 10; -#if defined(RASPBERRY) || defined(ANDROIDSDL) +#if defined(AMIBERRY) || defined(ANDROIDSDL) fscanf(f, "systemclock=%d\n", &dummy); // mainMenu_throttle never changes -> removed fscanf(f, "syncthreshold=%d\n", &dummy); // timeslice_mode never changes -> removed #else diff --git a/src/osdep/picasso96.cpp b/src/osdep/picasso96.cpp index 73812995..02bc9292 100644 --- a/src/osdep/picasso96.cpp +++ b/src/osdep/picasso96.cpp @@ -30,15 +30,6 @@ * programs started from a Picasso workbench. */ -/* - * Note: This is the Pandora specific version of Picasso96: - * - only 16 bit color mode is available (R5G6B5) in hardware - * - we simulate R8G8B8A8 on Amiga side and use Neon-code to convert to R5G6B5 - * - we have no hardware sprite for mouse pointer - * I removed some code which handled unsupported modes and formats to make code - * easier to read. - */ - #include "sysconfig.h" #include "sysdeps.h" @@ -888,7 +879,7 @@ void picasso_handle_vsync() #define BLT_FUNC(s,d) *d = (*s) | (*d) #include "p96_blit.cpp" #define BLT_NAME BLIT_TRUE_32 -#ifdef RASPBERRY +#ifdef AMIBERRY #define BLT_FUNC(s,d) memset(d, 0xff, sizeof (*d)) #else #define BLT_FUNC(s,d) *d = 0xffffffff @@ -943,7 +934,7 @@ void picasso_handle_vsync() #define BLT_FUNC(s,d) *d = (*s) | (*d) #include "p96_blit.cpp" #define BLT_NAME BLIT_TRUE_24 -#ifdef RASPBERRY +#ifdef AMIBERRY #define BLT_FUNC(s,d) memset(d, 0xff, sizeof (*d)) #else #define BLT_FUNC(s,d) *d = 0xffffffff @@ -998,7 +989,7 @@ void picasso_handle_vsync() #define BLT_FUNC(s,d) *d = (*s) | (*d) #include "p96_blit.cpp" #define BLT_NAME BLIT_TRUE_16 -#ifdef RASPBERRY +#ifdef AMIBERRY #define BLT_FUNC(s,d) memset(d, 0xff, sizeof (*d)) #else #define BLT_FUNC(s,d) *d = 0xffffffff @@ -1053,7 +1044,7 @@ void picasso_handle_vsync() #define BLT_FUNC(s,d) *d = (*s) | (*d) #include "p96_blit.cpp" #define BLT_NAME BLIT_TRUE_8 -#ifdef RASPBERRY +#ifdef AMIBERRY #define BLT_FUNC(s,d) memset(d, 0xff, sizeof (*d)) #else #define BLT_FUNC(s,d) *d = 0xffffffff diff --git a/src/osdep/sysconfig.h b/src/osdep/sysconfig.h index 0ff32a43..ece93d65 100644 --- a/src/osdep/sysconfig.h +++ b/src/osdep/sysconfig.h @@ -36,7 +36,7 @@ #define CPUEMU_11 /* 68000+prefetch emulation */ /* #define CPUEMU_12 */ /* cycle-exact cpu&blitter */ /* #define ACTION_REPLAY */ /* Action Replay 1/2/3 support */ -/* #define PICASSO96 */ /* Picasso96 display card emulation */ +#define PICASSO96 /* Picasso96 display card emulation */ /* #define UAEGFX_INTERNAL */ /* built-in libs:picasso96/uaegfx.card */ #define BSDSOCKET /* bsdsocket.library emulation */ /* #define CAPS */ /* CAPS-image support */ diff --git a/src/sounddep/sound.cpp b/src/sounddep/sound.cpp deleted file mode 100644 index 1b2705fc..00000000 --- a/src/sounddep/sound.cpp +++ /dev/null @@ -1,317 +0,0 @@ - /* - * Minimalistic sound.c implementation for gp2x - * (c) notaz, 2007 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysconfig.h" -#include "sysdeps.h" -#include "uae.h" -#include "options.h" -#include "memory.h" -#include "newcpu.h" -#include "custom.h" -#include "audio.h" -#include "gensound.h" -#include "sd-pandora/sound.h" -#include "savestate.h" - - -uae_u16 sndbuffer[4][(SNDBUFFER_LEN+32)*DEFAULT_SOUND_CHANNELS]; -uae_u16 *sndbufpt = sndbuffer[0]; -uae_u16 *render_sndbuff = sndbuffer[0]; -uae_u16 *finish_sndbuff = sndbuffer[0] + SNDBUFFER_LEN*2; - -uae_u16 cdaudio_buffer[CDAUDIO_BUFFERS][(CDAUDIO_BUFFER_LEN + 32) * 2]; -uae_u16 *cdbufpt = cdaudio_buffer[0]; -uae_u16 *render_cdbuff = cdaudio_buffer[0]; -uae_u16 *finish_cdbuff = cdaudio_buffer[0] + CDAUDIO_BUFFER_LEN * 2; -bool cdaudio_active = false; -static int cdwrcnt = 0; -static int cdrdcnt = 0; - -static int have_sound = 0; -static int lastfreq; - -void update_sound (float clk) -{ - float evtime; - - evtime = clk * CYCLE_UNIT / (float)currprefs.sound_freq; - scaled_sample_evtime = (int)evtime; -} - - -static int sounddev = -1, s_oldrate = 0, s_oldbits = 0, s_oldstereo = 0; -static int sound_thread_active = 0, sound_thread_exit = 0; -static sem_t sound_sem; -static sem_t sound_out_sem; -static int output_cnt = 0; -static int wrcnt = 0; - -static void *sound_thread(void *unused) -{ - int cnt = 0, sem_val = 0; - sound_thread_active = 1; - - for (;;) - { - sem_getvalue(&sound_sem, &sem_val); - while (sem_val > 1) - { - sem_wait(&sound_sem); - sem_getvalue(&sound_sem, &sem_val); - } - - sem_wait(&sound_sem); - if (sound_thread_exit) - break; - - cnt = output_cnt; - sem_post(&sound_out_sem); - - if(currprefs.sound_stereo) { - if(cdaudio_active && currprefs.sound_freq == 44100 && cdrdcnt < cdwrcnt) { - for(int i=0; i 22050) { bsize*=4; buffers*=2; } // 44k mode seems to be very demanding - while ((bsize>>=1)) frag++; - frag |= buffers<<16; // 16 buffers - ioctl(sounddev, SNDCTL_DSP_SETFRAGMENT, &frag); - - s_oldrate = rate; - s_oldbits = bits; - s_oldstereo = stereo; - usleep(100000); - return 0; -} - - -// this is meant to be called only once on exit -void pandora_stop_sound(void) -{ - if (sound_thread_exit) - printf("don't call pandora_stop_sound more than once!\n"); - if (sound_thread_active) - { - sound_thread_exit = 1; - sem_post(&sound_sem); - sem_wait(&sound_out_sem); - sem_destroy(&sound_sem); - sem_destroy(&sound_out_sem); - } - - if (sounddev > 0) - close(sounddev); - sounddev = -1; -} - - -void finish_sound_buffer (void) -{ - output_cnt = wrcnt; - - sem_post(&sound_sem); - sem_wait(&sound_out_sem); - - wrcnt++; - sndbufpt = render_sndbuff = sndbuffer[wrcnt&3]; - if(currprefs.sound_stereo) - finish_sndbuff = sndbufpt + SNDBUFFER_LEN; - else - finish_sndbuff = sndbufpt + SNDBUFFER_LEN/2; -} - - -void pause_sound_buffer (void) -{ - reset_sound (); -} - - -void restart_sound_buffer(void) -{ - sndbufpt = render_sndbuff = sndbuffer[wrcnt&3]; - if(currprefs.sound_stereo) - finish_sndbuff = sndbufpt + SNDBUFFER_LEN; - else - finish_sndbuff = sndbufpt + SNDBUFFER_LEN/2; - - cdbufpt = render_cdbuff = cdaudio_buffer[cdwrcnt & (CDAUDIO_BUFFERS - 1)]; - finish_cdbuff = cdbufpt + CDAUDIO_BUFFER_LEN * 2; -} - - -void finish_cdaudio_buffer (void) -{ - cdwrcnt++; - cdbufpt = render_cdbuff = cdaudio_buffer[cdwrcnt & (CDAUDIO_BUFFERS - 1)]; - finish_cdbuff = cdbufpt + CDAUDIO_BUFFER_LEN; - audio_activate(); -} - - -bool cdaudio_catchup(void) -{ - while((cdwrcnt > cdrdcnt + CDAUDIO_BUFFERS - 10) && (sound_thread_active != 0) && (quit_program == 0)) { - sleep_millis(10); - } - return (sound_thread_active != 0); -} - - -/* Try to determine whether sound is available. This is only for GUI purposes. */ -int setup_sound (void) -{ - if (pandora_start_sound(currprefs.sound_freq, 16, currprefs.sound_stereo) != 0) - return 0; - - sound_available = 1; - return 1; -} - -static int open_sound (void) -{ - if (pandora_start_sound(currprefs.sound_freq, 16, currprefs.sound_stereo) != 0) - return 0; - - have_sound = 1; - sound_available = 1; - - if(currprefs.sound_stereo) - sample_handler = sample16s_handler; - else - sample_handler = sample16_handler; - - return 1; -} - -void close_sound (void) -{ - if (!have_sound) - return; - - // testing shows that reopenning sound device is not a good idea on pandora (causes random sound driver crashes) - // we will close it on real exit instead - //pandora_stop_sound(); - have_sound = 0; -} - -int init_sound (void) -{ - have_sound=open_sound(); - return have_sound; -} - -void pause_sound (void) -{ - /* nothing to do */ -} - -void resume_sound (void) -{ - /* nothing to do */ -} - -void reset_sound (void) -{ - if (!have_sound) - return; - - init_soundbuffer_usage(); - - clear_sound_buffers(); - clear_cdaudio_buffers(); -} - -void sound_volume (int dir) -{ -} diff --git a/src/sounddep/sound_sdl_new.cpp b/src/sounddep/sound_sdl_new.cpp index 9fc724e7..cf5c130c 100644 --- a/src/sounddep/sound_sdl_new.cpp +++ b/src/sounddep/sound_sdl_new.cpp @@ -384,7 +384,7 @@ void close_sound(void) // testing shows that reopenning sound device is not a good idea (causes random sound driver crashes) // we will close it on real exit instead -#ifdef RASPBERRY +#ifdef AMIBERRY //amiberry_stop_sound(); #endif have_sound = 0; From d8167087871d46877ecc3d0ab5af8bafa41ea521 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 31 Mar 2017 22:26:57 +0200 Subject: [PATCH 11/11] Added include paths and pre-processor defines for VSLinux solution --- .gitignore | 1 + VSLinux/Amiberry.vcxproj | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 7ca9e302..ee446735 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ VisualGDB/VisualGDB/Release/gencomp *.tlog VSLinux/obj/ARM/Debug/amiberry-sdl2-dev VisualGDB/VisualGDB/Debug/Amiberry-sdl2-dev +VSLinux/obj/ diff --git a/VSLinux/Amiberry.vcxproj b/VSLinux/Amiberry.vcxproj index c305cc2e..b7c29555 100644 --- a/VSLinux/Amiberry.vcxproj +++ b/VSLinux/Amiberry.vcxproj @@ -54,15 +54,17 @@ cd ~/projects/Amiberry-dev; make cd ~/projects/Amiberry-dev; make clean; make cd ~/projects/Amiberry-dev; make clean - D:\midwa\Projects\GitHub\amiberry\src\guisan\include;D:\midwa\Projects\GitHub\amiberry\src\include;D:\midwa\Projects\GitHub\amiberry\src\threaddep;D:\midwa\Projects\GitHub\amiberry\src\osdep;D:\midwa\Projects\GitHub\amiberry\src;$(NMakeIncludeSearchPath) - $(RemoteRootDir)/$(ProjectName)-dev + C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include\libxml2;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include\interface\vcos\pthreads;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include\interface\vmcs_host\linux;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include\SDL2;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\include\c++\4.9;C:\SysGCC\raspberry\lib\gcc\arm-linux-gnueabihf\4.9\include;D:\midwa\Projects\GitHub\amiberry\src\guisan\include;D:\midwa\Projects\GitHub\amiberry\src\threaddep;D:\midwa\Projects\GitHub\amiberry\src\osdep;D:\midwa\Projects\GitHub\amiberry\src;D:\midwa\Projects\GitHub\amiberry\src\include;$(NMakeIncludeSearchPath) + DEBUG;ARMV6T2;USE_ARMNEON;ARMV6_ASSEMBLY;AMIBERRY;CAPSLOCK_DEBIAN_WORKAROUND;ROM_PATH_PREFIX=\"./\";DATA_PREFIX=\"./data/\";SAVE_PREFIX=\"./saves/\";USE_SDL;_REENTRANT;$(NMakePreprocessorDefinitions) + $(RemoteRootDir)/$(ProjectName)-dev cd ~/projects/Amiberry-dev; make cd ~/projects/Amiberry-dev; make clean; make cd ~/projects/Amiberry-dev; make clean - D:\midwa\Projects\GitHub\amiberry\src\guisan\include;D:\midwa\Projects\GitHub\amiberry\src\include;D:\midwa\Projects\GitHub\amiberry\src\threaddep;D:\midwa\Projects\GitHub\amiberry\src\osdep;D:\midwa\Projects\GitHub\amiberry\src;$(NMakeIncludeSearchPath) - $(RemoteRootDir)/$(ProjectName)-dev + C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include\libxml2;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include\interface\vcos\pthreads;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include\interface\vmcs_host\linux;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\opt\vc\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include\SDL2;C:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\include;C:\SysGCC\raspberry\arm-linux-gnueabihf\include\c++\4.9;C:\SysGCC\raspberry\lib\gcc\arm-linux-gnueabihf\4.9\include;D:\midwa\Projects\GitHub\amiberry\src\guisan\include;D:\midwa\Projects\GitHub\amiberry\src\threaddep;D:\midwa\Projects\GitHub\amiberry\src\osdep;D:\midwa\Projects\GitHub\amiberry\src;D:\midwa\Projects\GitHub\amiberry\src\include;$(NMakeIncludeSearchPath) + ARMV6T2;USE_ARMNEON;ARMV6_ASSEMBLY;AMIBERRY;CAPSLOCK_DEBIAN_WORKAROUND;ROM_PATH_PREFIX=\"./\";DATA_PREFIX=\"./data/\";SAVE_PREFIX=\"./saves/\";USE_SDL;_REENTRANT;$(NMakePreprocessorDefinitions) + $(RemoteRootDir)/$(ProjectName)-dev