📄 klib88.s
字号:
movs ! copy the message
pop di ! restore di
pop si ! restore si
pop ds ! restore ds
pop es ! restore es
ret ! that is all folks!
!*===========================================================================*
!* exit *
!*===========================================================================*
! PUBLIC void exit();
! Some library routines use exit, so provide a dummy version.
! Actual calls to exit cannot occur in the kernel.
! Same for .fat & .trp.
_exit:
__exit:
___exit:
.fat:
.trp:
sti
jmp __exit
!*===========================================================================*
!* in_byte *
!*===========================================================================*
! PUBLIC unsigned in_byte(port_t port);
! Read an (unsigned) byte from the i/o port port and return it.
_in_byte:
pop bx
pop dx ! port
dec sp
dec sp
inb ! input 1 byte
subb ah,ah ! unsign extend
jmp (bx)
!*===========================================================================*
!* in_word *
!*===========================================================================*
! PUBLIC unsigned short in_word(port_t port);
! Read an (unsigned) word from the i/o port and return it.
_in_word:
pop bx
pop dx ! port
dec sp
dec sp ! added to new klib.s 3/21/91 d.e.c.
inw ! input 1 word no sign extend needed
jmp (bx)
!*===========================================================================*
!* out_byte *
!*===========================================================================*
! PUBLIC void out_byte(port_t port, int value);
! Write value (cast to a byte) to the I/O port port.
_out_byte:
pop bx
pop dx ! port
pop ax ! value
sub sp,#2+2
outb ! output 1 byte
jmp (bx)
!*===========================================================================*
!* out_word *
!*===========================================================================*
! PUBLIC void out_word(port_t port, int value);
! Write value (cast to a word) to the I/O port port.
_out_word:
pop bx
pop dx ! port
pop ax ! value
sub sp,#2+2
outw ! output 1 word
jmp (bx)
!*===========================================================================*
!* port_read *
!*===========================================================================*
! PUBLIC void port_read(port_t port, phys_bytes destination,unsigned bytcount);
! Transfer data from (hard disk controller) port to memory.
_port_read:
push bp
mov bp,sp
push di
push es
call portio_setup
shr cx,#1 ! count in words
mov di,bx ! di = destination offset
mov es,ax ! es = destination segment
rep
ins
pop es
pop di
pop bp
ret
portio_setup:
mov ax,4+2(bp) ! source/destination address in dx:ax
mov dx,4+2+2(bp)
mov bx,ax
and bx,#OFF_MASK ! bx = offset = address % 16
andb dl,#HCHIGH_MASK ! ax = segment = address / 16 % 0x10000
andb al,#HCLOW_MASK
orb al,dl
movb cl,#HCLICK_SHIFT
ror ax,cl
mov cx,4+2+4(bp) ! count in bytes
mov dx,4(bp) ! port to read from
cld ! direction is UP
ret
!*===========================================================================*
!* port_read_byte *
!*===========================================================================*
! PUBLIC void port_read_byte(port_t port, phys_bytes destination,
! unsigned bytcount);
! Transfer data port to memory.
_port_read_byte:
push bp
mov bp,sp
push di
push es
call portio_setup
mov di,bx ! di = destination offset
mov es,ax ! es = destination segment
rep
insb
pop es
pop di
pop bp
ret
!*===========================================================================*
!* port_write *
!*===========================================================================*
! PUBLIC void port_write(port_t port, phys_bytes source, unsigned bytcount);
! Transfer data from memory to (hard disk controller) port.
_port_write:
push bp
mov bp,sp
push si
push ds
call portio_setup
shr cx,#1 ! count in words
mov si,bx ! si = source offset
mov ds,ax ! ds = source segment
rep
outs
pop ds
pop si
pop bp
ret
!*===========================================================================*
!* port_write_byte *
!*===========================================================================*
! PUBLIC void port_write_byte(port_t port, phys_bytes source,
! unsigned bytcount);
! Transfer data from memory to port.
_port_write_byte:
push bp
mov bp,sp
push si
push ds
call portio_setup
mov si,bx ! si = source offset
mov ds,ax ! ds = source segment
rep
outsb
pop ds
pop si
pop bp
ret
!*===========================================================================*
!* lock *
!*===========================================================================*
! PUBLIC void lock();
! Disable CPU interrupts.
_lock:
cli ! disable interrupts
ret
!*===========================================================================*
!* unlock *
!*===========================================================================*
! PUBLIC void unlock();
! Enable CPU interrupts.
_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));
_enable_irq:
mov bx, sp
mov cx, 2(bx) ! 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
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.
_disable_irq:
mov bx, sp
mov cx, 2(bx) ! 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 ax, #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 ax, #1 ! disabled by this function
ret
dis_already:
popf
xor ax, ax ! already disabled
ret
!*===========================================================================*
!* phys_copy *
!*===========================================================================*
! PUBLIC void phys_copy(phys_bytes source, phys_bytes destination,
! phys_bytes bytecount);
! Copy a block of physical memory.
SRCLO = 4
SRCHI = 6
DESTLO = 8
DESTHI = 10
COUNTLO = 12
COUNTHI = 14
_phys_copy:
push bp ! save only registers required by C
mov bp,sp ! set bp to point to source arg less 4
push si ! save si
push di ! save di
push ds ! save ds
push es ! save es
mov ax,SRCLO(bp) ! dx:ax = source address (dx is NOT segment)
mov dx,SRCHI(bp)
mov si,ax ! si = source offset = address % 16
and si,#OFF_MASK
andb dl,#HCHIGH_MASK ! ds = source segment = address / 16 % 0x10000
andb al,#HCLOW_MASK
orb al,dl ! now bottom 4 bits of dx are in ax
movb cl,#HCLICK_SHIFT ! rotate them to the top 4
ror ax,cl
mov ds,ax
mov ax,DESTLO(bp) ! dx:ax = destination addr (dx is NOT segment)
mov dx,DESTHI(bp)
mov di,ax ! di = dest offset = address % 16
and di,#OFF_MASK
andb dl,#HCHIGH_MASK ! es = dest segment = address / 16 % 0x10000
andb al,#HCLOW_MASK
orb al,dl
ror ax,cl
mov es,ax
mov ax,COUNTLO(bp) ! dx:ax = remaining count
mov dx,COUNTHI(bp)
! copy upwards (cannot handle overlapped copy)
pc_loop:
mov cx,ax ! provisional count for this iteration
test ax,ax ! if count >= 0x8000, only do 0x8000 per iter
js pc_bigcount ! low byte already >= 0x8000
test dx,dx
jz pc_upcount ! less than 0x8000
pc_bigcount:
mov cx,#0x8000 ! use maximum count per iteration
pc_upcount:
sub ax,cx ! update count
sbb dx,#0 ! cannot underflow, so carry clear now for rcr
rcr cx,#1 ! count in words, carry remembers if byte
jnb pc_even ! no odd byte
movb ! copy odd byte
pc_even:
rep ! copy 1 word at a time
movs ! word copy
mov cx,ax ! test if remaining count is 0
or cx,dx
jnz pc_more ! more to do
pop es ! restore es
pop ds ! restore ds
pop di ! restore di
pop si ! restore si
pop bp ! restore bp
ret ! return to caller
pc_more:
sub si,#0x8000 ! adjust pointers so the offset does not
mov cx,ds ! overflow in the next 0x8000 bytes
add cx,#0x800 ! pointers end up same physical location
mov ds,cx ! the current offsets are known >= 0x8000
sub di,#0x8000 ! since we just copied that many
mov cx,es
add cx,#0x800
mov es,cx
jmp pc_loop ! start next iteration
!*===========================================================================*
!* mem_rdw *
!*===========================================================================*
! PUBLIC u16_t mem_rdw(u16_t segment, u16_t *offset);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -