Number: 1103 Date: 12-May-84 15':11':22 Submitter: Sannella.PA Source: Jeffrey Shulman <SHULMAN@RUTGERS.ARPA> Subject: Document internal represation of clkcks and number boxes Lisp Version: Description: ' Return-Path': SHULMAN@RUTGERS.ARPA' Received': from RUTGERS.ARPA by Xerox.ARPA ; 28 APR 84 15':14':56 PST' Date': 28 Apr 84 18':13':27 EST' From': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>' Subject': Clocks and boxes' To': Lispsupport.pa' cc': SHULMAN@RUTGERS.ARPA' ' ' Can someone please explain how these things work?' ' This is what I think I know (correct me if I am wrong)':' ' a) (CREATECELL \FIXP) will create a number box.' b) (\CLOCK0 numberbox) puts the millisecond clock in numberbox.' c) (\BOXIDIFFERENCE box1 box2) does box1 = box1 - box2' ' Now, how would I do tests on these boxes':' (ILEQ somebox somenumber) ??' (FEQP somebox somenumber) ??' (FEQP somebox somebox) ??' etc.' ' ' I can break a number into two bytes via':' (LRSH somesmallpnumber 8) for the high order byte and' (LOGAND somesmallpnumber 255) for the low order byte' can I do this to a "box"?' ' Jeff' ' P.S. This is going in the recorder version of \KEYHANDLER1 so it must be' fast. Doing' ' (SETQ START.TIME (CLOCK 0))' (SETQ DELTA (IDIFFERENCE (CLOCK 0) START.TIME))' ' seems to take a significant amount of time in this respect. I also need to' put these numbers into a byte array (I use \PUTBASEBYTE to do this) so I' must also break them up as described above (in EXPORTS.ALL there are four' macros called FOLD, UNFOLD, FOLDHI and FOLDLO that sound like they might do' this. Do they? How do they work?)' ' -------' ' Date': 4 May 84 15':26 PDT' From': JonL.pa' Subject': Re': Shulman needs info on "Clocks and boxes"' In-reply-to': LispSupport.pa''s message of 30 Apr 84 13':26':48 PDT (Monday)' To': Shulman@Rutgers' cc': LispSupport.pa' ' I''ll make a stab at answering your questions, leaving it to John S. to decide how much of the reply to integrate into the implementors guide.' ' ' ----------------------------------------------------------------' ' Date': 28 Apr 84 18':13':27 EST' From': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>' Subject': Clocks and boxes' To': Lispsupport.pa' cc': SHULMAN@RUTGERS.ARPA' ' ' Can someone please explain how these things work?' ' This is what I think I know (correct me if I am wrong)':' ' a) (CREATECELL \FIXP) will create a number box.' b) (\CLOCK0 numberbox) puts the millisecond clock in numberbox.' c) (\BOXIDIFFERENCE box1 box2) does box1 = box1 - box2' ' Now, how would I do tests on these boxes':' (ILEQ somebox somenumber) ??' (FEQP somebox somenumber) ??' (FEQP somebox somebox) ??' etc.' ' ' I can break a number into two bytes via':' (LRSH somesmallpnumber 8) for the high order byte and' (LOGAND somesmallpnumber 255) for the low order byte' can I do this to a "box"?' ' Jeff' ' P.S. This is going in the recorder version of \KEYHANDLER1 so it must be' fast. Doing' ' (SETQ START.TIME (CLOCK 0))' (SETQ DELTA (IDIFFERENCE (CLOCK 0) START.TIME))' ' seems to take a significant amount of time in this respect. I also need to' put these numbers into a byte array (I use \PUTBASEBYTE to do this) so I' must also break them up as described above (in EXPORTS.ALL there are four' macros called FOLD, UNFOLD, FOLDHI and FOLDLO that sound like they might do' this. Do they? How do they work?)' ' ----------------------------------------------------------------' ' ' ' ' Question a':' ----------' ' (CREATECELL <n>) will create a cell in the datatype space with NTYPX number <n>; as a convenience for lots of system code, some favorite spaces have their type numbers set in the toplevel cell of certain variables; namely' \FIXP for 32-bit cell for non-smallp fixps, \FLOATP for 32bit floatps' \LISTP for a 32-bit cell -- 24 bits of address and 8 of cdr code' \STRINGP and \ARRAYP for the respective 2-cell headers' \SMALLP and \LITATOM exist also, but not that they aren''t implemented' as a cell or sequence of cells as the others are.' In general, it would be preferable to use NCREATE rather than CREATECELL; in this case, you would say (NCREATE ''FIXP), which currently macroexpands into (CREATECELL \FIXP).' ' ' Question b':' ------------' ' Indeed, (\CLOCK0 <box>) smashes ateh current millisecond clock into the fixp cell <box>' ' ' Question c':' ------------' ' (\BOXIDIFFERENCE <box> <number>) performs (IDIFFERENCE <box> <number>), with no overflow checking!, but insists that <box> be of type \FIXP; then the result is smashed back into <box>. \BOXIDIFFERENCE is in microcode on the Dolphin and Dorado, and also on the 8K control-store DLion. (same for \BOXIPLUS). ' ' If the result of \BOXIDIFFERENCE and/or \BOXIPLUS is out of the \SMALLP range, then it appears to most of the rest of the world to be a normal fixp; if it is in the smallp range, then some of the arithmetic functions may have trouble with it (ZEROP comes to mind, but there are others). But the happy news is that the IGREATERP/ILESSP opcodes work right, regardless of whether their fixp arguments are "normalized". The floating point microcode will not accept any <box> that \BOXIDIFFERENCE etc will accept, but will punt out to macrocode, which manages to do the comparison as if the fixp were "floated". ' ' One particularly interesting use of \fixp boxes is as "timers"; in general, you should be able to get by with SETUPTIMER and TIMEREXPRED? (which don''t require consing if you have cached a "timer" -- a \fixp box -- for use by the call to SETUPTIMER), or with \CLOCKGREATERP which tests for the current clock being at least 2ndArgument milliseconds greater than 1stArgument (which is presumable some former reading of the milliseconds clock). However, if you do want to compare clocks, IGREATERP in the obvious usages isn''t right; it doesn''t account for "wrap around" at the high end of the range. Since IGREATERP will work with "unnormalized" fixp boxes, then a special-case of the currently-undocumented funciton called IMODLESSP can be coded as' (IGREATERP (\BOXIDIFFERENCE <newTime> <oldTime>) 0)' Below, I''ve reproduced the documentation on IMODLESSP, culled from {Phylum}<LispCore>Doc>Addarith.tty':' ' ' (IMODLESSP <x> <y> <modulus> <equal?>) This function is inspired by' the need to use "wrap-around" counters. It is not possible to define ' a "perfect" ordering function on the integers [0, 1, ... <modulus-1>], ' but this function takes the view that it is better to limit the ' "diameter" of the applicable domain, than to "bump" into the ' singularity at the endpoints of the interval. So MODLESSP will return ' "true" iff <y>-<x> mod <modulus> is less than 1/2*<modulus>. The ' optional argument <equal?>, if non-null, says to do a "less than or ' equal" test rather than a "lessp" test. Generally the <modulus> should ' be a power of two (for faster running speed), but this isn''t necessary.' Two exceptional arguments are also admitted -- if <modulus> is ' ''WORD, then the appropriate value is taken for word-sized arithmetic;' if it is ''CELL, then the appropriate value is taken for double-word,' or cell, sized arithmetic. In Interlisp-D, WORD sized is 16-bit, and' CELL-sized is 32-bit.' ' (IMODPLUS <x> <y> <modulus>)' (IMODDIFFERENCE <x> <y> <modulus>)' Essentially (MOD (<operation> <x> <y>) <modulus>),' except no overflow is permitted to occur during the intermediate ' arithmetic <operation>. A macro produces some slightly-optimized code ' for the case where <modulus> is CELL. A current limitation is that ' an arithmetic overflow occurring when <modulus> is not a power of two ' (or CELL or WORD) causes an error.' ' ' ' Question in P.S.':' -----------------' ' Clearly, you don''t want to cause consing in the keyhandler! thus don''t do (CLOCK 0), but rather set up some global fixp box, say \START.TIME, at initialization (or even file loading) time, and do (\CLOCK0 \START.TIME); the if you really need to compute up Delta, have another \fixp box, say \DELTA, and then do ' (\BOXIDIFFERENCE (\CLOCK0 \DELTA) \START.TIME)' and as with \START.TIME, be aware that this box is a global resource.' ' Note that one thing is missing so far': if you have a random fixp box, say \BOX, and you want to use it to hold the result of the difference between two random numbers, say X and Y, you have to first get X into the box, and then call (\BOXIDIFFERENCE \BOX Y). There is another undocumented function, used by the record package called \PUTFIXP, that will simply take its second argument (coerced to a fixp the same way that IDIFFERENCE and \BOXIDIFFERENCE would) and stuff it into the cell pointed to by the first argument. Note Very Well': there is no type checking on the first argument, so you can smash any random cell in the system this way. ' Workaround: Test Case: Edit-By: Edit-Date: 12-May-84 15':09':51 Attn: jonl Assigned To: In/By: Disposition: System: Language Support Subsystem: Storage Formats/Mgt Machine: Disk: Microcode Version: Memory Size: File Server: Server Software Version: Difficulty: Moderate Frequency: Everytime Impact: Minor Priority: Unlikely Status: Open Problem Type: Documentation Source Files: