     1                                  ; ****************************************************************************
     2                                  ; sh386.s (sh6.s) - Retro Unix 386 v1 Shell - /bin/sh
     3                                  ; ----------------------------------------------------------------------------
     4                                  ;
     5                                  ; RETRO UNIX 386 (Retro Unix == Turkish Rational Unix)
     6                                  ; Operating System Project (v0.2) by ERDOGAN TAN (Beginning: 24/12/2013)
     7                                  ;
     8                                  ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
     9                                  ; (v0.1 - Beginning: 11/07/2012)
    10                                  ;
    11                                  ; [ Last Modification: 17/06/2022 ]
    12                                  ;
    13                                  ; Derived from UNIX Operating System (v1.0 for PDP-11) 
    14                                  ; (Original) Source Code by Ken Thompson (Bell Laboratories, 1971-1972)
    15                                  ; ****************************************************************************
    16                                  ;
    17                                  ; <Preliminary Release of UNIX Implementation Document>
    18                                  ; <Isuse: D, Date: 17/3/1972, ID: IMO.1-1, Section: E.11> 
    19                                  ; <sh - command interpreter>
    20                                  ;
    21                                  ; ****************************************************************************
    22                                  
    23                                  ; Assembler: NASM v2.15
    24                                  ; ((nasm sh6.s -l sh6.txt -o sh6 -Z error.txt))
    25                                  
    26                                  ; sh6.s (17/06/2022, Retro UNIX 386 v1) -- (modified sh2.s) --
    27                                  ; sh5.s (17/06/2022, Retro UNIX 386 v1.1) -- (modified sh2.s) --
    28                                  ; sh4.s (13/06/2022, Retro UNIX 386 v1.2) -- (modified sh2.s) ---
    29                                  ; sh3.s (29/05/2022, Retro UNIX 386 v1) -- (modified sh0.s) ---
    30                                  ; sh2.s (29/05/2022, Retro UNIX 386 v1.1 & v1.2) -- (modified sh1.s) --
    31                                  ; sh1.s (03/01/2016, Retro UNIX 386 v1.1)
    32                                  ; sh0.s (28/12/2015, Retro UNIX 386 v1, NASM 2.11, 32 bit version of 'sh.asm')
    33                                  ; SHELL03.ASM, 13/11/2013 - 27/06/2014 (sh.asm, Retro UNIX 8086 v1, MASM 6.11)  
    34                                  
    35                                  ; 12/01/2022 (Retro UNIX 386 v1.2)
    36                                  ; 13/10/2015
    37                                  ; 27/08/2015
    38                                  ; 24/08/2015
    39                                  ; 08/04/2014
    40                                  ; 13/11/2013
    41                                  
    42                                  ; UNIX v1 system calls
    43                                  _rele 	equ 0
    44                                  _exit 	equ 1
    45                                  _fork 	equ 2
    46                                  _read 	equ 3
    47                                  _write	equ 4
    48                                  _open	equ 5
    49                                  _close 	equ 6
    50                                  _wait 	equ 7
    51                                  _creat 	equ 8
    52                                  _link 	equ 9
    53                                  _unlink	equ 10
    54                                  _exec	equ 11
    55                                  _chdir	equ 12
    56                                  _time 	equ 13
    57                                  _mkdir 	equ 14
    58                                  _chmod	equ 15
    59                                  _chown	equ 16
    60                                  _break	equ 17
    61                                  _stat	equ 18
    62                                  _seek	equ 19
    63                                  _tell 	equ 20
    64                                  _mount	equ 21
    65                                  _umount	equ 22
    66                                  _setuid	equ 23
    67                                  _getuid	equ 24
    68                                  _stime	equ 25
    69                                  _quit	equ 26	
    70                                  _intr	equ 27
    71                                  _fstat	equ 28
    72                                  _emt 	equ 29
    73                                  _mdate 	equ 30
    74                                  _stty 	equ 31
    75                                  _gtty	equ 32
    76                                  _ilgins	equ 33
    77                                  _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
    78                                  _msg    equ 35 ; Retro UNIX 386 v1 feature only !
    79                                  _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
    80                                  ; 12/01/2022 - Retro UNIX 386 v1.2
    81                                  ; Retro UNIX 386 v2 system calls
    82                                  _setgid	equ 37
    83                                  _getgid	equ 38
    84                                  _sysver	equ 39 ; (get) Retro Unix 386 version
    85                                  
    86                                  %macro sys 1-4
    87                                      ; 03/09/2015
    88                                      ; 13/04/2015
    89                                      ; Retro UNIX 386 v1 system call.
    90                                      %if %0 >= 2   
    91                                          mov ebx, %2
    92                                          %if %0 >= 3
    93                                              mov ecx, %3
    94                                              ;%if %0 = 4
    95                                              %if	%0 >= 4 ; 11/03/2022
    96                                  		mov edx, %4
    97                                              %endif
    98                                          %endif
    99                                      %endif
   100                                      mov eax, %1
   101                                      int 30h
   102                                  %endmacro
   103                                  
   104                                  ; 17/06/2022 - Retro UNIX 386 v1.1
   105                                  struc stat
   106                                  	; Retro UNIX v1 'sysstat' output !
   107                                  	; (34 bytes)
   108 00000000 ????                    	.inode:  resw 1	
   109 00000002 ????                    	.mode:	 resw 1
   110 00000004 ??                      	.nlinks: resb 1
   111 00000005 ??                      	.uid:	 resb 1
   112 00000006 ????                    	.size:	 resw 1
   113 00000008 <res 10h>               	.dskptr: resw 8
   114 00000018 ????????                	.ctime:	 resd 1
   115 0000001C ????????                	.mtime:	 resd 1
   116 00000020 ????                    	.rsvd:   resw 1
   117                                  	.strucsize:
   118                                  endstruc  
   119                                  
   120                                  ; Retro UNIX 386 v1 system call format:
   121                                  ; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
   122                                  
   123                                  ;-----------------------------------------------------------------
   124                                  ;  text - code
   125                                  ;-----------------------------------------------------------------
   126                                  
   127                                  [BITS 32] ; 32-bit intructions (for 80386 protected mode)
   128                                  
   129                                  [ORG 0] 
   130                                  
   131                                  START_CODE:
   132                                  ;/ sh -- command interpreter
   133                                  
   134                                  	; 17/06/2022
   135                                  	; 29/05/2022 - Erdogan Tan
   136                                  	; (Modified by using disassembled unix v2 'sh' code.)
   137                                  	
   138                                  	;;27/12/2015
   139                                  	;;clear BSS
   140                                  	;mov	ecx, ((bss_end - bss_start) + 3) / 4
   141                                  	;sub	eax, eax
   142                                  	;mov	edi, bss_start
   143                                  	;rep	stosd
   144                                  s0:
   145 00000000 89E5                    	mov	ebp, esp
   146                                  		; mov sp,r5
   147 00000002 892D[820C0000]          	mov	[shellarg], ebp
   148                                  		; mov r5,shellarg / save orig sp in shellarg
   149 00000008 8B5D04                  	mov	ebx, [ebp+4]
   150 0000000B 803B2D                  	cmp	byte [ebx], '-'
   151                                  		; cmpb	*2(r5),$'- / was this sh called by init or login
   152 0000000E 752E                    	jne	short s1
   153                                  		; bne 2f / no
   154                                  	sys	_intr, 0
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000010 BB00000000          <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000015 B81B000000          <1>  mov eax, %1
   101 0000001A CD30                <1>  int 30h
   155                                  		; sys intr; 0 / yes, turn off interrupts
   156                                  	sys	_quit, 0
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 0000001C BB00000000          <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000021 B81A000000          <1>  mov eax, %1
   101 00000026 CD30                <1>  int 30h
   157                                  		; sys quit; 0
   158                                  	sys	_write, 1, msg_unix_sh, msgsh_size
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000028 BB01000000          <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 0000002D B9[FD050000]        <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96 00000032 BA1B000000          <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000037 B804000000          <1>  mov eax, %1
   101 0000003C CD30                <1>  int 30h
   159                                  s1: ;2:
   160                                  	sys	_getuid
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91                              <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 0000003E B818000000          <1>  mov eax, %1
   101 00000043 CD30                <1>  int 30h
   161                                  		; sys	getuid / who is user
   162                                  	;and	eax, eax
   163 00000045 20C0                    	and	al, al
   164                                  		; tst r0 / is it superuser
   165 00000047 7507                    	jnz	short s2
   166                                  		; bne 2f / no
   167 00000049 C605[89060000]23        	mov	byte [_at], '#'
   168                                  		; movb $'#,at / yes, set new prompt symbol
   169                                  s2: ;2:
   170 00000050 837D0001                	cmp	dword [ebp], 1
   171                                  		; cmp (r5),$1 / tty input?
   172 00000054 7631                    	jna	short newline
   173                                  		; ble newline / yes, call with '-' (or with no command
   174                                  		      ; / file name)
   175 00000056 31DB                    	xor	ebx, ebx
   176                                  		; clr r0 / no, set tty
   177                                  	sys	_close
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91                              <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000058 B806000000          <1>  mov eax, %1
   101 0000005D CD30                <1>  int 30h
   178                                  		; sys close / close it
   179 0000005F 8B5D08                  	mov	ebx, [ebp+8] ; arg 1
   180                                  		; mov 4(r5),0f / get new file name
   181 00000062 31C9                    	xor	ecx, ecx ; arg 2
   182                                  	sys	_open
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91                              <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000064 B805000000          <1>  mov eax, %1
   101 00000069 CD30                <1>  int 30h
   183                                  		; sys open; 0:..; 0 / open it
   184 0000006B 7311                    	jnc	short s3
   185                                  		; bec 1f / branch if no error
   186 0000006D BE[25060000]            	mov	esi, msgNotFound
   187 00000072 E8EA010000              	call	error
   188                                  		; jsr r5,error / error in file name
   189                                  		; <Input not found\n\0>; .even
   190                                  	sys	_exit
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91                              <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000077 B801000000          <1>  mov eax, %1
   101 0000007C CD30                <1>  int 30h
   191                                  		; sys exit
   192                                  s3: ;1:
   193 0000007E C605[89060000]00        	mov	byte [_at], 0
   194                                  		; clr at / clear prompt character, if reading non-tty
   195                                  		   ; / input file
   196 00000085 EB1F                    	jmp	short newcom
   197                                  newline:
   198 00000087 803D[89060000]00        	cmp	byte [_at], 0
   199                                  		; tst at / is there a prompt symbol
   200 0000008E 7616                    	jna	short newcom
   201                                  		; beq newcom / no
   202                                  		; mov $1,r0 / yes
   203                                  nl:
   204                                  	sys	_write, 1, prompt, p_size
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000090 BB01000000          <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 00000095 B9[87060000]        <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96 0000009A BA04000000          <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 0000009F B804000000          <1>  mov eax, %1
   101 000000A4 CD30                <1>  int 30h
   205                                  	;sys	_write, 1, _at, 2
   206                                  		; sys write; at; 2. / print prompt
   207                                  newcom:
   208 000000A6 8B25[820C0000]          	mov	esp, [shellarg]
   209                                  		; mov shellarg,sp /
   210 000000AC BE[B6060000]            	mov	esi, parbuf 
   211                                  		; mov $parbuf,r3 / initialize command list area
   212 000000B1 BF[B00A0000]            	mov	edi, parp
   213                                  		; mov $parp,r4 / initialize command list pointers
   214 000000B6 31C0                    	xor	eax, eax
   215 000000B8 A3[A40A0000]            	mov	[infile], eax ; 0	
   216                                  		; clr infile / initialize alternate input
   217 000000BD A3[A80A0000]            	mov	[outfile], eax ; 0
   218                                  		; clr outfile / initialize alternate output
   219 000000C2 A2[A20A0000]            	mov	[glflag], al ; 0
   220                                  	;mov	[glflag], ax ; 0
   221                                  		; clr glflag / initialize global flag
   222                                  	; 27/12/2015
   223 000000C7 A2[86060000]            	mov	[FCAT], al ; 0
   224                                  newarg:
   225 000000CC E8B8030000              	call	blank
   226                                  		; jsr pc,blank / squeeze out leading blanks
   227 000000D1 E894030000              	call	delim
   228 000000D6 7467                    	je	short nch4 ; '\n', ';', '&'
   229                                  		; jsr r5,delim / is new character a ; \n or &
   230                                  		;     br 2f / yes
   231 000000D8 56                      	push	esi
   232                                  		; mov r3,-(sp) / no, push arg pointer onto stack
   233 000000D9 3C3C                    	cmp	al, '<'
   234                                  		; cmp r0,$'< / new input file?
   235 000000DB 7508                    	jne	short na1
   236                                  		; bne 1f / no
   237 000000DD 8935[A40A0000]          	mov	[infile], esi
   238                                  		; mov (sp),infile / yes, save arg pointer
   239                                  	;jmp 	short na4
   240 000000E3 EB1E                    	jmp	short na3
   241                                  	;mov	dword [esp], 0
   242                                  		; clr (sp) / clear pointer
   243                                  	;jmp	short nch1
   244                                  		; br 3f
   245                                  na1: ;1:
   246 000000E5 3C3E                    	cmp	al, '>'
   247                                  		; cmp r0,$'> / new output file?
   248 000000E7 7530                    	jne	short nch0
   249                                  	;jne	short newchar
   250                                  		; bne newchar / no
   251 000000E9 8935[A80A0000]          	mov	[outfile], esi
   252                                  		; mov (sp),outfile / yes, save arg pointer
   253                                  	; 27/12/2015
   254 000000EF E8A7030000              	call	getc
   255 000000F4 3C3E                    	cmp	al, '>'
   256 000000F6 7507                    	jne	short na2
   257                                  	;
   258 000000F8 A2[86060000]            	mov	[FCAT], al ; '>>'
   259 000000FD EB04                    	jmp	short na3
   260                                  na2:
   261 000000FF 3C20                    	cmp	al, 20h ; ' '
   262 00000101 7505                    	jne	short na4
   263                                  na3:
   264 00000103 E881030000              	call	blank
   265                                  na4:	
   266 00000108 C7042400000000          	mov	dword [esp], 0
   267                                  		; clr (sp) / clear pointer
   268                                  	;jmp	short nch1
   269                                  		; br 3f
   270 0000010F EB12                    	jmp	short nch7
   271                                  newchar:
   272 00000111 3C20                    	cmp	al, 20h
   273                                  		; cmp $' ,r0 / is character a blank
   274 00000113 7415                    	je	short nch2
   275                                  		; beq 1f / branch if it is (blank as arg separator)
   276 00000115 3C8D                            cmp     al, 8Dh ; 128 + 13
   277 00000117 7411                    	je	short nch2
   278                                  		; cmp $'\n+200,r0 / treat \n preceded by 		; beq 1f / as blank
   280                                  nch0:
   281 00000119 E8A0010000              	call	putc
   282                                  		; jsr pc,putc / put this character in parbuf list
   283                                  nch1: ;3:
   284 0000011E E878030000              	call	getc
   285                                  		; jsr pc,getc / get next character
   286                                  nch7:
   287 00000123 E842030000              	call	delim
   288 00000128 75E7                    	jne	short newchar
   289                                  	;jz	short nch2 ; '\n', ';', '&'
   290                                  		; jsr r5,delim / is char a ; \n or &,
   291                                  		;     br 1f / yes
   292                                  	;jmp	short newchar
   293                                  		; br newchar / no, start new character tests
   294                                  nch2: ;1:
   295 0000012A C60600                  	mov	byte [esi], 0
   296 0000012D 46                      	inc	esi
   297                                  		; clrb (r3)+ / end name with \0 when read blank, 
   298                                  			  ; or delim
   299 0000012E 5B                      	pop	ebx
   300 0000012F 891F                    	mov	[edi], ebx
   301                                  		; mov (sp)+,(r4)+ / move arg ptr to parp location
   302 00000131 09DB                    	or	ebx, ebx
   303 00000133 7403                    	jz	short nch3
   304                                  	;jnz	short nch3
   305                                  		; bne 1f / if (sp)=0, in file or out file points
   306                                  				; to arg
   307 00000135 83C704                  	add	edi, 4
   308                                  		; tst -(r4) / so ignore dummy (0), in pointer list
   309                                  nch3: ;1:
   310 00000138 E82D030000              	call	delim
   311 0000013D 758D                    	jne	short newarg
   312                                  	;jz	short nch4 ; '\n', ';', '&'
   313                                  		; jsr r5,delim / is char a ; \n or &.
   314                                  		;     br 2f / yes
   315                                  	;jmp	short newarg
   316                                  		; br newarg / no, start newarg processing
   317                                  nch4: ;2:
   318 0000013F C70700000000            	mov	dword [edi], 0
   319                                  		; clr (r4) / \n, &, or ; takes to here 
   320                                  			 ; / (end of arg list) after 'delim' call
   321 00000145 50                      	push	eax
   322                                  		; mov r0,-(sp) / save delimiter in stack
   323 00000146 E827000000              	call	docom
   324                                  		; jsr pc,docom / go to exec command in parbuf
   325 0000014B 803C2426                	cmp	byte [esp], '&'
   326                                  		; cmpb (sp),$'& / get a new command without wait?
   327                                          ;je	newcom
   328                                  	;	; beq newcom / yes
   329                                  	; 29/05/2022
   330 0000014F 7505                    	jne	short nch_9
   331                                  nch_8:
   332 00000151 E950FFFFFF              	jmp	newcom
   333                                  nch_9:
   334 00000156 21D2                    	and	edx, edx
   335                                  		; tst r1 / was chdir just executed or line ended
   336                                  			; / with ampersand?
   337 00000158 740D                    	jz	short nch6
   338                                  		; beq 2f / yes
   339                                  nch5: ;1:
   340                                  	sys	_wait
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91                              <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 0000015A B807000000          <1>  mov eax, %1
   101 0000015F CD30                <1>  int 30h
   341                                  		; sys wait / no, wait for new process to terminate
   342                                                          ; / command executed)
   343 00000161 7204                    	jc	short nch6
   344                                  		; bcs 2f / no, children not previously waited for
   345 00000163 39D0                    	cmp	eax, edx
   346                                  		; cmp r0,r1 / is this my child
   347 00000165 75F3                    	jne	short nch5
   348                                  		; bne 1b
   349                                  nch6: ;2:
   350 00000167 803C240D                	cmp	byte [esp], 0Dh
   351                                  	;cmp	byte [esp], 0Ah
   352                                  		; cmp (sp),$'\n / was delimiter a new line
   353                                          ;je	newline
   354                                  	;	; beq newline / yes
   355                                  	; 29/05/2022
   356                                  	;jmp	newcom
   357                                  	;	; br newcom / no, pick up next command
   358 0000016B 75E4                    	jne	short nch_8  ; jne newcom
   359 0000016D E915FFFFFF              	jmp	newline  ; je newline
   360                                  docom:
   361 00000172 81EF[B00A0000]          	sub	edi, parp
   362                                  		; sub $parp,r4 / out arg count in r4
   363 00000178 7503                    	jne	short dcom1
   364                                  		; bne 1f / any arguments?
   365                                  dcom0:
   366 0000017A 29D2                    	sub 	edx, edx ; 0
   367                                  		; clr r1 / no, line ended with ampersand
   368 0000017C C3                      	retn
   369                                  		; rts pc / return from call
   370                                  dcom1: ;1:
   371 0000017D 89FB                    	mov	ebx, edi
   372                                  	; 06/12/2013
   373 0000017F BE[8B060000]            	mov	esi, qecho 
   374 00000184 E827010000              	call	chcom
   375 00000189 7543                    	jnz	short dcom7
   376                                  	; 28/12/2015
   377 0000018B 89DD                    	mov	ebp, ebx
   378 0000018D BF[B00A0000]            	mov	edi, parp
   379                                  dcom9:  ; CRLF
   380                                  	sys	_write, 1, nextline, 2
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000192 BB01000000          <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 00000197 B9[22060000]        <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96 0000019C BA02000000          <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 000001A1 B804000000          <1>  mov eax, %1
   101 000001A6 CD30                <1>  int 30h
   381                                  	;
   382 000001A8 83ED04                  	sub	ebp, 4 ; remain arg count x 4
   383 000001AB 76CD                    	jna	short dcom0
   384 000001AD 83C704                  	add	edi, 4
   385 000001B0 8B37                    	mov	esi, [edi]
   386                                  	;or 	esi, esi
   387                                  	;jz	short dcom0
   388 000001B2 89F2                    	mov	edx, esi ; string address
   389                                  dcom10:
   390 000001B4 AC                      	lodsb
   391 000001B5 08C0                    	or 	al, al
   392 000001B7 75FB                    	jnz	short dcom10
   393 000001B9 87D6                    	xchg 	edx, esi
   394 000001BB 29F2                    	sub	edx, esi  ; byte count
   395 000001BD 4A                      	dec	edx
   396                                  	;jz	short dcom0
   397                                  	; write string
   398                                  	sys	_write, 1, esi ; edx = byte count
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 000001BE BB01000000          <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 000001C3 89F1                <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 000001C5 B804000000          <1>  mov eax, %1
   101 000001CA CD30                <1>  int 30h
   399 000001CC EBC4                    	jmp	short dcom9
   400                                  dcom7:
   401 000001CE BE[93060000]            	mov	esi, qchdir
   402 000001D3 E8D8000000              	call	chcom
   403 000001D8 752D                    	jnz	short dcom4
   404                                  		; jsr r5,chcom; qchdir / is command chdir?
   405                                  		;     br 2f / command not chdir
   406                                  dcom12:
   407 000001DA 80FB08                  	cmp	bl, 8 ; 8 = arg count x 4 (24/08/2015)
   408                                  	;cmp	bx, 8
   409                                  		; cmp r4,$4 / prepare to exec chdir, 
   410                                  			  ; 4 = arg count x 2
   411 000001DD 740C                    	je	short dcom2
   412                                  		; beq 3f
   413                                  dcom8:
   414 000001DF BE[35060000]            	mov	esi, msgArgCount
   415 000001E4 E878000000              	call	error
   416                                  		; jsr r5,error / go to print error
   417                                  		;  	<Arg count\n\0>; .even
   418                                  	;jmp	short dcom3
   419                                  		; br 4f
   420 000001E9 EB8F                    	jmp	short dcom0
   421                                  dcom2: ;3:
   422 000001EB 8B1D[B40A0000]          	mov	ebx, [parp+4]
   423                                  		;mov parp+2,0f / move directory name to sys call
   424                                  	sys	_chdir
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91                              <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 000001F1 B80C000000          <1>  mov eax, %1
   101 000001F6 CD30                <1>  int 30h
   425                                  		; sys chdir; 0:0 / exec chdir
   426 000001F8 730A                    	jnc	short dcom3
   427                                  		; bec 4f / no error exit
   428 000001FA BE[3F060000]            	mov	esi, msgBadDir
   429 000001FF E85D000000              	call	error
   430                                  		; jsr r5,error / go to print error
   431                                  		; 	<Bad directory\n\0>; .even
   432                                  				; / this diagnostic
   433                                  dcom3: ;4:
   434 00000204 31D2                    	xor	edx, edx ; 0
   435                                  		; clr r1 / set r1 to zero to skip wait
   436 00000206 C3                      	retn
   437                                  		; rts pc / and return
   438                                  dcom4: ;2:
   439                                  	; 06/12/2013
   440 00000207 BE[90060000]            	mov	esi, qcd
   441 0000020C E89F000000              	call	chcom
   442 00000211 74C7                    	jz	short dcom12
   443                                  dcom11:
   444 00000213 BE[99060000]            	mov	esi, glogin
   445 00000218 E893000000              	call	chcom
   446 0000021D 7522                    	jnz	short dcom5
   447                                  		; jsr r5,chcom; glogin / is command login?
   448                                  		;     br 2f / not loqin, go to fork
   449                                  	sys	_exec, parbuf, parp
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 0000021F BB[B6060000]        <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 00000224 B9[B00A0000]        <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000229 B80B000000          <1>  mov eax, %1
   101 0000022E CD30                <1>  int 30h
   450                                  		; sys exec; parbuf; parp / exec login
   451                                  	sys	_exec, binpb, parp
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000230 BB[B1060000]        <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 00000235 B9[B00A0000]        <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 0000023A B80B000000          <1>  mov eax, %1
   101 0000023F CD30                <1>  int 30h
   452                                  		; sys exec; binpb; parp / or /bin/login
   453                                  dcom5: ;2: / no error return??
   454 00000241 BB[F3020000]            	mov	ebx, newproc
   455                                  	; child process will return to 'newproc' address
   456                                  	sys	_fork
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91                              <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000246 B802000000          <1>  mov eax, %1
   101 0000024B CD30                <1>  int 30h
   457                                  		; sys fork / generate sh child process
   458                                  			 ; for command
   459                                                  ;     br newproc / exec command with 
   460                                  			 ; new process
   461                                  	; parent process will return here
   462 0000024D 730F                    	jnc	short dcom6
   463                                  		; bec 1f / no error exit, old process
   464 0000024F BE[4D060000]            	mov	esi, msgTryAgain
   465 00000254 E808000000              	call	error
   466                                  		; jsr r5,error / go to print error
   467                                  		;     <Try again\n\0>; .even / this diagnostic
   468 00000259 E929FEFFFF                      jmp     newline
   469                                  		; jmp newline / and return for next try
   470                                  dcom6: ;1:
   471 0000025E 89C2                    	mov	edx, eax ; child process ID
   472                                  		; mov r0,r1 / save id of child sh
   473 00000260 C3                      	retn
   474                                  		; rts pc / return to "jsr pc, docom" call
   475                                  			; in parent sh
   476                                  error:
   477                                  	sys	_write, 1, nextline, 2
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000261 BB01000000          <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 00000266 B9[22060000]        <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96 0000026B BA02000000          <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000270 B804000000          <1>  mov eax, %1
   101 00000275 CD30                <1>  int 30h
   478                                  s4:
   479 00000277 AC                      	lodsb
   480 00000278 A2[800C0000]            	mov	[och], al
   481                                                  ; movb (r5)+,och / pick up diagnostic character
   482 0000027D 20C0                    	and	al, al
   483 0000027F 7418                    	jz	short s5
   484                                  		; beq 1f / 0 is end of line
   485                                  	sys	_write, 1, och, 1
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000281 BB01000000          <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 00000286 B9[800C0000]        <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96 0000028B BA01000000          <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000290 B804000000          <1>  mov eax, %1
   101 00000295 CD30                <1>  int 30h
   486                                  		; mov $1,r0 / set for tty output
   487                                  		; sys write; och; 1 / print it
   488 00000297 EBDE                    	jmp	short s4
   489                                  	;jmp	short error
   490                                  		; br error / continue to get characters
   491                                  s5: ;1:
   492                                  	;inc	esi
   493                                  		; inc r5 / inc r5 to point to return
   494                                  	;;and	si, 0FFFEh
   495                                  	;shr	esi, 1
   496                                  	;shl	esi, 1
   497                                  		; bic $1,r5 / make it even
   498                                  	sys	_seek, 0, 0, 2	
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000299 BB00000000          <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 0000029E B900000000          <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96 000002A3 BA02000000          <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 000002A8 B813000000          <1>  mov eax, %1
   101 000002AD CD30                <1>  int 30h
   499                                  		; clr r0 / set for input
   500                                  		; sys seek; 0; 2 / exit from runcom. skip to
   501                                  			       ; / end of input file
   502 000002AF C3                      	retn
   503                                  		;; rts r5 ; unix v2 shell ; 29/05/2022
   504                                  		;; (not in original unix v1 'sh.s')
   505                                  
   506                                  chcom: ; / has no effect if tty input
   507                                  		; mov (r5)+,r1 / glogin gchdir r1, bump r5
   508 000002B0 BF[B6060000]            	mov	edi, parbuf
   509                                  		; mov $parbuf,r2 / command address r2 'login'
   510                                  s6: ;1:
   511 000002B5 AC                      	lodsb
   512                                  		; movb (r1)+,r0 / is this command 'chdir'
   513 000002B6 AE                      	scasb
   514                                                  ; cmpb (r2)+,r0 / compare command name byte
   515                                                                ; / with 'login' or 'chdir'
   516 000002B7 7504                    	jne	short s7
   517                                  		; bne 1f / doesn't compare
   518 000002B9 08C0                    	or	al, al
   519                                  		; tst r0 / is this
   520 000002BB 75F8                    	jnz	short s6
   521                                  		; bne 1b / end of names
   522                                  		; tst (r5)+ / yes, bump r5 again to execute 
   523                                  			; / login or chdir
   524                                  s7: ;1:
   525 000002BD C3                      	retn
   526                                  		; rts r5 / no, return to exec command
   527                                  
   528                                  putc:
   529 000002BE 3C27                    	cmp	al, 27h ; '
   530                                  		; cmp r0,$'' / single quote?
   531 000002C0 740A                    	je	short pch1	
   532                                  		; beq 1f / yes
   533 000002C2 3C22                    	cmp	al, 22h ; "
   534                                  		; cmp r0,$'" / double quote
   535 000002C4 7406                    	je	short pch1
   536                                  		; beq 1f / yes
   537 000002C6 247F                    	and	al, 7Fh
   538                                  		; bic $!177,r0 / no, remove 200, if present
   539 000002C8 8806                    	mov	[esi], al
   540 000002CA 46                      	inc	esi
   541                                  		; movb r0,(r3)+ / store character in parbuf
   542 000002CB C3                      	retn
   543                                  		; rts pc
   544                                  pch1: ;1:
   545 000002CC 50                      	push	eax
   546                                  		; mov r0,-(sp) / push quote mark onto stack
   547                                  pch2: ;1:
   548 000002CD E8C9010000              	call	getc
   549                                  		; jsr pc,getc / get a quoted character
   550 000002D2 3C0D                    	cmp	al, 0Dh
   551                                  	;cmp	al, 0Ah ; \n
   552                                  		; cmp r0,$'\n / is it end or line
   553 000002D4 750F                    	jne	short pch3
   554                                  		; bne 2f / no
   555 000002D6 BE[57060000]            	mov	esi, msgImbalance
   556 000002DB E881FFFFFF              	call	error
   557                                  		; jsr r5,error / yes, indicate missing
   558                                  			      ; quote mark
   559                                  		;     <"' imbalance\n\0>; .even
   560 000002E0 E9A2FDFFFF                      jmp     newline
   561                                  		; jmp newline / ask for new line
   562                                  pch3: ;2:
   563 000002E5 380424                  	cmp	[esp], al
   564                                  		; cmp r0,(sp) / is this closing quote mark
   565 000002E8 7407                    	je	short pch4
   566                                  		; beq 1f / yes
   567 000002EA 247F                    	and	al, 7Fh
   568                                  		; bic $!177,r0 / no, strip off 200
   569                                  			      ; if present
   570 000002EC 8806                    	mov	[esi], al
   571 000002EE 46                      	inc	esi
   572                                  		; movb r0,(r3)+ / store quoted character
   573                                  			      ; in parbuf
   574 000002EF EBDC                    	jmp	short pch2
   575                                  		; br 1b / continue
   576                                  pch4: ;1:
   577 000002F1 58                      	pop	eax
   578                                  		; tst (sp)+ / pop quote mark off stack
   579 000002F2 C3                      	retn
   580                                  		; rts pc / return
   581                                  
   582                                  ; / thp`e new process
   583                                  
   584                                  newproc:
   585 000002F3 8B35[A40A0000]          	mov	esi, [infile]
   586 000002F9 09F6                    	or	esi, esi
   587 000002FB 7456                    	jz	short np2
   588                                  		; mov infile,0f / move pointer to new file name
   589                                  		; beq 1f / branch if no alternate read file given
   590 000002FD 803E00                  	cmp 	byte [esi], 0
   591                                  		; tstb *0f
   592 00000300 7640                    	jna	short np1
   593                                  		; beq 3f / branch if no file name given
   594                                  
   595                                  	; 17/06/2022 - Retro UNIX 386 v1.1
   596                                  	sys	_stat, esi, stbuf  ; get file (inode) status
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000302 89F3                <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 00000304 B9[880C0000]        <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000309 B812000000          <1>  mov eax, %1
   101 0000030E CD30                <1>  int 30h
   597 00000310 7230                    	jc	short np1
   598                                  	;
   599                                  	; (regular files, disk blocks may be used as input source)
   600                                  	; ((pseudo tty input redirection not allowed)) 
   601                                  	
   602 00000312 66A1[880C0000]          	mov	ax, [stbuf] ; inode number 
   603 00000318 6683F813                	cmp	ax, 19 ; > tty9 inode number (regular file) ?
   604 0000031C 7708                    	ja	short np13 ; yes
   605 0000031E 3C0A                    	cmp	al, 10 ; < tty0 ?
   606 00000320 7320                    	jnb	short np1 ; yes
   607 00000322 3C01                    	cmp	al, 1
   608 00000324 741C                    	je	short np1
   609                                  np13:
   610                                  	sys	_close, 0
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000326 BB00000000          <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 0000032B B806000000          <1>  mov eax, %1
   101 00000330 CD30                <1>  int 30h
   611                                  		; clr r0 / set tty input file name
   612                                  		; sys close / close it
   613                                  	sys	_open, esi, 0  
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000332 89F3                <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 00000334 B900000000          <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000339 B805000000          <1>  mov eax, %1
   101 0000033E CD30                <1>  int 30h
   614                                  		; sys open; 0:..; 0 / open new input file 
   615                                  				  ; for reading
   616 00000340 7311                    	jnc	short np2
   617                                  		; bcc 1f / branch if input file ok
   618                                  np1: ;3:
   619 00000342 BE[64060000]            	mov	esi, msgInputFile
   620 00000347 E815FFFFFF              	call	error
   621                                  		; jsr r5,error / file not ok, print error
   622                                  		;     <Input file\n\0>; .even / this diagnostic
   623                                  	sys	_exit
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91                              <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 0000034C B801000000          <1>  mov eax, %1
   101 00000351 CD30                <1>  int 30h
   624                                  		; sys exit / terminate this process 
   625                                  			  ; and make parent sh
   626                                  np2: ;1:
   627 00000353 8B35[A80A0000]          	mov	esi, [outfile]
   628                                  		; mov outfile,r2 / more pointer to new file name
   629 00000359 21F6                    	and	esi, esi
   630                                  	;jz	short np6
   631                                  		; beq 1f / branch if no alternate write file
   632                                  	; 17/06/2022
   633 0000035B 7505                    	jnz	short np11
   634 0000035D E9AB000000              	jmp	np6
   635                                  np11:
   636                                  	; 27/12/2015
   637 00000362 803E00                  	cmp	byte [esi], 0
   638 00000365 763D                    	jna	short np4
   639                                  	;
   640                                  	;cmp	byte [esi], '>'
   641                                  		; cmpb (r2),$'> / is > at beqinning of file name?
   642                                  	;jne	short np3
   643                                  		; bne 4f / branch if it isn't
   644                                  	;inc	esi
   645                                  		; inc r2 / yes, increment pointer
   646                                  	;
   647                                  	; 17/06/2022
   648                                  	;cmp	byte [FCAT], '>' ; '>>'
   649                                  	;jne	short np3
   650                                  
   651                                  	; 17/06/2022 - Retro UNIX 386 v1.1
   652                                  	sys	_stat, esi, stbuf  ; get file (inode) status
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000367 89F3                <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 00000369 B9[880C0000]        <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 0000036E B812000000          <1>  mov eax, %1
   101 00000373 CD30                <1>  int 30h
   653 00000375 7247                    	jc	short np3
   654                                  
   655                                  	; Block devices and dirs must not be target
   656 00000377 F605[8B0C0000]40        	test	byte [stbuf+stat.mode+1], 40h ; directory ?
   657 0000037E 7524                    	jnz	short np4 ; yes ; error
   658                                  	
   659 00000380 66A1[880C0000]          	mov	ax, [stbuf] ; inode number
   660 00000386 6683F829                	cmp	ax, 41 ; regular file ?
   661 0000038A 7729                    	ja	short np14 ; yes 
   662                                   
   663 0000038C 3C08                    	cmp	al, 8 ; > hd3 inode number ?
   664 0000038E 7704                    	ja	short np12 ; yes ; character device
   665                                  
   666 00000390 3C03                    	cmp	al, 3 ; >= fd0 inode number ?
   667 00000392 7310                    	jnb	short np4 ; yes ; output file error
   668                                  np12:
   669                                  	sys	_open, esi, 1
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000394 89F3                <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 00000396 B901000000          <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 0000039B B805000000          <1>  mov eax, %1
   101 000003A0 CD30                <1>  int 30h
   670                                  		; mov r2,0f
   671                                  		; sys open; 0:..; 1 / open file for writing
   672 000003A2 732A                    	jnc	short np5
   673                                  		; bec 3f / if no error
   674                                  np4: ;2:
   675 000003A4 BE[6F060000]            	mov	esi, msgOutputFile
   676 000003A9 E8B3FEFFFF              	call	error
   677                                  		; jsr r5,error
   678                                  		;     <Output file\n\0>; .even
   679                                  	sys	_exit
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91                              <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 000003AE B801000000          <1>  mov eax, %1
   101 000003B3 CD30                <1>  int 30h
   680                                  		; sys exit
   681                                  
   682                                  	;jmp	short np4
   683                                  
   684                                  	; 17/06/2022
   685                                  np14:
   686 000003B5 803D[86060000]3E        	cmp	byte [FCAT], '>' ; '>>' ?
   687 000003BC 74D6                    	je	short np12  ; no, '>'
   688                                  np3: ;4:
   689                                  	sys	_creat, esi, 15 ; Decimal 15 = Octal 17
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 000003BE 89F3                <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 000003C0 B90F000000          <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 000003C5 B808000000          <1>  mov eax, %1
   101 000003CA CD30                <1>  int 30h
   690                                  		; mov r2,0f
   691                                  		; sys creat; 0:..; 17 / create new file 
   692                                  				    ; with this name
   693                                  	;jnc	short np5
   694                                  		; bec 3f / branch if no error
   695                                  	; 17/06/2022
   696 000003CC 72D6                    	jc	short np4
   697                                  
   698                                  np5: ;3:
   699                                  	sys	_close, eax
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 000003CE 89C3                <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 000003D0 B806000000          <1>  mov eax, %1
   101 000003D5 CD30                <1>  int 30h
   700                                  		; sys close / close the new write file
   701                                  		; mov	r2,0f / move new name to open
   702                                  np10:
   703                                  	sys	_close, 1
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 000003D7 BB01000000          <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 000003DC B806000000          <1>  mov eax, %1
   101 000003E1 CD30                <1>  int 30h
   704                                  		; mov $1,r0 / set tty file name
   705                                  		; sys close / close it
   706                                  	sys	_open, esi, 1
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 000003E3 89F3                <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 000003E5 B901000000          <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 000003EA B805000000          <1>  mov eax, %1
   101 000003EF CD30                <1>  int 30h
   707                                  		; sys open; 0:..; 1 / open new output file,
   708                                  			      ; /it now has file descriptor 1
   709                                  	; 27/12/2015
   710 000003F1 803D[86060000]3E        	cmp	byte [FCAT], '>' ; '>>'
   711 000003F8 7513                    	jne	short np6
   712                                  	;
   713                                  	sys	_seek, eax, 0, 2
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 000003FA 89C3                <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 000003FC B900000000          <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96 00000401 BA02000000          <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000406 B813000000          <1>  mov eax, %1
   101 0000040B CD30                <1>  int 30h
   714                                  		; sys seek; 0; 2 / set pointer to 
   715                                  				; current end of file
   716                                  np6: ;1:
   717 0000040D 803D[A20A0000]00        	cmp	byte [glflag], 0
   718                                  		; tst glflag / was *, ? or [ encountered?
   719 00000414 7739                            ja      short np9
   720                                  		; bne 1f / yes
   721                                  	sys	_exec, parbuf, parp
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000416 BB[B6060000]        <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 0000041B B9[B00A0000]        <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000420 B80B000000          <1>  mov eax, %1
   101 00000425 CD30                <1>  int 30h
   722                                  		; sys exec; parbuf; parp / no, execute
   723                                  					;  this command
   724                                  	sys	_exec, binpb, parp
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000427 BB[B1060000]        <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 0000042C B9[B00A0000]        <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000431 B80B000000          <1>  mov eax, %1
   101 00000436 CD30                <1>  int 30h
   725                                  		; sys exec; binpb; parp / or /bin/this command
   726                                  
   727                                  ;------ 29/05/2022 - unix v2 shell
   728                                  ;	 (source code from disassembled /bin/sh binary)
   729                                  ;	following part is not existing in v2 shell
   730                                  ;
   731                                  ;np7: ;2:
   732                                  ;	sys	_stat, binpb, inbuf
   733                                  ;		; sys stat; binpb; inbuf / if can't execute
   734                                  ;					; / does it exist?
   735                                  ;	jc	short np8
   736                                  ;		; bes 2f / branch if it doesn't
   737                                  ;	mov	esi, parp-4
   738                                  ;	mov	dword [esi], shell
   739                                  ;		; mov $shell,parp-2 / does exist,
   740                                  ;				   ;  not executable
   741                                  ;	mov	eax, binpb
   742                                  ;	mov	[parp], eax
   743                                  ;		; mov $binpb,parp / so it must be
   744                                  ;	sys	_exec, shell, esi 
   745                                  ;		; sys exec; shell; parp-2 / a command file,
   746                                  ;		; / get it with sh /bin/x (if x name of file)
   747                                  ;------
   748                                  
   749                                  np8: ;2:
   750 00000438 BE[7B060000]            	mov	esi, msgNoCmd
   751 0000043D E81FFEFFFF              	call	error
   752                                  		; jsr r5,error / a return for exec 
   753                                  			       ; is the diagnostic
   754                                  		;     <No command\n\0>; .even
   755 00000442 8B25[820C0000]          	mov	esp, [shellarg]
   756                                  	sys 	_exit
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91                              <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000448 B801000000          <1>  mov eax, %1
   101 0000044D CD30                <1>  int 30h
   757                                  		; sys exit
   758                                  np9: ;1:
   759 0000044F BE[AC0A0000]            	mov	esi, parp-4
   760 00000454 C706[A7060000]          	mov	dword [esi], glob
   761                                  		; mov $glob,parp-2 / prepare to process *,?
   762                                  	sys	_exec, glob, esi
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 0000045A BB[A7060000]        <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 0000045F 89F1                <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000461 B80B000000          <1>  mov eax, %1
   101 00000466 CD30                <1>  int 30h
   763                                  		; sys exec; glob; parp-2
   764                                  			    ; / execute modified command
   765 00000468 EBCE                    	jmp	short np8
   766                                  		; br 2b
   767                                  
   768                                  delim:
   769 0000046A 3C0D                            cmp     al, 0Dh ; carriage return
   770 0000046C 741A                    	je	short dlim2
   771                                  	;cmp	al, 0Ah
   772                                  		; cmp r0,$'\n / is character a newline
   773                                  	;je	short dlim2
   774                                  		; beq 1f
   775 0000046E 3C26                    	cmp	al, '&'
   776                                  		;cmp r0,$'& / is it &
   777 00000470 7416                    	je	short dlim2
   778                                  		; beq 1f / yes
   779 00000472 3C3B                    	cmp	al, ';'
   780                                  		; cmp r0,$'; / is it ;
   781 00000474 7412                    	je	short dlim2
   782                                  		; beq 1f / yes
   783 00000476 3C3F                    	cmp	al, '?'
   784                                  		; cmp r0,$'? / is it ?
   785 00000478 7408                    	je	short dlim1
   786                                  		; beq 3f
   787                                  ;
   788                                  ;------ 29/05/2022 - unix v2 shell
   789                                  ;	 (source code from disassembled /bin/sh binary)
   790 0000047A 3C2A                    	cmp	al, '*'
   791                                  		; cmp r0,$'* / is it *
   792 0000047C 7404                    	je	short dlim1
   793                                  		; beq 3f
   794                                  
   795 0000047E 3C5B                    	cmp	al, '['
   796                                  		; cmp r0,$'[ / is it beginning of character string
   797                                  		      ; / (for glob)
   798 00000480 7506                    	jne	short dlim2
   799                                  		; bne 2f
   800                                  dlim1: ;3:
   801 00000482 FE05[A20A0000]          	inc	byte [glflag]
   802                                  		; inc glflag / ? or * or [ set flag
   803                                  ;2:
   804                                  	;tst	(r5)+ / bump to process all except \n,;,&
   805                                  dlim2: ;1:
   806                                  	; zf = 1 if the char is '\n' or ';' or '&'
   807 00000488 C3                      	retn
   808                                  		; rts r5
   809                                  blank:
   810 00000489 E80D000000              	call	getc
   811                                  		; jsr pc,getc / get next character
   812 0000048E 3C20                    	cmp	al, 20h
   813                                  		; cmp $' ,r0 / leading blanks
   814 00000490 74F7                    	je	short blank
   815                                  		; beq blank / yes, 'squeeze out'
   816 00000492 3C8D                    	cmp	al, 8Dh ; 80h + 0Dh
   817                                          ;cmp	al, 8Ah ; 80h + 0Ah
   818 00000494 74F3                    	je	short blank
   819                                  	        ; cmp r0,$200+'\n / new-line preceded by 				 ;  is translated
   821                                  		; beq blank / into blank
   822                                  	; 28/12/2015
   823 00000496 3C0A                    	cmp	al, 0Ah
   824 00000498 74EF                    	je	short blank
   825                                  	;
   826 0000049A C3                      	retn
   827                                  		; rts pc
   828                                  getc:
   829 0000049B 833D[9E0A0000]00        	cmp	dword [param], 0
   830                                  		; tst param / are we substituting for $n
   831 000004A2 773D                    	ja	short gch3
   832                                  		; bne 2f/ yes
   833                                  gch0:
   834 000004A4 8B1D[780C0000]                  mov     ebx, [inbufp]
   835                                  		; mov inbufp,r1 / no, move normal input pointer to r1
   836                                  s8:
   837 000004AA 3B1D[7C0C0000]          	cmp	ebx, [einbuf]
   838                                  		; cmp r1,einbuf / end of input line?
   839 000004B0 7207                    	jb	short gch1
   840                                  		; bne 1f / no
   841 000004B2 E877000000              	call	getbuf	
   842                                  		; jsr pc,getbuf / yes, put next console line
   843                                  				;  in buffer
   844 000004B7 EBEB                    	jmp	short gch0
   845                                  		; br getc
   846                                  gch1: ;1:
   847 000004B9 8A03                    	mov	al, [ebx]
   848 000004BB 43                      	inc	ebx
   849                                  		; movb (r1)+,r0 / move byte from input buffer to r0
   850 000004BC 891D[780C0000]          	mov	[inbufp], ebx
   851                                  		; mov r1,inbufp / increment routine
   852 000004C2 0A05[860C0000]          	or	al, [escap]
   853                                  	;or	ax, escap
   854                                  		; bis escap,r0 / if last character was \ this adds
   855                                  		        	; / 200 to current character
   856                                  	;mov	byte [escap], 0
   857                                  	;mov	word [escap], 0
   858                                  		; clr escap / clear, so escap normally zero
   859 000004C8 3C5C                    	cmp	al, '\'
   860                                  		; cmp r0,$'\\ / note that \\ is equal \ in as
   861 000004CA 740C                    	je	short gch2
   862                                  		; beq 1f
   863 000004CC C605[860C0000]00        	mov	byte [escap], 0
   864 000004D3 3C24                    	cmp	al, '$'
   865                                  		; cmp r0,$'$ / is it $
   866 000004D5 7429                    	je	short gch5
   867                                  		; beq 3f / yes
   868 000004D7 C3                      	retn
   869                                  		; rts pc / no
   870                                  gch2: ;1:
   871 000004D8 C605[860C0000]80                mov     byte [escap], 80h
   872                                  	;mov	word [escap], 128
   873                                  		; mov $200,escap / mark presence of \ in command line
   874 000004DF EBC9                    	jmp	short s8
   875                                  	;jmp	short gch0
   876                                  		; br getc / get next character
   877                                  gch3: ;2:
   878 000004E1 8B1D[9E0A0000]          	mov	ebx, [param]
   879 000004E7 8A03                    	mov	al, [ebx]
   880                                  		; movb *param,r0 / pick up substitution character
   881                                  				; / put in r0
   882 000004E9 08C0                    	or	al, al
   883 000004EB 7407                    	jz	short gch4
   884                                  		; beq 1f / if end of substitution arg, branch
   885 000004ED FF05[9E0A0000]          	inc	dword [param]
   886                                  		; inc param / if not end, set for next character
   887 000004F3 C3                      	retn
   888                                  		; rts pc / return as though character in ro is normal
   889                                  		       ; / input
   890                                  gch4: ;1:
   891 000004F4 C705[9E0A0000]0000-     	mov	dword [param], 0
   891 000004FC 0000               
   892                                  		; clr param / unset substitution pointer
   893 000004FE EBA4                    	jmp	short gch0
   894                                  		; br getc / get next char in normal input
   895                                  gch5: ;3:
   896 00000500 E89FFFFFFF              	call	gch0
   897                                  	;call	getc
   898                                  		; jsr pc,getc / get digit after $
   899 00000505 2C30                    	sub	al, '0'
   900                                  		; sub $'0,r0 / strip off zone bits
   901 00000507 3C09                    	cmp	al, 9
   902                                  		; cmp r0,$9. / compare with digit 9
   903 00000509 7602                    	jna	short gch6 
   904                                  		; blos 1f / less than or equal 9
   905 0000050B B009                    	mov	al, 9
   906                                  		; mov $9.,r0 / if larger than 9, force 9
   907                                  gch6: ;1:
   908 0000050D 8B1D[820C0000]          	mov	ebx, [shellarg]
   909                                  		; mov shellarg,r1 / get pointer to stack for
   910                                  		           ; / this call of shell
   911 00000513 0FB6C0                  	movzx 	eax, al	; al->eax
   912 00000516 FEC0                    	inc	al
   913                                  	;inc	eax
   914                                  		; inc r0 / digit +1
   915 00000518 3B03                    	cmp	eax, [ebx]
   916                                  		; cmp r0,(r1) / is it less than # of args 
   917                                  			      ;	in this call
   918 0000051A 7388                    	jnb	short gch0
   919                                  		; bge getc / no, ignore it. so this $n is not replaced
   920 0000051C C0E002                  	shl	al, 2 ; multiply by 4 (24/08/2015)
   921                                  	;shl	al, 1
   922                                  	;;shl	ax, 1
   923                                  		; asl r0 / yes, multiply by 2 (to skip words)
   924 0000051F 01C3                    	add	ebx, eax
   925                                  		; add r1,r0 / form pointer to arg pointer (-2)
   926 00000521 8B4304                  	mov	eax, [ebx+4]
   927 00000524 A3[9E0A0000]            	mov	[param], eax
   928                                  		; mov 2(r0),param / move arg pointer to param
   929 00000529 E96DFFFFFF                      jmp     getc
   930                                  		; br getc / go to get substitution arg for $n
   931                                  getbuf:
   932 0000052E B9[780B0000]            	mov	ecx, inbuf
   933                                  		; mov $inbuf,r0 / move input buffer address
   934 00000533 890D[780C0000]                  mov     [inbufp], ecx
   935                                  		; mov r0,inbufp / to input buffer pointer
   936 00000539 890D[7C0C0000]          	mov	[einbuf], ecx
   937                                  		; mov r0,einbuf / and initialize pointer to end of
   938                                  		         ; / character string
   939 0000053F 49                      	dec	ecx
   940                                  		; dec r0 / decrement pointer so can utilize normal
   941                                  		       ; / 100p starting at 1f
   942                                  		; mov r0,0f / initialize address for reading 1st char
   943 00000540 BA01000000              	mov	edx, 1
   944                                  gbuf0: ;1:
   945 00000545 41                      	inc	ecx
   946                                  		; inc 0f / this routine filles inbuf with line from
   947                                  		       ; / console - if there is cnc
   948 00000546 51                      	push	ecx
   949                                  	; edx = 1
   950                                  	sys	_read, 0, och
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 00000547 BB00000000          <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 0000054C B9[800C0000]        <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 00000551 B803000000          <1>  mov eax, %1
   101 00000556 CD30                <1>  int 30h
   951 00000558 59                      	pop	ecx
   952                                  	;xor	ebx, ebx ; 0
   953                                  	;sys	_read ; sys _read, ebx, ecx, edx ; ebx = 0, edx = 1
   954                                  		; sys read; 0:0; 1 / read next char into inbuf
   955 00000559 7254                            jc	short xit1 ; 29/05/2022
   956                                  		; bcs xit1 / error exit
   957 0000055B 21C0                    	and	eax, eax
   958                                  		; tst r0 / a zero input is end of file
   959 0000055D 7450                            jz	short xit1 ; 29/05/2022
   960                                  		; beq xit1 / exit
   961 0000055F FF05[7C0C0000]          	inc	dword [einbuf]  ; 08/04/2014 (24/08/2015, 32 bit)
   962 00000565 A0[800C0000]            	mov	al, [och]
   963 0000056A 803D[89060000]00        	cmp	byte [_at], 0
   964 00000571 7608                    	jna	short gbuf1
   965 00000573 3C08                    	cmp	al, 8 ; backspace
   966 00000575 746B                    	je	short gbuf3
   967 00000577 3C7F                    	cmp	al, 127 ; delete
   968 00000579 7460                    	je	short gbuf6 ; 06/12/2013
   969                                  gbuf1:
   970                                  	;mov	ebx, ecx
   971                                  	;inc	dword [einbuf]
   972                                  		; inc einbuf / eventually einbuf points to \n
   973                                  		       ; / (+1) of this line
   974 0000057B 81F9[780C0000]          	cmp	ecx, inbuf + 256
   975                                  		; cmp 0b,$inbuf+256. / have we exceeded 
   976                                  				   ; input buffer size
   977 00000581 732C                            jnb	short xit1 ; 29/05/2022
   978                                  		; bhis xit1 / if so, exit assume some sort of binary
   979                                  	; 08/04/2014
   980 00000583 3C0D                    	cmp	al, 0Dh
   981 00000585 752F                    	jne	short gbuf8
   982 00000587 8B1D[7C0C0000]          	mov	ebx, [einbuf]
   983 0000058D 4B                      	dec	ebx
   984 0000058E 8803                    	mov	[ebx], al
   985 00000590 C3                      	retn
   986                                  
   987                                  gbuf2:
   988                                  	 ; 28/12/2015
   989 00000591 803D[89060000]00        	cmp	byte [_at], 0
   990 00000598 76AB                    	jna	short gbuf0 ; 29/05/2022
   991                                  gbuf7:
   992 0000059A 51                      	push	ecx
   993                                  	;mov	[och], al
   994                                  	; edx = 1
   995                                  	sys	_write, 1, och
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91 0000059B BB01000000          <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93 000005A0 B9[800C0000]        <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 000005A5 B804000000          <1>  mov eax, %1
   101 000005AA CD30                <1>  int 30h
   996                                  	;sys	_write, 1, och, 1  ; echo (write char on tty)
   997 000005AC 59                      	pop	ecx
   998 000005AD EB96                    	jmp	short gbuf0 ; 29/05/2022
   999                                  
  1000                                  xit1:	; 29/05/2022
  1001                                  	sys	_exit
    87                              <1> 
    88                              <1> 
    89                              <1> 
    90                              <1>  %if %0 >= 2
    91                              <1>  mov ebx, %2
    92                              <1>  %if %0 >= 3
    93                              <1>  mov ecx, %3
    94                              <1> 
    95                              <1>  %if %0 >= 4
    96                              <1>  mov edx, %4
    97                              <1>  %endif
    98                              <1>  %endif
    99                              <1>  %endif
   100 000005AF B801000000          <1>  mov eax, %1
   101 000005B4 CD30                <1>  int 30h
  1002                                  		; sys exit
  1003                                  
  1004                                  gbuf8:
  1005 000005B6 89CB                    	mov	ebx, ecx
  1006 000005B8 8803                    	mov	[ebx], al
  1007                                  	;cmp	al, 0Ah ; \n
  1008                                  		; cmpb *0b,$'\n / end of line?
  1009                                  	;je	short gbuf5
  1010                                  	;jne	short gbuf1
  1011                                  		; bne 1b / no, go to get next char
  1012                                  	;cmp	al, 0Dh ; ENTER
  1013                                  	;je	short gbuf5
  1014 000005BA 803D[89060000]00        	cmp	byte [_at], 0 ; at > 0 --> tty input
  1015 000005C1 7682                    	jna	short gbuf0
  1016 000005C3 3C1B                    	cmp	al, 1Bh	; ESC
  1017 000005C5 75CA                    	jne	short gbuf2
  1018 000005C7 B8[780B0000]            	mov	eax, inbuf
  1019 000005CC A3[780C0000]            	mov	[inbufp], eax
  1020 000005D1 A3[7C0C0000]            	mov	[einbuf], eax
  1021 000005D6 E9B5FAFFFF                      jmp     nl  ; cancel current command, new line
  1022                                  
  1023                                  	; 29/05/2022
  1024                                  ;gbuf2:
  1025                                  ;	 ; 28/12/2015
  1026                                  ;	cmp	byte [_at], 0
  1027                                  ;	jna	gbuf0
  1028                                  ;gbuf7:
  1029                                  ;	push	ecx
  1030                                  ;	;mov	[och], al
  1031                                  ;	; edx = 1
  1032                                  ;	sys	_write, 1, och
  1033                                  ;	;sys	_write, 1, och, 1  ; echo (write char on tty)
  1034                                  ;	pop	ecx
  1035                                  ;	jmp	gbuf0
  1036                                  
  1037                                  gbuf6: ; DELETE key -> BACKSPACE key
  1038                                  	;mov 	al, 8
  1039 000005DB C605[800C0000]08        	mov	byte [och], 8 ; 06/12/2013
  1040                                  gbuf3:
  1041                                  	; 08/04/2014
  1042 000005E2 FF0D[7C0C0000]          	dec	dword [einbuf] ; (24/08/2015, 32 bit code)
  1043                                  	; 12/12/2013
  1044 000005E8 49                      	dec	ecx
  1045 000005E9 81F9[780B0000]          	cmp	ecx, inbuf
  1046 000005EF 7203                    	jb	short gbuf4
  1047 000005F1 49                      	dec 	ecx
  1048                                  	; 08/04/2014
  1049                                  	;jmp	short gbuf2
  1050 000005F2 EBA6                    	jmp 	short gbuf7
  1051                                  gbuf4:
  1052                                  	;mov 	al, 7
  1053 000005F4 C605[800C0000]07        	mov	byte [och], 07h ; beep
  1054                                  	; 08/04/2014
  1055                                  	;jmp	short gbuf2
  1056 000005FB EB9D                    	jmp 	short gbuf7
  1057                                  ;gbuf5:
  1058                                  ;	retn
  1059                                  		; rts pc / yes, return
  1060                                  
  1061                                  	; 29/05/2022
  1062                                  ;xit1:
  1063                                  ;	sys	_exit
  1064                                  ;		; sys exit
  1065                                  
  1066                                  ;-----------------------------------------------------------------
  1067                                  ;  data - initialized data
  1068                                  ;-----------------------------------------------------------------
  1069                                  
  1070                                  ;  /// Messages
  1071                                  
  1072 000005FD 0D0A                    msg_unix_sh:	db 0Dh, 0Ah
  1073 000005FF 526574726F20556E69-     		db 'Retro Unix 386 v1 - shell'
  1073 00000608 782033383620763120-
  1073 00000611 2D207368656C6C     
  1074                                  		;db 0Dh, 0Ah
  1075                                  msgsh_size equ  $ - msg_unix_sh
  1076                                  		;db 0
  1077 00000618 31372F30362F323032-     		db '17/06/2022'
  1077 00000621 32                 
  1078 00000622 0D0A00                  nextline:	db 0Dh, 0Ah, 0
  1079                                  ;Error messages:
  1080 00000625 496E707574206E6F74-     msgNotFound: 	db 'Input not found', 0
  1080 0000062E 20666F756E6400     
  1081 00000635 41726720636F756E74-     msgArgCount: 	db 'Arg count',  0
  1081 0000063E 00                 
  1082 0000063F 426164206469726563-     msgBadDir: 	db 'Bad directory', 0
  1082 00000648 746F727900         
  1083 0000064D 54727920616761696E-     msgTryAgain: 	db 'Try again', 0
  1083 00000656 00                 
  1084 00000657 222720696D62616C61-     msgImbalance:   db 22h, 27h, 20h, 'imbalance',  0
  1084 00000660 6E636500           
  1085 00000664 496E7075742066696C-     msgInputFile: 	db 'Input file', 0
  1085 0000066D 6500               
  1086 0000066F 4F7574707574206669-     msgOutputFile: 	db 'Output file', 0
  1086 00000678 6C6500             
  1087 0000067B 4E6F20636F6D6D616E-     msgNoCmd: 	db 'No command',  0
  1087 00000684 6400               
  1088                                  
  1089                                  ; /// Commands, files, parameters
  1090                                  
  1091                                  ; 27/12/2015
  1092                                  FCAT:	; '>>' 
  1093 00000686 00                      	db 0
  1094                                  
  1095                                  ;quest:
  1096                                  	;db '?', 0Dh, 0Ah
  1097                                  	;<?\n>
  1098                                  
  1099                                  prompt:
  1100 00000687 0D0A                    	db 0Dh, 0Ah
  1101                                  _at:
  1102 00000689 4020                    	db '@ '
  1103                                  	;<@ >
  1104                                  p_size  equ $ - prompt
  1105                                  
  1106 0000068B 6563686F00              qecho: 	db 'echo', 0
  1107                                  ;
  1108 00000690 636400                  qcd:	db 'cd', 0
  1109                                  ;
  1110                                  qchdir:
  1111 00000693 636864697200            	db 'chdir', 0
  1112                                  	;<chdir\0>
  1113                                  glogin:
  1114 00000699 6C6F67696E00            	db 'login', 0
  1115                                  	;<login\0>
  1116                                  shell:
  1117 0000069F 2F62696E2F736800        	db '/bin/sh', 0
  1118                                  	;</bin/sh\0>
  1119                                  glob:
  1120 000006A7 2F6574632F676C6F62-     	db '/etc/glob', 0
  1120 000006B0 00                 
  1121                                  	;</etc/glob\0>
  1122                                  binpb:
  1123 000006B1 2F62696E2F              	db '/bin/'
  1124                                  	;</bin/>
  1125                                  
  1126                                  ;-----------------------------------------------------------------
  1127                                  ;  bss - uninitialized data
  1128                                  ;-----------------------------------------------------------------
  1129                                  
  1130                                  bss_start:
  1131                                  
  1132                                  ABSOLUTE bss_start
  1133                                  
  1134                                  parbuf:
  1135 000006B6 <res 3E8h>                      resb 1000
  1136                                   	; .=.+1000.
  1137                                  alignb 2
  1138                                  	;.even
  1139                                  param:
  1140 00000A9E ????????                	resd 1
  1141                                  	;.=.+2
  1142                                  glflag:
  1143 00000AA2 ??                      	resb 1
  1144 00000AA3 ??                      	resb 1
  1145                                  	;.=.+2
  1146                                  infile:
  1147 00000AA4 ????????                	resd 1
  1148                                  	; .=.+2 
  1149                                  outfile:
  1150 00000AA8 ????????                	resd 1
  1151                                  	;.=.+2
  1152                                  ; parp-4
  1153 00000AAC ????????                	resd 1
  1154                                  	;.=.+2 / room for glob
  1155                                  parp:
  1156 00000AB0 <res C8h>                       resb 200
  1157                                  	;.=.+200.
  1158                                  inbuf:
  1159 00000B78 <res 100h>                      resb 256
  1160                                  	;.=.+256.
  1161                                  ;escap:
  1162                                  	;resw 1
  1163                                  	;.=.+2
  1164                                  inbufp:
  1165 00000C78 ????????                	resd 1
  1166                                  	;.=.+2
  1167                                  einbuf:
  1168 00000C7C ????????                	resd 1
  1169                                  	;.=.+2
  1170                                  och:
  1171 00000C80 ??                      	resb 1
  1172 00000C81 ??                      	resb 1
  1173                                  	;.=.+2
  1174                                  shellarg:
  1175 00000C82 ????????                	resd 1
  1176                                  	;.=.+2
  1177                                  escap:
  1178 00000C86 ??                      	resb 1
  1179                                  	;
  1180 00000C87 ??                      	resb 1
  1181                                  
  1182                                  stbuf:	; 17/06/2022 - Retro UNIX 386 v1.1
  1183 00000C88 <res 22h>               	resb 34	; sysstat output buffer
  1184                                  
  1185                                  bss_end:
  1186                                  
  1187                                  ; 29/05/2022
  1188                                  ;-----------------------------------------------------------------
  1189                                  ; Original UNIX v2 - shell - PDP-11 assembly source code (sh.s)
  1190                                  ;-----------------------------------------------------------------
  1191                                  ; UNIX V2 source code: see www.tuhs.org for details.
  1192                                  ;-----------------------------------------------------------------
  1193                                  ; /// Modified unix v1 shell (sh.s) source code by Erdogan Tan /// 
  1194                                  ;-----------------------------------------------------------------
  1195                                  ; s2.tar.gz - \bin\sh 
  1196                                  ;
  1197                                  ; Source code modified via disassembled unix v2 /bin/sh binary file
  1198                                  ; Dissasembler: Hex-Rays Interactive Disassembler (IDA)
  1199                                  ;
  1200                                  ;/ sh -- command interpreter
  1201                                  ;	mov	sp,r5
  1202                                  ;	mov	r5,shellarg / save orig sp in shellarg
  1203                                  ;	cmpb	*2(r5),$'- / was this sh called by init or login
  1204                                  ;	bne	2f / no
  1205                                  ;	sys	intr; 0 / yes, turn off interrupts
  1206                                  ;	sys	quit; 0
  1207                                  ;2:
  1208                                  ;	sys	getuid / who is user
  1209                                  ;	tst	r0 / is it superuser
  1210                                  ;	bne	2f / no
  1211                                  ;	movb	$'#,at / yes, set new prompt symbol
  1212                                  ;2:
  1213                                  ;	cmp	(r5),$1 / tty input?
  1214                                  ;	ble	newline / yes, call with '-(or with no command
  1215                                  ;		        / file name)
  1216                                  ;	clr	r0 / no, set ttv
  1217                                  ;	sys	close / close it
  1218                                  ;	mov	4(r5),0f / get new file name
  1219                                  ;	sys	open; 0:..; 0 / open it
  1220                                  ;	bec	1f / branch if no error
  1221                                  ;	jsr	r5,error / error in file name
  1222                                  ;		<Input not found\n\0>; .even
  1223                                  ;	sys	exit
  1224                                  ;1:
  1225                                  ;	clr	at / clear prompt character, if reading non-tty
  1226                                  ;		   / input file
  1227                                  ;newline:
  1228                                  ;	tst	at / is there a prompt symbol
  1229                                  ;	beq	newcom / no
  1230                                  ;	mov	$1,r0 / yes
  1231                                  ;	sys	write; at; 2. / print prompt
  1232                                  ;newcom:
  1233                                  ;	mov	shellarg,sp /
  1234                                  ;	mov	$parbuf,r3 / initialize command list area
  1235                                  ;	mov	$parp,r4 / initialize command list pointers
  1236                                  ;	clr	infile / initialize alternate input
  1237                                  ;	clr	outfile / initialize alternate output
  1238                                  ;	clr	glflag / initialize global flag
  1239                                  ;newarg:
  1240                                  ;	jsr	pc,blank / squeeze out leading blanks
  1241                                  ;	jsr	r5,delim / is new character a ; \n or &
  1242                                  ;		br 2f / yes
  1243                                  ;	mov	r3,-(sp) / no, push arg pointer onto stack
  1244                                  ;	cmp	r0,$'< / new input file?
  1245                                  ;	bne	1f / no
  1246                                  ;	mov	(sp),infile / yes, save arg pointer
  1247                                  ;	clr	(sp) / clear pointer
  1248                                  ;	br	3f
  1249                                  ;1:
  1250                                  ;	cmp	r0,$'> / new output file?
  1251                                  ;	bne	newchar / no
  1252                                  ;	mov	(sp),outfile / yes, save arg pointer
  1253                                  ;	clr	(sp) / clear pointer
  1254                                  ;	br	3f
  1255                                  ;newchar:
  1256                                  ;	cmp	$' ,r0 / is character a blank
  1257                                  ;	beq	1f / branch if it is (blank as arg separator)
  1258                                  ;	cmp	$'\n+200,r0 / treat \n preceded by ;	beq	1f / as blank
  1260                                  ;	jsr	pc,putc / put this character in parbuf list
  1261                                  ;3:
  1262                                  ;	jsr	pc,getc / get next character
  1263                                  ;	jsr	r5,delim / is char a ; \n or &,
  1264                                  ;		br 1f / yes
  1265                                  ;	br	newchar / no, start new character tests
  1266                                  ;1:
  1267                                  ;	clrb	(r3)+ / end name with \0 when read blank, or
  1268                                  ;		      / delim
  1269                                  ;	mov	(sp)+,(r4)+ / move arg ptr to parp location
  1270                                  ;	bne	1f / if (sp)=0, in file or out file points to arg
  1271                                  ;	tst	-(r4) / so ignore dummy (0), in pointer list
  1272                                  ;1:
  1273                                  ;	jsr	r5,delim / is char a ; \n or &.
  1274                                  ;		br 2f / yes
  1275                                  ;	br	newarg / no, start newarg processing
  1276                                  ;2:
  1277                                  ;	clr	(r4) / \n, &, or ; takes to here (end of arg list)
  1278                                  ;		     / after 'delim' call
  1279                                  ;	mov	r0,-(sp) / save delimiter in stack
  1280                                  ;	jsr	pc,docom / go to exec command in parbuf
  1281                                  ;	cmpb	(sp),$'& / get a new command without wait?
  1282                                  ;	beq	newcom / yes
  1283                                  ;	tst	r1 / was chdir just executed or line ended with
  1284                                  ;		   / ampersand?
  1285                                  ;	beq	2f / yes
  1286                                  ;1:
  1287                                  ;	sys	wait / no, wait for new process to terminate
  1288                                  ;		     / command executed)
  1289                                  ;	bcs	2f / no, children not previously waited for
  1290                                  ;	cmp	r0,r1 / is this my child
  1291                                  ;	bne	1b
  1292                                  ;2:
  1293                                  ;	cmp	(sp),$'\n / was delimiter a new line
  1294                                  ;	beq	newline / yes
  1295                                  ;	br	newcom / no, pick up next command
  1296                                  ;docom:
  1297                                  ;	sub	$parp,r4 / out arg count in r4
  1298                                  ;	bne	1f / any arguments?
  1299                                  ;	clr	r1 / no, line ended with ampersand
  1300                                  ;	rts	pc / return from call
  1301                                  ;1:
  1302                                  ;	jsr	r5,chcom; qchdir / is command chdir?
  1303                                  ;		br 2f / command not chdir
  1304                                  ;	cmp	r4,$4 / prepare to exec chdir, 4=arg count x 2
  1305                                  ;	beq	3f
  1306                                  ;	jsr	r5,error / go to print error
  1307                                  ;		<Arg count\n\0>; .even
  1308                                  ;	br	4f
  1309                                  ;3:
  1310                                  ;	mov	parp+2,0f / more directory name to sys coll
  1311                                  ;	sys	chdir; 0:0 / exec chdir
  1312                                  ;	bec	4f / no error exit
  1313                                  ;	jsr	r5,error / go to print error
  1314                                  ;		<Bad directory\n\0>; .even / this diagnostic
  1315                                  ;4:
  1316                                  ;	clr	r1 / set r1 to zero to dkip wait
  1317                                  ;	rts	pc / and return
  1318                                  ;2:
  1319                                  ;	jsr	r5,chcom; glogin / is command login?
  1320                                  ;		br 2f / not loqin, go to fork
  1321                                  ;	sys	exec; parbuf; parp / exec login
  1322                                  ;	sys	exec; binpb; parp / or /bin/login
  1323                                  ;2: / no error return??
  1324                                  ;	sys	fork / generate sh child process for command
  1325                                  ;		br newproc / exec command with new process
  1326                                  ;	bec	1f / no error exit, old orocess
  1327                                  ;	jsr	r5,error / go to print error
  1328                                  ;		<Try again\n\0>; .even / this diaonostic
  1329                                  ;	jmp	newline / and return for next try
  1330                                  ;1:
  1331                                  ;	mov	r0,r1 / save id of child sh
  1332                                  ;	rts	pc / return to "jsr pc, docom" call in parent sh
  1333                                  ;
  1334                                  ;error:
  1335                                  ;	movb	(r5)+,och / pick up diagnostic character
  1336                                  ;	beq	1f / 0 is end of line
  1337                                  ;	mov	$1,r0 / set for tty output
  1338                                  ;	sys	write; och; 1 / print it
  1339                                  ;	br	error / continue to get characters
  1340                                  ;1:
  1341                                  ;	inc	r5 / inc r5 to point to return
  1342                                  ;	bic	$1,r5 / make it even
  1343                                  ;	clr	r0 / set for input
  1344                                  ;	sys	seek; 0; 2 / exit from runcom. skip to end of
  1345                                  ;		           / input file
  1346                                  ;
  1347                                  ;/------ 29/05/2022 - unix v2 shell
  1348                                  ;/	 (source code from disassembled /bin/sh binary)
  1349                                  ;	rts	r5
  1350                                  ;
  1351                                  ;chcom: / has no effect if tty input
  1352                                  ;	mov	(r5)+,r1 / glogin gchdir r1, bump r5
  1353                                  ;	mov	$parbuf,r2 / command address  r2 'login'
  1354                                  ;1:
  1355                                  ;	movb	 (r1)+,r0 / is this command 'chdir'
  1356                                  ;	cmpb	(r2)+,r0 / compare command name byte with 'login'
  1357                                  ;		         / or 'chdir'
  1358                                  ;	bne	1f / doesn't compare
  1359                                  ;	tst	r0 / is this
  1360                                  ;	bne	1b / end of names
  1361                                  ;	tst	(r5)+ / yes, bump r5 again to execute login
  1362                                  ;		      / chdir
  1363                                  ;1:
  1364                                  ;	rts	r5 / no, return to exec command
  1365                                  ;
  1366                                  ;putc:
  1367                                  ;	cmp	r0,$'' / single quote?
  1368                                  ;	beq	1f / yes
  1369                                  ;	cmp	r0,$'" / double quote
  1370                                  ;	beq	1f / yes
  1371                                  ;	bic	$!177,r0 / no, remove 200, if present
  1372                                  ;	movb	r0,(r3)+ / store character in parbuf
  1373                                  ;	rts	pc
  1374                                  ;1:
  1375                                  ;	mov	r0,-(sp) / push quote mark onto stack
  1376                                  ;1:
  1377                                  ;	jsr	pc,getc / get a quoted character
  1378                                  ;	cmp	r0,$'\n / is it end or line
  1379                                  ;	bne	2f / no
  1380                                  ;	jsr	r5,error / yes, indicate missing quote mark
  1381                                  ;		<"' imbalance\n\0>; .even
  1382                                  ;	jmp	newline / ask for new line
  1383                                  ;2:
  1384                                  ;	cmp	r0,(sp) / is this closing quote mark
  1385                                  ;	beq	1f / yes
  1386                                  ;	bic	$!177,r0 / no, strip off 200 if present
  1387                                  ;	movb	r0,(r3)+ / store quoted character in parbuf
  1388                                  ;	br	1b / continue
  1389                                  ;1:
  1390                                  ;	tst	(sp)+ / pop quote mark off stack
  1391                                  ;	rts	pc / return
  1392                                  ;
  1393                                  ;/ thp`e new process
  1394                                  ;
  1395                                  ;newproc:
  1396                                  ;	mov	infile,0f / move pointer to new file name
  1397                                  ;	beq	1f / branch if no alternate read file given
  1398                                  ;	tstb	*0f
  1399                                  ;	beq	3f / branch if no file name miven
  1400                                  ;	clr	r0 / set tty input file name
  1401                                  ;	sys	close / close it
  1402                                  ;	sys	open; 0:..; 0 / open new input file for reading
  1403                                  ;	bcc	1f / branch if input file ok
  1404                                  ;3:
  1405                                  ;	jsr	r5,error / file not ok, print error
  1406                                  ;		<Input file\n\0>; .even / this diagnostic
  1407                                  ;	sys	exit / terminate this process and make parent sh
  1408                                  ;1:
  1409                                  ;	mov	outfile,r2 / more pointer to new file name
  1410                                  ;	beq	1f / branch if no alternate write file
  1411                                  ;	cmpb	(r2),$'> / is > at beqinning of file name?
  1412                                  ;	bne	4f / branch if it isn't
  1413                                  ;	inc	r2 / yes, increment pointer
  1414                                  ;	mov	r2,0f
  1415                                  ;	sys	open; 0:..; 1 / open file for writing
  1416                                  ;	bec	3f / if no error
  1417                                  ;4:
  1418                                  ;	mov	r2,0f
  1419                                  ;	sys	creat; 0:..; 17 / create new file with this name
  1420                                  ;	bec	3f / branch if no error
  1421                                  ;2:
  1422                                  ;	jsr	r5,error
  1423                                  ;		<Output file\n\0>; .even
  1424                                  ;	sys	exit
  1425                                  ;3:
  1426                                  ;	sys	close / close the new write file
  1427                                  ;	mov	r2,0f / move new name to open
  1428                                  ;	mov	$1,r0 / set ttv file name
  1429                                  ;	sys	close / close it
  1430                                  ;	sys	open; 0:..; 1 / open new output file, it now has
  1431                                  ;		              / file descriptor 1
  1432                                  ;	sys	seek; 0; 2 / set pointer to current end of file
  1433                                  ;1:
  1434                                  ;	tst	glflag / was *, ? or [ encountered?
  1435                                  ;	bne	1f / yes
  1436                                  ;	sys	exec; parbuf; parp / no, execute this commend
  1437                                  ;	sys	exec; binpb; parp / or /bin/this command
  1438                                  ;
  1439                                  ;/------ 29/05/2022 - unix v2 shell
  1440                                  ;/	 (source code from disassembled /bin/sh binary)
  1441                                  ;/	following part is not existing in v2 shell
  1442                                  ;
  1443                                  ;/2:
  1444                                  ;/	sys	stat; binpb; inbuf / if can't execute does it
  1445                                  ;/		                   / exist?
  1446                                  ;/	bes	2f / branch if it doesn't
  1447                                  ;/	mov	$shell,parp-2 / does exist, not executable
  1448                                  ;/	mov	$binpb,parp / so it must be
  1449                                  ;/	sys	exec; shell; parp-2 / a command file, get it with
  1450                                  ;/		                    / sh /bin/x (if x name of file)
  1451                                  ;/------
  1452                                  ;2:
  1453                                  ;	jsr	r5,error / a return for exec is the diagnostic
  1454                                  ;		<No command\n\0>; .even
  1455                                  ;	sys	exit
  1456                                  ;1:
  1457                                  ;	mov	$glob,parp-2 / prepare to process *,?
  1458                                  ;	sys	exec; glob; parp-2 / execute modified command
  1459                                  ;	br	2b
  1460                                  ;
  1461                                  ;delim:
  1462                                  ;	cmp	r0,$'\n / is character a newline
  1463                                  ;	beq	1f
  1464                                  ;	cmp	r0,$'& / is it &
  1465                                  ;	beq	1f / yes
  1466                                  ;	cmp	r0,$'; / is it ;
  1467                                  ;	beq	1f / yes
  1468                                  ;	cmp	r0,$'? / is it ?
  1469                                  ;	beq	3f
  1470                                  ;
  1471                                  ;/------ 29/05/2022 - unix v2 shell
  1472                                  ;/	 (source code from disassembled /bin/sh binary)
  1473                                  ;	cmp	r0,$'* / is it *
  1474                                  ;	beq	3f
  1475                                  ;
  1476                                  ;	cmp	r0,$'[ / is it beginning of character string
  1477                                  ;		       / (for glob)
  1478                                  ;	bne	2f
  1479                                  ;3:
  1480                                  ;	inc	glflag / ? or * or [ set flag
  1481                                  ;2:
  1482                                  ;	tst	(r5)+ / bump to process all except \n,;,&
  1483                                  ;1:
  1484                                  ;	rts	r5
  1485                                  ;
  1486                                  ;blank:
  1487                                  ;	jsr	pc,getc / get next character
  1488                                  ;	cmp	$' ,r0 / leading blanks
  1489                                  ;	beq	blank / yes, 'squeeze out'
  1490                                  ;	cmp	r0,$200+'\n / new-line preceded by \ is translated
  1491                                  ;	beq	blank / into blank
  1492                                  ;	rts	pc
  1493                                  ;getc:
  1494                                  ;	tst	param / are we substituting for $n
  1495                                  ;	bne	2f/ yes
  1496                                  ;	mov	inbufp,r1 / no, move normal input pointer to r1
  1497                                  ;	cmp	r1,einbuf / end of input line?
  1498                                  ;	bne	1f / no
  1499                                  ;	jsr	pc,getbuf / yes, put next console line in buffer
  1500                                  ;	br	getc
  1501                                  ;1:
  1502                                  ;	movb	(r1)+,r0 / move byte from input buffer to r0
  1503                                  ;	mov	r1,inbufp / increment routine
  1504                                  ;	bis	escap,r0 / if last character was \ this adds
  1505                                  ;		         / 200 to current character
  1506                                  ;	clr	escap / clear, so escap normally zero
  1507                                  ;	cmp	r0,$'\\ / note that \\ is equal \ in as
  1508                                  ;	beq	1f
  1509                                  ;	cmp	r0,$'$ / is it $
  1510                                  ;	beq	3f / yes
  1511                                  ;	rts	pc / no
  1512                                  ;1:
  1513                                  ;	mov	$200,escap / mark presence of \ in command line
  1514                                  ;	br	getc / get next character
  1515                                  ;2:
  1516                                  ;	movb	*param,r0 / pick up substitution character put in
  1517                                  ;		          / r0
  1518                                  ;	beq	1f / if end of substitution arg, branch
  1519                                  ;	inc	param / if not end, set for next character
  1520                                  ;	rts	pc / return as though character in ro is normal
  1521                                  ;		   / input
  1522                                  ;1:
  1523                                  ;	clr	param / unset substitution pointer
  1524                                  ;	br	getc / get next char in normal input
  1525                                  ;3:
  1526                                  ;	jsr	pc,getc / get digit after $
  1527                                  ;	sub	$'0,r0 / strip off zone bits
  1528                                  ;	cmp	r0,$9. / compare with digit 9 
  1529                                  ;	blos	1f / less than or equal 9
  1530                                  ;	mov	$9.,r0 / if larger than 9, force 9
  1531                                  ;1:
  1532                                  ;	mov	shellarg,r1 / get pointer to stack for
  1533                                  ;		            / this call of shell
  1534                                  ;	inc	r0 / digit +1
  1535                                  ;	cmp	r0,(r1) / is it less than # of args in this call
  1536                                  ;	bge	getc / no, ignore it. so this $n is not replaced
  1537                                  ;	asl	r0 / yes, multiply by 2 (to skip words)
  1538                                  ;	add	r1,r0 / form pointer to arg pointer (-2)
  1539                                  ;	mov	2(r0),param / move arg pointer to param
  1540                                  ;	br	getc / go to get substitution arg for $n
  1541                                  ;getbuf:
  1542                                  ;	mov	$inbuf,r0 / move input buffer address
  1543                                  ;	mov	r0,inbufp / to input buffer pointer
  1544                                  ;	mov	r0,einbuf / and initialize pointer to end of
  1545                                  ;		          / character string
  1546                                  ;	dec	r0 / decrement pointer so can utilize normal
  1547                                  ;		   / 100p starting at 1f
  1548                                  ;	mov	r0,0f / initialize address for reading 1st char
  1549                                  ;1:
  1550                                  ;	inc	0f / this routine filles inbuf with line from
  1551                                  ;		   / console - if there is cnc
  1552                                  ;	clr	r0 / set for tty input
  1553                                  ;	sys	read; 0:0; 1 / read next char into inbuf
  1554                                  ;	bcs	xit1 / error exit
  1555                                  ;	tst	r0 / a zero input is end of file
  1556                                  ;	beq	xit1 / exit
  1557                                  ;	inc	einbuf / eventually einbuf points to \n
  1558                                  ;		       / (+1) of this line
  1559                                  ;	cmp	0b,$inbuf+256. / have we exceeded input buffer size
  1560                                  ;	bhis	xit1 / if so, exit assume some sort of binary
  1561                                  ;	cmpb	*0b,$'\n / end of line?
  1562                                  ;	bne	1b / no, go to get next char
  1563                                  ;	rts	pc / yes, return
  1564                                  ;
  1565                                  ;xit1:
  1566                                  ;	sys	exit
  1567                                  ;
  1568                                  ;quest:
  1569                                  ;	<?\n>
  1570                                  ;
  1571                                  ;at:
  1572                                  ;	<@ >
  1573                                  ;
  1574                                  ;qchdir:
  1575                                  ;	<chdir\0>
  1576                                  ;glogin:
  1577                                  ;	<login\0>
  1578                                  ;shell:
  1579                                  ;	</bin/sh\0>
  1580                                  ;glob:
  1581                                  ;	</etc/glob\0>
  1582                                  ;binpb:
  1583                                  ;	</bin/>
  1584                                  ;parbuf: .=.+1000.
  1585                                  ;	.even
  1586                                  ;param:	.=.+2
  1587                                  ;glflag: .=.+2
  1588                                  ;infile: .=.+2 
  1589                                  ;outfile:.=.+2
  1590                                  ;	.=.+2 / room for glob
  1591                                  ;parp:	.=.+200.
  1592                                  ;inbuf:	.=.+256.
  1593                                  ;escap:	.=.+2
  1594                                  ;inbufp: .=.+2
  1595                                  ;einbuf: .=.+2
  1596                                  ;och:	.=.+2
  1597                                  ;shellarg:.=.+2
  1598                                  
  1599                                  ; 29/05/2022
  1600                                  ;-----------------------------------------------------------------
  1601                                  ; Original UNIX v1 - shell - PDP-11 assembly source code (sh.s)
  1602                                  ;-----------------------------------------------------------------
  1603                                  ; UNIX V1 source code: see www.tuhs.org for details.
  1604                                  ;-----------------------------------------------------------------
  1605                                  ; PreliminaryUnixImplementationDocument_Jun72.pdf - Section: E11
  1606                                  ;-----------------------------------------------------------------
  1607                                  ; https://minnie.tuhs.org/cgi-bin/utree.pl?file=V1/sh.s
  1608                                  ;
  1609                                  ;/ sh -- command interpreter
  1610                                  ;	mov	sp,r5
  1611                                  ;	mov	r5,shellarg / save orig sp in shellarg
  1612                                  ;	cmpb	*2(r5),$'- / was this sh called by init or login
  1613                                  ;	bne	2f / no
  1614                                  ;	sys	intr; 0 / yes, turn off interrupts
  1615                                  ;	sys	quit; 0
  1616                                  ;2:
  1617                                  ;	sys	getuid / who is user
  1618                                  ;	tst	r0 / is it superuser
  1619                                  ;	bne	2f / no
  1620                                  ;	movb	$'#,at / yes, set new prompt symbol
  1621                                  ;2:
  1622                                  ;	cmp	(r5),$1 / tty input?
  1623                                  ;	ble	newline / yes, call with '-(or with no command
  1624                                  ;		        / file name)
  1625                                  ;	clr	r0 / no, set ttv
  1626                                  ;	sys	close / close it
  1627                                  ;	mov	4(r5),0f / get new file name
  1628                                  ;	sys	open; 0:..; 0 / open it
  1629                                  ;	bec	1f / branch if no error
  1630                                  ;	jsr	r5,error / error in file name
  1631                                  ;		<Input not found\n\0>; .even
  1632                                  ;	sys	exit
  1633                                  ;1:
  1634                                  ;	clr	at / clear prompt character, if reading non-tty
  1635                                  ;		   / input file
  1636                                  ;newline:
  1637                                  ;	tst	at / is there a prompt symbol
  1638                                  ;	beq	newcom / no
  1639                                  ;	mov	$1,r0 / yes
  1640                                  ;	sys	write; at; 2. / print prompt
  1641                                  ;newcom:
  1642                                  ;	mov	shellarg,sp /
  1643                                  ;	mov	$parbuf,r3 / initialize command list area
  1644                                  ;	mov	$parp,r4 / initialize command list pointers
  1645                                  ;	clr	infile / initialize alternate input
  1646                                  ;	clr	outfile / initialize alternate output
  1647                                  ;	clr	glflag / initialize global flag
  1648                                  ;newarg:
  1649                                  ;	jsr	pc,blank / squeeze out leading blanks
  1650                                  ;	jsr	r5,delim / is new character a ; \n or &
  1651                                  ;		br 2f / yes
  1652                                  ;	mov	r3,-(sp) / no, push arg pointer onto stack
  1653                                  ;	cmp	r0,$'< / new input file?
  1654                                  ;	bne	1f / no
  1655                                  ;	mov	(sp),infile / yes, save arg pointer
  1656                                  ;	clr	(sp) / clear pointer
  1657                                  ;	br	3f
  1658                                  ;1:
  1659                                  ;	cmp	r0,$'> / new output file?
  1660                                  ;	bne	newchar / no
  1661                                  ;	mov	(sp),outfile / yes, save arg pointer
  1662                                  ;	clr	(sp) / clear pointer
  1663                                  ;	br	3f
  1664                                  ;newchar:
  1665                                  ;	cmp	$' ,r0 / is character a blank
  1666                                  ;	beq	1f / branch if it is (blank as arg separator)
  1667                                  ;	cmp	$'\n+200,r0 / treat \n preceded by ;	beq	1f / as blank
  1669                                  ;	jsr	pc,putc / put this character in parbuf list
  1670                                  ;3:
  1671                                  ;	jsr	pc,getc / get next character
  1672                                  ;	jsr	r5,delim / is char a ; \n or &,
  1673                                  ;		br 1f / yes
  1674                                  ;	br	newchar / no, start new character tests
  1675                                  ;1:
  1676                                  ;	clrb	(r3)+ / end name with \0 when read blank, or
  1677                                  ;		      / delim
  1678                                  ;	mov	(sp)+,(r4)+ / move arg ptr to parp location
  1679                                  ;	bne	1f / if (sp)=0, in file or out file points to arg
  1680                                  ;	tst	-(r4) / so ignore dummy (0), in pointer list
  1681                                  ;1:
  1682                                  ;	jsr	r5,delim / is char a ; \n or &.
  1683                                  ;		br 2f / yes
  1684                                  ;	br	newarg / no, start newarg processing
  1685                                  ;2:
  1686                                  ;	clr	(r4) / \n, &, or ; takes to here (end of arg list)
  1687                                  ;		     / after 'delim' call
  1688                                  ;	mov	r0,-(sp) / save delimiter in stack
  1689                                  ;	jsr	pc,docom / go to exec command in parbuf
  1690                                  ;	cmpb	(sp),$'& / get a new command without wait?
  1691                                  ;	beq	newcom / yes
  1692                                  ;	tst	r1 / was chdir just executed or line ended with
  1693                                  ;		   / ampersand?
  1694                                  ;	beq	2f / yes
  1695                                  ;1:
  1696                                  ;	sys	wait / no, wait for new process to terminate
  1697                                  ;		     / command executed)
  1698                                  ;	bcs	2f / no, children not previously waited for
  1699                                  ;	cmp	r0,r1 / is this my child
  1700                                  ;	bne	1b
  1701                                  ;2:
  1702                                  ;	cmp	(sp),$'\n / was delimiter a new line
  1703                                  ;	beq	newline / yes
  1704                                  ;	br	newcom / no, pick up next command
  1705                                  ;docom:
  1706                                  ;	sub	$parp,r4 / out arg count in r4
  1707                                  ;	bne	1f / any arguments?
  1708                                  ;	clr	r1 / no, line ended with ampersand
  1709                                  ;	rts	pc / return from call
  1710                                  ;1:
  1711                                  ;	jsr	r5,chcom; qchdir / is command chdir?
  1712                                  ;		br 2f / command not chdir
  1713                                  ;	cmp	r4,$4 / prepare to exec chdir, 4=arg count x 2
  1714                                  ;	beq	3f
  1715                                  ;	jsr	r5,error / go to print error
  1716                                  ;		<Arg count\n\0>; .even
  1717                                  ;	br	4f
  1718                                  ;3:
  1719                                  ;	mov	parp+2,0f / more directory name to sys coll
  1720                                  ;	sys	chdir; 0:0 / exec chdir
  1721                                  ;	bec	4f / no error exit
  1722                                  ;	jsr	r5,error / go to print error
  1723                                  ;		<Bad directory\n\0>; .even / this diagnostic
  1724                                  ;4:
  1725                                  ;	clr	r1 / set r1 to zero to dkip wait
  1726                                  ;	rts	pc / and return
  1727                                  ;2:
  1728                                  ;	jsr	r5,chcom; glogin / is command login?
  1729                                  ;		br 2f / not loqin, go to fork
  1730                                  ;	sys	exec; parbuf; parp / exec login
  1731                                  ;	sys	exec; binpb; parp / or /bin/login
  1732                                  ;2: / no error return??
  1733                                  ;	sys	fork / generate sh child process for command
  1734                                  ;		br newproc / exec command with new process
  1735                                  ;	bec	1f / no error exit, old orocess
  1736                                  ;	jsr	r5,error / go to print error
  1737                                  ;		<Try again\n\0>; .even / this diaonostic
  1738                                  ;	jmp	newline / and return for next try
  1739                                  ;1:
  1740                                  ;	mov	r0,r1 / save id of child sh
  1741                                  ;	rts	pc / return to "jsr pc, docom" call in parent sh
  1742                                  ;
  1743                                  ;error:
  1744                                  ;	movb	(r5)+,och / pick up diagnostic character
  1745                                  ;	beq	1f / 0 is end of line
  1746                                  ;	mov	$1,r0 / set for tty output
  1747                                  ;	sys	write; och; 1 / print it
  1748                                  ;	br	error / continue to get characters
  1749                                  ;1:
  1750                                  ;	inc	r5 / inc r5 to point to return
  1751                                  ;	bic	$1,r5 / make it even
  1752                                  ;	clr	r0 / set for input
  1753                                  ;	sys	seek; 0; 2 / exit from runcom. skip to end of
  1754                                  ;		           / input file
  1755                                  ;chcom: / has no effect if tty input
  1756                                  ;	mov	(r5)+,r1 / glogin gchdir r1, bump r5
  1757                                  ;	mov	$parbuf,r2 / command address  r2 'login'
  1758                                  ;1:
  1759                                  ;	movb	 (r1)+,r0 / is this command 'chdir'
  1760                                  ;	cmpb	(r2)+,r0 / compare command name byte with 'login'
  1761                                  ;		         / or 'chdir'
  1762                                  ;	bne	1f / doesn't compare
  1763                                  ;	tst	r0 / is this
  1764                                  ;	bne	1b / end of names
  1765                                  ;	tst	(r5)+ / yes, bump r5 again to execute login
  1766                                  ;		      / chdir
  1767                                  ;1:
  1768                                  ;	rts	r5 / no, return to exec command
  1769                                  ;
  1770                                  ;putc:
  1771                                  ;	cmp	r0,$'' / single quote?
  1772                                  ;	beq	1f / yes
  1773                                  ;	cmp	r0,$'" / double quote
  1774                                  ;	beq	1f / yes
  1775                                  ;	bic	$!177,r0 / no, remove 200, if present
  1776                                  ;	movb	r0,(r3)+ / store character in parbuf
  1777                                  ;	rts	pc
  1778                                  ;1:
  1779                                  ;	mov	r0,-(sp) / push quote mark onto stack
  1780                                  ;1:
  1781                                  ;	jsr	pc,getc / get a quoted character
  1782                                  ;	cmp	r0,$'\n / is it end or line
  1783                                  ;	bne	2f / no
  1784                                  ;	jsr	r5,error / yes, indicate missing quote mark
  1785                                  ;		<"' imbalance\n\0>; .even
  1786                                  ;	jmp	newline / ask for new line
  1787                                  ;2:
  1788                                  ;	cmp	r0,(sp) / is this closing quote mark
  1789                                  ;	beq	1f / yes
  1790                                  ;	bic	$!177,r0 / no, strip off 200 if present
  1791                                  ;	movb	r0,(r3)+ / store quoted character in parbuf
  1792                                  ;	br	1b / continue
  1793                                  ;1:
  1794                                  ;	tst	(sp)+ / pop quote mark off stack
  1795                                  ;	rts	pc / return
  1796                                  ;
  1797                                  ;/ thp`e new process
  1798                                  ;
  1799                                  ;newproc:
  1800                                  ;	mov	infile,0f / move pointer to new file name
  1801                                  ;	beq	1f / branch if no alternate read file given
  1802                                  ;	tstb	*0f
  1803                                  ;	beq	3f / branch if no file name miven
  1804                                  ;	clr	r0 / set tty input file name
  1805                                  ;	sys	close / close it
  1806                                  ;	sys	open; 0:..; 0 / open new input file for reading
  1807                                  ;	bcc	1f / branch if input file ok
  1808                                  ;3:
  1809                                  ;	jsr	r5,error / file not ok, print error
  1810                                  ;		<Input file\n\0>; .even / this diagnostic
  1811                                  ;	sys	exit / terminate this process and make parent sh
  1812                                  ;1:
  1813                                  ;	mov	outfile,r2 / more pointer to new file name
  1814                                  ;	beq	1f / branch if no alternate write file
  1815                                  ;	cmpb	(r2),$'> / is > at beqinning of file name?
  1816                                  ;	bne	4f / branch if it isn't
  1817                                  ;	inc	r2 / yes, increment pointer
  1818                                  ;	mov	r2,0f
  1819                                  ;	sys	open; 0:..; 1 / open file for writing
  1820                                  ;	bec	3f / if no error
  1821                                  ;4:
  1822                                  ;	mov	r2,0f
  1823                                  ;	sys	creat; 0:..; 17 / create new file with this name
  1824                                  ;	bec	3f / branch if no error
  1825                                  ;2:
  1826                                  ;	jsr	r5,error
  1827                                  ;		<Output file\n\0>; .even
  1828                                  ;	sys	exit
  1829                                  ;3:
  1830                                  ;	sys	close / close the new write file
  1831                                  ;	mov	r2,0f / move new name to open
  1832                                  ;	mov	$1,r0 / set ttv file name
  1833                                  ;	sys	close / close it
  1834                                  ;	sys	open; 0:..; 1 / open new output file, it now has
  1835                                  ;		              / file descriptor 1
  1836                                  ;	sys	seek; 0; 2 / set pointer to current end of file
  1837                                  ;1:
  1838                                  ;	tst	glflag / was *, ? or [ encountered?
  1839                                  ;	bne	1f / yes
  1840                                  ;	sys	exec; parbuf; parp / no, execute this commend
  1841                                  ;	sys	exec; binpb; parp / or /bin/this command
  1842                                  ;2:
  1843                                  ;	sys	stat; binpb; inbuf / if can't execute does it
  1844                                  ;		                   / exist?
  1845                                  ;	bes	2f / branch if it doesn't
  1846                                  ;	mov	$shell,parp-2 / does exist, not executable
  1847                                  ;	mov	$binpb,parp / so it must be
  1848                                  ;	sys	exec; shell; parp-2 / a command file, get it with
  1849                                  ;		                    / sh /bin/x (if x name of file)
  1850                                  ;2:
  1851                                  ;	jsr	r5,error / a return for exec is the diagnostic
  1852                                  ;		<No command\n\0>; .even
  1853                                  ;	sys	exit
  1854                                  ;1:
  1855                                  ;	mov	$glob,parp-2 / prepare to process *,?
  1856                                  ;	sys	exec; glob; parp-2 / execute modified command
  1857                                  ;	br	2b
  1858                                  ;
  1859                                  ;delim:
  1860                                  ;	cmp	r0,$'\n / is character a newline
  1861                                  ;	beq	1f
  1862                                  ;	cmp	r0,$'& / is it &
  1863                                  ;	beq	1f / yes
  1864                                  ;	cmp	r0,$'; / is it ;
  1865                                  ;	beq	1f / yes
  1866                                  ;	cmp	r0,$'? / is it ?
  1867                                  ;	beq	3f
  1868                                  ;	cmp	r0,$'[ / is it beginning of character string
  1869                                  ;		       / (for glob)
  1870                                  ;	bne	2f
  1871                                  ;3:
  1872                                  ;	inc	glflag / ? or * or [ set flag
  1873                                  ;2:
  1874                                  ;	tst	(r5)+ / bump to process all except \n,;,&
  1875                                  ;1:
  1876                                  ;	rts	r5
  1877                                  ;
  1878                                  ;blank:
  1879                                  ;	jsr	pc,getc / get next character
  1880                                  ;	cmp	$' ,r0 / leading blanks
  1881                                  ;	beq	blank / yes, 'squeeze out'
  1882                                  ;	cmp	r0,$200+'\n / new-line preceded by \ is translated
  1883                                  ;	beq	blank / into blank
  1884                                  ;	rts	pc
  1885                                  ;getc:
  1886                                  ;	tst	param / are we substituting for $n
  1887                                  ;	bne	2f/ yes
  1888                                  ;	mov	inbufp,r1 / no, move normal input pointer to r1
  1889                                  ;	cmp	r1,einbuf / end of input line?
  1890                                  ;	bne	1f / no
  1891                                  ;	jsr	pc,getbuf / yes, put next console line in buffer
  1892                                  ;	br	getc
  1893                                  ;1:
  1894                                  ;	movb	(r1)+,r0 / move byte from input buffer to r0
  1895                                  ;	mov	r1,inbufp / increment routine
  1896                                  ;	bis	escap,r0 / if last character was \ this adds
  1897                                  ;		         / 200 to current character
  1898                                  ;	clr	escap / clear, so escap normally zero
  1899                                  ;	cmp	r0,$'\\ / note that \\ is equal \ in as
  1900                                  ;	beq	1f
  1901                                  ;	cmp	r0,$'$ / is it $
  1902                                  ;	beq	3f / yes
  1903                                  ;	rts	pc / no
  1904                                  ;1:
  1905                                  ;	mov	$200,escap / mark presence of \ in command line
  1906                                  ;	br	getc / get next character
  1907                                  ;2:
  1908                                  ;	movb	*param,r0 / pick up substitution character put in
  1909                                  ;		          / r0
  1910                                  ;	beq	1f / if end of substitution arg, branch
  1911                                  ;	inc	param / if not end, set for next character
  1912                                  ;	rts	pc / return as though character in ro is normal
  1913                                  ;		   / input
  1914                                  ;1:
  1915                                  ;	clr	param / unset substitution pointer
  1916                                  ;	br	getc / get next char in normal input
  1917                                  ;3:
  1918                                  ;	jsr	pc,getc / get digit after $
  1919                                  ;	sub	$'0,r0 / strip off zone bits
  1920                                  ;	cmp	r0,$9. / compare with digit 9 
  1921                                  ;	blos	1f / less than or equal 9
  1922                                  ;	mov	$9.,r0 / if larger than 9, force 9
  1923                                  ;1:
  1924                                  ;	mov	shellarg,r1 / get pointer to stack for
  1925                                  ;		            / this call of shell
  1926                                  ;	inc	r0 / digit +1
  1927                                  ;	cmp	r0,(r1) / is it less than # of args in this call
  1928                                  ;	bge	getc / no, ignore it. so this $n is not replaced
  1929                                  ;	asl	r0 / yes, multiply by 2 (to skip words)
  1930                                  ;	add	r1,r0 / form pointer to arg pointer (-2)
  1931                                  ;	mov	2(r0),param / move arg pointer to param
  1932                                  ;	br	getc / go to get substitution arg for $n
  1933                                  ;getbuf:
  1934                                  ;	mov	$inbuf,r0 / move input buffer address
  1935                                  ;	mov	r0,inbufp / to input buffer pointer
  1936                                  ;	mov	r0,einbuf / and initialize pointer to end of
  1937                                  ;		          / character string
  1938                                  ;	dec	r0 / decrement pointer so can utilize normal
  1939                                  ;		   / 100p starting at 1f
  1940                                  ;	mov	r0,0f / initialize address for reading 1st char
  1941                                  ;1:
  1942                                  ;	inc	0f / this routine filles inbuf with line from
  1943                                  ;		   / console - if there is cnc
  1944                                  ;	clr	r0 / set for tty input
  1945                                  ;	sys	read; 0:0; 1 / read next char into inbuf
  1946                                  ;	bcs	xit1 / error exit
  1947                                  ;	tst	r0 / a zero input is end of file
  1948                                  ;	beq	xit1 / exit
  1949                                  ;	inc	einbuf / eventually einbuf points to \n
  1950                                  ;		       / (+1) of this line
  1951                                  ;	cmp	0b,$inbuf+256. / have we exceeded input buffer size
  1952                                  ;	bhis	xit1 / if so, exit assume some sort of binary
  1953                                  ;	cmpb	*0b,$'\n / end of line?
  1954                                  ;	bne	1b / no, go to get next char
  1955                                  ;	rts	pc / yes, return
  1956                                  ;
  1957                                  ;xit1:
  1958                                  ;	sys	exit
  1959                                  ;
  1960                                  ;quest:
  1961                                  ;	<?\n>
  1962                                  ;
  1963                                  ;at:
  1964                                  ;	<@ >
  1965                                  ;
  1966                                  ;qchdir:
  1967                                  ;	<chdir\0>
  1968                                  ;glogin:
  1969                                  ;	<login\0>
  1970                                  ;shell:
  1971                                  ;	</bin/sh\0>
  1972                                  ;glob:
  1973                                  ;	</etc/glob\0>
  1974                                  ;binpb:
  1975                                  ;	</bin/>
  1976                                  ;parbuf: .=.+1000.
  1977                                  ;	.even
  1978                                  ;param:	.=.+2
  1979                                  ;glflag: .=.+2
  1980                                  ;infile: .=.+2 
  1981                                  ;outfile:.=.+2
  1982                                  ;	.=.+2 / room for glob
  1983                                  ;parp:	.=.+200.
  1984                                  ;inbuf:	.=.+256.
  1985                                  ;escap:	.=.+2
  1986                                  ;inbufp: .=.+2
  1987                                  ;einbuf: .=.+2
  1988                                  ;och:	.=.+2
  1989                                  ;shellarg:.=.+2
