*********************************************************************** * BootTwister (BT) V1.00 ® 21-10-1998 / 14:31:58 * BootTwister (BT) V2.00 ® 26-02-2002 / 01:10:11 * --------------------------------------------------------------------- * Programmiert von Volker Stepprath, testaware@arcor.de, BRD * --------------------------------------------------------------------- * Assembler: GenAm Macro Assembler V2.11D Copyright © HiSoft 1985,8 * Editor: CygnusEd Professional Release 2 © 1989 by CygnusSoft Software *********************************************************************** opt o+,ow- Output RAM:BT *********************************************************************** ;Library Offsets _LVOOpen equ -30 _LVOClose equ -36 _LVORead equ -42 _LVOWrite equ -48 _LVOOutput equ -60 _LVOClearPointer equ -60 _LVOCloseScreen equ -66 _LVOCloseWindow equ -72 _LVOLock equ -84 _LVOUnLock equ -90 _LVOFindResident equ -96 _LVOExamine equ -102 _LVODeviceProc equ -174 _LVOAllocMem equ -198 _LVOOpenScreen equ -198 _LVOOpenWindow equ -204 _LVOFreeMem equ -210 _LVOScreenToBack equ -246 _LVOSetPointer equ -270 _LVOWaitTOF equ -270 _LVOSetRGB4 equ -288 _LVOFindTask equ -294 _LVOPutMsg equ -366 _LVOGetMsg equ -372 _LVOWaitPort equ -384 _LVOOpenLibrary equ -552 _LVOCloseLibrary equ -414 _LVOOpenDevice equ -444 _LVOCloseDevice equ -450 _LVODoIO equ -456 _LVORawDoFmt equ -522 _LVOCopyMem equ -624 *********************************************************************** ;Struktur Offsets ns_Width equ $4 ns_Height equ $6 ns_Depth equ $8 ns_ViewModes equ $C ns_Type equ $E ns_SIZEOF equ $20 sc_BitMap equ $B8 sc_ViewPort equ $2C bm_BytesPerRow equ $0 bm_Rows equ $2 bm_Depth equ $5 bm_Planes equ $8 nw_Width equ $4 nw_Height equ $6 nw_Flags equ $E nw_Screen equ $1E nw_Type equ $2E nw_SIZE equ $30 fib_Size equ 124 io_Command equ 28 io_Error equ 31 io_Actual equ 32 io_Length equ 36 io_Data equ 40 io_Offset equ 44 *********************************************************************** ;Allgemeine Konstanten CMD_READ equ 2 CMD_WRITE equ 3 CMD_UPDATE equ 4 TD_MOTOR equ 9 TD_SEEK equ 10 TD_CHANGESTATE equ 14 TD_PROSTATUS equ 15 V_HIRES equ $8000 V_LACE equ $4 V_HAM equ $800 CUSTOMSCREEN equ $F SCREENQUIET equ $100 ACTIVATE equ $1000 MODE_OLDFILE equ 1005 ACCESS_READ equ -2 *********************************************************************** ;Datenstruktur RsReset MY_Base rs.b 0 my_DosBase rs.l 1 my_ParamStr rs.l 1 my_ParamLen rs.l 1 my_PicName rs.l 1 my_ModName rs.l 1 my_PicLen rs.l 1 my_ModLen rs.l 1 my_BitNum rs.l 1 my_Lock rs.l 1 my_Fib rs.b 260 my_Handle rs.l 1 my_TrkBuf rs.l 1 my_TrkLen rs.l 1 my_TrkOfs rs.l 1 my_OldBoot rs.l 1 my_DiskReply rs.l 8 my_StdIOReq rs.b 52 my_WorkBuffer rs.b 1024 my_FmtBuffer rs.b 1024 my_BusyBuffer rs.b 1024 my_TrkBuffer rs.b 5632 my_Error rs.l 1 my_SIZEOF rs.w 0 ;BT BootBlock-Offsets RsReset bt_BBMark rs.l 1 ;DOS0 bt_BBCKSum rs.l 1 ;Cheksum bt_BBRoot rs.l 1 ;RootBlk bt_BBnop1 rs.l 1 ;Not used bt_BBOffset rs.l 1 ;CMD_READ Offset bt_BBPicLen rs.l 1 bt_BBModLen rs.l 1 bt_BBBlkLen rs.l 1 ;Gesamte Anz. Bytes bt_BBExecBB rs.l 1 ;Boot ausführen? bt_BBID rs.l 1 ;BT98 Marker *********************************************************************** ;Macros definieren EXE MACRO movea.l 4.w,a6 jsr _LVO\1(a6) ENDM DOS MACRO movea.l my_DosBase(a5),a6 jsr _LVO\1(a6) ENDM LIB MACRO jsr _LVO\1(a6) ENDM LAB MACRO jmp _LVO\1(a6) ENDM VER MACRO dc.b ' V2.00 ' ENDM bra.s BT_Start cnop 0,4 dc.b 'BootTwister' VER dc.b '© Volker Stepprath, Testaware (27.02.2002)' cnop 0,4 ***************************************************************** ************* Installations-Program für BootTwister ************* ***************************************************************** BT_Start clr.b -1(a0,d0.l) move.l a0,d6 move.l d0,d7 move.l #my_SIZEOF,d0 move.l #$10003,d1 EXE AllocMem tst.l d0 beq BT_Exit movea.l d0,a5 move.l d6,my_ParamStr(a5) move.l d7,my_ParamLen(a5) lea bb_DosLib(pc),a1 ;dos.library öffnen moveq #0,d0 LIB OpenLibrary move.l d0,my_DosBase(a5) beq BT_Finish * ------------------------------------------------------------- * Parametertest nach DFn: & Param -? sowie TrkDev bereitstellen * ------------------------------------------------------------- * BT_PCheck movea.l my_ParamStr(a5),a0 move.l my_ParamLen(a5),d0 cmpi.b #':',3(a0) ;Test nach DFn: bne.s .2 ;Fehler cmpi.b #'-',5(a0) ;Test nach -? bne.s .2 ;Fehler move.b 2(a0),d4 ;LW Nummer lea TxDrive(pc),a0 move.b d4,2(a0) ;DFn: übergeben subi.b #'0',d4 bsr PrtBThead ;Kopfzeile ausgeben suba.l a1,a1 ;TrkDisk.Dev bereitstellen LIB FindTask lea my_DiskReply(a5),a2 move.l d0,16(a2) lea my_StdIOReq(a5),a1 move.l a2,14(a1) moveq #0,d1 move.l d4,d0 lea bb_TrkDev(pc),a0 LIB OpenDevice tst.l d0 ;Alles geklappt bne.s .1 ;Nein! Fehler bsr.s BT_Options ;Parameter ausführen bra.s .3 ;Programm beenden .1 bsr PrtDeverr ;Fehler aufgetreten bra.s .3 .2 bsr PrtUsage ;Benutzerhinweis .3 bra BT_Finish ;Programm beenden * ------------------------------------ * Auswertung der übergebenen Parameter * ------------------------------------ * BT_Options move.b #'R',d0 ;Opt -[R]emove bsr BT_GetOpt ;Suchen tst.b my_Error(a5) ;Übergeben? bne.s .1 ;Nein! bsr BT_Remove ;Ja, dann BT entfernen bra BT_ExitKey .1 move.b #'E',d0 ;Opt -[E]xecute bsr BT_GetOpt ;Suchen tst.b my_Error(a5) ;übergeben? bne.s .2 ;Nein move.l #1024,my_OldBoot(a5) ;Flag & Größe setzen lea bb_ExecBB(pc),a0 not.l (a0) ;Flag für BB bra.s BT_Parameter .2 move.b #'C',d0 ;Opt -[C]heck bsr BT_GetOpt ;Suchen tst.b my_Error(a5) ;Übergeben? bne.s .3 ;Nein bsr BT_Check ;Ja, dann Disk testen bra BT_ExitKey .3 move.b #'I',d0 ;Opt -[I]nfo bsr BT_GetOpt tst.b my_Error(a5) bne.s .4 bsr BT_Info ;Ja, dann BT BB Info bra BT_ExitKey .4 move.b #'S',d0 ;Opt -[S]wap bsr BT_GetOpt tst.b my_Error(a5) bne.s .5 bsr BT_Swap ;Ja, dann Swap Exec BB Flag bra BT_ExitKey .5 move.b #'X',d0 ;Opt -[X]ecute bsr BT_GetOpt tst.b my_Error(a5) bne.s BT_Parameter bsr BT_Xecute ;Ja, Exec BT Boot bra BT_ExitKey BT_Parameter move.b #'P',d0 ;Opt -P PicName bsr BT_GetParam ;Pos. PicName ermitteln tst.b my_Error(a5) ;Fehler? bne PrtUsage ;Wenn nicht dann Fehler move.l a0,my_PicName(a5) ;Name des Bildes move.b #'M',d0 ;Opt -M ModName bsr BT_GetParam ;Pos. ModName ermitteln tst.b my_Error(a5) ;Module übergeben bne.s .1 ;Nein! Nicht unbedingt nötig move.l a0,my_ModName(a5) ;Name des Modules .1 move.b #'B',d0 ;Opt -B #Blk bsr.s BT_GetParam ;Pos. Offset ermitteln tst.b my_Error(a5) ;Übergabe? bne.s .2 ;Nein! bsr BT_CalcNumb cmpi.l #2,d0 blt PrtBadoffset cmpi.l #1756,d0 bgt PrtBadoffset mulu #512,d0 lea bb_Offset(pc),a0 move.l d0,(a0) .2 move.b #'T',d0 ;Opt -T #Trk bsr.s BT_GetParam tst.b my_Error(a5) bne.s .3 bsr BT_CalcNumb cmpi.l #1,d0 blt PrtBadoffset cmpi.l #159,d0 bgt PrtBadoffset mulu #5632,d0 lea bb_Offset(pc),a0 move.l d0,(a0) .3 bsr BT_GetPMSize ;Größe Pic/Mod ermitteln tst.b my_Error(a5) bne.s .Skip bsr BT_Load ;Dateien einladen tst.b my_Error(a5) bne.s .Skip bsr BT_Install ;BT installieren bra BT_ExitKey ;Auf [RETURN] warten .Skip rts * ------------------------------------ * Paramterangaben ermitteln -(PMTB) * * In: D0 = Parameter * Out: A0 = Zeiger auf Parameterangabe * * my_Error <> 0 wenn Fehler * ------------------------------------ * BT_GetParam movea.l my_ParamStr(a5),a1 move.l my_ParamLen(a5),d1 .1 move.b (a1)+,d2 cmpi.b #'-',d2 bne.s .4 move.b (a1),d2 bclr #5,d2 cmp.b d0,d2 bne.s .4 adda.l #2,a1 movea.l a1,a0 .2 move.b (a1)+,d2 cmpi.b #' ',d2 beq.s .3 tst.b d2 bne.s .2 .3 clr.b -1(a1) bra BT_Ok .4 dbf d1,.1 bra BT_Error * -------------------------- * Option ermitteln -(CEIRSX) * * In: D0 = Param * * my_Error <> 0 wenn Fehler * -------------------------- * BT_GetOpt movea.l my_ParamStr(a5),a0 move.l my_ParamLen(a5),d1 .1 move.b (a0)+,d2 cmpi.b #'-',d2 bne.s .2 move.b (a0),d2 bclr #5,d2 cmp.b d0,d2 bne.s .2 bra BT_Ok .2 dbf d1,.1 bra BT_Error * -------------------------------------------- * ASCII-String in Zahl wandeln für #Blk & #Trk * * In: A0 = Zeichenkette mit Zahlen * Out: D0 = Long-Zahl * -------------------------------------------- * BT_CalcNumb moveq.l #0,d0 .1 moveq.l #0,d1 move.b (a0)+,d1 subi.b #'0',d1 bmi.s .2 mulu #10,d0 ext.w d1 ext.l d1 add.l d1,d0 bra.s .1 .2 rts * ----------------------------------- * Größe von Pic & Mod-Datei ermitteln * ----------------------------------- * BT_GetPMSize move.l my_PicName(a5),d1 ;IFF-Bild moveq #ACCESS_READ,d2 DOS Lock move.l d0,my_Lock(a5) ble PrtNopic move.l my_Lock(a5),d1 lea my_Fib(a5),a3 move.l a3,d2 LIB Examine tst.l d0 beq.s .1 move.l fib_Size(a3),my_PicLen(a5) move.l my_Lock(a5),d1 LIB UnLock move.l my_ModName(a5),d1 ;ST-Module ble BT_Ok moveq #ACCESS_READ,d2 LIB Lock move.l d0,my_Lock(a5) ble PrtNomod move.l my_Lock(a5),d1 lea my_Fib(a5),a3 move.l a3,d2 LIB Examine tst.l d0 beq.s .1 move.l fib_Size(a3),my_ModLen(a5) move.l my_Lock(a5),d1 LIB UnLock bra BT_Ok .1 move.l my_Lock(a5),d1 ;Fehler! LIB UnLock bra BT_Error * -------------------------------------------------------------- * BootBlock, BT, Pic & Module in Speicher einlesen bzw. kopieren * -------------------------------------------------------------- * BT_Load move.l #1024*2,d0 ;Platz für BB`s add.l #PM_LEN,d0 ;Platz für BT PM add.l my_PicLen(a5),d0 ;Platz für Pic add.l my_ModLen(a5),d0 ;Platz für Mod andi.l #$FFFFFE00,d0 ;KgV von 512 ermitteln addi.l #512,d0 ;Für TrkCmd's move.l d0,my_TrkLen(a5) ;Gesamte Speichergröße move.l d0,my_BitNum(a5) ;Für SetBitMap move.l #$10003,d1 EXE AllocMem move.l d0,my_TrkBuf(a5) ble PrtMemout movea.l my_TrkBuf(a5),a3 ;Zeiger auf Puffer adda.l #PM_LEN+2048,a3 ;Freiraum für PM & BB`s move.l my_PicName(a5),d1 ;Bild einlesen lea TxLoadPic(pc),a0 lea my_WorkBuffer(a5),a1 move.l d1,(a1) bsr BT_FmtStr move.l #MODE_OLDFILE,d2 DOS Open move.l d0,my_Handle(a5) beq.s .3 move.l my_Handle(a5),d1 move.l a3,d2 move.l my_PicLen(a5),d3 LIB Read cmp.l my_PicLen(a5),d0 bne.s .2 move.l my_Handle(a5),d1 LIB Close adda.l my_PicLen(a5),a3 move.l my_ModName(a5),d1 ;Module kopieren ble BT_Ok ;Nein! lea TxLoadMod(pc),a0 lea my_WorkBuffer(a5),a1 move.l d1,(a1) bsr BT_FmtStr move.l #MODE_OLDFILE,d2 LIB Open move.l d0,my_Handle(a5) beq.s .3 move.l my_Handle(a5),d1 move.l a3,d2 move.l my_ModLen(a5),d3 LIB Read cmp.l my_ModLen(a5),d0 bne.s .2 move.l my_Handle(a5),d1 LIB Close adda.l my_ModLen(a5),a3 bra BT_Ok .2 move.l my_Handle(a5),d1 LIB Close .3 lea TxFileErr(pc),a0 lea my_WorkBuffer(a5),a1 ;Dateiname war installiert! bsr BT_FmtStr bra BT_Error * ------------------------------------- * BootTwister auf Diskette installieren * ------------------------------------- * BT_Install bsr BT_WaitKey ;Warten auf [RETURN] bsr BT_DiskIN ;Eingelegt tst.b my_Error(a5) ;Testflag bne.s .0 ;Alles OK, ansonsten Abbruch bsr BT_DiskWP tst.b my_Error(a5) beq.s .1 .0 rts .1 lea bb_PicLen(pc),a0 move.l my_PicLen(a5),(a0) lea bb_ModLen(pc),a0 move.l my_ModLen(a5),(a0) lea bb_BlkLen(pc),a0 move.l my_TrkLen(a5),(a0) movea.l my_TrkBuf(a5),a3 lea BT_BB(pc),a0 ;BootBlock kopieren movea.l a3,a1 move.l #BB_LEN,d0 LIB CopyMem lea BT_PM(pc),a0 ;PicMod kopieren lea 2048(a3),a1 ;BB`s überspringen move.l #PM_LEN,d0 LIB CopyMem movea.l a3,a0 ;BootBlock Daten bsr BT_CalcBBSum ;CkSum berechnen & Eintragen * -------------------------------------- * Alten BootBlock zuvor retten für -(ER) * -------------------------------------- * BT_SaveOldBB lea my_StdIOReq(a5),a1 bsr PrtReadbb lea 1024(a3),a0 ;Alten BB sichern move.w #CMD_READ,io_Command(a1) move.l #1024,io_Length(a1) move.l a0,io_Data(a1) clr.l io_Offset(a1) bsr BT_DoIO bne BT_Error * ------------------------------------------- * BootTwister-Daten auf Diskette installieren * ------------------------------------------- * BT_WriteDisk move.w #CMD_WRITE,io_Command(a1) move.l #1024,io_Length(a1) ;BB_LEN move.l a3,io_Data(a1) ;Adresse BB clr.l io_Offset(a1) ;Offset Block 0 bsr BT_DoIO ;Installieren bne.s .Skip move.l my_TrkLen(a5),d0 ;Totale Byte-Größe subi.l #1024,d0 ;Ohne BootBlock move.l d0,io_Length(a1) lea 1024(a3),a0 ;Daten für BT move.l a0,io_Data(a1) lea bb_Offset(pc),a0 ;Byte-Offset move.l (a0),io_Offset(a1) ;Falls Opt -B/T bsr BT_DoIO bne.s .Skip move.w #CMD_UPDATE,io_Command(a1) bsr BT_DoIO bne.s .Skip move.l io_Offset(a1),d0 cmpi.l #1024,d0 ;Opt -T/B übergeben bne.s .1 ;Nein bsr PrtSetbm moveq.l #$FFFFFFFF,d7 ;BitMuster = Freie Blöcke bsr BT_SetBitMap .1 bra PrtBTinfo .Skip rts * ----------------------------------------------------------------- * -R = BootTwister Daten von Disk entfernen & BootBlock restauieren * ----------------------------------------------------------------- * BT_Remove bsr BT_WaitKey bsr BT_DiskIN tst.b my_Error(a5) bne .Skip bsr BT_DiskWP tst.b my_Error(a5) bne .Skip lea my_WorkBuffer(a5),a3 lea my_StdIOReq(a5),a1 move.w #CMD_READ,io_Command(a1) move.l #1024,io_Length(a1) move.l a3,io_Data(a1) clr.l io_Offset(a1) bsr BT_DoIO bne .Skip move.l 28(a3),my_BitNum(a5) ;Anz. belegter Blöcke cmpi.l #'BT98',36(a3) bne PrtNobt lea TxRestore(pc),a0 ;Restore-Info bsr BT_Print move.l 16(a3),d7 ;Offset für Überprüfung move.w #CMD_READ,io_Command(a1) move.l #1024,io_Length(a1) move.l d7,io_Offset(a1) ;Offset bsr BT_DoIO bne.s .Skip move.w #CMD_WRITE,io_Command(a1) clr.l io_Offset(a1) bsr BT_DoIO bne.s .Skip move.w #CMD_UPDATE,io_Command(a1) bsr BT_DoIO bne.s .Skip lea TxCleanup(pc),a0 ;Textausgabe bra BT_Print move.l my_BitNum(a5),d6 ;Freie Blöcke formatieren .0 lea my_TrkBuffer(a5),a4 lea my_StdIOReq(a5),a1 move.w #CMD_WRITE,io_Command(a1) move.l #512,io_Length(a1) move.l a4,io_Data(a1) move.l d7,io_Offset(a1) ;Offset bsr BT_DoIO bne.s .Skip subi.l #512,d6 ble.s .1 addi.l #512,d7 bra.s .0 .1 move.w #CMD_UPDATE,io_Command(a1) bsr BT_DoIO move.l 16(a3),d7 cmpi.l #1024,d7 ;Wurde -T/-B übergeben bne.s .Skip ;Ja, kein BM-Update moveq.l #0,d7 ;Belgete Blöcke freigeben bra BT_SetBitMap .Skip rts * ------------------------------------- * -C = Disk nach freien Tracks absuchen * ------------------------------------- * BT_Check bsr BT_WaitKey bsr BT_DiskIN tst.b my_Error(a5) bne .Skip move.l #5632,d7 ;Offset Start Track 1 .0 lea TxCheckTrk(pc),a0 bsr.s .4 ;Test Track anzeigen lea my_StdIOReq(a5),a1 move.w #CMD_READ,io_Command(a1) move.l #5632,io_Length(a1) lea my_TrkBuffer(a5),a3 move.l a3,io_Data(a1) move.l d7,io_Offset(a1) bsr BT_DoIO bne.s .Skip move.l #1408,d6 lea my_TrkBuffer(a5),a3 .1 tst.l (a3)+ bne.s .2 dbf d6,.1 lea TxFreeTrk(pc),a0 bsr.s .4 ;Freien Track anzeigen .2 btst #6,$BFE001 beq.s .3 addi.l #5632,d7 cmpi.l #901120,d7 bne.s .0 .3 lea TxFreeLine(pc),a0 bsr BT_Print .4 lea my_WorkBuffer(a5),a1 move.l d7,d0 divu #5632,d0 move.w d0,(a1) ;Track move.l d7,d0 divu #512,d0 move.w d0,2(a1) ;Block addi.w #10,d0 move.w d0,4(a1) ;To Block bra BT_FmtStr .Skip rts * ------------------------------- * -I = BT BootBlock Info ausgeben * ------------------------------- * BT_Info bsr BT_WaitKey bsr BT_DiskIN tst.b my_Error(a5) bne.s .Skip lea my_StdIOReq(a5),a1 ;BootBlock einlesen lea my_WorkBuffer(a5),a3 move.w #CMD_READ,io_Command(a1) move.l #1024,io_Length(a1) move.l a3,io_Data(a1) clr.l io_Offset(a1) bsr BT_DoIO bne.s .Skip cmpi.l #'BT98',bt_BBID(a3) bne PrtNobt move.l bt_BBOffset(a3),d0 ;BytePos. divu #512,d0 ;BlockPos. clr.l bt_BBOffset(a3) move.w d0,bt_BBOffset+2(a3) ;Eintragen tst.l bt_BBExecBB(a3) bne.s .0 lea TxInfoNOT(pc),a0 move.l a0,bt_BBExecBB(a3) .0 lea TxInfo(pc),a0 lea bt_BBOffset(a3),a1 bsr BT_FmtStr .Skip rts * ------------------------------------ * -S = Swap execute old BootBlock flag * ------------------------------------ * BT_Swap bsr BT_WaitKey bsr BT_DiskIN tst.b my_Error(a5) bne.s .Skip bsr BT_DiskWP tst.b my_Error(a5) bne.s .Skip lea TxSwapFlag(pc),a0 bsr BT_Print lea my_StdIOReq(a5),a1 ;BootBlock einlesen lea my_WorkBuffer(a5),a3 move.w #CMD_READ,io_Command(a1) move.l #1024,io_Length(a1) move.l a3,io_Data(a1) clr.l io_Offset(a1) bsr BT_DoIO bne.s .Skip cmpi.l #'BT98',bt_BBID(a3) bne PrtNobt not.l bt_BBExecBB(a3) ;Exec Old Boot On/Off lea my_StdIOReq(a5),a1 ;BootBlock einlesen move.w #CMD_WRITE,io_Command(a1) move.l #1024,io_Length(a1) move.l a3,io_Data(a1) clr.l io_Offset(a1) bsr BT_DoIO bne.s .Skip move.w #CMD_UPDATE,io_Command(a1) bra BT_DoIO .Skip rts * ------------------------------ * -X = Xecute BT Intro from disk * ------------------------------ * BT_Xecute bsr BT_WaitKey bsr BT_DiskIN tst.b my_Error(a5) bne .Skip lea my_StdIOReq(a5),a1 ;BootBlock einlesen lea my_WorkBuffer(a5),a3 move.w #CMD_READ,io_Command(a1) move.l #1024,io_Length(a1) move.l a3,io_Data(a1) clr.l io_Offset(a1) bsr BT_DoIO bne .Skip cmpi.l #'BT98',bt_BBID(a3) bne PrtNobt move.l bt_BBOffset(a3),my_TrkOfs(a5) move.l bt_BBPicLen(a3),my_PicLen(a5) move.l bt_BBModLen(a3),my_ModLen(a5) move.l bt_BBBlkLen(a3),d0 move.l d0,my_TrkLen(a5) move.l #$10003,d1 EXE AllocMem tst.l d0 beq BT_Error move.l d0,my_TrkBuf(a5) lea TxXecute(pc),a0 bsr BT_Print lea my_StdIOReq(a5),a1 ;BootBlock einlesen move.w #CMD_READ,io_Command(a1) move.l my_TrkLen(a5),io_Length(a1) move.l my_TrkBuf(a5),io_Data(a1) move.l my_TrkOfs(a5),io_Offset(a1) bsr.s BT_DoIO bne.s .Skip movem.l a0-a6/d0-d7,-(sp) move.l my_TrkBuf(a5),d7 add.l #PM_LEN+1024,d7 ;Iff/Mod/BB-Routine übspr. movea.l d7,a0 ;Adr. Pic movea.l a0,a1 move.l my_PicLen(a5),d0 ;Byte Pic move.l my_ModLen(a5),d1 beq.s .0 movea.l d7,a1 adda.l d0,a1 ;Adr. Mod .0 bsr BT_PM ;Xecute movem.l (sp)+,a0-a6/d0-d7 .Skip rts * ----------------------------------------- * Standart-Ausführung & Test für TD_Command * ----------------------------------------- * BT_DoIO lea my_StdIOReq(a5),a1 EXE DoIO tst.l d0 bne.s .1 move.b io_Error(a1),d0 beq BT_Ok ext.w d0 ext.l d0 .1 bsr PrtDiskerr bsr BT_MotorOFF bra BT_Error * ----------------------------- * Disk-Interrupt aus/anschalten * ----------------------------- * BT_BusyON moveq #0,d7 bra.s BT_BusyDisk BT_BusyOFF moveq #-1,d7 BT_BusyDisk lea TxDrive(pc),a0 move.l a0,d1 DOS DeviceProc move.l d0,d6 beq.s .Skip suba.l a1,a1 EXE FindTask move.l d0,d5 addi.l #$5C,d5 lea my_BusyBuffer+$14(a5),a0 lea my_BusyBuffer(a5),a1 move.l a0,10(a1) move.l a1,(a0) move.l d5,4(a0) move.l #$1F,8(a0) move.l d7,$14(a0) movea.l d6,a0 LIB PutMsg movea.l d5,a0 LIB WaitPort movea.l d5,a0 LIB GetMsg .Skip rts * -------------------------------------------- * Berechnung und eintragen der BootBlock-CkSum * * In: A0 = BootBlock-Daten * -------------------------------------------- * BT_CalcBBSum movem.l a1/d0/d1,-(sp) movea.l a0,a1 clr.l 4(a0) moveq #0,d0 move.w #$FF,d1 .1 add.l (a1)+,d0 bcc.s .2 addq.l #1,d0 .2 dbf d1,.1 not.l d0 move.l d0,4(a0) movem.l (sp)+,a1/d0/d1 rts * ------------------------------------------- * Berechnung der BitMap-CkSum zur Überprüfung * * In: A0 = BitMap-Daten * Out: D0 = CkSum * * my_Error <> 0 bei nicht Übereinstimmung * ------------------------------------------- * BT_CalcBMSum movem.l a1/d1,-(sp) bsr BT_Ok lea 4(a0),a1 move.w #$7E,d1 moveq.l #0,d0 .1 sub.l (a1)+,d0 dbf d1,.1 cmp.l (a0),d0 beq.s .2 bsr BT_Error .2 movem.l (sp)+,a1/d1 rts * ----------------------------------------------------- * BitMap-Block einlesen & BitMap installieren * * In: D7 = Bit-Modus ($FFFFFFFF=Belegen / $0=Freigeben) * ----------------------------------------------------- * BT_SetBitMap lea my_WorkBuffer(a5),a3 lea my_StdIOReq(a5),a1 ;RootBlock einlesen move.w #CMD_READ,io_Command(a1) move.l #512,io_Length(a1) move.l a3,io_Data(a1) move.l #880*512,io_Offset(a1) ;RootBlock-Pos. auf Disk bsr BT_DoIO bne.s .Skip tst.l 312(a3) ;BitMap gültig? beq BT_MotorOFF ;Nein! move.l 316(a3),d0 ;Zeiger auf BitMapBlock mulu #512,d0 move.l d0,io_Offset(a1) ;BitMapBlock-Pos. auf Disk bsr BT_DoIO bne.s .Skip movea.l a3,a0 ;Zeiger auf BM-Daten bsr.s BT_CalcBMSum ;BM-CkSum überprüfen tst.b my_Error(a5) ;Fehler? bne.s .Skip ;Ja, keine DOS-Disk lea 4(a3),a0 ;BitMuster-Pos. move.l my_BitNum(a5),d0 ;Anzahl Bytes divu #512,d0 ;In Blockanzahl umrechnen subi.l #2,d0 ;BB nicht nochmals .1 move.l d7,d1 ;Def. BitMuster $FFFFFFFF/$0 moveq #32,d2 ;Letzte BitMuster-Pos. .2 subq #1,d2 ;BitPos - 1 bchg d2,d1 ;Block belegt/frei markieren tst.l d2 ;Schon BitPos = 0? bne.s .3 ;Nein move.l d1,(a0)+ ;Belegungs-Bits installieren bra.s .1 ;Von vorn .3 dbf d0,.2 ;Wiederhole bis Blks markiert tst.l d7 bne.s .4 tst.l d7 ;Opt -R bne.s .4 ;Nein or.l (a0),d1 ;Letztes BM-Muster verknüpfen .4 move.l d1,(a0) ;Letzte Belegungsmarkierung movea.l a3,a0 ;Zeiger auf BM-Daten bsr BT_CalcBMSum ;BM-CkSum berechnen move.l d0,(a3) ;Eintragen move.w #CMD_WRITE,io_Command(a1) bsr BT_DoIO bne.s .Skip move.w #CMD_UPDATE,io_Command(a1) bsr BT_DoIO bne.s .Skip bra BT_Ok .Skip rts * ------------------------ * Test ob Disk eingelegt * * my_Error <> 0 für Fehler * ------------------------ * BT_DiskIN lea my_StdIOReq(a5),a1 move.w #TD_CHANGESTATE,io_Command(a1) EXE DoIO tst.l io_Actual(a1) beq BT_Ok lea TxNoDisk(pc),a0 ;Keine Disk eingelegt bsr BT_Print bra BT_Error * ----------------------------- * Test ob Disk schreibgeschützt * * my_Error <> 0 für Fehler * ----------------------------- * BT_DiskWP lea my_StdIOReq(a5),a1 move.w #TD_PROSTATUS,io_Command(a1) EXE DoIO tst.l io_Actual(a1) beq BT_Ok lea TxDiskPro(pc),a0 ;Disk ist schreibgeschützt bsr BT_Print bra BT_Error * ------------------------------------------ * TD_Head auf Position 0 & Motor ausschalten * ------------------------------------------ * BT_MotorOFF lea my_StdIOReq(a5),a1 move.w #TD_SEEK,io_Command(a1) clr.l io_Offset(a1) EXE DoIO move.w #TD_MOTOR,io_Command(a1) clr.l io_Length(a1) LAB DoIO * ----------------------------------------- * Start: Auf Betätigung von [RETURN] warten * ----------------------------------------- * BT_WaitKey movem.l a0-a6/d0-d3,-(sp) bsr BT_BusyOFF ;Disk-Interrupt aus lea TxWaitKey(pc),a0 ;Text ausgeben bsr BT_Print lea TxDrive(pc),a0 bsr BT_Print DOS Output move.l d0,d1 lea my_WorkBuffer(a5),a0 ;Platz für Read move.l a0,d2 moveq.l #1,d3 LIB Read ;Auf [RETURN] warten movem.l (sp)+,a0-a6/d0-d3 rts * ---------------------------------------- * Ende: Auf Betätigung von [RETURN] warten * ---------------------------------------- * BT_ExitKey movem.l a0-a6/d0-d3,-(sp) tst.b my_Error(a5) ;Fehler? bne.s .0 ;Joo! nicht warten lea TxExitKey(pc),a0 bsr BT_Print lea TxDrive(pc),a0 bsr BT_Print DOS Output move.l d0,d1 lea my_WorkBuffer(a5),a0 move.l a0,d2 moveq.l #1,d3 LIB Read bsr PrtThatsAll .0 bsr BT_BusyON ;Disk-Interrupt wieder an movem.l (sp)+,a0-a6/d0-d3 rts * ------------------------------------------------------- * String-Kette mit Formatelementen formatieren & ausgeben * * In: A0 = Ausgabe-String der Formatdaten * A1 = Formatdaten für Ausgabe-String * ------------------------------------------------------- * BT_FmtStr movem.l a0-a6/d0-d7,-(sp) lea .1(pc),a2 lea my_FmtBuffer(a5),a3 EXE RawDoFmt lea my_FmtBuffer(a5),a0 bsr BT_Print movem.l (sp)+,a0-a6/d0-d7 rts .1 move.b d0,(a3)+ rts * ---------------------- * Allgemeine Textausgabe * ---------------------- * PrtDiskerr lea TxDiskErr(pc),a0 ;Disk defekt lea my_WorkBuffer(a5),a1 move.l d0,(a1) bsr.s BT_FmtStr lea my_StdIOReq(a5),a1 bra BT_Error PrtBTinfo lea TxMessage(pc),a0 ;Installations-Info lea my_WorkBuffer(a5),a1 move.l my_TrkLen(a5),d0 subi.l #1024,d0 ;BB nicht mitgerechnet move.l d0,4(a1) ;Bytes reserviert divu #512,d0 move.l d0,(a1) ;Blocks reserviert bra.s BT_FmtStr PrtNopic lea TxFileErr(pc),a0 ;Bild nicht vorhanden lea my_WorkBuffer(a5),a1 move.l my_PicName(a5),(a1) bsr.s BT_FmtStr bra BT_Error PrtNomod lea TxFileErr(pc),a0 ;Module nicht vorhanden lea my_WorkBuffer(a5),a1 move.l my_ModName(a5),(a1) bsr.s BT_FmtStr bra.s BT_Error PrtThatsAll lea TxThatsAll(pc),a0 bra.s BT_Print PrtBadoffset lea TxBadOffset(pc),a0 ;Falsches Block-Offset bra.s BT_Print PrtUsage lea TxUsage(pc),a0 ;Keine gültigen Parameter bra.s BT_Print PrtDeverr lea TxDevErr(pc),a0 ;Laufwerk nicht vorhanden bra.s BT_Print PrtMemout lea TxMemOut(pc),a0 ;Nicht genügend Speicher bsr.s BT_Print bra.s BT_Error PrtReadbb lea TxReadBB(pc),a0 ;Alten BootBlock sichern bra.s BT_Print PrtSetbm lea TxSetBMap(pc),a0 ;BitMap belegen bra.s BT_Print PrtNobt lea TxNoBT(pc),a0 ;Keine BT Disk bsr.s BT_Print bra.s BT_Error PrtBThead lea TxHeadLine(pc),a0 ;BootTwister Kopfzeile * ------------------------------ * Textausgabe » NULL Byte Test « * * In: A0 = TextPtr * ------------------------------ * BT_Print movem.l a1-a6/d0-d3,-(sp) move.l a0,d2 moveq #0,d3 .1 tst.b (a0)+ beq.s .2 addq.l #1,d3 bra.s .1 .2 DOS Output move.l d0,d1 LIB Write movem.l (sp)+,a1-a6/d0-d3 rts * ------------------ * Fehler-Flag setzen * ------------------ * BT_Error move.b #$FF,my_Error(a5) rts BT_Ok move.b #0,my_Error(a5) rts * ------------ * Programmende * ------------ * BT_Finish movea.l $4.w,a6 ;ExecBase move.l my_DosBase(a5),d0 ;DosLib beq.s .1 ;Konnte nicht geöffnet werden movea.l d0,a1 LIB CloseLibrary .1 lea my_StdIOReq(a5),a1 ;DeviceStruc tst.w io_Command(a1) ;Wurde Kommando übergeben beq.s .2 ;Nein! Fehler aufgetreten bsr BT_MotorOFF LIB CloseDevice .2 tst.l my_TrkBuf(a5) ;TrackBuffer freigeben ble.s .3 movea.l my_TrkBuf(a5),a1 move.l my_TrkLen(a5),d0 LIB FreeMem .3 move.l #my_SIZEOF,d0 ;DatenStruc freigeben movea.l a5,a1 LIB FreeMem BT_Exit RTS * --------------- * BT Datenbereich * --------------- * TxUsage dc.b 10 dc.b 'Usage: ',$9B,'33mBT',$9B,'0m - [-] [-]',10,10 dc.b ' drive = DF0: up to DF3:',10,10 dc.b ' file = -P file - install IFF picture',10 dc.b ' -M file - use ST module additional',10,10 dc.b ' pos = -T #trk - start at track 1 up to 158',10 dc.b ' -B #blk - start at block 2 up to 1756',10,10 dc.b ' opt = -C - checks for free tracks/blocks on disk',10 dc.b ' -E - executes old bootblock after work',10 dc.b ' -I - infos about installed data on disk',10 dc.b ' -R - remove BootTwister and restore disk',10 dc.b ' -S - swap flag for execute old bootblock',10 dc.b ' -X - execute BootTwister of installed disk',10,10 dc.b ' Files could be in PowerPacker data format',10,10 dc.b $9B,'33mBT',$9B,'0m' VER dc.b $9B,'33mFD',$9B,'0m © 2002 by Volker Stepprath, Testaware',10,10,0 TxHeadLine dc.b 10 dc.b '- - - - - - - - - - - - - - - - - - -',10 dc.b ' BootTwister ® by Volker Stepprath',10 dc.b 'BootTwister' VER dc.b '© 2002 by Testaware',10 dc.b '- - - - - - - - - - - - - - - - - - -',10,10,0 TxRestore dc.b $9B,'33mRestore',$9B,'0m: Remove BootTwister from disk',10,0 TxCleanup dc.b $9B,'33mCleanup',$9B,'0m: Format restored blocks on disk',10,0 TxLoadPic dc.b $9B,'33mLoading',$9B,'0m: IFF picture ',$22,'%s',$22,10,0 TxLoadMod dc.b $9B,'33mLoading',$9B,'0m: ST module ',$22,'%s',$22,10,0 TxReadBB dc.b $9B,'33mReading',$9B,'0m: Preserve boot to execute/restore',10,0 TxSetBMap dc.b $9B,'33mReserve',$9B,'0m: Allocate used blocks in BitMap',10,0 TxWaitKey dc.b $9B,'33mRequest',$9B,'0m: Insert disk to twist in ',0 TxExitKey dc.b $9B,'33mRequest',$9B,'0m: Remove disk to finish from ',0 TxCheckTrk dc.b $9B,'33mTesting',$9B,'0m: Track %d, Block %d to %d',10,$B,0 TxFreeTrk dc.b $9B,'33mUnused!',$9B,'0m: Track %d, Block %d to %d',10,0 TxSwapFlag dc.b $9B,'33mSwaping',$9B,'0m: Swap execute old bootblock flag',10,0 TxXecute dc.b $9B,'33mExecute',$9B,'0m: Start twisted bootblock',10,0 even TxDrive dc.b 'DF0:',0 TxFreeLine dc.b $9B,$4B,0 TxInfo dc.b 10 dc.b $9B,'33mInfo ',$9B,'0m: Installed position%9ld block',10 dc.b ' Length of picture%10ld bytes',10 dc.b ' Length of module%11ld bytes',10 dc.b ' Total installed data%7ld bytes',10,10 dc.b $9B,'33mMessage',$9B,'0m: Old boot will %sbe execute!',10,10,0 TxInfoNOT dc.b 'not ',0 TxMessage dc.b $9B,'33mMessage',$9B,'0m: %ld blocks (%ld bytes) installed',10,0 TxThatsAll dc.b 10,'That`s all for now, bye.',10,10,0 TxDevErr dc.b 7,$9B,'33mError',$9B,'0m: Drive not available',10,10,7,0 TxFileErr dc.b 7,$9B,'33mError',$9B,'0m: Can`t open ',$22,'%s',$22,10,10,7,0 TxBadOffset dc.b 7,$9B,'33mError',$9B,'0m: Bad track/blocknumber',10,10,7,0 TxMemOut dc.b 10,7,$9B,'33mError',$9B,'0m: Out of memory',10,10,7,0 TxNoDisk dc.b 10,7,$9B,'33mError',$9B,'0m: No disk in drive',10,10,7,0 TxDiskPro dc.b 10,7,$9B,'33mError',$9B,'0m: Disk is write protected',10,10,7,0 TxNoBT dc.b 10,7,$9B,'33mError',$9B,'0m: Not a BootTwister installed disk',10,10,7,0 TxDiskErr dc.b 10,7,$9B,'33mError',$9B,'0m: Fatal TD_IOERR %ld occurred',10,10,7,0 cnop 0,4 ***************************************************************** ******** Boot-Routine für BootTwister mit Standart-Boot ********* ***************************************************************** RsReset bb_IOReply rs.l 8 bb_StdIOReq rs.b 48 bb_BufLen rs.l 1 bb_Buffer rs.l 1 bb_SIZEOF rs.w 0 BT_BB dc.l $444F5300 ;00 DOS0 dc.l $00000000 ;04 CheckSum dc.l $00000370 ;08 RootBlock bra.s BB_Start ;12 cnop 0,4 bb_Offset dc.l 1024 ;16 CMD_READ Offset (Def.1024) bb_PicLen dc.l 0 ;20 Länge des Bildes bb_ModLen dc.l 0 ;24 Länge des Modules (auch Flag) bb_BlkLen dc.l 0 ;28 Länge der zu lesenden Bytes bb_ExecBB dc.l 0 ;32 Flag ob BB ausgeführt wird bb_ID dc.b 'BT98' ;36 BT-Markierung BB_Start lea bb_ExpLib(pc),a1 moveq #37,d0 LIB OpenLibrary tst.l d0 beq.s .no_explib movea.l d0,a1 bset #6,34(a1) LIB CloseLibrary .no_explib lea bb_DosLib(pc),a1 LIB FindResident tst.l d0 beq.s .not_found movea.l d0,a0 movea.l 22(a0),a0 moveq #0,d0 bra.s BB ;Boot-Program ausführen .not_found moveq #-1,d0 rts BB movem.l d0-d7/a0-a6,-(sp) move.w #0,$DFF180 ;Display schwarz moveq #bb_SIZEOF,d0 lea bb_BlkLen(pc),a3 add.l (a3),d0 move.l #$10003,d1 LIB AllocMem tst.l d0 beq BB_End movea.l d0,a5 move.l (a3),bb_BufLen(a5) BB_OpenDev suba.l a1,a1 LIB FindTask lea bb_IOReply(a5),a2 move.l d0,16(a2) lea bb_StdIOReq(a5),a1 move.l a2,14(a1) lea bb_TrkDev(pc),a0 moveq #0,d0 ;Laufwerk immer DF0: moveq #0,d1 LIB OpenDevice lea bb_Buffer(a5),a3 move.w #CMD_READ,io_Command(a1) lea bb_BlkLen(pc),a0 move.l (a0),io_Length(a1) move.l a3,io_Data(a1) lea bb_Offset(pc),a0 move.l (a0),io_Offset(a1) LIB DoIO tst.b io_Error(a1) beq.s .1 bra.s BB_Finish .1 bsr.s BB_MotorOFF movem.l a0-a6/d0-d7,-(sp) adda.l #PM_LEN+1024,a3 ;Iff/Mod/BB-Routine übspr. movea.l a3,a0 ;Adr. Pic lea bb_PicLen(pc),a2 move.l (a2),d0 ;Byt. Pic lea bb_ModLen(pc),a2 move.l (a2),d1 ;Byt. Mod movea.l a3,a1 adda.l d0,a1 ;Adr. Mod jsr bb_Buffer+1024(a5) ;Alten BB überspringen movem.l (sp)+,a0-a6/d0-d7 BB_ExeBoot lea bb_ExecBB(pc),a0 ;Test ob alt. BB ausführen tst.l (a0) beq.s BB_Finish ;Nein movem.l a0-a6,-(sp) jsr bb_Buffer+12(a5) ;Alt. BB ausführen movem.l (sp)+,a0-a6 BB_Finish bsr.s BB_MotorOFF LIB CloseDevice movea.l a5,a1 moveq #bb_SIZEOF,d0 add.l bb_BufLen(a5),d0 LIB FreeMem BB_End movem.l (sp)+,d0-d7/a0-a6 rts BB_MotorOFF lea bb_StdIOReq(a5),a1 move.w #TD_SEEK,io_Command(a1) clr.l io_Length(a1) LIB DoIO move.w #TD_MOTOR,io_Command(a1) clr.l io_Length(a1) LAB DoIO bb_DosLib dc.b 'dos.library',0 bb_ExpLib dc.b 'expansion.library',0 bb_TrkDev dc.b 'trackdisk.device',0 dcb.b 15,0 bb_Mess dc.b 'BootTwister' VER dc.b '(c) by Testaware ' dc.b '- This boot is NOT a Virus!!!' cnop 0,4 BB_LEN equ *-BT_BB ***************************************************************** ********** Show IFF- / Play Mod-Routine für BootTwister ********* ***************************************************************** ;Macros für BT-ShowIff / PlayMod PM_INT MACRO movea.l pm_IntBase(a5),a6 jsr _LVO\1(a6) ENDM PM_GFX MACRO movea.l pm_GfxBase(a5),a6 jsr _LVO\1(a6) ENDM ;ShowIFF/PlayMOD spezifische Struktur RsReset pm_IntBase rs.l 1 pm_GfxBase rs.l 1 pm_PicBuf rs.l 1 pm_PicLen rs.l 1 pm_PicUpkLen rs.l 1 pm_ModBuf rs.l 1 pm_ModLen rs.l 1 pm_ModUpkLen rs.l 1 pm_ModPlay rs.l 1 pm_PackBuf rs.l 1 pm_PackLen rs.l 1 pm_UnpackBuf rs.l 1 pm_UnpackLen rs.l 1 pm_NewWind rs.l nw_SIZE pm_WindPtr rs.l 1 pm_NewScrn rs.b ns_SIZEOF pm_ScrnPtr rs.l 1 pm_PlanPtr rs.l 8 pm_Palette rs.l 1 pm_OwnMouse rs.b 16*16 pm_PkMode rs.l 1 ;Struktur für mt_PlayRoutine mt_module rs.l 1 mt_partnote rs.l 1 mt_partnrplay rs.l 1 mt_counter rs.l 1 mt_partpoint rs.l 1 mt_samples rs.l 1 mt_sample1 rs.l $1F mt_sixpack rs.l 1 mt_maxpart rs.w 1 mt_dmacon rs.w 1 mt_status rs.w 1 mt_type rs.w 1 pm_SIZEOF rs.w 0 PKMODE_NORMAL equ 0 ;Unkomprimiert PKMODE_COMPRESSED equ 1 ;Komprimiert PKMODE_AMIGABASIC equ 2 ;AmigaBASIC BitMap * ----------------------------------- * BootTwister ShowIFF/PlayMOD-Routine * * In: A0 = Adresse von Pic * A1 = Adresse von Mod * D0 = Größe in Bytes von Pic * D1 = Größe in Bytes von Mod * ----------------------------------- * BT_PM movem.l a0/a1/d0/d1,-(sp) move.l #pm_SIZEOF,d0 move.l #$10003,d1 EXE AllocMem move.l d0,d2 movem.l (sp)+,a0/a1/d0/d1 tst.l d2 ble PM_Error movea.l d2,a5 move.l a0,pm_PicBuf(a5) move.l d0,pm_PicLen(a5) move.l a1,pm_ModBuf(a5) move.l d1,pm_ModLen(a5) lea pm_IntLib(pc),a1 moveq #0,d0 LIB OpenLibrary move.l d0,pm_IntBase(a5) lea pm_GfxLib(pc),a1 moveq #0,d0 LIB OpenLibrary move.l d0,pm_GfxBase(a5) movea.l pm_PicBuf(a5),a0 ;Gepackter Buffer move.l pm_PicLen(a5),d0 ;Gepackte Byte-Größe bsr PM_Decrunch ;Entpacken bne.s PM_Finish ;Wenn Fehler Ende! move.l pm_UnpackLen(a5),pm_PicLen(a5) ;Entpackte Byte-Größe move.l pm_UnpackBuf(a5),d0 cmp.l pm_PicBuf(a5),d0 ;Gleiche Adresse? beq.s .1 ;Nein! Entpackt! move.l pm_UnpackLen(a5),pm_PicUpkLen(a5) .1 move.l pm_UnpackBuf(a5),pm_PicBuf(a5) ;Bilddaten movea.l pm_ModBuf(a5),a0 move.l pm_ModLen(a5),d0 beq.s .3 ;Kein Module abspielen bsr PM_Decrunch bne.s PM_Finish move.l pm_UnpackLen(a5),pm_ModLen(a5) move.l pm_UnpackBuf(a5),d0 cmp.l pm_ModBuf(a5),d0 beq.s .2 move.l pm_UnpackLen(a5),pm_ModUpkLen(a5) .2 move.l pm_UnpackBuf(a5),pm_ModBuf(a5) .3 bsr.s PM_ShowIff * -------------------------------------------------------- * Alle geöffneten Libraries schließen und Programm beenden * -------------------------------------------------------- * PM_Finish movea.l pm_IntBase(a5),a1 EXE CloseLibrary movea.l pm_GfxBase(a5),a1 LIB CloseLibrary move.l pm_PicUpkLen(a5),d0 beq.s .1 movea.l pm_PicBuf(a5),a1 LIB FreeMem .1 move.l pm_ModUpkLen(a5),d0 beq.s .2 movea.l pm_ModBuf(a5),a1 LIB FreeMem .2 movea.l a5,a1 move.l #pm_SIZEOF,d0 LAB FreeMem * ---------------------------------- * Zeige das IFF - Format (ILBM/ACBM) * ---------------------------------- * PM_ShowIff movea.l pm_PicBuf(a5),a1 ;Datei-Buffer global in A1 cmpi.l #'BMHD',12(a1) ;IFF - Grafikformat? bne PM_Error ;Nein! chunk0 lea 16(a1),a1 ;ID_BMHD überspringen lea pm_NewScrn(a5),a0 move.w 4(a1),ns_Width(a0) move.w 6(a1),ns_Height(a0) move.b 12(a1),ns_Depth+1(a0) move.b 14(a1),pm_PkMode(a5) ;Kompressionsflag clr.w ns_ViewModes(a0) ;Def. ViewMode installieren cmpi.w #320,ns_Width(a0) bls.s .1 ori.w #V_HIRES,ns_ViewModes(a0) .1 cmpi.w #256,ns_Height(a0) bls.s .2 ori.w #V_LACE,ns_ViewModes(a0) .2 adda.l (a1)+,a1 chunk1 cmpi.l #'CMAP',(a1) bne.s chunk2 lea 4(a1),a2 ;Farbtabelle -> A2 move.l a2,pm_Palette(a5) cmp.l #$C0,(a2) ;HAM-Modus? bne.s chunk2 ;Nein! ori.w #V_HAM,ns_ViewModes(a0) ;HAM-Flag einblenden chunk2 cmpi.l #'CAMG',(a1) bne.s chunk3 move.w 10(a1),ns_ViewModes(a0) chunk3 cmpi.l #'ABIT',(a1) ;Etwa das AmigaBASIC Format? bne.s chunk4 ;Nein! move.b #PKMODE_AMIGABASIC,pm_PkMode(a5) lea 4(a1),a1 ;Zeiger auf Chunk-Größe bra.s PM_ViewIff ;Grafik zeigen chunk4 cmpi.l #'BODY',(a1)+ ;Normales IFF-Format? beq.s PM_ViewIff ;Ja! adda.l (a1)+,a1 ;Zeiger auf nächsten Chunk bra.s chunk1 ;Weiter suchen PM_ViewIff lea 4(a1),a4 ;Zeiger auf Gfxdaten -> A4 bsr PM_OpenScrn ;IFF-Screen öffnen bne PM_Error ;Wenn Fehler dann Ende! movea.l pm_ScrnPtr(a5),a3 lea sc_BitMap(a3),a3 cmpi.b #PKMODE_NORMAL,pm_PkMode(a5) beq.s PM_NormIff cmpi.b #PKMODE_COMPRESSED,pm_PkMode(a5) beq.s PM_PackIff cmpi.b #PKMODE_AMIGABASIC,pm_PkMode(a5) beq.s PM_AbasIff PM_NormIff moveq.l #0,d3 move.w bm_BytesPerRow(a3),d5 move.w bm_Rows(a3),d6 ext.l d5 .1 moveq.l #bm_Planes,d4 .2 move.l (a3,d4.l),d0 beq.s .3 movea.l a4,a0 add.l d3,d0 movea.l d0,a1 move.l d5,d0 EXE CopyMem adda.l d5,a4 addq.l #4,d4 bra.s .2 .3 subq.w #1,d6 beq.s PM_SetCols add.l d5,d3 bra.s .1 PM_PackIff lea bm_Planes(a3),a0 lea pm_PlanPtr(a5),a1 .1 move.l (a0)+,(a1)+ ;BitMap Zeiger kopieren bne.s .1 move.w bm_Rows(a3),d6 .2 move.b bm_Depth(a3),d5 lea pm_PlanPtr(a5),a1 .3 movea.l (a1),a0 move.w bm_BytesPerRow(a3),d2 .4 move.b (a4)+,d0 bmi.s .6 .5 move.b (a4)+,(a0)+ subq.w #1,d2 subq.b #1,d0 bpl.s .5 bra.s .8 .6 neg.b d0 bmi.s .4 move.b (a4)+,d3 .7 move.b d3,(a0)+ subq.w #1,d2 subq.b #1,d0 bpl.s .7 .8 tst.w d2 bne.s .4 move.l a0,(a1)+ subq.b #1,d5 ;bm_Depth-1 bne.s .3 subq.w #1,d6 ;bm_Rows-1 bne.s .2 bra.s PM_SetCols PM_AbasIff move.w bm_BytesPerRow(a3),d7 mulu bm_Rows(a3),d7 ;Größe der Planes -> D7 lea bm_Planes(a3),a2 .1 movea.l a4,a0 ;Zeiger Grafikdaten move.l (a2)+,d0 ;Zeiger BitPlane beq.s PM_SetCols ;Keine weitere Plane movea.l d0,a1 move.l d7,d0 EXE CopyMem adda.l d7,a4 bra.s .1 PM_SetCols movea.l pm_Palette(a5),a2 move.l (a2)+,d7 divu #3,d7 moveq.l #0,d6 .1 movea.l pm_ScrnPtr(a5),a0 lea sc_ViewPort(a0),a0 move.l d6,d0 moveq.l #0,d1 move.b (a2)+,d1 lsr.b #4,d1 moveq.l #0,d2 move.b (a2)+,d2 lsr.b #4,d2 moveq.l #0,d3 move.b (a2)+,d3 lsr.b #4,d3 PM_GFX SetRGB4 addq.l #1,d6 dbf d7,.1 bra.s PM_WaitScrn * --------------------------------------- * Screen/Window öffnen bzw. Warteschleife * --------------------------------------- * PM_OpenScrn lea pm_NewScrn(a5),a0 move.w #CUSTOMSCREEN|SCREENQUIET,ns_Type(a0) PM_INT OpenScreen move.l d0,pm_ScrnPtr(a5) beq PM_Error bsr PM_ColsOff lea pm_NewWind(a5),a0 lea pm_NewScrn(a5),a1 move.w ns_Width(a1),nw_Width(a0) move.w ns_Height(a1),nw_Height(a0) move.l #ACTIVATE,nw_Flags(a0) move.l pm_ScrnPtr(a5),nw_Screen(a0) move.w #CUSTOMSCREEN,nw_Type(a0) PM_INT OpenWindow move.l d0,pm_WindPtr(a5) beq.s .1 bsr PM_MouseOFF bra PM_OK .1 bsr.s PM_CloseScrn bra PM_Error PM_WaitScrn tst.l pm_ModLen(a5) ;Module vorhanden? beq.s .1 ;Nein! movea.l pm_ModBuf(a5),a0 ;Ja! bsr mt_init ;Module initialisieren .1 tst.l pm_ModLen(a5) ;Module vorhanden? beq.s .2 ;Nein! bsr mt_music ;Module spielen .2 PM_GFX WaitTOF ;Synchronisation btst #6,$BFE001 ;Linke Maustaste? bne.s .1 ;Nein! tst.l pm_ModLen(a5) ;Module vorhanden? beq.s .3 ;Nein! bsr mt_end ;Module freigeben .3 bsr.s PM_ColsOff ;Alle Farben aus PM_CloseWin bsr.s PM_MouseON movea.l pm_WindPtr(a5),a0 LIB CloseWindow PM_CloseScrn movea.l pm_ScrnPtr(a5),a0 LIB ScreenToBack movea.l pm_ScrnPtr(a5),a0 LIB CloseScreen moveq #10,d7 bsr.s PM_WaitVBL bra PM_OK * -------------------------------------------- * Farben des Screens auf NULL setzen (schwarz) * -------------------------------------------- * PM_ColsOff movea.l pm_Palette(a5),a2 move.l (a2)+,d7 divu #3,d7 cmpi.l #31,d7 bgt.s .1 moveq #31,d7 .1 moveq.l #0,d6 .2 movea.l pm_ScrnPtr(a5),a0 lea sc_ViewPort(a0),a0 move.l d6,d0 ;Farbregister moveq #0,d1 ;R moveq #0,d2 ;G moveq #0,d3 ;B PM_GFX SetRGB4 ;Schwarz addq.l #1,d6 dbf d7,.2 moveq #25,d7 * ------------------------------------- * Warten auf Rasterstrahl-Position oben * * D7 <= Anzahl VBL's * ------------------------------------- * PM_WaitVBL PM_GFX WaitTOF dbf d7,PM_WaitVBL rts * ------------------------------- * Mauszeiger aus- bzw. anschalten * ------------------------------- * PM_MouseOFF movea.l pm_WindPtr(a5),a0 lea pm_OwnMouse(a5),a1 moveq #0,d0 moveq #0,d1 moveq #0,d2 moveq #0,d3 PM_INT SetPointer rts PM_MouseON movea.l pm_WindPtr(a5),a0 PM_INT ClearPointer rts * ----------------------------- * SoundTracker-Format abspielen * * In: A0 = Zeiger auf Module * ----------------------------- * mt_init bset #1,$BFE001 move.l a0,mt_module(a5) move.l #6,mt_sixpack(a5) clr.w mt_type(a5) cmp.b #'x',$1D7(a0) beq.s mt_old move.w #-1,mt_type(a5) mt_old lea $01D8(a0),a0 tst.w mt_type(a5) beq.s mt_old2 lea $01E0(a0),a0 mt_old2 move.l #$0080,d0 moveq #0,d1 mt_init1 move.l d1,d2 subq.w #1,d0 mt_init2 move.b (a0)+,d1 cmp.b d2,d1 bgt.s mt_init1 dbf d0,mt_init2 addq.b #1,d2 mt_init3 movea.l mt_module(a5),a0 lea mt_sample1(a5),a1 asl.l #$0008,d2 asl.l #$0002,d2 add.l #$0258,d2 moveq #$000E,d0 tst.w mt_type(a5) beq.s mt_old3 add.l #$01E4,d2 moveq #$001E,d0 mt_old3 add.l a0,d2 mt_init4 move.l d2,(a1)+ moveq #0,d1 move.w 42(a0),d1 asl.l #1,d1 add.l d1,d2 lea $001E(a0),a0 dbf d0,mt_init4 lea mt_sample1(a5),a0 moveq #0,d0 mt_clear movea.l (a0,d0),a1 clr.l (a1) addq.l #4,d0 cmp.l #$003C,d0 blo.s mt_clear tst.w mt_type(a5) beq.s mt_old4 cmp.l #$007C,d0 blo.s mt_clear mt_old4 clr.w $DFF0A8 clr.w $DFF0B8 clr.w $DFF0C8 clr.w $DFF0D8 clr.l mt_partnrplay(a5) clr.l mt_partnote(a5) clr.l mt_partpoint(a5) movea.l mt_module(a5),a0 move.b $01D6(a0),d0 tst.w mt_type(a5) beq.s mt_old5 move.b $03B6(a0),d0 mt_old5 move.b d0,mt_maxpart+1(a5) rts mt_end clr.w $DFF0A8 clr.w $DFF0B8 clr.w $DFF0C8 clr.w $DFF0D8 move.w #$000F,$DFF096 rts mt_music addq.l #1,mt_counter(a5) move.l mt_sixpack(a5),d0 cmp.l mt_counter(a5),d0 bne.s mt_notsix clr.l mt_counter(a5) bra mt_rout2 mt_notsix lea mt_aud1temp(pc),a6 tst.b 3(a6) beq.s mt_arp1 lea $DFF0A0,a4 bsr.s mt_arprout mt_arp1 lea mt_aud2temp(pc),a6 tst.b 3(a6) beq.s mt_arp2 lea $DFF0B0,a4 bsr.s mt_arprout mt_arp2 lea mt_aud3temp(pc),a6 tst.b 3(a6) beq.s mt_arp3 lea $DFF0C0,a4 bsr.s mt_arprout mt_arp3 lea mt_aud4temp(pc),a6 tst.b 3(a6) beq.s mt_arp4 lea $DFF0D0,a4 bra.s mt_arprout mt_arp4 rts mt_arprout move.b 2(a6),d0 and.b #$000F,d0 tst.b d0 beq.s mt_arpegrt cmp.b #1,d0 beq.s mt_portup cmp.b #2,d0 beq.s mt_portdwn rts mt_portup moveq #0,d0 move.b 3(a6),d0 sub.w d0,22(a6) cmp.w #$0071,22(a6) bpl.s mt_ok1 move.w #$0071,22(a6) mt_ok1 move.w 22(a6),6(a4) rts mt_portdwn moveq #0,d0 move.b 3(a6),d0 add.w d0,22(a6) cmp.w #$0358,22(a6) bmi.s mt_ok2 move.w #$0358,22(a6) mt_ok2 move.w 22(a6),6(a4) rts mt_arpegrt cmp.l #1,mt_counter(a5) beq.s mt_loop2 cmp.l #2,mt_counter(a5) beq.s mt_loop3 cmp.l #3,mt_counter(a5) beq.s mt_loop4 cmp.l #4,mt_counter(a5) beq.s mt_loop2 cmp.l #5,mt_counter(a5) beq.s mt_loop3 rts mt_loop2 moveq #0,d0 move.b 3(a6),d0 lsr.b #4,d0 bra.s mt_cont mt_loop3 moveq #0,d0 move.b 3(a6),d0 and.b #$000F,d0 bra.s mt_cont mt_loop4 move.w 16(a6),d2 bra.s mt_endpart mt_cont asl.w #1,d0 moveq #0,d1 move.w 16(a6),d1 lea mt_arpeggio(pc),a0 mt_loop5 move.w (a0,d0),d2 cmp.w (a0),d1 beq.s mt_endpart addq.l #2,a0 bra.s mt_loop5 mt_endpart move.w d2,6(a4) rts mt_rout2 movea.l mt_module(a5),a0 lea $000C(a0),a3 lea $01D8(a0),a2 lea $0258(a0),a0 tst.w mt_type(a5) beq.s mt_old6 lea $01E0(a2),a2 lea $01E4(a0),a0 mt_old6 move.l mt_partnrplay(a5),d0 moveq #0,d1 move.b (a2,d0),d1 asl.l #$0008,d1 asl.l #$0002,d1 add.l mt_partnote(a5),d1 move.l d1,mt_partpoint(a5) clr.w mt_dmacon(a5) lea $DFF0A0,a4 lea mt_aud1temp(pc),a6 bsr mt_playit lea $DFF0B0,a4 lea mt_aud2temp(pc),a6 bsr mt_playit lea $DFF0C0,a4 lea mt_aud3temp(pc),a6 bsr mt_playit lea $DFF0D0,a4 lea mt_aud4temp(pc),a6 bsr mt_playit move.w #$01F4,d0 mt_rls dbf d0,mt_rls move.w #$8000,d0 or.w mt_dmacon(a5),d0 move.w d0,$DFF096 lea mt_aud4temp(pc),a6 cmp.w #1,14(a6) bne.s mt_voice3 move.l 10(a6),$DFF0D0 move.w #1,$DFF0D4 mt_voice3 lea mt_aud3temp(pc),a6 cmp.w #1,14(a6) bne.s mt_voice2 move.l 10(a6),$DFF0C0 move.w #1,$DFF0C4 mt_voice2 lea mt_aud2temp(pc),a6 cmp.w #1,14(a6) bne.s mt_voice1 move.l 10(a6),$DFF0B0 move.w #1,$DFF0B4 mt_voice1 lea mt_aud1temp(pc),a6 cmp.w #1,14(a6) bne.s mt_voice0 move.l 10(a6),$DFF0A0 move.w #1,$DFF0A4 mt_voice0 move.l mt_partnote(a5),d0 add.l #$0010,d0 move.l d0,mt_partnote(a5) cmp.l #$0400,d0 bne.s mt_stop mt_higher clr.l mt_partnote(a5) addq.l #1,mt_partnrplay(a5) moveq #0,d0 move.w mt_maxpart(a5),d0 move.l mt_partnrplay(a5),d1 cmp.l d0,d1 bne.s mt_stop clr.l mt_partnrplay(a5) mt_stop tst.w mt_status(a5) beq.s mt_stop2 clr.w mt_status(a5) bra.s mt_higher mt_stop2 rts mt_playit move.l (a0,d1),(a6) addq.l #4,d1 moveq #0,d2 tst.w mt_type(a5) beq.s mt_old7 move.b (a6),d2 and.b #$000F,(a6) lsl.w #4,d2 mt_old7 move.b 2(a6),d2 lsr.w #4,d2 tst.b d2 beq.s mt_nosamplchan moveq #0,d3 lea mt_samples(a5),a1 move.l d2,d4 asl.l #2,d2 mulu #$001E,d4 move.l (a1,d2),4(a6) move.w (a3,d4),8(a6) move.w 2(a3,d4),18(a6) move.w 4(a3,d4),d3 tst.w d3 beq.s mt_displace move.l 4(a6),d2 add.l d3,d2 move.l d2,4(a6) move.l d2,10(a6) move.w 6(a3,d4),8(a6) move.w 6(a3,d4),14(a6) move.w 18(a6),8(a4) bra.s mt_nosamplchan mt_displace move.l 4(a6),d2 add.l d3,d2 move.l d2,10(a6) move.w 6(a3,d4),14(a6) move.w 18(a6),8(a4) mt_nosamplchan tst.w (a6) beq.s mt_retrout move.w (a6),16(a6) move.w 20(a6),$DFF096 move.l 4(a6),(a4) move.w 8(a6),4(a4) move.w (a6),6(a4) move.w 20(a6),d0 or.w d0,mt_dmacon(a5) mt_retrout tst.w (a6) beq.s mt_nonewper move.w (a6),22(a6) mt_nonewper move.b 2(a6),d0 and.b #$000F,d0 cmp.b #11,d0 beq.s mt_posjmp cmp.b #12,d0 beq.s mt_setvol cmp.b #13,d0 beq.s mt_break cmp.b #14,d0 beq.s mt_setfil cmp.b #15,d0 beq.s mt_setspeed rts mt_posjmp not.w mt_status(a5) moveq #0,d0 move.b 3(a6),d0 subq.b #1,d0 move.l d0,mt_partnrplay(a5) rts mt_setvol move.b 3(a6),8(a4) rts mt_break not.w mt_status(a5) rts mt_setfil moveq #0,d0 move.b 3(a6),d0 and.b #$0001,d0 rol.b #$0001,d0 and.b #$00FD,$BFE001 or.b d0,$BFE001 rts mt_setspeed move.b 3(a6),d0 and.b #$000F,d0 beq.s mt_back ext.w d0 ext.l d0 move.l d0,mt_sixpack(a5) clr.l mt_counter(a5) mt_back rts * ------------------------------------------------ * Entpacken wenn Daten im PP-Data Format vorliegen * * In: A0 = Datenbereich * D0 = Byte-Größe * ------------------------------------------------ * PM_Decrunch move.l a0,pm_PackBuf(a5) move.l d0,pm_PackLen(a5) move.l a0,pm_UnpackBuf(a5) ;Für Default move.l d0,pm_UnpackLen(a5) cmpi.l #'PP20',(a0) ;PP-Data Format? beq.s .1 ;Ja! bra PM_OK ;Nein! .1 move.l pm_PackLen(a5),d0 move.l -4(a0,d0.l),d0 lsr.l #8,d0 move.l #$10003,d1 move.l d0,pm_UnpackLen(a5) EXE AllocMem move.l d0,pm_UnpackBuf(a5) ble PM_Error movea.l pm_PackBuf(a5),a0 movea.l pm_UnpackBuf(a5),a1 move.l pm_PackLen(a5),d0 bsr.s PpStart clr.w $DFF180 ;Farbe 0 = schwarz bra PM_OK PpStart lea 4(a0),a3 adda.l d0,a0 movea.l a1,a2 moveq #1,d5 moveq #3,d6 moveq #7,d7 move.l -(a0),d1 tst.b d1 beq.s .1 bsr.s Pp2 subq.b #1,d1 lsr.l d1,d5 .1 lsr.l #8,d1 adda.l d1,a2 Pp1 bsr.s Pp2 bcs.s Pp5 moveq #0,d2 .1 moveq #1,d0 bsr.s Pp4 add.w d1,d2 cmp.w d6,d1 beq.s .1 .2 moveq #7,d0 bsr.s Pp4 move.b d1,-(a2) dbra d2,.2 cmpa.l a2,a1 bcs.s Pp5 rts Pp2 lsr.l #1,d5 beq.s .1 rts .1 move.l -(a0),d5 roxr.l #1,d5 rts Pp3 subq.w #1,d0 Pp4 moveq #0,d1 .1 lsr.l #1,d5 beq.s .3 .2 roxl.l #1,d1 dbra d0,.1 rts .3 move.l -(a0),d5 roxr.l #1,d5 bra.s .2 Pp5 moveq #1,d0 bsr.s Pp4 moveq #0,d0 move.b (a3,d1.w),d0 move.w d1,$DFF180 ;Crunch-FX Farbe 0 move.w d1,d2 cmp.w d6,d2 bne.s .3 bsr.s Pp2 bcs.s .1 moveq #7,d0 .1 bsr.s Pp3 move.w d1,d3 .2 moveq #2,d0 bsr.s Pp4 add.w d1,d2 cmp.w d7,d1 beq.s .2 bra.s .4 .3 bsr.s Pp3 move.w d1,d3 .4 addq.w #1,d2 .5 move.b (a2,d3.w),-(a2) dbra d2,.5 cmpa.l a2,a1 bcs.s Pp1 rts * ----------------------- * Fehler / Ok-Flag setzen * ----------------------- * PM_Error moveq #-1,d0 ;Fehler! rts PM_OK moveq #0,d0 ;Alles geklappt! rts * ----------------------------------- * Datenbereich ST-Abspielroutine usw. * ----------------------------------- * mt_aud1temp ds.w 10 dc.w $0001 ds.w 2 mt_aud2temp ds.w 10 dc.w $0002 ds.w 2 mt_aud3temp ds.w 10 dc.w $0004 ds.w 2 mt_aud4temp ds.w 10 dc.w $0008 ds.w 2 mt_arpeggio dc.w $0358,$0328,$02fa,$02d0,$02a6,$0280,$025c dc.w $023a,$021a,$01fc,$01e0,$01c5,$01ac,$0194,$017d dc.w $0168,$0153,$0140,$012e,$011d,$010d,$00fe,$00f0 dc.w $00e2,$00d6,$00ca,$00be,$00b4,$00aa,$00a0,$0097 dc.w $008f,$0087,$007f,$0078,$0071,$0000,$0000,$0000 pm_IntLib dc.b 'intuition.library',0 pm_GfxLib dc.b 'graphics.library',0 cnop 0,4 PM_LEN equ *-BT_PM END