diff options
Diffstat (limited to 'noao/mtlocal/cyber/rdumpf.x')
-rw-r--r-- | noao/mtlocal/cyber/rdumpf.x | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/noao/mtlocal/cyber/rdumpf.x b/noao/mtlocal/cyber/rdumpf.x new file mode 100644 index 00000000..d9371579 --- /dev/null +++ b/noao/mtlocal/cyber/rdumpf.x @@ -0,0 +1,283 @@ +include <mach.h> +include "cyber.h" + +# READ_DUMPF -- Read data from an array of cyber words, passing the +# requested number of cyber words to the output buffer. +# The word array contains control words and "Zero length PRU's" as well +# as data. The control words are read and used to properly +# interpret the PRU that follows. Each read by GET_CYBER_WORDS begins +# on a control word boundry. It is expected that read_dumpf returns an +# integral number of PRU's; if not, the data remaining in the PRU is discarded, +# as the buffer pointer must be positioned to the control word preceeding +# a PRU upon entry to read_dumpf. The number of cyber words read is +# returned by read_dumpf. Pointer ip is in units of cyber words; there +# are two array elements per cyber word. + +int procedure read_dumpf (rd, out, max_cyb_words) + +int rd, max_cyb_words +int out[ARB], pru_buf[NINT_CYBER_WRD * LEN_CYBER_READ] +int nwords, nwords_read, word_count, ip +int get_cyber_words(), read_dumpf_init(), bitupk() + +begin + if (mod (max_cyb_words, LEN_PRU) != 0) + call error (0, "READ_DUMPF: Non-integral PRU requested") + + for (nwords=0; nwords < max_cyb_words; nwords = nwords + word_count) { + # If necessary, read more data into the pru buffer. This + # will be necessary when all data in the pru buffer has + # been transferred to the output buffer. + + if (ip >= nwords_read) { + # Read another chunk of cyber words; reset buffer position + nwords_read = get_cyber_words (rd, pru_buf, LEN_CYBER_READ) + ip = 1 + + if (nwords_read == EOF) + break + } + + # Get the number of 12-bit bytes in the next pru from control word. + # This number stored in lowest 9 bits of the cyber word. + word_count = bitupk (pru_buf[(NINT_CYBER_WRD * ip) - 1], 1, 9) / + NBYTES_WORD + ip = ip + 1 + + if (word_count == 0) { + # Zero length PRU to be skipped over + ip = ip + LEN_PRU + next + } + + if (mod (word_count * 60, NBITS_CHAR) != 0) + call error (0, "READ_DUMPF: Impossible PRU to CHAR Conversion") + + call amovi (pru_buf[(NINT_CYBER_WRD * ip) - 1], out[(nwords * + NINT_CYBER_WRD) + 1], word_count * NINT_CYBER_WRD) + ip = ip + LEN_PRU + } + + if (nwords == 0) + return (EOF) + else + return (nwords) + +entry read_dumpf_init () + + ip = 1 + nwords_read = 0 +end + +.help read_cyber +.nf ________________________________________________________________________ +GET_CYBER_WORDS -- Read binary chars from a file, ignoring short "noise" +records and extraneous bits inserted to fill out a byte. The requested +number of cyber words is returned, one cyber word per two array elements. +Data is read from +the file buffer and placed in the output array by UNPACK_CYBER_WORDS. The +file buffer is refilled as necessary by calling READ; the output array is +supplied by the calling procedure. Cyber noise records (48 bits) and bits +used to fill out a byte are not transferred to the output array. +Variables marking the current position and top of the buffer are initialized +by GET_CYBER_WORDS_INIT; buf pos marks the buffer position in cyber words. +The number of cyber words read is returned as the function value; the number +of output array elements filled is twice the number of cyber words read. +.endhelp ___________________________________________________________________ + +int procedure get_cyber_words (rd, out, max_cyb_words) + +int rd, max_cyb_words +int out[ARB] +char cyber_buf[SZ_TAPE_BUFFER] +int buf_pos, ncyber_words +int nwords, word_chunk, nchars_read +int read(), get_cyber_words_init() + +begin + for (nwords = 0; nwords < max_cyb_words; nwords = nwords + word_chunk) { + # See if it is necessary to transfer more data from the binary file + # to the file buffer. This will be necessary when all data from the + # file buffer has been transferred to the output array. + + if (buf_pos >= ncyber_words) { + # Read the next non-noise record into cyber_buf; reset buf_pos + repeat { + nchars_read = read (rd, cyber_buf, SZ_TAPE_BUFFER) + } until (nchars_read >= NCHARS_NOISE || nchars_read == EOF) + buf_pos = 1 + ncyber_words = (nchars_read * NBITS_CHAR) / NBITS_CYBER_WORD + + if (nchars_read == EOF) + break + } + + # The number of cyber words to output is the smaller of the number + # requested or the number of words left in the buffer. + + word_chunk = min (max_cyb_words - nwords, ncyber_words- buf_pos + 1) + call unpack_cyber_words (cyber_buf, buf_pos, out, + (NINT_CYBER_WRD * nwords) + 1, word_chunk) + buf_pos = buf_pos + word_chunk + } + + if (nwords == 0) + return (EOF) + else + return (nwords) + +entry get_cyber_words_init () + + buf_pos = 1 + ncyber_words = 0 + return (OK) +end + + + +.help unpack_cyber_words +.nf __________________________________________________________________________ +UNPACK_CYBER_WORDS -- Convert a raw data array from a 60-bit Cyber computer into +an SPP array containing one Cyber word in each 64-bit increment. +The least significant Cyber bit is bit 1 in each output word and the most +significant bit is bit 60. [MACHDEP]. + +When the Cyber outputs an array of 60 bit Cyber words it moves a stream of +bits into output bytes, filling however many bytes as necessary to output a +given number of Cyber words. The most significant bits are output first, +i.e., bit 60 of the first word is moved to bit 8 of the first output byte, +bit 59 is moved to bit 7 of the first output byte, and so on. If effect the +Cyber byte flips each 60-bit word. + +To deal with Cyber words as an ordered bit stream we must reorder the bytes +and bits so that the least significant bits are first. This function is +performed by the primitives CYBOOW and CYBOEW (order odd/even Cyber word) +for individual 60-bit Cyber words. A portable (and less efficient) version +of order_cyber_bits is available which does not use these primitives. +.endhelp _____________________________________________________________________ + + +procedure unpack_cyber_words (raw_cyber, first_cyber_word, int_array, + first_output_element, ncyber_words) + +char raw_cyber[ARB] # raw Cyber array (e.g. from tape) +int first_cyber_word # first 60-bit Cyber word to be unpacked +int int_array[ARB] # output unpacked array of Cyber words +int first_output_element # first output integer to be filled +int ncyber_words # number of Cyber words to unpack + +bool odd_word +int word, inbit, outbit + +begin + odd_word = (mod (first_cyber_word, 2) == 1) + inbit = (first_cyber_word - 1) * NBITS_CYBER_WORD + 1 + outbit = (first_output_element - 1) * NBITS_INT + 1 + + do word = 1, ncyber_words { + # Call odd or even primitive to reorder bits and move 60-bit + # ordered Cyber word to the output array. + + if (odd_word) { + call cyboow (raw_cyber, inbit, int_array, outbit) + odd_word = false + } else { + call cyboew (raw_cyber, inbit, int_array, outbit) + odd_word = true + } + + inbit = inbit + NBITS_CYBER_WORD + outbit = outbit + NINT_CYBER_WRD * NBITS_INT + } +end + + +# The portable version of order_cyber_bits follows. +#.help order_cyber_bits +#.nf __________________________________________________________________________ +#ORDER_CYBER_BITS -- Convert a raw data array from a 60-bit Cyber computer into +#an SPP bit-array. The output SPP bit-array is a bit-packed array of 60-bit +#Cyber words, i.e., bits 1-60 are word 1, bits 61-120 are word 2, and so on. +#The least significant Cyber bit is bit 1 in each output word and the most +#significant bit is bit 60. [MACHDEP]. +# +#The byte stream from the Cyber contains bits 53-60 of the first word in the +#first byte, bits 45-52 in the second byte, and so on (most significant bytes +#first). In essence we swap the order of the 7 8-bit bytes and the 4-bit half +#byte in each 60 bit word. The bits in each byte are in the correct order. +# +#Each successive pair of Cyber words fits into 15 bytes. Byte 8 contains the +#last 4 bits of word 1 in the most signficant half of the byte and the first +#4 bits of word 2 in the first half of the byte. In each 60 bit word we must +#move bit segments (bytes or half bytes) as follows (for the VAX): +# +#Odd words (from N*60 bit-offset): +# [from] [to] [nbits] +# 1 53 8 +# 9 45 8 +# 17 37 8 +# 25 29 8 +# 33 21 8 +# 41 13 8 +# 49 5 8 +# 61 1 4 +# +#Even words (from N*60 bit-offset): +# [from] [to] [nbits] +# -3 57 4 +# 5 49 8 +# 13 41 8 +# 21 33 8 +# 29 25 8 +# 37 17 8 +# 45 9 8 +# 53 1 8 +#.endhelp _____________________________________________________________________ +# +#define NBITS_PER_WORD 60 +#define NSEGMENTS 8 +# +# +#procedure order_cyber_bits (raw_cyber, first_cyber_word, bit_array, +# ncyber_words) +# +#char raw_cyber[ARB] # raw Cyber array (e.g. from tape) +#int first_cyber_word # first 60-bit Cyber word to be unpacked +#char bit_array[ARB] # output bit-array +#int ncyber_words # number of Cyber words to unpack +# +#int word, inword, inbit, outbit, temp, i +#int o_from[NSEGMENTS], o_to[NSEGMENTS], o_nbits[NSEGMENTS] +#int e_from[NSEGMENTS], e_to[NSEGMENTS], e_nbits[NSEGMENTS] +#int bitupk() +# +#data o_from / 1, 9,17,25,33,41,49,61/ # odd words +#data o_to /53,45,37,29,21,13, 5, 1/ +#data o_nbits / 8, 8, 8, 8, 8, 8, 8, 4/ +#data e_from /-3, 5,13,21,29,37,45,53/ # even words +#data e_to /57,49,41,33,25,17, 9, 1/ +#data e_nbits / 4, 8, 8, 8, 8, 8, 8, 8/ +# +#begin +# do word = 1, ncyber_words { +# inword = first_cyber_word + word - 1 +# inbit = (inword - 1) * NBITS_PER_WORD +# outbit = ( word - 1) * NBITS_PER_WORD +# +# # Move bits to the output bit array. Segment list used depends +# # on whether the word is an odd or even word. This code will work +# # even if the caller only wishes to order a single word. +# +# if (mod (inword,2) == 1) { +# do i = 1, NSEGMENTS { +# temp = bitupk (raw_cyber, inbit + o_from[i], o_nbits[i]) +# call bitpak (temp, bit_array, outbit + o_to[i], o_nbits[i]) +# } +# } else { +# do i = 1, NSEGMENTS { +# temp = bitupk (raw_cyber, inbit + e_from[i], e_nbits[i]) +# call bitpak (temp, bit_array, outbit + e_to[i], e_nbits[i]) +# } +# } +# } +#end |