     1                                  ; ****************************************************************************
     2                                  ; pwd386.s (pwd2.s) - by Erdogan Tan - 05/05/2022
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Retro UNIX 386 v1.1 - pwd - print working directory pathname
     5                                  ;
     6                                  ; [ Last Modification: 15/05/2022 ]
     7                                  ;
     8                                  ; Derived from (original) UNIX v5 (&v7) 'pwd.c' source Code
     9                                  ; Ref:
    10                                  ; www.tuhs.org (https://minnie.tuhs.org)
    11                                  ; v5root.tar.gz
    12                                  ; ****************************************************************************
    13                                  ; [ usr/source/s2/pwd.c (archive date: 27-11-1974) ]
    14                                  
    15                                  ; pwd0.s - Retro UNIX 8086 v1 (16 bit version of 'pwd1.s')
    16                                  ; pwd1.s - Retro UNIX 386 v1 (unix v1 inode structure)
    17                                  ; pwd2.s - Retro UNIX 386 v1.1 (16 byte directory entries)
    18                                  ; pwd3.s - Retro UNIX 386 v1.2 (& v2) (modified unix v7 inode)
    19                                  
    20                                  ; UNIX v1 system calls
    21                                  _rele 	equ 0
    22                                  _exit 	equ 1
    23                                  _fork 	equ 2
    24                                  _read 	equ 3
    25                                  _write	equ 4
    26                                  _open	equ 5
    27                                  _close 	equ 6
    28                                  _wait 	equ 7
    29                                  _creat 	equ 8
    30                                  _link 	equ 9
    31                                  _unlink	equ 10
    32                                  _exec	equ 11
    33                                  _chdir	equ 12
    34                                  _time 	equ 13
    35                                  _mkdir 	equ 14
    36                                  _chmod	equ 15
    37                                  _chown	equ 16
    38                                  _break	equ 17
    39                                  _stat	equ 18
    40                                  _seek	equ 19
    41                                  _tell 	equ 20
    42                                  _mount	equ 21
    43                                  _umount	equ 22
    44                                  _setuid	equ 23
    45                                  _getuid	equ 24
    46                                  _stime	equ 25
    47                                  _quit	equ 26	
    48                                  _intr	equ 27
    49                                  _fstat	equ 28
    50                                  _emt 	equ 29
    51                                  _mdate 	equ 30
    52                                  _stty 	equ 31
    53                                  _gtty	equ 32
    54                                  _ilgins	equ 33
    55                                  _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
    56                                  _msg    equ 35 ; Retro UNIX 386 v1 feature only !
    57                                  
    58                                  ;;;
    59                                  ESCKey equ 1Bh
    60                                  EnterKey equ 0Dh
    61                                  
    62                                  %macro sys 1-4
    63                                      ; 03/09/2015	
    64                                      ; 13/04/2015
    65                                      ; Retro UNIX 386 v1 system call.		
    66                                      %if %0 >= 2   
    67                                  	mov ebx, %2
    68                                  	%if %0 >= 3    
    69                                  	    mov ecx, %3
    70                                  	    %if %0 = 4
    71                                  	       mov edx, %4   
    72                                  	    %endif
    73                                  	%endif
    74                                      %endif
    75                                      mov eax, %1
    76                                      int 30h	   
    77                                  %endmacro
    78                                  
    79                                  ; Retro UNIX 386 v1 system call format:
    80                                  ; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
    81                                  
    82                                  [BITS 32] ; 32-bit intructions (for 80386 protected mode)
    83                                  
    84                                  [ORG 0] 
    85                                  
    86                                  START_CODE:
    87                                  	; 06/05/2022
    88                                  	; 05/05/2022
    89                                  
    90                                  ;main() {
    91                                  ;	int n;
    92                                  
    93                                  	;  clear (reset) stack (not necessary)
    94 00000000 59                      	pop	ecx ; ecx = number of arguments
    95                                  pwd_0:
    96 00000001 58                      	pop	eax ; eax = argument 0 = executable file name
    97 00000002 E2FD                    	loop	pwd_0
    98                                  
    99                                  	;mov	byte [y.zero], 0 ; (not necessary)
   100                                  			; (because Retro UNIX kernel
   101                                  			; clears bss -memory page- while
   102                                  			; assigning it to program)
   103                                  	;mov	 dword [off], 0
   104                                  
   105                                  	; 06/05/2022
   106 00000004 FF0D[3C040000]          	dec	dword [off] ; -1
   107                                  
   108                                  ;loop0:
   109                                  ;	stat(dot, &x);
   110                                  ;	if((file = open(dotdot,0)) < 0) prname();
   111                                  
   112                                  loop0:
   113                                  	;sys	_stat, dot, _x
   114                                  
   115                                  	; 14/05/2022
   116                                  	;stat(dot, &d);
   117                                  	;if (d.st_ino==rino && d.st_dev==rdev)
   118                                  	;	prname();
   119                                  
   120                                  	sys	_stat, dot, _d
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67 0000000A BB[F6010000]        <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69 0000000F B9[42040000]        <1>  mov ecx, %3
    70                              <1>  %if %0 = 4
    71                              <1>  mov edx, %4
    72                              <1>  %endif
    73                              <1>  %endif
    74                              <1>  %endif
    75 00000014 B812000000          <1>  mov eax, %1
    76 00000019 CD30                <1>  int 30h
   121 0000001B 723D                    	jc	short error
   122                                  
   123 0000001D 66833D[42040000]29      	cmp	word [d.ino], 41 ; d.st_ino == rino
   124 00000025 7504                    	jne	short pwd_1
   125 00000027 09C0                    	or	eax, eax
   126                                  	;or	ax, ax ; [d.dev] ; && d.st_dev==rdev
   127                                  	;jz	short prname ; root device, root dir
   128 00000029 742A                    	jz	short pwd_p ; 14/05/2022
   129                                  pwd_1:
   130 0000002B 66A3[40040000]          	mov	[d.dev], ax
   131                                  
   132                                  	; 15/05/2022
   133                                  	sys	_open, dotdot, 0  ; open for read
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67 00000031 BB[F5010000]        <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69 00000036 B900000000          <1>  mov ecx, %3
    70                              <1>  %if %0 = 4
    71                              <1>  mov edx, %4
    72                              <1>  %endif
    73                              <1>  %endif
    74                              <1>  %endif
    75 0000003B B805000000          <1>  mov eax, %1
    76 00000040 CD30                <1>  int 30h
   134                                  	;jc	short prname
   135                                  	; 14/05/2022
   136 00000042 731D                    	jnc	short pwd_2
   137                                  
   138                                  	; 14/05/2022
   139                                  pwd_err:
   140 00000044 B8[07020000]            	mov	eax, err_1
   141                                  pmsg_exit:
   142 00000049 E88D010000              	call	print_msg
   143                                  exit:
   144                                  	sys	_exit ; exit(1);
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67                              <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69                              <1>  mov ecx, %3
    70                              <1>  %if %0 = 4
    71                              <1>  mov edx, %4
    72                              <1>  %endif
    73                              <1>  %endif
    74                              <1>  %endif
    75 0000004E B801000000          <1>  mov eax, %1
    76 00000053 CD30                <1>  int 30h
   145                                  ;hang:
   146                                  ;	nop
   147                                  ;	jmp	short hang
   148                                  
   149                                  
   150                                  pwd_p:	; 14/05/2022
   151 00000055 E9E6000000              	jmp	prname
   152                                  	
   153                                  error:	; 14/05/2022
   154 0000005A B8[FC010000]            	mov	eax, err_0
   155 0000005F EBE3                    	jmp	short pwd_err
   156                                  
   157                                  pwd_2:
   158                                  
   159                                  ;loop1:
   160                                  ;	if((n = read(file,&y,16)) < 16) prname();
   161                                  ;	if(y.jnum != x.inum)goto loop1;
   162                                  ;	close(file);
   163                                  ;	if(y.jnum == 1) ckroot();
   164                                  ;	cat();
   165                                  ;	chdir(dotdot);
   166                                  ;	goto loop0;
   167                                  ;}
   168                                  
   169 00000061 A3[38040000]            	mov	[file], eax
   170                                  
   171                                  	; 14/05/2022
   172                                  	;fstat(file, &dd);
   173                                  	;chdir(dotdot);
   174                                  
   175                                  	sys	_fstat, eax, _dd
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67 00000066 89C3                <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69 00000068 B9[64040000]        <1>  mov ecx, %3
    70                              <1>  %if %0 = 4
    71                              <1>  mov edx, %4
    72                              <1>  %endif
    73                              <1>  %endif
    74                              <1>  %endif
    75 0000006D B81C000000          <1>  mov eax, %1
    76 00000072 CD30                <1>  int 30h
   176 00000074 72E4                    	jc	short error
   177                                  
   178                                  	;mov	[dd.dev], ax
   179 00000076 89C1                    	mov	ecx, eax
   180                                  	
   181                                  	sys	_chdir, dotdot
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67 00000078 BB[F5010000]        <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69                              <1>  mov ecx, %3
    70                              <1>  %if %0 = 4
    71                              <1>  mov edx, %4
    72                              <1>  %endif
    73                              <1>  %endif
    74                              <1>  %endif
    75 0000007D B80C000000          <1>  mov eax, %1
    76 00000082 CD30                <1>  int 30h
   182 00000084 72D4                    	jc	short error
   183                                  
   184 00000086 663B0D[40040000]        	cmp	cx, [d.dev]
   185 0000008D 7557                    	jne	short pwd_4
   186                                  
   187 0000008F 66A1[42040000]          	mov	ax, [d.ino]
   188 00000095 663B05[64040000]        	cmp	ax, [dd.ino]
   189                                  	;je	short prname
   190                                  	; 14/05/2022
   191 0000009C 7505                    	jne	short loop1
   192 0000009E E99D000000              	jmp	prname
   193                                  	
   194                                  	; do .. while
   195                                  loop1:
   196                                  	;;sys	_read, [file], _y, 10 ; Retro UNIX 386 v1
   197                                  	sys	_read, [file], _y, 16 ; Retro UNIX 386 v1.1 & v1.2
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67 000000A3 8B1D[38040000]      <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69 000000A9 B9[86040000]        <1>  mov ecx, %3
    70                              <1>  %if %0 = 4
    71 000000AE BA10000000          <1>  mov edx, %4
    72                              <1>  %endif
    73                              <1>  %endif
    74                              <1>  %endif
    75 000000B3 B803000000          <1>  mov eax, %1
    76 000000B8 CD30                <1>  int 30h
   198                                  	;jc	short prname
   199                                  	; 14/05/2022
   200 000000BA 7247                    	jc	short pwd_5
   201                                  	;cmp	eax, 16	 ; cmp eax, 10
   202                                  	;;jb	short prname	
   203                                  	;jb	short pwd_5 ; 14/05/2022
   204 000000BC 09C0                    	or	eax, eax
   205                                  	;jz	short prname
   206 000000BE 7443                    	jz	short pwd_5 ; 14/05/2022
   207                                  	
   208                                  	; 14/05/2022
   209                                  	; while (dir.d_ino != d.st_ino);
   210 000000C0 66A1[86040000]          	mov	ax, [jnum] 
   211                                  	;cmp	ax, [inum]
   212 000000C6 663B05[42040000]        	cmp	ax, [d.ino]
   213 000000CD 75D4                    	jne	short loop1
   214                                  pwd_3:
   215                                  	sys	_close, [file]
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67 000000CF 8B1D[38040000]      <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69                              <1>  mov ecx, %3
    70                              <1>  %if %0 = 4
    71                              <1>  mov edx, %4
    72                              <1>  %endif
    73                              <1>  %endif
    74                              <1>  %endif
    75 000000D5 B806000000          <1>  mov eax, %1
    76 000000DA CD30                <1>  int 30h
   216                                  	
   217                                  	;;cmp	word [jnum], 1	; Retro UNIX 386 v1.2
   218                                  	;cmp	word [jnum], 41 ; root dir inode number
   219                                  	;je	short ckroot
   220                                  	;call	cat
   221                                  	;sys	_chdir, dotdot
   222                                  	;jmp	short loop0
   223                                  
   224                                  	; 11/05/2022
   225 000000DC E8A4000000              	call	cat
   226 000000E1 E924FFFFFF              	jmp	loop0  ; for (;;)
   227                                  pwd_4:
   228                                  loop_2:
   229                                  	; 14/05/2022
   230                                  	; else do .. while
   231                                  	;sys	_read, [file], _y, 10 ; Retro UNIX 386 v1
   232                                  	sys	_read, [file], _y, 16 ; Retro UNIX 386 v1.1 & v1.2
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67 000000E6 8B1D[38040000]      <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69 000000EC B9[86040000]        <1>  mov ecx, %3
    70                              <1>  %if %0 = 4
    71 000000F1 BA10000000          <1>  mov edx, %4
    72                              <1>  %endif
    73                              <1>  %endif
    74                              <1>  %endif
    75 000000F6 B803000000          <1>  mov eax, %1
    76 000000FB CD30                <1>  int 30h
   233 000000FD 7204                    	jc	short pwd_5
   234 000000FF 21C0                    	and	eax, eax
   235 00000101 750A                    	jnz	short pwd_6
   236                                  pwd_5:
   237 00000103 B8[20020000]            	mov	eax, err_2
   238 00000108 E93CFFFFFF              	jmp	pmsg_exit
   239                                  pwd_6:
   240                                  	; stat(dir.d_name, &dd);
   241                                  	sys	_stat, yname, _dd
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67 0000010D BB[88040000]        <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69 00000112 B9[64040000]        <1>  mov ecx, %3
    70                              <1>  %if %0 = 4
    71                              <1>  mov edx, %4
    72                              <1>  %endif
    73                              <1>  %endif
    74                              <1>  %endif
    75 00000117 B812000000          <1>  mov eax, %1
    76 0000011C CD30                <1>  int 30h
   242 0000011E 7305                    	jnc	short pwd_7
   243 00000120 E935FFFFFF              	jmp	error
   244                                  pwd_7:
   245                                  	; while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
   246 00000125 668B0D[42040000]        	mov	cx, [d.ino]
   247 0000012C 663B0D[64040000]        	cmp	cx, [dd.ino]
   248 00000133 75B1                    	jne	short loop_2
   249 00000135 663B05[40040000]        	cmp	ax, [d.dev]
   250 0000013C 75A8                    	jne	short loop_2
   251 0000013E EB8F                    	jmp	short pwd_3
   252                                  
   253                                  ;prname() {
   254                                  ;	name[off] = '\n';
   255                                  ;	write(1,name,off+1);
   256                                  ;	exit();
   257                                  
   258                                  prname:
   259                                  	sys	_write, 1, nextline, 3	; 06/05/2022
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67 00000140 BB01000000          <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69 00000145 B9[F8010000]        <1>  mov ecx, %3
    70                              <1>  %if %0 = 4
    71 0000014A BA03000000          <1>  mov edx, %4
    72                              <1>  %endif
    73                              <1>  %endif
    74                              <1>  %endif
    75 0000014F B804000000          <1>  mov eax, %1
    76 00000154 CD30                <1>  int 30h
   260                                  
   261 00000156 8B35[3C040000]          	mov	esi, [off]
   262                                  
   263                                  	; 14/05/2022
   264                                  	;if (off<0) off = 0;	
   265 0000015C 46                      	inc	esi ; -1 -> 0
   266 0000015D 7401                    	jz	short prname_crlf
   267 0000015F 4E                      	dec	esi
   268                                  prname_crlf:
   269                                  	;mov	byte [esi+name], 0Dh ; CR
   270 00000160 66C786[38020000]0D-     	mov	word [esi+name], 0A0Dh  ; CRLF 
   270 00000168 0A                 
   271                                  	;inc	dword [off]
   272 00000169 46                      	inc	esi
   273 0000016A 46                      	inc	esi
   274                                  	;mov	[off], esi
   275                                  	;sys	_write, 1, name, [off]
   276                                  	sys	_write, 1, name, esi
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67 0000016B BB01000000          <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69 00000170 B9[38020000]        <1>  mov ecx, %3
    70                              <1>  %if %0 = 4
    71 00000175 89F2                <1>  mov edx, %4
    72                              <1>  %endif
    73                              <1>  %endif
    74                              <1>  %endif
    75 00000177 B804000000          <1>  mov eax, %1
    76 0000017C CD30                <1>  int 30h
   277                                  _exit_:
   278                                  	sys	_exit
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67                              <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69                              <1>  mov ecx, %3
    70                              <1>  %if %0 = 4
    71                              <1>  mov edx, %4
    72                              <1>  %endif
    73                              <1>  %endif
    74                              <1>  %endif
    75 0000017E B801000000          <1>  mov eax, %1
    76 00000183 CD30                <1>  int 30h
   279                                  ;hang:
   280                                  ;	nop
   281                                  ;	jmp	short hang
   282                                  
   283                                  ;ckroot() {
   284                                  ;	int i, n;
   285                                  ;
   286                                  ;	if((n = stat(y.name,&x)) < 0) prname();
   287                                  ;	i = x.devn;
   288                                  ;	if((n = chdir(root)) < 0) prname();
   289                                  ;	if((file = open(root,0)) < 0) prname();
   290                                  ;loop:
   291                                  ;	if((n = read(file,&y,16)) < 16) prname();
   292                                  ;	if(y.jnum == 0) goto loop;
   293                                  ;	if((n = stat(y.name,&x)) < 0) prname();
   294                                  ;	if(x.devn != i) goto loop;
   295                                  ;	x.i[0] =& 060000;
   296                                  ;	if(x.i[0] != 040000) goto loop;
   297                                  ;	cat();
   298                                  ;	prname();
   299                                  
   300                                  ; 14/05/2022
   301                                  ;	; 06/05/2022
   302                                  ;	; Note: For Retro UNIX 386 v1 & v1.1 & v1.2,
   303                                  ;	;	mounted device is handled via 'mnti'
   304                                  ;	;	field which keeps (device 0) mounting
   305                                  ;	;	directory inode number for mounted
   306                                  ;	;	device (1). Device number (0 or 1) check
   307                                  ;	;	(via 'sysstat') is not possible
   308                                  ;	;	for current Retro UNIX kernel versions
   309                                  ;	;	because 'sysstat' output does not contain
   310                                  ;	;	device number.
   311                                  ;	;	***
   312                                  ;	;	As a temporary solution (before a next
   313                                  ;	;	kernel version with new 'sysstat'),
   314                                  ;	;	root dir entries are checked for a subdir 
   315                                  ;	;	('usr' & 'mnt' dirs for now) with root dir
   316                                  ;	;	inode number (41 or 1), if there is..
   317                                  ;	;	root directory is a real (device 0) root
   318                                  ;	;	directory; if not, device 1 root directory 
   319                                  ;	;	is mounted to a sub directory of device 0.
   320                                  ;	; 	(Also it must be verified after 'chdir /')
   321                                  ;	;
   322                                  ;	;	assumptions...
   323                                  ;	;	a sub dir with root inode number
   324                                  ;	;	dotdot / - chdir /
   325                                  ;	;	   no    -  no ----> root
   326                                  ;	;	   yes 	 - (yes) --> root, not checked
   327                                  ;	;	   no    - yes ----> mounted
   328                                  ;	;	   yes   - (no) ---> root, not checked
   329                                  ;
   330                                  ;ckroot:
   331                                  ;	; 06/05/2022
   332                                  ;	; check 'usr' directory
   333                                  ;	mov	edx, usr
   334                                  ;	call	statm 
   335                                  ;	jz	short ckroot_2	; root dir
   336                                  ;	; check 'mnt' directory
   337                                  ;	mov	edx, mnt
   338                                  ;	call	statm 
   339                                  ;	jz	short ckroot_2	; root dir
   340                                  ;
   341                                  ;	sys	_chdir, root
   342                                  ;	jc	short ckroot_2	; jmp short prname
   343                                  ;
   344                                  ;	; check 'usr' directory
   345                                  ;	mov	edx, usr
   346                                  ;	call	statm 
   347                                  ;	jz	short ckroot_1	; mounted
   348                                  ;	; check 'mnt' directory
   349                                  ;	mov	edx, mnt
   350                                  ;	call	statm 
   351                                  ;	jnz	short ckroot_2	; not mounted
   352                                  ;
   353                                  ;	; mounted
   354                                  ;ckroot_1:
   355                                  ;	; move mounting directory name
   356                                  ;	mov	esi, edx
   357                                  ;	mov	edi, yname
   358                                  ;	movsd
   359                                  ;	; concatenate (add to head of the path)
   360                                  ;	call	cat
   361                                  ;ckroot_2:
   362                                  ;	jmp	prname
   363                                  ;
   364                                  ;statm:
   365                                  ;	; 06/05/2022
   366                                  ;	sys	_stat, edx, _x
   367                                  ;	jc	short statm_1
   368                                  ;	;cmp	word [inum], 1	; Retro UNIX 386 v1.2
   369                                  ;	cmp	word [inum], 41 ; root dir inode number
   370                                  ;statm_1:
   371                                  ;	retn
   372                                  
   373                                  ;cat() {
   374                                  ;	int i, j;
   375                                  ;
   376                                  ;	i = -1;
   377                                  ;	while(y.name[++i] != 0);
   378                                  ;	if((off+i+2) > 511) prname();
   379                                  ;	for(j=off+1; j>=0; --j) name[j+i+1] = name[j];
   380                                  ;	off=i+off+1;
   381                                  ;	name[i] = root[0];
   382                                  ;	for(--i; i>=0; --i) name[i] = y.name[i];
   383                                  ;}
   384                                  
   385                                  cat:
   386 00000185 31DB                    	xor	ebx, ebx
   387 00000187 4B                      	dec	ebx ; i = -1
   388                                  cat_0:
   389 00000188 43                      	inc	ebx ; ++i
   390 00000189 80BB[88040000]00        	cmp	byte [yname+ebx], 0
   391 00000190 77F6                    	ja	short cat_0
   392 00000192 89DA                    	mov	edx, ebx ; i
   393 00000194 8B0D[3C040000]          	mov	ecx, [off]
   394 0000019A 41                      	inc	ecx ; j = [off]+1
   395 0000019B 01CA                    	add	edx, ecx  ; edx = [off]+i+1
   396 0000019D 81FAFD010000            	cmp	edx, 511-2 ; (+ CRLF + 0) 
   397 000001A3 779B                    	ja	short prname  ; 14/05/2022
   398                                  	;;ja	short ckroot_2 ; jmp prname
   399                                  	;ja	short ckroot_err
   400 000001A5 BE[38020000]            	mov	esi, name
   401 000001AA 01CE                    	add	esi, ecx ; name[j]
   402 000001AC 89F7                    	mov	edi, esi
   403 000001AE 01DF                    	add	edi, ebx ; name[j+i]
   404 000001B0 47                      	inc	edi ; name[j+i+1]	
   405                                  cat_1:
   406                                  	;std
   407                                  	;rep	stosb
   408                                  	;cld
   409 000001B1 49                      	dec	ecx
   410 000001B2 7808                    	js	short cat_2
   411 000001B4 4E                      	dec	esi
   412 000001B5 8A06                    	mov	al, [esi]
   413 000001B7 4F                      	dec	edi
   414 000001B8 8807                    	mov	[edi], al
   415 000001BA EBF5                    	jmp	short cat_1
   416                                  cat_2:
   417 000001BC 8915[3C040000]          	mov	[off], edx ; [off] = i+[off]+1
   418 000001C2 C683[38020000]2F        	mov	byte [name+ebx], '/' ; name[i] = root[0]
   419                                  cat_3:
   420 000001C9 4B                      	dec	ebx ; --i
   421 000001CA 780E                    	js	short cat_4 ; 0 -> -1
   422                                  		 ; name[i] = yname[i]
   423 000001CC 8A83[88040000]          	mov	al, [yname+ebx]
   424 000001D2 8883[38020000]          	mov	[name+ebx], al
   425 000001D8 EBEF                    	jmp	short cat_3 ; i >= 0
   426                                  cat_4:
   427 000001DA C3                      	retn
   428                                  
   429                                  ;-----------------------------------------------------------------
   430                                  
   431                                  print_msg:
   432                                  	; 08/05/2022
   433                                  	; eax = asciiz string address
   434 000001DB 89C2                    	mov	edx, eax
   435 000001DD 4A                      	dec	edx
   436                                  nextchr:
   437 000001DE 42                      	inc	edx
   438 000001DF 803A00                  	cmp	byte [edx], 0
   439 000001E2 77FA                    	ja	short nextchr
   440                                  	;cmp	[edx], 0Dh
   441                                  	;ja	short nextchr
   442 000001E4 29C2                    	sub	edx, eax
   443                                  	; edx = asciiz string length
   444                                  	;
   445                                  	sys	_write, 1, eax
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67 000001E6 BB01000000          <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69 000001EB 89C1                <1>  mov ecx, %3
    70                              <1>  %if %0 = 4
    71                              <1>  mov edx, %4
    72                              <1>  %endif
    73                              <1>  %endif
    74                              <1>  %endif
    75 000001ED B804000000          <1>  mov eax, %1
    76 000001F2 CD30                <1>  int 30h
   446                                  	;
   447 000001F4 C3                      	retn
   448                                  
   449                                  ;-----------------------------------------------------------------
   450                                  ;  data - initialized data
   451                                  ;-----------------------------------------------------------------
   452                                  
   453                                  ; 05/05/2022
   454                                  
   455 000001F5 2E                      dotdot:	db '.'
   456 000001F6 2E                      dot:	db '.'
   457 000001F7 00                      	db 0
   458                                  
   459                                  ; 06/05/2022
   460                                  nextline:
   461 000001F8 0D0A                    	db 0Dh, 0Ah
   462 000001FA 2F00                    root:	db '/', 0
   463                                  
   464                                  ; 14/05/2022
   465                                  ; default mounting directories (for current retro unix version)
   466                                  ;usr:	db 'usr', 0
   467                                  ;mnt:	db 'mnt', 0
   468                                  
   469                                  ; 14/05/2022
   470 000001FC 0D0A                    err_0:	db 0Dh, 0Ah
   471 000001FE 4572726F7221            	db "Error!"
   472 00000204 0D0A00                  	db 0dh, 0Ah, 0
   473                                  
   474 00000207 0D0A                    err_1:	db 0Dh, 0Ah
   475 00000209 7077643A2063616E20-     	db "pwd: can not open .."
   475 00000212 6E6F74206F70656E20-
   475 0000021B 2E2E               
   476 0000021D 0D0A00                  	db 0Dh, 0Ah, 0
   477 00000220 0D0A                    err_2:	db 0Dh, 0Ah
   478 00000222 72656164206572726F-     	db "read error in .."
   478 0000022B 7220696E202E2E     
   479 00000232 0D0A00                  	db 0Dh, 0Ah, 0
   480                                  
   481                                  ;-----------------------------------------------------------------
   482                                  ;  bss - uninitialized data
   483                                  ;-----------------------------------------------------------------	
   484                                  
   485 00000235 90<rep 3h>              align 4
   486                                  
   487                                  bss_start:
   488                                  
   489                                  ABSOLUTE bss_start
   490                                  
   491                                  ; 05/05/2022
   492                                  
   493 00000238 <res 200h>              name:	resb 512
   494                                  
   495 00000438 ????????                file:	resd 1
   496 0000043C ????????                off:	resd 1
   497                                  
   498                                  ; 14/05/2022
   499                                  idev:
   500 00000440 ????                    d.dev:	resw 1 ; device number (0 = root, 1 = mounted)
   501                                  ;dd.dev: resw 1
   502                                  
   503                                  _x:	; stat(us) buffer
   504                                  _d:	; 14/05/2022
   505                                  inum:
   506                                  d.ino:	; 14/05/2022
   507 00000442 ????                    	resw 1
   508                                  ximode:
   509                                  d.mode: ; 14/05/22022
   510                                  	;resb 64 ; Retro UNIX 386 v1.2
   511 00000444 <res 20h>               	resb 32 ; Retro UNIX 386 v1 & v1.1
   512                                  
   513                                  ; 14/05/2022
   514                                  _dd:	; stat(us) buffer
   515 00000464 ????                    dd.ino:	resw 1
   516                                  dd.mode:
   517 00000466 <res 20h>               	resb 32
   518                                  
   519                                  _y:	; directory entry buffer
   520 00000486 ????                    jnum:	resw 1
   521 00000488 <res Eh>                yname:	resb 14 ; Retro UNIX 386 v1.1 & v1.2
   522                                  	;resb 8 ; Retro UNIX 386 v1 (unix v1)
   523 00000496 ????                    yzero:	resw 1
   524                                  
   525                                  ;-----------------------------------------------------------------
   526                                  ; Original UNIX v7 - /bin/pwd file - c source code (pwd.c)
   527                                  ;-----------------------------------------------------------------
   528                                  ;
   529                                  ;/*
   530                                  ; * Print working (current) directory
   531                                  ; */
   532                                  ;#include <stdio.h>
   533                                  ;#include <sys/param.h>
   534                                  ;#include <sys/stat.h>
   535                                  ;#include <sys/dir.h>
   536                                  ;
   537                                  ;char	dot[]	= ".";
   538                                  ;char	dotdot[] = "..";
   539                                  ;char	name[512];
   540                                  ;int	file;
   541                                  ;int	off	= -1;
   542                                  ;struct	stat	d, dd;
   543                                  ;struct	direct	dir;
   544                                  ;
   545                                  ;main()
   546                                  ;{
   547                                  ;	int rdev, rino;
   548                                  ;
   549                                  ;	stat("/", &d);
   550                                  ;	rdev = d.st_dev;
   551                                  ;	rino = d.st_ino;
   552                                  ;	for (;;) {
   553                                  ;		stat(dot, &d);
   554                                  ;		if (d.st_ino==rino && d.st_dev==rdev)
   555                                  ;			prname();
   556                                  ;		if ((file = open(dotdot,0)) < 0) {
   557                                  ;			fprintf(stderr,"pwd: cannot open ..\n");
   558                                  ;			exit(1);
   559                                  ;		}
   560                                  ;		fstat(file, &dd);
   561                                  ;		chdir(dotdot);
   562                                  ;		if(d.st_dev == dd.st_dev) {
   563                                  ;			if(d.st_ino == dd.st_ino)
   564                                  ;				prname();
   565                                  ;			do
   566                                  ;				if (read(file, (char *)&dir, sizeof(dir)) < sizeof(dir)) {
   567                                  ;					fprintf(stderr,"read error in ..\n");
   568                                  ;					exit(1);
   569                                  ;				}
   570                                  ;			while (dir.d_ino != d.st_ino);
   571                                  ;		}
   572                                  ;		else do {
   573                                  ;				if(read(file, (char *)&dir, sizeof(dir)) < sizeof(dir)) {
   574                                  ;					fprintf(stderr,"read error in ..\n");
   575                                  ;					exit(1);
   576                                  ;				}
   577                                  ;				stat(dir.d_name, &dd);
   578                                  ;			} while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
   579                                  ;		close(file);
   580                                  ;		cat();
   581                                  ;	}
   582                                  ;}
   583                                  ;
   584                                  ;prname()
   585                                  ;{
   586                                  ;	write(1, "/", 1);
   587                                  ;	if (off<0)
   588                                  ;		off = 0;
   589                                  ;	name[off] = '\n';
   590                                  ;	write(1, name, off+1);
   591                                  ;	exit(0);
   592                                  ;}
   593                                  ;
   594                                  ;cat()
   595                                  ;{
   596                                  ;	register i, j;
   597                                  ;
   598                                  ;	i = -1;
   599                                  ;	while (dir.d_name[++i] != 0);
   600                                  ;	if ((off+i+2) > 511)
   601                                  ;		prname();
   602                                  ;	for(j=off+1; j>=0; --j)
   603                                  ;		name[j+i+1] = name[j];
   604                                  ;	off=i+off+1;
   605                                  ;	name[i] = '/';
   606                                  ;	for(--i; i>=0; --i)
   607                                  ;		name[i] = dir.d_name[i];
   608                                  ;}
   609                                  
   610                                  ; 05/05/2022
   611                                  
   612                                  ;-----------------------------------------------------------------
   613                                  ; Original UNIX v5 - /usr/bin/pwd file - c source code (pwd.c)
   614                                  ;-----------------------------------------------------------------
   615                                  ;
   616                                  ;char dot[] ".";
   617                                  ;char dotdot[] "..";
   618                                  ;char root[] "/";
   619                                  ;char name[512];
   620                                  ;int file, off -1;
   621                                  ;struct statb {int devn, inum, i[18];}x;
   622                                  ;struct entry { int jnum; char name[16];}y;
   623                                  ;
   624                                  ;main() {
   625                                  ;	int n;
   626                                  ;
   627                                  ;loop0:
   628                                  ;	stat(dot, &x);
   629                                  ;	if((file = open(dotdot,0)) < 0) prname();
   630                                  ;loop1:
   631                                  ;	if((n = read(file,&y,16)) < 16) prname();
   632                                  ;	if(y.jnum != x.inum)goto loop1;
   633                                  ;	close(file);
   634                                  ;	if(y.jnum == 1) ckroot();
   635                                  ;	cat();
   636                                  ;	chdir(dotdot);
   637                                  ;	goto loop0;
   638                                  ;}
   639                                  ;ckroot() {
   640                                  ;	int i, n;
   641                                  ;
   642                                  ;	if((n = stat(y.name,&x)) < 0) prname();
   643                                  ;	i = x.devn;
   644                                  ;	if((n = chdir(root)) < 0) prname();
   645                                  ;	if((file = open(root,0)) < 0) prname();
   646                                  ;loop:
   647                                  ;	if((n = read(file,&y,16)) < 16) prname();
   648                                  ;	if(y.jnum == 0) goto loop;
   649                                  ;	if((n = stat(y.name,&x)) < 0) prname();
   650                                  ;	if(x.devn != i) goto loop;
   651                                  ;	x.i[0] =& 060000;
   652                                  ;	if(x.i[0] != 040000) goto loop;
   653                                  ;	cat();
   654                                  ;	prname();
   655                                  ;}
   656                                  ;prname() {
   657                                  ;	name[off] = '\n';
   658                                  ;	write(1,name,off+1);
   659                                  ;	exit();
   660                                  ;}
   661                                  ;cat() {
   662                                  ;	int i, j;
   663                                  ;
   664                                  ;	i = -1;
   665                                  ;	while(y.name[++i] != 0);
   666                                  ;	if((off+i+2) > 511) prname();
   667                                  ;	for(j=off+1; j>=0; --j) name[j+i+1] = name[j];
   668                                  ;	off=i+off+1;
   669                                  ;	name[i] = root[0];
   670                                  ;	for(--i; i>=0; --i) name[i] = y.name[i];
   671                                  ;}
