     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) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
    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 <res 00000004>          fhandle: resd 1
   347                                  
   348 00000234 <res 00000018>          DTA:	 resb 24
   349                                  
   350                                  Name_Buffer:	
   351                                  
   352                                  IMAGE_BUFFER equ 10000h	 
