           Section  takeover,Code

           Opt      C-,O+,w-

Start:     lea      $dff000,a5          ; hardware base address
                                        ; needed to allow address register with
                                        ; offset to access hardware resisters

           Move.w   $1c(a5),OldInt      ; Save Old Interupts (INTENAR, save the
                                        ; contents of interupt enable bits read)

           Move.w   $02(a5),OldDma      ; Save Old DMA (DMACONR, save the
                                        ; contents of DMA control bits read)

           Move.w   #$7fff,$96(a5)      ; Clear DMA (turn all DMA channels
                                        ; etc. off)

           Move.w   #$7fff,$9a(a5)      ; Clear Interupts  (turn all Interupts
                                        ; off)

           Move.w   #$7fff,$9c(a5)      ; Clear Interupt Requests  (turn all
                                        ; interupt requests etc. off)
           Move.b   #$7f,$bfed01        ; kill timers

           Move.l   $6c.w,OldV3         ; save addess of the level 3 interupt
                                        ; routine

           Move.l   #my_level3,$6c.w    ; put new interupt level 3 server
                                        ; address in level 3 vector

           Move.l   #my_copper,$80(a5)  ; put address of my copperlist into
                                        ; COP1LCH

           Lea      Sprites+2,a0        ; This bit points all the sprites to
           Move.l   #Dumsprite,d0       ; a dummy sprite to prevent them from
           Move.w   #7,d1               ; leaving vertical lines all over!
Clrsprite:                              ;
           Swap     d0                  ; Get low word of address
           Move.w   d0,(a0)             ; put it in copper list
           Swap     d0                  ; Get high word
           Move.w   d0,4(a0)            ; put it in copper list
           Add.l    #8,a0               ; point to next entry in copper list
           Dbra     d1,Clrsprite        ; Do all 8 sprites

           Move.w   #$c010,$9a(a5)      ; Start interupts (turn on the level 3
                                        ; interupt)

           Move.w   #$83ef,$96(a5)      ; Start DMA ( all DMA except disk DMA)

           Move.w   #1,$88(a5)          ; Strobe for copper start (needed
                                        ; because graphics library is no longer
                                        ; automatically strobing for the copper
                                        ; to restart)


           ********************
           bsr      my_programme        ; this is where your program goes
           ********************



           ; this section now returns control back the OS, if you packing below
           ; $20000, your demo should not be able to quit and therefore should
           ; not do the following, if you wish to exit you must put the reset
           ; routine given later here (instead of the OS Restore). The demo will
           ; just Guru if you try to exit when it is absolute packed to low a
           ; address


           ; ****** OS restore ******

           lea      $dff000,a5          ; hardware base address

           Move.l   OldV3,$6c.w         ; restore old level 3 vector

           Lea      GfxLib,a1           ; Pointer to Library Text

           move.l   4.w,a6              ; Get the address of exec library

           jsr      -132(a6)            ; Forbid() - this is needed because
                                        ; the old level 3 interupt is now
                                        ; running again

           Move.l   4.w,a6              ; Exec base
           Moveq.l  #0,d0               ; Clear D0
           Jsr      -$228(a6)           ; OpenLibrary() - opening the gfx
                                        ; library gives you the addresses of
                                        ; the old copperlists
           cmp.l    #0,d0               ; if gfx library not open dont restore
           beq      no_gfx_lib          ; copper library, this can cause a
                                        ; crash if the demo is packed below
                                        ; $20000 and the reason you shouldn't
                                        ; exit

           Move.l   d0,a1               ; move the address of the gfx library
                                        ; into a1 for offset addressing

           Move.l   $26(a1),$80(a5)     ; restore address of CLI copper 1
           Move.l   $32(a1),$84(a5)     ; restore address of CLI copper 2
                                        ; from the gfx library.
no_gfx_lib:
           Move.w   OldInt,d0           ; start old interupts
           Or.w     #$8000,d0           ; enables you to set bits 0-14
           Move.w   d0,$9a(a5)          ; set INTENA
           Move.w   OldDma,d0           ; start old DMA
           Or.w     #$8000,d0           ; enables you to set bits 0-14
           Move.w   d0,$96(a5)          ; set DMACON

           Move.b   #$9b,$bfed01        ; Re-start CIA Timers

           Move.l   4.w,a6              ; Close Gfx lib
           Jsr      -$19e(a6)

           move.l   4.w,a6
           jsr      -138(a6)            ; Permit()

           Moveq.l  #0,d0               ; No errors, always clear before
                                        ; returning to prevent RETURN CODE
                                        ; errors on the CLI
           Rts                          ; Exit


my_level3:
           Movem.l  d0-d7/a0-a6,-(a7)   ; New copper
           Move.w   #$10,$dff09c        ; Serviced Interupt

           ****************
           bsr      my_interupt         ; your stuff goes here
           ****************

Exit:      Movem.l  (a7)+,d0-d7/a0-a6   ; Return from Interupt
           Rte

           section  Copperdata,data_c   ; force to chipmem

my_copper:
           dc.w     $100,$0200          ; no bitpplanes
           dc.w     $104,$a             ; bp control reg
           dc.w     $108,0              ; bp modulo - odd
           dc.w     $10a,0              ; bp modulo - even
           dc.w     $180,0              ; colour 0 to black
           dc.w     $102,0              ; no scroll

           dc.w     $08e,$2c81          ; bp window start left
           dc.w     $090,$2cc1          ; bp window bot right
           dc.w     $094,$d0            ; bp stop horz
           dc.w     $92,$38

sprites:   dc.w     $120,0,$122,0,$124,0,$126,0   ; Sprite pointers should
           dc.w     $128,0,$12a,0,$12c,0,$12e,0   ; be pointed to a location
           dc.w     $130,0,$132,0,$134,0,$136,0   ; which is initialised to
           dc.w     $138,0,$13a,0,$13c,0,$13e,0   ; 0

           dc.w     $ffe1,$fffe              ; end of ntsc screen
           dc.w     $3001,$ff00              ; end of pal screen
           dc.w     $9c,$8010                ; irq set bits - restart copper
           dc.w     $ffff,$fffe              ; end of copper list


           Section  Variables,Data           ; This is where the old system
                                             ; pointers etc are saved

DumSpite:  dc.l     0,0
oldint:    dc.l     0
olddma:    dc.l     0
oldv3:     dc.l     0
gfxlib:    dc.b     "graphics.library",0
           even

           ; End of takover/return control routine


           ; This is the reset routine, use this to reset the computer
           ; when exiting a demo packed to a low address

           move.l   #$fc00d0,$80        ; Address of reset routine in rom
           trap     #0                  ; call reset routine in supervisor mode


