You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
340 lines
7.2 KiB
340 lines
7.2 KiB
|
|
typedef struct Length_String { |
|
short dynamic; |
|
unsigned int length; |
|
char *chars; |
|
} Length_String; |
|
|
|
typedef struct String_Array { |
|
unsigned int length; |
|
Length_String **strings; |
|
} String_Array; |
|
|
|
void strcpy (destination, destination_segment, source, source_segment ); |
|
int strlen (source, source_segment); |
|
void memcpy (destination, destination_segment, source, source_segment, num_bytes ); |
|
|
|
/* Additionals to standard c lib. */ |
|
String_Array *string_split_c(string, delim, keep_delim); |
|
Length_String *make_length_string(length, chars); |
|
Length_String *make_length_string_c(cstring); |
|
String_Array *length_string_split(string, delim, keep_delim); |
|
String_Array *create_length_string_array(array_size); |
|
Length_String *create_length_string(length, chars); |
|
|
|
|
|
|
|
int strlen (source, source_segment) |
|
{ |
|
#asm |
|
#define strlen_SOURCE 4[bp]; |
|
#define strlen_SOURCE_SEGMENT 6[bp]; |
|
push bp |
|
mov bp,sp |
|
push ds |
|
push bx |
|
|
|
mov ax, strlen_SOURCE_SEGMENT |
|
mov ds, ax |
|
|
|
mov bx, strlen_SOURCE |
|
|
|
label_strlen: |
|
mov cx, #0x0 ; Set counte to zero |
|
.label_strlen_loop: |
|
mov BYTE al, [bx] |
|
cmp al, #0x0 |
|
je .label_strlen_done |
|
inc cx ; Count 1 |
|
inc bx ; Look at next char |
|
jmp .label_strlen_loop |
|
.label_strlen_done: |
|
mov ax, cx |
|
|
|
pop bx |
|
pop ds |
|
pop bp |
|
#endasm |
|
} |
|
|
|
void strcpy (destination, destination_segment, source, source_segment ) |
|
char *destination; |
|
int destination_segment; |
|
char *source; |
|
int source_segment; |
|
{ |
|
#asm |
|
; copy two strings |
|
; IN si: the first (zero terminated) string |
|
; IN di: the second (zero terminated) string |
|
; OUT SF and ZF (same semantics as cmp) |
|
|
|
#define DESTINATION 4[bp]; |
|
#define DESTINATION_SEGMENT 6[bp]; |
|
#define SOURCE 8[bp]; |
|
#define SOURCE_SEGMENT 10[bp]; |
|
|
|
push bp |
|
mov bp,sp |
|
label_strcpy: |
|
push ax |
|
push bx |
|
push di |
|
push es |
|
push si |
|
push ds |
|
mov ax, DESTINATION; |
|
mov di, ax |
|
mov ax, DESTINATION_SEGMENT; |
|
mov es, ax |
|
mov ax, SOURCE; |
|
mov si, ax |
|
mov ax, SOURCE_SEGMENT; |
|
mov ds, ax |
|
mov cx, 0x050 ;TODO(Jørn) Hardcded number of bytes to copy |
|
.label_strcpy_loop: |
|
movsb |
|
cmp cx, 0x0 |
|
je .label_strcpy_end |
|
dec cx |
|
jmp .label_strcpy_loop |
|
.label_strcpy_end: |
|
pop ds |
|
pop si |
|
pop es |
|
pop di |
|
pop bx |
|
pop ax |
|
pop bp |
|
|
|
#endasm |
|
} |
|
|
|
void memcpy (destination, destination_segment, source, source_segment, num_bytes) |
|
void *destination; |
|
int destination_segment; |
|
void *source; |
|
int source_segment; |
|
int num_bytes; |
|
{ |
|
#asm |
|
; copy two strings |
|
; IN si: the first (zero terminated) string |
|
; IN di: the second (zero terminated) string |
|
; OUT SF and ZF (same semantics as cmp) |
|
|
|
#define DESTINATION 4[bp]; |
|
#define DESTINATION_SEGMENT 6[bp]; |
|
#define SOURCE 8[bp]; |
|
#define SOURCE_SEGMENT 10[bp]; |
|
#define NUM_BYTES 12[bp]; |
|
|
|
push bp |
|
mov bp,sp |
|
label_memcpy: |
|
push ax |
|
push bx |
|
push di |
|
push es |
|
push si |
|
push ds |
|
mov ax, DESTINATION; |
|
mov di, ax |
|
mov ax, DESTINATION_SEGMENT; |
|
mov es, ax |
|
mov ax, SOURCE; |
|
mov si, ax |
|
mov ax, SOURCE_SEGMENT; |
|
mov ds, ax |
|
mov cx, NUM_BYTES |
|
.label_memcpy_loop: |
|
movsb |
|
cmp cx, 0x0 |
|
je .label_memcpy_end |
|
dec cx |
|
jmp .label_memcpy_loop |
|
.label_memcpy_end: |
|
pop ds |
|
pop si |
|
pop es |
|
pop di |
|
pop bx |
|
pop ax |
|
pop bp |
|
|
|
#endasm |
|
} |
|
|
|
int strcmp(source_1, source_2) |
|
char* source_1; |
|
char* source_2; |
|
{ |
|
int i; |
|
int count; |
|
|
|
count = strlen(source_1, 0x7e0); |
|
if (count != strlen(source_2, 0x7e0)) |
|
{ |
|
return -1; |
|
} |
|
|
|
|
|
for (i = 0; i < count; i++) |
|
{ |
|
if(source_1[i] != source_2[i]) |
|
{ |
|
return -1; |
|
} |
|
} |
|
|
|
return 0; |
|
/* |
|
#asm |
|
#define DESTINATION 4[bp]; |
|
#define DESTINATION_SEGMENT 6[bp]; |
|
#define SOURCE 8[bp]; |
|
#define SOURCE_SEGMENT 10[bp]; |
|
; Compares two strings |
|
; IN si: the first (zero terminated) string |
|
; IN di: the second (zero terminated) string |
|
; OUT SF and ZF (same semantics as cmp) |
|
strcmp_stringcompare: |
|
push bx |
|
push si |
|
push di |
|
.strcmp_loop: |
|
mov bl, [si] |
|
mov bh, [di] |
|
cmp bl, bh |
|
jne .strcmp_end |
|
test bl, bl ; bl and bh are the same, so bl = 0 => dl = 0 |
|
jz .strcmp_end |
|
inc si |
|
inc di |
|
jmp .strcmp_loop |
|
.strcmp_end: |
|
pop di |
|
pop si |
|
pop bx |
|
|
|
ret |
|
|
|
#endasm |
|
*/ |
|
} |
|
|
|
String_Array *string_split_c(string, delim, keep_delim) |
|
char *string; |
|
char delim; |
|
short keep_delim; |
|
{ |
|
return length_string_split(make_length_string_c(string), delim, keep_delim); |
|
} |
|
|
|
Length_String *make_length_string_c(cstring) |
|
char *cstring; |
|
{ |
|
return make_length_string(strlen(cstring, 0x7e0), cstring); |
|
} |
|
|
|
Length_String *make_length_string(length, chars) |
|
unsigned int length; |
|
char *chars; |
|
{ |
|
|
|
Length_String *legth_string = malloc(sizeof(Length_String)); |
|
char *copy = malloc(length + 1); /* Space for null terminator */ |
|
memcpy(copy, 0x7e0, chars, 0x7e0, length); |
|
copy[length] = '\0'; |
|
|
|
legth_string->dynamic = 0; |
|
legth_string->length = length; |
|
legth_string->chars = (char *)chars; |
|
|
|
return legth_string; |
|
} |
|
|
|
String_Array *length_string_split(string, delim, keep_delim) |
|
Length_String *string; |
|
char delim; |
|
short keep_delim; |
|
{ |
|
unsigned int i; |
|
unsigned int last; |
|
|
|
unsigned int count = 0; |
|
unsigned int insert_index = 0; |
|
String_Array *result; |
|
int k; |
|
|
|
i = 0; |
|
last = 0; |
|
while(i < string->length) { |
|
if (string->chars[i] == delim) { |
|
if (i > last+1) { |
|
++count; |
|
} |
|
last = i; |
|
} |
|
++i; |
|
} |
|
if (i > last+1) { |
|
++count; |
|
} |
|
|
|
result = create_length_string_array(count); |
|
|
|
if (keep_delim) |
|
{ |
|
k = 0; |
|
} |
|
else |
|
{ |
|
k = 1; |
|
} |
|
|
|
i = 0; |
|
last = 0; |
|
while(i < string->length) { |
|
if (string->chars[i] == delim) { |
|
if (i > last+1) { |
|
result->strings[insert_index++] = create_length_string(i-(last+k), string->chars+(last+k)); |
|
} |
|
last = i; |
|
} |
|
++i; |
|
} |
|
if (i > last+1) { |
|
result->strings[insert_index++] = create_length_string(i-(last+k), ((string->chars)+(last+k))); |
|
} |
|
|
|
return result; |
|
|
|
} |
|
|
|
String_Array *create_length_string_array(array_size) |
|
int array_size; |
|
{ |
|
String_Array *result = malloc(sizeof(String_Array)); |
|
result->length = array_size; |
|
result->strings = malloc(array_size * sizeof(Length_String)); |
|
return result; |
|
} |
|
|
|
|
|
Length_String *create_length_string(length, chars) |
|
unsigned int length; |
|
char *chars; |
|
{ |
|
|
|
Length_String *legth_string = malloc(sizeof(Length_String)); |
|
char *copy = malloc(length + 1); /* Space for null terminator */ |
|
memcpy(copy, 0x7e0, chars, 0x7e0, length); |
|
copy[length] = '\0'; |
|
|
|
legth_string->dynamic = 1; |
|
legth_string->length = length; |
|
legth_string->chars = copy; |
|
|
|
return legth_string; |
|
} |