     1                                  ; ****************************************************************************
     2                                  ; cat386.s (Retro Unix 386 v1) - /bin/cat - concatenate files
     3                                  ; ----------------------------------------------------------------------------
     4                                  ;
     5                                  ; RETRO UNIX 386 (Retro Unix == Turkish Rational Unix)
     6                                  ; Operating System Project (v0.2) by ERDOGAN TAN (Beginning: 24/12/2013)
     7                                  ;
     8                                  ; Retro UNIX 8086 v1 - '/bin/cat' file
     9                                  ;
    10                                  ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
    11                                  ; (v0.1 - Beginning: 11/07/2012)
    12                                  ;
    13                                  ; [ Last Modification: 05/03/2022 ] -cat1.s-
    14                                  ;
    15                                  ; Derived from UNIX Operating System (v1.0 for PDP-11) 
    16                                  ; (Original) Source Code by Ken Thompson (Bell Laboratories, 1971-1972)
    17                                  ; ****************************************************************************
    18                                  ; ((nasm cat1.s -l cat1.txt -o cat1 -Z error.txt))
    19                                  ; cat386.s - cat1.s (05/03/2022, Retro UNIX 386 v1 & v1.1 & v1.2)
    20                                  ; cat386.s - cat0.s (17/10/2015 - 28/12/2015, Retro UNIX 386 v1, NASM 2.11)
    21                                  ; CAT2.ASM (02/12/2013 - 16/07/2015, Retro UNIX 8086 v1, MASM 6.11) 
    22                                  
    23                                  ; 17/10/2015
    24                                  
    25                                  ; UNIX v1 system calls
    26                                  _rele 	equ 0
    27                                  _exit 	equ 1
    28                                  _fork 	equ 2
    29                                  _read 	equ 3
    30                                  _write	equ 4
    31                                  _open	equ 5
    32                                  _close 	equ 6
    33                                  _wait 	equ 7
    34                                  _creat 	equ 8
    35                                  _link 	equ 9
    36                                  _unlink	equ 10
    37                                  _exec	equ 11
    38                                  _chdir	equ 12
    39                                  _time 	equ 13
    40                                  _mkdir 	equ 14
    41                                  _chmod	equ 15
    42                                  _chown	equ 16
    43                                  _break	equ 17
    44                                  _stat	equ 18
    45                                  _seek	equ 19
    46                                  _tell 	equ 20
    47                                  _mount	equ 21
    48                                  _umount	equ 22
    49                                  _setuid	equ 23
    50                                  _getuid	equ 24
    51                                  _stime	equ 25
    52                                  _quit	equ 26	
    53                                  _intr	equ 27
    54                                  _fstat	equ 28
    55                                  _emt 	equ 29
    56                                  _mdate 	equ 30
    57                                  _stty 	equ 31
    58                                  _gtty	equ 32
    59                                  _ilgins	equ 33
    60                                  _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
    61                                  _msg    equ 35 ; Retro UNIX 386 v1 feature only !
    62                                  
    63                                  %macro sys 1-4
    64                                      ; 03/09/2015	
    65                                      ; 13/04/2015
    66                                      ; Retro UNIX 386 v1 system call.		
    67                                      %if %0 >= 2   
    68                                          mov ebx, %2
    69                                          %if %0 >= 3    
    70                                              mov ecx, %3
    71                                              %if %0 = 4
    72                                                 mov edx, %4   
    73                                              %endif
    74                                          %endif
    75                                      %endif
    76                                      mov eax, %1
    77                                      int 30h	   
    78                                  %endmacro
    79                                  
    80                                  ; Retro UNIX 386 v1 system call format:
    81                                  ; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
    82                                  
    83                                  [BITS 32] ; We need 32-bit intructions for protected mode
    84                                  
    85                                  [ORG 0] 
    86                                  
    87                                  START_CODE:
    88                                  	;; / cat -- concatenate files
    89                                  
    90                                  	sys	_write, 1, nl, 2
    64                              <1> 
    65                              <1> 
    66                              <1> 
    67                              <1>  %if %0 >= 2
    68 00000000 BB01000000          <1>  mov ebx, %2
    69                              <1>  %if %0 >= 3
    70 00000005 B9[04010000]        <1>  mov ecx, %3
    71                              <1>  %if %0 = 4
    72 0000000A BA02000000          <1>  mov edx, %4
    73                              <1>  %endif
    74                              <1>  %endif
    75                              <1>  %endif
    76 0000000F B804000000          <1>  mov eax, %1
    77 00000014 CD30                <1>  int 30h
    91                                  
    92 00000016 5D                      	pop	ebp
    93 00000017 5A                      	pop	edx
    94                                  	; esi = 0 ; ('sysexec' sets regs to zero)
    95                                  	; 05/03/2022
    96                                  	;mov	esi, fin 
    97                                  	;mov    edi, obuf
    98                                  	;EAX = 2 (written byte count)
    99 00000018 30C0                    	xor	al, al ; 0
   100 0000001A 4D                              dec     ebp
   101 0000001B 745A                    	jz	short cat_3
   102                                  		;;mov	(sp)+,r5
   103                                  		;;tst	(sp)+
   104                                  		;;mov	$obuf,r2
   105                                  		;;cmp	r5,$1
   106                                  		;;beq	3f
   107                                  cat_0:	
   108 0000001D 5B                      	pop	ebx
   109 0000001E 803B2D                  	cmp	byte [ebx], '-'
   110 00000021 7410                    	je	short cat_2
   111                                  		;;dec	r5
   112                                  		;;ble	done
   113                                  		;;mov	(sp)+,r0
   114                                  		;;cmpb	(r0),$'-
   115                                  		;;bne	2f
   116                                  		;;clr	fin
   117                                  		;;br	3f
   118                                  cat_1:
   119                                  	;;2:
   120                                  	; ebx = file name offset
   121 00000023 31C9                    	xor 	ecx, ecx ; 0
   122                                  	sys 	_open
    64                              <1> 
    65                              <1> 
    66                              <1> 
    67                              <1>  %if %0 >= 2
    68                              <1>  mov ebx, %2
    69                              <1>  %if %0 >= 3
    70                              <1>  mov ecx, %3
    71                              <1>  %if %0 = 4
    72                              <1>  mov edx, %4
    73                              <1>  %endif
    74                              <1>  %endif
    75                              <1>  %endif
    76 00000025 B805000000          <1>  mov eax, %1
    77 0000002A CD30                <1>  int 30h
   123                                  	;jc	short cat_7
   124                                  	; 05/03/2022 ; (+)
   125 0000002C 7305                    	jnc	short cat_2
   126 0000002E E9BF000000              	jmp	cat_7
   127                                  cat_2:
   128                                  	; 05/03/2022
   129 00000033 89C6                    	mov	esi, eax
   130                                  	;mov	[esi], eax ; 05/03/2022
   131                                  	;mov	[esi], ax
   132                                  		;;mov	r0,0f
   133                                  		;;sys	open; 0:..; 0
   134                                  		;;bes	loop
   135                                  		;;mov	r0,fin
   136                                  
   137                                  	; 05/03/2022 ; (+)
   138                                  	; convert user's file number to inode number
   139                                  	; (get 34 byte inode details, inode num + inode)
   140                                  	; (get 66 byte inode details for runix 386 v1.2)
   141                                  	sys	_fstat, esi, iobuf 
    64                              <1> 
    65                              <1> 
    66                              <1> 
    67                              <1>  %if %0 >= 2
    68 00000035 89F3                <1>  mov ebx, %2
    69                              <1>  %if %0 >= 3
    70 00000037 B9[10010000]        <1>  mov ecx, %3
    71                              <1>  %if %0 = 4
    72                              <1>  mov edx, %4
    73                              <1>  %endif
    74                              <1>  %endif
    75                              <1>  %endif
    76 0000003C B81C000000          <1>  mov eax, %1
    77 00000041 CD30                <1>  int 30h
   142                                  	;jc	short cat_7
   143                                  	; 05/03/2022 ; (+)
   144 00000043 7305                    	jnc	short cat_f
   145 00000045 E9A8000000              	jmp	cat_7
   146                                  cat_f:
   147                                  	; 05/03/2022 ; (+)
   148                                  	;;movzx	edi, word [iobuf] ; inode number
   149                                  	;movzx	edi, word [ecx] ; inode number
   150                                  	; edi = 0 ; ('sysexec' sets regs to zero)
   151 0000004A 668B39                  	mov	di, [ecx]	
   152                                  
   153                                  	; 05/03/2022 ; (+)
   154                                  	; check against '/dev/tty' inode number
   155                                  	;sys	_stat, consoletty, iobuf
   156                                  	; (get 34 byte inode details, inode num + inode)
   157                                  	; (get 66 byte inode details for runix 386 v1.2)
   158                                  	;mov	ecx, iobuf 
   159                                  	sys	_stat, consoletty
    64                              <1> 
    65                              <1> 
    66                              <1> 
    67                              <1>  %if %0 >= 2
    68 0000004D BB[07010000]        <1>  mov ebx, %2
    69                              <1>  %if %0 >= 3
    70                              <1>  mov ecx, %3
    71                              <1>  %if %0 = 4
    72                              <1>  mov edx, %4
    73                              <1>  %endif
    74                              <1>  %endif
    75                              <1>  %endif
    76 00000052 B812000000          <1>  mov eax, %1
    77 00000057 CD30                <1>  int 30h
   160 00000059 7207                    	jc	short cat_x
   161                                  	
   162                                  	;movzx	eax, word [iobuf]
   163 0000005B 668B01                  	mov	ax, [ecx]
   164 0000005E 39C7                    	cmp	edi, eax ; is it /dev/tty inode ?
   165 00000060 7413                    	je	short cat_y ; yes
   166                                  	; no, it is not '/dev/tty'
   167                                  cat_x:
   168                                  	; 05/03/2022 ; (+)
   169                                  	; get inode number of current tty (stdin)
   170                                  	; (get 34 byte inode details, inode num + inode)
   171                                  	; (get 66 byte inode details for runix 386 v1.2)
   172                                  	;sys	_fstat, 0, iobuf 
   173                                  	;;jc	short cat_z
   174                                  	;mov	ecx, iobuf	
   175                                  	sys	_fstat, 0  ; get stdin file inode details
    64                              <1> 
    65                              <1> 
    66                              <1> 
    67                              <1>  %if %0 >= 2
    68 00000062 BB00000000          <1>  mov ebx, %2
    69                              <1>  %if %0 >= 3
    70                              <1>  mov ecx, %3
    71                              <1>  %if %0 = 4
    72                              <1>  mov edx, %4
    73                              <1>  %endif
    74                              <1>  %endif
    75                              <1>  %endif
    76 00000067 B81C000000          <1>  mov eax, %1
    77 0000006C CD30                <1>  int 30h
   176                                  
   177                                  	;movzx	eax, word [iobuf]
   178 0000006E 668B01                  	mov	ax, [ecx] ; inode number
   179 00000071 39C7                    	cmp	edi, eax
   180 00000073 7504                    	jne	short cat_z ; (ebx = 0)
   181                                  	; (/dev/tyy0 .. /dev/tty9)
   182                                  cat_y:
   183                                  	; same with input file inode
   184 00000075 29F6                    	sub	esi, esi ; 0 
   185                                  		; use console tty input (stdin)
   186                                  cat_3:	;;3:
   187                                  	; 05/03/2022
   188                                  	;or	eax, eax  ; console tty input (stdin) ?	
   189                                  	;jnz	short cat_r ; no..
   190                                  	;
   191                                  	; get keyboard status of console tty
   192 00000077 31DB                    	xor	ebx, ebx  ; 0	
   193                                  cat_z:
   194 00000079 31C9                    	xor	ecx, ecx  ; 0
   195                                  	sys	_gtty
    64                              <1> 
    65                              <1> 
    66                              <1> 
    67                              <1>  %if %0 >= 2
    68                              <1>  mov ebx, %2
    69                              <1>  %if %0 >= 3
    70                              <1>  mov ecx, %3
    71                              <1>  %if %0 = 4
    72                              <1>  mov edx, %4
    73                              <1>  %endif
    74                              <1>  %endif
    75                              <1>  %endif
    76 0000007B B820000000          <1>  mov eax, %1
    77 00000080 CD30                <1>  int 30h
   196                                  	;;sub	eax, eax  ; clear ax
   197                                  	;mov	eax, [esi] ; file descriptor/number
   198 00000082 21DB                    	and	ebx, ebx ; is there a waiting char ?
   199                                  	;jz	short cat_3 ; no, wait for keystroke again
   200 00000084 7506                    	jnz	short cat_c ; (a char is waiting in buffer)
   201                                  	;mov	eax, [esi]
   202                                  	;or	eax, eax ; 0 ; console tty input ?
   203 00000086 09F6                    	or	esi, esi ; 05/03/2022
   204 00000088 752D                    	jnz	short cat_r ; no, continue (to read file)
   205 0000008A EBED                    	jmp	short cat_z ; yes, wait for keystroke again		
   206                                  cat_c:
   207                                  	; 05/03/2022
   208                                  	; read from console tty (stdin)
   209                                  	sys	_read, 0, iobuf, 1	
    64                              <1> 
    65                              <1> 
    66                              <1> 
    67                              <1>  %if %0 >= 2
    68 0000008C BB00000000          <1>  mov ebx, %2
    69                              <1>  %if %0 >= 3
    70 00000091 B9[10010000]        <1>  mov ecx, %3
    71                              <1>  %if %0 = 4
    72 00000096 BA01000000          <1>  mov edx, %4
    73                              <1>  %endif
    74                              <1>  %endif
    75                              <1>  %endif
    76 0000009B B803000000          <1>  mov eax, %1
    77 000000A0 CD30                <1>  int 30h
   210                                  		; read one char into [iobuf]
   211 000000A2 7241                    	jc	short cat_6 ; (ebx = 0)
   212                                  	;and	eax, eax
   213                                  	;jz	short cat_6
   214 000000A4 48                      	dec	eax ; 1 -> 0
   215 000000A5 753E                    	jnz	short cat_6
   216 000000A7 40                      	inc	eax
   217                                  	; eax = 1
   218 000000A8 8A1D[10010000]          	mov	bl, [iobuf] ; ascii code of the character
   219 000000AE 80FB1B                  	cmp	bl, 1Bh ; 27 ; ESCape key ?
   220 000000B1 7447                    	je	short cat_exit ; yes, exit
   221                                  	;mov	eax, [esi] ; file descriptor/number
   222                                  	;or	eax, eax ; 0 ; console_tty input ?
   223 000000B3 09F6                    	or	esi, esi ; 05/03/2022	
   224 000000B5 7419                    	jz	short cat_w ; yes, write char to screen
   225                                  cat_r:
   226                                  	; 05/03/2022
   227                                  	;mov	eax, [esi] ; file descriptor/number
   228                                  	;;mov	ax, [esi]
   229                                  	;
   230                                  	;sys	_read, eax, iobuf, 512 ; 16/07/2015
   231                                  	;;sys 	_read, eax, ibuf, 512 
   232                                  	;jc	short cat_6
   233                                  	; 05/03/2022
   234                                  	; esi = file descriptor/number
   235                                  	sys	_read, esi, iobuf, 512	
    64                              <1> 
    65                              <1> 
    66                              <1> 
    67                              <1>  %if %0 >= 2
    68 000000B7 89F3                <1>  mov ebx, %2
    69                              <1>  %if %0 >= 3
    70 000000B9 B9[10010000]        <1>  mov ecx, %3
    71                              <1>  %if %0 = 4
    72 000000BE BA00020000          <1>  mov edx, %4
    73                              <1>  %endif
    74                              <1>  %endif
    75                              <1>  %endif
    76 000000C3 B803000000          <1>  mov eax, %1
    77 000000C8 CD30                <1>  int 30h
   236                                  		 ; read 512 chars into [iobuf]
   237                                  	;jc	short cat_6
   238 000000CA 721D                    	jc	short cat_k ; 05/03/2022
   239                                  
   240                                  	; NOTE: If input file is a tty (keyboard)
   241                                  	;	only 1 byte will be read, by ignoring
   242                                  	;	byte count (512).
   243                                  	;	Retro UNIX 8086 v1 kernel ('rtty')
   244                                  	;	has been modified fot that.
   245                                  	;       Erdogan Tan (16/07/2015)
   246                                  	;
   247                                  
   248 000000CC 21C0                    	and	eax, eax ; EAX = 1 for tty (keyboard)
   249                                  	;jz	short cat_6
   250 000000CE 7419                    	jz	short cat_k ; 05/03/2022
   251                                  
   252                                  ;	push	esi
   253                                  	;mov	esi, ibuf
   254                                  ;	mov	esi, ecx ; offset ibuf
   255                                  ;	mov	ecx, eax
   256                                  		;;mov	fin,r0
   257                                  		;;sys	read; ibuf; 512.
   258                                  		;;bes	3f
   259                                  		;;mov	r0,r4
   260                                  		;;beq	3f
   261                                  		;;mov	$ibuf,r3
   262                                  	 ; 16/07/2015
   263                                  ;	mov	edx, eax
   264                                  ;	;add	edx, obuf
   265                                  ;cat_4:
   266                                  ;	;;4:
   267                                  ;	lodsb
   268                                  	;call	putc
   269                                  cat_w:
   270                                  	; 16/07/2015
   271                                  	; write to console tty (stdout)
   272                                  	sys 	_write, 1, iobuf, eax
    64                              <1> 
    65                              <1> 
    66                              <1> 
    67                              <1>  %if %0 >= 2
    68 000000D0 BB01000000          <1>  mov ebx, %2
    69                              <1>  %if %0 >= 3
    70 000000D5 B9[10010000]        <1>  mov ecx, %3
    71                              <1>  %if %0 = 4
    72 000000DA 89C2                <1>  mov edx, %4
    73                              <1>  %endif
    74                              <1>  %endif
    75                              <1>  %endif
    76 000000DC B804000000          <1>  mov eax, %1
    77 000000E1 CD30                <1>  int 30h
   273                                  	;jc	short cat_6
   274                                  	; 05/03/2022
   275 000000E3 7392                    	jnc	short cat_3
   276                                  	;
   277                                  ;	loop	cat_4
   278                                  ;	pop	esi
   279                                  cat_5:
   280                                  	;mov	eax, [esi] ; 05/03/2022
   281                                  	;;mov	ax, [esi]
   282                                  	;jmp	short cat_3
   283                                  		;;movb	(r3)+,r0
   284                                  		;;jsr	pc,putc
   285                                  		;;dec	r4
   286                                  		;;bne	4b
   287                                  		;;br	3b
   288                                  	;; 05/03/2022
   289                                  	;; ebx = file descriptor/input
   290                                  	;;and	ebx, ebx ; console input ?
   291                                  	;;jnz	short cat_3 ; no, file input
   292                                  	;;cmp	byte [quit], al ; 0
   293                                  	;;ja	short cat_7 ; ebx = 0
   294                                  	;;jmp	short cat_z
   295                                  	; 05/03/2022
   296                                  	;jmp	short cat_3
   297                                  		
   298                                  cat_6:	;;3:
   299                                  	; 05/03/2022
   300                                  	; ebx = file descriptor/number
   301                                  	;movzx	ebx, word [esi]
   302                                  	;
   303 000000E5 09F6                    	or	esi, esi
   304 000000E7 7409                    	jz	short cat_7
   305                                  cat_k:
   306                                  	sys	_close, esi
    64                              <1> 
    65                              <1> 
    66                              <1> 
    67                              <1>  %if %0 >= 2
    68 000000E9 89F3                <1>  mov ebx, %2
    69                              <1>  %if %0 >= 3
    70                              <1>  mov ecx, %3
    71                              <1>  %if %0 = 4
    72                              <1>  mov edx, %4
    73                              <1>  %endif
    74                              <1>  %endif
    75                              <1>  %endif
    76 000000EB B806000000          <1>  mov eax, %1
    77 000000F0 CD30                <1>  int 30h
   307                                  	;
   308                                  	;or	ebx, ebx
   309                                  	;jz	short cat_7
   310                                  	;sys 	_close
   311                                  		;;mov	fin,r0
   312                                  		;;beq	loop
   313                                  		;;sys	close
   314                                  		;;br	loop
   315                                  cat_7:	
   316                                  	;;loop:
   317 000000F2 4D                      	dec	ebp
   318                                  	;;jz	short cat_8
   319                                  	; 28/12/2015
   320                                  	;jg	short cat_0
   321                                  	; 05/03/2022
   322 000000F3 7E05                    	jng	short cat_exit
   323 000000F5 E923FFFFFF              	jmp	cat_0
   324                                  cat_exit:
   325                                  	sys	_exit
    64                              <1> 
    65                              <1> 
    66                              <1> 
    67                              <1>  %if %0 >= 2
    68                              <1>  mov ebx, %2
    69                              <1>  %if %0 >= 3
    70                              <1>  mov ecx, %3
    71                              <1>  %if %0 = 4
    72                              <1>  mov edx, %4
    73                              <1>  %endif
    74                              <1>  %endif
    75                              <1>  %endif
    76 000000FA B801000000          <1>  mov eax, %1
    77 000000FF CD30                <1>  int 30h
   326                                  here:
   327 00000101 90                      	nop
   328 00000102 EBFD                    	jmp short here
   329                                  	;;
   330                                  ;cat_8:
   331                                  ;	;;done:
   332                                  ;	sub	di, obuf
   333                                  ;	jz	short cat_9
   334                                  ;	sys	_write, 1, obuf, di 
   335                                  		;;sub	$obuf,r2
   336                                  		;;beq	1f
   337                                  		;;mov	r2,0f
   338                                  		;;mov	$1,r0
   339                                  		;;sys	write; obuf; 0:..
   340                                  ;cat_9:	
   341                                  ;	;;1:
   342                                  ;	sys	_exit
   343                                  		;;sys	exit
   344                                  	;;
   345                                  ;putc:	
   346                                  ;	;;putc:
   347                                  ;	stosb
   348                                  ;	cmp	di, dx ; 16/07/2015
   349                                  	;cmp	di, obuf + 512
   350                                  ;	jb	short cat_10
   351                                  ;	push	cx
   352                                  	 ; 16/07/2015
   353                                  ;	mov	di, obuf
   354                                  ;	sub	dx, di ; byte (char) count
   355                                  	; 
   356                                  ;	sys 	_write, 1, obuf
   357                                  	;sys 	_write, 1, obuf, 512
   358                                  	;mov	di, obuf
   359                                  		;;movb	r0,(r2)+
   360                                  		;;cmp	r2,$obuf+512.
   361                                  		;;blo	1f
   362                                  		;;mov	$1,r0
   363                                  		;;sys	write; obuf; 512.
   364                                  		;;mov	$obuf,r2
   365                                  ;	pop	cx
   366                                  ;cat_10:	
   367                                  	;;1:
   368                                  ;	retn
   369                                  		;;rts	pc
   370                                  
   371 00000104 0D0A                    nl:	db 0Dh, 0Ah ; , 0
   372                                  ; 05/03/2022
   373 00000106 00                      quit:	db 0
   374                                  consoletty:
   375 00000107 2F6465762F74747900      	db '/dev/tty', 0 ; (+)	
   376                                  
   377                                  align 4
   378                                  
   379                                  bss_start:
   380                                  
   381                                  ABSOLUTE bss_start
   382                                  
   383 00000110 <res 200h>              iobuf:  resb 512
   384                                  ;ibuf:	resb 512
   385                                  ;obuf:	resb 512
   386                                  ;;fin:	resw 1
   387                                  ;fin:	resd 1 ; 05/03/2022	
   388                                  		;;.bss
   389                                  		;;ibuf:	.=.+512.
   390                                  		;;obuf:	.=.+512.
   391                                  		;;fin:	.=.+2
   392                                  		;;.text
   393                                  ;bss_end:
