     1                                  ; ****************************************************************************
     2                                  ; pwd386.s (pwd3.s) - by Erdogan Tan - 05/05/2022
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Retro UNIX 386 v1.2 - 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]01      	cmp	word [d.ino], 1 ; d.st_ino == rino
   124                                  	;cmp	word [d.ino], 41 ; d.st_ino == rino
   125 00000025 7504                    	jne	short pwd_1
   126 00000027 09C0                    	or	eax, eax ; [d.dev]
   127                                  	;or	ax, ax ; [d.dev] ; && d.st_dev==rdev
   128                                  	;jz	short prname ; root device, root dir
   129 00000029 742A                    	jz	short pwd_p ; 14/05/2022
   130                                  pwd_1:
   131 0000002B 66A3[40040000]          	mov	[d.dev], ax
   132                                  
   133                                  	; 15/05/2022
   134                                  	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
   135                                  	;jc	short prname
   136                                  	; 14/05/2022
   137 00000042 731D                    	jnc	short pwd_2
   138                                  
   139                                  	; 14/05/2022
   140                                  pwd_err:
   141 00000044 B8[07020000]            	mov	eax, err_1
   142                                  pmsg_exit:
   143 00000049 E88D010000              	call	print_msg
   144                                  exit:
   145                                  	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
   146                                  ;hang:
   147                                  ;	nop
   148                                  ;	jmp	short hang
   149                                  
   150                                  
   151                                  pwd_p:	; 14/05/2022
   152 00000055 E9E6000000              	jmp	prname
   153                                  	
   154                                  error:	; 14/05/2022
   155 0000005A B8[FC010000]            	mov	eax, err_0
   156 0000005F EBE3                    	jmp	short pwd_err
   157                                  
   158                                  pwd_2:
   159                                  
   160                                  ;loop1:
   161                                  ;	if((n = read(file,&y,16)) < 16) prname();
   162                                  ;	if(y.jnum != x.inum)goto loop1;
   163                                  ;	close(file);
   164                                  ;	if(y.jnum == 1) ckroot();
   165                                  ;	cat();
   166                                  ;	chdir(dotdot);
   167                                  ;	goto loop0;
   168                                  ;}
   169                                  
   170 00000061 A3[38040000]            	mov	[file], eax
   171                                  
   172                                  	; 14/05/2022
   173                                  	;fstat(file, &dd);
   174                                  	;chdir(dotdot);
   175                                  
   176                                  	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[84040000]        <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
   177 00000074 72E4                    	jc	short error
   178                                  
   179                                  	;mov	[dd.dev], ax
   180 00000076 89C1                    	mov	ecx, eax
   181                                  	
   182                                  	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
   183 00000084 72D4                    	jc	short error
   184                                  
   185 00000086 663B0D[40040000]        	cmp	cx, [d.dev]
   186 0000008D 7557                    	jne	short pwd_4
   187                                  
   188 0000008F 66A1[42040000]          	mov	ax, [d.ino]
   189 00000095 663B05[84040000]        	cmp	ax, [dd.ino]
   190                                  	;je	short prname
   191                                  	; 14/05/2022
   192 0000009C 7505                    	jne	short loop1
   193 0000009E E99D000000              	jmp	prname
   194                                  	
   195                                  	; do .. while
   196                                  loop1:
   197                                  	;;sys	_read, [file], _y, 10 ; Retro UNIX 386 v1
   198                                  	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[C6040000]        <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
   199                                  	;jc	short prname
   200                                  	; 14/05/2022
   201 000000BA 7247                    	jc	short pwd_5
   202                                  	;cmp	eax, 16	 ; cmp eax, 10
   203                                  	;;jb	short prname	
   204                                  	;jb	short pwd_5 ; 14/05/2022
   205 000000BC 09C0                    	or	eax, eax
   206                                  	;jz	short prname
   207 000000BE 7443                    	jz	short pwd_5 ; 14/05/2022
   208                                  	
   209                                  	; 14/05/2022
   210                                  	; while (dir.d_ino != d.st_ino);
   211 000000C0 66A1[C6040000]          	mov	ax, [jnum] 
   212                                  	;cmp	ax, [inum]
   213 000000C6 663B05[42040000]        	cmp	ax, [d.ino]
   214 000000CD 75D4                    	jne	short loop1
   215                                  pwd_3:
   216                                  	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
   217                                  	
   218                                  	;cmp	word [jnum], 1	; Retro UNIX 386 v1.2
   219                                  	;;cmp	word [jnum], 41 ; root dir inode number
   220                                  	;je	short ckroot
   221                                  	;call	cat
   222                                  	;sys	_chdir, dotdot
   223                                  	;jmp	short loop0
   224                                  
   225                                  	; 14/05/2022
   226 000000DC E8A4000000              	call	cat
   227 000000E1 E924FFFFFF              	jmp	loop0  ; for (;;)
   228                                  pwd_4:
   229                                  loop_2:
   230                                  	; 14/05/2022
   231                                  	; else do .. while
   232                                  	;sys	_read, [file], _y, 10 ; Retro UNIX 386 v1
   233                                  	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[C6040000]        <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
   234 000000FD 7204                    	jc	short pwd_5
   235 000000FF 21C0                    	and	eax, eax
   236 00000101 750A                    	jnz	short pwd_6
   237                                  pwd_5:
   238 00000103 B8[20020000]            	mov	eax, err_2
   239 00000108 E93CFFFFFF              	jmp	pmsg_exit
   240                                  pwd_6:
   241                                  	; stat(dir.d_name, &dd);
   242                                  	sys	_stat, yname, _dd
    63                              <1> 
    64                              <1> 
    65                              <1> 
    66                              <1>  %if %0 >= 2
    67 0000010D BB[C8040000]        <1>  mov ebx, %2
    68                              <1>  %if %0 >= 3
    69 00000112 B9[84040000]        <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
   243 0000011E 7305                    	jnc	short pwd_7
   244 00000120 E935FFFFFF              	jmp	error
   245                                  pwd_7:
   246                                  	; while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
   247 00000125 668B0D[42040000]        	mov	cx, [d.ino]
   248 0000012C 663B0D[84040000]        	cmp	cx, [dd.ino]
   249 00000133 75B1                    	jne	short loop_2
   250 00000135 663B05[40040000]        	cmp	ax, [d.dev]
   251 0000013C 75A8                    	jne	short loop_2
   252 0000013E EB8F                    	jmp	short pwd_3
   253                                  
   254                                  ;prname() {
   255                                  ;	name[off] = '\n';
   256                                  ;	write(1,name,off+1);
   257                                  ;	exit();
   258                                  
   259                                  prname:
   260                                  	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
   261                                  
   262 00000156 8B35[3C040000]          	mov	esi, [off]
   263                                  
   264                                  	; 14/05/2022
   265                                  	;if (off<0) off = 0;	
   266 0000015C 46                      	inc	esi ; -1 -> 0
   267 0000015D 7401                    	jz	short prname_crlf
   268 0000015F 4E                      	dec	esi
   269                                  prname_crlf:
   270                                  	;mov	byte [esi+name], 0Dh ; CR
   271 00000160 66C786[38020000]0D-     	mov	word [esi+name], 0A0Dh  ; CRLF 
   271 00000168 0A                 
   272                                  	;inc	dword [off]
   273 00000169 46                      	inc	esi
   274 0000016A 46                      	inc	esi
   275                                  	;mov	[off], esi
   276                                  	;sys	_write, 1, name, [off]
   277                                  	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
   278                                  _exit_:
   279                                  	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
   280                                  ;hang:
   281                                  ;	nop
   282                                  ;	jmp	short hang
   283                                  
   284                                  ;ckroot() {
   285                                  ;	int i, n;
   286                                  ;
   287                                  ;	if((n = stat(y.name,&x)) < 0) prname();
   288                                  ;	i = x.devn;
   289                                  ;	if((n = chdir(root)) < 0) prname();
   290                                  ;	if((file = open(root,0)) < 0) prname();
   291                                  ;loop:
   292                                  ;	if((n = read(file,&y,16)) < 16) prname();
   293                                  ;	if(y.jnum == 0) goto loop;
   294                                  ;	if((n = stat(y.name,&x)) < 0) prname();
   295                                  ;	if(x.devn != i) goto loop;
   296                                  ;	x.i[0] =& 060000;
   297                                  ;	if(x.i[0] != 040000) goto loop;
   298                                  ;	cat();
   299                                  ;	prname();
   300                                  
   301                                  ; 14/05/2022
   302                                  ;	; 06/05/2022
   303                                  ;	; Note: For Retro UNIX 386 v1 & v1.1 & v1.2,
   304                                  ;	;	mounted device is handled via 'mnti'
   305                                  ;	;	field which keeps (device 0) mounting
   306                                  ;	;	directory inode number for mounted
   307                                  ;	;	device (1). Device number (0 or 1) check
   308                                  ;	;	(via 'sysstat') is not possible
   309                                  ;	;	for current Retro UNIX kernel versions
   310                                  ;	;	because 'sysstat' output does not contain
   311                                  ;	;	device number.
   312                                  ;	;	***
   313                                  ;	;	As a temporary solution (before a next
   314                                  ;	;	kernel version with new 'sysstat'),
   315                                  ;	;	root dir entries are checked for a subdir 
   316                                  ;	;	('usr' & 'mnt' dirs for now) with root dir
   317                                  ;	;	inode number (41 or 1), if there is..
   318                                  ;	;	root directory is a real (device 0) root
   319                                  ;	;	directory; if not, device 1 root directory 
   320                                  ;	;	is mounted to a sub directory of device 0.
   321                                  ;	; 	(Also it must be verified after 'chdir /')
   322                                  ;	;
   323                                  ;	;	assumptions...
   324                                  ;	;	a sub dir with root inode number
   325                                  ;	;	dotdot / - chdir /
   326                                  ;	;	   no    -  no ----> root
   327                                  ;	;	   yes 	 - (yes) --> root, not checked
   328                                  ;	;	   no    - yes ----> mounted
   329                                  ;	;	   yes   - (no) ---> root, not checked
   330                                  ;
   331                                  ;ckroot:
   332                                  ;	; 06/05/2022
   333                                  ;	; check 'usr' directory
   334                                  ;	mov	edx, usr
   335                                  ;	call	statm 
   336                                  ;	jz	short ckroot_2	; root dir
   337                                  ;	; check 'mnt' directory
   338                                  ;	mov	edx, mnt
   339                                  ;	call	statm 
   340                                  ;	jz	short ckroot_2	; root dir
   341                                  ;
   342                                  ;	sys	_chdir, root
   343                                  ;	jc	short ckroot_2	; jmp short prname
   344                                  ;
   345                                  ;	; check 'usr' directory
   346                                  ;	mov	edx, usr
   347                                  ;	call	statm 
   348                                  ;	jz	short ckroot_1	; mounted
   349                                  ;	; check 'mnt' directory
   350                                  ;	mov	edx, mnt
   351                                  ;	call	statm 
   352                                  ;	jnz	short ckroot_2	; not mounted
   353                                  ;
   354                                  ;	; mounted
   355                                  ;ckroot_1:
   356                                  ;	; move mounting directory name
   357                                  ;	mov	esi, edx
   358                                  ;	mov	edi, yname
   359                                  ;	movsd
   360                                  ;	; concatenate (add to head of the path)
   361                                  ;	call	cat
   362                                  ;ckroot_2:
   363                                  ;	jmp	prname
   364                                  ;
   365                                  ;statm:
   366                                  ;	; 06/05/2022
   367                                  ;	sys	_stat, edx, _x
   368                                  ;	jc	short statm_1
   369                                  ;	cmp	word [inum], 1	; Retro UNIX 386 v1.2
   370                                  ;	;cmp	word [inum], 41 ; root dir inode number
   371                                  ;statm_1:
   372                                  ;	retn
   373                                  
   374                                  
   375                                  ;cat() {
   376                                  ;	int i, j;
   377                                  ;
   378                                  ;	i = -1;
   379                                  ;	while(y.name[++i] != 0);
   380                                  ;	if((off+i+2) > 511) prname();
   381                                  ;	for(j=off+1; j>=0; --j) name[j+i+1] = name[j];
   382                                  ;	off=i+off+1;
   383                                  ;	name[i] = root[0];
   384                                  ;	for(--i; i>=0; --i) name[i] = y.name[i];
   385                                  ;}
   386                                  
   387                                  cat:
   388 00000185 31DB                    	xor	ebx, ebx
   389 00000187 4B                      	dec	ebx ; i = -1
   390                                  cat_0:
   391 00000188 43                      	inc	ebx ; ++i
   392 00000189 80BB[C8040000]00        	cmp	byte [yname+ebx], 0
   393 00000190 77F6                    	ja	short cat_0
   394 00000192 89DA                    	mov	edx, ebx ; i
   395 00000194 8B0D[3C040000]          	mov	ecx, [off]
   396 0000019A 41                      	inc	ecx ; j = [off]+1
   397 0000019B 01CA                    	add	edx, ecx  ; edx = [off]+i+1
   398 0000019D 81FAFD010000            	cmp	edx, 511-2 ; (+ CRLF + 0) 
   399 000001A3 779B                    	ja	short prname  ; 14/05/2022
   400                                  	;;ja	short ckroot_2 ; jmp prname
   401                                  	;ja	short ckroot_err
   402 000001A5 BE[38020000]            	mov	esi, name
   403 000001AA 01CE                    	add	esi, ecx ; name[j]
   404 000001AC 89F7                    	mov	edi, esi
   405 000001AE 01DF                    	add	edi, ebx ; name[j+i]
   406 000001B0 47                      	inc	edi ; name[j+i+1]	
   407                                  cat_1:
   408                                  	;std
   409                                  	;rep	stosb
   410                                  	;cld
   411 000001B1 49                      	dec	ecx
   412 000001B2 7808                    	js	short cat_2
   413 000001B4 4E                      	dec	esi
   414 000001B5 8A06                    	mov	al, [esi]
   415 000001B7 4F                      	dec	edi
   416 000001B8 8807                    	mov	[edi], al
   417 000001BA EBF5                    	jmp	short cat_1
   418                                  cat_2:
   419 000001BC 8915[3C040000]          	mov	[off], edx ; [off] = i+[off]+1
   420 000001C2 C683[38020000]2F        	mov	byte [name+ebx], '/' ; name[i] = root[0]
   421                                  cat_3:
   422 000001C9 4B                      	dec	ebx ; --i
   423 000001CA 780E                    	js	short cat_4 ; 0 -> -1
   424                                  		 ; name[i] = yname[i]
   425 000001CC 8A83[C8040000]          	mov	al, [yname+ebx]
   426 000001D2 8883[38020000]          	mov	[name+ebx], al
   427 000001D8 EBEF                    	jmp	short cat_3 ; i >= 0
   428                                  cat_4:
   429 000001DA C3                      	retn
   430                                  
   431                                  ;-----------------------------------------------------------------
   432                                  
   433                                  print_msg:
   434                                  	; 08/05/2022
   435                                  	; eax = asciiz string address
   436 000001DB 89C2                    	mov	edx, eax
   437 000001DD 4A                      	dec	edx
   438                                  nextchr:
   439 000001DE 42                      	inc	edx
   440 000001DF 803A00                  	cmp	byte [edx], 0
   441 000001E2 77FA                    	ja	short nextchr
   442                                  	;cmp	[edx], 0Dh
   443                                  	;ja	short nextchr
   444 000001E4 29C2                    	sub	edx, eax
   445                                  	; edx = asciiz string length
   446                                  	;
   447                                  	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
   448                                  	;
   449 000001F4 C3                      	retn
   450                                  
   451                                  ;-----------------------------------------------------------------
   452                                  ;  data - initialized data
   453                                  ;-----------------------------------------------------------------
   454                                  
   455                                  ; 05/05/2022
   456                                  
   457 000001F5 2E                      dotdot:	db '.'
   458 000001F6 2E                      dot:	db '.'
   459 000001F7 00                      	db 0
   460                                  
   461                                  ; 06/05/2022
   462                                  nextline:
   463 000001F8 0D0A                    	db 0Dh, 0Ah
   464 000001FA 2F00                    root:	db '/', 0
   465                                  
   466                                  ; 14/05/2022
   467                                  ; default mounting directories (for current retro unix version)
   468                                  ;usr:	db 'usr', 0
   469                                  ;mnt:	db 'mnt', 0
   470                                  
   471                                  ; 14/05/2022
   472 000001FC 0D0A                    err_0:	db 0Dh, 0Ah
   473 000001FE 4572726F7221            	db "Error!"
   474 00000204 0D0A00                  	db 0dh, 0Ah, 0
   475                                  
   476 00000207 0D0A                    err_1:	db 0Dh, 0Ah
   477 00000209 7077643A2063616E20-     	db "pwd: can not open .."
   477 00000212 6E6F74206F70656E20-
   477 0000021B 2E2E               
   478 0000021D 0D0A00                  	db 0Dh, 0Ah, 0
   479 00000220 0D0A                    err_2:	db 0Dh, 0Ah
   480 00000222 72656164206572726F-     	db "read error in .."
   480 0000022B 7220696E202E2E     
   481 00000232 0D0A00                  	db 0Dh, 0Ah, 0
   482                                  
   483                                  ;-----------------------------------------------------------------
   484                                  ;  bss - uninitialized data
   485                                  ;-----------------------------------------------------------------	
   486                                  
   487 00000235 90<rep 3h>              align 4
   488                                  
   489                                  bss_start:
   490                                  
   491                                  ABSOLUTE bss_start
   492                                  
   493                                  ; 05/05/2022
   494                                  
   495 00000238 <res 200h>              name:	resb 512
   496                                  
   497 00000438 ????????                file:	resd 1
   498 0000043C ????????                off:	resd 1
   499                                  
   500                                  ; 14/05/2022
   501                                  idev:
   502 00000440 ????                    d.dev:	resw 1 ; device number (0 = root, 1 = mounted)
   503                                  ;dd.dev: resw 1
   504                                  
   505                                  _x:	; stat(us) buffer
   506                                  _d:	; 14/05/2022
   507                                  inum:
   508                                  d.ino:	; 14/05/2022
   509 00000442 ????                    	resw 1
   510                                  ximode:
   511                                  d.mode: ; 14/05/22022
   512 00000444 <res 40h>               	resb 64 ; Retro UNIX 386 v1.2
   513                                  	;resb 32 ; Retro UNIX 386 v1 & v1.1
   514                                  
   515                                  ; 14/05/2022
   516                                  _dd:	; stat(us) buffer
   517 00000484 ????                    dd.ino:	resw 1
   518                                  dd.mode:
   519 00000486 <res 40h>               	resb 64 ; Retro UNIX 386 v1.2
   520                                  	;resb 32 ; Retro UNIX 386 v1 & v1.1
   521                                  
   522                                  _y:	; directory entry buffer
   523 000004C6 ????                    jnum:	resw 1
   524 000004C8 <res Eh>                yname:	resb 14 ; Retro UNIX 386 v1.1 & v1.2
   525                                  	;resb 8 ; Retro UNIX 386 v1 (unix v1)
   526 000004D6 ????                    yzero:	resw 1
   527                                  
   528                                  ;-----------------------------------------------------------------
   529                                  ; Original UNIX v7 - /bin/pwd file - c source code (pwd.c)
   530                                  ;-----------------------------------------------------------------
   531                                  ;
   532                                  ;/*
   533                                  ; * Print working (current) directory
   534                                  ; */
   535                                  ;#include <stdio.h>
   536                                  ;#include <sys/param.h>
   537                                  ;#include <sys/stat.h>
   538                                  ;#include <sys/dir.h>
   539                                  ;
   540                                  ;char	dot[]	= ".";
   541                                  ;char	dotdot[] = "..";
   542                                  ;char	name[512];
   543                                  ;int	file;
   544                                  ;int	off	= -1;
   545                                  ;struct	stat	d, dd;
   546                                  ;struct	direct	dir;
   547                                  ;
   548                                  ;main()
   549                                  ;{
   550                                  ;	int rdev, rino;
   551                                  ;
   552                                  ;	stat("/", &d);
   553                                  ;	rdev = d.st_dev;
   554                                  ;	rino = d.st_ino;
   555                                  ;	for (;;) {
   556                                  ;		stat(dot, &d);
   557                                  ;		if (d.st_ino==rino && d.st_dev==rdev)
   558                                  ;			prname();
   559                                  ;		if ((file = open(dotdot,0)) < 0) {
   560                                  ;			fprintf(stderr,"pwd: cannot open ..\n");
   561                                  ;			exit(1);
   562                                  ;		}
   563                                  ;		fstat(file, &dd);
   564                                  ;		chdir(dotdot);
   565                                  ;		if(d.st_dev == dd.st_dev) {
   566                                  ;			if(d.st_ino == dd.st_ino)
   567                                  ;				prname();
   568                                  ;			do
   569                                  ;				if (read(file, (char *)&dir, sizeof(dir)) < sizeof(dir)) {
   570                                  ;					fprintf(stderr,"read error in ..\n");
   571                                  ;					exit(1);
   572                                  ;				}
   573                                  ;			while (dir.d_ino != d.st_ino);
   574                                  ;		}
   575                                  ;		else do {
   576                                  ;				if(read(file, (char *)&dir, sizeof(dir)) < sizeof(dir)) {
   577                                  ;					fprintf(stderr,"read error in ..\n");
   578                                  ;					exit(1);
   579                                  ;				}
   580                                  ;				stat(dir.d_name, &dd);
   581                                  ;			} while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
   582                                  ;		close(file);
   583                                  ;		cat();
   584                                  ;	}
   585                                  ;}
   586                                  ;
   587                                  ;prname()
   588                                  ;{
   589                                  ;	write(1, "/", 1);
   590                                  ;	if (off<0)
   591                                  ;		off = 0;
   592                                  ;	name[off] = '\n';
   593                                  ;	write(1, name, off+1);
   594                                  ;	exit(0);
   595                                  ;}
   596                                  ;
   597                                  ;cat()
   598                                  ;{
   599                                  ;	register i, j;
   600                                  ;
   601                                  ;	i = -1;
   602                                  ;	while (dir.d_name[++i] != 0);
   603                                  ;	if ((off+i+2) > 511)
   604                                  ;		prname();
   605                                  ;	for(j=off+1; j>=0; --j)
   606                                  ;		name[j+i+1] = name[j];
   607                                  ;	off=i+off+1;
   608                                  ;	name[i] = '/';
   609                                  ;	for(--i; i>=0; --i)
   610                                  ;		name[i] = dir.d_name[i];
   611                                  ;}
   612                                  
   613                                  ; 05/05/2022
   614                                  
   615                                  ;-----------------------------------------------------------------
   616                                  ; Original UNIX v5 - /usr/bin/pwd file - c source code (pwd.c)
   617                                  ;-----------------------------------------------------------------
   618                                  ;
   619                                  ;char dot[] ".";
   620                                  ;char dotdot[] "..";
   621                                  ;char root[] "/";
   622                                  ;char name[512];
   623                                  ;int file, off -1;
   624                                  ;struct statb {int devn, inum, i[18];}x;
   625                                  ;struct entry { int jnum; char name[16];}y;
   626                                  ;
   627                                  ;main() {
   628                                  ;	int n;
   629                                  ;
   630                                  ;loop0:
   631                                  ;	stat(dot, &x);
   632                                  ;	if((file = open(dotdot,0)) < 0) prname();
   633                                  ;loop1:
   634                                  ;	if((n = read(file,&y,16)) < 16) prname();
   635                                  ;	if(y.jnum != x.inum)goto loop1;
   636                                  ;	close(file);
   637                                  ;	if(y.jnum == 1) ckroot();
   638                                  ;	cat();
   639                                  ;	chdir(dotdot);
   640                                  ;	goto loop0;
   641                                  ;}
   642                                  ;ckroot() {
   643                                  ;	int i, n;
   644                                  ;
   645                                  ;	if((n = stat(y.name,&x)) < 0) prname();
   646                                  ;	i = x.devn;
   647                                  ;	if((n = chdir(root)) < 0) prname();
   648                                  ;	if((file = open(root,0)) < 0) prname();
   649                                  ;loop:
   650                                  ;	if((n = read(file,&y,16)) < 16) prname();
   651                                  ;	if(y.jnum == 0) goto loop;
   652                                  ;	if((n = stat(y.name,&x)) < 0) prname();
   653                                  ;	if(x.devn != i) goto loop;
   654                                  ;	x.i[0] =& 060000;
   655                                  ;	if(x.i[0] != 040000) goto loop;
   656                                  ;	cat();
   657                                  ;	prname();
   658                                  ;}
   659                                  ;prname() {
   660                                  ;	name[off] = '\n';
   661                                  ;	write(1,name,off+1);
   662                                  ;	exit();
   663                                  ;}
   664                                  ;cat() {
   665                                  ;	int i, j;
   666                                  ;
   667                                  ;	i = -1;
   668                                  ;	while(y.name[++i] != 0);
   669                                  ;	if((off+i+2) > 511) prname();
   670                                  ;	for(j=off+1; j>=0; --j) name[j+i+1] = name[j];
   671                                  ;	off=i+off+1;
   672                                  ;	name[i] = root[0];
   673                                  ;	for(--i; i>=0; --i) name[i] = y.name[i];
   674                                  ;}
