; TAIL.ASM
;
; Display the Command Tail from the Program Segment Prefix.
; Original concept by Alan Pinck.
;
; This is this algorithm:
;
;   static char newln[] = { "\r\n" };
;   main(){
;	    char *si = (char *)0x81; /* memory location of tail */
;
;	    while( *si != '\r' ){
;		    if( *si == ' ' ){
;			    printf("%s", newln);
;			    do {
;				    ++si;
;			    } while( *si == ' ' );
;			    continue;
;		    }
;		    printf("%c",*si);
;		    ++si;
;	    }
;	    return 0;
;   }
;
; Note: The assembler needs to know whether an instruction operating on
; memory and a constant is operating on a single byte or a full 2-byte word.
; The syntax to specify a BYTE or a WORD looks like this:
;
;	cmp	BYTE PTR [si],0   ; compare one byte of memory with 0
;	cmp	WORD PTR [si],0   ; compare two bytes (a word) of memory
;
; -IAN! idallen@ncf.ca  November 1999
;----------------------------------------------------------------------
Tail	segment
	assume	CS:Tail,DS:Tail
	org	100h		; .COM requires this
;----------------------------------------------------------------------
start:
	; char *si = (char *)0x81;
	;
	mov	si,0081h	; point to start of tail

whiler:
	; while ( *si != '\r' )
	;
	cmp	BYTE PTR [si],0Dh ; look for ending CR byte
	je	done		; found it! exit loop

	; if ( *si == ' ' )
	;
	cmp	BYTE PTR [si]," " ; look for a blank
	jne	notsp		; no blank - jump to notsp code

	; printf("%s", newln);
	;
	mov	dx,offset newln	; ASCII$ string containing CR+LF
	mov	ah,09h		; code for "output ASCII$ string"
	int	21h

whiles:
	; do { ++si; } while ( *si == ' ' );
	;
	add	si,1h		; increment tail pointer
	cmp	BYTE PTR [si]," " ; look for another blank
	je	whiles		; keep looping if found

	; continue;
	;
	jmp	whiler		; continue outer loop when no more blanks

notsp:
	; printf("%c", *si);
	;
	mov	dl,[si]		; load byte from memory into DL
	mov	ah,02h		; code for "output one ASCII char from DL"
	int	21h

	; ++si;  (and jump back up to top of outer while loop)
	;
	add	si,1h		; increment pointer into tail
	jmp	whiler		; go back for next character

done:
	; return 0;
	;
	mov	al,0h		; return 0
	mov	ah,4Ch		; code for "terminate program"
	int	21h
;----------------------------------------------------------------------
; Data and variables down here.
;
newln	db	0Dh,0Ah
	db	"$"		; end of ASCII$ string
;----------------------------------------------------------------------
Tail	ends
	end start		; "start" is the label on the first instruction
