[FORMAT "WCOFF"]
[BITS 32]
[INSTRSET "i486p"]

[FILE "naskfunc.nas"]		; ソースファイル名

		global		_io_hlt,_io_cli,_io_sti,_io_stihlt
		global		_io_out8,_io_out16,_io_out32
		global		_io_in8,_io_in16,_io_in32
		global		_io_load_eflags,_io_store_eflags
		global		_load_cr0,_store_cr0
		global		_load_gdtr,_load_idtr,_load_tr
		global		_farjmp,_farcall
		global		_asm_nos_api,_start_app,_asm_end_app
;		extern		_nos_api
;		global		_asm_inthandler0c,_asm_inthandler0d
;		global		_asm_inthandler21,_asm_inthandler23,_asm_inthandler24
		global		_asm_inthandler20,_asm_inthandler21
		global		_asm_inthandler27,_asm_inthandler2c
;		extern		_inthandler0c,_inthandler0d
;		extern		_inthandler20,_inthandler21,_inthandler23,_inthandler24
		extern		_inthandler20,_inthandler21
		extern		_inthandler27,_inthandler2c
		
		; FPU関係
		global		_clts, _fnsave, _frstor, _asm_inthandler07
		extern		_inthandler07

[SECTION .text]
_io_hlt:		; void _io_hlt();
		hlt
		ret
_io_cli:		; void _io_cli();
		cli
		ret
_io_sti:		; void _io_sti();
		sti
		ret
_io_stihlt:		; void _io_stihlt();
		sti
		hlt
		ret
_io_in8:		; char io_in8(int port);
		mov		edx,[esp+4]		; port
		mov		eax,0
		in		al,dx
		ret
_io_in16:		; short io_in16(int port);
		mov		edx,[esp+4]		; port
		mov		eax,0
		in		ax,dx
		ret
_io_in32:		; int io_in32(int port);
		mov		edx,[esp+4]		; port
		in		eax,dx
		ret
_io_out8:		; void io_out8(int port, char data);
		mov		edx,[esp+4]		; port
		mov		al,[esp+8]		; data
		out		dx,al
		ret
_io_out16:		; void io_out16(int port, short data);
		mov		edx,[esp+4]		; port
		mov		ax,[esp+8]		; data
		out		dx,ax
		ret
_io_out32:		; void io_out32(int port, int data);
		mov		edx,[esp+4]		; port
		mov		eax,[esp+8]		; data
		out		dx,eax
		ret
_io_load_eflags:	; int io_load_eflags();
		pushfd
		pop		eax
		ret
_io_store_eflags:	; void io_store_eflags(int eflags);
		mov		eax,[esp+4]
		push	eax
		popfd
		ret

_load_cr0:	; int load_cr0()
		mov		eax,cr0
		ret
_store_cr0:		; void store_cr0()
		mov		eax,[esp+4]
		mov		cr0,eax
		ret

_load_gdtr:		; void load_gdtr(unsigned int limit, unsigned int base);
		mov		ax,[esp+4]		; limit
		mov		[esp+6],ax
		lgdt	[esp+6]
		ret
_load_idtr:		; void load_idtr(unsigned int limit, unsigned int base);
		mov		ax,[esp+4]		; limit
		mov		[esp+6],ax
		lidt	[esp+6]
		ret
_load_tr:		; void load_tr(unsigned int tr);
		ltr		[esp+4]
		ret
_farjmp:		; void farjmp(unsigned int eip, unsigned int cs);
		jmp		far [esp+4]		; eip, cs
		ret
_farcall:		; void farcall(unsigned int eip, unsigned int cs);
		call	far [esp+4]		; eip, cs
		ret

#if 0
_asm_nos_api:	; void asm_nos_api();
		sti
		push	ds
		push	es
		pushad					; 保存
		pushad					; nos_apiに渡すデータ
		mov		ax,ss
		mov		ds,ax			; OS用のセグメントをds,esにも入れる
		mov		es,ax
		call	_nos_api
		cmp		eax,0			; eaxが0でなければアプリ終了する
		jne		_asm_end_app
		add		esp,32
		popad
		pop		es
		pop		ds
		iretd
_asm_end_app:
; eaxはtss.esp0の番地
		mov		esp,[eax]
		mov		dword [eax+4],0
		popad
		ret

_start_app:		; void start_app(int eip, int cs, int esp, int ds, int *tss_esp0);
		pushad			; 全て保存
		mov		eax,[esp+36]	; eip for app
		mov		ecx,[esp+40]	; cs for app
		mov		edx,[esp+44]	; esp for app
		mov		ebx,[esp+48]	; ds/ss for app
		mov		ebp,[esp+52]	; addr of tss_esp0
		mov		[ebp  ],esp		; esp for OS
		mov		[ebp+4],ss		; ss for OS
		mov		es,bx
		mov		ds,bx
		mov		fs,bx
		mov		gs,bx
; スタック調整
		or		ecx,3
		or		ebx,3
		push	ebx
		push	edx
		push	ecx
		push	eax
		retf
; アプリが終了してもここにはこない
;_asm_inthandler0c:
		sti
		push	es
		push	ds
		pushad
		mov		eax,esp
		push	eax
		mov		ax,ss
		mov		ds,ax
		mov		es,ax
		call	_inthandler0c
		cmp		eax,0
		jne		_asm_end_app
		pop		eax
		popad
		pop		ds
		pop		es
		add		esp,4
		iretd

_asm_inthandler0d:
		sti
		push	es
		push	ds
		pushad
		mov		eax,esp
		push	eax
		mov		ax,ss
		mov		ds,ax
		mov		es,ax
		call	_inthandler0d
		cmp		eax,0
		jne		_asm_end_app
		pop		eax
		popad
		pop		ds
		pop		es
		add		esp,4
		iretd

#endif

_asm_inthandler20:
		push	es
		push	ds
		pushad
		mov		eax,esp
		push	eax
		mov		ax,ss
		mov		ds,ax
		mov		es,ax
		call	_inthandler20
		pop		eax
		popad
		pop		ds
		pop		es
		iretd


_asm_inthandler21:
		push	es
		push	ds
		pushad
		mov		eax,esp
		push	eax
		mov		ax,ss
		mov		ds,ax
		mov		es,ax
		call	_inthandler21
		pop		eax
		popad
		pop		ds
		pop		es
		iretd

#if 0

_asm_inthandler23:
		push	es
		push	ds
		pushad
		mov		eax,esp
		push	eax
		mov		ax,ss
		mov		ds,ax
		mov		es,ax
		call	_inthandler23
		pop		eax
		popad
		pop		ds
		pop		es
		iretd

_asm_inthandler24:
		push	es
		push	ds
		pushad
		mov		eax,esp
		push	eax
		mov		ax,ss
		mov		ds,ax
		mov		es,ax
		call	_inthandler24
		pop		eax
		popad
		pop		ds
		pop		es
		iretd

#endif

_asm_inthandler27:
		push    es
		push    ds
		pushad
		mov     eax,esp
		push    eax
		mov     ax,ss
		mov     ds,ax
		mov     es,ax
		call    _inthandler27
		pop     eax
		popad
		pop     ds
		pop     es
		iretd

_asm_inthandler2c:
		push	es
		push	ds
		pushad
		mov		eax,esp
		push	eax
		mov		ax,ss
		mov		ds,ax
		mov		es,ax
		call	_inthandler2c
		pop		eax
		popad
		pop		ds
		pop		es
		iretd

#if 0

; FPU関係
_clts:          ; void clts(void);
		clts
		ret

_fnsave:		; void fnsave(int *addr);
		mov 	eax,[esp+4] 	; addr
		fnsave	[eax]
		ret

_frstor:		; void frstor(int *addr);
		mov 	eax,[esp+4] 	; addr
		frstor	[eax]
		ret

_asm_inthandler07:
		sti
		push	es
		push	ds
		pushad
		mov 	eax,esp
		push	eax
		mov 	ax,ss
		mov 	ds,ax
		mov 	es,ax
		call	_inthandler07
		cmp 	eax,0
		jne 	_asm_end_app
		pop 	eax
		popad
		pop 	ds
		pop 	es
		iretd					; int07では esp += 4; はいらない
#endif
