     1                                  ; ****************************************************************************
     2                                  ; cat386.s (Retro Unix 386 v1.2) - /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: 19/06/2022 ] -cat3.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 cat3.s -l cat3.txt -o cat3 -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                                  ; 15/06/2022 - Retro UNIX 386 v1.2
    90                                  struc stat
    91                                     ; Retro UNIX v1.2 'sysstat' output !
    92                                     ; (66 bytes)
    93 00000000 ????                       .inode:  resw 1	
    94 00000002 ????                       .mode:   resw 1
    95 00000004 ????                       .nlinks: resw 1 
    96 00000006 ????                       .uid:    resw 1
    97 00000008 ??                         .gid:    resb 1
    98 00000009 ??                         .size_h: resb 1
    99 0000000A ????????                   .size:   resd 1
   100 0000000E <res 28h>                  .dskptr: resd 10
   101 00000036 ????????                   .atime:  resd 1
   102 0000003A ????????                   .mtime:  resd 1
   103 0000003E ????????                   .ctime:  resd 1
   104                                     .strucsize:
   105                                  endstruc
   106                                  
   107                                  ENTERKEY  equ 0Dh
   108                                  NEXTLINE  equ 0Ah
   109                                  BACKSPACE equ 08h
   110                                  
   111                                  ; Retro UNIX 386 v1 system call format:
   112                                  ; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
   113                                  
   114                                  [BITS 32] ; We need 32-bit intructions for protected mode
   115                                  
   116                                  [ORG 0] 
   117                                  
   118                                  START_CODE:
   119                                  	;; / cat -- concatenate files
   120                                  
   121                                  	;sys	_write, 1, nl, 2
   122                                  	
   123                                  	; 18/06/2022
   124                                  	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[A0030000]        <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
   125 00000011 E862000000              	call	rwcount
   126 00000016 8815[8C030000]          	mov	[stdout], dl ; 19/06/2022
   127 0000001C 20D2                    	and 	dl, dl
   128 0000001E 7424                    	jz	short cat_@ ; block device or regular file
   129 00000020 803D[A0030000]10        	cmp	byte [iobuf], 16  ; /dev/lpr
   130 00000027 741B                    	je	short cat_@
   131                                  	; /dev/tty0 .. /dev/tty9
   132                                  	; next line
   133                                  	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[7E030000]        <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
   134 0000003F B9[A0030000]            	mov	ecx, iobuf
   135                                  cat_@:
   136 00000044 5D                      	pop	ebp
   137 00000045 5A                      	pop	edx
   138                                  	; esi = 0 ; ('sysexec' sets regs to zero)
   139                                  	; 05/03/2022
   140                                  	;mov	esi, fin 
   141                                  	;mov    edi, obuf
   142                                  	;EAX = 2 (written byte count)
   143 00000046 30C0                    	xor	al, al ; 0
   144                                          ; 18/06/2022  
   145                                  	;mov	ecx, iobuf ; 17/06/2022
   146 00000048 4D                      	dec     ebp
   147                                  	;jz	short cat_3	
   148                                  		;;mov	(sp)+,r5
   149                                  		;;tst	(sp)+
   150                                  		;;mov	$obuf,r2
   151                                  		;;cmp	r5,$1
   152                                  		;;beq	3f
   153                                  	
   154                                  	; 18/06/2022
   155                                  	;jnz	short cat_0
   156                                  	;jmp	cat_3
   157                                  	; 19/06/2022
   158 00000049 7469                    	jz	short cat_10
   159                                  cat_0:	
   160 0000004B 5B                      	pop	ebx
   161 0000004C 803B2D                  	cmp	byte [ebx], '-'
   162 0000004F 747D                    	je	short cat_3 ; 16/06/2022
   163                                  		;;dec	r5
   164                                  		;;ble	done
   165                                  		;;mov	(sp)+,r0
   166                                  		;;cmpb	(r0),$'-
   167                                  		;;bne	2f
   168                                  		;;clr	fin
   169                                  		;;br	3f
   170                                  cat_1:
   171                                  	;;2:
   172                                  	; ebx = file name offset
   173 00000051 31C9                    	xor 	ecx, ecx ; 0
   174                                  	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 00000053 B805000000          <1>  mov eax, %1
    86 00000058 CD30                <1>  int 30h
   175                                  	;jc	short cat_7
   176                                  	; 05/03/2022 ; (+)
   177 0000005A 7305                    	jnc	short cat_2
   178 0000005C E99A010000              	jmp	cat_7
   179                                  cat_2:
   180                                  	; 05/03/2022
   181 00000061 89C6                    	mov	esi, eax
   182                                  	;mov	[esi], eax ; 05/03/2022
   183                                  	;mov	[esi], ax
   184                                  		;;mov	r0,0f
   185                                  		;;sys	open; 0:..; 0
   186                                  		;;bes	loop
   187                                  		;;mov	r0,fin
   188                                  
   189                                  	; 05/03/2022 ; (+)
   190                                  	; convert user's file number to inode number
   191                                  	; (get 34 byte inode details, inode num + inode)
   192                                  	; (get 66 byte inode details for runix 386 v1.2)
   193                                  	sys	_fstat, esi, iobuf 
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000063 89F3                <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000065 B9[A0030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 0000006A B81C000000          <1>  mov eax, %1
    86 0000006F CD30                <1>  int 30h
   194                                  	;jc	short cat_7
   195                                  	; 05/03/2022 ; (+)
   196 00000071 731A                    	jnc	short cat_f
   197 00000073 E97A010000              	jmp	cat_k ; 15/06/2022
   198                                  
   199                                  rwcount:
   200                                  	; 15/06/2022
   201 00000078 31D2                    	xor	edx, edx
   202 0000007A A0[A3030000]            	mov	al, [iobuf+stat.mode+1]
   203 0000007F A880                    	test	al, 80h
   204 00000081 7507                    	jnz	short rwc_1
   205 00000083 A840                    	test	al, 40h ; block device ?
   206 00000085 7503                    	jnz	short rwc_1 ; yes
   207                                  	; no, character device
   208                                  	; read/write count = 1
   209 00000087 FEC2                    	inc	dl
   210 00000089 C3                      	retn
   211                                  rwc_1:
   212                                  	; regular file or block device
   213                                  	; read/write count = 512
   214 0000008A B602                    	mov	dh, 2 ; edx = 512
   215 0000008C C3                      	retn
   216                                  	
   217                                  cat_f:
   218                                  	; 15/06/2022
   219 0000008D E8E6FFFFFF              	call	rwcount
   220 00000092 8915[9C030000]          	mov	[filerwc], edx
   221                                  
   222                                  	; 18/06/2022
   223                                  	; (check if input file is a tty)
   224 00000098 C605[8D030000]00        	mov	byte [chrin], 0
   225 0000009F 20D2                    	and	dl, dl
   226 000000A1 742B                    	jz	short cat_3 ; not a character device
   227                                  	;mov	ax, [iobuf]
   228 000000A3 A0[A0030000]            	mov	al, [iobuf] ; inode number
   229 000000A8 3C1A                    	cmp	al, 26 ; tty9
   230 000000AA 7722                    	ja	short cat_3
   231 000000AC 3C11                    	cmp	al, 17 ; tty0
   232 000000AE 7317                    	jnb	short cat_g
   233                                  
   234                                  	; [chrin] = 0
   235 000000B0 3C08                    	cmp	al, 8  ; /dev/tty
   236 000000B2 751A                    	jne	short cat_3
   237                                  cat_10:
   238                                  	sys	_gtty, 0, 1 ; get status of console tty (w)
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000000B4 BB00000000          <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 000000B9 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 000000BE B820000000          <1>  mov eax, %1
    86 000000C3 CD30                <1>  int 30h
   239 000000C5 FEC0                    	inc	al  ; console tty number + 1
   240                                  	;jmp	short cat_h
   241                                  cat_g:
   242                                  	;sub 	al, 16
   243 000000C7 240F                    	and	al, 0Fh ; 15
   244                                  ;cat_h:
   245 000000C9 A2[8D030000]            	mov	[chrin], al
   246                                  	; [chrin] = tty number + 1
   247                                  
   248                                  cat_3:	
   249                                  	; 05/03/2022 ; (+)
   250                                  	; get inode number of current tty (stdin)
   251                                  	; (get 34 byte inode details, inode num + inode)
   252                                  	; (get 66 byte inode details for runix 386 v1.2)
   253                                  	;sys	_fstat, 0, iobuf 
   254                                  	;;jc	short cat_n
   255                                  	;mov	ecx, iobuf	
   256                                  	sys	_fstat, 0  ; get stdin file inode details
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000000CE 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 000000D3 B81C000000          <1>  mov eax, %1
    86 000000D8 CD30                <1>  int 30h
   257                                  
   258                                  	; 15/06/2022
   259 000000DA E899FFFFFF              	call	rwcount
   260 000000DF 8915[98030000]          	mov	[stdinrw], edx
   261                                  
   262                                  cat_n:	;;3:
   263                                  	; get keyboard status of console tty
   264 000000E5 31DB                    	xor	ebx, ebx ; 0
   265 000000E7 31C9                    	xor	ecx, ecx ; 0
   266                                  	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 000000E9 B820000000          <1>  mov eax, %1
    86 000000EE CD30                <1>  int 30h
   267                                  	; 19/06/2022
   268 000000F0 A2[8F030000]            	mov	[consol], al
   269                                  	; 18/06/2022
   270 000000F5 FEC0                    	inc	al ; tty number + 1
   271 000000F7 3A05[8D030000]          	cmp	al, [chrin]
   272 000000FD 750E                    	jne	short cat_b
   273                                  	; input (source) file and stdin (console tty) is same
   274                                  	;sub	esi, esi ; 0
   275                                  ;cat_l:
   276                                  	; 19/06/2022
   277 000000FF F605[8C030000]01        	test	byte [stdout], 1
   278 00000106 7505                    	jnz	short cat_b ; stdout is not a file		
   279                                  
   280                                  	;call	writeline
   281                                  	;cmp	al, 1Bh ; ESCape
   282                                  	;jne	short cat_l
   283                                  	;jmp	cat_exit
   284                                  	; 19/06/2022
   285 00000108 E944010000              	jmp	writeline 
   286                                  		; write tty/user input line(s) to file
   287                                  cat_b:	
   288                                  	; 15/06/2022
   289 0000010D 21DB                    	and	ebx, ebx ; is there a waiting char ?
   290 0000010F 7524                    	jnz	short cat_x ; yes
   291                                  
   292 00000111 08F6                    	or	dh, dh  ; is stdin a character device (tty) ?
   293 00000113 752A                    	jnz	short cat_p
   294                                  			; no, stdin is a file or block device
   295                                  
   296                                  	; is there a file to read ?
   297 00000115 09F6                    	or	esi, esi ; 05/03/2022
   298 00000117 7556                    	jnz	short cat_r ; yes
   299                                  
   300                                  	; edx = [stdinrw]
   301 00000119 B9[A0030000]            	mov	ecx, iobuf
   302                                  	; ebx = 0
   303                                  	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 0000011E B803000000          <1>  mov eax, %1
    86 00000123 CD30                <1>  int 30h
   304                                  	;sys	_read, 0, iobuf
   305                                  		; read one char into [iobuf]
   306                                  	;jc	short cat_6 ; (ebx = 0)
   307                                  	; 18/06/2022
   308 00000125 722B                    	jc	short cat_d
   309                                  
   310 00000127 803D[A0030000]1B        	cmp	byte [iobuf], 1Bh ; 27 ; ESCape key ?
   311 0000012E 7579                    	jne	short cat_c 
   312 00000130 E9F6000000              	jmp	cat_exit ; yes, exit
   313                                  
   314                                  cat_x:
   315 00000135 80FB1B                  	cmp	bl, 1Bh ; 27 ; ESCape key ?
   316                                  	;je	short cat_exit ; yes, exit
   317                                  	; 18/06/2022
   318 00000138 7505                    	jne	short cat_p
   319 0000013A E9C4000000              	jmp	cat_q
   320                                  cat_p:
   321                                  	; edx = [stdinrw]
   322                                  	sys	_read, 0, iobuf
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 0000013F BB00000000          <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000144 B9[A0030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000149 B803000000          <1>  mov eax, %1
    86 0000014E CD30                <1>  int 30h
   323                                  		; read one char into [iobuf]
   324                                  	;jc	short cat_6 ; (ebx = 0)
   325                                  	; 18/06/2022
   326 00000150 7305                    	jnc	short cat_s
   327                                  cat_d:
   328 00000152 E997000000              	jmp	cat_6
   329                                  cat_s:	
   330                                  	; eax = read count
   331                                  	; read (redirected) stdin at first then other files 
   332 00000157 09C0                    	or	eax, eax
   333                                  	;jnz	short cat_w ; write bytes in buffer
   334                                  	; 18/06/2022
   335 00000159 7406                    	jz	short cat_u
   336 0000015B 20F6                    	and	dh, dh
   337 0000015D 744A                    	jz	short cat_c ; console tty (crlf check)
   338 0000015F EB78                    	jmp	short cat_w
   339                                  cat_u:
   340                                  	; 16/06/2022
   341                                  	; trick to skip reading stdin file
   342                                  	;xor	edx, edx
   343                                  	; edx = 0
   344                                  	;mov	[stdinrw], edx  ; end of stdin file
   345                                  	; 18/06/2022
   346 00000161 A3[98030000]            	mov	[stdinrw], eax  ; 0 ; end of stdin file
   347                                  	;jmp	short cat_c ; read (input) file
   348                                  
   349                                  	; is there a file to read ?
   350 00000166 21F6                    	and	esi, esi
   351                                  	;jz	short cat_7 ; no
   352                                  	; 18/06/2022
   353 00000168 7505                    	jnz	short cat_r
   354 0000016A E98C000000              	jmp	cat_7 
   355                                  
   356                                  cat_r:
   357                                  	; 18/06/2022
   358 0000016F 8A2D[8D030000]          	mov	ch, [chrin]
   359 00000175 20ED                    	and	ch, ch
   360 00000177 7446                    	jz	short cat_m ; not a tty file
   361 00000179 30C9                    	xor	cl, cl ; 0
   362 0000017B 29DB                    	sub	ebx, ebx ; 0	
   363                                  	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 0000017D B820000000          <1>  mov eax, %1
    86 00000182 CD30                <1>  int 30h
   364 00000184 09DB                    	or	ebx, ebx
   365                                  	;jz	short cat_n ; check for console keystroke
   366                                  	; 18/06/2022
   367 00000186 7505                    	jnz	short cat_e
   368 00000188 E958FFFFFF              	jmp	cat_n
   369                                  
   370                                  cat_e:
   371                                  	sys	_read, esi, iobuf, 1
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 0000018D 89F3                <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 0000018F B9[A0030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81 00000194 BA01000000          <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000199 B803000000          <1>  mov eax, %1
    86 0000019E CD30                <1>  int 30h
   372 000001A0 803D[A0030000]1B        	cmp	byte [iobuf], 1Bh ; 27 ; ESCape key ?
   373 000001A7 7449                    	je	short cat_k ; close file
   374                                  
   375                                  cat_c:
   376                                  	; is there a file to read ?
   377                                  	;or	esi, esi ; 05/03/2022
   378                                  	;jnz	short cat_r ; yes
   379                                  
   380                                  	; 16/06/2022
   381                                  	;and	edx, edx
   382                                  	;jz	short cat_exit ; end of stdin file
   383                                  
   384                                  	;xor	eax, eax
   385                                  	;inc	al
   386 000001A9 B001                    	mov	al, 1
   387                                  	; eax = 1	
   388 000001AB 803D[A0030000]0D        	cmp	byte [iobuf], 0Dh ; carriage return ?
   389 000001B2 7525                    	jne	short cat_w
   390 000001B4 C605[A1030000]0A        	mov	byte [iobuf+1], 0Ah ; line feed
   391 000001BB FEC0                    	inc	al
   392                                  	; eax = 2
   393 000001BD EB1A                    	jmp	short cat_w
   394                                  
   395                                  cat_m:
   396                                  	; 05/03/2022
   397                                  	;mov	eax, [esi] ; file descriptor/number
   398                                  	;;mov	ax, [esi]
   399                                  	;
   400                                  	;sys	_read, eax, iobuf, 512 ; 16/07/2015
   401                                  	;;sys 	_read, eax, ibuf, 512 
   402                                  	;jc	short cat_6
   403                                  	; 15/06/2022
   404                                  	; 05/03/2022
   405                                  	; esi = file descriptor/number
   406                                  	sys	_read, esi, iobuf, [filerwc]
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000001BF 89F3                <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 000001C1 B9[A0030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81 000001C6 8B15[9C030000]      <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 000001CC B803000000          <1>  mov eax, %1
    86 000001D1 CD30                <1>  int 30h
   407                                  		; read 512 chars into [iobuf]
   408                                  	;jc	short cat_6
   409 000001D3 721D                    	jc	short cat_k ; 05/03/2022
   410                                  
   411                                  	; NOTE: If input file is a tty (keyboard)
   412                                  	;	only 1 byte will be read, by ignoring
   413                                  	;	byte count (512).
   414                                  	;	Retro UNIX 8086 v1 kernel ('rtty')
   415                                  	;	has been modified fot that.
   416                                  	;       Erdogan Tan (16/07/2015)
   417                                  	;
   418                                  
   419                                  	; 15/06/2022
   420 000001D5 21C0                    	and	eax, eax ; EAX = 1 for tty (keyboard)
   421                                  	;jz	short cat_6
   422 000001D7 7419                    	jz	short cat_k ; 05/03/2022
   423                                  
   424                                  ;	push	esi
   425                                  	;mov	esi, ibuf
   426                                  ;	mov	esi, ecx ; offset ibuf
   427                                  ;	mov	ecx, eax
   428                                  		;;mov	fin,r0
   429                                  		;;sys	read; ibuf; 512.
   430                                  		;;bes	3f
   431                                  		;;mov	r0,r4
   432                                  		;;beq	3f
   433                                  		;;mov	$ibuf,r3
   434                                  	 ; 16/07/2015
   435                                  ;	mov	edx, eax
   436                                  ;	;add	edx, obuf
   437                                  ;cat_4:
   438                                  ;	;;4:
   439                                  ;	lodsb
   440                                  	;call	putc
   441                                  cat_w:
   442                                  	; 16/07/2015
   443                                  	; write to console tty (stdout)
   444                                  	sys 	_write, 1, iobuf, eax
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000001D9 BB01000000          <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 000001DE B9[A0030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81 000001E3 89C2                <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 000001E5 B804000000          <1>  mov eax, %1
    86 000001EA CD30                <1>  int 30h
   445                                  	;jc	short cat_6
   446                                  	; 05/03/2022
   447                                  	;jnc	short cat_3
   448                                  	; 15/06/2022
   449 000001EC 7347                    	jnc	short cat_8
   450                                  
   451                                  ;	loop	cat_4
   452                                  ;	pop	esi
   453                                  cat_5:
   454                                  	;mov	eax, [esi] ; 05/03/2022
   455                                  	;;mov	ax, [esi]
   456                                  	;jmp	short cat_3
   457                                  		;;movb	(r3)+,r0
   458                                  		;;jsr	pc,putc
   459                                  		;;dec	r4
   460                                  		;;bne	4b
   461                                  		;;br	3b
   462                                  	;; 05/03/2022
   463                                  	;; ebx = file descriptor/input
   464                                  	;;and	ebx, ebx ; console input ?
   465                                  	;;jnz	short cat_3 ; no, file input
   466                                  	;;cmp	byte [quit], al ; 0
   467                                  	;;ja	short cat_7 ; ebx = 0
   468                                  	;;jmp	short cat_z
   469                                  	; 05/03/2022
   470                                  	;jmp	short cat_3
   471                                  		
   472                                  cat_6:	;;3:
   473                                  	; 05/03/2022
   474                                  	; ebx = file descriptor/number
   475                                  	;movzx	ebx, word [esi]
   476                                  	;
   477 000001EE 09F6                    	or	esi, esi
   478 000001F0 7409                    	jz	short cat_7
   479                                  cat_k:
   480                                  	sys	_close, esi
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000001F2 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 000001F4 B806000000          <1>  mov eax, %1
    86 000001F9 CD30                <1>  int 30h
   481                                  	;
   482                                  	;or	ebx, ebx
   483                                  	;jz	short cat_7
   484                                  	;sys 	_close
   485                                  		;;mov	fin,r0
   486                                  		;;beq	loop
   487                                  		;;sys	close
   488                                  		;;br	loop
   489                                  cat_7:	
   490                                  	;;loop:
   491 000001FB 4D                      	dec	ebp
   492                                  	;;jz	short cat_8
   493                                  	; 28/12/2015
   494                                  	;jg	short cat_0
   495                                  	; 05/03/2022
   496 000001FC 7E2D                    	jng	short cat_exit
   497 000001FE E948FEFFFF              	jmp	cat_0
   498                                  
   499                                  	; 18/06/2022 (ESCape)
   500                                  cat_q:
   501                                  	; open console tty for read
   502                                  	sys	_open, consoletty, 0
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000203 BB[81030000]        <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000208 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 0000020D B805000000          <1>  mov eax, %1
    86 00000212 CD30                <1>  int 30h
   503 00000214 7215                    	jc	short cat_exit
   504                                  	sys	_read, eax, iobuf
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000216 89C3                <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000218 B9[A0030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 0000021D B803000000          <1>  mov eax, %1
    86 00000222 CD30                <1>  int 30h
   505                                  	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 00000224 B806000000          <1>  mov eax, %1
    86 00000229 CD30                <1>  int 30h
   506                                  
   507                                  	;jmp	short cat_exit	
   508                                  
   509                                  cat_exit:
   510                                  	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 0000022B B801000000          <1>  mov eax, %1
    86 00000230 CD30                <1>  int 30h
   511                                  here:
   512 00000232 90                      	nop
   513 00000233 EBFD                    	jmp	short here
   514                                  
   515                                  cat_8:
   516                                  	; 15/06/2022
   517 00000235 39D0                    	cmp	eax, edx
   518 00000237 72B5                    	jb	short cat_6
   519 00000239 8B15[98030000]          	mov	edx, [stdinrw]
   520 0000023F 09D2                    	or 	edx, edx  ; end of stdin file
   521 00000241 7405                    	jz	short cat_9
   522 00000243 E99DFEFFFF              	jmp	cat_n
   523                                  
   524                                  cat_9:
   525                                  	; 16/06/2022
   526 00000248 21F6                    	and	esi, esi
   527 0000024A 74A6                    	jz	short cat_k
   528 0000024C E91EFFFFFF              	jmp	cat_r ; 18/06/2022
   529                                  
   530                                  ;cat_8:
   531                                  ;	;;done:
   532                                  ;	sub	di, obuf
   533                                  ;	jz	short cat_9
   534                                  ;	sys	_write, 1, obuf, di 
   535                                  		;;sub	$obuf,r2
   536                                  		;;beq	1f
   537                                  		;;mov	r2,0f
   538                                  		;;mov	$1,r0
   539                                  		;;sys	write; obuf; 0:..
   540                                  ;cat_9:	
   541                                  ;	;;1:
   542                                  ;	sys	_exit
   543                                  		;;sys	exit
   544                                  	;;
   545                                  ;putc:	
   546                                  ;	;;putc:
   547                                  ;	stosb
   548                                  ;	cmp	di, dx ; 16/07/2015
   549                                  	;cmp	di, obuf + 512
   550                                  ;	jb	short cat_10
   551                                  ;	push	cx
   552                                  	 ; 16/07/2015
   553                                  ;	mov	di, obuf
   554                                  ;	sub	dx, di ; byte (char) count
   555                                  	; 
   556                                  ;	sys 	_write, 1, obuf
   557                                  	;sys 	_write, 1, obuf, 512
   558                                  	;mov	di, obuf
   559                                  		;;movb	r0,(r2)+
   560                                  		;;cmp	r2,$obuf+512.
   561                                  		;;blo	1f
   562                                  		;;mov	$1,r0
   563                                  		;;sys	write; obuf; 512.
   564                                  		;;mov	$obuf,r2
   565                                  ;	pop	cx
   566                                  ;cat_10:	
   567                                  	;;1:
   568                                  ;	retn
   569                                  		;;rts	pc
   570                                  
   571                                  writeline:
   572                                  	; 19/06/2022
   573                                  
   574                                  	; write line(s) to file (with echo)
   575                                  	; stdin = console tty
   576                                  	; stdout = file or another tty
   577                                  
   578                                  	;mov	edi, linebuf
   579                                   
   580                                  	;sys	_gtty, 0, 1  ; get status of console tty (w)	
   581                                  	;jc	short done3
   582                                  	
   583 00000251 A0[8F030000]            	mov	al, [consol]
   584                                  	; al = console tty number
   585 00000256 0430                    	add	al, '0'
   586 00000258 A2[89030000]            	mov	[consoletty+8], al
   587                                  
   588 0000025D C605[8E030000]1B        	mov	byte [chr], 1Bh ; ESCape
   589                                  
   590                                  	sys	_open, consoletty, 0 ; open for read
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000264 BB[81030000]        <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000269 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 0000026E B805000000          <1>  mov eax, %1
    86 00000273 CD30                <1>  int 30h
   591                                  	;jc	short done3
   592 00000275 7305                    	jnc	short G0
   593 00000277 E995000000              	jmp	done3 
   594                                  G0:
   595 0000027C A3[90030000]            	mov	[consol_r], eax
   596                                  	sys	_open, consoletty, 1 ; open for write
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000281 BB[81030000]        <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000286 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 0000028B B805000000          <1>  mov eax, %1
    86 00000290 CD30                <1>  int 30h
   597 00000292 7270                    	jc	short done2
   598 00000294 A3[94030000]            	mov	[consol_w], eax
   599                                  	sys	_write, [consol_w], crlf, 2
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000299 8B1D[94030000]      <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 0000029F B9[7E030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81 000002A4 BA02000000          <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 000002A9 B804000000          <1>  mov eax, %1
    86 000002AE CD30                <1>  int 30h
   600                                  do:
   601 000002B0 BF[A0030000]                    mov	edi, linebuf
   602                                  getc:
   603                                  	sys	_read, [consol_r], chr, 1
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000002B5 8B1D[90030000]      <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 000002BB B9[8E030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81 000002C0 BA01000000          <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 000002C5 B803000000          <1>  mov eax, %1
    86 000002CA CD30                <1>  int 30h
   604 000002CC 7229                    	jc	short done1
   605                                  	;and	eax, eax
   606                                  	;jz	short done1
   607                                  	;
   608 000002CE A0[8E030000]            	mov	al, [chr]
   609                                  
   610 000002D3 3C1B                    	cmp	al, 1Bh ; ESCape key
   611 000002D5 7420                    	je	short done1
   612                                  
   613 000002D7 3C20                    	cmp	al, 20h
   614 000002D9 7256                    	jb	short G1
   615                                  
   616 000002DB 3C7F                    	cmp	al, 127
   617 000002DD 745F                    	je	short G2
   618                                  
   619 000002DF 81FF[F0030000]                  cmp	edi, linebuf+80
   620 000002E5 73CE                    	jnb	short getc
   621                                  putc:
   622 000002E7 AA                      	stosb
   623                                  echo:
   624                                  	;sys	_write, [consol_w], chr, 1
   625                                  	; ecx = chr
   626                                  	; edx = 1
   627                                  	sys	_write, [consol_w]
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000002E8 8B1D[94030000]      <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 000002EE B804000000          <1>  mov eax, %1
    86 000002F3 CD30                <1>  int 30h
   628 000002F5 EBBE                    	jmp	short getc
   629                                  
   630                                  done1:
   631                                  	sys	_close, [consol_w]
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 000002F7 8B1D[94030000]      <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 000002FD B806000000          <1>  mov eax, %1
    86 00000302 CD30                <1>  int 30h
   632                                  done2:
   633                                  	sys	_close, [consol_r]
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 00000304 8B1D[90030000]      <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 0000030A B806000000          <1>  mov eax, %1
    86 0000030F CD30                <1>  int 30h
   634                                  done3:
   635                                  	;mov	byte [edi], 0
   636                                  	;mov	al, [chr]
   637                                  	;retn
   638                                  
   639 00000311 89FA                    	mov	edx, edi
   640 00000313 81EA[A0030000]          	sub	edx, linebuf	
   641 00000319 7411                    	jz	short done4
   642                                  
   643                                  	sys	_write, 1, linebuf
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 0000031B BB01000000          <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000320 B9[A0030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81                              <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 00000325 B804000000          <1>  mov eax, %1
    86 0000032A CD30                <1>  int 30h
   644                                  done4:
   645                                  	;sys	_exit
   646 0000032C E9FAFEFFFF              	jmp	cat_exit
   647                                  
   648                                  G1:
   649 00000331 3C0D                    	cmp	al, ENTERKEY  ; \r (carriage return)
   650 00000333 7414                            je	short G3
   651                                  
   652                                  	;cmp	al, NEXTLINE  ; \n (next line)
   653                                          ;je	short G3
   654                                  
   655 00000335 3C08                    	cmp	al, BACKSPACE ; \b (back space)
   656 00000337 7405                    	je	short G2
   657                                  getch:
   658 00000339 E977FFFFFF              	jmp	getc
   659                                  G2:
   660                                  	; Backspace
   661 0000033E 81FF[A0030000]          	cmp	edi, linebuf
   662 00000344 76F3                    	jna	short getch
   663 00000346 4F                      	dec	edi
   664 00000347 EB9F                    	jmp	short echo
   665                                  
   666                                  G3:
   667                                  	;mov	al, ENTERKEY ; carriage return
   668 00000349 AA                      	stosb
   669 0000034A B00A                    	mov	al, NEXTLINE ; line feed
   670 0000034C AA                      	stosb
   671                                  	sys	_write, [consol_w], crlf, 2
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 0000034D 8B1D[94030000]      <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 00000353 B9[7E030000]        <1>  mov ecx, %3
    80                              <1>  %if %0 = 4
    81 00000358 BA02000000          <1>  mov edx, %4
    82                              <1>  %endif
    83                              <1>  %endif
    84                              <1>  %endif
    85 0000035D B804000000          <1>  mov eax, %1
    86 00000362 CD30                <1>  int 30h
   672 00000364 B9[A0030000]            	mov	ecx, linebuf 
   673 00000369 89FA                    	mov	edx, edi
   674 0000036B 29CA                    	sub	edx, ecx ; sub edx, linebuf
   675                                  	; ecx = offset crlf
   676                                  	sys	_write, 1
    73                              <1> 
    74                              <1> 
    75                              <1> 
    76                              <1>  %if %0 >= 2
    77 0000036D 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 00000372 B804000000          <1>  mov eax, %1
    86 00000377 CD30                <1>  int 30h
   677 00000379 E932FFFFFF              	jmp	do ; next line
   678                                  
   679                                  ; ;;;;
   680                                  
   681                                  crlf:	; 19/06/2022
   682 0000037E 0D0A00                  nl:	db 0Dh, 0Ah, 0
   683                                  
   684                                  ;; 05/03/2022
   685                                  ;quit:	db 0
   686                                  ; 18/06/2022
   687                                  consoletty:
   688 00000381 2F6465762F74747900-     	db '/dev/tty', 0, 0 ; ; 19/06/2022
   688 0000038A 00                 
   689                                  
   690 0000038B 90                      align 4
   691                                  
   692                                  bss_start:
   693                                  
   694                                  ABSOLUTE bss_start
   695                                  
   696                                  ; 19/06/2022
   697 0000038C ??                      stdout:	resb 1
   698                                  ; 18/06/2022
   699 0000038D ??                      chrin:	resb 1
   700                                  ; 19/06/2022
   701 0000038E ??                      chr:	resb 1
   702 0000038F ??                      consol:	resb 1
   703 00000390 ????????                consol_r: resd 1
   704 00000394 ????????                consol_w: resd 1
   705                                  
   706                                  ; 15/06/2022
   707 00000398 ????????                stdinrw: resd 1
   708 0000039C ????????                filerwc: resd 1
   709                                  
   710                                  linebuf: ; 19/06/2022	
   711 000003A0 <res 200h>              iobuf:  resb 512
   712                                  ;ibuf:	resb 512
   713                                  ;obuf:	resb 512
   714                                  ;;fin:	resw 1
   715                                  ;fin:	resd 1 ; 05/03/2022	
   716                                  		;;.bss
   717                                  		;;ibuf:	.=.+512.
   718                                  		;;obuf:	.=.+512.
   719                                  		;;fin:	.=.+2
   720                                  		;;.text
   721                                  ;bss_end:
