trunk/3rdparty/unittest-cpp/ChangeLog
|
r0 | r249095 | |
| 1 | Installation Instructions |
| 2 | ************************* |
| 3 | |
| 4 | Copyright (C) 1994-1996, 1999-2002, 2004-2012 Free Software Foundation, |
| 5 | Inc. |
| 6 | |
| 7 | Copying and distribution of this file, with or without modification, |
| 8 | are permitted in any medium without royalty provided the copyright |
| 9 | notice and this notice are preserved. This file is offered as-is, |
| 10 | without warranty of any kind. |
| 11 | |
| 12 | Basic Installation |
| 13 | ================== |
| 14 | |
| 15 | Briefly, the shell commands `./configure; make; make install' should |
| 16 | configure, build, and install this package. The following |
| 17 | more-detailed instructions are generic; see the `README' file for |
| 18 | instructions specific to this package. Some packages provide this |
| 19 | `INSTALL' file but do not implement all of the features documented |
| 20 | below. The lack of an optional feature in a given package is not |
| 21 | necessarily a bug. More recommendations for GNU packages can be found |
| 22 | in *note Makefile Conventions: (standards)Makefile Conventions. |
| 23 | |
| 24 | The `configure' shell script attempts to guess correct values for |
| 25 | various system-dependent variables used during compilation. It uses |
| 26 | those values to create a `Makefile' in each directory of the package. |
| 27 | It may also create one or more `.h' files containing system-dependent |
| 28 | definitions. Finally, it creates a shell script `config.status' that |
| 29 | you can run in the future to recreate the current configuration, and a |
| 30 | file `config.log' containing compiler output (useful mainly for |
| 31 | debugging `configure'). |
| 32 | |
| 33 | It can also use an optional file (typically called `config.cache' |
| 34 | and enabled with `--cache-file=config.cache' or simply `-C') that saves |
| 35 | the results of its tests to speed up reconfiguring. Caching is |
| 36 | disabled by default to prevent problems with accidental use of stale |
| 37 | cache files. |
| 38 | |
| 39 | If you need to do unusual things to compile the package, please try |
| 40 | to figure out how `configure' could check whether to do them, and mail |
| 41 | diffs or instructions to the address given in the `README' so they can |
| 42 | be considered for the next release. If you are using the cache, and at |
| 43 | some point `config.cache' contains results you don't want to keep, you |
| 44 | may remove or edit it. |
| 45 | |
| 46 | The file `configure.ac' (or `configure.in') is used to create |
| 47 | `configure' by a program called `autoconf'. You need `configure.ac' if |
| 48 | you want to change it or regenerate `configure' using a newer version |
| 49 | of `autoconf'. |
| 50 | |
| 51 | The simplest way to compile this package is: |
| 52 | |
| 53 | 1. `cd' to the directory containing the package's source code and type |
| 54 | `./configure' to configure the package for your system. |
| 55 | |
| 56 | Running `configure' might take a while. While running, it prints |
| 57 | some messages telling which features it is checking for. |
| 58 | |
| 59 | 2. Type `make' to compile the package. |
| 60 | |
| 61 | 3. Optionally, type `make check' to run any self-tests that come with |
| 62 | the package, generally using the just-built uninstalled binaries. |
| 63 | |
| 64 | 4. Type `make install' to install the programs and any data files and |
| 65 | documentation. When installing into a prefix owned by root, it is |
| 66 | recommended that the package be configured and built as a regular |
| 67 | user, and only the `make install' phase executed with root |
| 68 | privileges. |
| 69 | |
| 70 | 5. Optionally, type `make installcheck' to repeat any self-tests, but |
| 71 | this time using the binaries in their final installed location. |
| 72 | This target does not install anything. Running this target as a |
| 73 | regular user, particularly if the prior `make install' required |
| 74 | root privileges, verifies that the installation completed |
| 75 | correctly. |
| 76 | |
| 77 | 6. You can remove the program binaries and object files from the |
| 78 | source code directory by typing `make clean'. To also remove the |
| 79 | files that `configure' created (so you can compile the package for |
| 80 | a different kind of computer), type `make distclean'. There is |
| 81 | also a `make maintainer-clean' target, but that is intended mainly |
| 82 | for the package's developers. If you use it, you may have to get |
| 83 | all sorts of other programs in order to regenerate files that came |
| 84 | with the distribution. |
| 85 | |
| 86 | 7. Often, you can also type `make uninstall' to remove the installed |
| 87 | files again. In practice, not all packages have tested that |
| 88 | uninstallation works correctly, even though it is required by the |
| 89 | GNU Coding Standards. |
| 90 | |
| 91 | 8. Some packages, particularly those that use Automake, provide `make |
| 92 | distcheck', which can by used by developers to test that all other |
| 93 | targets like `make install' and `make uninstall' work correctly. |
| 94 | This target is generally not run by end users. |
| 95 | |
| 96 | Compilers and Options |
| 97 | ===================== |
| 98 | |
| 99 | Some systems require unusual options for compilation or linking that |
| 100 | the `configure' script does not know about. Run `./configure --help' |
| 101 | for details on some of the pertinent environment variables. |
| 102 | |
| 103 | You can give `configure' initial values for configuration parameters |
| 104 | by setting variables in the command line or in the environment. Here |
| 105 | is an example: |
| 106 | |
| 107 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix |
| 108 | |
| 109 | *Note Defining Variables::, for more details. |
| 110 | |
| 111 | Compiling For Multiple Architectures |
| 112 | ==================================== |
| 113 | |
| 114 | You can compile the package for more than one kind of computer at the |
| 115 | same time, by placing the object files for each architecture in their |
| 116 | own directory. To do this, you can use GNU `make'. `cd' to the |
| 117 | directory where you want the object files and executables to go and run |
| 118 | the `configure' script. `configure' automatically checks for the |
| 119 | source code in the directory that `configure' is in and in `..'. This |
| 120 | is known as a "VPATH" build. |
| 121 | |
| 122 | With a non-GNU `make', it is safer to compile the package for one |
| 123 | architecture at a time in the source code directory. After you have |
| 124 | installed the package for one architecture, use `make distclean' before |
| 125 | reconfiguring for another architecture. |
| 126 | |
| 127 | On MacOS X 10.5 and later systems, you can create libraries and |
| 128 | executables that work on multiple system types--known as "fat" or |
| 129 | "universal" binaries--by specifying multiple `-arch' options to the |
| 130 | compiler but only a single `-arch' option to the preprocessor. Like |
| 131 | this: |
| 132 | |
| 133 | ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ |
| 134 | CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ |
| 135 | CPP="gcc -E" CXXCPP="g++ -E" |
| 136 | |
| 137 | This is not guaranteed to produce working output in all cases, you |
| 138 | may have to build one architecture at a time and combine the results |
| 139 | using the `lipo' tool if you have problems. |
| 140 | |
| 141 | Installation Names |
| 142 | ================== |
| 143 | |
| 144 | By default, `make install' installs the package's commands under |
| 145 | `/usr/local/bin', include files under `/usr/local/include', etc. You |
| 146 | can specify an installation prefix other than `/usr/local' by giving |
| 147 | `configure' the option `--prefix=PREFIX', where PREFIX must be an |
| 148 | absolute file name. |
| 149 | |
| 150 | You can specify separate installation prefixes for |
| 151 | architecture-specific files and architecture-independent files. If you |
| 152 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses |
| 153 | PREFIX as the prefix for installing programs and libraries. |
| 154 | Documentation and other data files still use the regular prefix. |
| 155 | |
| 156 | In addition, if you use an unusual directory layout you can give |
| 157 | options like `--bindir=DIR' to specify different values for particular |
| 158 | kinds of files. Run `configure --help' for a list of the directories |
| 159 | you can set and what kinds of files go in them. In general, the |
| 160 | default for these options is expressed in terms of `${prefix}', so that |
| 161 | specifying just `--prefix' will affect all of the other directory |
| 162 | specifications that were not explicitly provided. |
| 163 | |
| 164 | The most portable way to affect installation locations is to pass the |
| 165 | correct locations to `configure'; however, many packages provide one or |
| 166 | both of the following shortcuts of passing variable assignments to the |
| 167 | `make install' command line to change installation locations without |
| 168 | having to reconfigure or recompile. |
| 169 | |
| 170 | The first method involves providing an override variable for each |
| 171 | affected directory. For example, `make install |
| 172 | prefix=/alternate/directory' will choose an alternate location for all |
| 173 | directory configuration variables that were expressed in terms of |
| 174 | `${prefix}'. Any directories that were specified during `configure', |
| 175 | but not in terms of `${prefix}', must each be overridden at install |
| 176 | time for the entire installation to be relocated. The approach of |
| 177 | makefile variable overrides for each directory variable is required by |
| 178 | the GNU Coding Standards, and ideally causes no recompilation. |
| 179 | However, some platforms have known limitations with the semantics of |
| 180 | shared libraries that end up requiring recompilation when using this |
| 181 | method, particularly noticeable in packages that use GNU Libtool. |
| 182 | |
| 183 | The second method involves providing the `DESTDIR' variable. For |
| 184 | example, `make install DESTDIR=/alternate/directory' will prepend |
| 185 | `/alternate/directory' before all installation names. The approach of |
| 186 | `DESTDIR' overrides is not required by the GNU Coding Standards, and |
| 187 | does not work on platforms that have drive letters. On the other hand, |
| 188 | it does better at avoiding recompilation issues, and works well even |
| 189 | when some directory options were not specified in terms of `${prefix}' |
| 190 | at `configure' time. |
| 191 | |
| 192 | Optional Features |
| 193 | ================= |
| 194 | |
| 195 | If the package supports it, you can cause programs to be installed |
| 196 | with an extra prefix or suffix on their names by giving `configure' the |
| 197 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. |
| 198 | |
| 199 | Some packages pay attention to `--enable-FEATURE' options to |
| 200 | `configure', where FEATURE indicates an optional part of the package. |
| 201 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE |
| 202 | is something like `gnu-as' or `x' (for the X Window System). The |
| 203 | `README' should mention any `--enable-' and `--with-' options that the |
| 204 | package recognizes. |
| 205 | |
| 206 | For packages that use the X Window System, `configure' can usually |
| 207 | find the X include and library files automatically, but if it doesn't, |
| 208 | you can use the `configure' options `--x-includes=DIR' and |
| 209 | `--x-libraries=DIR' to specify their locations. |
| 210 | |
| 211 | Some packages offer the ability to configure how verbose the |
| 212 | execution of `make' will be. For these packages, running `./configure |
| 213 | --enable-silent-rules' sets the default to minimal output, which can be |
| 214 | overridden with `make V=1'; while running `./configure |
| 215 | --disable-silent-rules' sets the default to verbose, which can be |
| 216 | overridden with `make V=0'. |
| 217 | |
| 218 | Particular systems |
| 219 | ================== |
| 220 | |
| 221 | On HP-UX, the default C compiler is not ANSI C compatible. If GNU |
| 222 | CC is not installed, it is recommended to use the following options in |
| 223 | order to use an ANSI C compiler: |
| 224 | |
| 225 | ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" |
| 226 | |
| 227 | and if that doesn't work, install pre-built binaries of GCC for HP-UX. |
| 228 | |
| 229 | HP-UX `make' updates targets which have the same time stamps as |
| 230 | their prerequisites, which makes it generally unusable when shipped |
| 231 | generated files such as `configure' are involved. Use GNU `make' |
| 232 | instead. |
| 233 | |
| 234 | On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot |
| 235 | parse its `<wchar.h>' header file. The option `-nodtk' can be used as |
| 236 | a workaround. If GNU CC is not installed, it is therefore recommended |
| 237 | to try |
| 238 | |
| 239 | ./configure CC="cc" |
| 240 | |
| 241 | and if that doesn't work, try |
| 242 | |
| 243 | ./configure CC="cc -nodtk" |
| 244 | |
| 245 | On Solaris, don't put `/usr/ucb' early in your `PATH'. This |
| 246 | directory contains several dysfunctional programs; working variants of |
| 247 | these programs are available in `/usr/bin'. So, if you need `/usr/ucb' |
| 248 | in your `PATH', put it _after_ `/usr/bin'. |
| 249 | |
| 250 | On Haiku, software installed for all users goes in `/boot/common', |
| 251 | not `/usr/local'. It is recommended to use the following options: |
| 252 | |
| 253 | ./configure --prefix=/boot/common |
| 254 | |
| 255 | Specifying the System Type |
| 256 | ========================== |
| 257 | |
| 258 | There may be some features `configure' cannot figure out |
| 259 | automatically, but needs to determine by the type of machine the package |
| 260 | will run on. Usually, assuming the package is built to be run on the |
| 261 | _same_ architectures, `configure' can figure that out, but if it prints |
| 262 | a message saying it cannot guess the machine type, give it the |
| 263 | `--build=TYPE' option. TYPE can either be a short name for the system |
| 264 | type, such as `sun4', or a canonical name which has the form: |
| 265 | |
| 266 | CPU-COMPANY-SYSTEM |
| 267 | |
| 268 | where SYSTEM can have one of these forms: |
| 269 | |
| 270 | OS |
| 271 | KERNEL-OS |
| 272 | |
| 273 | See the file `config.sub' for the possible values of each field. If |
| 274 | `config.sub' isn't included in this package, then this package doesn't |
| 275 | need to know the machine type. |
| 276 | |
| 277 | If you are _building_ compiler tools for cross-compiling, you should |
| 278 | use the option `--target=TYPE' to select the type of system they will |
| 279 | produce code for. |
| 280 | |
| 281 | If you want to _use_ a cross compiler, that generates code for a |
| 282 | platform different from the build platform, you should specify the |
| 283 | "host" platform (i.e., that on which the generated programs will |
| 284 | eventually be run) with `--host=TYPE'. |
| 285 | |
| 286 | Sharing Defaults |
| 287 | ================ |
| 288 | |
| 289 | If you want to set default values for `configure' scripts to share, |
| 290 | you can create a site shell script called `config.site' that gives |
| 291 | default values for variables like `CC', `cache_file', and `prefix'. |
| 292 | `configure' looks for `PREFIX/share/config.site' if it exists, then |
| 293 | `PREFIX/etc/config.site' if it exists. Or, you can set the |
| 294 | `CONFIG_SITE' environment variable to the location of the site script. |
| 295 | A warning: not all `configure' scripts look for a site script. |
| 296 | |
| 297 | Defining Variables |
| 298 | ================== |
| 299 | |
| 300 | Variables not defined in a site shell script can be set in the |
| 301 | environment passed to `configure'. However, some packages may run |
| 302 | configure again during the build, and the customized values of these |
| 303 | variables may be lost. In order to avoid this problem, you should set |
| 304 | them in the `configure' command line, using `VAR=value'. For example: |
| 305 | |
| 306 | ./configure CC=/usr/local2/bin/gcc |
| 307 | |
| 308 | causes the specified `gcc' to be used as the C compiler (unless it is |
| 309 | overridden in the site shell script). |
| 310 | |
| 311 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to |
| 312 | an Autoconf limitation. Until the limitation is lifted, you can use |
| 313 | this workaround: |
| 314 | |
| 315 | CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash |
| 316 | |
| 317 | `configure' Invocation |
| 318 | ====================== |
| 319 | |
| 320 | `configure' recognizes the following options to control how it |
| 321 | operates. |
| 322 | |
| 323 | `--help' |
| 324 | `-h' |
| 325 | Print a summary of all of the options to `configure', and exit. |
| 326 | |
| 327 | `--help=short' |
| 328 | `--help=recursive' |
| 329 | Print a summary of the options unique to this package's |
| 330 | `configure', and exit. The `short' variant lists options used |
| 331 | only in the top level, while the `recursive' variant lists options |
| 332 | also present in any nested packages. |
| 333 | |
| 334 | `--version' |
| 335 | `-V' |
| 336 | Print the version of Autoconf used to generate the `configure' |
| 337 | script, and exit. |
| 338 | |
| 339 | `--cache-file=FILE' |
| 340 | Enable the cache: use and save the results of the tests in FILE, |
| 341 | traditionally `config.cache'. FILE defaults to `/dev/null' to |
| 342 | disable caching. |
| 343 | |
| 344 | `--config-cache' |
| 345 | `-C' |
| 346 | Alias for `--cache-file=config.cache'. |
| 347 | |
| 348 | `--quiet' |
| 349 | `--silent' |
| 350 | `-q' |
| 351 | Do not print messages saying which checks are being made. To |
| 352 | suppress all normal output, redirect it to `/dev/null' (any error |
| 353 | messages will still be shown). |
| 354 | |
| 355 | `--srcdir=DIR' |
| 356 | Look for the package's source code in directory DIR. Usually |
| 357 | `configure' can determine that directory automatically. |
| 358 | |
| 359 | `--prefix=DIR' |
| 360 | Use DIR as the installation prefix. *note Installation Names:: |
| 361 | for more details, including other options available for fine-tuning |
| 362 | the installation locations. |
| 363 | |
| 364 | `--no-create' |
| 365 | `-n' |
| 366 | Run the configure checks, but stop before creating any output |
| 367 | files. |
| 368 | |
| 369 | `configure' also accepts some other, not widely useful, options. Run |
| 370 | `configure --help' for more details. |
trunk/3rdparty/unittest-cpp/tests/TestCheckMacros.cpp
r0 | r249095 | |
| 1 | #include "UnitTest++/UnitTestPP.h" |
| 2 | #include "UnitTest++/CurrentTest.h" |
| 3 | #include "RecordingReporter.h" |
| 4 | #include "ScopedCurrentTest.h" |
| 5 | |
| 6 | using namespace std; |
| 7 | |
| 8 | namespace { |
| 9 | |
| 10 | TEST(CheckSucceedsOnTrue) |
| 11 | { |
| 12 | bool failure = true; |
| 13 | { |
| 14 | RecordingReporter reporter; |
| 15 | UnitTest::TestResults testResults(&reporter); |
| 16 | |
| 17 | ScopedCurrentTest scopedResults(testResults); |
| 18 | CHECK(true); |
| 19 | |
| 20 | failure = (testResults.GetFailureCount() > 0); |
| 21 | } |
| 22 | |
| 23 | CHECK(!failure); |
| 24 | } |
| 25 | |
| 26 | TEST(CheckFailsOnFalse) |
| 27 | { |
| 28 | bool failure = false; |
| 29 | { |
| 30 | RecordingReporter reporter; |
| 31 | UnitTest::TestResults testResults(&reporter); |
| 32 | ScopedCurrentTest scopedResults(testResults); |
| 33 | CHECK(false); |
| 34 | failure = (testResults.GetFailureCount() > 0); |
| 35 | } |
| 36 | |
| 37 | CHECK(failure); |
| 38 | } |
| 39 | |
| 40 | TEST(FailureReportsCorrectTestName) |
| 41 | { |
| 42 | RecordingReporter reporter; |
| 43 | { |
| 44 | UnitTest::TestResults testResults(&reporter); |
| 45 | ScopedCurrentTest scopedResults(testResults); |
| 46 | CHECK(false); |
| 47 | } |
| 48 | |
| 49 | CHECK_EQUAL(m_details.testName, reporter.lastFailedTest); |
| 50 | } |
| 51 | |
| 52 | TEST(CheckFailureIncludesCheckContents) |
| 53 | { |
| 54 | RecordingReporter reporter; |
| 55 | { |
| 56 | UnitTest::TestResults testResults(&reporter); |
| 57 | ScopedCurrentTest scopedResults(testResults); |
| 58 | const bool yaddayadda = false; |
| 59 | CHECK(yaddayadda); |
| 60 | } |
| 61 | |
| 62 | CHECK(strstr(reporter.lastFailedMessage, "yaddayadda")); |
| 63 | } |
| 64 | |
| 65 | TEST(CheckEqualSucceedsOnEqual) |
| 66 | { |
| 67 | bool failure = true; |
| 68 | { |
| 69 | RecordingReporter reporter; |
| 70 | UnitTest::TestResults testResults(&reporter); |
| 71 | ScopedCurrentTest scopedResults(testResults); |
| 72 | CHECK_EQUAL(1, 1); |
| 73 | failure = (testResults.GetFailureCount() > 0); |
| 74 | } |
| 75 | |
| 76 | CHECK(!failure); |
| 77 | } |
| 78 | |
| 79 | TEST(CheckEqualFailsOnNotEqual) |
| 80 | { |
| 81 | bool failure = false; |
| 82 | { |
| 83 | RecordingReporter reporter; |
| 84 | UnitTest::TestResults testResults(&reporter); |
| 85 | ScopedCurrentTest scopedResults(testResults); |
| 86 | CHECK_EQUAL(1, 2); |
| 87 | failure = (testResults.GetFailureCount() > 0); |
| 88 | } |
| 89 | |
| 90 | CHECK(failure); |
| 91 | } |
| 92 | |
| 93 | TEST(CheckEqualFailureContainsCorrectDetails) |
| 94 | { |
| 95 | int line = 0; |
| 96 | RecordingReporter reporter; |
| 97 | { |
| 98 | UnitTest::TestResults testResults(&reporter); |
| 99 | UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1); |
| 100 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 101 | |
| 102 | CHECK_EQUAL(1, 123); line = __LINE__; |
| 103 | } |
| 104 | |
| 105 | CHECK_EQUAL("testName", reporter.lastFailedTest); |
| 106 | CHECK_EQUAL("suiteName", reporter.lastFailedSuite); |
| 107 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 108 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 109 | } |
| 110 | |
| 111 | int g_sideEffect = 0; |
| 112 | int FunctionWithSideEffects() |
| 113 | { |
| 114 | ++g_sideEffect; |
| 115 | return 1; |
| 116 | } |
| 117 | |
| 118 | TEST(CheckEqualDoesNotHaveSideEffectsWhenPassing) |
| 119 | { |
| 120 | g_sideEffect = 0; |
| 121 | { |
| 122 | UnitTest::TestResults testResults; |
| 123 | ScopedCurrentTest scopedResults(testResults); |
| 124 | CHECK_EQUAL(1, FunctionWithSideEffects()); |
| 125 | } |
| 126 | CHECK_EQUAL(1, g_sideEffect); |
| 127 | } |
| 128 | |
| 129 | TEST(CheckEqualDoesNotHaveSideEffectsWhenFailing) |
| 130 | { |
| 131 | g_sideEffect = 0; |
| 132 | { |
| 133 | UnitTest::TestResults testResults; |
| 134 | ScopedCurrentTest scopedResults(testResults); |
| 135 | CHECK_EQUAL(2, FunctionWithSideEffects()); |
| 136 | } |
| 137 | CHECK_EQUAL(1, g_sideEffect); |
| 138 | } |
| 139 | |
| 140 | |
| 141 | TEST(CheckCloseSucceedsOnEqual) |
| 142 | { |
| 143 | bool failure = true; |
| 144 | { |
| 145 | RecordingReporter reporter; |
| 146 | UnitTest::TestResults testResults(&reporter); |
| 147 | ScopedCurrentTest scopedResults(testResults); |
| 148 | CHECK_CLOSE (1.0f, 1.001f, 0.01f); |
| 149 | failure = (testResults.GetFailureCount() > 0); |
| 150 | } |
| 151 | |
| 152 | CHECK(!failure); |
| 153 | } |
| 154 | |
| 155 | TEST(CheckCloseFailsOnNotEqual) |
| 156 | { |
| 157 | bool failure = false; |
| 158 | { |
| 159 | RecordingReporter reporter; |
| 160 | UnitTest::TestResults testResults(&reporter); |
| 161 | ScopedCurrentTest scopedResults(testResults); |
| 162 | CHECK_CLOSE (1.0f, 1.1f, 0.01f); |
| 163 | failure = (testResults.GetFailureCount() > 0); |
| 164 | } |
| 165 | |
| 166 | CHECK(failure); |
| 167 | } |
| 168 | |
| 169 | TEST(CheckCloseFailureContainsCorrectDetails) |
| 170 | { |
| 171 | int line = 0; |
| 172 | RecordingReporter reporter; |
| 173 | { |
| 174 | UnitTest::TestResults testResults(&reporter); |
| 175 | UnitTest::TestDetails testDetails("test", "suite", "filename", -1); |
| 176 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 177 | |
| 178 | CHECK_CLOSE (1.0f, 1.1f, 0.01f); line = __LINE__; |
| 179 | } |
| 180 | |
| 181 | CHECK_EQUAL("test", reporter.lastFailedTest); |
| 182 | CHECK_EQUAL("suite", reporter.lastFailedSuite); |
| 183 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 184 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 185 | } |
| 186 | |
| 187 | TEST(CheckCloseDoesNotHaveSideEffectsWhenPassing) |
| 188 | { |
| 189 | g_sideEffect = 0; |
| 190 | { |
| 191 | UnitTest::TestResults testResults; |
| 192 | ScopedCurrentTest scopedResults(testResults); |
| 193 | CHECK_CLOSE (1, FunctionWithSideEffects(), 0.1f); |
| 194 | } |
| 195 | CHECK_EQUAL(1, g_sideEffect); |
| 196 | } |
| 197 | |
| 198 | TEST(CheckCloseDoesNotHaveSideEffectsWhenFailing) |
| 199 | { |
| 200 | g_sideEffect = 0; |
| 201 | { |
| 202 | UnitTest::TestResults testResults; |
| 203 | ScopedCurrentTest scopedResults(testResults); |
| 204 | CHECK_CLOSE (2, FunctionWithSideEffects(), 0.1f); |
| 205 | } |
| 206 | CHECK_EQUAL(1, g_sideEffect); |
| 207 | } |
| 208 | |
| 209 | TEST(CheckArrayCloseSucceedsOnEqual) |
| 210 | { |
| 211 | bool failure = true; |
| 212 | { |
| 213 | RecordingReporter reporter; |
| 214 | UnitTest::TestResults testResults(&reporter); |
| 215 | ScopedCurrentTest scopedResults(testResults); |
| 216 | const float data[4] = { 0, 1, 2, 3 }; |
| 217 | CHECK_ARRAY_CLOSE (data, data, 4, 0.01f); |
| 218 | failure = (testResults.GetFailureCount() > 0); |
| 219 | } |
| 220 | |
| 221 | CHECK(!failure); |
| 222 | } |
| 223 | |
| 224 | TEST(CheckArrayCloseFailsOnNotEqual) |
| 225 | { |
| 226 | bool failure = false; |
| 227 | { |
| 228 | RecordingReporter reporter; |
| 229 | UnitTest::TestResults testResults(&reporter); |
| 230 | ScopedCurrentTest scopedResults(testResults); |
| 231 | |
| 232 | int const data1[4] = { 0, 1, 2, 3 }; |
| 233 | int const data2[4] = { 0, 1, 3, 3 }; |
| 234 | CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); |
| 235 | |
| 236 | failure = (testResults.GetFailureCount() > 0); |
| 237 | } |
| 238 | |
| 239 | CHECK(failure); |
| 240 | } |
| 241 | |
| 242 | TEST(CheckArrayCloseFailureIncludesCheckExpectedAndActual) |
| 243 | { |
| 244 | RecordingReporter reporter; |
| 245 | { |
| 246 | UnitTest::TestResults testResults(&reporter); |
| 247 | ScopedCurrentTest scopedResults(testResults); |
| 248 | |
| 249 | int const data1[4] = { 0, 1, 2, 3 }; |
| 250 | int const data2[4] = { 0, 1, 3, 3 }; |
| 251 | CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); |
| 252 | } |
| 253 | |
| 254 | CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]")); |
| 255 | CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]")); |
| 256 | } |
| 257 | |
| 258 | TEST(CheckArrayCloseFailureContainsCorrectDetails) |
| 259 | { |
| 260 | int line = 0; |
| 261 | RecordingReporter reporter; |
| 262 | { |
| 263 | UnitTest::TestResults testResults(&reporter); |
| 264 | UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1); |
| 265 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 266 | |
| 267 | int const data1[4] = { 0, 1, 2, 3 }; |
| 268 | int const data2[4] = { 0, 1, 3, 3 }; |
| 269 | CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); line = __LINE__; |
| 270 | } |
| 271 | |
| 272 | CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); |
| 273 | CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); |
| 274 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 275 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 276 | } |
| 277 | |
| 278 | TEST(CheckArrayCloseFailureIncludesTolerance) |
| 279 | { |
| 280 | RecordingReporter reporter; |
| 281 | { |
| 282 | UnitTest::TestResults testResults(&reporter); |
| 283 | ScopedCurrentTest scopedResults(testResults); |
| 284 | |
| 285 | float const data1[4] = { 0, 1, 2, 3 }; |
| 286 | float const data2[4] = { 0, 1, 3, 3 }; |
| 287 | CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); |
| 288 | } |
| 289 | |
| 290 | CHECK(strstr(reporter.lastFailedMessage, "0.01")); |
| 291 | } |
| 292 | |
| 293 | TEST(CheckArrayEqualSuceedsOnEqual) |
| 294 | { |
| 295 | bool failure = true; |
| 296 | { |
| 297 | RecordingReporter reporter; |
| 298 | UnitTest::TestResults testResults(&reporter); |
| 299 | ScopedCurrentTest scopedResults(testResults); |
| 300 | |
| 301 | const float data[4] = { 0, 1, 2, 3 }; |
| 302 | CHECK_ARRAY_EQUAL (data, data, 4); |
| 303 | |
| 304 | failure = (testResults.GetFailureCount() > 0); |
| 305 | } |
| 306 | |
| 307 | CHECK(!failure); |
| 308 | } |
| 309 | |
| 310 | TEST(CheckArrayEqualFailsOnNotEqual) |
| 311 | { |
| 312 | bool failure = false; |
| 313 | { |
| 314 | RecordingReporter reporter; |
| 315 | UnitTest::TestResults testResults(&reporter); |
| 316 | ScopedCurrentTest scopedResults(testResults); |
| 317 | |
| 318 | int const data1[4] = { 0, 1, 2, 3 }; |
| 319 | int const data2[4] = { 0, 1, 3, 3 }; |
| 320 | CHECK_ARRAY_EQUAL (data1, data2, 4); |
| 321 | |
| 322 | failure = (testResults.GetFailureCount() > 0); |
| 323 | } |
| 324 | |
| 325 | CHECK(failure); |
| 326 | } |
| 327 | |
| 328 | TEST(CheckArrayEqualFailureIncludesCheckExpectedAndActual) |
| 329 | { |
| 330 | RecordingReporter reporter; |
| 331 | { |
| 332 | UnitTest::TestResults testResults(&reporter); |
| 333 | ScopedCurrentTest scopedResults(testResults); |
| 334 | |
| 335 | int const data1[4] = { 0, 1, 2, 3 }; |
| 336 | int const data2[4] = { 0, 1, 3, 3 }; |
| 337 | CHECK_ARRAY_EQUAL (data1, data2, 4); |
| 338 | } |
| 339 | |
| 340 | CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]")); |
| 341 | CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]")); |
| 342 | } |
| 343 | |
| 344 | TEST(CheckArrayEqualFailureContainsCorrectInfo) |
| 345 | { |
| 346 | int line = 0; |
| 347 | RecordingReporter reporter; |
| 348 | { |
| 349 | UnitTest::TestResults testResults(&reporter); |
| 350 | ScopedCurrentTest scopedResults(testResults); |
| 351 | |
| 352 | int const data1[4] = { 0, 1, 2, 3 }; |
| 353 | int const data2[4] = { 0, 1, 3, 3 }; |
| 354 | CHECK_ARRAY_EQUAL (data1, data2, 4); line = __LINE__; |
| 355 | } |
| 356 | |
| 357 | CHECK_EQUAL("CheckArrayEqualFailureContainsCorrectInfo", reporter.lastFailedTest); |
| 358 | CHECK_EQUAL(__FILE__, reporter.lastFailedFile); |
| 359 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 360 | } |
| 361 | |
| 362 | float const* FunctionWithSideEffects2() |
| 363 | { |
| 364 | ++g_sideEffect; |
| 365 | static float const data[] = {1,2,3,4}; |
| 366 | return data; |
| 367 | } |
| 368 | |
| 369 | TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenPassing) |
| 370 | { |
| 371 | g_sideEffect = 0; |
| 372 | { |
| 373 | UnitTest::TestResults testResults; |
| 374 | ScopedCurrentTest scopedResults(testResults); |
| 375 | |
| 376 | const float data[] = { 0, 1, 2, 3 }; |
| 377 | CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f); |
| 378 | } |
| 379 | CHECK_EQUAL(1, g_sideEffect); |
| 380 | } |
| 381 | |
| 382 | TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenFailing) |
| 383 | { |
| 384 | g_sideEffect = 0; |
| 385 | { |
| 386 | UnitTest::TestResults testResults; |
| 387 | ScopedCurrentTest scopedResults(testResults); |
| 388 | |
| 389 | const float data[] = { 0, 1, 3, 3 }; |
| 390 | CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f); |
| 391 | } |
| 392 | |
| 393 | CHECK_EQUAL(1, g_sideEffect); |
| 394 | } |
| 395 | |
| 396 | TEST(CheckArray2DCloseSucceedsOnEqual) |
| 397 | { |
| 398 | bool failure = true; |
| 399 | { |
| 400 | RecordingReporter reporter; |
| 401 | UnitTest::TestResults testResults(&reporter); |
| 402 | ScopedCurrentTest scopedResults(testResults); |
| 403 | |
| 404 | const float data[2][2] = { {0, 1}, {2, 3} }; |
| 405 | CHECK_ARRAY2D_CLOSE (data, data, 2, 2, 0.01f); |
| 406 | |
| 407 | failure = (testResults.GetFailureCount() > 0); |
| 408 | } |
| 409 | |
| 410 | CHECK(!failure); |
| 411 | } |
| 412 | |
| 413 | TEST(CheckArray2DCloseFailsOnNotEqual) |
| 414 | { |
| 415 | bool failure = false; |
| 416 | { |
| 417 | RecordingReporter reporter; |
| 418 | UnitTest::TestResults testResults(&reporter); |
| 419 | ScopedCurrentTest scopedResults(testResults); |
| 420 | |
| 421 | int const data1[2][2] = { {0, 1}, {2, 3} }; |
| 422 | int const data2[2][2] = { {0, 1}, {3, 3} }; |
| 423 | CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); |
| 424 | |
| 425 | failure = (testResults.GetFailureCount() > 0); |
| 426 | } |
| 427 | |
| 428 | CHECK(failure); |
| 429 | } |
| 430 | |
| 431 | TEST(CheckArray2DCloseFailureIncludesCheckExpectedAndActual) |
| 432 | { |
| 433 | RecordingReporter reporter; |
| 434 | { |
| 435 | UnitTest::TestResults testResults(&reporter); |
| 436 | ScopedCurrentTest scopedResults(testResults); |
| 437 | |
| 438 | int const data1[2][2] = { {0, 1}, {2, 3} }; |
| 439 | int const data2[2][2] = { {0, 1}, {3, 3} }; |
| 440 | |
| 441 | CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); |
| 442 | } |
| 443 | |
| 444 | CHECK(strstr(reporter.lastFailedMessage, "xpected [ [ 0 1 ] [ 2 3 ] ]")); |
| 445 | CHECK(strstr(reporter.lastFailedMessage, "was [ [ 0 1 ] [ 3 3 ] ]")); |
| 446 | } |
| 447 | |
| 448 | TEST(CheckArray2DCloseFailureContainsCorrectDetails) |
| 449 | { |
| 450 | int line = 0; |
| 451 | RecordingReporter reporter; |
| 452 | { |
| 453 | UnitTest::TestResults testResults(&reporter); |
| 454 | UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1); |
| 455 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 456 | |
| 457 | int const data1[2][2] = { {0, 1}, {2, 3} }; |
| 458 | int const data2[2][2] = { {0, 1}, {3, 3} }; |
| 459 | CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); line = __LINE__; |
| 460 | } |
| 461 | |
| 462 | CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); |
| 463 | CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); |
| 464 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 465 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 466 | } |
| 467 | |
| 468 | TEST(CheckArray2DCloseFailureIncludesTolerance) |
| 469 | { |
| 470 | RecordingReporter reporter; |
| 471 | { |
| 472 | UnitTest::TestResults testResults(&reporter); |
| 473 | ScopedCurrentTest scopedResults(testResults); |
| 474 | |
| 475 | float const data1[2][2] = { {0, 1}, {2, 3} }; |
| 476 | float const data2[2][2] = { {0, 1}, {3, 3} }; |
| 477 | CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); |
| 478 | } |
| 479 | |
| 480 | CHECK(strstr(reporter.lastFailedMessage, "0.01")); |
| 481 | } |
| 482 | |
| 483 | float const* const* FunctionWithSideEffects3() |
| 484 | { |
| 485 | ++g_sideEffect; |
| 486 | static float const data1[] = {0,1}; |
| 487 | static float const data2[] = {2,3}; |
| 488 | static const float* const data[] = {data1, data2}; |
| 489 | return data; |
| 490 | } |
| 491 | |
| 492 | TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenPassing) |
| 493 | { |
| 494 | g_sideEffect = 0; |
| 495 | { |
| 496 | UnitTest::TestResults testResults; |
| 497 | ScopedCurrentTest scopedResults(testResults); |
| 498 | |
| 499 | const float data[2][2] = { {0, 1}, {2, 3} }; |
| 500 | CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f); |
| 501 | } |
| 502 | CHECK_EQUAL(1, g_sideEffect); |
| 503 | } |
| 504 | |
| 505 | TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenFailing) |
| 506 | { |
| 507 | g_sideEffect = 0; |
| 508 | { |
| 509 | UnitTest::TestResults testResults; |
| 510 | ScopedCurrentTest scopedResults(testResults); |
| 511 | |
| 512 | const float data[2][2] = { {0, 1}, {3, 3} }; |
| 513 | CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f); |
| 514 | } |
| 515 | CHECK_EQUAL(1, g_sideEffect); |
| 516 | } |
| 517 | |
| 518 | } |
trunk/3rdparty/unittest-cpp/tests/TestChecks.cpp
r0 | r249095 | |
| 1 | #include "UnitTest++/UnitTestPP.h" |
| 2 | #include "RecordingReporter.h" |
| 3 | |
| 4 | #include <cstring> |
| 5 | |
| 6 | using namespace UnitTest; |
| 7 | |
| 8 | |
| 9 | namespace { |
| 10 | |
| 11 | |
| 12 | TEST(CheckEqualWithUnsignedLong) |
| 13 | { |
| 14 | TestResults results; |
| 15 | unsigned long something = 2; |
| 16 | CHECK_EQUAL(something, something); |
| 17 | } |
| 18 | |
| 19 | TEST(CheckEqualsWithStringsFailsOnDifferentStrings) |
| 20 | { |
| 21 | char txt1[] = "Hello"; |
| 22 | char txt2[] = "Hallo"; |
| 23 | TestResults results; |
| 24 | CheckEqual(results, txt1, txt2, TestDetails("", "", "", 0)); |
| 25 | CHECK_EQUAL(1, results.GetFailureCount()); |
| 26 | } |
| 27 | |
| 28 | char txt1[] = "Hello"; // non-const on purpose so no folding of duplicate data |
| 29 | char txt2[] = "Hello"; |
| 30 | |
| 31 | TEST(CheckEqualsWithStringsWorksOnContentsNonConstNonConst) |
| 32 | { |
| 33 | char const* const p1 = txt1; |
| 34 | char const* const p2 = txt2; |
| 35 | TestResults results; |
| 36 | CheckEqual(results, p1, p2, TestDetails("", "", "", 0)); |
| 37 | CHECK_EQUAL(0, results.GetFailureCount()); |
| 38 | } |
| 39 | |
| 40 | TEST(CheckEqualsWithStringsWorksOnContentsConstConst) |
| 41 | { |
| 42 | char* const p1 = txt1; |
| 43 | char* const p2 = txt2; |
| 44 | TestResults results; |
| 45 | CheckEqual(results, p1, p2, TestDetails("", "", "", 0)); |
| 46 | CHECK_EQUAL(0, results.GetFailureCount()); |
| 47 | } |
| 48 | |
| 49 | TEST(CheckEqualsWithStringsWorksOnContentsNonConstConst) |
| 50 | { |
| 51 | char* const p1 = txt1; |
| 52 | char const* const p2 = txt2; |
| 53 | TestResults results; |
| 54 | CheckEqual(results, p1, p2, TestDetails("", "", "", 0)); |
| 55 | CHECK_EQUAL(0, results.GetFailureCount()); |
| 56 | } |
| 57 | |
| 58 | TEST(CheckEqualsWithStringsWorksOnContentsConstNonConst) |
| 59 | { |
| 60 | char const* const p1 = txt1; |
| 61 | char* const p2 = txt2; |
| 62 | TestResults results; |
| 63 | CheckEqual(results, p1, p2, TestDetails("", "", "", 0)); |
| 64 | CHECK_EQUAL(0, results.GetFailureCount()); |
| 65 | } |
| 66 | |
| 67 | TEST(CheckEqualsWithStringsWorksOnContentsWithALiteral) |
| 68 | { |
| 69 | char const* const p1 = txt1; |
| 70 | TestResults results; |
| 71 | CheckEqual(results, "Hello", p1, TestDetails("", "", "", 0)); |
| 72 | CHECK_EQUAL(0, results.GetFailureCount()); |
| 73 | } |
| 74 | |
| 75 | TEST(CheckEqualsWithStringsWorksOnNullExpected) |
| 76 | { |
| 77 | char const* const expected = "hi"; |
| 78 | char const* const actual = NULL; |
| 79 | TestResults results; |
| 80 | CheckEqual(results, expected, actual, TestDetails("", "", "", 0)); |
| 81 | CHECK_EQUAL (1, results.GetFailureCount()); |
| 82 | } |
| 83 | |
| 84 | TEST(CheckEqualsWithStringsWorksOnNullActual) |
| 85 | { |
| 86 | char const* const expected = NULL; |
| 87 | char const* const actual = "hi"; |
| 88 | TestResults results; |
| 89 | CheckEqual(results, expected, actual, TestDetails("", "", "", 0)); |
| 90 | CHECK_EQUAL (1, results.GetFailureCount()); |
| 91 | } |
| 92 | |
| 93 | TEST(CheckEqualsWithStringsWorksOnNullExpectedAndActual) |
| 94 | { |
| 95 | char const* const expected = NULL; |
| 96 | char const* const actual = NULL; |
| 97 | TestResults results; |
| 98 | CheckEqual(results, expected, actual, TestDetails("", "", "", 0)); |
| 99 | CHECK_EQUAL (0, results.GetFailureCount()); |
| 100 | } |
| 101 | |
| 102 | TEST(CheckEqualFailureIncludesCheckExpectedAndActual) |
| 103 | { |
| 104 | RecordingReporter reporter; |
| 105 | TestResults results(&reporter); |
| 106 | const int something = 2; |
| 107 | CheckEqual(results, 1, something, TestDetails("", "", "", 0)); |
| 108 | |
| 109 | using namespace std; |
| 110 | CHECK(strstr(reporter.lastFailedMessage, "xpected 1")); |
| 111 | CHECK(strstr(reporter.lastFailedMessage, "was 2")); |
| 112 | } |
| 113 | |
| 114 | TEST(CheckEqualFailureIncludesDetails) |
| 115 | { |
| 116 | RecordingReporter reporter; |
| 117 | TestResults results(&reporter); |
| 118 | TestDetails const details("mytest", "mysuite", "file.h", 101); |
| 119 | |
| 120 | CheckEqual(results, 1, 2, details); |
| 121 | |
| 122 | CHECK_EQUAL("mytest", reporter.lastFailedTest); |
| 123 | CHECK_EQUAL("mysuite", reporter.lastFailedSuite); |
| 124 | CHECK_EQUAL("file.h", reporter.lastFailedFile); |
| 125 | CHECK_EQUAL(101, reporter.lastFailedLine); |
| 126 | } |
| 127 | |
| 128 | TEST(CheckCloseTrue) |
| 129 | { |
| 130 | TestResults results; |
| 131 | CheckClose(results, 3.001f, 3.0f, 0.1f, TestDetails("", "", "", 0)); |
| 132 | CHECK_EQUAL(0, results.GetFailureCount()); |
| 133 | } |
| 134 | |
| 135 | TEST(CheckCloseFalse) |
| 136 | { |
| 137 | TestResults results; |
| 138 | CheckClose(results, 3.12f, 3.0f, 0.1f, TestDetails("", "", "", 0)); |
| 139 | CHECK_EQUAL(1, results.GetFailureCount()); |
| 140 | } |
| 141 | |
| 142 | TEST(CheckCloseWithZeroEpsilonWorksForSameNumber) |
| 143 | { |
| 144 | TestResults results; |
| 145 | CheckClose(results, 0.1f, 0.1f, 0, TestDetails("", "", "", 0)); |
| 146 | CHECK_EQUAL(0, results.GetFailureCount()); |
| 147 | } |
| 148 | |
| 149 | TEST(CheckCloseWithNaNFails) |
| 150 | { |
| 151 | const unsigned int bitpattern = 0xFFFFFFFF; |
| 152 | float nan; |
| 153 | UNIITEST_NS_QUAL_STD(memcpy)(&nan, &bitpattern, sizeof(bitpattern)); |
| 154 | |
| 155 | TestResults results; |
| 156 | CheckClose(results, 3.0f, nan, 0.1f, TestDetails("", "", "", 0)); |
| 157 | CHECK_EQUAL(1, results.GetFailureCount()); |
| 158 | } |
| 159 | |
| 160 | TEST(CheckCloseWithNaNAgainstItselfFails) |
| 161 | { |
| 162 | const unsigned int bitpattern = 0xFFFFFFFF; |
| 163 | float nan; |
| 164 | UNIITEST_NS_QUAL_STD(memcpy)(&nan, &bitpattern, sizeof(bitpattern)); |
| 165 | |
| 166 | TestResults results; |
| 167 | CheckClose(results, nan, nan, 0.1f, TestDetails("", "", "", 0)); |
| 168 | CHECK_EQUAL(1, results.GetFailureCount()); |
| 169 | } |
| 170 | |
| 171 | TEST(CheckCloseFailureIncludesCheckExpectedAndActual) |
| 172 | { |
| 173 | RecordingReporter reporter; |
| 174 | TestResults results(&reporter); |
| 175 | const float expected = 0.9f; |
| 176 | const float actual = 1.1f; |
| 177 | CheckClose(results, expected, actual, 0.01f, TestDetails("", "", "", 0)); |
| 178 | |
| 179 | using namespace std; |
| 180 | CHECK(strstr(reporter.lastFailedMessage, "xpected 0.9")); |
| 181 | CHECK(strstr(reporter.lastFailedMessage, "was 1.1")); |
| 182 | } |
| 183 | |
| 184 | TEST(CheckCloseFailureIncludesTolerance) |
| 185 | { |
| 186 | RecordingReporter reporter; |
| 187 | TestResults results(&reporter); |
| 188 | CheckClose(results, 2, 3, 0.01f, TestDetails("", "", "", 0)); |
| 189 | |
| 190 | using namespace std; |
| 191 | CHECK(strstr(reporter.lastFailedMessage, "0.01")); |
| 192 | } |
| 193 | |
| 194 | TEST(CheckCloseFailureIncludesDetails) |
| 195 | { |
| 196 | RecordingReporter reporter; |
| 197 | TestResults results(&reporter); |
| 198 | TestDetails const details("mytest", "mysuite", "header.h", 10); |
| 199 | |
| 200 | CheckClose(results, 2, 3, 0.01f, details); |
| 201 | |
| 202 | CHECK_EQUAL("mytest", reporter.lastFailedTest); |
| 203 | CHECK_EQUAL("mysuite", reporter.lastFailedSuite); |
| 204 | CHECK_EQUAL("header.h", reporter.lastFailedFile); |
| 205 | CHECK_EQUAL(10, reporter.lastFailedLine); |
| 206 | } |
| 207 | |
| 208 | |
| 209 | TEST(CheckArrayEqualTrue) |
| 210 | { |
| 211 | TestResults results; |
| 212 | |
| 213 | int const array[3] = { 1, 2, 3 }; |
| 214 | CheckArrayEqual(results, array, array, 3, TestDetails("", "", "", 0)); |
| 215 | CHECK_EQUAL(0, results.GetFailureCount()); |
| 216 | } |
| 217 | |
| 218 | TEST(CheckArrayEqualFalse) |
| 219 | { |
| 220 | TestResults results; |
| 221 | |
| 222 | int const array1[3] = { 1, 2, 3 }; |
| 223 | int const array2[3] = { 1, 2, 2 }; |
| 224 | CheckArrayEqual(results, array1, array2, 3, TestDetails("", "", "", 0)); |
| 225 | CHECK_EQUAL(1, results.GetFailureCount()); |
| 226 | } |
| 227 | |
| 228 | TEST(CheckArrayCloseTrue) |
| 229 | { |
| 230 | TestResults results; |
| 231 | |
| 232 | float const array1[3] = { 1.0f, 1.5f, 2.0f }; |
| 233 | float const array2[3] = { 1.01f, 1.51f, 2.01f }; |
| 234 | CheckArrayClose(results, array1, array2, 3, 0.02f, TestDetails("", "", "", 0)); |
| 235 | CHECK_EQUAL(0, results.GetFailureCount()); |
| 236 | } |
| 237 | |
| 238 | TEST(CheckArrayCloseFalse) |
| 239 | { |
| 240 | TestResults results; |
| 241 | |
| 242 | float const array1[3] = { 1.0f, 1.5f, 2.0f }; |
| 243 | float const array2[3] = { 1.01f, 1.51f, 2.01f }; |
| 244 | CheckArrayClose(results, array1, array2, 3, 0.001f, TestDetails("", "", "", 0)); |
| 245 | CHECK_EQUAL(1, results.GetFailureCount()); |
| 246 | } |
| 247 | |
| 248 | TEST(CheckArrayCloseFailureIncludesDetails) |
| 249 | { |
| 250 | RecordingReporter reporter; |
| 251 | TestResults results(&reporter); |
| 252 | TestDetails const details("arrayCloseTest", "arrayCloseSuite", "file", 1337); |
| 253 | |
| 254 | float const array1[3] = { 1.0f, 1.5f, 2.0f }; |
| 255 | float const array2[3] = { 1.01f, 1.51f, 2.01f }; |
| 256 | CheckArrayClose(results, array1, array2, 3, 0.001f, details); |
| 257 | |
| 258 | CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); |
| 259 | CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); |
| 260 | CHECK_EQUAL("file", reporter.lastFailedFile); |
| 261 | CHECK_EQUAL(1337, reporter.lastFailedLine); |
| 262 | } |
| 263 | |
| 264 | |
| 265 | TEST(CheckArray2DCloseTrue) |
| 266 | { |
| 267 | TestResults results; |
| 268 | |
| 269 | float const array1[3][3] = { { 1.0f, 1.5f, 2.0f }, |
| 270 | { 2.0f, 2.5f, 3.0f }, |
| 271 | { 3.0f, 3.5f, 4.0f } }; |
| 272 | float const array2[3][3] = { { 1.01f, 1.51f, 2.01f }, |
| 273 | { 2.01f, 2.51f, 3.01f }, |
| 274 | { 3.01f, 3.51f, 4.01f } }; |
| 275 | CheckArray2DClose(results, array1, array2, 3, 3, 0.02f, TestDetails("", "", "", 0)); |
| 276 | CHECK_EQUAL(0, results.GetFailureCount()); |
| 277 | } |
| 278 | |
| 279 | TEST(CheckArray2DCloseFalse) |
| 280 | { |
| 281 | TestResults results; |
| 282 | |
| 283 | float const array1[3][3] = { { 1.0f, 1.5f, 2.0f }, |
| 284 | { 2.0f, 2.5f, 3.0f }, |
| 285 | { 3.0f, 3.5f, 4.0f } }; |
| 286 | float const array2[3][3] = { { 1.01f, 1.51f, 2.01f }, |
| 287 | { 2.01f, 2.51f, 3.01f }, |
| 288 | { 3.01f, 3.51f, 4.01f } }; |
| 289 | CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, TestDetails("", "", "", 0)); |
| 290 | CHECK_EQUAL(1, results.GetFailureCount()); |
| 291 | } |
| 292 | |
| 293 | TEST(CheckCloseWithDoublesSucceeds) |
| 294 | { |
| 295 | CHECK_CLOSE(0.5, 0.5, 0.0001); |
| 296 | } |
| 297 | |
| 298 | TEST(CheckArray2DCloseFailureIncludesDetails) |
| 299 | { |
| 300 | RecordingReporter reporter; |
| 301 | TestResults results(&reporter); |
| 302 | TestDetails const details("array2DCloseTest", "array2DCloseSuite", "file", 1234); |
| 303 | |
| 304 | float const array1[3][3] = { { 1.0f, 1.5f, 2.0f }, |
| 305 | { 2.0f, 2.5f, 3.0f }, |
| 306 | { 3.0f, 3.5f, 4.0f } }; |
| 307 | float const array2[3][3] = { { 1.01f, 1.51f, 2.01f }, |
| 308 | { 2.01f, 2.51f, 3.01f }, |
| 309 | { 3.01f, 3.51f, 4.01f } }; |
| 310 | CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, details); |
| 311 | |
| 312 | CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); |
| 313 | CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); |
| 314 | CHECK_EQUAL("file", reporter.lastFailedFile); |
| 315 | CHECK_EQUAL(1234, reporter.lastFailedLine); |
| 316 | } |
| 317 | |
| 318 | } |
trunk/3rdparty/unittest-cpp/tests/TestExceptions.cpp
r0 | r249095 | |
| 1 | #include "UnitTest++/Config.h" |
| 2 | #ifndef UNITTEST_NO_EXCEPTIONS |
| 3 | |
| 4 | #include "UnitTest++/UnitTestPP.h" |
| 5 | #include "UnitTest++/CurrentTest.h" |
| 6 | #include "RecordingReporter.h" |
| 7 | #include "ScopedCurrentTest.h" |
| 8 | |
| 9 | #include <stdexcept> |
| 10 | |
| 11 | using namespace std; |
| 12 | |
| 13 | namespace { |
| 14 | |
| 15 | int ThrowingFunction() |
| 16 | { |
| 17 | throw "Doh"; |
| 18 | } |
| 19 | |
| 20 | int ThrowingStdExceptionFunction() |
| 21 | { |
| 22 | throw std::logic_error("Doh"); |
| 23 | } |
| 24 | |
| 25 | SUITE(CheckExceptionTests) |
| 26 | { |
| 27 | struct CheckFixture |
| 28 | { |
| 29 | CheckFixture() |
| 30 | : reporter() |
| 31 | , testResults(&reporter) |
| 32 | { |
| 33 | } |
| 34 | |
| 35 | void PerformCheckWithNonStdThrow() |
| 36 | { |
| 37 | ScopedCurrentTest scopedResults(testResults); |
| 38 | CHECK(ThrowingFunction() == 1); |
| 39 | } |
| 40 | |
| 41 | void PerformCheckWithStdThrow() |
| 42 | { |
| 43 | ScopedCurrentTest scopedResults(testResults); |
| 44 | CHECK(ThrowingStdExceptionFunction() == 1); |
| 45 | } |
| 46 | |
| 47 | RecordingReporter reporter; |
| 48 | UnitTest::TestResults testResults; |
| 49 | }; |
| 50 | |
| 51 | TEST_FIXTURE(CheckFixture, CheckFailsOnException) |
| 52 | { |
| 53 | PerformCheckWithNonStdThrow(); |
| 54 | CHECK(testResults.GetFailureCount() > 0); |
| 55 | } |
| 56 | |
| 57 | TEST_FIXTURE(CheckFixture, CheckFailsOnStdException) |
| 58 | { |
| 59 | PerformCheckWithStdThrow(); |
| 60 | CHECK(testResults.GetFailureCount() > 0); |
| 61 | } |
| 62 | |
| 63 | TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfExceptionIncludesCheckContents) |
| 64 | { |
| 65 | PerformCheckWithNonStdThrow(); |
| 66 | CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction() == 1")); |
| 67 | } |
| 68 | |
| 69 | TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfStdExceptionIncludesCheckContents) |
| 70 | { |
| 71 | PerformCheckWithStdThrow(); |
| 72 | CHECK(strstr(reporter.lastFailedMessage, "ThrowingStdExceptionFunction() == 1")); |
| 73 | } |
| 74 | |
| 75 | TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfStandardExceptionIncludesWhat) |
| 76 | { |
| 77 | PerformCheckWithStdThrow(); |
| 78 | CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)")); |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | SUITE(CheckEqualExceptionTests) |
| 83 | { |
| 84 | struct CheckEqualFixture |
| 85 | { |
| 86 | CheckEqualFixture() |
| 87 | : reporter() |
| 88 | , testResults(&reporter) |
| 89 | , line(-1) |
| 90 | { |
| 91 | } |
| 92 | |
| 93 | void PerformCheckWithNonStdThrow() |
| 94 | { |
| 95 | UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1); |
| 96 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 97 | CHECK_EQUAL(ThrowingFunction(), 123); line = __LINE__; |
| 98 | } |
| 99 | |
| 100 | void PerformCheckWithStdThrow() |
| 101 | { |
| 102 | UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1); |
| 103 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 104 | CHECK_EQUAL(ThrowingStdExceptionFunction(), 123); line = __LINE__; |
| 105 | } |
| 106 | |
| 107 | RecordingReporter reporter; |
| 108 | UnitTest::TestResults testResults; |
| 109 | int line; |
| 110 | }; |
| 111 | |
| 112 | TEST_FIXTURE(CheckEqualFixture, CheckEqualFailsOnException) |
| 113 | { |
| 114 | PerformCheckWithNonStdThrow(); |
| 115 | CHECK(testResults.GetFailureCount() > 0); |
| 116 | } |
| 117 | |
| 118 | TEST_FIXTURE(CheckEqualFixture, CheckEqualFailsOnStdException) |
| 119 | { |
| 120 | PerformCheckWithStdThrow(); |
| 121 | CHECK(testResults.GetFailureCount() > 0); |
| 122 | } |
| 123 | |
| 124 | TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfExceptionContainsCorrectDetails) |
| 125 | { |
| 126 | PerformCheckWithNonStdThrow(); |
| 127 | |
| 128 | CHECK_EQUAL("testName", reporter.lastFailedTest); |
| 129 | CHECK_EQUAL("suiteName", reporter.lastFailedSuite); |
| 130 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 131 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 132 | } |
| 133 | |
| 134 | TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfStdExceptionContainsCorrectDetails) |
| 135 | { |
| 136 | PerformCheckWithStdThrow(); |
| 137 | |
| 138 | CHECK_EQUAL("testName", reporter.lastFailedTest); |
| 139 | CHECK_EQUAL("suiteName", reporter.lastFailedSuite); |
| 140 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 141 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 142 | } |
| 143 | |
| 144 | TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfExceptionIncludesCheckContents) |
| 145 | { |
| 146 | PerformCheckWithNonStdThrow(); |
| 147 | |
| 148 | CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction()")); |
| 149 | CHECK(strstr(reporter.lastFailedMessage, "123")); |
| 150 | } |
| 151 | |
| 152 | TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfStdExceptionIncludesCheckContents) |
| 153 | { |
| 154 | PerformCheckWithStdThrow(); |
| 155 | |
| 156 | CHECK(strstr(reporter.lastFailedMessage, "ThrowingStdExceptionFunction()")); |
| 157 | CHECK(strstr(reporter.lastFailedMessage, "123")); |
| 158 | } |
| 159 | |
| 160 | TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfStandardExceptionIncludesWhat) |
| 161 | { |
| 162 | PerformCheckWithStdThrow(); |
| 163 | |
| 164 | CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)")); |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | SUITE(CheckCloseExceptionTests) |
| 169 | { |
| 170 | struct CheckCloseFixture |
| 171 | { |
| 172 | CheckCloseFixture() |
| 173 | : reporter() |
| 174 | , testResults(&reporter) |
| 175 | , line(-1) |
| 176 | { |
| 177 | } |
| 178 | |
| 179 | void PerformCheckWithNonStdThrow() |
| 180 | { |
| 181 | UnitTest::TestDetails const testDetails("closeTest", "closeSuite", "filename", -1); |
| 182 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 183 | CHECK_CLOSE(static_cast<float>(ThrowingFunction()), 1.0001f, 0.1f); line = __LINE__; |
| 184 | } |
| 185 | |
| 186 | void PerformCheckWithStdThrow() |
| 187 | { |
| 188 | UnitTest::TestDetails const testDetails("closeTest", "closeSuite", "filename", -1); |
| 189 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 190 | CHECK_CLOSE(static_cast<float>(ThrowingStdExceptionFunction()), 1.0001f, 0.1f); line = __LINE__; |
| 191 | } |
| 192 | |
| 193 | RecordingReporter reporter; |
| 194 | UnitTest::TestResults testResults; |
| 195 | int line; |
| 196 | }; |
| 197 | |
| 198 | TEST_FIXTURE(CheckCloseFixture, CheckCloseFailsOnException) |
| 199 | { |
| 200 | PerformCheckWithNonStdThrow(); |
| 201 | |
| 202 | CHECK(testResults.GetFailureCount() > 0); |
| 203 | } |
| 204 | |
| 205 | TEST_FIXTURE(CheckCloseFixture, CheckCloseFailsOnStdException) |
| 206 | { |
| 207 | PerformCheckWithStdThrow(); |
| 208 | |
| 209 | CHECK(testResults.GetFailureCount() > 0); |
| 210 | } |
| 211 | |
| 212 | TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfExceptionContainsCorrectDetails) |
| 213 | { |
| 214 | PerformCheckWithNonStdThrow(); |
| 215 | |
| 216 | CHECK_EQUAL("closeTest", reporter.lastFailedTest); |
| 217 | CHECK_EQUAL("closeSuite", reporter.lastFailedSuite); |
| 218 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 219 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 220 | } |
| 221 | |
| 222 | TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfStdExceptionContainsCorrectDetails) |
| 223 | { |
| 224 | PerformCheckWithStdThrow(); |
| 225 | |
| 226 | CHECK_EQUAL("closeTest", reporter.lastFailedTest); |
| 227 | CHECK_EQUAL("closeSuite", reporter.lastFailedSuite); |
| 228 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 229 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 230 | } |
| 231 | |
| 232 | TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfExceptionIncludesCheckContents) |
| 233 | { |
| 234 | PerformCheckWithNonStdThrow(); |
| 235 | |
| 236 | CHECK(strstr(reporter.lastFailedMessage, "static_cast<float>(ThrowingFunction())")); |
| 237 | CHECK(strstr(reporter.lastFailedMessage, "1.0001f")); |
| 238 | } |
| 239 | |
| 240 | TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfStdExceptionIncludesCheckContents) |
| 241 | { |
| 242 | PerformCheckWithStdThrow(); |
| 243 | |
| 244 | CHECK(strstr(reporter.lastFailedMessage, "static_cast<float>(ThrowingStdExceptionFunction())")); |
| 245 | CHECK(strstr(reporter.lastFailedMessage, "1.0001f")); |
| 246 | } |
| 247 | |
| 248 | TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfStandardExceptionIncludesWhat) |
| 249 | { |
| 250 | PerformCheckWithStdThrow(); |
| 251 | |
| 252 | CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)")); |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | class ThrowingObject |
| 257 | { |
| 258 | public: |
| 259 | float operator[](int) const |
| 260 | { |
| 261 | throw "Test throw"; |
| 262 | } |
| 263 | }; |
| 264 | |
| 265 | class StdThrowingObject |
| 266 | { |
| 267 | public: |
| 268 | float operator[](int) const |
| 269 | { |
| 270 | throw std::runtime_error("Test throw"); |
| 271 | } |
| 272 | }; |
| 273 | |
| 274 | SUITE(CheckArrayCloseExceptionTests) |
| 275 | { |
| 276 | struct CheckArrayCloseFixture |
| 277 | { |
| 278 | CheckArrayCloseFixture() |
| 279 | : reporter() |
| 280 | , testResults(&reporter) |
| 281 | , line(-1) |
| 282 | { |
| 283 | } |
| 284 | |
| 285 | void PerformCheckWithNonStdThrow() |
| 286 | { |
| 287 | UnitTest::TestDetails const testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1); |
| 288 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 289 | int const data[4] = { 0, 1, 2, 3 }; |
| 290 | CHECK_ARRAY_CLOSE(data, ThrowingObject(), 4, 0.01f); line = __LINE__; |
| 291 | } |
| 292 | |
| 293 | void PerformCheckWithStdThrow() |
| 294 | { |
| 295 | UnitTest::TestDetails const testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1); |
| 296 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 297 | int const data[4] = { 0, 1, 2, 3 }; |
| 298 | CHECK_ARRAY_CLOSE(data, StdThrowingObject(), 4, 0.01f); line = __LINE__; |
| 299 | } |
| 300 | |
| 301 | RecordingReporter reporter; |
| 302 | UnitTest::TestResults testResults; |
| 303 | int line; |
| 304 | }; |
| 305 | |
| 306 | TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureBecauseOfExceptionContainsCorrectDetails) |
| 307 | { |
| 308 | PerformCheckWithNonStdThrow(); |
| 309 | |
| 310 | CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); |
| 311 | CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); |
| 312 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 313 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 314 | } |
| 315 | |
| 316 | TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureBecauseOfStdExceptionContainsCorrectDetails) |
| 317 | { |
| 318 | PerformCheckWithStdThrow(); |
| 319 | |
| 320 | CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); |
| 321 | CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); |
| 322 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 323 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 324 | } |
| 325 | |
| 326 | TEST_FIXTURE(CheckArrayCloseFixture, CheckFailsOnException) |
| 327 | { |
| 328 | PerformCheckWithNonStdThrow(); |
| 329 | |
| 330 | CHECK(testResults.GetFailureCount() > 0); |
| 331 | } |
| 332 | |
| 333 | TEST_FIXTURE(CheckArrayCloseFixture, CheckFailsOnStdException) |
| 334 | { |
| 335 | PerformCheckWithStdThrow(); |
| 336 | |
| 337 | CHECK(testResults.GetFailureCount() > 0); |
| 338 | } |
| 339 | |
| 340 | TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureOnExceptionIncludesCheckContents) |
| 341 | { |
| 342 | PerformCheckWithNonStdThrow(); |
| 343 | |
| 344 | CHECK(strstr(reporter.lastFailedMessage, "data")); |
| 345 | CHECK(strstr(reporter.lastFailedMessage, "ThrowingObject()")); |
| 346 | } |
| 347 | |
| 348 | TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureOnStdExceptionIncludesCheckContents) |
| 349 | { |
| 350 | PerformCheckWithStdThrow(); |
| 351 | |
| 352 | CHECK(strstr(reporter.lastFailedMessage, "data")); |
| 353 | CHECK(strstr(reporter.lastFailedMessage, "StdThrowingObject()")); |
| 354 | } |
| 355 | |
| 356 | TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureOnStdExceptionIncludesWhat) |
| 357 | { |
| 358 | PerformCheckWithStdThrow(); |
| 359 | |
| 360 | CHECK(strstr(reporter.lastFailedMessage, "exception (Test throw)")); |
| 361 | } |
| 362 | } |
| 363 | |
| 364 | SUITE(CheckArrayEqualExceptionTests) |
| 365 | { |
| 366 | struct CheckArrayEqualFixture |
| 367 | { |
| 368 | CheckArrayEqualFixture() |
| 369 | : reporter() |
| 370 | , testResults(&reporter) |
| 371 | , line(-1) |
| 372 | { |
| 373 | } |
| 374 | |
| 375 | void PerformCheckWithNonStdThrow() |
| 376 | { |
| 377 | UnitTest::TestDetails const testDetails("arrayEqualTest", "arrayEqualSuite", "filename", -1); |
| 378 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 379 | int const data[4] = { 0, 1, 2, 3 }; |
| 380 | CHECK_ARRAY_EQUAL(data, ThrowingObject(), 4); line = __LINE__; |
| 381 | } |
| 382 | |
| 383 | void PerformCheckWithStdThrow() |
| 384 | { |
| 385 | UnitTest::TestDetails const testDetails("arrayEqualTest", "arrayEqualSuite", "filename", -1); |
| 386 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 387 | int const data[4] = { 0, 1, 2, 3 }; |
| 388 | CHECK_ARRAY_EQUAL(data, StdThrowingObject(), 4); line = __LINE__; |
| 389 | } |
| 390 | |
| 391 | RecordingReporter reporter; |
| 392 | UnitTest::TestResults testResults; |
| 393 | int line; |
| 394 | }; |
| 395 | |
| 396 | TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureBecauseOfExceptionContainsCorrectDetails) |
| 397 | { |
| 398 | PerformCheckWithNonStdThrow(); |
| 399 | |
| 400 | CHECK_EQUAL("arrayEqualTest", reporter.lastFailedTest); |
| 401 | CHECK_EQUAL("arrayEqualSuite", reporter.lastFailedSuite); |
| 402 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 403 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 404 | } |
| 405 | |
| 406 | TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureBecauseOfStdExceptionContainsCorrectDetails) |
| 407 | { |
| 408 | PerformCheckWithStdThrow(); |
| 409 | |
| 410 | CHECK_EQUAL("arrayEqualTest", reporter.lastFailedTest); |
| 411 | CHECK_EQUAL("arrayEqualSuite", reporter.lastFailedSuite); |
| 412 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 413 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 414 | } |
| 415 | |
| 416 | TEST_FIXTURE(CheckArrayEqualFixture, CheckFailsOnException) |
| 417 | { |
| 418 | PerformCheckWithNonStdThrow(); |
| 419 | |
| 420 | CHECK(testResults.GetFailureCount() > 0); |
| 421 | } |
| 422 | |
| 423 | TEST_FIXTURE(CheckArrayEqualFixture, CheckFailsOnStdException) |
| 424 | { |
| 425 | PerformCheckWithStdThrow(); |
| 426 | |
| 427 | CHECK(testResults.GetFailureCount() > 0); |
| 428 | } |
| 429 | |
| 430 | TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureOnExceptionIncludesCheckContents) |
| 431 | { |
| 432 | PerformCheckWithNonStdThrow(); |
| 433 | |
| 434 | CHECK(strstr(reporter.lastFailedMessage, "data")); |
| 435 | CHECK(strstr(reporter.lastFailedMessage, "ThrowingObject()")); |
| 436 | } |
| 437 | |
| 438 | TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureOnStdExceptionIncludesCheckContents) |
| 439 | { |
| 440 | PerformCheckWithStdThrow(); |
| 441 | |
| 442 | CHECK(strstr(reporter.lastFailedMessage, "data")); |
| 443 | CHECK(strstr(reporter.lastFailedMessage, "StdThrowingObject()")); |
| 444 | } |
| 445 | |
| 446 | TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureOnStdExceptionIncludesWhat) |
| 447 | { |
| 448 | PerformCheckWithStdThrow(); |
| 449 | |
| 450 | CHECK(strstr(reporter.lastFailedMessage, "exception (Test throw)")); |
| 451 | } |
| 452 | } |
| 453 | |
| 454 | SUITE(CheckArray2DExceptionTests) |
| 455 | { |
| 456 | class ThrowingObject2D |
| 457 | { |
| 458 | public: |
| 459 | float* operator[](int) const |
| 460 | { |
| 461 | throw "Test throw"; |
| 462 | } |
| 463 | }; |
| 464 | |
| 465 | class StdThrowingObject2D |
| 466 | { |
| 467 | public: |
| 468 | float* operator[](int) const |
| 469 | { |
| 470 | throw std::runtime_error("Test throw"); |
| 471 | } |
| 472 | }; |
| 473 | |
| 474 | struct CheckArray2DCloseFixture |
| 475 | { |
| 476 | CheckArray2DCloseFixture() |
| 477 | : reporter() |
| 478 | , testResults(&reporter) |
| 479 | , line(-1) |
| 480 | { |
| 481 | } |
| 482 | |
| 483 | void PerformCheckWithNonStdThrow() |
| 484 | { |
| 485 | UnitTest::TestDetails const testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1); |
| 486 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 487 | const float data[2][2] = { {0, 1}, {2, 3} }; |
| 488 | CHECK_ARRAY2D_CLOSE(data, ThrowingObject2D(), 2, 2, 0.01f); line = __LINE__; |
| 489 | } |
| 490 | |
| 491 | void PerformCheckWithStdThrow() |
| 492 | { |
| 493 | UnitTest::TestDetails const testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1); |
| 494 | ScopedCurrentTest scopedResults(testResults, &testDetails); |
| 495 | const float data[2][2] = { {0, 1}, {2, 3} }; |
| 496 | CHECK_ARRAY2D_CLOSE(data, StdThrowingObject2D(), 2, 2, 0.01f); line = __LINE__; |
| 497 | } |
| 498 | |
| 499 | RecordingReporter reporter; |
| 500 | UnitTest::TestResults testResults; |
| 501 | int line; |
| 502 | }; |
| 503 | |
| 504 | TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureBecauseOfExceptionContainsCorrectDetails) |
| 505 | { |
| 506 | PerformCheckWithNonStdThrow(); |
| 507 | |
| 508 | CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); |
| 509 | CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); |
| 510 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 511 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 512 | } |
| 513 | |
| 514 | TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureBecauseOfStdExceptionContainsCorrectDetails) |
| 515 | { |
| 516 | PerformCheckWithStdThrow(); |
| 517 | |
| 518 | CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); |
| 519 | CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); |
| 520 | CHECK_EQUAL("filename", reporter.lastFailedFile); |
| 521 | CHECK_EQUAL(line, reporter.lastFailedLine); |
| 522 | } |
| 523 | |
| 524 | TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailsOnException) |
| 525 | { |
| 526 | PerformCheckWithNonStdThrow(); |
| 527 | |
| 528 | CHECK(testResults.GetFailureCount() > 0); |
| 529 | } |
| 530 | |
| 531 | TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailsOnStdException) |
| 532 | { |
| 533 | PerformCheckWithStdThrow(); |
| 534 | |
| 535 | CHECK(testResults.GetFailureCount() > 0); |
| 536 | } |
| 537 | |
| 538 | TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureOnExceptionIncludesCheckContents) |
| 539 | { |
| 540 | PerformCheckWithNonStdThrow(); |
| 541 | |
| 542 | CHECK(strstr(reporter.lastFailedMessage, "data")); |
| 543 | CHECK(strstr(reporter.lastFailedMessage, "ThrowingObject2D()")); |
| 544 | } |
| 545 | |
| 546 | TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureOnStdExceptionIncludesCheckContents) |
| 547 | { |
| 548 | PerformCheckWithStdThrow(); |
| 549 | |
| 550 | CHECK(strstr(reporter.lastFailedMessage, "data")); |
| 551 | CHECK(strstr(reporter.lastFailedMessage, "StdThrowingObject2D()")); |
| 552 | } |
| 553 | |
| 554 | TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureOnStdExceptionIncludesWhat) |
| 555 | { |
| 556 | PerformCheckWithStdThrow(); |
| 557 | |
| 558 | CHECK(strstr(reporter.lastFailedMessage, "exception (Test throw)")); |
| 559 | } |
| 560 | } |
| 561 | } |
| 562 | |
| 563 | #endif |
trunk/3rdparty/unittest-cpp/tests/TestTestRunner.cpp
r0 | r249095 | |
| 1 | #include "UnitTest++/UnitTestPP.h" |
| 2 | #include "RecordingReporter.h" |
| 3 | #include "UnitTest++/ReportAssert.h" |
| 4 | #include "UnitTest++/TestList.h" |
| 5 | #include "UnitTest++/TimeHelpers.h" |
| 6 | #include "UnitTest++/TimeConstraint.h" |
| 7 | #include "UnitTest++/ReportAssertImpl.h" |
| 8 | |
| 9 | using namespace UnitTest; |
| 10 | |
| 11 | namespace |
| 12 | { |
| 13 | |
| 14 | struct MockTest : public Test |
| 15 | { |
| 16 | MockTest(char const* testName, bool const success_, bool const assert_, int const count_ = 1) |
| 17 | : Test(testName) |
| 18 | , success(success_) |
| 19 | , asserted(assert_) |
| 20 | , count(count_) |
| 21 | { |
| 22 | } |
| 23 | |
| 24 | virtual void RunImpl() const |
| 25 | { |
| 26 | TestResults& testResults_ = *CurrentTest::Results(); |
| 27 | |
| 28 | for (int i=0; i < count; ++i) |
| 29 | { |
| 30 | if (asserted) |
| 31 | { |
| 32 | ReportAssert("desc", "file", 0); |
| 33 | } |
| 34 | else if (!success) |
| 35 | { |
| 36 | testResults_.OnTestFailure(m_details, "message"); |
| 37 | } |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | bool const success; |
| 42 | bool const asserted; |
| 43 | int const count; |
| 44 | }; |
| 45 | |
| 46 | struct FixtureBase |
| 47 | { |
| 48 | FixtureBase() |
| 49 | : runner(reporter) |
| 50 | { |
| 51 | } |
| 52 | |
| 53 | template <class Predicate> |
| 54 | int RunTestsIf(TestList const& list, char const* suiteName, |
| 55 | const Predicate& predicate, int maxTestTimeInMs) |
| 56 | { |
| 57 | TestResults* oldResults = CurrentTest::Results(); |
| 58 | const TestDetails* oldDetails = CurrentTest::Details(); |
| 59 | int result = runner.RunTestsIf(list, suiteName, predicate, maxTestTimeInMs); |
| 60 | CurrentTest::Results() = oldResults; |
| 61 | CurrentTest::Details() = oldDetails; |
| 62 | return result; |
| 63 | } |
| 64 | |
| 65 | TestRunner runner; |
| 66 | RecordingReporter reporter; |
| 67 | }; |
| 68 | |
| 69 | struct TestRunnerFixture : public FixtureBase |
| 70 | { |
| 71 | TestList list; |
| 72 | }; |
| 73 | |
| 74 | TEST_FIXTURE(TestRunnerFixture, TestStartIsReportedCorrectly) |
| 75 | { |
| 76 | MockTest test("goodtest", true, false); |
| 77 | list.Add(&test); |
| 78 | |
| 79 | RunTestsIf(list, NULL, True(), 0); |
| 80 | CHECK_EQUAL(1, reporter.testRunCount); |
| 81 | CHECK_EQUAL("goodtest", reporter.lastStartedTest); |
| 82 | } |
| 83 | |
| 84 | TEST_FIXTURE(TestRunnerFixture, TestFinishIsReportedCorrectly) |
| 85 | { |
| 86 | MockTest test("goodtest", true, false); |
| 87 | list.Add(&test); |
| 88 | |
| 89 | RunTestsIf(list, NULL, True(), 0); |
| 90 | CHECK_EQUAL(1, reporter.testFinishedCount); |
| 91 | CHECK_EQUAL("goodtest", reporter.lastFinishedTest); |
| 92 | } |
| 93 | |
| 94 | class SlowTest : public Test |
| 95 | { |
| 96 | public: |
| 97 | SlowTest() |
| 98 | : Test("slow", "somesuite", "filename", 123) |
| 99 | { |
| 100 | } |
| 101 | |
| 102 | virtual void RunImpl() const |
| 103 | { |
| 104 | TimeHelpers::SleepMs(20); |
| 105 | } |
| 106 | }; |
| 107 | |
| 108 | TEST_FIXTURE(TestRunnerFixture, TestFinishIsCalledWithCorrectTime) |
| 109 | { |
| 110 | SlowTest test; |
| 111 | list.Add(&test); |
| 112 | |
| 113 | RunTestsIf(list, NULL, True(), 0); |
| 114 | CHECK(reporter.lastFinishedTestTime >= 0.005f && reporter.lastFinishedTestTime <= 0.050f); |
| 115 | } |
| 116 | |
| 117 | TEST_FIXTURE(TestRunnerFixture, FailureCountIsZeroWhenNoTestsAreRun) |
| 118 | { |
| 119 | CHECK_EQUAL(0, RunTestsIf(list, NULL, True(), 0)); |
| 120 | CHECK_EQUAL(0, reporter.testRunCount); |
| 121 | CHECK_EQUAL(0, reporter.testFailedCount); |
| 122 | } |
| 123 | |
| 124 | TEST_FIXTURE(TestRunnerFixture, CallsReportFailureOncePerFailingTest) |
| 125 | { |
| 126 | MockTest test1("test", false, false); |
| 127 | list.Add(&test1); |
| 128 | MockTest test2("test", true, false); |
| 129 | list.Add(&test2); |
| 130 | MockTest test3("test", false, false); |
| 131 | list.Add(&test3); |
| 132 | |
| 133 | CHECK_EQUAL(2, RunTestsIf(list, NULL, True(), 0)); |
| 134 | CHECK_EQUAL(2, reporter.testFailedCount); |
| 135 | } |
| 136 | |
| 137 | TEST_FIXTURE(TestRunnerFixture, TestsThatAssertAreReportedAsFailing) |
| 138 | { |
| 139 | MockTest test("test", true, true); |
| 140 | list.Add(&test); |
| 141 | |
| 142 | RunTestsIf(list, NULL, True(), 0); |
| 143 | CHECK_EQUAL(1, reporter.testFailedCount); |
| 144 | } |
| 145 | |
| 146 | |
| 147 | TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfTestCount) |
| 148 | { |
| 149 | MockTest test1("test", true, false); |
| 150 | MockTest test2("test", true, false); |
| 151 | MockTest test3("test", true, false); |
| 152 | list.Add(&test1); |
| 153 | list.Add(&test2); |
| 154 | list.Add(&test3); |
| 155 | |
| 156 | RunTestsIf(list, NULL, True(), 0); |
| 157 | CHECK_EQUAL(3, reporter.summaryTotalTestCount); |
| 158 | } |
| 159 | |
| 160 | TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailedTests) |
| 161 | { |
| 162 | MockTest test1("test", false, false, 2); |
| 163 | MockTest test2("test", true, false); |
| 164 | MockTest test3("test", false, false, 3); |
| 165 | list.Add(&test1); |
| 166 | list.Add(&test2); |
| 167 | list.Add(&test3); |
| 168 | |
| 169 | RunTestsIf(list, NULL, True(), 0); |
| 170 | CHECK_EQUAL(2, reporter.summaryFailedTestCount); |
| 171 | } |
| 172 | |
| 173 | TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailures) |
| 174 | { |
| 175 | MockTest test1("test", false, false, 2); |
| 176 | MockTest test2("test", true, false); |
| 177 | MockTest test3("test", false, false, 3); |
| 178 | list.Add(&test1); |
| 179 | list.Add(&test2); |
| 180 | list.Add(&test3); |
| 181 | |
| 182 | RunTestsIf(list, NULL, True(), 0); |
| 183 | CHECK_EQUAL(5, reporter.summaryFailureCount); |
| 184 | } |
| 185 | |
| 186 | TEST_FIXTURE(TestRunnerFixture, SlowTestPassesForHighTimeThreshold) |
| 187 | { |
| 188 | SlowTest test; |
| 189 | list.Add(&test); |
| 190 | |
| 191 | RunTestsIf(list, NULL, True(), 0); |
| 192 | CHECK_EQUAL(0, reporter.testFailedCount); |
| 193 | } |
| 194 | |
| 195 | TEST_FIXTURE(TestRunnerFixture, SlowTestFailsForLowTimeThreshold) |
| 196 | { |
| 197 | SlowTest test; |
| 198 | list.Add(&test); |
| 199 | |
| 200 | RunTestsIf(list, NULL, True(), 3); |
| 201 | CHECK_EQUAL(1, reporter.testFailedCount); |
| 202 | } |
| 203 | |
| 204 | TEST_FIXTURE(TestRunnerFixture, SlowTestHasCorrectFailureInformation) |
| 205 | { |
| 206 | SlowTest test; |
| 207 | list.Add(&test); |
| 208 | |
| 209 | RunTestsIf(list, NULL, True(), 3); |
| 210 | |
| 211 | using namespace std; |
| 212 | |
| 213 | CHECK_EQUAL(test.m_details.testName, reporter.lastFailedTest); |
| 214 | CHECK(strstr(test.m_details.filename, reporter.lastFailedFile)); |
| 215 | CHECK_EQUAL(test.m_details.lineNumber, reporter.lastFailedLine); |
| 216 | |
| 217 | CHECK(strstr(reporter.lastFailedMessage, "Global time constraint failed")); |
| 218 | CHECK(strstr(reporter.lastFailedMessage, "3ms")); |
| 219 | } |
| 220 | |
| 221 | TEST_FIXTURE(TestRunnerFixture, SlowTestWithTimeExemptionPasses) |
| 222 | { |
| 223 | class SlowExemptedTest : public Test |
| 224 | { |
| 225 | public: |
| 226 | SlowExemptedTest() : Test("slowexempted", "", 0) {} |
| 227 | virtual void RunImpl() const |
| 228 | { |
| 229 | UNITTEST_TIME_CONSTRAINT_EXEMPT(); |
| 230 | TimeHelpers::SleepMs(20); |
| 231 | } |
| 232 | }; |
| 233 | |
| 234 | SlowExemptedTest test; |
| 235 | list.Add(&test); |
| 236 | |
| 237 | RunTestsIf(list, NULL, True(), 3); |
| 238 | CHECK_EQUAL(0, reporter.testFailedCount); |
| 239 | } |
| 240 | |
| 241 | struct TestSuiteFixture : FixtureBase |
| 242 | { |
| 243 | TestSuiteFixture() |
| 244 | : test1("TestInDefaultSuite") |
| 245 | , test2("TestInOtherSuite", "OtherSuite") |
| 246 | , test3("SecondTestInDefaultSuite") |
| 247 | { |
| 248 | list.Add(&test1); |
| 249 | list.Add(&test2); |
| 250 | } |
| 251 | |
| 252 | Test test1; |
| 253 | Test test2; |
| 254 | Test test3; |
| 255 | TestList list; |
| 256 | }; |
| 257 | |
| 258 | TEST_FIXTURE(TestSuiteFixture, TestRunnerRunsAllSuitesIfNullSuiteIsPassed) |
| 259 | { |
| 260 | RunTestsIf(list, NULL, True(), 0); |
| 261 | CHECK_EQUAL(2, reporter.summaryTotalTestCount); |
| 262 | } |
| 263 | |
| 264 | TEST_FIXTURE(TestSuiteFixture,TestRunnerRunsOnlySpecifiedSuite) |
| 265 | { |
| 266 | RunTestsIf(list, "OtherSuite", True(), 0); |
| 267 | CHECK_EQUAL(1, reporter.summaryTotalTestCount); |
| 268 | CHECK_EQUAL("TestInOtherSuite", reporter.lastFinishedTest); |
| 269 | } |
| 270 | |
| 271 | struct RunTestIfNameIs |
| 272 | { |
| 273 | RunTestIfNameIs(char const* name_) |
| 274 | : name(name_) |
| 275 | { |
| 276 | } |
| 277 | |
| 278 | bool operator()(const Test* const test) const |
| 279 | { |
| 280 | using namespace std; |
| 281 | return (0 == strcmp(test->m_details.testName, name)); |
| 282 | } |
| 283 | |
| 284 | char const* name; |
| 285 | }; |
| 286 | |
| 287 | TEST(TestMockPredicateBehavesCorrectly) |
| 288 | { |
| 289 | RunTestIfNameIs predicate("pass"); |
| 290 | |
| 291 | Test pass("pass"); |
| 292 | Test fail("fail"); |
| 293 | |
| 294 | CHECK(predicate(&pass)); |
| 295 | CHECK(!predicate(&fail)); |
| 296 | } |
| 297 | |
| 298 | TEST_FIXTURE(TestRunnerFixture, TestRunnerRunsTestsThatPassPredicate) |
| 299 | { |
| 300 | Test should_run("goodtest"); |
| 301 | list.Add(&should_run); |
| 302 | |
| 303 | Test should_not_run("badtest"); |
| 304 | list.Add(&should_not_run); |
| 305 | |
| 306 | RunTestsIf(list, NULL, RunTestIfNameIs("goodtest"), 0); |
| 307 | CHECK_EQUAL(1, reporter.testRunCount); |
| 308 | CHECK_EQUAL("goodtest", reporter.lastStartedTest); |
| 309 | } |
| 310 | |
| 311 | TEST_FIXTURE(TestRunnerFixture, TestRunnerOnlyRunsTestsInSpecifiedSuiteAndThatPassPredicate) |
| 312 | { |
| 313 | Test runningTest1("goodtest", "suite"); |
| 314 | Test skippedTest2("goodtest"); |
| 315 | Test skippedTest3("badtest", "suite"); |
| 316 | Test skippedTest4("badtest"); |
| 317 | |
| 318 | list.Add(&runningTest1); |
| 319 | list.Add(&skippedTest2); |
| 320 | list.Add(&skippedTest3); |
| 321 | list.Add(&skippedTest4); |
| 322 | |
| 323 | RunTestsIf(list, "suite", RunTestIfNameIs("goodtest"), 0); |
| 324 | |
| 325 | CHECK_EQUAL(1, reporter.testRunCount); |
| 326 | CHECK_EQUAL("goodtest", reporter.lastStartedTest); |
| 327 | CHECK_EQUAL("suite", reporter.lastStartedSuite); |
| 328 | } |
| 329 | |
| 330 | } |
| | No newline at end of file |
trunk/src/emu/bus/pc_kbd/iskr1030.c
r249094 | r249095 | |
42 | 42 | |
43 | 43 | ROM_START( iskr_1030_keyboard ) |
44 | 44 | ROM_REGION( 0x800, I8048_TAG, 0 ) |
| 45 | // XXX add P/N etc |
45 | 46 | ROM_LOAD( "i1030.bin", 0x000, 0x800, CRC(7cac9c4b) SHA1(03959d3350e012ebfe61cee9c062b6c1fdd8766e) ) |
46 | 47 | ROM_END |
47 | 48 | |
r249094 | r249095 | |
61 | 62 | //------------------------------------------------- |
62 | 63 | |
63 | 64 | static ADDRESS_MAP_START( iskr_1030_keyboard_io, AS_IO, 8, iskr_1030_keyboard_device ) |
64 | | AM_RANGE(0x00, 0xFF) AM_READWRITE(ram_r, ram_w) |
| 65 | AM_RANGE(0x00, 0xFF) AM_RAM |
65 | 66 | AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(p1_r, p1_w) |
66 | 67 | AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_WRITE(p2_w) |
| 68 | // AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_READ(t0_r) |
67 | 69 | AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(t1_r) |
68 | 70 | ADDRESS_MAP_END |
69 | 71 | |
r249094 | r249095 | |
73 | 75 | //------------------------------------------------- |
74 | 76 | |
75 | 77 | static MACHINE_CONFIG_FRAGMENT( iskr_1030_keyboard ) |
76 | | MCFG_CPU_ADD(I8048_TAG, I8048, XTAL_5MHz) |
| 78 | // XXX check |
| 79 | MCFG_CPU_ADD(I8048_TAG, I8048, MCS48_LC_CLOCK(IND_U(47), CAP_P(20.7))) |
77 | 80 | MCFG_CPU_IO_MAP(iskr_1030_keyboard_io) |
78 | 81 | MACHINE_CONFIG_END |
79 | 82 | |
r249094 | r249095 | |
95 | 98 | |
96 | 99 | INPUT_PORTS_START( iskr_1030_keyboard ) |
97 | 100 | PORT_START("MD00") |
98 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
99 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
100 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
101 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 101 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 102 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_MAMEKEY(TAB)) |
| 103 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') |
| 104 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') |
| 105 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?59?") // 0x59 = Inf |
| 106 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) |
| 107 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 108 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
102 | 109 | |
103 | 110 | PORT_START("MD01") |
104 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
105 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
106 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
107 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 111 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) |
| 112 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') |
| 113 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') |
| 114 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') |
| 115 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') |
| 116 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 7 Home") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) |
| 117 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 118 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
108 | 119 | |
109 | 120 | PORT_START("MD02") |
110 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
111 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
112 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
113 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 121 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') |
| 122 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') |
| 123 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') |
| 124 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') |
| 125 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RCONTROL) // 0x5a = R/L (R) |
| 126 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 8 " UTF8_UP) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) |
| 127 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 128 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
114 | 129 | |
115 | 130 | PORT_START("MD03") |
116 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
117 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
118 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
119 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 131 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') |
| 132 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') |
| 133 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') |
| 134 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') |
| 135 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) // 0x5b = Rus |
| 136 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 9 PgUp") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) |
| 137 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 138 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
120 | 139 | |
121 | 140 | PORT_START("MD04") |
122 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
123 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
124 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
125 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 141 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') |
| 142 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') |
| 143 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') |
| 144 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') |
| 145 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) |
| 146 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 4 " UTF8_LEFT) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) |
| 147 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 148 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
126 | 149 | |
127 | 150 | PORT_START("MD05") |
128 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
129 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
130 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
131 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 151 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') |
| 152 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') |
| 153 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') |
| 154 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') |
| 155 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) |
| 156 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) |
| 157 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 158 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
132 | 159 | |
133 | 160 | PORT_START("MD06") |
134 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
135 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
136 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
137 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 161 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') |
| 162 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') |
| 163 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') |
| 164 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') |
| 165 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) |
| 166 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 6 " UTF8_RIGHT) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) |
| 167 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 168 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
138 | 169 | |
139 | 170 | PORT_START("MD07") |
140 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
141 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
142 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
143 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 171 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') |
| 172 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') |
| 173 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') |
| 174 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') |
| 175 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) |
| 176 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 1 End") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) |
| 177 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 178 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
144 | 179 | |
145 | 180 | PORT_START("MD08") |
146 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
147 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
148 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
149 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 181 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') |
| 182 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') |
| 183 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') |
| 184 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?2a?") |
| 185 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) |
| 186 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 2 " UTF8_DOWN) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) |
| 187 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 188 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
150 | 189 | |
151 | 190 | PORT_START("MD09") |
152 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
153 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
154 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
155 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 191 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') |
| 192 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') |
| 193 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') |
| 194 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?5c?") // 0x5c = YO |
| 195 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) |
| 196 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 3 PgDn") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) |
| 197 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 198 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
156 | 199 | |
157 | 200 | PORT_START("MD10") |
158 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
159 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
160 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
161 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 201 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') |
| 202 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') |
| 203 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') |
| 204 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') |
| 205 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) |
| 206 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 0 Ins") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) |
| 207 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 208 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
162 | 209 | |
163 | 210 | PORT_START("MD11") |
164 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
165 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
166 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
167 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 211 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') |
| 212 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?36?") |
| 213 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') |
| 214 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') |
| 215 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) |
| 216 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad . Del") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) |
| 217 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 218 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
168 | 219 | |
169 | 220 | PORT_START("MD12") |
170 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
171 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
172 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
173 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 221 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') |
| 222 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?3a?") |
| 223 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') |
| 224 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) // 0x55 |
| 225 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) |
| 226 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) |
| 227 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 228 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
174 | 229 | |
175 | 230 | PORT_START("MD13") |
176 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
177 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
178 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
179 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 231 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') |
| 232 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') |
| 233 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) |
| 234 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) // 0x56 |
| 235 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) |
| 236 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 237 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 238 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
180 | 239 | |
181 | 240 | PORT_START("MD14") |
182 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
183 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
184 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
185 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 241 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') |
| 242 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PRTSCR) |
| 243 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT)) |
| 244 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) // 0x57 = Lat |
| 245 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK)) |
| 246 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 247 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 248 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
186 | 249 | |
187 | 250 | PORT_START("MD15") |
188 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
189 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
190 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
191 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
192 | | |
193 | | PORT_START("MD16") |
194 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
195 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
196 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
197 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
198 | | |
199 | | PORT_START("MD17") |
200 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
201 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
202 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
203 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
204 | | |
205 | | PORT_START("MD18") |
206 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
207 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
208 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
209 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
210 | | |
211 | | PORT_START("MD19") |
212 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
213 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
214 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
215 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
216 | | |
217 | | PORT_START("MD20") |
218 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
219 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
220 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
221 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
222 | | |
223 | | PORT_START("MD21") |
224 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
225 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
226 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
227 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
228 | | |
229 | | PORT_START("MD22") |
230 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
231 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
232 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
233 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
234 | | |
235 | | PORT_START("MD23") |
236 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
237 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
238 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
239 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) |
| 251 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) |
| 252 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) |
| 253 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) // 0x54 |
| 254 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RALT) // 0x58 = R/L (L) |
| 255 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Scroll Lock Break") PORT_CODE(KEYCODE_SCRLOCK) PORT_CHAR(UCHAR_MAMEKEY(SCRLOCK)) |
| 256 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 257 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 258 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
240 | 259 | INPUT_PORTS_END |
241 | 260 | |
242 | 261 | |
r249094 | r249095 | |
279 | 298 | m_md13(*this, "MD13"), |
280 | 299 | m_md14(*this, "MD14"), |
281 | 300 | m_md15(*this, "MD15"), |
282 | | m_md16(*this, "MD16"), |
283 | | m_md17(*this, "MD17"), |
284 | | m_md18(*this, "MD18"), |
285 | | m_md19(*this, "MD19"), |
286 | | m_md20(*this, "MD20"), |
287 | | m_md21(*this, "MD21"), |
288 | | m_md22(*this, "MD22"), |
289 | | m_md23(*this, "MD23"), |
290 | 301 | m_p1(0), |
291 | 302 | m_p2(0), |
292 | 303 | m_q(0) |
r249094 | r249095 | |
302 | 313 | { |
303 | 314 | set_pc_kbdc_device(); |
304 | 315 | |
305 | | m_ram.resize(0x100); |
306 | | save_item(NAME(m_ram)); |
307 | | |
308 | | save_item(NAME(m_bus)); |
| 316 | // state saving |
309 | 317 | save_item(NAME(m_p1)); |
310 | 318 | save_item(NAME(m_p2)); |
311 | 319 | save_item(NAME(m_q)); |
r249094 | r249095 | |
343 | 351 | |
344 | 352 | |
345 | 353 | //------------------------------------------------- |
346 | | // t1_r - |
| 354 | // t0_r - XXX ENT0 CLK |
347 | 355 | //------------------------------------------------- |
348 | 356 | |
349 | | READ8_MEMBER( iskr_1030_keyboard_device::t1_r ) |
| 357 | READ8_MEMBER( iskr_1030_keyboard_device::t0_r ) |
350 | 358 | { |
351 | | UINT8 data = data_signal(); |
352 | | UINT8 bias = m_p1 & 15; |
353 | | |
354 | | if (!BIT(m_p1, 7)) { |
355 | | DBG_LOG(2,0,( "%s: t1_r (l) %d\n", tag(), data)); |
356 | | return data; |
357 | | } |
358 | | |
359 | | if (bias) { |
360 | | DBG_LOG(2,0,( "%s: t1_r (b) %d\n", tag(), bias)); |
361 | | return 1; |
362 | | } |
363 | | |
364 | | data = 0; |
365 | | switch (m_bus >> 2) |
366 | | { |
367 | | case 0<<1: data = m_md00->read(); break; |
368 | | case 1<<1: data = m_md01->read(); break; |
369 | | case 2<<1: data = m_md02->read(); break; |
370 | | case 3<<1: data = m_md03->read(); break; |
371 | | case 4<<1: data = m_md04->read(); break; |
372 | | case 5<<1: data = m_md05->read(); break; |
373 | | case 6<<1: data = m_md06->read(); break; |
374 | | case 7<<1: data = m_md07->read(); break; |
375 | | case 8<<1: data = m_md08->read(); break; |
376 | | case 9<<1: data = m_md09->read(); break; |
377 | | case 10<<1: data = m_md10->read(); break; |
378 | | case 11<<1: data = m_md11->read(); break; |
379 | | case (0<<1)+1: data = m_md12->read(); break; |
380 | | case (1<<1)+1: data = m_md13->read(); break; |
381 | | case (2<<1)+1: data = m_md14->read(); break; |
382 | | case (3<<1)+1: data = m_md15->read(); break; |
383 | | case (4<<1)+1: data = m_md16->read(); break; |
384 | | case (5<<1)+1: data = m_md17->read(); break; |
385 | | case (6<<1)+1: data = m_md18->read(); break; |
386 | | case (7<<1)+1: data = m_md19->read(); break; |
387 | | case (8<<1)+1: data = m_md20->read(); break; |
388 | | case (9<<1)+1: data = m_md21->read(); break; |
389 | | case (10<<1)+1: data = m_md22->read(); break; |
390 | | case (11<<1)+1: data = m_md23->read(); break; |
391 | | } |
392 | | data = BIT(data, m_bus&3); |
393 | | |
394 | | DBG_LOG(2,0,( "%s: t1_r (k r%d c%d) %d\n", tag(), m_bus&3, m_bus>>2, data)); |
395 | | return data; |
| 359 | return 0; |
| 360 | // return clock_signal(); |
396 | 361 | } |
397 | 362 | |
398 | 363 | |
399 | 364 | //------------------------------------------------- |
400 | | // ram_w - |
| 365 | // t1_r - OK |
401 | 366 | //------------------------------------------------- |
402 | 367 | |
403 | | WRITE8_MEMBER( iskr_1030_keyboard_device::ram_w ) |
| 368 | READ8_MEMBER( iskr_1030_keyboard_device::t1_r ) |
404 | 369 | { |
405 | | DBG_LOG(2,0,( "%s: ram_w[%02x] <- %02x\n", tag(), offset, data)); |
| 370 | UINT8 data = data_signal(); |
406 | 371 | |
407 | | m_bus = offset; |
408 | | m_ram[offset] = data; |
409 | | } |
| 372 | DBG_LOG(2,0,( "%s: t1_r %d\n", tag(), data)); |
410 | 373 | |
411 | | |
412 | | //------------------------------------------------- |
413 | | // ram_r - |
414 | | //------------------------------------------------- |
415 | | |
416 | | READ8_MEMBER( iskr_1030_keyboard_device::ram_r ) |
417 | | { |
418 | | DBG_LOG(2,0,( "%s: ram_r[%02x] = %02x\n", tag(), offset, m_ram[offset])); |
419 | | |
420 | | return m_ram[offset]; |
| 374 | return data; |
421 | 375 | } |
422 | 376 | |
423 | 377 | |
r249094 | r249095 | |
428 | 382 | READ8_MEMBER( iskr_1030_keyboard_device::p1_r ) |
429 | 383 | { |
430 | 384 | /* |
| 385 | |
431 | 386 | bit description |
432 | 387 | |
433 | 388 | 0 -REQ IN |
r249094 | r249095 | |
438 | 393 | 5 |
439 | 394 | 6 |
440 | 395 | 7 |
| 396 | |
441 | 397 | */ |
442 | 398 | |
443 | 399 | UINT8 data = 0; |
r249094 | r249095 | |
457 | 413 | /* |
458 | 414 | bit description |
459 | 415 | |
460 | | 0 ... |
461 | | 1 ... |
462 | | 2 ... |
463 | | 3 (not connected) |
464 | | 4 SPEAKER |
465 | | 5 LED RUS/LAT |
466 | | 6 LED NLK |
467 | | 7 LED CLK |
| 416 | 0 |
| 417 | 1 |
| 418 | 2 |
| 419 | 3 |
| 420 | 4 |
| 421 | 5 LED XXX |
| 422 | 6 LED XXX |
| 423 | 7 LED XXX |
468 | 424 | */ |
469 | 425 | DBG_LOG(1,0,( "%s: p2_w %02x\n", tag(), data)); |
470 | 426 | |
471 | | m_p2 = data; |
| 427 | m_p1 = data; |
472 | 428 | } |
473 | 429 | |
474 | 430 | |
r249094 | r249095 | |
486 | 442 | 2 XXX |
487 | 443 | 3 XXX |
488 | 444 | 4 CLOCK out |
489 | | 5 DATA out |
| 445 | 5 DATA out (inverted!) |
490 | 446 | 6 XXX |
491 | | 7 POLL GATE |
| 447 | 7 XXX |
492 | 448 | */ |
| 449 | DBG_LOG(1,0,( "%s: p1_w %02x (clk %d data %d)\n", tag(), data, BIT(data, 4), BIT(data, 5))); |
493 | 450 | |
494 | | m_p1 = data; |
495 | | |
496 | | DBG_LOG(1,0,( "%s: p1_w %02x (c %d d %d bias %d)\n", tag(), data, BIT(data, 4), BIT(data, 5), data&15)); |
497 | | |
498 | 451 | m_pc_kbdc->data_write_from_kb(BIT(data, 5)); |
499 | 452 | m_pc_kbdc->clock_write_from_kb(BIT(data, 4)); |
500 | 453 | } |
trunk/src/emu/machine/68230pit.c
r249094 | r249095 | |
1 | 1 | // license:BSD-3-Clause |
2 | 2 | // copyright-holders:Joakim Larsson Edstr??m |
3 | 3 | /********************************************************************** |
4 | | * |
5 | | * Motorola MC68230 PI/T Parallell Interface and Timer |
6 | | * |
7 | | * Revisions |
8 | | * 2015-07-15 JLE initial |
9 | | * |
10 | | * Todo |
11 | | * - Add clock and timers |
12 | | * - Add all missing registers |
13 | | * - Add configuration |
14 | | **********************************************************************/ |
15 | 4 | |
16 | | #include "68230pit.h" |
| 5 | Motorola MC68230 PI/T Parallell Interface and Timer |
17 | 6 | |
18 | | #define LOG(x) /* x */ |
| 7 | Revisions |
| 8 | 2015-07-15 JLE initial |
19 | 9 | |
20 | | //************************************************************************** |
21 | | // DEVICE TYPE DEFINITIONS |
22 | | //************************************************************************** |
| 10 | Todo |
| 11 | - Add clock and timers |
| 12 | - Add all missing registers |
| 13 | - Add configuration |
| 14 | **********************************************************************/ |
23 | 15 | |
24 | | const device_type PIT68230 = &device_creator<pit68230_device>; |
| 16 | /* |
| 17 | Force CPU-1 init sequence |
| 18 | 0801EA 0E0000 W 0000 PGCR data_w: 0000 -> 0000 & 00ff |
| 19 | 0801EA 0E0002 W 0000 PSRR data_w: 0000 -> 0001 & 00ff |
| 20 | 0801EA 0E0004 W FFFF PADDR data_w: 00ff -> 0002 & 00ff |
| 21 | 0801EA 0E0006 W 0000 PBDDR data_w: 0000 -> 0003 & 00ff |
| 22 | 0801F0 0E000C W 6060 PACR data_w: 0060 -> 0006 & 00ff |
| 23 | 0801F6 0E000E W A0A0 PBCR data_w: 00a0 -> 0007 & 00ff |
| 24 | 0801FC 0E0000 W 3030 PGCR data_w: 0030 -> 0000 & 00ff |
| 25 | 080202 0E000E W A8A8 PBCR data_w: 00a8 -> 0007 & 00ff |
| 26 | 080210 0E000E W A0A0 PBCR data_w: 00a0 -> 0007 & 00ff |
25 | 27 | |
26 | | //------------------------------------------------- |
27 | | // pit68230_device - constructors |
28 | | //------------------------------------------------- |
29 | | pit68230_device::pit68230_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 variant, const char *shortname, const char *source) |
30 | | : device_t (mconfig, type, name, tag, owner, clock, shortname, source), |
31 | | device_execute_interface (mconfig, *this) |
32 | | , m_icount (0) |
33 | | , m_write_pa (*this) |
34 | | , m_write_h2 (*this) |
35 | | { |
36 | | } |
| 28 | Force CPU-1 after one keypress in terminal |
| 29 | 081DC0 0E000C W 6868 PACR |
| 30 | 081DC8 0E000C W 6060 PACR |
| 31 | */ |
37 | 32 | |
38 | 33 | |
39 | | pit68230_device::pit68230_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
40 | | : device_t (mconfig, PIT68230, "PIT68230", tag, owner, clock, "pit68230", __FILE__), |
41 | | device_execute_interface (mconfig, *this) |
42 | | , m_icount (0) |
43 | | , m_write_pa (*this) |
44 | | , m_write_h2 (*this) |
45 | | { |
46 | | } |
| 34 | #include "emu.h" |
| 35 | #include "68230pit.h" |
47 | 36 | |
48 | | //------------------------------------------------- |
49 | | // device_start - device-specific startup |
50 | | //------------------------------------------------- |
51 | | void pit68230_device::device_start () |
52 | | { |
53 | | LOG (logerror ("PIT68230 device started\n")); |
54 | | m_icountptr = &m_icount; |
| 37 | /*************************************************************************** |
| 38 | IMPLEMENTATION |
| 39 | ***************************************************************************/ |
55 | 40 | |
56 | | // resolve callbacks |
57 | | m_write_pa.resolve_safe (); |
58 | | m_write_h2.resolve_safe (); |
59 | | } |
| 41 | // device type definition |
| 42 | const device_type PIT68230 = &device_creator<pit68230_device>; |
60 | 43 | |
61 | 44 | //------------------------------------------------- |
62 | | // device_reset - device-specific reset |
| 45 | // pit68230_device - constructor |
63 | 46 | //------------------------------------------------- |
64 | | void pit68230_device::device_reset () |
| 47 | |
| 48 | pit68230_device::pit68230_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 49 | : device_t(mconfig, PIT68230, "Motorola 68230 PI/T", tag, owner, clock, "pit68230", __FILE__) |
65 | 50 | { |
66 | | LOG (logerror ("PIT68230 device reseted\n")); |
67 | | m_pgcr = 0; |
68 | | m_psrr = 0; |
69 | | m_paddr = 0; |
70 | | m_pbddr = 0; |
71 | | m_pcddr = 0; |
72 | | m_pacr = 0; m_write_h2 (m_pacr); |
73 | | m_pbcr = 0; |
74 | | m_padr = 0; m_write_pa ((offs_t)0, m_padr); // TODO: check PADDR |
75 | | m_pbdr = 0; |
76 | | m_psr = 0; |
77 | 51 | } |
78 | 52 | |
79 | | //------------------------------------------------- |
80 | | // device_timer - handler timer events |
81 | | //------------------------------------------------- |
82 | | void pit68230_device::device_timer (emu_timer &timer, device_timer_id id, INT32 param, void *ptr) |
| 53 | void pit68230_device::device_start() |
83 | 54 | { |
| 55 | printf("PIT68230 device started\n"); |
84 | 56 | } |
85 | 57 | |
86 | | void pit68230_device::h1_set (UINT8 state) |
| 58 | void pit68230_device::device_reset() |
87 | 59 | { |
88 | | LOG (logerror ("h1_set %d @ m_psr %2x => ", state, m_psr)); |
89 | | if (state) m_psr |= 1; else m_psr &= ~1; |
90 | | LOG (logerror ("%02x %lld\n", m_psr, machine ().firstcpu->total_cycles ())); |
| 60 | printf("PIT68230 device reseted\n"); |
| 61 | m_pgcr = 0; |
| 62 | m_psrr = 0; |
| 63 | m_paddr = 0; |
| 64 | m_pbddr = 0; |
| 65 | m_pcddr = 0; |
| 66 | m_pacr = 0; |
| 67 | m_pbcr = 0; |
| 68 | m_padr = 0; |
| 69 | m_pbdr = 0; |
| 70 | m_psr = 0; |
91 | 71 | } |
92 | 72 | |
93 | | void pit68230_device::portb_setbit (UINT8 bit, UINT8 state) |
| 73 | WRITE8_MEMBER( pit68230_device::data_w ) |
94 | 74 | { |
95 | | LOG (logerror ("portb_setbit %d/%d @ m_pbdr %2x => ", bit, state, m_pbdr)); |
96 | | if (state) m_pbdr |= (1 << bit); else m_pbdr &= ~(1 << bit); |
97 | | LOG (logerror ("%02x %lld\n", m_pbdr, machine ().firstcpu->total_cycles ())); |
| 75 | printf("data_w: %04x -> ", data); |
| 76 | switch (offset) |
| 77 | { |
| 78 | case PIT_68230_PGCR: |
| 79 | printf("PGCR"); |
| 80 | m_pgcr = data; |
| 81 | break; |
| 82 | case PIT_68230_PSRR: |
| 83 | printf("PSRR"); |
| 84 | m_psrr = data; |
| 85 | break; |
| 86 | case PIT_68230_PADDR: |
| 87 | printf("PADDR"); |
| 88 | m_paddr = data; |
| 89 | break; |
| 90 | case PIT_68230_PBDDR: |
| 91 | printf("PBDDR"); |
| 92 | m_pbddr = data; |
| 93 | break; |
| 94 | case PIT_68230_PACR: |
| 95 | printf("PACR"); |
| 96 | m_pacr = data; |
| 97 | break; |
| 98 | case PIT_68230_PBCR: |
| 99 | printf("PBCR"); |
| 100 | m_pbcr = data; |
| 101 | break; |
| 102 | case PIT_68230_PADR: |
| 103 | printf("PADR"); |
| 104 | m_padr = data; |
| 105 | break; |
| 106 | case PIT_68230_PSR: |
| 107 | printf("PSR"); |
| 108 | m_padr = data; |
| 109 | break; |
| 110 | default: |
| 111 | printf("unhandled register %02x", offset); |
| 112 | } |
| 113 | printf("\n"); |
98 | 114 | } |
99 | 115 | |
100 | | //------------------------------------------------- |
101 | | // execute_run - |
102 | | //------------------------------------------------- |
103 | | void pit68230_device::execute_run () |
| 116 | READ8_MEMBER( pit68230_device::data_r ) |
104 | 117 | { |
105 | | do { |
106 | | synchronize (); |
| 118 | UINT8 data = 0; |
107 | 119 | |
108 | | m_icount--; |
109 | | } while (m_icount > 0); |
110 | | } |
| 120 | printf("data_r: "); |
| 121 | switch (offset) |
| 122 | { |
| 123 | case PIT_68230_PGCR: |
| 124 | printf("PGCR"); |
| 125 | data = m_pgcr; |
| 126 | break; |
| 127 | case PIT_68230_PSRR: |
| 128 | printf("PSRR"); |
| 129 | data = m_psrr; |
| 130 | break; |
| 131 | case PIT_68230_PADDR: |
| 132 | printf("PADDR"); |
| 133 | data = m_paddr; |
| 134 | break; |
| 135 | case PIT_68230_PBDDR: |
| 136 | printf("PBDDR"); |
| 137 | data = m_pbddr; |
| 138 | break; |
| 139 | case PIT_68230_PACR: |
| 140 | printf("PACR"); |
| 141 | data = m_pacr; |
| 142 | break; |
| 143 | case PIT_68230_PBCR: |
| 144 | printf("PBCR"); |
| 145 | data = m_pbcr; |
| 146 | break; |
| 147 | case PIT_68230_PADR: |
| 148 | printf("PADR"); |
| 149 | data = m_padr; |
| 150 | break; |
| 151 | case PIT_68230_PBDR: |
| 152 | /* 4.6.2. PORT B DATA REGISTER (PBDR). The port B data register is a holding register for moving data |
| 153 | to and from port B pins. The port B data direction register determines whether each pin is an input (zero) |
| 154 | or an output (one). This register is readable and writable at all times. Depending on the chosen mode/submode, |
| 155 | reading or writing may affect the double-buffered handshake mechanism. The port B data register is not affected |
| 156 | by the assertion of the RESET pin. PB0-PB7 sits on pins 17-24 on a 48 pin DIP package */ |
| 157 | printf("PBDR"); |
| 158 | data = m_pbdr; |
| 159 | // data = (m_pbdr & 0xfc) | 1; // CPU-1 centronics interface expects to see 2 lowest bits equal 1 for printer |
| 160 | break; |
| 161 | case PIT_68230_PSR: |
| 162 | printf("PSR"); |
| 163 | data = m_psr; |
| 164 | // data = m_psr | 1; // CPU-1 centronics interface expects status to be non zero |
| 165 | break; |
| 166 | default: |
| 167 | printf("unhandled register %02x", offset); |
| 168 | data = 0; |
| 169 | } |
| 170 | printf("\n"); |
111 | 171 | |
112 | | LOG (static INT32 ow_cnt = 0); |
113 | | LOG (static INT32 ow_data = 0); |
114 | | LOG (static INT32 ow_ofs = 0); |
115 | | |
116 | | WRITE8_MEMBER (pit68230_device::write){ |
117 | | switch (offset) { |
118 | | case PIT_68230_PGCR: |
119 | | m_pgcr = data; |
120 | | break; |
121 | | |
122 | | case PIT_68230_PSRR: |
123 | | m_psrr = data; |
124 | | break; |
125 | | |
126 | | case PIT_68230_PADDR: |
127 | | m_paddr = data; |
128 | | break; |
129 | | |
130 | | case PIT_68230_PBDDR: |
131 | | m_pbddr = data; |
132 | | break; |
133 | | |
134 | | case PIT_68230_PCDDR: |
135 | | m_pcddr = data; |
136 | | break; |
137 | | |
138 | | case PIT_68230_PACR: |
139 | | m_pacr = data; |
140 | | // callbacks |
141 | | /*PACR in Mode 0 |
142 | | * 5 43 H2 Control in Submode 00 && 01 |
143 | | * ------------------------------------ |
144 | | * 0 XX Input pin - edge-sensitive status input, H2S is set on an asserted edge. |
145 | | * 1 00 Output pin - negated, H2S is always clear. |
146 | | * 1 01 Output pin - asserted, H2S is always clear. |
147 | | * 1 10 Output pin - interlocked input handshake protocol, H2S is always clear. |
148 | | * 1 11 Output pin - pulsed input handshake protocol, H2S is always clear. |
149 | | * |
150 | | * 5 43 H2 Control in Submode 1x |
151 | | * ------------------------------------ |
152 | | * 0 XX Input pin - edge-sensitive status input, H2S is set on an asserted edge. |
153 | | * 1 X0 Output pin - negated, H2S is always cleared. |
154 | | * 1 X1 Output pin - asserted, H2S is always cleared. |
155 | | */ |
156 | | m_write_h2 (m_pacr & 0x08 ? 1 : 0); // TODO: Check mode and submodes |
157 | | break; |
158 | | |
159 | | case PIT_68230_PBCR: |
160 | | m_pbcr = data; |
161 | | break; |
162 | | |
163 | | case PIT_68230_PADR: |
164 | | m_padr = data; |
165 | | // callbacks |
166 | | m_write_pa ((offs_t)0, m_padr); // TODO: check PADDR |
167 | | break; |
168 | | |
169 | | case PIT_68230_PSR: |
170 | | m_psr = data; |
171 | | break; |
172 | | |
173 | | default: |
174 | | LOG (logerror ("unhandled register %02x", offset)); |
175 | | } |
176 | | |
177 | | LOG (if (offset != ow_ofs || data != ow_data || ow_cnt >= 1000) { |
178 | | logerror ("\npit68230_device::write: previous identical operation performed %02x times\n", ow_cnt); |
179 | | ow_cnt = 0; |
180 | | ow_data = data; |
181 | | ow_ofs = offset; |
182 | | logerror ("pit68230_device::write: offset=%02x data=%02x %lld\n", ow_ofs, ow_data, machine ().firstcpu->total_cycles ()); |
183 | | } |
184 | | else |
185 | | ow_cnt++; ) |
| 172 | return data; |
186 | 173 | } |
187 | | |
188 | | LOG (static INT32 or_cnt = 0); |
189 | | LOG (static INT32 or_data = 0); |
190 | | LOG (static INT32 or_ofs = 0); |
191 | | |
192 | | READ8_MEMBER (pit68230_device::read){ |
193 | | UINT8 data = 0; |
194 | | |
195 | | switch (offset) { |
196 | | case PIT_68230_PGCR: |
197 | | data = m_pgcr; |
198 | | break; |
199 | | |
200 | | case PIT_68230_PSRR: |
201 | | data = m_psrr; |
202 | | break; |
203 | | |
204 | | case PIT_68230_PADDR: |
205 | | data = m_paddr; |
206 | | break; |
207 | | |
208 | | case PIT_68230_PBDDR: |
209 | | data = m_pbddr; |
210 | | break; |
211 | | |
212 | | case PIT_68230_PCDDR: |
213 | | data = m_pcddr; |
214 | | break; |
215 | | |
216 | | case PIT_68230_PACR: |
217 | | data = m_pacr; |
218 | | break; |
219 | | |
220 | | case PIT_68230_PBCR: |
221 | | data = m_pbcr; |
222 | | break; |
223 | | |
224 | | case PIT_68230_PADR: |
225 | | data = m_padr; |
226 | | break; |
227 | | |
228 | | case PIT_68230_PBDR: |
229 | | /* 4.6.2. PORT B DATA REGISTER (PBDR). The port B data register is a holding |
230 | | * register for moving data to and from port B pins. The port B data direction |
231 | | * register determines whether each pin is an input (zero) or an output (one). |
232 | | * This register is readable and writable at all times. Depending on the chosen |
233 | | * mode/submode, reading or writing may affect the double-buffered handshake |
234 | | * mechanism. The port B data register is not affected by the assertion of the |
235 | | * RESET pin. PB0-PB7 sits on pins 17-24 on a 48 pin DIP package */ |
236 | | data = m_pbdr; |
237 | | break; |
238 | | |
239 | | case PIT_68230_PSR: |
240 | | /* 4.8. PORT STATUS REGISTER (PSR) The port status register contains information about |
241 | | * handshake pin activity. Bits 7-4 show the instantaneous level of the respective handshake |
242 | | * pin, and are independent of the handshake pin sense bits in the port general control |
243 | | * register. Bits 3-0 are the respective status bits referred to throughout this document. |
244 | | * Their interpretation depends on the programmed mode/submode of the PI/T. For bits |
245 | | * 3-0 a one is the active or asserted state. */ |
246 | | data = m_psr; |
247 | | break; |
248 | | |
249 | | default: |
250 | | LOG (logerror ("unhandled register %02x", offset)); |
251 | | data = 0; |
252 | | } |
253 | | |
254 | | LOG (if (offset != or_ofs || data != or_data || or_cnt >= 1000) { |
255 | | logerror ("\npit68230_device::read: previous identical operation performed %02x times\n", or_cnt); |
256 | | or_cnt = 0; |
257 | | or_data = data; |
258 | | or_ofs = offset; |
259 | | logerror ("pit68230_device::read: offset=%02x data=%02x %lld\n", or_ofs, or_data, machine ().firstcpu->total_cycles ()); |
260 | | } |
261 | | else |
262 | | or_cnt++; ) |
263 | | |
264 | | return data; |
265 | | } |
trunk/src/emu/sound/tms5110.c
r249094 | r249095 | |
14 | 14 | |
15 | 15 | Todo: |
16 | 16 | - implement CS |
| 17 | - implement missing commands |
17 | 18 | - TMS5110_CMD_TEST_TALK is only partially implemented |
18 | 19 | |
19 | 20 | TMS5100: |
r249094 | r249095 | |
78 | 79 | //define INTERP_SHIFT / (1<<m_coeff->interp_coeff[m_IP]) |
79 | 80 | |
80 | 81 | /* Other hacks */ |
81 | | /* HACK: if defined, outputs the low 4 bits of the lattice filter to the i/o |
| 82 | /* HACK?: if defined, outputs the low 4 bits of the lattice filter to the i/o |
82 | 83 | * or clip logic, even though the real hardware doesn't do this, partially verified by decap */ |
83 | 84 | #undef ALLOW_4_LSB |
84 | 85 | |
85 | | /* forces m_TALK active instantly whenever m_SPEN would be activated, causing speech delay to be reduced by up to one frame time */ |
86 | | /* for some reason, this hack makes snmath behave marginally more accurate to hardware, though it does not match the patent */ |
87 | | #define FAST_START_HACK 1 |
88 | 86 | |
89 | | |
90 | 87 | /* *****configuration of chip connection stuff***** */ |
91 | 88 | /* must be defined; if 0, output the waveform as if it was tapped on the speaker pin as usual, if 1, output the waveform as if it was tapped on the i/o pin (volume is much lower in the latter case) */ |
92 | 89 | #define FORCE_DIGITAL 0 |
r249094 | r249095 | |
215 | 212 | { |
216 | 213 | save_item(NAME(m_variant)); |
217 | 214 | |
| 215 | save_item(NAME(m_fifo)); |
| 216 | save_item(NAME(m_fifo_head)); |
| 217 | save_item(NAME(m_fifo_tail)); |
| 218 | save_item(NAME(m_fifo_count)); |
| 219 | |
218 | 220 | save_item(NAME(m_PDC)); |
219 | 221 | save_item(NAME(m_CTL_pins)); |
220 | 222 | save_item(NAME(m_SPEN)); |
r249094 | r249095 | |
239 | 241 | save_item(NAME(m_old_frame_pitch_idx)); |
240 | 242 | save_item(NAME(m_old_frame_k_idx)); |
241 | 243 | save_item(NAME(m_old_zpar)); |
242 | | save_item(NAME(m_old_uv_zpar)); |
243 | 244 | #endif |
244 | 245 | save_item(NAME(m_current_energy)); |
245 | 246 | save_item(NAME(m_current_pitch)); |
r249094 | r249095 | |
309 | 310 | } |
310 | 311 | #endif |
311 | 312 | |
| 313 | |
312 | 314 | /****************************************************************************************** |
313 | 315 | |
314 | | extract_bits -- extract a specific number of bits from the VSM |
| 316 | FIFO_data_write -- handle bit data write to the TMS5110 (as a result of toggling M0 pin) |
315 | 317 | |
316 | 318 | ******************************************************************************************/ |
| 319 | void tms5110_device::FIFO_data_write(int data) |
| 320 | { |
| 321 | /* add this bit to the FIFO */ |
| 322 | if (m_fifo_count < FIFO_SIZE) |
| 323 | { |
| 324 | m_fifo[m_fifo_tail] = (data&1); /* set bit to 1 or 0 */ |
317 | 325 | |
| 326 | m_fifo_tail = (m_fifo_tail + 1) % FIFO_SIZE; |
| 327 | m_fifo_count++; |
| 328 | |
| 329 | if (DEBUG_5110) logerror("Added bit to FIFO (size=%2d)\n", m_fifo_count); |
| 330 | } |
| 331 | else |
| 332 | { |
| 333 | if (DEBUG_5110) logerror("Ran out of room in the FIFO!\n"); |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | /****************************************************************************************** |
| 338 | |
| 339 | extract_bits -- extract a specific number of bits from the FIFO |
| 340 | |
| 341 | ******************************************************************************************/ |
| 342 | |
318 | 343 | int tms5110_device::extract_bits(int count) |
319 | 344 | { |
320 | 345 | int val = 0; |
321 | | if (DEBUG_5110) logerror("requesting %d bits", count); |
322 | | for (int i = 0; i < count; i++) |
| 346 | if (DEBUG_5110) logerror("requesting %d bits from fifo: ", count); |
| 347 | while (count--) |
323 | 348 | { |
324 | | val = (val<<1) | new_int_read(); |
325 | | if (DEBUG_5110) logerror("bit read: %d\n", val&1); |
| 349 | val = (val << 1) | (m_fifo[m_fifo_head] & 1); |
| 350 | m_fifo_count--; |
| 351 | m_fifo_head = (m_fifo_head + 1) % FIFO_SIZE; |
326 | 352 | } |
327 | 353 | if (DEBUG_5110) logerror("returning: %02x\n", val); |
328 | 354 | return val; |
329 | 355 | } |
330 | 356 | |
| 357 | void tms5110_device::request_bits(int no) |
| 358 | { |
| 359 | for (int i = 0; i < no; i++) |
| 360 | { |
| 361 | UINT8 data = new_int_read(); |
| 362 | if (DEBUG_5110) logerror("bit added to fifo: %d\n", data); |
| 363 | FIFO_data_write(data); |
| 364 | } |
| 365 | } |
331 | 366 | |
332 | 367 | void tms5110_device::perform_dummy_read() |
333 | 368 | { |
r249094 | r249095 | |
354 | 389 | int i, bitout; |
355 | 390 | INT32 this_sample; |
356 | 391 | |
| 392 | /* if we're not speaking, fill with nothingness */ |
| 393 | if (!m_TALKD) |
| 394 | goto empty; |
| 395 | |
357 | 396 | /* loop until the buffer is full or we've stopped speaking */ |
358 | | while (size > 0) |
| 397 | while ((size > 0) && m_TALKD) |
359 | 398 | { |
360 | | if(m_TALKD) // speaking |
| 399 | /* if it is the appropriate time to update the old energy/pitch indices, |
| 400 | * i.e. when IP=7, PC=12, T=17, subcycle=2, do so. Since IP=7 PC=12 T=17 |
| 401 | * is JUST BEFORE the transition to IP=0 PC=0 T=0 sybcycle=(0 or 1), |
| 402 | * which happens 4 T-cycles later), we change on the latter. |
| 403 | * The indices are updated here ~12 PCs before the new frame is applied. |
| 404 | */ |
| 405 | /** TODO: the patents 4331836, 4335277, and 4419540 disagree about the timing of this **/ |
| 406 | if ((m_IP == 0) && (m_PC == 0) && (m_subcycle < 2)) |
361 | 407 | { |
362 | | /* if we're ready for a new frame to be applied, i.e. when IP=0, PC=12, Sub=1 |
363 | | * (In reality, the frame was really loaded incrementally during the entire IP=0 |
364 | | * PC=x time period, but it doesn't affect anything until IP=0 PC=12 happens) |
365 | | */ |
366 | | if ((m_IP == 0) && (m_PC == 12) && (m_subcycle == 1)) |
367 | | { |
368 | | // HACK for regression testing, be sure to comment out before release! |
369 | | //m_RNG = 0x1234; |
370 | | // end HACK |
| 408 | m_OLDE = (m_new_frame_energy_idx == 0); |
| 409 | m_OLDP = (m_new_frame_pitch_idx == 0); |
| 410 | } |
371 | 411 | |
| 412 | /* if we're ready for a new frame to be applied, i.e. when IP=0, PC=12, Sub=1 |
| 413 | * (In reality, the frame was really loaded incrementally during the entire IP=0 |
| 414 | * PC=x time period, but it doesn't affect anything until IP=0 PC=12 happens) |
| 415 | */ |
| 416 | if ((m_IP == 0) && (m_PC == 12) && (m_subcycle == 1)) |
| 417 | { |
| 418 | // HACK for regression testing, be sure to comment out before release! |
| 419 | //m_RNG = 0x1234; |
| 420 | // end HACK |
| 421 | |
372 | 422 | #ifdef PERFECT_INTERPOLATION_HACK |
373 | | /* remember previous frame energy, pitch, and coefficients */ |
374 | | m_old_frame_energy_idx = m_new_frame_energy_idx; |
375 | | m_old_frame_pitch_idx = m_new_frame_pitch_idx; |
376 | | for (i = 0; i < m_coeff->num_k; i++) |
377 | | m_old_frame_k_idx[i] = m_new_frame_k_idx[i]; |
| 423 | /* remember previous frame energy, pitch, and coefficients */ |
| 424 | m_old_frame_energy_idx = m_new_frame_energy_idx; |
| 425 | m_old_frame_pitch_idx = m_new_frame_pitch_idx; |
| 426 | for (i = 0; i < m_coeff->num_k; i++) |
| 427 | m_old_frame_k_idx[i] = m_new_frame_k_idx[i]; |
378 | 428 | #endif |
379 | 429 | |
380 | | /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[] */ |
381 | | parse_frame(); |
382 | | |
383 | | // if the new frame is unvoiced (or silenced via ZPAR), be sure to zero out the k5-k10 parameters |
384 | | // NOTE: this is probably the bug the tms5100/tmc0280 has, pre-rev D, I think. |
385 | | // GUESS: Pre-rev D versions start zeroing k5-k10 immediately upon new frame load regardless of interpolation inhibit |
386 | | // I.e. ZPAR = /TALKD || (PC>5&&P=0) |
387 | | // GUESS: D and later versions only start or stop zeroing k5-k10 at the IP7->IP0 transition AFTER the frame |
388 | | // I.e. ZPAR = /TALKD || (PC>5&&OLDP) |
389 | | #ifdef PERFECT_INTERPOLATION_HACK |
390 | | m_old_uv_zpar = m_uv_zpar; |
391 | | m_old_zpar = m_zpar; // unset old zpar on new frame |
| 430 | /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[] */ |
| 431 | parse_frame(); |
| 432 | #ifdef DEBUG_PARSE_FRAME_DUMP |
| 433 | fprintf(stderr,"\n"); |
392 | 434 | #endif |
393 | | m_zpar = 0; |
394 | | //m_uv_zpar = (OLD_FRAME_UNVOICED_FLAG||m_zpar); // GUESS: fixed version in tmc0280d/tms5100a/cd280x/tms5110 |
395 | | m_uv_zpar = (NEW_FRAME_UNVOICED_FLAG||m_zpar); // GUESS: buggy version in tmc0280/tms5100 |
| 435 | /* if the new frame is unvoiced (or silenced via ZPAR), be sure to zero out the k5-k10 parameters */ |
| 436 | m_uv_zpar = NEW_FRAME_UNVOICED_FLAG | m_zpar; |
396 | 437 | |
397 | | /* if the new frame is a stop frame, unset both TALK and SPEN (via TCON). TALKD remains active while the energy is ramping to 0. */ |
398 | | if (NEW_FRAME_STOP_FLAG == 1) |
399 | | { |
400 | | m_TALK = m_SPEN = 0; |
401 | | } |
| 438 | /* if the new frame is a stop frame, unset both TALK and SPEN. TALKD remains active while the energy is ramping to 0. */ |
| 439 | if (NEW_FRAME_STOP_FLAG == 1) |
| 440 | { |
| 441 | m_TALK = m_SPEN = 0; |
| 442 | } |
402 | 443 | |
403 | | /* in all cases where interpolation would be inhibited, set the inhibit flag; otherwise clear it. |
404 | | Interpolation inhibit cases: |
405 | | * Old frame was voiced, new is unvoiced |
406 | | * Old frame was silence/zero energy, new has nonzero energy |
407 | | * Old frame was unvoiced, new is voiced (note this is the case on the patent but may not be correct on the real final chip) |
408 | | */ |
409 | | if ( ((OLD_FRAME_UNVOICED_FLAG == 0) && (NEW_FRAME_UNVOICED_FLAG == 1)) |
410 | | || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_UNVOICED_FLAG == 0)) /* this line needs further investigation, starwars tie fighters may sound better without it */ |
411 | | || ((OLD_FRAME_SILENCE_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 0)) ) |
412 | | m_inhibit = 1; |
413 | | else // normal frame, normal interpolation |
414 | | m_inhibit = 0; |
| 444 | /* in all cases where interpolation would be inhibited, set the inhibit flag; otherwise clear it. |
| 445 | Interpolation inhibit cases: |
| 446 | * Old frame was voiced, new is unvoiced |
| 447 | * Old frame was silence/zero energy, new has nonzero energy |
| 448 | * Old frame was unvoiced, new is voiced (note this is the case on the patent but may not be correct on the real final chip) |
| 449 | */ |
| 450 | if ( ((OLD_FRAME_UNVOICED_FLAG == 0) && (NEW_FRAME_UNVOICED_FLAG == 1)) |
| 451 | || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_UNVOICED_FLAG == 0)) /* this line needs further investigation, starwars tie fighters may sound better without it */ |
| 452 | || ((OLD_FRAME_SILENCE_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 0)) ) |
| 453 | m_inhibit = 1; |
| 454 | else // normal frame, normal interpolation |
| 455 | m_inhibit = 0; |
415 | 456 | |
416 | 457 | #ifdef DEBUG_GENERATION |
417 | | /* Debug info for current parsed frame */ |
418 | | fprintf(stderr, "OLDE: %d; OLDP: %d; ", m_OLDE, m_OLDP); |
419 | | fprintf(stderr,"Processing new frame: "); |
420 | | if (m_inhibit == 0) |
421 | | fprintf(stderr, "Normal Frame\n"); |
422 | | else |
423 | | fprintf(stderr,"Interpolation Inhibited\n"); |
424 | | fprintf(stderr,"*** current Energy, Pitch and Ks = %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_current_energy, m_current_pitch, m_current_k[0], m_current_k[1], m_current_k[2], m_current_k[3], m_current_k[4], m_current_k[5], m_current_k[6], m_current_k[7], m_current_k[8], m_current_k[9]); |
425 | | fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n", |
426 | | (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)), |
427 | | m_new_frame_energy_idx, |
428 | | (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)), |
429 | | (m_coeff->ktable[0][m_new_frame_k_idx[0]] * (1-m_zpar)), |
430 | | (m_coeff->ktable[1][m_new_frame_k_idx[1]] * (1-m_zpar)), |
431 | | (m_coeff->ktable[2][m_new_frame_k_idx[2]] * (1-m_zpar)), |
432 | | (m_coeff->ktable[3][m_new_frame_k_idx[3]] * (1-m_zpar)), |
433 | | (m_coeff->ktable[4][m_new_frame_k_idx[4]] * (1-m_uv_zpar)), |
434 | | (m_coeff->ktable[5][m_new_frame_k_idx[5]] * (1-m_uv_zpar)), |
435 | | (m_coeff->ktable[6][m_new_frame_k_idx[6]] * (1-m_uv_zpar)), |
436 | | (m_coeff->ktable[7][m_new_frame_k_idx[7]] * (1-m_uv_zpar)), |
437 | | (m_coeff->ktable[8][m_new_frame_k_idx[8]] * (1-m_uv_zpar)), |
438 | | (m_coeff->ktable[9][m_new_frame_k_idx[9]] * (1-m_uv_zpar)) ); |
| 458 | /* Debug info for current parsed frame */ |
| 459 | fprintf(stderr, "OLDE: %d; OLDP: %d; ", m_OLDE, m_OLDP); |
| 460 | fprintf(stderr,"Processing frame: "); |
| 461 | if (m_inhibit == 0) |
| 462 | fprintf(stderr, "Normal Frame\n"); |
| 463 | else |
| 464 | fprintf(stderr,"Interpolation Inhibited\n"); |
| 465 | fprintf(stderr,"*** current Energy, Pitch and Ks = %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_current_energy, m_current_pitch, m_current_k[0], m_current_k[1], m_current_k[2], m_current_k[3], m_current_k[4], m_current_k[5], m_current_k[6], m_current_k[7], m_current_k[8], m_current_k[9]); |
| 466 | fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n", |
| 467 | (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)), |
| 468 | m_new_frame_energy_idx, |
| 469 | (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)), |
| 470 | (m_coeff->ktable[0][m_new_frame_k_idx[0]] * (1-m_zpar)), |
| 471 | (m_coeff->ktable[1][m_new_frame_k_idx[1]] * (1-m_zpar)), |
| 472 | (m_coeff->ktable[2][m_new_frame_k_idx[2]] * (1-m_zpar)), |
| 473 | (m_coeff->ktable[3][m_new_frame_k_idx[3]] * (1-m_zpar)), |
| 474 | (m_coeff->ktable[4][m_new_frame_k_idx[4]] * (1-m_uv_zpar)), |
| 475 | (m_coeff->ktable[5][m_new_frame_k_idx[5]] * (1-m_uv_zpar)), |
| 476 | (m_coeff->ktable[6][m_new_frame_k_idx[6]] * (1-m_uv_zpar)), |
| 477 | (m_coeff->ktable[7][m_new_frame_k_idx[7]] * (1-m_uv_zpar)), |
| 478 | (m_coeff->ktable[8][m_new_frame_k_idx[8]] * (1-m_uv_zpar)), |
| 479 | (m_coeff->ktable[9][m_new_frame_k_idx[9]] * (1-m_uv_zpar)) ); |
439 | 480 | #endif |
440 | 481 | |
| 482 | } |
| 483 | else // Not a new frame, just interpolate the existing frame. |
| 484 | { |
| 485 | int inhibit_state = ((m_inhibit==1)&&(m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the m_inhibit value |
| 486 | #ifdef PERFECT_INTERPOLATION_HACK |
| 487 | int samples_per_frame = m_subc_reload?175:266; // either (13 A cycles + 12 B cycles) * 7 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 7 interps for SPKSLOW |
| 488 | //int samples_per_frame = m_subc_reload?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW |
| 489 | int current_sample = (m_subcycle - m_subc_reload)+(m_PC*(3-m_subc_reload))+((m_subc_reload?25:38)*((m_IP-1)&7)); |
| 490 | //fprintf(stderr, "CS: %03d", current_sample); |
| 491 | // reset the current energy, pitch, etc to what it was at frame start |
| 492 | m_current_energy = (m_coeff->energytable[m_old_frame_energy_idx] * (1-m_zpar)); |
| 493 | m_current_pitch = (m_coeff->pitchtable[m_old_frame_pitch_idx] * (1-m_old_zpar)); |
| 494 | for (i = 0; i < 4; i++) |
| 495 | m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-m_old_zpar)); |
| 496 | for (i = 4; i < m_coeff->num_k; i++) |
| 497 | m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-m_uv_zpar)); |
| 498 | // now adjust each value to be exactly correct for each of the samples per frame |
| 499 | if (m_IP != 0) // if we're still interpolating... |
| 500 | { |
| 501 | m_current_energy += ((((m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)) - m_current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame; |
| 502 | m_current_pitch += ((((m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)) - m_current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame; |
| 503 | for (i = 0; i < m_coeff->num_k; i++) |
| 504 | m_current_k[i] += ((((m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-((i<4)?m_zpar:m_uv_zpar))) - m_current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame; |
441 | 505 | } |
442 | | else // Not a new frame, just interpolate the existing frame. |
| 506 | else // we're done, play this frame for 1/8 frame. |
443 | 507 | { |
444 | | int inhibit_state = ((m_inhibit==1)&&(m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the m_inhibit value |
445 | | #ifdef PERFECT_INTERPOLATION_HACK |
446 | | int samples_per_frame = m_subc_reload?175:266; // either (13 A cycles + 12 B cycles) * 7 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 7 interps for SPKSLOW |
447 | | //int samples_per_frame = m_subc_reload?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW |
448 | | int current_sample = (m_subcycle - m_subc_reload)+(m_PC*(3-m_subc_reload))+((m_subc_reload?25:38)*((m_IP-1)&7)); |
449 | | //fprintf(stderr, "CS: %03d", current_sample); |
450 | | // reset the current energy, pitch, etc to what it was at frame start |
451 | | m_current_energy = (m_coeff->energytable[m_old_frame_energy_idx] * (1-m_old_zpar)); |
452 | | m_current_pitch = (m_coeff->pitchtable[m_old_frame_pitch_idx] * (1-m_old_zpar)); |
| 508 | m_current_energy = (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)); |
| 509 | m_current_pitch = (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)); |
453 | 510 | for (i = 0; i < m_coeff->num_k; i++) |
454 | | m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-((i<4)?m_old_zpar:m_old_uv_zpar))); |
455 | | // now adjust each value to be exactly correct for each of the samples per frame |
456 | | if (m_IP != 0) // if we're still interpolating... |
457 | | { |
458 | | m_current_energy = (m_current_energy + (((m_coeff->energytable[m_new_frame_energy_idx] - m_current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-m_zpar); |
459 | | m_current_pitch = (m_current_pitch + (((m_coeff->pitchtable[m_new_frame_pitch_idx] - m_current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-m_zpar); |
460 | | for (i = 0; i < m_coeff->num_k; i++) |
461 | | m_current_k[i] = (m_current_k[i] + (((m_coeff->ktable[i][m_new_frame_k_idx[i]] - m_current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-((i<4)?m_zpar:m_uv_zpar)); |
462 | | } |
463 | | else // we're done, play this frame for 1/8 frame. |
464 | | { |
465 | | m_current_energy = (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)); |
466 | | m_current_pitch = (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)); |
467 | | for (i = 0; i < m_coeff->num_k; i++) |
468 | | m_current_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-((i<4)?m_zpar:m_uv_zpar))); |
469 | | } |
| 511 | m_current_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-((i<4)?m_zpar:m_uv_zpar))); |
| 512 | } |
470 | 513 | #else |
471 | | //Updates to parameters only happen on subcycle '2' (B cycle) of PCs. |
472 | | if (m_subcycle == 2) |
| 514 | //Updates to parameters only happen on subcycle '2' (B cycle) of PCs. |
| 515 | if (m_subcycle == 2) |
| 516 | { |
| 517 | switch(m_PC) |
473 | 518 | { |
474 | | switch(m_PC) |
475 | | { |
476 | | case 0: /* PC = 0, B cycle, write updated energy */ |
477 | | m_current_energy = (m_current_energy + (((m_coeff->energytable[m_new_frame_energy_idx] - m_current_energy)*(1-inhibit_state)) INTERP_SHIFT))*(1-m_zpar); |
478 | | break; |
479 | | case 1: /* PC = 1, B cycle, write updated pitch */ |
480 | | m_current_pitch = (m_current_pitch + (((m_coeff->pitchtable[m_new_frame_pitch_idx] - m_current_pitch)*(1-inhibit_state)) INTERP_SHIFT))*(1-m_zpar); |
481 | | break; |
482 | | case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: |
483 | | /* PC = 2 through 11, B cycle, write updated K1 through K10 */ |
484 | | m_current_k[m_PC-2] = (m_current_k[m_PC-2] + (((m_coeff->ktable[m_PC-2][m_new_frame_k_idx[m_PC-2]] - m_current_k[m_PC-2])*(1-inhibit_state)) INTERP_SHIFT))*(((m_PC-2)>4)?(1-m_uv_zpar):(1-m_zpar)); |
485 | | break; |
486 | | case 12: /* PC = 12 */ |
487 | | /* we should NEVER reach this point, PC=12 doesn't have a subcycle 2 */ |
488 | | break; |
489 | | } |
| 519 | case 0: /* PC = 0, B cycle, write updated energy */ |
| 520 | m_current_energy += ((((m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)) - m_current_energy)*(1-inhibit_state)) INTERP_SHIFT); |
| 521 | break; |
| 522 | case 1: /* PC = 1, B cycle, write updated pitch */ |
| 523 | m_current_pitch += ((((m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)) - m_current_pitch)*(1-inhibit_state)) INTERP_SHIFT); |
| 524 | break; |
| 525 | case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: |
| 526 | /* PC = 2 through 11, B cycle, write updated K1 through K10 */ |
| 527 | m_current_k[m_PC-2] += ((((m_coeff->ktable[m_PC-2][m_new_frame_k_idx[m_PC-2]] * (1-(((m_PC-2)<4)?m_zpar:m_uv_zpar))) - m_current_k[m_PC-2])*(1-inhibit_state)) INTERP_SHIFT); |
| 528 | break; |
| 529 | case 12: /* PC = 12, do nothing */ |
| 530 | break; |
490 | 531 | } |
| 532 | } |
491 | 533 | #endif |
492 | | } |
| 534 | } |
493 | 535 | |
494 | | // calculate the output |
495 | | if (OLD_FRAME_UNVOICED_FLAG == 1) |
496 | | { |
497 | | // generate unvoiced samples here |
498 | | if (m_RNG & 1) |
499 | | m_excitation_data = ~0x3F; /* according to the patent it is (either + or -) half of the maximum value in the chirp table, so either 01000000(0x40) or 11000000(0xC0)*/ |
500 | | else |
501 | | m_excitation_data = 0x40; |
502 | | } |
503 | | else /* (OLD_FRAME_UNVOICED_FLAG == 0) */ |
504 | | { |
505 | | // generate voiced samples here |
506 | | /* US patent 4331836 Figure 14B shows, and logic would hold, that a pitch based chirp |
507 | | * function has a chirp/peak and then a long chain of zeroes. |
508 | | * The last entry of the chirp rom is at address 0b110011 (51d), the 52nd sample, |
509 | | * and if the address reaches that point the ADDRESS incrementer is |
510 | | * disabled, forcing all samples beyond 51d to be == 51d |
511 | | */ |
512 | | if (m_pitch_count >= 51) |
513 | | m_excitation_data = (INT8)m_coeff->chirptable[51]; |
514 | | else /*m_pitch_count < 51*/ |
515 | | m_excitation_data = (INT8)m_coeff->chirptable[m_pitch_count]; |
516 | | } |
| 536 | // calculate the output |
| 537 | if (OLD_FRAME_UNVOICED_FLAG == 1) |
| 538 | { |
| 539 | // generate unvoiced samples here |
| 540 | if (m_RNG & 1) |
| 541 | m_excitation_data = ~0x3F; /* according to the patent it is (either + or -) half of the maximum value in the chirp table, so either 01000000(0x40) or 11000000(0xC0)*/ |
| 542 | else |
| 543 | m_excitation_data = 0x40; |
| 544 | } |
| 545 | else /* (OLD_FRAME_UNVOICED_FLAG == 0) */ |
| 546 | { |
| 547 | // generate voiced samples here |
| 548 | /* US patent 4331836 Figure 14B shows, and logic would hold, that a pitch based chirp |
| 549 | * function has a chirp/peak and then a long chain of zeroes. |
| 550 | * The last entry of the chirp rom is at address 0b110011 (51d), the 52nd sample, |
| 551 | * and if the address reaches that point the ADDRESS incrementer is |
| 552 | * disabled, forcing all samples beyond 51d to be == 51d |
| 553 | */ |
| 554 | if (m_pitch_count >= 51) |
| 555 | m_excitation_data = (INT8)m_coeff->chirptable[51]; |
| 556 | else /*m_pitch_count < 51*/ |
| 557 | m_excitation_data = (INT8)m_coeff->chirptable[m_pitch_count]; |
| 558 | } |
517 | 559 | |
518 | | // Update LFSR *20* times every sample (once per T cycle), like patent shows |
519 | | for (i=0; i<20; i++) |
520 | | { |
521 | | bitout = ((m_RNG >> 12) & 1) ^ |
522 | | ((m_RNG >> 3) & 1) ^ |
523 | | ((m_RNG >> 2) & 1) ^ |
524 | | ((m_RNG >> 0) & 1); |
525 | | m_RNG <<= 1; |
526 | | m_RNG |= bitout; |
527 | | } |
528 | | this_sample = lattice_filter(); /* execute lattice filter */ |
| 560 | // Update LFSR *20* times every sample (once per T cycle), like patent shows |
| 561 | for (i=0; i<20; i++) |
| 562 | { |
| 563 | bitout = ((m_RNG >> 12) & 1) ^ |
| 564 | ((m_RNG >> 3) & 1) ^ |
| 565 | ((m_RNG >> 2) & 1) ^ |
| 566 | ((m_RNG >> 0) & 1); |
| 567 | m_RNG <<= 1; |
| 568 | m_RNG |= bitout; |
| 569 | } |
| 570 | this_sample = lattice_filter(); /* execute lattice filter */ |
529 | 571 | #ifdef DEBUG_GENERATION_VERBOSE |
530 | | //fprintf(stderr,"C:%01d; ",m_subcycle); |
531 | | fprintf(stderr,"IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",m_IP, m_PC, m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); |
532 | | //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); |
533 | | for (i=0; i<10; i++) |
534 | | fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]); |
535 | | fprintf(stderr,"Out:%06d ", this_sample); |
536 | | //#ifdef PERFECT_INTERPOLATION_HACK |
537 | | // fprintf(stderr,"%d%d%d%d",m_old_zpar,m_zpar,m_old_uv_zpar,m_uv_zpar); |
538 | | //#else |
539 | | // fprintf(stderr,"x%dx%d",m_zpar,m_uv_zpar); |
540 | | //#endif |
541 | | fprintf(stderr,"\n"); |
| 572 | //fprintf(stderr,"C:%01d; ",m_subcycle); |
| 573 | fprintf(stderr,"IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",m_IP, m_PC, m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); |
| 574 | //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); |
| 575 | for (i=0; i<10; i++) |
| 576 | fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]); |
| 577 | fprintf(stderr,"Out:%06d", this_sample); |
| 578 | fprintf(stderr,"\n"); |
542 | 579 | #endif |
543 | | /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */ |
544 | | while (this_sample > 16383) this_sample -= 32768; |
545 | | while (this_sample < -16384) this_sample += 32768; |
546 | | if (m_digital_select == 0) // analog SPK pin output is only 8 bits, with clipping |
547 | | buffer[buf_count] = clip_analog(this_sample); |
548 | | else // digital I/O pin output is 12 bits |
549 | | { |
| 580 | /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */ |
| 581 | while (this_sample > 16383) this_sample -= 32768; |
| 582 | while (this_sample < -16384) this_sample += 32768; |
| 583 | if (m_digital_select == 0) // analog SPK pin output is only 8 bits, with clipping |
| 584 | buffer[buf_count] = clip_analog(this_sample); |
| 585 | else // digital I/O pin output is 12 bits |
| 586 | { |
550 | 587 | #ifdef ALLOW_4_LSB |
551 | | // input: ssss ssss ssss ssss ssnn nnnn nnnn nnnn |
552 | | // N taps: ^ = 0x2000; |
553 | | // output: ssss ssss ssss ssss snnn nnnn nnnn nnnN |
554 | | buffer[buf_count] = (this_sample<<1)|((this_sample&0x2000)>>13); |
| 588 | // input: ssss ssss ssss ssss ssnn nnnn nnnn nnnn |
| 589 | // N taps: ^ = 0x2000; |
| 590 | // output: ssss ssss ssss ssss snnn nnnn nnnn nnnN |
| 591 | buffer[buf_count] = (this_sample<<1)|((this_sample&0x2000)>>13); |
555 | 592 | #else |
556 | | this_sample &= ~0xF; |
557 | | // input: ssss ssss ssss ssss ssnn nnnn nnnn 0000 |
558 | | // N taps: ^^ ^^^ = 0x3E00; |
559 | | // output: ssss ssss ssss ssss snnn nnnn nnnN NNNN |
560 | | buffer[buf_count] = (this_sample<<1)|((this_sample&0x3E00)>>9); |
| 593 | this_sample &= ~0xF; |
| 594 | // input: ssss ssss ssss ssss ssnn nnnn nnnn 0000 |
| 595 | // N taps: ^^ ^^^ = 0x3E00; |
| 596 | // output: ssss ssss ssss ssss snnn nnnn nnnN NNNN |
| 597 | buffer[buf_count] = (this_sample<<1)|((this_sample&0x3E00)>>9); |
561 | 598 | #endif |
562 | | } |
563 | | // Update all counts |
| 599 | } |
| 600 | // Update all counts |
564 | 601 | |
565 | | m_subcycle++; |
566 | | if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3 |
| 602 | m_subcycle++; |
| 603 | if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3 |
| 604 | { |
| 605 | /* Circuit 412 in the patent acts a reset, resetting the pitch counter to 0 |
| 606 | * if INHIBIT was true during the most recent frame transition. |
| 607 | * The exact time this occurs is betwen IP=7, PC=12 sub=0, T=t12 |
| 608 | * and m_IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles, |
| 609 | * which overlaps the time OLDE and OLDP are updated at IP=7 PC=12 T17 |
| 610 | * (and hence INHIBIT itself 2 t-cycles later). We do it here because it is |
| 611 | * convenient and should make no difference in output. |
| 612 | */ |
| 613 | if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_zero = 1; |
| 614 | if ((m_IP == 0)&&(m_pitch_zero==1)) m_pitch_zero = 0; |
| 615 | #ifdef PERFECT_INTERPOLATION_HACK |
| 616 | m_old_zpar = m_zpar; |
| 617 | #endif |
| 618 | m_zpar = 0; /* this gets effectively reset by resetf3, same signal which resets m_PC to 0 */ |
| 619 | if (m_IP == 7) // RESETL4 |
567 | 620 | { |
568 | | /* Circuit 412 in the patent acts a reset, resetting the pitch counter to 0 |
569 | | * if INHIBIT was true during the most recent frame transition. |
570 | | * The exact time this occurs is betwen IP=7, PC=12 sub=0, T=t12 |
571 | | * and m_IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles, |
572 | | * which overlaps the time OLDE and OLDP are updated at IP=7 PC=12 T17 |
573 | | * (and hence INHIBIT itself 2 t-cycles later). We do it here because it is |
574 | | * convenient and should make no difference in output. |
575 | | */ |
576 | | if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_zero = 1; |
577 | | if ((m_IP == 0)&&(m_pitch_zero==1)) m_pitch_zero = 0; |
578 | | if (m_IP == 7) // RESETL4 |
579 | | { |
580 | | // Latch OLDE and OLDP |
581 | | OLD_FRAME_SILENCE_FLAG = NEW_FRAME_SILENCE_FLAG; // m_OLDE |
582 | | OLD_FRAME_UNVOICED_FLAG = NEW_FRAME_UNVOICED_FLAG; // m_OLDP |
583 | | /* if TALK was clear last frame, halt speech now, since TALKD (latched from TALK on new frame) just went inactive. */ |
| 621 | /* if TALK was clear last frame, halt speech now, since TALKD (latched from TALK on new frame) just went inactive. */ |
584 | 622 | #ifdef DEBUG_GENERATION |
585 | | if (m_TALK == 0) |
586 | | fprintf(stderr,"tms5110_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n"); |
| 623 | if (m_TALK == 0) |
| 624 | fprintf(stderr,"tms5110_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n"); |
587 | 625 | #endif |
588 | | m_TALKD = m_TALK; // TALKD is latched from TALK |
589 | | m_TALK = m_SPEN; // TALK is latched from SPEN |
590 | | } |
591 | | m_subcycle = m_subc_reload; |
592 | | m_PC = 0; |
593 | | m_IP++; |
594 | | m_IP&=0x7; |
| 626 | m_TALKD = m_TALK; // TALKD is latched from TALK |
| 627 | m_TALK = m_SPEN; // TALK is latched from SPEN |
595 | 628 | } |
596 | | else if (m_subcycle == 3) |
597 | | { |
598 | | m_subcycle = m_subc_reload; |
599 | | m_PC++; |
600 | | } |
601 | | m_pitch_count++; |
602 | | if ((m_pitch_count >= m_current_pitch)||(m_pitch_zero == 1)) m_pitch_count = 0; |
603 | | m_pitch_count &= 0x1FF; |
| 629 | m_subcycle = m_subc_reload; |
| 630 | m_PC = 0; |
| 631 | m_IP++; |
| 632 | m_IP&=0x7; |
604 | 633 | } |
605 | | else // m_TALKD == 0 |
| 634 | else if (m_subcycle == 3) |
606 | 635 | { |
607 | | m_subcycle++; |
608 | | if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3 |
| 636 | m_subcycle = m_subc_reload; |
| 637 | m_PC++; |
| 638 | } |
| 639 | m_pitch_count++; |
| 640 | if ((m_pitch_count >= m_current_pitch)||(m_pitch_zero == 1)) m_pitch_count = 0; |
| 641 | m_pitch_count &= 0x1FF; |
| 642 | buf_count++; |
| 643 | size--; |
| 644 | } |
| 645 | |
| 646 | empty: |
| 647 | |
| 648 | while (size > 0) |
| 649 | { |
| 650 | m_subcycle++; |
| 651 | if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3 |
| 652 | { |
| 653 | if (m_IP == 7) // RESETL4 |
609 | 654 | { |
610 | | if (m_IP == 7) // RESETL4 |
611 | | { |
612 | | m_TALKD = m_TALK; // TALKD is latched from TALK |
613 | | m_TALK = m_SPEN; // TALK is latched from SPEN |
614 | | } |
615 | | m_subcycle = m_subc_reload; |
616 | | m_PC = 0; |
617 | | m_IP++; |
618 | | m_IP&=0x7; |
| 655 | m_TALKD = m_TALK; // TALKD is latched from TALK |
| 656 | m_TALK = m_SPEN; // TALK is latched from SPEN |
619 | 657 | } |
620 | | else if (m_subcycle == 3) |
621 | | { |
622 | | m_subcycle = m_subc_reload; |
623 | | m_PC++; |
624 | | } |
625 | | buffer[buf_count] = -1; /* should be just -1; actual chip outputs -1 every idle sample; (cf note in data sheet, p 10, table 4) */ |
| 658 | m_subcycle = m_subc_reload; |
| 659 | m_PC = 0; |
| 660 | m_IP++; |
| 661 | m_IP&=0x7; |
626 | 662 | } |
627 | | buf_count++; |
628 | | size--; |
| 663 | else if (m_subcycle == 3) |
| 664 | { |
| 665 | m_subcycle = m_subc_reload; |
| 666 | m_PC++; |
| 667 | } |
| 668 | buffer[buf_count] = -1; /* should be just -1; actual chip outputs -1 every idle sample; (cf note in data sheet, p 10, table 4) */ |
| 669 | buf_count++; |
| 670 | size--; |
629 | 671 | } |
630 | 672 | } |
631 | 673 | |
r249094 | r249095 | |
855 | 897 | #endif |
856 | 898 | perform_dummy_read(); |
857 | 899 | m_SPEN = 1; /* start immediately */ |
858 | | #ifdef FAST_START_HACK |
859 | | m_TALK = 1; |
860 | | #endif |
861 | 900 | /* clear out variables before speaking */ |
862 | 901 | m_zpar = 1; // zero all the parameters |
863 | | m_uv_zpar = 1; // zero k4-k10 as well |
864 | | m_OLDE = 1; // 'silence/zpar' frames are zero energy |
865 | | m_OLDP = 1; // 'silence/zpar' frames are zero pitch |
866 | | #ifdef PERFECT_INTERPOLATION_HACK |
867 | | m_old_zpar = 1; // zero all the old parameters |
868 | | m_old_uv_zpar = 1; // zero old k4-k10 as well |
869 | | #endif |
870 | 902 | m_subc_reload = 0; // SPKSLOW means this is 0 |
| 903 | m_subcycle = m_subc_reload; |
| 904 | m_PC = 0; |
| 905 | m_IP = 0; |
871 | 906 | break; |
872 | 907 | |
873 | 908 | case TMS5110_CMD_READ_BIT: |
r249094 | r249095 | |
881 | 916 | #ifdef DEBUG_COMMAND_DUMP |
882 | 917 | fprintf(stderr,"actually reading a bit now\n"); |
883 | 918 | #endif |
| 919 | request_bits(1); |
884 | 920 | m_CTL_buffer >>= 1; |
885 | 921 | m_CTL_buffer |= (extract_bits(1)<<3); |
886 | 922 | m_CTL_buffer &= 0xF; |
r249094 | r249095 | |
893 | 929 | #endif |
894 | 930 | perform_dummy_read(); |
895 | 931 | m_SPEN = 1; /* start immediately */ |
896 | | #ifdef FAST_START_HACK |
897 | | m_TALK = 1; |
898 | | #endif |
899 | 932 | /* clear out variables before speaking */ |
900 | 933 | m_zpar = 1; // zero all the parameters |
901 | | m_uv_zpar = 1; // zero k4-k10 as well |
902 | | m_OLDE = 1; // 'silence/zpar' frames are zero energy |
903 | | m_OLDP = 1; // 'silence/zpar' frames are zero pitch |
904 | | #ifdef PERFECT_INTERPOLATION_HACK |
905 | | m_old_zpar = 1; // zero all the old parameters |
906 | | m_old_uv_zpar = 1; // zero old k4-k10 as well |
907 | | #endif |
908 | 934 | m_subc_reload = 1; // SPEAK means this is 1 |
| 935 | m_subcycle = m_subc_reload; |
| 936 | m_PC = 0; |
| 937 | m_IP = 0; |
909 | 938 | break; |
910 | 939 | |
911 | 940 | case TMS5110_CMD_READ_BRANCH: |
r249094 | r249095 | |
950 | 979 | |
951 | 980 | void tms5110_device::parse_frame() |
952 | 981 | { |
953 | | int i, rep_flag; |
| 982 | int bits, i, rep_flag; |
| 983 | /** TODO: get rid of bits handling here and move into extract_bits (as in tms5220.c) **/ |
| 984 | /* count the total number of bits available */ |
| 985 | bits = m_fifo_count; |
954 | 986 | |
| 987 | /* attempt to extract the energy index */ |
| 988 | bits -= m_coeff->energy_bits; |
| 989 | if (bits < 0) |
| 990 | { |
| 991 | request_bits( -bits ); /* toggle M0 to receive needed bits */ |
| 992 | bits = 0; |
| 993 | } |
955 | 994 | // attempt to extract the energy index |
956 | 995 | m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits); |
957 | 996 | #ifdef DEBUG_PARSE_FRAME_DUMP |
r249094 | r249095 | |
959 | 998 | fprintf(stderr," "); |
960 | 999 | #endif |
961 | 1000 | |
| 1001 | /* if the energy index is 0 or 15, we're done |
| 1002 | |
| 1003 | if ((indx == 0) || (indx == 15)) |
| 1004 | { |
| 1005 | if (DEBUG_5110) logerror(" (4-bit energy=%d frame)\n",m_new_energy); |
| 1006 | |
| 1007 | // clear the k's |
| 1008 | if (indx == 0) |
| 1009 | { |
| 1010 | for (i = 0; i < m_coeff->num_k; i++) |
| 1011 | m_new_k[i] = 0; |
| 1012 | } |
| 1013 | |
| 1014 | // clear fifo if stop frame encountered |
| 1015 | if (indx == 15) |
| 1016 | { |
| 1017 | if (DEBUG_5110) logerror(" (4-bit energy=%d STOP frame)\n",m_new_energy); |
| 1018 | m_fifo_head = m_fifo_tail = m_fifo_count = 0; |
| 1019 | } |
| 1020 | return; |
| 1021 | }*/ |
962 | 1022 | // if the energy index is 0 or 15, we're done |
963 | 1023 | if ((m_new_frame_energy_idx == 0) || (m_new_frame_energy_idx == 15)) |
964 | 1024 | return; |
965 | 1025 | |
| 1026 | |
| 1027 | /* attempt to extract the repeat flag */ |
| 1028 | bits -= 1; |
| 1029 | if (bits < 0) |
| 1030 | { |
| 1031 | request_bits( -bits ); /* toggle M0 to receive needed bits */ |
| 1032 | bits = 0; |
| 1033 | } |
966 | 1034 | rep_flag = extract_bits(1); |
967 | 1035 | #ifdef DEBUG_PARSE_FRAME_DUMP |
968 | 1036 | printbits(rep_flag, 1); |
969 | 1037 | fprintf(stderr," "); |
970 | 1038 | #endif |
971 | 1039 | |
| 1040 | /* attempt to extract the pitch */ |
| 1041 | bits -= m_coeff->pitch_bits; |
| 1042 | if (bits < 0) |
| 1043 | { |
| 1044 | request_bits( -bits ); /* toggle M0 to receive needed bits */ |
| 1045 | bits = 0; |
| 1046 | } |
972 | 1047 | m_new_frame_pitch_idx = extract_bits(m_coeff->pitch_bits); |
973 | 1048 | #ifdef DEBUG_PARSE_FRAME_DUMP |
974 | 1049 | printbits(m_new_frame_pitch_idx,m_coeff->pitch_bits); |
r249094 | r249095 | |
981 | 1056 | // extract first 4 K coefficients |
982 | 1057 | for (i = 0; i < 4; i++) |
983 | 1058 | { |
| 1059 | /* attempt to extract 4 K's */ |
| 1060 | bits -= m_coeff->kbits[i]; |
| 1061 | if (bits < 0) |
| 1062 | { |
| 1063 | request_bits( -bits ); /* toggle M0 to receive needed bits */ |
| 1064 | bits = 0; |
| 1065 | } |
984 | 1066 | m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]); |
985 | 1067 | #ifdef DEBUG_PARSE_FRAME_DUMP |
986 | 1068 | printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]); |
r249094 | r249095 | |
998 | 1080 | // If we got here, we need the remaining 6 K's |
999 | 1081 | for (i = 4; i < m_coeff->num_k; i++) |
1000 | 1082 | { |
| 1083 | bits -= m_coeff->kbits[i]; |
| 1084 | if (bits < 0) |
| 1085 | { |
| 1086 | request_bits( -bits ); /* toggle M0 to receive needed bits */ |
| 1087 | bits = 0; |
| 1088 | } |
1001 | 1089 | m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]); |
1002 | 1090 | #ifdef DEBUG_PARSE_FRAME_DUMP |
1003 | 1091 | printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]); |
1004 | 1092 | fprintf(stderr," "); |
1005 | 1093 | #endif |
1006 | 1094 | } |
1007 | | #ifdef DEBUG_PARSE_FRAME_DUMP |
1008 | | fprintf(stderr,"\n"); |
1009 | | #endif |
1010 | 1095 | #ifdef VERBOSE |
| 1096 | if (m_speak_external) |
| 1097 | logerror("Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken)); |
| 1098 | else |
1011 | 1099 | logerror("Parsed a frame successfully in ROM\n"); |
1012 | 1100 | #endif |
1013 | 1101 | return; |
r249094 | r249095 | |
1151 | 1239 | void tms5110_device::device_reset() |
1152 | 1240 | { |
1153 | 1241 | m_digital_select = FORCE_DIGITAL; // assume analog output |
| 1242 | /* initialize the FIFO */ |
| 1243 | memset(m_fifo, 0, sizeof(m_fifo)); |
| 1244 | m_fifo_head = m_fifo_tail = m_fifo_count = 0; |
1154 | 1245 | |
1155 | 1246 | /* initialize the chip state */ |
1156 | 1247 | m_SPEN = m_TALK = m_TALKD = 0; |
r249094 | r249095 | |
1163 | 1254 | #ifdef PERFECT_INTERPOLATION_HACK |
1164 | 1255 | m_old_frame_energy_idx = m_old_frame_pitch_idx = 0; |
1165 | 1256 | memset(m_old_frame_k_idx, 0, sizeof(m_old_frame_k_idx)); |
1166 | | m_old_zpar = m_old_uv_zpar = 0; |
| 1257 | m_old_zpar = 0; |
1167 | 1258 | #endif |
1168 | 1259 | m_new_frame_energy_idx = m_current_energy = m_previous_energy = 0; |
1169 | 1260 | m_new_frame_pitch_idx = m_current_pitch = 0; |
r249094 | r249095 | |
1300 | 1391 | } |
1301 | 1392 | |
1302 | 1393 | |
| 1394 | |
1303 | 1395 | /****************************************************************************** |
1304 | 1396 | |
| 1397 | tms5110_ready_r -- return the not ready status from the sound chip |
| 1398 | |
| 1399 | ******************************************************************************/ |
| 1400 | |
| 1401 | int tms5110_device::ready_r() |
| 1402 | { |
| 1403 | /* bring up to date first */ |
| 1404 | m_stream->update(); |
| 1405 | return (m_fifo_count < FIFO_SIZE-1); |
| 1406 | } |
| 1407 | |
| 1408 | |
| 1409 | |
| 1410 | /****************************************************************************** |
| 1411 | |
1305 | 1412 | tms5110_update -- update the sound chip so that it is in sync with CPU execution |
1306 | 1413 | |
1307 | 1414 | ******************************************************************************/ |
trunk/src/emu/sound/tms5220.c
r249094 | r249095 | |
48 | 48 | |
49 | 49 | TODO: |
50 | 50 | * Ever since the big rewrite, there are glitches on certain frame transitions |
51 | | for example in the word 'rid' during the eprom attract mode, |
| 51 | for example in the word 'robots' during the eprom attract mode, |
52 | 52 | I (LN) am not entirely sure why the real chip doesn't have these as well. |
53 | 53 | Needs more real hardware testing/dumps for comparison. |
| 54 | * Ever since the timing rewrite, the above problem is slightly worse. This |
| 55 | time, however, it is probably a 'real' bug, which I (LN) am in the process |
| 56 | of tracking down. |
| 57 | i.e. the word 'congratulations' in victory when you get a high score. |
54 | 58 | * Implement a ready callback for pc interfaces |
55 | 59 | - this will be quite a challenge since for it to be really accurate |
56 | 60 | the whole emulation has to run in sync (lots of timers) with the |
r249094 | r249095 | |
58 | 62 | * If a command is still executing, /READY will be kept high until the command has |
59 | 63 | finished if the next command is written. |
60 | 64 | * tomcat has a 5220 which is not hooked up at all |
| 65 | * Is the TS=0 forcing energy to 0 for next frame in the interpolator actually correct? I'm (LN) guessing no. The patent schematics state that TS=0 shuts off the output dac completely, though doesn't affect the I/O pin. |
61 | 66 | |
62 | 67 | Pedantic detail from observation of real chip: |
63 | 68 | The 5200 and 5220 chips outputs the following coefficients over PROMOUT while |
r249094 | r249095 | |
262 | 267 | //define INTERP_SHIFT / (1<<m_coeff->interp_coeff[m_IP]) |
263 | 268 | |
264 | 269 | /* Other hacks */ |
265 | | /* HACK: if defined, outputs the low 4 bits of the lattice filter to the i/o |
| 270 | /* HACK?: if defined, outputs the low 4 bits of the lattice filter to the i/o |
266 | 271 | * or clip logic, even though the real hardware doesn't do this, partially verified by decap */ |
267 | 272 | #undef ALLOW_4_LSB |
268 | 273 | |
269 | | /* forces m_TALK active instantly whenever m_SPEN would be activated, causing speech delay to be reduced by up to one frame time */ |
270 | | /* for some reason, this hack makes victory behave better, though it does not match the patent */ |
271 | | #define FAST_START_HACK 1 |
272 | 274 | |
273 | | |
274 | 275 | /* *****configuration of chip connection stuff***** */ |
275 | 276 | /* must be defined; if 0, output the waveform as if it was tapped on the speaker pin as usual, if 1, output the waveform as if it was tapped on the i/o pin (volume is much lower in the latter case) */ |
276 | 277 | #define FORCE_DIGITAL 0 |
r249094 | r249095 | |
360 | 361 | save_item(NAME(m_fifo_count)); |
361 | 362 | save_item(NAME(m_fifo_bits_taken)); |
362 | 363 | |
363 | | save_item(NAME(m_previous_TALK_STATUS)); |
364 | | save_item(NAME(m_SPEN)); |
365 | | save_item(NAME(m_DDIS)); |
366 | | save_item(NAME(m_TALK)); |
367 | | save_item(NAME(m_TALKD)); |
| 364 | save_item(NAME(m_speaking_now)); |
| 365 | save_item(NAME(m_speak_external)); |
| 366 | save_item(NAME(m_talk_status)); |
368 | 367 | save_item(NAME(m_buffer_low)); |
369 | 368 | save_item(NAME(m_buffer_empty)); |
370 | 369 | save_item(NAME(m_irq_pin)); |
r249094 | r249095 | |
385 | 384 | save_item(NAME(m_current_pitch)); |
386 | 385 | save_item(NAME(m_current_k)); |
387 | 386 | |
| 387 | save_item(NAME(m_target_energy)); |
| 388 | save_item(NAME(m_target_pitch)); |
| 389 | save_item(NAME(m_target_k)); |
| 390 | |
388 | 391 | save_item(NAME(m_previous_energy)); |
389 | 392 | |
390 | 393 | save_item(NAME(m_subcycle)); |
r249094 | r249095 | |
392 | 395 | save_item(NAME(m_PC)); |
393 | 396 | save_item(NAME(m_IP)); |
394 | 397 | save_item(NAME(m_inhibit)); |
395 | | save_item(NAME(m_uv_zpar)); |
396 | | save_item(NAME(m_zpar)); |
397 | | save_item(NAME(m_pitch_zero)); |
398 | 398 | save_item(NAME(m_c_variant_rate)); |
399 | 399 | save_item(NAME(m_pitch_count)); |
400 | 400 | |
r249094 | r249095 | |
465 | 465 | |
466 | 466 | void tms5220_device::data_write(int data) |
467 | 467 | { |
468 | | int old_buffer_low = m_buffer_low; |
469 | 468 | #ifdef DEBUG_DUMP_INPUT_DATA |
470 | 469 | fprintf(stdout, "%c",data); |
471 | 470 | #endif |
472 | | if (m_DDIS) // If we're in speak external mode |
| 471 | if (m_speak_external) // If we're in speak external mode |
473 | 472 | { |
474 | 473 | // add this byte to the FIFO |
475 | 474 | if (m_fifo_count < FIFO_SIZE) |
r249094 | r249095 | |
478 | 477 | m_fifo_tail = (m_fifo_tail + 1) % FIFO_SIZE; |
479 | 478 | m_fifo_count++; |
480 | 479 | #ifdef DEBUG_FIFO |
481 | | fprintf(stderr,"data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count); |
| 480 | logerror("data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count); |
482 | 481 | #endif |
483 | 482 | update_fifo_status_and_ints(); |
484 | | // if we just unset buffer low with that last write, and SPEN *was* zero (see circuit 251, sheet 12) |
485 | | if ((m_SPEN == 0) && ((old_buffer_low == 1) && (m_buffer_low == 0))) // MUST HAVE EDGE DETECT |
| 483 | if ((m_talk_status == 0) && (m_buffer_low == 0)) // we just unset buffer low with that last write, and talk status *was* zero... |
486 | 484 | { |
487 | | int i; |
| 485 | int i; |
488 | 486 | #ifdef DEBUG_FIFO |
489 | | fprintf(stderr,"data_write triggered SPEN to go active!\n"); |
| 487 | logerror("data_write triggered talk status to go active!\n"); |
490 | 488 | #endif |
491 | | // ...then we now have enough bytes to start talking; set zpar and clear out the new frame parameters (it will become old frame just before the first call to parse_frame() ) |
492 | | m_zpar = 1; |
493 | | m_uv_zpar = 1; // zero k4-k10 as well |
494 | | m_OLDE = 1; // 'silence/zpar' frames are zero energy |
495 | | m_OLDP = 1; // 'silence/zpar' frames are zero pitch |
496 | | #ifdef PERFECT_INTERPOLATION_HACK |
497 | | m_old_zpar = 1; // zero all the old parameters |
498 | | m_old_uv_zpar = 1; // zero old k4-k10 as well |
499 | | #endif |
500 | | m_SPEN = 1; |
501 | | #ifdef FAST_START_HACK |
502 | | m_TALK = 1; |
503 | | #endif |
| 489 | // ...then we now have enough bytes to start talking; clear out the new frame parameters (it will become old frame just before the first call to parse_frame() ) |
| 490 | // TODO: the 3 lines below (and others) are needed for victory to not fail its selftest due to a sample ending too late, may require additional investigation |
| 491 | m_subcycle = m_subc_reload; |
| 492 | m_PC = 0; |
| 493 | m_IP = reload_table[m_c_variant_rate&0x3]; // is this correct? should this be always 7 instead, so that the new frame is loaded quickly? |
504 | 494 | m_new_frame_energy_idx = 0; |
505 | 495 | m_new_frame_pitch_idx = 0; |
506 | 496 | for (i = 0; i < 4; i++) |
r249094 | r249095 | |
509 | 499 | m_new_frame_k_idx[i] = 0xF; |
510 | 500 | for (i = 7; i < m_coeff->num_k; i++) |
511 | 501 | m_new_frame_k_idx[i] = 0x7; |
512 | | |
| 502 | m_talk_status = m_speaking_now = 1; |
513 | 503 | } |
514 | 504 | } |
515 | 505 | else |
516 | 506 | { |
517 | 507 | #ifdef DEBUG_FIFO |
518 | | fprintf(stderr,"data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n"); |
| 508 | logerror("data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n"); |
519 | 509 | // at this point, /READY should remain HIGH/inactive until the fifo has at least one byte open in it. |
520 | 510 | #endif |
521 | 511 | } |
522 | 512 | |
523 | 513 | |
524 | 514 | } |
525 | | else //(! m_DDIS) |
| 515 | else //(! m_speak_external) |
526 | 516 | // R Nabet : we parse commands at once. It is necessary for such commands as read. |
527 | 517 | process_command(data); |
528 | 518 | } |
r249094 | r249095 | |
570 | 560 | m_buffer_low = 0; |
571 | 561 | |
572 | 562 | /* BE is set if neither byte 15 nor 14 of the fifo are in use; this |
573 | | translates to having fifo_count equal to exactly 0 |
574 | | */ |
| 563 | translates to having fifo_count equal to exactly 0 */ |
575 | 564 | if (m_fifo_count == 0) |
576 | 565 | { |
577 | 566 | // generate an interrupt if necessary; if /BE was inactive and is now active, set int. |
578 | 567 | if (!m_buffer_empty) |
579 | 568 | set_interrupt_state(1); |
580 | 569 | m_buffer_empty = 1; |
581 | | m_TALK = m_SPEN = 0; // /BE being active clears the TALK(TCON) status which in turn clears SPEN |
582 | 570 | } |
583 | 571 | else |
584 | 572 | m_buffer_empty = 0; |
585 | 573 | |
586 | | // generate an interrupt if /TS was active, and is now inactive. |
587 | | // also, in this case, regardless if DDIS was set, unset it. |
588 | | if (m_previous_TALK_STATUS == 1 && (TALK_STATUS == 0)) |
| 574 | /* TS is talk status and is set elsewhere in the fifo parser and in |
| 575 | the SPEAK command handler; however, if /BE is true during speak external |
| 576 | mode, it is immediately unset here. */ |
| 577 | if ((m_speak_external == 1) && (m_buffer_empty == 1)) |
589 | 578 | { |
590 | | #ifdef VERBOSE |
591 | | fprintf(stderr,"Talk status WAS 1, is now 0, unsetting DDIS and firing an interrupt!\n"); |
592 | | #endif |
593 | | set_interrupt_state(1); |
594 | | m_DDIS = 0; |
| 579 | // generate an interrupt: /TS was active, and is now inactive. |
| 580 | if (m_talk_status == 1) |
| 581 | { |
| 582 | m_talk_status = m_speak_external = 0; |
| 583 | set_interrupt_state(1); |
| 584 | } |
595 | 585 | } |
596 | | m_previous_TALK_STATUS = TALK_STATUS; |
597 | | |
| 586 | /* Note that TS being unset will also generate an interrupt when a STOP |
| 587 | frame is encountered; this is handled in the sample generator code and not here */ |
598 | 588 | } |
599 | 589 | |
600 | 590 | /********************************************************************************************** |
r249094 | r249095 | |
607 | 597 | { |
608 | 598 | int val = 0; |
609 | 599 | |
610 | | if (m_DDIS) |
| 600 | if (m_speak_external) |
611 | 601 | { |
612 | 602 | // extract from FIFO |
613 | 603 | while (count--) |
r249094 | r249095 | |
653 | 643 | /* clear the interrupt pin on status read */ |
654 | 644 | set_interrupt_state(0); |
655 | 645 | #ifdef DEBUG_PIN_READS |
656 | | fprintf(stderr,"Status read: TS=%d BL=%d BE=%d\n", TALK_STATUS, m_buffer_low, m_buffer_empty); |
| 646 | logerror("Status read: TS=%d BL=%d BE=%d\n", m_talk_status, m_buffer_low, m_buffer_empty); |
657 | 647 | #endif |
658 | 648 | |
659 | | return (TALK_STATUS << 7) | (m_buffer_low << 6) | (m_buffer_empty << 5); |
| 649 | return (m_talk_status << 7) | (m_buffer_low << 6) | (m_buffer_empty << 5); |
660 | 650 | } |
661 | 651 | } |
662 | 652 | |
r249094 | r249095 | |
670 | 660 | int tms5220_device::ready_read() |
671 | 661 | { |
672 | 662 | #ifdef DEBUG_PIN_READS |
673 | | fprintf(stderr,"ready_read: ready pin read, io_ready is %d, fifo count is %d, DDIS(speak external) is %d\n", m_io_ready, m_fifo_count, m_DDIS); |
| 663 | logerror("ready_read: ready pin read, io_ready is %d, fifo count is %d\n", m_io_ready, m_fifo_count); |
674 | 664 | #endif |
675 | | return ((m_fifo_count < FIFO_SIZE)||(!m_DDIS)) && m_io_ready; |
| 665 | return ((m_fifo_count < FIFO_SIZE)||(!m_speak_external)) && m_io_ready; |
676 | 666 | } |
677 | 667 | |
678 | 668 | |
r249094 | r249095 | |
728 | 718 | int tms5220_device::int_read() |
729 | 719 | { |
730 | 720 | #ifdef DEBUG_PIN_READS |
731 | | fprintf(stderr,"int_read: irq pin read, state is %d\n", m_irq_pin); |
| 721 | logerror("int_read: irq pin read, state is %d\n", m_irq_pin); |
732 | 722 | #endif |
733 | 723 | return m_irq_pin; |
734 | 724 | } |
r249094 | r249095 | |
743 | 733 | void tms5220_device::process(INT16 *buffer, unsigned int size) |
744 | 734 | { |
745 | 735 | int buf_count=0; |
746 | | int i, bitout; |
| 736 | int i, bitout, zpar; |
747 | 737 | INT32 this_sample; |
748 | 738 | |
749 | | #ifdef VERBOSE |
750 | | fprintf(stderr,"process called with size of %d; IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", size, m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); |
751 | | #endif |
| 739 | /* the following gotos are probably safe to remove */ |
| 740 | /* if we're empty and still not speaking, fill with nothingness */ |
| 741 | if (!m_speaking_now) |
| 742 | goto empty; |
752 | 743 | |
| 744 | /* if speak external is set, but talk status is not (yet) set, |
| 745 | wait for buffer low to clear */ |
| 746 | if (!m_talk_status && m_speak_external && m_buffer_low) |
| 747 | goto empty; |
| 748 | |
753 | 749 | /* loop until the buffer is full or we've stopped speaking */ |
754 | | while (size > 0) |
| 750 | while ((size > 0) && m_speaking_now) |
755 | 751 | { |
756 | | if(m_TALKD) // speaking |
| 752 | /* if it is the appropriate time to update the old energy/pitch indices, |
| 753 | * i.e. when IP=7, PC=12, T=17, subcycle=2, do so. Since IP=7 PC=12 T=17 |
| 754 | * is JUST BEFORE the transition to IP=0 PC=0 T=0 sybcycle=(0 or 1), |
| 755 | * which happens 4 T-cycles later), we change on the latter. |
| 756 | * The indices are updated here ~12 PCs before the new frame is applied. |
| 757 | */ |
| 758 | /** TODO: the patents 4331836, 4335277, and 4419540 disagree about the timing of this **/ |
| 759 | if ((m_IP == 0) && (m_PC == 0) && (m_subcycle < 2)) |
757 | 760 | { |
758 | | /* if we're ready for a new frame to be applied, i.e. when IP=0, PC=12, Sub=1 |
759 | | * (In reality, the frame was really loaded incrementally during the entire IP=0 |
760 | | * PC=x time period, but it doesn't affect anything until IP=0 PC=12 happens) |
761 | | */ |
762 | | if ((m_IP == 0) && (m_PC == 12) && (m_subcycle == 1)) |
763 | | { |
764 | | // HACK for regression testing, be sure to comment out before release! |
765 | | //m_RNG = 0x1234; |
766 | | // end HACK |
| 761 | m_OLDE = (m_new_frame_energy_idx == 0); |
| 762 | m_OLDP = (m_new_frame_pitch_idx == 0); |
| 763 | } |
767 | 764 | |
768 | | /* appropriately override the interp count if needed; this will be incremented after the frame parse! */ |
769 | | m_IP = reload_table[m_c_variant_rate&0x3]; |
| 765 | /* if we're ready for a new frame to be applied, i.e. when IP=0, PC=12, Sub=1 |
| 766 | * (In reality, the frame was really loaded incrementally during the entire IP=0 |
| 767 | * PC=x time period, but it doesn't affect anything until IP=0 PC=12 happens) |
| 768 | */ |
| 769 | if ((m_IP == 0) && (m_PC == 12) && (m_subcycle == 1)) |
| 770 | { |
| 771 | // HACK for regression testing, be sure to comment out before release! |
| 772 | //m_RNG = 0x1234; |
| 773 | // end HACK |
770 | 774 | |
| 775 | /* appropriately override the interp count if needed; this will be incremented after the frame parse! */ |
| 776 | m_IP = reload_table[m_c_variant_rate&0x3]; |
| 777 | |
771 | 778 | #ifdef PERFECT_INTERPOLATION_HACK |
772 | | /* remember previous frame energy, pitch, and coefficients */ |
773 | | m_old_frame_energy_idx = m_new_frame_energy_idx; |
774 | | m_old_frame_pitch_idx = m_new_frame_pitch_idx; |
775 | | for (i = 0; i < m_coeff->num_k; i++) |
776 | | m_old_frame_k_idx[i] = m_new_frame_k_idx[i]; |
| 779 | /* remember previous frame energy, pitch, and coefficients */ |
| 780 | m_old_frame_energy_idx = m_new_frame_energy_idx; |
| 781 | m_old_frame_pitch_idx = m_new_frame_pitch_idx; |
| 782 | for (i = 0; i < m_coeff->num_k; i++) |
| 783 | m_old_frame_k_idx[i] = m_new_frame_k_idx[i]; |
777 | 784 | #endif |
778 | 785 | |
779 | | /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[] */ |
780 | | parse_frame(); |
| 786 | /* if the talk status was clear last frame, halt speech now. */ |
| 787 | if (m_talk_status == 0) |
| 788 | { |
| 789 | #ifdef DEBUG_GENERATION |
| 790 | fprintf(stderr,"tms5220_process: processing frame: talk status = 0 caused by stop frame or buffer empty, halting speech.\n"); |
| 791 | #endif |
| 792 | if (m_speaking_now == 1) // we're done, set all coeffs to idle state but keep going for a bit... |
| 793 | { |
| 794 | /**TODO: should index clearing be done here, or elsewhere? **/ |
| 795 | m_new_frame_energy_idx = 0; |
| 796 | m_new_frame_pitch_idx = 0; |
| 797 | for (i = 0; i < 4; i++) |
| 798 | m_new_frame_k_idx[i] = 0; |
| 799 | for (i = 4; i < 7; i++) |
| 800 | m_new_frame_k_idx[i] = 0xF; |
| 801 | for (i = 7; i < m_coeff->num_k; i++) |
| 802 | m_new_frame_k_idx[i] = 0x7; |
| 803 | m_speaking_now = 2; // wait 8 extra interp periods before shutting down so we can interpolate everything to zero state |
| 804 | } |
| 805 | else // m_speaking_now == 2 // now we're really done. |
| 806 | { |
| 807 | m_speaking_now = 0; // finally halt speech |
| 808 | goto empty; |
| 809 | } |
| 810 | } |
781 | 811 | |
782 | | // if the new frame is unvoiced (or silenced via ZPAR), be sure to zero out the k5-k10 parameters |
783 | | // NOTE: this is probably the bug the tms5100/tmc0280 has, pre-rev D, I think. |
784 | | // GUESS: Pre-rev D versions start zeroing k5-k10 immediately upon new frame load regardless of interpolation inhibit |
785 | | // I.e. ZPAR = /TALKD || (PC>5&&P=0) |
786 | | // GUESS: D and later versions only start or stop zeroing k5-k10 at the IP7->IP0 transition AFTER the frame |
787 | | // I.e. ZPAR = /TALKD || (PC>5&&OLDP) |
788 | | #ifdef PERFECT_INTERPOLATION_HACK |
789 | | m_old_uv_zpar = m_uv_zpar; |
790 | | m_old_zpar = m_zpar; // unset old zpar on new frame |
| 812 | |
| 813 | /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[], |
| 814 | * but only if we're not just about to end speech */ |
| 815 | if (m_speaking_now == 1) parse_frame(); |
| 816 | #ifdef DEBUG_PARSE_FRAME_DUMP |
| 817 | fprintf(stderr,"\n"); |
791 | 818 | #endif |
792 | | m_zpar = 0; |
793 | | //m_uv_zpar = (OLD_FRAME_UNVOICED_FLAG||m_zpar); // GUESS: fixed version in tmc0280d/tms5100a/cd280x/tms5110 |
794 | | m_uv_zpar = (NEW_FRAME_UNVOICED_FLAG||m_zpar); // GUESS: buggy version in tmc0280/tms5100 |
795 | 819 | |
796 | | /* if the new frame is a stop frame, unset both TALK and SPEN (via TCON). TALKD remains active while the energy is ramping to 0. */ |
797 | | if (NEW_FRAME_STOP_FLAG == 1) |
| 820 | /* if the new frame is a stop frame, set an interrupt and set talk status to 0 */ |
| 821 | /** TODO: investigate this later! **/ |
| 822 | if (NEW_FRAME_STOP_FLAG == 1) |
798 | 823 | { |
799 | | m_TALK = m_SPEN = 0; |
| 824 | m_talk_status = m_speak_external = 0; |
| 825 | set_interrupt_state(1); |
| 826 | update_fifo_status_and_ints(); |
800 | 827 | } |
801 | 828 | |
802 | | /* in all cases where interpolation would be inhibited, set the inhibit flag; otherwise clear it. |
803 | | Interpolation inhibit cases: |
804 | | * Old frame was voiced, new is unvoiced |
805 | | * Old frame was silence/zero energy, new has nonzero energy |
806 | | * Old frame was unvoiced, new is voiced |
807 | | * Old frame was unvoiced, new frame is silence/zero energy (unique to tms52xx) |
808 | | */ |
809 | | if ( ((OLD_FRAME_UNVOICED_FLAG == 0) && (NEW_FRAME_UNVOICED_FLAG == 1)) |
810 | | || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_UNVOICED_FLAG == 0)) |
811 | | || ((OLD_FRAME_SILENCE_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 0)) |
812 | | || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 1)) ) |
813 | | m_inhibit = 1; |
814 | | else // normal frame, normal interpolation |
815 | | m_inhibit = 0; |
| 829 | /* in all cases where interpolation would be inhibited, set the inhibit flag; otherwise clear it. |
| 830 | Interpolation inhibit cases: |
| 831 | * Old frame was voiced, new is unvoiced |
| 832 | * Old frame was silence/zero energy, new has nonzero energy |
| 833 | * Old frame was unvoiced, new is voiced |
| 834 | * Old frame was unvoiced, new frame is silence/zero energy (unique to tms52xx) |
| 835 | */ |
| 836 | if ( ((OLD_FRAME_UNVOICED_FLAG == 0) && (NEW_FRAME_UNVOICED_FLAG == 1)) |
| 837 | || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_UNVOICED_FLAG == 0)) |
| 838 | || ((OLD_FRAME_SILENCE_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 0)) |
| 839 | || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 1)) ) |
| 840 | m_inhibit = 1; |
| 841 | else // normal frame, normal interpolation |
| 842 | m_inhibit = 0; |
816 | 843 | |
| 844 | /* load new frame targets from tables, using parsed indices */ |
| 845 | m_target_energy = m_coeff->energytable[m_new_frame_energy_idx]; |
| 846 | m_target_pitch = m_coeff->pitchtable[m_new_frame_pitch_idx]; |
| 847 | zpar = NEW_FRAME_UNVOICED_FLAG; // find out if parameters k5-k10 should be zeroed |
| 848 | for (i = 0; i < 4; i++) |
| 849 | m_target_k[i] = m_coeff->ktable[i][m_new_frame_k_idx[i]]; |
| 850 | for (i = 4; i < m_coeff->num_k; i++) |
| 851 | m_target_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-zpar)); |
| 852 | |
817 | 853 | #ifdef DEBUG_GENERATION |
818 | | /* Debug info for current parsed frame */ |
819 | | fprintf(stderr, "OLDE: %d; OLDP: %d; ", m_OLDE, m_OLDP); |
820 | | fprintf(stderr,"Processing new frame: "); |
821 | | if (m_inhibit == 0) |
822 | | fprintf(stderr, "Normal Frame\n"); |
823 | | else |
824 | | fprintf(stderr,"Interpolation Inhibited\n"); |
825 | | fprintf(stderr,"*** current Energy, Pitch and Ks = %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_current_energy, m_current_pitch, m_current_k[0], m_current_k[1], m_current_k[2], m_current_k[3], m_current_k[4], m_current_k[5], m_current_k[6], m_current_k[7], m_current_k[8], m_current_k[9]); |
826 | | fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n", |
827 | | (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)), |
828 | | m_new_frame_energy_idx, |
829 | | (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)), |
830 | | (m_coeff->ktable[0][m_new_frame_k_idx[0]] * (1-m_zpar)), |
831 | | (m_coeff->ktable[1][m_new_frame_k_idx[1]] * (1-m_zpar)), |
832 | | (m_coeff->ktable[2][m_new_frame_k_idx[2]] * (1-m_zpar)), |
833 | | (m_coeff->ktable[3][m_new_frame_k_idx[3]] * (1-m_zpar)), |
834 | | (m_coeff->ktable[4][m_new_frame_k_idx[4]] * (1-m_uv_zpar)), |
835 | | (m_coeff->ktable[5][m_new_frame_k_idx[5]] * (1-m_uv_zpar)), |
836 | | (m_coeff->ktable[6][m_new_frame_k_idx[6]] * (1-m_uv_zpar)), |
837 | | (m_coeff->ktable[7][m_new_frame_k_idx[7]] * (1-m_uv_zpar)), |
838 | | (m_coeff->ktable[8][m_new_frame_k_idx[8]] * (1-m_uv_zpar)), |
839 | | (m_coeff->ktable[9][m_new_frame_k_idx[9]] * (1-m_uv_zpar)) ); |
| 854 | /* Debug info for current parsed frame */ |
| 855 | fprintf(stderr, "OLDE: %d; OLDP: %d; ", m_OLDE, m_OLDP); |
| 856 | fprintf(stderr,"Processing frame: "); |
| 857 | if (m_inhibit == 0) |
| 858 | fprintf(stderr, "Normal Frame\n"); |
| 859 | else |
| 860 | fprintf(stderr,"Interpolation Inhibited\n"); |
| 861 | fprintf(stderr,"*** current Energy, Pitch and Ks = %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_current_energy, m_current_pitch, m_current_k[0], m_current_k[1], m_current_k[2], m_current_k[3], m_current_k[4], m_current_k[5], m_current_k[6], m_current_k[7], m_current_k[8], m_current_k[9]); |
| 862 | fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_target_energy, m_new_frame_energy_idx, m_target_pitch, m_target_k[0], m_target_k[1], m_target_k[2], m_target_k[3], m_target_k[4], m_target_k[5], m_target_k[6], m_target_k[7], m_target_k[8], m_target_k[9]); |
840 | 863 | #endif |
841 | 864 | |
842 | | } |
843 | | else // Not a new frame, just interpolate the existing frame. |
| 865 | /* if TS is now 0, ramp the energy down to 0. Is this really correct to hardware? */ |
| 866 | if (m_talk_status == 0) |
844 | 867 | { |
845 | | int inhibit_state = ((m_inhibit==1)&&(m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the m_inhibit value |
846 | | #ifdef PERFECT_INTERPOLATION_HACK |
847 | | int samples_per_frame = m_subc_reload?175:266; // either (13 A cycles + 12 B cycles) * 7 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 7 interps for SPKSLOW |
848 | | //int samples_per_frame = m_subc_reload?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW |
849 | | int current_sample = (m_subcycle - m_subc_reload)+(m_PC*(3-m_subc_reload))+((m_subc_reload?25:38)*((m_IP-1)&7)); |
850 | | //fprintf(stderr, "CS: %03d", current_sample); |
851 | | // reset the current energy, pitch, etc to what it was at frame start |
852 | | m_current_energy = (m_coeff->energytable[m_old_frame_energy_idx] * (1-m_old_zpar)); |
853 | | m_current_pitch = (m_coeff->pitchtable[m_old_frame_pitch_idx] * (1-m_old_zpar)); |
854 | | for (i = 0; i < m_coeff->num_k; i++) |
855 | | m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-((i<4)?m_old_zpar:m_old_uv_zpar))); |
856 | | // now adjust each value to be exactly correct for each of the samples per frame |
857 | | if (m_IP != 0) // if we're still interpolating... |
858 | | { |
859 | | m_current_energy = (m_current_energy + (((m_coeff->energytable[m_new_frame_energy_idx] - m_current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-m_zpar); |
860 | | m_current_pitch = (m_current_pitch + (((m_coeff->pitchtable[m_new_frame_pitch_idx] - m_current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-m_zpar); |
861 | | for (i = 0; i < m_coeff->num_k; i++) |
862 | | m_current_k[i] = (m_current_k[i] + (((m_coeff->ktable[i][m_new_frame_k_idx[i]] - m_current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-((i<4)?m_zpar:m_uv_zpar)); |
863 | | } |
864 | | else // we're done, play this frame for 1/8 frame. |
865 | | { |
866 | | m_current_energy = (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)); |
867 | | m_current_pitch = (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)); |
868 | | for (i = 0; i < m_coeff->num_k; i++) |
869 | | m_current_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-((i<4)?m_zpar:m_uv_zpar))); |
870 | | } |
871 | | #else |
872 | | //Updates to parameters only happen on subcycle '2' (B cycle) of PCs. |
873 | | if (m_subcycle == 2) |
874 | | { |
875 | | switch(m_PC) |
876 | | { |
877 | | case 0: /* PC = 0, B cycle, write updated energy */ |
878 | | m_current_energy = (m_current_energy + (((m_coeff->energytable[m_new_frame_energy_idx] - m_current_energy)*(1-inhibit_state)) INTERP_SHIFT))*(1-m_zpar); |
879 | | break; |
880 | | case 1: /* PC = 1, B cycle, write updated pitch */ |
881 | | m_current_pitch = (m_current_pitch + (((m_coeff->pitchtable[m_new_frame_pitch_idx] - m_current_pitch)*(1-inhibit_state)) INTERP_SHIFT))*(1-m_zpar); |
882 | | break; |
883 | | case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: |
884 | | /* PC = 2 through 11, B cycle, write updated K1 through K10 */ |
885 | | m_current_k[m_PC-2] = (m_current_k[m_PC-2] + (((m_coeff->ktable[m_PC-2][m_new_frame_k_idx[m_PC-2]] - m_current_k[m_PC-2])*(1-inhibit_state)) INTERP_SHIFT))*(((m_PC-2)>4)?(1-m_uv_zpar):(1-m_zpar)); |
886 | | break; |
887 | | case 12: /* PC = 12 */ |
888 | | /* we should NEVER reach this point, PC=12 doesn't have a subcycle 2 */ |
889 | | break; |
890 | | } |
891 | | } |
| 868 | #ifdef DEBUG_GENERATION |
| 869 | fprintf(stderr,"Talk status is 0, forcing target energy to 0\n"); |
892 | 870 | #endif |
| 871 | m_target_energy = 0; |
893 | 872 | } |
| 873 | } |
| 874 | else // Not a new frame, just interpolate the existing frame. |
| 875 | { |
| 876 | int inhibit_state = ((m_inhibit==1)&&(m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the m_inhibit value |
| 877 | #ifdef PERFECT_INTERPOLATION_HACK |
| 878 | int samples_per_frame = m_subc_reload?175:266; // either (13 A cycles + 12 B cycles) * 7 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 7 interps for SPKSLOW |
| 879 | //int samples_per_frame = m_subc_reload?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW |
| 880 | int current_sample = (m_subcycle - m_subc_reload)+(m_PC*(3-m_subc_reload))+((m_subc_reload?25:38)*((m_IP-1)&7)); |
894 | 881 | |
895 | | // calculate the output |
896 | | if (OLD_FRAME_UNVOICED_FLAG == 1) |
| 882 | zpar = OLD_FRAME_UNVOICED_FLAG; |
| 883 | //fprintf(stderr, "CS: %03d", current_sample); |
| 884 | // reset the current energy, pitch, etc to what it was at frame start |
| 885 | m_current_energy = m_coeff->energytable[m_old_frame_energy_idx]; |
| 886 | m_current_pitch = m_coeff->pitchtable[m_old_frame_pitch_idx]; |
| 887 | for (i = 0; i < 4; i++) |
| 888 | m_current_k[i] = m_coeff->ktable[i][m_old_frame_k_idx[i]]; |
| 889 | for (i = 4; i < m_coeff->num_k; i++) |
| 890 | m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-zpar)); |
| 891 | // now adjust each value to be exactly correct for each of the samples per frame |
| 892 | if (m_IP != 0) // if we're still interpolating... |
897 | 893 | { |
898 | | // generate unvoiced samples here |
899 | | if (m_RNG & 1) |
900 | | m_excitation_data = ~0x3F; /* according to the patent it is (either + or -) half of the maximum value in the chirp table, so either 01000000(0x40) or 11000000(0xC0)*/ |
901 | | else |
902 | | m_excitation_data = 0x40; |
| 894 | m_current_energy += (((m_target_energy - m_current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame; |
| 895 | m_current_pitch += (((m_target_pitch - m_current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame; |
| 896 | for (i = 0; i < m_coeff->num_k; i++) |
| 897 | m_current_k[i] += (((m_target_k[i] - m_current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame; |
903 | 898 | } |
904 | | else /* (OLD_FRAME_UNVOICED_FLAG == 0) */ |
| 899 | else // we're done, play this frame for 1/8 frame. |
905 | 900 | { |
906 | | // generate voiced samples here |
907 | | /* US patent 4331836 Figure 14B shows, and logic would hold, that a pitch based chirp |
908 | | * function has a chirp/peak and then a long chain of zeroes. |
909 | | * The last entry of the chirp rom is at address 0b110011 (51d), the 52nd sample, |
910 | | * and if the address reaches that point the ADDRESS incrementer is |
911 | | * disabled, forcing all samples beyond 51d to be == 51d |
912 | | */ |
913 | | if (m_pitch_count >= 51) |
914 | | m_excitation_data = (INT8)m_coeff->chirptable[51]; |
915 | | else /*m_pitch_count < 51*/ |
916 | | m_excitation_data = (INT8)m_coeff->chirptable[m_pitch_count]; |
| 901 | m_current_energy = m_target_energy; |
| 902 | m_current_pitch = m_target_pitch; |
| 903 | for (i = 0; i < m_coeff->num_k; i++) |
| 904 | m_current_k[i] = m_target_k[i]; |
917 | 905 | } |
918 | | |
919 | | // Update LFSR *20* times every sample (once per T cycle), like patent shows |
920 | | for (i=0; i<20; i++) |
| 906 | #else |
| 907 | //Updates to parameters only happen on subcycle '2' (B cycle) of PCs. |
| 908 | if (m_subcycle == 2) |
921 | 909 | { |
922 | | bitout = ((m_RNG >> 12) & 1) ^ |
923 | | ((m_RNG >> 3) & 1) ^ |
924 | | ((m_RNG >> 2) & 1) ^ |
925 | | ((m_RNG >> 0) & 1); |
926 | | m_RNG <<= 1; |
927 | | m_RNG |= bitout; |
| 910 | switch(m_PC) |
| 911 | { |
| 912 | case 0: /* PC = 0, B cycle, write updated energy */ |
| 913 | m_current_energy += (((m_target_energy - m_current_energy)*(1-inhibit_state)) INTERP_SHIFT); |
| 914 | break; |
| 915 | case 1: /* PC = 1, B cycle, write updated pitch */ |
| 916 | m_current_pitch += (((m_target_pitch - m_current_pitch)*(1-inhibit_state)) INTERP_SHIFT); |
| 917 | break; |
| 918 | case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: |
| 919 | /* PC = 2 through 11, B cycle, write updated K1 through K10 */ |
| 920 | m_current_k[m_PC-2] += (((m_target_k[m_PC-2] - m_current_k[m_PC-2])*(1-inhibit_state)) INTERP_SHIFT); |
| 921 | break; |
| 922 | case 12: /* PC = 12, do nothing */ |
| 923 | break; |
| 924 | } |
928 | 925 | } |
929 | | this_sample = lattice_filter(); /* execute lattice filter */ |
| 926 | #endif |
| 927 | } |
| 928 | |
| 929 | // calculate the output |
| 930 | if (OLD_FRAME_UNVOICED_FLAG == 1) |
| 931 | { |
| 932 | // generate unvoiced samples here |
| 933 | if (m_RNG & 1) |
| 934 | m_excitation_data = ~0x3F; /* according to the patent it is (either + or -) half of the maximum value in the chirp table, so either 01000000(0x40) or 11000000(0xC0)*/ |
| 935 | else |
| 936 | m_excitation_data = 0x40; |
| 937 | } |
| 938 | else /* (OLD_FRAME_UNVOICED_FLAG == 0) */ |
| 939 | { |
| 940 | // generate voiced samples here |
| 941 | /* US patent 4331836 Figure 14B shows, and logic would hold, that a pitch based chirp |
| 942 | * function has a chirp/peak and then a long chain of zeroes. |
| 943 | * The last entry of the chirp rom is at address 0b110011 (51d), the 52nd sample, |
| 944 | * and if the address reaches that point the ADDRESS incrementer is |
| 945 | * disabled, forcing all samples beyond 51d to be == 51d |
| 946 | */ |
| 947 | if (m_pitch_count >= 51) |
| 948 | m_excitation_data = (INT8)m_coeff->chirptable[51]; |
| 949 | else /*m_pitch_count < 51*/ |
| 950 | m_excitation_data = (INT8)m_coeff->chirptable[m_pitch_count]; |
| 951 | } |
| 952 | |
| 953 | // Update LFSR *20* times every sample (once per T cycle), like patent shows |
| 954 | for (i=0; i<20; i++) |
| 955 | { |
| 956 | bitout = ((m_RNG >> 12) & 1) ^ |
| 957 | ((m_RNG >> 3) & 1) ^ |
| 958 | ((m_RNG >> 2) & 1) ^ |
| 959 | ((m_RNG >> 0) & 1); |
| 960 | m_RNG <<= 1; |
| 961 | m_RNG |= bitout; |
| 962 | } |
| 963 | this_sample = lattice_filter(); /* execute lattice filter */ |
930 | 964 | #ifdef DEBUG_GENERATION_VERBOSE |
931 | | //fprintf(stderr,"C:%01d; ",m_subcycle); |
932 | | fprintf(stderr,"IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",m_IP, m_PC, m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); |
933 | | //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); |
934 | | for (i=0; i<10; i++) |
935 | | fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]); |
936 | | fprintf(stderr,"Out:%06d ", this_sample); |
937 | | //#ifdef PERFECT_INTERPOLATION_HACK |
938 | | // fprintf(stderr,"%d%d%d%d",m_old_zpar,m_zpar,m_old_uv_zpar,m_uv_zpar); |
939 | | //#else |
940 | | // fprintf(stderr,"x%dx%d",m_zpar,m_uv_zpar); |
941 | | //#endif |
942 | | fprintf(stderr,"\n"); |
| 965 | //fprintf(stderr,"C:%01d; ",m_subcycle); |
| 966 | fprintf(stderr,"IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",m_IP, m_PC, m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); |
| 967 | //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); |
| 968 | for (i=0; i<10; i++) |
| 969 | fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]); |
| 970 | fprintf(stderr,"Out:%06d", this_sample); |
| 971 | fprintf(stderr,"\n"); |
943 | 972 | #endif |
944 | | /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */ |
945 | | while (this_sample > 16383) this_sample -= 32768; |
946 | | while (this_sample < -16384) this_sample += 32768; |
947 | | if (m_digital_select == 0) // analog SPK pin output is only 8 bits, with clipping |
948 | | buffer[buf_count] = clip_analog(this_sample); |
949 | | else // digital I/O pin output is 12 bits |
950 | | { |
| 973 | /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */ |
| 974 | while (this_sample > 16383) this_sample -= 32768; |
| 975 | while (this_sample < -16384) this_sample += 32768; |
| 976 | if (m_digital_select == 0) // analog SPK pin output is only 8 bits, with clipping |
| 977 | buffer[buf_count] = clip_analog(this_sample); |
| 978 | else // digital I/O pin output is 12 bits |
| 979 | { |
951 | 980 | #ifdef ALLOW_4_LSB |
952 | | // input: ssss ssss ssss ssss ssnn nnnn nnnn nnnn |
953 | | // N taps: ^ = 0x2000; |
954 | | // output: ssss ssss ssss ssss snnn nnnn nnnn nnnN |
955 | | buffer[buf_count] = (this_sample<<1)|((this_sample&0x2000)>>13); |
| 981 | // input: ssss ssss ssss ssss ssnn nnnn nnnn nnnn |
| 982 | // N taps: ^ = 0x2000; |
| 983 | // output: ssss ssss ssss ssss snnn nnnn nnnn nnnN |
| 984 | buffer[buf_count] = (this_sample<<1)|((this_sample&0x2000)>>13); |
956 | 985 | #else |
957 | | this_sample &= ~0xF; |
958 | | // input: ssss ssss ssss ssss ssnn nnnn nnnn 0000 |
959 | | // N taps: ^^ ^^^ = 0x3E00; |
960 | | // output: ssss ssss ssss ssss snnn nnnn nnnN NNNN |
961 | | buffer[buf_count] = (this_sample<<1)|((this_sample&0x3E00)>>9); |
| 986 | this_sample &= ~0xF; |
| 987 | // input: ssss ssss ssss ssss ssnn nnnn nnnn 0000 |
| 988 | // N taps: ^^ ^^^ = 0x3E00; |
| 989 | // output: ssss ssss ssss ssss snnn nnnn nnnN NNNN |
| 990 | buffer[buf_count] = (this_sample<<1)|((this_sample&0x3E00)>>9); |
962 | 991 | #endif |
963 | | } |
964 | | // Update all counts |
| 992 | } |
| 993 | // Update all counts |
965 | 994 | |
966 | | m_subcycle++; |
967 | | if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3 |
968 | | { |
969 | | /* Circuit 412 in the patent acts a reset, resetting the pitch counter to 0 |
970 | | * if INHIBIT was true during the most recent frame transition. |
971 | | * The exact time this occurs is betwen IP=7, PC=12 sub=0, T=t12 |
972 | | * and m_IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles, |
973 | | * which overlaps the time OLDE and OLDP are updated at IP=7 PC=12 T17 |
974 | | * (and hence INHIBIT itself 2 t-cycles later). We do it here because it is |
975 | | * convenient and should make no difference in output. |
976 | | */ |
977 | | if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_zero = 1; |
978 | | if ((m_IP == 0)&&(m_pitch_zero==1)) m_pitch_zero = 0; |
979 | | if (m_IP == 7) // RESETL4 |
980 | | { |
981 | | // Latch OLDE and OLDP |
982 | | OLD_FRAME_SILENCE_FLAG = NEW_FRAME_SILENCE_FLAG; // m_OLDE |
983 | | OLD_FRAME_UNVOICED_FLAG = NEW_FRAME_UNVOICED_FLAG; // m_OLDP |
984 | | /* if TALK was clear last frame, halt speech now, since TALKD (latched from TALK on new frame) just went inactive. */ |
985 | | #ifdef DEBUG_GENERATION |
986 | | fprintf(stderr,"RESETL4, about to update status: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); |
987 | | #endif |
988 | | #ifdef DEBUG_GENERATION |
989 | | if (m_TALK == 0) |
990 | | fprintf(stderr,"tms5220_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n"); |
991 | | #endif |
992 | | m_TALKD = m_TALK; // TALKD is latched from TALK |
993 | | update_fifo_status_and_ints(); // to trigger an interrupt if TALK_STATUS is now inactive |
994 | | m_TALK = m_SPEN; // TALK is latched from SPEN |
995 | | #ifdef DEBUG_GENERATION |
996 | | fprintf(stderr,"RESETL4, status updated: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); |
997 | | #endif |
998 | | } |
999 | | m_subcycle = m_subc_reload; |
1000 | | m_PC = 0; |
1001 | | m_IP++; |
1002 | | m_IP&=0x7; |
1003 | | } |
1004 | | else if (m_subcycle == 3) |
1005 | | { |
1006 | | m_subcycle = m_subc_reload; |
1007 | | m_PC++; |
1008 | | } |
1009 | | m_pitch_count++; |
1010 | | if ((m_pitch_count >= m_current_pitch)||(m_pitch_zero == 1)) m_pitch_count = 0; |
1011 | | m_pitch_count &= 0x1FF; |
| 995 | m_subcycle++; |
| 996 | if ((m_subcycle == 2) && (m_PC == 12)) |
| 997 | { |
| 998 | /* Circuit 412 in the patent acts a reset, resetting the pitch counter to 0 |
| 999 | * if INHIBIT was true during the most recent frame transition. |
| 1000 | * The exact time this occurs is betwen IP=7, PC=12 sub=0, T=t12 |
| 1001 | * and m_IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles, |
| 1002 | * which overlaps the time OLDE and OLDP are updated at IP=7 PC=12 T17 |
| 1003 | * (and hence INHIBIT itself 2 t-cycles later). We do it here because it is |
| 1004 | * convenient and should make no difference in output. |
| 1005 | */ |
| 1006 | if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_count = 0; |
| 1007 | m_subcycle = m_subc_reload; |
| 1008 | m_PC = 0; |
| 1009 | m_IP++; |
| 1010 | m_IP&=0x7; |
1012 | 1011 | } |
1013 | | else // m_TALKD == 0 |
| 1012 | else if (m_subcycle == 3) |
1014 | 1013 | { |
1015 | | m_subcycle++; |
1016 | | if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3 |
1017 | | { |
1018 | | if (m_IP == 7) // RESETL4 |
1019 | | { |
1020 | | m_TALKD = m_TALK; // TALKD is latched from TALK |
1021 | | m_TALK = m_SPEN; // TALK is latched from SPEN |
1022 | | } |
1023 | | m_subcycle = m_subc_reload; |
1024 | | m_PC = 0; |
1025 | | m_IP++; |
1026 | | m_IP&=0x7; |
1027 | | } |
1028 | | else if (m_subcycle == 3) |
1029 | | { |
1030 | | m_subcycle = m_subc_reload; |
1031 | | m_PC++; |
1032 | | } |
1033 | | buffer[buf_count] = -1; /* should be just -1; actual chip outputs -1 every idle sample; (cf note in data sheet, p 10, table 4) */ |
| 1014 | m_subcycle = m_subc_reload; |
| 1015 | m_PC++; |
1034 | 1016 | } |
1035 | | buf_count++; |
1036 | | size--; |
| 1017 | m_pitch_count++; |
| 1018 | if (m_pitch_count >= m_current_pitch) m_pitch_count = 0; |
| 1019 | m_pitch_count &= 0x1FF; |
| 1020 | buf_count++; |
| 1021 | size--; |
1037 | 1022 | } |
| 1023 | |
| 1024 | empty: |
| 1025 | |
| 1026 | while (size > 0) |
| 1027 | { |
| 1028 | m_subcycle++; |
| 1029 | if ((m_subcycle == 2) && (m_PC == 12)) |
| 1030 | { |
| 1031 | m_subcycle = m_subc_reload; |
| 1032 | m_PC = 0; |
| 1033 | m_IP++; |
| 1034 | m_IP&=0x7; |
| 1035 | } |
| 1036 | else if (m_subcycle == 3) |
| 1037 | { |
| 1038 | m_subcycle = m_subc_reload; |
| 1039 | m_PC++; |
| 1040 | } |
| 1041 | buffer[buf_count] = -1; /* should be just -1; actual chip outputs -1 every idle sample; (cf note in data sheet, p 10, table 4) */ |
| 1042 | buf_count++; |
| 1043 | size--; |
| 1044 | } |
1038 | 1045 | } |
1039 | 1046 | |
1040 | 1047 | /********************************************************************************************** |
r249094 | r249095 | |
1175 | 1182 | |
1176 | 1183 | void tms5220_device::process_command(unsigned char cmd) |
1177 | 1184 | { |
1178 | | int i; |
1179 | 1185 | #ifdef DEBUG_COMMAND_DUMP |
1180 | 1186 | fprintf(stderr,"process_command called with parameter %02X\n",cmd); |
1181 | 1187 | #endif |
r249094 | r249095 | |
1183 | 1189 | switch (cmd & 0x70) |
1184 | 1190 | { |
1185 | 1191 | case 0x10 : /* read byte */ |
1186 | | if (TALK_STATUS == 0) /* TALKST must be clear for RDBY */ |
| 1192 | if (m_talk_status == 0) /* TALKST must be clear for RDBY */ |
1187 | 1193 | { |
1188 | 1194 | if (m_schedule_dummy_read) |
1189 | 1195 | { |
r249094 | r249095 | |
1205 | 1211 | break; |
1206 | 1212 | |
1207 | 1213 | case 0x30 : /* read and branch */ |
1208 | | if (TALK_STATUS == 0) /* TALKST must be clear for RB */ |
| 1214 | if (m_talk_status == 0) /* TALKST must be clear for RB */ |
1209 | 1215 | { |
1210 | 1216 | #ifdef VERBOSE |
1211 | | fprintf(stderr,"read and branch command received\n"); |
| 1217 | logerror("read and branch command received\n"); |
1212 | 1218 | #endif |
1213 | 1219 | m_RDB_flag = FALSE; |
1214 | 1220 | if (m_speechrom) |
r249094 | r249095 | |
1217 | 1223 | break; |
1218 | 1224 | |
1219 | 1225 | case 0x40 : /* load address */ |
1220 | | if (TALK_STATUS == 0) /* TALKST must be clear for LA */ |
| 1226 | if (m_talk_status == 0) /* TALKST must be clear for LA */ |
1221 | 1227 | { |
1222 | 1228 | /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work. |
1223 | 1229 | This code does not care about this. */ |
r249094 | r249095 | |
1234 | 1240 | if (m_speechrom) |
1235 | 1241 | m_speechrom->read(1); |
1236 | 1242 | } |
1237 | | m_SPEN = 1; |
1238 | | #ifdef FAST_START_HACK |
1239 | | m_TALK = 1; |
1240 | | #endif |
1241 | | m_DDIS = 0; |
1242 | | m_zpar = 1; // zero all the parameters |
1243 | | m_uv_zpar = 1; // zero k4-k10 as well |
1244 | | m_OLDE = 1; // 'silence/zpar' frames are zero energy |
1245 | | m_OLDP = 1; // 'silence/zpar' frames are zero pitch |
1246 | | #ifdef PERFECT_INTERPOLATION_HACK |
1247 | | m_old_zpar = 1; // zero all the old parameters |
1248 | | m_old_uv_zpar = 1; // zero old k4-k10 as well |
1249 | | #endif |
1250 | | // following is semi-hack but matches idle state observed on chip |
| 1243 | m_speaking_now = 1; |
| 1244 | m_speak_external = 0; |
| 1245 | m_talk_status = 1; /* start immediately */ |
| 1246 | /* clear out variables before speaking */ |
| 1247 | // TODO: similar to the victory case described above, but for VSM speech |
| 1248 | m_subcycle = m_subc_reload; |
| 1249 | m_PC = 0; |
| 1250 | m_IP = reload_table[m_c_variant_rate&0x3]; |
1251 | 1251 | m_new_frame_energy_idx = 0; |
1252 | 1252 | m_new_frame_pitch_idx = 0; |
| 1253 | int i; |
1253 | 1254 | for (i = 0; i < 4; i++) |
1254 | 1255 | m_new_frame_k_idx[i] = 0; |
1255 | 1256 | for (i = 4; i < 7; i++) |
r249094 | r249095 | |
1259 | 1260 | break; |
1260 | 1261 | |
1261 | 1262 | case 0x60 : /* speak external */ |
1262 | | // SPKEXT going active activates SPKEE which clears the fifo |
| 1263 | //SPKEXT going active activates SPKEE which clears the fifo |
1263 | 1264 | m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0; |
1264 | | // SPEN is enabled when the fifo passes half full (falling edge of BL signal) |
1265 | | m_DDIS = 1; |
1266 | | m_zpar = 1; // zero all the parameters |
1267 | | m_uv_zpar = 1; // zero k4-k10 as well |
1268 | | m_OLDE = 1; // 'silence/zpar' frames are zero energy |
1269 | | m_OLDP = 1; // 'silence/zpar' frames are zero pitch |
1270 | | #ifdef PERFECT_INTERPOLATION_HACK |
1271 | | m_old_zpar = 1; // zero all the old parameters |
1272 | | m_old_uv_zpar = 1; // zero old k4-k10 as well |
1273 | | #endif |
1274 | | // following is semi-hack but matches idle state observed on chip |
1275 | | m_new_frame_energy_idx = 0; |
1276 | | m_new_frame_pitch_idx = 0; |
1277 | | for (i = 0; i < 4; i++) |
1278 | | m_new_frame_k_idx[i] = 0; |
1279 | | for (i = 4; i < 7; i++) |
1280 | | m_new_frame_k_idx[i] = 0xF; |
1281 | | for (i = 7; i < m_coeff->num_k; i++) |
1282 | | m_new_frame_k_idx[i] = 0x7; |
| 1265 | m_speak_external = 1; |
1283 | 1266 | m_RDB_flag = FALSE; |
1284 | 1267 | break; |
1285 | 1268 | |
r249094 | r249095 | |
1325 | 1308 | m_IP = reload_table[m_c_variant_rate&0x3]; |
1326 | 1309 | |
1327 | 1310 | update_fifo_status_and_ints(); |
1328 | | if (m_DDIS && m_buffer_empty) goto ranout; |
| 1311 | if (!m_talk_status) goto ranout; |
1329 | 1312 | |
1330 | 1313 | // attempt to extract the energy index |
1331 | 1314 | m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits); |
r249094 | r249095 | |
1334 | 1317 | fprintf(stderr," "); |
1335 | 1318 | #endif |
1336 | 1319 | update_fifo_status_and_ints(); |
1337 | | if (m_DDIS && m_buffer_empty) goto ranout; |
| 1320 | if (!m_talk_status) goto ranout; |
1338 | 1321 | // if the energy index is 0 or 15, we're done |
1339 | 1322 | if ((m_new_frame_energy_idx == 0) || (m_new_frame_energy_idx == 15)) |
1340 | 1323 | return; |
r249094 | r249095 | |
1354 | 1337 | fprintf(stderr," "); |
1355 | 1338 | #endif |
1356 | 1339 | update_fifo_status_and_ints(); |
1357 | | if (m_DDIS && m_buffer_empty) goto ranout; |
| 1340 | if (!m_talk_status) goto ranout; |
1358 | 1341 | // if this is a repeat frame, just do nothing, it will reuse the old coefficients |
1359 | 1342 | if (rep_flag) |
1360 | 1343 | return; |
r249094 | r249095 | |
1368 | 1351 | fprintf(stderr," "); |
1369 | 1352 | #endif |
1370 | 1353 | update_fifo_status_and_ints(); |
1371 | | if (m_DDIS && m_buffer_empty) goto ranout; |
| 1354 | if (!m_talk_status) goto ranout; |
1372 | 1355 | } |
1373 | 1356 | |
1374 | 1357 | // if the pitch index was zero, we only need 4 K's... |
r249094 | r249095 | |
1387 | 1370 | fprintf(stderr," "); |
1388 | 1371 | #endif |
1389 | 1372 | update_fifo_status_and_ints(); |
1390 | | if (m_DDIS && m_buffer_empty) goto ranout; |
| 1373 | if (!m_talk_status) goto ranout; |
1391 | 1374 | } |
1392 | | #ifdef DEBUG_PARSE_FRAME_DUMP |
1393 | | fprintf(stderr,"\n"); |
1394 | | #endif |
1395 | 1375 | #ifdef VERBOSE |
1396 | | if (m_DDIS) |
1397 | | fprintf(stderr,"Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken)); |
| 1376 | if (m_speak_external) |
| 1377 | logerror("Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken)); |
1398 | 1378 | else |
1399 | | fprintf(stderr,"Parsed a frame successfully in ROM\n"); |
| 1379 | logerror("Parsed a frame successfully in ROM\n"); |
1400 | 1380 | #endif |
1401 | 1381 | return; |
1402 | 1382 | |
1403 | 1383 | ranout: |
1404 | 1384 | #ifdef DEBUG_FRAME_ERRORS |
1405 | | fprintf(stderr,"Ran out of bits on a parse!\n"); |
| 1385 | logerror("Ran out of bits on a parse!\n"); |
1406 | 1386 | #endif |
1407 | 1387 | return; |
1408 | 1388 | } |
r249094 | r249095 | |
1417 | 1397 | { |
1418 | 1398 | if (!TMS5220_IS_52xx) return; // bail out if not a 52xx chip, since there's no int pin |
1419 | 1399 | #ifdef DEBUG_PIN_READS |
1420 | | fprintf(stderr,"irq pin set to state %d\n", state); |
| 1400 | logerror("irq pin set to state %d\n", state); |
1421 | 1401 | #endif |
1422 | 1402 | if (!m_irq_handler.isnull() && state != m_irq_pin) |
1423 | 1403 | m_irq_handler(!state); |
r249094 | r249095 | |
1434 | 1414 | { |
1435 | 1415 | int state = ready_read(); |
1436 | 1416 | #ifdef DEBUG_PIN_READS |
1437 | | fprintf(stderr,"ready pin set to state %d\n", state); |
| 1417 | logerror("ready pin set to state %d\n", state); |
1438 | 1418 | #endif |
1439 | 1419 | if (!m_readyq_handler.isnull() && state != m_ready_pin) |
1440 | 1420 | m_readyq_handler(!state); |
r249094 | r249095 | |
1534 | 1514 | |
1535 | 1515 | /* initialize the chip state */ |
1536 | 1516 | /* Note that we do not actually clear IRQ on start-up : IRQ is even raised if m_buffer_empty or m_buffer_low are 0 */ |
1537 | | m_SPEN = m_DDIS = m_TALK = m_TALKD = m_previous_TALK_STATUS = m_irq_pin = m_ready_pin = 0; |
| 1517 | m_speaking_now = m_speak_external = m_talk_status = m_irq_pin = m_ready_pin = 0; |
1538 | 1518 | set_interrupt_state(0); |
1539 | 1519 | update_ready_state(); |
1540 | 1520 | m_buffer_empty = m_buffer_low = 1; |
r249094 | r249095 | |
1545 | 1525 | #ifdef PERFECT_INTERPOLATION_HACK |
1546 | 1526 | m_old_frame_energy_idx = m_old_frame_pitch_idx = 0; |
1547 | 1527 | memset(m_old_frame_k_idx, 0, sizeof(m_old_frame_k_idx)); |
1548 | | m_old_zpar = 0; |
1549 | 1528 | #endif |
1550 | | m_new_frame_energy_idx = m_current_energy = m_previous_energy = 0; |
1551 | | m_new_frame_pitch_idx = m_current_pitch = 0; |
1552 | | m_zpar = m_uv_zpar = 0; |
| 1529 | m_new_frame_energy_idx = m_current_energy = m_target_energy = m_previous_energy = 0; |
| 1530 | m_new_frame_pitch_idx = m_current_pitch = m_target_pitch = 0; |
1553 | 1531 | memset(m_new_frame_k_idx, 0, sizeof(m_new_frame_k_idx)); |
1554 | 1532 | memset(m_current_k, 0, sizeof(m_current_k)); |
| 1533 | memset(m_target_k, 0, sizeof(m_target_k)); |
1555 | 1534 | |
1556 | 1535 | /* initialize the sample generators */ |
1557 | 1536 | m_inhibit = 1; |
r249094 | r249095 | |
1595 | 1574 | /* Write */ |
1596 | 1575 | /* bring up to date first */ |
1597 | 1576 | #ifdef DEBUG_IO_READY |
1598 | | fprintf(stderr,"Serviced write: %02x\n", m_write_latch); |
| 1577 | logerror("Serviced write: %02x\n", m_write_latch); |
1599 | 1578 | //fprintf(stderr, "Processed write data: %02X\n", m_write_latch); |
1600 | 1579 | #endif |
1601 | 1580 | m_stream->update(); |
r249094 | r249095 | |
1631 | 1610 | m_true_timing = 1; |
1632 | 1611 | state &= 0x01; |
1633 | 1612 | #ifdef DEBUG_RS_WS |
1634 | | fprintf(stderr,"/RS written with data: %d\n", state); |
| 1613 | logerror("/RS written with data: %d\n", state); |
1635 | 1614 | #endif |
1636 | 1615 | new_val = (m_rs_ws & 0x01) | (state<<1); |
1637 | 1616 | if (new_val != m_rs_ws) |
r249094 | r249095 | |
1644 | 1623 | #ifdef DEBUG_RS_WS |
1645 | 1624 | else |
1646 | 1625 | /* illegal */ |
1647 | | fprintf(stderr,"tms5220_rs_w: illegal\n"); |
| 1626 | logerror("tms5220_rs_w: illegal\n"); |
1648 | 1627 | #endif |
1649 | 1628 | return; |
1650 | 1629 | } |
r249094 | r249095 | |
1662 | 1641 | { |
1663 | 1642 | /* high to low - schedule ready cycle */ |
1664 | 1643 | #ifdef DEBUG_RS_WS |
1665 | | fprintf(stderr,"Scheduling ready cycle for /RS...\n"); |
| 1644 | logerror("Scheduling ready cycle for /RS...\n"); |
1666 | 1645 | #endif |
1667 | 1646 | /* upon /RS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ |
1668 | 1647 | m_io_ready = 0; |
r249094 | r249095 | |
1683 | 1662 | m_true_timing = 1; |
1684 | 1663 | state &= 0x01; |
1685 | 1664 | #ifdef DEBUG_RS_WS |
1686 | | fprintf(stderr,"/WS written with data: %d\n", state); |
| 1665 | logerror("/WS written with data: %d\n", state); |
1687 | 1666 | #endif |
1688 | 1667 | new_val = (m_rs_ws & 0x02) | (state<<0); |
1689 | 1668 | if (new_val != m_rs_ws) |
r249094 | r249095 | |
1696 | 1675 | #ifdef DEBUG_RS_WS |
1697 | 1676 | else |
1698 | 1677 | /* illegal */ |
1699 | | fprintf(stderr,"tms5220_ws_w: illegal\n"); |
| 1678 | logerror("tms5220_ws_w: illegal\n"); |
1700 | 1679 | #endif |
1701 | 1680 | return; |
1702 | 1681 | } |
r249094 | r249095 | |
1714 | 1693 | { |
1715 | 1694 | /* high to low - schedule ready cycle */ |
1716 | 1695 | #ifdef DEBUG_RS_WS |
1717 | | fprintf(stderr,"Scheduling ready cycle for /WS...\n"); |
| 1696 | logerror("Scheduling ready cycle for /WS...\n"); |
1718 | 1697 | #endif |
1719 | 1698 | /* upon /WS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ |
1720 | 1699 | m_io_ready = 0; |
r249094 | r249095 | |
1747 | 1726 | if (space.debugger_access()) return; |
1748 | 1727 | |
1749 | 1728 | #ifdef DEBUG_RS_WS |
1750 | | fprintf(stderr,"tms5220_data_w: data %02x\n", data); |
| 1729 | logerror("tms5220_data_w: data %02x\n", data); |
1751 | 1730 | #endif |
1752 | 1731 | if (!m_true_timing) |
1753 | 1732 | { |
r249094 | r249095 | |
1760 | 1739 | /* actually in a write ? */ |
1761 | 1740 | #ifdef DEBUG_RS_WS |
1762 | 1741 | if (!(m_rs_ws == 0x02)) |
1763 | | fprintf(stderr,"tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws); |
| 1742 | logerror("tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws); |
1764 | 1743 | #endif |
1765 | 1744 | m_write_latch = data; |
1766 | 1745 | } |
r249094 | r249095 | |
1792 | 1771 | return m_read_latch; |
1793 | 1772 | #ifdef DEBUG_RS_WS |
1794 | 1773 | else |
1795 | | fprintf(stderr,"tms5220_status_r: data read outside rs!\n"); |
| 1774 | logerror("tms5220_status_r: data read outside rs!\n"); |
1796 | 1775 | #endif |
1797 | 1776 | return 0xff; |
1798 | 1777 | } |
trunk/src/mame/drivers/deco32.c
r249094 | r249095 | |
223 | 223 | |
224 | 224 | PROM.9J Fujitsu MB7124 compatible with 82S147 Labelled 'LN-00' |
225 | 225 | |
226 | | Night Slashers |
227 | | Data East, 1993 |
228 | | |
229 | | DE-0395-1 DEC-22VO |
230 | | |-----------------------------------------------------| |
231 | | | TA8205AH 6164 |-----| 2M-16M* MBH-07| |
232 | | | 02- HuC6280A | 52 | MBH-09 MBH-06| |
233 | | | YM2151 | | 2M-16M* MBH-05| |
234 | | | YM3012 32.220MHz |-----| MBH-08 MBH-04| |
235 | | | JP1 MBH-11 93C45 |-----| MBH-03| |
236 | | |CN2 MBH-10 | 52 | MBH-02| |
237 | | | M6295(1) | | | |
238 | | | M6295(2) |-----| | |
239 | | | |-----| |-----| | |
240 | | |J | 104 | |-----| |-----| | 52 | | |
241 | | |A | | | 153 | | 113 | | | | |
242 | | |M |-----| | | | | |-----| | |
243 | | |M |-----| |-----| 28MHz | |
244 | | |A |-----| | |
245 | | | | 99 | VM-02 | |
246 | | | | | LN-00 |-----| 6164 MBH-01 | |
247 | | | |-----| | 74 | 6164 | |
248 | | | | | MBH-00 | |
249 | | | |-----| |-----| |-----| | |
250 | | | | 113 | | 200 | |-----| 6164 | |
251 | | | | | | | | 141 | 6164 | |
252 | | | |-----| |-----| | | VE-01A | |
253 | | |TEST_SW |-----| VE-00 |-----| | |
254 | | | | 156 | | |
255 | | | CN4 LH52250 LH52250 01- | | | |
256 | | | CN3 LH52250 LH52250 00- |-----| | |
257 | | |-----------------------------------------------------| |
258 | 226 | |
259 | | NOTE: Program EPROMs did NOT have regional letter codes, just 00, 01 & 02 |
260 | 227 | |
261 | | Same PCB as shown below for Fighter's History, but populated with more |
262 | | chips as needed. It is worth noting that Night Slashers uses the encryption |
263 | | features of the 156 chip where as Fighter's History does not. |
264 | | |
265 | | ***************************************************************************************************** |
266 | | |
267 | 228 | Fighter's History |
268 | 229 | Data East, 1993 |
269 | 230 | |
r249094 | r249095 | |
300 | 261 | | CN3* LH52250 LH52250 LE00 |-----| | |
301 | 262 | |-----------------------------------------------------| |
302 | 263 | |
303 | | |
304 | 264 | Very similar to the DE-0396-0 described below with the notable exceptions: |
305 | 265 | The sound area reworked to use the HuC6280A instead of a standard Z80 |
306 | 266 | Uses the larger 113 instead of the 153 chips, however both PCBs have |
r249094 | r249095 | |
2512 | 2472 | |
2513 | 2473 | /**********************************************************************************/ |
2514 | 2474 | |
2515 | | ROM_START( captaven ) /* DE-0351-x PCB (x=3 or 4) */ |
| 2475 | ROM_START( captaven ) |
2516 | 2476 | ROM_REGION(0x100000, "maincpu", 0 ) /* ARM 32 bit code */ |
2517 | 2477 | ROM_LOAD32_BYTE( "hn_00-4.1e", 0x000000, 0x20000, CRC(147fb094) SHA1(6bd759c42f4b7f9e1c3f2d3ece0b3ec72de1a982) ) |
2518 | 2478 | ROM_LOAD32_BYTE( "hn_01-4.1h", 0x000001, 0x20000, CRC(11ecdb95) SHA1(832b56f05ae7e15e67fbdd321da8c1cc5e7629a0) ) |
r249094 | r249095 | |
2562 | 2522 | |
2563 | 2523 | ROM_REGION(0x80000, "oki1", 0 ) |
2564 | 2524 | ROM_LOAD( "man-11.16k", 0x000000, 0x80000, CRC(0dc60a4c) SHA1(4d0daa6a0272852a37f341a0cdc48baee0ad9dd8) ) |
2565 | | |
2566 | | ROM_REGION( 0x0600, "plds", 0 ) |
2567 | | ROM_LOAD( "ts-00.4h", 0x0000, 0x0117, CRC(ebc2908e) SHA1(dca14a55abd1d88ee09092d4122614e55c3e7f53) ) |
2568 | | ROM_LOAD( "ts-01.5h", 0x0200, 0x0117, CRC(c776a980) SHA1(cd4bdcfb755f561fefa4c88fab5d6d2397332aa7) ) |
2569 | | ROM_LOAD( "ts-02.12l", 0x0400, 0x01bf, CRC(6f26528c) SHA1(2cf869b2a789a9b0646162a61c147bcbb13c9141) ) |
2570 | 2525 | ROM_END |
2571 | 2526 | |
2572 | | ROM_START( captavena ) /* DE-0351-x PCB (x=3 or 4) */ |
| 2527 | ROM_START( captavena ) |
2573 | 2528 | ROM_REGION(0x100000, "maincpu", 0 ) /* ARM 32 bit code */ |
2574 | 2529 | ROM_LOAD32_BYTE( "hn_00.e1", 0x000000, 0x20000, CRC(12dd0c71) SHA1(77bd0e5f1b105ec70de5e76cb9c8138f02a496be) ) |
2575 | 2530 | ROM_LOAD32_BYTE( "hn_01.h1", 0x000001, 0x20000, CRC(ac5ea492) SHA1(e08fa2b3e3a40cba6dcdf07049d67056d59ed72a) ) |
r249094 | r249095 | |
2619 | 2574 | |
2620 | 2575 | ROM_REGION(0x80000, "oki1", 0 ) |
2621 | 2576 | ROM_LOAD( "man-11.16k", 0x000000, 0x80000, CRC(0dc60a4c) SHA1(4d0daa6a0272852a37f341a0cdc48baee0ad9dd8) ) |
2622 | | |
2623 | | ROM_REGION( 0x0600, "plds", 0 ) |
2624 | | ROM_LOAD( "ts-00.4h", 0x0000, 0x0117, CRC(ebc2908e) SHA1(dca14a55abd1d88ee09092d4122614e55c3e7f53) ) |
2625 | | ROM_LOAD( "ts-01.5h", 0x0200, 0x0117, CRC(c776a980) SHA1(cd4bdcfb755f561fefa4c88fab5d6d2397332aa7) ) |
2626 | | ROM_LOAD( "ts-02.12l", 0x0400, 0x01bf, CRC(6f26528c) SHA1(2cf869b2a789a9b0646162a61c147bcbb13c9141) ) |
2627 | 2577 | ROM_END |
2628 | 2578 | |
2629 | | ROM_START( captavene ) /* DE-0351-x PCB (x=3 or 4) */ |
| 2579 | ROM_START( captavene ) |
2630 | 2580 | ROM_REGION(0x100000, "maincpu", 0 ) /* ARM 32 bit code */ |
2631 | 2581 | ROM_LOAD32_BYTE( "hg_00-4.1e", 0x000000, 0x20000, CRC(7008d43c) SHA1(a39143e13075ebc58ecc576391f04d2649675dfb) ) |
2632 | 2582 | ROM_LOAD32_BYTE( "hg_01-4.1h", 0x000001, 0x20000, CRC(53dc1042) SHA1(4547ad20e5bc3b9cedae53f73f1628fa3493aafa) ) |
r249094 | r249095 | |
2678 | 2628 | ROM_LOAD( "man-11.16k", 0x000000, 0x80000, CRC(0dc60a4c) SHA1(4d0daa6a0272852a37f341a0cdc48baee0ad9dd8) ) |
2679 | 2629 | |
2680 | 2630 | ROM_REGION( 0x0800, "plds", 0 ) |
2681 | | ROM_LOAD( "ts-00.4h", 0x0000, 0x0117, CRC(ebc2908e) SHA1(dca14a55abd1d88ee09092d4122614e55c3e7f53) ) |
2682 | | ROM_LOAD( "ts-01.5h", 0x0200, 0x0117, CRC(c776a980) SHA1(cd4bdcfb755f561fefa4c88fab5d6d2397332aa7) ) |
2683 | | ROM_LOAD( "ts-02.12l", 0x0400, 0x01bf, CRC(6f26528c) SHA1(2cf869b2a789a9b0646162a61c147bcbb13c9141) ) |
| 2631 | ROM_LOAD( "pal16l8a.12l", 0x0000, 0x0104, NO_DUMP ) /* PAL is read protected */ |
| 2632 | ROM_LOAD( "pal16l8a.4h", 0x0200, 0x0104, NO_DUMP ) /* PAL is read protected */ |
| 2633 | ROM_LOAD( "pal16l8a.5h", 0x0400, 0x0104, NO_DUMP ) /* PAL is read protected */ |
2684 | 2634 | ROM_LOAD( "pal16r8b.14c", 0x0600, 0x0104, NO_DUMP ) /* PAL is read protected */ |
2685 | 2635 | ROM_END |
2686 | 2636 | |
2687 | | ROM_START( captavenu ) /* DE-0351-x PCB (x=3 or 4) */ |
| 2637 | ROM_START( captavenu ) |
2688 | 2638 | ROM_REGION(0x100000, "maincpu", 0 ) /* ARM 32 bit code */ |
2689 | 2639 | ROM_LOAD32_BYTE( "hh_00-19.1e", 0x000000, 0x20000, CRC(08b870e0) SHA1(44c837e3c5dfc9764d89b0ebb3e9b7a40fe4d76f) ) |
2690 | 2640 | ROM_LOAD32_BYTE( "hh_01-19.1h", 0x000001, 0x20000, CRC(0dc0feca) SHA1(cb1c97aac59dabcf6c37bc1562cf2f62bca951f1) ) |
r249094 | r249095 | |
2734 | 2684 | |
2735 | 2685 | ROM_REGION(0x80000, "oki1", 0 ) |
2736 | 2686 | ROM_LOAD( "man-11.16k", 0x000000, 0x80000, CRC(0dc60a4c) SHA1(4d0daa6a0272852a37f341a0cdc48baee0ad9dd8) ) |
2737 | | |
2738 | | ROM_REGION( 0x0600, "plds", 0 ) |
2739 | | ROM_LOAD( "ts-00.4h", 0x0000, 0x0117, CRC(ebc2908e) SHA1(dca14a55abd1d88ee09092d4122614e55c3e7f53) ) |
2740 | | ROM_LOAD( "ts-01.5h", 0x0200, 0x0117, CRC(c776a980) SHA1(cd4bdcfb755f561fefa4c88fab5d6d2397332aa7) ) |
2741 | | ROM_LOAD( "ts-02.12l", 0x0400, 0x01bf, CRC(6f26528c) SHA1(2cf869b2a789a9b0646162a61c147bcbb13c9141) ) |
2742 | 2687 | ROM_END |
2743 | 2688 | |
2744 | | ROM_START( captavenuu ) /* DE-0351-x PCB (x=3 or 4) */ |
| 2689 | ROM_START( captavenuu ) |
2745 | 2690 | ROM_REGION(0x100000, "maincpu", 0 ) /* ARM 32 bit code */ |
2746 | 2691 | ROM_LOAD32_BYTE( "hh-00.1e", 0x000000, 0x20000, CRC(c34da654) SHA1(a1988a6a45991db6dee10b484049f6703b4671c9) ) |
2747 | 2692 | ROM_LOAD32_BYTE( "hh-01.1h", 0x000001, 0x20000, CRC(55abe63f) SHA1(98772eff3ebb5a4f243c7a77d398eb142d1505cb) ) |
r249094 | r249095 | |
2791 | 2736 | |
2792 | 2737 | ROM_REGION(0x80000, "oki1", 0 ) |
2793 | 2738 | ROM_LOAD( "man-11.16k", 0x000000, 0x80000, CRC(0dc60a4c) SHA1(4d0daa6a0272852a37f341a0cdc48baee0ad9dd8) ) |
2794 | | |
2795 | | ROM_REGION( 0x0600, "plds", 0 ) |
2796 | | ROM_LOAD( "ts-00.4h", 0x0000, 0x0117, CRC(ebc2908e) SHA1(dca14a55abd1d88ee09092d4122614e55c3e7f53) ) |
2797 | | ROM_LOAD( "ts-01.5h", 0x0200, 0x0117, CRC(c776a980) SHA1(cd4bdcfb755f561fefa4c88fab5d6d2397332aa7) ) |
2798 | | ROM_LOAD( "ts-02.12l", 0x0400, 0x01bf, CRC(6f26528c) SHA1(2cf869b2a789a9b0646162a61c147bcbb13c9141) ) |
2799 | 2739 | ROM_END |
2800 | 2740 | |
2801 | | ROM_START( captavenua ) /* DE-0351-x PCB (x=3 or 4) */ |
| 2741 | ROM_START( captavenua ) |
2802 | 2742 | ROM_REGION(0x100000, "maincpu", 0 ) /* ARM 32 bit code */ |
2803 | 2743 | ROM_LOAD32_BYTE( "hh_00-4.2e", 0x000000, 0x20000, CRC(0e1acc05) SHA1(7eb6206efad233f9f4ee51102f9fe6b58f0719ea) ) |
2804 | 2744 | ROM_LOAD32_BYTE( "hh_01-4.2h", 0x000001, 0x20000, CRC(4ff0351d) SHA1(15fc2662ff0d32986c4d4d074b985ad853da34e1) ) |
r249094 | r249095 | |
2848 | 2788 | |
2849 | 2789 | ROM_REGION(0x80000, "oki1", 0 ) |
2850 | 2790 | ROM_LOAD( "man-11.16k", 0x000000, 0x80000, CRC(0dc60a4c) SHA1(4d0daa6a0272852a37f341a0cdc48baee0ad9dd8) ) |
2851 | | |
2852 | | ROM_REGION( 0x0600, "plds", 0 ) |
2853 | | ROM_LOAD( "ts-00.4h", 0x0000, 0x0117, CRC(ebc2908e) SHA1(dca14a55abd1d88ee09092d4122614e55c3e7f53) ) |
2854 | | ROM_LOAD( "ts-01.5h", 0x0200, 0x0117, CRC(c776a980) SHA1(cd4bdcfb755f561fefa4c88fab5d6d2397332aa7) ) |
2855 | | ROM_LOAD( "ts-02.12l", 0x0400, 0x01bf, CRC(6f26528c) SHA1(2cf869b2a789a9b0646162a61c147bcbb13c9141) ) |
2856 | 2791 | ROM_END |
2857 | 2792 | |
2858 | | ROM_START( captavenj ) /* DE-0351-x PCB (x=3 or 4) */ |
| 2793 | ROM_START( captavenj ) |
2859 | 2794 | ROM_REGION(0x100000, "maincpu", 0 ) /* ARM 32 bit code */ |
2860 | 2795 | ROM_LOAD32_BYTE( "hj_00-2.1e", 0x000000, 0x20000, CRC(10b1faaf) SHA1(9d76885200a846b4751c8d44ff591e2aff7c4148) ) |
2861 | 2796 | ROM_LOAD32_BYTE( "hj_01-2.1h", 0x000001, 0x20000, CRC(62c59f27) SHA1(20bbb7f3ff63a8c795686c1d56d51e90305daa77) ) |
r249094 | r249095 | |
2905 | 2840 | |
2906 | 2841 | ROM_REGION(0x80000, "oki1", 0 ) |
2907 | 2842 | ROM_LOAD( "man-11.16k", 0x000000, 0x80000, CRC(0dc60a4c) SHA1(4d0daa6a0272852a37f341a0cdc48baee0ad9dd8) ) |
2908 | | |
2909 | | ROM_REGION( 0x0600, "plds", 0 ) |
2910 | | ROM_LOAD( "ts-00.4h", 0x0000, 0x0117, CRC(ebc2908e) SHA1(dca14a55abd1d88ee09092d4122614e55c3e7f53) ) |
2911 | | ROM_LOAD( "ts-01.5h", 0x0200, 0x0117, CRC(c776a980) SHA1(cd4bdcfb755f561fefa4c88fab5d6d2397332aa7) ) |
2912 | | ROM_LOAD( "ts-02.12l", 0x0400, 0x01bf, CRC(6f26528c) SHA1(2cf869b2a789a9b0646162a61c147bcbb13c9141) ) |
2913 | 2843 | ROM_END |
2914 | 2844 | |
2915 | 2845 | ROM_START( dragngun ) |
r249094 | r249095 | |
3092 | 3022 | ROM_LOAD( "kt-00.8j", 0, 512, CRC(7294354b) SHA1(14fe42ad5d26d022c0fe9a46a4a9017af2296f40) ) /* MB7124H type prom */ |
3093 | 3023 | |
3094 | 3024 | ROM_REGION( 0x0400, "plds", 0 ) |
3095 | | ROM_LOAD( "ve-00.3d", 0x0000, 0x0117, CRC(384d316c) SHA1(61b50c695d4210c199cf6f7bbe50c8a5ecd1d21c) ) |
3096 | | ROM_LOAD( "ve-01.4d", 0x0200, 0x0117, CRC(4ba7e6a9) SHA1(b65d696a3519e792df226f9f148c759cdb0e1e43) ) |
| 3025 | ROM_LOAD( "ve-00.3d", 0x0000, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
| 3026 | ROM_LOAD( "ve-01.4d", 0x0200, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
3097 | 3027 | ROM_END |
3098 | 3028 | |
3099 | 3029 | ROM_START( fghthista ) /* DE-0380-2 PCB */ |
r249094 | r249095 | |
3126 | 3056 | ROM_LOAD( "kt-00.8j", 0, 512, CRC(7294354b) SHA1(14fe42ad5d26d022c0fe9a46a4a9017af2296f40) ) /* MB7124H type prom */ |
3127 | 3057 | |
3128 | 3058 | ROM_REGION( 0x0400, "plds", 0 ) |
3129 | | ROM_LOAD( "ve-00.3d", 0x0000, 0x0117, CRC(384d316c) SHA1(61b50c695d4210c199cf6f7bbe50c8a5ecd1d21c) ) |
3130 | | ROM_LOAD( "ve-01.4d", 0x0200, 0x0117, CRC(4ba7e6a9) SHA1(b65d696a3519e792df226f9f148c759cdb0e1e43) ) |
3131 | | /* PAL16L8BCN at 8J is unpopulated */ |
| 3059 | ROM_LOAD( "ve-00.3d", 0x0000, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
| 3060 | ROM_LOAD( "ve-01.4d", 0x0200, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
3132 | 3061 | ROM_END |
3133 | 3062 | |
3134 | 3063 | ROM_START( fghthistu ) /* DE-0396-0 PCB */ |
r249094 | r249095 | |
3161 | 3090 | ROM_LOAD( "kt-00.8j", 0, 512, CRC(7294354b) SHA1(14fe42ad5d26d022c0fe9a46a4a9017af2296f40) ) /* MB7124H type prom */ |
3162 | 3091 | |
3163 | 3092 | ROM_REGION( 0x0400, "plds", 0 ) |
3164 | | ROM_LOAD( "ve-00.3d", 0x0000, 0x0117, CRC(384d316c) SHA1(61b50c695d4210c199cf6f7bbe50c8a5ecd1d21c) ) |
3165 | | ROM_LOAD( "ve-01.4d", 0x0200, 0x0117, CRC(4ba7e6a9) SHA1(b65d696a3519e792df226f9f148c759cdb0e1e43) ) |
3166 | | /* PAL16L8BCN at 8J is unpopulated */ |
| 3093 | ROM_LOAD( "ve-00.3d", 0x0000, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
| 3094 | ROM_LOAD( "ve-01.4d", 0x0200, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
3167 | 3095 | ROM_END |
3168 | 3096 | |
3169 | 3097 | ROM_START( fghthistua ) /* DE-0395-1 PCB */ |
r249094 | r249095 | |
3196 | 3124 | ROM_LOAD( "kt-00.8j", 0, 512, CRC(7294354b) SHA1(14fe42ad5d26d022c0fe9a46a4a9017af2296f40) ) /* MB7124H type prom */ |
3197 | 3125 | |
3198 | 3126 | ROM_REGION( 0x0400, "plds", 0 ) |
3199 | | ROM_LOAD( "ve-00.3d", 0x0000, 0x0117, CRC(384d316c) SHA1(61b50c695d4210c199cf6f7bbe50c8a5ecd1d21c) ) |
3200 | | ROM_LOAD( "ve-01a.4d", 0x0200, 0x0117, CRC(109613c8) SHA1(5991e010c1bc2a827c8ee2c85a9b40e00a3167b3) ) |
3201 | | /* PAL16L8BCN at 8J is unpopulated */ |
| 3127 | ROM_LOAD( "ve-00.3d", 0x0000, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
| 3128 | ROM_LOAD( "ve-01a.4d", 0x0200, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
3202 | 3129 | ROM_END |
3203 | 3130 | |
3204 | 3131 | ROM_START( fghthistub ) /* DE-0395-1 PCB */ |
r249094 | r249095 | |
3231 | 3158 | ROM_LOAD( "kt-00.8j", 0, 512, CRC(7294354b) SHA1(14fe42ad5d26d022c0fe9a46a4a9017af2296f40) ) /* MB7124H type prom */ |
3232 | 3159 | |
3233 | 3160 | ROM_REGION( 0x0400, "plds", 0 ) |
3234 | | ROM_LOAD( "ve-00.3d", 0x0000, 0x0117, CRC(384d316c) SHA1(61b50c695d4210c199cf6f7bbe50c8a5ecd1d21c) ) |
3235 | | ROM_LOAD( "ve-01a.4d", 0x0200, 0x0117, CRC(109613c8) SHA1(5991e010c1bc2a827c8ee2c85a9b40e00a3167b3) ) |
3236 | | /* PAL16L8BCN at 8J is unpopulated */ |
| 3161 | ROM_LOAD( "ve-00.3d", 0x0000, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
| 3162 | ROM_LOAD( "ve-01a.4d", 0x0200, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
3237 | 3163 | ROM_END |
3238 | 3164 | |
3239 | 3165 | ROM_START( fghthistuc ) /* DE-0380-2 PCB */ |
r249094 | r249095 | |
3266 | 3192 | ROM_LOAD( "kt-00.8j", 0, 512, CRC(7294354b) SHA1(14fe42ad5d26d022c0fe9a46a4a9017af2296f40) ) /* MB7124H type prom */ |
3267 | 3193 | |
3268 | 3194 | ROM_REGION( 0x0400, "plds", 0 ) |
3269 | | ROM_LOAD( "ve-00.3d", 0x0000, 0x0117, CRC(384d316c) SHA1(61b50c695d4210c199cf6f7bbe50c8a5ecd1d21c) ) |
3270 | | ROM_LOAD( "ve-01.4d", 0x0200, 0x0117, CRC(4ba7e6a9) SHA1(b65d696a3519e792df226f9f148c759cdb0e1e43) ) |
3271 | | /* PAL16L8BCN at 8J is unpopulated */ |
| 3195 | ROM_LOAD( "ve-00.3d", 0x0000, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
| 3196 | ROM_LOAD( "ve-01.4d", 0x0200, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
3272 | 3197 | ROM_END |
3273 | 3198 | |
3274 | 3199 | ROM_START( fghthistj ) /* DE-0395-1 PCB */ |
r249094 | r249095 | |
3301 | 3226 | ROM_LOAD( "kt-00.8j", 0, 512, CRC(7294354b) SHA1(14fe42ad5d26d022c0fe9a46a4a9017af2296f40) ) /* MB7124H type prom */ |
3302 | 3227 | |
3303 | 3228 | ROM_REGION( 0x0400, "plds", 0 ) |
3304 | | ROM_LOAD( "ve-00.3d", 0x0000, 0x0117, CRC(384d316c) SHA1(61b50c695d4210c199cf6f7bbe50c8a5ecd1d21c) ) |
3305 | | ROM_LOAD( "ve-01a.4d", 0x0200, 0x0117, CRC(109613c8) SHA1(5991e010c1bc2a827c8ee2c85a9b40e00a3167b3) ) |
3306 | | /* PAL16L8BCN at 8J is unpopulated */ |
| 3229 | ROM_LOAD( "ve-00.3d", 0x0000, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
| 3230 | ROM_LOAD( "ve-01a.4d", 0x0200, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
3307 | 3231 | ROM_END |
3308 | 3232 | |
3309 | 3233 | ROM_START( fghthistja ) /* DE-0380-2 PCB */ |
r249094 | r249095 | |
3336 | 3260 | ROM_LOAD( "kt-00.8j", 0, 512, CRC(7294354b) SHA1(14fe42ad5d26d022c0fe9a46a4a9017af2296f40) ) /* MB7124H type prom */ |
3337 | 3261 | |
3338 | 3262 | ROM_REGION( 0x0400, "plds", 0 ) |
3339 | | ROM_LOAD( "ve-00.3d", 0x0000, 0x0117, CRC(384d316c) SHA1(61b50c695d4210c199cf6f7bbe50c8a5ecd1d21c) ) |
3340 | | ROM_LOAD( "ve-01.4d", 0x0200, 0x0117, CRC(4ba7e6a9) SHA1(b65d696a3519e792df226f9f148c759cdb0e1e43) ) |
3341 | | /* PAL16L8BCN at 8J is unpopulated */ |
| 3263 | ROM_LOAD( "ve-00.3d", 0x0000, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
| 3264 | ROM_LOAD( "ve-01.4d", 0x0200, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
3342 | 3265 | ROM_END |
3343 | 3266 | |
3344 | 3267 | ROM_START( fghthistjb ) /* DE-0380-1 PCB */ |
r249094 | r249095 | |
3371 | 3294 | ROM_LOAD( "kt-00.8j", 0, 512, CRC(7294354b) SHA1(14fe42ad5d26d022c0fe9a46a4a9017af2296f40) ) /* MB7124H type prom */ |
3372 | 3295 | |
3373 | 3296 | ROM_REGION( 0x0400, "plds", 0 ) |
3374 | | ROM_LOAD( "ve-00.3d", 0x0000, 0x0117, CRC(384d316c) SHA1(61b50c695d4210c199cf6f7bbe50c8a5ecd1d21c) ) |
3375 | | ROM_LOAD( "ve-01.4d", 0x0200, 0x0117, CRC(4ba7e6a9) SHA1(b65d696a3519e792df226f9f148c759cdb0e1e43) ) |
3376 | | /* PAL16L8BCN at 8J is unpopulated */ |
| 3297 | ROM_LOAD( "ve-00.3d", 0x0000, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
| 3298 | ROM_LOAD( "ve-01.4d", 0x0200, 0x0104, NO_DUMP ) /* PAL16L8 is read protected */ |
3377 | 3299 | ROM_END |
3378 | 3300 | |
3379 | 3301 | ROM_START( lockload ) /* Board No. DE-0420-1 + Bottom board DE-0421-0 slightly different hardware, a unique PCB and not a Dragongun conversion */ |
r249094 | r249095 | |
3751 | 3673 | ROM_LOAD( "eeprom-tattass.bin", 0x0000, 0x0400, CRC(7140f40c) SHA1(4fb7897933046b6adaf00b4626d5fd23d0e8a666) ) |
3752 | 3674 | ROM_END |
3753 | 3675 | |
3754 | | ROM_START( nslasher ) /* DE-0397-0 PCB */ |
| 3676 | ROM_START( nslasher ) |
3755 | 3677 | ROM_REGION(0x100000, "maincpu", 0 ) /* Encrypted ARM 32 bit code */ |
3756 | 3678 | ROM_LOAD32_WORD( "mainprg.1f", 0x000000, 0x80000, CRC(507acbae) SHA1(329a2bb244f2f3adb8d75cab5aa2dcb129d70712) ) |
3757 | 3679 | ROM_LOAD32_WORD( "mainprg.2f", 0x000002, 0x80000, CRC(931fc7ee) SHA1(54eb12abfa3f332ce9b43a45ec424aaee88641a6) ) |
r249094 | r249095 | |
3759 | 3681 | ROM_REGION(0x10000, "audiocpu", 0 ) /* Sound CPU */ |
3760 | 3682 | ROM_LOAD( "sndprg.17l", 0x00000, 0x10000, CRC(18939e92) SHA1(50b37a78d9d2259d4b140dd17393c4e5ca92bca5) ) |
3761 | 3683 | |
| 3684 | |
3762 | 3685 | ROM_REGION( 0x200000, "gfx1", 0 ) |
3763 | 3686 | ROM_LOAD( "mbh-00.8c", 0x000000, 0x200000, CRC(a877f8a3) SHA1(79253525f360a73161894f31e211e4d6b38d307a) ) /* Encrypted tiles */ |
3764 | 3687 | |
r249094 | r249095 | |
3785 | 3708 | |
3786 | 3709 | ROM_REGION(0x200, "prom", 0 ) |
3787 | 3710 | ROM_LOAD( "ln-00.j7", 0x000000, 0x200, CRC(5e83eaf3) SHA1(95f5eb8e56dff6c2dce7c39a6dd458bfc38fe1cf) ) |
3788 | | |
3789 | | ROM_REGION( 0x0600, "plds", 0 ) |
3790 | | ROM_LOAD( "vm-00.3d", 0x0000, 0x0117, NO_DUMP ) /* 16L8ACN is read protected */ |
3791 | | ROM_LOAD( "vm-01.4d", 0x0200, 0x0117, NO_DUMP ) /* 16L8ACN is read protected */ |
3792 | | ROM_LOAD( "vm-02.8j", 0x0400, 0x0117, CRC(53692426) SHA1(b8f8cf6b1f6b637fcd1fcd62474e637f5d4a6901) ) |
3793 | 3711 | ROM_END |
3794 | 3712 | |
3795 | | ROM_START( nslasherj ) /* DE-0397-0 PCB */ |
| 3713 | ROM_START( nslasherj ) |
3796 | 3714 | ROM_REGION(0x100000, "maincpu", 0 ) /* Encrypted ARM 32 bit code */ |
3797 | 3715 | ROM_LOAD32_WORD( "lx-00.1f", 0x000000, 0x80000, CRC(6ed5fb88) SHA1(84350da7939a479968a523c84e254e3ee54b8da2) ) |
3798 | 3716 | ROM_LOAD32_WORD( "lx-01.2f", 0x000002, 0x80000, CRC(a6df2152) SHA1(6fe7e0b2e71c5f807951dcc81a6a3cff55247961) ) |
r249094 | r249095 | |
3826 | 3744 | |
3827 | 3745 | ROM_REGION(0x200, "prom", 0 ) |
3828 | 3746 | ROM_LOAD( "ln-00.j7", 0x000000, 0x200, CRC(5e83eaf3) SHA1(95f5eb8e56dff6c2dce7c39a6dd458bfc38fe1cf) ) |
3829 | | |
3830 | | ROM_REGION( 0x0600, "plds", 0 ) |
3831 | | ROM_LOAD( "vm-00.3d", 0x0000, 0x0117, NO_DUMP ) /* 16L8ACN is read protected */ |
3832 | | ROM_LOAD( "vm-01.4d", 0x0200, 0x0117, NO_DUMP ) /* 16L8ACN is read protected */ |
3833 | | ROM_LOAD( "vm-02.8j", 0x0400, 0x0117, CRC(53692426) SHA1(b8f8cf6b1f6b637fcd1fcd62474e637f5d4a6901) ) |
3834 | 3747 | ROM_END |
3835 | 3748 | |
3836 | | ROM_START( nslashers ) /* DE-0397-0 PCB */ |
| 3749 | ROM_START( nslashers ) |
3837 | 3750 | ROM_REGION(0x100000, "maincpu", 0 ) /* Encrypted ARM 32 bit code */ |
3838 | 3751 | ROM_LOAD32_WORD( "ly-00.1f", 0x000000, 0x80000, CRC(fa0646f9) SHA1(7f9633bda230a0ced59171cdc5ab40a6d56c3d34) ) |
3839 | 3752 | ROM_LOAD32_WORD( "ly-01.2f", 0x000002, 0x80000, CRC(ae508149) SHA1(3592949e5fb2770adb9c9daa4e38c4e75f3e2554) ) |
r249094 | r249095 | |
3867 | 3780 | |
3868 | 3781 | ROM_REGION(0x200, "prom", 0 ) |
3869 | 3782 | ROM_LOAD( "ln-00.j7", 0x000000, 0x200, CRC(5e83eaf3) SHA1(95f5eb8e56dff6c2dce7c39a6dd458bfc38fe1cf) ) |
3870 | | |
3871 | | ROM_REGION( 0x0600, "plds", 0 ) |
3872 | | ROM_LOAD( "vm-00.3d", 0x0000, 0x0117, NO_DUMP ) /* 16L8ACN is read protected */ |
3873 | | ROM_LOAD( "vm-01.4d", 0x0200, 0x0117, NO_DUMP ) /* 16L8ACN is read protected */ |
3874 | | ROM_LOAD( "vm-02.8j", 0x0400, 0x0117, CRC(53692426) SHA1(b8f8cf6b1f6b637fcd1fcd62474e637f5d4a6901) ) |
3875 | 3783 | ROM_END |
3876 | 3784 | |
3877 | | ROM_START( nslasheru ) /* DE-0395-1 PCB */ |
| 3785 | ROM_START( nslasheru ) |
3878 | 3786 | ROM_REGION(0x100000, "maincpu", 0 ) /* Encrypted ARM 32 bit code */ |
3879 | 3787 | ROM_LOAD32_WORD( "00.f1", 0x000000, 0x80000, CRC(944f3329) SHA1(7e7909e203b9752de3d3d798c6f84ac6ae824a07) ) |
3880 | 3788 | ROM_LOAD32_WORD( "01.f2", 0x000002, 0x80000, CRC(ac12d18a) SHA1(7cd4e843bf575c70c5c39a8afa78b803106f59b0) ) |
r249094 | r249095 | |
3908 | 3816 | |
3909 | 3817 | ROM_REGION(0x200, "prom", 0 ) |
3910 | 3818 | ROM_LOAD( "ln-00.j7", 0x000000, 0x200, CRC(5e83eaf3) SHA1(95f5eb8e56dff6c2dce7c39a6dd458bfc38fe1cf) ) |
3911 | | |
3912 | | ROM_REGION( 0x0600, "plds", 0 ) |
3913 | | ROM_LOAD( "ve-00.3d", 0x0000, 0x0117, CRC(384d316c) SHA1(61b50c695d4210c199cf6f7bbe50c8a5ecd1d21c) ) |
3914 | | ROM_LOAD( "ve-01a.4d", 0x0200, 0x0117, CRC(109613c8) SHA1(5991e010c1bc2a827c8ee2c85a9b40e00a3167b3) ) |
3915 | | ROM_LOAD( "vm-02.8j", 0x0400, 0x0117, CRC(53692426) SHA1(b8f8cf6b1f6b637fcd1fcd62474e637f5d4a6901) ) |
3916 | 3819 | ROM_END |
3917 | 3820 | |
3918 | 3821 | DRIVER_INIT_MEMBER(deco32_state,captaven) |
r249094 | r249095 | |
4075 | 3978 | GAME( 1991, captavenua, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (US Rev 1.4)", MACHINE_SUPPORTS_SAVE ) |
4076 | 3979 | GAME( 1991, captavenj, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (Japan Rev 0.2)", MACHINE_SUPPORTS_SAVE ) |
4077 | 3980 | |
4078 | | // DE-0396-0 PCB sets (Z80 for sound) |
| 3981 | // DE-0396-0 PCB sets (uses a Z80) |
4079 | 3982 | GAME( 1993, fghthistu, fghthist, fghthistz,fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (US ver 42-09, DE-0396-0 PCB)", MACHINE_SUPPORTS_SAVE ) |
4080 | | // DE-0395-1 PCB sets (HuC6280 for sound) |
| 3983 | // DE-0395-1 PCB sets |
4081 | 3984 | GAME( 1993, fghthistua, fghthist, fghthsta, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (US ver 42-06, DE-0395-1 PCB)", MACHINE_SUPPORTS_SAVE ) |
4082 | 3985 | GAME( 1993, fghthistub, fghthist, fghthsta, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (US ver 42-05, DE-0395-1 PCB)", MACHINE_SUPPORTS_SAVE ) |
4083 | 3986 | GAME( 1993, fghthistj, fghthist, fghthsta, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (Japan ver 41-07, DE-0395-1 PCB)", MACHINE_SUPPORTS_SAVE ) |
4084 | | // DE-0380-2 PCB sets (HuC6280 for sound) |
| 3987 | // DE-0380-2 PCB sets |
4085 | 3988 | GAME( 1993, fghthist, 0, fghthist, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (World ver 43-07, DE-0380-2 PCB)", MACHINE_SUPPORTS_SAVE ) |
4086 | 3989 | GAME( 1993, fghthista, fghthist, fghthist, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (World ver 43-05, DE-0380-2 PCB)", MACHINE_SUPPORTS_SAVE ) |
4087 | 3990 | GAME( 1993, fghthistuc, fghthist, fghthist, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (US ver 42-03, DE-0380-2 PCB)", MACHINE_SUPPORTS_SAVE ) |
4088 | 3991 | GAME( 1993, fghthistja, fghthist, fghthist, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (Japan ver 41-05, DE-0380-2 PCB)", MACHINE_SUPPORTS_SAVE ) |
4089 | | // DE-0380-1 PCB sets (HuC6280 for sound) |
| 3992 | // DE-0380-1 PCB sets |
4090 | 3993 | GAME( 1993, fghthistjb, fghthist, fghthist, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (Japan ver 41-04, DE-0380-1 PCB)", MACHINE_SUPPORTS_SAVE ) |
4091 | 3994 | |
4092 | | // DE-0397-0 PCB sets (Z80 for sound) |
4093 | | GAME( 1994, nslasher, 0, nslasher, nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (Korea Rev 1.3, DE-0397-0 PCB)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) |
4094 | | GAME( 1994, nslasherj, nslasher, nslasher, nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (Japan Rev 1.2, DE-0397-0 PCB)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) |
4095 | | GAME( 1994, nslashers, nslasher, nslasher, nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (Over Sea Rev 1.2, DE-0397-0 PCB)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) |
4096 | | // DE-0395-1 PCB sets (HuC6280 for sound) |
4097 | | GAME( 1994, nslasheru, nslasher, nslasheru,nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (US Rev 1.2, DE-0395-1 PCB)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) |
| 3995 | GAME( 1994, nslasher, 0, nslasher, nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (Korea Rev 1.3)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) |
| 3996 | GAME( 1994, nslasherj, nslasher, nslasher, nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (Japan Rev 1.2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) |
| 3997 | GAME( 1994, nslashers, nslasher, nslasher, nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (Over Sea Rev 1.2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) |
| 3998 | GAME( 1994, nslasheru, nslasher, nslasheru,nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (US Rev 1.2, HuC6280 Sound CPU)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) |
4098 | 3999 | |
4099 | 4000 | GAME( 1994, tattass, 0, tattass, tattass, deco32_state, tattass, ROT0, "Data East Pinball", "Tattoo Assassins (US prototype)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) |
4100 | 4001 | GAME( 1994, tattassa, tattass, tattass, tattass, deco32_state, tattass, ROT0, "Data East Pinball", "Tattoo Assassins (Asia prototype)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) |
trunk/src/mame/drivers/model2.c
r249094 | r249095 | |
5985 | 5985 | |
5986 | 5986 | |
5987 | 5987 | // Model 2 (TGPs, Model 1 sound board) |
5988 | | GAME( 1993, daytona, 0, model2o, daytona, driver_device, 0, ROT0, "Sega", "Daytona USA (Japan, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
5989 | | GAME( 1993, daytonase, daytona, model2o, daytona, driver_device, 0, ROT0, "Sega", "Daytona USA Special Edition (Japan, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
5990 | | GAME( 1993, daytona93, daytona, model2o, daytona, driver_device, 0, ROT0, "Sega", "Daytona USA Deluxe '93", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
5991 | | GAME( 1993, daytonas, daytona, model2o, daytona, driver_device, 0, ROT0, "Sega", "Daytona USA (With Saturn Adverts)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
5992 | | GAME( 1993, daytonat, daytona, model2o, daytona, driver_device, 0, ROT0, "Sega", "Daytona USA (Japan, Turbo hack, set 1)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
5993 | | GAME( 1993, daytonata, daytona, model2o, daytona, driver_device, 0, ROT0, "Sega", "Daytona USA (Japan, Turbo hack, set 2)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
5994 | | GAME( 1993, daytonam, daytona, model2o, daytona, model2_state, daytonam, ROT0, "Sega", "Daytona USA (Japan, To The MAXX)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
5995 | | GAME( 1994, desert, 0, model2o, desert, driver_device, 0, ROT0, "Sega / Martin Marietta", "Desert Tank", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
5996 | | GAME( 1994, vcop, 0, model2o, vcop, driver_device, 0, ROT0, "Sega", "Virtua Cop (Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
5997 | | GAME( 1994, vcopa, vcop, model2o, vcop, driver_device, 0, ROT0, "Sega", "Virtua Cop (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 5988 | GAME( 1993, daytona, 0, model2o, daytona, driver_device, 0, ROT0, "Sega", "Daytona USA (Japan, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 5989 | GAME( 1993, daytonase, daytona, model2o, daytona, driver_device, 0, ROT0, "Sega", "Daytona USA Special Edition (Japan, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 5990 | GAME( 1993, daytona93, daytona, model2o, daytona, driver_device, 0, ROT0, "Sega", "Daytona USA Deluxe '93", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 5991 | GAME( 1993, daytonas, daytona, model2o, daytona, driver_device, 0, ROT0, "Sega", "Daytona USA (With Saturn Adverts)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 5992 | GAME( 1993, daytonat, daytona, model2o, daytona, driver_device, 0, ROT0, "Sega", "Daytona USA (Japan, Turbo hack, set 1)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 5993 | GAME( 1993, daytonata, daytona, model2o, daytona, driver_device, 0, ROT0, "Sega", "Daytona USA (Japan, Turbo hack, set 2)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 5994 | GAME( 1993, daytonam, daytona, model2o, daytona, model2_state, daytonam,ROT0, "Sega", "Daytona USA (Japan, To The MAXX)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 5995 | GAME( 1994, desert, 0, model2o, desert, driver_device, 0, ROT0, "Sega / Martin Marietta", "Desert Tank", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 5996 | GAME( 1994, vcop, 0, model2o, vcop, driver_device, 0, ROT0, "Sega", "Virtua Cop (Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 5997 | GAME( 1994, vcopa, vcop, model2o, vcop, driver_device, 0, ROT0, "Sega", "Virtua Cop (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
5998 | 5998 | |
5999 | 5999 | // Model 2A-CRX (TGPs, SCSP sound board) |
6000 | | GAME( 1995, manxtt, 0, manxttdx, manxtt, driver_device, 0, ROT0, "Sega", "Manx TT Superbike - DX (Revision D)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6001 | | GAME( 1995, manxttc, 0, model2a, manxtt, driver_device, 0, ROT0, "Sega", "Manx TT Superbike - Twin (Revision C)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6002 | | GAME( 1995, srallyc, 0, srallyc, srallyc, model2_state, srallyc, ROT0, "Sega", "Sega Rally Championship - TWIN (Revision C)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6003 | | GAME( 1995, srallycb, srallyc, srallyc, srallyc, model2_state, srallyc, ROT0, "Sega", "Sega Rally Championship - TWIN (Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6004 | | GAME( 1995, srallyca, srallyc, srallyc, srallyc, model2_state, srallyc, ROT0, "Sega", "Sega Rally Championship - DX (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6005 | | GAME( 1995, vf2, 0, model2a, model2, driver_device, 0, ROT0, "Sega", "Virtua Fighter 2 (Version 2.1)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6006 | | GAME( 1995, vf2b, vf2, model2a, model2, driver_device, 0, ROT0, "Sega", "Virtua Fighter 2 (Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6007 | | GAME( 1995, vf2a, vf2, model2a, model2, driver_device, 0, ROT0, "Sega", "Virtua Fighter 2 (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6008 | | GAME( 1995, vf2o, vf2, model2a, model2, driver_device, 0, ROT0, "Sega", "Virtua Fighter 2", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6009 | | GAME( 1995, vcop2, 0, model2a, vcop2, driver_device, 0, ROT0, "Sega", "Virtua Cop 2", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6010 | | GAME( 1995, skytargt, 0, model2a, skytargt, driver_device, 0, ROT0, "Sega", "Sky Target", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6011 | | GAME( 1996, doaa, doa, model2a_0229, model2, model2_state, doa, ROT0, "Sega", "Dead or Alive (Model 2A, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6012 | | GAME( 1997, zeroguna, zerogun, model2a_5881, model2, model2_state, zerogun, ROT0, "Psikyo", "Zero Gunner (Export, Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6013 | | GAME( 1997, zerogunaj, zerogun, model2a_5881, model2, model2_state, zerogun, ROT0, "Psikyo", "Zero Gunner (Japan, Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6014 | | GAME( 1997, motoraid, 0, model2a, manxtt, driver_device, 0, ROT0, "Sega", "Motor Raid - Twin", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6015 | | GAME( 1998, dynamcop, 0, model2a_5881, model2, model2_state, genprot, ROT0, "Sega", "Dynamite Cop (Export, Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6016 | | GAME( 1998, dyndeka2, dynamcop, model2a_5881, model2, model2_state, genprot, ROT0, "Sega", "Dynamite Deka 2 (Japan, Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6017 | | GAME( 1998, pltkidsa, pltkids, model2a_5881, model2, model2_state, pltkids, ROT0, "Psikyo", "Pilot Kids (Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6000 | GAME( 1995, manxtt, 0, manxttdx ,manxtt, driver_device, 0, ROT0, "Sega", "Manx TT Superbike - DX (Revision D)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6001 | GAME( 1995, manxttc, 0, model2a, manxtt, driver_device, 0, ROT0, "Sega", "Manx TT Superbike - Twin (Revision C)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6002 | GAME( 1995, srallyc, 0, srallyc, srallyc, model2_state, srallyc, ROT0, "Sega", "Sega Rally Championship - TWIN (Revision C)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6003 | GAME( 1995, srallycb, srallyc, srallyc, srallyc, model2_state, srallyc, ROT0, "Sega", "Sega Rally Championship - TWIN (Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6004 | GAME( 1995, srallyca, srallyc, srallyc, srallyc, model2_state, srallyc, ROT0, "Sega", "Sega Rally Championship - DX (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6005 | GAME( 1995, vf2, 0, model2a, model2, driver_device, 0, ROT0, "Sega", "Virtua Fighter 2 (Version 2.1)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6006 | GAME( 1995, vf2b, vf2, model2a, model2, driver_device, 0, ROT0, "Sega", "Virtua Fighter 2 (Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6007 | GAME( 1995, vf2a, vf2, model2a, model2, driver_device, 0, ROT0, "Sega", "Virtua Fighter 2 (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6008 | GAME( 1995, vf2o, vf2, model2a, model2, driver_device, 0, ROT0, "Sega", "Virtua Fighter 2", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6009 | GAME( 1995, vcop2, 0, model2a, vcop2, driver_device, 0, ROT0, "Sega", "Virtua Cop 2", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6010 | GAME( 1995, skytargt, 0, model2a, skytargt,driver_device, 0, ROT0, "Sega", "Sky Target", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6011 | GAME( 1996, doaa, doa, model2a_0229, model2, model2_state, doa, ROT0, "Sega", "Dead or Alive (Model 2A, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6012 | GAME( 1997, zeroguna, zerogun, model2a_5881, model2, model2_state, zerogun, ROT0, "Psikyo", "Zero Gunner (Export, Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6013 | GAME( 1997, zerogunaj, zerogun, model2a_5881, model2, model2_state, zerogun, ROT0, "Psikyo", "Zero Gunner (Japan, Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6014 | GAME( 1997, motoraid, 0, model2a, manxtt, driver_device, 0, ROT0, "Sega", "Motor Raid - Twin", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6015 | GAME( 1998, dynamcop, 0, model2a_5881, model2, model2_state, genprot, ROT0, "Sega", "Dynamite Cop (Export, Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6016 | GAME( 1998, dyndeka2, dynamcop, model2a_5881, model2, model2_state, genprot, ROT0, "Sega", "Dynamite Deka 2 (Japan, Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
| 6017 | GAME( 1998, pltkidsa, pltkids, model2a_5881, model2, model2_state, pltkids, ROT0, "Psikyo", "Pilot Kids (Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
6018 | 6018 | |
6019 | 6019 | // Model 2B-CRX (SHARC, SCSP sound board) |
6020 | 6020 | GAME( 1994, vstriker, 0, model2b, model2, driver_device, 0, ROT0, "Sega", "Virtua Striker (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) |
trunk/src/mame/drivers/namcos23.c
r249094 | r249095 | |
1234 | 1234 | |
1235 | 1235 | #include "emu.h" |
1236 | 1236 | #include <float.h> |
1237 | | #include "video/poly.h" |
| 1237 | #include "video/polylgcy.h" |
1238 | 1238 | #include "cpu/mips/mips3.h" |
1239 | 1239 | #include "cpu/h8/h83002.h" |
1240 | 1240 | #include "cpu/h8/h83337.h" |
r249094 | r249095 | |
1247 | 1247 | #define JVSCLOCK (XTAL_14_7456MHz) |
1248 | 1248 | #define H8CLOCK (16737350) /* from 2061 */ |
1249 | 1249 | #define BUSCLOCK (16737350*2) /* 33MHz CPU bus clock / input */ |
1250 | | #define C352CLOCK (25992000) /* measured at 25.992MHz from 2061 pin 9 */ |
1251 | | #define C352DIV (296) |
| 1250 | #define C352CLOCK (25992000) /* measured at 25.992MHz from 2061 pin 9 (System 12 uses a divider of 332) */ |
1252 | 1251 | #define VSYNC1 (59.8824) |
1253 | 1252 | #define VSYNC2 (59.915) |
1254 | 1253 | #define HSYNC (16666150) |
r249094 | r249095 | |
1264 | 1263 | |
1265 | 1264 | enum { MODEL, FLUSH }; |
1266 | 1265 | |
1267 | | enum { RENDER_MAX_ENTRIES = 1000, POLY_MAX_ENTRIES = 10000 }; |
1268 | | |
1269 | 1266 | struct namcos23_render_entry |
1270 | 1267 | { |
1271 | 1268 | int type; |
r249094 | r249095 | |
1289 | 1286 | UINT32 (*texture_lookup)(running_machine &machine, const pen_t *pens, float x, float y); |
1290 | 1287 | }; |
1291 | 1288 | |
1292 | | class namcos23_state; |
1293 | | |
1294 | | class namcos23_renderer : public poly_manager<float, namcos23_render_data, 4, POLY_MAX_ENTRIES> |
1295 | | { |
1296 | | public: |
1297 | | namcos23_renderer(namcos23_state &state); |
1298 | | |
1299 | | void render_flush(bitmap_rgb32& bitmap); |
1300 | | void render_scanline(INT32 scanline, const extent_t& extent, const namcos23_render_data& object, int threadid); |
1301 | | |
1302 | | private: |
1303 | | namcos23_state& m_state; |
1304 | | bitmap_rgb32 m_bitmap; |
1305 | | }; |
1306 | | |
1307 | | typedef namcos23_renderer::vertex_t poly_vertex; |
1308 | | |
1309 | 1289 | struct namcos23_poly_entry |
1310 | 1290 | { |
1311 | 1291 | namcos23_render_data rd; |
r249094 | r249095 | |
1315 | 1295 | poly_vertex pv[16]; |
1316 | 1296 | }; |
1317 | 1297 | |
| 1298 | enum { RENDER_MAX_ENTRIES = 1000, POLY_MAX_ENTRIES = 10000 }; |
1318 | 1299 | |
| 1300 | |
1319 | 1301 | struct c417_t |
1320 | 1302 | { |
1321 | 1303 | UINT16 ram[0x10000]; |
r249094 | r249095 | |
1361 | 1343 | |
1362 | 1344 | struct render_t |
1363 | 1345 | { |
1364 | | namcos23_renderer *polymgr; |
| 1346 | legacy_poly_manager *polymgr; |
1365 | 1347 | int cur; |
1366 | 1348 | int poly_count; |
1367 | 1349 | int count[2]; |
r249094 | r249095 | |
1557 | 1539 | void render_apply_matrot(INT32 xi, INT32 yi, INT32 zi, const namcos23_render_entry *re, INT32 &x, INT32 &y, INT32 &z); |
1558 | 1540 | void render_project(poly_vertex &pv); |
1559 | 1541 | void render_one_model(const namcos23_render_entry *re); |
| 1542 | void render_flush(bitmap_rgb32 &bitmap); |
1560 | 1543 | void render_run(bitmap_rgb32 &bitmap); |
1561 | 1544 | }; |
1562 | 1545 | |
r249094 | r249095 | |
1583 | 1566 | |
1584 | 1567 | ***************************************************************************/ |
1585 | 1568 | |
1586 | | namcos23_renderer::namcos23_renderer(namcos23_state &state) |
1587 | | : poly_manager<float, namcos23_render_data, 4, POLY_MAX_ENTRIES>(state.machine()), |
1588 | | m_state(state), |
1589 | | m_bitmap(state.m_screen->width(), state.m_screen->height()) |
1590 | | {} |
1591 | | |
1592 | 1569 | // 3D hardware, to throw at least in part in video/namcos23.c |
1593 | 1570 | |
1594 | 1571 | inline INT32 namcos23_state::u32_to_s24(UINT32 v) |
r249094 | r249095 | |
1879 | 1856 | |
1880 | 1857 | |
1881 | 1858 | |
1882 | | void namcos23_renderer::render_scanline(INT32 scanline, const extent_t& extent, const namcos23_render_data& object, int threadid) |
| 1859 | static void render_scanline(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid) |
1883 | 1860 | { |
1884 | | const namcos23_render_data& rd = object; |
| 1861 | const namcos23_render_data *rd = (const namcos23_render_data *)extradata; |
1885 | 1862 | |
1886 | | float w = extent.param[0].start; |
1887 | | float u = extent.param[1].start; |
1888 | | float v = extent.param[2].start; |
1889 | | float l = extent.param[3].start; |
1890 | | float dw = extent.param[0].dpdx; |
1891 | | float du = extent.param[1].dpdx; |
1892 | | float dv = extent.param[2].dpdx; |
1893 | | float dl = extent.param[3].dpdx; |
1894 | | UINT32 *img = &m_bitmap.pix32(scanline, extent.startx); |
| 1863 | float w = extent->param[0].start; |
| 1864 | float u = extent->param[1].start; |
| 1865 | float v = extent->param[2].start; |
| 1866 | float l = extent->param[3].start; |
| 1867 | float dw = extent->param[0].dpdx; |
| 1868 | float du = extent->param[1].dpdx; |
| 1869 | float dv = extent->param[2].dpdx; |
| 1870 | float dl = extent->param[3].dpdx; |
| 1871 | bitmap_rgb32 *bitmap = (bitmap_rgb32 *)dest; |
| 1872 | UINT32 *img = &bitmap->pix32(scanline, extent->startx); |
1895 | 1873 | |
1896 | | for(int x = extent.startx; x < extent.stopx; x++) { |
| 1874 | for(int x = extent->startx; x < extent->stopx; x++) { |
1897 | 1875 | float z = w ? 1/w : 0; |
1898 | | UINT32 pcol = rd.texture_lookup(*rd.machine, rd.pens, u*z, v*z); |
| 1876 | UINT32 pcol = rd->texture_lookup(*rd->machine, rd->pens, u*z, v*z); |
1899 | 1877 | float ll = l*z; |
1900 | 1878 | *img = (light(pcol >> 16, ll) << 16) | (light(pcol >> 8, ll) << 8) | light(pcol, ll); |
1901 | 1879 | |
r249094 | r249095 | |
2034 | 2012 | |
2035 | 2013 | namcos23_poly_entry *p = render.polys + render.poly_count; |
2036 | 2014 | |
2037 | | p->vertex_count = render.polymgr->zclip_if_less(ne, pv, p->pv, 4, 0.001f); |
| 2015 | p->vertex_count = poly_zclip_if_less(ne, pv, p->pv, 4, 0.001f); |
2038 | 2016 | |
2039 | 2017 | if(p->vertex_count >= 3) { |
2040 | 2018 | for(int i=0; i<p->vertex_count; i++) { |
r249094 | r249095 | |
2068 | 2046 | return p1->zkey < p2->zkey ? 1 : p1->zkey > p2->zkey ? -1 : 0; |
2069 | 2047 | } |
2070 | 2048 | |
2071 | | void namcos23_renderer::render_flush(bitmap_rgb32& bitmap) |
| 2049 | void namcos23_state::render_flush(bitmap_rgb32 &bitmap) |
2072 | 2050 | { |
2073 | | render_t &render = m_state.m_render; |
| 2051 | render_t &render = m_render; |
2074 | 2052 | |
2075 | 2053 | if(!render.poly_count) |
2076 | 2054 | return; |
r249094 | r249095 | |
2084 | 2062 | |
2085 | 2063 | for(int i=0; i<render.poly_count; i++) { |
2086 | 2064 | const namcos23_poly_entry *p = render.poly_order[i]; |
2087 | | namcos23_render_data& extra = render.polymgr->object_data_alloc(); |
2088 | | extra = p->rd; |
2089 | | |
2090 | | if (p->vertex_count == 3) |
2091 | | render_triangle(scissor, render_delegate(FUNC(namcos23_renderer::render_scanline), this), 4, p->pv[0], p->pv[1], p->pv[2]); |
2092 | | else if (p->vertex_count == 4) |
2093 | | render_polygon<4>(scissor, render_delegate(FUNC(namcos23_renderer::render_scanline), this), 4, p->pv); |
2094 | | else if (p->vertex_count == 5) |
2095 | | render_polygon<5>(scissor, render_delegate(FUNC(namcos23_renderer::render_scanline), this), 4, p->pv); |
| 2065 | namcos23_render_data *rd = (namcos23_render_data *)poly_get_extra_data(render.polymgr); |
| 2066 | *rd = p->rd; |
| 2067 | poly_render_triangle_fan(render.polymgr, &bitmap, scissor, render_scanline, 4, p->vertex_count, p->pv); |
2096 | 2068 | } |
2097 | 2069 | render.poly_count = 0; |
2098 | | |
2099 | | copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, scissor); |
2100 | 2070 | } |
2101 | 2071 | |
2102 | 2072 | void namcos23_state::render_run(bitmap_rgb32 &bitmap) |
r249094 | r249095 | |
2111 | 2081 | render_one_model(re); |
2112 | 2082 | break; |
2113 | 2083 | case FLUSH: |
2114 | | render.polymgr->render_flush(bitmap); |
| 2084 | render_flush(bitmap); |
2115 | 2085 | break; |
2116 | 2086 | } |
2117 | 2087 | re++; |
2118 | 2088 | } |
2119 | | render.polymgr->render_flush(bitmap); |
2120 | | render.polymgr->wait(); |
| 2089 | render_flush(bitmap); |
| 2090 | |
| 2091 | poly_wait(render.polymgr, "render_run"); |
2121 | 2092 | } |
2122 | 2093 | |
2123 | 2094 | |
r249094 | r249095 | |
2189 | 2160 | m_bgtilemap = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(namcos23_state::TextTilemapGetInfo),this), TILEMAP_SCAN_ROWS, 16, 16, 64, 64); |
2190 | 2161 | m_bgtilemap->set_transparent_pen(0xf); |
2191 | 2162 | m_bgtilemap->set_scrolldx(860, 860); |
2192 | | m_render.polymgr = auto_alloc(machine(), namcos23_renderer(*this)); |
| 2163 | m_render.polymgr = poly_alloc(machine(), 10000, sizeof(namcos23_render_data), 0); |
2193 | 2164 | } |
2194 | 2165 | |
2195 | 2166 | |
r249094 | r249095 | |
3349 | 3320 | /* sound hardware */ |
3350 | 3321 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
3351 | 3322 | |
3352 | | MCFG_C352_ADD("c352", C352CLOCK, C352DIV) |
| 3323 | MCFG_C352_ADD("c352", C352CLOCK, C352_DIVIDER_332) |
3353 | 3324 | MCFG_SOUND_ROUTE(0, "rspeaker", 1.00) |
3354 | 3325 | MCFG_SOUND_ROUTE(1, "lspeaker", 1.00) |
3355 | 3326 | MCFG_SOUND_ROUTE(2, "rspeaker", 1.00) |
r249094 | r249095 | |
3418 | 3389 | /* sound hardware */ |
3419 | 3390 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
3420 | 3391 | |
3421 | | MCFG_C352_ADD("c352", C352CLOCK, C352DIV) |
| 3392 | MCFG_C352_ADD("c352", C352CLOCK, C352_DIVIDER_332) |
3422 | 3393 | MCFG_SOUND_ROUTE(0, "rspeaker", 1.00) |
3423 | 3394 | MCFG_SOUND_ROUTE(1, "lspeaker", 1.00) |
3424 | 3395 | MCFG_SOUND_ROUTE(2, "rspeaker", 1.00) |
r249094 | r249095 | |
3498 | 3469 | /* sound hardware */ |
3499 | 3470 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
3500 | 3471 | |
3501 | | MCFG_C352_ADD("c352", C352CLOCK, C352DIV) |
| 3472 | MCFG_C352_ADD("c352", C352CLOCK, C352_DIVIDER_332) |
3502 | 3473 | MCFG_SOUND_ROUTE(0, "rspeaker", 1.00) |
3503 | 3474 | MCFG_SOUND_ROUTE(1, "lspeaker", 1.00) |
3504 | 3475 | MCFG_SOUND_ROUTE(2, "rspeaker", 1.00) |
trunk/src/mame/video/chihiro.c
r249094 | r249095 | |
3 | 3 | #include "emu.h" |
4 | 4 | #include "video/poly.h" |
5 | 5 | #include "bitmap.h" |
6 | | #include "machine/pic8259.h" |
7 | 6 | #include "includes/chihiro.h" |
8 | 7 | |
9 | 8 | //#define LOG_NV2A |
r249094 | r249095 | |
946 | 945 | UINT32 nv2a_renderer::geforce_object_offset(UINT32 handle) |
947 | 946 | { |
948 | 947 | UINT32 h = ((((handle >> 11) ^ handle) >> 11) ^ handle) & 0x7ff; |
949 | | UINT32 o = (pfifo[0x210 / 4] & 0x1ff) << 8; // 0x1ff is not certain |
| 948 | UINT32 o = (pfifo[0x210 / 4] & 0x1f) << 8; // or 12 ? |
950 | 949 | UINT32 e = o + h * 8; // at 0xfd000000+0x00700000 |
951 | 950 | UINT32 w; |
952 | 951 | |
953 | | if (ramin[e / 4] != handle) { |
954 | | // this should never happen |
955 | | for (UINT32 aa = o / 4; aa < (sizeof(ramin) / 4); aa = aa + 2) { |
956 | | if (ramin[aa] == handle) { |
957 | | e = aa * 4; |
958 | | } |
959 | | } |
960 | | } |
| 952 | if (ramin[e / 4] != handle) |
| 953 | e = 0; |
961 | 954 | w = ramin[e / 4 + 1]; |
962 | | return (w & 0xffff) * 0x10; // 0xffff is not certain |
| 955 | return (w & 0xffff) * 0x10; |
963 | 956 | } |
964 | 957 | |
965 | 958 | void nv2a_renderer::geforce_read_dma_object(UINT32 handle, UINT32 &offset, UINT32 &size) |
r249094 | r249095 | |
1253 | 1246 | addr = rendertarget + (dilated0[dilate_rendertarget][x] + dilated1[dilate_rendertarget][y]); |
1254 | 1247 | else // type_rendertarget == LINEAR*/ |
1255 | 1248 | addr = rendertarget + (pitch_rendertarget / 4)*y + x; |
1256 | | fbcolor = 0; |
1257 | | if (color_mask != 0) |
1258 | | fbcolor = *addr; |
| 1249 | fbcolor = *addr; |
1259 | 1250 | daddr=depthbuffer + (pitch_depthbuffer / 4)*y + x; |
1260 | 1251 | deptsten = *daddr; |
1261 | 1252 | c[3] = color >> 24; |
r249094 | r249095 | |
1781 | 1772 | break; |
1782 | 1773 | } |
1783 | 1774 | } |
1784 | | if (color_mask != 0) { |
1785 | | UINT32 fbcolor_tmp; |
1786 | | |
1787 | | fbcolor_tmp = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0]; |
1788 | | *addr = (fbcolor & ~color_mask) | (fbcolor_tmp & color_mask); |
1789 | | } |
| 1775 | fbcolor = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0]; |
| 1776 | *addr = fbcolor; |
1790 | 1777 | if (depth_write_enabled) |
1791 | 1778 | dep = depth; |
1792 | 1779 | deptsten = (dep << 8) | sten; |
r249094 | r249095 | |
2246 | 2233 | maddress = method * 4; |
2247 | 2234 | data = space.read_dword(address); |
2248 | 2235 | channel[chanel][subchannel].object.method[method] = data; |
2249 | | #ifdef LOG_NV2A |
2250 | | printf("A:%08X MTHD:%08X D:%08X\n\r",address,maddress,data); |
2251 | | #endif |
2252 | 2236 | if (maddress == 0x17fc) { |
2253 | 2237 | indexesleft_count = 0; |
2254 | 2238 | indexesleft_first = 0; |
r249094 | r249095 | |
2286 | 2270 | } |
2287 | 2271 | wait(); |
2288 | 2272 | } |
2289 | | else if (type == nv2a_renderer::TRIANGLE_FAN) { |
2290 | | vertex_nv vert[3]; |
2291 | | vertex_t xy[3]; |
2292 | | |
2293 | | read_vertices_0x1810(space, vert, offset, 2); |
2294 | | convert_vertices_poly(vert, xy, 2); |
2295 | | count = count - 2; |
2296 | | offset = offset + 2; |
2297 | | for (n = 0; n <= count; n++) { |
2298 | | read_vertices_0x1810(space, vert + (((n + 1) & 1) + 1), offset + n, 1); |
2299 | | convert_vertices_poly(vert + (((n + 1) & 1) + 1), xy + (((n + 1) & 1) + 1), 1); |
2300 | | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[(~(n + 1) & 1) + 1], xy[((n + 1) & 1) + 1]); |
2301 | | } |
2302 | | wait(); |
2303 | | } |
2304 | 2273 | else if (type == nv2a_renderer::TRIANGLE_STRIP) { |
2305 | 2274 | vertex_nv vert[4]; |
2306 | 2275 | vertex_t xy[4]; |
r249094 | r249095 | |
2342 | 2311 | // each dword after 1800 contains two 16 bit index values to select the vartices |
2343 | 2312 | // each dword after 1808 contains a 32 bit index value to select the vartices |
2344 | 2313 | type = channel[chanel][subchannel].object.method[0x17fc / 4]; |
| 2314 | #ifdef LOG_NV2A |
| 2315 | printf("vertex %d %d %d\n\r", type, offset, count); |
| 2316 | #endif |
2345 | 2317 | if (type == nv2a_renderer::QUADS) { |
2346 | 2318 | while (1) { |
2347 | 2319 | vertex_nv vert[4]; |
r249094 | r249095 | |
2360 | 2332 | render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv |
2361 | 2333 | } |
2362 | 2334 | } |
2363 | | else if (type == nv2a_renderer::TRIANGLE_FAN) { |
2364 | | if ((countlen * mult + indexesleft_count) >= 3) { |
2365 | | vertex_nv vert[3]; |
2366 | | vertex_t xy[3]; |
2367 | | int c, count; |
2368 | | |
2369 | | if (mult == 1) |
2370 | | c = read_vertices_0x1808(space, vert, address, 2); |
2371 | | else |
2372 | | c = read_vertices_0x1800(space, vert, address, 2); |
2373 | | convert_vertices_poly(vert, xy, 2); |
2374 | | address = address + c * 4; |
2375 | | countlen = countlen - c; |
2376 | | count = countlen * mult + indexesleft_count; |
2377 | | for (n = 1; n <= count; n++) { |
2378 | | if (mult == 1) |
2379 | | c = read_vertices_0x1808(space, vert + ((n & 1) + 1), address, 1); |
2380 | | else |
2381 | | c = read_vertices_0x1800(space, vert + ((n & 1) + 1), address, 1); |
2382 | | |
2383 | | convert_vertices_poly(vert + ((n & 1) + 1), xy + ((n & 1) + 1), 1); |
2384 | | address = address + c * 4; |
2385 | | countlen = countlen - c; |
2386 | | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[(~n & 1) + 1], xy[(n & 1) + 1]); |
2387 | | } |
2388 | | wait(); |
2389 | | } |
2390 | | } |
2391 | 2335 | else if (type == nv2a_renderer::TRIANGLES) { |
2392 | 2336 | while (1) { |
2393 | 2337 | vertex_nv vert[3]; |
r249094 | r249095 | |
2502 | 2446 | } |
2503 | 2447 | wait(); |
2504 | 2448 | } |
2505 | | else if (type == nv2a_renderer::TRIANGLES) { |
2506 | | while (countlen > 0) { |
2507 | | vertex_nv vert[3]; |
2508 | | vertex_t xy[3]; |
2509 | | int c; |
2510 | | |
2511 | | c = read_vertices_0x1818(space, vert, address, 3); |
2512 | | convert_vertices_poly(vert, xy, 3); |
2513 | | countlen = countlen - c; |
2514 | | if (countlen < 0) { |
2515 | | logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen); |
2516 | | countlen = 0; |
2517 | | break; |
2518 | | } |
2519 | | address = address + c * 3; |
2520 | | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv |
2521 | | } |
2522 | | } |
2523 | 2449 | else if (type == nv2a_renderer::TRIANGLE_STRIP) { |
2524 | 2450 | vertex_nv vert[4]; |
2525 | 2451 | vertex_t xy[4]; |
r249094 | r249095 | |
2687 | 2613 | // clear colors |
2688 | 2614 | UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4]; |
2689 | 2615 | bm.fill(color); |
2690 | | #ifdef LOG_NV2A |
2691 | | printf("clearscreen\n\r"); |
2692 | | #endif |
| 2616 | //printf("clearscreen\n\r"); |
2693 | 2617 | } |
2694 | 2618 | if ((data & 0x03) == 3) { |
2695 | 2619 | bitmap_rgb32 bm(depthbuffer, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ? |
r249094 | r249095 | |
2725 | 2649 | dilate_rendertarget = dilatechose[(log2width_rendertarget << 4) + log2height_rendertarget]; |
2726 | 2650 | } |
2727 | 2651 | if (maddress == 0x020c) { |
| 2652 | // line size ? |
2728 | 2653 | pitch_rendertarget=data & 0xffff; |
2729 | 2654 | pitch_depthbuffer=(data >> 16) & 0xffff; |
2730 | | #ifdef LOG_NV2A |
2731 | | printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer); |
2732 | | #endif |
| 2655 | //printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer); |
2733 | 2656 | countlen--; |
2734 | 2657 | } |
2735 | 2658 | if (maddress == 0x0100) { |
2736 | | countlen--; |
2737 | | if (data != 0) { |
2738 | | pgraph[0x704 / 4] = 0x100; |
2739 | | pgraph[0x708 / 4] = data; |
2740 | | pgraph[0x100 / 4] |= 1; |
2741 | | pgraph[0x108 / 4] |= 1; |
2742 | | if (update_interrupts() == true) |
2743 | | interruptdevice->ir3_w(1); // IRQ 3 |
2744 | | else |
2745 | | interruptdevice->ir3_w(0); // IRQ 3 |
2746 | | return 2; |
| 2659 | // just temporarily |
| 2660 | if ((data & 0x1f) == 1) { |
| 2661 | data = data >> 5; |
| 2662 | data = data & 0x0ffffff0; |
| 2663 | displayedtarget = (UINT32 *)direct_access_ptr(data); |
2747 | 2664 | } |
2748 | | else |
2749 | | return 0; |
2750 | 2665 | } |
2751 | 2666 | if (maddress == 0x0130) { |
2752 | 2667 | countlen--; |
r249094 | r249095 | |
2755 | 2670 | else |
2756 | 2671 | return 0; |
2757 | 2672 | } |
2758 | | if (maddress == 0x1d8c) { |
2759 | | countlen--; |
2760 | | // it is used to specify the clear value for the depth buffer (zbuffer) |
2761 | | // but also as a parameter for interrupt routines |
2762 | | pgraph[0x1a88 / 4] = data; |
2763 | | } |
2764 | | if (maddress == 0x1d90) { |
2765 | | countlen--; |
2766 | | // it is used to specify the clear value for the color buffer |
2767 | | // but also as a parameter for interrupt routines |
2768 | | pgraph[0x186c / 4] = data; |
2769 | | } |
2770 | 2673 | if (maddress == 0x0210) { |
2771 | 2674 | // framebuffer offset ? |
2772 | 2675 | rendertarget = (UINT32 *)direct_access_ptr(data); |
2773 | | #ifdef LOG_NV2A |
2774 | | printf("Render target at %08X\n\r", data); |
2775 | | #endif |
| 2676 | //printf("Render target at %08X\n\r",data); |
2776 | 2677 | countlen--; |
2777 | 2678 | } |
2778 | 2679 | if (maddress == 0x0214) { |
2779 | 2680 | // zbuffer offset ? |
2780 | 2681 | depthbuffer = (UINT32 *)direct_access_ptr(data); |
2781 | | #ifdef LOG_NV2A |
2782 | | printf("Depth buffer at %08X\n\r",data); |
2783 | | #endif |
| 2682 | //printf("Depth buffer at %08X\n\r",data); |
2784 | 2683 | if ((data == 0) || (data > 0x7ffffffc)) |
2785 | 2684 | depth_write_enabled = false; |
2786 | 2685 | else if (channel[chanel][subchannel].object.method[0x035c / 4] != 0) |
r249094 | r249095 | |
2810 | 2709 | if (maddress == 0x0354) { |
2811 | 2710 | depth_function = data; |
2812 | 2711 | } |
2813 | | if (maddress == 0x0358) { |
2814 | | //color_mask = data; |
2815 | | if (data & 0x000000ff) |
2816 | | data |= 0x000000ff; |
2817 | | if (data & 0x0000ff00) |
2818 | | data |= 0x0000ff00; |
2819 | | if (data & 0x00ff0000) |
2820 | | data |= 0x00ff0000; |
2821 | | if (data & 0xff000000) |
2822 | | data |= 0xff000000; |
2823 | | color_mask = data; |
2824 | | } |
2825 | 2712 | if (maddress == 0x035c) { |
2826 | 2713 | UINT32 g = channel[chanel][subchannel].object.method[0x0214 / 4]; |
2827 | 2714 | depth_write_enabled = data != 0; |
r249094 | r249095 | |
3761 | 3648 | combiner.function_Aop3 = MAX(MIN((combiner.function_Aop3 + biasa) * scalea, 1.0f), -1.0f); |
3762 | 3649 | } |
3763 | 3650 | |
3764 | | void nv2a_renderer::vblank_callback(screen_device &screen, bool state) |
| 3651 | bool nv2a_renderer::vblank_callback(screen_device &screen, bool state) |
3765 | 3652 | { |
3766 | | #ifdef LOG_NV2A |
3767 | | printf("vblank_callback\n\r"); |
3768 | | #endif |
3769 | | if ((state == true) && (puller_waiting == 1)) { |
3770 | | puller_waiting = 0; |
3771 | | puller_timer_work(NULL, 0); |
3772 | | } |
3773 | | if (state == true) { |
| 3653 | //printf("vblank_callback\n\r"); |
| 3654 | if (state == true) |
3774 | 3655 | pcrtc[0x100 / 4] |= 1; |
3775 | | pcrtc[0x808 / 4] |= 0x10000; |
3776 | | } |
3777 | | else { |
3778 | | pcrtc[0x100 / 4] &= ~1; |
3779 | | pcrtc[0x808 / 4] &= ~0x10000; |
3780 | | } |
3781 | | if (update_interrupts() == true) |
3782 | | interruptdevice->ir3_w(1); // IRQ 3 |
3783 | 3656 | else |
3784 | | interruptdevice->ir3_w(0); // IRQ 3 |
3785 | | } |
3786 | | |
3787 | | bool nv2a_renderer::update_interrupts() |
3788 | | { |
| 3657 | pcrtc[0x100 / 4] &= ~1; |
3789 | 3658 | if (pcrtc[0x100 / 4] & pcrtc[0x140 / 4]) |
3790 | 3659 | pmc[0x100 / 4] |= 0x1000000; |
3791 | 3660 | else |
3792 | 3661 | pmc[0x100 / 4] &= ~0x1000000; |
3793 | | if (pgraph[0x100 / 4] & pgraph[0x140 / 4]) |
3794 | | pmc[0x100 / 4] |= 0x1000; |
3795 | | else |
3796 | | pmc[0x100 / 4] &= ~0x1000; |
3797 | | if (((pmc[0x100 / 4] & 0x7fffffff) && (pmc[0x140 / 4] & 1)) || ((pmc[0x100 / 4] & 0x80000000) && (pmc[0x140 / 4] & 2))) { |
| 3662 | if ((state == true) && (puller_waiting == 1)) { |
| 3663 | puller_waiting = 0; |
| 3664 | puller_timer_work(NULL, 0); |
| 3665 | } |
| 3666 | if ((pmc[0x100 / 4] != 0) && (pmc[0x140 / 4] != 0)) { |
3798 | 3667 | // send interrupt |
3799 | 3668 | return true; |
3800 | 3669 | } |
r249094 | r249095 | |
3823 | 3692 | int countlen; |
3824 | 3693 | int ret; |
3825 | 3694 | address_space *space = puller_space; |
3826 | | #ifdef LOG_NV2A |
3827 | | UINT32 subch; |
3828 | | #endif |
3829 | 3695 | |
3830 | 3696 | chanel = puller_channel; |
3831 | 3697 | subchannel = puller_subchannel; |
r249094 | r249095 | |
3882 | 3748 | } |
3883 | 3749 | if (ret != 0) { |
3884 | 3750 | puller_timer->enable(false); |
3885 | | puller_waiting = ret; |
| 3751 | puller_waiting = 1; |
3886 | 3752 | return; |
3887 | 3753 | } |
3888 | 3754 | } |
r249094 | r249095 | |
3981 | 3847 | //logerror("NV_2A: read PRAMIN[%06X] value %08X\n",offset*4-0x00700000,ret); |
3982 | 3848 | } |
3983 | 3849 | else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) { |
3984 | | ret = pgraph[offset - 0x00400000 / 4]; |
3985 | 3850 | //logerror("NV_2A: read PGRAPH[%06X] value %08X\n",offset*4-0x00400000,ret); |
3986 | 3851 | } |
3987 | 3852 | else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) { |
r249094 | r249095 | |
4005 | 3870 | //logerror("NV_2A: read channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,ret); |
4006 | 3871 | return ret; |
4007 | 3872 | } |
| 3873 | else |
| 3874 | { |
| 3875 | /* nothing */ |
| 3876 | } |
4008 | 3877 | //logerror("NV_2A: read at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,ret); |
4009 | 3878 | return ret; |
4010 | 3879 | } |
4011 | 3880 | |
4012 | 3881 | WRITE32_MEMBER(nv2a_renderer::geforce_w) |
4013 | 3882 | { |
4014 | | UINT32 old; |
4015 | | bool update_int; |
4016 | | |
4017 | | update_int = false; |
4018 | 3883 | if ((offset >= 0x00101000 / 4) && (offset < 0x00102000 / 4)) { |
4019 | 3884 | //logerror("NV_2A: write STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,data); |
4020 | 3885 | } |
r249094 | r249095 | |
4033 | 3898 | //logerror("NV_2A: write PRAMIN[%06X]=%08X\n",offset*4-0x00700000,data & mem_mask); |
4034 | 3899 | } |
4035 | 3900 | else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) { |
4036 | | int e = offset - 0x00400000 / 4; |
4037 | | if (e >= (sizeof(pgraph) / sizeof(UINT32))) |
4038 | | return; |
4039 | | old = pgraph[e]; |
4040 | | COMBINE_DATA(pgraph + e); |
4041 | | if (e == 0x100 / 4) { |
4042 | | pgraph[e] = old & ~data; |
4043 | | if (data & 1) |
4044 | | pgraph[0x108 / 4] = 0; |
4045 | | update_int = true; |
4046 | | } |
4047 | | if (e == 0x140 / 4) |
4048 | | update_int = true; |
4049 | | if (e == 0x720 / 4) { |
4050 | | if ((data & 1) && (puller_waiting == 2)) { |
4051 | | puller_waiting = 0; |
4052 | | puller_timer->enable(); |
4053 | | puller_timer->adjust(attotime::zero); |
4054 | | } |
4055 | | } |
4056 | | if ((e >= 0x900 / 4) && (e < 0xa00 / 4)) |
4057 | | pgraph[e] = 0; |
4058 | 3901 | //logerror("NV_2A: write PGRAPH[%06X]=%08X\n",offset*4-0x00400000,data & mem_mask); |
4059 | 3902 | } |
4060 | 3903 | else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) { |
4061 | 3904 | int e = offset - 0x00600000 / 4; |
4062 | 3905 | if (e >= (sizeof(pcrtc) / sizeof(UINT32))) |
4063 | 3906 | return; |
4064 | | old = pcrtc[e]; |
4065 | 3907 | COMBINE_DATA(pcrtc + e); |
4066 | | if (e == 0x100 / 4) { |
4067 | | pcrtc[e] = old & ~data; |
4068 | | update_int = true; |
4069 | | } |
4070 | | if (e == 0x140 / 4) |
4071 | | update_int = true; |
4072 | 3908 | if (e == 0x800 / 4) { |
4073 | | displayedtarget = (UINT32 *)direct_access_ptr(pcrtc[e]); |
4074 | | #ifdef LOG_NV2A |
4075 | | printf("crtc buffer %08X\n\r", data); |
4076 | | #endif |
| 3909 | displayedtarget = (UINT32 *)direct_access_ptr(data); |
| 3910 | //printf("crtc buffer %08X\n\r", data); |
4077 | 3911 | } |
4078 | 3912 | //logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask); |
4079 | 3913 | } |
r249094 | r249095 | |
4088 | 3922 | // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each |
4089 | 3923 | int chanel, subchannel, suboffset; |
4090 | 3924 | //int method, count, handle, objclass; |
| 3925 | #ifdef LOG_NV2A |
| 3926 | int subch; |
| 3927 | #endif |
4091 | 3928 | |
4092 | 3929 | suboffset = offset - 0x00800000 / 4; |
4093 | 3930 | chanel = (suboffset >> (16 - 2)) & 31; |
r249094 | r249095 | |
4122 | 3959 | } |
4123 | 3960 | //else |
4124 | 3961 | // logerror("NV_2A: write at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,data); |
4125 | | if (update_int == true) { |
4126 | | if (update_interrupts() == true) |
4127 | | interruptdevice->ir3_w(1); // IRQ 3 |
4128 | | else |
4129 | | interruptdevice->ir3_w(0); // IRQ 3 |
4130 | | } |
4131 | 3962 | } |
4132 | 3963 | |
4133 | 3964 | void nv2a_renderer::savestate_items() |
r249094 | r249095 | |
4140 | 3971 | puller_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nv2a_renderer::puller_timer_work), this), (void *)"NV2A Puller Timer"); |
4141 | 3972 | puller_timer->enable(false); |
4142 | 3973 | } |
4143 | | |
4144 | | void nv2a_renderer::set_interrupt_device(pic8259_device *device) |
4145 | | { |
4146 | | interruptdevice = device; |
4147 | | } |
trunk/src/mame/video/model2.c
r249094 | r249095 | |
89 | 89 | *********************************************************************************************************************************/ |
90 | 90 | #include "emu.h" |
91 | 91 | #include "video/segaic24.h" |
| 92 | #include "video/polylgcy.h" |
92 | 93 | #include "includes/model2.h" |
93 | 94 | |
94 | 95 | #define MODEL2_VIDEO_DEBUG 0 |
r249094 | r249095 | |
101 | 102 | |
102 | 103 | /******************************************* |
103 | 104 | * |
| 105 | * Basic Data Types |
| 106 | * |
| 107 | *******************************************/ |
| 108 | |
| 109 | struct plane |
| 110 | { |
| 111 | poly_vertex normal; |
| 112 | float distance; |
| 113 | }; |
| 114 | |
| 115 | struct texture_parameter |
| 116 | { |
| 117 | float diffuse; |
| 118 | float ambient; |
| 119 | UINT32 specular_control; |
| 120 | float specular_scale; |
| 121 | }; |
| 122 | |
| 123 | struct triangle |
| 124 | { |
| 125 | void * next; |
| 126 | poly_vertex v[3]; |
| 127 | UINT16 z; |
| 128 | UINT16 texheader[4]; |
| 129 | UINT8 luma; |
| 130 | INT16 viewport[4]; |
| 131 | INT16 center[2]; |
| 132 | }; |
| 133 | |
| 134 | struct quad_m2 |
| 135 | { |
| 136 | poly_vertex v[4]; |
| 137 | UINT16 z; |
| 138 | UINT16 texheader[4]; |
| 139 | UINT8 luma; |
| 140 | }; |
| 141 | |
| 142 | struct m2_poly_extra_data |
| 143 | { |
| 144 | model2_state * state; |
| 145 | UINT32 lumabase; |
| 146 | UINT32 colorbase; |
| 147 | UINT32 * texsheet; |
| 148 | UINT32 texwidth; |
| 149 | UINT32 texheight; |
| 150 | UINT32 texx, texy; |
| 151 | UINT8 texmirrorx; |
| 152 | UINT8 texmirrory; |
| 153 | }; |
| 154 | |
| 155 | |
| 156 | /******************************************* |
| 157 | * |
104 | 158 | * Generic 3D Math Functions |
105 | 159 | * |
106 | 160 | *******************************************/ |
r249094 | r249095 | |
780 | 834 | } |
781 | 835 | |
782 | 836 | /***********************************************************************************************/ |
783 | | |
| 837 | |
| 838 | INLINE UINT16 get_texel( UINT32 base_x, UINT32 base_y, int x, int y, UINT32 *sheet ) |
| 839 | { |
| 840 | UINT32 baseoffs = ((base_y/2)*512)+(base_x/2); |
| 841 | UINT32 texeloffs = ((y/2)*512)+(x/2); |
| 842 | UINT32 offset = baseoffs + texeloffs; |
| 843 | UINT32 texel = sheet[offset>>1]; |
| 844 | |
| 845 | if ( offset & 1 ) |
| 846 | texel >>= 16; |
| 847 | |
| 848 | if ( (y & 1) == 0 ) |
| 849 | texel >>= 8; |
| 850 | |
| 851 | if ( (x & 1) == 0 ) |
| 852 | texel >>= 4; |
| 853 | |
| 854 | return (texel & 0x0f); |
| 855 | } |
| 856 | |
| 857 | /* checker = 0, textured = 0, transparent = 0 */ |
| 858 | #define MODEL2_FUNC 0 |
| 859 | #define MODEL2_FUNC_NAME model2_3d_render_0 |
| 860 | #include "model2rd.inc" |
| 861 | #undef MODEL2_FUNC |
| 862 | #undef MODEL2_FUNC_NAME |
| 863 | |
| 864 | /* checker = 0, textured = 0, translucent = 1 */ |
| 865 | #define MODEL2_FUNC 1 |
| 866 | #define MODEL2_FUNC_NAME model2_3d_render_1 |
| 867 | #include "model2rd.inc" |
| 868 | #undef MODEL2_FUNC |
| 869 | #undef MODEL2_FUNC_NAME |
| 870 | |
| 871 | /* checker = 0, textured = 1, translucent = 0 */ |
| 872 | #define MODEL2_FUNC 2 |
| 873 | #define MODEL2_FUNC_NAME model2_3d_render_2 |
| 874 | #include "model2rd.inc" |
| 875 | #undef MODEL2_FUNC |
| 876 | #undef MODEL2_FUNC_NAME |
| 877 | |
| 878 | /* checker = 0, textured = 1, translucent = 1 */ |
| 879 | #define MODEL2_FUNC 3 |
| 880 | #define MODEL2_FUNC_NAME model2_3d_render_3 |
| 881 | #include "model2rd.inc" |
| 882 | #undef MODEL2_FUNC |
| 883 | #undef MODEL2_FUNC_NAME |
| 884 | |
| 885 | /* checker = 1, textured = 0, translucent = 0 */ |
| 886 | #define MODEL2_FUNC 4 |
| 887 | #define MODEL2_FUNC_NAME model2_3d_render_4 |
| 888 | #include "model2rd.inc" |
| 889 | #undef MODEL2_FUNC |
| 890 | #undef MODEL2_FUNC_NAME |
| 891 | |
| 892 | /* checker = 1, textured = 0, translucent = 1 */ |
| 893 | #define MODEL2_FUNC 5 |
| 894 | #define MODEL2_FUNC_NAME model2_3d_render_5 |
| 895 | #include "model2rd.inc" |
| 896 | #undef MODEL2_FUNC |
| 897 | #undef MODEL2_FUNC_NAME |
| 898 | |
| 899 | /* checker = 1, textured = 1, translucent = 0 */ |
| 900 | #define MODEL2_FUNC 6 |
| 901 | #define MODEL2_FUNC_NAME model2_3d_render_6 |
| 902 | #include "model2rd.inc" |
| 903 | #undef MODEL2_FUNC |
| 904 | #undef MODEL2_FUNC_NAME |
| 905 | |
| 906 | /* checker = 1, textured = 1, translucent = 1 */ |
| 907 | #define MODEL2_FUNC 7 |
| 908 | #define MODEL2_FUNC_NAME model2_3d_render_7 |
| 909 | #include "model2rd.inc" |
| 910 | #undef MODEL2_FUNC |
| 911 | #undef MODEL2_FUNC_NAME |
| 912 | |
784 | 913 | /***********************************************************************************************/ |
785 | 914 | |
786 | | void model2_renderer::model2_3d_render(triangle *tri, const rectangle &cliprect) |
| 915 | static const poly_draw_scanline_func render_funcs[8] = |
787 | 916 | { |
788 | | model2_renderer *poly = m_state.m_poly; |
789 | | m2_poly_extra_data& extra = poly->object_data_alloc(); |
790 | | UINT8 renderer; |
| 917 | model2_3d_render_0, /* checker = 0, textured = 0, translucent = 0 */ |
| 918 | model2_3d_render_1, /* checker = 0, textured = 0, translucent = 1 */ |
| 919 | model2_3d_render_2, /* checker = 0, textured = 1, translucent = 0 */ |
| 920 | model2_3d_render_3, /* checker = 0, textured = 1, translucent = 1 */ |
| 921 | model2_3d_render_4, /* checker = 1, textured = 0, translucent = 0 */ |
| 922 | model2_3d_render_5, /* checker = 1, textured = 0, translucent = 1 */ |
| 923 | model2_3d_render_6, /* checker = 1, textured = 1, translucent = 0 */ |
| 924 | model2_3d_render_7 /* checker = 1, textured = 1, translucent = 1 */ |
| 925 | }; |
791 | 926 | |
| 927 | static void model2_3d_render( model2_state *state, bitmap_rgb32 &bitmap, triangle *tri, const rectangle &cliprect ) |
| 928 | { |
| 929 | legacy_poly_manager *poly = state->m_poly; |
| 930 | m2_poly_extra_data *extra = (m2_poly_extra_data *)poly_get_extra_data(poly); |
| 931 | UINT8 renderer; |
| 932 | |
792 | 933 | /* select renderer based on attributes (bit15 = checker, bit14 = textured, bit13 = transparent */ |
793 | 934 | renderer = (tri->texheader[0] >> 13) & 7; |
794 | 935 | |
r249094 | r249095 | |
796 | 937 | rectangle vp(tri->viewport[0] - 8, tri->viewport[2] - 8, (384-tri->viewport[3])+90, (384-tri->viewport[1])+90); |
797 | 938 | vp &= cliprect; |
798 | 939 | |
799 | | extra.state = &m_state; |
800 | | extra.lumabase = ((tri->texheader[1] & 0xFF) << 7) + ((tri->luma >> 5) ^ 0x7); |
801 | | extra.colorbase = (tri->texheader[3] >> 6) & 0x3FF; |
| 940 | extra->state = state; |
| 941 | extra->lumabase = ((tri->texheader[1] & 0xFF) << 7) + ((tri->luma >> 5) ^ 0x7); |
| 942 | extra->colorbase = (tri->texheader[3] >> 6) & 0x3FF; |
802 | 943 | |
803 | 944 | if (renderer & 2) |
804 | 945 | { |
805 | | extra.texwidth = 32 << ((tri->texheader[0] >> 0) & 0x7); |
806 | | extra.texheight = 32 << ((tri->texheader[0] >> 3) & 0x7); |
807 | | extra.texx = 32 * ((tri->texheader[2] >> 0) & 0x1f); |
808 | | extra.texy = 32 * (((tri->texheader[2] >> 6) & 0x1f) + ( tri->texheader[2] & 0x20 )); |
| 946 | extra->texwidth = 32 << ((tri->texheader[0] >> 0) & 0x7); |
| 947 | extra->texheight = 32 << ((tri->texheader[0] >> 3) & 0x7); |
| 948 | extra->texx = 32 * ((tri->texheader[2] >> 0) & 0x1f); |
| 949 | extra->texy = 32 * (((tri->texheader[2] >> 6) & 0x1f) + ( tri->texheader[2] & 0x20 )); |
809 | 950 | /* TODO: Virtua Striker contradicts with this. */ |
810 | | extra.texmirrorx = 0;//(tri->texheader[0] >> 9) & 1; |
811 | | extra.texmirrory = 0;//(tri->texheader[0] >> 8) & 1; |
812 | | extra.texsheet = (tri->texheader[2] & 0x1000) ? m_state.m_textureram1 : m_state.m_textureram0; |
| 951 | extra->texmirrorx = 0;//(tri->texheader[0] >> 9) & 1; |
| 952 | extra->texmirrory = 0;//(tri->texheader[0] >> 8) & 1; |
| 953 | extra->texsheet = (tri->texheader[2] & 0x1000) ? state->m_textureram1 : state->m_textureram0; |
813 | 954 | |
814 | 955 | tri->v[0].pz = 1.0f / (1.0f + tri->v[0].pz); |
815 | 956 | tri->v[0].pu = tri->v[0].pu * tri->v[0].pz * (1.0f / 8.0f); |
r249094 | r249095 | |
821 | 962 | tri->v[2].pu = tri->v[2].pu * tri->v[2].pz * (1.0f / 8.0f); |
822 | 963 | tri->v[2].pv = tri->v[2].pv * tri->v[2].pz * (1.0f / 8.0f); |
823 | 964 | |
824 | | // Note : The class model2_renderer has an array of function pointers in it named m_renderfuncs, in theory this simply |
825 | | // needs to be passed into the render_triangle function as such model2_renderer::m_renderfuncs[renderer], but |
826 | | // I was unable to make it work when converting to the new polygon rasterizer interface. |
827 | | switch (renderer) |
828 | | { |
829 | | case 0: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_0), this), 3, tri->v[0], tri->v[1], tri->v[2]); break; |
830 | | case 1: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_1), this), 3, tri->v[0], tri->v[1], tri->v[2]); break; |
831 | | case 2: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_2), this), 3, tri->v[0], tri->v[1], tri->v[2]); break; |
832 | | case 3: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_3), this), 3, tri->v[0], tri->v[1], tri->v[2]); break; |
833 | | case 4: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_4), this), 3, tri->v[0], tri->v[1], tri->v[2]); break; |
834 | | case 5: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_5), this), 3, tri->v[0], tri->v[1], tri->v[2]); break; |
835 | | case 6: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_6), this), 3, tri->v[0], tri->v[1], tri->v[2]); break; |
836 | | case 7: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_7), this), 3, tri->v[0], tri->v[1], tri->v[2]); break; |
837 | | } |
| 965 | poly_render_triangle(poly, &bitmap, vp, render_funcs[renderer], 3, &tri->v[0], &tri->v[1], &tri->v[2]); |
838 | 966 | } |
839 | 967 | else |
840 | | { |
841 | | switch (renderer) |
842 | | { |
843 | | case 0: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_0), this), 0, tri->v[0], tri->v[1], tri->v[2]); break; |
844 | | case 1: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_1), this), 0, tri->v[0], tri->v[1], tri->v[2]); break; |
845 | | case 2: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_2), this), 0, tri->v[0], tri->v[1], tri->v[2]); break; |
846 | | case 3: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_3), this), 0, tri->v[0], tri->v[1], tri->v[2]); break; |
847 | | case 4: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_4), this), 0, tri->v[0], tri->v[1], tri->v[2]); break; |
848 | | case 5: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_5), this), 0, tri->v[0], tri->v[1], tri->v[2]); break; |
849 | | case 6: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_6), this), 0, tri->v[0], tri->v[1], tri->v[2]); break; |
850 | | case 7: render_triangle(vp, render_delegate(FUNC(model2_renderer::model2_3d_render_7), this), 0, tri->v[0], tri->v[1], tri->v[2]); break; |
851 | | } |
852 | | } |
| 968 | poly_render_triangle(poly, &bitmap, vp, render_funcs[renderer], 0, &tri->v[0], &tri->v[1], &tri->v[2]); |
853 | 969 | } |
854 | 970 | |
855 | 971 | /* |
r249094 | r249095 | |
903 | 1019 | void model2_state::model2_3d_frame_end( bitmap_rgb32 &bitmap, const rectangle &cliprect ) |
904 | 1020 | { |
905 | 1021 | raster_state *raster = m_raster; |
906 | | INT32 z; |
| 1022 | INT32 z; |
907 | 1023 | |
908 | 1024 | /* if we have nothing to render, bail */ |
909 | 1025 | if ( raster->tri_list_index == 0 ) |
r249094 | r249095 | |
947 | 1063 | } |
948 | 1064 | #endif |
949 | 1065 | |
950 | | m_poly->destmap().fill(0x00000000, cliprect); |
951 | | |
952 | 1066 | /* go through the Z levels, and render each bucket */ |
953 | 1067 | for( z = raster->max_z; z >= raster->min_z; z-- ) |
954 | 1068 | { |
r249094 | r249095 | |
963 | 1077 | { |
964 | 1078 | /* project and render */ |
965 | 1079 | model2_3d_project( tri ); |
966 | | m_poly->model2_3d_render(tri, cliprect); |
| 1080 | model2_3d_render( this, bitmap, tri, cliprect ); |
967 | 1081 | |
968 | 1082 | tri = (triangle *)tri->next; |
969 | 1083 | } |
970 | 1084 | } |
971 | 1085 | } |
972 | | m_poly->wait("End of frame"); |
973 | | |
974 | | copybitmap_trans(bitmap, m_poly->destmap(), 0, 0, 0, 0, cliprect, 0x00000000); |
| 1086 | poly_wait(m_poly, "End of frame"); |
975 | 1087 | } |
976 | 1088 | |
977 | 1089 | /* 3D Rasterizer main data input port */ |
r249094 | r249095 | |
2582 | 2694 | /***********************************************************************************************/ |
2583 | 2695 | |
2584 | 2696 | |
| 2697 | void model2_state::model2_exit() |
| 2698 | { |
| 2699 | poly_free(m_poly); |
| 2700 | } |
| 2701 | |
2585 | 2702 | VIDEO_START_MEMBER(model2_state,model2) |
2586 | 2703 | { |
2587 | 2704 | const rectangle &visarea = m_screen->visible_area(); |
r249094 | r249095 | |
2590 | 2707 | |
2591 | 2708 | m_sys24_bitmap.allocate(width, height+4); |
2592 | 2709 | |
2593 | | m_poly = auto_alloc(machine(), model2_renderer(*this)); |
| 2710 | m_poly = poly_alloc(machine(), 4000, sizeof(m2_poly_extra_data), 0); |
| 2711 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(model2_state::model2_exit), this)); |
2594 | 2712 | |
2595 | 2713 | /* initialize the hardware rasterizer */ |
2596 | 2714 | model2_3d_init( machine(), (UINT16*)memregion("user3")->base() ); |
trunk/src/mess/drivers/dvk_kcgd.c
r249094 | r249095 | |
1 | | /*************************************************************************** |
2 | | |
3 | | KCGD (Kontroller Cvetnogo Graficheskogo Displeya = Colour Graphics |
4 | | Display Controller), a replacement for KSM (dvk_ksm.c) in later |
5 | | models of DVK desktops. |
6 | | |
7 | | MPI (Q-Bus clone) board. Interfaces with MS7004 (DEC LK201 workalike) |
8 | | keyboard, mouse, and monochrome or color CRT. |
9 | | |
10 | | To do: |
11 | | - K1801VM2 CPU core (interrupts and EVNT pin, full EIS set, other insns) |
12 | | - Everything else :-) |
13 | | |
14 | | ****************************************************************************/ |
15 | | |
16 | | #include "emu.h" |
17 | | |
18 | | #include "bus/rs232/rs232.h" |
19 | | #include "cpu/t11/t11.h" |
20 | | #include "machine/clock.h" |
21 | | #include "machine/ms7004.h" |
22 | | |
23 | | #define KCGD_TOTAL_HORZ 1000 // XXX verify |
24 | | #define KCGD_DISP_HORZ 800 |
25 | | #define KCGD_HORZ_START 200 // XXX verify |
26 | | |
27 | | #define KCGD_TOTAL_VERT 600 // XXX verify |
28 | | #define KCGD_DISP_VERT 480 |
29 | | #define KCGD_VERT_START 100 // XXX verify |
30 | | |
31 | | #define KCGD_STATUS_PAGE 0 |
32 | | #define KCGD_STATUS_INTERLACE 1 |
33 | | #define KCGD_STATUS_TIMER_INT 5 |
34 | | #define KCGD_STATUS_MODE_INT 6 |
35 | | #define KCGD_STATUS_MODE_LAST 7 |
36 | | #define KCGD_STATUS_TIMER_VAL 15 |
37 | | |
38 | | #define KCGD_PAGE_0 015574 |
39 | | #define KCGD_PAGE_1 005574 |
40 | | |
41 | | #define VERBOSE_DBG 1 /* general debug messages */ |
42 | | |
43 | | #define DBG_LOG(N,M,A) \ |
44 | | do { \ |
45 | | if(VERBOSE_DBG>=N) \ |
46 | | { \ |
47 | | if( M ) \ |
48 | | logerror("%11.6f at %s: %-24s",machine().time().as_double(),machine().describe_context(),(char*)M ); \ |
49 | | logerror A; \ |
50 | | } \ |
51 | | } while (0) |
52 | | |
53 | | |
54 | | class kcgd_state : public driver_device |
55 | | { |
56 | | public: |
57 | | kcgd_state(const machine_config &mconfig, device_type type, const char *tag) : |
58 | | driver_device(mconfig, type, tag), |
59 | | m_maincpu(*this, "maincpu"), |
60 | | // m_ms7004(*this, "ms7004"), |
61 | | m_palette(*this, "palette"), |
62 | | m_screen(*this, "screen") |
63 | | { } |
64 | | |
65 | | virtual void machine_reset(); |
66 | | virtual void video_start(); |
67 | | UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
68 | | TIMER_DEVICE_CALLBACK_MEMBER(scanline_callback); |
69 | | DECLARE_PALETTE_INIT(kcgd); |
70 | | |
71 | | enum |
72 | | { |
73 | | TIMER_ID_VSYNC_ON, |
74 | | TIMER_ID_VSYNC_OFF, |
75 | | TIMER_ID_500HZ |
76 | | }; |
77 | | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
78 | | |
79 | | DECLARE_WRITE_LINE_MEMBER(write_keyboard_clock); |
80 | | DECLARE_WRITE_LINE_MEMBER(write_line_clock); |
81 | | |
82 | | DECLARE_READ16_MEMBER(vram_addr_r); |
83 | | DECLARE_READ16_MEMBER(vram_data_r); |
84 | | DECLARE_READ16_MEMBER(vram_mmap_r); |
85 | | DECLARE_WRITE16_MEMBER(vram_addr_w); |
86 | | DECLARE_WRITE16_MEMBER(vram_data_w); |
87 | | DECLARE_WRITE16_MEMBER(vram_mmap_w); |
88 | | DECLARE_READ16_MEMBER(status_r); |
89 | | DECLARE_WRITE16_MEMBER(status_w); |
90 | | DECLARE_READ8_MEMBER(palette_index_r); |
91 | | DECLARE_READ8_MEMBER(palette_data_r); |
92 | | DECLARE_WRITE8_MEMBER(palette_index_w); |
93 | | DECLARE_WRITE8_MEMBER(palette_data_w); |
94 | | |
95 | | emu_timer *m_vsync_on_timer; |
96 | | emu_timer *m_vsync_off_timer; |
97 | | emu_timer *m_500hz_timer; |
98 | | |
99 | | private: |
100 | | void draw_scanline(UINT16 *p, UINT16 offset); |
101 | | rectangle m_tmpclip; |
102 | | bitmap_ind16 m_tmpbmp; |
103 | | |
104 | | struct { |
105 | | UINT16 status; // 167770 |
106 | | UINT8 control; // 167772 |
107 | | int palette_index, vram_addr; |
108 | | UINT8 palette[16]; |
109 | | } m_video; |
110 | | UINT32 *m_videoram; |
111 | | |
112 | | protected: |
113 | | required_device<cpu_device> m_maincpu; |
114 | | // required_device<ms7004_device> m_ms7004; |
115 | | required_device<palette_device> m_palette; |
116 | | required_device<screen_device> m_screen; |
117 | | }; |
118 | | |
119 | | static ADDRESS_MAP_START( kcgd_mem, AS_PROGRAM, 16, kcgd_state ) |
120 | | ADDRESS_MAP_UNMAP_HIGH |
121 | | AM_RANGE (0000000, 0077777) AM_READWRITE(vram_mmap_r, vram_mmap_w) |
122 | | AM_RANGE (0100000, 0157777) AM_ROM |
123 | | AM_RANGE (0160000, 0160001) AM_MIRROR(03774) AM_READWRITE(vram_addr_r, vram_addr_w) |
124 | | AM_RANGE (0160002, 0160003) AM_MIRROR(03774) AM_READWRITE(vram_data_r, vram_data_w) |
125 | | AM_RANGE (0167770, 0167771) AM_READWRITE(status_r, status_w) |
126 | | AM_RANGE (0167772, 0167773) AM_READWRITE8(palette_index_r, palette_index_w, 0x00ff) // reads always return 0 |
127 | | AM_RANGE (0167772, 0167773) AM_READWRITE8(palette_data_r, palette_data_w, 0xff00) |
128 | | // AM_RANGE (0176560, 0176567) AM_RAM // USART2 -- host |
129 | | // AM_RANGE (0177560, 0177567) AM_RAM // USART3 -- keyboard |
130 | | ADDRESS_MAP_END |
131 | | |
132 | | void kcgd_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
133 | | { |
134 | | switch (id) |
135 | | { |
136 | | /* |
137 | | case TIMER_ID_VSYNC_ON: |
138 | | m_maincpu->set_input_line(INPUT_LINE_EVNT, ASSERT_LINE); |
139 | | break; |
140 | | |
141 | | case TIMER_ID_VSYNC_OFF: |
142 | | m_maincpu->set_input_line(INPUT_LINE_EVNT, CLEAR_LINE); |
143 | | break; |
144 | | */ |
145 | | case TIMER_ID_500HZ: |
146 | | m_video.status ^= (1 << KCGD_STATUS_TIMER_VAL); |
147 | | break; |
148 | | } |
149 | | } |
150 | | |
151 | | void kcgd_state::machine_reset() |
152 | | { |
153 | | memset(&m_video, 0, sizeof(m_video)); |
154 | | } |
155 | | |
156 | | void kcgd_state::video_start() |
157 | | { |
158 | | // screen_device *screen = machine().device<screen_device>("screen"); |
159 | | |
160 | | // 64 kwords, word size is 17 bits |
161 | | m_videoram = auto_alloc_array(machine(), UINT32, 65536); |
162 | | |
163 | | m_tmpclip = rectangle(0, KCGD_DISP_HORZ-1, 0, KCGD_DISP_VERT-1); |
164 | | m_tmpbmp.allocate(KCGD_DISP_HORZ, KCGD_DISP_VERT); |
165 | | /* |
166 | | m_vsync_on_timer = timer_alloc(TIMER_ID_VSYNC_ON); |
167 | | m_vsync_on_timer->adjust(screen->time_until_pos(0, 0), 0, screen->frame_period()); |
168 | | |
169 | | m_vsync_off_timer = timer_alloc(TIMER_ID_VSYNC_OFF); |
170 | | m_vsync_off_timer->adjust(screen->time_until_pos(16, 0), 0, screen->frame_period()); |
171 | | */ |
172 | | m_500hz_timer = timer_alloc(TIMER_ID_500HZ); |
173 | | m_500hz_timer->adjust(attotime::from_hz(500), 0, attotime::from_hz(500)); |
174 | | } |
175 | | |
176 | | PALETTE_INIT_MEMBER(kcgd_state, kcgd) |
177 | | { |
178 | | for (int i = 0; i < 16; i++) |
179 | | { |
180 | | palette.set_pen_color(i, i?i:255, i?i:255, i?i:255); |
181 | | } |
182 | | } |
183 | | |
184 | | /* |
185 | | VRAM is 128K and is word-addressable, so address fits into 16 bits. |
186 | | Low 32K of VRAM are not used to store pixel data -- XXX. |
187 | | */ |
188 | | WRITE16_MEMBER(kcgd_state::vram_addr_w) |
189 | | { |
190 | | DBG_LOG(3,"VRAM WA", ("%06o\n", data)); |
191 | | m_video.vram_addr = data; |
192 | | } |
193 | | |
194 | | READ16_MEMBER(kcgd_state::vram_addr_r) |
195 | | { |
196 | | DBG_LOG(3,"VRAM RA", ("\n")); |
197 | | return m_video.vram_addr; |
198 | | } |
199 | | |
200 | | WRITE16_MEMBER(kcgd_state::vram_data_w) |
201 | | { |
202 | | DBG_LOG(1,"VRAM W2", ("%06o <- %04XH\n", m_video.vram_addr, data)); |
203 | | m_videoram[m_video.vram_addr] = data | (BIT(m_video.control, 7) << 16); |
204 | | } |
205 | | |
206 | | READ16_MEMBER(kcgd_state::vram_data_r) |
207 | | { |
208 | | DBG_LOG(2,"VRAM R2", ("%06o\n", m_video.vram_addr)); |
209 | | m_video.status = (m_video.status & 0xff7f) | (BIT(m_videoram[m_video.vram_addr], 16) << 7); |
210 | | return (UINT16) (m_videoram[m_video.vram_addr] & 0xffff); |
211 | | } |
212 | | |
213 | | WRITE16_MEMBER(kcgd_state::vram_mmap_w) |
214 | | { |
215 | | DBG_LOG(3,"VRAM W1", ("%06o <- %04XH\n", offset, data)); |
216 | | m_videoram[offset] = data | (BIT(m_video.control, 7) << 16); |
217 | | } |
218 | | |
219 | | READ16_MEMBER(kcgd_state::vram_mmap_r) |
220 | | { |
221 | | DBG_LOG(3,"VRAM R1", ("%06o\n", offset)); |
222 | | return (UINT16) (m_videoram[offset] & 0xffff); |
223 | | } |
224 | | |
225 | | WRITE16_MEMBER(kcgd_state::status_w) |
226 | | { |
227 | | DBG_LOG(1,"Status W", ("data %04XH (useful %02XH)\n", data, data & 0x63)); |
228 | | // bits 7 and 15 are read-only |
229 | | m_video.status = (m_video.status & 0x8080) | (data & 0x7f7f); |
230 | | } |
231 | | |
232 | | READ16_MEMBER(kcgd_state::status_r) |
233 | | { |
234 | | UINT16 data = m_video.status ^ (BIT(m_video.control, 6) << 7); |
235 | | DBG_LOG(1,"Status R", ("data %04X index %d\n", data, m_video.palette_index)); |
236 | | return data; |
237 | | } |
238 | | |
239 | | WRITE8_MEMBER(kcgd_state::palette_index_w) |
240 | | { |
241 | | m_video.control = data; |
242 | | m_video.palette_index = ((data >> 2) & 15); |
243 | | DBG_LOG(1,"Palette index, Control W", ("data %02XH index %d\n", data, m_video.palette_index)); |
244 | | } |
245 | | |
246 | | WRITE8_MEMBER(kcgd_state::palette_data_w) |
247 | | { |
248 | | DBG_LOG(1,"Palette data W", ("data %02XH index %d\n", data, m_video.palette_index)); |
249 | | m_video.palette[m_video.palette_index] = data; |
250 | | m_palette->set_pen_color(m_video.palette_index, |
251 | | 85*(data & 3), 85*((data >> 2) & 3), 85*((data >> 4) & 3)); |
252 | | } |
253 | | |
254 | | READ8_MEMBER(kcgd_state::palette_index_r) |
255 | | { |
256 | | return 0; |
257 | | } |
258 | | |
259 | | READ8_MEMBER(kcgd_state::palette_data_r) |
260 | | { |
261 | | DBG_LOG(1,"Palette data R", ("index %d\n", m_video.palette_index)); |
262 | | return m_video.palette[m_video.palette_index]; |
263 | | } |
264 | | |
265 | | /* |
266 | | Raster sizes are: |
267 | | - 800(400)x480 in hires(lores) 60 Hz interlaced mode |
268 | | - 800(400)x240 in hires(lores) 30 Hz progressive mode |
269 | | |
270 | | Video memory is 17 bits wide (bit 16 indicates hi/lo res mode for each word, |
271 | | host writes it separately (via bit 7 in 167772). |
272 | | */ |
273 | | |
274 | | void kcgd_state::draw_scanline(UINT16 *p, UINT16 offset) |
275 | | { |
276 | | int i; |
277 | | |
278 | | for ( i = 0; i < 100; i++ ) |
279 | | { |
280 | | UINT32 data = m_videoram[ offset++ ]; |
281 | | if (BIT(data, 16)) { |
282 | | *p = ( data >> 12) & 0x0F; p++; |
283 | | *p = ( data >> 12) & 0x0F; p++; |
284 | | *p = ( data >> 8 ) & 0x0F; p++; |
285 | | *p = ( data >> 8 ) & 0x0F; p++; |
286 | | *p = ( data >> 4 ) & 0x0F; p++; |
287 | | *p = ( data >> 4 ) & 0x0F; p++; |
288 | | *p = data & 0x0F; p++; |
289 | | *p = data & 0x0F; p++; |
290 | | } else { |
291 | | *p = 5*(( data >> 14) & 0x03); p++; |
292 | | *p = 5*(( data >> 12) & 0x03); p++; |
293 | | *p = 5*(( data >> 10) & 0x03); p++; |
294 | | *p = 5*(( data >> 8 ) & 0x03); p++; |
295 | | *p = 5*(( data >> 6 ) & 0x03); p++; |
296 | | *p = 5*(( data >> 4 ) & 0x03); p++; |
297 | | *p = 5*(( data >> 2 ) & 0x03); p++; |
298 | | *p = 5*( data & 0x03); p++; |
299 | | } |
300 | | } |
301 | | } |
302 | | |
303 | | TIMER_DEVICE_CALLBACK_MEMBER(kcgd_state::scanline_callback) |
304 | | { |
305 | | UINT16 y = m_screen->vpos(), offset; |
306 | | |
307 | | if (y < KCGD_VERT_START) return; |
308 | | y -= KCGD_VERT_START; |
309 | | if (y >= KCGD_DISP_VERT) return; |
310 | | |
311 | | offset = BIT(m_video.status, KCGD_STATUS_PAGE) ? (KCGD_PAGE_1 >> 1) : (KCGD_PAGE_0 >> 1); |
312 | | |
313 | | DBG_LOG(2,"scanline_cb", ("frame %" I64FMT "d y %.3d page %d offset %04X *offset %04X\n", |
314 | | m_screen->frame_number(), BIT(m_video.status, KCGD_STATUS_PAGE), |
315 | | y, offset + y, m_videoram[offset + y])); |
316 | | |
317 | | draw_scanline(&m_tmpbmp.pix16(y), m_videoram[offset + (KCGD_DISP_VERT-1) - y]); |
318 | | } |
319 | | |
320 | | UINT32 kcgd_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
321 | | { |
322 | | copybitmap(bitmap, m_tmpbmp, 0, 0, KCGD_HORZ_START, KCGD_VERT_START, cliprect); |
323 | | return 0; |
324 | | } |
325 | | |
326 | | /* F4 Character Displayer */ |
327 | | static const gfx_layout kcgd_charlayout = |
328 | | { |
329 | | 8, 10, /* 8x10 pixels */ |
330 | | 256, /* 256 characters */ |
331 | | 1, /* 1 bits per pixel */ |
332 | | { 0 }, /* no bitplanes */ |
333 | | /* x offsets */ |
334 | | { 0, 1, 2, 3, 4, 5, 6, 7 }, |
335 | | /* y offsets */ |
336 | | { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8 }, |
337 | | 8*10 /* every char takes 10 bytes */ |
338 | | }; |
339 | | |
340 | | static GFXDECODE_START( kcgd ) |
341 | | GFXDECODE_ENTRY("maincpu", 0112236, kcgd_charlayout, 0, 1) |
342 | | GFXDECODE_END |
343 | | |
344 | | static MACHINE_CONFIG_START( kcgd, kcgd_state ) |
345 | | MCFG_CPU_ADD("maincpu", K1801VM2, XTAL_30_8MHz/4) |
346 | | MCFG_CPU_PROGRAM_MAP(kcgd_mem) |
347 | | MCFG_T11_INITIAL_MODE(0100000) |
348 | | |
349 | | MCFG_TIMER_DRIVER_ADD_PERIODIC("scantimer", kcgd_state, scanline_callback, attotime::from_hz(50*28*11)) // XXX verify |
350 | | MCFG_TIMER_START_DELAY(attotime::from_hz(XTAL_30_8MHz/KCGD_HORZ_START)) |
351 | | |
352 | | MCFG_SCREEN_ADD("screen", RASTER) |
353 | | MCFG_SCREEN_UPDATE_DRIVER(kcgd_state, screen_update) |
354 | | MCFG_SCREEN_RAW_PARAMS(XTAL_30_8MHz, KCGD_TOTAL_HORZ, KCGD_HORZ_START, |
355 | | KCGD_HORZ_START+KCGD_DISP_HORZ, KCGD_TOTAL_VERT, KCGD_VERT_START, |
356 | | KCGD_VERT_START+KCGD_DISP_VERT); |
357 | | |
358 | | MCFG_SCREEN_PALETTE("palette") |
359 | | MCFG_PALETTE_ADD("palette", 16) |
360 | | MCFG_PALETTE_INIT_OWNER(kcgd_state, kcgd) |
361 | | |
362 | | MCFG_GFXDECODE_ADD("gfxdecode", "palette", kcgd) |
363 | | #if 0 |
364 | | MCFG_DEVICE_ADD("ms7004", MS7004, 0) |
365 | | MCFG_MS7004_TX_HANDLER(DEVWRITELINE("i8251kbd", i8251_device, write_rxd)) |
366 | | |
367 | | MCFG_DEVICE_ADD("keyboard_clock", CLOCK, 4800*16) |
368 | | MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(kcgd_state, write_keyboard_clock)) |
369 | | #endif |
370 | | MACHINE_CONFIG_END |
371 | | |
372 | | ROM_START( dvk_kcgd ) |
373 | | ROM_REGION16_BE(0x100000,"maincpu", ROMREGION_ERASE00) |
374 | | ROM_DEFAULT_BIOS("181") |
375 | | ROM_SYSTEM_BIOS(0, "181", "mask 181") |
376 | | ROMX_LOAD("kr1801re2-181.bin", 0100000, 020000, CRC(acac124f) SHA1(412c3eb71bece6f791fc5a9d707cf4692fd0b45b), ROM_BIOS(1)) |
377 | | ROM_SYSTEM_BIOS(1, "182", "mask 182") |
378 | | ROMX_LOAD("kr1801re2-182.bin", 0100000, 020000, CRC(3ca2921a) SHA1(389b30c40ed7e41dae71d58c7bff630359a48153), ROM_BIOS(2)) |
379 | | ROM_END |
380 | | |
381 | | /* Driver */ |
382 | | |
383 | | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
384 | | COMP( 1987, dvk_kcgd, 0, 0, kcgd, 0, driver_device, 0, "USSR", "DVK KCGD", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) |
trunk/src/mess/drivers/force68k.c
r249094 | r249095 | |
1 | | // license:BSD-3-Clause |
| 1 | // license:BSD-3-Clause |
2 | 2 | // copyright-holders:Joakim Larsson Edstr??m |
3 | 3 | /*************************************************************************** |
4 | | * |
5 | | * Force SYS68K CPU-1/CPU-6 VME SBC drivers, initially based on the 68ksbc.c |
6 | | * |
7 | | * 13/06/2015 |
8 | | * |
9 | | * The info found on the links below is for a later revisions of the board I have |
10 | | * but it is somewhat compatible so I got the system ROM up and running in terminal. |
11 | | * My CPU-1 board has proms from 1983 and the PCB has no rev markings so probably |
12 | | * the original or a very early design. The board real estate differs from the later |
13 | | * CPU-1:s I found pictures of but has the same main chips and functions. |
14 | | * |
15 | | * http://bitsavers.trailing-edge.com/pdf/forceComputers/1988_Force_VMEbus_Products.pdf |
16 | | * http://www.artisantg.com/info/P_wUovN.pdf |
17 | | * |
18 | | * Some info from those documents: |
19 | | * |
20 | | * Address Map |
21 | | * ---------------------------------------------------------- |
22 | | * Address Range Description |
23 | | * ---------------------------------------------------------- |
24 | | * 000 000 - 000 007 Initialisation vectors from system EPROM |
25 | | * 000 008 - 01F FFF Dynamic RAM on CPU-1 B |
26 | | * 000 008 - 07F FFF Dynamic RAM on CPU-1 D |
27 | | * 080 008 - 09F FFF SYSTEM EPROM Area |
28 | | * OAO 000 - OBF FFF USER EPROMArea |
29 | | * 0C0 041 - 0C0 043 ACIA (P3) Host |
30 | | * 0C0 080 - 0C0 082 ACIA (P4) Terminal |
31 | | * 0C0 101 - 0C0 103 ACIA (P5) Remote device (eg serial printer) |
32 | | * 0C0 401 - 0C0 42F RTC |
33 | | * OEO 001 - 0E0 035 PI/T (eg centronics printer) |
34 | | * OEO 200 - 0E0 2FF FPU |
35 | | * OEO 300 - 0E0 300 Reset Off |
36 | | * OEO 380 - 0E0 380 Reset On |
37 | | * 100 000 - FEF FFF VMEbus addresses (A24) |
38 | | * FFO 000 - FFF FFF VMEbus Short I/O (A16) |
39 | | * ---------------------------------------------------------- |
40 | | * |
41 | | * Interrupt sources |
42 | | * ---------------------------------------------------------- |
43 | | * Description Device Lvl IRQ VME board |
44 | | * /Board Vector Address |
45 | | * ---------------------------------------------------------- |
46 | | * On board Sources |
47 | | * ABORT Switch 7 31 |
48 | | * Real Time Clock (RTC) 58167A 6 30 |
49 | | * Parallel/Timer (PI/T) 68230 5 29 |
50 | | * Terminal ACIA 6850 4 28 |
51 | | * Remote ACIA 6850 3 27 |
52 | | * Host ACIA 6850 2 26 |
53 | | * ACFAIL, SYSFAIL VME 5 29 |
54 | | * Off board Sources (other VME boards) |
55 | | * 6 Port Serial I/O board SIO 4 64-75 0xb00000 |
56 | | * 8 Port Serial I/O board ISIO 4 76-83 0x960000 |
57 | | * Disk Controller WFC 3 119 0xb01000 |
58 | | * SCSI Controller ISCSI 4 119 0xa00000 |
59 | | * Slot 1 Controller Board ASCU 7 31 0xb02000 |
60 | | * ---------------------------------------------------------- |
61 | | * |
62 | | * TODO: |
63 | | * - Finish 3 x ACIA6850, host and remote interface left, terminal works |
64 | | * - Finish 1 x 68230 Motorola, Parallel Interface / Timer as required by ROM |
65 | | * - Configure PIT to the Centronics device printer interface as |
66 | | * supported by ROM (DONE) |
67 | | * - Add 1 x Abort Switch |
68 | | * - Add 1 x Reset Switch |
69 | | * - Add 1 x Halt LED |
70 | | * - Add a jumper field device as supported by PCB |
71 | | * - Add configurable serial connector between ACIA:s and |
72 | | * - Real terminal emulator, ie rs232 "socket" |
73 | | * - Debug console |
74 | | * - Add VME bus driver |
75 | | * |
76 | | ****************************************************************************/ |
77 | 4 | |
| 5 | Force SYS68K CPU-1/CPU-6 VME SBC drivers, initially based on the 68ksbc.c |
| 6 | |
| 7 | 13/06/2015 |
| 8 | |
| 9 | The info found on the links below is for a later revisions of the board I have |
| 10 | but I hope it is somewhat compatible so I can get it up and running at least. |
| 11 | My CPU-1 board has proms from 1983 and no rev markings so probably the original. |
| 12 | |
| 13 | http://bitsavers.trailing-edge.com/pdf/forceComputers/1988_Force_VMEbus_Products.pdf |
| 14 | http://www.artisantg.com/info/P_wUovN.pdf |
| 15 | |
| 16 | Some info from those documents: |
| 17 | |
| 18 | Address Map |
| 19 | ---------------------------------------------------------- |
| 20 | Address Range Description |
| 21 | ---------------------------------------------------------- |
| 22 | 000 000 - 000 007 Initialisation vectors from system EPROM |
| 23 | 000 008 - 01F FFF Dynamic RAM on CPU-1 B |
| 24 | 000 008 - 07F FFF Dynamic RAM on CPU-1 D |
| 25 | 080 008 - 09F FFF SYSTEM EPROM Area |
| 26 | OAO 000 - OBF FFF USER EPROMArea |
| 27 | 0C0 041 - 0C0 043 ACIA (P3) Host |
| 28 | 0C0 080 - 0C0 082 ACIA (P4) Terminal |
| 29 | 0C0 101 - 0C0 103 ACIA (P5) Remote device (eg serial printer) |
| 30 | 0C0 401 - 0C0 42F RTC |
| 31 | OEO 001 - 0E0 035 PI/T (eg centronics printer) |
| 32 | OEO 200 - 0E0 2FF FPU |
| 33 | OEO 300 - 0E0 300 Reset Off |
| 34 | OEO 380 - 0E0 380 Reset On |
| 35 | 100 000 - FEF FFF VMEbus addresses (A24) |
| 36 | FFO 000 - FFF FFF VMEbus Short I/O (A16) |
| 37 | ---------------------------------------------------------- |
| 38 | |
| 39 | Interrupt sources |
| 40 | ---------------------------------------------------------- |
| 41 | Description Device Lvl IRQ VME board |
| 42 | /Board Vector Address |
| 43 | ---------------------------------------------------------- |
| 44 | On board Sources |
| 45 | ABORT Switch 7 31 |
| 46 | Real Time Clock (RTC) 58167A 6 30 |
| 47 | Parallel/Timer (PI/T) 68230 5 29 |
| 48 | Terminal ACIA 6850 4 28 |
| 49 | Remote ACIA 6850 3 27 |
| 50 | Host ACIA 6850 2 26 |
| 51 | ACFAIL, SYSFAIL VME 5 29 |
| 52 | Off board Sources (other VME boards) |
| 53 | 6 Port Serial I/O board SIO 4 64-75 0xb00000 |
| 54 | 8 Port Serial I/O board ISIO 4 76-83 0x960000 |
| 55 | Disk Controller WFC 3 119 0xb01000 |
| 56 | SCSI Controller ISCSI 4 119 0xa00000 |
| 57 | Slot 1 Controller Board ASCU 7 31 0xb02000 |
| 58 | ---------------------------------------------------------- |
| 59 | |
| 60 | 10. The VMEbus |
| 61 | --------------- |
| 62 | The implemented VMEbus Interface includes 24 address, 16 data, |
| 63 | 6 address modifier and the asynchronous control signals. |
| 64 | A single level bus arbiter is provided to build multi master |
| 65 | systems. In addition to the bus arbiter, a separate slave bus |
| 66 | arbitration allows selection of the arbitration level (0-3). |
| 67 | |
| 68 | The address modifier range .,Short 110 Access?? can be selected |
| 69 | via a jumper for variable system generation. The 7 interrupt |
| 70 | request levels of the VMEbus are fully supported from the |
| 71 | SYS68K1CPU-1 B/D. For multi-processing, each IRQ signal can be |
| 72 | enabled/disabled via a jumper field. |
| 73 | |
| 74 | Additionally, the SYS68K1CPU-1 B/D supports the ACFAIL, SYSRESET, |
| 75 | SYSFAIL and SYSCLK signal (16 MHz). |
| 76 | |
| 77 | |
| 78 | TODO: |
| 79 | - Finish 2 x ACIA6850, host and remote interface left, terminal works |
| 80 | - Finish 1 x 68230 Motorola, Parallel Interface / Timer |
| 81 | - Connect Port B to a Centronics printer interface |
| 82 | - Add 1 x Abort Switch |
| 83 | - Add configurable serial connector between ACIA:s and |
| 84 | - Real terminal emulator, ie rs232 "socket" |
| 85 | - Debug console |
| 86 | - Add VME bus driver |
| 87 | |
| 88 | ****************************************************************************/ |
| 89 | |
78 | 90 | #include "emu.h" |
79 | 91 | #include "bus/rs232/rs232.h" |
80 | 92 | #include "cpu/m68000/m68000.h" |
r249094 | r249095 | |
82 | 94 | #include "machine/68230pit.h" |
83 | 95 | #include "machine/6850acia.h" |
84 | 96 | #include "machine/clock.h" |
85 | | #include "bus/centronics/ctronics.h" |
86 | | #include "bus/generic/slot.h" |
87 | | #include "bus/generic/carts.h" |
88 | 97 | |
89 | | #define LOG(x) x |
90 | | |
91 | 98 | #define BAUDGEN_CLOCK XTAL_1_8432MHz |
92 | 99 | /* |
93 | | * The baudrate on the Force68k CPU-1 to CPU-6 is generated by a |
94 | | * Motorola 14411 bitrate generator, the CPU-6 documents matches the circuits |
95 | | * that I could find on the CPU-1 board. Here how I calculated the clock for |
96 | | * the factory settings. No need to add selectors until terminal.c supports |
97 | | * configurable baudrates. Fortunality CPU-1 was shipped with 9600N8! |
98 | | * |
99 | | * From the documents: |
100 | | * |
101 | | * 3 RS232C interfaces, strap selectable baud rate from 110-9600 or 600-19200 baud |
102 | | * |
103 | | * Default Jumper Settings of B7: |
104 | | * -------------------------------- |
105 | | * GND 10 - 11 RSA input on 14411 |
106 | | * F1 on 14411 1 - 20 Baud selector of the terminal port |
107 | | * F1 on 14411 3 - 18 Baud selector of the host port |
108 | | * F1 on 14411 5 - 16 Baud selector of the remote port |
109 | | * |
110 | | * The RSB input on the 14411 is kept high always so RSA=0, RSB=1 and a 1.8432MHz crystal |
111 | | * generates 153600 on the F1 output pin which by default strapping is connected to all |
112 | | * three 6850 acias on the board. These can be strapped separatelly to speedup downloads. |
113 | | * |
114 | | * The selectable outputs from 14411, F1-F16: |
115 | | * X16 RSA=0,RSB=1: 153600, 115200, 76800, 57600, 38400, 28800, 19200, 9600, 4800, 3200, 2153.3, 1758.8, 1200, 921600, 1843000 |
116 | | * X64 RSA=1,RSB=1: 614400, 460800, 307200, 230400, 153600, 115200, 76800, 57600, 38400, 28800, 19200, 9600, 4800, 921600, 1843000 |
117 | | * |
118 | | * However, the datasheet says baudrate is strapable for 110-9600 but the output is 153600 |
119 | | * so the system rom MUST setup the acia to divide by 16 to generate the correct baudrate. |
120 | | * |
121 | | */ |
| 100 | The baudrate on the Force68k CPU-1 to CPU-6 is generated by a |
| 101 | Motorola 14411 bitrate generator, the CPU-6 documents matches the circuits |
| 102 | that I could find on the CPU-1 board. Here how I calculated the clock for |
| 103 | the factory settings. No need to add selectors until terminal.c supports |
| 104 | configurable baudrates. Fortunality CPU-1 was shipped with 9600N8! |
| 105 | |
| 106 | From the documents: |
| 107 | |
| 108 | 3 RS232C interfaces, strap selectable baud rate from 110-9600 or 600-19200 baud |
| 109 | |
| 110 | Default Jumper Settings of B7: |
| 111 | -------------------------------- |
| 112 | GND 10 - 11 RSA input on 14411 |
| 113 | F1 on 14411 1 - 20 Baud selector of the terminal port |
| 114 | F1 on 14411 3 - 18 Baud selector of the host port |
| 115 | F1 on 14411 5 - 16 Baud selector of the remote port |
| 116 | |
| 117 | The RSB input on the 14411 is kept high always so RSA=0, RSB=1 and a 1.8432MHz crystal |
| 118 | generates 153600 on the F1 output pin which by default strapping is connected to all |
| 119 | three 6850 acias on the board. These can be strapped separatelly to speedup downloads. |
| 120 | |
| 121 | The selectable outputs from 14411, F1-F16: |
| 122 | X16 RSA=0,RSB=1: 153600, 115200, 76800, 57600, 38400, 28800, 19200, 9600, 4800, 3200, 2153.3, 1758.8, 1200, 921600, 1843000 |
| 123 | X64 RSA=1,RSB=1: 614400, 460800, 307200, 230400, 153600, 115200, 76800, 57600, 38400, 28800, 19200, 9600, 4800, 921600, 1843000 |
| 124 | |
| 125 | However, the datasheet says baudrate is strapable for 110-9600 but the output is 153600 |
| 126 | so the system rom MUST setup the acia to divide by 16 to generate the correct baudrate. |
| 127 | |
| 128 | */ |
122 | 129 | #define ACIA_CLOCK (BAUDGEN_CLOCK / 12) |
123 | 130 | |
124 | 131 | class force68k_state : public driver_device |
125 | 132 | { |
126 | 133 | public: |
127 | | force68k_state(const machine_config &mconfig, device_type type, const char *tag) : |
128 | | driver_device (mconfig, type, tag), |
129 | | m_maincpu (*this, "maincpu"), |
130 | | m_rtc (*this, "rtc"), |
131 | | m_pit (*this, "pit"), |
132 | | m_aciahost (*this, "aciahost"), |
133 | | m_aciaterm (*this, "aciaterm"), |
134 | | m_aciaremt (*this, "aciaremt"), |
135 | | m_centronics (*this, "centronics") |
136 | | , m_centronics_ack (0) |
137 | | , m_centronics_busy (0) |
138 | | , m_centronics_perror (0) |
139 | | , m_centronics_select (0) |
140 | | ,m_cart(*this, "exp_rom1") |
141 | | { |
142 | | } |
| 134 | force68k_state(const machine_config &mconfig, device_type type, const char *tag) : |
| 135 | driver_device(mconfig, type, tag), |
| 136 | // m_rtc(*this, "rtc") |
| 137 | m_maincpu(*this, "maincpu"), |
| 138 | m_rtc(*this, "rtc"), |
| 139 | m_pit(*this, "pit"), |
| 140 | m_aciahost(*this, "aciahost"), |
| 141 | m_aciaterm(*this, "aciaterm"), |
| 142 | m_aciaremt(*this, "aciaremt") |
| 143 | { |
| 144 | } |
143 | 145 | |
144 | | DECLARE_READ16_MEMBER (bootvect_r); |
145 | | DECLARE_READ16_MEMBER (vme_a24_r); |
146 | | DECLARE_WRITE16_MEMBER (vme_a24_w); |
147 | | DECLARE_READ16_MEMBER (vme_a16_r); |
148 | | DECLARE_WRITE16_MEMBER (vme_a16_w); |
149 | | virtual void machine_start (); |
150 | | // clocks |
151 | | DECLARE_WRITE_LINE_MEMBER (write_aciahost_clock); |
152 | | DECLARE_WRITE_LINE_MEMBER (write_aciaterm_clock); |
153 | | DECLARE_WRITE_LINE_MEMBER (write_aciaremt_clock); |
154 | | // centronics printer interface |
155 | | DECLARE_WRITE_LINE_MEMBER (centronics_ack_w); |
156 | | DECLARE_WRITE_LINE_MEMBER (centronics_busy_w); |
157 | | DECLARE_WRITE_LINE_MEMBER (centronics_perror_w); |
158 | | DECLARE_WRITE_LINE_MEMBER (centronics_select_w); |
159 | | // User EPROM/SRAM slot(s) |
160 | | int force68k_load_cart(device_image_interface &image, generic_slot_device *slot); |
161 | | DECLARE_DEVICE_IMAGE_LOAD_MEMBER (exp1_load) { return force68k_load_cart(image, m_cart); } |
162 | | DECLARE_READ16_MEMBER (read16_rom); |
| 146 | DECLARE_READ16_MEMBER(bootvect_r); |
| 147 | virtual void machine_start(); |
| 148 | DECLARE_WRITE_LINE_MEMBER(write_aciahost_clock); |
| 149 | DECLARE_WRITE_LINE_MEMBER(write_aciaterm_clock); |
| 150 | DECLARE_WRITE_LINE_MEMBER(write_aciaremt_clock); |
163 | 151 | |
164 | | protected: |
165 | | |
166 | 152 | private: |
167 | | required_device<cpu_device> m_maincpu; |
168 | | required_device<mm58167_device> m_rtc; |
169 | | required_device<pit68230_device> m_pit; |
170 | | required_device<acia6850_device> m_aciahost; |
171 | | required_device<acia6850_device> m_aciaterm; |
172 | | required_device<acia6850_device> m_aciaremt; |
173 | | optional_device<centronics_device> m_centronics; |
| 153 | required_device<cpu_device> m_maincpu; |
| 154 | required_device<mm58167_device> m_rtc; |
| 155 | required_device<pit68230_device> m_pit; |
| 156 | required_device<acia6850_device> m_aciahost; |
| 157 | required_device<acia6850_device> m_aciaterm; |
| 158 | required_device<acia6850_device> m_aciaremt; |
174 | 159 | |
175 | | INT32 m_centronics_ack; |
176 | | INT32 m_centronics_busy; |
177 | | INT32 m_centronics_perror; |
178 | | INT32 m_centronics_select; |
179 | | |
180 | | // Pointer to System ROMs needed by bootvect_r |
181 | | UINT16 *m_sysrom; |
182 | | UINT16 *m_usrrom; |
183 | | |
184 | | required_device<generic_slot_device> m_cart; |
185 | | |
| 160 | // Pointer to System ROMs needed by bootvect_r |
| 161 | UINT16 *m_sysrom; |
186 | 162 | }; |
187 | 163 | |
188 | | static ADDRESS_MAP_START (force68k_mem, AS_PROGRAM, 16, force68k_state) |
189 | | ADDRESS_MAP_UNMAP_HIGH |
190 | | AM_RANGE (0x000000, 0x000007) AM_ROM AM_READ (bootvect_r) /* Vectors mapped from System EPROM */ |
191 | | AM_RANGE (0x000008, 0x01ffff) AM_RAM /* DRAM CPU-1B */ |
192 | | //AM_RANGE (0x020000, 0x07ffff) AM_RAM /* Additional DRAM CPU-1D */ |
193 | | AM_RANGE (0x080000, 0x083fff) AM_ROM /* System EPROM Area 16Kb DEBUGGER supplied as default on CPU-1B/D */ |
194 | | AM_RANGE (0x084000, 0x09ffff) AM_ROM /* System EPROM Area 112Kb additional space for System ROM */ |
195 | | //AM_RANGE (0x0a0000, 0x0bffff) AM_ROM /* User EPROM/SRAM Area, max 128Kb mapped by a cartslot */ |
196 | | AM_RANGE (0x0c0040, 0x0c0041) AM_DEVREADWRITE8 ("aciahost", acia6850_device, status_r, control_w, 0x00ff) |
197 | | AM_RANGE (0x0c0042, 0x0c0043) AM_DEVREADWRITE8 ("aciahost", acia6850_device, data_r, data_w, 0x00ff) |
198 | | AM_RANGE (0x0c0080, 0x0c0081) AM_DEVREADWRITE8 ("aciaterm", acia6850_device, status_r, control_w, 0xff00) |
199 | | AM_RANGE (0x0c0082, 0x0c0083) AM_DEVREADWRITE8 ("aciaterm", acia6850_device, data_r, data_w, 0xff00) |
200 | | AM_RANGE (0x0c0100, 0x0c0101) AM_DEVREADWRITE8 ("aciaremt", acia6850_device, status_r, control_w, 0x00ff) |
201 | | AM_RANGE (0x0c0102, 0x0c0103) AM_DEVREADWRITE8 ("aciaremt", acia6850_device, data_r, data_w, 0x00ff) |
202 | | AM_RANGE (0x0c0400, 0x0c042f) AM_DEVREADWRITE8 ("rtc", mm58167_device, read, write, 0x00ff) |
203 | | AM_RANGE (0x0e0000, 0x0e0035) AM_DEVREADWRITE8 ("pit", pit68230_device, read, write, 0x00ff) |
| 164 | static ADDRESS_MAP_START(force68k_mem, AS_PROGRAM, 16, force68k_state) |
| 165 | ADDRESS_MAP_UNMAP_HIGH |
| 166 | AM_RANGE(0x000000, 0x000007) AM_ROM AM_READ(bootvect_r) /* Vectors mapped from System EPROM */ |
| 167 | AM_RANGE(0x000008, 0x01ffff) AM_RAM /* DRAM */ |
| 168 | AM_RANGE(0x080000, 0x09ffff) AM_ROM /* System EPROM Area */ |
| 169 | // AM_RANGE(0x0a0000, 0x0bffff) AM_ROM /* User EPROM Area */ |
| 170 | AM_RANGE(0x0c0040, 0x0c0041) AM_DEVREADWRITE8("aciahost", acia6850_device, status_r, control_w, 0x00ff) |
| 171 | AM_RANGE(0x0c0042, 0x0c0043) AM_DEVREADWRITE8("aciahost", acia6850_device, data_r, data_w, 0x00ff) |
| 172 | AM_RANGE(0x0c0080, 0x0c0081) AM_DEVREADWRITE8("aciaterm", acia6850_device, status_r, control_w, 0xff00) |
| 173 | AM_RANGE(0x0c0082, 0x0c0083) AM_DEVREADWRITE8("aciaterm", acia6850_device, data_r, data_w, 0xff00) |
| 174 | AM_RANGE(0x0c0100, 0x0c0101) AM_DEVREADWRITE8("aciaremt", acia6850_device, status_r, control_w, 0x00ff) |
| 175 | AM_RANGE(0x0c0102, 0x0c0103) AM_DEVREADWRITE8("aciaremt", acia6850_device, data_r, data_w, 0x00ff) |
| 176 | AM_RANGE(0x0c0400, 0x0c042f) AM_DEVREADWRITE8("rtc", mm58167_device, read, write, 0x00ff) |
| 177 | AM_RANGE(0x0e0000, 0x0e0035) AM_DEVREADWRITE8("pit", pit68230_device, data_r, data_w, 0x00ff) |
204 | 178 | // AM_RANGE(0x0e0200, 0x0e0380) AM_READWRITE(fpu_r, fpu_w) /* optional FPCP 68881 FPU interface */ |
205 | | AM_RANGE(0x100000, 0xfeffff) AM_READWRITE(vme_a24_r, vme_a24_w) /* VMEbus Rev B addresses (24 bits) */ |
206 | | AM_RANGE(0xff0000, 0xffffff) AM_READWRITE(vme_a16_r, vme_a16_w) /* VMEbus Rev B addresses (16 bits) */ |
| 179 | // AM_RANGE(0x100000, 0xfeffff) /* VMEbus Rev B addresses (24 bits) */ |
| 180 | // AM_RANGE(0xff0000, 0xffffff) /* VMEbus Rev B addresses (16 bits) */ |
207 | 181 | ADDRESS_MAP_END |
208 | 182 | |
209 | 183 | /* Input ports */ |
210 | | static INPUT_PORTS_START (force68k) |
| 184 | static INPUT_PORTS_START( force68k ) |
211 | 185 | INPUT_PORTS_END |
212 | 186 | |
213 | | /* |
214 | | * Centronics support |
215 | | * |
216 | | * The system ROMs has support for a parallel printer interface but the signals are just routed to row A |
217 | | * of the VME P2 connector so no on board Centronics connector is available but assumed to be added on a |
218 | | * separate I/O board. After some detective work I found that the ROM works as follows: |
219 | | * |
220 | | * The 'PA' (Printer Attach) command issues a <cr> on Port A and sends a strobe on H2 it then loops over |
221 | | * the select signal, bit 0 on Port B, and the ack signal on HS1, both to be non zero. The support is really |
222 | | * flawed as the strobe signal goes high instead of low ( this might assume an inverting driver on the |
223 | | * P2 board ) and the busy signal is not checked at all. Or I might have assumed it all wrong, but it now |
224 | | * works with the generic centronics printer driver. Need the printer board documentation to improve further. |
225 | | * |
226 | | * When the 'PA' command is successful everything printed to screen is mirrored on the printer. Use the |
227 | | * 'NOPA' command to stop mirroring. I had no printer ROMs so could not test it with a "real" printer. |
228 | | * |
229 | | * Force CPU-1 init sequence for MC68230 PIT |
230 | | * ----------------------------------------- |
231 | | * 0801E6 0E0000 W 00 -> PGCR Mode 0 (uni8), H34 dis, H12 dis, H1234 HZ |
232 | | * 0801E6 0E0002 W 00 -> PSRR PC4, PC5, H1S>H2S>H3S>H4S |
233 | | * 0801E6 0E0004 W FF -> PADDR Port A all Outputs |
234 | | * 0801E6 0E0006 W 00 -> PBDDR Port B all Inputs |
235 | | * 0801EA 0E000C W 60 -> PACR Port A Mode 01, pin def, dbfr H1 data rec, H2 status/int, H2 output neg, H2S clrd |
236 | | * 0801F0 0E000E W A0 -> PBCR Port B mode 1x, H4 output neg, H4S clrd, H3 int dis, H3 edg input, H3S set by assrt edg |
237 | | * 0801F6 0E0000 W 30 -> PGCR H34 enable, H12enable |
238 | | * 0801FC 0E000E W A8 -> PBCR +H4 asserted |
239 | | * 08020A 0E000E W A0 -> PBCR +H4 negated |
240 | | * |
241 | | * Upon PA (Printer Attach) command enabling the Centronics printer mode |
242 | | * --------------------------------------------------------------------- |
243 | | * 081DB4 0E0011 W D0 -> PADR Data to Port A |
244 | | * 081DB8 0E000D W 68 -> PACR H2 output asserted Centronics Strobe |
245 | | * 081DC0 0E000D W 60 -> PACR H2 output negated |
246 | | * 081DD0 0E0013 R 00 <- PBDR Port B polled for 01 (data) & 03 (mask) |
247 | | * |
248 | | */ |
249 | | |
250 | | /* Centronics ACK handler |
251 | | * The centronics ack signal is expected by the ROM to arrive at H1 input line |
252 | | */ |
253 | | WRITE_LINE_MEMBER (force68k_state::centronics_ack_w) |
| 187 | void force68k_state::machine_start() |
254 | 188 | { |
255 | | // LOG (logerror ("centronics_ack_w(%d) %lld\n", state, m_maincpu->total_cycles ())); |
256 | | m_centronics_ack = state; |
257 | | m_pit->h1_set (state); |
| 189 | m_sysrom = (UINT16*)(memregion("maincpu")->base() + 0x080000); |
258 | 190 | } |
259 | 191 | |
260 | | /* Centronics BUSY handler |
261 | | * The centronics busy signal is not used by the ROM driver afaik |
262 | | */ |
263 | | WRITE_LINE_MEMBER (force68k_state::centronics_busy_w){ |
264 | | // LOG (logerror ("centronics_busy_w(%d) %lld\n", state, m_maincpu->total_cycles ())); |
265 | | m_centronics_busy = state; |
| 192 | READ16_MEMBER(force68k_state::bootvect_r) |
| 193 | { |
| 194 | return m_sysrom[offset]; |
266 | 195 | } |
267 | 196 | |
268 | | /* Centronics PERROR handler |
269 | | * The centronics perror signal is not used by the ROM driver afaik |
270 | | */ |
271 | | WRITE_LINE_MEMBER (force68k_state::centronics_perror_w){ |
272 | | // LOG (logerror ("centronics_perror_w(%d) %lld\n", state, m_maincpu->total_cycles ())); |
273 | | m_centronics_perror = state; |
| 197 | WRITE_LINE_MEMBER(force68k_state::write_aciahost_clock) |
| 198 | { |
| 199 | m_aciahost->write_txc(state); |
| 200 | m_aciahost->write_rxc(state); |
274 | 201 | } |
275 | 202 | |
276 | | /* Centronics SELECT handler |
277 | | * The centronics select signal is expected by the ROM on Port B bit 0 |
278 | | */ |
279 | | WRITE_LINE_MEMBER (force68k_state::centronics_select_w){ |
280 | | // LOG (logerror ("centronics_select_w(%d) %lld\n", state, m_maincpu->total_cycles ())); |
281 | | m_centronics_select = state; |
282 | | m_pit->portb_setbit (0, state); |
283 | | } |
284 | | |
285 | | /* Start it up */ |
286 | | void force68k_state::machine_start () |
| 203 | WRITE_LINE_MEMBER(force68k_state::write_aciaterm_clock) |
287 | 204 | { |
288 | | LOG (logerror ("machine_start\n")); |
289 | | |
290 | | save_item (NAME (m_centronics_busy)); |
291 | | save_item (NAME (m_centronics_ack)); |
292 | | save_item (NAME (m_centronics_select)); |
293 | | save_item (NAME (m_centronics_perror)); |
294 | | |
295 | | /* Setup pointer to bootvector in ROM for bootvector handler bootvect_r */ |
296 | | m_sysrom = (UINT16*)(memregion ("maincpu")->base () + 0x080000); |
297 | | |
298 | | /* Map user ROM/RAM socket(s) */ |
299 | | if (m_cart->exists()) |
300 | | { |
301 | | m_usrrom = (UINT16*)m_cart->get_rom_base(); |
302 | | #if 0 // This should be the correct way but produces odd and even bytes swapped |
303 | | m_maincpu->space(AS_PROGRAM).install_read_handler(0xa0000, 0xbffff, read16_delegate(FUNC(generic_slot_device::read16_rom), (generic_slot_device*)m_cart)); |
304 | | #else // So we installs a custom very ineffecient handler for now until we understand hwp to solve the problem better |
305 | | m_maincpu->space(AS_PROGRAM).install_read_handler(0xa0000, 0xbffff, read16_delegate(FUNC(force68k_state::read16_rom), this)); |
306 | | #endif |
307 | | } |
| 205 | m_aciaterm->write_txc(state); |
| 206 | m_aciaterm->write_rxc(state); |
308 | 207 | } |
309 | 208 | |
310 | | /* A very ineffecient User cart emulation of two 8 bit sockets (odd and even) */ |
311 | | READ16_MEMBER (force68k_state::read16_rom){ |
312 | | offset = offset % m_cart->common_get_size("rom"); // Don't read outside buffer... |
313 | | return ((m_usrrom [offset] << 8) & 0xff00) | ((m_usrrom [offset] >> 8) & 0x00ff); |
314 | | } |
315 | | |
316 | | /* Boot vector handler, the PCB hardwires the first 8 bytes from 0x80000 to 0x0 */ |
317 | | READ16_MEMBER (force68k_state::bootvect_r){ |
318 | | return m_sysrom [offset]; |
319 | | } |
320 | | |
321 | | /* 10. The VMEbus (text from board documentation) |
322 | | * --------------- |
323 | | * The implemented VMEbus Interface includes 24 address, 16 data, |
324 | | * 6 address modifier and the asynchronous control signals. |
325 | | * A single level bus arbiter is provided to build multi master |
326 | | * systems. In addition to the bus arbiter, a separate slave bus |
327 | | * arbitration allows selection of the arbitration level (0-3). |
328 | | * |
329 | | * The address modifier range .,Short 110 Access« can be selected |
330 | | * via a jumper for variable system generation. The 7 interrupt |
331 | | * request levels of the VMEbus are fully supported from the |
332 | | * SYS68K1CPU-1 B/D. For multi-processing, each IRQ signal can be |
333 | | * enabled/disabled via a jumper field. |
334 | | * |
335 | | * Additionally, the SYS68K1CPU-1 B/D supports the ACFAIL, SYSRESET, |
336 | | * SYSFAIL and SYSCLK signal (16 MHz). |
337 | | */ |
338 | | |
339 | | /* Dummy VME access methods until the VME bus device is ready for use */ |
340 | | READ16_MEMBER (force68k_state::vme_a24_r){ |
341 | | LOG (logerror ("vme_a24_r\n")); |
342 | | return (UINT16) 0; |
343 | | } |
344 | | |
345 | | WRITE16_MEMBER (force68k_state::vme_a24_w){ |
346 | | LOG (logerror ("vme_a24_w\n")); |
347 | | } |
348 | | |
349 | | READ16_MEMBER (force68k_state::vme_a16_r){ |
350 | | LOG (logerror ("vme_16_r\n")); |
351 | | return (UINT16) 0; |
352 | | } |
353 | | |
354 | | WRITE16_MEMBER (force68k_state::vme_a16_w){ |
355 | | LOG (logerror ("vme_a16_w\n")); |
356 | | } |
357 | | |
358 | | /* |
359 | | * Serial port clock sources can all be driven by different outputs of the 14411 |
360 | | */ |
361 | | WRITE_LINE_MEMBER (force68k_state::write_aciahost_clock){ |
362 | | m_aciahost->write_txc (state); |
363 | | m_aciahost->write_rxc (state); |
364 | | } |
365 | | |
366 | | WRITE_LINE_MEMBER (force68k_state::write_aciaterm_clock){ |
367 | | m_aciaterm->write_txc (state); |
368 | | m_aciaterm->write_rxc (state); |
369 | | } |
370 | | |
371 | | WRITE_LINE_MEMBER (force68k_state::write_aciaremt_clock){ |
372 | | m_aciaremt->write_txc (state); |
373 | | m_aciaremt->write_rxc (state); |
374 | | } |
375 | | |
376 | | /* |
377 | | * 4. The USER Area (Text from the board manual) |
378 | | The USER area contains two 28 pin sockets with JEDEC compatible pin out. |
379 | | To allow the usage of static RAM's, the access to the USER area is byte |
380 | | oriented. Table 3. lists the usable device types. |
381 | | |
382 | | Bits Bytes EPROM SRAM |
383 | | -------------------------- |
384 | | 2Kx16 4 Kbyte 2716 6116 |
385 | | 4Kx16 8 Kbyte 2732 |
386 | | 8Kx16 16 Kbyte 2764 6264 |
387 | | 16Kx16 32 Kbyte 27128 |
388 | | 32Kx16 64 Kbyte 27256 |
389 | | -------------------------- |
390 | | */ |
391 | | // Implementation of static 2 x 64K EPROM in sockets J10/J11 as 16 bit wide cartridge for easier |
392 | | // software handling. TODO: make configurable according to table above. |
393 | | static MACHINE_CONFIG_FRAGMENT( fccpu1_eprom_sockets ) |
394 | | MCFG_GENERIC_CARTSLOT_ADD("exp_rom1", generic_plain_slot, "fccpu1_cart") |
395 | | MCFG_GENERIC_EXTENSIONS("bin,rom") |
396 | | MCFG_GENERIC_WIDTH(GENERIC_ROM16_WIDTH) |
397 | | MCFG_GENERIC_ENDIAN(ENDIANNESS_BIG) |
398 | | MCFG_GENERIC_LOAD(force68k_state, exp1_load) |
399 | | // MCFG_SOFTWARE_LIST_ADD("cart_list", "fccpu1_cart") |
400 | | MACHINE_CONFIG_END |
401 | | |
402 | | /*************************** |
403 | | Rom loading functions |
404 | | ****************************/ |
405 | | int force68k_state::force68k_load_cart(device_image_interface &image, generic_slot_device *slot) |
| 209 | WRITE_LINE_MEMBER(force68k_state::write_aciaremt_clock) |
406 | 210 | { |
407 | | UINT32 size = slot->common_get_size("rom"); |
408 | | |
409 | | if (size > 0x20000) // Max 128Kb |
410 | | { |
411 | | LOG( printf("Cartridge size exceeding max size (128Kb): %d\n", size) ); |
412 | | image.seterror(IMAGE_ERROR_UNSPECIFIED, "Cartridge size exceeding max size (128Kb)"); |
413 | | return IMAGE_INIT_FAIL; |
414 | | } |
415 | | |
416 | | slot->rom_alloc(size, GENERIC_ROM16_WIDTH, ENDIANNESS_BIG); |
417 | | slot->common_load_rom(slot->get_rom_base(), size, "rom"); |
418 | | |
419 | | return IMAGE_INIT_PASS; |
| 211 | m_aciaremt->write_txc(state); |
| 212 | m_aciaremt->write_rxc(state); |
420 | 213 | } |
421 | 214 | |
422 | | /* |
423 | | * Machine configuration |
424 | | */ |
425 | | static MACHINE_CONFIG_START (fccpu1, force68k_state) |
426 | | /* basic machine hardware */ |
427 | | MCFG_CPU_ADD ("maincpu", M68000, XTAL_16MHz / 2) |
428 | | MCFG_CPU_PROGRAM_MAP (force68k_mem) |
| 215 | static MACHINE_CONFIG_START( fccpu1, force68k_state ) |
| 216 | /* basic machine hardware */ |
| 217 | MCFG_CPU_ADD("maincpu", M68000, XTAL_16MHz / 2) |
| 218 | MCFG_CPU_PROGRAM_MAP(force68k_mem) |
429 | 219 | |
430 | | /* P3/Host Port config |
431 | | * LO command causes ROM monitor to expect S-records on HOST port by default |
432 | | * Implementation through nullmodem currently does not support handshakes so |
433 | | * the ROM momitor is over-run while checking for checksums etc if used with |
434 | | * UI mount <file> feature. |
435 | | */ |
436 | | MCFG_DEVICE_ADD ("aciahost", ACIA6850, 0) |
| 220 | /* P3/Host Port config */ |
| 221 | MCFG_DEVICE_ADD("aciahost", ACIA6850, 0) |
| 222 | MCFG_DEVICE_ADD("aciahost_clock", CLOCK, ACIA_CLOCK) |
| 223 | MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(force68k_state, write_aciahost_clock)) |
437 | 224 | |
438 | | MCFG_ACIA6850_TXD_HANDLER (DEVWRITELINE ("rs232host", rs232_port_device, write_txd)) |
439 | | MCFG_ACIA6850_RTS_HANDLER (DEVWRITELINE ("rs232host", rs232_port_device, write_rts)) |
| 225 | /* P4/Terminal Port config */ |
| 226 | MCFG_DEVICE_ADD("aciaterm", ACIA6850, 0) |
440 | 227 | |
441 | | MCFG_RS232_PORT_ADD ("rs232host", default_rs232_devices, "null_modem") |
442 | | MCFG_RS232_RXD_HANDLER (DEVWRITELINE ("aciahost", acia6850_device, write_rxd)) |
443 | | MCFG_RS232_CTS_HANDLER (DEVWRITELINE ("aciahost", acia6850_device, write_cts)) |
| 228 | MCFG_ACIA6850_TXD_HANDLER(DEVWRITELINE("rs232trm", rs232_port_device, write_txd)) |
| 229 | MCFG_ACIA6850_RTS_HANDLER(DEVWRITELINE("rs232trm", rs232_port_device, write_rts)) |
444 | 230 | |
445 | | MCFG_DEVICE_ADD ("aciahost_clock", CLOCK, ACIA_CLOCK) |
446 | | MCFG_CLOCK_SIGNAL_HANDLER (WRITELINE (force68k_state, write_aciahost_clock)) |
| 231 | MCFG_RS232_PORT_ADD("rs232trm", default_rs232_devices, "terminal") |
| 232 | MCFG_RS232_RXD_HANDLER(DEVWRITELINE("aciaterm", acia6850_device, write_rxd)) |
| 233 | MCFG_RS232_CTS_HANDLER(DEVWRITELINE("aciaterm", acia6850_device, write_cts)) |
447 | 234 | |
448 | | /* P4/Terminal Port config */ |
449 | | MCFG_DEVICE_ADD ("aciaterm", ACIA6850, 0) |
| 235 | MCFG_DEVICE_ADD("aciaterm_clock", CLOCK, ACIA_CLOCK) |
| 236 | MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(force68k_state, write_aciaterm_clock)) |
450 | 237 | |
451 | | MCFG_ACIA6850_TXD_HANDLER (DEVWRITELINE ("rs232trm", rs232_port_device, write_txd)) |
452 | | MCFG_ACIA6850_RTS_HANDLER (DEVWRITELINE ("rs232trm", rs232_port_device, write_rts)) |
| 238 | /* P5/Remote Port config */ |
| 239 | MCFG_DEVICE_ADD("aciaremt", ACIA6850, 0) |
453 | 240 | |
454 | | MCFG_RS232_PORT_ADD ("rs232trm", default_rs232_devices, "terminal") |
455 | | MCFG_RS232_RXD_HANDLER (DEVWRITELINE ("aciaterm", acia6850_device, write_rxd)) |
456 | | MCFG_RS232_CTS_HANDLER (DEVWRITELINE ("aciaterm", acia6850_device, write_cts)) |
| 241 | #define PRINTER 0 |
| 242 | #if PRINTER |
| 243 | MCFG_ACIA6850_TXD_HANDLER(DEVWRITELINE("rs232rmt", rs232_port_device, write_txd)) |
| 244 | MCFG_ACIA6850_RTS_HANDLER(DEVWRITELINE("rs232rmt", rs232_port_device, write_rts)) |
457 | 245 | |
458 | | MCFG_DEVICE_ADD ("aciaterm_clock", CLOCK, ACIA_CLOCK) |
459 | | MCFG_CLOCK_SIGNAL_HANDLER (WRITELINE (force68k_state, write_aciaterm_clock)) |
| 246 | MCFG_RS232_PORT_ADD("rs232rmt", default_rs232_devices, "printer") |
| 247 | MCFG_RS232_RXD_HANDLER(DEVWRITELINE("aciaremt", acia6850_device, write_rxd)) |
| 248 | MCFG_RS232_CTS_HANDLER(DEVWRITELINE("aciaremt", acia6850_device, write_cts)) |
| 249 | #endif |
460 | 250 | |
461 | | /* P5/Remote Port config */ |
462 | | MCFG_DEVICE_ADD ("aciaremt", ACIA6850, 0) |
| 251 | MCFG_DEVICE_ADD("aciaremt_clock", CLOCK, ACIA_CLOCK) |
| 252 | MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(force68k_state, write_aciaterm_clock)) |
463 | 253 | |
464 | | MCFG_DEVICE_ADD ("aciaremt_clock", CLOCK, ACIA_CLOCK) |
465 | | MCFG_CLOCK_SIGNAL_HANDLER (WRITELINE (force68k_state, write_aciaterm_clock)) |
| 254 | /* RTC Real Time Clock device */ |
| 255 | MCFG_DEVICE_ADD("rtc", MM58167, XTAL_32_768kHz) |
466 | 256 | |
467 | | /* RTC Real Time Clock device */ |
468 | | MCFG_DEVICE_ADD ("rtc", MM58167, XTAL_32_768kHz) |
| 257 | /* PIT Parallel Interface and Timer device, assuming strapped for on board clock */ |
| 258 | MCFG_DEVICE_ADD("pit", PIT68230, XTAL_16MHz / 2) |
469 | 259 | |
470 | | /* PIT Parallel Interface and Timer device, assuming strapped for on board clock */ |
471 | | MCFG_DEVICE_ADD ("pit", PIT68230, XTAL_16MHz / 2) |
472 | | MCFG_PIT68230_PA_OUTPUT_CALLBACK (DEVWRITE8 ("cent_data_out", output_latch_device, write)) |
473 | | MCFG_PIT68230_H2_CALLBACK (DEVWRITELINE ("centronics", centronics_device, write_strobe)) |
| 260 | MACHINE_CONFIG_END |
474 | 261 | |
475 | | // centronics |
476 | | MCFG_CENTRONICS_ADD ("centronics", centronics_devices, "printer") |
477 | | MCFG_CENTRONICS_ACK_HANDLER (WRITELINE (force68k_state, centronics_ack_w)) |
478 | | MCFG_CENTRONICS_BUSY_HANDLER (WRITELINE (force68k_state, centronics_busy_w)) |
479 | | MCFG_CENTRONICS_PERROR_HANDLER (WRITELINE (force68k_state, centronics_perror_w)) |
480 | | MCFG_CENTRONICS_SELECT_HANDLER (WRITELINE (force68k_state, centronics_select_w)) |
481 | | MCFG_CENTRONICS_OUTPUT_LATCH_ADD ("cent_data_out", "centronics") |
| 262 | #if 0 |
482 | 263 | |
483 | | // EPROM sockets |
484 | | MCFG_FRAGMENT_ADD(fccpu1_eprom_sockets) |
| 264 | static MACHINE_CONFIG_START( fccpu6, force68k_state ) |
| 265 | MCFG_CPU_ADD("maincpu", M68000, XTAL_8MHz) /* Jumper B10 Mode B */ |
| 266 | MCFG_CPU_PROGRAM_MAP(force68k_mem) |
485 | 267 | MACHINE_CONFIG_END |
486 | 268 | |
487 | | #if 0 /* |
488 | | * CPU-6 family is device and adressmap compatible with CPU-1 but with additions |
489 | | * such as an optional 68881 FPU |
490 | | */ |
491 | | static MACHINE_CONFIG_START (fccpu6, force68k_state) |
492 | | MCFG_CPU_ADD ("maincpu", M68000, XTAL_8MHz) /* Jumper B10 Mode B */ |
493 | | MCFG_CPU_PROGRAM_MAP (force68k_mem) |
| 269 | static MACHINE_CONFIG_START( fccpu6a, force68k_state ) |
| 270 | MCFG_CPU_ADD("maincpu", M68000, XTAL_12_5MHz) /* Jumper B10 Mode A */ |
| 271 | MCFG_CPU_PROGRAM_MAP(force68k_mem) |
494 | 272 | MACHINE_CONFIG_END |
495 | 273 | |
496 | | static MACHINE_CONFIG_START (fccpu6a, force68k_state) |
497 | | MCFG_CPU_ADD ("maincpu", M68000, XTAL_12_5MHz) /* Jumper B10 Mode A */ |
498 | | MCFG_CPU_PROGRAM_MAP (force68k_mem) |
| 274 | static MACHINE_CONFIG_START( fccpu6v, force68k_state ) |
| 275 | MCFG_CPU_ADD("maincpu", M68010, XTAL_8MHz) /* Jumper B10 Mode B */ |
| 276 | MCFG_CPU_PROGRAM_MAP(force68k_mem) |
499 | 277 | MACHINE_CONFIG_END |
500 | 278 | |
501 | | static MACHINE_CONFIG_START (fccpu6v, force68k_state) |
502 | | MCFG_CPU_ADD ("maincpu", M68010, XTAL_8MHz) /* Jumper B10 Mode B */ |
503 | | MCFG_CPU_PROGRAM_MAP (force68k_mem) |
| 279 | static MACHINE_CONFIG_START( fccpu6va, force68k_state ) |
| 280 | MCFG_CPU_ADD("maincpu", M68010, XTAL_12_5MHz) /* Jumper B10 Mode A */ |
| 281 | MCFG_CPU_PROGRAM_MAP(force68k_mem) |
504 | 282 | MACHINE_CONFIG_END |
505 | 283 | |
506 | | static MACHINE_CONFIG_START (fccpu6va, force68k_state) |
507 | | MCFG_CPU_ADD ("maincpu", M68010, XTAL_12_5MHz) /* Jumper B10 Mode A */ |
508 | | MCFG_CPU_PROGRAM_MAP (force68k_mem) |
| 284 | static MACHINE_CONFIG_START( fccpu6vb, force68k_state ) |
| 285 | MCFG_CPU_ADD("maincpu", M68010, XTAL_12_5MHz) /* Jumper B10 Mode A */ |
| 286 | MCFG_CPU_PROGRAM_MAP(force68k_mem) |
509 | 287 | MACHINE_CONFIG_END |
510 | | |
511 | | static MACHINE_CONFIG_START (fccpu6vb, force68k_state) |
512 | | MCFG_CPU_ADD ("maincpu", M68010, XTAL_12_5MHz) /* Jumper B10 Mode A */ |
513 | | MCFG_CPU_PROGRAM_MAP (force68k_mem) |
514 | | MACHINE_CONFIG_END |
515 | 288 | #endif |
516 | 289 | |
517 | 290 | /* ROM definitions */ |
518 | | ROM_START (fccpu1) |
519 | | ROM_REGION (0x1000000, "maincpu", 0) |
| 291 | ROM_START( fccpu1 ) |
| 292 | ROM_REGION(0x1000000, "maincpu", 0) |
520 | 293 | |
521 | | ROM_LOAD16_BYTE ("fccpu1V1.0L.j8.bin", 0x080001, 0x2000, CRC (3ac6f08f) SHA1 (502f6547b508d8732bd68bbbb2402d8c30fefc3b)) |
522 | | ROM_LOAD16_BYTE ("fccpu1V1.0L.j9.bin", 0x080000, 0x2000, CRC (035315fb) SHA1 (90dc44d9c25d28428233e6846da6edce2d69e440)) |
523 | | |
524 | | /* |
525 | | * System ROM terminal commands |
526 | | * |
527 | | * COMMAND SUMMARY DESCRIPTION (From CPU-1B datasheet, ROMs were dumped |
528 | | * from a CPU-1 board so some features might be missing or different) |
529 | | * --------------------------------------------------------------------------- |
530 | | * BF <address1> <address2> <data> <CR> Block Fill memory - from addr1 through addr2 with data |
531 | | * BM <address1> <address2> <address 3> <CR> Block Move - move from addr1 through addr2to addr3 |
532 | | * BR [<address> [; <count>] ... ] <CR> Set/display Breakpoint |
533 | | * BS <address1> <address2> <data> <CR> Block Search - search addr1 through addr2 for data |
534 | | * BT <address1> <address2> <CR> Block Test of memory |
535 | | * DC <expression> <CR> Data Conversion |
536 | | * DF <CR> Display Formatted registers |
537 | | * DU [n] <address1> <address2>[<string>] <CR> Dump memory to object file |
538 | | * GO or G [<address] <CR> Execute program. |
539 | | * GD [<address] <CR> Go Direct |
540 | | * GT <address> <CR> Exec prog: temporary breakpoint |
541 | | * HE<CR> Help; display monitor commands |
542 | | * LO [n] [;<options] <CR> Load Object file |
543 | | * MD <address> [<count>] <CR> Memory Display |
544 | | * MM or M <address> [<data<][;<options>] <CR> Memory Modify |
545 | | * MS <address> <data1 > <data2> < ... <CR> Memory Set - starting at addr with data 1. data 2 ... |
546 | | * NOBR [<address> ... ] <CR> Remove Breakpoint |
547 | | * NOPA <CR> Printer Detach (Centronics on PIT/P2) |
548 | | * OF <CR> Offset |
549 | | * PA <CR> Printer Attach (Centronics on PIT/P2) |
550 | | * PF[n] <CR> Set/display Port Format |
551 | | * RM <CR> Register Modify |
552 | | * TM [<exit character>] <CR> Transparent Mode |
553 | | * TR OR T [<count] <CR> Trace |
554 | | * TT <address> <CR> Trace: temporary breakpoint |
555 | | * VE [n] [<string] <CR> Verify memory/object file |
556 | | * ---------------------------------------------------------------------------- |
557 | | * .AO - .A7 [<expression] <CR> Display/set address register |
558 | | * .00 - .07 [<expression] <CR> Display/set data register |
559 | | * .RO - .R6 [<expression] <CR> Display/set offset register |
560 | | * .PC [<expression] <CR> Display/set program counter |
561 | | * .SR [<expression] <CR> Display/set status register |
562 | | * .SS [<expression] <CR> Display/set supervisor stack |
563 | | * .US [<expression] <CR> Display/set user stack |
564 | | * ---------------------------------------------------------------------------- |
565 | | * MD <address> [<count>]; DI <CR> Disassemble memory location |
566 | | * MM <address>; DI <CR> Disassemble/Assemble memory location |
567 | | * ---------------------------------------------------------------------------- |
568 | | * Undocumented commands found in ROM table at address 0x80308 |
569 | | * .* No WHAT message displayed, no action seen. |
570 | | */ |
| 294 | ROM_LOAD16_BYTE( "fccpu1V1.0L.j8.bin", 0x080001, 0x2000, CRC(3ac6f08f) SHA1(502f6547b508d8732bd68bbbb2402d8c30fefc3b) ) |
| 295 | ROM_LOAD16_BYTE( "fccpu1V1.0L.j9.bin", 0x080000, 0x2000, CRC(035315fb) SHA1(90dc44d9c25d28428233e6846da6edce2d69e440) ) |
| 296 | /* COMMAND SUMMARY DESCRIPTION (From CPU-1B datasheet, ROMs were dumped |
| 297 | from a CPU-1 board so some features might be missing or different) |
| 298 | --------------------------------------------------------------------------- |
| 299 | BF <address1> <address2> <data> <CR> Block Fill memory - from addr1 through addr2 with data |
| 300 | BM <address1> <address2> <address 3> <CR> Block Move - move from addr1 through addr2to addr3 |
| 301 | BR [<address> [; <count>] ... ] <CR> Set/display Breakpoint |
| 302 | BS <address1> <address2> <data> <CR> Block Search - search addr1 through addr2 for data |
| 303 | BT <address1> <address2> <CR> Block Test of memory |
| 304 | DC <expression> <CR> Data Conversion |
| 305 | DF <CR> Display Formatted registers |
| 306 | DU [n] <address1> <address2>[<string>] <CR> Dump memory to object file |
| 307 | GO [<address] <CR> Execute program |
| 308 | GD [<address] <CR> Go Direct |
| 309 | GT <address> <CR> Exec prog: temporary breakpoint |
| 310 | HE<CR> Help; display monitor commands |
| 311 | LO [n] [;<options] <CR> Load Object file |
| 312 | MD <address> [<count?? <CR> Memory Display |
| 313 | MM <address> [<data?? [;<options?? <CR> Memory Modify |
| 314 | MS <address> <data1 > <data2> < ... <CR> Memory Set - starting at addr with data 1. data 2 ... |
| 315 | NOBR [<address> ... ] <CR> Remove Breakpoint |
| 316 | NOPA <CR> Printer Detach (Centronics on PIT/P2) |
| 317 | OF <CR> Offset |
| 318 | PA <CR> Printer Attach (Centronics on PIT/P2) |
| 319 | PF[n] <CR> Set/display Port Format |
| 320 | RM <CR> Register Modify |
| 321 | TM [<exit character?? <CR> Transparent Mode |
| 322 | TR [<count] <CR> Trace |
| 323 | TT <address> <CR> Trace: temporary breakpoint |
| 324 | VE [n] [<string] <CR> Verify memory/object file |
| 325 | ---------------------------------------------------------------------------- |
| 326 | .AO - .A7 [<expression] <CR> Display/set address register |
| 327 | .00 - .07 [<expression] <CR> Display/set data register |
| 328 | .RO - .R6 [<expression] <CR> Display/set offset register |
| 329 | .PC [<expression] <CR> Display/set program counter |
| 330 | .SR [<expression] <CR> Display/set status register |
| 331 | .SS [<expression] <CR> Display/set supervisor stack |
| 332 | .US [<expression] <CR> Display/set user stack |
| 333 | ---------------------------------------------------------------------------- |
| 334 | MD <address> [<count>]; D1 <CR> Disassemble memory location |
| 335 | MM <address>; DI <CR> Disassemble/Assemble memory location |
| 336 | ---------------------------------------------------------------------------- |
| 337 | */ |
571 | 338 | ROM_END |
572 | 339 | |
573 | | /* |
574 | | * CPU-6 ROMs were generally based om VMEPROM which contained the PDOS RTOS from Eyring Research. |
575 | | * I don't have these but if anyone can dump them and send to me I can verify that they work as expected. |
576 | | */ |
577 | 340 | #if 0 |
578 | | ROM_START (fccpu6) |
579 | | ROM_REGION (0x1000000, "maincpu", 0) |
| 341 | ROM_START( fccpu6 ) |
| 342 | ROM_REGION(0x1000000, "maincpu", 0) |
580 | 343 | ROM_END |
581 | 344 | |
582 | | ROM_START (fccpu6a) |
583 | | ROM_REGION (0x1000000, "maincpu", 0) |
| 345 | ROM_START( fccpu6a ) |
| 346 | ROM_REGION(0x1000000, "maincpu", 0) |
584 | 347 | ROM_END |
585 | 348 | |
586 | | ROM_START (fccpu6v) |
587 | | ROM_REGION (0x1000000, "maincpu", 0) |
| 349 | ROM_START( fccpu6v ) |
| 350 | ROM_REGION(0x1000000, "maincpu", 0) |
588 | 351 | ROM_END |
589 | 352 | |
590 | | ROM_START (fccpu6va) |
591 | | ROM_REGION (0x1000000, "maincpu", 0) |
| 353 | ROM_START( fccpu6va ) |
| 354 | ROM_REGION(0x1000000, "maincpu", 0) |
592 | 355 | ROM_END |
593 | 356 | |
594 | | ROM_START (fccpu6vb) |
595 | | ROM_REGION (0x1000000, "maincpu", 0) |
| 357 | ROM_START( fccpu6vb ) |
| 358 | ROM_REGION(0x1000000, "maincpu", 0) |
596 | 359 | ROM_END |
597 | 360 | #endif |
598 | 361 | |
trunk/src/mess/drivers/mzr8105.c
r0 | r249095 | |
| 1 | // license:BSD-3-Clause |
| 2 | // copyright-holders:Joakim Larsson Edstr??m |
| 3 | /*************************************************************************** |
| 4 | * |
| 5 | * Mizar VME8105 rev D 3U SBC driver, initially derived from force68k.c |
| 6 | * |
| 7 | * 19/08/2015 |
| 8 | * |
| 9 | * I baught this board from http://www.retrotechnology.com without documentation. |
| 10 | * It has a Motorola 68000 CPU @ 10MHz and two 27128 EPROMS with OS9 DEBUG labels |
| 11 | * and not much more except 16 or so TTLs, 2 PALs and a VME P1 connector. It is a |
| 12 | * 2 sided design so it shold be possible to trace the schematics quite easily. |
| 13 | * There is a date on the P1 Connector: "Feb 20 1987" |
| 14 | * |
| 15 | * || |
| 16 | * || |
| 17 | * || |
| 18 | * || |
| 19 | * ||____________________________________________________________ ___ |
| 20 | * || --------------K2|U6-7432|U7-7474|U14-7405|U21-74645 | |_| | |
| 21 | * || | 2764 - low |-+-------+-------+--------+-----------+ | | | |
| 22 | * || | OS9 DEBUG U4| +---------+ +--------+---------+ | | | |
| 23 | * || -------------- | | |U13-7474|U20-74645| | | | |
| 24 | * || ______________ | | +--------+---------+ | | | |
| 25 | * || | | | | ______________K4____ | | | |
| 26 | * || | U3| | | |U12-7438|U19-74244| | |VME| |
| 27 | * || -------------- | |+------K6---------K3---+ | | | |
| 28 | * || ______________ | ||U11-PAL20L10|U18-74244| | |P1 | |
| 29 | * || | 2764 - high | | |+-----021102-+---------+ | | | |
| 30 | * || | OS9 DEBUG U2| |MC68000L10+------------+---------+ | | | |
| 31 | * || |______________| | ||U10-PAL14L4 |U17-74244| | | | |
| 32 | * || | |+-----021001-+---------+ | | | |
| 33 | * || -------------- | |+----+_______|U16-74244|+--+| | | |
| 34 | * || | | | |XTAL |U9-7410+---------+| || | | |
| 35 | * ||K1 | U1| | |FOX100-------+---------+|K5||_| | |
| 36 | * || -------------- |_________|10MHz|U8-7404|U15-74148|| || |___| |
| 37 | * ||--||--------------------------------+----+-------+---------++--+ |
| 38 | * ||--|| |
| 39 | * || |
| 40 | * |
| 41 | * PAL:s |
| 42 | *------ |
| 43 | * The board has two PAL:s, a PAL20L10 and a PAL14L4. |
| 44 | * |
| 45 | * _____ _____ |
| 46 | * OD/CLK 1 |* \_/ | 20 VCC |
| 47 | * CPU A13 I0 2 | | 19 O0/LR A23 |
| 48 | * U9 7410p12 I1 3 | | 18 O1/A0 A22 |
| 49 | * CPU *AS I2 4 | | 17 02/A1 U2/U4 2764p22 *OE |
| 50 | * GND I3 5 | | 16 03/A2 U11 PAL20L10p6 I4 |
| 51 | * CPU A14 I4 6 | U10 | 15 A0/O0 U11 PAL20L10p7 I5 |
| 52 | * CPU A15 I5 7 | PAL14L4 | 14 A1/O1 U19 74LS244p11 I0b |
| 53 | * CPU A16 I6 8 | | 13 A2/O2 A18 |
| 54 | * CPU A17 I7 9 | | 12 LR/O3 A20 |
| 55 | * GND 10 |_____________| 11 CLK/OD A21 |
| 56 | * |
| 57 | * _____ _____ |
| 58 | * OD/CLK 1 |* \_/ | 24 VCC |
| 59 | * I0 2 | | 23 O0/LR |
| 60 | * CPU *AS I1 3 | | 22 O1/A0 |
| 61 | * U10 PAL14L4p3 I2 4 | | 21 02/A1 |
| 62 | * I3 5 | | 20 03/A2 |
| 63 | * U10 PAL14L4p16 I4 6 | U10 | 19 04/NC |
| 64 | * U10 PAL14L4p15 I5 7 | PAL20L10 | 18 NC/O0 |
| 65 | * I6 8 | | 17 A2/O1 |
| 66 | * I7 9 | | 16 A1/O2 |
| 67 | * I8 10 | | 15 A0/O3 |
| 68 | * I9 11 | | 14 LR/O4 |
| 69 | * GND 12 |_____________| 13 CLK/OD |
| 70 | * |
| 71 | * Trace is not fully completed and validated. |
| 72 | * |
| 73 | * History of Mizar |
| 74 | *------------------- |
| 75 | * Mizar was one of the first companies that released VME boards in 1982-3 together with |
| 76 | * Force Computers and Motorola. Their systems was often supported by OS9/68000 from Microware. |
| 77 | * In 1993 Mizar discontinued their OS9/CPU board product range and focused entirely on DSP |
| 78 | * boards. RTSI was founded by Mizar employees preserving the knowledge in OS9 as consultants. |
| 79 | * In 1998 Blue Wave resulted from the merger of Mizar and Loughborough Sound Images. |
| 80 | * Not much tech information availabe but I found some quotes about Mizar on the internet: |
| 81 | * |
| 82 | * From http://archive.org/stream/68micro-vol-11-num-02/V11N02_Feb1989_djvu.txt : |
| 83 | *-------------------------------------------------------------------------------- |
| 84 | * " Mizar provides complete OS-9 solutions for the VMEbus. Mizar's VME CPUs |
| 85 | * offer (he functions and performance your application demands. Our single |
| 86 | * height (3U) VME processors are uniquely configurable computing engines, |
| 87 | * Through Mizar's unique MXbus™ expansion interface, standard and custom side |
| 88 | * modules can be added to basic processors to create double-height (6U) boards |
| 89 | * tor specific applications, 3U CPU options include 68010, 66020, and 63030 |
| 90 | * microprocessors, up to one MB of DRAM, serial I/O, real-time clock, and |
| 91 | * mailbox interrupt support. Standard MXbus side modules include additional DRAM. |
| 92 | * SRAM, and I/O. |
| 93 | * |
| 94 | * Mizar's standard double- height (6U) processors provide additional features such |
| 95 | * as a high-speed cache to enhance 68030 performance, floating, point coprocessor |
| 96 | * support, up to four MB dual ported DRAM, VSB memory interface, Ethernet, and SCSI. |
| 97 | * |
| 98 | * Mizar also supports OS-9 with completely configured OS9 development systems and |
| 99 | * OS-9 application server systems. For more information, call Mizar today |
| 100 | * |
| 101 | * 800-635-0200 MIZAR 1419 Dunn Drive • CarrolHon, TX 75006 • 214-446-2664" |
| 102 | * |
| 103 | * Known boards from Mizar: |
| 104 | * |
| 105 | *-Comp.Os.Vxworks diguest mailing list May 1992: VxWorks Drivers Available from Mizar: |
| 106 | * EMX 7320 Serial I/O Board |
| 107 | * EMX 7550 Ethernet Controller Board (AMD 7990 Lance) MAC: 00:80:F8 MIZAR, INC. |
| 108 | * MZ 7300 Serial I/O Board (Z8530) |
| 109 | * MZ 7400 Disk Controller Board (WD 2010; WD 1772) |
| 110 | * MZ 7500 IEEE-488 (GPIB) Interface Board |
| 111 | * MZ 7810 I/O Expansion Module (6681 DUART) |
| 112 | * MZ 7831 SCSI Expansion Module (WD 33C93A) |
| 113 | * MZ 7850 Ethernet Expansion Module (WD 83C690) |
| 114 | * MZ 8505 IEEE-488 (GPIB) Interface Board" |
| 115 | *- Other sources: |
| 116 | * MZ 8000 ?? |
| 117 | * MZ 8105 3U 68000 CPU board |
| 118 | * MZ 8300 3U serial board, 2 NEC 7201 (Z80 DART) and 1 AMD CTS9513 5 x 16 bit Counter/Timer |
| 119 | * |
| 120 | * From http://www.megalextoria.com/forum2/index.php?t=msg&goto=73945& |
| 121 | *-------------------------------------------------------------------- |
| 122 | * Aug 20 1984 a report by James Jones from the OS/9 conferance in Des Moines: |
| 123 | * "... |
| 124 | * Mizar: is selling VME bus 68010 boards, running OS-9/68000; they also make |
| 125 | * various memory and I/O boards, disk controller boards, and and a NEC 7220-based |
| 126 | * graphics controller board...." |
| 127 | * |
| 128 | * Misc links about Mizar: |
| 129 | * http://www.vita.com/History |
| 130 | * http://www.verycomputer.com/154_e272024804bbe203_1.htm |
| 131 | * https://www.aihitdata.com/company/00814595/RTSI/overview |
| 132 | * |
| 133 | * Address Map |
| 134 | * -------------------------------------------------------------------------- |
| 135 | * Address Range Description/Assumption |
| 136 | * -------------------------------------------------------------------------- |
| 137 | * 0x000000 0x01ffff ROM because of fixed vectors |
| 138 | * 0x020000 0x03ffff RAM because bootvector stack starts at 0x21000 |
| 139 | * -- VME adresses--- |
| 140 | * 0xff0000 0xff0003 Bootstrap expects to find a UPD7201 serial device here |
| 141 | * -------------------------------------------------------------------------- |
| 142 | * |
| 143 | * Interrupt sources |
| 144 | * ---------------------------------------------------------- |
| 145 | * Description Device Lvl IRQ VME board |
| 146 | * /Board Vector Address |
| 147 | * ---------------------------------------------------------- |
| 148 | * On board Sources |
| 149 | * TBD |
| 150 | * Off board Sources (other VME boards) |
| 151 | * TBD |
| 152 | * ---------------------------------------------------------- |
| 153 | * |
| 154 | * TODO: |
| 155 | * - Dump the ROMs (DONE) |
| 156 | * - Setup a working address map (DONE) |
| 157 | * - Add VME bus driver (Faked one) |
| 158 | * |
| 159 | ****************************************************************************/ |
| 160 | |
| 161 | #include "emu.h" |
| 162 | #include "cpu/m68000/m68000.h" |
| 163 | #include "machine/z80dart.h" |
| 164 | #include "bus/rs232/rs232.h" |
| 165 | #include "machine/clock.h" |
| 166 | |
| 167 | #define CARDSLOT 0 |
| 168 | |
| 169 | #if CARDSLOT // Awaiting info on how to boot the user eproms |
| 170 | #include "bus/generic/slot.h" |
| 171 | #include "bus/generic/carts.h" |
| 172 | #endif |
| 173 | |
| 174 | #define LOG(x) x |
| 175 | |
| 176 | |
| 177 | /* These values are borrowed just to get the terminal going and should be replaced |
| 178 | * once a proper serial board hardware (ie MZ 8300) is found and emulated. */ |
| 179 | #define BAUDGEN_CLOCK XTAL_19_6608MHz /* fake */ |
| 180 | #define UPD_CLOCK (BAUDGEN_CLOCK / 128) /* This will give prompt */ |
| 181 | |
| 182 | class mzr8105_state : public driver_device |
| 183 | { |
| 184 | public: |
| 185 | mzr8105_state(const machine_config &mconfig, device_type type, const char *tag) : |
| 186 | driver_device (mconfig, type, tag), |
| 187 | m_maincpu (*this, "maincpu") |
| 188 | ,m_updterm(*this, "upd") |
| 189 | // ,m_cart(*this, "exp_rom1") |
| 190 | { |
| 191 | } |
| 192 | |
| 193 | DECLARE_READ16_MEMBER (vme_a24_r); |
| 194 | DECLARE_WRITE16_MEMBER (vme_a24_w); |
| 195 | DECLARE_READ16_MEMBER (vme_a16_r); |
| 196 | DECLARE_WRITE16_MEMBER (vme_a16_w); |
| 197 | virtual void machine_start (); |
| 198 | DECLARE_WRITE_LINE_MEMBER (write_updterm_clock); |
| 199 | |
| 200 | #if CARDSLOT |
| 201 | // User EPROM/SRAM slot(s) |
| 202 | int mzr8105_load_cart(device_image_interface &image, generic_slot_device *slot); |
| 203 | DECLARE_DEVICE_IMAGE_LOAD_MEMBER (exp1_load) { return mzr8105_load_cart(image, m_cart); } |
| 204 | DECLARE_READ16_MEMBER (read16_rom); |
| 205 | #endif |
| 206 | |
| 207 | protected: |
| 208 | |
| 209 | private: |
| 210 | required_device<cpu_device> m_maincpu; |
| 211 | required_device<upd7201_device> m_updterm; |
| 212 | |
| 213 | // Pointer to System ROMs needed by bootvect_r |
| 214 | // UINT16 *m_sysrom; |
| 215 | |
| 216 | #if CARDSLOT |
| 217 | UINT16 *m_usrrom; |
| 218 | required_device<generic_slot_device> m_cart; |
| 219 | #endif |
| 220 | }; |
| 221 | |
| 222 | static ADDRESS_MAP_START (mzr8105_mem, AS_PROGRAM, 16, mzr8105_state) |
| 223 | ADDRESS_MAP_UNMAP_HIGH |
| 224 | //AM_RANGE (0x000000, 0x000007) AM_ROM AM_READ (bootvect_r) /* Not verified */ |
| 225 | AM_RANGE (0x000000, 0x003fff) AM_ROM /* System EPROM Area 16Kb OS9 DEBUG - not verified */ |
| 226 | AM_RANGE (0x004000, 0x01ffff) AM_ROM /* System EPROM Area 112Kb for System ROM - not verified */ |
| 227 | AM_RANGE (0x020000, 0x03ffff) AM_RAM /* Not verified */ |
| 228 | //AM_RANGE (0x0a0000, 0x0bffff) AM_ROM /* User EPROM/SRAM Area, max 128Kb mapped by a cartslot */ |
| 229 | //AM_RANGE (0x0c0080, 0x0c0081) AM_DEVREADWRITE8 ("aciaterm", acia6850_device, status_r, control_w, 0xff00) |
| 230 | //AM_RANGE (0x0c0082, 0x0c0083) AM_DEVREADWRITE8 ("aciaterm", acia6850_device, data_r, data_w, 0xff00) |
| 231 | AM_RANGE(0x100000, 0xfeffff) AM_READWRITE(vme_a24_r, vme_a24_w) /* VMEbus Rev B addresses (24 bits) - not verified */ |
| 232 | //AM_RANGE(0xff0000, 0xffffff) AM_READWRITE(vme_a16_r, vme_a16_w) /* VMEbus Rev B addresses (16 bits) - not verified */ |
| 233 | // Faking a Mizar 8300 SIO BOARD in VME A16 adress space |
| 234 | AM_RANGE (0xFF0000, 0xFF0001) AM_DEVREADWRITE8("upd", upd7201_device, da_r, da_w, 0x00ff) /* Dual serial port NEC uPD7201 */ |
| 235 | AM_RANGE (0xFF0002, 0xFF0003) AM_DEVREADWRITE8("upd", upd7201_device, ca_r, ca_w, 0x00ff) /* Dual serial port NEC uPD7201 */ |
| 236 | AM_RANGE (0xFF0004, 0xFF0005) AM_DEVREADWRITE8("upd", upd7201_device, db_r, db_w, 0x00ff) /* Dual serial port NEC uPD7201 */ |
| 237 | AM_RANGE (0xFF0006, 0xFF0007) AM_DEVREADWRITE8("upd", upd7201_device, cb_r, cb_w, 0x00ff) /* Dual serial port NEC uPD7201 */ |
| 238 | |
| 239 | ADDRESS_MAP_END |
| 240 | |
| 241 | /* Input ports */ |
| 242 | static INPUT_PORTS_START (mzr8105) |
| 243 | INPUT_PORTS_END |
| 244 | |
| 245 | /* Start it up */ |
| 246 | void mzr8105_state::machine_start () |
| 247 | { |
| 248 | LOG (logerror ("machine_start\n")); |
| 249 | |
| 250 | #if CARDSLOT |
| 251 | /* Map user ROM/RAM socket(s) */ |
| 252 | if (m_cart->exists()) |
| 253 | { |
| 254 | m_usrrom = (UINT16*)m_cart->get_rom_base(); |
| 255 | m_maincpu->space(AS_PROGRAM).install_read_handler(0xa0000, 0xbffff, read16_delegate(FUNC(generic_slot_device::read16_rom), (generic_slot_device*)m_cart)); |
| 256 | } |
| 257 | #endif |
| 258 | } |
| 259 | |
| 260 | /* Dummy VME access methods until the VME bus device is ready for use */ |
| 261 | READ16_MEMBER (mzr8105_state::vme_a24_r){ |
| 262 | LOG (logerror ("vme_a24_r\n")); |
| 263 | return (UINT16) 0; |
| 264 | } |
| 265 | |
| 266 | WRITE16_MEMBER (mzr8105_state::vme_a24_w){ |
| 267 | LOG (logerror ("vme_a24_w\n")); |
| 268 | } |
| 269 | |
| 270 | READ16_MEMBER (mzr8105_state::vme_a16_r){ |
| 271 | LOG (logerror ("vme_16_r\n")); |
| 272 | return (UINT16) 0; |
| 273 | } |
| 274 | |
| 275 | WRITE16_MEMBER (mzr8105_state::vme_a16_w){ |
| 276 | LOG (logerror ("vme_a16_w\n")); |
| 277 | } |
| 278 | |
| 279 | #if CARDSLOT |
| 280 | /* |
| 281 | * 4. The USER EPROM Area |
| 282 | */ |
| 283 | // Implementation of static 2 x 64K EPROM in sockets U1/U3 as 16 bit wide cartridge for easier |
| 284 | // software handling. TODO: make configurable according to table above. |
| 285 | static MACHINE_CONFIG_FRAGMENT( mzr8105_eprom_sockets ) |
| 286 | MCFG_GENERIC_CARTSLOT_ADD("exp_rom1", generic_plain_slot, "mzr8105_cart") |
| 287 | MCFG_GENERIC_EXTENSIONS("bin,rom") |
| 288 | MCFG_GENERIC_WIDTH(GENERIC_ROM16_WIDTH) |
| 289 | MCFG_GENERIC_ENDIAN(ENDIANNESS_BIG) |
| 290 | MCFG_GENERIC_LOAD(mzr8105_state, exp1_load) |
| 291 | // MCFG_SOFTWARE_LIST_ADD("cart_list", "mzr8105_cart") |
| 292 | MACHINE_CONFIG_END |
| 293 | |
| 294 | /*************************** |
| 295 | Rom loading functions |
| 296 | ****************************/ |
| 297 | int mzr8105_state::mzr8105_load_cart(device_image_interface &image, generic_slot_device *slot) |
| 298 | { |
| 299 | UINT32 size = slot->common_get_size("rom"); |
| 300 | |
| 301 | if (size > 0x20000) // Max 128Kb - not verified |
| 302 | { |
| 303 | LOG( printf("Cartridge size exceeding max size (128Kb): %d\n", size) ); |
| 304 | image.seterror(IMAGE_ERROR_UNSPECIFIED, "Cartridge size exceeding max size (128Kb)"); |
| 305 | return IMAGE_INIT_FAIL; |
| 306 | } |
| 307 | |
| 308 | slot->rom_alloc(size, GENERIC_ROM16_WIDTH, ENDIANNESS_BIG); |
| 309 | slot->common_load_rom(slot->get_rom_base(), size, "rom"); |
| 310 | |
| 311 | return IMAGE_INIT_PASS; |
| 312 | } |
| 313 | #endif |
| 314 | |
| 315 | WRITE_LINE_MEMBER (mzr8105_state::write_updterm_clock){ |
| 316 | m_updterm->txca_w (state); |
| 317 | m_updterm->rxca_w (state); |
| 318 | } |
| 319 | |
| 320 | /* |
| 321 | * Machine configuration |
| 322 | */ |
| 323 | static MACHINE_CONFIG_START (mzr8105, mzr8105_state) |
| 324 | /* basic machine hardware */ |
| 325 | MCFG_CPU_ADD ("maincpu", M68000, XTAL_10MHz) |
| 326 | MCFG_CPU_PROGRAM_MAP (mzr8105_mem) |
| 327 | |
| 328 | |
| 329 | /* Terminal Port config */ |
| 330 | MCFG_UPD7201_ADD("upd", XTAL_4MHz, 0, 0, 0, 0 ) |
| 331 | MCFG_Z80DART_OUT_TXDA_CB(DEVWRITELINE("rs232trm", rs232_port_device, write_txd)) |
| 332 | MCFG_Z80DART_OUT_DTRA_CB(DEVWRITELINE("rs232trm", rs232_port_device, write_dtr)) |
| 333 | MCFG_Z80DART_OUT_RTSA_CB(DEVWRITELINE("rs232trm", rs232_port_device, write_rts)) |
| 334 | |
| 335 | MCFG_RS232_PORT_ADD ("rs232trm", default_rs232_devices, "terminal") |
| 336 | MCFG_RS232_RXD_HANDLER (DEVWRITELINE ("upd", upd7201_device, rxa_w)) |
| 337 | MCFG_RS232_CTS_HANDLER (DEVWRITELINE ("upd", upd7201_device, ctsa_w)) |
| 338 | |
| 339 | MCFG_DEVICE_ADD ("updterm_clock", CLOCK, UPD_CLOCK) |
| 340 | MCFG_CLOCK_SIGNAL_HANDLER (WRITELINE (mzr8105_state, write_updterm_clock)) |
| 341 | |
| 342 | #if CARDSLOT |
| 343 | |
| 344 | // EPROM sockets |
| 345 | MCFG_FRAGMENT_ADD(mzr8105_eprom_sockets) |
| 346 | #endif |
| 347 | |
| 348 | MACHINE_CONFIG_END |
| 349 | |
| 350 | /* ROM definitions */ |
| 351 | ROM_START (mzr8105) |
| 352 | ROM_REGION (0x1000000, "maincpu", 0) |
| 353 | |
| 354 | ROM_LOAD16_BYTE ("mzros9LB.bin", 0x000001, 0x2000, CRC (7c6a354d) SHA1 (2721eb649c8046dbcb517a36a97dc0816cd133f2)) |
| 355 | ROM_LOAD16_BYTE ("mzros9HB.bin", 0x000000, 0x2000, CRC (d18e69a6) SHA1 (a00b68f4d649bcc09a29361f8692e52be12b3792)) |
| 356 | |
| 357 | /* |
| 358 | * System ROM information |
| 359 | * |
| 360 | * The ROMs contains an OS9 bootloader. It is position independent but reset vector suggests that it sits flat on adress 0 (zero) |
| 361 | * |
| 362 | * We got a prompt but the command reportoair are very sparse to non OS9 users so investigation needed. |
| 363 | * |
| 364 | */ |
| 365 | ROM_END |
| 366 | |
| 367 | /* Driver */ |
| 368 | /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ |
| 369 | COMP (1987, mzr8105, 0, 0, mzr8105, mzr8105, driver_device, 0, "Mizar Inc", "Mizar VME8105", MACHINE_IS_SKELETON ) |