-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathblockmem.q
137 lines (133 loc) · 5 KB
/
blockmem.q
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
.blockmem.new:{([]addr:`long$();data:())};
.blockmem.write:{[bm;offset;content]
offset:`long$offset;
if[0=count bm;
:enlist[(`addr`data!(offset;content))];
];
cc:count content;
endaddr:offset+cc;
blockBef:bm[`addr] bin offset;
blockAft:(bm[`addr]+count each bm[`data]) bin endaddr-1;
bmBef:(blockBef+1)#bm;
bmAft:(blockAft+1)_bm;
if[blockBef=blockAft+1;
la:bmAft[0;`addr];
bmAft[0;`data;(offset-la)+til count content]:content;
:(-1_bmBef),bmAft;
];
if[(0<count bmAft)and(endaddr>=fa:first[bmAft`addr]);
fd:bmAft[0;`data];
content,:(endaddr-fa)_fd;
bmAft:1_bmAft;
];
if[[fa:last[bmBef`addr];(0<count bmBef)and(offset>=fa)and(offset<=fa+count[last bmBef`data])];
fd:last[bmBef][`data];
bmBef[count[bmBef]-1;`data]:((offset-fa)#fd),content;
:bmBef,bmAft;
];
if[blockBef=-1;
bm:(`addr`data!(offset;content)),bmAft;
:bm;
];
bm:bmBef,(`addr`data!(offset;content)),bmAft;
bm};
.blockmem.read:{[bm;offset;size]
if[0=count bm; :size#0x00];
endaddr:offset+size;
blockBef:bm[`addr]bin offset;
blockAft:bm[`addr]bin endaddr-1;
begin:`byte$();
if[blockBef=-1;
ba:bm[0;`addr];
if[ba>=endaddr; :size#0x00];
begin:(ba-offset)#0x00;
size-:(ba-offset);
offset:ba;
blockBef+:1;
];
if[blockBef=blockAft;
ba:bm[blockBef;`addr];
bs:count bm[blockBef;`data];
:begin,$[endaddr<=ba+bs;
bm[blockBef;`data][(offset-ba)+til size];
offset<=ba+bs;
((offset-ba)_bm[blockBef;`data]),(size-bs-offset-ba)#0x00;
size#0x00
];
];
if[not offset=bm[blockBef;`addr];
ba:bm[blockBef;`addr];
nba:bm[blockBef+1;`addr];
bs:count bm[blockBef;`data];
nbegin:$[offset<=ba+bs;
((offset-ba)_bm[blockBef;`data]),((nba-ba)-bs)#0x00;
(nba-offset)#0x00];
begin,:nbegin;
offset+:count nbegin;
size-:count nbegin;
blockBef+:1;
];
end:`byte$();
if[not endaddr=bm[blockAft;`addr];
ea:bm[blockAft;`addr];
es:count bm[blockAft;`data];
nend:$[endaddr<=ea+es;
(endaddr-ea)#bm[blockAft;`data];
bm[blockAft;`data],(endaddr-ea+es)#0x00];
end,:nend;
size-:count nend;
];
if[blockBef=blockAft; :begin,end];
zeroSizes:((1_bm[`addr]),0)-(bm[`addr]+count each bm[`data]);
:begin,(raze(blockBef _ blockAft#bm[`data]),'(blockBef _ blockAft#zeroSizes)#\:0x00),end;
};
.blockmem.unitTest:{
bm:.blockmem.new[];
bm:.blockmem.write[bm;100;0x01020304];
bm:.blockmem.write[bm;140;0x01020304];
bm:.blockmem.write[bm;90;0x01020304];
if[not 90 100 140~bm[`addr]; {'"failed"}[]];
bm:.blockmem.write[bm;110;0x01020304];
if[not 90 100 110 140~bm[`addr]; {'"failed"}[]];
bm:.blockmem.write[bm;101;0xfffe];
if[not 90 100 110 140~bm[`addr]; {'"failed"}[]];
if[not 0x01fffe04~bm[1;`data]; {'"failed"}[]];
bm:.blockmem.write[bm;89;0xefee];
if[not 89 100 110 140~bm[`addr]; {'"failed"}[]];
if[not 0xefee020304~bm[0;`data]; {'"failed"}[]];
bm:.blockmem.write[bm;108;0xdfde];
if[not 89 100 108 140~bm[`addr]; {'"failed"}[]];
if[not 0xdfde01020304~bm[2;`data]; {'"failed"}[]];
bm:.blockmem.write[bm;112;0x0506];
if[not 89 100 108 140~bm[`addr]; {'"failed"}[]];
if[not 0xdfde01020506~bm[2;`data]; {'"failed"}[]];
bm:.blockmem.write[bm;113;0x0708];
if[not 89 100 108 140~bm[`addr]; {'"failed"}[]];
if[not 0xdfde0102050708~bm[2;`data]; {'"failed"}[]];
bm:.blockmem.write[bm;104;0x0708];
if[not 89 100 108 140~bm[`addr]; {'"failed"}[]];
if[not 0x01fffe040708~bm[1;`data]; {'"failed"}[]];
bm:.blockmem.write[bm;106;0x090a];
if[not 89 100 140~bm[`addr]; {'"failed"}[]];
if[not 0x01fffe040708090adfde0102050708~bm[1;`data]; {'"failed"}[]];
bm:.blockmem.write[bm;145;enlist 0x10];
bm:.blockmem.write[bm;147;enlist 0x10];
bm:.blockmem.write[bm;149;0x1011];
if[not 0x0000~.blockmem.read[bm;87;2]; {'"failed"}[]];
if[not 0x00ef~.blockmem.read[bm;88;2]; {'"failed"}[]];
if[not 0x0203~.blockmem.read[bm;141;2]; {'"failed"}[]];
if[not 0x1100~.blockmem.read[bm;150;2]; {'"failed"}[]];
if[not 0x0000~.blockmem.read[bm;151;2]; {'"failed"}[]];
if[not 0x000000~.blockmem.read[bm;96;3]; {'"failed"}[]];
if[not 0x000001~.blockmem.read[bm;98;3]; {'"failed"}[]];
if[not 0x0400100010~.blockmem.read[bm;143;5]; {'"failed"}[]];
if[not 0x04001000100010~.blockmem.read[bm;143;7]; {'"failed"}[]];
bm:.blockmem.write[bm;143;0x20202020202020];
if[not 89 100 140~bm[`addr]; {'"failed"}[]];
if[not 0x0102032020202020202011~bm[2;`data]; {'"failed"}[]];
bm:.blockmem.new[];
bm:.blockmem.write[bm;10;1#0x00];
bm:.blockmem.write[bm;20i;1#0x00];
bm:.blockmem.write[bm;30i;1#0x00];
};
.blockmem.unitTest[]