     1                                  ; ****************************************************************************
     2                                  ; pwd8086.s (pwd0.s) - by Erdogan Tan - 05/05/2022
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Retro UNIX 8086 v1 - pwd - print working directory pathname
     5                                  ;
     6                                  ; [ Last Modification: 11/05/2022 ]
     7                                  ;
     8                                  ; Derived from (original) UNIX v5 '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                                  
    63                                  ;%macro sys 1-4
    64                                  ;   ; 03/09/2015
    65                                  ;   ; 13/04/2015
    66                                  ;   ; Retro UNIX 386 v1 system call.
    67                                  ;   %if %0 >= 2   
    68                                  ;       mov ebx, %2
    69                                  ;       %if %0 >= 3    
    70                                  ;           mov ecx, %3
    71                                  ;           ;%if %0 = 4
    72                                  ;           %if	%0 >= 4 ; 11/03/2022
    73                                  ;		mov edx, %4
    74                                  ;           %endif
    75                                  ;       %endif
    76                                  ;   %endif
    77                                  ;   mov eax, %1
    78                                  ;   int 30h
    79                                  ;%endmacro
    80                                  
    81                                  %macro sys 1-4
    82                                      ; Retro UNIX 8086 v1 system call.
    83                                      %if %0 >= 2   
    84                                          mov bx, %2
    85                                          %if %0 >= 3
    86                                              mov cx, %3
    87                                              %if %0 >= 4
    88                                                 mov dx, %4
    89                                              %endif
    90                                          %endif
    91                                      %endif
    92                                      mov ax, %1
    93                                      int 20h
    94                                  %endmacro
    95                                  
    96                                  ;; Retro UNIX 386 v1 system call format:
    97                                  ;; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
    98                                  
    99                                  ;; 11/03/2022
   100                                  ;; Note: Above 'sys' macro has limitation about register positions;
   101                                  ;;	ebx, ecx, edx registers must not be used after their
   102                                  ;;	positions in sys macro.
   103                                  ;; for example:
   104                                  ;;	'sys _write, 1, msg, ecx' is defective, because
   105                                  ;;	 ecx will be used/assigned before edx in 'sys' macro.
   106                                  ;; correct order may be:
   107                                  ;;	'sys _write, 1, msg, eax ; (eax = byte count)
   108                                  
   109                                  ; Retro UNIX 8086 v1 system call format:
   110                                  ; sys systemcall (ax) <arg1 (bx)>, <arg2 (cx)>, <arg3 (dx)>
   111                                  
   112                                  ; ----------------------------------------------------------------------------
   113                                  
   114                                  [BITS 16] ; 16-bit intructions (for 8086/x86 real mode)
   115                                  
   116                                  [ORG 0] 
   117                                  
   118                                  START_CODE:
   119                                  	; 11/05/2022
   120                                  	; 10/05/2022
   121                                  	; 09/05/2022
   122                                  	; 06/05/2022 (16 bit version) -ax,bx,cx,dx-
   123                                  	; 06/05/2022 (32 bit version) -eax,ebx,ecx,edx-
   124                                  	; 05/05/2022
   125                                  
   126                                  ;main() {
   127                                  ;	int n;
   128                                  
   129                                  	;  clear (reset) stack (not necessary)
   130 00000000 59                      	pop	cx ; cx = number of arguments
   131                                  pwd_0:
   132 00000001 58                      	pop	ax ; ax = argument 0 = executable file name
   133 00000002 E2FD                    	loop	pwd_0
   134                                  
   135                                  	;mov	byte [y.zero], 0 ; (not necessary)
   136                                  			; (because Retro UNIX kernel
   137                                  			; clears bss -memory page- while
   138                                  			; assigning it to program)
   139                                  	;mov	word [off], 0
   140                                  
   141                                  	; 06/05/2022
   142 00000004 FF0E[B203]              	dec	word [off] ; -1
   143                                  
   144                                  ;loop0:
   145                                  ;	stat(dot, &x);
   146                                  ;	if((file = open(dotdot,0)) < 0) prname();
   147                                  
   148                                  loop0:
   149                                  	;sys	_stat, dot, _x
   150                                  
   151                                  	; 11/05/2022
   152                                  	;stat(dot, &d);
   153                                  	;if (d.st_ino==rino && d.st_dev==rdev)
   154                                  	;	prname();
   155                                  	
   156                                  	sys	_stat, dot, _d
    82                              <1> 
    83                              <1>  %if %0 >= 2
    84 00000008 BB[6901]            <1>  mov bx, %2
    85                              <1>  %if %0 >= 3
    86 0000000B B9[B803]            <1>  mov cx, %3
    87                              <1>  %if %0 >= 4
    88                              <1>  mov dx, %4
    89                              <1>  %endif
    90                              <1>  %endif
    91                              <1>  %endif
    92 0000000E B81200              <1>  mov ax, %1
    93 00000011 CD20                <1>  int 20h
   157 00000013 7229                    	jc	short error
   158                                  
   159 00000015 833E[B803]29            	cmp	word [d.ino], 41 ; d.st_ino == rino
   160 0000001A 7504                    	jne	short pwd_1
   161 0000001C 09C0                    	or	ax, ax ; [d.dev] ; && d.st_dev==rdev
   162                                  	;jz	short prname ; root device, root dir
   163 0000001E 741B                    	jz	short pwd_p ; 11/05/2022
   164                                  pwd_1:
   165 00000020 A3[B403]                	mov	[d.dev], ax
   166                                  
   167                                  	sys	_open, dotdot, 0  ; open for read
    82                              <1> 
    83                              <1>  %if %0 >= 2
    84 00000023 BB[6801]            <1>  mov bx, %2
    85                              <1>  %if %0 >= 3
    86 00000026 B90000              <1>  mov cx, %3
    87                              <1>  %if %0 >= 4
    88                              <1>  mov dx, %4
    89                              <1>  %endif
    90                              <1>  %endif
    91                              <1>  %endif
    92 00000029 B80500              <1>  mov ax, %1
    93 0000002C CD20                <1>  int 20h
   168                                  	;jc	short prname
   169                                  	; 11/05/2022
   170 0000002E 7313                    	jnc	short pwd_2
   171                                  
   172                                  	; 11/05/2022
   173                                  pwd_err:
   174 00000030 B8[8201]                	mov	ax, err_1
   175                                  pmsg_exit:
   176 00000033 E81A01                  	call	print_msg
   177                                  exit:
   178                                  	sys	_exit ; exit(1);
    82                              <1> 
    83                              <1>  %if %0 >= 2
    84                              <1>  mov bx, %2
    85                              <1>  %if %0 >= 3
    86                              <1>  mov cx, %3
    87                              <1>  %if %0 >= 4
    88                              <1>  mov dx, %4
    89                              <1>  %endif
    90                              <1>  %endif
    91                              <1>  %endif
    92 00000036 B80100              <1>  mov ax, %1
    93 00000039 CD20                <1>  int 20h
   179                                  ;hang:
   180                                  ;	nop
   181                                  ;	jmp	short hang
   182                                  
   183                                  	
   184                                  pwd_p:	; 11/05/2022
   185 0000003B E99C00                  	jmp	prname
   186                                  	
   187                                  error:	; 11/05/2022
   188 0000003E B8[7701]                	mov	ax, err_0
   189 00000041 EBED                    	jmp	short pwd_err
   190                                  
   191                                  pwd_2:	
   192                                  
   193                                  ;loop1:
   194                                  ;	if((n = read(file,&y,16)) < 16) prname();
   195                                  ;	if(y.jnum != x.inum)goto loop1;
   196                                  ;	close(file);
   197                                  ;	if(y.jnum == 1) ckroot();
   198                                  ;	cat();
   199                                  ;	chdir(dotdot);
   200                                  ;	goto loop0;
   201                                  ;}
   202                                  
   203 00000043 A3[B003]                	mov	[file], ax
   204                                  
   205                                  	; 11/05/2022
   206                                  	;fstat(file, &dd);
   207                                  	;chdir(dotdot);
   208                                  
   209                                  	sys	_fstat, ax, _dd
    82                              <1> 
    83                              <1>  %if %0 >= 2
    84 00000046 89C3                <1>  mov bx, %2
    85                              <1>  %if %0 >= 3
    86 00000048 B9[DA03]            <1>  mov cx, %3
    87                              <1>  %if %0 >= 4
    88                              <1>  mov dx, %4
    89                              <1>  %endif
    90                              <1>  %endif
    91                              <1>  %endif
    92 0000004B B81C00              <1>  mov ax, %1
    93 0000004E CD20                <1>  int 20h
   210 00000050 72EC                    	jc	short error
   211                                  
   212 00000052 A3[B603]                	mov	[dd.dev], ax
   213 00000055 89C1                    	mov	cx, ax
   214                                  	
   215                                  	sys	_chdir, dotdot
    82                              <1> 
    83                              <1>  %if %0 >= 2
    84 00000057 BB[6801]            <1>  mov bx, %2
    85                              <1>  %if %0 >= 3
    86                              <1>  mov cx, %3
    87                              <1>  %if %0 >= 4
    88                              <1>  mov dx, %4
    89                              <1>  %endif
    90                              <1>  %endif
    91                              <1>  %endif
    92 0000005A B80C00              <1>  mov ax, %1
    93 0000005D CD20                <1>  int 20h
   216 0000005F 72DD                    	jc	short error
   217                                  
   218 00000061 3B0E[B403]              	cmp	cx, [d.dev]
   219 00000065 7536                    	jne	short pwd_4
   220                                  
   221 00000067 A1[B803]                	mov	ax, [d.ino]
   222 0000006A 3B06[DA03]              	cmp	ax, [dd.ino]
   223 0000006E 746A                    	je	short prname
   224                                  	
   225                                  	; do .. while
   226                                  loop1:
   227                                  	sys	_read, [file], _y, 10 ; Retro UNIX 386 v1
    82                              <1> 
    83                              <1>  %if %0 >= 2
    84 00000070 8B1E[B003]          <1>  mov bx, %2
    85                              <1>  %if %0 >= 3
    86 00000074 B9[FC03]            <1>  mov cx, %3
    87                              <1>  %if %0 >= 4
    88 00000077 BA0A00              <1>  mov dx, %4
    89                              <1>  %endif
    90                              <1>  %endif
    91                              <1>  %endif
    92 0000007A B80300              <1>  mov ax, %1
    93 0000007D CD20                <1>  int 20h
   228                                  	;;sys	_read, [file], _y, 16 ; Retro UNIX 386 v1.1 & v1.2
   229                                  	;jc	short prname
   230                                  	; 11/05/2022
   231 0000007F 7231                    	jc	short pwd_5
   232                                  	;cmp	ax, 10	 ; cmp eax, 16
   233                                  	;;jb	short prname	
   234                                  	;jb	short pwd_5 ; 11/05/2022
   235 00000081 09C0                    	or	ax, ax
   236                                  	;jz	short prname
   237 00000083 742D                    	jz	short pwd_5 ; 11/05/2022
   238                                  	
   239                                  	; 11/05/2022
   240                                  	; while (dir.d_ino != d.st_ino);
   241 00000085 A1[FC03]                	mov	ax, [jnum]	   
   242                                  	;cmp	ax, [inum]
   243 00000088 3B06[B803]              	cmp	ax, [d.ino]
   244 0000008C 75E2                    	jne	short loop1
   245                                  
   246                                  pwd_3:
   247                                  	sys	_close, [file]
    82                              <1> 
    83                              <1>  %if %0 >= 2
    84 0000008E 8B1E[B003]          <1>  mov bx, %2
    85                              <1>  %if %0 >= 3
    86                              <1>  mov cx, %3
    87                              <1>  %if %0 >= 4
    88                              <1>  mov dx, %4
    89                              <1>  %endif
    90                              <1>  %endif
    91                              <1>  %endif
    92 00000092 B80600              <1>  mov ax, %1
    93 00000095 CD20                <1>  int 20h
   248                                  	
   249                                  	;;cmp	word [jnum], 1	; Retro UNIX 386 v1.2
   250                                  	;cmp	word [jnum], 41 ; root dir inode number
   251                                  	;je	short ckroot
   252                                  	;call	cat
   253                                  	;sys	_chdir, dotdot
   254                                  	;jmp	short loop0
   255                                  
   256                                  	; 11/05/2022
   257 00000097 E87000                  	call	cat
   258 0000009A E96BFF                  	jmp	loop0  ; for (;;)
   259                                  
   260                                  pwd_4:
   261                                  loop_2:
   262                                  	; 11/05/2022
   263                                  	; else do .. while
   264                                  	sys	_read, [file], _y, 10 ; Retro UNIX 386 v1
    82                              <1> 
    83                              <1>  %if %0 >= 2
    84 0000009D 8B1E[B003]          <1>  mov bx, %2
    85                              <1>  %if %0 >= 3
    86 000000A1 B9[FC03]            <1>  mov cx, %3
    87                              <1>  %if %0 >= 4
    88 000000A4 BA0A00              <1>  mov dx, %4
    89                              <1>  %endif
    90                              <1>  %endif
    91                              <1>  %endif
    92 000000A7 B80300              <1>  mov ax, %1
    93 000000AA CD20                <1>  int 20h
   265                                  	;sys	_read, [file], _y, 16 ; Retro UNIX 386 v1.1 & v1.2
   266 000000AC 7204                    	jc	short pwd_5
   267 000000AE 21C0                    	and	ax, ax
   268 000000B0 7506                    	jnz	short pwd_6
   269                                  pwd_5
   269          ******************       warning: label alone on a line without a colon might be in error [-w+label-orphan]
   270 000000B2 B8[9B01]                	mov	ax, err_2
   271 000000B5 E97BFF                  	jmp	pmsg_exit
   272                                  pwd_6:
   273                                  	; stat(dir.d_name, &dd);
   274                                  	sys	_stat, yname, _dd
    82                              <1> 
    83                              <1>  %if %0 >= 2
    84 000000B8 BB[FE03]            <1>  mov bx, %2
    85                              <1>  %if %0 >= 3
    86 000000BB B9[DA03]            <1>  mov cx, %3
    87                              <1>  %if %0 >= 4
    88                              <1>  mov dx, %4
    89                              <1>  %endif
    90                              <1>  %endif
    91                              <1>  %endif
    92 000000BE B81200              <1>  mov ax, %1
    93 000000C1 CD20                <1>  int 20h
   275 000000C3 7303                    	jnc	short pwd_7
   276 000000C5 E976FF                  	jmp	error
   277                                  pwd_7:
   278                                  	; while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
   279 000000C8 8B0E[B803]              	mov	cx, [d.ino]
   280 000000CC 3B0E[DA03]              	cmp	cx, [dd.ino]
   281 000000D0 75CB                    	jne	short loop_2
   282 000000D2 3B06[B403]              	cmp	ax, [d.dev]
   283 000000D6 75C5                    	jne	short loop_2
   284 000000D8 EBB4                    	jmp	short pwd_3 	
   285                                  
   286                                  ;prname() {
   287                                  ;	name[off] = '\n';
   288                                  ;	write(1,name,off+1);
   289                                  ;	exit();
   290                                  
   291                                  prname:
   292                                  	sys	_write, 1, nextline, 3	; 06/05/2022
    82                              <1> 
    83                              <1>  %if %0 >= 2
    84 000000DA BB0100              <1>  mov bx, %2
    85                              <1>  %if %0 >= 3
    86 000000DD B9[6B01]            <1>  mov cx, %3
    87                              <1>  %if %0 >= 4
    88 000000E0 BA0300              <1>  mov dx, %4
    89                              <1>  %endif
    90                              <1>  %endif
    91                              <1>  %endif
    92 000000E3 B80400              <1>  mov ax, %1
    93 000000E6 CD20                <1>  int 20h
   293                                  
   294 000000E8 8B36[B203]              	mov	si, [off]
   295                                  	
   296                                  	;if (off<0) off = 0;	
   297 000000EC 46                      	inc	si ; -1 -> 0
   298 000000ED 7401                    	jz	short prname_crlf
   299 000000EF 4E                      	dec	si
   300                                  prname_crlf:
   301                                  	;mov	byte [si+name], 0Dh ; CR
   302 000000F0 C784[B001]0D0A          	mov	word [si+name], 0A0Dh  ; CRLF 
   303                                  	;inc	dword [off]
   304 000000F6 46                      	inc	si
   305 000000F7 46                      	inc	si
   306                                  	;mov	[off], si
   307                                  	;sys	_write, 1, name, [off]
   308                                  	sys	_write, 1, name, si
    82                              <1> 
    83                              <1>  %if %0 >= 2
    84 000000F8 BB0100              <1>  mov bx, %2
    85                              <1>  %if %0 >= 3
    86 000000FB B9[B001]            <1>  mov cx, %3
    87                              <1>  %if %0 >= 4
    88 000000FE 89F2                <1>  mov dx, %4
    89                              <1>  %endif
    90                              <1>  %endif
    91                              <1>  %endif
    92 00000100 B80400              <1>  mov ax, %1
    93 00000103 CD20                <1>  int 20h
   309                                  _exit_:
   310                                  	sys	_exit  ; exit(0);
    82                              <1> 
    83                              <1>  %if %0 >= 2
    84                              <1>  mov bx, %2
    85                              <1>  %if %0 >= 3
    86                              <1>  mov cx, %3
    87                              <1>  %if %0 >= 4
    88                              <1>  mov dx, %4
    89                              <1>  %endif
    90                              <1>  %endif
    91                              <1>  %endif
    92 00000105 B80100              <1>  mov ax, %1
    93 00000108 CD20                <1>  int 20h
   311                                  ;hang:
   312                                  ;	nop
   313                                  ;	jmp	short hang
   314                                  
   315                                  ;ckroot() {
   316                                  ;	int i, n;
   317                                  ;
   318                                  ;	if((n = stat(y.name,&x)) < 0) prname();
   319                                  ;	i = x.devn;
   320                                  ;	if((n = chdir(root)) < 0) prname();
   321                                  ;	if((file = open(root,0)) < 0) prname();
   322                                  ;loop:
   323                                  ;	if((n = read(file,&y,16)) < 16) prname();
   324                                  ;	if(y.jnum == 0) goto loop;
   325                                  ;	if((n = stat(y.name,&x)) < 0) prname();
   326                                  ;	if(x.devn != i) goto loop;
   327                                  ;	x.i[0] =& 060000;
   328                                  ;	if(x.i[0] != 040000) goto loop;
   329                                  ;	cat();
   330                                  ;	prname();
   331                                  
   332                                  ;	; 10/05/2022
   333                                  ;	; 09/05/2022 (new -retro unix 8286 v1- kernel)
   334                                  ;	; (sysstat returns with device number in ax)
   335                                  ;ckroot:
   336                                  ;	; 09/05/2022	
   337                                  ;	sys	_stat, yname, _x
   338                                  ;	jc	short ckroot_err
   339                                  ;	mov	[idev], ax ; device number
   340                                  ;	sys	_chdir, root
   341                                  ;	jc	short ckroot_err
   342                                  ;	sys	_open, root, 0 ; open root dir for read
   343                                  ;	jc	short ckroot_err
   344                                  ;	; 10/05/2022
   345                                  ;	mov	[file], ax
   346                                  ;ckroot_loop:
   347                                  ;	sys	_read, [file], _y, 10
   348                                  ;			; read one dir entry	
   349                                  ;	jc	short ckroot_err
   350                                  ;	; 10/05/2022
   351                                  ;	or	ax, ax
   352                                  ;	jz	short ckroot_err	
   353                                  ;	cmp	word [jnum], 0
   354                                  ;	jna	short ckroot_loop
   355                                  ;	sys	_stat, yname, _x
   356                                  ;	jc	short ckroot_err
   357                                  ;	cmp	ax, [idev] ; same device number ?
   358                                  ;	jne	short ckroot_loop ; no
   359                                  ;	; 10/05/2022
   360                                  ;	test	byte [ximode+1], 40h ; directory ?
   361                                  ;	jz	short ckroot_loop
   362                                  ;	;
   363                                  ;	call	cat	
   364                                  ;	;
   365                                  ;ckroot_err:
   366                                  ;	jmp	prname
   367                                  	
   368                                  ;	; 06/05/2022
   369                                  ;	; Note: For Retro UNIX 386 v1 & v1.1 & v1.2,
   370                                  ;	;	mounted device is handled via 'mnti'
   371                                  ;	;	field which keeps (device 0) mounting
   372                                  ;	;	directory inode number for mounted
   373                                  ;	;	device (1). Device number (0 or 1) check
   374                                  ;	;	(via 'sysstat') is not possible
   375                                  ;	;	for current Retro UNIX kernel versions
   376                                  ;	;	because 'sysstat' output does not contain
   377                                  ;	;	device number.
   378                                  ;	;	***
   379                                  ;	;	As a temporary solution (before a next
   380                                  ;	;	kernel version with new 'sysstat'),
   381                                  ;	;	root dir entries are checked for a subdir 
   382                                  ;	;	('usr' & 'mnt' dirs for now) with root dir
   383                                  ;	;	inode number (41 or 1), if there is..
   384                                  ;	;	root directory is a real (device 0) root
   385                                  ;	;	directory; if not, device 1 root directory 
   386                                  ;	;	is mounted to a sub directory of device 0.
   387                                  ;	; 	(Also it must be verified after 'chdir /')
   388                                  ;	;
   389                                  ;	;	assumptions...
   390                                  ;	;	a sub dir with root inode number	
   391                                  ;	;	dotdot / - chdir /
   392                                  ;	;	   no    -  no ----> root
   393                                  ;	;	   yes 	 - (yes) --> root, not checked
   394                                  ;	;	   no    - yes ----> mounted
   395                                  ;	;	   yes   - (no) ---> root, not checked				  
   396                                  ;
   397                                  ;ckroot:
   398                                  ;	; 06/05/2022
   399                                  ;	; check 'usr' directory
   400                                  ;	mov	dx, usr
   401                                  ;	call	statm 
   402                                  ;	jz	short ckroot_2	; root dir
   403                                  ;	; check 'mnt' directory
   404                                  ;	mov	dx, mnt
   405                                  ;	call	statm 
   406                                  ;	jz	short ckroot_2	; root dir
   407                                  ;
   408                                  ;	sys	_chdir, root
   409                                  ;	jc	short ckroot_2	; jmp short prname
   410                                  ;
   411                                  ;	; check 'usr' directory
   412                                  ;	mov	dx, usr
   413                                  ;	call	statm 
   414                                  ;	jz	short ckroot_1	; mounted
   415                                  ;	; check 'mnt' directory
   416                                  ;	mov	dx, mnt
   417                                  ;	call	statm 
   418                                  ;	jnz	short ckroot_2	; not mounted
   419                                  ;
   420                                  ;	; mounted
   421                                  ;ckroot_1:
   422                                  ;	; move mounting directory name
   423                                  ;	mov	si, dx
   424                                  ;	mov	di, yname
   425                                  ;	movsw
   426                                  ;	movsw
   427                                  ;	; concatenate (add to head of the path)
   428                                  ;	call	cat
   429                                  ;ckroot_2:
   430                                  ;	jmp	prname
   431                                  ;
   432                                  ;statm:
   433                                  ;	; 06/05/2022
   434                                  ;	sys	_stat, dx, _x
   435                                  ;	jc	short statm_1
   436                                  ;	;cmp	word [inum], 1	; Retro UNIX 386 v1.2
   437                                  ;	cmp	word [inum], 41 ; root dir inode number
   438                                  ;statm_1:
   439                                  ;	retn
   440                                  
   441                                  ;cat() {
   442                                  ;	int i, j;
   443                                  ;
   444                                  ;	i = -1;
   445                                  ;	while(y.name[++i] != 0);
   446                                  ;	if((off+i+2) > 511) prname();
   447                                  ;	for(j=off+1; j>=0; --j) name[j+i+1] = name[j];
   448                                  ;	off=i+off+1;
   449                                  ;	name[i] = root[0];
   450                                  ;	for(--i; i>=0; --i) name[i] = y.name[i];
   451                                  ;}
   452                                  
   453                                  cat:
   454 0000010A 31DB                    	xor	bx, bx
   455 0000010C 4B                      	dec	bx ; i = -1
   456                                  cat_0:
   457 0000010D 43                      	inc	bx ; ++i
   458 0000010E 80BF[FE03]00            	cmp	byte [yname+bx], 0
   459 00000113 77F8                    	ja	short cat_0
   460 00000115 89DA                    	mov	dx, bx ; i
   461 00000117 8B0E[B203]              	mov	cx, [off]
   462 0000011B 41                      	inc	cx ; j = [off]+1
   463 0000011C 01CA                    	add	dx, cx  ; dx = [off]+i+1
   464 0000011E 81FAFD01                	cmp	dx, 511-2 ; (+ CRLF + 0) 
   465 00000122 77B6                    	ja	short prname
   466                                  	;;ja	short ckroot_2 ; jmp prname
   467                                  	;ja	short ckroot_err ; 09/05/2022
   468 00000124 BE[B001]                	mov	si, name
   469 00000127 01CE                    	add	si, cx ; name[j]
   470 00000129 89F7                    	mov	di, si
   471 0000012B 01DF                    	add	di, bx ; name[j+i]
   472 0000012D 47                      	inc	di ; name[j+i+1]	
   473                                  cat_1:
   474                                  	;std
   475                                  	;rep	stosb
   476                                  	;cld
   477 0000012E 49                      	dec	cx
   478 0000012F 7808                    	js	short cat_2
   479 00000131 4E                      	dec	si
   480 00000132 8A04                    	mov	al, [si]
   481 00000134 4F                      	dec	di
   482 00000135 8805                    	mov	[di], al
   483 00000137 EBF5                    	jmp	short cat_1
   484                                  cat_2:
   485 00000139 8916[B203]              	mov	[off], dx ; [off] = i+[off]+1
   486 0000013D C687[B001]2F            	mov	byte [name+bx], '/' ; name[i] = '/';
   487                                  cat_3:
   488 00000142 4B                      	dec	bx ; --i
   489 00000143 780A                    	js	short cat_4 ; 0 -> -1
   490                                  		 ; name[i] = yname[i]
   491 00000145 8A87[FE03]              	mov	al, [yname+bx]
   492 00000149 8887[B001]              	mov	[name+bx], al
   493 0000014D EBF3                    	jmp	short cat_3 ; i >= 0
   494                                  cat_4:
   495 0000014F C3                      	retn
   496                                  
   497                                  ;-----------------------------------------------------------------
   498                                  
   499                                  print_msg:
   500                                  	; ax = asciiz string address
   501 00000150 89C6                    	mov	si, ax
   502 00000152 4E                      	dec	si
   503                                  nextchr:
   504 00000153 46                      	inc	si
   505 00000154 803C00                  	cmp	byte [si], 0
   506 00000157 77FA                    	ja	short nextchr
   507                                  	;cmp	[si], 0Dh
   508                                  	;ja	short nextchr
   509 00000159 29C6                    	sub	si, ax
   510                                  	; si = asciiz string length
   511                                  	;
   512                                  	sys	_write, 1, ax, si
    82                              <1> 
    83                              <1>  %if %0 >= 2
    84 0000015B BB0100              <1>  mov bx, %2
    85                              <1>  %if %0 >= 3
    86 0000015E 89C1                <1>  mov cx, %3
    87                              <1>  %if %0 >= 4
    88 00000160 89F2                <1>  mov dx, %4
    89                              <1>  %endif
    90                              <1>  %endif
    91                              <1>  %endif
    92 00000162 B80400              <1>  mov ax, %1
    93 00000165 CD20                <1>  int 20h
   513                                  	;
   514 00000167 C3                      	retn
   515                                  
   516                                  ;-----------------------------------------------------------------
   517                                  ;  data - initialized data
   518                                  ;-----------------------------------------------------------------
   519                                  
   520                                  ; 05/05/2022
   521                                  
   522 00000168 2E                      dotdot:	db '.'
   523 00000169 2E                      dot:	db '.'
   524 0000016A 00                      	db 0
   525                                  
   526                                  ; 06/05/2022
   527                                  nextline:
   528 0000016B 0D0A                    	db 0Dh, 0Ah
   529 0000016D 2F00                    root:	db '/', 0
   530                                  
   531                                  ; default mounting directories (for current retro unix version)
   532 0000016F 75737200                usr:	db 'usr', 0
   533 00000173 6D6E7400                mnt:	db 'mnt', 0
   534                                  
   535                                  ; 11/05/2022
   536 00000177 0D0A                    err_0:	db 0Dh, 0Ah
   537 00000179 4572726F7221            	db "Error!"
   538 0000017F 0D0A00                  	db 0dh, 0Ah, 0
   539                                  
   540 00000182 0D0A                    err_1:	db 0Dh, 0Ah
   541 00000184 7077643A2063616E20-     	db "pwd: can not open .."
   541 0000018D 6E6F74206F70656E20-
   541 00000196 2E2E               
   542 00000198 0D0A00                  	db 0Dh, 0Ah, 0
   543 0000019B 0D0A                    err_2:	db 0Dh, 0Ah
   544 0000019D 72656164206572726F-     	db "read error in .."
   544 000001A6 7220696E202E2E     
   545 000001AD 0D0A00                  	db 0Dh, 0Ah, 0
   546                                  ;-----------------------------------------------------------------
   547                                  ;  bss - uninitialized data
   548                                  ;-----------------------------------------------------------------	
   549                                  
   550                                  align 4
   551                                  
   552                                  bss_start:
   553                                  
   554                                  ABSOLUTE bss_start
   555                                  
   556                                  ; 06/05/2022
   557                                  
   558 000001B0 <res 200h>              name:	resb 512
   559                                  
   560 000003B0 ????                    file:	resw 1
   561 000003B2 ????                    off:	resw 1
   562                                  
   563                                  ; 11/05/2022
   564                                  d.dev:
   565                                  ; 09/05/2022
   566 000003B4 ????                    idev:	resw 1 ; device number (0 = root, 1 = mounted)
   567                                  ; 11/05/2022
   568 000003B6 ????                    dd.dev: resw 1
   569                                  
   570                                  ; 06/05/2022
   571                                  _x:	; stat(us) buffer
   572                                  _d:	; 11/05/2022
   573                                  inum:
   574                                  d.ino:	; 11/05/2022
   575 000003B8 ????                    	resw 1
   576                                  ximode:
   577                                  d.mode: ; 11/05/22022
   578                                  	;resb 64 ; Retro UNIX 386 v1.2
   579 000003BA <res 20h>               	resb 32 ; Retro UNIX 386 v1 & v1.1
   580                                  
   581                                  ; 11/05/2022
   582                                  _dd:	; stat(us) buffer
   583 000003DA ????                    dd.ino:	resw 1
   584                                  dd.mode:
   585 000003DC <res 20h>               	resb 32
   586                                  
   587                                  ; 06/05/2022
   588                                  _y:	; directory entry buffer
   589 000003FC ????                    jnum:	resw 1
   590                                  yname:	;resb 14 ; Retro UNIX 386 v1.1 & v1.2
   591 000003FE ????????????????        	resb 8 ; Retro UNIX 386 v1 (unix v1)
   592                                  
   593 00000406 ????                    yzero:	resw 1
   594                                  
   595                                  ; 05/05/2022
   596                                  
   597                                  ;-----------------------------------------------------------------
   598                                  ; Original UNIX v7 - /bin/pwd file - c source code (pwd.c)
   599                                  ;-----------------------------------------------------------------
   600                                  ;
   601                                  ;/*
   602                                  ; * Print working (current) directory
   603                                  ; */
   604                                  ;#include <stdio.h>
   605                                  ;#include <sys/param.h>
   606                                  ;#include <sys/stat.h>
   607                                  ;#include <sys/dir.h>
   608                                  ;
   609                                  ;char	dot[]	= ".";
   610                                  ;char	dotdot[] = "..";
   611                                  ;char	name[512];
   612                                  ;int	file;
   613                                  ;int	off	= -1;
   614                                  ;struct	stat	d, dd;
   615                                  ;struct	direct	dir;
   616                                  ;
   617                                  ;main()
   618                                  ;{
   619                                  ;	int rdev, rino;
   620                                  ;
   621                                  ;	stat("/", &d);
   622                                  ;	rdev = d.st_dev;
   623                                  ;	rino = d.st_ino;
   624                                  ;	for (;;) {
   625                                  ;		stat(dot, &d);
   626                                  ;		if (d.st_ino==rino && d.st_dev==rdev)
   627                                  ;			prname();
   628                                  ;		if ((file = open(dotdot,0)) < 0) {
   629                                  ;			fprintf(stderr,"pwd: cannot open ..\n");
   630                                  ;			exit(1);
   631                                  ;		}
   632                                  ;		fstat(file, &dd);
   633                                  ;		chdir(dotdot);
   634                                  ;		if(d.st_dev == dd.st_dev) {
   635                                  ;			if(d.st_ino == dd.st_ino)
   636                                  ;				prname();
   637                                  ;			do
   638                                  ;				if (read(file, (char *)&dir, sizeof(dir)) < sizeof(dir)) {
   639                                  ;					fprintf(stderr,"read error in ..\n");
   640                                  ;					exit(1);
   641                                  ;				}
   642                                  ;			while (dir.d_ino != d.st_ino);
   643                                  ;		}
   644                                  ;		else do {
   645                                  ;				if(read(file, (char *)&dir, sizeof(dir)) < sizeof(dir)) {
   646                                  ;					fprintf(stderr,"read error in ..\n");
   647                                  ;					exit(1);
   648                                  ;				}
   649                                  ;				stat(dir.d_name, &dd);
   650                                  ;			} while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
   651                                  ;		close(file);
   652                                  ;		cat();
   653                                  ;	}
   654                                  ;}
   655                                  ;
   656                                  ;prname()
   657                                  ;{
   658                                  ;	write(1, "/", 1);
   659                                  ;	if (off<0)
   660                                  ;		off = 0;
   661                                  ;	name[off] = '\n';
   662                                  ;	write(1, name, off+1);
   663                                  ;	exit(0);
   664                                  ;}
   665                                  ;
   666                                  ;cat()
   667                                  ;{
   668                                  ;	register i, j;
   669                                  ;
   670                                  ;	i = -1;
   671                                  ;	while (dir.d_name[++i] != 0);
   672                                  ;	if ((off+i+2) > 511)
   673                                  ;		prname();
   674                                  ;	for(j=off+1; j>=0; --j)
   675                                  ;		name[j+i+1] = name[j];
   676                                  ;	off=i+off+1;
   677                                  ;	name[i] = '/';
   678                                  ;	for(--i; i>=0; --i)
   679                                  ;		name[i] = dir.d_name[i];
   680                                  ;}
   681                                  
   682                                  ; 05/05/2022
   683                                  
   684                                  ;-----------------------------------------------------------------
   685                                  ; Original UNIX v5 - /usr/bin/pwd file - c source code (pwd.c)
   686                                  ;-----------------------------------------------------------------
   687                                  ;
   688                                  ;char dot[] ".";
   689                                  ;char dotdot[] "..";
   690                                  ;char root[] "/";
   691                                  ;char name[512];
   692                                  ;int file, off -1;
   693                                  ;struct statb {int devn, inum, i[18];}x;
   694                                  ;struct entry { int jnum; char name[16];}y;
   695                                  ;
   696                                  ;main() {
   697                                  ;	int n;
   698                                  ;
   699                                  ;loop0:
   700                                  ;	stat(dot, &x);
   701                                  ;	if((file = open(dotdot,0)) < 0) prname();
   702                                  ;loop1:
   703                                  ;	if((n = read(file,&y,16)) < 16) prname();
   704                                  ;	if(y.jnum != x.inum)goto loop1;
   705                                  ;	close(file);
   706                                  ;	if(y.jnum == 1) ckroot();
   707                                  ;	cat();
   708                                  ;	chdir(dotdot);
   709                                  ;	goto loop0;
   710                                  ;}
   711                                  ;ckroot() {
   712                                  ;	int i, n;
   713                                  ;
   714                                  ;	if((n = stat(y.name,&x)) < 0) prname();
   715                                  ;	i = x.devn;
   716                                  ;	if((n = chdir(root)) < 0) prname();
   717                                  ;	if((file = open(root,0)) < 0) prname();
   718                                  ;loop:
   719                                  ;	if((n = read(file,&y,16)) < 16) prname();
   720                                  ;	if(y.jnum == 0) goto loop;
   721                                  ;	if((n = stat(y.name,&x)) < 0) prname();
   722                                  ;	if(x.devn != i) goto loop;
   723                                  ;	x.i[0] =& 060000;
   724                                  ;	if(x.i[0] != 040000) goto loop;
   725                                  ;	cat();
   726                                  ;	prname();
   727                                  ;}
   728                                  ;prname() {
   729                                  ;	name[off] = '\n';
   730                                  ;	write(1,name,off+1);
   731                                  ;	exit();
   732                                  ;}
   733                                  ;cat() {
   734                                  ;	int i, j;
   735                                  ;
   736                                  ;	i = -1;
   737                                  ;	while(y.name[++i] != 0);
   738                                  ;	if((off+i+2) > 511) prname();
   739                                  ;	for(j=off+1; j>=0; --j) name[j+i+1] = name[j];
   740                                  ;	off=i+off+1;
   741                                  ;	name[i] = root[0];
   742                                  ;	for(--i; i>=0; --i) name[i] = y.name[i];
   743                                  ;}
