     1                                  ; ****************************************************************************
     2                                  ; glob8086.s (glob0.s) - by Erdogan Tan - 28/05/2022
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Retro UNIX 8086 v1 - global command (/etc/glob)
     5                                  ;
     6                                  ; [ Last Modification: 30/05/2022 ]
     7                                  ;
     8                                  ; Derived from (original) UNIX v5 'glob.c' source Code
     9                                  ; Ref:
    10                                  ; www.tuhs.org (https://minnie.tuhs.org)
    11                                  ; ****************************************************************************
    12                                  ; [ v5root.tar.gz - usr/source/s1/glob.c (archive date: 27-11-1974) ]
    13                                  ;
    14                                  ; Assembler: NASM v2.15
    15                                  ; ((nasm glob1.s -l glob1.txt -o glob1 -Z error.txt))
    16                                  
    17                                  ; glob2.s - 30/05/2022 - Retro UNIX 386 v1.1 & v1.2 & v2
    18                                  ; glob1.s - 30/05/2022 - Retro UNIX 386 v1
    19                                  ; glob0.s - 30/05/2022 - Retro UNIX 8086 v1 (16 bit 'glob1.s')
    20                                  
    21                                  ; 12/01/2022 (Retro UNIX 386 v1.2)
    22                                  ; 13/10/2015
    23                                  
    24                                  ; UNIX v1 system calls
    25                                  _rele 	equ 0
    26                                  _exit 	equ 1
    27                                  _fork 	equ 2
    28                                  _read 	equ 3
    29                                  _write	equ 4
    30                                  _open	equ 5
    31                                  _close 	equ 6
    32                                  _wait 	equ 7
    33                                  _creat 	equ 8
    34                                  _link 	equ 9
    35                                  _unlink	equ 10
    36                                  _exec	equ 11
    37                                  _chdir	equ 12
    38                                  _time 	equ 13
    39                                  _mkdir 	equ 14
    40                                  _chmod	equ 15
    41                                  _chown	equ 16
    42                                  _break	equ 17
    43                                  _stat	equ 18
    44                                  _seek	equ 19
    45                                  _tell 	equ 20
    46                                  _mount	equ 21
    47                                  _umount	equ 22
    48                                  _setuid	equ 23
    49                                  _getuid	equ 24
    50                                  _stime	equ 25
    51                                  _quit	equ 26	
    52                                  _intr	equ 27
    53                                  _fstat	equ 28
    54                                  _emt 	equ 29
    55                                  _mdate 	equ 30
    56                                  _stty 	equ 31
    57                                  _gtty	equ 32
    58                                  _ilgins	equ 33
    59                                  _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
    60                                  _msg    equ 35 ; Retro UNIX 386 v1 feature only !
    61                                  _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
    62                                  ; 12/01/2022 - Retro UNIX 386 v1.2
    63                                  ; Retro UNIX 386 v2 system calls
    64                                  _setgid	equ 37
    65                                  _getgid	equ 38
    66                                  _sysver	equ 39 ; (get) Retro Unix 386 version
    67                                  
    68                                  ;;;
    69                                  ESCKey equ 1Bh
    70                                  EnterKey equ 0Dh
    71                                  
    72                                  ;%macro sys 1-4
    73                                  ;   ; 03/09/2015
    74                                  ;   ; 13/04/2015
    75                                  ;   ; Retro UNIX 386 v1 system call.
    76                                  ;   %if %0 >= 2   
    77                                  ;       mov ebx, %2
    78                                  ;       %if %0 >= 3    
    79                                  ;           mov ecx, %3
    80                                  ;           ;%if %0 = 4
    81                                  ;           %if	%0 >= 4 ; 11/03/2022
    82                                  ;		mov edx, %4
    83                                  ;           %endif
    84                                  ;       %endif
    85                                  ;   %endif
    86                                  ;   mov eax, %1
    87                                  ;   int 30h
    88                                  ;%endmacro
    89                                  
    90                                  %macro sys 1-4
    91                                      ; Retro UNIX 8086 v1 system call.
    92                                      %if %0 >= 2   
    93                                          mov bx, %2
    94                                          %if %0 >= 3
    95                                              mov cx, %3
    96                                              %if %0 >= 4
    97                                                 mov dx, %4
    98                                              %endif
    99                                          %endif
   100                                      %endif
   101                                      mov ax, %1
   102                                      int 20h
   103                                  %endmacro
   104                                  
   105                                  ;; Retro UNIX 386 v1 system call format:
   106                                  ;; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
   107                                  
   108                                  ;; 11/03/2022
   109                                  ;; Note: Above 'sys' macro has limitation about register positions;
   110                                  ;;	ebx, ecx, edx registers must not be used after their
   111                                  ;;	positions in sys macro.
   112                                  ;; for example:
   113                                  ;;	'sys _write, 1, msg, ecx' is defective, because
   114                                  ;;	 ecx will be used/assigned before edx in 'sys' macro.
   115                                  ;; correct order may be:
   116                                  ;;	'sys _write, 1, msg, eax ; (eax = byte count)
   117                                  
   118                                  ; Retro UNIX 8086 v1 system call format:
   119                                  ; sys systemcall (ax) <arg1 (bx)>, <arg2 (cx)>, <arg3 (dx)>
   120                                  
   121                                  struc stat
   122                                  	; Note: This is for Retro UNIX v1 'sysstat' output !!!
   123                                  	; (34 bytes)
   124 00000000 ????                    	.inode:  resw 1	
   125 00000002 ????                    	.mode:	 resw 1
   126 00000004 ??                      	.nlinks: resb 1
   127 00000005 ??                      	.uid:	 resb 1
   128 00000006 ????                    	.size:	 resw 1
   129 00000008 <res 10h>               	.dskptr: resw 8
   130 00000018 ????????                	.ctime:	 resd 1
   131 0000001C ????????                	.mtime:	 resd 1
   132 00000020 ????                    	.rsvd:   resw 1
   133                                  	.strucsize:
   134                                  endstruc 
   135                                  
   136                                  ;struc stat
   137                                  ;	; Note: This is for Retro UNIX v1.2 'sysstat' output !!!
   138                                  ;	; (66 bytes)
   139                                  ;	.inode:  resw 1	
   140                                  ;	.mode:	 resw 1
   141                                  ;	.nlinks: resw 1 
   142                                  ;	.uid:	 resw 1
   143                                  ;	.gid:	 resb 1
   144                                  ;	.size_h: resb 1
   145                                  ;	.size:	 resd 1
   146                                  ;	.dskptr: resd 10
   147                                  ;	.atime:	 resd 1
   148                                  ;	.mtime:	 resd 1
   149                                  ;	.ctime:  resd 1
   150                                  ;	.strucsize:
   151                                  ;endstruc   
   152                                  
   153                                  ;;struc stat
   154                                  ;;	; Note: Retro UNIX v2 'sysstat' output DRAFT !!!
   155                                  ;;	; (72 bytes)
   156                                  ;;	.idev:	 resb 1
   157                                  ;;	.rsvd:	 resb 3
   158                                  ;;	.inum:   resd 1	
   159                                  ;;	.mode:	 resw 1
   160                                  ;;	.nlinks: resw 1 
   161                                  ;;	.uid:	 resw 1
   162                                  ;;	.gid:	 resb 1
   163                                  ;;	.size_h: resb 1
   164                                  ;;	.size:	 resd 1
   165                                  ;;	.dskptr: resd 10
   166                                  ;;	.atime:	 resd 1
   167                                  ;;	.mtime:	 resd 1
   168                                  ;;	.ctime:  resd 1
   169                                  ;;	.strucsize:
   170                                  ;;endstruc 
   171                                  
   172                                  ;S_IFMT   equ 0F000h ; /* type of file */
   173                                  ;S_IFDIR  equ 04000h ; /* directory */
   174                                  ;S_IFCHR  equ 02000h ; /* character special */
   175                                  ;S_IFBLK  equ 06000h ; /* block special */
   176                                  ;S_IFREG  equ 08000h ; /* regular */
   177                                  ;S_ISUID  equ 00800h ; /* set user id on execution */
   178                                  ;S_ISGID  equ 00400h ; /* set group id on execution */
   179                                  ;S_IREAD  equ 00100h ; /* read permission, owner */
   180                                  ;S_IWRITE equ 00080h ; /* write permission, owner */
   181                                  ;S_IEXEC  equ 00040h ; /* execute/search permission, owner */
   182                                  
   183                                  S_IFMT   equ 0F0h ; /* type of file */
   184                                  S_IFDIR  equ 040h ; /* directory */
   185                                  S_IFCHR  equ 020h ; /* character special */
   186                                  S_IFBLK  equ 060h ; /* block special */
   187                                  S_IFREG  equ 080h ; /* regular */
   188                                  S_ISUID  equ 008h ; /* set user id on execution */
   189                                  S_ISGID  equ 004h ; /* set group id on execution */
   190                                  S_IREAD  equ 001h ; /* read permission, owner */
   191                                  S_IWRITE equ 080h ; /* write permission, owner */
   192                                  S_IEXEC  equ 040h ; /* execute/search permission, owner */
   193                                  
   194                                  ;; UNIX v1 inode
   195                                  ;; byte 1
   196                                  ;S_ALLOC  equ 080h ; Allocated flag
   197                                  ;S_IFDIR  equ 040h ; Directory flag
   198                                  ;S_IFMDF  equ 020h ; File modified flag (always on)
   199                                  ;S_IFLRG  equ 010h ; Large File flag
   200                                  ;; byte 0
   201                                  ;S_ISUID  equ 020h ; Set User ID On Execution flag
   202                                  ;S_IEXEC  equ 010h ; Executable File flag
   203                                  ;S_IREAD  equ 008h ; Owner's Read Permission flag
   204                                  ;S_IWRITE equ 004h ; Owner's Write Permission flag
   205                                  
   206                                  ; 28/05/2022
   207                                  STRSIZ equ 522
   208                                  ;DIRSIZ equ 16  ; Retro UNIX 386 v1.1 & v1.2
   209                                  DIRSIZ equ 10 ; Retro UNIX 8086 v1 & 386 v1 	
   210                                  
   211                                  ;-----------------------------------------------------------------
   212                                  ;  text - code
   213                                  ;-----------------------------------------------------------------
   214                                  
   215                                  [BITS 16] ; 16-bit intructions (for 8086-80386 real mode)
   216                                  
   217                                  [ORG 0] 
   218                                  
   219                                  START_CODE:
   220                                  	; 28/05/2022
   221                                  ;-----------------------------------------------------------------
   222                                  
   223                                  main:
   224                                  	; main(argc, argv)
   225                                  	
   226 00000000 58                      	pop	ax ; number of arguments
   227                                  
   228                                  	;mov	[argc], ax
   229 00000001 A2[1803]                	mov	[argc], al
   230                                  
   231                                  	;if (argc < 3) {
   232                                  	;	write(2, "Arg count\n", 10);
   233                                  	;	return;
   234                                  	;}
   235                                  
   236                                  	;cmp	ax, 3
   237 00000004 3C03                    	cmp	al, 3
   238 00000006 730B                    	jnb	short glb_0
   239                                  	
   240 00000008 B8[B802]                	mov	ax, msg_arg_count
   241                                  glb_print_exit:
   242 0000000B E84A02                  	call	print_msg
   243                                  glb_exit:
   244                                  	sys	_exit	; sys exit
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93                              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000000E B80100              <1>  mov ax, %1
   102 00000011 CD20                <1>  int 20h
   245                                  ;hlt:
   246                                  ;	nop
   247                                  ;	nop
   248                                  ;	jmp	short hlt
   249                                  
   250                                  glb_0:
   251                                  	;argv++;
   252                                  	;*av++ = *argv;
   253 00000013 5A                      	pop	dx ; argv[0]
   254 00000014 BB[2A03]                	mov	bx, ava
   255 00000017 8917                    	mov	[bx], dx
   256 00000019 83C302                  	add	bx, 2
   257 0000001C 5A                      	pop	dx ; argv[1]
   258 0000001D 8917                    	mov	[bx], dx
   259 0000001F 83C302                  	add	bx, 2
   260 00000022 891E[1103]              	mov	[av], bx
   261                                  
   262                                  	;while (--argc >= 2)
   263                                  	;	expand(*++argv);
   264                                  glb_1:
   265 00000026 FE0E[1803]              	dec	byte [argc]
   266 0000002A 803E[1803]02            	cmp	byte [argc], 2
   267 0000002F 7206                    	jb	short glb_2
   268                                  
   269 00000031 5D                      	pop	bp  ; argument pointer
   270                                  
   271 00000032 E83E00                  	call	expand
   272 00000035 EBEF                    	jmp	short glb_1
   273                                  
   274                                  glb_2:	
   275                                  	;if (ncoll==0) {
   276                                  	;	write(2, "No match\n", 9);
   277                                  	;	return;
   278                                  	;}
   279                                  
   280 00000037 803E[1A03]00            	cmp	byte [ncoll], 0
   281 0000003C 7705                    	ja	short glb_3
   282                                  
   283 0000003E B8[C602]                	mov	ax, msg_no_match
   284 00000041 EBC8                    	jmp	short glb_print_exit
   285                                  
   286                                  glb_3:
   287                                  	;execute(ava[1], &ava[1]);
   288                                  	;cp = cat("/usr/bin/", ava[1]);
   289                                  	;execute(cp+4, &ava[1]);
   290                                  	;execute(cp, &ava[1]);
   291                                  
   292                                  	sys	_exec, [ava+2], ava+2
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000043 8B1E[2C03]          <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000047 B9[2C03]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000004A B80B00              <1>  mov ax, %1
   102 0000004D CD20                <1>  int 20h
   293 0000004F BD[AE02]                	mov	bp, usr_bin
   294                                  	;mov	bx, [ava+2]
   295 00000052 E8B301                  	call	cat
   296                                  	; cp = binary file name pointer
   297                                  	; dx = cp
   298 00000055 89D7                    	mov	di, dx
   299 00000057 83C704                  	add	di, 4
   300                                  	;execute(cp+4, &ava[1])
   301                                  	sys	_exec, di, ava+2 ; '/bin...'
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 0000005A 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 0000005C B9[2C03]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000005F B80B00              <1>  mov ax, %1
   102 00000062 CD20                <1>  int 20h
   302                                  	;execute(cp, &ava[1]);
   303                                  	sys	_exec, dx, ava+2 ; '/usr/bin...'
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000064 89D3                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000066 B9[2C03]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000069 B80B00              <1>  mov ax, %1
   102 0000006C CD20                <1>  int 20h
   304                                  
   305 0000006E B8[D302]                	mov	ax, msg_not_found
   306 00000071 EB98                    	jmp	glb_print_exit
   307                                  
   308                                  ;-----------------------------------------------------------------
   309                                  
   310                                  expand: ;expand(as)
   311                                  
   312                                  	;register char *s, *cs;
   313                                  	;register int dirf;
   314                                  	;char **oav;
   315                                  
   316                                  	;static struct {
   317                                  	;	int  ino;
   318                                  	;	char name[16];
   319                                  	;} entry;	
   320                                  
   321                                  	;s = cs = as	
   322                                  
   323                                  	; INPUT:
   324                                  	;   bp = argument pointer 
   325                                  
   326                                  	; Modified regs: ax, bx, cx, dx, si, di, bp
   327                                  	
   328 00000073 89EE                    	mov	si, bp
   329 00000075 31D2                    	xor	dx, dx ; dx = 0 
   330                                  
   331                                  expd_0:	
   332                                  	;while (*cs!='*' && *cs!='?' && *cs!='[') {
   333                                  
   334 00000077 8A04                    	mov	al, [si]
   335 00000079 3C2A                    	cmp	al, '*'
   336 0000007B 7420                    	je	short expd_1
   337 0000007D 3C3F                    	cmp	al, '?'
   338 0000007F 741C                    	je	short expd_1
   339 00000081 3C5B                    	cmp	al, '['
   340 00000083 7418                    	je	short expd_1
   341                                  
   342                                  	;if (*cs++ == 0) {
   343                                  	;	*av++ = cat(s, "");
   344                                  	;	return;
   345                                  	;}
   346                                  
   347 00000085 46                      	inc	si
   348 00000086 08C0                    	or	al, al
   349 00000088 75ED                    	jnz	short expd_0
   350                                  
   351 0000008A 29DB                    	sub	bx, bx ; 0
   352                                  
   353                                  	; bp = pointer to (current) argument
   354                                  	; bx = 0
   355                                  
   356                                  cat_get_av:
   357 0000008C E87901                  	call	cat
   358                                  	; dx = concatenated string address (ab[])
   359                                  
   360 0000008F 8B1E[1103]              	mov	bx, [av]  ; offset address of ava[] pointer
   361 00000093 8917                    	mov	[bx], dx ; [bx] = ava[] pointer's itself
   362 00000095 83C302                  	add	bx, 2
   363 00000098 891E[1103]              	mov	[av], bx  ; next ava[] address
   364                                  
   365 0000009C C3                      	retn
   366                                  
   367                                  expd_1:	
   368 0000009D 29FF                    	sub	di, di ; 0
   369                                  expd_2:
   370                                  	;for (;;) {
   371                                  
   372                                  	;if (cs==s) {
   373                                  	;	dirf = open(".", 0);
   374                                  	;	s = "";
   375                                  	;	break;
   376                                  
   377 0000009F 39EE                    	cmp	si, bp
   378                                  	;jne	short expd_4
   379 000000A1 7713                    	ja	short expd_4
   380                                  
   381                                  	;sub	di, di ; 0
   382                                  	sys	_open, DOT, di ; open '.' for read
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000000A3 BB[AC02]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000000A6 89F9                <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000000A8 B80500              <1>  mov ax, %1
   102 000000AB CD20                <1>  int 20h
   383 000000AD 7203                    	jc	short expd_3	
   384 000000AF 89C7                    	mov	di, ax ; file descriptor (>=0)
   385 000000B1 47                      	inc	di ; file descriptor + 1
   386                                  expd_3:
   387                                  	; dx = 1
   388 000000B2 29ED                    	sub	bp, bp ; 0  ; s = ""
   389 000000B4 EB24                    	jmp	short expd_break
   390                                  expd_4:
   391                                  	;if (*--cs == '/') {
   392                                  	;	*cs = 0;
   393                                  	;	dirf = open(s==cs? "/": s, 0);
   394                                  	;	*cs++ = 0200;
   395                                  	;	break;
   396 000000B6 4E                      	dec	si
   397 000000B7 803C2F                  	cmp	byte [si], '/'
   398 000000BA 75E3                    	jne	short expd_2
   399 000000BC C60400                  	mov	byte [si], 0
   400 000000BF 89EA                    	mov	dx, bp
   401 000000C1 39EE                    	cmp	si, bp
   402 000000C3 7503                    	jne	short expd_5
   403                                  	;ja	short expd_5
   404 000000C5 BA[AA02]                	mov	dx, ROOTDIR
   405                                  expd_5:	
   406                                  	;dirf = open(s==cs? "/": s, 0);
   407                                  	;sub	di, di ; 0
   408                                  	sys	_open, dx, di ; ; open for read
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000000C8 89D3                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000000CA 89F9                <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000000CC B80500              <1>  mov ax, %1
   102 000000CF CD20                <1>  int 20h
   409 000000D1 7203                    	jc	short expd_6
   410 000000D3 89C7                    	mov	di, ax ; file descriptor (>=0)
   411 000000D5 47                      	inc	di ; file descriptor + 1
   412                                  expd_6:
   413 000000D6 C60480                  	mov	byte [si], 80h ; *cs++ = 0200;
   414 000000D9 46                      	inc	si
   415                                  expd_7:
   416                                  expd_break:
   417                                  	;if (dirf<0) {
   418                                  	;	write(2, "No directory\n", 13);
   419                                  	;	exit();
   420                                  	;}
   421 000000DA 4F                      	dec	di ; 1 -> 0 or 0 -> -1
   422 000000DB 790B                    	jns	short expd_9
   423                                  
   424 000000DD B8[EA02]                	mov	ax, msg_no_dir
   425                                  expd_8:
   426 000000E0 E87501                  	call	print_msg
   427                                  _exit_:
   428                                  	sys	_exit
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93                              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000000E3 B80100              <1>  mov ax, %1
   102 000000E6 CD20                <1>  int 20h
   429                                  ;hang:
   430                                  	;nop
   431                                  	;jmp	short hang
   432                                  
   433                                  expd_9:
   434                                  	;oav = av;
   435 000000E8 FF36[1103]              	push	word [av]
   436                                  expd_10:
   437                                  	;while (read(dirf, &entry, 16) == 16) {
   438                                  
   439                                  	sys	_read, di, entry, DIRSIZ
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000000EC 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000000EE B9[1C03]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97 000000F1 BA0A00              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000000F4 B80300              <1>  mov ax, %1
   102 000000F7 CD20                <1>  int 20h
   440 000000F9 721C                    	jc	short expd_11
   441                                  	;cmp	ax, 10
   442                                  	;jne	short expd_11
   443 000000FB 09C0                    	or	ax, ax  ; read count
   444 000000FD 7418                    	jz	short expd_11
   445                                  	
   446                                  	;if (entry.ino==0)
   447                                  	;	continue;
   448 000000FF 833E[1C03]00            	cmp	word [entry.ino], 0
   449 00000104 76E6                    	jna	short expd_10 ; continue
   450                                  	
   451                                  	;if (match(entry.name, cs)
   452 00000106 BB[1E03]                	mov	bx, entry.name
   453                                  	; si = cs 
   454 00000109 E85200                  	call	match
   455 0000010C 75DE                    	jnz	short expd_10
   456                                  
   457                                  	; bp = pointer to (current) argument
   458                                  	; bx = entry.name
   459                                  
   460                                  	;; *av++ = cat(s, entry.name);
   461                                  	;call	cat
   462                                  	;; dx = concatenated string address (ab[])
   463                                  	
   464                                  	;mov	bx, [av]
   465                                  	;mov	[bx], dx
   466                                  	;add	bx, 2
   467                                  	;mov	[av], bx
   468                                  
   469                                  	; *av++ = cat(s, entry.name);
   470 0000010E E87BFF                  	call	cat_get_av
   471                                  
   472                                  	; ncoll++;
   473 00000111 FE06[1A03]              	inc	byte [ncoll]
   474                                  
   475                                  	; di = file descriptor = dirf
   476                                  	; si = cs
   477                                  	; bp = s
   478                                  
   479 00000115 EBD5                    	jmp	short expd_10
   480                                  
   481                                  expd_11:
   482                                  	;close(dirf);
   483                                  	sys	_close, di
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000117 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000119 B80600              <1>  mov ax, %1
   102 0000011C CD20                <1>  int 20h
   484 0000011E 5E                      	pop	si ; oav	
   485                                  	;sort(oav);
   486                                  	;call	sort
   487                                  	;retn
   488                                  	;;jmp	sort
   489                                  
   490                                  ;-----------------------------------------------------------------
   491                                  
   492                                  sort:	;sort(oav)
   493                                  
   494                                  	; INPUT:
   495                                  	;    si = first ptr to
   496                                  	;	   file/dir names to be sorted
   497                                  
   498                                  	;p1 = oav;
   499 0000011F A1[1103]                	mov	ax, [av]
   500 00000122 83E802                  	sub	ax, 2
   501 00000125 8B16[1103]              	mov	dx, [av]  ; dx = [av]
   502                                  srt_1:
   503                                  	; ax = [av] - 2	
   504                                  	;while (p1 < av-1) {
   505 00000129 39C6                    	cmp	si, ax ; si = p1
   506 0000012B 731B                    	jnb	short srt_4
   507 0000012D 89F7                    	mov	di, si ; p2 = p1;
   508                                  srt_2:
   509                                  	;while(++p2 < av) {
   510 0000012F 83C702                  	add	di, 2
   511 00000132 39D7                    	cmp	di, dx ; di = p2
   512 00000134 730D                    	jnb	short srt_3
   513                                  	
   514                                  	;if (compar(*p1, *p2) > 0)
   515 00000136 E81000                  	call	compar
   516 00000139 76F4                    	jna	short srt_2
   517                                  
   518                                  	;c = *p1;
   519                                  	;*p1 = *p2;
   520                                  	;*p2 = c;
   521 0000013B 8B0D                    	mov	cx, [di]
   522 0000013D 870C                    	xchg	[si], cx
   523 0000013F 890D                    	mov	[di], cx
   524                                  
   525 00000141 EBEC                    	jmp	short srt_2	
   526                                  
   527                                  srt_3:
   528                                  	;p1++;
   529 00000143 83C602                  	add	si, 2
   530 00000146 EBE1                    	jmp	short srt_1
   531                                  srt_4:
   532 00000148 C3                      	retn
   533                                  
   534                                  ;-----------------------------------------------------------------
   535                                  
   536                                  compar: ;compar(as1, as2)
   537                                  	; INPUT:
   538                                  	;	si = p1 ; asciiz string (compared)
   539                                  	;	di = p2 ; asciiz string (with this)
   540                                  	;
   541                                  	; OUTPUT:
   542                                  	;	*p1 - *p2 (first non-equal chars)
   543                                  	;	0 = equal strings (with p2 length)
   544                                  
   545                                  	; Modified registers: cx, bx, bp
   546                                  	;
   547                                  
   548                                  	;s1 = as1;
   549                                  	;s2 = as2;
   550                                  
   551 00000149 8B1C                    	mov	bx, [si] ; *p1
   552 0000014B 8B2D                    	mov	bp, [di] ; *p2
   553                                  comp_1:
   554                                  	;while (*s1++ == *s2)
   555                                  	;	if (*s2++ == 0)
   556 0000014D 8A0F                    	mov	cl, [bx] ; *s1++
   557 0000014F 43                      	inc	bx
   558 00000150 8A6E00                  	mov	ch, [bp] ; *s2
   559 00000153 45                      	inc	bp
   560                                  	;return (*--s1 - *s2);
   561 00000154 28E9                    	sub	cl, ch
   562 00000156 7401                    	jz	short comp_2
   563 00000158 C3                      	retn
   564                                  comp_2:
   565                                  	;if (*s2++ == 0)
   566                                  	;  return(0);
   567 00000159 08ED                    	or	ch, ch
   568 0000015B 75F0                    	jnz	short comp_1
   569                                  	; zf = 1
   570                                  mtch_0:
   571 0000015D C3                      	retn
   572                                  
   573                                  ;-----------------------------------------------------------------	
   574                                  
   575                                  match:	; match(s, p)
   576                                  
   577                                  	; char *s, *p;
   578                                  	; if (*s=='.' && *p!='.')
   579                                  	;	return(0);
   580                                  	; return(amatch(s, p));
   581                                  
   582                                  	; INPUT:
   583                                  	;	bx = directory entry
   584                                  	;	si = user input
   585                                  	; OUTPUT:
   586                                  	;	zf = 1 ->
   587                                  	;	     dir entry matches with input
   588                                  	;	zf = 0 ->
   589                                  	;	     dir entry does not match with input
   590                                  	;
   591                                  	; Modified registers: ax, cx, dx
   592                                  
   593 0000015E 8A07                    	mov	al, [bx] ; *s
   594 00000160 3C2E                    	cmp	al, '.'
   595 00000162 7504                    	jne	short mtch_1
   596 00000164 3A04                    	cmp	al, [si] ; *p
   597                                  	;je	short mtch_1
   598                                  	;retn 	; zf = 0
   599 00000166 75F5                    	jne	short mtch_0 ; retn  ; zf = 0
   600                                  mtch_1:
   601 00000168 56                      	push	si ; *
   602 00000169 57                      	push	di ; **
   603 0000016A 53                      	push	bx ; ***
   604 0000016B 55                      	push	bp ; ****
   605                                  
   606 0000016C E80500                  	call	amatch
   607                                  
   608 0000016F 5D                      	pop	bp ; ****
   609 00000170 5B                      	pop	bx ; ***
   610 00000171 5F                      	pop	di ; **
   611 00000172 5E                      	pop	si ; *
   612                                  	
   613 00000173 C3                      	retn
   614                                  
   615                                  ;-----------------------------------------------------------------
   616                                  
   617                                  amatch:	;amatch(as, ap)
   618                                  
   619                                  	;char *as, *ap;
   620                                  	;
   621                                  	;register char *s, *p;
   622                                  	;register scc;
   623                                  	;int c, cc, ok, lc;
   624                                  
   625                                  	; INPUT:
   626                                  	;	bx = directory entry
   627                                  	;	si = user input
   628                                  	; OUTPUT:
   629                                  	;	zf = 1 ->
   630                                  	;	     dir entry matches with input
   631                                  	;	zf = 0 ->
   632                                  	;	     dir entry does not match with input
   633                                  	;
   634                                  	; Modified registers: ax, cx, dx, bx, si, di, bp
   635                                  
   636 00000174 31C0                    	xor	ax, ax
   637                                  
   638                                  	;s = as;
   639                                  	;p = ap;
   640                                  
   641                                  amch_next:
   642                                  	;if (scc = *s++)
   643                                  	;	if ((scc =& 0177) == 0)
   644                                  	;		scc = 0200;
   645                                  	
   646                                  	; si = p	
   647                                  	; bx = s
   648                                  
   649 00000176 8A07                    	mov	al, [bx] ; *s++
   650 00000178 43                      	inc	bx
   651                                  	;mov	bp, ax  ; scc
   652 00000179 20C0                    	and	al, al
   653 0000017B 7406                    	jz	short amch_0
   654 0000017D 247F                    	and	al, 7Fh ; 127
   655 0000017F 7502                    	jnz	short amch_0
   656 00000181 0C80                    	or	al, 80h ;  scc = 80h
   657                                  amch_0:
   658 00000183 89C5                    	mov	bp, ax ; scc
   659                                  
   660                                  switch:	;switch (c = *p++) {
   661                                  
   662 00000185 AC                      	lodsb
   663 00000186 3C5B                    	cmp	al, '['
   664 00000188 7531                    	jne	short amch_10
   665                                  amch_1: 
   666                                  	;case '[':
   667                                  	;ok = 0;
   668                                  	;lc = 077777;
   669                                  	;while (cc = *p++) {
   670                                  	;	if (cc==']') {
   671                                  	;	   if (ok)
   672                                  	;	      return(amatch(s, p));
   673                                  	;	   else
   674                                  	;	      return(0);
   675                                  	;	} else if (cc=='-') {
   676                                  	;	    if (lc<=scc && scc<=(c = *p++))
   677                                  	;		ok++;
   678                                  	;	    } else
   679                                  	;		if (scc == (lc=cc))
   680                                  	;	     	   ok++;
   681                                  	;	}
   682                                  	;	return(0);
   683                                  
   684 0000018A 31C9                    	xor	cx, cx ; ok = 0
   685 0000018C BAFF7F                  	mov	dx, 7FFFh ; lc = 077777
   686                                  amch_2:
   687                                  	;while (cc = *p++) {
   688 0000018F AC                      	lodsb	; cc = *p++
   689 00000190 20C0                    	and	al, al
   690 00000192 7456                    	jz	short amch_x
   691 00000194 3C5D                    	cmp	al, ']' ; if (cc=']')
   692 00000196 750B                    	jne	short amch_3
   693 00000198 21C9                    	and	cx, cx ; 0 ; if (ok)
   694 0000019A 744C                    	jz	short amch_xx
   695                                  	
   696                                  	;return(amatch(s, p));
   697                                  	; bx = s
   698                                  	; si = p
   699 0000019C E8D5FF                  	call	amatch
   700 0000019F FEC8                    	dec	al ; 1 -> 0, 0 -> 0FFh
   701 000001A1 EB47                    	jmp	short amch_x
   702                                  amch_3:
   703 000001A3 3C2D                    	cmp	al, '-' ; else if (cc='-')
   704 000001A5 750C                    	jne	short amch_5
   705 000001A7 39EA                    	cmp	dx, bp ; if (lc<=scc
   706 000001A9 77E4                    	ja	short amch_2 ; while
   707                                  			; && scc<=(c = *p++))
   708 000001AB AC                      	lodsb
   709 000001AC 39C5                    	cmp	bp, ax
   710 000001AE 77DF                    	ja	short amch_2 ; while
   711                                  amch_4:
   712 000001B0 41                      	inc	cx ; ok++;
   713 000001B1 EBDC                    	jmp	short amch_2 ; while
   714                                  amch_5: 
   715 000001B3 89C2                    	mov	dx, ax ; (lc=cc)
   716 000001B5 39C5                    	cmp	bp, ax ; if (scc == (lc=cc))
   717 000001B7 75D6                      	jne	short amch_2 ; while
   718 000001B9 EBF5                    	jmp	short amch_4 ; ok++; ; while 
   719                                  amch_10:
   720 000001BB 3C3F                    	cmp	al, '?'
   721 000001BD 750B                    	jne	short amch_20
   722                                  amch_11: 
   723                                  	;case '?':
   724                                  	;	if (scc)
   725                                  	;	   return(amatch(s, p));
   726                                  	;	return(0);
   727                                  
   728 000001BF 09ED                    	or	bp, bp
   729 000001C1 7425                    	jz	short amch_xx ; not match
   730                                  
   731                                  	;return(amatch(s, p));
   732                                  	; bx = s
   733                                  	; si = p
   734 000001C3 E8AEFF                  	call	amatch
   735 000001C6 FEC8                    	dec	al ; 1 -> 0, 0 -> 0FFh
   736 000001C8 EB20                    	jmp	short amch_x
   737                                  amch_20:
   738 000001CA 3C2A                    	cmp	al, '*'
   739 000001CC 7508                    	jne	short amch_30
   740                                  amch_21:
   741                                  	;case '*':
   742                                  	;	return(umatch(--s, p));
   743                                  
   744 000001CE 4B                      	dec	bx ; --s
   745                                  	; bx = s
   746                                  	; si = p
   747 000001CF E81B00                  	call	umatch
   748 000001D2 FEC8                    	dec	al ; 1 -> 0, 0 -> 0FFh
   749 000001D4 EB14                    	jmp	short amch_x
   750                                  amch_30:
   751 000001D6 20C0                    	and	al, al
   752 000001D8 7508                    	jnz	short amch_40 ; default	
   753                                  amch_31:
   754                                  	;case '\0':
   755                                  	;	return(!scc);
   756                                  
   757                                  	; al = 0
   758 000001DA 09ED                    	or	bp, bp
   759 000001DC 750C                    	jnz	short amch_x ; not match
   760 000001DE FEC8                    	dec	al ; 0FFh
   761 000001E0 EB08                    	jmp	short amch_x ; match
   762                                  amch_40:
   763                                  	;default:
   764                                  	;	if (c!=scc)
   765                                  	;	   return(0);
   766                                  
   767 000001E2 39E8                    	cmp	ax, bp	
   768 000001E4 7502                    	jne	short amch_xx ; not match
   769                                  	;mov	al, 0FFh
   770                                  	;jmp	short amch_x ; match
   771 000001E6 EB8E                    	jmp	amch_next
   772                                  
   773                                  amch_xx:
   774 000001E8 30C0                    	xor	al, al ; 0
   775                                  amch_x:
   776                                  	; al = 0 -> not match
   777                                  	; al = 0FFh -> match
   778                                  	
   779 000001EA FEC0                    	inc	al ; 0 -> 1, 0FFh -> 0
   780                                  
   781                                  	; al = 0 -> zf = 1
   782                                  	; al > 0 -> zf = 0
   783                                  umch_x:
   784 000001EC C3                      	retn
   785                                  
   786                                  ;-----------------------------------------------------------------	
   787                                  
   788                                  umatch: ; umatch(s, p)
   789                                  	; char *s, *p;
   790                                  
   791                                  	; INPUT:
   792                                  	;	bx = s
   793                                  	;	si = p
   794                                  	; OUTPUT:
   795                                  	;	zf = 1 ->
   796                                  	;	     dir entry matches with input
   797                                  	;	zf = 0 ->
   798                                  	;	     dir entry does not match with input
   799                                  	;
   800                                  	; Modified registers: ax, bx, cx, dx
   801                                  
   802                                  	;if(*p==0)
   803                                  	;	return(1);
   804                                  	;while(*s)
   805                                  	;	if (amatch(s++,p))
   806                                  	;		return(1);
   807                                  	;return(0);
   808                                  
   809 000001ED 8A04                    	mov	al, [si]
   810 000001EF 08C0                    	or	al, al ; if (*p==0)
   811 000001F1 74F9                    	jz	short umch_x ; return(1) ; match
   812                                  umch_0:
   813 000001F3 8A07                    	mov	al, [bx] ; while(*s)	
   814 000001F5 20C0                    	and	al, al
   815 000001F7 7503                    	jnz	short umch_2
   816 000001F9 FEC0                    	inc	al ; 1 ; not match
   817                                  umch_1:
   818 000001FB C3                      	retn
   819                                  umch_2:
   820                                  	; bx = s
   821                                  	; si = p
   822 000001FC 56                      	push	si
   823 000001FD 53                      	push	bx
   824 000001FE E873FF                  	call	amatch
   825 00000201 5B                      	pop	bx
   826 00000202 5E                      	pop	si
   827 00000203 74F6                    	jz	short umch_1 ; al = 0 ; match
   828                                  	
   829                                  	; al = 1 ; not match
   830 00000205 43                      	inc	bx ; s++
   831 00000206 EBEB                    	jmp	short umch_0
   832                                  
   833                                  ;-----------------------------------------------------------------
   834                                  	
   835                                  cat:	;cat(as1, as2)
   836                                  	
   837                                  	;char *as1, *as2;
   838                                  
   839                                  	;register char *s1, *s2;
   840                                  	;register int c;
   841                                  
   842                                  	; INPUT:
   843                                  	;    bp = base name (path)
   844                                  	;    bx = name to be added
   845                                  	; OUTPUT:
   846                                  	;    dx = concatenated name (path)
   847                                  	;
   848                                  	; Modified regs: ax, cx, dx	
   849                                  
   850                                  	;s2 = string;
   851                                  	;s1 = as1;
   852                                  	
   853                                  	; bp = as1
   854                                  	; bx = as2
   855                                  	
   856 00000208 56                      	push	si ; *
   857 00000209 57                      	push	di ; **
   858                                  
   859 0000020A 8B3E[1303]              	mov	di, [string] ; s2 = string 	 
   860 0000020E 09ED                    	or	bp, bp ; 0 ?
   861 00000210 7425                    	jz	short cat_3
   862 00000212 89EE                    	mov	si, bp ; s1 = as1
   863                                  cat_0:
   864                                  	;while (c = *s1++) {
   865                                  	
   866 00000214 AC                      	lodsb
   867 00000215 08C0                    	or	al, al
   868 00000217 7412                    	jz	short cat_2
   869                                  
   870                                  	;if (s2 > &ab[STRSIZ])
   871                                  	;		toolong();
   872                                  
   873 00000219 81FF[FC05]              	cmp	di, ab+STRSIZ
   874 0000021D 7331                    	jnb	short cat_too_long
   875                                  	
   876 0000021F 247F                    	and	al, 7Fh ; c =& 0177;
   877 00000221 7505                    	jnz	short cat_1
   878                                  
   879                                  	;if (c==0) {
   880                                  	;	*s2++ = '/';
   881                                  	;	break;
   882                                  
   883                                  	;or	bx, bx ; bx = 0 ?
   884                                  	;jz	short cat_5 ; al = 0
   885                                  	
   886 00000223 B02F                    	mov	al, '/'
   887 00000225 AA                      	stosb
   888                                  	;jmp	short cat_3
   889 00000226 EB03                    	jmp	short cat_2
   890                                  
   891                                  cat_1:
   892                                  	; *s2++ = c;
   893 00000228 AA                      	stosb
   894 00000229 EBE9                    	jmp	short cat_0 ; while
   895                                  cat_2:
   896                                  	; al = 0
   897 0000022B 21DB                    	and	bx, bx ; bx = 0 ?
   898 0000022D 7508                    	jnz	short cat_3
   899 0000022F 81FF[FC05]              	cmp	di, ab+STRSIZ
   900 00000233 720B                    	jb	short cat_5
   901 00000235 EB19                    	jmp	short cat_too_long
   902                                  cat_3:
   903                                  	;s1 = as2;
   904 00000237 89DE                    	mov	si, bx	
   905                                  cat_4:
   906                                  	;do {
   907                                  	;	if (s2 > &ab[STRSIZ])
   908                                  	;		toolong();
   909                                  	;	*s2++ = c = *s1++;
   910                                  	;} while (c);
   911                                  
   912 00000239 81FF[FC05]              	cmp	di, ab+STRSIZ
   913 0000023D 7311                    	jnb	short cat_too_long
   914                                  	
   915 0000023F AC                      	lodsb	; c = *s1++;
   916                                  cat_5:
   917 00000240 AA                      	stosb	; *s2++ = c
   918 00000241 20C0                    	and	al, al  ; while (c);	
   919 00000243 75F4                    	jnz	short cat_4
   920                                  
   921                                  	;s1 = string;
   922                                  	;string = s2;
   923                                  	
   924 00000245 8B16[1303]              	mov	dx, [string]
   925 00000249 893E[1303]              	mov	[string], di
   926                                  
   927                                  	;return(s1);
   928                                  
   929 0000024D 5F                      	pop	di ; **
   930 0000024E 5E                      	pop	si ; *
   931 0000024F C3                      	retn
   932                                  
   933                                  ;-----------------------------------------------------------------
   934                                  
   935                                  cat_too_long:
   936 00000250 5F                      	pop	di ; **
   937 00000251 5E                      	pop	si ; *
   938                                  too_long:
   939 00000252 B8[FB02]                	mov	ax, msg_too_long
   940 00000255 E9B3FD                  	jmp	glb_print_exit
   941                                  
   942                                  ;	call	print_msg
   943                                  ;
   944                                  ;	sys	_exit	; sys exit
   945                                  ;hangemhigh:
   946                                  ;	nop
   947                                  ;	nop
   948                                  ;	jmp	short hangemhigh
   949                                  
   950                                  ;-----------------------------------------------------------------
   951                                  
   952                                  print_msg:
   953                                  	; ax = asciiz string address
   954 00000258 89C6                    	mov	si, ax
   955 0000025A 4E                      	dec	si
   956                                  nextchr:
   957 0000025B 46                      	inc	si
   958 0000025C 803C00                  	cmp	byte [si], 0
   959 0000025F 77FA                    	ja	short nextchr
   960                                  	;cmp	[si], 0Dh
   961                                  	;ja	short nextchr
   962 00000261 29C6                    	sub	si, ax
   963                                  	; si = asciiz string length
   964                                  	;
   965                                  	sys	_write, 1, ax, si
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000263 BB0100              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000266 89C1                <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97 00000268 89F2                <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000026A B80400              <1>  mov ax, %1
   102 0000026D CD20                <1>  int 20h
   966                                  	;
   967 0000026F C3                      	retn
   968                                  
   969                                  ;-----------------------------------------------------------------
   970                                  ;  data - initialized data
   971                                  ;-----------------------------------------------------------------
   972                                  
   973                                  program_msg:
   974 00000270 00                      	db  0
   975 00000271 526574726F20554E49-     	db  'Retro UNIX 8086 v1 /etc/glob by Erdogan TAN'
   975 0000027A 582038303836207631-
   975 00000283 202F6574632F676C6F-
   975 0000028C 62206279204572646F-
   975 00000295 67616E2054414E     
   976 0000029C 202D2033302F30352F-     	db  ' - 30/05/2022'
   976 000002A5 32303232           
   977 000002A9 00                      	db  0
   978                                  
   979                                  ROOTDIR:
   980 000002AA 2F00                    	db '/', 0
   981                                  
   982 000002AC 2E00                    DOT:	db '.', 0
   983                                  	;db 0, 0
   984                                  
   985                                  usr_bin:	
   986 000002AE 2F7573722F62696E2F-     	db '/usr/bin/', 0
   986 000002B7 00                 
   987                                  
   988                                  msg_arg_count:
   989 000002B8 0D0A                    	db 0Dh, 0Ah
   990 000002BA 41726720636F756E74      	db "Arg count"
   991                                  nextline:
   992 000002C3 0D0A00                  	db  0Dh, 0Ah, 0
   993                                  
   994                                  msg_no_match:
   995 000002C6 0D0A                    	db 0Dh, 0Ah
   996 000002C8 4E6F206D61746368        	db "No match"
   997 000002D0 0D0A00                  	db  0Dh, 0Ah, 0
   998                                  
   999                                  msg_not_found:
  1000 000002D3 0D0A                    	db 0Dh, 0Ah
  1001 000002D5 436F6D6D616E64206E-     	db "Command not found."
  1001 000002DE 6F7420666F756E642E 
  1002 000002E7 0D0A00                  	db  0Dh, 0Ah, 0
  1003                                  
  1004                                  msg_no_dir:
  1005 000002EA 0D0A                    	db 0Dh, 0Ah
  1006 000002EC 4E6F20646972656374-     	db "No directory"
  1006 000002F5 6F7279             
  1007 000002F8 0D0A00                  	db  0Dh, 0Ah, 0
  1008                                  
  1009                                  msg_too_long:
  1010 000002FB 0D0A                    	db 0Dh, 0Ah
  1011 000002FD 417267206C69737420-     	db 'Arg list too long'
  1011 00000306 746F6F206C6F6E67   
  1012 0000030E 0D0A00                  	db  0Dh, 0Ah, 0
  1013                                  
  1014 00000311 [2A03]                  av:	dw ava	 ;char **av &ava[1];
  1015 00000313 [F203]                  string:	dw ab	 ;char *string ab;
  1016                                  
  1017                                  ;-----------------------------------------------------------------
  1018                                  ;  bss - uninitialized data
  1019                                  ;-----------------------------------------------------------------
  1020                                  
  1021 00000315 90<rep 3h>              align 4
  1022                                  
  1023                                  bss_start:
  1024                                  
  1025                                  ABSOLUTE bss_start
  1026                                  
  1027                                  ;argc:	resd 1
  1028 00000318 ??                      argc:	resb 1
  1029 00000319 ??                      errno:	resb 1	;int errno;
  1030 0000031A ????                    ncoll:	resw 1	;int ncoll;
  1031                                  entry:
  1032                                  entry.ino:
  1033 0000031C ????                    	resw 1
  1034                                  entry.name:
  1035                                  	;resb 14
  1036 0000031E <res Ah>                	resb 10
  1037 00000328 ????                    	resb 2
  1038                                  
  1039 0000032A <res C8h>               ava:	resb 200
  1040 000003F2 <res 20Ah>              ab:	resb STRSIZ ; 522
  1041                                  
  1042                                  ; 28/05/2022
  1043                                  ;-----------------------------------------------------------------
  1044                                  ; Original UNIX v5 - /etc/glob (utility) c source code (glob.c)
  1045                                  ;-----------------------------------------------------------------
  1046                                  ;/* UNIX V5 source code: see www.tuhs.org for details. */;
  1047                                  ; * v5root.tar.gz (/usr/source/s1) *
  1048                                  ;
  1049                                  ;#
  1050                                  ;/* global command --
  1051                                  ;
  1052                                  ;  glob params
  1053                                  ;
  1054                                  ;  "*" in params matches r.e ".*"
  1055                                  ;  "?" in params matches r.e. "."
  1056                                  ;  "[...]" in params matches character class
  1057                                  ;  "[...a-z...]" in params matches a through z.
  1058                                  ;
  1059                                  ;  perform command with argument list
  1060                                  ;  constructed as follows:
  1061                                  ;    if param does not contain "*", "[", or "?", use it as is
  1062                                  ;    if it does, find all files in current directory
  1063                                  ;    which match the param, sort them, and use them
  1064                                  ;
  1065                                  ;  prepend the command name with "/bin" or "/usr/bin"
  1066                                  ;  as required.
  1067                                  ;*/
  1068                                  ;
  1069                                  ;#define E2BIG	 7
  1070                                  ;#define ENOEXEC 8
  1071                                  ;#define ENOENT	 2
  1072                                  ;
  1073                                  ;#define STRSIZ	522
  1074                                  ;char	ab[STRSIZ];		/* generated characters */
  1075                                  ;char	*ava[200];		/* generated arguments */
  1076                                  ;char	**av &ava[1];
  1077                                  ;char	*string ab;
  1078                                  ;int	errno;
  1079                                  ;int	ncoll;
  1080                                  ;
  1081                                  ;main(argc, argv)
  1082                                  ;char *argv[];
  1083                                  ;{
  1084                                  ;	register char *cp;
  1085                                  ;
  1086                                  ;	if (argc < 3) {
  1087                                  ;		write(2, "Arg count\n", 10);
  1088                                  ;		return;
  1089                                  ;	}
  1090                                  ;	argv++;
  1091                                  ;	*av++ = *argv;
  1092                                  ;	while (--argc >= 2)
  1093                                  ;		expand(*++argv);
  1094                                  ;	if (ncoll==0) {
  1095                                  ;		write(2, "No match\n", 9);
  1096                                  ;		return;
  1097                                  ;	}
  1098                                  ;	execute(ava[1], &ava[1]);
  1099                                  ;	cp = cat("/usr/bin/", ava[1]);
  1100                                  ;	execute(cp+4, &ava[1]);
  1101                                  ;	execute(cp, &ava[1]);
  1102                                  ;	write(2, "Command not found.\n", 19);
  1103                                  ;}
  1104                                  ;
  1105                                  ;expand(as)
  1106                                  ;char *as;
  1107                                  ;{
  1108                                  ;	register char *s, *cs;
  1109                                  ;	register int dirf;
  1110                                  ;	char **oav;
  1111                                  ;	static struct {
  1112                                  ;		int	ino;
  1113                                  ;		char	name[16];
  1114                                  ;	} entry;
  1115                                  ;
  1116                                  ;	s = cs = as;
  1117                                  ;	while (*cs!='*' && *cs!='?' && *cs!='[') {
  1118                                  ;		if (*cs++ == 0) {
  1119                                  ;			*av++ = cat(s, "");
  1120                                  ;			return;
  1121                                  ;		}
  1122                                  ;	}
  1123                                  ;	for (;;) {
  1124                                  ;		if (cs==s) {
  1125                                  ;			dirf = open(".", 0);
  1126                                  ;			s = "";
  1127                                  ;			break;
  1128                                  ;		}
  1129                                  ;		if (*--cs == '/') {
  1130                                  ;			*cs = 0;
  1131                                  ;			dirf = open(s==cs? "/": s, 0);
  1132                                  ;			*cs++ = 0200;
  1133                                  ;			break;
  1134                                  ;		}
  1135                                  ;	}
  1136                                  ;	if (dirf<0) {
  1137                                  ;		write(2, "No directory\n", 13);
  1138                                  ;		exit();
  1139                                  ;	}
  1140                                  ;	oav = av;
  1141                                  ;	while (read(dirf, &entry, 16) == 16) {
  1142                                  ;		if (entry.ino==0)
  1143                                  ;			continue;
  1144                                  ;		if (match(entry.name, cs)) {
  1145                                  ;			*av++ = cat(s, entry.name);
  1146                                  ;			ncoll++;
  1147                                  ;		}
  1148                                  ;	}
  1149                                  ;	close(dirf);
  1150                                  ;	sort(oav);
  1151                                  ;}
  1152                                  ;
  1153                                  ;sort(oav)
  1154                                  ;char **oav;
  1155                                  ;{
  1156                                  ;	register char **p1, **p2, **c;
  1157                                  ;
  1158                                  ;	p1 = oav;
  1159                                  ;	while (p1 < av-1) {
  1160                                  ;		p2 = p1;
  1161                                  ;		while(++p2 < av) {
  1162                                  ;			if (compar(*p1, *p2) > 0) {
  1163                                  ;				c = *p1;
  1164                                  ;				*p1 = *p2;
  1165                                  ;				*p2 = c;
  1166                                  ;			}
  1167                                  ;		}
  1168                                  ;		p1++;
  1169                                  ;	}
  1170                                  ;}
  1171                                  ;
  1172                                  ;execute(afile, aarg)
  1173                                  ;char *afile;
  1174                                  ;char **aarg;
  1175                                  ;{
  1176                                  ;	register char *file, **arg;
  1177                                  ;
  1178                                  ;	arg = aarg;
  1179                                  ;	file = afile;
  1180                                  ;	execv(file, arg);
  1181                                  ;	if (errno==ENOEXEC) {
  1182                                  ;		arg[0] = file;
  1183                                  ;		*--arg = "/bin/sh";
  1184                                  ;		execv(*arg, arg);
  1185                                  ;	}
  1186                                  ;	if (errno==E2BIG)
  1187                                  ;		toolong();
  1188                                  ;}
  1189                                  ;
  1190                                  ;toolong()
  1191                                  ;{
  1192                                  ;	write(2, "Arg list too long\n", 18);
  1193                                  ;	exit();
  1194                                  ;}
  1195                                  ;
  1196                                  ;match(s, p)
  1197                                  ;char *s, *p;
  1198                                  ;{
  1199                                  ;	if (*s=='.' && *p!='.')
  1200                                  ;		return(0);
  1201                                  ;	return(amatch(s, p));
  1202                                  ;}
  1203                                  ;
  1204                                  ;amatch(as, ap)
  1205                                  ;char *as, *ap;
  1206                                  ;{
  1207                                  ;	register char *s, *p;
  1208                                  ;	register scc;
  1209                                  ;	int c, cc, ok, lc;
  1210                                  ;
  1211                                  ;	s = as;
  1212                                  ;	p = ap;
  1213                                  ;	if (scc = *s++)
  1214                                  ;		if ((scc =& 0177) == 0)
  1215                                  ;			scc = 0200;
  1216                                  ;	switch (c = *p++) {
  1217                                  ;
  1218                                  ;	case '[':
  1219                                  ;		ok = 0;
  1220                                  ;		lc = 077777;
  1221                                  ;		while (cc = *p++) {
  1222                                  ;			if (cc==']') {
  1223                                  ;				if (ok)
  1224                                  ;					return(amatch(s, p));
  1225                                  ;				else
  1226                                  ;					return(0);
  1227                                  ;			} else if (cc=='-') {
  1228                                  ;				if (lc<=scc && scc<=(c = *p++))
  1229                                  ;					ok++;
  1230                                  ;			} else
  1231                                  ;				if (scc == (lc=cc))
  1232                                  ;					ok++;
  1233                                  ;		}
  1234                                  ;		return(0);
  1235                                  ;
  1236                                  ;	default:
  1237                                  ;		if (c!=scc)
  1238                                  ;			return(0);
  1239                                  ;
  1240                                  ;	case '?':
  1241                                  ;		if (scc)
  1242                                  ;			return(amatch(s, p));
  1243                                  ;		return(0);
  1244                                  ;
  1245                                  ;	case '*':
  1246                                  ;		return(umatch(--s, p));
  1247                                  ;
  1248                                  ;	case '\0':
  1249                                  ;		return(!scc);
  1250                                  ;	}
  1251                                  ;}
  1252                                  ;
  1253                                  ;umatch(s, p)
  1254                                  ;char *s, *p;
  1255                                  ;{
  1256                                  ;	if(*p==0)
  1257                                  ;		return(1);
  1258                                  ;	while(*s)
  1259                                  ;		if (amatch(s++,p))
  1260                                  ;			return(1);
  1261                                  ;	return(0);
  1262                                  ;}
  1263                                  ;
  1264                                  ;compar(as1, as2)
  1265                                  ;char *as1, *as2;
  1266                                  ;{
  1267                                  ;	register char *s1, *s2;
  1268                                  ;
  1269                                  ;	s1 = as1;
  1270                                  ;	s2 = as2;
  1271                                  ;	while (*s1++ ==  *s2)
  1272                                  ;		if (*s2++ == 0)
  1273                                  ;			return(0);
  1274                                  ;	return (*--s1 - *s2);
  1275                                  ;}
  1276                                  ;
  1277                                  ;cat(as1, as2)
  1278                                  ;char *as1, *as2;
  1279                                  ;{
  1280                                  ;	register char *s1, *s2;
  1281                                  ;	register int c;
  1282                                  ;
  1283                                  ;	s2 = string;
  1284                                  ;	s1 = as1;
  1285                                  ;	while (c = *s1++) {
  1286                                  ;		if (s2 > &ab[STRSIZ])
  1287                                  ;			toolong();
  1288                                  ;		c =& 0177;
  1289                                  ;		if (c==0) {
  1290                                  ;			*s2++ = '/';
  1291                                  ;			break;
  1292                                  ;		}
  1293                                  ;		*s2++ = c;
  1294                                  ;	}
  1295                                  ;	s1 = as2;
  1296                                  ;	do {
  1297                                  ;		if (s2 > &ab[STRSIZ])
  1298                                  ;			toolong();
  1299                                  ;		*s2++ = c = *s1++;
  1300                                  ;	} while (c);
  1301                                  ;	s1 = string;
  1302                                  ;	string = s2;
  1303                                  ;	return(s1);
  1304                                  ;}
  1305                                  
  1306                                  ; 28/05/2022
  1307                                  ;-----------------------------------------------------------------
  1308                                  ; Original UNIX v2 - /etc/glob (utility) c source code (glob.c)
  1309                                  ;-----------------------------------------------------------------
  1310                                  ;/* UNIX V2 source code: see www.tuhs.org for details. */;
  1311                                  ; * svntree-20081216.tar.gz (unix72) *
  1312                                  ;
  1313                                  ;/* global command --
  1314                                  ;
  1315                                  ;  glob params
  1316                                  ;
  1317                                  ;  "*" in params matches r.e ".*"
  1318                                  ;  "?" in params matches r.e. "."
  1319                                  ;  "[...]" in params matches character class
  1320                                  ;  "[...a-z...]" in params matches a through z.
  1321                                  ;
  1322                                  ;  perform command with argument list
  1323                                  ;  constructed as follows:
  1324                                  ;    if param does not contain "*", "[", or "?", use it as is
  1325                                  ;    if it does, find all files in current directory
  1326                                  ;    which match the param, sort them, and use them
  1327                                  ;
  1328                                  ;  prepend the command name with "/bin" or "/usr/bin"
  1329                                  ;  as required.
  1330                                  ;*/
  1331                                  ;
  1332                                  ;char	ab[2000];		/* generated characters */
  1333                                  ;char	*ava[200];		/* generated arguments */
  1334                                  ;char	**av ava;
  1335                                  ;char	*string ab;
  1336                                  ;
  1337                                  ;main(argc, argv)
  1338                                  ;char *argv[];
  1339                                  ;{
  1340                                  ;	int i, j, c;
  1341                                  ;	int inode, dirf, ap;
  1342                                  ;	int fb[5], sb[17];
  1343                                  ;	char *cp, *cpo;
  1344                                  ;
  1345                                  ;	if (argc < 3) {
  1346                                  ;		write(1, "Arg count\n", 10);
  1347                                  ;		return;
  1348                                  ;	}
  1349                                  ;	ap = 0;
  1350                                  ;	av++;
  1351                                  ;	fb[4] = 0;
  1352                                  ;loop:
  1353                                  ;	cpo = cp = *++argv;
  1354                                  ;	while(c = *cp++) if (c=='*' | c=='?' | c=='[') goto compl;
  1355                                  ;	av[ap++] = copy(cpo);
  1356                                  ;	if (--argc>=2) goto loop;
  1357                                  ;	goto donow;
  1358                                  ;
  1359                                  ;compl:
  1360                                  ;	if(*--cp == '/') {
  1361                                  ;		*cp = '\0';
  1362                                  ;		if((dirf=open(cp==cpo? "/" : cpo, 0))<0)
  1363                                  ;			goto oper;
  1364                                  ;		*cp++ = '/';
  1365                                  ;		goto compl1;
  1366                                  ;	}
  1367                                  ;	if(cp != cpo) goto compl;
  1368                                  ;	if((dirf=open(".",0)) >= 0) goto compl1;
  1369                                  ;oper:
  1370                                  ;	write(1, "No directory\n", 13);
  1371                                  ;	return;
  1372                                  ;compl1:
  1373                                  ;	j = ap;
  1374                                  ;l2:
  1375                                  ;	while (read(dirf, &inode, 2)>0) {
  1376                                  ;		read(dirf, fb, 8);
  1377                                  ;		if (inode==0) goto l2;
  1378                                  ;		if (match(fb, cp)) {
  1379                                  ;			c = *cp;
  1380                                  ;			*cp = '\0';
  1381                                  ;			av[ap++] = cat(cpo, fb);
  1382                                  ;			*cp = c;
  1383                                  ;		}
  1384                                  ;	}
  1385                                  ;	close(dirf);
  1386                                  ;	i = j;
  1387                                  ;	while(i<ap-1) {
  1388                                  ;		j = i;
  1389                                  ;		while(++j<ap) {
  1390                                  ;			if (compar(av[i],av[j])) {
  1391                                  ;				c = av[i];
  1392                                  ;				av[i] = av[j];
  1393                                  ;				av[j] = c;
  1394                                  ;			}
  1395                                  ;		}
  1396                                  ;		i++;
  1397                                  ;	}
  1398                                  ;	if (--argc>=2) goto loop;
  1399                                  ;donow:
  1400                                  ;	if (ap<=1) {
  1401                                  ;		write(1, "No match\n", 9);
  1402                                  ;		return;
  1403                                  ;	}
  1404                                  ;	av[ap] = 0;
  1405                                  ;	execv(av[0], av);
  1406                                  ;	i = cat("/bin/", av[0]);
  1407                                  ;	execv(i, av);
  1408                                  ;	i = cat("/usr", i);
  1409                                  ;	execv(i, av);
  1410                                  ;	if (stat(i, sb) == 0) {
  1411                                  ;		*av = i;
  1412                                  ;		*--av = "/bin/sh";
  1413                                  ;		execv(av[0], av);
  1414                                  ;	}
  1415                                  ;	write(1, "No command\n", 11);
  1416                                  ;}
  1417                                  ;
  1418                                  ;match(s, p)
  1419                                  ;char *s, *p; {
  1420                                  ;	if (*s=='.' & *p!='.') return(0);
  1421                                  ;	return(amatch(s, p));
  1422                                  ;}
  1423                                  ;
  1424                                  ;amatch(s, p)
  1425                                  ;char *s, *p;
  1426                                  ;{
  1427                                  ;	int c, cc, ok, lc, scc;
  1428                                  ;
  1429                                  ;	scc = *s;
  1430                                  ;	lc = 077777;
  1431                                  ;	switch (c = *p) {
  1432                                  ;
  1433                                  ;	case '[':
  1434                                  ;		ok = 0;
  1435                                  ;		while (cc = *++p) {
  1436                                  ;			switch (cc) {
  1437                                  ;
  1438                                  ;			case ']':
  1439                                  ;				if (ok)
  1440                                  ;					return(amatch(++s, ++p));
  1441                                  ;				else
  1442                                  ;					return(0);
  1443                                  ;
  1444                                  ;			case '-':
  1445                                  ;				ok =| lc <= scc & scc <= (cc=p[1]);
  1446                                  ;			}
  1447                                  ;			if (scc==(lc=cc)) ok++;
  1448                                  ;		}
  1449                                  ;		return(0);
  1450                                  ;
  1451                                  ;	case '?':
  1452                                  ;	caseq:
  1453                                  ;		if(scc) return(amatch(++s, ++p));
  1454                                  ;		return(0);
  1455                                  ;	case '*':
  1456                                  ;		return(umatch(s, ++p));
  1457                                  ;	case 0:
  1458                                  ;		return(!scc);
  1459                                  ;	}
  1460                                  ;	if (c==scc) goto caseq;
  1461                                  ;	return(0);
  1462                                  ;}
  1463                                  ;
  1464                                  ;umatch(s, p)
  1465                                  ;char *s, *p;
  1466                                  ;{
  1467                                  ;	if(*p==0) return(1);
  1468                                  ;	while(*s)
  1469                                  ;		if (amatch(s++,p)) return(1);
  1470                                  ;	return(0);
  1471                                  ;}
  1472                                  ;
  1473                                  ;compar(s1,s2)
  1474                                  ;char *s1, *s2;
  1475                                  ;{
  1476                                  ;	int c1,c2;
  1477                                  ;
  1478                                  ;loop:
  1479                                  ;	if ((c1 = *s1++)==0) return(0);
  1480                                  ;	if ((c2 = *s2++)==0) return(1);
  1481                                  ;	if (c1==c2) goto loop;
  1482                                  ;	return(c1>c2);
  1483                                  ;}
  1484                                  ;
  1485                                  ;copy(s1)
  1486                                  ;char *s1;
  1487                                  ;{
  1488                                  ;	char *ts;
  1489                                  ;
  1490                                  ;	ts = string;
  1491                                  ;	while(*string++ = *s1++);
  1492                                  ;	return(ts);
  1493                                  ;}
  1494                                  ;
  1495                                  ;cat(s1, s2)
  1496                                  ;char *s1, *s2;
  1497                                  ;{
  1498                                  ;	char *ts;
  1499                                  ;
  1500                                  ;	ts = string;
  1501                                  ;	while(*string++ = *s1++);
  1502                                  ;	string--;
  1503                                  ;	while(*string++ = *s2++);
  1504                                  ;	return(ts);
  1505                                  ;}
