home *** CD-ROM | disk | FTP | other *** search
- ;============================================================================
- ; TRACKR.COM keeps logs of time spent on individual tasks
- ;
- ; Revision History:
- ;
- ; Version 1.0 Initial Release
- ; 1.1 1/7/92 Bug fixes
- ;
- ;============================================================================
-
- Code segment byte public 'code'
- assume cs:code
- assume ds:code
-
- org 100h
- LGo: jmp Init
-
-
- Drive db 79 dup (0) ;full pathname of .LOG files
- NameOff dw offset Drive ;offset where filename goes onto path
- TaskOff dw 0 ;offset of current task in TaskList
- SrchName db '*'
- Extension db '.LOG',0
- ScanCode db 13h ;Hot key scan code (R)
- ShiftState db 4 ;hot key shift state (Ctrl)
- Space db ' '
- HAt db 1Fh ;hi-lite screen attribute
- NAt db 31h ;normal screen attribute
-
- Vec09 dd 0 ;original BIOS interupt address
- Vec13 dd 0
- Vec08 dd 0
- Vec28 dd 0
-
- OrgCursor dw 0 ;cursor location when popped up
- VidPage db 0 ;video page during pop-up
- Up? db 0 ;1 if Tracker is popped up
- MsgUp? db 0 ;1 if Reminder msg is up
- Minutes dw 0 ;# of minutes task has been active
- Min_Ticks dw 0444h ;ticks in a minute
- Display? db 1 ;1 if reminder is to be displayed
- WaitTicks dw 444h ;interval between reminders (ticks)
- Rem_Ticks dw 0 ;interval between reminders (ticks)
- MsgTicks db 5Ah ;clock ticks reminder stays up
- Timer? db 0 ;1 if timer is activated
- Resume db 'Resume'
- Msg db ' hh:mm '
- FileName db 14 dup (0)
- db 0Dh,0Ah,'$'
- PauseMsg db ' Timer on Pause '
- ScrnMsg db ' : '
- Tick dw 0
- OurPSP dw 0 ;Trackr's PSP segment
- ParentPSP dw 0 ;parent program's PSP segment
- OrgVidSeg dw 0B000h ;video segment
- VidSeg dw 0 ;OrgVidSeg adjusted for screen offset
- Pausing? db 0 ;1 if pausing
- Message db 'TrackerPro'
- Pause db 'PAUSE'
- DayTot dw 0 ;day total of time
- Total dw 0 ;grand total of time
- DayTotMsg db '* Day Total: :'
- db ' ',0Dh,0Ah,0Dh,0Ah
- TotalMsg db '========== Task Total: : ',0Dh,0Ah
- VidMode db 0 ;video mode
- StrSize db 0 ;size of string inputted
- TopPage db 0 ;first task of current display
- NumTasks db 0 ;# of tasks
- NumClients db 0 ;# of Clients
- Update? db 0 ;1 if updating
-
- ThisFile db 'TRACKR.COM',0
- Menu db 'P',1,'ause',2
- db 'L',1,'og off',2
- db 'S',1,'witch',2
- Menu2 db 'C',1,'reate new task',2
- db 'U',1,'pdate task log'
- MenuEnd db 3
- db 'L',1,'og in new task',3
- SelectTask db ' Task #:',0
- InpClient db ' Client #:',0
-
- TaskMsg db 'Tasks ─'
- Status db ' Active task: Elapsed time: '
-
- Screen db ' Active task: Elapsed time: '
- db '┌ Tasks ──────────────────┬ Press: ─────────────┐'
- db '│ 0 NEW 5 │ │'
- db '│ 1 6 │ │'
- db '│ 2 7 │ │'
- db '│ 3 8 │ │'
- db '│ 4 9 │ │'
- db '└────────────── Press Escape to Exit ───────────┘'
- ; Note: "Screen" is also used to store screen characters overwritten by
- ; Trackr when it pops up
-
- Attributes db 398 dup (0) ;stores overwritten screen attributes
- DTA db 49 dup (0) ;disk transfer area
- DiskOp? db 0 ;1 if disk ops in progress
- DBOff dw 0 ;DOS busy byte offset
- DBSeg dw 0 ;DOS busy byte segment
- Request? db 0 ;1=request to pop-up
- TryCnt db 5Bh ;clock ticks to try to pop-up
- NameMsg db 'Task name:',0
- DupNameMsg db 'Task already exists. Press any key.',0
- InvNameMsg db 'Invalid file name. Press any key.',0
- TooManyMsg db 'Ignoring extra clients. Press any key.',0
- StackPtr dw 0
- HoldSP dw 0
- ClientFH dw 0FFFh ;CLIENT.DAT file handle
- LogFH dw 0FFFh ;log file handle
- TempFH dw 0FFFh ;temp file's file handle
- HoldFH dw 0 ;temporarily holds file handle
- Flag db 0 ;procedure flag
- Client? db 0 ;procedure flag
- Client db 21 dup (0) ;first 21 bytes of Client info
- Rate dw 0 ;billing rate
- Units dw 0 ;billing increments
- CTopPage db 0 ;first client of current display
- ClientFN db 'CLIENT.DAT',0
- TempFN db 'TEMP',0
- BytesRead dw 0 ;# of bytes read
- EndRec dw 0 ;signal end of record
- EoF db 0 ;signals end of file
- Date db 8 dup (0)
- Today db ' / / ',0
- LogIn dw 0 ;time logged in
- LogOut dw 0 ;time logged out
- LogOff? db 0 ;1 if logging out
- CListPtr dw 0
- ClientArray dw 30 dup (0) ;30 clients
- TaskList db 650 dup (0) ;50 entries 13 bytes each
- RecOff dw 0 ;file offset of desired record
- db ' '
- Comments db 30 dup (0)
- CommentMsg db ' Comment: ',0
- FirstRec? db 0
- Temp dw 0
- EndStr dw 0 ;sets max lenght of input string
- Cursor dw 0 ;current cursor location
- ErrInfo dw 3 dup (0) ;extended error info of parent
-
- ;============================================================================
- ; Int08 processes BIOS timer interrupt (Int 08h)
- ;============================================================================
- Int08 proc
-
- pushf
- call cs:Vec08 ;call original interupt
-
- sti
- cmp cs:Timer?,1
- je A1
- cmp cs:Pausing?,1
- je A1
- A0: cmp cs:Request?,1
- jne A05
- jmp Readyet? ;okay to pop-up yet?
-
- A05: iret
-
- A1: dec cs:Min_Ticks ;count down ticks per minute
- jnz A11
- inc cs:Minutes ;another minute has passed
- mov cs:Min_Ticks,0444h ;reset counter
-
- A11: cmp cs:MsgUp?,1
- jne A12
-
- ;reminder message is up
- dec cs:MsgTicks
- jz DisTimer ;if up for 5 secs then remove
- jmp A0
-
- ;reminder message not up
- A12: dec cs:Rem_Ticks
- jnz A0
-
- ;time to display reminder
- push cs:WaitTicks
- pop cs:Rem_Ticks
-
- ;displays or removes reminder
- DisTimer: cmp cs:Up?,1 ;is TRACKR popped up?
- je A0
- cmp cs:Display?,1 ;don't want to re-enter
- jne A0
-
- mov cs:Display?,0 ;make sure we don't re-enter
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push ds
- push es
-
- push cs
- pop ds
-
- A15: mov ax,40h
- mov es,ax
- mov al,es:49h ;bios mode
- cmp al,7
- je A2
- cmp al,3
- ja RetInt ;if not text mode return
-
- A2: call AdjVidSeg
- mov es,VidSeg
- mov di,32h ;offset into screen of stuff to grab
- mov cx,36h ;number of words to grab
- mov si,offset Buffer
- cld
- cmp MsgUp?,1
- jne A3
-
- ;restore background
- mov cx,5
- repe cmpsw ;are previous 5 characters same
- jne Bally ;nope? then don't restore original
- mov cx,31h
- rep movsw
- jmp Bally
-
- ;save background
- A3: xchg si,di
- push es
- pop ds
- push cs
- pop es
-
- rep movsw ;save screen
- push cs
- pop ds
-
- ;display reminder message
- mov di,3Dh
- mov si,offset Attributes
- mov cx,31h
- call DisStr
- mov MsgTicks,5Ah
- call DisStatus ;display reminder
-
- Bally: xor MsgUp?,1
-
- RetInt: pop es
- pop ds
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
-
- mov cs:Display?,1
- cmp cs:Request?,1
- jne RY0
-
- ;checks to see if it's safe to pop-up
- Readyet?: dec cs:TryCnt ;how many times have we tried?
- jnz RY1
-
- mov cs:Request?,0 ;if tried for 5 secs then give up
- RY0: iret
-
- RY1: push ax
-
- ;check DOS busy byte
- push es
- push si
- mov es,cs:DBseg
- mov si,cs:DBoff
- cmp byte ptr es:[si],0 ;DOS busy byte
- pop si
- pop es
-
- jne T1 ;can't pop-up if DOS is busy
-
- ;DOS not busy
- cmp cs:Diskop?,0
- je T2
-
- ;unable to accomodate request (DOS busy or disk ops in progress)
- T1: pop ax
- iret
-
- ;DOS not busy and no disk ops, let's do it
- T2: pop ax
- jmp MainStuff
-
- Int08 endp
-
- ;============================================================================
- ; Int09 processes BIOS keyboard interrupt (Int 09h)
- ;============================================================================
-
- Int09 proc
-
- sti
- push ax
- push es
-
- mov ax,40h
- mov es,ax
- mov al,es:17h
- and al,0Fh
- cmp al,cs:ShiftState ;check shift state
- je R1
-
- R0: pop es ;chain to original interupt
- pop ax
- cli
- jmp cs:Vec09
-
- R1: in al,60h
- cmp al,cs:ScanCode ;check scan code
- jne R0
-
- ;hot key has been pressed, ask to pop-up
- cmp cs:Up?,1
- je R0
- mov cs:Request?,1
- mov cs:TryCnt,5Bh
-
- cli
- mov al,20h ;reset interupts
- out 20h,al
- sti
-
- pop es
- pop ax
- iret
-
- Int09 endp
-
- ;============================================================================
- ; Int28 processes undocumented DOS interrupt "keyboard busy loop" (Int 28h)
- ;============================================================================
-
- Int28 proc
- pushf
- call cs:Vec28
- sti
- cmp cs:Request?,1
- je I28b
- I28a: iret
- I28b: cmp cs:Diskop?,1
- je I28a
-
- ;no disk ops, and in Int28, let's do it
- jmp MainStuff
- Int28 endp
-
- ;============================================================================
- ; Int13 processes BIOS disk services interrupt (Int 13h)
- ;============================================================================
-
- Int13 proc
- ;won't let you pop-up during BIOS disk operations
- sti
- mov cs:Diskop?,1
- pushf
- call cs:Vec13 ;call original interupt
- mov cs:Diskop?,0
- retf 2
- Int13 endp
-
- ;============================================================================
- ; Start logs in a new task
- ;============================================================================
-
- Start proc
- call GetTime ;get log-in time
- mov LogIn,ax
- mov Timer?,1 ;we're on, ignore further requests
- mov Pausing?,0 ;we're not pausing
- mov ax,WaitTicks ;set up Rem_Ticks
- mov Rem_Ticks,ax
- ret
- Start endp
-
- ;============================================================================
- ; GetTime returns with seconds since midnight in AX
- ;============================================================================
-
- GetTime proc
- push es
- mov ax,40h
- mov es,ax
- mov ax,es:6Ch
- mov dx,es:6Eh
- mov bx,0444h
- div bx ;ax=minutes since midnight
- pop es
- ret
- GetTime endp
-
- ;============================================================================
- ; Stop logs-off
- ;============================================================================
-
- Stop proc
- call GetTime
- mov LogOut,ax ;get log-out time
- mov Timer?,0 ;we're off
- mov Minutes,0 ;reset elapsed time
- ret
- Stop endp
-
- ;============================================================================
- ; Encode puts time in HHH:MM format
- ; Entry: AX = minutes
- ; DI = offset HHH:MM string goes
- ;============================================================================
-
- Encode proc
- mov cx,3030h
- mov bx,3Ch
- xor dx,dx
- div bx
- xchg dx,ax ;put minutes in ax
- aam
- xchg ah,al
- or ax,cx
- mov [di+4],ax ;minutes
-
- mov ax,dx ;put hours in ax
- mov bl,64h
- div bl ;divide by 100
- mov bl,al
- mov al,ah
- aam
- xchg ah,al
- or ax,cx
- mov [di+1],ax ;hours mod 100
- cmp bl,0
- je E1
- mov al,bl
- aam
- or ax,cx
- mov [di],al ;hundreds of hours value
- E1: mov byte ptr [di+3],':' ;stick in colon
- ret
- Encode endp
-
- ;============================================================================
- ; Decode takes time value in HH:MM and returns AX=minutes
- ; Entry: SI = offset of HH:MM value
- ; Exit: AX = minutes
- ;============================================================================
-
- Decode proc
- cmp byte ptr [si],' '
- jne DD1
- mov byte ptr [si],'0'
- DD1: mov ax,[si]
- xor ax,3030h
- xchg ah,al
- aad
- mov bl,3Ch
- mul bl
- mov dx,ax
- mov ax,[si+3]
- xor ax,3030h
- xchg ah,al
- aad
- add ax,dx
- ret
- Decode endp
-
- ;============================================================================
- ; MainStuff prepares for popping up by saving registers, cursor location,
- ; extended error information, getting and setting the PSP, getting the video
- ; segment and offsets, saving the background, and displaying Trackr's main
- ; screen.
- ;============================================================================
-
- MainStuff proc
- mov cs:Request?,0
- mov cs:Up?,1
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push ds
- push es
-
- mov ax,cs
- mov ds,ax
- mov es,ax
-
- mov ah,51h
- int 21h ;get parent PSP
- mov ParentPSP,bx
-
- mov ah,50h
- mov bx,OurPSP
- int 21h ;set our PSP
-
- mov ah,59h
- int 21h ;get extended error information
- mov ErrInfo,ax
- mov ErrInfo[2],bx
- mov ErrInfo[4],cx
-
- call AdjVidSeg ;get video segment
-
- cmp MsgUp?,1
- jne MS1
-
- ;remove reminder if currently displayed
- push es
- mov es,VidSeg
- mov di,3Ch
- mov cx,31h
- mov si,offset Buffer
- cld
- rep movsw
- mov MsgUp?,0
- pop es
-
- MS1: mov ah,0Fh
- int 10h
- mov VidPage,bh
- mov ah,3
- int 10h
- mov OrgCursor,dx ;save cursor position
-
- mov ax,sp
- mov StackPtr,ax ;save stack ptr
-
- call SwapScreen ;save background and display Trackr
-
- call MakeDate
- cmp NumTasks,0
- jne Main
-
- ;if no tasks then jump to Create Task
- jmp M51
-
- ;============================================================================
- ; Main procedure
- ;============================================================================
-
- Main proc
- mov Client?,0
- mov Update?,0
-
- ;display Menus
- mov ah,2
- mov bh,VidPage
- mov dx,1900h
- int 10h ;move cursor off screen
-
- mov si,offset TaskMsg
- mov cx,7
- mov di,0E0h
- call DisStr ;display TaskMsg
-
- mov si,offset Menu
- mov MenuEnd,3
- cmp TaskOff,0
- jne Mt
- mov si,offset Menu2
- dec MenuEnd
-
- Mt: call DisMenu ;display appropriate Menu
- cmp Pausing?,1
- jne Mu
- mov di,01B4h
- mov si,offset Resume
- mov cx,6
- call DisStr ;display Pausing message
-
- Mu: call DisStatus ;display task status
- call DisList ;display list of tasks
- ;fall thru to GetKey
- Main endp
- MainStuff endp
-
- ;============================================================================
- ; GetKey gets menu keystrokes and directs efforts as appropriate
- ;============================================================================
-
- GetKey proc
- M0: xor ah,ah
- int 16h
- cmp ah,1
- jne M2
- jmp Returnn ;Escape? then exit
-
- M2: cmp ah,49h ;PgUp
- je M3
- cmp ah,51h ;PgDn
- jne M4
- M3: call Chk_PgUp
- jmp M0
-
- M4: cmp Update?,1
- jne M41
- jmp M9 ;if Updating then jmp M9
-
- M41: cmp ah,26h ;Log-Off
- jne M5
- cmp TaskOff,0
- je M8
-
- call LogOff
- mov TaskOff,0
- jmp Returnn
-
- M5: cmp ah,2Eh ;Create new task?
- jne M6
- cmp Pausing?,1
- je M51
- cmp TaskOff,0
- je M51
- call LogOff ;if logged on then log-off first
- M51: call NewTask
- jmp M36
-
- M6: cmp ah,19h ;Pause?
- jne M7
- cmp TaskOff,0
- je M8
- call LogOff
- mov Pausing?,1
- jmp Returnn
-
- M7: cmp ah,13h ;Resume?
- jne M8
- cmp Pausing?,1
- jne M0
- call Start ;log back on
- jmp Returnn
-
- M8: cmp ah,16h ;Update?
- jne M9
- mov Update?,1
- push TaskOff ;save TaskOff
- call Update
- pop TaskOff ;restore TaskOff
- mov Update?,0
- jmp Returnn
-
- M9: cmp ah,1Fh ;Switch
- je M10
- cmp ah,26h ;Log-on
- je M10
- jmp M0
-
- M10: mov si,offset SelectTask
- mov Client?,0
- call GetNumber ;returns task # in al
-
- ;number has been pressed
- mov bl,0Dh
- mul bl
- add ax,offset TaskList ;offset of task name
-
- push ax
- cmp Pausing?,1
- je M35a
- cmp TaskOff,0
- je M35a
- call LogOff ;if logged on then log-off (switch)
-
- ;log on to task whose # was pressed
- M35a: pop ax
- mov TaskOff,ax
-
- M36: call GetComment ;get comment
-
- call Start ;log-on
- jmp Returnn ;exit
-
- GetKey endp
-
- ;============================================================================
- ; GetNumber returns with client (if Client?=1) or task number in AL
- ; Entry: SI = offset of prompt message
- ; Client? = 1 if getting client number else 0
- ; Exit: AL = client or task number
- ;============================================================================
-
- GetNumber proc
-
- GN0: push si
- mov ax,2 ;limit input to 2 characters
- call GetInput
- pop si
-
- mov al,Buffer ;convert to binary number
- sub al,'0'
- cmp al,9
- ja GN0
- cmp StrSize,1
- je GN1
- mov bl,0Ah
- mul bl
- mov bl,Buffer+1
- sub bl,'0'
- cmp bl,9
- ja GN0
-
- add al,bl
-
- GN1: mov cl,NumTasks
- cmp Client?,0
- je GN2
- mov cl,NumClients
- GN2: cmp al,cl
- jae GN0 ;check to see if number is out of limits
- mov Client?,0
- ret
- GetNumber endp
-
- ;============================================================================
- ; Returnn exits Trackr and restores everything as it was before popping up
- ;============================================================================
-
- Returnn proc
- push cs
- pop ds
-
- call CloseFiles ;close any open files
-
- mov bx,ParentPSP
- mov ah,50h
- int 21h ;restore parent PSP
-
- call SwapScreen
-
- mov ax,5D0Ah
- mov dx,offset ErrInfo
- int 21h ;restore extended error info
-
- mov ah,2
- mov dx,OrgCursor
- mov bh,VidPage
- int 10h ;restore cursor
-
- mov ax,StackPtr
- mov sp,ax ;restore stackptr
-
- pop es
- pop ds
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- mov cs:Up?,0
- iret
- Returnn endp
-
- ;============================================================================
- ; CloseFiles closes any open files
- ;============================================================================
-
- CloseFiles proc
- mov cx,3
- mov si,offset ClientFH
- Ret1: mov bx,[si]
- cmp bx,0FFFh
- je Ret2
- mov word ptr [si],0FFFh
- mov ah,3Eh
- int 21h
- Ret2: inc si
- inc si
- loop Ret1
- ret
- CloseFiles endp
-
- ;============================================================================
- ; DisStatus displays task name and elapsed time (or pausing message)
- ;============================================================================
-
- DisStatus proc
- mov al,' '
- mov di,offset Status+14
- push di
- mov cx,8
- rep stosb ;clear task name
- add di,18
- mov cx,5
- rep stosb ;clear elapsed time
- pop di
-
- mov si,TaskOff
- cmp si,0
- je ST3
-
- ;insert task name
- ST0: mov al,[si]
- cmp al,'.'
- je ST1
- mov [di],al
- inc si
- inc di
- jmp ST0
-
- ST1: mov di,offset Status+40
- cmp Pausing?,1
- jne ST2
- inc di
- mov si,offset Pause
- mov cx,5
- rep movsb ;insert "Pausing" if appropriate
- jmp ST3
-
- ST2: mov ax,Minutes
- call Encode ;convert elapsed time into ASCII
-
- ST3: mov si,offset Status
- mov cx,31h
- mov di,3Ch
- jmp DisStr ;display status message
- DisStatus endp
-
- ;============================================================================
- ; DisList displays the list of tasks
- ;============================================================================
-
- DisList proc
-
- DLz: call ClrList
-
- mov di,180h
- mov al,TopPage
- mov bl,0Dh
- mul bl
- add ax,offset TaskList
- mov si,ax ;first task name on page
-
- mov dl,TopPage
- mov cl,NumTasks
- sub cl,dl
- cmp cl,0Ah
- jbe DL1
- mov cx,0Ah
-
- DL1: push si
- push di
- mov al,dl
- aam
- xor ax,'00'
- mov es:[di],ah
- mov es:[di+2],al
- inc dl
- add di,6
-
- DL2: mov al,[si]
- cmp al,'.'
- je DL3
- mov es:[di],al
- inc si
- inc di
- inc di
- jmp DL2
-
- DL3: pop di
- pop si
- add si,0Dh
- add di,0A0h
- cmp di,04A0h
- jb DL4
- mov di,019Ah
- DL4: loop DL1
- push ds
- pop es
- ret
- DisList endp
-
- ;============================================================================
- ; ClrList clears the screen where the task list goes
- ;============================================================================
-
- ClrList proc
- mov ah,NAt
- mov al,' '
- mov es,VidSeg
- mov di,180h
- mov cx,5
- DL0: push cx
- push di
- mov cx,18h
- rep stosw
- pop di
- add di,0A0h
- pop cx
- loop DL0
- ret
- ClrList endp
-
- ;============================================================================
- ; MakeDate gets date and converts to DD/MM/YR format in "Today" variable
- ;============================================================================
-
- MakeDate proc
- mov ah,2Ah
- int 21h ;dh=month,dl=day,cx=yr
- mov al,dh
- aam
- xchg al,ah
- add ax,3030h
- mov word ptr Today,ax
- mov al,dl
- aam
- xchg al,ah
- add ax,3030h
- mov word ptr Today[3],ax
- sub cx,076Ch
- D1: cmp cx,64h
- jae D1
- mov al,cl
- aam
- xchg al,ah
- add ax,3030h
- mov word ptr Today[6],ax
- ret
- MakeDate endp
-
- ;============================================================================
- ; LogOff logs off the current task and updates the task file
- ;============================================================================
-
- LogOff proc
- call Stop ;get log-off time
- cmp Pausing?,1
- jne LO1
- mov Pausing?,0
- ret
- LO1: mov LogOff?,1
- jmp FixLog ;update task file
- LogOff endp
-
- ;============================================================================
- ; SwapScreen moves data in the "Screen" and "Attributes" buffers back onto
- ; the screen and vice versa.
- ;============================================================================
-
- SwapScreen proc
- ;swaps screen to "Screen" buffer
- mov es,VidSeg
- mov di,3Ch
- mov si,offset Screen
- mov cx,8
-
- SW1: push cx
- push di
-
- mov cx,31h
- SW2: mov ax,es:[di]
- mov bl,[si]
- mov bh,[si+188h]
- mov es:[di],bx
- mov [si],al
- mov [si+188h],ah
- inc si
- inc di
- inc di
- loop SW2
-
- pop di
- pop cx
- add di,0A0h
- loop SW1
-
- push ds
- pop es
- ret
- SwapScreen endp
-
- ;============================================================================
- ; AdjVidSeg adjusts VidSeg for offset into the screen (pages)
- ;============================================================================
-
- AdjVidSeg proc
- push es
- mov ax,40h
- mov es,ax
- mov ax,es:4Eh ;screen offset
- mov cl,4
- shr ax,cl ;divided by 16
- add ax,OrgVidSeg
- mov VidSeg,ax ;add to original video segment
- pop es
- ret
- AdjVidSeg endp
-
- ;============================================================================
- ; Update gets task number and then updates the task file to incorporate
- ; additions or changes
- ;============================================================================
-
- Update proc
- mov HoldSP,sp
- mov si,offset SelectTask
- mov Client?,0
- call GetNumber ;returns with task number in al
- mov bl,0Dh
- mul bl
- add ax,offset TaskList
- mov TaskOff,ax
- call FixLog ;fix the task file
- mov sp,HoldSP
- ret
- Update endp
-
- ;============================================================================
- ; LoadLog opens the task file with LogFH=file handle
- ; moves to first data location
- ; gets Units and Rate info
- ;============================================================================
-
- LoadLog proc
- mov di,NameOff
- mov si,TaskOff
- mov cx,0Dh
- rep movsb
-
- mov ax,3D02h
- mov dx,offset Drive
- int 21h ;open file
- jnc S1
-
- S0: push cs ;unable to open file
- pop ds
- jmp TaskErr
-
- S1: mov LogFH,ax ;file handle
- mov bx,ax
- mov LogFH,ax
- mov al,2
- mov RecOff,0
- ;fall through to GetHeader
- LoadLog endp
-
- ;============================================================================
- ; GetHeader loads in Units and Rate information and returns with file at start
- ; of next entry and AX=offset into file of next entry
- ; Entry: AL = 0 if task, 1 if making Client array, 2 if making new task
- ; BX = file handle (LogFH or ClientFH)
- ; Exit: AX = file offset of next entry
- ;============================================================================
-
- GetHeader proc
- mov Flag,al
- mov HoldFH,bx
- mov EoF,0
-
- H1: mov dx,RecOff
- xor cx,cx
- mov ax,4200h
- int 21h ;mov to file ptr to RecOff
-
- ;read 10 more than scanning to account for unit message length overrun
- mov ah,3Fh
- mov cx,50h
- mov dx,offset Buffer
- int 21h ;read
-
- mov cx,ax ;bytes read
- cmp Flag,1
- jne H2
-
- ;making client array
- push di
- push cx
- mov si,dx
-
- ;go past tabs, spaces, linefeeds and carraige returns
- H14: mov al,[si]
- cmp al,7
- je H15
- cmp al,' '
- je H15
- cmp al,0Ah
- je H15
- cmp al,0Dh
- jne H16
- H15: inc si
- jmp H14
-
- H16: mov di,offset Client
- mov cx,15h
- rep movsb ;move in client name
- pop cx
- pop di
- mov Flag,0
-
- H2: cmp cx,50h ;bytes read
- je H3
- mov EoF,1 ;set EoF if bytes read less than requested
-
- H3: mov di,dx
- mov cx,46h
- H31: mov al,'\'
- repne scasb ;look for start of rate info
-
- cmp cx,0
- je H34
-
- ;check to see if '\' is first character in line
- cmp di,offset Buffer+1
- je H4
- push di
- dec di
- H32: dec di
- mov al,[di]
- cmp al,' '
- je H32
- cmp al,0Ah
- je H33
- cmp al,0Dh
- je H33
-
- pop di ;'\' isn't first character in line
- jmp H31 ;so keep looking
-
- H33: pop di
- jmp H4
-
- ;haven't found '\' yet
- H34: cmp EoF,1
- je H4 ;if end of file then goto H4
-
- add RecOff,46h ;else read in more and try again
- cmp Flag,2
- je H34a
- jmp H1
-
- H34a: mov bx,TempFH ;if making new task then write info to
- ;TEMP file first
- mov ah,40h
- mov cx,46h
- int 21h ;write info to TEMP file
- jnc H35
- jmp TaskErr
-
- H35: mov bx,HoldFH ;restore original file handle
- jmp H1 ;go read in more and continue search
-
- H4: call GetVal
- mov Rate,ax ;get Rate Value
- call GetVal
- mov Units,ax ;get Units value (billing increment)
-
- S3: mov al,[di] ;go past end of line
- cmp al,0Dh
- je S4
- cmp al,0Ah
- jne S5
- S4: inc di
- jmp S3
-
- S5: sub di,offset Buffer
- cmp Flag,2
- jne S6
-
- mov cx,di ;if creating new task then write info
- ;to TEMP file
- mov bx,TempFH
- mov ah,40h
- int 21h
- jnc S6
- jmp TaskErr
-
- S6: mov dx,di ;change RecOff to next record's offset
- add dx,RecOff
- mov RecOff,dx
- xor cx,cx
- mov ax,4200h
- mov bx,HoldFH
- int 21h ;move file pos to next record
- ret
- GetHeader endp
-
- ;============================================================================
- ; GetVal takes ASCII # pointed to by DI and returns a binary number in AX
- ; and DI pointing to the next ASCII # or carraige return. Used for
- ; decoding task files or CLIENT.DAT.
- ; Entry: DI = offset of ASCII number
- ; Exit: AX = binary number
- ; DI = offset of next ASCII # or CR
- ;============================================================================
-
- GetVal proc
- xor ax,ax
- mov cx,ax
- mov bl,0Ah
-
- G1: mov cl,[di]
- cmp cl,0Dh
- je G2
- cmp cl,'\'
- je G2
- sub cl,'0'
- cmp cl,9
- ja G15
- mul bl
- add ax,cx
- G15: inc di
- jmp G1
- G2: inc di
- ret
- GetVal endp
-
- ;============================================================================
- ; NewTask
- ;============================================================================
-
- NewTask proc
- mov si,offset SelectTask-1
- call DisMenu ;display "Select task" menu
- call GetClients ;get clients from CLIENT.DAT
- mov CTopPage,0
- NT0: call DisClients ;display client list
-
- mov si,offset InpClient
- mov Client?,1
- call GetNumber ;get client #
-
- call MovPtr ;move file ptr to client
-
- ;create new task file
- NT8a: mov si,offset NameMsg
- mov ax,8
- call GetInput ;get task file name
- mov si,offset Buffer
- mov di,NameOff
-
- NT9: mov al,[si]
- cmp al,0Dh
- je NT11
- cmp al,' ' ;no spaces allowed
- je NT11c
- cmp al,'.' ;ignore extension
- je NT11
-
- cmp al,'a'
- jb NT10
- cmp al,'z'
- ja NT10
- sub al,20h ;change to upper case
- NT10: mov [di],al
- inc si
- inc di
- jmp NT9
-
- NT11: mov si,offset Extension
- mov cx,5
- rep movsb ;add .LOG extension
-
- mov dx,offset Drive
- mov ax,3D02h
- int 21h ;check for duplicate file
- jc NT11b
-
- mov bx,ax
- mov ah,3Eh
- int 21h ;file already exists so close file
-
- mov si,offset DupNameMsg
- NT11a: call DisErrMsg
- jmp NT8a
-
- ;create new file
- NT11b: mov ah,3Ch
- xor cx,cx
- mov dx,offset Drive
- int 21h ;create new task file
- jnc NT12
-
- NT11c: mov si,offset InvNameMsg
- jmp NT11a ;invalid file name, try again
-
- NT12: mov TempFH,ax ;file handle of task file
-
- mov si,NameOff
- call PutTask ;add task name to task list
-
- mov bx,ClientFH
- mov al,2 ;flag
- call GetHeader ;get info from CLIENT.DAT and create
- ;task file
- mov bx,ClientFH
- mov ClientFH,0FFFh
- mov ah,3Eh ;close CLIENT.DAT
- int 21h
-
- mov bx,TempFH
- mov TempFH,0FFFh
- mov ah,3Eh ;close TEMP file
- int 21h
- ret
- NewTask endp
-
- ;============================================================================
- ; DisClients displays the list of clients starting with CTopPage as the first
- ; client
- ;============================================================================
-
- DisClients proc
- call ClrList ;clear the screen
- push ds
- pop es
- mov al,CTopPage
- mov Flag,al
- mov di,186h
- mov cx,5
-
- NT1: mov al,5
- sub al,cl
- add al,CTopPage
- cmp al,NumClients
- jb NT13
- ret
-
- NT13: push cx
- push di
-
- mov bx,ClientFH
- call MovPtr
- mov dx,offset Client
- mov cx,15h
- mov ah,3Fh
- int 21h ;read in first 21 bytes of client data
-
- pop di
- push di
-
- mov es,VidSeg
- mov al,Flag
- aam
- or ax,'00'
- mov es:[di-6],ah
- mov es:[di-4],al ;display client number
- inc Flag
- mov cx,15h
- mov si,offset Client
-
- NT15: mov al,[si]
- cmp al,0Ah
- je NT2
- cmp al,0Dh
- je NT2
- cmp al,7
- je NT2
- cmp al,' '
- jne NT3
- NT2: inc si
- dec cx
- jmp NT15
-
- NT3: call DisStr ;display 15 bytes of client info
- pop di
- add di,0A0h
-
- pop cx
- loop NT1
- ret
- DisClients endp
-
- ;============================================================================
- ; MovPtr takes client number in AL and returns with file ptr at client's
- ; record
- ; Entry: AL = # of client
- ;============================================================================
-
- MovPtr proc
- xor ah,ah
- shl ax,1
- add ax,offset ClientArray
- mov di,ax
- mov dx,[di]
- mov RecOff,dx
- xor cx,cx
- mov ax,4200h
- mov bx,ClientFH
- int 21h ;move file ptr to first entry
- ret
- MovPtr endp
-
- ;============================================================================
- ; FixLog updates task log pointed to by TaskOff
- ;
- ; Entry: TaskOff pointing to desired task
- ;============================================================================
-
- FixLog proc
- mov DayTot,0
- mov di,NameOff
- mov si,offset TempFN
- mov cx,5
- rep movsb ;make full pathname for TEMP
- mov dx,offset Drive
- mov ah,3Ch
- xor cx,cx
- int 21h ;create TEMP file
- jnc FL1
- jmp TaskErr
-
- FL1: mov bx,ax ;file handle
- mov TempFH,ax
-
- mov Flag,2
- call LoadLog
-
- cmp LogOff?,1
- jne FL4
-
- ;if logging off add new entry to file
- mov di,offset Buffer+2
- mov al,' '
- mov cx,50h
-
- push di
- rep stosb
- pop di
-
- mov si,offset Today
- mov cx,8
- rep movsb ;mov in today's date
-
- mov ax,LogIn
- mov di,offset Buffer+11
- call Encode ;add log in time
-
- mov ax,LogOut
- mov di,offset Buffer+18
- call Encode ;add log out time
-
- mov di,offset Buffer+31
- mov si,offset Comments-2
- FL2: mov al,[si] ;add comments
- cmp al,0Dh
- je FL3
- mov [di],al
- inc di
- inc si
- jmp FL2
-
- FL3: mov ax,0A0Dh
- mov [di],ax
- mov word ptr Buffer,ax ;add carraige return, line feed
- sub di,offset Buffer-4
-
- xor cx,cx
- mov dx,cx
- mov ax,4202h
- mov bx,LogFH
- int 21h ;move to end of task file
-
- mov dx,offset Buffer
- mov cx,di
- mov ah,40h
- int 21h ;write entry
- jnc FL35
- jmp TaskErr
-
- FL35: mov ax,4200h
- mov dx,RecOff
- xor cx,cx
- int 21h ;return to first record
- mov LogOff?,0
- mov EoF,0
-
- FL4: mov FirstRec?,1
-
- FL5: mov bx,LogFH
- mov cx,50h
- mov ah,3Fh
- mov dx,offset Buffer
- int 21h ;read in 80 bytes from task file
-
- cmp ax,0 ;ax=bytes read
- jne FL6
- jmp FL22
-
- FL6: mov BytesRead,ax
- mov cx,ax
- add ax,offset Buffer
- mov EndRec,ax
-
- ;search for 13 then go until not 10 or 13, this is next record
- mov di,offset buffer
- mov al,0Dh
- repne scasb
- cmp cx,0
- jne FL7
- mov EoF,1
-
- FL7: mov al,[di]
- cmp al,0Dh
- je FL8
- cmp al,0Ah
- jne FL9
- FL8: inc di
- cmp di,EndRec
- jb FL7
-
- FL9: sub di,offset Buffer
- mov dx,di
- add dx,RecOff
- mov RecOff,dx ;RecOff points to next record
- xor cx,cx
- mov ax,4200h
- int 21h ;mov source file to next record
-
- cmp di,20h
- jae FL10
-
- dec di
- dec di
- mov cx,1Eh
- sub cx,di
- mov al,' '
- add di,offset Buffer
- rep stosb
- mov word ptr [di],0A0Dh
-
- FL10: cmp Buffer+0Ch,':'
- jne FL11
- cmp Buffer+13h,':'
- je FL12
- FL11: jmp FL21
-
- FL12: cmp FirstRec?,1
- jne FL13
- mov FirstRec?,0
- jmp FL16
-
- FL13: cmp Buffer,' ' ;no date
- jne FL14
- jmp FL18
-
- FL14: mov di,offset Buffer
- mov si,offset Date
- mov cx,8
- repe cmpsb ;compare entry date with last entry
- jz FL17
-
- ;new date
- call DayTally
-
- FL16: mov si,offset Buffer
- mov di,offset Date
- mov cx,8
- rep movsb
- jmp FL18
-
- ;dates are same
- FL17: mov al,' '
- mov cx,8
- mov di,offset Buffer
- rep stosb
-
- FL18: mov si,offset Buffer+0Ah
- call Decode
- push ax ;log in time
- mov si,offset Buffer+11h
- call Decode ;log off time
- pop bx
- sub ax,bx ;elapsed minutes
- cmp ax,0
- jne FL19
- inc ax
- FL19: jg FL191
- add ax,05A0h ;minutes in 24 hours
- FL191: mov bx,Units
- cmp bx,1
- je FL20
- xor dx,dx
- div bx
- inc ax
- mul bx ;elapsed time in billing increments
- FL20: add DayTot,ax ;add to day total
- add Total,ax ;add to grand total
- mov di,offset Buffer+17h
- call Encode ;encode and add to log entry string
- mov dx,offset Buffer
- call WrtEntry ;write log entry string
-
- FL21: cmp EoF,1
- je FL22
- jmp FL5
-
- ;construct and display summary
- FL22: call DayTally
- mov ax,Total
- mov di,offset TotalMsg+23
- call Encode
- cmp Rate,0
- jne FL23
- mov di,offset TotalMsg+31
- mov al,' '
- mov cx,10
- rep stosb
- jmp FL24
-
- FL23: mov ax,Total
- mov di,offset TotalMsg+40
- call EncBucks
-
- FL24: mov dx,offset TotalMsg
- call WrtEntry
- mov Total,0
-
- mov bx,TempFH
- mov TempFH,0FFFh
- mov ah,3Eh
- int 21h ;close TEMP file
-
- mov bx,LogFH
- mov LogFH,0FFFh
- mov ah,3Eh
- int 21h ;close .LOG file
-
- mov di,NameOff
- mov si,TaskOff
- mov cx,0Dh
- rep movsb ;make complete pathname for task file
-
- mov si,offset Drive ;contains task's complete pathname
- mov di,offset Buffer
- mov cx,50h
- rep movsb ;move task name to buffer
-
- mov di,NameOff
- mov si,offset TempFN
- mov cx,5
- rep movsb ;make full pathname for TEMP
-
- mov dx,offset Buffer
- mov ah,41h
- int 21h ;delete original task file
- jnc FL25
- jmp TaskErr
-
- FL25: mov di,offset Buffer
- mov dx,offset Drive
- mov ah,56h
- int 21h ;rename TEMP to task file
- ret
- FixLog endp
-
- ;============================================================================
- ; DayTally makes the daily total entry for the task log
- ;============================================================================
-
- DayTally proc
- mov ax,DayTot
- cmp ax,0
- jne DT1
- ret
- DT1: mov di,offset DayTotMsg+23
- call Encode
- mov di,offset DayTotMsg+31
- mov al,' '
- mov cx,10
- rep stosb
- cmp Rate,0
- je DT4
-
- DT2: mov ax,DayTot
- mov di,offset DayTotMsg+40
- call EncBucks
-
- DT4: mov DayTot,0
- mov dx,offset DayTotMsg
- mov cx,2Dh
- jmp WriteEntry
- DayTally endp
-
- ;============================================================================
- ; WrtEntry takes a log entry pointed to by DX and writes it to the file whose
- ; file handle is in TempFH
- ; Entry: DX - pointing to log entry string
- ; TempFH - holding file handle
- ;============================================================================
-
- WrtEntry proc
- mov di,dx
- mov al,0Ah
- mov cx,50h
- repne scasb
-
- sub di,dx
- mov cx,di
- WriteEntry proc
- mov bx,TempFH
- mov ah,40h
- int 21h
- jc Err
- ret
- Err: jmp TaskErr
- WriteEntry endp
- WrtEntry endp
-
- ;============================================================================
- ; EncBucks displays flush right at DI, minutes (in AX) times Rate
- ; Entry: AX = minutes
- ; DI = where rightmost character goes
- ;============================================================================
-
- EncBucks proc
- mov bx,di
- mov cx,8
- sub bx,cx
- EB00: mov byte ptr [bx],' '
- inc bx
- loop EB00 ;clear display area
-
- mov bx,Rate
- mul bx ;hourly rate times minutes
- mov bx,3Ch
- div bx ;divided by 60
- mov cx,ax ;dollars
- mov ax,dx ;remainder
- mov bl,64h
- mul bl ;multiplied by 100
- mov bl,3Ch
- div bl ;and divided by 60, al=cents
- aam
- xchg ah,al
- add ax,3030h
- dec di
- mov [di],ax ;display cents
- dec di
- mov byte ptr [di],'.'
- mov ax,cx ;ax = dollars
-
- EB2: dec di
- cmp ax,0
- je EB3
- xor dx,dx
- mov bx,0Ah
- div bx
- add dl,'0'
- mov [di],dl ;display dollars
- jmp EB2
-
- EB3: dec di
- mov byte ptr [di],'$'
- ret
- EncBucks endp
-
- NeedDATAmsg db ' Unable to open CLIENT.DAT.',0
- WriteErrMsg db ' Unable to create, open, or modify .LOG file. ',0
-
- ;============================================================================
- ; TaskErr handles errors with the task (.LOG) file
- ;============================================================================
-
- TaskErr proc
- mov TaskOff,0
- mov si,offset WriteErrMsg
- TaskErr endp
-
- ;============================================================================
- ; DisErr displays the error message in SI, waits for keypress and return to
- ; the "Main" procedure
- ;============================================================================
-
- DisErr proc
- call ClrLine
- mov di,3Ch
- call DisStrZ
- xor ah,ah
- int 16h
- Abort: push cs
- pop ds
-
- call CloseFiles
-
- AB0: mov ax,StackPtr
- mov sp,ax
- cmp NumTasks,0
- jne AB1
- jmp Returnn
- AB1: jmp Main
- DisErr endp
-
- ;============================================================================
- ; DisErrMsg displays the Error message pointed at by SI and waits for keypress
- ;============================================================================
-
- DisErrMsg proc
- call ClrLine
- mov di,3Eh
- call DisStrZ
- xor ah,ah
- int 16h
- ret
- DisErrMsg endp
-
- ;============================================================================
- ; Chk_PgUp chks for PgUp and PgDn while at a menu and acts accordingly
- ;============================================================================
-
- Chk_PgUp proc
- GI1: cmp ah,49h
- jne GI3
- ;PgUp
- cmp Client?,1
- jne GI2
- cmp CTopPage,0
- jne GI1b
- GI1a: ret
- GI1b: sub CTopPage,5
- jmp GI4
-
- GI2: cmp TopPage,0
- je GI1a
- sub TopPage,0Ah
- jmp GI6
-
- ;PgDn
- GI3: cmp Client?,1
- jne GI5
- mov al,NumClients
- sub al,CTopPage
- cmp al,5
- jbe GI1a
- add CTopPage,5
- GI4: push di
- call DisClients
- pop di
- ret
-
- GI5: mov al,NumTasks
- sub al,TopPage
- cmp al,0Ah
- jbe GI6
- add TopPage,0Ah
- GI6: push di
- call DisList
- pop di
- ret
-
- Chk_PgUp endp
-
- ;============================================================================
- ; GetInput displays prompt message and then gets keyboard input which it puts
- ; in "Buffer"
- ; Entry: SI = pointer to prompt message
- ; AX = max length of input
- ; Exit: Buffer - holds keyboard input string
- ;============================================================================
-
- GetInput proc
-
- add ax,offset Buffer
- mov EndStr,ax
-
- call ClrLine ;clear the input area on screen
-
- mov di,3Ch
- call DisStrZ ;display prompt
- mov di,offset Buffer
-
- mov Cursor,28h
- jmp J1
-
- ;get input
- J0: xor ah,ah
- int 16h
- cmp ah,1 ;escape?
- jne J02
- jmp Abort
-
- J02: cmp ah,49h ;PgUp?
- je J03
- cmp ah,51h ;PgDn?
- jne J05
- J03: call Chk_PgUp
- jmp J0
-
- J05: cmp ah,0Eh ;BS
- je J2
- cmp al,0Dh ;return
- je J9
- cmp al,80h ;no values >127
- jae J0
-
- cmp di,EndStr
- jae J0
-
- mov ah,0Ah
- mov cx,1
- int 10h ;display value
- mov [di],al
- inc di
-
- J1: inc Cursor
- mov ah,2
- xor bh,bh
- mov dx,Cursor
- int 10h ;advance cursor
- jmp J0
-
- ;backspace
- J2: cmp Cursor,29h
- jne J3
- jmp J0
- J3: dec Cursor
- dec di
- mov byte ptr [di],0
- mov ah,2
- mov dx,Cursor
- int 10h
- mov al,' '
- mov ah,0Ah
- mov cx,1
- int 10h
- jmp J0
-
- J9: mov ah,2
- mov dx,2000h
- mov bh,VidPage
- int 10h
-
- mov byte ptr [di],0Dh ;add carraige return
- mov ax,di
- sub ax,offset Buffer
- mov StrSize,al
-
- push ds
- pop es
-
- ret
- GetInput endp
-
- ;============================================================================
- ; ClrLine clears top line of Trackr's screen
- ;============================================================================
-
- ClrLine proc
- mov di,3Ch
- mov cx,31h
- mov ax,word ptr Space
- mov es,VidSeg
- rep stosw ;clear line
- push ds
- pop es
- ret
- ClrLine endp
-
- ;============================================================================
- ; DisStrZ displays ASCIIZ string
- ; Entry: SI = offset of string
- ; DI = offset of destination
- ;============================================================================
-
- DisStrZ proc
- mov cx,255 ;fall through to DisStr
-
- ;============================================================================
- ; DisStr displays string
- ; Entry: SI = offset of string
- ; CX = string length
- ; DI = destination offset
- ;============================================================================
-
- DisStr proc
- ;enter with di pointing to destination, cx=str len, si point to str
- mov es,VidSeg
- DS1: mov al,[si]
- cmp al,0
- je DS3
- cmp al,0Dh
- jne DS2
- mov al,' '
- dec si
- DS2: mov es:[di],al
- inc si
- inc di
- inc di
- loop DS1
- push ds
- pop es
- DS3: ret
- DisStr endp
- DisStrZ endp
-
- ;============================================================================
- ; DisMenu displays the menu options
- ; Entry: SI = offset of Menu string
- ;============================================================================
-
- DisMenu proc
- ;clear the screen
- mov ah,NAt
- mov al,' '
- mov di,01B4h
- push di
- mov es,VidSeg
- mov cx,5
- DMx: push cx
- push di
- mov cx,13h
- rep stosw
- pop di
- pop cx
- add di,0A0h
- loop DMx
-
- pop di
- push di
-
- DM0: mov al,[si] ;menu string
- cmp al,3
- jne DM1
- pop di ;if al=3 then return
- push ds
- pop es
- ret
-
- DM1: cmp al,1 ;if al=1 then hi-lite last value
- jne DM2
- mov al,HAt
- mov es:[di-1],al
- inc si
- jmp DM0
-
- DM2: cmp al,2 ;if al=2 then go to next line
- jne DM3
- inc si
- mov al,[si]
- pop di
- add di,0A0h
- push di
- DM3: mov es:[di],al ;else display character
- inc si
- inc di
- inc di
- jmp DM0
- DisMenu endp
-
- ;============================================================================
- ; GetComment gets log on comments for task entry
- ;============================================================================
-
- GetComment proc
- mov si,offset CommentMsg
- mov ax,1Eh
- call GetInput
- mov cl,StrSize
- mov ch,0
- inc cx
- mov si,offset Buffer
- mov di,offset Comments
- rep movsb
- mov byte ptr [di],0
- jmp DisStatus
- GetComment endp
-
- ;============================================================================
- ; PutTask inserts task information into task list in alphebetical order
- ; Entry: SI = offset of task name
- ; Exit: TaskOff pointing to desired task
- ; task list in alphabetical order
- ;============================================================================
-
- PutTask proc
- ;enter with si pointing to task name
- ;returns with TaskOff and task list in alpha order
-
- mov Temp,si
- mov di,offset TaskList-0Dh
- mov cl,NumTasks
- cmp cl,32h
- jb PT1
- dec cl
- mov NumTasks,cl ;ignore tasks if more than 50
- PT1: xor ch,ch
- inc cx
-
- CR11: add di,0Dh
- push di
- push cx
- mov cx,0Dh
- mov si,Temp
- cmp word ptr [di],0
- je CR11a
- repe cmpsb
- CR11a: pop cx
- pop di
- jbe CR12
- loop CR11 ;doesn't go here, keep trying
-
- CR12: mov ax,di
- mov di,offset TaskList+289h
- cmp ax,di
- jae CR13
- mov si,di
- sub si,0Dh
- mov cx,si
- sub cx,ax
- inc cx
-
- std
- rep movsb ;make room for new entry by moving
- ;other tasks up
- cld
- CR13: mov di,ax
- mov TaskOff,di
- mov si,Temp
- mov cx,0Dh
- rep movsb ;move in new task
- inc NumTasks
- ret
- PutTask endp
-
- ;============================================================================
- ; GetClients makes Client array from CLIENT.DAT file
- ;============================================================================
-
- GetClients proc
- xor ax,ax
- mov RecOff,ax
- mov NumClients,0
- mov di,offset ClientArray
- mov cx,1Eh
- rep stosw ;zero out ClientArray
-
- ;make Client Array
- mov di,NameOff
- mov si,offset ClientFN
- mov cx,11
- push es
- push ds
- pop es
- rep movsb ;make full pathname for CLIENT.DAT
- pop es
-
- mov ax,3D00h
- mov dx,offset Drive
- int 21h ;open CLIENT.DAT
- jnc K31
-
- mov si,offset NeedDATAmsg
- jmp DisErr ;if no CLIENT.DAT file then abort
-
- K31: mov bx,ax ;file handle
- mov ClientFH,ax
- mov di,offset ClientArray+2
- K4: push di
- mov al,1
- mov bx,ClientFH
- call GetHeader ;get client info
- inc NumClients
- pop di
-
- cmp NumClients,30
- jb K5
-
- mov si,offset TooManyMsg
- jmp DisErrMsg ;more than 30 clients
-
- K5: mov ax,RecOff
- mov [di],ax ;store in ClientArray
- inc di
- inc di
- cmp EoF,1 ;End of CLIENT.DAT file?
- jne K4
- ret
- GetClients endp
-
- Buffer db 108 dup (0)
-
- ;----------------------------------------------------------------------------
- ; Non-TSR portion
- ;----------------------------------------------------------------------------
-
- CodeSeg dw 0
- RemovedMsg db 0Dh,0Ah,'TRACKR is removed.',0Dh,0Ah,'$'
- UnableMsg db 0Dh,0Ah,'Unable to remove TRACKR.',0Dh,0Ah,'$'
- InHereMsg db 0Dh,0Ah,'TRACKR is already loaded',0Dh,0Ah,'$'
- Copyright db 0Ah,'TRACKR 1.0 Copyright (c) 1991 Ziff '
- db 'Communications Co.',0Dh,0Ah
- db 'PC Magazine ■ Scott Chaney',0Dh,0Ah,0Ah
- Syntax db 'Syntax: TRACKR [/#] [/U] [/I D:\PATH]',0Dh,0Ah
- db ' /# = Minutes between reminders '
- db '(1-9, 0=disable)',0Dh,0Ah
- db ' /U = Uninstall',0Dh,0Ah
- db ' /I = Sets path for .LOG files',0Dh,0Ah,0Ah
- ActMsg db 'Activation Hot Key: '
- HKmsg db 'Ctrl-R ',0Dh,0Ah,'$'
-
- Init proc
-
- push cs
- pop es
-
- B4: mov ax,cs
- mov ds,ax
- mov es,ax
-
- ;check for DOS 3.0 or greater
- mov ah,30h
- int 21h
- cmp al,3
- jae B5
- mov dx,offset WrongVerMsg
- jmp P32b
-
- ;get our PSP
- B5: mov ah,51h
- int 21h
- mov OurPSP,bx
-
- ;move NAt into attribute array
- mov al,HAt
- mov cx,31h
- mov di,offset Attributes
- rep stosb
- mov cx,157h
- mov al,NAt
- rep stosb
-
- ;check for command line
- In0: mov bx,80h
- mov cl,[bx] ;number of characters in command line
- cmp cl,0
- jne In2
- In1: jmp P4
-
- In2: mov si,81h
-
- Parse: mov al,[si]
- inc si
- cmp al,0Dh
- je In1
- cmp al,'/'
- je Parse
- P01: cmp al,' '
- je Parse
-
- cmp al,'?'
- jne P012
-
- ;asking for help: display copyright and exit
- mov dx,offset Syntax
- mov ah,9
- mov ActMsg,'$'
- int 21h
- mov ah,4Ch
- int 21h
-
- P012: cmp al,'0'
- jb P015
- cmp al,'9'
- ja P015
-
- ;adjusting reminder interval
- sub al,'0'
- jnz P013
- mov Display?,0
- jmp P4 ;if 0 then no reminders
-
- P013: mov bl,al
- mov ax,0444h
- mul bx ;multiply reminder interval by clock
- ;ticks per minute
- mov WaitTicks,ax
-
- jmp P4
-
- P015: or al,20h
-
- cmp al,'u' ;uninstall?
- jne P3
- jmp UnInstall
-
- P3: cmp al,'i' ;initialize path for .LOG files?
- jne Parse
- mov di,offset Drive
-
- P31: lodsb
- cmp al,' '
- je P31
- cmp al,0Dh
- je P32
- stosb ;store path in "Drive"
- jmp P31
-
- P32: mov al,'\' ;add '\' to end
- stosb
- mov NameOff,di ;put offset in NameOff
-
- ;get full pathname of TRACKR.COM
- mov ax,cs:2Ch
- mov es,ax
- xor ax,ax
- mov di,ax
- mov cx,1024
- GP0: cmp word ptr es:[di],ax
- je GP1
- inc di
- loop GP0
- mov dx,offset ThisFile
- jmp GP2
-
- GP1: add di,4
- mov dx,di
- push es
- pop ds
-
- GP2: mov ax,3D02h
- int 21h ;open TRACKR.COM
- push cs
- pop ds
- jnc P33
-
- ;can't find TRACKR.COM
- P32a: mov dx,offset CantInitMsg
- P32b: mov ah,9
- int 21h
- mov ah,4Ch
- int 21h ;end
-
- P33: mov bx,ax ;file handle
- mov cx,54h
- mov dx,100h
- mov ah,40h
- int 21h ;write task and client directory info
- jc P32a
- mov ah,3Eh
- int 21h ;close file
-
- P4: call Loaded? ;Trackr loaded already?
- jne P45
-
- mov dx,offset InHereMsg ;if so, say so and quit
- mov ah,9
- int 21h
- mov ah,4Ch
- int 21h
-
- P45: mov ah,0Fh ;get video mode
- int 10h
- xor ah,ah
- cmp al,7
- je L1
- mov al,3
- mov OrgVidSeg,0B800h ;set video segment (0B000 by default)
-
- L1: mov dx,offset DTA
- mov ah,1Ah
- int 21h ;set DTA
-
- ;make task list
- push cs
- pop es
-
- mov di,NameOff
- mov si,offset SrchName
- mov cx,6
- rep movsb
-
- mov dx,offset Drive
- mov cx,0
- mov ah,4Eh
-
- int 21h ;find first .LOG file
- jc K3
-
- K1: mov si,offset DTA+1Eh
- call PutTask
- cmp NumTasks,32h
- jb K2
- mov dx,offset Warning
- mov ah,9
- int 21h
- jmp K3
-
- K2: mov ah,4Fh
- int 21h ;find next .LOG file
- jnc K1
-
- K3: mov TaskOff,0
-
- mov ah,9
- mov dx,offset Copyright
- int 21h ;print copyright
-
- M1: mov ax,cs:2Ch
- mov es,ax
- mov ah,49h
- int 21h ;free environment memory
-
- mov ax,3509h
- int 21h ;get int 09 vector
- mov word ptr Vec09,bx
- mov word ptr Vec09[2],es
-
- mov ax,3513h
- int 21h ;get int vec 13
- mov word ptr Vec13,bx
- mov word ptr Vec13[2],es
-
- mov ax,3508h
- int 21h ;get int vec 1C
- mov word ptr Vec08,bx
- mov word ptr Vec08[2],es
-
- mov ax,3528h
- int 21h ;get int vec 28
- mov word ptr Vec28,bx
- mov word ptr Vec28[2],es
-
- mov ah,34h
- int 21h ;location of DOS busy byte
- mov DBseg,es
- mov DBoff,bx
-
- mov dx,offset Int09
- mov ax,2509h
- int 21h ;set vector for Int 09
-
- mov dx,offset Int13
- mov ax,2513h
- int 21h ;set vector for Int 13
-
- mov dx,offset Int08
- mov ax,2508h
- int 21h ;set vector for Int 1C
-
- mov dx,offset Int28
- mov ax,2528h
- int 21h ;set vector for Int 28
-
- mov ax,offset CodeSeg
- mov cl,4
- shr ax,cl
- inc ax
- mov dx,ax ;paragraphs to remain resident
- mov ax,3100h
- int 21h ;go TSR
- Init endp
-
- UnInstall proc
- call Loaded?
- je UI1
- jmp U2
-
- UI1: mov CodeSeg,es
- ;check to see if anyone else has taken our interupts
- mov ax,es
- xor si,si
- mov ds,si
- cmp [si+26h],ax ;Int 09
- jne Unable
- cmp [si+4Eh],ax ;Int 13h
- jne Unable
- cmp [si+22h],ax ;Int 08h
- jne Unable
- cmp [si+0A2h],ax ;Int 28h
- je U1
-
- Unable: mov ah,9
- mov dx,offset UnableMsg
- push cs
- pop ds
- int 21h
- mov ah,4Ch
- int 21h
-
- U1: inc es:Message+2 ;change message
-
- ;reset interupts to original values
- mov dx,word ptr es:Vec09
- mov ax,word ptr es:Vec09[2]
- mov ds,ax
- mov ax,2509h ;reset int 09
- int 21h
-
- mov dx,word ptr es:Vec13
- mov ax,word ptr es:Vec13[2]
- mov ds,ax
- mov ax,2513h ;reset int 13
- int 21h
-
- mov dx,word ptr es:Vec08
- mov ax,word ptr es:Vec08[2]
- mov ds,ax
- mov ax,2508h ;reset int 1C
- int 21h
-
- mov dx,word ptr es:Vec28
- mov ax,word ptr es:Vec28[2]
- mov ds,ax
- mov ax,2528h ;reset int 28
- int 21h
-
- mov ah,49h
- int 21h ;free memory block
-
- push cs
- pop ds
- mov dx,offset RemovedMsg
- mov ah,9
- int 21h ;print message
- U2: mov ah,4Ch
- int 21h ;end
-
- UnInstall endp
-
- Loaded? proc
- ;checks to see if TSR already is loaded. If it is then zf set upon
- ;return and es:di points to offset info in TSR
-
- mov bx,offset Message
- inc Message ;avoid disk cache match
- mov ax,cs
- mov dx,0A000h-1
- NextPara: inc dx ;next paragraph
- mov es,dx
- cmp dx,ax
- je NotHere ;If our seg then search is done
- mov si,bx ;else check for match
- mov di,bx
- mov cx,0Ah
- rep cmpsb ;a match?
- jnz NextPara ;if no match, keep looking
- ret
-
- NotHere: inc ax
- cmp ax,dx ;return with not equal
- ret
-
- Loaded? endp
-
- CantInitMsg db 'Unable to locate TRACKR.COM. Aborting.$'
- Warning db 0Dh,0Ah,'WARNING: Number of tasks exceeds limit'
- db ' of 50. Extras will be ignored.',7,0Dh,0Ah,'$'
- WrongVerMsg db 'Sorry, TRACKR needs DOS 3.0 or greater.',7,'$'
-
- ;data needed for CONFIG program
- Preface db 255,'*RsE*',128
- Method db 1
- Colors db 2
- ColorOff dw offset HAt
- NumKeys db 1
- NumEtc db 0
- SSoff dw offset ShiftState
- SCoff dw offset ScanCode
- DesOff dw offset HKmsg
-
- Code ends
- end LGo
-
-