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