;
;Source of Run68017 . CopyWrite © Kamran Karimi.
;
;emulates 30.5 (!) 68020 instructions.
;
;Instructions: bra.l, extb.l, cas, pack, unpk, link.l, movec, rtd, moves,
;              move ccr,<ea>, trapcc, mulu.l, muls.l, divu.l, divs.l,
;              divul.l, divsl.l, cas2, chk.l, chk2, cmp2, bsr.l, bfchg
;              bftst, bfset, bfclr, bfextu, bfexts, bfffo, bfins,
;          (!) bcc.l (bcc.l is emulated only if branch is taken!)
;
;Only the emulated instructions can use new 68020 addressing modes.
;
;Assembled with AssemPro (Profimat) assembler using an standard A500.
;Refer to Run68017.ReadMe for more information.
 


ExecBase    equ 4

;Exec:
AllocMem    equ -198
FreeMem     equ -210
OpenLib     equ -408
CloseLib    equ -414
GetMsg      equ -372
AllocSignal equ -330
FindPort    equ -390
AddPort     equ -354
WaitPort    equ -384
RemPort     equ -360
FindTask    equ -294
Forbid      equ -132
Permit      equ -138

;Intuition:
AutoRequest equ -348
PrintIText  equ -216
OpenWindow  equ -204
CloseWindow equ -72

;DOS:
Delay       equ -198


  CODE

 moveq   #0,d6          ;flag to see if command line entered
 movem.l d0/a0,-(a7)       ;save command line parameters
 move.l  ExecBase,a6
 movea.l #0,a1
 jsr     FindTask(a6)
 move.l  d0,a4
 tst.l   $ac(a4)        ;WorkBench or CLI?
 bne     FromCLI
 lea     $5c(a4),a0
 jsr     WaitPort(a6)
 lea     $5c(a4),a0
 jsr     GetMsg(a6)       ;Get startup message,but we don't use it
 bra     StackAdjust
FromCLI:
 movem.l (a7)+,d0/a0   ;command line parameters
 subq    #1,d0
 beq     NoParam
LoopParam1:
 cmpi.b  #' ',(a0)+
 bne     FoundP
 dbra    d0,LoopParam1
 bra     NoParam
FoundP:
 suba.l  #1,a0
 cmpi.b  #'6',(a0)
 bne     No68k
 adda.l  #1,a0
 cmpi.b  #'8',(a0)+
 bne     NoParam
 cmpi.b  #'k',(a0)
 beq     FoundK
 cmpi.b  #'K',(a0)
 bne     NoParam
FoundK:
 adda.l  #1,a0
 cmpi.b  #' ',(a0)    ;any thing after '68k'?
 beq     Found68
 cmp.b   #10,(a0)
 bne     NoParam
Found68:
 moveq   #1,d6        ;the command was 68k, go on.
 bra     NoParam
No68k:
 cmpi.b  #'q',(a0)
 beq     Q
 cmpi.b  #'Q',(a0)
 bne     NoParam
Q:
 adda.l  #1,a0
 cmpi.b  #'u',(a0)
 beq     U
 cmpi.b  #'U',(a0)
 bne     NoParam
U:
 adda.l  #1,a0
 cmpi.b  #'i',(a0)
 beq     I
 cmpi.b  #'I',(a0)
 bne     NoParam
I:
 adda.l  #1,a0
 cmpi.b  #'t',(a0)
 beq     T
 cmpi.b  #'T',(a0)
 bne     NoParam
T:
 adda.l  #1,a0
 cmpi.b  #' ',(a0)
 beq     FoundQuit
 cmp.b   #10,(a0)
 bne     NoParam
FoundQuit:
 moveq   #2,d6        ;the command was quit
 bra     NoParam

StackAdjust:
 movem.l (a7)+,d0/a0
NoParam:
 move.l  ExecBase,a6
 move.l  #20,DOSResult   ;DOSResult will give a return value to DOS

Open_DOS:             ;we'll open dos.library
 lea     DOS_Name,a1
 moveq   #0,d0          ;any version
 jsr     OpenLib(a6)
 move.l  d0,DOS_Base
 beq     No_DOS        ;if could not open DOS, then we should exit!
Open_Intuition:
 lea     Intuition_Name,a1
 moveq   #0,d0              ;any version
 jsr     OpenLib(a6)
 move.l  d0,Intuition_Base   ;we (hopefully) opened intuition.library
 beq     No_Intuition
 move.l  #Text68000,CPUName    ;assume the CPU is 68000
 move.l  ExecBase,a6
 move.w  $128(a6),d0
 andi.w  #$000f,d0      ;check the ExecBase
 beq     My68000
 andi.w  #$e,d0             ;is the CPU 68010?
 bne     NO_68000_68010
 move.l  #Text68010,CPUName      ;if yes, get the name
 bra     My68000
NO_68000_68010:
 move.l  Intuition_Base,a6    ;ExecBase does not mention a 68000
 move.l  #0,a0
 lea     No68T,a1
 lea     CancelT,a2
 lea     CancelT,a3
 move.l  #0,d0
 move.l  #0,d1
 move.l  #250,d2
 move.l  #58,d3
 jsr     AutoRequest(a6)     ;tell you don't have a 68000/68010
 bra     Close_All
My68000:
 move.l  ExecBase,a6
 lea     PortName,a1
 jsr     FindPort(a6)        ;is the routine already present?
 tst.l   d0
 beq     InstallPort
 move.l  Intuition_Base,a6    ;routine already installed!
 move.l  #0,a0
 lea     RoutinePresent,a1
 lea     CancelT,a2
 lea     CancelT,a3
 move.l  #0,d0
 move.l  #0,d1
 move.l  #270,d2
 move.l  #65,d3
 jsr     AutoRequest(a6)      ;tell routine already present
 move.l  #10,DOSResult
 bra     Close_All
InstallPort:
 move.l  #-1,d0
 jsr     AllocSignal(a6)     ;set up a proper message port.we may need
 move.b  d0,SigBit           ;it in future versions of the program
 movea.l #0,a1
 jsr     FindTask(a6)
 move.l  d0,ThisTask
 move.l  #MSGPortEnd-MSGPort,d0  ; length  of actual code in d0
 moveq   #1,d1         ;PUBLIC Memory, don't move it around!
 jsr     AllocMem(a6)   ;allocate mem
 move.l  d0,PortAddr    ;we should copy the message port so after exit
 beq     NoMem          ;it remains in the memory
 movea.l #MSGPort,a0
 movea.l PortAddr,a1
 move.l  #MSGPortEnd-MSGPort,d0
 divu    #2,d0
 andi.l  #$ffff,d0
 sub.l   #1,d0
copyport:
 move.w  (a0)+,(a1)+      ;copy our exception code to the allocated mem
 dbf     d0,copyport
 move.l  PortAddr,a0      ;adjust pointer to name
 move.l  #Name-MSGPort,d1
 adda.l  d1,a0
 movea.l #PortName-Name,a2
 adda.l  a0,a2      ;a2 has the new address of the port name
 move.l  a2,(a0)
 move.l  #EndAddr-BeginAddr,d0  ; length  of actual code in d0
 moveq   #1,d1            ;PUBLIC memory
 jsr     AllocMem(a6)    ;allocate mem
 move.l  d0,NewAddrExcept
 bne     AddrAllocated
 move.l  PortAddr,a1
 move.l  #MSGPortEnd-MSGPort,d0
 jsr     FreeMem(a6)
 bra     NoMem
AddrAllocated:
 move.l  $c,OldAddrExcept  ;save the original 'address error' vector
 movea.l #BeginAddr,a0
 movea.l NewAddrExcept,a1
 move.l  #EndAddr-BeginAddr,d0
 divu    #2,d0
 andi.l  #$ffff,d0
 sub.l   #1,d0
copyaddr:
 move.w  (a0)+,(a1)+      ;copy our exception code to the allocated mem
 dbf     d0,copyaddr
 move.l  #EndIllegal-BeginIllegal,d0  ; length  of actual code in d0
 moveq   #1,d1          ;PUBLIC Memory
 jsr     AllocMem(a6)     ;allocate mem
 move.l  d0,NewIllegalExcept
 bne     IllAllocated
 move.l  PortAddr,a1
 move.l  #MSGPortEnd-MSGPort,d0
 jsr     FreeMem(a6)
 move.l  NewAddrExcept,a1
 move.l  #EndAddr-BeginAddr,d0
 jsr     FreeMem(a6)
 bra     NoMem
IllAllocated:
 move.l  #1024,d0      ;there are 255 longword vector addresses
 moveq   #1,d1          ;PUBLIC Memory
 move.l  ExecBase,a6
 jsr     AllocMem(a6)
 move.l  d0,NewVec         ;address of the copied original vectors
 bne     NewVecAllocated
 move.l  PortAddr,a1            ;if we could not allocate enough mem. then
 move.l  #MSGPortEnd-MSGPort,d0  ;we should free the previously allocated
 jsr     FreeMem(a6)             ;mem.
 move.l  NewIllegalExcept,a1
 move.l  #EndIllegal-BeginIllegal,d0
 jsr     FreeMem(a6)
 move.l  NewAddrExcept,a1
 move.l  #EndAddr-BeginAddr,d0
 jsr     FreeMem(a6)
 bra     NoMem
NewVecAllocated:
 move.l  $10,OldIllegalExcept  ;save the original illegal instruction vector
 movea.l #BeginIllegal,a0
 movea.l NewIllegalExcept,a1
 move.l  #EndIllegal-BeginIllegal,d0
 divu    #2,d0
 andi.l  #$ffff,d0
 sub.l   #1,d0
copy:
 move.w  (a0)+,(a1)+      ;copy our exception code to the allocated mem
 dbf     d0,copy
 move.l  #511,d0
 movea.l #0,a0
 movea.l NewVec,a1
copy2:
 move.w  (a0)+,(a1)+     ;get a copy of all the vector area contents
 dbf     d0,copy2  
 move.l  PortAddr,a1
 jsr     AddPort(a6)
 move.l  Intuition_Base,a6
 lea     InfoWindow,a0
 jsr     OpenWindow(a6)
 move.l  d0,Window_Handler
 beq     FrMem
 lea     NextText1,a1
 move.l  #5,d0
 move.l  #3,d1
 move.l  Window_Handler,a0
 move.l  50(a0),a0           ;rastport
 jsr     PrintIText(a6)
 move.l  DOS_Base,a6
 move.l  #175,d1
 jsr     Delay(a6)
 move.l  Intuition_Base,a6
 move.l  Window_Handler,a0
 jsr     CloseWindow(a6)
 movea.l CPUName,a5
 moveq   #0,d7                 ;0 = routine not installed
 cmpi.l  #1,d6           ;command was '68k' ?
 beq     Put68000
 lea     Text68017,a5
 move.l  NewAddrExcept,$c
 move.l  NewIllegalExcept,$10
 move.l  #-1,d7                  ;-1 = routine installed
 cmpi.l  #2,d6           ;command was 'quit' ?
 bne     Put68000
 move.l  #0,DOSResult
 bra     Close_All
Put68000:
 lea     WindowMain,a0        ;open window and write processor name
 jsr     OpenWindow(a6)
 move.l  d0,Window_Handler
 beq     FrMem
 movea.l a5,a1
 move.l  #0,d0
 move.l  #0,d1
 move.l  Window_Handler,a0
 move.l  50(a0),a0   ;rastport
 jsr     PrintIText(a6)
 lea     PText,a1
 move.l  #0,d0
 move.l  #0,d1
 move.l  Window_Handler,a0
 move.l  50(a0),a0             ;rastport
 jsr     PrintIText(a6)

Loop:                        ;this is the mian loop
 move.l  Intuition_Base,a6
 move.l  Window_Handler,a0
 move.l  86(a0),a0
 move.l  ExecBase,a6
 jsr     WaitPort(a6)          ;wait for a message to arrive
 move.l  Window_Handler,a0
 move.l  86(a0),a0
 jsr     GetMsg(a6)
 move.l  d0,a0
 move.l  20(a0),d0
 cmpi.l  #$200,d0
 beq     CloseIt        ;was it close?
GadChanged:
 move.l  Intuition_Base,a6       ;no! the user changed the processor!
 tst.l   d7                  ;should we install the routine or not?
 beq     InstallRoutine
 move.l  OldIllegalExcept,$10
 move.l  OldAddrExcept,$c
 movea.l CPUName,a1
 move.l  #0,d0
 move.l  #0,d1
 move.l  Window_Handler,a0
 move.l  50(a0),a0          ;rastport
 jsr     PrintIText(a6)
 not.l   d7
 bra     Loop

InstallRoutine:               ;install the routine and write in the window
 move.l  NewIllegalExcept,$10 ;that the processor is 68017
 move.l  NewAddrExcept,$c
 lea     Text68017,a1
 move.l  #0,d0
 move.l  #0,d1
 move.l  Window_Handler,a0
 move.l  50(a0),a0          ;rastport
 jsr     PrintIText(a6)
 not.l   d7
 bra     Loop

CloseIt:
 move.l  Intuition_Base,a6
 tst.l   d7                ;based on the d7 contents,we should display
 beq     JustQuit          ;different requesters before quitting
 lea     Quit_Deinstall,a1 ;write: quitting without removing routine...
 move.l  #300,d2
 move.l  #63,d3
 bra     Decide
JustQuit:
 lea     QuitT,a1    ;write: really want to quit ?
 move.l  #240,d2
 move.l  #57,d3
Decide:
 move.l  #0,a0
 lea     YesT,a2
 lea     CancelT,a3
 move.l  #0,d0
 move.l  #0,d1
 jsr     AutoRequest(a6)       ;really want to quit?
 tst     d0
 beq     Loop
 move.l  #0,DOSResult
 move.l  Window_Handler,a0
 jsr     CloseWindow(a6)
 tst.l   d7
 bne     Close_All

FrMem:
 move.l  ExecBase,a6
 move.l  NewAddrExcept,a1
 move.l  #EndAddr-BeginAddr,d0
 jsr     FreeMem(a6)
 move.l  NewIllegalExcept,a1
 move.l  #EndIllegal-BeginIllegal,d0
 jsr     FreeMem(a6)
 move.l  NewVec,a1
 move.l  #1024,d0
 jsr     FreeMem(a6)
 move.l  PortAddr,a1
 jsr     RemPort(a6)
 move.l  PortAddr,a1
 move.l  #MSGPortEnd-MSGPort,d0
 jsr     FreeMem(a6)
 bra     Close_All

NoMem:
 move.l  Intuition_Base,a6
 movea.l #0,a0
 lea     MemErrorT,a1
 lea     CancelT,a2
 lea     CancelT,a3
 move.l  #0,d0
 move.l  #0,d1
 move.l  #280,d2
 move.l  #58,d3
 jsr     AutoRequest(a6)      ;tell we could not allocate enough memory


Close_All:
 move.l  Intuition_Base,a1
 move.l  ExecBase,a6
 jsr     CloseLib(a6)
Close_DOS:
No_Intuition:
 move.l  DOS_Base,a1
 move.l  ExecBase,a6
 jsr     CloseLib(a6)    ;close DOS
No_DOS: 
 move.l  DOSResult,d0
 rts

 DATA

DOS_Name:       dc.b 'dos.library',0
Intuition_Name: dc.b 'intuition.library',0
PortAddr:       dc.l 0
CPUName:        dc.l 0

MSGPort:       ;message port structure
 dc.l 0  ;pred.
 dc.l 0  ;succ.
 dc.b 4  ;type = NT_MSGPORT
 dc.b 0  ;priority = 0
Name:
 dc.l PortName ;name
 dc.b 2 ;flags.do nothing 
SigBit:
 dc.b 0
ThisTask:
 dc.l 0
 ds.b 16,0 ;list

PortName: dc.b 'Run68017 Is Present!',0
 ds.w 0
MSGPortEnd:

WindowMain:
 dc.w 57,25
 dc.w 150,45
 dc.b 0,1
 dc.l $240
 dc.l $e
 dc.l GadgetMain
 dc.l 0
 dc.l WindowMainName
 dc.l 0
 dc.l 0
 dc.w 5,5
 dc.w 640,200
 dc.w 1
WindowMainName: dc.b 'Run68017',0
 ds.w 0

GadgetMain:      ;'change cpu' gadget
 dc.l 0
 dc.w 28,29
 dc.w 92,10
 dc.w 0
 dc.w 1
 dc.w 1
 dc.l BorderMain
 dc.l 0
 dc.l TextGadMain
 dc.l 0
 dc.l 0
 dc.w 0
 dc.l 0

BorderMain:
 dc.w -2,-1
 dc.b 1,0,0
 dc.b 5
 dc.l BorderMainPair
 dc.l 0

BorderMainPair:
 dc.w 0,0
 dc.w 94,0
 dc.w 94,11
 dc.w 0,11
 dc.w 0,0

TextGadMain:
 dc.b 3,0,0,0
 dc.w 5,1
 dc.l 0
 dc.l GadTextMain
 dc.l 0
GadTextMain: dc.b 'CHANGE CPU',0
 ds.w 0

PText:
 dc.b 2,0,0,0
 dc.w 10,14
 dc.l TOPAZ80
 dc.l Text2
 dc.l 0
Text2: dc.b 'Processor:',0
 ds.w 0
 
Text68000:
 dc.b 1,0,1,0
 dc.w 99,14
 dc.l 0
 dc.l Text00
 dc.l 0
Text00: dc.b '68000',0
 ds.w 0

Text68010:
 dc.b 1,0,1,0
 dc.w 99,14
 dc.l 0
 dc.l Text10
 dc.l 0
Text10: dc.b '68010',0
 ds.w 0

Text68017:
 dc.b 1,0,1,0
 dc.w 99,14
 dc.l 0
 dc.l Text17
 dc.l 0
Text17: dc.b '68017',0
 ds.w 0

No68T:
 dc.b 2,0,0,0
 dc.w 10,5
 dc.l TOPAZ80
 dc.l No68Text
 dc.l 0
No68Text: dc.b  ' 68000/68010 Not Found!',0
 ds.w 0

RoutinePresent:
 dc.b 2,0,0,0
 dc.w 10,5
 dc.l TOPAZ80
 dc.l RPText1
 dc.l RP2
RPText1: dc.b  ' 68017 Emulation Routine',0
 ds.w 0

RP2:
 dc.b 2,0,0,0
 dc.w 10,16
 dc.l TOPAZ80
 dc.l RPText2
 dc.l 0
RPText2: dc.b  ' Already Present!',0
 ds.w 0

CancelT:
 dc.b 2,0,0,0
 dc.w 5,3
 dc.l TOPAZ80
 dc.l CancelText
 dc.l 0
CancelText: dc.b 'Cancel',0
 ds.w 0

YesT:
 dc.b 2,0,0,0
 dc.w 5,3
 dc.l TOPAZ80
 dc.l YesText
 dc.l 0
YesText: dc.b 'Yes',0
 ds.w 0

MemErrorT:
 dc.b 2,0,0,0
 dc.w 5,5
 dc.l TOPAZ80
 dc.l MemErrorText
 dc.l 0
MemErrorText: dc.b ' Could Not Allocate Memory!',0
 ds.w 0

Quit_Deinstall:
 dc.b 2,0,0,0
 dc.w 5,5
 dc.l TOPAZ80
 dc.l QD1Text
 dc.l Quit_Deinstall2
QD1Text: dc.b ' Quit Run68017 Without Removing',0
 ds.w 0

Quit_Deinstall2:
 dc.b 2,0,0,0
 dc.w 5,16
 dc.l TOPAZ80
 dc.l QD2Text
 dc.l 0
QD2Text: dc.b ' The Emulation Routine?',0
 ds.w 0

QuitT:
 dc.b 2,0,0,0
 dc.w 5,5
 dc.l TOPAZ80
 dc.l QuitText
 dc.l 0
QuitText: dc.b ' Really Quit Run68017?',0
 ds.w 0

InfoWindow:
 dc.w 100,33
 dc.w 350,85
 dc.b 0,1
 dc.l 0
 dc.l $6
 dc.l 0
 dc.l 0
 dc.l InfoWindowName
 dc.l 0
 dc.l 0
 dc.w 5,5
 dc.w 640,200
 dc.w 1
InfoWindowName: dc.b 'Run68017 ',0
 ds.w 0

NextText1:
 dc.b 1,0,0,0
 dc.w 123,15
 dc.l TOPAZ60
 dc.l InfoText1
 dc.l NextText2
InfoText1: dc.b 'Run68017',0
 ds.w 0

NextText2:
 dc.b 1,0,0,0
 dc.w 105,26
 dc.l TOPAZ80
 dc.l InfoText2
 dc.l NextText3
InfoText2: dc.b 'By Kamran Karimi',0
 ds.w 0

NextText3:
 dc.b 1,0,0,0
 dc.w 10,36
 dc.l TOPAZ80
 dc.l InfoText3
 dc.l NextText4
InfoText3: dc.b 'This program allows you to use 68020',0
 ds.w 0

NextText4:
 dc.b 1,0,0,0
 dc.w 10,46
 dc.l TOPAZ80
 dc.l InfoText4
 dc.l NextText5
InfoText4: dc.b 'instructions with a 68000.',0
 ds.w 0

NextText5:
 dc.b 1,0,0,0
 dc.w 10,56
 dc.l TOPAZ80
 dc.l InfoText5
 dc.l NextText6
InfoText5: dc.b 'It uses Self-Modifying Code.',0
 ds.w 0

NextText6:
 dc.b 1,0,0,0
 dc.w 10,66
 dc.l TOPAZ80
 dc.l InfoText6
 dc.l 0
InfoText6: dc.b 'Refer to Run68017.ReadMe for more info',0
 ds.w 0

TOPAZ60:
 dc.l Fontname
 dc.l 589824

TOPAZ80:
 dc.l Fontname
 dc.l 524288

Fontname:
 dc.b 'topaz.font',0
 ds.w 0

DOS_Base:        dc.l 0
Intuition_Base:  dc.l 0
Window_Handler:  dc.l 0
DOSResult:       dc.l 0


 CODE

BeginAddr:
 movem.l d0/d1/a0/a1/a6,-(a7)
 move.l  ExecBase,a6
 jsr     Forbid(a6)
 movea.l 30(a7),a0
 move.l  a0,d0
 lsr.l   #1,d0
 bcs     OddAddr
 suba.l  #2,a0
 bra     TestAddr
OddAddr:
 suba.l  #1,a0    ;a0 should hold an even address
TestAddr:
 move.w  (a0),d0
 move.w  d0,d1
 cmpi.w  #$61ff,d1
 beq     B_S_R_L
 andi.w  #$f0ff,d0
 cmpi.w  #$60ff,d0
 beq     B_R_A_L

IllegaleAddr:
 jsr     Permit(a6)
 movem.l (a7)+,d0/d1/a0/a1/a6
 move.l  OldAddrExcept(pc),-(a7) ;place address of original except handler
 suba.l  #2,a7                   ;as return address on the stack
 move.w  14(a7),(a7)
 bset    #5,(a7)
 bclr    #7,(a7)
 rte

B_c_c_L:   ;bra.l and bcc.l (when executed)  are te same
B_R_A_L:
 movea.l 30(a7),a0
 move.l  (a0),d0
 adda.l  d0,a0
 move.l  a0,30(a7)
 jsr     Permit(a6)
 movem.l (a7)+,d0/d1/a0/a1/a6
 adda.l  #8,a7         ;remove address error stack frame
 btst    #7,(a7)
 beq     NT00
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)      ;no trace
 bset    #5,(a7)      ;supervisor
NT00:
 rte


B_S_R_L:
 btst    #5,29(a7)      ;supervisor or user stack?
 bne     SuperMode
 movea.l 30(a7),a0
 adda.l  #1,a0
 move.l  (a0),d0
 move.l  a0,d1
 add.l   #4,d1
 move    USP,a1
 move.l  d1,(a1)
 adda.l  d0,a0
 move.l  a0,30(a7)
 jsr     Permit(a6)
 movem.l (a7)+,d0/d1/a0/a1/a6
 adda.l  #8,a7         ;remove address error stack frame
 btst    #7,(a7)
 beq     NT10
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)      ;no trace
 bset    #5,(a7)      ;supervisor
NT10:
 rte


SuperMode:
 movea.l 30(a7),a0
 adda.l  #1,a0
 move.l  (a0),d0
 add.l   #4,a0
 move.l  a0,34(a7)  ;ret addr.
 adda.l  d0,a0
 move.l  a0,30(a7)  ;branch addr.
 jsr     Permit(a6)
 movem.l (a7)+,d0/d1/a0/a1/a6
 adda.l  #8,a7         ;remove address error stack frame
 btst    #7,(a7)      ;trace bit set at the time of error?
 beq     NT11
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)      ;no trace
 bset    #5,(a7)      ;supervisor
NT11:
 rte


OldAddrExcept:  dc.l 0
NewAddrExcept:  dc.l 0

EndAddr:


BeginIllegal:        ;determining which command caused exception
 movem.l d0-d7/a0-a6,-(a7)
 move.l  ExecBase,a6
 jsr     Forbid(a6)
 lea     StackP(pc),a3
 move.w  60(a7),d0
 btst    #13,d0
 bne     SupStack
 move    USP,a1
 move.l  a1,(a3)
 bra     StackSaved
SupStack:
 move.l  a7,(a3)
 add.l   #66,(a3)
StackSaved:         ;a7 at the time of exception saved!
 movea.l 62(a7),a0
 move.w  (a0),d3
 move.w  d3,d4
 lea     WhichOne(pc),a3
 move.l  #1,(a3)     ;assume bfclr
 andi.w  #$ffc0,d3
 cmpi.w  #$ecc0,d3
 beq     B_F_C_L_R
 move.l  #2,(a3)     ;assume bfset
 cmpi.w  #$eec0,d3
 beq     B_F_S_E_T
 move.l  #3,(a3)     ;assume bfchg
 cmpi.w  #$eac0,d3
 beq     B_F_C_H_G
 move.l  #4,(a3)
 cmpi.w  #$edc0,d3
 beq     B_F_F_F_O
 move.l  #5,(a3)
 cmpi.w  #$e8c0,d3
 beq     B_F_T_S_T
 move.l  #6,(a3)
 cmpi.w  #$e9c0,d3
 beq     B_F_E_X_T_U
 move.l  #7,(a3)
 cmpi.w  #$ebc0,d3
 beq     B_F_E_X_T_S
 cmpi.w  #$efc0,d3
 beq     B_F_I_N_S
 move.w  d4,d3
 andi.w  #$f9c0,d3
 cmpi.w  #$00c0,d3
 beq     CMP2_CHK2  ;chk2 or cmp2 ?
 move.w  d4,d3
 andi.w  #$f1c0,d3
 cmpi.w  #$4100,d3
 beq     C_H_K_L      ;chk.l ?
 move.w  d4,d3
 andi.w  #$ffc0,d3
 cmpi.w  #$4c40,d3
 beq     D_I_V_L    ;division ?
 move.w  d4,d3
 andi.w  #$ffc0,d3
 cmpi.w  #$4c00,d3
 beq     M_U_L_L    ;multiply ?
 move.w  d4,d3
 andi.w  #$f9ff,d3
 cmpi.w  #$08fc,d3
 beq     C_A_S_2     ;cas2 ?
 move.w  d4,d3
 andi.w  #$f9c0,d3
 cmpi.w  #$08c0,d3
 beq     C_A_S        ;cas ?
 move.w  d4,d3
 andi.w  #$f1f0,d3
 cmpi.w  #$8180,d3
 beq     U_N_P_K       ;unpk ?
 move.w  d4,d3
 andi.w  #$f1f0,d3
 cmpi.w  #$8140,d3
 beq     P_A_C_K       ;pack ?
 move.w  d4,d3
 andi.w  #$fff8,d3
 cmpi.w  #$4808,d3
 beq     L_I_N_K_L     ;link.l
 move.w  d4,d3
 andi.w  #$f0f8,d3
 cmpi.w  #$50f8,d3     ;TRAPcc ?
 beq     T_R_A_P_C_C
 move.w  d4,d3
 andi.w  #$fe00,d3
 cmpi.w  #$4800,d3     ;EXTB ?
 beq     E_X_T_B
 move.w  d4,d3
 cmpi.w  #$4e74,d3   ;was is RTD?
 beq     R_T_D
 lsr.w   #1,d3
 cmpi.w  #$273d,d3     ;or MOVEC?
 bne     what1
 move.w  60(a7),d0  ;get status register
 btst    #13,d0 ;check if we were in supervisor mode when exception occured
 bne     M_O_V_E_C
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 move.l  $20,-(a7)           ;making a fake return address and SR on stack
 suba.l  #2,a7
 move.w  $6(a7),(a7)
 bset    #5,(a7)    ;supervisor mode
 bclr    #7,(a7)    ;no trace
 rte              ;go privillage violation
what1:
 move.w  d4,d3
 lsr.w   #8,d3
 cmpi.w  #$0e,d3    ;was the illegal command MOVES?
 bne     what2
 move.w  60(a7),d0
 btst    #13,d0      ;in supervisor mode
 bne     M_O_V_E_S
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 move.l  $20,-(a7)    ;making a fake return address and SR on stack
 suba.l  #2,a7
 move.w  $6(a7),(a7)
 bset    #5,(a7)    ;supervisor mode
 bclr    #7,(a7)    ;no trace
 rte               ; go privillage violation
what2:
 move.w  d4,d3
 lsr.w   #6,d3
 cmpi.w  #$010b,d3         ;was the instruction move ccr,<ea> ?
 beq     M_O_V_E_F_C_C_R

illegale:      ;it was non of them so do the usual exception processing
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 move.l  OldIllegalExcept(pc),-(a7) ;place address of original except handler
 suba.l  #2,a7                  ;as return address on the stack
 move.w  $6(a7),(a7)
 bset    #5,(a7)
 bclr    #7,(a7)
 rte



B_F_I_N_S:
 lea     Nextbfins(pc),a3
 lea     Val3(pc),a4
 move.l  a3,(a4)
 bra     BFCommon              ;go to the common routine
Nextbfins:
 andi.b  #$f0,61(a7)  ;flags cleared
 bset    #2,61(a7)   ;assume zero
 move.l  #7,d3
 move.l  d4,d1   ;d1 has width
 sub.l   #1,d1
 sub.l   d2,d3   ;d2 has offset
 sub.l   d3,d4
 sub.l   #1,d4
 move.l  d3,d6  ;counter
 move.l  62(a7),a0
 move.w  2(a0),d0
 andi.w  #$7000,d0
 lsr.w   #7,d0
 lsr.w   #5,d0
 mulu    #4,d0
 move.l  0(a7,d0),d0
 btst    d1,d0
 beq     InsLoop
 bset    #3,61(a7)
InsLoop:
 btst    d1,d0
 beq     ClrIns
 bclr    #2,61(a7)
 bset    d3,(a1)
 bra     InstDone
ClrIns:
 bclr    d3,(a1)
InstDone:
 sub.l   #1,d1
 sub.l   #1,d3
 sub.l   #1,d6
 bpl     InsLoop
 adda.l  #1,a1
 divu    #8,d4
 move.l  d4,d5
 andi.l  #$ffff,d5
 beq     Noinsquote
 move.l  #7,d3
 move.l  #7,d6
 sub.l   #1,d5
 mulu    #8,d5
 swap    d4
 andi.l  #$ffff,d4
 add.l   d5,d4
 bra     InsLoop
Noinsquote:
 swap    d4
 tst.w   d4
 beq     InsDone
 move.l  d4,d6
 sub.l   #1,d6
 move.l  #7,d3
 moveq   #0,d4
 bra     InsLoop
InsDone:
 tst.l   d7             ;if the operand was in a data register, update it
 beq     insModified
 move.l  62(a7),a0
 move.w  (a0),d0
 andi.w  #$7,d0
 mulu    #4,d0
 move.l  SaveVal(pc),a1
 move.l  (a1),0(a7,d0)
insModified:
 move.l  62(a7),a0
 adda.l  NumAdd(pc),a0
 move.l  a0,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)       ;trace bit was set at the time of exception?
 beq     NT30
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT30:
 rte



B_F_E_X_T_S:
B_F_E_X_T_U:
 lea     Nextbfext(pc),a3
 lea     Val3(pc),a4
 move.l  a3,(a4)
 bra     BFCommon
Nextbfext:
 move.l  d4,d0
 moveq   #0,d7
 andi.b  #$f0,61(a7)  ;flags cleared
 bset    #2,61(a7)   ;assume zero
 move.l  #7,d3
 sub.l   d2,d3
 sub.l   d3,d4
 sub.l   #1,d4
 move.l  d3,d6  ;counter
 btst    d3,(a1)
 beq     ExtLoop
 bset    #3,61(a7)
ExtLoop:
 btst    d3,(a1)
 beq     AZero
 bclr    #2,61(a7)
 bset    #0,d7
 bra     NextBit
AZero:
 bclr    #0,d7
NextBit:
 sub.l   #1,d3
 sub.l   #1,d6
 bpl     CommonLoop
 adda.l  #1,a1
 divu    #8,d4
 move.l  d4,d5
 andi.l  #$ffff,d5
 beq     Noextquote
 move.l  #7,d3
 move.l  #7,d6
 sub.l   #1,d5
 mulu    #8,d5
 swap    d4
 andi.l  #$ffff,d4
 add.l   d5,d4
 bra     CommonLoop
Noextquote:
 swap    d4
 tst.w   d4
 beq     ExtDone
 move.l  d4,d6
 sub.l   #1,d6
 move.l  #7,d3
 moveq   #0,d4
CommonLoop:
 lsl.l   #1,d7
 bra     ExtLoop
ExtDone:
 move.l  WhichOne(pc),d5
 cmpi.w  #6,d5
 beq     Plus
 btst    #3,61(a7)
 beq     Plus
 move.l  #31,d5
 sub.l   d0,d5
bfexts:
 bset    d0,d7
 add.l   #1,d0
 dbra    d5,bfexts
Plus:
 move.l  62(a7),a0
 move.w  2(a0),d0
 andi.w  #$7000,d0
 lsr.w   #5,d0
 lsr.w   #7,d0
 mulu    #4,d0
 move.l  d7,0(a7,d0)
 move.l  62(a7),a0
 adda.l  NumAdd(pc),a0
 move.l  a0,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT40
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT40:
 rte



B_F_T_S_T:
B_F_F_F_O:
 lea     Nextbftst(pc),a3
 lea     Val3(pc),a4
 move.l  a3,(a4)
 bra     BFCommon
Nextbftst:
 move.l  BFOffset(pc),d7 ;get the offset
 sub.l   #1,d7
 move.l  d4,d0   ;width
 andi.b  #$f0,61(a7)  ;flags cleared
 bset    #2,61(a7)   ;assume zero
 move.l  #7,d3
 sub.l   d2,d3
 sub.l   d3,d4
 sub.l   #1,d4
 move.l  d3,d6  ;counter
 btst    d3,(a1)
 beq     TestLoop
 bset    #3,61(a7)
TestLoop:
 add.l   #1,d7
 btst    d3,(a1)
 beq     tstDone
 bclr    #2,61(a7)
 bra     testDone
tstDone:
 sub.l   #1,d0
 beq     tstDone
 sub.l   #1,d3
 sub.l   #1,d6
 bpl     TestLoop
 adda.l  #1,a1
 divu    #8,d4
 move.l  d4,d5
 andi.l  #$ffff,d5
 beq     Notstquote
 move.l  #7,d3
 move.l  #7,d6
 sub.l   #1,d5
 mulu    #8,d5
 swap    d4
 andi.l  #$ffff,d4
 add.l   d5,d4
 bra     TestLoop
Notstquote:
 swap    d4
 tst.w   d4
 beq     testDone
 move.l  d4,d6
 sub.l   #1,d6
 move.l  #7,d3
 moveq   #0,d4
 bra     TestLoop
testDone:
 move.l  WhichOne(pc),d5
 cmpi.w  #5,d5
 beq     NobfDest
 move.l  62(a7),a0
 move.w  2(a0),d1
 andi.w  #$7000,d1
 lsr.w   #7,d1
 lsr.w   #5,d1
 mulu    #4,d1
 move.l  d7,0(a7,d1)
NobfDest:
 adda.l  NumAdd(pc),a0
 move.l  a0,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT50
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT50:
 rte



B_F_C_L_R:
B_F_S_E_T:
B_F_C_H_G:
 lea     Nextbfchg(pc),a3
 lea     Val3(pc),a4
 move.l  a3,(a4)
 bra     BFCommon
Nextbfchg:
 andi.b  #$f0,61(a7)  ;flags cleared
 bset    #2,61(a7)   ;assume zero
 move.l  #7,d3
 sub.l   d2,d3
 sub.l   d3,d4
 sub.l   #1,d4
 move.l  d3,d6  ;counter
 btst    d3,(a1)
 beq     ChangeLoop
 bset    #3,61(a7)
ChangeLoop:
 move.l  WhichOne(pc),d5
 cmpi.l  #1,d5
 bne     chgset
 bclr    d3,(a1)
 beq     chgset
 bclr    #2,61(a7)
chgset:
 cmpi.l  #2,d5
 bne     chg
 bset    d3,(a1)
 beq     chg
 bclr    #2,61(a7)
chg:
 cmpi.l  #3,d5
 bne     CLSDone
 bchg    d3,(a1)
 beq     CLSDone
 bclr    #2,61(a7)
CLSDone:
 sub.l   #1,d3
 sub.l   #1,d6
 bpl     ChangeLoop
 adda.l  #1,a1
 divu    #8,d4
 move.l  d4,d5
 andi.l  #$ffff,d5
 beq     Nochgquote
 move.l  #7,d3
 move.l  #7,d6
 sub.l   #1,d5
 mulu    #8,d5
 swap    d4
 andi.l  #$ffff,d4
 add.l   d5,d4
 bra     ChangeLoop
Nochgquote:
 swap    d4
 tst.w   d4
 beq     ChgDone
 move.l  d4,d6
 sub.l   #1,d6
 move.l  #7,d3
 moveq   #0,d4
 bra     ChangeLoop
ChgDone:
 tst.l   d7
 beq     chgModified
 move.l  62(a7),a0
 move.w  (a0),d0
 andi.w  #$7,d0
 mulu    #4,d0
 move.l  SaveVal(pc),a1
 move.l  (a1),0(a7,d0)
chgModified:
 move.l  62(a7),a0
 adda.l  NumAdd(pc),a0
 move.l  a0,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT60
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT60:
 rte





CMP2_CHK2:
 lea     Flag(pc),a3
 move.l  #0,(a3)
 move.l  62(a7),a0
 move.w  (a0),d0
 move.w  d0,d4
 andi.w  #$0600,d0
 lsr.w   #7,d0
 lsr.w   #2,d0
 cmpi.w  #0,d0
 bne     cmplw
 move.w  #$1000,d2
 move.w  #0,d3
 move.l  #2,(a3)
 bra     CmpSizeDone
cmplw:
 cmpi.w  #$1,d0
 bne     cmpl
 move.w  #$3000,d2
 move.w  #$0040,d3
 move.l  #1,(a3)
 bra     CmpSizeDone
cmpl:
 move.w  #$2000,d2
 move.w  #$0080,d3
CmpSizeDone:
 move.l  62(a7),a0
 move.w  2(a0),d0
 btst    #15,d0
 beq     NotAddr
 add.l   #4,(a3)      ;address should be compared long!
NotAddr:
 lea     MoveCMP1(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d2,(a3)
 lea     MoveCMP2(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d2,(a3)
 lea     CMPHigh(pc),a3
 andi.w  #$fe3f,(a3)
 or.w    d3,(a3)
 lea     CMPLow(pc),a3
 andi.w  #$fe3f,(a3)
 or.w    d3,(a3)
 move.w  d4,d0
 andi.w  #$3f,d0
 lea     NumAdd(pc),a5
 lea     MoveCMP(pc),a3
 andi.w  #$ffc0,(a3)
 or.w    d0,(a3)
 move.l  #$4e714e71,2(a3)
 move.l  #4,(a5)
 cmpi.w  #$39,d0       ;abs long
 bne     labcmp10
 move.l  4(a0),2(a3)
 move.l  #8,(a5)
 bra     CMPDone
labcmp10:
 cmpi.w  #$38,d0    ;abs short
 bne     labcmp20
 move.w  4(a0),2(a3)
 move.l  #6,(a5)
 bra     CMPDone
labcmp20:
 cmpi.w  #$3c,d0   ;imm. data
 bne     labcmp30
 move.l  4(a0),2(a3)
 move.l  #8,(a5)
 bra     CMPDone
labcmp30:
 cmpi.w  #$3a,d0
 bne     labcmp40
 move.w  4(a0),d0
 ext.l   d0
 adda.l  #4,a0
 adda.l  d0,a0
 lea     saved1(pc),a3
 move.l  a0,(a3)
 move.l  #6,(a5)
 bra     PCcmpBack
labcmp40:
 cmpi.w  #$3b,d0
 bne     labcmp50
PCIndexcmp:
 move.l  62(a7),a0
 move.w  4(a0),d3
 btst    #8,d3
 beq     cmpshort
 lea     BDFlag(pc),a3
 move.l  #1,(a3)
 lea     cmp13(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     NEWADDRESSING   ;it is a 68020 addressing mode
cmp13:
 lea     MoveCMP(pc),a3
 andi.w  #$ffc0,(a3)
 ori.w   #$0039,(a3)
 move.l  RetAddr(pc),2(a3)
 bra     CMPDone
cmpshort:
 lea     NumAdd(pc),a4
 move.l  #6,(a4)
 lea     BDFlag(pc),a3
 move.l  #1,(a3)
 lea     cmp23(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     BriefFormat   ;it is a 68020 addressing mode
cmp23:
 lea     MoveCMP(pc),a3
 andi.w  #$ffc0,(a3)
 ori.w   #$0039,(a3)
 move.l  RetAddr(pc),2(a3)
 bra     CMPDone
labcmp50:
 andi.w  #$38,d0
 cmpi.w  #$28,d0
 bne     labcmp60
 move.w  4(a0),2(a3)
 move.l  #6,(a5)
 bra     CMPDone
labcmp60:
 cmpi.w  #$30,d0
 bne     labcmp70
 move.w  4(a0),d3
 btst    #8,d3
 beq     cmp12
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     cmp11(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     NEWADDRESSING   ;it is a 68020 addressing mode
cmp11:
 lea     MoveCMP(pc),a3
 andi.w  #$ffc0,(a3)
 ori.w   #$0039,(a3)
 move.l  RetAddr(pc),2(a3)
 bra     CMPDone
cmp12:
 lea     NumAdd(pc),a4
 move.l  #6,(a4)
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     cmp21(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     BriefFormat    ;it is a 68020 addressing mode
cmp21:
 lea     MoveCMP(pc),a3
 andi.w  #$ffc0,(a3)
 ori.w   #$0039,(a3)
 move.l  RetAddr(pc),2(a3)
 bra     CMPDone
labcmp70:
 cmpi.w  #$38,d0
 beq     illegale
CMPDone:
 move.l  Flag(pc),d7
 cmpi.l  #4,d7
 ble     Not32bitAddrcmp
 move.w  #$0080,d3
 lea     CMPHigh(pc),a3
 andi.w  #$fe3f,(a3)
 or.w    d3,(a3)
 lea     CMPLow(pc),a3
 andi.w  #$fe3f,(a3)
 or.w    d3,(a3)
Not32bitAddrcmp:
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 lea     savea1(pc),a7
 move.l  a1,(a7)
 move.l  StackP(pc),a7
MoveCMP:
 lea     (a1),a1   ;(a1) will be changed to propper value
 nop
 nop
 lea     SaveVal(pc),a7
 move.l  a1,(a7)          ;SaveVal has the first operand
 move.l  savea1(pc),a1
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0-d7/a0-a6,-(a7)
PCcmpBack:
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),-(a7)
 movem.l d0-d7/a0-a6,-(a7)
 move.l  66(a7),a0
 move.w  2(a0),d0
 move.w  d0,d1
 andi.w  #$7000,d0
 lsr.w   #7,d0
 lsr.w   #5,d0
 mulu    #4,d0
 btst    #15,d1
 beq     cmpdatareg
 add.l   #32,d0
cmpdatareg:
 move.l  0(a7,d0),d1   ;d1 has the register operand.
 lea     saved1(pc),a3
 move.l  d1,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 adda.l  #4,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.w  60(a7),d7
 bclr    #2,d7     ;reset Z
 bclr    #0,d7     ;reset C
 move.w  d7,60(a7)
 move.l  SaveVal(pc),a1
 lea     Val1(pc),a2
 lea     Val2(pc),a3
MoveCMP1:
 move.l  (a1)+,(a2)   ;lower bound
MoveCMP2:
 move.l  (a1),(a3)    ;upper bound
 move.l  saved1(pc),d1  ;d1 has register operand
 move.l  Flag(pc),d7
 cmpi.l  #4,d7
 ble     CMPLowVal
 move.l  Val1(pc),d3
 move.l  Val2(pc),d4
 btst    #0,d7
 bne     extLong
 ext.w   d3
 ext.w   d4
extLong:
 ext.l   d3
 ext.l   d4
 lea     Val1(pc),a3
 lea     Val2(a3),a4
 move.l  d3,(a3)
 move.l  d4,(a4)
CMPLowVal:
 move.w  60(a7),d7
CMPLow:
 cmp.l   Val1(pc),d1
 blt     CMPOut
 bne     CMPHigh
 bset    #2,d7
CMPHigh:
 cmp.l   Val2(pc),d1
 ble     CMPIn
CMPOut:
 bset    #0,d7
 move.w  d7,60(a7)
 move.l  62(a7),a0
 move.w  2(a0),d1
 btst    #11,d1
 beq     CmpBound
 adda.l  NumAdd(pc),a0
 move.l  a0,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 move.l  $18,-(a7)         ;go CHK,CHK2 exception routine
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
 rte

CMPIn:             ;no need to go CHK,CHK2 exception!,either operands within
 bne     CmpBound   ;bounds or it was CMP2
 bset    #2,d7
CmpBound:
 move.w  d7,60(a7)
 move.l  62(a7),a0
 adda.l  NumAdd(pc),a0
 move.l  a0,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT71
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT71:
 rte


C_H_K_L:
 move.l  62(a7),a0
 move.w  (a0),d0
 andi.w  #$3f,d0
 lea     NumAdd(pc),a5
 lea     MoveCHK(pc),a3
 andi.w  #$ffc0,(a3)
 or.w    d0,(a3)
 move.l  #$4e714e71,2(a3)
 move.l  #2,(a5)
 cmpi.w  #$39,d0       ;abs long
 bne     labchk10
 move.l  2(a0),2(a3)
 move.l  #6,(a5)
 bra     CHKDone
labchk10:
 cmpi.w  #$38,d0    ;abs short
 bne     labchk20
 move.w  2(a0),2(a3)
 move.l  #4,(a5)
 bra     CHKDone
labchk20:
 cmpi.w  #$3c,d0   ;imm. data
 bne     labchk30
 move.l  2(a0),2(a3)
 move.l  #6,(a5)
 bra     CHKDone
labchk30:
 cmpi.w  #$3a,d0
 bne     labchk40
 moveq   #2,d1             ;operand size for PCRelative
 lea     NumAdd(pc),a3
 move.l  #4,(a3)
 lea     chklr(pc),a3
 lea     Val3(pc),a4
 move.l  a3,(a4)
 bra     PCRelative
chklr:
 bra     PCchkBack
labchk40:
 cmpi.w  #$3b,d0
 bne     labchk50
 lea     NumAdd(pc),a3
 move.l  #4,(a3)
 moveq   #2,d1
 lea     chkli(pc),a3
 lea     Val3(pc),a4
 move.l  a3,(a4)
 lea     PCIndex(pc),a3
 jmp     (a3)
chkli:
 bra     PCchkBack
labchk50:
 andi.w  #$38,d0
 cmpi.w  #$28,d0
 bne     labchk60
 move.w  2(a0),2(a3)
 move.l  #4,(a5)
 bra     CHKDone
labchk60:
 cmpi.w  #$30,d0
 bne     labchk70
 move.w  2(a0),d3
 btst    #8,d3
 beq     chk12
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     chk11(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #2,(a3)
 bra     NEWADDRESSING   ;it is a 68020 addressing mode
chk11:
 move.l  RetAddr(pc),a1
 move.l  (a1),d3
 bra     PCchkBack
chk12:
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     NumAdd(pc),a4
 move.l  #4,(a4)
 lea     chk21(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #2,(a3)
 bra     BriefFormat   ;it is a 68020 addressing mode
chk21:
 move.l  RetAddr(pc),a1
 move.l  (a1),d3
 bra     PCchkBack
labchk70:
 cmpi.w  #$38,d0
 beq     illegale
CHKDone:
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 lea     savea1(pc),a7
 move.l  a1,(a7)
 move.l  StackP(pc),a7
MoveCHK:
 movea.l d0,a1   ;d0 will be changed to propper value
 nop
 nop
 lea     saved1(pc),a7
 move.l  a1,(a7)          ;saved1 has the first operand
 move.l  savea1(pc),a1
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.l  saved1(pc),d3    ;d3 has the <ea> operand.
PCchkBack:
 move.l  62(a7),a0
 move.w  (a0),d0
 andi.w  #$0e00,d0
 lsr.w   #7,d0
 lsr.w   #2,d0
 mulu    #4,d0
 move.l  0(a7,d0),d1   ;d1 has the register operand.
 cmpi.l  #0,d1
 blt     LessZero  ;less than zero
 cmp.l   d3,d1
 bgt     GreatEf   ;greater than <ea>
 bra     DoneCHK
LessZero:
 move.w  60(a7),d0
 bset    #3,d0
 move.w  d0,60(a7)
 bra     GoCHKTrap
GreatEf:
 move.w  60(a7),d0
 bclr    #3,d0
 move.w  d0,60(a7)
GoCHKTrap:
 movea.l 62(a7),a0
 adda.l  NumAdd(pc),a0
 move.l  a0,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 move.l  $18,-(a7)          ;go CHK,CHK2 exception processing
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
 rte
DoneCHK:
 movea.l 62(a7),a0
 adda.l  NumAdd(pc),a0
 move.l  a0,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT80
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT80:
 rte



D_I_V_L:
 move.l  62(a7),a0
 move.w  (a0),d0
 andi.w  #$3f,d0
 lea     NumAdd(pc),a5
 lea     MoveDiv(pc),a3
 andi.w  #$ffc0,(a3)
 or.w    d0,(a3)
 move.l  #$4e714e71,2(a3)
 move.l  #4,(a5)
 cmpi.w  #$39,d0       ;abs long
 bne     labdiv10
 move.l  4(a0),2(a3)
 move.l  #8,(a5)
 bra     DivDone
labdiv10:
 cmpi.w  #$38,d0    ;abs short
 bne     labdiv20
 move.w  4(a0),2(a3)
 move.l  #6,(a5)
 bra     DivDone
labdiv20:
 cmpi.w  #$3c,d0   ;imm. data
 bne     labdiv30
 move.l  4(a0),2(a3)
 move.l  #8,(a5)
 bra     DivDone
labdiv30:
 cmpi.w  #$3a,d0
 bne     labdiv40
 moveq   #4,d1             ;operand size for PCRelative
 lea     NumAdd(pc),a3
 move.l  #6,(a3)
 lea     divr(pc),a3
 lea     Val3(pc),a4
 move.l  a3,(a4)
 bra     PCRelative

divr:
 bra     PCDivBack
labdiv40:
 cmpi.w  #$3b,d0
 bne     labdiv50
 lea     NumAdd(pc),a3
 move.l  #6,(a3)
 moveq   #4,d1
 lea     divi(pc),a3
 lea     Val3(pc),a4
 move.l  a3,(a4)
 bra     PCIndex
divi:
 bra     PCDivBack
labdiv50:
 andi.w  #$38,d0
 cmpi.w  #$28,d0
 bne     labdiv60
 move.w  4(a0),2(a3)
 move.l  #6,(a5)
 bra     DivDone
labdiv60:
 cmpi.w  #$30,d0  ;index
 bne     labdiv70
 move.w  4(a0),d3
 btst    #8,d3
 beq     div12
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     div11(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     NEWADDRESSING   ;it is a 68020 addressing mode
div11:
 move.l  RetAddr(pc),a1
 move.l  (a1),d3
 bra     PCDivBack
div12:
 lea     NumAdd(pc),a4
 move.l  #6,(a4)
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     div21(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     BriefFormat   ;it is a 68020 addressing mode
div21:
 move.l  RetAddr(pc),a1
 move.l  (a1),d3
 bra     PCDivBack
labdiv70:
 cmpi.w  #$38,d0
 beq     illegale
DivDone:
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 lea     savea1(pc),a7
 move.l  a1,(a7)
 move.l  StackP(pc),a7
MoveDiv:
 movea.l d0,a1   ;d0 will be changed to propper value
 nop
 nop
 lea     saved1(pc),a7
 move.l  a1,(a7)          ;saved1 has the first operand
 move.l  savea1(pc),a1
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.l  saved1(pc),d3    ;d3 has the <ea> operand.(divisor)
PCDivBack:
 move.l  62(a7),a0
 move.w  2(a0),d0
 lsr.w   #7,d0
 lsr.w   #5,d0
 mulu    #4,d0
 move.l  0(a7,d0),d1   ;d1 has the register operand.(dividend)
 tst.l   d3
 bne     NotZeroDiv
 move.l  62(a7),d0
 add.l   NumAdd(pc),d0
 move.l  d0,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6   ;go division by zero
 move.l  $14,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
 rte              ;divide by zero
NotZeroDiv:
 lea     SaveVal(pc),a3
 move.l  #0,(a3)
 move.l  62(a7),a0
 move.w  2(a0),d4
 moveq   #0,d2
 btst    #10,d4
 beq     TestSign
 andi.w  #$7,d4
 mulu    #4,d4
 move.l  0(a7,d4),d2
 move.w  2(a0),d4
TestSign:               ;test to see if the division is signed
 btst    #11,d4        ;if yes, make the operans positive and divide
 beq     UnSignedDiv   ;then adjust the signs
 btst    #10,d4
 beq     Div32Div
 tst.l   d2
 bpl     FirstPlusDiv
 not.l   d1
 not.l   d2
 moveq   #0,d0
 add.l   #1,d1
 addx.l  d0,d2
 add.l   #1,(a3)
 bra     FirstPlusDiv
Div32Div:
 tst.l   d1
 bpl     FirstPlusDiv
 neg.l   d1
 add.l   #1,(a3)
FirstPlusDiv:
 tst.l   d3
 bpl     UnSignedDiv
 neg.l   d3
 add.l   #2,(a3)
UnSignedDiv:       ;d2:d1 ;Dividend - quot.
 moveq   #0,d4    ;d4:d3
 moveq   #0,d6
Div:
 move.l  #64,d0   ;counter
 moveq   #0,d5    ;d6:d5 Rem.
 move    #0,ccr
 roxl.l  #1,d1    ;d2:d1 Quot.
 roxl.l  #1,d2
 roxl.l  #1,d5
 roxl.l  #1,d6
Div0:
 sub.l   d3,d5
 subx.l  d4,d6
 bcc     Div1
 add.l   d3,d5
 addx.l  d4,d6
 move    #16,ccr  ;should go to x
Div1:
 eori    #$10,ccr
 roxl.l  #1,d1
 roxl.l  #1,d2
 move    sr,d7
 sub.l   #1,d0
 beq     DoneDiv
 move    d7,ccr
 roxl.l  #1,d5
 roxl.l  #1,d6
 bra     Div0
DoneDiv:
 move.l  62(a7),a0
 move.w  2(a0),d0
 btst    #11,d0
 beq     UnSignedDiv2
 move.l  SaveVal(pc),d0
 tst.l   d0
 beq     UnSignedDiv2
 cmpi.l  #1,d0
 bne     DivisorNeg
 neg.l   d5    ;neg rem.
 neg.l   d1    ;and quot.
DivisorNeg:
 cmpi.l  #2,d0
 bne     RemNeg
 neg.l   d1    ;neg quot.
RemNeg:
 cmpi.l  #3,d0
 bne     UnSignedDiv2
 neg.l   d5       ;neg rem
UnSignedDiv2:
 move.l  62(a7),a0
 move.w  2(a0),d0
 move.w  d0,d7
 move.w  d7,d6
 andi.w  #$7,d0
 lsr.w   #7,d6
 lsr.w   #5,d6
 mulu    #4,d6
 mulu    #4,d0
 move.l  d5,0(a7,d0)
DivQ:
 move.l  d1,0(a7,d6)
 move    SR,d3      ;affect the flags
 andi.w  #$f,d3
 move.w  60(a7),d4
 andi.w  #$fff0,d4
 or.w    d3,d4
 tst.l   d2
 beq     NoOverFlow
 bset    #1,d4
NoOverFlow:
 move.w  d4,60(a7)
 movea.l 62(a7),a0
 adda.l  NumAdd(pc),a0
 move.l  a0,62(a7)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT90
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT90:
 rte



M_U_L_L:
 move.l  62(a7),a0
 move.w  (a0),d0
 andi.w  #$3f,d0
 lea     NumAdd(pc),a4
 lea     MoveMul(pc),a3
 andi.w  #$ffc0,(a3)
 or.w    d0,(a3)
 move.l  #$4e714e71,2(a3)
 move.l  #4,(a4)
 cmpi.w  #$39,d0       ;abs long
 bne     labmul10
 move.l  4(a0),2(a3)
 move.l  #8,(a4)
 bra     MulDone
labmul10:
 cmpi.w  #$38,d0    ;abs short
 bne     labmul20
 move.w  4(a0),2(a3)
 move.l  #6,(a4)
 bra     MulDone
labmul20:
 cmpi.w  #$3c,d0   ;imm. data
 bne     labmul30
 move.l  4(a0),2(a3)
 move.l  #8,(a4)
 bra     MulDone
labmul30:
 cmpi.w  #$3a,d0
 bne     labmul40
 moveq   #4,d1             ;operand size for PCRelative
 lea     NumAdd(pc),a3
 move.l  #6,(a3)
 lea     mulr(pc),a3
 lea     Val3(pc),a4
 move.l  a3,(a4)
 bra     PCRelative
mulr:
 bra     PCMulBack
labmul40:
 cmpi.w  #$3b,d0
 bne     labmul50
 lea     NumAdd(pc),a3
 move.l  #6,(a3)
 moveq   #4,d1
 lea     muli(pc),a3
 lea     Val3(pc),a4
 move.l  a3,(a4)
 bra     PCIndex

muli:
 bra     PCMulBack
labmul50:
 andi.w  #$38,d0
 cmpi.w  #$28,d0
 bne     labmul60
 move.w  4(a0),2(a3)
 move.l  #6,(a4)
 bra     MulDone
labmul60:
 cmpi.w  #$30,d0     ;index
 bne     labmul70
 move.l  4(a0),d3
 btst    #8,d3
 beq     mul12
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     mul11(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     NEWADDRESSING   ;it is a 68020 addressing mode
mul11:
 move.l  RetAddr(pc),a1
 move.l  (a1),d3
 bra     PCMulBack
mul12:
 lea     NumAdd(pc),a4
 move.l  #6,(a4)
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     mul21(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     NEWADDRESSING   ;it is a 68020 addressing mode
mul21:
 move.l  RetAddr(pc),a1
 move.l  (a1),d3
 bra     PCMulBack
labmul70:
 cmpi.w  #$38,d0
 beq     illegale
MulDone:
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 lea     savea1(pc),a7
 move.l  a1,(a7)
 move.l  StackP(pc),a7
MoveMul:
 movea.l d0,a1   ;d0 will be changed to propper value
 nop
 nop
 lea     saved1(pc),a7
 move.l  a1,(a7)          ;saved1 has the first operand
 move.l  savea1(pc),a1
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.l  saved1(pc),d3    ;d3 has the <ea> operand
PCMulBack:
 move.l  62(a7),a0
 move.w  2(a0),d0
 lsr.w   #7,d0
 lsr.w   #5,d0
 mulu    #4,d0
 move.l  0(a7,d0),d1   ;d1 has the register operand
 move.l  62(a7),a0
 move.w  2(a0),d4
 btst    #11,d4
 beq     UnSigned
 lea     SaveVal(pc),a3
 move.l  #0,(a3)
 tst.l   d1
 bpl     FirstPlus
 neg.l   d1
 add.l   #1,(a3)
FirstPlus:
 tst.l   d3
 bpl     UnSigned
 neg.l   d3
 add.l   #1,(a3)
UnSigned:
 move.l  d1,d2
 move.l  d3,d4
 mulu    d1,d3
 move.l  d3,d6
 move.l  d4,d3
 swap    d3
 mulu    d1,d3
 swap    d3
 move.w  d3,d7
 andi.l  #$ffff0000,d3
 add.l   d3,d6
 move.l  #0,d5
 addx.l  d5,d7
 move.l  d4,d3
 swap    d1
 mulu    d1,d3
 swap    d3
 add.w   d3,d7
 addx.l  d5,d7
 andi.l  #$ffff0000,d3
 add.l   d3,d6
 addx.l  d5,d7
 swap    d4
 swap    d2
 mulu    d2,d4
 add.l   d4,d7
 move.l  62(a7),a0
 move.w  2(a0),d0
 btst    #11,d0       ;if the multiply is signed, change the operand
 beq     UnSigned2     ;size to positive. at the end, adjust the signs
 move.l  SaveVal(pc),d3
 btst    #0,d3
 beq     UnSigned2
 btst    #10,d0
 bne     NegD7
 neg.l   d6
 bra     UnSigned2
NegD7:
 neg.l   d7
UnSigned2:
 move.w  d0,d1
 move.w  d1,d2
 andi.w  #$7,d0
 lsr.w   #7,d1
 lsr.w   #5,d1
 mulu    #4,d1
 mulu    #4,d0
 moveq   #0,d5    ;flag for the size
 btst    #10,d2
 beq     Mul32
 move.l  d7,0(a7,d0)  ;high long word
 move    SR,d3          ;affect the flags
 andi.w  #$f,d3
 move.w  60(a7),d4
 andi.w  #$fff0,d4
 or.w    d3,d4
 move.w  d4,60(a7)
 bclr    #1,61(a7)   ;no overflow
 moveq   #1,d5
Mul32:
 move.l  d6,0(a7,d1)  ;low long word
 beq     NoModifi
 bclr    #2,61(a7) ;if low long word is not zero,then the total is not zero!
NoModifi:
 tst.l   d5
 bne     CCRMulDone
 tst.l   d6
 move    SR,d3       ;affect the flags
 andi.w  #$f,d3
 move.w  60(a7),d4
 andi.w  #$fff0,d4
 or.w    d3,d4
 move.w  d4,60(a7)
 tst.l   d7
 bne     Over32
 bclr    #1,61(a7)  ;no overflow
 bra     CCRMulDone
Over32:
 bset    #1,61(a7)  ;overflow
CCRMulDone:
 movea.l 62(a7),a0
 adda.l  NumAdd(pc),a0
 move.l  a0,62(a7)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT100
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT100:
 rte


C_A_S_2:
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),-(a7)
 movem.l d0-d7/a0-a6,-(a7)
 lea     NumAdd(pc),a3
 move.l  #6,(a3)
 move.l  66(a7),a0
 move.w  (a0),d1
 move.w  d1,d2
 andi.w  #$0600,d1
 lsr.w   #5,d1
 lsr.w   #4,d1
 cmpi.w  #2,d1
 bne     lng2
 move.w  #3,d1
 move.w  #1,d3
 moveq   #2,d7   ; adjust size
 bra     adjsize2
lng2:
 move.w  #2,d1
 move.w  #2,d3
 moveq   #0,d7
adjsize2:
 lsl.w   #7,d1
 lsl.w   #5,d1
 lsl.w   #6,d3      ;d1 for move ,d3 for cmp
 lea     MoveEffAddr1(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d1,(a3)
 lea     UP1(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d1,(a3)
 lea     Mov21(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d1,(a3)
 lea     Movcas21(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d1,(a3)
 lea     Movcas22(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d1,(a3)
 lea     Comp21(pc),a3
 andi.w  #$fe3f,(a3)
 or.w    d3,(a3)
 lea     MoveEffAddr2(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d1,(a3)
 lea     UP2(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d1,(a3)
 lea     Mov22(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d1,(a3)
 lea     Comp22(pc),a3
 andi.w  #$fe3f,(a3)
 or.w    d3,(a3)     
   ;operand sizes adjusted
 move.l  66(a7),a0
 move.w  2(a0),d1
 move.w  d1,d2
 andi.w  #$7000,d1
 lsr.w   #7,d1
 lsr.w   #5,d1
 mulu    #4,d1
 btst    #15,d2
 beq     Cas1
 add.l   #32,d1
Cas1:
 move.l  0(a7,d1),d5  ;d5 has the address
 move.l  d5,a4
 lea     Val1(pc),a3
MoveEffAddr1:
 move.l  (a4),(a3)   ;save (r1) in Val1
 move.l  66(a7),a0
 move.w  4(a0),d1
 move.w  d1,d2
 andi.w  #$7000,d1
 lsr.w   #7,d1
 lsr.w   #5,d1
 mulu    #4,d1
 btst    #15,d2
 beq     Cas2
 add.l   #32,d1
Cas2:
 move.l  0(a7,d1),d6
 movea.l d6,a4
 lea     Val2(pc),a3
MoveEffAddr2:
 move.l  (a4),(a3)   ;save (r2) in Val2
 move.l  66(a7),a0
 move.w  2(a0),d1
 andi.w  #$7,d1
 mulu    #4,d1
 move.l  0(a7,d1),d0
Movcas21:
 move.l  Val1(pc),d1
Comp21:
 cmp.l   d0,d1    ;compare savea1 to dc
 lea     SaveVal(pc),a3
 move    SR,(a3)
 bne     NotEQ21
 move.l  66(a7),a0
 move.w  4(a0),d1
 andi.w  #$7,d1
 mulu    #4,d1
 move.l  0(a7,d1),d0
Movcas22:
 move.l  Val2(pc),d1
Comp22:
 cmp.l   d0,d1    ;compare savea1 to dc2
 lea     SaveVal(pc),a3
 move    SR,(a3)
 bne     NotEQ21
 move.l  66(a7),a0
 move.w  2(a0),d1
 andi.w  #$01c0,d1
 lsr.w   #6,d1
 mulu    #4,d1
 add.l   d7,d1
 move.l  d5,a3
Mov21:
 move.l  0(a7,d1),(a3)     ;move du1 to (r1)
 move.l  66(a7),a0
 move.w  4(a0),d1
 andi.w  #$01c0,d1
 lsr.w   #6,d1
 mulu    #4,d1
 add.l   d7,d1
 move.l  d6,a3  
Mov22:
 move.l  0(a7,d1),(a3)     ;move du2 to (r2)
 bra     CASDone21
NotEQ21:
 move.l  66(a7),a0
 move.w  2(a0),d1
 andi.w  #$7,d1
 mulu    #4,d1
 add.l   d7,d1
 move.l  d5,a3 
UP1:
 move.l  (a3),0(a7,d1)      ;(r1) to dc1
NotEQ22:
 move.l  66(a7),a0
 move.w  4(a0),d1
 andi.w  #$7,d1
 mulu    #4,d1
 add.l   d7,d1
 move.l  d6,a3
UP2:
 move.l  (a3),0(a7,d1)  
CASDone21:
 move.w  SaveVal(pc),d3
 andi.l  #$f,d3
 move.w  64(a7),d2
 andi.w  #$fff0,d2
 or.w    d2,d3
 move.w  d3,64(a7)
 move.l  66(a7),d4
 add.l   NumAdd(pc),d4
 move.l  d4,66(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 adda.l  #4,a7
 btst    #7,(a7)
 beq     NT110
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT110:
 rte



C_A_S:
 move.l  62(a7),a0
 move.w  (a0),d1
 move.w  d1,d2
 andi.w  #$0600,d1
 lsr.w   #5,d1
 lsr.w   #4,d1
 move.w  #0,d3
 cmpi.w  #1,d1
 beq     adjsize
longword:
 cmpi.w  #2,d1
 bne     lng
 move.w  #3,d1
 move.w  #1,d3
 bra     adjsize
lng:
 move.w  #2,d1
 move.w  #2,d3
adjsize:
 lsl.w   #7,d1
 lsl.w   #5,d1
 lsl.w   #6,d3
 lea     EffAddr(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d1,(a3)
 lea     NotEQ(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d1,(a3)
 lea     Mov(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d1,(a3)
 lea     Comp(pc),a3
 andi.w  #$fe3f,(a3)
 or.w    d3,(a3)
 lea     Movd01(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d1,(a3)
 lea     Movd02(pc),a3
 andi.w  #$cfff,(a3)
 or.w    d1,(a3)      ;operand sizes adjustecd

 move.w  d2,d1
 andi.w  #$003f,d1
 lea     EffAddr(pc),a3
 andi.w  #$ffc0,(a3)
 or.w    d1,(a3)
 lea     NotEQ(pc),a3
 andi.w  #$ffc0,(a3)
 or.w    d1,(a3)
 andi.w  #$7,d1
 andi.w  #$38,d2
 lsl.w   #2,d1
 lsl.w   #7,d1
 lsl.w   #3,d2
 or.w    d2,d1
 lea     Mov(pc),a3
 lea     NumAdd(pc),a4
 lea     NotEQ(pc),a5
 move.l  #$4e714e71,2(a3)
 lea     EffAddr(pc),a6
 move.l  #$4e714e71,2(a6)
 andi.w  #$f03f,(a3)
 or.w    d1,(a3)
 lsr.w   #6,d2
 cmpi.w  #$5,d2
 bne     tst21
 move.l  #6,(a4)       ;it is address reg. indirect with displ.
 move.w  4(a0),2(a3)
 move.w  4(a0),2(a6)
 move.w  4(a0),2(a5)
 bra     Here71
tst21:
 cmpi.w  #$6,d2
 bne     tst31
 move.w  4(a0),d3
 btst    #8,d3
 beq     her12
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     her11(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     NEWADDRESSING   ;it is a 68020 addressing mode
her11:
 lea     Mov(pc),a3      ;Modify necessary insructions
 lea     NotEQ(pc),a5
 lea     EffAddr(pc),a6
 move.l  RetAddr(pc),2(a3)
 move.l  RetAddr(pc),2(a6)
 move.l  RetAddr(pc),2(a5)
 andi.w  #$ffc0,(a3)
 ori.w   #$0039,(a3)
 andi.w  #$ffc0,(a5)
 ori.w   #$0039,(a5)
 andi.w  #$ffc0,(a6)
 ori.w   #$0039,(a6)
 bra     Here71  
her12:
 lea     NumAdd(pc),a4
 move.l  #6,(a4)
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     her21(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     BriefFormat         ;it is a 68020 addressing mode
her21:
 lea     Mov(pc),a3
 lea     NotEQ(pc),a5
 lea     EffAddr(pc),a6
 move.l  RetAddr(pc),2(a3)
 move.l  RetAddr(pc),2(a6)
 move.l  RetAddr(pc),2(a5)
 andi.w  #$ffc0,(a3)
 ori.w   #$0039,(a3)
 andi.w  #$ffc0,(a5)
 ori.w   #$0039,(a5)
 andi.w  #$ffc0,(a6)
 ori.w   #$0039,(a6)
 bra     Here71  
tst31:
 lsr.w   #6,d1
 cmpi.w  #$7,d1
 bne     tst41
 move.l  #6,(a4)
 move.w  4(a0),2(a3)
 move.w  4(a0),2(a6)
 move.w  4(a0),2(a5)
 bra     Here71
tst41:
 cmpi.w  #$f,d1
 bne     tst51
 move.l  #8,(a4)
 move.l  4(a0),2(a3)
 move.l  4(a0),2(a6)
 move.l  4(a0),2(a5)
 bra     Here71
tst51:
 move.l  #4,(a4)
Here71:
 move.l  62(a7),a0
 move.w  2(a0),d4
 move.w  d4,d5
 andi.w  #$7,d4
 lsl.w   #7,d4
 lsl.w   #2,d4
 lea     NotEQ(pc),a3
 andi.w  #$f1ff,(a3)
 or.w    d4,(a3)
 andi.w  #$01c0,d5
 lsr.w   #6,d5
 lea     Mov(pc),a3
 andi.w  #$fff8,(a3)
 or.w    d5,(a3)
 lea     SaveVal(pc),a3
 move.l  #0,(a3)
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 lea     saved0(pc),a7
 move.l  d0,(a7)
 move.l  StackP(pc),a7
EffAddr:
 move.l  d0,d0     ;move <ea> to savea1
 nop
 nop
 lea     savea1(pc),a7
Movd01:
 move.l  d0,(a7)     ;place the operand in savea1
 move.l  saved0(pc),d0
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.l  62(a7),a0
 move.w  2(a0),d0
 andi.w  #7,d0
 mulu    #4,d0
 move.l  0(a7,d0),d1
Movd02:
 move.l  savea1(pc),d0
Comp:
 cmp.l   d1,d0    ;compare savea1 to dc
 lea     SaveVal(pc),a3
 move    SR,(a3)
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 lea     saved1(pc),a7
 move.l  d1,(a7)
 move.w  SaveVal(pc),d1
 btst    #2,d1      ; Z = 0?
 beq     NE
 move.l  StackP(pc),a7
 move.l  saved1(pc),d1
Mov:
 move.l  d0,d0     ;move du to <ea>
 nop
 nop
 bra     CASDone
NE:
 move.l  saved1(pc),d1
NotEQ:
 move.l  d0,d1      ;d0 to <ea>, d1 to dc
 nop
 nop
CASDone:
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.w  SaveVal(pc),d3
 andi.w  #$000f,d3
 move.w  60(a7),d2
 andi.w  #$fff0,d2
 or.w    d2,d3
 move.w  d3,60(a7)
 move.l  62(a7),d4
 add.l   NumAdd(pc),d4
 move.l  d4,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT120
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT120:
 rte

  


U_N_P_K:
 move.l  62(a7),a0
 move.w  (a0),d1
 move.w  d1,d2
 andi.w  #$8,d1
 beq     datareg
 move.w  #32,d3
 bra     lab10
datareg:
 move.w  #0,d3
lab10:
 move.w  d2,d1
 andi.w  #$7,d1 
 or.w    d3,d1     ;get source
 lea     Source(pc),a1
 andi.w  #$ffc0,(a1)
 or.w    d1,(a1)
 move.w  d2,d1
 andi.w  #$0e00,d1
 lsl.w   #3,d3
 or.w    d3,d1
 lea     Dest(pc),a1
 andi.w  #$f03f,(a1)
 or.w    d1,(a1)
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 lea     saved1(pc),a7
 move.l  d1,(a7)
 move.l  StackP(pc),a7
Source:
 move.b  d0,d1; move.b  d0,(a7)
 lea     SaveVal(pc),a7
 move.b  d1,(a7)
 move.l  saved1(pc),d1
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.b  SaveVal(pc),d5
 move.w  d5,d4
 andi.w  #$000f,d5
 andi.w  #$00f0,d4
 lsl.w   #4,d4
 or.w    d4,d5
 move.l  62(a7),a0
 move.w  2(a0),d1
 add.w   d1,d5
 lea     Dest(pc),a3
 move.w  d5,2(a3)
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),a7
Dest:
 move.w  #$0000,d0
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0/d1/a0/a1/a6,-(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 move.l  22(a7),d0
 add.l   #4,d0
 move.l  d0,22(a7)
 movem.l (a7)+,d0/d1/a0/a1/a6
 btst    #7,(a7)
 beq     NT130
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT130:
 rte



P_A_C_K:
 move.l  62(a7),a0
 move.w  (a0),d1
 move.w  d1,d2
 andi.w  #$8,d1
 beq     datareg20
 move.w  #32,d3
 bra     lab100
datareg20:
 move.w  #0,d3
lab100:
 move.w  d2,d1
 andi.w  #$7,d1 
 or.w    d3,d1    ;get source
 lea     Source20(pc),a1
 andi.w  #$ffc0,(a1)
 or.w    d1,(a1)
 move.w  d2,d1
 andi.w  #$0e00,d1
 lsl.w   #3,d3
 or.w    d3,d1
 lea     Dest20(pc),a1
 andi.w  #$f03f,(a1)
 or.w    d1,(a1)
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 lea     saved1(pc),a7
 move.l  d1,(a7)
 move.l  StackP(pc),a7
Source20:
 move.w  d0,d1     ; move.w  d0,(a7)
 lea     SaveVal(pc),a7
 move.w  d1,(a7)
 move.l  saved1(pc),d1
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.w  SaveVal(pc),d5
 move.l  62(a7),a0
 move.w  2(a0),d1
 add.w   d1,d5
 move.w  d5,d6
 andi.w  #$0f00,d6
 lsr.w   #4,d6
 andi.w  #$000f,d5
 or.w    d6,d5
 lea     Dest20(pc),a3
 move.w  d5,2(a3)
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),a7
Dest20:
 move.b  #00,d0
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0/d1/a0/a1/a6,-(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 move.l  22(a7),d0
 add.l   #4,d0
 move.l  d0,22(a7)
 movem.l (a7)+,d0/d1/a0/a1/a6
 btst    #7,(a7)
 beq     NT140
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT140:
 rte




L_I_N_K_L:
 move.l  62(a7),a0
 move.w  (a0),d1
 andi.w  #$0007,d1
 lea     RetAddr(pc),a3
 move.l  62(a7),(a3)
 lea     MySR(pc),a3
 move.w  60(a7),d0
 move.w  d0,(a3)
 btst    #13,d0
 bne     SuperS1        ;supervisor or user stack?
 move    USP,a1
 lea     savea1(pc),a3  ;save USP
 move.l  a1,(a3)
 suba.l  #4,a1
 lea     MySP(pc),a3
 move    a1,USP
 move.l  a1,(a3)
 bra     DoOr
SuperS1:
 lea     savea1(pc),a3
 move.l  a7,d5
 move.l  d5,(a3)
 add.l   #66,(a3)    ;66 - 4 = 62
 lea     MySP(pc),a3
 move.l  d5,(a3)
 add.l   #62,(a3)
DoOr:
 cmpi.w  #1,d1
 beq     lab2
 lea     mova1(pc),a2
 andi.w  #$fff8,(a2)
 or.w    d1,(a2)+
 lsl.w   #7,d1
 lsl.w   #2,d1
 andi.w  #$f0ff,(a2)
 or.w    d1,(a2)
 lea     SaveA7(pc),a3
 move.l  a7,(a3)            ;save a7
 movem.l (a7)+,d0-d7/a0-a6
 lea     saved1(pc),a7
 move.l  a1,(a7)
 movea.l savea1(pc),a1
mova1:
 move.l  a0,-(a1)
 movea.l MySP(pc),a0
 movea.l saved1(pc),a1
 bra     lab1
lab2:
 lea     SaveA7(pc),a3
 move.l  a7,(a3)            ;save a7
 movem.l (a7)+,d0-d7/a0-a6
 lea     saved1(pc),a7
 move.l  a0,(a7)
 movea.l savea1(pc),a0
mova0:
 move.l  a1,-(a0)
 movea.l MySP(pc),a1
 movea.l saved1(pc),a0
lab1:
 movea.l SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0-d7/a0-a6,-(a7)
 movea.l RetAddr(pc),a0
 adda.l  #2,a0
 move.l  (a0),d1
 move.w  MySR(pc),d3
 btst    #13,d3
 bne     SuperS2
 move    USP,a1
 adda.l  d1,a1
 move    a1,USP
 bra     fin
SuperS2:
 lea     saved1(pc),a3
 move.l  d1,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 move.l  MySP(pc),a7
 adda.l  saved1(pc),a7
 move.l  RetAddr(pc),-(a7)
 add.l   #6,(a7)           ;link.l requires 6 bytes.
 move.w  MySR(pc),-(a7)
 movem.l d0/d1/a0/a1/a6,-(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0/d1/a0/a1/a6
 btst    #7,(a7)
 beq     NT150
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT150:
 rte

fin:
 move.l  RetAddr(pc),d0
 add.l   #6,d0
 move.l  d0,62(a7)
 move.w  MySR(pc),d0
 move.w  d0,60(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT160
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT160:
 rte


T_R_A_P_C_C:
 move.l  62(a7),a0
 move.w  (a0),d0
 move.w  d0,d4
 andi.w  #$0f00,d0
 lea     bcond(pc),a1
 andi.w  #$f0ff,(a1)
 or.w    d0,(a1)
 andi.w  #$0007,d4
 cmpi.w  #4,d4       ;has a operand
 bne     HasOp
 moveq   #2,d6
 bra     OpFound
HasOp:
 cmpi.w  #2,d4    ;is the operand word?
 bne     long
 moveq   #4,d6
 bra     OpFound
long:
 cmpi.w  #3,d4
 beq     Found
 bra     illegale
Found:
 moveq   #6,d6
OpFound:
 cmpi.w  #$0100,d0      ;is it trapf?
 beq     Exit1
 cmpi.w  #$0000,d0    ;is it trapt?
 beq     GoTrap
 move.w  60(a7),d0
 move    d0,ccr
 nop               ;force the cpu to use the original status register
bcond:
 bcs     GoTrap
Exit1:
 move.l  62(a7),d4         
 add.l   d6,d4
 move.l  d4,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT170
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT170:
 rte 

GoTrap:
 move.l  62(a7),d2
 add.l   d6,d2
 move.l  d2,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 move.l  $1c,-(a7)     ;place address of original except handler
 suba.l  #2,a7                  ;as return address on the stack
 move.w  $6(a7),(a7)
 bset    #5,(a7)
 bclr    #7,(a7)
 rte


 

E_X_T_B:
 move.l  62(a7),a0
 move.w  (a0),d5
 andi.w  #$7,d5
 mulu    #4,d5
 move.l  0(a7,d5),d2  ;get the operand in d2
 ext.w   d2
 ext.l   d2          ;extend it
 move    SR,d0
 andi.w  #$000f,d0
 move.w  60(a7),d1
 andi.w  #$fff0,d1
 or.w    d0,d1
 move.w  d1,60(a7)
 move.l  d2,0(a7,d5)
 move.l  62(a7),d4         ;get the address of the extb.l instruction
 add.l   #2,d4       ;add 2 so that execution begins with the next opcode
 move.l  d4,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT180
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT180:
 rte
 

R_T_D:      ;Syntax: rtd  #<data>
 move.l  62(a7),a0
 moveq   #0,d0
 move.w  2(a0),d0    ;d0 = #<data>
 ext.l   d0
 move.w  60(a7),d1
 btst    #13,d1         ;which stack we were using befor the exception?
 bne     SuperStack
 move.l  USP,a6
 move.l  (a6)+,62(a7)  ;place return address on the usp as the except return
 adda.l  d0,a6        ;address on top of the ssp so we'll return there
               ;then add  the number of bytes appropriate to the usp
 move.l  a6,USP
 bra     EndIt
SuperStack:
 move.l  a7,a6
 adda.l  #70,a6 ;60=15 regs*4,2 for SR,4 for illegal inst,addr,4for ret addr
 adda.l  d0,a6
 move.l  66(a7),-(a6)  ;retun address for rtd
 move.w  60(a7),-(a6)  ;SR
 move.l  #14,d4       ;15 regs
 adda.l  #60,a7
cop:
 move.l  -(a7),-(a6)
 dbra    d4,cop
 move.l  a6,a7
EndIt:
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT190
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT190:
 rte


M_O_V_E_C:   ;Syntax:movec CR,Rn or movec Rn,CR (CR=a control register)
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),-(a7)
 movem.l d0-d7/a0-a6,-(a7)
 move.l  66(a7),a0
 move.w  (a0),d3  ;this is the illegal instruction
 btst    #0,d3
 bne     ToCR
 move.w  2(a0),d3
 move.w  d3,d4
 andi.w  #$7000,d3
 lsr.w   #7,d3
 lsr.w   #5,d3    ;d3 has the register number
 mulu    #4,d3
 btst    #15,d4
 beq     DatReg
 add.l   #32,d3
DatReg:
 andi.w  #$0fff,d4     ;get the control register
 cmpi.w  #$0,d4        ;is it SFC?
 bne     nextt1
 movea.l MySFC(pc),a1     ;put its contents in a1
 bra     Here1
nextt1:
 cmpi.w  #$0001,d4     ;is it DFC?
 bne     nextt2
 movea.l MyDFC(pc),a1    ;put it in a1
 bra     Here1
nextt2:
 cmpi.w  #$0800,d4     ;is it USP?
 bne     nextt3
 move    USP,a1        ;put it in a1
 bra     Here1
nextt3:
 cmpi.w  #$0002,d4     ;is it CACR?
 bne     nextt4
 movea.l MyCACR(pc),a1        ;put it in a1
 bra     Here1
nextt4:
 cmpi.w  #$0802,d4     ;is it CAAR?
 bne     nextt5
 movea.l MyCAAR(pc),a1        ;put it in a1
 bra     Here1
nextt5:
 cmpi.w  #$0803,d4     ;is it MSP?
 beq     ssp1
 cmpi.w  #$0804,d4    ;or ISP?
 bne     nextt6
ssp1:
 movea.l a7,a1
 adda.l  #70,a1       ;don't consider the pushed registers!
 bra     Here1
nextt6:
 cmpi.w  #$0801,d4    ;is it VBR ?
 beq     mvbr
 movem.l (a7)+,d0-d7/a0-a6
 adda.l  #4,a7
 movem.l d0-d7/a0-a6,-(a7)
 bra     illegale
mvbr:
 movea.l MyVBR(pc),a1    ; put it in a1
Here1:
 move.l  a1,0(a7,d3)   ;put in actual reg.putting in a7 has no effect
 move.l  66(a7),d4         ;get the address of the movec instruction
 add.l   #4,d4       ;add 4 so that execution begins with the next opcode
 move.l  d4,66(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 adda.l  #4,a7
 btst    #7,(a7)
 beq     NT200
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT200:
 rte

ToCR:
 move.w  2(a0),d3
 move.w  d3,d4
 andi.w  #$7000,d3
 lsr.w   #7,d3
 lsr.w   #5,d3
 mulu    #4,d3
 btst    #15,d4
 beq     DatReg2
 add.l   #32,d3
DatReg2:
 move.l  0(a7,d3),d1    ;get the value in d1
 lea     saved1(pc),a3
 move.l  d1,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 adda.l  #4,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.l  saved1(pc),d1
 move.l  62(a7),a0
 move.w  2(a0),d4
 andi.w  #$0fff,d4
 cmpi.w  #$0,d4
 bne     nextr1
 lea     MySFC(pc),a3
 andi.l  #$7,d1
 move.l  d1,(a3)
 bra     here2
nextr1:
 cmpi.w  #$0001,d4
 bne     nextr2
 lea     MyDFC(pc),a3
 andi.l  #$7,d1
 move.l  d1,(a3)
 bra     here2
nextr2:
 cmpi.w  #$0800,d4
 bne     nextr3
 movea.l d1,a2
 move    a2,USP
nextr3:
 cmpi.w  #$0002,d4
 bne     nextr4
 lea     MyCACR(pc),a3
 andi.l  #$f,d1
 move.l  d1,(a3)
 bra     here2
nextr4:
 cmpi.w  #$0802,d4
 bne     nextr5
 lea     MyCAAR(pc),a3
 move.l  d1,(a3)
 bra     here2
nextr5:
 cmpi.w  #$0803,d4
 beq     ssp2
 cmpi.w  #$0804,d4
 bne     nextr6
ssp2:
 lea     saved1(pc),a3
 move.l  d1,(a3)
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 lea     savea1(pc),a7
 move.l  a1,(a7)
 move.l  saved1(pc),a1
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 move.l  2(a7),-(a1)   ;return address
 move.w  (a7),-(a1)   ;status register
 move.l  a1,a7
 move.l  savea1(pc),a1
 movem.l d0-d7/a0-a6,-(a7)
 bra     here2
nextr6:
 cmpi.w  #$0801,d4
 bne     illegale
mvbr2:
 lea     MyVBR(pc),a3
 move.l  d1,(a3)
 bne     NotZero   ;if new address not zero then copy the 1024 bytes at the
 movea.l #0,a5         ;VBR address to the locations 0-1024
 movea.l NewVec(pc),a4
 move.l  #511,d4
copy3:
 move.w  (a4)+,(a5)+
 dbf     d4,copy3
 bra     here2
NotZero:
 movea.l MyVBR(pc),a4 ;if the VBR holds 0,then copy the original vectors in
 movea.l #0,a5      ;in its place
 move.l  #511,d4
copy4:
 move.w  (a4)+,(a5)+
 dbf     d4,copy4
here2:
 move.l  62(a7),d4
 add.l   #4,d4
 move.l  d4,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT210
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT210:
 rte


M_O_V_E_S:       ;Syntax:moves Rn,<ea> or moves <ea>,Rn
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),-(a7)
 movem.l d0-d7/a0-a6,-(a7)
 move.l  66(a7),a0
 move.w  2(a0),d3
 btst    #11,d3
 beq     ea2Rn
 lea     MovSREf(pc),a3
 andi.w  #$f03f,(a3)
 move.w  (a0),d4
 andi.w  #$003f,d4
 move.w  d4,d3
 andi.w  #$7,d3
 andi.w  #$38,d4
 lsl.w   #7,d3
 lsl.w   #2,d3
 lsl.w   #3,d4
 or.w    d3,d4
 or.w    d4,(a3)
 move.w  (a0),d4
 andi.w  #$003f,d4
 lea     NumAdd(pc),a4
 move.l  #$4e714e71,4(a3)
 move.l  #4,(a4)
 cmpi.w  #$38,d4
 bne     MVS10
 move.w  4(a0),4(a3)
 move.l  #6,(a4)
 bra     EffFound
MVS10:
 cmpi.w  #$39,d4
 bne     MVS20
 move.l  4(a0),4(a3)
 move.l  #8,(a4)
 bra     EffFound
MVS20:
 andi.w  #$38,d4
 cmpi.w  #$28,d4
 bne     MVS30
 move.w  4(a0),4(a3)
 move.l  #6,(a4)
 bra     EffFound
MVS30:
 cmpi.w  #$30,d4    ;index
 bne     MVS40
 move.w  4(a0),d3
 btst    #8,d3
 beq     legalMoves1
 movem.l (a7)+,d0-d7/a0-a6
 adda.l  #4,a7
 movem.l d0-d7/a0-a6,-(a7)
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     mvs11(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     NEWADDRESSING   ;it is a 68020 addressing mode
mvs11:
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),-(a7)
 movem.l d0-d7/a0-a6,-(a7)
 lea     MovSREf(pc),a3
 andi.w  #$ffc0,(a3)
 ori.w   #$0039,(a3)
 move.l  RetAddr(pc),2(a3)
 move.l  62(a7),a0
 bra     EffFound
legalMoves1:
 movem.l (a7)+,d0-d7/a0-a6
 adda.l  #4,a7
 movem.l d0-d7/a0-a6,-(a7)
 lea     NumAdd(pc),a4
 move.l  #6,(a4)
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     mvs21(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     BriefFormat   ;it is a 68020 addressing mode
mvs21:
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),-(a7)
 movem.l d0-d7/a0-a6,-(a7)
 lea     MovSREf(pc),a3
 andi.w  #$ffc0,(a3)
 ori.w   #$0039,(a3)
 move.l  RetAddr(pc),2(a3)
 move.l  62(a7),a0
 bra     EffFound
MVS40:
 cmpi.w  #$28,d4
 bne     EffFound
 movem.l (a7)+,d0-d7/a0-a6
 adda.l  #4,a7
 movem.l d0-d7/a0-a6,-(a7)
 bra     illegale
EffFound:
 move.w  (a0),d3    ;first word in d3
 andi.w  #$00c0,d3     ;determine operation size (.B, .W or .L)
 lsr.w   #6,d3
 cmpi.w  #0,d3
 bne     wl
 move.w  #$1000,d2
 move.l  #24,d7    ;byte operation, so shift mem. loc. SaveVal, 24 bits
 bra     size1
wl:               ;Word or Long
 cmpi.w  #1,d3
 bne     l
 move.w  #$3000,d2
 move.l  #16,d7
 bra     size1
l:                 ;Long
 move.w  #$2000,d2
 move.l  #0,d7
size1:
 andi.w  #$cfff,(a3)
 or.w    d2,(a3)      ;set the size bits in the opcode
 move.w  2(a0),d3    ;second word in d3
 move.w  d3,d4
 andi.w  #$7000,d3
 lsr.w   #7,d3
 lsr.w   #5,d3
 mulu    #4,d3
 btst    #15,d4
 beq     DR
 add.l   #32,d3
DR:
 move.l  0(a7,d3),d1   ;d1 has the Rn contents
 tst.l   d7
 beq     NoSh
 lsl.l   d7,d1
NoSh:
 lea     SaveVal(pc),a3
 move.l  d1,(a3)
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 add.l   #4,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),a7
MovSREf:
 move.l  SaveVal(pc),d0   ;d0 will be replaced with the <ea>
 nop
 nop
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.l  62(a7),d4
 add.l   NumAdd(pc),d4
 move.l  d4,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT220
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT220:
 rte


ea2Rn:
 lea     MovSEfR(pc),a3
 andi.w  #$ffc0,(a3)
 movea.l 66(a7),a0
 move.w  (a0),d4
 andi.w  #$003f,d4
 or.w    d4,(a3)
 lea     NumAdd(pc),a4
 move.l  #$4e714e71,2(a3)
 move.l  #4,(a4)
 cmpi.w  #$38,d4
 bne     MVS100
 move.w  4(a0),2(a3)
 move.l  #6,(a4)
 bra     EffFound2
MVS100:
 cmpi.w  #$39,d4
 bne     MVS200
 move.l  4(a0),2(a3)
 move.l  #8,(a4)
 bra     EffFound2
MVS200:
 andi.w  #$38,d4
 cmpi.w  #$28,d4
 bne     MVS300
 move.w  4(a0),2(a3)
 move.l  #6,(a4)
 bra     EffFound2
MVS300:
 cmpi.w  #$30,d4   ;index
 bne     MVS400
 move.w  4(a0),d3
 btst    #8,d3
 beq     legalMoves2
 movem.l (a7)+,d0-d7/a0-a6
 adda.l  #4,a7
 movem.l d0-d7/a0-a6,-(a7)
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     ther11(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     NEWADDRESSING   ;it is a 68020 addressing mode
ther11:
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),-(a7)
 movem.l d0-d7/a0-a6,-(a7)
 move.l  66(a7),a0
 lea     MovSEfR(pc),a3
 andi.w  #$ffc0,(a3)
 ori.w   #$0039,(a3)
 move.l  RetAddr(pc),2(a3)
 bra     EffFound2
legalMoves2:
 movem.l (a7)+,d0-d7/a0-a6
 adda.l  #4,a7
 movem.l d0-d7/a0-a6,-(a7)
 lea     NumAdd(pc),a4
 move.l  #6,(a4)
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     ther21(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     BriefFormat   ;it is a 68020 addressing mode
ther21:
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),-(a7)
 movem.l d0-d7/a0-a6,-(a7)
 move.l  66(a7),a0
 lea     MovSEfR(pc),a3
 andi.w  #$ffc0,(a3)
 ori.w   #$0039,(a3)
 move.l  RetAddr(pc),2(a3)
 bra     EffFound2
MVS400:
 cmpi.w  #$28,d4
 bne     EffFound2
 movem.l (a7)+,d0-d7/a0-a6
 adda.l  #4,a7
 movem.l d0-d7/a0-a6,-(a7)
 bra     illegale
EffFound2:
 move.w  (a0),d3    ;first word in d3
 andi.w  #$00c0,d3     ;determine operation size (.B, .W or .L)
 lsr.w   #6,d3
 cmpi.w  #0,d3
 bne     wl2
 move.w  #$1000,d2
 bra     size2
wl2:               ;Word or Long
 cmpi.w  #1,d3
 bne     l2
 move.w  #$3000,d2
 bra     size2
l2:                 ;Long
 move.w  #$2000,d2
size2:
 andi.w  #$cfff,(a3)
 or.w    d2,(a3)      ;set the size bits in the opcode
 move.w  2(a0),d3
 moveq   #0,d4
 btst    #15,d3
 beq     DR2
 move.w  #$0040,d4
DR2:
 andi.w  #$7000,d3
 lsr.w   #3,d3
 or.w    d3,d4
 andi.w  #$f03f,(a3)
 or.w    d4,(a3)
 lea     SaveA7(pc),a4
 move.l  A7,(a4)
 add.l   #4,(a4)
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),a7
MovSEfR:
 move.l  d1,d0         ;d1 will be changed to <ea>.
 nop                   ;putting in a7 has no effect
 nop
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.l  62(a7),d4
 add.l   NumAdd(pc),d4
 move.l  d4,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT230
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT230:
 rte


M_O_V_E_F_C_C_R:     ;Syntax: move CCR,<ea> = move CCR,d0 + move d0,<ea>
 move.l  62(a7),a0
 move.w  (a0),d1
 move.w  d1,d2
 andi.w  #$7,d1
 andi.w  #$38,d2
 lsl.w   #2,d1
 lsl.w   #7,d1
 lsl.w   #3,d2
 or.w    d2,d1
 lea     From(pc),a3
 lea     NumAdd(pc),a4
 move.l  #$4e714e71,4(a3)
 andi.w  #$f03f,(a3)
 or.w    d1,(a3)
 lsr.w   #6,d2
 cmpi.w  #$5,d2
 bne     tst2
 move.l  #4,(a4)       ;it is address reg. indirect with displ.
 move.w  2(a0),4(a3)
 bra     Here7
tst2:
 cmpi.w  #6,d2
 bne     tst3
 move.w  2(a0),d3    ;index
 btst    #8,d3
 beq     ccr12
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     ccr11(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #2,(a3)
 bra     NEWADDRESSING   ;it is a 68020 addressing mode
ccr11:
 move.w  60(a7),d0
 andi.l  #$ff,d0
 move.l  RetAddr(pc),a1
 move.w  d0,(a1)
 bra     EndMoveCCR
ccr12:
 lea     NumAdd(pc),a4
 move.l  #4,(a4)
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     ccr21(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #2,(a3)
 bra     BriefFormat    ;it is a 68020 addressing mode
ccr21:
 move.w  60(a7),d0
 andi.l  #$ff,d0
 move.l  RetAddr(pc),a1
 move.w  d0,(a1)
 bra     EndMoveCCR
tst3:
 lsr.w   #6,d1
 cmpi.w  #$7,d1
 bne     tst4
 move.l  #4,(a4)
 move.w  2(a0),4(a3)
 bra     Here7
tst4:
 cmpi.w   #$f,d1
 bne      tst5
 move.l   #6,(a4)
 move.l   2(a0),4(a3)
 bra      Here7
tst5:
 move.l   #2,(a4)
Here7:
 lea      SaveVal(pc),a4
 move.w   60(a7),d0
 andi.w   #$00ff,d0
 move.w   d0,(a4)
 lea      SaveA7(pc),a3
 move.l   a7,(a3)
 movem.l  (a7)+,d0-d7/a0-a6
 move.l   StackP(pc),a7
From:
 move.w  SaveVal(pc),d0
 nop
 nop
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0-d7/a0-a6,-(a7)
EndMoveCCR:
 move.l  62(a7),d4
 add.l   NumAdd(pc),d4
 move.l  d4,62(a7)
 move.l  ExecBase,a6
 jsr     Permit(a6)
 movem.l (a7)+,d0-d7/a0-a6
 btst    #7,(a7)
 beq     NT240
 move.l  $24,-(a7)
 suba.l  #2,a7
 move.w  6(a7),(a7)
 bclr    #7,(a7)
 bset    #5,(a7)
NT240:
 rte




BFCommon:               ;all the bit field instructions call this routine
 move.l  62(a7),a0      ;when they start executing.It gets the starting
 move.w  (a0),d1        ;address of the operand and also width and offset
 move.w  d1,d2          ;of the intended bitfield.if the operand is in a
 andi.w  #$3f,d1         ;data register, it is copied to a memory location
 lea     NumAdd(pc),a4   ;and it't address is passed. a flag is set to show
 lea     LEABF(pc),a3     ;this situation.
 move.l  #$4e714e71,2(a3)
 move.l  #4,(a4)
 andi.w  #$ffc0,(a3)
 or.w    d1,(a3)
 andi.w  #$38,d2
 bne     AddressInvolved
 move.w  d1,d2
 mulu    #4,d2
 move.l  0(a7,d2),d0
 lea     Val1(pc),a3
 move.l  d0,(a3)
 lea     Val1(pc),a4
 lea     SaveVal(pc),a3
 move.l  a4,(a3)
 moveq   #1,d7
 bra     bfEADone
AddressInvolved:
 cmpi.w  #$38,d1   ;imm. short
 bne     bflab10
 move.w  4(a0),2(a3)
 move.l  #6,(a4)
 bra     bfDone
bflab10:
 cmpi.w  #$39,d1    ;imm. long
 bne     bflab20
 move.l  4(a0),2(a3)
 move.l  #8,(a4)
 bra     bfDone
bflab20:
 cmpi.w  #$3a,d1     ;pc+displ
 beq     pcaddress
 cmpi.w  #$3b,d1
 bne     bflab30
 move.l  62(a7),a0
 move.w  4(a0),d3
 btst    #8,d3
 beq     pcaddress
 lea     BDFlag(pc),a3
 move.l  #1,(a3)
 lea     bf13(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     NEWADDRESSING   ;it is a 68020 addressing mode
bf13:
 lea     SaveVal(pc),a3
 move.l  RetAddr(pc),(a3)
 moveq   #0,d7
 bra     bfEADone
pcaddress:
 lea     NumAdd(pc),a4
 move.l  #6,(a4)
 lea     BDFlag(pc),a3
 move.l  #1,(a3)
 lea     bf23(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     BriefFormat       ;it is a 68020 addressing mode
bf23:
 lea     SaveVal(pc),a3
 move.l  RetAddr(pc),(a3)
 moveq   #0,d7
 bra     bfEADone
bflab30:
 andi.w  #$38,d1
 cmpi.w  #$28,d1    ;displ.
 bne     bflab40
 move.w  4(a0),2(a0)
 move.l  #6,(a4)
 bra     bfDone
bflab40:
 cmpi.w  #$30,d1   ;index
 bne     bfDone
 move.w  4(a0),d3
 btst    #8,d3
 beq     bf12
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     bf11(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     NEWADDRESSING   ;it is a 68020 addressing mode
bf11:
 lea     SaveVal(pc),a3
 move.l  RetAddr(pc),(a3)
 moveq   #0,d7
 bra     bfEADone
bf12:
 lea     NumAdd(pc),a4
 move.l  #6,(a4)
 lea     BDFlag(pc),a3
 move.l  #0,(a3)
 lea     bf21(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  #4,(a3)
 bra     BriefFormat     ;it is a 68020 addressing mode
bf21:
 lea     SaveVal(pc),a3
 move.l  RetAddr(pc),(a3)
 moveq   #0,d7
 bra     bfEADone
bfDone:
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 lea     savea1(pc),a7
 move.l  a1,(a7)
 move.l  StackP(pc),a7
LEABF:
 lea     (a1),a1     ;(a1) will be changed to <ea>
 nop
 nop
 lea      SaveVal(pc),a7
 move.l   a1,(a7)
 move.l   savea1(pc),a1
 move.l   SaveA7(pc),a7
 adda.l   #60,a7
 movem.l  d0-d7/a0-a6,-(a7)
 moveq    #0,d7
bfEADone:
 move.l   62(a7),a0
 move.w   2(a0),d1
 move.w   d1,d3
 btst     #11,d1
 beq      OffsetImm
 lsr.w    #6,d1
 andi.w   #$7,d1
 mulu     #4,d1
 move.l   0(a7,d1),d0  ;d0 has the offset
 lea      BFOffset(pc),a3
 move.l   d0,(a3)
 divs     #32768,d0
 move.w   d0,d1
 andi.l   #$ffff,d1
 muls     #4096,d1
 lsr.l    #8,d0
 lsr.l    #8,d0
 divs     #8,d0
 move.w   d0,d2
 andi.l   #$ffff,d2
 add.l    d2,d1      ;d1 has the number of bytes from the <ea>
 lsr.l    #8,d0
 lsr.l    #8,d0
 ext.l    d0
 tst.l    d0
 bpl      bfNoChange
 move.l   #8,d4
 add.l    d0,d4
 move.l   d4,d0
 sub.l    #1,d1
bfNoChange:
 move.l   d0,d2      ;d2 has the final offset
 bra      OffsetDone
OffsetImm:
 lsr.w    #6,d1
 andi.l   #$1f,d1
 lea      BFOffset(pc),a3
 move.l   d1,(a3)
 divu     #8,d1
 move.l   d1,d2
 andi.l   #$ffff,d1
 swap     d2
 andi.l   #$ffff,d2
OffsetDone:
 move.w   d3,d4
 btst     #5,d4
 beq      WidthImm
 andi.w   #$7,d4
 mulu     #4,d4
 move.l   0(a7,d4),d0
 andi.l   #$1f,d0       ;modulo 32
 bne      mod321
 move.l   #32,d0
mod321:
 move.l   d0,d4        ;d4 has the width
 bra      WidthDone
WidthImm:
 andi.l   #$1f,d4
 bne      WidthDone
 move.l   #32,d4
WidthDone:
 move.l   SaveVal(pc),a1
 adda.l   d1,a1 
             ;a1 points to the first byte containing the bit to manipulate
 move.l   Val3(pc),a3
 jmp      (a3)




PCRelative:                   ;<ea> = (d16,pc)
 move.l  62(a7),a0
 lea     PCRMove(pc),a3
 adda.l  d1,a0           ;a0 holds the pc that the assembler assumed at the
 move.w  (a0),2(a3)         ;time of assembly
 lea     SaveA7(pc),a3
 move.l  a7,(a3)
 lea     savea0(pc),a3
 move.l  a0,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 lea     savea1(pc),a7
 move.l  a1,(a7)
 lea     saved0(pc),a7
 move.l  d0,(a7)
 move.l  savea0(pc),a1
 move.l  StackP(pc),a7
PCRMove:
 move.l  0(a1),d0
 nop
 lea     SaveVal(pc),a7
 move.l  d0,(a7)
 move.l  saved0(pc),d0
 move.l  savea1(pc),a1
 move.l  SaveA7(pc),a7
 adda.l  #60,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.l  SaveVal(pc),d3
 move.l  Val3(pc),a3     ;ret addr
 jmp     (a3)



PCIndex:
 move.l  62(a7),a0
 adda.l  d1,a0
 move.w  (a0),d3
 btst    #8,d3
 beq     pcindexshort
 lea     BDFlag(pc),a3
 move.l  #1,(a3)
 lea     pc13(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  d1,(a3)
 bra     NEWADDRESSING   ;it is a 68020 addressing mode
pc13:
 move.l  RetAddr(pc),a1
 move.l  (a1),d3
 move.l  Val3(pc),a3
 jmp     (a3)
pcindexshort:
 lea     BDFlag(pc),a3
 move.l  #1,(a3)
 lea     pc23(pc),a3
 lea     Val2(pc),a4
 move.l  a3,(a4)
 lea     Offset(pc),a3
 move.l  d1,(a3)
 bra     BriefFormat   ;it is a 68020 addressing mode
pc23:
 move.l  RetAddr(pc),a1
 move.l  (a1),d3
 move.l  Val3(pc),a3
 jmp     (a3)




BriefFormat:                   ;<ea> = (d8,An,Xn*scale)
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),-(a7)
 movem.l d0-d7/a0-a6,-(a7)
 move.l  66(a7),a0
 move.l  Offset(pc),d0
 move.l  BDFlag(pc),d1
 beq     BaseAddressingBrief
 adda.l  d0,a0
 move.l  a0,d6
 bra     BasePCDoneBrief
BaseAddressingBrief:
 move.w  (a0),d1
 andi.w  #$7,d1
 mulu    #4,d1
 add.l   #32,d1
 move.l  0(a7,d1),d6    ;d6 has base register
 adda.l  d0,a0
BasePCDoneBrief:
 move.w  (a0),d1
 move.w  d1,d2
 andi.w  #$7000,d1
 lsr.w   #7,d1
 lsr.w   #5,d1
 mulu    #4,d1
 btst    #15,d2
 beq     BriefData
 add.l   #32,d1
BriefData:
 move.l  0(a7,d1),d4   ;d4 has index register
 btst    #11,d2
 bne     BriefLong
 ext.l   d4
BriefLong:           ;now multiply the index
 move.w  d2,d1
 andi.w  #$0600,d1
 lsr.w   #7,d1
 lsr.w   #2,d1
 cmpi.w  #0,d1
 beq     BriefIndexDone
 cmpi.w  #1,d1
 bne     Mul4
 mulu    #2,d4
 bra     BriefIndexDone
Mul4:
 cmpi.w  #2,d1
 bne     Mul8
 mulu    #4,d4
 bra     BriefIndexDone
Mul8:
 mulu    #8,d4
BriefIndexDone:
 ext.w   d2       ;d2 has displacement
 ext.l   d2
 add.l   d2,d4     ;add them all
 add.l   d4,d6
 lea     RetAddr(pc),a3
 move.l  d6,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 adda.l  #4,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.l  Val2(pc),a3
 jmp     (a3)

   
NEWADDRESSING:
 movem.l (a7)+,d0-d7/a0-a6
 move.l  StackP(pc),-(a7)       ;insert a7
 movem.l d0-d7/a0-a6,-(a7)
 move.l  66(a7),a0
 move.l  Offset(pc),d0
 move.l  BDFlag(pc),d1
 beq     BaseAddressing
 adda.l  d0,a0
 move.l  a0,d6
 bra     BasePCDone
BaseAddressing:
 move.w  (a0),d1
 andi.w  #$7,d1
 mulu    #4,d1
 add.l   #32,d1
 move.l  0(a7,d1),d6   ;d6 has base register
 adda.l  d0,a0
BasePCDone:
 move.w  (a0),d1
 move.w  d1,d2
 btst    #7,d1
 beq     BaseDone
 moveq   #0,d6
BaseDone:
 moveq   #0,d5    ;d5 has index
 btst    #6,d1
 bne     IndexDone
 andi.w  #$7000,d1
 lsr.w   #7,d1
 lsr.w   #5,d1
 mulu    #4,d1
 btst    #15,d2         ;address or data register?
 beq     NAAddr
 add.l   #32,d1
NAAddr:
 move.l  0(a7,d1),d5
 btst    #11,d2
 bne     NALong
 ext.l   d5
NALong:
 move.l  d2,d1        ;now multipy index
 andi.w  #$0600,d1
 lsr.w   #7,d1
 lsr.w   #2,d1
 cmpi.w  #0,d1
 beq     IndexDone
 cmpi.w  #1,d1
 bne     Scale4
 mulu    #2,d5
 bra     IndexDone
Scale4:
 cmpi.w  #2,d1
 bne     Scale8
 mulu    #4,d5
 bra     IndexDone
Scale8:
 mulu    #8,d5

IndexDone:
 move.w  d2,d1
 andi.w  #$0030,d1
 lsr.w   #4,d1
 cmpi.w  #1,d1
 beq     BaseDispDone
 cmpi.w  #2,d1
 bne     LongDisp
 move.w  2(a0),d4     ;d4 has base displacement
 ext.l   d4
 add.l   #4,d0
 bra     BaseDispDone
LongDisp:
 move.l  2(a0),d4
 add.l   #6,d0

BaseDispDone:
 move.l  66(a7),a0
 add.l   d0,a0
 moveq   #0,d3     ;d3 has outer displacement
 move.w  d2,d1
 andi.w  #$7,d1
 btst    #6,d2
 bne     NoPrePost      ;it is not preindex or post index
 cmpi.w  #0,d1
 beq     AddrDone
 cmpi.w  #1,d1
 beq     CalPre
Case2:
 cmpi.w  #2,d1
 bne     Case3
 move.w  (a0),d3
 ext.l   d3
 add.l   #2,d0
 bra     CalPre
Case3:
 cmpi.w  #3,d1
 bne     Case4
 move.l  (a0),d3
 add.l   #4,d0

CalPre:              ;calculate pre index
 add.l   d4,d6
 add.l   d5,d6
 moveq   #0,d4
 moveq   #0,d5
 movea.l d6,a3
 move.l  (a3),d6
 add.l   d3,d6
 moveq   #0,d3
 bra     AddrDone     ;pre indexed address calculated

Case4:
 cmpi.w  #5,d1
 beq     CalPost
 cmpi.w  #6,d1
 bne     Case5
 move.w  (a0),d3
 ext.l   d3
 add.l   #2,d0
 bra     CalPost
Case5:
 move.l  (a0),d3
 add.l   #4,d0

CalPost:            ;calculate post index
 add.l   d4,d6
 move.l  d6,a3
 move.l  (a3),d6
 add.l   d5,d6
 moveq   #0,d4
 moveq   #0,d5
 add.l   d3,d6
 moveq   #0,d3
 bra     AddrDone   ;post indexed address calculated

NoPrePost:
 cmpi.w  #0,d1
 beq     AddrDone
 cmpi.w  #1,d1
 beq     AddrDone
 cmpi.w  #2,d1
 bne     Case6
 move.w  (a0),d3
 ext.l   d3
 add.l   #2,d0
 bra     AddrDone
Case6:
 move.l  (a0),d3
 add.l   #4,d0
AddrDone:
 add.l   d4,d5
 add.l   d5,d6
 add.l   d3,d6
 lea     RetAddr(pc),a3  ;this is the effevctive address.
 move.l  d6,(a3)
 lea     NumAdd(pc),a3    ;length of the instruction.
 move.l  d0,(a3)
 movem.l (a7)+,d0-d7/a0-a6
 adda.l  #4,a7
 movem.l d0-d7/a0-a6,-(a7)
 move.l  Val2(pc),a3
 jmp     (a3)



OldIllegalExcept:  dc.l 0
NewIllegalExcept:  dc.l 0
NewVec:            dc.l 0
Except:            dc.l 0
MyVBR:             dc.l 0
MySFC:             dc.l 0
MyDFC:             dc.l 0
MyCAAR:            dc.l 0
MyCACR:            dc.l 0
MySR:              dc.w 0
MySP:              dc.l 0
SaveVal:           dc.l 0
RetAddr:           dc.l 0
savea0:            dc.l 0
savea1:            dc.l 0
saved1:            dc.l 0
saved0:            dc.l 0
savereg:           dc.l 0
SaveA7:            dc.l 0
NumAdd:            dc.l 0   ;NumAdd holds the instruction length
StackP:            dc.l 0
Val1:              dc.l 0
Val2:              dc.l 0
Val3:              dc.l 0
WhichOne:          dc.l 0
Flag:              dc.l 0
Offset:            dc.l 0
BDFlag:            dc.l 0
BFOffset           dc.l 0


EndIllegal:
 end

