summaryrefslogtreecommitdiff
path: root/command_line/CmdLine/Src/Project/CLSegs.c
blob: e2c7369b5ac25423015da7ca7ecc82a31547f841 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "cmdline.h"

Segment *Segment_New(const char *name, UInt16 attrs) {
    Segment *seg = xmalloc(NULL, sizeof(Segment));
    strncpy(seg->name, name, sizeof(seg->name));
    seg->name[sizeof(seg->name) - 1] = 0;
    seg->attrs = attrs;
    return seg;
}

void Segment_Free(Segment *seg) {
    if (seg)
        xfree(seg);
}

Boolean Segments_Initialize(Segments *segs) {
    Segment *jump;
    Segment *main;
    UInt16 idx;

    OS_ASSERT(36, segs != NULL);

    memset(segs, 0, sizeof(Segments));
    segs->segsArray = NULL;

    jump = Segment_New("Jump Table", 0x28);
    Segments_AddSegment(segs, jump, &idx);
    OS_ASSERT(44, idx==0);

    main = Segment_New("Main", 0xFFFF);
    Segments_AddSegment(segs, main, &idx);
    OS_ASSERT(49, idx==1);

    return 1;
}

Boolean Segments_Terminate(Segments *segs) {
    UInt16 index;

    OS_ASSERT(57, segs != NULL);

    if (segs->segsArray) {
        for (index = 0; index < segs->segsCount; index++)
            Segment_Free(segs->segsArray[index]);
        xfree(segs->segsArray);
    }
    segs->segsArray = NULL;

    return 1;
}

static Boolean Segments_GrowSegments(Segments *segs, UInt16 *index) {
    Segment **newArray;

    OS_ASSERT(78, segs != NULL);

    if (segs->segsCount >= segs->arraySize) {
        segs->arraySize += 20;
        newArray = xrealloc("segments", segs->segsArray, sizeof(Segment *) * segs->arraySize);
        segs->segsArray = newArray;
    }

    *index = segs->segsCount++;
    return 1;
}

Boolean Segments_AddSegment(Segments *segs, Segment *seg, UInt16 *index) {
    UInt16 ni;

    if (Segments_GrowSegments(segs, &ni)) {
        segs->segsArray[ni] = seg;
        *index = ni;
        return 1;
    } else {
        return 0;
    }
}

Boolean Segments_InsertSegment(Segments *segs, UInt16 index, Segment *seg) {
    UInt16 ni;

    if (Segments_GrowSegments(segs, &ni)) {
        if (index > ni)
            index = ni - 1;
        memmove(&segs->segsArray[index + 1], &segs->segsArray[index], sizeof(Segment *) * (segs->segsCount - index));
        segs->segsArray[index] = seg;
        return 1;
    } else {
        return 0;
    }
}

Boolean Segments_DeleteSegment(Segments *segs, UInt16 index) {
    if (index >= segs->segsCount)
        return 0;

    Segment_Free(segs->segsArray[index]);
    memmove(&segs->segsArray[index], &segs->segsArray[index + 1], sizeof(Segment *) * (segs->segsCount - index));
    segs->segsCount--;
    return 1;
}

Segment *Segments_GetSegment(Segments *segs, UInt16 segnum) {
    OS_ASSERT(137, segs != NULL);

    if (segnum < segs->segsCount)
        return segs->segsArray[segnum];
    else
        return NULL;
}

UInt16 Segments_Count(const Segments *segs) {
    OS_ASSERT(147, segs != NULL);

    return segs->segsCount;
}