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;
|
|
}
|