OPT c+,l-,o+ ********************* * * * BootNTSC 1.0 * * * * by Nico François * ********************* incdir "INCLUDE:" include "exec/types.i" include "exec/execbase.i" include "exec/memory.i" include "exec/resident.i" include "exec/exec_lib.i" include "graphics/gfxbase.i" include "graphics/graphics_lib.i" include "libraries/dos_lib.i" 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 move.w $DFF004,d0 ; check for new 1Mb Agnus and.w #$2000,d0 bne.s ok1MbAgnus addq.w #8,a7 lea oldagnus.txt(PC),a0 ; if not available print move.l #oldagnus.len,d3 ; message move.l ($4).w,a6 bra putsandexit ok1MbAgnus: 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 bra.s cmdloop template: ; print usage line lea usage.txt(PC),a0 move.l #usage.len,d3 bra putsandexit install: move.l ($4).w,a6 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 move.l #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 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 beq.s noclr2 bclr #7,KickCheckSum(a6) noclr2: 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,'1mBootNTSC 1.0 ',$9b,'0m',$9b,'33mby Nico François',$9b,'0m',10 header.len equ *-header.txt oldagnus.txt: dc.b 'You haven''t got the ECS 1Mb Agnus, so run out and buy one !',10,0 oldagnus.len equ *-oldagnus.txt already.txt: dc.b 'NTSC RomTag already installed !',10,0 already.len equ *-already.txt usage.txt: dc.b 'Usage: BootNTSC [I=INSTALL|R=REMOVE]',10,0 usage.len equ *-usage.txt installed.txt: dc.b 'NTSC RomTag installed, reset to activate !',10,0 installed.len equ *-installed.txt nomem.txt: dc.b 'No memory for RomTag (I only need about 250 bytes) !?!',10,0 nomem.len equ *-nomem.txt nohandler.txt: dc.b 'NTSC RomTag not installed !',10,0 nohandler.len equ *-nohandler.txt removed.txt: dc.b 'NTSC RomTag removed !',10,0 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) **** Put AMIGA in NTSC mode **** lea GfxName(PC),a1 jsr _LVOOldOpenLibrary(a6) ; open graphics.library move.l d0,a1 move.w gb_DisplayFlags(a1),d0 and.b #%11111011,d0 ; clear PAL flag or.b #%00000001,d0 ; set NTSC flag move.w d0,gb_DisplayFlags(a1) move.w #200,gb_NormalDisplayRows(a1) ; WorkBench 200 pixels high or.b #LIBF_CHANGED,LIB_FLAGS(a1) move.l a1,a2 jsr _LVOSumLibrary(a6) ; recalculate checksum move.l a2,a1 jsr _LVOCloseLibrary(a6) move.b #60,VBlankFrequency(a6) ; change VBLANK or.b #LIBF_CHANGED,LIB_FLAGS(a6) jsr _LVOSumLibrary(a6) ; recalculate checksum ************************ move.w #0,$dff1dc ; this one does all the magic ************************ endtag: movem.l (sp)+,d0-d7/a0-a6 ; back to kickstart rts RomTagPtrs: dc.l 0,0 ; array of RomTag pointers GfxName: dc.b 'graphics.library',0 PortName: dc.b 'BootNTSC.port',0 ; port name TagName: dc.b 'NTSC-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 dc.b RTF_COLDSTART dc.b 1 dc.b 0 dc.b -10 dc.l NULL dc.l NULL dc.l 0 BlockLen equ *-StartBlock ; length of block to be copied ***************************************************************************** END