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