Initial commit
This commit is contained in:
commit
4b4c46d7ca
6
Tupfile
Normal file
6
Tupfile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.gitignore
|
||||||
|
|
||||||
|
ASFLAGS = -m68010 -spaces -Felf -ldots -align -quiet -x -nowarn=62
|
||||||
|
|
||||||
|
: foreach *.68k |> vasmm68k_mot $(ASFLAGS) -o %o %f |> %B.o
|
||||||
|
: *.o |> ar rs %o %f |> libstd.a
|
0
Tupfile.imi
Normal file
0
Tupfile.imi
Normal file
7
include/memory.i
Normal file
7
include/memory.i
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
ifnd __STD_MEMORY_I
|
||||||
|
__STD_MEMORY_I equ 1
|
||||||
|
; Frees the memory block pointed to by a0
|
||||||
|
xref free
|
||||||
|
; Allocates a memory block of size d0 and returns the address in a0
|
||||||
|
xref malloc
|
||||||
|
endif
|
9
include/string.i
Normal file
9
include/string.i
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
ifnd __STD_STRING_I
|
||||||
|
__STD_STRING_I equ 1
|
||||||
|
; Writes the hexdecimal ASCII representation of d0.l to the 11-byte buffer at a0
|
||||||
|
xref hex_to_ascii
|
||||||
|
; Compares the strings in a0 and a1
|
||||||
|
; Returns 0 in d0.b if identical
|
||||||
|
; Returns difference of first mismatching character in d0.b (s1-s2) if different
|
||||||
|
xref strcmp
|
||||||
|
endif
|
22
include/syscalls.i
Normal file
22
include/syscalls.i
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
ifnd __STD_SYSCALLS_I
|
||||||
|
__STD_SYSCALLS_I equ 1
|
||||||
|
; Exits the process
|
||||||
|
xref syscall_exit
|
||||||
|
; Yields to the next process
|
||||||
|
xref syscall_yield
|
||||||
|
; Prints the string pointed to by d0
|
||||||
|
xref syscall_print
|
||||||
|
; Prints the string pointed to by d0 followed by a newline
|
||||||
|
xref syscall_println
|
||||||
|
; Maps the range of pages starting at address a0 with length d0 to free physical frames
|
||||||
|
; Permission flags in d1
|
||||||
|
xref syscall_vmem_map
|
||||||
|
; Map a free range of pages with length d0 to free physical frames
|
||||||
|
; Returns the range start in a0
|
||||||
|
; Permission flags in d1
|
||||||
|
xref syscall_vmem_map_free
|
||||||
|
; Maps a free range of virtual pages with length d1 to the range of physical frames starting at d0
|
||||||
|
; Returns the range start in a0
|
||||||
|
; Permission flags in d2
|
||||||
|
xref syscall_vmem_map_free_to
|
||||||
|
endif
|
145
memory.68k
Normal file
145
memory.68k
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
include include/syscalls.i
|
||||||
|
section .text,text
|
||||||
|
; Frees the memory block pointed to by a0
|
||||||
|
; free_w_size internal entry expecting size in d0
|
||||||
|
; instead of 4 bytes before passed in address
|
||||||
|
public free
|
||||||
|
free:
|
||||||
|
move.l -(a0), d0 ; Read the allocatuon size and get the true hole pointer
|
||||||
|
free_w_size:
|
||||||
|
move.l (free_list), a1 ; Get the head of the free list in a0
|
||||||
|
cmpa.l #0, a1 ; Check if the free list is empty
|
||||||
|
bne.b free_list_not_empty ; If not, find the right position and insert the hole
|
||||||
|
move.l d0, (a0) ; Otherwise, set the free list to be the passed in hole and return
|
||||||
|
move.l #0, ($4,a0)
|
||||||
|
move.l a0, (free_list)
|
||||||
|
rts
|
||||||
|
free_list_not_empty:
|
||||||
|
move.l a2, -(a7) ; Preserve a2 (callee saved)
|
||||||
|
move.l #0, a1 ; a1 is the pointer to the previous hole in the list, starts out NULL
|
||||||
|
move.l (free_list), a2 ; a2 is the pointer to the current hole in the list
|
||||||
|
free_find_loop:
|
||||||
|
cmpa.l #0, a2 ; If we have hit the end of the list, we have found the right position
|
||||||
|
beq.b free_find_loop_done
|
||||||
|
cmp.l a0, a2
|
||||||
|
bgt.b free_find_loop_done
|
||||||
|
move.l a2, a1 ; Go to the next item
|
||||||
|
move.l ($4,a2), a2
|
||||||
|
bra.b free_find_loop
|
||||||
|
free_find_loop_done:
|
||||||
|
; We have now found where to put the hole, that being between a1 (previous hole), and a2 (current hole)
|
||||||
|
cmpa.l #0, a1 ; If there is no previous item, we cannot merge
|
||||||
|
beq.b free_no_prev
|
||||||
|
move.l (a1), d1 ; If size of prev hole + address of prev hole = address of hole to free, they are consecutive and can be merged
|
||||||
|
add.l a1, d1
|
||||||
|
cmp.l a0, d1
|
||||||
|
bne.b free_no_prev_merge
|
||||||
|
add.l d0, (a1) ; size of prev hole += size of hole to free
|
||||||
|
move.l a1, a0 ; hole to free = prev hole
|
||||||
|
move.l #0, a1 ; prev hole = NULL
|
||||||
|
bra.b free_prev_merge_done
|
||||||
|
free_no_prev_merge:
|
||||||
|
move.l a2, ($4,a0) ; If we are not merging, hole to free next = current hole, prev hole next = hole to free
|
||||||
|
move.l a0, ($4,a1)
|
||||||
|
bra free_prev_merge_done
|
||||||
|
free_no_prev:
|
||||||
|
move.l (free_list), ($4,a0) ; If there is no previous hole, add it to the beginning of the free list
|
||||||
|
move a0, (free_list)
|
||||||
|
free_prev_merge_done:
|
||||||
|
cmpa.l #0, a2 ; If there is no current hole, no merging must be done
|
||||||
|
beq.b free_curr_merge_done
|
||||||
|
move.l (a0), d1 ; If size of hole to free + address of hole to free = address of current hole, they are consecutive and can be merged
|
||||||
|
add.l a0, d1
|
||||||
|
cmp.l a2, d1
|
||||||
|
bne.b free_curr_merge_done
|
||||||
|
move.l ($4,a2), d1 ; hole to free next = current hole next
|
||||||
|
move.l d1, ($4,a0)
|
||||||
|
move.l (a0), d1 ; hole to free size += current hole size
|
||||||
|
add.l (a2), d1
|
||||||
|
move.l d1, (a0)
|
||||||
|
free_curr_merge_done:
|
||||||
|
move.l (a7)+, a2 ; Restore a2 (callee saved)
|
||||||
|
rts
|
||||||
|
|
||||||
|
; Allocates a memory block of size d0 and returns the address in a0
|
||||||
|
public malloc
|
||||||
|
malloc:
|
||||||
|
; Return NULL if d0=0
|
||||||
|
cmpi.l #0, d0
|
||||||
|
bne .1
|
||||||
|
move.l #0, a0
|
||||||
|
rts
|
||||||
|
.1:
|
||||||
|
; d0=d0+4 rounded to next multiple of 4
|
||||||
|
addi.l #4, d0
|
||||||
|
move.l d0, d1
|
||||||
|
andi.l #$2, d1
|
||||||
|
beq.b .2
|
||||||
|
move.l d0, d1
|
||||||
|
andi.l #~$2, d1
|
||||||
|
addi.l #8, d1
|
||||||
|
move.l d1, d0
|
||||||
|
.2:
|
||||||
|
move.l (free_list), a0
|
||||||
|
malloc_find_loop:
|
||||||
|
cmpa.l #0, a0
|
||||||
|
beq malloc_found_end
|
||||||
|
move.l (a0), d1
|
||||||
|
cmp.l d0, d1
|
||||||
|
blt.b malloc_too_small
|
||||||
|
beq.b malloc_block_exact_size
|
||||||
|
sub.l d0, d1
|
||||||
|
move.l d1, (a0)
|
||||||
|
adda.l d1, a0
|
||||||
|
move.l d0, (a0)+
|
||||||
|
rts
|
||||||
|
malloc_block_exact_size:
|
||||||
|
adda.l #4, a0
|
||||||
|
rts
|
||||||
|
malloc_too_small:
|
||||||
|
move.l ($8,a0), a0
|
||||||
|
bra.b malloc_find_loop
|
||||||
|
malloc_found_end:
|
||||||
|
move.l d0, -(a7)
|
||||||
|
move.l d0, d1
|
||||||
|
andi.l #$fff, d1
|
||||||
|
beq.b .1
|
||||||
|
move.l d0, d1
|
||||||
|
andi.l #~$fff, d1
|
||||||
|
addi.l #$1000, d1
|
||||||
|
move.l d1, d0
|
||||||
|
.1:
|
||||||
|
lsr.l #8, d0
|
||||||
|
lsr.l #4, d0
|
||||||
|
move.l d0, -(a7)
|
||||||
|
jsr alloc_pages
|
||||||
|
move.l (a7)+, d0
|
||||||
|
lsl.l #8, d0
|
||||||
|
lsl.l #4, d0
|
||||||
|
move.l d0, d1
|
||||||
|
move.l (a7)+, d0
|
||||||
|
sub.l d0, d1
|
||||||
|
move.l a0, a1
|
||||||
|
adda.l d1, a1
|
||||||
|
move.l d0, (a1)+
|
||||||
|
move.l d1, d0
|
||||||
|
move.l a1, -(a7)
|
||||||
|
bsr.w free_w_size
|
||||||
|
move.l (a7)+, a0
|
||||||
|
rts
|
||||||
|
|
||||||
|
; Allocate a block of memory d0 pages in length and returns the address in a0
|
||||||
|
weak alloc_pages
|
||||||
|
alloc_pages:
|
||||||
|
move.l d2, -(a7)
|
||||||
|
move.l #$2, d1
|
||||||
|
jsr syscall_vmem_map_free
|
||||||
|
alloc_pages_done:
|
||||||
|
move.l (a7)+, d2
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
section .bss,bss
|
||||||
|
free_list:
|
||||||
|
ds.b 4
|
71
string.68k
Normal file
71
string.68k
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
section .text,text
|
||||||
|
public hex_to_ascii
|
||||||
|
; Writes the hexdecimal ASCII representation of d0.l to the 11-byte buffer at a0
|
||||||
|
hex_to_ascii:
|
||||||
|
movem.l d2/d3, -(a7) ; Save old values of d2 and d3 (callee preserved)
|
||||||
|
move.b #'0', (a0)+
|
||||||
|
move.b #'x', (a0)+
|
||||||
|
move.b #0, d1
|
||||||
|
move.w #28, d2
|
||||||
|
hex_to_ascii_loop:
|
||||||
|
cmpi.w #0, d2
|
||||||
|
beq.b hex_to_ascii_loop_done
|
||||||
|
move.l d0, d3
|
||||||
|
lsr.l d2, d3
|
||||||
|
andi.l #$F, d3
|
||||||
|
cmp.l #0, d3
|
||||||
|
bne.b .1
|
||||||
|
cmp.b #0, d1
|
||||||
|
bne.b .1
|
||||||
|
subi.w #4, d2
|
||||||
|
bra.b hex_to_ascii_loop
|
||||||
|
.1:
|
||||||
|
move.b #1, d1
|
||||||
|
cmp.b #$A, d3
|
||||||
|
blt.b .2
|
||||||
|
add.b #('a' - $A), d3
|
||||||
|
move.b d3, (a0)+
|
||||||
|
bra.b .3
|
||||||
|
.2:
|
||||||
|
add.b #'0', d3
|
||||||
|
move.b d3, (a0)+
|
||||||
|
.3:
|
||||||
|
subi.w #4, d2
|
||||||
|
bra.b hex_to_ascii_loop
|
||||||
|
hex_to_ascii_loop_done:
|
||||||
|
move.l d0, d3
|
||||||
|
andi.l #$F, d3
|
||||||
|
cmp.b #$A, d3
|
||||||
|
blt.b .2
|
||||||
|
add.b #('a' - $A), d3
|
||||||
|
move.b d3, (a0)+
|
||||||
|
bra.b .3
|
||||||
|
.2:
|
||||||
|
add.b #'0', d3
|
||||||
|
move.b d3, (a0)+
|
||||||
|
.3:
|
||||||
|
move.b #0, (a0)
|
||||||
|
movem.l (a7)+, d2/d3 ; Restore d2 and d3 (callee preserved)
|
||||||
|
rts
|
||||||
|
|
||||||
|
; Compares the strings in a0 and a1
|
||||||
|
; Returns 0 in d0.b if identical
|
||||||
|
; Returns difference of first mismatching character in d0.b (s1-s2) if different
|
||||||
|
public strcmp
|
||||||
|
strcmp:
|
||||||
|
strcmp_loop:
|
||||||
|
move.b (a0), d0
|
||||||
|
cmp.b (a1), d0
|
||||||
|
bne.b strcmp_loop_done
|
||||||
|
cmpi.b #0, (a0)
|
||||||
|
bne.b .1
|
||||||
|
move.b #0, d0
|
||||||
|
rts
|
||||||
|
.1:
|
||||||
|
adda.l #1, a0
|
||||||
|
adda.l #1, a1
|
||||||
|
bra.b strcmp_loop
|
||||||
|
strcmp_loop_done:
|
||||||
|
move.b (a0), d0
|
||||||
|
sub.b (a1), d0
|
||||||
|
rts
|
70
syscalls.68k
Normal file
70
syscalls.68k
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
section .text,text
|
||||||
|
|
||||||
|
public syscall_exit
|
||||||
|
; Exits the process
|
||||||
|
syscall_exit:
|
||||||
|
move.l #0, d0
|
||||||
|
trap #0
|
||||||
|
rts
|
||||||
|
|
||||||
|
public syscall_yield
|
||||||
|
; Yields to the next process
|
||||||
|
syscall_yield:
|
||||||
|
move.l #1, d0
|
||||||
|
rts
|
||||||
|
|
||||||
|
public syscall_print
|
||||||
|
; Prints the string pointed to by d0
|
||||||
|
syscall_print:
|
||||||
|
move.l d0, d1
|
||||||
|
move.l #2, d0
|
||||||
|
trap #0
|
||||||
|
rts
|
||||||
|
|
||||||
|
public syscall_println
|
||||||
|
; Prints the string pointed to by d0 followed by a newline
|
||||||
|
syscall_println:
|
||||||
|
move.l d0, d1
|
||||||
|
move.l #3, d0
|
||||||
|
trap #0
|
||||||
|
rts
|
||||||
|
|
||||||
|
public syscall_vmem_map
|
||||||
|
; Maps the range of pages starting at address a0 with length d0 to free physical frames
|
||||||
|
; Permission flags in d1
|
||||||
|
syscall_vmem_map:
|
||||||
|
move.l d2, -(a7)
|
||||||
|
move.l d1, d2
|
||||||
|
move.l d0, d1
|
||||||
|
move.l #4, d0
|
||||||
|
trap #0
|
||||||
|
move.l (a7)+, d2
|
||||||
|
rts
|
||||||
|
|
||||||
|
public syscall_vmem_map_free
|
||||||
|
; Map a free range of pages with length d0 to free physical frames
|
||||||
|
; Returns the range start in a0
|
||||||
|
; Permission flags in d1
|
||||||
|
syscall_vmem_map_free:
|
||||||
|
move.l d2, -(a7)
|
||||||
|
move.l d1, d2
|
||||||
|
move.l d0, d1
|
||||||
|
move.l #5, d0
|
||||||
|
trap #0
|
||||||
|
move.l (a7)+, d2
|
||||||
|
rts
|
||||||
|
|
||||||
|
public syscall_vmem_map_free_to
|
||||||
|
; Maps a free range of virtual pages with length d1 to the range of physical frames starting at d0
|
||||||
|
; Returns the range start in a0
|
||||||
|
; Permission flags in d2
|
||||||
|
syscall_vmem_map_free_to:
|
||||||
|
move.l d3, -(a7)
|
||||||
|
move.l d2, d3
|
||||||
|
move.l d1, d2
|
||||||
|
move.l d0, d1
|
||||||
|
move.l #6, d0
|
||||||
|
trap #0
|
||||||
|
move.l (a7)+, d3
|
||||||
|
rts
|
||||||
|
|
Loading…
Reference in New Issue
Block a user