mirror of
https://github.com/open-simh/simtools.git
synced 2026-03-03 10:06:36 +00:00
Implement .RAD50 <CHR> syntax, and tests.
This commit is contained in:
69
assemble.c
69
assemble.c
@@ -1154,33 +1154,60 @@ static int assemble(
|
||||
report(stack->top, ".RAD50 on odd " "boundary\n");
|
||||
DOT++; /* Fix it */
|
||||
}
|
||||
|
||||
while (!EOL(*cp)) {
|
||||
char endstr[6];
|
||||
int len;
|
||||
{
|
||||
char *radstr;
|
||||
char *radp;
|
||||
int i, len;
|
||||
|
||||
endstr[0] = *cp++;
|
||||
endstr[1] = '\n';
|
||||
endstr[2] = 0;
|
||||
/*
|
||||
* Allocate storage sufficient for the rest of
|
||||
* the line.
|
||||
*/
|
||||
radstr = memcheck(malloc(strlen(cp)));
|
||||
len = 0;
|
||||
|
||||
len = strcspn(cp, endstr);
|
||||
radstr = memcheck(malloc(len + 1));
|
||||
memcpy(radstr, cp, len);
|
||||
radstr[len] = 0;
|
||||
cp += len;
|
||||
if (*cp && *cp != '\n')
|
||||
cp++;
|
||||
for (radp = radstr; *radp;) {
|
||||
unsigned rad;
|
||||
do {
|
||||
cp = skipwhite(cp);
|
||||
if (*cp == '<') {
|
||||
EX_TREE *value;
|
||||
/* A byte value */
|
||||
value = parse_unary_expr(cp, 0);
|
||||
cp = value->cp;
|
||||
if (value->type != EX_LIT) {
|
||||
report(stack->top, "expression must be constant\n");
|
||||
radstr[len++] = 0;
|
||||
} else if (value->data.lit >= 050) {
|
||||
report(stack->top, "invalid character value %o\n", value->data.lit);
|
||||
radstr[len++] = 0;
|
||||
} else {
|
||||
radstr[len++] = value->data.lit;
|
||||
}
|
||||
free_tree(value);
|
||||
} else {
|
||||
char quote = *cp++;
|
||||
|
||||
rad = rad50(radp, &radp);
|
||||
store_word(stack->top, tr, 2, rad);
|
||||
while (*cp && *cp != '\n' && *cp != quote) {
|
||||
int ch = ascii2rad50(*cp++);
|
||||
|
||||
if (ch == -1) {
|
||||
report(stack->top, "invalid character '%c'\n", cp[-1]);
|
||||
radstr[len++] = 0;
|
||||
} else {
|
||||
radstr[len++] = ch;
|
||||
}
|
||||
|
||||
}
|
||||
cp++; /* Skip closing quote */
|
||||
}
|
||||
|
||||
cp = skipwhite(cp);
|
||||
} while (!EOL(*cp));
|
||||
|
||||
for (i = 0; i < len; i += 3) {
|
||||
int word = packrad50word(radstr + i, len - i);
|
||||
store_word(stack->top, tr, 2, word);
|
||||
}
|
||||
free(radstr);
|
||||
|
||||
cp = skipwhite(cp);
|
||||
free(radstr);
|
||||
}
|
||||
return 1;
|
||||
|
||||
|
||||
40
rad50.c
40
rad50.c
@@ -118,3 +118,43 @@ void unrad50(
|
||||
} else
|
||||
cp[0] = cp[1] = cp[2] = ' ';
|
||||
}
|
||||
|
||||
/* ascii2rad50 - convert a single character to a RAD50 character */
|
||||
|
||||
int ascii2rad50(
|
||||
char c)
|
||||
{
|
||||
char *rp;
|
||||
|
||||
if (c == '\0') /* Not a RAD50 character */
|
||||
return -1;
|
||||
rp = strchr(radtbl, toupper((unsigned char)c));
|
||||
if (rp == NULL) /* Not a RAD50 character */
|
||||
return -1;
|
||||
return (int) (rp - radtbl); /* Convert */
|
||||
}
|
||||
|
||||
/* packrad50word - packs up to 3 characters into a RAD50 word.
|
||||
*
|
||||
* The characters should be in the range [0, 050),
|
||||
* such as having been converted by ascii2rad50().
|
||||
*/
|
||||
|
||||
unsigned packrad50word(
|
||||
char *cp,
|
||||
int len)
|
||||
{
|
||||
unsigned long acc = 0;
|
||||
|
||||
if (len >= 1) {
|
||||
acc += (cp[0] % 050) * 050 * 050;
|
||||
}
|
||||
if (len >= 2) {
|
||||
acc += (cp[1] % 050) * 050;
|
||||
}
|
||||
if (len >= 3) {
|
||||
acc += cp[2] % 050;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
7
rad50.h
7
rad50.h
@@ -46,4 +46,11 @@ extern void unrad50(
|
||||
unsigned word,
|
||||
char *cp);
|
||||
|
||||
int ascii2rad50(
|
||||
char c);
|
||||
|
||||
unsigned packrad50word(
|
||||
char *cp,
|
||||
int len);
|
||||
|
||||
#endif /* RAD50_H */
|
||||
|
||||
@@ -17,6 +17,7 @@ TESTS="test-asciz \
|
||||
test-locals \
|
||||
test-macro-comma \
|
||||
test-psect \
|
||||
test-rad50 \
|
||||
test-undef \
|
||||
test-word-comma"
|
||||
|
||||
|
||||
47
tests/test-rad50.lst.ok
Normal file
47
tests/test-rad50.lst.ok
Normal file
@@ -0,0 +1,47 @@
|
||||
1 ;;;;;
|
||||
2 ;
|
||||
3 ; Test .rad50 directive
|
||||
4 ;
|
||||
5 ;
|
||||
6 ; 0 space
|
||||
7 ; 01-32 A-Z
|
||||
8 ; 33 $
|
||||
9 ; 34 .
|
||||
10 ; 35 (undefined)
|
||||
11 ; 36-47 0-9
|
||||
12 ;
|
||||
13 ; radix-50 value: ((C1 * 50) + C2) * 50) + C3 ; everything octal of course
|
||||
14 ; example: ABC => ((1*50)+2)*50+3 = 3223
|
||||
15
|
||||
16 000000 003223 .rad50 /ABC/ ; Packs ABC into one word
|
||||
17 000002 003223 .rad50 ^ABC^ ; Packs ABC into one word
|
||||
18 000004 003220 .rad50 /AB/ ; Packs AB (SPACE) into one word
|
||||
19 000006 003223 014400 .rad50 /ABCD/ ; Packs ABC into first word and
|
||||
20 ; D (SPACE) (SPACE) into second word.
|
||||
21 000012 003223 014716 .rad50 /ABCDEF/ ; Packs ABC into first word, DEF into
|
||||
22 ; second word.
|
||||
23 000016 003255 .rad50 /AB/<35> ; stores 3255 in one word
|
||||
test-rad50.mac:24: ***ERROR invalid character '?'
|
||||
test-rad50.mac:24: ***ERROR invalid character '!'
|
||||
test-rad50.mac:24: ***ERROR invalid character '='
|
||||
24 000020 000000 .rad50 /?!=/ ; invalid characters
|
||||
test-rad50.mac:25: ***ERROR invalid character value 50
|
||||
test-rad50.mac:25: ***ERROR invalid character value 37777777777
|
||||
25 000022 000000 .rad50 <0><50><-1> ; invalid characters
|
||||
26 000001 CHR1=1
|
||||
27 000002 CHR2=2
|
||||
28 000003 CHR3=3
|
||||
29 000024 003223 .RAD50 <1><2><3> ; Equivalent to .RAD50 /ABC/
|
||||
30 000026 003223 .RAD50 <CHR1><CHR2><CHR3> ; Equivalent to .RAD50 /ABC/
|
||||
30
|
||||
|
||||
|
||||
Symbol table
|
||||
|
||||
. ******R 001 CHR1 =000001 CHR2 =000002 CHR3 =000003
|
||||
|
||||
|
||||
Program sections:
|
||||
|
||||
. ABS. 000000 000 (RW,I,GBL,ABS,OVR,NOSAV)
|
||||
000030 001 (RW,I,LCL,REL,CON,NOSAV)
|
||||
30
tests/test-rad50.mac
Normal file
30
tests/test-rad50.mac
Normal file
@@ -0,0 +1,30 @@
|
||||
;;;;;
|
||||
;
|
||||
; Test .rad50 directive
|
||||
;
|
||||
;
|
||||
; 0 space
|
||||
; 01-32 A-Z
|
||||
; 33 $
|
||||
; 34 .
|
||||
; 35 (undefined)
|
||||
; 36-47 0-9
|
||||
;
|
||||
; radix-50 value: ((C1 * 50) + C2) * 50) + C3 ; everything octal of course
|
||||
; example: ABC => ((1*50)+2)*50+3 = 3223
|
||||
|
||||
.rad50 /ABC/ ; Packs ABC into one word
|
||||
.rad50 ^ABC^ ; Packs ABC into one word
|
||||
.rad50 /AB/ ; Packs AB (SPACE) into one word
|
||||
.rad50 /ABCD/ ; Packs ABC into first word and
|
||||
; D (SPACE) (SPACE) into second word.
|
||||
.rad50 /ABCDEF/ ; Packs ABC into first word, DEF into
|
||||
; second word.
|
||||
.rad50 /AB/<35> ; stores 3255 in one word
|
||||
.rad50 /?!=/ ; invalid characters
|
||||
.rad50 <0><50><-1> ; invalid characters
|
||||
CHR1=1
|
||||
CHR2=2
|
||||
CHR3=3
|
||||
.RAD50 <1><2><3> ; Equivalent to .RAD50 /ABC/
|
||||
.RAD50 <CHR1><CHR2><CHR3> ; Equivalent to .RAD50 /ABC/
|
||||
Reference in New Issue
Block a user