**** A Privilige Violation handler for the 68010 CPU **** **** To use for traping those MOVE SR,ea instructions I went to use *** **** Decigel but found it would not survive a reboot. I needed this *** **** for those copy protected programs that run from boot. The idea *** **** for the Violation code is from Scott Turner's Decigel program. I * **** added the code that will allow it to survive a warm boot. **** **** To remove the handler press the left mouse button while **** **** rebooting. The screen will flash red to let you know the code **** **** has gone. It allocates a port so that if you try to install **** **** it again it will tell you it is already there. **** **** The other way to get rid of it is to type Decigel -q **** **** I am placing this into the public domain for use by anyone **** **** John Veldthuis **** 21 Ngatai Street **** Manaia, Taranaki **** New Zealand **** Revision 1 3 April 1988 **** Added code to remove handler from Cli **** Revision 2 20 September 1988 **** Changed from using the CoolCapture Vector to using RomTAGS **** This is the proper way to survive a reboot. **** Took awhile to work out how to use them though **** Will work with other RomTAGS **** Revision 3 23 September 1988 **** Changed memory allocation tactics when I found my program **** got wiped out by an ADDMEM C00000 CFFFFF command _LVOOpenLibrary EQU -$228 _LVOCloseLibrary EQU -$19E _LVOFindPort EQU -$186 _LVOAddPort EQU -$162 _LVORemovePort EQU -$168 _LVOSumKickData EQU -$264 _LVOAllocMem EQU -$C6 _LVOAllocAbs EQU -$CC _LVOFreeMem EQU -$D2 _LVOOutput EQU -$3C _LVOWrite EQU -$30 Start: movem.l d0/a0,-(sp) move.l 4,a6 lea DosName(pc),a1 moveq.l #0,d0 jsr _LVOOpenLibrary(a6) ;open dos library tst.l d0 bne.s 1$ moveq.l #20,d0 ;error if no Dos rts 1$ lea DosBase(pc),a5 move.l d0,(a5) move.l d0,a6 jsr _LVOOutput(a6) move.l d0,4(a5) movem.l (sp)+,d0/a0 ;restore command line move.b #0,0(a0,d0.w) ;zero end of line move.l 4,a6 Loop move.b (a0)+,d0 tst.b d0 beq NoQuit ;if no command install handler cmp.b #'-',d0 bne.s Loop ;look for -q move.b (a0),d0 ;should now be a 'q' cmp.b #'q',d0 bne.s Loop lea PortName(pc),a1 jsr _LVOFindPort(a6) tst.l d0 bne.s PortHere lea NoHandler(pc),a1 move.l a1,d2 move.l 4(a5),d1 move.l #23,d3 move.l (a5),a6 bra Q1 PortHere move.l d0,a4 ;a4 = pointer to port move.l -4(a4),d0 ;d0 = old exception handler lea $20,a0 move.l d0,(a0) ;put back old exception handler move.l a4,a1 jsr _LVORemovePort(a6) ;remove port move.w #$4000,$DFF09A ;disable interupts addq.b #1,$126(a6) ;1 to disable count move.l $2A(a4),$226(a6) ;retsore old pointer beq.s 1$ ;was there a pointer bclr #7,$226(a6) ;yes, restore extension bit 1$ jsr _LVOSumKickData(a6) move.l d0,$22A(a6) ;restore new checksum subq.b #1,$126(a6) ;one off disable count bge.s 2$ move.w #-$4000,$DFF09A ;restore interupts 2$ lea -(Port1-Install)(a4),a1 ;Start of memory move.l #EndProg-StartProg,d0 ;length of Memory jsr _LVOFreeMem(a6) ;free the memory lea Remove(pc),a0 move.l a0,d2 move.l 4(a5),d1 move.l #17,d3 move.l (a5),a6 bra.s Q1 NoQuit move.l 4,a6 lea PortName(pc),a1 jsr _LVOFindPort(a6) ;find port tst.l d0 beq.s 10$ ;if no port then go install handler move.l (a5),a6 ;otherwise print that handler installed move.l 4(a5),d1 lea Mess3(pc),a0 move.l a0,d2 move.l #27,d3 bra.s Q1 10$ move.l #EndProg-StartProg,d0 ;length of memory we need move.l #$10003,d1 ;put it in Chip Memory + Clear Mem jsr _LVOAllocMem(a6) tst.l d0 beq.s MemErr bsr MoveProg ;move prog up into memory above normal move.l (a5),a6 lea Mess2(pc),a0 move.l a0,d2 move.l 4(a5),d1 move.l #29,d3 Q1 jsr _LVOWrite(a6) ;print installed message Quit move.l a6,a1 move.l 4,a6 jsr _LVOCloseLibrary(a6) ;close dos.library moveq.l #0,d0 rts MemErr move.l (a5),a6 lea MemMess(pc),a0 move.l a0,d2 move.l 4(a5),d1 move.l #30,d3 bra.s Q1 ;print Message and exit MoveProg: move.l d0,a1 ;d0 holds our memory Allocation move.l d0,a3 lea StartProg(pc),a0 lea EndProg(pc),a2 1$ move.b (a0)+,(a1)+ ;move memory up cmp.l a0,a2 bne.s 1$ jmp (a3) ;jump to install routine StartProg: Install bsr.s Sub1 bsr Sub2 rts Sub1 move.w #$4000,$DFF09A ;Interupts off addq.b #1,$126(a6) ;add one to disable count lea Block(pc),a0 lea 8(a0),a1 move.l a1,(a0) ;pointer to our RomTAG move.l $226(a6),4(a0) ;get old KickTagPtr beq.s 1$ ;Nothing there bset #7,4(a0) ;otherwise set bit to tell exec 1$ move.l a0,$226(a6) ;put our KickTagPtr in move.w #$4AFC,(a1) ;magic number move.l a1,2(a1) ;pointer to base of RomTAG lea $1a(a1),a2 move.l a2,6(a1) ;End of RomTAG move.b #1,$a(a1) ;Flags (run program on reboot) move.b #$21,$b(a1) ;version of the program move.b #0,$c(a1) ;Type of module move.b #-$a,$d(a1) ;pri of this program move.l #0,$e(a1) ;pointer to node name move.l #0,$12(a1) ;pointer to ID string lea Init(pc),a3 move.l a3,$16(a1) ;pointer to Init code (called at boot) jsr _LVOSumKickData(a6) ;redo checksum move.l d0,$22a(a6) ;put it into ExecBase subq.b #1,$126(a6) ;one off disable count bge.s 2$ ;are we still disabled move.w #-$4000,$DFF09A ;enable interupts 2$ rts Sub2: lea Port1(pc),a0 ;Message port address moveq.l #0,d0 move.l d0,(a0) ;zero successor move.l d0,4(a0) ;zero predisessor move.w #$0400,8(a0) ;type = messageport, pri = 0 move.w d0,14(a0) ;zero list header move.l d0,16(a0) ;zero list tail lea PortName(pc),a1 ;name of this port move.l a1,10(a0) ;put it in structure lea Port1(pc),a1 ;get port address jsr _LVOAddPort(a6) ;addport to let every know we are here lea OpCode+2(pc),a0 ;get end of our patch code lea $20,a1 ;get address of priv violation move.l (a1),(A0) ; Patch old vector into our handler lea PivVi(pc),a2 move.l A2,(a1) ; Patch us into the vector rts ; Back to AmigaDOS, no error Init movem.l d0-d7/a0-a6,-(sp) ;RomTag calls Here move.l 4,a6 btst #6,$BFE001 ;Test left mouse button bne.s 2$ 11$ lea $DFF000,a5 ;custom chip base move.w #$F00,$180(a5) ;move red into color 0 moveq #$64,d0 ;delay loop 4$ cmpi.b #0,6(a5) ;flash screen to indicate bne.s 4$ ;handler removed 5$ cmpi.b #0,6(a5) bne.s 5$ dbf d0,4$ ;delay for a bit move.w #$00D,$180(a5) ;put screen back to blue move.w #$4000,$9A(a5) ;disable interupts addq.b #1,$126(a6) ;1 to disable count lea Tag2(pc),a0 ;get old TagPtr move.l (a0),$226(a6) ;restore pointer beq.s 10$ bclr #7,$226(a6) ;reset continuation bit 10$ jsr _LVOSumKickData(a6) move.l d0,$22A(a6) ;put new checksum in subq.b #1,$126(a6) ;1 from disable count bge.s 6$ move.w #-$4000,$9A(a5) ;enable interupts bra.s 6$ ;return to kickstart routine 2$ lea Install(pc),a1 ;start of our program move.l #EndProg-StartProg,d0 ;number of byte to allocate jsr _LVOAllocAbs(a6) ;alloc memory tst.l d0 beq.s 11$ ;dont install it if no memory bsr Sub2 ;addport and reset pointer to routine 6$ movem.l (sp)+,d0-d7/a0-a6 ;restore regs for kickstart rts PivVi movem.l D0/A0,-(SP) ; Save registers move.l 8+2(SP),A0 ; Pointer to opcode move.w (A0),D0 ; Pickup opcode andi.w #~%111111,D0 ; Mask out EA field cmpi.w #$40C0,D0 ; Is it a MOVE SR,ea? bne.s NotOne bset #1,(A0) ; Convert it to MOVE CCR,ea movem.l (SP)+,D0/A0 ; Restore regs rte ; Rerun new opcode NotOne movem.l (SP)+,D0/A0 ; Restore regs OpCode jmp $FC0000 ; To previous handler, patched by our install Port1 dc.l 0 ;This is a message port structure dc.l 0 dc.b 4 ;port type dc.b 0 dc.l 0 ;port name dc.b 0 dc.b 0 dc.l 0 ds.b 14 dc.l 0 Block dc.l 0 ;This is storage for the RomTag Tag2 dc.l 0 dc.l 0 dc.l 0 dc.l 0 dc.l 0 dc.l 0 dc.l 0 dc.l 0 dc.l 0 dc.l 0 dc.l 0 dc.l 0 DosBase dc.l 0 StdOut dc.l 0 DosName dc.b 'dos.library',0 Mess2 dc.b 'Privilige Handler Installed',10,0 Mess3 dc.b 'Handler already Installed',10,0 NoHandler dc.b 'Handler not Installed',10,0 MemMess dc.b 'Not Enough memory for Handler',10,0 Remove dc.b 'Handler Removed',10,0 PortName dc.b 'PrivHandler',0 NAME dc.b 'John Veldthuis',0 dc.b '21 Nagtai Steet',0 dc.b 'Manaia, Taranaki',0 dc.b 'New Zealand',0 EndProg: end