
; flat assembler interface for Solar OS
; Copyright (c) 1999-2007, Tomasz Grysztar.
; All rights reserved.

; Solar OS port by pelaillo

format	PE GUI
include 'solar.inc'

BASE_WIDTH	= 680
BASE_HEIGHT = 480

color_comments	= 0008000h
color_strings	= 0573380h
color_digits	= 0808080h
color_keywords	= 09999FFh
color_background	= 0C0DCC0h
color_grip	= 0FEAFE0h

font_pitch_v	= 16
font_pitch_h	= 8
interline_spacing	= 4
tab_size		= 6
top_margin		= 26
left_margin		= 8 + font_pitch_h

struct TEXT_LINE
	contents	dd 0
	next		dd 0
	previous	dd 0
	status	dd 0
	size		dd 0
	reserved1	dd 0
	reserved2	dd 0
	reserved3	dd 0
ends

struct SELECTION
	row	dd 0
	col	dd 0
	col_e	dd 0
	char	dd 0
	line	dd 0
ends

struct RECT
	top	dd 0
	bottom	dd 0
	left	dd 0
	right	dd 0
ends

section '.code' code readable executable

start:
	mov	[input_file],sample_file
	mov	[memory_setting],0
	mov	[passes_limit],100
	mov	[output_file],0

	call	Read_File
	mov	[caret.row],1
	mov	[caret.col],1
	mov	[caret.char],0
	mov	[caret_x],left_margin
	mov	[caret_y],30

	call	API_Window_Create,[desk_crt],64,8,BASE_WIDTH,BASE_HEIGHT,FLAG_WND_NONE,WND_TYPE_TOP
	mov	[main_win],eax
	call	API_Window_Set_Caption,eax,_logo
	call	API_Window_Set_Callback,[main_win],OS_CALL_AFTER,Main_Callback
;	call	CaretMoveVertical,0
	xor	eax,eax
	ret

proc Main_Callback wnd_handle,wnd_action,wnd_param1,wnd_param2
	local .app_addr	dd 0
	local .x1	dd 0
	local .y1	dd 0
	local .x2	dd 0
	local .y2	dd 0
	local .dx1	dd 0
	local .dy1	dd 0
	push	ebx esi
	call	API_Window_Get_Rect,[wnd_handle]
	mov	[.x1],eax
	mov	[.x2],ebx
	mov	[.y1],ecx
	mov	[.y2],edx

	mov	[caret_x],eax
	mov	[caret_y],ecx

	sub	ebx,eax
	mov	[.dx1],ebx
	sub	edx,ecx
	mov	[.dy1],edx
	sub	ebx,font_pitch_h
	mov	[end_pos],ebx
	
	mov	eax,[wnd_action]
	cmp	eax,ACT_PAINT_CHILD
	je	.act_paint_child
	cmp	eax,ACT_LEFT_UP_CHILD
	je	.act_left_up_child
	cmp	eax,ACT_KEY_CHILD
	je	.act_key_child
	cmp	eax,ACT_CLOSE_CHILD
	jne	.default
  .act_close_child:
	call	API_Memory_Release,[source_tree],1
	call	API_Memory_Release,[source_file],1
	jmp	.done
  
  .act_paint_child:
	call	RenderEditor,[wnd_handle]
	jmp	.done

  .act_left_up_child:
	jmp	.done

  .act_key_child:
	mov	eax,[wnd_param1]	
	cmp	eax,KEY_EX_ARROW_LEFT
	je	.key_left
	cmp	eax,KEY_EX_ARROW_RIGHT
	je	.key_right
	cmp	eax,KEY_EX_ARROW_UP
	je	.key_up
	cmp	eax,KEY_EX_ARROW_DOWN
	je	.key_down
	cmp	eax,KEY_EX_HOME
	je	.key_home
	cmp	eax,KEY_EX_END
	je	.key_end
	cmp	eax,KEY_EX_F4
	je	.key_F4
	cmp	eax,KEY_EX_F5
	je	.key_F5
	jne	.default
  .key_F4:
	call	RenderEditor,[wnd_handle]
	jmp	.done
  .key_F5:
	call	Compile
	jmp	.done
  .key_end:
	jmp	.done
  .key_left:
	call	CaretMoveHorizontal,-1
	jmp	.done
  .key_right:
	call	CaretMoveHorizontal,1
	jmp	.done
  .key_up:
	call	CaretMoveVertical,-1
	jmp	.done
  .key_down:
	call	CaretMoveVertical,1
	jmp	.done
  .key_home:
	jmp	.done

  .default:
  .done:
	xor	eax,eax
 	pop	esi ebx
	ret
endp

proc Read_File
	local	.file_handle dd 0
	push	esi

	call	API_Memory_Allocate,1
	mov	[source_tree],esi
	call	API_Memory_Allocate,1
	mov	[source_file],esi
	call	API_File_Open,sample_file
	mov	[.file_handle],eax
	call	API_File_Get_Size,eax
	mov	[source_file_size],eax
	call	API_File_Read,[.file_handle],eax,[source_file],0,0
	call	API_File_Close,[.file_handle]

	mov	esi,[source_file]
	mov	ecx,[source_file_size]
	mov	edx,[source_tree]
  .get_line:
	inc	[row_count]
	mov	[edx+TEXT_LINE.contents],esi
  .store_buffer:
	cmp	byte [esi],0
	je	.end_of_text
	cmp	byte [esi],0Dh
	je	.eol
	cmp	byte [esi],0Ah
	je	.eol
	inc	esi
	loop	.store_buffer
	jmp	.end_of_text
  .eol:
	mov	eax,esi
	sub	eax,[edx+TEXT_LINE.contents]
	mov	[edx+TEXT_LINE.size],eax
  .not_next:
	inc	esi
	cmp	byte [esi],0Ah
	jne	.next_line
	loop	.not_next
	jmp	.end_of_text
  .next_line:
	lea	eax,[edx+sizeof.TEXT_LINE]
	mov	[edx+TEXT_LINE.next],eax
	mov	edx,eax
	jmp	.get_line
  .end_of_text:
	mov	eax,esi
	sub	eax,[edx+TEXT_LINE.contents]
	mov	[edx+TEXT_LINE.size],eax
	lea	eax,[edx+sizeof.TEXT_LINE]
	mov	[edx+TEXT_LINE.next],eax
	mov	edx,eax
  .done:
	call	Dwtoa_Hex32,[source_tree],buffer
	call	API_Debug_Out_String,0,buffer,0
	pop	esi
	ret
endp

proc Alert_Box wnd_handle,msg,title
	local	box_handle dd 0
	call	API_Window_Create,[wnd_handle],80,80,120,80,FLAG_WND_MINI,WND_TYPE_TOP
	mov	[box_handle],eax
	call	API_Window_Set_Caption,eax,[title]
	call	API_Window_Set_Callback,[box_handle],OS_CALL_AFTER,Alert_Box_Callback
	call	API_Text_Draw,[box_handle],5,5,[msg],color_keywords
	ret
endp

proc Alert_Box_Callback wnd_handle,wnd_action,wnd_param1,wnd_param2
	mov	eax,[wnd_action]
	cmp	eax,ACT_PAINT_CHILD
	je	.act_paint_child
	cmp	eax,ACT_KEY_CHILD
	je	.act_key_child
	cmp	eax,ACT_CLOSE_CHILD
	jne	.default
  .act_paint_child:
	jmp	.done
  .act_key_child:
	mov	eax,[wnd_param1]	
	cmp	eax,KEY_ASCII_ESC
	je	.done
	jne	.default
  .default:
  .done:
	xor	eax,eax
	ret
endp

proc Compile
	;call	Alert_Box,[main_win],_copyright,_logo
	call	API_Debug_Out_String,0,_logo,0
	call	init_memory
	call	preprocessor
jmp	.done
	call	parser
	call	assembler
	call	formatter

  .done:
	ret
endp

proc Debug_Out_Regs
	call	Dwtoa_Hex32,eax,buffer
	call	API_Debug_Out_String,0,buffer,0
	call	Dwtoa_Hex32,ebx,buffer
	call	API_Debug_Out_String,0,buffer,0
	call	Dwtoa_Hex32,ecx,buffer
	call	API_Debug_Out_String,0,buffer,0
	call	Dwtoa_Hex32,edx,buffer
	call	API_Debug_Out_String,0,buffer,0
	call	Dwtoa_Hex32,esi,buffer
	call	API_Debug_Out_String,0,buffer,0
	call	Dwtoa_Hex32,edi,buffer
	call	API_Debug_Out_String,0,buffer,0
	ret
endp

proc GetTextLine,row
	mov	eax,[row]
	dec	eax
	imul	eax,sizeof.TEXT_LINE
	add	eax,buffer
	ret
endp

proc RenderEditor,hwnd
	local .rc RECT
	push	esi edi ebx
	mov	[.rc.top],top_margin
	mov	[.rc.right],BASE_WIDTH
	mov	[.rc.bottom],BASE_HEIGHT
	mov	[.rc.left],left_margin
	sub	[.rc.right],left_margin
	;call	API_Draw_Rect_Fill,[hwnd],0,[.rc.top],left_margin,[.rc.bottom],color_grip
	;call	API_Draw_Rect_Fill,[hwnd],[.rc.left],[.rc.top],[.rc.right],[.rc.bottom],color_background
	mov	esi,[source_tree]
	mov	edi,top_margin
	xor	ecx,ecx
  .get_line:
	cmp	[esi+TEXT_LINE.next],0
	je	.end_of_text
	inc	ecx
	cmp	ecx,[caret.row]
	jne	.render_line
	mov	[.rc.top],edi
	mov	[.rc.bottom],edi
	add	[.rc.bottom],font_pitch_v
	;call	API_Draw_Rect_Fill,[hwnd],[.rc.left],[.rc.top],[.rc.right],[.rc.bottom],color_grip

  .render_line:
	cmp	[esi+TEXT_LINE.size],0
	je	.render_done
	call	RenderLine,[hwnd],edi,esi
  .render_done:
	add	edi,font_pitch_v
	add	esi,sizeof.TEXT_LINE
	jmp	.get_line
  .end_of_text:
	mov	dword [status],'Ln: '
	call	Dwtoa_Dec,[caret.row],status+4
	add	eax,4
	call	API_Draw_Chars,[hwnd],left_margin,BASE_HEIGHT-font_pitch_v-4,status,eax,color_strings
	mov	dword [status],'Ch: '
	call	Dwtoa_Dec,[caret.char],status+4
	add	eax,4
	call	API_Draw_Chars,[hwnd],left_margin+8*font_pitch_h,BASE_HEIGHT-font_pitch_v-4,status,eax,color_strings
	mov	dword [status],'Cl: '
	call	Dwtoa_Dec,[caret.col],status+4
	add	eax,4
	call	API_Draw_Chars,[hwnd],left_margin+16*font_pitch_h,BASE_HEIGHT-font_pitch_v-4,status,eax,color_strings
	mov	dword [status],'Ce: '
	call	Dwtoa_Dec,[caret.col_e],status+4
	add	eax,4
	call	API_Draw_Chars,[hwnd],left_margin+24*font_pitch_h,BASE_HEIGHT-font_pitch_v-4,status,eax,color_strings
	;call	CaretMoveVertical,0
	xor	eax,eax
	pop	ebx edi esi
	ret
endp

proc CaretMoveHorizontal,move
	push	esi edi ebx ecx
	push	[caret.col_e]
	pop	[caret.col]
	mov	eax,[move]
	add	[caret.char],eax
  .get_row:
	call	GetTextLine,[caret.row]
	mov	esi,eax
	mov	eax,1
	xor	edi,edi
	mov	ecx,[esi+TEXT_LINE.size]
	cmp	[caret.char],-1
	je	.on_left
	cmp	ecx,[caret.char]
	jb	.on_right
	mov	ebx,tab_size
	mov	esi,[esi+TEXT_LINE.contents]
	jmp	.seek_line

  .on_left:
	cmp	[caret.row],1
	je	.on_top_left
	dec	[caret.row]
	call	GetTextLine,[caret.row]
	mov	ecx,[eax+TEXT_LINE.size]
	mov	[caret.char],ecx
	jmp	.get_row
  .on_top_left:
	mov	[caret.char],0
	jmp	.exit

  .on_right:
	mov	eax,[caret.row]
	cmp	eax,[row_count]
	jae	.on_bottom_right
	inc	[caret.row]
	mov	[caret.char],0
	jmp	.get_row
  .on_bottom_right:
	mov	[caret.char],ecx
	jmp	.exit

  .seek_line:
	cmp	edi,[caret.char]
	je	.done
  .find_tab:
	cmp	byte [esi+edi],09h
	jne	.no_tab
  .tab:
	cmp	ebx,eax
	jae	.tab_done
	add	ebx,tab_size
  .tab_done:
	mov	eax,ebx
  .no_tab:
	inc	eax
	inc	edi
	loop	.seek_line

  .done:
	mov	[caret.char],edi
	mov	[caret.col],eax
	mov	[caret.col_e],eax
	dec	eax
	imul	eax,font_pitch_h
	add	eax,left_margin
	mov	ebx,[caret.row]
	dec	ebx
	imul	ebx,font_pitch_v
	add	ebx,top_margin
	call	SetCaretPos,eax,ebx
  .exit:
	pop	ecx ebx edi esi
	ret
endp

proc CaretMoveVertical,move
	local	.prev_tab dd ?
	push	esi edi ebx ecx
int3
	mov	eax,[caret.row]
	add	eax,[move]
	cmp	eax,[row_count]
	ja	.on_bottom
	cmp	eax,1
	jb	.on_top
	jmp	.get_row
  .on_top:
	mov	[caret.row],1
	jmp	.exit
  .on_bottom:
	mov	eax,[row_count]
	mov	[caret.row],eax
	jmp	.exit
  .get_row:
	mov	[caret.row],eax
	call	GetTextLine,eax
	mov	esi,eax
	mov	eax,1
	xor	edi,edi
	mov	ecx,[esi+TEXT_LINE.size]
	or	ecx,ecx
	je	.done
	mov	ebx,tab_size
	mov	esi,[esi+TEXT_LINE.contents]
  .seek_line:
	cmp	eax,[caret.col]
	je	.done
	jb	.find_tab
	mov	eax,ebx
	sub	eax,[.prev_tab]
	inc	eax
	shr	eax,1
	add	eax,[caret.col]
	cmp	eax,ebx
	ja	.next_tab
	mov	eax,[.prev_tab]
	dec	edi
	jmp	.done
  .next_tab:
	mov	eax,ebx
	inc	eax
	jmp	.done

  .find_tab:
	cmp	byte [esi+edi],09h
	jne	.no_tab
  .tab:
	cmp	ebx,eax
	jae	.tab_done
	add	ebx,tab_size
  .tab_done:
	mov	[.prev_tab],eax
	mov	eax,ebx
  .no_tab:
	inc	eax
	inc	edi
	loop	.seek_line

  .done:
	mov	[caret.char],edi
	mov	[caret.col_e],eax
	dec	eax
	imul	eax,font_pitch_h
	add	eax,left_margin
	mov	ebx,[caret.row]
	dec	ebx
	imul	ebx,font_pitch_v
	add	ebx,top_margin
	call	SetCaretPos,eax,ebx
  .exit:
	pop	ecx ebx edi esi
	ret
endp

proc RenderLine,hdc,y_msg,line
	push	esi edi ebx ecx
	mov	esi,[line]
	mov	ecx,[esi+TEXT_LINE.size]
	mov	esi,[esi+TEXT_LINE.contents]
	xor	edx,edx
	mov	ebx,left_margin

;	call	API_Debug_Out_String,0,dbg_msg0,0
;	call	Dwtoa_Hex32,ecx,buffer
;	call	API_Debug_Out_String,0,buffer,0
;
;jmp	.done

  .paint_line:
	cmp	byte [esi+edx],09h
	je	.tab
	cmp	byte [esi+edx],';'
	je	.comment
	cmp	byte [esi+edx],"'"
	je	.string1
	cmp	byte [esi+edx],'"'
	je	.string2
	cmp	byte [esi+edx],'9'
	ja	.no_digit
	cmp	byte [esi+edx],'0'
	jae	.digit
  .no_digit:
	inc	edx
  .continue:
	loop	.paint_line
	call	API_Draw_Chars,[hdc],ebx,[y_msg],esi,edx,color_keywords
	jmp	.done
  .tab:
	call	API_Draw_Chars,[hdc],ebx,[y_msg],esi,edx,color_keywords
  .next_tab:
	add	ebx,tab_size*font_pitch_h
	cmp	eax,ebx
	jae	.next_tab
	add	esi,edx
	xor	edx,edx
	inc	esi
	jmp	.continue
  .comment:
	call	API_Draw_Chars,[hdc],ebx,[y_msg],esi,edx,color_keywords
	mov	ebx,eax
	add	esi,edx
	call	API_Draw_Chars,[hdc],ebx,[y_msg],esi,ecx,color_comments
	jmp	.done
  .string1:
	inc	edx
	call	API_Draw_Chars,[hdc],ebx,[y_msg],esi,edx,color_keywords
	mov	ebx,eax
	add	esi,edx
	mov	edx,1
  .skip_string1:
	cmp	byte [esi+edx],"'"
	je	.close_strings
	inc	edx
	loop	.skip_string1
	jmp	.continue
  .string2:
	inc	edx
	call	API_Draw_Chars,[hdc],ebx,[y_msg],esi,edx,color_keywords
	mov	ebx,eax
	add	esi,edx
	mov	edx,1
  .skip_string2:
	cmp	byte [esi+edx],'"'
	je	.close_strings
	inc	edx
	loop	.skip_string2
	jmp	.continue
  .close_strings:
	call	API_Draw_Chars,[hdc],ebx,[y_msg],esi,edx,color_strings
	mov	ebx,eax
	add	esi,edx
	call	API_Draw_Chars,[hdc],ebx,[y_msg],esi,1,color_keywords
	mov	ebx,eax
	xor	edx,edx
	inc	esi
	sub	ecx,2
	jmp	.continue

  .digit:
	call	API_Draw_Chars,[hdc],ebx,[y_msg],esi,edx,color_keywords
	mov	ebx,eax
	add	esi,edx
	xor	edx,edx
	xor	eax,eax ; look for hex digits
  .complete_digit:
	inc	edx
	cmp	byte [esi+edx],'0'
	jb	.digit_complete
	cmp	byte [esi+edx],'9'
	ja	.verify_hex1
	jmp	.is_digit
  .verify_hex1:
	inc	eax
	cmp	byte [esi+edx],'A'
	jb	.digit_complete
	cmp	byte [esi+edx],'F'
	ja	.verify_hex2
	jmp	.is_digit
  .verify_hex2:
	inc	eax
	cmp	byte [esi+edx],'a'
	jb	.digit_complete
	cmp	byte [esi+edx],'f'
	ja	.digit_complete
  .is_digit:
	loop	.complete_digit
  .digit_complete:
	or	eax,eax ; if hex digits are present
	je	.no_hex
	cmp	byte [esi+edx],'h'
	je	.hex
	cmp	byte [esi+edx],'H'
	je	.hex
	push	color_keywords
	jmp	.digits_ready
  .no_hex:
	push	color_digits
	jmp	.digits_ready
  .hex:
	inc	edx
	dec	ecx
	push	color_digits
  .digits_ready:
	call	API_Draw_Chars,[hdc],ebx,[y_msg],esi,edx ;,color is in stack
	mov	ebx,eax
	add	esi,edx
	xor	edx,edx
	or	ecx,ecx
	jne	.continue
	
  .done:
	pop	ecx ebx edi esi
	ret
endp

; function to replace when implemented on solar OS API
proc API_Draw_Chars,hdc,x_msg,y_msg,lp_string,size,color
	push	ecx edi esi
	mov	esi,[lp_string]
	mov	edi,buffer
	mov	ecx,[size]
	or	ecx,ecx
	je	.done
  .fill:
	lodsb
	stosb
	loop	.fill
	xor	al,al
	stosb
	call	API_Text_Draw,[hdc],[x_msg],[y_msg],buffer,[color]
  .done:
	mov	eax,[size]
	imul	eax,font_pitch_h
	add	eax,[x_msg]
	pop	esi edi ecx
	ret
endp

proc SetCaretPos,x,y
	push	eax ecx
	mov	eax,[caret_x]
	add	[x],eax
	mov	ecx,[caret_y]
	add	[y],ecx
	call	API_Draw_Caret,[x],[y],2,font_pitch_v
	pop	ecx eax
	ret
endp

; Here starts the fasm code unmodified:
macro skip_fasm_code {
	mov	esi,_logo
	call	display_string

	call	get_params
	jc	information

	call	init_memory

	mov	esi,_memory_prefix
	call	display_string
	mov	eax,[memory_end]
	sub	eax,[memory_start]
	add	eax,[additional_memory_end]
	sub	eax,[additional_memory]
	shr	eax,10
	call	display_number
	mov	esi,_memory_suffix
	call	display_string

	call	API_Tick_Count
	mov	[start_time],eax

	call	preprocessor
	call	parser
	call	assembler
	call	formatter

	call	display_user_messages
	movzx	eax,[current_pass]
	inc	eax
	call	display_number
	mov	esi,_passes_suffix
	call	display_string
	call	API_Tick_Count
	sub	eax,[start_time]
	xor	edx,edx
	mov	ebx,100
	div	ebx
	or	eax,eax
	jz	display_bytes_count
	xor	edx,edx
	mov	ebx,10
	div	ebx
	push	edx
	call	display_number
	mov	dl,'.'
	call	display_character
	pop	eax
	call	display_number
	mov	esi,_seconds_suffix
	call	display_string
      display_bytes_count:
	mov	eax,[written_size]
	call	display_number
	mov	esi,_bytes_suffix
	call	display_string
	xor	al,al
	jmp	exit_program

information:
	mov	esi,_usage
	call	display_string
	mov	al,1
	jmp	exit_program

get_params:
	mov	[memory_setting],0
	mov	[passes_limit],100
	call	API_Command_Line
	mov	esi,eax
	mov	edi,params
    find_command_start:
	lodsb
	cmp	al,20h
	je	find_command_start
	cmp	al,22h
	je	skip_quoted_name
    skip_name:
	lodsb
	cmp	al,20h
	je	find_param
	or	al,al
	jz	all_params
	jmp	skip_name
    skip_quoted_name:
	lodsb
	cmp	al,22h
	je	find_param
	or	al,al
	jz	all_params
	jmp	skip_quoted_name
    find_param:
	lodsb
	cmp	al,20h
	je	find_param
	cmp	al,22h
	je	string_param
	cmp	al,'-'
	je	option_param
	cmp	al,0Dh
	je	all_params
	or	al,al
	jz	all_params
	inc	edi
	mov	ebx,edi
    copy_param:
	stosb
	lodsb
	cmp	al,20h
	je	param_end
	cmp	al,0Dh
	je	param_end
	or	al,al
	jz	param_end
	jmp	copy_param
    string_param:
	inc	edi
	mov	ebx,edi
    copy_string_param:
	lodsb
	cmp	al,22h
	je	string_param_end
	cmp	al,0Dh
	je	param_end
	or	al,al
	jz	param_end
	stosb
	jmp	copy_string_param
    option_param:
	lodsb
	cmp	al,'m'
	je	memory_option
	cmp	al,'M'
	je	memory_option
	cmp	al,'p'
	je	passes_option
	cmp	al,'P'
	je	passes_option
    bad_params:
	stc
	ret
    get_option_value:
	xor	eax,eax
	mov	edx,eax
    get_option_digit:
	lodsb
	cmp	al,20h
	je	option_value_ok
	cmp	al,0Dh
	je	option_value_ok
	or	al,al
	jz	option_value_ok
	sub	al,30h
	jc	invalid_option_value
	cmp	al,9
	ja	invalid_option_value
	imul	edx,10
	jo	invalid_option_value
	add	edx,eax
	jc	invalid_option_value
	jmp	get_option_digit
    option_value_ok:
	dec	esi
	clc
	ret
    invalid_option_value:
	stc
	ret
    memory_option:
	lodsb
	cmp	al,20h
	je	memory_option
	cmp	al,0Dh
	je	bad_params
	or	al,al
	jz	bad_params
	dec	esi
	call	get_option_value
	or	edx,edx
	jz	bad_params
	cmp	edx,1 shl (32-10)
	jae	bad_params
	mov	[memory_setting],edx
	jmp	find_param
    passes_option:
	lodsb
	cmp	al,20h
	je	passes_option
	cmp	al,0Dh
	je	bad_params
	or	al,al
	jz	bad_params
	dec	esi
	call	get_option_value
	or	edx,edx
	jz	bad_params
	cmp	edx,10000h
	ja	bad_params
	mov	[passes_limit],dx
	jmp	find_param
    param_end:
	dec	esi
    string_param_end:
	xor	al,al
	stosb
	mov	eax,edi
	sub	eax,ebx
	mov	[ebx-1],al
	jmp	find_param
    all_params:
	xor	al,al
	stosb
	cmp	[params],0
	je	bad_params
	lea	eax,[params+1]
	mov	[input_file],eax
	mov	[output_file],0
	movzx	ecx,byte [eax-1]
	add	eax,ecx
	cmp	byte [eax],0
	je	params_ok
	inc	eax
	mov	[output_file],eax
	movzx	ecx,byte [eax-1]
	add	eax,ecx
	cmp	byte [eax],0
	jne	bad_params
    params_ok:
	clc
	ret
}

;--- jump table: completely useless but Solar needs it

API_Exit_Process:
	jmp		[j_API_Exit_Process]
API_File_Get_Size:
	jmp		[j_API_File_Get_Size]
API_File_Open:
	jmp		[j_API_File_Open]
API_File_Read:
	jmp		[j_API_File_Read]
API_File_Write:
	jmp		[j_API_File_Write]
API_File_Close:
	jmp		[j_API_File_Close]
API_File_Seek:
	jmp		[j_API_File_Seek]
API_Command_Line:
	jmp		[j_API_Command_Line]
API_Environment_Variable:
	jmp		[j_API_Environment_Variable]
API_Handle_Std:
	jmp		[j_API_Handle_Std]
API_Memory_Allocate:
	jmp		[j_API_Memory_Allocate]
API_Memory_Release:
	jmp		[j_API_Memory_Release]
API_Tick_Count:
	jmp		[j_API_Tick_Count]
API_System_Time:
	jmp		[j_API_System_Time]
API_Memory_Status:
	jmp		[j_API_Memory_Status]

API_Debug_Out_String:
	jmp		[j_API_Debug_Out_String]
API_Text_Draw:
	jmp		[j_API_Text_Draw]
API_Draw_Caret:
	jmp		[j_API_Draw_Caret]
;API_Draw_Chars1:
;	jmp		[j_API_Draw_Chars]
API_Draw_Rect:
	jmp		[j_API_Draw_Rect]
API_Draw_Rect_Fill:
	jmp		[j_API_Draw_Rect_Fill]
API_Window_Create:
	jmp		[j_API_Window_Create]
API_Window_Set_Callback:
	jmp		[j_API_Window_Set_Callback]
API_Window_Set_Caption:
	jmp		[j_API_Window_Set_Caption]
API_Window_Get_Rect:
	jmp		[j_API_Window_Get_Rect]
Dwtoa_Dec:
	jmp		[j_Dwtoa_Dec]
Dwtoa_Hex32:
	jmp		[j_Dwtoa_Hex32]
;.

include 'system.inc'

include '..\version.inc'

sample_file	db 'C:\SAMPLE.ASM',0,0,0

dbg_msg0	db 'Here we goooo...',0
dbg_msg1	db 'Exiting preprocessor...',0
dbg_msg2	db 'Gonna Read from:',0
dbg_msg3	db 'Converting line data...',0
dbg_msg4	db 'Exiting preprocess line...',0

_copyright	db 'Copyright (c) 1999-2006, Tomasz Grysztar',0Dh,0Ah,0

_logo	db 'flat assembler  version ',VERSION_STRING,0
_usage db 0Dh,0Ah
       db 'usage: fasm <source> [output]',0Dh,0Ah
       db 'optional settings:',0Dh,0Ah
       db ' -m <limit>  set the limit in kilobytes for the memory available to assembler',0Dh,0Ah
       db ' -p <limit>  set the maximum allowed number of passes',0D,0Ah
       db 0
_memory_prefix db '  (',0
_memory_suffix db ' kilobytes memory)',0Dh,0Ah,0
_passes_suffix db ' passes, ',0
_seconds_suffix db ' seconds, ',0
_bytes_suffix db ' bytes.',0Dh,0Ah,0

include '..\errors.inc'
include '..\expressi.inc'
include '..\preproce.inc'
include '..\parser.inc'
include '..\assemble.inc'
include '..\formats.inc'
include '..\x86_64.inc'
include '..\tables.inc'

align 4

include '..\variable.inc'

source_file_size	dd 0
source_file dd 0
source_tree	dd 0
row_count	dd 0

main_win	dd 0
desk_crt	dd 0
caret_x	dd ?
caret_y	dd ?
end_pos	dd ?
filepos	dd ?

caret	SELECTION

memory_setting dd ?
start_time dd ?

status rb 100h
params rb 1000h
buffer rb 4000h

stack 10000h

section '.idata' import data readable writeable

  library solar,'solar.dll'

  import solar,\
	j_API_Debug_Out_String,'API_Debug_Out_String',\
	j_API_Draw_Caret,'Draw_Carret_H',\
\;	j_API_Draw_Chars,'API_Draw_Chars',\
	j_API_Draw_Rect,'API_Draw_Rect',\
	j_API_Draw_Rect_Fill,'API_Draw_Rect_Fill',\
	j_API_Exit_Process,'API_Debug_Out_String',\
	j_API_File_Get_Size,'API_File_Get_Size',\
	j_API_File_Open,'API_File_Open',\
	j_API_File_Read,'API_File_Read',\
	j_API_File_Write,'API_Debug_Out_String',\
	j_API_File_Close,'API_File_Close',\
	j_API_File_Seek,'API_Debug_Out_String',\
	j_API_Command_Line,'API_Debug_Out_String',\
	j_API_Environment_Variable,'API_Debug_Out_String',\
	j_API_Handle_Std,'API_Debug_Out_String',\
	j_API_Memory_Allocate,'API_Memory_Allocate',\
	j_API_Memory_Release,'API_Memory_Release',\
	j_API_Tick_Count,'API_Debug_Out_String',\
	j_API_System_Time,'API_Debug_Out_String',\
	j_API_Memory_Status,'API_Debug_Out_String',\
	j_API_Text_Draw,'API_Text_Draw',\
	j_API_Window_Create,'API_Window_Create',\
	j_API_Window_Set_Callback,'API_Window_Set_Callback',\
	j_API_Window_Get_Rect,'API_Window_Get_Rect',\
	j_API_Window_Set_Caption,'API_Window_Set_Caption',\
	j_Dwtoa_Dec,'Dwtoa_Dec',\
	j_Dwtoa_Hex32,'Dwtoa_Hex32'

section '.reloc' fixups data readable discardable
