⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 klib386.s

📁 MINIX2.0操作系统源码 MINIX2.0操作系统源码
💻 S
📖 第 1 页 / 共 2 页
字号:
	mov	ecx, PR_ARGS_B+4+4(esp)
	rep
	insb
	pop	es
	pop	edi
	ret


!*===========================================================================*
!*				port_write				     *
!*===========================================================================*
! PUBLIC void port_write(port_t port, phys_bytes source, unsigned bytcount);
! Transfer data from memory to (hard disk controller) port.

PW_ARGS	=	4 + 4 + 4		! 4 + 4 + 4
!		es edi eip		port src len

	.align	16
_port_write:
	cld
	push	esi
	push	ds
	mov	ecx, FLAT_DS_SELECTOR
	mov	ds, cx
	mov	edx, PW_ARGS(esp)	! port to write to
	mov	esi, PW_ARGS+4(esp)	! source addr
	mov	ecx, PW_ARGS+4+4(esp)	! byte count
	shr	ecx, 1			! word count
	rep				! (hardware cannot handle dwords)
    o16	outs				! write everything
	pop	ds
	pop	esi
	ret


!*===========================================================================*
!*				port_write_byte				     *
!*===========================================================================*
! PUBLIC void port_write_byte(port_t port, phys_bytes source,
!						unsigned bytcount);
! Transfer data from memory to port.

PW_ARGS_B =	4 + 4 + 4		! 4 + 4 + 4
!		es edi eip		port src len

_port_write_byte:
	cld
	push	esi
	push	ds
	mov	ecx, FLAT_DS_SELECTOR
	mov	ds, cx
	mov	edx, PW_ARGS_B(esp)
	mov	esi, PW_ARGS_B+4(esp)
	mov	ecx, PW_ARGS_B+4+4(esp)
	rep
	outsb
	pop	ds
	pop	esi
	ret


!*===========================================================================*
!*				lock					     *
!*===========================================================================*
! PUBLIC void lock();
! Disable CPU interrupts.

	.align	16
_lock:
	cli				! disable interrupts
	ret


!*===========================================================================*
!*				unlock					     *
!*===========================================================================*
! PUBLIC void unlock();
! Enable CPU interrupts.

	.align	16
_unlock:
	sti
	ret


!*==========================================================================*
!*				enable_irq				    *
!*==========================================================================*/
! PUBLIC void enable_irq(unsigned irq)
! Enable an interrupt request line by clearing an 8259 bit.
! Equivalent code for irq < 8:
!	out_byte(INT_CTLMASK, in_byte(INT_CTLMASK) & ~(1 << irq));

	.align	16
_enable_irq:
	mov	ecx, 4(esp)		! irq
	pushf
	cli
	movb	ah, ~1
	rolb	ah, cl			! ah = ~(1 << (irq % 8))
	cmpb	cl, 8
	jae	enable_8		! enable irq >= 8 at the slave 8259
enable_0:
	inb	INT_CTLMASK
	andb	al, ah
	outb	INT_CTLMASK		! clear bit at master 8259
	popf
	ret
	.align	4
enable_8:
	inb	INT2_CTLMASK
	andb	al, ah
	outb	INT2_CTLMASK		! clear bit at slave 8259
	popf
	ret


!*==========================================================================*
!*				disable_irq				    *
!*==========================================================================*/
! PUBLIC int disable_irq(unsigned irq)
! Disable an interrupt request line by setting an 8259 bit.
! Equivalent code for irq < 8:
!	out_byte(INT_CTLMASK, in_byte(INT_CTLMASK) | (1 << irq));
! Returns true iff the interrupt was not already disabled.

	.align	16
_disable_irq:
	mov	ecx, 4(esp)		! irq
	pushf
	cli
	movb	ah, 1
	rolb	ah, cl			! ah = (1 << (irq % 8))
	cmpb	cl, 8
	jae	disable_8		! disable irq >= 8 at the slave 8259
disable_0:
	inb	INT_CTLMASK
	testb	al, ah
	jnz	dis_already		! already disabled?
	orb	al, ah
	outb	INT_CTLMASK		! set bit at master 8259
	popf
	mov	eax, 1			! disabled by this function
	ret
disable_8:
	inb	INT2_CTLMASK
	testb	al, ah
	jnz	dis_already		! already disabled?
	orb	al, ah
	outb	INT2_CTLMASK		! set bit at slave 8259
	popf
	mov	eax, 1			! disabled by this function
	ret
dis_already:
	popf
	xor	eax, eax		! already disabled
	ret


!*===========================================================================*
!*				phys_copy				     *
!*===========================================================================*
! PUBLIC void phys_copy(phys_bytes source, phys_bytes destination,
!			phys_bytes bytecount);
! Copy a block of physical memory.

PC_ARGS	=	4 + 4 + 4 + 4	! 4 + 4 + 4
!		es edi esi eip	 src dst len

	.align	16
_phys_copy:
	cld
	push	esi
	push	edi
	push	es

	mov	eax, FLAT_DS_SELECTOR
	mov	es, ax

	mov	esi, PC_ARGS(esp)
	mov	edi, PC_ARGS+4(esp)
	mov	eax, PC_ARGS+4+4(esp)

	cmp	eax, 10			! avoid align overhead for small counts
	jb	pc_small
	mov	ecx, esi		! align source, hope target is too
	neg	ecx
	and	ecx, 3			! count for alignment
	sub	eax, ecx
	rep
   eseg	movsb
	mov	ecx, eax
	shr	ecx, 2			! count of dwords
	rep
   eseg	movs
	and	eax, 3
pc_small:
	xchg	ecx, eax		! remainder
	rep
   eseg	movsb

	pop	es
	pop	edi
	pop	esi
	ret


!*===========================================================================*
!*				mem_rdw					     *
!*===========================================================================*
! PUBLIC u16_t mem_rdw(U16_t segment, u16_t *offset);
! Load and return word at far pointer segment:offset.

	.align	16
_mem_rdw:
	mov	cx, ds
	mov	ds, 4(esp)		! segment
	mov	eax, 4+4(esp)		! offset
	movzx	eax, (eax)		! word to return
	mov	ds, cx
	ret


!*===========================================================================*
!*				reset					     *
!*===========================================================================*
! PUBLIC void reset();
! Reset the system by loading IDT with offset 0 and interrupting.

_reset:
	lidt	(idt_zero)
	int	3		! anything goes, the 386 will not like it
.sect .data
idt_zero:	.data4	0, 0
.sect .text


!*===========================================================================*
!*				mem_vid_copy				     *
!*===========================================================================*
! PUBLIC void mem_vid_copy(u16 *src, unsigned dst, unsigned count);
!
! Copy count characters from kernel memory to video memory.  Src, dst and
! count are character (word) based video offsets and counts.  If src is null
! then screen memory is blanked by filling it with blank_color.

MVC_ARGS	=	4 + 4 + 4 + 4	! 4 + 4 + 4
!			es edi esi eip	 src dst ct

_mem_vid_copy:
	push	esi
	push	edi
	push	es
	mov	esi, MVC_ARGS(esp)	! source
	mov	edi, MVC_ARGS+4(esp)	! destination
	mov	edx, MVC_ARGS+4+4(esp)	! count
	mov	es, (_vid_seg)		! destination is video segment
	cld				! make sure direction is up
mvc_loop:
	and	edi, (_vid_mask)	! wrap address
	mov	ecx, edx		! one chunk to copy
	mov	eax, (_vid_size)
	sub	eax, edi
	cmp	ecx, eax
	jbe	0f
	mov	ecx, eax		! ecx = min(ecx, vid_size - edi)
0:	sub	edx, ecx		! count -= ecx
	shl	edi, 1			! byte address
	test	esi, esi		! source == 0 means blank the screen
	jz	mvc_blank
mvc_copy:
	rep				! copy words to video memory
    o16	movs
	jmp	mvc_test
mvc_blank:
	mov	eax, (_blank_color)	! ax = blanking character
	rep
    o16	stos				! copy blanks to video memory
	!jmp	mvc_test
mvc_test:
	shr	edi, 1			! word addresses
	test	edx, edx
	jnz	mvc_loop
mvc_done:
	pop	es
	pop	edi
	pop	esi
	ret


!*===========================================================================*
!*				vid_vid_copy				     *
!*===========================================================================*
! PUBLIC void vid_vid_copy(unsigned src, unsigned dst, unsigned count);
!
! Copy count characters from video memory to video memory.  Handle overlap.
! Used for scrolling, line or character insertion and deletion.  Src, dst
! and count are character (word) based video offsets and counts.

VVC_ARGS	=	4 + 4 + 4 + 4	! 4 + 4 + 4
!			es edi esi eip	 src dst ct

_vid_vid_copy:
	push	esi
	push	edi
	push	es
	mov	esi, VVC_ARGS(esp)	! source
	mov	edi, VVC_ARGS+4(esp)	! destination
	mov	edx, VVC_ARGS+4+4(esp)	! count
	mov	es, (_vid_seg)		! use video segment
	cmp	esi, edi		! copy up or down?
	jb	vvc_down
vvc_up:
	cld				! direction is up
vvc_uploop:
	and	esi, (_vid_mask)	! wrap addresses
	and	edi, (_vid_mask)
	mov	ecx, edx		! one chunk to copy
	mov	eax, (_vid_size)
	sub	eax, esi
	cmp	ecx, eax
	jbe	0f
	mov	ecx, eax		! ecx = min(ecx, vid_size - esi)
0:	mov	eax, (_vid_size)
	sub	eax, edi
	cmp	ecx, eax
	jbe	0f
	mov	ecx, eax		! ecx = min(ecx, vid_size - edi)
0:	sub	edx, ecx		! count -= ecx
	shl	esi, 1
	shl	edi, 1			! byte addresses
	rep
eseg o16 movs				! copy video words
	shr	esi, 1
	shr	edi, 1			! word addresses
	test	edx, edx
	jnz	vvc_uploop		! again?
	jmp	vvc_done
vvc_down:
	std				! direction is down
	lea	esi, -1(esi)(edx*1)	! start copying at the top
	lea	edi, -1(edi)(edx*1)
vvc_downloop:
	and	esi, (_vid_mask)	! wrap addresses
	and	edi, (_vid_mask)
	mov	ecx, edx		! one chunk to copy
	lea	eax, 1(esi)
	cmp	ecx, eax
	jbe	0f
	mov	ecx, eax		! ecx = min(ecx, esi + 1)
0:	lea	eax, 1(edi)
	cmp	ecx, eax
	jbe	0f
	mov	ecx, eax		! ecx = min(ecx, edi + 1)
0:	sub	edx, ecx		! count -= ecx
	shl	esi, 1
	shl	edi, 1			! byte addresses
	rep
eseg o16 movs				! copy video words
	shr	esi, 1
	shr	edi, 1			! word addresses
	test	edx, edx
	jnz	vvc_downloop		! again?
	cld				! C compiler expect up
	!jmp	vvc_done
vvc_done:
	pop	es
	pop	edi
	pop	esi
	ret


!*===========================================================================*
!*			      level0					     *
!*===========================================================================*
! PUBLIC void level0(void (*func)(void))
! Call a function at permission level 0.  This allows kernel tasks to do
! things that are only possible at the most privileged CPU level.
!
_level0:
	mov	eax, 4(esp)
	mov	(_level0_func), eax
	int	LEVEL0_VECTOR
	ret

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -