home *** CD-ROM | disk | FTP | other *** search
- * 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
-
-