     1                                  ; ****************************************************************************
     2                                  ; sh386.s (sh1.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: 03/01/2016 ]
    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                                  ; sh1.s (27/12/2015, Retro UNIX 386 v1.1)
    24                                  ; sh0.s (24/08/2015, Retro UNIX 386 v1, NASM 2.11, 32 bit version of 'sh.asm')
    25                                  ; SHELL02.ASM, 13/11/2013 - 08/04/2014 (sh.asm, Retro UNIX 8086 v1, MASM 6.11) 
    26                                  
    27                                  ; 27/08/2015
    28                                  ; 24/08/2015
    29                                  ; 08/04/2014
    30                                  ; 13/11/2013
    31                                  
    32                                  ; UNIX v1 system calls
    33                                  _rele 	equ 0
    34                                  _exit 	equ 1
    35                                  _fork 	equ 2
    36                                  _read 	equ 3
    37                                  _write	equ 4
    38                                  _open	equ 5
    39                                  _close 	equ 6
    40                                  _wait 	equ 7
    41                                  _creat 	equ 8
    42                                  _link 	equ 9
    43                                  _unlink	equ 10
    44                                  _exec	equ 11
    45                                  _chdir	equ 12
    46                                  _time 	equ 13
    47                                  _mkdir 	equ 14
    48                                  _chmod	equ 15
    49                                  _chown	equ 16
    50                                  _break	equ 17
    51                                  _stat	equ 18
    52                                  _seek	equ 19
    53                                  _tell 	equ 20
    54                                  _mount	equ 21
    55                                  _umount	equ 22
    56                                  _setuid	equ 23
    57                                  _getuid	equ 24
    58                                  _stime	equ 25
    59                                  _quit	equ 26	
    60                                  _intr	equ 27
    61                                  _fstat	equ 28
    62                                  _emt 	equ 29
    63                                  _mdate 	equ 30
    64                                  _stty 	equ 31
    65                                  _gtty	equ 32
    66                                  _ilgins	equ 33
    67                                  _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
    68                                  _msg    equ 35 ; Retro UNIX 386 v1 feature only !
    69                                  
    70                                  %macro sys 1-4
    71                                      ; 03/09/2015	
    72                                      ; 13/04/2015
    73                                      ; Retro UNIX 386 v1 system call.		
    74                                      %if %0 >= 2   
    75                                          mov ebx, %2
    76                                          %if %0 >= 3    
    77                                              mov ecx, %3
    78                                              %if %0 = 4
    79                                                 mov edx, %4   
    80                                              %endif
    81                                          %endif
    82                                      %endif
    83                                      mov eax, %1
    84                                      int 30h	   
    85                                  %endmacro
    86                                  
    87                                  ; Retro UNIX 386 v1 system call format:
    88                                  ; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
    89                                  
    90                                  [BITS 32] ; We need 32-bit intructions for protected mode
    91                                  
    92                                  [ORG 0] 
    93                                  
    94                                  START_CODE:
    95                                  ;/ sh -- command interpreter
    96                                  	
    97                                  	;;27/12/2015
    98                                  	;;clear BSS
    99                                  	;mov	ecx, ((bss_end - bss_start) + 3) / 4
   100                                  	;sub	eax, eax
   101                                  	;mov	edi, bss_start
   102                                  	;rep	stosd
   103                                  s0:
   104 00000000 89E5                    	mov	ebp, esp
   105                                  		; mov sp,r5
   106 00000002 892D[720C0000]          	mov	[shellarg], ebp
   107                                  		; mov r5,shellarg / save orig sp in shellarg
   108 00000008 8B5D04                  	mov	ebx, [ebp+4]
   109 0000000B 803B2D                  	cmp	byte [ebx], '-'
   110                                  		 ; cmpb	*2(r5),$'- / was this sh called by init or loginx~
   111 0000000E 752E                    	jne	short s1
   112                                  		; bne 2f / no
   113                                  	sys	_intr, 0
   114                              <1> 
   115                              <1> 
   116                              <1> 
   117                              <1>  %if %0 >= 2
   118 00000010 BB00000000          <1>  mov ebx, %2
   119                              <1>  %if %0 >= 3
   120                              <1>  mov ecx, %3
   121                              <1>  %if %0 = 4
   122                              <1>  mov edx, %4
   123                              <1>  %endif
   124                              <1>  %endif
   125                              <1>  %endif
   126 00000015 B81B000000          <1>  mov eax, %1
   127 0000001A CD30                <1>  int 30h
   128                                  		; sys intr; 0 / yes, turn off interrupts
   129                                  	sys	_quit, 0
   130                              <1> 
   131                              <1> 
   132                              <1> 
   133                              <1>  %if %0 >= 2
   134 0000001C BB00000000          <1>  mov ebx, %2
   135                              <1>  %if %0 >= 3
   136                              <1>  mov ecx, %3
   137                              <1>  %if %0 = 4
   138                              <1>  mov edx, %4
   139                              <1>  %endif
   140                              <1>  %endif
   141                              <1>  %endif
   142 00000021 B81A000000          <1>  mov eax, %1
   143 00000026 CD30                <1>  int 30h
   144                                  		; sys quit; 0
   145                                  	sys	_write, 1, msg_unix_sh, msgsh_size
   146                              <1> 
   147                              <1> 
   148                              <1> 
   149                              <1>  %if %0 >= 2
   150 00000028 BB01000000          <1>  mov ebx, %2
   151                              <1>  %if %0 >= 3
   152 0000002D B9[EB050000]        <1>  mov ecx, %3
   153                              <1>  %if %0 = 4
   154 00000032 BA1D000000          <1>  mov edx, %4
   155                              <1>  %endif
   156                              <1>  %endif
   157                              <1>  %endif
   158 00000037 B804000000          <1>  mov eax, %1
   159 0000003C CD30                <1>  int 30h
   160                                  s1: ;2:
   161                                  	sys	_getuid
   162                              <1> 
   163                              <1> 
   164                              <1> 
   165                              <1>  %if %0 >= 2
   166                              <1>  mov ebx, %2
   167                              <1>  %if %0 >= 3
   168                              <1>  mov ecx, %3
   169                              <1>  %if %0 = 4
   170                              <1>  mov edx, %4
   171                              <1>  %endif
   172                              <1>  %endif
   173                              <1>  %endif
   174 0000003E B818000000          <1>  mov eax, %1
   175 00000043 CD30                <1>  int 30h
   176                                  		; sys	getuid / who is user
   177                                  	;and	eax, eax
   178 00000045 20C0                    	and	al, al
   179                                  		; tst r0 / is it superuser
   180 00000047 7507                    	jnz	short s2
   181                                  		; bne 2f / no
   182 00000049 C605[79060000]23        	mov	byte [_at], '#'
   183                                  		; movb $'#,at / yes, set new prompt symbol
   184                                  s2: ;2:
   185 00000050 837D0001                	cmp	dword [ebp], 1
   186                                  		; cmp (r5),$1 / tty input?
   187 00000054 7631                    	jna	short newline
   188                                  		; ble newline / yes, call with '-' (or with no command
   189                                  		      ; / file name)
   190 00000056 31DB                    	xor	ebx, ebx
   191                                  		; clr r0 / no, set tty
   192                                  	sys	_close
   193                              <1> 
   194                              <1> 
   195                              <1> 
   196                              <1>  %if %0 >= 2
   197                              <1>  mov ebx, %2
   198                              <1>  %if %0 >= 3
   199                              <1>  mov ecx, %3
   200                              <1>  %if %0 = 4
   201                              <1>  mov edx, %4
   202                              <1>  %endif
   203                              <1>  %endif
   204                              <1>  %endif
   205 00000058 B806000000          <1>  mov eax, %1
   206 0000005D CD30                <1>  int 30h
   207                                  		; sys close / close it
   208 0000005F 8B5D08                  	mov	ebx, [ebp+8] ; arg 1
   209                                  		; mov 4(r5),0f / get new file name
   210 00000062 31C9                    	xor	ecx, ecx ; arg 2
   211                                  	sys	_open
   212                              <1> 
   213                              <1> 
   214                              <1> 
   215                              <1>  %if %0 >= 2
   216                              <1>  mov ebx, %2
   217                              <1>  %if %0 >= 3
   218                              <1>  mov ecx, %3
   219                              <1>  %if %0 = 4
   220                              <1>  mov edx, %4
   221                              <1>  %endif
   222                              <1>  %endif
   223                              <1>  %endif
   224 00000064 B805000000          <1>  mov eax, %1
   225 00000069 CD30                <1>  int 30h
   226                                  		; sys open; 0:..; 0 / open it
   227 0000006B 7311                    	jnc	short s3
   228                                  		; bec 1f / branch if no error
   229 0000006D BE[15060000]            	mov	esi, msgNotFound
   230 00000072 E8ED010000              	call	error
   231                                  		; jsr r5,error / error in file name
   232                                  		; <Input not found\n\0>; .even
   233                                  	sys	_exit
   234                              <1> 
   235                              <1> 
   236                              <1> 
   237                              <1>  %if %0 >= 2
   238                              <1>  mov ebx, %2
   239                              <1>  %if %0 >= 3
   240                              <1>  mov ecx, %3
   241                              <1>  %if %0 = 4
   242                              <1>  mov edx, %4
   243                              <1>  %endif
   244                              <1>  %endif
   245                              <1>  %endif
   246 00000077 B801000000          <1>  mov eax, %1
   247 0000007C CD30                <1>  int 30h
   248                                  		; sys exit
   249                                  s3: ;1:
   250 0000007E C605[79060000]00        	mov	byte [_at], 0
   251                                  		; clr at / clear prompt character, if reading non-tty
   252                                  		   ; / input file
   253 00000085 EB1F                    	jmp	short newcom
   254                                  newline:
   255 00000087 803D[79060000]00        	cmp	byte [_at], 0
   256                                  		; tst at / is there a prompt symbol
   257 0000008E 7616                    	jna	short newcom
   258                                  		; beq newcom / no
   259                                  		; mov $1,r0 / yes
   260                                  nl:
   261                                  	sys	_write, 1, prompt, p_size
   262                              <1> 
   263                              <1> 
   264                              <1> 
   265                              <1>  %if %0 >= 2
   266 00000090 BB01000000          <1>  mov ebx, %2
   267                              <1>  %if %0 >= 3
   268 00000095 B9[77060000]        <1>  mov ecx, %3
   269                              <1>  %if %0 = 4
   270 0000009A BA04000000          <1>  mov edx, %4
   271                              <1>  %endif
   272                              <1>  %endif
   273                              <1>  %endif
   274 0000009F B804000000          <1>  mov eax, %1
   275 000000A4 CD30                <1>  int 30h
   276                                  	;sys	_write, 1, _at, 2
   277                                  		; sys write; at; 2. / print prompt
   278                                  newcom:
   279 000000A6 8B25[720C0000]          	mov	esp, [shellarg]
   280                                  		; mov shellarg,sp /
   281 000000AC BE[A6060000]            	mov	esi, parbuf 
   282                                  		; mov $parbuf,r3 / initialize command list area
   283 000000B1 BF[A00A0000]            	mov	edi, parp
   284                                  		; mov $parp,r4 / initialize command list pointers
   285 000000B6 31C0                    	xor	eax, eax
   286 000000B8 A3[940A0000]            	mov	[infile], eax ; 0	
   287                                  		; clr infile / initialize alternate input
   288 000000BD A3[980A0000]            	mov	[outfile], eax ; 0
   289                                  		; clr outfile / initialize alternate output
   290 000000C2 A2[920A0000]            	mov	[glflag], al ; 0
   291                                  	;mov	[glflag], ax ; 0
   292                                  		; clr glflag / initialize global flag
   293                                  	; 27/12/2015
   294 000000C7 A2[76060000]            	mov	[FCAT], al ; 0
   295                                  newarg:
   296 000000CC E897030000              	call	blank
   297                                  		; jsr pc,blank / squeeze out leading blanks
   298 000000D1 E877030000              	call	delim
   299 000000D6 7467                    	je	short nch4 ; '\n', ';', '&'
   300                                  		; jsr r5,delim / is new character a ; \n or &
   301                                  		;     br 2f / yes
   302 000000D8 56                      	push	esi
   303                                  		; mov r3,-(sp) / no, push arg pointer onto stack
   304 000000D9 3C3C                    	cmp	al, '<'
   305                                  		; cmp r0,$'< / new input file?
   306 000000DB 7508                    	jne	short na1
   307                                  		; bne 1f / no
   308 000000DD 8935[940A0000]          	mov	[infile], esi
   309                                  		; mov (sp),infile / yes, save arg pointer
   310                                  	;jmp 	short na4
   311 000000E3 EB1E                    	jmp	short na3
   312                                  	;mov	dword [esp], 0
   313                                  		; clr (sp) / clear pointer
   314                                  	;jmp	short nch1
   315                                  		; br 3f
   316                                  na1: ;1:
   317 000000E5 3C3E                    	cmp	al, '>'
   318                                  		; cmp r0,$'> / new output file?
   319 000000E7 7530                    	jne	short nch0
   320                                  	;jne	short newchar
   321                                  		; bne newchar / no
   322 000000E9 8935[980A0000]          	mov	[outfile], esi
   323                                  		; mov (sp),outfile / yes, save arg pointer
   324                                  	; 27/12/2015
   325 000000EF E886030000              	call	getc
   326 000000F4 3C3E                    	cmp	al, '>'
   327 000000F6 7507                    	jne	short na2
   328                                  	;
   329 000000F8 A2[76060000]            	mov	[FCAT], al ; '>>'
   330 000000FD EB04                    	jmp	short na3
   331                                  na2:
   332 000000FF 3C20                    	cmp	al, 20h ; ' '
   333 00000101 7505                    	jne	short na4
   334                                  na3:
   335 00000103 E860030000              	call	blank
   336                                  na4:	
   337 00000108 C7042400000000          	mov	dword [esp], 0
   338                                  		; clr (sp) / clear pointer
   339                                  	;jmp	short nch1
   340                                  		; br 3f
   341 0000010F EB12                    	jmp	short nch7
   342                                  newchar:
   343 00000111 3C20                    	cmp	al, 20h
   344                                  		; cmp $' ,r0 / is character a blank
   345 00000113 7415                    	je	short nch2
   346                                  		; beq 1f / branch if it is (blank as arg separator)
   347 00000115 3C8D                            cmp     al, 8Dh ; 128 + 13
   348 00000117 7411                    	je	short nch2
   349                                  		; cmp $'\n+200,r0 / treat \n preceded by 		; beq 1f / as blank
   350                                  nch0:
   351 00000119 E8A3010000              	call	putc
   352                                  		; jsr pc,putc / put this character in parbuf list
   353                                  nch1: ;3:
   354 0000011E E857030000              	call	getc
   355                                  		; jsr pc,getc / get next character
   356                                  nch7:
   357 00000123 E825030000              	call	delim
   358 00000128 75E7                    	jne	short newchar
   359                                  	;jz	short nch2 ; '\n', ';', '&'
   360                                  		; jsr	r5,delim / is char a ; \n or &,
   361                                  		;	br 1f / yes
   362                                  	;jmp	short newchar
   363                                  		; br newchar / no, start new character tests
   364                                  nch2: ;1:
   365 0000012A C60600                  	mov	byte [esi], 0
   366 0000012D 46                      	inc	esi
   367                                  		; clrb (r3)+ / end name with \0 when read blank, 
   368                                  			  ; or delim
   369 0000012E 5B                      	pop	ebx
   370 0000012F 891F                    	mov	[edi], ebx
   371                                  		; mov (sp)+,(r4)+ / move arg ptr to parp location
   372 00000131 09DB                    	or	ebx, ebx
   373 00000133 7403                    	jz	short nch3
   374                                  	;jnz	short nch3
   375                                  		; bne 1f / if (sp)=0, in file or out file points
   376                                  				; to arg
   377 00000135 83C704                  	add	edi, 4
   378                                  		; tst -(r4) / so ignore dummy (0), in pointer list
   379                                  nch3: ;1:
   380 00000138 E810030000              	call	delim
   381 0000013D 758D                    	jne	short newarg
   382                                  	;jz	short nch4 ; '\n', ';', '&'
   383                                  		; jsr r5,delim / is char a ; \n or &.
   384                                  		;     br 2f / yes
   385                                  	;jmp	short newarg
   386                                  		; br newarg / no, start newarg processing
   387                                  nch4: ;2:
   388 0000013F C70700000000            	mov	dword [edi], 0
   389                                  		; clr (r4) / \n, &, or ; takes to here 
   390                                  			 ; / (end of arg list) after 'delim' call
   391 00000145 50                      	push	eax
   392                                  		; mov r0,-(sp) / save delimiter in stack
   393 00000146 E82A000000              	call	docom
   394                                  		; jsr pc,docom / go to exec command in parbuf
   395 0000014B 803C2426                	cmp	byte [esp], '&'
   396                                  		; cmpb (sp),$'& / get a new command without wait?
   397 0000014F 0F8451FFFFFF                    je      newcom
   398                                  		; beq newcom / yes
   399 00000155 21D2                    	and	edx, edx
   400                                  		; tst r1 / was chdir just executed or line ended
   401                                  			; / with ampersand?
   402 00000157 740D                    	jz	short nch6
   403                                  		; beq 2f / yes
   404                                  nch5: ;1:
   405                                  	sys	_wait
   406                              <1> 
   407                              <1> 
   408                              <1> 
   409                              <1>  %if %0 >= 2
   410                              <1>  mov ebx, %2
   411                              <1>  %if %0 >= 3
   412                              <1>  mov ecx, %3
   413                              <1>  %if %0 = 4
   414                              <1>  mov edx, %4
   415                              <1>  %endif
   416                              <1>  %endif
   417                              <1>  %endif
   418 00000159 B807000000          <1>  mov eax, %1
   419 0000015E CD30                <1>  int 30h
   420                                  		; sys wait / no, wait for new process to terminate
   421                                                          ; / command executed)
   422 00000160 7204                    	jc	short nch6
   423                                  		; bcs 2f / no, children not previously waited for
   424 00000162 39D0                    	cmp	eax, edx
   425                                  		; cmp r0,r1 / is this my child
   426 00000164 75F3                    	jne	short nch5
   427                                  		; bne 1b
   428                                  nch6: ;2:
   429 00000166 803C240D                	cmp	byte [esp], 0Dh
   430                                  	;cmp	byte [esp], 0Ah
   431                                  		; cmp (sp),$'\n / was delimiter a new line
   432 0000016A 0F8417FFFFFF                    je      newline
   433                                  		; beq newline / yes
   434 00000170 E931FFFFFF                      jmp     newcom
   435                                  		; br newcom / no, pick up next command
   436                                  docom:
   437 00000175 81EF[A00A0000]          	sub	edi, parp
   438                                  		; sub $parp,r4 / out arg count in r4
   439 0000017B 7503                    	jne	short dcom1
   440                                  		; bne 1f / any arguments?
   441                                  dcom0:
   442 0000017D 29D2                    	sub 	edx, edx ; 0
   443                                  		; clr r1 / no, line ended with ampersand
   444 0000017F C3                      	retn
   445                                  		; rts pc / return from call
   446                                  dcom1: ;1:
   447 00000180 89FB                    	mov	ebx, edi
   448                                  	; 06/12/2013
   449 00000182 BE[7B060000]            	mov	esi, qecho 
   450 00000187 E827010000              	call	chcom
   451 0000018C 7543                    	jnz	short dcom7
   452                                  	; 28/12/2015
   453 0000018E 89DD                    	mov	ebp, ebx
   454 00000190 BF[A00A0000]            	mov	edi, parp
   455                                  dcom9:  ; CRLF
   456                                  	sys	_write, 1, nextline, 2
   457                              <1> 
   458                              <1> 
   459                              <1> 
   460                              <1>  %if %0 >= 2
   461 00000195 BB01000000          <1>  mov ebx, %2
   462                              <1>  %if %0 >= 3
   463 0000019A B9[12060000]        <1>  mov ecx, %3
   464                              <1>  %if %0 = 4
   465 0000019F BA02000000          <1>  mov edx, %4
   466                              <1>  %endif
   467                              <1>  %endif
   468                              <1>  %endif
   469 000001A4 B804000000          <1>  mov eax, %1
   470 000001A9 CD30                <1>  int 30h
   471                                  	;
   472 000001AB 83ED04                  	sub	ebp, 4 ; remain arg count x 4
   473 000001AE 76CD                    	jna	short dcom0
   474 000001B0 83C704                  	add	edi, 4
   475 000001B3 8B37                    	mov	esi, [edi]
   476                                  	;or 	esi, esi
   477                                  	;jz	short dcom0
   478 000001B5 89F2                    	mov	edx, esi ; string address
   479                                  dcom10:
   480 000001B7 AC                      	lodsb
   481 000001B8 08C0                    	or 	al, al
   482 000001BA 75FB                    	jnz	short dcom10
   483 000001BC 87D6                    	xchg 	edx, esi
   484 000001BE 29F2                    	sub	edx, esi  ; byte count
   485 000001C0 4A                      	dec	edx
   486                                  	;jz	short dcom0
   487                                  	; write string
   488                                  	sys	_write, 1, esi ; edx = byte count
   489                              <1> 
   490                              <1> 
   491                              <1> 
   492                              <1>  %if %0 >= 2
   493 000001C1 BB01000000          <1>  mov ebx, %2
   494                              <1>  %if %0 >= 3
   495 000001C6 89F1                <1>  mov ecx, %3
   496                              <1>  %if %0 = 4
   497                              <1>  mov edx, %4
   498                              <1>  %endif
   499                              <1>  %endif
   500                              <1>  %endif
   501 000001C8 B804000000          <1>  mov eax, %1
   502 000001CD CD30                <1>  int 30h
   503 000001CF EBC4                    	jmp	short dcom9
   504                                  dcom7:
   505 000001D1 BE[83060000]            	mov	esi, qchdir
   506 000001D6 E8D8000000              	call	chcom
   507 000001DB 752D                    	jnz	short dcom4
   508                                  		; jsr r5,chcom; qchdir / is command chdir?
   509                                  		;     br 2f / command not chdir
   510                                  dcom12:
   511 000001DD 80FB08                  	cmp	bl, 8 ; 8 = arg count x 4 (24/08/2015)
   512                                  	;cmp	bx, 8
   513                                  		; cmp r4,$4 / prepare to exec chdir, 
   514                                  			  ; 4 = arg count x 2
   515 000001E0 740C                    	je	short dcom2
   516                                  		; beq 3f
   517                                  dcom8:
   518 000001E2 BE[25060000]            	mov	esi, msgArgCount
   519 000001E7 E878000000              	call	error
   520                                  		; jsr r5,error / go to print error
   521                                  		;  	<Arg count\n\0>; .even
   522                                  	;jmp	short dcom3
   523                                  		; br 4f
   524 000001EC EB8F                    	jmp	short dcom0
   525                                  dcom2: ;3:
   526 000001EE 8B1D[A40A0000]          	mov	ebx, [parp+4]
   527                                  		;mov parp+2,0f / move directory name to sys call
   528                                  	sys	_chdir
   529                              <1> 
   530                              <1> 
   531                              <1> 
   532                              <1>  %if %0 >= 2
   533                              <1>  mov ebx, %2
   534                              <1>  %if %0 >= 3
   535                              <1>  mov ecx, %3
   536                              <1>  %if %0 = 4
   537                              <1>  mov edx, %4
   538                              <1>  %endif
   539                              <1>  %endif
   540                              <1>  %endif
   541 000001F4 B80C000000          <1>  mov eax, %1
   542 000001F9 CD30                <1>  int 30h
   543                                  		; sys chdir; 0:0 / exec chdir
   544 000001FB 730A                    	jnc	short dcom3
   545                                  		; bec 4f / no error exit
   546 000001FD BE[2F060000]            	mov	esi, msgBadDir
   547 00000202 E85D000000              	call	error
   548                                  		; jsr r5,error / go to print error
   549                                  		; 	<Bad directory\n\0>; .even
   550                                  				; / this diagnostic
   551                                  dcom3: ;4:
   552 00000207 31D2                    	xor	edx, edx ; 0
   553                                  		; clr r1 / set r1 to zero to skip wait
   554 00000209 C3                      	retn
   555                                  		; rts pc / and return
   556                                  dcom4: ;2:
   557                                  	; 06/12/2013
   558 0000020A BE[80060000]            	mov	esi, qcd
   559 0000020F E89F000000              	call	chcom
   560 00000214 74C7                    	jz	short dcom12
   561                                  dcom11:
   562 00000216 BE[89060000]            	mov	esi, glogin
   563 0000021B E893000000              	call	chcom
   564 00000220 7522                    	jnz	short dcom5
   565                                  		; jsr r5,chcom; glogin / is command login?
   566                                  		;     br 2f / not loqin, go to fork
   567                                  	sys	_exec, parbuf, parp
   568                              <1> 
   569                              <1> 
   570                              <1> 
   571                              <1>  %if %0 >= 2
   572 00000222 BB[A6060000]        <1>  mov ebx, %2
   573                              <1>  %if %0 >= 3
   574 00000227 B9[A00A0000]        <1>  mov ecx, %3
   575                              <1>  %if %0 = 4
   576                              <1>  mov edx, %4
   577                              <1>  %endif
   578                              <1>  %endif
   579                              <1>  %endif
   580 0000022C B80B000000          <1>  mov eax, %1
   581 00000231 CD30                <1>  int 30h
   582                                  		; sys exec; parbuf; parp / exec login
   583                                  	sys	_exec, binpb, parp
   584                              <1> 
   585                              <1> 
   586                              <1> 
   587                              <1>  %if %0 >= 2
   588 00000233 BB[A1060000]        <1>  mov ebx, %2
   589                              <1>  %if %0 >= 3
   590 00000238 B9[A00A0000]        <1>  mov ecx, %3
   591                              <1>  %if %0 = 4
   592                              <1>  mov edx, %4
   593                              <1>  %endif
   594                              <1>  %endif
   595                              <1>  %endif
   596 0000023D B80B000000          <1>  mov eax, %1
   597 00000242 CD30                <1>  int 30h
   598                                  		; sys exec; binpb; parp / or /bin/login
   599                                  dcom5: ;2: / no error return??
   600 00000244 BB[F6020000]            	mov	ebx, newproc
   601                                  	; child process will return to 'newproc' address
   602                                  	sys	_fork
   603                              <1> 
   604                              <1> 
   605                              <1> 
   606                              <1>  %if %0 >= 2
   607                              <1>  mov ebx, %2
   608                              <1>  %if %0 >= 3
   609                              <1>  mov ecx, %3
   610                              <1>  %if %0 = 4
   611                              <1>  mov edx, %4
   612                              <1>  %endif
   613                              <1>  %endif
   614                              <1>  %endif
   615 00000249 B802000000          <1>  mov eax, %1
   616 0000024E CD30                <1>  int 30h
   617                                  		; sys fork / generate sh child process
   618                                  			 ; for command
   619                                                  ;     br newproc / exec command with 
   620                                  			 ; new process
   621                                  	; parent process will return here
   622 00000250 730F                    	jnc	short dcom6
   623                                  		; bec 1f / no error exit, old process
   624 00000252 BE[3D060000]            	mov	esi, msgTryAgain
   625 00000257 E808000000              	call	error
   626                                  		; jsr r5,error / go to print error
   627                                  		;     <Try again\n\0>; .even / this diagnostic
   628 0000025C E926FEFFFF                      jmp     newline
   629                                  		; jmp newline / and return for next try
   630                                  dcom6: ;1:
   631 00000261 89C2                    	mov	edx, eax ; child process ID
   632                                  		; mov r0,r1 / save id of child sh
   633 00000263 C3                      	retn
   634                                  		; rts pc / return to "jsr pc, docom" call
   635                                  			; in parent sh
   636                                  error:
   637                                  	sys	_write, 1, nextline, 2
   638                              <1> 
   639                              <1> 
   640                              <1> 
   641                              <1>  %if %0 >= 2
   642 00000264 BB01000000          <1>  mov ebx, %2
   643                              <1>  %if %0 >= 3
   644 00000269 B9[12060000]        <1>  mov ecx, %3
   645                              <1>  %if %0 = 4
   646 0000026E BA02000000          <1>  mov edx, %4
   647                              <1>  %endif
   648                              <1>  %endif
   649                              <1>  %endif
   650 00000273 B804000000          <1>  mov eax, %1
   651 00000278 CD30                <1>  int 30h
   652                                  s4:
   653 0000027A AC                      	lodsb
   654 0000027B A2[700C0000]            	mov	[och], al
   655                                                  ; movb (r5)+,och / pick up diagnostic character
   656 00000280 20C0                    	and	al, al
   657 00000282 7418                    	jz	short s5
   658                                  		; beq 1f / 0 is end of line
   659                                  	sys	_write, 1, och, 1
   660                              <1> 
   661                              <1> 
   662                              <1> 
   663                              <1>  %if %0 >= 2
   664 00000284 BB01000000          <1>  mov ebx, %2
   665                              <1>  %if %0 >= 3
   666 00000289 B9[700C0000]        <1>  mov ecx, %3
   667                              <1>  %if %0 = 4
   668 0000028E BA01000000          <1>  mov edx, %4
   669                              <1>  %endif
   670                              <1>  %endif
   671                              <1>  %endif
   672 00000293 B804000000          <1>  mov eax, %1
   673 00000298 CD30                <1>  int 30h
   674                                  		; mov $1,r0 / set for tty output
   675                                  		; sys write; och; 1 / print it
   676 0000029A EBDE                    	jmp	short s4
   677                                  	;jmp	short error
   678                                  		; br error / continue to get characters
   679                                  s5: ;1:
   680                                  	;inc	esi
   681                                  		; inc r5 / inc r5 to point to return
   682                                  	;;and	si, 0FFFEh
   683                                  	;shr	esi, 1
   684                                  	;shl	esi, 1
   685                                  		; bic $1,r5 / make it even
   686                                  	sys	_seek, 0, 0, 2	
   687                              <1> 
   688                              <1> 
   689                              <1> 
   690                              <1>  %if %0 >= 2
   691 0000029C BB00000000          <1>  mov ebx, %2
   692                              <1>  %if %0 >= 3
   693 000002A1 B900000000          <1>  mov ecx, %3
   694                              <1>  %if %0 = 4
   695 000002A6 BA02000000          <1>  mov edx, %4
   696                              <1>  %endif
   697                              <1>  %endif
   698                              <1>  %endif
   699 000002AB B813000000          <1>  mov eax, %1
   700 000002B0 CD30                <1>  int 30h
   701                                  		; clr r0 / set for input
   702                                  		; sys seek; 0; 2 / exit from runcom. skip to
   703                                  			       ; / end of input file
   704 000002B2 C3                      	retn
   705                                  		;; ((/ rts r5)) 
   706                                  		;; (not in original unix v1 'sh.s')
   707                                  
   708                                  chcom: ; / has no effect if tty input
   709                                  		; mov (r5)+,r1 / glogin gchdir r1, bump r5
   710 000002B3 BF[A6060000]            	mov	edi, parbuf
   711                                  		; mov $parbuf,r2 / command address  r2 'login'
   712                                  s6: ;1:
   713 000002B8 AC                      	lodsb
   714                                  		; movb (r1)+,r0 / is this command 'chdir'
   715 000002B9 AE                      	scasb
   716                                                  ; cmpb (r2)+,r0 / compare command name byte
   717                                                                ; / with 'login' or 'chdir'
   718 000002BA 7504                    	jne	short s7
   719                                  		; bne 1f / doesn't compare
   720 000002BC 08C0                    	or	al, al
   721                                  		; tst r0 / is this
   722 000002BE 75F8                    	jnz	short s6
   723                                  		; bne 1b / end of names
   724                                  		; tst (r5)+ / yes, bump r5 again to execute 
   725                                  			; / login or chdir
   726                                  s7: ;1:
   727 000002C0 C3                      	retn
   728                                  		; rts r5 / no, return to exec command
   729                                  
   730                                  putc:
   731 000002C1 3C27                    	cmp	al, 27h ; '
   732                                  		; cmp r0,$'' / single quote?
   733 000002C3 740A                    	je	short pch1	
   734                                  		; beq 1f / yes
   735 000002C5 3C22                    	cmp	al, 22h ; "
   736                                  		; cmp r0,$'" / double quote
   737 000002C7 7406                    	je	short pch1
   738                                  		; beq 1f / yes
   739 000002C9 247F                    	and	al, 7Fh
   740                                  		; bic $!177,r0 / no, remove 200, if present
   741 000002CB 8806                    	mov	[esi], al
   742 000002CD 46                      	inc	esi
   743                                  		; movb r0,(r3)+ / store character in parbuf
   744 000002CE C3                      	retn
   745                                  		; rts pc
   746                                  pch1: ;1:
   747 000002CF 50                      	push	eax
   748                                  		; mov r0,-(sp) / push quote mark onto stack
   749                                  pch2: ;1:
   750 000002D0 E8A5010000              	call	getc
   751                                  		; jsr pc,getc / get a quoted character
   752 000002D5 3C0D                    	cmp	al, 0Dh
   753                                  	;cmp	al, 0Ah ; \n
   754                                  		; cmp r0,$'\n / is it end or line
   755 000002D7 750F                    	jne	short pch3
   756                                  		; bne 2f / no
   757 000002D9 BE[47060000]            	mov	esi, msgImbalance
   758 000002DE E881FFFFFF              	call	error
   759                                  		; jsr r5,error / yes, indicate missing
   760                                  			      ; quote mark
   761                                  		;     <"' imbalance\n\0>; .even
   762 000002E3 E99FFDFFFF                      jmp     newline
   763                                  		; jmp newline / ask for new line
   764                                  pch3: ;2:
   765 000002E8 380424                  	cmp	[esp], al
   766                                  		; cmp r0,(sp) / is this closing quote mark
   767 000002EB 7407                    	je	short pch4
   768                                  		; beq 1f / yes
   769 000002ED 247F                    	and	al, 7Fh
   770                                  		; bic $!177,r0 / no, strip off 200
   771                                  			      ; if present
   772 000002EF 8806                    	mov	[esi], al
   773 000002F1 46                      	inc	esi
   774                                  		; movb r0,(r3)+ / store quoted character
   775                                  			      ; in parbuf
   776 000002F2 EBDC                    	jmp	short pch2
   777                                  		; br 1b / continue
   778                                  pch4: ;1:
   779 000002F4 58                      	pop	eax
   780                                  		; tst (sp)+ / pop quote mark off stack
   781 000002F5 C3                      	retn
   782                                  		; rts pc / return
   783                                  
   784                                  ; / thp`e new process
   785                                  
   786                                  newproc:
   787 000002F6 8B35[940A0000]          	mov	esi, [infile]
   788 000002FC 09F6                    	or	esi, esi
   789 000002FE 7432                    	jz	short np2
   790                                  		; mov infile,0f / move pointer to new file name
   791                                  		; beq 1f / branch if no alternate read file given
   792 00000300 803E00                  	cmp 	byte [esi], 0
   793                                  		; tstb *0f
   794 00000303 761C                    	jna	short np1
   795                                  		; beq 3f / branch if no file name given
   796                                  	sys	_close, 0
   797                              <1> 
   798                              <1> 
   799                              <1> 
   800                              <1>  %if %0 >= 2
   801 00000305 BB00000000          <1>  mov ebx, %2
   802                              <1>  %if %0 >= 3
   803                              <1>  mov ecx, %3
   804                              <1>  %if %0 = 4
   805                              <1>  mov edx, %4
   806                              <1>  %endif
   807                              <1>  %endif
   808                              <1>  %endif
   809 0000030A B806000000          <1>  mov eax, %1
   810 0000030F CD30                <1>  int 30h
   811                                  		; clr r0 / set tty input file name
   812                                  		; sys close / close it
   813                                  	sys	_open, esi, 0  
   814                              <1> 
   815                              <1> 
   816                              <1> 
   817                              <1>  %if %0 >= 2
   818 00000311 89F3                <1>  mov ebx, %2
   819                              <1>  %if %0 >= 3
   820 00000313 B900000000          <1>  mov ecx, %3
   821                              <1>  %if %0 = 4
   822                              <1>  mov edx, %4
   823                              <1>  %endif
   824                              <1>  %endif
   825                              <1>  %endif
   826 00000318 B805000000          <1>  mov eax, %1
   827 0000031D CD30                <1>  int 30h
   828                                  		; sys open; 0:..; 0 / open new input file 
   829                                  				  ; for reading
   830 0000031F 7311                    	jnc	short np2
   831                                  		; bcc 1f / branch if input file ok
   832                                  np1: ;3:
   833 00000321 BE[54060000]            	mov	esi, msgInputFile
   834 00000326 E839FFFFFF              	call	error
   835                                  		; jsr r5,error / file not ok, print error
   836                                  		;     <Input file\n\0>; .even / this diagnostic
   837                                  	sys	_exit
   838                              <1> 
   839                              <1> 
   840                              <1> 
   841                              <1>  %if %0 >= 2
   842                              <1>  mov ebx, %2
   843                              <1>  %if %0 >= 3
   844                              <1>  mov ecx, %3
   845                              <1>  %if %0 = 4
   846                              <1>  mov edx, %4
   847                              <1>  %endif
   848                              <1>  %endif
   849                              <1>  %endif
   850 0000032B B801000000          <1>  mov eax, %1
   851 00000330 CD30                <1>  int 30h
   852                                  		; sys exit / terminate this process 
   853                                  			  ; and make parent sh
   854                                  np2: ;1:
   855 00000332 8B35[980A0000]          	mov	esi, [outfile]
   856                                  		; mov outfile,r2 / more pointer to new file name
   857 00000338 21F6                    	and	esi, esi
   858 0000033A 747E                    	jz	short np6
   859                                  		; beq 1f / branch if no alternate write file
   860                                  	; 27/12/2015
   861 0000033C 803E00                  	cmp	byte [esi], 0
   862 0000033F 7629                    	jna	short np4
   863                                  	;
   864                                  	;cmp	byte [esi], '>'
   865                                  		; cmpb (r2),$'> / is > at beqinning of file name?
   866                                  	;jne	short np3
   867                                  		; bne 4f / branch if it isn't
   868                                  	;inc	esi
   869                                  		; inc r2 / yes, increment pointer
   870                                  	; 27/12/2015
   871 00000341 803D[76060000]3E        	cmp	byte [FCAT], '>' ; '>>'
   872 00000348 7510                    	jne	short np3
   873                                  	;
   874                                  	sys	_open, esi, 1
   875                              <1> 
   876                              <1> 
   877                              <1> 
   878                              <1>  %if %0 >= 2
   879 0000034A 89F3                <1>  mov ebx, %2
   880                              <1>  %if %0 >= 3
   881 0000034C B901000000          <1>  mov ecx, %3
   882                              <1>  %if %0 = 4
   883                              <1>  mov edx, %4
   884                              <1>  %endif
   885                              <1>  %endif
   886                              <1>  %endif
   887 00000351 B805000000          <1>  mov eax, %1
   888 00000356 CD30                <1>  int 30h
   889                                  		; mov r2,0f
   890                                  		; sys open; 0:..; 1 / open file for writing
   891 00000358 7321                    	jnc	short np5
   892                                  		; bec 3f / if no error
   893                                  np3: ;4:
   894                                  	sys	_creat, esi, 15 ; Decimal 15 = Octal 17
   895                              <1> 
   896                              <1> 
   897                              <1> 
   898                              <1>  %if %0 >= 2
   899 0000035A 89F3                <1>  mov ebx, %2
   900                              <1>  %if %0 >= 3
   901 0000035C B90F000000          <1>  mov ecx, %3
   902                              <1>  %if %0 = 4
   903                              <1>  mov edx, %4
   904                              <1>  %endif
   905                              <1>  %endif
   906                              <1>  %endif
   907 00000361 B808000000          <1>  mov eax, %1
   908 00000366 CD30                <1>  int 30h
   909                                  		; mov r2,0f
   910                                  		; sys creat; 0:..; 17 / create new file 
   911                                  				    ; with this name
   912 00000368 7311                    	jnc	short np5
   913                                  		; bec 3f / branch if no error
   914                                  np4: ;2:
   915 0000036A BE[5F060000]            	mov	esi, msgOutputFile
   916 0000036F E8F0FEFFFF              	call	error
   917                                  		; jsr r5,error
   918                                  		;     <Output file\n\0>; .even
   919                                  	sys	_exit
   920                              <1> 
   921                              <1> 
   922                              <1> 
   923                              <1>  %if %0 >= 2
   924                              <1>  mov ebx, %2
   925                              <1>  %if %0 >= 3
   926                              <1>  mov ecx, %3
   927                              <1>  %if %0 = 4
   928                              <1>  mov edx, %4
   929                              <1>  %endif
   930                              <1>  %endif
   931                              <1>  %endif
   932 00000374 B801000000          <1>  mov eax, %1
   933 00000379 CD30                <1>  int 30h
   934                                  		; sys exit
   935                                  np5: ;3:
   936                                  	sys	_close, eax
   937                              <1> 
   938                              <1> 
   939                              <1> 
   940                              <1>  %if %0 >= 2
   941 0000037B 89C3                <1>  mov ebx, %2
   942                              <1>  %if %0 >= 3
   943                              <1>  mov ecx, %3
   944                              <1>  %if %0 = 4
   945                              <1>  mov edx, %4
   946                              <1>  %endif
   947                              <1>  %endif
   948                              <1>  %endif
   949 0000037D B806000000          <1>  mov eax, %1
   950 00000382 CD30                <1>  int 30h
   951                                  		; sys close / close the new write file
   952                                  		; mov	r2,0f / move new name to open
   953                                  np10:
   954                                  	sys	_close, 1
   955                              <1> 
   956                              <1> 
   957                              <1> 
   958                              <1>  %if %0 >= 2
   959 00000384 BB01000000          <1>  mov ebx, %2
   960                              <1>  %if %0 >= 3
   961                              <1>  mov ecx, %3
   962                              <1>  %if %0 = 4
   963                              <1>  mov edx, %4
   964                              <1>  %endif
   965                              <1>  %endif
   966                              <1>  %endif
   967 00000389 B806000000          <1>  mov eax, %1
   968 0000038E CD30                <1>  int 30h
   969                                  		; mov $1,r0 / set tty file name
   970                                  		; sys close / close it
   971                                  	sys	_open, esi, 1
   972                              <1> 
   973                              <1> 
   974                              <1> 
   975                              <1>  %if %0 >= 2
   976 00000390 89F3                <1>  mov ebx, %2
   977                              <1>  %if %0 >= 3
   978 00000392 B901000000          <1>  mov ecx, %3
   979                              <1>  %if %0 = 4
   980                              <1>  mov edx, %4
   981                              <1>  %endif
   982                              <1>  %endif
   983                              <1>  %endif
   984 00000397 B805000000          <1>  mov eax, %1
   985 0000039C CD30                <1>  int 30h
   986                                  		; sys open; 0:..; 1 / open new output file,
   987                                  			      ; /it now has file descriptor 1
   988                                  	; 27/12/2015
   989 0000039E 803D[76060000]3E        	cmp	byte [FCAT], '>' ; '>>'
   990 000003A5 7513                    	jne	short np6
   991                                  	;
   992                                  	sys	_seek, eax, 0, 2
   993                              <1> 
   994                              <1> 
   995                              <1> 
   996                              <1>  %if %0 >= 2
   997 000003A7 89C3                <1>  mov ebx, %2
   998                              <1>  %if %0 >= 3
   999 000003A9 B900000000          <1>  mov ecx, %3
  1000                              <1>  %if %0 = 4
  1001 000003AE BA02000000          <1>  mov edx, %4
  1002                              <1>  %endif
  1003                              <1>  %endif
  1004                              <1>  %endif
  1005 000003B3 B813000000          <1>  mov eax, %1
  1006 000003B8 CD30                <1>  int 30h
  1007                                  		; sys seek; 0; 2 / set pointer to 
  1008                                  				; current end of file
  1009                                  np6: ;1:
  1010 000003BA 803D[920A0000]00        	cmp	byte [glflag], 0
  1011                                  		; tst glflag / was *, ? or [ encountered?
  1012 000003C1 776F                            ja      short np9
  1013                                  		; bne 1f / yes
  1014                                  	sys	_exec, parbuf, parp
  1015                              <1> 
  1016                              <1> 
  1017                              <1> 
  1018                              <1>  %if %0 >= 2
  1019 000003C3 BB[A6060000]        <1>  mov ebx, %2
  1020                              <1>  %if %0 >= 3
  1021 000003C8 B9[A00A0000]        <1>  mov ecx, %3
  1022                              <1>  %if %0 = 4
  1023                              <1>  mov edx, %4
  1024                              <1>  %endif
  1025                              <1>  %endif
  1026                              <1>  %endif
  1027 000003CD B80B000000          <1>  mov eax, %1
  1028 000003D2 CD30                <1>  int 30h
  1029                                  		; sys exec; parbuf; parp / no, execute
  1030                                  					;  this command
  1031                                  	sys	_exec, binpb, parp
  1032                              <1> 
  1033                              <1> 
  1034                              <1> 
  1035                              <1>  %if %0 >= 2
  1036 000003D4 BB[A1060000]        <1>  mov ebx, %2
  1037                              <1>  %if %0 >= 3
  1038 000003D9 B9[A00A0000]        <1>  mov ecx, %3
  1039                              <1>  %if %0 = 4
  1040                              <1>  mov edx, %4
  1041                              <1>  %endif
  1042                              <1>  %endif
  1043                              <1>  %endif
  1044 000003DE B80B000000          <1>  mov eax, %1
  1045 000003E3 CD30                <1>  int 30h
  1046                                  		; sys exec; binpb; parp / or /bin/this command
  1047                                  np7: ;2:
  1048                                  	sys	_stat, binpb, inbuf
  1049                              <1> 
  1050                              <1> 
  1051                              <1> 
  1052                              <1>  %if %0 >= 2
  1053 000003E5 BB[A1060000]        <1>  mov ebx, %2
  1054                              <1>  %if %0 >= 3
  1055 000003EA B9[680B0000]        <1>  mov ecx, %3
  1056                              <1>  %if %0 = 4
  1057                              <1>  mov edx, %4
  1058                              <1>  %endif
  1059                              <1>  %endif
  1060                              <1>  %endif
  1061 000003EF B812000000          <1>  mov eax, %1
  1062 000003F4 CD30                <1>  int 30h
  1063                                  		; sys stat; binpb; inbuf / if can't execute
  1064                                  					; / does it exist?
  1065 000003F6 7223                    	jc	short np8
  1066                                  		; bes 2f / branch if it doesn't
  1067 000003F8 BE[9C0A0000]            	mov	esi, parp-4
  1068 000003FD C706[8F060000]          	mov	dword [esi], shell
  1069                                  		; mov $shell,parp-2 / does exist,
  1070                                  				   ;  not executable
  1071 00000403 B8[A1060000]            	mov	eax, binpb
  1072 00000408 A3[A00A0000]            	mov	[parp], eax
  1073                                  		; mov $binpb,parp / so it must be
  1074                                  	sys	_exec, shell, esi 
  1075                              <1> 
  1076                              <1> 
  1077                              <1> 
  1078                              <1>  %if %0 >= 2
  1079 0000040D BB[8F060000]        <1>  mov ebx, %2
  1080                              <1>  %if %0 >= 3
  1081 00000412 89F1                <1>  mov ecx, %3
  1082                              <1>  %if %0 = 4
  1083                              <1>  mov edx, %4
  1084                              <1>  %endif
  1085                              <1>  %endif
  1086                              <1>  %endif
  1087 00000414 B80B000000          <1>  mov eax, %1
  1088 00000419 CD30                <1>  int 30h
  1089                                  		; sys exec; shell; parp-2 / a command file,
  1090                                  		; / get it with sh /bin/x (if x name of file)
  1091                                  np8: ;2:
  1092 0000041B BE[6B060000]            	mov	esi, msgNoCmd
  1093 00000420 E83FFEFFFF              	call	error
  1094                                  		; jsr r5,error / a return for exec 
  1095                                  			       ; is the diagnostic
  1096                                  		;     <No command\n\0>; .even
  1097 00000425 8B25[720C0000]          	mov	esp, [shellarg]
  1098                                  	sys 	_exit
  1099                              <1> 
  1100                              <1> 
  1101                              <1> 
  1102                              <1>  %if %0 >= 2
  1103                              <1>  mov ebx, %2
  1104                              <1>  %if %0 >= 3
  1105                              <1>  mov ecx, %3
  1106                              <1>  %if %0 = 4
  1107                              <1>  mov edx, %4
  1108                              <1>  %endif
  1109                              <1>  %endif
  1110                              <1>  %endif
  1111 0000042B B801000000          <1>  mov eax, %1
  1112 00000430 CD30                <1>  int 30h
  1113                                  		; sys exit
  1114                                  np9: ;1:
  1115 00000432 BE[9C0A0000]            	mov	esi, parp-4
  1116 00000437 C706[97060000]          	mov	dword [esi], glob
  1117                                  		; mov $glob,parp-2 / prepare to process *,?
  1118                                  	sys	_exec, glob, esi
  1119                              <1> 
  1120                              <1> 
  1121                              <1> 
  1122                              <1>  %if %0 >= 2
  1123 0000043D BB[97060000]        <1>  mov ebx, %2
  1124                              <1>  %if %0 >= 3
  1125 00000442 89F1                <1>  mov ecx, %3
  1126                              <1>  %if %0 = 4
  1127                              <1>  mov edx, %4
  1128                              <1>  %endif
  1129                              <1>  %endif
  1130                              <1>  %endif
  1131 00000444 B80B000000          <1>  mov eax, %1
  1132 00000449 CD30                <1>  int 30h
  1133                                  		; sys exec; glob; parp-2
  1134                                  			    ; / execute modified command
  1135 0000044B EBCE                    	jmp	short np8
  1136                                  		; br 2b
  1137                                  
  1138                                  delim:
  1139 0000044D 3C0D                            cmp     al, 0Dh ; carriage return
  1140 0000044F 7416                    	je	short dlim2
  1141                                  	;cmp	al, 0Ah
  1142                                  		; cmp r0,$'\n / is character a newline
  1143                                  	;je	short dlim2
  1144                                  		; beq 1f
  1145 00000451 3C26                    	cmp	al, '&'
  1146                                  		;cmp r0,$'& / is it &
  1147 00000453 7412                    	je	short dlim2
  1148                                  		; beq 1f / yes
  1149 00000455 3C3B                    	cmp	al, ';'
  1150                                  		; cmp r0,$'; / is it ;
  1151 00000457 740E                    	je	short dlim2
  1152                                  		; beq 1f / yes
  1153 00000459 3C3F                    	cmp	al, '?'
  1154                                  		; cmp r0,$'? / is it ?
  1155 0000045B 7404                    	je	short dlim1
  1156                                  		; beq 3f
  1157 0000045D 3C5B                    	cmp	al, '['
  1158                                  		; cmp r0,$'[ / is it beginning of character string
  1159                                  		      ; / (for glob)
  1160 0000045F 7506                    	jne	short dlim2
  1161                                  		; bne 2f
  1162                                  dlim1: ;3:
  1163 00000461 FE05[920A0000]          	inc	byte [glflag]
  1164                                  		; inc glflag / ? or * or [ set flag
  1165                                  ;2:
  1166                                  	;tst	(r5)+ / bump to process all except \n,;,&
  1167                                  dlim2: ;1:
  1168                                  	; zf = 1 if the char is '\n' or ';' or '&'
  1169 00000467 C3                      	retn
  1170                                  		; rts r5
  1171                                  blank:
  1172 00000468 E80D000000              	call	getc
  1173                                  		; jsr pc,getc / get next character
  1174 0000046D 3C20                    	cmp	al, 20h
  1175                                  		; cmp $' ,r0 / leading blanks
  1176 0000046F 74F7                    	je	short blank
  1177                                  		; beq blank / yes, 'squeeze out'
  1178 00000471 3C8D                    	cmp	al, 8Dh ; 80h + 0Dh
  1179                                          ;cmp     al, 8Ah ; 80h + 0Ah
  1180 00000473 74F3                    	je	short blank
  1181                                  	        ; cmp r0,$200+'\n / new-line preceded by 				 ;  is translated
  1182                                  		; beq blank / into blank
  1183                                  	; 28/12/2015
  1184 00000475 3C0A                    	cmp	al, 0Ah
  1185 00000477 74EF                    	je	short blank
  1186                                  	;
  1187 00000479 C3                      	retn
  1188                                  		; rts pc
  1189                                  getc:
  1190 0000047A 833D[8E0A0000]00        	cmp	dword [param], 0
  1191                                  		; tst param / are we substituting for $n
  1192 00000481 773D                    	ja	short gch3
  1193                                  		; bne 2f/ yes
  1194                                  gch0:
  1195 00000483 8B1D[680C0000]                  mov     ebx, [inbufp]
  1196                                  		; mov inbufp,r1 / no, move normal input pointer to r1
  1197                                  s8:
  1198 00000489 3B1D[6C0C0000]          	cmp	ebx, [einbuf]
  1199                                  		; cmp r1,einbuf / end of input line?
  1200 0000048F 7207                    	jb	short gch1
  1201                                  		; bne 1f / no
  1202 00000491 E877000000              	call	getbuf	
  1203                                  		; jsr pc,getbuf / yes, put next console line
  1204                                  				;  in buffer
  1205 00000496 EBEB                    	jmp	short gch0
  1206                                  		; br getc
  1207                                  gch1: ;1:
  1208 00000498 8A03                    	mov	al, [ebx]
  1209 0000049A 43                      	inc	ebx
  1210                                  		; movb (r1)+,r0 / move byte from input buffer to r0
  1211 0000049B 891D[680C0000]          	mov	[inbufp], ebx
  1212                                  		; mov r1,inbufp / increment routine
  1213 000004A1 0A05[760C0000]          	or	al, [escap]
  1214                                  	;or	ax, escap
  1215                                  		; bis escap,r0 / if last character was \ this adds
  1216                                  		        	; / 200 to current character
  1217                                  	;mov	byte [escap], 0
  1218                                  	;mov	word [escap], 0
  1219                                  		; clr escap / clear, so escap normally zero
  1220 000004A7 3C5C                    	cmp	al, '\'
  1221                                  		; cmp r0,$'\\ / note that \\ is equal \ in as
  1222 000004A9 740C                    	je	short gch2
  1223                                  		; beq 1f
  1224 000004AB C605[760C0000]00        	mov	byte [escap], 0
  1225 000004B2 3C24                    	cmp	al, '$'
  1226                                  		; cmp r0,$'$ / is it $
  1227 000004B4 7429                    	je	short gch5
  1228                                  		; beq 3f / yes
  1229 000004B6 C3                      	retn
  1230                                  		; rts pc / no
  1231                                  gch2: ;1:
  1232 000004B7 C605[760C0000]80                mov     byte [escap], 80h
  1233                                  	;mov	word [escap], 128
  1234                                  		; mov $200,escap / mark presence of \ in command line
  1235 000004BE EBC9                    	jmp	short s8
  1236                                  	;jmp	short gch0
  1237                                  		; br getc / get next character
  1238                                  gch3: ;2:
  1239 000004C0 8B1D[8E0A0000]          	mov	ebx, [param]
  1240 000004C6 8A03                    	mov	al, [ebx]
  1241                                  		; movb *param,r0 / pick up substitution character
  1242                                  				; / put in r0
  1243 000004C8 08C0                    	or	al, al
  1244 000004CA 7407                    	jz	short gch4
  1245                                  		; beq	1f / if end of substitution arg, branch
  1246 000004CC FF05[8E0A0000]          	inc	dword [param]
  1247                                  		; inc param / if not end, set for next character
  1248 000004D2 C3                      	retn
  1249                                  		; rts pc / return as though character in ro is normal
  1250                                  		       ; / input
  1251                                  gch4: ;1:
  1252 000004D3 C705[8E0A0000]0000-     	mov	dword [param], 0
  1253 000004DB 0000               
  1254                                  		; clr param / unset substitution pointer
  1255 000004DD EBA4                    	jmp	short gch0
  1256                                  		; br getc / get next char in normal input
  1257                                  gch5: ;3:
  1258 000004DF E89FFFFFFF              	call	gch0
  1259                                  	;call	getc
  1260                                  		; jsr pc,getc / get digit after $
  1261 000004E4 2C30                    	sub	al, '0'
  1262                                  		; sub $'0,r0 / strip off zone bits
  1263 000004E6 3C09                    	cmp	al, 9
  1264                                  		; cmp r0,$9. / compare with digit 9
  1265 000004E8 7602                    	jna	short gch6 
  1266                                  		; blos 1f / less than or equal 9
  1267 000004EA B009                    	mov	al, 9
  1268                                  		; mov $9.,r0 / if larger than 9, force 9
  1269                                  gch6: ;1:
  1270 000004EC 8B1D[720C0000]          	mov	ebx, [shellarg]
  1271                                  		; mov shellarg,r1 / get pointer to stack for
  1272                                  		           ; / this call of shell
  1273 000004F2 0FB6C0                  	movzx 	eax, al	; al->eax
  1274 000004F5 FEC0                    	inc	al
  1275                                  	;inc	eax
  1276                                  		; inc r0 / digit +1
  1277 000004F7 3B03                    	cmp	eax, [ebx]
  1278                                  		; cmp r0,(r1) / is it less than # of args 
  1279                                  			      ;	in this call
  1280 000004F9 7388                    	jnb	short gch0
  1281                                  		; bge getc / no, ignore it. so this $n is not replaced
  1282 000004FB C0E002                  	shl	al, 2 ; multiply by 4 (24/08/2015)
  1283                                  	;shl	al, 1
  1284                                  	;;shl	ax, 1
  1285                                  		; asl r0 / yes, multiply by 2 (to skip words)
  1286 000004FE 01C3                    	add	ebx, eax
  1287                                  		; add r1,r0 / form pointer to arg pointer (-2)
  1288 00000500 8B4304                  	mov	eax, [ebx+4]
  1289 00000503 A3[8E0A0000]            	mov	[param], eax
  1290                                  		; mov 2(r0),param / move arg pointer to param
  1291 00000508 E96DFFFFFF                      jmp     getc
  1292                                  		; br getc / go to get substitution arg for $n
  1293                                  getbuf:
  1294 0000050D B9[680B0000]            	mov	ecx, inbuf
  1295                                  		; mov $inbuf,r0 / move input buffer address
  1296 00000512 890D[680C0000]                  mov     [inbufp], ecx
  1297                                  		; mov r0,inbufp / to input buffer pointer
  1298 00000518 890D[6C0C0000]          	mov	[einbuf], ecx
  1299                                  		; mov r0,einbuf / and initialize pointer to end of
  1300                                  		         ; / character string
  1301 0000051E 49                      	dec	ecx
  1302                                  		; dec r0 / decrement pointer so can utilize normal
  1303                                  		       ; / 100p starting at 1f
  1304                                  		; mov r0,0f / initialize address for reading 1st char
  1305 0000051F BA01000000              	mov	edx, 1
  1306                                  gbuf0: ;1:
  1307 00000524 41                      	inc	ecx
  1308                                  		; inc 0f / this routine filles inbuf with line from
  1309                                  		       ; / console - if there is cnc
  1310 00000525 51                      	push	ecx
  1311                                  	; edx = 1
  1312                                  	sys	_read, 0, och
  1313                              <1> 
  1314                              <1> 
  1315                              <1> 
  1316                              <1>  %if %0 >= 2
  1317 00000526 BB00000000          <1>  mov ebx, %2
  1318                              <1>  %if %0 >= 3
  1319 0000052B B9[700C0000]        <1>  mov ecx, %3
  1320                              <1>  %if %0 = 4
  1321                              <1>  mov edx, %4
  1322                              <1>  %endif
  1323                              <1>  %endif
  1324                              <1>  %endif
  1325 00000530 B803000000          <1>  mov eax, %1
  1326 00000535 CD30                <1>  int 30h
  1327 00000537 59                      	pop	ecx
  1328                                  	;xor	ebx, ebx ; 0
  1329                                  	;sys	_read ; sys _read, ebx, ecx, edx ; ebx = 0, edx = 1
  1330                                  		; sys read; 0:0; 1 / read next char into inbuf
  1331 00000538 0F82A6000000                    jc      xit1
  1332                                  		; bcs xit1 / error exit
  1333 0000053E 21C0                    	and	eax, eax
  1334                                  		; tst r0 / a zero input is end of file
  1335 00000540 0F849E000000                    jz      xit1
  1336                                  		; beq xit1 / exit
  1337 00000546 FF05[6C0C0000]          	inc	dword [einbuf]  ; 08/04/2014 (24/08/2015, 32 bit)
  1338 0000054C A0[700C0000]            	mov	al, [och]
  1339 00000551 803D[79060000]00        	cmp	byte [_at], 0
  1340 00000558 7608                    	jna	short gbuf1
  1341 0000055A 3C08                    	cmp	al, 8 ; backspace
  1342 0000055C 746B                    	je	short gbuf3
  1343 0000055E 3C7F                    	cmp	al, 127 ; delete
  1344 00000560 7460                    	je	short gbuf6 ; 06/12/2013
  1345                                  gbuf1:
  1346                                  	;mov	ebx, ecx
  1347                                  	;inc	dword [einbuf]
  1348                                  		; inc einbuf / eventually einbuf points to \n
  1349                                  		       ; / (+1) of this line
  1350 00000562 81F9[680C0000]          	cmp	ecx, inbuf + 256
  1351                                  		; cmp 0b,$inbuf+256. / have we exceeded 
  1352                                  				   ; input buffer size
  1353 00000568 737A                            jnb     xit1
  1354                                  		; bhis xit1 / if so, exit assume some sort of binary
  1355                                  	; 08/04/2014
  1356 0000056A 3C0D                    	cmp	al, 0Dh
  1357 0000056C 750A                    	jne	short gbuf8
  1358 0000056E 8B1D[6C0C0000]          	mov	ebx, [einbuf]
  1359 00000574 4B                      	dec	ebx
  1360 00000575 8803                    	mov	[ebx], al
  1361 00000577 C3                      	retn
  1362                                  gbuf8:
  1363 00000578 89CB                    	mov	ebx, ecx
  1364 0000057A 8803                    	mov	[ebx], al
  1365                                  	;cmp	al, 0Ah ; \n
  1366                                  		; cmpb	*0b,$'\n / end of line?
  1367                                  	;je	short  gbuf5
  1368                                  	;jne	short gbuf1
  1369                                  		; bne 1b / no, go to get next char
  1370                                  	;cmp	al, 0Dh ; ENTER
  1371                                  	;je	short gbuf5
  1372 0000057C 803D[79060000]00        	cmp	byte [_at], 0 ; at > 0 --> tty input
  1373 00000583 769F                    	jna	short gbuf0
  1374 00000585 3C1B                    	cmp	al, 1Bh	; ESC
  1375 00000587 7514                    	jne	short gbuf2
  1376 00000589 B8[680B0000]            	mov	eax, inbuf
  1377 0000058E A3[680C0000]            	mov	[inbufp], eax
  1378 00000593 A3[6C0C0000]            	mov	[einbuf], eax
  1379 00000598 E9F3FAFFFF                      jmp     nl  ; cancel current command, new line
  1380                                  gbuf2:
  1381                                  	 ; 28/12/2015
  1382 0000059D 803D[79060000]00        	cmp	byte [_at], 0
  1383 000005A4 0F867AFFFFFF            	jna	gbuf0
  1384                                  gbuf7:
  1385 000005AA 51                      	push	ecx
  1386                                  	;mov	[och], al
  1387                                  	; edx = 1
  1388                                  	sys	_write, 1, och
  1389                              <1> 
  1390                              <1> 
  1391                              <1> 
  1392                              <1>  %if %0 >= 2
  1393 000005AB BB01000000          <1>  mov ebx, %2
  1394                              <1>  %if %0 >= 3
  1395 000005B0 B9[700C0000]        <1>  mov ecx, %3
  1396                              <1>  %if %0 = 4
  1397                              <1>  mov edx, %4
  1398                              <1>  %endif
  1399                              <1>  %endif
  1400                              <1>  %endif
  1401 000005B5 B804000000          <1>  mov eax, %1
  1402 000005BA CD30                <1>  int 30h
  1403                                  	;sys	_write, 1, och, 1  ; echo (write char on tty)
  1404 000005BC 59                      	pop	ecx
  1405 000005BD E962FFFFFF                      jmp     gbuf0
  1406                                  gbuf6: ; DELETE key -> BACKSPACE key
  1407                                  	; mov 	al, 8
  1408 000005C2 C605[700C0000]08        	mov	byte [och], 8 ; 06/12/2013
  1409                                  gbuf3:
  1410                                  	; 08/04/2014
  1411 000005C9 FF0D[6C0C0000]          	dec	dword [einbuf] ; (24/08/2015, 32 bit code)
  1412                                  	; 12/12/2013
  1413 000005CF 49                      	dec	ecx
  1414 000005D0 81F9[680B0000]          	cmp	ecx, inbuf
  1415 000005D6 7203                    	jb	short gbuf4
  1416 000005D8 49                      	dec 	ecx
  1417                                  	; 08/04/2014
  1418                                  	;jmp	short gbuf2
  1419 000005D9 EBCF                    	jmp 	short gbuf7
  1420                                  gbuf4:
  1421                                  	;mov 	al, 7
  1422 000005DB C605[700C0000]07        	mov	byte [och], 07h ; beep
  1423                                  	; 08/04/2014
  1424                                  	;jmp	short gbuf2
  1425 000005E2 EBC6                    	jmp 	short gbuf7
  1426                                  ;gbuf5:
  1427                                  ;	retn
  1428                                  		; rts pc / yes, return
  1429                                  
  1430                                  xit1:
  1431                                  	sys	_exit
  1432                              <1> 
  1433                              <1> 
  1434                              <1> 
  1435                              <1>  %if %0 >= 2
  1436                              <1>  mov ebx, %2
  1437                              <1>  %if %0 >= 3
  1438                              <1>  mov ecx, %3
  1439                              <1>  %if %0 = 4
  1440                              <1>  mov edx, %4
  1441                              <1>  %endif
  1442                              <1>  %endif
  1443                              <1>  %endif
  1444 000005E4 B801000000          <1>  mov eax, %1
  1445 000005E9 CD30                <1>  int 30h
  1446                                  		; sys exit
  1447                                  
  1448                                  ;-----------------------------------------------------------------
  1449                                  ;  DATA
  1450                                  ;-----------------------------------------------------------------
  1451                                  
  1452                                  ;  /// Messages
  1453                                  
  1454 000005EB 0D0A                    msg_unix_sh:	db 0Dh, 0Ah
  1455 000005ED 526574726F20556E69-     		db 'Retro Unix 386 v1.1 - shell'
  1456 000005F6 78203338362076312E-
  1457 000005FF 31202D207368656C6C 
  1458                                  		;db 0Dh, 0Ah
  1459                                  msgsh_size equ  $ - msg_unix_sh
  1460                                  		;db 0
  1461 00000608 30332F30312F323031-     		db '03/01/2016'
  1462 00000611 36                 
  1463 00000612 0D0A00                  nextline:	db 0Dh, 0Ah, 0
  1464                                  ;Error messages:
  1465 00000615 496E707574206E6F74-     msgNotFound: 	db 'Input not found', 0
  1466 0000061E 20666F756E6400     
  1467 00000625 41726720636F756E74-     msgArgCount: 	db 'Arg count',  0
  1468 0000062E 00                 
  1469 0000062F 426164206469726563-     msgBadDir: 	db 'Bad directory', 0
  1470 00000638 746F727900         
  1471 0000063D 54727920616761696E-     msgTryAgain: 	db 'Try again', 0
  1472 00000646 00                 
  1473 00000647 222720696D62616C61-     msgImbalance:   db 22h, 27h, 20h, 'imbalance',  0
  1474 00000650 6E636500           
  1475 00000654 496E7075742066696C-     msgInputFile: 	db 'Input file', 0
  1476 0000065D 6500               
  1477 0000065F 4F7574707574206669-     msgOutputFile: 	db 'Output file', 0
  1478 00000668 6C6500             
  1479 0000066B 4E6F20636F6D6D616E-     msgNoCmd: 	db 'No command',  0
  1480 00000674 6400               
  1481                                  
  1482                                  ; /// Commands, files, parameters
  1483                                  
  1484                                  ; 27/12/2015
  1485                                  FCAT:	; '>>' 
  1486 00000676 00                      	db 0
  1487                                  
  1488                                  ;quest:
  1489                                  	;db '?', 0Dh, 0Ah
  1490                                  	;<?\n>
  1491                                  
  1492                                  prompt:
  1493 00000677 0D0A                    	db 0Dh, 0Ah
  1494                                  _at:
  1495 00000679 4020                    	db '@ '
  1496                                  	;<@ >
  1497                                  p_size  equ $ - prompt
  1498                                  
  1499 0000067B 6563686F00              qecho: 	db 'echo', 0
  1500                                  ;
  1501 00000680 636400                  qcd:	db 'cd', 0
  1502                                  ;
  1503                                  qchdir:
  1504 00000683 636864697200            	db 'chdir', 0
  1505                                  	;<chdir\0>
  1506                                  glogin:
  1507 00000689 6C6F67696E00            	db 'login', 0
  1508                                  	;<login\0>
  1509                                  shell:
  1510 0000068F 2F62696E2F736800        	db '/bin/sh', 0
  1511                                  	;</bin/sh\0>
  1512                                  glob:
  1513 00000697 2F6574632F676C6F62-     	db '/etc/glob', 0
  1514 000006A0 00                 
  1515                                  	;</etc/glob\0>
  1516                                  binpb:
  1517 000006A1 2F62696E2F              	db '/bin/'
  1518                                  	;</bin/>
  1519                                  
  1520                                  ; /// BSS data
  1521                                  
  1522                                  bss_start:
  1523                                  
  1524                                  ABSOLUTE bss_start
  1525                                  
  1526                                  parbuf:
  1527 000006A6 <res 000003E8>                  resb 1000
  1528                                   	; .=.+1000.
  1529                                  alignb 2
  1530                                  	;.even
  1531                                  param:
  1532 00000A8E <res 00000004>          	resd 1
  1533                                  	;.=.+2
  1534                                  glflag:
  1535 00000A92 <res 00000001>          	resb 1
  1536 00000A93 <res 00000001>          	resb 1
  1537                                  	;.=.+2
  1538                                  infile:
  1539 00000A94 <res 00000004>          	resd 1
  1540                                  	; .=.+2 
  1541                                  outfile:
  1542 00000A98 <res 00000004>          	resd 1
  1543                                  	;.=.+2
  1544                                  ; parp-4
  1545 00000A9C <res 00000004>          	resd 1
  1546                                  	;.=.+2 / room for glob
  1547                                  parp:
  1548 00000AA0 <res 000000C8>                  resb 200
  1549                                  	;.=.+200.
  1550                                  inbuf:
  1551 00000B68 <res 00000100>                  resb 256
  1552                                  	;.=.+256.
  1553                                  ;escap:
  1554                                  	;resw 1
  1555                                  	;.=.+2
  1556                                  inbufp:
  1557 00000C68 <res 00000004>          	resd 1
  1558                                  	;.=.+2
  1559                                  einbuf:
  1560 00000C6C <res 00000004>          	resd 1
  1561                                  	;.=.+2
  1562                                  och:
  1563 00000C70 <res 00000001>          	resb 1
  1564 00000C71 <res 00000001>          	resb 1
  1565                                  	;.=.+2
  1566                                  shellarg:
  1567 00000C72 <res 00000004>          	resd 1
  1568                                  	;.=.+2
  1569                                  escap:
  1570 00000C76 <res 00000001>          	resb 1
  1571                                  	;
  1572 00000C77 <res 00000001>          	resb 1
  1573                                  
  1574                                  bss_end:
