perm filename HOST.FAI[HST,NET]2 blob sn#719192 filedate 1983-07-05 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00007 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	 A B C X Y P PDLEN HSTSID HSTFN1 HSTVRS HSTDIR HSTDEV HSTWHO HSTDAT HSTTIM NAMPTR SITPTR NETPTR NTNPTR HDRLEN NETNUM NTLNAM NTRTAB NETLEN ADDADR ADLSIT ADRCDR ADLXXX ADRSVC SVLCNT SVRCDR SVLFLG SVRNAM SVCARG ADDLEN STLNAM STRADR STLSYS STRMCH STLFLG STFSRV STFGWY SITLEN NMLSIT NMRNAM NAMLEN NNLNET NNRNAM NTNLEN NT$NUM NE%UNT NE%STR NN%IP NW%ARP NW%SU HSTFIL HSTPPN
C00015 00003	 START FLSINP HSTCOM CMDSCN PROMPT DOCMD HSTLUP GOTHST GETNUM NOTIPH HSTLUZ ALPHST CNTCHR
C00020 00004	 SEARCH SRCNXW SRCWIN OFFNAM NXTHST PRINT NAMLP NAMDUN MCHTYP ENDNIC
C00024 00005	 MAPHST
C00025 00006	 HSTNUM HSTNU0 HSTNUS HSTNU1 HSTNU2 HSTNU3 HSTNUD
C00027 00007	Subroutines  SWINIR SWINR1 SWINR2 SWINIP CPOPJ1 CPOPJ SWINP1 PRHNUM PRHNIP PRDECP PRDEC PROCT PRLOOP PDL MONCMP HSTADR HSTTOP HSTEXT
C00034 ENDMK
C⊗;
;⊗ A B C X Y P PDLEN HSTSID HSTFN1 HSTVRS HSTDIR HSTDEV HSTWHO HSTDAT HSTTIM NAMPTR SITPTR NETPTR NTNPTR HDRLEN NETNUM NTLNAM NTRTAB NETLEN ADDADR ADLSIT ADRCDR ADLXXX ADRSVC SVLCNT SVRCDR SVLFLG SVRNAM SVCARG ADDLEN STLNAM STRADR STLSYS STRMCH STLFLG STFSRV STFGWY SITLEN NMLSIT NMRNAM NAMLEN NNLNET NNRNAM NTNLEN NT$NUM NE%UNT NE%STR NN%IP NW%ARP NW%SU HSTFIL HSTPPN

	TITLE HOST

;This program is adapted from the old HOST.MID, which read the HOSTS1.BIN
;file, and from various code in NETWRK.FAI.  NETWRK isn't inserted directly,
;because we want to do slightly different things in searching for host names.

A←12				;Our AC's don't interfere with NETWRK's
B←13
C←14
X←15
Y←16
P←17

PDLEN←←20

;The format of the host table binary file is:

HSTSID←←0	; wd 0	SIXBIT /HOSTS3/
HSTFN1←←1	; wd 1	SIXBIT FN1 of source file (eg HOSTS)
HSTVRS←←2	; wd 2	SIXBIT FN2 of source file (TNX: version #)
HSTDIR←←3	; wd 3  SIXBIT directory name of source file (eg SYSENG)
HSTDEV←←4	; wd 4  SIXBIT device name of source file (eg AI)
HSTWHO←←5	; wd 5	SIXBIT login name of person who compiled this
HSTDAT←←6	; wd 6  SIXBIT Date of compilation as YYMMDD
HSTTIM←←7	; wd 7	SIXBIT Time of compilation as HHMMSS
NAMPTR←←10	; wd 10 Fileaddress of NAME table.
SITPTR←←11	; wd 11	Fileaddress of SITE table.
NETPTR←←12	; wd 12 Fileaddress of NETWORK table.
NTNPTR←←13	; wd 13 Fileaddress of NETNAME table.
		;....expandable....
  HDRLEN←←14	; length of header

; NETWORK table
;	wd 0	Number of entries in table.
;	wd 1	Number of words per entry. (2)
; This table contains one entry for each known network.
; It is sorted by network number.
; Each entry contains:

NETNUM←←0	; wd 0 network number (full netaddr)
NTLNAM←←1	; wd 1 LH - fileaddr of ASCIZ name of network
NTRTAB←←1	; wd 1 RH - fileaddr of network's ADDRESS table
 NETLEN←←2

; ADDRESS table(s)
;	wd 0	Number of entries in table.
;	wd 1	Number of words per entry. (3)
; There is one of these tables for each network.  It contains entries
; for each site attached to that network, sorted by network address.
; These tables are used to convert a numeric address into a host name.
; Also, the list of network addresses and services for a site is stored
; within these tables.
; Each entry contains:

ADDADR←←0	; wd 0	Network address of this entry, in HOSTS3 fmt.
ADLSIT←←1	; wd 1 LH - fileaddr of SITE table entry
ADRCDR←←1	; wd 1 RH - fileaddr of next ADDRESS entry for this site
		;	 0 = end of list
ADLXXX←←2	; wd 2 LH - unused
ADRSVC←←2	; wd 2 RH - fileaddr of services list for this address
		;	0 = none, else points to SERVICE node of format:
	SVLCNT←←0	;		<# wds>,,<fileaddr of next, or 0>
	SVRCDR←←0
	SVLFLG←←1	;		<flags>,,<fileaddr of svc name>
	SVRNAM←←1
	SVCARG←←2	;		<param1> ? <param2> ? ...
 ADDLEN←←3

; SITE table
;	wd 0	Number of entries in table.
;	wd 1	Number of words per entry. (3)
; This table contains entries for each network site,
; not sorted by anything in particular. A site can have more
; than one network address, usually on different networks.
; This is the main, central table.
; Each entry looks like:

STLNAM←←0	; wd 0 LH - fileaddr of official host name
STRADR←←0	; wd 0 RH - fileaddr of first ADDRESS table entry for this
		;		site.  Successive entries are threaded
		;		together through ADRCDR.
STLSYS←←1	; wd 1 LH - fileaddr of system name (ITS, TIP, TENEX, etc.)
		;		May be 0 → not known.
STRMCH←←1	; wd 1 RH - fileaddr of machine name (PDP10, etc.)
		;		May be 0 → not known.
STLFLG←←2	; wd 2 LH - flags:
STFSRV←←400000	;	4.9 1 → server site (has FTP or TELNET)
STFGWY←←200000	;	4.8 1 → Internet Gateway site (HOSTS3 only)
 SITLEN←←3

; NAMES table:
;	wd 0	Number of entries
;	wd 1	Number of words per entry. (1)
; This table is used to convert host names into network addresses.  It
; contains entries sorted alphabetically by host name.

NMLSIT←←0	; wd 0 LH - fileaddr of SITE table entry for this host.
NMRNAM←←0	; wd 0 RH - fileaddr of host name
		; This name is official if NMRNAM = STLNAM of NMLSIT.
 NAMLEN←←1

; NETNAME table:
;	wd 0	Number of entries
;	wd 1	Number of words per entry. (1)
; This table is used to convert network names into network numbers.  It
; contains entries sorted alphabetically by network name, exactly as
; for the NAMES table.  Although the symbols below are different (in order
; to make semantic distinctions), programs can depend on the fact
; that the NETNAME table format is identical to that of the NAMES table.

NNLNET←←0	; wd 0 LH - fileaddr of NETWORK table entry for this host.
NNRNAM←←0	; wd 0 RH - fileaddr of network name
 NTNLEN←←1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;		HOSTS3 Network Address Format           ;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

comment |
HOSTS3 network address format:

   4.9-4.6 - 4 bits of format type, which specify interpretation of
		the remaining 32 bits.
IN	0000 - Internet address (handles ARPA, RCC, LCS)
		4.5-1.1 - 32 bits of IN address.
UN	0001 - Unternet address.  Same format, but not part of Internet.
		4.5-3.7 - HOSTS3-defined network number (1st 8-bit byte)
		3.6-1.1 - address value in next 24 bits.
			This handles CHAOS and any local nets.  The network
			numbers are unique within the HOSTS3 table but
			don't necessarily mean anything globally, as do
			Internet network numbers.
	0011 - String address.
		4.5-3.7 - HOSTS3-defined network number (1st 8-bit byte)
		3.6-3.1 - 0
		2.9-1.1 - address of ASCIZ string in file/process space

Note that the "network number" for all of these formats is located in
the same place.  However, for fast deciphering of the entire range of
possibilities, one could simply consider all of the high 12 bits as the
network number.  Beware of the Internet class A, B, and C formats, though;
the only truly general way to compare network numbers is to use their
masked 36-bit values, although simpler checks are OK for specific nets.
For this reason (among others) network numbers are represented by
full 36-bit values with the "local address" portion zero.

The 4-bit "String address" value is much more tentative than the IN or UN
values.  Bit 4.9, the sign bit, is being reserved as usual for the possible
advent of a truly spectacular incompatible format.
|

NT$NUM←←301400		;Byte pointer to network number (high 12 bits)
NE%UNT←←<040000,,0>	;Escape bit indicating "Unternet" type address
NE%STR←←<100000,,0>	;Escape bit indicating "string" type address
NN%IP←←<740000,,0>	;host number bits that are off for all IP addresses
NW%ARP←←<12⊗=24>	;HOSTS3 uses full word network # values
NW%SU←←<NE%UNT+44⊗=24>	;"Unternet" used for Stanford Ethernet


DEFINE GETNET(AC,ADDR)<
IFDIF <ADDR><><MOVE AC,ADDR>
	TLNN AC,(17⊗=32)	; Check for non-Internet type addrs
	 TLNN AC,(1⊗=31)	;  Internet address, see if class A net
	  TDZA AC,[77,,-1]	;   Unternet or class A, zap low 3 octets
	TLNN AC,(1⊗=30)		; Class B or C, see which.
	 TRZA AC,177777		;  Class B network, zap low 2 octets
	  TRZ AC,377		;   Class C net, only zap 1 low octet
>;GETNET

HSTFIL:	SIXBIT/HOSTS3/		;filename and extension of binary file
	SIXBIT/BIN/
HSTPPN:	SIXBIT/HSTNET/		;PPN of binary file
;⊗ START FLSINP HSTCOM CMDSCN PROMPT DOCMD HSTLUP GOTHST GETNUM NOTIPH HSTLUZ ALPHST CNTCHR

START:	CAI
	RESET
	SETZM MONCMP
	MOVE P,[IOWD PDLEN,PDL]
	PUSHJ P,MAPHST		;Map host table in core
	RESCAN A
	JUMPE A,PROMPT
	INCHRS X
	 JRST PROMPT
	CAIE X,"H"		;Check for HOST command
	 CAIN X,"h"
	  JRST HSTCOM
FLSINP:	INCHRS X
	 JRST PROMPT
	CAIE X,175
	 CAIN X,12
	  JRST PROMPT
	JRST FLSINP

HSTCOM:	OUTSTR [ASCIZ/
/]
CMDSCN:	INCHRS X
	 JRST GOTHST
	CAIE X,175
	 CAIN X,12
	  JRST GOTHST		;No command argument
	CAIE X," "
	 JRST CMDSCN
	SETOM MONCMP
	JRST DOCMD

PROMPT:	SKIPE MONCMP
	 EXIT 1,
	OUTSTR [ASCIZ/
Host name or number: /]
DOCMD:	SETZM HSTEXT
	MOVE Y,[POINT 7,HSTEXT]
HSTLUP:	INCHWL X
	ANDI X,177
	CAIN X,15
	 INCHWL X
	CAIE X,175
	 CAIN X,12
	  JRST GOTHST
	IDPB X,Y
	JRST HSTLUP

GOTHST:	SKIPN HSTEXT
	 JRST [	MOVEI A,[SIXBIT/SYS/
			 SIXBIT/HOSTAB/
			 SIXBIT/DMP/
			 0 ↔ 0 ↔ 0]
		SWAP A,]
	SETZ X,
	IDPB X,Y
;Here with input text string in HSTEXT.
	MOVE Y,[POINT 7,HSTEXT]	;Start at beginning of text
	ILDB X,Y		;Now see if we got a name or a number
	CAIL X,"0"
	 CAILE X,"9"
	  JRST ALPHST		;Alphabetic host specification
	PUSHJ P,SWINIP		;Get host number
	 JRST NOTIPH		;Not an IP host number
	JUMPN X,HSTLUZ
	MOVE 0,B		;Set up for HSTNUM
GETNUM:	PUSHJ P,HSTNUM		;Look up the number
	 JRST [ OUTSTR [ASCIZ/Unknown host
/]
		JRST PROMPT]
	HLRZ 6,STLNAM(7)	;Get official name
	ADD 6,HSTADR
	OUTSTR (6)
	PUSHJ P,PRINT
	JRST PROMPT

;Here with a non-IP host number in A (octal) and B (decimal).
NOTIPH:	JUMPE X,[OUTSTR [ASCIZ/Incomplete host number specification
/]
		JRST PROMPT]
	CAIN X,"/"		;BBN style number?
	 JRST [	CAILE B,377
		 SETO B,
		PUSH P,B
		ILDB X,Y	;Check numericness
		CAIL X,"0"
		 CAILE X,"9"
		  JRST HSTLUZ
		PUSHJ P,SWINIR
		SKIPN B
		 SETZM (P)
		POP P,A		;A←host, B←IMP
		JUMPN X,HSTLUZ
		LSH A,=16
		ADDI A,(B)
		TLO A,(NW%ARP)	;Set network
		MOVE 0,A
		JRST GETNUM]
	CAIN X,"#"		;XEROX style number
	 JRST [	SKIPLE A
		CAILE A,377
		 JRST HSTLUZ
		PUSH P,A
		ILDB X,Y	;Check numericness
		CAIL X,"0"
		 CAILE X,"9"
		  JRST HSTLUZ
		PUSHJ P,SWINIR
		POP P,B		;B←subnet, A←host
		JUMPN X,HSTLUZ
		SKIPLE A
		CAILE A,377
		 JRST HSTLUZ
		LSH B,=8
		ADDI B,(A)
		TLO B,(NW%SU)	;Set network
		MOVE 0,B
		JRST GETNUM]
HSTLUZ:	OUTSTR [ASCIZ/Bad host number format
/]
	JRST PROMPT

;Here with an alphabetic host name.
ALPHST:	MOVEI 0,HSTEXT

;  Set up various AC's for hairy search below.  0 has a pointer to the input
; host, 1 has the host table pointer, 2 has the character count.

	MOVE 1,HSTADR			; base host address
	MOVE 2,NAMPTR(1)
	ADD 2,HSTADR			; address of NAMES table
	HRLO 1,(2)			; # of entries,,-1
	EQVI 1,1(2)			; -<1+# of entries>,,table-1
	ADJSP 1,1			; now have AOJBN pointer to table
	MOVE 3,
	HRLI 3,440700			; make byte pointer
	SETZ 2,				; character count

; Compute character count in AC 2

CNTCHR:	ILDB 4,3
	JUMPE 4,[	SETZB 3,4	; init pointers
			JRST SEARCH]
	CAIL 4,"a"			; lowercase?
	 SUBI 4,"a"-"A"
	DPB 4,3
	AOJA 2,CNTCHR
;⊗ SEARCH SRCNXW SRCWIN OFFNAM NXTHST PRINT NAMLP NAMDUN MCHTYP ENDNIC

;Host name search

SEARCH:	JUMPE 2,SRCWIN
	MOVEI 5,(2)			; copy of count
	MOVE 6,0			; copy of source pointer
	HRRZ 7,(1)
	ADD 7,HSTADR			; pointer for this entry
SRCNXW:	MOVE 10,(7)
	MOVE 11,(6)
	ANDCMI 11,1			; 1.1 is a loser
	CAIL 5,=5			; account for this word
	 JRST [	CAME 10,11		; match for this word?
		 JRST NXTHST
		SUBI 5,=5		; match, account for this word
		ADDI 7,1
		AOJA 6,SRCNXW]		; still more to go
	AND 11,[BYTE (7)000,000,000,000,000
		BYTE (7)177,000,000,000,000
		BYTE (7)177,177,000,000,000
		BYTE (7)177,177,177,000,000
		BYTE (7)177,177,177,177,000](5)
	CAMN 10,11			; exact match?
	 JRST SRCWIN			; stop the presses!
	SOJL 5,SRCWIN			; this string ends on word boundry
	AND 10,[BYTE (7)177,000,000,000,000
		BYTE (7)177,177,000,000,000
		BYTE (7)177,177,177,000,000
		BYTE (7)177,177,177,177,000](5)
	CAME 10,11			; match for partial word?
	 JRST NXTHST
SRCWIN:	HRRZ 5,NMRNAM(1)
	ADD 5,HSTADR
	OUTSTR (5)
	HLRZ 7,(1)
	ADD 7,HSTADR
	HLRZ 6,STLNAM(7)
	ADD 6,HSTADR
	CAIN 5,(6)
	 JRST OFFNAM			; official name
	OUTSTR [ASCIZ/ is a nickname for /]
	OUTSTR (6)
	OUTSTR [ASCIZ/ which/]
OFFNAM:	PUSHJ P,PRINT
NXTHST:	AOBJN 1,SEARCH
	JRST PROMPT

;Here to print information for a host.  Call with site table entry address in 7.

PRINT:	OUTSTR [ASCIZ/ is number /]
	HRRZ 6,STRADR(7)
NAMLP:	ADD 6,HSTADR
	MOVE X,ADDADR(6)
	PUSHJ P,PRHNUM
	HRRZ 6,ADRCDR(6)
	JUMPE 6,NAMDUN
	OUTSTR [ASCIZ/, /]
	JRST NAMLP
NAMDUN:	OUTSTR [ASCIZ/,
a /]
	SKIPL STLFLG(7)
	 SKIPA 10,[[ASCIZ/user /]]
	  MOVEI 10,[ASCIZ/server /]
	OUTSTR (10)
	HRRZ 6,STRMCH(7)
	JUMPE 6,[	OUTSTR [ASCIZ/unknown/]
			JRST MCHTYP]
	ADD 6,HSTADR
	OUTSTR (6)
MCHTYP:	OUTSTR [ASCIZ/ machine running /]
	HLRZ 6,STLSYS(7)
	JUMPE 6,[	OUTSTR [ASCIZ/an unknown operating system.

/]
			POPJ P,]
	ADD 6,HSTADR
	OUTSTR (6)
ENDNIC:	OUTSTR [ASCIZ/.

/]
	POPJ P,
;⊗ MAPHST

; MAPHST -- Map host table into core
; Call:	PUSHJ 17,MAPHST
;	<return>
; Smashes 0, 1, 2, and 3.

↑MAPHST:OPEN 0,[17 ↔ 'DSK   ' ↔ 0]
	 JRST 4,.-1
	DMOVE 0,HSTFIL
	MOVE 3,HSTPPN
	LOOKUP 0,
	 JRST 4,.-1
	MOVE 2,JOBFF↑
	MOVS 0,3 ↔ MOVN 0,0 ↔ ADDB 0, JOBFF↑	; get address of highest addr we need
	MOVEM 0,HSTTOP
	CORE 0,				; get more core from system maybe
	 JRST 4.,-1
	MOVE 0,3 ↔ HRRI 0,-1(2)		; compute IOWD to read host table in
	SETZ 1,
	INPUT 0,
	MOVE 0,(2)			; get first word of host table
	CAME 0,HSTFIL
	 JRST 4,.-1
	MOVEM 2,HSTADR			; remember where host table begins
	RELEAS 0,
	POPJ 17,
;⊗ HSTNUM HSTNU0 HSTNUS HSTNU1 HSTNU2 HSTNU3 HSTNUD

; HSTNUM -- Return descriptor block for a host
; Call:	MOVEI <host number>
;	PUSHJ 17,HSTNUM
;	<error return--no such host>
;	<return--absolute NAMNUM in 0, NUMSYS,,NUMNAM in 1, NUMBTS,,NUMMCH in 2>
; Smashes 0, 1, 2, 3, and 4.

HSTNUM:	GETNET 4,0			; get network number
	SKIPN 4
	 TLO 0,(NW%ARP)			; if none given, assume ARPANet
	MOVE 1,HSTADR
	MOVE 1,NETPTR(1)
	PUSHJ 17,HSTNUS			; lookup network number
	  POPJ 17,
	MOVE 1,NTRTAB(1)		; get address table for network
	MOVEM 4				; thing to search for
	PUSHJ 17,HSTNUS			; lookup address
	  POPJ 17,
	HLRZ 7,ADLSIT(1)		; get site table entry
	ADD 7,HSTADR
	JRST CPOPJ1

HSTNUS:	ADD 1,HSTADR			; relocate table
	MOVE 2,(1)			; get # of entries
	MOVE 3,1(1)			; and entry size
	ADDI 1,2			; point at first entry
HSTNU1:	CAMN 4,(1)			; found it?
	  JRST CPOPJ1			;   yes, skip return for success
	ADD 1,3				; point at next entry
	SOJG 2,HSTNU1			; keep on searching
	POPJ P,				; failed
;Subroutines ;⊗ SWINIR SWINR1 SWINR2 SWINIP CPOPJ1 CPOPJ SWINP1 PRHNUM PRHNIP PRDECP PRDEC PROCT PRLOOP PDL MONCMP HSTADR HSTTOP HSTEXT

;Some of these adapted from TELNET.MID[S,NET].

;  Super winning numeric input routine.  Numbers are parsed as both octal and
; decimal, unless either (a) an 8 or 9 appears in the number, or (b) the number
; is followed by a decimal point.

SWINIR:	SETZB A,B			; A ← octal number, B ← decimal
SWINR1:	CAIL X,"8"			; if can't be octal, A ← -1
	 SETO A,
	JUMPL A,SWINR2
	LSH A,3
	ADDI A,-"0"(X)			; bring in next octal digit
SWINR2:	IMULI B,=10
	ADDI B,-"0"(X)			; bring in next decimal digit
	ILDB X,Y
	CAIN X,"."			; decimal point ends spec and forces decimal
	 JRST [	SETO A,
		ILDB X,Y
		POPJ P,]
	CAIL X,"0"
	 CAILE X,"9"
	  POPJ P,			; non-numeric, return
	JRST SWINR1

;Super winning IP host number parser.  If an IP host number is seen, then it
;will be returned in B and for IFE FTHST3, IPHOST will be set; for IFN FTHST3,
;SWINIP will skip return.  Otherwise, just like SWINIR.

SWINIP:	PUSHJ P,SWINIR		;Parse a number
	CAIL X,"0"		;Check the next character
	CAILE X,"9"
	POPJ P,			;Not a digit, so not an IP host number
	PUSH P,B		;Save 1st byte
	PUSHJ P,SWINP1		;Get rest of IP host number left-adj in B
	POP P,A			;Restore 1st byte
	LSHC A,-=12		;Right-adjust entire number in B
CPOPJ1:	AOS (P)			;Skip to show IP host number
CPOPJ:	POPJ P,

;Subroutine to return an IP host number left-adjusted in B.

SWINP1:	PUSHJ P,SWINIR		;Get a number
	PUSH P,B		;Save it
	CAIL X,"0"		;See if a digit follows
	CAILE X,"9"
	TDZA B,B		;No.  Zero B and skip
	PUSHJ P,SWINP1		;Yes, get rest of IP host in B
	POP P,A			;Get back current byte
	LSHC A,-=8		;Shift into rest of number
	POPJ P,

;Routine to print a host number, either in SU Ethernet or IP format.  Takes
;host number in X.
PRHNUM:	TLNE X,740000		;Non-Internet?
	 JRST PRHNIP		;Yes, print non-IP
	LDB A,[POINT 8,X,11]
	PUSHJ P,PRDEC		;Print first byte
	LDB A,[POINT 8,X,19]
	PUSHJ P,PRDECP		;Print period and second byte
	LDB A,[POINT 8,X,27]
	PUSHJ P,PRDECP		;Print period and third byte
	LDB A,[POINT 8,X,35]
	PUSHJ P,PRDECP		;Print period and fourth byte
	POPJ P,

PRHNIP:	HLRZ A,X		;Get left half of addr
	CAIE A,(NW%SU)		;SU-Net?
	 POPJ P,		;No, return quietly
	OUTSTR [ASCIZ/SU /]
	LDB A,[POINT 8,X,27]
	PUSHJ P,PROCT		;Print first byte
	OUTCHR ["#"]
	LDB A,[POINT 8,X,35]
	PUSHJ P,PROCT		;Print second byte
	POPJ P,

PRDECP:	OUTCHR ["."]
PRDEC:	SKIPA C,[=10]
PROCT:	MOVEI C,10
PRLOOP:	IDIV A,C
	PUSH P,B
	SKIPE A
	 PUSHJ P,PRLOOP
	POP P,A
	ADDI A,"0"
	OUTCHR A
	POPJ P,

PDL:	BLOCK PDLEN

MONCMP:	BLOCK 1				; -1 → got a monitor command

HSTADR:	BLOCK 1
HSTTOP:	BLOCK 1
HSTEXT:	BLOCK 25

END START