7147 lines
157 KiB
ArmAsm
7147 lines
157 KiB
ArmAsm
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<<S_BIT ;x_HEX used to build masks in STAT rtns
|
|
Z_HEX equ $1<<Z_BIT
|
|
V_HEX equ $1<<V_BIT
|
|
C_HEX equ $1<<C_BIT
|
|
|
|
;Scc SpecAddr [11]
|
|
;AND.w #Imm, Dn [06]
|
|
;AND.l #Imm, Dn [08]
|
|
;Bcc.b [05/09]
|
|
;BTST/BSET/BCLR #imm,Dx [05]
|
|
;eor.l #Imm, Dn [08]
|
|
;BCHG.l #Imm, Dn [05]
|
|
|
|
* Status bits emulated in two separate registers (low word of each).
|
|
* StatusSZ has S & Z bits, and StatusCV holds C & V bits. Note that
|
|
* the other bits in these two words can't be used for anything!
|
|
|
|
STAT_SZ MACRO
|
|
move.w ccr,StatusSZ [06]
|
|
ENDM
|
|
|
|
STAT_C MACRO (ASL,ROL,ROR,ADCbcd)
|
|
scs.b StatusCV ;set bit 7 (& more) [04] = 10
|
|
ENDM
|
|
|
|
STAT_SZC MACRO (ASL,ROL,ROR,ADCbcd)
|
|
move.w ccr,StatusSZ [06]
|
|
scs.b StatusCV ;set bit 7 (& more) [04] = 10
|
|
ENDM
|
|
|
|
STAT_SZiC MACRO ;do C bit reversed (CMP, CPX, CPY, SBCbcd)
|
|
move.w ccr,StatusSZ [06]
|
|
scc.b StatusCV [04] = 10
|
|
ENDM
|
|
|
|
STAT_SVZC MACRO (ADC)
|
|
move.w ccr,StatusSZ [06]
|
|
move.b StatusSZ,StatusCV [03]
|
|
lsl.w #7,StatusCV ;shift C ->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=<EA>
|
|
;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< |