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