1 ; **************************************************************************** 2 ; loadbmp1.s (TRDOS 386, TRDOS v2.0 - sample binary file, 'loadbmp1.prg') 3 ; ---------------------------------------------------------------------------- 4 ; LOADBMP.PRG ! VESA VBE (bitmap image display) TEST program for TRDOS 386 ! 5 ; 6 ; 14/12/2020 7 ; 8 ; [ Last Modification: 20/12/2020 ] 9 ; 10 ; derived from (bmp loading) asm source code (for msdos) by Glen Quinn, 1998 11 ; modified from 'loadpcx.s' (by Erdogan Tan), 14/10/2016 12 ; 13 ; Assembler: NASM 2.15 14 ; command: nasm loadbmp1.s -l loadbmp1.txt -o LOADBMP1.PRG -Z error.txt 15 ; 16 ; Note: This program displays 640x480 8bpp non-compressed BMP files only. 17 ; **************************************************************************** 18 19 ; 14/07/2020 20 ; 31/12/2017 21 ; TRDOS 386 (v2.0) system calls 22 _ver equ 0 23 _exit equ 1 24 _fork equ 2 25 _read equ 3 26 _write equ 4 27 _open equ 5 28 _close equ 6 29 _wait equ 7 30 _create equ 8 31 _rename equ 9 32 _delete equ 10 33 _exec equ 11 34 _chdir equ 12 35 _time equ 13 36 _mkdir equ 14 37 _chmod equ 15 38 _rmdir equ 16 39 _break equ 17 40 _drive equ 18 41 _seek equ 19 42 _tell equ 20 43 _memory equ 21 44 _prompt equ 22 45 _path equ 23 46 _env equ 24 47 _stime equ 25 48 _quit equ 26 49 _intr equ 27 50 _dir equ 28 51 _emt equ 29 52 _ldrvt equ 30 53 _video equ 31 54 _audio equ 32 55 _timer equ 33 56 _sleep equ 34 57 _msg equ 35 58 _geterr equ 36 59 _fpstat equ 37 60 _pri equ 38 61 _rele equ 39 62 _fff equ 40 63 _fnf equ 41 64 _alloc equ 42 65 _dalloc equ 43 66 _calbac equ 44 67 _dma equ 45 68 69 %macro sys 1-4 70 ; 29/04/2016 - TRDOS 386 (TRDOS v2.0) 71 ; 03/09/2015 72 ; 13/04/2015 73 ; Retro UNIX 386 v1 system call. 74 %if %0 >= 2 75 mov ebx, %2 76 %if %0 >= 3 77 mov ecx, %3 78 %if %0 = 4 79 mov edx, %4 80 %endif 81 %endif 82 %endif 83 mov eax, %1 84 ;int 30h 85 int 40h ; TRDOS 386 (TRDOS v2.0) 86 %endmacro 87 88 ; TRDOS 386 (and Retro UNIX 386 v1) system call format: 89 ; sys systemcall (eax) , , 90 91 struc BMPHEAD ; This is the bitmap structure 92 00000000 ???? .id: resw 1 93 00000002 ???????? .filesize: resd 1 94 00000006 ???????? .reserved: resd 1 95 0000000A ???????? .headersize: resd 1 96 0000000E ???????? .infosize: resd 1 97 00000012 ???????? .width: resd 1 98 00000016 ???????? .depth: resd 1 99 0000001A ???? .biplanes: resw 1 100 0000001C ???? .bits: resw 1 101 0000001E ???????? .bicomp: resd 1 102 00000022 ???????? .bisizeim: resd 1 103 00000026 ???????? .bixpels: resd 1 104 0000002A ???????? .biypels: resd 1 105 0000002E ???????? .biclrused: resd 1 106 00000032 ???????? .biclrimp: resd 1 107 .size: ; 54 bytes 108 endstruc 109 110 struc RGBQUAD ; This is how the bitmap stores its colours 111 00000000 ?? .blue: resb 1 112 00000001 ?? .green: resb 1 113 00000002 ?? .red: resb 1 114 00000003 ?? .fill: resb 1 115 endstruc 116 117 ;BMP equ BUFFER ; buffer which bmp file will be loaded 118 119 [BITS 32] ; 32-bit protected mode intructions for 80386 (compatible) cpu 120 121 [ORG 0] 122 123 START_CODE: 124 00000000 89E6 mov esi, esp 125 00000002 AD lodsd 126 00000003 83F802 cmp eax, 2 ; two arguments (program file name & bmp file name) 127 ;jb terminate ; nothing top do 128 00000006 0F82A5000000 jb _terminate ; write program name, usage & exit 129 0000000C AD lodsd ; program file name address 130 0000000D AD lodsd ; bmp file name address 131 ; 20/12/2020 132 ;push eax ; arg2 ; file name 133 134 sys _open, eax, 0 ; open for reading 70 <1> 71 <1> 72 <1> 73 <1> 74 <1> %if %0 >= 2 75 0000000E 89C3 <1> mov ebx, %2 76 <1> %if %0 >= 3 77 00000010 B900000000 <1> mov ecx, %3 78 <1> %if %0 = 4 79 <1> mov edx, %4 80 <1> %endif 81 <1> %endif 82 <1> %endif 83 00000015 B805000000 <1> mov eax, %1 84 <1> 85 0000001A CD40 <1> int 40h 135 0000001C 0F82A4000000 jc open_error 136 137 00000022 A3[84030000] mov [fhandle], eax ; file handle/index number 138 139 sys _read, [fhandle], BUFFER, 0FFFFFFFFh ; read all bytes of the file 70 <1> 71 <1> 72 <1> 73 <1> 74 <1> %if %0 >= 2 75 00000027 8B1D[84030000] <1> mov ebx, %2 76 <1> %if %0 >= 3 77 0000002D B9[94030000] <1> mov ecx, %3 78 <1> %if %0 = 4 79 00000032 BAFFFFFFFF <1> mov edx, %4 80 <1> %endif 81 <1> %endif 82 <1> %endif 83 00000037 B803000000 <1> mov eax, %1 84 <1> 85 0000003C CD40 <1> int 40h 140 0000003E 0F829F000000 jc read_error ; disk read or memory allocation error 141 ; eax = file size 142 143 ; DIRECT LINEAR FRAME BUFFER ACCESS 144 ;xor ebx, ebx 145 ;mov bh, 6 ; Direct access/map to LFB address 146 ;inc bl ; bl = 01h -> 101h, VESA MODE 101h 147 00000044 66BB0106 mov bx, 601h ; Direct access/map to LFB for VBE video mode 101h 148 ;mov eax, _video ; 1Fh 149 00000048 B81F000000 mov eax, 1Fh ; sys _video ; TRDOS 386 Video functions 150 0000004D CD40 int 40h ; TRDOS 386 system call 151 0000004F 09C0 or eax, eax 152 00000051 7465 jz short lfb_error 153 00000053 A3[88030000] mov [LFB_addr], eax 154 155 ; 19/12/2020 156 00000058 C1E810 shr eax, 16 ; ax = high word of LFB address 157 0000005B E84F010000 call wordtohex 158 00000060 A3[52030000] mov [lfb_addr_str], eax 159 160 00000065 BE[27030000] mov esi, msg_lfb_ok 161 0000006A E885000000 call print_msg 162 163 0000006F 30E4 xor ah, ah 164 ;int 16h ; KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTY 165 ; Return: AH = scan code, AL = character 166 00000071 CD32 int 32h ; TRDOS 386 Keyboard interrupt 167 168 ;xor ecx, ecx 169 170 set_vesa_vbe_mode: 171 00000073 66B8024F mov ax, 4F02h ; vbe function 02h, set video mode 172 ;int 10h ; bios video interrupt 173 00000077 66BB0141 mov bx, 4101h ; vbe mode 101h with LFB 174 0000007B CD31 int 31h ; TRDOS 386 - Video interrupt 175 0000007D 6683F84F cmp ax, 004Fh 176 00000081 753C jne short vbe_error 177 178 00000083 E883000000 call loadbmp 179 180 00000088 30E4 xor ah, ah 181 ;int 16h ; KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTY 182 ; Return: AH = scan code, AL = character 183 0000008A CD32 int 32h ; TRDOS 386 Keyboard interrupt 184 185 0000008C E873000000 call set_text_mode 186 187 ; Write GLEN message 188 189 00000091 BE[78020000] mov esi, msg_glen 190 00000096 E859000000 call print_msg 191 192 cf_terminate: 193 sys _close, [fhandle] ; close file 70 <1> 71 <1> 72 <1> 73 <1> 74 <1> %if %0 >= 2 75 0000009B 8B1D[84030000] <1> mov ebx, %2 76 <1> %if %0 >= 3 77 <1> mov ecx, %3 78 <1> %if %0 = 4 79 <1> mov edx, %4 80 <1> %endif 81 <1> %endif 82 <1> %endif 83 000000A1 B806000000 <1> mov eax, %1 84 <1> 85 000000A6 CD40 <1> int 40h 194 195 terminate: 196 sys _exit ; INT 40h 70 <1> 71 <1> 72 <1> 73 <1> 74 <1> %if %0 >= 2 75 <1> mov ebx, %2 76 <1> %if %0 >= 3 77 <1> mov ecx, %3 78 <1> %if %0 = 4 79 <1> mov edx, %4 80 <1> %endif 81 <1> %endif 82 <1> %endif 83 000000A8 B801000000 <1> mov eax, %1 84 <1> 85 000000AD CD40 <1> int 40h 197 here: 198 000000AF EBFE jmp short here 199 200 _terminate: 201 000000B1 BE[F9010000] mov esi, msg_program 202 000000B6 EB24 jmp short write_and_exit 203 204 lfb_error: 205 000000B8 BE[07030000] mov esi, msg_lfb_error 206 000000BD EB2E jmp short err_close_file 207 208 vbe_error: 209 000000BF BE[E7020000] mov esi, msg_vbe_error 210 000000C4 EB27 jmp short err_close_file 211 212 open_error: 213 000000C6 50 push eax 214 000000C7 BE[AD020000] mov esi, msg_open_error 215 000000CC E823000000 call print_msg ; INT 31h 216 000000D1 58 pop eax 217 000000D2 83F802 cmp eax, 2 218 000000D5 75D1 jne short terminate 219 000000D7 BE[C1020000] mov esi, msg_not_found 220 write_and_exit: 221 000000DC E813000000 call print_msg ; INT 31h 222 000000E1 EBC5 jmp short terminate 223 224 read_error: 225 000000E3 E81C000000 call set_text_mode 226 000000E8 BE[D6020000] mov esi, msg_read_error 227 err_close_file: 228 000000ED E802000000 call print_msg ; INT 31h 229 000000F2 EBA7 jmp short cf_terminate 230 231 print_msg: 232 ;mov ebx, 0Eh ; yellow characters (bl) 233 000000F4 BB0F000000 mov ebx, 0Fh ; white characters 234 ; video page 0 (bh) 235 000000F9 B40E mov ah, 0Eh ; teletype output (write tty) 236 ;mov ah, bl 237 000000FB AC lodsb 238 _1: 239 000000FC CD31 int 31h 240 000000FE AC lodsb 241 000000FF 20C0 and al, al 242 00000101 75F9 jnz short _1 243 _2: 244 00000103 C3 retn 245 246 set_text_mode: 247 00000104 30E4 xor ah, ah 248 00000106 B003 mov al, 3 249 ;int 10h ; al = 03h text mode, int 10 video 250 00000108 CD31 int 31h ; TRDOS 386 - Video interrupt 251 252 0000010A C3 retn 253 254 ;----------------------------------------------------------------- 255 ; subroutine - loadbmp 256 ;----------------------------------------------------------------- 257 258 loadbmp: ; this procedure is for loading in the bitmap 259 260 ; 20/12/2020 261 ;mov ebx, [LFB_addr] ; Linear Frame Buffer base addr 262 263 0000010B BE[CA030000] mov esi, BUFFER+BMPHEAD.size ; BUFFER+54 264 00000110 28C9 sub cl, cl ; 0 ; reading in the palette 265 G1: 266 00000112 88C8 mov al, cl 267 00000114 66BAC803 mov dx, 3C8h 268 ;out dx, al 269 00000118 B401 mov ah, 1 270 0000011A CD34 int 34h 271 0000011C 8A4602 mov al, [esi+RGBQUAD.red] 272 0000011F C0E802 shr al, 2 273 ;mov dx, 3C9h 274 00000122 6642 inc dx 275 ;out dx, al 276 00000124 B401 mov ah, 1 277 00000126 CD34 int 34h 278 00000128 8A4601 mov al, [esi+RGBQUAD.green] 279 0000012B C0E802 shr al, 2 280 ;out dx, al 281 0000012E B401 mov ah, 1 282 00000130 CD34 int 34h 283 ;mov al, [esi+RGBQUAD.blue] 284 00000132 8A06 mov al, [esi] 285 00000134 C0E802 shr al, 2 286 ;out dx, al 287 00000137 B401 mov ah, 1 288 00000139 CD34 int 34h 289 0000013B 83C604 add esi, 4 290 ; 19/12/2020 291 0000013E FEC1 inc cl 292 00000140 75D0 jnz short G1 ; palette read ends 293 294 00000142 66C705[90030000]DF- mov word [Y], 479 ; bottom row 294 0000014A 01 295 0000014B 66C705[8C030000]00- mov word [X], 0 ; column 0 295 00000153 00 296 A1: 297 ; writing a single pixel to the display in SVGA 298 299 ; 19/12/2020 300 ; start address of pixel array is at header ofset 10 301 00000154 8B35[9E030000] mov esi, [BUFFER+BMPHEAD.headersize] 302 0000015A 81C6[94030000] add esi, BUFFER 303 A2: 304 00000160 E82D000000 call putpixel 305 306 00000165 66FF05[8C030000] inc word [X] 307 0000016C 66813D[8C030000]80- cmp word [X], 640 ; end of row ? 307 00000174 02 308 00000175 75E9 jne short A2 309 00000177 66C705[8C030000]00- mov word [X], 0 ; start of row 309 0000017F 00 310 00000180 66FF0D[90030000] dec word [Y] ; next/prev row (from bottom to up/top) 311 00000187 66833D[90030000]FF cmp word [Y], -1 ; row 0 done ? 312 0000018F 75CF jne short A2 ; no 313 314 00000191 C3 retn 315 316 ;----------------------------------------------------------------- 317 ; subroutine - putpixel 318 ;----------------------------------------------------------------- 319 320 putpixel: ; this procedure is for putting a single pixel in LFB 321 322 ; The linear address of the pixel is y*640+x 323 00000192 B880020000 mov eax, 640 324 00000197 F725[90030000] mul dword [Y] ; calculating linear = y*640 325 ; 19/12/2020 326 0000019D 8B1D[88030000] mov ebx, [LFB_addr] 327 000001A3 01C3 add ebx, eax 328 000001A5 031D[8C030000] add ebx, [X] ; now adding x to the expression 329 000001AB AC lodsb 330 331 000001AC 8803 mov [ebx], al ; writing a single pixel 332 ; to the display 333 000001AE C3 retn 334 335 336 ;----------------------------------------------------------------- 337 ; subroutine - wordtohex 338 ;----------------------------------------------------------------- 339 340 ; Convert binary number to hexadecimal string 341 ; 10/05/2015 342 ; dsectpm.s (28/02/2015) 343 ; Retro UNIX 386 v1 - Kernel v0.2.0.6 344 ; 01/12/2014 345 ; 25/11/2014 346 347 ; 19/12/2020 348 wordtohex: 349 ; INPUT -> 350 ; AX = word (binary number) 351 ; OUTPUT -> 352 ; EAX = hexadecimal string 353 ; 354 000001AF 53 push ebx 355 000001B0 31DB xor ebx, ebx 356 000001B2 86E0 xchg ah, al 357 000001B4 6650 push ax 358 000001B6 88E3 mov bl, ah 359 000001B8 C0EB04 shr bl, 4 360 000001BB 8A83[E9010000] mov al, [ebx+hexchrs] 361 000001C1 88E3 mov bl, ah 362 000001C3 80E30F and bl, 0Fh 363 000001C6 8AA3[E9010000] mov ah, [ebx+hexchrs] 364 000001CC C1E010 shl eax, 16 365 000001CF 6658 pop ax 366 000001D1 88C3 mov bl, al 367 000001D3 C0EB04 shr bl, 4 368 000001D6 8A9B[E9010000] mov bl, [ebx+hexchrs] 369 000001DC 86D8 xchg bl, al 370 000001DE 80E30F and bl, 0Fh 371 000001E1 8AA3[E9010000] mov ah, [ebx+hexchrs] 372 000001E7 5B pop ebx 373 000001E8 C3 retn 374 375 ;----------------------------------------------------------------- 376 ; data 377 ;----------------------------------------------------------------- 378 379 ; 19/12/2020 380 hexchrs: 381 000001E9 303132333435363738- db '0123456789ABCDEF' 381 000001F2 39414243444546 382 383 ;----------------------------------------------------------------- 384 ; messages 385 ;----------------------------------------------------------------- 386 387 msg_program: 388 000001F9 0D0A db 0Dh, 0Ah 389 000001FB 4C4F4144424D50312E- db "LOADBMP1.PRG /// TRDOS 386 VESA VBE function test program" 389 00000204 505247202F2F2F2054- 389 0000020D 52444F532033383620- 389 00000216 564553412056424520- 389 0000021F 66756E6374696F6E20- 389 00000228 746573742070726F67- 389 00000231 72616D 390 00000234 0D0A db 0Dh, 0Ah 391 00000236 6279204572646F6761- db "by Erdogan Tan, 20/12/2020", 0Dh, 0Ah 391 0000023F 6E2054616E2C203230- 391 00000248 2F31322F323032300D- 391 00000251 0A 392 00000252 0D0A0D0A db 0Dh, 0Ah, 0Dh, 0Ah 393 00000256 55736167653A206C6F- db "Usage: loadbmp1 " 393 0000025F 6164626D7031203C62- 393 00000268 6D702066696C65206E- 393 00000271 616D653E 394 00000275 0D0A00 db 0Dh, 0Ah, 0 395 msg_glen: 396 00000278 0D0A db 0Dh, 0Ah 397 0000027A 50726F6772616D6D65- db "Programmed by Glen Quinn, BINARY SOFTWARE (1998)" 397 00000283 6420627920476C656E- 397 0000028C 205175696E6E2C2042- 397 00000295 494E41525920534F46- 397 0000029E 545741524520283139- 397 000002A7 393829 398 000002AA 0D0A00 db 0Dh, 0Ah, 0 399 400 msg_open_error: 401 000002AD 0D0A db 0Dh, 0Ah 402 000002AF 7379736F70656E2065- db 'sysopen error !' 402 000002B8 72726F722021 403 000002BE 0D0A00 db 0Dh, 0Ah, 0 404 msg_not_found: 405 000002C1 0D0A db 0Dh, 0Ah 406 000002C3 66696C65206E6F7420- db 'file not found !' 406 000002CC 666F756E642021 407 000002D3 0D0A00 db 0Dh, 0Ah, 0 408 msg_read_error: 409 000002D6 0D0A db 0Dh, 0Ah 410 000002D8 72656164206572726F- db 'read error !' 410 000002E1 722021 411 nextline: 412 000002E4 0D0A00 db 0Dh, 0Ah, 0 413 msg_vbe_error: 414 000002E7 0D0A db 0Dh, 0Ah 415 000002E9 766573612076626520- db 'vesa vbe video mode error !' 415 000002F2 766964656F206D6F64- 415 000002FB 65206572726F722021 416 00000304 0D0A00 db 0Dh, 0Ah, 0 417 msg_lfb_error: 418 00000307 0D0A db 0Dh, 0Ah 419 00000309 6C696E656172206672- db 'linear frame buffer error !' 419 00000312 616D65206275666665- 419 0000031B 72206572726F722021 420 00000324 0D0A00 db 0Dh, 0Ah, 0 421 422 msg_lfb_ok: 423 00000327 0D0A db 0Dh, 0Ah 424 00000329 6C696E656172206672- db 'linear frame buffer ready .. (at address ' 424 00000332 616D65206275666665- 424 0000033B 72207265616479202E- 424 00000344 2E2028617420616464- 424 0000034D 7265737320 425 lfb_addr_str: ; 8 (hex) digits 426 00000352 303030303030303068- db '00000000h)' 426 0000035B 29 427 0000035C 0D0A db 0Dh, 0Ah 428 0000035E 70726573732061206B- db 'press a key to load bmp image ..' 428 00000367 657920746F206C6F61- 428 00000370 6420626D7020696D61- 428 00000379 6765202E2E 429 0000037E 0D0A00 db 0Dh, 0Ah, 0 430 ;bss 431 432 bss_start: 433 434 ABSOLUTE bss_start 435 436 ;----------------------------------------------------------------- 437 ; uninitialized data 438 ;----------------------------------------------------------------- 439 440 00000381 ?????? alignb 4 441 442 ; fhandle is used to store the file pointer 443 444 00000384 ???????? fhandle: resd 1 445 446 ; linear frame buffer address 447 448 00000388 ???????? LFB_addr: resd 1 449 450 ; X and Y is used to fill the screen with pixels 451 452 0000038C ???? X: resw 1 453 0000038E ???? resw 1 ; double word for 32 bit multiplication 454 00000390 ???? Y: resw 1 455 00000392 ???? resw 1 ; double word for 32 bit multiplication 456 457 ;alignb 4 458 459 BUFFER: 460 BMP: