1 ; **************************************************************************** 2 ; srvs4.s - TRDOS 386 (TRDOS v2.0.3) Test Program - Save/Restore Video State 3 ; ---------------------------------------------------------------------------- 4 ; 5 ; 25/01/2021 6 ; 7 ; **************************************************************************** 8 ; nasm srvs4.s -l srvs4.txt -o SRVS4.PRG -Z error.txt 9 10 ; (Modified from 'srvs2.s', 24/01/2021) 11 12 ; restore video state after a child process ('sysfork', 'sysexec', 'sysvideo') 13 14 ; 14/07/2020 15 ; 31/12/2017 16 ; TRDOS 386 (v2.0) system calls 17 _ver equ 0 18 _exit equ 1 19 _fork equ 2 20 _read equ 3 21 _write equ 4 22 _open equ 5 23 _close equ 6 24 _wait equ 7 25 _create equ 8 26 _rename equ 9 27 _delete equ 10 28 _exec equ 11 29 _chdir equ 12 30 _time equ 13 31 _mkdir equ 14 32 _chmod equ 15 33 _rmdir equ 16 34 _break equ 17 35 _drive equ 18 36 _seek equ 19 37 _tell equ 20 38 _memory equ 21 39 _prompt equ 22 40 _path equ 23 41 _env equ 24 42 _stime equ 25 43 _quit equ 26 44 _intr equ 27 45 _dir equ 28 46 _emt equ 29 47 _ldrvt equ 30 48 _video equ 31 49 _audio equ 32 50 _timer equ 33 51 _sleep equ 34 52 _msg equ 35 53 _geterr equ 36 54 _fpstat equ 37 55 _pri equ 38 56 _rele equ 39 57 _fff equ 40 58 _fnf equ 41 59 _alloc equ 42 60 _dalloc equ 43 61 _calbac equ 44 62 _dma equ 45 63 64 %macro sys 1-4 65 ; 29/04/2016 - TRDOS 386 (TRDOS v2.0) 66 ; 03/09/2015 67 ; 13/04/2015 68 ; Retro UNIX 386 v1 system call. 69 %if %0 >= 2 70 mov ebx, %2 71 %if %0 >= 3 72 mov ecx, %3 73 %if %0 = 4 74 mov edx, %4 75 %endif 76 %endif 77 %endif 78 mov eax, %1 79 ;int 30h 80 int 40h ; TRDOS 386 (TRDOS v2.0) 81 %endmacro 82 83 ; Retro UNIX 386 v1 system call format: 84 ; sys systemcall (eax) , , 85 86 [BITS 32] ; We need 32-bit intructions for protected mode 87 88 [ORG 0] 89 90 START_CODE: 91 ; clear bss 92 00000000 BF[18040000] mov edi, bss_start 93 00000005 B91E040000 mov ecx, (bss_end - bss_start)/4 94 ;xor eax, eax 95 0000000A F3AB rep stosd 96 97 ; program message 98 0000000C BE[5E020000] mov esi, program_msg 99 00000011 E892010000 call print_msg 100 101 ; get video state permission flag 102 sys _video, 0905h 102 <1> 102 <1> 102 <1> 102 <1> 102 <1> %if %0 >= 2 102 00000016 BB05090000 <1> mov ebx, %2 102 <1> %if %0 >= 3 102 <1> mov ecx, %3 102 <1> %if %0 = 4 102 <1> mov edx, %4 102 <1> %endif 102 <1> %endif 102 <1> %endif 102 0000001B B81F000000 <1> mov eax, %1 102 <1> 102 00000020 CD40 <1> int 40h 103 00000022 20C0 and al, al 104 ;jnz short _0 105 00000024 7539 jnz short _1 106 107 ; enable 'srvs' fuction 108 sys _video, 0904h 108 <1> 108 <1> 108 <1> 108 <1> 108 <1> %if %0 >= 2 108 00000026 BB04090000 <1> mov ebx, %2 108 <1> %if %0 >= 3 108 <1> mov ecx, %3 108 <1> %if %0 = 4 108 <1> mov edx, %4 108 <1> %endif 108 <1> %endif 108 <1> %endif 108 0000002B B81F000000 <1> mov eax, %1 108 <1> 108 00000030 CD40 <1> int 40h 109 00000032 20C0 and al, al 110 ;jz short _save_err1 ; error 111 00000034 7529 jnz short _1 112 ;_0: 113 ; save video state 114 115 ; Note: Available buffer size is 4096 bytes. 116 ; (vbe3 state buffer size can not be more 117 ; than 2048 bytes because of system buff limit) 118 ; So, it is not needed to check buffer size here. 119 120 ;mov eax, 4F04h 121 ;xor edx, edx ; dl = 0 ; get buffer size 122 ;mov ecx, 0Fh 123 ;int 31h 124 ;cmp eax, 4Fh 125 ;je short _1 126 _save_err1: 127 00000036 BE[32030000] mov esi, save_error_msg 128 0000003B E868010000 call print_msg 129 _terminate: 130 sys _exit 130 <1> 130 <1> 130 <1> 130 <1> 130 <1> %if %0 >= 2 130 <1> mov ebx, %2 130 <1> %if %0 >= 3 130 <1> mov ecx, %3 130 <1> %if %0 = 4 130 <1> mov edx, %4 130 <1> %endif 130 <1> %endif 130 <1> %endif 130 00000040 B801000000 <1> mov eax, %1 130 <1> 130 00000045 CD40 <1> int 40h 131 _hang: 132 00000047 EBFE jmp short _hang 133 _save_err2: 134 00000049 BE[32030000] mov esi, save_error_msg 135 0000004E E855010000 call print_msg 136 00000053 BE[E5020000] mov esi, vstate_size_msg 137 00000058 E84B010000 call print_msg 138 0000005D EBE1 jmp short _terminate 139 _1: 140 ;mov eax, ebx 141 ;shl ax, 6 ; * 64 142 ;call write_number 143 144 ;mov eax, 4F04h 145 ;mov dl, 1 ; save video state 146 ;mov ecx, 0Fh 147 ;mov ebx, vstate 148 ;int 31h 149 ;cmp eax, 4Fh 150 ;jne short _save_err2 151 152 ; Save (complete) vide state to user's buffer 153 sys _video, 0E3Eh, vstate 153 <1> 153 <1> 153 <1> 153 <1> 153 <1> %if %0 >= 2 153 0000005F BB3E0E0000 <1> mov ebx, %2 153 <1> %if %0 >= 3 153 00000064 B9[90040000] <1> mov ecx, %3 153 <1> %if %0 = 4 153 <1> mov edx, %4 153 <1> %endif 153 <1> %endif 153 <1> %endif 153 00000069 B81F000000 <1> mov eax, %1 153 <1> 153 0000006E CD40 <1> int 40h 154 ; BL option bit 2 will be cleared by kernel 155 ; if video system is a vesa vbe3 system 156 ;sys _video, 0E3Ah, vstate 157 00000070 09C0 or eax, eax ; transfer count > 0 ; ? 158 00000072 74C2 jz short _save_err1 ; no, fail ! 159 160 00000074 E8D0000000 call write_number 161 162 00000079 BE[C3020000] mov esi, save_ok_msg 163 0000007E E825010000 call print_msg 164 165 00000083 E8E2000000 call file_name_input 166 00000088 7258 jc short parent_return 167 ; restore video state and then exit 168 169 ; EBX = EAX = file name or path address 170 ; CL = file attributes (archive = 20h, read only = 01h) 171 ; (21h = Archived & Read Only files are included) 172 ; CH = 0 = basic parameters (24 bytes) 173 ; EDX = DTA = buffer address (24 bytes for basic parameters) 174 ; EAX = _fff = 'Find First File' system call for TRDOS 386 175 176 ; Find First File 177 sys _fff, prg_file_name, 0021h, DTA 177 <1> 177 <1> 177 <1> 177 <1> 177 <1> %if %0 >= 2 177 0000008A BB[30040000] <1> mov ebx, %2 177 <1> %if %0 >= 3 177 0000008F B921000000 <1> mov ecx, %3 177 <1> %if %0 = 4 177 00000094 BA[18040000] <1> mov edx, %4 177 <1> %endif 177 <1> %endif 177 <1> %endif 177 00000099 B828000000 <1> mov eax, %1 177 <1> 177 0000009E CD40 <1> int 40h 178 000000A0 730C jnc short _3 179 _2: 180 000000A2 BE[4E030000] mov esi, not_found_msg 181 000000A7 E8FC000000 call print_msg 182 183 000000AC EB92 jmp short _terminate 184 _3: 185 ; check file attributes 186 000000AE F605[18040000]1E test byte [DTA], 1Eh ; 10h = directory, 08h = volume label 187 ; 04h = system, 02h = hidden 188 000000B5 75EB jnz short _2 ; attributes are not proper 189 190 ; atributes are proper 191 000000B7 BE[6A030000] mov esi, press_any_key_msg 192 000000BC E8E7000000 call print_msg 193 194 000000C1 30E4 xor ah, ah 195 000000C3 CD32 int 32h 196 197 000000C5 BE[98030000] mov esi, nextline 198 000000CA E8D9000000 call print_msg 199 200 000000CF BB[19010000] mov ebx, child_exec 201 sys _fork 201 <1> 201 <1> 201 <1> 201 <1> 201 <1> %if %0 >= 2 201 <1> mov ebx, %2 201 <1> %if %0 >= 3 201 <1> mov ecx, %3 201 <1> %if %0 = 4 201 <1> mov edx, %4 201 <1> %endif 201 <1> %endif 201 <1> %endif 201 000000D4 B802000000 <1> mov eax, %1 201 <1> 201 000000D9 CD40 <1> int 40h 202 203 sys _wait 203 <1> 203 <1> 203 <1> 203 <1> 203 <1> %if %0 >= 2 203 <1> mov ebx, %2 203 <1> %if %0 >= 3 203 <1> mov ecx, %3 203 <1> %if %0 = 4 203 <1> mov edx, %4 203 <1> %endif 203 <1> %endif 203 <1> %endif 203 000000DB B807000000 <1> mov eax, %1 203 <1> 203 000000E0 CD40 <1> int 40h 204 205 parent_return: 206 ; restore video state 207 ;mov eax, 4F04h 208 ;mov dl, 2 ; restore video state 209 ;mov ecx, 0Fh 210 ;mov ebx, vstate 211 ;int 31h 212 ;cmp eax, 4Fh 213 ;je short _4 214 215 sys _video, 0E3Fh, vstate 215 <1> 215 <1> 215 <1> 215 <1> 215 <1> %if %0 >= 2 215 000000E2 BB3F0E0000 <1> mov ebx, %2 215 <1> %if %0 >= 3 215 000000E7 B9[90040000] <1> mov ecx, %3 215 <1> %if %0 = 4 215 <1> mov edx, %4 215 <1> %endif 215 <1> %endif 215 <1> %endif 215 000000EC B81F000000 <1> mov eax, %1 215 <1> 215 000000F1 CD40 <1> int 40h 216 ; BL option bit 2 will be cleared by kernel 217 ; if video system is a vesa vbe3 system 218 ;sys _video, 0E3Bh, vstate 219 220 000000F3 09C0 or eax, eax ; transfer count > 0 ; ? 221 000000F5 750C jnz short _4 ; yes, success . 222 223 _restore_err: 224 000000F7 BE[9B030000] mov esi, restore_error_msg 225 000000FC E8A7000000 call print_msg 226 00000101 EB3D jmp short terminate 227 _4: 228 00000103 BE[BA030000] mov esi, restore_ok 229 00000108 E89B000000 call print_msg 230 0000010D BE[13030000] mov esi, msg_ok 231 00000112 E891000000 call print_msg 232 00000117 EB27 jmp short terminate 233 234 child_exec: 235 ; execute (run) program 236 sys _exec, prg_file_name, prgp 236 <1> 236 <1> 236 <1> 236 <1> 236 <1> %if %0 >= 2 236 00000119 BB[30040000] <1> mov ebx, %2 236 <1> %if %0 >= 3 236 0000011E B9[0A040000] <1> mov ecx, %3 236 <1> %if %0 = 4 236 <1> mov edx, %4 236 <1> %endif 236 <1> %endif 236 <1> %endif 236 00000123 B80B000000 <1> mov eax, %1 236 <1> 236 00000128 CD40 <1> int 40h 237 238 ; Error if child returns here 239 240 sys _msg, error_msg, 255, 0Eh 240 <1> 240 <1> 240 <1> 240 <1> 240 <1> %if %0 >= 2 240 0000012A BB[F3030000] <1> mov ebx, %2 240 <1> %if %0 >= 3 240 0000012F B9FF000000 <1> mov ecx, %3 240 <1> %if %0 = 4 240 00000134 BA0E000000 <1> mov edx, %4 240 <1> %endif 240 <1> %endif 240 <1> %endif 240 00000139 B823000000 <1> mov eax, %1 240 <1> 240 0000013E CD40 <1> int 40h 241 terminate: 242 sys _exit 242 <1> 242 <1> 242 <1> 242 <1> 242 <1> %if %0 >= 2 242 <1> mov ebx, %2 242 <1> %if %0 >= 3 242 <1> mov ecx, %3 242 <1> %if %0 = 4 242 <1> mov edx, %4 242 <1> %endif 242 <1> %endif 242 <1> %endif 242 00000140 B801000000 <1> mov eax, %1 242 <1> 242 00000145 CD40 <1> int 40h 243 halt: 244 00000147 EBFE jmp short halt 245 246 write_number: 247 00000149 B908000000 mov ecx, 8 248 0000014E 89C2 mov edx, eax 249 00000150 BF[01030000] mov edi, number_txt 250 wn_0: 251 00000155 C1C204 rol edx, 4 ; move highest 4 bits to lowest pos 252 00000158 88D0 mov al, dl 253 0000015A 240F and al, 0Fh ; isolate lowest 4 bits 254 0000015C 3C09 cmp al, 9 255 0000015E 7604 jna short wn_1 256 00000160 0437 add al, 'A'-10 257 00000162 EB02 jmp short wn_2 258 wn_1: 259 00000164 0430 add al, '0' 260 wn_2: 261 00000166 AA stosb 262 00000167 E2EC loop wn_0 263 264 00000169 C3 retn 265 266 file_name_input: 267 ; subroutine for entering file name to run 268 269 0000016A BE[E0030000] mov esi, prg_file_name_msg 270 0000016F E834000000 call print_msg 271 00000174 E840000000 call rw_char 272 00000179 7214 jc short fni_1 273 0000017B BF[30040000] mov edi, prg_file_name 274 00000180 803E20 cmp byte [esi], 20h 275 00000183 760A jna short short fni_1 276 00000185 B90C000000 mov ecx, 12 277 fni_0: 278 0000018A AC lodsb 279 0000018B 3C20 cmp al, 20h 280 0000018D 7306 jnb short fni_2 281 fni_1: 282 ;mov [edi], 0 283 ;inc edi 284 ;loop fni_1 285 ;jmp short fni_3 ; find_file 286 287 0000018F 28C0 sub al, al ; 0 288 00000191 F3AA rep stosb 289 00000193 EB05 jmp short fni_3 ; find_file 290 fni_2: 291 00000195 8807 mov byte [edi], al 292 00000197 47 inc edi 293 00000198 E2F0 loop fni_0 294 fni_3: 295 0000019A 803D[30040000]21 cmp byte [prg_file_name], 21h 296 000001A1 7215 jb short fni_4 ; cf = 1 297 298 ; next line 299 000001A3 BE[98030000] mov esi, nextline 300 print_msg: 301 000001A8 B40E mov ah, 0Eh 302 000001AA BB07000000 mov ebx, 7 303 ;mov bl, 7 ; char attribute & color 304 p_next_chr: 305 000001AF AC lodsb 306 000001B0 08C0 or al, al 307 000001B2 7404 jz short fni_4 ; retn 308 000001B4 CD31 int 31h 309 000001B6 EBF7 jmp short p_next_chr 310 fni_4: 311 000001B8 C3 retn 312 313 rw_char: 314 ; file name (text) input routine 315 ; OUTPUT -> esi = Entered String (ASCIIZ) 316 000001B9 BE[30040000] mov esi, prg_file_name 317 000001BE BB07000000 mov ebx, 7 318 000001C3 B403 mov ah, 3 319 ;int 10h 320 000001C5 CD31 int 31h 321 000001C7 668915[3E040000] mov [cursor_pos], dx 322 000001CE EB0A jmp short read_next_char 323 loc_arrow: 324 000001D0 80FC4B cmp ah, 4Bh 325 000001D3 7415 je short loc_back 326 000001D5 80FC53 cmp ah, 53h 327 000001D8 7410 je short loc_back 328 read_next_char: 329 000001DA 30E4 xor ah, ah 330 ;int 16h 331 000001DC CD32 int 32h 332 000001DE 20C0 and al, al 333 000001E0 74EE jz short loc_arrow 334 000001E2 3CE0 cmp al, 0E0h 335 000001E4 74EA je short loc_arrow 336 000001E6 3C08 cmp al, 08h 337 000001E8 753C jne short char_return 338 loc_back: 339 000001EA B307 mov bl, 7 340 000001EC B403 mov ah, 3 341 ;int 10h 342 000001EE CD31 int 31h 343 000001F0 3A15[3E040000] cmp dl, [cursor_pos] 344 000001F6 7708 ja short prev_column 345 loc_beep: 346 000001F8 B40E mov ah, 0Eh 347 000001FA B007 mov al, 7 348 ;int 10h 349 000001FC CD31 int 31h 350 000001FE EBDA jmp short read_next_char 351 prev_column: 352 00000200 FECA dec dl 353 set_cursor_pos: 354 00000202 B402 mov ah, 02h 355 ;int 10h 356 00000204 CD31 int 31h 357 00000206 88D3 mov bl, dl 358 00000208 2A1D[3E040000] sub bl, [cursor_pos] 359 0000020E 66B90100 mov cx, 1 360 00000212 B409 mov ah, 09h 361 00000214 B020 mov al, 20h 362 00000216 88041E mov [esi+ebx], al 363 loc_write_it: 364 00000219 B307 mov bl, 7 365 ;int 10h 366 0000021B CD31 int 31h 367 0000021D 668B15[3E040000] mov dx, [cursor_pos] 368 00000224 EBB4 jmp short read_next_char 369 ;loc_arrow: 370 ; cmp ah, 4Bh 371 ; je short loc_back 372 ; cmp AH, 53h 373 ; je short loc_back 374 ; jmp short read_next_char 375 char_return: 376 00000226 B307 mov bl, 7 377 00000228 B403 mov ah, 3 378 ;int 10h 379 0000022A CD31 int 31h 380 0000022C 88D3 mov bl, dl 381 0000022E 2A1D[3E040000] sub bl, [cursor_pos] 382 00000234 3C20 cmp al, 20h 383 00000236 7220 jb short loc_escape 384 00000238 80FB3F cmp bl, 63 385 0000023B 77BB ja short loc_beep 386 ;cmp al, "z" 387 ;ja short read_next_char 388 ;cmp al, "a" 389 ;jb short pass_capitalize 390 ;and al, 0DFh 391 pass_capitalize: 392 0000023D 30E4 xor ah, ah 393 0000023F 6689041E mov [esi+ebx], ax 394 00000243 B40E mov ah, 0Eh 395 00000245 B307 mov bl, 7 396 ;int 10h 397 00000247 CD31 int 31h 398 00000249 EB8F jmp short read_next_char 399 pass_escape: 400 0000024B 3C0D cmp al, 0Dh 401 0000024D 758B jne short read_next_char 402 0000024F B307 mov bl, 7 403 ;int 10h 404 00000251 CD31 int 31h 405 00000253 B00A mov al, 0Ah 406 ;int 10h 407 00000255 CD31 int 31h 408 00000257 C3 retn 409 loc_escape: 410 00000258 3C1B cmp al, 1Bh 411 0000025A 75EF jne short pass_escape 412 0000025C F9 stc 413 0000025D C3 retn 414 415 program_msg: 416 0000025E 5452444F5320333836- db "TRDOS 386 v2.0.3 - Save/Restore Video State ('sysvideo') Test Program" 416 00000267 2076322E302E33202D- 416 00000270 20536176652F526573- 416 00000279 746F72652056696465- 416 00000282 6F2053746174652028- 416 0000028B 27737973766964656F- 416 00000294 272920546573742050- 416 0000029D 726F6772616D 417 000002A3 0D0A db 0Dh, 0Ah 418 000002A5 6279204572646F6761- db "by Erdogan Tan - 25/01/2021" 418 000002AE 6E2054616E202D2032- 418 000002B7 352F30312F32303231 419 000002C0 0D0A00 db 0Dh, 0Ah, 0 420 save_ok_msg: 421 000002C3 0D0A db 0Dh, 0Ah 422 000002C5 566964656F20537461- db "Video State has been saved ..." 422 000002CE 746520686173206265- 422 000002D7 656E20736176656420- 422 000002E0 2E2E2E 423 000002E3 0D0A db 0Dh, 0Ah 424 vstate_size_msg: 425 000002E5 0D0A db 0Dh, 0Ah 426 000002E7 566964656F20537461- db "Video State Buffer Size : " 426 000002F0 746520427566666572- 426 000002F9 2053697A65203A20 427 number_txt: 428 00000301 585858585858585868- db "XXXXXXXXh bytes" 428 0000030A 206279746573 429 00000310 0D0A00 db 0Dh, 0Ah, 0 430 431 msg_ok: 432 ;db 0Dh, 0Ah 433 00000313 2852657475726E2074- db "(Return to parent is) OK." 433 0000031C 6F20706172656E7420- 433 00000325 697329204F4B2E 434 0000032C 0D0A00 db 0Dh, 0Ah, 0 435 0000032F 0D0A00 db 0Dh, 0Ah, 0 436 437 save_error_msg: 438 00000332 0D0A db 0Dh, 0Ah 439 00000334 566964656F20537461- db "Video State Save Error!" 439 0000033D 746520536176652045- 439 00000346 72726F7221 440 0000034B 0D0A00 db 0Dh, 0Ah, 0 441 442 not_found_msg: 443 0000034E 0D0A db 0Dh, 0Ah 444 00000350 50726F6772616D2066- db "Program file not found!" 444 00000359 696C65206E6F742066- 444 00000362 6F756E6421 445 00000367 0D0A00 db 0Dh, 0Ah, 0 446 447 press_any_key_msg: 448 0000036A 0D0A db 0Dh, 0Ah 449 0000036C 507265737320616E79- db "Press any key to run (child) program file .." 449 00000375 206B657920746F2072- 449 0000037E 756E20286368696C64- 449 00000387 292070726F6772616D- 449 00000390 2066696C65202E2E 450 nextline: 451 00000398 0D0A00 db 0Dh, 0Ah, 0 452 453 restore_error_msg: 454 0000039B 0D0A db 0Dh, 0Ah 455 0000039D 566964656F20537461- db "Video State Restore Error!" 455 000003A6 746520526573746F72- 455 000003AF 65204572726F7221 456 000003B7 0D0A00 db 0Dh, 0Ah, 0 457 458 restore_ok: 459 000003BA 0D0A db 0Dh, 0Ah 460 000003BC 566964656F20537461- db "Video State has been restored ..." 460 000003C5 746520686173206265- 460 000003CE 656E20726573746F72- 460 000003D7 6564202E2E2E 461 000003DD 0D0A00 db 0Dh, 0Ah, 0 462 463 prg_file_name_msg: 464 000003E0 0D0A db 0Dh, 0Ah 465 000003E2 5052472046696C6520- db "PRG File Name : ", 0 465 000003EB 4E616D65203A2000 466 467 error_msg: 468 000003F3 0D0A07 db 0Dh, 0Ah, 07h 469 000003F6 277379736578656327- db "'sysexec' error !" 469 000003FF 206572726F722021 470 00000407 0D0A db 0Dh, 0Ah 471 00000409 00 db 0 472 473 0000040A [30040000] prgp: dd prg_file_name 474 0000040E [40040000] dd arguments 475 00000412 00000000 dd 0 476 477 bss: 478 479 ABSOLUTE bss 480 481 00000416 alignb 4 482 483 bss_start: 484 485 00000418 DTA: resb 24 486 487 alignb 16 488 489 prg_file_name: 490 00000430 resb 13 491 0000043D resb 1 492 493 cursor_pos: 494 0000043E resw 1 495 496 arguments: 497 00000440 resb 80 498 499 vstate: 500 00000490 resb 4096 501 502 bss_end: