; ****************************************************************************
; runme.s (TRDOS 386, TRDOS v2.0 - sample binary file, 'runme.prg')
; ----------------------------------------------------------------------------
; RUNME.PRG ! TEST program !  TRDOS 386 VGA Functionality test !
;
; 10/07/2016
;
; [ Last Modification: 23/07/2016 ]
;
; Derived from disassembly of 'runme.com' (1/9/1995) intro by gecemavisi bbs.
;
; Assembler: NASM 2.11

; Original code disassembler: IDA Pro Free (MASM syntax)
; 
; (Original -msdos- code has been modifed for TRDOS 386 system calls and
; other protected mode (TRDOS 386) interrupts.)
; ****************************************************************************

; 19/05/2016
; 29/04/2016
; TRDOS 386 system calls (temporary list!)
_ver 	equ 0
_exit 	equ 1
_fork 	equ 2
_read 	equ 3
_write	equ 4
_open	equ 5
_close 	equ 6
_wait 	equ 7
_creat 	equ 8
_link 	equ 9
_unlink	equ 10
_exec	equ 11
_chdir	equ 12
_time 	equ 13
_mkdir 	equ 14
_chmod	equ 15
_chown	equ 16
_break	equ 17
_stat	equ 18
_seek	equ 19
_tell 	equ 20
_mount	equ 21
_umount	equ 22
_setuid	equ 23
_getuid	equ 24
_stime	equ 25
_quit	equ 26	
_intr	equ 27
_fstat	equ 28
_emt 	equ 29
_mdate 	equ 30
_video	equ 31
_audio	equ 32
_ilgins	equ 33
_sleep	equ 34
_msg    equ 35
_geterr equ 36
_rsrvd1	equ 37
_pri	equ 38
_rele 	equ 39

%macro sys 1-4
    ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)	
    ; 03/09/2015	
    ; 13/04/2015
    ; Retro UNIX 386 v1 system call.	
    %if %0 >= 2   
        mov ebx, %2
        %if %0 >= 3    
            mov ecx, %3
            %if %0 = 4
               mov edx, %4   
            %endif
        %endif
    %endif
    mov eax, %1
    ;int 30h
    int 40h ; TRDOS 386 (TRDOS v2.0)	   
%endmacro

; TRDOS 386 (and Retro UNIX 386 v1) system call format:
; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>

; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;;	This file is generated by The Interactive Disassembler (IDA)	   ;;
; ;;	Copyright (c) 2010 by Hex-Rays SA, <support@hex-rays.com>	   ;;
; ;;			 Licensed to: Freeware version			   ;;
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; File Name   :	C:\Documents and Settings\Erdoðan Tan\Desktop\RUNME.COM
; Format      :	MS-DOS COM-file
; Base Address:	1000h Range: 10100h-10398h Loaded length: 298h

; NOTE: Assembly source code of RUNME.COM (by IDA, in MASM syntax)
; has been modified to NASM syntax (for 386 protected mode & for TRDOS 386)
; by Erdogan Tan. (10/07/2016)

[BITS 32] ; We need 32-bit intructions for protected mode

[ORG 0] 

start: 

call	sub_10321
;mov	edi, 3A3h ; _end = 398h (runme.com)
mov     edi, _end + 11 ; (runme.prg)
mov	cl, 0C8h

loc_10108:
call	sub_10183
mov	[edi], dx
mov	[edi+4], ah
add	edi, 5
loop	loc_10108

mov     esi, prg_msg
call	print_msg

xor	ax, ax
int	32h

xor	eax, eax
xor	ebx, ebx

; DIRECT VGA MEMOY ACCESS
;xor	ebx, ebx
mov	bh, 5 ; Direct access/map to VGA memory (0A0000h)
;mov	eax, _video ; 1Fh
mov	al, 1Fh ; sys _video ; TRDOS 386 Video functions
int	40h   ; TRDOS 386 system call

; eax = 0A0000h
and	eax, eax
jz      terminate ; error (eax = 0)

; *************************

xor 	ah, ah


; ah = 0
mov	al, 13h ; set video mode to 13h 
;int	10h		; - VIDEO -
int	31h  ; TRDOS 386 - VIDEO Interrupt
;
mov	ax, 1124h ; set (load) 8x16 VGA font
mov	bl, 1	; 14 rows
;int	10h  ; - VIDEO - TEXT-MODE CHARACTER GENERATOR FUNCTIONS
int	31h  ; TRDOS 386 - VIDEO Interrupt

loc_10125:
mov	dx, 3DAh
loc_10128:	; Video	status bits
;in	al, dx		
; TRDOS 386 - IOCTL Interrupt (for ring 3)
mov	ah, 0 ; in (byte)
; al = data byte
; dx = port number
int	34h ; TRDOS 386 - IOCTL 
test	al, 8	; bit 3 : 1 = vertical sync pulse is occurring.
jz	short loc_10128
;mov	edi, 3A3h
mov     edi, _end + 11 ; (runme.prg)
mov	esi, 0A0000h
mov	cx, 0C8h

loc_10135:
;movzx	ebx, word [edi]
mov	bx, [edi]
cmp	byte [ebx+esi], 22h
je	short loc_10143
mov	al, [edi+4]
mov	[ebx+esi], al

loc_10143:
;movzx	eax, word [edi+2]
;sub	ebx, eax
mov	ax, [edi+2]
sub	bx, ax
jnb	short loc_10151
;add	ebx, 140h
add	bx, 140h
call	sub_10183

loc_10151:
mov	[edi], bx
mov	ah, [ebx+esi]
mov	[edi+4], ah
or	ah, ah
jnz	short loc_10164
shl	al, 1
add	al, 0Eh
mov	[ebx+esi], al

loc_10164:
add	edi, 5
add	esi, 140h
loop	loc_10135
call	sub_101AC
call	sub_1027A
mov	ah, 1	; check keyboard buffer
;int	16h		; KEYBOARD - CHECK BUFFER, DO NOT CLEAR
			; Return: ZF clear if character	in buffer
			; AH = scan code, AL = character
			; ZF set if no character in buffer
int	32h	; TRDOS 386 - KEYBOARD Interrupt
jz	short loc_10125
mov	ah, 0 ; read char from keyboard buffer
;int	16h		; KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTY
			; Return: AH = scan code, AL = character
int	32h	; TRDOS 386 - KEYBOARD Interrupt
mov	ax, 3	; set mode (to 80x25 color, text)	
;int	10h		; - VIDEO - SET	VIDEO MODE
			; AL = mode
int	32h	; TRDOS 386 - KEYBOARD Interrupt

terminate:
	sys 	_exit   ; INT 40h
here:
	jmp	short here

sub_10183:
mov	ax, 5B9Ch
rol	ax, 3
add	ax, 7
mov	[sub_10183+1], ax
loc_1018F:
add	ax, 35B9h
add	word [loc_1018F+1], 0A0A5h
ror	word [loc_1018F+1], 7
xor	dx, dx
mov	bp, 140h
div	bp
and	ax, 7
inc	ax
mov	[edi+2], ax
retn

sub_101AC:
;inc	byte [ds:78Bh]
inc	byte [_end+11+1000]
;and	byte [ds:78Bh], 3
and	byte [_end+11+1000], 3
jnz	short locret_101DF
;mov	si, [word_101E0]
mov	esi, [word_101E0]
lodsb
or	al, al
jnz	short loc_101C4
;mov	si, 220h
mov	esi, loc_220
lodsb

loc_101C4:
cmp	al, 20h
jnb	short loc_101D4
mov	ah, al
lodsb
mov	dx, ax
mov	ah, 2	; set cursor position
xor	bh, bh
;int	10h	; - VIDEO - SET	CURSOR POSITION
		; DH,DL	= row, column (0,0 = upper left)
		; BH = page number
int	31h  ; TRDOS 386 - VIDEO Interrupt
lodsb
loc_101D4:
;mov	[word_101E0], si
mov	[word_101E0], esi
mov	bx, 22h
mov	ah, 0Eh	; write tty
;int	10h	; - VIDEO - WRITE CHARACTER AND	ADVANCE	CURSOR (TTY WRITE)
		; AL = character, BH = display page (alpha modes)
		; BL = foreground color	(graphics modes)
int	31h  ; TRDOS 386 - VIDEO Interrupt
locret_101DF:
retn

;word_101E0: dw 1E2h
word_101E0: dd loc_1E2
loc_1E2:
db    4
db  0Fh
db  20h
db  20h
db  20h
db  47h	; G
db 0EEh	; ¯
db  43h	; C
db 0EEh	; ¯
db  20h
db  20h
db  20h
db    5
db  0Fh
db  20h
db  20h
db  4Dh	; M
db  92h	; Æ
db  56h	; V
db 0ADh	; ¡
db  53h	; S
db 0ADh	; ¡
db  20h
db  20h
db    6
db  0Ch
db  20h
db  20h
db  20h
db  20h
db  43h	; C
db  41h	; A
db  4Ch	; L
db  4Ch	; L
db  20h
db  4Eh	; N
db  4Fh	; O
db  57h	; W
db  20h
db  20h
db  20h
db  20h
db    7
db  0Ch
db  2Bh	; +
db  39h	; 9
db  30h	; 0
db  2Dh	; -
db  32h	; 2
db  31h	; 1
db  36h	; 6
db  2Dh	; -
db  33h	; 3
db  31h	; 1
db  35h	; 5
db  2Dh	; -
db  32h	; 2
db  32h	; 2
db  33h	; 3
db  33h	; 3
db  20h
db  20h
loc_220:
db    4
db  13h
db  45h	; E
db  43h	; C
db  45h	; E
db  20h
db  20h
db  20h
db    4
db  13h
db  65h	; e
db  43h	; C
db  65h	; e
db  20h
db    4
db  13h
db 0EEh	; ¯
db  43h	; C
db 0EEh	; ¯
db  20h
db  20h
db  20h
db    0
loc_237:
db 0E0h	; Ó
db  20h
db  21h	; !
db    0
db 0C3h	; +
db 0B6h	; Â
db 0F5h	; §
db 0F6h	; ÷
db    3
db    3
db    2
loc_242:
db  40h	; @
db    0
db    0
db    0
db 0FAh	; ·
db 0D9h	; -
db  37h	; 7
db    4
db    0
db    0
db    0
loc_24D:
db  80h ; Ç
db  84h ; ä
loc_24F:
db 0FCh ; ³
db    8
db  99h ; Ö
db  21h ; !
db 0A5h ; Ñ
db  1Eh
db  99h ; Ö
db  1Bh
db 0A3h ; ú
db  18h
db 0A5h ; Ñ
db  15h
db  99h ; Ö
db  21h ; !
db 0A5h ; Ñ
db  28h ; (
db  99h ; Ö
db  2Fh ; /
db  7Dh ; }
db 0FEh ; ¦
loc_263:
db 0FCh ; ³
db    4
db  80h ; Ç
db 0C0h ; L
db  7Dh ; }
db 0FCh ; ³
db  10h
db  8Dh ; ý
db  90h ; É
db  7Dh ; }
db 0FEh ; ¦
loc_26E:
;db  4Fh ; O
;db    2
dd  loc_24F
;db  4Fh ; O
;db    2
dd  loc_24F
;db  63h ; c
;db    2
dd  loc_263	
loc_274:
;db  4Fh ; O
;db    2
dd  loc_24F    		
;db  4Dh ; M
;db    2
dd  loc_24D 	
;db  63h ; c
;db    2
dd  loc_263

sub_1027A:
xor     byte [byte_10393], 1
jnz	short locret_1028C
xor	edi, edi

loc_10283:
call	sub_1028D
inc	edi
;cmp	edi, 3
cmp	di, 3
jne	short loc_10283
locret_1028C:
retn

sub_1028D:
mov	ebx, edi
;shl	bx, 1
shl	bx, 2
;mov	si, [bx+274h]
mov	esi, [ebx+loc_274]
;dec	byte [di+394h]
dec	byte [edi+loc_394]
jnz	short locret_1028C
;mov	byte [di+394h], 8
mov	byte [edi+loc_394], 8

loc_102A0:
lodsb
cmp	al, 7Dh
jne	short loc_102B1
;dec	byte [edi+3A0h]
dec	byte [edi+_end+8] ; 3A3h = _end + 11
jz	short loc_102A0
;mov	si, [bx+39Ah]
;movzx	esi, word [ebx+_end+2] ; 39Ah = _end + 11 - 9
mov	si, [ebx+_end+2]
jmp	short loc_102A0

loc_102B1:
cmp	al, 0FCh
jne	short loc_102C0
lodsb
;mov	[di+3A0h], al
mov	byte [edi+_end+8], al
;mov	[bx+39Ah], si
mov	[ebx+_end+2], si
jmp	short loc_102A0

loc_102C0:
cmp	al, 0FEh
jne	short loc_102CA
;mov	si, [bx+26Eh]
mov	esi, [ebx+loc_26E]
jmp	short loc_102A0

loc_102CA:
push	ax
lodsb
rol	al, 1
shr	al, 1
jnb	short loc_102D8
;mov	[di+394h], al
mov	[edi+loc_394], al
jmp	short loc_102DF

loc_102D8:
mov	ah, al
mov	al, 40h
call	sub_10358

loc_102DF:
pop	ax
and	al, 7Fh
jz	short loc_10318
push	ax
;mov	ah, [di+397h]
mov	ah, [edi+loc_397]
mov	al, 0B0h
call	sub_10358
pop	ax
dec	al
xor	ah, ah
mov	bl, 0Ch
div	bl
;movzx	ebx, ax
mov	bx, ax
shr	bx, 7
shl	ax, 0Ah
;or	ax, [bx+370h]
or	ax, [ebx+loc_370]
;mov	[di+397h], ah
mov	[edi+loc_397], ah
or	ah, 20h
mov	bl, al
mov	al, 0B0h
call	sub_10358
mov	al, 0A0h
mov	ah, bl
call	sub_10358

loc_10318:
;shl	di, 1
shl	di, 2
;mov	[di+274h], si
mov	[edi+loc_274], esi
;shr	di, 1
shr	di, 2
retn

sub_10321:
mov	ax, 2001h
call	sub_1035A
mov	ax, 8
call	sub_1035A
mov	ax, 0C0BDh
call	sub_1035A
xor	edi, edi
;mov	si, 237h
mov	esi, loc_237
call	sub_10345
mov	byte [esi+3], 8
call	sub_10345
;mov	si, 242h
mov	esi, loc_242

sub_10345:
xor	ebx, ebx
loc_10347:
;mov	al, [bx+388h]
mov	al, [ebx+loc_388]
mov	ah, [ebx+esi]
call	sub_10358
inc	ebx
cmp	ebx, 0Bh
jb	short loc_10347
inc	edi
retn

sub_10358:
add	ax, di

sub_1035A:
push	ax
mov	dx, 388h
;out	dx, al
; TRDOS 386 - IOCTL Interrupt (for ring 3)
mov	ah, 1 ; out (byte)
; al = data byte
; dx = port number
int	34h ; TRDOS 386 - IOCTL
;in	al, dx
;in	al, dx
;in	al, dx
;in	al, dx
;out	dx, al
; TRDOS 386 - IOCTL Interrupt (for ring 3)
mov	ah, 0 ; in (byte)
; al = data byte
; dx = port number
int	34h ; TRDOS 386 - IOCTL 
pop	ax
inc	dl
mov	al, ah
;out	dx, al
; TRDOS 386 - IOCTL Interrupt (for ring 3)
mov	ah, 1 ; out (byte)
; al = data byte
; dx = port number
int	34h ; TRDOS 386 - IOCTL
dec	dl
mov	ecx, 14h
loc_1036C:
;in	al, dx
; TRDOS 386 - IOCTL Interrupt (for ring 3)
mov	ah, 0 ; in (byte)
; al = data byte
; dx = port number
int	34h ; TRDOS 386 - IOCTL
loop	loc_1036C
retn

print_msg:
	mov	bx, 7
        mov     ah, 0Eh
pmsg_loop:
	lodsb
	and	al, al
	jz	short pmsg_ok
	int	31h	; TRDOS 386 video interrupt
	jmp	short pmsg_loop	
pmsg_ok:
	mov	ah, 10h ; Getchar
	int	32h	; TRDOS 386 keyboard interrupt
	retn

loc_370:
db  57h	; W
db    1
db  6Bh	; k
db    1
db  81h	; ü
db    1
db  98h	; Ý
db    1
db 0B0h	; -
db    1
db 0CAh	; ¦
db    1
db 0E5h	; Õ
db    1
db    2
db    2
db  20h
db    2
db  41h	; A
db    2
db  63h	; c
db    2
db  87h	; ç
db    2
loc_388:
db  20h
db  23h	; #
db  40h	; @
db  43h	; C
db  60h	; `
db  63h	; c
db  80h	; Ç
db  83h	; â
db 0E0h	; Ó
db 0E3h	; Ò
db 0C0h	; L
byte_10393: db 0
loc_394:
db    1
db    1
db    1
loc_397:
db  1Ah

db 	0
prg_msg:
db	'ERDOGAN TAN - TRDOS 386 - RUNME.PRG'
db	0Dh, 0Ah
db	'23/07/2016'
db 	0
dw	_end
db	0 
_end:
