Date: 29 Mar 90 20:13:24 GMT
From: madler@tybalt.caltech.edu (Mark Adler)
Organization: California Institute of Technology, Pasadena
Subject: Shorter APPT, APDIR (this is a LONG message)
Message-Id: <1990Mar29.201324.3810@spectre.ccsf.caltech.edu>
Sender: handhelds-request@csl.sri.com
To: handhelds@csl.sri.com
After getting the Appointment application (APPT and APDIR) from the
HP bulletin board and kermiting it over to my calculator, I found
that I didn't have much memory left. With a few other things loaded
in as well (the stopwatch, some of my own things), I started thinking
about buying more memory for the thing. Then I looked at the
programs in APDIR, and decided it was really a ploy to make me get
more memory. It almost worked too!
Without changing the functionality whatsoever, I reduced the size of
APDIR from 13714 bytes to 8173.5 bytes. I did this by rewriting
parts of the programs, putting them all in one directory, and
combining some programs (and even fixing a bug or two here and
there). It is even a little faster now. The thing really deserves a
total rewrite, and I estimate it could be made faster and more
functional in less than 5 or 6K bytes. But, alas, I don't have time
for that. Anyway, here is the shortened version, first APPT and then
APDIR.
Mark Adler
madler@tybalt.caltech.edu
%%HP: T(3)A(R)F(.);
@ Store as 'APPT'
@ 'APPT' BYTES should give CRC #5470h, and length 83.5.
\<<
APDIR
RCLF 'flags' STO MYFLGS STOF
CNTL
flags STOF HOME 2 MENU
\>>
%%HP: T(3)A(R)F(.);
@ Store as 'APDIR'
@ 'APDIR' BYTES should give CRC #B8C7h, and length 8173.5.
@ Note that if APPT is run, APDIR changes.
DIR
CNTL
@ Main function---called by APPT (not in APDIR)
@ Setup and process keystrokes at top (calendar) level.
\<<
DEPTH \->LIST 'STACK' STO @ save stack
DATE 'DSTR' STO @ set date to current date
REFRESH @ put up calendar
DO @ process keys until ...
-1 WAIT DOKEY
UNTIL
IP 16 == @ menu key F.
END
DROP2 STACK OBJ\-> DROP @ restore stack
\>>
REFRESH
@ called by CNTL, DOKEY (5)
@ Put up calendar display and menu.
\<<
@ SETUP
{ "FIND" "GOTO" "ADD" "UPLD" "APPTS" "Stop" } MENU DSTR SETUP2
MNTH LCD\->
@ HLIT
Dy ADR + 7 / FP 7 * 3 * 6 * 1 - 'COL' STO
Dy ADR + 7 / IP 1 + 8 * 1 - 'ROW' STO
DUP COL R\->B ROW R\->B 2 \->LIST COL 12 + R\->B ROW 8 + R\->B
2 \->LIST SUB NEG COL R\->B ROW R\->B 2 \->LIST SWAP REPL
DUP \->LCD
\>>
DOKEY
@ called by CNTL
@ Execute the keystroke on the stack for the calendar menu, update DSTR.
\<<
{ 11.1 { DROP SRCMAIN REFRESH 11.1 }
12.1 { DROP GOTO REFRESH 12.1 }
13.1 { CLEAR DSTR TIME 100 * IP 100 / "" 0 4 \->LIST
BEG 1 CF REFRESH 13.1 }
14.1 { DROP OVERALL REFRESH 14.1 }
15.1 { APPTS REFRESH 15.1 }
36.1 DYPL 34.1 DYMIN 35.1 NWEEK 25.1 PWEEK
95.1 MOPL 85.1 MOMIN 95.2 YRPLS 85.2 YRMIN
91.3 OFF
}
DUP2 SWAP POS
IF DUP THEN
1 + GET EVAL
ELSE
DROP2
END
Yr OBJ\-> 10000 / Dy + 100 / Mo + 'DSTR' STO
\>>
SRCMAIN
@ called by DOKEY
@ FIND key: find an appointment and go to that date.
\<<
@ GTSTR
DROP2 { } MENU "Type search string\010Then press ENTER." SRCSTR
\Ga 2 \->LIST INPUT 'SRCSTR' STO
CLLCD "Searching" 2 DISP
@ GTALN
DSTR FINDALARM 'NXTALRM' STO
@ SRCALRM
0 'ENDALRM' STO 0 'FNDALRM' STO
DO
NXTALRM
IFERR RCLALARM THEN
1 'ENDALRM' STO
ELSE
@ CHKALRM
1 GETI TIME TSTR 1 12 SUB 4 DISP DROP 3 GETI SWAP DROP
DUP TYPE 2 ==
IF THEN
SRCSTR POS
ELSE
DROP 0
END
IF THEN
1 'FNDALRM' STO
ELSE
DROP
END
END
NXTALRM 1 + 'NXTALRM' STO
UNTIL
ENDALRM FNDALRM OR
END
@ ENDPROC
IF ENDALRM THEN
CLEAR CLLCD "No appointment found\010\010Press a top row key." 3 DISP
-1 WAIT DROP
ELSE
1 GET 'DSTR' STO
END
\>>
GOTO
@ called by DOKEY
@ GOTO key: goto the entered date.
\<<
DROP2 { } MENU "Type date (MM.DDYYYY):\010Then press ENTER."
DSTR \->STR -1 2 \->LIST INPUT OBJ\-> 'DSTR' STO
\>>
YRMIN
@ called by DOKEY
@ left - key: go back one year.
\<<
ROT DROP2 DSTR .000001 - RDOSCR
\>>
YRPLS
@ called by DOKEY
@ left + key: go forward one year.
\<<
ROT DROP2 DSTR .000001 + RDOSCR
\>>
MOMIN
@ called by DOKEY
@ - key: go back one month.
\<<
ROT DROP2 DSTR DUP IP 1 - SWAP 100 * FP 100 / .01 + + DUP
IF 1 < THEN
.000001 - 12 +
END
RDOSCR
\>>
MOPL
@ called by DOKEY
@ + key: go forward one month.
\<<
ROT DROP2 DSTR DUP IP 1 + SWAP 100 * FP 100 / .01 + + DUP
IF 13 > THEN FP
1.000001 +
END
RDOSCR
\>>
PWEEK
@ called by DOKEY
@ down key: go forward one week (but stay in month).
\<<
IF Dy 7 > THEN
SWAP HLIT2 Dy 7 - 'Dy' STO RC HLIT2 DUP \->LCD SWAP
ELSE
400 .2 BEEP
END
\>>
NWEEK
@ called by DOKEY
@ up key: go back one week (but stay in month).
\<<
IF Dy DSTR LMNTH 6 - < THEN
SWAP HLIT2 7 Dy + 'Dy' STO RC HLIT2 DUP \->LCD SWAP
ELSE
400 .2 BEEP
END
\>>
DYMIN
@ called by DOKEY
@ left key: go back one day (but stay in month).
\<<
IF Dy 1 > THEN
SWAP HLIT2 Dy 1 - 'Dy' STO RC HLIT2 DUP \->LCD SWAP
ELSE
400 .2 BEEP
END
\>>
DYPL
@ called by DOKEY
@ right key: go forward one day (but stay in month).
\<<
IF Dy DSTR LMNTH < THEN
SWAP HLIT2 1 Dy + 'Dy' STO RC HLIT2 DUP \->LCD SWAP
ELSE
400 .2 BEEP
END
\>>
OVERALL
@ called by DOKEY
@ UPLD key: dump a range of appointments to I/O device.
\<<
@ GDATES
"Enter Start Date\010(MM.DDYYYY)\010Then press ENTER" DSTR
\->STR -1 2 \->LIST INPUT OBJ\-> 'SDAT' STO
"Enter End Date\010(MM.DDYYYY)\010Then press ENTER" DSTR
\->STR -1 2 \->LIST INPUT OBJ\-> 'ENDAT' STO
"\010"
@ RAPPTS
SDAT FINDALARM DUP 'NXTALRM' STO
SDAT DFLIP 'SDAT' STO
ENDAT DFLIP 'ENDAT' STO
CLLCD
"Finding appointments" 1 DISP
WHILE
@ GDALRM
IFERR RCLALARM THEN
DROP 0
ELSE
DUP 1 GET DFLIP DUP SDAT \>= SWAP ENDAT \<= AND
IF THEN
1
ELSE
DROP 0
END
END
REPEAT
@ MKSTR
DUP 1 GETI 3 ROLLD GET TSTR 1 19 SUB " " + SWAP 3 GET DUP
IF TYPE 2 == THEN
+
ELSE
DROP "Control Alarm" +
END
+ "\010" + NXTALRM 1 + DUP 'NXTALRM' STO
END
'APPTSTR' STO
@ TOPC
CLLCD
"The data is ready.\010Press the appropriate\010key when you are\010ready."
1 DISP { "SEND" "" "" "" "" "ABRT" } MENU
DO
-1 WAIT
IF DUP 11.1 == THEN
DROP 'APPTSTR'
IFERR CLLCD SEND THEN
DROP CLLCD
"I/O Problem\010Check configuration\010and retry." 1 DISP
ELSE
CLLCD "Successful transfer" 1 DISP
END
3 WAIT 16.1
END
UNTIL
16.1 ==
END
CLEAR
\>>
DFLIP
@ called by OVERALL (3)
@ Change MM.DDYYYY to YYYYMMDD for numerical comparisons.
\<<
100 * DUP IP SWAP FP 100000000 * +
\>>
APPTS
@ called by DOKEY
@ APPTS key: show appointments for selected day, allow operations.
\<<
3 DROPN
IF
@ FAPPTS
DSTR FINDALARM DUP
IF THEN
@ ALRM\->
'NXTALRM' STO
DO
NXTALRM
IFERR RCLALARM THEN
DROP DSTR 1 + 1 \->LIST
ELSE
OBJ\-> DROP NXTALRM 5 \->LIST NXTALRM 1 + 'NXTALRM' STO
END
UNTIL
DUP 1 GET DSTR \=/
END
DROP
ELSE
DROP
END
DEPTH
THEN
DEPTH ROLL
@ APS\->MS
DEPTH 1 SWAP
START
@ OAL\->MSG
DUP 5 GET SWAP DUP 3 GET SWAP 2 GET DUP IP DUP
IF 10 < THEN
"0" SWAP +
END
":" + SWAP FP 100 * IP DUP
IF NOT THEN
DROP "00"
END
+ " " + SWAP + SWAP 2 \->LIST
DEPTH ROLL
NEXT
@ PSTMSG
PG
DO
-1 WAIT
@ DOK5 and DOKX
{ 91.3 OFF
25.1 { DROP DEPTH ROLL PG 25.1 }
35.1 { DROP DEPTH ROLLD PG 35.1 }
11.1 \<<
DROP 2 GETI SWAP DROP DUP RCLALARM SWAP DELALARM DUP BEG
IF 1 FC? THEN
STOALARM
ELSE
DROP
END
1 CF 16.1
\>>
12.1 { DROP 2 GETI SWAP DROP
# 18CEAh SYSEVAL # E402h SYSEVAL # 3244h SYSEVAL
# E80Dh SYSEVAL # 172Bh SYSEVAL DROP2 12.1 }
13.1 { DROP 2 GET DELALARM 16.1 }
14.1 { DROP DSTR TIME 100 * IP 100 / "" 0 4 \->LIST BEG 1 CF 16.1 }
15.1 \<<
DROP
@ PRVW
CLLCD DUP 1 GET DUP SIZE 7 SWAP SUB DUP SIZE 1 SWAP
FOR x
DUP 1 22 SUB x 22 / 1 + DISP
IF DUP SIZE 22 > THEN
DUP SIZE 23 SWAP SUB
END
22 STEP
DROP { "" "" "" "" "" "RTRN" } MENU -1 WAIT DROP
PG 15.1
\>>
}
IF DEPTH 7 > THEN
{ 25.2 { DROP 1 5 START DEPTH ROLL NEXT PG 25.2 }
35.2 { DROP 1 5 START DEPTH ROLLD NEXT PG 35.2 }
} +
END
DUP2 SWAP POS
IF DUP THEN
1 + GET EVAL
ELSE
DROP2
END
UNTIL
16.1 ==
END
CLEAR
ELSE
@ NOAPPTS
DO
@ NOHEAD
DSTR TIME TSTR 1 12 SUB " " SWAP + " NO APPTS YET FOR"
CLLCD 1 DISP 3 DISP
@ SETNO
{ "" "" "" "ADD" "" "RTN" } MENU
-1 WAIT
@ DOK3
CASE
DUP 91.3 == THEN OFF END
DUP 14.1 == THEN DROP DSTR 8 "" 0 4 \->LIST BEG 16.1 END
END
UNTIL
16.1 ==
END
END
\>>
PG
@ called by APPTS (5)
@ Put the (first 5) appointments on the stack in the display,
@ and show the menu.
\<<
@ MHEAD
DSTR TIME TSTR 1 12 SUB " " SWAP + "Appts and meetings for"
CLLCD 1 DISP 2 DISP
@ SETU3
{ "EDIT" "ACK" "DEL" "ADD" "VIEW" "RTN" } MENU
DEPTH 5 MIN
@ POSTX
\-> d \<<
1 d FOR i
DUP 1 GET i 2 + DISP DEPTH ROLL
1 STEP
1 d START
DEPTH ROLLD
NEXT
@ TSK1
LCD\-> DUP { # 0h # Fh } { # 87h # 17h } SUB NEG
{ # 0h # Fh } SWAP REPL \->LCD
\>>
\>>
BEG
@ called by DOKEY, APPTS
@ ADD or EDIT key: edit a new or existing appointment.
\<<
DO
@ RFSH
CLLCD 1
GETI "Date " SWAP + 1 DISP
GETI "Hour " SWAP + 2 DISP
GETI "Msg. " SWAP + 3 DISP
DROP "Press a softkey first" 5 DISP
@ SETU4
{ "DATE" "TIME" "MSG" "RPT" "SET" "ABRT" } MENU
-1 WAIT
@ DOK4
{ 91.3 OFF
11.1 { DROP DATTE 11.1 }
12.1 { DROP HOUR 12.1 }
13.1 { DROP MSSG 13.1 }
14.1 { REPEET 14.1 }
15.1 { DROP STOALARM DROP 1 SF 15.1 }
16.1 { 1 CF SWAP DROP }
}
DUP2 SWAP POS
IF DUP THEN
1 + GET EVAL
ELSE
DROP2 1000 .2 BEEP
END
UNTIL
DUP 15.1 == SWAP 16.1 == OR
END
\>>
MSSG
@ called by BEG
@ MSG key: change text message for appointment.
\<<
{ } MENU 3 GETI SWAP DROP \Ga 2 \->LIST
"Message:\010Then press ENTER." SWAP INPUT 3 SWAP PUT
\>>
HOUR
@ called by BEG
@ TIME key: change time for appointment.
\<<
{ } MENU 2 GETI SWAP DROP \->STR -1 2 \->LIST
"Hour (HH.MM):\010Then press ENTER." SWAP INPUT OBJ\-> 2 SWAP PUT
\>>
DATTE
@ called by BEG
@ DATE key: change date for appointment.
\<<
DO
{ } MENU 1 GETI SWAP DROP \->STR -1 2 \->LIST
"Date (MM.DDYYYY):\010Then press ENTER." SWAP INPUT OBJ\->
UNTIL
DUP DUP DUP IP DUP 0 > SWAP 13 < AND SWAP FP 100 * IP 32 < AND
SWAP 100 * FP 10000 * 1990 \>= AND DUP
IF NOT THEN
SWAP DROP CLLCD
"Bad date. The rules:\010\0100 < MM < 13\0100 < DD < 32\0101990 \<=
YYYY\010\010Press a top row key"
1 DISP -1 WAIT DROP
END
END
1 SWAP PUT
\>>
REPEET
@ called by BEG
@ RPT key: change repeat specification for appointment.
@ (Note: this function expects no number to be entered if NONE will
@ be pressed on the next menu.)
\<<
{ } MENU
"Repeat #. Then ENTER." "" INPUT OBJ\->
{ "Week" "Day" "Hour" "Min" "Sec" "None" } MENU
"Now press repeat unit" 3 DISP -1 WAIT
{ 11.1 4954521600
12.1 707788800
13.1 29491200
14.1 491520
15.1 8192
}
DUP ROT POS
IF DUP THEN
1 + GET *
ELSE
DROP2 0 @ this assumes no input
END
SWAP DROP 4 SWAP PUT
\>>
RDOSCR
@ called by YRMIN, YRPLS, MOMIN, MOPL
@ Change current date and display the new month.
\<<
SETUP2 MNTH LCD\-> RC HLIT2 DUP \->LCD SWAP
\>>
HLIT2
@ called by RDOSCR, PWEEK (2), NWEEK (2), DYMIN (2), DYPL (2)
@ Toggle the highlighting of the current date in the calendar.
\<<
COL R\->B ROW R\->B 2 \->LIST DUP2
COL 12 + R\->B ROW 8 + R\->B 2 \->LIST
SUB NEG REPL
\>>
RC
@ called by RDOSCR, PWEEK, NWEEK, DYMIN, DYPL
@ Update ROW and COL for the current date in the calendar.
\<<
Dy ADR + 7 / FP 126 * 1 - 'COL' STO
Dy ADR + 7 / IP 1 + 8 * 1 - 'ROW' STO
\>>
SETUP2
@ called by REFRESH, RDOSCR
@ Set DSTR, update Mo, Dy, Yr, Day1, and ADR.
\<<
DUP 'DSTR' STO DUP
@ MMYY
DUP IP 'Mo' STO
FP 100 * DUP IP 'Dy' STO
FP 10000 * \->STR 'Yr' STO
DUP
@ DFRST
DUP IP SWAP FP 100 * FP 1 + 100 / + TIME TSTR 1 3 SUB 'Day1' STO
@ CADR
{ "SUN" "MON" "TUE" "WED" "THU" "FRI" "SAT" } Day1 POS 2 - 'ADR' STO
\>>
MNTH
@ called by REFRESH, RDOSCR
@ Put the current month in the display.
\<<
@ HEADR
{ "January " "February " "March " "April " "May " "June "
"July " "August " "September " "October " "November " "December " }
Mo GET Yr + " " SWAP + 1 DISP
DSTR LMNTH Day1
@ MN
\-> n d \<<
" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30 31"
{ "SAT" "FRI" "THU" "WED" "TUE" "MON" "SUN" } d POS 3 * 2 -
n 3 * 17 + SUB
2 7 FOR i
DUP i 2 - 21 * 1 + DUP 19 + SUB i DISP
NEXT
DROP
\>>
\>>
LMNTH
@ called by NWEEK, DYPL, MNTH
@ Compute the number of days in the month.
\<<
DUP IP SWAP 100 * FP 100 / .01 + + DUP 1 + DUP
IF 13 > THEN
FP 1.000001 +
END
DDAYS
\>>
SRCSTR "" @ used in CHKALRM, GETSTR
MYFLGS { # 90400000FF0h # 0h } @ used by APPT (not in APDIR)
END @ APDIR
Date: 30 Mar 90 04:48:06 GMT
From: rhelps@yoda.UUCP
Subject: Shorter APPT, APDIR (this is a LONG message)
Message-Id: <103rhelps@yoda.byu.edu>
Sender: handhelds-request@csl.sri.com
To: handhelds@csl.sri.com
>Anyway, here is the shortened version, first APPT and then
>APDIR.
Thank you for this improved version. Unfortunately two lines near the
end of the file got garbled when I downloaded them as they are more than 80
characters long. They are the line lines that start
"Bad Date. ...... and
" 1 2 3 4 ......
Could you please re-send these lines with the lines split into shorter text
strings. I could then patch my ASCII file.
Thanks again.
- Richard Helps -
@BYU
Date: 30 Mar 90 20:25:38 GMT
From: madler@eeyore.UUCP (Mark Adler)
Organization: California Institute of Technology, Pasadena
Subject: Re: Shorter APPT, APDIR (this is a LONG message)
Message-Id: <1990Mar30.202538.16968@spectre.ccsf.caltech.edu>
References: <103rhelps@yoda.byu.edu>
Sender: handhelds-request@csl.sri.com
To: handhelds@csl.sri.com
Here are the two strings from the shortened version of APDIR that are on
lines that are longer than 80 characters. Each string is broken into two
strings that should be put back together in the ASCII file before being
downloaded into the HP. This is to get the checksum and length to be correct.
In function DATTE:
"Bad date. The rules:\010\0100 < MM < 13\0100 < DD < 32\010"
"1990 \<= YYYY\010\010Press a top row key"
In funciton MNTH:
" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"
" 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31"
Mark Adler
madler@tybalt.caltech.edu