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