; PClock V1.0 ; by Preben Nielsen. ; Assemble it as case-sensitive. ; OPT O+ ; OPT O1+ ;Tells when a branch could be optimised to short ; OPT i+ ;Tells when '#' is probably missing ;TWELVE_HOURS ;Uncomment this line if you don't want ;a 24-hour clock incdir "INCLUDE:" include "devices/timer.i" include "exec/memory.i" include "exec/devices.i" include "exec/exec_lib.i" include "graphics/graphics_lib.i" include "intuition/intuition.i" include "intuition/intuition_lib.i" include "libraries/dosextens.i" include "libraries/dos_lib.i" ;TWELVE_HOURS ;Uncomment this line if you don't want ;a 24-hour clock * A few macro's LoadBase MACRO IFNC '\1','ExecBase' movea.l \1(A5),A6 ENDC IFC '\1','ExecBase' movea.l 4.W,A6 ENDC ENDM CallLib MACRO jsr _LVO\1(A6) ENDM Call MACRO bsr \1 ENDM Push MACRO movem.l \1,-(SP) ENDM Pop MACRO movem.l (SP)+,\1 ENDM * Offsets into datablock WBenchMsg =0 DosBase =4 GfxBase =8 IntBase =12 TimerPort =16 TimerOpen =20 Counter =22 CWindow =24 Rp =28 Up =32 Stamp =36 ;\ Days =36 ; \struct DateStamp Stamp; Minutes =40 ; / Ticks =44 ;/ TimeReq =48 ;struct TimeRequest TimeReq; (Size IOTV_SIZE) RelDataSize =48+4+IOTV_SIZE SECTION CLOCKCODE,CODE DBase EQUR A5 PClock Push D0-D7/A0-A6 lea -RelDataSize(SP),SP ;Make room on stack for data movea.l SP,DBase moveq #RelDataSize-1,D0 ClrData clr.b (DBase)+ ;Clear data area dbf D0,ClrData movea.l SP,DBase LoadBase ExecBase suba.l A1,A1 CallLib FindTask ;Find us movea.l D0,A2 tst.l pr_CLI(A2) ;pr_CLI bne.S CLIAndWBStartup WBenchStartup lea pr_MsgPort(A2),A0 ;pr_MsgPort CallLib WaitPort ;Wait for a message lea pr_MsgPort(A2),A0 CallLib GetMsg ;Then get it move.l D0,WBenchMsg(DBase) ;Save it for later reply CLIAndWBStartup lea DosName(PC),A1 CallLib OldOpenLibrary ;Open dos move.l D0,DosBase(DBase) beq.S Exit lea GfxName(PC),A1 CallLib OldOpenLibrary ;Open graphics move.l D0,GfxBase(DBase) beq.S Exit lea IntuiName(PC),A1 CallLib OldOpenLibrary ;Open Intuition move.l D0,IntBase(DBase) beq.S Exit lea FileNW(PC),A0 LoadBase IntBase CallLib OpenWindow ;Open the Window move.l D0,CWindow(DBase) beq.S Exit movea.l D0,A0 move.l 50(A0),Rp(DBase) ;Get RastPort move.l 86(A0),Up(DBase) ;Get UserPort suba.l A1,A1 lea ScrTitle(PC),A2 CallLib SetWindowTitles lea TxtAttr(PC),A0 LoadBase GfxBase CallLib OpenFont tst.l D0 beq.S Exit movea.l D0,A0 movea.l Rp(DBase),A1 CallLib SetFont ;Have to be sure to use the right size of font moveq #0,D0 movea.l Rp(DBase),A1 CallLib SetAPen moveq #1,D0 movea.l Rp(DBase),A1 CallLib SetBPen Call OpenTimer beq.S Main ;Lets begin * Here we exit Exit Call CloseTimer CloseWin LoadBase IntBase move.l CWindow(DBase),D0 beq.S CloseIntui movea.l D0,A0 CallLib CloseWindow ;Close window if it is open CloseIntui LoadBase ExecBase move.l IntBase(DBase),D0 beq.S CloseGfx movea.l D0,A1 CallLib CloseLibrary ;Close intuition if it is open CloseGfx move.l GfxBase(DBase),D0 beq.S CloseDos movea.l D0,A1 CallLib CloseLibrary ;Close graphics if it is open CloseDos move.l DosBase(DBase),D0 beq.S ReplyWB movea.l D0,A1 CallLib CloseLibrary ;Close graphics if it is open ReplyWB move.l WBenchMsg(DBase),D2 beq.S AllDone CallLib Forbid movea.l D2,A1 CallLib ReplyMsg ;Reply WBenchMessage if we are started from WB AllDone lea RelDataSize(DBase),SP ;Restore SP Pop D0-D7/A0-A6 moveq #0,D0 rts * Here we really begin Main StartTimer Call WriteStr EventLoop LoadBase ExecBase moveq #0,D0 moveq #0,D1 movea.l Up(DBase),A0 move.b MP_SIGBIT(A0),D1 bset D1,D0 movea.l TimerPort(DBase),A0 move.b MP_SIGBIT(A0),D1 bset D1,D0 CallLib Wait movea.l TimerPort(DBase),A0 CallLib GetMsg ;Message from Timer tst.l D0 bne.S StartTimer GetNextMsg movea.l Up(DBase),A0 ;Has to be message from intuition CallLib GetMsg ;Get the message tst.l D0 beq.S EventLoop ;Did we get a message movea.l D0,A1 ;Yes, put message address to A1 and reply move.l 20(A1),D7 CallLib ReplyMsg ;Reply the message cmpi.l #CLOSEWINDOW,D7 beq Exit bra.S GetNextMsg ;Writes available memory, writes time, and sends a timer-request WriteStr Push D0-D7/A0-A6 LoadBase DosBase lea Stamp(DBase),A0 move.l A0,D1 CallLib DateStamp ;Get current time Call StampToStr subq.w #1,Counter(DBase) bgt.S DontUpdateMem move.w #4,Counter(DBase) Call MemToStr ;Updates memory every 4 seconds DontUpdateMem LoadBase GfxBase moveq #30,D0 moveq #7,D1 movea.l Rp(DBase),A1 CallLib Move moveq #36,D0 lea AllStr(PC),A0 movea.l Rp(DBase),A1 CallLib Text Call SendTimerReq Pop D0-D7/A0-A6 rts StampToStr Push D0-D7/A0-A6 move.l Minutes(DBase),D2 divu #60,D2 move.l D2,D1 swap D1 IFD TWELVE_HOURS ext.l D2 divu #12,D2 swap D2 ENDC move.l Ticks(DBase),D0 divu #50,D0 move.w D0,-(SP) ;Seconds move.w D1,-(SP) ;Minutes move.w D2,-(SP) ;Hours pea TimeFormat pea TimeStr ;Destination Call Format ;sprintf(fmt,Destination,Hour,Minute,Second); lea 14(SP),SP Pop D0-D7/A0-A6 rts MemToStr Push D0-D7/A0-A6 LoadBase ExecBase moveq #MEMF_CHIP,D1 CallLib AvailMem ;AvailMem(MEMF_CHIP); move.l D0,-(SP) pea MemFormat(PC) pea ChipStr(PC) Call Format lea 12(SP),SP moveq #MEMF_FAST,D1 CallLib AvailMem ;AvailMem(MEMF_FAST); move.l D0,-(SP) pea MemFormat(PC) pea FastStr(PC) Call Format lea 12(SP),SP lea AllStr(PC),A0 move.b #' ',13(A0) move.b #' ',27(A0) Pop D0-D7/A0-A6 rts * ----------------------- Misc sub-routines ---------------------------- ;Format(Buffer,Format-string,datastream); Format Push D0-D1/A0-A3 move.l 4*6+4(SP),A3 ;Destination buffer move.l 4*6+8(SP),A0 ;Format-string lea 4*6+12(SP),A1 ;Data on stack lea PutChar(PC),A2 ;Function LoadBase ExecBase CallLib RawDoFmt Pop D0-D1/A0-A3 rts PutChar move.b D0,(A3)+ rts ;A0=Port Name, D0=Priority ;Returns 0 if it failed address of port if it had success CreatePort Push D1-D7/A0-A6 LoadBase ExecBase move.l D0,D5 movea.l A0,A5 moveq #-1,D0 CallLib AllocSignal move.b D0,D6 bmi.S CPortFailed ;AllocSignal returned -1 moveq #MP_SIZE,D0 move.l #MEMF_PUBLIC!MEMF_CLEAR,D1 CallLib AllocMem move.l D0,D7 beq.S CNoMemory movea.l D0,A2 move.l A5,MP+LN_NAME(A2) ;MsgPort->mp_Node.ln_Name=Name; move.b D5,MP+LN_PRI(A2) ;MsgPort->mp_Node.ln_Pri =Pri; move.b #NT_MSGPORT,MP+LN_TYPE(A2) ;MsgPort->mp_Node.ln_Type=NT_MSGPORT; clr.b MP_FLAGS(A2) ;MsgPort->mp_Flags =PA_SIGNAL; move.b D6,MP_SIGBIT(A2) ;MsgPort->mp_SigBit =MPSigBit; suba.l A1,A1 CallLib FindTask move.l D0,MP_SIGTASK(A2) ;MsgPort->mp_SigTask =FindTask(0); movea.l A2,A1 CallLib AddPort move.l D7,D0 bra.S DoneCPort CNoMemory move.b D6,D0 CallLib FreeSignal CPortFailed moveq #0,D0 DoneCPort Pop D1-D7/A0-A6 ;Returns 0 or address of port rts ;A1=MsgPort DeletePort Push D0-D7/A0-A6 LoadBase ExecBase movea.l A1,A2 CallLib RemPort moveq #0,D0 move.b MP_SIGBIT(A2),D0 CallLib FreeSignal movea.l A2,A1 moveq #MP_SIZE,D0 CallLib FreeMem Pop D0-D7/A0-A6 rts ;Send a timer request for 1 second SendTimerReq Push D0-D1/A0-A1/A6 LoadBase ExecBase lea TimeReq(DBase),A1 move.l TimerPort(DBase),IO+MN_REPLYPORT(A1);TimeReq.tr_node.io_Message.mn_ReplyPort=Rep; move.w #TR_ADDREQUEST,IO_COMMAND(A1) ;TimeReq.tr_node.io_Command =TR_ADDREQUEST; clr.b IO_FLAGS(A1) ;TimeReq.tr_node.io_Flags =0; clr.b IO_ERROR(A1) ;TimeReq.tr_node.io_Error =0; move.l #1,IOTV_TIME+TV_SECS(A1) ;TimeReq.tr_time.tv_Secs =1; clr.l IOTV_TIME+TV_MICRO(A1) ;TimeReq.tr_time.tv_Micros =0; CallLib SendIO Pop D0-D1/A0-A1/A6 rts ;Creates port and opens timer.device ;Returns -1 if it failed and 0 if it had success OpenTimer Push D1/A0-A1/A6 lea PortName(PC),A0 moveq #0,D0 ;Priority Call CreatePort move.l D0,TimerPort(DBase) beq.S OTimerFailed lea TimerName(PC),A0 lea TimeReq(DBase),A1 moveq #UNIT_VBLANK,D0 moveq #0,D1 LoadBase ExecBase CallLib OpenDevice tst.l D0 beq.S DoneOTimer movea.l TimerPort(DBase),A1 Call DeletePort OTimerFailed moveq #-1,D0 DoneOTimer move.w D0,TimerOpen(DBase) ;0 or -1 Pop D1/A0-A1/A6 rts ;Deletes port and closes timer.device CloseTimer Push D0-D1/A0-A1/A6 tst.w TimerOpen(DBase) bne.S DoneCloseTimer LoadBase ExecBase lea TimeReq(DBase),A1 CallLib AbortIO lea TimeReq(DBase),A1 CallLib CloseDevice movea.l TimerPort(DBase),A1 Call DeletePort DoneCloseTimer Pop D0-D1/A0-A1/A6 rts DosName dc.b 'dos.library',0 GfxName dc.b 'graphics.library',0 IntuiName dc.b 'intuition.library',0 TimerName dc.b 'timer.device',0 PortName dc.b 'PClock Port',0 EVEN FileNW dc.w 217,0,373,10 dc.b 0,1 dc.l CLOSEWINDOW,WINDOWCLOSE!WINDOWDRAG!WINDOWDEPTH!RMBTRAP,0,0,0,0,0 dc.w 0,0,0,0,WBENCHSCREEN TxtAttr dc.l FontName dc.w TOPAZ_EIGHTY dc.b FS_NORMAL,FPB_ROMFONT FontName dc.b 'topaz.font',0 ScrTitle dc.b 'PClock V1.0 by Preben Nielsen in 1990. This is Public Domain',0 MemFormat dc.b '%8ld',0 TimeFormat dc.b '%02d:%02d:%02d',0 AllStr dc.b 'Chip:' ChipStr dc.b ' 0 Fast:' FastStr dc.b ' 0 ' TimeStr dc.b '12:12:12 ' END