1 ; **************************************************************************** 2 ; loadpcx2.s (TRDOS 386, TRDOS v2.0 - sample binary file, 'loadpcx2.prg') 3 ; ---------------------------------------------------------------------------- 4 ; LOADPCX2.PRG ! 'sysfff' and 'sysfnf', 'sysopen', 'sysread' 5 ; and VGA TEST program for TRDOS 386 ! 6 ; 7 ; 14/10/2016 8 ; 9 ; [ Last Modification: 16/10/2016 ] 10 ; 11 ; Derived from: MICROPCX.ASM (1994, Lord Debugger. Poznan, Poland.) 12 ; 13 ; Note: This program displays 320x200x256 pcx files only. 14 ; **************************************************************************** 15 ; Previous Version: loadpcx.s (14/10/2016) 16 17 ; 16/10/2016 18 ; 29/04/2016 19 ; TRDOS 386 system calls (temporary list!) 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 _creat equ 8 29 _link equ 9 30 _unlink equ 10 31 _exec equ 11 32 _chdir equ 12 33 _time equ 13 34 _mkdir equ 14 35 _chmod equ 15 36 _chown equ 16 37 _break equ 17 38 _stat equ 18 39 _seek equ 19 40 _tell equ 20 41 _mount equ 21 42 _umount equ 22 43 _setuid equ 23 44 _getuid equ 24 45 _stime equ 25 46 _quit equ 26 47 _intr equ 27 48 _fstat equ 28 49 _emt equ 29 50 _mdate 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 _rsvd1 equ 37 58 _pri equ 38 59 _rele equ 39 60 _fff equ 40 61 _fnf equ 41 62 63 %macro sys 1-4 64 ; 29/04/2016 - TRDOS 386 (TRDOS v2.0) 65 ; 03/09/2015 66 ; 13/04/2015 67 ; Retro UNIX 386 v1 system call. 68 %if %0 >= 2 69 mov ebx, %2 70 %if %0 >= 3 71 mov ecx, %3 72 %if %0 = 4 73 mov edx, %4 74 %endif 75 %endif 76 %endif 77 mov eax, %1 78 ;int 30h 79 int 40h ; TRDOS 386 (TRDOS v2.0) 80 %endmacro 81 82 ; TRDOS 386 (and Retro UNIX 386 v1) system call format: 83 ; sys systemcall (eax) , , 84 85 [BITS 32] ; We need 32-bit intructions for protected mode 86 87 [ORG 0] 88 89 START_CODE: 90 00000000 89E6 mov esi, esp 91 00000002 AD lodsd 92 00000003 83F802 cmp eax, 2 ; two arguments (program file name & text file name) 93 00000006 0F8254010000 jb terminate ; nothing top do 94 0000000C AD lodsd ; program file name address 95 0000000D AD lodsd ; text file name address 96 ; EAX = arg2 ; file name address 97 98 ; EBX = EAX = file name or path address 99 ; CL = file attributes (archive = 20h, read only = 01h) 100 ; (21h = Archived & Read Only files are included) 101 ; CH = 0 = basic parameters (24 bytes) 102 ; EDX = DTA = buffer address (24 bytes for basic parameters) 103 ; EAX = _fff = 'Find First File' system call for TRDOS 386 104 105 ; Find First File 106 sys _fff, eax, 0021h, DTA 106 <1> 106 <1> 106 <1> 106 <1> 106 <1> %if %0 >= 2 106 0000000E 89C3 <1> mov ebx, %2 106 <1> %if %0 >= 3 106 00000010 B921000000 <1> mov ecx, %3 106 <1> %if %0 = 4 106 00000015 BA[34020000] <1> mov edx, %4 106 <1> %endif 106 <1> %endif 106 <1> %endif 106 0000001A B828000000 <1> mov eax, %1 106 <1> 106 0000001F CD40 <1> int 40h 107 00000021 0F8234010000 jc _terminate ; terminate if there is 108 ; file not found error or another error 109 _0: 110 ; check file attributes 111 00000027 F605[34020000]1E test byte [DTA], 1Eh ; 10h = directory, 08h = volume label 112 ; 04h = system, 02h = hidden 113 0000002E 740B jz short _2 ; atributes are proper 114 ; but we need to check ".PCX" extension 115 _1: 116 ; Find Next File 117 sys _fnf ; if the first file is not proper file 117 <1> 117 <1> 117 <1> 117 <1> 117 <1> %if %0 >= 2 117 <1> mov ebx, %2 117 <1> %if %0 >= 3 117 <1> mov ecx, %3 117 <1> %if %0 = 4 117 <1> mov edx, %4 117 <1> %endif 117 <1> %endif 117 <1> %endif 117 00000030 B829000000 <1> mov eax, %1 117 <1> 117 00000035 CD40 <1> int 40h 118 ; check for next file 119 00000037 7240 jc short _show_pcx 120 00000039 EBEC jmp short _0 121 _2: 122 0000003B BE[3F020000] mov esi, DTA+11 ; 2nd char of file name 123 ; (ASCIIZ, capitalized file name) 124 _3: 125 00000040 AC lodsb 126 00000041 3C20 cmp al, 20h 127 00000043 76EB jna short _1 128 129 00000045 3C2E cmp al, '.' 130 00000047 75F7 jne short _3 131 132 00000049 AC lodsb 133 0000004A 3C50 cmp al, 'P' 134 0000004C 75E2 jne short _1 135 0000004E 66AD lodsw 136 00000050 3C43 cmp al, 'C' 137 00000052 75DC jne short _1 138 00000054 80FC58 cmp ah, 'X' 139 00000057 75D7 jne short _1 140 141 _4: ; OK ! We have 1 PCX file at least, to show 142 ; DTA: Offset 143 ; 0 - file attributes byte 144 ; 1 - ambiguous file name wildcards are used sign 145 ; 2 - time stamp of file 146 ; 4 - date stamp off file 147 ; 6 - file size in bytes 148 ; 10 - file name (ASCIIZ) 149 ; (in 8.3 dos filename format as capitalized) 150 151 ; Move/Copy File Name (from DTA) to Name_Buffer 152 00000059 8B3D[B0010000] mov edi, [Buffer_Pos] 153 0000005F BE[3E020000] mov esi, DTA+10 154 00000064 B90D000000 mov ecx, 13 155 00000069 F3A4 rep movsb 156 0000006B 893D[B0010000] mov [Buffer_Pos], edi 157 158 00000071 FE05[AF010000] inc byte [Max_Files] 159 00000077 75B7 jnz short _1 160 161 _show_pcx: 162 00000079 BB[4C020000] mov ebx, Name_Buffer 163 0000007E 891D[B0010000] mov [Buffer_Pos], ebx 164 165 ; DIRECT VGA MEMORY ACCESS 166 167 ;xor ebx, ebx 168 ;mov bh, 5 ; Direct access/map to VGA memory (0A0000h) 169 ;mov eax, _video ; 1Fh 170 ;mov al, 1Fh ; sys _video ; TRDOS 386 Video functions 171 ;int 40h ; TRDOS 386 system call 172 ;jc terminate 173 174 ; BH = 5 -> Direct access/map to VGA memory 175 ; BL = 0 -> 320 pixels width or default VGA screen width 176 177 sys _video, 0500h ; sys macro formats INT 40h system calls 177 <1> 177 <1> 177 <1> 177 <1> 177 <1> %if %0 >= 2 177 00000084 BB00050000 <1> mov ebx, %2 177 <1> %if %0 >= 3 177 <1> mov ecx, %3 177 <1> %if %0 = 4 177 <1> mov edx, %4 177 <1> %endif 177 <1> %endif 177 <1> %endif 177 00000089 B81F000000 <1> mov eax, %1 177 <1> 177 0000008E CD40 <1> int 40h 178 00000090 0F82C5000000 jc _terminate ; in fact, an error is not possible 179 ; if multi tasking is not enabled -default- 180 ; (VGA memory -0A0000h- will be free to use 181 ; if multi tasking is off!) 182 ; (If TRDOS 386 kernel has not got a memory 183 ; allocation error, as bug!?) 184 ; Note: As default, TRDOS 386 kernel 185 ; does not enable multi tasking feature 186 ; (Also, it is not programmed yet, 187 ; for October 2016). 188 set_vga_mode: 189 00000096 66B81300 mov ax, 13h ; function 00h, mode 13h 190 ;int 10h ; bios video interrupt 191 0000009A CD31 int 31h ; TRDOS 386 - Video interrupt 192 ; Note: This is not a system call -INT 40h-, 193 ; this is a direct video service like as 194 ; INT 10h ROMBIOS service in real mode. 195 196 open_file: 197 0000009C 8B35[B0010000] mov esi, [Buffer_Pos] 198 199 sys _open, esi, 1800h ; open for reading 199 <1> 199 <1> 199 <1> 199 <1> 199 <1> %if %0 >= 2 199 000000A2 89F3 <1> mov ebx, %2 199 <1> %if %0 >= 3 199 000000A4 B900180000 <1> mov ecx, %3 199 <1> %if %0 = 4 199 <1> mov edx, %4 199 <1> %endif 199 <1> %endif 199 <1> %endif 199 000000A9 B805000000 <1> mov eax, %1 199 <1> 199 000000AE CD40 <1> int 40h 200 000000B0 0F82B3000000 jc open_error 201 202 000000B6 A3[30020000] mov [fhandle], eax ; file handle/index number 203 204 read_file: 205 sys _read, eax, IMAGE_BUFFER, 0FFFFFFFFh ; read all bytes 205 <1> 205 <1> 205 <1> 205 <1> 205 <1> %if %0 >= 2 205 000000BB 89C3 <1> mov ebx, %2 205 <1> %if %0 >= 3 205 000000BD B900000100 <1> mov ecx, %3 205 <1> %if %0 = 4 205 000000C2 BAFFFFFFFF <1> mov edx, %4 205 <1> %endif 205 <1> %endif 205 <1> %endif 205 000000C7 B803000000 <1> mov eax, %1 205 <1> 205 000000CC CD40 <1> int 40h 206 000000CE 0F82A6000000 jc read_error ; disk read or memory allocation error 207 208 000000D4 31C9 xor ecx, ecx 209 000000D6 89C7 mov edi, eax ; file size (read bytes) 210 211 close_file: 212 sys _close, [fhandle] ; close file 212 <1> 212 <1> 212 <1> 212 <1> 212 <1> %if %0 >= 2 212 000000D8 8B1D[30020000] <1> mov ebx, %2 212 <1> %if %0 >= 3 212 <1> mov ecx, %3 212 <1> %if %0 = 4 212 <1> mov edx, %4 212 <1> %endif 212 <1> %endif 212 <1> %endif 212 000000DE B806000000 <1> mov eax, %1 212 <1> 212 000000E3 CD40 <1> int 40h 213 214 000000E5 81C703000100 add edi, IMAGE_BUFFER+3 215 000000EB 6683E7FC and di, 0FFFCh ; dword alignment 216 000000EF 89FD mov ebp, edi 217 000000F1 89EA mov edx, ebp 218 000000F3 81C201FA0000 add edx, 64001 219 000000F9 BE80000100 mov esi, IMAGE_BUFFER + 128 ; PCX header + data 220 ldlp1: 221 000000FE AC lodsb 222 000000FF 88C4 mov ah, al 223 00000101 80E4C0 and ah, 0C0h 224 00000104 80FCC0 cmp ah, 0C0h 225 00000107 7509 jne short single 226 00000109 243F and al, 3Fh 227 0000010B 88C1 mov cl, al 228 0000010D AC lodsb 229 0000010E F3AA ldlp2: rep stosb 230 00000110 EB01 jmp short cnt 231 single: 232 00000112 AA stosb 233 cnt: 234 00000113 39D7 cmp edi, edx ; 64001 ; end of pixel data 235 00000115 72E7 jb short ldlp1 236 237 00000117 89F2 mov edx, esi 238 00000119 89F7 mov edi, esi 239 0000011B 66B90003 mov cx, 768 240 set256: 241 0000011F AC lodsb 242 00000120 C0E802 shr al, 2 243 00000123 AA stosb 244 00000124 E2F9 loop set256 245 00000126 66B81210 mov ax, 1012h ; set palette registers 246 0000012A 31DB xor ebx, ebx 247 0000012C 66B90001 mov cx, 256 248 ;int 10h 249 00000130 CD31 int 31h ; TRDOS 386 Video interrupt 250 251 ; move_image_to_VGA_address: 252 00000132 89EE mov esi, ebp 253 00000134 66B9803E mov cx, 16000 254 00000138 BF00000A00 mov edi, 0A0000h 255 0000013D F3A5 rep movsd 256 257 0000013F 30E4 xor ah, ah 258 ;int 16h ; KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTY 259 ; Return: AH = scan code, AL = character 260 00000141 CD32 int 32h ; TRDOS 386 Keyboard interrupt 261 ; Note: This is not a system call -INT 40h-, 262 ; this is a direct video service like as 263 ; INT 16h ROMBIOS service in real mode. 264 265 00000143 3C1B cmp al, 1Bh ; ESC key 266 00000145 7414 je short _terminate 267 268 00000147 FE0D[AF010000] dec byte [Max_Files] 269 0000014D 740C jz short _terminate 270 271 0000014F 8305[B0010000]0D add dword [Buffer_Pos], 13 272 273 00000156 E941FFFFFF jmp open_file ; loop (we use same code for the next file) 274 275 _terminate: 276 0000015B E848000000 call set_text_mode 277 terminate: 278 sys _exit ; INT 40h 278 <1> 278 <1> 278 <1> 278 <1> 278 <1> %if %0 >= 2 278 <1> mov ebx, %2 278 <1> %if %0 >= 3 278 <1> mov ecx, %3 278 <1> %if %0 = 4 278 <1> mov edx, %4 278 <1> %endif 278 <1> %endif 278 <1> %endif 278 00000160 B801000000 <1> mov eax, %1 278 <1> 278 00000165 CD40 <1> int 40h 279 here: 280 00000167 EBFE jmp short here 281 282 open_error: 283 00000169 E83A000000 call set_text_mode 284 0000016E BE[0B020000] mov esi, msg_open_error 285 00000173 E820000000 call print_msg ; INT 31h 286 00000178 EBE6 jmp short terminate 287 288 read_error: 289 sys _close, [fhandle] ; close file 289 <1> 289 <1> 289 <1> 289 <1> 289 <1> %if %0 >= 2 289 0000017A 8B1D[30020000] <1> mov ebx, %2 289 <1> %if %0 >= 3 289 <1> mov ecx, %3 289 <1> %if %0 = 4 289 <1> mov edx, %4 289 <1> %endif 289 <1> %endif 289 <1> %endif 289 00000180 B806000000 <1> mov eax, %1 289 <1> 289 00000185 CD40 <1> int 40h 290 00000187 E81C000000 call set_text_mode 291 0000018C BE[1F020000] mov esi, msg_read_error 292 00000191 E802000000 call print_msg ; INT 31h 293 00000196 EBC8 jmp short terminate 294 295 print_msg: 296 00000198 BB0E000000 mov ebx, 0Eh ; yellow characters (bl) 297 ; video page 0 (bh) 298 ;mov ah, 0Eh ; teletype output (write tty) 299 0000019D 88DC mov ah, bl 300 0000019F AC lodsb 301 _p_nextchar: 302 000001A0 CD31 int 31h 303 000001A2 AC lodsb 304 000001A3 20C0 and al, al 305 000001A5 75F9 jnz short _p_nextchar 306 000001A7 C3 retn 307 308 set_text_mode: 309 000001A8 30E4 xor ah, ah 310 000001AA B003 mov al, 3 311 ;int 10h ; al = 03h text mode, int 10h video 312 000001AC CD31 int 31h ; TRDOS 386 - Video interrupt 313 000001AE C3 retn 314 315 Max_Files: 316 000001AF 00 db 0 317 318 Buffer_Pos: 319 000001B0 [4C020000] dd Name_Buffer 320 321 ;----------------------------------------------------------------- 322 ; messages 323 ;----------------------------------------------------------------- 324 325 msg_program: 326 000001B4 0D0A db 0Dh, 0Ah 327 000001B6 4C4F4144504358322E- db "LOADPCX2.PRG /// TRDOS 386 sysfff, sysfnf test program" 327 000001BF 505247202F2F2F2054- 327 000001C8 52444F532033383620- 327 000001D1 7379736666662C2073- 327 000001DA 7973666E6620746573- 327 000001E3 742070726F6772616D 328 000001EC 0D0A db 0Dh, 0Ah 329 000001EE 6279204572646F6761- db "by Erdogan Tan, 16/10/2016", 0Dh, 0Ah, 0 329 000001F7 6E2054616E2C203136- 329 00000200 2F31302F323031360D- 329 00000209 0A00 330 msg_open_error: 331 0000020B 0D0A db 0Dh, 0Ah 332 0000020D 7379736F70656E2065- db 'sysopen error !' 332 00000216 72726F722021 333 0000021C 0D0A00 db 0Dh, 0Ah, 0 334 msg_read_error: 335 0000021F 0D0A db 0Dh, 0Ah 336 00000221 72656164206572726F- db 'read error !' 336 0000022A 722021 337 nextline: 338 0000022D 0D0A00 db 0Dh, 0Ah, 0 339 340 bss: 341 342 ABSOLUTE bss 343 344 alignb 4 345 346 00000230 fhandle: resd 1 347 348 00000234 DTA: resb 24 349 350 Name_Buffer: 351 352 IMAGE_BUFFER equ 10000h