* TD * By Preben Nielsen * * Based on 'TrackDisplay' on Fish-disk 399 by Olaf Barthel. * * TD is a program that continuously monitors and displays * the current track for each connected floppy disk. * * The size of the window and the use of colors in it depends on * the version of the Kickstart/Workbench (1.2/1.3 vs. 2.?). * * NOTE: There's no need to 'RUN' or 'RUNBACK' this program from the * CLI. It is auto-detaching. * *HISTORY * Made with Hisoft V2.12 * * January: Recieved 'Trackdisplay' on Fish-disk 399. * Nice program Olaf. Thanks. * * V1.0 03-Mar-91: First working version. * 04-Mar-91: Added auto-detaching code. * 07-Mar-91: Uses 'PrintIText' instead of 'Move'/'Text'. Because of * this, my version used nearly twice the amount of * processor-time as the original (according to Xoper). * 15-Mar-91: Now uses 'Move'/'Text'. Code is now larger but faster. * 19-Apr-91: Made some modifications to make it look better * under WB2.0 (haven't actually tried it yet) * V1.1 02-Aug-91: Damned - why didn't anyone tell me that TD looked * awful (strange) under kickstart 1.3. It thought it * it was running under kickstart 2.x, and therefore * changed its own appearance ! Not only didn't it look * good - it also didn't work correctly as a trackdisplay * because of differences between 1.3 and 2.x. Well, all * that has been fixed now. TD looks a lot better than the * original 'TrackDisplay' when running under 2.x. * 08-Aug-91: Now the opened window is as high as the dragbar of * all the other windows on the WB-screen. * V2.0 09-Aug-91: Now TD only shows the drives which are available. * 22-Aug-91: Now TD can perfecty emulate the 2.x way of using * colors in windows. OPT O+ OPT O1+ ; Tells when a branch could be optimised to short OPT i+ ; Tells when '#' is probably missing incdir "AsmInc:" include "P.i" include "Detach.i" include "relMacros.i" include "exec/exec_lib.i" include "exec/memory.i" include "exec/interrupts.i" include "exec/ports.i" include "intuition/intuition.i" include "intuition/intuitionbase.i" include "intuition/intuition_lib.i" include "graphics/graphics_lib.i" include "libraries/dos_lib.i" include "libraries/dos.i" include "libraries/dosextens.i" include "hardware/intbits.i" include "devices/trackdisk.i" * My Unit structure MU_Unit =0 ; Address of drive-unit MU_Number =4 ; Track number MU_SIZE =6 DB EQUR A4 dcDeclare A4 dcAPtr TDProcess ; This process dcAPtr WBenchMsg ; Message from Workbench dcAPtr GraphBase dcAPtr IntuiBase dcAPtr DWindow ; APtr to Window dcAPtr Rp ; APtr to RastPort dcAPtr Up ; APtr to UserPort dcAPtr Font ; APtr to Topaz-80 dcWord StrLength dcArea IOExtTD,IOTD_SIZE ; IOExtTD structure dcArea TDPort,MP_SIZE ; MessagePort structure dcArea TDInterrupt,IS_SIZE ; Interrupt structure dcArea Drive0,MU_SIZE dcArea Drive1,MU_SIZE dcArea Drive2,MU_SIZE dcArea Drive3,MU_SIZE dcWord yPos ; y-position of text in window dcWord Height ; Height of window dcWord xPos ; x-position of text in window dcWord Width ; Width of window dcWord UOffset ; Offset into unit structure (to get to track indicator) dcWord Version ; Kickstart version ID dcArea TDDrives,32 ; Yes, 32. dcEnd Start DetachSingle <'TD'>,4000,0 dcAlloc ; Allocate memory for variables dcReset ; Clear the memory lea TxtAttr(PC),A0 ; To avoid reloc32 hunks lea FontName(PC),A1 move.l A1,(A0) Prepare Exec_Call lea Settings1.3H(PC),A0 cmp.w #34,LIB_VERSION(A6) ble.S 1$ lea Settings2.0H(PC),A0 1$ movem.l (A0),D0-D1 movem.l D0-D1,Version(DB) ; Initialize variables suba.l A1,A1 CallLib FindTask ; Find us move.l D0,TDProcess(DB) move.l D0,A2 tst.l pr_CLI(A2) bne.S GetLibs ; Also works after segment-splitting lea pr_MsgPort(A2),A0 CallLib WaitPort ; wait for a message lea pr_MsgPort(A2),A0 CallLib GetMsg ; then get it move.l D0,WBenchMsg(DB) ; save it for later reply GetLibs lea GfxName(PC),A1 CallLib OldOpenLibrary move.l D0,GraphBase(DB) beq Error lea IntuiName(PC),A1 CallLib OldOpenLibrary move.l D0,IntuiBase(DB) beq Error GetIOExtTD moveq #-1,D0 CallLib AllocSignal cmpi.b #-1,D0 beq Error lea TDPort(DB),A0 clr.b MP+LN_PRI(A0) ; MsgPort->mp_Node.ln_Pri =Pri move.b #NT_MSGPORT,MP+LN_TYPE(A0) ; MsgPort->mp_Node.ln_Type=NT_MSGPORT move.b #PA_SIGNAL,MP_FLAGS(A0) ; MsgPort->mp_Flags =PA_SIGNAL move.b D0,MP_SIGBIT(A0) ; MsgPort->mp_SigBit =MPSigBit lea TDPort(DB),A1 move.l TDProcess(DB),MP_SIGTASK(A1) ; MsgPort->mp_SigTask =FindTask(0) CallLib AddPort lea IOExtTD(DB),A1 move.b #NT_MESSAGE,IO+MN+LN_TYPE(A1) ; IOExtTD->io_Message.mn_Node.ln_Type=NT_MESSAGE clr.b IO+MN+LN_PRI(A1) ; IOExtTD->io_Message.mn_Node.ln_Pri =0 lea TDPort(DB),A0 move.l A0,IO+MN_REPLYPORT(A1) ; IOExtTD->io_Message.mn_ReplyPort =Rep GetUnits lea Drive0(DB),A2 ; See which drives are available lea TDDrives(DB),A3 moveq #0,D2 moveq #0,D3 1$; clr.l MU_Unit(A2) not.w MU_Number(A2) ; Was 0, now -1 move.l D2,D0 moveq #0,D1 lea TrackName(PC),A0 lea IOExtTD(DB),A1 CallLib OpenDevice tst.l D0 bne.S 2$ move.b #'D',(A3)+ ; Create 'DFx: ?? ' move.b #'F',(A3)+ move.b #'0',(A3) add.b D2,(A3)+ move.b #':',(A3)+ move.b #' ',(A3)+ addq.l #2,A3 move.b #' ',(A3)+ addq.w #1,D3 lea IOExtTD(DB),A1 ; Oh yeah, drive is available move.l IO_UNIT(A1),MU_Unit(A2) ; Store address of unit-structure CallLib CloseDevice ; Close Unit again 2$ subq.l #MU_SIZE,A2 addq.l #1,D2 cmp.w #4,D2 blt.S 1$ move.w D3,D0 mulu #7,D3 subq.w #1,D0 bmi Error add.w D0,D3 move.w D3,StrLength(DB) mulu #8,D3 add.w D3,Width(DB) GetWindow Prepare Intuition_Call CallLib OpenWorkBench tst.l D0 beq Error move.l D0,A1 move.w sc_Width(A1),D0 sub.w Width(DB),D0 lsr.w #1,D0 lea NW(PC),A0 move.w D0,nw_LeftEdge(A0) ; Center the window moveq #0,D1 move.b sc_BarHeight(A1),D1 tst.w Version(DB) beq.S 1$ addq.w #1,D1 ; Because of newlook 1$ move.w D1,Height(DB) subq.w #7,D1 lsr.w #1,D1 addq.w #6,D1 move.w D1,yPos(DB) move.w Width(DB),nw_Width(A0) move.w Height(DB),nw_Height(A0) CallLib OpenWindow move.l D0,DWindow(DB) beq Error move.l D0,A0 move.l wd_RPort(A0),Rp(DB) move.l wd_UserPort(A0),Up(DB) ; UserPort move.l DWindow(DB),A0 suba.l A1,A1 lea ScrTitle(PC),A2 CallLib SetWindowTitles Prepare Gfx_Call move.l Rp(DB),A2 moveq #0,D0 ; Assume 1.3 colors moveq #1,D2 tst.w Version(DB) beq.S 2$ exg D0,D2 ; Well, use 2.0 colors 2$ move.l A2,A1 CallLib SetAPen move.l A2,A1 move.w D2,D0 CallLib SetBPen move.l A2,A1 moveq #RP_JAM2,D0 CallLib SetDrMd lea TxtAttr(PC),A0 CallLib OpenFont move.l D0,Font(DB) beq.S Error move.l D0,A0 move.l A2,A1 CallLib SetFont SetInterrupt Prepare Exec_Call lea TDInterrupt(DB),A1 ; Start vertical-blanking interrupt-server move.b #NT_INTERRUPT,LN_TYPE(A1) ; TDInterrupt->is_Node.ln_Type=NT_INTERRUPT lea TDIntName(PC),A0 move.l A0,LN_NAME(A1) ; TDInterrupt->is_Node.ln_Name=TDIntName lea TDIntServer(PC),A0 move.l A0,IS_CODE(A1) ; TDInterrupt->is_Code =TDIntServer move.l DB,IS_DATA(A1) ; TDInterrupt->is_Data =DB moveq #INTB_VERTB,D0 CallLib AddIntServer bra Main Exit Error FreeInterrupt Prepare Exec_Call lea TDInterrupt(DB),A1 tst.l IS_CODE(A1) ; If this is set then server has been added beq.S FreeFont moveq #INTB_VERTB,D0 CallLib RemIntServer FreeFont Prepare Gfx_Call move.l Font(DB),D0 beq.S FreeWindow move.l D0,A1 CallLib CloseFont FreeWindow Prepare Intuition_Call move.l DWindow(DB),D0 beq.S FreePort move.l D0,A0 CallLib CloseWindow FreePort Prepare Exec_Call lea TDPort(DB),A2 tst.b MP_SIGBIT(A2) ; If we have bit we also have port beq.S FreeIntui move.l A2,A1 CallLib RemPort moveq #0,D0 move.b MP_SIGBIT(A2),D0 CallLib FreeSignal FreeIntui move.l IntuiBase(DB),D0 beq.S FreeGfx move.l D0,A1 CallLib CloseLibrary FreeGfx move.l GraphBase(DB),D0 beq.S ReplyWB move.l D0,A1 CallLib CloseLibrary ReplyWB move.l WBenchMsg(DB),D2 beq.S AllDone CallLib Forbid move.l D2,A1 CallLib ReplyMsg ; Reply WBenchMessage if we are started from WB AllDone dcFree moveq #0,D0 rts Main EventLoop move.l Up(DB),A0 moveq #0,D0 moveq #0,D1 move.b MP_SIGBIT(A0),D1 bset D1,D0 bset #SIGBREAKB_CTRL_D,D0 Prepare Exec_Call CallLib Wait btst #SIGBREAKB_CTRL_D,D0 beq.S GetNextMsg lea TDDrives+5(DB),A1 lea Drive0(DB),A0 moveq #'0',D2 moveq #0,D1 1$ move.w MU_Number(A0),D0 bmi.S 2$ ext.l D0 divu #10,D0 add.w D2,D0 move.b D0,(A1) swap D0 add.w D2,D0 move.b D0,1(A1) addq.l #8,A1 2$ subq.l #MU_SIZE,A0 addq.w #1,D1 cmp.w #4,D1 blt.S 1$ Call UpdateDisplay bra.S EventLoop GetNextMsg move.l Up(DB),A0 Prepare Exec_Call CallLib GetMsg tst.l D0 beq.S EventLoop move.l D0,A1 move.l im_Class(A1),D2 CallLib ReplyMsg cmp.l #CLOSEWINDOW,D2 beq Exit tst.w Version(DB) ; No need to change color beq.S 3$ ; under 1.2/1.3 cmp.l #ACTIVEWINDOW,D2 bne.S 1$ Call GetBackColor move.w D0,D2 Call GetFrontColor bra.S 2$ 1$ cmp.l #INACTIVEWINDOW,D2 bne.S 3$ moveq #0,D2 moveq #1,D0 2$ Prepare Gfx_Call move.l Rp(DB),A1 CallLib SetAPen move.w D2,D0 move.l Rp(DB),A1 CallLib SetBPen 3$ Call UpdateDisplay ; Do some refreshing bra.S GetNextMsg UpdateDisplay Prepare Gfx_Call move.l Rp(DB),A1 move.w xPos(DB),D0 move.w yPos(DB),D1 CallLib Move lea TDDrives(DB),A0 move.l Rp(DB),A1 move.w StrLength(DB),D0 CallLib Text rts *»»» Call: A1 = DB *»»» Inside the server the registers D0-D1/A0-A1/A5-A6 can be used *»»» without restoring them on exit TDIntServer Push D2/DB move.l A1,DB moveq #0,D2 ; Don't signal lea Drive3(DB),A0 moveq #3,D1 1$ move.l MU_Unit(A0),D0 beq.S 2$ ; Does drive exist move.l D0,A1 add.w UOffset(DB),A1 move.w (A1),D0 asr.w #1,D0 cmp.w MU_Number(A0),D0 beq.S 2$ move.w D0,MU_Number(A0) moveq #1,D2 ; Do signal 2$ addq.l #MU_SIZE,A0 dbf D1,1$ tst.w D2 beq.S 3$ move.l TDProcess(DB),A1 move.l #SIGBREAKF_CTRL_D,D0 Prepare Exec_Call CallLib Signal 3$ Pop D2/DB rts *»»» These routines return the colors that Kickstart 2.x uses for *»»» title-text and window-frames in active windows. Perhaps I *»»» am using system-private values here - I didn't have access *»»» Kickstart 2.x includes and autodocs when I wrote this. *»»» *»»» Return: D0 = Color used for title-text in active windows. GetFrontColor moveq #12,D0 bra.S GetColor *»»» Return: D0 = Color used for window-frames in active windows. GetBackColor moveq #10,D0 GetColor move.l DWindow(DB),A0 move.l wd_WScreen(A0),A0 move.l $1DE+4(A0),A0 move.w 0(A0,D0.W),D0 rts GfxName dc.b 'graphics.library',0 IntuiName dc.b 'intuition.library',0 TrackName dc.b 'trackdisk.device',0 TDIntName dc.b 'TD Interrupt',0 ScrTitle dc.b 'TD V2.0 1991 by Preben Nielsen.',0 EVEN Kick1 =0 *»»» Defines for hires under kickstart 1.2-1.3 (and below ?) Offset1.3 =74 Width1.3H =85 ; Gadget size xPos1.3H =30 Kick2 =1 *»»» Defines for hires under kickstart 2.0 (and up ?) Offset2.0 =54 Width2.0H =51 ; Gadget size xPos2.0H =23 Settings1.3H dc.w Kick1,Offset1.3,Width1.3H,xPos1.3H Settings2.0H dc.w Kick2,Offset2.0,Width2.0H,xPos2.0H IDCMP_Flags = CLOSEWINDOW|INACTIVEWINDOW|ACTIVEWINDOW Other_Flags = RMBTRAP|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG NW dc.w 0,0,0,0 dc.b 0,1 dc.l IDCMP_Flags,Other_Flags dc.l 0,0,0,0,0 dc.w 0,0,0,0,WBENCHSCREEN TxtAttr dc.l 0 dc.w TOPAZ_EIGHTY dc.b FS_NORMAL,FPB_ROMFONT FontName dc.b 'topaz.font',0 END