LISTFORMAT by Roelof Koning, SGGA, 1996

LISTFORMAT prints a neat listing to screen or printer. The line numbers 
are printed in a separate (first) column. Keywords are wrapped around to 
the next line when they do not fit on the current line. Evry statement begins 
on a new line. Indentation (a space) is used with FOR, taken back at NEXT.
Indentation only takes place between the fifth character position (min.) and 
halfway the current line length (max.). The line length can be adjusted by 
POKE 60255, linelength. Ideal for printing listings that must be publicized in 
two columns. Listing starts after a LIST USR command. Because the BC 
register holds 65535 on return to BASIC, the normal 'LIST' command used 
here does nothing when the 'USR' function is finished. PRINT USR 6e4 
gives 65535. RANDOMIZE USR 6e4 prints in the lower screen part.
This version 1.0 is the first version, the use of registers might be optimized
in a later version.

LIST FORMAT v1.0	( This routine starts with LIST USR 60000, or
           	  LLIST USR 60000, so 'open #2 /3 ' is omitted)

Variables
60252 : Leftmargin text Permanent (= 5)
60253 : Leftmargin text Temporarely
60254 : Charactercounter
60255 : Linelength (default 32)
In red: Addresses of  Spectrum ROM routines

MAINLOOP
------------------
60000  3E05     	LD   	A,005       	Set leftmargin
60002  325CEB   	LD   	(60252),A
60005  2A535C   	LD   	HL,(23635)  	Get PROG-start
60008  3ED7     	LD   	A,215       	Trick to skip the D7 (=RST 016) on entry !!!!
60010  01FFFF   	LD   	BC,65535    	When finished, no listing will appear!
60013  3A5CEB   	LD   	A,(60252)   	leftmarg P              
60016  325DEB   	LD   	(60253),A   	into leftmarg T
60019  7E       	LD   	A,(HL)      	Get char. (= line no.)
60020  FE40     	CP   	064         	Test for last BASICline
60022  D0       	RET  	NC          	Exit if so
60023  CD281A   	CALL	06696       	Print linenumber
60026  23       	INC  	HL          	Skip linelength bytes
60027  23       	INC  	HL
60028  23       	INC  	HL
60029  0E04     	LD    	C,004       	Print (leftmarg) spaces
60031  CD15EB   	CALL 	60181            	   minus 4
60034  FDCB3096 	RES  	2,(IY+048)  	Signal 'not inside quotes'
60038  7E       	LD   	A,(HL)      	Get char
60039  CDB618   	CALL 	06326       	Skip any FP notation
60042  23       	INC  	HL          	Point already to next char
60043  FE0D     	CP   	013
60045  28DA     	JR   	Z,60009     	Start next BASIC line
60047  FE3A     	CP   	058         	Test for end of STMT  (:)
60049  200B     	JR   	NZ,60062    	Cont. if not
60051  FDCB3056 	BIT  	2,(IY+048)  	Is ':' inside quotes?
60055  2005     	JR   	NZ,60062    	Jp if so, treat like normal char
60057  CD10EB   	CALL 	60176       	Print NL + leftmargin
60060  18E8     	JR   	60038       	Next char

PRINT A CHAR.
-----------------------
60062  E5       	PUSH 	HL          	Save mem.pointer
60063  F5       	PUSH 	AF          	Save char.
60064  FEA5     	CP   	165         	Test for TOKEN
60066  300C     	JR   	NC,60080    	Jp if so
60068  FE20     	CP   	032         	Test for controlchars
60070  D433EB   	CALL 	NC,60211    Inc counter if not control
60073  F1       	POP  	AF          	Retrieve char
60074  CD5A19   	CALL 	06490       	Print char, testing for quotes
60077  E1       	POP  	HL          	Retrieve pointer
60078  18D6     	JR   	60038       	Next char

PRINT TOKEN
---------------------
60080  F5       	PUSH 	AF          	Save char
60081  D6A3     	SUB  	163         	Adjust range  (2 to -)
60083  219500   	LD   	HL,00149    	Start of tokentable
60086  54       	LD   	D,H            	Find address of next token
60087  5D       	LD   	E,L            	 in HL, address of token in
60088  CB7E     	BIT  	7,(HL)         	 DE.
60090  23       	INC  	HL             	Length of keyword is HL-DE
60091  28FB     	JR   	Z,60088
60093  3D       	DEC  	A
60094  20F6     	JR   	NZ,60086
60096  AF       	XOR  	A           	Reset carryflag
60097  ED52     	SBC  	HL,DE       	Calc. length
60099  F1       	POP  	AF          	Retrieve char
60100  FEC5     	CP   	197         	Leading space needed?
60102  D5       	PUSH 	DE          	Store tokentablepointer
60103  3806     	JR   	C,60111     	Jp if no space needed
60105  1A       	LD   	A,(DE)      	Test for '<=' and '>='
60106  D641     	SUB  	065
60108  D465EB   	CALL 	NC,60231	Print leading space
60111  45       	LD   	B,L         	Length into B
60112  CD35EB   	CALL 	60213       	Adjust counter
60115  D1       	POP  	DE          	Retrieve pointer
60116  1A       	LD   	A,(DE)      	Print keyword
60117  E67F     	AND  	127     	Drop any endmarker (bit 7)
60119  CD3B0C   	CALL 	03131
60122  1A       	LD   	A,(DE)	Each following char in turn
60123  13       	INC  	DE
60124  87       	ADD  	A,A                  Test for last char (bit 7 set)
60125  30F5     	JR   	NC,60116
60127  D1       	POP  	DE          	Retrieve tokennr. in D
60128  FE48     	CP   	072         	Test last char of keyword for $
60130  2804     	JR   	Z,60136     	Jp if so
60132  FE82     	CP   	130         	Test for alphanumeric
60134  38C5     	JR   	C,60077     	Jp if not
60136  7A       	LD   	A,D         	Get tokennr.
60137  FEA8     	CP   	168         	exclude first three
60139  D44CEB   	CALL 	NC,60236 	Print trailing space

TEST 'FOR' & 'THEN', ADJUST LEFTMARGIN WHEN APPROPRIATE
-----------------------------------------------------------------------------------------------
60142  215CEB   	LD   	HL,60252    	Point to DEFB-table
60145  7A       	LD   	A,D         	Get tokennr.
60146  FEEB     	CP   	235         	Test for 'FOR'
60148  200F     	JR   	NZ,60165    	Jp if not
60150  34       	INC  	(HL)        	Inc leftmargin P
60151  3A5FEB   	LD   	A,(60255)   	Test against linelenght/2
60154  CB3F     	SRL  	A
60156  BE       	CP   	(HL)
60157  3801     	JR   	C,60160     	Jp if past half-line
60159  7E       	LD   	A,(HL)      	Get leftmarg P
60160  77       	LD   	(HL),A      	Store into leftmarg P
60161  23       	INC  	HL          	Point to leftmarg T
60162  77       	LD   	(HL),A      	Store same value
60163  18AC     	JR   	60077       	Next char

60165  FECB     	CP   	203         	Test for 'THEN'
60167  20A4     	JR   	NZ,60077    	Next char, if not
60169  23       	INC  	HL          	Point to leftmarg T
60170  34       	INC  	(HL)        	Inc lmT only
60171  CD10EB   	CALL 	60176       	Print NEWLINE and leftmargin
60174  18A1     	JR   	60077       	Next char

PRINT  + ADJUST LEFTMARGIN IF NEXT CHAR = NEXT
-------------------------------------------------------------------------------
60176  3E0D     	LD   	A,13        	Print NEWLINE
60178  D7       	RST  	016
60179  0E00     	LD   	C,000       	Signal 'no margin offset'

60181  115DEB   	LD  	DE,60253    	Point to DEFB-table, lmT
60184  7E       	LD   	A,(HL)      	Fetch next (!) BASIC char
60185  FEF3     	CP   	243         	Test for 'NEXT'
60187  200A     	JR   	NZ,60199    	Jp if not
60189  1B       	DEC  	DE          	DE = lmP
60190  1A       	LD   	A,(DE)
60191  3D       	DEC  	A           	Dec leftmargin P
60192  FE05     	CP   	005        	Keep at least 5 spaces
60194  CE00     	ADC  	A,000
60196  12       	LD   	(DE),A      	Store new lm P
60197  13       	INC  	DE          	Point to lmT
60198  12       	LD   	(DE),A      	Store also in lmT
60199  1A       	LD   	A,(DE)      	Get value when coming from 60187
60200  13       	INC  	DE          	Point to counter
60201  12       	LD   	(DE),A      	Move leftmarg into counter
60202  91       	SUB  	C           	Evaluate any 'offset' (used when
60203  4F       	LD   	C,A        	     linenumber printed)
60204  3E20     	LD   	A,032       	Print 'C' spaces
60206  D7       	RST  	016
60207  0D       	DEC  	C
60208  20FA     	JR   	NZ,60204
60210  C9       	RET

ADJUST COUNTER
---------------------------
60211  0601     	LD   	B,001       	Enter here when single char has
                                                     			    to be printed
60213  3A5EEB   	LD   	A,(60254)   	Point to COUNTER
60216  80       	ADD  	A,B         	Inc counter
60217  325EEB   	LD   	(60254),A   	Store new value
60220  4F       	LD   	C,A         	Save counter
60221  3A5FEB   	LD   	A,(60255)   	Get linelength
60224  B9       	CP   	C           	Test for end of line
60225  D0       	RET  	NC          	Ret if not
60226  CD10EB   	CALL 	60176       	Print NEWLINE + leftmargin
60229  18EE     	JR   	60213       	Adjust counter on new line

PRINT LEADING OR TRAILING SPACE
------------------------------------------------------
60231  FDCB0146 	BIT  	0,(IY+001)  	Test if last char was space
60235  C0       	RET  	NZ          	Jp if so
 
60236  3A5EEB   	LD   	A,(60254)   	Fetch counter
60239  4F       	LD   	C,A         	Store
60240  3A5DEB   	LD   	A,(60253)   	Fetch leftmargin T
60243  91       	SUB  	C           	Test for 'on first column'
60244  C8       	RET  	Z           	Ret if so, no space printed
60245  CD33EB   	CALL 	60211       	Adjust counter
60248  3E20     	LD   	A,032       	Print space
60250  D7       	RST  	016
60251  C9       	RET

Adresses that hold variables
--------------------------------------
60252   lmP		: Leftmargin text Permanent
60253   lmT		: Leftmargin text Temporarely
60254   counter		: Charactercounter
60255   linelength		: Linelength (default 32, can be poked)

**end