OPT c+,l-,o+ ********************* * * * BootCACHE 1.0 * * * * by Nico François * ********************* incdir "INCLUDE:" include "exec/types.i" include "exec/funcdef.i" include "exec/execbase.i" include "exec/memory.i" include "exec/resident.i" include "exec/exec_lib.i" include "graphics/gfxbase.i" include "libraries/dos_lib.i" IFND _LVOCacheControl _LVOCacheControl equ -$288 ENDC NULL equ 0 movem.l d0/a0,-(a7) move.l ($4).w,a6 lea DosName(PC),a1 jsr _LVOOldOpenLibrary(a6) ; open DOS lea DOSBase(PC),a1 move.l d0,(a1) move.l d0,a6 jsr _LVOOutput(a6) ; get stdout lea stdout(PC),a1 move.l d0,(a1) lea header.txt(PC),a0 ; print header to console move.l #header.len,d3 bsr puts movem.l (a7)+,d0/a0 ; get command line back move.l ($4).w,a6 move.b #0,0(a0,d0.w) ; zero terminated cmdloop: move.b (a0)+,d0 ; look for 'I' or 'R' beq.s template cmp.b #'i',d0 beq.s install cmp.b #'I',d0 beq.s install cmp.b #'r',d0 beq quit cmp.b #'R',d0 beq quit cmp.b #'b',d0 beq.s bbinstall cmp.b #'B',d0 beq.s bbinstall bra.s cmdloop template: ; print usage line lea usage.txt(PC),a0 move.l #usage.len,d3 bra putsandexit bbinstall: moveq #0,d7 bra.s installrt install: moveq #1,d7 installrt: move.l ($4).w,a6 move.w LIB_VERSION(a6),d0 cmp.w #36,d0 blo.s Kickstart13 tst.l d7 beq.s Kickstart13 move.b #-37,rtpri move.b #RTF_AFTERDOS,rtflags Kickstart13: lea PortName(PC),a1 jsr _LVOFindPort(a6) ; find our port tst.l d0 beq.s allocit lea already.txt(PC),a0 ; found, so already installed move.l #already.len,d3 bra putsandexit allocit: move.l #BlockLen,d0 moveq #MEMF_CHIP,d1 ; allocate memory for reset code jsr _LVOAllocMem(a6) ; must be in CHIP !! tst.l d0 bne.s memok lea nomem.txt(PC),a0 ; out of memory ??? move.l #nomem.len,d3 bra putsandexit memok: move.l d0,a5 ; a5 holds address of copy lea StartBlock(PC),a0 move.l d0,a1 move.l #BlockLen,d0 jsr _LVOCopyMem(a6) ; copy block to allocated memory move.w #$4000,$DFF09A ; DISABLE addq.b #1,IDNestCnt(a6) lea RomTagPtrs-StartBlock(a5),a0 move.l KickTagPtr(a6),4(a0) ; old romtag pointer in array beq.s yestag bset #7,4(a0) ; set bit if there are more yestag: move.l a0,KickTagPtr(a6) ; pointer to our array lea RomTag-StartBlock(a5),a1 move.l a1,(a0) ; fill in our romtag pointer lea myMemList-StartBlock(a5),a1 ; init memlist and put in move.l a5,ML_SIZE+ME_ADDR(a1) ; KickMemPtr list to protect move.l KickMemPtr(a6),d0 ; our memory move.l d0,LN_SUCC(a1) move.l a1,KickMemPtr(a6) inittag: lea RomTag-StartBlock(a5),a1 ; init romtag move.l a1,RT_MATCHTAG(a1) lea RT_SIZE(a1),a2 move.l a2,RT_ENDSKIP(a1) lea TagName-StartBlock(a5),a2 move.l a2,RT_NAME(a1) move.l a5,RT_INIT(a1) jsr _LVOSumKickData(a6) ; calculate checksum move.l d0,KickCheckSum(a6) lea Port-StartBlock(a5),a1 ; init and add our port moveq #0,d0 move.l d0,(a1) move.l d0,LN_PRED(a1) lea PortName-StartBlock(a5),a0 move.l a0,LN_NAME(a1) jsr _LVOAddPort(a6) subq.b #1,IDNestCnt(a6) ; ENABLE bge.s noenable move.w #$C000,$DFF09A noenable: lea installed.txt(PC),a0 ; inform user of installation move.l #installed.len,d3 move.w LIB_VERSION(a6),d0 cmp.w #36,d0 blo putsandexit tst.l d7 bne putsandexit bsr puts lea bootinstalled.txt(PC),a0 move.l #bootinstalled.len,d3 bra.s putsandexit quit: lea PortName(PC),a1 ; are we already installed ? jsr _LVOFindPort(a6) tst.l d0 bne.s portfound lea nohandler.txt(PC),a0 ; no, can't quit then move.l #nohandler.len,d3 bra.s putsandexit portfound: move.l d0,a4 ; we found our port, so remove it move.l a4,a1 jsr _LVORemPort(a6) move.w #$4000,$DFF09A ; DISABLE addq.b #1,IDNestCnt(a6) lea myMemList-Port(a4),a1 ; remove our memlist from lea KickMemPtr(a6),a0 ; KickMemPtr list. nextnode: move.l LN_SUCC(a0),d0 cmp.l d0,a1 beq.s foundmylist move.l d0,a0 bra.s nextnode foundmylist: move.l LN_SUCC(a1),d0 move.l d0,LN_SUCC(a0) ; LN_SUCC = 0, so this also works for KickMemPtr move.l RomTagPtrs-Port+4(a4),KickTagPtr(a6) ; old RomTag back bclr #7,KickTagPtr(a6) jsr _LVOSumKickData(a6) ; calculate checksum move.l d0,KickCheckSum(a6) subq.b #1,IDNestCnt(a6) ; ENABLE bge.s noenable2 move.w #$C000,$DFF09A noenable2: lea StartBlock-Port(a4),a1 ; free our copied block move.l #BlockLen,d0 jsr _LVOFreeMem(a6) lea removed.txt(PC),a0 ; and inform the user move.l #removed.len,d3 putsandexit: bsr.s puts ; print string in A0, length D3 move.l DOSBase(PC),a1 jsr _LVOCloseLibrary(a6) ; close DOS and exit moveq #0,d0 rts * text-ptr in A0, length in D3 puts: move.l a6,-(a7) move.l a0,d2 move.l stdout(PC),d1 move.l DOSBase(PC),a6 jsr _LVOWrite(a6) move.l (a7)+,a6 rts header.txt: dc.b $9b,'1mBootCACHE 1.0 ',$9b,'0m',$9b,'33mby Nico François',$9b,'0m',10 header.len equ *-header.txt already.txt: dc.b 'CACHE RomTag already installed !',10 already.len equ *-already.txt usage.txt: dc.b 'Usage: BootCACHE [I=INSTALL|B=BOOTBLOCK|R=REMOVE]',10 dc.b ' Use BOOTBLOCK on Kickstart 2.0 for programs that',10 dc.b ' boot from the bootblock (mostly games).',10 usage.len equ *-usage.txt installed.txt: dc.b 'CACHE RomTag installed, reset to disable all caches!',10 installed.len equ *-installed.txt bootinstalled.txt: dc.b 'NOTE: Cache will only be disabled for programs that boot from the bootblock!' dc.b 10 bootinstalled.len equ *-bootinstalled.txt nomem.txt: dc.b 'No memory for RomTag (I only need about 200 bytes) !?!',10 nomem.len equ *-nomem.txt nohandler.txt: dc.b 'CACHE RomTag not installed !',10 nohandler.len equ *-nohandler.txt removed.txt: dc.b 'CACHE RomTag removed !',10 removed.len equ *-removed.txt DosName: dc.b 'dos.library',0 EVEN DOSBase: dc.l 0 stdout: dc.l 0 ***************************************************************************** StartBlock: ; this is the routine that will movem.l d0-d7/a0-a6,-(a7) ; be executed when we reset move.l ($4).w,a6 lea Port(PC),a1 ; add our port to the system list moveq #0,d0 move.l d0,(a1) move.l d0,LN_PRED(a1) lea PortName(PC),a0 move.l a0,LN_NAME(a1) jsr _LVOAddPort(a6) move.w LIB_VERSION(a6),d0 cmp.w #36,d0 blo.s Kick13 Kick20: move.l #$2000,d0 moveq #-1,d1 jsr _LVOCacheControl(a6) bra.s endtag Kick13: jsr _LVODisable(a6) lea DisableCache,a5 jsr _LVOSupervisor(a6) jsr _LVOEnable(a6) endtag: movem.l (a7)+,d0-d7/a0-a6 ; back to rom boot code move.w #$0f0,$DFF180 ; green screen rts cnop 0,4 DisableCache: move.l #$2000,d0 dc.w $4e7b,$0002 ; movec d0,CACR rte RomTagPtrs: dc.l 0,0 ; array of RomTag pointers PortName: dc.b 'BootCACHE.port',0 ; port name TagName: dc.b 'CACHE-boot',0 ; tag name EVEN myMemList: ; memory list for reset protection ds.b LN_SIZE dc.w 1 dc.l NULL dc.l BlockLen Port: ; our port structure dc.l NULL dc.l NULL dc.b NT_MSGPORT dc.b 0 dc.l NULL dc.b 0 dc.b 0 dc.l NULL ds.b 14 RomTag: ; the RomTag to inform kickstart dc.w RTC_MATCHWORD ; of what we want dc.l NULL dc.l NULL rtflags: dc.b RTF_COLDSTART ; RTF_AFTERDOS in Kick 2.0 dc.b 1 dc.b 0 rtpri: dc.b -10 ; -37 in Kick 2.0 dc.l NULL dc.l NULL dc.l NULL BlockLen equ *-StartBlock ; length of block to be copied ***************************************************************************** END