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 .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) , , 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 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 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: