     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: 17/07/2022 ] -cat4.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 cat4.s -l cat4.txt -o cat4 -Z error.txt))
    19                                  ; cat386.s - cat4.s (17/06/2022, Retro UNIX 386 v1 & v1.1)
    20                                  ; cat386.s - cat3.s (15/06/2022, Retro UNIX 386 v1.2)
    21                                  ; cat386.s - cat2.s (14/06/2022, Retro UNIX 386 v1 & v1.1)
    22                                  ; cat386.s - cat1.s (05/03/2022, Retro UNIX 386 v1 & v1.1 & v1.2)
    23                                  ; cat386.s - cat0.s (17/10/2015 - 28/12/2015, Retro UNIX 386 v1, NASM 2.11)
    24                                  ; CAT2.ASM (02/12/2013 - 16/07/2015, Retro UNIX 8086 v1, MASM 6.11) 
    25                                  
    26                                  ; 17/10/2015
    27                                  
    28                                  ; UNIX v1 system calls
    29                                  _rele 	equ 0
    30                                  _exit 	equ 1
    31                                  _fork 	equ 2
    32                                  _read 	equ 3
    33                                  _write	equ 4
    34                                  _open	equ 5
    35                                  _close 	equ 6
    36                                  _wait 	equ 7
    37                                  _creat 	equ 8
    38                                  _link 	equ 9
    39                                  _unlink	equ 10
    40                                  _exec	equ 11
    41                                  _chdir	equ 12
    42                                  _time 	equ 13
    43                                  _mkdir 	equ 14
    44                                  _chmod	equ 15
    45                                  _chown	equ 16
    46                                  _break	equ 17
    47                                  _stat	equ 18
    48                                  _seek	equ 19
    49                                  _tell 	equ 20
    50                                  _mount	equ 21
    51                                  _umount	equ 22
    52                                  _setuid	equ 23
    53                                  _getuid	equ 24
    54                                  _stime	equ 25
    55                                  _quit	equ 26	
    56                                  _intr	equ 27
    57                                  _fstat	equ 28
    58                                  _emt 	equ 29
    59                                  _mdate 	equ 30
    60                                  _stty 	equ 31
    61                                  _gtty	equ 32
    62                                  _ilgins	equ 33
    63                                  _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
    64                                  _msg    equ 35 ; Retro UNIX 386 v1 feature only !
    65                                  _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
    66                                  ; 12/01/2022 - Retro UNIX 386 v1.2
    67                                  ; Retro UNIX 386 v2 system calls
    68                                  _setgid	equ 37
    69                                  _getgid	equ 38
    70                                  _sysver	equ 39 ; (get) Retro Unix 386 version
    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                                                 mov edx, %4   
    82                                              %endif
    83                                          %endif
    84                                      %endif
    85                                      mov eax, %1
    86                                      int 30h	   
    87                                  %endmacro
    88                                  
    89                                  ; 17/06/2022 - Retro UNIX 386 v1
    90                                  ;struc stat
    91                                  ;	; Retro UNIX v1 'sysstat' output !
    92                                  ;	; (34 bytes)
    93                                  ;	.inode:  resw 1	
    94                                  ;	.mode:	 resw 1
    95                                  ;	.nlinks: resb 1
    96                                  ;	.uid:	 resb 1
    97                                  ;	.size:	 resw 1
    98                                  ;	.dskptr: resw 8
    99                                  ;	.ctime:	 resd 1
   100                                  ;	.mtime:	 resd 1
   101                                  ;	.rsvd:   resw 1
   102                                  ;	.strucsize:
   103                                  ;endstruc 
   104                                  
   105                                  ENTERKEY  equ 0Dh
   106                                  NEXTLINE  equ 0Ah
   107                                  BACKSPACE equ 08h 
   108                                  
   109                                  ; Retro UNIX 386 v1 system call format:
   110                                  ; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
   111                                  
   112                                  [BITS 32] ; We need 32-bit intructions for protected mode
   113                                  
   114                                  [ORG 0] 
   115                                  
   116                                  START_CODE:
   117                                  	;; / cat -- concatenate files
   118                                  
   119                                  	;sys	_write, 1, nl, 2
   120                                  
   121                                  	; 18/06/2022
   122                                  	sys	_fstat, 1, iobuf 
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000000 BB01000000          <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000005 B9[AC030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 0000000A B81C000000          <1>  mov eax, %1
    86 0000000F CD30                <1>  int 30h
   123 00000011 E865000000              	call	rwcount
   124 00000016 8815[98030000]          	mov	[stdout], dl ; 19/06/2022
   125 0000001C 20D2                    	and 	dl, dl
   126 0000001E 7424                    	jz	short cat_@ ; block device or regular file
   127 00000020 803D[AC030000]09        	cmp	byte [iobuf], 9  ; /dev/lpr
   128 00000027 741B                    	je	short cat_@
   129                                  	; /dev/tty0 .. /dev/tty9
   130                                  	; next line
   131                                  	sys	_write, 1, nl, 2 
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000029 BB01000000          <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 0000002E B9[8A030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81 00000033 BA02000000          <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000038 B804000000          <1>  mov eax, %1
    86 0000003D CD30                <1>  int 30h
   132 0000003F B9[AC030000]            	mov	ecx, iobuf
   133                                  cat_@:
   134 00000044 5D                      	pop	ebp
   135 00000045 5A                      	pop	edx
   136                                  	; esi = 0 ; ('sysexec' sets regs to zero)
   137                                  	; 05/03/2022
   138                                  	;mov	esi, fin 
   139                                  	;mov    edi, obuf
   140                                  	;EAX = 2 (written byte count)
   141                                  	; 17/07/2022
   142                                  	;xor	al, al ; 0
   143                                          ; 18/06/2022  
   144                                  	;mov	ecx, iobuf ; 17/06/2022
   145 00000046 4D                      	dec     ebp
   146                                  	;jz	short cat_3	
   147                                  		;;mov	(sp)+,r5
   148                                  		;;tst	(sp)+
   149                                  		;;mov	$obuf,r2
   150                                  		;;cmp	r5,$1
   151                                  		;;beq	3f
   152                                  	; 18/06/ 2022
   153                                  	;jnz	short cat_0
   154                                  ;cat_y:
   155                                  	;jmp	cat_3
   156                                  	; 19/06/2022
   157 00000047 7475                    	jz	short cat_10
   158                                  cat_0:	
   159 00000049 5B                      	pop	ebx
   160 0000004A 803B2D                  	cmp	byte [ebx], '-'
   161                                  	;je	short cat_3 ; 16/06/2022
   162                                  		;;dec	r5
   163                                  		;;ble	done
   164                                  		;;mov	(sp)+,r0
   165                                  		;;cmpb	(r0),$'-
   166                                  		;;bne	2f
   167                                  		;;clr	fin
   168                                  		;;br	3f
   169                                  	; 18/06/2022
   170                                  	;je	short cat_y
   171 0000004D 7505                    	jne	short cat_1
   172 0000004F E986000000              	jmp	cat_3
   173                                  cat_1:
   174                                  	;;2:
   175                                  	; ebx = file name offset
   176 00000054 31C9                    	xor 	ecx, ecx ; 0
   177                                  	sys 	_open
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77                              <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79                              <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000056 B805000000          <1>  mov eax, %1
    86 0000005B CD30                <1>  int 30h
   178                                  	;jc	short cat_7
   179                                  	; 05/03/2022 ; (+)
   180 0000005D 7305                    	jnc	short cat_2
   181 0000005F E9A3010000              	jmp	cat_7
   182                                  cat_2:
   183                                  	; 05/03/2022
   184 00000064 89C6                    	mov	esi, eax
   185                                  	;mov	[esi], eax ; 05/03/2022
   186                                  	;mov	[esi], ax
   187                                  		;;mov	r0,0f
   188                                  		;;sys	open; 0:..; 0
   189                                  		;;bes	loop
   190                                  		;;mov	r0,fin
   191                                  
   192                                  	; 05/03/2022 ; (+)
   193                                  	; convert user's file number to inode number
   194                                  	; (get 34 byte inode details, inode num + inode)
   195                                  	; (get 66 byte inode details for runix 386 v1.2)
   196                                  	sys	_fstat, esi, iobuf 
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000066 89F3                <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000068 B9[AC030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 0000006D B81C000000          <1>  mov eax, %1
    86 00000072 CD30                <1>  int 30h
   197                                  	;jc	short cat_7
   198                                  	; 05/03/2022 ; (+)
   199 00000074 7321                    	jnc	short cat_f
   200 00000076 E983010000              	jmp	cat_k ; 15/06/2022
   201                                  
   202                                  rwcount:
   203                                  	; 17/06/2022 - Retro UNIX 386 v1 (& v1.1)
   204 0000007B 31D2                    	xor	edx, edx
   205 0000007D 66A1[AC030000]          	mov	ax, [iobuf] ; inode number
   206 00000083 6683F829                	cmp	ax, 41 ; regular file (or directory) ?
   207 00000087 730B                    	jnb	short rwc_2 ; yes
   208                                  
   209 00000089 3C08                    	cmp	al, 8 ; > hd3 inode number ?
   210 0000008B 7704                    	ja	short rwc_1 ; yes ; character device
   211                                  
   212 0000008D 3C03                    	cmp	al, 3 ; >= fd0 inode number ?
   213 0000008F 7303                    	jnb	short rwc_2 ; yes ; block device
   214                                  rwc_1:
   215                                  	; no, character device
   216                                  	; read/write count = 1
   217 00000091 FEC2                    	inc	dl
   218 00000093 C3                      	retn
   219                                  rwc_2:
   220                                  	; regular file or block device
   221                                  	; read/write count = 512
   222 00000094 B602                    	mov	dh, 2 ; edx = 512
   223 00000096 C3                      	retn
   224                                  	
   225                                  cat_f:
   226                                  	; 15/06/2022
   227 00000097 E8DFFFFFFF              	call	rwcount
   228 0000009C 8915[A8030000]          	mov	[filerwc], edx
   229                                  
   230                                  	; 18/06/2022
   231                                  	; (check if input file is a tty)
   232 000000A2 C605[99030000]00        	mov	byte [chrin], 0
   233 000000A9 20D2                    	and	dl, dl
   234 000000AB 742D                    	jz	short cat_3  ; not a character device
   235                                  	;mov	ax, [iobuf]
   236 000000AD A0[AC030000]            	mov	al, [iobuf] ; inode number
   237 000000B2 3C13                    	cmp	al, 19 ; tty9
   238 000000B4 7724                    	ja	short cat_3
   239 000000B6 3C0A                    	cmp	al, 10 ; tty0
   240 000000B8 7319                    	jnb	short cat_g
   241                                  
   242                                  	; [chrin] = 0
   243 000000BA 3C01                    	cmp	al, 1  ; /dev/tty
   244 000000BC 751C                    	jne	short cat_3
   245                                  cat_10:
   246                                  	sys	_gtty, 0, 1  ; get status of console tty (w)
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000000BE BB00000000          <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 000000C3 B901000000          <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 000000C8 B820000000          <1>  mov eax, %1
    86 000000CD CD30                <1>  int 30h
   247 000000CF FEC0                    	inc	al  ; console tty number + 1
   248 000000D1 EB02                    	jmp	short cat_h
   249                                  cat_g:
   250 000000D3 2C09                    	sub 	al, 9
   251                                  cat_h:
   252 000000D5 A2[99030000]            	mov	[chrin], al
   253                                  	; [chrin] = tty number + 1
   254                                  
   255                                  cat_3:	
   256                                  	; 05/03/2022 ; (+)
   257                                  	; get inode number of current tty (stdin)
   258                                  	; (get 34 byte inode details, inode num + inode)
   259                                  	; (get 66 byte inode details for runix 386 v1.2)
   260                                  	;sys	_fstat, 0, iobuf 
   261                                  	;;jc	short cat_n
   262                                  	;mov	ecx, iobuf	
   263                                  	sys	_fstat, 0  ; get stdin file inode details
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000000DA BB00000000          <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79                              <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 000000DF B81C000000          <1>  mov eax, %1
    86 000000E4 CD30                <1>  int 30h
   264                                  
   265                                  	; 15/06/2022
   266 000000E6 E890FFFFFF              	call	rwcount
   267 000000EB 8915[A4030000]          	mov	[stdinrw], edx
   268                                  
   269                                  cat_n:	;;3:
   270                                  	; get keyboard status of console tty
   271 000000F1 31DB                    	xor	ebx, ebx  ; 0
   272 000000F3 31C9                    	xor	ecx, ecx ; 0
   273                                  	sys	_gtty
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77                              <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79                              <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 000000F5 B820000000          <1>  mov eax, %1
    86 000000FA CD30                <1>  int 30h
   274                                  	; 19/06/2022
   275 000000FC A2[9B030000]            	mov	[consol], al
   276                                  	; 18/06/2022
   277 00000101 FEC0                    	inc	al ; tty number + 1
   278 00000103 3A05[99030000]          	cmp	al, [chrin]
   279 00000109 750E                    	jne	short cat_b
   280                                  	; input (source) file and stdin (console tty) is same
   281                                  	;sub	esi, esi ; 0
   282                                  ;cat_l:
   283                                  	; 19/06/2022
   284 0000010B F605[98030000]01        	test	byte [stdout], 1
   285 00000112 7505                    	jnz	short cat_b ; stdout is not a file		
   286                                  
   287                                  	;call	writeline
   288                                  	;cmp	al, 1Bh ; ESCape
   289                                  	;jne	short cat_l
   290                                  	;jmp	cat_exit
   291                                  	; 19/06/2022
   292 00000114 E944010000              	jmp	writeline 
   293                                  		; write tty/user input line(s) to file
   294                                  cat_b:	
   295                                  	; 15/06/2022
   296 00000119 21DB                    	and	ebx, ebx ; is there a waiting char ?
   297 0000011B 7524                    	jnz	short cat_x ; yes
   298                                  
   299 0000011D 08F6                    	or	dh, dh  ; is stdin a character device (tty) ?
   300 0000011F 752A                    	jnz	short cat_p
   301                                  			; no, stdin is a file or block device
   302                                  
   303                                  	; is there a file to read ?
   304 00000121 09F6                    	or	esi, esi ; 05/03/2022
   305 00000123 7556                    	jnz	short cat_r ; yes
   306                                  
   307                                  	; edx = [stdinrw]
   308 00000125 B9[AC030000]            	mov	ecx, iobuf
   309                                  	; ebx = 0
   310                                  	sys	_read	; 18/06/2022
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77                              <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79                              <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 0000012A B803000000          <1>  mov eax, %1
    86 0000012F CD30                <1>  int 30h
   311                                  	;sys	_read, 0, iobuf
   312                                  		; read one char into [iobuf]
   313                                  	;jc	short cat_6 ; (ebx = 0)
   314                                  	; 18/06/2022
   315 00000131 722B                    	jc	short cat_d
   316                                  
   317 00000133 803D[AC030000]1B        	cmp	byte [iobuf], 1Bh ; 27 ; ESCape key ?
   318 0000013A 7579                    	jne	short cat_c 
   319                                  
   320 0000013C E9F6000000              	jmp	cat_exit ; yes, exit
   321                                  
   322                                  cat_x:
   323 00000141 80FB1B                  	cmp	bl, 1Bh ; 27 ; ESCape key ?
   324                                  	;je	short cat_exit ; yes, exit
   325                                  	; 18/06/2022
   326 00000144 7505                    	jne	short cat_p
   327 00000146 E9C4000000              	jmp	cat_q
   328                                  cat_p:
   329                                  	; edx = [stdinrw]
   330                                  	sys	_read, 0, iobuf
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 0000014B BB00000000          <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000150 B9[AC030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000155 B803000000          <1>  mov eax, %1
    86 0000015A CD30                <1>  int 30h
   331                                  		; read one char into [iobuf]
   332                                  	;jc	short cat_6 ; (ebx = 0)
   333                                  	; 18/06/2022
   334 0000015C 7305                    	jnc	short cat_s
   335                                  cat_d:
   336 0000015E E997000000              	jmp	cat_6
   337                                  cat_s:	
   338                                  	; eax = read count
   339                                  	; read (redirected) stdin at first then other files 
   340 00000163 09C0                    	or	eax, eax
   341                                  	;jnz	short cat_w ; write bytes in buffer
   342                                  	; 18/06/2022
   343 00000165 7406                    	jz	short cat_u
   344 00000167 20F6                    	and	dh, dh
   345 00000169 744A                    	jz	short cat_c ; console tty (crlf check)
   346 0000016B EB78                    	jmp	short cat_w
   347                                  cat_u:
   348                                  	; 16/06/2022
   349                                  	; trick to skip reading stdin file
   350                                  	;xor	edx, edx
   351                                  	; edx = 0
   352                                  	;mov	[stdinrw], edx  ; end of stdin file
   353                                  	; 18/06/2022
   354 0000016D A3[A4030000]            	mov	[stdinrw], eax  ; 0 ; end of stdin file
   355                                  	;jmp	short cat_c ; read (input) file
   356                                  
   357                                  	; is there a file to read ?
   358 00000172 21F6                    	and	esi, esi
   359                                  	;jz	short cat_7 ; no
   360                                  	; 18/06/2022
   361 00000174 7505                    	jnz	short cat_r
   362 00000176 E98C000000              	jmp	cat_7 
   363                                  
   364                                  cat_r:
   365                                  	; 18/06/2022
   366 0000017B 8A2D[99030000]          	mov	ch, [chrin]
   367 00000181 20ED                    	and	ch, ch
   368 00000183 7446                    	jz	short cat_m ; not a tty file
   369 00000185 30C9                    	xor	cl, cl ; 0
   370 00000187 29DB                    	sub	ebx, ebx ; 0	
   371                                  	sys	_gtty	; get keyboard status of tty
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77                              <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79                              <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000189 B820000000          <1>  mov eax, %1
    86 0000018E CD30                <1>  int 30h
   372 00000190 09DB                    	or	ebx, ebx
   373                                  	;jz	short cat_n ; check for console keystroke
   374                                  	; 18/06/2022
   375 00000192 7505                    	jnz	short cat_e
   376 00000194 E958FFFFFF              	jmp	cat_n	
   377                                  
   378                                  cat_e:
   379                                  	sys	_read, esi, iobuf, 1
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000199 89F3                <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 0000019B B9[AC030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81 000001A0 BA01000000          <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 000001A5 B803000000          <1>  mov eax, %1
    86 000001AA CD30                <1>  int 30h
   380 000001AC 803D[AC030000]1B        	cmp	byte [iobuf], 1Bh ; 27 ; ESCape key ?
   381 000001B3 7449                    	je	short cat_k ; close file
   382                                  
   383                                  cat_c:
   384                                  	; is there a file to read ?
   385                                  	;or	esi, esi ; 05/03/2022
   386                                  	;jnz	short cat_r ; yes
   387                                  
   388                                  	; 16/06/2022
   389                                  	;and	edx, edx
   390                                  	;jz	short cat_exit ; end of stdin file
   391                                  
   392                                  	;xor	eax, eax
   393                                  	;inc	al
   394 000001B5 B001                    	mov	al, 1
   395                                  	; eax = 1	
   396 000001B7 803D[AC030000]0D        	cmp	byte [iobuf], 0Dh ; carriage return ?
   397 000001BE 7525                    	jne	short cat_w
   398 000001C0 C605[AD030000]0A        	mov	byte [iobuf+1], 0Ah ; line feed
   399 000001C7 FEC0                    	inc	al
   400                                  	; eax = 2
   401 000001C9 EB1A                    	jmp	short cat_w
   402                                  
   403                                  cat_m:
   404                                  	; 05/03/2022
   405                                  	;mov	eax, [esi] ; file descriptor/number
   406                                  	;;mov	ax, [esi]
   407                                  	;
   408                                  	;sys	_read, eax, iobuf, 512 ; 16/07/2015
   409                                  	;;sys 	_read, eax, ibuf, 512 
   410                                  	;jc	short cat_6
   411                                  	; 15/06/2022
   412                                  	; 05/03/2022
   413                                  	; esi = file descriptor/number
   414                                  	sys	_read, esi, iobuf, [filerwc]
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000001CB 89F3                <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 000001CD B9[AC030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81 000001D2 8B15[A8030000]      <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 000001D8 B803000000          <1>  mov eax, %1
    86 000001DD CD30                <1>  int 30h
   415                                  		; read 512 chars into [iobuf]
   416                                  	;jc	short cat_6
   417 000001DF 721D                    	jc	short cat_k ; 05/03/2022
   418                                  
   419                                  	; NOTE: If input file is a tty (keyboard)
   420                                  	;	only 1 byte will be read, by ignoring
   421                                  	;	byte count (512).
   422                                  	;	Retro UNIX 8086 v1 kernel ('rtty')
   423                                  	;	has been modified fot that.
   424                                  	;       Erdogan Tan (16/07/2015)
   425                                  	;
   426                                  
   427                                  	; 15/06/2022
   428 000001E1 21C0                    	and	eax, eax ; EAX = 1 for tty (keyboard)
   429                                  	;jz	short cat_6
   430 000001E3 7419                    	jz	short cat_k ; 05/03/2022
   431                                  
   432                                  ;	push	esi
   433                                  	;mov	esi, ibuf
   434                                  ;	mov	esi, ecx ; offset ibuf
   435                                  ;	mov	ecx, eax
   436                                  		;;mov	fin,r0
   437                                  		;;sys	read; ibuf; 512.
   438                                  		;;bes	3f
   439                                  		;;mov	r0,r4
   440                                  		;;beq	3f
   441                                  		;;mov	$ibuf,r3
   442                                  	 ; 16/07/2015
   443                                  ;	mov	edx, eax
   444                                  ;	;add	edx, obuf
   445                                  ;cat_4:
   446                                  ;	;;4:
   447                                  ;	lodsb
   448                                  	;call	putc
   449                                  cat_w:
   450                                  	; 16/07/2015
   451                                  	; write to console tty (stdout)
   452                                  	sys 	_write, 1, iobuf, eax
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000001E5 BB01000000          <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 000001EA B9[AC030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81 000001EF 89C2                <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 000001F1 B804000000          <1>  mov eax, %1
    86 000001F6 CD30                <1>  int 30h
   453                                  	;jc	short cat_6
   454                                  	; 05/03/2022
   455                                  	;jnc	short cat_3
   456                                  	; 15/06/2022
   457 000001F8 7347                    	jnc	short cat_8
   458                                  
   459                                  ;	loop	cat_4
   460                                  ;	pop	esi
   461                                  cat_5:
   462                                  	;mov	eax, [esi] ; 05/03/2022
   463                                  	;;mov	ax, [esi]
   464                                  	;jmp	short cat_3
   465                                  		;;movb	(r3)+,r0
   466                                  		;;jsr	pc,putc
   467                                  		;;dec	r4
   468                                  		;;bne	4b
   469                                  		;;br	3b
   470                                  	;; 05/03/2022
   471                                  	;; ebx = file descriptor/input
   472                                  	;;and	ebx, ebx ; console input ?
   473                                  	;;jnz	short cat_3 ; no, file input
   474                                  	;;cmp	byte [quit], al ; 0
   475                                  	;;ja	short cat_7 ; ebx = 0
   476                                  	;;jmp	short cat_z
   477                                  	; 05/03/2022
   478                                  	;jmp	short cat_3
   479                                  		
   480                                  cat_6:	;;3:
   481                                  	; 05/03/2022
   482                                  	; ebx = file descriptor/number
   483                                  	;movzx	ebx, word [esi]
   484                                  	;
   485 000001FA 09F6                    	or	esi, esi
   486 000001FC 7409                    	jz	short cat_7
   487                                  cat_k:
   488                                  	sys	_close, esi
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000001FE 89F3                <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79                              <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000200 B806000000          <1>  mov eax, %1
    86 00000205 CD30                <1>  int 30h
   489                                  	;
   490                                  	;or	ebx, ebx
   491                                  	;jz	short cat_7
   492                                  	;sys 	_close
   493                                  		;;mov	fin,r0
   494                                  		;;beq	loop
   495                                  		;;sys	close
   496                                  		;;br	loop
   497                                  cat_7:	
   498                                  	;;loop:
   499 00000207 4D                      	dec	ebp
   500                                  	;;jz	short cat_8
   501                                  	; 28/12/2015
   502                                  	;jg	short cat_0
   503                                  	; 05/03/2022
   504 00000208 7E2D                    	jng	short cat_exit
   505 0000020A E93AFEFFFF              	jmp	cat_0
   506                                  
   507                                  	; 18/06/2022 (ESCape)
   508                                  cat_q:
   509                                  	; open console tty for read
   510                                  	sys	_open, consoletty, 0
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 0000020F BB[8D030000]        <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000214 B900000000          <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000219 B805000000          <1>  mov eax, %1
    86 0000021E CD30                <1>  int 30h
   511 00000220 7215                    	jc	short cat_exit
   512                                  	sys	_read, eax, iobuf
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000222 89C3                <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000224 B9[AC030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000229 B803000000          <1>  mov eax, %1
    86 0000022E CD30                <1>  int 30h
   513                                  	sys	_close
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77                              <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79                              <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000230 B806000000          <1>  mov eax, %1
    86 00000235 CD30                <1>  int 30h
   514                                  
   515                                  	;jmp	short cat_exit	
   516                                  
   517                                  cat_exit:
   518                                  	sys	_exit
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77                              <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79                              <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000237 B801000000          <1>  mov eax, %1
    86 0000023C CD30                <1>  int 30h
   519                                  here:
   520 0000023E 90                      	nop
   521 0000023F EBFD                    	jmp	short here
   522                                  
   523                                  cat_8:
   524                                  	; 15/06/2022
   525 00000241 39D0                    	cmp	eax, edx
   526 00000243 72B5                    	jb	short cat_6
   527 00000245 8B15[A4030000]          	mov	edx, [stdinrw]
   528 0000024B 09D2                    	or 	edx, edx  ; end of stdin file
   529 0000024D 7405                    	jz	short cat_9
   530 0000024F E99DFEFFFF              	jmp	cat_n
   531                                  
   532                                  cat_9:
   533                                  	; 16/06/2022
   534 00000254 21F6                    	and	esi, esi
   535 00000256 74A6                    	jz	short cat_k
   536 00000258 E91EFFFFFF              	jmp	cat_r ; 18/06/2022
   537                                  
   538                                  ;cat_8:
   539                                  ;	;;done:
   540                                  ;	sub	di, obuf
   541                                  ;	jz	short cat_9
   542                                  ;	sys	_write, 1, obuf, di 
   543                                  		;;sub	$obuf,r2
   544                                  		;;beq	1f
   545                                  		;;mov	r2,0f
   546                                  		;;mov	$1,r0
   547                                  		;;sys	write; obuf; 0:..
   548                                  ;cat_9:	
   549                                  ;	;;1:
   550                                  ;	sys	_exit
   551                                  		;;sys	exit
   552                                  	;;
   553                                  ;putc:	
   554                                  ;	;;putc:
   555                                  ;	stosb
   556                                  ;	cmp	di, dx ; 16/07/2015
   557                                  	;cmp	di, obuf + 512
   558                                  ;	jb	short cat_10
   559                                  ;	push	cx
   560                                  	 ; 16/07/2015
   561                                  ;	mov	di, obuf
   562                                  ;	sub	dx, di ; byte (char) count
   563                                  	; 
   564                                  ;	sys 	_write, 1, obuf
   565                                  	;sys 	_write, 1, obuf, 512
   566                                  	;mov	di, obuf
   567                                  		;;movb	r0,(r2)+
   568                                  		;;cmp	r2,$obuf+512.
   569                                  		;;blo	1f
   570                                  		;;mov	$1,r0
   571                                  		;;sys	write; obuf; 512.
   572                                  		;;mov	$obuf,r2
   573                                  ;	pop	cx
   574                                  ;cat_10:	
   575                                  	;;1:
   576                                  ;	retn
   577                                  		;;rts	pc
   578                                  
   579                                  writeline:
   580                                  	; 19/06/2022
   581                                  
   582                                  	; write line(s) to file (with echo)
   583                                  	; stdin = console tty
   584                                  	; stdout = file or another tty
   585                                  
   586                                  	;mov	edi, linebuf
   587                                   
   588                                  	;sys	_gtty, 0, 1  ; get status of console tty (w)	
   589                                  	;jc	short done3
   590                                  	
   591 0000025D A0[9B030000]            	mov	al, [consol]
   592                                  	; al = console tty number
   593 00000262 0430                    	add	al, '0'
   594 00000264 A2[95030000]            	mov	[consoletty+8], al
   595                                  
   596 00000269 C605[9A030000]1B        	mov	byte [chr], 1Bh ; ESCape
   597                                  
   598                                  	sys	_open, consoletty, 0 ; open for read
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000270 BB[8D030000]        <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000275 B900000000          <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 0000027A B805000000          <1>  mov eax, %1
    86 0000027F CD30                <1>  int 30h
   599                                  	;jc	short done3
   600 00000281 7305                    	jnc	short G0
   601 00000283 E995000000              	jmp	done3 
   602                                  G0:
   603 00000288 A3[9C030000]            	mov	[consol_r], eax
   604                                  	sys	_open, consoletty, 1 ; open for write
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 0000028D BB[8D030000]        <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000292 B901000000          <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000297 B805000000          <1>  mov eax, %1
    86 0000029C CD30                <1>  int 30h
   605 0000029E 7270                    	jc	short done2
   606 000002A0 A3[A0030000]            	mov	[consol_w], eax
   607                                  	sys	_write, [consol_w], crlf, 2
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000002A5 8B1D[A0030000]      <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 000002AB B9[8A030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81 000002B0 BA02000000          <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 000002B5 B804000000          <1>  mov eax, %1
    86 000002BA CD30                <1>  int 30h
   608                                  do:
   609 000002BC BF[AC030000]                    mov	edi, linebuf
   610                                  getc:
   611                                  	sys	_read, [consol_r], chr, 1
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000002C1 8B1D[9C030000]      <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 000002C7 B9[9A030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81 000002CC BA01000000          <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 000002D1 B803000000          <1>  mov eax, %1
    86 000002D6 CD30                <1>  int 30h
   612 000002D8 7229                    	jc	short done1
   613                                  	;and	eax, eax
   614                                  	;jz	short done1
   615                                  	;
   616 000002DA A0[9A030000]            	mov	al, [chr]
   617                                  
   618 000002DF 3C1B                    	cmp	al, 1Bh ; ESCape key
   619 000002E1 7420                    	je	short done1
   620                                  
   621 000002E3 3C20                    	cmp	al, 20h
   622 000002E5 7256                    	jb	short G1
   623                                  
   624 000002E7 3C7F                    	cmp	al, 127
   625 000002E9 745F                    	je	short G2
   626                                  
   627 000002EB 81FF[FC030000]                  cmp	edi, linebuf+80
   628 000002F1 73CE                    	jnb	short getc
   629                                  putc:
   630 000002F3 AA                      	stosb
   631                                  echo:
   632                                  	;sys	_write, [consol_w], chr, 1
   633                                  	; ecx = chr
   634                                  	; edx = 1
   635                                  	sys	_write, [consol_w]
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000002F4 8B1D[A0030000]      <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79                              <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 000002FA B804000000          <1>  mov eax, %1
    86 000002FF CD30                <1>  int 30h
   636 00000301 EBBE                    	jmp	short getc
   637                                  
   638                                  done1:
   639                                  	sys	_close, [consol_w]
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000303 8B1D[A0030000]      <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79                              <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000309 B806000000          <1>  mov eax, %1
    86 0000030E CD30                <1>  int 30h
   640                                  done2:
   641                                  	sys	_close, [consol_r]
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000310 8B1D[9C030000]      <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79                              <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000316 B806000000          <1>  mov eax, %1
    86 0000031B CD30                <1>  int 30h
   642                                  done3:
   643                                  	;mov	byte [edi], 0
   644                                  	;mov	al, [chr]
   645                                  	;retn
   646                                  
   647 0000031D 89FA                    	mov	edx, edi
   648 0000031F 81EA[AC030000]          	sub	edx, linebuf	
   649 00000325 7411                    	jz	short done4
   650                                  
   651                                  	sys	_write, 1, linebuf
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000327 BB01000000          <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 0000032C B9[AC030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000331 B804000000          <1>  mov eax, %1
    86 00000336 CD30                <1>  int 30h
   652                                  done4:
   653                                  	;sys	_exit
   654 00000338 E9FAFEFFFF              	jmp	cat_exit
   655                                  
   656                                  G1:
   657 0000033D 3C0D                    	cmp	al, ENTERKEY  ; \r (carriage return)
   658 0000033F 7414                            je	short G3
   659                                  
   660                                  	;cmp	al, NEXTLINE  ; \n (next line)
   661                                          ;je	short G3
   662                                  
   663 00000341 3C08                    	cmp	al, BACKSPACE ; \b (back space)
   664 00000343 7405                    	je	short G2
   665                                  getch:
   666 00000345 E977FFFFFF              	jmp	getc
   667                                  G2:
   668                                  	; Backspace
   669 0000034A 81FF[AC030000]          	cmp	edi, linebuf
   670 00000350 76F3                    	jna	short getch
   671 00000352 4F                      	dec	edi
   672 00000353 EB9F                    	jmp	short echo
   673                                  
   674                                  G3:
   675                                  	;mov	al, ENTERKEY ; carriage return
   676 00000355 AA                      	stosb
   677 00000356 B00A                    	mov	al, NEXTLINE ; line feed
   678 00000358 AA                      	stosb
   679                                  	sys	_write, [consol_w], crlf, 2
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000359 8B1D[A0030000]      <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 0000035F B9[8A030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81 00000364 BA02000000          <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000369 B804000000          <1>  mov eax, %1
    86 0000036E CD30                <1>  int 30h
   680 00000370 B9[AC030000]            	mov	ecx, linebuf 
   681 00000375 89FA                    	mov	edx, edi
   682 00000377 29CA                    	sub	edx, ecx ; sub edx, linebuf
   683                                  	; ecx = offset crlf
   684                                  	sys	_write, 1
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000379 BB01000000          <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79                              <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 0000037E B804000000          <1>  mov eax, %1
    86 00000383 CD30                <1>  int 30h
   685 00000385 E932FFFFFF              	jmp	do ; next line
   686                                  
   687                                  ; ;;;;
   688                                  
   689                                  crlf:	; 19/06/2022
   690 0000038A 0D0A00                  nl:	db 0Dh, 0Ah, 0
   691                                  
   692                                  ;; 05/03/2022
   693                                  ;quit:	db 0
   694                                  ; 18/06/2022
   695                                  consoletty:
   696 0000038D 2F6465762F74747900-     	db '/dev/tty', 0, 0 ; ; 19/06/2022
   696 00000396 00                 
   697                                  
   698 00000397 90                      align 4
   699                                  
   700                                  bss_start:
   701                                  
   702                                  ABSOLUTE bss_start
   703                                  
   704                                  ; 19/06/2022
   705 00000398 ??                      stdout:	resb 1
   706                                  ; 18/06/2022
   707 00000399 ??                      chrin:	resb 1
   708                                  ; 19/06/2022
   709 0000039A ??                      chr:	resb 1
   710 0000039B ??                      consol:	resb 1
   711 0000039C ????????                consol_r: resd 1
   712 000003A0 ????????                consol_w: resd 1
   713                                  
   714                                  ; 15/06/2022
   715 000003A4 ????????                stdinrw: resd 1
   716 000003A8 ????????                filerwc: resd 1
   717                                  
   718                                  linebuf: ; 19/06/2022	
   719 000003AC <res 200h>              iobuf:  resb 512
   720                                  ;ibuf:	resb 512
   721                                  ;obuf:	resb 512
   722                                  ;;fin:	resw 1
   723                                  ;fin:	resd 1 ; 05/03/2022	
   724                                  		;;.bss
   725                                  		;;ibuf:	.=.+512.
   726                                  		;;obuf:	.=.+512.
   727                                  		;;fin:	.=.+2
   728                                  		;;.text
   729                                  ;bss_end:
