home *** CD-ROM | disk | FTP | other *** search
- ;======================================================================
- ;
- ; SetCPU V1.60
- ; by Dave Haynie, April 13, 1990
- ; Released to the Public Domain
- ;
- ; REBOOT.A MODULE
- ;
- ; This module contains functions that do the clever reset magic
- ; needed for KickStart imaging.
- ;
- ;======================================================================
-
- include "setcpu.i"
-
- cseg
-
- xdef _RAMBoot ; Effects the reboot into a RAM image
- xdef _BootCode ; Actual main reboot code
- xdef _BootCodeSize ; Size of this magic code
- xdef _CleanBoot ; Boot back to system ROM, reset Exec
- xdef _ResetCode ; Smart reset routine
- xdef _ResetCodeSize ; Size of this magic code
-
- ;======================================================================
- ;
- ; This is the RAMBoot routine as called from C. The C code has
- ; set up the tag structure with valid MMU data and a pointer to
- ; the main reset routine in safe memory. The routine will fetch
- ; the systag from the stack, then call the safe routine in the
- ; supervisor mode. That call is the last kernal call used; the
- ; reset routine itself doesn't use any ROM routines, so it can
- ; safely turn off the MMU before it goes to work, methinks.
- ;
- ; void RAMBoot(struct systag *tag, LONG ClearExec,LONG Delay)
- ;
- ;======================================================================
-
- _RAMBoot:
- move.l 4(sp),a2 ; Get the systag where we can use it
- move.l 8(sp),d4 ; KeepExec?
- move.l 12(sp),d5 ; Delay value
- move.l 4,a6
- lea.l TrickyBits,a5 ; Get the supervisor code
- CALLSYS Supervisor ; Go to supervisor mode
- rts ; We never get here!
-
- ;======================================================================
- ;
- ; This is the start of the supervisor portion of the reboot code.
- ; This code gets things in the registers the ChipRAM code
- ; requires, loads up a reset routine into cache, freezes the
- ; cache, resets, waits for the CIA chips, and then calls the
- ; ChipRAM code portion which will turn the MMU on and jump to
- ; ROM's start address.
- ;
- ; a2 SetCPU system tag
- ; a6 ExecBase
- ; d4 KeepExec Flag
- ; d5 Boot Delay
- ;
- ;======================================================================
-
- TrickyBits:
- move.l TAG_ROMSTART(a2),a4 ; Get the ROM jump address
- move.l TAG_RESETCODE(a2),a3 ; Get the ChipRAM based code
- lea.l TAG_CRP_0(a2),a1 ; Get CRP register
- lea.l TAG_TC(a2),a0 ; Get TC register
-
- and.l #$7fffffff,(a0) ; Turn off MMU
- PMOVE_ (a0),tc ; -> $f010,$4000
- or.l #$80000000,(a0) ; Prep for startup
- PMOVE_ (a1),crp ; -> $f011,$4c00
-
- cmp.l #0,d4 ; If asked for, zap ExecBase good
- bne 1$
- moveq.l #0,d0
- move.l d0,$4
- 1$
- move.l #1,d1 ; Make sure inst cache is on!
- MOVEC_ d1,cacr
-
- move.l #1,d3 ; First pass, no delay
- lea.l CacheRun,a6 ; Get the initial branch address
-
- RSTLoop:
- jmp (a6)
-
- RSTIt:
- reset ; Clobber the system
- reset
-
- CacheRun:
- move.w ANYCREG,d1 ; Set a spell, take yer shoes off
- subq.l #1,d3
- bne CacheRun
- move.b #3,$bfe201 ; Turn off Amiga ROM Overlay
- move.b #2,$bfe001
-
- cmp.l a3,a6 ; Last time through?
- beq RSTLoop ; If so, go back
-
- move.l a3,a6 ; No? Get the address,
- move.l d5,d3 ; the delay
- move.l #3,d1 ; freeze the cache
- MOVEC_ d1,cacr
- bra RSTIt ; And Up to the reset stuff
-
- ;======================================================================
- ;
- ; This is the RAM reboot code, which is called to reset the
- ; system into the new ROM, which is of course now in some magic
- ; and safe place. The ROM's jump address in in A4 when this
- ; code is called, and the TC register is in A0.
- ;
- ;======================================================================
-
- RAMBootCode:
- move.l #0,d1 ; Turn all caches off
- MOVEC_ d1,cacr
- move.l #10,d1 ; Let 'em know we're here
- 1$
- bchg #1,$bfe001
- move.l #80000,d0
- 2$ subq.l #1,d0
- bne 2$
- dbra d1,1$
-
- PMOVE_ (a0),tc ; Turn on the MMU
- jmp (a4) ; Start up the ROM
- nop
- nop
- nop
- nop
- RAMBootEnd:
-
- _BootCode:
- dc.l RAMBootCode
- _BootCodeSize:
- dc.l RAMBootEnd-RAMBootCode+1
-
- ;======================================================================
- ;
- ; This routine forces a boot back to ROM, clearing out the
- ; ExecBase and turning off the MMU and caches.
- ;
- ; void CleanBoot(void)
- ;
- ;======================================================================
-
- _CleanBoot:
- move.l 4,a6
-
- lea 1$,a5
- CALLSYS Supervisor
- rts
- 1$
- move.l #0,(sp) ; Turn off MMU
- move.l sp,a0
- PMOVE_ (a0),tc ; -> $f010,$4000
-
- move.l #0,d1 ; Turn all caches off
- MOVEC_ d1,cacr
-
- move.l 4,a6 ; Clear out ExecBase
- move.l #0,$4
-
- move.l $00f80000,d0 ; Which kind of real ROM?
- cmp.l #$11144ef9,d0
- beq 2$
- move.l $00fc0004,a0
- bra 3$
- 2$
- move.l $00f80004,a0 ; We have a 512K ROM
- 3$
- reset
- reset
- jmp (a0)
- nop
- nop
- nop
- nop
- CleanBootEnd:
-
- ;======================================================================
- ;
- ; Pointers to the smart reset routine, and the length of this
- ; routine. Currently I'm using the CleanBoot routine, which will
- ; get the machine back to the ROM OS. A better smart reset routine
- ; could boot back to the virtual ROM rather than the physcial ROM.
- ;
- ;======================================================================
-
- _ResetCode:
- dc.l _CleanBoot
- _ResetCodeSize:
- dc.l CleanBootEnd-_CleanBoot+1
-
- end
-