
;/*
;** clock - a dumb, digital clock in the upper right-hand corner. Designed
;**      to be (very) small, not flexible!
;**
;** Copyright (c) 1986, Mike Meyer
;**
;** Lattice C 5.0x version by Thomas Siemens, Jan 1990
;**
;** Aztec 5.0a Assembler version by Götz Müller, 08 September 1990
;**
;*/

 nolist
 nomlist

 include <exec/types.i>
 include <exec/memory.i>
 include <exec/ports.i>
 include <intuition/intuitionbase.i>
 include <graphics/text.i>
 include <devices/timer.i>
 include <libraries/dosextens.i>
 include <intuition/intuition.i>

 list

INTUITTION_VERSION   equ   1
WIN_WIDTH            equ   275
WAIT_TIME            equ   500000L

Disable              equ   -120
Enable               equ   -126
AvailMem             equ   -216
FindTask             equ   -294
Wait                 equ   -318
AllocSignal          equ   -330
FreeSignal           equ   -336
GetMsg               equ   -372
ReplyMsg             equ   -378
CloseLibrary         equ   -414
OpenDevice           equ   -444
CloseDevice          equ   -450
SendIO               equ   -462
WaitIO               equ   -474
AbortIO              equ   -480
RawDoFmt             equ   -522
OpenLibrary          equ   -552

CloseWindow          equ   -72
OpenWindow           equ   -204
PrintIText           equ   -216

         cseg
;***************************************************************************
;
;     clock_fct
;
;     Function:   Main process code
;
;
;     Input:      ---
;
;     Output:     ---
;
;     Register:
;                 D2 :  &rn_Time
;                 D3 :  DOSBase
;                 D4 :  IntuitionBase
;                 D5 :  SysBase
;                 D6 :  &time_req
;                 D7 :  &timer_port
;                 A2 :  Window->UserPort
;                 A3 :  &date_buffer temporär
;                 A4 :  window
;                 A5 :  &date_buffer
;                 A6 :  LibraryBases
;
;***************************************************************************

         xdef     clock_fct
clock_fct: public clock_fct
         lea      _time_req,a0
         move.l   a0,d6
         lea      _timer_port,a0
         move.l   a0,d7
         lea      -40(sp),sp
         movea.l  sp,a5
         lea      _date_text,a0
         move.l   a5,it_IText(a0)
;         lea      _date_buffer,a5
         open_lib: public open_lib
         moveq    #33,d0
         lea      intui_name,a1
         jsr      OpenLibrary(a6)
         move.l   d0,d4 ;IntuitionBase
         bne      0$
            moveq    #20,d0
            jsr      done ;(20)
         0$:
         alloc_signal: public alloc_signal
         moveq    #-1,d0
         jsr      AllocSignal(a6)
         cmp.l    #-1,d0
         bne      1$
            moveq    #20,d0
            jsr      done ;(20)
         1$:
         init_port: public init_port
         movea.l  d7,a0 ;timer_port
         move.b   d0,MP_SIGBIT(a0)
         suba.l   a1,a1
         jsr      FindTask(a6)
         movea.l  d7,a0 ;timer_port
         move.l   d0,MP_SIGTASK(a0)
         open_device: public open_device
         moveq    #0,d1
         movea.l  d6,a1 ;time_req
         move.l   #UNIT_VBLANK,d0
         lea      _timer_dev,a0
         jsr      OpenDevice(a6) ;("timer.device",UNIT_VBLANK,&time_req,0L)
         tst.l    d0
         beq      2$
            moveq    #20,d0
            jsr      done ;(20)
         2$:
         open_window: public open_window
         move.l   d4,a6 ;IntuitionBase
         move.l   ib_ActiveScreen(a6),a0
         move.w   sc_Width(a0),d0
         sub.w    #(WIN_WIDTH+53),d0
         lea      _nw,a0
         move.w   d0,nw_LeftEdge(a0)
         jsr      OpenWindow(a6) ;(&_nw)
         tst.l    d0
         bne      3$
            moveq    #20,d0
            jsr      done ;(20)
         3$:
         movea.l  d0,a4
         movea.l  wd_UserPort(a4),a2
         movea.l  d3,a1 ;DOSBase
         movea.l  dl_Root(a1),a1
         lea      rn_Time(a1),a1
         move.l   a1,d2
         movea.l  d5,a6 ;SysBase
         loop:
            datestamp: public datestamp
            movea.l  d2,a0
            jsr      Disable(a6)
            move.l   ds_Tick(a0),d0
            move.l   ds_Minute(a0),a1
            jsr      Enable(a6)
            moveq    #TICKS_PER_SECOND,d1
            divu     d1,d0
            move.w   d0,-(sp)             ; seconds
            move.l   a1,d0
            moveq    #60,d1
            divu     d1,d0  ; hours = ds_Minute / 60
                            ; minutes = ds_Minutes % 60
            swap     d0
            move.l   d0,-(sp)             ; hours.minutes
            avail_fast: public avail_fast
            move.l   #MEMF_FAST,d1
            jsr      AvailMem(a6) ;(MEMF_FAST)
            moveq    #10,d1
            lsr.l    d1,d0       ; in KBytes
            move.w   d0,-(sp)
            avail_chip: public avail_chip
            move.l   #MEMF_CHIP,d1
            jsr      AvailMem(a6) ;(MEMF_CHIP)
            moveq    #10,d1
            lsr.l    d1,d0       ; in KBytes
            move.w   d0,-(sp)
            sprintf: public sprintf
            lea      (sp),a1              ; Pointer to rguments
            lea      format_string,a0
            movem.l  a2,-(sp)
            lea      stuffChar(pc),a2
            movea.l  a5,a3                ; &date_buffer
            jsr      RawDoFmt(a6)
            movem.l  (sp)+,a2
            lea      10(sp),sp
            bsr      print_date
            sendio: public sendio
            movea.l  d6,a1 ;&time_req
            clr.l    IOTV_TIME+TV_SECS(a1)
            move.l   #WAIT_TIME,IOTV_TIME+TV_MICRO(a1)
            move.l   d5,a6 ;SysBase
            jsr      SendIO(a6) ;(&time_req)
            wait: public wait
            7$:
               moveq    #0,d1
               move.b   MP_SIGBIT(a2),d1
               move.l   #1,d0
               lsl.l    d1,d0
               move.l   d0,-(sp)
               movea.l  d7,a0 ;timer_port
               moveq    #0,d0
               move.b   MP_SIGBIT(a0),d0
               move.l   #1,d1
               lsl.l    d0,d1
               move.l   (sp)+,d0
               or.l     d1,d0
               jsr      Wait(a6) ;(1L<<Window->UserPort->mp_SigBit
                              ;                 | 1L<<timer_port->mp_SigBit)
               6$:
                  movea.l  a2,a0
                  jsr      GetMsg(a6)
                  movea.l  d0,a1
                  tst.l    d0
                  beq      4$
                     cmp.l    #CLOSEWINDOW,im_Class(a1)
                     bne      5$
                        jsr      ReplyMsg(a6) ;(Msg)
                        moveq    #0,d0
                        jsr      done ;(0L)
                     5$:
                     jsr      ReplyMsg(a6) ;(Msg)
                     bra      6$
                  4$:
               movea.l  d7,a0 ;timer_port
               jsr      GetMsg(a6)
               tst.l    d0
               bne      loop
                  bsr      print_date
                  bra      7$
         rts

;------ PutChProc function used by RawDoFmt -----------
stuffChar:
         move.b   d0,(a3)+             ;Put data to output string
         rts

;***************************************************************************
;
;     print_date
;
;     Function:   Call PrintIText with fix arguments
;
;
;     Input:      ---
;
;     Output:     ---
;
;***************************************************************************

print_date
         moveq    #1,d1
         moveq    #6,d0
         lea      _date_text,a1
         movea.l  wd_RPort(a4),a0
         movea.l  d4,a6 ;IntuitionBase
         jsr      PrintIText(a6) ;(Window->RPort,&date_text,6L,1L)
         movea.l  d5,a6 ;SysBase
         rts

;***************************************************************************
;
;     done
;
;     Function:   releases open system resources
;
;
;     Input:      D0 :  Return value for CLI
;
;     Output:     ---
;
;     Register:   D2 :  Return value
;                 A6 :  LibraryBase
;
;***************************************************************************

done:
         movea.l  d5,a6 ;SysBase
         move.l   d0,d2
         bne      0$
            movea.l  d6,a1
            jsr      AbortIO(a6) ;(&time_req)
            movea.l  d6,a1
            jsr      WaitIO(a6)  ;(&time_req)
         0$:
         close_device: public close_device
         movea.l  d6,a1
         tst.l    IO_UNIT(a1)
         beq      1$
            jsr      CloseDevice(a6) ;(&time_req)
         1$:
         movea.l  d7,a0 ;timer_port
         moveq    #-1,d0
         moveq    #0,d0
         move.b   MP_SIGBIT(a0),d0
         beq      2$
            jsr      FreeSignal(a6)
         2$:
         movea.l  d3,a1 ;DOSBase
         jsr      CloseLibrary(a6)
         close_window: public close_window
         movea.l  d4,a6 ;IntuitonBase
         tst.l    d4
         beq      3$
            movea.l  a4,a0
            cmpa.w   #0,a0
            beq      4$
               jsr      CloseWindow(a6) ;(Window)
            4$:
            movea.l  a6,a1
            movea.l  d5,a6 ;SysBase
            jsr      CloseLibrary(a6)
         3$:
         lea         44(sp),sp
;         addq.w      #4,sp ; correct return address
         rts

format_string:
         dc.b     'Chip:%4d Fast:%4d Time:%2d:%02d:%02d',0
intui_name:
         dc.b     'intuition.library',0
_timer_dev:
         dc.b     'timer.device',0
_topaz_font
         dc.b     'topaz.font',0
         ds       0
_nw: public _nw
         dc.w     0           ; LeftEdge filled in by program
         dc.w     0           ; TopEdge
         dc.w     WIN_WIDTH   ; Width  Just big enough for the time
         dc.w     10          ; Height
         dc.b     255         ; Default pens
         dc.b     255
         dc.l     CLOSEWINDOW|ACTIVEWINDOW|INACTIVEWINDOW ; IDCMP
         dc.l     WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG|SMART_REFRESH|NOCAREREFRESH
         dc.l     0
         dc.l     0
         dc.l     0
         dc.l     0
         dc.l     0
         dc.w     0           ; MinMaxSize
         dc.w     0
         dc.w     0
         dc.w     0
         dc.w     WBENCHSCREEN
_text_attr:
         dc.l     _topaz_font       ; ta_Name
         dc.w     8                 ; ta_YSize
         dc.b     FS_NORMAL         ; ta_Style
         dc.b     0                 ; ta_Flags
_date_text: public _date_text
         dc.b     1                 ; Use the standard pen colors
         dc.b     0
         dc.b     RP_JAM2
         ds.b     1
         dc.w     0                 ; LeftEdge
         dc.w     0                 ; TopEdge
         dc.l     _text_attr
         dc.l     0                 ; IText
;         dc.l     _date_buffer
         dc.l     0                 ; Next
_time_req: public _time_req
         ds.b     LN_SIZE           ; mn_Node = 14
         dc.l     _timer_port       ; mn_ReplyPort
         dc.w     IOTV_SIZE
         dc.l     0                 ; io_Device
         dc.l     0                 ; io_Unit
         dc.w     TR_ADDREQUEST     ; io_Command
         dc.b     0                 ; io_Flags
         dc.b     0                 ; io_Error
         dc.l     0                 ; tv_secs
         dc.l     WAIT_TIME         ; tv_microsecs
_timer_port: public _timer_port
         ds.b     LN_SIZE           ; mp_Node = 14
         dc.b     PA_SIGNAL         ; mp_Flags
         dc.b     0                 ; mp_SigBit
         dc.l     0                 ; mp_SigTask
     0$: dc.l     1$                ; lh_Head
     1$: dc.l     0                 ; lh_Tail
         dc.l     0$                ; lh_TailPred
         dc.b     NT_MESSAGE        ; lh_Type
         dc.b     0                 ; lh_pad
;_date_buffer
;         ds.b     40
         end

