diff options
author | kdx <kikoodx@paranoici.org> | 2023-07-24 04:43:57 +0200 |
---|---|---|
committer | kdx <kikoodx@paranoici.org> | 2023-07-24 04:43:57 +0200 |
commit | 2fc7013751708afbf668a61b7e492d9e58057652 (patch) | |
tree | a07c677aa2b8022e3a43614edb854428e79ce92d | |
download | egecs-2fc7013751708afbf668a61b7e492d9e58057652.tar.gz |
initial commit
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | board.golem | 110 | ||||
-rw-r--r-- | color.golem | 39 | ||||
-rw-r--r-- | egecs.golem | 76 | ||||
-rw-r--r-- | iron.golem | 771 | ||||
-rw-r--r-- | pieces.golem | 32 | ||||
-rwxr-xr-x | run.sh | 5 |
7 files changed, 1034 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a699c8b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/tmp.* diff --git a/board.golem b/board.golem new file mode 100644 index 0000000..6b858b9 --- /dev/null +++ b/board.golem @@ -0,0 +1,110 @@ +define BOARD_SIZE = 64; +global gBoard[BOARD_SIZE] = 0; + +board_init() { + memset(gBoard, EMPTY, BOARD_SIZE); + board_set("a1", piece(WHITE, ROOK)); + board_set("b1", piece(WHITE, KNIGHT)); + board_set("c1", piece(WHITE, BISHOP)); + board_set("d1", piece(WHITE, QUEEN)); + board_set("e1", piece(WHITE, KING)); + board_set("f1", piece(WHITE, BISHOP)); + board_set("g1", piece(WHITE, KNIGHT)); + board_set("h1", piece(WHITE, ROOK)); + board_set("a2", piece(WHITE, PAWN)); + board_set("b2", piece(WHITE, PAWN)); + board_set("c2", piece(WHITE, PAWN)); + board_set("d2", piece(WHITE, PAWN)); + board_set("e2", piece(WHITE, PAWN)); + board_set("f2", piece(WHITE, PAWN)); + board_set("g2", piece(WHITE, PAWN)); + board_set("h2", piece(WHITE, PAWN)); + board_set("a8", piece(BLACK, ROOK)); + board_set("b8", piece(BLACK, KNIGHT)); + board_set("c8", piece(BLACK, BISHOP)); + board_set("d8", piece(BLACK, QUEEN)); + board_set("e8", piece(BLACK, KING)); + board_set("f8", piece(BLACK, BISHOP)); + board_set("g8", piece(BLACK, KNIGHT)); + board_set("h8", piece(BLACK, ROOK)); + board_set("a7", piece(BLACK, PAWN)); + board_set("b7", piece(BLACK, PAWN)); + board_set("c7", piece(BLACK, PAWN)); + board_set("d7", piece(BLACK, PAWN)); + board_set("e7", piece(BLACK, PAWN)); + board_set("f7", piece(BLACK, PAWN)); + board_set("g7", piece(BLACK, PAWN)); + board_set("h7", piece(BLACK, PAWN)); +} + +board_pos(pos, x, y) { + [x] = [pos + 0] - 'a'; + [y] = 7 - ([pos + 1] - '1'); +} + +board_set(pos, v) { + local x, y; + if (pos == NULL) + return putstr("pos is NULL\n"); + board_pos(pos, &x, &y); + if ((x > 7) | (y > 7)) { + putstr("wrong pos "); + putstr(pos); + wrt '\n'; + return; + } + [gBoard + x + y * 8] = v; +} + +board_get(pos) { + local x, y; + if (pos == NULL) + return putstr("pos is NULL\n"); + board_pos(pos, &x, &y); + if ((x > 7) | (y > 7)) { + putstr("wrong pos "); + putstr(pos); + wrt '\n'; + return INVALID; + } + return [gBoard + x + y * 8]; +} + +board_display(highlight) { + local x = 0xffff, y = 0xffff, i = 0, p; + if (highlight != NULL) + board_pos(highlight, &x, &y); + cls(); + col_reset(); + putstr("\n a b c d e f g h\n\n"); + loop { + if (i % 8 == 0) { + col_reset(); + wrt ' '; + wrt ' '; + wrt '1' + 7 - i / 8; + wrt ' '; + wrt ' '; + wrt ' '; + } + + p = [gBoard + i]; + if (x + y * 8 == i) + col_swap(); + if black(p) + col_red(); + else if p + col_green(); + else + col_blue(); + putstr([str_pieces + p]); + col_reset(); + + i = i + 1; + if (i % 8 == 0) + wrt '\n'; + if (i >= BOARD_SIZE) + break; + } + wrt '\n'; +} diff --git a/color.golem b/color.golem new file mode 100644 index 0000000..bc95276 --- /dev/null +++ b/color.golem @@ -0,0 +1,39 @@ +col_red() { + wrt 0x1b; + return putstr("[31m"); +} + +col_green() { + wrt 0x1b; + return putstr("[32m"); +} + +col_yellow() { + wrt 0x1b; + return putstr("[33m"); +} + +col_blue() { + wrt 0x1b; + return putstr("[34m"); +} + +col_magenta() { + wrt 0x1b; + return putstr("[35m"); +} + +col_cyan() { + wrt 0x1b; + return putstr("[36m"); +} + +col_reset() { + wrt 0x1b; + return putstr("[0m"); +} + +col_swap() { + wrt 0x1b; + return putstr("[7m"); +} diff --git a/egecs.golem b/egecs.golem new file mode 100644 index 0000000..3dcc3de --- /dev/null +++ b/egecs.golem @@ -0,0 +1,76 @@ +main() { + init_str_pieces(); + return egecs(); +} + +egecs() { + board_init(); + loop { + egecs_cycle(); + } +} + +cls() { + wrt 0x1b; + wrt 'c'; +} + +egecs_cycle() { + local from, to; + + loop { + board_display(NULL); + col_green(); + from = geadline("> "); + if (white(board_get(from))) + break; + if (from) { + free(from); + from = NULL; + } + } + loop { + board_display(from); + col_green(); + to = geadline("> "); + if ((board_get(to) != INVALID) & (white(board_get(to)) == 0)) + break; + if (to) { + free(to); + to = NULL; + } + } + + board_set(to, board_get(from)); + board_set(from, EMPTY); + free(to); to = NULL; + free(from); from = NULL; + + loop { + board_display(NULL); + col_red(); + from = geadline("> "); + if (black(board_get(from))) + break; + if (from) { + free(from); + from = NULL; + } + } + loop { + board_display(from); + col_red(); + to = geadline("> "); + if ((board_get(to) != INVALID) & (black(board_get(to)) == 0)) + break; + if (to) { + free(to); + to = NULL; + } + } + + board_set(to, board_get(from)); + board_set(from, EMPTY); + free(to); + free(from); +} diff --git a/iron.golem b/iron.golem new file mode 100644 index 0000000..997c70e --- /dev/null +++ b/iron.golem @@ -0,0 +1,771 @@ +aton(str) +{ + local i = 0; + local out = 0; + + loop { + if ([str + i] != '+') + break; + i++; + } + loop { + if ([str + i] == 0 | isdigit([str + i]) == 0) + break; + out = out * 10 + [str + i] - '0'; + i++; + } + return out; +} +aton_s(str) +{ + local i = 0; + local sign = 0; + local out = 0; + + loop { + if ([str + i] == '-') + sign = sign == 0; + else if ([str + i] != '+') + break; + i++; + } + loop { + if ([str + i] == 0 | isdigit([str + i]) == 0) + break; + out = out * 10 + [str + i] - '0'; + i++; + } + if (sign) + return (0 - out); + return out; +} +bzero(tab, size) memset(tab, size, 0); +define NUM_MAX = 0xffff; +define NUM_MIN = 0x0000; +define NUM_S_MIN = 0x8000; +define NUM_S_MAX = 0x7fff; +define NULL = 0; +define ZIED = NUM_MAX; +free_tab(tab) +{ + local tmp = tab; + + loop + { + if ([tmp] == 0) + return; + free([tmp]); + tmp++; + } + free(tab); +} +define HEAP_SIZE = 0x8000; +global heap[HEAP_SIZE] = 0; + +define PADDING_SIZE = 4; +define HEADER_SIZE = 5; + +πΏHEADER REPRESENTATION +πΏ+-------------+--------+--------+-------------------------------+---------------------------+---------+---------+---------+ +πΏ| initialised | used | size | pointer to the previous block | pointer to the next block | padding | data | padding | +πΏ| 1 case | 1 case | 1 case | 1 case | 1 case | 4 cases | n cases | 4 cases | +πΏ+-------------+--------+--------+-------------------------------+---------------------------+---------+---------+---------+ + +πΏ INITIALISED +πΏ a boolean to state if the block is initialised + +πΏ USED +πΏ a boolean to state if the block is used + +πΏ SIZE +πΏ The size of the data + +πΏ POINTER +πΏ The address of block + +πΏ PADDING +πΏ Is used to check invalid write +πΏ If a case doesn't equal to 0 it is an invalid write + +define LOCATION_INITIALISED = 0; +define LOCATION_USED = 1; +define LOCATION_SIZE = 2; +define LOCATION_PREV = 3; +define LOCATION_NEXT = 4; +define LOCATION_DATA = HEADER_SIZE + PADDING_SIZE; + +galloc_setup_header(ptr, used, size, next_block, prev_block) +{ + local i; + + [ptr + LOCATION_INITIALISED] = 1; + [ptr + LOCATION_USED] = used; + [ptr + LOCATION_SIZE] = size; + [ptr + LOCATION_PREV] = prev_block; + [ptr + LOCATION_NEXT] = next_block; + + i = HEADER_SIZE; + loop + { + if (i == HEADER_SIZE + PADDING_SIZE) + break; + [ptr + i] = 0; πΏ INITIALISE TOP PADDING + [ptr + i + PADDING_SIZE + size] = 0; πΏ INITIALISE BOT PADDING + i++; + } +} + +galloc_find_next_space(size) +{ + local current; + + current = heap; + loop + { + if ([current + LOCATION_USED] == 0 + & [current + LOCATION_SIZE] >= size) + return (current); + current = [current + LOCATION_NEXT]; + if (current == 0) + return (0); + } +} + +galloc_print_heap() +{ + local i; + + i = 0; + loop + { + if (i == HEAP_SIZE) + return (0); + dbg [heap + i]; + i++; + } +} + +galloc_split_block(ptr, size) +{ + local old_next; + local next; + local prev; + local old_size; + + old_size = [ptr + LOCATION_SIZE]; + if (size + HEADER_SIZE + PADDING_SIZE * 2 > old_size) πΏ if the block is to small to be split + { + [ptr + LOCATION_USED] = 1; + return (ptr); + } + old_next = [ptr + LOCATION_NEXT]; + next = ptr + size + HEADER_SIZE + PADDING_SIZE * 2; + prev = [ptr + LOCATION_PREV]; +πΏ galloc_setup_header(ptr, used, size, next_block, prev_block); + galloc_setup_header(ptr, 1, size, ptr + HEADER_SIZE + PADDING_SIZE * 2 + size, prev); + galloc_setup_header(next, 0, old_size - size - HEADER_SIZE - PADDING_SIZE * 2, old_next, ptr); + return (0); +} + +galloc(size) +{ + local ptr; + + if ([heap] == 0) πΏ if the heap is not initialised + galloc_setup_header(heap, 0, HEAP_SIZE - HEADER_SIZE - PADDING_SIZE * 2, 0, 0); πΏ initialised all the heap + ptr = galloc_find_next_space(size); + if (ptr == 0) + return (0); + if ([ptr + LOCATION_SIZE] == size) + { + [ptr + LOCATION_USED] = 1; + return (ptr + LOCATION_DATA); + } + galloc_split_block(ptr, size); + return (ptr + LOCATION_DATA); +} + +galloc_merge_blocks(first_block, last_block) +{ + local size; + + if (last_block == first_block) + { + galloc_setup_header(first_block, 0, [first_block + LOCATION_SIZE], [first_block + LOCATION_NEXT], [first_block + LOCATION_PREV]); + } + size = last_block - first_block + [last_block + LOCATION_SIZE]; + galloc_setup_header(first_block, 0, size, [last_block + LOCATION_NEXT], [first_block + LOCATION_PREV]); +} + +free(ptr) +{ + local block; + local prev_block; + local next_block; + local first_block; + local last_block; + + if (ptr > heap + HEAP_SIZE | heap > ptr) + { + putstr("Error: free: invalid ptr\n"); + return; + } + block = ptr - LOCATION_DATA; + prev_block = [block + LOCATION_PREV]; + if (prev_block == 0 | [prev_block + LOCATION_USED]) + first_block = block; + else + first_block = prev_block; + next_block = [block + LOCATION_NEXT]; + if (next_block == 0 | [next_block + LOCATION_USED]) + last_block = block; + else + last_block = next_block; + galloc_merge_blocks(first_block, last_block); +} + +leaks() +{ + return ([heap + LOCATION_NEXT] != 0); +} +geadline(prompt) { + local capacity = 64, + size = 0, + i = 0, + c, + buf = galloc(capacity); + if (prompt) + putstr(prompt); + if (buf == NULL) + return NULL; + + loop { + red &c; + if ((c == 0xffff) | (c == 0x04)) { + if ((size == 0) | (c == 0xffff)) { + free(buf); + return 0; + } + } else if (c == 0x007f) { + if (size) { + size = size - 1; + i = i - 1; + [buf + size] = 0; + + wrt 0x1b; + wrt 0x5b; + wrt 0x44; + wrt ' '; + wrt 0x1b; + wrt 0x5b; + wrt 0x44; + } + } else { + size = size + 1; + if (size > capacity) { + buf = reallocarray(buf, capacity, capacity * 2); + if (buf == NULL) + return NULL; + capacity = capacity * 2; + } + [buf + i] = c; + i = i + 1; + [buf + i] = 0; + wrt c; + if (c == '\n') + return buf; + } + } +} +define GET_LINE_BUFFER=100; + +get_line() +{ + local tmp; + local out; + local c; + local i; + + out = NULL; + i = 0; + loop + { + if (i % GET_LINE_BUFFER == 0) + { + tmp = reallocarray(out, i, i + GET_LINE_BUFFER + 1); + if (tmp == NULL) + return NULL; + } + red &c; + if (c == 0xffff) + return NULL; + [tmp + i] = c; + i++; + if (c == '\n') + break; + } + [tmp + i] = 0; + out = strdup(tmp); + free(tmp); + return out; +} +get_raw_bit(number) +{ + local tab = galloc(16); + if (tab == NULL) + return (NULL); + [tab] = number & 0x8000; + [tab + 1] = number & 0x4000; + [tab + 2] = number & 0x2000; + [tab + 3] = number & 0x1000; + [tab + 4] = number & 0x800; + [tab + 5] = number & 0x400; + [tab + 6] = number & 0x200; + [tab + 7] = number & 0x100; + [tab + 8] = number & 0x80; + [tab + 9] = number & 0x40; + [tab + 10] = number & 0x20; + [tab + 11] = number & 0x10; + [tab + 12] = number & 0x8; + [tab + 13] = number & 0x4; + [tab + 14] = number & 0x2; + [tab + 15] = number & 0x1; + return tab; +} +isalpha(c) return (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z'); +isascii(c) return c < 128; +isdigit(c) return c >= '0' & c <= '9'; +isalnum(c) return isalpha(c) | isdigit(c); +isprint(c) return c >= ' ' & c <= '~'; +memset(tab, size, value) +{ + local i = 0; + + loop { + if (i == size) + return (tab); + [tab + i++] = value; + } +} +ntoa_get_size(number) +{ + local size = 0; + + if (number == 0) + size++; + loop + { + if (number == 0) + return (size); + number = number / 10; + size++; + } +} + +ntoa(number) +{ + local str; + local size; + + size = ntoa_get_size(number); + str = galloc(size + 1); + if (str == 0) + return (0); + [str + size] = 0; + if (number == 0) + [str] = '0'; + loop + { + if (number == 0) + return (str); + [str + size - 1] = number % 10 + '0'; + number = number / 10; + size--; + } +} +ntoa_get_size(number) +{ + local size = 0; + + if (number == 0) + size++; + loop + { + if (number == 0) + return (size); + number = number / 10; + size++; + } +} + +ntoa_s(number) +{ + local str, sign, size; + + if (number >= 0x8000) + { + number = 0 - number; + sign = 1; + } + size = ntoa_get_size(number); + if (sign) + size++; + str = galloc(size + 1); + if (str == 0) + return (0); + [str + size] = 0; + if (sign) + [str] = '-'; + else if (number == 0) + [str] = '0'; + loop + { + if (number == 0) + return (str); + [str + size - 1] = number % 10 + '0'; + number = number / 10; + size--; + } +} +print_raw_bit(number) +{ + local tab = get_raw_bit(number), i = 0; + puttab_num(tab, 16); + free(tab); +} +putchar(c) wrt c; +putnum(number) +{ + local str; + str = ntoa(number); + if (str == 0) + return; + putstr(str); + free(str); +} +putnum_s(num_s) +{ + local str = ntoa_s(num_s); + putstr(str); + free(str); +} +putstr(str) +{ + local i = 0; + loop { + if ([str + i] == 0) + return; + putchar([str + i]); + i++; + } +} +puttab_str(tab) +{ + local tmp = tab; + + putchar('['); + loop + { + if ([tmp] == 0) + break; + putchar('"'); + putstr([tmp]); + putchar('"'); + if ([tmp + 1] != 0) + putstr(", "); + tmp++; + } + putchar(']'); +} + +puttab_num(tab, size) +{ + local i = 0; + + putchar('['); + loop + { + if (i == size) + break; + putnum([tab + i]); + i++; + if (i != size) + putstr(", "); + } + putchar(']'); +} +reallocarray(ptr, nmemb, size) +{ + local tmp; + local start; + + start = ptr; + tmp = galloc(size); + if (tmp == NULL) + return NULL; + if (ptr == NULL) + return tmp; + loop + { + if (start - ptr == nmemb) + break; + [tmp + start - ptr] = [start]; + start++; + } + free(ptr); + return tmp; +} +replace(str, fill, start, stop) +{ + local out; + local sum; + + out = galloc(strlen(str) + strlen(fill) - (stop - start) + 1); + if (out == NULL) + return (NULL); + strncpy(out, str, start); + strncpy(out + start, fill, strlen(fill)); + sum = start + strlen(fill); + strncpy(out + sum, str + stop, strlen(str) - stop); + [out + sum + strlen(str) - stop] = 0; + return (out); +} +split_delimiter_size(str, delimiter, delimiter_len) +{ + local i = 0; + loop + { + if (strncmp(str + i, delimiter, delimiter_len) != 0 | delimiter_len == 0) + return (i); + i = i + delimiter_len; + } +} + +split_get_size_need(str, delimiter) +{ + local tmp = str; + local len = 0; + local delimiter_len = strlen(delimiter); + + loop + { + len++; + tmp = strstr(tmp, delimiter); + if (tmp == 0 | [tmp] == 0) + return (len); + tmp = tmp + split_delimiter_size(tmp, delimiter, delimiter_len); + } +} + +split_fill_tab(tab, str, delimiter, delimiter_len) +{ + local tab_tmp = tab; + local tmp = str; + local next; + + loop + { + next = strstr(tmp, delimiter); + if (next != 0) + [tab_tmp] = strndup(tmp, next - tmp); + else + [tab_tmp] = strdup(tmp); + if ([tab_tmp] == 0) + { + free_tab(tab); + return (1); + } + if (next == 0 | [next] == 0) + return (0); + tmp = next + split_delimiter_size(next, delimiter, delimiter_len); + tab_tmp++; + } +} + +split(str, delimiter) +{ + local len, tab, delimiter_len; + + delimiter_len = strlen(delimiter); + len = split_get_size_need(str, delimiter); + tab = galloc(len + 1); + if (tab == 0) + return (0); + [tab + len] = 0; + if (split_fill_tab(tab, str, delimiter, delimiter_len)) + { + free(tab); + return (0); + } + return (tab); +} +strcat(dst, src) +{ + local i = 0; + local j = 0; + + loop { + if ([dst + i] == 0) + break; + i++; + } + loop { + if ([src + j] == 0) + break; + [dst + i + j] = [src + j]; + j++; + } + [dst + i + j] = 0; + return j; +} +strchr(str, c) +{ + local i = 0; + + loop { + if ([str + i] == c) + return (str + i); + if ([str + i] == 0) + return (0); + i++; + } +} +strchri(str, c) +{ + local i = 0; + + loop { + if ([str + i] == c) + return (i); + if ([str + i] == 0) + return (0 - 1); + i++; + } +} +strcmp(s1, s2) +{ + local i = 0; + + loop { + if ([s1 + i] != [s2 + i] | [s1 + i] == 0 | [s2 + i] == 0) + return ([s1 + i] - [s2 + i]); + i++; + } +} +strcpy(dst, src) +{ + local i = 0; + + loop { + if ([src + i] == 0) + break; + [dst + i] = [src + i]; + i++; + } + [dst + i] = 0; + return i; +} +strdup(str) +{ + local out; + + out = galloc(strlen(str) + 1); + if (out == 0) + return (0); + strcpy(out, str); + return (out); +} +strlen(str) { + local i = 0; + + loop { + if ([str + i] == 0) + return (i); + i++; + } +} +strncmp(s1, s2, n) +{ + local i; + + if (n-- == 0) + return (0); + i = 0; + loop + { + if (i == n | [s1 + i] != [s2 + i] | [s1 + i] == 0 | [s2 + i] == 0) + return ([s1 + i] - [s2 + i]); + i++; + } +} +strncpy(dst, src, size) +{ + local i = 0; + + loop { + if ([src + i] == 0 | i >= size) + break; + [dst + i] = [src + i]; + i++; + } + [dst + i] = 0; + return i; +} +strndup(str, n) +{ + local i = 0; + local out; + local size; + + size = strlen(str); + if (size > n) + size = n; + out = galloc(size + 1); + if (out == 0) + return (0); + [out + size] = 0; + strncpy(out, str, size); + return (out); +} +strstr(str, to_find) +{ + local to_find_size; + local tmp; + + to_find_size = strlen(to_find); + loop + { + tmp = strchr(str, [to_find]); + if (tmp == 0) + return (0); + if (strncmp(tmp, to_find, to_find_size) == 0) + return (tmp); + } +} +tabcmp_str(tab1, tab2) +{ + local i = 0; + + loop + { + if (strcmp([tab1 + i], [tab2 + i]) | [tab1 + i] == 0) + return ([tab1 + i] - [tab2 + i]); + i++; + } +} + +tabcmp_num(tab1, tab2, size) +{ + local i = 0; + + if (size == 0) + return (0); + loop + { + if (i == size & [tab1 + i] == [tab2 + i]) + return ([tab1 + i] - [tab2 + i]); + i++; + } +} +tolower(c) return c + 32 * (c >= 'A' & c <= 'Z'); +toupper(c) return c - 32 * (c >= 'a' & c <= 'z'); diff --git a/pieces.golem b/pieces.golem new file mode 100644 index 0000000..5952344 --- /dev/null +++ b/pieces.golem @@ -0,0 +1,32 @@ +global str_pieces[16] = 0; +init_str_pieces() { + [str_pieces + EMPTY] = "β‘ "; + [str_pieces + (WHITE | KING)] = "β "; + [str_pieces + (WHITE | QUEEN)] = "β "; + [str_pieces + (WHITE | ROOK)] = "β "; + [str_pieces + (WHITE | BISHOP)] = "β "; + [str_pieces + (WHITE | KNIGHT)] = "β "; + [str_pieces + (WHITE | PAWN)] = "β "; + [str_pieces + (BLACK | KING)] = "β "; + [str_pieces + (BLACK | QUEEN)] = "β "; + [str_pieces + (BLACK | ROOK)] = "β "; + [str_pieces + (BLACK | BISHOP)] = "β "; + [str_pieces + (BLACK | KNIGHT)] = "β "; + [str_pieces + (BLACK | PAWN)] = "β "; +} + +define EMPTY = 0; +define KING = 1; +define QUEEN = 2; +define ROOK = 3; +define BISHOP = 4; +define KNIGHT = 5; +define PAWN = 6; +define TYPE = 7; +define WHITE = 0; +define BLACK = 8; +define INVALID = 0xffff; + +piece(color, type) => color | type; +black(piece) => (piece & BLACK) != 0; +white(piece) => piece != 0 & ((piece & BLACK) == 0); @@ -0,0 +1,5 @@ +rm -f tmp.* +cat *.golem >tmp.golem +golemc tmp.golem >tmp.asm +orgaasm tmp.asm tmp.rom +orgaemu tmp.rom |