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