commit fecf997d010eea3aacfc1d401009e555992f6eff Author: Kevin Kralian Date: Sat Jul 21 15:39:32 2018 -0400 Revised Initial Checkin diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..0b04945 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 1994 Kevin Kralian + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..03e4d8d --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# Apple 2000 v1.3 Source Code + +"Apple 2000" is a high performance Apple II computer system emulator that was made for the Amiga computer and released in the 1990's. The sourcecode is now being publicly released and open sourced for historical archival purposes. Enjoy! + +Apple 2000 was written entirely in 68020 assembly language, and compiled with the DevPac 3 assembler. All the source files were included together (via main.s) and assembled as a single unit. There is also a runtime dependency on "ReqTools" by Nico Francois. + +### License +Apple 2000 has been open-sourced under the MIT license. + +### Contact + +This program marks the beginning of my professional career as a videogame developer - one that continues to this day 20+ years later. You can reach the author, Kevin Kralian, at kevin.kralian AT gmail + + diff --git a/docs+icons/Apple2000.doc b/docs+icons/Apple2000.doc new file mode 100644 index 0000000..f6baa0d --- /dev/null +++ b/docs+icons/Apple2000.doc @@ -0,0 +1,832 @@ + + APPLE 2000 v1.3 + The premier Apple ][ emulator for the Amiga + Copyright � 1994 by Kevin Kralian + All Rights Reserved + + Does anybody still use this text file instead of the AmigaGuide doc?? + If so, LET ME KNOW! Otherwise, I'm going to remove this duplicate info! +-------------------------------------------------------------------------- + +This program is freely distributable, as long as this instruction file is +kept with the program, and no modifications are made to my program or +instructions. I grant people the right to use this program privately, +however, it may not be included as part of any commercial package. + +This program is FREEWARE (well, more accurately, Tech-Ware). I do not +expect a monetary payment, however, donating me useful, enabling technical +material will result in me creating other emulations... + +NOTICE: Although this program is distributed as Freeware, copyright laws +& protection still apply. As such, *any* infringement upon this code, +especially as applied towards other 6502 or Apple II emulations will be +rigorously pursued via legal channels. + +Standard Disclaimer: This program is AS IS; use it at your own risk! I +assume no responsibility if this program or its use should cause something +disastrous to happen (like your computer exploding or you getting killed.) + +I may be contacted at + +This program uses "ReqTools.library", Copyright � by Nico Fran�ois. + +"Disk2File" program Copyright � by Ron Menelli. + +-------------------------------------------------------------------------- + +REQUIREMENTS: + + o Amiga computer with Kickstart 2.0 or newer + o A 68020+ CPU. Emulation WILL NOT WORK on a 68000 system at this time. + o About 900k free RAM (preferably most of it FAST RAM) + o ReqTools.library by Nico Fran�ois + o Apple ][ ROM image (called _APPLE.ROM) + + Recommended: + o A two-button joystick (to emulate the Apple's two-button joystick) + o A 68020 at ~25MHz (for full speed 1 MHz emulation) + + +DESCRIPTION: + +"Apple 2000" is the premier Apple ][ emulator for the Amiga computer. At +its current level it accurately emulates a 64K Apple ][+, including: + + o 6502 CPU + o ALL video modes (Text, LoRes, HiRes, Mixed modes, etc) + o 16k RAM card (64k computer) + o 5�" disk drive (1 or 2, via disk images) + o Two button joystick / Koala-Pad / Paddles + o Controllable Speed Regulation + o Keyboard + o Sound + +The emulation also runs in a completely system friendly manner, +multitasking properly with other programs. The two main goals were speed +and accuracy. This was accomplished by hand coding the emulator in 100% +machine language, optimization via instruction cycle analysis, and +painstaking attention to Apple hardware details. + +I feel confident that this is the fastest, most complete Apple ][ emulator +available for the Amiga computer (commercial, public domain, or +otherwise). Some of the highlights of my emulation: + + o Apple 2000 video emulation is the most accurate around: + - There is no "dithering" of the 16 Lo-Res colors. + - The text supports inverse and flashing characters. + - Two consecutive color pixels are drawn as white (as the Apple does). + - There are no missing, skipped, or fat vertical lines on Hi-Res gfx. + - Identical text character set. + o Disk drive emulation supports loading of "disk images" from any amiga + device (no custom archives or conversions required), including: + - Dalton Disk Disintegrator (DDD) 2.1 format (like DMS on amiga) + - 143,360 byte "Generic Disk Image", found on the Net & used by other + Apple ][ emulators on other platforms (Unix, Mac, & PC based) + o Apple 2000 disk drive emulation saves disk images in the standard + "Generic Disk Image". + o Apple 2000 is able to instantly load and run Apple executable files + from any Amiga device (better than a real Apple; no disk booting rqrd!). + + +WHY AN APPLE ][ EMULATOR? + +Why the Apple ][? Sentimental reasons. It's the computer I grew up with +and learned to program on. Since I have a fundamental understanding of +the Apple and because there aren't any other useable Apple emulators out +there (I've seen 5 or 6), the task called to me. I wanted to be able to +play all of my favorite games that I grew up with. Yes, they certainly +are not cutting edge as far as the graphics and sound goes, but they +certainly are playable! And I can overlook the cosmetics for some good +gameplay (i.e, just like people appreciate classic cars or oldies music). +Plus I wanted all of my friends to be able to play all of those great +forgotten games...the classics! The original CASTLE WOLFENSTEIN, +CHOPLIFTER, KARATEKA and CARMEN SANDIEGO. How many other multitasking +versions of JUNGLE HUNT or ROBOTRON 2084 can you play while downloading a +program? By writing this one emulator, the entire Amiga community is +suddenly presented with over 10,000 (now multitasking) Apple ][ programs +we wouldn't have otherwise been able to use (or play). + +After letting the idea stew in my head for 6 months, and much apparent +rambling to my friends (who so nicely encouraged me by saying, "What? YOU +write an emulator? And in C? UGH!"), I began coding. One month later, I +brought my first creation over to a friends house to see how it worked on +his system. After starting it up, we sat there. 30 seconds later we were +still sitting there, looking at a white screen. Eventually, we watched as +each little white character s-l-o-w-l-y was replaced by a black space. +Two minutes later, after getting bored of waiting for it to finish +clearing the screen, we gave up and played 2-player LEMMINGS. I knew the +only way I was going to be able to make this program 'practical' was to do +it in assembly. + +I finally bought DevPac 3. After writing a program to bounce 65,535 +colored pixels around a screen, I felt ready and experienced. I began +converting my routines for my emulator into assembly code. Almost two +years later (and after rewriting most of my emulation 10 times) my +emulator has finally matured enough to go out into the cold and brutal +world. Here it is, ready to be challenged by thousands of Apple programs +I have never even heard of, and ready to do its damndest to run them all! + + +RUNNING THE EMULATION + +Make sure "ReqTools.library" is in your libs: directory and place +"Apple2000" and "_APPLE.ROM" in the same directory. Then from the +CLI/Shell, CD to its directory and type "Apple2000" (or use it's icon). +If you want to run the emulation with two emulated disk drives, type +"Apple2000 -2" (or modify the startup script used by the icon). + +Now, assuming a little common sense (press the "OK" button on the +window!), you will see a black screen with the words "Apple ][ at the top. +Congratulations, you are now using an Apple ][ computer. The Apple is +trying to boot a disk. + +I will assume you have a little knowledge on using an Apple ][. Here are +some of the pertinant keys: + + KEY Function + ------------ ------------------------------------------------------ + DEL Apple "Reset" key. + ctrl-DEL Similar to "Ctrl-Open Apple-Reset" on ][e, ][c, ][gs. + Forces reboot, even if reset vectors have been changed. + RAmiga-Q Quit the emulator (after verification). + RAmiga-L Load Apple disk image or executable into the emulator. + RAmiga-S Save Apple disk image. + L-ALT (Like Open-Apple on ][e) Represents Apple Paddle + Button #0 + R-ALT (Like Closed-Apple on ][e) Represents Apple Paddle + Button #1 + (Alt keys do not affect other keystrokes to emulator) + F9 Sequence through Joystick/Paddle control devices. + HELP Sequence through simple help-messages. + + Speed Governing: + F1 50% Apple Speed (0.5 Mhz) + F2 100% Apple Speed (1.0 Mhz) + F3 150% Apple Speed (1.5 Mhz) + F4 200% Apple Speed (2.0 Mhz) + F5 Unlimited (as fast as your system can go!) + ^ + | Arrow keys patched to be like Apple ][e, ][c, ][gs. + <--+--> (Note: Apple ][+ had no Up/Down arrows, and most + | older programs won't handle them as expected.) + v + + NumPad only: + 8 Trim Apple joystick center position in respective + 4 5 6 directions. + 2 "5" will reset it to default (of 127,127). + + + +LOADING DISKS/FILES + +Once the Apple is running, you'll probably want to load an Apple disk or +executable. Here's how: at ANY time during emulation, feel free to press +Right-Amiga-L to bring up the Load File requester. From this requester +you may load Apple 5�" disk images or executable files. Simply navigate +to wherever the files are kept and load the file/disk image you want. +Apple 2000 recognizes several types of load files: + + o Filenames with a suffix are Dalton Disk Disintegrator archives + (DDD was a common disk compression util for the Apple, similar to DMS + for the Amiga) and the emulator will automatically decompress them! + + o 143,360 byte files are assumed to be "Generic Disk Images", such as + the many available on the net. + + o Files with the proper internal Dos/ProDos header are executable files; + these are single files that were runnable from Apple DOS 3.3/ProDos + and did not require any disk access thereafter. These files now do + not even require booting any Apple disk and are simply loaded into the + appropriate Apple memory areas and started instantly (quicker and + easier than a real Apple!). + +If you started Apple 2000 with the 2 disk drive option (via -2 option), +you will be asked which drive you want to load the image into. After +loading a disk image into drive #1, the emulator will ask you if you want +to 'boot' the disk. If you choose not to, you have effectively just 'put +the disk in the drive' (useful when you need to insert 'Disk 2'). On the +other hand, loading an executable Apple file does not give you any choices +and immediately runs it. This has all been designed to keep the emulator +as clean and simple as possible in terms of starting and running Apple +programs for the non Apple-literate user. + +Keep in mind, loading a disk image is the same thing as inserting the disk +into the Apple drive. It will STAY there until you replace it with +another disk (or some program erases that disk). Even after you load and +run several executable Apple programs, hitting Ctrl-DEL (rebooting the +Apple) will boot up the last DISK IMAGE you loaded (if any). This can be +confusing if you don't know whats going on (i.e, after finishing playing +MS. PACMAN and reseting the Apple, why is MUSIC CONSTRUCTION SET loading? +Because the disk is still in the drive from before). + + + +SAVING DISK IMAGES + +Pressing Right-Amiga-S will bring up a requester to save a disk image. +Disk images are saved in either the 143,360 byte "Generic" format, or in a +semi-compressed DDD format! The determination is made by the filename. To +compress a file in the DDD format, the filename must end with a '>' char. +Otherwise, it will be saved in the 143,360 byte format. If you do save the +image that way, it is suggested you append a ".disk" onto the filename to +maintain naming conventions (and so the requester will show the file). + +Keep in mind, DDD compression is not as tight as external compression +programs (LHA, etc). Also, loading/saving DDD files takes a couple extra +seconds to perform the (de)compression. + + +TRANSFERRING APPLE FILES + +To get an executable binary file from a real Apple to the Amiga is quite +simple. Use a terminal program and and then transfer it via null-modem +(or however you want) to the Amiga. It's recommended you attach a .PROG to +the end of the filename for consistent naming conventions. + + +TRANSFERRING APPLE DISKS + +Only UNPROTECTED standard 16 sector Apple disks are currently useable. +This eliminates copy protected software. Simply run Dalton Disk +Disintegrator (do not use version 2.0! It has a bug! Use version 2.1) +and use it to compress the disk into a file. Then, transfer it to an +Amiga (as described in "Transferring Apple Files" above). Once on the +Amiga, ensure the filename ends in so the emulator recognizes it as +a DDD file. + + +TRANSFERRING APPLE ROMS + +The Apple emulator, being true to form, requires the actual Apple ROM data +in order for the Apple to do anything. The standard Apple ROMs in use +were the 'AppleSoft ROMs that contained AppleSoft BASIC, the assembly +language monitor, and autobooting code. So I suggest that you obtain the +same ROM if you would like the same compatibility. The ROM image can be +obtained by booting an Apple ][ or ][+ with DOS 3.3, then typing: + + BSAVE BASICROM,A$D000,L$2FFF + +to save it to disk. Also, the disk controller Rom (not required) can be +saved by typing: + + BSAVE DISKROM,A$C600,L$00FF + +Incidentally, the main ROM image is on Apple's "DOS 3.3 System Master" +disk, called FPBASIC (which may be used instead). After saving these +images to disk, use your favorite terminal software and a null modem cable +(or real modems or whatever you like) to transfer these files to the +Amiga. Once transferred to the Amiga, give these files the proper names +and place them in the same directory as the Apple2000 executable. + +Theoretically, you can use the ROMs obtained from an Apple ][ clone (i.e, +Franklin Ace, PineApple, etc.), but keep in mind that these ROMs were not +100% compatible (but were quite close). This would effectively make my +emulation a "Franklin Ace Emulator". :-) However, you CANNOT use the ROM +images from an Apple ][e, ][c, or ][gs (maybe eventually...we'll see)! + +Once on the Amiga, the main Rom MUST be named "_APPLE.ROM" and the disk +rom (if you have it) must be called _DISK.ROM. + +** NOTE ** +Starting with version 1.1, due to the difficulties people had trying to +obtain it, the _DISK.ROM is no longer required! If that file is not +present, Apple2000 will automatically use a custom-disk rom instead. +However, obtaining the true rom image is still recommended for 100% +compatibility with all software. + +These ROM files can also be found in several other Apple emulator archives +available on the net and on several CD-Rom compilations (including the PC +Apple ][ emulator called "Apple2Em.zip"). + + + +PADDLE/JOYSTICK EMULATION + +The Apple ][ commonly uses either two paddles, a joystick, or a graphics +tablet (like a free-floating joystick). My emulation covers all bases. +Apple 2000 supports using these control devices: + + o Amiga Joystick (preferably 2 button, to emulate apple joystick) + o Amiga Mouse (to emulate free-floating joystick / paddles / Koala-pad) + o Analog PC Joystick (via FighterDuel dongle, to emulate apple joystick) + o Atari Paddles (to emulate apple paddles) + +The F9 key toggles through the choices and displays your selection at the +bottom of the screen. + + +Amiga Joystick: +--------------- +The emulator can utilize the standard amiga/atari/sega joystick +(preferably, a true 2-button joystick), and will assign the 8 switch +positions (up, up-right, right, etc) to the extreme values that an analog +stick would return (0 & 255). The "center" position defaults to the +optimum values (127 x 127), however, some games expect different center +values. This center value can be trimmed with the 2, 4, 6, & 8 keys on +the -numeric keypad- ONLY (see "Running Emulation"). For example, if you +start CHOPLIFTER and your character drifts towards the left, press the "6" +key to center the joystick more towards the right until your character no +longer drifts! (This is the emulated 'joystick trim' function). + +If you do not have a two button joystick, you have two choices. Spend $8 +and buy one, or else just use the Right-ALT key in lieu of the second +button (by the way, the two ALT keys work great for pinball games like +RASTER BLASTER). Note that the Sega Genesis Game controllers work well +with the amiga, and have two buttons! + +Amiga Mouse: +------------ +The emulator can utilize the absolute mouse coordinates, and this works +well for simulating a Koala-Pad graphics tablet, free-floating joystick, +or paddles (left/right control paddle #0, up/down control paddle #1). + +Programs designed for graphics tablets (KOALA PAD) or un-centered +joysticks work great in this mode, i.e, FANTAVISION, MISSILE COMMAND, +MUSIC CONSTRUCTION SET, and most other free floating cursor control +programs work ideally. The mouse works just like you would expect here. + +Analog PC Joystick: +------------------- +The emulation also supports true analog joysticks via joystick-dongles +(such as the adapter used for Fighter-Duel). The joystick will work just +like a real analog stick. + +*** Note: Apple 2000 uses "dynamic range setting & calibration" for analog +joysticks. This means that when you choose the "Analog Joystick" option, +the first thing you must do when starting to play your game is to move the +joystick over its full range of motion (extreme left, right, up, & down). +Once that is done, you need not worry about it anymore (unless you turn +off "Analog Joystick" and select it again). Joystick trimming is to be +done with the joystick's own trim pots. This 1 second of work from the +user ensures that Apple 2000 will work with a wide variety of joysticks. + +Atari Paddles: +-------------- +The emulator also now supports using actual Atari Paddles (the kind used +in the old Atari VCS/2600). They plug right into the amiga game port, and +work just like real apple paddles. NOTE: Like the analog joystick, the +paddles need to be moved over their complete range of motion when you +start to use them. + +Other game controller notes: +---------------------------- +Some of the older Apple games were designed to be used with paddles, not +joysticks. This is noticable in games (APPLE GALAXIAN, SNEAKERS) as in +when you release the joystick, your ship automatically moves back towards +the center point on the screen. This is exactly what would happen on a +real Apple with a joystick. You need to use some type of paddle emulation +here, either via the "Amiga Mouse" or "Atari Paddles" options. + +*** WARNING! While it is a bad habit many people have of (un)plugging game +controllers while the computer is on, be aware of this potential disaster: +Some of the Analog-Joystick Adapters have a metal jacket around the front +plug. This metal sheath has the potential to short out pins on the amiga +game port while trying to plug it in, which can damage your amiga! The +solution is simple: turn off your computer while changing controllers. +"An ounce of prevention..." + + + +SPEED REGULATION + + +"IT'S TOO FAST!" :-) +By popular request, Apple 2000 now offers selectable speed regulation so +people with fast systems can slow down games to humanly playable speeds. +Speed regulation is controlled via 5 function keys (F1 -> F5), which are +in order from slowest to fastest. + + F1 50% Apple Speed (0.5 Mhz) + F2 100% Apple Speed (1.0 Mhz) + F3 150% Apple Speed (1.5 Mhz) + F4 200% Apple Speed (2.0 Mhz) + F5 Unlimited (as fast as your system can go!) + +F2 selects "100% Apple Speed", which limits emulation speed to that of a +real Apple ][ (1.024 Mhz). F1 selects 50% (slow down games to half +speed), and F5 selects "unlimited speed" (which runs as fast as your +system can). + +Use of these keys during gameplay can be used as an aid- For example, +switching to 50% speed during a difficult part in an arcade game. Also, +some games on the apple might be a little sluggish compared to today's +standards and skills. 150% speed usually takes care of those. :) + +Understand that Speed Regulation works like a "Speed Limit". If your +system can't run the emulation quickly in the first place, choosing 150% +or 200% regulation won't have any noticeable effects (Like taking a '74 +Pinto out on the Autobahn. Who cares if there's no speed limit- You won't +go very fast. :) + +Keep in mind that Apple sound is made via speaker clicks and timing loops. +Faster/slower emulation will cause higher/lower pitched sound. + + +"IT'S TOO SLOW!" :-( +Okay. For the remaining 93% of the Amiga owners who don't have '040s, +there are a few things that can be done to speed up the emulation. + +Press F5 to turn off speed regulation- This completely turns off the +overhead of the speed-regulation code. + +If you have an MMU (and an additional 512K free fast-ram), turn on the +"FastRom" option. (Type "CPU FASTROM" from the shell). + +If you are running ENFORCER, turn it off! On my system, graphics intensive +games slow down 20% while enforcer is running. + +Start "Apple 2000" in a relatively clean system with large blocks of +fast-ram available. (IE: Instead of trying to run the emulator while +you've been working on your system for 8 hours and have DirOpus, AMAX IV, +and ADPro all running, just reboot the system first). + +Of course, you can always add an accellerator to your system. ;-) + + + +THE STATUS BAR + +By popular request, the "Title Bar" at the top of the screen has been +removed, and has now been replaced with a new "Status Bar". The bar +appears at the bottom of the screen momentarily to notify the user of any +significant events, and then goes away. And it's black and white so the +grey scale users can read it. + +This bar displays significant messages, including feedback on Speed +Regulation Selections, Paddle/Joystick Controls, Apple Crashes, Help, and +disk drive access (including drive & track #'s). Most the time the status +bar will be invisible. + + + +TECH NOTES + +Some Apple programs use "unimplemented" 6502 instructions. These are +instructions that are not official, but partially decode into doing a +particular function (as discovered by many unorthodox programmers). My +emulation does not support ANY unimplemented instructions, and will simply +break upon hitting any of those instructions (with Apple ][ software, I +have seen very few programs that use them). Those few programs will also +fail on the Apple ][gs. + +The ONLY graphics glitch is that the Hi-Res graphics screens do not fill +in the entire display width. That is, they leave a half-inch black border +on each side of the display. Why? Because the Apple Hi-Res screen has a +horizontal resolution of 280 pixels, and the Amiga's display has a minimum +resolution of 320. Trying to stretch this display by leaving an empty +pixel after every 7 pixels or drawing every 7th pixel twice, results in a +highly distorted and uneven image. The Text modes and LoRes modes still +use the entire screen width (to maintain aspect ratio). This slightly +narrow display is only noticeable in the 'mixed Graphics/Text' mode, where +text will be a little wider than the graphics above it. + +Also regarding Text and Graphics (but not a glitch, it's an improvement) +is the fact that mixed Graphics and Text on the old Apple ]['s originally +caused the text to be fringed with green and purple instead of being solid +white. This fringing has absolutely no purpose, but is a mere artifact of +the Apple video circuity. My emulation cleans it up with crisp & clean +text output at all times (does anybody have any complaints?). Apple +finally cleaned this up with the Apple ][gs and its RGB output (but +introduced a couple other graphic glitches), so I believe my clean Text +display is desirable. + + + +WHAT ABOUT EMPLANT? + +My emulator, "Apple 2000" was (p)reviewed in Amiga Computing (Issue 71, +March 94), inside a larger review for the Emplant card (there's even a +screenshot where you can read my title bar, Apple 2000!). For all intents +and purposes, the review makes it APPEAR as if this program was written +by, owned by, and coming soon from Utilities Unlimited, makers of the +Emplant card (A macintosh emulator). Regardless, the reviewer loved it, +noting that this was the fastest 6502 emulation he has seen. + +At several World Of Commodore shows, Jim Drew showed my early versions of +"Apple 2000" to crowds of people during his presentations of his Mac +emulator. A friend even has a video-tape of Jim loading up and showing my +emulator to a crowd when I asked, "What other emulators are you doing?" +(before he knew who I was) at WOC in Pasadena, 1993. + +To set the record straight, I did send Utilities Unlimited several early +exclusive 'evaluation' versions of my emulator to see if they were +interested in purchasing it (for their Emplant package), but no agreements +were ever reached. Utilities Unlimited was in no way involved with the +development of, and has no connection to, this program (Apple 2000). + +This program is NOT part of the Emplant package, as many people have been +led to believe. The positive side of this is that you may use Apple 2000 +without having to spend >$300! + + + +ABOUT THE AUTHOR + +"Apple 2000" was written by Kevin Kralian over the course of two years. +After serving in the US Marine Corps Infantry (!), he then earned a +college degree in Fire Technology, and continued in school towards his +Computer Science degree. He is also a volunteer FireFighter/EMT and a +freelance programmer. + +He has over 10 years of programming experience, including ADA, BASIC, C, +Pascal, 6502 and 680x0 assembly. Programming interests focus on +performance programming, including games and emulation. Career goals +include firefighter and game programmer. + +He has recently been hired as a full time game programmer, and is now +working on the Sega "Saturn". Good things do happen to good people. :-) + +He may be contacted at + + + +"PAYMENT" FOR THIS PROGRAM + +This program is being distributed as freeware, I do not expect monetary +payment. My original intentions were simply to have my program be 'used' +by the Amiga community, and I still feel the same way. I've worked long +and hard on this program and the most rewarding thing to me know would be +to simply know people are enjoying it! + +However, what I WOULD appreciate would be any technical references for any +computer/hardware/platform. Let me explain... + +Many improvements in the Apple emulator are dependant upon me finding +Apple technical reference material (i.e, unimplemented instructions, +serial/parallel support, ProDOS harddrive support, etc). If you would +like to see these features implemented, the biggest thing you can do is +send me any tech material that could be helpful. + +Also, some ideas for my next emulator include: Atari VCS (2600), GameBoy, +Nintendo, Atari 400/800 and Commodore 64/128. Though there are a few C-64 +emulators out there, many people have urged me to do one "the right way". +I tend to want to do the old Atari VCS or Gameboy emulation. HOWEVER, in +order to do this, I need tech information that I cannot publically obtain. + +Do YOU want these game machines to be emulated (I do)? If you are one of +those priviledged people who might have been involved in developing +software for any of these machines or somehow have any tech info on these +machines, please send me any and all tech information. *** I WILL *** +make an emulator of these machines when I have enough tech information to +do so. But I need your help. + +I am open to any suggestions, comments, or feedback. Let me know how the +emulator works for you. Please let me know of anything that does not work +(that works on a real Apple ][), and I will do my best to correct the +problem. I am also interested in obtaining any Apple ][ programs people +may have to test under my emulation. + +Anybody interested please contact me at + + +Particular things I'm looking for: + + o Whats Where in the Apple ][: An Atlas to the Apple computer + o Apple Super Serial Card / Parallel card manuals + o AmigaDOS Programmers Reference + o Any 2.0+ Amiga AutoDocs (AmigaGuide format would be cool!) + o ANY kind of tech info on Gameboy, Nintendo, or the old Atari VCS + (there once was an Apple ][ card to program the Atari. Anybody + have it?) + o Any and all Apple ][ programs. + o Any responses, reactions, suggestions, etc. on my emulation. + o etc... + + + +CREDITS + +I owe lots of thanks to lots of people. + +Thank you my dearest JoAnnaBear for being so supportive of me and this +project over the last two years, and for not going crazy over my many +hours of "techno-babble", but just patiently smiling back as if you +understood me. :-) + +Thank you Robbie for all your inspiration and encouragement. And thanks +for your brainstorm sessions and hundreds of hours worth of second-hand +smoke (cough cough). Thank you for the book "Amiga Machine Language +Programming Guide" - the very first 680x0 assembly book I've seen +(blech!). By the way, this book was due back at the library in 1989! +How are your games "To Sir With Love" and "The Piano" coming along? Oh +yeah... and thanks for cleaning up and converting my docs to AmigaGuide +format for me :-) + +Thanks to Ronald J. Menelli, for his contribution of the "Disk2File" +conversion utility. ("Disk2File" is Copyright � by Ronald J. Menelli). + +Thank you Brian J. Bernstein, for his beautiful new Apple 2000 icon. +And thanks to the many others who sent icons. Apparently people did not +consider the little face representative of Apple2000? ;-) + +Thank you so much to Rand, another Firefighter, for recognizing a good +thing when he sees it. (Whats with all these firefighter/programmers?) + +Of course, Thanks to Jason Compton (Amiga Report columnist), the man who +did the first [authorized] review of Apple2000, and informed the public of +this great program. How could I have forgotten you for so long? + +Thanks Ed Brown, your support and encouragement has been exceptional! You +better be happy with the new "Analog Joystick Support" after telling me +about the advantages over the "digital" sticks! ;-) + +Thanks to "Nine Inch Nails" and "Frankie Goes to Hollywood" for their +soothing sounds to which much of Apple2000 was created. + +Thanks to the authors of other Apple ][ emulators on other platforms, for +their open discussions, comparisons, and sharing of emulation techniques +and technology. Their willingness to disclose results in improved software +for all computer users. + +Thank you to the many people who have contacted me with letters of +support, feedback, contributions, suggestions, programs, etc. + +Thanks to those incredible guys at Computer Cafe. I appreciate how you let +me use your various machines for debugging and testing during the +development of my emulation. Without your help, I would have never been +able to work out the '040 bugs, nor have seen my emulation running on a +28" monitor with cool 24 bit backgrounds. + +Thanks to Carmen Rizzolo, the computer artist extraordinaire! Your +original artwork for my previous programs are utterly amazing. Without +people like Carmen, where would we get cool 3D Star Trek and telephone +objects? + +Thanks to Will, the only intelligent Mac owner I know. It was great to +share ideas on high performance 6502 emulation with the 680x0. Have you +finished your Mac version of your Apple ][ emulator yet? Thanks for that +'half' of the "Inside the Apple //e" manual. Did you ever find pages +1-110? + +Thank you Nico Fran�ois, for your contribution to the Amiga community. +ReqTools is a very polished piece of work, and I know that your work has +saved me (and many others) hours of work trying to "recreate the wheel". +(Reqtools.library is Copyright � by Nico Fran�ois). + +Thanks to the many helpful people on the Internet, for helping me through +many obscure programming and debugging challenges. + +Thanks to Steve Wozniak for creating the original Apple ][. And congrats +to Apple Computer for knowing how to market computers and becoming a +large, successful company. Maybe Commodore can learn a few things from +you before they drive themselves out of business? [May '94- too late] + +Thanks to 'Dalton', for his "Dalton's Disk Disintegrator" (DDD) program on +the Apple ][. My (de)compression routines were based on his routines and +attempt to compress data in an identical, compatible way. + +Thank you Bill, for taking your family and moving far, far away. + +Thanks to an unnamed individual, for teaching me a very important lesson- +That I can never trust anybody, and that people like you will lie, cheat, +and steal to try and build the credibility of yourself/your company. Just +another page in your book of lies, eh? + +And finally, thanks to the many people I do not have space to mention, and +to all of the Amiga users who have made the Amiga scene as wonderful as it +is. + + + +HISTORY + + +08/21/94 ***** Version 1.3 ***** + + o Controllable Speed Regulation (50%, 100%, 150%, 200%, Unlimited) + + o Overhauled entire video subsystem + - No more hardware hitting or copperlists + - Works happily with AGA/Mode promotions + - No more "Screen Jitter" for the few who had it + - Screens can be pulled down in front without disturbances + - All Apple screens can now be "Grabbed" + + o Added optional 2 disk drive support (via -2 command) + + o Overhauled File Loading/Saving related functions + - With 2 drives, loading/saving will prompt for drive # + - Saving: The proper "loaded" disk name will appear (for each drive) + - Saving: DDD vs 143,360 byte formats chosen via filename. + - Added "Warning: Disk Data Changed" notice during loads & quit. + + o Replaced TitleBar at top of screen with "Status Bar" at bottom + - Only shown during significant events + - Black and white (so greyscale users can read it) + + o Added support for Analog Joystick w/ 2 buttons + o Added support for Atari Paddles + + o Video page-flipping handled properly + - ShortCircuit, BileStoad, & OutPost run much better! + o A couple bug fixes (and duplicated a 6502 bug thats required) + - Canyon Climber, Drol animation, Frogger, Lode Runner, MoonPatrol, + Pinball Construction Set, Randamn, Sargon, & Tetris II All work! + o Added Lower Case Text display (Apple ][e charset) + o Optimized disk loading/decompression routines (twice as fast) + o Added a cheesy "Turn Off Monitor" effect when exited ;-) + o And of course, its a little bit faster! + +(Version 1.2 skipped due to misnamed archives already out) + +05/18/94 ***** Version 1.1 ***** + + o Wrote custom disk Rom that is used if _DISK.ROM file is not present! + (_DISK.ROM is no longer required! But still recommended...) + o Check for 68020+ CPU (instead of crashing) + o Support for 143,360 byte generic "disk images" (Loading/Saving) + (as used by many other emulators & available on the net) + o Disk images saved in "generic" format instead of DDD + (DDD format still recognized & loaded, though) + o Dos 3.3/ProDos headers recognized and handled in both disk images + and executable files (instead of just ProDos like version 1.0) + o Dos 3.3/ProDos/Raw ROM images all recognized and acceptable. + o Inclusion of "Disk2File" utility, which reads a 5�" Apple disk via + the C= 1020 Drive, and saves it as a file + o Included "Version" string + o Numerous optimizations (-slightly- faster) + + +04/10/94 ***** FIRST PUBLIC RELEASE v1.0 ***** + + + +FINDING YOURSELF SOME SOFTWARE + +Finding apple disk images is like a treasure hunt. If you can't transfer +files yourself, there are lots of apple files out on the Net and BBS's. + +I'm told you can find lot's of disk images on anon ftp: + + wilbur.stanford.edu:/pub/apple2/disk_images and /pub/apple2/incoming + ftp.uni-kl.de:/pub/apple2/disk_images + cassandra.ucr.edu:/pub/apple2/incoming + + FSP site, at: 134.184.15.12 2424 + At (unknown) site at: minnie.sc.adfa.oz.au + +Expect difficulties! Some of the images have Mac headers on them that +need to be removed (Leave it to the mac to screw up a simple data file). +Some are compressed with Mac, Apple, or Unix protocols. Some have +out-of-order sectoring and need to be re-mapped (via AFID utility). Some +files are "text" files that try to install themselves via "executing" from +the apple. And many archives are simply corrupt and won't even work on +real Apples! + +The best way to avoid the headache of sifting through so much garbage is +to trade with other people who have known, tested, and working programs. +I've even been informed of several huge archives or commercial games for +Apple 2000 floating around many BBS's. + +That brings out another issue. Most these games are/were copyrighted, +commercial programs. But now what? Most the companies have since +dissolved, none of the apple programs are sold or produced anymore, and +who retains the copyright is hard to determine. This very issue has been +controversial for quite some time, and there is no easy answer. + +What is known is that many of the classic apple programs have been placed +in public domain by their authors (and many agree to it just by asking). +Some other companies have even placed all their old Apple titles into +public domain (as written in the late issues of A+ or InCider). The +sample programs I include with my archive, to the best of my knowledge, +are now in the public domain (according to statements in magazines or +what's sold by PD distributors). + + + +COMPATIBILITY + +Every effort was made to provide the highest degree of compatibility with +all Apple ][ software. This is a small sampling of the more than 600 +programs that I have successfully ran under Apple2000. + +AIR_CARS, ALIEN_AMBUSH, ALIEN_TYPHOON, ALPHAPLOT, APPLE_PANIC, APPLE_ZAP, +APPLECIDER, APPLEIIeINTRO, ASTEROID_FIELD, AUTOBAHN, BAG_OF_TRICKS, +BEAGLE_BAG, BEER_RUN, BEYOND_CASTLE_WOLFENSTEIN, BIG_MAC_ASM, BLISTERBALL, +BLITZKREIG, BOLO, BOULDER_DASH, BUG_ATTACK, BUG_BATTLE, BUZZARD_BAIT, +CANNONBALL.BLITZ, CENTIPEDE, CHAMPIONSHIP LODE RUNNER, CHIVALRY, +CHOPLIFTER, COMPUTER_FOOSBALL, CONAN, COPY_II+_7.4, COUNTY_CARNIVAL, +CROSSFIRE, CUBIT, CYCLOD, D-CODE, DEFENDER, DIG_DUG, DINO_EGGS, DOGFIGHT, +DOS_3.3_SYSTEM_MASTER, DRAGONFIRE, DRAW_POKER, DREADNOUGHTS, DUNG_BEETLES, +ELIMINATOR, F-15_STRIKE_EAGLE, FALCONS, FANTAVISION, FIGHT_NIGHT, +FIREBIRD, FISHIES, FLIGHT_SIM_II, FRAMEUP, FRAZZLE, FRENZY, GALAXIAN, +GOLD.RUSH, GRAPHICS_MAGICIAN, GREAT_CROSS_COUNRY_ROAD_RACE, GUARDIAN, +GULF_STRIKE, HACKER, HACKER_II, HA`RD_HAT_MACK, HARDBALL, HUNGRY_BOY, +INTERLUDE_II, INTERNATIONAL_GRAN_PRIX, JAWBREAKER, JPORT, JUMPJET, +JUNGLE_HUNT, KARATEKA, LABYRINTH, LEATHER_GODDESS_OF_PHOBOS, LEMMINGS, +MARAUDER, MARIO_BROS, MASQUERADE, MICRO_ILLUSTRATOR, MILLIONWAIRE, +MINE_SWEEP, MINER_2049ER, MR.DO, MS_PACMAN, MURDER_ON_THE_ZINDERNEUF, +MUSIC_MAKER, MUSIC_CONSTRUCTION_SET, NEPTUNE, NIGHT_MISSION_PINBALL, +NIGHTMARE.GALLERY, NORAD, PACMAN, PINBALL_CONSTRUCTION_SET, POOYAN, +POPPLES_XMAS_ADVENTURE, PRODOS_MASTER, RASTER_BLASTER, RED.ALERT, REPTON, +RESCUE_RAIDERS, ROADWAR_2000, ROBOTRON, ROCKET.COMMAND, SAMMY_LIGHTFOOT, +SEA_DRAGON, SERPENTINE, SHORT_CIRCUIT, SKYFOX, SNEAKERS, SPACE_RAIDERS, +SPACE_QUARKS, SPACE_WARRIOR, SPY.HUNTER, SPYS_DEMISE, SQUADRON_617, +STAR.THIEF, STAR_WARS_II, STARGATE, STARMAZE, STICKYBEAR_MATH#1, +STICKYBEAR_MATH#2, SUCCESSION, SUICIDE, SUMMER_GAMES, SUMMER_GAMES_II, +SUPER.PUCKMAN, SUPERMAP, SWASHBUCKLER, TAKE1, TAXMAN, TERRAPIN_LOGO, +THIEF, TIME_IS_MONEY, TRANQUILITY_BASE, TRIVIA_FEVER, TWERPS, +UBOAT_COMMAND, XEVIOUS, ZAXXON + +:-) ...have fun! -Kevin Kralian diff --git a/docs+icons/Apple2000.doc.info b/docs+icons/Apple2000.doc.info new file mode 100644 index 0000000..1cbbe2c Binary files /dev/null and b/docs+icons/Apple2000.doc.info differ diff --git a/docs+icons/Apple2000.guide b/docs+icons/Apple2000.guide new file mode 100644 index 0000000..87534d8 --- /dev/null +++ b/docs+icons/Apple2000.guide @@ -0,0 +1,941 @@ +@database "Apple2000.guide" + +@node Main "Apple 2000" + APPLE 2000 v1.3 + The premier Apple ][ emulator for the Amiga + Copyright � 1994, by @{" Kevin Kralian " link ABOUT} + All Rights Reserved + + @{" " link INTRODUCTION} Introduction @{" " link ABOUT} ABOUT THE AUTHOR + @{" " link REQUIREMENTS} Requirements @{" " link CREDITS} CREDITS + @{" " link DESCRIPTION} Description @{" " link HISTORY} HISTORY + @{" " link WHY} Why An Apple ][ Emulator? @{" " link COMPATIBILITY} COMPATIBILITY + @{" " link RUNNING} Running the Emulation @{" " link FINDING} FINDING SOFTWARE + @{" " link LOADING} Loading/Saving Disks/Files + @{" " link TRANSFERRING} Transferring Apple Files/Disks/ROMs + @{" " link PADDLE} Paddle/Joystick Emulation + @{" " link SPEED} Speed Regulation + @{" " link STATUS} Status Bar + @{" " link TECH} Tech Notes + @{" " link PAYMENT} Payment + @{" " link EMPLANT} What About EMPLANT? +@endnode + +@node INTRODUCTION "Introduction" + +This program is freely distributable, as long as this instruction file is +kept with the program, and no modifications are made to my program or +instructions. I grant people the right to use this program privately, +however, it may not be included as part of any commercial package. + +This program is FREEWARE (well, more accurately, Tech-Ware). I do not +expect a monetary payment, however, donating me useful, enabling technical +material will result in me creating other emulations... + click here for more info @{" " link PAYMENT} + +NOTICE: Although this program is distributed as Freeware, copyright laws +& protection still apply. As such, *any* infringement upon this code, +especially as applied towards other 6502 or Apple II emulations will be +rigorously pursued via legal channels. + +Standard Disclaimer: This program is AS IS; use it at your own risk! I +assume no responsibility if this program or its use should cause something +disastrous to happen (like your computer exploding or you getting killed.) + +I may be contacted at + +This program uses "ReqTools.library", Copyright � by Nico Fran�ois. + +"Disk2File" program Copyright � by Ron Menelli. + +@endnode + +@node REQUIREMENTS "Requirements" + +REQUIREMENTS: + + o Amiga computer with Kickstart 2.0 or newer + o A 68020+ CPU. Emulation WILL NOT WORK on a 68000 system at this time. + o About 900k free RAM (preferably most of it FAST RAM) + o ReqTools.library by Nico Fran�ois + o Apple ][ ROM image (called _APPLE.ROM) + + Recommended: + o A two-button joystick (to emulate the Apple's two-button joystick) + o A 68020 at ~25MHz (for full speed 1 MHz emulation) + +@endnode + +@node DESCRIPTION "Description" + +DESCRIPTION: + +"Apple 2000" is the premier Apple ][ emulator for the Amiga computer. At +its current level it accurately emulates a 64K Apple ][+, including: + + o 6502 CPU + o ALL video modes (Text, LoRes, HiRes, Mixed modes, etc) + o 16k RAM card (64k computer) + o 5�" disk drive (1 or 2, via disk images) + o Two button joystick / Koala-Pad / Paddles + o Controllable Speed Regulation + o Keyboard + o Sound + +The emulation also runs in a completely system friendly manner, +multitasking properly with other programs. The two main goals were speed +and accuracy. This was accomplished by hand coding the emulator in 100% +machine language, optimization via instruction cycle analysis, and +painstaking attention to Apple hardware details. + +I feel confident that this is the fastest, most complete Apple ][ emulator +available for the Amiga computer (commercial, public domain, or +otherwise). Some of the highlights of my emulation: + + o Apple 2000 video emulation is the most accurate around: + - There is no "dithering" of the 16 Lo-Res colors. + - The text supports inverse and flashing characters. + - Two consecutive color pixels are drawn as white (as the Apple does). + - There are no missing, skipped, or fat vertical lines on Hi-Res gfx. + - Identical text character set. + o Disk drive emulation supports loading of "disk images" from any amiga + device (no custom archives or conversions required), including: + - Dalton Disk Disintegrator (DDD) 2.1 format (like DMS on amiga) + - 143,360 byte "Generic Disk Image", found on the Net & used by other + Apple ][ emulators on other platforms (Unix, Mac, & PC based) + o Apple 2000 disk drive emulation saves disk images in the standard + "Generic Disk Image". + o Apple 2000 is able to instantly load and run Apple executable files + from any Amiga device (better than real Apple; no disk booting rqrd!). + +@endnode + +@node WHY "Why An Apple ][ Emulator?" + +WHY AN APPLE ][ EMULATOR? + +Why the Apple ][? Sentimental reasons. It's the computer I grew up with +and learned to program on. Since I have a fundamental understanding of +the Apple and because there aren't any other useable Apple emulators out +there (I've seen 5 or 6), the task called to me. I wanted to be able to +play all of my favorite games that I grew up with. Yes, they certainly +are not cutting edge as far as the graphics and sound goes, but they +certainly are playable! And I can overlook the cosmetics for some good +gameplay (i.e, just like people appreciate classic cars or oldies music). +Plus I wanted all of my friends to be able to play all of those great +forgotten games...the classics! The original CASTLE WOLFENSTEIN, +CHOPLIFTER, KARATEKA and CARMEN SANDIEGO. How many other multitasking +versions of JUNGLE HUNT or ROBOTRON 2084 can you play while downloading a +program? By writing this one emulator, the entire Amiga community is +suddenly presented with over 10,000 (now multitasking) Apple ][ programs +we wouldn't have otherwise been able to use (or play). + +After letting the idea stew in my head for 6 months, and much apparent +rambling to my friends (who so nicely encouraged me by saying, "What? YOU +write an emulator? And in C? UGH!"), I began coding. One month later, I +brought my first creation over to a friends house to see how it worked on +his system. After starting it up, we sat there. 30 seconds later we were +still sitting there, looking at a white screen. Eventually, we watched as +each little white character s-l-o-w-l-y was replaced by a black space. +Two minutes later, after getting bored of waiting for it to finish +clearing the screen, we gave up and played 2-player LEMMINGS. I knew the +only way I was going to be able to make this program 'practical' was to do +it in assembly. + +I finally bought DevPac 3. After writing a program to bounce 65,535 +colored pixels around a screen, I felt ready and experienced. I began +converting my routines for my emulator into assembly code. Almost two +years later (and after rewriting most of my emulation 10 times) my +emulator has finally matured enough to go out into the cold and brutal +world. Here it is, ready to be challenged by thousands of Apple programs +I have never even heard of, and ready to do its damndest to run them all! + +@endnode + +@node RUNNING "Running the Emulation" + +RUNNING THE EMULATION + +Make sure "ReqTools.library" is in your libs: directory and place +"Apple2000" and "_APPLE.ROM" in the same directory. Then from the +CLI/Shell, CD to its directory and type "Apple2000" (or use it's icon). +If you want to run the emulation with two emulated disk drives, type +"Apple2000 -2" (or modify the startup script used by the icon). + +Now, assuming a little common sense (press the "OK" button on the +window!), you will see a black screen with words "Apple ][" at the top. +Congratulations, you are now using an Apple ][ computer. The Apple is +trying to boot a disk. + +I will assume you have a little knowledge on using an Apple ][. Here are +some of the pertinant keys: + + KEY Function + ------------ ------------------------------------------------------ + DEL Apple "Reset" key. + ctrl-DEL Similar to "Ctrl-Open Apple-Reset" on ][e, ][c, ][gs. + Forces reboot, even if reset vectors have been changed. + RAmiga-Q Quit the emulator (after verification). + RAmiga-L Load Apple disk image or executable into the emulator. + RAmiga-S Save Apple disk image. + L-ALT (Like Open-Apple on ][e) Represents Apple Paddle + Button #0 + R-ALT (Like Closed-Apple on ][e) Represents Apple Paddle + Button #1 + (Alt keys do not affect other keystrokes to emulator) + F9 Toggle between Mouse / Joystick control. + HELP Sequence through simple help-messages. + + Speed Regulation: + F1 50% Apple Speed (0.5 Mhz) + F2 100% Apple Speed (1.0 Mhz) + F3 150% Apple Speed (1.5 Mhz) + F4 200% Apple Speed (2.0 Mhz) + F5 Unlimited (as fast as your system can go!) + ^ + | Arrow keys patched to be like Apple ][e, ][c, ][gs. + <--+--> (Note: Apple ][+ had no Up/Down arrows, and most + | older programs won't handle them as expected.) + v + + NumPad only: + 8 Trim Apple joystick center position in respective + 4 5 6 directions. + 2 "5" will reset it to default (of 127,127). + +@endnode + +@node LOADING "Loading/Saving Disks/Files" + +LOADING DISKS/FILES + +Once the Apple is running, you'll probably want to load an Apple disk or +executable. Here's how: at ANY time during emulation, feel free to press +Right-Amiga-L to bring up the Load File requester. From this requester +you may load Apple 5�" disk images or executable files. Simply navigate +to wherever the files are kept and load the file/disk image you want. +Apple 2000 recognizes several types of load files: + + o Filenames with a suffix are Dalton Disk Disintegrator archives + (DDD was a common disk compression util for the Apple, similar to DMS + for the Amiga) and the emulator will automatically decompress them! + + o 143,360 byte files are assumed to be "Generic Disk Images", such as + the many available on the net. + + o Files with the proper internal Dos/ProDos header are executable files; + these are single files that were runnable from Apple DOS 3.3/ProDos + and did not require any disk access thereafter. These files now do + not even require booting any Apple disk and are simply loaded into the + appropriate Apple memory areas and started instantly (quicker and + easier than a real Apple!). + +If you started Apple 2000 with the 2 disk drive option (via -2 option), +you will be asked which drive you want to load the image into. After +loading a disk image into drive #1, the emulator will ask you if you want +to 'boot' the disk. If you choose not to, you have effectively just 'put +the disk in the drive' (useful when you need to insert 'Disk 2'). On the +other hand, loading an executable Apple file does not give you any choices +and immediately runs it. This has all been designed to keep the emulator +as clean and simple as possible in terms of starting and running Apple +programs for the non Apple-literate user. + +Keep in mind, loading a disk image is the same thing as inserting the disk +into the Apple drive. It will STAY there until you replace it with +another disk (or some program erases that disk). Even after you load and +run several executable Apple programs, hitting Ctrl-DEL (rebooting the +Apple) will boot up the last DISK IMAGE you loaded (if any). This can be +confusing if you don't know whats going on (i.e, after finishing playing +MS. PACMAN and reseting the Apple, why is MUSIC CONSTRUCTION SET loading? +Because the disk is still in the drive from before). + + + +SAVING DISK IMAGES + +Pressing Right-Amiga-S will bring up a requester to save a disk image. +Disk images are saved in either the 143,360 byte "Generic" format, or in a +semi-compressed DDD format! The determination is made by the filename. To +compress a file in the DDD format, the filename must end with a '>' char. +Otherwise, it will be saved in the 143,360 byte format. If you do save the +image that way, it is suggested you append a ".disk" onto the filename to +maintain naming conventions (and so the requester will show the file). + +Keep in mind, DDD compression is not as tight as external compression +programs (LHA, etc). Also, loading/saving DDD files takes a couple extra +seconds to perform the (de)compression. + +@endnode + +@node TRANSFERRING "Transferring Apple Files/Disks/ROMs" + +TRANSFERRING APPLE FILES + +To get an executable binary file from a real Apple to the Amiga is quite +simple. Use a terminal program and and then transfer it via null-modem +(or however you want) to the Amiga. It's recommended you attach a .PROG to +the end of the filename for consistent naming conventions. + + +TRANSFERRING APPLE DISKS + +Only UNPROTECTED standard 16 sector Apple disks are currently useable. +This eliminates copy protected software. Simply run Dalton Disk +Disintegrator (do not use version 2.0! It has a bug! Use version 2.1) +and use it to compress the disk into a file. Then, transfer it to an +Amiga (as described in "Transferring Apple Files" above). Once on the +Amiga, ensure the filename ends in so the emulator recognizes it as +a DDD file. + + +TRANSFERRING APPLE ROMS + +The Apple emulator, being true to form, requires the actual Apple ROM data +in order for the Apple to do anything. The standard Apple ROMs in use +were the 'AppleSoft ROMs that contained AppleSoft BASIC, the assembly +language monitor, and autobooting code. So I suggest that you obtain the +same ROM if you would like the same compatibility. The ROM image can be +obtained by booting an Apple ][ or ][+ with DOS 3.3, then typing: + + BSAVE BASICROM,A$D000,L$2FFF + +to save it to disk. Also, the disk controller Rom (not required) can be +saved by typing: + + BSAVE DISKROM,A$C600,L$00FF + +Incidentally, the main ROM image is on Apple's "DOS 3.3 System Master" +disk, called FPBASIC (which may be used instead). After saving these +images to disk, use your favorite terminal software and a null modem cable +(or real modems or whatever you like) to transfer these files to the +Amiga. Once transferred to the Amiga, give these files the proper names +and place them in the same directory as the Apple2000 executable. + +Theoretically, you can use the ROMs obtained from an Apple ][ clone (i.e, +Franklin Ace, PineApple, etc.), but keep in mind that these ROMs were not +100% compatible (but were quite close). This would effectively make my +emulation a "Franklin Ace Emulator". :-) However, you CANNOT use the ROM +images from an Apple ][e, ][c, or ][gs (maybe eventually...we'll see)! + +Once on the Amiga, the main Rom MUST be named "_APPLE.ROM" and the disk +rom (if you have it) must be called _DISK.ROM. + +** NOTE ** +Starting with version 1.1, due to the difficulties people had trying to +obtain it, the _DISK.ROM is no longer required! If that file is not +present, Apple2000 will automatically use a custom-disk rom instead. +However, obtaining the true rom image is still recommended for 100% +compatibility with all software. + +These ROM files can also be found in several other Apple emulator archives +available on the net and on several CD-Rom compilations (including the PC +Apple ][ emulator called "Apple2Em.zip"). + + +@endnode + +@node PADDLE "Paddle/Joystick Emulation" + +PADDLE/JOYSTICK EMULATION + +The Apple ][ commonly uses either two paddles, an analog joystick, or a +graphics tablet (like a free-floating joystick). My emulation covers all +bases. Apple 2000 supports using these control devices: + + o Amiga Joystick (preferably 2 button, to emulate apple joystick) + o Amiga Mouse (to emulate free-floating joystick / paddles / Koala-pad) + o Analog PC Joystick (via FighterDuel dongle, to emulate apple joystick) + o Atari Paddles (to emulate apple paddles) + +The F9 key toggles through the choices and displays your selection at the +bottom of the screen. + + +Amiga Joystick: +--------------- +The emulator can utilize the standard amiga/atari/sega joystick +(preferably, a true 2-button joystick), and will assign the 8 switch +positions (up, up-right, right, etc) to the extreme values that an analog +stick would return (0 & 255). The "center" position defaults to the +optimum values (127 x 127), however, some games expect different center +values. This center value can be trimmed with the 2, 4, 6, & 8 keys on +the -numeric keypad- ONLY (see "Running Emulation"). For example, if you +start CHOPLIFTER and your character drifts towards the left, press the "6" +key to center the joystick more towards the right until your character no +longer drifts! (This is the emulated 'joystick trim' function). + +If you do not have a two button joystick, you have two choices. Spend $8 +and buy one, or else just use the Right-ALT key in lieu of the second +button (by the way, the two ALT keys work great for pinball games like +RASTER BLASTER). Note that the Sega Genesis Game controllers work well +with the amiga, and have two buttons! + +Amiga Mouse: +------------ +The emulator can utilize the absolute mouse coordinates, and this works +well for simulating a Koala-Pad graphics tablet, free-floating joystick, +or paddles (left/right control paddle #0, up/down control paddle #1). + +Programs designed for graphics tablets (KOALA PAD) or un-centered +joysticks work great in this mode, i.e, FANTAVISION, MISSILE COMMAND, +MUSIC CONSTRUCTION SET, and most other free floating cursor control +programs work ideally. The mouse works just like you would expect here. + +Analog PC Joystick: +------------------- +The emulation also supports true analog joysticks via joystick-dongles +(such as the adapter used for Fighter-Duel). The joystick will work just +like a real analog stick. + +*** Note: Apple 2000 uses "dynamic range setting & calibration" for analog +joysticks. This means that when you choose the "Analog Joystick" option, +the first thing you must do when starting to play your game is to move the +joystick over its full range of motion (extreme left, right, up, & down). +Once that is done, you need not worry about it anymore (unless you turn +off "Analog Joystick" and select it again). Joystick trimming is to be +done with the joystick's own trim pots. This 1 second of work from the +user ensures that Apple 2000 will work with a wide variety of joysticks. + +Atari Paddles: +-------------- +The emulator also now supports using actual Atari Paddles (the kind used +in the old Atari VCS/2600). They plug right into the amiga game port, and +work just like real apple paddles. NOTE: Like the analog joystick, the +paddles need to be moved over their complete range of motion when you +start to use them. + +Other game controller notes: +---------------------------- +Some of the older Apple games were designed to be used with paddles, not +joysticks. This is noticable in games (APPLE GALAXIAN, SNEAKERS) as in +when you release the joystick, your ship automatically moves back towards +the center point on the screen. This is exactly what would happen on a +real Apple with a joystick. You need to use some type of paddle emulation +here, either via the "Amiga Mouse" or "Atari Paddles" options. + +*** WARNING! While it is a bad habit many people have of (un)plugging game +controllers while the computer is on, be aware of this potential disaster: +Some of the Analog-Joystick Adapters have a metal jacket around the front +plug. This metal sheath has the potential to short out pins on the amiga +game port while trying to plug it in, which can damage your amiga! The +solution is simple: turn off your computer while changing controllers. +"An ounce of prevention..." + + +@endnode + +@node SPEED "Speed Regulation" + +SPEED REGULATION + + +"IT'S TOO FAST!" :-) +By popular request, Apple 2000 now offers selectable speed regulation so +people with fast systems can slow down games to humanly playable speeds. +Speed regulation is controlled via 5 function keys (F1 -> F5), which are +in order from slowest to fastest. + + F1 50% Apple Speed (0.5 Mhz) + F2 100% Apple Speed (1.0 Mhz) + F3 150% Apple Speed (1.5 Mhz) + F4 200% Apple Speed (2.0 Mhz) + F5 Unlimited (as fast as your system can go!) + +F2 selects "100% Apple Speed", which limits emulation speed to that of a +real Apple ][ (1.024 Mhz). F1 selects 50% (slow down games to half +speed), and F5 selects "unlimited speed" (which runs as fast as your +system can). + +Use of these keys during gameplay can be used as an aid- For example, +switching to 50% speed during a difficult part in an arcade game. Also, +some games on the apple might be a little sluggish compared to today's +standards and skills. 150% speed usually takes care of those. :) + +Understand that Speed Regulation works like a "Speed Limit". If your +system can't run the emulation quickly in the first place, choosing 150% +or 200% regulation won't have any noticeable effects (Like taking a '74 +Pinto out on the Autobahn. Who cares if there's no speed limit- You won't +go very fast. :) + +Keep in mind that Apple sound is made via speaker clicks and timing loops. +Faster/slower emulation will cause higher/lower pitched sound. + + + +"IT'S TOO SLOW!" :-( +Okay. For the remaining 93% of the Amiga owners who don't have '040s, +there are a few things that can be done to speed up the emulation. + +Press F5 to turn off speed regulation- This completely turns off the +overhead of the speed-regulation code. + +If you have an MMU (and an additional 512K free fast-ram), turn on the +"FastRom" option. (Type "CPU FASTROM" from the shell). + +If you are running ENFORCER, turn it off! On my system, graphics intensive +games slow down 20% while enforcer is running. + +Start "Apple 2000" in a relatively clean system with large blocks of +fast-ram available. (IE: Instead of trying to run the emulator while +you've been working on your system for 8 hours and have DirOpus, AMAX IV, +and ADPro all running, just reboot the system first). + +Of course, you can always add an accellerator to your system. ;-) + +@endnode + +@node STATUS "The Status Bar" + +THE STATUS BAR + +By popular request, the "Title Bar" at the top of the screen has been +removed, and has now been replaced with a new "Status Bar". The bar +appears at the bottom of the screen momentarily to notify the user of any +significant events, and then goes away. And it's black and white so the +grey scale users can read it. + +This bar displays significant messages, including feedback on Speed +Regulation Selections, Paddle/Joystick Controls, Apple Crashes, Help, and +disk drive access (including drive & track #'s). Most the time the status +bar will be invisible. + +@endnode + +@node TECH "Tech Notes" + +TECH NOTES + +Some Apple programs use "unimplemented" 6502 instructions. These are +instructions that are not official, but partially decode into doing a +particular function (as discovered by many unorthodox programmers). My +emulation does not support ANY unimplemented instructions, and will simply +break upon hitting any of those instructions (with Apple ][ software, I +have seen very few programs that use them). Those few programs will also +fail on the Apple ][gs. + +The ONLY graphics glitch is that the Hi-Res graphics screens do not fill +in the entire display width. That is, they leave a half-inch black border +on each side of the display. Why? Because the Apple Hi-Res screen has a +horizontal resolution of 280 pixels, and the Amiga's display has a minimum +resolution of 320. Trying to stretch this display by leaving an empty +pixel after every 7 pixels or drawing every 7th pixel twice, results in a +highly distorted and uneven image. The Text modes and LoRes modes still +use the entire screen width (to maintain aspect ratio). This slightly +narrow display is only noticeable in the 'mixed Graphics/Text' mode, where +text will be a little wider than the graphics above it. + +Also regarding Text and Graphics (but not a glitch, it's an improvement) +is the fact that mixed Graphics and Text on the old Apple ]['s originally +caused the text to be fringed with green and purple instead of being solid +white. This fringing has absolutely no purpose, but is a mere artifact of +the Apple video circuity. My emulation cleans it up with crisp & clean +text output at all times (does anybody have any complaints?). Apple +finally cleaned this up with the Apple ][gs and its RGB output (but +introduced a couple other graphic glitches), so I believe my clean Text +display is desirable. + +@endnode + +@node PLANNED "Planned Improvements" + +PLANNED IMPROVEMENTS + +Currently, emulation speed is pretty much as fast as possible under the +current 'interpreted' method. A speedup of about 3X is possible if I do +'pre-interpretation' which essentially converts 6502 code to native 680x0 +code ahead of time, then running it at full speed. However, this comes at +a cost of excessive memory usage (I estimate using about 2 megs for the +64k Apple emulation). This could be considered if enough people are +interested (this would be the final speed boost required for the A1200 +owners if they have enough memory!), but is of low priority for now. + +A 68000 version is easily possible, but emulation is so slow at that point +(games are frustratingly unplayable), that I haven't bothered to do one. + +I plan to add Apple printer & serial emulation (and redirection). This +way you could redirect Apple printer output to an Amiga file or to an +Epson emulator (to print Epson output to any Amiga Prefs printer). Or +emulate the Apple serial card with an Amiga Modem, etc. + +I plan to (eventually) upgrade the entire emulation to Apple ][e / ][c +status. This includes Apple "Double-Hi-Res" graphics, 128k RAM, and +80-column text. + +I have thought about writing a ProDOS driver allowing the Apple to access +Amiga devices as an Apple hard drive (is anybody using the emulator this +seriously?). + +I might tackle using a real 5�" disk drive if enough people want it. + +@endnode + +@node EMPLANT "What About EMPLANT?" + +WHAT ABOUT EMPLANT? + +My emulator, "Apple 2000" was (p)reviewed in Amiga Computing (Issue 71, +March 94), inside a larger review for the Emplant card (there's even a +screenshot where you can read my title bar, Apple 2000!). For all intents +and purposes, the review makes it APPEAR as if this program was written +by, owned by, and coming soon from Utilities Unlimited, makers of the +Emplant card (A macintosh emulator). Regardless, the reviewer loved it, +noting that this was the fastest 6502 emulation he has seen. + +At several World Of Commodore shows, Jim Drew showed my early versions of +"Apple 2000" to crowds of people during his presentations of his Mac +emulator. A friend even has a video-tape of Jim loading up and showing my +emulator to a crowd when I asked, "What other emulators are you doing?" +(before he knew who I was) at WOC in Pasadena, 1993. + +To set the record straight, I did send Utilities Unlimited several early +exclusive 'evaluation' versions of my emulator to see if they were +interested in purchasing it (for their Emplant package), but no agreements +were ever reached. Utilities Unlimited was in no way involved with the +development of, and has no connection to, this program (Apple 2000). + +This program is NOT part of the Emplant package, as many people have been +led to believe. The positive side of this is that you may use Apple 2000 +without having to spend >$300! + +@endnode + +@node ABOUT "About the Author" + +ABOUT THE AUTHOR + +"Apple 2000" was written by Kevin Kralian over the course of two years. +After serving in the US Marine Corps Infantry (!), he then earned a +college degree in Fire Technology, and continued in school towards his +Computer Science degree. He is also a volunteer FireFighter/EMT and a +freelance programmer. + +He has over 10 years of programming experience, including ADA, BASIC, C, +Pascal, 6502 and 680x0 assembly. Programming interests focus on +performance programming, including games and emulation. Career goals +include firefighter and game programmer. + +He has recently been hired as a full time game programmer, and is now +working on the Sega "Saturn". Good things do happen to good people. :-) + +He may be contacted at + +@endnode + + # # #### # # # # # + # # # # # # # # + ##### ### # # # # + # # # # + # # #### # # # # + +yuyuyuyuyatytytyt... This is Kevin at the keys... Congratulations! You +have found the "hidden part" of my doc file! I'm attempting to write some +senseless dribble like the Europeans do... It's another hot, sweltering +day (106� F)... I'm adding the final few touches to Apple 2000 v1.3, and +I'm running out of things to do to it... Good thing, I'm getting sick of +working on it!... Are their any LlamaTron fans out there? By far my +favorite game on the amiga, I've probably logged 500 hours into that game. +After killing that spinning thing on level 99, does anybody else have the +problem where the screen gets stuck "exploding" forever??? Ahhhhhh...... +I think I'll go out to the pool and vomit out all this beer I've ingested +while in my coding frenzy... (Just kidding! I'm trying to act european, +give me a break!) :-) Enjoy the program, folks! -Kevin Kralian 08/03/94 + +@node PAYMENT "Payment" + +"PAYMENT" FOR THIS PROGRAM + +This program is being distributed as Freeware, I do not expect monetary +payment. My original intentions were simply to have my program be 'used' +by the Amiga community, and I still feel the same way. I've worked long +and hard on this program and the most rewarding thing to me know would be +to simply know people are enjoying it! + +However, what I WOULD appreciate would be any technical references for any +computer/hardware/platform. Let me explain... + +Many improvements in the Apple emulator are dependant upon me finding +Apple technical reference material (i.e, unimplemented instructions, +serial/parallel support, ProDOS harddrive support, etc). If you would +like to see these features implemented, the biggest thing you can do is +send me any tech material that could be helpful. + +Also, some ideas for my next emulator include: Atari VCS (2600), GameBoy, +Nintendo, Atari 400/800 and Commodore 64/128. Though there are a few C-64 +emulators out there, many people have urged me to do one "the right way". +I tend to want to do the old Atari VCS or Gameboy emulation. HOWEVER, in +order to do this, I need tech information that I cannot publically obtain. + +Do YOU want these game machines to be emulated (I do)? If you are one of +those priviledged people who might have been involved in developing +software for any of these machines or somehow have any tech info on these +machines, please send me any and all tech information. *** I WILL *** +make an emulator of these machines when I have enough tech information to +do so. But I need your help. + +I am open to any suggestions, comments, or feedback. Let me know how the +emulator works for you. Please let me know of anything that does not work +(that works on a real Apple ][), and I will do my best to correct the +problem. I am also interested in obtaining any Apple ][ programs people +may have to test under my emulation. + +Anybody interested please contact me at + + +Particular things I'm looking for: + + o Whats Where in the Apple ][: An Atlas to the Apple computer + o Apple Super Serial Card / Parallel card manuals + o AmigaDOS Programmers Reference + o Any 2.0+ Amiga AutoDocs (AmigaGuide format would be cool!) + o ANY kind of tech info on Gameboy, Nintendo, or the old Atari VCS + (there once was an Apple ][ card to program the Atari. Anybody + have it?) + o Any and all Apple ][ programs. + o Any responses, reactions, suggestions, etc. on my emulation + o etc... + +@endnode + +@node CREDITS "Credits" + +CREDITS + +I owe lots of thanks to lots of people. + +Thank you my dearest JoAnnaBear for being so supportive of me and this +project over the last two years, and for not going crazy over my many +hours of "techno-babble", but just patiently smiling back as if you +understood me. :-) + +Thank you Robbie for all your inspiration and encouragement. And thanks +for your brainstorm sessions and hundreds of hours worth of second-hand +smoke (cough cough). Thank you for the book "Amiga Machine Language +Programming Guide" - the very first 680x0 assembly book I've seen +(blech!). By the way, this book was due back at the library in 1989! How +are your games "To Sir With Love" and "The Piano" coming along? Oh +yeah... and thanks for cleaning up and converting my docs to AmigaGuide +format for me :-) + +Thanks to Ronald J. Menelli, for his contribution of the "Disk2File" +conversion utility. ("Disk2File" is Copyright � by Ronald J. Menelli). + +Thank you Brian J. Bernstein, for his beautiful new Apple 2000 icon. +And thanks to the many others who sent icons. Apparently people did not +consider the little face representative of Apple2000? ;-) + +Thank you so much to Rand, another Firefighter, for recognizing a good +thing when he sees it. (Whats with all these firefighter/programmers?) + +Of course, Thanks to Jason Compton (Amiga Report columnist), the man who +did the first [authorized] review of Apple2000, and informed the public of +this great program. How could I have forgotten you for so long? + +Thanks Ed Brown, your support and encouragement has been exceptional! You +better be happy with the new "Analog Joystick Support" after telling me +about the advantages over the "digital" sticks! ;-) + +Thanks to "Nine Inch Nails" and "Frankie Goes to Hollywood" for their +soothing sounds to which much of Apple2000 was created. + +Thanks to the authors of other Apple ][ emulators on other platforms, for +their open discussions, comparisons, and sharing of emulation techniques +and technology. Their willingness to disclose results in improved software +for all computer users. + +Thank you to the many people who have contacted me about the initial +release of "Apple 2000". All of your letters of support, feedback, +contributions, suggestions, etc. are enthusiastically welcomed! + +Thanks to those incredible guys at Computer Cafe. I appreciate how you let +me use your various machines for debugging and testing during the +development of my emulation. Without your help, I would have never been +able to work out the '040 bugs, nor have seen my emulation running on a +28" monitor with cool 24 bit backgrounds. + +Thanks to Carmen Rizzolo, the computer artist extraordinaire! Your +original artwork for my previous programs are utterly amazing. Without +people like Carmen, where would we get cool 3D Star Trek and telephone +objects? + +Thanks to Will, the only intelligent Mac owner I know. It was great to +share ideas on high performance 6502 emulation with the 680x0. Have you +finished your Mac version of your Apple ][ emulator yet? Thanks for that +'half' of the "Inside the Apple //e" manual. Did you ever find pages +1-110? + +Thank you Nico Fran�ois, for your contributions to the Amiga community. +ReqTools is a very polished piece of work, and I know that your work has +saved me (and many others) hours of work trying to "recreate the wheel". +(Reqtools.library is Copyright � by Nico Fran�ois). + +Thanks to the many helpful people on the Internet, for helping me through +many obscure programming and debugging challenges. + +Thanks to Steve Wozniak for creating the original Apple ][. And congrats +to Apple Computer for knowing how to market computers and becoming a +large, successful company. Maybe Commodore can learn a few things from +you before they drive themselves out of business? [May '94- too late] + +Thanks to 'Dalton', for his "Dalton's Disk Disintegrator" (DDD) program on +the Apple ][. My (de)compression routines were based on his routines and +attempt to compress data in an identical, compatible way. + +Thank you Bill, for taking your family and moving far,far away. + +Thanks to an unnamed individual, for teaching me a very important lesson- +That I can never trust anybody, and that people like you will lie, cheat, +and steal to try and build the credibility of yourself/your company. Just +another page in your book of lies, eh? + +And finally, thanks to the many people I do not have space to mention, and +to all of the Amiga users who have made the Amiga scene as wonderful as it +is. + +@endnode + +@node HISTORY "History" + +HISTORY + +08/21/94 ***** Version 1.3 ***** + + o Controllable Speed Regulation (50%, 100%, 150%, 200%, Unlimited) + + o Overhauled entire video subsystem + - No more hardware hitting or copperlists + - Works happily with AGA/Mode promotions + - No more "Screen Jitter" for the few who had it + - Screens can be pulled down in front without disturbances + - All Apple screens can now be "Grabbed" + + o Added optional 2 disk drive support (via -2 command) + + o Overhauled File Loading/Saving related functions + - With 2 drives, loading/saving will prompt for drive # + - Saving: The proper "loaded" disk name will appear (for each drive) + - Saving: DDD vs 143,360 byte formats chosen via filename. + - Added "Warning: Disk Data Changed" notice during loads & quit. + + o Replaced TitleBar at top of screen with "Status Bar" at bottom + - Only shown during significant events + - Black and white (so greyscale users can read it) + + o Added support for Analog Joystick w/ 2 buttons + o Added support for Atari Paddles + + o Video page-flipping handled properly + - ShortCircuit, BileStoad, & OutPost run much better! + o A couple bug fixes (and duplicated a 6502 bug thats required) + - Canyon Climber, Drol animation, Frogger, Lode Runner, MoonPatrol, + Pinball Construction Set, Randamn, Sargon, & Tetris II All work! + o Added Lower Case Text display (Apple ][e charset) + o Optimized disk loading/decompression routines (twice as fast) + o Added a cheesy "Turn Off Monitor" effect when exited ;-) + o And of course, its a little bit faster! + +(Version 1.2 skipped due to misnamed archives already out) + +05/18/94 ***** Version 1.1 ***** + + o Wrote custom disk Rom that is used if _DISK.ROM file is not present! + (_DISK.ROM is no longer required! But still recommended...) + o Check for 68020+ CPU (instead of crashing) + o Support for 143,360 byte generic "disk images" (Loading/Saving) + (as used by many other emulators & available on the net) + o Disk images saved in "generic" format instead of DDD + (DDD format still recognized & loaded, though) + o Dos 3.3/ProDos headers recognized and handled in both disk images + and executable files (instead of just ProDos like version 1.0) + o Dos 3.3/ProDos/Raw ROM images all recognized and acceptable. + o Inclusion of "Disk2File" utility, which reads a 5�" Apple disk via + the C= 1020 Drive, and saves it as a file + o Included "Version" string + o Numerous optimizations (-slightly- faster) + + +04/10/94 ***** FIRST PUBLIC RELEASE v1.0 ***** + +@endnode + +@node FINDING "Finding Software" + +FINDING YOURSELF SOME SOFTWARE + +Finding apple disk images is like a treasure hunt. If you can't transfer +files yourself, there are lots of apple files out on the Net and BBS's. + +I'm told you can find lot's of disk images on anon ftp: + + wilbur.stanford.edu:/pub/apple2/disk_images and /pub/apple2/incoming + ftp.uni-kl.de:/pub/apple2/disk_images + cassandra.ucr.edu:/pub/apple2/incoming + + FSP site, at: 134.184.15.12 2424 + At (unknown) site at: minnie.sc.adfa.oz.au + +Expect difficulties! Some of the images have Mac headers on them that +need to be removed (Leave it to the mac to screw up a simple data file). +Some are compressed with Mac, Apple, or Unix protocols. Some have +out-of-order sectoring and need to be re-mapped (via AFID utility). Some +files are "text" files that try to install themselves via "executing" from +the apple. And many archives are simply corrupt and won't even work on +real Apples! + +The best way to avoid the headache of sifting through so much garbage is +to trade with other people who have known, tested, and working programs. +I've even been informed of several huge archives or commercial games for +Apple 2000 floating around many BBS's. + +That brings out another issue. Most these games are/were copyrighted, +commercial programs. But now what? Most the companies have since +dissolved, none of the apple programs are sold or produced anymore, and +who retains the copyright is hard to determine. This very issue has been +controversial for quite some time, and there is no easy answer. + +What is known is that many of the classic apple programs have been placed +in public domain by their authors (and many agree to it just by asking). +Some other companies have even placed all their old Apple titles into +public domain (as written in the late issues of A+ or InCider). The +sample programs I include with my archive, to the best of my knowledge, +are now in the public domain (according to statements in magazines or +what's sold by PD distributors). + +@endnode + +@node COMPATIBILITY "Compatibility" + +COMPATIBILITY + +Every effort was made to provide the highest degree of compatibility with +all Apple ][ software. This is a small sampling of the more than 600 +programs that I have successfully ran under Apple2000. + +AIR_CARS, ALIEN_AMBUSH, ALIEN_TYPHOON, ALPHAPLOT, APPLE_PANIC, APPLE_ZAP, +APPLECIDER, APPLEIIeINTRO, ASTEROID_FIELD, AUTOBAHN, BAG_OF_TRICKS, +BEAGLE_BAG, BEER_RUN, BEYOND_CASTLE_WOLFENSTEIN, BIG_MAC_ASM, BLISTERBALL, +BLITZKREIG, BOLO, BOULDER_DASH, BUG_ATTACK, BUG_BATTLE, BUZZARD_BAIT, +CANNONBALL.BLITZ, CENTIPEDE, CHAMPIONSHIP LODE RUNNER, CHIVALRY, +CHOPLIFTER, COMPUTER_FOOSBALL, CONAN, COPY_II+_7.4, COUNTY_CARNIVAL, +CROSSFIRE, CUBIT, CYCLOD, D-CODE, DEFENDER, DIG_DUG, DINO_EGGS, DOGFIGHT, +DOS_3.3_SYSTEM_MASTER, DRAGONFIRE, DRAW_POKER, DREADNOUGHTS, DUNG_BEETLES, +ELIMINATOR, F-15_STRIKE_EAGLE, FALCONS, FANTAVISION, FIGHT_NIGHT, +FIREBIRD, FISHIES, FLIGHT_SIM_II, FRAMEUP, FRAZZLE, FRENZY, GALAXIAN, +GOLD.RUSH, GRAPHICS_MAGICIAN, GREAT_CROSS_COUNRY_ROAD_RACE, GUARDIAN, +GULF_STRIKE, HACKER, HACKER_II, HARD_HAT_MACK, HARDBALL, HUNGRY_BOY, +INTERLUDE_II, INTERNATIONAL_GRAN_PRIX, JAWBREAKER, JPORT, JUMPJET, +JUNGLE_HUNT, KARATEKA, LABYRINTH, LEATHER_GODDESS_OF_PHOBOS, LEMMINGS, +MARAUDER, MARIO_BROS, MASQUERADE, MICRO_ILLUSTRATOR, MILLIONWAIRE, +MINE_SWEEP, MINER_2049ER, MR.DO, MS_PACMAN, MURDER_ON_THE_ZINDERNEUF, +MUSIC_MAKER, MUSIC_CONSTRUCTION_SET, NEPTUNE, NIGHT_MISSION_PINBALL, +NIGHTMARE.GALLERY, NORAD, PACMAN, PINBALL_CONSTRUCTION_SET, POOYAN, +POPPLES_XMAS_ADVENTURE, PRODOS_MASTER, RASTER_BLASTER, RED.ALERT, REPTON, +RESCUE_RAIDERS, ROADWAR_2000, ROBOTRON, ROCKET.COMMAND, SAMMY_LIGHTFOOT, +SEA_DRAGON, SERPENTINE, SHORT_CIRCUIT, SKYFOX, SNEAKERS, SPACE_RAIDERS, +SPACE_QUARKS, SPACE_WARRIOR, SPY.HUNTER, SPYS_DEMISE, SQUADRON_617, +STAR.THIEF, STAR_WARS_II, STARGATE, STARMAZE, STICKYBEAR_MATH#1, +STICKYBEAR_MATH#2, SUCCESSION, SUICIDE, SUMMER_GAMES, SUMMER_GAMES_II, +SUPER.PUCKMAN, SUPERMAP, SWASHBUCKLER, TAKE1, TAXMAN, TERRAPIN_LOGO, +THIEF, TIME_IS_MONEY, TRANQUILITY_BASE, TRIVIA_FEVER, TWERPS, +UBOAT_COMMAND, XEVIOUS, ZAXXON + +@endnode diff --git a/docs+icons/Apple2000.guide.info b/docs+icons/Apple2000.guide.info new file mode 100644 index 0000000..8626e9c Binary files /dev/null and b/docs+icons/Apple2000.guide.info differ diff --git a/docs+icons/Apple_2000.info b/docs+icons/Apple_2000.info new file mode 100644 index 0000000..3eba839 Binary files /dev/null and b/docs+icons/Apple_2000.info differ diff --git a/src/AppleII.s b/src/AppleII.s new file mode 100644 index 0000000..cdc1cbe --- /dev/null +++ b/src/AppleII.s @@ -0,0 +1,7146 @@ + SECTION APPLEII,CODE + +* Changes: PCount is a full 32 bit pointer, so memory model is now flat. ABSOLUTE!!! +* Full "GetByte" IS USED in insts that will ultimately PutByte! (due to hardware rds) +* Fixed a couple instructions to work with more flexible hardware emulation subs +* fixed intertask communication... + +* new changes: +* Optimized Video-mode rtns for consecutive mode-changing insts (do nothing until +* last instruction) +* Broke program into different SECTIONS (APPLEII,OPENCLOSE, and TABLES) +* A couple HW locations have data ($c020, $c060) to make a couple progs work +* Fixed Drive emulation to disable physical drive activity unless drive #1 is enabled +* (but ignoring motor status for now due to speed) +* Added 16K ram card emulation! (Currently ignores 2-access rule for write enabling) +* RESET will set system to ROM read and Write enable bank 2 (like //e, not //+) +* NumPad keys used to trim joystick center... (#2,4,5,6, & 8) +* Changing PCount during "Stop Inst" (eg: LOADING an executable) sets Video to Text1 +* Loading an executable file also sets ram card to "Rom Read" +* Added PCount History diagnostic for debugging... +* Added "FlushMsgs" so all inputs immediately after a requester are ignored +* Removed 1/2 second delay after requesters (due to fixed intertask comm & flush msgs) +* Added automatic DISK IMAGE COMPRESSION during save, with pseudo-prodos header! +* Expanded Joystick cycle counts to work with LodeRunner... +* Added toggleable MOUSE/JOYSTICK control of pdls... (f9 key) w/ word in title bar +* Reworked Title Bar/Window display so can read mouse buttons ANYWHERE in screen... +* Reworked Diagnostic message in title bar (each has a FORBID due to shared lib) +* Added a custom (blank) pointer so not to confuse it with apple progs... +* I think the DECOMPRESS function automatically handles both ProDos & Dos headers... +* Clear Slot Rom memory ($c100 - $c7ff) to FF's so ProDos thinks they're empty! +* Minor opt in PUSHWORD to write to memory once... +* Reworked all STAT macros! +* --Did I fix the Copperlists by adding a CBUMP at the end of each one??? +* DOCYCLE reads word with PostInc'ing of PCount (so PCount needs less adding) +* ** Reg d0 is kept with top word clean at ALL TIMES in 6502 emulation. ** +* Lots of MEM_addressing & cpu optimizations because of it... +* Opt'ed BIT__ functions for more straightforward Status update... +* Hi-Res draw routines first check if memory has been changed! (big opt!) +* Text/Lo-Res draw routines first check if memory has been changed! +* Sound is sent to both channel 0 & 1 (stereo'ish) +* Fixed mischevious bug (undocumented) in PUSHSTAT subroutine... (see it) +* Optimized: JSR, RTS, ADC, SBC, ROL, ROR... +* Upon loading executable Apple prog, low memory is reset to fresh "power-up" state + + +* Major opts to:Vector-Jump table now 256K (16 bit word referenced * 4) +* DOCYCLE doesn't have to clear hi 8 bits of word anymore +* All MEM_IMMED routines opt'd to not reference memory, but use d1 from DOCYCLE +* All Bcc's dont reference mem, but use d1 from DOCYCLE (& other opts) + +* PUBLIC RELEASE v1.0 around in April, 94 + +* 04/21/94 Fixed PBHardware so "unhandled" writes DO NOT change memory +* (fixed probs w/ button read on "Red Alert", which tried to ROL $c061) +* 04/26/94 Included Custom Disk Rom that is used if _DISK.ROM file not present +* 04/27/94 Included ability to load 143,360 byte generic "disk images" +* 04/29/94 Upon any ResumeCPU call, re-activate our window... +* 04/29/94 Check for 68020+ CPU (instead of crashing!) +* 04/29/94 Reading from $c050 - $c057 returns progressive data (Tetris II now boots) +* 05/01/94 Now saves disk images in 143,360 byte "generic disk image" instead of DDD format +* 05/01/94 Opt'd STAT routines a little (ie: use BCHG instead of EOR for inverse carry) +* 05/01/94 Opt'd TX_ Insts to use STAT_SZfast instead of STAT_SZ +* 05/01/94 Opt'd all CLC+ADC and SEC+SBC combinations... +* 05/07/94 Proper Dos/ProDos executable/disk image/Rom file recognition +* 05/08/94 Opt'd all DEX/INX/DEY/INY + CPX/CPY Insts... +* 05/11/94 Put STACK in HIGH WORD of register to make lower word available for use!!!!!! +* 05/13/94 Opt'd STAT_ stuff... +* 05/15/94 Opt'd all DEX/INX/DEY/INY/PHA/TAX/TAY + LDA instruction pairs +* 05/18/94 Opt'd bunch more xxx + STA instruction pairs... +* PUBLIC RELEASE v1.1 on 05/18/94 + +* 05/28/94 Added support for Analog Joystick w/ 2 buttons! +* 05/29/94 Fixed Stack (now 100% accurate) so words wrap on same page +* (Sargon, MoonPatrol, Lode Runner, Pinball Co Set now work) +* 06/01/94 Added "Page-flipping loop" recognition & skipping... +* (ShortCircuit,BileStoad,OutPost) +* 06/04/94 Overhaul entire video subsystem! No more copper lists, hardware hitting, etc... +* 06/10/94 Continuing to optimize video switches... Useless changes ignored +* 06/17/24 Added StatusBar messaging system +* 06/20/94 Added Lower Case characters from //e charset +* 06/20/94 Flashing/Color-changing only occurs when flashing is visible. +* 06/24/94 Added Dynamic Analog Joystick ranging (for different joysticks) +* 06/24/94 Added Atari Paddle support +* 06/24/94 "Requestor Screen" now uses Workbench colors +* 06/30/94 Fixed AGA/Mode promo bug... Can't set more colors than screen allows! +* 07/01/94 Added 2 drive support (via -2 command) to hardware ($C0xx) handlers... +* 07/02/94 Added 2 drive req support to load/save commands +* 07/03/94 All video-HW reads return values from list (Canyon Climber, Tetris II ttl, Drol) +* 07/03/94 Made keyboard read vals for $c000 - $c007 (Frogger into screen works) +* 07/10/94 Optional DDD compression by ending filename in '>' during save +* 07/12/94 16K card banking routines optimized to prevent needless memcpy... +* 07/15/94 Working Speed Regulation & interface (60 hz screen only) +* 07/17/94 Added 6502 bug- Jump ($xxff) wrap-around getting indirection... (Randamn works) +* 07/18/94 Optimized DDD decompress & denibbleize functions... +* 07/19/94 FileReqs retain independant filenames for each drive for loading/saving +* 07/22/94 Fixed "Rewrite file xxx" requester... +* 07/22/94 Opt'd DDD compress & some saving routines... +* 07/23/94 Screen now 200 lines (standard size) +* 07/24/94 Re-did Joystick & Mouse pdl emu routines (simple, full-range of motion) +* 07/28/94 Added "Warning- Disk image Changed" warnings during disk loads & quit +* 07/28/94 Opt'd Memory Address modes even more... +* 07/28/94 Opt'd BIT, ROL, ROR, ASL insts +* 07/29/94 Free'd up a register ("Temp") by using stack instead (seldom) +* 07/29/94 Opt'd CLC/SEC + ROL pairs... +* 08/02/94 Added cheesy "Monitor off" effect +* 08/18/94 Used old default "requester" colors again... (not WB) +* 08/20/94 Default speed regulation to 100% + +* To Do: +* check ADC/SBC bcd status settings, optimize ROL,ROR,ASL, etc... +* Handle lores/hires page swapping (gorgon, zenith, space voyage, etc...) +* Add Icon... +* Check keymap thing (# on swedish keyboard) +* check if potbits & intrpts are turned off at exit properly... + +* Comments: Map is clean and flat from $0000->$FFFF +* IMPORTANT! Reg d0 MUST be kept with top word clear at ALL TIMES in 6502 context. + +AReg EQUR d7 ;AReg,XReg,&YReg are clean 8 bit nums. KEEP CLEAN!!! +XReg EQUR d6 +YReg EQUR d5 +StatusSZ EQUR d4 +Cycles EQUR d3 ;Progressive counter of effective apple cycles... +Stack EQUR d2 ;(Stack) -> Current byte of stack ($100 - $1ff)(HIGH WORD ONLY!!!!!) +StatusCV EQUR d2 ;bottom word only (shared w/ Stack) + +;Temp EQUR a5 ;for routines (CPU inst's) to backup data... +Mem_Ptr EQUR a4 ;reference start of 64k apple memory block... +InstTbl EQUR a3 +PCount EQUR a2 ;ABSOLUTE 32 bit ptr, not index! + rts + + +**************************************** +* General Note: All "F" routines are FastGetByte or FastPutByte functions, +* which read/write from apple memory in a QUICK fashion, with no checks +* or support for i/o accesses. 6502 Instructions, Operands, and addressing +* from memory use these routines, and therefore will execute differently +* from an actual apple in these conditions. However, executing from i/o +* would be a rare circumstance (NO reason for it), and in all probability +* would only happen during an apple-crash. +* +* Reading from ROM or RAM Banks (for speed) is not checked for but +* is accounted for. When apple i/o to change "bank/Rom to read from" is +* set, memory is actually copied to the top ($d000-$ffff, whatever) area. +**************************************** +CLEAR MACRO.w + moveq.l #0,\1 + ENDM + +******************************* +* FPUTBYTE does a quick PutByte with no i/o,hardware,graphic checks. +* Enter: a0 = LONG 16 bit address (clean in top 16 bits!!!) to write +* d0 = Byte to write +******************************* +FPUTBYTE MACRO.w + move.b d0,(Mem_Ptr,a0.l) + ENDM + +***************************************** +* FGETBYTE does a quick GetByte with no i/o checks. Preserves high bits. +* Enter: a0 = LONG 16 bit address (clean in top 16 bits) to read +* Return: d0 = Byte read, clean! +***************************************** + +FGETBYTE MACRO.w + move.b (Mem_Ptr,a0.l),d0 [14]= 18 total! + ENDM + + +********************************* +* FGETWORD does a fast read of a 'normalized' word from apple memory. No i/o. +* Enter: A0 = Long 16 bit addr to read. +* Return: D0 = Word in form 'xxxxHILO', preserving top 16 bits. +********************************** (used in Brk, ResetCPU, and MEM_routines) +FGETWORD MACRO.w + move.w (Mem_Ptr,a0.l),d0 + ror.w #8,d0 + ENDM + +***** FGETWORDd0 is same as FGETWORD, but refs "D0" instead of "A0" ***** +FGETWORDd0 MACRO.w + move.w (Mem_Ptr,d0.l),d0 + ror.w #8,d0 + ENDM + +************************************************** +* GETBYTE - General Routine to Read a Byte of Memory from apple memory. +* Checks for hardware/io access, and handle if rqrd. +* Enter: D0 = LONG 16 bit addr to read (CLEAN!) <------ d0!!!! +* Return: D0 = Byte of Data in D0:0-7. (FGetByte is fast-no check) +****************************************** +GETBYTE MACRO.w + cmp.w #$c000,d0 [6] ;in $c001 - $c0ff range??? + bls.b .InBnd [9] + cmp.w #$c0ff,d0 + bhi.b .InBnd + + bsr GBHardWare ;HardWare! Go Handle! + and.l #$ff,d0 ;remove once all GBHardware routines cleaned... + bra.b .EndGB + CNOP 0,4 +.InBnd move.b (Mem_Ptr,d0.l),d0 ; [14] +.EndGB + ENDM + +************************************************* +* PUTBYTE - General Routine to Write a Byte of Memory to apple memory. +* Checks for ALL EXCEPTIONS (hardware/io/Video pages), and handle if rqrd. +* ENTER: D0 = LONG 16 bit addr to write, +* D1 = Byte to write. +************************************************* + +PUTBYTE MACRO.w + move.l d0,a0 [03] + lsr.w #8,d0 ;/64 Memory page # * 4... [04] + + move.l #PBPageList,a1 [5] + move.l (a1,d0.w*4),d0 [11] = [29] ! + + beq.b .safe\@ + move.l d0,a1 + jsr (a1) ;A0 = address, d1 = Data !!!! + CLEAR d0 ;remove when all routines clean... + bra.b .cont\@ +.safe\@ move.b d1,(Mem_Ptr,a0.l) ;modified FPUTBYTE +.cont\@ + ENDM + +PUTBYTE_DOCYCLE MACRO.w + move.l d0,a0 [03] + lsr.w #8,d0 ;/64 Memory page # * 4... [04] + + move.l #PBPageList,a1 [5] + move.l (a1,d0.w*4),d0 [11] = [29] ! + + beq.b .safe\@ + move.l d0,a1 + jsr (a1) ;A0 = address, d1 = Data !!!! + CLEAR d0 ;remove when all routines clean... + bra.b .cont\@ +; DOCYCLE +.safe\@ move.b d1,(Mem_Ptr,a0.l) ;modified FPUTBYTE +.cont\@ DOCYCLE + ENDM + +******************************** +* PUSH/PULL will push or pull selected byte to/from Apple Stack ($100-$1ff). +* eg... "PUSH d0", "PULL AReg" etc.... DO NOT push/pull Status this way!!!! +* +* NOTE: Due to Opts, Pre/Post +- opposite of 6502, +* and "Stack" is +1 actual location. TSX & TXS fixed. (INVALID- Works identically) +******************************** +PUSH MACRO.w ;eg "PUSH d0" + swap Stack + move.b \1,(Mem_Ptr,Stack.w) ; [08] + subq.b #1,Stack + swap Stack + ENDM + +PULL MACRO.w ;eg "PULL AReg" + swap Stack + addq.b #1,Stack + move.b (Mem_Ptr,Stack.w),\1 ; [08] + swap Stack + ENDM + +************************************* +* PUSH16 / PULL16 will push or pull a word to/from apple stack & update. +* Push - Hi 1st, LO 2nd. Pull - LO first, HI 2nd. +* Enter: (PUSH16) = D0 = Word to push +* Return (PULL16) = D0 = Word from stack +************************************** +PUSH16 MACRO.w + ror.w #8,d0 + PUSH d0 + lsr.w #8,d0 + PUSH d0 + ENDM + + ;Pull 16 bit number from Apple Stack... LO byte, Then Hi + ;Update Stack ptr and return # in D0 +PULL16 MACRO.w + PULL d1 + PULL d0 + lsl.w #8,d0 + move.b d1,d0 + ENDM + + +***** All the grind work due to using different bits in the emulated StatusReg +***** are taken care of when pushing/pulling status here... +* Strangely, it appears that the Break flag is always set upon pushing the Status. +* Perhaps its only clear during an interrupt? Saving it as clear allowed a nasty +* bug in Dos 3.3 filtered text, accidentally making a match to the "INIT" command. +* (See dos 3.3 $9fc0 - $9a10). Experiments on the //gs show even if B is forced clear, +* any command that changes the Status reg will automatically set B as well... + +* Apple Status= ; Bit 7 6 5 4 3 2 1 0 + ; _________________________________ + ; | S | V | | B | D | I | Z | C | + ; +---+---+---+---+---+---+---+---+ + ; | | | | | | |__Carry + ; | |_Over- | | | |_Zero + ; | Flow | | |_Intrpt Disable + ; |_Sign | |_Decimal + ; |_Break + + +PUSHSTAT MACRO.w ;pushes status in proper apple way + ;build d0 in proper 6502 Status form (above) +.s7 btst.l #S_BIT,StatusSZ [05] + sne.b d0 [04] + lsl.w d0 [04] + +.v6 btst.l #V_BIT,StatusCV + sne.b d0 + lsl.w d0 + +.b54 move.b #$ff,d0 ;B Always set (& unused bit 5 set too!) + lsl.w #2,d0 + +.d3 btst.l #D_BIT,StatusSZ + sne.b d0 + lsl.w d0 + +.i2 btst.l #I_BIT,StatusSZ + sne.b d0 + lsl.w d0 + +.z1 btst.l #Z_BIT,StatusSZ + sne.b d0 + lsl.w d0 + +.c0 btst.l #C_BIT,StatusCV + sne.b d0 + lsl.w d0 + + lsr.w #8,d0 + PUSH d0 + ENDM + +* Apple Status= ; Bit 7 6 5 4 3 2 1 0 + ; _________________________________ + ; | S | V | | B | D | I | Z | C | + ; +---+---+---+---+---+---+---+---+ + ; | | | | | | |__Carry + ; | |_Over- | | | |_Zero + ; | Flow | | |_Intrpt Disable + ; |_Sign | |_Decimal + ; |_Break + +PULLSTAT MACRO.w + PULL d0 +; moveq.l #0,StatusSZ ;build internal Status from 6502 form (above) +; move.w #0,StatusCV ;low word only... + +.bdi move.b d0,StatusSZ [03] ;Got B, D, and I + swap StatusSZ [04] + +.sBit lsl.b d0 [04] ;get S (temporarily in bit 8) + scs.b StatusSZ [04] + lsl.w StatusSZ [04] + +.vBit lsl.b d0 ;get V + scs.b StatusCV + lsl.w StatusCV + +.cBit lsr.b #3,d0 ;get C + scs.b StatusCV + +.zBit lsr.b d0 ;Get Z + scs.b StatusSZ + lsr.w #5,StatusSZ ;and slide S & Z to proper bits... + + ENDM + +************************************* +* All MEM_ routines are to handle different 6502 address modes. +* Note: Due to 16 bit read of PCount mem, optimizations are made by +* expecting low byte in D0 to have next byte of data! +* +* Enter: "PCount" = pointing at opcode +* D0 = word of data from "PCount" +* Return: D0 = operand's 16 bit address in A0 (CLEAN!) -----D0----- +* PCount = PCount + Full Inst Size +* +************************************* +MEM_Abs MACRO.w ;*** LDA $xxxx *** + move.b (PCount)+,d0 [07] + lsl.w #8,d0 [04] + move.b d1,d0 [03] = 14 + ENDM + +MEM_ZP MACRO.w ;*** LDA $xx *** + moveq.l #0,d0 [03] + move.b d1,d0 [03] + ENDM + +MEM_PreIndx MACRO.w ;*** LDA ($xx,X) *** + move.w XReg,d0 ;(clear high byte) + add.b d1,d0 ;FGETBYTE1PC + ;FGETWORDd0 ;get 16 bit # being pointed at + move.w (Mem_Ptr,d0.l),d0 + ror.w #8,d0 + ENDM + + +MEM_PostIndx MACRO.w ;*** LDA ($xx),Y *** + moveq.l #0,d0 + move.b d1,d0 + FGETWORDd0 + add.w YReg,d0 ;16 bit add...(YReg & d0 must be clean!) + ENDM + +MEM_ZPIndxX MACRO.w ;*** LDA $xx,X *** + move.w XReg,d0 + add.b d1,d0 ;8 bit add + ENDM + +MEM_ZPIndxY MACRO.w ;*** LDA $xx,Y *** + move.w YReg,d0 + add.b d1,d0 ;8 bit add + ENDM + +MEM_AbsIndxX MACRO.w ;*** LDA $xxxx,X *** + move.b (PCount)+,d0 [07] + lsl.w #8,d0 [04] + move.b d1,d0 [03] = 14 + add.w XReg,d0 ;16 bit add + ENDM + +MEM_AbsIndxY MACRO.w ;*** LDA $xxxx,Y *** + move.b (PCount)+,d0 [07] + lsl.w #8,d0 [04] + move.b d1,d0 [03] = 14 + add.w YReg,d0 ;16 bit add + ENDM + + +*** OLDMEM routines and are for 2'nd INST of CPU inst pairs that don't have operands in D1. +** They read from and Inc PCOUNT to get operands. + +OLDMEM_Abs MACRO.w ;*** LDA $xxxx *** + move.w (PCount)+,d0 [07] + ror.w #8,d0 [08] = [15] + ENDM + +OLDMEM_ZP MACRO.w ;*** LDA $xx *** + moveq.l #0,d0 + move.b (PCount)+,d0 [07] + ENDM + +OLDMEM_PreIndx MACRO.w ;*** LDA ($xx,X) *** (optd) + move.w XReg,d0 + add.b (PCount)+,d0 + FGETWORDd0 ;get 16 bit # being pointed at + ENDM + +OLDMEM_PostIndx MACRO.w ;*** LDA ($xx),Y *** + moveq.l #0,d0 + move.b (PCount)+,d0 + FGETWORDd0 + add.w YReg,d0 ;16 bit add...(YReg & d0 must be clean!) + ENDM + +OLDMEM_ZPIndxX MACRO.w ;*** LDA $xx,X *** (optd) + move.w XReg,d0 + add.b (PCount)+,d0 ;8 bit add + ENDM + +OLDMEM_ZPIndxY MACRO.w ;*** LDA $xx,Y *** (optd) + move.w YReg,d0 + add.b (PCount)+,d0 ;8 bit add + ENDM + +OLDMEM_AbsIndxX MACRO.w ;*** LDA $xxxx,X *** + move.w (PCount)+,d0 + ror.w #8,d0 + add.w XReg,d0 ;16 bit add + ENDM + +OLDMEM_AbsIndxY MACRO.w ;*** LDA $xxxx,Y *** + move.w (PCount)+,d0 + ror.w #8,d0 + add.w YReg,d0 ;16 bit add + ENDM + +OLDMEM_ImmedD0 MACRO.w ;*** LDA #$08 *** + move.b (PCount)+,d0 ;(returns immediate val in d0) + ENDM + + +*************************************************8 +* STAT_ routines check actual CCR reg after an instruction, and will +* copy pertinent bits to Status. +* +* Enter: amiga CCR = conditions set (via operations) +* Return: Status = new status bits properly set +* +* NOTE: due to opts, the BIT / HEX settings are DIFFERENT than the 6502 cpu +* status register. PUSH/PULL STATUS routines accomidate this difference, +* so the apple will never know. + +B_BIT equ 20 ;(7,6,5 not in Amiga ccr, but we'll let 'em be in Status high word anyways) +D_BIT equ 19 +I_BIT equ 18 + +S_BIT equ 3 ;within StatusSZ word (just like amiga CCR) +Z_BIT equ 2 + +V_BIT equ 8 ;within StatusCV word +C_BIT equ 7 + +S_HEX equ $1<bit 7, V ->8 [04] = 13 + ENDM + + +STAT_SVZiC MACRO ;for SBC & CMP due to inverse C... (SBC) + move.w ccr,StatusSZ [06] + move.b StatusSZ,StatusCV [03] + lsl.w #7,StatusCV [04] + bchg.l #C_BIT,StatusCV [05] = 18 + ENDM + +************************************** +* "Regulate" is a macro that checks if speed regulation is necessary, and if so, +* it properly waits the rqrd amount of time. +************************************** +REGULATE MACRO.w + + move.l WaitCycPerFrame,d0 ;d0 = WaitCyc, if -1 then no regulation! + bmi.b .done + + move.l Cycles,d1 ;CurrentCycle - LastStopCycle = ElapsedCycles + sub.l LastStopCycle,d1 ; (okay if Cycles has wrapped around) + sub.l d0,d1 + bmi.b .done + + move.l CIAControlReg,a0 +.wait btst.b #0,(a0) ;wait for timer to finish + bne.b .wait + bset.b #0,(a0) ;and restart it + + add.l d0,LastStopCycle + sub.l d0,d1 ;Reset LastCycleCount + bpl.b .wait + +.done + moveq.l #0,d0 + ENDM + +RegulateSize dc.l .end-.strt +.strt REGULATE +.end + + +************************************** +* "DoCycle" is the main routine that reads instruction & jumps via +* table to code to process it. Call with all CPU vars set! +************************************** +DOCYCLE MACRO.w +; jsr KeepHistory ;FOR DEBUGGING!!!! ---------------- + move.w (PCount)+,d1 ;read byte, inc PCount by 2... [07] + move.l (InstTbl,d1.w*4),a0 + jmp (a0) + CNOP 0,8 + ENDM + + + CNOP 0,4 +PCountIndex dc.l 0 + +PCHistory: + ds.l 256 ;for PC history for debugging!!! + + EVEN +KeepHistory: + move.l PCountIndex,d0 + move.l PCount,(PCHistory.l,d0.l*4) + addq.b #1,d0 + move.l d0,PCountIndex + rts + +ReportHistory: + move.l d2,-(sp) + + lea .msg,a0 + jsr DB_String ;"PC History:" + move.l PCountIndex,d1 + sub.b #40,d1 ;d1 = memIndx + move.l #39,d2 ;d2 = count +.lp move.l (PCHistory.l,d1.l*4),d0 + sub.l Mem_Ptr,d0 + sub.l #2,d0 ;adjust for PostInc of PCount + jsr DB_HexW ;Print HexAddr... + addq.b #1,d1 + dbf d2,.lp + move.l (sp)+,d2 + rts + + +.msg dc.b "6502 execution history:",10,13,0 + + CNOP 0,4 +Start6502: ;*** ONLY CALL to BEGIN 6502 emu task!!!! *** + move.l #-1,d0 + CALLEXEC AllocSignal ;Get signal for Stop/Resume control. + move.l d0,ChildSigBit ;(fail now and we're screwed!!!) + moveq.l #0,d1 + bset d0,d1 + move.l d1,ChildSigMask + + jsr RestoreTable + + move.l ParentTaskPtr,a1 + move.l ParentSigMask,d0 + CALLEXEC Signal ;critical init'ing done... Tell parent.. + + move.w #60,Hardware+aud0+ac_vol.l ;Set Channel 0 Volume to Max + move.w #1,Hardware+aud0+ac_per.l ;Channel 0 Period + move.w #60,Hardware+aud1+ac_vol.l ;Set Channel 1 Volume to Max + move.w #1,Hardware+aud1+ac_per.l ;Channel 1 Period + + move.l Mem_PtrVar,Mem_Ptr + move.l InstTbl_Var,InstTbl <---- + add.l #$20000,InstTbl ;due to (-) word offset reference... + + moveq.l #0,Cycles ;start it with 0 elapsed cycles... + move.l Cycles,LastStopCycle + + move.l #0,PCount + clr.l XReg + clr.l YReg + clr.l AReg ; _____ (set rom/ram if rqrd) + move.l #$fffc,a0 ; RESET vector! + moveq.l #0,d0 + FGETWORD ;D0=apple PC (clean) + add.l Mem_Ptr,d0 + move.l d0,PCount + move.l #$01ff0000,Stack ;reset it to top of frame! (high word is used) + clr.l StatusSZ + bset.l #I_BIT,StatusSZ + bset.l #B_BIT,StatusSZ + + move.b #%00000001,VidMode ;text page 1 + jsr RefreshVideo + + + CLEAR d0 + + DOCYCLE + + ;All CPU instructions are labeled in 3 letter CAPS, + ;followed by the Hex Opcode for it... eg: BRK00 . + ;Internal Names are 3 letter CAPS, followed by + ;a _MEM if gets/puts addr, _ACC if gets addr, puts ACC. + ;Enter with: PCount pointing to OpCode + 2 !!!! D1 = word of mem... + ;Internally ( _Acc, _Mem) enters with A0= + ;All are called directly from DOCYCLE + + ;NOTE: Due to a global optimization in 6502 emulation code, + ; register d0 must always maintain the high word as 0. + ; Any instruction code/hardware handler MUST obey! +*------------------------- BRK / UNDefined --------------------------* +UND00: +; jsr ReportHistory ;<------- DEBUGGING DIAGNOSTIC! + lea .UNDMsg,a0 + lea .UNDMsg2,a1 + bra BrkPrnt + +.UNDMsg dc.b "!!! UNDEFINED INST AT $" +.UNDMsg2 dc.b "0000",0,50 + + EVEN + +BRK00: +; jsr ReportHistory ;<------- DEBUGGING DIAGNOSTIC! + lea .BRKMsg,a0 + lea .BRKMsg2,a1 + bra BrkPrnt + +.BRKMsg dc.b "!!! BREAK INST AT $" +.BRKMsg2 dc.b "0000",0,50,0 + + EVEN + +BrkPrnt move.l PCount,d0 ;<--- for our information + sub.l Mem_Ptr,d0 + sub.l #2,d0 ;adjust for PostInc'ing of PCount + + move.w d0,d1 ;parse hex digits... + lsr.w #8,d0 ;1st digit... + lsr.w #4,d0 + add.b #'0',d0 + cmp.b #'9',d0 + bls 1$ + add.b #'A'-'9'-1,d0 +1$ move.b d0,(a1)+ + + move.w d1,d0 + lsr.w #8,d0 ;2st digit... + and.b #$0f,d0 + add.b #'0',d0 + cmp.b #'9',d0 + bls 2$ + add.b #'A'-'9'-1,d0 +2$ move.b d0,(a1)+ + + move.w d1,d0 + lsr.b #4,d0 ;3rd digit... + add.b #'0',d0 + cmp.b #'9',d0 + bls 3$ + add.b #'A'-'9'-1,d0 +3$ move.b d0,(a1)+ + + move.w d1,d0 ;4th digit... + and.b #$0f,d0 + add.b #'0',d0 + cmp.b #'9',d0 + bls 4$ + add.b #'A'-'9'-1,d0 +4$ move.b d0,(a1)+ + + move.l a0,NewStatusMsgPtr ;and set to print! + +.DoActualBreak: + + move.l #$c081,d0 ;reset 16k card on reset! + GETBYTE +;floob move.l #$c081,d0 +; GETBYTE + + bset.l #B_BIT,StatusSZ ;Set Break bit... + move.l PCount,d0 + sub.l Mem_Ptr,d0 + PUSH16 + PUSHSTAT + bset.l #I_BIT,StatusSZ ;Set Intrpt Mask + move.l #$fffe,a0 + moveq.l #0,d0 + FGETWORD + add.l Mem_Ptr,d0 + move.l d0,PCount + addq.l #7,Cycles + CLEAR d0 + DOCYCLE + + + EVEN +*------------------- ADC ------ Add Mem + Carry -> Acc---------*** STATUS DEPENDANT *** +ADC6D: MEM_Abs ;ADC $1234 + addq.l #4,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ [05] + bne.b .bcd [05] +.dec lsr.b #8,StatusCV [04] Sets/Clrs X flag based on C in Status & Sets Z Flag + addx.b d0,AReg [03] ADDX - Z flag only cleared, not set! = [17] + STAT_SVZC + DOCYCLE +.bcd lsr.b #8,StatusCV ;Sets/Clrs X flag based on C in Status & Sets Z Flag + abcd.b d0,AReg ;ABCD - Z flag only cleared, not set! + STAT_SZC ;manual says Z not set. Is V??? + DOCYCLE + +ADC61: MEM_PreIndx ;ADC ($06,X) + addq.l #6,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + addx.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd lsr.b #8,StatusCV + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +ADC71: MEM_PostIndx ;ADC ($06),Y + addq.l #5,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + addx.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd lsr.b #8,StatusCV + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +ADC79: MEM_AbsIndxY ;ADC $1234,Y + addq.l #4,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + addx.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd lsr.b #8,StatusCV + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +ADC7D: MEM_AbsIndxX ;ADC $1234,X + addq.l #4,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + addx.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd lsr.b #8,StatusCV + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +ADC65: MEM_ZP ;ADC $06 + addq.l #3,Cycles + move.b (Mem_Ptr,d0.l),d0 + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + addx.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd lsr.b #8,StatusCV + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +ADC75: MEM_ZPIndxX ;ADC $06,X + addq.l #4,Cycles + move.b (Mem_Ptr,d0.l),d0 + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + addx.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd lsr.b #8,StatusCV + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +ADC69: move.b d1,d0 ;Mem_Immed - ADC #$06 + addq.l #2,Cycles + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + addx.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd lsr.b #8,StatusCV + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +*--------------------------- AND -----------------------------------* +AND2D: MEM_Abs ;AND $1234 + addq.l #4,Cycles + GETBYTE + and.b d0,AReg + STAT_SZ + DOCYCLE + +AND21: MEM_PreIndx ;AND ($06,X) + addq.l #6,Cycles + GETBYTE + and.b d0,AReg + STAT_SZ + DOCYCLE + +AND31: MEM_PostIndx ;AND ($06),Y + addq.l #5,Cycles + GETBYTE + and.b d0,AReg + STAT_SZ + DOCYCLE + +AND39: MEM_AbsIndxY ;AND $1234,Y + addq.l #4,Cycles + GETBYTE + and.b d0,AReg + STAT_SZ + DOCYCLE + +AND3D: MEM_AbsIndxX ;AND $1234,X + addq.l #4,Cycles + GETBYTE + and.b d0,AReg + STAT_SZ + DOCYCLE + +AND29: ;MEM_Immed - AND #$06 + addq.l #2,Cycles + and.b d1,AReg + STAT_SZ + DOCYCLE + +AND25: MEM_ZP ;AND $06 + and.b (Mem_Ptr,d0.l),AReg + STAT_SZ + addq.l #3,Cycles + DOCYCLE + +AND35: MEM_ZPIndxX ;AND $06,X + and.b (Mem_Ptr,d0.l),AReg + STAT_SZ + addq.l #4,Cycles + DOCYCLE + +*--------------------------- ASL -----------------------------------* +ASL0E: MEM_Abs ;ASL $1234 + addq.l #6,Cycles + move.w d0,-(sp) + GETBYTE ;must do safe read in case of PDL, DISK, etc... + + move.b d0,d1 + lsl.b d1 ;lsl leaves V flag clear + STAT_SZC + + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + +ASL1E: MEM_AbsIndxX ;ASL $1234,X + addq.l #7,Cycles + move.w d0,-(sp) + GETBYTE + move.b d0,d1 + lsl.b d1 + STAT_SZC + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + +ASL0A: lsl.b AReg ;ASL Acc + STAT_SZC + subq.w #1,PCount + addq.l #2,Cycles + DOCYCLE + +ASL06: MEM_ZP ;ASL $20 + move.b (Mem_Ptr,d0.l),d1 + lsl.b d1 + STAT_SZC ;preserve addr in d0 + move.b d1,(Mem_Ptr,d0.l) + addq.l #5,Cycles + DOCYCLE + +ASL16: MEM_ZPIndxX ;ASL $06,X + move.b (Mem_Ptr,d0.l),d1 + lsl.b d1 + STAT_SZC ;preserve addr in d0 + move.b d1,(Mem_Ptr,d0.l) + addq.l #6,Cycles + DOCYCLE +*---------------------------- BIT ---------- (Stat Dependant) -------------------* +BIT2C: MEM_Abs ;BIT $1234 + addq.l #4,Cycles + GETBYTE ;(Doesnt Change Acc, just Status) + move.b AReg,d1 + and.b d0,d1 + + STAT_SZ ;get Z from result of "and" + lsr.b #6,d0 [04] ;copy this bit into V flag + bfins d0,StatusCV{31-V_BIT:1} [10] + lsr.b d0 [04] ;and S flag + bfins d0,StatusSZ{31-S_BIT:1} [10] + DOCYCLE + +BIT24: MEM_ZP ;BIT $06 + addq.l #3,Cycles + move.b (Mem_Ptr,d0.l),d0 ;(Doesnt Change Acc, just Status) + move.b AReg,d1 + and.b d0,d1 + + STAT_SZ ;get Z from result of "and" + lsr.b #6,d0 [04] ;copy this bit into V flag + bfins d0,StatusCV{31-V_BIT:1} [10] + lsr.b d0 [04] ;and S flag + bfins d0,StatusSZ{31-S_BIT:1} [10] + DOCYCLE + +*----------------------- BRANCHING! --------------------------------* + +BPL10Reg: + move.l d1,a6 + REGULATE + move.l a6,d1 + +BPL10: btst.l #S_BIT,StatusSZ ;BPL +-disp branch if plus (s=0) + bne.b .NoJmp + ext.w d1 + add.w d1,PCount + addq.l #3,Cycles + DOCYCLE +.NoJmp addq.l #2,Cycles + DOCYCLE + +BMI30Reg: + move.l d1,a6 + REGULATE + move.l a6,d1 + +BMI30: btst.l #S_BIT,StatusSZ ;BMI (+-Disp) branch if minus (s=1) + beq.b .NoJmp + ext.w d1 + add.w d1,PCount + addq.l #3,Cycles + DOCYCLE +.NoJmp addq.l #2,Cycles + DOCYCLE + +BCC90: btst.l #C_BIT,StatusCV ;BCC +- Disp Branch if Carry Clear (C=0) + bne.b .NoJmp + ext.w d1 + add.w d1,PCount + addq.l #3,Cycles + DOCYCLE +.NoJmp addq.l #2,Cycles + DOCYCLE + +BCSB0: btst.l #C_BIT,StatusCV ;BCS +-Disp Branch Carry Set (C=1) + beq.b .NoJmp + ext.w d1 + add.w d1,PCount + addq.l #3,Cycles + DOCYCLE +.NoJmp addq.l #2,Cycles + DOCYCLE + +BVC50: btst.l #V_BIT,StatusCV ;BVC +-Disp Branch if Overflow clear (V=0) + bne.b .NoJmp + ext.w d1 + add.w d1,PCount + addq.l #3,Cycles + DOCYCLE +.NoJmp addq.l #2,Cycles + DOCYCLE + +BVS70: btst.l #V_BIT,StatusCV ;BVS +-Disp branch if overflow (V=1) set + beq.b .NoJmp + ext.w d1 + add.w d1,PCount + addq.l #3,Cycles + DOCYCLE +.NoJmp addq.l #2,Cycles + DOCYCLE + + +BNED0Reg: + move.l d1,a6 + REGULATE + move.l a6,d1 + +BNED0: btst.l #Z_BIT,StatusSZ [05] ;BNE +-Disp Branch if not Equal (z=0) + bne.b .NoJmp [05] ;not taken + ext.w d1 [03] + add.w d1,PCount [03] + addq.l #3,Cycles [03] + DOCYCLE [25]=44 +.NoJmp addq.l #2,Cycles + DOCYCLE + +BEQF0Reg: + move.l d1,a6 + REGULATE + move.l a6,d1 + +BEQF0: btst.l #Z_BIT,StatusSZ ;beq +-Disp Branch if Equal (z=1) + beq.b .NoJmp + ext.w d1 + add.w d1,PCount + addq.l #3,Cycles + DOCYCLE +.NoJmp addq.l #2,Cycles + DOCYCLE + + +*----------------------- CLEAR STATUS BITS -------------------------* +CLC18: bclr.l #C_BIT,StatusCV ;CLC - Clear Carry (C=0) + subq.w #1,PCount + addq.l #2,Cycles + DOCYCLE + +CLVB8: bclr.l #V_BIT,StatusCV ;CLV - Clear Overflow (V=0) + subq.w #1,PCount + addq.l #2,Cycles + DOCYCLE + +CLDD8: bclr.l #D_BIT,StatusSZ ;CLD - Clear Decimal status (D=0) + subq.w #1,PCount + addq.l #2,Cycles + DOCYCLE + +CLI58: bclr.l #I_BIT,StatusSZ ;CLI- Clear Intrpt Mask (enable) (I=0) + subq.w #1,PCount + addq.l #2,Cycles + DOCYCLE +*--------------------------- CMP -----------------------------------* +CMPCD: MEM_Abs ;CMP $1234 + addq.l #4,Cycles + GETBYTE ;read mem, subtract from ACC, set SZC + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +CMPC1: MEM_PreIndx ;CMP ($06,X) + addq.l #6,Cycles + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +CMPD1: MEM_PostIndx ;CMP ($06),Y + addq.l #5,Cycles + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +CMPD9: MEM_AbsIndxY ;CMP $1234,Y + addq.l #4,Cycles + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +CMPDD: MEM_AbsIndxX ;CMP $1234,X + addq.l #4,Cycles + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +CMPC9: ;MEM_Immed - CMP #$06 + cmp.b d1,AReg + STAT_SZiC + addq.l #2,Cycles + DOCYCLE + +CMPD5: MEM_ZPIndxX ;CMP $06,X + addq.l #4,Cycles + cmp.b (Mem_Ptr,d0.l),AReg + STAT_SZiC + DOCYCLE + +CMPC5: MEM_ZP ;CMP $06 + addq.l #3,Cycles + cmp.b (Mem_Ptr,d0.l),AReg + STAT_SZiC + DOCYCLE + +*-------------------------- CPX ------------------------------------* +CPXEC: MEM_Abs ;CPX $1234 + addq.l #4,Cycles + GETBYTE ;read mem, subtract from XReg, set SZC + cmp.b d0,XReg + STAT_SZiC + DOCYCLE + +CPXE4: MEM_ZP ;CPX $06 + cmp.b (Mem_Ptr,d0.l),XReg + STAT_SZiC + addq.l #3,Cycles + DOCYCLE + +CPXE0: cmp.b d1,XReg ;MEM_Immed - CPX #$06 + STAT_SZiC + addq.l #2,Cycles + DOCYCLE +*--------------------------- CPY -----------------------------------* +CPYCC: MEM_Abs ;CPY $1234 + addq.l #4,Cycles + GETBYTE ;read mem, subtract from YReg, set SZC + cmp.b d0,YReg + STAT_SZiC + DOCYCLE + +CPYC4: MEM_ZP ;CPY $06 + cmp.b (Mem_Ptr,d0.l),YReg + STAT_SZiC + addq.l #3,Cycles + DOCYCLE + +CPYC0: ;MEM_Immed - CPY #$06 + cmp.b d1,YReg + STAT_SZiC + addq.l #2,Cycles + DOCYCLE +*--------------------------- DEC -----------------------------------* +DECCE: MEM_Abs ;DEC $1234 + addq.l #6,Cycles + move.b (Mem_Ptr,d0.l),d1 ;fast read now, i/o check at write! (IMPerfect!) + subq.b #1,d1 ;DEC memory by 1, set SZ + STAT_SZ + PUTBYTE ;d0 still there? + DOCYCLE + +DECDE: MEM_AbsIndxX ;DEX $1234,X + addq.l #7,Cycles + move.b (Mem_Ptr,d0.l),d1 + subq.b #1,d1 + STAT_SZ + PUTBYTE + DOCYCLE + +DECD6: MEM_ZPIndxX ;DEC $06,X + addq.l #6,Cycles + subq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +DECC6: MEM_ZP ;DEC $06 + addq.l #5,Cycles + subq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +*------------------------ DEX/DEY ----------------------------------* + CNOP 0,4 +DEXCA: subq.b #1,XReg [03] ;DEX - Decrement XReg by 1 + STAT_SZ [04] ? + subq.w #1,PCount [03] + addq.l #2,Cycles [03] + DOCYCLE [25]=38 + + CNOP 0,4 +DEY88: subq.b #1,YReg ;DEY - Decrement YReg by 1 + STAT_SZ + subq.w #1,PCount + addq.l #2,Cycles + DOCYCLE +*-------------------------- EOR ------------------------------------* +EOR4D: MEM_Abs ;EOR $1234 + addq.l #4,Cycles + GETBYTE + eor.b d0,AReg + STAT_SZ + DOCYCLE + +EOR51: MEM_PostIndx ;EOR ($06),Y + addq.l #5,Cycles + GETBYTE + eor.b d0,AReg + STAT_SZ + DOCYCLE + +EOR59: MEM_AbsIndxY ;EOR $1234,Y + addq.l #4,Cycles + GETBYTE + eor.b d0,AReg + STAT_SZ + DOCYCLE + +EOR5D: MEM_AbsIndxX ;EOR $1234,X + addq.l #4,Cycles + GETBYTE + eor.b d0,AReg + STAT_SZ + DOCYCLE + +EOR41: MEM_PreIndx ;EOR ($06,X) + addq.l #6,Cycles + GETBYTE + eor.b d0,AReg + STAT_SZ + DOCYCLE + +EOR49: ;MEM_Immed - EOR #$06 + addq.l #2,Cycles + eor.b d1,AReg + STAT_SZ + DOCYCLE + +EOR45: MEM_ZP ;EOR $06 + addq.l #3,Cycles + move.b (Mem_Ptr,d0.l),d0 + eor.b d0,AReg + STAT_SZ + DOCYCLE + +EOR55: MEM_ZPIndxX ;EOR $06,X + addq.l #4,Cycles + move.b (Mem_Ptr,d0.l),d0 + eor.b d0,AReg + STAT_SZ + DOCYCLE +*-------------------------- INC ------------------------------------* +INCEE: MEM_Abs ;INC $1234 + addq.l #6,Cycles + move.b (Mem_Ptr,d0.l),d1 ;INC memory by 1, set SZ + addq.b #1,d1 + STAT_SZ + PUTBYTE ;d0 still there? + DOCYCLE + +INCFE: MEM_AbsIndxX ;INC $1234,X + addq.l #7,Cycles + move.b (Mem_Ptr,d0.l),d1 + addq.b #1,d1 + STAT_SZ + PUTBYTE ;d0 still there? + DOCYCLE + +INCE6: MEM_ZP ;INC $06 + addq.l #5,Cycles + addq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +INCF6: MEM_ZPIndxX ;INC $06,X + addq.l #6,Cycles + addq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE +*----------------------- INX / INY ---------------------------------* +INXE8: subq.w #1,PCount + addq.b #1,XReg ;INX - Increment XReg by 1 + STAT_SZ + addq.l #2,Cycles + DOCYCLE + + +INYC8: subq.w #1,PCount + addq.b #1,YReg ;INY - Increment YReg by 1 + STAT_SZ + addq.l #2,Cycles + DOCYCLE +*------------------------ JSR / JMP --------------------------------* +JMP4CReg: + move.l d1,a6 + REGULATE + move.l a6,d1 +JMP4C: ;JMP $xxxx ;MEM_Abs -> PCount (clean!) + MEM_Abs + lea (Mem_Ptr,d0.l),PCount + addq.l #3,Cycles + DOCYCLE + +JSR20: move.l PCount,d0 ;JSR $1234 (only type) + sub.l Mem_Ptr,d0 + PUSH16 + + move.w -1(PCount),d0 ; FGETWORD1PC -> d0 + ror.w #8,d0 ; "" + lea (Mem_Ptr,d0.l),PCount + addq.l #6,Cycles + DOCYCLE + +JMP6C: ;JMP($xxxx) +; FGETWORD1PC ; Mem_Indirect ($xxxx) for JMP only + + move.w -1(PCount),d0 ;FGETWORD1PC -> D0 + ror.w #8,d0 + + move.w (Mem_Ptr,d0.l),d0 ;FGETWORDd0 -> PCount + ror.w #8,d0 + lea (Mem_Ptr,d0.l),PCount + addq.l #5,Cycles + DOCYCLE + +*--------------------------- LDA -----------------------------------* +LDAAD: MEM_Abs ;LDA $1234 + addq.l #4,Cycles + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +LDAA1: MEM_PreIndx ;LDA ($06,X) + addq.l #6,Cycles + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +LDAB1: MEM_PostIndx ;LDA ($06),Y + addq.l #5,Cycles + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +LDAB9: MEM_AbsIndxY ;LDA $1234,Y + addq.l #4,Cycles + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +LDABD: MEM_AbsIndxX ;LDA $1234,X + addq.l #4,Cycles + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +LDAA9: ;MEM_Immed - LDA #$06 + addq.l #2,Cycles + move.b d1,AReg + STAT_SZ + DOCYCLE + +LDAB5: MEM_ZPIndxX ;LDA $06,X + addq.l #4,Cycles + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +LDAA5: MEM_ZP ;LDA $06 + addq.l #3,Cycles + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE +*-------------------------- LDX ------------------------------------* +LDXAE: MEM_Abs ;LDX $1234 + addq.l #4,Cycles + GETBYTE ;read mem into XReg + move.b d0,XReg + STAT_SZ + DOCYCLE + +LDXBE: MEM_AbsIndxY ;LDX $1234,Y + addq.l #4,Cycles + GETBYTE + move.b d0,XReg + STAT_SZ + DOCYCLE + +LDXA2: ;MEM_Immed - LDX #$06 + addq.l #2,Cycles + move.b d1,XReg + STAT_SZ + DOCYCLE + +LDXA6: MEM_ZP ;LDX $06 + addq.l #3,Cycles + move.b (Mem_Ptr,d0.l),XReg + STAT_SZ + DOCYCLE + +LDXB6: MEM_ZPIndxY ;LDX $06,Y + addq.l #4,Cycles + move.b (Mem_Ptr,d0.l),XReg + STAT_SZ + DOCYCLE +*------------------------- LDY -------------------------------------* +LDYAC: MEM_Abs ;LDY $1234 + addq.l #4,Cycles + GETBYTE ;read mem into YReg.. + move.b d0,YReg + STAT_SZ + DOCYCLE + +LDYBC: MEM_AbsIndxX ;LDY $1234,X + addq.l #4,Cycles + GETBYTE + move.b d0,YReg + STAT_SZ + DOCYCLE + +LDYA0: ;MEM_Immed - LDY #$06 + addq.l #2,Cycles + move.b d1,YReg + STAT_SZ + DOCYCLE + +LDYA4: MEM_ZP ;LDY $06 + addq.l #3,Cycles + move.b (Mem_Ptr,d0.l),YReg + STAT_SZ + DOCYCLE + +LDYB4: MEM_ZPIndxX ;LDY $06,X + addq.l #4,Cycles + move.b (Mem_Ptr,d0.l),YReg + STAT_SZ + DOCYCLE +*------------------------- LSR -------------------------------------* +LSR4E: MEM_Abs ;LSR $1234 + addq.l #6,Cycles + move.w d0,-(sp) + GETBYTE ;must do long read in case of PDL, DISK, etc... + move.b d0,d1 + lsr.b #1,d1 + STAT_SZC + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + +LSR5E: MEM_AbsIndxX ;LSR $1234,X + addq.l #7,Cycles + move.w d0,-(sp) + GETBYTE ;must do long read in case of PDL, DISK, etc... + move.b d0,d1 + lsr.b #1,d1 + STAT_SZC + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + +LSR4A: subq.w #1,PCount + lsr.b #1,AReg ;LSR Acc + STAT_SZC + addq.l #2,Cycles + DOCYCLE + +LSR46: MEM_ZP ;LSR $06 + move.b (Mem_Ptr,d0.l),d1 + lsr.b #1,d1 + STAT_SZC + move.b d1,(Mem_Ptr,d0.l) + addq.l #5,Cycles + DOCYCLE + +LSR56: MEM_ZPIndxX ;LSR $06,X + move.b (Mem_Ptr,d0.l),d1 + lsr.b #1,d1 + STAT_SZC + move.b d1,(Mem_Ptr,d0.l) + addq.l #6,Cycles + DOCYCLE + + dc.b "This program is Copyright 1994 by Kevin Kralian",0 + EVEN +*--------------------------------------------------------------------* +NOPEA: subq.w #1,PCount + addq.l #2,Cycles + DOCYCLE ;NOP - Do nothing! time waster +*-------------------------- ORA -------------------------------------* +ORA0D: MEM_Abs ;ORA $1234 + addq.l #4,Cycles + GETBYTE + or.b d0,AReg + STAT_SZ + DOCYCLE + +ORA01: MEM_PreIndx ;ORA ($20,X) + addq.l #6,Cycles + GETBYTE + or.b d0,AReg + STAT_SZ + DOCYCLE + +ORA19: MEM_AbsIndxY ;ORA $1234,Y + addq.l #4,Cycles + GETBYTE + or.b d0,AReg + STAT_SZ + DOCYCLE + +ORA1D: MEM_AbsIndxX ;ORA $1234,X + addq.l #4,Cycles + GETBYTE + or.b d0,AReg + STAT_SZ + DOCYCLE + +ORA11: MEM_PostIndx ;ORA ($06),Y + addq.l #5,Cycles + GETBYTE + or.b d0,AReg + STAT_SZ + DOCYCLE + +ORA09: ;MEM_Immed - ORA #$20 + addq.l #2,Cycles + or.b d1,AReg + STAT_SZ + DOCYCLE + +ORA05: MEM_ZP ;ORA $20 + addq.l #3,Cycles + or.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +ORA15: MEM_ZPIndxX ;ORA $06,X + addq.l #4,Cycles + or.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE +*-------------------------- PHP ------------------------------------* +PHA48: PUSH AReg ;PHA - Push AReg + subq.w #1,PCount + addq.l #3,Cycles + DOCYCLE + +PHP08: PUSHSTAT ;PHP + subq.w #1,PCount + addq.l #3,Cycles + DOCYCLE +*---------------------- PLA / PLP ----------------------------------* +PLA68: addq.l #4,Cycles + PULL AReg ;PLA - Pull Accum from stack + tst.b AReg + STAT_SZ + subq.w #1,PCount + DOCYCLE + +PLP28: addq.l #4,Cycles + PULLSTAT ;PLP + subq.w #1,PCount + DOCYCLE +*-------------------------- ROL (through Carry)----(Status Dependant)---------------* + +ROL2E: MEM_Abs ;ROL $1234 + addq.l #6,Cycles +.rol move.w d0,-(sp) + GETBYTE + move.b d0,d1 ;needs to be there for PUTBYTE anyways... + + lsl.b d1 [04] ;shift it + lsr.b #C_BIT,StatusCV [04] ;and add in carry bit... + add.b StatusCV,d1 [03] + STAT_SZ [06] ;and get SZ flags... (faster than ROXL) + move.b d0,StatusCV [03] ;get Carry Flag + + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + +ROL3E: MEM_AbsIndxX ;ROL $1234,X + addq.l #7,Cycles +.rol move.w d0,-(sp) + GETBYTE + move.b d0,d1 + + lsl.b d1 + lsr.b #C_BIT,StatusCV + add.b StatusCV,d1 + STAT_SZ + move.b d0,StatusCV + + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + + + +ROL26: MEM_ZP ;ROL $06 + addq.l #5,Cycles +.rol move.b (Mem_Ptr,d0.l),d1 ;FGETBYTE + + lsr.b #C_BIT+1,StatusCV + roxl.b #1,d1 + STAT_SZC + + move.b d1,(Mem_Ptr,d0.l) + DOCYCLE + +ROL36: MEM_ZPIndxX ;ROL $06,X + addq.l #6,Cycles +.rol move.b (Mem_Ptr,d0.l),d1 ;FGETBYTE + lsr.b #C_BIT+1,StatusCV + roxl.b #1,d1 + STAT_SZC + move.b d1,(Mem_Ptr,d0.l) + DOCYCLE + + + CNOP 0,4 +ROL2A: subq.w #1,PCount ;ROL Acc + addq.l #2,Cycles + lsr.b #C_BIT+1,StatusCV [04] + roxl.b #1,AReg [12] + STAT_SZC [10] 26 + DOCYCLE + + +*-------------------------- ROR (through Carry)------------------------* +ROR6E: MEM_Abs ;ROR $2134 + addq.l #6,Cycles +.ror move.w d0,-(sp) + GETBYTE + move.b d0,d1 ;needs to be there for PUTBYTE anyways... + lsr.b #C_BIT+1,StatusCV ;Sets/Clrs Extend (X) flag based on C + roxr.b #1,d1 ;(this always clears V in CCR) + STAT_SZC + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + +ROR66: MEM_ZP ;ROR $06 + addq.l #5,Cycles +.ror move.b (Mem_Ptr,d0.l),d1 + lsr.b #C_BIT+1,StatusCV + roxr.b #1,d1 + STAT_SZC + move.b d1,(Mem_Ptr,d0.l) + DOCYCLE + + +ROR76: MEM_ZPIndxX ;ROR $06,X + addq.l #6,Cycles +.ror move.b (Mem_Ptr,d0.l),d1 + lsr.b #C_BIT+1,StatusCV + roxr.b #1,d1 + STAT_SZC + move.b d1,(Mem_Ptr,d0.l) + DOCYCLE + +ROR7E: MEM_AbsIndxX ;ROR $1234,X + addq.l #7,Cycles +.ror move.w d0,-(sp) + GETBYTE + move.b d0,d1 + lsr.b #C_BIT+1,StatusCV + roxr.b #1,d1 + STAT_SZC + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + + CNOP 0,4 +ROR6A: subq.w #1,PCount ;ROR ACC + lsr.b #C_BIT+1,StatusCV + roxr.b #1,AReg + STAT_SZC + addq.l #2,Cycles + DOCYCLE +*---------------------- RTI / RTS -----------------------------------* +RTI40: addq.l #7,Cycles + PULLSTAT ;RTI - Return From Intrpt + PULL16 + lea (Mem_Ptr,d0.l),PCount + DOCYCLE + +RTS60: PULL16 ;RTS - Return from Subroutine + lea 1(Mem_Ptr,d0.l),PCount + addq.l #6,Cycles + DOCYCLE +*------------------------- SBC -------------------------------------* STATUS DEPENDANT!!! +SBCE5: MEM_ZP ;SBC $06 + addq.l #3,Cycles + GETBYTE + eor.b #C_HEX,StatusCV [06] ;for subtraction, C flag works backwards + btst.l #D_BIT,StatusSZ [05] + bne.b .bcd [05] +.dec lsr.b #8,StatusCV [04] ;Sets/Clrs X flag based on C & Sets Z Flag + subx.b d0,AReg [03] ; SUBX - Z flag only cleared, not set! + STAT_SVZiC + DOCYCLE +.bcd lsr.b #8,StatusCV ;Sets/Clrs X flag based on C & Sets Z Flag + sbcd.b d0,AReg ;SBCD - Z flag only cleared, not set! + STAT_SZiC ;manual says Z not set. Is V??? + DOCYCLE + + +SBCE1: MEM_PreIndx ;SBC ($06,X) + addq.l #6,Cycles + GETBYTE + eor.b #C_HEX,StatusCV + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + subx.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd lsr.b #8,StatusCV + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +SBCED: MEM_Abs ;SBC $1234 + addq.l #4,Cycles + GETBYTE + eor.b #C_HEX,StatusCV + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + subx.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd lsr.b #8,StatusCV + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +SBCF1: MEM_PostIndx ;SBC ($06),Y + addq.l #5,Cycles + GETBYTE + eor.b #C_HEX,StatusCV + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + subx.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd lsr.b #8,StatusCV + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +SBCF9: MEM_AbsIndxY ;SBC $1234,Y + addq.l #4,Cycles + GETBYTE + eor.b #C_HEX,StatusCV + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + subx.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd lsr.b #8,StatusCV + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +SBCFD: MEM_AbsIndxX ;SBC $1234,X + addq.l #4,Cycles + GETBYTE + eor.b #C_HEX,StatusCV + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + subx.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd lsr.b #8,StatusCV + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +SBCE9: ;MEM_Immed - SBC #$06 + addq.l #2,Cycles + move.b d1,d0 + eor.b #C_HEX,StatusCV + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + subx.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd lsr.b #8,StatusCV + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + + +SBCF5: MEM_ZPIndxX ;SBC $06,X + addq.l #4,Cycles + move.b (Mem_Ptr,d0.l),d0 + eor.b #C_HEX,StatusCV + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + subx.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd lsr.b #8,StatusCV + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +*-------------------- SET STATUS BITS ------------------------------* +SEI78: subq.w #1,PCount + bset.l #I_BIT,StatusSZ ;SEI - Set Interrupt Mask (disable intrps) + addq.l #2,Cycles + DOCYCLE + +SEDF8: subq.w #1,PCount + bset.l #D_BIT,StatusSZ ;SED - Set Decimal mode (D=1) + addq.l #2,Cycles + DOCYCLE + +SEC38: subq.w #1,PCount + bset.l #C_BIT,StatusCV ;SEC - Set Carry (C=1) + addq.l #2,Cycles + DOCYCLE +*-------------------------- STA ------------------------------------* +STA81: MEM_PreIndx ;STA ($06,X) + addq.l #6,Cycles + move.b AReg,d1 + PUTBYTE_DOCYCLE + +STA8D: MEM_Abs ;STA $1234 + addq.l #4,Cycles + move.b AReg,d1 + PUTBYTE_DOCYCLE + +STA91: MEM_PostIndx ;STA ($06),Y + addq.l #6,Cycles + move.b AReg,d1 + PUTBYTE_DOCYCLE + +STA99: MEM_AbsIndxY ;STA $1234,Y + addq.l #5,Cycles + move.b AReg,d1 + PUTBYTE_DOCYCLE + +STA9D: MEM_AbsIndxX ;STA $1234,X + addq.l #5,Cycles + move.b AReg,d1 + PUTBYTE_DOCYCLE + +STA85: MEM_ZP ;STA $06 + move.b AReg,(Mem_Ptr,d0.l) + addq.l #3,Cycles + DOCYCLE + +STA95: MEM_ZPIndxX ;STA $06,X + move.b AReg,(Mem_Ptr,d0.l) + addq.l #4,Cycles + DOCYCLE +*-------------------------- STX ------------------------------------* +STX8E: MEM_Abs ;STX $1234 + addq.l #4,Cycles + move.b XReg,d1 + PUTBYTE_DOCYCLE + +STX96: MEM_ZPIndxY ;STX $06,Y + move.b XReg,(Mem_Ptr,d0.l) + addq.l #4,Cycles + DOCYCLE + +STX86: MEM_ZP ;STX $06 + move.b XReg,(Mem_Ptr,d0.l) + addq.l #3,Cycles + DOCYCLE +*-------------------------- STY ------------------------------------* +STY8C: MEM_Abs ;STY $1234 + addq.l #4,Cycles + move.b YReg,d1 + PUTBYTE_DOCYCLE + +STY94: MEM_ZPIndxX ;STY $06,X + move.b YReg,(Mem_Ptr,d0.l) + addq.l #4,Cycles + DOCYCLE + +STY84: MEM_ZP ;STY $06 + move.b YReg,(Mem_Ptr,d0.l) + addq.l #3,Cycles + DOCYCLE +*------------------------ TRANSFER REGS ----------------------------* +TXA8A: subq.w #1,PCount + move.b XReg,AReg ;TXA - Transfer XReg to AReg + STAT_SZ + addq.l #2,Cycles + DOCYCLE + +TYA98: subq.w #1,PCount + move.b YReg,AReg ;TYA - Transfer Yreg to AReg + STAT_SZ + addq.l #2,Cycles + DOCYCLE + +TXS9A: subq.w #1,PCount + swap Stack + move.b XReg,Stack ;TXS - Transfer XREG to StackPtr + swap Stack + addq.l #2,Cycles + DOCYCLE + +TAYA8: subq.w #1,PCount + move.b AReg,YReg ;TAY - Transfer Acc to YReg + STAT_SZ + addq.l #2,Cycles + DOCYCLE + +TAXAA: subq.w #1,PCount + move.b AReg,XReg ;TAX - Transfer Acc to XReg + STAT_SZ + addq.l #2,Cycles + DOCYCLE + +TSXBA: subq.w #1,PCount + swap Stack + move.b Stack,XReg ;TSX - move StackPtr to XReg + STAT_SZ + swap Stack + addq.l #2,Cycles + DOCYCLE + + +;************************** + CNOP 0,4 + +*----------------------------- Inst Pairs !!!------------------------------------* +********************************************************************* +* DEX/INX/DEY/INY + BPL/BMI/BNE/BEQ Pairs... +********************************************************************* + +***************** DEX + Bxx *************************** + +DEXCA_BNED0: + cmp.b #$fd,(PCount) ;is the BNE at {-3} ? + beq.b .GotBNE +.dex subq.b #1,XReg [03] + beq.b .NoJmp [05] +.bne STAT_SZ [12] ? + addq.l #5,Cycles [03] + move.b (PCount)+,d1 [07] + ext.w d1 [03] + add.w d1,PCount [03] + DOCYCLE [25] = 64 cycles (branch taken) (vs 93 for seperate insts) +.NoJmp STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +.GotBNE ; INY + BNE {-3} (delay Lp!) + ; [02] + [03] = 5 each + addq.l #1,PCount + addq.l #4,Cycles + + subq.b #1,XReg ;add AReg*5 to cycles + add.l XReg,Cycles + lsl.l #2,XReg + add.l XReg,Cycles + + REGULATE + + moveq.l #0,XReg + STAT_SZ + DOCYCLE + +DEXCA_BEQF0: +.dex subq.b #1,XReg + bne.b .NoJmp ;decision... +.beq + STAT_SZ + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +DEXCA_BPL10: +.dex subq.b #1,XReg + bmi.b .NoJmp ;decision... +.bpl + STAT_SZ + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +DEXCA_BMI30: +.dex subq.b #1,XReg + bpl.b .NoJmp ;decision... +.bmi + STAT_SZ + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + + ************ DEY + Bcc *********** +DEY88_BNED0: + cmp.b #$fd,(PCount) ;is the BNE at {-3} ? + beq.b .GotBNE + +.dey subq.b #1,YReg [03] + beq.b .NoJmp [05] +.bne + STAT_SZ [12] ? + addq.l #5,Cycles [03] + move.b (PCount)+,d1 [07] + ext.w d1 [03] + add.w d1,PCount [03] + DOCYCLE [25] = 64 cycles (branch taken) (vs 93 for seperate insts) +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +.GotBNE ; INY + BNE {-3} (delay Lp!) + ; [02] + [03] = 5 each + + addq.l #1,PCount + addq.l #4,Cycles + + subq.b #1,YReg ;add AReg*5 to cycles + add.l YReg,Cycles + lsl.l #2,YReg + add.l YReg,Cycles + + REGULATE + + moveq.l #0,YReg + STAT_SZ + DOCYCLE + +DEY88_BEQF0: +.dey subq.b #1,YReg + bne.b .NoJmp ;decision... +.beq + STAT_SZ + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +DEY88_BPL10: +.dey subq.b #1,YReg + bmi.b .NoJmp ;decision... +.bpl + STAT_SZ + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +DEY88_BMI30: +.dey subq.b #1,YReg + bpl.b .NoJmp ;decision... +.bmi + STAT_SZ + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + + ******** INX + Bcc *********** +INXE8_BNED0: + cmp.b #$fd,(PCount) ;is the BNE at {-3} ? + beq.b .GotBNE + +.inx addq.b #1,XReg [03] + beq.b .NoJmp [05] +.bne + STAT_SZ [12] ? + addq.l #5,Cycles [03] + move.b (PCount)+,d1 [07] + ext.w d1 [03] + add.w d1,PCount [03] + DOCYCLE [25] = 64 cycles (branch taken) (vs 93 for seperate insts) +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +.GotBNE ; INY + BNE {-3} (delay Lp!) + ; [02] + [03] = 5 each + + addq.l #1,PCount + addq.l #4,Cycles + + addq.b #1,XReg ;add AReg*5 to cycles + neg.b XReg + add.l XReg,Cycles + lsl.l #2,XReg + add.l XReg,Cycles + + REGULATE + + moveq.l #0,XReg + STAT_SZ + DOCYCLE + +INXE8_BEQF0: +.inx addq.b #1,XReg + bne.b .NoJmp ;decision... +.beq + STAT_SZ + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +INXE8_BPL10: +.inx addq.b #1,XReg + bmi.b .NoJmp ;decision... +.bpl + STAT_SZ + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +INXE8_BMI30: +.inx addq.b #1,XReg + bpl.b .NoJmp ;decision... +.bmi + STAT_SZ + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + + ******** INY + Bcc *********** + +INYC8_BNED0: + cmp.b #$fd,(PCount) ;is the BNE at {-3} ? + beq.b .GotBNE +.iny addq.b #1,YReg [03] + beq.b .NoJmp [05] +.bne + STAT_SZ [12] ? + addq.l #5,Cycles [03] + move.b (PCount)+,d1 [07] + ext.w d1 [03] + add.w d1,PCount [03] + DOCYCLE [25] = 64 cycles (branch taken) (vs 93 for seperate insts) +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +.GotBNE ; INY + BNE {-3} (delay Lp!) + ; [02] + [03] = 5 each + addq.l #1,PCount + addq.l #4,Cycles + + addq.b #1,YReg ;add AReg*5 to cycles + neg.b YReg + add.l YReg,Cycles + lsl.l #2,YReg + add.l YReg,Cycles + + REGULATE + + moveq.l #0,YReg + STAT_SZ + DOCYCLE + + + + + +INYC8_BEQF0: +.iny addq.b #1,YReg + bne.b .NoJmp ;decision... +.beq + STAT_SZ + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +INYC8_BPL10: +.iny addq.b #1,YReg + bmi.b .NoJmp ;decision... +.bpl + STAT_SZ + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +INYC8_BMI30: +.iny addq.b #1,YReg + bpl.b .NoJmp ;decision... +.bmi + STAT_SZ + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZ + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +************************************************************************** + + +SBCE9_01: ;MEM_Immed - SBC #$01 + cmp.w #$d0fc,(PCount) ;is next inst BNE {-4} ? + beq.b .GotBNE + addq.l #2,Cycles + move.b d1,d0 + eor.b #C_HEX,StatusCV + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec lsr.b #8,StatusCV + subx.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd lsr.b #8,StatusCV + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +.GotBNE ;SBC #$01 + BNE {-4} (delay Lp!) + ; [02] + [03] = 5 each + addq.l #2,PCount + addq.l #4,Cycles + + subq.b #1,AReg ;add AReg*5 to cycles + add.l AReg,Cycles + lsl.l #2,AReg + add.l AReg,Cycles + + REGULATE + + moveq.l #0,AReg + STAT_SVZiC + DOCYCLE + + +********************************************************** +**** Common Simple Pairs..... +********************************************************** + +INXE8_INXE8: +.inx addq.b #2,XReg ;INX twice! + STAT_SZ + addq.l #4,Cycles + DOCYCLE + + +INYC8_INYC8: +.iny addq.b #2,YReg + STAT_SZ + addq.l #4,Cycles + DOCYCLE + +DEXCA_DEXCA: +.dex subq.b #2,XReg + STAT_SZ + addq.l #4,Cycles + DOCYCLE + +DEY88_DEY88: +.dey subq.b #2,YReg + STAT_SZ + addq.l #4,Cycles + DOCYCLE + + +ASL0A_ASL0A: +.asl lsl.b #2,AReg + STAT_SZC + addq.l #4,Cycles + DOCYCLE + +LSR4A_LSR4A: +.lsr_x2 lsr.b #2,AReg ;LSR Acc + STAT_SZC + addq.l #4,Cycles + DOCYCLE + +PLA68_PLA68: +.pla swap Stack + addq.b #2,Stack + move.b (Mem_Ptr,Stack.w),AReg + STAT_SZ + swap Stack + addq.l #8,Cycles + DOCYCLE + +JMP6C_BUGFF: ;JMP($xxxx) w/ end-of page wrap-around bug! +; FGETWORD1PC ; Mem_Indirect ($xxxx) for JMP only + + move.w -1(PCount),d0 + ror.w #8,d0 ;D0 = Pre-indirect address + + moveq.l #0,d1 + move.b (Mem_Ptr,d0.l),d1 ;get low byte of final addr... + move.b #0,d0 + lsl.w #8,d1 + move.b (Mem_Ptr,d0.l),d1 ;and get hi byte of dest in lo byte! + ror.w #8,d1 ;and rotate into position... + + lea (Mem_Ptr,d1.l),PCount + addq.l #5,Cycles + DOCYCLE + + + +;**************************************************** +; New opts as of 05/01/94 follow... + +TXA8A_PHA48: +.txa move.b XReg,AReg ;TXA - Transfer XReg to AReg + STAT_SZ +.pha PUSH AReg ;PHA - Push AReg + addq.l #5,Cycles + DOCYCLE + +TYA98_PHA48: +.tya move.b YReg,AReg + STAT_SZ +.pha PUSH AReg + addq.l #5,Cycles + DOCYCLE + +PLA68_PHA48: +.PlaPha swap Stack + move.b 1(Mem_Ptr,Stack.w),AReg ; [08] + STAT_SZ + swap Stack + addq.l #7,Cycles + DOCYCLE + +PLA68_TAYA8: +.pla PULL AReg +.tay move.b AReg,YReg + STAT_SZ + addq.l #6,Cycles + DOCYCLE + +PLA68_TAXAA: +.pla PULL AReg +.tax move.b AReg,XReg + STAT_SZ + addq.l #6,Cycles + DOCYCLE + +************************************************************* +** CLC + ADC pairs - No need to do BCLR #C_BIT since is reset by Stat after ADD +** No need to check C, always clear for Add! No need for ADDX! C Always clear! +************************************************************* +CLC18_ADC6D: ;(no need to CLC, gets reset by ADC) + OLDMEM_Abs ;ADC $1234 + addq.l #6,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ [05] + bne.b .bcd [05] +.dec add.b d0,AReg [03] ;ADDX - Z flag only cleared, not set! = [17] + STAT_SVZC + DOCYCLE +.bcd moveq.b #0,d1 ;Clrs X flag & Sets Z Flag + abcd.b d0,AReg ;ABCD - Z flag only cleared, not set! + STAT_SZC ;manual says Z not set. Is V??? + DOCYCLE + +CLC18_ADC61: + OLDMEM_PreIndx ;ADC ($06,X) + addq.l #8,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec add.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd moveq.b #0,d1 + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +CLC18_ADC71: + OLDMEM_PostIndx ;ADC ($06),Y + addq.l #7,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec add.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd moveq.b #0,d1 + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +CLC18_ADC79: + OLDMEM_AbsIndxY ;ADC $1234,Y + addq.l #6,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec add.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd moveq.b #0,d1 + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +CLC18_ADC7D: + OLDMEM_AbsIndxX ;ADC $1234,X + addq.l #6,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec add.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd moveq.b #0,d1 + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +CLC18_ADC65: + OLDMEM_ZP ;ADC $06 + addq.l #5,Cycles + move.b (Mem_Ptr,d0.l),d0 + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec add.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd moveq.b #0,d1 + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +CLC18_ADC75: + OLDMEM_ZPIndxX ;ADC $06,X + addq.l #6,Cycles + move.b (Mem_Ptr,d0.l),d0 + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec add.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd moveq.b #0,d1 + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +CLC18_ADC69: + OLDMEM_ImmedD0 ;Mem_Immed - ADC #$06 + addq.l #4,Cycles + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec add.b d0,AReg + STAT_SVZC + DOCYCLE +.bcd moveq.b #0,d1 + abcd.b d0,AReg + STAT_SZC + DOCYCLE + +************************************************************* +** SEC + SBC pairs - No need to do BSET #C_BIT since is reset by Stat after SUB +** No need to check C, always set for this sub! No need for SUBX! C Always clear! +************************************************************* + +SEC38_SBCED: ;(no need to SEC, gets reset by SBC) + OLDMEM_Abs ;SBC $1234 + addq.l #6,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ [05] + bne.b .bcd [05] +.dec sub.b d0,AReg [03] ;ADDX - Z flag only cleared, not set! = [17] + STAT_SVZiC + DOCYCLE +.bcd moveq.b #0,d1 ;Clrs X flag & Sets Z Flag + sbcd.b d0,AReg ;ABCD - Z flag only cleared, not set! + STAT_SZiC ;manual says Z not set. Is V??? + DOCYCLE + +SEC38_SBCE1: + OLDMEM_PreIndx ;SBC ($06,X) + addq.l #8,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec sub.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd moveq.b #0,d1 + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +SEC38_SBCF1: + OLDMEM_PostIndx ;SBC ($06),Y + addq.l #7,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec sub.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd moveq.b #0,d1 + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +SEC38_SBCF9: + OLDMEM_AbsIndxY ;SBC $1234,Y + addq.l #6,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec sub.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd moveq.b #0,d1 + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +SEC38_SBCFD: + OLDMEM_AbsIndxX ;SBC $1234,X + addq.l #6,Cycles + GETBYTE + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec sub.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd moveq.b #0,d1 + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +SEC38_SBCE5: + OLDMEM_ZP ;SBC $06 + addq.l #5,Cycles + move.b (Mem_Ptr,d0.l),d0 + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec sub.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd moveq.b #0,d1 + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +SEC38_SBCF5: + OLDMEM_ZPIndxX ;SBC $06,X + addq.l #6,Cycles + move.b (Mem_Ptr,d0.l),d0 + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec sub.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd moveq.b #0,d1 + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +SEC38_SBCE9: + OLDMEM_ImmedD0 ;Mem_Immed - SBC #$06 + addq.l #4,Cycles + btst.l #D_BIT,StatusSZ + bne.b .bcd +.dec sub.b d0,AReg + STAT_SVZiC + DOCYCLE +.bcd moveq.b #0,d1 + sbcd.b d0,AReg + STAT_SZiC + DOCYCLE + +; New opts as of 05/08/94 follow... +************************************************************* +** AnythingX + CPX... Anything that affects X reg then Compares it... +************************************************************* + +DEXCA_CPXEC: + subq.b #1,XReg ;INX - Increment XReg by 1 + addq.l #6,Cycles +.cpx OLDMEM_Abs ;CPX $1234 + GETBYTE + cmp.b d0,XReg + STAT_SZiC + DOCYCLE + +DEXCA_CPXE4: + subq.b #1,XReg ;INX - Increment XReg by 1 + addq.l #5,Cycles +.cpx OLDMEM_ZP ;CPX $06 + cmp.b (Mem_Ptr,d0.l),XReg + STAT_SZiC + DOCYCLE + +DEXCA_CPXE0: + subq.b #1,XReg ;INX - Increment XReg by 1 + addq.l #4,Cycles +.cpx OLDMEM_ImmedD0 + cmp.b d0,XReg ;MEM_Immed - CPX #$06 + STAT_SZiC + DOCYCLE + +*----------* + +INXE8_CPXEC: + addq.b #1,XReg ;INX - Increment XReg by 1 + addq.l #6,Cycles +.cpx OLDMEM_Abs ;CPX $1234 + GETBYTE + cmp.b d0,XReg + STAT_SZiC + DOCYCLE + +INXE8_CPXE4: + addq.b #1,XReg ;INX - Increment XReg by 1 + addq.l #5,Cycles +.cpx OLDMEM_ZP ;CPX $06 + cmp.b (Mem_Ptr,d0.l),XReg + STAT_SZiC + DOCYCLE + +INXE8_CPXE0: + addq.b #1,XReg ;INX - Increment XReg by 1 + addq.l #4,Cycles +.cpx OLDMEM_ImmedD0 + cmp.b d0,XReg ;MEM_Immed - CPX #$06 + STAT_SZiC + DOCYCLE + +************************************************************* +** AnythingX + CPX... Anything that affects X reg then Compares it... +************************************************************* +DEY88_CPYCC: + subq.b #1,YReg ;INY - Increment YReg by 1 + addq.l #6,Cycles +.cpy OLDMEM_Abs ;CPY $1234 + GETBYTE ;read mem, subtract from YReg, set SZC + cmp.b d0,YReg + STAT_SZiC + DOCYCLE + +DEY88_CPYC4: + subq.b #1,YReg ;INY - Increment YReg by 1 + addq.l #5,Cycles +.cpy OLDMEM_ZP ;CPY $06 + cmp.b (Mem_Ptr,d0.l),YReg + STAT_SZiC + DOCYCLE + +DEY88_CPYC0: + subq.b #1,YReg ;INY - Increment YReg by 1 + addq.l #4,Cycles +.cpy OLDMEM_ImmedD0 ;MEM_Immed - CPY #$06 + cmp.b d0,YReg + STAT_SZiC + DOCYCLE + +*----------* + +INYC8_CPYCC: + addq.b #1,YReg ;INY - Increment YReg by 1 + addq.l #6,Cycles +.cpy OLDMEM_Abs ;CPY $1234 + GETBYTE ;read mem, subtract from YReg, set SZC + cmp.b d0,YReg + STAT_SZiC + DOCYCLE + +INYC8_CPYC4: + addq.b #1,YReg ;INY - Increment YReg by 1 + addq.l #5,Cycles +.cpy OLDMEM_ZP ;CPY $06 + cmp.b (Mem_Ptr,d0.l),YReg + STAT_SZiC + DOCYCLE + +INYC8_CPYC0: + addq.b #1,YReg ;INY - Increment YReg by 1 + addq.l #4,Cycles +.cpy OLDMEM_ImmedD0 ;MEM_Immed - CPY #$06 + cmp.b d0,YReg + STAT_SZiC + DOCYCLE + +; New opts as of 05/08/94 follow... +************************************************************* +** ANYInst + LDA pairs... No need to do STAT_SZ, reset by LDA! +************************************************************* + +INXE8_LDAA1: +.inx addq.b #1,XReg ;INX + addq.l #8,Cycles +.lda OLDMEM_PreIndx ;LDA ($06,X) + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +INXE8_LDAA5: +.inx addq.b #1,XReg ;INX + addq.l #5,Cycles +.lda OLDMEM_ZP ;LDA $06 + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +INXE8_LDAA9: +.inx addq.b #1,XReg ;INX + addq.l #2,Cycles +.lda OLDMEM_ImmedD0 ;LDA #$06 + move.b d0,AReg + STAT_SZ + DOCYCLE + +INXE8_LDAAD: +.inx addq.b #1,XReg ;INX + addq.l #6,Cycles +.lda OLDMEM_Abs ;LDA $1234 + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +INXE8_LDAB1: +.inx addq.b #1,XReg ;INX + addq.l #7,Cycles +.lda OLDMEM_PostIndx ;LDA ($06),Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +INXE8_LDAB5: +.inx addq.b #1,XReg ;INX + addq.l #6,Cycles +.lda OLDMEM_ZPIndxX ;LDA $06,X + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +INXE8_LDAB9: +.inx addq.b #1,XReg ;INX + addq.l #6,Cycles +.lda OLDMEM_AbsIndxY ;LDA $1234,Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +INXE8_LDABD: +.inx addq.b #1,XReg ;INX + addq.l #6,Cycles +.lda OLDMEM_AbsIndxX ;LDA $1234,X + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +*---------* + +DEXCA_LDAA1: +.dex subq.b #1,XReg ;DEX + addq.l #8,Cycles +.lda OLDMEM_PreIndx ;LDA ($06,X) + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +DEXCA_LDAA5: +.dex subq.b #1,XReg ;DEX + addq.l #5,Cycles +.lda OLDMEM_ZP ;LDA $06 + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +DEXCA_LDAA9: +.dex subq.b #1,XReg ;DEX + addq.l #4,Cycles +.lda OLDMEM_ImmedD0 ;LDA #$06 + move.b d0,AReg + STAT_SZ + DOCYCLE + +DEXCA_LDAAD: +.dex subq.b #1,XReg ;DEX + addq.l #6,Cycles +.lda OLDMEM_Abs ;LDA $1234 + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +DEXCA_LDAB1: +.dex subq.b #1,XReg ;DEX + addq.l #7,Cycles +.lda OLDMEM_PostIndx ;LDA ($06),Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +DEXCA_LDAB5: +.dex subq.b #1,XReg ;DEX + addq.l #6,Cycles +.lda OLDMEM_ZPIndxX ;LDA $06,X + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +DEXCA_LDAB9: +.dex subq.b #1,XReg ;DEX + addq.l #6,Cycles +.lda OLDMEM_AbsIndxY ;LDA $1234,Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +DEXCA_LDABD: +.dex subq.b #1,XReg ;DEX + addq.l #6,Cycles +.lda OLDMEM_AbsIndxX ;LDA $1234,X + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +*---------* +** INY + LDA... No need to do STAT_SZ after INY, reset by LDA! + +INYC8_LDAA1: +.iny addq.b #1,YReg ;INY + addq.l #8,Cycles +.lda OLDMEM_PreIndx ;LDA ($06,X) + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +INYC8_LDAA5: +.iny addq.b #1,YReg ;INY + addq.l #5,Cycles +.lda OLDMEM_ZP ;LDA $06 + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +INYC8_LDAA9: +.iny addq.b #1,YReg ;INY + addq.l #4,Cycles +.lda OLDMEM_ImmedD0 ;LDA #$06 + move.b d0,AReg + STAT_SZ + DOCYCLE + +INYC8_LDAAD: +.iny addq.b #1,YReg ;INY + addq.l #6,Cycles +.lda OLDMEM_Abs ;LDA $1234 + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +INYC8_LDAB1: +.iny addq.b #1,YReg ;INY + addq.l #7,Cycles +.lda OLDMEM_PostIndx ;LDA ($06),Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +INYC8_LDAB5: +.iny addq.b #1,YReg ;INY + addq.l #6,Cycles +.lda OLDMEM_ZPIndxX ;LDA $06,X + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +INYC8_LDAB9: +.iny addq.b #1,YReg ;INY + addq.l #6,Cycles +.lda OLDMEM_AbsIndxY ;LDA $1234,Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +INYC8_LDABD: +.iny addq.b #1,YReg ;INY + addq.l #6,Cycles +.lda OLDMEM_AbsIndxX ;LDA $1234,X + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +*---------* + +DEY88_LDAA1: +.dey subq.b #1,YReg ;DEY + addq.l #8,Cycles +.lda OLDMEM_PreIndx ;LDA ($06,X) + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +DEY88_LDAA5: +.dey subq.b #1,YReg ;DEY + addq.l #5,Cycles +.lda OLDMEM_ZP ;LDA $06 + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +DEY88_LDAA9: +.dey subq.b #1,YReg ;DEY + addq.l #4,Cycles +.lda OLDMEM_ImmedD0 ;LDA #$06 + move.b d0,AReg + STAT_SZ + DOCYCLE + +DEY88_LDAAD: +.dey subq.b #1,YReg ;DEY + addq.l #6,Cycles +.lda OLDMEM_Abs ;LDA $1234 + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +DEY88_LDAB1: +.dey subq.b #1,YReg ;DEY + addq.l #7,Cycles +.lda OLDMEM_PostIndx ;LDA ($06),Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +DEY88_LDAB5: +.dey subq.b #1,YReg ;DEY + addq.l #6,Cycles +.lda OLDMEM_ZPIndxX ;LDA $06,X + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +DEY88_LDAB9: +.dey subq.b #1,YReg ;DEY + addq.l #6,Cycles +.lda OLDMEM_AbsIndxY ;LDA $1234,Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +DEY88_LDABD: +.dey subq.b #1,YReg ;DEY + addq.l #6,Cycles +.lda OLDMEM_AbsIndxX ;LDA $1234,X + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +*---------* +** TAY + LDA... No need to do STAT_SZ after INY, reset by LDA! + +TAYA8_LDAA1: +.tay move.b AReg,YReg ;TAY + addq.l #8,Cycles +.lda OLDMEM_PreIndx ;LDA ($06,X) + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +TAYA8_LDAA5: +.tay move.b AReg,YReg ;TAY + addq.l #5,Cycles +.lda OLDMEM_ZP ;LDA $06 + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +TAYA8_LDAA9: +.tay move.b AReg,YReg ;TAY + addq.l #4,Cycles +.lda OLDMEM_ImmedD0 ;LDA #$06 + move.b d0,AReg + STAT_SZ + DOCYCLE + +TAYA8_LDAAD: +.tay move.b AReg,YReg ;TAY + addq.l #6,Cycles +.lda OLDMEM_Abs ;LDA $1234 + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +TAYA8_LDAB1: +.tay move.b AReg,YReg ;TAY + addq.l #7,Cycles +.lda OLDMEM_PostIndx ;LDA ($06),Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +TAYA8_LDAB5: +.tay move.b AReg,YReg ;TAY + addq.l #6,Cycles +.lda OLDMEM_ZPIndxX ;LDA $06,X + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +TAYA8_LDAB9: +.tay move.b AReg,YReg ;TAY + addq.l #6,Cycles +.lda OLDMEM_AbsIndxY ;LDA $1234,Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +TAYA8_LDABD: +.tay move.b AReg,YReg ;TAY + addq.l #6,Cycles +.lda OLDMEM_AbsIndxX ;LDA $1234,X + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +*---- TAX + LDA -----* + +TAXAA_LDAA1: +.tax move.b AReg,XReg ;TAX + addq.l #8,Cycles +.lda OLDMEM_PreIndx ;LDA ($06,X) + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +TAXAA_LDAA5: +.tax move.b AReg,XReg ;TAX + addq.l #5,Cycles +.lda OLDMEM_ZP ;LDA $06 + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +TAXAA_LDAA9: +.tax move.b AReg,XReg ;TAX + addq.l #4,Cycles +.lda OLDMEM_ImmedD0 ;LDA #$06 + move.b d0,AReg + STAT_SZ + DOCYCLE + +TAXAA_LDAAD: +.tax move.b AReg,XReg ;TAX + addq.l #6,Cycles +.lda OLDMEM_Abs ;LDA $1234 + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +TAXAA_LDAB1: +.tax move.b AReg,XReg ;TAX + addq.l #7,Cycles +.lda OLDMEM_PostIndx ;LDA ($06),Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +TAXAA_LDAB5: +.tax move.b AReg,XReg ;TAX + addq.l #6,Cycles +.lda OLDMEM_ZPIndxX ;LDA $06,X + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +TAXAA_LDAB9: +.tax move.b AReg,XReg ;TAX + addq.l #6,Cycles +.lda OLDMEM_AbsIndxY ;LDA $1234,Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +TAXAA_LDABD: +.tax move.b AReg,XReg ;TAX + addq.l #6,Cycles +.lda OLDMEM_AbsIndxX ;LDA $1234,X + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +*---------* + +PHA48_LDAA1: +.pha PUSH AReg ;PHA + addq.l #4,Cycles ;2 addq's faster than 1 addi.l + addq.l #5,Cycles +.lda OLDMEM_PreIndx ;LDA ($06,X) + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +PHA48_LDAA5: +.pha PUSH AReg ;PHA + addq.l #6,Cycles +.lda OLDMEM_ZP ;LDA $06 + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +PHA48_LDAA9: +.pha PUSH AReg ;PHA + addq.l #5,Cycles +.lda OLDMEM_ImmedD0 ;LDA #$06 + move.b d0,AReg + STAT_SZ + DOCYCLE + +PHA48_LDAAD: +.pha PUSH AReg ;PHA + addq.l #7,Cycles +.lda OLDMEM_Abs ;LDA $1234 + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +PHA48_LDAB1: +.pha PUSH AReg ;PHA + addq.l #8,Cycles +.lda OLDMEM_PostIndx ;LDA ($06),Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +PHA48_LDAB5: +.pha PUSH AReg ;PHA + addq.l #7,Cycles +.lda OLDMEM_ZPIndxX ;LDA $06,X + move.b (Mem_Ptr,d0.l),AReg + STAT_SZ + DOCYCLE + +PHA48_LDAB9: +.pha PUSH AReg ;PHA + addq.l #7,Cycles +.lda OLDMEM_AbsIndxY ;LDA $1234,Y + GETBYTE ;read mem into Acc... + move.b d0,AReg + STAT_SZ + DOCYCLE + +PHA48_LDABD: +.pha PUSH AReg ;PHA + addq.l #7,Cycles +.lda OLDMEM_AbsIndxX ;LDA $1234,X + GETBYTE + move.b d0,AReg + STAT_SZ + DOCYCLE + +************************************************************* +** ANY Inst + STA pairs... +************************************************************* + +INXE8_STA81: +.inx addq.b #1,XReg ;INX + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_PreIndx ;STA ($06,X) + move.b AReg,d1 + PUTBYTE_DOCYCLE + +INXE8_STA8D: +.inx addq.b #1,XReg ;INX + STAT_SZ + addq.l #6,Cycles +.sta OLDMEM_Abs ;STA $1234 8D + move.b AReg,d1 + PUTBYTE_DOCYCLE + +INXE8_STA91: +.inx addq.b #1,XReg ;INX + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_PostIndx ;STA ($06),Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +INXE8_STA99: +.inx addq.b #1,XReg ;INX + STAT_SZ + addq.l #7,Cycles +.sta OLDMEM_AbsIndxY ;STA $1234,Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +INXE8_STA9D: +.inx addq.b #1,XReg ;INX + STAT_SZ + addq.l #7,Cycles +.sta OLDMEM_AbsIndxX ;STA $1234,X + move.b AReg,d1 + PUTBYTE_DOCYCLE + +INXE8_STA85: +.inx addq.b #1,XReg ;INX + STAT_SZ + addq.l #5,Cycles +.sta OLDMEM_ZP ;STA $06 + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +INXE8_STA95: +.inx addq.b #1,XReg ;INX + STAT_SZ + addq.l #6,Cycles +.sta OLDMEM_ZPIndxX ;STX $06,X + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************** + +INYC8_STA81: +.iny addq.b #1,YReg ;INY + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_PreIndx ;STA ($06,X) + move.b AReg,d1 + PUTBYTE_DOCYCLE + +INYC8_STA8D: +.iny addq.b #1,YReg ;INY + STAT_SZ + addq.l #6,Cycles +.sta OLDMEM_Abs ;STA $1234 + move.b AReg,d1 + PUTBYTE_DOCYCLE + +INYC8_STA91: +.iny addq.b #1,YReg ;INY + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_PostIndx ;STA ($06),Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +INYC8_STA99: +.iny addq.b #1,YReg ;INY + STAT_SZ + addq.l #7,Cycles +.sta OLDMEM_AbsIndxY ;STA $1234,Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +INYC8_STA9D: +.iny addq.b #1,YReg ;INY + STAT_SZ + addq.l #7,Cycles +.sta OLDMEM_AbsIndxX ;STA $1234,X + move.b AReg,d1 + PUTBYTE_DOCYCLE + +INYC8_STA85: +.iny addq.b #1,YReg ;INY + STAT_SZ + addq.l #5,Cycles +.sta OLDMEM_ZP ;STA $06 + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +INYC8_STA95: +.iny addq.b #1,YReg ;INY + STAT_SZ + addq.l #6,Cycles +.sta OLDMEM_ZPIndxX ;STX $06,X + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************** + +DEXCA_STA81: +.dex subq.b #1,XReg ;DEX + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_PreIndx ;STA ($06,X) + move.b AReg,d1 + PUTBYTE_DOCYCLE + +DEXCA_STA8D: +.dex subq.b #1,XReg ;DEX + STAT_SZ + addq.l #6,Cycles +.sta OLDMEM_Abs ;STA $1234 + move.b AReg,d1 + PUTBYTE_DOCYCLE + +DEXCA_STA91: +.dex subq.b #1,XReg ;DEX + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_PostIndx ;STA ($06),Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +DEXCA_STA99: +.dex subq.b #1,XReg ;DEX + STAT_SZ + addq.l #7,Cycles +.sta OLDMEM_AbsIndxY ;STA $1234,Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +DEXCA_STA9D: +.dex subq.b #1,XReg ;DEX + STAT_SZ + addq.l #7,Cycles +.sta OLDMEM_AbsIndxX ;STA $1234,X + move.b AReg,d1 + PUTBYTE_DOCYCLE + +DEXCA_STA85: +.dex subq.b #1,XReg ;DEX + STAT_SZ + addq.l #5,Cycles +.sta OLDMEM_ZP ;STA $06 + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +DEXCA_STA95: +.dex subq.b #1,XReg ;DEX + STAT_SZ + addq.l #6,Cycles +.sta OLDMEM_ZPIndxX ;STX $06,X + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************** + +DEY88_STA81: +.dey subq.b #1,YReg ;DEY + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_PreIndx ;STA ($06,X) + move.b AReg,d1 + PUTBYTE_DOCYCLE + +DEY88_STA8D: +.dey subq.b #1,YReg ;DEY + STAT_SZ + addq.l #6,Cycles +.sta OLDMEM_Abs ;STA $1234 + move.b AReg,d1 + PUTBYTE_DOCYCLE + +DEY88_STA91: +.dey subq.b #1,YReg ;DEY + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_PostIndx ;STA ($06),Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +DEY88_STA99: +.dey subq.b #1,YReg ;DEY + STAT_SZ + addq.l #7,Cycles +.sta OLDMEM_AbsIndxY ;STA $1234,Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +DEY88_STA9D: +.dey subq.b #1,YReg ;DEY + STAT_SZ + addq.l #7,Cycles +.sta OLDMEM_AbsIndxX ;STA $1234,X + move.b AReg,d1 + PUTBYTE_DOCYCLE + +DEY88_STA85: +.dey subq.b #1,YReg ;DEY + STAT_SZ + addq.l #5,Cycles +.sta OLDMEM_ZP ;STA $06 + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +DEY88_STA95: +.dey subq.b #1,YReg ;DEY + STAT_SZ + addq.l #6,Cycles +.sta OLDMEM_ZPIndxX ;STX $06,X + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************** + +PLA68_STA81: +.pla PULL AReg ;PLA + tst.b AReg + STAT_SZ + addq.l #5,Cycles ;faster than addi.l #10 + addq.l #5,Cycles +.sta OLDMEM_PreIndx ;STA ($06,X) + move.b AReg,d1 + PUTBYTE_DOCYCLE + +PLA68_STA8D: +.pla PULL AReg ;PLA + tst.b AReg + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_Abs ;STA $1234 + move.b AReg,d1 + PUTBYTE_DOCYCLE + +PLA68_STA91: +.pla PULL AReg ;PLA + tst.b AReg + STAT_SZ + addq.l #5,Cycles + addq.l #5,Cycles +.sta OLDMEM_PostIndx ;STA ($06),Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +PLA68_STA99: +.pla PULL AReg ;PLA + tst.b AReg + STAT_SZ + addq.l #4,Cycles + addq.l #5,Cycles +.sta OLDMEM_AbsIndxY ;STA $1234,Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +PLA68_STA9D: +.pla PULL AReg ;PLA + tst.b AReg + STAT_SZ + addq.l #4,Cycles + addq.l #5,Cycles +.sta OLDMEM_AbsIndxX ;STA $1234,X + move.b AReg,d1 + PUTBYTE_DOCYCLE + +PLA68_STA85: +.pla PULL AReg ;PLA + tst.b AReg + STAT_SZ + addq.l #7,Cycles +.sta OLDMEM_ZP ;STA $06 + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +PLA68_STA95: +.pla PULL AReg ;PLA + tst.b AReg + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_ZPIndxX ;STX $06,X + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************** + +TXA8A_STA81: +.txa move.b XReg,AReg ;TXA + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_PreIndx ;STA ($06,X) + move.b AReg,d1 + PUTBYTE_DOCYCLE + +TXA8A_STA8D: +.txa move.b XReg,AReg ;TXA + STAT_SZ + addq.l #6,Cycles +.sta OLDMEM_Abs ;STA $1234 + move.b AReg,d1 + PUTBYTE_DOCYCLE + +TXA8A_STA91: +.txa move.b XReg,AReg ;TXA + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_PostIndx ;STA ($06),Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +TXA8A_STA99: +.txa move.b XReg,AReg ;TXA + STAT_SZ + addq.l #7,Cycles +.sta OLDMEM_AbsIndxY ;STA $1234,Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +TXA8A_STA9D: +.txa move.b XReg,AReg ;TXA + STAT_SZ + addq.l #7,Cycles +.sta OLDMEM_AbsIndxX ;STA $1234,X + move.b AReg,d1 + PUTBYTE_DOCYCLE + +TXA8A_STA85: +.txa move.b XReg,AReg ;TXA + STAT_SZ + addq.l #5,Cycles +.sta OLDMEM_ZP ;STA $06 + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +TXA8A_STA95: +.txa move.b XReg,AReg ;TXA + STAT_SZ + addq.l #6,Cycles +.sta OLDMEM_ZPIndxX ;STX $06,X + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************** + +TYA98_STA81: +.tya move.b YReg,AReg ;TYA + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_PreIndx ;STA ($06,X) + move.b AReg,d1 + PUTBYTE_DOCYCLE + +TYA98_STA8D: +.tya move.b YReg,AReg ;TYA + STAT_SZ + addq.l #6,Cycles +.sta OLDMEM_Abs ;STA $1234 + move.b AReg,d1 + PUTBYTE_DOCYCLE + +TYA98_STA91: +.tya move.b YReg,AReg ;TYA + STAT_SZ + addq.l #8,Cycles +.sta OLDMEM_PostIndx ;STA ($06),Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +TYA98_STA99: +.tya move.b YReg,AReg ;TYA + STAT_SZ + addq.l #7,Cycles +.sta OLDMEM_AbsIndxY ;STA $1234,Y + move.b AReg,d1 + PUTBYTE_DOCYCLE + +TYA98_STA9D: +.tya move.b YReg,AReg ;TYA + STAT_SZ + addq.l #7,Cycles +.sta OLDMEM_AbsIndxX ;STA $1234,X + move.b AReg,d1 + PUTBYTE_DOCYCLE + +TYA98_STA85: +.tya move.b YReg,AReg ;TYA + STAT_SZ + addq.l #5,Cycles +.sta OLDMEM_ZP ;STA $06 + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +TYA98_STA95: +.tya move.b YReg,AReg ;TYA + STAT_SZ + addq.l #6,Cycles +.sta OLDMEM_ZPIndxX ;STX $06,X + move.b AReg,(Mem_Ptr,d0.l) + DOCYCLE + +** New opts as of 07/29/94 +************************************************************* +** ANY Inst + STX pairs... +************************************************************* + +DEXCA_STX8E: +.dex subq.b #1,XReg ;DEX + STAT_SZ + addq.l #6,Cycles +.stx OLDMEM_Abs ;STX $1234 (4 cyc) + move.b XReg,d1 + PUTBYTE_DOCYCLE + +DEXCA_STX96: +.dex subq.b #1,XReg ;DEX + STAT_SZ + addq.l #6,Cycles +.stx OLDMEM_ZPIndxY ;STX $06,Y (4 cyc) + move.b XReg,(Mem_Ptr,d0.l) + DOCYCLE + +DEXCA_STX86: +.dex subq.b #1,XReg ;DEX + STAT_SZ + addq.l #5,Cycles +.stx OLDMEM_ZP ;STX $06 (3 cyc) + move.b XReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************** + +INXE8_STX8E: +.inx addq.b #1,XReg ;INX + STAT_SZ + addq.l #6,Cycles +.stx OLDMEM_Abs ;STX $1234 (4 cyc) + move.b XReg,d1 + PUTBYTE_DOCYCLE + +INXE8_STX96: +.inx addq.b #1,XReg ;INX + STAT_SZ + addq.l #6,Cycles +.stx OLDMEM_ZPIndxY ;STX $06,Y (4 cyc) + move.b XReg,(Mem_Ptr,d0.l) + DOCYCLE + +INXE8_STX86: +.inx addq.b #1,XReg ;INX + STAT_SZ + addq.l #5,Cycles +.stx OLDMEM_ZP ;STX $06 (3 cyc) + move.b XReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************** + +DEY88_STX8E: +.dey subq.b #1,YReg ;DEY + STAT_SZ + addq.l #6,Cycles +.stx OLDMEM_Abs ;STX $1234 (4 cyc) + move.b XReg,d1 + PUTBYTE_DOCYCLE + +DEY88_STX96: +.dey subq.b #1,YReg ;DEY + STAT_SZ + addq.l #6,Cycles +.stx OLDMEM_ZPIndxY ;STX $06,Y (4 cyc) + move.b XReg,(Mem_Ptr,d0.l) + DOCYCLE + +DEY88_STX86: +.dey subq.b #1,YReg ;DEY + STAT_SZ + addq.l #5,Cycles +.stx OLDMEM_ZP ;STX $06 (3 cyc) + move.b XReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************** + +INYC8_STX8E: +.iny addq.b #1,YReg ;INY + STAT_SZ + addq.l #6,Cycles +.stx OLDMEM_Abs ;STX $1234 (4 cyc) + move.b XReg,d1 + PUTBYTE_DOCYCLE + +INYC8_STX96: +.iny addq.b #1,YReg ;INY + STAT_SZ + addq.l #6,Cycles +.stx OLDMEM_ZPIndxY ;STX $06,Y (4 cyc) + move.b XReg,(Mem_Ptr,d0.l) + DOCYCLE + +INYC8_STX86: +.iny addq.b #1,YReg ;INY + STAT_SZ + addq.l #5,Cycles +.stx OLDMEM_ZP ;STX $06 (3 cyc) + move.b XReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************************************* +** ANY Inst + STY pairs... +************************************************************* + +DEXCA_STY8C: +.dex subq.b #1,XReg ;DEX + STAT_SZ + addq.l #6,Cycles +.sty OLDMEM_Abs ;STY $1234 (4 cyc) + move.b YReg,d1 + PUTBYTE_DOCYCLE + +DEXCA_STY94: +.dex subq.b #1,XReg ;DEX + STAT_SZ + addq.l #6,Cycles +.sty OLDMEM_ZPIndxX ;STY $06,X (4 cyc) + move.b YReg,(Mem_Ptr,d0.l) + DOCYCLE + +DEXCA_STY84: +.dex subq.b #1,XReg ;DEX + STAT_SZ + addq.l #5,Cycles +.sty OLDMEM_ZP ;STY $06 (3 cyc) + move.b YReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************** + +INXE8_STY8C: +.inx addq.b #1,XReg ;INX + STAT_SZ + addq.l #6,Cycles +.sty OLDMEM_Abs ;STY $1234 (4 cyc) + move.b YReg,d1 + PUTBYTE_DOCYCLE + +INXE8_STY94: +.inx addq.b #1,XReg ;INX + STAT_SZ + addq.l #6,Cycles +.sty OLDMEM_ZPIndxX ;STY $06,X (4 cyc) + move.b YReg,(Mem_Ptr,d0.l) + DOCYCLE + +INXE8_STY84: +.inx addq.b #1,XReg ;INX + STAT_SZ + addq.l #5,Cycles +.sty OLDMEM_ZP ;STY $06 (3 cyc) + move.b YReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************** + +DEY88_STY8C: +.dey subq.b #1,YReg ;DEY + STAT_SZ + addq.l #6,Cycles +.sty OLDMEM_Abs ;STY $1234 (4 cyc) + move.b YReg,d1 + PUTBYTE_DOCYCLE + +DEY88_STY94: +.dey subq.b #1,YReg ;DEY + STAT_SZ + addq.l #6,Cycles +.sty OLDMEM_ZPIndxX ;STY $06,X (4 cyc) + move.b YReg,(Mem_Ptr,d0.l) + DOCYCLE + +DEY88_STY84: +.dey subq.b #1,YReg ;DEY + STAT_SZ + addq.l #5,Cycles +.sty OLDMEM_ZP ;STY $06 (3 cyc) + move.b YReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************** + +INYC8_STY8C: +.iny addq.b #1,YReg ;INY + STAT_SZ + addq.l #6,Cycles +.sty OLDMEM_Abs ;STY $1234 (4 cyc) + move.b YReg,d1 + PUTBYTE_DOCYCLE + +INYC8_STY94: +.iny addq.b #1,YReg ;INY + STAT_SZ + addq.l #6,Cycles +.sty OLDMEM_ZPIndxX ;STY $06,X (4 cyc) + move.b YReg,(Mem_Ptr,d0.l) + DOCYCLE + +INYC8_STY84: +.iny addq.b #1,YReg ;INY + STAT_SZ + addq.l #5,Cycles +.sty OLDMEM_ZP ;STY $06 (3 cyc) + move.b YReg,(Mem_Ptr,d0.l) + DOCYCLE + +************************************************************* +** All CLC/SEC + ROL/ROR pairs... +************************************************************* + ;*** Stat dependant! *** +CLC18_ROL2E: +.clc addq.l #8,Cycles +.rol OLDMEM_Abs ;ROL $1234 (6 cyc) + move.w d0,-(sp) + GETBYTE + move.b d0,d1 ;needs to be there for PUTBYTE anyways... + move.b d0,StatusCV ;get Carry from pre-shifted hi-bit + lsl.b d1 ;just do LSL (shift 0 in since carry clear) + STAT_SZ ;get SZ flags + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + +CLC18_ROL26: +.clc addq.l #7,Cycles +.rol OLDMEM_ZP ;ROL $06 (5 cyc) + move.b (Mem_Ptr,d0.l),d1 + move.b d1,StatusCV + lsl.b d1 + STAT_SZ + move.b d1,(Mem_Ptr,d0.l) + DOCYCLE + +CLC18_ROL36: +.clc addq.l #8,Cycles +.rol OLDMEM_ZPIndxX ;ROL $06,X (6 cyc) + move.b (Mem_Ptr,d0.l),d1 + move.b d1,StatusCV + lsl.b d1 + STAT_SZ + move.b d1,(Mem_Ptr,d0.l) + DOCYCLE + +CLC18_ROL3E: +.clc addq.l #8,Cycles + addq.l #1,Cycles +.rol OLDMEM_AbsIndxX ;ROL $1234,X (7 cyc) + move.w d0,-(sp) + GETBYTE + move.b d0,d1 + move.b d0,StatusCV + lsl.b d1 + STAT_SZ + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + + CNOP 0,4 +CLC18_ROL2A: +.clc addq.l #4,Cycles +.rol move.b AReg,StatusCV ;ROL Acc (2 cyc) + lsl.b AReg + STAT_SZ + DOCYCLE + +************************************** + ;*** Stat dependant! *** +SEC38_ROL2E: +.sec addq.l #8,Cycles +.rol OLDMEM_Abs ;ROL $1234 (6 cyc) + move.w d0,-(sp) + GETBYTE + move.b d0,d1 + lsl.b d1 ;do LSL and force in a 1 (due to SEC) + move.b d0,StatusCV ;get carry bit (pre-shifted hi bit) + addq.b #1,d1 ;and force in that 1 + STAT_SZ + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + +SEC38_ROL26: +.sec addq.l #7,Cycles +.rol OLDMEM_ZP ;ROL $06 (5 cyc) + move.b (Mem_Ptr,d0.l),d1 + move.b d1,StatusCV + lsl.b d1 + addq.b #1,d1 + STAT_SZ + move.b d1,(Mem_Ptr,d0.l) + DOCYCLE + +SEC38_ROL36: +.sec addq.l #8,Cycles +.rol OLDMEM_ZPIndxX ;ROL $06,X (6 cyc) + move.b (Mem_Ptr,d0.l),d1 + move.b d1,StatusCV + lsl.b d1 + addq.b #1,d1 + STAT_SZ + move.b d1,(Mem_Ptr,d0.l) + DOCYCLE + +SEC38_ROL3E: +.sec addq.l #8,Cycles + addq.l #1,Cycles +.rol OLDMEM_AbsIndxX ;ROL $1234,X (7 cyc) + move.w d0,-(sp) + GETBYTE + move.b d0,d1 + lsl.b d1 + move.b d0,StatusCV + addq.b #1,d1 + STAT_SZ + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + + CNOP 0,4 +SEC38_ROL2A: +.sec addq.l #8,Cycles +.rol move.b AReg,StatusCV ;ROL Acc (2 cyc) + lsl.b AReg + addq.b #1,AReg + STAT_SZ + DOCYCLE + +************************************** (ROR) + +CLC18_ROR6E: +.clc addq.l #8,Cycles ;CLC +.ror OLDMEM_Abs ;ROR $2134 (6 cyc) + move.w d0,-(sp) + GETBYTE + move.b d0,d1 ;needs to be there for PUTBYTE anyways... + lsr d1 ;shift in a 0 (due to CLC) + STAT_SZC + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + +CLC18_ROR66: +.clc addq.l #7,Cycles ;CLC +.ror OLDMEM_ZP ;ROR $06 (5 cyc) + move.b (Mem_Ptr,d0.l),d1 + lsr d1 + STAT_SZC + move.b d1,(Mem_Ptr,d0.l) + DOCYCLE + + +CLC18_ROR76: +.clc addq.l #8,Cycles ;CLC +.ror OLDMEM_ZPIndxX ;ROR $06,X (6 cyc) + move.b (Mem_Ptr,d0.l),d1 + lsr d1 + STAT_SZC + move.b d1,(Mem_Ptr,d0.l) + DOCYCLE + +CLC18_ROR7E: +.clc addq.l #8,Cycles ;CLC + addq.l #1,Cycles +.ror OLDMEM_AbsIndxX ;ROR $1234,X (7 cyc) + move.w d0,-(sp) + GETBYTE + move.b d0,d1 + lsr d1 + STAT_SZC + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + + CNOP 0,4 +CLC18_ROR6A: +.clc addq.l #4,Cycles ;CLC +.ror lsr AReg ;ROR ACC (2 cyc) + STAT_SZC + DOCYCLE + +************************************** + +SEC38_ROR6E: +.sec addq.l #8,Cycles ;SEC +.ror OLDMEM_Abs ;ROR $2134 (6 cyc) + move.w d0,-(sp) + GETBYTE + move.b d0,d1 ;needs to be there for PUTBYTE anyways... + + lsr d1 [04] ;shift it + STAT_C [04] ;get carry.. + or.b #%10000000,d1 [06] ;and insert a 1 (due to SEC) + STAT_SZ [06]=20 ;and get remaining flags... + + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + +SEC38_ROR66: +.sec addq.l #7,Cycles ;SEC +.ror OLDMEM_ZP ;ROR $06 (5 cyc) + move.b (Mem_Ptr,d0.l),d1 + lsr d1 + STAT_C + or.b #%10000000,d1 + STAT_SZ + move.b d1,(Mem_Ptr,d0.l) + DOCYCLE + + +SEC38_ROR76: +.sec addq.l #8,Cycles ;SEC +.ror OLDMEM_ZPIndxX ;ROR $06,X (6 cyc) + move.b (Mem_Ptr,d0.l),d1 + lsr d1 + STAT_C + or.b #%10000000,d1 + STAT_SZ + move.b d1,(Mem_Ptr,d0.l) + DOCYCLE + +SEC38_ROR7E: +.sec addq.l #8,Cycles ;SEC + addq.l #1,Cycles +.ror OLDMEM_AbsIndxX ;ROR $1234,X (7 cyc) + move.w d0,-(sp) + GETBYTE + move.b d0,d1 + lsr d1 + STAT_C + or.b #%10000000,d1 + STAT_SZ + move.w (sp)+,d0 + PUTBYTE_DOCYCLE + + CNOP 0,4 +SEC38_ROR6A: +.sec addq.l #4,Cycles ;SEC +.ror lsr AReg ;ROR ACC (2 cyc) + STAT_C + or.b #%10000000,AReg + STAT_SZ + DOCYCLE + +************************************************************* +** ANY INST + CMP pairs... +************************************************************* + +INXE8_CMPCD: +.inx addq.b #1,XReg ;INX + addq.l #6,Cycles +.cmp OLDMEM_Abs ;CMP $1234 (4 cyc) + GETBYTE ;read mem, subtract from ACC, set SZC + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +INXE8_CMPC1: +.inx addq.b #1,XReg ;INX + addq.l #8,Cycles +.cmp OLDMEM_PreIndx ;CMP ($06,X) (6 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +INXE8_CMPD1: +.inx addq.b #1,XReg ;INX + addq.l #7,Cycles +.cmp OLDMEM_PostIndx ;CMP ($06),Y (5 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +INXE8_CMPD9: +.inx addq.b #1,XReg ;INX + addq.l #6,Cycles +.cmp OLDMEM_AbsIndxY ;CMP $1234,Y (4 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +INXE8_CMPD5: +.inx addq.b #1,XReg ;INX + addq.l #6,Cycles +.cmp OLDMEM_ZPIndxX ;CMP $06,X (4 cyc) + cmp.b (Mem_Ptr,d0.l),AReg + STAT_SZiC + DOCYCLE + +INXE8_CMPC5: +.inx addq.b #1,XReg ;INX + addq.l #5,Cycles +.cmp OLDMEM_ZP ;CMP $06 (3 cyc) + cmp.b (Mem_Ptr,d0.l),AReg + STAT_SZiC + DOCYCLE + +INXE8_CMPDD: +.inx addq.b #1,XReg ;INX + addq.l #6,Cycles +.cmp OLDMEM_AbsIndxX ;CMP $1234,X (4 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +INXE8_CMPC9: +.inx addq.b #1,XReg ;INX + addq.l #4,Cycles +.cmp OLDMEM_ImmedD0 ;CMP #$06 (2 cyc) + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +************************************** + +DEXCA_CMPCD: +.dex subq.b #1,XReg ;DEX + addq.l #6,Cycles +.cmp OLDMEM_Abs ;CMP $1234 (4 cyc) + GETBYTE ;read mem, subtract from ACC, set SZC + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +DEXCA_CMPC1: +.dex subq.b #1,XReg ;DEX + addq.l #8,Cycles +.cmp OLDMEM_PreIndx ;CMP ($06,X) (6 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +DEXCA_CMPD1: +.dex subq.b #1,XReg ;DEX + addq.l #7,Cycles +.cmp OLDMEM_PostIndx ;CMP ($06),Y (5 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +DEXCA_CMPD9: +.dex subq.b #1,XReg ;DEX + addq.l #6,Cycles +.cmp OLDMEM_AbsIndxY ;CMP $1234,Y (4 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +DEXCA_CMPD5: +.dex subq.b #1,XReg ;DEX + addq.l #6,Cycles +.cmp OLDMEM_ZPIndxX ;CMP $06,X (4 cyc) + cmp.b (Mem_Ptr,d0.l),AReg + STAT_SZiC + DOCYCLE + +DEXCA_CMPC5: +.dex subq.b #1,XReg ;DEX + addq.l #5,Cycles +.cmp OLDMEM_ZP ;CMP $06 (3 cyc) + cmp.b (Mem_Ptr,d0.l),AReg + STAT_SZiC + DOCYCLE + +DEXCA_CMPDD: +.dex subq.b #1,XReg ;DEX + addq.l #6,Cycles +.cmp OLDMEM_AbsIndxX ;CMP $1234,X (4 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +DEXCA_CMPC9: +.dex subq.b #1,XReg ;DEX + addq.l #4,Cycles +.cmp OLDMEM_ImmedD0 ;CMP #$06 (2 cyc) + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +************************************** + +INYC8_CMPCD: +.iny addq.b #1,YReg ;INY + addq.l #6,Cycles +.cmp OLDMEM_Abs ;CMP $1234 (4 cyc) + GETBYTE ;read mem, subtract from ACC, set SZC + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +INYC8_CMPC1: +.iny addq.b #1,YReg ;INY + addq.l #8,Cycles +.cmp OLDMEM_PreIndx ;CMP ($06,X) (6 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +INYC8_CMPD1: +.iny addq.b #1,YReg ;INY + addq.l #7,Cycles +.cmp OLDMEM_PostIndx ;CMP ($06),Y (5 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +INYC8_CMPD9: +.iny addq.b #1,YReg ;INY + addq.l #6,Cycles +.cmp OLDMEM_AbsIndxY ;CMP $1234,Y (4 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +INYC8_CMPD5: +.iny addq.b #1,YReg ;INY + addq.l #6,Cycles +.cmp OLDMEM_ZPIndxX ;CMP $06,X (4 cyc) + cmp.b (Mem_Ptr,d0.l),AReg + STAT_SZiC + DOCYCLE + +INYC8_CMPC5: +.iny addq.b #1,YReg ;INY + addq.l #5,Cycles +.cmp OLDMEM_ZP ;CMP $06 (3 cyc) + cmp.b (Mem_Ptr,d0.l),AReg + STAT_SZiC + DOCYCLE + +INYC8_CMPDD: +.iny addq.b #1,YReg ;INY + addq.l #6,Cycles +.cmp OLDMEM_AbsIndxX ;CMP $1234,X (4 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +INYC8_CMPC9: +.iny addq.b #1,YReg ;INY + addq.l #4,Cycles +.cmp OLDMEM_ImmedD0 ;CMP #$06 (2 cyc) + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +************************************** + +DEY88_CMPCD: +.dey subq.b #1,YReg ;DEY + addq.l #6,Cycles +.cmp OLDMEM_Abs ;CMP $1234 (4 cyc) + GETBYTE ;read mem, subtract from ACC, set SZC + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +DEY88_CMPC1: +.dey subq.b #1,YReg ;DEY + addq.l #8,Cycles +.cmp OLDMEM_PreIndx ;CMP ($06,X) (6 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +DEY88_CMPD1: +.dey subq.b #1,YReg ;DEY + addq.l #7,Cycles +.cmp OLDMEM_PostIndx ;CMP ($06),Y (5 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +DEY88_CMPD9: +.dey subq.b #1,YReg ;DEY + addq.l #6,Cycles +.cmp OLDMEM_AbsIndxY ;CMP $1234,Y (4 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +DEY88_CMPD5: +.dey subq.b #1,YReg ;DEY + addq.l #6,Cycles +.cmp OLDMEM_ZPIndxX ;CMP $06,X (4 cyc) + cmp.b (Mem_Ptr,d0.l),AReg + STAT_SZiC + DOCYCLE + +DEY88_CMPC5: +.dey subq.b #1,YReg ;DEY + addq.l #5,Cycles +.cmp OLDMEM_ZP ;CMP $06 (3 cyc) + cmp.b (Mem_Ptr,d0.l),AReg + STAT_SZiC + DOCYCLE + +DEY88_CMPDD: +.dey subq.b #1,YReg ;DEY + addq.l #6,Cycles +.cmp OLDMEM_AbsIndxX ;CMP $1234,X (4 cyc) + GETBYTE + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +DEY88_CMPC9: +.dey subq.b #1,YReg ;DEY + addq.l #4,Cycles +.cmp OLDMEM_ImmedD0 ;CMP #$06 (2 cyc) + cmp.b d0,AReg + STAT_SZiC + DOCYCLE + +************************************************************* +** Shifts + Bcc pairs... +************************************************************* + +ASL0A_BNED0: +.asl lsl.b AReg ;ASL Acc + beq.b .NoJmp +.bne ;BNE + STAT_SZC + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZC + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +ASL0A_BEQF0: +.asl lsl.b AReg ;ASL Acc + bne.b .NoJmp +.beq ;BEQ + STAT_SZC + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZC + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +ASL0A_BCC90: +.asl lsl.b AReg ;ASL Acc + STAT_SZC + bcs.b .NoJmp +.bcc ;BCC + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE + +.NoJmp + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +ASL0A_BCSB0: +.asl lsl.b AReg ;ASL Acc + STAT_SZC + bcc.b .NoJmp +.bcs ;BCS + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE + +.NoJmp + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +************************************** + +LSR4A_BNED0: +.lsr lsr.b AReg ;LSR Acc + beq.b .NoJmp +.bne ;BNE + STAT_SZC + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZC + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +LSR4A_BEQF0: +.lsr lsr.b AReg ;LSR Acc + bne.b .NoJmp +.beq ;BEQ + STAT_SZC + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZC + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +LSR4A_BCC90: +.lsr lsr.b AReg ;LSR Acc + bcs.b .NoJmp +.bcc ;BCC + STAT_SZC + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZC + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +LSR4A_BCSB0: +.lsr lsr.b AReg ;LSR Acc + bcc.b .NoJmp +.bcs ;BCS + STAT_SZC + addq.l #5,Cycles + move.b (PCount)+,d1 + ext.w d1 + add.w d1,PCount + DOCYCLE +.NoJmp + STAT_SZC + addq.w #1,PCount + addq.l #4,Cycles + DOCYCLE + +************************************************************* +** INX/DEX/INY/DEY + DEC/INC pairs... +************************************************************* + +INXE8_DECCE: +.inx addq.b #1,XReg ;INX + addq.l #8,Cycles +.dec OLDMEM_Abs ;DEC $1234 + move.b (Mem_Ptr,d0.l),d1 ;delay i/o check until write! (not perfect!!!) + subq.b #1,d1 ;DEC memory by 1, set SZ + STAT_SZ + PUTBYTE ;d0 still there? + DOCYCLE + +INXE8_DECDE: +.inx addq.b #1,XReg ;INX + addq.l #8,Cycles + addq.l #1,Cycles +.dec OLDMEM_AbsIndxX ;DEX $1234,X + move.b (Mem_Ptr,d0.l),d1 + subq.b #1,d1 + STAT_SZ + PUTBYTE + DOCYCLE + +INXE8_DECD6: +.inx addq.b #1,XReg ;INX + addq.l #8,Cycles +.dec OLDMEM_ZPIndxX ;DEC $06,X + subq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +INXE8_DECC6: +.inx addq.b #1,XReg ;INX + addq.l #7,Cycles +.dec OLDMEM_ZP ;DEC $06 + subq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +************************************** + +DEXCA_DECCE: +.dex subq.b #1,XReg ;DEX + addq.l #8,Cycles +.dec OLDMEM_Abs ;DEC $1234 + move.b (Mem_Ptr,d0.l),d1 ;delay i/o check until write! (not perfect!!!) + subq.b #1,d1 ;DEC memory by 1, set SZ + STAT_SZ + PUTBYTE ;d0 still there? + DOCYCLE + +DEXCA_DECDE: +.dex subq.b #1,XReg ;DEX + addq.l #8,Cycles + addq.l #1,Cycles +.dec OLDMEM_AbsIndxX ;DEX $1234,X + move.b (Mem_Ptr,d0.l),d1 + subq.b #1,d1 + STAT_SZ + PUTBYTE + DOCYCLE + +DEXCA_DECD6: +.dex subq.b #1,XReg ;DEX + addq.l #8,Cycles +.dec OLDMEM_ZPIndxX ;DEC $06,X + subq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +DEXCA_DECC6: +.dex subq.b #1,XReg ;DEX + addq.l #7,Cycles +.dec OLDMEM_ZP ;DEC $06 + subq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + + + +************************************** + +INYC8_DECCE: +.iny addq.b #1,YReg ;INY + addq.l #8,Cycles +.dec OLDMEM_Abs ;DEC $1234 + move.b (Mem_Ptr,d0.l),d1 ;delay i/o check until write! (not perfect!!!) + subq.b #1,d1 ;DEC memory by 1, set SZ + STAT_SZ + PUTBYTE ;d0 still there? + DOCYCLE + +INYC8_DECDE: +.iny addq.b #1,YReg ;INY + addq.l #8,Cycles + addq.l #1,Cycles +.dec OLDMEM_AbsIndxX ;DEX $1234,X + move.b (Mem_Ptr,d0.l),d1 + subq.b #1,d1 + STAT_SZ + PUTBYTE + DOCYCLE + +INYC8_DECD6: +.iny addq.b #1,YReg ;INY + addq.l #8,Cycles +.dec OLDMEM_ZPIndxX ;DEC $06,X + subq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +INYC8_DECC6: +.iny addq.b #1,YReg ;INY + addq.l #7,Cycles +.dec OLDMEM_ZP ;DEC $06 + subq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + + + +************************************** + +DEY88_DECCE: +.dey subq.b #1,YReg ;DEY + addq.l #8,Cycles +.dec OLDMEM_Abs ;DEC $1234 + move.b (Mem_Ptr,d0.l),d1 ;delay i/o check until write! (not perfect!!!) + subq.b #1,d1 ;DEC memory by 1, set SZ + STAT_SZ + PUTBYTE ;d0 still there? + DOCYCLE + +DEY88_DECDE: +.dey subq.b #1,YReg ;DEY + addq.l #8,Cycles + addq.l #1,Cycles +.dec OLDMEM_AbsIndxX ;DEX $1234,X + move.b (Mem_Ptr,d0.l),d1 + subq.b #1,d1 + STAT_SZ + PUTBYTE + DOCYCLE + +DEY88_DECD6: +.dey subq.b #1,YReg ;DEY + addq.l #8,Cycles +.dec OLDMEM_ZPIndxX ;DEC $06,X + subq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +DEY88_DECC6: +.dey subq.b #1,YReg ;DEY + addq.l #7,Cycles +.dec OLDMEM_ZP ;DEC $06 + subq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + + + +************************************** + +INXE8_INCEE: +.inx addq.b #1,XReg ;INX + addq.l #8,Cycles +.inc OLDMEM_Abs ;INC $1234 (6 cyc) + move.b (Mem_Ptr,d0.l),d1 ;(not perfect!) + addq.b #1,d1 + STAT_SZ + PUTBYTE + DOCYCLE + +INXE8_INCFE: +.inx addq.b #1,XReg ;INX + addq.l #8,Cycles + addq.l #1,Cycles +.inc OLDMEM_AbsIndxX ;INC $1234,X (7 cyc) + move.b (Mem_Ptr,d0.l),d1 + addq.b #1,d1 + STAT_SZ + PUTBYTE + DOCYCLE + +INXE8_INCE6: +.inx addq.b #1,XReg ;INX + addq.l #7,Cycles +.inc OLDMEM_ZP ;INC $06 (5 cyc) + addq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +INXE8_INCF6: +.inx addq.b #1,XReg ;INX + addq.l #8,Cycles +.inc OLDMEM_ZPIndxX ;INC $06,X (6 cyc) + addq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +************************************** + +DEXCA_INCEE: +.dex subq.b #1,XReg ;DEX + addq.l #8,Cycles +.inc OLDMEM_Abs ;INC $1234 (6 cyc) + move.b (Mem_Ptr,d0.l),d1 ;(not perfect!) + addq.b #1,d1 + STAT_SZ + PUTBYTE + DOCYCLE + +DEXCA_INCFE: +.dex subq.b #1,XReg ;DEX + addq.l #8,Cycles + addq.l #1,Cycles +.inc OLDMEM_AbsIndxX ;INC $1234,X (7 cyc) + move.b (Mem_Ptr,d0.l),d1 + addq.b #1,d1 + STAT_SZ + PUTBYTE + DOCYCLE + +DEXCA_INCE6: +.dex subq.b #1,XReg ;DEX + addq.l #7,Cycles +.inc OLDMEM_ZP ;INC $06 (5 cyc) + addq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +DEXCA_INCF6: +.dex subq.b #1,XReg ;DEX + addq.l #8,Cycles +.inc OLDMEM_ZPIndxX ;INC $06,X (6 cyc) + addq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +************************************** + +INYC8_INCEE: +.iny addq.b #1,YReg ;INY + addq.l #8,Cycles +.inc OLDMEM_Abs ;INC $1234 (6 cyc) + move.b (Mem_Ptr,d0.l),d1 ;(not perfect!) + addq.b #1,d1 + STAT_SZ + PUTBYTE + DOCYCLE + +INYC8_INCFE: +.iny addq.b #1,YReg ;INY + addq.l #8,Cycles + addq.l #1,Cycles +.inc OLDMEM_AbsIndxX ;INC $1234,X (7 cyc) + move.b (Mem_Ptr,d0.l),d1 + addq.b #1,d1 + STAT_SZ + PUTBYTE + DOCYCLE + +INYC8_INCE6: +.iny addq.b #1,YReg ;INY + addq.l #7,Cycles +.inc OLDMEM_ZP ;INC $06 (5 cyc) + addq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +INYC8_INCF6: +.iny addq.b #1,YReg ;INY + addq.l #8,Cycles +.inc OLDMEM_ZPIndxX ;INC $06,X (6 cyc) + addq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +************************************** + +DEY88_INCEE: +.dey subq.b #1,YReg ;DEY + addq.l #8,Cycles +.inc OLDMEM_Abs ;INC $1234 (6 cyc) + move.b (Mem_Ptr,d0.l),d1 ;(not perfect!) + addq.b #1,d1 + STAT_SZ + PUTBYTE + DOCYCLE + +DEY88_INCFE: +.dey subq.b #1,YReg ;DEY + addq.l #8,Cycles + addq.l #1,Cycles +.inc OLDMEM_AbsIndxX ;INC $1234,X (7 cyc) + move.b (Mem_Ptr,d0.l),d1 + addq.b #1,d1 + STAT_SZ + PUTBYTE + DOCYCLE + +DEY88_INCE6: +.dey subq.b #1,YReg ;DEY + addq.l #7,Cycles +.inc OLDMEM_ZP ;INC $06 (5 cyc) + addq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +DEY88_INCF6: +.dey subq.b #1,YReg ;DEY + addq.l #8,Cycles +.inc OLDMEM_ZPIndxX ;INC $06,X (6 cyc) + addq.b #1,(Mem_Ptr,d0.l) + STAT_SZ + DOCYCLE + +************************************** + + SECTION TABLES,DATA + CNOP 0,4 +InstPairList: + ;--- Misc simple inst pairs --- + dc.l $e8e8,INXE8_INXE8,$c8c8,INYC8_INYC8,$caca,DEXCA_DEXCA,$8888,DEY88_DEY88 ;OK! + dc.l $0a0a,ASL0A_ASL0A,$4a4a,LSR4A_LSR4A,$6868,PLA68_PLA68 ;ok + + dc.l $8a48,TXA8A_PHA48,$9848,TYA98_PHA48 ;ok + dc.l $6848,PLA68_PHA48,$68a8,PLA68_TAYA8,$68aa,PLA68_TAXAA ;ok + + ;--- And special case JMP (xxFF) bug --- + dc.l $6cff,JMP6C_BUGFF + + ;--- CLC + ADC Pairs --- + dc.l $1861,CLC18_ADC61,$186d,CLC18_ADC6D,$1865,CLC18_ADC65,$1869,CLC18_ADC69 ;ok + dc.l $1871,CLC18_ADC71,$187d,CLC18_ADC7D,$1875,CLC18_ADC75,$1879,CLC18_ADC79 ;ok + + ;--- SEC + SBC Pairs --- + dc.l $38e5,SEC38_SBCE5,$38e1,SEC38_SBCE1,$38ed,SEC38_SBCED,$38f1,SEC38_SBCF1 ;ok + dc.l $38f9,SEC38_SBCF9,$38fd,SEC38_SBCFD,$38e9,SEC38_SBCE9,$38f5,SEC38_SBCF5 + + ;--- DEX/INX + CPX Pairs --- + dc.l $caec,DEXCA_CPXEC,$cae4,DEXCA_CPXE4,$cae0,DEXCA_CPXE0 + dc.l $e8ec,INXE8_CPXEC,$e8e4,INXE8_CPXE4,$e8e0,INXE8_CPXE0 + + ;--- DEY/INY + CPY Pairs --- + dc.l $88cc,DEY88_CPYCC,$88c4,DEY88_CPYC4,$88c0,DEY88_CPYC0 + dc.l $c8cc,INYC8_CPYCC,$c8c4,INYC8_CPYC4,$c8c0,INYC8_CPYC0 + + ;--- AnyInst + LDA Pairs --- + dc.l $e8a1,INXE8_LDAA1,$e8a5,INXE8_LDAA5,$e8a9,INXE8_LDAA9,$e8ad,INXE8_LDAAD + dc.l $e8b1,INXE8_LDAB1,$e8b5,INXE8_LDAB5,$e8b9,INXE8_LDAB9,$e8bd,INXE8_LDABD + dc.l $caa1,DEXCA_LDAA1,$caa5,DEXCA_LDAA5,$caa9,DEXCA_LDAA9,$caad,DEXCA_LDAAD + dc.l $cab1,DEXCA_LDAB1,$cab5,DEXCA_LDAB5,$cab9,DEXCA_LDAB9,$cabd,DEXCA_LDABD + + dc.l $c8a1,INYC8_LDAA1,$c8a5,INYC8_LDAA5,$c8a9,INYC8_LDAA9,$c8ad,INYC8_LDAAD + dc.l $c8b1,INYC8_LDAB1,$c8b5,INYC8_LDAB5,$c8b9,INYC8_LDAB9,$c8bd,INYC8_LDABD + dc.l $88a1,DEY88_LDAA1,$88a5,DEY88_LDAA5,$88a9,DEY88_LDAA9,$88ad,DEY88_LDAAD + dc.l $88b1,DEY88_LDAB1,$88b5,DEY88_LDAB5,$88b9,DEY88_LDAB9,$88bd,DEY88_LDABD + + dc.l $a8a1,TAYA8_LDAA1,$a8a5,TAYA8_LDAA5,$a8a9,TAYA8_LDAA9,$a8ad,TAYA8_LDAAD + dc.l $a8b1,TAYA8_LDAB1,$a8b5,TAYA8_LDAB5,$a8b9,TAYA8_LDAB9,$a8bd,TAYA8_LDABD + dc.l $aaa1,TAXAA_LDAA1,$aaa5,TAXAA_LDAA5,$aaa9,TAXAA_LDAA9,$aaad,TAXAA_LDAAD + dc.l $aab1,TAXAA_LDAB1,$aab5,TAXAA_LDAB5,$aab9,TAXAA_LDAB9,$aabd,TAXAA_LDABD + + dc.l $48a1,PHA48_LDAA1,$48a5,PHA48_LDAA5,$48a9,PHA48_LDAA9,$48ad,PHA48_LDAAD + dc.l $48b1,PHA48_LDAB1,$48b5,PHA48_LDAB5,$48b9,PHA48_LDAB9,$48bd,PHA48_LDABD + + ;---AnyInst + STA Pairs--- + dc.l $e881,INXE8_STA81,$e88d,INXE8_STA8D,$e891,INXE8_STA91,$e899,INXE8_STA99 + dc.l $e89d,INXE8_STA9D,$e885,INXE8_STA85,$e895,INXE8_STA95 + dc.l $c881,INYC8_STA81,$c88d,INYC8_STA8D,$c891,INYC8_STA91,$c899,INYC8_STA99 + dc.l $c89d,INYC8_STA9D,$c885,INYC8_STA85,$c895,INYC8_STA95 + + dc.l $ca81,DEXCA_STA81,$ca8d,DEXCA_STA8D,$ca91,DEXCA_STA91,$ca99,DEXCA_STA99 + dc.l $ca9d,DEXCA_STA9D,$ca85,DEXCA_STA85,$ca95,DEXCA_STA95 + dc.l $8881,DEY88_STA81,$888d,DEY88_STA8D,$8891,DEY88_STA91,$8899,DEY88_STA99 + dc.l $889d,DEY88_STA9D,$8885,DEY88_STA85,$8895,DEY88_STA95 + + dc.l $6881,PLA68_STA81,$688d,PLA68_STA8D,$6891,PLA68_STA91,$6899,PLA68_STA99 + dc.l $689d,PLA68_STA9D,$6885,PLA68_STA85,$6895,PLA68_STA95 + + dc.l $8a81,TXA8A_STA81,$8a8d,TXA8A_STA8D,$8a91,TXA8A_STA91,$8a99,TXA8A_STA99 + dc.l $8a9d,TXA8A_STA9D,$8a85,TXA8A_STA85,$8a95,TXA8A_STA95 + + dc.l $9881,TYA98_STA81,$988d,TYA98_STA8D,$9891,TYA98_STA91,$9899,TYA98_STA99 + dc.l $989d,TYA98_STA9D,$9885,TYA98_STA85,$9895,TYA98_STA95 + + ;---AnyInst + STX Pairs--- (new 7/29/94) + dc.l $ca8e,DEXCA_STX8E,$ca96,DEXCA_STX96,$ca86,DEXCA_STX86 + dc.l $e88e,INXE8_STX8E,$e896,INXE8_STX96,$e886,INXE8_STX86 + dc.l $888e,DEY88_STX8E,$8896,DEY88_STX96,$8886,DEY88_STX86 + dc.l $c88e,INYC8_STX8E,$c896,INYC8_STX96,$c886,INYC8_STX86 + + ;---AnyInst + STY Pairs--- (new 7/29/94) + dc.l $ca8c,DEXCA_STY8C,$ca94,DEXCA_STY94,$ca84,DEXCA_STY84 + dc.l $e88c,INXE8_STY8C,$e894,INXE8_STY94,$e884,INXE8_STY84 + dc.l $888c,DEY88_STY8C,$8894,DEY88_STY94,$8884,DEY88_STY84 + dc.l $c88c,INYC8_STY8C,$c894,INYC8_STY94,$c884,INYC8_STY84 + + ;---CLC/SEC + ROL Pairs--- (new 7/30/94) + dc.l $182e,CLC18_ROL2E,$1826,CLC18_ROL26,$1836,CLC18_ROL36 + dc.l $183e,CLC18_ROL3E,$182a,CLC18_ROL2A + dc.l $382e,SEC38_ROL2E,$3826,SEC38_ROL26,$3836,SEC38_ROL36 + dc.l $383e,SEC38_ROL3E,$382a,SEC38_ROL2A + + ;---CLC/SEC + ROR Pairs--- (new 7/30/94) + dc.l $186e,CLC18_ROR6E,$1866,CLC18_ROR66,$1876,CLC18_ROR76 + dc.l $187e,CLC18_ROR7E,$186a,CLC18_ROR6A + dc.l $386e,SEC38_ROR6E,$3866,SEC38_ROR66,$3876,SEC38_ROR76 + dc.l $387e,SEC38_ROR7E,$386a,SEC38_ROR6A + + ;---AnyInst + CMP Pairs--- (new 7/30/94) + dc.l $e8cd,INXE8_CMPCD,$e8c1,INXE8_CMPC1,$e8d1,INXE8_CMPD1,$e8d9,INXE8_CMPD9 + dc.l $e8d5,INXE8_CMPD5,$e8c5,INXE8_CMPC5,$e8dd,INXE8_CMPDD,$e8c9,INXE8_CMPC9 + dc.l $cacd,DEXCA_CMPCD,$cac1,DEXCA_CMPC1,$cad1,DEXCA_CMPD1,$cad9,DEXCA_CMPD9 + dc.l $cad5,DEXCA_CMPD5,$cac5,DEXCA_CMPC5,$cadd,DEXCA_CMPDD,$cac9,DEXCA_CMPC9 + + dc.l $c8cd,INYC8_CMPCD,$c8c1,INYC8_CMPC1,$c8d1,INYC8_CMPD1,$c8d9,INYC8_CMPD9 + dc.l $c8d5,INYC8_CMPD5,$c8c5,INYC8_CMPC5,$c8dd,INYC8_CMPDD,$c8c9,INYC8_CMPC9 + dc.l $88cd,DEY88_CMPCD,$88c1,DEY88_CMPC1,$88d1,DEY88_CMPD1,$88d9,DEY88_CMPD9 + dc.l $88d5,DEY88_CMPD5,$88c5,DEY88_CMPC5,$88dd,DEY88_CMPDD,$88c9,DEY88_CMPC9 + + + ;--- Shifts + Bcc Pairs --- + dc.l $0ad0,ASL0A_BNED0,$0af0,ASL0A_BEQF0 ;$0a90,ASL0A_BCC90,$0ab0,ASL0A_BCSB0 + dc.l $4ad0,LSR4A_BNED0,$4af0,LSR4A_BEQF0 ;$4a90,LSR4A_BCC90,$4ab0,LSR4A_BCSB0 + + ;--- INX/DEX/INY/DEY + DEC/INC Pairs --- + dc.l $e8ce,INXE8_DECCE,$e8de,INXE8_DECDE,$e8d6,INXE8_DECD6,$e8c6,INXE8_DECC6 + dc.l $cace,DEXCA_DECCE,$cade,DEXCA_DECDE,$cad6,DEXCA_DECD6,$cac6,DEXCA_DECC6 + dc.l $c8ce,INYC8_DECCE,$c8de,INYC8_DECDE,$c8d6,INYC8_DECD6,$c8c6,INYC8_DECC6 + dc.l $88ce,DEY88_DECCE,$88de,DEY88_DECDE,$88d6,DEY88_DECD6,$88c6,DEY88_DECC6 + + dc.l $e8ee,INXE8_INCEE,$e8fe,INXE8_INCFE,$e8e6,INXE8_INCE6,$e8f6,INXE8_INCF6 + dc.l $caee,DEXCA_INCEE,$cafe,DEXCA_INCFE,$cae6,DEXCA_INCE6,$caf6,DEXCA_INCF6 + dc.l $c8ee,INYC8_INCEE,$c8fe,INYC8_INCFE,$c8e6,INYC8_INCE6,$c8f6,INYC8_INCF6 + dc.l $88ee,DEY88_INCEE,$88fe,DEY88_INCFE,$88e6,DEY88_INCE6,$88f6,DEY88_INCF6 + + + dc.l $e901,SBCE9_01 + dc.l $cad0,DEXCA_BNED0,$88d0,DEY88_BNED0 + dc.l $e8d0,INXE8_BNED0,$c8d0,INYC8_BNED0 + +InstPairEarlyEnd: + dc.l $0000,$0000 ;PUT $0001,BRK00 to go past here...! + + ;--- Inc/Dec + Bcc Pairs --- (** Unused during speed regulation! **) + dc.l $caf0,DEXCA_BEQF0,$ca10,DEXCA_BPL10,$ca30,DEXCA_BMI30 + dc.l $88f0,DEY88_BEQF0,$8810,DEY88_BPL10,$8830,DEY88_BMI30 + dc.l $e8f0,INXE8_BEQF0,$e810,INXE8_BPL10,$e830,INXE8_BMI30 + dc.l $c8f0,INYC8_BEQF0,$c810,INYC8_BPL10,$c830,INYC8_BMI30 + + + dc.l 0,0,0,0 + dc.l 0,0,0,0 + + +*-------------------------------------------------------------------* + SECTION APPLEII,CODE + CNOP 0,4 +STOP_INST: ;6502 Inst to stop processing, (Parent WAITING for sig) + clr.l ResumePCount ;set to 0 incase I should resume elsewhere... + clr.l RebootApple ;"" + clr.l ResumeWithDiagnostic ;"" + clr.l ResumeWithNewSpeed + + subq.w #2,PCount + + move.l ParentTaskPtr,a1 + move.l ParentSigMask,d0 + CALLEXEC Signal ;Tell parent "Okay, I'm Stopped..." + + move.l ChildSigMask,d0 ;"When can I continue???" + CALLEXEC Wait + + move.l ResumeWithNewSpeed,d0 + beq .SameSpeed + bmi.b .NoRegulation + +.Regulate + mulu.l RealCycPerFrame,d0 ;WaitCycles= RealCycles*Percentage/100 + divu.l #100,d0 ;32/32->32q + move.l d0,WaitCycPerFrame + move.l Cycles,LastStopCycle + + clr.l InstPairEarlyEnd ;patch out opt'd INC/DEC+BNE/BEQ/BPL pairs! + clr.l InstPairEarlyEnd+4 + + move.l #BNED0Reg,InstJmpTblBkUp+$50*4 ;and use regulated BNE/BEQ/BPL/BMI/JMP + move.l #BEQF0Reg,InstJmpTblBkUp+$70*4 + move.l #BPL10Reg,InstJmpTblBkUp+$90*4 + move.l #BMI30Reg,InstJmpTblBkUp+$b0*4 + move.l #JMP4CReg,InstJmpTblBkUp+$cc*4 + bra.b .DoneFixingSpeed + +.NoRegulation + move.l d0,WaitCycPerFrame ;FIX THIS LATER!!! + move.l #$0001,InstPairEarlyEnd ;patch back in opt'd INC/DEC+Bxx pairs! + move.l #BRK00,InstPairEarlyEnd+4 + + move.l #BNED0,InstJmpTblBkUp+$50*4 ;and fast BNE/BEQ/BPL/BMI/JMP + move.l #BEQF0,InstJmpTblBkUp+$70*4 + move.l #BPL10,InstJmpTblBkUp+$90*4 + move.l #BMI30,InstJmpTblBkUp+$b0*4 + move.l #JMP4C,InstJmpTblBkUp+$cc*4 + +.DoneFixingSpeed: +.SameSpeed: + jsr RestoreTable + move.l ParentTaskPtr,a1 + move.l ParentSigMask,d0 + CALLEXEC Signal ;Signal parent "Okay, Table restored & Im going..." + + tst.l RebootApple ;reboot flag set? + bne .CauseReboot ;yep, go force a reboot + + tst.l ResumeWithDiagnostic ;Diagnostic Message wanted? + beq .noDiag ;no... + +.diag lea .Diag1,a0 ;PCount + jsr DB_String + move.l PCount,d0 + sub.l Mem_Ptr,d0 + jsr DB_HexL + lea .Diag2,a0 ;Acc + jsr DB_String + move.w AReg,d0 + jsr DB_HexW + lea .Diag3,a0 ;XReg + jsr DB_String + move.w XReg,d0 + jsr DB_HexW + lea .Diag4,a0 + jsr DB_String ;YReg + move.w YReg,d0 + jsr DB_HexW + lea .Diag5,a0 ;Stack Loc + jsr DB_String + move.l Stack,d0 + swap d0 + jsr DB_HexW + lea .Diag6,a0 ;Stack Frame + jsr DB_String + move.l Stack,d1 + swap d1 + move.l 1(Mem_Ptr,d1.w),d0 + jsr DB_HexL + move.l 5(Mem_Ptr,d1.w),d0 + jsr DB_HexL + lea .Diag7,a0 + jsr DB_String ;Cycles + move.l Cycles,d0 + jsr DB_HexL + +.noDiag tst.l ResumePCount ;new PCount set? patch it in! + beq .samePC + ;Executable Prog! Set Apple to "freshly booted" status + move.b #%00000001,VidMode ;text page 1 (reset Video!) + jsr RefreshVideo + + move.l #$c082,d0 ;reset 16k card on reset! + GETBYTE ;(read rom, write prot ram) + move.l ResumePCount,PCount ;set PCount + add.l Mem_Ptr,PCount + move.l #$01f00000,Stack ;set stack near top of frame... (top word) + +.samePC jsr RefreshVideo ;get screens all proper! (does ChkVid too) + CLEAR d0 + DOCYCLE + +.CauseReboot: + move.w #00,([Mem_PtrVar.l],$3f2.w) ;blank out soft reset vector... + move.b #00,([Mem_PtrVar.l],$3f4.w) ;and checksum byte... WILL REBOOT! + bsr ChkVid + bra RESET_INSTa ;just go to there myself! + +.Diag1 dc.b 10,13,"PC:",0 +.Diag2 dc.b " A:",0 +.Diag3 dc.b " X:",0 +.Diag4 dc.b " Y:",0 +.Diag5 dc.b " StackPtr:",0 +.Diag6 dc.b " Frame:",0 +.Diag7 dc.b " Cycles:",0 + CNOP 0,4 + +ResumePCount dc.l 0 ;<-- LONG!!! Set 16 bit PC when paused to resume at +RebootApple dc.l 0 ;<-- Boolean! Set TRUE to reboot when continued... +ResumeWithDiagnostic dc.l 0 ;<-- Boolean! Set TRUE to print Diagnostic when continued... +ResumeWithNewSpeed dc.l 0 ;<-- Set to % of Apple speed (or -1 for no regulation!) + +RESET_INST: ;6502 Inst to do a hard-reset (No signals) + jsr RestoreTable ;restore 256k jump table... +RESET_INSTa: + move.w #64,Hardware+aud0+ac_vol.l ;Set Channel 0 Volume to Max + move.w #1,Hardware+aud0+ac_per.l ;Channel 0 Period + + move.w #64,Hardware+aud1+ac_vol.l ;Set Channel 1 Volume to Max + move.w #1,Hardware+aud1+ac_per.l ;Channel 1 Period + + move.l #$c081,d0 ;reset 16k card on reset! + GETBYTE +;floob move.l #$c081,d0 +; GETBYTE + + move.l #0,d0 + move.l #$fffc,a0 ; RESET vector! + FGETWORD ;(doest change hi D0) + add.l Mem_Ptr,d0 + move.l d0,PCount + move.l #$01ff0000,Stack ;reset it to top of frame! (top word) + bset.l #I_BIT,StatusSZ + CLEAR d0 + DOCYCLE + +RestoreTable: ;*** Restore 256k jump table... *** + move.l d2,-(sp) + CALLEXEC Forbid + move.l #InstJmpTblBkUp,a0 ;array of 256 longs... + move.l InstTbl_Var,a1 ;array of 65536 longs... + move.w #255,d1 +.loop move.w #255,d0 + move.l (a0)+,d2 +.lp move.l d2,(a1)+ + dbf d0,.lp + dbf d1,.loop +; bra .done ;<<<-------- temporary + + move.l #InstPairList,a0 + move.l InstTbl_Var,a1 + add.l #$20000,a1 +2$ move.l (a0)+,d0 + beq.b .done + move.l (a0)+,(a1,d0.w*4) + bra.b 2$ +.done CALLEXEC Permit + move.l (sp)+,d2 + rts + + CNOP 0,4 +GBHardWare: ;enter with d0=address to read, clean! + move.l #HardwareReadTbl-$c000*4,a0 + move.l (a0,d0.l*4),d1 + beq .noJmp + move.l d1,a0 + jmp (a0) +.noJmp move.b (Mem_Ptr,d0.l),d0 ;read anything else (for $c000!) + rts + + SECTION TABLES,DATA + CNOP 0,4 +HardwareReadTbl: ;$c000 - $c0ff range... + dc.l $00,HWr_Kybd,HWr_Kybd,HWr_Kybd,HWr_Kybd,HWr_Kybd,HWr_Kybd,HWr_Kybd ;$00-07 + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;$08-0f + dc.l HW_C010,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$10-1f + dc.l $00,$00,$00,$00,$00,$00,$00,$00,HWr_C028,HWr_C029,$0,$0,$0,$0,$0,$00 ;$20-2f + dc.l HW_C030,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$30-3f + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$40-4f + dc.l HW_C050,HW_C051,HW_C052,HW_C053,HW_C054,HW_C055,HW_C056,HW_C057 ;$50-57 + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;58-5f + dc.l $00,HWr_C061,HWr_C062,$00,HWr_C064,HWr_C065,$00,$00 ;60-67 + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;68-6f + dc.l HW_C070_Joystick,HW_C071,$00,$00,$00,$00,$00,$00 ;70-77 + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;78-7f + dc.l HW_C080,HW_C081,HW_C082,HW_C083,HW_C080,HW_C081,HW_C082,HW_C083 ;80-87 + dc.l HW_C088,HW_C089,HW_C082,HW_C08B,HW_C088,HW_C089,HW_C082,HW_C08B ;88-8f + + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;a0-af +; dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,HWr_C099,$00,$00,$00,$00,$00,$00 ;90-9f + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;a0-af + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;b0-bf + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;c0-cf + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;d0-df + dc.l $00,HW_C0E1,$00,HW_C0E3,$00,HW_C0E5,$00,HW_C0E7 ;e0-e7 + dc.l HW_C0E8,HW_C0E9,HW_C0EA,HW_C0EB,HW_C0EC,HWr_C0ED,HW_C0EE,HW_C0EF ;e8-ef + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,HWr_Dgn ;f0-ff + + SECTION APPLEII,CODE + + CNOP 0,4 +PBSlot: rts ;dont write to slot addresses ($c100 - $cfff) + + include "TextMap.s" ;has PBTxt1/PBTxt2 routine! + + include "HiResMap.s" ;has PBHgr1 routine! + + CNOP 0,4 +PBHardWare: ;Called from PutByte. A0=Address, D1=Byte to write. + move.l #HardwareWriteTbl-$c000*4,a1 + move.l (a1,a0.l*4),d0 + beq .noJmp + move.l d0,a1 + jmp (a1) +.noJmp ;move.b d1,(Mem_Ptr,a0.l) + rts + + CNOP 0,4 + + + SECTION TABLES,DATA + CNOP 0,4 +HardwareWriteTbl: + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$00-0f + dc.l HW_C010,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$10-1f + dc.l $00,$00,$00,$00,$00,$00,$00,$00,HWw_C028,$00,$00,$00,$00,$00,$00,$00 ;$20-2f + dc.l HW_C030,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$30-3f + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$40-4f + dc.l HW_C050,HW_C051,HW_C052,HW_C053,HW_C054,HW_C055,HW_C056,HW_C057 ;$50-57 + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;58-5f + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;60-67 (c060=CasseteIn) + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;$c068 - $c06f + dc.l HW_C070_Joystick,HW_C071,$0,$0,$0,$0,$0,$0 ;70-77 + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;78-7f + dc.l HW_C080,HW_C081,HW_C082,HW_C083,HW_C080,HW_C081,HW_C082,HW_C083 ;80-87 + dc.l HW_C088,HW_C089,HW_C082,HW_C08B,HW_C088,HW_C089,HW_C082,HW_C08B ;88-8f +; dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,HWw_C09A,$00,$00,$00,$00,$00 ;90-9f + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;90-9f + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;a0-af + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;b0-bf + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;c0-cf + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;d0-df + dc.l $00,HW_C0E1,$00,HW_C0E3,$00,HW_C0E5,$00,HW_C0E7 ;e0-e7 + dc.l HW_C0E8,HW_C0E9,HW_C0EA,HW_C0EB,HW_C0EC,HWw_C0ED,HW_C0EE,HW_C0EF ;e8-ef + dc.l HW_C0F0,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,HWw_Dgn ;f0-ff + + SECTION APPLEII,CODE + CNOP 0,4 +******** HardWare Accesses ********* + ;HW_$$$$ subroutines are intended to handle "touch" access + ;(not READ or WRITE). Input: D1 = Data to write (if any) + ;HWR_$$$$ are for Hardware Reads (d0 = result) + +HWr_Dgn: ;diagnostic, print msg & hardware addr attempting to read... + lea .msg,a0 + jsr DB_String + jsr DB_HexW + rts +.msg dc.b 10,"Hardware read of: ",0 + + CNOP 0,4 +HWw_Dgn: ;diagnostic, print msg & hardware addr attempting to read... + move.l a0,d0 + lea .msg,a0 + jsr DB_String + jsr DB_HexW + rts +.msg dc.b 10,"Hardware write of: ",0 + + CNOP 0,4 + +HWr_C099: ;read from ser port? + move.l #$c099,a0 + move.b (Mem_Ptr,a0.l),d0 +; move.b #0,(Mem_Ptr,a0.l) + rts + +HWw_C09A: ;write to ser port? + move.l #$c09a,a0 + move.b d1,.msg + lea .msg,a0 + jsr DB_String + rts +.msg dc.b 0,0 + + CNOP 0,4 +HWr_Kybd: ;for $c001 - $c007 (frogger uses $c006) + move.l #$c000,a0 + move.b (Mem_Ptr,a0.l),d0 + rts + + CNOP 0,4 +HW_C010 move.l #$c000,a0 ;Kybrd strobe, Clear keyboard + and.b #$7f,(Mem_Ptr,a0.l) + rts + +; +; HWw_C028 --- My custom hardware interface, located in disk subsystem code.... + + CNOP 0,4 +HW_C030 + move.w #INTF_AUD0!INTF_AUD1,Hardware+intreq.l ;Chnl 0 int req clr, Audio Machine can take data + eor.w #$ffff,.SndDat + move.w .SndDat,Hardware+aud0+ac_dat.l ;Channel 0 Data! + move.w .SndDat,Hardware+aud1+ac_dat.l ;Channel 1 data! + rts +.SndDat dc.w $7f7f + + + + CNOP 0,4 +HWr_C061 move.b $bfe001.l,d0 ;reading Button #0 status... (Fix to CIAAPRA laters!) + bpl .press +.noBut move.l #$c061,a0 ;No joy button, return contents of memory + move.b (Mem_Ptr,a0.l),d0 ; location (cause ALT keys set it..) + rts +.press move.b #$ff,d0 ;Joy Button pressed! Return as such!! + rts + CNOP 0,4 + +HWr_C061_Analog: + + move.w Hardware+joy1dat.l,d0 + + btst.l #9,d0 ;test joystick button... + sne.b d0 + move.l #$c061,a0 ;& allow ALT override... + or.b (Mem_Ptr,a0.l),d0 + rts + +HWr_C062 move.w $dff016.l,d0 ;read button #1 status... (Fix to POTINP laters!) + + btst.l #14,d0 + beq .press +.noBut move.l #$c062,a0 ;no joy, return contents of memory + move.b (Mem_Ptr,a0.l),d0 ;location (cause ALT keys set it...) + rts +.press move.b #$ff,d0 + rts + +HWr_C062_Analog: + move.w Hardware+joy1dat.l,d0 + + btst.l #1,d0 ;test joystick button... + sne.b d0 + move.l #$c062,a0 ;& allow ALT override... + or.b (Mem_Ptr,a0.l),d0 + rts + + CNOP 0,4 +HWr_C064 move.l Cycles,d0 ;PDL 0 Countdown timer.. (goes + when done) + sub.l PdlOrigCyc,d0 ;get elapsed cycles... + cmp.l Pdl0Wait,d0 + blo.s .NotYet +.Yes move.b #00,d0 + rts +.NotYet move.b #$80,d0 + rts + + CNOP 0,4 +HWr_C065 move.l Cycles,d0 ;PDL 1 Countdown timer.. (goes + when done) + sub.l PdlOrigCyc,d0 ;get elapsed cycles... + cmp.l Pdl1Wait,d0 + blo.s .NotYet +.Yes move.b #00,d0 + rts +.NotYet move.b #$80,d0 + rts + CNOP 0,4 + +HW_C070_Joystick: ;*** Strobe PDLs, start timers (Joystick) *** + move.w Hardware+joy1dat.l,d0 + + moveq.l #8,d1 ;If left, use 8 cycles... + btst.l #9,d0 + bne.b .CkUpDn + + move.w #2940,d1 ;If right, use use 2940 cycles... + btst.l #1,d0 ;(2940 is min for champ Lode Runner) + bne.b .CkUpDn + + move.w Pdl0CenterW,d1 ;else centered, use variable center value + +.CkUpDn move.l d1,Pdl0Wait + ;pdl routines have 11 cycles min resolution + move.w d0,d1 ;(hardware already read above) + lsl.w d1 + eor.w d1,d0 ;XOR bit #0 onto bit #1, bit #8 onto bit #9 + + moveq.l #8,d1 ;if up, use 8 cycles... + btst.l #9,d0 + bne.b .done + + move.w #2940,d1 ;if down, use 2940 cycles... + btst.l #1,d0 + bne.b .done + + move.w Pdl1CenterW,d1 ;else centered, use variable center value + +.done move.l d1,Pdl1Wait + move.l Cycles,PdlOrigCyc + rts + + CNOP 0,4 + +HW_C070_Mouse: ;*** Strobe PDLs, start timers (Mouse) *** + +.pdl0 move.l MyWindow,a0 + move.w wd_MouseX(a0),d1 + +.pdl0ok mulu.w #2360,d1 ;d1 = XPos * 2360 / 256 (cycles=0->2940) + lsr.l #8,d1 + move.l d1,Pdl0Wait ;how many cycles timer will need for this... + +.pdl1 move.l MyWindow,a0 + move.w wd_MouseY(a0),d1 + + mulu.w #3783,d1 ;d1 = YPos * 3783 / 256 (cycles=0->2940) + lsr.l #8,d1 + move.l d1,Pdl1Wait + + move.l Cycles,PdlOrigCyc + rts + + +HW_C070_Analog: ;*** Strobe PDLs, start timers (Anlg Jystk) *** + move.w PotPosition,a0 ;a0 = backup PotPosition value + move.w a0,d0 + +.ChkY cmp.b PotMinY,d0 ;Check min Y value, extend if needed + bhs.b .1 + move.b d0,PotMinY + bra.b .2 +.1 cmp.b PotMaxY,d0 ;Check max Y value, extend if needed + bls.b .2 + move.b d0,PotMaxY +.2 moveq.l #0,d1 + move.b PotMaxY,d1 + sub.b PotMinY,d1 ;d1.l = Range of values (MaxY-MinY) in clean Long + + sub.b PotMinY,d0 ;d0 = Normalized Y value (starting at 0) + + tst.b PdlMode ;if in Pdl mode, then value = Max-Value + beq .3 + neg.b d0 + add.b PotMaxY,d0 + +.3 lsl.w #8,d0 + and.l #$ffff,d0 + divu.w d1,d0 ;d0.w = Value * 256 / Range + + mulu.w #12,d0 + addq.l #1,d0 ;d0.l = how many cycles for pdl strobe to go hi + move.l d0,Pdl1Wait + + + move.w a0,d0 + lsr.w #8,d0 + +.ChkX cmp.b PotMinX,d0 ;Check min X value, extend if needed + bhs.b .5 + move.b d0,PotMinX + bra.b .6 +.5 cmp.b PotMaxX,d0 ;Check max X value, extend if needed + bls.b .6 + move.b d0,PotMaxX + +.6 moveq.l #0,d1 + move.b PotMaxX,d1 + sub.b PotMinX,d1 ;d1.l = Range of values (MaxX-MinX) in clean Long + + sub.b PotMinX,d0 ;d0 = Normalized Y value (starting at 0) + + tst.b PdlMode ;if in Pdl mode, then value = Max-Value + beq .7 + neg.b d0 + add.b PotMaxX,d0 + +.7 lsl.w #8,d0 + and.l #$ffff,d0 + divu.w d1,d0 ;d0.w = Value * 256 / Range + + mulu.w #12,d0 + addq.l #1,d0 ;d0.l = how many cycles for pdl strobe to go hi + move.l d0,Pdl0Wait + + move.l Cycles,PdlOrigCyc + rts + + +HW_C070_AtariPdl: ;Merely jump to AnalogJoystick support call... + jmp HW_C070_Analog + + +HW_C071 ;I'm not sure EXACTLY how this works, but it sets PDL 1 timer + move.l HardwareWriteTbl+$70*4,a1 ;just call $c070 routine for now... +; move.l $70*4(a1),a1 + jmp (a1) + +Pdl0Wait dc.l 0 ;# of cycles until paddle timer is done +Pdl1Wait dc.l 0 ;# of cycles "" +PdlOrigCyc dc.l 0 ;Current cycles at strobe of pdls... +Pdl0CenterW dc.w 127*11 ;adjustable, default to 127 +Pdl1CenterW dc.w 127*11 ;adjustable, "" + +HW_C0F0 ;MY CONTROL of hi-res shadowing on/off + ;write #$00 for both off, $f0 for pg 1 on, $0f for pg2 on + ;$ff for both pages on + + move.b d0,(Mem_Ptr,a0.l) + lea PBPageList,a0 +.OffOff move.w #$20,d0 +.lp1 move.l #0,(a0,d0.w*4) + addq.w #1,d0 + cmp.w #$60,d0 + blo.b .lp1 + + cmp.b #$f0,d1 + beq .On1 + cmp.b #$ff,d1 + beq .On1 + beq .NotOn1 + +.On1 move.w #$20,d0 +.lp2 move.l #PBHgr1,(a0,d0.w*4) + addq.w #1,d0 + cmp.w #$40,d0 + blo.b .lp2 + +.NotOn1 cmp.b #$0f,d1 + beq .On2 + cmp.b #$ff,d1 + beq .On2 + rts + +.On2 move.w #$40,d0 +.lp3 move.l #PBHgr2,(a0,d0.w*4) + addq.w #1,d0 + cmp.w #$60,d0 + blo.b .lp3 + rts + + + + +*************************************************************************************** +* 16K card hardware routines - Each of the individual hardware accesses to slot 0 +* ram card. Bank memory is handled via screened & re-directed memory writes, and +* reads are quick from direct ram (but swapped beforehand). enter w/ d1=data, a0=addr +* NOTE: DBL-Access to enable ram writing is not implimented until I understand exact +* circumstances of STAs, Pre-Enabled writing (another single enable disables?), etc + +* The "Bank" memory ptd to by "Bank_PtrVar" is mapped as follows: +* $0000 - $0fff : Bank1 Ram (used in apple $d000 - $dfff) +* $1000 - $1fff : Bank2 Ram (used in apple $d000 - $dfff) +* $2000 - $3fff : 8K block (used in apple $e000 - $ffff) + + +HW_C080: ;*** Read from Ram Bank 2, write Disabled *** + cmp.b #2,CurrentReadBank ;reading from bank 2 already? + beq.b .setWrt + +; move.l Bank_PtrVar,a0 ;Put bank 2 in memory to read... +; add.l #$1000,a0 ;a0 -> Bank 2 & 8K block +; move.l Mem_PtrVar,a1 +; add.l #$d000,a1 ;a1 -> Apple $d000 +; move.w #$3000/4-1,d0 +;.MemCpy move.l (a0)+,(a1)+ +; dbf d0,.MemCpy + + move.l Bank_PtrVar,a0 ;Put bank 2 in memory to read... + add.l #$1000,a0 ;a0 -> Bank 2 backup + move.l Mem_PtrVar,a1 + add.l #$d000,a1 ;a1 -> Apple $d000 + move.w #$1000/4-1,d0 +.2 move.l (a0)+,(a1)+ + dbf d0,.2 + + tst.b CurrentReadBank ;reading from common 8k block already? + bne.b .setWrt + +.8k move.l Bank_PtrVar,a0 ;Put 8k block in memory to read... + add.l #$2000,a0 ;a0 -> 8k block backup + move.l Mem_PtrVar,a1 + add.l #$e000,a1 ;a1 -> Apple $e000 + move.w #$2000/4-1,d0 +.8 move.l (a0)+,(a1)+ + dbf d0,.8 + +.setWrt + lea PBPageList,a0 ;write protect rom space... + lea $d0*4(a0),a0 ;a0 -> PBPageList entry for $D0xx + lea PBNone,a1 ;a1 -> Addr of "PBNone" + move.w #$30-1,d0 +.WPRam move.l a1,(a0)+ + dbf d0,.WPRam + +.done move.l #$c080,Last_C08x + move.b #2,CurrentReadBank + rts + + + +HW_C081: ;*** Read from ROM, write Ram Bank 2 *** + cmp.b #0,CurrentReadBank ;reading from Rom already? + beq.b .setWrt + + move.l Bank_PtrVar,a0 ;Put Rom data in memory to read... + add.l #$4000,a0 ;a0 -> Rom Buffer + move.l Mem_PtrVar,a1 + add.l #$d000,a1 ;a1 -> Apple $d000 + move.w #$3000/4-1,d0 +.RomCpy move.l (a0)+,(a1)+ + dbf d0,.RomCpy + +.setWrt + lea PBPageList,a0 + lea $d0*4(a0),a0 ;a0 -> PBPageList entry for $D0xx + lea PBBank2,a1 ;a1 -> Addr of "PBBank2" + move.w #$10-1,d0 +.Bnk2 move.l a1,(a0)+ + dbf d0,.Bnk2 + lea PBBank,a1 ;a1 -> Addr of "PBBank" 8k block + move.w #$20-1,d0 +.Bnk8 move.l a1,(a0)+ + dbf d0,.Bnk8 + +.done move.l #$c081,Last_C08x + move.b #0,CurrentReadBank + rts + + + +HW_C082: ;*** Read from ROM, write Disabled *** + cmp.b #0,CurrentReadBank ;reading from Rom already? + beq.b .setWrt + + move.l Bank_PtrVar,a0 ;Put Rom data in memory to read... + add.l #$4000,a0 ;a0 -> ROM Buffer... + move.l Mem_PtrVar,a1 + add.l #$d000,a1 ;a1 -> Apple $d000 + move.w #$3000/4-1,d0 +.RomCpy move.l (a0)+,(a1)+ + dbf d0,.RomCpy + +.setWrt + lea PBPageList,a0 + lea $d0*4(a0),a0 ;a0 -> PBPageList entry for $D0xx + lea PBNone,a1 ;a1 -> Addr of "PBNone" + move.w #$30-1,d0 +.WPRam move.l a1,(a0)+ + dbf d0,.WPRam + +.done move.l #$c082,Last_C08x + move.b #0,CurrentReadBank + rts + + + +HW_C083 ;*** Read & Write Ram Bank 2 *** + cmp.b #2,CurrentReadBank ;reading from bank 2 already? + beq.b .setWrt + +; move.l Bank_PtrVar,a0 +; add.l #$1000,a0 ;a0 -> Bank 2 & 8K Block +; move.l Mem_PtrVar,a1 +; add.l #$d000,a1 ;a1 -> Apple $d000 +; move.w #$3000/4-1,d0 +;.MemCpy move.l (a0)+,(a1)+ +; dbf d0,.MemCpy + + move.l Bank_PtrVar,a0 ;Put bank 2 in memory to read... + add.l #$1000,a0 ;a0 -> Bank 2 backup + move.l Mem_PtrVar,a1 + add.l #$d000,a1 ;a1 -> Apple $d000 + move.w #$1000/4-1,d0 +.2 move.l (a0)+,(a1)+ + dbf d0,.2 + + tst.b CurrentReadBank ;reading from common 8k block already? + bne.b .setWrt + +.8k move.l Bank_PtrVar,a0 ;Put 8k block in memory to read... + add.l #$2000,a0 ;a0 -> 8k block backup + move.l Mem_PtrVar,a1 + add.l #$e000,a1 ;a1 -> Apple $e000 + move.w #$2000/4-1,d0 +.8 move.l (a0)+,(a1)+ + dbf d0,.8 + +.setWrt + lea PBPageList,a0 + lea $d0*4(a0),a0 ;a0 -> PBPageList entry for $D0xx + lea PBBoth2,a1 ;a1 -> Addr of "PBBoth2" + move.w #$10-1,d0 +.Bnk2 move.l a1,(a0)+ + dbf d0,.Bnk2 +; lea PBBank,a1 ;a1 -> """" + move.w #$20-1,d0 +.Bnk8 move.l a1,(a0)+ + dbf d0,.Bnk8 + +.done move.l #$c083,Last_C08x + move.b #2,CurrentReadBank + rts + + + +HW_C088: ;*** Read from Ram Bank 1, write Disabled *** + cmp.b #1,CurrentReadBank ;reading from bank 1 already? + beq.b .setWrt + +; move.l Bank_PtrVar,a0 +; move.l Mem_PtrVar,a1 ;a0 -> Bank 1 +; add.l #$d000,a1 ;a1 -> Apple $d000 +; move.w #$1000/4-1,d0 +;.MemCpy move.l (a0)+,(a1)+ +; dbf d0,.MemCpy +; +; add.l #$1000,a0 ;a0 -> 8K Bank ( a1 -> Apple $e000) +; move.w #$2000/4-1,d0 +;.Mem2 move.l (a0)+,(a1)+ +; dbf d0,.Mem2 + + move.l Bank_PtrVar,a0 ;Put bank 1 in memory to read... + move.l Mem_PtrVar,a1 ;a0 -> Bank 1 backup + add.l #$d000,a1 ;a1 -> Apple $d000 + move.w #$1000/4-1,d0 +.1 move.l (a0)+,(a1)+ + dbf d0,.1 + + tst.b CurrentReadBank ;reading from common 8k block already? + bne.b .setWrt + +.8k move.l Bank_PtrVar,a0 ;Put 8k block in memory to read... + add.l #$2000,a0 ;a0 -> 8k block backup + move.l Mem_PtrVar,a1 + add.l #$e000,a1 ;a1 -> Apple $e000 + move.w #$2000/4-1,d0 +.8 move.l (a0)+,(a1)+ + dbf d0,.8 + +.setWrt + lea PBPageList,a0 + lea $d0*4(a0),a0 ;a0 -> PBPageList entry for $D0xx + lea PBNone,a1 ;a1 -> Addr of "PBNone" + move.w #$30-1,d0 +.WPRam move.l a1,(a0)+ + dbf d0,.WPRam + +.done move.l #$c088,Last_C08x + move.b #1,CurrentReadBank + rts + + + +HW_C089: ;**** Read from ROM, write Ram Bank 1 *** + cmp.b #0,CurrentReadBank ;reading from Rom already? + beq.b .setWrt + + move.l Bank_PtrVar,a0 + add.l #$4000,a0 ;a0 -> Rom Buffer + move.l Mem_PtrVar,a1 + add.l #$d000,a1 ;a1 -> Apple $d000 + move.w #$3000/4-1,d0 +.RomCpy move.l (a0)+,(a1)+ + dbf d0,.RomCpy + +.setWrt + lea PBPageList,a0 + lea $d0*4(a0),a0 ;a0 -> PBPageList entry for $D0xx + lea PBBank1,a1 ;a1 -> Addr of "PBBank1" + move.w #$10-1,d0 +.Bnk1 move.l a1,(a0)+ + dbf d0,.Bnk1 + lea PBBank,a1 ;a1 -> Addr of "PBBank" 8k block + move.w #$20-1,d0 +.Bnk8 move.l a1,(a0)+ + dbf d0,.Bnk8 + +.done move.l #$c089,Last_C08x + move.b #0,CurrentReadBank + rts + + + +HW_C08B ;*** Read & write Ram Bank 1 *** + cmp.b #1,CurrentReadBank ;reading from bank 1 already? + beq.b .setWrt + +; move.l Bank_PtrVar,a0 +; move.l Mem_PtrVar,a1 ;a0 -> Bank 1 +; add.l #$d000,a1 ;a1 -> Apple $d000 +; move.w #$1000/4-1,d0 +;.MemCpy move.l (a0)+,(a1)+ +; dbf d0,.MemCpy +; +; add.l #$1000,a0 ;a0 -> 8K Bank ( a1 -> Apple $e000) +; move.w #$2000/4-1,d0 +;.Mem2 move.l (a0)+,(a1)+ +; dbf d0,.Mem2 + + move.l Bank_PtrVar,a0 ;Put bank 1 in memory to read... + move.l Mem_PtrVar,a1 ;a0 -> Bank 1 backup + add.l #$d000,a1 ;a1 -> Apple $d000 + move.w #$1000/4-1,d0 +.1 move.l (a0)+,(a1)+ + dbf d0,.1 + + tst.b CurrentReadBank ;reading from common 8k block already? + bne.b .setWrt + +.8k move.l Bank_PtrVar,a0 ;Put 8k block in memory to read... + add.l #$2000,a0 ;a0 -> 8k block backup + move.l Mem_PtrVar,a1 + add.l #$e000,a1 ;a1 -> Apple $e000 + move.w #$2000/4-1,d0 +.8 move.l (a0)+,(a1)+ + dbf d0,.8 + +.setWrt + lea PBPageList,a0 + lea $d0*4(a0),a0 ;a0 -> PBPageList entry for $D0xx + lea PBBank1RW,a1 ;a1 -> Addr of "PBBank1RW" (read & write) + move.w #$10-1,d0 +.Bnk2 move.l a1,(a0)+ + dbf d0,.Bnk2 + lea PBBoth2,a1 ;a1 -> addr of "PBBoth2" + move.w #$20-1,d0 +.Bnk8 move.l a1,(a0)+ + dbf d0,.Bnk8 + +.done move.l #$c08b,Last_C08x + move.b #1,CurrentReadBank + rts + + CNOP 0,4 +CurrentReadBank dc.b 0 ;= 0 (rom), 1 (bank 1), 2 (bank 2) +;CurrentWriteBank dc.b 0 ;= 0 (rom), 1 (bank 1), 2 (bank 2) + + CNOP 0,4 +PBBank1 move.l Bank_PtrVar,a1 ;Write a byte to Bank 1 + sub.l #$d000,a1 ;offset + move.b d1,(a1,a0.l) + rts + +PBBank2 move.l Bank_PtrVar,a1 ;Write a byte to Bank 2 + sub.l #$c000,a1 ;offset... - $d000 + $1000 + move.b d1,(a1,a0.l) + rts + +PBBoth2 move.l Bank_PtrVar,a1 ;Write to Bank 2/8k bank & apple $d000 area (rd/wrt) + sub.l #$c000,a1 + move.b d1,(a1,a0.l) + move.b d1,(Mem_Ptr,a0.l) + rts + +PBBank1RW + move.l Bank_PtrVar,a1 ;Write a byte to Bank 1 AND Apple $dxxx + sub.l #$d000,a1 + move.b d1,(a1,a0.l) + move.b d1,(Mem_Ptr,a0.l) + rts + +PBBank move.l Bank_PtrVar,a1 ;Write a byte to 8K bank ($e000-$ffff) + sub.l #$c000,a1 ; - $e000 + $2000 + move.b d1,(a1,a0.l) +PBNone rts + +Last_C08x dc.l 0 ;holds last address touched +;BankRamStat dc.l 0 ; + +*************************************************************************************** +* Disk hardware routines - Each of the individual hardware accesses to the slot 6 +* drive controller. For optimization, when the drive 1 is turned off, most entries +* for slot 6 h/w jump tables are turned off, and turned back on when used. +* This prevents contant checks for each byte read/written... +* ---(currently, only checks Drive #, not motor status for speed) + + CNOP 0,4 + +HWw_C028: ;MY Custom Hardware location for Drive i/o + cmp.b #$22,d1 + bhi.b .NotTrk +.Trk move.b d1,disk_Track + bra NewTk + +.NotTrk cmp.b #$90,d1 + beq.b .MkTbl + rts +.MkTbl lea DiskDataToValTbl,a0 + move.l #$36c,a1 ;Put table in $36c -> $3d5 magically! +.lp move.b (a0)+,(Mem_Ptr,a1.l) + addq.l #1,a1 + cmp.w #$3d5,a1 + bls.b .lp + rts + +HWr_C028: ;MY Custom Hardware location for Drive i/o + ;Upon reading this location, the next byte will be read from the disk, + ;and will be returned as NORMALIZED 6 bit number (via table)... + + jsr HW_C0EC ;go read next byte of data... + and.w #$ff,d0 ;mask out top... + cmp.b #$96,d0 ;ensure in range (in case no disk image present) + bhs.b .InRng + move.b #$96,d0 +.InRng move.l #DiskDataToValTbl-$96,a0 ;look up normal val in table... + move.b (a0,d0.w),d0 + rts + +HWr_C029: ;MY Custom Hardware location for Drive i/o + ;Reading this location will read next 2 bytes from disk, + ;and return a byte in 4X4 decoded format... + jsr HW_C0EC + lsl.b d0 + or.b #$01,d0 + move.w d0,-(sp) + jsr HW_C0EC + and.w (sp)+,d0 + rts + + ;The lookup table used as $ba00,y ALWAYS had Y >= $96, + ;so here is the pertinant portion of the table ($ba96-$baff) + ;Make sure to subtract $96 when getting the address of it. +DiskDataToValTbl: + dc.b $00,$01,$00,$00,$02,$03,$00,$04,$05,$06,$00,$00,$00,$00,$00 + dc.b $00,$07,$08,$00,$00,$00,$09,$0A,$0B,$0C,$0D,$00,$00,$0E,$0F + dc.b $10,$11,$12,$13,$00,$14,$15,$16,$17,$18,$19,$1A,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$1B,$00,$1C,$1D,$1E,$00,$00 + dc.b $00,$1F,$00,$00,$20,$21,$00,$22,$23,$24,$25,$26,$27,$28,$00 + dc.b $00,$00,$00,$00,$29,$2A,$2B,$00,$2C,$2D,$2E,$2F,$30,$31,$32 + dc.b $00,$00,$33,$34,$35,$36,$37,$38,$00,$39,$3A,$3B,$3C,$3D,$3E,$3F + + CNOP 0,4 + +HW_C0E1 move.w disk_DriveW,d1 ;index of 0 or 1 into disk drive fields... + move.b (disk_Phase.l,d1.w),d0 ;access fields (indexed to drive 1 or 2) + move.b #0,(disk_Phase.l,d1.w) + cmp.b #3,d0 ;phase 0 high (track!) + beq IncTk + cmp.b #1,d0 + beq DecTk + rts + +HW_C0E3 move.w disk_DriveW,d1 + move.b #1,(disk_Phase.l,d1.w) ;phase 1 high (half track) + rts + +HW_C0E5 move.w disk_DriveW,d1 + move.b (disk_Phase.l,d1.w),d0 + move.b #2,(disk_Phase.l,d1.w) + cmp.b #1,d0 ;phase 2 high (track!) + beq IncTk + cmp.b #3,d0 + beq DecTk + rts + +HW_C0E7 move.w disk_DriveW,d1 + move.b #3,(disk_Phase.l,d1.w) ;phase 3 high (half track) + rts + +IncTk move.w disk_DriveW,d1 + addq.b #1,(disk_Track.l,d1.w) ;Increment Track! + cmp.b #34,(disk_Track.l,d1.w) + bls NewTk + move.b #34,(disk_Track.l,d1.w) + bra NewTk + +DecTk move.w disk_DriveW,d1 + subq.b #1,(disk_Track.l,d1.w) ;Decrement Track! + bpl NewTk + move.b #0,(disk_Track.l,d1.w) + +; VVV -fall through- VVV + +NewTk move.w disk_DriveW,d1 + moveq.l #0,d0 ;Adjusts ptrs after moving to new track... + move.b (disk_Track.l,d1.w),d0 + mulu.w #disk_TrackLen,d0 ;calc ptr to where track starts in memory + add.l (disk_Buffer.l,d1.w*4),d0 + move.l d0,disk_TkStrt + move.l #0,disk_TkPos ;reset track position/offset counter... + +PrintTk ;*** print trk num in title bar *** + move.w disk_DriveW,d1 + move.b (disk_Track.l,d1.w),d0 + + lsr.b #4,d0 ;convert Track to 2 hex digits... + add.b #'0',d0 + move.b d0,.Disk1Digits + move.b d0,.Disk2Digits + move.b (disk_Track.l,d1.w),d0 + and.b #$0f,d0 + add.b #'0',d0 + cmp.b #'9',d0 + bls .ok + add.b #'A'-'9'-1,d0 +.ok move.b d0,.Disk1Digits+1 + move.b d0,.Disk2Digits+1 + + move.l (.MsgPtr.l,d1.w*4),NewStatusMsgPtr + + rts + +.MsgPtr dc.l .Disk1Msg,.Disk2Msg + +.Disk1Msg dc.b " DRIVE ONE : TK $" +.Disk1Digits dc.b "00",0,10 + +.Disk2Msg dc.b " DRIVE TWO : TK $" +.Disk2Digits dc.b "00",0,10 + +; dc.b "1234567890123456789012345678901234567890" + CNOP 0,4 +HW_C0E8 move.b #0,disk_Motor ;turn drive off! + rts ;<-- no motor check currently for speed... + + +HW_C0E9 move.b #1,disk_Motor ;turn drive on! + tst.w disk_DriveW + beq PrintTk ;reprint StatusBar if drive #1 active... + tst.l disk_Buffer2 ;or if drive #2 present & active... + bne PrintTk ;no motor check currently for speed... + move.l #.NothingMsg,NewStatusMsgPtr + rts +.NothingMsg dc.b 0,1 ;empty message, 1 tick duration (blank) + +HW_C0EA move.w #0,disk_DriveW ;drive 1 selected + + lea HardwareReadTbl,a0 ;enable full drive function by patching + move.l #HW_C0E1,$e1*4(a0) ;in routines that might have been disabled + move.l #HW_C0E3,$e3*4(a0) + move.l #HW_C0E5,$e5*4(a0) + move.l #HW_C0E7,$e7*4(a0) + move.l #HW_C0EC,$ec*4(a0) + + lea HardwareWriteTbl,a0 + move.l #HW_C0E1,$e1*4(a0) + move.l #HW_C0E3,$e3*4(a0) + move.l #HW_C0E5,$e5*4(a0) + move.l #HW_C0E7,$e7*4(a0) + move.l #HW_C0EC,$ec*4(a0) + bra NewTk ;reset track pointers for this drive... + rts + +HW_C0EB tst.l disk_Buffer2 ;is there a 2nd drive buffer enabled? + beq.b .NoDrv + move.w #1,disk_DriveW ;drive 2 selected + bra NewTk ;reset track pointers for this drive... + rts + +.NoDrv lea HardwareReadTbl,a0 ;Only 1 drive system, so when #2 selected, + moveq.l #0,d0 ;disable mechanical drive functions! + move.l d0,$e1*4(a0) + move.l d0,$e3*4(a0) + move.l d0,$e5*4(a0) + move.l d0,$e7*4(a0) + move.l #HW_C0EC_DrvOff,$ec*4(a0) + + lea HardwareWriteTbl,a0 + move.l d0,$e1*4(a0) + move.l d0,$e3*4(a0) + move.l d0,$e5*4(a0) + move.l d0,$e7*4(a0) + move.l #HW_C0EC_DrvOff,$ec*4(a0) + rts + + +HW_C0EC move.b #0,disk_Q6 ;q6 = low; READ / WRITE Latch! + + tst.b disk_Q7 + bne.b .write ;if q7=hi then go write latch to disk +.read move.l disk_TkStrt,a0 ;else read + move.l disk_TkPos,d1 + move.b (a0,d1.w),d0 ;get data + bset #7,d0 ;force disk data hi-bit high + addq.w #1,d1 + cmp.w #disk_TrackLen,d1 ;within length of track? + bhs.b .Rept + move.l d1,disk_TkPos + rts +.Rept move.l #0,disk_TkPos + rts +;.noZero move.b #$ff,d0 +; bra.b .ok + +.write move.l disk_TkStrt,a0 + move.l disk_TkPos,d1 + move.b disk_Latch,(a0,d1.w) ;write data + addq.w #1,d1 + cmp.w #disk_TrackLen,d1 ;within length of track? + blo.b .NoRep2 + move.w #0,d1 +.NoRep2 move.l d1,disk_TkPos + move.w disk_DriveW,d1 ;and mark drive as being changed + move.b #1,(disk_Changed.l,d1.w) + rts + + +HW_C0EC_DrvOff: + move.b #0,disk_Q6 ;q6 = low; return $ff while drive is off + move.b #$ff,d0 + rts + + +HWr_C0ED move.b #1,disk_Q6 ;on read, q6 = Hi + rts + + +HWw_C0ED move.b #1,disk_Q6 ;on write, q6 = Hi ; load latch + move.b d1,disk_Latch + rts + + +HW_C0EE move.b #0,disk_Q7 ; q7 = lo + tst.b disk_Q6 ; if q6=1 then return Write Prot Status + bne .WPstat + rts +.WPstat move.b #0,d0 ;return -1 for WP'ed disk + rts + + +HW_C0EF move.b #1,disk_Q7 ; q7 = hi + rts + +*************************************************************************************** +* Video handling... Hardware switches, mode checking, redundancy elimination, etc... +* + CNOP 0,4 +HW_C050 bclr.b #0,VidMode ;GRAPHICS! (vs text) + bne ChkVid ;if this video flag already set, do nothing... + bra ProgressiveRetVal + + CNOP 0,4 +HW_C051 bset.b #0,VidMode ;TEXT! (vs graphics) + beq ChkVid + bra ProgressiveRetVal + + CNOP 0,4 +HW_C052 bclr.b #1,VidMode ;FULL SCRN GRFX (vs mixed text) + bne ChkVid + bra ProgressiveRetVal + + CNOP 0,4 +HW_C053 bset.b #1,VidMode ;MIXED GRFX/TXT (vs full scrn) + beq ChkVid + bra ProgressiveRetVal + + CNOP 0,4 +HW_C054 bclr.b #2,VidMode ;PAGE 1 (vs 2) + bne ChkVid + bra ProgressiveRetVal + + CNOP 0,4 +HW_C055 bset.b #2,VidMode ;PAGE 2 (vs 1) + beq ChkVid + bra ProgressiveRetVal + + CNOP 0,4 +HW_C056 bclr.b #3,VidMode ;LORES (vs Hires) + bne ChkVid + bra ProgressiveRetVal + + CNOP 0,4 +HW_C057 bset.b #3,VidMode ;HIRES (vs Lores) + beq ChkVid + bra ProgressiveRetVal + + CNOP 0,4 +*--------------------------------------------------------------------------------* +* ChkVid - Called after any of the video modes have been changed. This routine +* first checks to see if the next instruction will change another video +* attribute, and if so, does nothing. +* Otherwise, it examines "VidMode" and sets pointers to the proper BPlanes, +* refreshes if necessary, and remakes the display. +* CALL ONLY from 6502 CPU context! + +ChkVid move.l -1(PCount),d0 ;1st check if next inst changes video also... + cmp.b #$c0,d0 + bne.b .chgVid + lsr.l #8,d0 + cmp.b #$50,d0 + blo.b .chgVid + cmp.b #$57,d0 + bhi.b .chgVid ;at this point, its $c050 - $c057, now check inst + + lsr.l #8,d0 + cmp.b #$2c,d0 ;bit $xxxx +; beq .done + cmp.b #$ad,d0 ;lda $xxxx +; beq .done + cmp.b #$8d,d0 ;sta $xxxx +; beq .done ;any .done match means return, & do video on next inst + +.chgVid + clr.w d0 + move.b VidMode,d0 + jmp ([VideoDispatchTbl.l,d0.w*4]) + +.done rts + +VideoDispatchTbl + dc.l SetGr1,SetTxt1,SetGrTxt1,SetTxt1 + dc.l SetGr2,SetTxt2,SetGrTxt2,SetTxt2 + dc.l SetHgr1,SetTxt1,SetHgrTxt1,SetTxt1 + dc.l SetHgr2,SetTxt2,SetHgrTxt2,SetTxt2 + +SetTxt1: + move.l #0,d0 + CALLINT LockIBase + move.l d0,IBaseLock + + move.l MyScreen,a1 ;SET BITMAP fields... + lea sc_BitMap(a1),a1 ;a1 -> Screen.BitMap + move.b #2,bm_Depth(a1) + move.l Gr1_Planes,a0 + move.l a0,bm_Planes(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+4(a1) + + move.l IBaseLock,a0 + CALLINT UnlockIBase + + move.l #PBTxt1,PBPageList+16 + move.l #PBTxt1,PBPageList+20 + move.l #PBTxt1,PBPageList+24 + move.l #PBTxt1,PBPageList+28 + + jsr RefreshTxt1 + + move.b #1,FlashEnableB + + lea TxtColorTable,a1 ;a1 -> MyColorTable for this mode... + + bra SetDone + + +SetGr1: + move.l #0,d0 + CALLINT LockIBase + move.l d0,IBaseLock + + move.l MyScreen,a1 ;SET BITMAP fields... + lea sc_BitMap(a1),a1 ;a1 -> Screen.BitMap + move.b #5,bm_Depth(a1) + move.l Gr1_Planes,a0 + move.l a0,bm_Planes(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+4(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+8(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+12(a1) + move.l BackDrop_Plane,a0 ;5th bplane! (choose text/gr colors) + move.l a0,bm_Planes+16(a1) + + jsr SetBackDropToGrfx + + move.l IBaseLock,a0 + CALLINT UnlockIBase + + move.l #PBGr1,PBPageList+16 + move.l #PBGr1,PBPageList+20 + move.l #PBGr1,PBPageList+24 + move.l #PBGr1,PBPageList+28 + + jsr RefreshTxt1 + + move.b #0,FlashEnableB + + lea GrColorTable,a1 ;a1 -> MyColorTable for this mode... + + bra SetDone + +SetGrTxt1: + move.l #0,d0 + CALLINT LockIBase + move.l d0,IBaseLock + + move.l MyScreen,a1 ;SET BITMAP fields... + lea sc_BitMap(a1),a1 ;a1 -> Screen.BitMap + move.b #5,bm_Depth(a1) + move.l Gr1_Planes,a0 + move.l a0,bm_Planes(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+4(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+8(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+12(a1) + move.l BackDrop_Plane,a0 ;5th bplane! (choose text/gr colors) + move.l a0,bm_Planes+16(a1) + + jsr SetBackDropToText + + move.l IBaseLock,a0 + CALLINT UnlockIBase + + move.l #PBGrTxt1,PBPageList+16 + move.l #PBGrTxt1,PBPageList+20 + move.l #PBGrTxt1,PBPageList+24 + move.l #PBGrTxt1,PBPageList+28 + + jsr ClearXtraPlanesTxt1 + jsr RefreshTxt1 + + move.b #1,FlashEnableB + + lea GrColorTable,a1 + + bra SetDone + +SetTxt2: + move.l #0,d0 + CALLINT LockIBase + move.l d0,IBaseLock + + move.l MyScreen,a1 ;SET BITMAP fields... + lea sc_BitMap(a1),a1 ;a1 -> Screen.BitMap + move.b #2,bm_Depth(a1) + move.l Gr2_Planes,a0 + move.l a0,bm_Planes(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+4(a1) + + move.l IBaseLock,a0 + CALLINT UnlockIBase + + move.l #PBTxt2,PBPageList+32 + move.l #PBTxt2,PBPageList+36 + move.l #PBTxt2,PBPageList+40 + move.l #PBTxt2,PBPageList+44 + + jsr ClearXtraPlanesTxt2 + jsr RefreshTxt2 + + move.b #1,FlashEnableB + + lea TxtColorTable,a1 + + bra SetDone + + +SetGr2: + move.l #0,d0 + CALLINT LockIBase + move.l d0,IBaseLock + + move.l MyScreen,a1 ;SET BITMAP fields... + lea sc_BitMap(a1),a1 ;a1 -> Screen.BitMap + move.b #5,bm_Depth(a1) + move.l Gr2_Planes,a0 + move.l a0,bm_Planes(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+4(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+8(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+12(a1) + move.l BackDrop_Plane,a0 ;5th bplane! (choose text/gr colors) + move.l a0,bm_Planes+16(a1) + + jsr SetBackDropToGrfx + + + move.l IBaseLock,a0 + CALLINT UnlockIBase + + move.l #PBGr2,PBPageList+32 + move.l #PBGr2,PBPageList+36 + move.l #PBGr2,PBPageList+40 + move.l #PBGr2,PBPageList+44 + + jsr RefreshTxt2 + + move.b #0,FlashEnableB + + lea GrColorTable,a1 + + bra SetDone + +SetGrTxt2: + move.l #0,d0 + CALLINT LockIBase + move.l d0,IBaseLock + + move.l MyScreen,a1 ;SET BITMAP fields... + lea sc_BitMap(a1),a1 ;a1 -> Screen.BitMap + move.b #5,bm_Depth(a1) + move.l Gr2_Planes,a0 + move.l a0,bm_Planes(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+4(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+8(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+12(a1) + move.l BackDrop_Plane,a0 ;5th bplane! (choose text/gr colors) + move.l a0,bm_Planes+16(a1) + + jsr SetBackDropToText + + move.l IBaseLock,a0 + CALLINT UnlockIBase + + move.l #PBGrTxt2,PBPageList+32 + move.l #PBGrTxt2,PBPageList+36 + move.l #PBGrTxt2,PBPageList+40 + move.l #PBGrTxt2,PBPageList+44 + + jsr ClearXtraPlanesTxt2 + jsr RefreshTxt2 + + move.b #1,FlashEnableB + + lea GrColorTable,a1 + + bra SetDone + +SetHgr1: + move.l #0,d0 + CALLINT LockIBase + move.l d0,IBaseLock + + move.l MyScreen,a1 ;SET BITMAP fields... + lea sc_BitMap(a1),a1 ;a1 -> Screen.BitMap + move.b #4,bm_Depth(a1) + move.l Hgr1_Planes,a0 + move.l a0,bm_Planes(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+4(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+8(a1) + move.l BackDrop_Plane,a0 ;4th bplane! (choose text/gr colors) + move.l a0,bm_Planes+12(a1) + + jsr SetBackDropToGrfx + + move.l IBaseLock,a0 + CALLINT UnlockIBase + + moveq.l #0,d0 + move.l d0,PBPageList+16 ;ignore txt1 page... + move.l d0,PBPageList+20 + move.l d0,PBPageList+24 + move.l d0,PBPageList+28 + + move.l d0,PBPageList+32 ;and ignore txt2... + move.l d0,PBPageList+36 + move.l d0,PBPageList+40 + move.l d0,PBPageList+44 + + cmp.l #PBHgr1,PBPageList+$20*4 ;already doing full-scrn hgr1 + beq .SkpChg + + move.l #PBHgr1,d0 + move.l #PBPageList+$20*4,a0 + jsr InstallHgrServer + + jsr RefreshHgr1 + +.SkpChg + move.b #0,FlashEnableB + + lea HiResColorTable,a1 + + bra SetDone + +SetHgrTxt1: + move.l #0,d0 + CALLINT LockIBase + move.l d0,IBaseLock + + move.l MyScreen,a1 ;SET BITMAP fields... + lea sc_BitMap(a1),a1 ;a1 -> Screen.BitMap + move.b #4,bm_Depth(a1) + move.l Hgr1_Planes,a0 + move.l a0,bm_Planes(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+4(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+8(a1) + move.l BackDrop_Plane,a0 ;4th bplane! (choose text/gr colors) + move.l a0,bm_Planes+12(a1) + + jsr SetBackDropToText + + move.l IBaseLock,a0 + CALLINT UnlockIBase + + move.l #PBHgrTxt1,PBPageList+16 + move.l #PBHgrTxt1,PBPageList+20 + move.l #PBHgrTxt1,PBPageList+24 + move.l #PBHgrTxt1,PBPageList+28 + + cmp.l #PBHgr1Top,PBPageList+$20*4 + beq .SkpChg ;already doing mixed-scrn hgr1 + + move.l #PBHgr1Top,d0 + move.l #PBPageList+$20*4,a0 + jsr InstallHgrServer + + jsr RefreshHgr1 + +.SkpChg jsr RefreshTxt1 + + move.b #1,FlashEnableB + + lea HiResColorTable,a1 + + bra SetDone + + +SetHgr2: + move.l #0,d0 + CALLINT LockIBase + move.l d0,IBaseLock + + move.l MyScreen,a1 ;SET BITMAP fields... + lea sc_BitMap(a1),a1 ;a1 -> Screen.BitMap + move.b #4,bm_Depth(a1) + move.l Hgr2_Planes,a0 + move.l a0,bm_Planes(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+4(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+8(a1) + move.l BackDrop_Plane,a0 ;4th bplane! (choose text/gr colors) + move.l a0,bm_Planes+12(a1) + + jsr SetBackDropToGrfx + + move.l IBaseLock,a0 + CALLINT UnlockIBase + + moveq.l #0,d0 + move.l d0,PBPageList+16 ;ignore txt1 page... + move.l d0,PBPageList+20 + move.l d0,PBPageList+24 + move.l d0,PBPageList+28 + + move.l d0,PBPageList+32 ;and ignore txt2... + move.l d0,PBPageList+36 + move.l d0,PBPageList+40 + move.l d0,PBPageList+44 + + cmp.l #PBHgr2,PBPageList+$40*4 + beq .SkpChg ;already doing full-scrn hgr2 + + move.l #PBHgr2,d0 + move.l #PBPageList+$40*4,a0 + jsr InstallHgrServer + + jsr RefreshHgr2 + +.SkpChg + move.b #0,FlashEnableB + + lea HiResColorTable,a1 + + bra SetDone + + + +SetHgrTxt2: + move.l #0,d0 + CALLINT LockIBase + move.l d0,IBaseLock + + move.l MyScreen,a1 ;SET BITMAP fields... + lea sc_BitMap(a1),a1 ;a1 -> Screen.BitMap + move.b #4,bm_Depth(a1) + move.l Hgr2_Planes,a0 + move.l a0,bm_Planes(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+4(a1) + add.l #LINES*40,a0 + move.l a0,bm_Planes+8(a1) + move.l BackDrop_Plane,a0 ;4th bplane! (choose text/gr colors) + move.l a0,bm_Planes+12(a1) + + jsr SetBackDropToText + + move.l IBaseLock,a0 + CALLINT UnlockIBase + + move.l #PBHgrTxt2,PBPageList+32 + move.l #PBHgrTxt2,PBPageList+36 + move.l #PBHgrTxt2,PBPageList+40 + move.l #PBHgrTxt2,PBPageList+44 + + cmp.l #PBHgr2Top,PBPageList+$40*4 + beq .SkpChg ;already doing mixed-scrn hgr2 + + move.l #PBHgr2Top,d0 + move.l #PBPageList+$40*4,a0 + jsr InstallHgrServer + + jsr RefreshHgr2 + +.SkpChg jsr RefreshTxt2 + + move.b #1,FlashEnableB + + lea HiResColorTable,a1 + + bra SetDone + +;-------------------- + +InstallHgrServer: ;Plugs in server for either Hi-res memory dispatchs + ;Enter: d0 = Addr of HiRes server + ; a0-> Base of server table (PBPageList+$20*4 or +$40*4) + move.w #$20-1,d1 +.lp move.l d0,(a0)+ + dbf d1,.lp + rts + +;-------------------- + +SetDone: ;enter w/ a1 -> MyColorTable + move.l Cycles,d1 + sub.l LastVideoCycle,d1 ;skip if we are in a "page flipping" rtn + move.l Cycles,LastVideoCycle + cmp.l #5680,d1 ;1/3 the cycles in a single frame... + blo .TooSoon ;(LATER check if more than 3 changes happen 1st) + +.DoIt clr.l DoVideoFlag ;enter w/ a1 -> MyColorTable + cmp.l LastColorTable,a1 + beq.b .same + + +.ChgCol move.l a1,-(sp) + + move.l #0,d0 + CALLINT LockIBase + move.l d0,IBaseLock + + move.l MyScreen,a0 + CALLINT MakeScreen ;Rebuild local VPort copper list + CALLINT RethinkDisplay ;Rebuild Display + + move.l MyScreen,a0 ;Set Colors... (IF NEEDED!) + move.l (sp)+,a1 + move.l a1,LastColorTable + lea sc_ViewPort(a0),a0 ;a0 -> Screen ViewPort + move.w (a1)+,d0 ;d0 = # of colors, a1 -> ColorList + CALLGRAF LoadRGB4 ;(takes effect immed, but doesn't ReThink display) + ;(not very fast either) + move.l IBaseLock,a0 + CALLINT UnlockIBase + + bra.b ProgressiveRetVal + + ;enter w/ a1 -> MyColorTable +.same + move.l #0,d0 + CALLINT LockIBase + move.l d0,IBaseLock + + move.l MyScreen,a0 ;Rebuild local VPort copper list + CALLINT MakeScreen + CALLINT RethinkDisplay ;and Rebuild Display + + move.l IBaseLock,a0 + CALLINT UnlockIBase + + bra.b ProgressiveRetVal + +.TooSoon ;enter w/ a1 -> MyColorTable + move.l a1,DoVideoFlag ;do nothing now, Main routine will change it soon... + +ProgressiveRetVal: ;return the next value from a list, because + ;some games expect certain values in HW locations. + + move.l .ListPtr,a0 + move.b (a0)+,d0 + bne.b .ok + lea .List,a0 +.ok move.l a0,.ListPtr + rts + +.ListPtr dc.l .List ; (Drol Anim wants 4 x $80) +.List dc.b $20,$20,$20,$20,$80,$80,$80,$80,$ff,$ff,$ff,$ff,$81,$81,$00 + + + +;-------------------- + CNOP 0,4 + +DoVideoFlag dc.l 0 +LastVideoCycle dc.l 0 +IBaseLock dc.l 0 +LastColorTable dc.l 0 + EVEN + +;-------------------- + +RefreshVideo: ;----- "refreshes" all video related ram ----- + ; not performance critical (after using screen) + move.l d2,-(sp) + bsr ChkVid + move.l #$400,d2 ; (only call from 6502 context) +.lp move.l d2,d0 + move.b (Mem_Ptr,d0.l),d1 ;FGETBYTE + addq.b #$1,(Mem_Ptr,d0.l) ;must change mem so Hi-res routines re-draw... + PUTBYTE + + addq.l #1,d2 + cmp.l #$6000,d2 + blo .lp + move.l (sp)+,d2 + rts + +;-------------------- + +RefreshTxt1: +.rfrsh move.l d2,-(sp) ;Refresh video ram $400 -> $7ff only + move.l #$400,d2 +.lp move.l d2,d0 + move.b (Mem_Ptr,d0.l),d1 + addq.b #$1,(Mem_Ptr,d0.l) + PUTBYTE + addq.l #1,d2 + cmp.w #$800,d2 + blo .lp + move.l (sp)+,d2 + rts + + +ClearXtraPlanesTxt1: + move.l Gr1_Planes,a0 + add.l #LINES*40*2+160*40,a0 ;a0 ->3 Bplane line #160 + moveq.l #$0,d0 + move.w #32*40/4-1,d1 ;clear 32 lines in text window... +.fill move.l d0,LINES*40(a0) ;bplanes 3 & 4 + move.l d0,(a0)+ + dbf d1,.fill + rts + +;-------------------- + +RefreshTxt2: +.rfrsh move.l d2,-(sp) ;Refresh video ram $800 -> $bff + move.l #$800,d2 +.lp move.l d2,d0 + move.b (Mem_Ptr,d0.l),d1 + addq.b #$1,(Mem_Ptr,d0.l) + PUTBYTE + addq.l #1,d2 + cmp.w #$c00,d2 + blo.b .lp + move.l (sp)+,d2 + rts + + +ClearXtraPlanesTxt2: + move.l Gr2_Planes,a0 + add.l #LINES*40*2+160*40,a0 ;a0 ->3 Bplane line #160 + moveq.l #$0,d0 + move.w #32*40/4-1,d1 ;clear 32 lines in text window... +.fill move.l d0,LINES*40(a0) ;bplanes 3 & 4 + move.l d0,(a0)+ + dbf d1,.fill + rts + +;-------------------- + +RefreshHgr1: ;clear txt at edges / hi-res bplns... +.clearXtraPlanes: + move.l Hgr1_Planes,a0 + add.l #160*40,a0 ;a0 ->Bplane1 line #160 + moveq.l #$0,d0 + move.w #32*40/4-1,d1 ;clear 32 lines in text window... +.fill move.l d0,LINES*40*2(a0) ;bplanes 3 + move.l d0,LINES*40(a0) ; 2 + move.l d0,(a0)+ ; 1 + dbf d1,.fill + + +.Hgr1RefreshBottom: + movem.l a2-a4/d2-d7,-(sp) + move.l HiResDrawTbl,a1 ;a1 -> HiRes Draw Table (Preserve!) + +* Step through all the HGR line addresses... + + move.l #$2250,a3 ;a3 = main base counter... + move.l a3,a2 ;a2 -> Base of HGR line we are doing (preserve!) + +.loop move.l #40-1,d2 +1$ move.l a2,d0 ;address + add.l d2,d0 + move.b (Mem_Ptr,d0.l),d1 ;FGETBYTE + addq.b #$1,(Mem_Ptr,d0.l) ;must change mem so Hi-res routines re-draw... + PUTBYTE + dbf d2,1$ + +.done + add.w #$400,a2 ;$2000 -> $2400 -> ... -> $3800 (each line in grp of 8) + cmp.w #$4000,a2 + blo .loop + sub.w #$2000-$80,a2 + cmp.w #$2400,a2 ;$2000 -> $2080 -> $2100 -> $2180 -> ... -> $2380 + blo .loop + + add.w #$28,a3 ;from $2000 -> $2028 -> $2050 + move.w a3,a2 + cmp.w #$2050,a3 + bls .loop + + movem.l (sp)+,a2-a4/d2-d7 + rts + +;-------------------- + +RefreshHgr2: +.clearXtraplanes: + move.l Hgr2_Planes,a0 + add.l #160*40,a0 ;a0 ->Bplane1 line #160 + moveq.l #$0,d0 + move.w #32*40/4-1,d1 ;clear 32 lines in text window... +.fill move.l d0,LINES*40*2(a0) ;bplanes 3 + move.l d0,LINES*40(a0) ; 2 + move.l d0,(a0)+ ; 1 + dbf d1,.fill + +.Hgr2RefreshBottom: + movem.l a2-a4/d2-d7,-(sp) + move.l HiResDrawTbl,a1 ;a1 -> HiRes Draw Table (Preserve!) + + ;Step through all the HGR line addresses... + move.l #$4250,a3 ;a3 = main base counter... + move.l a3,a2 ;a2 -> Base of HGR line we are doing (preserve!) + +.loop move.l #40-1,d2 +1$ move.l a2,d0 ;address + add.l d2,d0 + move.b (Mem_Ptr,d0.l),d1 ;FGETBYTE + addq.b #$1,(Mem_Ptr,d0.l) ;must change mem so Hi-res routines re-draw... + PUTBYTE + dbf d2,1$ + +.done add.w #$400,a2 ;$4000 -> $4400 -> ... -> $5800 (each line in grp of 8) + cmp.w #$6000,a2 + blo .loop + sub.w #$2000-$80,a2 + cmp.w #$4400,a2 ;$4000 -> $4080 -> $4100 -> $4180 -> ... -> $2380 + blo .loop + + add.w #$28,a3 ;from $4000 -> $4028 -> $4050 + move.w a3,a2 + cmp.w #$4050,a3 + bls .loop + + movem.l (sp)+,a2-a4/d2-d7 + rts + +;-------------------- + +SetBackDropToText: + move.l BackDrop_Plane,a0 ;and completely fill it! + add.l #160*40,a0 ;a0 -> Bplane line #160 + tst.b (a0) + beq.b .done ;if already in mode, then return + + moveq.l #$0,d0 + move.w #32*40/4-1,d1 ;change 32 lines in text window... +.fill move.l d0,(a0)+ + dbf d1,.fill +.done rts + +SetBackDropToGrfx: + move.l BackDrop_Plane,a0 ;and completely fill it! + add.l #160*40,a0 ;a0 -> Bplane line #160 + tst.b (a0) + bne.b .done ;if already in mode, then return + + move.l #$ffffffff,d0 + move.w #32*40/4-1,d1 ;change 32 lines in text window... +.fill move.l d0,(a0)+ + dbf d1,.fill +.done rts + +************************************************************************ + + SECTION TABLES,DATA + CNOP 0,4 + +;BPlaneTbl1 dc.l Gr1_Planes,Txt1_Plane1ND,Gr1_Planes,Txt1_Plane1ND +; dc.l Gr2_Planes,Txt2_Planes,Gr2_Planes,Txt2_Planes +; dc.l Hgr1_Planes,Txt1_Plane1ND,Hgr1_Planes,Txt1_Plane1ND +; dc.l Hgr2_Planes,Txt2_Planes,Hgr2_Planes,Txt2_Planes + +;BPlaneTbl2 dc.l 0,Txt1_Plane2ND,0,Txt1_Plane2ND +; dc.l 0,0,0,0 +; dc.l 0,Txt1_Plane2ND,0,Txt1_Plane2ND +; dc.l 0,0,0,0 + +ModeColorTbl dc.l GrColorTable,TxtColorTable,GrColorTable,TxtColorTable + dc.l GrColorTable,TxtColorTable,GrColorTable,TxtColorTable + dc.l HiResColorTable,TxtColorTable,HiResColorTable,TxtColorTable + dc.l HiResColorTable,TxtColorTable,HiResColorTable,TxtColorTable + +************************************************************************ + +Variables +VidMode ds.b 1 ;bits showing apple video mode! + + CNOP 0,4 +InstJmpTblBkUp + dc.l UND00,STA81,UND00,UND00,STY84,STA85,STX86,UND00 + dc.l DEY88,UND00,TXA8A,UND00,STY8C,STA8D,STX8E,UND00 + dc.l BCC90,STA91,UND00,UND00,STY94,STA95,STX96,UND00 + dc.l TYA98,STA99,TXS9A,UND00,UND00,STA9D,UND00,UND00 + dc.l LDYA0,LDAA1,LDXA2,UND00,LDYA4,LDAA5,LDXA6,UND00 + dc.l TAYA8,LDAA9,TAXAA,UND00,LDYAC,LDAAD,LDXAE,UND00 + dc.l BCSB0,LDAB1,UND00,UND00,LDYB4,LDAB5,LDXB6,UND00 + dc.l CLVB8,LDAB9,TSXBA,UND00,LDYBC,LDABD,LDXBE,UND00 + dc.l CPYC0,CMPC1,UND00,UND00,CPYC4,CMPC5,DECC6,UND00 + dc.l INYC8,CMPC9,DEXCA,UND00,CPYCC,CMPCD,DECCE,UND00 + dc.l BNED0Reg,CMPD1,UND00,UND00,UND00,CMPD5,DECD6,UND00 + dc.l CLDD8,CMPD9,UND00,UND00,UND00,CMPDD,DECDE,UND00 + dc.l CPXE0,SBCE1,UND00,UND00,CPXE4,SBCE5,INCE6,UND00 + dc.l INXE8,SBCE9,NOPEA,UND00,CPXEC,SBCED,INCEE,UND00 + dc.l BEQF0Reg,SBCF1,UND00,UND00,UND00,SBCF5,INCF6,UND00 + dc.l SEDF8,SBCF9,UND00,UND00,UND00,SBCFD,INCFE,UND00 + + dc.l BRK00,ORA01,UND00,UND00,UND00,ORA05,ASL06,UND00 + dc.l PHP08,ORA09,ASL0A,UND00,UND00,ORA0D,ASL0E,UND00 + dc.l BPL10Reg,ORA11,UND00,UND00,UND00,ORA15,ASL16,UND00 + dc.l CLC18,ORA19,UND00,UND00,UND00,ORA1D,ASL1E,UND00 + dc.l JSR20,AND21,UND00,UND00,BIT24,AND25,ROL26,UND00 + dc.l PLP28,AND29,ROL2A,UND00,BIT2C,AND2D,ROL2E,UND00 + dc.l BMI30Reg,AND31,UND00,UND00,UND00,AND35,ROL36,UND00 + dc.l SEC38,AND39,UND00,UND00,UND00,AND3D,ROL3E,UND00 + dc.l RTI40,EOR41,UND00,UND00,UND00,EOR45,LSR46,UND00 + dc.l PHA48,EOR49,LSR4A,UND00,JMP4CReg,EOR4D,LSR4E,UND00 + dc.l BVC50,EOR51,UND00,UND00,UND00,EOR55,LSR56,UND00 + dc.l CLI58,EOR59,UND00,UND00,UND00,EOR5D,LSR5E,UND00 + dc.l RTS60,ADC61,UND00,UND00,UND00,ADC65,ROR66,UND00 + dc.l PLA68,ADC69,ROR6A,UND00,JMP6C,ADC6D,ROR6E,UND00 + dc.l BVS70,ADC71,UND00,UND00,UND00,ADC75,ROR76,UND00 + dc.l SEI78,ADC79,UND00,UND00,UND00,ADC7D,ROR7E,UND00 ;end of POSitives... + dc.l 0,0,0,0 + +PBPageList: ;$00-$bf - nothing; $c0-$cf hardware; $d0-$ff rom... + dc.l 00,00,00,00 ;$00-$03 - nothing + dc.l PBTxt1,PBTxt1,PBTxt1,PBTxt1 ;$04-$07 - Text1 + dc.l PBTxt2,PBTxt2,PBTxt2,PBTxt2 ;$08-$0b - Text2 + dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;$0c-$1f - nothing + dc.l PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1 + dc.l PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1 + dc.l PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1 + dc.l PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1,PBHgr1 ;$20-$3f - HGR1 +; dc.l PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick +; dc.l PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick +; dc.l PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick +; dc.l PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick,PBHgr1Quick ;$20-$3f - HGR1; + dc.l PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2 + dc.l PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2 + dc.l PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2 + dc.l PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2,PBHgr2 ;$40-$5f - HGR2 +; dc.l PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick +; dc.l PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick +; dc.l PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick +; dc.l PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick,PBHgr2Quick ;$20-$3f - HGR1 + dcb.l $60,0 ;$60-$BF nothing! + dc.l PBHardWare + dc.l 00,PBSlot,00,PBSlot,PBSlot,PBSlot,PBSlot + dc.l PBSlot,PBSlot,PBSlot,PBSlot,PBSlot,PBSlot,PBSlot,PBSlot ;$c1-$cf - SLOTS + dc.l PBBank2,PBBank2,PBBank2,PBBank2,PBBank2,PBBank2,PBBank2,PBBank2 + dc.l PBBank2,PBBank2,PBBank2,PBBank2,PBBank2,PBBank2,PBBank2,PBBank2 + dc.l PBBank,PBBank,PBBank,PBBank,PBBank,PBBank,PBBank,PBBank + dc.l PBBank,PBBank,PBBank,PBBank,PBBank,PBBank,PBBank,PBBank + dc.l PBBank,PBBank,PBBank,PBBank,PBBank,PBBank,PBBank,PBBank + dc.l PBBank,PBBank,PBBank,PBBank,PBBank,PBBank,PBBank,PBBank + dc.b ~'K',~'E',~'V',~'I',~'N',~'K',~'R',~'A',~'L',~'I',~'A',~'N' + + CNOP 0,4 + + +FreshBootMemory: ;a snapshot of low mem upon a clean power-up of Apple II + ;Zero Page + dc.b $4C,$3C,$D4,$4C,$3A,$DB,$00,$00,$00,$00,$4C,$99,$E1,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$28,$00,$18,$01,$17,$00,$08,$D0,$07,$D0,$07,$00,$00,$00,$00 + dc.b $00,$00,$FF,$DD,$00,$D4,$F0,$FD,$1B,$FD,$00,$00,$7F,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$38,$B6 + dc.b $00,$C2,$55,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$01,$08,$03,$08,$03,$08,$03,$08,$00 + dc.b $C0,$00,$00,$00,$C0,$00,$FF,$00,$00,$00,$00,$00,$00,$00,$08,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$03 + dc.b $4C,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$03 + dc.b $08,$E6,$B8,$D0,$02,$E6,$B9,$AD,$00,$08,$C9,$3A,$B0,$0A,$C9,$20 + dc.b $F0,$EF,$38,$E9,$30,$38,$E9,$D0,$60,$80,$4F,$C7,$52,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + + ;Page 1 (stack), page 2 (keybuffer) + dcb.b $100,0 + dcb.b $100,0 + + ;Page 3 (some system vectors) + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$00,$00 + dc.b $02,$03,$00,$04,$05,$06,$00,$00,$00,$00,$00,$00,$07,$08,$00,$00 + dc.b $00,$09,$0A,$0B,$0C,$0D,$00,$00,$0E,$0F,$10,$11,$12,$13,$00,$14 + dc.b $15,$16,$17,$18,$19,$1A,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$1B,$00,$1C,$1D,$1E,$00,$00,$00,$1F,$00,$00,$20,$21,$00,$22 + dc.b $23,$24,$25,$26,$27,$28,$00,$00,$00,$00,$00,$29,$2A,$2B,$00,$2C + dc.b $2D,$2E,$2F,$30,$31,$32,$00,$00,$33,$34,$35,$36,$37,$38,$00,$39 + dc.b $3A,$3B,$3C,$3D,$3E,$3F,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + dc.b $59,$FA,$03,$E0,$45,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + + ;Page 4,5,6,7 (text- all white space!) + dcb.b $400,$a0 + diff --git a/src/CharSets.s b/src/CharSets.s new file mode 100644 index 0000000..d5e17a0 --- /dev/null +++ b/src/CharSets.s @@ -0,0 +1,922 @@ +*** This file contains charset data, for both the Apple text display and also +*** for the "Status bar" display at the bottom of the screen. + + SECTION TABLES,DATA + + CNOP 0,4 +IIeCharSet: + dc.b $c7,$bb,$ab,$a3,$a7,$bf,$c3,$ff ;@ INVERSE + dc.b $ef,$d7,$bb,$bb,$83,$bb,$bb,$ff ;A + dc.b $87,$bb,$bb,$87,$bb,$bb,$87,$ff ;B + dc.b $c7,$bb,$bf,$bf,$bf,$bb,$c7,$ff ;C + dc.b $87,$bb,$bb,$bb,$bb,$bb,$87,$ff ;D + dc.b $83,$bf,$bf,$87,$bf,$bf,$83,$ff ;E + dc.b $83,$bf,$bf,$87,$bf,$bf,$bf,$ff ;F + dc.b $c3,$bf,$bf,$bf,$b3,$bb,$c3,$ff ;G + dc.b $bb,$bb,$bb,$83,$bb,$bb,$bb,$ff ;H + dc.b $c7,$ef,$ef,$ef,$ef,$ef,$c7,$ff ;I + dc.b $fb,$fb,$fb,$fb,$fb,$bb,$c7,$ff ;J + dc.b $bb,$b7,$af,$9f,$af,$b7,$bb,$ff ;K + dc.b $bf,$bf,$bf,$bf,$bf,$bf,$83,$ff ;L + dc.b $bb,$93,$ab,$ab,$bb,$bb,$bb,$ff ;M + dc.b $bb,$bb,$9b,$ab,$b3,$bb,$bb,$ff ;N + dc.b $c7,$bb,$bb,$bb,$bb,$bb,$c7,$ff ;O + dc.b $87,$bb,$bb,$87,$bf,$bf,$bf,$ff ;P + dc.b $c7,$bb,$bb,$bb,$ab,$b7,$cb,$ff ;Q + dc.b $87,$bb,$bb,$87,$af,$b7,$bb,$ff ;R + dc.b $c7,$bb,$bf,$c7,$fb,$bb,$c7,$ff ;S + dc.b $83,$ef,$ef,$ef,$ef,$ef,$ef,$ff ;T + dc.b $bb,$bb,$bb,$bb,$bb,$bb,$c7,$ff ;U + dc.b $bb,$bb,$bb,$bb,$bb,$d7,$ef,$ff ;V + dc.b $bb,$bb,$bb,$ab,$ab,$93,$bb,$ff ;W + dc.b $bb,$bb,$d7,$ef,$d7,$bb,$bb,$ff ;X + dc.b $bb,$bb,$d7,$ef,$ef,$ef,$ef,$ff ;Y + dc.b $83,$fb,$f7,$ef,$df,$bf,$83,$ff ;Z + dc.b $83,$9f,$9f,$9f,$9f,$9f,$83,$ff ;[ + dc.b $ff,$bf,$df,$ef,$f7,$fb,$fd,$ff ;\ + dc.b $83,$f3,$f3,$f3,$f3,$f3,$83,$ff ;] + dc.b $ff,$ff,$ef,$d7,$bb,$ff,$ff,$ff ;^ + dc.b $ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 ;_ + dc.b $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff ; (space) + dc.b $ef,$ef,$ef,$ef,$ef,$ff,$ef,$ff ;! + dc.b $d7,$d7,$d7,$ff,$ff,$ff,$ff,$ff ;" + dc.b $d7,$d7,$83,$d7,$83,$d7,$d7,$ff ;# + dc.b $ef,$c3,$af,$c7,$eb,$87,$ef,$ff ;$ + dc.b $9f,$9b,$f7,$ef,$df,$b3,$f3,$ff ;% + dc.b $df,$af,$af,$df,$ab,$b7,$cb,$ff ;& + dc.b $ef,$ef,$ef,$ff,$ff,$ff,$ff,$ff ;' + dc.b $ef,$df,$bf,$bf,$bf,$df,$ef,$ff ;( + dc.b $ef,$f7,$fb,$fb,$fb,$f7,$ef,$ff ;) + dc.b $ef,$ab,$c7,$ef,$c7,$ab,$ef,$ff ;* + dc.b $ff,$ef,$ef,$83,$ef,$ef,$ff,$ff ;+ + dc.b $ff,$ff,$ff,$ff,$ef,$ef,$df,$ff ;, + dc.b $ff,$ff,$ff,$83,$ff,$ff,$ff,$ff ;- + dc.b $ff,$ff,$ff,$ff,$ff,$ff,$ef,$ff ;. + dc.b $ff,$fb,$f7,$ef,$df,$bf,$ff,$ff ;/ + dc.b $c7,$bb,$b3,$ab,$9b,$bb,$c7,$ff ;0 + dc.b $ef,$cf,$ef,$ef,$ef,$ef,$c7,$ff ;1 + dc.b $c7,$bb,$fb,$e7,$df,$bf,$83,$ff ;2 + dc.b $83,$fb,$f7,$e7,$fb,$bb,$c7,$ff ;3 + dc.b $f7,$e7,$d7,$b7,$83,$f7,$f7,$ff ;4 + dc.b $83,$bf,$87,$fb,$fb,$bb,$c7,$ff ;5 + dc.b $e3,$df,$bf,$87,$bb,$bb,$c7,$ff ;6 + dc.b $83,$fb,$f7,$ef,$df,$df,$df,$ff ;7 + dc.b $c7,$bb,$bb,$c7,$bb,$bb,$c7,$ff ;8 + dc.b $c7,$bb,$bb,$c3,$fb,$f7,$cf,$ff ;9 + dc.b $ff,$ff,$ef,$ff,$ef,$ff,$ff,$ff ;: + dc.b $ff,$ff,$ef,$ff,$ef,$ef,$df,$ff ;; + dc.b $f7,$ef,$df,$bf,$df,$ef,$f7,$ff ;< + dc.b $ff,$ff,$83,$ff,$83,$ff,$ff,$ff ;= + dc.b $df,$ef,$f7,$fb,$f7,$ef,$df,$ff ;> + dc.b $c7,$bb,$f7,$ef,$ef,$ff,$ef,$ff ;? + + dc.b $38,$44,$54,$5c,$58,$40,$3c,$00 ;@ FLASHING!!! + dc.b $10,$28,$44,$44,$7c,$44,$44,$00 ;A + dc.b $78,$44,$44,$78,$44,$44,$78,$00 ;B + dc.b $38,$44,$40,$40,$40,$44,$38,$00 ;C + dc.b $78,$44,$44,$44,$44,$44,$78,$00 ;D + dc.b $7c,$40,$40,$78,$40,$40,$7c,$00 ;E + dc.b $7c,$40,$40,$78,$40,$40,$40,$00 ;F + dc.b $3c,$40,$40,$40,$4c,$44,$3c,$00 ;G + dc.b $44,$44,$44,$7c,$44,$44,$44,$00 ;H + dc.b $38,$10,$10,$10,$10,$10,$38,$00 ;I + dc.b $04,$04,$04,$04,$04,$44,$38,$00 ;J + dc.b $44,$48,$50,$60,$50,$48,$44,$00 ;K + dc.b $40,$40,$40,$40,$40,$40,$7c,$00 ;L + dc.b $44,$6c,$54,$54,$44,$44,$44,$00 ;M + dc.b $44,$44,$64,$54,$4c,$44,$44,$00 ;N + dc.b $38,$44,$44,$44,$44,$44,$38,$00 ;O + dc.b $78,$44,$44,$78,$40,$40,$40,$00 ;P + dc.b $38,$44,$44,$44,$54,$48,$34,$00 ;Q + dc.b $78,$44,$44,$78,$50,$48,$44,$00 ;R + dc.b $38,$44,$40,$38,$04,$44,$38,$00 ;S + dc.b $7c,$10,$10,$10,$10,$10,$10,$00 ;T + dc.b $44,$44,$44,$44,$44,$44,$38,$00 ;U + dc.b $44,$44,$44,$44,$44,$28,$10,$00 ;V + dc.b $44,$44,$44,$54,$54,$6c,$44,$00 ;W + dc.b $44,$44,$28,$10,$28,$44,$44,$00 ;X + dc.b $44,$44,$28,$10,$10,$10,$10,$00 ;Y + dc.b $7c,$04,$08,$10,$20,$40,$7c,$00 ;Z + dc.b $7c,$60,$60,$60,$60,$60,$7c,$00 ;[ + dc.b %00,$40,$20,$10,$08,$04,$02,$00 ;\ + dc.b $7c,$0c,$0c,$0c,$0c,$0c,$7c,$00 ;] + dc.b $00,$00,$10,$28,$44,$00,$00,$00 ;^ + dc.b $00,$00,$00,$00,$00,$00,$00,$fe ;_ + dc.b $00,$00,$00,$00,$00,$00,$00,$00 ; (space) + dc.b $10,$10,$10,$10,$10,$00,$10,$00 ;! + dc.b $28,$28,$28,$00,$00,$00,$00,$00 ;" + dc.b $28,$28,$7c,$28,$7c,$28,$28,$00 ;# + dc.b $10,$3c,$50,$38,$14,$78,$10,$00 ;$ + dc.b $60,$64,$08,$10,$20,$4c,$0c,$00 ;% + dc.b $20,$50,$50,$20,$54,$48,$34,$00 ;& + dc.b $10,$10,$10,$00,$00,$00,$00,$00 ;' + dc.b $10,$20,$40,$40,$40,$20,$10,$00 ;( + dc.b $10,$08,$04,$04,$04,$08,$10,$00 ;) + dc.b $10,$54,$38,$10,$38,$54,$10,$00 ;* + dc.b $00,$10,$10,$7c,$10,$10,$00,$00 ;+ + dc.b $00,$00,$00,$00,$10,$10,$20,$00 ;, + dc.b $00,$00,$00,$7c,$00,$00,$00,$00 ;- + dc.b $00,$00,$00,$00,$00,$00,$10,$00 ;. + dc.b $00,$04,$08,$10,$20,$40,$00,$00 ;/ + dc.b $38,$44,$4c,$54,$64,$44,$38,$00 ;0 + dc.b $10,$30,$10,$10,$10,$10,$38,$00 ;1 + dc.b $38,$44,$04,$18,$20,$40,$7c,$00 ;2 + dc.b $7c,$04,$08,$18,$04,$44,$38,$00 ;3 + dc.b $08,$18,$28,$48,$7c,$08,$08,$00 ;4 + dc.b $7c,$40,$78,$04,$04,$44,$38,$00 ;5 + dc.b $1c,$20,$40,$78,$44,$44,$38,$00 ;6 + dc.b $7c,$04,$08,$10,$20,$20,$20,$00 ;7 + dc.b $38,$44,$44,$38,$44,$44,$38,$00 ;8 + dc.b $38,$44,$44,$3c,$04,$08,$30,$00 ;9 + dc.b $00,$00,$10,$00,$10,$00,$00,$00 ;: + dc.b $00,$00,$10,$00,$10,$10,$20,$00 ;; + dc.b $08,$10,$20,$40,$20,$10,$08,$00 ;< + dc.b $00,$00,$7c,$00,$7c,$00,$00,$00 ;= + dc.b $20,$10,$08,$04,$08,$10,$20,$00 ;> + dc.b $38,$44,$08,$10,$10,$00,$10,$00 ;? + + dc.b $38,$44,$54,$5c,$58,$40,$3c,$00 ;@ NORMAL(lower?) + dc.b $10,$28,$44,$44,$7c,$44,$44,$00 ;A + dc.b $78,$44,$44,$78,$44,$44,$78,$00 ;B + dc.b $38,$44,$40,$40,$40,$44,$38,$00 ;C + dc.b $78,$44,$44,$44,$44,$44,$78,$00 ;D + dc.b $7c,$40,$40,$78,$40,$40,$7c,$00 ;E + dc.b $7c,$40,$40,$78,$40,$40,$40,$00 ;F + dc.b $3c,$40,$40,$40,$4c,$44,$3c,$00 ;G + dc.b $44,$44,$44,$7c,$44,$44,$44,$00 ;H + dc.b $38,$10,$10,$10,$10,$10,$38,$00 ;I + dc.b $04,$04,$04,$04,$04,$44,$38,$00 ;J + dc.b $44,$48,$50,$60,$50,$48,$44,$00 ;K + dc.b $40,$40,$40,$40,$40,$40,$7c,$00 ;L + dc.b $44,$6c,$54,$54,$44,$44,$44,$00 ;M + dc.b $44,$44,$64,$54,$4c,$44,$44,$00 ;N + dc.b $38,$44,$44,$44,$44,$44,$38,$00 ;O + dc.b $78,$44,$44,$78,$40,$40,$40,$00 ;P + dc.b $38,$44,$44,$44,$54,$48,$34,$00 ;Q + dc.b $78,$44,$44,$78,$50,$48,$44,$00 ;R + dc.b $38,$44,$40,$38,$04,$44,$38,$00 ;S + dc.b $7c,$10,$10,$10,$10,$10,$10,$00 ;T + dc.b $44,$44,$44,$44,$44,$44,$38,$00 ;U + dc.b $44,$44,$44,$44,$44,$28,$10,$00 ;V + dc.b $44,$44,$44,$54,$54,$6c,$44,$00 ;W + dc.b $44,$44,$28,$10,$28,$44,$44,$00 ;X + dc.b $44,$44,$28,$10,$10,$10,$10,$00 ;Y + dc.b $7c,$04,$08,$10,$20,$40,$7c,$00 ;Z + dc.b $7c,$60,$60,$60,$60,$60,$7c,$00 ;[ + dc.b %00,$40,$20,$10,$08,$04,$02,$00 ;\ + dc.b $7c,$0c,$0c,$0c,$0c,$0c,$7c,$00 ;] + dc.b $00,$00,$10,$28,$44,$00,$00,$00 ;^ + dc.b $00,$00,$00,$00,$00,$00,$00,$fe ;_ + dc.b $00,$00,$00,$00,$00,$00,$00,$00 ; (space) + dc.b $10,$10,$10,$10,$10,$00,$10,$00 ;! + dc.b $28,$28,$28,$00,$00,$00,$00,$00 ;" + dc.b $28,$28,$7c,$28,$7c,$28,$28,$00 ;# + dc.b $10,$3c,$50,$38,$14,$78,$10,$00 ;$ + dc.b $60,$64,$08,$10,$20,$4c,$0c,$00 ;% + dc.b $20,$50,$50,$20,$54,$48,$34,$00 ;& + dc.b $10,$10,$10,$00,$00,$00,$00,$00 ;' + dc.b $10,$20,$40,$40,$40,$20,$10,$00 ;( + dc.b $10,$08,$04,$04,$04,$08,$10,$00 ;) + dc.b $10,$54,$38,$10,$38,$54,$10,$00 ;* + dc.b $00,$10,$10,$7c,$10,$10,$00,$00 ;+ + dc.b $00,$00,$00,$00,$10,$10,$20,$00 ;, + dc.b $00,$00,$00,$7c,$00,$00,$00,$00 ;- + dc.b $00,$00,$00,$00,$00,$00,$10,$00 ;. + dc.b $00,$04,$08,$10,$20,$40,$00,$00 ;/ + dc.b $38,$44,$4c,$54,$64,$44,$38,$00 ;0 + dc.b $10,$30,$10,$10,$10,$10,$38,$00 ;1 + dc.b $38,$44,$04,$18,$20,$40,$7c,$00 ;2 + dc.b $7c,$04,$08,$18,$04,$44,$38,$00 ;3 + dc.b $08,$18,$28,$48,$7c,$08,$08,$00 ;4 + dc.b $7c,$40,$78,$04,$04,$44,$38,$00 ;5 + dc.b $1c,$20,$40,$78,$44,$44,$38,$00 ;6 + dc.b $7c,$04,$08,$10,$20,$20,$20,$00 ;7 + dc.b $38,$44,$44,$38,$44,$44,$38,$00 ;8 + dc.b $38,$44,$44,$3c,$04,$08,$30,$00 ;9 + dc.b $00,$00,$10,$00,$10,$00,$00,$00 ;: + dc.b $00,$00,$10,$00,$10,$10,$20,$00 ;; + dc.b $08,$10,$20,$40,$20,$10,$08,$00 ;< + dc.b $00,$00,$7c,$00,$7c,$00,$00,$00 ;= + dc.b $20,$10,$08,$04,$08,$10,$20,$00 ;> + dc.b $38,$44,$08,$10,$10,$00,$10,$00 ;? + + dc.b $38,$44,$54,$5c,$58,$40,$3c,$00 ;@ NORMAL + dc.b $10,$28,$44,$44,$7c,$44,$44,$00 ;A + dc.b $78,$44,$44,$78,$44,$44,$78,$00 ;B + dc.b $38,$44,$40,$40,$40,$44,$38,$00 ;C + dc.b $78,$44,$44,$44,$44,$44,$78,$00 ;D + dc.b $7c,$40,$40,$78,$40,$40,$7c,$00 ;E + dc.b $7c,$40,$40,$78,$40,$40,$40,$00 ;F + dc.b $3c,$40,$40,$40,$4c,$44,$3c,$00 ;G + dc.b $44,$44,$44,$7c,$44,$44,$44,$00 ;H + dc.b $38,$10,$10,$10,$10,$10,$38,$00 ;I + dc.b $04,$04,$04,$04,$04,$44,$38,$00 ;J + dc.b $44,$48,$50,$60,$50,$48,$44,$00 ;K + dc.b $40,$40,$40,$40,$40,$40,$7c,$00 ;L + dc.b $44,$6c,$54,$54,$44,$44,$44,$00 ;M + dc.b $44,$44,$64,$54,$4c,$44,$44,$00 ;N + dc.b $38,$44,$44,$44,$44,$44,$38,$00 ;O + dc.b $78,$44,$44,$78,$40,$40,$40,$00 ;P + dc.b $38,$44,$44,$44,$54,$48,$34,$00 ;Q + dc.b $78,$44,$44,$78,$50,$48,$44,$00 ;R + dc.b $38,$44,$40,$38,$04,$44,$38,$00 ;S + dc.b $7c,$10,$10,$10,$10,$10,$10,$00 ;T + dc.b $44,$44,$44,$44,$44,$44,$38,$00 ;U + dc.b $44,$44,$44,$44,$44,$28,$10,$00 ;V + dc.b $44,$44,$44,$54,$54,$6c,$44,$00 ;W + dc.b $44,$44,$28,$10,$28,$44,$44,$00 ;X + dc.b $44,$44,$28,$10,$10,$10,$10,$00 ;Y + dc.b $7c,$04,$08,$10,$20,$40,$7c,$00 ;Z + dc.b $7c,$60,$60,$60,$60,$60,$7c,$00 ;[ + dc.b %00,$40,$20,$10,$08,$04,$02,$00 ;\ + dc.b $7c,$0c,$0c,$0c,$0c,$0c,$7c,$00 ;] + dc.b $00,$00,$10,$28,$44,$00,$00,$00 ;^ + dc.b $00,$00,$00,$00,$00,$00,$00,$fe ;_ + + dc.b $10,$08,$04,$00,$00,$00,$00,$00 ;` ($e0) //e lowercase charset... + dc.b $00,$00,$38,$04,$3c,$44,$3c,$00 ;a + +; dc.b %00000000 ;b + dc.b %01000000 + dc.b %01000000 + dc.b %01111000 + dc.b %01000100 + dc.b %01000100 + dc.b %01000100 + dc.b %01111000 + dc.b %00000000 + + dc.b %00000000 ;c + dc.b %00000000 + dc.b %00111100 + dc.b %01000000 + dc.b %01000000 + dc.b %01000000 + dc.b %00111100 + dc.b %00000000 + +; dc.b %00000000 ;d + dc.b %00000100 + dc.b %00000100 + dc.b %00111100 + dc.b %01000100 + dc.b %01000100 + dc.b %01000100 + dc.b %00111100 + dc.b %00000000 + + dc.b %00000000 ;e + dc.b %00000000 + dc.b %00111000 + dc.b %01000100 + dc.b %01111100 + dc.b %01000000 + dc.b %00111100 + dc.b %00000000 + +; dc.b %00000000 ;f + dc.b %00011000 + dc.b %00100100 + dc.b %00100000 + dc.b %01111000 + dc.b %00100000 + dc.b %00100000 + dc.b %00100000 + dc.b %00000000 + + dc.b %00000000 ;g + dc.b %00000000 + dc.b %00111000 + dc.b %01000100 + dc.b %01000100 + dc.b %00111100 + dc.b %00000100 + dc.b %00111000 + +; dc.b %00000000 ;h + dc.b %01000000 + dc.b %01000000 + dc.b %01111000 + dc.b %01000100 + dc.b %01000100 + dc.b %01000100 + dc.b %01000100 + dc.b %00000000 + +; dc.b %00000000 ;i + dc.b %00010000 + dc.b %00000000 + dc.b %00110000 + dc.b %00010000 + dc.b %00010000 + dc.b %00010000 + dc.b %00111000 + dc.b %00000000 + + dc.b %00001000 ;j + dc.b %00000000 + dc.b %00011000 + dc.b %00001000 + dc.b %00001000 + dc.b %00001000 + dc.b %01001000 + dc.b %00110000 + +; dc.b %00000000 ;k + dc.b %01000000 + dc.b %01000000 + dc.b %01000100 + dc.b %01001000 + dc.b %01110000 + dc.b %01001000 + dc.b %01000100 + dc.b %00000000 + +; dc.b %00000000 ;l + dc.b %00110000 + dc.b %00010000 + dc.b %00010000 + dc.b %00010000 + dc.b %00010000 + dc.b %00010000 + dc.b %00111000 + dc.b %00000000 + + dc.b %00000000 ;m + dc.b %00000000 + dc.b %01101100 + dc.b %01010100 + dc.b %01010100 + dc.b %01010100 + dc.b %01000100 + dc.b %00000000 + + dc.b %00000000 ;n + dc.b %00000000 + dc.b %01111000 + dc.b %01000100 + dc.b %01000100 + dc.b %01000100 + dc.b %01000100 + dc.b %00000000 + + dc.b %00000000 ;o + dc.b %00000000 + dc.b %00111000 + dc.b %01000100 + dc.b %01000100 + dc.b %01000100 + dc.b %00111000 + dc.b %00000000 + + dc.b %00000000 ;p + dc.b %00000000 + dc.b %01111000 + dc.b %01000100 + dc.b %01000100 + dc.b %01111000 + dc.b %01000000 + dc.b %01000000 + + dc.b %00000000 ;q + dc.b %00000000 + dc.b %00111100 + dc.b %01000100 + dc.b %01000100 + dc.b %00111100 + dc.b %00000100 + dc.b %00000100 + + dc.b %00000000 ;r + dc.b %00000000 + dc.b %01011100 + dc.b %01100000 + dc.b %01000000 + dc.b %01000000 + dc.b %01000000 + dc.b %00000000 + + dc.b %00000000 ;s + dc.b %00000000 + dc.b %00111100 + dc.b %01000000 + dc.b %00111000 + dc.b %00000100 + dc.b %01111000 + dc.b %00000000 + + dc.b %00100000 ;t + dc.b %00100000 + dc.b %01111000 + dc.b %00100000 + dc.b %00100000 + dc.b %00100100 + dc.b %00011000 + dc.b %00000000 + + dc.b %00000000 ;u + dc.b %00000000 + dc.b %01000100 + dc.b %01000100 + dc.b %01000100 + dc.b %01001100 + dc.b %00110100 + dc.b %00000000 + + dc.b %00000000 ;v + dc.b %00000000 + dc.b %01000100 + dc.b %01000100 + dc.b %01000100 + dc.b %00101000 + dc.b %00010000 + dc.b %00000000 + + dc.b %00000000 ;w + dc.b %00000000 + dc.b %01000100 + dc.b %01000100 + dc.b %01010100 + dc.b %01010100 + dc.b %00101000 + dc.b %00000000 + + dc.b %00000000 ;x + dc.b %00000000 + dc.b %01000100 + dc.b %00101000 + dc.b %00010000 + dc.b %00101000 + dc.b %01000100 + dc.b %00000000 + + dc.b %00000000 ;y + dc.b %00000000 + dc.b %01000100 + dc.b %01000100 + dc.b %01000100 + dc.b %00111100 + dc.b %00000100 + dc.b %00111000 + + dc.b %00000000 ;z + dc.b %00000000 + dc.b %01111100 + dc.b %00001000 + dc.b %00010000 + dc.b %00100000 + dc.b %01111100 + dc.b %00000000 + + dc.b %00011100 ;{ + dc.b %00110000 + dc.b %00110000 + dc.b %01100000 + dc.b %00110000 + dc.b %00110000 + dc.b %00011100 + dc.b %00000000 + + dc.b %00010000 ;| + dc.b %00010000 + dc.b %00010000 + dc.b %00010000 + dc.b %00010000 + dc.b %00010000 + dc.b %00010000 + dc.b %00000000 + + dc.b %01110000 ;} + dc.b %00011000 + dc.b %00011000 + dc.b %00001100 + dc.b %00011000 + dc.b %00011000 + dc.b %01110000 + dc.b %00000000 + + dc.b %00110100 ;~ + dc.b %01011000 + dc.b %00000000 + dc.b %00000000 + dc.b %00000000 + dc.b %00000000 + dc.b %00000000 + dc.b %00000000 + + dc.b %00000000 ;block + dc.b %01010100 + dc.b %00101000 + dc.b %01010100 + dc.b %00101000 + dc.b %01010100 + dc.b %00000000 + dc.b %00000000 + + CNOP 0,4 + +IIeCharSet2: ;for text BitPlane2. Only flashing has $ff for that char! + dcb.b 64,0 + dcb.b 64,$ff + dcb.b 128,0 + + +************************************************************************** +*** The following character set is used for the "Status Bar" at the bottom +*** of the screen. + + CNOP 0,4 + +StatusCharSet8X5: + dc.b ~%00000000 ;space $20 #32 + dc.b ~%00000000 + dc.b ~%00000000 + dc.b ~%00000000 + dc.b ~%00000000 + + dc.b ~%00001000 ;! $21 #33 + dc.b ~%00001000 + dc.b ~%00001000 + dc.b ~%00000000 + dc.b ~%00001000 + + dc.b ~%00010100 ;" + dc.b ~%00010100 + dc.b ~%00000000 + dc.b ~%00000000 + dc.b ~%00000000 + + dc.b ~%00010100 ;# + dc.b ~%00111110 + dc.b ~%00010100 + dc.b ~%00111110 + dc.b ~%00010100 + + dc.b ~%00111100 ;$ + dc.b ~%01010000 + dc.b ~%00111000 + dc.b ~%00010100 + dc.b ~%01111000 + + dc.b ~%00100010 ;% + dc.b ~%00000100 + dc.b ~%00001000 + dc.b ~%00010000 + dc.b ~%00100010 + + dc.b ~%00001000 ;& + dc.b ~%00010100 + dc.b ~%00001000 + dc.b ~%00010100 + dc.b ~%00001010 + + dc.b ~%00001000 ;' + dc.b ~%00001000 + dc.b ~%00000000 + dc.b ~%00000000 + dc.b ~%00000000 + + dc.b ~%00001000 ;( + dc.b ~%00010000 + dc.b ~%00010000 + dc.b ~%00010000 + dc.b ~%00001000 + + dc.b ~%00010000 ;) + dc.b ~%00001000 + dc.b ~%00001000 + dc.b ~%00001000 + dc.b ~%00010000 + + dc.b ~%00101010 ;* + dc.b ~%00011100 + dc.b ~%00111110 + dc.b ~%00011100 + dc.b ~%00101010 + + dc.b ~%00001000 ;+ + dc.b ~%00001000 + dc.b ~%00111110 + dc.b ~%00001000 + dc.b ~%00001000 + + dc.b ~%00000000 ;, + dc.b ~%00000000 + dc.b ~%00000000 + dc.b ~%00001000 + dc.b ~%00010000 + + dc.b ~%00000000 ;- + dc.b ~%00000000 + dc.b ~%00111100 + dc.b ~%00000000 + dc.b ~%00000000 + + dc.b ~%00000000 ;. + dc.b ~%00000000 + dc.b ~%00000000 + dc.b ~%00000000 + dc.b ~%00001000 + + dc.b ~%00000010 ;/ + dc.b ~%00000100 + dc.b ~%00001000 + dc.b ~%00010000 + dc.b ~%00100000 + + dc.b ~%00011000 ;0 + dc.b ~%00100100 + dc.b ~%00100100 + dc.b ~%00100100 + dc.b ~%00011000 + + dc.b ~%00001000 ;1 + dc.b ~%00011000 + dc.b ~%00001000 + dc.b ~%00001000 + dc.b ~%00011100 + + dc.b ~%00011000 ;2 + dc.b ~%00000100 + dc.b ~%00001000 + dc.b ~%00010000 + dc.b ~%00011100 + + dc.b ~%00111000 ;3 + dc.b ~%00000100 + dc.b ~%00011000 + dc.b ~%00000100 + dc.b ~%00111000 + + dc.b ~%00100100 ;4 + dc.b ~%00100100 + dc.b ~%00111100 + dc.b ~%00000100 + dc.b ~%00000100 + + dc.b ~%00111100 ;5 + dc.b ~%00100000 + dc.b ~%00111000 + dc.b ~%00000100 + dc.b ~%00111000 + + dc.b ~%00011100 ;6 + dc.b ~%00100000 + dc.b ~%00111000 + dc.b ~%00100100 + dc.b ~%00011000 + + dc.b ~%00011100 ;7 + dc.b ~%00000100 + dc.b ~%00001000 + dc.b ~%00001000 + dc.b ~%00001000 + + dc.b ~%00011000 ;8 + dc.b ~%00100100 + dc.b ~%00011000 + dc.b ~%00100100 + dc.b ~%00011000 + + dc.b ~%00011000 ;9 + dc.b ~%00100100 + dc.b ~%00011100 + dc.b ~%00000100 + dc.b ~%00011000 + + dc.b ~%00000000 ;: + dc.b ~%00001000 + dc.b ~%00000000 + dc.b ~%00001000 + dc.b ~%00000000 + + dc.b ~%00000000 ;: + dc.b ~%00001000 + dc.b ~%00000000 + dc.b ~%00001000 + dc.b ~%00010000 + + dc.b ~%00000100 ;< + dc.b ~%00001000 + dc.b ~%00010000 + dc.b ~%00001000 + dc.b ~%00000100 + + dc.b ~%00000000 ;= + dc.b ~%00111100 + dc.b ~%00000000 + dc.b ~%00111100 + dc.b ~%00000000 + + dc.b ~%00010000 ;> + dc.b ~%00001000 + dc.b ~%00000100 + dc.b ~%00001000 + dc.b ~%00010000 + + dc.b ~%00011000 ;? + dc.b ~%00000100 + dc.b ~%00001000 + dc.b ~%00000000 + dc.b ~%00001000 + + dc.b ~%00001111 ;@ as Rt-Amiga... + dc.b ~%00011011 + dc.b ~%00111111 + dc.b ~%01100011 + dc.b ~%11110111 + + dc.b ~%00011000 ;A + dc.b ~%00100100 + dc.b ~%00111100 + dc.b ~%00100100 + dc.b ~%00100100 + + dc.b ~%00111000 ;B + dc.b ~%00100100 + dc.b ~%00111000 + dc.b ~%00100100 + dc.b ~%00111000 + + dc.b ~%00011100 + dc.b ~%00100000 + dc.b ~%00100000 + dc.b ~%00100000 + dc.b ~%00011100 + + dc.b ~%00111000 + dc.b ~%00100100 + dc.b ~%00100100 + dc.b ~%00100100 + dc.b ~%00111000 + + dc.b ~%00111100 + dc.b ~%00100000 + dc.b ~%00111000 + dc.b ~%00100000 + dc.b ~%00111100 + + dc.b ~%00111100 + dc.b ~%00100000 + dc.b ~%00111000 + dc.b ~%00100000 + dc.b ~%00100000 + + dc.b ~%00011000 + dc.b ~%00100000 + dc.b ~%00101100 + dc.b ~%00100100 + dc.b ~%00011000 + + dc.b ~%00100100 + dc.b ~%00100100 + dc.b ~%00111100 + dc.b ~%00100100 + dc.b ~%00100100 + + dc.b ~%00111000 + dc.b ~%00010000 + dc.b ~%00010000 + dc.b ~%00010000 + dc.b ~%00111000 + + dc.b ~%00000100 + dc.b ~%00000100 + dc.b ~%00000100 + dc.b ~%00100100 + dc.b ~%00011000 + + dc.b ~%00100100 + dc.b ~%00101000 + dc.b ~%00110000 + dc.b ~%00101000 + dc.b ~%00100100 + + dc.b ~%00100000 + dc.b ~%00100000 + dc.b ~%00100000 + dc.b ~%00100000 + dc.b ~%00111100 + + dc.b ~%00100010 + dc.b ~%00110110 + dc.b ~%00101010 + dc.b ~%00100010 + dc.b ~%00100010 + + dc.b ~%00100010 + dc.b ~%00110010 + dc.b ~%00101010 + dc.b ~%00100110 + dc.b ~%00100010 + + dc.b ~%00011000 + dc.b ~%00100100 + dc.b ~%00100100 + dc.b ~%00100100 + dc.b ~%00011000 + + dc.b ~%00111000 + dc.b ~%00100100 + dc.b ~%00111000 + dc.b ~%00100000 + dc.b ~%00100000 + + dc.b ~%00011000 + dc.b ~%00100100 + dc.b ~%00100100 + dc.b ~%00101000 + dc.b ~%00010100 + + dc.b ~%00111000 + dc.b ~%00100100 + dc.b ~%00111000 + dc.b ~%00100100 + dc.b ~%00100100 + + dc.b ~%00011100 + dc.b ~%00100000 + dc.b ~%00011000 + dc.b ~%00000100 + dc.b ~%00111000 + + dc.b ~%00111110 + dc.b ~%00001000 + dc.b ~%00001000 + dc.b ~%00001000 + dc.b ~%00001000 + + dc.b ~%00100100 + dc.b ~%00100100 + dc.b ~%00100100 + dc.b ~%00100100 + dc.b ~%00011000 + + dc.b ~%00100010 + dc.b ~%00100010 + dc.b ~%00010100 + dc.b ~%00010100 + dc.b ~%00001000 + + dc.b ~%00100010 + dc.b ~%00100010 + dc.b ~%00101010 + dc.b ~%00110110 + dc.b ~%00100010 + + dc.b ~%00100010 + dc.b ~%00010100 + dc.b ~%00001000 + dc.b ~%00010100 + dc.b ~%00100010 + + dc.b ~%00100010 + dc.b ~%00010100 + dc.b ~%00001000 + dc.b ~%00001000 + dc.b ~%00001000 + + dc.b ~%00111100 + dc.b ~%00000100 + dc.b ~%00001000 + dc.b ~%00010000 + dc.b ~%00111100 + + dc.b ~%00111100 ;[ + dc.b ~%00100000 + dc.b ~%00100000 + dc.b ~%00100000 + dc.b ~%00111100 + + dc.b ~%00100000 ;\ + dc.b ~%00010000 + dc.b ~%00001000 + dc.b ~%00000100 + dc.b ~%00000010 + + dc.b ~%00111100 ;] + dc.b ~%00000100 + dc.b ~%00000100 + dc.b ~%00000100 + dc.b ~%00111100 + + dc.b ~%00001000 ;^ + dc.b ~%00010100 + dc.b ~%00000000 + dc.b ~%00000000 + dc.b ~%00000000 + + dc.b ~%00000000 ;_ + dc.b ~%00000000 + dc.b ~%00000000 + dc.b ~%00000000 + dc.b ~%00111110 + + dc.b ~%00001000 ;` + dc.b ~%00000100 + dc.b ~%00000000 + dc.b ~%00000000 + dc.b ~%00000000 + + + \ No newline at end of file diff --git a/src/Compress.s b/src/Compress.s new file mode 100644 index 0000000..6fd4177 --- /dev/null +++ b/src/Compress.s @@ -0,0 +1,581 @@ + SECTION APPLEII,CODE + EVEN + +** NOTE ** Disk image is extraced from "Src_Disk_Buffer" (either buffer1 or buffer2)!!! + +************************************** +* +* CompressDisk: +* This function does an entire Decoding & Compression of a disk image, +* using the "Dalton Disk Disintegrator 2.0" algorithm. (see DDD, $1b41-$1b86, $1bc6...) +* +* Inputs: Floppy Image in disk_Buffer memory +* A0 -> Destination Buffer (at least 145,000 bytes to be safe) +* +* Output: Compressed Disk Image (DDD) in Destination Buffer w/ simple ProDos header +* D0 = FileSize; Total length of compressedData (including header) (0 if failed) +* + +CompressDisk: + + movem.l a2-a6/d2-d5,-(sp) + + move.l a0,a5 ;A5-> Base of Dest Buffer! + moveq.l #0,d5 ;D5 = Dest buffer bit offset! + lea ReverseByteTbl,a6 ;a6-> Reverse byte lookup tbl + + + move.l #$00000000,(a5) ;Make blank 4 byte Dos3.3 header + add.l #32,d5 + + move.l #0,.TrackNum + +.loop move.l .TrackNum,d0 ;trk num <----- main loop + lea .TrackData,a0 ;dest buffer + jsr ReadTrack + tst d0 + beq .Error + + lea .TrackData,a0 ;track data + lea .FreqTable,a1 ;dest for Frequency Count Tbl + jsr FrequencyCount + + tst.l .TrackNum + bne .Not0 +.Trk0 moveq.b #0,d0 ;val Encode DDD header (Three 0 bits) + moveq.w #3,d1 ;# of bits + bsr .WriteNBits + moveq.l #0,d0 + move.b SecVolumeNumB,d0 ;Encode Volume # of disk + move.b (a6,d0.w),d0 ;ReverseByte & add 8 bits at once... + bfins d0,(a5){d5:8} + addq.l #8,d5 +.Not0 + + lea .FreqTable,a0 ;freq count table + lea .Top20List,a1 ;top 20 values list destination + bsr Top20Search + + lea .Top20List,a2 + move.w #19,d2 ;Encode the 20 top values... + moveq.l #0,d0 +.Encd20 move.b (a2)+,d0 + move.b (a6,d0.w),d0 ;ReverseByte & add 8 bits at once... + bfins d0,(a5){d5:8} + addq.l #8,d5 + dbf d2,.Encd20 + + ;------------------- +.CompressTrackData ;The real compression algorithm, using top 20 values + + lea .TrackData,a2 ;A2 -> TrackData (4096 bytes) + moveq.w #0,d2 ;D2 = main index into track data + +.CompLp move.b (a2,d2.w),d0 ;read 1st val + + move.w d2,d3 ;d3 = local index. How many times does D0 repeat? +.Count cmp.b (a2,d3.w),d0 ;1st check against self to maintain bounds check & get >=1 + bne.b 5$ + addq.w #1,d3 + cmp.w #4095,d3 ;still in range? + bls.b .Count + +5$ sub.w d2,d3 ;d3 = # of times byte D0 is there (at least 1)! + cmp.w #4,d3 + blo.b .Single + +.Multiple ;------- value D0 repeats D3 times... (D3 >= #4) + cmp.w #$100,d3 + bls.b 10$ + move.w #$100,d3 ;limit of $100 repeat values (written as #$00) + +10$ move.b d0,d1 ;save value temporarily... + move.w #$97,d0 ;Encode code for "Repeat" + move.b (a6,d0.w),d0 ;ReverseByte & add 8 bits at once... + bfins d0,(a5){d5:8} + addq.l #8,d5 + + move.b d1,d0 ;Encode data value + move.b (a6,d0.w),d0 ;ReverseByte & add 8 bits at once... + bfins d0,(a5){d5:8} + addq.l #8,d5 + + move.b d3,d0 ;Encode # of times repeats + move.b (a6,d0.w),d0 ;ReverseByte & add 8 bits at once... + bfins d0,(a5){d5:8} + addq.l #8,d5 + + add.w d3,d2 ;update main index into track data... + bra 100$ + +.Single ;------- single value D0... + move.w #19,d3 ;d3 = index to search Top20List with (19 -> 0) + lea .Top20List,a0 ;a0 -> Top20List, UBYTES[20] +20$ cmp.b (a0,d3.w),d0 + beq.b .SingleTop20 ;is D0 a top 20 value? + dbf d3,20$ + ;Not top20, so encode this byte by itself... + move.b d0,-(sp) + move.b #0,d0 + moveq.b #1,d1 ;Encode "SingleByte" code + bsr .WriteNBits + + moveq.l #0,d0 + move.b (sp)+,d0 + move.b (a6,d0.w),d0 ;ReverseByte & add 8 bits at once... + bfins d0,(a5){d5:8} + addq.l #8,d5 + + bra 99$ + +.SingleTop20 ;-- single value is a Top 20 value! UBYTE[d3.w] + lea .Top20Codes,a0 + move.b (a0,d3.w),d0 + lea .Top20Lengths,a0 + move.b (a0,d3.w),d1 + bsr .WriteNBits + +; bra 99$ (fall through!) + +99$ addq.w #1,d2 +100$ cmp.w #4095,d2 + bls .CompLp ;Do all 4096 bytes of track data... + +;--------------------- + + addq.l #1,.TrackNum + cmp.l #34,.TrackNum ;Do all 35 tracks! + bls .loop + ;Disk image compressed, now report len in bytes + ;D5 = Length in bits... + addq.l #7,d5 ;we want any partial bytes... + divu.l #8,d5 ;d5 = Length in bytes! + + move.l d5,d0 ;lenth of compression! + movem.l (sp)+,a2-a6/d2-d5 + rts + +.Error movem.l (sp)+,a2-a6/d2-d5 + moveq.l #0,d0 + rts + +.WriteNBits: ;Enter: d0 = Data to write (low order bits), d1 = # of bits to write + ; a5 -> Base of destination memory, d5 = Offset in BITS... + ;Output: Memory written, updated Offset (d5) + ; (see DDD $1d28 - $1d54) + + subq.b #1,d1 + and.w #$000f,d1 +.lp bfins d0,(a5){d5:1} ;place low order bit in memory + lsr.l d0 + addq.l #1,d5 ;1 at a time until done... + dbf d1,.lp + rts + + CNOP 0,4 + +.Top20Codes dc.b $03,$09,$1f,$0f,$07,$1b,$0b,$0d,$15,$37 ;(see DDD $1d55-$1d7c) + dc.b $3d,$25,$05,$b1,$11,$21,$01,$57,$5d,$1d +.Top20Lengths dc.b $04,$04,$05,$05,$05,$05,$05,$05,$05,$06 + dc.b $06,$06,$06,$06,$06,$06,$06,$07,$07,$07 + +.TrackNum ds.l 1 + +.TrackData ds.b 4096 +.FreqTable ds.w 256 +.Top20List ds.b 20 + + even +************************************** +* +* PlainDiskImage_Save: +* This function takes a disk image in ram, and saved it to disk in the "plain image" +* format, which is the normalilzed track/sector data (143,360 bytes) in order. +* +* Inputs: Floppy Image in disk_Buffer memory +* A0 -> Destination Buffer (at least 143,360 bytes to be safe) +* +* Output: Plain Image Data in Destination Buffer w/ no headers/trailor/checksums +* D0 = FileSize; Total length of data (should be 143,360) (0 if failed) +* + +PlainDiskImage_Save: + + movem.l a2-a5/d2-d5,-(sp) + + move.l a0,a5 ;A5-> Base of Dest Buffer! + moveq.l #0,d5 ;D5 = Dest buffer bit offset! + + move.l #0,.TrackNum + +.loop move.l .TrackNum,d0 ;trk num <----- main loop + + move.l d0,d1 + mulu.w #4096,d1 + lea (a5,d1.l),a0 ;A0 = dest buffer... + jsr ReadTrack ;fix dest buffer + tst d0 + beq .Error + + + addq.l #1,.TrackNum + cmp.l #34,.TrackNum ;Do all 35 tracks! + bls .loop + ;Disk image compressed, now report len in bytes + move.l #143360,d0 ;d0 = lenth of disk data + movem.l (sp)+,a2-a5/d2-d5 + rts + +.Error movem.l (sp)+,a2-a5/d2-d5 + moveq.l #0,d0 + rts + + CNOP 0,4 +.TrackNum ds.l 1 + +.TrackData ds.b 4096 +.FreqTable ds.w 256 +.Top20List ds.b 20 + EVEN +***************************************** +* +* ReadTrack: +* This function will extract 1 track of normalized data from a disk image, +* using Apple Dos's normal decoding algorithms. (uses ReadSector) +* +* Inputs: Floppy Image in disk_Buffer memory (normal) +* D0 = Track number to extract from +* A0 -> Destination for data (4096 bytes!) +* +* Output: 4096 bytes of sector data in dest. buffer +* D0 = True (1) for Successful extraction +* False (0) for ERROR +* + +ReadTrack: + movem.l a2/d2-d3,-(sp) + + cmp.w #34,d0 + bhi.b .Error ;track out of range... + + move.l d0,d2 ;d2 = Track # + moveq.l #0,d3 ;d3 = Sector # + move.l a0,a2 ;a2 -> Ptr to destination buffer + +.loop move.l d2,d0 ;track num + move.l d3,d1 ;sector num + move.l a2,a0 ;dest buffer + jsr ReadSector + tst d0 ;did it work? + beq.b .Error + + add.l #$100,a2 ;set dest to next page of mem + addq.l #1,d3 ;inc sector + cmp.b #15,d3 + bls.b .loop ;read all 16 sectors! + + moveq.l #1,d0 + movem.l (sp)+,a2/d2-d3 + rts + +.Error moveq.l #0,d0 + movem.l (sp)+,a2/d2-d3 + rts + +;---------------------------------------------------------------------------------------- + +***************************************** +* +* ReadSector: +* This function will extract 1 sector of normalized data from a disk image, +* using Apple Dos's normal decoding algorithms. +* +* Inputs: Floppy Image in disk_Buffer memory (normal) +* D0 = Track number (0 - 34) +* D1 = Sector number (0 - 15) +* A0 -> Destination for data (256 bytes) +* +* Output: 256 bytes of sector data in dest. buffer +* D0 = True (1) for Successful extraction +* False (0) for ERROR +* + +ReadSector: + movem.l a2-a5/d2-d4,-(sp) + + mulu.w #disk_TrackLen,d0 + add.l Src_Disk_Buffer,d0 + move.l d0,a2 ;a2 -> Start of raw track data + move.l a2,a3 ;a3 -> CURRENT ptr to raw track data (a2 <= a3 <= a4) + lea disk_TrackLen-1(a2),a4 ;a4 -> Last byte of raw track data + move.l d1,d4 ;d4 = Sector # we want... + move.l #disk_TrackLen+500,d3 ;d3 = Max "GetNext" searches allowed! + bra.b .addr + +.NxtSec + lea 345(a3),a3 + cmp.l a4,a3 ;make sure addr still in range + bls.b .addr + sub.l #disk_TrackLen,a3 ;if not, reset it + +.addr jsr .GetNext + cmp.b #$D5,d0 ;Search for D5 AA 96 address header + bne .addr + jsr .GetNext + cmp.b #$AA,d0 + bne .addr + jsr .GetNext + cmp.b #$96,d0 + bne .addr + ;***** Extract 4X4 address data ***** + jsr .Get4X4 ;Volume Number + move.b d0,SecVolumeNumB + + jsr .Get4X4 ;Track Number + + jsr .Get4X4 ;HARD sector num... + cmp.b #$0f,d0 + bhi.b .addr ;outside legal range? Keep searching... + move.b (.HardToSoft.l,d0.w),d0 ;d0 = SOFT sector num... + cmp.b d0,d4 + bne .NxtSec ;doh! Not the right sector! + + jsr .Get4X4 ;Checksum (ignore for now) + + jsr .GetNext ;better get DE AA address epilog + cmp.b #$DE,d0 + bne .addr + jsr .GetNext + cmp.b #$AA,d0 + bne .addr + +.data jsr .GetNext + cmp.b #$D5,d0 ;Wait for D5 AA AD data header + bne .data + jsr .GetNext + cmp.b #$AA,d0 + bne .data + jsr .GetNext + cmp.b #$AD,d0 + bne .data + + moveq.w #$55,d1 ;d1 = cntr... + lea .NibbleHunk56+$56,a1 ;a1 -> destination + moveq.l #0,d4 ;d4 == ACC == running EOR checksum + lea .DecodeTable-$96,a5 ;a5 -> DecodeTable (-$96) + + moveq.l #0,d0 ;See $b8ff -> $b911 in DOS 3.3 +.loop jsr .GetNext ;LDY $c0ec + move.b (a5,d0.w),d0 ;eor $ba00,y + eor.b d0,d4 ; ... + move.b d4,-(a1) ;sta $bc00,y (y decrements) + dbf d1,.loop + + move.w #$ff,d1 ;d1 = cntr + lea .NibbleHunk100,a1 ;a1 -> dest + +.loop2 jsr .GetNext ;See $b915 -> $b923 + move.b (a5,d0.w),d0 ;eor $ba00,y + eor.b d0,d4 ; + move.b d4,(a1)+ ;sta $bb00,y (y inc's) + dbf d1,.loop2 + +.cksum jsr .GetNext ;See $b925 (checksum) + cmp.b (a5,d0.w),d4 ;cmp $ba00,y + bne .Error + + jsr .GetNext ;better get DE AA data epilog + cmp.b #$DE,d0 + bne .Error + jsr .GetNext + cmp.b #$AA,d0 + bne .Error + +* DeNibble-ize: (see dos 3.3 code at $b800) +* Takes 342 bytes of "6 & 2" disk encoded crap as returns 256 bytes of normal data. +* +* Nib1: Nib2: Dest: +* $ff-+- o $ff-+- o +* | ^ $55-+- vvo | ^ +* | ^ | vvv | ^ +* | ^ | vvv | ^ +* $00-+- o $00-+- ovv $00-+- o +* +* Inputs: a0 = destination for 256 bytes of data +* NibbleHunk100 & 56 = Contain nibble data + + ;at this point, all nibble data is read...! + ;Now, DE-NIBBLIZE !!! (dos 3.3 $b8c2 - $b8db) + ; d1 = YReg, d2 = XReg, d3 = ACC + + lea .NibbleHunk100,a2 ;a2-> NibbleHunk1[$00] ($100) + lea .NibbleHunk56,a3 ;a3-> NibbleHunk2[$00] ($56) + move.l a0,a4 ;a4-> Dest buffer (256 bytes) + move.w #$00ff,d1 ;d1 = Byte Countdown + +.DeNibl +.b8c4 move.w #$56,d2 ;LDX #$56 +.b8c6 subq.b #1,d2 ;DEX + bmi.b .b8c4 ;BMI $b8c4 + move.b (a2)+,d3 ;LDA $bb00,Y + move.b (a3,d2.w),d0 + lsr.b d0 ;LSR $bc00,X + roxl.b d3 ;ROL + lsr.b d0 ;LSR $bc00,X + roxl.b d3 ;ROL + move.b d0,(a3,d2.w) + move.b d3,(a4)+ ;store another byte of normal data! + dbf d1,.b8c6 + + movem.l (sp)+,a2-a5/d2-d4 + move.l #1,d0 ;success... + rts + +.GetNext: ;a2 -> Start track data, a3 -> Current track data + ;a4 -> Max track data ptr, d3=remaining tries + ; Return: d0 = byte + move.b (a3)+,d0 + cmp.l a4,a3 ;make sure addr still in range + bls.b .ok + move.l a2,a3 ;if not, reset it +.ok subq.l #1,d3 + bmi .GNErr + rts + +.GNErr move.l (sp)+,d0 ;Exceeded # of tries, POP STACK, and fall to error... + + +.Error moveq.l #0,d0 ;Failed (d0 = False).... + movem.l (sp)+,a2-a5/d2-d4 + rts + +.Get4X4 + ;a2 -> Start track data, a3 -> Current track data + ;a4 -> Max track data ptr + ;Return: d0 = byte + moveq.l #0,d0 + move.b (a3)+,d0 + cmp.l a4,a3 ;make sure addr still in range + bls.b .ok3 + move.l a2,a3 ;if not, reset it +.ok3 lsl.b d0 + or.b #$01,d0 + + and.b (a3)+,d0 + cmp.l a4,a3 ;make sure addr still in range + bls.b .ok4 + move.l a2,a3 ;if not, reset it +.ok4 rts + + + +.HardToSoft dc.b $0,$7,$e,$6,$d,$5,$c,$4,$b,$3,$a,$2,$9,$1,$8,$f + + ;The lookup table used as $ba00,y ALWAYS had Y >= $96, + ;so here is the pertinant portion of the table ($ba96-$baff) + ;Make sure to subtract $96 when getting the address of it. +.DecodeTable: + dc.b $00,$01,$98,$99,$02,$03,$9C,$04,$05,$06,$A0,$A1,$A2,$A3,$A4 + dc.b $A5,$07,$08,$A8,$A9,$AA,$09,$0A,$0B,$0C,$0D,$B0,$B1,$0E,$0F + dc.b $10,$11,$12,$13,$B8,$14,$15,$16,$17,$18,$19,$1A,$C0,$C1,$C2 + dc.b $C3,$C4,$C5,$C6,$C7,$C8,$C9,$CA,$1B,$CC,$1C,$1D,$1E,$D0,$D1 + dc.b $D2,$1F,$D4,$D5,$20,$21,$D8,$22,$23,$24,$25,$26,$27,$28,$E0 + dc.b $E1,$E2,$E3,$E4,$29,$2A,$2B,$E8,$2C,$2D,$2E,$2F,$30,$31,$32 + dc.b $F0,$F1,$33,$34,$35,$36,$37,$38,$F8,$39,$3A,$3B,$3C,$3D,$3E,$3F + +.NibbleHunk100 ds.b $100 ;342 bytes of storage space... +.NibbleHunk56 ds.b $56 +.NibblePad dc.b $ff,$ff,$ff,$ff + +SecVolumeNumB ds.b 1 + +;--------------------------------------------------------------------------------------- + + EVEN +***************************************** +* +* FrequencyCount: (see DDD $1bc6 - $1c2b) +* This function will scan through 4096 bytes of data, counting occurances +* of each byte value and will create a list of UWORDS[256]. +* As in DDD, any Repeating value of 4 or more will be skipped. +* +* Inputs: A0 -> 4096 bytes of data to analyze +* A1 -> Destination for UWORDS[256] result (512 bytes!) +* +* Output: list of UWORDS[256] frequency count in dest. buffer +* + +FrequencyCount: ;---- Produce list of most popular bytes... + + movem.l a2-a5/d2-d5,-(sp) + + move.l a0,a2 ;a2 -> 4096 bytes of data + move.l a1,a3 ;a3 -> Destination table of UWORDS[256] + + move.w #255,d0 +.ClrLp move.w #0,(a1,d0.w*2) ;clear dest table + dbf d0,.ClrLp + + move.w #0,d2 ;d2 = main index + moveq.l #0,d0 +.MnLoop move.b (a2,d2.w),d0 ;read 1st val + + move.w d2,d3 ;d3 = local index. How many times does D0 repeat? +.repeat cmp.b (a2,d3.w),d0 + bne.b 5$ + addq.w #1,d3 + cmp.w #4095,d3 + bls.b .repeat + +5$ sub.w d2,d3 ;d3 = # of times byte D0 is there (at least 1)! + cmp.w #4,d3 + bhs.b .NoCnt +.Cnt addq.w #1,(a3,d0.w*2) + move.w #1,d3 ;only inc 1 byte +.NoCnt add.w d3,d2 + + cmp.w #4095,d2 + bls.b .MnLoop + + movem.l (sp)+,a2-a5/d2-d5 + rts + +***************************************** +* +* Top20Search: (see DDD $1c2c - $1c75) +* This function will scan through the frequency list UWORDS[256], create a list +* of the top 20 values in UBYTE[20]. During each search, this function will examine +* each entry, and if >= current high number, replace the current high number with it. +* +* Inputs: A0 -> Source of frequency count UWORDS[256] +* A1 -> Destination for top 20 values UBYTES[20] (20 bytes!) +* Output: list of most popular values UBYTES[20] in dest. buffer +* + +Top20Search: ;---- Produce list of most popular bytes... + + movem.l a2-a5/d2-d5,-(sp) + + move.w #0,d1 ;D1 = value index # (0 -> 19) we are looking for +.loop20 moveq.l #0,d0 ;D0 = max frequency number found so far... + move.w #0,d2 ;D2 = search index (0 - 255) + +.search cmp.w (a0,d2.w*2),d0 + bhi.b .nope + move.w (a0,d2.w*2),d0 ;new max frequency number + move.b d2,(a1,d1.w) ;temporarily (?) keep the number in the table... + +.nope addq.b #1,d2 ;search/compare all 256 values... + bne.b .search + + move.b (a1,d1.w),d2 ;get that popular value... + move.w #0,(a0,d2.w*2) ;and blank its entry out in the freq table... + + addq.b #1,d1 ;get 20 values total... + cmp.b #19,d1 + bls.b .loop20 + + movem.l (sp)+,a2-a5/d2-d5 + rts + + \ No newline at end of file diff --git a/src/Debug.s b/src/Debug.s new file mode 100644 index 0000000..4b49594 --- /dev/null +++ b/src/Debug.s @@ -0,0 +1,78 @@ +** DEBUGGING Routines... Print Strings, hex numbers, dec numbers, etc... +** to MYCHANNEL... (opened prior) + SECTION APPLEII,CODE + EVEN + rts +DB_String: ** A0 -> Null Terminated String to Print + movem.l a1-a6/d0-d4,-(sp) + move.l a0,.ds ;move str ptr into data stream... + lea .fs,a0 ;format string ptr + lea .ds,a1 ;data stream ptr + lea DB_PutChProc,a2 + move.l #0,a3 ;indx to buffer + lea DB_Buffer,a4 + CALLEXEC RawDoFmt + movem.l (sp)+,a1-a6/d0-d4 + rts +.ds ds.l 1 +.fs dc.b '%s',0 + + even +DB_HexB movem.l a0-a6/d0-d4,-(sp) ** D0 = a word value to print + move.w d0,.ds ;move # into data stream + lea .fs,a0 ;format string ptr + lea .ds,a1 ;data stream ptr + lea DB_PutChProc,a2 + move.l #0,a3 + lea DB_Buffer,a4 + CALLEXEC RawDoFmt + movem.l (sp)+,a0-a6/d0-d4 + rts +.ds ds.w 1 +.fs dc.b '$%02x ',0 + + even +DB_HexW movem.l a0-a6/d0-d4,-(sp) ** D0 = a word value to print + move.w d0,.ds ;move # into data stream + lea .fs,a0 ;format string ptr + lea .ds,a1 ;data stream ptr + lea DB_PutChProc,a2 + move.l #0,a3 + lea DB_Buffer,a4 + CALLEXEC RawDoFmt + movem.l (sp)+,a0-a6/d0-d4 + rts +.ds ds.w 1 +.fs dc.b '$%04x',0 + + even +DB_HexL movem.l a0-a6/d0-d4,-(sp) ** D0 = A LONG value to print + move.l d0,.ds ;move # into data stream + lea .fs,a0 ;format string ptr + lea .ds,a1 ;data stream ptr + lea DB_PutChProc,a2 + move.l #0,a3 + lea DB_Buffer,a4 + CALLEXEC RawDoFmt + movem.l (sp)+,a0-a6/d0-d4 + rts +.ds ds.l 1 +.fs dc.b '$%08lx',0 + EVEN + +DB_PutChProc: + move.b d0,(a4,a3.w) ;buffer + indx + beq DB_PrintBuffer + addq.w #1,a3 + rts + + even +DB_PrintBuffer: ** Called with a3= Length of Buffer (excludes NULL) + move.l MyChannel,d1 + move.l #DB_Buffer,d2 + move.l a3,d3 ;length + CALLDOS Write + rts + +DataStream dc.w 9,8,7,6,5 +DB_Buffer ds.b 85 diff --git a/src/Decompress.s b/src/Decompress.s new file mode 100644 index 0000000..403ca61 --- /dev/null +++ b/src/Decompress.s @@ -0,0 +1,531 @@ + SECTION APPLEII,CODE +*** NOTE *** +* The Destination drive is chosen by putting the disk buffer address in the +* the global var Dest_Disk_Buffer !!!!! + + +************************************** +* +* DecompressDisk: +* This function does an entire decompression & encoding of a disk file +* compressed with "Dalton Disk Disintegrator 2.0" to the emulated 5 1/4" floppy. +* +* Inputs: D_FileSize = total length of compressedData (including header) +* CompressedData (with prodos header) at mem ptd by InstTbl_Var +* +* Output: Floppy Image in disk_Buffer memory... +* + + even +DecompressDisk: + movem.l d2-d4/a2-a5,-(sp) + + jsr Decomp_Init + + move.l #3,d0 ;should be a 0... + bsr ReadNBitsOld + + move.l #8,d0 + bsr ReadNBitsOld + + lea ReverseByteTbl,a0 + and.l #$00ff,d0 + move.b (a0,d0.w),d0 ;ReverseByte + + move.l d0,D_VolumeNum + + ****************** + move.l #0,d3 ;D3 = Track # +.lp35tk + lea .TrackBuffer,a0 + bsr DecompressTrackData ;decompress track data... + + move.l #15,d2 ;D2 = Sector # + +.lp16 lea .TrackBuffer,a0 + move.l d2,d0 + mulu.w #$100,d0 + lea (a0,d0.w),a0 ;get offset into track data... + + bsr Nibbleize ;take page at A0 & prepare it for encoding (rtns A0) + + move.l d3,d0 + move.l d2,d1 + bsr EncodeSector ;Encode Nibble Data into disk image... + + dbf d2,.lp16 ;do all sectors on this track... + + addq.b #1,d3 ;do all 35 tracks... + cmp.b #34,d3 + bls.b .lp35tk + + movem.l (sp)+,d2-d4/a2-a5 + rts + +.TrackBuffer ds.b $3000 + EVEN +************************************** +* PlainDiskImage_Load: +* This function takes an plain disk image (standard Unix/PC disk file format) +* and builds a perfectly encoded 16 sector disk image in memory... +* +* Note: A "plain disk image" is exactly 143,360 bytes long, and consists of +* the normal data bytes in sequential order (tracks 0 - 34, sectors 0 - 15) +* with NO header/trailer/checksums. +* +* Inputs: Plain image in buffer pointed to by InstTbl_Var +* +* Output: Floppy Image in disk_Buffer memory... +* + EVEN + +PlainDiskImage_Load: + movem.l d2-d4/a2-a5,-(sp) + + jsr Decomp_Init + move.l InstTbl_Var,D_Source ;shouldn't be any headers in this file... + + move.l #254,D_VolumeNum + + ****************** + move.l #0,d3 ;d3 = Track # +.lp35tk + move.l #15,d2 ;d2 = Sector # +.lp16 move.l InstTbl_Var,a0 + move.l d3,d0 + mulu.w #$1000,d0 ;trk offset + lea (a0,d0.l),a0 + move.l d2,d0 ;sect offset + mulu.w #$100,d0 + lea (a0,d0.w),a0 ;get offset into track data... + + bsr Nibbleize ;take page at A0 at prepare it for encoding + + move.l d3,d0 ;trk + move.l d2,d1 ;sec + bsr EncodeSector ;Auto-Inc'ing write to floppy area... + + dbf d2,.lp16 ;do all 16 sectors in each track.... + + addq.b #1,d3 ;do all 35 tracks... + cmp.b #34,d3 + bls.b .lp35tk + + movem.l (sp)+,d2-d4/a2-a5 + + rts + + + even + + even + +**************************************** +* EncodeSector: (see dos 3.3 code at $b82a) +* Takes 342 bytes of "Nibble-ized" data and encodes data to +* disk drive. (+ sector header/trailers, etc). +* +* WARNING! This function writes sector data into a specific offset in a track, +* NOT 1st searching for an area to replace! Only use to write ALL 16 sectors of a track. +* +* Inputs: Floppy Image in disk_Buffer memory (normal) +* D_VolumeNum = disk Volume # +* A0 -> 342 bytes of Nibbilized data +* D0 = Track number (0 - 34) +* D1 = Sector number (0 - 15) +* +* Output: One sector of disk data encoded to "Dest_Buffer" !!! (either buffer 1 or 2) +* Note: Rewrite these damn routines to handle simple source/dest ptrs later!!!!! + +EncodeSector: + ;do any track/sector error checking here...! + movem.l d2-d4/a2-a5,-(sp) + + move.l a0,a5 ;a5-> NibbleHunk Source + move.l d0,d3 ;d3 = track # + move.l d1,d4 ;d4 = sector # + + move.l Dest_Disk_Buffer,a4 ;Compute Track offset + mulu.w #disk_TrackLen,d0 + lea (a4,d0.l),a4 + + move.w (SectorReMapTbl.l,d4.w*2),d1 ;and sector offset + mulu.w #$18a,d1 + lea (a4,d1.l),a4 ;a4 -> Hard sector offset in disk memory + + move.w #22/2-1,d0 ;write 22 FF's (sync field) (MUST BE < 26!!) +.sync1 move.w #$ffff,(a4)+ + dbf d0,.sync1 + +.head1 move.l #$ffd5aa96,(a4)+ ;FF + addr field header D5 AA 96 [26] + + ;*** 4X4 encode the following: *** +.Vol move.l D_VolumeNum,d0 ;Volume # + move.l d0,d2 ;chksum + bsr .Do4x4 +.Trk move.l d3,d0 ;Track # + eor.l d0,d2 + bsr.b .Do4x4 +.Sec move.l d4,d0 ;Soft Sector num... + lea SectorReMapTbl,a0 ;remap soft to hard sector # + move.w (a0,d0.w*2),d0 + eor.l d0,d2 + bsr.b .Do4x4 +.ChkSum move.l d2,d0 + bsr.b .Do4x4 ;EOR'd checksum [34 bytes] + +.trail1 move.l #$deaaebff,(a4)+ ;addr field trailer DE AA EB... +.sync2 move.l #$ffffffff,(a4)+ ;5 FF's (sync field, exactly 5!) +.head2 move.w #$d5aa,(a4)+ ;Data header D5 AA AD [45 bytes] + move.b #$ad,(a4)+ + + lea $100(a5),a2 ;a2 -> NibbleHunk2 + lea EncodeLkUpTbl,a3 ;a3 -> LookUpTable (apple $ba29) (6 bit val -> disk num) + + moveq.l #0,d2 ;d2 = Accumulator + moveq.l #$56,d3 ;d3 = YReg + + bra.b .first ;Now go do 343 bytes of Data!!! + +.lp1 move.b (a2,d3),d2 ;lda $bc00,y +.first move.b -1(a2,d3),d4 ;eor $bbff,y + eor.b d4,d2 + move.b (a3,d2),(a4)+ ;tax, lda $ba29,x, write it + subq.b #1,d3 ;dey + bne.b .lp1 + + move.b (a2),d2 ;lda $bc00 + move.l a5,a2 ;a2 -> NibbleHunk + +.lp2 move.b (a2,d3),d4 ;eor $bb00,y + eor.b d4,d2 + move.b (a3,d2),(a4)+ ;tax, lda $ba29,x, write it + move.b (a2,d3),d2 ;lda $bb00,y + addq.b #1,d3 ;iny + bne.b .lp2 + move.b (a3,d2),(a4)+ ;tax, lda $ba29,x, write it (jsr $b8bb) last byte + +.trail2 move.w #$deaa,(a4)+ ;data field trailer DE AA EB... [391 bytes] + move.b #$eb,(a4)+ + + move.w #$ffff,(a4)+ ;fill in the rest like dos 3.3 does... [394 bytes] + move.b #$eb,(a4)+ + + movem.l (sp)+,d2-d4/a2-a5 + rts + +.Do4x4 move.b d0,d1 ;do 4X4 encoding of byte in D0!!! + lsl.w #7,d0 + move.b d1,d0 + or.w #$aaaa,d0 + move.w d0,(a4)+ + rts + + +;.Do4x4 move.b d0,d1 ;OLD 4X4 encoding of byte in D0!!! + lsr.b #1,d0 + or.b #$aa,d0 + move.b d0,(a4)+ + or.b #$aa,d1 + move.b d1,(a4)+ + rts + + +EncodeLkUpTbl: ;($ba29 - $ba68 in Dos 3.3) + dc.b $96,$97,$9A,$9B,$9D,$9E,$9F,$A6,$A7,$AB,$AC,$AD,$AE,$AF + dc.b $B2,$B3,$B4,$B5,$B6,$B7,$B9,$BA,$BB,$BC,$BD,$BE,$BF,$CB + dc.b $CD,$CE,$CF,$D3,$D6,$D7,$D9,$DA,$DB,$DC,$DD,$DE,$DF,$E5 + dc.b $E6,$E7,$E9,$EA,$EB,$EC,$ED,$EE,$EF,$F2,$F3,$F4,$F5,$F6 + dc.b $F7,$F9,$FA,$FB,$FC,$FD,$FE,$FF + +SectorReMapTbl: ;(soft to hard remap, $bfb8-$bfc7 in Dos 3.3) + dc.w $00,$0d,$0b,$09,$07,$05,$03,$01,$0e,$0c,$0a,$08,$06,$04,$02,$0f + dc.w $00,$0d,$0b,$09,$07,$05,$03,$01,$0e,$0c,$0a,$08,$06,$04,$02,$0f + even + +***************************************** +* Nibble-ize: (see dos 3.3 code at $b800) +* Takes a page (256 bytes) of memory & translates it into 342 bytes of "6 & 2" disk +* encoded crap as done by Apple 5 1/4" dos routines. +* +* SrcData: Nib1: Nib2: (note wrap around of sourcedata & redundant bits +* $ff-+- v (same) for first 2 entries into Nib2) +* | v +* | v $55-+- ^^o +* | ov | ^^^ +* $00-+- vo $00-+- o^^ +* +* Inputs: a0 = addr of page of memory +* Return: a0 = addr of 342 'nibble-ized' bytes (note: this is an internal static buffer) + + +Nibbleize: + movem.l d2-d4/a2-a4,-(sp) + + lea .NibbleHunk,a1 ;a1-> NibbleHunk1[$00] ($100) + lea .NibbleHunk2,a2 ;a2-> NibbleHunk2[$00] ($56) + +* ;*** Do 1st wrap-around case *** + moveq.l #0,d1 ;d1- shifted 2 bits from each of 3 #'s + move.b 1(a0),d0 ;First of 3 + lsr.b #1,d0 + roxl.b #1,d1 + lsr.b #1,d0 + roxl.b #1,d1 ;IGNORE these remaining 6 bits... + + move.b $ab(a0),d0 ;2 of 3 + lsr.b #1,d0 + roxl.b #1,d1 + lsr.b #1,d0 + roxl.b #1,d1 + move.b d0,$ab(a1) ;and keep remaining 6 bits... + + move.b $55(a0),d0 ;3 of 3 + lsr.b #1,d0 + roxl.b #1,d1 + lsr.b #1,d0 + roxl.b #1,d1 + move.b d0,$55(a1) ;and keep remaining 6 bits... + move.b d1,(a2)+ ;and keep those 6 packed bits... + +* ;*** Do 2nd wrap-around case *** + moveq.l #0,d1 ;d1- shifted 2 bits from each of 3 #'s + move.b (a0),d0 ;First of 3 + lsr.b #1,d0 + roxl.b #1,d1 + lsr.b #1,d0 + roxl.b #1,d1 ;IGNORE remaining 6 bits... + + move.b $aa(a0),d0 ;2 of 3 + lsr.b #1,d0 + roxl.b #1,d1 + lsr.b #1,d0 + roxl.b #1,d1 + move.b d0,$aa(a1) ;and keep remaining 6 bits... + + move.b $54(a0),d0 ;3 of 3 + lsr.b #1,d0 + roxl.b #1,d1 + lsr.b #1,d0 + roxl.b #1,d1 + move.b d0,$54(a1) ;and keep remaining 6 bits... + move.b d1,(a2)+ ;and keep those 6 packed bits... + + ;*** And do rest of them! *** + lea .NibbleHunk+$100,a1 ;a1-> NibbleHunk1[$100] + ;a2-> NibbleHunk2[$02] ($56) + + lea $100(a0),a0 ;a0-> SourceByte[$100] + + move.w #$54-1,d3 ;d3= countdown +.lp moveq.l #0,d1 ;d1- shifted 2 bits from each of 3 #'s + move.b -(a0),d0 ;First of 3 + lsr.b #1,d0 + roxl.b #1,d1 + lsr.b #1,d0 + roxl.b #1,d1 + move.b d0,-(a1) ;and keep remaining 6 bits... + + move.b -$56(a0),d0 ;2 of 3 + lsr.b #1,d0 + roxl.b #1,d1 + lsr.b #1,d0 + roxl.b #1,d1 + move.b d0,-$56(a1) ;and keep remaining 6 bits... + + move.b -$56*2(a0),d0 ;3 of 3 + lsr.b #1,d0 + roxl.b #1,d1 + lsr.b #1,d0 + roxl.b #1,d1 + move.b d0,-$56*2(a1) ;and keep remaining 6 bits... + + move.b d1,(a2)+ ;and keep those 6 packed bits... + + dbf d3,.lp + lea .NibbleHunk,a0 + movem.l (sp)+,d2-d4/a2-a4 + rts + + even + +.NibbleHunk ds.b 256 ;342 bytes of storage space... +.NibbleHunk2 ds.b 86 +.NibblePadding ds.b 8 + even + +****************************************** +* +*read into D_TrackMem +* +* Inputs: A0 -> Track Data dest buffer... (AT LEAST large enough to hold track data!) + +DecompressTrackData: + movem.l d2-d4/d6/a2-a6,-(sp) + + ;********** Function constants *********** + move.l a0,a5 ;A5-> Track Dest ptr (for entire function) + + lea ReverseByteTbl,a4 ;A4-> Reverse Byte Lookup table... (bytes[]) + + lea .Top_Values,a2 ;A2-> Values[] (for entire function) + move.l #16*256-1,d3 ;d4 = Num of bytes to read (incld. 0) + + move.l D_Source,a6 ;A6-> DataSource (entire function) + move.l D_SourceBit,d6 ;D6 = Bit offset (entire function) + + + move.l #19,d2 ;*** Read 20 most frequent bytes for track *** +.vals bfextu (a6){d6:8},d0 ;Read 8 Bits from stream... + addq.l #8,d6 + move.b (a4,d0.w),(a2,d2.w) ;ReverseByte & add to list... + dbf d2,.vals + +.StartNextDecode + bfextu (a6){d6:1},d0 ;read first bit from stream... + addq.l #1,d6 + tst.l d0 + bne.b .ReadCode ;if bit=0 then read unique byte, else code... + +.ReadUniqueByte + bfextu (a6){d6:8},d0 ;*** bit=0; read 8 bits as a unique byte *** + addq.l #8,d6 + move.b (a4,d0.w),(a5)+ ;ReverseByte & AddByte + + subq.l #1,d3 ;More to read? + bpl.b .StartNextDecode + bra.b .done + +.ReadCode: + lea .CmpList,a3 ;a3 = addr of CmpList (rdCode section only) + move.l #19,d4 ;d4 = Index (of Values[]) (rdCode section only) + + moveq.l #0,d0 + +.CodeLp move.b (a3)+,d1 ;cmpList + bpl.b .CdVal + +.Cd1Bit lsl.b #1,d0 ;cmpTbl=-1 *** Read another bit into code *** + move.b d0,-(sp) + bfextu (a6){d6:1},d0 ;Read 1 Bit from stream... + addq.l #1,d6 + or.b (sp)+,d0 + bra.b .CodeLp ;and repeat + +.CdVal cmp.b d1,d0 ;it the code so far = the val in table? + beq.b .match + subq.l #1,d4 + bpl.b .CodeLp ;go again if still possible table match... + + bfextu (a6){d6:1},d0 ;else read 1 last bit from stream (discarded) + addq.l #1,d6 + +.repeat ;*** REPEATing byte case *** + bfextu (a6){d6:8},d0 ;Read 8 Bits from stream... + addq.l #8,d6 + move.b (a4,d0.w),d2 ;ReverseByte, d2 = RepeatValue + bfextu (a6){d6:8},d4 ;Read 8 Bits from stream... (into d4) + addq.l #8,d6 + move.b (a4,d4.w),d4 ;ReverseByte, d4 = Count (0=255) + subq.b #1,d4 ;Prepare it for DBF countdown (to -1) +.rptLp move.b d2,(a5)+ ;AddByte + subq.l #1,d3 + dbmi d4,.rptLp ;Do 'x' times or until max bytes read! + + tst.l d3 ;More to read? + bpl.b .StartNextDecode + bra.b .done + +.match move.b (a2,d4),(a5)+ ;else cmpList[]==code; use Values[d4] & AddByte + + subq.l #1,d3 ;More to read? + bpl.b .StartNextDecode +; bra.b .done + +.done + move.l d6,D_SourceBit ;D6 = Bit offset (entire function) + + + movem.l (sp)+,d2-d4/d6/a2-a6 + rts + + +.Top_Values ds.b 20 + +.CmpList dc.b -1,-1,-1,4,1,-1,15,14,12,11,10,6,5,-1 + dc.b 27,15,9,8,3,2,1,0,-1,53,29,28,-1,-2 ;-1 & -2 no longer needed... + + + CNOP 0,4 + +************************************ +* Inputs: d0 = # of bits to read (normally 8, 3, 2, or 1) +* Return: d0 = bits read (low order) + +ReadNBitsOld: + + move.l D_Source,a0 + move.l D_SourceBit,d1 + add.l d0,D_SourceBit ;inc bit cntr by bits read... + bfextu (a0){d1:d0},d0 + + rts + + +ReverseByteTbl: *** This is a lookup table of bytes with bit order reversed *** + dc.b $00,$80,$40,$c0,$20,$a0,$60,$e0,$10,$90,$50,$d0,$30,$b0,$70,$f0 + dc.b $08,$88,$48,$c8,$28,$a8,$68,$e8,$18,$98,$58,$d8,$38,$b8,$78,$f8 + dc.b $04,$84,$44,$c4,$24,$a4,$64,$e4,$14,$94,$54,$d4,$34,$b4,$74,$f4 + dc.b $0c,$8c,$4c,$cc,$2c,$ac,$6c,$ec,$1c,$9c,$5c,$dc,$3c,$bc,$7c,$fc + dc.b $02,$82,$42,$c2,$22,$a2,$62,$e2,$12,$92,$52,$d2,$32,$b2,$72,$f2 + dc.b $0a,$8a,$4a,$ca,$2a,$aa,$6a,$ea,$1a,$9a,$5a,$da,$3a,$ba,$7a,$fa + dc.b $06,$86,$46,$c6,$26,$a6,$66,$e6,$16,$96,$56,$d6,$36,$b6,$76,$f6 + dc.b $0e,$8e,$4e,$ce,$2e,$ae,$6e,$ee,$1e,$9e,$5e,$de,$3e,$be,$7e,$fe + dc.b $01,$81,$41,$c1,$21,$a1,$61,$e1,$11,$91,$51,$d1,$31,$b1,$71,$f1 + dc.b $09,$89,$49,$c9,$29,$a9,$69,$e9,$19,$99,$59,$d9,$39,$b9,$79,$f9 + dc.b $05,$85,$45,$c5,$25,$a5,$65,$e5,$15,$95,$55,$d5,$35,$b5,$75,$f5 + dc.b $0d,$8d,$4d,$cd,$2d,$ad,$6d,$ed,$1d,$9d,$5d,$dd,$3d,$bd,$7d,$fd + dc.b $03,$83,$43,$c3,$23,$a3,$63,$e3,$13,$93,$53,$d3,$33,$b3,$73,$f3 + dc.b $0b,$8b,$4b,$cb,$2b,$ab,$6b,$eb,$1b,$9b,$5b,$db,$3b,$bb,$7b,$fb + dc.b $07,$87,$47,$c7,$27,$a7,$67,$e7,$17,$97,$57,$d7,$37,$b7,$77,$f7 + dc.b $0f,$8f,$4f,$cf,$2f,$af,$6f,$ef,$1f,$9f,$5f,$df,$3f,$bf,$7f,$ff + even + +************************************* +* Inputs: "D_FileSize" +* +* Output: Sets up "D_Source" "D_SourceBit" "D_SourceBitEnd" + +Decomp_Init: + + move.l InstTbl_Var,D_Source +.Header move.l InstTbl_Var,a0 + cmp.w #$0a47,(a0) ;first 2 bytes in ProDos header... + bne .Dos3_3 + cmp.b #$4c,2(a0) ;Third byte in ProDos header... + bne .Dos3_3 + +.ProDos add.l #$7c,D_Source ;ProDos header; add $80 bytes... +.Dos3_3 add.l #$04,D_Source ;Dos 3.3; 4 byte header... + + move.l #0,D_SourceBit + + move.l D_FileSize,d0 ;do we ever set this??? FIX LATER!!! + sub.l #$80,d0 + mulu.l #8,d0 + move.l d0,D_SourceBitEnd + rts + +* Globals for these functions... * +************************************ +D_Source ds.l 1 ;Source addr of decompression data... +D_SourceBit ds.l 1 ;Source bit offset of data... +D_SourceBitEnd ds.l 1 ;Highest bit offset allowable... + +D_FileSize ds.l 1 ;Size in Bytes of file read... +D_VolumeNum ds.l 1 ;Volume # of disk... +;D_TrackNum ds.l 1 +;D_SectorNum ds.l 1 + +************************************* + even diff --git a/src/HiResMap.s b/src/HiResMap.s new file mode 100644 index 0000000..81694ab --- /dev/null +++ b/src/HiResMap.s @@ -0,0 +1,627 @@ +* Needs to be included in file with "WinRastPort" set and FPutByte available. +* enter with: a0=address to write ($2000-$3fff for PBHgr1), and d1=data. +* MAJOR OPT: At entry to PBHgrx, checks to see if mem is already same as data, if so, return! + + SECTION HiResAPPLEII,CODE + CNOP 0,4 +PBHgr1 cmp.b (Mem_Ptr,a0.l),d1 + beq.b .NoShow + move.b d1,(Mem_Ptr,a0.l) ;FPUTBYTE + move.l -2(Mem_Ptr,a0.l),d0 ;2 pre-data bytes & 1 post-data byte!!!!! + ;bits we want: (H= HighBit, #=PixelData) + ;xxxx xxxx H654 3210 H654 3210 H654 3210 (14 sig bits) + ; --- --------- - -- + + swap d0 [04] + lsr.b #5,d0 [04] ;now got: + swap d0 [04] ;xxxx xxxx oooo oH65 H654 3210 Hxxx xx10 + ; --- ---- ---- - -- + lsl.l #1,d0 [04] ;xxxx xxxo oooo H65H 6543 210H xxxx x10x + lsl.b #5,d0 [04] ;xxxx xxxo oooo H65H 6543 210H 10xo oooo + lsr.l #6,d0 [04] ;xxxx xxxx xxxx xooo ooH6 5H65 4321 0H10 + ; -- ---- ---- ---- + ; total = [ 24 ] ! + ;d0 = clean word of all video data (index w/ it later) + move.l d0,a6 + + move.l a0,d0 + lea HgrHorByteLookup,a1 + and.w #$7f,d0 [06] ;(later make list 256 words & remove this line?) + move.w (a1,d0.w*2),d0 ;D0 has horizontal byte offset! (0->39 *7+20 for BFINS) CLEAN! + beq.b .NoShow ;its a video hole... no draw.... + bmi .Hgr1Edge +.AfterEdge: + move.l a0,d1 + lsr.w #3,d1 ;/8 for list optimization... (from 8192 bytes to 1024) + and.w #$3ff,d1 ;mask off above #1023... (we didnt -$2000 from addr) + lea HgrLineLookup,a1 + move.w (a1,d1.w*2),d1 ;D1 Has vertical Line # !!!! (0-191) * 40 (BytesPerRow) + ;d1 = Y*40(bytesPerRow) + move.l Hgr1_Planes,a0 + add.l d1,a0 ; a0 = Planet1 Line StartLoc + btst.l #0,d0 + bne.b .Odd +.Even ;a0 = Plane1 Line StartLoc + ;d0 = BitField Offset (for solid grfx & centered) + move.l HiResDrawTbl,a1 + move.l a6,d1 ;swap nibbles on %H765 4321 to 1234 567o + + btst.l #10,d1 + sne.b d1 + bfins d1,(LINES*2*40.w,a0){d0:7} ;if data hi bit set, make $ff, else $00 + + subq.l #1,d0 + + move.l (a1,a6.w*4),d1 + bfins d1,(a0){d0:9} ;plane 1 + + swap d1 + bfins d1,(LINES*40.w,a0){d0:9} ;plane 2 + +.NoShow + rts + CNOP 0,4 +.Odd ;a0 = Plane1 StartLoc + ;d0 = Bitfield offset + move.l HiResDrawTbl,a1 + move.l a6,d1 ;swap nibbles on %H765 4321 to 1234 567o + + btst.l #10,d1 + sne.b d1 + bfins d1,(LINES*40*2.w,a0){d0:7} ;if data hi bit set, make $ff, else $00 + + subq.l #1,d0 + + move.l (a1,a6.w*4),d1 + bfins d1,(LINES*40.w,a0){d0:9} ;plane 2 + + swap d1 + bfins d1,(a0){d0:9} ;plane 1 + + rts + +.Hgr1Edge: ;determine which edge & mask off... + move.l a6,d1 + btst.l #14,d0 + beq.b .RtEdge +.LtEdge and.l #$07ff,d1 ;dont want data from previous line + move.l d1,a6 + and.w #$0fff,d0 ;and remove this Edge Identifying bits... + bra .AfterEdge +.RtEdge and.l #$fff8,d1 ;dont want data from next line + move.l d1,a6 + and.w #$0fff,d0 + bra .AfterEdge + + CNOP 0,4 +.addr ds.l 1 + dc.b 'K'+1,'E'+2,'V'+3,'I'+4,'N'+5,'K'+6,'R'+7,'A'+8,'L'+9,'I'+10,'A'+11,'N'+12 + +************************************************8 + + CNOP 0,4 +PBHgr2 cmp.b (Mem_Ptr,a0.l),d1 + beq.b .NoShow + move.b d1,(Mem_Ptr,a0.l) ;FPUTBYTE + move.l -2(Mem_Ptr,a0.l),d0 ;2 pre-data bytes & 1 post-data byte!!!!! + ;bits we want: (H= HighBit, #=PixelData) + ;xxxx xxxx H654 3210 H654 3210 H654 3210 (14 sig bits) + ; --- --------- - -- + + swap d0 [04] + lsr.b #5,d0 [04] ;now got: + swap d0 [04] ;xxxx xxxx xxxx xH65 H654 3210 Hxxx xx10 + ; --- ---- ---- - -- + lsl.l #1,d0 [04] ;xxxx xxxx xxxx H65H 6543 210H xxxx x10x + lsl.b #5,d0 [04] ;xxxx xxxx xxxx H65H 6543 210H 10xx xxxx + lsr.l #6,d0 [04] ;xxxx xxxx xxxx xxxx xxH6 5H65 4321 0H10 + ; -- ---- ---- ---- + ; total = [ 24 ] ! + move.l d0,a6 + + move.l a0,d0 + lea HgrHorByteLookup,a1 + and.w #$7f,d0 [06] ;(later make list 256 words & remove this line?) + move.w (a1,d0.w*2),d0 ;D0 has horizontal byte offset! (0->39 *7+20 for BFINS) CLEAN! + beq.b .NoShow ;its a video hole... no draw.... + bmi.b .Hgr2Edge +.AfterEdge: + move.l a0,d1 + lsr.w #3,d1 ;/8 for list optimization... (from 8192 bytes to 1024) + and.w #$3ff,d1 ;mask off above #1023... (we didnt -$4000 from addr) + lea HgrLineLookup,a1 + move.w (a1,d1.w*2),d1 ;D1 Has vertical Line # !!!! (0-191) * 40 (bytesPerRow) + + move.l Hgr2_Planes,a0 + add.l d1,a0 ; a0 = Planet1 Line StartLoc + btst.l #0,d0 + bne.b .Odd +.Even ;a0 = Plane1 Line StartLoc + ;d0 = BitField Offset (for solid grfx & centered) + move.l HiResDrawTbl,a1 + move.l a6,d1 ;swap nibbles on %H765 4321 to 1234 567o + + btst.l #10,d1 + sne.b d1 + bfins d1,(LINES*40*2.w,a0){d0:7} ;if data hi bit set, make $ff, else $00 + + subq.l #1,d0 + + move.l (a1,a6.w*4),d1 ;+1 for OddOffset... + bfins d1,(a0){d0:9} ;plane 1 + + swap d1 + bfins d1,(LINES*40.w,a0){d0:9} ;plane 2 + +.NoShow + rts + CNOP 0,4 +.Odd ;a0 = Plane1 StartLoc + ;d0 = Bitfield offset + move.l HiResDrawTbl,a1 + move.l a6,d1 ;swap nibbles on %H765 4321 to 1234 567o + + btst.l #10,d1 + sne.b d1 + bfins d1,(LINES*40*2.w,a0){d0:7} ;if data hi bit set, make $ff, else $00 + + subq.l #1,d0 + + move.l (a1,a6.w*4),d1 + bfins d1,(LINES*40.w,a0){d0:9} ;plane 2 + + swap d1 + bfins d1,(a0){d0:9} ;plane 1 + + rts + +.Hgr2Edge: ;determine which edge & mask off... + move.l a6,d1 + btst.l #14,d0 + beq.b .RtEdge +.LtEdge and.l #$07ff,d1 ;dont want data from previous line + move.l d1,a6 + and.w #$0fff,d0 ;and remove this Edge Identifying bits... + bra .AfterEdge +.RtEdge and.l #$fff8,d1 ;dont want data from next line + move.l d1,a6 + and.w #$0fff,d0 + bra .AfterEdge + +************************************************8 + + CNOP 0,4 +PBHgr1Top: + cmp.b (Mem_Ptr,a0.l),d1 + beq.b .NoShow + move.b d1,(Mem_Ptr,a0.l) ;FPUTBYTE + move.l -2(Mem_Ptr,a0.l),d0 ;2 pre-data bytes & 1 post-data byte!!!!! + ;bits we want: (H= HighBit, #=PixelData) + ;xxxx xxxx H654 3210 H654 3210 H654 3210 (14 sig bits) + ; --- --------- - -- + + swap d0 [04] + lsr.b #5,d0 [04] ;now got: + swap d0 [04] ;xxxx xxxx oooo oH65 H654 3210 Hxxx xx10 + ; --- ---- ---- - -- + lsl.l #1,d0 [04] ;xxxx xxxo oooo H65H 6543 210H xxxx x10x + lsl.b #5,d0 [04] ;xxxx xxxo oooo H65H 6543 210H 10xo oooo + lsr.l #6,d0 [04] ;xxxx xxxx xxxx xooo ooH6 5H65 4321 0H10 + ; -- ---- ---- ---- + ; total = [ 24 ] ! + ;d0 = clean word of all video data (index w/ it later) + move.l d0,a6 + + move.l a0,d0 + lea HgrHorByteLookup,a1 + and.w #$7f,d0 [06] ;(later make list 256 words & remove this line?) + move.w (a1,d0.w*2),d0 ;D0 has horizontal byte offset! (0->39 *7+20 for BFINS) CLEAN! + beq.b .NoShow ;its a video hole... no draw.... + bmi .Hgr1Edge +.AfterEdge: + move.l a0,d1 + lsr.w #3,d1 ;/8 for list optimization... (from 8192 bytes to 1024) + and.w #$3ff,d1 ;mask off above #1023... (we didnt -$2000 from addr) + lea HgrLineLookup,a1 + move.w (a1,d1.w*2),d1 ;D1 Has vertical Line # !!!! (0-191) * 40 (BytesPerRow) + ;d1 = Y*40(bytesPerRow) + cmp.w #40*160,d1 + bhs.b .NoShow + + move.l Hgr1_Planes,a0 + add.l d1,a0 ; a0 = Planet1 Line StartLoc + btst.l #0,d0 + bne.b .Odd +.Even ;a0 = Plane1 Line StartLoc + ;d0 = BitField Offset (for solid grfx & centered) + move.l HiResDrawTbl,a1 + move.l a6,d1 ;swap nibbles on %H765 4321 to 1234 567o + + btst.l #10,d1 + sne.b d1 + bfins d1,(LINES*2*40.w,a0){d0:7} ;if data hi bit set, make $ff, else $00 + + subq.l #1,d0 + + move.l (a1,a6.w*4),d1 + bfins d1,(a0){d0:9} ;plane 1 + + swap d1 + bfins d1,(LINES*40.w,a0){d0:9} ;plane 2 + +.NoShow + rts + CNOP 0,4 +.Odd ;a0 = Plane1 StartLoc + ;d0 = Bitfield offset + move.l HiResDrawTbl,a1 + move.l a6,d1 ;swap nibbles on %H765 4321 to 1234 567o + + btst.l #10,d1 + sne.b d1 + bfins d1,(LINES*40*2.w,a0){d0:7} ;if data hi bit set, make $ff, else $00 + + subq.l #1,d0 + + move.l (a1,a6.w*4),d1 + bfins d1,(LINES*40.w,a0){d0:9} ;plane 2 + + swap d1 + bfins d1,(a0){d0:9} ;plane 1 + + rts + +.Hgr1Edge: ;determine which edge & mask off... + move.l a6,d1 + btst.l #14,d0 + beq.b .RtEdge +.LtEdge and.l #$07ff,d1 ;dont want data from previous line + move.l d1,a6 + and.w #$0fff,d0 ;and remove this Edge Identifying bits... + bra .AfterEdge +.RtEdge and.l #$fff8,d1 ;dont want data from next line + move.l d1,a6 + and.w #$0fff,d0 + bra .AfterEdge + + CNOP 0,4 +.addr ds.l 1 + dc.b 'K'+1,'E'+2,'V'+3,'I'+4,'N'+5,'K'+6,'R'+7,'A'+8,'L'+9,'I'+10,'A'+11,'N'+12 + +************************************************8 + + CNOP 0,4 +PBHgr2Top: + cmp.b (Mem_Ptr,a0.l),d1 + beq.b .NoShow + move.b d1,(Mem_Ptr,a0.l) ;FPUTBYTE + move.l -2(Mem_Ptr,a0.l),d0 ;2 pre-data bytes & 1 post-data byte!!!!! + ;bits we want: (H= HighBit, #=PixelData) + ;xxxx xxxx H654 3210 H654 3210 H654 3210 (14 sig bits) + ; --- --------- - -- + + swap d0 [04] + lsr.b #5,d0 [04] ;now got: + swap d0 [04] ;xxxx xxxx xxxx xH65 H654 3210 Hxxx xx10 + ; --- ---- ---- - -- + lsl.l #1,d0 [04] ;xxxx xxxx xxxx H65H 6543 210H xxxx x10x + lsl.b #5,d0 [04] ;xxxx xxxx xxxx H65H 6543 210H 10xx xxxx + lsr.l #6,d0 [04] ;xxxx xxxx xxxx xxxx xxH6 5H65 4321 0H10 + ; -- ---- ---- ---- + ; total = [ 24 ] ! + move.l d0,a6 + + move.l a0,d0 + lea HgrHorByteLookup,a1 + and.w #$7f,d0 [06] ;(later make list 256 words & remove this line?) + move.w (a1,d0.w*2),d0 ;D0 has horizontal byte offset! (0->39 *7+20 for BFINS) CLEAN! + beq.b .NoShow ;its a video hole... no draw.... + bmi.b .Hgr2Edge +.AfterEdge: + move.l a0,d1 + lsr.w #3,d1 ;/8 for list optimization... (from 8192 bytes to 1024) + and.w #$3ff,d1 ;mask off above #1023... (we didnt -$4000 from addr) + lea HgrLineLookup,a1 + move.w (a1,d1.w*2),d1 ;D1 Has vertical Line # !!!! (0-191) * 40 (bytesPerRow) + + cmp.w #40*160,d1 + bhs.b .NoShow + + move.l Hgr2_Planes,a0 + add.l d1,a0 ; a0 = Planet1 Line StartLoc + btst.l #0,d0 + bne.b .Odd +.Even ;a0 = Plane1 Line StartLoc + ;d0 = BitField Offset (for solid grfx & centered) + move.l HiResDrawTbl,a1 + move.l a6,d1 ;swap nibbles on %H765 4321 to 1234 567o + + btst.l #10,d1 + sne.b d1 + bfins d1,(LINES*40*2.w,a0){d0:7} ;if data hi bit set, make $ff, else $00 + + subq.l #1,d0 + + move.l (a1,a6.w*4),d1 ;+1 for OddOffset... + bfins d1,(a0){d0:9} ;plane 1 + + swap d1 + bfins d1,(LINES*40.w,a0){d0:9} ;plane 2 + +.NoShow + rts + CNOP 0,4 +.Odd ;a0 = Plane1 StartLoc + ;d0 = Bitfield offset + move.l HiResDrawTbl,a1 + move.l a6,d1 ;swap nibbles on %H765 4321 to 1234 567o + + btst.l #10,d1 + sne.b d1 + bfins d1,(LINES*40*2.w,a0){d0:7} ;if data hi bit set, make $ff, else $00 + + subq.l #1,d0 + + move.l (a1,a6.w*4),d1 + bfins d1,(LINES*40.w,a0){d0:9} ;plane 2 + + swap d1 + bfins d1,(a0){d0:9} ;plane 1 + + rts + +.Hgr2Edge: ;determine which edge & mask off... + move.l a6,d1 + btst.l #14,d0 + beq.b .RtEdge +.LtEdge and.l #$07ff,d1 ;dont want data from previous line + move.l d1,a6 + and.w #$0fff,d0 ;and remove this Edge Identifying bits... + bra .AfterEdge +.RtEdge and.l #$fff8,d1 ;dont want data from next line + move.l d1,a6 + and.w #$0fff,d0 + bra .AfterEdge + + CNOP 0,4 +************************************************8 +* enter with: a0=address to write ($2000-$3fff for PBHgr1), and d1=data. +* + +Hgr1Refresh: + movem.l a2-a5/d2-d7,-(sp) + move.l Mem_PtrVar,Mem_Ptr ;a4 (USED!) + move.l HiResDrawTbl,a1 ;a1 -> HiRes Draw Table (Preserve!) + +* Step through all the HGR line addresses... + + move.l #$2000,a3 ;a3 = main base counter... + move.l a3,a2 ;a2 -> Base of HGR line we are doing (preserve!) + move.l Hgr1_Planes,a5 ;a5 -> Base of BitPlane memory (top line to start) + +.loop + move.l a2,a0 + +;PBHgr1-EntireLine! + move.w #$0,d5 ;byte counter for full line... + move.w #20-7,d4 ;always start with leftmost byte...! + + +.NextByte + + move.l -2(Mem_Ptr,a0.l),d0 ;2 pre-data bytes & 1 post-data byte!!!!! + ;bits we want: (H= HighBit, #=PixelData) + ;xxxx xxxx H654 3210 H654 3210 H654 3210 (14 sig bits) + ; --- --------- - -- + + swap d0 [04] + lsr.b #5,d0 [04] ;now got: + swap d0 [04] ;xxxx xxxx xxxx xH65 H654 3210 Hxxx xx10 + ; --- ---- ---- - -- + lsl.l #1,d0 [04] ;xxxx xxxx xxxx H65H 6543 210H xxxx x10x + lsl.b #5,d0 [04] ;xxxx xxxx xxxx H65H 6543 210H 10xx xxxx + lsr.l #6,d0 [04] ;xxxx xxxx xxxx xxxx xxH6 5H65 4321 0H10 + ; -- ---- ---- ---- + ; total = [ 24 ] ! + move.l d0,a6 + ;d0 = clean word of all video data (index w/ it later) + + + addq.w #7,d4 ;next byte Horizontal Offset + + + btst.l #0,d4 ;is this an even or odd byte? + bne.b .Odd +.Even ;a0 = Plane1 Line StartLoc + ;d0 = BitField Offset (for solid grfx & centered) +; move.l HiResDrawTbl,a1 + move.l a6,d1 ;swap nibbles on %H765 4321 to 1234 567o + + btst.l #10,d1 + sne.b d1 + bfins d1,(LINES*40*2.w,a5){d4:7} ;if data hi bit set, make $ff, else $00 + + subq.l #1,d4 + + move.l (a1,a6.w*4),d1 + bfins d1,(a5){d4:9} ;plane 1 + + swap d1 + bfins d1,(LINES*40.w,a5){d4:9} ;plane 2 + addq.l #1,d4 + +.again + move.l -1(Mem_Ptr,a0.l),d0 ;2 pre-data bytes & 1 post-data byte!!!!! + ;bits we want: (H= HighBit, #=PixelData) + ;xxxx xxxx H654 3210 H654 3210 H654 3210 (14 sig bits) + ; --- --------- - -- + + swap d0 [04] + lsr.b #5,d0 [04] ;now got: + swap d0 [04] ;xxxx xxxx xxxx xH65 H654 3210 Hxxx xx10 + ; --- ---- ---- - -- + lsl.l #1,d0 [04] ;xxxx xxxx xxxx H65H 6543 210H xxxx x10x + lsl.b #5,d0 [04] ;xxxx xxxx xxxx H65H 6543 210H 10xx xxxx + lsr.l #6,d0 [04] ;xxxx xxxx xxxx xxxx xxH6 5H65 4321 0H10 + ; -- ---- ---- ---- + ; total = [ 24 ] ! + move.l d0,a6 + ;d0 = clean word of all video data (index w/ it later) + + addq.w #7,d4 ;next byte Horizontal Offset + +.Odd ;a0 = Plane1 StartLoc + ;d0 = Bitfield offset +; move.l HiResDrawTbl,a1 + move.l a6,d1 ;swap nibbles on %H765 4321 to 1234 567o + + btst.l #10,d1 + sne.b d1 + bfins d1,(LINES*40*2.w,a5){d4:7} ;if data hi bit set, make $ff, else $00 + + subq.l #1,d4 + + move.l (a1,a6.w*4),d1 + bfins d1,(LINES*40.w,a5){d4:9} ;plane 2 + + swap d1 + bfins d1,(a5){d4:9} ;plane 1 + + addq.l #1,d4 + bra .done + + +.done + addq.w #2,d5 + lea (a2,d5.w),a0 ;set next byte addr... + cmp.w #40,d5 + blo .NextByte + + add.l #40,a5 ;inc BitPlane ptr to next line... + + add.w #$400,a2 ;$2000 -> $2400 -> ... -> $3800 (each line in grp of 8) + cmp.w #$4000,a2 + blo .loop + sub.w #$2000-$80,a2 + cmp.w #$2400,a2 ;$2000 -> $2080 -> $2100 -> $2180 -> ... -> $2380 + blo .loop + + add.w #$28,a3 ;from $2000 -> $2028 -> $2050 + move.w a3,a2 + cmp.w #$2050,a3 + bls .loop + + movem.l (sp)+,a2-a5/d2-d7 + rts + +************************************************** +** HorizByte is 127-Word lookup table. Using the low-end mask of the txt / hgr address, +** This returns the HORizontal BYTE offset...!!! (0-39! (+ special)) +** (00 -> 39, *7 for BFINS offset field (7 pixels per byte), + 20 to center on screen) +** 0 = Video Hole (no visible effect) +** - = Its an edge byte (left or right extreme) (numeric offset in lower 9 bits, 0 -> 293) +** bit 14 = boolean LEFT side (1=left side, 0=right side) +** so, left edge bytes add +$C000, right edge bytes add +$8000 + + SECTION TABLES,DATA + CNOP 0,4 +HgrHorByteLookup + dc.w 00*7+20+$c000,01*7+20,02*7+20,03*7+20,04*7+20,05*7+20,06*7+20,07*7+20,08*7+20,09*7+20 + dc.w 10*7+20,11*7+20,12*7+20,13*7+20,14*7+20,15*7+20,16*7+20,17*7+20,18*7+20,19*7+20 + dc.w 20*7+20,21*7+20,22*7+20,23*7+20,24*7+20,25*7+20,26*7+20,27*7+20,28*7+20,29*7+20 + dc.w 30*7+20,31*7+20,32*7+20,33*7+20,34*7+20,35*7+20,36*7+20,37*7+20,38*7+20,39*7+20+$8000 + dc.w 00*7+20+$c000,01*7+20,02*7+20,03*7+20,04*7+20,05*7+20,06*7+20,07*7+20,08*7+20,09*7+20 + dc.w 10*7+20,11*7+20,12*7+20,13*7+20,14*7+20,15*7+20,16*7+20,17*7+20,18*7+20,19*7+20 + dc.w 20*7+20,21*7+20,22*7+20,23*7+20,24*7+20,25*7+20,26*7+20,27*7+20,28*7+20,29*7+20 + dc.w 30*7+20,31*7+20,32*7+20,33*7+20,34*7+20,35*7+20,36*7+20,37*7+20,38*7+20,39*7+20+$8000 + dc.w 00*7+20+$c000,01*7+20,02*7+20,03*7+20,04*7+20,05*7+20,06*7+20,07*7+20,08*7+20,09*7+20 + dc.w 10*7+20,11*7+20,12*7+20,13*7+20,14*7+20,15*7+20,16*7+20,17*7+20,18*7+20,19*7+20 + dc.w 20*7+20,21*7+20,22*7+20,23*7+20,24*7+20,25*7+20,26*7+20,27*7+20,28*7+20,29*7+20 + dc.w 30*7+20,31*7+20,32*7+20,33*7+20,34*7+20,35*7+20,36*7+20,37*7+20,38*7+20,39*7+20+$8000 + dc.w 0,0,0,0,0,0,0,0 + +* Test for "Quick & Dirty" video display. List of byte offsets from left of screen... +QuickHgrHorByteLookup + dc.w 00,01,02,03,04,05,06,07,08,09 + dc.w 10,11,12,13,14,15,16,17,18,19 + dc.w 20,21,22,23,24,25,26,27,28,29 + dc.w 30,31,32,33,34,35,36,37,38,39 + dc.w 00,01,02,03,04,05,06,07,08,09 + dc.w 10,11,12,13,14,15,16,17,18,19 + dc.w 20,21,22,23,24,25,26,27,28,29 + dc.w 30,31,32,33,34,35,36,37,38,39 + dc.w 00,01,02,03,04,05,06,07,08,09 + dc.w 10,11,12,13,14,15,16,17,18,19 + dc.w 20,21,22,23,24,25,26,27,28,29 + dc.w 30,31,32,33,34,35,36,37,38,39 + dc.w -1,-1,-1,-1,-1,-1,-1,-1 + +** 1024 Entries. Take HGR address, offset to $0000, /8 (to eliminate repetition) +** Video "Holes" are listed as 0, for safety. Catch by checking horizontal byte offset. +** Line # * 40 (bytes per line) as optimization... + +HgrLineLookup: + dc.w 0*40,0*40,0*40,0*40,0*40,64*40,64*40,64*40,64*40,64*40,128*40,128*40,128*40,128*40,128*40,0 + dc.w 8*40,8*40,8*40,8*40,8*40,72*40,72*40,72*40,72*40,72*40,136*40,136*40,136*40,136*40,136*40,0 + dc.w 16*40,16*40,16*40,16*40,16*40,80*40,80*40,80*40,80*40,80*40,144*40,144*40,144*40,144*40,144*40,0 + dc.w 24*40,24*40,24*40,24*40,24*40,88*40,88*40,88*40,88*40,88*40,152*40,152*40,152*40,152*40,152*40,0 + dc.w 32*40,32*40,32*40,32*40,32*40,96*40,96*40,96*40,96*40,96*40,160*40,160*40,160*40,160*40,160*40,0 + dc.w 40*40,40*40,40*40,40*40,40*40,104*40,104*40,104*40,104*40,104*40,168*40,168*40,168*40,168*40,168*40,0 + dc.w 48*40,48*40,48*40,48*40,48*40,112*40,112*40,112*40,112*40,112*40,176*40,176*40,176*40,176*40,176*40,0 + dc.w 56*40,56*40,56*40,56*40,56*40,120*40,120*40,120*40,120*40,120*40,184*40,184*40,184*40,184*40,184*40,0 + dc.w 1*40,1*40,1*40,1*40,1*40,65*40,65*40,65*40,65*40,65*40,129*40,129*40,129*40,129*40,129*40,0 + dc.w 9*40,9*40,9*40,9*40,9*40,73*40,73*40,73*40,73*40,73*40,137*40,137*40,137*40,137*40,137*40,0 + dc.w 17*40,17*40,17*40,17*40,17*40,81*40,81*40,81*40,81*40,81*40,145*40,145*40,145*40,145*40,145*40,0 + dc.w 25*40,25*40,25*40,25*40,25*40,89*40,89*40,89*40,89*40,89*40,153*40,153*40,153*40,153*40,153*40,0 + dc.w 33*40,33*40,33*40,33*40,33*40,97*40,97*40,97*40,97*40,97*40,161*40,161*40,161*40,161*40,161*40,0 + dc.w 41*40,41*40,41*40,41*40,41*40,105*40,105*40,105*40,105*40,105*40,169*40,169*40,169*40,169*40,169*40,0 + dc.w 49*40,49*40,49*40,49*40,49*40,113*40,113*40,113*40,113*40,113*40,177*40,177*40,177*40,177*40,177*40,0 + dc.w 57*40,57*40,57*40,57*40,57*40,121*40,121*40,121*40,121*40,121*40,185*40,185*40,185*40,185*40,185*40,0 + dc.w 2*40,2*40,2*40,2*40,2*40,66*40,66*40,66*40,66*40,66*40,130*40,130*40,130*40,130*40,130*40,0 + dc.w 10*40,10*40,10*40,10*40,10*40,74*40,74*40,74*40,74*40,74*40,138*40,138*40,138*40,138*40,138*40,0 + dc.w 18*40,18*40,18*40,18*40,18*40,82*40,82*40,82*40,82*40,82*40,146*40,146*40,146*40,146*40,146*40,0 + dc.w 26*40,26*40,26*40,26*40,26*40,90*40,90*40,90*40,90*40,90*40,154*40,154*40,154*40,154*40,154*40,0 + dc.w 34*40,34*40,34*40,34*40,34*40,98*40,98*40,98*40,98*40,98*40,162*40,162*40,162*40,162*40,162*40,0 + dc.w 42*40,42*40,42*40,42*40,42*40,106*40,106*40,106*40,106*40,106*40,170*40,170*40,170*40,170*40,170*40,0 + dc.w 50*40,50*40,50*40,50*40,50*40,114*40,114*40,114*40,114*40,114*40,178*40,178*40,178*40,178*40,178*40,0 + dc.w 58*40,58*40,58*40,58*40,58*40,122*40,122*40,122*40,122*40,122*40,186*40,186*40,186*40,186*40,186*40,0 + dc.w 3*40,3*40,3*40,3*40,3*40,67*40,67*40,67*40,67*40,67*40,131*40,131*40,131*40,131*40,131*40,0 + dc.w 11*40,11*40,11*40,11*40,11*40,75*40,75*40,75*40,75*40,75*40,139*40,139*40,139*40,139*40,139*40,0 + dc.w 19*40,19*40,19*40,19*40,19*40,83*40,83*40,83*40,83*40,83*40,147*40,147*40,147*40,147*40,147*40,0 + dc.w 27*40,27*40,27*40,27*40,27*40,91*40,91*40,91*40,91*40,91*40,155*40,155*40,155*40,155*40,155*40,0 + dc.w 35*40,35*40,35*40,35*40,35*40,99*40,99*40,99*40,99*40,99*40,163*40,163*40,163*40,163*40,163*40,0 + dc.w 43*40,43*40,43*40,43*40,43*40,107*40,107*40,107*40,107*40,107*40,171*40,171*40,171*40,171*40,171*40,0 + dc.w 51*40,51*40,51*40,51*40,51*40,115*40,115*40,115*40,115*40,115*40,179*40,179*40,179*40,179*40,179*40,0 + dc.w 59*40,59*40,59*40,59*40,59*40,123*40,123*40,123*40,123*40,123*40,187*40,187*40,187*40,187*40,187*40,0 + dc.w 4*40,4*40,4*40,4*40,4*40,68*40,68*40,68*40,68*40,68*40,132*40,132*40,132*40,132*40,132*40,0 + dc.w 12*40,12*40,12*40,12*40,12*40,76*40,76*40,76*40,76*40,76*40,140*40,140*40,140*40,140*40,140*40,0 + dc.w 20*40,20*40,20*40,20*40,20*40,84*40,84*40,84*40,84*40,84*40,148*40,148*40,148*40,148*40,148*40,0 + dc.w 28*40,28*40,28*40,28*40,28*40,92*40,92*40,92*40,92*40,92*40,156*40,156*40,156*40,156*40,156*40,0 + dc.w 36*40,36*40,36*40,36*40,36*40,100*40,100*40,100*40,100*40,100*40,164*40,164*40,164*40,164*40,164*40,0 + dc.w 44*40,44*40,44*40,44*40,44*40,108*40,108*40,108*40,108*40,108*40,172*40,172*40,172*40,172*40,172*40,0 + dc.w 52*40,52*40,52*40,52*40,52*40,116*40,116*40,116*40,116*40,116*40,180*40,180*40,180*40,180*40,180*40,0 + dc.w 60*40,60*40,60*40,60*40,60*40,124*40,124*40,124*40,124*40,124*40,188*40,188*40,188*40,188*40,188*40,0 + dc.w 5*40,5*40,5*40,5*40,5*40,69*40,69*40,69*40,69*40,69*40,133*40,133*40,133*40,133*40,133*40,0 + dc.w 13*40,13*40,13*40,13*40,13*40,77*40,77*40,77*40,77*40,77*40,141*40,141*40,141*40,141*40,141*40,0 + dc.w 21*40,21*40,21*40,21*40,21*40,85*40,85*40,85*40,85*40,85*40,149*40,149*40,149*40,149*40,149*40,0 + dc.w 29*40,29*40,29*40,29*40,29*40,93*40,93*40,93*40,93*40,93*40,157*40,157*40,157*40,157*40,157*40,0 + dc.w 37*40,37*40,37*40,37*40,37*40,101*40,101*40,101*40,101*40,101*40,165*40,165*40,165*40,165*40,165*40,0 + dc.w 45*40,45*40,45*40,45*40,45*40,109*40,109*40,109*40,109*40,109*40,173*40,173*40,173*40,173*40,173*40,0 + dc.w 53*40,53*40,53*40,53*40,53*40,117*40,117*40,117*40,117*40,117*40,181*40,181*40,181*40,181*40,181*40,0 + dc.w 61*40,61*40,61*40,61*40,61*40,125*40,125*40,125*40,125*40,125*40,189*40,189*40,189*40,189*40,189*40,0 + dc.w 6*40,6*40,6*40,6*40,6*40,70*40,70*40,70*40,70*40,70*40,134*40,134*40,134*40,134*40,134*40,0 + dc.w 14*40,14*40,14*40,14*40,14*40,78*40,78*40,78*40,78*40,78*40,142*40,142*40,142*40,142*40,142*40,0 + dc.w 22*40,22*40,22*40,22*40,22*40,86*40,86*40,86*40,86*40,86*40,150*40,150*40,150*40,150*40,150*40,0 + dc.w 30*40,30*40,30*40,30*40,30*40,94*40,94*40,94*40,94*40,94*40,158*40,158*40,158*40,158*40,158*40,0 + dc.w 38*40,38*40,38*40,38*40,38*40,102*40,102*40,102*40,102*40,102*40,166*40,166*40,166*40,166*40,166*40,0 + dc.w 46*40,46*40,46*40,46*40,46*40,110*40,110*40,110*40,110*40,110*40,174*40,174*40,174*40,174*40,174*40,0 + dc.w 54*40,54*40,54*40,54*40,54*40,118*40,118*40,118*40,118*40,118*40,182*40,182*40,182*40,182*40,182*40,0 + dc.w 62*40,62*40,62*40,62*40,62*40,126*40,126*40,126*40,126*40,126*40,190*40,190*40,190*40,190*40,190*40,0 + dc.w 7*40,7*40,7*40,7*40,7*40,71*40,71*40,71*40,71*40,71*40,135*40,135*40,135*40,135*40,135*40,0 + dc.w 15*40,15*40,15*40,15*40,15*40,79*40,79*40,79*40,79*40,79*40,143*40,143*40,143*40,143*40,143*40,0 + dc.w 23*40,23*40,23*40,23*40,23*40,87*40,87*40,87*40,87*40,87*40,151*40,151*40,151*40,151*40,151*40,0 + dc.w 31*40,31*40,31*40,31*40,31*40,95*40,95*40,95*40,95*40,95*40,159*40,159*40,159*40,159*40,159*40,0 + dc.w 39*40,39*40,39*40,39*40,39*40,103*40,103*40,103*40,103*40,103*40,167*40,167*40,167*40,167*40,167*40,0 + dc.w 47*40,47*40,47*40,47*40,47*40,111*40,111*40,111*40,111*40,111*40,175*40,175*40,175*40,175*40,175*40,0 + dc.w 55*40,55*40,55*40,55*40,55*40,119*40,119*40,119*40,119*40,119*40,183*40,183*40,183*40,183*40,183*40,0 + dc.w 63*40,63*40,63*40,63*40,63*40,127*40,127*40,127*40,127*40,127*40,191*40,191*40,191*40,191*40,191*40,0 diff --git a/src/Main.s b/src/Main.s new file mode 100644 index 0000000..7eab925 --- /dev/null +++ b/src/Main.s @@ -0,0 +1,1343 @@ + +DEBUG EQU 1 ;0 or 1 to control "DEBUG" option, Diagnostic output, etc + OPT P=68020,USER + + IFNE DEBUG + OPT DEBUG + ELSE + OPT NODEBUG + ENDC + + include system + include libraries/dos_lib.i + include libraries/dos.i + include exec/exec_lib.i + include exec/interrupts.i + include exec/execbase.i + include graphics/graphics_lib.i + include graphics/gfxbase.i + include intuition/intuition_lib.i + include hardware/custom.i + include hardware/intbits.i + include hardware/dmabits.i + include devices/console.i ;just for "RawKeyConvert" fnctn + include devices/console_lib.i + include devices/inputevent.i + include resources/potgo.i ;for PotBits stuff... + include resources/potgo_lib.i + include hardware/cia.i ;all for CIA stuff + include resources/cia.i + include resources/cia_lib.i + include ReqTools/reqtools_lib.i ;for reqTools!!!! + include ReqTools/reqtools.i + +CALLREQ MACRO + move.l _REQBase,a6 + jsr _LVO\1(a6) + ENDM + +*-------------------------------------------------------------------------* + SECTION APPLEII,CODE + + jmp OpenAll ;returns to "Main" + include "OpenClose.s" ;opens all, Exits too! + include "Decompress.s" ;does DDD & Plain disk loading + include "Compress.s" ;does DDD & Plain disk saving + include "AppleII.s" ;does 6502/hardware/etc ! + + IFNE DEBUG + include "Debug.s" ;Debugging/Diagnostic help + ELSE + include "NoDebug.s" + ENDC + + include "CharSets.s" ;has bitmap character sets + +_SysBase equ 4 +Hardware equ $dff000 + +*-------------------------------------------------------------------------* + SECTION APPLEII,CODE + CNOP 0,4 + +Main: +Wait move.l ([MyWindow.l],wd_UserPort),a0 + CALLEXEC WaitPort + + move.l ([MyWindow.l],wd_UserPort),a0 + CALLEXEC GetMsg ;get Intui-Message + tst.l d0 ;message arrive? + beq Wait ;nope, wait some more! + move.l d0,a1 + move.l im_Class(a1),d2 + move.w im_Code(a1),d3 + move.w im_Qualifier(a1),d4 + move.l im_IAddress(a1),d5 + CALLEXEC ReplyMsg + ;d2.l= im_Class + ;d3.w= im_Code + ;d4.w= qualifier + ;d5.l = IAddress + cmp.l #RAWKEY,d2 + beq key + cmp.l #MOUSEBUTTONS,d2 + beq button + cmp.l #INTUITICKS,d2 + bne.b Wait + + tst.l NewStatusMsgPtr ;Handle StatusMsg's.. New one present? + beq.b .NoNew + jsr DrawNewStatusMsg + +.NoNew tst.b StatusCountdown ;and remove msg in timely manner... + beq.b .NewVid + subq.b #1,StatusCountdown + bne.b .NewVid + jsr ClearStatusMsg + +.NewVid move.l DoVideoFlag,d2 + beq.b .skip + + clr.l DoVideoFlag + move.l #0,d0 + CALLINT LockIBase + move.l d0,d5 + + move.l MyScreen,a0 ;Rebuild local VPort copper list (but not display) + CALLINT MakeScreen + CALLINT RethinkDisplay ;and update screen! + + cmp.l LastColorTable,d2 + beq.b .sameColor + + move.l d2,a1 + move.l MyScreen,a0 ;Set Colors... (IF NEEDED!) + move.l a1,LastColorTable + lea sc_ViewPort(a0),a0 ;a0 -> Screen ViewPort + move.w (a1)+,d0 ;d0 = # of colors, a1 -> ColorList + CALLGRAF LoadRGB4 ;(takes effect immed, but doesn't ReThink display) + +.sameColor + move.l d5,a0 + CALLINT UnlockIBase ;(is locking really needed?) + +.skip tst.b FlashEnableB ;see if flashing is even enabled 1st... + beq Wait + + addq.l #1,TickCount + cmp.l #3,TickCount + bne Wait + move.l #0,TickCount +.flash + lea Flash1ColorTbl,a1 + eor.b #1,Toggle + beq .alt + lea Flash2ColorTbl,a1 + +.alt move.l #0,d0 + CALLINT LockIBase + move.l d0,d5 + + move.l MyScreen,a0 ;SET COLORS... + lea sc_ViewPort(a0),a0 ;a0 -> Screen ViewPort + move.w (a1)+,d0 ;d0 = # of colors, a1 -> ColorList + CALLGRAF LoadRGB4 ;(takes effect immed, but doesn't ReThink display) + + move.l d5,a0 + CALLINT UnlockIBase ;(is locking really needed?) + + bra Wait + + CNOP 0,4 +TickCount dc.l 0 +FlashEnableB dc.b 1 +Toggle dc.b 0 + + CNOP 0,4 +*-------------------------------------------------------------------------* +FlushMsgs: +.flush move.l ([MyWindow.l],wd_UserPort),a0 + CALLEXEC GetMsg ;get any Intui-Message + tst.l d0 ;message arrive? + beq .done ;nope, wait some more! + move.l d0,a1 + CALLEXEC ReplyMsg ;we dont care what it is, just reply... + bra.b .flush +.done rts +*-------------------------------------------------------------------------* + CNOP 0,4 +KillApple: ;***** QUIT PROGRAM!!!! ***** + bsr PauseCPU ;stop 6502 task, clear & show MyScreen + bsr ShowMainScreen + + moveq.l #0,d0 ;check & warn if drive #1 changed + bsr CheckDiskAndWarn + tst.w d0 + beq.b .NoKill + + moveq.l #1,d0 ;check & warn if drive #2 changed (if present) + tst.l disk_Buffer2 + beq.b .NoD2 + bsr CheckDiskAndWarn + tst.w d0 + beq.b .NoKill + +.NoD2 move.l MyWindow,.win + + lea .QuitMsg,a1 + lea .QuitAns,a2 ; "are you sure?" req + move.l EasyReq,a3 + move.l #0,a4 + lea .QuitTag,a0 + CALLREQ rtEZRequestA + + tst.l d0 + beq .NoKill ; nope! don't quit! + +.Kill move.l MySubTask,a1 ;6502 paused- Don't respond, Remove it! + CALLEXEC RemTask + jsr FadeEffect + jmp exit ;instead of NiceExit!!!!! + +.NoKill jsr FlushMsgs + bsr ResumeCPU ;resume 6502 task, restore pointer & video... + + bra Wait + +.QuitMsg dc.b "Really Quit?",0 +.QuitAns dc.b "_Yes|_No",0 +.QuitTag dc.l RT_Underscore,'_',RT_ReqPos,REQPOS_TOPLEFTSCR + dc.l RTEZ_Flags,EZREQF_NORETURNKEY,RT_Window +.win dc.l 0 ;<-- patch in window before using taglist... + dc.l RT_LockWindow,1,RTEZ_ReqTitle,.QuitTtl,TAG_DONE +.QuitTtl dc.b "Quit?",0 +*-------------------------------------------------------------------------* + CNOP 0,4 + ;----Here for RAWKEY event only!!!------ +key: btst.l #IEQUALIFIERB_LCOMMAND,d4 ;LeftAmiga pressed? Ignore... + bne Wait + + lea .KyTbl,a0 ;Look up key, jump to handler + move.l (a0,d3.l*4),d0 + beq .NotHardKey + move.l d0,a0 + jmp (a0) + + ;*** These Raw keycodes are from page 661, RKM Libs&Devs *** + ;* Only handle special 'hard' keys here. Others get parsed by con dev +.KyTbl dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$00-$0f + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;$10 + dc.l $00,$00,$00,$00,$00,$00,.Num2,$00 ;$18-$1f + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;$20 + dc.l $00,$00,$00,$00,$00,.Num4,.Num5,.Num6 ;$28 + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;$30 + dc.l $00,$00,$00,$00,$00,$00,.Num8,$00 ;$38 + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;$40 + dc.l $00,$00,$00,$00,.Up,.Down,.Right,.Left ;$48 + dc.l .F1,.F2,.F3,.F4,.F5,$00,$00,.F8 ;$50 + dc.l .F9,.F10,$00,$00,$00,$00,$00,.Help ;$58 + dc.l $00,$00,$00,$00,.LAltDn,.RAltDn,$00,$00 ;$60-$67 + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;$68-$6f + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$70 + + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$80 + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$90 + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$a0 + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$b0 + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$c0 + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$d0 + dc.l $00,$00,$00,$00,.LAltUp,.RAltUp,$00,$00 ;$e0-$e7 + dc.l $00,$00,$00,$00,$00,$00,$00,$00 ;$e8-$ef + dc.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;$f0 + + +.LAltDn ;Left-Alt down: set button 0 + move.b #$ff,([Mem_PtrVar.l],$c061.l) + bra Wait +.LAltUp ;L-Alt up: clear button 0 + move.b #$00,([Mem_PtrVar.l],$c061.l) + bra Wait +.RAltDn ;R-Alt down: set button 1 + move.b #$ff,([Mem_PtrVar.l],$c062.l) + bra Wait +.RAltUp ;R-Alt up: clear button 1 + move.b #$00,([Mem_PtrVar.l],$c062.l) + bra Wait +.Left ;Left Arrow: store as ctrl-h + move.b #8+128,([Mem_PtrVar.l],$c000.l) + bra Wait +.Right ;Right Arrow: store as ctrl-u + move.b #21+128,([Mem_PtrVar.l],$c000.l) + bra Wait +.Up ;Up Arrow: store as ctrl-k + move.b #11+128,([Mem_PtrVar.l],$c000.l) + bra Wait +.Down ;Down Arrow: store as ctrl-j + move.b #10+128,([Mem_PtrVar.l],$c000.l) + bra Wait + + ;*** Joystick Trimming controls *** +.Num4 sub.w #11,Pdl0CenterW ;NumPad 4 <-- + bpl.b .Num4ok + move.w #2805,Pdl0CenterW +.Num4ok bra Wait + +.Num6 add.w #11,Pdl0CenterW ;NumPad 6 --> + cmp.w #2805,Pdl0CenterW + bls.b .Num6ok + move.w #0,Pdl0CenterW +.Num6ok bra Wait + +.Num8 sub.w #11,Pdl1CenterW ;NumPad 8 ^ + bpl.b .Num8ok + move.w #2805,Pdl1CenterW +.Num8ok bra Wait + +.Num2 add.w #11,Pdl1CenterW ;NumPad 2 V + cmp.w #2805,Pdl1CenterW + bls.b .Num2ok + move.w #0,Pdl1CenterW +.Num2ok bra Wait + +.Num5 move.w #127*11,Pdl0CenterW ;NumPad 5 (Center) + move.w #127*11,Pdl1CenterW + bra Wait + + ;*** Set regulation speed *** +.F1 move.l #50,d3 ;F1 key: Set speed regulation to 50% + lea .Speed50Msg,a3 + bra .F1to5 + +.F2 move.l #100,d3 ;F2 key: Set speed regulation to 100% + lea .Speed100Msg,a3 + bra .F1to5 + +.F3 move.l #150,d3 ;F3 key: Set speed regulation to 150% + lea .Speed150Msg,a3 + bra .F1to5 + +.F4 move.l #200,d3 ;F4 key: Set to 200% + lea .Speed200Msg,a3 + bra .F1to5 + +.F5 move.l #-1,d3 ;F5 key: Turn off speed regulation + lea .SpeedNoneMsg,a3 + bra .F1to5 + +.F1to5 bsr PauseCPU ;enter w/ d3=new speed, a3->NewMsg + move.l d3,ResumeWithNewSpeed + bsr ResumeCPU + bsr FlushMsgs + move.l a3,NewStatusMsgPtr + bra Wait + +.Speed50Msg dc.b " SPEED LIMIT: 50% (0.5 MHZ)",0,25 +.Speed100Msg dc.b " SPEED LIMIT: 100% (1.0 MHZ)",0,25 +.Speed150Msg dc.b " SPEED LIMIT: 150% (1.5 MHZ)",0,25 +.Speed200Msg dc.b " SPEED LIMIT: 200% (2.0 MHZ)",0,25 +.SpeedNoneMsg dc.b " LUDICROUS SPEED! (NO LIMIT)",0,25 +; dc.b "1234567890123456789012345678901234567890" + CNOP 0,4 + +.F10 ;F10 key: Do Diagnostic print! + jsr PauseCPU ;sometime, make Pause w/o screen changes + move.l #1,ResumeWithDiagnostic + jsr ResumeCPU + jsr FlushMsgs + bra Wait + +.F9 ;F9 key: Toggle Joystk/Mouse controls! + move.l PotBits,d0 ;free any previously allocated PotBits... + CALLPOTGO FreePotBits + clr.l PotBits + + lea HardwareWriteTbl,a0 ;Cycle through Joy/Mouse/Analog + move.l $70*4(a0),a1 + cmpa.l #HW_C070_Joystick,a1 + beq.b .wasJoy + cmpa.l #HW_C070_Mouse,a1 + beq.b .wasMouse + cmpa.l #HW_C070_AtariPdl,a1 + beq .wasAtariPdl + bra .wasAnalog + + +.wasJoy ;Was Joystick, now make it mouse! + move.l #HW_C070_Mouse,$70*4(a0) ;set to mouse control... + lea HardwareReadTbl,a0 + move.l #HW_C070_Mouse,$70*4(a0) + + move.l #.MouseMsg,NewStatusMsgPtr + bra Wait + +.wasMouse + move.l #HW_C070_Analog,$70*4(a0) ;set to Analog control... + lea HardwareReadTbl,a0 + move.l #HW_C070_Analog,$70*4(a0) + move.l #HWr_C061_Analog,$61*4(a0) ;and buttons... + move.l #HWr_C062_Analog,$62*4(a0) + + move.l #%1111000000000001,d0 ;allocate 2 prop bits & Start bit... + CALLPOTGO AllocPotBits + move.l d0,PotBits + + move.l #%0101000000000000,d0 ;bits to set + move.l PotBits,d1 ;mask + CALLPOTGO WritePotgo ;set output lines hi to read joy 2nd btn... + + move.w #$01fe,PotPosition + +.10 cmp.w #$01fe,PotPosition ;wait until intrpt server is running + beq.b .10 + move.w #$01fe,PotPosition +.20 cmp.w #$01fe,PotPosition + beq.b .20 + + move.w PotPosition,d0 + and.w #%1111111011111110,d0 ;Ensure each val is even and <= $FE + + move.b d0,PotMinY + addq.b #1,d0 + move.b d0,PotMaxY + + lsr.w #8,d0 + move.b d0,PotMinX + addq.b #1,d0 + move.b d0,PotMaxX + + move.b #0,PdlMode + + move.l #.AnalogMsg,NewStatusMsgPtr + bra Wait + +.wasAnalog ;set to Atari Paddles... Only change + ;from Analog Joystick is a flag setting. + + move.l #HW_C070_AtariPdl,$70*4(a0) ;set to Atari Pdl control... + lea HardwareReadTbl,a0 + move.l #HW_C070_AtariPdl,$70*4(a0) + move.l #HWr_C061_Analog,$61*4(a0) ;and buttons... + move.l #HWr_C062_Analog,$62*4(a0) + + move.l #%1111000000000001,d0 ;allocate 2 prop bits & Start bit... + CALLPOTGO AllocPotBits + move.l d0,PotBits + + move.l #%0101000000000000,d0 ;bits to set + move.l PotBits,d1 ;mask + CALLPOTGO WritePotgo ;set output lines hi to read joy 2nd btn... + + + move.w #$01fe,PotPosition + +.51 cmp.w #$01fe,PotPosition ;wait until intrpt server is running + beq.b .51 + move.w #$01fe,PotPosition +.52 cmp.w #$01fe,PotPosition + beq.b .52 + + move.w PotPosition,d0 + and.w #%1111111011111110,d0 ;Ensure each val is even and <= $FE + + move.b d0,PotMinY + addq.b #1,d0 + move.b d0,PotMaxY + + lsr.w #8,d0 + move.b d0,PotMinX + addq.b #1,d0 + move.b d0,PotMaxX + + move.b #1,PdlMode + + move.l #.AtariPdlMsg,NewStatusMsgPtr + bra Wait + + +.wasAtariPdl + move.l #HW_C070_Joystick,$70*4(a0) ;set to joystick control... + lea HardwareReadTbl,a0 + move.l #HW_C070_Joystick,$70*4(a0) + move.l #HWr_C061,$61*4(a0) ;and buttons... + move.l #HWr_C062,$62*4(a0) + + move.l #$c000,d0 ;we want bits #14 & bit #15... (DATRY & OUTRY) + CALLPOTGO AllocPotBits + move.l d0,PotBits + + move.l #$c000,d0 ;bits to set + move.l PotBits,d1 ;mask + CALLPOTGO WritePotgo ;set output lines hi to read joy 2nd btn... + + move.l #.JoyMsg,NewStatusMsgPtr + bra Wait + +.JoyMsg dc.b " ---==== JOYSTICK ====--- ",0,25 +.MouseMsg dc.b " ---==== MOUSE ====--- ",0,25 +.AnalogMsg dc.b " ---==== ANALOG JOYSTICK ====--- ",0,25 +.AtariPdlMsg dc.b " ---==== ATARI PADDLES ====--- ",0,25 + dc.b "1234567890123456789012345678901234567890" + CNOP 0,4 + + bra Wait + +.F8 ;F8 key? Print Contents of 0 page... +; jsr PauseCPU ;sometime, make Pause w/o screen changes + +; move.l Mem_PtrVar,a0 ;Print memory... +; move.l #$c600,d1 +;.pg0lp move.b (a0,d1.l),d0 +; jsr DB_HexB +; addq.l #1,d1 +; cmp.l #$c700,d1 +; blo .pg0lp + +; move.l Mem_PtrVar,a0 ;Search memory & print finds... +; move.l #$0300,d1 +;.srchlp cmp.w #$d0fd,(a0,d1.l) +; bne .nope +; move.w d1,d0 +; jsr DB_HexW +;.nope addq.w #1,d1 +; bne .srchlp + + +; move.b #$ff,([Mem_PtrVar.l],$fca8.l) ;patch rom for experiment... + +; jsr ResumeCPU + +; jsr Hgr1Refresh + + jsr FlushMsgs + bra Wait + +;--------- + + +.Help ; key: Toggle through msgs... + + move.l .NextHelpMsg,a0 + move.l (a0)+,.NextHelpMsg ;setup next message for next time... + + move.l a0,NewStatusMsgPtr ;and load status message... + + bra Wait + +.NextHelpMsg dc.l .Help1 ;index to help message... + + ;Help_ has ptr to next sequential message & message... +.Help1 dc.l .Help2 + dc.b "HELP: @L- LOAD, @S- SAVE, @Q- QUIT...",0,40 +.Help2 dc.l .Help3 + dc.b "HELP: DEL = RESET, F9 = SET CONTROLS...",0,40 +.Help3 dc.l .Help4 + dc.b "HELP: F1 -> F5 = SPEED REGULATION...",0,40 +.Help4 dc.l .Help1 + dc.b "HELP: HELP = HELP (READ THE DOCS! -KK)",0,40 +; dc.b "1234567890123456789012345678901234567890" + CNOP 0,4 + + + +;----------- + ;d2.l= im_Class + ;d3.w= im_Code + ;d4.w= qualifier + ;d5.l = IAddress +.NotHardKey +1$ and.w #~(IEQUALIFIER_LALT!IEQUALIFIER_RALT),d4 ;mask out ALT's + lea InputStrct,a0 + move.w d3,ie_Code(a0) + tst.b d3 + bmi Wait ;key release? ignore! + move.w d4,ie_Qualifier(a0) + move.l d5,ie_EventAddress(a0) + lea KeyBuffer,a1 + move.l #80,d1 ;buffer len + move.l #0,a2 ;keymap (0=default) + move.l _ConBase,a6 + jsr _LVORawKeyConvert(a6) + cmp.l #1,d0 + bne Wait ;not a 1 byte simple answer? Ignore it! + + move.b KeyBuffer,d3 ;new plain ascii keycode in d3! + + btst.l #IEQUALIFIERB_RCOMMAND,d4 ;right amiga? + bne .ComKey ;yes! + cmp.b #$7f,d3 ;KEYBOARD! is it "DEL"? + beq .reset + + cmp.b #'a',d3 + blo.b .notLo + cmp.b #'z',d3 + bhi.b .notLo + eor.b #'a'^'A',d3 ;FORCE TO UPPER CASE... (1 bit change) +.notLo add.b #$80,d3 ;no, put it in $c000 to read later + move.b d3,([Mem_PtrVar.l],$c000.l) ;place key... + bra Wait + +.ComKey bclr #5,d3 ;force all keys to lower case + cmp.b #'Q',d3 ;R-Amiga q ? + beq KillApple ;Yes, go Quit! + cmp.b #'L',d3 + beq LoadReq + cmp.b #'S',d3 + beq SaveReq + + bra Wait + +.reset btst.l #IEQUALIFIERB_CONTROL,d4 ;is it CTRL-HELP? + beq .CauseReset + +.CauseReboot: + move.w #00,([Mem_PtrVar.l],$3f2.w) ;blank out soft reset vector... + move.b #00,([Mem_PtrVar.l],$3f4.w) ;and checksum byte... WILL REBOOT! +.CauseReset: + CALLEXEC Forbid + move.l #RESET_INST,a0 ;Next 6502 inst will be RESET_INST + move.l InstTbl_Var,a1 ;array of 65536 longs... + move.w #65535,d1 +.lp move.l a0,(a1)+ + dbf d1,.lp + CALLEXEC Permit ;done! Will continue at Reset_Vector!!! + bra Wait + + +*-------------------------------------------------------------------------* + CNOP 0,4 +button: cmp.w #SELECTDOWN,d3 ;Left mousebutton down? UPDATE button 0 status... + bne.b 2$ + move.b #$ff,([Mem_PtrVar.l],$c061.l) ;set button 0 + bra Wait + +2$ cmp.w #SELECTUP,d3 ;Left MB up? + bne.b 3$ + move.b #$00,([Mem_PtrVar.l],$c061.l) + bra Wait + +3$ cmp.w #MENUDOWN,d3 ;Right MB down? + bne.b 4$ + move.b #$ff,([Mem_PtrVar.l],$c062.l) + bra Wait + +4$ cmp.w #MENUUP,d3 ;Right MB up? + bne.b 5$ + move.b #$00,([Mem_PtrVar.l],$c062.l) + +5$ bra Wait + +*-------------------------------------------------------------------------* +* LOADREQ is the entire function to put up a File Requester, attempt to load +* the file, identify the type of file (or report the error), & jump to the +* beginning of it (run it) if its an executable/snapshot... + +LoadReq: + bsr PauseCPU ;stop 6502 task, clear & show MyScreen + bsr ShowMainScreen + + move.l MyWindow,.win + move.l MyWindow,.win4 + move.l MyWindow,.win12 + + lea .LoadTag,a0 + move.l FileReq,a1 + lea .TempLoadFileNm,a2 + lea .LoadTtl,a3 ; "Load A File" req + CALLREQ rtFileRequestA + + tst.l d0 + beq .DoneLd ;cancel + +.build move.l FileReq,a0 ;Build string w/ full DOS path * filename + move.l rtfi_Dir(a0),a0 ;* path string + lea .FullPath,a1 ;dest buffer + + tst.b (a0) + beq.b .bldFl ;No path info, use current dir... + +.lp1 move.b (a0)+,(a1)+ + bne .lp1 + lea -1(a1),a1 ;back over NULL (pts at that byte now) + cmp.b #':',-1(a1) ;end with a : ? + beq.b .bldFl + move.b #'/',(a1)+ ;No, tag a trailing / in dest... + +.bldFl lea .TempLoadFileNm,a0 +.lp2 move.b (a0)+,(a1)+ + bne .lp2 + move.b -2(a0),.LastChar ;Keep last char (to check for ddd type) + + lea .FullPath,a0 + jsr DB_String +;--------------- +.load move.l #.FullPath,d1 ;Load parsed File [arg] name + move.l #MODE_OLDFILE,d2 + CALLDOS Open + move.l d0,d4 ;temp + beq .Err + + move.l d4,d1 ;Read entire file specified... (up to 64k) + move.l InstTbl_Var,d2 ;read temporarily into 256k area "InstTbl" + move.l #262140,d3 ;256k max read! (should never be that big!) + CALLDOS Read ;d0 = # of bytes read + + move.l d0,d6 ;d6 = # of bytes read + + move.l d4,d1 ;Close file + CALLDOS Close + +*............................... + +.PlnImg cmp.l #143360,d6 ;Check if = # of bytes in "plain" disk image + beq.b .IsDisk + + cmp.b #'>',.LastChar ;Is it a DDD filename (ends in '>' char?) + bne .CheckProDosExe + +.IsDisk ;Is a disk image! Determine type by D6 (size) + moveq.l #0,d0 ;default to drive 1 + + tst.l disk_Buffer2 ;unless 2 drives present... + beq.b .DriveSelected + + lea .Load12Msg,a1 ; "Which drive?" req + lea .Load12Ans,a2 + move.l EasyReq,a3 + move.l #0,a4 + lea .Load12Tag,a0 + CALLREQ rtEZRequestA + tst.l d0 + beq .DoneLd ;Cancel + + subq.l #1,d0 ;Else d0 = drive # (0 or 1) + +.DriveSelected ;d0 = drive # (0 or 1) !!! + move.l (disk_Buffer.l,d0.w*4),Dest_Disk_Buffer ;Set proper destination... + move.l d0,d2 + + bsr CheckDiskAndWarn ;check & warn if old drive data changed + tst.w d0 + beq .DoneLd + + clr.b (disk_Changed.l,d2.w) ;and mark new drive as being UNchanged + + lea .TempLoadFileNm,a0 ;And Keep filename for proper drive... + move.l (LoadSaveNmPtrs.l,d2.w*4),a1 + move.w #120/4-1,d0 +.KeepNm move.l (a0)+,(a1)+ + dbf d0,.KeepNm + + cmp.l #143360,d6 ;Check if = # of bytes in "plain" disk image + bne.b .DDD + +.Plain jsr PlainDiskImage_Load + bra .boot +.DDD jsr DecompressDisk ;THEN Decompress DDD disk... + bra .boot + +;----------------------------- + +.boot move.l disk_Buffer,d0 + cmp.l Dest_Disk_Buffer,d0 ;did we load drive #1? + bne .DoneLd + + lea .BootMsg,a1 ;Yes- "Want to Boot disk?" req + lea .BootAns,a2 + move.l EasyReq,a3 + move.l #0,a4 + lea .BootTag,a0 + CALLREQ rtEZRequestA + + move.l d0,RebootApple ;Set flag in "STOP_INST" to reboot... + bra .DoneLd + +.CheckProDosExe + move.l InstTbl_Var,a3 ;IS THIS A PRODOS FILE? + cmp.w #$0a47,(a3) ;first 2 bytes in ProDos header... + bne .CheckDosExe ;No??? Maybe DOS 3.3? + cmp.b #$4c,2(a3) ;Third byte in ProDos header... + bne .CheckDosExe + bra .ProDos + +.CheckDosExe + moveq.l #0,d4 ;Dos 3.3 test... + moveq.l #0,d5 ;assume dos 3.3 unless out of range err... + move.w (a3),d4 + ror.w #8,d4 + move.w 2(a3),d5 + ror.w #8,d5 + + move.l d4,d0 + cmp.l #$c000,d0 + bhs .Err + jsr DB_HexL + move.l d5,d0 + jsr DB_HexL + move.l d4,d0 + add.l d5,d0 + cmp.l #$c000,d0 + bhs .Err + + move.l d4,ResumePCount ;<------ to immediately execute!!! + + lea FreshBootMemory,a0 ;1st reset memory as a "fresh" powerup + move.l Mem_PtrVar,a1 + move.w #$07ff,d0 +.frsh move.b (a0,d0.w),(a1,d0.w) + dbf d0,.frsh + + move.l InstTbl_Var,a0 + add.l #$4,a0 ;data source... + move.l Mem_PtrVar,a1 + add.l d4,a1 ;data dest... + subq.w #1,d5 +.mlp2 move.b (a0)+,(a1)+ + dbf d5,.mlp2 ;Now in Apple Memory!!! + bra .DoneLd + +.ProDos moveq.l #0,d4 + moveq.l #0,d5 + + move.w $5(a3),d4 + ror.w #8,d4 ;starting addr in d4... + + move.w $14(a3),d5 + ror.w #8,d5 ;length in d5 + + move.l d4,d0 + cmp.l #$c000,d0 + bhs .Err + jsr DB_HexL + move.l d5,d0 + jsr DB_HexL + move.l d4,d0 + add.l d5,d0 + cmp.l #$c000,d0 + bhs .Err + + move.l d4,ResumePCount ;<------ to immediately execute!!! + + lea FreshBootMemory,a0 ;1st reset memory as a "fresh" powerup + move.l Mem_PtrVar,a1 + move.w #$07ff,d0 +.fresh move.b (a0,d0.w),(a1,d0.w) + dbf d0,.fresh + +.MemMv move.l InstTbl_Var,a0 + add.l #$80,a0 ;data source... + move.l Mem_PtrVar,a1 + add.l d4,a1 ;data dest... + subq.w #1,d5 +.mlp move.b (a0)+,(a1)+ + dbf d5,.mlp ;Now in Apple Memory!!! + +;---------- +.DoneLd jsr FlushMsgs + bsr ResumeCPU ;resume 6502 task, restore pointer, restore video... + + bra Wait +;----------- +.Err move.l MyWindow,.winErr ;say error happened, then go to ".NoLoad" + + lea .ErrMsg,a1 + lea .ErrAns,a2 ; "Hey, error loading" req + move.l EasyReq,a3 + move.l #0,a4 + lea .ErrTag,a0 + CALLREQ rtEZRequestA + bra .DoneLd + +.ErrMsg dc.b "An Error Occured",10 + dc.b "With That File.",0 +.ErrAns dc.b "_OK",0 +.ErrTag dc.l RT_Underscore,'_',RT_ReqPos,REQPOS_TOPLEFTSCR + dc.l RT_Window +.winErr dc.l 0 ;<-- patch in window before using taglist... + dc.l RT_LockWindow,1,RTEZ_ReqTitle,.ErrTtl,TAG_DONE +.ErrTtl dc.b "Error",0 +;------------ +.LoadTtl dc.b "File to Load:",0 + +.LoadTag dc.l RT_Underscore,'_',RTFI_Flags,FREQF_PATGAD ;RT_ReqPos,REQPOS_TOPLEFTSCR + dc.l RT_Window +.win dc.l 0 ;<-- patch in window before using taglist... + dc.l RT_LockWindow,1,TAG_DONE +.FullPath ds.b 255 +;----------- +.BootMsg dc.b "Disk Loaded.",10,"Boot Disk?",0 +.BootAns dc.b "_Yes|_No",0 +.BootTag dc.l RT_Underscore,'_',RT_ReqPos,REQPOS_TOPLEFTSCR + dc.l RTEZ_Flags,EZREQF_NORETURNKEY!EZREQF_LAMIGAQUAL,RT_Window +.win4 dc.l 0 ;<-- patch in window before using taglist... + dc.l RT_LockWindow,1,RTEZ_ReqTitle,.BootTtl,TAG_DONE +.BootTtl dc.b "Boot?",0 +;----------- +.Load12Msg dc.b "Load disk into",10,"drive 1 or 2 ?",0 +.Load12Ans dc.b "_1|_2|Abort",0 +.Load12Tag dc.l RT_Underscore,'_',RT_ReqPos,REQPOS_TOPLEFTSCR + dc.l RTEZ_Flags,EZREQF_NORETURNKEY!EZREQF_LAMIGAQUAL,RT_Window +.win12 dc.l 0 ;<-- patch in window before using taglist... + dc.l RT_LockWindow,1,RTEZ_ReqTitle,.Load12Ttl,TAG_DONE +.Load12Ttl dc.b "Which Drive?",0 + +.LastChar dc.b 0 ;last char of filename(to check for ddd type) + +.TempLoadFileNm ds.b 120 ;temporary "load" name (until drive # known) + +LoadSaveNmPtrs dc.l .LoadSaveNm1,.LoadSaveNm2 +.LoadSaveNm1 ds.b 120 ;drive 1 filename.... +.LoadSaveNm2 ds.b 120 ;drive 2 filename... + even +*-------------------------------------------------------------------------* +SaveReq bsr PauseCPU ;stop 6502 task, clear & show MyScreen + bsr ShowMainScreen + + move.l MyWindow,.win1 + move.l MyWindow,.win2 + move.l MyWindow,.win3 + move.l MyWindow,.win12 + +; lea .SaveMsg1,a1 +; lea .SaveAns1,a2 ; "Save as Disk, Mem, or Cancel?" req +; move.l EasyReq,a3 ; type= 1 2 +; move.l #0,a4 +; lea .SaveTag1,a0 +; CALLREQ rtEZRequestA + +; move.b d0,.SaveType +; beq .Done ; nope! don't quit! + + +*................................... + moveq.l #0,d0 ;default to drive 1 + tst.l disk_Buffer2 ;unless 2 drives present... + beq.b .DriveSelected + + lea .Save12Msg,a1 ; "Save Which drive?" req + lea .Save12Ans,a2 + move.l EasyReq,a3 + move.l #0,a4 + lea .Save12Tag,a0 + CALLREQ rtEZRequestA + tst.l d0 + beq .Done ;Cancel + + subq.l #1,d0 ;Else d0 = drive # (0 or 1) + +.DriveSelected ;d0 = drive # (0 or 1) !!! + move.l (disk_Buffer.l,d0.w*4),Src_Disk_Buffer ;Set proper destination... + move.l (LoadSaveNmPtrs.l,d0.w*4),a5 ;a5-> Proper Filename for drive + move.w d0,.DriveNumW ;keep drive # +*................................................................................. + + lea .SaveTag2,a0 ;*** "Save A File" req *** + move.l FileReq,a1 + move.l a5,a2 ;filename for this drive + lea .SaveTtl2,a3 + CALLREQ rtFileRequestA + + tst.l d0 + beq .Done + +.build move.l FileReq,a0 ;*** Build string with path + filename *** + move.l rtfi_Dir(a0),a0 ;path string + lea .FullPath,a1 ;dest buffer + + tst.b (a0) + beq .bldFl ;No path info, use current dir... + +.lp1 move.b (a0)+,(a1)+ + bne .lp1 + + lea -1(a1),a1 ;back over NULL (pts at that byte now) + cmp.b #':',-1(a1) ;end with a : ? + beq.s .bldFl + + move.b #'/',(a1)+ ;No, tag a trailing / in dest... + +.bldFl move.l a5,a0 +.lp2 move.b (a0)+,(a1)+ + bne .lp2 + move.b -2(a0),.LastChar ;Keep last char (to check for ddd type) + +.verify move.l #.FullPath,d1 ;CHECK Pre-Existance of file! + move.l #ACCESS_READ,d2 + CALLDOS Lock + move.l d0,d1 + beq .DoSave ;file does not exist, so go ahead & save + CALLDOS UnLock + +.SaveV lea .VerMsg,a1 ;*** "are you sure?" req *** + lea .VerAns,a2 + move.l EasyReq,a3 + move.l a5,.FilenamePtr ;filename + lea .FilenamePtr,a4 + lea .VerTag,a0 + CALLREQ rtEZRequestA + + tst.l d0 + beq .Done ; nope! don't quit! + +.DoSave ;cmp.b #1,.SaveType + ;bne .SvMem + +.SvDsk move.l #.FullPath,d1 ;*** And save the image! *** + move.l #MODE_NEWFILE,d2 ;were saving + CALLDOS Open + move.l d0,.FileHandle ;file handle + beq .SaveErr + + cmp.b #'>',.LastChar + bne.b .Plain + +.DDD move.l InstTbl_Var,a0 ;256k dest (will be restored by resumeCpu) + jsr CompressDisk ;Save it! Use DDD compression + bra .DnSv + +.Plain move.l InstTbl_Var,a0 ;256k dest (will be restored by resumeCpu) + jsr PlainDiskImage_Save ;Save it as a plain 143,360 byte image + +.DnSv move.l .FileHandle,d1 + move.l InstTbl_Var,d2 + move.l d0,d3 ;Length of file... + CALLDOS Write + + move.l .FileHandle,d1 + CALLDOS Close + + move.w .DriveNumW,d0 + clr.b (disk_Changed.l,d0.w) ;mark drive as having no active changes + + bra .Done + +.SvMem nop +.SaveErr + +.Done jsr FlushMsgs + bsr ResumeCPU ;resume 6502 task, restore pointer, restore video... + + bra Wait + +.DriveNumW dc.w 0 ;Drive we are saving (0 or 1) +.LastChar dc.b 0 ;Last char in filename (is it a '>' ?) +;---------- +.SaveMsg1 dc.b "Save Disk Image or",10 + dc.b "Memory Snapshot?",0 +.SaveAns1 dc.b "_Disk|_Memory|_Cancel",0 +.SaveTag1 dc.l RT_Underscore,'_',RT_ReqPos,REQPOS_TOPLEFTSCR + dc.l RTEZ_Flags,EZREQF_NORETURNKEY|EZREQF_LAMIGAQUAL,RT_Window +.win1 dc.l 0 ;<-- patch in window before using taglist... + dc.l RT_LockWindow,1,RTEZ_ReqTitle,.SaveTtl1,TAG_DONE +.SaveTtl1 dc.b "Save Type:",0 +.SaveType dc.b 0 ;<-- 1 for Disk Image, 2 for Mem Snapshot +.FileHandle dc.l 0 +;------------ +.SaveTtl2 dc.b "File to Save:",0 + +.SaveTag2 dc.l RT_Underscore,'_',RTFI_Flags,FREQF_SAVE!FREQF_PATGAD + dc.l RT_Window +.win2 dc.l 0 ;<-- patch in window before using taglist... + dc.l RT_LockWindow,1,TAG_DONE +.FullPath ds.b 255 +.FilenamePtr dc.l 00 +;------------- +.VerMsg dc.b "Replace File",10,'"%s" ?',0 +.VerAns dc.b "_Yes|_Cancel",0 +.VerTag dc.l RT_Underscore,'_',RT_ReqPos,REQPOS_TOPLEFTSCR + dc.l RTEZ_Flags,EZREQF_NORETURNKEY!EZREQF_LAMIGAQUAL!EZREQF_CENTERTEXT + dc.l RT_Window +.win3 dc.l 0 ;<-- patch in window before using taglist... + dc.l RT_LockWindow,1,RTEZ_ReqTitle,.VerTtl,TAG_DONE +.VerTtl dc.b "Sure?",0 +;------------- +.Save12Msg dc.b "Save disk from",10,"drive 1 or 2 ?",0 +.Save12Ans dc.b "_1|_2|Abort",0 +.Save12Tag dc.l RT_Underscore,'_',RT_ReqPos,REQPOS_TOPLEFTSCR + dc.l RTEZ_Flags,EZREQF_NORETURNKEY!EZREQF_LAMIGAQUAL,RT_Window +.win12 dc.l 0 ;<-- patch in window before using taglist... + dc.l RT_LockWindow,1,RTEZ_ReqTitle,.Save12Ttl,TAG_DONE +.Save12Ttl dc.b "Save Which Drive?",0 + + CNOP 0,4 +*-------------------------------------------------------------------------* +* This routine will cause the 6502 emulation sub-task to stop running. +* It works by setting a global "stop6502" variable, signals that it's stopped, +* and waits to be signaled to restart. When this function returns, +* the sub-task is stopped! (Can remove or resume subtask at this time) +* Does not need 6502 task context! + +PauseCPU: + + CALLEXEC Forbid + + move.l #STOP_INST,a0 ;Next 6502 inst will be STOP_INST ! + move.l InstTbl_Var,a1 ;array of 65536 longs... + move.w #65535,d1 +.lp move.l a0,(a1)+ + dbf d1,.lp + CALLEXEC Permit + + move.l ParentSigMask,d0 + CALLEXEC Wait ;Wait for 6502 emulation to stop... + rts + + +*-------------------------------------------------------------------------* +* This function turns sets up, shows, and clears the main screen in +* preparation for a requester or graphics. +* This function is usually called AFTER Pausing the Cpu. + +ShowMainScreen: + + movem.l d2-d4,-(sp) + move.l #0,d0 + CALLINT LockIBase + move.l d0,IBaseLock + + move.l MyScreen,a1 + lea sc_BitMap(a1),a1 ;a1 -> Screen.BitMap + move.l OrigPlane1,bm_Planes(a1) ;plug in BitMap Plane Ptrs + move.l OrigPlane2,bm_Planes+4(a1) ;plug in BitMap Plane Ptrs + move.l OrigPlane3,bm_Planes+8(a1) ;plug in BitMap Plane Ptrs + move.l OrigPlane4,bm_Planes+12(a1) ;plug in BitMap Plane Ptrs + move.l OrigPlane5,bm_Planes+14(a1) ;plug in BitMap Plane Ptrs + + move.w OrigRows,bm_Rows(a1) + move.b OrigDepth,bm_Depth(a1) + + move.l MyScreen,a0 + lea sc_ViewPort(a0),a0 ;a1 -> Screen ViewPort + lea MainColorTable,a1 + move.w (a1)+,d0 + CALLGRAF LoadRGB4 + move.l MainColorTable,LastColorTable + + move.l MyScreen,a0 + CALLINT MakeScreen + + move.l IBaseLock,a0 + CALLINT UnlockIBase + + CALLINT RethinkDisplay + + move.l MyWindow,a0 + move.l wd_RPort(a0),a1 ;rastport + move.b #0,d0 + CALLGRAF SetAPen + + move.l MyWindow,a0 ;blank text screen to black... + move.l wd_RPort(a0),a1 + move.w #0,d0 + move.w #12,d1 + move.w #330,d2 + move.w #210,d3 + CALLGRAF RectFill + + ;------- Show screen w/ no copper magic +; CALLEXEC Forbid ;Change to default blank screen... +; move.l MyScreen,a0 ;screen +; lea sc_ViewPort(a0),a0 ;screen.viewport +; move.l #0,vp_UCopIns(a0) ;screen.viewport.UCopIns = 0 +; CALLEXEC Permit +; CALLINT RethinkDisplay + + movem.l (sp)+,d2-d4 + rts + +*-------------------------------------------------------------------------* +* This routine will resume the 6502 emulation sub-task. It restores the +* instruction opcode jump-table and signals the emulation to continue. +* These actions also refresh all graphics memory, restore the window pointer, +* and show the proper video mode. And activates our window! When this routine +* returns, the emulation sub-task is running. Does not need 6502 task context! + +ResumeCPU: + +.sprite move.l MyWindow,a0 ;setup an invisible sprite! + lea SpriteImage,a1 + move.l #4,d0 ;height + move.l #16,d1 ;width + moveq.l #0,d2 + moveq.l #0,d3 + CALLINT SetPointer + + move.l MySubTask,a1 + move.l ChildSigMask,d0 + CALLEXEC Signal ;Tell 6502 to continue running! + + move.l ParentSigMask,d0 + CALLEXEC Wait ;Wait for 6502 to respond (list restored)... + + move.l MyWindow,a0 + CALLINT ActivateWindow + + rts + +*********************************************************************** +* DrawNewStatusMsg- Takes PTR from StatusNewMsgPtr (Null term string + duration) so there +* won't be a conflict between multiple-resettings at any time. Copies string to local buffer, +* prints it on screen, and sets StatusCountdown with duration. +* +* Enter: NewStatusMsgPtr -> String + Null + Duration byte (in intuiticks) +* Return: Sets "StatusCountdown" +* Draws status msg on screen... + +DrawNewStatusMsg: + tst.l NewStatusMsgPtr ;Handle StatusMsg's.. New one present? + beq .done + + move.l NewStatusMsgPtr,a0 ;Copy string... + clr.l NewStatusMsgPtr + lea .StatusTxt,a1 +.copy move.b (a0)+,(a1)+ + bne.b .copy + + move.b (a0),StatusCountdown ;and set countdown variable... + + move.l #$ffffffff,d0 +.draw move.l Hgr1_Planes,a1 + add.l #193*40,a1 ;a1 - a4 -> Bplane(s)1 line #193 + move.l Hgr2_Planes,a2 + add.l #193*40,a2 + move.l Gr1_Planes,a3 + add.l #193*40,a3 + move.l Gr2_Planes,a4 + add.l #193*40,a4 + + move.w #7*40/4-1,d1 ;clear 32 lines in text window... +.fill move.l d0,(a1)+ + move.l d0,(a2)+ + move.l d0,(a3)+ + move.l d0,(a4)+ + dbf d1,.fill + +.DoTxt move.l Hgr1_Planes,a1 + add.l #194*40,a1 ;a1 -> Top line to draw into, left side + move.l Hgr2_Planes,a2 ;a2,a3,a4 -> Other BPlanes to write to... + add.l #194*40,a2 + move.l Gr1_Planes,a3 + add.l #194*40,a3 + move.l Gr2_Planes,a4 + add.l #194*40,a4 + + + lea .StatusTxt,a0 + +.TxtLp clr.w d0 + move.b (a0)+,d0 + beq .done + + lea StatusCharSet8X5,a5 + sub.b #' ',d0 ;space is 1st char in table... + mulu.w #5,d0 + lea (a5,d0.w),a5 + + move.b (a5),(a1)+ ;top rasterline of text to all 4 bplanes... + move.b (a5),(a2)+ + move.b (a5),(a3)+ + move.b (a5)+,(a4)+ + + move.b (a5),40-1(a1) + move.b (a5),40-1(a2) + move.b (a5),40-1(a3) + move.b (a5)+,40-1(a4) + + move.b (a5),40*2-1(a1) + move.b (a5),40*2-1(a2) + move.b (a5),40*2-1(a3) + move.b (a5)+,40*2-1(a4) + + move.b (a5),40*3-1(a1) + move.b (a5),40*3-1(a2) + move.b (a5),40*3-1(a3) + move.b (a5)+,40*3-1(a4) + + move.b (a5),40*4-1(a1) ;bottom rasterline to all 4 bplanes... + move.b (a5),40*4-1(a2) + move.b (a5),40*4-1(a3) + move.b (a5)+,40*4-1(a4) + + bra.b .TxtLp +.done rts + +.StatusTxt ds.b 40 + dc.l 0,0 ;extra NULL's just in case... + + + +********************************************************************* +* ClearStatusMsg - +* This function is called to erase all status bars from the Apple2000 display. +* Enter: None Return: None (Status Bar erased) + +ClearStatusMsg: + moveq.l #$0,d0 +.draw move.l Hgr1_Planes,a1 + add.l #193*40,a1 ;a1 - a4 -> Bplane(s)1 line #193 + move.l Hgr2_Planes,a2 + add.l #193*40,a2 + move.l Gr1_Planes,a3 + add.l #193*40,a3 + move.l Gr2_Planes,a4 + add.l #193*40,a4 + + move.w #7*40/4-1,d1 ;clear 32 lines in text window... +.fill move.l d0,(a1)+ + move.l d0,(a2)+ + move.l d0,(a3)+ + move.l d0,(a4)+ + dbf d1,.fill + rts + +NewStatusMsgPtr dc.l 0 ;any new msg ptr's appear here! +StatusCountdown dc.b 0 ;Byte counter... (set in DrawNewStatusMsg) + even + +**************************************888 +* +* CheckDiskAndWarn - +* This function takes a drive # (0 or 1) and checks if the contents of that drive have +* been changed. If so, it places up a "Data has changed. It will be lost. Ok?" requester. +* Usefull during loading new disks and when quiting emulation. +* Note: Only call from "Paused" cpu state +* +* Enter: d0.w = Drive # (0 or 1) +* Return: d0 = "OK" boolean response (1="Ok" or disk not changed, 0=Cancel, No Way!) + +CheckDiskAndWarn: + move.l MyWindow,.win1 + + tst.b (disk_Changed.l,d0.w) ;has drive data been changed? + bne.b .chngd + moveq.l #1,d0 ;no, let program proceed + rts + +.chngd move.b d0,d1 ;patch in drive # '1' or '2' into msg + add.b #'1',d1 + move.b d1,.WarnMsgDrvNum + + move.l (LoadSaveNmPtrs.l,d0.w*4),.FilenamePtr ;a5-> Proper Filename for drive + + lea .WarnMsg,a1 ;*** "It will be lost. Ok?" req *** + lea .WarnAns,a2 + move.l EasyReq,a3 + lea .FilenamePtr,a4 ;filename + lea .WarnTag,a0 + CALLREQ rtEZRequestA + + rts + +;------------- +.WarnMsg dc.b "Disk Image in drive " +.WarnMsgDrvNum dc.b "1",10,'"%s"',10,"was changed & will be lost!",0 +.WarnAns dc.b "_Ok|_Cancel",0 +.WarnTag dc.l RT_Underscore,'_',RT_ReqPos,REQPOS_TOPLEFTSCR + dc.l RTEZ_Flags,EZREQF_NORETURNKEY!EZREQF_LAMIGAQUAL!EZREQF_CENTERTEXT + dc.l RT_Window +.win1 dc.l 0 ;<-- patch in window before using taglist... + dc.l RT_LockWindow,1,RTEZ_ReqTitle,.WarnTtl,TAG_DONE +.WarnTtl dc.b "Pardon Me, but...",0 +.FilenamePtr dc.l 0 + + + EVEN diff --git a/src/NoDebug.s b/src/NoDebug.s new file mode 100644 index 0000000..baa693f --- /dev/null +++ b/src/NoDebug.s @@ -0,0 +1,8 @@ +** DEBUGGING Routines... Print Strings, hex numbers, dec numbers, etc... +** to MYCHANNEL... (opened prior) + EVEN + rts +DB_String: ** A0 -> Null Terminated String to Print +DB_HexB +DB_HexW +DB_HexL rts diff --git a/src/OpenClose.s b/src/OpenClose.s new file mode 100644 index 0000000..5d6e2ce --- /dev/null +++ b/src/OpenClose.s @@ -0,0 +1,1493 @@ + SECTION APPLEII,CODE + EVEN +**************** OPEN EVERYTHING ******************* +OpenAll move.l a0,StartA0 ;Command line info... + move.l d0,StartD0 + + move.l #VarList,a0 ;clear val's for resident run! + move.l #EndVarList,a1 + moveq.l #0,d0 +.loop move.l d0,(a0)+ + cmp.l a1,a0 + blo.b .loop + + CALLEXEC CacheClearU ;stop crashing after recompile? + + lea dosname,a1 ;Open DOS Library! + moveq #0,d0 + CALLEXEC OpenLibrary + move.l d0,_DOSBase + beq exit ;cant print, so exit + + CALLDOS Output ;and get channel for console + move.l d0,MyChannel + beq exit ;no channel? WB? + + + move.l 4.w,a6 ;check for at least 68020 status! + move.w AttnFlags(a6),d0 + btst.l #1,d0 + bne.b .020 + jmp Fail020 + +.020 lea grafname,a1 ;open Graphics Lib! + moveq.l #0,d0 + CALLEXEC OpenLibrary + move.l d0,_GfxBase + beq fail + + lea intname,a1 ;open Intuition Lib! + moveq #0,d0 + CALLEXEC OpenLibrary + move.l d0,_IntuitionBase + beq fail + + lea reqname,a1 ;open reqtools lib! + moveq #0,d0 + CALLEXEC OpenLibrary + move.l d0,_REQBase + beq fail + + lea potgoname,a1 ;open "potgo.resource" lib, no need to close... + CALLEXEC OpenResource + move.l d0,_PotgoBase + beq fail + ;Set up for Joystick 2nd button... + move.l #$c000,d0 ;we want bits #14 & bit #15... (DATRY & OUTRY) + CALLPOTGO AllocPotBits + move.l d0,PotBits + + move.l #$c000,d0 + move.l PotBits,d1 ;mask + CALLPOTGO WritePotgo ;set output lines hi to read joy 2nd btn... + + + move.l #InstLookUpTableMem,InstTbl_Var ;alloc 256k ram!+4 bytes for inst lookup!!! + + move.l #HiResDrawTableMem,HiResDrawTbl ;alloc 64k hires draw tbl lookup!!! + + move.l #DiskBufferMem,disk_Buffer ;alloc 215K ram for disk buffer + move.l disk_Buffer,disk_TkStrt + + move.l #RT_REQINFO,d0 ;alloc RT_REQINFO structure... + move.l #0,a0 + CALLREQ rtAllocRequestA + move.l d0,EasyReq + beq exit ;(failed) + + move.l #RT_FILEREQ,d0 ;alloc RT_FILEREQ structure... + move.l #0,a0 + CALLREQ rtAllocRequestA + move.l d0,FileReq + beq exit ;(failed) + + move.l FileReq,a1 + lea .TagLst,a0 + CALLREQ rtChangeReqAttrA + + lea .StartBody,a1 + lea .StartGadg,a2 + move.l EasyReq,a3 + move.l #0,a4 + lea .StartTag,a0 + CALLREQ rtEZRequestA + + bra .nxt + +.Pat dc.b "(#?.disk|#?.prog|#?>)",0 +.TagLst dc.l RTFI_MatchPat,.Pat,TAG_DONE + +.StartBody dc.b "******* APPLE 2000 v1.3 *******",10,10 + IIF DEBUG dc.b "***DEBUGGING***",10 + dc.b "The Premier Apple II emulator",10 + dc.b "Copyright © 1994 by Kevin Kralian",10,10 + + dc.b "(No, this is not part of the Emplant",10 + dc.b "package as many have been led to believe.)",0 +.StartGadg dc.b "_Ok",0 +.StartTag dc.l RT_ReqPos,REQPOS_TOPLEFTSCR,RT_Underscore,'_' + dc.l RTEZ_Flags,EZREQF_NORETURNKEY!EZREQF_LAMIGAQUAL!EZREQF_CENTERTEXT + dc.l TAG_DONE + + dc.b "NOTICE: Although this program is distributed as Freeware, " + dc.b "copyright laws & protection still apply. " + dc.b "As such, *any* infringement upon this code, especially as applied " + dc.b "towards other 6502 or Apple II emulations will be rigorously " + dc.b "pursued via legal channels. -Kevin Kralian",0,0,0 + + EVEN +.nxt move.l #65545,d0 ;alloc 64k ram!+9 bytes (for PCount overflow) + move.l #MEMF_PUBLIC!MEMF_CLEAR,d1 + CALLEXEC AllocMem + move.l d0,Mem_PtrVar + beq fail + + move.l d0,a0 + + move.l #$c100,d0 +.FF move.b #$ff,(a0,d0.l) ;put FF's in slot Rom areas (so look empty) + addq.l #1,d0 + cmp.l #$c800,d0 + blo.b .FF + + move.b #$81,(a0,$c020.l) ;Beyond Wolfenstein hangs w/o it + move.b #$81,(a0,$c060.l) ;Serpentine hangs w/o it +; move.b #$60,(a0,$c100.l) ;an RTS when attempts pr#1 +; move.b #$60,(a0,$c300.l) ;an RTS when attempts pr#3 + + move.l #$7000,d0 ;alloc 28K for Rom & Ram banks + move.l #MEMF_PUBLIC!MEMF_CLEAR,d1 + CALLEXEC AllocMem + move.l d0,Bank_PtrVar + beq fail + +;----- Open & set up Con device... ---- + move.l #IOSTD_SIZE,d0 ;alloc mem for IOStdReq... + move.l #MEMF_PUBLIC!MEMF_CLEAR,d1 + CALLEXEC AllocMem + move.l d0,ConReq + beq fail + + lea conname,a0 + move.l #-1,d0 + move.l ConReq,a1 + move.l #0,d1 + CALLEXEC OpenDevice + tst.l d0 + bne fail ;0 is successful + + move.l ConReq,a0 + move.l IO_DEVICE(a0),_ConBase ;get vector base... (unlike libraries) + + lea InputStrct,a0 + move.b #IECLASS_RAWKEY,ie_Class(a0) ;set up static struct... + + + +* Note: Passing args from Devpac supresses last $0A character (NL)... Debugger/Shell don't. +* Normally, a "-2" command is passed as length: 3, data: '-2' + $0a + + cmp.l #2,StartD0 ;# of chars after filename... (inc. NL char) + blo.b .noArg + + move.l StartA0,a0 + + cmp.w #'-2',(a0)+ ;is there a -2 option??? + bne.b .noArg + cmp.l #2,StartD0 + beq.b .SecondDrive ;no more chars... is "-2" + cmp.b #$0a,(a0) + beq.b .SecondDrive ;next char is NL char... is "-2" + cmp.b #' ',(a0) + beq.b .SecondDrive ;next char is Space... is "-2" + bra .noArg ;else NOT "-2" + +.SecondDrive + lea .2ndmsg,a0 ;diagnostic "2nd drive" msg + jsr DB_String + + move.l #disk_TrackLen*35,d0 ;alloc 215K ram for disk buffer + move.l #MEMF_PUBLIC!MEMF_CLEAR,d1 + CALLEXEC AllocMem + move.l d0,disk_Buffer2 + beq fail + + bra .noArg + +.2ndmsg dc.b "2nd drive option selected.",10,13,0 +;DiskBufferMem ds.b disk_TrackLen*35 ;alloc 215K ram for disk buffer + + +*-----------------------------------------------------* + +.noArg move.l #RomName,d1 ;Load Rom Image + move.l #MODE_OLDFILE,d2 + CALLDOS Open + move.l d0,d4 ;temp + beq failrom + + move.l d4,d1 ;file handle + move.l InstTbl_Var,d2 ;Load Image temporarily into InstTbl buffer + move.l #$3080,d3 ;read $3080 bytes ($d000-$ffff + $80 prodos hdr) + CALLDOS Read + + move.l d4,d1 ;Done loading Rom Image + CALLDOS Close + + move.l InstTbl_Var,a0 + cmp.w #$0a47,(a0) ;first 2 bytes in ProDos header... + bne .NotProDos + cmp.b #$4c,2(a0) ;Third byte in ProDos header... + bne .NotProDos + +.ProDos lea $80(a0),a0 ;Rom image begins $80 bytes later... + bra .DoIt + +.NotProDos + cmp.w #$00d0,(a0) ;Dos 3.3 test (check is A$=$d000) + bne .NotDos3 ;if neither, assume raw image... + +.Dos33 lea $4(a0),a0 ;Rom image begins after 4 byte header + +.NotDos3 ;assume raw image, no header... + + ;a0 -> Rom Image +.DoIt move.l Mem_PtrVar,a1 + lea (a1,$d000.l),a1 ;a1 -> $d000 in apple memory + move.l Bank_PtrVar,a2 + lea (a2,$4000.l),a2 ;a2 -> Rom Buffer (backup) + + move.l #$3000/4-1,d0 +.CpyRom move.l (a0),(a1)+ + move.l (a0)+,(a2)+ + dbf d0,.CpyRom + +*-----------------------------------------------------* + +LoadDiskRom: + move.l #DiskRomName,d1 ;Load Disk Rom Image (If available) + move.l #MODE_OLDFILE,d2 + CALLDOS Open + move.l d0,d4 ;temp + + lea MyDiskRom,a0 ;if no file, copy MyDiskRom image instead... + beq .CopyMem + + move.l d4,d1 ;file handle + move.l InstTbl_Var,d2 ;Load Image temporarily into InstTbl buffer + move.l #$0180,d3 ;read $180 bytes ($c600-$c6ff + $80 prodos hdr) + CALLDOS Read + + move.l d4,d1 ;Done loading Disk Rom Image + CALLDOS Close + +.CheckProDos + move.l InstTbl_Var,a0 + cmp.w #$0a47,(a0) ;first 2 bytes in ProDos header... + bne .CheckDos33 + cmp.b #$4c,2(a0) ;Third byte in ProDos header... + bne .CheckDos33 + +.ProDos lea $80(a0),a0 ;Rom image begins $80 bytes later... + bra .CopyMem + +.CheckDos33 + cmp.w #$00c6,(a0) ;Dos 3.3 test (check if A$=$c600) + bne .NotDos3 ;if neither, assume raw image... + +.Dos33 lea $4(a0),a0 ;Rom image begins after 4 byte header + +.NotDos3 ;assume raw image, no header... + +.CopyMem: ;a0 -> Rom Image + move.l Mem_PtrVar,a1 + lea (a1,$c600.l),a1 ;a1 -> $c600 in apple memory + + move.l #$100/4-1,d0 +.CpyR2 move.l (a0)+,(a1)+ + dbf d0,.CpyR2 + +*-----------------------------------------------------* + + lea MyNewScreen,a0 ;Open my screen! + CALLINT OpenScreen + move.l d0,MyScreen + beq fail + +; move.l MyScreen,a0 ;Set main screen color table to WB defaults +; move.l sc_ViewPort+vp_ColorMap(a0),a2 +; lea MainColorTable,a3 +; move.l a2,a0 +; moveq.l #0,d0 +; CALLGRAF GetRGB4 +; move.w d0,(a3)+ +; move.l a2,a0 +; moveq.l #1,d0 +; CALLGRAF GetRGB4 +; move.w d0,(a3)+ +; move.l a2,a0 +; moveq.l #2,d0 +; CALLGRAF GetRGB4 +; move.w d0,(a3)+ +; move.l a2,a0 +; moveq.l #3,d0 +; CALLGRAF GetRGB4 +; move.w d0,(a3)+ + + move.l MyScreen,a0 + moveq.l #0,d0 ;We have to hide screen title bar so we can receive + CALLINT ShowTitle ;all mouse button clicks into our window... + +*-----------------------------------------------------* + move.l MyScreen,a0 + lea sc_BitMap(a0),a0 ;a1 -> Screen BitMap + move.l bm_Planes(a0),OrigPlane1 ;plug in BitMap Plane Ptrs + move.l bm_Planes+4(a0),OrigPlane2 + move.l bm_Planes+8(a0),OrigPlane3 + move.l bm_Planes+12(a0),OrigPlane4 + move.l bm_Planes+16(a0),OrigPlane5 + + move.w bm_Rows(a0),OrigRows + move.b bm_Depth(a0),OrigDepth + +*-----------------------------------------------------* + +; CALLEXEC Forbid +; +; move.l MyScreen,a0 ;Show my new screen +; CALLINT ScreenToFront ;and help ourselves to view fields... +; +;* Compute screen refresh (hz) with following formula: +;* +;* 1 Line 1 Screen 1 CClk 1000000000 uSecs zz Screens +;* -------- * -------- * --------- * ---------------- = ---------- +;* xx CClks yy Lines 280 uSecs 1 Second 1 second +; +; moveq.l #0,d4 +; move.l _GfxBase,a0 +; move.w gb_current_tot_cclks(a0),d4 ;d4 = CurrentTotColorClks (1 clk=280 uSec) +; moveq.l #0,d5 +; move.w gb_MaxDisplayRow(a0),d5 ;d5 = Current Tot Rows +; +; mulu.w #280,d5 ;*** Compute FrameRate (Hz) *** +; mulu.l d4,d5 ;Hertz = 1,000,000,000/(CClks*TotRow*280) +; move.l #1000000000,d0 +; divu.l d5,d0 ;d0 = hertz +; +; move.l #1026000,d1 ;Apple cycles/frame = 1,024,000 / Hz (+some) +; divu.l d0,d1 ;d1 = Apple CyclesPer Frame! +; +; move.l d1,RealCycPerFrame +; jsr DB_HexL +; +; CALLEXEC Permit + +*--------------------------- Open CIA Timer & setup --------------------------* + +CIASetUp: + move.l #-1,CIAAllocBit + + lea ciaBname,a1 ;Open CIA-B Resource... + CALLEXEC OpenResource + move.l d0,_CIABase + beq fail ;should *never* fail! + +; We attempt opening either CIA timer with the VBlankInterrupt server, because +; some int server is needed in case it gets called! VBlank server wont hurt anything. + +.tryB move.l #VBlankIntServer,a1 ;Can we allocate timer B? + move.l #CIAICRB_TB,d0 + move.l _CIABase,a6 + jsr _LVOAddICRVector(a6) + tst.l d0 + bne .tryA + + move.l #$bfd600,CIATimerLo ;set up all TimerA addresses + move.l #$bfd700,CIATimerHi + move.l #$bfdf00,CIAControlReg + move.l #CIAICRB_TB,CIAAllocBit ;we NEED this to de-alloc later + moveq.b #%00000010,d0 ;to clear timer A intrpt + bra .gotCIA + +.tryA move.l #VBlankIntServer,a1 ;Can we allocate timer A? + move.l #CIAICRB_TA,d0 + move.l _CIABase,a6 + jsr _LVOAddICRVector(a6) + tst.l d0 + bne .failCIA + + move.l #$bfd400,CIATimerLo ;set up all TimerA addresses + move.l #$bfd500,CIATimerHi + move.l #$bfde00,CIAControlReg + move.l #CIAICRB_TA,CIAAllocBit + moveq.b #%00000001,d0 ;to clear timer A intrpt + bra .gotCIA + +.failCIA + move.l MyChannel,d1 + move.l #FailCIAMsg,d2 + move.l #EndFailCIAMsg-FailCIAMsg,d3 + CALLDOS Write + bra exit + +.gotCIA + move.l _CIABase,a6 ;and disable ICR interrupts for timer + jsr _LVOAbleICR(a6) + + move.b ([CIAControlReg.l]),d0 + or.b #%00001000,d0 ;one-shot + and.b #%11011101,d0 ;Cnt 02 pulses, PB6 normal (no extrnl output) + move.b d0,([CIAControlReg.l]) + +TIME EQU 96 ;microSecs (PAL & NTSC) + + move.b #(TIME&$ff),([CIATimerLo.l]) + move.b #(TIME>>8),([CIATimerHi.l]) + + +*-----------------------------------------------------* + +LINES equ 200 + + move.w #320,d0 ;Get -4- Gr1 BitPlanes (320*193) + move.w #LINES*4,d1 + CALLGRAF AllocRaster + move.l d0,Gr1_Planes + beq fail + move.l Gr1_Planes,a1 ;And Clear them! + move.l #40*LINES*4,d0 ;320/8*193*4 + clr.l d1 ; 7720 byte offset to each plane! + CALLGRAF BltClear + + move.w #320,d0 ;Get -4- Gr2 BitPlanes (320*193) + move.w #LINES*4,d1 + CALLGRAF AllocRaster + move.l d0,Gr2_Planes + beq fail + move.l Gr2_Planes,a1 ;And Clear them! + move.l #40*LINES*4,d0 ;320/8*193*4 + clr.l d1 + CALLGRAF BltClear + + move.w #320,d0 ;Get -3- Hgr1 BitPlanes (320*193) + move.w #LINES*3,d1 + CALLGRAF AllocRaster + move.l d0,Hgr1_Planes + beq fail + move.l Hgr1_Planes,a1 ;And Clear them! + move.l #40*LINES*3,d0 ;320/8*193*3 + clr.l d1 + CALLGRAF BltClear + + move.w #320,d0 ;Get -3- Hgr2 BitPlanes (320*193) + move.w #LINES*3,d1 + CALLGRAF AllocRaster + move.l d0,Hgr2_Planes + beq fail + move.l Hgr2_Planes,a1 ;And Clear them! + move.l #40*LINES*3,d0 ;320/8*193*3 + clr.l d1 + CALLGRAF BltClear + + move.w #320,d0 ;Get -1- "BackDrop" BitPlane (320*193) + move.w #LINES,d1 + CALLGRAF AllocRaster + move.l d0,BackDrop_Plane + beq fail + move.l BackDrop_Plane,a0 ;and completely fill it! + move.l #$ffffffff,d0 + move.w #192*40/4-1,d1 +.fill move.l d0,(a0)+ + dbf d1,.fill + moveq.l #0,d0 + move.w #(LINES-192)*40/4-1,d1 +.fill2 move.l d0,(a0)+ + dbf d1,.fill2 + + lea MyNewWindow,a0 ;Open my window! + move.l MyScreen,nw_Screen(a0) ;(into my screen) + CALLINT OpenWindow + move.l d0,MyWindow + beq fail + + move.l MyWindow,a0 + move.l wd_RPort(a0),WinRastPort + + move.l WinRastPort,a1 + moveq.l #1,d0 ;--------------------- + CALLGRAF SetAPen + + move.l WinRastPort,a1 + moveq.l #1,d0 + CALLGRAF SetBPen + + move.l WinRastPort,a1 ;BLUE BACKGROUND TO FAKE TITLE BAR... + move.w #0,d0 + move.w #0,d1 + move.w #320,d2 + move.w #10,d3 + CALLGRAF RectFill + + move.l WinRastPort,a1 + moveq.l #2,d0 + CALLGRAF SetAPen + bra .skip + +.Msg dc.b "APPLE 2000 " ;extra 2 spaces to center it to "APPLE ][" +.MsgLen dc.w .MsgLen-.Msg + +.skip move.l WinRastPort,a1 + lea .Msg,a0 + move.w .MsgLen,d0 + CALLGRAF TextLength + + move.l WinRastPort,a1 + lsr.w d0 ; / 2 + neg.w d0 ; -d0 + add.w #320/2,d0 ;X pos to center string + move.w #7,d1 + CALLGRAF Move + + move.l WinRastPort,a1 + lea .Msg,a0 + move.w .MsgLen,d0 + CALLGRAF Text + + lea StartMsg,a0 + jsr DB_String + +.Sprite move.l MyWindow,a0 ;redefine sprite? + lea SpriteImage,a1 + move.l #4,d0 ;height + move.l #16,d1 ;width + moveq.l #0,d2 + moveq.l #0,d3 + CALLINT SetPointer + bra .skip2 + + + even +.skip2 +****************** Create HiRes Draw Lookup Table ********************** +* Use a 14 bit counter to create a 2 plane response (9 bits each in +* separate words). Table will be indexed via a 14 bit index (scaled by 4), +* and return a LONG with the 1st 9 bits of plane info in the low order +* bits of the low word, and the 2nd 9 bits of plane info in the low order +* bits of the high word (accessibly via a SWAP). +* +* The 14 bits used as an index consist of 11 pixel bits, and 3 "color" bits. +* They are NOT in a very useful or logical order, this routine is made +* so these bit locations are defined. +* +* screen/pixel order: (not actual bit order) +* +* A B C11 - ColorSet Bit +* 12 3456789 01 - Pixel Data +* +* Rules: +* Any pixel 10 (even only) forms a green pixel (plane 1) +* Any pixel 01 (even only) forms a purple pixel (plane 2) +* Green plane saturates single 0 bits between 1 bits (ie: 10101 = 11111) +* Purple plane saturates single 0 bits between 1 bits +* Saturation does NOT apply on color bits at byte edges (pixel 2,3,9,10) +* where A != B or B != C (black or white okay though) +* Any 11 (anywhere) bit pairs form WHITE (both planes on) +* Extreme bits (pixel 1 in byte A & pixel 2 byte C) are discarded... + + + ;as reference... xxxx xxxx xxxx xxxx xxA6 5B65 4321 0C10 + ; ^ ^ ^ ^ + ;for equates, p1 -> p11 is pixel bit # (#0 -> #31) (left->Right as apple maps) + ; c1, c2, c3 = Color bit for byte 1,2, &3 +p1 equ 11 +p2 equ 12 +p3 equ 3 +p4 equ 4 +p5 equ 5 +p6 equ 6 +p7 equ 7 +p8 equ 8 +p9 equ 9 +p10 equ 0 +p11 equ 1 + +c1 equ 13 +c2 equ 10 +c3 equ 2 + + + ;d2 = 14 bit counter, d3 = Plane1 (grn), d4= Plane2 (prp) + ; d5 = Pl1 Saturatd, d6= Pl2 Saturatd + ;d7 = Pixel data in visual order... (bits 10 -> 0) + ;a2 = address to write next entry to... + + move.l HiResDrawTbl,a2 + moveq.l #0,d2 + +BuildHiResTbl: + moveq.l #0,d3 + moveq.l #0,d4 ;clear planes... set as needed... + + * First build normal PIXEL data in visual order... * + * ie: d7 = %0000 0xxx xxxx xxxx +.build moveq.l #0,d7 +.p1 btst.l #p1,d2 + beq .p2 + bset #10,d7 +.p2 btst.l #p2,d2 + beq .p3 + bset #9,d7 +.p3 btst.l #p3,d2 + beq .p4 + bset #8,d7 +.p4 btst.l #p4,d2 + beq .p5 + bset #7,d7 +.p5 btst.l #p5,d2 + beq .p6 + bset #6,d7 +.p6 btst.l #p6,d2 + beq .p7 + bset #5,d7 +.p7 btst.l #p7,d2 + beq .p8 + bset #4,d7 +.p8 btst.l #p8,d2 + beq .p9 + bset #3,d7 +.p9 btst.l #p9,d2 + beq .p10 + bset #2,d7 +.p10 btst.l #p10,d2 + beq .p11 + bset #1,d7 +.p11 btst.l #p11,d2 + beq .Plane1 + bset #0,d7 + +.Plane1 move.l #%10101010101,d3 + and.l d7,d3 ;only green bits in here... + +.Plane2 move.l #%01010101010,d4 + and.l d7,d4 ;only purple bits here... + + +.Sat1 move.l d3,d0 ;start = 001010010100 + move.l d3,d5 + lsl.l #1,d0 ; 010100101000 (left shifted) + lsr.l #1,d5 ; AND 000101001010 (right shifted) + ; -------------- + and.l d0,d5 ; 000100001000 (Saturation Bits + ; to be OR'd later) + +.Sat2 move.l d4,d0 + move.l d4,d6 + lsl.l #1,d0 + lsr.l #1,d6 + and.l d0,d6 ; (Saturation bits for Pl2 to be OR'd + ; later with Unsaturated Plane2 info) + +c1_vs_c2: + btst.l #c1,d2 ;Chk c1 HiBit... + beq .c1Lo +.c1Hi btst.l #c2,d2 ;c1 Hi, chk c2 Bit... + bne c2_vs_c3 ;c1 & c2 Hi, no worries here... + bclr.l #8,d5 ;c1 != c2, different color bits so + bclr.l #9,d5 ; don't saturate between bytes! + bclr.l #8,d6 + bclr.l #9,d6 + bra c2_vs_c3 +.c1Lo btst.l #c2,d2 ;c1 Lo, chk c2... + beq c2_vs_c3 ;c1 & c2 Lo, no worries... + bclr.l #8,d5 + bclr.l #9,d5 + bclr.l #8,d6 + bclr.l #9,d6 + +c2_vs_c3: + btst.l #c2,d2 ;chk c2... + beq .c2Lo +.c2Hi btst.l #c3,d2 ;c2 Hi, chk c3... + bne doneCvs ;c2 & c3 Hi, no worries... + bclr.l #1,d5 + bclr.l #2,d5 + bclr.l #1,d6 + bclr.l #2,d6 + bra doneCvs +.c2Lo btst.l #c3,d2 ;c2 Lo, chk c3... + beq doneCvs + bclr.l #1,d5 + bclr.l #2,d5 + bclr.l #1,d6 + bclr.l #2,d6 + +doneCvs or.l d5,d3 ;take (filtered) saturation bits & insert... + or.l d6,d4 ; "" + + * remember, d7 = %0000 0xxx xxxx xxxx + +.White moveq.l #0,d1 ;ignore c1->c3, look for "11" bits combos + move.l d7,d0 + and.w #%11000000000,d0 + cmp.w #%11000000000,d0 + bne .wh2 + or.w #%11000000000,d1 ;build white bits in D1... +.wh2 move.l d7,d0 + and.w #%01100000000,d0 + cmp.w #%01100000000,d0 + bne .wh3 + or.w #%01100000000,d1 +.wh3 move.l d7,d0 + and.w #%00110000000,d0 + cmp.w #%00110000000,d0 + bne .wh4 + or.w #%00110000000,d1 +.wh4 move.l d7,d0 + and.w #%00011000000,d0 + cmp.w #%00011000000,d0 + bne .wh5 + or.w #%00011000000,d1 +.wh5 move.l d7,d0 + and.w #%00001100000,d0 + cmp.w #%00001100000,d0 + bne .wh6 + or.w #%00001100000,d1 +.wh6 move.l d7,d0 + and.w #%00000110000,d0 + cmp.w #%00000110000,d0 + bne .wh7 + or.w #%00000110000,d1 +.wh7 move.l d7,d0 + and.w #%00000011000,d0 + cmp.w #%00000011000,d0 + bne .wh8 + or.w #%00000011000,d1 +.wh8 move.l d7,d0 + and.w #%00000001100,d0 + cmp.w #%00000001100,d0 + bne .wh9 + or.w #%00000001100,d1 +.wh9 move.l d7,d0 + and.w #%00000000110,d0 + cmp.w #%00000000110,d0 + bne .wh10 + or.w #%00000000110,d1 +.wh10 move.l d7,d0 + and.w #%00000000011,d0 + cmp.w #%00000000011,d0 + bne .doneWhite + or.w #%00000000011,d1 + +.doneWhite: + or.w d1,d3 + or.w d1,d4 ;OR white bits to both planes... + + lsr.w #1,d3 + lsr.w #1,d4 ;eliminate last bit on each... + and.w #%111111111,d3 + and.w #%111111111,d4 ;only want these 9 bits! + + move.w d3,(a2)+ ;1st word in table... + move.w d4,(a2)+ ;2nd word in table... ! + + addq.w #1,d2 + cmp.w #16384,d2 ;0 -> 16383 (16384 entries for 14 bit indx) + blo BuildHiResTbl + +.DoneHGRTable + move.l MyWindow,a0 + CALLINT ActivateWindow + +**************************** Init INTrpt servers ********************** + + move.l #INTB_VERTB,d0 + lea VBlankIntServer,a1 + CALLEXEC AddIntServer + move.w #1,VBlankIntActive + +**************************** Init & Start 6502 emulation as subtask! *************** + + move.l #-1,d0 + CALLEXEC AllocSignal + move.l d0,ParentSigBit + bmi fail ;or for byte?should never fail anyways... + moveq.l #0,d1 + bset d0,d1 + move.l d1,ParentSigMask + + move.l #0,a1 ;Find Parent TaskPtr for signalling later... + CALLEXEC FindTask + move.l d0,ParentTaskPtr + + move.l #8192,d0 ;alloc 8k ram for SubTask Stack... + move.l #MEMF_CLEAR,d1 + CALLEXEC AllocMem + move.l d0,MySubStack + beq fail + + move.l #TC_SIZE,d0 ;alloc task control structure + move.l #MEMF_PUBLIC!MEMF_CLEAR,d1 + CALLEXEC AllocMem + move.l d0,MySubTask + beq fail + + move.l MySubTask,a0 ;init Task Cntl Struct (priority set -1) + move.b #NT_TASK,LN_TYPE(a0) + move.l #SubTaskName,LN_NAME(a0) + move.b #-1,LN_PRI(a0) ;Must be low Pri since hogs CPU...! + move.l MySubStack,TC_SPLOWER(a0) ;start of stack... + move.l MySubStack,a1 + lea 8188(a1),a1 ;4 bytes less than top of stack.. ? + move.l a1,TC_SPUPPER(a0) + move.l a1,TC_SPREG(a0) + + move.l a0,a1 ;Task Control struct... + move.l #Start6502,a2 ;PC beginning + move.l #0,a3 ;Finalize code... (shouldn't quit!) + CALLEXEC AddTask ;start the 6502 module!!! + + move.l ParentSigMask,d0 + CALLEXEC Wait ;Wait until 6502 task is initialized... + + jmp Main ;Main program!!!!! + +***************** VBlank-INT server ********************** + CNOP 0,4 +VBlankServerCode: + move.w $dff014.l,PotPosition ;Read Joystick X/Y positions + + move.l PotBits,d1 ;mask + btst.l #0,d1 ;is the start bit owned? + beq.b .done + move.l #$1,d0 ;Yes, then restart counters... + CALLPOTGO WritePotgo + +.done move.l #$dff000,a0 + moveq.l #0,d0 + rts + +PotPosition dc.w 0 +VBlankIntActive dc.w 0 ;boolean- is this intrpt installed? + +PotMinX dc.b 0 ;used for dynamic joystick range setting... +PotMaxX dc.b 0 +PotMinY dc.b 0 +PotMaxY dc.b 0 +PdlMode dc.b 0 ;boolean, TRUE if Paddle, FALSE if Analog Joystick + EVEN +;---------- and Static Structure ----------- + +VBlankIntServer dc.l 0,0 ;STATIC Interrupt-Server Struct + dc.b NT_INTERRUPT + dc.b 15 + dc.l .name + dc.l 0 ;IS_Data + dc.l VBlankServerCode + +.name dc.b "Apple2000 VBlank Interrupt Server",0 + EVEN + +*************** Some Copper SetUp Subs ******************** +* +* SetCop- Does a CMove & CBump, no need to re-load CopperPtr every time... +* Enter: a3= CopperList, d3 = Register, d4 (word)= Data + +SetCop move.l a3,a1 ;cop ptr + move.l d3,d0 ;register + move.w d4,d1 ;data + CALLGRAF CMove + move.l a3,a1 ;cop ptr + CALLGRAF CBump + rts + + dc.b "Apple 2000, Copyright 1994 by Kevin Kralian",0 + even + + +*************** Do "turn off screen" Effect! ******************** +FadeEffect: + move.l MyScreen,a0 ;*** restore orig screen ptrs *** + lea sc_BitMap(a0),a0 ;a1 -> Screen BitMap + move.l OrigPlane1,bm_Planes(a0) ;plug in BitMap Plane Ptrs + move.l OrigPlane2,bm_Planes+4(a0) + move.l OrigPlane3,bm_Planes+8(a0) + move.l OrigPlane4,bm_Planes+12(a0) + move.l OrigPlane5,bm_Planes+16(a0) + + move.w OrigRows,bm_Rows(a0) + move.b OrigDepth,bm_Depth(a0) + +.Sprite move.l MyWindow,a0 ;setup an invisible sprite! + lea SpriteImage,a1 + + move.l #4,d0 ;height + move.l #16,d1 ;width + moveq.l #0,d2 + moveq.l #0,d3 + CALLINT SetPointer + + move.l MyScreen,a0 ;Rebuild local VPort copper list (but not display) + CALLINT MakeScreen + CALLINT RethinkDisplay ;and update screen! + + lea .OffClr,a5 + move.l a5,a1 ;a1 -> ColorList + move.l MyScreen,a0 ;Set Colors... (IF NEEDED!) + lea sc_ViewPort(a0),a0 ;a0 -> Screen ViewPort + move.w #4,d0 ;d0 = # of colors + CALLGRAF LoadRGB4 ;(takes effect immed, but doesn't ReThink display) + + move.l MyWindow,a0 + move.l wd_RPort(a0),.Rp + + move.l .Rp,a1 ;*** Draw 4 concentric rectangles *** + moveq.l #0,d0 + CALLGRAF SetAPen + + move.l .Rp,a1 + move.w #0,d0 + move.w #0,d1 + move.w #319,d2 + move.w #199,d3 + CALLGRAF RectFill + + move.l .Rp,a1 + moveq.l #1,d0 + CALLGRAF SetAPen + + move.l .Rp,a1 + move.w #50,d0 + move.w #35,d1 + move.w #319-50,d2 + move.w #199-35,d3 + CALLGRAF RectFill + + move.l .Rp,a1 + moveq.l #2,d0 + CALLGRAF SetAPen + + move.l .Rp,a1 + move.w #100,d0 + move.w #70,d1 + move.w #319-100,d2 + move.w #199-70,d3 + CALLGRAF RectFill + + move.l .Rp,a1 + moveq.l #3,d0 + CALLGRAF SetAPen + + move.l .Rp,a1 + move.w #158,d0 + move.w #98,d1 + move.w #161,d2 + move.w #101,d3 + CALLGRAF RectFill ;Done rectangles + +.lp lea 8(a5),a5 + tst.w (a5) + bmi.b .done + move.l MyScreen,a0 ;Set Colors... (IF NEEDED!) + lea sc_ViewPort(a0),a0 ;a0 -> Screen ViewPort + move.w #4,d0 ;d0 = # of colors + move.l a5,a1 ;a1 -> ColorList + CALLGRAF LoadRGB4 ;(takes effect immed, but doesn't ReThink display) + + + CALLGRAF WaitTOF + CALLGRAF WaitTOF + CALLGRAF WaitTOF + bra.b .lp + +.done rts + + +.OffClr dc.w $0eee,$0eee,$0eee,$0eee ;color list for "turn off monitor" effect + dc.w $0eee,$0eee,$0eee,$0eee + dc.w $0eee,$0eee,$0eee,$0eee + dc.w $0eee,$0eee,$0eee,$0eee + dc.w $0eee,$0eee,$0eee,$0eee + dc.w $0000,$0eee,$0eee,$0eee + dc.w $0000,$0000,$0eee,$0eee + dc.w $0000,$0000,$0000,$0eee + dc.w $0000,$0000,$0000,$0eee + dc.w $0000,$0000,$0000,$0fff + dc.w $0000,$0000,$0000,$0fff + dc.w $0000,$0000,$0000,$0ddd + dc.w $0000,$0000,$0000,$0eee + dc.w $0000,$0000,$0000,$0ede + dc.w $0000,$0000,$0000,$0ede + dc.w $0000,$0000,$0000,$0ece + dc.w $0000,$0000,$0000,$0ece + dc.w $0000,$0000,$0000,$0dce + dc.w $0000,$0000,$0000,$0cce + dc.w $0000,$0000,$0000,$0cde + dc.w $0000,$0000,$0000,$0dde + dc.w $0000,$0000,$0000,$0eee + dc.w $0000,$0000,$0000,$0ddd + dc.w $0000,$0000,$0000,$0ccc + dc.w $0000,$0000,$0000,$0ddd + dc.w $0000,$0000,$0000,$0ccc + dc.w $0000,$0000,$0000,$0bbb + dc.w $0000,$0000,$0000,$0aaa + dc.w $0000,$0000,$0000,$0999 + dc.w $0000,$0000,$0000,$0888 + dc.w $0000,$0000,$0000,$0777 + dc.w $0000,$0000,$0000,$0666 + dc.w $0000,$0000,$0000,$0555 + dc.w $0000,$0000,$0000,$0444 + dc.w $0000,$0000,$0000,$0333 + dc.w $0000,$0000,$0000,$0222 + dc.w $0000,$0000,$0000,$0222 + dc.w $0000,$0000,$0000,$0111 + dc.w $0000,$0000,$0000,$0000 + dc.w $0000,$0000,$0000,$0000 + dc.w $0000,$0000,$0000,$0000 + dc.w $0000,$0000,$0000,$0000 + dc.w -1 + +.Rp dc.l 0 ;windows RastPort + even + +***************** NOW CLOSE EVERYTHING ***************** + +failLoad move.l MyChannel,d1 + move.l #NoFileMsg,d2 + move.l #EndNoFileMsg-NoFileMsg,d3 + CALLDOS Write + bra exit + +Fail020 move.l MyChannel,d1 + move.l #Fail020Msg,d2 + move.l #EndFail020Msg-Fail020Msg,d3 + CALLDOS Write + bra exit + +failrom move.l MyChannel,d1 + move.l #NoRomMsg,d2 + move.l #EndNoRomMsg-NoRomMsg,d3 + CALLDOS Write +; bra fail + +fail move.l MyChannel,d1 ;Error exit! + move.l #FailMsg,d2 + move.l #EndFailMsg-FailMsg,d3 + CALLDOS Write + + ;Clean exit... + +exit: + +.VBInt tst.w VBlankIntActive + beq.b .sub + move.l #INTB_VERTB,d0 ;remove VBlank int server... + lea VBlankIntServer,a1 + CALLEXEC RemIntServer + move.w #0,VBlankIntActive + +.sub tst.l MySubTask ;free subtask mem... + beq.b .mss + move.l MySubTask,a1 + move.l #TC_SIZE,d0 + CALLEXEC FreeMem + +.mss tst.l MySubStack ;free SubTask's Stack mem... + beq.b .EReq + move.l MySubStack,a1 + move.l #8192,d0 + CALLEXEC FreeMem + +.EReq tst.l EasyReq + beq.b .FReq + move.l EasyReq,a1 + CALLREQ rtFreeRequest ;okay to pass NULL... + +.FReq tst.l FileReq + beq.b .Tmr + move.l FileReq,a1 + CALLREQ rtFreeRequest + +.Tmr + +.IORq tst.l ConReq ;close device... + beq.b .Amem + move.l ConReq,a1 + CALLEXEC CloseDevice + +.IORq2 move.l ConReq,a1 + move.l #IOSTD_SIZE,d0 ;& free mem for IOStdReq. + CALLEXEC FreeMem + +.Amem tst.l Mem_PtrVar ;free Apple mem image + beq.b .BnkMem + move.l Mem_PtrVar,a1 + move.l #65545,d0 + CALLEXEC FreeMem + +.BnkMem tst.l Bank_PtrVar ;Free Rom & Ram banks + beq.b .timer + move.l Bank_PtrVar,a1 + move.l #$7000,d0 + CALLEXEC FreeMem + +.timer move.l CIAAllocBit,d0 ;timer 'x' + bmi.b .hires + move.l #VBlankIntServer,a1 ;Deallocate CIA intrpt + move.l _CIABase,a6 + jsr _LVORemICRVector(a6) + clr.l CIAAllocBit + + +.hires +; tst.l HiResDrawTbl ;free 64k hires draw lookup tbl... +; beq .disk +; move.l HiResDrawTbl,a1 +; move.l #65536,d0 +; CALLEXEC FreeMem + +.disk tst.l disk_Buffer2 ;free disk buffer + beq.b .InsTbl + move.l disk_Buffer2,a1 + move.l #disk_TrackLen*35,d0 + CALLEXEC FreeMem + +.InsTbl ;its a static buffer now + + + +.win tst.l MyWindow ;close window if open + beq.b .scrn1 + move.l MyWindow,a0 + CALLINT CloseWindow + +.scrn1 tst.l MyScreen ;close screen if open + beq.b .BkDp + move.l MyScreen,a0 + CALLINT CloseScreen + +.BkDp tst.l BackDrop_Plane ;Close Bkdrop Bitplanes if exists + beq.b .txt2pl + move.l BackDrop_Plane,a0 + move.w #320,d0 + move.w #LINES,d1 + CALLGRAF FreeRaster + + +.txt2pl + + ;removed text2 planes... + +.gr1pl tst.l Gr1_Planes ;Close Gr1 Bitplanes if exists + beq.b .gr2pl + move.l Gr1_Planes,a0 + move.w #320,d0 + move.w #LINES*4,d1 + CALLGRAF FreeRaster + +.gr2pl tst.l Gr2_Planes ;Close Gr2 Bitplanes if exists + beq.b .hgr1pl + move.l Gr2_Planes,a0 + move.w #320,d0 + move.w #LINES*4,d1 + CALLGRAF FreeRaster + +.hgr1pl tst.l Hgr1_Planes ;Close Hgr1 Bitplanes if exists + beq.b .hgr2pl + move.l Hgr1_Planes,a0 + move.w #320,d0 + move.w #LINES*3,d1 + CALLGRAF FreeRaster + +.hgr2pl tst.l Hgr2_Planes ;Close Hgr2 Bitplanes if exists + beq.b .hgrDpl + move.l Hgr2_Planes,a0 + move.w #320,d0 + move.w #LINES*3,d1 + CALLGRAF FreeRaster + +.hgrDpl +.temp + +.FreBts tst.l PotBits ;if we have any still allocated... + beq.b .lib + move.l PotBits,d0 ;free potgo bits #8 & bit #9... (DATLX & OUTLX) + CALLPOTGO FreePotBits + clr.l PotBits + +.lib tst.l _REQBase ;Close ReqTools.lib if open + beq.b 3$ + move.l _REQBase,a1 + CALLEXEC CloseLibrary + +3$ tst.l _IntuitionBase ;Close IntuitionLib if open + beq.b 4$ + move.l _IntuitionBase,a1 + CALLEXEC CloseLibrary + +4$ tst.l _GfxBase ;Close GfxLib if open + beq.b 6$ + move.l _GfxBase,a1 + CALLEXEC CloseLibrary + +6$ tst.l _DOSBase ;Close DosLib if open + beq.b 7$ + move.l _DOSBase,a1 + CALLEXEC CloseLibrary + +7$ rts + + CNOP 0,4 + +*************************** System Pointers ********************** +VarList: +_DOSBase dc.l 0 ;space for lib ptr +_GfxBase dc.l 0 +_IntuitionBase dc.l 0 +_REQBase dc.l 0 ;ptr for ReqTools lib... +_ConBase dc.l 0 ;from IOStdReq.io_Device after opening device... + +_PotgoBase dc.l 0 ;resource, don't close it! +_CIABase dc.l 0 ;resource for CIA timers + +PotBits dc.l 0 ;bits we allocated to read joystick btn #2 + +MyScreen dc.l 0 +MyWindow dc.l 0 + +MyChannel dc.l 0 +Mem_PtrVar dc.l 0 ;ptr to start of Apple Memory Block +Bank_PtrVar dc.l 0 ;ptr to block of Rom & Ram Banks +WinRastPort dc.l 0 +InstTbl_Var dc.l 0 ;ptr to 256K JmpTbl of 6502 instructions +ConReq dc.l 0 ;ptr to IOStdReq for CON access +HiResDrawTbl dc.l 0 ;ptr to 64k lookup tbl for byte -> Plane data + +***************************** Input stuff *************************** + EVEN +KeyBuffer ds.b 80 + EVEN +InputStrct ds.b ie_SIZEOF ;actual structure! + CNOP 0,4 + +*************************** ReqTools variables ************************* + +EasyReq dc.l 0 ;ptr to my EasyRequester struct... +FileReq dc.l 0 ;ptr to my File Requester struct... + +*************************** BitPlane Raster Pointers ************************* +Gr1_Planes dc.l 0 +Gr2_Planes dc.l 0 +Hgr1_Planes dc.l 0 +Hgr2_Planes dc.l 0 +BackDrop_Plane dc.l 0 + +*************************** task & signal vars *********************** +MySubTask dc.l 0 +MySubStack dc.l 0 +ParentSigBit dc.l 0 +ParentSigMask dc.l 0 +ChildSigBit dc.l 0 +ChildSigMask dc.l 0 + +ParentTaskPtr dc.l 0 + +********************** Disk drive interface variables *********************** +disk_Buffer dc.l 0 ;Ptr to 1st disk buffer ** 2 fields must be together ** +disk_Buffer2 dc.l 0 ;Ptr to 2nd disk buffer, or NULL if not present + +disk_Track dc.b 00 ;Track currently resting on. 0 -> 34 +disk_Track2 dc.b 00 ;** These 2 byte fields MUST follow each other ** + +disk_Phase dc.b 0 ;a 0,1,2 or 3 based on last hi-set phase... +disk_Phase2 dc.b 0 ;** These 2 byte fields MUST follow each other ** + +disk_Changed dc.b 0 ;boolean of whether data has been changed +disk_Changed2 dc.b 0 ;(used for "Save changes to disk xxx first?") + +disk_TkStrt dc.l 0 ;Ptr to memory where track info starts +disk_TkPos dc.l 0 ;Offset (0 -> 4096) into track + +disk_Q6 dc.b 0 ; +disk_Q7 dc.b 0 ;r/w mode boolean... 0 = read, !0 = Write +disk_DriveW dc.w 0 ;drive selected (0=drive 1 or 1=drive 2) +disk_Motor dc.b 0 ;drive on? Boolean 0=off, 1=on + +disk_Latch dc.b 0 ;latch where data goes to be written... + +Dest_Disk_Buffer dc.l 0 ;ptr to disk buffer used for disk image "loading" +Src_Disk_Buffer dc.l 0 ;ptr to disk buffer used for disk image "saving" + +disk_TrackLen EQU $18a0 ;CONST length of track... + +;Filler dcb.l 1024 + +EndVarList dc.l 0 ;---- end of variables to be cleared at start time! ---- + + + +StartA0 dc.l 0 ;(Outside VarList on purpose) +StartD0 dc.l 0 ;save CLI info when start... + + EVEN + + SECTION SpriteData,DATA_C +SpriteImage dc.w $0000,$0000 ;system position stuff + dc.w %0000000000000000,%0000000000000000 ;data... + dc.w %0000000000000000,%0000000000000000 + dc.w %0000000000000000,%0000000000000000 + dc.w %0000000000000000,%0000000000000000 + dc.w $0000,$0000 ;reserved by system + + SECTION MemoryHunk1,BSS +InstLookUpTableMem ds.b 262148 + + SECTION MemoryHunk2,BSS +HiResDrawTableMem ds.b 65536 + + SECTION MemoryHunk3,BSS +DiskBufferMem ds.b disk_TrackLen*35 ;alloc 215K ram for disk buffer + + +*************************************************************************************** + SECTION InitializedStructs,DATA + +;------------------------ Intuition Structures -------------------------- + +MyNewScreen: + dc.w 0,0,320,LINES,2 ;x/y/width/height/depth + dc.b 0,1 ;detailpen/blockpen + dc.w 0 ;viewmodes + dc.w CUSTOMSCREEN!SCREENQUIET ;type + dc.l .TxtAtr,.Ttl ;Font,Title + dc.l 0,0 ;Gadgets,BitMap +.Ttl dc.b "Happy Bear?",0 + EVEN + +.TxtAtr dc.l .Font ;Text attribute for NewScreen + dc.w 8 + dc.b FS_NORMAL + dc.b FPF_ROMFONT!FPF_DESIGNED +.Font dc.b "topaz.font",0 + EVEN + +MyNewWindow: + dc.w 0,0,320,LINES ;x/y/w/h + dc.b 0,1 ;detail/block pens + dc.l RAWKEY!MOUSEBUTTONS!INTUITICKS ;IDCMP codes + dc.l SMART_REFRESH!NOCAREREFRESH!BACKDROP!RMBTRAP!BORDERLESS ;flags + dc.l 0,0 ;gadget,checkmark + dc.l 0 ;WndwTtl + dc.l 0 ;Screen (FILL LATER) + dc.l 0 ;super bitmap + dc.w 40,40,-1,-1 ;min w/h, max w/h + dc.w CUSTOMSCREEN ;type of scrn to open on +.Ttl dc.b 0,"APPLE 2000 Window",0 + EVEN + + +*********************** Speed Regulation/Timer stuff *************************** + +CIATimerLo dc.l 0 ;ptrs for alloc'd CIA timer regs +CIATimerHi dc.l 0 +CIAControlReg dc.l 0 +CIAAllocBit dc.l -1 ;Allocated Int bit (used for de-alloc) + + +LastStopCycle dc.l 0 ;Cycle # we started regulation period on + +CPF equ 150 ;assuming 1.024 Mhz clock??? +RealCycPerFrame dc.l CPF +WaitCycPerFrame dc.l CPF + + + +;--------------------- Names & Messages -------------------------------- + +SubTaskName dc.b "Apple 6502 CPU Emulation",0 + +StartMsg dc.b "Libraries, AppleRom, Screen, Window Opened Ok...",10,13,0 + +FailMsg dc.b "Whoops, failed somewhere!",10,13 +EndFailMsg + +NoRomMsg dc.b "Startup Error: _APPLE.ROM file not found! ",10,13 +EndNoRomMsg + +FailCIAMsg dc.b "Startup Error: Couldn't obtain either CIAB timer!",10,13 +EndFailCIAMsg + +Fail020Msg dc.b "Sorry, Apple 2000 requires at least a 68020 CPU.",10,13 +EndFail020Msg + +RomName dc.b "_Apple.Rom",0 +DiskRomName dc.b "_Disk.Rom",0 + +MMUMsg dc.b "Sorry, this version requires an MMU.",10,13 + +NoFileMsg dc.b "File specified not found! ",10,13 +EndNoFileMsg + +BSMsg1 dc.b "Experimental Code Caching ",0 +BSMsg2 dc.b "On",10,13,0 +BSMsg3 dc.b "Off",10,13,0 +BSMsg4 dc.b "-Shadowed- video refreshing",0 +BSMsg5 dc.b "-Periodic Refresh- video refreshing",0 + +dosname DOSNAME ;from the dos_lib.i include... dcb ... +execname EXECNAME +grafname GRAFNAME +intname INTNAME +reqname REQTOOLSNAME +ciaBname CIABNAME +potgoname dc.b "potgo.resource",0 +conname dc.b "console.device",0 + +BSMsg6 dc.b "Sorry, AAA video drivers not complete.",10,13 + + * ReqTools Messages/TagLists * + +LoadMsg dc.b "Select File to Load:",0 +SaveMsg dc.b "Select File to Save:",0 + +;QuitMsg dc.b "Really Quit?" +;QuitAnsMsg dc.b "Yes|No" + + CNOP 0,4 +;------------------------ MyColor Tables --------------------------- +; Each color Table is the # of colors followed by the xRGB definition for each (WORDS) + +MainColorTable dc.w $0004 + dc.w $0000,$089a,$0fff,$0888 + dc.w $0000,$0eee,$000a,$0888 ;old colors + +TxtColorTable dc.w $0004 + dc.w $0000,$0eee,$0000,$0eee +HiResColorTable dc.w $0010 + dc.w $0000,$0eee,$0000,$0eee,$0666,$0888,$0aaa,$0ccc + dc.w $0000,$00e0,$0a0e,$0eee,$0000,$0e60,$000e,$0eee +GrColorTable dc.w $0020 + dc.w $0000,$0eee,$0000,$0eee,$0666,$0888,$0aaa,$0ccc + dc.w $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000 + dc.w $0000,$0e00,$0008,$0a0e,$00a0,$0a9a,$000a,$000e + dc.w $0830,$0e60,$0ba9,$0f3d,$00e0,$0ed0,$00ae,$0eee +Flash1ColorTbl dc.w $0004 + dc.w $0000,$0eee,$0000,$0eee +Flash2ColorTbl dc.w $0004 + dc.w $0000,$0eee,$0eee,$0000 + + EVEN +;----------------------- My DiskRom image ----------------------------- +MyDiskRom: + dc.b $A2,$20,$A0,$00,$A2,$03,$86,$3C,$A2,$09,$BD,$40,$C6,$9D,$0E,$04 + dc.b $CA,$10,$F7,$A9,$60,$85,$2B,$AD,$EE,$C0,$AD,$EC,$C0,$AD,$EA,$C0 + dc.b $AD,$E9,$C0,$A9,$00,$8D,$28,$C0,$A9,$90,$8D,$28,$C0,$D0,$21,$60 + dc.b $EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA + dc.b $C1,$D0,$D0,$CC,$C5,$A0,$B2,$B0,$B0,$B0,$EA,$EA,$EA,$EA,$EA,$EA + dc.b $A9,$00,$85,$26,$85,$3D,$85,$41,$A9,$08,$85,$27,$48,$EA,$AD,$EC + dc.b $C0,$EA,$EA,$C9,$D5,$D0,$F7,$AD,$EC,$C0,$C9,$AA,$D0,$F5,$AD,$EC + dc.b $C0,$C9,$96,$D0,$E9,$AD,$29,$C0,$D0,$09,$F0,$07,$60,$EA,$EA,$EA + dc.b $EA,$EA,$EA,$AD,$29,$C0,$85,$40,$EA,$C5,$41,$D0,$D1,$AD,$29,$C0 + dc.b $C5,$3D,$D0,$CA,$AD,$EC,$C0,$C9,$D5,$D0,$F9,$F0,$09,$EA,$EA,$EA + dc.b $EA,$EA,$EA,$EA,$EA,$EA,$AD,$EC,$C0,$C9,$AA,$D0,$EA,$AD,$EC,$C0 + dc.b $C9,$AD,$D0,$AA,$A9,$00,$A0,$56,$4D,$28,$C0,$88,$99,$00,$03,$D0 + dc.b $F7,$4D,$28,$C0,$91,$26,$C8,$D0,$F8,$4D,$28,$C0,$D0,$90,$F0,$06 + dc.b $EA,$EA,$EA,$90,$87,$EA,$68,$A2,$56,$CA,$30,$FB,$B1,$26,$5E,$00 + dc.b $03,$2A,$5E,$00,$03,$2A,$91,$26,$C8,$D0,$EE,$E6,$27,$E6,$3D,$A5 + dc.b $3D,$CD,$00,$08,$A6,$2B,$90,$DB,$4C,$01,$08,$00,$00,$00,$00,$00 + +;--------------------------- BackUp Bitmap data --------------------- +OrigScrnRasInfo dc.l 0 ;backup stuff to restore to close screen... +OrigPlane1 dc.l 0 +OrigPlane2 dc.l 0 +OrigPlane3 dc.l 0 +OrigPlane4 dc.l 0 +OrigPlane5 dc.l 0 + +OrigRows dc.w 0 +OrigDepth dc.b 0 + EVEN +; +; SECTION MemoryHunk4,BSS +; ds.b 1 +*************************************************************************************** + diff --git a/src/TextMap.s b/src/TextMap.s new file mode 100644 index 0000000..3d14fa4 --- /dev/null +++ b/src/TextMap.s @@ -0,0 +1,459 @@ +* Needs to be included in file with "WinRastPort" set and FPutByte available. +* enter with: a0=address to write ($400-$7ff for PBTxt1), and d1=data. + + SECTION APPLEII,CODE + EVEN + CNOP 0,4 +PBTxt1 cmp.b (Mem_Ptr,a0.l),d1 ;1st check if mem is different! + beq.b .rts ;mem is same so video is same; don't change anything + move.b d1,(Mem_Ptr,a0.l) ;FPUBYTE, write data to mem... + and.w #$ff,d1 + move.w d1,a6 + + move.l #TxtLookUp-$800,a1 + move.w (a1,a0.w*2),d1 ;d1 = BPlane Ptr Offset for particular address + bmi.b .rts + + move.l #IIeCharSet,a1 [03] + lea (a1,a6.w*8),a1 ;a1 -> CharSet for letter!!! [08] + +.Do_txt move.l Gr1_Planes,a0 ;a0 -> GR1 Plane1 ... (new test) + add.w d1,a0 ;a0 -> Plane1StartLoc + + move.b (a1)+,(a0) ;line 1 + move.b (a1)+,40(a0) ;line 2 + move.b (a1)+,80(a0) ;line 3 + move.b (a1)+,120(a0) ;line 4 + move.b (a1)+,160(a0) ;line 5 + move.b (a1)+,200(a0) ;line 6 + move.b (a1)+,240(a0) ;line 7 + move.b (a1)+,280(a0) ;line 8 + + move.l #IIeCharSet2,a1 + move.b (a1,a6.w),d0 ;a6 still present from above...! + + move.b d0,0+LINES*40(a0) + move.b d0,40+LINES*40(a0) ;line 2 + move.b d0,80+LINES*40(a0) ;line 3 + move.b d0,120+LINES*40(a0) ;line 4 + move.b d0,160+LINES*40(a0) ;line 5 + move.b d0,200+LINES*40(a0) ;line 6 + move.b d0,240+LINES*40(a0) ;line 7 + move.b d0,280+LINES*40(a0) ;line 8 +.rts +AnRts rts + +**************************************************** + + CNOP 0,4 +PBGr1 cmp.b (Mem_Ptr,a0.l),d1 ;1st check if mem is different! + beq.b AnRts ;mem is same so video is same; don't change anything + move.b d1,(Mem_Ptr,a0.l) ;FPUBYTE, write data to mem... + and.w #$ff,d1 + move.w d1,a6 + + move.l #TxtLookUp-$800,a1 + move.w (a1,a0.w*2),d1 ;d1 = BPlane Ptr Offset for particular address + bmi.b AnRts + +.dogr move.l Gr1_Planes,a0 ;a0 -> GR1 Plane1 + +GRFX add.w d1,a0 ;a0 -> GrPlane1 Start Loc (d1 still there???) + move.w a6,d1 + +****** Top 4 pixel lines of byte data.... ***** +*** (Done top 4 then bottom 4 in order to check bit data with LSR's) +*** BitPlane 1 **** Opt later by LSR'ing a Dn instead of Btsts on Mem... + lsr.b #1,d1 *** Opt later by only drawing 1 line for each color via Copper magic! + scs.b d0 ;bit set? Put a $ff in d0. Else, put $00 in d0! + + move.b d0,(a0) ;line 1 + move.b d0,40(a0) ;line 2 + move.b d0,80(a0) ;line 3 + move.b d0,120(a0) ;line 4 +**** BitPlane 2 + lsr.b #1,d1 + scs.b d0 ;bit set? Put a $ff in d0. Else, put $00 in d0! + + move.b d0,LINES*40(a0) ;line 1 + move.b d0,40+LINES*40(a0) ;line 2 + move.b d0,80+LINES*40(a0) ;line 3 + move.b d0,120+LINES*40(a0) ;line 4 +**** BitPlane 3 + lsr.b #1,d1 + scs.b d0 ;bit set? Put a $ff in d0. Else, put $00 in d0! + + move.b d0,LINES*40*2(a0) ;line 1 + move.b d0,40+LINES*40*2(a0) ;line 2 + move.b d0,80+LINES*40*2(a0) ;line 3 + move.b d0,120+LINES*40*2(a0) ;line 4 +**** BitPlane 4 + lsr.b #1,d1 + scs.b d0 ;bit set? Put a $ff in d0. Else, put $00 in d0! + + move.b d0,0+LINES*40*3(a0) ;line 1 + move.b d0,40+LINES*40*3(a0) ;line 2 + move.b d0,80+LINES*40*3(a0) ;line 3 + move.b d0,120+LINES*40*3(a0) ;line 4 + +******* Bottom 4 lines based on byte data,,, +*** BitPlane 1 + lsr.b #1,d1 + scs.b d0 ;bit set? Put a $ff in d0. Else, put $00 in d0! + + move.b d0,160(a0) ;line 5 + move.b d0,200(a0) ;line 6 + move.b d0,240(a0) ;line 7 + move.b d0,280(a0) ;line 8 +**** BitPlane 2 + lsr.b #1,d1 + scs.b d0 ;bit set? Put a $ff in d0. Else, put $00 in d0! + + move.b d0,160+LINES*40(a0) ;line 5 + move.b d0,200+LINES*40(a0) ;line 6 + move.b d0,240+LINES*40(a0) ;line 7 + move.b d0,280+LINES*40(a0) ;line 8 +**** BitPlane 3 + lsr.b #1,d1 + scs.b d0 ;bit set? Put a $ff in d0. Else, put $00 in d0! + + move.b d0,160+LINES*40*2(a0) ;line 5 + move.b d0,200+LINES*40*2(a0) ;line 6 + move.b d0,240+LINES*40*2(a0) ;line 7 + move.b d0,280+LINES*40*2(a0) ;line 8 +**** BitPlane 4 + lsr.b #1,d1 + scs.b d0 ;bit set? Put a $ff in d0. Else, put $00 in d0! + + move.b d0,160+LINES*40*3(a0) ;line 5 + move.b d0,200+LINES*40*3(a0) ;line 6 + move.b d0,240+LINES*40*3(a0) ;line 7 + move.b d0,280+LINES*40*3(a0) ;line 8 + + rts + +*********************************************** + CNOP 0,4 + +PBGrTxt1: + cmp.b (Mem_Ptr,a0.l),d1 ;1st check if mem is different! + beq.b .rts ;mem is same so video is same; don't change anything + move.b d1,(Mem_Ptr,a0.l) ;FPUBYTE, write data to mem... + and.w #$ff,d1 + move.w d1,a6 + + move.l #TxtLookUp-$800,a1 + move.w (a1,a0.w*2),d1 ;d1 = BPlane Ptr Offset for particular address + bmi.b .rts + + move.l Gr1_Planes,a0 + +.choose cmp.w #20*320+00,d1 ;cmp to 1st txt line addr... + bhs.b .txt + +.do_gr bra GRFX ;Go draw grfx block (a0/d1 set) + +.rts rts + +.txt move.l #IIeCharSet,a1 [03] + lea (a1,a6.w*8),a1 ;a1 -> CharSet for letter!!! [08] + + add.w d1,a0 ;a0 -> Plane1StartLoc + + move.b (a1)+,(a0) ;line 1 + move.b (a1)+,40(a0) ;line 2 + move.b (a1)+,80(a0) ;line 3 + move.b (a1)+,120(a0) ;line 4 + move.b (a1)+,160(a0) ;line 5 + move.b (a1)+,200(a0) ;line 6 + move.b (a1)+,240(a0) ;line 7 + move.b (a1)+,280(a0) ;line 8 + + move.l #IIeCharSet2,a1 + move.b (a1,a6.w),d0 ;a6 still present from above...! + + move.b d0,0+LINES*40(a0) + move.b d0,40+LINES*40(a0) ;line 2 + move.b d0,80+LINES*40(a0) ;line 3 + move.b d0,120+LINES*40(a0) ;line 4 + move.b d0,160+LINES*40(a0) ;line 5 + move.b d0,200+LINES*40(a0) ;line 6 + move.b d0,240+LINES*40(a0) ;line 7 + move.b d0,280+LINES*40(a0) ;line 8 + + rts + + +************************************** + CNOP 0,4 + ;This routine ONLY draws the bottom 4 lines of text into HiRes BPlanes... + +PBHgrTxt1: + cmp.b (Mem_Ptr,a0.l),d1 ;1st check if mem is different! + beq.b .rts ;mem is same so video is same; don't change anything + move.b d1,(Mem_Ptr,a0.l) ;FPUBYTE, write data to mem... + and.w #$ff,d1 + move.w d1,a6 + + move.l #TxtLookUp-$800,a1 + move.w (a1,a0.w*2),d1 ;d1 = BPlane Ptr Offset for particular address + bmi.b .rts + + move.l Hgr1_Planes,a0 + +.choose cmp.w #20*320+00,d1 ;cmp to 1st txt line addr... + bhs.b .txt +.rts rts + +.txt move.l #IIeCharSet,a1 [03] + lea (a1,a6.w*8),a1 ;a1 -> CharSet for letter!!! [08] + + add.w d1,a0 ;a0 -> Plane1StartLoc + + move.b (a1)+,(a0) ;line 1 + move.b (a1)+,40(a0) ;line 2 + move.b (a1)+,80(a0) ;line 3 + move.b (a1)+,120(a0) ;line 4 + move.b (a1)+,160(a0) ;line 5 + move.b (a1)+,200(a0) ;line 6 + move.b (a1)+,240(a0) ;line 7 + move.b (a1)+,280(a0) ;line 8 + + move.l #IIeCharSet2,a1 + move.b (a1,a6.w),d0 ;a6 still present from above...! + + move.b d0,0+LINES*40(a0) + move.b d0,40+LINES*40(a0) ;line 2 + move.b d0,80+LINES*40(a0) ;line 3 + move.b d0,120+LINES*40(a0) ;line 4 + move.b d0,160+LINES*40(a0) ;line 5 + move.b d0,200+LINES*40(a0) ;line 6 + move.b d0,240+LINES*40(a0) ;line 7 + move.b d0,280+LINES*40(a0) ;line 8 + + rts + +*********************************************************************** +* enter with: a0=address to write ($800-$bff for PBTxt2), and d1=data. +*********************************************************************** + CNOP 0,4 +PBTxt2 cmp.b (Mem_Ptr,a0.l),d1 + beq.b .rts + move.b d1,(Mem_Ptr,a0.l) ;FPUBYTE, write data to mem... + and.w #$ff,d1 + move.w d1,a6 + + move.l #TxtLookUp-$1000,a1 ;- $800 * 2 + move.w (a1,a0.w*2),d1 ;d1 = BPlane Ptr Offset for particular address + bmi.b .rts + + move.l #IIeCharSet,a1 [03] + lea (a1,a6.w*8),a1 ;a1 -> CharSet for letter!!! [08] + + +.do_txt move.l Gr2_Planes,a0 ;a0 -> BitPlane1 + add.w d1,a0 ;a0 -> Plane1StartLoc + + move.b (a1)+,(a0) ;line 1 + move.b (a1)+,40(a0) ;line 2 + move.b (a1)+,80(a0) ;line 3 + move.b (a1)+,120(a0) ;line 4 + move.b (a1)+,160(a0) ;line 5 + move.b (a1)+,200(a0) ;line 6 + move.b (a1)+,240(a0) ;line 7 + move.b (a1)+,280(a0) ;line 8 + + move.l #IIeCharSet2,a1 + move.b (a1,a6.w),d0 ;a6 still present from above...! + + move.b d0,0+LINES*40(a0) + move.b d0,40+LINES*40(a0) ;line 2 + move.b d0,80+LINES*40(a0) ;line 3 + move.b d0,120+LINES*40(a0) ;line 4 + move.b d0,160+LINES*40(a0) ;line 5 + move.b d0,200+LINES*40(a0) ;line 6 + move.b d0,240+LINES*40(a0) ;line 7 + move.b d0,280+LINES*40(a0) ;line 8 +.rts rts + +***************************** + + CNOP 0,4 +PBGr2 cmp.b (Mem_Ptr,a0.l),d1 + beq.b .rts + move.b d1,(Mem_Ptr,a0.l) ;FPUBYTE, write data to mem... + and.w #$ff,d1 + move.w d1,a6 + + move.l #TxtLookUp-$1000,a1 ;- $800 * 2 + move.w (a1,a0.w*2),d1 ;d1 = BPlane Ptr Offset for particular address + bmi.b .rts + +.do_gr move.l Gr2_Planes,a0 + bra GRFX +.rts rts + +*************************** + CNOP 0,4 + +PBGrTxt2: + cmp.b (Mem_Ptr,a0.l),d1 + beq.b .rts + move.b d1,(Mem_Ptr,a0.l) ;FPUBYTE, write data to mem... + and.w #$ff,d1 + move.w d1,a6 + + move.l #TxtLookUp-$1000,a1 ;- $800 * 2 + move.w (a1,a0.w*2),d1 ;d1 = BPlane Ptr Offset for particular address + bmi.b .rts + + move.l Gr2_Planes,a0 + +.choose cmp.w #20*320+00,d1 ;cmp to 1st txt line addr... + bhs.b .txt + +.do_gr bra GRFX ;Go draw grfx block (a0/d1 set) +.rts rts + +.txt move.l #IIeCharSet,a1 [03] + lea (a1,a6.w*8),a1 ;a1 -> CharSet for letter!!! [08] + + add.w d1,a0 ;a0 -> Plane1StartLoc + + move.b (a1)+,(a0) ;line 1 + move.b (a1)+,40(a0) ;line 2 + move.b (a1)+,80(a0) ;line 3 + move.b (a1)+,120(a0) ;line 4 + move.b (a1)+,160(a0) ;line 5 + move.b (a1)+,200(a0) ;line 6 + move.b (a1)+,240(a0) ;line 7 + move.b (a1)+,280(a0) ;line 8 + + move.l #IIeCharSet2,a1 + move.b (a1,a6.w),d0 ;a6 still present from above...! + + move.b d0,0+LINES*40(a0) + move.b d0,40+LINES*40(a0) ;line 2 + move.b d0,80+LINES*40(a0) ;line 3 + move.b d0,120+LINES*40(a0) ;line 4 + move.b d0,160+LINES*40(a0) ;line 5 + move.b d0,200+LINES*40(a0) ;line 6 + move.b d0,240+LINES*40(a0) ;line 7 + move.b d0,280+LINES*40(a0) ;line 8 + + rts + +*************************** + CNOP 0,4 + +PBHgrTxt2: + cmp.b (Mem_Ptr,a0.l),d1 + beq.b .rts + move.b d1,(Mem_Ptr,a0.l) ;FPUBYTE, write data to mem... + and.w #$ff,d1 + move.w d1,a6 + + move.l #TxtLookUp-$1000,a1 ;- $800 * 2 + move.w (a1,a0.w*2),d1 ;d1 = BPlane Ptr Offset for particular address + bmi.b .rts + + move.l Hgr2_Planes,a0 + +.choose cmp.w #20*320+00,d1 ;cmp to 1st txt line addr... + bhs.b .txt +.rts rts + +.txt move.l #IIeCharSet,a1 [03] + lea (a1,a6.w*8),a1 ;a1 -> CharSet for letter!!! [08] + + add.w d1,a0 ;a0 -> Plane1StartLoc + + move.b (a1)+,(a0) ;line 1 + move.b (a1)+,40(a0) ;line 2 + move.b (a1)+,80(a0) ;line 3 + move.b (a1)+,120(a0) ;line 4 + move.b (a1)+,160(a0) ;line 5 + move.b (a1)+,200(a0) ;line 6 + move.b (a1)+,240(a0) ;line 7 + move.b (a1)+,280(a0) ;line 8 + + move.l #IIeCharSet2,a1 + move.b (a1,a6.w),d0 ;a6 still present from above...! + + move.b d0,0+LINES*40(a0) + move.b d0,40+LINES*40(a0) ;line 2 + move.b d0,80+LINES*40(a0) ;line 3 + move.b d0,120+LINES*40(a0) ;line 4 + move.b d0,160+LINES*40(a0) ;line 5 + move.b d0,200+LINES*40(a0) ;line 6 + move.b d0,240+LINES*40(a0) ;line 7 + move.b d0,280+LINES*40(a0) ;line 8 + + rts + + + + + SECTION TABLES,DATA +** TxtLookUp is an entire BitMap Offset to draw a character onto based upon an absolute addr. +** For a number ($400-$7ff) it returns a word offset, or -1 if in a video "hole". +** Offset = Line # * 8 (Lines Per Character) * 40 (BytesPerLine) + Horizontal Byte Offset. + CNOP 0,4 +TxtLookUp: + dc.w 00*320+00,00*320+01,00*320+02,00*320+03,00*320+04,00*320+05,00*320+06,00*320+07,00*320+08,00*320+09,00*320+10,00*320+11,00*320+12,00*320+13,00*320+14,00*320+15,00*320+16,00*320+17,00*320+18,00*320+19 + dc.w 00*320+20,00*320+21,00*320+22,00*320+23,00*320+24,00*320+25,00*320+26,00*320+27,00*320+28,00*320+29,00*320+30,00*320+31,00*320+32,00*320+33,00*320+34,00*320+35,00*320+36,00*320+37,00*320+38,00*320+39 ;$400 -> $427 + dc.w 08*320+00,08*320+01,08*320+02,08*320+03,08*320+04,08*320+05,08*320+06,08*320+07,08*320+08,08*320+09,08*320+10,08*320+11,08*320+12,08*320+13,08*320+14,08*320+15,08*320+16,08*320+17,08*320+18,08*320+19 + dc.w 08*320+20,08*320+21,08*320+22,08*320+23,08*320+24,08*320+25,08*320+26,08*320+27,08*320+28,08*320+29,08*320+30,08*320+31,08*320+32,08*320+33,08*320+34,08*320+35,08*320+36,08*320+37,08*320+38,08*320+39 ;$428... + dc.w 16*320+00,16*320+01,16*320+02,16*320+03,16*320+04,16*320+05,16*320+06,16*320+07,16*320+08,16*320+09,16*320+10,16*320+11,16*320+12,16*320+13,16*320+14,16*320+15,16*320+16,16*320+17,16*320+18,16*320+19 + dc.w 16*320+20,16*320+21,16*320+22,16*320+23,16*320+24,16*320+25,16*320+26,16*320+27,16*320+28,16*320+29,16*320+30,16*320+31,16*320+32,16*320+33,16*320+34,16*320+35,16*320+36,16*320+37,16*320+38,16*320+39 ;$450... + dc.w -1,-1,-1,-1,-1,-1,-1,-1 ;$478 -> $47f + dc.w 01*320+00,01*320+01,01*320+02,01*320+03,01*320+04,01*320+05,01*320+06,01*320+07,01*320+08,01*320+09,01*320+10,01*320+11,01*320+12,01*320+13,01*320+14,01*320+15,01*320+16,01*320+17,01*320+18,01*320+19 + dc.w 01*320+20,01*320+21,01*320+22,01*320+23,01*320+24,01*320+25,01*320+26,01*320+27,01*320+28,01*320+29,01*320+30,01*320+31,01*320+32,01*320+33,01*320+34,01*320+35,01*320+36,01*320+37,01*320+38,01*320+39 ;$480... + dc.w 09*320+00,09*320+01,09*320+02,09*320+03,09*320+04,09*320+05,09*320+06,09*320+07,09*320+08,09*320+09,09*320+10,09*320+11,09*320+12,09*320+13,09*320+14,09*320+15,09*320+16,09*320+17,09*320+18,09*320+19 + dc.w 09*320+20,09*320+21,09*320+22,09*320+23,09*320+24,09*320+25,09*320+26,09*320+27,09*320+28,09*320+29,09*320+30,09*320+31,09*320+32,09*320+33,09*320+34,09*320+35,09*320+36,09*320+37,09*320+38,09*320+39 ;$4a8... + dc.w 17*320+00,17*320+01,17*320+02,17*320+03,17*320+04,17*320+05,17*320+06,17*320+07,17*320+08,17*320+09,17*320+10,17*320+11,17*320+12,17*320+13,17*320+14,17*320+15,17*320+16,17*320+17,17*320+18,17*320+19 + dc.w 17*320+20,17*320+21,17*320+22,17*320+23,17*320+24,17*320+25,17*320+26,17*320+27,17*320+28,17*320+29,17*320+30,17*320+31,17*320+32,17*320+33,17*320+34,17*320+35,17*320+36,17*320+37,17*320+38,17*320+39 ;$4d0... + dc.w -1,-1,-1,-1,-1,-1,-1,-1 ;$4f8 -> $4ff + dc.w 02*320+00,02*320+01,02*320+02,02*320+03,02*320+04,02*320+05,02*320+06,02*320+07,02*320+08,02*320+09,02*320+10,02*320+11,02*320+12,02*320+13,02*320+14,02*320+15,02*320+16,02*320+17,02*320+18,02*320+19 + dc.w 02*320+20,02*320+21,02*320+22,02*320+23,02*320+24,02*320+25,02*320+26,02*320+27,02*320+28,02*320+29,02*320+30,02*320+31,02*320+32,02*320+33,02*320+34,02*320+35,02*320+36,02*320+37,02*320+38,02*320+39 ;$500... + dc.w 10*320+00,10*320+01,10*320+02,10*320+03,10*320+04,10*320+05,10*320+06,10*320+07,10*320+08,10*320+09,10*320+10,10*320+11,10*320+12,10*320+13,10*320+14,10*320+15,10*320+16,10*320+17,10*320+18,10*320+19 + dc.w 10*320+20,10*320+21,10*320+22,10*320+23,10*320+24,10*320+25,10*320+26,10*320+27,10*320+28,10*320+29,10*320+30,10*320+31,10*320+32,10*320+33,10*320+34,10*320+35,10*320+36,10*320+37,10*320+38,10*320+39 ;$528... + dc.w 18*320+00,18*320+01,18*320+02,18*320+03,18*320+04,18*320+05,18*320+06,18*320+07,18*320+08,18*320+09,18*320+10,18*320+11,18*320+12,18*320+13,18*320+14,18*320+15,18*320+16,18*320+17,18*320+18,18*320+19 + dc.w 18*320+20,18*320+21,18*320+22,18*320+23,18*320+24,18*320+25,18*320+26,18*320+27,18*320+28,18*320+29,18*320+30,18*320+31,18*320+32,18*320+33,18*320+34,18*320+35,18*320+36,18*320+37,18*320+38,18*320+39 ;$550... + dc.w -1,-1,-1,-1,-1,-1,-1,-1 ;$578 -> $57f + dc.w 03*320+00,03*320+01,03*320+02,03*320+03,03*320+04,03*320+05,03*320+06,03*320+07,03*320+08,03*320+09,03*320+10,03*320+11,03*320+12,03*320+13,03*320+14,03*320+15,03*320+16,03*320+17,03*320+18,03*320+19 + dc.w 03*320+20,03*320+21,03*320+22,03*320+23,03*320+24,03*320+25,03*320+26,03*320+27,03*320+28,03*320+29,03*320+30,03*320+31,03*320+32,03*320+33,03*320+34,03*320+35,03*320+36,03*320+37,03*320+38,03*320+39 ;$580... + dc.w 11*320+00,11*320+01,11*320+02,11*320+03,11*320+04,11*320+05,11*320+06,11*320+07,11*320+08,11*320+09,11*320+10,11*320+11,11*320+12,11*320+13,11*320+14,11*320+15,11*320+16,11*320+17,11*320+18,11*320+19 + dc.w 11*320+20,11*320+21,11*320+22,11*320+23,11*320+24,11*320+25,11*320+26,11*320+27,11*320+28,11*320+29,11*320+30,11*320+31,11*320+32,11*320+33,11*320+34,11*320+35,11*320+36,11*320+37,11*320+38,11*320+39 ;$5a8... + dc.w 19*320+00,19*320+01,19*320+02,19*320+03,19*320+04,19*320+05,19*320+06,19*320+07,19*320+08,19*320+09,19*320+10,19*320+11,19*320+12,19*320+13,19*320+14,19*320+15,19*320+16,19*320+17,19*320+18,19*320+19 + dc.w 19*320+20,19*320+21,19*320+22,19*320+23,19*320+24,19*320+25,19*320+26,19*320+27,19*320+28,19*320+29,19*320+30,19*320+31,19*320+32,19*320+33,19*320+34,19*320+35,19*320+36,19*320+37,19*320+38,19*320+39 ;$5d0... + dc.w -1,-1,-1,-1,-1,-1,-1,-1 ;$5f8 -> $5ff + dc.w 04*320+00,04*320+01,04*320+02,04*320+03,04*320+04,04*320+05,04*320+06,04*320+07,04*320+08,04*320+09,04*320+10,04*320+11,04*320+12,04*320+13,04*320+14,04*320+15,04*320+16,04*320+17,04*320+18,04*320+19 + dc.w 04*320+20,04*320+21,04*320+22,04*320+23,04*320+24,04*320+25,04*320+26,04*320+27,04*320+28,04*320+29,04*320+30,04*320+31,04*320+32,04*320+33,04*320+34,04*320+35,04*320+36,04*320+37,04*320+38,04*320+39 ;$600... + dc.w 12*320+00,12*320+01,12*320+02,12*320+03,12*320+04,12*320+05,12*320+06,12*320+07,12*320+08,12*320+09,12*320+10,12*320+11,12*320+12,12*320+13,12*320+14,12*320+15,12*320+16,12*320+17,12*320+18,12*320+19 + dc.w 12*320+20,12*320+21,12*320+22,12*320+23,12*320+24,12*320+25,12*320+26,12*320+27,12*320+28,12*320+29,12*320+30,12*320+31,12*320+32,12*320+33,12*320+34,12*320+35,12*320+36,12*320+37,12*320+38,12*320+39 ;$628... + dc.w 20*320+00,20*320+01,20*320+02,20*320+03,20*320+04,20*320+05,20*320+06,20*320+07,20*320+08,20*320+09,20*320+10,20*320+11,20*320+12,20*320+13,20*320+14,20*320+15,20*320+16,20*320+17,20*320+18,20*320+19 + dc.w 20*320+20,20*320+21,20*320+22,20*320+23,20*320+24,20*320+25,20*320+26,20*320+27,20*320+28,20*320+29,20*320+30,20*320+31,20*320+32,20*320+33,20*320+34,20*320+35,20*320+36,20*320+37,20*320+38,20*320+39 ;$650... + dc.w -1,-1,-1,-1,-1,-1,-1,-1 ;$678 -> $67f + dc.w 05*320+00,05*320+01,05*320+02,05*320+03,05*320+04,05*320+05,05*320+06,05*320+07,05*320+08,05*320+09,05*320+10,05*320+11,05*320+12,05*320+13,05*320+14,05*320+15,05*320+16,05*320+17,05*320+18,05*320+19 + dc.w 05*320+20,05*320+21,05*320+22,05*320+23,05*320+24,05*320+25,05*320+26,05*320+27,05*320+28,05*320+29,05*320+30,05*320+31,05*320+32,05*320+33,05*320+34,05*320+35,05*320+36,05*320+37,05*320+38,05*320+39 ;$680... + dc.w 13*320+00,13*320+01,13*320+02,13*320+03,13*320+04,13*320+05,13*320+06,13*320+07,13*320+08,13*320+09,13*320+10,13*320+11,13*320+12,13*320+13,13*320+14,13*320+15,13*320+16,13*320+17,13*320+18,13*320+19 + dc.w 13*320+20,13*320+21,13*320+22,13*320+23,13*320+24,13*320+25,13*320+26,13*320+27,13*320+28,13*320+29,13*320+30,13*320+31,13*320+32,13*320+33,13*320+34,13*320+35,13*320+36,13*320+37,13*320+38,13*320+39 ;$6a8... + dc.w 21*320+00,21*320+01,21*320+02,21*320+03,21*320+04,21*320+05,21*320+06,21*320+07,21*320+08,21*320+09,21*320+10,21*320+11,21*320+12,21*320+13,21*320+14,21*320+15,21*320+16,21*320+17,21*320+18,21*320+19 + dc.w 21*320+20,21*320+21,21*320+22,21*320+23,21*320+24,21*320+25,21*320+26,21*320+27,21*320+28,21*320+29,21*320+30,21*320+31,21*320+32,21*320+33,21*320+34,21*320+35,21*320+36,21*320+37,21*320+38,21*320+39 ;$6d0... + dc.w -1,-1,-1,-1,-1,-1,-1,-1 ;$6f8 -> $6ff + dc.w 06*320+00,06*320+01,06*320+02,06*320+03,06*320+04,06*320+05,06*320+06,06*320+07,06*320+08,06*320+09,06*320+10,06*320+11,06*320+12,06*320+13,06*320+14,06*320+15,06*320+16,06*320+17,06*320+18,06*320+19 + dc.w 06*320+20,06*320+21,06*320+22,06*320+23,06*320+24,06*320+25,06*320+26,06*320+27,06*320+28,06*320+29,06*320+30,06*320+31,06*320+32,06*320+33,06*320+34,06*320+35,06*320+36,06*320+37,06*320+38,06*320+39 ;$700... + dc.w 14*320+00,14*320+01,14*320+02,14*320+03,14*320+04,14*320+05,14*320+06,14*320+07,14*320+08,14*320+09,14*320+10,14*320+11,14*320+12,14*320+13,14*320+14,14*320+15,14*320+16,14*320+17,14*320+18,14*320+19 + dc.w 14*320+20,14*320+21,14*320+22,14*320+23,14*320+24,14*320+25,14*320+26,14*320+27,14*320+28,14*320+29,14*320+30,14*320+31,14*320+32,14*320+33,14*320+34,14*320+35,14*320+36,14*320+37,14*320+38,14*320+39 ;$728... + dc.w 22*320+00,22*320+01,22*320+02,22*320+03,22*320+04,22*320+05,22*320+06,22*320+07,22*320+08,22*320+09,22*320+10,22*320+11,22*320+12,22*320+13,22*320+14,22*320+15,22*320+16,22*320+17,22*320+18,22*320+19 + dc.w 22*320+20,22*320+21,22*320+22,22*320+23,22*320+24,22*320+25,22*320+26,22*320+27,22*320+28,22*320+29,22*320+30,22*320+31,22*320+32,22*320+33,22*320+34,22*320+35,22*320+36,22*320+37,22*320+38,22*320+39 ;$750... + dc.w -1,-1,-1,-1,-1,-1,-1,-1 ;$778 -> $77f + dc.w 07*320+00,07*320+01,07*320+02,07*320+03,07*320+04,07*320+05,07*320+06,07*320+07,07*320+08,07*320+09,07*320+10,07*320+11,07*320+12,07*320+13,07*320+14,07*320+15,07*320+16,07*320+17,07*320+18,07*320+19 + dc.w 07*320+20,07*320+21,07*320+22,07*320+23,07*320+24,07*320+25,07*320+26,07*320+27,07*320+28,07*320+29,07*320+30,07*320+31,07*320+32,07*320+33,07*320+34,07*320+35,07*320+36,07*320+37,07*320+38,07*320+39 ;$780... + dc.w 15*320+00,15*320+01,15*320+02,15*320+03,15*320+04,15*320+05,15*320+06,15*320+07,15*320+08,15*320+09,15*320+10,15*320+11,15*320+12,15*320+13,15*320+14,15*320+15,15*320+16,15*320+17,15*320+18,15*320+19 + dc.w 15*320+20,15*320+21,15*320+22,15*320+23,15*320+24,15*320+25,15*320+26,15*320+27,15*320+28,15*320+29,15*320+30,15*320+31,15*320+32,15*320+33,15*320+34,15*320+35,15*320+36,15*320+37,15*320+38,15*320+39 ;$7a8... + dc.w 23*320+00,23*320+01,23*320+02,23*320+03,23*320+04,23*320+05,23*320+06,23*320+07,23*320+08,23*320+09,23*320+10,23*320+11,23*320+12,23*320+13,23*320+14,23*320+15,23*320+16,23*320+17,23*320+18,23*320+19 + dc.w 23*320+20,23*320+21,23*320+22,23*320+23,23*320+24,23*320+25,23*320+26,23*320+27,23*320+28,23*320+29,23*320+30,23*320+31,23*320+32,23*320+33,23*320+34,23*320+35,23*320+36,23*320+37,23*320+38,23*320+39 ;$7d0... + dc.w -1,-1,-1,-1,-1,-1,-1,-1 ;$7f8 -> $7ff + diff --git a/src/Version.s b/src/Version.s new file mode 100644 index 0000000..bb8671b --- /dev/null +++ b/src/Version.s @@ -0,0 +1,10 @@ +** Useless Header which simply contains Version string (does not get compressed ** + + nop + moveq.l #0,d0 + nop + rts + dc.b "$VER: Apple2000_v1.3 (68020+, non-MMU version)",0 + even + rts + \ No newline at end of file